From 36a4720dab77d5580010b81e59e8cbc2d915e4aa Mon Sep 17 00:00:00 2001 From: Igor Aleksanov Date: Thu, 15 Aug 2024 13:49:23 +0400 Subject: [PATCH 1/7] Historical release: v0.131.0 --- .gitignore | 1 + .../.github/ISSUE_TEMPLATE/bug_report.md | 39 + .../.github/ISSUE_TEMPLATE/feature_request.md | 21 + .../zk_evm/.github/pull_request_template.md | 20 + .../.github/workflows/cargo-license.yaml | 8 + crates/zk_evm/.github/workflows/ci.yaml | 26 + .../.github/workflows/secrets_scanner.yaml | 17 + crates/zk_evm/.gitignore | 2 + crates/zk_evm/CONTRIBUTING.md | 44 + crates/zk_evm/Cargo.toml | 31 + crates/zk_evm/LICENSE-APACHE | 176 +++ crates/zk_evm/LICENSE-MIT | 21 + crates/zk_evm/README.md | 32 + crates/zk_evm/SECURITY.md | 74 ++ crates/zk_evm/deny.toml | 78 ++ crates/zk_evm/eraLogo.svg | 13 + crates/zk_evm/src/abstractions/mod.rs | 197 ++++ crates/zk_evm/src/abstractions/tracing.rs | 93 ++ crates/zk_evm/src/aux_structures/mod.rs | 169 +++ crates/zk_evm/src/aux_structures/queries.rs | 74 ++ crates/zk_evm/src/block_properties/mod.rs | 7 + crates/zk_evm/src/errors/mod.rs | 13 + crates/zk_evm/src/flags.rs | 56 + crates/zk_evm/src/lib.rs | 25 + crates/zk_evm/src/opcodes/execution/add.rs | 54 + crates/zk_evm/src/opcodes/execution/binop.rs | 61 + .../zk_evm/src/opcodes/execution/context.rs | 112 ++ crates/zk_evm/src/opcodes/execution/div.rs | 75 ++ .../zk_evm/src/opcodes/execution/far_call.rs | 580 +++++++++ crates/zk_evm/src/opcodes/execution/jump.rs | 27 + crates/zk_evm/src/opcodes/execution/log.rs | 361 ++++++ crates/zk_evm/src/opcodes/execution/mod.rs | 24 + crates/zk_evm/src/opcodes/execution/mul.rs | 65 + .../zk_evm/src/opcodes/execution/near_call.rs | 75 ++ crates/zk_evm/src/opcodes/execution/noop.rs | 21 + crates/zk_evm/src/opcodes/execution/ptr.rs | 195 +++ crates/zk_evm/src/opcodes/execution/ret.rs | 255 ++++ crates/zk_evm/src/opcodes/execution/shift.rs | 78 ++ crates/zk_evm/src/opcodes/execution/sub.rs | 55 + crates/zk_evm/src/opcodes/execution/uma.rs | 460 ++++++++ crates/zk_evm/src/opcodes/mod.rs | 6 + crates/zk_evm/src/opcodes/parsing.rs | 80 ++ crates/zk_evm/src/precompiles/ecrecover.rs | 283 +++++ crates/zk_evm/src/precompiles/keccak256.rs | 290 +++++ crates/zk_evm/src/precompiles/mod.rs | 136 +++ crates/zk_evm/src/precompiles/sha256.rs | 186 +++ .../zk_evm/src/reference_impls/decommitter.rs | 98 ++ .../zk_evm/src/reference_impls/event_sink.rs | 175 +++ crates/zk_evm/src/reference_impls/memory.rs | 724 ++++++++++++ crates/zk_evm/src/reference_impls/mod.rs | 9 + crates/zk_evm/src/testing/debug_tracer.rs | 205 ++++ crates/zk_evm/src/testing/mod.rs | 75 ++ crates/zk_evm/src/testing/simple_tracer.rs | 110 ++ crates/zk_evm/src/testing/storage.rs | 184 +++ crates/zk_evm/src/testing/tests/mod.rs | 66 ++ .../testing/tests/precompiles/ecrecover.rs | 144 +++ .../testing/tests/precompiles/keccak256.rs | 138 +++ .../src/testing/tests/precompiles/mod.rs | 14 + .../src/testing/tests/precompiles/sha256.rs | 136 +++ crates/zk_evm/src/testing/tests/trivial.rs | 75 ++ crates/zk_evm/src/utils.rs | 93 ++ crates/zk_evm/src/vm_state/aux_data.rs | 7 + crates/zk_evm/src/vm_state/cycle.rs | 429 +++++++ crates/zk_evm/src/vm_state/execution_stack.rs | 141 +++ crates/zk_evm/src/vm_state/helpers.rs | 379 ++++++ crates/zk_evm/src/vm_state/mem_ops.rs | 123 ++ crates/zk_evm/src/vm_state/mod.rs | 260 ++++ crates/zk_evm/src/vm_state/pending_port.rs | 26 + crates/zk_evm/src/witness_trace/mod.rs | 86 ++ .../.github/ISSUE_TEMPLATE/bug_report.md | 39 + .../.github/ISSUE_TEMPLATE/feature_request.md | 21 + .../.github/pull_request_template.md | 20 + .../.github/workflows/cargo-license.yaml | 8 + .../.github/workflows/ci.yaml | 23 + .../.github/workflows/secrets_scanner.yaml | 17 + crates/zkevm_opcode_defs/.gitignore | 2 + crates/zkevm_opcode_defs/CONTRIBUTING.md | 44 + crates/zkevm_opcode_defs/Cargo.toml | 25 + crates/zkevm_opcode_defs/LICENSE-APACHE | 176 +++ crates/zkevm_opcode_defs/LICENSE-MIT | 21 + crates/zkevm_opcode_defs/README.md | 32 + crates/zkevm_opcode_defs/SECURITY.md | 74 ++ crates/zkevm_opcode_defs/deny.toml | 78 ++ crates/zkevm_opcode_defs/eraLogo.png | Bin 0 -> 79091 bytes .../zkevm_opcode_defs/src/circuit_prices.rs | 27 + .../src/circuit_pricing_generator/main.rs | 162 +++ .../src/decoding/encoding_mode_production.rs | 175 +++ .../src/decoding/encoding_mode_testing.rs | 174 +++ crates/zkevm_opcode_defs/src/decoding/mod.rs | 126 ++ .../src/definitions/abi/far_call.rs | 64 + .../src/definitions/abi/fat_pointer.rs | 89 ++ .../src/definitions/abi/meta.rs | 26 + .../src/definitions/abi/mod.rs | 17 + .../src/definitions/abi/near_call.rs | 15 + .../src/definitions/abi/precompile_call.rs | 77 ++ .../src/definitions/abi/ret.rs | 51 + .../zkevm_opcode_defs/src/definitions/add.rs | 71 ++ .../zkevm_opcode_defs/src/definitions/all.rs | 271 +++++ .../src/definitions/binop.rs | 75 ++ .../src/definitions/condition.rs | 58 + .../src/definitions/context.rs | 127 ++ .../zkevm_opcode_defs/src/definitions/div.rs | 71 ++ .../src/definitions/far_call.rs | 100 ++ .../src/definitions/invalid_opcode.rs | 65 + .../zkevm_opcode_defs/src/definitions/jump.rs | 65 + .../zkevm_opcode_defs/src/definitions/log.rs | 171 +++ .../zkevm_opcode_defs/src/definitions/mod.rs | 1041 +++++++++++++++++ .../zkevm_opcode_defs/src/definitions/mul.rs | 71 ++ .../src/definitions/near_call.rs | 65 + .../zkevm_opcode_defs/src/definitions/noop.rs | 65 + .../src/definitions/opcode_trait.rs | 133 +++ .../zkevm_opcode_defs/src/definitions/ptr.rs | 85 ++ .../zkevm_opcode_defs/src/definitions/ret.rs | 82 ++ .../src/definitions/shift.rs | 82 ++ .../zkevm_opcode_defs/src/definitions/sub.rs | 71 ++ .../zkevm_opcode_defs/src/definitions/uma.rs | 142 +++ .../src/definitions/versioned_hash/mod.rs | 103 ++ .../src/imm_mem_modifiers.rs | 129 ++ crates/zkevm_opcode_defs/src/lib.rs | 252 ++++ crates/zkevm_opcode_defs/src/opcode.rs | 89 ++ crates/zkevm_opcode_defs/src/system_params.rs | 85 ++ crates/zkevm_opcode_defs/src/utils.rs | 61 + 122 files changed, 13626 insertions(+) create mode 100644 crates/zk_evm/.github/ISSUE_TEMPLATE/bug_report.md create mode 100644 crates/zk_evm/.github/ISSUE_TEMPLATE/feature_request.md create mode 100644 crates/zk_evm/.github/pull_request_template.md create mode 100644 crates/zk_evm/.github/workflows/cargo-license.yaml create mode 100644 crates/zk_evm/.github/workflows/ci.yaml create mode 100644 crates/zk_evm/.github/workflows/secrets_scanner.yaml create mode 100644 crates/zk_evm/.gitignore create mode 100644 crates/zk_evm/CONTRIBUTING.md create mode 100644 crates/zk_evm/Cargo.toml create mode 100644 crates/zk_evm/LICENSE-APACHE create mode 100644 crates/zk_evm/LICENSE-MIT create mode 100644 crates/zk_evm/README.md create mode 100644 crates/zk_evm/SECURITY.md create mode 100644 crates/zk_evm/deny.toml create mode 100644 crates/zk_evm/eraLogo.svg create mode 100644 crates/zk_evm/src/abstractions/mod.rs create mode 100644 crates/zk_evm/src/abstractions/tracing.rs create mode 100644 crates/zk_evm/src/aux_structures/mod.rs create mode 100644 crates/zk_evm/src/aux_structures/queries.rs create mode 100644 crates/zk_evm/src/block_properties/mod.rs create mode 100644 crates/zk_evm/src/errors/mod.rs create mode 100644 crates/zk_evm/src/flags.rs create mode 100644 crates/zk_evm/src/lib.rs create mode 100644 crates/zk_evm/src/opcodes/execution/add.rs create mode 100644 crates/zk_evm/src/opcodes/execution/binop.rs create mode 100644 crates/zk_evm/src/opcodes/execution/context.rs create mode 100644 crates/zk_evm/src/opcodes/execution/div.rs create mode 100644 crates/zk_evm/src/opcodes/execution/far_call.rs create mode 100644 crates/zk_evm/src/opcodes/execution/jump.rs create mode 100644 crates/zk_evm/src/opcodes/execution/log.rs create mode 100644 crates/zk_evm/src/opcodes/execution/mod.rs create mode 100644 crates/zk_evm/src/opcodes/execution/mul.rs create mode 100644 crates/zk_evm/src/opcodes/execution/near_call.rs create mode 100644 crates/zk_evm/src/opcodes/execution/noop.rs create mode 100644 crates/zk_evm/src/opcodes/execution/ptr.rs create mode 100644 crates/zk_evm/src/opcodes/execution/ret.rs create mode 100644 crates/zk_evm/src/opcodes/execution/shift.rs create mode 100644 crates/zk_evm/src/opcodes/execution/sub.rs create mode 100644 crates/zk_evm/src/opcodes/execution/uma.rs create mode 100644 crates/zk_evm/src/opcodes/mod.rs create mode 100644 crates/zk_evm/src/opcodes/parsing.rs create mode 100644 crates/zk_evm/src/precompiles/ecrecover.rs create mode 100644 crates/zk_evm/src/precompiles/keccak256.rs create mode 100644 crates/zk_evm/src/precompiles/mod.rs create mode 100644 crates/zk_evm/src/precompiles/sha256.rs create mode 100644 crates/zk_evm/src/reference_impls/decommitter.rs create mode 100644 crates/zk_evm/src/reference_impls/event_sink.rs create mode 100644 crates/zk_evm/src/reference_impls/memory.rs create mode 100644 crates/zk_evm/src/reference_impls/mod.rs create mode 100644 crates/zk_evm/src/testing/debug_tracer.rs create mode 100644 crates/zk_evm/src/testing/mod.rs create mode 100644 crates/zk_evm/src/testing/simple_tracer.rs create mode 100644 crates/zk_evm/src/testing/storage.rs create mode 100644 crates/zk_evm/src/testing/tests/mod.rs create mode 100644 crates/zk_evm/src/testing/tests/precompiles/ecrecover.rs create mode 100644 crates/zk_evm/src/testing/tests/precompiles/keccak256.rs create mode 100644 crates/zk_evm/src/testing/tests/precompiles/mod.rs create mode 100644 crates/zk_evm/src/testing/tests/precompiles/sha256.rs create mode 100644 crates/zk_evm/src/testing/tests/trivial.rs create mode 100644 crates/zk_evm/src/utils.rs create mode 100644 crates/zk_evm/src/vm_state/aux_data.rs create mode 100644 crates/zk_evm/src/vm_state/cycle.rs create mode 100644 crates/zk_evm/src/vm_state/execution_stack.rs create mode 100644 crates/zk_evm/src/vm_state/helpers.rs create mode 100644 crates/zk_evm/src/vm_state/mem_ops.rs create mode 100644 crates/zk_evm/src/vm_state/mod.rs create mode 100644 crates/zk_evm/src/vm_state/pending_port.rs create mode 100644 crates/zk_evm/src/witness_trace/mod.rs create mode 100644 crates/zkevm_opcode_defs/.github/ISSUE_TEMPLATE/bug_report.md create mode 100644 crates/zkevm_opcode_defs/.github/ISSUE_TEMPLATE/feature_request.md create mode 100644 crates/zkevm_opcode_defs/.github/pull_request_template.md create mode 100644 crates/zkevm_opcode_defs/.github/workflows/cargo-license.yaml create mode 100644 crates/zkevm_opcode_defs/.github/workflows/ci.yaml create mode 100644 crates/zkevm_opcode_defs/.github/workflows/secrets_scanner.yaml create mode 100644 crates/zkevm_opcode_defs/.gitignore create mode 100644 crates/zkevm_opcode_defs/CONTRIBUTING.md create mode 100644 crates/zkevm_opcode_defs/Cargo.toml create mode 100644 crates/zkevm_opcode_defs/LICENSE-APACHE create mode 100644 crates/zkevm_opcode_defs/LICENSE-MIT create mode 100644 crates/zkevm_opcode_defs/README.md create mode 100644 crates/zkevm_opcode_defs/SECURITY.md create mode 100644 crates/zkevm_opcode_defs/deny.toml create mode 100644 crates/zkevm_opcode_defs/eraLogo.png create mode 100644 crates/zkevm_opcode_defs/src/circuit_prices.rs create mode 100644 crates/zkevm_opcode_defs/src/circuit_pricing_generator/main.rs create mode 100644 crates/zkevm_opcode_defs/src/decoding/encoding_mode_production.rs create mode 100644 crates/zkevm_opcode_defs/src/decoding/encoding_mode_testing.rs create mode 100644 crates/zkevm_opcode_defs/src/decoding/mod.rs create mode 100644 crates/zkevm_opcode_defs/src/definitions/abi/far_call.rs create mode 100644 crates/zkevm_opcode_defs/src/definitions/abi/fat_pointer.rs create mode 100644 crates/zkevm_opcode_defs/src/definitions/abi/meta.rs create mode 100644 crates/zkevm_opcode_defs/src/definitions/abi/mod.rs create mode 100644 crates/zkevm_opcode_defs/src/definitions/abi/near_call.rs create mode 100644 crates/zkevm_opcode_defs/src/definitions/abi/precompile_call.rs create mode 100644 crates/zkevm_opcode_defs/src/definitions/abi/ret.rs create mode 100644 crates/zkevm_opcode_defs/src/definitions/add.rs create mode 100644 crates/zkevm_opcode_defs/src/definitions/all.rs create mode 100644 crates/zkevm_opcode_defs/src/definitions/binop.rs create mode 100644 crates/zkevm_opcode_defs/src/definitions/condition.rs create mode 100644 crates/zkevm_opcode_defs/src/definitions/context.rs create mode 100644 crates/zkevm_opcode_defs/src/definitions/div.rs create mode 100644 crates/zkevm_opcode_defs/src/definitions/far_call.rs create mode 100644 crates/zkevm_opcode_defs/src/definitions/invalid_opcode.rs create mode 100644 crates/zkevm_opcode_defs/src/definitions/jump.rs create mode 100644 crates/zkevm_opcode_defs/src/definitions/log.rs create mode 100644 crates/zkevm_opcode_defs/src/definitions/mod.rs create mode 100644 crates/zkevm_opcode_defs/src/definitions/mul.rs create mode 100644 crates/zkevm_opcode_defs/src/definitions/near_call.rs create mode 100644 crates/zkevm_opcode_defs/src/definitions/noop.rs create mode 100644 crates/zkevm_opcode_defs/src/definitions/opcode_trait.rs create mode 100644 crates/zkevm_opcode_defs/src/definitions/ptr.rs create mode 100644 crates/zkevm_opcode_defs/src/definitions/ret.rs create mode 100644 crates/zkevm_opcode_defs/src/definitions/shift.rs create mode 100644 crates/zkevm_opcode_defs/src/definitions/sub.rs create mode 100644 crates/zkevm_opcode_defs/src/definitions/uma.rs create mode 100644 crates/zkevm_opcode_defs/src/definitions/versioned_hash/mod.rs create mode 100644 crates/zkevm_opcode_defs/src/imm_mem_modifiers.rs create mode 100644 crates/zkevm_opcode_defs/src/lib.rs create mode 100644 crates/zkevm_opcode_defs/src/opcode.rs create mode 100644 crates/zkevm_opcode_defs/src/system_params.rs create mode 100644 crates/zkevm_opcode_defs/src/utils.rs diff --git a/.gitignore b/.gitignore index dbf3d8e..b4b7767 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ target/ Cargo.lock .vscode *.log +tmp_copy* diff --git a/crates/zk_evm/.github/ISSUE_TEMPLATE/bug_report.md b/crates/zk_evm/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..2d3e38a --- /dev/null +++ b/crates/zk_evm/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,39 @@ +--- +name: Bug report +about: Use this template for reporting issues +title: '' +labels: bug +assignees: '' +--- + +### 🐛 Bug Report + +#### 📝 Description + +Provide a clear and concise description of the bug. + +#### 🔄 Reproduction Steps + +Steps to reproduce the behaviour + +#### 🤔 Expected Behavior + +Describe what you expected to happen. + +#### 😯 Current Behavior + +Describe what actually happened. + +#### 🖥️ Environment + +Any relevant environment details. + +#### 📋 Additional Context + +Add any other context about the problem here. If applicable, add screenshots to help explain. + +#### 📎 Log Output + +``` +Paste any relevant log output here. +``` diff --git a/crates/zk_evm/.github/ISSUE_TEMPLATE/feature_request.md b/crates/zk_evm/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..d921e06 --- /dev/null +++ b/crates/zk_evm/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,21 @@ +--- +name: Feature request +about: Use this template for requesting features +title: '' +labels: feat +assignees: '' +--- + +### 🌟 Feature Request + +#### 📝 Description + +Provide a clear and concise description of the feature you'd like to see. + +#### 🤔 Rationale + +Explain why this feature is important and how it benefits the project. + +#### 📋 Additional Context + +Add any other context or information about the feature request here. diff --git a/crates/zk_evm/.github/pull_request_template.md b/crates/zk_evm/.github/pull_request_template.md new file mode 100644 index 0000000..8ce206c --- /dev/null +++ b/crates/zk_evm/.github/pull_request_template.md @@ -0,0 +1,20 @@ +# What ❔ + + + + + +## Why ❔ + + + + +## Checklist + + + + +- [ ] PR title corresponds to the body of PR (we generate changelog entries from PRs). +- [ ] Tests for the changes have been added / updated. +- [ ] Documentation comments have been added / updated. +- [ ] Code has been formatted via `zk fmt` and `zk lint`. diff --git a/crates/zk_evm/.github/workflows/cargo-license.yaml b/crates/zk_evm/.github/workflows/cargo-license.yaml new file mode 100644 index 0000000..d6ee929 --- /dev/null +++ b/crates/zk_evm/.github/workflows/cargo-license.yaml @@ -0,0 +1,8 @@ +name: CI +on: [push, pull_request] +jobs: + cargo-deny: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: EmbarkStudios/cargo-deny-action@v1 diff --git a/crates/zk_evm/.github/workflows/ci.yaml b/crates/zk_evm/.github/workflows/ci.yaml new file mode 100644 index 0000000..8b2b519 --- /dev/null +++ b/crates/zk_evm/.github/workflows/ci.yaml @@ -0,0 +1,26 @@ +name: "Rust CI" +on: + pull_request: + +jobs: + build: + name: cargo build and test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: nightly-2023-04-17 + - run: cargo build --verbose --all-features + - run: RUSTFLAGS="-Awarnings" cargo test --verbose --all-features + + formatting: + name: cargo fmt + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + components: rustfmt + - name: Rustfmt Check + uses: actions-rust-lang/rustfmt@v1 diff --git a/crates/zk_evm/.github/workflows/secrets_scanner.yaml b/crates/zk_evm/.github/workflows/secrets_scanner.yaml new file mode 100644 index 0000000..54054cf --- /dev/null +++ b/crates/zk_evm/.github/workflows/secrets_scanner.yaml @@ -0,0 +1,17 @@ +name: Leaked Secrets Scan +on: [pull_request] +jobs: + TruffleHog: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3 + with: + fetch-depth: 0 + - name: TruffleHog OSS + uses: trufflesecurity/trufflehog@0c66d30c1f4075cee1aada2e1ab46dabb1b0071a + with: + path: ./ + base: ${{ github.event.repository.default_branch }} + head: HEAD + extra_args: --debug --only-verified diff --git a/crates/zk_evm/.gitignore b/crates/zk_evm/.gitignore new file mode 100644 index 0000000..96ef6c0 --- /dev/null +++ b/crates/zk_evm/.gitignore @@ -0,0 +1,2 @@ +/target +Cargo.lock diff --git a/crates/zk_evm/CONTRIBUTING.md b/crates/zk_evm/CONTRIBUTING.md new file mode 100644 index 0000000..dd3d458 --- /dev/null +++ b/crates/zk_evm/CONTRIBUTING.md @@ -0,0 +1,44 @@ +# Contribution Guidelines + +Hello! Thanks for your interest in joining the mission to accelerate the mass adoption of crypto for personal +sovereignty! We welcome contributions from anyone on the internet, and are grateful for even the smallest of fixes! + +## Ways to contribute + +There are many ways to contribute to the ZK Stack: + +1. Open issues: if you find a bug, have something you believe needs to be fixed, or have an idea for a feature, please + open an issue. +2. Add color to existing issues: provide screenshots, code snippets, and whatever you think would be helpful to resolve + issues. +3. Resolve issues: either by showing an issue isn't a problem and the current state is ok as is or by fixing the problem + and opening a PR. +4. Report security issues, see [our security policy](./github/SECURITY.md). +5. [Join the team!](https://matterlabs.notion.site/Shape-the-future-of-Ethereum-at-Matter-Labs-dfb3b5a037044bb3a8006af2eb0575e0) + +## Fixing issues + +To contribute code fixing issues, please fork the repo, fix an issue, commit, add documentation as per the PR template, +and the repo's maintainers will review the PR. +[here](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork) +for guidance how to work with PRs created from a fork. + +## Licenses + +If you contribute to this project, your contributions will be made to the project under both Apache 2.0 and the MIT +license. + +## Resources + +We aim to make it as easy as possible to contribute to the mission. This is still WIP, and we're happy for contributions +and suggestions here too. Some resources to help: + +1. [In-repo docs aimed at developers](docs) +2. [zkSync Era docs!](https://era.zksync.io/docs/) +3. Company links can be found in the [repo's readme](README.md) + +## Code of Conduct + +Be polite and respectful. + +### Thank you diff --git a/crates/zk_evm/Cargo.toml b/crates/zk_evm/Cargo.toml new file mode 100644 index 0000000..ebd1829 --- /dev/null +++ b/crates/zk_evm/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "zk_evm" +version = "0.131.0-rc.2" +edition = "2021" +authors = ["The Matter Labs Team "] +homepage = "https://zksync.io/" +repository = "https://github.com/matter-labs/era-zk_evm" +license = "MIT OR Apache-2.0" +keywords = ["blockchain", "zksync"] +categories = ["cryptography"] +description = "ZKsync out-of-circuit EraEVM implementation" + +resolver = "2" + +[dependencies] +zkevm_opcode_defs = { version = "=0.131.0", path = "../zkevm_opcode_defs" } + +serde = { version = "1", features = ["derive"] } +serde_json = "1.0" +num = { version = "0.4"} +sha3 = { package = "sha3_ce", version = "=0.10.6" } +sha2 = { package = "sha2_ce", version = "=0.10.6" } +blake2 = { package = "blake2_ce", version = "=0.10.6" } +k256 = { version = "0.11", features = ["arithmetic", "ecdsa"] } +static_assertions = "1" +lazy_static = "1.4" + +[dev-dependencies] +hex = "0.4" + +[features] diff --git a/crates/zk_evm/LICENSE-APACHE b/crates/zk_evm/LICENSE-APACHE new file mode 100644 index 0000000..d9a10c0 --- /dev/null +++ b/crates/zk_evm/LICENSE-APACHE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/crates/zk_evm/LICENSE-MIT b/crates/zk_evm/LICENSE-MIT new file mode 100644 index 0000000..2739ea6 --- /dev/null +++ b/crates/zk_evm/LICENSE-MIT @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Matter Labs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/crates/zk_evm/README.md b/crates/zk_evm/README.md new file mode 100644 index 0000000..a14bca9 --- /dev/null +++ b/crates/zk_evm/README.md @@ -0,0 +1,32 @@ +# zkSync Era: A ZK Rollup For Scaling Ethereum + +[![Logo](eraLogo.svg)](https://zksync.io/) + +zkSync Era is a layer 2 rollup that uses zero-knowledge proofs to scale Ethereum without compromising on security or +decentralization. Since it's EVM compatible (Solidity/Vyper), 99% of Ethereum projects can redeploy without refactoring +or re-auditing a single line of code. zkSync Era also uses an LLVM-based compiler that will eventually let developers +write smart contracts in C++, Rust and other popular languages. + +## License + +zkSync Era is distributed under the terms of either + +- Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or ) +- MIT license ([LICENSE-MIT](LICENSE-MIT) or ) + +at your option. + +## Official Links + +- [Website](https://zksync.io/) +- [GitHub](https://github.com/matter-labs) +- [Twitter](https://twitter.com/zksync) +- [Twitter for Devs](https://twitter.com/zkSyncDevs) +- [Discord](https://discord.gg/nMaPGrDDwk) + +## Disclaimer + +zkSync Era has been through lots of testing and audits. Although it is live, it is still in alpha state and will go +through more audits and bug bounties programs. We would love to hear our community's thoughts and suggestions about it! +It is important to state that forking it now can potentially lead to missing important security updates, critical +features, and performance improvements. diff --git a/crates/zk_evm/SECURITY.md b/crates/zk_evm/SECURITY.md new file mode 100644 index 0000000..2f2871c --- /dev/null +++ b/crates/zk_evm/SECURITY.md @@ -0,0 +1,74 @@ +# Security Policy + +We truly appreciate efforts to discover and disclose security issues responsibly! + +## Vulnerabilities + +If you'd like to report a security issue in the repositories of matter-labs organization, please proceed to our +[Bug Bounty Program on Immunefi](https://era.zksync.io/docs/reference/troubleshooting/audit-bug-bounty.html#bug-bounty-program). + +## Other Security Issues + +We take an impact-first approach instead of a rules-first approach. Therefore, if you believe you found the impactful +issue but can't report it via the Bug Bounty, please email us at +[security@matterlabs.dev](mailto:security@matterlabs.dev). + +### PGP Key + +The following PGP key may be used to communicate sensitive information to developers: + +Fingerprint: `5FED B2D0 EA2C 4906 DD66 71D7 A2C5 0B40 CE3C F297` + +``` +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +=xkM3 +-----END PGP PUBLIC KEY BLOCK----- +``` diff --git a/crates/zk_evm/deny.toml b/crates/zk_evm/deny.toml new file mode 100644 index 0000000..1ee7ccc --- /dev/null +++ b/crates/zk_evm/deny.toml @@ -0,0 +1,78 @@ +all-features = false +no-default-features = false + +[advisories] +vulnerability = "deny" +unmaintained = "warn" +yanked = "warn" +notice = "warn" +ignore = [ + #"RUSTSEC-0000-0000", +] + +[licenses] +unlicensed = "deny" +allow = [ + #"Apache-2.0 WITH LLVM-exception", + "MIT", + "Apache-2.0", + "ISC", + "Unlicense", + "MPL-2.0", + "Unicode-DFS-2016", + "CC0-1.0", + "BSD-2-Clause", + "BSD-3-Clause", +] +deny = [ + #"Nokia", +] +copyleft = "warn" +allow-osi-fsf-free = "neither" +default = "deny" +confidence-threshold = 0.8 +exceptions = [ + # Each entry is the crate and version constraint, and its specific allow + # list + #{ allow = ["Zlib"], name = "adler32", version = "*" }, +] + +unused-allowed-license = "allow" + +[licenses.private] +ignore = false +registries = [ + #"https://sekretz.com/registry +] + +[bans] +multiple-versions = "warn" +wildcards = "allow" +highlight = "all" +workspace-default-features = "allow" +external-default-features = "allow" +allow = [ + #{ name = "ansi_term", version = "=0.11.0" }, +] +# List of crates to deny +deny = [ + # Each entry the name of a crate and a version range. If version is + # not specified, all versions will be matched. + #{ name = "ansi_term", version = "=0.11.0" }, +] + +skip = [ + #{ name = "ansi_term", version = "=0.11.0" }, +] +skip-tree = [ + #{ name = "ansi_term", version = "=0.11.0", depth = 20 }, +] + +[sources] +unknown-registry = "deny" +unknown-git = "allow" +allow-registry = ["https://github.com/rust-lang/crates.io-index"] +allow-git = [] + +[sources.allow-org] +#github = ["matter-labs"] diff --git a/crates/zk_evm/eraLogo.svg b/crates/zk_evm/eraLogo.svg new file mode 100644 index 0000000..6ec790c --- /dev/null +++ b/crates/zk_evm/eraLogo.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/crates/zk_evm/src/abstractions/mod.rs b/crates/zk_evm/src/abstractions/mod.rs new file mode 100644 index 0000000..f1379df --- /dev/null +++ b/crates/zk_evm/src/abstractions/mod.rs @@ -0,0 +1,197 @@ +use zkevm_opcode_defs::FatPointer; + +use super::*; +use crate::aux_structures::*; +pub mod tracing; +pub use self::tracing::*; + +pub const MEMORY_CELLS_STACK_OR_CODE_PAGE: usize = 1 << 16; +pub const MAX_MEMORY_BYTES: usize = 1 << 24; +pub const MEMORY_CELLS_OTHER_PAGES: usize = MAX_MEMORY_BYTES / 32; + +pub const MAX_STACK_PAGE_SIZE_IN_WORDS: usize = 1 << 16; +pub const MAX_CODE_PAGE_SIZE_IN_WORDS: usize = 1 << 16; +pub const MAX_HEAP_PAGE_SIZE_IN_WORDS: usize = MAX_MEMORY_BYTES / 32; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] +pub enum MemoryType { + Stack, + Code, + Heap, + AuxHeap, + FatPointer, +} + +impl MemoryType { + pub const fn page_size_limit(&self) -> usize { + match self { + MemoryType::Stack | MemoryType::Code => MEMORY_CELLS_STACK_OR_CODE_PAGE, + MemoryType::Heap | MemoryType::AuxHeap | MemoryType::FatPointer => { + MEMORY_CELLS_OTHER_PAGES + } + } + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub struct RefundedAmounts { + pub pubdata_bytes: u32, + pub ergs: u32, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub enum RefundType { + None, + RepeatedRead(RefundedAmounts), + RepeatedWrite(RefundedAmounts), + RevertToOriginalInFrame(RefundedAmounts), +} + +impl RefundType { + pub const fn pubdata_refund(&self) -> u32 { + match self { + RefundType::None => 0, + RefundType::RepeatedRead(amounts) => amounts.pubdata_bytes, + RefundType::RepeatedWrite(amounts) => amounts.pubdata_bytes, + RefundType::RevertToOriginalInFrame(amounts) => amounts.pubdata_bytes, + } + } +} + +use crate::precompiles::ecrecover::ECRecoverPrecompile; +use crate::precompiles::keccak256::Keccak256Precompile; +use crate::precompiles::sha256::Sha256Precompile; + +// for strong typing we have to enumerate all of the supported precompiles here +pub enum PrecompileCyclesWitness { + Sha256(Vec< as Precompile>::CycleWitness>), + Keccak256(Vec< as Precompile>::CycleWitness>), + ECRecover(Vec< as Precompile>::CycleWitness>), +} + +// ALL traits here are for execution and NOT for witness generation. They can depend on one another, but should +// not have large interconnections. + +// Note: We may need to extend them to allow sequencer to easily perform decisions on whether or +// not to accept a transaction (or revert to the previous state) and actually perform "huge" rollbacks on +// on all the corresponding implementors + +pub trait Storage: std::fmt::Debug { + // We can evaluate a query cost (or more precisely - get expected refunds) + // before actually executing query + fn estimate_refunds_for_write( + &mut self, // to avoid any hacks inside, like prefetch + monotonic_cycle_counter: u32, + partial_query: &LogQuery, + ) -> RefundType; + + // Perform a storage read/write access by taking an partially filled query + // and returning filled query and cold/warm marker for pricing purposes + fn execute_partial_query(&mut self, monotonic_cycle_counter: u32, query: LogQuery) -> LogQuery; + // Indicate a start of execution frame for rollback purposes + fn start_frame(&mut self, timestamp: Timestamp); + // Indicate that execution frame went out from the scope, so we can + // log the history and either rollback immediately or keep records to rollback later + fn finish_frame(&mut self, timestamp: Timestamp, panicked: bool); + + // N.B. We may need to extend frame markers for e.g. special bootloader execution frame + // such that we can flush all the changes of particular transaction since bootloader doesn't + // rollback further (at least now) +} + +pub trait Memory: std::fmt::Debug { + // Perform a memory access using a partially filled query and return the result + fn execute_partial_query( + &mut self, + monotonic_cycle_counter: u32, + query: MemoryQuery, + ) -> MemoryQuery; + + fn specialized_code_query( + &mut self, + monotonic_cycle_counter: u32, + query: MemoryQuery, + ) -> MemoryQuery; + + fn read_code_query(&self, monotonic_cycle_counter: u32, query: MemoryQuery) -> MemoryQuery; + + // Notify that a certain page went out of scope and can be discarded + fn start_global_frame( + &mut self, + _current_base_page: MemoryPage, + _new_base_page: MemoryPage, + _calldata_fat_pointer: FatPointer, + _timestamp: Timestamp, + ) { + } + fn finish_global_frame( + &mut self, + _page_page: MemoryPage, + _returndata_fat_pointer: FatPointer, + _timestamp: Timestamp, + ) { + } +} + +pub trait EventSink: std::fmt::Debug { + // Largely the same as storage with exception that events are always "write"-like, + // so we do not need to return anything + fn add_partial_query(&mut self, monotonic_cycle_counter: u32, query: LogQuery); + fn start_frame(&mut self, timestamp: Timestamp); + fn finish_frame(&mut self, panicked: bool, timestamp: Timestamp); +} + +pub trait PrecompilesProcessor: std::fmt::Debug { + // Precompiles may be write-like (rollbackable, are more like markers), + // and read-like (pure function calls like sha256, etc). Here we perform an execution + // and optionally return memory queries performed by the executor that are useful for witness + // at the end of the block + fn execute_precompile( + &mut self, + monotonic_cycle_counter: u32, + query: LogQuery, + memory: &mut M, + ) -> Option<(Vec, Vec, PrecompileCyclesWitness)>; + fn start_frame(&mut self); + fn finish_frame(&mut self, panicked: bool); +} + +pub trait DecommittmentProcessor: std::fmt::Debug { + // For calls to external contract we use storage read + request to decommit a particular hash into some memory page. + // We also optimize in a way that since code and calldata locations ar read-only we can just give + // already filled page if we decommit the same hash. + // We also optinally return a set of memory writes that such decommitment has made (if it's a new page) + // for witness generation at the end of the block + fn decommit_into_memory( + &mut self, + monotonic_cycle_counter: u32, + partial_query: DecommittmentQuery, + memory: &mut M, + ) -> (DecommittmentQuery, Option>); +} + +/// Abstraction over precompile implementation. Precompile is usually a closure-forming FSM, so it must output +/// some cycle-like witness +pub trait Precompile: std::fmt::Debug { + type CycleWitness: Clone + std::fmt::Debug; + + /// execute a precompile by using request and access to memory. May be output + /// - all memory reads (may be removed later on) + /// - all memory writes (depending on the implementation we may directly write to `memory` and also remove it) + /// - FSM cycle witness parameters + fn execute_precompile( + &mut self, + monotonic_cycle_counter: u32, + query: LogQuery, + memory: &mut M, + ) -> Option<(Vec, Vec, Vec)>; +} + +pub enum SpongeExecutionMarker { + MemoryQuery, + DecommittmentQuery, + StorageLogReadOnly, + StorageLogWrite, + CallstackPush, + CallstackPop, +} diff --git a/crates/zk_evm/src/abstractions/tracing.rs b/crates/zk_evm/src/abstractions/tracing.rs new file mode 100644 index 0000000..8f0cb5f --- /dev/null +++ b/crates/zk_evm/src/abstractions/tracing.rs @@ -0,0 +1,93 @@ +use zkevm_opcode_defs::decoding::{EncodingModeProduction, VmEncodingMode}; + +use crate::{ + opcodes::DecodedOpcode, + vm_state::{ErrorFlags, PrimitiveValue, VmLocalState}, +}; + +use super::*; + +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct VmLocalStateData<'a, const N: usize = 8, E: VmEncodingMode = EncodingModeProduction> { + pub vm_local_state: &'a VmLocalState, +} + +#[derive(Clone, Copy, Debug)] +pub struct AfterDecodingData = EncodingModeProduction> { + pub raw_opcode_unmasked: E::IntegerRepresentation, // what one gets from memory + pub opcode_masked: DecodedOpcode, // what one gets after exception handling + pub error_flags_accumulated: ErrorFlags, + pub resolved_condition: bool, + pub did_skip_cycle: bool, +} + +#[derive(Clone, Copy, Debug)] +pub struct BeforeExecutionData = EncodingModeProduction> { + pub opcode: DecodedOpcode, + pub src0_value: PrimitiveValue, + pub src1_value: PrimitiveValue, + pub src0_mem_location: Option, + pub new_pc: E::PcOrImm, +} + +#[derive(Clone, Copy, Debug)] +pub struct AfterExecutionData = EncodingModeProduction> { + pub opcode: DecodedOpcode, + pub dst0_mem_location: Option, +} + +impl Memory for () { + fn execute_partial_query( + &mut self, + _monotonic_cycle_counter: u32, + _query: MemoryQuery, + ) -> MemoryQuery { + unreachable!() + } + + fn specialized_code_query( + &mut self, + _monotonic_cycle_counter: u32, + _query: MemoryQuery, + ) -> MemoryQuery { + unreachable!() + } + + fn read_code_query(&self, _monotonic_cycle_counter: u32, _query: MemoryQuery) -> MemoryQuery { + unreachable!() + } +} + +pub trait Tracer = EncodingModeProduction>: + std::fmt::Debug +{ + const CALL_BEFORE_DECODING: bool = false; + const CALL_AFTER_DECODING: bool = false; + const CALL_BEFORE_EXECUTION: bool = false; + const CALL_AFTER_EXECUTION: bool = false; + + type SupportedMemory: Memory; + fn before_decoding( + &mut self, + state: VmLocalStateData<'_, N, E>, + memory: &Self::SupportedMemory, + ); + fn after_decoding( + &mut self, + state: VmLocalStateData<'_, N, E>, + data: AfterDecodingData, + memory: &Self::SupportedMemory, + ); + fn before_execution( + &mut self, + state: VmLocalStateData<'_, N, E>, + data: BeforeExecutionData, + memory: &Self::SupportedMemory, + ); + fn after_execution( + &mut self, + state: VmLocalStateData<'_, N, E>, + data: AfterExecutionData, + memory: &Self::SupportedMemory, + ); +} diff --git a/crates/zk_evm/src/aux_structures/mod.rs b/crates/zk_evm/src/aux_structures/mod.rs new file mode 100644 index 0000000..55df338 --- /dev/null +++ b/crates/zk_evm/src/aux_structures/mod.rs @@ -0,0 +1,169 @@ +use crate::abstractions::MemoryType; + +use super::*; + +pub mod queries; + +pub use self::queries::*; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] +pub struct Timestamp(pub u32); + +impl Timestamp { + pub const fn empty() -> Self { + Self(0) + } +} + +impl std::cmp::PartialOrd for Timestamp { + fn partial_cmp(&self, other: &Self) -> Option { + self.0.partial_cmp(&other.0) + } +} + +impl std::cmp::Ord for Timestamp { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.0.cmp(&other.0) + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] +pub struct MemoryIndex(pub u32); + +impl MemoryIndex { + pub const fn empty() -> Self { + Self(0) + } +} + +impl std::cmp::PartialOrd for MemoryIndex { + fn partial_cmp(&self, other: &Self) -> Option { + self.0.partial_cmp(&other.0) + } +} + +impl std::cmp::Ord for MemoryIndex { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.0.cmp(&other.0) + } +} + +impl MemoryIndex { + pub fn increment_unchecked(&mut self) { + self.0 = self.0.wrapping_add(1u32); + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] +pub struct MemoryOffset(pub u32); + +impl std::cmp::PartialOrd for MemoryOffset { + fn partial_cmp(&self, other: &Self) -> Option { + self.0.partial_cmp(&other.0) + } +} + +impl std::cmp::Ord for MemoryOffset { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.0.cmp(&other.0) + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] +pub struct MemoryPage(pub u32); + +impl MemoryPage { + pub const fn empty() -> Self { + Self(0) + } +} + +impl std::cmp::PartialOrd for MemoryPage { + fn partial_cmp(&self, other: &Self) -> Option { + self.0.partial_cmp(&other.0) + } +} + +impl std::cmp::Ord for MemoryPage { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.0.cmp(&other.0) + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] +pub struct MemoryLocation { + pub memory_type: MemoryType, + pub page: MemoryPage, + pub index: MemoryIndex, +} + +impl MemoryLocation { + pub const fn empty() -> Self { + Self { + memory_type: MemoryType::Heap, + page: MemoryPage::empty(), + index: MemoryIndex::empty(), + } + } +} + +impl std::cmp::PartialOrd for MemoryLocation { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl std::cmp::Ord for MemoryLocation { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + let tt = self.page.cmp(&other.page); + if tt != std::cmp::Ordering::Equal { + return tt; + } + + let tt = self.index.cmp(&other.index); + if tt != std::cmp::Ordering::Equal { + return tt; + } + + std::cmp::Ordering::Equal + } +} + +impl MemoryLocation { + #[inline] + pub const fn add_offset(&self, offset: MemoryOffset) -> Self { + Self { + memory_type: self.memory_type, + page: self.page, + index: MemoryIndex(self.index.0.wrapping_add(offset.0)), + } + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub struct MemoryKey { + pub location: MemoryLocation, + pub timestamp: Timestamp, +} + +impl std::cmp::PartialOrd for MemoryKey { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl std::cmp::Ord for MemoryKey { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + let tt = self.location.cmp(&other.location); + if tt != std::cmp::Ordering::Equal { + return tt; + } + + let tt = self.timestamp.cmp(&other.timestamp); + if tt != std::cmp::Ordering::Equal { + return tt; + } + + std::cmp::Ordering::Equal + } +} diff --git a/crates/zk_evm/src/aux_structures/queries.rs b/crates/zk_evm/src/aux_structures/queries.rs new file mode 100644 index 0000000..cd15bbb --- /dev/null +++ b/crates/zk_evm/src/aux_structures/queries.rs @@ -0,0 +1,74 @@ +use super::*; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] +pub struct MemoryQuery { + pub timestamp: Timestamp, + pub location: MemoryLocation, + pub rw_flag: bool, + pub is_pended: bool, + pub value_is_pointer: bool, + pub value: U256, +} + +impl MemoryQuery { + pub const fn empty() -> Self { + Self { + timestamp: Timestamp::empty(), + location: MemoryLocation::empty(), + rw_flag: false, + is_pended: false, + value_is_pointer: false, + value: U256::zero(), + } + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] +pub struct LogQuery { + pub timestamp: Timestamp, + pub tx_number_in_block: u16, + pub aux_byte: u8, + pub shard_id: u8, + pub address: Address, + pub key: U256, + pub read_value: U256, + pub written_value: U256, + pub rw_flag: bool, + pub rollback: bool, + pub is_service: bool, +} + +impl LogQuery { + pub fn derive_final_address_for_params(address: &Address, key: &U256) -> [u8; 32] { + let mut buffer = [0u8; 64]; + buffer[12..32].copy_from_slice(&address.0); + key.to_big_endian(&mut buffer[32..64]); + + use blake2::*; + let mut result = [0u8; 32]; + result.copy_from_slice(Blake2s256::digest(&buffer).as_slice()); + + result + } + + pub fn key_derivation_bytes(&self) -> [u8; 64] { + let mut result = [0u8; 64]; + result[12..32].copy_from_slice(&self.address.0); + self.key.to_big_endian(&mut result[32..64]); + + result + } + + pub fn derive_final_address(&self) -> [u8; 32] { + Self::derive_final_address_for_params(&self.address, &self.key) + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] +pub struct DecommittmentQuery { + pub hash: U256, + pub timestamp: Timestamp, + pub memory_page: MemoryPage, + pub decommitted_length: u16, + pub is_fresh: bool, +} diff --git a/crates/zk_evm/src/block_properties/mod.rs b/crates/zk_evm/src/block_properties/mod.rs new file mode 100644 index 0000000..6e7cf28 --- /dev/null +++ b/crates/zk_evm/src/block_properties/mod.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct BlockProperties { + pub default_aa_code_hash: U256, + pub zkporter_is_available: bool, +} diff --git a/crates/zk_evm/src/errors/mod.rs b/crates/zk_evm/src/errors/mod.rs new file mode 100644 index 0000000..d93b068 --- /dev/null +++ b/crates/zk_evm/src/errors/mod.rs @@ -0,0 +1,13 @@ +#[derive(Clone, Copy, Debug)] +pub enum OpcodeDecodingError { + UnknownOpcode, + EncodingIsTooLong, +} + +impl std::fmt::Display for OpcodeDecodingError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> { + write!(f, "{:?}", self) + } +} + +impl std::error::Error for OpcodeDecodingError {} diff --git a/crates/zk_evm/src/flags.rs b/crates/zk_evm/src/flags.rs new file mode 100644 index 0000000..1c8091c --- /dev/null +++ b/crates/zk_evm/src/flags.rs @@ -0,0 +1,56 @@ +use std::fmt::{Debug, Formatter}; + +#[derive(Clone, Copy, PartialEq)] +pub struct Flags { + pub overflow_or_less_than_flag: bool, + pub equality_flag: bool, + pub greater_than_flag: bool, +} + +impl Flags { + pub const fn empty() -> Self { + Self { + overflow_or_less_than_flag: false, + equality_flag: false, + greater_than_flag: false, + } + } + pub fn reset(&mut self) { + self.overflow_or_less_than_flag = false; + self.equality_flag = false; + self.greater_than_flag = false; + } + + pub fn get_set_flags_captions(&self) -> Vec { + let mut res: Vec = vec![]; + if self.overflow_or_less_than_flag { + res.push(String::from("lt")) + } + if self.equality_flag { + res.push(String::from("eq")) + } + if self.greater_than_flag { + res.push(String::from("gt")) + } + res + } +} + +impl Debug for Flags { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + fn bool_to_sym(b: bool) -> &'static str { + if b { + "+" + } else { + "-" + } + } + write!( + f, + "lt{} eq{} gt{}", + bool_to_sym(self.overflow_or_less_than_flag), + bool_to_sym(self.equality_flag), + bool_to_sym(self.greater_than_flag) + ) + } +} diff --git a/crates/zk_evm/src/lib.rs b/crates/zk_evm/src/lib.rs new file mode 100644 index 0000000..0879098 --- /dev/null +++ b/crates/zk_evm/src/lib.rs @@ -0,0 +1,25 @@ +pub mod abstractions; +pub mod aux_structures; +pub mod block_properties; +pub mod errors; +pub mod flags; +pub mod opcodes; +pub mod precompiles; +pub mod reference_impls; +pub mod testing; +pub mod utils; +pub mod vm_state; +pub mod witness_trace; + +pub use self::utils::*; + +pub use zkevm_opcode_defs::{bitflags, ethereum_types}; + +use self::ethereum_types::{Address, U256}; + +pub use zkevm_opcode_defs; + +pub use blake2; +pub use k256; +pub use sha2; +pub use sha3; diff --git a/crates/zk_evm/src/opcodes/execution/add.rs b/crates/zk_evm/src/opcodes/execution/add.rs new file mode 100644 index 0000000..ecbb06a --- /dev/null +++ b/crates/zk_evm/src/opcodes/execution/add.rs @@ -0,0 +1,54 @@ +use super::*; + +impl> DecodedOpcode { + pub fn add_opcode_apply< + S: crate::abstractions::Storage, + M: crate::abstractions::Memory, + EV: crate::abstractions::EventSink, + PP: crate::abstractions::PrecompilesProcessor, + DP: crate::abstractions::DecommittmentProcessor, + WT: crate::witness_trace::VmWitnessTracer, + >( + &self, + vm_state: &mut VmState, + prestate: PreState, + ) { + let PreState { + src0, + src1, + dst0_mem_location, + new_pc, + .. + } = prestate; + let PrimitiveValue { + value: src0, + is_pointer: _, + } = src0; + let PrimitiveValue { + value: src1, + is_pointer: _, + } = src1; + + let set_flags = self.variant.flags[SET_FLAGS_FLAG_IDX]; + vm_state.local_state.callstack.get_current_stack_mut().pc = new_pc; + let (result, of) = src0.overflowing_add(src1); + let eq = result.is_zero(); + let gt = !eq && !of; + + if set_flags { + vm_state.local_state.flags.overflow_or_less_than_flag = of; + vm_state.local_state.flags.equality_flag = eq; + vm_state.local_state.flags.greater_than_flag = gt; + } + let result = PrimitiveValue { + value: result, + is_pointer: false, + }; + vm_state.perform_dst0_update( + vm_state.local_state.monotonic_cycle_counter, + result, + dst0_mem_location, + self, + ); + } +} diff --git a/crates/zk_evm/src/opcodes/execution/binop.rs b/crates/zk_evm/src/opcodes/execution/binop.rs new file mode 100644 index 0000000..fe0f624 --- /dev/null +++ b/crates/zk_evm/src/opcodes/execution/binop.rs @@ -0,0 +1,61 @@ +use super::*; +use zkevm_opcode_defs::{BinopOpcode, Opcode}; + +impl> DecodedOpcode { + pub fn binop_opcode_apply< + S: crate::abstractions::Storage, + M: crate::abstractions::Memory, + EV: crate::abstractions::EventSink, + PP: crate::abstractions::PrecompilesProcessor, + DP: crate::abstractions::DecommittmentProcessor, + WT: crate::witness_trace::VmWitnessTracer, + >( + &self, + vm_state: &mut VmState, + prestate: PreState, + ) { + let PreState { + src0, + src1, + dst0_mem_location, + new_pc, + .. + } = prestate; + let PrimitiveValue { + value: src0, + is_pointer: _, + } = src0; + let PrimitiveValue { + value: src1, + is_pointer: _, + } = src1; + + let inner_variant = match self.variant.opcode { + Opcode::Binop(inner) => inner, + _ => unreachable!(), + }; + let set_flags = self.variant.flags[SET_FLAGS_FLAG_IDX]; + vm_state.local_state.callstack.get_current_stack_mut().pc = new_pc; + // it is always XOR unless flags are set + let result = match inner_variant { + BinopOpcode::Xor => src0 ^ src1, + BinopOpcode::And => src0 & src1, + BinopOpcode::Or => src0 | src1, + }; + if set_flags { + let eq = result.is_zero(); + vm_state.reset_flags(); + vm_state.local_state.flags.equality_flag = eq; + } + let result = PrimitiveValue { + value: result, + is_pointer: false, + }; + vm_state.perform_dst0_update( + vm_state.local_state.monotonic_cycle_counter, + result, + dst0_mem_location, + self, + ); + } +} diff --git a/crates/zk_evm/src/opcodes/execution/context.rs b/crates/zk_evm/src/opcodes/execution/context.rs new file mode 100644 index 0000000..34ace17 --- /dev/null +++ b/crates/zk_evm/src/opcodes/execution/context.rs @@ -0,0 +1,112 @@ +use super::*; + +use zkevm_opcode_defs::{ContextOpcode, Opcode}; + +impl> DecodedOpcode { + pub fn context_opcode_apply< + S: crate::abstractions::Storage, + M: crate::abstractions::Memory, + EV: crate::abstractions::EventSink, + PP: crate::abstractions::PrecompilesProcessor, + DP: crate::abstractions::DecommittmentProcessor, + WT: crate::witness_trace::VmWitnessTracer, + >( + &self, + vm_state: &mut VmState, + prestate: PreState, + ) { + let PreState { + src0, + new_pc, + dst0_mem_location, + .. + } = prestate; + let PrimitiveValue { + value: src0, + is_pointer: _, + } = src0; + let inner_variant = match self.variant.opcode { + Opcode::Context(inner) => inner, + _ => unreachable!(), + }; + vm_state.local_state.callstack.get_current_stack_mut().pc = new_pc; + let current_context = vm_state.local_state.callstack.get_current_stack(); + + // these functions by definition require kernel mode, so we do not need extra checks + if inner_variant == ContextOpcode::SetContextU128 { + vm_state.local_state.context_u128_register = src0.low_u128(); + return; + } + + if inner_variant == ContextOpcode::SetErgsPerPubdataByte { + vm_state.local_state.current_ergs_per_pubdata_byte = src0.low_u32(); + return; + } + + if inner_variant == ContextOpcode::IncrementTxNumber { + vm_state.local_state.tx_number_in_block = + vm_state.local_state.tx_number_in_block.wrapping_add(1); + return; + } + + let value = match inner_variant { + ContextOpcode::This => { + let address = ¤t_context.this_address; + address_to_u256(address) + } + ContextOpcode::Caller => { + let address = ¤t_context.msg_sender; + address_to_u256(address) + } + ContextOpcode::CodeAddress => { + let address = ¤t_context.code_address; + address_to_u256(address) + } + ContextOpcode::Meta => { + use zkevm_opcode_defs::VmMetaParameters; + + let meta = VmMetaParameters { + ergs_per_pubdata_byte: vm_state.local_state.current_ergs_per_pubdata_byte, + this_shard_id: current_context.this_shard_id, + caller_shard_id: current_context.caller_shard_id, + code_shard_id: current_context.code_shard_id, + heap_size: vm_state + .local_state + .callstack + .get_current_stack() + .heap_bound, + aux_heap_size: vm_state + .local_state + .callstack + .get_current_stack() + .aux_heap_bound, + }; + + meta.to_u256() + } + ContextOpcode::ErgsLeft => U256::from(current_context.ergs_remaining as u64), + ContextOpcode::Sp => U256::from(current_context.sp.as_u64()), + ContextOpcode::GetContextU128 => U256::from(current_context.context_u128_value), + ContextOpcode::SetContextU128 => { + unreachable!() + } + ContextOpcode::SetErgsPerPubdataByte => { + unreachable!() + } + ContextOpcode::IncrementTxNumber => { + unreachable!() + } + }; + + let result = PrimitiveValue { + value, + is_pointer: false, + }; + vm_state.perform_dst0_update( + vm_state.local_state.monotonic_cycle_counter, + result, + dst0_mem_location, + self, + ); + } +} diff --git a/crates/zk_evm/src/opcodes/execution/div.rs b/crates/zk_evm/src/opcodes/execution/div.rs new file mode 100644 index 0000000..0ef52d4 --- /dev/null +++ b/crates/zk_evm/src/opcodes/execution/div.rs @@ -0,0 +1,75 @@ +use super::*; + +impl> DecodedOpcode { + pub fn div_opcode_apply< + S: crate::abstractions::Storage, + M: crate::abstractions::Memory, + EV: crate::abstractions::EventSink, + PP: crate::abstractions::PrecompilesProcessor, + DP: crate::abstractions::DecommittmentProcessor, + WT: crate::witness_trace::VmWitnessTracer, + >( + &self, + vm_state: &mut VmState, + prestate: PreState, + ) { + let PreState { + src0, + src1, + dst0_mem_location, + new_pc, + .. + } = prestate; + let PrimitiveValue { + value: src0, + is_pointer: _, + } = src0; + let PrimitiveValue { + value: src1, + is_pointer: _, + } = src1; + let set_flags = self.variant.flags[SET_FLAGS_FLAG_IDX]; + vm_state.local_state.callstack.get_current_stack_mut().pc = new_pc; + if src1.is_zero() { + let of = true; + if set_flags { + vm_state.reset_flags(); + vm_state.local_state.flags.overflow_or_less_than_flag = of; + } + + vm_state.perform_dst0_update( + vm_state.local_state.monotonic_cycle_counter, + PrimitiveValue::empty(), + dst0_mem_location, + self, + ); + vm_state.perform_dst1_update(PrimitiveValue::empty(), self.dst1_reg_idx); + } else { + let (q, r) = src0.div_mod(src1); + if set_flags { + let eq = q.is_zero(); + let gt = r.is_zero(); + + vm_state.reset_flags(); + vm_state.local_state.flags.equality_flag = eq; + vm_state.local_state.flags.greater_than_flag = gt; + } + + let q = PrimitiveValue { + value: q, + is_pointer: false, + }; + vm_state.perform_dst0_update( + vm_state.local_state.monotonic_cycle_counter, + q, + dst0_mem_location, + self, + ); + let r = PrimitiveValue { + value: r, + is_pointer: false, + }; + vm_state.perform_dst1_update(r, self.dst1_reg_idx); + } + } +} diff --git a/crates/zk_evm/src/opcodes/execution/far_call.rs b/crates/zk_evm/src/opcodes/execution/far_call.rs new file mode 100644 index 0000000..da51cc0 --- /dev/null +++ b/crates/zk_evm/src/opcodes/execution/far_call.rs @@ -0,0 +1,580 @@ +use super::*; + +use zkevm_opcode_defs::definitions::far_call::*; +use zkevm_opcode_defs::system_params::DEPLOYER_SYSTEM_CONTRACT_ADDRESS; +use zkevm_opcode_defs::system_params::STORAGE_AUX_BYTE; +use zkevm_opcode_defs::FatPointerValidationException; +use zkevm_opcode_defs::{INITIAL_SP_ON_FAR_CALL, UNMAPPED_PAGE}; + +use zkevm_opcode_defs::bitflags::bitflags; + +bitflags! { + pub struct FarCallExceptionFlags: u64 { + const INPUT_IS_NOT_POINTER_WHEN_EXPECTED = 1u64 << 0; + const INVALID_CODE_HASH_FORMAT = 1u64 << 1; + const NOT_ENOUGH_ERGS_TO_DECOMMIT = 1u64 << 2; + const NOT_ENOUGH_ERGS_TO_GROW_MEMORY = 1u64 << 3; + const MALFORMED_ABI_QUASI_POINTER = 1u64 << 4; + const CALL_IN_NOW_CONSTRUCTED_SYSTEM_CONTRACT = 1u64 << 5; + } +} + +use zkevm_opcode_defs::{FarCallABI, FarCallForwardPageType, FarCallOpcode, FatPointer, Opcode}; + +// Internally FarCall uses all 7 sponges: +// - 1 for decommittment +// - 3 for storage read +// - 3 for callstack manipulation + +impl> DecodedOpcode { + pub fn far_call_opcode_apply< + S: crate::abstractions::Storage, + M: crate::abstractions::Memory, + EV: crate::abstractions::EventSink, + PP: crate::abstractions::PrecompilesProcessor, + DP: crate::abstractions::DecommittmentProcessor, + WT: crate::witness_trace::VmWitnessTracer, + >( + &self, + vm_state: &mut VmState, + prestate: PreState, + ) { + let PreState { + src0, + src1, + new_pc, + is_kernel_mode, + .. + } = prestate; + let inner_variant = match self.variant.opcode { + Opcode::FarCall(inner) => inner, + _ => unreachable!(), + }; + + let PrimitiveValue { + value: abi_src, + is_pointer: abi_src_is_ptr, + } = src0; + let PrimitiveValue { + value: call_destination_value, + is_pointer: _, + } = src1; + + // any call resets flags + vm_state.reset_flags(); + + let is_static_call = self.variant.flags[FAR_CALL_STATIC_FLAG_IDX]; + let is_call_shard = self.variant.flags[FAR_CALL_SHARD_FLAG_IDX]; + + let exception_handler_location = self.imm_0; + // binary interface of parameters passing + + let called_address = u256_to_address_unchecked(&call_destination_value); + let called_address_as_u256 = call_destination_value & *U256_TO_ADDRESS_MASK; + let dst_is_kernel = CallStackEntry::::address_is_kernel(&called_address); + + // ergs, shard_id and calldata + let mut far_call_abi = FarCallABI::from_u256(abi_src); + + // we ignore extra features if not in kernel + far_call_abi.constructor_call = far_call_abi.constructor_call & is_kernel_mode; + far_call_abi.to_system = far_call_abi.to_system & dst_is_kernel; + + let current_stack = vm_state.local_state.callstack.get_current_stack(); + + // read for case of delegatecall + let current_address = current_stack.this_address; + let current_msg_sender = current_stack.msg_sender; + let current_base_page = current_stack.base_memory_page; + let caller_shard_id = current_stack.this_shard_id; + let remaining_ergs = current_stack.ergs_remaining; + let current_context_u128 = current_stack.context_u128_value; + + drop(current_stack); + + let timestamp_for_storage_read = vm_state.timestamp_for_first_decommit_or_precompile_read(); + let tx_number_in_block = vm_state.local_state.tx_number_in_block; + + // we read code from some shard ID + let new_code_shard_id = if is_call_shard { + far_call_abi.shard_id + } else { + caller_shard_id + }; + + // but for contract awareness purposes it may still see an old one (one of the caller) + let new_this_shard_id = if inner_variant == FarCallOpcode::Delegate { + caller_shard_id + } else { + new_code_shard_id + }; + + let new_base_memory_page = vm_state.new_base_memory_page_on_call(); + + // NOTE: our far-call MUST take ergs to cover storage read, but we also have a contribution + // that depends on the actual code length, so we work with it here + let (mapped_code_page, ergs_after_code_read_and_exceptions_resolution) = { + let (code_hash, map_to_trivial) = if new_code_shard_id != 0 + && !vm_state.block_properties.zkporter_is_available + { + // we do NOT mask it into default AA here + // and for now formally jump to the page containing zeroes + + (U256::zero(), true) + } else { + let partial_query = LogQuery { + timestamp: timestamp_for_storage_read, + tx_number_in_block, + aux_byte: STORAGE_AUX_BYTE, + shard_id: new_code_shard_id, + address: *DEPLOYER_SYSTEM_CONTRACT_ADDRESS, + key: called_address_as_u256, + read_value: U256::zero(), + written_value: U256::zero(), + rw_flag: false, + rollback: false, + is_service: false, + }; + let query = vm_state + .access_storage(vm_state.local_state.monotonic_cycle_counter, partial_query); + + vm_state.witness_tracer.add_sponge_marker( + vm_state.local_state.monotonic_cycle_counter, + SpongeExecutionMarker::StorageLogReadOnly, + 1..4, + true, + ); + let code_hash_from_storage = query.read_value; + + // mask for default AA + let mask_into_default_aa = + code_hash_from_storage.is_zero() && dst_is_kernel == false; + let code_hash = if mask_into_default_aa { + vm_state.block_properties.default_aa_code_hash + } else { + code_hash_from_storage + }; + + (code_hash, false) + }; + + let memory_page_candidate_for_code_decommittment = if map_to_trivial == true { + MemoryPage(UNMAPPED_PAGE) + } else { + CallStackEntry::::code_page_candidate_from_base(new_base_memory_page) + }; + + // now we handle potential exceptions + + use zkevm_opcode_defs::{ContractCodeSha256, VersionedHashGeneric}; + + let mut buffer = [0u8; 32]; + code_hash.to_big_endian(&mut buffer); + + let mut exceptions = FarCallExceptionFlags::empty(); + + // now let's check if code format "makes sense" + let (code_hash, code_length_in_words) = if let Some(versioned_hash) = + VersionedHashGeneric::::try_create_from_raw(buffer) + { + // code is in proper format, let's check other markers + + let layout = versioned_hash.layout_ref(); + + let code_marker = layout.extra_marker; + + let code_marker_is_at_rest = code_marker == ContractCodeSha256::CODE_AT_REST_MARKER; + let code_marker_is_constructed_now = + code_marker == ContractCodeSha256::YET_CONSTRUCTED_MARKER; + + let code_marker_is_valid = code_marker_is_at_rest || code_marker_is_constructed_now; + + if code_marker_is_valid == false { + // code marker is generally invalid + exceptions.set(FarCallExceptionFlags::INVALID_CODE_HASH_FORMAT, true); + + (U256::zero(), 0u32) + } else { + // it's valid in general, so do the constructor masking work + let code_hash_at_storage = versioned_hash + .serialize_to_stored() + .map(|arr| U256::from_big_endian(&arr)) + .expect("Failed to serialize a valid hash"); + + let can_call_at_rest = !far_call_abi.constructor_call && code_marker_is_at_rest; + let can_call_by_constructor = + far_call_abi.constructor_call && code_marker_is_constructed_now; + + let can_call_code_without_masking = can_call_at_rest || can_call_by_constructor; + if can_call_code_without_masking == true { + // true values + (code_hash_at_storage, layout.code_length_in_words as u32) + } else { + // calling mode is unknown, so it's most likely a normal + // call to contract that is still created + if dst_is_kernel == false { + // still degrade to default AA + let mut buffer = [0u8; 32]; + vm_state + .block_properties + .default_aa_code_hash + .to_big_endian(&mut buffer); + let versioned_hash = + VersionedHashGeneric::::try_create_from_raw( + buffer, + ) + .expect("default AA code hash must be always valid"); + let layout = versioned_hash.layout_ref(); + let code_marker = layout.extra_marker; + assert!( + code_marker == ContractCodeSha256::CODE_AT_REST_MARKER, + "default AA marker is always in storage format" + ); + + ( + vm_state.block_properties.default_aa_code_hash, + layout.code_length_in_words as u32, + ) + } else { + // we should not decommit 0, so it's an exception + exceptions.set( + FarCallExceptionFlags::CALL_IN_NOW_CONSTRUCTED_SYSTEM_CONTRACT, + true, + ); + (U256::zero(), 0u32) + } + } + } + } else { + exceptions.set(FarCallExceptionFlags::INVALID_CODE_HASH_FORMAT, true); + // we still return placeholders + (U256::zero(), 0u32) + }; + + // we also use code hash as an exception hatch here + if far_call_abi.forwarding_mode == FarCallForwardPageType::ForwardFatPointer { + if abi_src_is_ptr == false { + exceptions.set( + FarCallExceptionFlags::INPUT_IS_NOT_POINTER_WHEN_EXPECTED, + true, + ); + } + } + + // validate that fat pointer (one a future one) we formed is somewhat valid + let validate_as_fresh = + far_call_abi.forwarding_mode != FarCallForwardPageType::ForwardFatPointer; + + // NOTE: one can not properly address a range [2^32 - 32..2^32] here, but we never care in practice about this case + // as one can not ever pay to grow memory to such extent + + let pointer_validation_exceptions = far_call_abi + .memory_quasi_fat_pointer + .validate(validate_as_fresh); + + if pointer_validation_exceptions.is_empty() == false { + // pointer is malformed + exceptions.set(FarCallExceptionFlags::MALFORMED_ABI_QUASI_POINTER, true); + } + if far_call_abi.memory_quasi_fat_pointer.validate_in_bounds() == false + && far_call_abi.memory_quasi_fat_pointer.is_trivial() == false + { + exceptions.set(FarCallExceptionFlags::MALFORMED_ABI_QUASI_POINTER, true); + } + + // these modifications we can do already as all pointer formal validity related things are done + match far_call_abi.forwarding_mode { + FarCallForwardPageType::ForwardFatPointer => { + // We can formally shrink the pointer + // If it was malformed then we masked and overflows can not happen + let new_start = far_call_abi + .memory_quasi_fat_pointer + .start + .wrapping_add(far_call_abi.memory_quasi_fat_pointer.offset); + let new_length = far_call_abi + .memory_quasi_fat_pointer + .length + .wrapping_sub(far_call_abi.memory_quasi_fat_pointer.offset); + + far_call_abi.memory_quasi_fat_pointer.start = new_start; + far_call_abi.memory_quasi_fat_pointer.length = new_length; + far_call_abi.memory_quasi_fat_pointer.offset = 0; + } + FarCallForwardPageType::UseHeap => { + let owned_page = + CallStackEntry::::heap_page_from_base(current_base_page).0; + + far_call_abi.memory_quasi_fat_pointer.memory_page = owned_page; + } + FarCallForwardPageType::UseAuxHeap => { + let owned_page = + CallStackEntry::::aux_heap_page_from_base(current_base_page).0; + + far_call_abi.memory_quasi_fat_pointer.memory_page = owned_page; + } + }; + + if exceptions.is_empty() == false { + far_call_abi.memory_quasi_fat_pointer = FatPointer::empty(); + // even though we will not pay for memory resize, + // we do not care + } + + let current_stack_mut = vm_state.local_state.callstack.get_current_stack_mut(); + + // potentially pay for memory growth + let memory_growth_in_bytes = match far_call_abi.forwarding_mode { + a @ FarCallForwardPageType::UseHeap | a @ FarCallForwardPageType::UseAuxHeap => { + // pointer is already validated, so we do not need to check that start + length do not overflow + let mut upper_bound = far_call_abi.memory_quasi_fat_pointer.start + + far_call_abi.memory_quasi_fat_pointer.length; + + let penalize_out_of_bounds_growth = pointer_validation_exceptions + .contains(FatPointerValidationException::DEREF_BEYOND_HEAP_RANGE); + if penalize_out_of_bounds_growth { + upper_bound = u32::MAX; + } + + let current_bound = if a == FarCallForwardPageType::UseHeap { + current_stack_mut.heap_bound + } else if a == FarCallForwardPageType::UseAuxHeap { + current_stack_mut.aux_heap_bound + } else { + unreachable!(); + }; + let (mut diff, uf) = upper_bound.overflowing_sub(current_bound); + if uf { + // heap bound is already beyond what we pass + diff = 0u32; + } else { + // save new upper bound in context. + // Note that we are ok so save even penalizing upper bound because we will burn + // all the ergs in this frame anyway, and no further resizes are possible + if a == FarCallForwardPageType::UseHeap { + current_stack_mut.heap_bound = upper_bound; + } else if a == FarCallForwardPageType::UseAuxHeap { + current_stack_mut.aux_heap_bound = upper_bound; + } else { + unreachable!(); + } + } + + diff + } + FarCallForwardPageType::ForwardFatPointer => 0u32, + }; + + drop(current_stack_mut); + + // MEMORY_GROWTH_ERGS_PER_BYTE is always 1 + let cost_of_memory_growth = + memory_growth_in_bytes.wrapping_mul(zkevm_opcode_defs::MEMORY_GROWTH_ERGS_PER_BYTE); + let remaining_ergs_after_growth = if remaining_ergs >= cost_of_memory_growth { + remaining_ergs - cost_of_memory_growth + } else { + exceptions.set(FarCallExceptionFlags::NOT_ENOUGH_ERGS_TO_GROW_MEMORY, true); + // we do not need to mask fat pointer, as we will jump to the page number 0, + // that can not even read it + + 0 + }; + + // we mask instead of branching + let cost_of_decommittment = + zkevm_opcode_defs::ERGS_PER_CODE_WORD_DECOMMITTMENT * code_length_in_words; + + let mut remaining_ergs_after_decommittment = + if remaining_ergs_after_growth >= cost_of_decommittment { + remaining_ergs_after_growth - cost_of_decommittment + } else { + exceptions.set(FarCallExceptionFlags::NOT_ENOUGH_ERGS_TO_DECOMMIT, true); + + remaining_ergs_after_growth // do not burn, as it's irrelevant - we just will not perform a decommittment and call + }; + + let code_memory_page = if exceptions.is_empty() == false { + vm_state.set_shorthand_panic(); + + // we also do not return back cost of decommittment as it wasn't subtracted + MemoryPage(UNMAPPED_PAGE) + } else { + let timestamp_for_decommit = + vm_state.timestamp_for_first_decommit_or_precompile_read(); + let processed_decommittment_query = vm_state.decommit( + vm_state.local_state.monotonic_cycle_counter, + code_hash, + memory_page_candidate_for_code_decommittment, + timestamp_for_decommit, + ); + vm_state.witness_tracer.add_sponge_marker( + vm_state.local_state.monotonic_cycle_counter, + SpongeExecutionMarker::DecommittmentQuery, + 4..5, + true, + ); + + if processed_decommittment_query.is_fresh == false { + // refund + remaining_ergs_after_decommittment += cost_of_decommittment; + } + + processed_decommittment_query.memory_page + }; + + (code_memory_page, remaining_ergs_after_decommittment) + }; + + // resolve passed ergs, by using a value afte decommittment cost is taken + let remaining_ergs_to_pass = ergs_after_code_read_and_exceptions_resolution; + let max_passable = (remaining_ergs_to_pass / 64) * 63; // so callee will always have some + let leftover = remaining_ergs_to_pass - max_passable; + // for exception handling + let (passed_ergs, remaining_ergs_for_this_context) = { + let (remaining_from_max_passable, uf) = + max_passable.overflowing_sub(far_call_abi.ergs_passed); + if uf { + // pass max(passable, want to pass) + (max_passable, leftover) + } else { + ( + far_call_abi.ergs_passed, + leftover + remaining_from_max_passable, + ) + } + }; + + // update current ergs and PC + vm_state + .local_state + .callstack + .get_current_stack_mut() + .ergs_remaining = remaining_ergs_for_this_context; + vm_state.local_state.callstack.get_current_stack_mut().pc = new_pc; + + let current_stack = vm_state.local_state.callstack.get_current_stack(); + + // compute if call is static either by modifier or + let new_context_is_static = current_stack.is_static | is_static_call; + + // no matter if we did execute a query or not, we need to save context at worst + vm_state.local_state.pending_port.pending_type = Some(PendingType::FarCall); + + vm_state.increment_memory_pages_on_call(); + + // read address for mimic_call + let implicit_reg = + &vm_state.local_state.registers[CALL_IMPLICIT_PARAMETER_REG_IDX as usize]; + let address_from_implicit_reg = u256_to_address_unchecked(&implicit_reg.value); + + let (address_for_next, msg_sender_for_next) = match inner_variant { + FarCallOpcode::Normal => { + // we set that caller of next == this + (called_address, current_address) + } + FarCallOpcode::Delegate => { + // save current address for context purposes + (current_address, current_msg_sender) + } + FarCallOpcode::Mimic => { + // we pretent to be calling from some address + (called_address, address_from_implicit_reg) + } + }; + let code_address_for_next = called_address; + + let context_u128_for_next = match inner_variant { + FarCallOpcode::Normal | FarCallOpcode::Mimic => { + // we set that caller of next == this + vm_state.local_state.context_u128_register + } + FarCallOpcode::Delegate => { + // save current address for context purposes + current_context_u128 + } + }; + + let new_stack = CallStackEntry { + this_address: address_for_next, + msg_sender: msg_sender_for_next, + code_address: code_address_for_next, + base_memory_page: new_base_memory_page, + code_page: mapped_code_page, + sp: E::PcOrImm::from_u64_clipped(INITIAL_SP_ON_FAR_CALL), + pc: E::PcOrImm::from_u64_clipped(0u64), + exception_handler_location: exception_handler_location, + ergs_remaining: passed_ergs, + this_shard_id: new_this_shard_id, + caller_shard_id, + code_shard_id: new_code_shard_id, + is_static: new_context_is_static, + is_local_frame: false, + context_u128_value: context_u128_for_next, + heap_bound: 0u32, + aux_heap_bound: 0u32, + }; + + // zero out the temporary register if it was not trivial + vm_state.local_state.context_u128_register = 0; + + // perform some extra steps to ensure that our rollbacks are properly written and saved + // both in storage and for witness + vm_state.start_frame(vm_state.local_state.monotonic_cycle_counter, new_stack); + + vm_state.memory.start_global_frame( + current_base_page, + new_base_memory_page, + far_call_abi.memory_quasi_fat_pointer, + Timestamp(vm_state.local_state.timestamp), + ); + + vm_state.witness_tracer.add_sponge_marker( + vm_state.local_state.monotonic_cycle_counter, + SpongeExecutionMarker::CallstackPush, + 5..8, + true, + ); + // mark the jump to refresh the memory word + vm_state.local_state.did_call_or_ret_recently = true; + + // write down calldata information + + let r1_value = PrimitiveValue { + value: far_call_abi.memory_quasi_fat_pointer.to_u256(), + is_pointer: true, + }; + vm_state.local_state.registers[CALL_IMPLICIT_CALLDATA_FAT_PTR_REGISTER as usize] = r1_value; + + let mut r2_value = U256::zero(); + if far_call_abi.constructor_call { + r2_value.0[0] |= 1u64; + } + if far_call_abi.to_system { + r2_value.0[0] |= 1u64 << 1; + } + + vm_state.local_state.registers[CALL_IMPLICIT_CONSTRUCTOR_MARKER_REGISTER as usize] = + PrimitiveValue { + value: r2_value, + is_pointer: false, + }; + + if far_call_abi.to_system == false { + for reg_idx in CALL_SYSTEM_ABI_REGISTERS { + // if it's not a call to the system then we zero out those registers + vm_state.local_state.registers[reg_idx as usize] = PrimitiveValue::empty(); + } + } else { + for reg_idx in CALL_SYSTEM_ABI_REGISTERS { + // remove "ptr" markers + vm_state.local_state.registers[reg_idx as usize].is_pointer = false; + } + } + + // ALL other registers are zeroed out! + for reg_idx in CALL_RESERVED_RANGE { + vm_state.local_state.registers[reg_idx as usize] = PrimitiveValue::empty(); + } + vm_state.local_state.registers[CALL_IMPLICIT_PARAMETER_REG_IDX as usize] = + PrimitiveValue::empty(); + } +} diff --git a/crates/zk_evm/src/opcodes/execution/jump.rs b/crates/zk_evm/src/opcodes/execution/jump.rs new file mode 100644 index 0000000..f265de1 --- /dev/null +++ b/crates/zk_evm/src/opcodes/execution/jump.rs @@ -0,0 +1,27 @@ +use super::*; + +impl> DecodedOpcode { + pub fn jump_opcode_apply< + S: crate::abstractions::Storage, + M: crate::abstractions::Memory, + EV: crate::abstractions::EventSink, + PP: crate::abstractions::PrecompilesProcessor, + DP: crate::abstractions::DecommittmentProcessor, + WT: crate::witness_trace::VmWitnessTracer, + >( + &self, + vm_state: &mut VmState, + prestate: PreState, + ) { + let PreState { + new_pc: _, src0, .. + } = prestate; + let PrimitiveValue { + value: src0, + is_pointer: _, + } = src0; + // we use lowest 16 bits of src0 as a jump destination + let dest_pc = E::PcOrImm::from_u64_clipped(src0.low_u64()); + vm_state.local_state.callstack.get_current_stack_mut().pc = dest_pc; + } +} diff --git a/crates/zk_evm/src/opcodes/execution/log.rs b/crates/zk_evm/src/opcodes/execution/log.rs new file mode 100644 index 0000000..26d2a47 --- /dev/null +++ b/crates/zk_evm/src/opcodes/execution/log.rs @@ -0,0 +1,361 @@ +use super::*; + +use zkevm_opcode_defs::{ + LogOpcode, Opcode, PrecompileCallABI, PrecompileCallInnerABI, FIRST_MESSAGE_FLAG_IDX, +}; + +use zkevm_opcode_defs::system_params::{ + EVENT_AUX_BYTE, L1_MESSAGE_AUX_BYTE, PRECOMPILE_AUX_BYTE, STORAGE_AUX_BYTE, +}; + +impl> DecodedOpcode { + pub fn log_opcode_apply< + S: crate::abstractions::Storage, + M: crate::abstractions::Memory, + EV: crate::abstractions::EventSink, + PP: crate::abstractions::PrecompilesProcessor, + DP: crate::abstractions::DecommittmentProcessor, + WT: crate::witness_trace::VmWitnessTracer, + >( + &self, + vm_state: &mut VmState, + prestate: PreState, + ) { + let PreState { + src0, + src1, + dst0_mem_location, + new_pc, + .. + } = prestate; + let PrimitiveValue { + value: src0, + is_pointer: _, + } = src0; + let PrimitiveValue { + value: src1, + is_pointer: _, + } = src1; + let inner_variant = match self.variant.opcode { + Opcode::Log(inner) => inner, + _ => unreachable!(), + }; + vm_state.local_state.callstack.get_current_stack_mut().pc = new_pc; + let is_first_message = self.variant.flags[FIRST_MESSAGE_FLAG_IDX]; + + // this is the only case where we do extra checking for costs as it's related to pubdata + // and shard_id + + // We do it as the following: + // - check if we have enough + // - if not - just set remaining ergs to 0 (that will cause an exception on the next cycle) + // - DO NOT set any pending + // - return + + // ergs exception handling + let shard_id = vm_state + .local_state + .callstack + .get_current_stack() + .this_shard_id; + let ergs_available = vm_state + .local_state + .callstack + .get_current_stack() + .ergs_remaining; + let is_rollup = shard_id == 0; + + let ergs_on_pubdata = match inner_variant { + LogOpcode::StorageWrite => { + let key = src0; + let written_value = src1; + + let current_context = vm_state.local_state.callstack.get_current_stack(); + let address = current_context.this_address; + let shard_id = current_context.this_shard_id; + drop(current_context); + + // we do not need all the values here, but we DO need the written value + // for oracle to do estimations + + let partial_query = LogQuery { + timestamp: Timestamp(0u32), + tx_number_in_block: 0u16, + aux_byte: STORAGE_AUX_BYTE, + shard_id, + address, + key, + read_value: U256::zero(), + written_value, + rw_flag: true, + rollback: false, + is_service: false, + }; + + let refund = vm_state.refund_for_partial_query( + vm_state.local_state.monotonic_cycle_counter, + &partial_query, + ); + let pubdata_refund = refund.pubdata_refund(); + + let net_pubdata = if is_rollup { + let (net_cost, uf) = + (zkevm_opcode_defs::system_params::INITIAL_STORAGE_WRITE_PUBDATA_BYTES + as u32) + .overflowing_sub(pubdata_refund); + assert!(uf == false, "refund can not be more than net cost itself"); + + net_cost + } else { + assert_eq!(pubdata_refund, 0); + + 0 + }; + + vm_state.local_state.current_ergs_per_pubdata_byte * net_pubdata + } + LogOpcode::ToL1Message => { + vm_state.local_state.current_ergs_per_pubdata_byte + * zkevm_opcode_defs::system_params::L1_MESSAGE_PUBDATA_BYTES + } + _ => 0, + }; + + let extra_cost = match inner_variant { + LogOpcode::PrecompileCall => src1.low_u32(), + _ => 0, + }; + + let total_cost = extra_cost + ergs_on_pubdata; + + let (ergs_remaining, not_enough_power) = ergs_available.overflowing_sub(total_cost); + if not_enough_power { + vm_state + .local_state + .callstack + .get_current_stack_mut() + .ergs_remaining = 0; + + vm_state.local_state.spent_pubdata_counter += + std::cmp::min(ergs_available, ergs_on_pubdata); + } else { + vm_state + .local_state + .callstack + .get_current_stack_mut() + .ergs_remaining = ergs_remaining; + + vm_state.local_state.spent_pubdata_counter += ergs_on_pubdata; + } + + let current_context = vm_state.local_state.callstack.get_current_stack(); + let address = current_context.this_address; + let shard_id = current_context.this_shard_id; + drop(current_context); + let tx_number_in_block = vm_state.local_state.tx_number_in_block; + let timestamp_for_log = vm_state.timestamp_for_first_decommit_or_precompile_read(); + match inner_variant { + LogOpcode::StorageRead => { + assert!(not_enough_power == false); + let key = src0; + + let partial_query = LogQuery { + timestamp: timestamp_for_log, + tx_number_in_block, + aux_byte: STORAGE_AUX_BYTE, + shard_id, + address, + key, + read_value: U256::zero(), + written_value: U256::zero(), + rw_flag: false, + rollback: false, + is_service: is_first_message, + }; + + // we do not expect refunds for reads yet + let query = vm_state + .access_storage(vm_state.local_state.monotonic_cycle_counter, partial_query); + vm_state.witness_tracer.add_sponge_marker( + vm_state.local_state.monotonic_cycle_counter, + SpongeExecutionMarker::StorageLogReadOnly, + 1..4, + false, + ); + let result = PrimitiveValue { + value: query.read_value, + is_pointer: false, + }; + vm_state.perform_dst0_update( + vm_state.local_state.monotonic_cycle_counter, + result, + dst0_mem_location, + self, + ); + } + LogOpcode::StorageWrite => { + if not_enough_power { + // we can return immediatelly and do not need to update regs + return; + } + let key = src0; + let written_value = src1; + + let partial_query = LogQuery { + timestamp: timestamp_for_log, + tx_number_in_block, + aux_byte: STORAGE_AUX_BYTE, + shard_id, + address, + key, + read_value: U256::zero(), + written_value, + rw_flag: true, + rollback: false, + is_service: is_first_message, + }; + + // we still do a formal query to execute write and record witness + let _query = vm_state + .access_storage(vm_state.local_state.monotonic_cycle_counter, partial_query); + + vm_state.witness_tracer.add_sponge_marker( + vm_state.local_state.monotonic_cycle_counter, + SpongeExecutionMarker::StorageLogWrite, + 1..5, + true, + ); + vm_state.local_state.pending_port.pending_type = Some(PendingType::WriteLog); + } + variant @ LogOpcode::Event | variant @ LogOpcode::ToL1Message => { + if not_enough_power { + assert_eq!(variant, LogOpcode::ToL1Message); + // we do not add anything into log and do not need to update + // registers + return; + } + let key = src0; + let written_value = src1; + + let aux_byte = if variant == LogOpcode::Event { + EVENT_AUX_BYTE + } else { + L1_MESSAGE_AUX_BYTE + }; + + let query = LogQuery { + timestamp: timestamp_for_log, + tx_number_in_block, + aux_byte, + shard_id, + address, + key, + read_value: U256::zero(), + written_value, + rw_flag: true, + rollback: false, + is_service: is_first_message, + }; + vm_state.emit_event(vm_state.local_state.monotonic_cycle_counter, query); + vm_state.local_state.pending_port.pending_type = Some(PendingType::WriteLog); + vm_state.witness_tracer.add_sponge_marker( + vm_state.local_state.monotonic_cycle_counter, + SpongeExecutionMarker::StorageLogWrite, + 1..5, + true, + ); + } + LogOpcode::PrecompileCall => { + // add extra information about precompile abi in the "key" field + + if not_enough_power { + // we have to update register + vm_state.perform_dst0_update( + vm_state.local_state.monotonic_cycle_counter, + PrimitiveValue::empty(), + dst0_mem_location, + &self, + ); + return; + } + + let precompile_abi = PrecompileCallABI::from_u256(src0); + let PrecompileCallABI { + input_memory_offset, + input_memory_length, + output_memory_offset, + output_memory_length, + per_precompile_interpreted, + } = precompile_abi; + + // normal execution + vm_state + .local_state + .callstack + .get_current_stack_mut() + .ergs_remaining = ergs_remaining; + let memory_page_to_read = CallStackEntry::::heap_page_from_base( + vm_state + .local_state + .callstack + .get_current_stack() + .base_memory_page, + ); + let memory_page_to_write = CallStackEntry::::heap_page_from_base( + vm_state + .local_state + .callstack + .get_current_stack() + .base_memory_page, + ); + + let timestamp_to_read = vm_state.timestamp_for_first_decommit_or_precompile_read(); + let timestamp_to_write = + vm_state.timestamp_for_second_decommit_or_precompile_write(); + assert!(timestamp_to_read.0 + 1 == timestamp_to_write.0); + + let precompile_inner_abi = PrecompileCallInnerABI { + input_memory_offset, + input_memory_length, + output_memory_offset, + output_memory_length, + memory_page_to_read: memory_page_to_read.0, + memory_page_to_write: memory_page_to_write.0, + precompile_interpreted_data: per_precompile_interpreted, + }; + let precompile_inner_abi = precompile_inner_abi.to_u256(); + + let query = LogQuery { + timestamp: timestamp_for_log, + tx_number_in_block, + aux_byte: PRECOMPILE_AUX_BYTE, + shard_id, + address, + key: precompile_inner_abi, + read_value: U256::zero(), + written_value: U256::zero(), + rw_flag: false, + rollback: false, + is_service: is_first_message, + }; + vm_state.call_precompile(vm_state.local_state.monotonic_cycle_counter, query); + vm_state.witness_tracer.add_sponge_marker( + vm_state.local_state.monotonic_cycle_counter, + SpongeExecutionMarker::StorageLogReadOnly, + 1..4, + false, + ); + let result = PrimitiveValue { + value: U256::from(1u64), + is_pointer: false, + }; + vm_state.perform_dst0_update( + vm_state.local_state.monotonic_cycle_counter, + result, + dst0_mem_location, + &self, + ); + } + } + } +} diff --git a/crates/zk_evm/src/opcodes/execution/mod.rs b/crates/zk_evm/src/opcodes/execution/mod.rs new file mode 100644 index 0000000..31a47d7 --- /dev/null +++ b/crates/zk_evm/src/opcodes/execution/mod.rs @@ -0,0 +1,24 @@ +use super::*; +use crate::abstractions::SpongeExecutionMarker; +use crate::aux_structures::*; +use crate::vm_state::*; +use zkevm_opcode_defs::decoding::AllowedPcOrImm; +use zkevm_opcode_defs::decoding::VmEncodingMode; + +use zkevm_opcode_defs::SET_FLAGS_FLAG_IDX; + +pub mod add; +pub mod binop; +pub mod context; +pub mod div; +pub mod far_call; +pub mod jump; +pub mod log; +pub mod mul; +pub mod near_call; +pub mod noop; +pub mod ptr; +pub mod ret; +pub mod shift; +pub mod sub; +pub mod uma; diff --git a/crates/zk_evm/src/opcodes/execution/mul.rs b/crates/zk_evm/src/opcodes/execution/mul.rs new file mode 100644 index 0000000..6ba3526 --- /dev/null +++ b/crates/zk_evm/src/opcodes/execution/mul.rs @@ -0,0 +1,65 @@ +use super::*; + +impl> DecodedOpcode { + pub fn mul_opcode_apply< + S: crate::abstractions::Storage, + M: crate::abstractions::Memory, + EV: crate::abstractions::EventSink, + PP: crate::abstractions::PrecompilesProcessor, + DP: crate::abstractions::DecommittmentProcessor, + WT: crate::witness_trace::VmWitnessTracer, + >( + &self, + vm_state: &mut VmState, + prestate: PreState, + ) { + let PreState { + src0, + src1, + dst0_mem_location, + new_pc, + .. + } = prestate; + let PrimitiveValue { + value: src0, + is_pointer: _, + } = src0; + let PrimitiveValue { + value: src1, + is_pointer: _, + } = src1; + let set_flags = self.variant.flags[SET_FLAGS_FLAG_IDX]; + vm_state.local_state.callstack.get_current_stack_mut().pc = new_pc; + let tmp = src0.full_mul(src1).0; + let mut low = U256::zero(); + low.0 = [tmp[0], tmp[1], tmp[2], tmp[3]]; + let mut high = U256::zero(); + high.0 = [tmp[4], tmp[5], tmp[6], tmp[7]]; + + if set_flags { + let of = !high.is_zero(); + let eq = low.is_zero(); + + vm_state.reset_flags(); + vm_state.local_state.flags.overflow_or_less_than_flag = of; + vm_state.local_state.flags.equality_flag = eq; + vm_state.local_state.flags.greater_than_flag = !of & !eq; + } + + let low = PrimitiveValue { + value: low, + is_pointer: false, + }; + vm_state.perform_dst0_update( + vm_state.local_state.monotonic_cycle_counter, + low, + dst0_mem_location, + self, + ); + let high = PrimitiveValue { + value: high, + is_pointer: false, + }; + vm_state.perform_dst1_update(high, self.dst1_reg_idx); + } +} diff --git a/crates/zk_evm/src/opcodes/execution/near_call.rs b/crates/zk_evm/src/opcodes/execution/near_call.rs new file mode 100644 index 0000000..3b680da --- /dev/null +++ b/crates/zk_evm/src/opcodes/execution/near_call.rs @@ -0,0 +1,75 @@ +use zkevm_opcode_defs::NearCallABI; + +use super::*; + +impl> DecodedOpcode { + pub fn near_call_opcode_apply< + S: crate::abstractions::Storage, + M: crate::abstractions::Memory, + EV: crate::abstractions::EventSink, + PP: crate::abstractions::PrecompilesProcessor, + DP: crate::abstractions::DecommittmentProcessor, + WT: crate::witness_trace::VmWitnessTracer, + >( + &self, + vm_state: &mut VmState, + prestate: PreState, + ) { + let PreState { src0, new_pc, .. } = prestate; + let PrimitiveValue { + value: src0, + is_pointer: _, + } = src0; + // reset flags + vm_state.reset_flags(); + + // proceed with call + let dst = self.imm_0; + let exception_handler_location = self.imm_1; + let near_call_abi = NearCallABI::from_u256(src0); + + // resolve passed ergs + let pass_all_ergs = near_call_abi.ergs_passed == 0; + let current_callstack_entry = vm_state.local_state.callstack.get_current_stack(); + let remaining_ergs = current_callstack_entry.ergs_remaining; + let (passed_ergs, remaining_ergs_for_this_context) = if pass_all_ergs { + (remaining_ergs, 0u32) + } else { + let (remaining_for_this_context, uf) = + remaining_ergs.overflowing_sub(near_call_abi.ergs_passed); + if uf { + // pass max(remaining, want to pass) + (remaining_ergs, 0u32) + } else { + (near_call_abi.ergs_passed, remaining_for_this_context) + } + }; + + // update current ergs and PC + vm_state + .local_state + .callstack + .get_current_stack_mut() + .ergs_remaining = remaining_ergs_for_this_context; + vm_state.local_state.callstack.get_current_stack_mut().pc = new_pc; + + let current_stack = vm_state.local_state.callstack.get_current_stack(); + // we only need to change a PC and formally start a new context + + let mut new_stack = current_stack.clone(); + new_stack.pc = dst; + new_stack.exception_handler_location = exception_handler_location; + new_stack.ergs_remaining = passed_ergs; + new_stack.is_local_frame = true; + + // perform some extra steps to ensure that our rollbacks are properly written and saved + // both in storage and for witness + vm_state.start_frame(vm_state.local_state.monotonic_cycle_counter, new_stack); + vm_state.witness_tracer.add_sponge_marker( + vm_state.local_state.monotonic_cycle_counter, + SpongeExecutionMarker::CallstackPush, + 1..4, + false, + ); + } +} diff --git a/crates/zk_evm/src/opcodes/execution/noop.rs b/crates/zk_evm/src/opcodes/execution/noop.rs new file mode 100644 index 0000000..d4b95ed --- /dev/null +++ b/crates/zk_evm/src/opcodes/execution/noop.rs @@ -0,0 +1,21 @@ +use super::*; + +impl> DecodedOpcode { + pub fn noop_opcode_apply< + S: crate::abstractions::Storage, + M: crate::abstractions::Memory, + EV: crate::abstractions::EventSink, + PP: crate::abstractions::PrecompilesProcessor, + DP: crate::abstractions::DecommittmentProcessor, + WT: crate::witness_trace::VmWitnessTracer, + >( + &self, + vm_state: &mut VmState, + prestate: PreState, + ) { + let PreState { new_pc, .. } = prestate; + vm_state.local_state.callstack.get_current_stack_mut().pc = new_pc; + // IMPORTANT: while we formally do not update the register value here, the NOP operation + // may still formally address the operand and move SP this way + } +} diff --git a/crates/zk_evm/src/opcodes/execution/ptr.rs b/crates/zk_evm/src/opcodes/execution/ptr.rs new file mode 100644 index 0000000..c2b548a --- /dev/null +++ b/crates/zk_evm/src/opcodes/execution/ptr.rs @@ -0,0 +1,195 @@ +use super::*; + +use zkevm_opcode_defs::{FatPointer, Opcode, PtrOpcode}; + +impl> DecodedOpcode { + pub fn ptr_opcode_apply< + S: crate::abstractions::Storage, + M: crate::abstractions::Memory, + EV: crate::abstractions::EventSink, + PP: crate::abstractions::PrecompilesProcessor, + DP: crate::abstractions::DecommittmentProcessor, + WT: crate::witness_trace::VmWitnessTracer, + >( + &self, + vm_state: &mut VmState, + prestate: PreState, + ) { + let PreState { + src0, + src1, + dst0_mem_location, + new_pc, + .. + } = prestate; + let inner_variant = match self.variant.opcode { + Opcode::Ptr(inner) => inner, + _ => unreachable!(), + }; + + vm_state.local_state.callstack.get_current_stack_mut().pc = new_pc; + + match inner_variant { + a @ PtrOpcode::Add | a @ PtrOpcode::Sub => { + // we check whether src0 is fat pointer + if src0.is_pointer == false { + // src0 is not a pointer + vm_state.set_shorthand_panic(); + return; + } + + if src1.is_pointer == true { + // can not have ptr + ptr + vm_state.set_shorthand_panic(); + return; + } + + if src1.value >= zkevm_opcode_defs::ptr::MAX_OFFSET_FOR_ADD_SUB { + // offset is too far to be reasonable, so instead of wrapping behavior we bail out + vm_state.set_shorthand_panic(); + return; + } + + let PrimitiveValue { + value: src0, + is_pointer: _, + } = src0; + let PrimitiveValue { + value: src1, + is_pointer: _, + } = src1; + + let fat_ptr = FatPointer::from_u256(src0); + let offset = src1.low_u32(); + + let (new_ptr_offset, error) = if a == PtrOpcode::Add { + fat_ptr.offset.overflowing_add(offset) + } else { + fat_ptr.offset.overflowing_sub(offset) + }; + + if error { + vm_state.set_shorthand_panic(); + return; + } + + let mut new_ptr = fat_ptr; + new_ptr.offset = new_ptr_offset; + + let ptr_as_u256 = new_ptr.to_u256(); + + // low 128 bits from ptr_as_u256, high 128 - from src0 + let result = U256([ptr_as_u256.0[0], ptr_as_u256.0[1], src0.0[2], src0.0[3]]); + + let result = PrimitiveValue { + value: result, + is_pointer: true, + }; + + vm_state.perform_dst0_update( + vm_state.local_state.monotonic_cycle_counter, + result, + dst0_mem_location, + self, + ); + } + PtrOpcode::Pack => { + // we check whether src0 is fat pointer + if src0.is_pointer == false { + // src0 is not a pointer + vm_state.set_shorthand_panic(); + return; + } + + if src1.is_pointer == true { + // can not have ptr + ptr + vm_state.set_shorthand_panic(); + return; + } + + if src1.value.low_u128() != 0 { + // mask is not a mask indeed + vm_state.set_shorthand_panic(); + return; + } + + let PrimitiveValue { + value: src0, + is_pointer: _, + } = src0; + let PrimitiveValue { + value: src1, + is_pointer: _, + } = src1; + + // low 128 bits from src0, high 128 - from src1 + let result = U256([src0.0[0], src0.0[1], src1.0[2], src1.0[3]]); + + let result = PrimitiveValue { + value: result, + is_pointer: true, + }; + + vm_state.perform_dst0_update( + vm_state.local_state.monotonic_cycle_counter, + result, + dst0_mem_location, + self, + ); + } + PtrOpcode::Shrink => { + // we check whether src0 is fat pointer + if src0.is_pointer == false { + // src0 is not a pointer + vm_state.set_shorthand_panic(); + return; + } + + if src1.is_pointer == true { + // can not have ptr + ptr + vm_state.set_shorthand_panic(); + return; + } + + let PrimitiveValue { + value: src0, + is_pointer: _, + } = src0; + let PrimitiveValue { + value: src1, + is_pointer: _, + } = src1; + + let fat_ptr = FatPointer::from_u256(src0); + let offset = src1.low_u32(); + + let (new_ptr_length, error) = fat_ptr.length.overflowing_sub(offset); + + if error { + vm_state.set_shorthand_panic(); + return; + } + + let mut new_ptr = fat_ptr; + new_ptr.length = new_ptr_length; + + let ptr_as_u256 = new_ptr.to_u256(); + + // low 128 bits from ptr_as_u256, high 128 - from src0 + let result = U256([ptr_as_u256.0[0], ptr_as_u256.0[1], src0.0[2], src0.0[3]]); + + let result = PrimitiveValue { + value: result, + is_pointer: true, + }; + + vm_state.perform_dst0_update( + vm_state.local_state.monotonic_cycle_counter, + result, + dst0_mem_location, + self, + ); + } + } + } +} diff --git a/crates/zk_evm/src/opcodes/execution/ret.rs b/crates/zk_evm/src/opcodes/execution/ret.rs new file mode 100644 index 0000000..bfb5295 --- /dev/null +++ b/crates/zk_evm/src/opcodes/execution/ret.rs @@ -0,0 +1,255 @@ +use super::*; + +use zkevm_opcode_defs::definitions::ret::*; +use zkevm_opcode_defs::FatPointerValidationException; +use zkevm_opcode_defs::{FatPointer, Opcode, RetABI, RetForwardPageType, RetOpcode}; + +impl> DecodedOpcode { + pub fn ret_opcode_apply< + S: crate::abstractions::Storage, + M: crate::abstractions::Memory, + EV: crate::abstractions::EventSink, + PP: crate::abstractions::PrecompilesProcessor, + DP: crate::abstractions::DecommittmentProcessor, + WT: crate::witness_trace::VmWitnessTracer, + >( + &self, + vm_state: &mut VmState, + prestate: PreState, + ) { + let PreState { src0, .. } = prestate; + let mut inner_variant = match self.variant.opcode { + Opcode::Ret(inner) => inner, + _ => unreachable!(), + }; + // ret always resets flags + vm_state.local_state.flags.reset(); + + let PrimitiveValue { + value: src0, + is_pointer: src0_is_ptr, + } = src0; + + let ret_abi = RetABI::from_u256(src0); + + // we want to mark with one that was will become a new current (taken from stack) + vm_state.witness_tracer.add_sponge_marker( + vm_state.local_state.monotonic_cycle_counter, + SpongeExecutionMarker::CallstackPop, + 1..4, + false, + ); + + let RetABI { + mut memory_quasi_fat_pointer, + page_forwarding_mode, + } = ret_abi; + + let is_to_label = self.variant.flags[RET_TO_LABEL_BIT_IDX]; + let label_pc = self.imm_0; + + let current_callstack = vm_state.local_state.callstack.get_current_stack(); + + let mut pointer_validation_exceptions = FatPointerValidationException::empty(); + + if current_callstack.is_local_frame == false { + // if we try to do forwarding then we have to have ptr in src0, + // otherwise we will panic instead! + if page_forwarding_mode == RetForwardPageType::ForwardFatPointer { + if src0_is_ptr == false { + inner_variant = RetOpcode::Panic; + } + if memory_quasi_fat_pointer.memory_page < current_callstack.base_memory_page.0 { + // it's an exotic case when we try to + // return-forward our own calldata. To avoid + // a sequence of: + // - caller makes far call to some contract + // - callee does return-forward @calldataptr + // - caller modifies calldata corresponding heap region, that leads to modification of returndata + // we require that returndata forwarding is unidirectional + inner_variant = RetOpcode::Panic; + } + } + + // validate that fat pointer (one a future one) we formed is somewhat valid + let validate_as_fresh = page_forwarding_mode != RetForwardPageType::ForwardFatPointer; + + pointer_validation_exceptions = memory_quasi_fat_pointer.validate(validate_as_fresh); + + if pointer_validation_exceptions.is_empty() == false { + // pointer is malformed + inner_variant = RetOpcode::Panic; + } + // our formal definition of "in bounds" is strictly "less than", but we want to allow to return + // "trivial" pointer, like `ret.ok r0` + if memory_quasi_fat_pointer.validate_in_bounds() == false + && memory_quasi_fat_pointer.is_trivial() == false + { + inner_variant = RetOpcode::Panic; + } + + if inner_variant == RetOpcode::Panic { + memory_quasi_fat_pointer = FatPointer::empty(); + } + } + + let mut ergs_remaining = current_callstack.ergs_remaining; + + // now we are all good to form a new fat pointer for + let fat_ptr_for_returndata = if current_callstack.is_local_frame == true { + None + } else { + match inner_variant { + RetOpcode::Ok | RetOpcode::Revert => { + match page_forwarding_mode { + RetForwardPageType::ForwardFatPointer => { + // We can formally shrink the pointer + // If it was malformed then we masked and overflows can not happen + let new_start = memory_quasi_fat_pointer + .start + .wrapping_add(memory_quasi_fat_pointer.offset); + let new_length = memory_quasi_fat_pointer + .length + .wrapping_sub(memory_quasi_fat_pointer.offset); + + memory_quasi_fat_pointer.start = new_start; + memory_quasi_fat_pointer.length = new_length; + memory_quasi_fat_pointer.offset = 0; + } + RetForwardPageType::UseHeap => { + let owned_page = CallStackEntry::::heap_page_from_base( + current_callstack.base_memory_page, + ) + .0; + + memory_quasi_fat_pointer.memory_page = owned_page; + } + RetForwardPageType::UseAuxHeap => { + let owned_page = CallStackEntry::::aux_heap_page_from_base( + current_callstack.base_memory_page, + ) + .0; + + memory_quasi_fat_pointer.memory_page = owned_page; + } + } + } + RetOpcode::Panic => { + memory_quasi_fat_pointer = FatPointer::empty(); + } + } + + // potentially pay for memory growth + let memory_growth_in_bytes = match page_forwarding_mode { + a @ RetForwardPageType::UseHeap | a @ RetForwardPageType::UseAuxHeap => { + // pointer is already validated, so we do not need to check that start + length do not overflow + let mut upper_bound = + memory_quasi_fat_pointer.start + memory_quasi_fat_pointer.length; + + let penalize_out_of_bounds_growth = pointer_validation_exceptions + .contains(FatPointerValidationException::DEREF_BEYOND_HEAP_RANGE); + if penalize_out_of_bounds_growth { + upper_bound = u32::MAX; + } + + let current_bound = if a == RetForwardPageType::UseHeap { + current_callstack.heap_bound + } else if a == RetForwardPageType::UseAuxHeap { + current_callstack.aux_heap_bound + } else { + unreachable!(); + }; + let (mut diff, uf) = upper_bound.overflowing_sub(current_bound); + if uf { + // heap bound is already beyond what we pass + diff = 0u32; + } else { + // we do not need to do anything with the frame that goes out of scope + }; + + diff + } + RetForwardPageType::ForwardFatPointer => 0u32, + }; + + // MEMORY_GROWTH_ERGS_PER_BYTE is always 1 + let cost_of_memory_growth = + memory_growth_in_bytes.wrapping_mul(zkevm_opcode_defs::MEMORY_GROWTH_ERGS_PER_BYTE); + if ergs_remaining >= cost_of_memory_growth { + ergs_remaining -= cost_of_memory_growth; + } else { + ergs_remaining = 0; + inner_variant = RetOpcode::Panic; + memory_quasi_fat_pointer = FatPointer::empty(); + }; + + // we do nothing with it later on, so just keep returndata page, and set zeroes for other + Some(memory_quasi_fat_pointer) + }; + drop(current_callstack); + + // done with exceptions, so we can pop the callstack entry + let panicked = inner_variant == RetOpcode::Revert || inner_variant == RetOpcode::Panic; + + let finished_callstack = + vm_state.finish_frame(vm_state.local_state.monotonic_cycle_counter, panicked); + + // we did finish frame, so get_current_stack_mut is one of the original caller's + let is_to_label = is_to_label & finished_callstack.is_local_frame; + + if finished_callstack.is_local_frame == false { + let returndata_fat_pointer = fat_ptr_for_returndata.unwrap(); + + vm_state.memory.finish_global_frame( + finished_callstack.base_memory_page, + returndata_fat_pointer, + Timestamp(vm_state.local_state.timestamp), + ); + + vm_state.local_state.did_call_or_ret_recently = true; + vm_state.local_state.registers[RET_IMPLICIT_RETURNDATA_PARAMS_REGISTER as usize] = + PrimitiveValue { + value: returndata_fat_pointer.to_u256(), + is_pointer: true, + }; + vm_state.local_state.registers[RET_RESERVED_REGISTER_0 as usize] = + PrimitiveValue::empty(); + vm_state.local_state.registers[RET_RESERVED_REGISTER_1 as usize] = + PrimitiveValue::empty(); + vm_state.local_state.registers[RET_RESERVED_REGISTER_2 as usize] = + PrimitiveValue::empty(); + + // ALL other registers are zeroed out! + for dst in vm_state + .local_state + .registers + .iter_mut() + .skip((RET_RESERVED_REGISTER_2 as usize) + 1) + { + *dst = PrimitiveValue::empty(); + } + + // clean up context register + vm_state.local_state.context_u128_register = 0u128; + } else { + debug_assert!(fat_ptr_for_returndata.is_none()); + } + + let next_context = vm_state.local_state.callstack.get_current_stack_mut(); + // return ergs + next_context.ergs_remaining += ergs_remaining; + // jump properly + if is_to_label { + next_context.pc = label_pc; + } else if panicked { + next_context.pc = finished_callstack.exception_handler_location; + } else { + // just use a saved value + } + + // and set flag on panic + if inner_variant == RetOpcode::Panic { + vm_state.local_state.flags.overflow_or_less_than_flag = true; + } + } +} diff --git a/crates/zk_evm/src/opcodes/execution/shift.rs b/crates/zk_evm/src/opcodes/execution/shift.rs new file mode 100644 index 0000000..7cdc058 --- /dev/null +++ b/crates/zk_evm/src/opcodes/execution/shift.rs @@ -0,0 +1,78 @@ +use super::*; + +use std::ops::*; + +use zkevm_opcode_defs::{Opcode, ShiftOpcode}; + +impl> DecodedOpcode { + pub fn shift_opcode_apply< + S: crate::abstractions::Storage, + M: crate::abstractions::Memory, + EV: crate::abstractions::EventSink, + PP: crate::abstractions::PrecompilesProcessor, + DP: crate::abstractions::DecommittmentProcessor, + WT: crate::witness_trace::VmWitnessTracer, + >( + &self, + vm_state: &mut VmState, + prestate: PreState, + ) { + let PreState { + src0, + src1, + dst0_mem_location, + new_pc, + .. + } = prestate; + let PrimitiveValue { + value: src0, + is_pointer: _, + } = src0; + let PrimitiveValue { + value: src1, + is_pointer: _, + } = src1; + + let inner_variant = match self.variant.opcode { + Opcode::Shift(inner) => inner, + _ => unreachable!(), + }; + let set_flags = self.variant.flags[SET_FLAGS_FLAG_IDX]; + vm_state.local_state.callstack.get_current_stack_mut().pc = new_pc; + let shift_abs = src1.low_u64() as u8; + let is_cyclic = inner_variant == ShiftOpcode::Rol || inner_variant == ShiftOpcode::Ror; + let is_right_shift = inner_variant == ShiftOpcode::Shr || inner_variant == ShiftOpcode::Ror; + + let result = if is_right_shift { + let mut result = src0.shr(shift_abs as u32); + if is_cyclic { + result = result | src0.shl(256u32 - shift_abs as u32); + } + + result + } else { + let mut result = src0.shl(shift_abs as u32); + if is_cyclic { + result = result | src0.shr(256u32 - shift_abs as u32); + } + + result + }; + if set_flags { + let eq = result.is_zero(); + vm_state.reset_flags(); + vm_state.local_state.flags.equality_flag = eq; + } + + let result = PrimitiveValue { + value: result, + is_pointer: false, + }; + vm_state.perform_dst0_update( + vm_state.local_state.monotonic_cycle_counter, + result, + dst0_mem_location, + self, + ); + } +} diff --git a/crates/zk_evm/src/opcodes/execution/sub.rs b/crates/zk_evm/src/opcodes/execution/sub.rs new file mode 100644 index 0000000..27d1129 --- /dev/null +++ b/crates/zk_evm/src/opcodes/execution/sub.rs @@ -0,0 +1,55 @@ +use super::*; + +impl> DecodedOpcode { + pub fn sub_opcode_apply< + S: crate::abstractions::Storage, + M: crate::abstractions::Memory, + EV: crate::abstractions::EventSink, + PP: crate::abstractions::PrecompilesProcessor, + DP: crate::abstractions::DecommittmentProcessor, + WT: crate::witness_trace::VmWitnessTracer, + >( + &self, + vm_state: &mut VmState, + prestate: PreState, + ) { + let PreState { + src0, + src1, + dst0_mem_location, + new_pc, + .. + } = prestate; + let PrimitiveValue { + value: src0, + is_pointer: _, + } = src0; + let PrimitiveValue { + value: src1, + is_pointer: _, + } = src1; + + let set_flags = self.variant.flags[SET_FLAGS_FLAG_IDX]; + vm_state.local_state.callstack.get_current_stack_mut().pc = new_pc; + let (result, of) = src0.overflowing_sub(src1); + let eq = result.is_zero(); + let gt = !eq && !of; + + if set_flags { + vm_state.local_state.flags.reset(); + vm_state.local_state.flags.overflow_or_less_than_flag = of; + vm_state.local_state.flags.equality_flag = eq; + vm_state.local_state.flags.greater_than_flag = gt; + } + let result = PrimitiveValue { + value: result, + is_pointer: false, + }; + vm_state.perform_dst0_update( + vm_state.local_state.monotonic_cycle_counter, + result, + dst0_mem_location, + &self, + ); + } +} diff --git a/crates/zk_evm/src/opcodes/execution/uma.rs b/crates/zk_evm/src/opcodes/execution/uma.rs new file mode 100644 index 0000000..d99b3ec --- /dev/null +++ b/crates/zk_evm/src/opcodes/execution/uma.rs @@ -0,0 +1,460 @@ +use crate::abstractions::MemoryType; + +use super::*; +use zkevm_opcode_defs::{FatPointer, Opcode, UMAOpcode, UMA_INCREMENT_FLAG_IDX}; + +const U64_TOP_32_BITS_MASK: u64 = 0xffff_ffff_0000_0000; + +use zkevm_opcode_defs::bitflags::bitflags; + +bitflags! { + pub struct UMAExceptionFlags: u64 { + const INPUT_IS_NOT_POINTER_WHEN_EXPECTED = 1u64 << 0; + const DEREF_BEYOND_HEAP_RANGE = 1u64 << 1; + const OVERFLOW_ON_INCREMENT = 1u64 << 2; + const NOT_ENOUGH_ERGS_TO_GROW_MEMORY = 1u64 << 3; + } + + pub struct UMASkipMemoryAccessFlags: u64 { + const FAT_PTR_IS_OUT_OF_BOUNDS = 1u64 << 0; + const DEREF_BEYOND_HEAP_RANGE = 1u64 << 1; + } +} + +impl> DecodedOpcode { + pub fn uma_opcode_apply< + S: crate::abstractions::Storage, + M: crate::abstractions::Memory, + EV: crate::abstractions::EventSink, + PP: crate::abstractions::PrecompilesProcessor, + DP: crate::abstractions::DecommittmentProcessor, + WT: crate::witness_trace::VmWitnessTracer, + >( + &self, + vm_state: &mut VmState, + prestate: PreState, + ) { + let PreState { + src0, + src1, + dst0_mem_location, + new_pc, + .. + } = prestate; + debug_assert!( + dst0_mem_location.is_none(), + "UMA opcode has dst0 not in register" + ); + let inner_variant = match self.variant.opcode { + Opcode::UMA(inner) => inner, + _ => unreachable!(), + }; + vm_state.local_state.callstack.get_current_stack_mut().pc = new_pc; + + let increment_offset = self.variant.flags[UMA_INCREMENT_FLAG_IDX]; + + let PrimitiveValue { + value: src0_value, + is_pointer: src0_is_ptr, + } = src0; + let PrimitiveValue { + value: src1, + is_pointer: _, + } = src1; + let mut fat_ptr = FatPointer::from_u256(src0_value); + + let mut exceptions = UMAExceptionFlags::empty(); + let mut skip_memory_access_flags = UMASkipMemoryAccessFlags::empty(); + + let is_ptr_read = inner_variant == UMAOpcode::FatPointerRead; + + // heap and aux heap are under full user's control, but fat pointers must be accessed in a valid manner + if is_ptr_read { + if src0_is_ptr == false { + // we are trying to dereference not a pointer + exceptions.set(UMAExceptionFlags::INPUT_IS_NOT_POINTER_WHEN_EXPECTED, true); + } + } + + let memory_type = match inner_variant { + UMAOpcode::HeapRead | UMAOpcode::HeapWrite => { + let page = CallStackEntry::::heap_page_from_base( + vm_state + .local_state + .callstack + .get_current_stack() + .base_memory_page, + ); + + fat_ptr.memory_page = page.0; + + MemoryType::Heap + } + UMAOpcode::AuxHeapRead | UMAOpcode::AuxHeapWrite => { + let page = CallStackEntry::::aux_heap_page_from_base( + vm_state + .local_state + .callstack + .get_current_stack() + .base_memory_page, + ); + + fat_ptr.memory_page = page.0; + + MemoryType::AuxHeap + } + UMAOpcode::FatPointerRead => MemoryType::FatPointer, + }; + + let src_offset = if is_ptr_read { + if fat_ptr.validate_in_bounds() == false { + // it's not an exception, but we do not need to access memory, + // and can just return 0 + skip_memory_access_flags + .set(UMASkipMemoryAccessFlags::FAT_PTR_IS_OUT_OF_BOUNDS, true); + } + // there can be no overflow over u32 due to how we create fat pointers + // if we are in bounds, and if we are not - do not care + + fat_ptr.start.wrapping_add(fat_ptr.offset) + } else { + // for heaps we offset encodes absolute position + let offset = fat_ptr.offset; + + // if our register is either not u32, or it's just "too large", + // then we should also panic + if src0.value > zkevm_opcode_defs::uma::MAX_OFFSET_TO_DEREF { + // this is an exception because one tries to address too far into the heap + exceptions.set(UMAExceptionFlags::DEREF_BEYOND_HEAP_RANGE, true); + skip_memory_access_flags + .set(UMASkipMemoryAccessFlags::DEREF_BEYOND_HEAP_RANGE, true); + } + + offset + }; + + let (incremented_offset, increment_offset_of) = fat_ptr.offset.overflowing_add(32); + + if increment_offset_of { + // incremented_offset is an indication of the non-inclusive end of memory region we try + // to access. So if it overflows we have an exception + exceptions.set(UMAExceptionFlags::OVERFLOW_ON_INCREMENT, true); + if is_ptr_read == false { + // sanity check - it should be caught by comparison above + assert!(exceptions.contains(UMAExceptionFlags::DEREF_BEYOND_HEAP_RANGE)); + } + } + + let current_callstack_mut = vm_state.local_state.callstack.get_current_stack_mut(); + + // potentially pay for memory growth + let memory_growth_in_bytes = match inner_variant { + UMAOpcode::HeapRead + | UMAOpcode::HeapWrite + | UMAOpcode::AuxHeapRead + | UMAOpcode::AuxHeapWrite => { + let current_bound = match inner_variant { + UMAOpcode::HeapRead | UMAOpcode::HeapWrite => current_callstack_mut.heap_bound, + UMAOpcode::AuxHeapRead | UMAOpcode::AuxHeapWrite => { + current_callstack_mut.aux_heap_bound + } + _ => { + unreachable!() + } + }; + + // here do do not care about potential overflow, and later on penalize + // for it + let upper_bound = incremented_offset; + let (mut diff, uf) = upper_bound.overflowing_sub(current_bound); + if uf { + // heap bound is already beyond what we pass + diff = 0u32; + } else { + match inner_variant { + UMAOpcode::HeapRead | UMAOpcode::HeapWrite => { + current_callstack_mut.heap_bound = upper_bound; + } + UMAOpcode::AuxHeapRead | UMAOpcode::AuxHeapWrite => { + current_callstack_mut.aux_heap_bound = upper_bound; + } + _ => { + unreachable!() + } + }; + }; + + diff + } + UMAOpcode::FatPointerRead => { + // cost was paid somewhere, and we if try to go out of bound we will just not read + 0u32 + } + }; + + let mut cost_of_memory_growth = + memory_growth_in_bytes.wrapping_mul(zkevm_opcode_defs::MEMORY_GROWTH_ERGS_PER_BYTE); + + // if we try to go "too far" in memory that our normal memory growth payment routines + // are short-circuited, we still account for net cost here + + let penalize_for_out_of_bounds = + exceptions.contains(UMAExceptionFlags::DEREF_BEYOND_HEAP_RANGE); // offset is not U32 + + if penalize_for_out_of_bounds { + cost_of_memory_growth = u32::MAX; + } + + let (mut ergs_after_memory_growth, uf) = current_callstack_mut + .ergs_remaining + .overflowing_sub(cost_of_memory_growth); + if uf { + ergs_after_memory_growth = 0; + // out of ergs common exception + exceptions.set(UMAExceptionFlags::NOT_ENOUGH_ERGS_TO_GROW_MEMORY, true); + } + current_callstack_mut.ergs_remaining = ergs_after_memory_growth; + drop(current_callstack_mut); + + // we will set panic if any exception was triggered + let set_panic = exceptions.is_empty() == false; + let legitimate_skip_memory_access = skip_memory_access_flags.is_empty() == false; + // but we may skip memory accesses in practice in some other legitimate cases, + // like deref fat pointer out of bounds. It's OR with `set_panic` because + // it will still be not observable as we will not update any registers + let skip_memory_access = legitimate_skip_memory_access || set_panic; + + // even if src_offset is beyond addressable memory, we are still fine with it as we will eventually NOT do the read. + // When memory growth payments will be implemented we will be able to remove restriction of 2^24 addressable memory + let word_0 = src_offset / 32; + let word_1 = word_0 + 1; + let unalignment = src_offset % 32; + let word_0_lowest_bytes = 32 - unalignment; + let word_1_highest_bytes = unalignment; + debug_assert!(word_1_highest_bytes != 32); + let is_unaligned = unalignment != 0; + + let word_0_location = MemoryLocation { + memory_type, + page: MemoryPage(fat_ptr.memory_page), + index: MemoryIndex(word_0), + }; + let word_1_location = MemoryLocation { + memory_type, + page: MemoryPage(fat_ptr.memory_page), + index: MemoryIndex(word_1), + }; + + let timestamp_to_read = vm_state.timestamp_for_code_or_src_read(); + let timestamp_to_write = vm_state.timestamp_for_dst_write(); + + // NOTE: endianess + // we use naturally LE U256 base type, but in VM it's BE + // so when we do unaligned read we need LOWEST bits of first word + // and HIGHEST bits for second word + + // N.B. Reads are NOT pending + let key_0 = MemoryKey { + location: word_0_location, + timestamp: timestamp_to_read, + }; + + let word_0_read_value = if skip_memory_access == false { + let word_0_query = vm_state.read_memory( + vm_state.local_state.monotonic_cycle_counter, + key_0, + /* is_pended */ false, + ); + vm_state.witness_tracer.add_sponge_marker( + vm_state.local_state.monotonic_cycle_counter, + SpongeExecutionMarker::MemoryQuery, + 1..2, + /* is_pended */ false, + ); + + let word_0_read_value = word_0_query.value; + + word_0_read_value + } else { + U256::zero() + }; + + let word_1_read_value = if is_unaligned && skip_memory_access == false { + let key_1 = MemoryKey { + location: word_1_location, + timestamp: timestamp_to_read, + }; + + let word_1_query = vm_state.read_memory( + vm_state.local_state.monotonic_cycle_counter, + key_1, + /* is_pended */ true, + ); + + vm_state.witness_tracer.add_sponge_marker( + vm_state.local_state.monotonic_cycle_counter, + SpongeExecutionMarker::MemoryQuery, + 3..4, + /* is_pended */ true, + ); + + word_1_query.value + } else { + U256::zero() + }; + + match inner_variant { + a @ UMAOpcode::HeapRead + | a @ UMAOpcode::AuxHeapRead + | a @ UMAOpcode::FatPointerRead => { + // if we do "skip op", then we just write formal 0 into destination, + // but if "increment" failed, then we skip updates all together + + // read always fits into single VM cycle + // we want lowest bits of the word0 (if unalignment is 0 then we indeed want it in full) + let mut result = word_0_read_value << (unalignment * 8); + // we want highest bits of the word1. If e.g unalignment is X, then we have already + // observed `32 - unalignment` of bytes from previous word, so we want only + // `unalignment` bytes of the word1 + result = result | (word_1_read_value >> ((32 - unalignment) * 8)); + + if a == UMAOpcode::FatPointerRead { + let (mut bytes_beyond_the_bound, uf) = + incremented_offset.overflowing_sub(fat_ptr.length); + if uf || skip_memory_access { + // we either failed some validation above, so we don't care about the result, + // or the tail is in bounds too. If `incremented_offset` == `fat_ptr.length` there is no underflow, + // but the difference is 0 anyway + bytes_beyond_the_bound = 0; + } + + bytes_beyond_the_bound = bytes_beyond_the_bound % 32; + + // cleanup + result >>= bytes_beyond_the_bound * 8; + result <<= bytes_beyond_the_bound * 8; + } + + let result = PrimitiveValue { + value: result, + is_pointer: false, + }; + + if set_panic == false { + vm_state.perform_dst0_update( + vm_state.local_state.monotonic_cycle_counter, + result, + dst0_mem_location, + &self, + ); + + if increment_offset { + let mut updated_value = src0_value; + updated_value.0[0] = (updated_value.0[0] & U64_TOP_32_BITS_MASK) + + (incremented_offset as u64); + let reg_value = PrimitiveValue { + value: updated_value, + is_pointer: src0_is_ptr, + }; + vm_state.perform_dst1_update(reg_value, self.dst1_reg_idx); + } + } else { + vm_state.set_shorthand_panic(); + } + } + UMAOpcode::HeapWrite | UMAOpcode::AuxHeapWrite => { + // we need to keep highest bytes of old word and place highest bytes of src1 into lowest + // cleanup lowest bytes + let mut new_word_0_value = + (word_0_read_value >> (word_0_lowest_bytes * 8)) << (word_0_lowest_bytes * 8); + // add highest bytes into lowest for overwriting + new_word_0_value = new_word_0_value | (src1 >> (unalignment * 8)); + // we need low bytes of old word and place low bytes of src1 into highest + // cleanup highest bytes + let mut new_word_1_value = + (word_1_read_value << (word_1_highest_bytes * 8)) >> (word_1_highest_bytes * 8); + // add lowest bytes into highest + new_word_1_value = new_word_1_value | (src1 << ((32 - word_1_highest_bytes) * 8)); + + let key_0 = MemoryKey { + location: word_0_location, + timestamp: timestamp_to_write, + }; + + let new_word_0_value = PrimitiveValue { + value: new_word_0_value, + is_pointer: false, + }; + + if skip_memory_access == false { + // just write word 0 + let _word_0_write_query = vm_state.write_memory( + vm_state.local_state.monotonic_cycle_counter, + key_0, + new_word_0_value, + /* is_pended */ false, + ); + } + + vm_state.witness_tracer.add_sponge_marker( + vm_state.local_state.monotonic_cycle_counter, + SpongeExecutionMarker::MemoryQuery, + 2..3, + /* is_pended */ false, + ); + + // may be write word 1 + if is_unaligned && skip_memory_access == false { + let key_1 = MemoryKey { + location: word_1_location, + timestamp: timestamp_to_write, + }; + + // always not a pointer + let new_word_1_value = PrimitiveValue { + value: new_word_1_value, + is_pointer: false, + }; + + let _word_1_write_query = vm_state.write_memory( + vm_state.local_state.monotonic_cycle_counter, + key_1, + new_word_1_value, + /* is_pended */ true, + ); + + vm_state.witness_tracer.add_sponge_marker( + vm_state.local_state.monotonic_cycle_counter, + SpongeExecutionMarker::MemoryQuery, + 4..5, + /* is_pended */ true, + ); + + vm_state.local_state.pending_port.pending_type = Some(PendingType::UMAWrite); + } + + if set_panic == false { + if increment_offset { + let mut updated_value = src0_value; + updated_value.0[0] = (updated_value.0[0] & U64_TOP_32_BITS_MASK) + + (incremented_offset as u64); + let result = PrimitiveValue { + value: updated_value, + is_pointer: false, + }; + debug_assert_eq!(src0_is_ptr, false); + + vm_state.perform_dst0_update( + vm_state.local_state.monotonic_cycle_counter, + result, + dst0_mem_location, + &self, + ); + } + } else { + vm_state.set_shorthand_panic(); + } + } + }; + } +} diff --git a/crates/zk_evm/src/opcodes/mod.rs b/crates/zk_evm/src/opcodes/mod.rs new file mode 100644 index 0000000..b7ad8cd --- /dev/null +++ b/crates/zk_evm/src/opcodes/mod.rs @@ -0,0 +1,6 @@ +use super::*; + +pub mod execution; +pub mod parsing; + +pub use self::parsing::*; diff --git a/crates/zk_evm/src/opcodes/parsing.rs b/crates/zk_evm/src/opcodes/parsing.rs new file mode 100644 index 0000000..42f0595 --- /dev/null +++ b/crates/zk_evm/src/opcodes/parsing.rs @@ -0,0 +1,80 @@ +use super::*; +use crate::vm_state::{PreState, VmState}; + +#[derive(Clone, Copy)] +pub struct DecodedOpcode = EncodingModeProduction> { + pub inner: zkevm_opcode_defs::DecodedOpcode, +} + +impl> std::ops::Deref for DecodedOpcode { + type Target = zkevm_opcode_defs::DecodedOpcode; + + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +impl> std::ops::DerefMut for DecodedOpcode { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.inner + } +} + +impl> std::fmt::Display for DecodedOpcode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.inner) + } +} + +impl> std::fmt::Debug for DecodedOpcode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.inner) + } +} + +use zkevm_opcode_defs::decoding::encoding_mode_production::EncodingModeProduction; +use zkevm_opcode_defs::decoding::VmEncodingMode; + +impl> DecodedOpcode { + pub fn mask_into_panic(&mut self) { + self.inner.mask_into_panic(); + } + + pub fn mask_into_nop(&mut self) { + self.inner.mask_into_nop(); + } + + pub fn apply< + S: crate::abstractions::Storage, + M: crate::abstractions::Memory, + EV: crate::abstractions::EventSink, + PP: crate::abstractions::PrecompilesProcessor, + DP: crate::abstractions::DecommittmentProcessor, + WT: crate::witness_trace::VmWitnessTracer, + >( + &self, + vm_state: &mut VmState, + prestate: PreState, + ) { + use zkevm_opcode_defs::Opcode; + + match self.inner.variant.opcode { + Opcode::Nop(_) => self.noop_opcode_apply(vm_state, prestate), + Opcode::Add(_) => self.add_opcode_apply(vm_state, prestate), + Opcode::Sub(_) => self.sub_opcode_apply(vm_state, prestate), + Opcode::Mul(_) => self.mul_opcode_apply(vm_state, prestate), + Opcode::Div(_) => self.div_opcode_apply(vm_state, prestate), + Opcode::Jump(_) => self.jump_opcode_apply(vm_state, prestate), + Opcode::Context(_) => self.context_opcode_apply(vm_state, prestate), + Opcode::Shift(_) => self.shift_opcode_apply(vm_state, prestate), + Opcode::Binop(_) => self.binop_opcode_apply(vm_state, prestate), + Opcode::Ptr(_) => self.ptr_opcode_apply(vm_state, prestate), + Opcode::Log(_) => self.log_opcode_apply(vm_state, prestate), + Opcode::NearCall(_) => self.near_call_opcode_apply(vm_state, prestate), + Opcode::FarCall(_) => self.far_call_opcode_apply(vm_state, prestate), + Opcode::Ret(_) => self.ret_opcode_apply(vm_state, prestate), + Opcode::UMA(_) => self.uma_opcode_apply(vm_state, prestate), + Opcode::Invalid(_) => unreachable!(), + } + } +} diff --git a/crates/zk_evm/src/precompiles/ecrecover.rs b/crates/zk_evm/src/precompiles/ecrecover.rs new file mode 100644 index 0000000..4c1caab --- /dev/null +++ b/crates/zk_evm/src/precompiles/ecrecover.rs @@ -0,0 +1,283 @@ +use super::*; + +// we need hash, r, s, v +pub const MEMORY_READS_PER_CYCLE: usize = 4; +pub const MEMORY_WRITES_PER_CYCLE: usize = 2; + +use k256::ecdsa::*; +use sha2::Digest; + +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct ECRecoverRoundWitness { + pub new_request: LogQuery, + pub reads: [MemoryQuery; MEMORY_READS_PER_CYCLE], + pub writes: [MemoryQuery; MEMORY_WRITES_PER_CYCLE], +} + +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct ECRecoverPrecompile; + +impl crate::abstractions::Precompile for ECRecoverPrecompile { + type CycleWitness = ECRecoverRoundWitness; + + fn execute_precompile( + &mut self, + monotonic_cycle_counter: u32, + query: LogQuery, + memory: &mut M, + ) -> Option<(Vec, Vec, Vec)> { + // read the parameters + let precompile_call_params = query; + let params = precompile_abi_in_log(precompile_call_params); + let timestamp_to_read = precompile_call_params.timestamp; + let timestamp_to_write = Timestamp(timestamp_to_read.0 + 1); // our default timestamping agreement + + let mut current_read_location = MemoryLocation { + memory_type: MemoryType::Heap, // we default for some value, here it's not that important + page: MemoryPage(params.memory_page_to_read), + index: MemoryIndex(params.input_memory_offset), + }; + + // we assume that we have + // - hash of the message + // - r + // - s + // - v as a single byte + + // we do 6 queries per precompile + let mut read_history = if B { + Vec::with_capacity(MEMORY_READS_PER_CYCLE) + } else { + vec![] + }; + let mut write_history = if B { + Vec::with_capacity(MEMORY_WRITES_PER_CYCLE) + } else { + vec![] + }; + + let mut round_witness = ECRecoverRoundWitness { + new_request: precompile_call_params, + reads: [MemoryQuery::empty(); MEMORY_READS_PER_CYCLE], + writes: [MemoryQuery::empty(); MEMORY_WRITES_PER_CYCLE], + }; + + let mut read_idx = 0; + + let hash_query = MemoryQuery { + timestamp: timestamp_to_read, + location: current_read_location, + value: U256::zero(), + value_is_pointer: false, + rw_flag: false, + is_pended: false, + }; + let hash_query = memory.execute_partial_query(monotonic_cycle_counter, hash_query); + let hash_value = hash_query.value; + if B { + round_witness.reads[read_idx] = hash_query; + read_idx += 1; + read_history.push(hash_query); + } + + current_read_location.index.0 += 1; + let v_query = MemoryQuery { + timestamp: timestamp_to_read, + location: current_read_location, + value: U256::zero(), + value_is_pointer: false, + rw_flag: false, + is_pended: false, + }; + let v_query = memory.execute_partial_query(monotonic_cycle_counter, v_query); + let v_value = v_query.value; + if B { + round_witness.reads[read_idx] = v_query; + read_idx += 1; + read_history.push(v_query); + } + + current_read_location.index.0 += 1; + let r_query = MemoryQuery { + timestamp: timestamp_to_read, + location: current_read_location, + value: U256::zero(), + value_is_pointer: false, + rw_flag: false, + is_pended: false, + }; + let r_query = memory.execute_partial_query(monotonic_cycle_counter, r_query); + let r_value = r_query.value; + if B { + round_witness.reads[read_idx] = r_query; + read_idx += 1; + read_history.push(r_query); + } + + current_read_location.index.0 += 1; + let s_query = MemoryQuery { + timestamp: timestamp_to_read, + location: current_read_location, + value: U256::zero(), + value_is_pointer: false, + rw_flag: false, + is_pended: false, + }; + let s_query = memory.execute_partial_query(monotonic_cycle_counter, s_query); + let s_value = s_query.value; + if B { + round_witness.reads[read_idx] = s_query; + read_history.push(s_query); + } + // read everything as bytes for ecrecover purposes + + let mut buffer = [0u8; 32]; + hash_value.to_big_endian(&mut buffer[..]); + let hash = buffer; + + r_value.to_big_endian(&mut buffer[..]); + let r_bytes = buffer; + + s_value.to_big_endian(&mut buffer[..]); + let s_bytes = buffer; + + v_value.to_big_endian(&mut buffer[..]); + let v = buffer[31]; + assert!(v == 0 || v == 1); + + let mut serialized = Vec::with_capacity(65); + serialized.extend(r_bytes); + serialized.extend(s_bytes); + serialized.push(v); + + let pk = ecrecover_inner(hash, serialized); + + // here it may be possible to have non-recoverable k*G point, so can fail + if let Ok(recovered_pubkey) = pk { + let pk = k256::PublicKey::from(&recovered_pubkey); + let affine_point = pk.as_affine().clone(); + use k256::elliptic_curve::sec1::ToEncodedPoint; + let pk_bytes = affine_point.to_encoded_point(false); + let pk_bytes_ref: &[u8] = pk_bytes.as_ref(); + assert_eq!(pk_bytes_ref.len(), 65); + debug_assert_eq!(pk_bytes_ref[0], 0x04); + let address_hash = sha3::Keccak256::digest(&pk_bytes_ref[1..]); + + let mut address = [0u8; 32]; + let hash_ref: &[u8] = address_hash.as_ref(); + address[12..].copy_from_slice(&hash_ref[12..]); + + let mut write_location = MemoryLocation { + memory_type: MemoryType::Heap, // we default for some value, here it's not that important + page: MemoryPage(params.memory_page_to_write), + index: MemoryIndex(params.output_memory_offset), + }; + + let ok_marker = U256::one(); + let ok_or_err_query = MemoryQuery { + timestamp: timestamp_to_write, + location: write_location, + value: ok_marker, + value_is_pointer: false, + rw_flag: true, + is_pended: false, + }; + let ok_or_err_query = + memory.execute_partial_query(monotonic_cycle_counter, ok_or_err_query); + + write_location.index.0 += 1; + let result = U256::from_big_endian(&address); + let result_query = MemoryQuery { + timestamp: timestamp_to_write, + location: write_location, + value: result, + value_is_pointer: false, + rw_flag: true, + is_pended: false, + }; + let result_query = memory.execute_partial_query(monotonic_cycle_counter, result_query); + + if B { + round_witness.writes[0] = ok_or_err_query; + round_witness.writes[1] = result_query; + write_history.push(ok_or_err_query); + write_history.push(result_query); + } + } else { + let mut write_location = MemoryLocation { + memory_type: MemoryType::Heap, // we default for some value, here it's not that important + page: MemoryPage(params.memory_page_to_write), + index: MemoryIndex(params.output_memory_offset), + }; + + let err_marker = U256::zero(); + let ok_or_err_query = MemoryQuery { + timestamp: timestamp_to_write, + location: write_location, + value: err_marker, + value_is_pointer: false, + rw_flag: true, + is_pended: false, + }; + let ok_or_err_query = + memory.execute_partial_query(monotonic_cycle_counter, ok_or_err_query); + + write_location.index.0 += 1; + let empty_result = U256::zero(); + let result_query = MemoryQuery { + timestamp: timestamp_to_write, + location: write_location, + value: empty_result, + value_is_pointer: false, + rw_flag: true, + is_pended: false, + }; + let result_query = memory.execute_partial_query(monotonic_cycle_counter, result_query); + + if B { + round_witness.writes[0] = ok_or_err_query; + round_witness.writes[1] = result_query; + write_history.push(ok_or_err_query); + write_history.push(result_query); + } + } + + if B { + Some((read_history, write_history, vec![round_witness])) + } else { + None + } + } +} + +pub fn ecrecover_inner( + digest: [u8; 32], + serialized_signature: Vec, +) -> Result { + if digest.iter().all(|el| *el == 0) { + // zero hash is not supported by our convension + return Err(()); + } + // we expect pre-validation, so this check always works + let sig = + k256::ecdsa::recoverable::Signature::try_from(&serialized_signature[..]).map_err(|_| ())?; + let mut hash_array = k256::FieldBytes::default(); + let hash_array_mut_ref: &mut [u8] = hash_array.as_mut(); + hash_array_mut_ref.copy_from_slice(&digest); + + sig.recover_verifying_key_from_digest_bytes(&hash_array) + .map_err(|_| ()) +} + +pub fn ecrecover_function( + monotonic_cycle_counter: u32, + precompile_call_params: LogQuery, + memory: &mut M, +) -> Option<( + Vec, + Vec, + Vec, +)> { + let mut processor = ECRecoverPrecompile::; + processor.execute_precompile(monotonic_cycle_counter, precompile_call_params, memory) +} diff --git a/crates/zk_evm/src/precompiles/keccak256.rs b/crates/zk_evm/src/precompiles/keccak256.rs new file mode 100644 index 0000000..f598b7d --- /dev/null +++ b/crates/zk_evm/src/precompiles/keccak256.rs @@ -0,0 +1,290 @@ +use super::*; + +pub const KECCAK_RATE_IN_U64_WORDS: usize = 17; +pub const MEMORY_READS_PER_CYCLE: usize = 5; +pub const MEMORY_WRITES_PER_CYCLE: usize = 1; +pub const NUM_WORDS_PER_QUERY: usize = 4; +pub const NEW_WORDS_PER_CYCLE: usize = NUM_WORDS_PER_QUERY * MEMORY_READS_PER_CYCLE; + +// we need a buffer such that if we can not fill it in this block eventually it should +// also contain enough data to run another round function this time +pub const BUFFER_SIZE: usize = NEW_WORDS_PER_CYCLE + KECCAK_RATE_IN_U64_WORDS - 1; + +// since NEW_WORDS_PER_CYCLE and KECCAK_RATE_IN_U64_WORDS are co-prime we will have remainders in a buffer like +// 0 - 3 - 6 - 9 - .... - 18 (here we can actually absorb), so there is no good trick to other than check +// if we skip or not memory reads at this cycle + +// static_assertions::const_assert!(BUFFER_SIZE - NEW_WORDS_PER_CYCLE >= KECCAK_RATE_IN_U64_WORDS); + +pub use sha3::*; + +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct Keccak256RoundWitness { + pub new_request: Option, + pub reads: Option<[MemoryQuery; MEMORY_READS_PER_CYCLE]>, + pub writes: Option<[MemoryQuery; MEMORY_WRITES_PER_CYCLE]>, +} + +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct Keccak256Precompile; + +impl crate::abstractions::Precompile for Keccak256Precompile { + type CycleWitness = Keccak256RoundWitness; + + fn execute_precompile( + &mut self, + monotonic_cycle_counter: u32, + query: LogQuery, + memory: &mut M, + ) -> Option<(Vec, Vec, Vec)> { + let precompile_call_params = query; + // read the parameters + let params = precompile_abi_in_log(precompile_call_params); + let timestamp_to_read = precompile_call_params.timestamp; + let timestamp_to_write = Timestamp(timestamp_to_read.0 + 1); // our default timestamping agreement + + let num_rounds = params.precompile_interpreted_data as usize; + let source_memory_page = params.memory_page_to_read; + let destination_memory_page = params.memory_page_to_write; + let mut current_read_offset = params.input_memory_offset; + let write_offset = params.output_memory_offset; + + let mut read_queries = if B { + Vec::with_capacity(MEMORY_READS_PER_CYCLE * num_rounds) + } else { + vec![] + }; + + let mut write_queries = if B { + Vec::with_capacity(MEMORY_WRITES_PER_CYCLE) + } else { + vec![] + }; + + let mut witness = if B { + Vec::with_capacity(num_rounds) + } else { + vec![] + }; + + let mut input_buffer = Buffer::new(); + let mut words_buffer = [0u64; NEW_WORDS_PER_CYCLE]; + + let mut internal_state = Keccak256::default(); + + for round in 0..num_rounds { + let mut round_witness = Keccak256RoundWitness { + new_request: None, + reads: None, + writes: None, + }; + + if B && round == 0 { + round_witness.new_request = Some(precompile_call_params); + } + + // fill the buffer if we can + if input_buffer.can_read_into() { + let mut reads = [MemoryQuery::empty(); MEMORY_READS_PER_CYCLE]; + + for query_index in 0..MEMORY_READS_PER_CYCLE { + let data_query = MemoryQuery { + timestamp: timestamp_to_read, + location: MemoryLocation { + memory_type: MemoryType::Heap, + page: MemoryPage(source_memory_page), + index: MemoryIndex(current_read_offset), + }, + value: U256::zero(), + value_is_pointer: false, + rw_flag: false, + is_pended: false, + }; + let data_query = + memory.execute_partial_query(monotonic_cycle_counter, data_query); + let data = data_query.value; + if B { + reads[query_index] = data_query; + read_queries.push(data_query); + } + let mut bytes32_buffer = [0u8; 32]; + data.to_big_endian(&mut bytes32_buffer[..]); + // revert endianess and push + for (i, chunk) in bytes32_buffer.chunks(8).enumerate() { + let as_u64 = u64::from_le_bytes(chunk.try_into().unwrap()); + words_buffer[query_index * NUM_WORDS_PER_QUERY + i] = as_u64; + } + + current_read_offset += 1; + } + + if B { + round_witness.reads = Some(reads); + } + + input_buffer.append(&words_buffer); + } + + // always consume rate and run keccak round function + let words = input_buffer.consume_rate(); + let mut block = [0u8; KECCAK_RATE_IN_U64_WORDS * 8]; + + for (i, word) in words.into_iter().enumerate() { + block[(i * 8)..(i * 8 + 8)].copy_from_slice(&word.to_le_bytes()); + } + internal_state.update(&block); + + let is_last = round == num_rounds - 1; + + if is_last { + let state_inner = transmute_state(internal_state.clone()); + + // take hash and properly set endianess for the output word + let mut hash_as_bytes32 = [0u8; 32]; + hash_as_bytes32[0..8].copy_from_slice(&state_inner[0].to_le_bytes()); + hash_as_bytes32[8..16].copy_from_slice(&state_inner[1].to_le_bytes()); + hash_as_bytes32[16..24].copy_from_slice(&state_inner[2].to_le_bytes()); + hash_as_bytes32[24..32].copy_from_slice(&state_inner[3].to_le_bytes()); + let as_u256 = U256::from_big_endian(&hash_as_bytes32); + let write_location = MemoryLocation { + memory_type: MemoryType::Heap, // we default for some value, here it's not that important + page: MemoryPage(destination_memory_page), + index: MemoryIndex(write_offset), + }; + + let result_query = MemoryQuery { + timestamp: timestamp_to_write, + location: write_location, + value: as_u256, + value_is_pointer: false, + rw_flag: true, + is_pended: false, + }; + + let result_query = + memory.execute_partial_query(monotonic_cycle_counter, result_query); + + if B { + round_witness.writes = Some([result_query]); + write_queries.push(result_query); + } + } + + witness.push(round_witness); + } + + if B { + Some((read_queries, write_queries, witness)) + } else { + None + } + } +} + +pub struct Buffer { + pub words: [u64; BUFFER_SIZE], + pub filled: usize, +} + +impl Buffer { + pub fn new() -> Self { + Self { + words: [0u64; BUFFER_SIZE], + filled: 0, + } + } + + pub fn reset(&mut self) { + self.words = [0u64; BUFFER_SIZE]; + self.filled = 0; + } + + pub fn can_read_into(&self) -> bool { + self.filled <= BUFFER_SIZE - NEW_WORDS_PER_CYCLE + } + + pub fn append(&mut self, data: &[u64; NEW_WORDS_PER_CYCLE]) { + debug_assert!( + self.filled <= BUFFER_SIZE - NEW_WORDS_PER_CYCLE, + "have {} words filled, but the limit is {}", + self.filled, + BUFFER_SIZE - NEW_WORDS_PER_CYCLE + ); + self.words[self.filled..(self.filled + NEW_WORDS_PER_CYCLE)].copy_from_slice(&data[..]); + self.filled += NEW_WORDS_PER_CYCLE; + } + + pub fn consume_rate(&mut self) -> [u64; KECCAK_RATE_IN_U64_WORDS] { + debug_assert!(self.filled >= KECCAK_RATE_IN_U64_WORDS); + let taken = self.words[..KECCAK_RATE_IN_U64_WORDS].try_into().unwrap(); + self.filled -= KECCAK_RATE_IN_U64_WORDS; + let mut tmp = [0u64; BUFFER_SIZE]; + tmp[..(BUFFER_SIZE - KECCAK_RATE_IN_U64_WORDS)] + .copy_from_slice(&self.words[KECCAK_RATE_IN_U64_WORDS..]); + self.words = tmp; + + taken + } +} + +pub fn keccak256_rounds_function( + monotonic_cycle_counter: u32, + precompile_call_params: LogQuery, + memory: &mut M, +) -> Option<( + Vec, + Vec, + Vec, +)> { + let mut processor = Keccak256Precompile::; + processor.execute_precompile(monotonic_cycle_counter, precompile_call_params, memory) +} + +pub type Keccak256InnerState = [u64; 25]; + +struct BlockBuffer { + _buffer: [u8; 136], + _pos: u8, +} + +struct CoreWrapper { + core: Keccak256VarCore, + _buffer: BlockBuffer, +} + +struct Keccak256VarCore { + state: Keccak256InnerState, +} + +static_assertions::assert_eq_size!(Keccak256, CoreWrapper); + +pub fn transmute_state(reference_state: Keccak256) -> Keccak256InnerState { + // we use a trick that size of both structures is the same, and even though we do not know a stable field layout, + // we can replicate it + let our_wrapper: CoreWrapper = unsafe { std::mem::transmute(reference_state) }; + + our_wrapper.core.state +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_empty_string() { + let mut hasher = Keccak256::new(); + hasher.update(&[]); + let result = hasher.finalize(); + println!("Empty string hash = {}", hex::encode(result.as_slice())); + + let mut our_hasher = Keccak256::default(); + let mut block = [0u8; 136]; + block[0] = 0x01; + block[135] = 0x80; + our_hasher.update(&block); + let state_inner = transmute_state(our_hasher); + for (idx, el) in state_inner.iter().enumerate() { + println!("Element {} = 0x{:016x}", idx, el); + } + } +} diff --git a/crates/zk_evm/src/precompiles/mod.rs b/crates/zk_evm/src/precompiles/mod.rs new file mode 100644 index 0000000..3a06faa --- /dev/null +++ b/crates/zk_evm/src/precompiles/mod.rs @@ -0,0 +1,136 @@ +use super::*; +use crate::abstractions::*; +use crate::aux_structures::*; + +pub mod ecrecover; +pub mod keccak256; +pub mod sha256; + +use zkevm_opcode_defs::system_params::{ + ECRECOVER_INNER_FUNCTION_PRECOMPILE_ADDRESS, KECCAK256_ROUND_FUNCTION_PRECOMPILE_ADDRESS, + SHA256_ROUND_FUNCTION_PRECOMPILE_ADDRESS, +}; + +#[derive(Clone, Copy, Debug)] +pub struct PrecompileCallParams { + pub input_location: MemoryLocation, + pub timestamp_for_input_read: Timestamp, + pub output_location: MemoryLocation, + pub timestamp_for_output_write: Timestamp, +} + +use zkevm_opcode_defs::PrecompileCallInnerABI; + +pub const fn precompile_abi_in_log(query: LogQuery) -> PrecompileCallInnerABI { + PrecompileCallInnerABI::from_u256(query.key) +} + +#[derive(Clone, Copy, Debug)] +pub struct DefaultPrecompilesProcessor; + +impl crate::abstractions::PrecompilesProcessor for DefaultPrecompilesProcessor { + fn start_frame(&mut self) { + // there are no precompiles to rollback, do nothing + } + fn execute_precompile( + &mut self, + monotonic_cycle_counter: u32, + query: LogQuery, + memory: &mut M, + ) -> Option<(Vec, Vec, PrecompileCyclesWitness)> { + let address_low = u16::from_le_bytes([query.address.0[19], query.address.0[18]]); + match address_low { + KECCAK256_ROUND_FUNCTION_PRECOMPILE_ADDRESS => { + // pure function call, non-revertable + if B { + let (reads, writes, round_witness) = + keccak256::keccak256_rounds_function::( + monotonic_cycle_counter, + query, + memory, + ) + .expect("must generate intermediate witness"); + + Some(( + reads, + writes, + PrecompileCyclesWitness::Keccak256(round_witness), + )) + } else { + let _ = keccak256::keccak256_rounds_function::( + monotonic_cycle_counter, + query, + memory, + ); + + None + } + } + SHA256_ROUND_FUNCTION_PRECOMPILE_ADDRESS => { + // pure function call, non-revertable + if B { + let (reads, writes, round_witness) = sha256::sha256_rounds_function::( + monotonic_cycle_counter, + query, + memory, + ) + .expect("must generate intermediate witness"); + + Some(( + reads, + writes, + PrecompileCyclesWitness::Sha256(round_witness), + )) + } else { + let _ = sha256::sha256_rounds_function::( + monotonic_cycle_counter, + query, + memory, + ); + + None + } + } + ECRECOVER_INNER_FUNCTION_PRECOMPILE_ADDRESS => { + // pure function call, non-revertable + if B { + let (reads, writes, round_witness) = ecrecover::ecrecover_function::( + monotonic_cycle_counter, + query, + memory, + ) + .expect("must generate intermediate witness"); + + Some(( + reads, + writes, + PrecompileCyclesWitness::ECRecover(round_witness), + )) + } else { + let _ = ecrecover::ecrecover_function::( + monotonic_cycle_counter, + query, + memory, + ); + + None + } + } + _ => { + // it's formally allowed for purposes of ergs-burning + // by special contracts + + None + } // _ => { + // unreachable!( + // "Tried to call a precompile from address {:?}", + // query.address + // ); + // } + } + } + + fn finish_frame(&mut self, _panicked: bool) { + // there are no revertable precompile yes, so we are ok + } +} diff --git a/crates/zk_evm/src/precompiles/sha256.rs b/crates/zk_evm/src/precompiles/sha256.rs new file mode 100644 index 0000000..913b8e8 --- /dev/null +++ b/crates/zk_evm/src/precompiles/sha256.rs @@ -0,0 +1,186 @@ +use super::*; + +// for sha256 we do not need complicated buffering as it uses 64 bytes per round, and this is divisible +// by our 32 byte per query + +pub const MEMORY_READS_PER_CYCLE: usize = 2; +pub const MEMORY_WRITES_PER_CYCLE: usize = 1; + +pub use sha2::*; + +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct Sha256RoundWitness { + pub new_request: Option, + pub reads: [MemoryQuery; MEMORY_READS_PER_CYCLE], + pub writes: Option<[MemoryQuery; MEMORY_WRITES_PER_CYCLE]>, +} + +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct Sha256Precompile; + +impl crate::abstractions::Precompile for Sha256Precompile { + type CycleWitness = Sha256RoundWitness; + + fn execute_precompile( + &mut self, + monotonic_cycle_counter: u32, + query: LogQuery, + memory: &mut M, + ) -> Option<(Vec, Vec, Vec)> { + let precompile_call_params = query; + let params = precompile_abi_in_log(precompile_call_params); + let timestamp_to_read = precompile_call_params.timestamp; + let timestamp_to_write = Timestamp(timestamp_to_read.0 + 1); // our default timestamping agreement + + let num_rounds = params.precompile_interpreted_data as usize; + let source_memory_page = params.memory_page_to_read; + let destination_memory_page = params.memory_page_to_write; + let mut current_read_offset = params.input_memory_offset; + let write_offset = params.output_memory_offset; + + let mut read_queries = if B { + Vec::with_capacity(MEMORY_READS_PER_CYCLE * num_rounds) + } else { + vec![] + }; + + let mut write_queries = if B { + Vec::with_capacity(MEMORY_WRITES_PER_CYCLE) + } else { + vec![] + }; + + let mut witness = if B { + Vec::with_capacity(num_rounds) + } else { + vec![] + }; + + let mut internal_state = Sha256::default(); + for round in 0..num_rounds { + let mut block = [0u8; 64]; + + let mut reads = [MemoryQuery::empty(); MEMORY_READS_PER_CYCLE]; + for query_index in 0..MEMORY_READS_PER_CYCLE { + let query = MemoryQuery { + timestamp: timestamp_to_read, + location: MemoryLocation { + memory_type: MemoryType::Heap, + page: MemoryPage(source_memory_page), + index: MemoryIndex(current_read_offset), + }, + value: U256::zero(), + value_is_pointer: false, + rw_flag: false, + is_pended: false, + }; + + let query = memory.execute_partial_query(monotonic_cycle_counter, query); + current_read_offset += 1; + if B { + read_queries.push(query); + } + + reads[query_index] = query; + let data = query.value; + data.to_big_endian(&mut block[(query_index * 32)..(query_index * 32 + 32)]); + } + + // run round function + internal_state.update(&block); + + let is_last = round == num_rounds - 1; + + let mut round_witness = Sha256RoundWitness { + new_request: None, + reads, + writes: None, + }; + + if round == 0 { + round_witness.new_request = Some(precompile_call_params); + } + + if is_last { + // let state_inner = transmute_state(internal_state.clone()).inner; + let state_inner = transmute_state(internal_state.clone()); + // take hash and properly set endianess for the output word + let mut hash_as_bytes32 = [0u8; 32]; + for (chunk, state_word) in + hash_as_bytes32.chunks_mut(4).zip(state_inner.into_iter()) + { + chunk.copy_from_slice(&state_word.to_be_bytes()); + } + let as_u256 = U256::from_big_endian(&hash_as_bytes32); + + let write_location = MemoryLocation { + memory_type: MemoryType::Heap, // we default for some value, here it's not that important + page: MemoryPage(destination_memory_page), + index: MemoryIndex(write_offset), + }; + + let result_query = MemoryQuery { + timestamp: timestamp_to_write, + location: write_location, + value: as_u256, + value_is_pointer: false, + rw_flag: true, + is_pended: false, + }; + let result_query = + memory.execute_partial_query(monotonic_cycle_counter, result_query); + round_witness.writes = Some([result_query]); + + if B { + write_queries.push(result_query); + } + } + + if B { + witness.push(round_witness); + } + } + + if B { + Some((read_queries, write_queries, witness)) + } else { + None + } + } +} + +pub fn sha256_rounds_function( + monotonic_cycle_counter: u32, + precompile_call_params: LogQuery, + memory: &mut M, +) -> Option<(Vec, Vec, Vec)> { + let mut processor = Sha256Precompile::; + processor.execute_precompile(monotonic_cycle_counter, precompile_call_params, memory) +} + +pub type Sha256InnerState = [u32; 8]; + +struct BlockBuffer { + _buffer: [u8; 64], + _pos: u8, +} + +struct CoreWrapper { + core: Sha256VarCore, + _buffer: BlockBuffer, +} + +struct Sha256VarCore { + state: Sha256InnerState, + _block_len: u64, +} + +static_assertions::assert_eq_size!(Sha256, CoreWrapper); + +pub fn transmute_state(reference_state: Sha256) -> Sha256InnerState { + // we use a trick that size of both structures is the same, and even though we do not know a stable field layout, + // we can replicate it + let our_wrapper: CoreWrapper = unsafe { std::mem::transmute(reference_state) }; + + our_wrapper.core.state +} diff --git a/crates/zk_evm/src/reference_impls/decommitter.rs b/crates/zk_evm/src/reference_impls/decommitter.rs new file mode 100644 index 0000000..93b62b9 --- /dev/null +++ b/crates/zk_evm/src/reference_impls/decommitter.rs @@ -0,0 +1,98 @@ +use super::*; + +pub const MEMORY_CELLS_PER_PAGE: usize = (1 << 16) - 1; + +#[derive(Debug)] +pub struct SimpleDecommitter { + known_hashes: HashMap>, + history: HashMap, +} + +impl SimpleDecommitter { + pub fn new() -> Self { + Self { + known_hashes: HashMap::default(), + history: HashMap::default(), + } + } + + pub fn populate(&mut self, elements: Vec<(U256, Vec)>) { + for (hash, values) in elements.into_iter() { + assert!(!self.known_hashes.contains_key(&hash)); + self.known_hashes.insert(hash, values); + } + } +} + +impl DecommittmentProcessor for SimpleDecommitter { + fn decommit_into_memory( + &mut self, + monotonic_cycle_counter: u32, + mut partial_query: DecommittmentQuery, + memory: &mut M, + ) -> (DecommittmentQuery, Option>) { + if let Some((old_page, old_len)) = self.history.get(&partial_query.hash).copied() { + partial_query.is_fresh = false; + partial_query.memory_page = MemoryPage(old_page); + partial_query.decommitted_length = old_len; + + if B { + (partial_query, Some(vec![])) // empty extra data + } else { + (partial_query, None) + } + } else { + // fresh one + let values = self + .known_hashes + .get(&partial_query.hash) + .cloned() + .expect(&format!( + "Code hash {:?} must be known", + &partial_query.hash + )); + let page_to_use = partial_query.memory_page; + let timestamp = partial_query.timestamp; + partial_query.decommitted_length = values.len() as u16; + partial_query.is_fresh = true; + // write into memory + let mut tmp_q = MemoryQuery { + timestamp, + location: MemoryLocation { + memory_type: MemoryType::Code, + page: page_to_use, + index: MemoryIndex(0), + }, + value: U256::zero(), + value_is_pointer: false, + rw_flag: true, + is_pended: false, + }; + + self.history.insert( + partial_query.hash, + ( + partial_query.memory_page.0, + partial_query.decommitted_length, + ), + ); + if B { + for (i, value) in values.iter().enumerate() { + tmp_q.location.index = MemoryIndex(i as u32); + tmp_q.value = *value; + memory.specialized_code_query(monotonic_cycle_counter, tmp_q); + } + + (partial_query, Some(values)) + } else { + for (i, value) in values.into_iter().enumerate() { + tmp_q.location.index = MemoryIndex(i as u32); + tmp_q.value = value; + memory.specialized_code_query(monotonic_cycle_counter, tmp_q); + } + + (partial_query, None) + } + } + } +} diff --git a/crates/zk_evm/src/reference_impls/event_sink.rs b/crates/zk_evm/src/reference_impls/event_sink.rs new file mode 100644 index 0000000..d4c72ee --- /dev/null +++ b/crates/zk_evm/src/reference_impls/event_sink.rs @@ -0,0 +1,175 @@ +use super::*; + +use zkevm_opcode_defs::system_params::{EVENT_AUX_BYTE, L1_MESSAGE_AUX_BYTE}; + +#[derive(Clone, Copy)] +pub struct EventMessage { + pub shard_id: u8, + pub is_first: bool, + pub tx_number_in_block: u16, + pub address: Address, + pub key: U256, + pub value: U256, +} + +impl std::fmt::Debug for EventMessage { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("EventMessage") + .field("shard_id", &self.shard_id) + .field("is_first", &self.is_first) + .field("tx_number_in_block", &self.tx_number_in_block) + .field("address", &self.address) + .field("key", &format_args!("{:#064x}", &self.key)) + .field("value", &format_args!("{:#064x}", &self.value)) + .finish() + } +} + +#[derive(Clone, Debug, PartialEq)] +pub struct ApplicationData { + pub forward: Vec, + pub rollbacks: Vec, +} + +impl Default for ApplicationData { + fn default() -> Self { + Self::empty() + } +} + +impl ApplicationData { + pub fn empty() -> Self { + Self { + forward: vec![], + rollbacks: vec![], + } + } +} + +#[derive(Clone, Debug)] +pub struct InMemoryEventSink { + pub frames_stack: Vec>, +} + +// as usual, if we rollback the current frame then we apply changes to storage immediately, +// otherwise we carry rollbacks to the parent's frames + +impl InMemoryEventSink { + pub fn new() -> Self { + Self { + // we add single frame that will serve as a last one + frames_stack: vec![ApplicationData::empty()], + } + } + + pub fn flatten(mut self) -> (Vec, Vec, Vec) { + assert_eq!( + self.frames_stack.len(), + 1, + "there must exist an initial keeper frame" + ); + let full_history = self.frames_stack.pop().unwrap(); + // we forget rollbacks as we have finished the execution and can just apply them + let ApplicationData { + forward, + rollbacks: _, + } = full_history; + let history = forward.clone(); + let mut tmp = HashMap::::with_capacity(forward.len()); + + // note that we only use "forward" part and discard the rollbacks at the end, + // since if rollbacks of parents were not appended anywhere we just still keep them + for el in forward.into_iter() { + // we are time ordered here in terms of rollbacks + if tmp.get(&el.timestamp.0).is_some() { + assert!(el.rollback); + tmp.remove(&el.timestamp.0); + } else { + assert!(!el.rollback); + tmp.insert(el.timestamp.0, el); + } + } + + // naturally sorted by timestamp + let mut keys: Vec<_> = tmp.keys().into_iter().cloned().collect(); + keys.sort(); + + let mut events = vec![]; + let mut l1_messages = vec![]; + + for k in keys.into_iter() { + let el = tmp.remove(&k).unwrap(); + let LogQuery { + shard_id, + is_service, + tx_number_in_block, + address, + key, + written_value, + aux_byte, + .. + } = el; + + let event = EventMessage { + shard_id, + is_first: is_service, + tx_number_in_block, + address, + key, + value: written_value, + }; + + if aux_byte == EVENT_AUX_BYTE { + events.push(event); + } else { + l1_messages.push(event); + } + } + + (history, events, l1_messages) + } +} + +impl EventSink for InMemoryEventSink { + // when we enter a new frame we should remember all our current applications and rollbacks + // when we exit the current frame then if we did panic we should concatenate all current + // forward and rollback cases + + fn add_partial_query(&mut self, _monotonic_cycle_counter: u32, mut query: LogQuery) { + assert!(query.rw_flag); + assert!(query.aux_byte == EVENT_AUX_BYTE || query.aux_byte == L1_MESSAGE_AUX_BYTE); + assert!(!query.rollback); + // just append to rollbacks and a full history + let frame_data = self.frames_stack.last_mut().expect("frame must be started"); + frame_data.forward.push(query); + // we do not need it explicitly here, but let's be consistent with circuit counterpart + query.rollback = true; + frame_data.rollbacks.push(query); + } + fn start_frame(&mut self, _timestamp: Timestamp) { + let new = ApplicationData::empty(); + self.frames_stack.push(new); + } + fn finish_frame(&mut self, panicked: bool, _timestamp: Timestamp) { + // if we panic then we append forward and rollbacks to the forward of parent, + // otherwise we place rollbacks of child before rollbacks of the parent + let current_frame = self + .frames_stack + .pop() + .expect("frame must be started before finishing"); + let ApplicationData { forward, rollbacks } = current_frame; + let parent_data = self + .frames_stack + .last_mut() + .expect("parent_frame_must_exist"); + if panicked { + parent_data.forward.extend(forward); + // add to forward part, but in reverse order + parent_data.forward.extend(rollbacks.into_iter().rev()); + } else { + parent_data.forward.extend(forward); + // we need to prepend rollbacks. No reverse here, as we do not care yet! + parent_data.rollbacks.extend(rollbacks); + } + } +} diff --git a/crates/zk_evm/src/reference_impls/memory.rs b/crates/zk_evm/src/reference_impls/memory.rs new file mode 100644 index 0000000..36611c6 --- /dev/null +++ b/crates/zk_evm/src/reference_impls/memory.rs @@ -0,0 +1,724 @@ +use std::collections::hash_map::RandomState; +use std::{collections::HashSet, hash::BuildHasher}; + +use crate::vm_state::CallStackEntry; +use crate::vm_state::PrimitiveValue; +use zkevm_opcode_defs::{FatPointer, BOOTLOADER_CALLDATA_PAGE}; + +use super::*; + +pub struct ReusablePool< + T: Sized, + InitFn: Fn() -> T, + OnPullFn: Fn(&mut T) -> (), + OnReturnFn: Fn(&mut T) -> (), +> { + pool: Vec, + init_fn: InitFn, + on_pull_fn: OnPullFn, + on_return_fn: OnReturnFn, +} + +impl T, OnPullFn: Fn(&mut T) -> (), OnReturnFn: Fn(&mut T) -> ()> + ReusablePool +{ + pub fn new_with_capacity( + capacity: usize, + init_fn: InitFn, + on_pull_fn: OnPullFn, + on_return_fn: OnReturnFn, + ) -> Self { + let mut pool = Vec::with_capacity(capacity); + for _ in 0..capacity { + let el = init_fn(); + pool.push(el); + } + + Self { + pool, + init_fn, + on_pull_fn, + on_return_fn, + } + } + + pub fn pull(&mut self) -> T { + if let Some(mut existing) = self.pool.pop() { + (self.on_pull_fn)(&mut existing); + + existing + } else { + let mut new = (self.init_fn)(); + (self.on_pull_fn)(&mut new); + + new + } + } + + pub fn return_element(&mut self, mut el: T) { + (self.on_return_fn)(&mut el); + self.pool.push(el); + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub enum Indirection { + Heap(usize), + AuxHeap(usize), + ExtendedLifetime, + Empty, +} + +// unfortunately we have to name it + +#[derive(Debug)] +pub struct HeapPagesReusablePool { + pool: Vec>, +} + +impl HeapPagesReusablePool { + pub fn new_with_capacity(capacity: usize) -> Self { + let mut pool = Vec::with_capacity(capacity); + for _ in 0..capacity { + let el = heap_init(); + pool.push(el); + } + + Self { pool } + } + + pub fn pull(&mut self) -> Vec { + if let Some(mut existing) = self.pool.pop() { + heap_on_pull(&mut existing); + + existing + } else { + let mut new = heap_init(); + heap_on_pull(&mut new); + + new + } + } + + pub fn return_element(&mut self, mut el: Vec) { + heap_on_return(&mut el); + self.pool.push(el); + } +} + +#[derive(Debug)] +pub struct StackPagesReusablePool { + pool: Vec>, +} + +impl StackPagesReusablePool { + pub fn new_with_capacity(capacity: usize) -> Self { + let mut pool = Vec::with_capacity(capacity); + for _ in 0..capacity { + let el = stack_init(); + pool.push(el); + } + + Self { pool } + } + + pub fn pull(&mut self) -> Vec { + if let Some(mut existing) = self.pool.pop() { + stack_on_pull(&mut existing); + + existing + } else { + let mut new = stack_init(); + stack_on_pull(&mut new); + + new + } + } + + pub fn return_element(&mut self, mut el: Vec) { + stack_on_return(&mut el); + self.pool.push(el); + } +} + +#[derive(Debug)] +pub struct SimpleMemory { + pub stack_pages: Vec<(u32, Vec)>, // easy to purge + pub heaps: Vec<((u32, Vec), (u32, Vec))>, // potentially easier to purge + pub code_pages: HashMap, S>, // live as long as VM is alive + // each frame can get calldata forwarded to it, + // and returndata too. We should keep in mind that + // - calldata ptr CAN be used as returndata + // - returndata ptr CAN be used for calldata + // so we should maintain something like a simple graph for it, + // based on the assumption that even though calldata originates from some HEAP + // it can end up being a returndata, so when we: + // - perform far call we are ok to just keep calldata ptr as indirection + // - but when we return we should check that our returndata ptr doesn't force us to later on + // extend a lifetime of calldataptr indirection + pub pages_with_extended_lifetime: HashMap, S>, + pub page_numbers_indirections: HashMap, + pub indirections_to_cleanup_on_return: Vec>, + + // we do not need a pool for code pages as those are extended lifetime always + pub heaps_pool: HeapPagesReusablePool, + pub stacks_pool: StackPagesReusablePool, +} + +fn heap_init() -> Vec { + vec![U256::zero(); MAX_HEAP_PAGE_SIZE_IN_WORDS] +} + +fn stack_init() -> Vec { + vec![PrimitiveValue::empty(); MAX_STACK_PAGE_SIZE_IN_WORDS] +} + +fn heap_on_pull(_el: &mut Vec) -> () {} + +fn stack_on_pull(_el: &mut Vec) -> () {} + +fn heap_on_return(el: &mut Vec) -> () { + assert_eq!(el.len(), MAX_HEAP_PAGE_SIZE_IN_WORDS); + el.fill(U256::zero()); +} + +fn stack_on_return(el: &mut Vec) -> () { + assert_eq!(el.len(), MAX_STACK_PAGE_SIZE_IN_WORDS); + el.fill(PrimitiveValue::empty()); +} + +// as usual, if we rollback the current frame then we apply changes to storage immediately, +// otherwise we carry rollbacks to the parent's frames + +pub fn new_reference_memory_impl() -> ReusablePool< + Vec, + impl Fn() -> Vec, + impl Fn(&mut Vec) -> (), + impl Fn(&mut Vec) -> (), +> { + ReusablePool::new_with_capacity(1 << 10, heap_init, heap_on_pull, heap_on_return) +} + +impl SimpleMemory { + pub fn new() -> Self { + let mut new = Self { + stack_pages: Vec::with_capacity(1024), // we do not need stack or heaps for root frame as it's never accessible + heaps: Vec::with_capacity(1024), + code_pages: HashMap::with_capacity_and_hasher(1 << 12, S::default()), + pages_with_extended_lifetime: HashMap::with_capacity_and_hasher(64, S::default()), + page_numbers_indirections: HashMap::with_capacity_and_hasher(64, S::default()), + indirections_to_cleanup_on_return: Vec::with_capacity(1024), + heaps_pool: HeapPagesReusablePool::new_with_capacity(1 << 12), + stacks_pool: StackPagesReusablePool::new_with_capacity(1 << 11), + }; + + // this one virtually exists always + new.code_pages + .insert(0u32, vec![U256::zero(); MAX_CODE_PAGE_SIZE_IN_WORDS]); + new.pages_with_extended_lifetime.insert( + BOOTLOADER_CALLDATA_PAGE, + vec![U256::zero(); MAX_HEAP_PAGE_SIZE_IN_WORDS], + ); + new.page_numbers_indirections.insert(0, Indirection::Empty); // quicker lookup + new.indirections_to_cleanup_on_return + .push(HashSet::with_capacity_and_hasher(4, S::default())); + new.heaps.push(( + (0u32, vec![U256::zero(); MAX_HEAP_PAGE_SIZE_IN_WORDS]), + (0u32, vec![U256::zero(); MAX_HEAP_PAGE_SIZE_IN_WORDS]), + )); // formally, so we can access "last" + + new + } + + pub fn new_without_preallocations() -> Self { + let mut new = Self { + stack_pages: Vec::with_capacity(1024), // we do not need stack or heaps for root frame as it's never accessible + heaps: Vec::with_capacity(1024), + code_pages: HashMap::with_capacity_and_hasher(1 << 12, S::default()), + pages_with_extended_lifetime: HashMap::with_capacity_and_hasher(64, S::default()), + page_numbers_indirections: HashMap::with_capacity_and_hasher(64, S::default()), + indirections_to_cleanup_on_return: Vec::with_capacity(1024), + heaps_pool: HeapPagesReusablePool::new_with_capacity(2), + stacks_pool: StackPagesReusablePool::new_with_capacity(2), + }; + + // this one virtually exists always + new.code_pages + .insert(0u32, vec![U256::zero(); MAX_CODE_PAGE_SIZE_IN_WORDS]); + new.pages_with_extended_lifetime.insert( + BOOTLOADER_CALLDATA_PAGE, + vec![U256::zero(); MAX_HEAP_PAGE_SIZE_IN_WORDS], + ); + new.page_numbers_indirections.insert(0, Indirection::Empty); // quicker lookup + new.indirections_to_cleanup_on_return + .push(HashSet::with_capacity_and_hasher(4, S::default())); + new.heaps.push(( + (0u32, vec![U256::zero(); MAX_HEAP_PAGE_SIZE_IN_WORDS]), + (0u32, vec![U256::zero(); MAX_HEAP_PAGE_SIZE_IN_WORDS]), + )); // formally, so we can access "last" + + new + } +} + +impl SimpleMemory { + // Can populate code pages only + pub fn populate_code(&mut self, elements: Vec<(u32, Vec)>) -> Vec<(u32, usize)> { + let mut results = vec![]; + for (page, values) in elements.into_iter() { + assert!(!self.code_pages.contains_key(&page)); + let len = values.len(); + assert!(len <= MAX_CODE_PAGE_SIZE_IN_WORDS); + let mut values = values; + values.resize(MAX_CODE_PAGE_SIZE_IN_WORDS, U256::zero()); + self.code_pages.insert(page, values); + results.push((page, len)); + } + + results + } + + // Can never populate stack or aux heap + pub fn populate_heap(&mut self, values: Vec) { + let heaps_data = self.heaps.last_mut().unwrap(); + let len = values.len(); + assert!(len <= MAX_HEAP_PAGE_SIZE_IN_WORDS); + let mut values = values; + values.resize(MAX_HEAP_PAGE_SIZE_IN_WORDS, U256::zero()); + + heaps_data.0 .1 = values; + } + + pub fn polulate_bootloaders_calldata(&mut self, values: Vec) { + let len = values.len(); + assert!(len <= MAX_HEAP_PAGE_SIZE_IN_WORDS); + let mut values = values; + values.resize(MAX_HEAP_PAGE_SIZE_IN_WORDS, U256::zero()); + + *self + .pages_with_extended_lifetime + .get_mut(&BOOTLOADER_CALLDATA_PAGE) + .unwrap() = values; + } + + pub fn dump_page_content( + &self, + page_number: u32, + range: std::ops::Range, + ) -> Vec<[u8; 32]> { + let u256_words = self.dump_page_content_as_u256_words(page_number, range); + let mut buffer = [0u8; 32]; + let mut result = Vec::with_capacity(u256_words.len()); + for el in u256_words.into_iter() { + el.to_big_endian(&mut buffer); + result.push(buffer); + } + + result + } + + pub fn dump_page_content_as_u256_words( + &self, + page_number: u32, + range: std::ops::Range, + ) -> Vec { + if let Some(page) = self.code_pages.get(&page_number) { + let mut result = vec![]; + for i in range { + if let Some(word) = page.get(i as usize) { + result.push(*word); + } else { + result.push(U256::zero()); + } + } + + return result; + } else { + if let Some(content) = self.pages_with_extended_lifetime.get(&page_number) { + let mut result = vec![]; + for i in range { + if let Some(word) = content.get(i as usize) { + result.push(*word); + } else { + result.push(U256::zero()); + } + } + + return result; + } + + for (page_idx, content) in self.stack_pages.iter().rev() { + if *page_idx == page_number { + let mut result = vec![]; + for i in range { + if let Some(word) = content.get(i as usize) { + result.push(word.value); + } else { + result.push(U256::zero()); + } + } + + return result; + } else { + continue; + } + } + + for (heap_data, aux_heap_data) in self.heaps.iter().rev() { + if heap_data.0 == page_number { + let content = &heap_data.1; + let mut result = vec![]; + for i in range { + if let Some(word) = content.get(i as usize) { + result.push(*word); + } else { + result.push(U256::zero()); + } + } + + return result; + } else if aux_heap_data.0 == page_number { + let content = &aux_heap_data.1; + let mut result = vec![]; + for i in range { + if let Some(word) = content.get(i as usize) { + result.push(*word); + } else { + result.push(U256::zero()); + } + } + + return result; + } else { + continue; + } + } + } + + vec![U256::zero(); range.len()] + } + + pub fn dump_full_page(&self, page_number: u32) -> Vec<[u8; 32]> { + let upper_bound = MAX_HEAP_PAGE_SIZE_IN_WORDS as u32; + self.dump_page_content(page_number, 0..upper_bound) + } +} + +impl Memory for SimpleMemory { + fn execute_partial_query( + &mut self, + _monotonic_cycle_counter: u32, + mut query: MemoryQuery, + ) -> MemoryQuery { + // we assume that all pages were pre-created, and use a hint here + let page_number = query.location.page.0; + match query.location.memory_type { + MemoryType::Stack => { + if query.rw_flag { + let (idx, page) = self.stack_pages.last_mut().unwrap(); + assert_eq!(*idx, page_number); + let primitive = PrimitiveValue { + value: query.value, + is_pointer: query.value_is_pointer, + }; + page[query.location.index.0 as usize] = primitive + } else { + let (idx, page) = self.stack_pages.last().unwrap(); + assert_eq!(*idx, page_number); + let primitive = page[query.location.index.0 as usize]; + query.value = primitive.value; + query.value_is_pointer = primitive.is_pointer; + } + } + a @ MemoryType::Heap | a @ MemoryType::AuxHeap => { + assert!(query.value_is_pointer == false); + if query.rw_flag { + let ( + (current_heap_page, current_heap_content), + (current_aux_heap_page, current_aux_heap_content), + ) = self.heaps.last_mut().unwrap(); + if a == MemoryType::Heap { + debug_assert_eq!(*current_heap_page, query.location.page.0); + current_heap_content[query.location.index.0 as usize] = query.value; + } else if a == MemoryType::AuxHeap { + debug_assert_eq!(*current_aux_heap_page, query.location.page.0); + current_aux_heap_content[query.location.index.0 as usize] = query.value; + } else { + unreachable!() + } + } else { + let ( + (current_heap_page, current_heap_content), + (current_aux_heap_page, current_aux_heap_content), + ) = self.heaps.last().unwrap(); + if a == MemoryType::Heap { + debug_assert_eq!(*current_heap_page, query.location.page.0); + query.value = current_heap_content[query.location.index.0 as usize]; + } else if a == MemoryType::AuxHeap { + debug_assert_eq!(*current_aux_heap_page, query.location.page.0); + query.value = current_aux_heap_content[query.location.index.0 as usize]; + } else { + unreachable!() + } + } + } + MemoryType::FatPointer => { + assert!(query.rw_flag == false); + assert!(query.value_is_pointer == false); + let indirection = self + .page_numbers_indirections + .get(&page_number) + .expect("fat pointer only points to reachable memory"); + + match indirection { + Indirection::Heap(index) => { + let forwarded_heap_data = &self.heaps[*index]; + assert_eq!(forwarded_heap_data.0 .0, query.location.page.0); + query.value = forwarded_heap_data.0 .1[query.location.index.0 as usize]; + } + Indirection::AuxHeap(index) => { + let forwarded_heap_data = &self.heaps[*index]; + assert_eq!(forwarded_heap_data.1 .0, query.location.page.0); + query.value = forwarded_heap_data.1 .1[query.location.index.0 as usize]; + } + Indirection::ExtendedLifetime => { + let page = self + .pages_with_extended_lifetime + .get(&page_number) + .expect("indirection target must exist"); + query.value = page[query.location.index.0 as usize]; + } + Indirection::Empty => { + query.value = U256::zero(); + } + } + } + MemoryType::Code => { + unreachable!("code should be through specialized query"); + } + } + + query + } + + fn specialized_code_query( + &mut self, + _monotonic_cycle_counter: u32, + query: MemoryQuery, + ) -> MemoryQuery { + assert_eq!(query.location.memory_type, MemoryType::Code); + let page = query.location.page.0; + + let idx = query.location.index.0 as usize; + let mut query = query; + if query.rw_flag { + if self.code_pages.contains_key(&page) == false { + self.code_pages + .insert(page, vec![U256::zero(); MAX_CODE_PAGE_SIZE_IN_WORDS]); + } + let page_content = self.code_pages.get_mut(&page).unwrap(); + page_content[idx] = query.value; + } else { + debug_assert!(query.value_is_pointer == false); + let page_content = self.code_pages.get(&page).unwrap(); + query.value = page_content[idx]; + } + + query + } + + fn read_code_query(&self, _monotonic_cycle_counter: u32, query: MemoryQuery) -> MemoryQuery { + assert_eq!(query.location.memory_type, MemoryType::Code); + assert!(!query.rw_flag); + let page = query.location.page.0; + + let idx = query.location.index.0 as usize; + let mut query = query; + + debug_assert!(query.value_is_pointer == false); + let page_content = self.code_pages.get(&page).unwrap(); + query.value = page_content[idx]; + + query + } + + // Notify that we start a new global frame. `calldata_fat_pointer` can not leak in a sense + // that it's already alive somewhere + fn start_global_frame( + &mut self, + _current_base_page: MemoryPage, + new_base_page: MemoryPage, + calldata_fat_pointer: FatPointer, + _timestamp: Timestamp, + ) { + use zkevm_opcode_defs::decoding::EncodingModeProduction; + + // we can prepare and preallocate, and then deallocate the number of pages that we want + let stack_page = + CallStackEntry::<8, EncodingModeProduction>::stack_page_from_base(new_base_page); + let stack_page_from_pool = self.stacks_pool.pull(); + self.stack_pages.push((stack_page.0, stack_page_from_pool)); + // self.stack_pages.push((stack_page.0, vec![PrimitiveValue::empty(); MAX_STACK_PAGE_SIZE_IN_WORDS])); + + let heap_page = + CallStackEntry::<8, EncodingModeProduction>::heap_page_from_base(new_base_page); + + let aux_heap_page = + CallStackEntry::<8, EncodingModeProduction>::aux_heap_page_from_base(new_base_page); + + let current_heaps_data = self.heaps.last().unwrap(); + let current_heap_page = current_heaps_data.0 .0; + let current_aux_heap_page = current_heaps_data.1 .0; + + let idx_to_use_for_calldata_ptrs = self.heaps.len() - 1; + + let heap_page_from_pool = self.heaps_pool.pull(); + let aux_heap_page_from_pool = self.heaps_pool.pull(); + + self.heaps.push(( + (heap_page.0, heap_page_from_pool), + (aux_heap_page.0, aux_heap_page_from_pool), + )); + + // self.heaps.push( + // ( + // (heap_page.0, vec![U256::zero(); MAX_HEAP_PAGE_SIZE_IN_WORDS]), + // (aux_heap_page.0, vec![U256::zero(); MAX_HEAP_PAGE_SIZE_IN_WORDS]) + // ) + // ); + // we may want to later on cleanup indirections + self.indirections_to_cleanup_on_return + .push(HashSet::with_capacity(4)); + + if calldata_fat_pointer.memory_page == 0 { + // no need to do anything + } else if calldata_fat_pointer.memory_page == current_heap_page { + self.page_numbers_indirections.insert( + current_heap_page, + Indirection::Heap(idx_to_use_for_calldata_ptrs), + ); + // if we will return from here and returndata page will not "leak" calldata page via forwarding, then we can cleanup the indirection + self.indirections_to_cleanup_on_return + .last_mut() + .unwrap() + .insert(current_heap_page); + } else if calldata_fat_pointer.memory_page == current_aux_heap_page { + self.page_numbers_indirections.insert( + current_aux_heap_page, + Indirection::AuxHeap(idx_to_use_for_calldata_ptrs), + ); + self.indirections_to_cleanup_on_return + .last_mut() + .unwrap() + .insert(current_aux_heap_page); + } else { + // it must be some extended lifetime page + assert!(self + .pages_with_extended_lifetime + .contains_key(&calldata_fat_pointer.memory_page)); + self.page_numbers_indirections.insert( + calldata_fat_pointer.memory_page, + Indirection::ExtendedLifetime, + ); + } + } + + // here we potentially want to do some cleanup + fn finish_global_frame( + &mut self, + base_page: MemoryPage, + returndata_fat_pointer: FatPointer, + _timestamp: Timestamp, + ) { + use zkevm_opcode_defs::decoding::EncodingModeProduction; + + // stack always goes out of scope + let stack_page = + CallStackEntry::<8, EncodingModeProduction>::stack_page_from_base(base_page); + + let (stack_page_number, stack_page_to_reuse) = self.stack_pages.pop().unwrap(); + assert_eq!(stack_page_number, stack_page.0); + self.stacks_pool.return_element(stack_page_to_reuse); + + let returndata_page = returndata_fat_pointer.memory_page; + + // we can cleanup all the heap pages that derive from base, if one of those is not in returndata + let heap_page = CallStackEntry::<8, EncodingModeProduction>::heap_page_from_base(base_page); + let aux_heap_page = + CallStackEntry::<8, EncodingModeProduction>::aux_heap_page_from_base(base_page); + + // when we finish the global frame then ALL indirections go out of scope except + // one that becomes returndata itself (if returndata is not taken from heap or aux heap) + + let ( + (current_heap_page, current_heap_content), + (current_aux_heap_page, current_aux_heap_content), + ) = self.heaps.pop().unwrap(); + assert_eq!(heap_page.0, current_heap_page); + assert_eq!(aux_heap_page.0, current_aux_heap_page); + + let mut current_frame_indirections_to_cleanup = self + .indirections_to_cleanup_on_return + .pop() + .expect("indirections must exist"); + let previous_frame_indirections_to_cleanup = self + .indirections_to_cleanup_on_return + .last_mut() + .expect("previous page indirections must exist"); + + if returndata_page == current_heap_page { + // we add indirection and move to extended lifetime + let existing = self + .pages_with_extended_lifetime + .insert(current_heap_page, current_heap_content); + assert!(existing.is_none()); + self.page_numbers_indirections + .insert(current_heap_page, Indirection::ExtendedLifetime); + previous_frame_indirections_to_cleanup.insert(current_heap_page); + + // and we can reuse another page + self.heaps_pool.return_element(current_aux_heap_content); + } else if returndata_page == current_aux_heap_page { + // we add indirection and move to extended lifetime + let existing = self + .pages_with_extended_lifetime + .insert(current_aux_heap_page, current_aux_heap_content); + assert!(existing.is_none()); + self.page_numbers_indirections + .insert(current_aux_heap_page, Indirection::ExtendedLifetime); + previous_frame_indirections_to_cleanup.insert(current_aux_heap_page); + + // and we can reuse another page + self.heaps_pool.return_element(current_heap_content); + } else { + // this means "forwarding" of some form, + // so we carry indirection forward + + // so it's not masked ret panic page + if returndata_page != 0 { + assert!(self + .page_numbers_indirections + .contains_key(&returndata_page), + "expected that indirections contain page {}. Heap page = {}, aux heap page = {}, full set = {:?}", + returndata_page, + current_heap_page, + current_aux_heap_page, + &self.page_numbers_indirections + ); + current_frame_indirections_to_cleanup.remove(&returndata_page); // otherwise it'll be lost + previous_frame_indirections_to_cleanup.insert(returndata_page); + } + + // and we can reuse all pages + self.heaps_pool.return_element(current_heap_content); + self.heaps_pool.return_element(current_aux_heap_content); + } + + // now it's safe to cleanup all the indirections we have encountered at this page + + for el in current_frame_indirections_to_cleanup.into_iter() { + let existing = self.page_numbers_indirections.remove(&el); + assert!(existing.is_some(), "double free in indirection"); + } + } +} diff --git a/crates/zk_evm/src/reference_impls/mod.rs b/crates/zk_evm/src/reference_impls/mod.rs new file mode 100644 index 0000000..c779a84 --- /dev/null +++ b/crates/zk_evm/src/reference_impls/mod.rs @@ -0,0 +1,9 @@ +use super::*; + +use crate::abstractions::*; +use crate::aux_structures::*; +use std::collections::HashMap; + +pub mod decommitter; +pub mod event_sink; +pub mod memory; diff --git a/crates/zk_evm/src/testing/debug_tracer.rs b/crates/zk_evm/src/testing/debug_tracer.rs new file mode 100644 index 0000000..c8d0916 --- /dev/null +++ b/crates/zk_evm/src/testing/debug_tracer.rs @@ -0,0 +1,205 @@ +use crate::vm_state::VmState; +use crate::vm_state::cycle::AuxTracingInformation; + +use super::*; + +pub struct NoopTracer< + S: crate::abstractions::Storage, + M: crate::abstractions::Memory, + EV: crate::abstractions::EventSink, + PP: crate::abstractions::PrecompilesProcessor, + DP: crate::abstractions::DecommittmentProcessor, + WT: crate::witness_trace::VmWitnessTracer +> { + _marker: std::marker::PhantomData> +} + +impl< + 'a, + S: crate::abstractions::Storage, + M: crate::abstractions::Memory, + EV: crate::abstractions::EventSink, + PP: crate::abstractions::PrecompilesProcessor, + DP: crate::abstractions::DecommittmentProcessor, + WT: crate::witness_trace::VmWitnessTracer +> std::fmt::Debug for NoopTracer<'a, S, M, EV, PP, DP, WT> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("NoopTracer") + .finish() + } +} + +impl< + 'a, + S: crate::abstractions::Storage, + M: crate::abstractions::Memory, + EV: crate::abstractions::EventSink, + PP: crate::abstractions::PrecompilesProcessor, + DP: crate::abstractions::DecommittmentProcessor, + WT: crate::witness_trace::VmWitnessTracer +> NoopTracer<'a, S, M, EV, PP, DP, WT> { + pub fn new() -> Self { + Self { + _marker: std::marker::PhantomData + } + } +} + +impl< + S: crate::abstractions::Storage, + M: crate::abstractions::Memory, + EV: crate::abstractions::EventSink, + PP: crate::abstractions::PrecompilesProcessor, + DP: crate::abstractions::DecommittmentProcessor, + WT: crate::witness_trace::VmWitnessTracer +> DebugTracer, AuxTracingInformation, ()> for NoopTracer<'a, S, M, EV, PP, DP, WT> { + #[inline] + fn perform_before_execution(&mut self, _main: &VmState< S, M, EV, PP, DP, WT>, _aux: AuxTracingInformation) { + + } + + #[inline] + fn perform_after_execution(&mut self, _main: &VmState< S, M, EV, PP, DP, WT>, _aux: ()) { + + } +} + +pub struct ClosureBasedTracer< + S: crate::abstractions::Storage, + M: crate::abstractions::Memory, + EV: crate::abstractions::EventSink, + PP: crate::abstractions::PrecompilesProcessor, + DP: crate::abstractions::DecommittmentProcessor, + WT: crate::witness_trace::VmWitnessTracer, + F: FnMut(&VmState< S, M, EV, PP, DP, WT>, AuxTracingInformation, u32, ) -> () +> { + closure: F, + cycle_number: u32, + _marker: std::marker::PhantomData> +} + +impl< + S: crate::abstractions::Storage, + M: crate::abstractions::Memory, + EV: crate::abstractions::EventSink, + PP: crate::abstractions::PrecompilesProcessor, + DP: crate::abstractions::DecommittmentProcessor, + WT: crate::witness_trace::VmWitnessTracer, + F: FnMut(&VmState, AuxTracingInformation, u32, ) -> () +> std::fmt::Debug for ClosureBasedTracer< S, M, EV, PP, DP, WT, F> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("ClosureBasedTracer") + .finish() + } +} + +impl< + S: crate::abstractions::Storage, + M: crate::abstractions::Memory, + EV: crate::abstractions::EventSink, + PP: crate::abstractions::PrecompilesProcessor, + DP: crate::abstractions::DecommittmentProcessor, + WT: crate::witness_trace::VmWitnessTracer, + F: FnMut(&VmState< S, M, EV, PP, DP, WT>, AuxTracingInformation, u32, ) -> () +> ClosureBasedTracer< S, M, EV, PP, DP, WT, F> { + pub fn new(closure: F) -> Self { + Self { + closure, + cycle_number: 0u32, + _marker: std::marker::PhantomData + } + } +} + +impl< + S: crate::abstractions::Storage, + M: crate::abstractions::Memory, + EV: crate::abstractions::EventSink, + PP: crate::abstractions::PrecompilesProcessor, + DP: crate::abstractions::DecommittmentProcessor, + WT: crate::witness_trace::VmWitnessTracer, + F: FnMut(&VmState, AuxTracingInformation, u32, ) -> () +> DebugTracer, AuxTracingInformation, ()> for ClosureBasedTracer<'a, S, M, EV, PP, DP, WT, F> { + fn perform_before_execution(&mut self, main: &VmState< S, M, EV, PP, DP, WT>, aux: AuxTracingInformation) { + (self.closure)(main, aux, self.cycle_number); + } + + fn perform_after_execution(&mut self, _main: &VmState< S, M, EV, PP, DP, WT>, _aux: ()) { + self.cycle_number += 1; + } +} + + +pub struct DynTracer< + 'b, + S: crate::abstractions::Storage, + M: crate::abstractions::Memory, + EV: crate::abstractions::EventSink, + PP: crate::abstractions::PrecompilesProcessor, + DP: crate::abstractions::DecommittmentProcessor, + WT: crate::witness_trace::VmWitnessTracer, +> { + // pub before_closure: Option, AuxTracingInformation, u32, ) -> () + 'a>>, + // pub after_closure: Option, (), u32, ) -> () + 'a>>, + pub before_closure: Option<&'b mut dyn FnMut(&VmState< S, M, EV, PP, DP, WT>, AuxTracingInformation, u32, ) -> ()>, + pub after_closure: Option<&'b mut dyn FnMut(&VmState< S, M, EV, PP, DP, WT>, (), u32, ) -> ()>, + cycle_number: u32, + _marker: std::marker::PhantomData> +} + +impl< + 'b, + S: crate::abstractions::Storage, + M: crate::abstractions::Memory, + EV: crate::abstractions::EventSink, + PP: crate::abstractions::PrecompilesProcessor, + DP: crate::abstractions::DecommittmentProcessor, + WT: crate::witness_trace::VmWitnessTracer, +> std::fmt::Debug for DynTracer< 'b, S, M, EV, PP, DP, WT> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("DynTracer") + .finish() + } +} + +impl< + 'b, + S: crate::abstractions::Storage, + M: crate::abstractions::Memory, + EV: crate::abstractions::EventSink, + PP: crate::abstractions::PrecompilesProcessor, + DP: crate::abstractions::DecommittmentProcessor, + WT: crate::witness_trace::VmWitnessTracer, +> DynTracer< 'b, S, M, EV, PP, DP, WT> { + pub fn new() -> Self { + Self { + before_closure: None, + after_closure: None, + cycle_number: 0u32, + _marker: std::marker::PhantomData + } + } +} + +impl< + 'b, + S: crate::abstractions::Storage, + M: crate::abstractions::Memory, + EV: crate::abstractions::EventSink, + PP: crate::abstractions::PrecompilesProcessor, + DP: crate::abstractions::DecommittmentProcessor, + WT: crate::witness_trace::VmWitnessTracer, +> DebugTracer, AuxTracingInformation, ()> for DynTracer<'a, 'b, S, M, EV, PP, DP, WT> { + fn perform_before_execution(&mut self, main: &VmState< S, M, EV, PP, DP, WT>, aux: AuxTracingInformation) { + if let Some(closure) = self.before_closure.as_deref_mut() { + (closure)(main, aux, self.cycle_number); + } + } + + fn perform_after_execution(&mut self, main: &VmState< S, M, EV, PP, DP, WT>, aux: ()) { + if let Some(closure) = self.after_closure.as_deref_mut() { + (closure)(main, aux, self.cycle_number); + } + self.cycle_number += 1; + } +} \ No newline at end of file diff --git a/crates/zk_evm/src/testing/mod.rs b/crates/zk_evm/src/testing/mod.rs new file mode 100644 index 0000000..7f1883e --- /dev/null +++ b/crates/zk_evm/src/testing/mod.rs @@ -0,0 +1,75 @@ +use super::*; +use crate::abstractions::*; +use crate::aux_structures::*; +use std::collections::*; + +pub const NUM_SHARDS: usize = 2; + +use crate::reference_impls::{decommitter::SimpleDecommitter, event_sink::*, memory::SimpleMemory}; +pub mod simple_tracer; +pub mod storage; + +use self::storage::InMemoryStorage; +use crate::precompiles::DefaultPrecompilesProcessor; +use crate::witness_trace::DummyTracer; + +pub struct BasicTestingTools { + pub storage: InMemoryStorage, + pub memory: SimpleMemory, + pub event_sink: InMemoryEventSink, + pub precompiles_processor: DefaultPrecompilesProcessor, + pub decommittment_processor: SimpleDecommitter, + pub witness_tracer: DummyTracer, +} + +pub fn create_default_testing_tools() -> BasicTestingTools { + let storage = InMemoryStorage::new(); + let memory = SimpleMemory::new(); + let event_sink = InMemoryEventSink::new(); + let precompiles_processor = DefaultPrecompilesProcessor::; + let decommittment_processor = SimpleDecommitter::::new(); + let witness_tracer = DummyTracer; + + BasicTestingTools:: { + storage, + memory, + event_sink, + precompiles_processor, + decommittment_processor, + witness_tracer, + } +} + +pub fn get_final_net_states( + tools: BasicTestingTools, +) -> ( + Vec, + [HashMap>; NUM_SHARDS], + Vec, + Vec, + Vec, + SimpleMemory, +) { + let BasicTestingTools:: { + storage, + event_sink, + memory, + .. + } = tools; + + let final_storage_state = storage.inner.clone(); + let (full_storage_access_history, _per_slot_history) = storage.flatten_and_net_history(); + let (events_log_history, events, l1_messages) = event_sink.flatten(); + + ( + full_storage_access_history, + final_storage_state, + events_log_history, + events, + l1_messages, + memory, + ) +} + +#[cfg(test)] +mod tests; diff --git a/crates/zk_evm/src/testing/simple_tracer.rs b/crates/zk_evm/src/testing/simple_tracer.rs new file mode 100644 index 0000000..5eea1c8 --- /dev/null +++ b/crates/zk_evm/src/testing/simple_tracer.rs @@ -0,0 +1,110 @@ +use crate::abstractions::Tracer; +use crate::testing::{ + AfterDecodingData, AfterExecutionData, BeforeExecutionData, VmLocalStateData, +}; + +#[derive(Debug, Clone, Copy)] +pub struct NoopTracer; + +impl Tracer for NoopTracer { + type SupportedMemory = (); + #[inline] + fn before_decoding(&mut self, _state: VmLocalStateData<'_>, _memory: &Self::SupportedMemory) {} + #[inline] + fn after_decoding( + &mut self, + _state: VmLocalStateData<'_>, + _data: AfterDecodingData, + _memory: &Self::SupportedMemory, + ) { + } + #[inline] + fn before_execution( + &mut self, + _state: VmLocalStateData<'_>, + _data: BeforeExecutionData, + _memory: &Self::SupportedMemory, + ) { + } + #[inline] + fn after_execution( + &mut self, + _state: VmLocalStateData<'_>, + _data: AfterExecutionData, + _memory: &Self::SupportedMemory, + ) { + } +} + +// pub struct ClosureBasedTracer< +// I, +// F0: FnMut(&mut I, VmLocalStateData<'_>, &dyn Memory) -> (), +// F1: FnMut(&mut I, VmLocalStateData<'_>, AfterDecodingData, &dyn Memory) -> (), +// F2: FnMut(&mut I, VmLocalStateData<'_>, BeforeExecutionData, &dyn Memory) -> (), +// F3: FnMut(&mut I, VmLocalStateData<'_>, AfterExecutionData, &dyn Memory) -> (), +// const BEFORE_DECODING: bool, +// const AFTER_DECODING: bool, +// const BEFORE_EXECUTION: bool, +// const AFTER_EXECUTION: bool, +// > { +// pub inner_state: I, +// pub before_decoding: Option, +// pub after_decoding: Option, +// pub before_execution: Option, +// pub after_execution: Option, +// } + +// impl< +// I: 'static, +// F0: FnMut(&mut I, VmLocalStateData<'_>, &dyn Memory) -> () + 'static, +// F1: FnMut(&mut I, VmLocalStateData<'_>, AfterDecodingData, &dyn Memory) -> () + 'static, +// F2: FnMut(&mut I, VmLocalStateData<'_>, BeforeExecutionData, &dyn Memory) -> () + 'static, +// F3: FnMut(&mut I, VmLocalStateData<'_>, AfterExecutionData, &dyn Memory) -> () + 'static, +// const BEFORE_DECODING: bool, +// const AFTER_DECODING: bool, +// const BEFORE_EXECUTION: bool, +// const AFTER_EXECUTION: bool, +// > Tracer for ClosureBasedTracer { +// const CALL_BEFORE_DECODING: bool = BEFORE_DECODING; +// const CALL_AFTER_DECODING: bool = AFTER_DECODING; +// const CALL_BEFORE_EXECUTION: bool = BEFORE_EXECUTION; +// const CALL_AFTER_EXECUTION: bool = AFTER_EXECUTION; + +// fn before_decoding(&mut self, state: VmLocalStateData<'_>, memory: &dyn Memory) { +// if let Some(c) = self.before_decoding.as_mut() { +// (c)(&mut self.inner_state, state, memory) +// } +// } +// fn after_decoding(&mut self, state: VmLocalStateData<'_>, data: AfterDecodingData, memory: &dyn Memory) { +// if let Some(c) = self.after_decoding.as_mut() { +// c(&mut self.inner_state, state, data, memory) +// } +// } +// fn before_execution(&mut self, state: VmLocalStateData<'_>, data: BeforeExecutionData, memory: &dyn Memory) { +// if let Some(c) = self.before_execution.as_mut() { +// c(&mut self.inner_state, state, data, memory) +// } +// } +// fn after_execution(&mut self, state: VmLocalStateData<'_>, data: AfterExecutionData, memory: &dyn Memory) { +// if let Some(c) = self.after_execution.as_mut() { +// c(&mut self.inner_state, state, data, memory) +// } +// } +// } + +// impl< +// I, +// F0: FnMut(&mut I, VmLocalStateData<'_>, &dyn Memory) -> (), +// F1: FnMut(&mut I, VmLocalStateData<'_>, AfterDecodingData, &dyn Memory) -> (), +// F2: FnMut(&mut I, VmLocalStateData<'_>, BeforeExecutionData, &dyn Memory) -> (), +// F3: FnMut(&mut I, VmLocalStateData<'_>, AfterExecutionData, &dyn Memory) -> (), +// const BEFORE_DECODING: bool, +// const AFTER_DECODING: bool, +// const BEFORE_EXECUTION: bool, +// const AFTER_EXECUTION: bool, +// > std::fmt::Debug for ClosureBasedTracer { +// fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +// f.debug_struct(&"ClosureBasedTracer") +// .finish() +// } +// } diff --git a/crates/zk_evm/src/testing/storage.rs b/crates/zk_evm/src/testing/storage.rs new file mode 100644 index 0000000..7f964bb --- /dev/null +++ b/crates/zk_evm/src/testing/storage.rs @@ -0,0 +1,184 @@ +use super::ApplicationData; +use super::*; + +#[derive(Debug, Clone)] +pub struct InMemoryStorage { + pub inner: [HashMap>; NUM_SHARDS], + pub cold_warm_markers: [HashMap>; NUM_SHARDS], + pub frames_stack: Vec>, +} + +// as usual, if we rollback the current frame then we apply changes to storage immediately, +// otherwise we carry rollbacks to the parent's frames + +impl InMemoryStorage { + pub fn new() -> Self { + Self { + inner: [(); NUM_SHARDS].map(|_| HashMap::default()), + cold_warm_markers: [(); NUM_SHARDS].map(|_| HashMap::default()), + frames_stack: vec![ApplicationData::empty()], + } + } + + pub fn populate(&mut self, elements: Vec<(u8, Address, U256, U256)>) { + for (shard_id, address, key, value) in elements.into_iter() { + let shard_level_map = &mut self.inner[shard_id as usize]; + let address_level_map = shard_level_map.entry(address).or_default(); + address_level_map.insert(key, value); + } + } + + pub fn flatten_and_net_history( + mut self, + ) -> (Vec, HashMap<(u8, Address, U256), Vec>) { + assert_eq!( + self.frames_stack.len(), + 1, + "there must exist an initial keeper frame" + ); + let full_history = self.frames_stack.pop().unwrap(); + // we forget rollbacks as we have finished the execution and can just apply them + let ApplicationData { + forward, + rollbacks: _, + } = full_history; + let history = forward.clone(); + // we want to have net queries for every storage slot + let mut tmp = HashMap::<(u8, Address, U256), Vec>::with_capacity(forward.len()); + + // note that we only use "forward" part and discard the rollbacks at the end, + // since if rollbacks of parents were not appended anywhere we just still keep them + for el in forward.into_iter() { + let LogQuery { + timestamp, + shard_id, + address, + key, + rollback, + .. + } = ⪙ + + let entry = tmp.entry((*shard_id, *address, *key)).or_insert(vec![]); + if let Some(last) = entry.last() { + // forward application always has monotonic time + if !rollback { + assert!(timestamp.0 > last.timestamp.0); + } + } + + entry.push(el); + } + + (history, tmp) + } +} + +impl Storage for InMemoryStorage { + fn estimate_refunds_for_write( + &mut self, + _monotonic_cycle_counter: u32, + _partial_query: &LogQuery, + ) -> RefundType { + RefundType::None + } + + fn execute_partial_query( + &mut self, + _monotonic_cycle_counter: u32, + mut query: LogQuery, + ) -> LogQuery { + let shard_level_map = &mut self.inner[query.shard_id as usize]; + let shard_level_warm_map = &mut self.cold_warm_markers[query.shard_id as usize]; + let frame_data = self.frames_stack.last_mut().expect("frame must be started"); + + assert!(!query.rollback); + if query.rw_flag { + // write, also append rollback + let address_level_map = shard_level_map.entry(query.address).or_default(); + let current_value = address_level_map + .get(&query.key) + .copied() + .unwrap_or(U256::zero()); + address_level_map.insert(query.key, query.written_value); + + // mark as warm, and return + let address_level_warm_map = shard_level_warm_map.entry(query.address).or_default(); + let warm = address_level_warm_map.contains(&query.key); + if !warm { + address_level_warm_map.insert(query.key); + } + query.read_value = current_value; + + frame_data.forward.push(query); + query.rollback = true; + frame_data.rollbacks.push(query); + query.rollback = false; + + query + } else { + // read, do not append to rollback + let address_level_map = shard_level_map.entry(query.address).or_default(); + let current_value = address_level_map + .get(&query.key) + .copied() + .unwrap_or(U256::zero()); + // mark as warm, and return + let address_level_warm_map = shard_level_warm_map.entry(query.address).or_default(); + let warm = address_level_warm_map.contains(&query.key); + if !warm { + address_level_warm_map.insert(query.key); + } + query.read_value = current_value; + frame_data.forward.push(query); + + query + } + } + fn start_frame(&mut self, _timestamp: Timestamp) { + let new = ApplicationData::empty(); + self.frames_stack.push(new); + } + fn finish_frame(&mut self, _timestamp: Timestamp, panicked: bool) { + // if we panic then we append forward and rollbacks to the forward of parent, + // otherwise we place rollbacks of child before rollbacks of the parent + let current_frame = self + .frames_stack + .pop() + .expect("frame must be started before finishing"); + let ApplicationData { forward, rollbacks } = current_frame; + let parent_data = self + .frames_stack + .last_mut() + .expect("parent_frame_must_exist"); + if panicked { + // perform actual rollback + for query in rollbacks.iter().rev() { + let LogQuery { + shard_id, + address, + key, + read_value, + written_value, + .. + } = *query; + let shard_level_map = &mut self.inner[shard_id as usize]; + let address_level_map = shard_level_map + .get_mut(&address) + .expect("must always exist on rollback"); + let current_value_ref = address_level_map + .get_mut(&key) + .expect("must always exist on rollback"); + assert_eq!(*current_value_ref, written_value); // compare current value + *current_value_ref = read_value; // write back an old value + } + + parent_data.forward.extend(forward); + // add to forward part, but in reverse order + parent_data.forward.extend(rollbacks.into_iter().rev()); + } else { + parent_data.forward.extend(forward); + // we need to prepend rollbacks. No reverse here, as we do not care yet! + parent_data.rollbacks.extend(rollbacks); + } + } +} diff --git a/crates/zk_evm/src/testing/tests/mod.rs b/crates/zk_evm/src/testing/tests/mod.rs new file mode 100644 index 0000000..03aee2e --- /dev/null +++ b/crates/zk_evm/src/testing/tests/mod.rs @@ -0,0 +1,66 @@ +use super::*; + +use zkevm_opcode_defs::system_params::BOOTLOADER_FORMAL_ADDRESS; + +use crate::precompiles::*; +use crate::vm_state::*; +use crate::{ + block_properties::BlockProperties, + reference_impls::{event_sink::InMemoryEventSink, memory::SimpleMemory}, + testing::storage::InMemoryStorage, + vm_state::VmState, + witness_trace::DummyTracer, +}; + +pub fn create_default_block_info() -> BlockProperties { + BlockProperties { + default_aa_code_hash: U256::zero(), + zkporter_is_available: true, + } +} + +pub fn create_initial_vm_state_for_basic_testing( + tools: BasicTestingTools, + block_properties: BlockProperties, +) -> VmState< + InMemoryStorage, + SimpleMemory, + InMemoryEventSink, + DefaultPrecompilesProcessor, + SimpleDecommitter, + DummyTracer, +> { + let mut vm = VmState::empty_state( + tools.storage, + tools.memory, + tools.event_sink, + tools.precompiles_processor, + tools.decommittment_processor, + tools.witness_tracer, + block_properties, + ); + + let bootloader_context = CallStackEntry { + this_address: *BOOTLOADER_FORMAL_ADDRESS, + msg_sender: Address::zero(), + code_address: *BOOTLOADER_FORMAL_ADDRESS, + base_memory_page: MemoryPage(zkevm_opcode_defs::BOOTLOADER_BASE_PAGE), + code_page: MemoryPage(zkevm_opcode_defs::BOOTLOADER_CODE_PAGE), + sp: 0u16, + pc: 0u16, + exception_handler_location: 0u16, + ergs_remaining: zkevm_opcode_defs::system_params::VM_INITIAL_FRAME_ERGS, + this_shard_id: 0u8, + caller_shard_id: 0u8, + code_shard_id: 0u8, + is_static: false, + is_local_frame: false, + context_u128_value: 0, + heap_bound: 0u32, + aux_heap_bound: 0u32, + }; + + vm.push_bootloader_context(0, bootloader_context); + + vm +} diff --git a/crates/zk_evm/src/testing/tests/precompiles/ecrecover.rs b/crates/zk_evm/src/testing/tests/precompiles/ecrecover.rs new file mode 100644 index 0000000..0585b7d --- /dev/null +++ b/crates/zk_evm/src/testing/tests/precompiles/ecrecover.rs @@ -0,0 +1,144 @@ +use super::*; + +fn fill_memory(hash: [u8; 32], r: [u8; 32], s: [u8; 32], v: bool, page: u32, memory: &mut M) -> u16 { + let mut location = MemoryLocation {page: MemoryPage(page), index: MemoryIndex(0)}; + let query = MemoryQuery { + timestamp: Timestamp(0u32), + location, + value: U256::from_big_endian(&hash), + rw_flag: true + }; + let _ = memory.execute_partial_query(query); + + location.index.0 += 1; + let query = MemoryQuery { + timestamp: Timestamp(0u32), + location, + value: U256::from_big_endian(&r), + rw_flag: true + }; + let _ = memory.execute_partial_query(query); + + location.index.0 += 1; + let query = MemoryQuery { + timestamp: Timestamp(0u32), + location, + value: U256::from_big_endian(&s), + rw_flag: true + }; + let _ = memory.execute_partial_query(query); + + location.index.0 += 1; + let mut buffer = [0u8; 32]; + if v { + buffer[31] = 1; + } + let query = MemoryQuery { + timestamp: Timestamp(0u32), + location, + value: U256::from_big_endian(&buffer), + rw_flag: true + }; + let _ = memory.execute_partial_query(query); + + + 4 as u16 +} + +fn ecrecover_test_inner(hash: [u8; 32], r: [u8; 32], s: [u8; 32], v: bool, expect_ok: bool, expected_address: [u8; 20]) -> (Vec<[u8; 32]>, std::ops::Range) { + let mut memory = SimpleMemory::new(); + let mut precompiles_processor = DefaultPrecompilesProcessor::; + + // fill the memory + let num_words_used = fill_memory(hash, r, s, v, 0u32, &mut memory); + + let precompile_call_params = PrecompileCallParams { + input_location: MemoryLocation {page: MemoryPage(0u32), index: MemoryIndex(0u16)}, + output_location: MemoryLocation {page: MemoryPage(0u32), index: MemoryIndex(num_words_used)}, + timestamp_for_input_read: Timestamp(1u32), + timestamp_for_output_write: Timestamp(2u32), + }; + + let address = Address::from_low_u64_be(ECRECOVER_INNER_FUNCTION_PRECOMPILE_ADDRESS as u64); + + let precompile_query = LogQuery { + timestamp: precompile_call_params.timestamp_for_input_read, + tx_number_in_block: 0, + shard_id: 0, + aux_byte: PRECOMPILE_AUX_BYTE, + address, + key: U256::zero(), + read_value: precompile_call_params.encode_into_log_value(), + written_value: U256::zero(), + rw_flag: false, + rollback: false, + is_service: false, + }; + + let _ = precompiles_processor.execute_precompile(precompile_query, &mut memory); + + let range = 0u16..(num_words_used + 2); + let content = memory.dump_page_content(0u32, range.clone()); + let content_len = content.len(); + let expected_output = content[content_len-1]; + let ok_or_error_marker = content[content_len-2]; + + if expect_ok { + let mut buffer = [0u8; 32]; + U256::one().to_big_endian(&mut buffer); + assert!(ok_or_error_marker == buffer); + assert_eq!(&expected_output[12..], &expected_address); + } else { + let mut buffer = [0u8; 32]; + U256::zero().to_big_endian(&mut buffer); + assert!(ok_or_error_marker == buffer); + assert_eq!(&expected_output[..], &[0u8; 32]); + } + + (content, range) +} + +fn ecrecover_test_inner_from_raw(raw_input: &str, raw_address: &str, expect_ok: bool) -> (Vec<[u8; 32]>, std::ops::Range) { + let input_bytes = hex::decode(raw_input).unwrap(); + let hash: [u8; 32] = input_bytes[0..32].try_into().unwrap(); + let v_padded: [u8; 32] = input_bytes[32..64].try_into().unwrap(); + let r: [u8; 32] = input_bytes[64..96].try_into().unwrap(); + let s: [u8; 32] = input_bytes[96..128].try_into().unwrap(); + + let address = hex::decode(raw_address).unwrap(); + let offset = address.len() - 20; + let expected_address: [u8; 20] = address[offset..].try_into().unwrap(); + + let v = if v_padded[31] == 1 { + true + } else if v_padded[31] == 0 { + false + } else if v_padded[31] == 28 { + true + } else if v_padded[31] == 27 { + false + } else { + panic!("v = {}", v_padded[31]); + }; + + ecrecover_test_inner(hash, r, s, v, expect_ok, expected_address) +} + +#[test] +fn test_valid() { + let raw_input = "38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e000000000000000000000000000000000000000000000000000000000000001b38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e789d1dd423d25f0772d2748d60f7e4b81bb14d086eba8e8e8efb6dcff8a4ae02"; + let raw_address = "000000000000000000000000ceaccac640adf55b2028469bd36ba501f28b699d"; + let (content, range) = ecrecover_test_inner_from_raw(raw_input, raw_address, true); + pretty_print_memory_dump(&content, range); +} + +#[test] +fn test_valid_large_s() { + let raw_input = "38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e000000000000000000000000000000000000000000000000000000000000001b38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0"; + let raw_address = hex::encode(&vec![ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 198, 174, 93, 17, 93, 119, 163, 216, 169, 239, + 54, 214, 164, 45, 35, 105, 43, 170, 127, + ]); + let (content, range) = ecrecover_test_inner_from_raw(raw_input, &raw_address, true); + pretty_print_memory_dump(&content, range); +} \ No newline at end of file diff --git a/crates/zk_evm/src/testing/tests/precompiles/keccak256.rs b/crates/zk_evm/src/testing/tests/precompiles/keccak256.rs new file mode 100644 index 0000000..ee1e743 --- /dev/null +++ b/crates/zk_evm/src/testing/tests/precompiles/keccak256.rs @@ -0,0 +1,138 @@ +use super::*; + +use crate::precompiles::keccak256::*; + +fn pad_and_fill_memory(input: &[u8], page: u32, memory: &mut M) -> u16 { + let mut padded = vec![]; + padded.extend_from_slice(input); + + let block_size = KECCAK_RATE_IN_U64_WORDS * 8; + let last_block_size = padded.len() % block_size; + let padlen = block_size - last_block_size; + if padlen == 1 { + padded.push(0x81); + } else { + padded.push(0x01); + padded.extend(std::iter::repeat(0u8).take(padlen - 2)); + padded.push(0x80); + } + + assert_eq!(padded.len() % block_size, 0); + + let num_rounds = padded.len() / block_size; + + let mut num_rounds_u256 = U256::zero(); + num_rounds_u256.0[0] = num_rounds as u64; + println!("Num rounds = {}", num_rounds_u256); + let mut location = MemoryLocation {page: MemoryPage(page), index: MemoryIndex(0)}; + let num_rounds_query = MemoryQuery { + timestamp: Timestamp(0u32), + location, + value: num_rounds_u256, + rw_flag: true + }; + + let _ = memory.execute_partial_query(num_rounds_query); + + let total_len_as_u64_words = padded.len() / 8; + let mut num_words = total_len_as_u64_words / 4; + if total_len_as_u64_words % 4 != 0 { + num_words += 1; + } + + let mut chunk_iter = padded.chunks_exact(8); + + for _word in 0..num_words { + location.index.0 += 1; + let mut value = U256::zero(); + for i in (0..4).rev() { + if let Some(chunk) = chunk_iter.next() { + let as_u64 = u64::from_be_bytes(chunk.try_into().unwrap()); + value.0[i] = as_u64; + } + } + + let data_query = MemoryQuery { + timestamp: Timestamp(0u32), + location, + value, + rw_flag: true + }; + + let _ = memory.execute_partial_query(data_query); + } + + assert!(chunk_iter.remainder().len() == 0); + + (1 + num_words) as u16 +} + +use sha3::Digest; +use sha3::Keccak256; + +fn run_keccak256_test_inner(input: &[u8]) -> (Vec<[u8; 32]>, std::ops::Range) { + let mut memory = SimpleMemory::new(); + let mut precompiles_processor = DefaultPrecompilesProcessor::; + + let mut hasher = Keccak256::default(); + hasher.update(input); + let result = hasher.finalize(); + let bytes: &[u8] = result.as_ref(); + println!("{}", hex::encode(bytes)); + + // fill the memory + let num_words_used = pad_and_fill_memory(input, 0u32, &mut memory); + + let precompile_call_params = PrecompileCallParams { + input_location: MemoryLocation {page: MemoryPage(0u32), index: MemoryIndex(0u16)}, + output_location: MemoryLocation {page: MemoryPage(0u32), index: MemoryIndex(num_words_used)}, + timestamp_for_input_read: Timestamp(1u32), + timestamp_for_output_write: Timestamp(2u32), + }; + + let address = Address::from_low_u64_be(KECCAK256_ROUND_FUNCTION_PRECOMPILE_ADDRESS as u64); + + let precompile_query = LogQuery { + timestamp: precompile_call_params.timestamp_for_input_read, + tx_number_in_block: 0, + shard_id: 0, + aux_byte: PRECOMPILE_AUX_BYTE, + address, + key: U256::zero(), + read_value: precompile_call_params.encode_into_log_value(), + written_value: U256::zero(), + rw_flag: false, + rollback: false, + is_service: false, + }; + + let _ = precompiles_processor.execute_precompile(precompile_query, &mut memory); + + let range = 0u16..(num_words_used + 1); + let content = memory.dump_page_content(0u32, range.clone()); + let expected_output = content.last().copied().unwrap(); + + assert_eq!(&expected_output[..], bytes); + + (content, range) +} + +#[test] +fn test_empty_keccak256() { + let (content, range) = run_keccak256_test_inner(&[]); + pretty_print_memory_dump(&content, range); +} + +#[test] +fn test_few_rounds_of_keccak256() { + let data = vec![255u8; 256]; + let (content, range) = run_keccak256_test_inner(&data); + pretty_print_memory_dump(&content, range); +} + +#[test] +fn test_very_long_keccak256() { + let data = vec![255u8; 10_000]; + let (content, range) = run_keccak256_test_inner(&data); + pretty_print_memory_dump(&content, range); +} \ No newline at end of file diff --git a/crates/zk_evm/src/testing/tests/precompiles/mod.rs b/crates/zk_evm/src/testing/tests/precompiles/mod.rs new file mode 100644 index 0000000..21ad581 --- /dev/null +++ b/crates/zk_evm/src/testing/tests/precompiles/mod.rs @@ -0,0 +1,14 @@ +use super::*; + +mod keccak256; +mod sha256; +mod ecrecover; + +fn pretty_print_memory_dump(content: &Vec<[u8; 32]>, range: std::ops::Range) { + println!("Memory dump:"); + println!("-----------------------------------------"); + for (cont, index) in content.into_iter().zip(range.into_iter()) { + println!("{:04x}: 0x{}", index, hex::encode(cont)); + } + println!("-----------------------------------------"); +} \ No newline at end of file diff --git a/crates/zk_evm/src/testing/tests/precompiles/sha256.rs b/crates/zk_evm/src/testing/tests/precompiles/sha256.rs new file mode 100644 index 0000000..9d28527 --- /dev/null +++ b/crates/zk_evm/src/testing/tests/precompiles/sha256.rs @@ -0,0 +1,136 @@ +use super::*; + +use crate::precompiles::sha256::*; + +fn pad_and_fill_memory(input: &[u8], page: u32, memory: &mut M) -> u16 { + let mut padded = vec![]; + padded.extend_from_slice(input); + + let block_size = 64; + + let message_bitlen = (padded.len() * 8) as u64; + let last_block_size = padded.len() % block_size; + + let (num_of_zero_bytes, _pad_overflowed) = if last_block_size <= (64 - 1 - 8) { + (64 - 1 - 8 - last_block_size, false) + } + else { + (128 - 1 - 8 - last_block_size, true) + }; + + padded.push(1u8 << 7); + padded.extend(std::iter::repeat(0u8).take(num_of_zero_bytes)); + + // represent L as big integer number: + let repr = message_bitlen.to_be_bytes(); + padded.extend(repr.into_iter()); + assert_eq!(padded.len() % block_size, 0); + + // number of words to put the data + let num_words = padded.len() / 32; + + // number of rounds of invocation + let num_rounds = padded.len() / block_size; + + let mut num_rounds_u256 = U256::zero(); + num_rounds_u256.0[0] = num_rounds as u64; + println!("Num rounds = {}", num_rounds_u256); + let mut location = MemoryLocation {page: MemoryPage(page), index: MemoryIndex(0)}; + let num_rounds_query = MemoryQuery { + timestamp: Timestamp(0u32), + location, + value: num_rounds_u256, + rw_flag: true + }; + + let _ = memory.execute_partial_query(num_rounds_query); + + let mut chunk_iter = padded.chunks_exact(32); + assert_eq!(chunk_iter.len(), num_words); + + for word_bytes in &mut chunk_iter { + location.index.0 += 1; + let value = U256::from_big_endian(word_bytes); + let data_query = MemoryQuery { + timestamp: Timestamp(0u32), + location, + value, + rw_flag: true + }; + + let _ = memory.execute_partial_query(data_query); + } + + assert!(chunk_iter.remainder().len() == 0); + + (1 + num_words) as u16 +} + +use sha2::*; + +fn run_sha256_test_inner(input: &[u8]) -> (Vec<[u8; 32]>, std::ops::Range) { + let mut memory = SimpleMemory::new(); + let mut precompiles_processor = DefaultPrecompilesProcessor::; + + let mut hasher = Sha256::default(); + hasher.update(input); + let result = hasher.finalize(); + let bytes: &[u8] = result.as_ref(); + println!("{}", hex::encode(bytes)); + + // fill the memory + let num_words_used = pad_and_fill_memory(input, 0u32, &mut memory); + + let precompile_call_params = PrecompileCallParams { + input_location: MemoryLocation {page: MemoryPage(0u32), index: MemoryIndex(0u16)}, + output_location: MemoryLocation {page: MemoryPage(0u32), index: MemoryIndex(num_words_used)}, + timestamp_for_input_read: Timestamp(1u32), + timestamp_for_output_write: Timestamp(2u32), + }; + + let address = Address::from_low_u64_be(SHA256_ROUND_FUNCTION_PRECOMPILE_ADDRESS as u64); + + let precompile_query = LogQuery { + timestamp: precompile_call_params.timestamp_for_input_read, + tx_number_in_block: 0, + shard_id: 0, + aux_byte: PRECOMPILE_AUX_BYTE, + address, + key: U256::zero(), + read_value: precompile_call_params.encode_into_log_value(), + written_value: U256::zero(), + rw_flag: false, + rollback: false, + is_service: false, + }; + + let _ = precompiles_processor.execute_precompile(precompile_query, &mut memory); + + let range = 0u16..(num_words_used + 1); + let content = memory.dump_page_content(0u32, range.clone()); + let expected_output = content.last().copied().unwrap(); + + assert_eq!(&expected_output[..], bytes); + + (content, range) +} + +#[test] +fn test_empty_sha256() { + let (content, range) = run_sha256_test_inner(&[]); + pretty_print_memory_dump(&content, range); +} + +#[test] +fn test_few_rounds_of_sha256() { + let data = vec![255u8; 256]; + let (content, range) = run_sha256_test_inner(&data); + pretty_print_memory_dump(&content, range); +} + +#[test] +fn test_very_long_sha256() { + let data = vec![255u8; 10_000]; + let (content, range) = run_sha256_test_inner(&data); + pretty_print_memory_dump(&content, range); +} \ No newline at end of file diff --git a/crates/zk_evm/src/testing/tests/trivial.rs b/crates/zk_evm/src/testing/tests/trivial.rs new file mode 100644 index 0000000..ac0f3ed --- /dev/null +++ b/crates/zk_evm/src/testing/tests/trivial.rs @@ -0,0 +1,75 @@ +use super::*; + +use super::simple_tracer::*; + +#[test] +fn run_dummy_log_and_unmapped_noop() { + let mut tools = create_default_testing_tools(); + let block_properties = create_default_block_info(); + let mut vm = create_initial_vm_state_for_basic_testing(&mut tools, &block_properties); + + let tracing_closure = |state: &VmState<_, _, _, _, _, _>, aux: AuxTracingInformation, cycle_idx: u32| { + println!("------------------------------------------------------------"); + println!("After the cycle {}", cycle_idx); + println!("Did skip cycle: {}", aux.skip_cycle); + println!("Executed opcode: {}", aux.final_masked_opcode); + println!("Registers:"); + for (i, r) in state.registers.iter().enumerate() { + println!("r{} = {:x}", i, r); + } + println!("Flags = {:?}", state.flags); + println!("Resolved jump condition = {}", aux.resolved_jump_condition); + println!("Exceptions: {:?}", aux.error_flags_collection); + if state.execution_has_ended() { + println!("Execution has ended"); + } else { + println!("Execution continues"); + } + println!("Final context value: {:?}", state.callstack.get_current_stack()); + println!("Pending state: {:?}", state.pending_port); + println!("Pending cycles left: {:?}", state.pending_cycles_left); + }; + + let mut debug_tracer = ClosureBasedTracer::new(tracing_closure); + + vm.memory.populate(vec![ + (BOOTLOADER_CODE_PAGE, vec![U256::from_str_radix("10", 10).unwrap()]) + ]); + + vm.cycle(&mut debug_tracer); + vm.cycle(&mut debug_tracer); + vm.cycle(&mut debug_tracer); + vm.cycle(&mut debug_tracer); + + let (full_storage_access_history, storage_pre_shard, events_log_history, events, l1_messages, _) = get_final_net_states!(vm, tools); + + println!("------------------------------------------------------"); + println!("Storage log access history:"); + println!("{:?}", full_storage_access_history); + println!("Event log access history:"); + println!("{:?}", events_log_history); + + println!("------------------------------------------------------"); + println!("Net events:"); + println!("{:?}", events); + println!("Net L1 messages:"); + println!("{:?}", l1_messages); +} + +#[test] +fn check_nop_moves_sp() { + let mut tools = create_default_testing_tools(); + let block_properties = create_default_block_info(); + let mut vm = create_initial_vm_state_for_basic_testing(&mut tools, &block_properties); + + let default_tracing_tool = DefaultTracingClosure::new(); + let mut debug_tracer = ClosureBasedTracer::new(|a, b, c| default_tracing_tool.trace(a, b, c)); + + // manually encode LE + let opcode = "000100005000002000"; + vm.memory.populate(vec![ + (BOOTLOADER_CODE_PAGE, vec![U256::from_little_endian(&hex::decode(opcode).unwrap())]) + ]); + + vm.cycle(&mut debug_tracer); +} diff --git a/crates/zk_evm/src/utils.rs b/crates/zk_evm/src/utils.rs new file mode 100644 index 0000000..7c054de --- /dev/null +++ b/crates/zk_evm/src/utils.rs @@ -0,0 +1,93 @@ +use crate::U256; +use zkevm_opcode_defs::decoding::VmEncodingMode; +pub use zkevm_opcode_defs::utils::*; + +use lazy_static::lazy_static; + +lazy_static! { + pub static ref U256_TO_ADDRESS_MASK: U256 = U256::MAX >> (256 - 160); +} + +pub fn contract_bytecode_to_words(code: &[[u8; 32]]) -> Vec { + code.into_iter() + .map(|el| U256::from_big_endian(el)) + .collect() + + // for code each 8 byte sequence is somehow encoded integer, + // or full 32 byte word is an integer constant (also encoded with some endianess) + + // let mut result = Vec::with_capacity(code.len()); + // let mut el = U256::zero(); + // for code_word in code.into_iter() { + // // each 8 byte sequence is an independent LE encoded u64, + // // but machine itself is BE regarding memory queries + // el.0[0] = u64::from_le_bytes(code_word[0..8].try_into().unwrap()); + // el.0[1] = u64::from_le_bytes(code_word[8..16].try_into().unwrap()); + // el.0[2] = u64::from_le_bytes(code_word[16..24].try_into().unwrap()); + // el.0[3] = u64::from_le_bytes(code_word[24..32].try_into().unwrap()); + + // result.push(el); + // } + + // result +} + +pub fn address_to_u256(address: &crate::Address) -> U256 { + let mut buffer = [0u8; 32]; + buffer[12..].copy_from_slice(&address.as_fixed_bytes()[..]); + + U256::from_big_endian(&buffer) +} + +pub fn u256_to_address_unchecked(integer: &U256) -> crate::Address { + let mut buffer = [0u8; 32]; + integer.to_big_endian(&mut buffer); + + crate::Address::from_slice(&buffer[12..32]) +} + +use crate::abstractions::*; + +#[derive(Debug, Clone, Copy)] +pub struct GenericNoopTracer { + _marker: std::marker::PhantomData, +} + +impl GenericNoopTracer { + pub fn new() -> Self { + Self { + _marker: std::marker::PhantomData, + } + } +} + +impl> Tracer for GenericNoopTracer { + type SupportedMemory = M; + fn before_decoding( + &mut self, + _state: VmLocalStateData<'_, N, E>, + _memory: &Self::SupportedMemory, + ) { + } + fn after_decoding( + &mut self, + _state: VmLocalStateData<'_, N, E>, + _data: AfterDecodingData, + _memory: &Self::SupportedMemory, + ) { + } + fn before_execution( + &mut self, + _state: VmLocalStateData<'_, N, E>, + _data: BeforeExecutionData, + _memory: &Self::SupportedMemory, + ) { + } + fn after_execution( + &mut self, + _state: VmLocalStateData<'_, N, E>, + _data: AfterExecutionData, + _memory: &Self::SupportedMemory, + ) { + } +} diff --git a/crates/zk_evm/src/vm_state/aux_data.rs b/crates/zk_evm/src/vm_state/aux_data.rs new file mode 100644 index 0000000..edbefd1 --- /dev/null +++ b/crates/zk_evm/src/vm_state/aux_data.rs @@ -0,0 +1,7 @@ +use super::*; + +#[derive(Debug, Clone)] +pub struct AuxDataHolder> { + pub empty_hash_port: AlgebraicHashPort, + pub hash_and_ports_round_function: R, +} \ No newline at end of file diff --git a/crates/zk_evm/src/vm_state/cycle.rs b/crates/zk_evm/src/vm_state/cycle.rs new file mode 100644 index 0000000..ae122b4 --- /dev/null +++ b/crates/zk_evm/src/vm_state/cycle.rs @@ -0,0 +1,429 @@ +use super::*; +use crate::abstractions::*; +use crate::aux_structures::MemoryIndex; +use crate::aux_structures::{MemoryKey, MemoryLocation}; +use crate::opcodes::parsing::*; +use zkevm_opcode_defs::{ImmMemHandlerFlags, NopOpcode, Operand, RegOrImmFlags}; + +pub struct PreState = EncodingModeProduction> { + pub src0: PrimitiveValue, + pub src1: PrimitiveValue, + pub dst0_mem_location: Option, + pub new_pc: E::PcOrImm, + pub is_kernel_mode: bool, +} + +pub const OPCODES_PER_WORD_LOG_2: usize = 2; +pub const OPCODES_PER_WORD: usize = 1 << OPCODES_PER_WORD_LOG_2; +pub const READ_OPCODE_SPONGE_IDX: usize = 0; +pub const READ_SRC_FROM_MEMORY_SPONGE_IDX: usize = 1; +pub const READ_DST_FROM_MEMORY_SPONGE_IDX: usize = 2; + +pub fn read_and_decode< + const N: usize, + E: VmEncodingMode, + M: crate::abstractions::Memory, + WT: crate::witness_trace::VmWitnessTracer, + DT: crate::abstractions::tracing::Tracer, +>( + local_state: &VmLocalState, + memory: &M, + witness_tracer: &mut WT, + tracer: &mut DT, +) -> (DecodedOpcode, DelayedLocalStateChanges, bool) { + let mut delayed_changes = DelayedLocalStateChanges::default(); + + // witness tracing + witness_tracer.start_new_execution_cycle(local_state); + + // global generic tracing + if DT::CALL_BEFORE_DECODING { + let local_state = VmLocalStateData { + vm_local_state: &local_state, + }; + + tracer.before_decoding(local_state, memory); + } + + let skip_cycle = local_state.pending_port.is_any_pending() || local_state.execution_has_ended(); + delayed_changes.reset_pending_port = local_state.pending_port.is_any_pending(); + + let pending_exception = local_state.pending_exception; + + // if we do not skip cycle then we read memory for a new opcode + let opcode_encoding = if !skip_cycle && !pending_exception { + let pc = local_state.callstack.get_current_stack().pc; + let previous_super_pc = local_state.previous_super_pc; + let did_call_or_ret_recently = local_state.did_call_or_ret_recently; + let (super_pc, sub_pc) = E::split_pc(pc); + let raw_opcode_u64 = match (did_call_or_ret_recently, previous_super_pc == super_pc) { + (true, _) | (false, false) => { + // we need to read the code word and select a proper subword + let code_page = local_state.callstack.get_current_stack().code_page; + let location = MemoryLocation { + memory_type: MemoryType::Code, + page: code_page, + index: MemoryIndex(super_pc.as_u64() as u32), + }; + let key = MemoryKey { + timestamp: local_state.timestamp_for_code_or_src_read(), + location, + }; + delayed_changes.reset_did_call_or_ret_recently = true; + + // code read is never pending + let code_query = read_code( + memory, + witness_tracer, + local_state.monotonic_cycle_counter, + key, + /* is_pended */ false, + ); + witness_tracer.add_sponge_marker( + local_state.monotonic_cycle_counter, + SpongeExecutionMarker::MemoryQuery, + 0..1, + /* is_pended */ false, + ); + let u256_word = code_query.value; + delayed_changes.new_previous_code_word = Some(u256_word); + delayed_changes.new_previous_super_pc = Some(super_pc); + + // our memory is a set of words in storage, and those are only re-interpreted + // as bytes in UMA. But natural storage for code is still bytes. + + // to ensure consistency with the future if we allow deployment of raw bytecode + // then for our BE machine we should consider that "first" bytes, that will be + // our integer's "highest" bytes, so to follow bytearray-like enumeration we + // have to use inverse order here + let u256_word = u256_word; + E::integer_representaiton_from_u256(u256_word, sub_pc) + } + (false, true) => { + // use a saved one + let u256_word = local_state.previous_code_word; + E::integer_representaiton_from_u256(u256_word, sub_pc) + } + }; + + raw_opcode_u64 + } else if !skip_cycle && pending_exception { + // there are no cases that set pending exception and + // simultaneously finish the execution + assert!(local_state.execution_has_ended() == false); + + // note that we do reset PC in VM for simplicity, so we do it here too + let pc = local_state.callstack.get_current_stack().pc; + let (super_pc, _) = E::split_pc(pc); + delayed_changes.new_previous_super_pc = Some(super_pc); + + // so we can just remove the marker as soon as we are no longer pending + delayed_changes.new_pending_exception = Some(false); + + E::exception_revert_encoding() + } else { + // we are skipping cycle for some reason, so we do nothing, + // and do not touch any flags + + if local_state.execution_has_ended() { + assert!(pending_exception == false); + delayed_changes.reset_did_call_or_ret_recently = true; + } + + E::nop_encoding() + }; + + // now we have some candidate for opcode. If it's noop we are not expecting to have any problems, + // so check for other meaningful exceptions + + let mut error_flags = ErrorFlags::empty(); + let (partially_decoded_inner, opcode_raw_variant_idx) = + E::parse_preliminary_variant_and_absolute_number(opcode_encoding); + + let mut partially_decoded = DecodedOpcode { + inner: partially_decoded_inner, + }; + + if partially_decoded.variant.is_explicit_panic() { + error_flags.set(ErrorFlags::INVALID_OPCODE, true); + } + + // now try to get ergs price (unmodified for hard cases), that will also allow us to catch invalid opcode + let mut ergs_cost = + zkevm_opcode_defs::OPCODES_PRICES[opcode_raw_variant_idx.into_usize()] as u32; + if skip_cycle { + // we have already paid for it + ergs_cost = 0; + } + + let (mut ergs_remaining, not_enough_power) = local_state + .callstack + .get_current_stack() + .ergs_remaining + .overflowing_sub(ergs_cost); + if not_enough_power { + ergs_remaining = 0; + error_flags.set(ErrorFlags::NOT_ENOUGH_ERGS, true); + } + + delayed_changes.new_ergs_remaining = Some(ergs_remaining); + + // we have only 3 exceptions that we check before execution + // - opcode requires kernel mode, but we are not in one + // - opcode requires non-static context, but we are in one + // - callstack is full because we have just called some other context + + let is_kernel = local_state.callstack.get_current_stack().is_kernel_mode(); + let is_static_execution = local_state.callstack.get_current_stack().is_static; + let callstack_is_full = local_state.callstack_is_full(); + + if partially_decoded.variant.requires_kernel_mode() && !is_kernel { + error_flags.set(ErrorFlags::PRIVILAGED_ACCESS_NOT_FROM_KERNEL, true); + } + + if !partially_decoded.variant.can_be_used_in_static_context() && is_static_execution { + error_flags.set(ErrorFlags::WRITE_IN_STATIC_CONTEXT, true); + } + + if callstack_is_full { + error_flags.set(ErrorFlags::CALLSTACK_IS_FULL, true); + } + + // now we have enough information to decide whether to mask the opcode into "panic" or not + let mask_into_panic_due_to_exception = error_flags.is_empty() == false; + if mask_into_panic_due_to_exception { + partially_decoded.mask_into_panic(); + }; + + // resolve condition once + let resolved_condition = { + use zkevm_opcode_defs::Condition; + match partially_decoded.condition { + Condition::Always => true, + Condition::Gt => local_state.flags.greater_than_flag, + Condition::Lt => local_state.flags.overflow_or_less_than_flag, + Condition::Eq => local_state.flags.equality_flag, + Condition::Ge => local_state.flags.greater_than_flag | local_state.flags.equality_flag, + Condition::Le => { + local_state.flags.overflow_or_less_than_flag | local_state.flags.equality_flag + } + Condition::Ne => local_state.flags.equality_flag == false, + Condition::GtOrLt => { + local_state.flags.greater_than_flag | local_state.flags.overflow_or_less_than_flag + } + } + }; + + // mask into NOP if condition doesn't match. Note that encoding for PANIC has "always" condition + if resolved_condition == false { + // we self-protect against double-masking + if mask_into_panic_due_to_exception == false { + partially_decoded.mask_into_nop(); + } + } + + if DT::CALL_AFTER_DECODING { + let local_state = VmLocalStateData { + vm_local_state: local_state, + }; + + let data = AfterDecodingData { + raw_opcode_unmasked: opcode_encoding, + opcode_masked: partially_decoded, + error_flags_accumulated: error_flags, + resolved_condition, + did_skip_cycle: skip_cycle, + }; + + tracer.after_decoding(local_state, data, memory); + } + + (partially_decoded, delayed_changes, skip_cycle) +} + +impl< + 'a, + S: crate::abstractions::Storage, + M: crate::abstractions::Memory, + EV: crate::abstractions::EventSink, + PP: crate::abstractions::PrecompilesProcessor, + DP: crate::abstractions::DecommittmentProcessor, + WT: crate::witness_trace::VmWitnessTracer, + const N: usize, + E: VmEncodingMode, + > VmState +{ + #[inline] + pub fn super_and_sub_pc_from_pc(pc: u16) -> (u16, u8) { + ( + (pc >> OPCODES_PER_WORD_LOG_2), + (pc & (OPCODES_PER_WORD as u16 - 1)) as u8, + ) + } + + pub fn cycle>( + &mut self, + tracer: &mut DT, + ) { + let (after_masking_decoded, delayed_changes, skip_cycle) = read_and_decode( + &self.local_state, + &mut self.memory, + &mut self.witness_tracer, + tracer, + ); + delayed_changes.apply(&mut self.local_state); + + // now we are exception-less! + + // Now we can try to access the memory, but should keep in mind that if we did encounter an error here + // then in addition to (later on) masking the opcode to be panicing Ret we also have to avoid + // memory reads here and later on also avoid writes (this will happen automatically inside of opcode processing itself) + + let mut mem_processor = MemOpsProcessor:: { + sp: self.local_state.callstack.get_current_stack().sp, + }; + let (src0_reg_value, mut src0_mem_location) = mem_processor + .compute_addresses_and_select_operands( + self, + after_masking_decoded.src0_reg_idx, + after_masking_decoded.imm_0, + after_masking_decoded.variant.src0_operand_type, + false, + ); + + let (_, dst0_mem_location) = mem_processor.compute_addresses_and_select_operands( + self, + after_masking_decoded.dst0_reg_idx, + after_masking_decoded.imm_1, + after_masking_decoded.variant.dst0_operand_type, + true, + ); + + // here we can either execute NOP r0, r0, r0, r0 after masking, or RET (that doesn't manipulate SP), + // so we can still set ergs and SP and be happy + self.local_state.callstack.get_current_stack_mut().sp = mem_processor.sp; + if after_masking_decoded.variant.opcode == zkevm_opcode_defs::Opcode::Nop(NopOpcode) { + // special rule for NOP - we do NOT read + src0_mem_location = None; + } + + // so we do read here + let src0_mem_value = if let Some(src0_mem_location) = src0_mem_location { + let key = MemoryKey { + timestamp: self.timestamp_for_code_or_src_read(), + location: src0_mem_location, + }; + // src read is never pending, but to keep consistent memory implementation we + // need to branch here for a case of loading constants from code space + let src0_query = if src0_mem_location.memory_type == MemoryType::Code { + self.read_code( + self.local_state.monotonic_cycle_counter, + key, + /* is_pended */ false, + ) + } else { + self.read_memory( + self.local_state.monotonic_cycle_counter, + key, + /* is_pended */ false, + ) + }; + self.witness_tracer.add_sponge_marker( + self.local_state.monotonic_cycle_counter, + SpongeExecutionMarker::MemoryQuery, + 1..2, + /* is_pended */ false, + ); + let u256_word = src0_query.value; + let is_pointer = src0_query.value_is_pointer; + + PrimitiveValue { + value: u256_word, + is_pointer, + } + } else { + PrimitiveValue::empty() + }; + + let src0 = match after_masking_decoded.variant.src0_operand_type { + Operand::RegOnly + | Operand::Full(ImmMemHandlerFlags::UseRegOnly) + | Operand::RegOrImm(RegOrImmFlags::UseRegOnly) => src0_reg_value, + Operand::Full(ImmMemHandlerFlags::UseImm16Only) + | Operand::RegOrImm(RegOrImmFlags::UseImm16Only) => PrimitiveValue { + value: U256::from(after_masking_decoded.imm_0.as_u64()), + is_pointer: false, + }, + _ => src0_mem_value, + }; + + let src1 = self.select_register_value(after_masking_decoded.src1_reg_idx); + + let (src0, src1) = if after_masking_decoded.variant.swap_operands() { + (src1, src0) + } else { + (src0, src1) + }; + + let mut new_pc = self.local_state.callstack.get_current_stack().pc; + if !skip_cycle { + new_pc = new_pc.wrapping_add(E::PcOrImm::from_u64_clipped(1u64)); + } + + if DT::CALL_BEFORE_EXECUTION { + let local_state = VmLocalStateData { + vm_local_state: &self.local_state, + }; + + let data = BeforeExecutionData { + opcode: after_masking_decoded, + src0_value: src0, + src1_value: src1, + src0_mem_location, + new_pc, + }; + + tracer.before_execution(local_state, data, &mut self.memory); + } + + let is_kernel_mode = self + .local_state + .callstack + .get_current_stack() + .is_kernel_mode(); + + let prestate = PreState { + src0, + src1, + dst0_mem_location, + new_pc, + is_kernel_mode, + }; + + after_masking_decoded.apply(self, prestate); + + if self.local_state.pending_port.is_any_pending() { + debug_assert!(self.local_state.pending_cycles_left.is_none()); + } + + if !skip_cycle { + self.increment_timestamp_after_cycle(); + } + self.local_state.monotonic_cycle_counter += 1; + + self.witness_tracer.end_execution_cycle(&self.local_state); + + if DT::CALL_AFTER_EXECUTION { + let local_state = VmLocalStateData { + vm_local_state: &self.local_state, + }; + + let data = AfterExecutionData { + opcode: after_masking_decoded, + dst0_mem_location, + }; + + tracer.after_execution(local_state, data, &mut self.memory); + } + } +} diff --git a/crates/zk_evm/src/vm_state/execution_stack.rs b/crates/zk_evm/src/vm_state/execution_stack.rs new file mode 100644 index 0000000..0ff55f4 --- /dev/null +++ b/crates/zk_evm/src/vm_state/execution_stack.rs @@ -0,0 +1,141 @@ +use super::*; +use crate::aux_structures::*; + +use zkevm_opcode_defs::{INITIAL_SP_ON_FAR_CALL, UNMAPPED_PAGE}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +pub struct CallStackEntry = EncodingModeProduction> { + pub this_address: Address, + pub msg_sender: Address, + pub code_address: Address, + pub base_memory_page: MemoryPage, + pub code_page: MemoryPage, + pub sp: E::PcOrImm, + pub pc: E::PcOrImm, + pub exception_handler_location: E::PcOrImm, + pub ergs_remaining: u32, + pub this_shard_id: u8, + pub caller_shard_id: u8, + pub code_shard_id: u8, + pub is_static: bool, + pub is_local_frame: bool, + pub context_u128_value: u128, + pub heap_bound: u32, + pub aux_heap_bound: u32, +} + +#[derive(Debug, Clone, PartialEq)] +pub struct Callstack = EncodingModeProduction> { + pub current: CallStackEntry, + pub inner: Vec>, +} + +impl> CallStackEntry { + // this is a context before bootloader actually starts. Necessary + // to continue no-oping + pub fn empty_context() -> Self { + Self { + this_address: Address::zero(), + msg_sender: Address::zero(), + code_address: Address::zero(), + base_memory_page: MemoryPage(UNMAPPED_PAGE), + code_page: MemoryPage(UNMAPPED_PAGE), + sp: E::PcOrImm::from_u64_clipped(INITIAL_SP_ON_FAR_CALL), + pc: E::PcOrImm::from_u64_clipped(0u64), + exception_handler_location: E::PcOrImm::from_u64_clipped(0u64), + ergs_remaining: zkevm_opcode_defs::system_params::VM_INITIAL_FRAME_ERGS, + this_shard_id: 0u8, + caller_shard_id: 0u8, + code_shard_id: 0u8, + is_static: false, + is_local_frame: false, + context_u128_value: 0u128, + heap_bound: 0u32, + aux_heap_bound: 0u32, + } + } + pub fn is_kernel_mode(&self) -> bool { + Self::address_is_kernel(&self.this_address) + } + + pub const fn get_address_low(&self) -> u16 { + let address_bytes = self.this_address.as_fixed_bytes(); + let address_u16 = u16::from_le_bytes([address_bytes[19], address_bytes[18]]); + + address_u16 + } + + pub const fn code_page_candidate_from_base(base: MemoryPage) -> MemoryPage { + MemoryPage(base.0) + } + + pub const fn stack_page_from_base(base: MemoryPage) -> MemoryPage { + MemoryPage(base.0 + 1) + } + + pub const fn heap_page_from_base(base: MemoryPage) -> MemoryPage { + MemoryPage(base.0 + 2) + } + + pub const fn aux_heap_page_from_base(base: MemoryPage) -> MemoryPage { + MemoryPage(base.0 + 3) + } + + pub fn address_is_kernel(address: &Address) -> bool { + // address < 2^16 + let address_bytes = address.as_fixed_bytes(); + address_bytes[0..18].iter().all(|&el| el == 0u8) + } +} + +impl> Callstack { + pub fn empty() -> Self { + let new = Self { + current: CallStackEntry::empty_context(), + inner: Vec::with_capacity(1 << 12), + }; + debug_assert_eq!(new.depth(), 0); + debug_assert!(new.is_empty()); + + new + } + + #[track_caller] + pub fn push_entry(&mut self, entry: CallStackEntry) { + let old = std::mem::replace(&mut self.current, entry); + self.inner.push(old); + debug_assert!( + self.depth() <= zkevm_opcode_defs::system_params::VM_MAX_STACK_DEPTH as usize + ); + } + + #[track_caller] + pub fn pop_entry(&mut self) -> CallStackEntry { + let previous = self.inner.pop().unwrap(); + let old = std::mem::replace(&mut self.current, previous); + + old + } + + pub fn is_full(&self) -> bool { + self.depth() == zkevm_opcode_defs::system_params::VM_MAX_STACK_DEPTH as usize + } + + pub fn is_empty(&self) -> bool { + self.inner.is_empty() + } + + pub fn depth(&self) -> usize { + self.inner.len() + } + + #[track_caller] + pub fn get_current_stack(&self) -> &CallStackEntry { + &self.current + } + + #[track_caller] + pub fn get_current_stack_mut(&mut self) -> &mut CallStackEntry { + &mut self.current + } +} diff --git a/crates/zk_evm/src/vm_state/helpers.rs b/crates/zk_evm/src/vm_state/helpers.rs new file mode 100644 index 0000000..5c0c816 --- /dev/null +++ b/crates/zk_evm/src/vm_state/helpers.rs @@ -0,0 +1,379 @@ +use super::*; +use crate::abstractions::RefundType; +use crate::abstractions::SpongeExecutionMarker; +use crate::{ + aux_structures::{ + DecommittmentQuery, LogQuery, MemoryKey, MemoryLocation, MemoryQuery, Timestamp, + }, + opcodes::parsing::*, +}; + +use zkevm_opcode_defs::UNMAPPED_PAGE; + +pub fn read_code< + const N: usize, + E: VmEncodingMode, + M: crate::abstractions::Memory, + WT: crate::witness_trace::VmWitnessTracer, +>( + memory: &M, + witness_tracer: &mut WT, + monotonic_cycle_counter: u32, + key: MemoryKey, + is_pended: bool, +) -> MemoryQuery { + let MemoryKey { + location, + timestamp, + } = key; + + let partial_query = MemoryQuery { + timestamp, + location, + value: U256::zero(), + value_is_pointer: false, + rw_flag: false, + is_pended, + }; + + let query = memory.read_code_query(monotonic_cycle_counter, partial_query); + + // also log into the historical sequence + witness_tracer.add_memory_query(monotonic_cycle_counter, query); + + query +} + +impl< + 'a, + S: crate::abstractions::Storage, + M: crate::abstractions::Memory, + EV: crate::abstractions::EventSink, + PP: crate::abstractions::PrecompilesProcessor, + DP: crate::abstractions::DecommittmentProcessor, + WT: crate::witness_trace::VmWitnessTracer, + const N: usize, + E: VmEncodingMode, + > VmState +{ + pub fn read_memory( + &mut self, + monotonic_cycle_counter: u32, + key: MemoryKey, + is_pended: bool, + ) -> MemoryQuery { + let MemoryKey { + location, + timestamp, + } = key; + + let partial_query = MemoryQuery { + timestamp, + location, + value: U256::zero(), + value_is_pointer: false, + rw_flag: false, + is_pended, + }; + + let query = self + .memory + .execute_partial_query(monotonic_cycle_counter, partial_query); + + // also log into the historical sequence + self.witness_tracer + .add_memory_query(monotonic_cycle_counter, query); + + query + } + + pub fn read_code( + &mut self, + monotonic_cycle_counter: u32, + key: MemoryKey, + is_pended: bool, + ) -> MemoryQuery { + read_code( + &mut self.memory, + &mut self.witness_tracer, + monotonic_cycle_counter, + key, + is_pended, + ) + } + + pub fn write_memory( + &mut self, + monotonic_cycle_counter: u32, + key: MemoryKey, + value: PrimitiveValue, + is_pended: bool, + ) -> MemoryQuery { + let MemoryKey { + location, + timestamp, + } = key; + + let PrimitiveValue { value, is_pointer } = value; + + let partial_query = MemoryQuery { + timestamp, + location, + value, + value_is_pointer: is_pointer, + rw_flag: true, + is_pended, + }; + + let query = self + .memory + .execute_partial_query(monotonic_cycle_counter, partial_query); + + // also log into the historical sequence + self.witness_tracer + .add_memory_query(monotonic_cycle_counter, query); + + query + } + + pub fn refund_for_partial_query( + &mut self, + monotonic_cycle_counter: u32, + partial_query: &LogQuery, + ) -> RefundType { + assert!(partial_query.rw_flag == true); + let refund = self + .storage + .estimate_refunds_for_write(monotonic_cycle_counter, partial_query); + + self.witness_tracer.record_refund_for_query( + monotonic_cycle_counter, + *partial_query, + refund, + ); + + refund + } + + pub fn access_storage(&mut self, monotonic_cycle_counter: u32, query: LogQuery) -> LogQuery { + // we do not touch pendings here and set them in the opcode only + // also storage should internally rollback when ret is performed + let mut query = self + .storage + .execute_partial_query(monotonic_cycle_counter, query); + + if !query.rw_flag { + // by convension we fill written value with the same value + query.written_value = query.read_value; + } + + // tracer takes care of proper placements in the double ended queue + self.witness_tracer + .add_log_query(monotonic_cycle_counter, query); + + query + } + + pub fn emit_event(&mut self, monotonic_cycle_counter: u32, query: LogQuery) { + self.event_sink + .add_partial_query(monotonic_cycle_counter, query); + self.witness_tracer + .add_log_query(monotonic_cycle_counter, query); + } + + pub fn decommit( + &mut self, + monotonic_cycle_counter: u32, + hash: U256, + candidate_page: MemoryPage, + timestamp: Timestamp, + ) -> DecommittmentQuery { + let partial_query = DecommittmentQuery { + hash, + timestamp, + memory_page: candidate_page, + decommitted_length: 0u16, + is_fresh: false, + }; + + let (query, witness_for_tracer) = self.decommittment_processor.decommit_into_memory( + monotonic_cycle_counter, + partial_query, + &mut self.memory, + ); + + if let Some(witness_for_tracer) = witness_for_tracer { + self.witness_tracer.add_decommittment( + monotonic_cycle_counter, + query, + witness_for_tracer, + ); + } + + query + } + + pub fn call_precompile(&mut self, monotonic_cycle_counter: u32, query: LogQuery) { + debug_assert!(self + .local_state + .callstack + .get_current_stack() + .is_kernel_mode()); + debug_assert_eq!( + query.timestamp, + self.timestamp_for_first_decommit_or_precompile_read() + ); + debug_assert_eq!(query.rw_flag, false); + // add to witness + self.witness_tracer + .add_log_query(monotonic_cycle_counter, query); + // add execution aux data + if let Some((mem_in, mem_out, round_witness)) = self + .precompiles_processor + .execute_precompile::<_>(monotonic_cycle_counter, query, &mut self.memory) + { + self.witness_tracer.add_precompile_call_result( + monotonic_cycle_counter, + query, + mem_in, + mem_out, + round_witness, + ); + } + } + + pub fn start_frame( + &mut self, + monotonic_cycle_counter: u32, + context_entry: CallStackEntry, + ) { + let timestamp = Timestamp(self.local_state.timestamp); + + self.storage.start_frame(timestamp); + self.event_sink.start_frame(timestamp); + self.precompiles_processor.start_frame(); + let previous_context = self.local_state.callstack.get_current_stack(); + + self.witness_tracer.start_new_execution_context( + monotonic_cycle_counter, + previous_context, + &context_entry, + ); + drop(previous_context); + self.local_state.callstack.push_entry(context_entry); + } + + pub fn finish_frame( + &mut self, + monotonic_cycle_counter: u32, + panicked: bool, + ) -> CallStackEntry { + let timestamp = Timestamp(self.local_state.timestamp); + + self.storage.finish_frame(timestamp, panicked); + self.event_sink.finish_frame(panicked, timestamp); + self.precompiles_processor.finish_frame(panicked); + self.witness_tracer + .finish_execution_context(monotonic_cycle_counter, panicked); + + let old_frame = self.local_state.callstack.pop_entry(); + + old_frame + } + + pub fn perform_dst0_update( + &mut self, + monotonic_cycle_counter: u32, + value: PrimitiveValue, + location: Option, + opcode: &DecodedOpcode, + ) { + // memory location is "Some" only if we use proper addressing + if let Some(location) = location { + let key = MemoryKey { + location, + timestamp: self.timestamp_for_dst_write(), + }; + let _dst0_query = self.write_memory( + monotonic_cycle_counter, + key, + value, + /* is_pended */ false, + ); // no pending on dst0 writes + + self.witness_tracer.add_sponge_marker( + self.local_state.monotonic_cycle_counter, + SpongeExecutionMarker::MemoryQuery, + 2..3, + /* is_pended */ false, + ); + } else { + self.update_register_value(opcode.dst0_reg_idx, value); + } + } + + pub fn perform_dst1_update(&mut self, value: PrimitiveValue, mask_u4_value: u8) { + self.update_register_value(mask_u4_value, value); + } + + pub fn push_bootloader_context( + &mut self, + monotonic_cycle_counter: u32, + bootloader_context: CallStackEntry, + ) { + // we have to zero out current ergs and pass all of them further + let empty_context = self.local_state.callstack.get_current_stack_mut(); + let all_ergs = empty_context.ergs_remaining; + let (remaining_for_this_frame, uf) = + all_ergs.overflowing_sub(bootloader_context.ergs_remaining); + assert!( + uf == false, + "trying to create bootloader frame with more ergs than VM has available" + ); + empty_context.ergs_remaining = remaining_for_this_frame; + drop(empty_context); + self.start_frame(monotonic_cycle_counter, bootloader_context); + let base_page = bootloader_context.base_memory_page; + self.memory.start_global_frame( + MemoryPage(UNMAPPED_PAGE), + base_page, + FatPointer::empty(), + Timestamp(self.local_state.timestamp), + ); + } + + pub(crate) fn select_register_value(&self, mask_u4_value: u8) -> PrimitiveValue { + if mask_u4_value == 0 { + PrimitiveValue::empty() + } else { + self.local_state.registers[(mask_u4_value - 1) as usize] + } + } + + pub(crate) fn update_register_value( + &mut self, + mask_u4_value: u8, + value_to_set: PrimitiveValue, + ) { + if mask_u4_value > 0 { + self.local_state.registers[(mask_u4_value - 1) as usize] = value_to_set; + } + } + + pub(crate) fn set_shorthand_panic(&mut self) { + self.local_state.pending_exception = true; + } +} + +use zkevm_opcode_defs::bitflags::bitflags; +use zkevm_opcode_defs::FatPointer; + +bitflags! { + pub struct ErrorFlags: u64 { + const INVALID_OPCODE = 1u64 << 0; + const NOT_ENOUGH_ERGS = 1u64 << 1; + const PRIVILAGED_ACCESS_NOT_FROM_KERNEL = 1u64 << 2; + const WRITE_IN_STATIC_CONTEXT = 1u64 << 3; + const CALLSTACK_IS_FULL = 1u64 << 4; + } +} diff --git a/crates/zk_evm/src/vm_state/mem_ops.rs b/crates/zk_evm/src/vm_state/mem_ops.rs new file mode 100644 index 0000000..093d2c5 --- /dev/null +++ b/crates/zk_evm/src/vm_state/mem_ops.rs @@ -0,0 +1,123 @@ +use super::*; +use crate::abstractions::MemoryType; +use crate::aux_structures::{MemoryIndex, MemoryLocation}; +use zkevm_opcode_defs::{ImmMemHandlerFlags, RegOrImmFlags}; + +pub struct MemOpsProcessor = EncodingModeProduction> { + pub sp: E::PcOrImm, +} + +use zkevm_opcode_defs::Operand; + +impl> MemOpsProcessor { + pub fn compute_addresses_and_select_operands< + 'a, + S: crate::abstractions::Storage, + M: crate::abstractions::Memory, + EV: crate::abstractions::EventSink, + PP: crate::abstractions::PrecompilesProcessor, + DP: crate::abstractions::DecommittmentProcessor, + WT: crate::witness_trace::VmWitnessTracer, + >( + &mut self, + vm_state: &VmState, + register_index_encoding: u8, + imm: E::PcOrImm, + mem_imm: Operand, + is_write: bool, + ) -> (PrimitiveValue, Option) { + let primitive_value = vm_state.select_register_value(register_index_encoding); + let PrimitiveValue { + value: reg_value, + is_pointer: _, + } = primitive_value; + let reg_low = E::PcOrImm::from_u64_clipped(reg_value.low_u64()); + let vaddr = reg_low.wrapping_add(imm); + let current_context = vm_state.local_state.callstack.get_current_stack(); + let memory_location = match mem_imm { + Operand::RegOnly => None, + Operand::RegOrImm(RegOrImmFlags::UseRegOnly) => None, + Operand::RegOrImm(RegOrImmFlags::UseImm16Only) => { + debug_assert!(!is_write); + + None + } + Operand::Full(ImmMemHandlerFlags::UseRegOnly) => None, + Operand::Full(ImmMemHandlerFlags::UseImm16Only) => { + debug_assert!(!is_write); + + None + } + Operand::Full(ImmMemHandlerFlags::UseStackWithPushPop) => { + // SP may point to uninit values, but we will leave it for compiler + let current_sp = self.sp; + // now we also have to decide on case of push or pop, to have push not to overflow 2^16, and pop not to underflow + if is_write { + let new_sp = current_sp.wrapping_add(vaddr); + self.sp = new_sp; + + let stack_page = CallStackEntry::::stack_page_from_base( + current_context.base_memory_page, + ); + let location = MemoryLocation { + memory_type: MemoryType::Stack, + page: stack_page, + index: MemoryIndex(new_sp.as_u64() as u32), + }; + + Some(location) + } else { + let new_sp = current_sp.wrapping_sub(vaddr); + self.sp = new_sp; + + let stack_page = CallStackEntry::::stack_page_from_base( + current_context.base_memory_page, + ); + let location = MemoryLocation { + memory_type: MemoryType::Stack, + page: stack_page, + index: MemoryIndex(new_sp.as_u64() as u32), + }; + + Some(location) + } + } + Operand::Full(ImmMemHandlerFlags::UseStackWithOffset) => { + let offset = self.sp.wrapping_sub(vaddr); + let stack_page = + CallStackEntry::::stack_page_from_base(current_context.base_memory_page); + let location = MemoryLocation { + memory_type: MemoryType::Stack, + page: stack_page, + index: MemoryIndex(offset.as_u64() as u32), + }; + + Some(location) + } + Operand::Full(ImmMemHandlerFlags::UseCodePage) => { + debug_assert!(!is_write); + let code_page = current_context.code_page; + let location = MemoryLocation { + memory_type: MemoryType::Code, + page: code_page, + index: MemoryIndex(vaddr.as_u64() as u32), + }; + + Some(location) + } + Operand::Full(ImmMemHandlerFlags::UseAbsoluteOnStack) => { + let stack_page = + CallStackEntry::::stack_page_from_base(current_context.base_memory_page); + let location = MemoryLocation { + memory_type: MemoryType::Stack, + page: stack_page, + index: MemoryIndex(vaddr.as_u64() as u32), + }; + + Some(location) + } + }; + + (primitive_value, memory_location) + } +} diff --git a/crates/zk_evm/src/vm_state/mod.rs b/crates/zk_evm/src/vm_state/mod.rs new file mode 100644 index 0000000..e066acb --- /dev/null +++ b/crates/zk_evm/src/vm_state/mod.rs @@ -0,0 +1,260 @@ +use zkevm_opcode_defs::decoding::encoding_mode_production::EncodingModeProduction; +use zkevm_opcode_defs::decoding::VmEncodingMode; +use zkevm_opcode_defs::ISAVersion; + +use super::*; +use crate::aux_structures::MemoryPage; +use crate::aux_structures::Timestamp; +use crate::flags::Flags; +use zkevm_opcode_defs::decoding::AllowedPcOrImm; + +pub mod cycle; +pub mod execution_stack; +pub mod helpers; +pub mod mem_ops; +pub mod pending_port; + +pub use self::cycle::*; +pub use self::execution_stack::*; +pub use self::helpers::*; +pub use self::mem_ops::*; +pub use self::pending_port::*; + +pub const SUPPORTED_ISA_VERSION: ISAVersion = ISAVersion(1); + +const _: () = if SUPPORTED_ISA_VERSION.0 != zkevm_opcode_defs::DEFAULT_ISA_VERSION.0 { + panic!() +} else { + () +}; + +use zkevm_opcode_defs::{STARTING_BASE_PAGE, STARTING_TIMESTAMP}; + +#[derive(Default, Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub struct PrimitiveValue { + pub value: U256, + pub is_pointer: bool, +} + +impl PrimitiveValue { + pub const fn empty() -> Self { + Self { + value: U256::zero(), + is_pointer: false, + } + } + + pub const fn from_value(value: U256) -> Self { + Self { + value, + is_pointer: false, + } + } +} + +#[derive(Clone, Debug, PartialEq)] +pub struct VmLocalState = EncodingModeProduction> { + pub previous_code_word: U256, + pub registers: [PrimitiveValue; zkevm_opcode_defs::REGISTERS_COUNT], + pub flags: Flags, + pub timestamp: u32, + pub monotonic_cycle_counter: u32, + // A counter for the *ergs* spent on public data for L2 -> L2 messages and storage writes. + // It is an out-of-circuit only value and it does not (and can not) include ergs spent + // on the content of long L2->L1 messages as well as well as publishing contract's bytecode. + pub spent_pubdata_counter: u32, + pub memory_page_counter: u32, + pub absolute_execution_step: u32, + pub current_ergs_per_pubdata_byte: u32, + pub tx_number_in_block: u16, + pub did_call_or_ret_recently: bool, + pub pending_exception: bool, + pub previous_super_pc: E::PcOrImm, + pub context_u128_register: u128, + pub callstack: Callstack, + pub pending_port: SpongePendingPort, + pub pending_cycles_left: Option, +} + +impl> VmLocalState { + pub fn empty_state() -> Self { + Self { + previous_code_word: U256::zero(), + registers: [PrimitiveValue::empty(); zkevm_opcode_defs::REGISTERS_COUNT], + flags: Flags::empty(), + timestamp: STARTING_TIMESTAMP, + monotonic_cycle_counter: 0u32, + spent_pubdata_counter: 0u32, + memory_page_counter: STARTING_BASE_PAGE, + absolute_execution_step: 0, + current_ergs_per_pubdata_byte: 0, + tx_number_in_block: 0, + previous_super_pc: E::PcOrImm::from_u64_clipped(0), + did_call_or_ret_recently: true, // to properly start the execution + pending_exception: false, + pending_port: SpongePendingPort::empty(), + pending_cycles_left: None, + context_u128_register: 0u128, + callstack: Callstack::empty(), + } + } + + pub fn execution_has_ended(&self) -> bool { + self.callstack.is_empty() + } + + pub fn timestamp_for_code_or_src_read(&self) -> Timestamp { + Timestamp(self.timestamp + 0) + } + + pub fn callstack_is_full(&self) -> bool { + self.callstack.is_full() + } +} + +#[derive(Clone, Debug, PartialEq)] +pub struct DelayedLocalStateChanges< + const N: usize = 8, + E: VmEncodingMode = EncodingModeProduction, +> { + pub reset_pending_port: bool, + pub reset_did_call_or_ret_recently: bool, + pub new_ergs_remaining: Option, + pub new_previous_code_word: Option, + pub new_previous_super_pc: Option, + pub new_pending_exception: Option, +} + +impl> Default for DelayedLocalStateChanges { + fn default() -> Self { + Self { + reset_pending_port: false, + reset_did_call_or_ret_recently: false, + new_ergs_remaining: None, + new_previous_code_word: None, + new_previous_super_pc: None, + new_pending_exception: None, + } + } +} + +impl> DelayedLocalStateChanges { + pub fn apply(self, local_state: &mut VmLocalState) { + if self.reset_pending_port { + local_state.pending_port.reset(); + } + if self.reset_did_call_or_ret_recently { + local_state.did_call_or_ret_recently = false; + } + if let Some(ergs_remaining) = self.new_ergs_remaining { + local_state.callstack.get_current_stack_mut().ergs_remaining = ergs_remaining; + } + if let Some(previous_code_word) = self.new_previous_code_word { + local_state.previous_code_word = previous_code_word; + } + + if let Some(previous_super_pc) = self.new_previous_super_pc { + local_state.previous_super_pc = previous_super_pc; + } + + if let Some(new_pending_exception) = self.new_pending_exception { + local_state.pending_exception = new_pending_exception; + } + } +} + +#[derive(Debug)] +pub struct VmState< + S: crate::abstractions::Storage, + M: crate::abstractions::Memory, + EV: crate::abstractions::EventSink, + PP: crate::abstractions::PrecompilesProcessor, + DP: crate::abstractions::DecommittmentProcessor, + WT: crate::witness_trace::VmWitnessTracer, + const N: usize = 8, + E: VmEncodingMode = EncodingModeProduction, +> { + pub local_state: VmLocalState, + pub block_properties: crate::block_properties::BlockProperties, + pub storage: S, + pub memory: M, + pub event_sink: EV, + pub precompiles_processor: PP, + pub decommittment_processor: DP, + pub witness_tracer: WT, +} + +impl< + S: crate::abstractions::Storage, + M: crate::abstractions::Memory, + EV: crate::abstractions::EventSink, + PP: crate::abstractions::PrecompilesProcessor, + DP: crate::abstractions::DecommittmentProcessor, + WT: crate::witness_trace::VmWitnessTracer, + const N: usize, + E: VmEncodingMode, + > VmState +{ + pub fn empty_state( + storage: S, + memory: M, + event_sink: EV, + precompiles_processor: PP, + decommittment_processor: DP, + witness_tracer: WT, + block_properties: crate::block_properties::BlockProperties, + ) -> Self { + Self { + local_state: VmLocalState::empty_state(), + storage, + memory, + event_sink, + precompiles_processor, + decommittment_processor, + witness_tracer, + block_properties, + } + } + pub fn reset_flags(&mut self) { + self.local_state.flags.reset(); + } + pub fn is_any_pending(&self) -> bool { + self.local_state.pending_port.is_any_pending() + } + pub fn callstack_is_full(&self) -> bool { + self.local_state.callstack_is_full() + } + pub fn execution_has_ended(&self) -> bool { + self.local_state.execution_has_ended() + } + pub fn check_skip_cycles_due_to_pending(&mut self) -> bool { + let should_skip = self.local_state.pending_port.is_any_pending(); + self.local_state.pending_port.reset(); + + should_skip + } + pub fn compute_if_should_skip_cycle(&mut self) -> bool { + self.check_skip_cycles_due_to_pending() || self.execution_has_ended() + } + pub fn timestamp_for_code_or_src_read(&self) -> Timestamp { + self.local_state.timestamp_for_code_or_src_read() + } + pub fn timestamp_for_first_decommit_or_precompile_read(&self) -> Timestamp { + Timestamp(self.local_state.timestamp + 1) + } + pub fn timestamp_for_second_decommit_or_precompile_write(&self) -> Timestamp { + Timestamp(self.local_state.timestamp + 2) + } + pub fn timestamp_for_dst_write(&self) -> Timestamp { + Timestamp(self.local_state.timestamp + 3) + } + pub fn increment_timestamp_after_cycle(&mut self) { + self.local_state.timestamp += zkevm_opcode_defs::TIME_DELTA_PER_CYCLE + } + pub fn new_base_memory_page_on_call(&self) -> MemoryPage { + MemoryPage(self.local_state.memory_page_counter) + } + pub fn increment_memory_pages_on_call(&mut self) { + self.local_state.memory_page_counter += zkevm_opcode_defs::NEW_MEMORY_PAGES_PER_FAR_CALL; + } +} diff --git a/crates/zk_evm/src/vm_state/pending_port.rs b/crates/zk_evm/src/vm_state/pending_port.rs new file mode 100644 index 0000000..05fa83f --- /dev/null +++ b/crates/zk_evm/src/vm_state/pending_port.rs @@ -0,0 +1,26 @@ +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum PendingType { + FarCall, + Ret, + WriteLog, + UMAWrite, +} + +#[derive(Debug, Clone, Copy, PartialEq)] +pub struct SpongePendingPort { + pub pending_type: Option, +} + +impl SpongePendingPort { + pub const fn empty() -> Self { + Self { pending_type: None } + } + + pub const fn is_any_pending(&self) -> bool { + self.pending_type.is_some() + } + + pub fn reset(&mut self) { + self.pending_type = None; + } +} diff --git a/crates/zk_evm/src/witness_trace/mod.rs b/crates/zk_evm/src/witness_trace/mod.rs new file mode 100644 index 0000000..11bb50d --- /dev/null +++ b/crates/zk_evm/src/witness_trace/mod.rs @@ -0,0 +1,86 @@ +use zkevm_opcode_defs::decoding::VmEncodingMode; + +use super::aux_structures::*; +use super::*; +use crate::abstractions::{PrecompileCyclesWitness, RefundType, SpongeExecutionMarker}; +use crate::vm_state::{CallStackEntry, VmLocalState}; +use std::ops::Range; + +#[allow(unused_variables)] +pub trait VmWitnessTracer>: Clone + std::fmt::Debug { + #[inline] + fn start_new_execution_cycle(&mut self, current_state: &VmLocalState) {} + + #[inline] + fn end_execution_cycle(&mut self, current_state: &VmLocalState) {} + + #[inline] + fn add_sponge_marker( + &mut self, + monotonic_cycle_counter: u32, + marker: SpongeExecutionMarker, + sponges_range: Range, + is_pended: bool, + ) { + } + + #[inline] + fn add_memory_query(&mut self, monotonic_cycle_counter: u32, memory_query: MemoryQuery) {} + + #[inline] + fn record_refund_for_query( + &mut self, + monotonic_cycle_counter: u32, + log_query: LogQuery, + refund: RefundType, + ) { + } + + #[inline] + fn add_log_query(&mut self, monotonic_cycle_counter: u32, log_query: LogQuery) {} + + #[inline] + fn add_decommittment( + &mut self, + monotonic_cycle_counter: u32, + decommittment_query: DecommittmentQuery, + mem_witness: Vec, + ) { + } + + #[inline] + fn add_precompile_call_result( + &mut self, + monotonic_cycle_counter: u32, + call_params: LogQuery, + mem_witness_in: Vec, + memory_witness_out: Vec, + round_witness: PrecompileCyclesWitness, + ) { + } + + #[inline] + fn add_revertable_precompile_call( + &mut self, + monotonic_cycle_counter: u32, + call_params: LogQuery, + ) { + } + + #[inline] + fn start_new_execution_context( + &mut self, + monotonic_cycle_counter: u32, + previous_context: &CallStackEntry, + new_context: &CallStackEntry, + ) { + } + + #[inline] + fn finish_execution_context(&mut self, monotonic_cycle_counter: u32, panicked: bool) {} +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct DummyTracer; + +impl> VmWitnessTracer for DummyTracer {} diff --git a/crates/zkevm_opcode_defs/.github/ISSUE_TEMPLATE/bug_report.md b/crates/zkevm_opcode_defs/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..2d3e38a --- /dev/null +++ b/crates/zkevm_opcode_defs/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,39 @@ +--- +name: Bug report +about: Use this template for reporting issues +title: '' +labels: bug +assignees: '' +--- + +### 🐛 Bug Report + +#### 📝 Description + +Provide a clear and concise description of the bug. + +#### 🔄 Reproduction Steps + +Steps to reproduce the behaviour + +#### 🤔 Expected Behavior + +Describe what you expected to happen. + +#### 😯 Current Behavior + +Describe what actually happened. + +#### 🖥️ Environment + +Any relevant environment details. + +#### 📋 Additional Context + +Add any other context about the problem here. If applicable, add screenshots to help explain. + +#### 📎 Log Output + +``` +Paste any relevant log output here. +``` diff --git a/crates/zkevm_opcode_defs/.github/ISSUE_TEMPLATE/feature_request.md b/crates/zkevm_opcode_defs/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..d921e06 --- /dev/null +++ b/crates/zkevm_opcode_defs/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,21 @@ +--- +name: Feature request +about: Use this template for requesting features +title: '' +labels: feat +assignees: '' +--- + +### 🌟 Feature Request + +#### 📝 Description + +Provide a clear and concise description of the feature you'd like to see. + +#### 🤔 Rationale + +Explain why this feature is important and how it benefits the project. + +#### 📋 Additional Context + +Add any other context or information about the feature request here. diff --git a/crates/zkevm_opcode_defs/.github/pull_request_template.md b/crates/zkevm_opcode_defs/.github/pull_request_template.md new file mode 100644 index 0000000..8ce206c --- /dev/null +++ b/crates/zkevm_opcode_defs/.github/pull_request_template.md @@ -0,0 +1,20 @@ +# What ❔ + + + + + +## Why ❔ + + + + +## Checklist + + + + +- [ ] PR title corresponds to the body of PR (we generate changelog entries from PRs). +- [ ] Tests for the changes have been added / updated. +- [ ] Documentation comments have been added / updated. +- [ ] Code has been formatted via `zk fmt` and `zk lint`. diff --git a/crates/zkevm_opcode_defs/.github/workflows/cargo-license.yaml b/crates/zkevm_opcode_defs/.github/workflows/cargo-license.yaml new file mode 100644 index 0000000..189b471 --- /dev/null +++ b/crates/zkevm_opcode_defs/.github/workflows/cargo-license.yaml @@ -0,0 +1,8 @@ +name: Cargo license check +on: pull_request +jobs: + cargo-deny: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: EmbarkStudios/cargo-deny-action@v1 diff --git a/crates/zkevm_opcode_defs/.github/workflows/ci.yaml b/crates/zkevm_opcode_defs/.github/workflows/ci.yaml new file mode 100644 index 0000000..fd0bd3b --- /dev/null +++ b/crates/zkevm_opcode_defs/.github/workflows/ci.yaml @@ -0,0 +1,23 @@ +name: "Rust CI" +on: + pull_request: + +jobs: + build: + name: cargo build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions-rust-lang/setup-rust-toolchain@v1 + - run: cargo build --verbose + + formatting: + name: cargo fmt + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + components: rustfmt + - name: Rustfmt Check + uses: actions-rust-lang/rustfmt@v1 diff --git a/crates/zkevm_opcode_defs/.github/workflows/secrets_scanner.yaml b/crates/zkevm_opcode_defs/.github/workflows/secrets_scanner.yaml new file mode 100644 index 0000000..54054cf --- /dev/null +++ b/crates/zkevm_opcode_defs/.github/workflows/secrets_scanner.yaml @@ -0,0 +1,17 @@ +name: Leaked Secrets Scan +on: [pull_request] +jobs: + TruffleHog: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3 + with: + fetch-depth: 0 + - name: TruffleHog OSS + uses: trufflesecurity/trufflehog@0c66d30c1f4075cee1aada2e1ab46dabb1b0071a + with: + path: ./ + base: ${{ github.event.repository.default_branch }} + head: HEAD + extra_args: --debug --only-verified diff --git a/crates/zkevm_opcode_defs/.gitignore b/crates/zkevm_opcode_defs/.gitignore new file mode 100644 index 0000000..96ef6c0 --- /dev/null +++ b/crates/zkevm_opcode_defs/.gitignore @@ -0,0 +1,2 @@ +/target +Cargo.lock diff --git a/crates/zkevm_opcode_defs/CONTRIBUTING.md b/crates/zkevm_opcode_defs/CONTRIBUTING.md new file mode 100644 index 0000000..dd3d458 --- /dev/null +++ b/crates/zkevm_opcode_defs/CONTRIBUTING.md @@ -0,0 +1,44 @@ +# Contribution Guidelines + +Hello! Thanks for your interest in joining the mission to accelerate the mass adoption of crypto for personal +sovereignty! We welcome contributions from anyone on the internet, and are grateful for even the smallest of fixes! + +## Ways to contribute + +There are many ways to contribute to the ZK Stack: + +1. Open issues: if you find a bug, have something you believe needs to be fixed, or have an idea for a feature, please + open an issue. +2. Add color to existing issues: provide screenshots, code snippets, and whatever you think would be helpful to resolve + issues. +3. Resolve issues: either by showing an issue isn't a problem and the current state is ok as is or by fixing the problem + and opening a PR. +4. Report security issues, see [our security policy](./github/SECURITY.md). +5. [Join the team!](https://matterlabs.notion.site/Shape-the-future-of-Ethereum-at-Matter-Labs-dfb3b5a037044bb3a8006af2eb0575e0) + +## Fixing issues + +To contribute code fixing issues, please fork the repo, fix an issue, commit, add documentation as per the PR template, +and the repo's maintainers will review the PR. +[here](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork) +for guidance how to work with PRs created from a fork. + +## Licenses + +If you contribute to this project, your contributions will be made to the project under both Apache 2.0 and the MIT +license. + +## Resources + +We aim to make it as easy as possible to contribute to the mission. This is still WIP, and we're happy for contributions +and suggestions here too. Some resources to help: + +1. [In-repo docs aimed at developers](docs) +2. [zkSync Era docs!](https://era.zksync.io/docs/) +3. Company links can be found in the [repo's readme](README.md) + +## Code of Conduct + +Be polite and respectful. + +### Thank you diff --git a/crates/zkevm_opcode_defs/Cargo.toml b/crates/zkevm_opcode_defs/Cargo.toml new file mode 100644 index 0000000..59253fd --- /dev/null +++ b/crates/zkevm_opcode_defs/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "zkevm_opcode_defs" +version = "0.131.0" +edition = "2021" +authors = ["The Matter Labs Team "] +homepage = "https://zksync.io/" +repository = "https://github.com/matter-labs/era-zkevm_opcode_defs" +license = "MIT OR Apache-2.0" +keywords = ["blockchain", "zksync"] +categories = ["cryptography"] +description = "ZKsync EraVM opcode definitions" + +resolver = "2" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[[bin]] +name = "circuit_pricing_generator" +path = "src/circuit_pricing_generator/main.rs" + +[dependencies] +bitflags = "1.3" +lazy_static = "1.4" +ethereum-types = "=0.14.1" +sha2 = "0.10" diff --git a/crates/zkevm_opcode_defs/LICENSE-APACHE b/crates/zkevm_opcode_defs/LICENSE-APACHE new file mode 100644 index 0000000..d9a10c0 --- /dev/null +++ b/crates/zkevm_opcode_defs/LICENSE-APACHE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/crates/zkevm_opcode_defs/LICENSE-MIT b/crates/zkevm_opcode_defs/LICENSE-MIT new file mode 100644 index 0000000..2739ea6 --- /dev/null +++ b/crates/zkevm_opcode_defs/LICENSE-MIT @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Matter Labs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/crates/zkevm_opcode_defs/README.md b/crates/zkevm_opcode_defs/README.md new file mode 100644 index 0000000..7009b8c --- /dev/null +++ b/crates/zkevm_opcode_defs/README.md @@ -0,0 +1,32 @@ +# CPU/GPU Based Prover for zkSync Era + +[![Logo](eraLogo.png)](https://zksync.io/) + +zkSync Era is a layer 2 rollup that uses zero-knowledge proofs to scale Ethereum without compromising on security or +decentralization. Since it's EVM compatible (Solidity/Vyper), 99% of Ethereum projects can redeploy without refactoring +or re-auditing a single line of code. zkSync Era also uses an LLVM-based compiler that will eventually let developers +write smart contracts in C++, Rust and other popular languages. + +## License + +The zkSync Era prover is distributed under the terms of either + +- Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) +- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) + +at your option. + +## Official Links + +- [Website](https://zksync.io/) +- [GitHub](https://github.com/matter-labs) +- [Twitter](https://twitter.com/zksync) +- [Twitter for Devs](https://twitter.com/zkSyncDevs) +- [Discord](https://join.zksync.dev) + +## Disclaimer + +zkSync Era has been through lots of testing and audits. Although it is live, it is still in alpha state and will go +through more audits and bug bounties programs. We would love to hear our community's thoughts and suggestions about it! +It is important to state that forking it now can potentially lead to missing important security updates, critical +features, and performance improvements. diff --git a/crates/zkevm_opcode_defs/SECURITY.md b/crates/zkevm_opcode_defs/SECURITY.md new file mode 100644 index 0000000..2f2871c --- /dev/null +++ b/crates/zkevm_opcode_defs/SECURITY.md @@ -0,0 +1,74 @@ +# Security Policy + +We truly appreciate efforts to discover and disclose security issues responsibly! + +## Vulnerabilities + +If you'd like to report a security issue in the repositories of matter-labs organization, please proceed to our +[Bug Bounty Program on Immunefi](https://era.zksync.io/docs/reference/troubleshooting/audit-bug-bounty.html#bug-bounty-program). + +## Other Security Issues + +We take an impact-first approach instead of a rules-first approach. Therefore, if you believe you found the impactful +issue but can't report it via the Bug Bounty, please email us at +[security@matterlabs.dev](mailto:security@matterlabs.dev). + +### PGP Key + +The following PGP key may be used to communicate sensitive information to developers: + +Fingerprint: `5FED B2D0 EA2C 4906 DD66 71D7 A2C5 0B40 CE3C F297` + +``` +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +=xkM3 +-----END PGP PUBLIC KEY BLOCK----- +``` diff --git a/crates/zkevm_opcode_defs/deny.toml b/crates/zkevm_opcode_defs/deny.toml new file mode 100644 index 0000000..a957d98 --- /dev/null +++ b/crates/zkevm_opcode_defs/deny.toml @@ -0,0 +1,78 @@ +all-features = false +no-default-features = false + +[advisories] +vulnerability = "deny" +unmaintained = "warn" +yanked = "warn" +notice = "warn" +ignore = [ + #"RUSTSEC-0000-0000", +] + +[licenses] +unlicensed = "deny" +allow = [ + #"Apache-2.0 WITH LLVM-exception", + "MIT", + "Apache-2.0", + "ISC", + "Unlicense", + "MPL-2.0", + "Unicode-DFS-2016", + "CC0-1.0", + "BSD-2-Clause", + "BSD-3-Clause", +] +deny = [ + #"Nokia", +] +copyleft = "warn" +allow-osi-fsf-free = "neither" +default = "deny" +confidence-threshold = 0.8 +exceptions = [ + # Each entry is the crate and version constraint, and its specific allow + # list + #{ allow = ["Zlib"], name = "adler32", version = "*" }, +] + +unused-allowed-license = "allow" + +[licenses.private] +ignore = false +registries = [ + #"https://sekretz.com/registry +] + +[bans] +multiple-versions = "warn" +wildcards = "allow" +highlight = "all" +workspace-default-features = "allow" +external-default-features = "allow" +allow = [ + #{ name = "ansi_term", version = "=0.11.0" }, +] +# List of crates to deny +deny = [ + # Each entry the name of a crate and a version range. If version is + # not specified, all versions will be matched. + #{ name = "ansi_term", version = "=0.11.0" }, +] + +skip = [ + #{ name = "ansi_term", version = "=0.11.0" }, +] +skip-tree = [ + #{ name = "ansi_term", version = "=0.11.0", depth = 20 }, +] + +[sources] +unknown-registry = "deny" +unknown-git = "deny" +allow-registry = ["https://github.com/rust-lang/crates.io-index"] +allow-git = [] + +[sources.allow-org] +#github = ["matter-labs"] diff --git a/crates/zkevm_opcode_defs/eraLogo.png b/crates/zkevm_opcode_defs/eraLogo.png new file mode 100644 index 0000000000000000000000000000000000000000..5d9480d8f05342a06cd1ee03405137552bdbebbf GIT binary patch literal 79091 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 u32 { + (a + b - 1) / b +} + +fn ergs_constant(name: &str, value: u32) -> String { + format!("pub const {}: u32 = {};\n", name, value) +} + +fn comment(comment: &str) -> String { + format!("\n// {}\n", comment) +} + +fn save_circiut_prices(prices: String, filepath: &str) { + let file_content = vec![ + "// This file is auto-generated, do not edit it manually\n".to_owned(), + "// Any changes to this file require system upgrade!\n\n".to_owned(), + prices, + ] + .concat(); + let mut f = File::create(filepath).expect("Unable to create file"); + f.write_all(file_content.as_bytes()) + .expect("Unable to write data"); +} + +fn main() { + let max_possible_initial_bytes_circuit_wise = + LIMIT_FOR_INITIAL_WRITES_PUBDATA_HASHER * (INITIAL_STORAGE_WRITE_PUBDATA_BYTES as u32); + let min_price_for_initial_pubdata_write = + if MAX_PUBDATA_PER_BLOCK <= max_possible_initial_bytes_circuit_wise { + // The cost of pubdata alone would not let the users to run out of this circuit + // before the end of the transaction. The users can safely pay nothing for the DDoS security. + 0 + } else { + ceil_div(MAX_TX_ERGS_LIMIT, LIMIT_FOR_INITIAL_WRITES_PUBDATA_HASHER) + }; + + let max_possible_repeated_bytes_circuit_wise = + LIMIT_FOR_REPEATED_WRITES_PUBDATA_HASHER * (REPEATED_STORAGE_WRITE_PUBDATA_BYTES as u32); + let min_price_for_repeated_pubdata_write = + if MAX_PUBDATA_PER_BLOCK <= max_possible_repeated_bytes_circuit_wise { + // The cost of pubdata alone would not let the users to run out of this circuit + // before the end of the transaction. The users can safely pay nothing for the DDoS security. + 0 + } else { + ceil_div(MAX_TX_ERGS_LIMIT, LIMIT_FOR_REPEATED_WRITES_PUBDATA_HASHER) + }; + + let circuit_prices = vec![ + ergs_constant( + "VM_CYCLE_COST_IN_ERGS", + ceil_div(ERGS_PER_CIRCUIT, CYCLES_PER_VM_SNAPSHOT), + ), + ergs_constant( + "RAM_PERMUTATION_COST_IN_ERGS", + ceil_div(ERGS_PER_CIRCUIT, CYCLES_PER_RAM_PERMUTATION), + ), + ergs_constant( + "CODE_DECOMMITMENT_COST_PER_WORD_IN_ERGS", + // Each round of decommitter outputs 64 bytes of the code, + // while the user will pay for each word. + ceil_div(ERGS_PER_CIRCUIT, 2 * CYCLES_PER_CODE_DECOMMITTER), + ), + ergs_constant( + "STORAGE_APPLICATION_COST_IN_ERGS", + ceil_div(ERGS_PER_CIRCUIT, CYCLES_PER_STORAGE_APPLICATION), + ), + ergs_constant( + "CODE_DECOMMITTER_SORTER_COST_IN_ERGS", + ceil_div(ERGS_PER_CIRCUIT, LIMIT_FOR_CODE_DECOMMITTER_SORTER), + ), + ergs_constant( + "LOG_DEMUXER_COST_IN_ERGS", + ceil_div(ERGS_PER_CIRCUIT, LIMIT_FOR_LOG_DEMUXER), + ), + ergs_constant( + "STORAGE_SORTER_COST_IN_ERGS", + ceil_div(ERGS_PER_CIRCUIT, LIMIT_FOR_STORAGE_SORTER), + ), + ergs_constant( + "EVENTS_OR_L1_MESSAGES_SORTER_COST_IN_ERGS", + ceil_div(ERGS_PER_CIRCUIT, LIMIT_FOR_EVENTS_OR_L1_MESSAGES_SORTER), + ), + ergs_constant( + "INITIAL_WRITES_PUBDATA_HASHER_COST_IN_ERGS", + ceil_div(ERGS_PER_CIRCUIT, LIMIT_FOR_INITIAL_WRITES_PUBDATA_HASHER), + ), + ergs_constant( + "REPEATED_WRITES_PUBDATA_HASHER_COST_IN_ERGS", + ceil_div(ERGS_PER_CIRCUIT, LIMIT_FOR_REPEATED_WRITES_PUBDATA_HASHER), + ), + comment("The following circuits are single-instance and so the provided prices are just minimal prices to preserve DDoS safety"), + ergs_constant( + "L1_MESSAGE_MIN_COST_IN_ERGS", + ceil_div(MAX_TX_ERGS_LIMIT, LIMIT_FOR_L1_MESSAGES_MERKLIZER), + ), + ergs_constant( + "CODE_DECOMMITMENT_SORTER_MIN_COST_IN_ERGS", + ceil_div(MAX_TX_ERGS_LIMIT, LIMIT_FOR_CODE_DECOMMITTER_SORTER) + ), + ergs_constant( + "INITIAL_WRITES_PUBDATA_HASHER_MIN_COST_IN_ERGS", + min_price_for_initial_pubdata_write + ), + ergs_constant( + "REPEATED_WRITES_PUBDATA_HASHER_MIN_COST_IN_ERGS", + min_price_for_repeated_pubdata_write + ), + comment("Equals to max(INITIAL_WRITES_PUBDATA_HASHER_MIN_COST_IN_ERGS, REPEATED_WRITES_PUBDATA_HASHER_MIN_COST_IN_ERGS)"), + ergs_constant( + "STORAGE_WRITE_MIN_COST_IN_ERGS", + std::cmp::max(min_price_for_initial_pubdata_write, min_price_for_repeated_pubdata_write) + ), + comment("The following constants should not be used in the VM directly, but only in Solidity wrappers"), + ergs_constant( + "KECCAK256_CIRCUIT_COST_IN_ERGS", + ceil_div(ERGS_PER_CIRCUIT, CYCLES_PER_KECCAK256_CIRCUIT), + ), + ergs_constant( + "SHA256_CIRCUIT_COST_IN_ERGS", + ceil_div(ERGS_PER_CIRCUIT, CYCLES_PER_SHA256_CIRCUIT), + ), + ergs_constant( + "ECRECOVER_CIRCUIT_COST_IN_ERGS", + ceil_div(ERGS_PER_CIRCUIT, CYCLES_PER_ECRECOVER_CIRCUIT), + ), + ] + .concat(); + + save_circiut_prices(circuit_prices, "src/circuit_prices.rs"); +} diff --git a/crates/zkevm_opcode_defs/src/decoding/encoding_mode_production.rs b/crates/zkevm_opcode_defs/src/decoding/encoding_mode_production.rs new file mode 100644 index 0000000..261b3be --- /dev/null +++ b/crates/zkevm_opcode_defs/src/decoding/encoding_mode_production.rs @@ -0,0 +1,175 @@ +use super::*; + +use crate::merge_u4; +use crate::split_as_u4; +use crate::Condition; +use crate::OpcodeVariant; +use crate::CONDITIONAL_BITS_SHIFT; +use crate::CONDITIONAL_BITS_WIDTH; +use crate::DST_REGS_SHIFT; +use crate::OPCODES_TABLE; +use crate::OPCODES_TABLE_WIDTH; +use crate::SRC_REGS_SHIFT; +use crate::{NOP_OPCODE_VARIANT, PANIC_OPCODE_VARIANT}; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub struct EncodingModeProduction; + +impl EncodingModeProduction { + const IMM0_SHIFT: u32 = 32; + const IMM1_SHIFT: u32 = 48; + const VARIANT_AND_CONDITION_BITS: usize = 16; + const VARIANT_MASK: u64 = (1u64 << OPCODES_TABLE_WIDTH) - 1; + const CONDITION_MASK: u64 = ((1u64 << CONDITIONAL_BITS_WIDTH) - 1) << CONDITIONAL_BITS_SHIFT; + const UNUSED_GAP_RAW_MASK: u64 = (1u64 + << (Self::VARIANT_AND_CONDITION_BITS - OPCODES_TABLE_WIDTH - CONDITIONAL_BITS_WIDTH)) + - 1; + const UNUSED_BITS_MASK: u64 = Self::UNUSED_GAP_RAW_MASK << OPCODES_TABLE_WIDTH; + + pub fn variant_and_condition_from_u64_word( + raw_value: u64, + ) -> (OpcodeVariant, Condition, usize) { + let variant_bits = raw_value & Self::VARIANT_MASK; + let opcode_variant = OPCODES_TABLE[variant_bits as usize]; + let condition_bits = (raw_value & Self::CONDITION_MASK) >> CONDITIONAL_BITS_SHIFT; + let condition = Condition::materialize_variant(condition_bits as usize); + + (opcode_variant, condition, variant_bits as usize) + } +} + +impl VmEncodingMode<8> for EncodingModeProduction { + type PcOrImm = u16; + type IntegerRepresentation = u64; + + fn nop_encoding() -> Self::IntegerRepresentation { + let variant = *NOP_OPCODE_VARIANT; + let full_nop_opcode = DecodedOpcode::<8, Self> { + variant, + condition: Condition::Always, + src0_reg_idx: 0, + src1_reg_idx: 0, + dst0_reg_idx: 0, + dst1_reg_idx: 0, + imm_0: Self::PcOrImm::from_u64_clipped(0), + imm_1: Self::PcOrImm::from_u64_clipped(0), + }; + + full_nop_opcode.serialize_as_integer() + } + + fn exception_revert_encoding() -> Self::IntegerRepresentation { + // ret.panic r0 + let variant = *PANIC_OPCODE_VARIANT; + let full_nop_opcode = DecodedOpcode::<8, Self> { + variant, + condition: Condition::Always, + src0_reg_idx: 0, + src1_reg_idx: 0, + dst0_reg_idx: 0, + dst1_reg_idx: 0, + imm_0: Self::PcOrImm::from_u64_clipped(0), + imm_1: Self::PcOrImm::from_u64_clipped(0), + }; + + full_nop_opcode.serialize_as_integer() + } + + fn parse_preliminary_variant_and_absolute_number( + integer_representaiton: Self::IntegerRepresentation, + ) -> (DecodedOpcode<8, Self>, VariantMonotonicNumber) { + let raw_value = integer_representaiton; + let (variant, condition, variant_bits) = + Self::variant_and_condition_from_u64_word(raw_value); + + // decode purely as integer + let src_byte = (raw_value >> SRC_REGS_SHIFT) as u8; + let dst_byte = (raw_value >> DST_REGS_SHIFT) as u8; + + let imm_0 = (raw_value >> Self::IMM0_SHIFT) as u16; + let imm_1 = (raw_value >> Self::IMM1_SHIFT) as u16; + + let (src0_reg_idx, src1_reg_idx) = split_as_u4(src_byte); + let (dst0_reg_idx, dst1_reg_idx) = split_as_u4(dst_byte); + + let new = DecodedOpcode { + variant, + condition, + src0_reg_idx, + src1_reg_idx, + dst0_reg_idx, + dst1_reg_idx, + imm_0, + imm_1, + }; + + (new, VariantMonotonicNumber::from_usize(variant_bits)) + } + + fn encode_as_integer(opcode: &DecodedOpcode<8, Self>) -> Self::IntegerRepresentation { + // we have 11 bits of opcode, + // then 2 bit gap, + // then 3 bit conditional, + // then 4x4 register indexes + // then 2x8 immediates + + // our encoding is just an integer + + let mut encoding = 0u64; + + let variant_bits = if let Some(variant_bits) = crate::OPCODE_TO_CANONICAL_INDEX_LOOKUP_MAP + .get(&opcode.variant) + .copied() + { + variant_bits + } else { + panic!("Unknown variant {}", opcode.variant); + }; + assert!(variant_bits.next_power_of_two().trailing_zeros() as usize <= OPCODES_TABLE_WIDTH); + + encoding |= variant_bits as u64; + + // condition + let condition = opcode.condition.variant_index(); + assert!(condition.next_power_of_two().trailing_zeros() as usize <= CONDITIONAL_BITS_WIDTH); + encoding |= (condition as u64) << CONDITIONAL_BITS_SHIFT; + + // register indexes + let src_registers_byte = merge_u4(opcode.src0_reg_idx, opcode.src1_reg_idx); + encoding |= (src_registers_byte as u64) << SRC_REGS_SHIFT; + let dst_registers_byte = merge_u4(opcode.dst0_reg_idx, opcode.dst1_reg_idx); + encoding |= (dst_registers_byte as u64) << DST_REGS_SHIFT; + + encoding |= (opcode.imm_0 as u64) << Self::IMM0_SHIFT; + encoding |= (opcode.imm_1 as u64) << Self::IMM1_SHIFT; + + encoding + } + + fn encode_as_bytes(opcode: &DecodedOpcode<8, Self>) -> [u8; 8] { + Self::encode_as_integer(opcode).encode_as_bytes() + } + + fn split_pc(pc: Self::PcOrImm) -> (Self::PcOrImm, Self::PcOrImm) { + (pc >> 2, pc & 0b11) + } + + fn integer_representaiton_from_u256( + value: U256, + index: Self::PcOrImm, + ) -> Self::IntegerRepresentation { + match index { + 0 => value.0[3], + 1 => value.0[2], + 2 => value.0[1], + 3 => value.0[0], + _ => unreachable!(), + } + } + + fn is_canonical_encoding(value: Self::IntegerRepresentation) -> bool { + let unused_bits = value & Self::UNUSED_BITS_MASK; + + unused_bits == 0 + } +} diff --git a/crates/zkevm_opcode_defs/src/decoding/encoding_mode_testing.rs b/crates/zkevm_opcode_defs/src/decoding/encoding_mode_testing.rs new file mode 100644 index 0000000..4018320 --- /dev/null +++ b/crates/zkevm_opcode_defs/src/decoding/encoding_mode_testing.rs @@ -0,0 +1,174 @@ +use super::*; + +use crate::merge_u4; +use crate::split_as_u4; +use crate::Condition; +use crate::OpcodeVariant; +use crate::CONDITIONAL_BITS_SHIFT; +use crate::CONDITIONAL_BITS_WIDTH; +use crate::DST_REGS_SHIFT; +use crate::OPCODES_TABLE; +use crate::OPCODES_TABLE_WIDTH; +use crate::SRC_REGS_SHIFT; +use crate::{NOP_OPCODE_VARIANT, PANIC_OPCODE_VARIANT}; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub struct EncodingModeTesting; + +impl EncodingModeTesting { + const IMM0_SHIFT: u32 = 32; + const IMM1_SHIFT: u32 = 64; + const VARIANT_AND_CONDITION_BITS: usize = 16; + const VARIANT_MASK: u64 = (1u64 << OPCODES_TABLE_WIDTH) - 1; + const CONDITION_MASK: u64 = ((1u64 << CONDITIONAL_BITS_WIDTH) - 1) << CONDITIONAL_BITS_SHIFT; + const UNUSED_GAP_RAW_MASK: u128 = (1u128 + << (Self::VARIANT_AND_CONDITION_BITS - OPCODES_TABLE_WIDTH - CONDITIONAL_BITS_WIDTH)) + - 1; + const UNUSED_BITS_MASK: u128 = Self::UNUSED_GAP_RAW_MASK << OPCODES_TABLE_WIDTH; + + pub fn variant_and_condition_from_u128_word( + raw_value: u128, + ) -> (OpcodeVariant, Condition, usize) { + let raw_value = raw_value as u64; // upper part is not relevant here + let variant_bits = raw_value & Self::VARIANT_MASK; + let opcode_variant = OPCODES_TABLE[variant_bits as usize]; + let condition_bits = (raw_value & Self::CONDITION_MASK) >> CONDITIONAL_BITS_SHIFT; + let condition = Condition::materialize_variant(condition_bits as usize); + + (opcode_variant, condition, variant_bits as usize) + } +} + +impl VmEncodingMode<16> for EncodingModeTesting { + type PcOrImm = u32; + type IntegerRepresentation = u128; + + fn nop_encoding() -> Self::IntegerRepresentation { + let variant = *NOP_OPCODE_VARIANT; + let full_nop_opcode = DecodedOpcode::<16, Self> { + variant, + condition: Condition::Always, + src0_reg_idx: 0, + src1_reg_idx: 0, + dst0_reg_idx: 0, + dst1_reg_idx: 0, + imm_0: Self::PcOrImm::from_u64_clipped(0), + imm_1: Self::PcOrImm::from_u64_clipped(0), + }; + + full_nop_opcode.serialize_as_integer() + } + + fn exception_revert_encoding() -> Self::IntegerRepresentation { + // ret.panic r0 + let variant = *PANIC_OPCODE_VARIANT; + let full_nop_opcode = DecodedOpcode::<16, Self> { + variant, + condition: Condition::Always, + src0_reg_idx: 0, + src1_reg_idx: 0, + dst0_reg_idx: 0, + dst1_reg_idx: 0, + imm_0: Self::PcOrImm::from_u64_clipped(0), + imm_1: Self::PcOrImm::from_u64_clipped(0), + }; + + full_nop_opcode.serialize_as_integer() + } + + fn parse_preliminary_variant_and_absolute_number( + integer_representaiton: Self::IntegerRepresentation, + ) -> (DecodedOpcode<16, Self>, VariantMonotonicNumber) { + let raw_value = integer_representaiton; + let (variant, condition, variant_bits) = + Self::variant_and_condition_from_u128_word(raw_value); + + // decode purely as integer + let src_byte = (raw_value >> SRC_REGS_SHIFT) as u8; + let dst_byte = (raw_value >> DST_REGS_SHIFT) as u8; + + let imm_0 = (raw_value >> Self::IMM0_SHIFT) as u32; + let imm_1 = (raw_value >> Self::IMM1_SHIFT) as u32; + + let (src0_reg_idx, src1_reg_idx) = split_as_u4(src_byte); + let (dst0_reg_idx, dst1_reg_idx) = split_as_u4(dst_byte); + + let new = DecodedOpcode { + variant, + condition, + src0_reg_idx, + src1_reg_idx, + dst0_reg_idx, + dst1_reg_idx, + imm_0, + imm_1, + }; + + (new, VariantMonotonicNumber::from_usize(variant_bits)) + } + + fn encode_as_integer(opcode: &DecodedOpcode<16, Self>) -> Self::IntegerRepresentation { + // we have 11 bits of opcode, + // then 2 bit gap, + // then 3 bit conditional, + // then 4x4 register indexes + // then 2x8 immediates + + // our encoding is just an integer + + let mut encoding = 0u128; + + let variant_bits = if let Some(variant_bits) = crate::OPCODE_TO_CANONICAL_INDEX_LOOKUP_MAP + .get(&opcode.variant) + .copied() + { + variant_bits + } else { + panic!("Unknown variant {}", opcode.variant); + }; + assert!(variant_bits.next_power_of_two().trailing_zeros() as usize <= OPCODES_TABLE_WIDTH); + + encoding |= variant_bits as u128; + + // condition + let condition = opcode.condition.variant_index(); + assert!(condition.next_power_of_two().trailing_zeros() as usize <= CONDITIONAL_BITS_WIDTH); + encoding |= (condition as u128) << CONDITIONAL_BITS_SHIFT; + + // register indexes + let src_registers_byte = merge_u4(opcode.src0_reg_idx, opcode.src1_reg_idx); + encoding |= (src_registers_byte as u128) << SRC_REGS_SHIFT; + let dst_registers_byte = merge_u4(opcode.dst0_reg_idx, opcode.dst1_reg_idx); + encoding |= (dst_registers_byte as u128) << DST_REGS_SHIFT; + + encoding |= (opcode.imm_0 as u128) << Self::IMM0_SHIFT; + encoding |= (opcode.imm_1 as u128) << Self::IMM1_SHIFT; + + encoding + } + + fn encode_as_bytes(opcode: &DecodedOpcode<16, Self>) -> [u8; 16] { + Self::encode_as_integer(opcode).encode_as_bytes() + } + + fn split_pc(pc: Self::PcOrImm) -> (Self::PcOrImm, Self::PcOrImm) { + (pc >> 1, pc & 0b1) + } + + fn integer_representaiton_from_u256( + value: U256, + index: Self::PcOrImm, + ) -> Self::IntegerRepresentation { + match index { + 0 => value.0[2] as u128 + ((value.0[3] as u128) << 64), + 1 => value.0[0] as u128 + ((value.0[1] as u128) << 64), + _ => unreachable!(), + } + } + + fn is_canonical_encoding(value: Self::IntegerRepresentation) -> bool { + let unused_bits = value & Self::UNUSED_BITS_MASK; + + unused_bits == 0 + } +} diff --git a/crates/zkevm_opcode_defs/src/decoding/mod.rs b/crates/zkevm_opcode_defs/src/decoding/mod.rs new file mode 100644 index 0000000..dc81945 --- /dev/null +++ b/crates/zkevm_opcode_defs/src/decoding/mod.rs @@ -0,0 +1,126 @@ +use crate::DecodedOpcode; +use ethereum_types::U256; + +pub mod encoding_mode_production; +pub mod encoding_mode_testing; + +pub use self::encoding_mode_production::EncodingModeProduction; +pub use self::encoding_mode_testing::EncodingModeTesting; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub struct VariantMonotonicNumber(pub usize); + +impl VariantMonotonicNumber { + #[inline] + pub const fn from_usize(value: usize) -> Self { + Self(value) + } + + #[inline] + pub const fn into_usize(self) -> usize { + self.0 as usize + } +} + +pub trait AllowedIntegerRepresentation: + Clone + Copy + Send + Sync + PartialEq + Eq + Default + std::fmt::Debug + std::fmt::LowerHex +{ + fn encode_as_bytes(self) -> [u8; N]; +} + +impl AllowedIntegerRepresentation<16> for u128 { + fn encode_as_bytes(self) -> [u8; 16] { + self.to_be_bytes() + } +} + +impl AllowedIntegerRepresentation<8> for u64 { + fn encode_as_bytes(self) -> [u8; 8] { + self.to_be_bytes() + } +} + +pub trait AllowedPcOrImm: + Clone + Copy + Send + Sync + PartialEq + Eq + Default + std::fmt::Debug + std::fmt::LowerHex +{ + fn from_u64_clipped(value: u64) -> Self; + fn as_u64(self) -> u64; + fn wrapping_add(self, other: Self) -> Self; + fn wrapping_sub(self, other: Self) -> Self; + fn max() -> Self; +} + +impl AllowedPcOrImm for u16 { + #[inline] + fn from_u64_clipped(value: u64) -> Self { + value as Self + } + #[inline] + fn as_u64(self) -> u64 { + self as u64 + } + #[inline] + fn wrapping_add(self, other: Self) -> Self { + self.wrapping_add(other) + } + #[inline] + fn wrapping_sub(self, other: Self) -> Self { + self.wrapping_sub(other) + } + #[inline] + fn max() -> Self { + u16::MAX + } +} +impl AllowedPcOrImm for u32 { + #[inline] + fn from_u64_clipped(value: u64) -> Self { + value as Self + } + #[inline] + fn as_u64(self) -> u64 { + self as u64 + } + #[inline] + fn wrapping_add(self, other: Self) -> Self { + self.wrapping_add(other) + } + #[inline] + fn wrapping_sub(self, other: Self) -> Self { + self.wrapping_sub(other) + } + #[inline] + fn max() -> Self { + u32::MAX + } +} + +// Some abstraction over encoding mode +// to be able to parse integer representation, as well as memory words +pub trait VmEncodingMode: + Clone + Copy + Send + Sync + PartialEq + Eq + std::fmt::Debug +{ + type PcOrImm: AllowedPcOrImm; + type IntegerRepresentation: AllowedIntegerRepresentation; + + fn nop_encoding() -> Self::IntegerRepresentation; + fn exception_revert_encoding() -> Self::IntegerRepresentation; + + fn parse_preliminary_variant_and_absolute_number( + integer_representaiton: Self::IntegerRepresentation, + ) -> (DecodedOpcode, VariantMonotonicNumber); + + fn encode_as_integer(opcode: &DecodedOpcode) -> Self::IntegerRepresentation; + + fn encode_as_bytes(opcode: &DecodedOpcode) -> [u8; N]; + + fn split_pc(pc: Self::PcOrImm) -> (Self::PcOrImm, Self::PcOrImm); + + fn integer_representaiton_from_u256( + value: U256, + index: Self::PcOrImm, + ) -> Self::IntegerRepresentation; + + // there may be some unused bits, but we want canonicality + fn is_canonical_encoding(value: Self::IntegerRepresentation) -> bool; +} diff --git a/crates/zkevm_opcode_defs/src/definitions/abi/far_call.rs b/crates/zkevm_opcode_defs/src/definitions/abi/far_call.rs new file mode 100644 index 0000000..8406af4 --- /dev/null +++ b/crates/zkevm_opcode_defs/src/definitions/abi/far_call.rs @@ -0,0 +1,64 @@ +use super::*; + +pub const FAR_CALL_FORWARDING_MODE_BYTE_IDX: usize = 28; +pub const FAR_CALL_SHARD_ID_BYTE_IDX: usize = 29; +pub const FAR_CALL_CONSTRUCTOR_CALL_BYTE_IDX: usize = 30; +pub const FAR_CALL_SYSTEM_CALL_BYTE_IDX: usize = 31; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[repr(u8)] +pub enum FarCallForwardPageType { + UseHeap = 0, + ForwardFatPointer, + UseAuxHeap, +} + +impl FarCallForwardPageType { + pub const fn from_u8(value: u8) -> Self { + match value { + 0 => FarCallForwardPageType::UseHeap, + 1 => FarCallForwardPageType::ForwardFatPointer, + 2 => FarCallForwardPageType::UseAuxHeap, + _ => FarCallForwardPageType::UseHeap, // default + } + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct FarCallABI { + pub memory_quasi_fat_pointer: FatPointer, + pub ergs_passed: u32, + pub shard_id: u8, + pub forwarding_mode: FarCallForwardPageType, + pub constructor_call: bool, + pub to_system: bool, +} + +impl FarCallABI { + pub const fn from_u256(raw_value: U256) -> Self { + let quasi_fat_pointer = FatPointer::from_u256(raw_value); + + let raw = raw_value.0; + + let extra_data = raw[3]; + let ergs_passed = extra_data as u32; + + let extra_data = (extra_data >> 32) as u32; + + let [forwarding_byte, shard_id, constructor_call_byte, to_system_byte] = + extra_data.to_le_bytes(); + + let page_forwarding_mode = FarCallForwardPageType::from_u8(forwarding_byte); + let constructor_call = constructor_call_byte != 0; + let to_system = to_system_byte != 0; + + Self { + memory_quasi_fat_pointer: quasi_fat_pointer, + ergs_passed, + shard_id, + forwarding_mode: page_forwarding_mode, + constructor_call, + to_system, + } + } +} diff --git a/crates/zkevm_opcode_defs/src/definitions/abi/fat_pointer.rs b/crates/zkevm_opcode_defs/src/definitions/abi/fat_pointer.rs new file mode 100644 index 0000000..fb3b590 --- /dev/null +++ b/crates/zkevm_opcode_defs/src/definitions/abi/fat_pointer.rs @@ -0,0 +1,89 @@ +use super::*; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct FatPointer { + pub offset: u32, // offset relative to `start` + pub memory_page: u32, // memory page where slice is located + pub start: u32, // absolute start of the slice + pub length: u32, // length of the slice +} + +bitflags::bitflags! { + pub struct FatPointerValidationException: u64 { + const OFFSET_IS_NOT_ZERO_WHEN_EXPECTED = 1u64 << 0; + const DEREF_BEYOND_HEAP_RANGE = 1u64 << 1; + } +} + +impl FatPointer { + pub const FAT_POINTER_PACKED_WIDTH: u32 = 128; + + // formally empty, for internal uses mainly + pub const fn empty() -> Self { + Self { + length: 0, + start: 0, + memory_page: 0, + offset: 0, + } + } + + pub const fn from_u256(value: U256) -> Self { + let raw_value = value.0; + let offset = raw_value[0] as u32; + let memory_page = (raw_value[0] >> 32) as u32; + + let start = raw_value[1] as u32; + let length = (raw_value[1] >> 32) as u32; + + Self { + offset, + memory_page, + start, + length, + } + } + + pub fn validate(self, is_fresh: bool) -> FatPointerValidationException { + let mut exceptions = FatPointerValidationException::empty(); + + // we have 2 invariants: + // fresh one has `offset` == 0 + if is_fresh && self.offset != 0 { + exceptions.set( + FatPointerValidationException::OFFSET_IS_NOT_ZERO_WHEN_EXPECTED, + true, + ); + } + // start + length doesn't overflow + let (_, of) = self.start.overflowing_add(self.length); + if of { + exceptions.set(FatPointerValidationException::DEREF_BEYOND_HEAP_RANGE, true); + } + + exceptions + } + + /// IMPORTANT: when we create a pointer in VM using checked routine + /// we know that `start` and `length` form a good combination in terms of no overflows + /// and spanning only addressable region, so we only need to check that `offset` < `length` + pub const fn validate_in_bounds(&self) -> bool { + let in_bounds = self.offset < self.length; + + in_bounds + } + + /// special case when we supply empty slice, that is formally NOT addressable + pub const fn is_trivial(&self) -> bool { + self.length == 0 && self.offset == 0 + } + + pub const fn to_u256(self) -> U256 { + let mut result = U256::zero(); + result.0[0] = (self.offset as u64) | ((self.memory_page as u64) << 32); + + result.0[1] = (self.start as u64) | ((self.length as u64) << 32); + + result + } +} diff --git a/crates/zkevm_opcode_defs/src/definitions/abi/meta.rs b/crates/zkevm_opcode_defs/src/definitions/abi/meta.rs new file mode 100644 index 0000000..35505ae --- /dev/null +++ b/crates/zkevm_opcode_defs/src/definitions/abi/meta.rs @@ -0,0 +1,26 @@ +use super::*; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct VmMetaParameters { + pub ergs_per_pubdata_byte: u32, + pub heap_size: u32, + pub aux_heap_size: u32, + pub this_shard_id: u8, + pub caller_shard_id: u8, + pub code_shard_id: u8, +} + +impl VmMetaParameters { + pub const fn to_u256(self) -> U256 { + let mut result = U256::zero(); + result.0[0] = self.ergs_per_pubdata_byte as u64; + result.0[1] = (self.heap_size as u64) | ((self.aux_heap_size as u64) << 32); + + let tmp = (self.this_shard_id as u64) + | ((self.caller_shard_id as u64) << 8) + | ((self.code_shard_id as u64) << 16); + result.0[3] = tmp << 32; + + result + } +} diff --git a/crates/zkevm_opcode_defs/src/definitions/abi/mod.rs b/crates/zkevm_opcode_defs/src/definitions/abi/mod.rs new file mode 100644 index 0000000..f099f03 --- /dev/null +++ b/crates/zkevm_opcode_defs/src/definitions/abi/mod.rs @@ -0,0 +1,17 @@ +use super::*; + +use ethereum_types::U256; + +pub mod far_call; +pub mod fat_pointer; +pub mod meta; +pub mod near_call; +pub mod precompile_call; +pub mod ret; + +pub use self::far_call::*; +pub use self::fat_pointer::*; +pub use self::meta::*; +pub use self::near_call::*; +pub use self::precompile_call::*; +pub use self::ret::*; diff --git a/crates/zkevm_opcode_defs/src/definitions/abi/near_call.rs b/crates/zkevm_opcode_defs/src/definitions/abi/near_call.rs new file mode 100644 index 0000000..d0f5576 --- /dev/null +++ b/crates/zkevm_opcode_defs/src/definitions/abi/near_call.rs @@ -0,0 +1,15 @@ +use super::*; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct NearCallABI { + pub ergs_passed: u32, +} + +impl NearCallABI { + pub const fn from_u256(raw_value: U256) -> Self { + let raw = raw_value.0; + let ergs_passed = raw[0] as u32; + + Self { ergs_passed } + } +} diff --git a/crates/zkevm_opcode_defs/src/definitions/abi/precompile_call.rs b/crates/zkevm_opcode_defs/src/definitions/abi/precompile_call.rs new file mode 100644 index 0000000..9d62111 --- /dev/null +++ b/crates/zkevm_opcode_defs/src/definitions/abi/precompile_call.rs @@ -0,0 +1,77 @@ +use super::*; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct PrecompileCallABI { + pub input_memory_offset: u32, + pub input_memory_length: u32, + pub output_memory_offset: u32, + pub output_memory_length: u32, + pub per_precompile_interpreted: u64, +} + +impl PrecompileCallABI { + pub const fn from_u256(raw_value: U256) -> Self { + let raw = raw_value.0; + let input_memory_offset = raw[0] as u32; + let input_memory_length = (raw[0] >> 32) as u32; + + let output_memory_offset = raw[1] as u32; + let output_memory_length = (raw[1] >> 32) as u32; + + let per_precompile_interpreted = raw[3]; + + Self { + input_memory_offset, + input_memory_length, + output_memory_offset, + output_memory_length, + per_precompile_interpreted, + } + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct PrecompileCallInnerABI { + pub input_memory_offset: u32, + pub input_memory_length: u32, + pub output_memory_offset: u32, + pub output_memory_length: u32, + pub memory_page_to_read: u32, + pub memory_page_to_write: u32, + pub precompile_interpreted_data: u64, +} + +impl PrecompileCallInnerABI { + pub const fn from_u256(raw_value: U256) -> Self { + let raw = raw_value.0; + let input_memory_offset = raw[0] as u32; + let input_memory_length = (raw[0] >> 32) as u32; + let output_memory_offset = raw[1] as u32; + let output_memory_length = (raw[1] >> 32) as u32; + let memory_page_to_read = raw[2] as u32; + let memory_page_to_write = (raw[2] >> 32) as u32; + let precompile_interpreted_data = raw[3]; + + Self { + input_memory_offset, + input_memory_length, + output_memory_offset, + output_memory_length, + memory_page_to_read, + memory_page_to_write, + precompile_interpreted_data, + } + } + + pub const fn to_u256(self) -> U256 { + let mut result = U256::zero(); + result.0[0] = (self.input_memory_offset as u64) | ((self.input_memory_length as u64) << 32); + result.0[1] = + (self.output_memory_offset as u64) | ((self.output_memory_length as u64) << 32); + result.0[2] = + (self.memory_page_to_read as u64) | ((self.memory_page_to_write as u64) << 32); + result.0[3] = self.precompile_interpreted_data; + + result + } +} diff --git a/crates/zkevm_opcode_defs/src/definitions/abi/ret.rs b/crates/zkevm_opcode_defs/src/definitions/abi/ret.rs new file mode 100644 index 0000000..b1d2e06 --- /dev/null +++ b/crates/zkevm_opcode_defs/src/definitions/abi/ret.rs @@ -0,0 +1,51 @@ +use super::*; + +pub const RET_FORWARDING_MODE_BYTE_IDX: usize = 28; + +const _: () = if RET_FORWARDING_MODE_BYTE_IDX != super::far_call::FAR_CALL_FORWARDING_MODE_BYTE_IDX +{ + panic!() +} else { +}; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[repr(u8)] +pub enum RetForwardPageType { + UseHeap = 0, + ForwardFatPointer, + UseAuxHeap, +} + +impl RetForwardPageType { + pub const fn from_u8(value: u8) -> Self { + // use inline consts when stable + match value { + 0 => RetForwardPageType::UseHeap, + 1 => RetForwardPageType::ForwardFatPointer, + 2 => RetForwardPageType::UseAuxHeap, + _ => RetForwardPageType::UseHeap, // default + } + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct RetABI { + pub memory_quasi_fat_pointer: FatPointer, + pub page_forwarding_mode: RetForwardPageType, +} + +impl RetABI { + pub const fn from_u256(raw_value: U256) -> Self { + let quasi_fat_pointer = FatPointer::from_u256(raw_value); + + let raw = raw_value.0; + let extra_data = (raw[3] >> 32) as u32; + let [forwarding_byte, _, _, _] = extra_data.to_le_bytes(); + let page_forwarding_mode = RetForwardPageType::from_u8(forwarding_byte); + + Self { + memory_quasi_fat_pointer: quasi_fat_pointer, + page_forwarding_mode, + } + } +} diff --git a/crates/zkevm_opcode_defs/src/definitions/add.rs b/crates/zkevm_opcode_defs/src/definitions/add.rs new file mode 100644 index 0000000..c307330 --- /dev/null +++ b/crates/zkevm_opcode_defs/src/definitions/add.rs @@ -0,0 +1,71 @@ +use super::*; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[repr(u8)] +pub enum AddOpcode { + Add = 0, +} + +impl OpcodeVariantProps for AddOpcode { + fn all_variants() -> Vec { + vec![AddOpcode::Add] + } + + fn max_variant_idx_for_version(_version: ISAVersion) -> usize { + AddOpcode::Add.variant_index() + } + + fn minimal_version(&self) -> ISAVersion { + ALL_ISA_VERSIONS[0] + } + + fn variant_index(&self) -> usize { + (*self as u8) as usize + } + + fn from_variant_index_for_version(index: usize, _version: &ISAVersion) -> Option { + match index { + i if i == AddOpcode::Add.variant_index() => Some(AddOpcode::Add), + _ => None, + } + } + + fn ergs_price(&self) -> u32 { + RICH_ADDRESSING_OPCODE_ERGS + } +} + +impl OpcodeProps for AddOpcode { + fn name(&self) -> &'static str { + "Add opcode" + } + fn variants_data(&self, version: ISAVersion) -> Vec { + match version { + ISAVersion(0) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 1, 2) + } + ISAVersion(1) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 1, 2) + } + _ => unimplemented!(), + } + } + fn max_variant_idx(&self, _version: ISAVersion) -> usize { + AddOpcode::Add.variant_index() + } + fn input_operands(&self, _version: ISAVersion) -> Vec { + vec![ + Operand::Full(ImmMemHandlerFlags::UseRegOnly), + Operand::RegOnly, + ] + } + fn output_operands(&self, _version: ISAVersion) -> Vec { + vec![Operand::Full(ImmMemHandlerFlags::UseRegOnly)] + } + fn requires_kernel_mode(&self) -> bool { + false + } + fn can_be_used_in_static_context(&self) -> bool { + true + } +} diff --git a/crates/zkevm_opcode_defs/src/definitions/all.rs b/crates/zkevm_opcode_defs/src/definitions/all.rs new file mode 100644 index 0000000..bde4025 --- /dev/null +++ b/crates/zkevm_opcode_defs/src/definitions/all.rs @@ -0,0 +1,271 @@ +use super::*; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub enum Opcode { + Invalid(InvalidOpcode), + Nop(NopOpcode), + Add(AddOpcode), + Sub(SubOpcode), + Mul(MulOpcode), + Div(DivOpcode), + Jump(JumpOpcode), + Context(ContextOpcode), + Shift(ShiftOpcode), + Binop(BinopOpcode), + Ptr(PtrOpcode), + NearCall(NearCallOpcode), + Log(LogOpcode), + FarCall(FarCallOpcode), + Ret(RetOpcode), + UMA(UMAOpcode), +} + +impl Opcode { + pub fn ergs_price(&self) -> u32 { + match self { + Opcode::Invalid(inner) => inner.ergs_price(), + Opcode::Nop(inner) => inner.ergs_price(), + Opcode::Add(inner) => inner.ergs_price(), + Opcode::Sub(inner) => inner.ergs_price(), + Opcode::Mul(inner) => inner.ergs_price(), + Opcode::Div(inner) => inner.ergs_price(), + Opcode::Jump(inner) => inner.ergs_price(), + Opcode::Context(inner) => inner.ergs_price(), + Opcode::Shift(inner) => inner.ergs_price(), + Opcode::Binop(inner) => inner.ergs_price(), + Opcode::Ptr(inner) => inner.ergs_price(), + Opcode::NearCall(inner) => inner.ergs_price(), + Opcode::Log(inner) => inner.ergs_price(), + Opcode::FarCall(inner) => inner.ergs_price(), + Opcode::Ret(inner) => inner.ergs_price(), + Opcode::UMA(inner) => inner.ergs_price(), + } + } + + pub fn materialize_subvariant_from_prototype(&self, idx: usize, version: &ISAVersion) -> Self { + match self { + Opcode::Invalid(_) => Opcode::Invalid( + InvalidOpcode::from_variant_index_for_version(idx, version) + .expect("must materialize"), + ), + Opcode::Nop(_) => Opcode::Nop( + NopOpcode::from_variant_index_for_version(idx, version).expect("must materialize"), + ), + Opcode::Add(_) => Opcode::Add( + AddOpcode::from_variant_index_for_version(idx, version).expect("must materialize"), + ), + Opcode::Sub(_) => Opcode::Sub( + SubOpcode::from_variant_index_for_version(idx, version).expect("must materialize"), + ), + Opcode::Mul(_) => Opcode::Mul( + MulOpcode::from_variant_index_for_version(idx, version).expect("must materialize"), + ), + Opcode::Div(_) => Opcode::Div( + DivOpcode::from_variant_index_for_version(idx, version).expect("must materialize"), + ), + Opcode::Jump(_) => Opcode::Jump( + JumpOpcode::from_variant_index_for_version(idx, version).expect("must materialize"), + ), + Opcode::Context(_) => Opcode::Context( + ContextOpcode::from_variant_index_for_version(idx, version) + .expect("must materialize"), + ), + Opcode::Shift(_) => Opcode::Shift( + ShiftOpcode::from_variant_index_for_version(idx, version) + .expect("must materialize"), + ), + Opcode::Binop(_) => Opcode::Binop( + BinopOpcode::from_variant_index_for_version(idx, version) + .expect("must materialize"), + ), + Opcode::Ptr(_) => Opcode::Ptr( + PtrOpcode::from_variant_index_for_version(idx, version).expect("must materialize"), + ), + Opcode::NearCall(_) => Opcode::NearCall( + NearCallOpcode::from_variant_index_for_version(idx, version) + .expect("must materialize"), + ), + Opcode::Log(_) => Opcode::Log( + LogOpcode::from_variant_index_for_version(idx, version).expect("must materialize"), + ), + Opcode::FarCall(_) => Opcode::FarCall( + FarCallOpcode::from_variant_index_for_version(idx, version) + .expect("must materialize"), + ), + Opcode::Ret(_) => Opcode::Ret( + RetOpcode::from_variant_index_for_version(idx, version).expect("must materialize"), + ), + Opcode::UMA(_) => Opcode::UMA( + UMAOpcode::from_variant_index_for_version(idx, version).expect("must materialize"), + ), + } + } + + pub const fn variant_idx(&self) -> usize { + match self { + Opcode::Invalid(_) => 0, + Opcode::Nop(_) => 1, + Opcode::Add(_) => 2, + Opcode::Sub(_) => 3, + Opcode::Mul(_) => 4, + Opcode::Div(_) => 5, + Opcode::Jump(_) => 6, + Opcode::Context(_) => 7, + Opcode::Shift(_) => 8, + Opcode::Binop(_) => 9, + Opcode::Ptr(_) => 10, + Opcode::NearCall(_) => 11, + Opcode::Log(_) => 12, + Opcode::FarCall(_) => 13, + Opcode::Ret(_) => 14, + Opcode::UMA(_) => 15, + } + } + + pub fn materialize_subvariant_idx(&self) -> usize { + match self { + Opcode::Invalid(sub) => sub.variant_index(), + Opcode::Nop(sub) => sub.variant_index(), + Opcode::Add(sub) => sub.variant_index(), + Opcode::Sub(sub) => sub.variant_index(), + Opcode::Mul(sub) => sub.variant_index(), + Opcode::Div(sub) => sub.variant_index(), + Opcode::Jump(sub) => sub.variant_index(), + Opcode::Context(sub) => sub.variant_index(), + Opcode::Shift(sub) => sub.variant_index(), + Opcode::Binop(sub) => sub.variant_index(), + Opcode::Ptr(sub) => sub.variant_index(), + Opcode::NearCall(sub) => sub.variant_index(), + Opcode::Log(sub) => sub.variant_index(), + Opcode::FarCall(sub) => sub.variant_index(), + Opcode::Ret(sub) => sub.variant_index(), + Opcode::UMA(sub) => sub.variant_index(), + } + } + + pub fn requires_kernel_mode(&self) -> bool { + match self { + Opcode::Invalid(sub) => sub.requires_kernel_mode(), + Opcode::Nop(sub) => sub.requires_kernel_mode(), + Opcode::Add(sub) => sub.requires_kernel_mode(), + Opcode::Sub(sub) => sub.requires_kernel_mode(), + Opcode::Mul(sub) => sub.requires_kernel_mode(), + Opcode::Div(sub) => sub.requires_kernel_mode(), + Opcode::Jump(sub) => sub.requires_kernel_mode(), + Opcode::Context(sub) => sub.requires_kernel_mode(), + Opcode::Shift(sub) => sub.requires_kernel_mode(), + Opcode::Binop(sub) => sub.requires_kernel_mode(), + Opcode::Ptr(sub) => sub.requires_kernel_mode(), + Opcode::NearCall(sub) => sub.requires_kernel_mode(), + Opcode::Log(sub) => sub.requires_kernel_mode(), + Opcode::FarCall(sub) => sub.requires_kernel_mode(), + Opcode::Ret(sub) => sub.requires_kernel_mode(), + Opcode::UMA(sub) => sub.requires_kernel_mode(), + } + } + + pub fn can_be_used_in_static_context(&self) -> bool { + match self { + Opcode::Invalid(sub) => sub.can_be_used_in_static_context(), + Opcode::Nop(sub) => sub.can_be_used_in_static_context(), + Opcode::Add(sub) => sub.can_be_used_in_static_context(), + Opcode::Sub(sub) => sub.can_be_used_in_static_context(), + Opcode::Mul(sub) => sub.can_be_used_in_static_context(), + Opcode::Div(sub) => sub.can_be_used_in_static_context(), + Opcode::Jump(sub) => sub.can_be_used_in_static_context(), + Opcode::Context(sub) => sub.can_be_used_in_static_context(), + Opcode::Shift(sub) => sub.can_be_used_in_static_context(), + Opcode::Binop(sub) => sub.can_be_used_in_static_context(), + Opcode::Ptr(sub) => sub.can_be_used_in_static_context(), + Opcode::NearCall(sub) => sub.can_be_used_in_static_context(), + Opcode::Log(sub) => sub.can_be_used_in_static_context(), + Opcode::FarCall(sub) => sub.can_be_used_in_static_context(), + Opcode::Ret(sub) => sub.can_be_used_in_static_context(), + Opcode::UMA(sub) => sub.can_be_used_in_static_context(), + } + } + + pub fn can_have_src0_from_mem(&self, version: ISAVersion) -> bool { + match self { + Opcode::Invalid(sub) => sub.can_have_src0_from_mem(version), + Opcode::Nop(sub) => sub.can_have_src0_from_mem(version), + Opcode::Add(sub) => sub.can_have_src0_from_mem(version), + Opcode::Sub(sub) => sub.can_have_src0_from_mem(version), + Opcode::Mul(sub) => sub.can_have_src0_from_mem(version), + Opcode::Div(sub) => sub.can_have_src0_from_mem(version), + Opcode::Jump(sub) => sub.can_have_src0_from_mem(version), + Opcode::Context(sub) => sub.can_have_src0_from_mem(version), + Opcode::Shift(sub) => sub.can_have_src0_from_mem(version), + Opcode::Binop(sub) => sub.can_have_src0_from_mem(version), + Opcode::Ptr(sub) => sub.can_have_src0_from_mem(version), + Opcode::NearCall(sub) => sub.can_have_src0_from_mem(version), + Opcode::Log(sub) => sub.can_have_src0_from_mem(version), + Opcode::FarCall(sub) => sub.can_have_src0_from_mem(version), + Opcode::Ret(sub) => sub.can_have_src0_from_mem(version), + Opcode::UMA(sub) => sub.can_have_src0_from_mem(version), + } + } + + pub fn can_write_dst0_into_memory(&self, version: ISAVersion) -> bool { + match self { + Opcode::Invalid(sub) => sub.can_write_dst0_into_memory(version), + Opcode::Nop(sub) => sub.can_write_dst0_into_memory(version), + Opcode::Add(sub) => sub.can_write_dst0_into_memory(version), + Opcode::Sub(sub) => sub.can_write_dst0_into_memory(version), + Opcode::Mul(sub) => sub.can_write_dst0_into_memory(version), + Opcode::Div(sub) => sub.can_write_dst0_into_memory(version), + Opcode::Jump(sub) => sub.can_write_dst0_into_memory(version), + Opcode::Context(sub) => sub.can_write_dst0_into_memory(version), + Opcode::Shift(sub) => sub.can_write_dst0_into_memory(version), + Opcode::Binop(sub) => sub.can_write_dst0_into_memory(version), + Opcode::Ptr(sub) => sub.can_write_dst0_into_memory(version), + Opcode::NearCall(sub) => sub.can_write_dst0_into_memory(version), + Opcode::Log(sub) => sub.can_write_dst0_into_memory(version), + Opcode::FarCall(sub) => sub.can_write_dst0_into_memory(version), + Opcode::Ret(sub) => sub.can_write_dst0_into_memory(version), + Opcode::UMA(sub) => sub.can_write_dst0_into_memory(version), + } + } + + pub fn input_operands(&self, version: ISAVersion) -> Vec { + match self { + Opcode::Invalid(sub) => sub.input_operands(version), + Opcode::Nop(sub) => sub.input_operands(version), + Opcode::Add(sub) => sub.input_operands(version), + Opcode::Sub(sub) => sub.input_operands(version), + Opcode::Mul(sub) => sub.input_operands(version), + Opcode::Div(sub) => sub.input_operands(version), + Opcode::Jump(sub) => sub.input_operands(version), + Opcode::Context(sub) => sub.input_operands(version), + Opcode::Shift(sub) => sub.input_operands(version), + Opcode::Binop(sub) => sub.input_operands(version), + Opcode::Ptr(sub) => sub.input_operands(version), + Opcode::NearCall(sub) => sub.input_operands(version), + Opcode::Log(sub) => sub.input_operands(version), + Opcode::FarCall(sub) => sub.input_operands(version), + Opcode::Ret(sub) => sub.input_operands(version), + Opcode::UMA(sub) => sub.input_operands(version), + } + } + + pub fn output_operands(&self, version: ISAVersion) -> Vec { + match self { + Opcode::Invalid(sub) => sub.output_operands(version), + Opcode::Nop(sub) => sub.output_operands(version), + Opcode::Add(sub) => sub.output_operands(version), + Opcode::Sub(sub) => sub.output_operands(version), + Opcode::Mul(sub) => sub.output_operands(version), + Opcode::Div(sub) => sub.output_operands(version), + Opcode::Jump(sub) => sub.output_operands(version), + Opcode::Context(sub) => sub.output_operands(version), + Opcode::Shift(sub) => sub.output_operands(version), + Opcode::Binop(sub) => sub.output_operands(version), + Opcode::Ptr(sub) => sub.output_operands(version), + Opcode::NearCall(sub) => sub.output_operands(version), + Opcode::Log(sub) => sub.output_operands(version), + Opcode::FarCall(sub) => sub.output_operands(version), + Opcode::Ret(sub) => sub.output_operands(version), + Opcode::UMA(sub) => sub.output_operands(version), + } + } +} diff --git a/crates/zkevm_opcode_defs/src/definitions/binop.rs b/crates/zkevm_opcode_defs/src/definitions/binop.rs new file mode 100644 index 0000000..76884eb --- /dev/null +++ b/crates/zkevm_opcode_defs/src/definitions/binop.rs @@ -0,0 +1,75 @@ +use super::*; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[repr(u8)] +pub enum BinopOpcode { + Xor = 0, + And, + Or, +} + +impl OpcodeVariantProps for BinopOpcode { + fn all_variants() -> Vec { + vec![BinopOpcode::Xor, BinopOpcode::And, BinopOpcode::Or] + } + + fn max_variant_idx_for_version(_version: ISAVersion) -> usize { + BinopOpcode::Or.variant_index() + } + + fn minimal_version(&self) -> ISAVersion { + ALL_ISA_VERSIONS[0] + } + + fn variant_index(&self) -> usize { + (*self as u8) as usize + } + + fn from_variant_index_for_version(index: usize, _version: &ISAVersion) -> Option { + match index { + i if i == BinopOpcode::Xor.variant_index() => Some(BinopOpcode::Xor), + i if i == BinopOpcode::And.variant_index() => Some(BinopOpcode::And), + i if i == BinopOpcode::Or.variant_index() => Some(BinopOpcode::Or), + _ => None, + } + } + + fn ergs_price(&self) -> u32 { + RICH_ADDRESSING_OPCODE_ERGS + } +} + +impl OpcodeProps for BinopOpcode { + fn name(&self) -> &'static str { + "Binop opcode" + } + fn variants_data(&self, version: ISAVersion) -> Vec { + match version { + ISAVersion(0) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 1, 2) + } + ISAVersion(1) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 1, 2) + } + _ => unimplemented!(), + } + } + fn max_variant_idx(&self, _version: ISAVersion) -> usize { + BinopOpcode::Or.variant_index() + } + fn input_operands(&self, _version: ISAVersion) -> Vec { + vec![ + Operand::Full(ImmMemHandlerFlags::UseRegOnly), + Operand::RegOnly, + ] + } + fn output_operands(&self, _version: ISAVersion) -> Vec { + vec![Operand::Full(ImmMemHandlerFlags::UseRegOnly)] + } + fn requires_kernel_mode(&self) -> bool { + false + } + fn can_be_used_in_static_context(&self) -> bool { + true + } +} diff --git a/crates/zkevm_opcode_defs/src/definitions/condition.rs b/crates/zkevm_opcode_defs/src/definitions/condition.rs new file mode 100644 index 0000000..16f8685 --- /dev/null +++ b/crates/zkevm_opcode_defs/src/definitions/condition.rs @@ -0,0 +1,58 @@ +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[repr(u8)] +pub enum Condition { + Always = 0, + Gt, + Lt, + Eq, + Ge, + Le, + Ne, + GtOrLt, +} + +pub const CONDITIONAL_BITS_WIDTH: usize = 3; + +impl Condition { + const NUM_VARIANTS: usize = 8; + + pub fn materialize_variant(idx: usize) -> Self { + assert!(idx < Self::NUM_VARIANTS); + + match idx { + 0 => Condition::Always, + 1 => Condition::Gt, + 2 => Condition::Lt, + 3 => Condition::Eq, + 4 => Condition::Ge, + 5 => Condition::Le, + 6 => Condition::Ne, + 7 => Condition::GtOrLt, + _ => panic!("unknown variant"), + } + } + + pub const fn variant_index(&self) -> usize { + match self { + Condition::Always => 0, + Condition::Gt => 1, + Condition::Lt => 2, + Condition::Eq => 3, + Condition::Ge => 4, + Condition::Le => 5, + Condition::Ne => 6, + Condition::GtOrLt => 7, + } + } +} + +pub const ALL_CONDITIONS: [Condition; 1 << CONDITIONAL_BITS_WIDTH] = [ + Condition::Always, + Condition::Gt, + Condition::Lt, + Condition::Eq, + Condition::Ge, + Condition::Le, + Condition::Ne, + Condition::GtOrLt, +]; diff --git a/crates/zkevm_opcode_defs/src/definitions/context.rs b/crates/zkevm_opcode_defs/src/definitions/context.rs new file mode 100644 index 0000000..760e79d --- /dev/null +++ b/crates/zkevm_opcode_defs/src/definitions/context.rs @@ -0,0 +1,127 @@ +use super::*; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[repr(u8)] +pub enum ContextOpcode { + This = 0, + Caller, + CodeAddress, + Meta, + ErgsLeft, + Sp, + GetContextU128, + SetContextU128, + SetErgsPerPubdataByte, + IncrementTxNumber, +} + +impl OpcodeVariantProps for ContextOpcode { + fn all_variants() -> Vec { + vec![ + ContextOpcode::This, + ContextOpcode::Caller, + ContextOpcode::CodeAddress, + ContextOpcode::Meta, + ContextOpcode::ErgsLeft, + ContextOpcode::Sp, + ContextOpcode::GetContextU128, + ContextOpcode::SetContextU128, + ContextOpcode::SetErgsPerPubdataByte, + ContextOpcode::IncrementTxNumber, + ] + } + + fn max_variant_idx_for_version(_version: ISAVersion) -> usize { + ContextOpcode::IncrementTxNumber.variant_index() + } + + fn minimal_version(&self) -> ISAVersion { + ALL_ISA_VERSIONS[0] + } + + fn variant_index(&self) -> usize { + (*self as u8) as usize + } + + fn from_variant_index_for_version(index: usize, _version: &ISAVersion) -> Option { + match index { + i if i == ContextOpcode::This.variant_index() => Some(ContextOpcode::This), + i if i == ContextOpcode::Caller.variant_index() => Some(ContextOpcode::Caller), + i if i == ContextOpcode::CodeAddress.variant_index() => { + Some(ContextOpcode::CodeAddress) + } + i if i == ContextOpcode::Meta.variant_index() => Some(ContextOpcode::Meta), + i if i == ContextOpcode::ErgsLeft.variant_index() => Some(ContextOpcode::ErgsLeft), + i if i == ContextOpcode::Sp.variant_index() => Some(ContextOpcode::Sp), + i if i == ContextOpcode::GetContextU128.variant_index() => { + Some(ContextOpcode::GetContextU128) + } + i if i == ContextOpcode::SetContextU128.variant_index() => { + Some(ContextOpcode::SetContextU128) + } + i if i == ContextOpcode::SetErgsPerPubdataByte.variant_index() => { + Some(ContextOpcode::SetErgsPerPubdataByte) + } + i if i == ContextOpcode::IncrementTxNumber.variant_index() => { + Some(ContextOpcode::IncrementTxNumber) + } + _ => None, + } + } + + fn ergs_price(&self) -> u32 { + AVERAGE_OPCODE_ERGS + } +} + +impl OpcodeProps for ContextOpcode { + fn name(&self) -> &'static str { + "Context opcode" + } + fn variants_data(&self, version: ISAVersion) -> Vec { + match version { + ISAVersion(0) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 0, 0) + } + ISAVersion(1) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 0, 0) + } + _ => unimplemented!(), + } + } + fn max_variant_idx(&self, _version: ISAVersion) -> usize { + ContextOpcode::IncrementTxNumber.variant_index() + } + fn input_operands(&self, _version: ISAVersion) -> Vec { + match self { + ContextOpcode::SetContextU128 | ContextOpcode::SetErgsPerPubdataByte => { + vec![Operand::RegOnly] + } + _ => vec![], + } + } + fn output_operands(&self, _version: ISAVersion) -> Vec { + match self { + ContextOpcode::SetContextU128 + | ContextOpcode::SetErgsPerPubdataByte + | ContextOpcode::IncrementTxNumber => vec![], + _ => vec![Operand::RegOnly], + } + } + fn requires_kernel_mode(&self) -> bool { + match self { + ContextOpcode::SetContextU128 + | ContextOpcode::SetErgsPerPubdataByte + | ContextOpcode::IncrementTxNumber => true, + _ => false, + } + } + fn can_be_used_in_static_context(&self) -> bool { + match self { + ContextOpcode::SetContextU128 + | ContextOpcode::SetErgsPerPubdataByte + | ContextOpcode::IncrementTxNumber => false, + _ => true, + } + } +} diff --git a/crates/zkevm_opcode_defs/src/definitions/div.rs b/crates/zkevm_opcode_defs/src/definitions/div.rs new file mode 100644 index 0000000..156cd2b --- /dev/null +++ b/crates/zkevm_opcode_defs/src/definitions/div.rs @@ -0,0 +1,71 @@ +use super::*; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct DivOpcode; + +impl OpcodeVariantProps for DivOpcode { + fn all_variants() -> Vec { + vec![DivOpcode] + } + + fn max_variant_idx_for_version(_version: ISAVersion) -> usize { + DivOpcode.variant_index() + } + + fn minimal_version(&self) -> ISAVersion { + ALL_ISA_VERSIONS[0] + } + + fn variant_index(&self) -> usize { + 0 + } + + fn from_variant_index_for_version(index: usize, _version: &ISAVersion) -> Option { + match index { + 0 => Some(DivOpcode), + _ => None, + } + } + + fn ergs_price(&self) -> u32 { + RICH_ADDRESSING_OPCODE_ERGS + } +} + +impl OpcodeProps for DivOpcode { + fn name(&self) -> &'static str { + "Div opcode" + } + fn variants_data(&self, version: ISAVersion) -> Vec { + match version { + ISAVersion(0) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 2, 2) + } + ISAVersion(1) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 2, 2) + } + _ => unimplemented!(), + } + } + fn max_variant_idx(&self, _version: ISAVersion) -> usize { + DivOpcode.variant_index() + } + fn input_operands(&self, _version: ISAVersion) -> Vec { + vec![ + Operand::Full(ImmMemHandlerFlags::UseRegOnly), + Operand::RegOnly, + ] + } + fn output_operands(&self, _version: ISAVersion) -> Vec { + vec![ + Operand::Full(ImmMemHandlerFlags::UseRegOnly), + Operand::RegOnly, + ] + } + fn requires_kernel_mode(&self) -> bool { + false + } + fn can_be_used_in_static_context(&self) -> bool { + true + } +} diff --git a/crates/zkevm_opcode_defs/src/definitions/far_call.rs b/crates/zkevm_opcode_defs/src/definitions/far_call.rs new file mode 100644 index 0000000..91c8bf2 --- /dev/null +++ b/crates/zkevm_opcode_defs/src/definitions/far_call.rs @@ -0,0 +1,100 @@ +use crate::circuit_prices::{ + CODE_DECOMMITMENT_SORTER_MIN_COST_IN_ERGS, RAM_PERMUTATION_COST_IN_ERGS, + STORAGE_SORTER_COST_IN_ERGS, VM_CYCLE_COST_IN_ERGS, +}; + +use super::*; + +// NOTE: registers are zero-enumerated +pub const CALL_IMPLICIT_CALLDATA_FAT_PTR_REGISTER: u8 = 0; +pub const CALL_IMPLICIT_CONSTRUCTOR_MARKER_REGISTER: u8 = 1; +pub const CALL_SYSTEM_ABI_REGISTERS: std::ops::Range = 2..12; +pub const CALL_RESERVED_RANGE: std::ops::Range = 12..14; +pub const CALL_IMPLICIT_PARAMETER_REG_IDX: u8 = 14; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[repr(u8)] +pub enum FarCallOpcode { + Normal = 0, + Delegate, + Mimic, +} + +pub const FAR_CALL_STATIC_FLAG_IDX: usize = 0; +pub const FAR_CALL_SHARD_FLAG_IDX: usize = 1; + +impl OpcodeVariantProps for FarCallOpcode { + fn all_variants() -> Vec { + vec![ + FarCallOpcode::Normal, + FarCallOpcode::Delegate, + FarCallOpcode::Mimic, + ] + } + + fn max_variant_idx_for_version(_version: ISAVersion) -> usize { + FarCallOpcode::Mimic.variant_index() + } + + fn minimal_version(&self) -> ISAVersion { + ALL_ISA_VERSIONS[0] + } + + fn variant_index(&self) -> usize { + (*self as u8) as usize + } + + fn from_variant_index_for_version(index: usize, _version: &ISAVersion) -> Option { + match index { + i if i == FarCallOpcode::Normal.variant_index() => Some(FarCallOpcode::Normal), + i if i == FarCallOpcode::Delegate.variant_index() => Some(FarCallOpcode::Delegate), + i if i == FarCallOpcode::Mimic.variant_index() => Some(FarCallOpcode::Mimic), + _ => None, + } + } + + fn ergs_price(&self) -> u32 { + let intrinsic = 2 * VM_CYCLE_COST_IN_ERGS + + RAM_PERMUTATION_COST_IN_ERGS + + STORAGE_READ_IO_PRICE + + CALL_LIKE_ERGS_COST + + STORAGE_SORTER_COST_IN_ERGS; + + std::cmp::max(intrinsic, CODE_DECOMMITMENT_SORTER_MIN_COST_IN_ERGS) + } +} + +impl OpcodeProps for FarCallOpcode { + fn name(&self) -> &'static str { + "Far call opcode" + } + fn variants_data(&self, version: ISAVersion) -> Vec { + match version { + ISAVersion(0) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 2, 1) + } + ISAVersion(1) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 2, 1) + } + _ => unimplemented!(), + } + } + fn max_variant_idx(&self, _version: ISAVersion) -> usize { + FarCallOpcode::Mimic.variant_index() + } + fn input_operands(&self, _version: ISAVersion) -> Vec { + vec![Operand::RegOnly, Operand::RegOnly] + } + fn output_operands(&self, _version: ISAVersion) -> Vec { + vec![] + } + fn requires_kernel_mode(&self) -> bool { + match self { + FarCallOpcode::Mimic => true, + _ => false, + } + } + fn can_be_used_in_static_context(&self) -> bool { + true + } +} diff --git a/crates/zkevm_opcode_defs/src/definitions/invalid_opcode.rs b/crates/zkevm_opcode_defs/src/definitions/invalid_opcode.rs new file mode 100644 index 0000000..99c4481 --- /dev/null +++ b/crates/zkevm_opcode_defs/src/definitions/invalid_opcode.rs @@ -0,0 +1,65 @@ +use super::*; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct InvalidOpcode; + +impl OpcodeVariantProps for InvalidOpcode { + fn all_variants() -> Vec { + vec![InvalidOpcode] + } + + fn max_variant_idx_for_version(_version: ISAVersion) -> usize { + InvalidOpcode.variant_index() + } + + fn minimal_version(&self) -> ISAVersion { + ALL_ISA_VERSIONS[0] + } + + fn variant_index(&self) -> usize { + 0 + } + + fn from_variant_index_for_version(index: usize, _version: &ISAVersion) -> Option { + match index { + 0 => Some(InvalidOpcode), + _ => None, + } + } + + fn ergs_price(&self) -> u32 { + INVALID_OPCODE_ERGS + } +} + +impl OpcodeProps for InvalidOpcode { + fn name(&self) -> &'static str { + "Invalid opcode" + } + fn variants_data(&self, version: ISAVersion) -> Vec { + match version { + ISAVersion(0) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 0, 0) + } + ISAVersion(1) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 0, 0) + } + _ => unimplemented!(), + } + } + fn max_variant_idx(&self, _version: ISAVersion) -> usize { + InvalidOpcode.variant_index() + } + fn input_operands(&self, _version: ISAVersion) -> Vec { + vec![] + } + fn output_operands(&self, _version: ISAVersion) -> Vec { + vec![] + } + fn requires_kernel_mode(&self) -> bool { + false + } + fn can_be_used_in_static_context(&self) -> bool { + true + } +} diff --git a/crates/zkevm_opcode_defs/src/definitions/jump.rs b/crates/zkevm_opcode_defs/src/definitions/jump.rs new file mode 100644 index 0000000..5348766 --- /dev/null +++ b/crates/zkevm_opcode_defs/src/definitions/jump.rs @@ -0,0 +1,65 @@ +use super::*; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct JumpOpcode; + +impl OpcodeVariantProps for JumpOpcode { + fn all_variants() -> Vec { + vec![JumpOpcode] + } + + fn max_variant_idx_for_version(_version: ISAVersion) -> usize { + JumpOpcode.variant_index() + } + + fn minimal_version(&self) -> ISAVersion { + ALL_ISA_VERSIONS[0] + } + + fn variant_index(&self) -> usize { + 0 + } + + fn from_variant_index_for_version(index: usize, _version: &ISAVersion) -> Option { + match index { + 0 => Some(JumpOpcode), + _ => None, + } + } + + fn ergs_price(&self) -> u32 { + RICH_ADDRESSING_OPCODE_ERGS + } +} + +impl OpcodeProps for JumpOpcode { + fn name(&self) -> &'static str { + "Jump opcode" + } + fn variants_data(&self, version: ISAVersion) -> Vec { + match version { + ISAVersion(0) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 0, 1) + } + ISAVersion(1) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 0, 1) + } + _ => unimplemented!(), + } + } + fn max_variant_idx(&self, _version: ISAVersion) -> usize { + JumpOpcode.variant_index() + } + fn input_operands(&self, _version: ISAVersion) -> Vec { + vec![Operand::Full(ImmMemHandlerFlags::UseRegOnly)] + } + fn output_operands(&self, _version: ISAVersion) -> Vec { + vec![] + } + fn requires_kernel_mode(&self) -> bool { + false + } + fn can_be_used_in_static_context(&self) -> bool { + true + } +} diff --git a/crates/zkevm_opcode_defs/src/definitions/log.rs b/crates/zkevm_opcode_defs/src/definitions/log.rs new file mode 100644 index 0000000..4268b1b --- /dev/null +++ b/crates/zkevm_opcode_defs/src/definitions/log.rs @@ -0,0 +1,171 @@ +use crate::circuit_prices::{ + EVENTS_OR_L1_MESSAGES_SORTER_COST_IN_ERGS, L1_MESSAGE_MIN_COST_IN_ERGS, + LOG_DEMUXER_COST_IN_ERGS, RAM_PERMUTATION_COST_IN_ERGS, STORAGE_SORTER_COST_IN_ERGS, + STORAGE_WRITE_MIN_COST_IN_ERGS, VM_CYCLE_COST_IN_ERGS, +}; + +use super::*; + +pub const FIRST_MESSAGE_FLAG_IDX: usize = 0; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[repr(u8)] +pub enum LogOpcode { + StorageRead = 0, + StorageWrite, + ToL1Message, + Event, + PrecompileCall, +} + +impl OpcodeVariantProps for LogOpcode { + fn all_variants() -> Vec { + vec![ + LogOpcode::StorageRead, + LogOpcode::StorageWrite, + LogOpcode::ToL1Message, + LogOpcode::Event, + LogOpcode::PrecompileCall, + ] + } + + fn max_variant_idx_for_version(_version: ISAVersion) -> usize { + LogOpcode::PrecompileCall.variant_index() + } + + fn minimal_version(&self) -> ISAVersion { + ALL_ISA_VERSIONS[0] + } + + fn variant_index(&self) -> usize { + (*self as u8) as usize + } + + fn from_variant_index_for_version(index: usize, _version: &ISAVersion) -> Option { + match index { + i if i == LogOpcode::StorageRead.variant_index() => Some(LogOpcode::StorageRead), + i if i == LogOpcode::StorageWrite.variant_index() => Some(LogOpcode::StorageWrite), + i if i == LogOpcode::ToL1Message.variant_index() => Some(LogOpcode::ToL1Message), + i if i == LogOpcode::Event.variant_index() => Some(LogOpcode::Event), + i if i == LogOpcode::PrecompileCall.variant_index() => Some(LogOpcode::PrecompileCall), + _ => None, + } + } + + fn ergs_price(&self) -> u32 { + match self { + LogOpcode::StorageRead => { + STORAGE_READ_IO_PRICE + + VM_CYCLE_COST_IN_ERGS + + RAM_PERMUTATION_COST_IN_ERGS + + LOG_DEMUXER_COST_IN_ERGS + + STORAGE_SORTER_COST_IN_ERGS + } + // If the write was not initial, the user will be refunded + LogOpcode::StorageWrite => { + let intrinsic = STORAGE_WRITE_IO_PRICE + + 2 * VM_CYCLE_COST_IN_ERGS + + RAM_PERMUTATION_COST_IN_ERGS + + 2 * LOG_DEMUXER_COST_IN_ERGS + + 2 * STORAGE_SORTER_COST_IN_ERGS; + + std::cmp::max(intrinsic, STORAGE_WRITE_MIN_COST_IN_ERGS) + } + // Note, that the `L1_MESSAGE_MIN_COST_IN_ERGS` is only needed for DDoS protection + LogOpcode::ToL1Message => { + let intrinsic_cost = L1_MESSAGE_IO_PRICE + + 2 * VM_CYCLE_COST_IN_ERGS + + RAM_PERMUTATION_COST_IN_ERGS + + 2 * LOG_DEMUXER_COST_IN_ERGS + + 2 * EVENTS_OR_L1_MESSAGES_SORTER_COST_IN_ERGS; + std::cmp::max(intrinsic_cost, L1_MESSAGE_MIN_COST_IN_ERGS) + } + LogOpcode::Event => { + EVENT_IO_PRICE + + 2 * VM_CYCLE_COST_IN_ERGS + + RAM_PERMUTATION_COST_IN_ERGS + + 2 * LOG_DEMUXER_COST_IN_ERGS + + 2 * EVENTS_OR_L1_MESSAGES_SORTER_COST_IN_ERGS + } + LogOpcode::PrecompileCall => { + VM_CYCLE_COST_IN_ERGS + RAM_PERMUTATION_COST_IN_ERGS + LOG_DEMUXER_COST_IN_ERGS + } + } + } +} + +impl OpcodeProps for LogOpcode { + fn name(&self) -> &'static str { + "Log opcode" + } + fn variants_data(&self, version: ISAVersion) -> Vec { + match version { + ISAVersion(0) | ISAVersion(1) => { + vec![ + // Storage read + OpcodeVariantData { + variant_idx: LogOpcode::StorageRead.variant_index(), + num_non_exclusive_flags: 0, + num_used_immediates: 0, + }, + // Storage write + OpcodeVariantData { + variant_idx: LogOpcode::StorageWrite.variant_index(), + num_non_exclusive_flags: 0, + num_used_immediates: 0, + }, + // L1 message + OpcodeVariantData { + variant_idx: LogOpcode::ToL1Message.variant_index(), + num_non_exclusive_flags: 1, // can be "initial" + num_used_immediates: 0, + }, + // Event + OpcodeVariantData { + variant_idx: LogOpcode::Event.variant_index(), + num_non_exclusive_flags: 1, // can be initial + num_used_immediates: 0, + }, + // Precompile calls + OpcodeVariantData { + variant_idx: LogOpcode::PrecompileCall.variant_index(), + num_non_exclusive_flags: 0, + num_used_immediates: 0, + }, + ] + } + _ => unimplemented!(), + } + } + fn max_variant_idx(&self, _version: ISAVersion) -> usize { + LogOpcode::PrecompileCall.variant_index() + } + fn input_operands(&self, _version: ISAVersion) -> Vec { + match self { + LogOpcode::StorageWrite | LogOpcode::Event | LogOpcode::ToL1Message => { + vec![Operand::RegOnly, Operand::RegOnly] + } + LogOpcode::StorageRead => vec![Operand::RegOnly], + LogOpcode::PrecompileCall => vec![Operand::RegOnly], + } + } + fn output_operands(&self, _version: ISAVersion) -> Vec { + match self { + LogOpcode::StorageWrite | LogOpcode::Event | LogOpcode::ToL1Message => vec![], + LogOpcode::StorageRead => vec![Operand::RegOnly], + LogOpcode::PrecompileCall => vec![Operand::RegOnly], + } + } + fn requires_kernel_mode(&self) -> bool { + match self { + LogOpcode::Event | LogOpcode::ToL1Message | LogOpcode::PrecompileCall => true, + _ => false, + } + } + fn can_be_used_in_static_context(&self) -> bool { + match self { + LogOpcode::StorageWrite | LogOpcode::Event | LogOpcode::ToL1Message => false, + _ => true, + } + } +} diff --git a/crates/zkevm_opcode_defs/src/definitions/mod.rs b/crates/zkevm_opcode_defs/src/definitions/mod.rs new file mode 100644 index 0000000..bcb8041 --- /dev/null +++ b/crates/zkevm_opcode_defs/src/definitions/mod.rs @@ -0,0 +1,1041 @@ +use std::collections::HashSet; + +use crate::imm_mem_modifiers::*; + +use super::*; + +pub mod opcode_trait; +pub use self::opcode_trait::*; + +pub mod all; +pub mod condition; + +pub mod abi; + +pub mod add; +pub mod binop; +pub mod context; +pub mod div; +pub mod far_call; +pub mod invalid_opcode; +pub mod jump; +pub mod log; +pub mod mul; +pub mod near_call; +pub mod noop; +pub mod ptr; +pub mod ret; +pub mod shift; +pub mod sub; +pub mod uma; + +pub mod versioned_hash; + +pub use self::add::*; +pub use self::binop::*; +pub use self::context::*; +pub use self::div::*; +pub use self::far_call::*; +pub use self::invalid_opcode::*; +pub use self::jump::*; +pub use self::log::*; +pub use self::mul::*; +pub use self::near_call::*; +pub use self::noop::*; +pub use self::ptr::*; +pub use self::ret::*; +pub use self::shift::*; +pub use self::sub::*; +pub use self::uma::*; + +pub use self::abi::*; +pub use self::all::*; +pub use self::condition::*; + +pub use self::versioned_hash::*; + +pub const NUM_OPCODES: usize = 16; + +pub const INVALID_OPCODE_VARIANT: OpcodeVariant = OpcodeVariant { + opcode: Opcode::Invalid(InvalidOpcode), + src0_operand_type: Operand::RegOnly, + dst0_operand_type: Operand::RegOnly, + flags: [false; NUM_NON_EXCLUSIVE_FLAGS], +}; + +pub(crate) fn all_opcodes() -> Vec> { + let opcodes = vec![ + Box::new(InvalidOpcode) as Box, + Box::new(NopOpcode), + Box::new(AddOpcode::Add), + Box::new(SubOpcode::Sub), + Box::new(MulOpcode), + Box::new(DivOpcode), + Box::new(JumpOpcode), + Box::new(BinopOpcode::Xor), + Box::new(ShiftOpcode::Shl), + Box::new(PtrOpcode::Add), + Box::new(NearCallOpcode), + Box::new(ContextOpcode::This), + Box::new(LogOpcode::StorageRead), + Box::new(FarCallOpcode::Normal), + Box::new(RetOpcode::Ok), + Box::new(UMAOpcode::HeapRead), + ]; + + assert_eq!(opcodes.len(), NUM_OPCODES, "number of opcodes mismatch"); + assert_eq!( + opcodes[0].name(), + "Invalid opcode", + "first opcode should be invalid opcode" + ); + + opcodes +} + +pub fn all_opcode_prototypes() -> [Opcode; NUM_OPCODES] { + let opcodes = [ + Opcode::Invalid(InvalidOpcode), + Opcode::Nop(NopOpcode), + Opcode::Add(AddOpcode::Add), + Opcode::Sub(SubOpcode::Sub), + Opcode::Mul(MulOpcode), + Opcode::Div(DivOpcode), + Opcode::Jump(JumpOpcode), + Opcode::Binop(BinopOpcode::Xor), + Opcode::Shift(ShiftOpcode::Shl), + Opcode::Ptr(PtrOpcode::Add), + Opcode::NearCall(NearCallOpcode), + Opcode::Context(ContextOpcode::This), + Opcode::Log(LogOpcode::StorageRead), + Opcode::FarCall(FarCallOpcode::Normal), + Opcode::Ret(RetOpcode::Ok), + Opcode::UMA(UMAOpcode::HeapRead), + ]; + + opcodes +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct OpcodeVariant { + pub opcode: Opcode, + pub src0_operand_type: Operand, + pub dst0_operand_type: Operand, + pub flags: [bool; NUM_NON_EXCLUSIVE_FLAGS], +} + +pub const SET_FLAGS_FLAG_IDX: usize = 0; +pub const SWAP_OPERANDS_FLAG_IDX_FOR_ARITH_OPCODES: usize = 1; +pub const SWAP_OPERANDS_FLAG_IDX_FOR_PTR_OPCODE: usize = 0; + +impl OpcodeVariant { + pub fn ergs_price(&self) -> u32 { + self.opcode.ergs_price() + } + + pub const fn swap_operands(&self) -> bool { + match self.opcode { + Opcode::Sub(_) | Opcode::Div(_) | Opcode::Shift(_) => { + self.flags[SWAP_OPERANDS_FLAG_IDX_FOR_ARITH_OPCODES] + } + Opcode::Ptr(_) => self.flags[SWAP_OPERANDS_FLAG_IDX_FOR_PTR_OPCODE], + _ => false, + } + } + + pub fn requires_kernel_mode(&self) -> bool { + self.opcode.requires_kernel_mode() + } + + pub fn can_be_used_in_static_context(&self) -> bool { + self.opcode.can_be_used_in_static_context() + } + + // At the moment "invalid" opcode burns all the ergs, + // but then nevertheless is masked into "ret.panic r0". + // This is an implementation detail and may change in the future + pub fn is_explicit_panic(&self) -> bool { + match &self.opcode { + Opcode::Invalid(_) => true, + _ => false, + } + } +} + +impl std::default::Default for OpcodeVariant { + fn default() -> Self { + OpcodeVariant { + opcode: Opcode::Nop(NopOpcode), + src0_operand_type: Operand::RegOnly, + dst0_operand_type: Operand::RegOnly, + flags: [false; NUM_NON_EXCLUSIVE_FLAGS], + } + } +} + +impl std::fmt::Display for OpcodeVariant { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + writeln!(f, "Opcode and variant: {:?}", self.opcode)?; + writeln!(f, "Src0 operand type: {:?}", self.src0_operand_type)?; + writeln!(f, "Dst0 operand type: {:?}", self.dst0_operand_type)?; + write!( + f, + "Non-exclusive flags: {:#01}|{:#01}", + self.flags[0], self.flags[1], + ) + } +} + +pub fn synthesize_opcode_decoding_tables( + table_bits: usize, + up_to_version: ISAVersion, +) -> Vec { + // we walk over all opcode variants, and perform passes: + // - first just encode everything and pad the table with invalid opcodes, + // with an extra convension that all zeroes is invalid opcode + // - replace invalid opcode with Ret::Panic + + let all_opcodes = all_opcodes(); + let mut checker = std::collections::HashSet::new(); + for (i, opcode) in all_opcodes.iter().enumerate() { + let is_new = checker.insert(opcode.name()); + if !is_new { + panic!( + "Duplicate opcode with name: {} at index {}", + opcode.name(), + i + ); + } + } + + let mut result = Vec::with_capacity(1 << table_bits); + + // we walk over the versions to get only opcodes added in the correspoding one + + for version in ALL_ISA_VERSIONS.iter() { + if version > &up_to_version { + break; + } + + let all_opcodes_in_version = all_variants_in_version(*version); + let new_opcodes = find_new_opcodes(&mut result, &all_opcodes_in_version); + + result.extend(new_opcodes); + + assert_eq!(result.len(), compute_encoding_density(*version)); + } + + assert_eq!(result[0], INVALID_OPCODE_VARIANT); + assert!(result.len() <= 1 << table_bits); + result.resize(1 << table_bits, INVALID_OPCODE_VARIANT); + + result +} + +pub fn synthesize_opcode_decoding_tables_legacy( + table_bits: usize, + up_to_version: ISAVersion, +) -> Vec { + // we walk over all opcode variants, and perform passes: + // - first just encode everything and pad the table with invalid opcodes, + // with an extra convension that all zeroes is invalid opcode + // - replace invalid opcode with Ret::Panic + + let all_opcodes = all_opcodes(); + let all_prototypes = all_opcode_prototypes(); + + let mut checker = std::collections::HashSet::new(); + for (i, opcode) in all_opcodes.iter().enumerate() { + let is_new = checker.insert(opcode.name()); + if !is_new { + panic!( + "Duplicate opcode with name: {} at index {}", + opcode.name(), + i + ); + } + } + + let mut result = Vec::with_capacity(1 << table_bits); + + // we walk over the versions to get only opcodes added in the correspoding one + + for version in ALL_ISA_VERSIONS.iter() { + if version > &up_to_version { + break; + } + + // walk over prototypes and use their declared information + + for (i, opcode) in all_opcodes.iter().enumerate() { + if i == 0 { + assert_eq!( + opcode.name(), + "Invalid opcode", + "first opcode should be invalid opcode" + ); + } + let all_variants_added_in_this_version = opcode.variants_data(*version); + match ( + &opcode.input_operands(*version)[..], + &opcode.output_operands(*version)[..], + ) { + (&[], &[]) + | (&[Operand::RegOnly], &[]) + | (&[], &[Operand::RegOnly]) + | (&[Operand::RegOnly], &[Operand::RegOnly]) + | (&[Operand::RegOnly, Operand::RegOnly], &[]) + | (&[Operand::RegOnly, Operand::RegOnly], &[Operand::RegOnly]) + | (&[Operand::RegOnly], &[Operand::RegOnly, Operand::RegOnly]) => { + // we do not need to encode any extra information, just a variant + for variant_data in all_variants_added_in_this_version.into_iter() { + let variant_idx = variant_data.variant_idx; + let num_non_exclusive_flags = variant_data.num_non_exclusive_flags; + let mut tmp = INVALID_OPCODE_VARIANT; + tmp.opcode = all_prototypes[i] + .materialize_subvariant_from_prototype(variant_idx, version); + match num_non_exclusive_flags { + 0 => { + // only 1 option + result.push(tmp); + } + 1 => { + // 2 options + for b in [false, true] { + let mut t = tmp; + t.flags[0] = b; + result.push(t); + } + } + 2 => { + // 4 options + for b0 in [false, true] { + for b1 in [false, true] { + let mut t = tmp; + t.flags[0] = b0; + t.flags[1] = b1; + result.push(t); + } + } + } + _ => { + unreachable!() + } + } + } + } + (&[Operand::Full(_)], &[Operand::Full(_)]) + | (&[Operand::Full(_), Operand::RegOnly], &[Operand::Full(_)]) + | (&[Operand::Full(_), Operand::RegOnly], &[Operand::Full(_), Operand::RegOnly]) => { + // we need to encode all combinations of input and output being reg/stack/code/imm + for variant_data in all_variants_added_in_this_version.into_iter() { + let variant_idx = variant_data.variant_idx; + let num_non_exclusive_flags = variant_data.num_non_exclusive_flags; + for input_variant in ImmMemHandlerFlags::all_variants() { + for output_variant in ImmMemHandlerFlags::all_variants() { + let mut tmp = INVALID_OPCODE_VARIANT; + tmp.opcode = all_prototypes[i] + .materialize_subvariant_from_prototype(variant_idx, version); + tmp.src0_operand_type = Operand::Full(input_variant); + if !output_variant.is_allowed_for_dst() { + // some of the variants are not applicable for dst + continue; + } + tmp.dst0_operand_type = Operand::Full(output_variant); + match num_non_exclusive_flags { + 0 => { + result.push(tmp); + } + 1 => { + for b in [false, true] { + let mut t = tmp; + t.flags[0] = b; + result.push(t); + } + } + 2 => { + for b0 in [false, true] { + for b1 in [false, true] { + let mut t = tmp; + t.flags[0] = b0; + t.flags[1] = b1; + result.push(t); + } + } + } + _ => { + unreachable!() + } + } + } + } + } + } + (&[Operand::Full(_)], &[]) => { + // we need to encode all combinations of input and output being reg/stack/code/imm + // but we only have a case of inputs + for variant_data in all_variants_added_in_this_version.into_iter() { + let variant_idx = variant_data.variant_idx; + let num_non_exclusive_flags = variant_data.num_non_exclusive_flags; + for input_variant in ImmMemHandlerFlags::all_variants() { + let mut tmp = INVALID_OPCODE_VARIANT; + tmp.opcode = all_prototypes[i] + .materialize_subvariant_from_prototype(variant_idx, version); + tmp.src0_operand_type = Operand::Full(input_variant); + match num_non_exclusive_flags { + 0 => { + result.push(tmp); + } + 1 => { + for b in [false, true] { + let mut t = tmp; + t.flags[0] = b; + result.push(t); + } + } + 2 => { + for b0 in [false, true] { + for b1 in [false, true] { + let mut t = tmp; + t.flags[0] = b0; + t.flags[1] = b1; + result.push(t); + } + } + } + _ => { + unreachable!() + } + } + } + } + } + a @ _ => { + unreachable!( + "unknown combination of operand types: {:?} for opcode {}", + a, + opcode.name() + ); + } + } + } + + assert_eq!(result.len(), compute_encoding_density(*version)); + } + + assert_eq!(result[0], INVALID_OPCODE_VARIANT); + assert!(result.len() <= 1 << table_bits); + result.resize(1 << table_bits, INVALID_OPCODE_VARIANT); + + result +} + +fn all_variants_in_version(version: ISAVersion) -> Vec { + // we walk over all opcode variants, and perform passes: + // - first just encode everything and pad the table with invalid opcodes, + // with an extra convension that all zeroes is invalid opcode + // - replace invalid opcode with Ret::Panic + + let all_opcodes = all_opcodes(); + let all_prototypes = all_opcode_prototypes(); + + let mut checker = std::collections::HashSet::new(); + for (i, opcode) in all_opcodes.iter().enumerate() { + let is_new = checker.insert(opcode.name()); + if !is_new { + panic!( + "Duplicate opcode with name: {} at index {}", + opcode.name(), + i + ); + } + } + + let mut result = Vec::with_capacity(1 << 11); + + // we walk over the versions to get only opcodes added in the correspoding one + + // walk over prototypes and use their declared information + + for (i, opcode) in all_opcodes.iter().enumerate() { + if i == 0 { + assert_eq!( + opcode.name(), + "Invalid opcode", + "first opcode should be invalid opcode" + ); + } + let all_variants_in_this_version = opcode.variants_data(version); + + // cycle over all variants without addressing mode yet + for variant_data in all_variants_in_this_version.into_iter() { + // each variant may have different addressing modes, specific for itself + let variant_idx = variant_data.variant_idx; + let concrete_opcode_without_addressing = + all_prototypes[i].materialize_subvariant_from_prototype(variant_idx, &version); + + // now match over addressing modes + match ( + &concrete_opcode_without_addressing.input_operands(version)[..], + &concrete_opcode_without_addressing.output_operands(version)[..], + ) { + (&[], &[]) + | (&[Operand::RegOnly], &[]) + | (&[], &[Operand::RegOnly]) + | (&[Operand::RegOnly], &[Operand::RegOnly]) + | (&[Operand::RegOnly, Operand::RegOnly], &[]) + | (&[Operand::RegOnly, Operand::RegOnly], &[Operand::RegOnly]) + | (&[Operand::RegOnly], &[Operand::RegOnly, Operand::RegOnly]) => { + // we do not need to encode any extra information, just a variant + let num_non_exclusive_flags = variant_data.num_non_exclusive_flags; + let mut tmp = INVALID_OPCODE_VARIANT; + tmp.opcode = all_prototypes[i] + .materialize_subvariant_from_prototype(variant_idx, &version); + assert!(matches!(tmp.src0_operand_type, Operand::RegOnly)); + assert!(matches!(tmp.dst0_operand_type, Operand::RegOnly)); + match num_non_exclusive_flags { + 0 => { + // only 1 option + result.push(tmp); + } + 1 => { + // 2 options + for b in [false, true] { + let mut t = tmp; + t.flags[0] = b; + result.push(t); + } + } + 2 => { + // 4 options + for b0 in [false, true] { + for b1 in [false, true] { + let mut t = tmp; + t.flags[0] = b0; + t.flags[1] = b1; + result.push(t); + } + } + } + _ => { + unreachable!() + } + } + } + (&[Operand::Full(_)], &[Operand::Full(_)]) + | (&[Operand::Full(_), Operand::RegOnly], &[Operand::Full(_)]) + | (&[Operand::Full(_), Operand::RegOnly], &[Operand::Full(_), Operand::RegOnly]) => { + // we need to encode all combinations of input and output being reg/stack/code/imm + let variant_idx = variant_data.variant_idx; + let num_non_exclusive_flags = variant_data.num_non_exclusive_flags; + for input_variant in ImmMemHandlerFlags::all_variants() { + for output_variant in ImmMemHandlerFlags::all_variants() { + let mut tmp = INVALID_OPCODE_VARIANT; + tmp.opcode = all_prototypes[i] + .materialize_subvariant_from_prototype(variant_idx, &version); + tmp.src0_operand_type = Operand::Full(input_variant); + if !output_variant.is_allowed_for_dst() { + continue; + } + tmp.dst0_operand_type = Operand::Full(output_variant); + match num_non_exclusive_flags { + 0 => { + result.push(tmp); + } + 1 => { + for b in [false, true] { + let mut t = tmp; + t.flags[0] = b; + result.push(t); + } + } + 2 => { + for b0 in [false, true] { + for b1 in [false, true] { + let mut t = tmp; + t.flags[0] = b0; + t.flags[1] = b1; + result.push(t); + } + } + } + _ => { + unreachable!() + } + } + } + } + } + (&[Operand::Full(_)], &[]) => { + // we need to encode all combinations of input and output being reg/stack/code/imm + // but we only have a case of inputs + let variant_idx = variant_data.variant_idx; + let num_non_exclusive_flags = variant_data.num_non_exclusive_flags; + for input_variant in ImmMemHandlerFlags::all_variants() { + let mut tmp = INVALID_OPCODE_VARIANT; + tmp.opcode = all_prototypes[i] + .materialize_subvariant_from_prototype(variant_idx, &version); + tmp.src0_operand_type = Operand::Full(input_variant); + assert!(matches!(tmp.dst0_operand_type, Operand::RegOnly)); + match num_non_exclusive_flags { + 0 => { + result.push(tmp); + } + 1 => { + for b in [false, true] { + let mut t = tmp; + t.flags[0] = b; + result.push(t); + } + } + 2 => { + for b0 in [false, true] { + for b1 in [false, true] { + let mut t = tmp; + t.flags[0] = b0; + t.flags[1] = b1; + result.push(t); + } + } + } + _ => { + unreachable!() + } + } + } + } + (&[Operand::RegOrImm(_), Operand::RegOnly], &[Operand::RegOnly]) + | (&[Operand::RegOrImm(_)], &[Operand::RegOnly, Operand::RegOnly]) => { + // we need to encode all combinations of input and output being reg/stack/code/imm + let variant_idx = variant_data.variant_idx; + let num_non_exclusive_flags = variant_data.num_non_exclusive_flags; + for src_variant in RegOrImmFlags::all_variants() { + let mut tmp = INVALID_OPCODE_VARIANT; + tmp.opcode = all_prototypes[i] + .materialize_subvariant_from_prototype(variant_idx, &version); + tmp.src0_operand_type = Operand::RegOrImm(src_variant); + assert!(matches!(tmp.dst0_operand_type, Operand::RegOnly)); + match num_non_exclusive_flags { + 0 => { + result.push(tmp); + } + 1 => { + for b in [false, true] { + let mut t = tmp; + t.flags[0] = b; + result.push(t); + } + } + 2 => { + for b0 in [false, true] { + for b1 in [false, true] { + let mut t = tmp; + t.flags[0] = b0; + t.flags[1] = b1; + result.push(t); + } + } + } + _ => { + unreachable!() + } + } + } + } + a @ _ => { + unreachable!( + "unknown combination of operand types: {:?} for opcode {}", + a, + opcode.name() + ); + } + } + } + } + + assert_eq!(result[0], INVALID_OPCODE_VARIANT); + + result +} + +// computes including backward compatibility +pub fn max_num_variants_for_version(version: ISAVersion) -> usize { + let all_opcodes = all_opcodes(); + let max_num_variants = all_opcodes + .iter() + .map(|op| op.max_variant_idx(version) + 1) // it's 0 enumerated, so +1 + .max() + .unwrap(); + + max_num_variants +} + +// computes including backward compatibility +pub fn max_num_flags_for_version(version: ISAVersion) -> usize { + let all_opcodes = all_opcodes(); + let num_flags = all_opcodes + .iter() + .map(|op| { + ALL_ISA_VERSIONS + .iter() + .filter(|el| *el <= &version) + .map(|el| { + let max_flags_for_added_in_this_version = op + .variants_data(*el) + .into_iter() + .map(|t| t.num_non_exclusive_flags) + .max() + .unwrap_or(0); + + max_flags_for_added_in_this_version + }) + .max() + .unwrap() + }) + .max() + .unwrap(); + + num_flags +} + +pub fn synthesize_bit_decomposition_table( + opcodes: &[OpcodeVariant], + assert_version: ISAVersion, +) -> Vec { + let all_opcodes = all_opcodes(); + let num_opcodes = all_opcodes.len(); + let input_flags = ImmMemHandlerFlags::num_src_variants(); + let output_flags = ImmMemHandlerFlags::num_dst_variants(); + assert_eq!(num_opcodes, OPCODE_TYPE_BITS); + assert_eq!(input_flags, OPCODE_INPUT_VARIANT_FLAGS); + assert_eq!(output_flags, OPCODE_OUTPUT_VARIANT_FLAGS); + + let mut result = Vec::with_capacity(opcodes.len()); + for opcode in opcodes.iter() { + let encoding = opcode_as_integer_bitmask(opcode, assert_version); + result.push(encoding); + } + + result +} + +// we only need opcodes added in this particular version, not the cumulative set +// from all the versions below +pub(crate) fn compute_encoding_density(for_version: ISAVersion) -> usize { + let all_opcodes = all_opcodes(); + + let mut checker = std::collections::HashSet::new(); + for (i, opcode) in all_opcodes.iter().enumerate() { + let is_new = checker.insert(opcode.name()); + if !is_new { + panic!( + "Duplicate opcode with name: {} at index {}", + opcode.name(), + i + ); + } + } + + let mut num_options = 0; + let all_prototypes = all_opcode_prototypes(); + for (idx, opcode) in all_opcodes.iter().enumerate() { + let variants_data = opcode.variants_data(for_version); + for variant in variants_data.into_iter() { + let variant_idx = variant.variant_idx; + let concrete_opcode_without_addressing = all_prototypes[idx] + .materialize_subvariant_from_prototype(variant_idx, &for_version); + let mut num_addressing_modes = 1; + for el in concrete_opcode_without_addressing.input_operands(for_version) { + let multiplier = match el { + Operand::Full(_) => ImmMemHandlerFlags::num_src_variants(), + Operand::RegOrImm(_) => RegOrImmFlags::num_src_variants(), + Operand::RegOnly => 1, + }; + num_addressing_modes *= multiplier; + } + + for el in concrete_opcode_without_addressing.output_operands(for_version) { + let multiplier = match el { + Operand::Full(_) => ImmMemHandlerFlags::num_dst_variants(), + Operand::RegOrImm(_) => RegOrImmFlags::num_dst_variants(), + Operand::RegOnly => 1, + }; + num_addressing_modes *= multiplier; + } + let multiplier_for_non_exclusive = 1 << variant.num_non_exclusive_flags; + let all_variants = multiplier_for_non_exclusive * num_addressing_modes; + num_options += all_variants; + } + } + + num_options +} + +pub(crate) fn opcode_as_integer_bitmask( + full_opcode_variant: &OpcodeVariant, + version: ISAVersion, +) -> u64 { + let max_variant_bits_in_version = max_num_variants_for_version(version); + let max_num_flags_in_version = max_num_flags_for_version(version); + + let mut encoding = 0u64; + let mut global_shift = 0; + // first encoding logical opcode + encoding |= 1u64 << (global_shift + full_opcode_variant.opcode.variant_idx()); + global_shift += *crate::NUM_LOGICAL_OPCODES; + // then encode sub-variant + encoding |= 1u64 << (global_shift + full_opcode_variant.opcode.materialize_subvariant_idx()); + global_shift += max_variant_bits_in_version; + // then encode flags + for (i, flag) in full_opcode_variant.flags.iter().enumerate() { + if *flag { + encoding |= 1u64 << (global_shift + i); + } + } + global_shift += max_num_flags_in_version; + // then encode src0 addressing mode + encoding |= 1u64 << (global_shift + full_opcode_variant.src0_operand_type.variant_idx()); + global_shift += *crate::NUM_INPUT_VARIANTS; + // then dst0 + encoding |= 1u64 << (global_shift + full_opcode_variant.dst0_operand_type.variant_idx()); + global_shift += *crate::NUM_OUTPUT_VARIANTS; + + let aligned_num_description_bits = total_description_bits_rounded_for_version(version); + assert!(global_shift <= aligned_num_description_bits); + global_shift = aligned_num_description_bits; + // then any auxilary information + // for now only kernel mode requirement + if full_opcode_variant.requires_kernel_mode() { + encoding |= 1u64 << global_shift; + } + global_shift += crate::KERNEL_MODE_FLAG_BITS; + if full_opcode_variant.can_be_used_in_static_context() { + encoding |= 1u64 << global_shift; + } + global_shift += crate::CAN_BE_USED_IN_STATIC_CONTEXT_FLAG_BITS; + // we also encode any INVALID opcode as explicit panic + if full_opcode_variant.is_explicit_panic() { + encoding |= 1u64 << global_shift; + } + global_shift += crate::EXPLICIT_PANIC_FLAG_BITS; + + assert!(global_shift <= 64); + + encoding +} + +fn semantically_equal(a: &OpcodeVariant, b: &OpcodeVariant) -> bool { + if a.opcode != b.opcode { + return false; + } + if a.flags != b.flags { + return false; + } + // first compare DST as it can not have difference between Reg only and RegImm + if a.dst0_operand_type != b.dst0_operand_type { + return false; + } + + if a.src0_operand_type == b.src0_operand_type { + return true; + } + + match (a.src0_operand_type, b.src0_operand_type) { + (Operand::RegOnly, Operand::RegOrImm(RegOrImmFlags::UseRegOnly)) + | (Operand::RegOrImm(RegOrImmFlags::UseRegOnly), Operand::RegOnly) => true, + _ => false, + } +} + +fn find_new_opcodes(old: &mut [OpcodeVariant], new: &[OpcodeVariant]) -> Vec { + // sanity check that we always expand + let tmp: HashSet = HashSet::from_iter(new.iter().copied()); + for el in old.iter() { + if tmp.contains(&el) == false { + // we may have semantic equivalents instead + let mut found_equal = false; + for new in new.iter() { + if found_equal { + break; + } + if semantically_equal(new, el) { + found_equal = true; + } + } + + assert!(found_equal, "new set doesn't contain {:?}", el); + } + } + + let mut difference = vec![]; + + for new in new.iter() { + let mut found_equivalent = false; + for old in old.iter_mut() { + if found_equivalent { + break; + } + + if semantically_equal(new, old) { + found_equivalent = true; + // also replace them + *old = *new; + } + } + + if found_equivalent == false { + difference.push(*new); + } + } + + difference +} + +pub fn compute_decoding_format(assert_version: ISAVersion) -> String { + let all_opcodes = all_opcodes(); + let num_opcodes = all_opcodes.len(); + let num_options = max_num_variants_for_version(assert_version); + let num_flags = max_num_flags_for_version(assert_version); + let input_flags = ImmMemHandlerFlags::num_src_variants(); + let output_flags = ImmMemHandlerFlags::num_dst_variants(); + + let total_bits = num_opcodes + num_options + num_flags + input_flags + output_flags; + + format!("{} bits in total.\n{} bit flags for opcode|{} bit flags for variant|{} bit flags for flags|{} bits flags for input type|{} bit flags for output type", + total_bits, + num_opcodes, + num_options, + num_flags, + input_flags, + output_flags + ) +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn show_num_variants() { + let all = compute_encoding_density(ISAVersion(0)); + println!( + "Need to encode {} variants in version {:?}", + all, + ISAVersion(0) + ); + let all = compute_encoding_density(ISAVersion(1)); + println!( + "Need to encode {} variants in version {:?}", + all, + ISAVersion(1) + ); + } + + #[test] + fn show_circuit_decoding_format() { + let format = compute_decoding_format(ISAVersion(0)); + println!("{} for version {:?}", format, ISAVersion(0)); + let format = compute_decoding_format(ISAVersion(1)); + println!("{} for version {:?}", format, ISAVersion(1)); + } + + #[test] + fn synthesize_table() { + let table = synthesize_opcode_decoding_tables(11, ISAVersion(0)); + for el in table[0..20].iter() { + println!("Opcode {:?}", el); + } + } + + #[test] + fn synthesize_bit_encoding_table() { + let table = synthesize_opcode_decoding_tables(11, ISAVersion(0)); + let encoding = synthesize_bit_decomposition_table(&table, ISAVersion(0)); + for (el, enc) in table.iter().zip(encoding.iter()).skip(40).take(20) { + println!("Opcode: {:?}\n Encoding {:035b}", el, enc); + } + } + + #[test] + fn check_encoding() { + let variant = OpcodeVariant { + opcode: Opcode::Add(AddOpcode::Add), + src0_operand_type: Operand::Full(ImmMemHandlerFlags::UseImm16Only), + dst0_operand_type: Operand::Full(ImmMemHandlerFlags::UseRegOnly), + flags: [false, false], + }; + let index = OPCODE_TO_CANONICAL_INDEX_LOOKUP_MAP.get(&variant).unwrap(); + dbg!(index); + let encoding = OPCODES_PROPS_INTEGER_BITMASKS[*index]; + println!("Opcode: {:?}\n Encoding {:048b}", variant, encoding); + } + + #[test] + fn check_serialize() { + let variant = OpcodeVariant { + opcode: Opcode::Log(LogOpcode::PrecompileCall), + src0_operand_type: Operand::RegOnly, + dst0_operand_type: Operand::RegOnly, + flags: [false, false], + }; + let index = OPCODE_TO_CANONICAL_INDEX_LOOKUP_MAP.get(&variant).unwrap(); + dbg!(index); + let encoding = OPCODES_PROPS_INTEGER_BITMASKS[*index]; + println!("Opcode: {:?}\n Encoding {:048b}", variant, encoding); + } + + fn decode_from_raw(raw: u64) -> OpcodeVariant { + let properties_index = raw & ((1u64 << OPCODES_TABLE_WIDTH) - 1); + let opcode = OPCODES_TABLE[properties_index as usize]; + + opcode + } + + #[test] + fn decode_opcode() { + let opcode = 0x000300000004001d; + + // Previous code word 0 = 0x0000000300010369 + // Previous code word 1 = 0x000000020000036d + // Previous code word 2 = 0x0000000000000368 + // Previous code word 3 = 0x000000010100003a + let variant = decode_from_raw(opcode); + dbg!(variant); + } + + #[test] + fn calculator() { + let mut v0 = all_variants_in_version(ISAVersion(0)); + dbg!(v0.len()); + let v1 = all_variants_in_version(ISAVersion(1)); + dbg!(v1.len()); + + // check that our ordering doesn't change for legacy tables + let legacy_v0 = synthesize_opcode_decoding_tables_legacy(11, ISAVersion(0)); + assert_eq!(&legacy_v0[..v0.len()], &v0[..]); + + let new_v0 = synthesize_opcode_decoding_tables(11, ISAVersion(0)); + let num_non_trivial_v0 = compute_encoding_density(ISAVersion(0)); + assert_eq!(&legacy_v0[..], &new_v0[..]); + + let difference = find_new_opcodes(&mut v0, &v1); + + let new_v1 = synthesize_opcode_decoding_tables(11, ISAVersion(1)); + let num_non_trivial_v1 = compute_encoding_density(ISAVersion(1)); + + for (a, b) in new_v0[..num_non_trivial_v0] + .iter() + .zip(new_v1[..num_non_trivial_v0].iter()) + { + assert!(semantically_equal(a, b)); + } + + assert!(num_non_trivial_v1 >= num_non_trivial_v0); + + for idx in num_non_trivial_v0..num_non_trivial_v1 { + assert!(new_v0[idx].is_explicit_panic()); + } + + dbg!(&difference); + } +} diff --git a/crates/zkevm_opcode_defs/src/definitions/mul.rs b/crates/zkevm_opcode_defs/src/definitions/mul.rs new file mode 100644 index 0000000..6b7fb39 --- /dev/null +++ b/crates/zkevm_opcode_defs/src/definitions/mul.rs @@ -0,0 +1,71 @@ +use super::*; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct MulOpcode; + +impl OpcodeVariantProps for MulOpcode { + fn all_variants() -> Vec { + vec![MulOpcode] + } + + fn max_variant_idx_for_version(_version: ISAVersion) -> usize { + MulOpcode.variant_index() + } + + fn minimal_version(&self) -> ISAVersion { + ALL_ISA_VERSIONS[0] + } + + fn variant_index(&self) -> usize { + 0 + } + + fn from_variant_index_for_version(index: usize, _version: &ISAVersion) -> Option { + match index { + 0 => Some(MulOpcode), + _ => None, + } + } + + fn ergs_price(&self) -> u32 { + RICH_ADDRESSING_OPCODE_ERGS + } +} + +impl OpcodeProps for MulOpcode { + fn name(&self) -> &'static str { + "Mul opcode" + } + fn variants_data(&self, version: ISAVersion) -> Vec { + match version { + ISAVersion(0) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 1, 2) + } + ISAVersion(1) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 1, 2) + } + _ => unimplemented!(), + } + } + fn max_variant_idx(&self, _version: ISAVersion) -> usize { + MulOpcode.variant_index() + } + fn input_operands(&self, _version: ISAVersion) -> Vec { + vec![ + Operand::Full(ImmMemHandlerFlags::UseRegOnly), + Operand::RegOnly, + ] + } + fn output_operands(&self, _version: ISAVersion) -> Vec { + vec![ + Operand::Full(ImmMemHandlerFlags::UseRegOnly), + Operand::RegOnly, + ] + } + fn requires_kernel_mode(&self) -> bool { + false + } + fn can_be_used_in_static_context(&self) -> bool { + true + } +} diff --git a/crates/zkevm_opcode_defs/src/definitions/near_call.rs b/crates/zkevm_opcode_defs/src/definitions/near_call.rs new file mode 100644 index 0000000..2a941e3 --- /dev/null +++ b/crates/zkevm_opcode_defs/src/definitions/near_call.rs @@ -0,0 +1,65 @@ +use super::*; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct NearCallOpcode; + +impl OpcodeVariantProps for NearCallOpcode { + fn all_variants() -> Vec { + vec![NearCallOpcode] + } + + fn max_variant_idx_for_version(_version: ISAVersion) -> usize { + NearCallOpcode.variant_index() + } + + fn minimal_version(&self) -> ISAVersion { + ALL_ISA_VERSIONS[0] + } + + fn variant_index(&self) -> usize { + 0 + } + + fn from_variant_index_for_version(index: usize, _version: &ISAVersion) -> Option { + match index { + 0 => Some(NearCallOpcode), + _ => None, + } + } + + fn ergs_price(&self) -> u32 { + AVERAGE_OPCODE_ERGS + CALL_LIKE_ERGS_COST + } +} + +impl OpcodeProps for NearCallOpcode { + fn name(&self) -> &'static str { + "Near call opcode" + } + fn variants_data(&self, version: ISAVersion) -> Vec { + match version { + ISAVersion(0) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 0, 2) + } + ISAVersion(1) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 0, 2) + } + _ => unimplemented!(), + } + } + fn max_variant_idx(&self, _version: ISAVersion) -> usize { + NearCallOpcode.variant_index() + } + fn input_operands(&self, _version: ISAVersion) -> Vec { + vec![Operand::RegOnly] + } + fn output_operands(&self, _version: ISAVersion) -> Vec { + vec![] + } + fn requires_kernel_mode(&self) -> bool { + false + } + fn can_be_used_in_static_context(&self) -> bool { + true + } +} diff --git a/crates/zkevm_opcode_defs/src/definitions/noop.rs b/crates/zkevm_opcode_defs/src/definitions/noop.rs new file mode 100644 index 0000000..072b8d5 --- /dev/null +++ b/crates/zkevm_opcode_defs/src/definitions/noop.rs @@ -0,0 +1,65 @@ +use super::*; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct NopOpcode; + +impl OpcodeVariantProps for NopOpcode { + fn all_variants() -> Vec { + vec![NopOpcode] + } + + fn max_variant_idx_for_version(_version: ISAVersion) -> usize { + NopOpcode.variant_index() + } + + fn minimal_version(&self) -> ISAVersion { + ALL_ISA_VERSIONS[0] + } + + fn variant_index(&self) -> usize { + 0 + } + + fn from_variant_index_for_version(index: usize, _version: &ISAVersion) -> Option { + match index { + 0 => Some(NopOpcode), + _ => None, + } + } + + fn ergs_price(&self) -> u32 { + RICH_ADDRESSING_OPCODE_ERGS + } +} + +impl OpcodeProps for NopOpcode { + fn name(&self) -> &'static str { + "Nop opcode" + } + fn variants_data(&self, version: ISAVersion) -> Vec { + match version { + ISAVersion(0) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 0, 2) + } + ISAVersion(1) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 0, 2) + } + _ => unimplemented!(), + } + } + fn max_variant_idx(&self, _version: ISAVersion) -> usize { + NopOpcode.variant_index() + } + fn input_operands(&self, _version: ISAVersion) -> Vec { + vec![Operand::Full(ImmMemHandlerFlags::UseRegOnly)] + } + fn output_operands(&self, _version: ISAVersion) -> Vec { + vec![Operand::Full(ImmMemHandlerFlags::UseRegOnly)] + } + fn requires_kernel_mode(&self) -> bool { + false + } + fn can_be_used_in_static_context(&self) -> bool { + true + } +} diff --git a/crates/zkevm_opcode_defs/src/definitions/opcode_trait.rs b/crates/zkevm_opcode_defs/src/definitions/opcode_trait.rs new file mode 100644 index 0000000..a71ee48 --- /dev/null +++ b/crates/zkevm_opcode_defs/src/definitions/opcode_trait.rs @@ -0,0 +1,133 @@ +use super::*; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub enum Operand { + RegOnly, + RegOrImm(RegOrImmFlags), + Full(ImmMemHandlerFlags), +} +impl Operand { + pub const fn variant_idx(&self) -> usize { + match self { + Operand::RegOnly => 0, + Operand::RegOrImm(v) => v.variant_index(), + Operand::Full(v) => v.variant_index(), + } + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct ISAVersion(pub u8); + +impl ISAVersion { + pub const fn as_index(&self) -> usize { + self.0 as usize + } + + pub fn all_backward_compatible_versions(including: Self) -> Vec { + let mut result = vec![]; + for v in ALL_ISA_VERSIONS.iter() { + if v <= &including { + result.push(*v); + } + } + + result + } +} + +pub const NUM_ISA_VERSIONS: usize = 2; +pub const ALL_ISA_VERSIONS: [ISAVersion; NUM_ISA_VERSIONS] = [ISAVersion(0), ISAVersion(1)]; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct OpcodeVariantData { + pub variant_idx: usize, + pub num_non_exclusive_flags: usize, + pub num_used_immediates: usize, +} + +// Extra traits are for lazy statics +pub trait OpcodeProps: 'static + Send + Sync { + fn name(&self) -> &'static str; + fn variants_data(&self, version: ISAVersion) -> Vec; + fn max_variant_idx(&self, version: ISAVersion) -> usize; + // addressing modes can not change from version to version + fn input_operands(&self, version: ISAVersion) -> Vec; + fn output_operands(&self, version: ISAVersion) -> Vec; + // These are aux flags that indicate extra properties + fn requires_kernel_mode(&self) -> bool; + fn can_be_used_in_static_context(&self) -> bool; + fn can_have_src0_from_mem(&self, version: ISAVersion) -> bool { + let possible_dests = self.input_operands(version); + + if possible_dests.len() == 0 { + false + } else { + match possible_dests[0] { + Operand::Full(_) => true, + Operand::RegOnly => false, + Operand::RegOrImm(_) => false, + } + } + } + fn can_write_dst0_into_memory(&self, version: ISAVersion) -> bool { + let possible_dests = self.output_operands(version); + + if possible_dests.len() == 0 { + false + } else { + match possible_dests[0] { + Operand::Full(_) => true, + Operand::RegOnly => false, + Operand::RegOrImm(_) => unreachable!(), + } + } + } +} + +pub trait OpcodeVariantProps: Sized + 'static + Send + Sync { + fn all_variants() -> Vec; + fn minimal_version(&self) -> ISAVersion; + fn max_variant_idx_for_version(version: ISAVersion) -> usize; + fn is_available_for_version(&self, version: ISAVersion) -> bool { + self.minimal_version() >= version + } + fn is_added_in_version(&self, version: ISAVersion) -> bool { + self.minimal_version() == version + } + fn variants_for_version(version: ISAVersion) -> Vec { + Self::all_variants() + .into_iter() + .filter(|el| el.is_available_for_version(version)) + .collect() + } + fn variants_added_in_version(version: ISAVersion) -> Vec { + Self::all_variants() + .into_iter() + .filter(|el| el.is_added_in_version(version)) + .collect() + } + fn variant_index(&self) -> usize; + fn from_variant_index_for_version(index: usize, version: &ISAVersion) -> Option; + fn ergs_price(&self) -> u32; +} + +use std::ops::RangeInclusive; + +pub(crate) fn full_variants_product( + variants_range: RangeInclusive, + num_non_exclusive_flags: usize, + num_immedates: usize, +) -> Vec { + let mut result = Vec::with_capacity(variants_range.clone().count()); + for idx in variants_range { + let descr = OpcodeVariantData { + variant_idx: idx, + num_non_exclusive_flags: num_non_exclusive_flags, + num_used_immediates: num_immedates, + }; + result.push(descr); + } + + result +} diff --git a/crates/zkevm_opcode_defs/src/definitions/ptr.rs b/crates/zkevm_opcode_defs/src/definitions/ptr.rs new file mode 100644 index 0000000..609ba64 --- /dev/null +++ b/crates/zkevm_opcode_defs/src/definitions/ptr.rs @@ -0,0 +1,85 @@ +use super::*; +use ethereum_types::U256; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[repr(u8)] +pub enum PtrOpcode { + Add = 0, + Sub, + Pack, + Shrink, +} + +pub const MAX_OFFSET_FOR_ADD_SUB: U256 = U256([1u64 << 32, 0, 0, 0]); + +impl OpcodeVariantProps for PtrOpcode { + fn all_variants() -> Vec { + vec![ + PtrOpcode::Add, + PtrOpcode::Sub, + PtrOpcode::Pack, + PtrOpcode::Shrink, + ] + } + + fn max_variant_idx_for_version(_version: ISAVersion) -> usize { + PtrOpcode::Shrink.variant_index() + } + + fn minimal_version(&self) -> ISAVersion { + ALL_ISA_VERSIONS[0] + } + + fn variant_index(&self) -> usize { + (*self as u8) as usize + } + + fn from_variant_index_for_version(index: usize, _version: &ISAVersion) -> Option { + match index { + i if i == PtrOpcode::Add.variant_index() => Some(PtrOpcode::Add), + i if i == PtrOpcode::Sub.variant_index() => Some(PtrOpcode::Sub), + i if i == PtrOpcode::Pack.variant_index() => Some(PtrOpcode::Pack), + i if i == PtrOpcode::Shrink.variant_index() => Some(PtrOpcode::Shrink), + _ => None, + } + } + + fn ergs_price(&self) -> u32 { + RICH_ADDRESSING_OPCODE_ERGS + } +} + +impl OpcodeProps for PtrOpcode { + fn name(&self) -> &'static str { + "Ptr opcode" + } + fn variants_data(&self, version: ISAVersion) -> Vec { + match version { + ISAVersion(0) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 1, 2) + } + ISAVersion(1) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 1, 2) + } + _ => unimplemented!(), + } + } + fn max_variant_idx(&self, _version: ISAVersion) -> usize { + PtrOpcode::Pack.variant_index() + } + fn input_operands(&self, _version: ISAVersion) -> Vec { + vec![ + Operand::Full(ImmMemHandlerFlags::UseRegOnly), + Operand::RegOnly, + ] + } + fn output_operands(&self, _version: ISAVersion) -> Vec { + vec![Operand::Full(ImmMemHandlerFlags::UseRegOnly)] + } + fn requires_kernel_mode(&self) -> bool { + false + } + fn can_be_used_in_static_context(&self) -> bool { + true + } +} diff --git a/crates/zkevm_opcode_defs/src/definitions/ret.rs b/crates/zkevm_opcode_defs/src/definitions/ret.rs new file mode 100644 index 0000000..ba73ca3 --- /dev/null +++ b/crates/zkevm_opcode_defs/src/definitions/ret.rs @@ -0,0 +1,82 @@ +use super::*; + +pub const RET_IMPLICIT_RETURNDATA_PARAMS_REGISTER: u8 = 0; +pub const RET_RESERVED_REGISTER_0: u8 = 1; +pub const RET_RESERVED_REGISTER_1: u8 = 2; +pub const RET_RESERVED_REGISTER_2: u8 = 3; + +pub const RET_TO_LABEL_BIT_IDX: usize = 0; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[repr(u8)] +pub enum RetOpcode { + Ok = 0, + Revert, + Panic, +} + +impl OpcodeVariantProps for RetOpcode { + fn all_variants() -> Vec { + vec![RetOpcode::Ok, RetOpcode::Revert, RetOpcode::Panic] + } + + fn max_variant_idx_for_version(_version: ISAVersion) -> usize { + RetOpcode::Panic.variant_index() + } + + fn minimal_version(&self) -> ISAVersion { + ALL_ISA_VERSIONS[0] + } + + fn variant_index(&self) -> usize { + (*self as u8) as usize + } + + fn from_variant_index_for_version(index: usize, _version: &ISAVersion) -> Option { + match index { + i if i == RetOpcode::Ok.variant_index() => Some(RetOpcode::Ok), + i if i == RetOpcode::Revert.variant_index() => Some(RetOpcode::Revert), + i if i == RetOpcode::Panic.variant_index() => Some(RetOpcode::Panic), + _ => None, + } + } + + fn ergs_price(&self) -> u32 { + AVERAGE_OPCODE_ERGS + } +} + +impl OpcodeProps for RetOpcode { + fn name(&self) -> &'static str { + "Ret opcode" + } + fn variants_data(&self, version: ISAVersion) -> Vec { + match version { + ISAVersion(0) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 1, 1) + } + ISAVersion(1) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 1, 1) + } + _ => unimplemented!(), + } + } + fn max_variant_idx(&self, _version: ISAVersion) -> usize { + RetOpcode::Panic.variant_index() + } + fn input_operands(&self, _version: ISAVersion) -> Vec { + match self { + RetOpcode::Ok | RetOpcode::Revert => vec![Operand::RegOnly], + RetOpcode::Panic => vec![], + } + } + fn output_operands(&self, _version: ISAVersion) -> Vec { + vec![] + } + fn requires_kernel_mode(&self) -> bool { + false + } + fn can_be_used_in_static_context(&self) -> bool { + true + } +} diff --git a/crates/zkevm_opcode_defs/src/definitions/shift.rs b/crates/zkevm_opcode_defs/src/definitions/shift.rs new file mode 100644 index 0000000..7e74b2a --- /dev/null +++ b/crates/zkevm_opcode_defs/src/definitions/shift.rs @@ -0,0 +1,82 @@ +use super::*; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[repr(u8)] +pub enum ShiftOpcode { + Shl = 0, + Shr, + Rol, + Ror, +} + +impl OpcodeVariantProps for ShiftOpcode { + fn all_variants() -> Vec { + vec![ + ShiftOpcode::Shl, + ShiftOpcode::Shr, + ShiftOpcode::Rol, + ShiftOpcode::Ror, + ] + } + + fn max_variant_idx_for_version(_version: ISAVersion) -> usize { + ShiftOpcode::Ror.variant_index() + } + + fn minimal_version(&self) -> ISAVersion { + ALL_ISA_VERSIONS[0] + } + + fn variant_index(&self) -> usize { + (*self as u8) as usize + } + + fn from_variant_index_for_version(index: usize, _version: &ISAVersion) -> Option { + match index { + i if i == ShiftOpcode::Shl.variant_index() => Some(ShiftOpcode::Shl), + i if i == ShiftOpcode::Shr.variant_index() => Some(ShiftOpcode::Shr), + i if i == ShiftOpcode::Rol.variant_index() => Some(ShiftOpcode::Rol), + i if i == ShiftOpcode::Ror.variant_index() => Some(ShiftOpcode::Ror), + _ => None, + } + } + + fn ergs_price(&self) -> u32 { + RICH_ADDRESSING_OPCODE_ERGS + } +} + +impl OpcodeProps for ShiftOpcode { + fn name(&self) -> &'static str { + "Shift opcode" + } + fn variants_data(&self, version: ISAVersion) -> Vec { + match version { + ISAVersion(0) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 2, 2) + } + ISAVersion(1) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 2, 2) + } + _ => unimplemented!(), + } + } + fn max_variant_idx(&self, _version: ISAVersion) -> usize { + ShiftOpcode::Ror.variant_index() + } + fn input_operands(&self, _version: ISAVersion) -> Vec { + vec![ + Operand::Full(ImmMemHandlerFlags::UseRegOnly), + Operand::RegOnly, + ] + } + fn output_operands(&self, _version: ISAVersion) -> Vec { + vec![Operand::Full(ImmMemHandlerFlags::UseRegOnly)] + } + fn requires_kernel_mode(&self) -> bool { + false + } + fn can_be_used_in_static_context(&self) -> bool { + true + } +} diff --git a/crates/zkevm_opcode_defs/src/definitions/sub.rs b/crates/zkevm_opcode_defs/src/definitions/sub.rs new file mode 100644 index 0000000..b67a404 --- /dev/null +++ b/crates/zkevm_opcode_defs/src/definitions/sub.rs @@ -0,0 +1,71 @@ +use super::*; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[repr(u8)] +pub enum SubOpcode { + Sub = 0, +} + +impl OpcodeVariantProps for SubOpcode { + fn all_variants() -> Vec { + vec![SubOpcode::Sub] + } + + fn max_variant_idx_for_version(_version: ISAVersion) -> usize { + SubOpcode::Sub.variant_index() + } + + fn minimal_version(&self) -> ISAVersion { + ALL_ISA_VERSIONS[0] + } + + fn variant_index(&self) -> usize { + (*self as u8) as usize + } + + fn from_variant_index_for_version(index: usize, _version: &ISAVersion) -> Option { + match index { + i if i == SubOpcode::Sub.variant_index() => Some(SubOpcode::Sub), + _ => None, + } + } + + fn ergs_price(&self) -> u32 { + RICH_ADDRESSING_OPCODE_ERGS + } +} + +impl OpcodeProps for SubOpcode { + fn name(&self) -> &'static str { + "Sub opcode" + } + fn variants_data(&self, version: ISAVersion) -> Vec { + match version { + ISAVersion(0) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 2, 2) + } + ISAVersion(1) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 2, 2) + } + _ => unimplemented!(), + } + } + fn max_variant_idx(&self, _version: ISAVersion) -> usize { + SubOpcode::Sub.variant_index() + } + fn input_operands(&self, _version: ISAVersion) -> Vec { + vec![ + Operand::Full(ImmMemHandlerFlags::UseRegOnly), + Operand::RegOnly, + ] + } + fn output_operands(&self, _version: ISAVersion) -> Vec { + vec![Operand::Full(ImmMemHandlerFlags::UseRegOnly)] + } + fn requires_kernel_mode(&self) -> bool { + false + } + fn can_be_used_in_static_context(&self) -> bool { + true + } +} diff --git a/crates/zkevm_opcode_defs/src/definitions/uma.rs b/crates/zkevm_opcode_defs/src/definitions/uma.rs new file mode 100644 index 0000000..3ac129e --- /dev/null +++ b/crates/zkevm_opcode_defs/src/definitions/uma.rs @@ -0,0 +1,142 @@ +use crate::circuit_prices::{RAM_PERMUTATION_COST_IN_ERGS, VM_CYCLE_COST_IN_ERGS}; + +use super::*; +use ethereum_types::U256; + +pub const MAX_OFFSET_TO_DEREF_LOW_U32: u32 = ((1u64 << 32) - 33) as u32; + +// Maximum offset which can be dereferenced. Formally we could dereference +// exactly 1<<32 - 32, but it would trigger extra checks and overflows, and in practice +// ergs cost to grow memory to that limit is beyond what can be used +pub const MAX_OFFSET_TO_DEREF: U256 = U256([MAX_OFFSET_TO_DEREF_LOW_U32 as u64, 0, 0, 0]); + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[repr(u8)] +pub enum UMAOpcode { + HeapRead = 0, + HeapWrite, + AuxHeapRead, + AuxHeapWrite, + FatPointerRead, +} + +pub const UMA_INCREMENT_FLAG_IDX: usize = 0; + +impl OpcodeVariantProps for UMAOpcode { + fn all_variants() -> Vec { + vec![ + UMAOpcode::HeapRead, + UMAOpcode::HeapWrite, + UMAOpcode::AuxHeapRead, + UMAOpcode::AuxHeapWrite, + UMAOpcode::FatPointerRead, + ] + } + + fn max_variant_idx_for_version(version: ISAVersion) -> usize { + match version { + ISAVersion(0) => UMAOpcode::FatPointerRead.variant_index(), + ISAVersion(1) => UMAOpcode::FatPointerRead.variant_index(), + _ => unimplemented!(), + } + } + + fn minimal_version(&self) -> ISAVersion { + match self { + _ => ALL_ISA_VERSIONS[0], + } + } + + fn variant_index(&self) -> usize { + (*self as u8) as usize + } + + fn from_variant_index_for_version(index: usize, _version: &ISAVersion) -> Option { + match index { + i if i == UMAOpcode::HeapRead.variant_index() => Some(UMAOpcode::HeapRead), + i if i == UMAOpcode::HeapWrite.variant_index() => Some(UMAOpcode::HeapWrite), + i if i == UMAOpcode::AuxHeapRead.variant_index() => Some(UMAOpcode::AuxHeapRead), + i if i == UMAOpcode::AuxHeapWrite.variant_index() => Some(UMAOpcode::AuxHeapWrite), + i if i == UMAOpcode::FatPointerRead.variant_index() => Some(UMAOpcode::FatPointerRead), + _ => None, + } + } + + fn ergs_price(&self) -> u32 { + match self { + UMAOpcode::AuxHeapWrite | UMAOpcode::HeapWrite => { + // 5 RAM permutations, because: 1 to read opcode + 2 reads + 2 writes. + // 2 reads and 2 writes are needed because unaligned access is implemented with + // aligned queries + 2 * VM_CYCLE_COST_IN_ERGS + 5 * RAM_PERMUTATION_COST_IN_ERGS + } + UMAOpcode::HeapRead | UMAOpcode::AuxHeapRead | UMAOpcode::FatPointerRead => { + // 5 RAM permutations, because: 1 to read opcode + 2 reads. + // 2 reads are needed because unaligned access is implemented with aligned queries + VM_CYCLE_COST_IN_ERGS + 3 * RAM_PERMUTATION_COST_IN_ERGS + } + } + } +} + +impl OpcodeProps for UMAOpcode { + fn name(&self) -> &'static str { + "UMA opcode" + } + fn variants_data(&self, version: ISAVersion) -> Vec { + match version { + ISAVersion(0) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 1, 0) + } + ISAVersion(1) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 1, 0) + } + _ => unimplemented!(), + } + } + fn max_variant_idx(&self, version: ISAVersion) -> usize { + match version { + ISAVersion(0) => UMAOpcode::FatPointerRead.variant_index(), + ISAVersion(1) => UMAOpcode::FatPointerRead.variant_index(), + _ => unimplemented!(), + } + } + fn input_operands(&self, version: ISAVersion) -> Vec { + match version { + ISAVersion(0) => match self { + UMAOpcode::HeapWrite | UMAOpcode::AuxHeapWrite => { + vec![Operand::RegOnly, Operand::RegOnly] + } + _ => vec![Operand::RegOnly], + }, + ISAVersion(1) => { + // we allow imm on the inputs for heap access for offsets + match self { + UMAOpcode::HeapWrite | UMAOpcode::AuxHeapWrite => vec![ + Operand::RegOrImm(RegOrImmFlags::UseRegOnly), + Operand::RegOnly, + ], + UMAOpcode::HeapRead | UMAOpcode::AuxHeapRead => { + vec![Operand::RegOrImm(RegOrImmFlags::UseRegOnly)] + } + UMAOpcode::FatPointerRead => { + vec![Operand::RegOnly] + } + } + } + _ => unimplemented!(), + } + } + fn output_operands(&self, _version: ISAVersion) -> Vec { + match self { + UMAOpcode::HeapWrite | UMAOpcode::AuxHeapWrite => vec![Operand::RegOnly], + _ => vec![Operand::RegOnly, Operand::RegOnly], + } + } + fn requires_kernel_mode(&self) -> bool { + false + } + fn can_be_used_in_static_context(&self) -> bool { + true + } +} diff --git a/crates/zkevm_opcode_defs/src/definitions/versioned_hash/mod.rs b/crates/zkevm_opcode_defs/src/definitions/versioned_hash/mod.rs new file mode 100644 index 0000000..e718826 --- /dev/null +++ b/crates/zkevm_opcode_defs/src/definitions/versioned_hash/mod.rs @@ -0,0 +1,103 @@ +pub trait VersionedHashDef: + Send + Sync + Sized + Clone + Copy + PartialEq + Eq + std::hash::Hash +{ + const VERSION_BYTE: u8; + type StorageLayout: Send + Sync + Sized + Clone + Copy + PartialEq + Eq + std::hash::Hash; + fn serialize(storage: Self::StorageLayout) -> Option<[u8; 32]>; + fn serialize_to_stored(storage: Self::StorageLayout) -> Option<[u8; 32]>; + fn try_deserialize(input: [u8; 32]) -> Option; +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub struct VersionedHashGeneric { + data: V::StorageLayout, +} + +impl VersionedHashGeneric { + pub fn serialize(self) -> Option<[u8; 32]> { + V::serialize(self.data) + } + + pub fn serialize_to_stored(self) -> Option<[u8; 32]> { + V::serialize_to_stored(self.data) + } + + pub fn try_create_from_raw(input: [u8; 32]) -> Option { + let layout = V::try_deserialize(input)?; + + Some(Self { data: layout }) + } + + pub fn layout_ref(&self) -> &V::StorageLayout { + &self.data + } +} + +impl VersionedHashGeneric { + pub fn from_digest_and_preimage_num_words(digest: [u8; 32], num_words: u16) -> Self { + let mut truncated_digest = [0u8; 28]; + truncated_digest.copy_from_slice(&digest[4..]); + + Self { + data: ContractCodeSha256Storage { + code_length_in_words: num_words, + extra_marker: 0u8, + partial_hash: truncated_digest, + }, + } + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub struct ContractCodeSha256; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub struct ContractCodeSha256Storage { + pub code_length_in_words: u16, + pub extra_marker: u8, + pub partial_hash: [u8; 28], +} + +impl ContractCodeSha256 { + pub const CODE_AT_REST_MARKER: u8 = 0; + pub const YET_CONSTRUCTED_MARKER: u8 = 1; +} + +impl VersionedHashDef for ContractCodeSha256 { + const VERSION_BYTE: u8 = 0x01; + type StorageLayout = ContractCodeSha256Storage; + fn serialize(storage: Self::StorageLayout) -> Option<[u8; 32]> { + let mut result = [0u8; 32]; + result[0] = Self::VERSION_BYTE; + result[1] = storage.extra_marker; + result[2..4].copy_from_slice(&storage.code_length_in_words.to_be_bytes()); + result[4..].copy_from_slice(&storage.partial_hash); + + Some(result) + } + fn serialize_to_stored(storage: Self::StorageLayout) -> Option<[u8; 32]> { + let mut result = [0u8; 32]; + result[0] = Self::VERSION_BYTE; + result[1] = 0; + result[2..4].copy_from_slice(&storage.code_length_in_words.to_be_bytes()); + result[4..].copy_from_slice(&storage.partial_hash); + + Some(result) + } + fn try_deserialize(input: [u8; 32]) -> Option { + if input[0] != Self::VERSION_BYTE { + return None; + } + + let extra_marker = input[1]; + + let code_length_in_words = u16::from_be_bytes([input[2], input[3]]); + let partial_hash: [u8; 28] = input[4..32].try_into().unwrap(); + + Some(Self::StorageLayout { + code_length_in_words, + extra_marker, + partial_hash, + }) + } +} diff --git a/crates/zkevm_opcode_defs/src/imm_mem_modifiers.rs b/crates/zkevm_opcode_defs/src/imm_mem_modifiers.rs new file mode 100644 index 0000000..2e6c0f6 --- /dev/null +++ b/crates/zkevm_opcode_defs/src/imm_mem_modifiers.rs @@ -0,0 +1,129 @@ +#[derive(Clone, Copy, Debug, PartialOrd, Ord, PartialEq, Eq, Hash)] +#[repr(u8)] +pub enum ImmMemHandlerFlags { + UseRegOnly = 0, + UseStackWithPushPop, + UseStackWithOffset, + UseAbsoluteOnStack, + UseImm16Only, + UseCodePage, +} + +impl ImmMemHandlerFlags { + const NUM_VARIANTS: usize = 6; + + pub const fn all_variants() -> [Self; 6] { + [ + ImmMemHandlerFlags::UseRegOnly, + ImmMemHandlerFlags::UseStackWithPushPop, + ImmMemHandlerFlags::UseStackWithOffset, + ImmMemHandlerFlags::UseAbsoluteOnStack, + ImmMemHandlerFlags::UseImm16Only, + ImmMemHandlerFlags::UseCodePage, + ] + } + + pub const fn encoding_byte(&self) -> u8 { + *self as u8 + } + pub const fn is_memory_used(&self) -> bool { + match self { + ImmMemHandlerFlags::UseRegOnly | ImmMemHandlerFlags::UseImm16Only => false, + _ => true, + } + } + pub fn num_variants() -> usize { + Self::NUM_VARIANTS + } + pub fn num_src_variants() -> usize { + Self::NUM_VARIANTS + } + pub fn num_dst_variants() -> usize { + Self::NUM_VARIANTS - 2 + } + // pub fn materialize_variant(idx: usize) -> Self { + // assert!(idx < Self::NUM_VARIANTS); + + // match idx { + // i if i == ImmMemHandlerFlags::UseRegOnly.variant_index() => { + // ImmMemHandlerFlags::UseRegOnly + // } + // i if i == ImmMemHandlerFlags::UseStackWithPushPop.variant_index() => { + // ImmMemHandlerFlags::UseStackWithPushPop + // } + // i if i == ImmMemHandlerFlags::UseStackWithOffset.variant_index() => { + // ImmMemHandlerFlags::UseStackWithOffset + // } + // i if i == ImmMemHandlerFlags::UseAbsoluteOnStack.variant_index() => { + // ImmMemHandlerFlags::UseAbsoluteOnStack + // } + // i if i == ImmMemHandlerFlags::UseImm16Only.variant_index() => { + // ImmMemHandlerFlags::UseImm16Only + // } + // i if i == ImmMemHandlerFlags::UseCodePage.variant_index() => { + // ImmMemHandlerFlags::UseCodePage + // } + // _ => panic!("unknown variant"), + // } + // } + pub const fn variant_index(&self) -> usize { + (*self as u8) as usize + } + pub const fn is_allowed_for_dst(&self) -> bool { + match self { + ImmMemHandlerFlags::UseImm16Only | ImmMemHandlerFlags::UseCodePage => false, + _ => true, + } + } +} + +#[derive(Clone, Copy, Debug, PartialOrd, Ord, PartialEq, Eq, Hash)] +#[repr(u8)] +pub enum RegOrImmFlags { + UseRegOnly = 0, + UseImm16Only = 4, +} + +impl RegOrImmFlags { + const NUM_VARIANTS: usize = 2; + + pub const fn all_variants() -> [Self; 2] { + [RegOrImmFlags::UseRegOnly, RegOrImmFlags::UseImm16Only] + } + + pub const fn encoding_byte(&self) -> u8 { + *self as u8 + } + pub const fn is_memory_used(&self) -> bool { + false + } + pub fn num_variants() -> usize { + Self::NUM_VARIANTS + } + pub fn num_src_variants() -> usize { + Self::NUM_VARIANTS + } + pub fn num_dst_variants() -> usize { + Self::NUM_VARIANTS - 1 + } + pub const fn variant_index(&self) -> usize { + (*self as u8) as usize + } + pub const fn is_allowed_for_dst(&self) -> bool { + match self { + RegOrImmFlags::UseImm16Only => false, + _ => true, + } + } +} + +const _: () = if ImmMemHandlerFlags::UseRegOnly.variant_index() + != RegOrImmFlags::UseRegOnly.variant_index() +{ + panic!() +}; +const _: () = if ImmMemHandlerFlags::UseImm16Only.variant_index() + != RegOrImmFlags::UseImm16Only.variant_index() +{ + panic!() +}; diff --git a/crates/zkevm_opcode_defs/src/lib.rs b/crates/zkevm_opcode_defs/src/lib.rs new file mode 100644 index 0000000..60204ee --- /dev/null +++ b/crates/zkevm_opcode_defs/src/lib.rs @@ -0,0 +1,252 @@ +pub const REGISTERS_COUNT: usize = 15; + +pub mod decoding; +pub mod definitions; +pub mod imm_mem_modifiers; +pub mod opcode; +pub mod system_params; +pub mod utils; + +pub mod circuit_prices; + +use std::collections::HashMap; + +pub use bitflags; +use circuit_prices::CODE_DECOMMITMENT_COST_PER_WORD_IN_ERGS; +use circuit_prices::CODE_DECOMMITTER_SORTER_COST_IN_ERGS; +use circuit_prices::RAM_PERMUTATION_COST_IN_ERGS; +use circuit_prices::VM_CYCLE_COST_IN_ERGS; +pub use ethereum_types; + +pub use self::definitions::*; +pub use self::imm_mem_modifiers::*; +pub use self::opcode::*; +pub use self::utils::*; + +pub use self::system_params::{ + ADDRESS_ACCOUNT_CODE_STORAGE, ADDRESS_BOOTLOADER, ADDRESS_CONTRACT_DEPLOYER, ADDRESS_ECRECOVER, + ADDRESS_ETH_TOKEN, ADDRESS_EVENT_WRITER, ADDRESS_FORCE_DEPLOYER, ADDRESS_IDENTITY, + ADDRESS_IMMUTABLE_SIMULATOR, ADDRESS_KECCAK256, ADDRESS_KNOWN_CODES_STORAGE, + ADDRESS_L1_MESSENGER, ADDRESS_MSG_VALUE, ADDRESS_NONCE_HOLDER, ADDRESS_RIPEMD160, + ADDRESS_SHA256, ADDRESS_SYSTEM_CONTEXT, ADDRESS_UNRESTRICTED_SPACE, +}; + +use lazy_static::lazy_static; + +use crate::decoding::VariantMonotonicNumber; + +pub const OPCODES_TABLE_WIDTH: usize = 11; +pub const CONDITIONAL_BITS_SHIFT: usize = 13; +pub const MEMORY_GROWTH_ERGS_PER_BYTE: u32 = 1; + +const _: () = if MEMORY_GROWTH_ERGS_PER_BYTE != 1 { + panic!() +}; + +pub const VARIANT_AND_CONDITION_ENCODING_BITS: usize = 16; + +pub const REGISTER_INDEX_ENCODING_BITS: usize = 4; + +pub const SRC_REGS_SHIFT: u32 = 16; +pub const DST_REGS_SHIFT: u32 = 24; + +// flattened bits the exclusively (mostly) encode all the opcode properties +pub const OPCODE_TYPE_BITS: usize = NUM_OPCODES; + +pub const OPCODE_INPUT_VARIANT_FLAGS: usize = 6; +pub const OPCODE_OUTPUT_VARIANT_FLAGS: usize = 4; + +// aux flags for resolution of exceptions +pub const KERNEL_MODE_FLAG_BITS: usize = 1; +pub const CAN_BE_USED_IN_STATIC_CONTEXT_FLAG_BITS: usize = 1; +pub const EXPLICIT_PANIC_FLAG_BITS: usize = 1; + +pub const KERNER_MODE_FLAG_IDX: usize = 0; +pub const CAN_BE_USED_IN_STATIC_CONTEXT_FLAG_IDX: usize = 1; +pub const EXPLICIT_PANIC_FLAG_IDX: usize = 2; + +const WIDTH_MULTIPLE: usize = 16; + +pub const INITIAL_SP_ON_FAR_CALL: u64 = 0; +pub const UNMAPPED_PAGE: u32 = 0; + +pub const BOOTLOADER_BASE_PAGE: u32 = 8; +pub const BOOTLOADER_CODE_PAGE: u32 = BOOTLOADER_BASE_PAGE; +pub const BOOTLOADER_CALLDATA_PAGE: u32 = BOOTLOADER_BASE_PAGE - 1; // some convention +pub const BOOTLOADER_STACK_PAGE: u32 = BOOTLOADER_BASE_PAGE + 1; +pub const BOOTLOADER_HEAP_PAGE: u32 = BOOTLOADER_BASE_PAGE + 2; +pub const BOOTLOADER_AUX_HEAP_PAGE: u32 = BOOTLOADER_BASE_PAGE + 3; + +pub const NEW_MEMORY_PAGES_PER_FAR_CALL: u32 = 8; +pub const STARTING_TIMESTAMP: u32 = 1024; +pub const STARTING_BASE_PAGE: u32 = 2048; +pub const TIME_DELTA_PER_CYCLE: u32 = 4; +pub const MAX_PENDING_CYCLES: usize = 1; + +pub const LOG2_NUM_ADDRESSABLE_HEAP_BYTES: u32 = 24; + +pub(crate) const NUM_NON_EXCLUSIVE_FLAGS: usize = 2; + +pub fn total_description_bits_for_version(version: ISAVersion) -> usize { + let total = OPCODE_TYPE_BITS + + max_num_variants_for_version(version) + + max_num_flags_for_version(version) + + OPCODE_INPUT_VARIANT_FLAGS + + OPCODE_OUTPUT_VARIANT_FLAGS; + + total +} + +pub fn total_description_bits_rounded_for_version(version: ISAVersion) -> usize { + let mut total = OPCODE_TYPE_BITS + + max_num_variants_for_version(version) + + max_num_flags_for_version(version) + + OPCODE_INPUT_VARIANT_FLAGS + + OPCODE_OUTPUT_VARIANT_FLAGS; + if total % WIDTH_MULTIPLE != 0 { + total += WIDTH_MULTIPLE - total % WIDTH_MULTIPLE; + } + + total +} + +pub const TOTAL_AUX_BITS: usize = + KERNEL_MODE_FLAG_BITS + CAN_BE_USED_IN_STATIC_CONTEXT_FLAG_BITS + EXPLICIT_PANIC_FLAG_BITS; + +pub fn total_opcode_description_and_aux_bits_for_version(version: ISAVersion) -> usize { + total_description_bits_rounded_for_version(version) + TOTAL_AUX_BITS +} + +pub const DEFAULT_ISA_VERSION: ISAVersion = ISAVersion(1); + +lazy_static! { + pub static ref OPCODES_TABLE: [OpcodeVariant; 1 << OPCODES_TABLE_WIDTH] = { + synthesize_opcode_decoding_tables(OPCODES_TABLE_WIDTH, DEFAULT_ISA_VERSION).try_into().unwrap() + }; + + pub static ref OPCODES_PROPS_INTEGER_BITMASKS: [u64; 1 << OPCODES_TABLE_WIDTH] = { + synthesize_bit_decomposition_table(&*OPCODES_TABLE, DEFAULT_ISA_VERSION).try_into().unwrap() + }; + + pub static ref OPCODE_TO_MONOTONIC_INDEX_NUMBER_MAP: HashMap = { + let mut result = HashMap::::new(); + for (idx, el) in OPCODES_TABLE.iter().enumerate() { + if let Some(existing) = result.get(el) { + let usize_index = (*existing).into_usize(); + assert_eq!(OPCODES_TABLE[usize_index], INVALID_OPCODE_VARIANT); + } else { + let _ = result.insert(*el, VariantMonotonicNumber::from_usize(idx)); + } + } + + result + }; + + pub static ref OPCODE_TO_CANONICAL_INDEX_LOOKUP_MAP: HashMap = { + let mut result = HashMap::new(); + for (idx, el) in OPCODES_TABLE.iter().enumerate() { + if let Some(existing) = result.get(el) { + assert_eq!(OPCODES_TABLE[*existing], INVALID_OPCODE_VARIANT); + } else { + let _ = result.insert(*el, idx); + } + } + + result + }; + + pub static ref NOP_OPCODE_VARIANT: OpcodeVariant = { + let variant = OpcodeVariant{ + opcode: Opcode::Nop(NopOpcode), + src0_operand_type: Operand::Full(ImmMemHandlerFlags::UseRegOnly), + dst0_operand_type: Operand::Full(ImmMemHandlerFlags::UseRegOnly), + flags: [false; NUM_NON_EXCLUSIVE_FLAGS], + }; + assert!(OPCODE_TO_CANONICAL_INDEX_LOOKUP_MAP.contains_key(&variant)); + + variant + }; + + pub static ref NOP_BITSPREAD_U64: u64 = { + let index = OPCODE_TO_CANONICAL_INDEX_LOOKUP_MAP[&NOP_OPCODE_VARIANT]; + let bitspread = OPCODES_PROPS_INTEGER_BITMASKS[index]; + + bitspread + }; + + pub static ref PANIC_OPCODE_VARIANT: OpcodeVariant = { + let variant = OpcodeVariant{ + opcode: Opcode::Ret(RetOpcode::Panic), + src0_operand_type: Operand::RegOnly, + dst0_operand_type: Operand::RegOnly, + flags: [false; NUM_NON_EXCLUSIVE_FLAGS], + }; + + assert!(OPCODE_TO_CANONICAL_INDEX_LOOKUP_MAP.contains_key(&variant)); + + variant + }; + + pub static ref PANIC_BITSPREAD_U64: u64 = { + let index = OPCODE_TO_CANONICAL_INDEX_LOOKUP_MAP[&PANIC_OPCODE_VARIANT]; + let bitspread = OPCODES_PROPS_INTEGER_BITMASKS[index]; + + bitspread + }; + + pub static ref OPCODE_PROTOTYPES: Vec> = { + all_opcodes() + }; + + pub static ref NUM_LOGICAL_OPCODES: usize = { + OPCODE_PROTOTYPES.len() + }; + + pub static ref NUM_INPUT_VARIANTS: usize = { + ImmMemHandlerFlags::num_src_variants() + }; + + pub static ref NUM_OUTPUT_VARIANTS: usize = { + ImmMemHandlerFlags::num_dst_variants() + }; + + // Preliminary pricing + pub static ref OPCODES_PRICES: [u32; 1 << OPCODES_TABLE_WIDTH] = { + let mut result = Vec::with_capacity(1 << OPCODES_TABLE_WIDTH); + for opcode in OPCODES_TABLE.iter() { + let price = opcode.ergs_price(); + result.push(price) + } + + result.try_into().unwrap() + }; +} + +pub const INVALID_OPCODE_ERGS: u32 = u32::MAX; // will burn everything at once + +// `RICH_ADDRESSING_OPCODE_ERGS` is for opcodes that can write +// their return value/read the input onto the stack and so take 1-2 RAM permutations more than +// an average opcode. Note, that while, in the worst case, a rich addressing may take 3 ram permutations +// (1 for reading the opcode, 1 for writing input value, 1 for writing output value), the +// 1 "reading of opcode" reads 4 sequential opcodes at the same time, so if we priced users by the worst case +// (VM_CYCLE_COST_IN_ERGS + 3 * RAM_PERMUTATION_COST_IN_ERGS), they would overpay too much, while in case of a DDoS +// attack, we would only overpay only 1.2x. +pub const RICH_ADDRESSING_OPCODE_ERGS: u32 = + VM_CYCLE_COST_IN_ERGS + 2 * RAM_PERMUTATION_COST_IN_ERGS; +pub const AVERAGE_OPCODE_ERGS: u32 = VM_CYCLE_COST_IN_ERGS + RAM_PERMUTATION_COST_IN_ERGS; + +/// The following prices are meant to take into account the I/O overhead for +/// these operations (i.e. state bloat that becomes with them) +pub const STORAGE_READ_IO_PRICE: u32 = 150; +pub const STORAGE_WRITE_IO_PRICE: u32 = 250; +pub const EVENT_IO_PRICE: u32 = 25; +pub const L1_MESSAGE_IO_PRICE: u32 = 100; // Extra for merklization + +/// This variable is meant to represent the cost for creating a new item on callstack +pub const CALL_LIKE_ERGS_COST: u32 = 20; + +pub const ERGS_PER_CODE_WORD_DECOMMITTMENT: u32 = CODE_DECOMMITMENT_COST_PER_WORD_IN_ERGS; + +const _: () = if CODE_DECOMMITTER_SORTER_COST_IN_ERGS > u16::MAX as u32 { + panic!() +}; diff --git a/crates/zkevm_opcode_defs/src/opcode.rs b/crates/zkevm_opcode_defs/src/opcode.rs new file mode 100644 index 0000000..35093c5 --- /dev/null +++ b/crates/zkevm_opcode_defs/src/opcode.rs @@ -0,0 +1,89 @@ +use super::*; + +use crate::decoding::VmEncodingMode; +use crate::{Condition, ImmMemHandlerFlags, NopOpcode, OpcodeVariant, Operand, RetOpcode}; + +use crate::decoding::encoding_mode_production::EncodingModeProduction; +use crate::definitions::all::Opcode; + +#[derive(Clone, Copy, Debug)] +pub struct DecodedOpcode = EncodingModeProduction> { + pub variant: OpcodeVariant, + pub condition: Condition, + pub src0_reg_idx: u8, + pub src1_reg_idx: u8, + pub dst0_reg_idx: u8, + pub dst1_reg_idx: u8, + pub imm_0: E::PcOrImm, + pub imm_1: E::PcOrImm, +} + +impl> Default for DecodedOpcode { + fn default() -> Self { + DecodedOpcode { + variant: OpcodeVariant::default(), + condition: Condition::Always, + src0_reg_idx: 0, + src1_reg_idx: 0, + dst0_reg_idx: 0, + dst1_reg_idx: 0, + imm_0: Default::default(), + imm_1: Default::default(), + } + } +} + +impl> DecodedOpcode { + pub fn mask_into_panic(&mut self) { + // we only mask first 8 bytes of the opcode, and do not touch regs or imms + self.variant.opcode = Opcode::Ret(RetOpcode::Panic); + // it's important that we set condition to "always" + self.condition = Condition::Always; + // the rest is just trivial downgrade + self.variant.src0_operand_type = Operand::RegOnly; + self.variant.dst0_operand_type = Operand::RegOnly; + // ret opcode doesn't use flags, so it's always empty + self.variant.flags = [false; NUM_NON_EXCLUSIVE_FLAGS]; + self.src0_reg_idx = 0; + self.src1_reg_idx = 0; + self.dst0_reg_idx = 0; + self.dst1_reg_idx = 0; + } + + pub fn mask_into_nop(&mut self) { + self.variant.opcode = Opcode::Nop(NopOpcode); + // it's important that we set condition to "always" + self.condition = Condition::Always; + // the rest is just trivial downgrade + self.variant.src0_operand_type = Operand::Full(ImmMemHandlerFlags::UseRegOnly); + self.variant.dst0_operand_type = Operand::Full(ImmMemHandlerFlags::UseRegOnly); + self.variant.flags = [false; NUM_NON_EXCLUSIVE_FLAGS]; + self.src0_reg_idx = 0; + self.src1_reg_idx = 0; + self.dst0_reg_idx = 0; + self.dst1_reg_idx = 0; + } + + pub fn serialize_as_integer(&self) -> E::IntegerRepresentation { + E::encode_as_integer(&self) + } + + pub fn serialize_as_bytes(&self) -> [u8; N] { + E::encode_as_bytes(&self) + } +} + +impl> std::fmt::Display for DecodedOpcode { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + // writeln!(f, "Decoded opcode")?; + writeln!(f, "{}", self.variant)?; + writeln!(f, "Condition: {:?}", self.condition)?; + writeln!( + f, + "Register selections: src0 = r{}, src1 = r{}, dst0 = r{}, dst1 = r{}", + self.src0_reg_idx, self.src1_reg_idx, self.dst0_reg_idx, self.dst1_reg_idx + )?; + writeln!(f, "IMM0 constant: {:#08x}", self.imm_0)?; + write!(f, "IMM1 constant: {:#08x}", self.imm_1) + } +} diff --git a/crates/zkevm_opcode_defs/src/system_params.rs b/crates/zkevm_opcode_defs/src/system_params.rs new file mode 100644 index 0000000..d52b987 --- /dev/null +++ b/crates/zkevm_opcode_defs/src/system_params.rs @@ -0,0 +1,85 @@ +use crate::CALL_LIKE_ERGS_COST; +use ethereum_types::Address; + +pub const MAX_TX_ERGS_LIMIT: u32 = 80_000_000; + +pub const VM_INITIAL_FRAME_ERGS: u32 = u32::MAX; + +/// How much a single circuit should cost in terms of ergs. +pub const ERGS_PER_CIRCUIT: u32 = 80000; + +/// The callstack depth large enough to ensure that we will not exceed the stack limit +/// in any of the transactions. THe `+80` is an arbitrary value, meant to take into accounts +/// some of the internal near_calls that are performed by the bootloader which the user does +/// not pay directly to. +pub const VM_MAX_STACK_DEPTH: u32 = VM_INITIAL_FRAME_ERGS / CALL_LIKE_ERGS_COST + 80; + +pub const INITIAL_FRAME_SUCCESSFUL_EXIT_PC: u16 = 0u16; +pub const INITIAL_FRAME_FORMAL_EH_LOCATION: u16 = u16::MAX; + +const SYSTEM_CONTRACTS_OFFSET_ADDRESS: u16 = 1 << 15; + +pub const KECCAK256_ROUND_FUNCTION_PRECOMPILE_ADDRESS: u16 = SYSTEM_CONTRACTS_OFFSET_ADDRESS + 0x10; +pub const SHA256_ROUND_FUNCTION_PRECOMPILE_ADDRESS: u16 = 0x02; // as in Ethereum +pub const ECRECOVER_INNER_FUNCTION_PRECOMPILE_ADDRESS: u16 = 0x01; // as in Ethereum + +pub const INITIAL_STORAGE_WRITE_PUBDATA_BYTES: usize = 64; +pub const REPEATED_STORAGE_WRITE_PUBDATA_BYTES: usize = 40; +pub const L1_MESSAGE_PUBDATA_BYTES: u32 = 1 + 1 + 2 + 20 + 32 + 32; + +/// The maximal amount of public data in bytes that could be sent within an L1 batch +/// The limit that the Geth nodes impose is 128kb. +/// We leave 10kb margin for possible parameters. +pub const MAX_PUBDATA_PER_BLOCK: u32 = 110000; + +pub const STORAGE_AUX_BYTE: u8 = 0; +pub const EVENT_AUX_BYTE: u8 = 1; +pub const L1_MESSAGE_AUX_BYTE: u8 = 2; +pub const PRECOMPILE_AUX_BYTE: u8 = 3; + +pub const NUM_SPONGES: usize = 4; + +use lazy_static::lazy_static; + +pub const BOOTLOADER_FORMAL_ADDRESS_LOW: u16 = SYSTEM_CONTRACTS_OFFSET_ADDRESS + 0x01; +pub const DEPLOYER_SYSTEM_CONTRACT_ADDRESS_LOW: u16 = SYSTEM_CONTRACTS_OFFSET_ADDRESS + 0x02; + +/// The unrestricted address space beginning. +pub const ADDRESS_UNRESTRICTED_SPACE: u64 = 1u64 << 16; + +pub const ADDRESS_ECRECOVER: u16 = 0x0001; +pub const ADDRESS_SHA256: u16 = 0x0002; +pub const ADDRESS_RIPEMD160: u16 = 0x0003; +pub const ADDRESS_IDENTITY: u16 = 0x0004; + +pub const ADDRESS_BOOTLOADER: u16 = 0x8001; +pub const ADDRESS_ACCOUNT_CODE_STORAGE: u16 = 0x8002; +pub const ADDRESS_NONCE_HOLDER: u16 = 0x8003; +pub const ADDRESS_KNOWN_CODES_STORAGE: u16 = 0x8004; +pub const ADDRESS_IMMUTABLE_SIMULATOR: u16 = 0x8005; +pub const ADDRESS_CONTRACT_DEPLOYER: u16 = 0x8006; +pub const ADDRESS_FORCE_DEPLOYER: u16 = 0x8007; +pub const ADDRESS_L1_MESSENGER: u16 = 0x8008; +pub const ADDRESS_MSG_VALUE: u16 = 0x8009; +pub const ADDRESS_ETH_TOKEN: u16 = 0x800A; +pub const ADDRESS_SYSTEM_CONTEXT: u16 = 0x800B; +pub const ADDRESS_BOOTLOADER_UTILITIES: u16 = 0x800C; +pub const ADDRESS_EVENT_WRITER: u16 = 0x800D; +pub const ADDRESS_KECCAK256: u16 = 0x8010; + +lazy_static! { + pub static ref BOOTLOADER_FORMAL_ADDRESS: Address = + Address::from_low_u64_be(BOOTLOADER_FORMAL_ADDRESS_LOW as u64); + pub static ref DEPLOYER_SYSTEM_CONTRACT_ADDRESS: Address = + Address::from_low_u64_be(DEPLOYER_SYSTEM_CONTRACT_ADDRESS_LOW as u64); + pub static ref NONCE_MANAGER_SYSTEM_CONTRACT_ADDRESS: Address = + Address::from_low_u64_be(SYSTEM_CONTRACTS_OFFSET_ADDRESS as u64 + 0x03); + pub static ref KNOWN_CODE_FACTORY_SYSTEM_CONTRACT_ADDRESS: Address = + Address::from_low_u64_be(SYSTEM_CONTRACTS_OFFSET_ADDRESS as u64 + 0x04); + pub static ref KECCAK256_ROUND_FUNCTION_PRECOMPILE_FORMAL_ADDRESS: Address = + Address::from_low_u64_be(KECCAK256_ROUND_FUNCTION_PRECOMPILE_ADDRESS as u64); + pub static ref SHA256_ROUND_FUNCTION_PRECOMPILE_FORMAL_ADDRESS: Address = + Address::from_low_u64_be(SHA256_ROUND_FUNCTION_PRECOMPILE_ADDRESS as u64); + pub static ref ECRECOVER_INNER_FUNCTION_PRECOMPILE_FORMAL_ADDRESS: Address = + Address::from_low_u64_be(ECRECOVER_INNER_FUNCTION_PRECOMPILE_ADDRESS as u64); +} diff --git a/crates/zkevm_opcode_defs/src/utils.rs b/crates/zkevm_opcode_defs/src/utils.rs new file mode 100644 index 0000000..e265f23 --- /dev/null +++ b/crates/zkevm_opcode_defs/src/utils.rs @@ -0,0 +1,61 @@ +use crate::decoding::{EncodingModeProduction, VmEncodingMode}; + +pub const fn split_as_u4(value: u8) -> (u8, u8) { + (value & ((1u8 << 4) - 1), value >> 4) +} + +pub const fn merge_u4(low: u8, high: u8) -> u8 { + debug_assert!(low < 16); + debug_assert!(high < 16); + low | (high << 4) +} + +/// Internally we use versioned hash by our convensions +pub fn bytecode_to_code_hash(bytecode_words: &[[u8; 32]]) -> Result<[u8; 32], ()> { + bytecode_to_code_hash_for_mode::<8, EncodingModeProduction>(bytecode_words) +} + +/// Internally we use versioned hash by our convensions +pub fn bytecode_to_code_hash_for_mode>( + bytecode_words: &[[u8; 32]], +) -> Result<[u8; 32], ()> { + // bytecode should have an odd number of 32-byte words for ease of use of SHA256 round function + if bytecode_words.len() % 2 != 1 { + return Err(()); + } + + // limit of the bytecode length can be different in different modes + use crate::decoding::AllowedPcOrImm; + + if bytecode_words.len() as u64 > E::PcOrImm::max().as_u64() { + return Err(()); + } + + use sha2::{Digest, Sha256}; + + let mut hasher = Sha256::new(); + for w in bytecode_words.iter() { + hasher.update(&w); + } + + let result = hasher.finalize(); + + let mut output = [0u8; 32]; + output[..].copy_from_slice(&result.as_slice()); + + use crate::{ContractCodeSha256, VersionedHashGeneric}; + + // this is invalid for modes other than production, but not that important + // because testing mode doesn't do strict decommittments + + let versioned_hash = + VersionedHashGeneric::::from_digest_and_preimage_num_words( + output, + bytecode_words.len() as u16, + ); + // this will place all the byte markers, lengths, etc + + let versioned_hash_bytes = versioned_hash.serialize().ok_or(())?; + + Ok(versioned_hash_bytes) +} From f3f48974742123d3328eaffb5cbb6bf5246a9fb6 Mon Sep 17 00:00:00 2001 From: Igor Aleksanov Date: Thu, 15 Aug 2024 13:56:56 +0400 Subject: [PATCH 2/7] Historical release: v0.133.0 --- crates/circuit_sequencer_api/.gitignore | 2 + crates/circuit_sequencer_api/Cargo.toml | 26 + crates/circuit_sequencer_api/README.md | 3 + crates/circuit_sequencer_api/src/lib.rs | 4 + crates/circuit_sequencer_api/src/proof.rs | 25 + .../src/sort_storage_access.rs | 330 ++++ .../.github/workflows/cargo-license.yaml | 4 +- crates/zk_evm/.github/workflows/ci.yaml | 2 +- crates/zk_evm/CONTRIBUTING.md | 45 +- crates/zk_evm/Cargo.toml | 11 +- crates/zk_evm/README.md | 2 +- crates/zk_evm/eraLogo.png | Bin 0 -> 79091 bytes crates/zk_evm/src/lib.rs | 28 +- crates/zk_evm/src/opcodes/execution/add.rs | 11 +- crates/zk_evm/src/opcodes/execution/binop.rs | 11 +- .../zk_evm/src/opcodes/execution/context.rs | 11 +- crates/zk_evm/src/opcodes/execution/div.rs | 11 +- .../zk_evm/src/opcodes/execution/far_call.rs | 87 +- crates/zk_evm/src/opcodes/execution/jump.rs | 11 +- crates/zk_evm/src/opcodes/execution/log.rs | 22 +- crates/zk_evm/src/opcodes/execution/mod.rs | 2 - crates/zk_evm/src/opcodes/execution/mul.rs | 11 +- .../zk_evm/src/opcodes/execution/near_call.rs | 12 +- crates/zk_evm/src/opcodes/execution/noop.rs | 11 +- crates/zk_evm/src/opcodes/execution/ptr.rs | 11 +- crates/zk_evm/src/opcodes/execution/ret.rs | 18 +- crates/zk_evm/src/opcodes/execution/shift.rs | 11 +- crates/zk_evm/src/opcodes/execution/sub.rs | 11 +- crates/zk_evm/src/opcodes/execution/uma.rs | 14 +- crates/zk_evm/src/opcodes/parsing.rs | 19 +- .../zk_evm/src/reference_impls/decommitter.rs | 22 +- .../zk_evm/src/reference_impls/event_sink.rs | 1 + crates/zk_evm/src/reference_impls/memory.rs | 42 +- crates/zk_evm/src/reference_impls/mod.rs | 2 - crates/zk_evm/src/testing/debug_tracer.rs | 66 +- crates/zk_evm/src/testing/mod.rs | 21 +- crates/zk_evm/src/testing/simple_tracer.rs | 5 +- crates/zk_evm/src/testing/storage.rs | 3 + crates/zk_evm/src/testing/tests/mod.rs | 11 +- crates/zk_evm/src/testing/tests/trivial.rs | 11 +- crates/zk_evm/src/tests/assembly.rs | 468 +++++ crates/zk_evm/src/tests/mod.rs | 1750 +++++++++++++++++ .../zk_evm/src/{abstractions => }/tracing.rs | 23 +- crates/zk_evm/src/utils.rs | 7 +- crates/zk_evm/src/vm_state/cycle.rs | 31 +- crates/zk_evm/src/vm_state/execution_stack.rs | 1 - crates/zk_evm/src/vm_state/helpers.rs | 41 +- crates/zk_evm/src/vm_state/mem_ops.rs | 15 +- crates/zk_evm/src/vm_state/mod.rs | 24 +- crates/zk_evm/src/witness_trace/mod.rs | 6 +- .../.github/ISSUE_TEMPLATE/bug_report.md | 39 + .../.github/ISSUE_TEMPLATE/feature_request.md | 21 + .../.github/pull_request_template.md | 20 + .../.github/workflows/cargo-license.yaml | 8 + .../.github/workflows/ci.yaml | 23 + .../.github/workflows/secrets_scanner.yaml | 17 + crates/zk_evm_abstractions/.gitignore | 2 + crates/zk_evm_abstractions/CONTRIBUTING.md | 44 + crates/zk_evm_abstractions/Cargo.toml | 24 + crates/zk_evm_abstractions/LICENSE-APACHE | 176 ++ crates/zk_evm_abstractions/LICENSE-MIT | 21 + crates/zk_evm_abstractions/README.md | 33 + crates/zk_evm_abstractions/SECURITY.md | 74 + crates/zk_evm_abstractions/deny.toml | 78 + crates/zk_evm_abstractions/eraLogo.png | Bin 0 -> 79091 bytes .../src/auxiliary.rs} | 8 +- crates/zk_evm_abstractions/src/lib.rs | 5 + .../src/precompiles/ecrecover.rs | 45 +- .../src/precompiles/keccak256.rs | 45 +- .../src/precompiles/mod.rs | 46 +- .../src/precompiles/sha256.rs | 31 +- .../src}/queries.rs | 11 +- .../mod.rs => zk_evm_abstractions/src/vm.rs} | 57 +- crates/zkevm_opcode_defs/CONTRIBUTING.md | 45 +- crates/zkevm_opcode_defs/Cargo.toml | 9 +- crates/zkevm_opcode_defs/deny.toml | 4 +- .../zkevm_opcode_defs/src/circuit_prices.rs | 4 +- .../src/circuit_pricing_generator/main.rs | 28 +- .../src/definitions/abi/fat_pointer.rs | 7 + .../src/definitions/far_call.rs | 9 +- .../zkevm_opcode_defs/src/definitions/log.rs | 13 +- crates/zkevm_opcode_defs/src/lib.rs | 7 +- crates/zkevm_opcode_defs/src/system_params.rs | 40 +- 83 files changed, 3818 insertions(+), 492 deletions(-) create mode 100644 crates/circuit_sequencer_api/.gitignore create mode 100644 crates/circuit_sequencer_api/Cargo.toml create mode 100644 crates/circuit_sequencer_api/README.md create mode 100644 crates/circuit_sequencer_api/src/lib.rs create mode 100644 crates/circuit_sequencer_api/src/proof.rs create mode 100644 crates/circuit_sequencer_api/src/sort_storage_access.rs create mode 100644 crates/zk_evm/eraLogo.png create mode 100644 crates/zk_evm/src/tests/assembly.rs create mode 100644 crates/zk_evm/src/tests/mod.rs rename crates/zk_evm/src/{abstractions => }/tracing.rs (82%) create mode 100644 crates/zk_evm_abstractions/.github/ISSUE_TEMPLATE/bug_report.md create mode 100644 crates/zk_evm_abstractions/.github/ISSUE_TEMPLATE/feature_request.md create mode 100644 crates/zk_evm_abstractions/.github/pull_request_template.md create mode 100644 crates/zk_evm_abstractions/.github/workflows/cargo-license.yaml create mode 100644 crates/zk_evm_abstractions/.github/workflows/ci.yaml create mode 100644 crates/zk_evm_abstractions/.github/workflows/secrets_scanner.yaml create mode 100644 crates/zk_evm_abstractions/.gitignore create mode 100644 crates/zk_evm_abstractions/CONTRIBUTING.md create mode 100644 crates/zk_evm_abstractions/Cargo.toml create mode 100644 crates/zk_evm_abstractions/LICENSE-APACHE create mode 100644 crates/zk_evm_abstractions/LICENSE-MIT create mode 100644 crates/zk_evm_abstractions/README.md create mode 100644 crates/zk_evm_abstractions/SECURITY.md create mode 100644 crates/zk_evm_abstractions/deny.toml create mode 100644 crates/zk_evm_abstractions/eraLogo.png rename crates/{zk_evm/src/aux_structures/mod.rs => zk_evm_abstractions/src/auxiliary.rs} (97%) create mode 100644 crates/zk_evm_abstractions/src/lib.rs rename crates/{zk_evm => zk_evm_abstractions}/src/precompiles/ecrecover.rs (93%) rename crates/{zk_evm => zk_evm_abstractions}/src/precompiles/keccak256.rs (93%) rename crates/{zk_evm => zk_evm_abstractions}/src/precompiles/mod.rs (80%) rename crates/{zk_evm => zk_evm_abstractions}/src/precompiles/sha256.rs (91%) rename crates/{zk_evm/src/aux_structures => zk_evm_abstractions/src}/queries.rs (93%) rename crates/{zk_evm/src/abstractions/mod.rs => zk_evm_abstractions/src/vm.rs} (85%) diff --git a/crates/circuit_sequencer_api/.gitignore b/crates/circuit_sequencer_api/.gitignore new file mode 100644 index 0000000..869df07 --- /dev/null +++ b/crates/circuit_sequencer_api/.gitignore @@ -0,0 +1,2 @@ +/target +Cargo.lock \ No newline at end of file diff --git a/crates/circuit_sequencer_api/Cargo.toml b/crates/circuit_sequencer_api/Cargo.toml new file mode 100644 index 0000000..3a8b4e1 --- /dev/null +++ b/crates/circuit_sequencer_api/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "circuit_sequencer_api" +version = "0.133.0" +edition = "2021" +authors = ["The Matter Labs Team "] +homepage = "https://zksync.io/" +repository = "https://github.com/matter-labs/era-zkevm_circuits" +license = "MIT OR Apache-2.0" +keywords = ["blockchain", "zksync"] +categories = ["cryptography"] +description = "ZKsync Era circuits for EraVM" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] + +zk_evm = { version = "=0.133.0", path = "../zk_evm" } +bellman = { package = "bellman_ce", version = "=0.7.0" } + +derivative = "2.2" +serde = {version = "1", features = ["derive"]} +rayon = "1.10" + + +[features] +default = [] diff --git a/crates/circuit_sequencer_api/README.md b/crates/circuit_sequencer_api/README.md new file mode 100644 index 0000000..3be5245 --- /dev/null +++ b/crates/circuit_sequencer_api/README.md @@ -0,0 +1,3 @@ +# circuit sequencer api + +Crate that can be used directly by the sequencer, without all the proving details. diff --git a/crates/circuit_sequencer_api/src/lib.rs b/crates/circuit_sequencer_api/src/lib.rs new file mode 100644 index 0000000..1f4fee4 --- /dev/null +++ b/crates/circuit_sequencer_api/src/lib.rs @@ -0,0 +1,4 @@ +pub mod proof; +pub mod sort_storage_access; + +pub const INITIAL_MONOTONIC_CYCLE_COUNTER: u32 = 1024; diff --git a/crates/circuit_sequencer_api/src/proof.rs b/crates/circuit_sequencer_api/src/proof.rs new file mode 100644 index 0000000..3cceffb --- /dev/null +++ b/crates/circuit_sequencer_api/src/proof.rs @@ -0,0 +1,25 @@ +use bellman::{ + bn256::Bn256, + plonk::better_better_cs::{ + cs::{Circuit, Width4MainGateWithDNext}, + proof::Proof, + }, +}; + +// Wrapper for the final scheduler proof. +// We use generic circuit here, as this is used only for serializing & deserializing in sequencer. +pub type FinalProof = Proof; + +#[derive(Clone)] +pub struct GenericCircuit {} + +impl Circuit for GenericCircuit { + type MainGate = Width4MainGateWithDNext; + + fn synthesize>( + &self, + _: &mut CS, + ) -> Result<(), bellman::SynthesisError> { + Ok(()) + } +} diff --git a/crates/circuit_sequencer_api/src/sort_storage_access.rs b/crates/circuit_sequencer_api/src/sort_storage_access.rs new file mode 100644 index 0000000..f02232e --- /dev/null +++ b/crates/circuit_sequencer_api/src/sort_storage_access.rs @@ -0,0 +1,330 @@ +use derivative::Derivative; +use rayon::prelude::*; +use std::cmp::Ordering; +use std::iter::IntoIterator; +use zk_evm::{ + aux_structures::{LogQuery, Timestamp}, + ethereum_types::{H160, U256}, +}; + +#[derive(Derivative)] +#[derivative(Default(bound = ""), Debug)] +pub struct StorageSlotHistoryKeeper { + pub initial_value: Option, + pub current_value: Option, + pub changes_stack: Vec>, + pub did_read_at_depth_zero: bool, +} + +// Proxy, as we just need read-only +pub trait LogQueryLike: 'static + Clone + Send + Sync + std::fmt::Debug { + fn shard_id(&self) -> u8; + fn address(&self) -> H160; + fn key(&self) -> U256; + fn rw_flag(&self) -> bool; + fn rollback(&self) -> bool; + fn read_value(&self) -> U256; + fn written_value(&self) -> U256; + fn create_partially_filled_from_fields( + shard_id: u8, + address: H160, + key: U256, + read_value: U256, + written_value: U256, + rw_flag: bool, + ) -> Self; +} + +impl LogQueryLike for LogQuery { + fn shard_id(&self) -> u8 { + self.shard_id + } + fn address(&self) -> H160 { + self.address + } + fn key(&self) -> U256 { + self.key + } + fn rw_flag(&self) -> bool { + self.rw_flag + } + fn rollback(&self) -> bool { + self.rollback + } + fn read_value(&self) -> U256 { + self.read_value + } + fn written_value(&self) -> U256 { + self.written_value + } + fn create_partially_filled_from_fields( + shard_id: u8, + address: H160, + key: U256, + read_value: U256, + written_value: U256, + rw_flag: bool, + ) -> Self { + // only smaller number of field matters in practice + LogQuery { + timestamp: Timestamp(0), + tx_number_in_block: 0, + aux_byte: 0, + shard_id, + address, + key, + read_value, + written_value, + rw_flag, + rollback: false, + is_service: false, + } + } +} + +#[derive(Clone, Debug)] +pub struct LogQueryLikeWithExtendedEnumeration { + pub raw_query: L, + pub extended_timestamp: u32, +} + +pub fn sort_storage_access_queries<'a, L: LogQueryLike, I: IntoIterator>( + unsorted_storage_queries: I, +) -> (Vec>, Vec) { + let mut sorted_storage_queries_with_extra_timestamp: Vec<_> = unsorted_storage_queries + .into_iter() + .enumerate() + .map(|(i, el)| LogQueryLikeWithExtendedEnumeration { + raw_query: el.clone(), + extended_timestamp: i as u32, + }) + .collect(); + + sorted_storage_queries_with_extra_timestamp.par_sort_by(|a, b| { + match a.raw_query.shard_id().cmp(&a.raw_query.shard_id()) { + Ordering::Equal => match a.raw_query.address().cmp(&b.raw_query.address()) { + Ordering::Equal => match a.raw_query.key().cmp(&b.raw_query.key()) { + Ordering::Equal => a.extended_timestamp.cmp(&b.extended_timestamp), + r @ _ => r, + }, + r @ _ => r, + }, + r @ _ => r, + } + }); + + let mut deduplicated_storage_queries = vec![]; + + // now just implement the logic to sort and deduplicate + let mut it = sorted_storage_queries_with_extra_timestamp + .iter() + .peekable(); + + loop { + if it.peek().is_none() { + break; + } + + let candidate = (*it.peek().unwrap()).clone(); + + let subit = it.clone().take_while(|el| { + el.raw_query.shard_id() == candidate.raw_query.shard_id() + && el.raw_query.address() == candidate.raw_query.address() + && el.raw_query.key() == candidate.raw_query.key() + }); + + let mut current_element_history = StorageSlotHistoryKeeper::::default(); + + for (_idx, el) in subit.enumerate() { + let _ = it.next().unwrap(); + + if current_element_history.current_value.is_none() { + assert!( + current_element_history.initial_value.is_none(), + "invalid for query {:?}", + el + ); + // first read potentially + if el.raw_query.rw_flag() == false { + current_element_history.did_read_at_depth_zero = true; + } + } else { + // explicit read at zero + if el.raw_query.rw_flag() == false + && current_element_history.changes_stack.is_empty() + { + current_element_history.did_read_at_depth_zero = true; + } + } + + if current_element_history.current_value.is_none() { + assert!( + current_element_history.initial_value.is_none(), + "invalid for query {:?}", + el + ); + if el.raw_query.rw_flag() == false { + current_element_history.initial_value = Some(el.raw_query.read_value()); + current_element_history.current_value = Some(el.raw_query.read_value()); + } else { + assert!(el.raw_query.rollback() == false); + current_element_history.initial_value = Some(el.raw_query.read_value()); + current_element_history.current_value = Some(el.raw_query.read_value()); + // note: We apply updates few lines later + } + } + + if el.raw_query.rw_flag() == false { + assert_eq!( + &el.raw_query.read_value(), + current_element_history.current_value.as_ref().unwrap(), + "invalid for query {:?}", + el + ); + // and do not place reads into the stack + } else { + // write-like things manipulate the stack + if el.raw_query.rollback() == false { + // write and push to the stack + assert_eq!( + &el.raw_query.read_value(), + current_element_history.current_value.as_ref().unwrap(), + "invalid for query {:?}", + el + ); + current_element_history.current_value = Some(el.raw_query.written_value()); + current_element_history.changes_stack.push(el.clone()); + } else { + // pop from stack and self-check + let popped_change = current_element_history.changes_stack.pop().unwrap(); + // we do not explicitly swap values, and use rollback flag instead, so compare this way + assert_eq!( + el.raw_query.read_value(), + popped_change.raw_query.read_value(), + "invalid for query {:?}", + el + ); + assert_eq!( + el.raw_query.written_value(), + popped_change.raw_query.written_value(), + "invalid for query {:?}", + el + ); + assert_eq!( + &el.raw_query.written_value(), + current_element_history.current_value.as_ref().unwrap(), + "invalid for query {:?}", + el + ); + // check that we properly apply rollbacks + assert_eq!( + el.raw_query.shard_id(), + popped_change.raw_query.shard_id(), + "invalid for query {:?}", + el + ); + assert_eq!( + el.raw_query.address(), + popped_change.raw_query.address(), + "invalid for query {:?}", + el + ); + assert_eq!( + el.raw_query.key(), + popped_change.raw_query.key(), + "invalid for query {:?}", + el + ); + // apply rollback + current_element_history.current_value = Some(el.raw_query.read_value()); + // our convension + } + } + } + + if current_element_history.did_read_at_depth_zero == false + && current_element_history.changes_stack.is_empty() + { + // whatever happened there didn't produce any final changes + assert_eq!( + current_element_history.initial_value.unwrap(), + current_element_history.current_value.unwrap() + ); + // here we know that last write was a rollback, and there we no reads after it (otherwise "did_read_at_depth_zero" == true), + // so whatever was an initial value in storage slot it's not ever observed, and we do not need to issue even read here + continue; + } else { + if current_element_history.initial_value.unwrap() + == current_element_history.current_value.unwrap() + { + // no change, but we may need protective read + if current_element_history.did_read_at_depth_zero { + // protective read + let sorted_log_query = L::create_partially_filled_from_fields( + candidate.raw_query.shard_id(), + candidate.raw_query.address(), + candidate.raw_query.key(), + current_element_history.initial_value.unwrap(), + current_element_history.current_value.unwrap(), + false, + ); + + deduplicated_storage_queries.push(sorted_log_query); + } else { + // we didn't read at depth zero, so it's something like + // - write cell from a into b + // .... + // - write cell from b into a + + // There is a catch here: + // - if it's two "normal" writes, then operator can claim that initial value + // was "a", but it could have been some other, and in this case we want to + // "read" that it was indeed "a" + // - but if the latest "write" was just a rollback, + // then we know that it's basically NOP. We already had a branch above that + // protects us in case of write - rollback - read, so we only need to degrade write into + // read here if the latest write wasn't a rollback + + if current_element_history.changes_stack.is_empty() == false { + // it means that we did accumlate some changes, even though in NET result + // it CLAIMS that it didn't change a value + // degrade to protective read + let sorted_log_query = L::create_partially_filled_from_fields( + candidate.raw_query.shard_id(), + candidate.raw_query.address(), + candidate.raw_query.key(), + current_element_history.initial_value.unwrap(), + current_element_history.current_value.unwrap(), + false, + ); + + deduplicated_storage_queries.push(sorted_log_query); + } else { + // Whatever has happened we rolled it back completely, so unless + // there was a need for protective read at depth 0, we do not need + // to go into storage and check or change any value + + // we just do nothing! + } + } + } else { + // it's final net write + let sorted_log_query = L::create_partially_filled_from_fields( + candidate.raw_query.shard_id(), + candidate.raw_query.address(), + candidate.raw_query.key(), + current_element_history.initial_value.unwrap(), + current_element_history.current_value.unwrap(), + true, + ); + + deduplicated_storage_queries.push(sorted_log_query); + } + } + } + + ( + sorted_storage_queries_with_extra_timestamp, + deduplicated_storage_queries, + ) +} diff --git a/crates/zk_evm/.github/workflows/cargo-license.yaml b/crates/zk_evm/.github/workflows/cargo-license.yaml index d6ee929..189b471 100644 --- a/crates/zk_evm/.github/workflows/cargo-license.yaml +++ b/crates/zk_evm/.github/workflows/cargo-license.yaml @@ -1,5 +1,5 @@ -name: CI -on: [push, pull_request] +name: Cargo license check +on: pull_request jobs: cargo-deny: runs-on: ubuntu-latest diff --git a/crates/zk_evm/.github/workflows/ci.yaml b/crates/zk_evm/.github/workflows/ci.yaml index 8b2b519..bd002d8 100644 --- a/crates/zk_evm/.github/workflows/ci.yaml +++ b/crates/zk_evm/.github/workflows/ci.yaml @@ -10,7 +10,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions-rust-lang/setup-rust-toolchain@v1 with: - toolchain: nightly-2023-04-17 + toolchain: stable - run: cargo build --verbose --all-features - run: RUSTFLAGS="-Awarnings" cargo test --verbose --all-features diff --git a/crates/zk_evm/CONTRIBUTING.md b/crates/zk_evm/CONTRIBUTING.md index dd3d458..f129e60 100644 --- a/crates/zk_evm/CONTRIBUTING.md +++ b/crates/zk_evm/CONTRIBUTING.md @@ -1,44 +1,9 @@ # Contribution Guidelines -Hello! Thanks for your interest in joining the mission to accelerate the mass adoption of crypto for personal -sovereignty! We welcome contributions from anyone on the internet, and are grateful for even the smallest of fixes! +Thank you for considering helping out with the source code! We are extremely grateful for any consideration of +contributions to this repository. However, at this time, we generally do not accept external contributions. This policy +will change in the future, so please check back regularly for updates. -## Ways to contribute +For security issues, please contact us at [security@matterlabs.dev](mailto:security@matterlabs.dev). -There are many ways to contribute to the ZK Stack: - -1. Open issues: if you find a bug, have something you believe needs to be fixed, or have an idea for a feature, please - open an issue. -2. Add color to existing issues: provide screenshots, code snippets, and whatever you think would be helpful to resolve - issues. -3. Resolve issues: either by showing an issue isn't a problem and the current state is ok as is or by fixing the problem - and opening a PR. -4. Report security issues, see [our security policy](./github/SECURITY.md). -5. [Join the team!](https://matterlabs.notion.site/Shape-the-future-of-Ethereum-at-Matter-Labs-dfb3b5a037044bb3a8006af2eb0575e0) - -## Fixing issues - -To contribute code fixing issues, please fork the repo, fix an issue, commit, add documentation as per the PR template, -and the repo's maintainers will review the PR. -[here](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork) -for guidance how to work with PRs created from a fork. - -## Licenses - -If you contribute to this project, your contributions will be made to the project under both Apache 2.0 and the MIT -license. - -## Resources - -We aim to make it as easy as possible to contribute to the mission. This is still WIP, and we're happy for contributions -and suggestions here too. Some resources to help: - -1. [In-repo docs aimed at developers](docs) -2. [zkSync Era docs!](https://era.zksync.io/docs/) -3. Company links can be found in the [repo's readme](README.md) - -## Code of Conduct - -Be polite and respectful. - -### Thank you +Thank you for your support in accelerating the mass adoption of crypto for personal sovereignty! diff --git a/crates/zk_evm/Cargo.toml b/crates/zk_evm/Cargo.toml index ebd1829..dbfbd54 100644 --- a/crates/zk_evm/Cargo.toml +++ b/crates/zk_evm/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zk_evm" -version = "0.131.0-rc.2" +version = "0.133.0" edition = "2021" authors = ["The Matter Labs Team "] homepage = "https://zksync.io/" @@ -13,16 +13,13 @@ description = "ZKsync out-of-circuit EraEVM implementation" resolver = "2" [dependencies] -zkevm_opcode_defs = { version = "=0.131.0", path = "../zkevm_opcode_defs" } - serde = { version = "1", features = ["derive"] } serde_json = "1.0" +anyhow = "1.0" num = { version = "0.4"} -sha3 = { package = "sha3_ce", version = "=0.10.6" } -sha2 = { package = "sha2_ce", version = "=0.10.6" } -blake2 = { package = "blake2_ce", version = "=0.10.6" } -k256 = { version = "0.11", features = ["arithmetic", "ecdsa"] } static_assertions = "1" +zkevm_opcode_defs = { version = "=0.132.0", path = "../zkevm_opcode_defs" } +zk_evm_abstractions = { version = "=0.140.0", path = "../zk_evm_abstractions" } lazy_static = "1.4" [dev-dependencies] diff --git a/crates/zk_evm/README.md b/crates/zk_evm/README.md index a14bca9..bb94174 100644 --- a/crates/zk_evm/README.md +++ b/crates/zk_evm/README.md @@ -1,6 +1,6 @@ # zkSync Era: A ZK Rollup For Scaling Ethereum -[![Logo](eraLogo.svg)](https://zksync.io/) +[![Logo](eraLogo.png)](https://zksync.io/) zkSync Era is a layer 2 rollup that uses zero-knowledge proofs to scale Ethereum without compromising on security or decentralization. Since it's EVM compatible (Solidity/Vyper), 99% of Ethereum projects can redeploy without refactoring diff --git a/crates/zk_evm/eraLogo.png b/crates/zk_evm/eraLogo.png new file mode 100644 index 0000000000000000000000000000000000000000..5d9480d8f05342a06cd1ee03405137552bdbebbf GIT binary patch literal 79091 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 DecodedOpcode { pub fn add_opcode_apply< - S: crate::abstractions::Storage, - M: crate::abstractions::Memory, - EV: crate::abstractions::EventSink, - PP: crate::abstractions::PrecompilesProcessor, - DP: crate::abstractions::DecommittmentProcessor, + 'a, + S: zk_evm_abstractions::vm::Storage, + M: zk_evm_abstractions::vm::Memory, + EV: zk_evm_abstractions::vm::EventSink, + PP: zk_evm_abstractions::vm::PrecompilesProcessor, + DP: zk_evm_abstractions::vm::DecommittmentProcessor, WT: crate::witness_trace::VmWitnessTracer, >( &self, diff --git a/crates/zk_evm/src/opcodes/execution/binop.rs b/crates/zk_evm/src/opcodes/execution/binop.rs index fe0f624..9b834a3 100644 --- a/crates/zk_evm/src/opcodes/execution/binop.rs +++ b/crates/zk_evm/src/opcodes/execution/binop.rs @@ -3,11 +3,12 @@ use zkevm_opcode_defs::{BinopOpcode, Opcode}; impl> DecodedOpcode { pub fn binop_opcode_apply< - S: crate::abstractions::Storage, - M: crate::abstractions::Memory, - EV: crate::abstractions::EventSink, - PP: crate::abstractions::PrecompilesProcessor, - DP: crate::abstractions::DecommittmentProcessor, + 'a, + S: zk_evm_abstractions::vm::Storage, + M: zk_evm_abstractions::vm::Memory, + EV: zk_evm_abstractions::vm::EventSink, + PP: zk_evm_abstractions::vm::PrecompilesProcessor, + DP: zk_evm_abstractions::vm::DecommittmentProcessor, WT: crate::witness_trace::VmWitnessTracer, >( &self, diff --git a/crates/zk_evm/src/opcodes/execution/context.rs b/crates/zk_evm/src/opcodes/execution/context.rs index 34ace17..a6a3f9f 100644 --- a/crates/zk_evm/src/opcodes/execution/context.rs +++ b/crates/zk_evm/src/opcodes/execution/context.rs @@ -4,11 +4,12 @@ use zkevm_opcode_defs::{ContextOpcode, Opcode}; impl> DecodedOpcode { pub fn context_opcode_apply< - S: crate::abstractions::Storage, - M: crate::abstractions::Memory, - EV: crate::abstractions::EventSink, - PP: crate::abstractions::PrecompilesProcessor, - DP: crate::abstractions::DecommittmentProcessor, + 'a, + S: zk_evm_abstractions::vm::Storage, + M: zk_evm_abstractions::vm::Memory, + EV: zk_evm_abstractions::vm::EventSink, + PP: zk_evm_abstractions::vm::PrecompilesProcessor, + DP: zk_evm_abstractions::vm::DecommittmentProcessor, WT: crate::witness_trace::VmWitnessTracer, >( &self, diff --git a/crates/zk_evm/src/opcodes/execution/div.rs b/crates/zk_evm/src/opcodes/execution/div.rs index 0ef52d4..be5ff04 100644 --- a/crates/zk_evm/src/opcodes/execution/div.rs +++ b/crates/zk_evm/src/opcodes/execution/div.rs @@ -2,11 +2,12 @@ use super::*; impl> DecodedOpcode { pub fn div_opcode_apply< - S: crate::abstractions::Storage, - M: crate::abstractions::Memory, - EV: crate::abstractions::EventSink, - PP: crate::abstractions::PrecompilesProcessor, - DP: crate::abstractions::DecommittmentProcessor, + 'a, + S: zk_evm_abstractions::vm::Storage, + M: zk_evm_abstractions::vm::Memory, + EV: zk_evm_abstractions::vm::EventSink, + PP: zk_evm_abstractions::vm::PrecompilesProcessor, + DP: zk_evm_abstractions::vm::DecommittmentProcessor, WT: crate::witness_trace::VmWitnessTracer, >( &self, diff --git a/crates/zk_evm/src/opcodes/execution/far_call.rs b/crates/zk_evm/src/opcodes/execution/far_call.rs index da51cc0..d41c8f5 100644 --- a/crates/zk_evm/src/opcodes/execution/far_call.rs +++ b/crates/zk_evm/src/opcodes/execution/far_call.rs @@ -1,5 +1,9 @@ use super::*; +use zk_evm_abstractions::aux::MemoryPage; +use zk_evm_abstractions::aux::Timestamp; +use zk_evm_abstractions::queries::LogQuery; +use zk_evm_abstractions::vm::SpongeExecutionMarker; use zkevm_opcode_defs::definitions::far_call::*; use zkevm_opcode_defs::system_params::DEPLOYER_SYSTEM_CONTRACT_ADDRESS; use zkevm_opcode_defs::system_params::STORAGE_AUX_BYTE; @@ -8,6 +12,8 @@ use zkevm_opcode_defs::{INITIAL_SP_ON_FAR_CALL, UNMAPPED_PAGE}; use zkevm_opcode_defs::bitflags::bitflags; +pub const FORCED_ERGS_FOR_MSG_VALUE_SIMULATOR: bool = false; + bitflags! { pub struct FarCallExceptionFlags: u64 { const INPUT_IS_NOT_POINTER_WHEN_EXPECTED = 1u64 << 0; @@ -16,6 +22,7 @@ bitflags! { const NOT_ENOUGH_ERGS_TO_GROW_MEMORY = 1u64 << 3; const MALFORMED_ABI_QUASI_POINTER = 1u64 << 4; const CALL_IN_NOW_CONSTRUCTED_SYSTEM_CONTRACT = 1u64 << 5; + const NOTE_ENOUGH_ERGS_FOR_EXTRA_FAR_CALL_COSTS = 1u64 << 6; } } @@ -28,17 +35,18 @@ use zkevm_opcode_defs::{FarCallABI, FarCallForwardPageType, FarCallOpcode, FatPo impl> DecodedOpcode { pub fn far_call_opcode_apply< - S: crate::abstractions::Storage, - M: crate::abstractions::Memory, - EV: crate::abstractions::EventSink, - PP: crate::abstractions::PrecompilesProcessor, - DP: crate::abstractions::DecommittmentProcessor, + 'a, + S: zk_evm_abstractions::vm::Storage, + M: zk_evm_abstractions::vm::Memory, + EV: zk_evm_abstractions::vm::EventSink, + PP: zk_evm_abstractions::vm::PrecompilesProcessor, + DP: zk_evm_abstractions::vm::DecommittmentProcessor, WT: crate::witness_trace::VmWitnessTracer, >( &self, vm_state: &mut VmState, prestate: PreState, - ) { + ) -> anyhow::Result<()> { let PreState { src0, src1, @@ -113,7 +121,7 @@ impl> DecodedOpcode { // NOTE: our far-call MUST take ergs to cover storage read, but we also have a contribution // that depends on the actual code length, so we work with it here - let (mapped_code_page, ergs_after_code_read_and_exceptions_resolution) = { + let (mapped_code_page, ergs_after_code_read_and_exceptions_resolution, stipend_for_callee) = { let (code_hash, map_to_trivial) = if new_code_shard_id != 0 && !vm_state.block_properties.zkporter_is_available { @@ -276,9 +284,8 @@ impl> DecodedOpcode { // pointer is malformed exceptions.set(FarCallExceptionFlags::MALFORMED_ABI_QUASI_POINTER, true); } - if far_call_abi.memory_quasi_fat_pointer.validate_in_bounds() == false - && far_call_abi.memory_quasi_fat_pointer.is_trivial() == false - { + // this captures the case of empty slice + if far_call_abi.memory_quasi_fat_pointer.validate_as_slice() == false { exceptions.set(FarCallExceptionFlags::MALFORMED_ABI_QUASI_POINTER, true); } @@ -379,17 +386,52 @@ impl> DecodedOpcode { 0 }; + let mut msg_value_stipend = if FORCED_ERGS_FOR_MSG_VALUE_SIMULATOR == false { + 0 + } else { + if called_address_as_u256 == U256::from(zkevm_opcode_defs::ADDRESS_MSG_VALUE as u64) + && far_call_abi.to_system + { + // use that doesn't know what's doing is trying to call "transfer" + + let pubdata_related = vm_state.local_state.current_ergs_per_pubdata_byte.checked_mul( + zkevm_opcode_defs::system_params::MSG_VALUE_SIMULATOR_PUBDATA_BYTES_TO_PREPAY + ).expect("must fit into u32"); + pubdata_related + .checked_add( + zkevm_opcode_defs::system_params::MSG_VALUE_SIMULATOR_ADDITIVE_COST, + ) + .expect("must not overflow") + } else { + 0 + } + }; + + let remaining_ergs_of_caller_frame = if remaining_ergs_after_growth >= msg_value_stipend + { + remaining_ergs_after_growth - msg_value_stipend + } else { + exceptions.set( + FarCallExceptionFlags::NOTE_ENOUGH_ERGS_FOR_EXTRA_FAR_CALL_COSTS, + true, + ); + // if tried to take and failed, but should not add it later on in this case + msg_value_stipend = 0; + + 0 + }; + // we mask instead of branching let cost_of_decommittment = zkevm_opcode_defs::ERGS_PER_CODE_WORD_DECOMMITTMENT * code_length_in_words; let mut remaining_ergs_after_decommittment = - if remaining_ergs_after_growth >= cost_of_decommittment { - remaining_ergs_after_growth - cost_of_decommittment + if remaining_ergs_of_caller_frame >= cost_of_decommittment { + remaining_ergs_of_caller_frame - cost_of_decommittment } else { exceptions.set(FarCallExceptionFlags::NOT_ENOUGH_ERGS_TO_DECOMMIT, true); - remaining_ergs_after_growth // do not burn, as it's irrelevant - we just will not perform a decommittment and call + remaining_ergs_of_caller_frame // do not burn, as it's irrelevant - we just will not perform a decommittment and call }; let code_memory_page = if exceptions.is_empty() == false { @@ -405,7 +447,7 @@ impl> DecodedOpcode { code_hash, memory_page_candidate_for_code_decommittment, timestamp_for_decommit, - ); + )?; vm_state.witness_tracer.add_sponge_marker( vm_state.local_state.monotonic_cycle_counter, SpongeExecutionMarker::DecommittmentQuery, @@ -421,9 +463,15 @@ impl> DecodedOpcode { processed_decommittment_query.memory_page }; - (code_memory_page, remaining_ergs_after_decommittment) + ( + code_memory_page, + remaining_ergs_after_decommittment, + msg_value_stipend, + ) }; + // we have taken everything that we want from caller and now can try to pass to callee + // resolve passed ergs, by using a value afte decommittment cost is taken let remaining_ergs_to_pass = ergs_after_code_read_and_exceptions_resolution; let max_passable = (remaining_ergs_to_pass / 64) * 63; // so callee will always have some @@ -443,6 +491,9 @@ impl> DecodedOpcode { } }; + // can not overflow + let passed_ergs = passed_ergs.wrapping_add(stipend_for_callee); + // update current ergs and PC vm_state .local_state @@ -509,8 +560,8 @@ impl> DecodedOpcode { is_static: new_context_is_static, is_local_frame: false, context_u128_value: context_u128_for_next, - heap_bound: 0u32, - aux_heap_bound: 0u32, + heap_bound: zkevm_opcode_defs::system_params::NEW_FRAME_MEMORY_STIPEND, + aux_heap_bound: zkevm_opcode_defs::system_params::NEW_FRAME_MEMORY_STIPEND, }; // zero out the temporary register if it was not trivial @@ -576,5 +627,7 @@ impl> DecodedOpcode { } vm_state.local_state.registers[CALL_IMPLICIT_PARAMETER_REG_IDX as usize] = PrimitiveValue::empty(); + + Ok(()) } } diff --git a/crates/zk_evm/src/opcodes/execution/jump.rs b/crates/zk_evm/src/opcodes/execution/jump.rs index f265de1..85cc4dc 100644 --- a/crates/zk_evm/src/opcodes/execution/jump.rs +++ b/crates/zk_evm/src/opcodes/execution/jump.rs @@ -2,11 +2,12 @@ use super::*; impl> DecodedOpcode { pub fn jump_opcode_apply< - S: crate::abstractions::Storage, - M: crate::abstractions::Memory, - EV: crate::abstractions::EventSink, - PP: crate::abstractions::PrecompilesProcessor, - DP: crate::abstractions::DecommittmentProcessor, + 'a, + S: zk_evm_abstractions::vm::Storage, + M: zk_evm_abstractions::vm::Memory, + EV: zk_evm_abstractions::vm::EventSink, + PP: zk_evm_abstractions::vm::PrecompilesProcessor, + DP: zk_evm_abstractions::vm::DecommittmentProcessor, WT: crate::witness_trace::VmWitnessTracer, >( &self, diff --git a/crates/zk_evm/src/opcodes/execution/log.rs b/crates/zk_evm/src/opcodes/execution/log.rs index 26d2a47..5913d4b 100644 --- a/crates/zk_evm/src/opcodes/execution/log.rs +++ b/crates/zk_evm/src/opcodes/execution/log.rs @@ -1,5 +1,8 @@ use super::*; +use zk_evm_abstractions::aux::Timestamp; +use zk_evm_abstractions::queries::LogQuery; +use zk_evm_abstractions::vm::SpongeExecutionMarker; use zkevm_opcode_defs::{ LogOpcode, Opcode, PrecompileCallABI, PrecompileCallInnerABI, FIRST_MESSAGE_FLAG_IDX, }; @@ -10,11 +13,12 @@ use zkevm_opcode_defs::system_params::{ impl> DecodedOpcode { pub fn log_opcode_apply< - S: crate::abstractions::Storage, - M: crate::abstractions::Memory, - EV: crate::abstractions::EventSink, - PP: crate::abstractions::PrecompilesProcessor, - DP: crate::abstractions::DecommittmentProcessor, + 'a, + S: zk_evm_abstractions::vm::Storage, + M: zk_evm_abstractions::vm::Memory, + EV: zk_evm_abstractions::vm::EventSink, + PP: zk_evm_abstractions::vm::PrecompilesProcessor, + DP: zk_evm_abstractions::vm::DecommittmentProcessor, WT: crate::witness_trace::VmWitnessTracer, >( &self, @@ -64,6 +68,8 @@ impl> DecodedOpcode { .get_current_stack() .ergs_remaining; let is_rollup = shard_id == 0; + let timestamp_for_log = vm_state.timestamp_for_first_decommit_or_precompile_read(); + let tx_number_in_block = vm_state.local_state.tx_number_in_block; let ergs_on_pubdata = match inner_variant { LogOpcode::StorageWrite => { @@ -79,8 +85,8 @@ impl> DecodedOpcode { // for oracle to do estimations let partial_query = LogQuery { - timestamp: Timestamp(0u32), - tx_number_in_block: 0u16, + timestamp: timestamp_for_log, + tx_number_in_block, aux_byte: STORAGE_AUX_BYTE, shard_id, address, @@ -152,8 +158,6 @@ impl> DecodedOpcode { let address = current_context.this_address; let shard_id = current_context.this_shard_id; drop(current_context); - let tx_number_in_block = vm_state.local_state.tx_number_in_block; - let timestamp_for_log = vm_state.timestamp_for_first_decommit_or_precompile_read(); match inner_variant { LogOpcode::StorageRead => { assert!(not_enough_power == false); diff --git a/crates/zk_evm/src/opcodes/execution/mod.rs b/crates/zk_evm/src/opcodes/execution/mod.rs index 31a47d7..0981481 100644 --- a/crates/zk_evm/src/opcodes/execution/mod.rs +++ b/crates/zk_evm/src/opcodes/execution/mod.rs @@ -1,6 +1,4 @@ use super::*; -use crate::abstractions::SpongeExecutionMarker; -use crate::aux_structures::*; use crate::vm_state::*; use zkevm_opcode_defs::decoding::AllowedPcOrImm; use zkevm_opcode_defs::decoding::VmEncodingMode; diff --git a/crates/zk_evm/src/opcodes/execution/mul.rs b/crates/zk_evm/src/opcodes/execution/mul.rs index 6ba3526..49469ce 100644 --- a/crates/zk_evm/src/opcodes/execution/mul.rs +++ b/crates/zk_evm/src/opcodes/execution/mul.rs @@ -2,11 +2,12 @@ use super::*; impl> DecodedOpcode { pub fn mul_opcode_apply< - S: crate::abstractions::Storage, - M: crate::abstractions::Memory, - EV: crate::abstractions::EventSink, - PP: crate::abstractions::PrecompilesProcessor, - DP: crate::abstractions::DecommittmentProcessor, + 'a, + S: zk_evm_abstractions::vm::Storage, + M: zk_evm_abstractions::vm::Memory, + EV: zk_evm_abstractions::vm::EventSink, + PP: zk_evm_abstractions::vm::PrecompilesProcessor, + DP: zk_evm_abstractions::vm::DecommittmentProcessor, WT: crate::witness_trace::VmWitnessTracer, >( &self, diff --git a/crates/zk_evm/src/opcodes/execution/near_call.rs b/crates/zk_evm/src/opcodes/execution/near_call.rs index 3b680da..8549893 100644 --- a/crates/zk_evm/src/opcodes/execution/near_call.rs +++ b/crates/zk_evm/src/opcodes/execution/near_call.rs @@ -1,14 +1,16 @@ +use zk_evm_abstractions::vm::SpongeExecutionMarker; use zkevm_opcode_defs::NearCallABI; use super::*; impl> DecodedOpcode { pub fn near_call_opcode_apply< - S: crate::abstractions::Storage, - M: crate::abstractions::Memory, - EV: crate::abstractions::EventSink, - PP: crate::abstractions::PrecompilesProcessor, - DP: crate::abstractions::DecommittmentProcessor, + 'a, + S: zk_evm_abstractions::vm::Storage, + M: zk_evm_abstractions::vm::Memory, + EV: zk_evm_abstractions::vm::EventSink, + PP: zk_evm_abstractions::vm::PrecompilesProcessor, + DP: zk_evm_abstractions::vm::DecommittmentProcessor, WT: crate::witness_trace::VmWitnessTracer, >( &self, diff --git a/crates/zk_evm/src/opcodes/execution/noop.rs b/crates/zk_evm/src/opcodes/execution/noop.rs index d4b95ed..1b2b8f8 100644 --- a/crates/zk_evm/src/opcodes/execution/noop.rs +++ b/crates/zk_evm/src/opcodes/execution/noop.rs @@ -2,11 +2,12 @@ use super::*; impl> DecodedOpcode { pub fn noop_opcode_apply< - S: crate::abstractions::Storage, - M: crate::abstractions::Memory, - EV: crate::abstractions::EventSink, - PP: crate::abstractions::PrecompilesProcessor, - DP: crate::abstractions::DecommittmentProcessor, + 'a, + S: zk_evm_abstractions::vm::Storage, + M: zk_evm_abstractions::vm::Memory, + EV: zk_evm_abstractions::vm::EventSink, + PP: zk_evm_abstractions::vm::PrecompilesProcessor, + DP: zk_evm_abstractions::vm::DecommittmentProcessor, WT: crate::witness_trace::VmWitnessTracer, >( &self, diff --git a/crates/zk_evm/src/opcodes/execution/ptr.rs b/crates/zk_evm/src/opcodes/execution/ptr.rs index c2b548a..3623954 100644 --- a/crates/zk_evm/src/opcodes/execution/ptr.rs +++ b/crates/zk_evm/src/opcodes/execution/ptr.rs @@ -4,11 +4,12 @@ use zkevm_opcode_defs::{FatPointer, Opcode, PtrOpcode}; impl> DecodedOpcode { pub fn ptr_opcode_apply< - S: crate::abstractions::Storage, - M: crate::abstractions::Memory, - EV: crate::abstractions::EventSink, - PP: crate::abstractions::PrecompilesProcessor, - DP: crate::abstractions::DecommittmentProcessor, + 'a, + S: zk_evm_abstractions::vm::Storage, + M: zk_evm_abstractions::vm::Memory, + EV: zk_evm_abstractions::vm::EventSink, + PP: zk_evm_abstractions::vm::PrecompilesProcessor, + DP: zk_evm_abstractions::vm::DecommittmentProcessor, WT: crate::witness_trace::VmWitnessTracer, >( &self, diff --git a/crates/zk_evm/src/opcodes/execution/ret.rs b/crates/zk_evm/src/opcodes/execution/ret.rs index bfb5295..97b0c51 100644 --- a/crates/zk_evm/src/opcodes/execution/ret.rs +++ b/crates/zk_evm/src/opcodes/execution/ret.rs @@ -1,16 +1,19 @@ use super::*; +use zk_evm_abstractions::aux::Timestamp; +use zk_evm_abstractions::vm::SpongeExecutionMarker; use zkevm_opcode_defs::definitions::ret::*; use zkevm_opcode_defs::FatPointerValidationException; use zkevm_opcode_defs::{FatPointer, Opcode, RetABI, RetForwardPageType, RetOpcode}; impl> DecodedOpcode { pub fn ret_opcode_apply< - S: crate::abstractions::Storage, - M: crate::abstractions::Memory, - EV: crate::abstractions::EventSink, - PP: crate::abstractions::PrecompilesProcessor, - DP: crate::abstractions::DecommittmentProcessor, + 'a, + S: zk_evm_abstractions::vm::Storage, + M: zk_evm_abstractions::vm::Memory, + EV: zk_evm_abstractions::vm::EventSink, + PP: zk_evm_abstractions::vm::PrecompilesProcessor, + DP: zk_evm_abstractions::vm::DecommittmentProcessor, WT: crate::witness_trace::VmWitnessTracer, >( &self, @@ -82,9 +85,8 @@ impl> DecodedOpcode { } // our formal definition of "in bounds" is strictly "less than", but we want to allow to return // "trivial" pointer, like `ret.ok r0` - if memory_quasi_fat_pointer.validate_in_bounds() == false - && memory_quasi_fat_pointer.is_trivial() == false - { + // this captures the case of empty slice + if memory_quasi_fat_pointer.validate_as_slice() == false { inner_variant = RetOpcode::Panic; } diff --git a/crates/zk_evm/src/opcodes/execution/shift.rs b/crates/zk_evm/src/opcodes/execution/shift.rs index 7cdc058..df4e31a 100644 --- a/crates/zk_evm/src/opcodes/execution/shift.rs +++ b/crates/zk_evm/src/opcodes/execution/shift.rs @@ -6,11 +6,12 @@ use zkevm_opcode_defs::{Opcode, ShiftOpcode}; impl> DecodedOpcode { pub fn shift_opcode_apply< - S: crate::abstractions::Storage, - M: crate::abstractions::Memory, - EV: crate::abstractions::EventSink, - PP: crate::abstractions::PrecompilesProcessor, - DP: crate::abstractions::DecommittmentProcessor, + 'a, + S: zk_evm_abstractions::vm::Storage, + M: zk_evm_abstractions::vm::Memory, + EV: zk_evm_abstractions::vm::EventSink, + PP: zk_evm_abstractions::vm::PrecompilesProcessor, + DP: zk_evm_abstractions::vm::DecommittmentProcessor, WT: crate::witness_trace::VmWitnessTracer, >( &self, diff --git a/crates/zk_evm/src/opcodes/execution/sub.rs b/crates/zk_evm/src/opcodes/execution/sub.rs index 27d1129..f876dde 100644 --- a/crates/zk_evm/src/opcodes/execution/sub.rs +++ b/crates/zk_evm/src/opcodes/execution/sub.rs @@ -2,11 +2,12 @@ use super::*; impl> DecodedOpcode { pub fn sub_opcode_apply< - S: crate::abstractions::Storage, - M: crate::abstractions::Memory, - EV: crate::abstractions::EventSink, - PP: crate::abstractions::PrecompilesProcessor, - DP: crate::abstractions::DecommittmentProcessor, + 'a, + S: zk_evm_abstractions::vm::Storage, + M: zk_evm_abstractions::vm::Memory, + EV: zk_evm_abstractions::vm::EventSink, + PP: zk_evm_abstractions::vm::PrecompilesProcessor, + DP: zk_evm_abstractions::vm::DecommittmentProcessor, WT: crate::witness_trace::VmWitnessTracer, >( &self, diff --git a/crates/zk_evm/src/opcodes/execution/uma.rs b/crates/zk_evm/src/opcodes/execution/uma.rs index d99b3ec..3cf5feb 100644 --- a/crates/zk_evm/src/opcodes/execution/uma.rs +++ b/crates/zk_evm/src/opcodes/execution/uma.rs @@ -1,4 +1,5 @@ -use crate::abstractions::MemoryType; +use zk_evm_abstractions::aux::*; +use zk_evm_abstractions::vm::{MemoryType, SpongeExecutionMarker}; use super::*; use zkevm_opcode_defs::{FatPointer, Opcode, UMAOpcode, UMA_INCREMENT_FLAG_IDX}; @@ -23,11 +24,12 @@ bitflags! { impl> DecodedOpcode { pub fn uma_opcode_apply< - S: crate::abstractions::Storage, - M: crate::abstractions::Memory, - EV: crate::abstractions::EventSink, - PP: crate::abstractions::PrecompilesProcessor, - DP: crate::abstractions::DecommittmentProcessor, + 'a, + S: zk_evm_abstractions::vm::Storage, + M: zk_evm_abstractions::vm::Memory, + EV: zk_evm_abstractions::vm::EventSink, + PP: zk_evm_abstractions::vm::PrecompilesProcessor, + DP: zk_evm_abstractions::vm::DecommittmentProcessor, WT: crate::witness_trace::VmWitnessTracer, >( &self, diff --git a/crates/zk_evm/src/opcodes/parsing.rs b/crates/zk_evm/src/opcodes/parsing.rs index 42f0595..6db4127 100644 --- a/crates/zk_evm/src/opcodes/parsing.rs +++ b/crates/zk_evm/src/opcodes/parsing.rs @@ -45,20 +45,21 @@ impl> DecodedOpcode { } pub fn apply< - S: crate::abstractions::Storage, - M: crate::abstractions::Memory, - EV: crate::abstractions::EventSink, - PP: crate::abstractions::PrecompilesProcessor, - DP: crate::abstractions::DecommittmentProcessor, + 'a, + S: zk_evm_abstractions::vm::Storage, + M: zk_evm_abstractions::vm::Memory, + EV: zk_evm_abstractions::vm::EventSink, + PP: zk_evm_abstractions::vm::PrecompilesProcessor, + DP: zk_evm_abstractions::vm::DecommittmentProcessor, WT: crate::witness_trace::VmWitnessTracer, >( &self, vm_state: &mut VmState, prestate: PreState, - ) { + ) -> anyhow::Result<()> { use zkevm_opcode_defs::Opcode; - match self.inner.variant.opcode { + Ok(match self.inner.variant.opcode { Opcode::Nop(_) => self.noop_opcode_apply(vm_state, prestate), Opcode::Add(_) => self.add_opcode_apply(vm_state, prestate), Opcode::Sub(_) => self.sub_opcode_apply(vm_state, prestate), @@ -71,10 +72,10 @@ impl> DecodedOpcode { Opcode::Ptr(_) => self.ptr_opcode_apply(vm_state, prestate), Opcode::Log(_) => self.log_opcode_apply(vm_state, prestate), Opcode::NearCall(_) => self.near_call_opcode_apply(vm_state, prestate), - Opcode::FarCall(_) => self.far_call_opcode_apply(vm_state, prestate), + Opcode::FarCall(_) => self.far_call_opcode_apply(vm_state, prestate)?, Opcode::Ret(_) => self.ret_opcode_apply(vm_state, prestate), Opcode::UMA(_) => self.uma_opcode_apply(vm_state, prestate), Opcode::Invalid(_) => unreachable!(), - } + }) } } diff --git a/crates/zk_evm/src/reference_impls/decommitter.rs b/crates/zk_evm/src/reference_impls/decommitter.rs index 93b62b9..b34998f 100644 --- a/crates/zk_evm/src/reference_impls/decommitter.rs +++ b/crates/zk_evm/src/reference_impls/decommitter.rs @@ -1,3 +1,7 @@ +use zk_evm_abstractions::aux::*; +use zk_evm_abstractions::queries::*; +use zk_evm_abstractions::vm::*; + use super::*; pub const MEMORY_CELLS_PER_PAGE: usize = (1 << 16) - 1; @@ -30,16 +34,16 @@ impl DecommittmentProcessor for SimpleDecommitter { monotonic_cycle_counter: u32, mut partial_query: DecommittmentQuery, memory: &mut M, - ) -> (DecommittmentQuery, Option>) { + ) -> anyhow::Result<(DecommittmentQuery, Option>)> { if let Some((old_page, old_len)) = self.history.get(&partial_query.hash).copied() { partial_query.is_fresh = false; partial_query.memory_page = MemoryPage(old_page); partial_query.decommitted_length = old_len; if B { - (partial_query, Some(vec![])) // empty extra data + Ok((partial_query, Some(vec![]))) // empty extra data } else { - (partial_query, None) + Ok((partial_query, None)) } } else { // fresh one @@ -47,10 +51,9 @@ impl DecommittmentProcessor for SimpleDecommitter { .known_hashes .get(&partial_query.hash) .cloned() - .expect(&format!( - "Code hash {:?} must be known", - &partial_query.hash - )); + .ok_or_else(|| { + anyhow::anyhow!("Code hash {:?} must be known", &partial_query.hash) + })?; let page_to_use = partial_query.memory_page; let timestamp = partial_query.timestamp; partial_query.decommitted_length = values.len() as u16; @@ -66,7 +69,6 @@ impl DecommittmentProcessor for SimpleDecommitter { value: U256::zero(), value_is_pointer: false, rw_flag: true, - is_pended: false, }; self.history.insert( @@ -83,7 +85,7 @@ impl DecommittmentProcessor for SimpleDecommitter { memory.specialized_code_query(monotonic_cycle_counter, tmp_q); } - (partial_query, Some(values)) + Ok((partial_query, Some(values))) } else { for (i, value) in values.into_iter().enumerate() { tmp_q.location.index = MemoryIndex(i as u32); @@ -91,7 +93,7 @@ impl DecommittmentProcessor for SimpleDecommitter { memory.specialized_code_query(monotonic_cycle_counter, tmp_q); } - (partial_query, None) + Ok((partial_query, None)) } } } diff --git a/crates/zk_evm/src/reference_impls/event_sink.rs b/crates/zk_evm/src/reference_impls/event_sink.rs index d4c72ee..a0da81a 100644 --- a/crates/zk_evm/src/reference_impls/event_sink.rs +++ b/crates/zk_evm/src/reference_impls/event_sink.rs @@ -1,5 +1,6 @@ use super::*; +use zk_evm_abstractions::{aux::Timestamp, queries::LogQuery, vm::EventSink}; use zkevm_opcode_defs::system_params::{EVENT_AUX_BYTE, L1_MESSAGE_AUX_BYTE}; #[derive(Clone, Copy)] diff --git a/crates/zk_evm/src/reference_impls/memory.rs b/crates/zk_evm/src/reference_impls/memory.rs index 36611c6..bbb11c5 100644 --- a/crates/zk_evm/src/reference_impls/memory.rs +++ b/crates/zk_evm/src/reference_impls/memory.rs @@ -3,10 +3,17 @@ use std::{collections::HashSet, hash::BuildHasher}; use crate::vm_state::CallStackEntry; use crate::vm_state::PrimitiveValue; +use zk_evm_abstractions::aux::{MemoryPage, Timestamp}; +use zk_evm_abstractions::queries::MemoryQuery; +use zk_evm_abstractions::vm::{ + Memory, MemoryType, MAX_CODE_PAGE_SIZE_IN_WORDS, MAX_STACK_PAGE_SIZE_IN_WORDS, +}; use zkevm_opcode_defs::{FatPointer, BOOTLOADER_CALLDATA_PAGE}; use super::*; +const MAX_HEAP_PAGE_SIZE_IN_WORDS: usize = (u16::MAX as usize) / 32; + pub struct ReusablePool< T: Sized, InitFn: Fn() -> T, @@ -65,7 +72,7 @@ impl T, OnPullFn: Fn(&mut T) -> (), OnReturnFn: Fn(&mu pub enum Indirection { Heap(usize), AuxHeap(usize), - ExtendedLifetime, + ReturndataExtendedLifetime, Empty, } @@ -481,7 +488,7 @@ impl Memory for SimpleMemory { assert_eq!(forwarded_heap_data.1 .0, query.location.page.0); query.value = forwarded_heap_data.1 .1[query.location.index.0 as usize]; } - Indirection::ExtendedLifetime => { + Indirection::ReturndataExtendedLifetime => { let page = self .pages_with_extended_lifetime .get(&page_number) @@ -612,14 +619,21 @@ impl Memory for SimpleMemory { .unwrap() .insert(current_aux_heap_page); } else { - // it must be some extended lifetime page - assert!(self - .pages_with_extended_lifetime - .contains_key(&calldata_fat_pointer.memory_page)); - self.page_numbers_indirections.insert( - calldata_fat_pointer.memory_page, - Indirection::ExtendedLifetime, - ); + // calldata is unidirectional, so we check that it's already an indirection + let existing_indirection = self + .page_numbers_indirections + .get(&calldata_fat_pointer.memory_page) + .expect("fat pointer must only point to reachable memory"); + match existing_indirection { + Indirection::Heap(..) | Indirection::AuxHeap(..) => {} + a @ _ => { + panic!("calldata forwaring using pointer {:?} should already have a heap/aux heap indirection, but has {:?}. All indirections:\n {:?}", + &calldata_fat_pointer, + a, + &self.page_numbers_indirections + ); + } + } } } @@ -673,7 +687,7 @@ impl Memory for SimpleMemory { .insert(current_heap_page, current_heap_content); assert!(existing.is_none()); self.page_numbers_indirections - .insert(current_heap_page, Indirection::ExtendedLifetime); + .insert(current_heap_page, Indirection::ReturndataExtendedLifetime); previous_frame_indirections_to_cleanup.insert(current_heap_page); // and we can reuse another page @@ -684,8 +698,10 @@ impl Memory for SimpleMemory { .pages_with_extended_lifetime .insert(current_aux_heap_page, current_aux_heap_content); assert!(existing.is_none()); - self.page_numbers_indirections - .insert(current_aux_heap_page, Indirection::ExtendedLifetime); + self.page_numbers_indirections.insert( + current_aux_heap_page, + Indirection::ReturndataExtendedLifetime, + ); previous_frame_indirections_to_cleanup.insert(current_aux_heap_page); // and we can reuse another page diff --git a/crates/zk_evm/src/reference_impls/mod.rs b/crates/zk_evm/src/reference_impls/mod.rs index c779a84..d04ed02 100644 --- a/crates/zk_evm/src/reference_impls/mod.rs +++ b/crates/zk_evm/src/reference_impls/mod.rs @@ -1,7 +1,5 @@ use super::*; -use crate::abstractions::*; -use crate::aux_structures::*; use std::collections::HashMap; pub mod decommitter; diff --git a/crates/zk_evm/src/testing/debug_tracer.rs b/crates/zk_evm/src/testing/debug_tracer.rs index c8d0916..43f19ca 100644 --- a/crates/zk_evm/src/testing/debug_tracer.rs +++ b/crates/zk_evm/src/testing/debug_tracer.rs @@ -4,14 +4,15 @@ use crate::vm_state::cycle::AuxTracingInformation; use super::*; pub struct NoopTracer< - S: crate::abstractions::Storage, + 'a, + S: crate::abstractions::Storage, M: crate::abstractions::Memory, EV: crate::abstractions::EventSink, PP: crate::abstractions::PrecompilesProcessor, DP: crate::abstractions::DecommittmentProcessor, WT: crate::witness_trace::VmWitnessTracer > { - _marker: std::marker::PhantomData> + _marker: std::marker::PhantomData> } impl< @@ -46,47 +47,50 @@ impl< } impl< - S: crate::abstractions::Storage, + 'a, + S: crate::abstractions::Storage, M: crate::abstractions::Memory, EV: crate::abstractions::EventSink, PP: crate::abstractions::PrecompilesProcessor, DP: crate::abstractions::DecommittmentProcessor, WT: crate::witness_trace::VmWitnessTracer -> DebugTracer, AuxTracingInformation, ()> for NoopTracer<'a, S, M, EV, PP, DP, WT> { +> DebugTracer, AuxTracingInformation, ()> for NoopTracer<'a, S, M, EV, PP, DP, WT> { #[inline] - fn perform_before_execution(&mut self, _main: &VmState< S, M, EV, PP, DP, WT>, _aux: AuxTracingInformation) { + fn perform_before_execution(&mut self, _main: &VmState<'a, S, M, EV, PP, DP, WT>, _aux: AuxTracingInformation) { } #[inline] - fn perform_after_execution(&mut self, _main: &VmState< S, M, EV, PP, DP, WT>, _aux: ()) { + fn perform_after_execution(&mut self, _main: &VmState<'a, S, M, EV, PP, DP, WT>, _aux: ()) { } } pub struct ClosureBasedTracer< - S: crate::abstractions::Storage, + 'a, + S: crate::abstractions::Storage, M: crate::abstractions::Memory, EV: crate::abstractions::EventSink, PP: crate::abstractions::PrecompilesProcessor, DP: crate::abstractions::DecommittmentProcessor, WT: crate::witness_trace::VmWitnessTracer, - F: FnMut(&VmState< S, M, EV, PP, DP, WT>, AuxTracingInformation, u32, ) -> () + F: FnMut(&VmState<'a, S, M, EV, PP, DP, WT>, AuxTracingInformation, u32, ) -> () > { closure: F, cycle_number: u32, - _marker: std::marker::PhantomData> + _marker: std::marker::PhantomData> } impl< - S: crate::abstractions::Storage, + 'a, + S: crate::abstractions::Storage, M: crate::abstractions::Memory, EV: crate::abstractions::EventSink, PP: crate::abstractions::PrecompilesProcessor, DP: crate::abstractions::DecommittmentProcessor, WT: crate::witness_trace::VmWitnessTracer, - F: FnMut(&VmState, AuxTracingInformation, u32, ) -> () -> std::fmt::Debug for ClosureBasedTracer< S, M, EV, PP, DP, WT, F> { + F: FnMut(&VmState<'a, S, M, EV, PP, DP, WT>, AuxTracingInformation, u32, ) -> () +> std::fmt::Debug for ClosureBasedTracer<'a, S, M, EV, PP, DP, WT, F> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("ClosureBasedTracer") .finish() @@ -94,14 +98,15 @@ impl< } impl< - S: crate::abstractions::Storage, + 'a, + S: crate::abstractions::Storage, M: crate::abstractions::Memory, EV: crate::abstractions::EventSink, PP: crate::abstractions::PrecompilesProcessor, DP: crate::abstractions::DecommittmentProcessor, WT: crate::witness_trace::VmWitnessTracer, - F: FnMut(&VmState< S, M, EV, PP, DP, WT>, AuxTracingInformation, u32, ) -> () -> ClosureBasedTracer< S, M, EV, PP, DP, WT, F> { + F: FnMut(&VmState<'a, S, M, EV, PP, DP, WT>, AuxTracingInformation, u32, ) -> () +> ClosureBasedTracer<'a, S, M, EV, PP, DP, WT, F> { pub fn new(closure: F) -> Self { Self { closure, @@ -112,25 +117,27 @@ impl< } impl< - S: crate::abstractions::Storage, + 'a, + S: crate::abstractions::Storage, M: crate::abstractions::Memory, EV: crate::abstractions::EventSink, PP: crate::abstractions::PrecompilesProcessor, DP: crate::abstractions::DecommittmentProcessor, WT: crate::witness_trace::VmWitnessTracer, - F: FnMut(&VmState, AuxTracingInformation, u32, ) -> () -> DebugTracer, AuxTracingInformation, ()> for ClosureBasedTracer<'a, S, M, EV, PP, DP, WT, F> { - fn perform_before_execution(&mut self, main: &VmState< S, M, EV, PP, DP, WT>, aux: AuxTracingInformation) { + F: FnMut(&VmState<'a, S, M, EV, PP, DP, WT>, AuxTracingInformation, u32, ) -> () +> DebugTracer, AuxTracingInformation, ()> for ClosureBasedTracer<'a, S, M, EV, PP, DP, WT, F> { + fn perform_before_execution(&mut self, main: &VmState<'a, S, M, EV, PP, DP, WT>, aux: AuxTracingInformation) { (self.closure)(main, aux, self.cycle_number); } - fn perform_after_execution(&mut self, _main: &VmState< S, M, EV, PP, DP, WT>, _aux: ()) { + fn perform_after_execution(&mut self, _main: &VmState<'a, S, M, EV, PP, DP, WT>, _aux: ()) { self.cycle_number += 1; } } pub struct DynTracer< + 'a, 'b, S: crate::abstractions::Storage, M: crate::abstractions::Memory, @@ -141,13 +148,14 @@ pub struct DynTracer< > { // pub before_closure: Option, AuxTracingInformation, u32, ) -> () + 'a>>, // pub after_closure: Option, (), u32, ) -> () + 'a>>, - pub before_closure: Option<&'b mut dyn FnMut(&VmState< S, M, EV, PP, DP, WT>, AuxTracingInformation, u32, ) -> ()>, - pub after_closure: Option<&'b mut dyn FnMut(&VmState< S, M, EV, PP, DP, WT>, (), u32, ) -> ()>, + pub before_closure: Option<&'b mut dyn FnMut(&VmState<'a, S, M, EV, PP, DP, WT>, AuxTracingInformation, u32, ) -> ()>, + pub after_closure: Option<&'b mut dyn FnMut(&VmState<'a, S, M, EV, PP, DP, WT>, (), u32, ) -> ()>, cycle_number: u32, - _marker: std::marker::PhantomData> + _marker: std::marker::PhantomData> } impl< + 'a, 'b, S: crate::abstractions::Storage, M: crate::abstractions::Memory, @@ -155,7 +163,7 @@ impl< PP: crate::abstractions::PrecompilesProcessor, DP: crate::abstractions::DecommittmentProcessor, WT: crate::witness_trace::VmWitnessTracer, -> std::fmt::Debug for DynTracer< 'b, S, M, EV, PP, DP, WT> { +> std::fmt::Debug for DynTracer<'a, 'b, S, M, EV, PP, DP, WT> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("DynTracer") .finish() @@ -163,6 +171,7 @@ impl< } impl< + 'a, 'b, S: crate::abstractions::Storage, M: crate::abstractions::Memory, @@ -170,7 +179,7 @@ impl< PP: crate::abstractions::PrecompilesProcessor, DP: crate::abstractions::DecommittmentProcessor, WT: crate::witness_trace::VmWitnessTracer, -> DynTracer< 'b, S, M, EV, PP, DP, WT> { +> DynTracer<'a, 'b, S, M, EV, PP, DP, WT> { pub fn new() -> Self { Self { before_closure: None, @@ -182,6 +191,7 @@ impl< } impl< + 'a, 'b, S: crate::abstractions::Storage, M: crate::abstractions::Memory, @@ -189,14 +199,14 @@ impl< PP: crate::abstractions::PrecompilesProcessor, DP: crate::abstractions::DecommittmentProcessor, WT: crate::witness_trace::VmWitnessTracer, -> DebugTracer, AuxTracingInformation, ()> for DynTracer<'a, 'b, S, M, EV, PP, DP, WT> { - fn perform_before_execution(&mut self, main: &VmState< S, M, EV, PP, DP, WT>, aux: AuxTracingInformation) { +> DebugTracer, AuxTracingInformation, ()> for DynTracer<'a, 'b, S, M, EV, PP, DP, WT> { + fn perform_before_execution(&mut self, main: &VmState<'a, S, M, EV, PP, DP, WT>, aux: AuxTracingInformation) { if let Some(closure) = self.before_closure.as_deref_mut() { (closure)(main, aux, self.cycle_number); } } - fn perform_after_execution(&mut self, main: &VmState< S, M, EV, PP, DP, WT>, aux: ()) { + fn perform_after_execution(&mut self, main: &VmState<'a, S, M, EV, PP, DP, WT>, aux: ()) { if let Some(closure) = self.after_closure.as_deref_mut() { (closure)(main, aux, self.cycle_number); } diff --git a/crates/zk_evm/src/testing/mod.rs b/crates/zk_evm/src/testing/mod.rs index 7f1883e..45f82b8 100644 --- a/crates/zk_evm/src/testing/mod.rs +++ b/crates/zk_evm/src/testing/mod.rs @@ -1,6 +1,4 @@ use super::*; -use crate::abstractions::*; -use crate::aux_structures::*; use std::collections::*; pub const NUM_SHARDS: usize = 2; @@ -10,8 +8,19 @@ pub mod simple_tracer; pub mod storage; use self::storage::InMemoryStorage; -use crate::precompiles::DefaultPrecompilesProcessor; +use crate::vm_state::VmState; use crate::witness_trace::DummyTracer; +use zk_evm_abstractions::precompiles::DefaultPrecompilesProcessor; +use zk_evm_abstractions::queries::LogQuery; + +pub type BasicTestingVmState = VmState< + InMemoryStorage, + SimpleMemory, + InMemoryEventSink, + DefaultPrecompilesProcessor, + SimpleDecommitter, + DummyTracer, +>; pub struct BasicTestingTools { pub storage: InMemoryStorage, @@ -41,7 +50,7 @@ pub fn create_default_testing_tools() -> BasicTestingTools { } pub fn get_final_net_states( - tools: BasicTestingTools, + vm: BasicTestingVmState, ) -> ( Vec, [HashMap>; NUM_SHARDS], @@ -50,12 +59,12 @@ pub fn get_final_net_states( Vec, SimpleMemory, ) { - let BasicTestingTools:: { + let BasicTestingVmState { storage, event_sink, memory, .. - } = tools; + } = vm; let final_storage_state = storage.inner.clone(); let (full_storage_access_history, _per_slot_history) = storage.flatten_and_net_history(); diff --git a/crates/zk_evm/src/testing/simple_tracer.rs b/crates/zk_evm/src/testing/simple_tracer.rs index 5eea1c8..2149063 100644 --- a/crates/zk_evm/src/testing/simple_tracer.rs +++ b/crates/zk_evm/src/testing/simple_tracer.rs @@ -1,7 +1,4 @@ -use crate::abstractions::Tracer; -use crate::testing::{ - AfterDecodingData, AfterExecutionData, BeforeExecutionData, VmLocalStateData, -}; +use crate::tracing::*; #[derive(Debug, Clone, Copy)] pub struct NoopTracer; diff --git a/crates/zk_evm/src/testing/storage.rs b/crates/zk_evm/src/testing/storage.rs index 7f964bb..d860b74 100644 --- a/crates/zk_evm/src/testing/storage.rs +++ b/crates/zk_evm/src/testing/storage.rs @@ -1,3 +1,6 @@ +use zk_evm_abstractions::aux::Timestamp; +use zk_evm_abstractions::vm::{RefundType, Storage}; + use super::ApplicationData; use super::*; diff --git a/crates/zk_evm/src/testing/tests/mod.rs b/crates/zk_evm/src/testing/tests/mod.rs index 03aee2e..16ed0bb 100644 --- a/crates/zk_evm/src/testing/tests/mod.rs +++ b/crates/zk_evm/src/testing/tests/mod.rs @@ -1,8 +1,8 @@ use super::*; +use zk_evm_abstractions::aux::MemoryPage; use zkevm_opcode_defs::system_params::BOOTLOADER_FORMAL_ADDRESS; -use crate::precompiles::*; use crate::vm_state::*; use crate::{ block_properties::BlockProperties, @@ -22,14 +22,7 @@ pub fn create_default_block_info() -> BlockProperties { pub fn create_initial_vm_state_for_basic_testing( tools: BasicTestingTools, block_properties: BlockProperties, -) -> VmState< - InMemoryStorage, - SimpleMemory, - InMemoryEventSink, - DefaultPrecompilesProcessor, - SimpleDecommitter, - DummyTracer, -> { +) -> BasicTestingVmState { let mut vm = VmState::empty_state( tools.storage, tools.memory, diff --git a/crates/zk_evm/src/testing/tests/trivial.rs b/crates/zk_evm/src/testing/tests/trivial.rs index ac0f3ed..f8f2988 100644 --- a/crates/zk_evm/src/testing/tests/trivial.rs +++ b/crates/zk_evm/src/testing/tests/trivial.rs @@ -1,12 +1,13 @@ +use zkevm_opcode_defs::BOOTLOADER_CODE_PAGE; use super::*; use super::simple_tracer::*; #[test] fn run_dummy_log_and_unmapped_noop() { - let mut tools = create_default_testing_tools(); + let tools = create_default_testing_tools(); let block_properties = create_default_block_info(); - let mut vm = create_initial_vm_state_for_basic_testing(&mut tools, &block_properties); + let mut vm = create_initial_vm_state_for_basic_testing(tools, block_properties); let tracing_closure = |state: &VmState<_, _, _, _, _, _>, aux: AuxTracingInformation, cycle_idx: u32| { println!("------------------------------------------------------------"); @@ -41,7 +42,7 @@ fn run_dummy_log_and_unmapped_noop() { vm.cycle(&mut debug_tracer); vm.cycle(&mut debug_tracer); - let (full_storage_access_history, storage_pre_shard, events_log_history, events, l1_messages, _) = get_final_net_states!(vm, tools); + let (full_storage_access_history, storage_pre_shard, events_log_history, events, l1_messages, _) = get_final_net_states(vm); println!("------------------------------------------------------"); println!("Storage log access history:"); @@ -60,10 +61,10 @@ fn run_dummy_log_and_unmapped_noop() { fn check_nop_moves_sp() { let mut tools = create_default_testing_tools(); let block_properties = create_default_block_info(); - let mut vm = create_initial_vm_state_for_basic_testing(&mut tools, &block_properties); + let mut vm = create_initial_vm_state_for_basic_testing(tools, block_properties); let default_tracing_tool = DefaultTracingClosure::new(); - let mut debug_tracer = ClosureBasedTracer::new(|a, b, c| default_tracing_tool.trace(a, b, c)); + let mut debug_tracer = ClosureBasedTracer::new(|a, b, c| default_tracing_tool.trace(a, b, c)); // manually encode LE let opcode = "000100005000002000"; diff --git a/crates/zk_evm/src/tests/assembly.rs b/crates/zk_evm/src/tests/assembly.rs new file mode 100644 index 0000000..e9d9907 --- /dev/null +++ b/crates/zk_evm/src/tests/assembly.rs @@ -0,0 +1,468 @@ +use crate::tests::set_account_type; +use crate::vm_runner::{run_vm, VmLaunchOption, VmSnapshot}; +use crate::VmExecutionResult; +use std::collections::HashMap; +use std::convert::TryFrom; +use std::num::ParseIntError; +use std::path::PathBuf; +use std::str::FromStr; + +#[test] +fn factorial_5() { + let assembly = + zkevm_assembly::Assembly::try_from(PathBuf::from("examples/factorial.sasm")).unwrap(); + let VmSnapshot { registers, .. } = run_vm( + assembly, + Vec::new(), + HashMap::new(), + vec![U256::from(5)], + None, + VmLaunchOption::Default, + usize::MAX, + ); + + assert_eq!(registers[0], U256::from(120)); //5! = 120 +} + +#[test] +fn errors_in_contract() { + // You can find the exact contract code in etc/contracts-test-data/error-contract/SimpleRequire.sol + let assembly = + zkevm_assembly::Assembly::try_from(PathBuf::from("examples/require.zasm")).unwrap(); + let short_calldata = decode_hex("000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e6136e38").unwrap(); + let long_calldata = decode_hex("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b5fa981").unwrap(); + let new_error_calldata = decode_hex("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000058f822ca").unwrap(); + + let mut storage = HashMap::new(); + let storage_key = StorageKey::UserKey( + AccountTreeId::Rollup(Address::default()), + AccountTreeId::Rollup(Address::default()), + H256::from_str("0xc49821d8653c58e43c7c6b0f17e15eb7f774bf3333419e9bedb01be51ae97e7c") + .unwrap(), + ); + storage.insert(storage_key, u32_to_h256(1)); + set_account_type(&mut storage, &Address::default(), &AccountType::ZkRollup); + let VmSnapshot { + execution_result: VmExecutionResult { revert_reason, .. }, + .. + } = run_vm( + assembly.clone(), + short_calldata, + storage.clone(), + vec![], + None, + VmLaunchOption::Default, + usize::MAX, + ); + let revert_reason = revert_reason.unwrap(); + assert_eq!(revert_reason.require_msg().unwrap(), "short"); + assert_eq!(hex::encode(revert_reason.complete_byte_message()),"08c379a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000573686f7274000000000000000000000000000000000000000000000000000000"); + let VmSnapshot { + execution_result: VmExecutionResult { revert_reason, .. }, + .. + } = run_vm( + assembly.clone(), + long_calldata, + storage.clone(), + vec![], + None, + VmLaunchOption::Default, + usize::MAX, + ); + assert_eq!(revert_reason.unwrap().require_msg().unwrap(), "llonglonglongtextblonglonglongtextblonglonglongtextblonglonglongtextblonglonglongtextblonglonglongtextblonglonglongtextblonglonglongtextblonglonglongtextblonglonglongtextblonglonglongtextblonglonglongtextbonglonglongtextb"); + let VmSnapshot { + execution_result: VmExecutionResult { revert_reason, .. }, + .. + } = run_vm( + assembly.clone(), + new_error_calldata, + storage.clone(), + vec![], + None, + VmLaunchOption::Default, + usize::MAX, + ); + //Correct error encoded with abi + assert_eq!(hex::encode(revert_reason.unwrap().msg), "000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000046461746100000000000000000000000000000000000000000000000000000000"); +} + +#[test] +fn factorial_rec_5() { + let assembly = + zkevm_assembly::Assembly::try_from(PathBuf::from("examples/factorial_rec.sasm")).unwrap(); + + let VmSnapshot { registers, .. } = run_vm( + assembly, + Vec::new(), + HashMap::new(), + vec![U256::from(5)], + None, + VmLaunchOption::Default, + usize::MAX, + ); + + assert_eq!(registers[0], U256::from(120)); //5! = 120 +} + +#[test] +#[ignore] // ignore because fibonacci.sasm is generated with compiler with old sp handling +fn fibonacci_23() { + vlog::init(); + let assembly = + zkevm_assembly::Assembly::try_from(PathBuf::from("examples/fibonacci.sasm")).unwrap(); + + let VmSnapshot { registers, .. } = run_vm( + assembly, + Vec::new(), + HashMap::new(), + vec![U256::from(5)], + None, + VmLaunchOption::Label(String::from("three")), + usize::MAX, + ); + + assert_eq!(registers[0], U256::from(63245986)); //23th fibonacci number = 17711 +} + +#[test] +#[ignore] +fn test_increase_storage() { + vlog::init(); + let asm_text = r#" + .text + .file "main" + .type reverse,@function +reverse: + push #33, r0 + add r1, r0, r4 + sfll #0, r5, r5 + sflh #0, r5, r5 + sfll #320, r3, r3 + sflh #0, r3, r3 + sfll #736, r0, r1 + add r1, r3, r3 + mov r3, 22(sp) + sfll #288, r3, r3 + sflh #0, r3, r3 + add r1, r3, r3 + mov r3, 7(sp) + sfll #224, r3, r3 + sflh #0, r3, r3 + add r1, r3, r3 + mov r3, 9(sp) + sfll #192, r3, r3 + sflh #0, r3, r3 + add r1, r3, r3 + mov r3, 8(sp) + sfll #160, r3, r3 + sflh #0, r3, r3 + add r1, r3, r3 + mov r3, 6(sp) + sfll #128, r3, r3 + sflh #0, r3, r3 + add r1, r3, r3 + mov r3, 5(sp) + sfll #96, r3, r3 + sflh #0, r3, r3 + add r1, r3, r3 + mov r3, 4(sp) + sfll #64, r3, r3 + sflh #0, r3, r3 + add r1, r3, r3 + mov r3, 3(sp) + sfll #32, r6, r6 + sflh #0, r6, r6 + div r2, r6, r3, r0 + mov r6, 23(sp) + add r1, r6, r2 + mov r2, 2(sp) + sfll #256, r6, r6 + sflh #0, r6, r6 + add r1, r6, r1 + mov r1, 1(sp) + add 1088, r4, r1 + mov r1, 11(sp) + mov 35(sp-r3), r2 + mov 36(sp-r3), r1 + mov r1, 13(sp) + mov 37(sp-r3), r1 + mov r1, 20(sp) + mov 38(sp-r3), r1 + mov r1, 19(sp) + mov 39(sp-r3), r1 + mov r1, 18(sp) + mov 40(sp-r3), r1 + mov r1, 17(sp) + mov 41(sp-r3), r1 + mov r1, 16(sp) + mov 42(sp-r3), r1 + mov r1, 15(sp) + mov 43(sp-r3), r1 + mov r1, 14(sp) + mov 44(sp-r3), r1 + mov 45(sp-r3), r4 + mov r4, 34(sp) + div r4, r6, r0, r3 + mov r3, 10(sp) + mov r1, 12(sp) + mov r1, 33(sp) + mov 14(sp), r1 + mov r1, 32(sp) + mov 15(sp), r1 + mov r1, 31(sp) + mov 16(sp), r1 + mov r1, 30(sp) + mov 17(sp), r1 + mov r1, 29(sp) + mov 18(sp), r1 + mov r1, 28(sp) + mov 19(sp), r1 + mov r1, 27(sp) + mov 20(sp), r1 + mov r1, 26(sp) + mov 13(sp), r1 + mov r1, 25(sp) + mov r2, 24(sp) + sfll #2, r3, r3 + sflh #0, r3, r3 + mov r3, 21(sp) + mov 10(sp), r1 + sub r1, r3, r0 + jlt .LBB0_4, .LBB0_1 +.LBB0_1: + sub r0, r5, r3 + sfll #340282366920938463463374607431768211455, r1, r1 + sflh #340282366920938463463374607431768211455, r1, r1 + add r3, r1, r1 + add r4, r1, r3 + div r3, r6, r0, r3 + mov 24(sp-r3), r3 + div r3, r6, r0, r3 + div r5, r6, r0, r4 + mov r3, 24(sp-r4) + mov 23(sp), r3 + mov 22(sp), r4 + div r4, r3, r3, r0 + mov 1(sp-r3), r4 + add r4, r1, r1 + div r2, r6, r0, r2 + div r1, r6, r0, r1 + mov r2, 24(sp-r1) + sfll #1, r1, r1 + sflh #0, r1, r1 + add r5, r1, r5 + mov 1(sp-r3), r4 + div r4, r6, r0, r1 + mov 21(sp), r2 + div r1, r2, r1, r0 + div r5, r6, r0, r2 + sub r2, r1, r0 + jge .LBB0_3, .LBB0_2 +.LBB0_2: + mov 24(sp-r2), r1 + div r1, r6, r0, r2 + j .LBB0_1, .LBB0_1 +.LBB0_3: + mov 23(sp), r1 + mov 1(sp), r2 + div r2, r1, r2, r0 + mov r2, 19(sp) + mov 7(sp), r2 + div r2, r1, r6, r0 + mov 2(sp), r2 + div r2, r1, r2, r0 + mov r2, 22(sp) + mov 3(sp), r2 + div r2, r1, r2, r0 + mov r2, 21(sp) + mov 4(sp), r2 + div r2, r1, r2, r0 + mov r2, 20(sp) + mov 5(sp), r2 + div r2, r1, r2, r0 + mov r2, 18(sp) + mov 6(sp), r2 + div r2, r1, r5, r0 + mov 8(sp), r2 + div r2, r1, r3, r0 + mov 9(sp), r2 + div r2, r1, r1, r0 + mov 24(sp), r2 + mov 1(sp-r6), r6 + mov r6, 12(sp) + mov 19(sp), r6 + mov 1(sp-r6), r6 + mov r6, 14(sp) + mov 1(sp-r1), r1 + mov r1, 15(sp) + mov 1(sp-r3), r1 + mov r1, 16(sp) + mov 1(sp-r5), r1 + mov r1, 17(sp) + mov 18(sp), r1 + mov 1(sp-r1), r1 + mov r1, 18(sp) + mov 20(sp), r1 + mov 1(sp-r1), r1 + mov r1, 19(sp) + mov 21(sp), r1 + mov 1(sp-r1), r1 + mov r1, 20(sp) + mov 22(sp), r1 + mov 1(sp-r1), r1 + mov r1, 13(sp) +.LBB0_4: + mov 11(sp), r1 + mov 23(sp), r3 + div r1, r3, r3, r0 + mov r4, 11(sp-r3) + mov 12(sp), r4 + mov r4, 10(sp-r3) + mov 14(sp), r4 + mov r4, 9(sp-r3) + mov 15(sp), r4 + mov r4, 8(sp-r3) + mov 16(sp), r4 + mov r4, 7(sp-r3) + mov 17(sp), r4 + mov r4, 6(sp-r3) + mov 18(sp), r4 + mov r4, 5(sp-r3) + mov 19(sp), r4 + mov r4, 4(sp-r3) + mov 20(sp), r4 + mov r4, 3(sp-r3) + mov 13(sp), r4 + mov r4, 2(sp-r3) + mov r2, 1(sp-r3) + pop #33, r0 + ret +reverse_test: + push #26, r0 + sfll #9, r1, r1 + sflh #0, r1, r1 + mov r1, 25(sp) + sfll #4, r1, r1 + sflh #0, r1, r1 + mov r1, 24(sp) + sfll #5, r1, r1 + sflh #0, r1, r1 + mov r1, 23(sp) + sfll #10, r1, r1 + sflh #0, r1, r1 + mov r1, 27(sp) + mov r1, 21(sp) + sfll #8, r1, r1 + sflh #0, r1, r1 + mov r1, 20(sp) + sfll #6, r1, r1 + sflh #0, r1, r1 + mov r1, 4(sp) + mov r1, 26(sp) + sfll #3, r1, r1 + sflh #0, r1, r1 + mov r1, 2(sp) + mov r1, 22(sp) + sfll #1, r1, r1 + sflh #0, r1, r1 + mov r1, 1(sp) + mov r1, 19(sp) + sfll #2, r1, r1 + sflh #0, r1, r1 + mov r1, 5(sp) + mov r1, 18(sp) + sfll #7, r1, r1 + sflh #0, r1, r1 + mov r1, 3(sp) + mov r1, 17(sp) + sfll #160, r0, r1 + sfll #512, r0, r2 + call reverse + mov 1(sp), r5 + sfll #0, r2, r2 + sflh #0, r2, r2 + mov 10(sp), r3 + add r5, r0, r1 + mov 2(sp), r4 + sub r3, r4, r0 + je .LBB1_2, .LBB1_1 +.LBB1_1: + add r2, r0, r1 +.LBB1_2: + mov 15(sp), r4 + add r5, r0, r3 + mov 3(sp), r6 + sub r4, r6, r0 + je .LBB1_4, .LBB1_3 +.LBB1_3: + add r2, r0, r3 +.LBB1_4: + mov 6(sp), r4 + mov 4(sp), r6 + sub r4, r6, r0 + je .LBB1_6, .LBB1_5 +.LBB1_5: + add r2, r0, r5 +.LBB1_6: + mul r5, r3, r2, r0 + mul r1, r2, r1, r0 + mov 5(sp), r2 + div r1, r2, r0, r1 + pop #26, r0 + ret +.Lfunc_end1: + .size reverse_test, .Lfunc_end1-reverse_test + + .section ".note.GNU-stack","",@progbits + "#; + + let assembly = zkevm_assembly::Assembly::try_from(asm_text.to_owned()).unwrap(); + let calldata = r#" + 0100 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0100 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 0000 0000 0000 0000 7bfc 6c64 + 0500 0000 0000 0000 0000 0000 0000 0000 + 0000 0000 0000 0000 0000 0000 0000 0000 + + "# + .replace(|c: char| c.is_whitespace(), ""); + + let decoded_calldata = decode_hex(&calldata).expect("Decoding failed"); + let storage_key = UserKey( + Rollup(H160::zero()), + Rollup(H160::zero()), + H256::from_low_u64_be(1), + ); + let mut initial_storage: HashMap = HashMap::new(); + initial_storage.insert(storage_key.clone(), H256::from_low_u64_be(43)); + let VmSnapshot { storage, .. } = run_vm( + assembly, + decoded_calldata, + initial_storage, + vec![], + None, + VmLaunchOption::Default, + usize::MAX, + ); + assert_eq!(storage.get(&storage_key), Some(&H256::from_low_u64_be(48))) // 43 + 5 = 48 +} + +pub fn decode_hex(s: &str) -> Result, ParseIntError> { + (0..s.len()) + .step_by(2) + .map(|i| u8::from_str_radix(&s[i..i + 2], 16)) + .collect() +} diff --git a/crates/zk_evm/src/tests/mod.rs b/crates/zk_evm/src/tests/mod.rs new file mode 100644 index 0000000..c33b137 --- /dev/null +++ b/crates/zk_evm/src/tests/mod.rs @@ -0,0 +1,1750 @@ +#![allow(clippy::bool_assert_comparison)] // There are a lot of bool checks, direct comparison is more declarative. + +mod assembly; + +use crate::vm::VmExecutionContext; +use crate::vm_runner::{run_vm_multi_contracts, set_account_type, RawInMemoryStorage}; +use crate::{run_vm, VmExecutionResult, VmInstance, VmLaunchOption, VmSnapshot}; +use std::collections::HashMap; +use zkevm_assembly::*; +use zksync_types::AccountTreeId::Rollup; +use zksync_types::{ + utils::{address_to_h256, h256_to_u256}, + Address, BlockNumber, VmEvent, H160, H256, U256, +}; +use zksync_types::{AccountTreeId, AccountType, StorageKey}; + +const NULL: RegisterOperand = RegisterOperand::Null; +const RG0: RegisterOperand = RegisterOperand::Register(0); +const RG1: RegisterOperand = RegisterOperand::Register(1); +const RG2: RegisterOperand = RegisterOperand::Register(2); +const RG3: RegisterOperand = RegisterOperand::Register(3); +const RG4: RegisterOperand = RegisterOperand::Register(4); +const RG5: RegisterOperand = RegisterOperand::Register(5); + +const RF0: FullOperand = FullOperand::Register(RG0); +const RF1: FullOperand = FullOperand::Register(RG1); +const RF2: FullOperand = FullOperand::Register(RG2); + +const OP_RETURN: Instruction = + Instruction::FunctionJump(FunctionJumpInstruction::Return { error: false }); + +#[test] +fn test_calldata_allocation() { + let storage = &mut dummy_storage(); + let mut calldata_word_2_bytes = [0u8; 32]; + U256::from(42424242).to_little_endian(&mut calldata_word_2_bytes); + let mut calldata = vec![0x0; 32]; + calldata.extend_from_slice(&calldata_word_2_bytes); + let mut vm = VmInstance::new( + storage, + &calldata, + dummy_context(), + usize::MAX, + Default::default(), + ) + .unwrap(); + + vm.dispatch_opcode(Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::SharedParent, + offset: 0, + register: NULL, + }, + operation: DataOperation::Read { destination: RG0 }, + })) + .unwrap(); + + vm.dispatch_opcode(Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::SharedParent, + offset: 1, + register: NULL, + }, + operation: DataOperation::Read { destination: RG1 }, + })) + .unwrap(); + + assert_eq!(vm.read_reg(RG0), U256::zero()); + assert_eq!(vm.read_reg(RG1), U256::from(42424242)); +} + +#[test] +fn test_add_execution() { + let storage = &mut dummy_storage(); + let mut vm = VmInstance::new( + storage, + &Vec::new(), + dummy_context(), + usize::MAX, + Default::default(), + ) + .unwrap(); + vm.write_reg(RG0, U256::from(1)); + vm.write_reg(RG1, U256::from(2)); + + vm.dispatch_opcode(Instruction::Add(AddInstruction { + source_1: RF0, + source_2: RG1, + destination: RG2, + })) + .unwrap(); + + assert_eq!(vm.read_reg(RG2), U256::from(3)); + assert_eq!(vm.flags.error_overflow_or_less_than_flag, false); +} + +#[test] +fn test_bitwise_xor() { + let storage = &mut dummy_storage(); + let mut vm = VmInstance::new( + storage, + &Vec::new(), + dummy_context(), + usize::MAX, + Default::default(), + ) + .unwrap(); + vm.write_reg(RG0, U256::from(0b01011011)); + vm.write_reg(RG1, U256::from(0b10000001)); + + vm.dispatch_opcode(Instruction::Bitwise(BitwiseInstruction { + source_1: RF0, + source_2: RG1, + destination: RG2, + op_type: BitwiseOpType::Xor, + })) + .unwrap(); + + assert_eq!(vm.read_reg(RG2), U256::from(0b11011010)); + assert_eq!(vm.flags.error_overflow_or_less_than_flag, false); +} + +#[test] +fn test_bitwise_shift() { + let storage = &mut dummy_storage(); + let mut vm = VmInstance::new( + storage, + &Vec::new(), + dummy_context(), + usize::MAX, + Default::default(), + ) + .unwrap(); + vm.write_reg(RG0, U256::from(3 + (17 << 8))); // only first 8 bytes must be considered + vm.write_reg(RG1, U256::from(0b010111011011) + (U256::one() << 255)); + + vm.dispatch_opcode(Instruction::Shift(ShiftInstruction { + source_1: RF0, + source_2: RG1, + destination: RG2, + is_cyclic: false, + is_right: false, + })) + .unwrap(); + + vm.dispatch_opcode(Instruction::Shift(ShiftInstruction { + source_1: RF0, + source_2: RG1, + destination: RG3, + is_cyclic: false, + is_right: true, + })) + .unwrap(); + + vm.dispatch_opcode(Instruction::Shift(ShiftInstruction { + source_1: RF0, + source_2: RG1, + destination: RG4, + is_cyclic: true, + is_right: false, + })) + .unwrap(); + + vm.dispatch_opcode(Instruction::Shift(ShiftInstruction { + source_1: RF0, + source_2: RG1, + destination: RG5, + is_cyclic: true, + is_right: true, + })) + .unwrap(); + assert_eq!(vm.read_reg(RG2), U256::from(0b010111011011000)); + assert_eq!( + vm.read_reg(RG3), + U256::from(0b010111011) + (U256::one() << 252) + ); + assert_eq!(vm.read_reg(RG4), U256::from(0b010111011011100)); + assert_eq!( + vm.read_reg(RG5), + U256::from(0b010111011) + (U256::from(0b111) << 252) + ); +} + +#[test] +fn test_add_execution_overflow() { + let storage = &mut dummy_storage(); + let mut vm = VmInstance::new( + storage, + &Vec::new(), + dummy_context(), + usize::MAX, + Default::default(), + ) + .unwrap(); + vm.write_reg(RG0, U256::max_value()); + vm.write_reg(RG1, U256::from(44)); + + vm.dispatch_opcode(Instruction::Add(AddInstruction { + source_1: RF0, + source_2: RG1, + destination: RG2, + })) + .unwrap(); + assert_eq!(vm.read_reg(RG2), U256::from(43)); + assert_eq!(vm.flags.error_overflow_or_less_than_flag, true); +} + +#[test] +fn test_mul_execution() { + let storage = &mut dummy_storage(); + let mut vm = VmInstance::new( + storage, + &Vec::new(), + dummy_context(), + usize::MAX, + Default::default(), + ) + .unwrap(); + vm.write_reg(RG0, U256::from(1000)); + vm.write_reg(RG1, U256::from(43)); + + vm.dispatch_opcode(Instruction::Mul(MulInstruction { + source_1: RF0, + source_2: RG1, + destination_1: RG2, + destination_2: RG3, + })) + .unwrap(); + + assert_eq!(vm.read_reg(RG2), U256::from(43000)); + assert_eq!(vm.flags.error_overflow_or_less_than_flag, true); + assert_eq!(vm.flags.greater_than_flag, false); +} + +#[test] +fn test_mul_execution_overflow() { + let storage = &mut dummy_storage(); + let mut vm = VmInstance::new( + storage, + &Vec::new(), + dummy_context(), + usize::MAX, + Default::default(), + ) + .unwrap(); + vm.write_reg(RG0, (U256::max_value() - 1) / 2); + vm.write_reg(RG1, U256::from(3)); + + vm.dispatch_opcode(Instruction::Mul(MulInstruction { + source_1: RF0, + source_2: RG1, + destination_1: RG2, + destination_2: RG3, + })) + .unwrap(); + + assert_eq!(vm.read_reg(RG2), (U256::max_value() - 4) / 2); + assert_eq!(vm.read_reg(RG3), U256::one()); + assert_eq!(vm.flags.error_overflow_or_less_than_flag, false); + assert_eq!(vm.flags.greater_than_flag, true); +} + +#[test] +fn test_div_execution() { + let storage = &mut dummy_storage(); + let mut vm = VmInstance::new( + storage, + &Vec::new(), + dummy_context(), + usize::MAX, + Default::default(), + ) + .unwrap(); + vm.write_reg(RG0, U256::from(43)); + vm.write_reg(RG1, U256::from(10)); + + vm.dispatch_opcode(Instruction::Div(DivInstruction { + source_1: RF0, + source_2: RG1, + quotient_destination: RG2, + remainder_destination: RG3, + swap_operands: false, + })) + .unwrap(); + + assert_eq!(vm.read_reg(RG2), U256::from(4)); + assert_eq!(vm.read_reg(RG3), U256::from(3)); + assert_eq!(vm.flags.error_overflow_or_less_than_flag, false); + assert_eq!(vm.flags.equality_flag, false); + assert_eq!(vm.flags.greater_than_flag, true); +} + +#[test] +fn test_div_execution_zero() { + let storage = &mut dummy_storage(); + let mut vm = VmInstance::new( + storage, + &Vec::new(), + dummy_context(), + usize::MAX, + Default::default(), + ) + .unwrap(); + + vm.write_reg(RG0, U256::from(43)); + vm.write_reg(RG1, U256::from(0)); + + vm.dispatch_opcode(Instruction::Div(DivInstruction { + source_1: RF0, + source_2: RG1, + quotient_destination: RG2, + remainder_destination: RG3, + swap_operands: false, + })) + .unwrap(); + + assert_eq!(vm.read_reg(RG2), U256::from(0)); + assert_eq!(vm.read_reg(RG3), U256::from(0)); + assert_eq!(vm.flags.error_overflow_or_less_than_flag, false); + assert_eq!(vm.flags.equality_flag, true); + assert_eq!(vm.flags.greater_than_flag, true); +} + +#[test] +fn test_div_execution_both_zero() { + let storage = &mut dummy_storage(); + let mut vm = VmInstance::new( + storage, + &Vec::new(), + dummy_context(), + usize::MAX, + Default::default(), + ) + .unwrap(); + vm.write_reg(RG0, U256::from(0)); + vm.write_reg(RG1, U256::from(0)); + + vm.dispatch_opcode(Instruction::Div(DivInstruction { + source_1: RF0, + source_2: RG1, + quotient_destination: RG2, + remainder_destination: RG3, + swap_operands: false, + })) + .unwrap(); + + assert_eq!(vm.read_reg(RG2), U256::from(0)); + assert_eq!(vm.read_reg(RG3), U256::from(0)); + assert_eq!(vm.flags.error_overflow_or_less_than_flag, false); + assert_eq!(vm.flags.equality_flag, true); + assert_eq!(vm.flags.greater_than_flag, false); +} + +#[test] +fn test_shuffle_lowest() { + let storage = &mut dummy_storage(); + let mut vm = VmInstance::new( + storage, + &Vec::new(), + dummy_context(), + usize::MAX, + Default::default(), + ) + .unwrap(); + vm.dispatch_opcode(Instruction::Shuffle(ShuffleInstruction { + source_1: FullOperand::Immediate(43), + source_2: NULL, + destination: RG3, + load_in_low: true, + })) + .unwrap(); + + assert_eq!(vm.read_reg(RG3), U256::from(43)); + assert_eq!(vm.flags.error_overflow_or_less_than_flag, false); + assert_eq!(vm.flags.equality_flag, false); + assert_eq!(vm.flags.greater_than_flag, false); +} + +#[test] +fn test_immediate_highest() { + let storage = &mut dummy_storage(); + let mut vm = VmInstance::new( + storage, + &Vec::new(), + dummy_context(), + usize::MAX, + Default::default(), + ) + .unwrap(); + vm.dispatch_opcode(Instruction::Shuffle(ShuffleInstruction { + source_1: FullOperand::Immediate(43), + source_2: NULL, + destination: RG3, + load_in_low: false, + })) + .unwrap(); + + assert_eq!(vm.read_reg(RG3), (U256::from(u128::MAX) + 1) * 43); + assert_eq!(vm.flags.error_overflow_or_less_than_flag, false); + assert_eq!(vm.flags.equality_flag, false); + assert_eq!(vm.flags.greater_than_flag, false); +} + +#[test] +fn test_hash_zero() { + let storage = &mut dummy_storage(); + let mut vm = VmInstance::new( + storage, + &Vec::new(), + dummy_context(), + usize::MAX, + Default::default(), + ) + .unwrap(); + vm.write_reg(RG1, U256::from(123)); + + vm.dispatch_opcode(Instruction::HashOutput(HashOutputInstruction { + destination: RG1, + })) + .unwrap(); + + assert_eq!(vm.read_reg(RG1), U256::zero()); +} + +#[test] +fn test_hash_reset() { + let assembly = Assembly { + instructions: vec![ + Instruction::HashAbsorb(HashAbsorbInstruction { + source: RF1, + reset: false, + }), + Instruction::HashAbsorb(HashAbsorbInstruction { + source: RF2, + reset: true, + }), + Instruction::HashOutput(HashOutputInstruction { destination: RG3 }), + OP_RETURN, + ], + labels: HashMap::new(), + assembly_code: "".to_string(), + pc_line_mapping: Default::default(), + }; + + let VmSnapshot { registers, .. } = run_vm( + assembly, + Vec::new(), + HashMap::new(), + vec![U256::zero(), U256::from(123), U256::zero()], + None, + VmLaunchOption::Default, + usize::MAX, + ); + + assert_eq!( + registers[3], + U256::from_dec_str( + "5862139083026206628832301127335791535962889136620943667582563443715053309945" + ) + .unwrap() + ); +} + +#[test] +fn test_hash() { + let assembly = Assembly { + instructions: vec![ + Instruction::HashAbsorb(HashAbsorbInstruction { + source: RF1, + reset: false, + }), + Instruction::HashAbsorb(HashAbsorbInstruction { + source: RF2, + reset: false, + }), + Instruction::HashOutput(HashOutputInstruction { destination: RG3 }), + OP_RETURN, + ], + labels: HashMap::new(), + assembly_code: "".to_string(), + pc_line_mapping: Default::default(), + }; + + let VmSnapshot { registers, .. } = run_vm( + assembly, + Vec::new(), + HashMap::new(), + vec![U256::zero(), U256::from(123), U256::from(125)], + None, + VmLaunchOption::Default, + usize::MAX, + ); + + assert_eq!( + registers[3], + U256::from_dec_str( + "9683768255054160865462551840877242526106853161404912121878200381733926296023" + ) + .unwrap() + ); +} + +#[test] +fn test_jump() { + // the second instruction will be skipped + let assembly = Assembly { + instructions: vec![ + Instruction::Jump(JumpInstruction { + source: FullOperand::Register(NULL), + flags: vec![JumpFlag::Unconditional], + destination_true: 2, + destination_false: 1, + }), + Instruction::Shuffle(ShuffleInstruction { + source_1: FullOperand::Immediate(17), + source_2: NULL, + destination: RG0, + load_in_low: true, + }), + Instruction::Shuffle(ShuffleInstruction { + source_1: FullOperand::Immediate(42), + source_2: NULL, + destination: RG2, + load_in_low: true, + }), + OP_RETURN, + ], + labels: HashMap::new(), + assembly_code: "".to_string(), + pc_line_mapping: Default::default(), + }; + + let VmSnapshot { registers, .. } = run_vm( + assembly, + Vec::new(), + HashMap::new(), + vec![U256::zero(), U256::from(123), U256::from(125)], + None, + VmLaunchOption::Default, + usize::MAX, + ); + + assert_eq!(registers[2], U256::from(42)); + assert_eq!(registers[0], U256::from(0)); +} + +#[test] +fn test_jump_source_zero() { + let assembly = Assembly { + instructions: vec![ + Instruction::Jump(JumpInstruction { + source: RF0, + flags: vec![], + // should jump here + destination_true: 2, + destination_false: 1, + }), + // this instruction should be skipped + Instruction::Shuffle(ShuffleInstruction { + source_1: FullOperand::Immediate(17), + source_2: NULL, + destination: RG2, + load_in_low: true, + }), + Instruction::Shuffle(ShuffleInstruction { + source_1: FullOperand::Immediate(42), + source_2: NULL, + destination: RG3, + load_in_low: true, + }), + Instruction::Jump(JumpInstruction { + source: RF1, + flags: vec![], + destination_true: 5, + // should jump here - no skipped instructions + destination_false: 4, + }), + Instruction::Shuffle(ShuffleInstruction { + source_1: FullOperand::Immediate(17), + source_2: NULL, + destination: RG4, + load_in_low: true, + }), + Instruction::Shuffle(ShuffleInstruction { + source_1: FullOperand::Immediate(42), + source_2: NULL, + destination: RG5, + load_in_low: true, + }), + OP_RETURN, + ], + labels: HashMap::new(), + assembly_code: "".to_string(), + pc_line_mapping: Default::default(), + }; + + let VmSnapshot { registers, .. } = run_vm( + assembly, + // first register: first two bytes are not zero, flag evaluates to true + // second register: first two bytes are zero, flag evaluates to false + Vec::new(), + HashMap::new(), + vec![U256::from(1 << 15), U256::from(1 << 17)], + None, + VmLaunchOption::Default, + usize::MAX, + ); + + assert_eq!(registers[2], U256::from(0)); + assert_eq!(registers[3], U256::from(42)); + assert_eq!(registers[4], U256::from(17)); + assert_eq!(registers[5], U256::from(42)); +} + +#[test] +fn test_mul_memory_stack() { + let assembly = Assembly { + instructions: vec![ + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::Stack { force: true }, + offset: 0, + register: NULL, + }, + operation: DataOperation::Write { source: RG0 }, + }), + Instruction::Shuffle(ShuffleInstruction { + source_1: FullOperand::Immediate(20), + source_2: NULL, + destination: RG1, + load_in_low: true, + }), + Instruction::Mul(MulInstruction { + source_1: FullOperand::Memory(MemoryOperand { + r#type: MemoryType::Stack { force: true }, + offset: 0, // pop one element - the one added in the preceding memory op (= 7) + register: RegisterOperand::Null, + }), + source_2: RG1, // = 20 + destination_1: RG2, + destination_2: RG3, + }), + OP_RETURN, + ], + labels: HashMap::new(), + + assembly_code: "".to_string(), + pc_line_mapping: Default::default(), + }; + + let VmSnapshot { + registers, + first_contract_stack, + .. + } = run_vm( + assembly, + Vec::new(), + HashMap::new(), + vec![U256::from(7)], + None, + VmLaunchOption::Default, + usize::MAX, + ); + + assert_eq!(registers[2], U256::from(140)); + // make sure stack pop clears the poped element + assert_eq!(first_contract_stack.read(0).unwrap(), U256::zero()); +} + +#[test] +fn test_mul_memory_local() { + let assembly = Assembly { + instructions: vec![ + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::Local, + offset: 5, + register: RG0, // = 3 + }, + operation: DataOperation::Write { source: RG1 }, // = 5 + }), + Instruction::Shuffle(ShuffleInstruction { + source_1: FullOperand::Immediate(20), + source_2: NULL, + destination: RG1, + load_in_low: true, + }), + Instruction::Mul(MulInstruction { + source_1: FullOperand::Memory(MemoryOperand { + r#type: MemoryType::Local, + offset: 8, + register: RegisterOperand::Null, + }), // = 5 + source_2: RG1, // = 20 + destination_1: RG2, + destination_2: RG3, + }), + OP_RETURN, + ], + labels: HashMap::new(), + + assembly_code: "".to_string(), + pc_line_mapping: Default::default(), + }; + + let VmSnapshot { + registers, + first_contract_local_memory, + .. + } = run_vm( + assembly, + Vec::new(), + HashMap::new(), + vec![U256::from(3), U256::from(5)], + None, + VmLaunchOption::Default, + usize::MAX, + ); + + assert_eq!(registers[2], U256::from(100)); + assert_eq!(first_contract_local_memory.read(8).unwrap(), U256::from(5)); +} + +#[test] +fn test_jump_lesser_than() { + let assembly = Assembly { + instructions: vec![ + Instruction::Sub(SubInstruction { + source_1: RF0, + source_2: RG1, + destination: NULL, // we only need it to set flags + swap_operands: false, + }), + Instruction::Jump(JumpInstruction { + source: FullOperand::Register(NULL), + flags: vec![JumpFlag::LesserThan], + // should jump here + destination_true: 3, + destination_false: 2, + }), + // this instruction should be skipped + Instruction::Shuffle(ShuffleInstruction { + source_1: FullOperand::Immediate(17), + source_2: NULL, + destination: RG2, + load_in_low: true, + }), + Instruction::Shuffle(ShuffleInstruction { + source_1: FullOperand::Immediate(42), + source_2: NULL, + destination: RG3, + load_in_low: true, + }), + OP_RETURN, + ], + labels: HashMap::new(), + + assembly_code: "".to_string(), + pc_line_mapping: Default::default(), + }; + + let VmSnapshot { registers, .. } = run_vm( + assembly, + Vec::new(), + HashMap::new(), + vec![U256::from(5), U256::from(7)], + None, + VmLaunchOption::Default, + usize::MAX, + ); + + assert_eq!(registers[2], U256::zero()); + assert_eq!(registers[3], U256::from(42)); +} + +#[test] +fn test_memory_stack_push_pop() { + let assembly = Assembly { + instructions: vec![ + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::Stack { force: true }, + offset: 0, + register: NULL, + }, + operation: DataOperation::Write { source: RG0 }, + }), + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::Stack { force: true }, + offset: 1, // pushes two elements: zero and RG1 + register: NULL, + }, + operation: DataOperation::Write { source: RG1 }, + }), + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::Stack { force: true }, + offset: 0, + register: NULL, + }, + operation: DataOperation::Write { source: RG2 }, + }), + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::Stack { force: true }, + offset: 0, + register: RG3, // RG3 == 1: raw_mem_offset = 1. POP two elements. + }, + operation: DataOperation::Read { destination: RG3 }, + }), + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::Stack { force: true }, + offset: 0, + register: RG4, // RG4 == 0: raw_mem_offset = 1. + }, + operation: DataOperation::Read { destination: RG4 }, + }), + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::Stack { force: true }, + offset: 0, + register: RG4, // RG4 == 0: raw_mem_offset = 1. + }, + operation: DataOperation::Read { destination: RG5 }, + }), + OP_RETURN, + ], + labels: HashMap::new(), + assembly_code: "".to_string(), + pc_line_mapping: Default::default(), + }; + + let VmSnapshot { registers, .. } = run_vm( + assembly, + Vec::new(), + HashMap::new(), + vec![ + U256::from(201), + U256::from(202), + U256::from(203), + U256::from(1), + ], + None, + VmLaunchOption::Default, + usize::MAX, + ); + + assert_eq!(registers[3], U256::from(202)); + assert_eq!(registers[4], U256::from(0)); + assert_eq!(registers[5], U256::from(201)); +} + +#[test] +fn test_memory_push_pop() { + let assembly = Assembly { + instructions: vec![ + Instruction::Memory(MemoryInstruction { + // bump sp to 1 + address: MemoryOperand { + r#type: MemoryType::Stack { force: true }, + offset: 0, + register: NULL, + }, + operation: DataOperation::Write { source: RG0 }, + }), + Instruction::Memory(MemoryInstruction { + // bump sp to 3 + address: MemoryOperand { + r#type: MemoryType::Stack { force: true }, + offset: 1, + register: NULL, + }, + operation: DataOperation::Write { source: RG1 }, + }), + Instruction::Memory(MemoryInstruction { + // bump sp to 5 + address: MemoryOperand { + r#type: MemoryType::Stack { force: true }, + offset: 1, + register: NULL, + }, + operation: DataOperation::Write { source: RG2 }, + }), + Instruction::Memory(MemoryInstruction { + // sp is down to 2 + address: MemoryOperand { + r#type: MemoryType::Stack { force: true }, + offset: 2, + register: NULL, + }, + operation: DataOperation::Read { destination: RG3 }, // value of RG1 goes here + }), + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + // sp is down to 1 + r#type: MemoryType::Stack { force: true }, + offset: 0, + register: NULL, + }, + operation: DataOperation::Read { destination: RG4 }, // NULL goes here + }), + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + // sp is down to 0 + r#type: MemoryType::Stack { force: true }, + offset: 0, + register: NULL, + }, + operation: DataOperation::Read { destination: RG5 }, //value of RG0 goes here + }), + OP_RETURN, + ], + labels: HashMap::new(), + assembly_code: "".to_string(), + pc_line_mapping: Default::default(), + }; + + let VmSnapshot { + registers, + first_contract_stack, + .. + } = run_vm( + assembly, + Vec::new(), + HashMap::new(), + vec![U256::from(10), U256::from(20)], + None, + VmLaunchOption::Default, + usize::MAX, + ); + + assert_eq!(first_contract_stack.read(0).unwrap(), U256::default()); + assert_eq!(first_contract_stack.read(1).unwrap(), U256::default()); + assert_eq!(first_contract_stack.read(2).unwrap(), U256::default()); + assert_eq!(first_contract_stack.read(3).unwrap(), U256::default()); + assert_eq!(first_contract_stack.read(4).unwrap(), U256::default()); + assert_eq!(registers[3], U256::from(20)); + assert_eq!(registers[4], U256::from(0)); + assert_eq!(registers[5], U256::from(10)); +} + +#[test] +fn test_storage() { + let assembly = Assembly { + instructions: vec![ + Instruction::Storage(StorageInstruction::Storage { + storage_key: RF0, + operation: DataOperation::Write { source: RG1 }, + is_external_storage_access: false, + }), + Instruction::Storage(StorageInstruction::Storage { + storage_key: RF0, + operation: DataOperation::Read { destination: RG2 }, + is_external_storage_access: false, + }), + OP_RETURN, + ], + labels: HashMap::new(), + assembly_code: "".to_string(), + pc_line_mapping: Default::default(), + }; + + let address1 = Address::random(); + let address2 = Address::random(); + + let address_to_u256 = |addr| h256_to_u256(address_to_h256(&addr)); + + let mut storage = HashMap::new(); + set_account_type(&mut storage, &Address::zero(), &AccountType::ZkRollup); + + let VmSnapshot { + registers, storage, .. + } = run_vm( + assembly, + Vec::new(), + storage, + vec![address_to_u256(address1), address_to_u256(address2)], + None, + VmLaunchOption::Default, + usize::MAX, + ); + + assert_eq!(registers[2], address_to_u256(address2)); + assert_eq!( + storage.get(&StorageKey::UserKey( + AccountTreeId::Rollup(Address::zero()), + AccountTreeId::Rollup(Address::zero()), + address_to_h256(&address1) + )), + Some(&address_to_h256(&address2)) + ); +} + +#[test] +fn test_limit_cycles() { + let assembly = Assembly { + instructions: vec![ + Instruction::Context(ContextInstruction { + destination: RG0, + field: ContextField::RemainingCycles, + }), + Instruction::Sub(SubInstruction { + source_1: FullOperand::Immediate(100), + source_2: RG0, + destination: NULL, + swap_operands: false, + }), // use this to compare current cycles to 100. It's more than 100 *before* the jump, and it's less *after*. + Instruction::Jump(JumpInstruction { + source: FullOperand::Register(NULL), + flags: vec![JumpFlag::LesserThan], + destination_true: 3, + destination_false: 5, + }), + Instruction::SwitchContext, + Instruction::FunctionJump(FunctionJumpInstruction::Call { + location: FunctionJumpLocation::External { + operand: FullOperand::Immediate(10 << 16), // bytes 2..4 represent `num_passed_cycles` + is_delegate: false, + }, + }), + Instruction::Context(ContextInstruction { + destination: RG1, + field: ContextField::RemainingCycles, + }), + Instruction::FunctionJump(FunctionJumpInstruction::Return { error: false }), + ], + labels: Default::default(), + assembly_code: "".to_string(), + pc_line_mapping: Default::default(), + }; + + let res_reg: [U256; 6] = run_vm( + assembly, + Vec::new(), + HashMap::new(), + vec![], + None, + VmLaunchOption::Default, + usize::MAX, + ) + .registers; + + assert_eq!(res_reg[0], U256::from(9)); + assert_eq!(res_reg[1], U256::from(usize::MAX - 11)); +} + +#[test] +fn test_rollback_multiple_contracts_explicit_error() { + let callee_1_contract_address = H160::from_low_u64_le(366); + let mut contract_1_address_bytes = callee_1_contract_address.as_bytes().to_vec(); + contract_1_address_bytes.reverse(); + let callee_2_contract_address = H160::from_low_u64_le(239); + let mut contract_2_address_bytes = callee_2_contract_address.as_bytes().to_vec(); + contract_2_address_bytes.reverse(); + let mut function_jump_calldata_bytes = vec![0u8; 32]; + function_jump_calldata_bytes.splice(4..24, contract_1_address_bytes); + let callee_1_calldata = U256::from_little_endian(&function_jump_calldata_bytes); + function_jump_calldata_bytes.splice(4..24, contract_2_address_bytes); + let callee_2_calldata = U256::from_little_endian(&function_jump_calldata_bytes); + + let main_contract = Assembly { + instructions: vec![ + Instruction::Storage(StorageInstruction::Storage { + storage_key: FullOperand::Immediate(42), + operation: DataOperation::Write { source: RG0 }, + is_external_storage_access: false, + }), + Instruction::SwitchContext, + Instruction::FunctionJump(FunctionJumpInstruction::Call { + location: FunctionJumpLocation::External { + operand: FullOperand::Register(RG2), + is_delegate: false, + }, + }), + Instruction::Storage(StorageInstruction::Storage { + storage_key: FullOperand::Immediate(34), + operation: DataOperation::Write { source: RG0 }, + is_external_storage_access: false, + }), + Instruction::FunctionJump(FunctionJumpInstruction::Return { error: false }), + ], + labels: Default::default(), + assembly_code: "".to_string(), + pc_line_mapping: Default::default(), + }; + + let callee_contract_1 = Assembly { + instructions: vec![ + Instruction::Storage(StorageInstruction::Storage { + storage_key: FullOperand::Immediate(44), + operation: DataOperation::Write { source: RG0 }, + is_external_storage_access: false, + }), + Instruction::SwitchContext, + Instruction::FunctionJump(FunctionJumpInstruction::Call { + location: FunctionJumpLocation::External { + operand: FullOperand::Register(RG3), + is_delegate: false, + }, + }), + // we return with an explicit error. This contract and the callee contract will be reverted. + Instruction::FunctionJump(FunctionJumpInstruction::Return { error: true }), + ], + labels: Default::default(), + assembly_code: "".to_string(), + pc_line_mapping: Default::default(), + }; + + let callee_contract_2 = Assembly { + instructions: vec![ + Instruction::Storage(StorageInstruction::Storage { + storage_key: FullOperand::Immediate(50), + operation: DataOperation::Write { source: RG0 }, + is_external_storage_access: false, + }), + Instruction::FunctionJump(FunctionJumpInstruction::Return { error: false }), + ], + labels: Default::default(), + assembly_code: "".to_string(), + pc_line_mapping: Default::default(), + }; + + let mut loaded_contracts: HashMap = HashMap::new(); + loaded_contracts.insert(Address::default(), main_contract); + loaded_contracts.insert(callee_1_contract_address, callee_contract_1); + loaded_contracts.insert(callee_2_contract_address, callee_contract_2); + + let mut storage = HashMap::new(); + set_account_type(&mut storage, &Address::default(), &AccountType::ZkRollup); + set_account_type( + &mut storage, + &callee_1_contract_address, + &AccountType::ZkRollup, + ); + set_account_type( + &mut storage, + &callee_2_contract_address, + &AccountType::ZkRollup, + ); + + let VmSnapshot { storage, .. } = run_vm_multi_contracts( + loaded_contracts, + Vec::new(), + storage, + vec![ + U256::from(10), + U256::from(12), + callee_1_calldata, + callee_2_calldata, + ], + Address::default(), + None, + VmLaunchOption::Default, + usize::MAX, + ); + assert_eq!( + storage.get(&StorageKey::new_user( + Rollup(Address::default()), + Rollup(Address::default()), + H256::from_low_u64_be(42) + )), + Some(&H256::from_low_u64_be(10)) + ); // the storage write from the entry contract shouldn't be rollback + assert_eq!( + storage.get(&StorageKey::new_user( + Rollup(Address::default()), + Rollup(Address::default()), + H256::from_low_u64_be(34) + )), + Some(&H256::from_low_u64_be(10)) + ); // the storage write from the entry contract shouldn't be rollback + assert_eq!( + storage.get(&StorageKey::new_user( + Rollup(callee_1_contract_address), + Rollup(callee_1_contract_address), + H256::from_low_u64_be(44) + )), + Some(&H256::zero()) + ); // callee storages must be reverted + assert_eq!( + storage.get(&StorageKey::new_user( + Rollup(callee_2_contract_address), + Rollup(callee_2_contract_address), + H256::from_low_u64_be(50) + )), + Some(&H256::zero()) + ); // callee storages must be reverted +} + +#[test] +fn test_local_call_memory_sharing() { + let assembly = Assembly { + instructions: vec![ + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::Local, + offset: 239, + register: NULL, + }, + operation: DataOperation::Write { source: RG1 }, + }), + Instruction::FunctionJump(FunctionJumpInstruction::Call { + location: FunctionJumpLocation::Local { + address: 4, // pc + operand: FullOperand::Immediate(0), + }, + }), + // read from stack - callee contract wrote there + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::Stack { force: true }, + offset: 0, + register: NULL, + }, + operation: DataOperation::Read { destination: RG2 }, + }), + Instruction::FunctionJump(FunctionJumpInstruction::Return { error: false }), + // local jump goes here + // read value saved by calling contract + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::Local, + offset: 239, + register: NULL, + }, + operation: DataOperation::Read { destination: RG3 }, + }), + // write to stack - calling contract should be able to pop it + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::Stack { force: true }, + offset: 0, + register: NULL, + }, + operation: DataOperation::Write { source: RG0 }, + }), + // return back to the entry frame + Instruction::FunctionJump(FunctionJumpInstruction::Return { error: true }), + ], + labels: Default::default(), + assembly_code: "".to_string(), + pc_line_mapping: Default::default(), + }; + + let VmSnapshot { registers, .. } = run_vm( + assembly, + Vec::new(), + HashMap::new(), + vec![U256::from(366), U256::from(30)], + None, + VmLaunchOption::Default, + usize::MAX, + ); + assert_eq!(registers[2], U256::from(366)); + assert_eq!(registers[3], U256::from(30)); +} + +#[test] +fn test_delegate_call_memory_sharing() { + let callee_contract_address = H160::from_low_u64_le(366); + let mut function_jump_calldata_bytes = vec![0u8; 32]; + let mut contract_address_bytes = callee_contract_address.as_bytes().to_vec(); + contract_address_bytes.reverse(); + function_jump_calldata_bytes.splice(4..24, contract_address_bytes); + let callee_calldata = U256::from_little_endian(&function_jump_calldata_bytes); + + let assembly_main = Assembly { + instructions: vec![ + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::Local, + offset: 239, + register: NULL, + }, + operation: DataOperation::Write { source: RG1 }, + }), + Instruction::FunctionJump(FunctionJumpInstruction::Call { + location: FunctionJumpLocation::External { + is_delegate: true, + operand: FullOperand::Register(RG2), + }, + }), + // read from stack - callee contract wrote there + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::Stack { force: true }, + offset: 0, + register: NULL, + }, + operation: DataOperation::Read { destination: RG2 }, + }), + Instruction::FunctionJump(FunctionJumpInstruction::Return { error: false }), + ], + labels: Default::default(), + assembly_code: "".to_string(), + pc_line_mapping: Default::default(), + }; + + let assembly_callee = Assembly { + instructions: vec![ + // read value saved by calling contract + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::Local, + offset: 239, + register: NULL, + }, + operation: DataOperation::Read { destination: RG3 }, + }), + // write to stack - calling contract should be able to pop it + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::Stack { force: true }, + offset: 0, + register: NULL, + }, + operation: DataOperation::Write { source: RG0 }, + }), + // return back to the entry frame + Instruction::FunctionJump(FunctionJumpInstruction::Return { error: true }), + ], + labels: Default::default(), + assembly_code: "".to_string(), + pc_line_mapping: Default::default(), + }; + + let mut loaded_contracts: HashMap = HashMap::new(); + loaded_contracts.insert(Address::default(), assembly_main); + loaded_contracts.insert(callee_contract_address, assembly_callee); + + let VmSnapshot { registers, .. } = run_vm_multi_contracts( + loaded_contracts, + Vec::new(), + HashMap::new(), + vec![U256::from(366), U256::from(30), callee_calldata], + Address::default(), + None, + VmLaunchOption::Default, + usize::MAX, + ); + + assert_eq!(registers[2], U256::from(366)); + assert_eq!(registers[3], U256::from(30)); +} + +#[test] +fn test_limit_cycles_exception() { + let assembly = Assembly { + instructions: vec![ + Instruction::Context(ContextInstruction { + destination: RG0, + field: ContextField::RemainingCycles, + }), + Instruction::Context(ContextInstruction { + destination: RG1, + field: ContextField::RemainingCycles, + }), + Instruction::SwitchContext, + Instruction::FunctionJump(FunctionJumpInstruction::Call { + location: FunctionJumpLocation::External { + operand: FullOperand::Immediate(1 << 16), // bytes 2..4 represent `num_passed_cycles`. Only pass one cycle. + is_delegate: false, + }, + }), + Instruction::Jump(JumpInstruction { + source: FullOperand::Register(NULL), + //make sure the Lesser flag is set (== exception flag) + flags: vec![JumpFlag::LesserThan], + destination_true: 5, + destination_false: 6, + }), + Instruction::Shuffle(ShuffleInstruction { + source_1: FullOperand::Immediate(42), + source_2: NULL, + destination: RG2, + load_in_low: true, + }), + Instruction::FunctionJump(FunctionJumpInstruction::Return { error: false }), + ], + labels: Default::default(), + assembly_code: "".to_string(), + pc_line_mapping: Default::default(), + }; + + let VmSnapshot { + registers, + execution_result, + .. + } = run_vm( + assembly, + Vec::new(), + HashMap::new(), + vec![], + None, + VmLaunchOption::Default, + usize::MAX, + ); + + assert_eq!( + execution_result.internal_errors, + vec![(Address::default(), "Ran out of cycles.".to_owned())] + ); + assert_eq!(registers[0], U256::from(0)); + assert_eq!(registers[1], U256::from(usize::MAX - 2)); // make sure the second operation (Instruction::Cycles(CyclesInstruction { destination: RG1 })) only ran once + assert_eq!(registers[2], U256::from(42)); +} + +#[test] +fn test_events_multi_contract() { + let callee_contract_address = H160::from_low_u64_le(366); + let mut function_jump_calldata_bytes = vec![0u8; 32]; + let mut contract_address_bytes = callee_contract_address.as_bytes().to_vec(); + contract_address_bytes.reverse(); + function_jump_calldata_bytes.splice(4..24, contract_address_bytes); + let callee_calldata = U256::from_little_endian(&function_jump_calldata_bytes); + + let assembly_main = Assembly { + instructions: vec![ + Instruction::Storage(StorageInstruction::LogInit { + packed_lengths: packed_log_lengths(2, 32), + first_topic_or_chunk: RG2, // 533 + }), + Instruction::Storage(StorageInstruction::Log(FullOperand::Immediate(777), RG3)), //366366366 + Instruction::SwitchContext, + Instruction::FunctionJump(FunctionJumpInstruction::Call { + location: FunctionJumpLocation::External { + // call `assembly_callee` + operand: FullOperand::Register(RG1), + is_delegate: false, + }, + }), + Instruction::FunctionJump(FunctionJumpInstruction::Return { error: false }), + ], + labels: Default::default(), + assembly_code: "".to_string(), + pc_line_mapping: Default::default(), + }; + + let assembly_callee = Assembly { + instructions: vec![ + Instruction::Storage(StorageInstruction::LogInit { + packed_lengths: packed_log_lengths(1, 32), + first_topic_or_chunk: RG2, // 533 + }), + Instruction::Storage(StorageInstruction::Log( + FullOperand::Immediate(239239239), + NULL, + )), + Instruction::FunctionJump(FunctionJumpInstruction::Return { error: false }), + ], + labels: Default::default(), + assembly_code: "".to_string(), + pc_line_mapping: Default::default(), + }; + + let mut loaded_contracts: HashMap = HashMap::new(); + loaded_contracts.insert(Address::default(), assembly_main); + loaded_contracts.insert(callee_contract_address, assembly_callee); + + let VmSnapshot { + execution_result: VmExecutionResult { events, .. }, + .. + } = run_vm_multi_contracts( + loaded_contracts, + Vec::new(), + HashMap::new(), + vec![ + U256::from(32), + callee_calldata, + U256::from(533), + U256::from(366366366), + ], + Address::default(), + None, + VmLaunchOption::Default, + usize::MAX, + ); + + let mut value1_bytes = [0u8; 32]; + let mut value2_bytes = [0u8; 32]; + + U256::from(366366366).to_big_endian(&mut value1_bytes); + U256::from(239239239).to_big_endian(&mut value2_bytes); + + // only one event should be emitted - + // the event in the callee contract is rolled back due to exception + assert_eq!(events.len(), 2); + assert_eq!( + events[0], + VmEvent { + address: Address::default(), + location: (BlockNumber(0), 0), + indexed_topics: vec!(H256::from_low_u64_be(533), H256::from_low_u64_be(777)), + value: value1_bytes.to_vec() + } + ); + assert_eq!( + events[1], + VmEvent { + address: callee_contract_address, + location: (BlockNumber(0), 0), + indexed_topics: vec!(H256::from_low_u64_be(533)), + value: value2_bytes.to_vec() + } + ); +} + +#[test] +fn test_events_multi_contract_exception() { + let callee_contract_address = H160::from_low_u64_le(366); + let mut function_jump_calldata_bytes = vec![0u8; 32]; + let mut contract_address_bytes = callee_contract_address.as_bytes().to_vec(); + contract_address_bytes.reverse(); + function_jump_calldata_bytes.splice(4..24, contract_address_bytes); + let callee_calldata = U256::from_little_endian(&function_jump_calldata_bytes); + + let assembly_main = Assembly { + instructions: vec![ + Instruction::Storage(StorageInstruction::LogInit { + packed_lengths: packed_log_lengths(1, 59), + first_topic_or_chunk: RG2, //533 + }), + Instruction::Storage(StorageInstruction::Log( + FullOperand::Immediate(366366366), + RG3, //544544544 + )), + Instruction::SwitchContext, + Instruction::FunctionJump(FunctionJumpInstruction::Call { + location: FunctionJumpLocation::External { + // call `assembly_callee` + operand: FullOperand::Register(RG1), + is_delegate: false, + }, + }), + Instruction::FunctionJump(FunctionJumpInstruction::Return { error: false }), + ], + labels: Default::default(), + assembly_code: "".to_string(), + pc_line_mapping: Default::default(), + }; + + let assembly_callee = Assembly { + instructions: vec![ + Instruction::Storage(StorageInstruction::LogInit { + packed_lengths: packed_log_lengths(1, 59), + first_topic_or_chunk: RG2, + }), + Instruction::Storage(StorageInstruction::Log( + FullOperand::Immediate(544544544), + NULL, + )), + Instruction::FunctionJump(FunctionJumpInstruction::Return { error: true }), + ], + labels: Default::default(), + assembly_code: "".to_string(), + pc_line_mapping: Default::default(), + }; + + let mut loaded_contracts: HashMap = HashMap::new(); + loaded_contracts.insert(Address::default(), assembly_main); + loaded_contracts.insert(callee_contract_address, assembly_callee); + + let VmSnapshot { + execution_result: + VmExecutionResult { + events, + internal_errors, + .. + }, + .. + } = run_vm_multi_contracts( + loaded_contracts, + Vec::new(), + HashMap::new(), + vec![ + U256::from(59), + callee_calldata, + U256::from(533), + U256::from(544544544), + ], // 32 + 27 bytes + Address::default(), + None, + VmLaunchOption::Default, + usize::MAX, + ); + + let mut topic_bytes = [0u8; 32]; + let mut value_bytes = [0u8; 64]; + + U256::from(533).to_little_endian(&mut topic_bytes); + U256::from(366366366).to_big_endian(&mut value_bytes[0..32]); + U256::from(544544544).to_big_endian(&mut value_bytes[32..64]); + assert_eq!( + internal_errors, + vec![( + callee_contract_address, + "Contract execution resulted in a revert".to_owned() + )] + ); + // only one event should be emitted - + // the event in the callee contract is rolled back due to exception + assert_eq!(events.len(), 1); + assert_eq!( + events[0], + VmEvent { + address: Address::default(), + location: (BlockNumber(0), 0), + indexed_topics: vec!(H256::from_low_u64_be(533)), + value: value_bytes[0..59].to_vec() + } + ); +} + +#[test] +fn test_context_contract_addresses() { + let contract_address = H160::from_low_u64_le(366); + let assembly = Assembly { + instructions: vec![ + Instruction::Context(ContextInstruction { + destination: RG0, + field: ContextField::CurrentAddress, + }), + Instruction::FunctionJump(FunctionJumpInstruction::Return { error: false }), + ], + labels: Default::default(), + assembly_code: "".to_string(), + pc_line_mapping: Default::default(), + }; + + let mut loaded_contracts: HashMap = HashMap::new(); + loaded_contracts.insert(contract_address, assembly); + + let VmSnapshot { registers, .. } = run_vm_multi_contracts( + loaded_contracts, + Vec::new(), + HashMap::new(), + vec![], + contract_address, + None, + VmLaunchOption::Default, + usize::MAX, + ); + + assert_eq!( + registers[0], + h256_to_u256(address_to_h256(&contract_address)) + ); +} + +#[test] +fn test_context_msg_sender() { + let callee_contract_address = H160::from_low_u64_le(366); + let mut function_jump_calldata_bytes = vec![0u8; 32]; + let mut contract_address_bytes = callee_contract_address.as_bytes().to_vec(); + contract_address_bytes.reverse(); + function_jump_calldata_bytes.splice(4..24, contract_address_bytes); + let callee_calldata = U256::from_little_endian(&function_jump_calldata_bytes); + + let assembly_main = Assembly { + instructions: vec![ + Instruction::Context(ContextInstruction { + destination: RG1, + field: ContextField::MsgSender, + }), + Instruction::SwitchContext, + Instruction::FunctionJump(FunctionJumpInstruction::Call { + location: FunctionJumpLocation::External { + // call `assembly_callee` + operand: FullOperand::Register(RG0), + is_delegate: false, + }, + }), + Instruction::FunctionJump(FunctionJumpInstruction::Return { error: false }), + ], + labels: Default::default(), + assembly_code: "".to_string(), + pc_line_mapping: Default::default(), + }; + + let assembly_callee = Assembly { + instructions: vec![ + Instruction::Context(ContextInstruction { + destination: RG2, + field: ContextField::MsgSender, + }), + Instruction::FunctionJump(FunctionJumpInstruction::Return { error: true }), + ], + labels: Default::default(), + assembly_code: "".to_string(), + pc_line_mapping: Default::default(), + }; + + let mut loaded_contracts: HashMap = HashMap::new(); + loaded_contracts.insert(H160::from_low_u64_be(777), assembly_main); + loaded_contracts.insert(callee_contract_address, assembly_callee); + + let VmSnapshot { registers, .. } = run_vm_multi_contracts( + loaded_contracts, + Vec::new(), + HashMap::new(), + vec![callee_calldata], // 32 + 27 bytes + H160::from_low_u64_be(777), + Some(VmExecutionContext { + msg_sender: H160::from_low_u64_be(223), + block_number: BlockNumber(0), + transaction_index: 0, + block_timestamp: 0, + entry_address: H160::from_low_u64_be(777), + }), + VmLaunchOption::Default, + usize::MAX, + ); + assert_eq!(registers[1], U256::from(223)); + assert_eq!(registers[2], U256::from(777)); +} + +fn packed_log_lengths(topics: u128, data_bytes: u128) -> FullOperand { + FullOperand::Immediate(topics + (data_bytes << 32)) +} + +fn dummy_storage() -> RawInMemoryStorage { + let mut contracts = HashMap::new(); + + contracts.insert( + Address::default(), + Assembly { + instructions: vec![OP_RETURN], + labels: HashMap::new(), + + assembly_code: "".to_string(), + pc_line_mapping: Default::default(), + }, + ); + RawInMemoryStorage { + values: Default::default(), + contracts, + } +} + +fn dummy_context() -> VmExecutionContext { + VmExecutionContext { + msg_sender: Default::default(), + block_number: BlockNumber(0), + transaction_index: 0, + block_timestamp: 0, + entry_address: Address::default(), + } +} diff --git a/crates/zk_evm/src/abstractions/tracing.rs b/crates/zk_evm/src/tracing.rs similarity index 82% rename from crates/zk_evm/src/abstractions/tracing.rs rename to crates/zk_evm/src/tracing.rs index 8f0cb5f..c226874 100644 --- a/crates/zk_evm/src/abstractions/tracing.rs +++ b/crates/zk_evm/src/tracing.rs @@ -1,3 +1,4 @@ +use zk_evm_abstractions::{aux::MemoryLocation, vm::Memory}; use zkevm_opcode_defs::decoding::{EncodingModeProduction, VmEncodingMode}; use crate::{ @@ -36,28 +37,6 @@ pub struct AfterExecutionData = Encodin pub dst0_mem_location: Option, } -impl Memory for () { - fn execute_partial_query( - &mut self, - _monotonic_cycle_counter: u32, - _query: MemoryQuery, - ) -> MemoryQuery { - unreachable!() - } - - fn specialized_code_query( - &mut self, - _monotonic_cycle_counter: u32, - _query: MemoryQuery, - ) -> MemoryQuery { - unreachable!() - } - - fn read_code_query(&self, _monotonic_cycle_counter: u32, _query: MemoryQuery) -> MemoryQuery { - unreachable!() - } -} - pub trait Tracer = EncodingModeProduction>: std::fmt::Debug { diff --git a/crates/zk_evm/src/utils.rs b/crates/zk_evm/src/utils.rs index 7c054de..de79e02 100644 --- a/crates/zk_evm/src/utils.rs +++ b/crates/zk_evm/src/utils.rs @@ -1,6 +1,7 @@ -use crate::U256; -use zkevm_opcode_defs::decoding::VmEncodingMode; +use crate::tracing::*; +use zk_evm_abstractions::vm::Memory; pub use zkevm_opcode_defs::utils::*; +use zkevm_opcode_defs::{decoding::VmEncodingMode, ethereum_types::U256}; use lazy_static::lazy_static; @@ -46,8 +47,6 @@ pub fn u256_to_address_unchecked(integer: &U256) -> crate::Address { crate::Address::from_slice(&buffer[12..32]) } -use crate::abstractions::*; - #[derive(Debug, Clone, Copy)] pub struct GenericNoopTracer { _marker: std::marker::PhantomData, diff --git a/crates/zk_evm/src/vm_state/cycle.rs b/crates/zk_evm/src/vm_state/cycle.rs index ae122b4..2ab86c6 100644 --- a/crates/zk_evm/src/vm_state/cycle.rs +++ b/crates/zk_evm/src/vm_state/cycle.rs @@ -1,8 +1,11 @@ use super::*; -use crate::abstractions::*; -use crate::aux_structures::MemoryIndex; -use crate::aux_structures::{MemoryKey, MemoryLocation}; + use crate::opcodes::parsing::*; +use tracing::*; +use zk_evm_abstractions::{ + aux::*, + vm::{MemoryType, SpongeExecutionMarker}, +}; use zkevm_opcode_defs::{ImmMemHandlerFlags, NopOpcode, Operand, RegOrImmFlags}; pub struct PreState = EncodingModeProduction> { @@ -22,9 +25,9 @@ pub const READ_DST_FROM_MEMORY_SPONGE_IDX: usize = 2; pub fn read_and_decode< const N: usize, E: VmEncodingMode, - M: crate::abstractions::Memory, + M: zk_evm_abstractions::vm::Memory, WT: crate::witness_trace::VmWitnessTracer, - DT: crate::abstractions::tracing::Tracer, + DT: crate::tracing::Tracer, >( local_state: &VmLocalState, memory: &M, @@ -243,11 +246,11 @@ pub fn read_and_decode< impl< 'a, - S: crate::abstractions::Storage, - M: crate::abstractions::Memory, - EV: crate::abstractions::EventSink, - PP: crate::abstractions::PrecompilesProcessor, - DP: crate::abstractions::DecommittmentProcessor, + S: zk_evm_abstractions::vm::Storage, + M: zk_evm_abstractions::vm::Memory, + EV: zk_evm_abstractions::vm::EventSink, + PP: zk_evm_abstractions::vm::PrecompilesProcessor, + DP: zk_evm_abstractions::vm::DecommittmentProcessor, WT: crate::witness_trace::VmWitnessTracer, const N: usize, E: VmEncodingMode, @@ -261,10 +264,10 @@ impl< ) } - pub fn cycle>( + pub fn cycle>( &mut self, tracer: &mut DT, - ) { + ) -> anyhow::Result<()> { let (after_masking_decoded, delayed_changes, skip_cycle) = read_and_decode( &self.local_state, &mut self.memory, @@ -400,7 +403,7 @@ impl< is_kernel_mode, }; - after_masking_decoded.apply(self, prestate); + after_masking_decoded.apply(self, prestate)?; if self.local_state.pending_port.is_any_pending() { debug_assert!(self.local_state.pending_cycles_left.is_none()); @@ -425,5 +428,7 @@ impl< tracer.after_execution(local_state, data, &mut self.memory); } + + Ok(()) } } diff --git a/crates/zk_evm/src/vm_state/execution_stack.rs b/crates/zk_evm/src/vm_state/execution_stack.rs index 0ff55f4..cd46fa0 100644 --- a/crates/zk_evm/src/vm_state/execution_stack.rs +++ b/crates/zk_evm/src/vm_state/execution_stack.rs @@ -1,5 +1,4 @@ use super::*; -use crate::aux_structures::*; use zkevm_opcode_defs::{INITIAL_SP_ON_FAR_CALL, UNMAPPED_PAGE}; diff --git a/crates/zk_evm/src/vm_state/helpers.rs b/crates/zk_evm/src/vm_state/helpers.rs index 5c0c816..97f7832 100644 --- a/crates/zk_evm/src/vm_state/helpers.rs +++ b/crates/zk_evm/src/vm_state/helpers.rs @@ -1,26 +1,23 @@ +use crate::opcodes::DecodedOpcode; + use super::*; -use crate::abstractions::RefundType; -use crate::abstractions::SpongeExecutionMarker; -use crate::{ - aux_structures::{ - DecommittmentQuery, LogQuery, MemoryKey, MemoryLocation, MemoryQuery, Timestamp, - }, - opcodes::parsing::*, -}; +use zk_evm_abstractions::aux::{MemoryKey, MemoryLocation}; +use zk_evm_abstractions::queries::{DecommittmentQuery, LogQuery, MemoryQuery}; +use zk_evm_abstractions::vm::{RefundType, SpongeExecutionMarker}; use zkevm_opcode_defs::UNMAPPED_PAGE; pub fn read_code< const N: usize, E: VmEncodingMode, - M: crate::abstractions::Memory, + M: zk_evm_abstractions::vm::Memory, WT: crate::witness_trace::VmWitnessTracer, >( memory: &M, witness_tracer: &mut WT, monotonic_cycle_counter: u32, key: MemoryKey, - is_pended: bool, + _is_pended: bool, ) -> MemoryQuery { let MemoryKey { location, @@ -33,7 +30,6 @@ pub fn read_code< value: U256::zero(), value_is_pointer: false, rw_flag: false, - is_pended, }; let query = memory.read_code_query(monotonic_cycle_counter, partial_query); @@ -46,11 +42,11 @@ pub fn read_code< impl< 'a, - S: crate::abstractions::Storage, - M: crate::abstractions::Memory, - EV: crate::abstractions::EventSink, - PP: crate::abstractions::PrecompilesProcessor, - DP: crate::abstractions::DecommittmentProcessor, + S: zk_evm_abstractions::vm::Storage, + M: zk_evm_abstractions::vm::Memory, + EV: zk_evm_abstractions::vm::EventSink, + PP: zk_evm_abstractions::vm::PrecompilesProcessor, + DP: zk_evm_abstractions::vm::DecommittmentProcessor, WT: crate::witness_trace::VmWitnessTracer, const N: usize, E: VmEncodingMode, @@ -60,7 +56,7 @@ impl< &mut self, monotonic_cycle_counter: u32, key: MemoryKey, - is_pended: bool, + _is_pended: bool, ) -> MemoryQuery { let MemoryKey { location, @@ -73,7 +69,6 @@ impl< value: U256::zero(), value_is_pointer: false, rw_flag: false, - is_pended, }; let query = self @@ -107,7 +102,7 @@ impl< monotonic_cycle_counter: u32, key: MemoryKey, value: PrimitiveValue, - is_pended: bool, + _is_pended: bool, ) -> MemoryQuery { let MemoryKey { location, @@ -122,7 +117,6 @@ impl< value, value_is_pointer: is_pointer, rw_flag: true, - is_pended, }; let query = self @@ -187,7 +181,7 @@ impl< hash: U256, candidate_page: MemoryPage, timestamp: Timestamp, - ) -> DecommittmentQuery { + ) -> anyhow::Result { let partial_query = DecommittmentQuery { hash, timestamp, @@ -200,7 +194,7 @@ impl< monotonic_cycle_counter, partial_query, &mut self.memory, - ); + )?; if let Some(witness_for_tracer) = witness_for_tracer { self.witness_tracer.add_decommittment( @@ -210,7 +204,7 @@ impl< ); } - query + Ok(query) } pub fn call_precompile(&mut self, monotonic_cycle_counter: u32, query: LogQuery) { @@ -369,6 +363,7 @@ use zkevm_opcode_defs::bitflags::bitflags; use zkevm_opcode_defs::FatPointer; bitflags! { + #[derive(Default, Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct ErrorFlags: u64 { const INVALID_OPCODE = 1u64 << 0; const NOT_ENOUGH_ERGS = 1u64 << 1; diff --git a/crates/zk_evm/src/vm_state/mem_ops.rs b/crates/zk_evm/src/vm_state/mem_ops.rs index 093d2c5..2d5a104 100644 --- a/crates/zk_evm/src/vm_state/mem_ops.rs +++ b/crates/zk_evm/src/vm_state/mem_ops.rs @@ -1,6 +1,7 @@ use super::*; -use crate::abstractions::MemoryType; -use crate::aux_structures::{MemoryIndex, MemoryLocation}; +use zk_evm_abstractions::aux::{MemoryIndex, MemoryLocation}; +use zk_evm_abstractions::vm::MemoryType; + use zkevm_opcode_defs::{ImmMemHandlerFlags, RegOrImmFlags}; pub struct MemOpsProcessor = EncodingModeProduction> { @@ -12,11 +13,11 @@ use zkevm_opcode_defs::Operand; impl> MemOpsProcessor { pub fn compute_addresses_and_select_operands< 'a, - S: crate::abstractions::Storage, - M: crate::abstractions::Memory, - EV: crate::abstractions::EventSink, - PP: crate::abstractions::PrecompilesProcessor, - DP: crate::abstractions::DecommittmentProcessor, + S: zk_evm_abstractions::vm::Storage, + M: zk_evm_abstractions::vm::Memory, + EV: zk_evm_abstractions::vm::EventSink, + PP: zk_evm_abstractions::vm::PrecompilesProcessor, + DP: zk_evm_abstractions::vm::DecommittmentProcessor, WT: crate::witness_trace::VmWitnessTracer, >( &mut self, diff --git a/crates/zk_evm/src/vm_state/mod.rs b/crates/zk_evm/src/vm_state/mod.rs index e066acb..e174ae5 100644 --- a/crates/zk_evm/src/vm_state/mod.rs +++ b/crates/zk_evm/src/vm_state/mod.rs @@ -3,9 +3,9 @@ use zkevm_opcode_defs::decoding::VmEncodingMode; use zkevm_opcode_defs::ISAVersion; use super::*; -use crate::aux_structures::MemoryPage; -use crate::aux_structures::Timestamp; use crate::flags::Flags; +use zk_evm_abstractions::aux::MemoryPage; +use zk_evm_abstractions::aux::Timestamp; use zkevm_opcode_defs::decoding::AllowedPcOrImm; pub mod cycle; @@ -165,11 +165,11 @@ impl> DelayedLocalStateChanges { #[derive(Debug)] pub struct VmState< - S: crate::abstractions::Storage, - M: crate::abstractions::Memory, - EV: crate::abstractions::EventSink, - PP: crate::abstractions::PrecompilesProcessor, - DP: crate::abstractions::DecommittmentProcessor, + S: zk_evm_abstractions::vm::Storage, + M: zk_evm_abstractions::vm::Memory, + EV: zk_evm_abstractions::vm::EventSink, + PP: zk_evm_abstractions::vm::PrecompilesProcessor, + DP: zk_evm_abstractions::vm::DecommittmentProcessor, WT: crate::witness_trace::VmWitnessTracer, const N: usize = 8, E: VmEncodingMode = EncodingModeProduction, @@ -185,11 +185,11 @@ pub struct VmState< } impl< - S: crate::abstractions::Storage, - M: crate::abstractions::Memory, - EV: crate::abstractions::EventSink, - PP: crate::abstractions::PrecompilesProcessor, - DP: crate::abstractions::DecommittmentProcessor, + S: zk_evm_abstractions::vm::Storage, + M: zk_evm_abstractions::vm::Memory, + EV: zk_evm_abstractions::vm::EventSink, + PP: zk_evm_abstractions::vm::PrecompilesProcessor, + DP: zk_evm_abstractions::vm::DecommittmentProcessor, WT: crate::witness_trace::VmWitnessTracer, const N: usize, E: VmEncodingMode, diff --git a/crates/zk_evm/src/witness_trace/mod.rs b/crates/zk_evm/src/witness_trace/mod.rs index 11bb50d..c994dd2 100644 --- a/crates/zk_evm/src/witness_trace/mod.rs +++ b/crates/zk_evm/src/witness_trace/mod.rs @@ -1,8 +1,10 @@ +use zk_evm_abstractions::{ + queries::{DecommittmentQuery, LogQuery, MemoryQuery}, + vm::{PrecompileCyclesWitness, RefundType, SpongeExecutionMarker}, +}; use zkevm_opcode_defs::decoding::VmEncodingMode; -use super::aux_structures::*; use super::*; -use crate::abstractions::{PrecompileCyclesWitness, RefundType, SpongeExecutionMarker}; use crate::vm_state::{CallStackEntry, VmLocalState}; use std::ops::Range; diff --git a/crates/zk_evm_abstractions/.github/ISSUE_TEMPLATE/bug_report.md b/crates/zk_evm_abstractions/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..2d3e38a --- /dev/null +++ b/crates/zk_evm_abstractions/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,39 @@ +--- +name: Bug report +about: Use this template for reporting issues +title: '' +labels: bug +assignees: '' +--- + +### 🐛 Bug Report + +#### 📝 Description + +Provide a clear and concise description of the bug. + +#### 🔄 Reproduction Steps + +Steps to reproduce the behaviour + +#### 🤔 Expected Behavior + +Describe what you expected to happen. + +#### 😯 Current Behavior + +Describe what actually happened. + +#### 🖥️ Environment + +Any relevant environment details. + +#### 📋 Additional Context + +Add any other context about the problem here. If applicable, add screenshots to help explain. + +#### 📎 Log Output + +``` +Paste any relevant log output here. +``` diff --git a/crates/zk_evm_abstractions/.github/ISSUE_TEMPLATE/feature_request.md b/crates/zk_evm_abstractions/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..d921e06 --- /dev/null +++ b/crates/zk_evm_abstractions/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,21 @@ +--- +name: Feature request +about: Use this template for requesting features +title: '' +labels: feat +assignees: '' +--- + +### 🌟 Feature Request + +#### 📝 Description + +Provide a clear and concise description of the feature you'd like to see. + +#### 🤔 Rationale + +Explain why this feature is important and how it benefits the project. + +#### 📋 Additional Context + +Add any other context or information about the feature request here. diff --git a/crates/zk_evm_abstractions/.github/pull_request_template.md b/crates/zk_evm_abstractions/.github/pull_request_template.md new file mode 100644 index 0000000..8ce206c --- /dev/null +++ b/crates/zk_evm_abstractions/.github/pull_request_template.md @@ -0,0 +1,20 @@ +# What ❔ + + + + + +## Why ❔ + + + + +## Checklist + + + + +- [ ] PR title corresponds to the body of PR (we generate changelog entries from PRs). +- [ ] Tests for the changes have been added / updated. +- [ ] Documentation comments have been added / updated. +- [ ] Code has been formatted via `zk fmt` and `zk lint`. diff --git a/crates/zk_evm_abstractions/.github/workflows/cargo-license.yaml b/crates/zk_evm_abstractions/.github/workflows/cargo-license.yaml new file mode 100644 index 0000000..189b471 --- /dev/null +++ b/crates/zk_evm_abstractions/.github/workflows/cargo-license.yaml @@ -0,0 +1,8 @@ +name: Cargo license check +on: pull_request +jobs: + cargo-deny: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: EmbarkStudios/cargo-deny-action@v1 diff --git a/crates/zk_evm_abstractions/.github/workflows/ci.yaml b/crates/zk_evm_abstractions/.github/workflows/ci.yaml new file mode 100644 index 0000000..fd0bd3b --- /dev/null +++ b/crates/zk_evm_abstractions/.github/workflows/ci.yaml @@ -0,0 +1,23 @@ +name: "Rust CI" +on: + pull_request: + +jobs: + build: + name: cargo build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions-rust-lang/setup-rust-toolchain@v1 + - run: cargo build --verbose + + formatting: + name: cargo fmt + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + components: rustfmt + - name: Rustfmt Check + uses: actions-rust-lang/rustfmt@v1 diff --git a/crates/zk_evm_abstractions/.github/workflows/secrets_scanner.yaml b/crates/zk_evm_abstractions/.github/workflows/secrets_scanner.yaml new file mode 100644 index 0000000..54054cf --- /dev/null +++ b/crates/zk_evm_abstractions/.github/workflows/secrets_scanner.yaml @@ -0,0 +1,17 @@ +name: Leaked Secrets Scan +on: [pull_request] +jobs: + TruffleHog: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3 + with: + fetch-depth: 0 + - name: TruffleHog OSS + uses: trufflesecurity/trufflehog@0c66d30c1f4075cee1aada2e1ab46dabb1b0071a + with: + path: ./ + base: ${{ github.event.repository.default_branch }} + head: HEAD + extra_args: --debug --only-verified diff --git a/crates/zk_evm_abstractions/.gitignore b/crates/zk_evm_abstractions/.gitignore new file mode 100644 index 0000000..f2f9e58 --- /dev/null +++ b/crates/zk_evm_abstractions/.gitignore @@ -0,0 +1,2 @@ +target +Cargo.lock \ No newline at end of file diff --git a/crates/zk_evm_abstractions/CONTRIBUTING.md b/crates/zk_evm_abstractions/CONTRIBUTING.md new file mode 100644 index 0000000..dd3d458 --- /dev/null +++ b/crates/zk_evm_abstractions/CONTRIBUTING.md @@ -0,0 +1,44 @@ +# Contribution Guidelines + +Hello! Thanks for your interest in joining the mission to accelerate the mass adoption of crypto for personal +sovereignty! We welcome contributions from anyone on the internet, and are grateful for even the smallest of fixes! + +## Ways to contribute + +There are many ways to contribute to the ZK Stack: + +1. Open issues: if you find a bug, have something you believe needs to be fixed, or have an idea for a feature, please + open an issue. +2. Add color to existing issues: provide screenshots, code snippets, and whatever you think would be helpful to resolve + issues. +3. Resolve issues: either by showing an issue isn't a problem and the current state is ok as is or by fixing the problem + and opening a PR. +4. Report security issues, see [our security policy](./github/SECURITY.md). +5. [Join the team!](https://matterlabs.notion.site/Shape-the-future-of-Ethereum-at-Matter-Labs-dfb3b5a037044bb3a8006af2eb0575e0) + +## Fixing issues + +To contribute code fixing issues, please fork the repo, fix an issue, commit, add documentation as per the PR template, +and the repo's maintainers will review the PR. +[here](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork) +for guidance how to work with PRs created from a fork. + +## Licenses + +If you contribute to this project, your contributions will be made to the project under both Apache 2.0 and the MIT +license. + +## Resources + +We aim to make it as easy as possible to contribute to the mission. This is still WIP, and we're happy for contributions +and suggestions here too. Some resources to help: + +1. [In-repo docs aimed at developers](docs) +2. [zkSync Era docs!](https://era.zksync.io/docs/) +3. Company links can be found in the [repo's readme](README.md) + +## Code of Conduct + +Be polite and respectful. + +### Thank you diff --git a/crates/zk_evm_abstractions/Cargo.toml b/crates/zk_evm_abstractions/Cargo.toml new file mode 100644 index 0000000..faa67a0 --- /dev/null +++ b/crates/zk_evm_abstractions/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "zk_evm_abstractions" +version = "0.140.0" +edition = "2021" +authors = ["The Matter Labs Team "] +homepage = "https://zksync.io/" +repository = "https://github.com/matter-labs/era-zk_evm_abstractions" +license = "MIT OR Apache-2.0" +keywords = ["blockchain", "zksync"] +categories = ["cryptography"] +description = "ZKsync EraVM abstractions" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = "1.0" +serde = { version = "1", features = ["derive"] } +static_assertions = "1" +num_enum = "0.6" + +zkevm_opcode_defs = { version = "=0.132.0", path = "../zkevm_opcode_defs" } + +[dev-dependencies] +hex = "0.4" diff --git a/crates/zk_evm_abstractions/LICENSE-APACHE b/crates/zk_evm_abstractions/LICENSE-APACHE new file mode 100644 index 0000000..d9a10c0 --- /dev/null +++ b/crates/zk_evm_abstractions/LICENSE-APACHE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/crates/zk_evm_abstractions/LICENSE-MIT b/crates/zk_evm_abstractions/LICENSE-MIT new file mode 100644 index 0000000..2739ea6 --- /dev/null +++ b/crates/zk_evm_abstractions/LICENSE-MIT @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Matter Labs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/crates/zk_evm_abstractions/README.md b/crates/zk_evm_abstractions/README.md new file mode 100644 index 0000000..f92a928 --- /dev/null +++ b/crates/zk_evm_abstractions/README.md @@ -0,0 +1,33 @@ +# CPU/GPU Based Prover for zkSync Era + +[![Logo](eraLogo.png)](https://zksync.io/) + +zkSync Era is a layer 2 rollup that uses zero-knowledge proofs to scale Ethereum without compromising on security or +decentralization. Since it's EVM compatible (Solidity/Vyper), 99% of Ethereum projects can redeploy without refactoring +or re-auditing a single line of code. zkSync Era also uses an LLVM-based compiler that will eventually let developers +write smart contracts in C++, Rust and other popular languages. + +## License + +The zkSync Era prover is distributed under the terms of either + +- Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) +- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) + +at your option. + +## Official Links + +- [Website](https://zksync.io/) +- [GitHub](https://github.com/matter-labs) +- [Twitter](https://twitter.com/zksync) +- [Twitter for Devs](https://twitter.com/zkSyncDevs) +- [Discord](https://join.zksync.dev) + +## Disclaimer + +zkSync Era has been through lots of testing and audits. Although it is live, it is still in alpha state and will go +through more audits and bug bounties programs. We would love to hear our community's thoughts and suggestions about it! +It is important to state that forking it now can potentially lead to missing important security updates, critical +features, and performance improvements. + diff --git a/crates/zk_evm_abstractions/SECURITY.md b/crates/zk_evm_abstractions/SECURITY.md new file mode 100644 index 0000000..2f2871c --- /dev/null +++ b/crates/zk_evm_abstractions/SECURITY.md @@ -0,0 +1,74 @@ +# Security Policy + +We truly appreciate efforts to discover and disclose security issues responsibly! + +## Vulnerabilities + +If you'd like to report a security issue in the repositories of matter-labs organization, please proceed to our +[Bug Bounty Program on Immunefi](https://era.zksync.io/docs/reference/troubleshooting/audit-bug-bounty.html#bug-bounty-program). + +## Other Security Issues + +We take an impact-first approach instead of a rules-first approach. Therefore, if you believe you found the impactful +issue but can't report it via the Bug Bounty, please email us at +[security@matterlabs.dev](mailto:security@matterlabs.dev). + +### PGP Key + +The following PGP key may be used to communicate sensitive information to developers: + +Fingerprint: `5FED B2D0 EA2C 4906 DD66 71D7 A2C5 0B40 CE3C F297` + +``` +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +=xkM3 +-----END PGP PUBLIC KEY BLOCK----- +``` diff --git a/crates/zk_evm_abstractions/deny.toml b/crates/zk_evm_abstractions/deny.toml new file mode 100644 index 0000000..1ee7ccc --- /dev/null +++ b/crates/zk_evm_abstractions/deny.toml @@ -0,0 +1,78 @@ +all-features = false +no-default-features = false + +[advisories] +vulnerability = "deny" +unmaintained = "warn" +yanked = "warn" +notice = "warn" +ignore = [ + #"RUSTSEC-0000-0000", +] + +[licenses] +unlicensed = "deny" +allow = [ + #"Apache-2.0 WITH LLVM-exception", + "MIT", + "Apache-2.0", + "ISC", + "Unlicense", + "MPL-2.0", + "Unicode-DFS-2016", + "CC0-1.0", + "BSD-2-Clause", + "BSD-3-Clause", +] +deny = [ + #"Nokia", +] +copyleft = "warn" +allow-osi-fsf-free = "neither" +default = "deny" +confidence-threshold = 0.8 +exceptions = [ + # Each entry is the crate and version constraint, and its specific allow + # list + #{ allow = ["Zlib"], name = "adler32", version = "*" }, +] + +unused-allowed-license = "allow" + +[licenses.private] +ignore = false +registries = [ + #"https://sekretz.com/registry +] + +[bans] +multiple-versions = "warn" +wildcards = "allow" +highlight = "all" +workspace-default-features = "allow" +external-default-features = "allow" +allow = [ + #{ name = "ansi_term", version = "=0.11.0" }, +] +# List of crates to deny +deny = [ + # Each entry the name of a crate and a version range. If version is + # not specified, all versions will be matched. + #{ name = "ansi_term", version = "=0.11.0" }, +] + +skip = [ + #{ name = "ansi_term", version = "=0.11.0" }, +] +skip-tree = [ + #{ name = "ansi_term", version = "=0.11.0", depth = 20 }, +] + +[sources] +unknown-registry = "deny" +unknown-git = "allow" +allow-registry = ["https://github.com/rust-lang/crates.io-index"] +allow-git = [] + +[sources.allow-org] +#github = ["matter-labs"] diff --git a/crates/zk_evm_abstractions/eraLogo.png b/crates/zk_evm_abstractions/eraLogo.png new file mode 100644 index 0000000000000000000000000000000000000000..5d9480d8f05342a06cd1ee03405137552bdbebbf GIT binary patch literal 79091 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 -impl crate::abstractions::Precompile for ECRecoverPrecompile { +impl Precompile for ECRecoverPrecompile { type CycleWitness = ECRecoverRoundWitness; fn execute_precompile( @@ -25,7 +26,12 @@ impl crate::abstractions::Precompile for ECRecoverPrecompile { monotonic_cycle_counter: u32, query: LogQuery, memory: &mut M, - ) -> Option<(Vec, Vec, Vec)> { + ) -> ( + usize, + Option<(Vec, Vec, Vec)>, + ) { + const NUM_ROUNDS: usize = 1; + // read the parameters let precompile_call_params = query; let params = precompile_abi_in_log(precompile_call_params); @@ -70,7 +76,6 @@ impl crate::abstractions::Precompile for ECRecoverPrecompile { value: U256::zero(), value_is_pointer: false, rw_flag: false, - is_pended: false, }; let hash_query = memory.execute_partial_query(monotonic_cycle_counter, hash_query); let hash_value = hash_query.value; @@ -87,7 +92,6 @@ impl crate::abstractions::Precompile for ECRecoverPrecompile { value: U256::zero(), value_is_pointer: false, rw_flag: false, - is_pended: false, }; let v_query = memory.execute_partial_query(monotonic_cycle_counter, v_query); let v_value = v_query.value; @@ -104,7 +108,6 @@ impl crate::abstractions::Precompile for ECRecoverPrecompile { value: U256::zero(), value_is_pointer: false, rw_flag: false, - is_pended: false, }; let r_query = memory.execute_partial_query(monotonic_cycle_counter, r_query); let r_value = r_query.value; @@ -121,7 +124,6 @@ impl crate::abstractions::Precompile for ECRecoverPrecompile { value: U256::zero(), value_is_pointer: false, rw_flag: false, - is_pended: false, }; let s_query = memory.execute_partial_query(monotonic_cycle_counter, s_query); let s_value = s_query.value; @@ -180,7 +182,6 @@ impl crate::abstractions::Precompile for ECRecoverPrecompile { value: ok_marker, value_is_pointer: false, rw_flag: true, - is_pended: false, }; let ok_or_err_query = memory.execute_partial_query(monotonic_cycle_counter, ok_or_err_query); @@ -193,7 +194,6 @@ impl crate::abstractions::Precompile for ECRecoverPrecompile { value: result, value_is_pointer: false, rw_flag: true, - is_pended: false, }; let result_query = memory.execute_partial_query(monotonic_cycle_counter, result_query); @@ -217,7 +217,6 @@ impl crate::abstractions::Precompile for ECRecoverPrecompile { value: err_marker, value_is_pointer: false, rw_flag: true, - is_pended: false, }; let ok_or_err_query = memory.execute_partial_query(monotonic_cycle_counter, ok_or_err_query); @@ -230,7 +229,6 @@ impl crate::abstractions::Precompile for ECRecoverPrecompile { value: empty_result, value_is_pointer: false, rw_flag: true, - is_pended: false, }; let result_query = memory.execute_partial_query(monotonic_cycle_counter, result_query); @@ -242,11 +240,13 @@ impl crate::abstractions::Precompile for ECRecoverPrecompile { } } - if B { + let witness = if B { Some((read_history, write_history, vec![round_witness])) } else { None - } + }; + + (NUM_ROUNDS, witness) } } @@ -255,7 +255,7 @@ pub fn ecrecover_inner( serialized_signature: Vec, ) -> Result { if digest.iter().all(|el| *el == 0) { - // zero hash is not supported by our convension + // zero hash is not supported by our convension at the current version, will be activated later separately return Err(()); } // we expect pre-validation, so this check always works @@ -273,11 +273,14 @@ pub fn ecrecover_function( monotonic_cycle_counter: u32, precompile_call_params: LogQuery, memory: &mut M, -) -> Option<( - Vec, - Vec, - Vec, -)> { +) -> ( + usize, + Option<( + Vec, + Vec, + Vec, + )>, +) { let mut processor = ECRecoverPrecompile::; processor.execute_precompile(monotonic_cycle_counter, precompile_call_params, memory) } diff --git a/crates/zk_evm/src/precompiles/keccak256.rs b/crates/zk_evm_abstractions/src/precompiles/keccak256.rs similarity index 93% rename from crates/zk_evm/src/precompiles/keccak256.rs rename to crates/zk_evm_abstractions/src/precompiles/keccak256.rs index f598b7d..aeb4b10 100644 --- a/crates/zk_evm/src/precompiles/keccak256.rs +++ b/crates/zk_evm_abstractions/src/precompiles/keccak256.rs @@ -1,4 +1,12 @@ -use super::*; +use zkevm_opcode_defs::ethereum_types::U256; +pub use zkevm_opcode_defs::sha2::Digest; +pub use zkevm_opcode_defs::sha3::Keccak256; + +use crate::aux::*; +use crate::queries::*; +use crate::vm::*; + +use super::precompile_abi_in_log; pub const KECCAK_RATE_IN_U64_WORDS: usize = 17; pub const MEMORY_READS_PER_CYCLE: usize = 5; @@ -16,8 +24,6 @@ pub const BUFFER_SIZE: usize = NEW_WORDS_PER_CYCLE + KECCAK_RATE_IN_U64_WORDS - // static_assertions::const_assert!(BUFFER_SIZE - NEW_WORDS_PER_CYCLE >= KECCAK_RATE_IN_U64_WORDS); -pub use sha3::*; - #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct Keccak256RoundWitness { pub new_request: Option, @@ -28,7 +34,7 @@ pub struct Keccak256RoundWitness { #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct Keccak256Precompile; -impl crate::abstractions::Precompile for Keccak256Precompile { +impl Precompile for Keccak256Precompile { type CycleWitness = Keccak256RoundWitness; fn execute_precompile( @@ -36,7 +42,10 @@ impl crate::abstractions::Precompile for Keccak256Precompile { monotonic_cycle_counter: u32, query: LogQuery, memory: &mut M, - ) -> Option<(Vec, Vec, Vec)> { + ) -> ( + usize, + Option<(Vec, Vec, Vec)>, + ) { let precompile_call_params = query; // read the parameters let params = precompile_abi_in_log(precompile_call_params); @@ -98,7 +107,6 @@ impl crate::abstractions::Precompile for Keccak256Precompile { value: U256::zero(), value_is_pointer: false, rw_flag: false, - is_pended: false, }; let data_query = memory.execute_partial_query(monotonic_cycle_counter, data_query); @@ -158,7 +166,6 @@ impl crate::abstractions::Precompile for Keccak256Precompile { value: as_u256, value_is_pointer: false, rw_flag: true, - is_pended: false, }; let result_query = @@ -170,14 +177,18 @@ impl crate::abstractions::Precompile for Keccak256Precompile { } } - witness.push(round_witness); + if B { + witness.push(round_witness); + } } - if B { + let witness = if B { Some((read_queries, write_queries, witness)) } else { None - } + }; + + (num_rounds, witness) } } @@ -231,11 +242,14 @@ pub fn keccak256_rounds_function( monotonic_cycle_counter: u32, precompile_call_params: LogQuery, memory: &mut M, -) -> Option<( - Vec, - Vec, - Vec, -)> { +) -> ( + usize, + Option<( + Vec, + Vec, + Vec, + )>, +) { let mut processor = Keccak256Precompile::; processor.execute_precompile(monotonic_cycle_counter, precompile_call_params, memory) } @@ -269,6 +283,7 @@ pub fn transmute_state(reference_state: Keccak256) -> Keccak256InnerState { #[cfg(test)] mod tests { use super::*; + use zkevm_opcode_defs::sha2::Digest; #[test] fn test_empty_string() { diff --git a/crates/zk_evm/src/precompiles/mod.rs b/crates/zk_evm_abstractions/src/precompiles/mod.rs similarity index 80% rename from crates/zk_evm/src/precompiles/mod.rs rename to crates/zk_evm_abstractions/src/precompiles/mod.rs index 3a06faa..7167f09 100644 --- a/crates/zk_evm/src/precompiles/mod.rs +++ b/crates/zk_evm_abstractions/src/precompiles/mod.rs @@ -1,16 +1,26 @@ -use super::*; -use crate::abstractions::*; -use crate::aux_structures::*; +use crate::aux::*; +use crate::queries::*; +use crate::vm::*; pub mod ecrecover; pub mod keccak256; pub mod sha256; +use num_enum::TryFromPrimitive; +use std::convert::TryFrom; use zkevm_opcode_defs::system_params::{ ECRECOVER_INNER_FUNCTION_PRECOMPILE_ADDRESS, KECCAK256_ROUND_FUNCTION_PRECOMPILE_ADDRESS, SHA256_ROUND_FUNCTION_PRECOMPILE_ADDRESS, }; +#[repr(u16)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive)] +pub enum PrecompileAddress { + Ecrecover = ECRECOVER_INNER_FUNCTION_PRECOMPILE_ADDRESS, + SHA256 = SHA256_ROUND_FUNCTION_PRECOMPILE_ADDRESS, + Keccak256 = KECCAK256_ROUND_FUNCTION_PRECOMPILE_ADDRESS, +} + #[derive(Clone, Copy, Debug)] pub struct PrecompileCallParams { pub input_location: MemoryLocation, @@ -28,7 +38,7 @@ pub const fn precompile_abi_in_log(query: LogQuery) -> PrecompileCallInnerABI { #[derive(Clone, Copy, Debug)] pub struct DefaultPrecompilesProcessor; -impl crate::abstractions::PrecompilesProcessor for DefaultPrecompilesProcessor { +impl PrecompilesProcessor for DefaultPrecompilesProcessor { fn start_frame(&mut self) { // there are no precompiles to rollback, do nothing } @@ -39,8 +49,14 @@ impl crate::abstractions::PrecompilesProcessor for DefaultPrecomp memory: &mut M, ) -> Option<(Vec, Vec, PrecompileCyclesWitness)> { let address_low = u16::from_le_bytes([query.address.0[19], query.address.0[18]]); - match address_low { - KECCAK256_ROUND_FUNCTION_PRECOMPILE_ADDRESS => { + let Ok(precompile_address) = PrecompileAddress::try_from(address_low) else { + // it's formally allowed for purposes of ergs-burning + // by special contracts + return None; + }; + + match precompile_address { + PrecompileAddress::Keccak256 => { // pure function call, non-revertable if B { let (reads, writes, round_witness) = @@ -49,6 +65,7 @@ impl crate::abstractions::PrecompilesProcessor for DefaultPrecomp query, memory, ) + .1 .expect("must generate intermediate witness"); Some(( @@ -66,7 +83,7 @@ impl crate::abstractions::PrecompilesProcessor for DefaultPrecomp None } } - SHA256_ROUND_FUNCTION_PRECOMPILE_ADDRESS => { + PrecompileAddress::SHA256 => { // pure function call, non-revertable if B { let (reads, writes, round_witness) = sha256::sha256_rounds_function::( @@ -74,6 +91,7 @@ impl crate::abstractions::PrecompilesProcessor for DefaultPrecomp query, memory, ) + .1 .expect("must generate intermediate witness"); Some(( @@ -91,7 +109,7 @@ impl crate::abstractions::PrecompilesProcessor for DefaultPrecomp None } } - ECRECOVER_INNER_FUNCTION_PRECOMPILE_ADDRESS => { + PrecompileAddress::Ecrecover => { // pure function call, non-revertable if B { let (reads, writes, round_witness) = ecrecover::ecrecover_function::( @@ -99,6 +117,7 @@ impl crate::abstractions::PrecompilesProcessor for DefaultPrecomp query, memory, ) + .1 .expect("must generate intermediate witness"); Some(( @@ -116,17 +135,6 @@ impl crate::abstractions::PrecompilesProcessor for DefaultPrecomp None } } - _ => { - // it's formally allowed for purposes of ergs-burning - // by special contracts - - None - } // _ => { - // unreachable!( - // "Tried to call a precompile from address {:?}", - // query.address - // ); - // } } } diff --git a/crates/zk_evm/src/precompiles/sha256.rs b/crates/zk_evm_abstractions/src/precompiles/sha256.rs similarity index 91% rename from crates/zk_evm/src/precompiles/sha256.rs rename to crates/zk_evm_abstractions/src/precompiles/sha256.rs index 913b8e8..8ed991d 100644 --- a/crates/zk_evm/src/precompiles/sha256.rs +++ b/crates/zk_evm_abstractions/src/precompiles/sha256.rs @@ -1,3 +1,12 @@ +use zkevm_opcode_defs::ethereum_types::U256; +pub use zkevm_opcode_defs::sha2::Digest; +pub use zkevm_opcode_defs::sha2::Sha256; + +use crate::{ + queries::MemoryQuery, + vm::{Memory, MemoryType, Precompile}, +}; + use super::*; // for sha256 we do not need complicated buffering as it uses 64 bytes per round, and this is divisible @@ -6,8 +15,6 @@ use super::*; pub const MEMORY_READS_PER_CYCLE: usize = 2; pub const MEMORY_WRITES_PER_CYCLE: usize = 1; -pub use sha2::*; - #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct Sha256RoundWitness { pub new_request: Option, @@ -18,7 +25,7 @@ pub struct Sha256RoundWitness { #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct Sha256Precompile; -impl crate::abstractions::Precompile for Sha256Precompile { +impl Precompile for Sha256Precompile { type CycleWitness = Sha256RoundWitness; fn execute_precompile( @@ -26,7 +33,10 @@ impl crate::abstractions::Precompile for Sha256Precompile { monotonic_cycle_counter: u32, query: LogQuery, memory: &mut M, - ) -> Option<(Vec, Vec, Vec)> { + ) -> ( + usize, + Option<(Vec, Vec, Vec)>, + ) { let precompile_call_params = query; let params = precompile_abi_in_log(precompile_call_params); let timestamp_to_read = precompile_call_params.timestamp; @@ -72,7 +82,6 @@ impl crate::abstractions::Precompile for Sha256Precompile { value: U256::zero(), value_is_pointer: false, rw_flag: false, - is_pended: false, }; let query = memory.execute_partial_query(monotonic_cycle_counter, query); @@ -125,7 +134,6 @@ impl crate::abstractions::Precompile for Sha256Precompile { value: as_u256, value_is_pointer: false, rw_flag: true, - is_pended: false, }; let result_query = memory.execute_partial_query(monotonic_cycle_counter, result_query); @@ -141,11 +149,13 @@ impl crate::abstractions::Precompile for Sha256Precompile { } } - if B { + let witness = if B { Some((read_queries, write_queries, witness)) } else { None - } + }; + + (num_rounds, witness) } } @@ -153,7 +163,10 @@ pub fn sha256_rounds_function( monotonic_cycle_counter: u32, precompile_call_params: LogQuery, memory: &mut M, -) -> Option<(Vec, Vec, Vec)> { +) -> ( + usize, + Option<(Vec, Vec, Vec)>, +) { let mut processor = Sha256Precompile::; processor.execute_precompile(monotonic_cycle_counter, precompile_call_params, memory) } diff --git a/crates/zk_evm/src/aux_structures/queries.rs b/crates/zk_evm_abstractions/src/queries.rs similarity index 93% rename from crates/zk_evm/src/aux_structures/queries.rs rename to crates/zk_evm_abstractions/src/queries.rs index cd15bbb..0f03810 100644 --- a/crates/zk_evm/src/aux_structures/queries.rs +++ b/crates/zk_evm_abstractions/src/queries.rs @@ -1,13 +1,17 @@ -use super::*; +use zkevm_opcode_defs::{ + blake2, + ethereum_types::{Address, U256}, +}; + +use crate::aux::{MemoryLocation, MemoryPage, Timestamp}; #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] pub struct MemoryQuery { pub timestamp: Timestamp, pub location: MemoryLocation, + pub value: U256, pub rw_flag: bool, - pub is_pended: bool, pub value_is_pointer: bool, - pub value: U256, } impl MemoryQuery { @@ -16,7 +20,6 @@ impl MemoryQuery { timestamp: Timestamp::empty(), location: MemoryLocation::empty(), rw_flag: false, - is_pended: false, value_is_pointer: false, value: U256::zero(), } diff --git a/crates/zk_evm/src/abstractions/mod.rs b/crates/zk_evm_abstractions/src/vm.rs similarity index 85% rename from crates/zk_evm/src/abstractions/mod.rs rename to crates/zk_evm_abstractions/src/vm.rs index f1379df..7fd7ab1 100644 --- a/crates/zk_evm/src/abstractions/mod.rs +++ b/crates/zk_evm_abstractions/src/vm.rs @@ -1,17 +1,16 @@ -use zkevm_opcode_defs::FatPointer; +use zkevm_opcode_defs::{ethereum_types::U256, FatPointer}; -use super::*; -use crate::aux_structures::*; -pub mod tracing; -pub use self::tracing::*; +use crate::{ + aux::{MemoryPage, Timestamp}, + precompiles::{ + ecrecover::ECRecoverPrecompile, keccak256::Keccak256Precompile, sha256::Sha256Precompile, + }, + queries::{DecommittmentQuery, LogQuery, MemoryQuery}, +}; pub const MEMORY_CELLS_STACK_OR_CODE_PAGE: usize = 1 << 16; -pub const MAX_MEMORY_BYTES: usize = 1 << 24; -pub const MEMORY_CELLS_OTHER_PAGES: usize = MAX_MEMORY_BYTES / 32; - pub const MAX_STACK_PAGE_SIZE_IN_WORDS: usize = 1 << 16; pub const MAX_CODE_PAGE_SIZE_IN_WORDS: usize = 1 << 16; -pub const MAX_HEAP_PAGE_SIZE_IN_WORDS: usize = MAX_MEMORY_BYTES / 32; #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] pub enum MemoryType { @@ -26,9 +25,7 @@ impl MemoryType { pub const fn page_size_limit(&self) -> usize { match self { MemoryType::Stack | MemoryType::Code => MEMORY_CELLS_STACK_OR_CODE_PAGE, - MemoryType::Heap | MemoryType::AuxHeap | MemoryType::FatPointer => { - MEMORY_CELLS_OTHER_PAGES - } + MemoryType::Heap | MemoryType::AuxHeap | MemoryType::FatPointer => u32::MAX as usize, } } } @@ -58,10 +55,6 @@ impl RefundType { } } -use crate::precompiles::ecrecover::ECRecoverPrecompile; -use crate::precompiles::keccak256::Keccak256Precompile; -use crate::precompiles::sha256::Sha256Precompile; - // for strong typing we have to enumerate all of the supported precompiles here pub enum PrecompileCyclesWitness { Sha256(Vec< as Precompile>::CycleWitness>), @@ -133,6 +126,28 @@ pub trait Memory: std::fmt::Debug { } } +impl Memory for () { + fn execute_partial_query( + &mut self, + _monotonic_cycle_counter: u32, + _query: MemoryQuery, + ) -> MemoryQuery { + unreachable!() + } + + fn specialized_code_query( + &mut self, + _monotonic_cycle_counter: u32, + _query: MemoryQuery, + ) -> MemoryQuery { + unreachable!() + } + + fn read_code_query(&self, _monotonic_cycle_counter: u32, _query: MemoryQuery) -> MemoryQuery { + unreachable!() + } +} + pub trait EventSink: std::fmt::Debug { // Largely the same as storage with exception that events are always "write"-like, // so we do not need to return anything @@ -167,7 +182,7 @@ pub trait DecommittmentProcessor: std::fmt::Debug { monotonic_cycle_counter: u32, partial_query: DecommittmentQuery, memory: &mut M, - ) -> (DecommittmentQuery, Option>); + ) -> anyhow::Result<(DecommittmentQuery, Option>)>; } /// Abstraction over precompile implementation. Precompile is usually a closure-forming FSM, so it must output @@ -175,7 +190,8 @@ pub trait DecommittmentProcessor: std::fmt::Debug { pub trait Precompile: std::fmt::Debug { type CycleWitness: Clone + std::fmt::Debug; - /// execute a precompile by using request and access to memory. May be output + /// Execute a precompile by using request and access to memory. Output number of cycles needed. + /// May be output /// - all memory reads (may be removed later on) /// - all memory writes (depending on the implementation we may directly write to `memory` and also remove it) /// - FSM cycle witness parameters @@ -184,7 +200,10 @@ pub trait Precompile: std::fmt::Debug { monotonic_cycle_counter: u32, query: LogQuery, memory: &mut M, - ) -> Option<(Vec, Vec, Vec)>; + ) -> ( + usize, + Option<(Vec, Vec, Vec)>, + ); } pub enum SpongeExecutionMarker { diff --git a/crates/zkevm_opcode_defs/CONTRIBUTING.md b/crates/zkevm_opcode_defs/CONTRIBUTING.md index dd3d458..f129e60 100644 --- a/crates/zkevm_opcode_defs/CONTRIBUTING.md +++ b/crates/zkevm_opcode_defs/CONTRIBUTING.md @@ -1,44 +1,9 @@ # Contribution Guidelines -Hello! Thanks for your interest in joining the mission to accelerate the mass adoption of crypto for personal -sovereignty! We welcome contributions from anyone on the internet, and are grateful for even the smallest of fixes! +Thank you for considering helping out with the source code! We are extremely grateful for any consideration of +contributions to this repository. However, at this time, we generally do not accept external contributions. This policy +will change in the future, so please check back regularly for updates. -## Ways to contribute +For security issues, please contact us at [security@matterlabs.dev](mailto:security@matterlabs.dev). -There are many ways to contribute to the ZK Stack: - -1. Open issues: if you find a bug, have something you believe needs to be fixed, or have an idea for a feature, please - open an issue. -2. Add color to existing issues: provide screenshots, code snippets, and whatever you think would be helpful to resolve - issues. -3. Resolve issues: either by showing an issue isn't a problem and the current state is ok as is or by fixing the problem - and opening a PR. -4. Report security issues, see [our security policy](./github/SECURITY.md). -5. [Join the team!](https://matterlabs.notion.site/Shape-the-future-of-Ethereum-at-Matter-Labs-dfb3b5a037044bb3a8006af2eb0575e0) - -## Fixing issues - -To contribute code fixing issues, please fork the repo, fix an issue, commit, add documentation as per the PR template, -and the repo's maintainers will review the PR. -[here](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork) -for guidance how to work with PRs created from a fork. - -## Licenses - -If you contribute to this project, your contributions will be made to the project under both Apache 2.0 and the MIT -license. - -## Resources - -We aim to make it as easy as possible to contribute to the mission. This is still WIP, and we're happy for contributions -and suggestions here too. Some resources to help: - -1. [In-repo docs aimed at developers](docs) -2. [zkSync Era docs!](https://era.zksync.io/docs/) -3. Company links can be found in the [repo's readme](README.md) - -## Code of Conduct - -Be polite and respectful. - -### Thank you +Thank you for your support in accelerating the mass adoption of crypto for personal sovereignty! diff --git a/crates/zkevm_opcode_defs/Cargo.toml b/crates/zkevm_opcode_defs/Cargo.toml index 59253fd..10e0c12 100644 --- a/crates/zkevm_opcode_defs/Cargo.toml +++ b/crates/zkevm_opcode_defs/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zkevm_opcode_defs" -version = "0.131.0" +version = "0.132.0" edition = "2021" authors = ["The Matter Labs Team "] homepage = "https://zksync.io/" @@ -19,7 +19,10 @@ name = "circuit_pricing_generator" path = "src/circuit_pricing_generator/main.rs" [dependencies] -bitflags = "1.3" +bitflags = "2" lazy_static = "1.4" ethereum-types = "=0.14.1" -sha2 = "0.10" +sha2 = { package = "sha2_ce", version = "=0.10.6" } +sha3 = { package = "sha3_ce", version = "=0.10.6" } +blake2 = { package = "blake2", version = "=0.10.6" } +k256 = { version = "0.11.6", features = ["arithmetic", "ecdsa"] } diff --git a/crates/zkevm_opcode_defs/deny.toml b/crates/zkevm_opcode_defs/deny.toml index a957d98..77d7d23 100644 --- a/crates/zkevm_opcode_defs/deny.toml +++ b/crates/zkevm_opcode_defs/deny.toml @@ -72,7 +72,9 @@ skip-tree = [ unknown-registry = "deny" unknown-git = "deny" allow-registry = ["https://github.com/rust-lang/crates.io-index"] -allow-git = [] +allow-git = [ + "https://github.com/RustCrypto/hashes.git", +] [sources.allow-org] #github = ["matter-labs"] diff --git a/crates/zkevm_opcode_defs/src/circuit_prices.rs b/crates/zkevm_opcode_defs/src/circuit_prices.rs index caf64f0..03330ff 100644 --- a/crates/zkevm_opcode_defs/src/circuit_prices.rs +++ b/crates/zkevm_opcode_defs/src/circuit_prices.rs @@ -11,15 +11,15 @@ pub const STORAGE_SORTER_COST_IN_ERGS: u32 = 2; pub const EVENTS_OR_L1_MESSAGES_SORTER_COST_IN_ERGS: u32 = 1; pub const INITIAL_WRITES_PUBDATA_HASHER_COST_IN_ERGS: u32 = 18; pub const REPEATED_WRITES_PUBDATA_HASHER_COST_IN_ERGS: u32 = 11; +pub const CODE_DECOMMITMENT_SORTER_COST_IN_ERGS: u32 = 1; // The following circuits are single-instance and so the provided prices are just minimal prices to preserve DDoS safety pub const L1_MESSAGE_MIN_COST_IN_ERGS: u32 = 156250; -pub const CODE_DECOMMITMENT_SORTER_MIN_COST_IN_ERGS: u32 = 416; pub const INITIAL_WRITES_PUBDATA_HASHER_MIN_COST_IN_ERGS: u32 = 0; pub const REPEATED_WRITES_PUBDATA_HASHER_MIN_COST_IN_ERGS: u32 = 0; // Equals to max(INITIAL_WRITES_PUBDATA_HASHER_MIN_COST_IN_ERGS, REPEATED_WRITES_PUBDATA_HASHER_MIN_COST_IN_ERGS) -pub const STORAGE_WRITE_MIN_COST_IN_ERGS: u32 = 0; +pub const STORAGE_WRITE_HASHER_MIN_COST_IN_ERGS: u32 = 0; // The following constants should not be used in the VM directly, but only in Solidity wrappers pub const KECCAK256_CIRCUIT_COST_IN_ERGS: u32 = 40; diff --git a/crates/zkevm_opcode_defs/src/circuit_pricing_generator/main.rs b/crates/zkevm_opcode_defs/src/circuit_pricing_generator/main.rs index 50d900c..ac42e12 100644 --- a/crates/zkevm_opcode_defs/src/circuit_pricing_generator/main.rs +++ b/crates/zkevm_opcode_defs/src/circuit_pricing_generator/main.rs @@ -17,15 +17,13 @@ pub const CYCLES_PER_STORAGE_APPLICATION: u32 = 118; pub const CYCLES_PER_KECCAK256_CIRCUIT: u32 = 2050; pub const CYCLES_PER_SHA256_CIRCUIT: u32 = 11500; pub const CYCLES_PER_ECRECOVER_CIRCUIT: u32 = 72; - -/// These circuits while not currently multi-instance, will become ones -pub const LIMIT_FOR_LOG_DEMUXER: u32 = 101500; -pub const LIMIT_FOR_STORAGE_SORTER: u32 = 79000; -pub const LIMIT_FOR_EVENTS_OR_L1_MESSAGES_SORTER: u32 = 88000; +pub const CYCLES_FOR_CODE_DECOMMITTER_SORTER: u32 = 192500; +pub const CYCLES_FOR_LOG_DEMUXER: u32 = 101500; +pub const CYCLES_FOR_STORAGE_SORTER: u32 = 79000; +pub const CYCLES_FOR_EVENTS_OR_L1_MESSAGES_SORTER: u32 = 88000; /// This kinds of circuit will always remain single-instance pub const LIMIT_FOR_L1_MESSAGES_MERKLIZER: u32 = 512; -pub const LIMIT_FOR_CODE_DECOMMITTER_SORTER: u32 = 192500; pub const LIMIT_FOR_INITIAL_WRITES_PUBDATA_HASHER: u32 = 4600; pub const LIMIT_FOR_REPEATED_WRITES_PUBDATA_HASHER: u32 = 7400; @@ -98,19 +96,19 @@ fn main() { ), ergs_constant( "CODE_DECOMMITTER_SORTER_COST_IN_ERGS", - ceil_div(ERGS_PER_CIRCUIT, LIMIT_FOR_CODE_DECOMMITTER_SORTER), + ceil_div(ERGS_PER_CIRCUIT, CYCLES_FOR_CODE_DECOMMITTER_SORTER), ), ergs_constant( "LOG_DEMUXER_COST_IN_ERGS", - ceil_div(ERGS_PER_CIRCUIT, LIMIT_FOR_LOG_DEMUXER), + ceil_div(ERGS_PER_CIRCUIT, CYCLES_FOR_LOG_DEMUXER), ), ergs_constant( "STORAGE_SORTER_COST_IN_ERGS", - ceil_div(ERGS_PER_CIRCUIT, LIMIT_FOR_STORAGE_SORTER), + ceil_div(ERGS_PER_CIRCUIT, CYCLES_FOR_STORAGE_SORTER), ), ergs_constant( "EVENTS_OR_L1_MESSAGES_SORTER_COST_IN_ERGS", - ceil_div(ERGS_PER_CIRCUIT, LIMIT_FOR_EVENTS_OR_L1_MESSAGES_SORTER), + ceil_div(ERGS_PER_CIRCUIT, CYCLES_FOR_EVENTS_OR_L1_MESSAGES_SORTER), ), ergs_constant( "INITIAL_WRITES_PUBDATA_HASHER_COST_IN_ERGS", @@ -120,15 +118,15 @@ fn main() { "REPEATED_WRITES_PUBDATA_HASHER_COST_IN_ERGS", ceil_div(ERGS_PER_CIRCUIT, LIMIT_FOR_REPEATED_WRITES_PUBDATA_HASHER), ), + ergs_constant( + "CODE_DECOMMITMENT_SORTER_COST_IN_ERGS", + ceil_div(ERGS_PER_CIRCUIT, CYCLES_FOR_CODE_DECOMMITTER_SORTER) + ), comment("The following circuits are single-instance and so the provided prices are just minimal prices to preserve DDoS safety"), ergs_constant( "L1_MESSAGE_MIN_COST_IN_ERGS", ceil_div(MAX_TX_ERGS_LIMIT, LIMIT_FOR_L1_MESSAGES_MERKLIZER), ), - ergs_constant( - "CODE_DECOMMITMENT_SORTER_MIN_COST_IN_ERGS", - ceil_div(MAX_TX_ERGS_LIMIT, LIMIT_FOR_CODE_DECOMMITTER_SORTER) - ), ergs_constant( "INITIAL_WRITES_PUBDATA_HASHER_MIN_COST_IN_ERGS", min_price_for_initial_pubdata_write @@ -139,7 +137,7 @@ fn main() { ), comment("Equals to max(INITIAL_WRITES_PUBDATA_HASHER_MIN_COST_IN_ERGS, REPEATED_WRITES_PUBDATA_HASHER_MIN_COST_IN_ERGS)"), ergs_constant( - "STORAGE_WRITE_MIN_COST_IN_ERGS", + "STORAGE_WRITE_HASHER_MIN_COST_IN_ERGS", std::cmp::max(min_price_for_initial_pubdata_write, min_price_for_repeated_pubdata_write) ), comment("The following constants should not be used in the VM directly, but only in Solidity wrappers"), diff --git a/crates/zkevm_opcode_defs/src/definitions/abi/fat_pointer.rs b/crates/zkevm_opcode_defs/src/definitions/abi/fat_pointer.rs index fb3b590..2a9409e 100644 --- a/crates/zkevm_opcode_defs/src/definitions/abi/fat_pointer.rs +++ b/crates/zkevm_opcode_defs/src/definitions/abi/fat_pointer.rs @@ -73,6 +73,13 @@ impl FatPointer { in_bounds } + /// We allow to pass empty (offset == length) slices in Far call / Ret + pub const fn validate_as_slice(&self) -> bool { + let is_valid_slice = self.offset <= self.length; + + is_valid_slice + } + /// special case when we supply empty slice, that is formally NOT addressable pub const fn is_trivial(&self) -> bool { self.length == 0 && self.offset == 0 diff --git a/crates/zkevm_opcode_defs/src/definitions/far_call.rs b/crates/zkevm_opcode_defs/src/definitions/far_call.rs index 91c8bf2..7afe829 100644 --- a/crates/zkevm_opcode_defs/src/definitions/far_call.rs +++ b/crates/zkevm_opcode_defs/src/definitions/far_call.rs @@ -1,5 +1,5 @@ use crate::circuit_prices::{ - CODE_DECOMMITMENT_SORTER_MIN_COST_IN_ERGS, RAM_PERMUTATION_COST_IN_ERGS, + CODE_DECOMMITMENT_SORTER_COST_IN_ERGS, RAM_PERMUTATION_COST_IN_ERGS, STORAGE_SORTER_COST_IN_ERGS, VM_CYCLE_COST_IN_ERGS, }; @@ -54,13 +54,12 @@ impl OpcodeVariantProps for FarCallOpcode { } fn ergs_price(&self) -> u32 { - let intrinsic = 2 * VM_CYCLE_COST_IN_ERGS + 2 * VM_CYCLE_COST_IN_ERGS + RAM_PERMUTATION_COST_IN_ERGS + STORAGE_READ_IO_PRICE + CALL_LIKE_ERGS_COST - + STORAGE_SORTER_COST_IN_ERGS; - - std::cmp::max(intrinsic, CODE_DECOMMITMENT_SORTER_MIN_COST_IN_ERGS) + + STORAGE_SORTER_COST_IN_ERGS + + CODE_DECOMMITMENT_SORTER_COST_IN_ERGS } } diff --git a/crates/zkevm_opcode_defs/src/definitions/log.rs b/crates/zkevm_opcode_defs/src/definitions/log.rs index 4268b1b..f6fead7 100644 --- a/crates/zkevm_opcode_defs/src/definitions/log.rs +++ b/crates/zkevm_opcode_defs/src/definitions/log.rs @@ -1,7 +1,10 @@ -use crate::circuit_prices::{ - EVENTS_OR_L1_MESSAGES_SORTER_COST_IN_ERGS, L1_MESSAGE_MIN_COST_IN_ERGS, - LOG_DEMUXER_COST_IN_ERGS, RAM_PERMUTATION_COST_IN_ERGS, STORAGE_SORTER_COST_IN_ERGS, - STORAGE_WRITE_MIN_COST_IN_ERGS, VM_CYCLE_COST_IN_ERGS, +use crate::{ + circuit_prices::{ + EVENTS_OR_L1_MESSAGES_SORTER_COST_IN_ERGS, L1_MESSAGE_MIN_COST_IN_ERGS, + LOG_DEMUXER_COST_IN_ERGS, RAM_PERMUTATION_COST_IN_ERGS, STORAGE_SORTER_COST_IN_ERGS, + VM_CYCLE_COST_IN_ERGS, + }, + system_params::MIN_STORAGE_WRITE_COST, }; use super::*; @@ -69,7 +72,7 @@ impl OpcodeVariantProps for LogOpcode { + 2 * LOG_DEMUXER_COST_IN_ERGS + 2 * STORAGE_SORTER_COST_IN_ERGS; - std::cmp::max(intrinsic, STORAGE_WRITE_MIN_COST_IN_ERGS) + std::cmp::max(intrinsic, MIN_STORAGE_WRITE_COST) } // Note, that the `L1_MESSAGE_MIN_COST_IN_ERGS` is only needed for DDoS protection LogOpcode::ToL1Message => { diff --git a/crates/zkevm_opcode_defs/src/lib.rs b/crates/zkevm_opcode_defs/src/lib.rs index 60204ee..b09ce8a 100644 --- a/crates/zkevm_opcode_defs/src/lib.rs +++ b/crates/zkevm_opcode_defs/src/lib.rs @@ -11,12 +11,17 @@ pub mod circuit_prices; use std::collections::HashMap; -pub use bitflags; use circuit_prices::CODE_DECOMMITMENT_COST_PER_WORD_IN_ERGS; use circuit_prices::CODE_DECOMMITTER_SORTER_COST_IN_ERGS; use circuit_prices::RAM_PERMUTATION_COST_IN_ERGS; use circuit_prices::VM_CYCLE_COST_IN_ERGS; + +pub use bitflags; +pub use blake2; pub use ethereum_types; +pub use k256; +pub use sha2; +pub use sha3; pub use self::definitions::*; pub use self::imm_mem_modifiers::*; diff --git a/crates/zkevm_opcode_defs/src/system_params.rs b/crates/zkevm_opcode_defs/src/system_params.rs index d52b987..00dd00e 100644 --- a/crates/zkevm_opcode_defs/src/system_params.rs +++ b/crates/zkevm_opcode_defs/src/system_params.rs @@ -1,4 +1,4 @@ -use crate::CALL_LIKE_ERGS_COST; +use crate::{circuit_prices::STORAGE_WRITE_HASHER_MIN_COST_IN_ERGS, CALL_LIKE_ERGS_COST}; use ethereum_types::Address; pub const MAX_TX_ERGS_LIMIT: u32 = 80_000_000; @@ -67,6 +67,44 @@ pub const ADDRESS_BOOTLOADER_UTILITIES: u16 = 0x800C; pub const ADDRESS_EVENT_WRITER: u16 = 0x800D; pub const ADDRESS_KECCAK256: u16 = 0x8010; +pub const BOOTLOADER_MAX_MEMORY: u32 = u32::MAX; +pub const NEW_FRAME_MEMORY_STIPEND: u32 = 1u32 << 10; // 1 KB for new frames is "free" + +pub const MSG_VALUE_SIMULATOR_PUBDATA_BYTES_TO_PREPAY: u32 = 32 + 32 + 32 + 32; + +/// 128k * 4 / 32 -- the maximal realistic smart contract size. NOTE this constant should be updated once a new +/// packing method is introduced or more than 128k of data is allowed to be sent on L1. +pub const DECOMMITMENT_MSG_VALUE_SIMULATOR_OVERHEAD: u32 = 64000; +pub const MSG_VALUE_SIMULATOR_ADDITIVE_COST: u32 = + 11500 + DECOMMITMENT_MSG_VALUE_SIMULATOR_OVERHEAD; + +/// The minimum amount of ergs that should be spent by the user while using the MsgValueSimulator (even if +/// the user spends less funds, only the parent frame will receivet the refund) +pub const MSG_VALUE_SIMULATOR_MIN_USED_ERGS: u32 = 8000 + DECOMMITMENT_MSG_VALUE_SIMULATOR_OVERHEAD; + +// std::cmp::max is not yet stabilized as const fn yet +const fn max(a: u32, b: u32) -> u32 { + if a > b { + a + } else { + b + } +} + +/// The minimum price in ergs that a storage write should cost in order to protect Ethereum's `.transfer / .send` function against reentrancy. +/// The first part of the expression is the stipend given by the MsgValueSimulator to the callee frame. The second part of the expression +/// is the 2300 constant used for 0-value `transfer/send` calls + 1 to make sure that within the call it is not possible to store anything. +pub const MIN_STORAGE_WRITE_PRICE_FOR_REENTRANCY_PROTECTION: u32 = max( + MSG_VALUE_SIMULATOR_ADDITIVE_COST - MSG_VALUE_SIMULATOR_MIN_USED_ERGS + 1, + 2300 + 1, +); + +/// The minimal price in ergs the storage could cost to protect against reentrancy + take into account the usage of the single instance circuits. +pub const MIN_STORAGE_WRITE_COST: u32 = max( + MIN_STORAGE_WRITE_PRICE_FOR_REENTRANCY_PROTECTION, + STORAGE_WRITE_HASHER_MIN_COST_IN_ERGS, +); + lazy_static! { pub static ref BOOTLOADER_FORMAL_ADDRESS: Address = Address::from_low_u64_be(BOOTLOADER_FORMAL_ADDRESS_LOW as u64); From 4c787b85d9a5e072b6f67e7ded130315e9ffff60 Mon Sep 17 00:00:00 2001 From: Igor Aleksanov Date: Thu, 15 Aug 2024 14:07:50 +0400 Subject: [PATCH 3/7] Historical release: v0.140.1 --- crates/circuit_encodings/.gitignore | 4 + crates/circuit_encodings/Cargo.toml | 24 + crates/circuit_encodings/README.md | 4 + .../circuit_encodings/src/callstack_entry.rs | 189 ++ .../src/decommittment_request.rs | 98 + crates/circuit_encodings/src/lib.rs | 787 ++++++++ crates/circuit_encodings/src/log_query.rs | 534 ++++++ crates/circuit_encodings/src/memory_query.rs | 144 ++ .../src/recursion_request.rs | 48 + .../src/state_diff_record.rs | 54 + crates/circuit_sequencer_api/Cargo.toml | 12 +- .../circuit_sequencer_api/src/commitments.rs | 74 + .../src/geometry_config.rs | 20 + crates/circuit_sequencer_api/src/lib.rs | 9 + crates/circuit_sequencer_api/src/proof.rs | 2 + .../src/sort_storage_access.rs | 84 +- crates/circuit_sequencer_api/src/toolset.rs | 19 + crates/circuit_sequencer_api/src/utils.rs | 68 + crates/zk_evm/.github/workflows/ci.yaml | 2 +- crates/zk_evm/Cargo.toml | 2 +- crates/zk_evm/src/lib.rs | 8 +- crates/zk_evm/src/opcodes/execution/add.rs | 1 + crates/zk_evm/src/opcodes/execution/binop.rs | 2 + crates/zk_evm/src/opcodes/execution/div.rs | 2 + .../zk_evm/src/opcodes/execution/far_call.rs | 36 +- crates/zk_evm/src/opcodes/execution/log.rs | 32 +- crates/zk_evm/src/opcodes/execution/mod.rs | 2 - crates/zk_evm/src/opcodes/execution/mul.rs | 2 + .../zk_evm/src/opcodes/execution/near_call.rs | 7 - crates/zk_evm/src/opcodes/execution/ret.rs | 9 - crates/zk_evm/src/opcodes/execution/shift.rs | 2 + crates/zk_evm/src/opcodes/execution/sub.rs | 1 + crates/zk_evm/src/opcodes/execution/uma.rs | 47 +- crates/zk_evm/src/reference_impls/memory.rs | 83 +- crates/zk_evm/src/vm_state/cycle.rs | 81 +- crates/zk_evm/src/vm_state/helpers.rs | 33 +- crates/zk_evm/src/vm_state/mod.rs | 35 +- crates/zk_evm/src/witness_trace/mod.rs | 13 +- .../.github/ISSUE_TEMPLATE/bug_report.md | 39 + .../.github/ISSUE_TEMPLATE/feature_request.md | 21 + .../.github/pull_request_template.md | 20 + .../.github/workflows/cargo-license.yaml | 8 + .../zkevm_circuits/.github/workflows/ci.yaml | 27 + .../.github/workflows/secrets_scanner.yaml | 17 + crates/zkevm_circuits/.gitignore | 3 + crates/zkevm_circuits/CONTRIBUTING.md | 44 + crates/zkevm_circuits/Cargo.toml | 39 + crates/zkevm_circuits/LICENSE-APACHE | 176 ++ crates/zkevm_circuits/LICENSE-MIT | 21 + crates/zkevm_circuits/README.md | 33 + crates/zkevm_circuits/SECURITY.md | 74 + crates/zkevm_circuits/cs_derive/.gitignore | 3 + crates/zkevm_circuits/cs_derive/Cargo.toml | 15 + crates/zkevm_circuits/cs_derive/src/.DS_Store | Bin 0 -> 6148 bytes .../cs_derive/src/allocatable/mod.rs | 283 +++ crates/zkevm_circuits/cs_derive/src/lib.rs | 100 ++ .../cs_derive/src/selectable/mod.rs | 105 ++ crates/zkevm_circuits/cs_derive/src/utils.rs | 167 ++ .../cs_derive/src/var_length_encodable/mod.rs | 110 ++ .../cs_derive/src/witness_hook/mod.rs | 124 ++ crates/zkevm_circuits/deny.toml | 79 + crates/zkevm_circuits/eraLogo.png | Bin 0 -> 79091 bytes crates/zkevm_circuits/rust-toolchain.toml | 2 + crates/zkevm_circuits/rustfmt.toml | 1 + .../src/base_structures/decommit_query/mod.rs | 185 ++ .../src/base_structures/log_query/mod.rs | 686 +++++++ .../src/base_structures/memory_query/mod.rs | 314 ++++ .../zkevm_circuits/src/base_structures/mod.rs | 18 + .../precompile_input_outputs/mod.rs | 52 + .../base_structures/recursion_query/mod.rs | 110 ++ .../src/base_structures/register/mod.rs | 86 + .../base_structures/state_diff_record/mod.rs | 75 + .../src/base_structures/vm_state/callstack.rs | 98 + .../src/base_structures/vm_state/mod.rs | 171 ++ .../base_structures/vm_state/saved_context.rs | 548 ++++++ .../src/code_unpacker_sha256/input.rs | 140 ++ .../src/code_unpacker_sha256/mod.rs | 716 ++++++++ crates/zkevm_circuits/src/config.rs | 5 + .../src/demux_log_queue/input.rs | 106 ++ .../zkevm_circuits/src/demux_log_queue/mod.rs | 922 ++++++++++ .../zkevm_circuits/src/ecrecover/baseline.rs | 937 ++++++++++ .../src/ecrecover/decomp_table.rs | 76 + crates/zkevm_circuits/src/ecrecover/input.rs | 51 + crates/zkevm_circuits/src/ecrecover/mod.rs | 73 + .../src/ecrecover/naf_abs_div2_table.rs | 33 + .../src/ecrecover/new_optimized.rs | 1551 ++++++++++++++++ .../secp256k1/fixed_base_mul_table.rs | 55 + .../src/ecrecover/secp256k1/fq.rs | 7 + .../src/ecrecover/secp256k1/fr.rs | 7 + .../src/ecrecover/secp256k1/mod.rs | 762 ++++++++ .../circuit_inputs/main_vm.rs | 71 + .../fsm_input_output/circuit_inputs/mod.rs | 6 + .../src/fsm_input_output/mod.rs | 326 ++++ .../src/keccak256_round_function/input.rs | 95 + .../src/keccak256_round_function/mod.rs | 573 ++++++ crates/zkevm_circuits/src/lib.rs | 41 + .../zkevm_circuits/src/linear_hasher/input.rs | 80 + .../zkevm_circuits/src/linear_hasher/mod.rs | 214 +++ crates/zkevm_circuits/src/log_sorter/input.rs | 106 ++ crates/zkevm_circuits/src/log_sorter/mod.rs | 814 +++++++++ crates/zkevm_circuits/src/main_vm/cycle.rs | 966 ++++++++++ .../src/main_vm/decoded_opcode.rs | 576 ++++++ crates/zkevm_circuits/src/main_vm/loading.rs | 226 +++ crates/zkevm_circuits/src/main_vm/mod.rs | 232 +++ .../src/main_vm/opcode_bitmask.rs | 130 ++ .../src/main_vm/opcodes/add_sub.rs | 282 +++ .../src/main_vm/opcodes/binop.rs | 244 +++ .../src/main_vm/opcodes/call_ret.rs | 512 ++++++ .../main_vm/opcodes/call_ret_impl/far_call.rs | 1594 +++++++++++++++++ .../src/main_vm/opcodes/call_ret_impl/mod.rs | 86 + .../opcodes/call_ret_impl/near_call.rs | 184 ++ .../src/main_vm/opcodes/call_ret_impl/ret.rs | 463 +++++ .../src/main_vm/opcodes/context.rs | 307 ++++ .../src/main_vm/opcodes/jump.rs | 38 + .../zkevm_circuits/src/main_vm/opcodes/log.rs | 667 +++++++ .../zkevm_circuits/src/main_vm/opcodes/mod.rs | 180 ++ .../src/main_vm/opcodes/mul_div.rs | 417 +++++ .../zkevm_circuits/src/main_vm/opcodes/nop.rs | 24 + .../zkevm_circuits/src/main_vm/opcodes/ptr.rs | 183 ++ .../src/main_vm/opcodes/shifts.rs | 221 +++ .../zkevm_circuits/src/main_vm/opcodes/uma.rs | 1103 ++++++++++++ .../zkevm_circuits/src/main_vm/pre_state.rs | 489 +++++ .../src/main_vm/register_input_view.rs | 54 + .../zkevm_circuits/src/main_vm/state_diffs.rs | 99 + crates/zkevm_circuits/src/main_vm/utils.rs | 521 ++++++ .../src/main_vm/witness_oracle.rs | 168 ++ .../src/ram_permutation/input.rs | 120 ++ .../zkevm_circuits/src/ram_permutation/mod.rs | 633 +++++++ .../src/recursion/compression/input.rs | 23 + .../src/recursion/compression/mod.rs | 121 ++ .../src/recursion/interblock/input.rs | 23 + .../recursion/interblock/keccak_aggregator.rs | 96 + .../src/recursion/interblock/mod.rs | 154 ++ .../src/recursion/leaf_layer/input.rs | 83 + .../src/recursion/leaf_layer/mod.rs | 214 +++ crates/zkevm_circuits/src/recursion/mod.rs | 9 + .../src/recursion/node_layer/input.rs | 61 + .../src/recursion/node_layer/mod.rs | 316 ++++ .../zkevm_circuits/src/scheduler/auxiliary.rs | 302 ++++ .../src/scheduler/block_header/mod.rs | 178 ++ crates/zkevm_circuits/src/scheduler/input.rs | 132 ++ crates/zkevm_circuits/src/scheduler/mod.rs | 1059 +++++++++++ .../src/sha256_round_function/input.rs | 89 + .../src/sha256_round_function/mod.rs | 464 +++++ .../src/sort_decommittment_requests/input.rs | 124 ++ .../src/sort_decommittment_requests/mod.rs | 1389 ++++++++++++++ .../src/storage_application/input.rs | 121 ++ .../src/storage_application/mod.rs | 720 ++++++++ .../input.rs | 136 ++ .../storage_validity_by_grand_product/mod.rs | 1133 ++++++++++++ .../test_input.rs | 632 +++++++ crates/zkevm_circuits/src/tables/bitshift.rs | 40 + .../zkevm_circuits/src/tables/conditional.rs | 58 + .../src/tables/integer_to_boolean_mask.rs | 91 + crates/zkevm_circuits/src/tables/mod.rs | 13 + .../src/tables/opcodes_decoding.rs | 38 + .../src/tables/uma_ptr_read_cleanup.rs | 40 + crates/zkevm_circuits/src/utils.rs | 137 ++ 158 files changed, 32548 insertions(+), 362 deletions(-) create mode 100644 crates/circuit_encodings/.gitignore create mode 100644 crates/circuit_encodings/Cargo.toml create mode 100644 crates/circuit_encodings/README.md create mode 100644 crates/circuit_encodings/src/callstack_entry.rs create mode 100644 crates/circuit_encodings/src/decommittment_request.rs create mode 100644 crates/circuit_encodings/src/lib.rs create mode 100644 crates/circuit_encodings/src/log_query.rs create mode 100644 crates/circuit_encodings/src/memory_query.rs create mode 100644 crates/circuit_encodings/src/recursion_request.rs create mode 100644 crates/circuit_encodings/src/state_diff_record.rs create mode 100644 crates/circuit_sequencer_api/src/commitments.rs create mode 100644 crates/circuit_sequencer_api/src/geometry_config.rs create mode 100644 crates/circuit_sequencer_api/src/toolset.rs create mode 100644 crates/circuit_sequencer_api/src/utils.rs create mode 100644 crates/zkevm_circuits/.github/ISSUE_TEMPLATE/bug_report.md create mode 100644 crates/zkevm_circuits/.github/ISSUE_TEMPLATE/feature_request.md create mode 100644 crates/zkevm_circuits/.github/pull_request_template.md create mode 100644 crates/zkevm_circuits/.github/workflows/cargo-license.yaml create mode 100644 crates/zkevm_circuits/.github/workflows/ci.yaml create mode 100644 crates/zkevm_circuits/.github/workflows/secrets_scanner.yaml create mode 100644 crates/zkevm_circuits/.gitignore create mode 100644 crates/zkevm_circuits/CONTRIBUTING.md create mode 100644 crates/zkevm_circuits/Cargo.toml create mode 100644 crates/zkevm_circuits/LICENSE-APACHE create mode 100644 crates/zkevm_circuits/LICENSE-MIT create mode 100644 crates/zkevm_circuits/README.md create mode 100644 crates/zkevm_circuits/SECURITY.md create mode 100644 crates/zkevm_circuits/cs_derive/.gitignore create mode 100644 crates/zkevm_circuits/cs_derive/Cargo.toml create mode 100644 crates/zkevm_circuits/cs_derive/src/.DS_Store create mode 100644 crates/zkevm_circuits/cs_derive/src/allocatable/mod.rs create mode 100644 crates/zkevm_circuits/cs_derive/src/lib.rs create mode 100644 crates/zkevm_circuits/cs_derive/src/selectable/mod.rs create mode 100644 crates/zkevm_circuits/cs_derive/src/utils.rs create mode 100644 crates/zkevm_circuits/cs_derive/src/var_length_encodable/mod.rs create mode 100644 crates/zkevm_circuits/cs_derive/src/witness_hook/mod.rs create mode 100644 crates/zkevm_circuits/deny.toml create mode 100644 crates/zkevm_circuits/eraLogo.png create mode 100644 crates/zkevm_circuits/rust-toolchain.toml create mode 100644 crates/zkevm_circuits/rustfmt.toml create mode 100644 crates/zkevm_circuits/src/base_structures/decommit_query/mod.rs create mode 100644 crates/zkevm_circuits/src/base_structures/log_query/mod.rs create mode 100644 crates/zkevm_circuits/src/base_structures/memory_query/mod.rs create mode 100644 crates/zkevm_circuits/src/base_structures/mod.rs create mode 100644 crates/zkevm_circuits/src/base_structures/precompile_input_outputs/mod.rs create mode 100644 crates/zkevm_circuits/src/base_structures/recursion_query/mod.rs create mode 100644 crates/zkevm_circuits/src/base_structures/register/mod.rs create mode 100644 crates/zkevm_circuits/src/base_structures/state_diff_record/mod.rs create mode 100644 crates/zkevm_circuits/src/base_structures/vm_state/callstack.rs create mode 100644 crates/zkevm_circuits/src/base_structures/vm_state/mod.rs create mode 100644 crates/zkevm_circuits/src/base_structures/vm_state/saved_context.rs create mode 100644 crates/zkevm_circuits/src/code_unpacker_sha256/input.rs create mode 100644 crates/zkevm_circuits/src/code_unpacker_sha256/mod.rs create mode 100644 crates/zkevm_circuits/src/config.rs create mode 100644 crates/zkevm_circuits/src/demux_log_queue/input.rs create mode 100644 crates/zkevm_circuits/src/demux_log_queue/mod.rs create mode 100644 crates/zkevm_circuits/src/ecrecover/baseline.rs create mode 100644 crates/zkevm_circuits/src/ecrecover/decomp_table.rs create mode 100644 crates/zkevm_circuits/src/ecrecover/input.rs create mode 100644 crates/zkevm_circuits/src/ecrecover/mod.rs create mode 100644 crates/zkevm_circuits/src/ecrecover/naf_abs_div2_table.rs create mode 100644 crates/zkevm_circuits/src/ecrecover/new_optimized.rs create mode 100644 crates/zkevm_circuits/src/ecrecover/secp256k1/fixed_base_mul_table.rs create mode 100644 crates/zkevm_circuits/src/ecrecover/secp256k1/fq.rs create mode 100644 crates/zkevm_circuits/src/ecrecover/secp256k1/fr.rs create mode 100644 crates/zkevm_circuits/src/ecrecover/secp256k1/mod.rs create mode 100644 crates/zkevm_circuits/src/fsm_input_output/circuit_inputs/main_vm.rs create mode 100644 crates/zkevm_circuits/src/fsm_input_output/circuit_inputs/mod.rs create mode 100644 crates/zkevm_circuits/src/fsm_input_output/mod.rs create mode 100644 crates/zkevm_circuits/src/keccak256_round_function/input.rs create mode 100644 crates/zkevm_circuits/src/keccak256_round_function/mod.rs create mode 100644 crates/zkevm_circuits/src/lib.rs create mode 100644 crates/zkevm_circuits/src/linear_hasher/input.rs create mode 100644 crates/zkevm_circuits/src/linear_hasher/mod.rs create mode 100644 crates/zkevm_circuits/src/log_sorter/input.rs create mode 100644 crates/zkevm_circuits/src/log_sorter/mod.rs create mode 100644 crates/zkevm_circuits/src/main_vm/cycle.rs create mode 100644 crates/zkevm_circuits/src/main_vm/decoded_opcode.rs create mode 100644 crates/zkevm_circuits/src/main_vm/loading.rs create mode 100644 crates/zkevm_circuits/src/main_vm/mod.rs create mode 100644 crates/zkevm_circuits/src/main_vm/opcode_bitmask.rs create mode 100644 crates/zkevm_circuits/src/main_vm/opcodes/add_sub.rs create mode 100644 crates/zkevm_circuits/src/main_vm/opcodes/binop.rs create mode 100644 crates/zkevm_circuits/src/main_vm/opcodes/call_ret.rs create mode 100644 crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/far_call.rs create mode 100644 crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/mod.rs create mode 100644 crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/near_call.rs create mode 100644 crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/ret.rs create mode 100644 crates/zkevm_circuits/src/main_vm/opcodes/context.rs create mode 100644 crates/zkevm_circuits/src/main_vm/opcodes/jump.rs create mode 100644 crates/zkevm_circuits/src/main_vm/opcodes/log.rs create mode 100644 crates/zkevm_circuits/src/main_vm/opcodes/mod.rs create mode 100644 crates/zkevm_circuits/src/main_vm/opcodes/mul_div.rs create mode 100644 crates/zkevm_circuits/src/main_vm/opcodes/nop.rs create mode 100644 crates/zkevm_circuits/src/main_vm/opcodes/ptr.rs create mode 100644 crates/zkevm_circuits/src/main_vm/opcodes/shifts.rs create mode 100644 crates/zkevm_circuits/src/main_vm/opcodes/uma.rs create mode 100644 crates/zkevm_circuits/src/main_vm/pre_state.rs create mode 100644 crates/zkevm_circuits/src/main_vm/register_input_view.rs create mode 100644 crates/zkevm_circuits/src/main_vm/state_diffs.rs create mode 100644 crates/zkevm_circuits/src/main_vm/utils.rs create mode 100644 crates/zkevm_circuits/src/main_vm/witness_oracle.rs create mode 100644 crates/zkevm_circuits/src/ram_permutation/input.rs create mode 100644 crates/zkevm_circuits/src/ram_permutation/mod.rs create mode 100644 crates/zkevm_circuits/src/recursion/compression/input.rs create mode 100644 crates/zkevm_circuits/src/recursion/compression/mod.rs create mode 100644 crates/zkevm_circuits/src/recursion/interblock/input.rs create mode 100644 crates/zkevm_circuits/src/recursion/interblock/keccak_aggregator.rs create mode 100644 crates/zkevm_circuits/src/recursion/interblock/mod.rs create mode 100644 crates/zkevm_circuits/src/recursion/leaf_layer/input.rs create mode 100644 crates/zkevm_circuits/src/recursion/leaf_layer/mod.rs create mode 100644 crates/zkevm_circuits/src/recursion/mod.rs create mode 100644 crates/zkevm_circuits/src/recursion/node_layer/input.rs create mode 100644 crates/zkevm_circuits/src/recursion/node_layer/mod.rs create mode 100644 crates/zkevm_circuits/src/scheduler/auxiliary.rs create mode 100644 crates/zkevm_circuits/src/scheduler/block_header/mod.rs create mode 100644 crates/zkevm_circuits/src/scheduler/input.rs create mode 100644 crates/zkevm_circuits/src/scheduler/mod.rs create mode 100644 crates/zkevm_circuits/src/sha256_round_function/input.rs create mode 100644 crates/zkevm_circuits/src/sha256_round_function/mod.rs create mode 100644 crates/zkevm_circuits/src/sort_decommittment_requests/input.rs create mode 100644 crates/zkevm_circuits/src/sort_decommittment_requests/mod.rs create mode 100644 crates/zkevm_circuits/src/storage_application/input.rs create mode 100644 crates/zkevm_circuits/src/storage_application/mod.rs create mode 100644 crates/zkevm_circuits/src/storage_validity_by_grand_product/input.rs create mode 100644 crates/zkevm_circuits/src/storage_validity_by_grand_product/mod.rs create mode 100644 crates/zkevm_circuits/src/storage_validity_by_grand_product/test_input.rs create mode 100644 crates/zkevm_circuits/src/tables/bitshift.rs create mode 100644 crates/zkevm_circuits/src/tables/conditional.rs create mode 100644 crates/zkevm_circuits/src/tables/integer_to_boolean_mask.rs create mode 100644 crates/zkevm_circuits/src/tables/mod.rs create mode 100644 crates/zkevm_circuits/src/tables/opcodes_decoding.rs create mode 100644 crates/zkevm_circuits/src/tables/uma_ptr_read_cleanup.rs create mode 100644 crates/zkevm_circuits/src/utils.rs diff --git a/crates/circuit_encodings/.gitignore b/crates/circuit_encodings/.gitignore new file mode 100644 index 0000000..37a4f98 --- /dev/null +++ b/crates/circuit_encodings/.gitignore @@ -0,0 +1,4 @@ +/target +Cargo.lock +.idea +.DS_Store \ No newline at end of file diff --git a/crates/circuit_encodings/Cargo.toml b/crates/circuit_encodings/Cargo.toml new file mode 100644 index 0000000..949b413 --- /dev/null +++ b/crates/circuit_encodings/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "circuit_encodings" +version = "0.140.1" +edition = "2021" +authors = ["The Matter Labs Team "] +homepage = "https://zksync.io/" +repository = "https://github.com/matter-labs/era-zkevm_test_harness/" +license = "MIT OR Apache-2.0" +keywords = ["blockchain", "zksync"] +categories = ["cryptography"] +description = "ZKsync Era circuits encodings" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +zkevm_circuits = { version = "0.140", path = "../zkevm_circuits" } # Not pinned, because it's an old version used only by MultiVM. +zk_evm = { version = "0.140", path = "../zk_evm" } # Not pinned, because it's an old version used only by MultiVM + +derivative = "2.2" +serde = {version = "1", features = ["derive"]} + +[features] +default = [] +log_tracing = ["zkevm_circuits/log_tracing"] diff --git a/crates/circuit_encodings/README.md b/crates/circuit_encodings/README.md new file mode 100644 index 0000000..cb77477 --- /dev/null +++ b/crates/circuit_encodings/README.md @@ -0,0 +1,4 @@ +# Circuit encodings + +Separate crate, to handle the encodings for circuits. +It is split away from circuits, to save on compilation time. \ No newline at end of file diff --git a/crates/circuit_encodings/src/callstack_entry.rs b/crates/circuit_encodings/src/callstack_entry.rs new file mode 100644 index 0000000..e2fdfda --- /dev/null +++ b/crates/circuit_encodings/src/callstack_entry.rs @@ -0,0 +1,189 @@ +use crate::boojum::field::SmallField; +use zk_evm::vm_state::CallStackEntry; + +use super::*; + +pub fn u128_as_u32_le(value: u128) -> [u32; 4] { + [ + value as u32, + (value >> 32) as u32, + (value >> 64) as u32, + (value >> 96) as u32, + ] +} + +// we need some extra data to preserve +#[derive(Clone, Copy, Debug, serde::Serialize, serde::Deserialize)] +#[serde(bound = "")] +pub struct ExtendedCallstackEntry { + pub callstack_entry: CallStackEntry, + pub rollback_queue_head: [F; QUEUE_STATE_WIDTH], + pub rollback_queue_tail: [F; QUEUE_STATE_WIDTH], + pub rollback_queue_segment_length: u32, +} + +#[derive(Clone, Copy, Debug, Default)] +pub struct CallstackEntryRollbackState { + pub rollback_queue_head: [F; QUEUE_STATE_WIDTH], + pub rollback_queue_tail: [F; QUEUE_STATE_WIDTH], + pub rollback_queue_segment_length: u32, +} + +use zkevm_circuits::base_structures::vm_state::saved_context::EXECUTION_CONTEXT_RECORD_ENCODING_WIDTH; + +impl OutOfCircuitFixedLengthEncodable + for ExtendedCallstackEntry +{ + fn encoding_witness(&self) -> [F; EXECUTION_CONTEXT_RECORD_ENCODING_WIDTH] { + debug_assert!(F::CAPACITY_BITS >= 57); + // full field elements first for simplicity + let v0 = self.rollback_queue_head[0]; + let v1 = self.rollback_queue_head[1]; + let v2 = self.rollback_queue_head[2]; + let v3 = self.rollback_queue_head[3]; + + let v4 = self.rollback_queue_tail[0]; + let v5 = self.rollback_queue_tail[1]; + let v6 = self.rollback_queue_tail[2]; + let v7 = self.rollback_queue_tail[3]; + + let code_address = decompose_address_as_u32x5(self.callstack_entry.code_address); + let v8 = code_address[0].into_field(); + let v9 = code_address[1].into_field(); + let v10 = code_address[2].into_field(); + let v11 = code_address[3].into_field(); + let v12 = code_address[4].into_field(); + + let this = decompose_address_as_u32x5(self.callstack_entry.this_address); + let v13 = this[0].into_field(); + let v14 = this[1].into_field(); + let v15 = this[2].into_field(); + let v16 = this[3].into_field(); + let v17 = this[4].into_field(); + + let caller_address = decompose_address_as_u32x5(self.callstack_entry.msg_sender); + let v18 = caller_address[0].into_field(); + let v19 = caller_address[1].into_field(); + let v20 = caller_address[2].into_field(); + let v21 = caller_address[3].into_field(); + let v22 = caller_address[4].into_field(); + + let context_u128_value_composite = u128_as_u32_le(self.callstack_entry.context_u128_value); + + let v23 = context_u128_value_composite[0].into_field(); + let v24 = context_u128_value_composite[1].into_field(); + let v25 = context_u128_value_composite[2].into_field(); + let v26 = context_u128_value_composite[3].into_field(); + + // now we have left + // - code_page + // - base_page + // - heap_upper_bound + // - aux_heap_upper_bound + // - ergs_remaining + // - sp + // - pc + // - eh + // - reverted_queue_segment_len + // - shard ids + // - few boolean flags + + // as usual, take u32 and add something on top + + let v27 = linear_combination(&[ + (self.callstack_entry.code_page.0.into_field(), F::ONE), + ( + self.callstack_entry.pc.into_field(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + self.callstack_entry.this_shard_id.into_field(), + F::from_u64_unchecked(1u64 << 48), + ), + ( + self.callstack_entry.is_static.into_field(), + F::from_u64_unchecked(1u64 << 56), + ), + ]); + + let is_kernel_mode = self.callstack_entry.is_kernel_mode(); + + let v28 = linear_combination(&[ + (self.callstack_entry.base_memory_page.0.into_field(), F::ONE), + ( + self.callstack_entry.sp.into_field(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + self.callstack_entry.caller_shard_id.into_field(), + F::from_u64_unchecked(1u64 << 48), + ), + ( + is_kernel_mode.into_field(), + F::from_u64_unchecked(1u64 << 56), + ), + ]); + + let v29 = linear_combination(&[ + (self.callstack_entry.ergs_remaining.into_field(), F::ONE), + ( + self.callstack_entry.exception_handler_location.into_field(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + self.callstack_entry.code_shard_id.into_field(), + F::from_u64_unchecked(1u64 << 48), + ), + ( + self.callstack_entry.is_local_frame.into_field(), + F::from_u64_unchecked(1u64 << 56), + ), + ]); + + // now we have left + // - heap_upper_bound + // - aux_heap_upper_bound + // - reverted_queue_segment_len + + let reverted_queue_segment_len_decomposition = + self.rollback_queue_segment_length.to_le_bytes(); + let v30 = linear_combination(&[ + (self.callstack_entry.heap_bound.into_field(), F::ONE), + ( + reverted_queue_segment_len_decomposition[0].into_field(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + reverted_queue_segment_len_decomposition[1].into_field(), + F::from_u64_unchecked(1u64 << 40), + ), + ]); + + let v31 = linear_combination(&[ + (self.callstack_entry.aux_heap_bound.into_field(), F::ONE), + ( + reverted_queue_segment_len_decomposition[2].into_field(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + reverted_queue_segment_len_decomposition[3].into_field(), + F::from_u64_unchecked(1u64 << 40), + ), + ]); + + [ + v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, + v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, + ] + } +} + +pub type CallstackSimulator = FullWidthStackSimulator< + F, + ExtendedCallstackEntry, + EXECUTION_CONTEXT_RECORD_ENCODING_WIDTH, + FULL_SPONGE_QUEUE_STATE_WIDTH, + 4, +>; +pub type CallstackSimulatorState = + FullWidthStackIntermediateStates; diff --git a/crates/circuit_encodings/src/decommittment_request.rs b/crates/circuit_encodings/src/decommittment_request.rs new file mode 100644 index 0000000..a00ac5a --- /dev/null +++ b/crates/circuit_encodings/src/decommittment_request.rs @@ -0,0 +1,98 @@ +use super::*; +use zk_evm::aux_structures::DecommittmentQuery; + +use zkevm_circuits::base_structures::decommit_query::DECOMMIT_QUERY_PACKED_WIDTH; + +impl OutOfCircuitFixedLengthEncodable + for DecommittmentQuery +{ + fn encoding_witness(&self) -> [F; DECOMMIT_QUERY_PACKED_WIDTH] { + debug_assert!(F::CAPACITY_BITS >= 56); + + let code_hash = decompose_u256_as_u32x8(self.hash); + + // we assume that page bytes are known, so it'll be nop anyway + let page_bytes = self.memory_page.0.to_le_bytes(); + let timestamp_bytes = self.timestamp.0.to_le_bytes(); + + let v0 = linear_combination(&[ + (code_hash[0].into_field(), F::ONE), + ( + page_bytes[0].into_field(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + page_bytes[1].into_field(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + page_bytes[2].into_field(), + F::from_u64_unchecked(1u64 << 48), + ), + ]); + + let v1 = linear_combination(&[ + (code_hash[1].into_field(), F::ONE), + ( + page_bytes[3].into_field(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + timestamp_bytes[0].into_field(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + timestamp_bytes[1].into_field(), + F::from_u64_unchecked(1u64 << 48), + ), + ]); + + let v2 = linear_combination(&[ + (code_hash[2].into_field(), F::ONE), + ( + timestamp_bytes[2].into_field(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + timestamp_bytes[3].into_field(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + self.is_fresh.into_field(), + F::from_u64_unchecked(1u64 << 48), + ), + ]); + + let v3 = code_hash[3].into_field(); + let v4 = code_hash[4].into_field(); + let v5 = code_hash[5].into_field(); + let v6 = code_hash[6].into_field(); + let v7 = code_hash[7].into_field(); + + [v0, v1, v2, v3, v4, v5, v6, v7] + } +} + +pub type DecommittmentQueueSimulator = FullWidthQueueSimulator< + F, + DecommittmentQuery, + DECOMMIT_QUERY_PACKED_WIDTH, + FULL_SPONGE_QUEUE_STATE_WIDTH, + 1, +>; +pub type DecommittmentQueueState = + FullWidthQueueIntermediateStates; + +impl CircuitEquivalentReflection for DecommittmentQuery { + type Destination = zkevm_circuits::base_structures::decommit_query::DecommitQuery; + fn reflect(&self) -> >::Witness { + use zkevm_circuits::base_structures::decommit_query::DecommitQueryWitness; + + DecommitQueryWitness { + timestamp: self.timestamp.0, + code_hash: self.hash, + is_first: self.is_fresh, + page: self.memory_page.0, + } + } +} diff --git a/crates/circuit_encodings/src/lib.rs b/crates/circuit_encodings/src/lib.rs new file mode 100644 index 0000000..6565a1b --- /dev/null +++ b/crates/circuit_encodings/src/lib.rs @@ -0,0 +1,787 @@ +use crate::boojum::algebraic_props::round_function::{ + absorb_multiple_rounds, AbsorptionModeOverwrite, AlgebraicRoundFunction, +}; +use crate::boojum::field::SmallField; +use crate::boojum::gadgets::traits::allocatable::CSAllocatable; +use crate::boojum::gadgets::traits::round_function::*; +use crate::boojum::gadgets::u160::decompose_address_as_u32x5; +use crate::boojum::gadgets::u256::decompose_u256_as_u32x8; +use derivative::Derivative; +use std::collections::VecDeque; +use zkevm_circuits::base_structures::vm_state::{FULL_SPONGE_QUEUE_STATE_WIDTH, QUEUE_STATE_WIDTH}; + +use crate::boojum::implementations::poseidon2::Poseidon2Goldilocks; +pub use zk_evm::ethereum_types; + +pub type ZkSyncDefaultRoundFunction = Poseidon2Goldilocks; + +pub use zk_evm; +pub use zkevm_circuits; +pub use zkevm_circuits::boojum; + +// for we need to encode some structures as packed field elements +pub trait OutOfCircuitFixedLengthEncodable: Clone { + fn encoding_witness(&self) -> [F; N]; +} + +// all encodings must match circuit counterparts +pub mod callstack_entry; +pub mod decommittment_request; +pub mod log_query; +pub mod memory_query; +pub mod recursion_request; +pub mod state_diff_record; + +pub use self::log_query::*; + +pub(crate) fn make_round_function_pairs( + initial: [F; N], + intermediates: [[F; N]; ROUNDS], +) -> [([F; N], [F; N]); ROUNDS] { + let mut result = [([F::ZERO; N], [F::ZERO; N]); ROUNDS]; + result[0].0 = initial; + result[0].1 = intermediates[0]; + for idx in 1..ROUNDS { + result[idx].0 = result[idx - 1].1; + result[idx].1 = intermediates[idx]; + } + + result +} + +#[derive(Derivative)] +#[derivative(Debug, Clone(bound = ""), Copy(bound = ""))] +pub struct QueueIntermediateStates< + F: SmallField, + const T: usize, + const SW: usize, + const ROUNDS: usize, +> { + pub head: [F; T], + pub tail: [F; T], + pub previous_head: [F; T], + pub previous_tail: [F; T], + pub num_items: u32, + pub round_function_execution_pairs: [([F; SW], [F; SW]); ROUNDS], +} + +impl + QueueIntermediateStates +{ + pub fn empty() -> Self { + Self { + head: [F::ZERO; T], + tail: [F::ZERO; T], + previous_head: [F::ZERO; T], + previous_tail: [F::ZERO; T], + num_items: 0, + round_function_execution_pairs: [([F::ZERO; SW], [F::ZERO; SW]); ROUNDS], + } + } +} + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative( + Clone(bound = ""), + Default(bound = "[F; T]: Default, [F; N]: Default"), + Debug +)] +#[serde(bound = "[F; T]: serde::Serialize + serde::de::DeserializeOwned, + [F; N]: serde::Serialize + serde::de::DeserializeOwned, + I: serde::Serialize + serde::de::DeserializeOwned")] +pub struct QueueSimulator< + F: SmallField, + I: OutOfCircuitFixedLengthEncodable, + const T: usize, + const N: usize, + const ROUNDS: usize, +> { + pub head: [F; T], + pub tail: [F; T], + pub num_items: u32, + pub witness: VecDeque<([F; N], [F; T], I)>, +} + +impl< + F: SmallField, + I: OutOfCircuitFixedLengthEncodable, + const T: usize, + const N: usize, + const ROUNDS: usize, + > QueueSimulator +{ + pub fn empty() -> Self { + Self { + head: [F::ZERO; T], + tail: [F::ZERO; T], + num_items: 0, + witness: VecDeque::new(), + } + } + + pub fn split(mut self, at: u32) -> (Self, Self) { + if at >= self.num_items { + let mut artificial_empty = Self::empty(); + artificial_empty.head = self.tail; + artificial_empty.tail = self.tail; + return (self, artificial_empty); + } + + let first_wit: VecDeque<_> = self.witness.drain(..(at as usize)).collect(); + let rest_wit = self.witness; + + let splitting_point = rest_wit.front().unwrap().1; + + let first = Self { + head: self.head, + tail: splitting_point, + num_items: at, + witness: first_wit, + }; + + let rest = Self { + head: splitting_point, + tail: self.tail, + num_items: self.num_items - at, + witness: rest_wit, + }; + + (first, rest) + } + + pub fn merge(first: Self, second: Self) -> Self { + assert_eq!(first.tail, second.head); + + let mut wit = first.witness; + wit.extend(second.witness); + + Self { + head: first.head, + tail: second.tail, + num_items: first.num_items + second.num_items, + witness: wit, + } + } + + pub fn push< + R: CircuitRoundFunction + AlgebraicRoundFunction, + const AW: usize, + const SW: usize, + const CW: usize, + >( + &mut self, + element: I, + round_function: &R, + ) { + let _ = self.push_and_output_intermediate_data(element, round_function); + } + + pub fn push_and_output_intermediate_data< + R: CircuitRoundFunction + AlgebraicRoundFunction, + const AW: usize, + const SW: usize, + const CW: usize, + >( + &mut self, + element: I, + _round_function: &R, + ) -> ( + [F; T], // old tail + QueueIntermediateStates, // new head/tail, as well as round function ins/outs + ) { + let old_tail = self.tail; + let encoding = element.encoding_witness(); + let mut to_hash = Vec::with_capacity(N + T); + to_hash.extend_from_slice(&encoding); + to_hash.extend(self.tail); + + let mut state = R::initial_state(); + let states = absorb_multiple_rounds::( + &mut state, &to_hash, + ); + let new_tail = + >::state_into_commitment::(&state); + self.witness.push_back((encoding, old_tail, element)); + + let states = make_round_function_pairs(R::initial_state(), states); + + self.num_items += 1; + self.tail = new_tail; + + let intermediate_info = QueueIntermediateStates { + head: self.head, + tail: new_tail, + previous_head: self.head, // unchanged + previous_tail: old_tail, + num_items: self.num_items, + round_function_execution_pairs: states, + }; + + (old_tail, intermediate_info) + } + + pub fn pop_and_output_intermediate_data< + R: CircuitRoundFunction + AlgebraicRoundFunction, + const AW: usize, + const SW: usize, + const CW: usize, + >( + &mut self, + _round_function: &R, + ) -> (I, QueueIntermediateStates) { + let old_head = self.head; + let (_, _, element) = self.witness.pop_front().unwrap(); + + let encoding = element.encoding_witness(); + let mut to_hash = Vec::with_capacity(N + T); + to_hash.extend_from_slice(&encoding); + to_hash.extend(self.head); + + let mut state = R::initial_state(); + let states = absorb_multiple_rounds::( + &mut state, &to_hash, + ); + let new_head = + >::state_into_commitment::(&state); + + let states = make_round_function_pairs(R::initial_state(), states); + + self.num_items -= 1; + self.head = new_head; + + if self.num_items == 0 { + assert_eq!(self.head, self.tail); + } + + let intermediate_info = QueueIntermediateStates { + head: self.head, + tail: self.tail, + previous_head: old_head, + previous_tail: self.tail, + num_items: self.num_items, + round_function_execution_pairs: states, + }; + + (element, intermediate_info) + } + + pub fn split_by< + R: CircuitRoundFunction + AlgebraicRoundFunction, + const AW: usize, + const SW: usize, + const CW: usize, + >( + mut self, + chunk_size: usize, + round_function: &R, + ) -> Vec { + let mut result = vec![]; + if self.num_items == 0 { + return result; + } else { + assert_eq!(self.witness.len(), self.num_items as usize); + } + + while self.num_items > 0 { + let mut subqueue = Self::empty(); + subqueue.head = self.head; + subqueue.tail = self.head; + for _ in 0..chunk_size { + if self.num_items == 0 { + break; + } + let (el, _) = self.pop_and_output_intermediate_data(round_function); + subqueue.push(el, round_function); + } + + result.push(subqueue); + } + + assert_eq!(self.tail, result.last().unwrap().tail); + + result + } +} + +#[derive(Derivative)] +#[derivative(Debug, Clone(bound = ""), Copy(bound = ""))] +pub struct FullWidthQueueIntermediateStates { + pub head: [F; SW], + pub tail: [F; SW], + pub old_head: [F; SW], + pub old_tail: [F; SW], + pub num_items: u32, + pub round_function_execution_pairs: [([F; SW], [F; SW]); ROUNDS], +} + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Debug, Clone(bound = ""))] +#[serde(bound = "[F; SW]: serde::Serialize + serde::de::DeserializeOwned, + [F; N]: serde::Serialize + serde::de::DeserializeOwned, + I: serde::Serialize + serde::de::DeserializeOwned")] +pub struct FullWidthQueueSimulator< + F: SmallField, + I: OutOfCircuitFixedLengthEncodable, + const N: usize, + const SW: usize, + const ROUNDS: usize, +> { + pub head: [F; SW], + pub tail: [F; SW], + pub num_items: u32, + pub witness: VecDeque<([F; N], [F; SW], I)>, +} + +impl< + F: SmallField, + I: OutOfCircuitFixedLengthEncodable, + const N: usize, + const SW: usize, + const ROUNDS: usize, + > Default for FullWidthQueueSimulator +{ + fn default() -> Self { + Self::empty() + } +} + +impl< + F: SmallField, + I: OutOfCircuitFixedLengthEncodable, + const N: usize, + const SW: usize, + const ROUNDS: usize, + > FullWidthQueueSimulator +{ + pub fn empty() -> Self { + Self { + head: [F::ZERO; SW], + tail: [F::ZERO; SW], + num_items: 0, + witness: VecDeque::new(), + } + } + + pub fn merge(first: Self, second: Self) -> Self { + assert_eq!(first.tail, second.head); + + let mut wit = first.witness; + wit.extend(second.witness); + + Self { + head: first.head, + tail: second.tail, + num_items: first.num_items + second.num_items, + witness: wit, + } + } + + pub fn push< + R: CircuitRoundFunction + AlgebraicRoundFunction, + const AW: usize, + const CW: usize, + >( + &mut self, + element: I, + round_function: &R, + ) { + let _ = self.push_and_output_intermediate_data(element, round_function); + } + + pub fn push_and_output_intermediate_data< + R: CircuitRoundFunction + AlgebraicRoundFunction, + const AW: usize, + const CW: usize, + >( + &mut self, + element: I, + _round_function: &R, + ) -> ( + [F; SW], // old tail + FullWidthQueueIntermediateStates, + ) { + let old_tail = self.tail; + assert!(N % AW == 0); + let encoding = element.encoding_witness(); + + let mut state = old_tail; + let states = absorb_multiple_rounds::( + &mut state, &encoding, + ); + let new_tail = state; + + let states = make_round_function_pairs(old_tail, states); + + self.witness.push_back((encoding, new_tail, element)); + self.num_items += 1; + self.tail = new_tail; + + let intermediate_info = FullWidthQueueIntermediateStates { + head: self.head, + tail: new_tail, + old_head: self.head, + old_tail, + num_items: self.num_items, + round_function_execution_pairs: states, + }; + + (old_tail, intermediate_info) + } + + pub fn pop_and_output_intermediate_data< + R: CircuitRoundFunction + AlgebraicRoundFunction, + const AW: usize, + const CW: usize, + >( + &mut self, + _round_function: &R, + ) -> (I, FullWidthQueueIntermediateStates) { + let old_head = self.head; + assert!(N % AW == 0); + let (_, _, element) = self.witness.pop_front().unwrap(); + let encoding = element.encoding_witness(); + + let mut state = old_head; + let states = absorb_multiple_rounds::( + &mut state, &encoding, + ); + let new_head = state; + + let states = make_round_function_pairs(old_head, states); + + self.num_items -= 1; + self.head = new_head; + + if self.num_items == 0 { + assert_eq!(self.head, self.tail); + } + + let intermediate_info = FullWidthQueueIntermediateStates { + head: self.head, + tail: self.tail, + old_head, + old_tail: self.tail, + num_items: self.num_items, + round_function_execution_pairs: states, + }; + + (element, intermediate_info) + } + + /// Splits the queue into the smaller queues of length `chunk_size`. The last queue might be shorter. + pub fn split_by< + R: CircuitRoundFunction + AlgebraicRoundFunction, + const AW: usize, + const CW: usize, + >( + mut self, + chunk_size: usize, + round_function: &R, + ) -> Vec { + let mut result = vec![]; + if self.num_items == 0 { + return result; + } else { + assert_eq!(self.witness.len(), self.num_items as usize); + } + + while self.num_items > 0 { + let mut subqueue = Self::empty(); + subqueue.head = self.head; + subqueue.tail = self.head; + for _ in 0..chunk_size { + if self.num_items == 0 { + break; + } + let (el, _) = self.pop_and_output_intermediate_data(round_function); + subqueue.push(el, round_function); + } + + result.push(subqueue); + } + + assert_eq!(self.tail, result.last().unwrap().tail); + + result + } +} + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Debug, Clone(bound = ""), Copy(bound = ""))] +#[serde(bound = "")] +pub struct FullWidthStackIntermediateStates { + pub is_push: bool, + #[serde(with = "crate::boojum::serde_utils::BigArraySerde")] + pub previous_state: [F; SW], + #[serde(with = "crate::boojum::serde_utils::BigArraySerde")] + pub new_state: [F; SW], + pub depth: u32, + #[serde(skip)] + #[serde(default = "empty_array_of_arrays::")] + pub round_function_execution_pairs: [([F; SW], [F; SW]); ROUNDS], +} + +fn empty_array_of_arrays( +) -> [([F; SW], [F; SW]); ROUNDS] { + [([F::ZERO; SW], [F::ZERO; SW]); ROUNDS] +} + +pub struct FullWidthStackSimulator< + F: SmallField, + I: OutOfCircuitFixedLengthEncodable, + const N: usize, + const SW: usize, + const ROUNDS: usize, +> { + pub state: [F; SW], + pub num_items: u32, + pub witness: Vec<([F; N], [F; SW], I)>, +} + +impl< + F: SmallField, + I: OutOfCircuitFixedLengthEncodable, + const N: usize, + const SW: usize, + const ROUNDS: usize, + > FullWidthStackSimulator +{ + pub fn empty() -> Self { + Self { + state: [F::ZERO; SW], + num_items: 0, + witness: vec![], + } + } + + pub fn push< + R: CircuitRoundFunction + AlgebraicRoundFunction, + const AW: usize, + const CW: usize, + >( + &mut self, + element: I, + round_function: &R, + ) { + let _ = self.push_and_output_intermediate_data(element, round_function); + } + + pub fn push_and_output_intermediate_data< + R: CircuitRoundFunction + AlgebraicRoundFunction, + const AW: usize, + const CW: usize, + >( + &mut self, + element: I, + _round_function: &R, + ) -> FullWidthStackIntermediateStates { + assert!(N % AW == 0); + let encoding = element.encoding_witness(); + + let old_state = self.state; + + let mut state = old_state; + let states = absorb_multiple_rounds::( + &mut state, &encoding, + ); + let new_state = state; + + let states = make_round_function_pairs(old_state, states); + + self.witness.push((encoding, self.state, element)); + self.num_items += 1; + self.state = new_state; + + let intermediate_info = FullWidthStackIntermediateStates { + is_push: true, + previous_state: old_state, + new_state, + depth: self.num_items, + round_function_execution_pairs: states, + }; + + intermediate_info + } + + pub fn pop_and_output_intermediate_data< + R: CircuitRoundFunction + AlgebraicRoundFunction, + const AW: usize, + const CW: usize, + >( + &mut self, + _round_function: &R, + ) -> (I, FullWidthStackIntermediateStates) { + assert!(N % AW == 0); + + let current_state = self.state; + + let popped = self.witness.pop().unwrap(); + self.num_items -= 1; + + let (_element_encoding, previous_state, element) = popped; + let encoding = element.encoding_witness(); + + let mut state = previous_state; + let states = absorb_multiple_rounds::( + &mut state, &encoding, + ); + let new_state = state; + assert_eq!(new_state, self.state); + + let states = make_round_function_pairs(previous_state, states); + + self.state = previous_state; + + let intermediate_info = FullWidthStackIntermediateStates { + is_push: false, + previous_state: current_state, + new_state: previous_state, + depth: self.num_items, + round_function_execution_pairs: states, + }; + + (element, intermediate_info) + } +} + +pub trait CircuitEquivalentReflection: Clone { + type Destination: Clone + CSAllocatable; + fn reflect(&self) -> >::Witness; +} + +pub trait BytesSerializable: Clone { + fn serialize(&self) -> [u8; N]; +} + +#[derive(Derivative)] +#[derivative(Clone, Copy, Debug, PartialEq, Eq)] +pub struct Key(pub [u32; N]); + +pub(crate) trait IntoSmallField: Sized { + fn into_field(self) -> F; +} + +impl IntoSmallField for bool { + #[inline(always)] + fn into_field(self) -> F { + F::from_u64_unchecked(self as u64) + } +} + +impl IntoSmallField for u8 { + #[inline(always)] + fn into_field(self) -> F { + F::from_u64_unchecked(self as u64) + } +} + +impl IntoSmallField for u16 { + #[inline(always)] + fn into_field(self) -> F { + F::from_u64_unchecked(self as u64) + } +} + +impl IntoSmallField for u32 { + #[inline(always)] + fn into_field(self) -> F { + F::from_u64_unchecked(self as u64) + } +} + +#[inline(always)] +pub(crate) fn scale_and_accumulate>( + dst: &mut F, + src: T, + shift: usize, +) { + let mut tmp = src.into_field(); + tmp.mul_assign(&F::SHIFTS[shift]); + dst.add_assign(&tmp); +} + +#[inline(always)] +pub(crate) fn linear_combination(input: &[(F, F)]) -> F { + let mut result = F::ZERO; + for (a, b) in input.iter() { + let mut tmp = *a; + tmp.mul_assign(&b); + result.add_assign(&tmp); + } + + result +} + +#[cfg(test)] +mod tests { + //use franklin_crypto::boojum::field::goldilocks::GoldilocksField; + use crate::boojum::field::goldilocks::GoldilocksField; + + use crate::ZkSyncDefaultRoundFunction; + + use super::{recursion_request::RecursionRequest, *}; + + fn create_recursion_request(x: u64) -> RecursionRequest { + RecursionRequest { + circuit_type: GoldilocksField::from_nonreduced_u64(x), + public_input: [GoldilocksField::from_nonreduced_u64(x); 4], + } + } + + /// Basic test to cover push, pop and split. + #[test] + fn basic_queue_test() { + let recursion_request = RecursionRequest { + circuit_type: GoldilocksField::from_nonreduced_u64(0), + public_input: [GoldilocksField::from_nonreduced_u64(0); 4], + }; + + let mut queue: FullWidthQueueSimulator< + GoldilocksField, + RecursionRequest, + 8, + 12, + 1, + > = FullWidthQueueSimulator::default(); + + let empty_head = queue.head; + assert_eq!(queue.num_items, 0); + + // First push 1 element, and then remaining 9. + let round_function = ZkSyncDefaultRoundFunction::default(); + queue.push(recursion_request, &round_function); + assert_eq!(queue.num_items, 1); + let tail_after_first = queue.tail; + + for i in 1..10 { + queue.push(create_recursion_request(i), &round_function) + } + assert_eq!(queue.num_items, 10); + + // pop one element + let (element, data) = queue.pop_and_output_intermediate_data(&round_function); + // it should return the first one that we entered (with circuit 0). + assert_eq!(element.circuit_type, 0); + + assert_eq!(queue.num_items, 9); + assert_eq!(data.num_items, 9); + + assert_eq!(data.head, tail_after_first); + assert_eq!(data.old_head, empty_head); + assert_eq!(data.old_tail, data.tail); + + let mut parts = queue.split_by(3, &round_function); + + assert_eq!(3, parts.len()); + // The queue was cut in 3 pieces, check that head and tails are matching. + assert_eq!(parts[0].head, tail_after_first); + assert_eq!(parts[0].tail, parts[1].head); + assert_eq!(parts[1].tail, parts[2].head); + assert_eq!(parts[2].tail, data.tail); + for i in 0..3 { + assert_eq!(parts[i].num_items, 3); + } + let (element, _) = parts[2].pop_and_output_intermediate_data(&round_function); + assert_eq!(element.circuit_type, 7); + } +} diff --git a/crates/circuit_encodings/src/log_query.rs b/crates/circuit_encodings/src/log_query.rs new file mode 100644 index 0000000..12e2a50 --- /dev/null +++ b/crates/circuit_encodings/src/log_query.rs @@ -0,0 +1,534 @@ +use zk_evm::aux_structures::LogQuery; +use zk_evm::aux_structures::Timestamp; +use zk_evm::ethereum_types::H160; +use zk_evm::ethereum_types::U256; + +// Proxy, as we just need read-only +pub trait LogQueryLike: 'static + Clone + Send + Sync + std::fmt::Debug { + fn shard_id(&self) -> u8; + fn address(&self) -> H160; + fn key(&self) -> U256; + fn rw_flag(&self) -> bool; + fn rollback(&self) -> bool; + fn read_value(&self) -> U256; + fn written_value(&self) -> U256; + fn create_partially_filled_from_fields( + shard_id: u8, + address: H160, + key: U256, + read_value: U256, + written_value: U256, + rw_flag: bool, + ) -> Self; +} + +impl LogQueryLike for LogQuery { + fn shard_id(&self) -> u8 { + self.shard_id + } + fn address(&self) -> H160 { + self.address + } + fn key(&self) -> U256 { + self.key + } + fn rw_flag(&self) -> bool { + self.rw_flag + } + fn rollback(&self) -> bool { + self.rollback + } + fn read_value(&self) -> U256 { + self.read_value + } + fn written_value(&self) -> U256 { + self.written_value + } + fn create_partially_filled_from_fields( + shard_id: u8, + address: H160, + key: U256, + read_value: U256, + written_value: U256, + rw_flag: bool, + ) -> Self { + // only smaller number of field matters in practice + LogQuery { + timestamp: Timestamp(0), + tx_number_in_block: 0, + aux_byte: 0, + shard_id, + address, + key, + read_value, + written_value, + rw_flag, + rollback: false, + is_service: false, + } + } +} + +#[derive(Clone, Debug)] +pub struct LogQueryLikeWithExtendedEnumeration { + pub raw_query: L, + pub extended_timestamp: u32, +} + +use super::*; + +use zkevm_circuits::storage_validity_by_grand_product::input::PACKED_KEY_LENGTH; + +pub fn comparison_key(query: &LogQuery) -> Key { + let key = decompose_u256_as_u32x8(query.key); + let address = decompose_address_as_u32x5(query.address); + + let le_words = [ + key[0], key[1], key[2], key[3], key[4], key[5], key[6], key[7], address[0], address[1], + address[2], address[3], address[4], + ]; + + Key(le_words) +} + +pub fn event_comparison_key(query: &LogQuery) -> Key<1> { + let le_words = [query.timestamp.0]; + + Key(le_words) +} + +use zkevm_circuits::base_structures::log_query::LOG_QUERY_PACKED_WIDTH; + +impl OutOfCircuitFixedLengthEncodable for LogQuery { + fn encoding_witness(&self) -> [F; LOG_QUERY_PACKED_WIDTH] { + debug_assert!(F::CAPACITY_BITS >= 56); + // we decompose "key" and mix it into other limbs because with high probability + // in VM decomposition of "key" will always exist beforehand + + let mut key_bytes = [0u8; 32]; + self.key.to_little_endian(&mut key_bytes); + let mut address_bytes = self.address.0; + address_bytes.reverse(); + + let read_value = decompose_u256_as_u32x8(self.read_value); + let written_value = decompose_u256_as_u32x8(self.written_value); + + // we want to pack tightly, so we "base" our packing on read and written values + + let v0 = linear_combination(&[ + (read_value[0].into_field(), F::ONE), + (key_bytes[0].into_field(), F::from_u64_unchecked(1u64 << 32)), + (key_bytes[1].into_field(), F::from_u64_unchecked(1u64 << 40)), + (key_bytes[2].into_field(), F::from_u64_unchecked(1u64 << 48)), + ]); + + let v1 = linear_combination(&[ + (read_value[1].into_field(), F::ONE), + (key_bytes[3].into_field(), F::from_u64_unchecked(1u64 << 32)), + (key_bytes[4].into_field(), F::from_u64_unchecked(1u64 << 40)), + (key_bytes[5].into_field(), F::from_u64_unchecked(1u64 << 48)), + ]); + + let v2 = linear_combination(&[ + (read_value[2].into_field(), F::ONE), + (key_bytes[6].into_field(), F::from_u64_unchecked(1u64 << 32)), + (key_bytes[7].into_field(), F::from_u64_unchecked(1u64 << 40)), + (key_bytes[8].into_field(), F::from_u64_unchecked(1u64 << 48)), + ]); + + let v3 = linear_combination(&[ + (read_value[3].into_field(), F::ONE), + (key_bytes[9].into_field(), F::from_u64_unchecked(1u64 << 32)), + ( + key_bytes[10].into_field(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + key_bytes[11].into_field(), + F::from_u64_unchecked(1u64 << 48), + ), + ]); + + let v4 = linear_combination(&[ + (read_value[4].into_field(), F::ONE), + ( + key_bytes[12].into_field(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + key_bytes[13].into_field(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + key_bytes[14].into_field(), + F::from_u64_unchecked(1u64 << 48), + ), + ]); + + let v5 = linear_combination(&[ + (read_value[5].into_field(), F::ONE), + ( + key_bytes[15].into_field(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + key_bytes[16].into_field(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + key_bytes[17].into_field(), + F::from_u64_unchecked(1u64 << 48), + ), + ]); + + let v6 = linear_combination(&[ + (read_value[6].into_field(), F::ONE), + ( + key_bytes[18].into_field(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + key_bytes[19].into_field(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + key_bytes[20].into_field(), + F::from_u64_unchecked(1u64 << 48), + ), + ]); + + let v7 = linear_combination(&[ + (read_value[7].into_field(), F::ONE), + ( + key_bytes[21].into_field(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + key_bytes[22].into_field(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + key_bytes[23].into_field(), + F::from_u64_unchecked(1u64 << 48), + ), + ]); + + // continue with written value + + let v8 = linear_combination(&[ + (written_value[0].into_field(), F::ONE), + ( + key_bytes[24].into_field(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + key_bytes[25].into_field(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + key_bytes[26].into_field(), + F::from_u64_unchecked(1u64 << 48), + ), + ]); + + let v9 = linear_combination(&[ + (written_value[1].into_field(), F::ONE), + ( + key_bytes[27].into_field(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + key_bytes[28].into_field(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + key_bytes[29].into_field(), + F::from_u64_unchecked(1u64 << 48), + ), + ]); + + // continue mixing bytes, now from "address" + + let v10 = linear_combination(&[ + (written_value[2].into_field(), F::ONE), + ( + key_bytes[30].into_field(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + key_bytes[31].into_field(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + address_bytes[0].into_field(), + F::from_u64_unchecked(1u64 << 48), + ), + ]); + + let v11 = linear_combination(&[ + (written_value[3].into_field(), F::ONE), + ( + address_bytes[1].into_field(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + address_bytes[2].into_field(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + address_bytes[3].into_field(), + F::from_u64_unchecked(1u64 << 48), + ), + ]); + + let v12 = linear_combination(&[ + (written_value[4].into_field(), F::ONE), + ( + address_bytes[4].into_field(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + address_bytes[5].into_field(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + address_bytes[6].into_field(), + F::from_u64_unchecked(1u64 << 48), + ), + ]); + + let v13 = linear_combination(&[ + (written_value[5].into_field(), F::ONE), + ( + address_bytes[7].into_field(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + address_bytes[8].into_field(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + address_bytes[9].into_field(), + F::from_u64_unchecked(1u64 << 48), + ), + ]); + + let v14 = linear_combination(&[ + (written_value[6].into_field(), F::ONE), + ( + address_bytes[10].into_field(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + address_bytes[11].into_field(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + address_bytes[12].into_field(), + F::from_u64_unchecked(1u64 << 48), + ), + ]); + + let v15 = linear_combination(&[ + (written_value[7].into_field(), F::ONE), + ( + address_bytes[13].into_field(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + address_bytes[14].into_field(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + address_bytes[15].into_field(), + F::from_u64_unchecked(1u64 << 48), + ), + ]); + + // now we can pack using some other "large" items as base + + let v16 = linear_combination(&[ + (self.timestamp.0.into_field(), F::ONE), + ( + address_bytes[16].into_field(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + address_bytes[17].into_field(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + address_bytes[18].into_field(), + F::from_u64_unchecked(1u64 << 48), + ), + ]); + + let v17 = linear_combination(&[ + (self.tx_number_in_block.into_field(), F::ONE), // NOTE: u16 out of circuit and u32 in circuit + ( + address_bytes[19].into_field(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + self.aux_byte.into_field(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + self.shard_id.into_field(), + F::from_u64_unchecked(1u64 << 48), + ), + ]); + + let v18 = linear_combination(&[ + (self.rw_flag.into_field(), F::ONE), + (self.is_service.into_field(), F::TWO), + ]); + + // and the final into_field() is just rollback flag itself + + let v19 = self.rollback.into_field(); + + [ + v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, + v19, + ] + } +} + +pub type LogQueryWithExtendedEnumeration = LogQueryLikeWithExtendedEnumeration; + +impl OutOfCircuitFixedLengthEncodable + for LogQueryWithExtendedEnumeration +{ + fn encoding_witness(&self) -> [F; LOG_QUERY_PACKED_WIDTH] { + let LogQueryWithExtendedEnumeration { + raw_query, + extended_timestamp, + } = self; + + let mut result = >::encoding_witness(raw_query); + use zkevm_circuits::storage_validity_by_grand_product::EXTENDED_TIMESTAMP_ENCODING_OFFSET; + + let mut shift = EXTENDED_TIMESTAMP_ENCODING_OFFSET; + use zkevm_circuits::storage_validity_by_grand_product::EXTENDED_TIMESTAMP_ENCODING_ELEMENT; + scale_and_accumulate::( + &mut result[EXTENDED_TIMESTAMP_ENCODING_ELEMENT], + *extended_timestamp, + shift, + ); + shift += 32; + assert!(shift <= F::CAPACITY_BITS as usize); + + result + } +} + +use zkevm_circuits::base_structures::log_query::LOG_QUERY_ABSORBTION_ROUNDS; + +pub type LogQueueSimulator = QueueSimulator< + F, + LogQuery, + QUEUE_STATE_WIDTH, + LOG_QUERY_PACKED_WIDTH, + LOG_QUERY_ABSORBTION_ROUNDS, +>; +pub type LogQueueState = QueueIntermediateStates< + F, + QUEUE_STATE_WIDTH, + FULL_SPONGE_QUEUE_STATE_WIDTH, + LOG_QUERY_ABSORBTION_ROUNDS, +>; + +pub type LogWithExtendedEnumerationQueueSimulator = QueueSimulator< + F, + LogQueryWithExtendedEnumeration, + QUEUE_STATE_WIDTH, + LOG_QUERY_PACKED_WIDTH, + LOG_QUERY_ABSORBTION_ROUNDS, +>; +// pub type LogQueueState = QueueIntermediateStates; + +pub fn log_query_into_circuit_log_query_witness( + query: &LogQuery, +) -> as CSAllocatable>::Witness { + use zkevm_circuits::base_structures::log_query::LogQueryWitness; + + LogQueryWitness { + address: query.address, + key: query.key, + read_value: query.read_value, + written_value: query.written_value, + rw_flag: query.rw_flag, + aux_byte: query.aux_byte, + rollback: query.rollback, + is_service: query.is_service, + shard_id: query.shard_id, + tx_number_in_block: query.tx_number_in_block as u32, + timestamp: query.timestamp.0, + } +} + +impl CircuitEquivalentReflection for LogQuery { + type Destination = zkevm_circuits::base_structures::log_query::LogQuery; + fn reflect(&self) -> >::Witness { + log_query_into_circuit_log_query_witness(self) + } +} + +pub fn log_query_into_timestamped_storage_record_witness( + query: &LogQueryWithExtendedEnumeration +) -> as CSAllocatable>::Witness{ + use zkevm_circuits::storage_validity_by_grand_product::TimestampedStorageLogRecordWitness; + + TimestampedStorageLogRecordWitness { + record: log_query_into_circuit_log_query_witness(&query.raw_query), + timestamp: query.extended_timestamp, + } +} + +impl CircuitEquivalentReflection for LogQueryWithExtendedEnumeration { + type Destination = + zkevm_circuits::storage_validity_by_grand_product::TimestampedStorageLogRecord; + fn reflect(&self) -> >::Witness { + log_query_into_timestamped_storage_record_witness(self) + } +} + +use zkevm_circuits::base_structures::log_query::L2_TO_L1_MESSAGE_BYTE_LENGTH; + +// for purposes of L1 messages +impl BytesSerializable for LogQuery { + fn serialize(&self) -> [u8; L2_TO_L1_MESSAGE_BYTE_LENGTH] { + let mut result = [0u8; L2_TO_L1_MESSAGE_BYTE_LENGTH]; + let mut offset = 0; + result[offset] = self.shard_id; + offset += 1; + result[offset] = self.is_service as u8; + offset += 1; + + let bytes_be = self.tx_number_in_block.to_be_bytes(); + result[offset..(offset + bytes_be.len())].copy_from_slice(&bytes_be); + offset += bytes_be.len(); + + let bytes_be = self.address.to_fixed_bytes(); + result[offset..(offset + bytes_be.len())].copy_from_slice(&bytes_be); + offset += bytes_be.len(); + + let mut bytes_be = [0u8; 32]; + self.key.to_big_endian(&mut bytes_be); + result[offset..(offset + bytes_be.len())].copy_from_slice(&bytes_be); + offset += bytes_be.len(); + + let mut bytes_be = [0u8; 32]; + self.written_value.to_big_endian(&mut bytes_be); + result[offset..(offset + bytes_be.len())].copy_from_slice(&bytes_be); + offset += bytes_be.len(); + + assert_eq!(offset, L2_TO_L1_MESSAGE_BYTE_LENGTH); + + result + } +} diff --git a/crates/circuit_encodings/src/memory_query.rs b/crates/circuit_encodings/src/memory_query.rs new file mode 100644 index 0000000..7db7e63 --- /dev/null +++ b/crates/circuit_encodings/src/memory_query.rs @@ -0,0 +1,144 @@ +use super::*; +use zk_evm::aux_structures::MemoryQuery; + +use zkevm_circuits::ram_permutation::input::{RAM_FULL_KEY_LENGTH, RAM_SORTING_KEY_LENGTH}; + +pub fn sorting_key(query: &MemoryQuery) -> Key { + let le_words = [ + query.timestamp.0, + query.location.index.0, + query.location.page.0, + ]; + + Key(le_words) +} + +pub fn comparison_key(query: &MemoryQuery) -> Key { + let le_words = [query.location.index.0, query.location.page.0]; + + Key(le_words) +} + +use zkevm_circuits::base_structures::memory_query::MEMORY_QUERY_PACKED_WIDTH; + +impl OutOfCircuitFixedLengthEncodable for MemoryQuery { + fn encoding_witness(&self) -> [F; MEMORY_QUERY_PACKED_WIDTH] { + // we assume the fact that capacity of F is quite close to 64 bits + debug_assert!(F::CAPACITY_BITS >= 56); + + let value = decompose_u256_as_u32x8(self.value); + + // strategy: we use 3 field elements to pack timestamp, decomposition of page, index and r/w flag, + // and 5 more elements to tightly pack 8xu32 of values + + let v0 = self.timestamp.0.into_field(); + let v1 = self.location.page.0.into_field(); + let v2 = linear_combination(&[ + (self.location.index.0.into_field(), F::ONE), + (self.rw_flag.into_field(), F::from_u64_unchecked(1u64 << 32)), + ( + self.value_is_pointer.into_field(), + F::from_u64_unchecked(1u64 << 33), + ), + ]); + + // value. Those in most of the cases will be nops + let decomposition_5 = value[5].to_le_bytes(); + let decomposition_6 = value[6].to_le_bytes(); + let decomposition_7 = value[7].to_le_bytes(); + + let v3 = linear_combination(&[ + (value[0].into_field(), F::ONE), + ( + decomposition_5[0].into_field(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + decomposition_5[1].into_field(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + decomposition_5[2].into_field(), + F::from_u64_unchecked(1u64 << 48), + ), + ]); + + let v4 = linear_combination(&[ + (value[1].into_field(), F::ONE), + ( + decomposition_5[3].into_field(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + decomposition_6[0].into_field(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + decomposition_6[1].into_field(), + F::from_u64_unchecked(1u64 << 48), + ), + ]); + + let v5 = linear_combination(&[ + (value[2].into_field(), F::ONE), + ( + decomposition_6[2].into_field(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + decomposition_6[3].into_field(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + decomposition_7[0].into_field(), + F::from_u64_unchecked(1u64 << 48), + ), + ]); + + let v6 = linear_combination(&[ + (value[3].into_field(), F::ONE), + ( + decomposition_7[1].into_field(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + decomposition_7[2].into_field(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + decomposition_7[3].into_field(), + F::from_u64_unchecked(1u64 << 48), + ), + ]); + + let v7 = value[4].into_field(); + + [v0, v1, v2, v3, v4, v5, v6, v7] + } +} + +pub type MemoryQueueSimulator = FullWidthQueueSimulator< + F, + MemoryQuery, + MEMORY_QUERY_PACKED_WIDTH, + FULL_SPONGE_QUEUE_STATE_WIDTH, + 1, +>; +pub type MemoryQueueState = + FullWidthQueueIntermediateStates; + +impl CircuitEquivalentReflection for MemoryQuery { + type Destination = zkevm_circuits::base_structures::memory_query::MemoryQuery; + fn reflect(&self) -> >::Witness { + use zkevm_circuits::base_structures::memory_query::MemoryQueryWitness; + + MemoryQueryWitness { + timestamp: self.timestamp.0, + memory_page: self.location.page.0, + index: self.location.index.0, + rw_flag: self.rw_flag, + value: self.value, + is_ptr: self.value_is_pointer, + } + } +} diff --git a/crates/circuit_encodings/src/recursion_request.rs b/crates/circuit_encodings/src/recursion_request.rs new file mode 100644 index 0000000..ae4614d --- /dev/null +++ b/crates/circuit_encodings/src/recursion_request.rs @@ -0,0 +1,48 @@ +use super::*; +use zkevm_circuits::base_structures::recursion_query::*; +use zkevm_circuits::fsm_input_output::circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH; + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Copy, Debug)] +#[serde(bound = "")] +pub struct RecursionRequest { + pub circuit_type: F, + pub public_input: [F; INPUT_OUTPUT_COMMITMENT_LENGTH], +} + +impl OutOfCircuitFixedLengthEncodable + for RecursionRequest +{ + fn encoding_witness(&self) -> [F; RECURSION_QUERY_PACKED_WIDTH] { + [ + self.circuit_type, + self.public_input[0], + self.public_input[1], + self.public_input[2], + self.public_input[3], + F::ZERO, + F::ZERO, + F::ZERO, + ] + } +} + +impl CircuitEquivalentReflection for RecursionRequest { + type Destination = zkevm_circuits::base_structures::recursion_query::RecursionQuery; + fn reflect(&self) -> >::Witness { + zkevm_circuits::base_structures::recursion_query::RecursionQueryWitness { + circuit_type: self.circuit_type, + input_commitment: self.public_input, + } + } +} + +pub type RecursionQueueSimulator = FullWidthQueueSimulator< + F, + RecursionRequest, + RECURSION_QUERY_PACKED_WIDTH, + FULL_SPONGE_QUEUE_STATE_WIDTH, + 1, +>; +pub type RecursionQueueState = + FullWidthQueueIntermediateStates; diff --git a/crates/circuit_encodings/src/state_diff_record.rs b/crates/circuit_encodings/src/state_diff_record.rs new file mode 100644 index 0000000..9f9dec3 --- /dev/null +++ b/crates/circuit_encodings/src/state_diff_record.rs @@ -0,0 +1,54 @@ +use zk_evm::ethereum_types::Address; + +use super::*; +use crate::ethereum_types::U256; + +#[derive(Derivative)] +#[derivative(Clone, Copy, Debug, Hash)] +pub struct StateDiffRecord { + pub address: Address, + pub key: U256, + pub derived_key: [u8; 32], + pub enumeration_index: u64, + pub initial_value: U256, + pub final_value: U256, +} + +use zkevm_circuits::base_structures::state_diff_record::STATE_DIFF_RECORD_BYTE_ENCODING_LEN; + +impl StateDiffRecord { + // the only thing we need is byte encoding + pub fn encode(&self) -> [u8; STATE_DIFF_RECORD_BYTE_ENCODING_LEN] { + let mut encoding = [0u8; STATE_DIFF_RECORD_BYTE_ENCODING_LEN]; + let mut offset = 0; + let mut end = 0; + + end += 20; + encoding[offset..end].copy_from_slice(self.address.as_fixed_bytes()); + offset = end; + + end += 32; + self.key.to_big_endian(&mut encoding[offset..end]); + offset = end; + + end += 32; + encoding[offset..end].copy_from_slice(&self.derived_key); + offset = end; + + end += 8; + encoding[offset..end].copy_from_slice(&self.enumeration_index.to_be_bytes()); + offset = end; + + end += 32; + self.initial_value.to_big_endian(&mut encoding[offset..end]); + offset = end; + + end += 32; + self.final_value.to_big_endian(&mut encoding[offset..end]); + offset = end; + + debug_assert_eq!(offset, encoding.len()); + + encoding + } +} diff --git a/crates/circuit_sequencer_api/Cargo.toml b/crates/circuit_sequencer_api/Cargo.toml index 3a8b4e1..4618212 100644 --- a/crates/circuit_sequencer_api/Cargo.toml +++ b/crates/circuit_sequencer_api/Cargo.toml @@ -1,21 +1,23 @@ [package] name = "circuit_sequencer_api" -version = "0.133.0" +version = "0.140.1" edition = "2021" authors = ["The Matter Labs Team "] homepage = "https://zksync.io/" -repository = "https://github.com/matter-labs/era-zkevm_circuits" +repository = "https://github.com/matter-labs/era-zkevm_test_harness/" license = "MIT OR Apache-2.0" keywords = ["blockchain", "zksync"] categories = ["cryptography"] -description = "ZKsync Era circuits for EraVM" +description = "ZKsync Era circuits API for sequencer" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +circuit_encodings = { version = "0.140", path = "../circuit_encodings" } # Not pinned, because it's an old version used only by MultiVM + +zk_evm = { version = "0.140", path = "../zk_evm" } # Not pinned, because it's an old version used only by MultiVM +bellman = { package = "bellman_ce", version = "0" } # Not pinned, because it's an old version used only by MultiVM -zk_evm = { version = "=0.133.0", path = "../zk_evm" } -bellman = { package = "bellman_ce", version = "=0.7.0" } derivative = "2.2" serde = {version = "1", features = ["derive"]} diff --git a/crates/circuit_sequencer_api/src/commitments.rs b/crates/circuit_sequencer_api/src/commitments.rs new file mode 100644 index 0000000..4ca135b --- /dev/null +++ b/crates/circuit_sequencer_api/src/commitments.rs @@ -0,0 +1,74 @@ +use crate::{ + boojum::{ + algebraic_props::round_function::AlgebraicRoundFunction, field::SmallField, + gadgets::traits::round_function::*, + }, + utils::{calldata_to_aligned_data, finalize_queue_state, finalized_queue_state_as_bytes}, +}; +use circuit_encodings::{boojum::field::goldilocks::GoldilocksField, *}; +use zk_evm::aux_structures::LogQuery; + +pub fn initial_heap_content_commitment< + F: SmallField, + R: BuildableCircuitRoundFunction + AlgebraicRoundFunction, +>( + bootloader_heap_data: &Vec, + round_function: &R, +) -> [u8; 32] { + let heap_writes = calldata_to_aligned_data(bootloader_heap_data); + + use circuit_encodings::memory_query::MemoryQueueSimulator; + use zk_evm::abstractions::*; + use zk_evm::aux_structures::*; + + let mut memory_queue = MemoryQueueSimulator::empty(); + + for (idx, el) in heap_writes.into_iter().enumerate() { + let query = MemoryQuery { + timestamp: Timestamp(0), + location: MemoryLocation { + memory_type: MemoryType::Heap, + page: MemoryPage(zk_evm::zkevm_opcode_defs::BOOTLOADER_HEAP_PAGE), + index: MemoryIndex(idx as u32), + }, + rw_flag: true, + value: el, + value_is_pointer: false, + }; + memory_queue.push(query, round_function); + } + + let finalized_state = finalize_queue_state(memory_queue.tail, round_function); + finalized_queue_state_as_bytes(finalized_state) +} + +pub fn initial_heap_content_commitment_fixed(bootloader_heap_data: &Vec) -> [u8; 32] { + initial_heap_content_commitment::( + bootloader_heap_data, + &ZkSyncDefaultRoundFunction::default(), + ) +} + +pub fn events_queue_commitment< + F: SmallField, + R: BuildableCircuitRoundFunction + AlgebraicRoundFunction, +>( + sorted_and_deduplicated_events: &Vec, + round_function: &R, +) -> [u8; 32] { + let mut queue = LogQueueSimulator::empty(); + + for el in sorted_and_deduplicated_events.iter() { + queue.push(*el, round_function); + } + + let finalized_state = finalize_queue_state(queue.tail, round_function); + finalized_queue_state_as_bytes(finalized_state) +} + +pub fn events_queue_commitment_fixed(sorted_and_deduplicated_events: &Vec) -> [u8; 32] { + events_queue_commitment::( + sorted_and_deduplicated_events, + &ZkSyncDefaultRoundFunction::default(), + ) +} diff --git a/crates/circuit_sequencer_api/src/geometry_config.rs b/crates/circuit_sequencer_api/src/geometry_config.rs new file mode 100644 index 0000000..b1096d7 --- /dev/null +++ b/crates/circuit_sequencer_api/src/geometry_config.rs @@ -0,0 +1,20 @@ +// This file is auto-generated, do not edit it manually + +use crate::toolset::GeometryConfig; + +pub const fn get_geometry_config() -> GeometryConfig { + GeometryConfig { + cycles_per_vm_snapshot: 5692, + cycles_code_decommitter_sorter: 117500, + cycles_per_log_demuxer: 58750, + cycles_per_storage_sorter: 46921, + cycles_per_events_or_l1_messages_sorter: 31287, + cycles_per_ram_permutation: 136714, + cycles_per_code_decommitter: 2845, + cycles_per_storage_application: 33, + cycles_per_keccak256_circuit: 672, + cycles_per_sha256_circuit: 2206, + cycles_per_ecrecover_circuit: 2, + limit_for_l1_messages_pudata_hasher: 774, + } +} diff --git a/crates/circuit_sequencer_api/src/lib.rs b/crates/circuit_sequencer_api/src/lib.rs index 1f4fee4..e12ff3b 100644 --- a/crates/circuit_sequencer_api/src/lib.rs +++ b/crates/circuit_sequencer_api/src/lib.rs @@ -1,4 +1,13 @@ +#![feature(array_chunks)] + +pub mod geometry_config; pub mod proof; pub mod sort_storage_access; +pub mod toolset; + +pub mod commitments; +pub mod utils; + +pub use circuit_encodings::boojum; pub const INITIAL_MONOTONIC_CYCLE_COUNTER: u32 = 1024; diff --git a/crates/circuit_sequencer_api/src/proof.rs b/crates/circuit_sequencer_api/src/proof.rs index 3cceffb..79431a5 100644 --- a/crates/circuit_sequencer_api/src/proof.rs +++ b/crates/circuit_sequencer_api/src/proof.rs @@ -8,6 +8,8 @@ use bellman::{ // Wrapper for the final scheduler proof. // We use generic circuit here, as this is used only for serializing & deserializing in sequencer. +// The exact circuti type does not change the rules of (de)serialization, so we use a very lightweight +// circuit in places that only pass proofs around to avoid unnecessary heavy compilation in most places. pub type FinalProof = Proof; #[derive(Clone)] diff --git a/crates/circuit_sequencer_api/src/sort_storage_access.rs b/crates/circuit_sequencer_api/src/sort_storage_access.rs index f02232e..fece565 100644 --- a/crates/circuit_sequencer_api/src/sort_storage_access.rs +++ b/crates/circuit_sequencer_api/src/sort_storage_access.rs @@ -2,10 +2,10 @@ use derivative::Derivative; use rayon::prelude::*; use std::cmp::Ordering; use std::iter::IntoIterator; -use zk_evm::{ - aux_structures::{LogQuery, Timestamp}, - ethereum_types::{H160, U256}, -}; +use zk_evm::ethereum_types::U256; + +use circuit_encodings::LogQueryLike; +use circuit_encodings::LogQueryLikeWithExtendedEnumeration; #[derive(Derivative)] #[derivative(Default(bound = ""), Debug)] @@ -16,78 +16,6 @@ pub struct StorageSlotHistoryKeeper { pub did_read_at_depth_zero: bool, } -// Proxy, as we just need read-only -pub trait LogQueryLike: 'static + Clone + Send + Sync + std::fmt::Debug { - fn shard_id(&self) -> u8; - fn address(&self) -> H160; - fn key(&self) -> U256; - fn rw_flag(&self) -> bool; - fn rollback(&self) -> bool; - fn read_value(&self) -> U256; - fn written_value(&self) -> U256; - fn create_partially_filled_from_fields( - shard_id: u8, - address: H160, - key: U256, - read_value: U256, - written_value: U256, - rw_flag: bool, - ) -> Self; -} - -impl LogQueryLike for LogQuery { - fn shard_id(&self) -> u8 { - self.shard_id - } - fn address(&self) -> H160 { - self.address - } - fn key(&self) -> U256 { - self.key - } - fn rw_flag(&self) -> bool { - self.rw_flag - } - fn rollback(&self) -> bool { - self.rollback - } - fn read_value(&self) -> U256 { - self.read_value - } - fn written_value(&self) -> U256 { - self.written_value - } - fn create_partially_filled_from_fields( - shard_id: u8, - address: H160, - key: U256, - read_value: U256, - written_value: U256, - rw_flag: bool, - ) -> Self { - // only smaller number of field matters in practice - LogQuery { - timestamp: Timestamp(0), - tx_number_in_block: 0, - aux_byte: 0, - shard_id, - address, - key, - read_value, - written_value, - rw_flag, - rollback: false, - is_service: false, - } - } -} - -#[derive(Clone, Debug)] -pub struct LogQueryLikeWithExtendedEnumeration { - pub raw_query: L, - pub extended_timestamp: u32, -} - pub fn sort_storage_access_queries<'a, L: LogQueryLike, I: IntoIterator>( unsorted_storage_queries: I, ) -> (Vec>, Vec) { @@ -125,7 +53,9 @@ pub fn sort_storage_access_queries<'a, L: LogQueryLike, I: IntoIterator) -> Vec { + if calldata.len() == 0 { + return vec![]; + } + let mut capacity = calldata.len() / 32; + if calldata.len() % 32 != 0 { + capacity += 1; + } + let mut result = Vec::with_capacity(capacity); + let mut it = calldata.chunks_exact(32); + for el in &mut it { + let el = U256::from_big_endian(el); + result.push(el); + } + let remainder = it.remainder(); + if remainder.len() != 0 { + let mut buffer = [0u8; 32]; + buffer[0..remainder.len()].copy_from_slice(remainder); + let el = U256::from_big_endian(&buffer); + result.push(el); + } + + result +} + +pub fn finalize_queue_state< + F: SmallField, + R: BuildableCircuitRoundFunction + AlgebraicRoundFunction, + const N: usize, +>( + tail: [F; N], + _round_function: &R, +) -> [F; QUEUE_FINAL_STATE_COMMITMENT_LENGTH] { + // rescue prime paddings + let mut to_absorb = vec![]; + to_absorb.extend(tail); + to_absorb.push(F::ONE); + + let mut state = R::initial_state(); + use crate::boojum::algebraic_props::round_function::absorb_into_state_vararg; + absorb_into_state_vararg::(&mut state, &to_absorb); + let commitment = >::state_into_commitment::< + QUEUE_FINAL_STATE_COMMITMENT_LENGTH, + >(&state); + + commitment +} + +pub fn finalized_queue_state_as_bytes( + input: [F; QUEUE_FINAL_STATE_COMMITMENT_LENGTH], +) -> [u8; 32] { + let mut result = [0u8; 32]; + for (dst, src) in result.array_chunks_mut::<8>().zip(input.into_iter()) { + *dst = src.as_u64_reduced().to_be_bytes(); + } + + result +} diff --git a/crates/zk_evm/.github/workflows/ci.yaml b/crates/zk_evm/.github/workflows/ci.yaml index bd002d8..8b2b519 100644 --- a/crates/zk_evm/.github/workflows/ci.yaml +++ b/crates/zk_evm/.github/workflows/ci.yaml @@ -10,7 +10,7 @@ jobs: - uses: actions/checkout@v3 - uses: actions-rust-lang/setup-rust-toolchain@v1 with: - toolchain: stable + toolchain: nightly-2023-04-17 - run: cargo build --verbose --all-features - run: RUSTFLAGS="-Awarnings" cargo test --verbose --all-features diff --git a/crates/zk_evm/Cargo.toml b/crates/zk_evm/Cargo.toml index dbfbd54..ee2bf35 100644 --- a/crates/zk_evm/Cargo.toml +++ b/crates/zk_evm/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zk_evm" -version = "0.133.0" +version = "0.140.0" edition = "2021" authors = ["The Matter Labs Team "] homepage = "https://zksync.io/" diff --git a/crates/zk_evm/src/lib.rs b/crates/zk_evm/src/lib.rs index 80aaa84..407c583 100644 --- a/crates/zk_evm/src/lib.rs +++ b/crates/zk_evm/src/lib.rs @@ -1,5 +1,3 @@ -#![allow(dropping_references)] - pub mod block_properties; pub mod errors; pub mod flags; @@ -17,9 +15,9 @@ pub use zkevm_opcode_defs::{bitflags, ethereum_types}; use self::ethereum_types::{Address, U256}; -pub use zk_evm_abstractions; pub use zkevm_opcode_defs; +pub use zk_evm_abstractions; pub use zkevm_opcode_defs::blake2; pub use zkevm_opcode_defs::k256; pub use zkevm_opcode_defs::sha2; @@ -33,7 +31,3 @@ pub mod aux_structures { pub use zk_evm_abstractions::aux::*; pub use zk_evm_abstractions::queries::*; } - -pub mod precompiles { - pub use zk_evm_abstractions::precompiles::*; -} diff --git a/crates/zk_evm/src/opcodes/execution/add.rs b/crates/zk_evm/src/opcodes/execution/add.rs index 297c1a7..d53ca88 100644 --- a/crates/zk_evm/src/opcodes/execution/add.rs +++ b/crates/zk_evm/src/opcodes/execution/add.rs @@ -30,6 +30,7 @@ impl> DecodedOpcode { is_pointer: _, } = src1; + use zkevm_opcode_defs::SET_FLAGS_FLAG_IDX; let set_flags = self.variant.flags[SET_FLAGS_FLAG_IDX]; vm_state.local_state.callstack.get_current_stack_mut().pc = new_pc; let (result, of) = src0.overflowing_add(src1); diff --git a/crates/zk_evm/src/opcodes/execution/binop.rs b/crates/zk_evm/src/opcodes/execution/binop.rs index 9b834a3..e31a421 100644 --- a/crates/zk_evm/src/opcodes/execution/binop.rs +++ b/crates/zk_evm/src/opcodes/execution/binop.rs @@ -35,6 +35,8 @@ impl> DecodedOpcode { Opcode::Binop(inner) => inner, _ => unreachable!(), }; + + use zkevm_opcode_defs::SET_FLAGS_FLAG_IDX; let set_flags = self.variant.flags[SET_FLAGS_FLAG_IDX]; vm_state.local_state.callstack.get_current_stack_mut().pc = new_pc; // it is always XOR unless flags are set diff --git a/crates/zk_evm/src/opcodes/execution/div.rs b/crates/zk_evm/src/opcodes/execution/div.rs index be5ff04..f09d9b9 100644 --- a/crates/zk_evm/src/opcodes/execution/div.rs +++ b/crates/zk_evm/src/opcodes/execution/div.rs @@ -29,6 +29,8 @@ impl> DecodedOpcode { value: src1, is_pointer: _, } = src1; + + use zkevm_opcode_defs::SET_FLAGS_FLAG_IDX; let set_flags = self.variant.flags[SET_FLAGS_FLAG_IDX]; vm_state.local_state.callstack.get_current_stack_mut().pc = new_pc; if src1.is_zero() { diff --git a/crates/zk_evm/src/opcodes/execution/far_call.rs b/crates/zk_evm/src/opcodes/execution/far_call.rs index d41c8f5..412f910 100644 --- a/crates/zk_evm/src/opcodes/execution/far_call.rs +++ b/crates/zk_evm/src/opcodes/execution/far_call.rs @@ -1,9 +1,7 @@ use super::*; -use zk_evm_abstractions::aux::MemoryPage; -use zk_evm_abstractions::aux::Timestamp; +use zk_evm_abstractions::aux::*; use zk_evm_abstractions::queries::LogQuery; -use zk_evm_abstractions::vm::SpongeExecutionMarker; use zkevm_opcode_defs::definitions::far_call::*; use zkevm_opcode_defs::system_params::DEPLOYER_SYSTEM_CONTRACT_ADDRESS; use zkevm_opcode_defs::system_params::STORAGE_AUX_BYTE; @@ -22,7 +20,7 @@ bitflags! { const NOT_ENOUGH_ERGS_TO_GROW_MEMORY = 1u64 << 3; const MALFORMED_ABI_QUASI_POINTER = 1u64 << 4; const CALL_IN_NOW_CONSTRUCTED_SYSTEM_CONTRACT = 1u64 << 5; - const NOTE_ENOUGH_ERGS_FOR_EXTRA_FAR_CALL_COSTS = 1u64 << 6; + const NOT_ENOUGH_ERGS_FOR_EXTRA_FAR_CALL_COSTS = 1u64 << 6; } } @@ -146,12 +144,6 @@ impl> DecodedOpcode { let query = vm_state .access_storage(vm_state.local_state.monotonic_cycle_counter, partial_query); - vm_state.witness_tracer.add_sponge_marker( - vm_state.local_state.monotonic_cycle_counter, - SpongeExecutionMarker::StorageLogReadOnly, - 1..4, - true, - ); let code_hash_from_storage = query.read_value; // mask for default AA @@ -321,6 +313,11 @@ impl> DecodedOpcode { } }; + // we mask out fat pointer based on: + // - invalid code hash format + // - call yet constructed kernel + // - not fat pointer when expected + // - invalid slice structure in ABI if exceptions.is_empty() == false { far_call_abi.memory_quasi_fat_pointer = FatPointer::empty(); // even though we will not pay for memory resize, @@ -412,7 +409,7 @@ impl> DecodedOpcode { remaining_ergs_after_growth - msg_value_stipend } else { exceptions.set( - FarCallExceptionFlags::NOTE_ENOUGH_ERGS_FOR_EXTRA_FAR_CALL_COSTS, + FarCallExceptionFlags::NOT_ENOUGH_ERGS_FOR_EXTRA_FAR_CALL_COSTS, true, ); // if tried to take and failed, but should not add it later on in this case @@ -448,12 +445,6 @@ impl> DecodedOpcode { memory_page_candidate_for_code_decommittment, timestamp_for_decommit, )?; - vm_state.witness_tracer.add_sponge_marker( - vm_state.local_state.monotonic_cycle_counter, - SpongeExecutionMarker::DecommittmentQuery, - 4..5, - true, - ); if processed_decommittment_query.is_fresh == false { // refund @@ -508,8 +499,6 @@ impl> DecodedOpcode { let new_context_is_static = current_stack.is_static | is_static_call; // no matter if we did execute a query or not, we need to save context at worst - vm_state.local_state.pending_port.pending_type = Some(PendingType::FarCall); - vm_state.increment_memory_pages_on_call(); // read address for mimic_call @@ -578,15 +567,6 @@ impl> DecodedOpcode { Timestamp(vm_state.local_state.timestamp), ); - vm_state.witness_tracer.add_sponge_marker( - vm_state.local_state.monotonic_cycle_counter, - SpongeExecutionMarker::CallstackPush, - 5..8, - true, - ); - // mark the jump to refresh the memory word - vm_state.local_state.did_call_or_ret_recently = true; - // write down calldata information let r1_value = PrimitiveValue { diff --git a/crates/zk_evm/src/opcodes/execution/log.rs b/crates/zk_evm/src/opcodes/execution/log.rs index 5913d4b..d99ca78 100644 --- a/crates/zk_evm/src/opcodes/execution/log.rs +++ b/crates/zk_evm/src/opcodes/execution/log.rs @@ -1,8 +1,6 @@ use super::*; -use zk_evm_abstractions::aux::Timestamp; use zk_evm_abstractions::queries::LogQuery; -use zk_evm_abstractions::vm::SpongeExecutionMarker; use zkevm_opcode_defs::{ LogOpcode, Opcode, PrecompileCallABI, PrecompileCallInnerABI, FIRST_MESSAGE_FLAG_IDX, }; @@ -68,6 +66,7 @@ impl> DecodedOpcode { .get_current_stack() .ergs_remaining; let is_rollup = shard_id == 0; + let timestamp_for_log = vm_state.timestamp_for_first_decommit_or_precompile_read(); let tx_number_in_block = vm_state.local_state.tx_number_in_block; @@ -86,7 +85,7 @@ impl> DecodedOpcode { let partial_query = LogQuery { timestamp: timestamp_for_log, - tx_number_in_block, + tx_number_in_block: tx_number_in_block, aux_byte: STORAGE_AUX_BYTE, shard_id, address, @@ -180,12 +179,6 @@ impl> DecodedOpcode { // we do not expect refunds for reads yet let query = vm_state .access_storage(vm_state.local_state.monotonic_cycle_counter, partial_query); - vm_state.witness_tracer.add_sponge_marker( - vm_state.local_state.monotonic_cycle_counter, - SpongeExecutionMarker::StorageLogReadOnly, - 1..4, - false, - ); let result = PrimitiveValue { value: query.read_value, is_pointer: false, @@ -222,14 +215,6 @@ impl> DecodedOpcode { // we still do a formal query to execute write and record witness let _query = vm_state .access_storage(vm_state.local_state.monotonic_cycle_counter, partial_query); - - vm_state.witness_tracer.add_sponge_marker( - vm_state.local_state.monotonic_cycle_counter, - SpongeExecutionMarker::StorageLogWrite, - 1..5, - true, - ); - vm_state.local_state.pending_port.pending_type = Some(PendingType::WriteLog); } variant @ LogOpcode::Event | variant @ LogOpcode::ToL1Message => { if not_enough_power { @@ -261,13 +246,6 @@ impl> DecodedOpcode { is_service: is_first_message, }; vm_state.emit_event(vm_state.local_state.monotonic_cycle_counter, query); - vm_state.local_state.pending_port.pending_type = Some(PendingType::WriteLog); - vm_state.witness_tracer.add_sponge_marker( - vm_state.local_state.monotonic_cycle_counter, - SpongeExecutionMarker::StorageLogWrite, - 1..5, - true, - ); } LogOpcode::PrecompileCall => { // add extra information about precompile abi in the "key" field @@ -343,12 +321,6 @@ impl> DecodedOpcode { is_service: is_first_message, }; vm_state.call_precompile(vm_state.local_state.monotonic_cycle_counter, query); - vm_state.witness_tracer.add_sponge_marker( - vm_state.local_state.monotonic_cycle_counter, - SpongeExecutionMarker::StorageLogReadOnly, - 1..4, - false, - ); let result = PrimitiveValue { value: U256::from(1u64), is_pointer: false, diff --git a/crates/zk_evm/src/opcodes/execution/mod.rs b/crates/zk_evm/src/opcodes/execution/mod.rs index 0981481..1fee64f 100644 --- a/crates/zk_evm/src/opcodes/execution/mod.rs +++ b/crates/zk_evm/src/opcodes/execution/mod.rs @@ -3,8 +3,6 @@ use crate::vm_state::*; use zkevm_opcode_defs::decoding::AllowedPcOrImm; use zkevm_opcode_defs::decoding::VmEncodingMode; -use zkevm_opcode_defs::SET_FLAGS_FLAG_IDX; - pub mod add; pub mod binop; pub mod context; diff --git a/crates/zk_evm/src/opcodes/execution/mul.rs b/crates/zk_evm/src/opcodes/execution/mul.rs index 49469ce..21f4415 100644 --- a/crates/zk_evm/src/opcodes/execution/mul.rs +++ b/crates/zk_evm/src/opcodes/execution/mul.rs @@ -29,6 +29,8 @@ impl> DecodedOpcode { value: src1, is_pointer: _, } = src1; + + use zkevm_opcode_defs::SET_FLAGS_FLAG_IDX; let set_flags = self.variant.flags[SET_FLAGS_FLAG_IDX]; vm_state.local_state.callstack.get_current_stack_mut().pc = new_pc; let tmp = src0.full_mul(src1).0; diff --git a/crates/zk_evm/src/opcodes/execution/near_call.rs b/crates/zk_evm/src/opcodes/execution/near_call.rs index 8549893..fbe7eed 100644 --- a/crates/zk_evm/src/opcodes/execution/near_call.rs +++ b/crates/zk_evm/src/opcodes/execution/near_call.rs @@ -1,4 +1,3 @@ -use zk_evm_abstractions::vm::SpongeExecutionMarker; use zkevm_opcode_defs::NearCallABI; use super::*; @@ -67,11 +66,5 @@ impl> DecodedOpcode { // perform some extra steps to ensure that our rollbacks are properly written and saved // both in storage and for witness vm_state.start_frame(vm_state.local_state.monotonic_cycle_counter, new_stack); - vm_state.witness_tracer.add_sponge_marker( - vm_state.local_state.monotonic_cycle_counter, - SpongeExecutionMarker::CallstackPush, - 1..4, - false, - ); } } diff --git a/crates/zk_evm/src/opcodes/execution/ret.rs b/crates/zk_evm/src/opcodes/execution/ret.rs index 97b0c51..0803f21 100644 --- a/crates/zk_evm/src/opcodes/execution/ret.rs +++ b/crates/zk_evm/src/opcodes/execution/ret.rs @@ -1,7 +1,6 @@ use super::*; use zk_evm_abstractions::aux::Timestamp; -use zk_evm_abstractions::vm::SpongeExecutionMarker; use zkevm_opcode_defs::definitions::ret::*; use zkevm_opcode_defs::FatPointerValidationException; use zkevm_opcode_defs::{FatPointer, Opcode, RetABI, RetForwardPageType, RetOpcode}; @@ -36,13 +35,6 @@ impl> DecodedOpcode { let ret_abi = RetABI::from_u256(src0); // we want to mark with one that was will become a new current (taken from stack) - vm_state.witness_tracer.add_sponge_marker( - vm_state.local_state.monotonic_cycle_counter, - SpongeExecutionMarker::CallstackPop, - 1..4, - false, - ); - let RetABI { mut memory_quasi_fat_pointer, page_forwarding_mode, @@ -208,7 +200,6 @@ impl> DecodedOpcode { Timestamp(vm_state.local_state.timestamp), ); - vm_state.local_state.did_call_or_ret_recently = true; vm_state.local_state.registers[RET_IMPLICIT_RETURNDATA_PARAMS_REGISTER as usize] = PrimitiveValue { value: returndata_fat_pointer.to_u256(), diff --git a/crates/zk_evm/src/opcodes/execution/shift.rs b/crates/zk_evm/src/opcodes/execution/shift.rs index df4e31a..010181a 100644 --- a/crates/zk_evm/src/opcodes/execution/shift.rs +++ b/crates/zk_evm/src/opcodes/execution/shift.rs @@ -38,6 +38,8 @@ impl> DecodedOpcode { Opcode::Shift(inner) => inner, _ => unreachable!(), }; + + use zkevm_opcode_defs::SET_FLAGS_FLAG_IDX; let set_flags = self.variant.flags[SET_FLAGS_FLAG_IDX]; vm_state.local_state.callstack.get_current_stack_mut().pc = new_pc; let shift_abs = src1.low_u64() as u8; diff --git a/crates/zk_evm/src/opcodes/execution/sub.rs b/crates/zk_evm/src/opcodes/execution/sub.rs index f876dde..19aec14 100644 --- a/crates/zk_evm/src/opcodes/execution/sub.rs +++ b/crates/zk_evm/src/opcodes/execution/sub.rs @@ -30,6 +30,7 @@ impl> DecodedOpcode { is_pointer: _, } = src1; + use zkevm_opcode_defs::SET_FLAGS_FLAG_IDX; let set_flags = self.variant.flags[SET_FLAGS_FLAG_IDX]; vm_state.local_state.callstack.get_current_stack_mut().pc = new_pc; let (result, of) = src0.overflowing_sub(src1); diff --git a/crates/zk_evm/src/opcodes/execution/uma.rs b/crates/zk_evm/src/opcodes/execution/uma.rs index 3cf5feb..72b07b7 100644 --- a/crates/zk_evm/src/opcodes/execution/uma.rs +++ b/crates/zk_evm/src/opcodes/execution/uma.rs @@ -1,5 +1,5 @@ use zk_evm_abstractions::aux::*; -use zk_evm_abstractions::vm::{MemoryType, SpongeExecutionMarker}; +use zk_evm_abstractions::vm::MemoryType; use super::*; use zkevm_opcode_defs::{FatPointer, Opcode, UMAOpcode, UMA_INCREMENT_FLAG_IDX}; @@ -262,17 +262,8 @@ impl> DecodedOpcode { }; let word_0_read_value = if skip_memory_access == false { - let word_0_query = vm_state.read_memory( - vm_state.local_state.monotonic_cycle_counter, - key_0, - /* is_pended */ false, - ); - vm_state.witness_tracer.add_sponge_marker( - vm_state.local_state.monotonic_cycle_counter, - SpongeExecutionMarker::MemoryQuery, - 1..2, - /* is_pended */ false, - ); + let word_0_query = + vm_state.read_memory(vm_state.local_state.monotonic_cycle_counter, key_0); let word_0_read_value = word_0_query.value; @@ -287,18 +278,8 @@ impl> DecodedOpcode { timestamp: timestamp_to_read, }; - let word_1_query = vm_state.read_memory( - vm_state.local_state.monotonic_cycle_counter, - key_1, - /* is_pended */ true, - ); - - vm_state.witness_tracer.add_sponge_marker( - vm_state.local_state.monotonic_cycle_counter, - SpongeExecutionMarker::MemoryQuery, - 3..4, - /* is_pended */ true, - ); + let word_1_query = + vm_state.read_memory(vm_state.local_state.monotonic_cycle_counter, key_1); word_1_query.value } else { @@ -394,17 +375,9 @@ impl> DecodedOpcode { vm_state.local_state.monotonic_cycle_counter, key_0, new_word_0_value, - /* is_pended */ false, ); } - vm_state.witness_tracer.add_sponge_marker( - vm_state.local_state.monotonic_cycle_counter, - SpongeExecutionMarker::MemoryQuery, - 2..3, - /* is_pended */ false, - ); - // may be write word 1 if is_unaligned && skip_memory_access == false { let key_1 = MemoryKey { @@ -422,17 +395,7 @@ impl> DecodedOpcode { vm_state.local_state.monotonic_cycle_counter, key_1, new_word_1_value, - /* is_pended */ true, ); - - vm_state.witness_tracer.add_sponge_marker( - vm_state.local_state.monotonic_cycle_counter, - SpongeExecutionMarker::MemoryQuery, - 4..5, - /* is_pended */ true, - ); - - vm_state.local_state.pending_port.pending_type = Some(PendingType::UMAWrite); } if set_panic == false { diff --git a/crates/zk_evm/src/reference_impls/memory.rs b/crates/zk_evm/src/reference_impls/memory.rs index bbb11c5..59eb9b0 100644 --- a/crates/zk_evm/src/reference_impls/memory.rs +++ b/crates/zk_evm/src/reference_impls/memory.rs @@ -12,8 +12,6 @@ use zkevm_opcode_defs::{FatPointer, BOOTLOADER_CALLDATA_PAGE}; use super::*; -const MAX_HEAP_PAGE_SIZE_IN_WORDS: usize = (u16::MAX as usize) / 32; - pub struct ReusablePool< T: Sized, InitFn: Fn() -> T, @@ -173,7 +171,7 @@ pub struct SimpleMemory { } fn heap_init() -> Vec { - vec![U256::zero(); MAX_HEAP_PAGE_SIZE_IN_WORDS] + vec![U256::zero(); 1 << 10] } fn stack_init() -> Vec { @@ -185,7 +183,6 @@ fn heap_on_pull(_el: &mut Vec) -> () {} fn stack_on_pull(_el: &mut Vec) -> () {} fn heap_on_return(el: &mut Vec) -> () { - assert_eq!(el.len(), MAX_HEAP_PAGE_SIZE_IN_WORDS); el.fill(U256::zero()); } @@ -194,6 +191,14 @@ fn stack_on_return(el: &mut Vec) -> () { el.fill(PrimitiveValue::empty()); } +fn resize_to_fit(el: &mut Vec, idx: usize) { + if el.len() >= idx + 1 { + return; + } + + el.resize(idx + 1, U256::zero()); +} + // as usual, if we rollback the current frame then we apply changes to storage immediately, // otherwise we carry rollbacks to the parent's frames @@ -222,16 +227,14 @@ impl SimpleMemory { // this one virtually exists always new.code_pages .insert(0u32, vec![U256::zero(); MAX_CODE_PAGE_SIZE_IN_WORDS]); - new.pages_with_extended_lifetime.insert( - BOOTLOADER_CALLDATA_PAGE, - vec![U256::zero(); MAX_HEAP_PAGE_SIZE_IN_WORDS], - ); + new.pages_with_extended_lifetime + .insert(BOOTLOADER_CALLDATA_PAGE, vec![U256::zero(); 1 << 10]); new.page_numbers_indirections.insert(0, Indirection::Empty); // quicker lookup new.indirections_to_cleanup_on_return .push(HashSet::with_capacity_and_hasher(4, S::default())); new.heaps.push(( - (0u32, vec![U256::zero(); MAX_HEAP_PAGE_SIZE_IN_WORDS]), - (0u32, vec![U256::zero(); MAX_HEAP_PAGE_SIZE_IN_WORDS]), + (0u32, vec![U256::zero(); 1 << 10]), + (0u32, vec![U256::zero(); 1 << 20]), )); // formally, so we can access "last" new @@ -252,17 +255,12 @@ impl SimpleMemory { // this one virtually exists always new.code_pages .insert(0u32, vec![U256::zero(); MAX_CODE_PAGE_SIZE_IN_WORDS]); - new.pages_with_extended_lifetime.insert( - BOOTLOADER_CALLDATA_PAGE, - vec![U256::zero(); MAX_HEAP_PAGE_SIZE_IN_WORDS], - ); + new.pages_with_extended_lifetime + .insert(BOOTLOADER_CALLDATA_PAGE, vec![]); new.page_numbers_indirections.insert(0, Indirection::Empty); // quicker lookup new.indirections_to_cleanup_on_return .push(HashSet::with_capacity_and_hasher(4, S::default())); - new.heaps.push(( - (0u32, vec![U256::zero(); MAX_HEAP_PAGE_SIZE_IN_WORDS]), - (0u32, vec![U256::zero(); MAX_HEAP_PAGE_SIZE_IN_WORDS]), - )); // formally, so we can access "last" + new.heaps.push(((0u32, vec![]), (0u32, vec![]))); // formally, so we can access "last" new } @@ -288,20 +286,11 @@ impl SimpleMemory { // Can never populate stack or aux heap pub fn populate_heap(&mut self, values: Vec) { let heaps_data = self.heaps.last_mut().unwrap(); - let len = values.len(); - assert!(len <= MAX_HEAP_PAGE_SIZE_IN_WORDS); - let mut values = values; - values.resize(MAX_HEAP_PAGE_SIZE_IN_WORDS, U256::zero()); heaps_data.0 .1 = values; } pub fn polulate_bootloaders_calldata(&mut self, values: Vec) { - let len = values.len(); - assert!(len <= MAX_HEAP_PAGE_SIZE_IN_WORDS); - let mut values = values; - values.resize(MAX_HEAP_PAGE_SIZE_IN_WORDS, U256::zero()); - *self .pages_with_extended_lifetime .get_mut(&BOOTLOADER_CALLDATA_PAGE) @@ -406,7 +395,7 @@ impl SimpleMemory { } pub fn dump_full_page(&self, page_number: u32) -> Vec<[u8; 32]> { - let upper_bound = MAX_HEAP_PAGE_SIZE_IN_WORDS as u32; + let upper_bound = 1 << 10; self.dump_page_content(page_number, 0..upper_bound) } } @@ -428,10 +417,20 @@ impl Memory for SimpleMemory { value: query.value, is_pointer: query.value_is_pointer, }; + assert!( + (query.location.index.0 as usize) < page.len(), + "out of bounds for stack page for query {:?}", + query + ); page[query.location.index.0 as usize] = primitive } else { let (idx, page) = self.stack_pages.last().unwrap(); assert_eq!(*idx, page_number); + assert!( + (query.location.index.0 as usize) < page.len(), + "out of bounds for stack page for query {:?}", + query + ); let primitive = page[query.location.index.0 as usize]; query.value = primitive.value; query.value_is_pointer = primitive.is_pointer; @@ -446,9 +445,11 @@ impl Memory for SimpleMemory { ) = self.heaps.last_mut().unwrap(); if a == MemoryType::Heap { debug_assert_eq!(*current_heap_page, query.location.page.0); + resize_to_fit(current_heap_content, query.location.index.0 as usize); current_heap_content[query.location.index.0 as usize] = query.value; } else if a == MemoryType::AuxHeap { debug_assert_eq!(*current_aux_heap_page, query.location.page.0); + resize_to_fit(current_aux_heap_content, query.location.index.0 as usize); current_aux_heap_content[query.location.index.0 as usize] = query.value; } else { unreachable!() @@ -457,12 +458,14 @@ impl Memory for SimpleMemory { let ( (current_heap_page, current_heap_content), (current_aux_heap_page, current_aux_heap_content), - ) = self.heaps.last().unwrap(); + ) = self.heaps.last_mut().unwrap(); if a == MemoryType::Heap { debug_assert_eq!(*current_heap_page, query.location.page.0); + resize_to_fit(current_heap_content, query.location.index.0 as usize); query.value = current_heap_content[query.location.index.0 as usize]; } else if a == MemoryType::AuxHeap { debug_assert_eq!(*current_aux_heap_page, query.location.page.0); + resize_to_fit(current_aux_heap_content, query.location.index.0 as usize); query.value = current_aux_heap_content[query.location.index.0 as usize]; } else { unreachable!() @@ -477,23 +480,39 @@ impl Memory for SimpleMemory { .get(&page_number) .expect("fat pointer only points to reachable memory"); + // NOTE: we CAN have a situation when e.g. callee returned part of the heap that + // was NEVER written into, so it's page would NOT be resized to the index which we try + // to access (even though fat pointe IS in bounds), so we need to use .get() match indirection { Indirection::Heap(index) => { let forwarded_heap_data = &self.heaps[*index]; assert_eq!(forwarded_heap_data.0 .0, query.location.page.0); - query.value = forwarded_heap_data.0 .1[query.location.index.0 as usize]; + query.value = forwarded_heap_data + .0 + .1 + .get(query.location.index.0 as usize) + .copied() + .unwrap_or(U256::zero()); } Indirection::AuxHeap(index) => { let forwarded_heap_data = &self.heaps[*index]; assert_eq!(forwarded_heap_data.1 .0, query.location.page.0); - query.value = forwarded_heap_data.1 .1[query.location.index.0 as usize]; + query.value = forwarded_heap_data + .1 + .1 + .get(query.location.index.0 as usize) + .copied() + .unwrap_or(U256::zero()); } Indirection::ReturndataExtendedLifetime => { let page = self .pages_with_extended_lifetime .get(&page_number) .expect("indirection target must exist"); - query.value = page[query.location.index.0 as usize]; + query.value = page + .get(query.location.index.0 as usize) + .copied() + .unwrap_or(U256::zero()); } Indirection::Empty => { query.value = U256::zero(); diff --git a/crates/zk_evm/src/vm_state/cycle.rs b/crates/zk_evm/src/vm_state/cycle.rs index 2ab86c6..faca3cb 100644 --- a/crates/zk_evm/src/vm_state/cycle.rs +++ b/crates/zk_evm/src/vm_state/cycle.rs @@ -2,10 +2,7 @@ use super::*; use crate::opcodes::parsing::*; use tracing::*; -use zk_evm_abstractions::{ - aux::*, - vm::{MemoryType, SpongeExecutionMarker}, -}; +use zk_evm_abstractions::{aux::*, vm::MemoryType}; use zkevm_opcode_defs::{ImmMemHandlerFlags, NopOpcode, Operand, RegOrImmFlags}; pub struct PreState = EncodingModeProduction> { @@ -18,9 +15,6 @@ pub struct PreState = EncodingModeProdu pub const OPCODES_PER_WORD_LOG_2: usize = 2; pub const OPCODES_PER_WORD: usize = 1 << OPCODES_PER_WORD_LOG_2; -pub const READ_OPCODE_SPONGE_IDX: usize = 0; -pub const READ_SRC_FROM_MEMORY_SPONGE_IDX: usize = 1; -pub const READ_DST_FROM_MEMORY_SPONGE_IDX: usize = 2; pub fn read_and_decode< const N: usize, @@ -48,18 +42,21 @@ pub fn read_and_decode< tracer.before_decoding(local_state, memory); } - let skip_cycle = local_state.pending_port.is_any_pending() || local_state.execution_has_ended(); - delayed_changes.reset_pending_port = local_state.pending_port.is_any_pending(); - + let execution_has_ended = local_state.execution_has_ended(); let pending_exception = local_state.pending_exception; + let code_page = local_state.callstack.get_current_stack().code_page; + delayed_changes.new_previous_code_memory_page = Some(code_page); + + let pc = local_state.callstack.get_current_stack().pc; + let previous_super_pc = local_state.previous_super_pc; + let code_pages_are_different = local_state.callstack.get_current_stack().code_page + != local_state.previous_code_memory_page; + let (super_pc, sub_pc) = E::split_pc(pc); + // if we do not skip cycle then we read memory for a new opcode - let opcode_encoding = if !skip_cycle && !pending_exception { - let pc = local_state.callstack.get_current_stack().pc; - let previous_super_pc = local_state.previous_super_pc; - let did_call_or_ret_recently = local_state.did_call_or_ret_recently; - let (super_pc, sub_pc) = E::split_pc(pc); - let raw_opcode_u64 = match (did_call_or_ret_recently, previous_super_pc == super_pc) { + let opcode_encoding = if execution_has_ended == false && pending_exception == false { + let raw_opcode_u64 = match (code_pages_are_different, previous_super_pc == super_pc) { (true, _) | (false, false) => { // we need to read the code word and select a proper subword let code_page = local_state.callstack.get_current_stack().code_page; @@ -72,7 +69,8 @@ pub fn read_and_decode< timestamp: local_state.timestamp_for_code_or_src_read(), location, }; - delayed_changes.reset_did_call_or_ret_recently = true; + + delayed_changes.new_previous_code_memory_page = Some(code_page); // code read is never pending let code_query = read_code( @@ -80,13 +78,6 @@ pub fn read_and_decode< witness_tracer, local_state.monotonic_cycle_counter, key, - /* is_pended */ false, - ); - witness_tracer.add_sponge_marker( - local_state.monotonic_cycle_counter, - SpongeExecutionMarker::MemoryQuery, - 0..1, - /* is_pended */ false, ); let u256_word = code_query.value; delayed_changes.new_previous_code_word = Some(u256_word); @@ -110,32 +101,33 @@ pub fn read_and_decode< }; raw_opcode_u64 - } else if !skip_cycle && pending_exception { + } else if pending_exception { // there are no cases that set pending exception and // simultaneously finish the execution - assert!(local_state.execution_has_ended() == false); - - // note that we do reset PC in VM for simplicity, so we do it here too - let pc = local_state.callstack.get_current_stack().pc; - let (super_pc, _) = E::split_pc(pc); - delayed_changes.new_previous_super_pc = Some(super_pc); + assert!(execution_has_ended == false); // so we can just remove the marker as soon as we are no longer pending delayed_changes.new_pending_exception = Some(false); + // anyway update super PC + delayed_changes.new_previous_super_pc = Some(super_pc); + E::exception_revert_encoding() } else { // we are skipping cycle for some reason, so we do nothing, // and do not touch any flags + // This only happens at the end of execution + if local_state.execution_has_ended() { assert!(pending_exception == false); - delayed_changes.reset_did_call_or_ret_recently = true; } E::nop_encoding() }; + let skip_cycle = execution_has_ended; + // now we have some candidate for opcode. If it's noop we are not expecting to have any problems, // so check for other meaningful exceptions @@ -158,7 +150,6 @@ pub fn read_and_decode< // we have already paid for it ergs_cost = 0; } - let (mut ergs_remaining, not_enough_power) = local_state .callstack .get_current_stack() @@ -235,7 +226,7 @@ pub fn read_and_decode< opcode_masked: partially_decoded, error_flags_accumulated: error_flags, resolved_condition, - did_skip_cycle: skip_cycle, + did_skip_cycle: false, }; tracer.after_decoding(local_state, data, memory); @@ -319,24 +310,10 @@ impl< // src read is never pending, but to keep consistent memory implementation we // need to branch here for a case of loading constants from code space let src0_query = if src0_mem_location.memory_type == MemoryType::Code { - self.read_code( - self.local_state.monotonic_cycle_counter, - key, - /* is_pended */ false, - ) + self.read_code(self.local_state.monotonic_cycle_counter, key) } else { - self.read_memory( - self.local_state.monotonic_cycle_counter, - key, - /* is_pended */ false, - ) + self.read_memory(self.local_state.monotonic_cycle_counter, key) }; - self.witness_tracer.add_sponge_marker( - self.local_state.monotonic_cycle_counter, - SpongeExecutionMarker::MemoryQuery, - 1..2, - /* is_pended */ false, - ); let u256_word = src0_query.value; let is_pointer = src0_query.value_is_pointer; @@ -405,10 +382,6 @@ impl< after_masking_decoded.apply(self, prestate)?; - if self.local_state.pending_port.is_any_pending() { - debug_assert!(self.local_state.pending_cycles_left.is_none()); - } - if !skip_cycle { self.increment_timestamp_after_cycle(); } diff --git a/crates/zk_evm/src/vm_state/helpers.rs b/crates/zk_evm/src/vm_state/helpers.rs index 97f7832..ab7129e 100644 --- a/crates/zk_evm/src/vm_state/helpers.rs +++ b/crates/zk_evm/src/vm_state/helpers.rs @@ -4,7 +4,7 @@ use super::*; use zk_evm_abstractions::aux::{MemoryKey, MemoryLocation}; use zk_evm_abstractions::queries::{DecommittmentQuery, LogQuery, MemoryQuery}; -use zk_evm_abstractions::vm::{RefundType, SpongeExecutionMarker}; +use zk_evm_abstractions::vm::RefundType; use zkevm_opcode_defs::UNMAPPED_PAGE; pub fn read_code< @@ -17,7 +17,6 @@ pub fn read_code< witness_tracer: &mut WT, monotonic_cycle_counter: u32, key: MemoryKey, - _is_pended: bool, ) -> MemoryQuery { let MemoryKey { location, @@ -52,12 +51,7 @@ impl< E: VmEncodingMode, > VmState { - pub fn read_memory( - &mut self, - monotonic_cycle_counter: u32, - key: MemoryKey, - _is_pended: bool, - ) -> MemoryQuery { + pub fn read_memory(&mut self, monotonic_cycle_counter: u32, key: MemoryKey) -> MemoryQuery { let MemoryKey { location, timestamp, @@ -82,18 +76,12 @@ impl< query } - pub fn read_code( - &mut self, - monotonic_cycle_counter: u32, - key: MemoryKey, - is_pended: bool, - ) -> MemoryQuery { + pub fn read_code(&mut self, monotonic_cycle_counter: u32, key: MemoryKey) -> MemoryQuery { read_code( &mut self.memory, &mut self.witness_tracer, monotonic_cycle_counter, key, - is_pended, ) } @@ -102,7 +90,6 @@ impl< monotonic_cycle_counter: u32, key: MemoryKey, value: PrimitiveValue, - _is_pended: bool, ) -> MemoryQuery { let MemoryKey { location, @@ -288,19 +275,7 @@ impl< location, timestamp: self.timestamp_for_dst_write(), }; - let _dst0_query = self.write_memory( - monotonic_cycle_counter, - key, - value, - /* is_pended */ false, - ); // no pending on dst0 writes - - self.witness_tracer.add_sponge_marker( - self.local_state.monotonic_cycle_counter, - SpongeExecutionMarker::MemoryQuery, - 2..3, - /* is_pended */ false, - ); + let _dst0_query = self.write_memory(monotonic_cycle_counter, key, value); } else { self.update_register_value(opcode.dst0_reg_idx, value); } diff --git a/crates/zk_evm/src/vm_state/mod.rs b/crates/zk_evm/src/vm_state/mod.rs index e174ae5..536b32b 100644 --- a/crates/zk_evm/src/vm_state/mod.rs +++ b/crates/zk_evm/src/vm_state/mod.rs @@ -55,6 +55,7 @@ impl PrimitiveValue { #[derive(Clone, Debug, PartialEq)] pub struct VmLocalState = EncodingModeProduction> { pub previous_code_word: U256, + pub previous_code_memory_page: MemoryPage, pub registers: [PrimitiveValue; zkevm_opcode_defs::REGISTERS_COUNT], pub flags: Flags, pub timestamp: u32, @@ -67,19 +68,17 @@ pub struct VmLocalState = EncodingModeP pub absolute_execution_step: u32, pub current_ergs_per_pubdata_byte: u32, pub tx_number_in_block: u16, - pub did_call_or_ret_recently: bool, pub pending_exception: bool, pub previous_super_pc: E::PcOrImm, pub context_u128_register: u128, pub callstack: Callstack, - pub pending_port: SpongePendingPort, - pub pending_cycles_left: Option, } impl> VmLocalState { pub fn empty_state() -> Self { Self { previous_code_word: U256::zero(), + previous_code_memory_page: MemoryPage(0u32), registers: [PrimitiveValue::empty(); zkevm_opcode_defs::REGISTERS_COUNT], flags: Flags::empty(), timestamp: STARTING_TIMESTAMP, @@ -90,10 +89,7 @@ impl> VmLocalState { current_ergs_per_pubdata_byte: 0, tx_number_in_block: 0, previous_super_pc: E::PcOrImm::from_u64_clipped(0), - did_call_or_ret_recently: true, // to properly start the execution pending_exception: false, - pending_port: SpongePendingPort::empty(), - pending_cycles_left: None, context_u128_register: 0u128, callstack: Callstack::empty(), } @@ -117,35 +113,27 @@ pub struct DelayedLocalStateChanges< const N: usize = 8, E: VmEncodingMode = EncodingModeProduction, > { - pub reset_pending_port: bool, - pub reset_did_call_or_ret_recently: bool, pub new_ergs_remaining: Option, pub new_previous_code_word: Option, pub new_previous_super_pc: Option, pub new_pending_exception: Option, + pub new_previous_code_memory_page: Option, } impl> Default for DelayedLocalStateChanges { fn default() -> Self { Self { - reset_pending_port: false, - reset_did_call_or_ret_recently: false, new_ergs_remaining: None, new_previous_code_word: None, new_previous_super_pc: None, new_pending_exception: None, + new_previous_code_memory_page: None, } } } impl> DelayedLocalStateChanges { pub fn apply(self, local_state: &mut VmLocalState) { - if self.reset_pending_port { - local_state.pending_port.reset(); - } - if self.reset_did_call_or_ret_recently { - local_state.did_call_or_ret_recently = false; - } if let Some(ergs_remaining) = self.new_ergs_remaining { local_state.callstack.get_current_stack_mut().ergs_remaining = ergs_remaining; } @@ -160,6 +148,10 @@ impl> DelayedLocalStateChanges { if let Some(new_pending_exception) = self.new_pending_exception { local_state.pending_exception = new_pending_exception; } + + if let Some(new_previous_code_memory_page) = self.new_previous_code_memory_page { + local_state.previous_code_memory_page = new_previous_code_memory_page; + } } } @@ -218,23 +210,14 @@ impl< pub fn reset_flags(&mut self) { self.local_state.flags.reset(); } - pub fn is_any_pending(&self) -> bool { - self.local_state.pending_port.is_any_pending() - } pub fn callstack_is_full(&self) -> bool { self.local_state.callstack_is_full() } pub fn execution_has_ended(&self) -> bool { self.local_state.execution_has_ended() } - pub fn check_skip_cycles_due_to_pending(&mut self) -> bool { - let should_skip = self.local_state.pending_port.is_any_pending(); - self.local_state.pending_port.reset(); - - should_skip - } pub fn compute_if_should_skip_cycle(&mut self) -> bool { - self.check_skip_cycles_due_to_pending() || self.execution_has_ended() + self.execution_has_ended() } pub fn timestamp_for_code_or_src_read(&self) -> Timestamp { self.local_state.timestamp_for_code_or_src_read() diff --git a/crates/zk_evm/src/witness_trace/mod.rs b/crates/zk_evm/src/witness_trace/mod.rs index c994dd2..d552394 100644 --- a/crates/zk_evm/src/witness_trace/mod.rs +++ b/crates/zk_evm/src/witness_trace/mod.rs @@ -1,12 +1,11 @@ use zk_evm_abstractions::{ queries::{DecommittmentQuery, LogQuery, MemoryQuery}, - vm::{PrecompileCyclesWitness, RefundType, SpongeExecutionMarker}, + vm::{PrecompileCyclesWitness, RefundType}, }; use zkevm_opcode_defs::decoding::VmEncodingMode; use super::*; use crate::vm_state::{CallStackEntry, VmLocalState}; -use std::ops::Range; #[allow(unused_variables)] pub trait VmWitnessTracer>: Clone + std::fmt::Debug { @@ -16,16 +15,6 @@ pub trait VmWitnessTracer>: Clone + std::fm #[inline] fn end_execution_cycle(&mut self, current_state: &VmLocalState) {} - #[inline] - fn add_sponge_marker( - &mut self, - monotonic_cycle_counter: u32, - marker: SpongeExecutionMarker, - sponges_range: Range, - is_pended: bool, - ) { - } - #[inline] fn add_memory_query(&mut self, monotonic_cycle_counter: u32, memory_query: MemoryQuery) {} diff --git a/crates/zkevm_circuits/.github/ISSUE_TEMPLATE/bug_report.md b/crates/zkevm_circuits/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..2d3e38a --- /dev/null +++ b/crates/zkevm_circuits/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,39 @@ +--- +name: Bug report +about: Use this template for reporting issues +title: '' +labels: bug +assignees: '' +--- + +### 🐛 Bug Report + +#### 📝 Description + +Provide a clear and concise description of the bug. + +#### 🔄 Reproduction Steps + +Steps to reproduce the behaviour + +#### 🤔 Expected Behavior + +Describe what you expected to happen. + +#### 😯 Current Behavior + +Describe what actually happened. + +#### 🖥️ Environment + +Any relevant environment details. + +#### 📋 Additional Context + +Add any other context about the problem here. If applicable, add screenshots to help explain. + +#### 📎 Log Output + +``` +Paste any relevant log output here. +``` diff --git a/crates/zkevm_circuits/.github/ISSUE_TEMPLATE/feature_request.md b/crates/zkevm_circuits/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..d921e06 --- /dev/null +++ b/crates/zkevm_circuits/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,21 @@ +--- +name: Feature request +about: Use this template for requesting features +title: '' +labels: feat +assignees: '' +--- + +### 🌟 Feature Request + +#### 📝 Description + +Provide a clear and concise description of the feature you'd like to see. + +#### 🤔 Rationale + +Explain why this feature is important and how it benefits the project. + +#### 📋 Additional Context + +Add any other context or information about the feature request here. diff --git a/crates/zkevm_circuits/.github/pull_request_template.md b/crates/zkevm_circuits/.github/pull_request_template.md new file mode 100644 index 0000000..8ce206c --- /dev/null +++ b/crates/zkevm_circuits/.github/pull_request_template.md @@ -0,0 +1,20 @@ +# What ❔ + + + + + +## Why ❔ + + + + +## Checklist + + + + +- [ ] PR title corresponds to the body of PR (we generate changelog entries from PRs). +- [ ] Tests for the changes have been added / updated. +- [ ] Documentation comments have been added / updated. +- [ ] Code has been formatted via `zk fmt` and `zk lint`. diff --git a/crates/zkevm_circuits/.github/workflows/cargo-license.yaml b/crates/zkevm_circuits/.github/workflows/cargo-license.yaml new file mode 100644 index 0000000..189b471 --- /dev/null +++ b/crates/zkevm_circuits/.github/workflows/cargo-license.yaml @@ -0,0 +1,8 @@ +name: Cargo license check +on: pull_request +jobs: + cargo-deny: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: EmbarkStudios/cargo-deny-action@v1 diff --git a/crates/zkevm_circuits/.github/workflows/ci.yaml b/crates/zkevm_circuits/.github/workflows/ci.yaml new file mode 100644 index 0000000..691210c --- /dev/null +++ b/crates/zkevm_circuits/.github/workflows/ci.yaml @@ -0,0 +1,27 @@ +name: "Rust CI" +on: + pull_request: + +jobs: + build: + name: cargo build and test + runs-on: [ubuntu-22.04-github-hosted-32core] + steps: + - uses: actions/checkout@v3 + - uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: nightly-2023-09-20 + rustflags: "" + - run: cargo build --verbose --release + - run: cargo test --verbose --release --all + + formatting: + name: cargo fmt + runs-on: [ubuntu-latest] + steps: + - uses: actions/checkout@v3 + - uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + components: rustfmt + - name: Rustfmt Check + uses: actions-rust-lang/rustfmt@v1 diff --git a/crates/zkevm_circuits/.github/workflows/secrets_scanner.yaml b/crates/zkevm_circuits/.github/workflows/secrets_scanner.yaml new file mode 100644 index 0000000..54054cf --- /dev/null +++ b/crates/zkevm_circuits/.github/workflows/secrets_scanner.yaml @@ -0,0 +1,17 @@ +name: Leaked Secrets Scan +on: [pull_request] +jobs: + TruffleHog: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3 + with: + fetch-depth: 0 + - name: TruffleHog OSS + uses: trufflesecurity/trufflehog@0c66d30c1f4075cee1aada2e1ab46dabb1b0071a + with: + path: ./ + base: ${{ github.event.repository.default_branch }} + head: HEAD + extra_args: --debug --only-verified diff --git a/crates/zkevm_circuits/.gitignore b/crates/zkevm_circuits/.gitignore new file mode 100644 index 0000000..3ab5292 --- /dev/null +++ b/crates/zkevm_circuits/.gitignore @@ -0,0 +1,3 @@ +/target +/Cargo.lock +.idea diff --git a/crates/zkevm_circuits/CONTRIBUTING.md b/crates/zkevm_circuits/CONTRIBUTING.md new file mode 100644 index 0000000..dd3d458 --- /dev/null +++ b/crates/zkevm_circuits/CONTRIBUTING.md @@ -0,0 +1,44 @@ +# Contribution Guidelines + +Hello! Thanks for your interest in joining the mission to accelerate the mass adoption of crypto for personal +sovereignty! We welcome contributions from anyone on the internet, and are grateful for even the smallest of fixes! + +## Ways to contribute + +There are many ways to contribute to the ZK Stack: + +1. Open issues: if you find a bug, have something you believe needs to be fixed, or have an idea for a feature, please + open an issue. +2. Add color to existing issues: provide screenshots, code snippets, and whatever you think would be helpful to resolve + issues. +3. Resolve issues: either by showing an issue isn't a problem and the current state is ok as is or by fixing the problem + and opening a PR. +4. Report security issues, see [our security policy](./github/SECURITY.md). +5. [Join the team!](https://matterlabs.notion.site/Shape-the-future-of-Ethereum-at-Matter-Labs-dfb3b5a037044bb3a8006af2eb0575e0) + +## Fixing issues + +To contribute code fixing issues, please fork the repo, fix an issue, commit, add documentation as per the PR template, +and the repo's maintainers will review the PR. +[here](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork) +for guidance how to work with PRs created from a fork. + +## Licenses + +If you contribute to this project, your contributions will be made to the project under both Apache 2.0 and the MIT +license. + +## Resources + +We aim to make it as easy as possible to contribute to the mission. This is still WIP, and we're happy for contributions +and suggestions here too. Some resources to help: + +1. [In-repo docs aimed at developers](docs) +2. [zkSync Era docs!](https://era.zksync.io/docs/) +3. Company links can be found in the [repo's readme](README.md) + +## Code of Conduct + +Be polite and respectful. + +### Thank you diff --git a/crates/zkevm_circuits/Cargo.toml b/crates/zkevm_circuits/Cargo.toml new file mode 100644 index 0000000..faa9256 --- /dev/null +++ b/crates/zkevm_circuits/Cargo.toml @@ -0,0 +1,39 @@ +[package] +name = "zkevm_circuits" +version = "0.140.2" +edition = "2021" +authors = ["The Matter Labs Team "] +homepage = "https://zksync.io/" +repository = "https://github.com/matter-labs/era-zkevm_circuits" +license = "MIT OR Apache-2.0" +keywords = ["blockchain", "zksync"] +categories = ["cryptography"] +description = "ZKsync Era circuits for EraVM" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +derivative = "2" +serde = { version = "1", features = ["derive"] } +rand = "0.4" +smallvec = { version = "1.13", features = [ + "const_generics", + "const_new", + "serde", +] } +arrayvec = "0.7" +bincode = "1.3" +serde_json = "1" +itertools = "0.10" +rand_new = { package = "rand", version = "0.8" } +hex = "0.4" +seq-macro = "0.3" + +zkevm_opcode_defs = { version = "=0.132.0", path = "../zkevm_opcode_defs" } +cs_derive = "0" # Version is not pinned, since it's an old dependency for MultiVM only. +boojum = "0" # Version is not pinned, since it's an old dependency for MultiVM only. + +[features] +default = [] +log_tracing = ["boojum/log_tracing"] +verbose_circuits = [] diff --git a/crates/zkevm_circuits/LICENSE-APACHE b/crates/zkevm_circuits/LICENSE-APACHE new file mode 100644 index 0000000..d9a10c0 --- /dev/null +++ b/crates/zkevm_circuits/LICENSE-APACHE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/crates/zkevm_circuits/LICENSE-MIT b/crates/zkevm_circuits/LICENSE-MIT new file mode 100644 index 0000000..2739ea6 --- /dev/null +++ b/crates/zkevm_circuits/LICENSE-MIT @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Matter Labs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/crates/zkevm_circuits/README.md b/crates/zkevm_circuits/README.md new file mode 100644 index 0000000..f92a928 --- /dev/null +++ b/crates/zkevm_circuits/README.md @@ -0,0 +1,33 @@ +# CPU/GPU Based Prover for zkSync Era + +[![Logo](eraLogo.png)](https://zksync.io/) + +zkSync Era is a layer 2 rollup that uses zero-knowledge proofs to scale Ethereum without compromising on security or +decentralization. Since it's EVM compatible (Solidity/Vyper), 99% of Ethereum projects can redeploy without refactoring +or re-auditing a single line of code. zkSync Era also uses an LLVM-based compiler that will eventually let developers +write smart contracts in C++, Rust and other popular languages. + +## License + +The zkSync Era prover is distributed under the terms of either + +- Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) +- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) + +at your option. + +## Official Links + +- [Website](https://zksync.io/) +- [GitHub](https://github.com/matter-labs) +- [Twitter](https://twitter.com/zksync) +- [Twitter for Devs](https://twitter.com/zkSyncDevs) +- [Discord](https://join.zksync.dev) + +## Disclaimer + +zkSync Era has been through lots of testing and audits. Although it is live, it is still in alpha state and will go +through more audits and bug bounties programs. We would love to hear our community's thoughts and suggestions about it! +It is important to state that forking it now can potentially lead to missing important security updates, critical +features, and performance improvements. + diff --git a/crates/zkevm_circuits/SECURITY.md b/crates/zkevm_circuits/SECURITY.md new file mode 100644 index 0000000..2f2871c --- /dev/null +++ b/crates/zkevm_circuits/SECURITY.md @@ -0,0 +1,74 @@ +# Security Policy + +We truly appreciate efforts to discover and disclose security issues responsibly! + +## Vulnerabilities + +If you'd like to report a security issue in the repositories of matter-labs organization, please proceed to our +[Bug Bounty Program on Immunefi](https://era.zksync.io/docs/reference/troubleshooting/audit-bug-bounty.html#bug-bounty-program). + +## Other Security Issues + +We take an impact-first approach instead of a rules-first approach. Therefore, if you believe you found the impactful +issue but can't report it via the Bug Bounty, please email us at +[security@matterlabs.dev](mailto:security@matterlabs.dev). + +### PGP Key + +The following PGP key may be used to communicate sensitive information to developers: + +Fingerprint: `5FED B2D0 EA2C 4906 DD66 71D7 A2C5 0B40 CE3C F297` + +``` +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +=xkM3 +-----END PGP PUBLIC KEY BLOCK----- +``` diff --git a/crates/zkevm_circuits/cs_derive/.gitignore b/crates/zkevm_circuits/cs_derive/.gitignore new file mode 100644 index 0000000..77147e2 --- /dev/null +++ b/crates/zkevm_circuits/cs_derive/.gitignore @@ -0,0 +1,3 @@ +/target +Cargo.lock +.idea/ diff --git a/crates/zkevm_circuits/cs_derive/Cargo.toml b/crates/zkevm_circuits/cs_derive/Cargo.toml new file mode 100644 index 0000000..4a102f4 --- /dev/null +++ b/crates/zkevm_circuits/cs_derive/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "cs_derive" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +syn = { version = "1.0.*", features = ["extra-traits", "printing"]} +quote = {version = "1.0.*"} +proc-macro2 = "1" +proc-macro-error = "1" + +[lib] +proc-macro = true \ No newline at end of file diff --git a/crates/zkevm_circuits/cs_derive/src/.DS_Store b/crates/zkevm_circuits/cs_derive/src/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..01117831263f46ee11bed5f9109806c7b9e43482 GIT binary patch literal 6148 zcmeHK%}&BV5S~R21WY8xM2~whF8hflcCSzn8{RWN)h-*;QO)K%&^^R7sdHp2ZtHgg=3DAPo`hR=6SNLv_lV2_Le$^ z>zD>$JH%5&V=zys?^eng?)A5Ia{YQPj0G;ur8{?*GZKXR}pm7Nr*jL;+DCQ-Ie8jm8)_Of8zF z1D!bn0LyS2!@b%2fSMh^z+q|;9+ proc_macro::TokenStream { + let derived_input = parse_macro_input!(input as DeriveInput); + + let DeriveInput { ident, data, generics, attrs, .. } = derived_input.clone(); + + let serde_remove_bounds = if let Some(serde_remove_bounds) = fetch_attr_nopanic(SERDE_REMOVE_BOUNDS, &attrs) { + let serde_remove_bounds = syn::parse_str::(&serde_remove_bounds).expect("has attr as Expr"); + + serde_remove_bounds == syn::parse_str::("true").unwrap() + } else { + false + }; + + let mut allocations = TokenStream::new(); + let mut allocations_without_value = TokenStream::new(); + let mut initializations = TokenStream::new(); + let mut placeholder_initializations = TokenStream::new(); + + match data { + syn::Data::Struct(ref struct_data) => { + match struct_data.fields { + syn::Fields::Named(ref named_fields) => { + for field in named_fields.named.iter() { + + let field_ident = field.ident.clone().expect("a field ident"); + + let allocation_line = match field.ty { + Type::Path(ref _path_ty) => derive_allocate_by_type_path(&field_ident, _path_ty), + Type::Array(ref _arr_ty) => { + derive_allocate_by_array_type(&field_ident, _arr_ty) + }, + _ => abort_call_site!("only array and path types are allowed"), + }; + allocations.extend(allocation_line); + + let allocation_without_value_line = match field.ty { + Type::Path(ref _path_ty) => derive_allocate_without_value_by_type_path(&field_ident, _path_ty), + Type::Array(ref _arr_ty) => { + derive_allocate_without_value_by_array_type(&field_ident, _arr_ty) + }, + _ => abort_call_site!("only array and path types are allowed"), + }; + allocations_without_value.extend(allocation_without_value_line); + + let placeholder_init_line = match field.ty { + Type::Path(ref _path_ty) => derive_placeholder_witness_by_type(&field_ident, _path_ty), + Type::Array(ref _arr_ty) => { + derive_placeholder_witness_by_array_type(&field_ident, _arr_ty) + }, + _ => abort_call_site!("only array and path types are allowed"), + }; + + placeholder_initializations.extend(placeholder_init_line); + + initializations.extend(quote!{ + #field_ident, + }); + } + } + _ => abort_call_site!("only named fields are allowed"), + } + } + _ => abort_call_site!("only data structs are allowed"), + } + + let comma = Comma(Span::call_site()); + + let type_params_of_allocated_struct = get_type_params_from_generics(&generics, &comma); + + let where_clause = if let Some(clause) = generics.where_clause.as_ref() { + quote! { + #clause + } + } else { + quote! {} + }; + + let field_generic_param = syn::parse_str::(&"F: SmallField").unwrap(); + let has_engine_param = has_proper_small_field_parameter(&generics.params, &field_generic_param); + if has_engine_param == false { + panic!("Expected to have `F: SmallField` somewhere in bounds"); + } + + let witness_ident = get_witness_ident(&ident); + let witness_struct = derive_witness_struct_recursive(derived_input.clone()); + + let derive_line = if serde_remove_bounds { + quote! { + #[derive(Derivative, ::serde::Serialize, ::serde::Deserialize)] + #[derivative(Clone, Debug, Hash(bound = ""), PartialEq(bound = ""), Eq(bound = ""))] + } + } else { + quote! { + #[derive(Derivative, ::serde::Serialize, ::serde::Deserialize)] + #[serde(bound = "")] + #[derivative(Clone, Debug, Hash(bound = ""), PartialEq(bound = ""), Eq(bound = ""))] + } + }; + + let expanded = quote! { + #derive_line + #witness_struct + + impl #generics CSAllocatable for #ident<#type_params_of_allocated_struct> #where_clause { + + type Witness = #witness_ident <#type_params_of_allocated_struct>; + + fn placeholder_witness() -> Self::Witness { + #witness_ident :: <#type_params_of_allocated_struct> { + #placeholder_initializations + } + } + + fn allocate>(cs: &mut CS, witness: Self::Witness) -> Self { + #allocations + + Self { + #initializations + } + } + + fn allocate_without_value>(cs: &mut CS) -> Self { + #allocations_without_value + + Self { + #initializations + } + } + } + }; + + proc_macro::TokenStream::from(expanded) +} + +fn derive_allocate_by_type_path(ident: &Ident, ty: &TypePath) -> TokenStream{ + // create a witness element + quote! { + let wit = witness.#ident.clone(); + let #ident = <#ty as CSAllocatable>::allocate(cs, wit); + } +} + +fn derive_allocate_without_value_by_type_path(ident: &Ident, ty: &TypePath) -> TokenStream{ + // create a witness element + quote! { + let #ident = <#ty as CSAllocatable>::allocate_without_value(cs); + } +} + +fn derive_allocate_by_array_type(ident: &Ident, ty: &TypeArray) -> TokenStream{ + quote! { + let wit = witness.#ident.clone(); + let #ident = <#ty as CSAllocatable>::allocate(cs, wit); + } +} + +fn derive_allocate_without_value_by_array_type(ident: &Ident, ty: &TypeArray) -> TokenStream{ + quote! { + let #ident = <#ty as CSAllocatable>::allocate_without_value(cs); + } +} + +// fn derive_get_witness_by_type(ident: &Ident, ty: &TypePath) -> TokenStream{ +// quote! { +// #ident: <#ty as CSAllocatable>::create_witness(&self.#ident)?, +// } +// } + +// fn derive_get_witness_by_array_type(ident: &Ident, ty: &TypeArray) -> TokenStream{ +// quote! { +// #ident: <#ty as CSAllocatable>::create_witness(&self.#ident)?, +// } +// } + +fn derive_placeholder_witness_by_type(ident: &Ident, ty: &TypePath) -> TokenStream{ + quote! { + #ident: <#ty as CSAllocatable>::placeholder_witness(), + } +} + +fn derive_placeholder_witness_by_array_type(ident: &Ident, ty: &TypeArray) -> TokenStream{ + quote! { + #ident: <#ty as CSAllocatable>::placeholder_witness(), + } +} + +pub(crate) fn derive_witness_struct_recursive(derived_input: DeriveInput) -> DeriveInput{ + let DeriveInput { + attrs: _attrs, + vis, + ident, + generics, + mut data, + .. + } = derived_input; + + let comma = Comma(Span::call_site()); + + match data { + Data::Struct(ref mut struct_data) => { + match struct_data.fields { + // we only use named fields for now + Fields::Named(ref mut fields) => { + for field in fields.named.iter_mut() { + let (new_ty, derive_hint) = get_equivalent_type_recursive(&field.ty); + field.ty = new_ty; + match derive_hint { + SerdeDeriveToUse::Default => { + // let att: Attribute = syn::parse_quote! { + // #[serde(bound = "")] + // }; + // field.attrs.push(att); + }, + SerdeDeriveToUse::BigArray => { + let att: Attribute = syn::parse_quote! { + #[serde(with = "crate::serde_utils::BigArraySerde")] + }; + field.attrs.push(att); + } + } + } + }, + _ => abort_call_site!("only named fields are allowed"), + } + }, + _ => abort_call_site!("only structs are allowed"), + }; + + let punc_generic_params = get_type_params_from_generics_output_params(&generics, &comma); + + let new_generics = Generics { + lt_token: generics.lt_token, + params: punc_generic_params, + gt_token: generics.gt_token, + where_clause: generics.where_clause, + }; + + let witness_ident = get_witness_ident(&ident); + + DeriveInput { + attrs: vec![], + vis: vis, + ident: witness_ident, + generics: new_generics, + data: data, + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub(crate) enum SerdeDeriveToUse { + Default, + BigArray +} + +// we assume that every type implements a trait +pub(crate) fn get_equivalent_type_recursive(original_ty: &Type) -> (Type, SerdeDeriveToUse) { + match original_ty { + Type::Array(ty) => { + let ts = quote! { + <#ty as CSAllocatable>::Witness + }; + let ts = proc_macro::TokenStream::from(ts); + (Type::Path(syn::parse::(ts).unwrap()), SerdeDeriveToUse::BigArray) + }, + Type::Path(ty) => { + let ts = quote! { + <#ty as CSAllocatable>::Witness + }; + let ts = proc_macro::TokenStream::from(ts); + (Type::Path(syn::parse::(ts).unwrap()), SerdeDeriveToUse::Default) + } + _ => abort_call_site!("only array and path types are allowed"), + } +} \ No newline at end of file diff --git a/crates/zkevm_circuits/cs_derive/src/lib.rs b/crates/zkevm_circuits/cs_derive/src/lib.rs new file mode 100644 index 0000000..b136eec --- /dev/null +++ b/crates/zkevm_circuits/cs_derive/src/lib.rs @@ -0,0 +1,100 @@ +use proc_macro::TokenStream; + +pub(crate) mod utils; +mod selectable; +mod allocatable; +mod witness_hook; +mod var_length_encodable; + +#[proc_macro_derive(CSSelectable, attributes(CSSelectableBound))] +#[proc_macro_error::proc_macro_error] +pub fn derive_selectable(input: TokenStream) -> TokenStream{ + self::selectable::derive_select(input) +} + +#[proc_macro_derive(CSAllocatable)] +#[proc_macro_error::proc_macro_error] +pub fn derive_allocatable(input: TokenStream) -> TokenStream{ + self::allocatable::derive_allocatable(input) +} + +#[proc_macro_derive(WitnessHookable, attributes(WitnessHookBound))] +#[proc_macro_error::proc_macro_error] +pub fn derive_witness_hook(input: TokenStream) -> TokenStream{ + self::witness_hook::derive_witness_hook(input) +} + +#[proc_macro_derive(CSVarLengthEncodable)] +#[proc_macro_error::proc_macro_error] +pub fn derive_var_length_encodable(input: TokenStream) -> TokenStream{ + self::var_length_encodable::derive_var_length_encodable(input) +} + +// #[proc_macro_derive(CSOrdering)] +// pub fn derive_ord(input: TokenStream) -> TokenStream{ +// self::ord::derive_ord(input) +// } + +// #[proc_macro_derive(CSOrthogonalSelectable)] +// pub fn derive_orthogonal_select(input: TokenStream) -> TokenStream{ +// self::orth_select::derive_orthogonal_select(input) +// } + +// #[proc_macro_derive(FixedLengthEncodableExt, attributes(EncodingLength, PackWithCS))] +// pub fn derive_encodable(input: TokenStream) -> TokenStream{ +// self::fixed_encodable::derive_encodable(input) +// } +// #[proc_macro_derive(FixedLengthDecodableExt, attributes(EncodingLength))] +// pub fn derive_decodable(input: TokenStream) -> TokenStream{ +// self::fixed_decodable::derive_decodable(input) +// } + +// mod witnessable; +// #[proc_macro_derive(CSWitnessable)] +// pub fn derive_witnessable(input: TokenStream) -> TokenStream{ +// self::witnessable::derive_witnessable(input) +// } + + + +// mod packable; +// #[proc_macro_derive(CSPackable)] +// pub fn derive_packable(input: TokenStream) -> TokenStream{ +// let mut _ts = proc_macro2::TokenStream::new(); +// let derived_input = self::packable::derive_packable(input, &mut _ts); + +// derived_input +// } + +// mod encodable; +// #[proc_macro_derive(CSEncodable)] +// pub fn derive_cs_encodable(input: TokenStream) -> TokenStream{ +// let mut len_expr = proc_macro2::TokenStream::new(); +// let _ = self::packable::derive_packable(input.clone(), &mut len_expr); + +// self::encodable::derive_encodable(input, len_expr).into() +// } + +// mod decodable; +// #[proc_macro_derive(CSDecodable)] +// pub fn derive_cs_decodable(input: TokenStream) -> TokenStream{ +// let mut len_expr = proc_macro2::TokenStream::new(); +// let _ = self::packable::derive_packable(input.clone(), &mut len_expr); + +// self::decodable::derive_decodable(input, len_expr).into() +// } + +// mod var_encodable; +// #[proc_macro_derive(CSVariableLengthEncodable)] +// pub fn derive_cs_var_encodable(input: TokenStream) -> TokenStream{ +// let inner_impl: proc_macro2::TokenStream = self::packable::derive_var_packable(input.clone()).into(); +// let outer_impl: proc_macro2::TokenStream = self::var_encodable::derive_var_encodable(input).into(); + +// let expanded = quote::quote!{ +// #inner_impl + +// #outer_impl +// }; + +// proc_macro::TokenStream::from(expanded).into() +// } diff --git a/crates/zkevm_circuits/cs_derive/src/selectable/mod.rs b/crates/zkevm_circuits/cs_derive/src/selectable/mod.rs new file mode 100644 index 0000000..1ebdf95 --- /dev/null +++ b/crates/zkevm_circuits/cs_derive/src/selectable/mod.rs @@ -0,0 +1,105 @@ +use proc_macro2::{Span, TokenStream}; +use proc_macro_error::abort_call_site; +use quote::quote; +use syn::{ + Expr, + Ident, parse_macro_input, punctuated::Punctuated, token::Comma, DeriveInput, GenericParam, Generics, + Type, WhereClause, parse_quote, +}; + +use crate::utils::*; + +const BOUND_ATTR_NAME: &'static str = "CSSelectableBound"; + +pub(crate) fn derive_select(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + let derived_input = parse_macro_input!(input as DeriveInput); + let DeriveInput { + ident, + generics, + data, + attrs, + .. + } = derived_input.clone(); + + let mut struct_initializations = TokenStream::new(); + let mut field_selections = TokenStream::new(); + + let bound = if let Some(bound) = fetch_attr_from_list(BOUND_ATTR_NAME, &attrs) { + let bound = syn::parse_str::(&bound).expect("must parse bound as WhereClause"); + + quote! { #bound } + } else { + quote! { } + }; + + match data { + syn::Data::Struct(ref struct_data) => match struct_data.fields { + syn::Fields::Named(ref named_fields) => { + for field in named_fields.named.iter() { + let field_ident = field.ident.clone().expect("should have a field elem ident"); + match field.ty { + Type::Array(ref _array_ty) => { + let field_select = quote! { + let #field_ident = Selectable::::conditionally_select(cs, flag, &a.#field_ident, &b.#field_ident); + }; + field_selections.extend(field_select); + } + Type::Path(_) => { + let field_select = quote! { + let #field_ident = Selectable::::conditionally_select(cs, flag, &a.#field_ident, &b.#field_ident); + }; + field_selections.extend(field_select); + } + _ => abort_call_site!("only array and path types are allowed"), + }; + + let init_field = quote! { + #field_ident, + }; + + struct_initializations.extend(init_field); + } + } + _ => abort_call_site!("only named fields are allowed!"), + }, + _ => abort_call_site!("only struct types are allowed!"), + } + + let comma = Comma(Span::call_site()); + + let field_generic_param = syn::parse_str::(&"F: SmallField").unwrap(); + let has_engine_param = has_proper_small_field_parameter(&generics.params, &field_generic_param); + if has_engine_param == false { + panic!("Expected to have `F: SmallField` somewhere in bounds"); + } + + // add CS to func generic params + let mut function_generic_params = Punctuated::new(); + let cs_generic_param = syn::parse_str::(&"CS: ConstraintSystem").unwrap(); + function_generic_params.push(cs_generic_param.clone()); + function_generic_params.push_punct(comma.clone()); + + let type_params_of_allocated_struct = get_type_params_from_generics(&generics, &comma); + + let function_generics = Generics { + lt_token: Some(syn::token::Lt(Span::call_site())), + params: function_generic_params, + gt_token: Some(syn::token::Gt(Span::call_site())), + where_clause: None, + }; + + + let expanded = quote! { + impl #generics Selectable for #ident<#type_params_of_allocated_struct> #bound { + fn conditionally_select #function_generics(cs: &mut CS, flag: Boolean, a: &Self, b: &Self) -> Self { + #field_selections + + Self { + #struct_initializations + } + } + } + }; + + proc_macro::TokenStream::from(expanded) +} diff --git a/crates/zkevm_circuits/cs_derive/src/utils.rs b/crates/zkevm_circuits/cs_derive/src/utils.rs new file mode 100644 index 0000000..7c076c5 --- /dev/null +++ b/crates/zkevm_circuits/cs_derive/src/utils.rs @@ -0,0 +1,167 @@ +use quote::__private::ext::RepToTokensExt; +use syn::punctuated::Punctuated; +use syn::{GenericParam, TypeParamBound, Generics, Ident}; + +/// Fetch an attribute string from the derived struct. +pub(crate) fn fetch_attr(name: &str, attrs: &[syn::Attribute]) -> Option { + for attr in attrs { + if let Ok(meta) = attr.parse_meta() { + match meta { + syn::Meta::NameValue(nv) => { + if nv.path.is_ident(name) { + match nv.lit { + syn::Lit::Str(ref s) =>{ + return Some(s.value()) + }, + _ => panic!("attribute {} not found", name) + } + } + } + _ => panic!("attribute {} not found", name) + } + } + } + + None +} + + +pub(crate) fn fetch_attr_from_list(name: &str, attrs: &[syn::Attribute]) -> Option { + for attr in attrs { + if attr.path.is_ident(name) { + if let Ok(meta) = attr.parse_meta() { + match meta { + syn::Meta::List(ml) => { + if let Some(nv) = ml.nested.first() { + match nv { + syn::NestedMeta::Lit( + nl + ) => { + match nl { + syn::Lit::Str(ref s) =>{ + return Some(s.value()) + }, + _ => {} + } + } + _ => {} + } + } + }, + _ => {} + } + + } + } + } + + None +} + +pub(crate) fn fetch_attr_nopanic(name: &str, attrs: &[syn::Attribute]) -> Option { + for attr in attrs { + if let Ok(meta) = attr.parse_meta() { + match meta { + syn::Meta::NameValue(nv) => { + if nv.path.is_ident(name) { + match nv.lit { + syn::Lit::Str(ref s) =>{ + return Some(s.value()) + }, + _ => {} + } + } + } + _ => {} + } + } + } + + None +} + +pub(crate) fn has_proper_small_field_parameter

( + generic_params: &Punctuated, + expected: &GenericParam +) -> bool { + for p in generic_params.iter() { + if p == expected { + return true; + } + } + return false; +} + +pub(crate) fn get_type_params_from_generics( + generics: &Generics, + punc: &P, +) -> Punctuated { + let type_params = generics.type_params(); + let const_params = generics.const_params(); + + let mut idents = Punctuated::new(); + + for param in type_params.into_iter() { + let ident = param.ident.clone(); + idents.push(ident); + idents.push_punct(punc.clone()); + } + + for param in const_params.into_iter() { + let ident = param.ident.clone(); + idents.push(ident.clone()); + idents.push_punct(punc.clone()); + } + + idents +} + +pub(crate) fn get_witness_ident(original_ident: &Ident) -> Ident{ + let mut witness_ident_str = original_ident.to_string(); + witness_ident_str.push_str(&"Witness"); + syn::parse_str(&witness_ident_str).unwrap() +} + + +pub(crate) fn get_type_params_from_generics_output_params( + generics: &Generics, + punc: &P, +) -> Punctuated { + let type_params = generics.type_params(); + let const_params = generics.const_params(); + + let mut idents = Punctuated::new(); + + for param in type_params.into_iter() { + idents.push(GenericParam::Type(param.clone())); + idents.push_punct(punc.clone()); + } + + for param in const_params.into_iter() { + idents.push(GenericParam::Const(param.clone())); + idents.push_punct(punc.clone()); + } + + idents +} + +// pub(crate) fn has_small_field_parameter

( - generic_params: &Punctuated, - expected: &GenericParam -) -> bool { - for p in generic_params.iter() { - if p == expected { - return true; - } - } - return false; -} - -pub(crate) fn get_type_params_from_generics( - generics: &Generics, - punc: &P, -) -> Punctuated { - let type_params = generics.type_params(); - let const_params = generics.const_params(); - - let mut idents = Punctuated::new(); - - for param in type_params.into_iter() { - let ident = param.ident.clone(); - idents.push(ident); - idents.push_punct(punc.clone()); - } - - for param in const_params.into_iter() { - let ident = param.ident.clone(); - idents.push(ident.clone()); - idents.push_punct(punc.clone()); - } - - idents -} - -pub(crate) fn get_witness_ident(original_ident: &Ident) -> Ident{ - let mut witness_ident_str = original_ident.to_string(); - witness_ident_str.push_str(&"Witness"); - syn::parse_str(&witness_ident_str).unwrap() -} - - -pub(crate) fn get_type_params_from_generics_output_params( - generics: &Generics, - punc: &P, -) -> Punctuated { - let type_params = generics.type_params(); - let const_params = generics.const_params(); - - let mut idents = Punctuated::new(); - - for param in type_params.into_iter() { - idents.push(GenericParam::Type(param.clone())); - idents.push_punct(punc.clone()); - } - - for param in const_params.into_iter() { - idents.push(GenericParam::Const(param.clone())); - idents.push_punct(punc.clone()); - } - - idents -} - -// pub(crate) fn has_small_field_parameter

( -// generic_params: &Punctuated, -// ) -> bool { -// for p in generic_params.iter() { -// match p { -// GenericParam::Type(ty) => { -// for bound in ty.bounds.iter() { -// match bound { -// TypeParamBound::Trait(t) => { - -// }, -// _ => {} -// } -// } -// } -// _ => {} -// } -// } -// return false; -// } \ No newline at end of file diff --git a/crates/zkevm_circuits/cs_derive/src/var_length_encodable/mod.rs b/crates/zkevm_circuits/cs_derive/src/var_length_encodable/mod.rs deleted file mode 100644 index 6a753ab..0000000 --- a/crates/zkevm_circuits/cs_derive/src/var_length_encodable/mod.rs +++ /dev/null @@ -1,110 +0,0 @@ -use proc_macro2::{Span, TokenStream}; -use proc_macro_error::abort_call_site; -use quote::quote; -use syn::{ - Expr, - Ident, parse_macro_input, punctuated::Punctuated, token::Comma, DeriveInput, GenericParam, Generics, - Type, WhereClause, parse_quote, -}; - -use crate::utils::*; - -// const BOUND_ATTR_NAME: &'static str = "CSSelectableBound"; - -pub(crate) fn derive_var_length_encodable(input: proc_macro::TokenStream) -> proc_macro::TokenStream { - let derived_input = parse_macro_input!(input as DeriveInput); - let DeriveInput { - ident, - generics, - data, - .. - } = derived_input.clone(); - - let mut length_impls = TokenStream::new(); - let mut field_impls = TokenStream::new(); - - // let bound = if let Some(bound) = fetch_attr_from_list(BOUND_ATTR_NAME, &attrs) { - // let bound = syn::parse_str::(&bound).expect("must parse bound as WhereClause"); - - // quote! { #bound } - // } else { - // quote! { } - // }; - - match data { - syn::Data::Struct(ref struct_data) => match struct_data.fields { - syn::Fields::Named(ref named_fields) => { - for field in named_fields.named.iter() { - let field_ident = field.ident.clone().expect("should have a field elem ident"); - match field.ty { - Type::Array(ref _array_ty) => { - let field_impl = quote! { - total_len += CircuitVarLengthEncodable::::encoding_length(&self.#field_ident); - }; - length_impls.extend(field_impl); - - let field_impl = quote! { - CircuitVarLengthEncodable::::encode_to_buffer(&self.#field_ident, cs, dst); - }; - field_impls.extend(field_impl); - } - Type::Path(_) => { - let field_impl = quote! { - total_len += CircuitVarLengthEncodable::::encoding_length(&self.#field_ident); - }; - length_impls.extend(field_impl); - let field_impl = quote! { - CircuitVarLengthEncodable::::encode_to_buffer(&self.#field_ident, cs, dst); - }; - field_impls.extend(field_impl); - } - _ => abort_call_site!("only array and path types are allowed"), - }; - } - } - _ => abort_call_site!("only named fields are allowed!"), - }, - _ => abort_call_site!("only struct types are allowed!"), - } - - let comma = Comma(Span::call_site()); - - let field_generic_param = syn::parse_str::(&"F: SmallField").unwrap(); - let has_engine_param = has_proper_small_field_parameter(&generics.params, &field_generic_param); - if has_engine_param == false { - panic!("Expected to have `F: SmallField` somewhere in bounds"); - } - - // add CS to func generic params - let mut function_generic_params = Punctuated::new(); - let cs_generic_param = syn::parse_str::(&"CS: ConstraintSystem").unwrap(); - function_generic_params.push(cs_generic_param.clone()); - function_generic_params.push_punct(comma.clone()); - - let type_params_of_allocated_struct = get_type_params_from_generics(&generics, &comma); - - let function_generics = Generics { - lt_token: Some(syn::token::Lt(Span::call_site())), - params: function_generic_params, - gt_token: Some(syn::token::Gt(Span::call_site())), - where_clause: None, - }; - - - let expanded = quote! { - impl #generics CircuitVarLengthEncodable for #ident<#type_params_of_allocated_struct> { - #[inline(always)] - fn encoding_length(&self) -> usize { - let mut total_len = 0; - #length_impls; - - total_len - } - fn encode_to_buffer>(&self, cs: &mut CS, dst: &mut Vec) { - #field_impls - } - } - }; - - proc_macro::TokenStream::from(expanded) -} diff --git a/crates/zkevm_circuits/cs_derive/src/witness_hook/mod.rs b/crates/zkevm_circuits/cs_derive/src/witness_hook/mod.rs deleted file mode 100644 index e6fa1a6..0000000 --- a/crates/zkevm_circuits/cs_derive/src/witness_hook/mod.rs +++ /dev/null @@ -1,124 +0,0 @@ -use proc_macro2::{Span, TokenStream}; -use proc_macro_error::abort_call_site; -use quote::quote; -use syn::{ - Expr, - Ident, parse_macro_input, punctuated::Punctuated, token::Comma, DeriveInput, GenericParam, Generics, - Type, WhereClause, parse_quote, -}; - -use crate::utils::*; - -const BOUND_ATTR_NAME: &'static str = "WitnessHookBound"; - -pub(crate) fn derive_witness_hook(input: proc_macro::TokenStream) -> proc_macro::TokenStream { - let derived_input = parse_macro_input!(input as DeriveInput); - let DeriveInput { - ident, - generics, - data, - attrs, - .. - } = derived_input.clone(); - - let mut struct_initializations = TokenStream::new(); - let mut field_selections = TokenStream::new(); - let mut field_callings = TokenStream::new(); - - let bound = if let Some(bound) = fetch_attr_from_list(BOUND_ATTR_NAME, &attrs) { - let bound = syn::parse_str::(&bound).expect("must parse bound as WhereClause"); - - quote! { #bound } - } else { - quote! { } - }; - - match data { - syn::Data::Struct(ref struct_data) => match struct_data.fields { - syn::Fields::Named(ref named_fields) => { - for field in named_fields.named.iter() { - let field_ident = field.ident.clone().expect("should have a field elem ident"); - match field.ty { - Type::Array(ref _array_ty) => { - let field_select = quote! { - let #field_ident = WitnessHookable::::witness_hook(&self.#field_ident, cs); - }; - field_selections.extend(field_select); - let field_calling = quote! { - let #field_ident = (#field_ident)()?; - }; - field_callings.extend(field_calling); - } - Type::Path(_) => { - let field_select = quote! { - let #field_ident = WitnessHookable::::witness_hook(&self.#field_ident, cs); - }; - field_selections.extend(field_select); - let field_calling = quote! { - let #field_ident = (#field_ident)()?; - }; - field_callings.extend(field_calling); - } - _ => abort_call_site!("only array and path types are allowed"), - }; - - let init_field = quote! { - #field_ident, - }; - - struct_initializations.extend(init_field); - } - } - _ => abort_call_site!("only named fields are allowed!"), - }, - _ => abort_call_site!("only struct types are allowed!"), - } - - let comma = Comma(Span::call_site()); - - let field_generic_param = syn::parse_str::(&"F: SmallField").unwrap(); - let has_engine_param = has_proper_small_field_parameter(&generics.params, &field_generic_param); - if has_engine_param == false { - panic!("Expected to have `F: SmallField` somewhere in bounds"); - } - - // add CS to func generic params - let mut function_generic_params = Punctuated::new(); - let cs_generic_param = syn::parse_str::(&"CS: ConstraintSystem").unwrap(); - function_generic_params.push(cs_generic_param.clone()); - function_generic_params.push_punct(comma.clone()); - - let type_params_of_allocated_struct = get_type_params_from_generics(&generics, &comma); - - let function_generics = Generics { - lt_token: Some(syn::token::Lt(Span::call_site())), - params: function_generic_params, - gt_token: Some(syn::token::Gt(Span::call_site())), - where_clause: None, - }; - - let expanded = quote! { - impl #generics WitnessHookable for #ident<#type_params_of_allocated_struct> #bound { - fn witness_hook #function_generics( - &self, - cs: &CS, - ) -> Box Option + 'static> { - #field_selections; - - Box::new( - move || { - #field_callings; - - Some( - Self::Witness { - #struct_initializations - } - ) - } - ) - } - } - }; - - proc_macro::TokenStream::from(expanded) -} diff --git a/crates/zkevm_circuits/src/base_structures/register/mod.rs b/crates/zkevm_circuits/src/base_structures/register/mod.rs index 12a33db..780e1c1 100644 --- a/crates/zkevm_circuits/src/base_structures/register/mod.rs +++ b/crates/zkevm_circuits/src/base_structures/register/mod.rs @@ -54,6 +54,26 @@ impl VMRegister { }, } } + + pub fn conditionally_erase>( + &mut self, + cs: &mut CS, + condition: Boolean, + ) { + self.is_pointer = self.is_pointer.mask_negated(cs, condition); + self.value = self.value.mask_negated(cs, condition); + } + + pub fn conditionally_erase_fat_pointer_data>( + &mut self, + cs: &mut CS, + condition: Boolean, + ) { + self.is_pointer = self.is_pointer.mask_negated(cs, condition); + // we need to erase bits 32-64 and 64-96 + self.value.inner[1] = self.value.inner[1].mask_negated(cs, condition); + self.value.inner[2] = self.value.inner[2].mask_negated(cs, condition); + } } impl CSAllocatableExt for VMRegister { diff --git a/crates/zkevm_circuits/src/code_unpacker_sha256/mod.rs b/crates/zkevm_circuits/src/code_unpacker_sha256/mod.rs index 5c555a0..2be44fd 100644 --- a/crates/zkevm_circuits/src/code_unpacker_sha256/mod.rs +++ b/crates/zkevm_circuits/src/code_unpacker_sha256/mod.rs @@ -443,6 +443,8 @@ fn decompose_uint32_to_uint16s>( #[cfg(test)] mod tests { + use std::alloc::Global; + use crate::base_structures::decommit_query; use super::*; @@ -542,12 +544,12 @@ mod tests { use boojum::cs::cs_builder_reference::CsReferenceImplementationBuilder; let builder_impl = - CsReferenceImplementationBuilder::::new(geometry, 1 << 26, 1 << 20); + CsReferenceImplementationBuilder::::new(geometry, 1 << 20); use boojum::cs::cs_builder::new_builder; let builder = new_builder::<_, F>(builder_impl); let builder = configure(builder); - let mut owned_cs = builder.build(()); + let mut owned_cs = builder.build(1 << 26); let table = create_maj4_table(); owned_cs.add_lookup_table::(table); @@ -611,7 +613,7 @@ mod tests { cs.pad_and_shrink(); let worker = Worker::new(); - let mut owned_cs = owned_cs.into_assembly(); + let mut owned_cs = owned_cs.into_assembly::(); owned_cs.print_gate_stats(); assert!(owned_cs.check_if_satisfied(&worker)); } diff --git a/crates/zkevm_circuits/src/demux_log_queue/input.rs b/crates/zkevm_circuits/src/demux_log_queue/input.rs index 119a5fc..f2f324c 100644 --- a/crates/zkevm_circuits/src/demux_log_queue/input.rs +++ b/crates/zkevm_circuits/src/demux_log_queue/input.rs @@ -16,6 +16,8 @@ use boojum::gadgets::{ use cs_derive::*; use derivative::*; +pub const NUM_OUTPUT_QUEUES: usize = 6; + #[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] #[derivative(Clone, Copy, Debug)] #[DerivePrettyComparison("true")] @@ -83,6 +85,19 @@ impl CSPlaceholder for LogDemuxerOutputData { } } +impl LogDemuxerOutputData { + pub fn all_output_queues_refs(&self) -> [&QueueState; NUM_OUTPUT_QUEUES] { + [ + &self.storage_access_queue_state, + &self.keccak256_access_queue_state, + &self.sha256_access_queue_state, + &self.ecrecover_access_queue_state, + &self.events_access_queue_state, + &self.l1messages_access_queue_state, + ] + } +} + pub type LogDemuxerInputOutput = crate::fsm_input_output::ClosedFormInput< F, LogDemuxerFSMInputOutput, diff --git a/crates/zkevm_circuits/src/demux_log_queue/mod.rs b/crates/zkevm_circuits/src/demux_log_queue/mod.rs index 438bf11..81cc1b2 100644 --- a/crates/zkevm_circuits/src/demux_log_queue/mod.rs +++ b/crates/zkevm_circuits/src/demux_log_queue/mod.rs @@ -459,6 +459,8 @@ pub fn check_if_bitmask_and_if_empty, con #[cfg(test)] mod tests { + use std::alloc::Global; + use super::*; use boojum::algebraic_props::poseidon2_parameters::Poseidon2GoldilocksExternalMatrix; use boojum::cs::traits::gate::GatePlacementStrategy; @@ -551,12 +553,12 @@ mod tests { use boojum::cs::cs_builder_reference::CsReferenceImplementationBuilder; let builder_impl = - CsReferenceImplementationBuilder::::new(geometry, 1 << 26, 1 << 20); + CsReferenceImplementationBuilder::::new(geometry, 1 << 20); use boojum::cs::cs_builder::new_builder; let builder = new_builder::<_, F>(builder_impl); let builder = configure(builder); - let mut owned_cs = builder.build(()); + let mut owned_cs = builder.build(1 << 26); // add tables let table = create_xor8_table(); @@ -592,7 +594,7 @@ mod tests { cs.pad_and_shrink(); let worker = Worker::new(); - let mut owned_cs = owned_cs.into_assembly(); + let mut owned_cs = owned_cs.into_assembly::(); owned_cs.print_gate_stats(); assert!(owned_cs.check_if_satisfied(&worker)); } diff --git a/crates/zkevm_circuits/src/ecrecover/baseline.rs b/crates/zkevm_circuits/src/ecrecover/baseline.rs index 1e01607..f688efb 100644 --- a/crates/zkevm_circuits/src/ecrecover/baseline.rs +++ b/crates/zkevm_circuits/src/ecrecover/baseline.rs @@ -675,6 +675,8 @@ where #[cfg(test)] mod test { + use std::alloc::Global; + use boojum::field::goldilocks::GoldilocksField; use boojum::gadgets::traits::allocatable::CSAllocatable; use boojum::pairing::ff::{Field, PrimeField, SqrtField}; @@ -776,7 +778,6 @@ mod test { num_constant_columns: 8, max_allowed_constraint_degree: 4, }; - let max_variables = 1 << 26; let max_trace_len = 1 << 20; fn configure< @@ -841,15 +842,12 @@ mod test { builder } - let builder_impl = CsReferenceImplementationBuilder::::new( - geometry, - max_variables, - max_trace_len, - ); + let builder_impl = + CsReferenceImplementationBuilder::::new(geometry, max_trace_len); let builder = new_builder::<_, F>(builder_impl); let builder = configure(builder); - let mut owned_cs = builder.build(()); + let mut owned_cs = builder.build(1 << 26); // add tables let table = create_xor8_table(); @@ -929,7 +927,7 @@ mod test { cs.pad_and_shrink(); - let mut cs = owned_cs.into_assembly(); + let mut cs = owned_cs.into_assembly::(); cs.print_gate_stats(); let worker = Worker::new(); assert!(cs.check_if_satisfied(&worker)); diff --git a/crates/zkevm_circuits/src/ecrecover/decomp_table.rs b/crates/zkevm_circuits/src/ecrecover/decomp_table.rs index 636b64e..7c7ea6e 100644 --- a/crates/zkevm_circuits/src/ecrecover/decomp_table.rs +++ b/crates/zkevm_circuits/src/ecrecover/decomp_table.rs @@ -11,10 +11,10 @@ const TABLE_NAME: &'static str = "WNAFDECOMP table"; #[derivative(Clone, Copy, Debug, PartialEq, Eq)] pub struct WnafDecompTable; -const GLV_WINDOW_SIZE: usize = 2; -const TABLE_SIZE: i8 = 1 << (GLV_WINDOW_SIZE + 1); -const HALF_TABLE_SIZE: i8 = 1 << GLV_WINDOW_SIZE; -const MASK_FOR_MOD_TABLE_SIZE: u8 = (TABLE_SIZE as u8) - 1; +pub const WNAF_WINDOW_SIZE: usize = 2; +pub const WNAF_TABLE_SIZE: i8 = 1 << (WNAF_WINDOW_SIZE + 1); +const HALF_TABLE_SIZE: i8 = 1 << WNAF_WINDOW_SIZE; +const MASK_FOR_MOD_TABLE_SIZE: u8 = (WNAF_TABLE_SIZE as u8) - 1; // Lookups for wNAF decomposition of scalars. pub fn create_wnaf_decomp_table() -> LookupTable { @@ -35,7 +35,7 @@ pub fn create_wnaf_decomp_table() -> LookupTable { if a % 2 == 1 { let mut naf = (a & MASK_FOR_MOD_TABLE_SIZE) as i8; if naf >= HALF_TABLE_SIZE { - naf -= TABLE_SIZE + naf -= WNAF_TABLE_SIZE }; let naf_abs = naf.abs() as u8; diff --git a/crates/zkevm_circuits/src/ecrecover/mod.rs b/crates/zkevm_circuits/src/ecrecover/mod.rs index 7316c0b..9ed10e6 100644 --- a/crates/zkevm_circuits/src/ecrecover/mod.rs +++ b/crates/zkevm_circuits/src/ecrecover/mod.rs @@ -70,4 +70,4 @@ fn secp256k1_scalar_field_params() -> Secp256ScalarNNFieldParams { } // re-exports for integration -pub use self::baseline::{ecrecover_function_entry_point, EcrecoverPrecompileCallParams}; +pub use self::new_optimized::{ecrecover_function_entry_point, EcrecoverPrecompileCallParams}; diff --git a/crates/zkevm_circuits/src/ecrecover/naf_abs_div2_table.rs b/crates/zkevm_circuits/src/ecrecover/naf_abs_div2_table.rs index e83dd9a..3cdd006 100644 --- a/crates/zkevm_circuits/src/ecrecover/naf_abs_div2_table.rs +++ b/crates/zkevm_circuits/src/ecrecover/naf_abs_div2_table.rs @@ -27,7 +27,7 @@ pub fn create_naf_abs_div2_table() -> LookupTable { // we need unsigned abs, to handle i8::MIN let v = a.unsigned_abs() >> 1; - smallvec::smallvec![F::from_u64_unchecked(v as u64), F::from_u64_unchecked(0u64)] + smallvec::smallvec![F::from_u64_unchecked(v as u64), F::ZERO] }, ) } diff --git a/crates/zkevm_circuits/src/ecrecover/new_optimized.rs b/crates/zkevm_circuits/src/ecrecover/new_optimized.rs index 6d8d548..646d17f 100644 --- a/crates/zkevm_circuits/src/ecrecover/new_optimized.rs +++ b/crates/zkevm_circuits/src/ecrecover/new_optimized.rs @@ -50,7 +50,7 @@ pub use self::input::*; use super::input::*; pub const MEMORY_QUERIES_PER_CALL: usize = 4; -pub const ALLOW_ZERO_MESSAGE: bool = false; +pub const ALLOW_ZERO_MESSAGE: bool = true; #[derive(Derivative, CSSelectable)] #[derivative(Clone, Debug)] @@ -81,7 +81,7 @@ impl EcrecoverPrecompileCallParams { const NUM_WORDS: usize = 17; const SECP_B_COEF: u64 = 7; -const EXCEPTION_FLAGS_ARR_LEN: usize = 9; +const EXCEPTION_FLAGS_ARR_LEN: usize = 10; const NUM_MEMORY_READS_PER_CYCLE: usize = 4; const X_POWERS_ARR_LEN: usize = 256; const VALID_Y_IN_EXTERNAL_FIELD: u64 = 4; @@ -89,8 +89,8 @@ const VALID_X_CUBED_IN_EXTERNAL_FIELD: u64 = 9; // GLV consts -// 2**128 -const TWO_POW_128: &'static str = "340282366920938463463374607431768211456"; +// Decomposition scalars can be a little more than 2^128 in practice, so we use 33 chunks of width 4 bits +const MAX_DECOMPOSITION_VALUE: U256 = U256([u64::MAX, u64::MAX, 0x0f, 0]); // BETA s.t. for any curve point Q = (x,y): // lambda * Q = (beta*x mod p, y) const BETA: &'static str = @@ -106,6 +106,13 @@ const A1: &'static str = "0x3086d221a7d46bcde86c90e49284eb15"; const B1: &'static str = "0xe4437ed6010e88286f547fa90abfe4c3"; const A2: &'static str = "0x114ca50f7a8e2f3f657c1108d9d44cfd8"; +const HALF_SUBGROUP_SIZE: &'static str = + "7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0"; + +const WINDOW_WIDTH: usize = 4; +const NUM_MULTIPLICATION_STEPS_FOR_WIDTH_4: usize = 33; +const PRECOMPUTATION_TABLE_SIZE: usize = (1 << WINDOW_WIDTH) - 1; + // assume that constructed field element is not zero // if this is not satisfied - set the result to be F::one fn convert_uint256_to_field_element_masked< @@ -141,6 +148,7 @@ where let (overflows, rem) = max_value.div_rem(¶ms.modulus_u1024); + assert!(overflows.lt(&U1024::from_word(1u64 << 32))); let mut max_moduluses = overflows.as_words()[0] as u32; if rem.is_zero().unwrap_u8() != 1 { max_moduluses += 1; @@ -187,6 +195,7 @@ fn convert_uint256_to_field_element< max_value = max_value.saturating_sub(&U1024::from_word(1u64)); let (overflows, rem) = max_value.div_rem(¶ms.modulus_u1024); + assert!(overflows.lt(&U1024::from_word(1u64 << 32))); let mut max_moduluses = overflows.as_words()[0] as u32; if rem.is_zero().unwrap_u8() != 1 { max_moduluses += 1; @@ -316,6 +325,263 @@ fn to_wnaf>( naf } +fn width_4_windowed_multiplication>( + cs: &mut CS, + mut point: SWProjectivePoint>, + mut scalar: Secp256ScalarNNField, + base_field_params: &Arc, + scalar_field_params: &Arc, +) -> SWProjectivePoint> { + scalar.enforce_reduced(cs); + + let beta = Secp256Fq::from_str(BETA).unwrap(); + let mut beta = Secp256BaseNNField::allocated_constant(cs, beta, &base_field_params); + + let bigint_from_hex_str = |cs: &mut CS, s: &str| -> UInt512 { + let v = U256::from_str_radix(s, 16).unwrap(); + UInt512::allocated_constant(cs, (v, U256::zero())) + }; + + let modulus_minus_one_div_two = bigint_from_hex_str(cs, MODULUS_MINUS_ONE_DIV_TWO); + + let u256_from_hex_str = |cs: &mut CS, s: &str| -> UInt256 { + let v = U256::from_str_radix(s, 16).unwrap(); + UInt256::allocated_constant(cs, v) + }; + + let a1 = u256_from_hex_str(cs, A1); + let b1 = u256_from_hex_str(cs, B1); + let a2 = u256_from_hex_str(cs, A2); + let b2 = a1.clone(); + + let boolean_false = Boolean::allocated_constant(cs, false); + + // Scalar decomposition + let (k1_was_negated, k1, k2_was_negated, k2) = { + let k = convert_field_element_to_uint256(cs, scalar.clone()); + + // We take 8 non-zero limbs for the scalar (since it could be of any size), and 4 for B2 + // (since it fits in 128 bits). + let b2_times_k = k.widening_mul(cs, &b2, 8, 4); + // can not overflow u512 + let (b2_times_k, of) = b2_times_k.overflowing_add(cs, &modulus_minus_one_div_two); + Boolean::enforce_equal(cs, &of, &boolean_false); + let c1 = b2_times_k.to_high(); + + // We take 8 non-zero limbs for the scalar (since it could be of any size), and 4 for B1 + // (since it fits in 128 bits). + let b1_times_k = k.widening_mul(cs, &b1, 8, 4); + // can not overflow u512 + let (b1_times_k, of) = b1_times_k.overflowing_add(cs, &modulus_minus_one_div_two); + Boolean::enforce_equal(cs, &of, &boolean_false); + let c2 = b1_times_k.to_high(); + + let mut a1 = convert_uint256_to_field_element(cs, &a1, &scalar_field_params); + let mut b1 = convert_uint256_to_field_element(cs, &b1, &scalar_field_params); + let mut a2 = convert_uint256_to_field_element(cs, &a2, &scalar_field_params); + let mut b2 = a1.clone(); + let mut c1 = convert_uint256_to_field_element(cs, &c1, &scalar_field_params); + let mut c2 = convert_uint256_to_field_element(cs, &c2, &scalar_field_params); + + let mut c1_times_a1 = c1.mul(cs, &mut a1); + let mut c2_times_a2 = c2.mul(cs, &mut a2); + let mut k1 = scalar.sub(cs, &mut c1_times_a1).sub(cs, &mut c2_times_a2); + k1.normalize(cs); + let mut c2_times_b2 = c2.mul(cs, &mut b2); + let mut k2 = c1.mul(cs, &mut b1).sub(cs, &mut c2_times_b2); + k2.normalize(cs); + + let k1_u256 = convert_field_element_to_uint256(cs, k1.clone()); + let k2_u256 = convert_field_element_to_uint256(cs, k2.clone()); + let max_k1_or_k2 = UInt256::allocated_constant(cs, MAX_DECOMPOSITION_VALUE); + // we will need k1 and k2 to be < 2^128, so we can compare via subtraction + let (_res, k1_out_of_range) = max_k1_or_k2.overflowing_sub(cs, &k1_u256); + let k1_negated = k1.negated(cs); + // dbg!(k1.witness_hook(cs)()); + // dbg!(k1_negated.witness_hook(cs)()); + let k1 = as NonNativeField>::conditionally_select( + cs, + k1_out_of_range, + &k1_negated, + &k1, + ); + let (_res, k2_out_of_range) = max_k1_or_k2.overflowing_sub(cs, &k2_u256); + let k2_negated = k2.negated(cs); + // dbg!(k2.witness_hook(cs)()); + // dbg!(k2_negated.witness_hook(cs)()); + let k2 = as NonNativeField>::conditionally_select( + cs, + k2_out_of_range, + &k2_negated, + &k2, + ); + + (k1_out_of_range, k1, k2_out_of_range, k2) + }; + + // create precomputed table of size 1<<4 - 1 + // there is no 0 * P in the table, we will handle it below + let mut table = Vec::with_capacity(PRECOMPUTATION_TABLE_SIZE); + let mut tmp = point.clone(); + let (mut p_affine, _) = point.convert_to_affine_or_default(cs, Secp256Affine::one()); + table.push(p_affine.clone()); + for _ in 1..PRECOMPUTATION_TABLE_SIZE { + // 2P, 3P, ... + tmp = tmp.add_mixed(cs, &mut p_affine); + let (affine, _) = tmp.convert_to_affine_or_default(cs, Secp256Affine::one()); + table.push(affine); + } + assert_eq!(table.len(), PRECOMPUTATION_TABLE_SIZE); + + let mut endomorphisms_table = table.clone(); + for (x, _) in endomorphisms_table.iter_mut() { + *x = x.mul(cs, &mut beta); + } + + // we also know that we will multiply k1 by points, and k2 by their endomorphisms, and if they were + // negated above to fit into range, we negate bases here + for (_, y) in table.iter_mut() { + let negated = y.negated(cs); + *y = Selectable::conditionally_select(cs, k1_was_negated, &negated, &*y); + } + + for (_, y) in endomorphisms_table.iter_mut() { + let negated = y.negated(cs); + *y = Selectable::conditionally_select(cs, k2_was_negated, &negated, &*y); + } + + // now decompose every scalar we are interested in + let k1_msb_decomposition = to_width_4_window_form(cs, k1); + let k2_msb_decomposition = to_width_4_window_form(cs, k2); + + let mut comparison_constants = Vec::with_capacity(PRECOMPUTATION_TABLE_SIZE); + for i in 1..=PRECOMPUTATION_TABLE_SIZE { + let constant = Num::allocated_constant(cs, F::from_u64_unchecked(i as u64)); + comparison_constants.push(constant); + } + + // now we do amortized double and add + let mut acc = SWProjectivePoint::zero(cs, base_field_params); + assert_eq!( + k1_msb_decomposition.len(), + NUM_MULTIPLICATION_STEPS_FOR_WIDTH_4 + ); + assert_eq!( + k2_msb_decomposition.len(), + NUM_MULTIPLICATION_STEPS_FOR_WIDTH_4 + ); + + for (idx, (k1_window_idx, k2_window_idx)) in k1_msb_decomposition + .into_iter() + .zip(k2_msb_decomposition.into_iter()) + .enumerate() + { + let ignore_k1_part = k1_window_idx.is_zero(cs); + let ignore_k2_part = k2_window_idx.is_zero(cs); + + // dbg!(k1_window_idx.witness_hook(cs)()); + // dbg!(k2_window_idx.witness_hook(cs)()); + // dbg!(ignore_k1_part.witness_hook(cs)()); + // dbg!(ignore_k2_part.witness_hook(cs)()); + + let (mut selected_k1_part_x, mut selected_k1_part_y) = table[0].clone(); + let (mut selected_k2_part_x, mut selected_k2_part_y) = endomorphisms_table[0].clone(); + for i in 1..PRECOMPUTATION_TABLE_SIZE { + let should_select_k1 = Num::equals(cs, &comparison_constants[i], &k1_window_idx); + let should_select_k2 = Num::equals(cs, &comparison_constants[i], &k2_window_idx); + selected_k1_part_x = Selectable::conditionally_select( + cs, + should_select_k1, + &table[i].0, + &selected_k1_part_x, + ); + selected_k1_part_y = Selectable::conditionally_select( + cs, + should_select_k1, + &table[i].1, + &selected_k1_part_y, + ); + selected_k2_part_x = Selectable::conditionally_select( + cs, + should_select_k2, + &endomorphisms_table[i].0, + &selected_k2_part_x, + ); + selected_k2_part_y = Selectable::conditionally_select( + cs, + should_select_k2, + &endomorphisms_table[i].1, + &selected_k2_part_y, + ); + } + + // dbg!(selected_k1_part_x.witness_hook(cs)()); + // dbg!(selected_k1_part_y.witness_hook(cs)()); + + let tmp_acc = acc.add_mixed(cs, &mut (selected_k1_part_x, selected_k1_part_y)); + acc = Selectable::conditionally_select(cs, ignore_k1_part, &acc, &tmp_acc); + let tmp_acc = acc.add_mixed(cs, &mut (selected_k2_part_x, selected_k2_part_y)); + acc = Selectable::conditionally_select(cs, ignore_k2_part, &acc, &tmp_acc); + + // let ((x, y), _) = acc.convert_to_affine_or_default(cs, Secp256Affine::zero()); + // dbg!(x.witness_hook(cs)()); + // dbg!(y.witness_hook(cs)()); + + if idx != NUM_MULTIPLICATION_STEPS_FOR_WIDTH_4 - 1 { + for _ in 0..WINDOW_WIDTH { + acc = acc.double(cs); + } + } + } + + acc +} + +fn to_width_4_window_form>( + cs: &mut CS, + mut limited_width_scalar: Secp256ScalarNNField, +) -> Vec> { + limited_width_scalar.enforce_reduced(cs); + // we know that width is 128 bits, so just do BE decomposition and put into resulting array + let zero_num = Num::zero(cs); + for word in limited_width_scalar.limbs[9..].iter() { + let word = Num::from_variable(*word); + Num::enforce_equal(cs, &word, &zero_num); + } + + let byte_split_id = cs + .get_table_id_for_marker::>() + .expect("table should exist"); + let mut result = Vec::with_capacity(32); + // special case + { + let highest_word = limited_width_scalar.limbs[8]; + let word = unsafe { UInt16::from_variable_unchecked(highest_word) }; + let [high, low] = word.to_be_bytes(cs); + Num::enforce_equal(cs, &high.into_num(), &zero_num); + let [l, h] = cs.perform_lookup::<1, 2>(byte_split_id, &[low.get_variable()]); + Num::enforce_equal(cs, &Num::from_variable(h), &zero_num); + let l = Num::from_variable(l); + result.push(l); + } + + for word in limited_width_scalar.limbs[..8].iter().rev() { + let word = unsafe { UInt16::from_variable_unchecked(*word) }; + let [high, low] = word.to_be_bytes(cs); + for t in [high, low].into_iter() { + let [l, h] = cs.perform_lookup::<1, 2>(byte_split_id, &[t.get_variable()]); + let h = Num::from_variable(h); + let l = Num::from_variable(l); + result.push(h); + result.push(l); + } + } + assert_eq!(result.len(), NUM_MULTIPLICATION_STEPS_FOR_WIDTH_4); + + result +} + +#[deprecated] fn wnaf_scalar_mul>( cs: &mut CS, mut point: SWProjectivePoint>, @@ -325,8 +591,7 @@ fn wnaf_scalar_mul>( ) -> SWProjectivePoint> { scalar.enforce_reduced(cs); - let pow_2_128 = U256::from_dec_str(TWO_POW_128).unwrap(); - let pow_2_128 = UInt512::allocated_constant(cs, (pow_2_128, U256::zero())); + let pow_2_128 = UInt512::allocated_constant(cs, (U256([0, 0, 1, 0]), U256::zero())); let beta = Secp256Fq::from_str(BETA).unwrap(); let mut beta = Secp256BaseNNField::allocated_constant(cs, beta, &base_field_params); @@ -338,31 +603,37 @@ fn wnaf_scalar_mul>( let modulus_minus_one_div_two = bigint_from_hex_str(cs, MODULUS_MINUS_ONE_DIV_TWO); - // Scalar decomposition - let (k1_neg, k1, k2_neg, k2) = { - let u256_from_hex_str = |cs: &mut CS, s: &str| -> UInt256 { - let v = U256::from_str_radix(s, 16).unwrap(); - UInt256::allocated_constant(cs, v) - }; + let u256_from_hex_str = |cs: &mut CS, s: &str| -> UInt256 { + let v = U256::from_str_radix(s, 16).unwrap(); + UInt256::allocated_constant(cs, v) + }; - let a1 = u256_from_hex_str(cs, A1); - let b1 = u256_from_hex_str(cs, B1); - let a2 = u256_from_hex_str(cs, A2); - let b2 = a1.clone(); + let a1 = u256_from_hex_str(cs, A1); + let b1 = u256_from_hex_str(cs, B1); + let a2 = u256_from_hex_str(cs, A2); + let b2 = a1.clone(); + + let boolean_false = Boolean::allocated_constant(cs, false); + // Scalar decomposition + let (k1_neg, k1, k2_neg, k2) = { let k = convert_field_element_to_uint256(cs, scalar.clone()); // We take 8 non-zero limbs for the scalar (since it could be of any size), and 4 for B2 // (since it fits in 128 bits). let b2_times_k = k.widening_mul(cs, &b2, 8, 4); - let b2_times_k = b2_times_k.overflowing_add(cs, &modulus_minus_one_div_two); - let c1 = b2_times_k.0.to_high(); + // can not overflow u512 + let (b2_times_k, of) = b2_times_k.overflowing_add(cs, &modulus_minus_one_div_two); + Boolean::enforce_equal(cs, &of, &boolean_false); + let c1 = b2_times_k.to_high(); // We take 8 non-zero limbs for the scalar (since it could be of any size), and 4 for B1 // (since it fits in 128 bits). let b1_times_k = k.widening_mul(cs, &b1, 8, 4); - let b1_times_k = b1_times_k.overflowing_add(cs, &modulus_minus_one_div_two); - let c2 = b1_times_k.0.to_high(); + // can not overflow u512 + let (b1_times_k, of) = b1_times_k.overflowing_add(cs, &modulus_minus_one_div_two); + Boolean::enforce_equal(cs, &of, &boolean_false); + let c2 = b1_times_k.to_high(); let mut a1 = convert_uint256_to_field_element(cs, &a1, &scalar_field_params); let mut b1 = convert_uint256_to_field_element(cs, &b1, &scalar_field_params); @@ -404,10 +675,10 @@ fn wnaf_scalar_mul>( // WNAF // The scalar multiplication window size. - const GLV_WINDOW_SIZE: usize = 2; + use super::decomp_table::WNAF_WINDOW_SIZE; - // The GLV table length. - const L: usize = 1 << (GLV_WINDOW_SIZE - 1); + // The WNAF precomputation table length + const L: usize = 1 << (WNAF_WINDOW_SIZE - 1); let mut t1 = Vec::with_capacity(L); // We use `convert_to_affine_or_default`, but we don't need to worry about returning 1, since @@ -416,23 +687,26 @@ fn wnaf_scalar_mul>( .double(cs) .convert_to_affine_or_default(cs, Secp256Affine::one()); t1.push(point.clone()); + // we need 1P, 3P, 5P, ... for i in 1..L { let next = t1[i - 1].add_mixed(cs, &mut double); t1.push(next); } + // (x, y) let t1 = t1 .iter_mut() .map(|el| el.convert_to_affine_or_default(cs, Secp256Affine::one()).0) .collect::>(); + // (x*beta, y) let t2 = t1 .clone() .into_iter() .map(|mut el| (el.0.mul(cs, &mut beta), el.1)) .collect::>(); - let overflow_checker = UInt8::allocated_constant(cs, 2u8.pow(7)); + let overflow_checker = UInt8::allocated_constant(cs, 1 << 7); let decomp_id = cs .get_table_id_for_marker::() .expect("table should exist"); @@ -454,7 +728,22 @@ fn wnaf_scalar_mul>( cs.perform_lookup::<1, 2>(naf_abs_div2_table_id, &[naf.get_variable()])[0], ) }; - let coords = &table[index.witness_hook(cs)().unwrap() as usize]; + // We assume that only one of the values in the table will be selected (since the index + // <= table.len()) and so we can iteratively conditionally select over all elements. + let mut sanity_checks = vec![index.is_zero(cs)]; + let mut coords = table[0].clone(); + for (i, v) in table.iter().enumerate().skip(1) { + assert!((i as u8) < u8::MAX); + let const_idx: UInt8 = UInt8::allocated_constant(cs, i as u8); + let correct_idx = UInt8::equals(cs, &index, &const_idx); + sanity_checks.push(correct_idx); + coords.0 = Selectable::conditionally_select(cs, correct_idx, &v.0, &coords.0); + coords.1 = Selectable::conditionally_select(cs, correct_idx, &v.1, &coords.1); + } + let matched = Boolean::multi_or(cs, &sanity_checks); + let boolean_true = Boolean::allocated_constant(cs, true); + Boolean::enforce_equal(cs, &matched, &boolean_true); + let mut p_1 = SWProjectivePoint::>::from_xy_unchecked( cs, @@ -503,7 +792,7 @@ fn fixed_base_mul, F: SmallField>( SWProjectivePoint::>::zero(cs, base_field_params); let mut full_table_ids = vec![]; seq_macro::seq!(C in 0..32 { - let ids = vec![ + let ids = [ cs.get_table_id_for_marker::>() .expect("table must exist"), cs.get_table_id_for_marker::>() @@ -529,11 +818,6 @@ fn fixed_base_mul, F: SmallField>( .zip(bytes) .rev() .for_each(|(ids, byte)| { - // let chunks = ids - // .iter() - // .map(|id| cs.perform_lookup::<1, 2>(*id, &[byte.get_variable()])) - // .collect::>(); - let (x, y): (Vec, Vec) = ids .iter() .flat_map(|id| { @@ -575,7 +859,9 @@ fn fixed_base_mul, F: SmallField>( params: base_field_params.clone(), _marker: std::marker::PhantomData, }; - acc = acc.add_mixed(cs, &mut (x, y)); + let new_acc = acc.add_mixed(cs, &mut (x, y)); + let should_not_update = byte.is_zero(cs); + acc = Selectable::conditionally_select(cs, should_not_update, &acc, &new_acc); }); acc = Selectable::conditionally_select(cs, is_zero, &zero_point, &acc); acc @@ -638,6 +924,13 @@ fn ecrecover_precompile_inner_routine< let [y_is_odd, x_overflow, ..] = Num::::from_variable(recid.get_variable()).spread_into_bits::<_, 8>(cs); + // check convention s < N/2 + let s_upper_bound = + UInt256::allocated_constant(cs, U256::from_str_radix(HALF_SUBGROUP_SIZE, 16).unwrap()); + let (_, uf) = s.overflowing_sub(cs, &s_upper_bound); + let s_too_large = uf.negated(cs); + exception_flags.push(s_too_large); + let (r_plus_n, of) = r.overflowing_add(cs, &secp_n_u256); let mut x_as_u256 = UInt256::conditionally_select(cs, x_overflow, &r_plus_n, &r); let error = Boolean::multi_and(cs, &[x_overflow, of]); @@ -720,6 +1013,11 @@ fn ecrecover_precompile_inner_routine< may_be_recovered_y.normalize(cs); let may_be_recovered_y_negated = may_be_recovered_y.negated(cs); + if crate::config::CIRCUIT_VERSOBE { + dbg!(may_be_recovered_y.witness_hook(cs)()); + dbg!(may_be_recovered_y_negated.witness_hook(cs)()); + } + let [lowest_bit, ..] = Num::::from_variable(may_be_recovered_y.limbs[0]).spread_into_bits::<_, 16>(cs); @@ -753,15 +1051,24 @@ fn ecrecover_precompile_inner_routine< let mut message_hash_by_r_inv = message_hash_fe.mul(cs, &mut r_fe_inversed); s_by_r_inv.normalize(cs); - message_hash_by_r_inv.normalize(cs); + let mut message_hash_by_r_inv_negated = message_hash_by_r_inv.negated(cs); + message_hash_by_r_inv_negated.normalize(cs); // now we are going to compute the public key Q = (x, y) determined by the formula: // Q = (s * X - hash * G) / r which is equivalent to r * Q = s * X - hash * G + if crate::config::CIRCUIT_VERSOBE { + dbg!(x.witness_hook(cs)()); + dbg!(y.witness_hook(cs)()); + dbg!(s_by_r_inv.witness_hook(cs)()); + dbg!(message_hash_by_r_inv_negated.witness_hook(cs)()); + } + let recovered_point = SWProjectivePoint::>::from_xy_unchecked(cs, x, y); + // now we do multiplication - let mut s_times_x = wnaf_scalar_mul( + let mut s_times_x = width_4_windowed_multiplication( cs, recovered_point.clone(), s_by_r_inv.clone(), @@ -769,7 +1076,16 @@ fn ecrecover_precompile_inner_routine< &scalar_field_params, ); - let mut hash_times_g = fixed_base_mul(cs, message_hash_by_r_inv, &base_field_params); + // let mut s_times_x = wnaf_scalar_mul( + // cs, + // recovered_point.clone(), + // s_by_r_inv.clone(), + // &base_field_params, + // &scalar_field_params, + // ); + + let mut hash_times_g = fixed_base_mul(cs, message_hash_by_r_inv_negated, &base_field_params); + // let mut hash_times_g = fixed_base_mul(cs, message_hash_by_r_inv, &base_field_params); let (mut q_acc, is_infinity) = hash_times_g.convert_to_affine_or_default(cs, Secp256Affine::one()); @@ -782,6 +1098,11 @@ fn ecrecover_precompile_inner_routine< let zero_u8 = UInt8::zero(cs); + if crate::config::CIRCUIT_VERSOBE { + dbg!(q_x.witness_hook(cs)()); + dbg!(q_y.witness_hook(cs)()); + } + let mut bytes_to_hash = [zero_u8; 64]; let it = q_x.limbs[..16] .iter() @@ -966,6 +1287,15 @@ where let [message_hash_as_u256, v_as_u256, r_as_u256, s_as_u256] = read_values; let rec_id = v_as_u256.inner[0].to_le_bytes(cs)[0]; + if crate::config::CIRCUIT_VERSOBE { + if should_process.witness_hook(cs)().unwrap() == true { + dbg!(rec_id.witness_hook(cs)()); + dbg!(r_as_u256.witness_hook(cs)()); + dbg!(s_as_u256.witness_hook(cs)()); + dbg!(message_hash_as_u256.witness_hook(cs)()); + } + } + let (success, written_value) = ecrecover_precompile_inner_routine::<_, _, ALLOW_ZERO_MESSAGE>( cs, &rec_id, @@ -983,6 +1313,13 @@ where let mut success_as_u256 = zero_u256; success_as_u256.inner[0] = success_as_u32; + if crate::config::CIRCUIT_VERSOBE { + if should_process.witness_hook(cs)().unwrap() == true { + dbg!(success_as_u256.witness_hook(cs)()); + dbg!(written_value.witness_hook(cs)()); + } + } + let success_query = MemoryQuery { timestamp: timestamp_to_use_for_write, memory_page: precompile_call_params.output_page, @@ -1048,7 +1385,10 @@ where #[cfg(test)] mod test { + use std::alloc::Global; + use boojum::field::goldilocks::GoldilocksField; + use boojum::gadgets::non_native_field::implementations::implementation_u16::FFProxyValue; use boojum::gadgets::traits::allocatable::CSAllocatable; use boojum::pairing::ff::{Field, PrimeField, SqrtField}; use boojum::worker::Worker; @@ -1232,15 +1572,12 @@ mod test { builder } - let builder_impl = CsReferenceImplementationBuilder::::new( - geometry, - max_variables, - max_trace_len, - ); + let builder_impl = + CsReferenceImplementationBuilder::::new(geometry, max_trace_len); let builder = new_builder::<_, F>(builder_impl); let builder = configure(builder); - let mut owned_cs = builder.build(()); + let mut owned_cs = builder.build(max_variables); // add tables let table = create_xor8_table(); @@ -1249,11 +1586,11 @@ mod test { let table = create_and8_table(); owned_cs.add_lookup_table::(table); - let table = create_naf_abs_div2_table(); - owned_cs.add_lookup_table::(table); + // let table = create_naf_abs_div2_table(); + // owned_cs.add_lookup_table::(table); - let table = create_wnaf_decomp_table(); - owned_cs.add_lookup_table::(table); + // let table = create_wnaf_decomp_table(); + // owned_cs.add_lookup_table::(table); seq_macro::seq!(C in 0..32 { let table = create_fixed_base_mul_table::(); @@ -1287,6 +1624,88 @@ mod test { } #[test] + fn test_fixed_base_mul() { + let mut owned_cs = create_cs(1 << 21); + let cs = &mut owned_cs; + let scalar_params = Arc::new(secp256k1_scalar_field_params()); + let base_params = Arc::new(secp256k1_base_field_params()); + + let mut seed = Secp256Fr::multiplicative_generator(); + seed = seed.pow([1234]); + + for _i in 0..16 { + let scalar = Secp256ScalarNNField::allocate_checked(cs, seed, &scalar_params); + let mut result = fixed_base_mul(cs, scalar, &base_params); + let ((result_x, result_y), _) = + result.convert_to_affine_or_default(cs, Secp256Affine::one()); + + let expected = Secp256Affine::one().mul(seed).into_affine(); + dbg!(_i); + dbg!(seed); + assert_eq!( + result_x.witness_hook(cs)().unwrap().get(), + *expected.as_xy().0 + ); + assert_eq!( + result_y.witness_hook(cs)().unwrap().get(), + *expected.as_xy().1 + ); + + seed.square(); + } + } + + #[test] + fn test_variable_base_mul() { + let mut owned_cs = create_cs(1 << 21); + let cs = &mut owned_cs; + let scalar_params = Arc::new(secp256k1_scalar_field_params()); + let base_params = Arc::new(secp256k1_base_field_params()); + + let mut seed = Secp256Fr::multiplicative_generator(); + seed = seed.pow([1234]); + + let mut seed_2 = Secp256Fr::multiplicative_generator(); + seed_2 = seed_2.pow([987654]); + + for _i in 0..16 { + dbg!(_i); + dbg!(seed); + + let base = Secp256Affine::one().mul(seed_2).into_affine(); + + // let mut seed = Secp256Fr::from_str("1234567890").unwrap(); + // dbg!(base); + // dbg!(base.mul(seed).into_affine()); + + let scalar = Secp256ScalarNNField::allocate_checked(cs, seed, &scalar_params); + let x = Secp256BaseNNField::allocate_checked(cs, *base.as_xy().0, &base_params); + let y = Secp256BaseNNField::allocate_checked(cs, *base.as_xy().1, &base_params); + let point = SWProjectivePoint::from_xy_unchecked(cs, x, y); + + let mut result = + width_4_windowed_multiplication(cs, point, scalar, &base_params, &scalar_params); + // let mut result = wnaf_scalar_mul(cs, point, scalar, &base_params, &scalar_params); + let ((result_x, result_y), _) = + result.convert_to_affine_or_default(cs, Secp256Affine::one()); + + let expected = base.mul(seed).into_affine(); + assert_eq!( + result_x.witness_hook(cs)().unwrap().get(), + *expected.as_xy().0 + ); + assert_eq!( + result_y.witness_hook(cs)().unwrap().get(), + *expected.as_xy().1 + ); + + seed.square(); + seed_2.square(); + } + } + + #[test] + #[ignore = "test vectors hits malleable S"] fn test_signature_for_address_verification() { let mut owned_cs = create_cs(1 << 20); let cs = &mut owned_cs; @@ -1297,6 +1716,7 @@ mod test { .unwrap(); let eth_address = hex::decode("12890d2cce102216644c59dae5baed380d84830c").unwrap(); let (r, s, _pk, digest) = simulate_signature_for_sk(sk); + dbg!(_pk); let scalar_params = secp256k1_scalar_field_params(); let base_params = secp256k1_base_field_params(); @@ -1330,7 +1750,159 @@ mod test { ); for _ in 0..5 { - let (no_error, digest) = ecrecover_precompile_inner_routine::<_, _, false>( + let (no_error, digest) = ecrecover_precompile_inner_routine::<_, _, true>( + cs, + &rec_id, + &r, + &s, + &digest, + valid_x_in_external_field.clone(), + valid_y_in_external_field.clone(), + valid_t_in_external_field.clone(), + &base_params, + &scalar_params, + ); + + assert!(no_error.witness_hook(&*cs)().unwrap() == true); + let recovered_address = digest.to_be_bytes(cs); + let recovered_address = recovered_address.witness_hook(cs)().unwrap(); + assert_eq!(&recovered_address[12..], ð_address[..]); + } + + dbg!(cs.next_available_row()); + + cs.pad_and_shrink(); + + let mut cs = owned_cs.into_assembly::(); + cs.print_gate_stats(); + let worker = Worker::new(); + assert!(cs.check_if_satisfied(&worker)); + } + + #[test] + fn test_signature_from_reference_vector() { + let mut owned_cs = create_cs(1 << 20); + let cs = &mut owned_cs; + + let digest = + hex::decode("38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e") + .unwrap(); + let v = 0; + let r = hex::decode("38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e") + .unwrap(); + let s = hex::decode("789d1dd423d25f0772d2748d60f7e4b81bb14d086eba8e8e8efb6dcff8a4ae02") + .unwrap(); + let eth_address = hex::decode("ceaccac640adf55b2028469bd36ba501f28b699d").unwrap(); + + let scalar_params = secp256k1_scalar_field_params(); + let base_params = secp256k1_base_field_params(); + + let digest_u256 = U256::from_big_endian(&digest); + let r_u256 = U256::from_big_endian(&r); + let s_u256 = U256::from_big_endian(&s); + + let rec_id = UInt8::allocate_checked(cs, v); + let r = UInt256::allocate(cs, r_u256); + let s = UInt256::allocate(cs, s_u256); + let digest = UInt256::allocate(cs, digest_u256); + + let scalar_params = Arc::new(scalar_params); + let base_params = Arc::new(base_params); + + let valid_x_in_external_field = Secp256BaseNNField::allocated_constant( + cs, + Secp256Fq::from_str("9").unwrap(), + &base_params, + ); + let valid_t_in_external_field = Secp256BaseNNField::allocated_constant( + cs, + Secp256Fq::from_str("16").unwrap(), + &base_params, + ); + let valid_y_in_external_field = Secp256BaseNNField::allocated_constant( + cs, + Secp256Fq::from_str("4").unwrap(), + &base_params, + ); + + for _ in 0..1 { + let (no_error, digest) = ecrecover_precompile_inner_routine::<_, _, true>( + cs, + &rec_id, + &r, + &s, + &digest, + valid_x_in_external_field.clone(), + valid_y_in_external_field.clone(), + valid_t_in_external_field.clone(), + &base_params, + &scalar_params, + ); + + assert!(no_error.witness_hook(&*cs)().unwrap() == true); + let recovered_address = digest.to_be_bytes(cs); + let recovered_address = recovered_address.witness_hook(cs)().unwrap(); + assert_eq!(&recovered_address[12..], ð_address[..]); + } + + dbg!(cs.next_available_row()); + + cs.pad_and_shrink(); + + let mut cs = owned_cs.into_assembly::(); + cs.print_gate_stats(); + let worker = Worker::new(); + assert!(cs.check_if_satisfied(&worker)); + } + + #[test] + fn test_signature_from_reference_vector_2() { + let mut owned_cs = create_cs(1 << 20); + let cs = &mut owned_cs; + + let digest = + hex::decode("14431339128bd25f2c7f93baa611e367472048757f4ad67f6d71a5ca0da550f5") + .unwrap(); + let v = 1; + let r = hex::decode("51e4dbbbcebade695a3f0fdf10beb8b5f83fda161e1a3105a14c41168bf3dce0") + .unwrap(); + let s = hex::decode("46eabf35680328e26ef4579caf8aeb2cf9ece05dbf67a4f3d1f28c7b1d0e3546") + .unwrap(); + let eth_address = hex::decode("7f8b3b04bf34618f4a1723fba96b5db211279a2b").unwrap(); + + let scalar_params = secp256k1_scalar_field_params(); + let base_params = secp256k1_base_field_params(); + + let digest_u256 = U256::from_big_endian(&digest); + let r_u256 = U256::from_big_endian(&r); + let s_u256 = U256::from_big_endian(&s); + + let rec_id = UInt8::allocate_checked(cs, v); + let r = UInt256::allocate(cs, r_u256); + let s = UInt256::allocate(cs, s_u256); + let digest = UInt256::allocate(cs, digest_u256); + + let scalar_params = Arc::new(scalar_params); + let base_params = Arc::new(base_params); + + let valid_x_in_external_field = Secp256BaseNNField::allocated_constant( + cs, + Secp256Fq::from_str("9").unwrap(), + &base_params, + ); + let valid_t_in_external_field = Secp256BaseNNField::allocated_constant( + cs, + Secp256Fq::from_str("16").unwrap(), + &base_params, + ); + let valid_y_in_external_field = Secp256BaseNNField::allocated_constant( + cs, + Secp256Fq::from_str("4").unwrap(), + &base_params, + ); + + for _ in 0..1 { + let (no_error, digest) = ecrecover_precompile_inner_routine::<_, _, true>( cs, &rec_id, &r, @@ -1353,7 +1925,7 @@ mod test { cs.pad_and_shrink(); - let mut cs = owned_cs.into_assembly(); + let mut cs = owned_cs.into_assembly::(); cs.print_gate_stats(); let worker = Worker::new(); assert!(cs.check_if_satisfied(&worker)); @@ -1543,7 +2115,7 @@ mod test { cs.pad_and_shrink(); - let mut cs = owned_cs.into_assembly(); + let mut cs = owned_cs.into_assembly::(); cs.print_gate_stats(); let worker = Worker::new(); assert!(cs.check_if_satisfied(&worker)); diff --git a/crates/zkevm_circuits/src/ecrecover/secp256k1/fixed_base_mul_table.rs b/crates/zkevm_circuits/src/ecrecover/secp256k1/fixed_base_mul_table.rs index 8aec309..87aa76e 100644 --- a/crates/zkevm_circuits/src/ecrecover/secp256k1/fixed_base_mul_table.rs +++ b/crates/zkevm_circuits/src/ecrecover/secp256k1/fixed_base_mul_table.rs @@ -9,47 +9,50 @@ const TABLE_NAME: &'static str = "FIXEDBASEMUL table"; #[derive(Derivative)] #[derivative(Clone, Copy, Debug, PartialEq, Eq)] -pub struct FixedBaseMulTable; +pub struct FixedBaseMulTable; // Allows for a radix scalar mul by storing all potential exponentiations // of the generator with 0..255 -pub fn create_fixed_base_mul_table( -) -> LookupTable { - assert!(INDEX < 8); - assert!(B < 32); - let mut all_keys = Vec::with_capacity(1 << 8); - for a in 0..=u8::MAX { - let key = smallvec::smallvec![F::from_u64_unchecked(a as u64)]; - all_keys.push(key); +pub fn create_fixed_base_mul_table< + F: SmallField, + const U32_WORD_INDEX: usize, + const BYTE_OFFSET: usize, +>() -> LookupTable { + assert!(U32_WORD_INDEX < 8); + assert!(BYTE_OFFSET < 32); + let mut content = Vec::with_capacity(1 << 8); + // point of infinity is encoded as (0,0), and we handle it via select in the multiplication routine + content.push([F::ZERO, F::ZERO, F::ZERO]); + let mut base_power = Fr::one(); + for _ in 0..(BYTE_OFFSET * 8) { + base_power.double(); } - let mut generator = Secp256Affine::one(); - generator.negate(); - let r = Fr::from_str("256").unwrap(); - LookupTable::new_from_keys_and_generation_function( - &all_keys, - TABLE_NAME.to_string(), - 1, - |keys| { - let a = keys[0].as_u64_reduced(); - let b = r.pow([B]); - let mut exp = Fr::from_str(&a.to_string()).unwrap(); - exp.mul_assign(&b); - let result = generator.mul(exp); - let result = result.into_affine(); - let is_even = INDEX % 2 == 0; - let res = [result.x, result.y] - .iter() - .map(|c| { - let index = INDEX / 2; - let segment = c.into_repr().0[index]; - if is_even { - F::from_u64_unchecked(segment & (u32::MAX as u64)) - } else { - F::from_u64_unchecked(segment >> 32) - } - }) - .collect::>(); - smallvec::smallvec![res[0], res[1]] - }, - ) + let base = Secp256Affine::one(); + let base = base.mul(base_power); + let mut current = base; + let base = base.into_affine(); + let repr_word_index = U32_WORD_INDEX / 2; + let take_low = U32_WORD_INDEX % 2 == 0; + for a in 1..=u8::MAX { + let current_affine = current.into_affine(); + let (x, y) = current_affine.as_xy(); + let x_repr_word = x.into_repr().as_ref()[repr_word_index]; + let y_repr_word = y.into_repr().as_ref()[repr_word_index]; + if take_low { + content.push([ + F::from_u64_unchecked(a as u64), + F::from_u64_unchecked((x_repr_word as u32) as u64), + F::from_u64_unchecked((y_repr_word as u32) as u64), + ]); + } else { + content.push([ + F::from_u64_unchecked(a as u64), + F::from_u64_unchecked(x_repr_word >> 32), + F::from_u64_unchecked(y_repr_word >> 32), + ]); + } + current.add_assign_mixed(&base); + } + assert_eq!(content.len(), 256); + LookupTable::new_from_content(content, TABLE_NAME.to_string(), 1) } diff --git a/crates/zkevm_circuits/src/eip_4844/input.rs b/crates/zkevm_circuits/src/eip_4844/input.rs new file mode 100644 index 0000000..9b202fc --- /dev/null +++ b/crates/zkevm_circuits/src/eip_4844/input.rs @@ -0,0 +1,66 @@ +use std::collections::VecDeque; + +use super::*; +use crate::base_structures::vm_state::*; +use boojum::cs::{traits::cs::ConstraintSystem, Variable}; +use boojum::field::SmallField; +use boojum::gadgets::keccak256; +use boojum::gadgets::traits::auxiliary::PrettyComparison; +use boojum::gadgets::u256::recompose_u256_as_u32x8; +use boojum::gadgets::u32::UInt32; +use boojum::gadgets::u8::UInt8; +use boojum::gadgets::{ + boolean::Boolean, + queue::*, + traits::{ + allocatable::*, + encodable::{CircuitEncodable, CircuitEncodableExt, CircuitVarLengthEncodable}, + selectable::Selectable, + witnessable::WitnessHookable, + }, +}; +use boojum::serde_utils::BigArraySerde; +use cs_derive::*; +use derivative::*; + +pub const BLOB_CHUNK_SIZE: usize = 31; +pub const ELEMENTS_PER_4844_BLOCK: usize = 4096; + +#[derive(Derivative, CSAllocatable, CSSelectable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +pub struct BlobChunk { + pub inner: [UInt8; BLOB_CHUNK_SIZE], +} + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +#[DerivePrettyComparison("true")] +pub struct EIP4844OutputData { + pub linear_hash: [UInt8; keccak256::KECCAK256_DIGEST_SIZE], + pub output_hash: [UInt8; keccak256::KECCAK256_DIGEST_SIZE], +} + +impl CSPlaceholder for EIP4844OutputData { + fn placeholder>(cs: &mut CS) -> Self { + Self { + linear_hash: [UInt8::::allocate_constant(cs, 0); keccak256::KECCAK256_DIGEST_SIZE], + output_hash: [UInt8::::allocate_constant(cs, 0); keccak256::KECCAK256_DIGEST_SIZE], + } + } +} + +pub type EIP4844InputOutput = + crate::fsm_input_output::ClosedFormInput>; + +pub type EIP4844InputOutputWitness = + crate::fsm_input_output::ClosedFormInputWitness>; + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Debug, Default)] +#[serde(bound = "")] +pub struct EIP4844CircuitInstanceWitness { + pub closed_form_input: EIP4844InputOutputWitness, + pub versioned_hash: [u8; 32], + pub linear_hash_output: [u8; 32], + pub data_chunks: VecDeque>, +} diff --git a/crates/zkevm_circuits/src/eip_4844/mod.rs b/crates/zkevm_circuits/src/eip_4844/mod.rs new file mode 100644 index 0000000..929f5cc --- /dev/null +++ b/crates/zkevm_circuits/src/eip_4844/mod.rs @@ -0,0 +1,772 @@ +use crate::base_structures::state_diff_record::StateDiffRecord; +use crate::demux_log_queue::StorageLogQueue; +use crate::ethereum_types::U256; +use crate::fsm_input_output::circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH; +use crate::keccak256_round_function::keccak256_absorb_and_run_permutation; +use boojum::algebraic_props::round_function::AlgebraicRoundFunction; +use boojum::config::*; +use boojum::crypto_bigint::{Zero, U1024}; +use boojum::cs::gates::ConstantAllocatableCS; +use boojum::cs::traits::cs::{ConstraintSystem, DstBuffer}; +use boojum::cs::{Place, Variable}; +use boojum::field::SmallField; +use boojum::gadgets::boolean::Boolean; +use boojum::gadgets::keccak256; +use boojum::gadgets::non_native_field::implementations::*; +use boojum::gadgets::num::Num; +use boojum::gadgets::queue::CircuitQueue; +use boojum::gadgets::queue::CircuitQueueWitness; +use boojum::gadgets::queue::QueueState; +use boojum::gadgets::traits::allocatable::{CSAllocatable, CSAllocatableExt, CSPlaceholder}; +use boojum::gadgets::traits::castable::WitnessCastable; +use boojum::gadgets::traits::round_function::CircuitRoundFunction; +use boojum::gadgets::traits::selectable::Selectable; +use boojum::gadgets::traits::witnessable::WitnessHookable; +use boojum::gadgets::u16::UInt16; +use boojum::gadgets::u256::UInt256; +use boojum::gadgets::u32::UInt32; +use boojum::gadgets::u8::UInt8; +use boojum::pairing::ff::{Field, PrimeField}; +use std::mem::MaybeUninit; +use std::sync::{Arc, RwLock}; + +use super::*; + +pub mod input; +use self::input::*; + +use boojum::pairing::bls12_381::fr::Fr as Bls12_381Fr; + +const NUM_WORDS_FR: usize = 17; +type Bls12_381ScalarNNFieldParams = NonNativeFieldOverU16Params; +type Bls12_381ScalarNNField = NonNativeFieldOverU16; + +// turns 128 bits into a Bls12 field element. +fn convert_truncated_keccak_digest_to_field_element>( + cs: &mut CS, + input: [UInt8; 16], + params: &Arc, +) -> Bls12_381ScalarNNField { + // compose the bytes into u16 words for the nonnative wrapper + let zero_var = cs.allocate_constant(F::ZERO); + let mut limbs = [zero_var; NUM_WORDS_FR]; + // since the value would be interpreted as big endian in the L1 we need to reverse our bytes to + // get the correct value + for (dst, src) in limbs.iter_mut().zip(input.array_chunks::<2>().rev()) { + let [c0, c1] = *src; + // for some reason there is no "from_be_bytes" + *dst = UInt16::from_le_bytes(cs, [c1, c0]).get_variable(); + } + + // Note: we do not need to check for overflows because the max value is 2^128 which is less + // than the field modulus. + NonNativeFieldOverU16 { + limbs: limbs, + non_zero_limbs: 16, + tracker: OverflowTracker { max_moduluses: 1 }, + form: RepresentationForm::Normalized, + params: params.clone(), + _marker: std::marker::PhantomData, + } +} + +// here we just interpret it as LE +fn convert_blob_chunk_to_field_element>( + cs: &mut CS, + input: [UInt8; BLOB_CHUNK_SIZE], + params: &Arc, +) -> Bls12_381ScalarNNField { + // compose the bytes into u16 words for the nonnative wrapper + let zero_var = cs.allocate_constant(F::ZERO); + let mut limbs = [zero_var; NUM_WORDS_FR]; + let input_chunks = input.array_chunks::<2>(); + let remainder = input_chunks.remainder(); + for (dst, src) in limbs.iter_mut().zip(input_chunks) { + *dst = UInt16::from_le_bytes(cs, *src).get_variable(); + } + + // since array_chunks drops any remaining elements that don't fit in the size requirement, + // we need to manually set the last byte in limbs + limbs[15] = remainder[0].get_variable(); + + // Note: we do not need to check for overflows because the max value is 2^248 which is less + // than the field modulus. + NonNativeFieldOverU16 { + limbs: limbs, + non_zero_limbs: 16, + tracker: OverflowTracker { max_moduluses: 1 }, + form: RepresentationForm::Normalized, + params: params.clone(), + _marker: std::marker::PhantomData, + } +} + +/// We interpret out pubdata as chunks of 31 bytes, that are coefficients of +/// some polynomial, starting from the highest one. It's different from 4844 blob data format, +/// and we provide additional functions to compute the corresponding 4844 blob data, and restore back +pub fn eip_4844_entry_point< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, +>( + cs: &mut CS, + witness: EIP4844CircuitInstanceWitness, + round_function: &R, + params: usize, +) -> [Num; INPUT_OUTPUT_COMMITMENT_LENGTH] +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, +{ + let limit = params; + + assert_eq!(limit, ELEMENTS_PER_4844_BLOCK); // max blob length eip4844 + + let EIP4844CircuitInstanceWitness { + closed_form_input, + versioned_hash, + linear_hash_output, + data_chunks, + } = witness; + + if ::WitnessConfig::EVALUATE_WITNESS { + assert_eq!(data_chunks.len(), ELEMENTS_PER_4844_BLOCK) + } + + let mut data_chunks = data_chunks; + let zero_u8 = UInt8::zero(cs); + + let versioned_hash = <[UInt8; 32]>::allocate(cs, versioned_hash); + let linear_hash_output = <[UInt8; 32]>::allocate(cs, linear_hash_output); + + let boolean_true = Boolean::allocated_constant(cs, true); + let mut structured_input = EIP4844InputOutput:: { + start_flag: boolean_true, + completion_flag: boolean_true, + observable_input: (), + observable_output: EIP4844OutputData { + linear_hash: [UInt8::::zero(cs); keccak256::KECCAK256_DIGEST_SIZE], + output_hash: [UInt8::::zero(cs); keccak256::KECCAK256_DIGEST_SIZE], + }, + hidden_fsm_input: (), + hidden_fsm_output: (), + }; + + // create a field element out of the hash of the input hash and the kzg commitment + let challenge_hash = boojum::gadgets::keccak256::keccak256( + cs, + linear_hash_output + .into_iter() + .chain(versioned_hash.into_iter()) + .collect::>>() + .as_slice(), + ); + + // truncate hash to 128 bits + // NOTE: it is safe to draw a random scalar at max 128 bits because of the schwartz zippel + // lemma + let mut truncated_hash = [zero_u8; 16]; + // take last 16 bytes to get max 2^128 + // in big endian scenario + truncated_hash.copy_from_slice(&challenge_hash[16..]); + let params = Arc::new(Bls12_381ScalarNNFieldParams::create()); + let mut evaluation_point = + convert_truncated_keccak_digest_to_field_element(cs, truncated_hash, ¶ms); + + let mut buffer = Vec::with_capacity(31 * 4096); + + let mut opening_value = + Bls12_381ScalarNNField::::allocated_constant(cs, Bls12_381Fr::zero(), ¶ms); + + // We always pad the pubdata to be 31*(2^12) bytes, no matter how many elements we fill. + // Therefore, we can run the circuit straightforwardly without needing to account for potential + // changes in the cycle number in which the padding happens. Hence, we run the loop + // to perform the horner's rule evaluation of the blob polynomial and then finalize the hash + // out of the loop with a single keccak256 call. + for cycle in 0..limit { + let el = data_chunks + .pop_front() + .unwrap_or(BlobChunk::placeholder_witness()); + let el = BlobChunk::::allocate(cs, el); + // polynomial evaluations via horner's rule + let mut fe = convert_blob_chunk_to_field_element(cs, el.inner, ¶ms); + // horner's rule is defined as evaluating a polynomial a_0 + a_1x + a_2x^2 + ... + a_nx^n + // in the form of a_0 + x(a_1 + x(a_2 + x(a_3 + ... + x(a_{n-1} + xa_n)))) + // since the blob is considered to be a polynomial in monomial form, we essentially + // 'work backwards' and start with the highest degree coefficients first. so we can + // add and multiply and at the last step we only add the coefficient. + opening_value = opening_value.add(cs, &mut fe); + if cycle != limit - 1 { + opening_value = opening_value.mul(cs, &mut evaluation_point); + } + + buffer.extend(el.inner); + } + + use boojum::gadgets::keccak256::keccak256; + let keccak256_hash = keccak256(cs, &buffer); + + // hash equality check + for (input_byte, hash_byte) in linear_hash_output.iter().zip(keccak256_hash) { + Num::enforce_equal(cs, &input_byte.into_num(), &hash_byte.into_num()); + } + + // now commit to versioned hash || opening point || openinig value + + // normalize and serialize opening value as BE + let mut opening_value_be_bytes = [zero_u8; 32]; + opening_value.normalize(cs); + + for (dst, src) in opening_value_be_bytes + .array_chunks_mut::<2>() + .zip(opening_value.limbs[..16].iter().rev()) + { + // field element is normalized, so all limbs are 16 bits + let be_bytes = unsafe { UInt16::from_variable_unchecked(*src).to_be_bytes(cs) }; + *dst = be_bytes; + } + + let output_hash = keccak256( + cs, + versioned_hash + .into_iter() + .chain(truncated_hash.into_iter()) + .chain(opening_value_be_bytes.into_iter()) + .collect::>>() + .as_slice(), + ); + + let mut observable_output = EIP4844OutputData::placeholder(cs); + observable_output.linear_hash = keccak256_hash; + observable_output.output_hash = output_hash; + structured_input.observable_output = observable_output; + + // self-check + structured_input.hook_compare_witness(cs, &closed_form_input); + + use crate::fsm_input_output::commit_variable_length_encodable_item; + use crate::fsm_input_output::ClosedFormInputCompactForm; + use boojum::cs::gates::PublicInputGate; + + let compact_form = + ClosedFormInputCompactForm::from_full_form(cs, &structured_input, round_function); + let input_commitment = commit_variable_length_encodable_item(cs, &compact_form, round_function); + for el in input_commitment.iter() { + let gate = PublicInputGate::new(el.get_variable()); + gate.add_to_cs(cs); + } + + input_commitment +} + +fn omega() -> Bls12_381Fr { + let mut omega = Bls12_381Fr::root_of_unity(); + let exp = ELEMENTS_PER_4844_BLOCK.trailing_zeros(); + + for _ in exp..Bls12_381Fr::S { + omega.square(); + } + + let mut t = omega; + for _ in 0..12 { + assert!(t != Bls12_381Fr::one()); + t.square(); + } + assert!(t == Bls12_381Fr::one()); + + omega +} + +fn omega_inv() -> Bls12_381Fr { + omega().inverse().unwrap() +} + +fn m_inv() -> Bls12_381Fr { + Bls12_381Fr::from_str(&format!("{}", ELEMENTS_PER_4844_BLOCK)) + .unwrap() + .inverse() + .unwrap() +} + +fn bitreverse_idx(mut n: u32, l: u32) -> u32 { + let mut r = 0; + for _ in 0..l { + r = (r << 1) | (n & 1); + n >>= 1; + } + + r +} + +pub fn bitreverse(a: &mut [T]) { + let n = a.len() as u32; + assert!(n.is_power_of_two()); + let log_n = n.trailing_zeros(); + + for k in 0..n { + let rk = bitreverse_idx(k, log_n); + if k < rk { + a.swap(rk as usize, k as usize); + } + } +} + +fn serial_fft(a: &mut [Bls12_381Fr], omega: &Bls12_381Fr, log_n: u32) { + let n = a.len() as u32; + assert_eq!(n, 1 << log_n); + + bitreverse(a); + + let mut m = 1; + for _ in 0..log_n { + let w_m = omega.pow(&[(n / (2 * m)) as u64]); + + let mut k = 0; + while k < n { + let mut w = Bls12_381Fr::one(); + for j in 0..m { + let mut t = a[(k + j + m) as usize]; + t.mul_assign(&w); + let mut tmp = a[(k + j) as usize]; + tmp.sub_assign(&t); + a[(k + j + m) as usize] = tmp; + a[(k + j) as usize].add_assign(&t); + w.mul_assign(&w_m); + } + + k += 2 * m; + } + + m *= 2; + } +} + +pub fn fft(a: &mut [Bls12_381Fr]) { + assert_eq!(a.len(), ELEMENTS_PER_4844_BLOCK); + serial_fft(a, &omega(), ELEMENTS_PER_4844_BLOCK.trailing_zeros()); +} + +pub fn ifft(a: &mut [Bls12_381Fr]) { + assert_eq!(a.len(), ELEMENTS_PER_4844_BLOCK); + serial_fft(a, &omega_inv(), ELEMENTS_PER_4844_BLOCK.trailing_zeros()); + let m_inv = m_inv(); + for a in a.iter_mut() { + a.mul_assign(&m_inv); + } +} + +pub fn zksync_pubdata_into_ethereum_4844_data(input: &[u8]) -> Vec { + let mut poly = zksync_pubdata_into_monomial_form_poly(input); + fft(&mut poly); + // and we need to bitreverse + bitreverse(&mut poly); + // and now serialize in BE form as Ethereum expects + let mut result = Vec::with_capacity(32 * ELEMENTS_PER_4844_BLOCK); + use boojum::pairing::ff::PrimeFieldRepr; + for el in poly.into_iter() { + let mut buffer = [0u8; 32]; + el.into_repr().write_be(&mut buffer[..]).unwrap(); + result.extend(buffer); + } + assert_eq!(result.len(), 32 * ELEMENTS_PER_4844_BLOCK); + + result +} + +pub fn zksync_pubdata_into_monomial_form_poly(input: &[u8]) -> Vec { + assert_eq!(input.len(), BLOB_CHUNK_SIZE * ELEMENTS_PER_4844_BLOCK); + // we interpret it as coefficients starting from the top one + let mut poly = Vec::with_capacity(ELEMENTS_PER_4844_BLOCK); + use boojum::pairing::ff::PrimeFieldRepr; + for bytes in input.array_chunks::().rev() { + let mut buffer = [0u8; 32]; + buffer[..BLOB_CHUNK_SIZE].copy_from_slice(bytes); + let mut repr = ::Repr::default(); + repr.read_le(&buffer[..]).unwrap(); // note that it's LE + // Since repr only has 31 bytes, repr is guaranteed to be below the modulus + let as_field_element = Bls12_381Fr::from_repr(repr).unwrap(); + poly.push(as_field_element); + } + + poly +} + +pub fn ethereum_4844_pubdata_into_bitreversed_lagrange_form_poly(input: &[u8]) -> Vec { + // Ethereum's blob data requires that all field element representations are canonical, but we will handle + // a generic case. For BLS12-381 one can fit 2*modulus into 32 bytes, but not 3, so we need to subtract at most twice + // to get completely canonical representation sooner or later + assert_eq!(input.len(), 32 * ELEMENTS_PER_4844_BLOCK); + let mut poly = Vec::with_capacity(ELEMENTS_PER_4844_BLOCK); + use boojum::pairing::ff::PrimeFieldRepr; + let modulus = ::char(); + for bytes in input.array_chunks::<32>() { + let mut repr = ::Repr::default(); + repr.read_be(&bytes[..]).unwrap(); + let mut as_field_element = None; + 'inner: for _ in 0..3 { + if let Ok(normalized_field_element) = Bls12_381Fr::from_repr(repr) { + as_field_element = Some(normalized_field_element); + break 'inner; + } else { + repr.sub_noborrow(&modulus) + } + } + let as_field_element = as_field_element.unwrap(); + poly.push(as_field_element); + } + assert_eq!(poly.len(), ELEMENTS_PER_4844_BLOCK); + + poly +} + +pub fn ethereum_4844_data_into_zksync_pubdata(input: &[u8]) -> Vec { + assert_eq!(input.len(), 32 * ELEMENTS_PER_4844_BLOCK); + let mut poly = ethereum_4844_pubdata_into_bitreversed_lagrange_form_poly(input); + // and we need to bitreverse + bitreverse(&mut poly); + // now we need to iFFT it to get monomial form + ifft(&mut poly); + // and now serialize in LE by BLOB_CHUNK_SIZE chunks + let mut result = Vec::with_capacity(BLOB_CHUNK_SIZE * ELEMENTS_PER_4844_BLOCK); + use boojum::pairing::ff::PrimeFieldRepr; + // note that highest monomial goes first in byte array + for el in poly.into_iter().rev() { + let mut buffer = [0u8; 32]; + el.into_repr().write_le(&mut buffer[..]).unwrap(); + assert_eq!( + 0, buffer[31], + "zksync data is representable by 31 byte field elements LE" + ); + result.extend_from_slice(&buffer[..BLOB_CHUNK_SIZE]); + } + assert_eq!(result.len(), BLOB_CHUNK_SIZE * ELEMENTS_PER_4844_BLOCK); + + result +} + +#[cfg(test)] +mod tests { + use std::alloc::Global; + use std::collections::VecDeque; + + use super::*; + use boojum::config::DevCSConfig; + use boojum::cs::cs_builder::*; + use boojum::cs::cs_builder_reference::CsReferenceImplementationBuilder; + use boojum::cs::gates::*; + use boojum::cs::traits::gate::GatePlacementStrategy; + use boojum::cs::CSGeometry; + use boojum::cs::*; + use boojum::field::goldilocks::GoldilocksField; + use boojum::field::traits::field_like::PrimeFieldLike; + use boojum::field::Field; + use boojum::field::SmallField; + use boojum::gadgets::queue::CircuitQueueRawWitness; + use boojum::gadgets::tables::byte_split::ByteSplitTable; + use boojum::gadgets::tables::*; + use boojum::implementations::poseidon2::Poseidon2Goldilocks; + use boojum::pairing::bls12_381::G1; + use boojum::pairing::ff::PrimeFieldRepr; + use boojum::pairing::ff::{Field as PairingField, PrimeField, SqrtField}; + use boojum::worker::Worker; + use rand::SeedableRng; + use rand::{Rand, Rng}; + + type F = GoldilocksField; + type P = GoldilocksField; + + #[test] + fn test_eip4844() { + let geometry = CSGeometry { + num_columns_under_copy_permutation: 60, + num_witness_columns: 0, + num_constant_columns: 8, + max_allowed_constraint_degree: 4, + }; + let max_variables = 1 << 26; + let max_trace_len = 1 << 20; + + fn configure< + F: SmallField, + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + let builder = builder.allow_lookup( + LookupParameters::UseSpecializedColumnsWithTableIdAsConstant { + width: 3, + num_repetitions: 20, + share_table_id: true, + }, + ); + let builder = ConstantsAllocatorGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = PublicInputGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = FmaGateInBaseFieldWithoutConstant::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ReductionGate::::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + // let owned_cs = ReductionGate::::configure_for_cs(owned_cs, GatePlacementStrategy::UseSpecializedColumns { num_repetitions: 8, share_constants: true }); + let builder = BooleanConstraintGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<32>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<16>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = SelectionGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = DotProductGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + // let owned_cs = DotProductGate::<4>::configure_for_cs(owned_cs, GatePlacementStrategy::UseSpecializedColumns { num_repetitions: 1, share_constants: true }); + let builder = NopGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + + builder + } + + let builder_impl = + CsReferenceImplementationBuilder::::new(geometry, max_trace_len); + let builder = new_builder::<_, F>(builder_impl); + + let builder = configure(builder); + let mut owned_cs = builder.build(max_variables); + + // add tables + let table = create_xor8_table(); + owned_cs.add_lookup_table::(table); + + let table = create_and8_table(); + owned_cs.add_lookup_table::(table); + + let table = create_byte_split_table::(); + owned_cs.add_lookup_table::, 3>(table); + let table = create_byte_split_table::(); + owned_cs.add_lookup_table::, 3>(table); + let table = create_byte_split_table::(); + owned_cs.add_lookup_table::, 3>(table); + let table = create_byte_split_table::(); + owned_cs.add_lookup_table::, 3>(table); + + let cs = &mut owned_cs; + + let round_function = Poseidon2Goldilocks; + + // make some random chunks + let mut data_chunks = vec![[0u8; BLOB_CHUNK_SIZE]; ELEMENTS_PER_4844_BLOCK]; + let mut rng = rand::XorShiftRng::from_seed([0, 0, 0, 42]); + for dst in data_chunks.iter_mut() { + let el = Bls12_381Fr::rand(&mut rng); + let mut bytes = [0u8; 32]; + el.into_repr().write_le(&mut bytes[..]).unwrap(); + dst.copy_from_slice(&bytes[..BLOB_CHUNK_SIZE]); + } + + let mut blob_data_flattened = vec![]; + for el in data_chunks.iter() { + blob_data_flattened.extend_from_slice(el); + } + + // now we can get it as polynomial, and + use zkevm_opcode_defs::sha3::*; + let mut linear_hash_output = [0u8; 32]; + let digest = Keccak256::digest(&blob_data_flattened); + + linear_hash_output.copy_from_slice(digest.as_slice()); + + // now we can get some quasi-setup for KZG and make a blob + let poly = zksync_pubdata_into_monomial_form_poly(&blob_data_flattened); + + let mut setup = Vec::with_capacity(ELEMENTS_PER_4844_BLOCK); + use boojum::pairing::CurveAffine; + use boojum::pairing::CurveProjective; + let mut point = G1::one(); + let scalar = Bls12_381Fr::from_str("42").unwrap().into_repr(); + for _ in 0..ELEMENTS_PER_4844_BLOCK { + setup.push(point); + point.mul_assign(scalar); + } + + // compute commitment + let mut commitment = G1::zero(); + for (scalar, point) in poly.iter().zip(setup.iter()) { + let mut el = *point; + el.mul_assign(scalar.into_repr()); + commitment.add_assign(&el); + } + + let (kzg_commitment_x, kzg_commitment_y) = commitment.into_affine().into_xy_unchecked(); + let mut buffer = [0u8; 96]; + kzg_commitment_x + .into_repr() + .write_be(&mut buffer[..48]) + .unwrap(); + kzg_commitment_y + .into_repr() + .write_be(&mut buffer[48..]) + .unwrap(); + + let mut versioned_hash = [0u8; 32]; + let digest = Keccak256::digest(&buffer); + versioned_hash.copy_from_slice(digest.as_slice()); + versioned_hash[0] = 0x01; + + let evaluation_point = Keccak256::digest( + linear_hash_output + .into_iter() + .chain(versioned_hash.into_iter()) + .collect::>(), + )[16..] + .to_vec(); + + dbg!(hex::encode(&evaluation_point)); + + let mut buffer = [0u8; 32]; + buffer[16..].copy_from_slice(&evaluation_point); + let mut evaluation_point_repr = + ::Repr::default(); + evaluation_point_repr.read_be(&buffer[..]).unwrap(); + let evaluation_point_fr = Bls12_381Fr::from_repr(evaluation_point_repr).unwrap(); + dbg!(evaluation_point_fr); + + use boojum::pairing::bls12_381::FrRepr; + // evaluate polynomial + let mut evaluation_result = Bls12_381Fr::zero(); + let mut power = Bls12_381Fr::one(); + for coeff in poly.iter() { + let mut tmp = *coeff; + tmp.mul_assign(&power); + evaluation_result.add_assign(&tmp); + power.mul_assign(&evaluation_point_fr); + } + + dbg!(evaluation_result); + let mut opening_value_bytes = [0u8; 32]; + evaluation_result + .into_repr() + .write_be(&mut opening_value_bytes[..]) + .unwrap(); + + let mut observable_output = EIP4844OutputData::::placeholder_witness(); + let output_hash = Keccak256::digest( + versioned_hash + .into_iter() + .chain(evaluation_point.into_iter()) + .chain(opening_value_bytes.into_iter()) + .collect::>(), + ) + .into(); + dbg!(hex::encode(&output_hash)); + observable_output.output_hash = output_hash; + observable_output.linear_hash = linear_hash_output; + + let closed_form_input = EIP4844InputOutputWitness { + start_flag: true, + completion_flag: true, + observable_input: (), + observable_output: observable_output, + hidden_fsm_input: (), + hidden_fsm_output: (), + }; + + let witness = EIP4844CircuitInstanceWitness { + closed_form_input, + versioned_hash, + linear_hash_output, + data_chunks: data_chunks + .into_iter() + .map(|el| BlobChunkWitness { inner: el }) + .collect::>>(), + }; + + eip_4844_entry_point::<_, _, _>(cs, witness, &round_function, 4096); + + dbg!(cs.next_available_row()); + + cs.pad_and_shrink(); + + let mut cs = owned_cs.into_assembly::(); + cs.print_gate_stats(); + let worker = Worker::new(); + assert!(cs.check_if_satisfied(&worker)); + } + + #[test] + fn round_trip_fft() { + let mut rng = rand::XorShiftRng::new_unseeded(); + for _ in 0..128 { + let mut input: Vec<_> = (0..4096).map(|_| Bls12_381Fr::rand(&mut rng)).collect(); + let expected = input.clone(); + ifft(&mut input); + fft(&mut input); + for (i, (a, b)) in input.iter().zip(expected.iter()).enumerate() { + if a != b { + panic!("Diverged at i = {}, a = {:?}, b = {:?}", i, a, b); + } + } + } + } + + #[test] + fn test_data_roundtrip() { + let mut rng = rand::XorShiftRng::new_unseeded(); + let zksync_data: Vec = (0..(31 * 4096)).map(|_| rng.gen()).collect(); + let monomial_form = zksync_pubdata_into_monomial_form_poly(&zksync_data); + let mut expected_lagrange_form = monomial_form.clone(); + fft(&mut expected_lagrange_form); + bitreverse(&mut expected_lagrange_form); + + let ethereum_data = zksync_pubdata_into_ethereum_4844_data(&zksync_data); + let recreated_lagrange_form = + ethereum_4844_pubdata_into_bitreversed_lagrange_form_poly(ðereum_data); + for (i, (a, b)) in expected_lagrange_form + .iter() + .zip(recreated_lagrange_form.iter()) + .enumerate() + { + if a != b { + panic!("Diverged at i = {}, a = {:?}, b = {:?}", i, a, b); + } + } + let mut recreated_monomial_form = recreated_lagrange_form.clone(); + bitreverse(&mut recreated_monomial_form); + ifft(&mut recreated_monomial_form); + for (i, (a, b)) in monomial_form + .iter() + .zip(recreated_monomial_form.iter()) + .enumerate() + { + if a != b { + panic!("Diverged at i = {}, a = {:?}, b = {:?}", i, a, b); + } + } + let data_back = ethereum_4844_data_into_zksync_pubdata(ðereum_data); + for (i, (a, b)) in zksync_data.iter().zip(data_back.iter()).enumerate() { + if a != b { + panic!("Diverged at i = {}, a = {:?}, b = {:?}", i, a, b); + } + } + } +} diff --git a/crates/zkevm_circuits/src/keccak256_round_function/buffer/mod.rs b/crates/zkevm_circuits/src/keccak256_round_function/buffer/mod.rs new file mode 100644 index 0000000..6747331 --- /dev/null +++ b/crates/zkevm_circuits/src/keccak256_round_function/buffer/mod.rs @@ -0,0 +1,164 @@ +use super::*; +use crate::boojum::gadgets::traits::auxiliary::PrettyComparison; +use crate::boojum::serde_utils::BigArraySerde; + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +#[DerivePrettyComparison("true")] +pub struct ByteBuffer { + pub bytes: [UInt8; BUFFER_SIZE], + pub filled: UInt8, // assume that it's enough +} + +impl CSPlaceholder for ByteBuffer { + fn placeholder>(cs: &mut CS) -> Self { + let zero_u8 = UInt8::zero(cs); + Self { + bytes: [zero_u8; BUFFER_SIZE], + filled: zero_u8, + } + } +} + +// we map a set of offset + current fill factor into "start from here" bit for 0-th byte of the buffer of length N +pub type BufferMappingFunction = + fn(&mut CS, UInt8, UInt8, [(); N]) -> [Boolean; M]; + +impl ByteBuffer { + pub fn can_fill_fixed_bytes, const N: usize>( + &self, + cs: &mut CS, + ) -> Boolean { + let max_filled = BUFFER_SIZE - N; + let max_filled = u8::try_from(max_filled).expect("must fit into u8"); + let upper_bound = UInt8::allocate_constant(cs, max_filled); + // we need to check that filled <= max_filled + let (_, uf) = upper_bound.overflowing_sub(cs, &self.filled); + let can_fill = uf.negated(cs); + + can_fill + } + + pub fn can_fill_bytes>( + &self, + cs: &mut CS, + bytes_to_fill: UInt8, + ) -> Boolean { + let next_filled = self.filled.add_no_overflow(cs, bytes_to_fill); + let max_filled = BUFFER_SIZE; + let max_filled = u8::try_from(max_filled).expect("must fit into u8"); + let upper_bound = UInt8::allocate_constant(cs, max_filled); + // we need to check that next_filled <= max_filled + let (_, uf) = upper_bound.overflowing_sub(cs, &next_filled); + let can_fill = uf.negated(cs); + + can_fill + } + + pub fn can_consume_n_bytes, const N: usize>( + &self, + cs: &mut CS, + ) -> Boolean { + let bytes_to_consume = N; + let bytes_to_consume = u8::try_from(bytes_to_consume).expect("must fit into u8"); + let bytes_to_consume = UInt8::allocate_constant(cs, bytes_to_consume); + // we need to check that filled >= bytes_to_consume + let (_, uf) = self.filled.overflowing_sub(cs, &bytes_to_consume); + let can_consume = uf.negated(cs); + + can_consume + } + + // must be called only after caller ensures enough capacity left + pub fn fill_with_bytes, const N: usize>( + &mut self, + cs: &mut CS, + input: &[UInt8; N], + offset: UInt8, + meaningful_bytes: UInt8, + mapping_function: BufferMappingFunction, + ) { + assert!(N < 128); // kind of arbitrary constant here, in practice we would only use 32 + // we do naive implementation of the shift register + let mut offset = offset.into_num(); + let one_num = Num::allocated_constant(cs, F::ONE); + let zero_u8 = UInt8::zero(cs); + // base case + let mut shifted_input = *input; + offset = offset.sub(cs, &one_num); + for i in 1..N { + let use_form_here = offset.is_zero(cs); + offset = offset.sub(cs, &one_num); + let mut candidate = [zero_u8; N]; + candidate[0..(N - i)].copy_from_slice(&input[i..]); + shifted_input = <[UInt8; N]>::conditionally_select( + cs, + use_form_here, + &candidate, + &shifted_input, + ); + } + // now we can use a mapping function to determine based on the number of meaningful bytes and current fill factor + // on which bytes to use from the start and which not. We already shifted all meaningful bytes to the left above, + // so we only need 1 bit to show "start here" + + // dbg!(shifted_input.witness_hook(cs)()); + + let use_byte_for_place_mask = mapping_function(cs, meaningful_bytes, self.filled, [(); N]); + let mut counter = meaningful_bytes.into_num(); + let mut shifted_buffer_exhausted = meaningful_bytes.is_zero(cs); + // TODO: transpose to use linear combination + for (idx, src) in shifted_input.into_iter().enumerate() { + // buffer above is shifted all the way to the left, so if byte number 0 can use any of 0..BUFFER_SIZE markers, + // then for byte number 1 we can only use markers 1..BUFFER_SIZE markers, and so on, and byte number 1 can never go into + // buffer position 0 + + // we also need to determine if we ever "use" this byte or should zero it out for later padding procedure + let src = src.mask_negated(cs, shifted_buffer_exhausted); + let markers = &use_byte_for_place_mask[..(BUFFER_SIZE - idx)]; + let dsts = &mut self.bytes[idx..]; + assert_eq!(markers.len(), dsts.len()); + + for (dst, flag) in dsts.iter_mut().zip(markers.iter()) { + *dst = UInt8::conditionally_select(cs, *flag, &src, &*dst); + } + + counter = counter.sub(cs, &one_num); + // this will underflow and walk around the field range, but not important for our ranges of N + let now_exhausted = counter.is_zero(cs); + shifted_buffer_exhausted = + Boolean::multi_or(cs, &[now_exhausted, shifted_buffer_exhausted]); + } + self.filled = self.filled.add_no_overflow(cs, meaningful_bytes); + // compare no overflow + let capacity = u8::try_from(BUFFER_SIZE).expect("must fit into u8"); + let _ = UInt8::allocated_constant(cs, capacity).sub_no_overflow(cs, self.filled); + } + + pub fn consume, const N: usize>( + &mut self, + cs: &mut CS, + allow_partial: Boolean, + ) -> [UInt8; N] { + let bytes_to_take = u8::try_from(N).expect("must fit"); + let bytes_to_take = UInt8::allocated_constant(cs, bytes_to_take); + let (leftover, uf) = self.filled.overflowing_sub(cs, &bytes_to_take); + let have_enough = uf.negated(cs); + let is_valid = Boolean::multi_or(cs, &[have_enough, allow_partial]); + let boolean_true = Boolean::allocated_constant(cs, true); + Boolean::enforce_equal(cs, &is_valid, &boolean_true); + + self.filled = leftover.mask_negated(cs, uf); + + let zero_u8 = UInt8::zero(cs); + let mut result = [zero_u8; N]; + result.copy_from_slice(&self.bytes[..N]); + + let mut new_bytes = [zero_u8; BUFFER_SIZE]; + new_bytes[..(BUFFER_SIZE - N)].copy_from_slice(&self.bytes[N..]); + + self.bytes = new_bytes; + + result + } +} diff --git a/crates/zkevm_circuits/src/keccak256_round_function/input.rs b/crates/zkevm_circuits/src/keccak256_round_function/input.rs index d521b41..480b518 100644 --- a/crates/zkevm_circuits/src/keccak256_round_function/input.rs +++ b/crates/zkevm_circuits/src/keccak256_round_function/input.rs @@ -4,6 +4,7 @@ use super::*; use crate::base_structures::precompile_input_outputs::*; use crate::base_structures::vm_state::*; +use crate::keccak256_round_function::buffer::ByteBuffer; use boojum::cs::Variable; use boojum::gadgets::queue::*; use boojum::gadgets::traits::allocatable::CSAllocatable; @@ -19,19 +20,22 @@ use boojum::gadgets::traits::selectable::Selectable; use boojum::gadgets::traits::witnessable::WitnessHookable; use boojum::serde_utils::BigArraySerde; +pub const MEMORY_QUERIES_PER_CYCLE: usize = 6; +pub const KECCAK_PRECOMPILE_BUFFER_SIZE: usize = MEMORY_QUERIES_PER_CYCLE * 32; + #[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] #[derivative(Clone, Copy, Debug)] #[DerivePrettyComparison("true")] pub struct Keccak256RoundFunctionFSM { pub read_precompile_call: Boolean, pub read_unaligned_words_for_round: Boolean, + pub padding_round: Boolean, pub completed: Boolean, pub keccak_internal_state: [[[UInt8; BYTES_PER_WORD]; LANE_WIDTH]; LANE_WIDTH], pub timestamp_to_use_for_read: UInt32, pub timestamp_to_use_for_write: UInt32, pub precompile_call_params: Keccak256PrecompileCallParams, - pub u8_words_buffer: [UInt8; BYTES_BUFFER_SIZE], - pub u64_words_buffer_markers: [Boolean; BUFFER_SIZE_IN_U64_WORDS], + pub buffer: ByteBuffer, } impl CSPlaceholder for Keccak256RoundFunctionFSM { @@ -42,13 +46,13 @@ impl CSPlaceholder for Keccak256RoundFunctionFSM { Self { read_precompile_call: boolean_false, read_unaligned_words_for_round: boolean_false, + padding_round: boolean_false, completed: boolean_false, keccak_internal_state: [[[zero_u8; BYTES_PER_WORD]; LANE_WIDTH]; LANE_WIDTH], timestamp_to_use_for_read: zero_u32, timestamp_to_use_for_write: zero_u32, precompile_call_params: Keccak256PrecompileCallParams::::placeholder(cs), - u8_words_buffer: [zero_u8; BYTES_BUFFER_SIZE], - u64_words_buffer_markers: [boolean_false; BUFFER_SIZE_IN_U64_WORDS], + buffer: ByteBuffer::::placeholder(cs), } } } diff --git a/crates/zkevm_circuits/src/keccak256_round_function/mod.rs b/crates/zkevm_circuits/src/keccak256_round_function/mod.rs index b726488..fd524c5 100644 --- a/crates/zkevm_circuits/src/keccak256_round_function/mod.rs +++ b/crates/zkevm_circuits/src/keccak256_round_function/mod.rs @@ -2,6 +2,7 @@ use super::*; use boojum::field::SmallField; +use boojum::config::*; use boojum::cs::traits::cs::ConstraintSystem; use boojum::gadgets::boolean::Boolean; use boojum::gadgets::traits::selectable::Selectable; @@ -13,6 +14,7 @@ use cs_derive::*; use crate::ethereum_types::U256; use crate::fsm_input_output::circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH; +use crate::keccak256_round_function::buffer::ByteBuffer; use boojum::gadgets::num::Num; use zkevm_opcode_defs::system_params::PRECOMPILE_AUX_BYTE; @@ -35,6 +37,8 @@ use boojum::gadgets::u160::UInt160; use boojum::gadgets::u8::UInt8; use std::sync::{Arc, RwLock}; +pub mod buffer; + pub mod input; use self::input::*; @@ -43,55 +47,110 @@ use self::input::*; // #[DerivePrettyComparison("true")] pub struct Keccak256PrecompileCallParams { pub input_page: UInt32, - pub input_offset: UInt32, + pub input_memory_byte_offset: UInt32, + pub input_memory_byte_length: UInt32, pub output_page: UInt32, - pub output_offset: UInt32, - pub num_rounds: UInt32, + pub output_word_offset: UInt32, + pub needs_full_padding_round: Boolean, } impl CSPlaceholder for Keccak256PrecompileCallParams { fn placeholder>(cs: &mut CS) -> Self { let zero_u32 = UInt32::zero(cs); + let boolean_false = Boolean::allocated_constant(cs, false); Self { input_page: zero_u32, - input_offset: zero_u32, + input_memory_byte_offset: zero_u32, + input_memory_byte_length: zero_u32, output_page: zero_u32, - output_offset: zero_u32, - num_rounds: zero_u32, + output_word_offset: zero_u32, + needs_full_padding_round: boolean_false, } } } impl Keccak256PrecompileCallParams { - pub fn from_encoding>(_cs: &mut CS, encoding: UInt256) -> Self { - let input_offset = encoding.inner[0]; - let output_offset = encoding.inner[2]; + // from PrecompileCallABI + pub fn from_encoding>(cs: &mut CS, encoding: UInt256) -> Self { + let input_memory_byte_offset = encoding.inner[0]; + let input_memory_byte_length = encoding.inner[1]; + + let output_word_offset = encoding.inner[2]; + let input_page = encoding.inner[4]; let output_page = encoding.inner[5]; - let num_rounds = encoding.inner[6]; + let (_, rem) = input_memory_byte_length.div_by_constant(cs, KECCAK_RATE_BYTES as u32); + + let needs_full_padding_round = rem.is_zero(cs); let new = Self { input_page, - input_offset, + input_memory_byte_offset, + input_memory_byte_length, output_page, - output_offset, - num_rounds, + output_word_offset, + needs_full_padding_round, }; new } } +fn trivial_mapping_function< + F: SmallField, + CS: ConstraintSystem, + const N: usize, + const BUFFER_SIZE: usize, +>( + cs: &mut CS, + bytes_to_consume: &UInt8, + current_fill_factor: &UInt8, + _unused: [(); N], +) -> [Boolean; BUFFER_SIZE] { + use boojum::config::*; + if ::DebugConfig::PERFORM_RUNTIME_ASSERTS == true { + let already_filled = current_fill_factor.witness_hook(cs)(); + let new_to_fill = bytes_to_consume.witness_hook(cs)(); + if let Some(already_filled) = already_filled { + if let Some(new_to_fill) = new_to_fill { + assert!(new_to_fill as usize + already_filled as usize <= BUFFER_SIZE); + } + } + } + + let boolean_false = Boolean::allocated_constant(cs, false); + + let mut result = [boolean_false; BUFFER_SIZE]; + let zero_to_fill = bytes_to_consume.is_zero(cs); + let marker = zero_to_fill.negated(cs); + + // we just need to put a marker after the current fill value + let mut tmp = current_fill_factor.into_num(); + let one_num = Num::allocated_constant(cs, F::ONE); + for dst in result.iter_mut() { + let should_fill = tmp.is_zero(cs); + *dst = should_fill.and(cs, marker); + tmp = tmp.sub(cs, &one_num); + } + + // if crate::config::CIRCUIT_VERSOBE { + // dbg!(result.witness_hook(cs)().unwrap()); + // } + + result +} + +use boojum::gadgets::keccak256::KECCAK_RATE_BYTES; + pub const KECCAK256_RATE_IN_U64_WORDS: usize = 17; -pub const MEMORY_EQURIES_PER_CYCLE: usize = 5; // we need to read as much as possible to use a round function every cycle +pub const MEMORY_EQURIES_PER_CYCLE: usize = 6; // we need to read as much as possible to use a round function every cycle pub const NUM_U64_WORDS_PER_CYCLE: usize = 4 * MEMORY_EQURIES_PER_CYCLE; pub const NEW_BYTES_PER_CYCLE: usize = 8 * NUM_U64_WORDS_PER_CYCLE; // we absorb 136 elements per cycle, and add 160 elements per cycle, so we need to skip memory reads // sometimes and do absorbs instead -pub const BUFFER_SIZE_IN_U64_WORDS: usize = - MEMORY_EQURIES_PER_CYCLE * 4 + KECCAK256_RATE_IN_U64_WORDS - 1; -pub const BYTES_BUFFER_SIZE: usize = BUFFER_SIZE_IN_U64_WORDS * 8; +pub const BUFFER_SIZE_IN_U64_WORDS: usize = 192 / 8; +pub const BYTES_BUFFER_SIZE: usize = 192; pub fn keccak256_precompile_inner< F: SmallField, @@ -123,10 +182,13 @@ where let boolean_false = Boolean::allocated_constant(cs, false); let boolean_true = Boolean::allocated_constant(cs, true); let zero_u8 = UInt8::zero(cs); - let buffer_len_bound = UInt16::allocated_constant( - cs, - (BUFFER_SIZE_IN_U64_WORDS - NUM_U64_WORDS_PER_CYCLE + 1) as u16, - ); + let one_num = Num::allocated_constant(cs, F::ONE); + + let empty_buffer = ByteBuffer::::placeholder(cs); + + let mut full_padding_buffer = [zero_u8; KECCAK_RATE_BYTES]; + full_padding_buffer[0] = UInt8::allocated_constant(cs, 0x01); + full_padding_buffer[KECCAK_RATE_BYTES - 1] = UInt8::allocated_constant(cs, 0x80); // we can have a degenerate case when queue is empty, but it's a first circuit in the queue, // so we taken default FSM state that has state.read_precompile_call = true; @@ -137,7 +199,6 @@ where if crate::config::CIRCUIT_VERSOBE { dbg!(can_finish_immediatelly.witness_hook(cs)()); - dbg!(state.witness_hook(cs)()); } state.read_precompile_call = state @@ -148,8 +209,53 @@ where .mask_negated(cs, can_finish_immediatelly); state.completed = Boolean::multi_or(cs, &[state.completed, can_finish_immediatelly]); + #[allow(unused_variables)] + let mut keccak_self_verifier = None; + if ::DebugConfig::PERFORM_RUNTIME_ASSERTS == true { + use zkevm_opcode_defs::sha3::Digest; + if state.read_precompile_call.witness_hook(cs)().unwrap() == true { + keccak_self_verifier = Some((true, zkevm_opcode_defs::sha3::Keccak256::new())); + } else { + keccak_self_verifier = Some((false, zkevm_opcode_defs::sha3::Keccak256::new())); + } + } + + if crate::config::CIRCUIT_VERSOBE { + if let Ok(witness) = precompile_calls_queue.witness.elements.read() { + dbg!(witness.len()); + } + } + // main work cycle for _cycle in 0..limit { + if crate::config::CIRCUIT_VERSOBE { + dbg!(_cycle); + dbg!(state.read_precompile_call.witness_hook(cs)()); + dbg!(state.read_unaligned_words_for_round.witness_hook(cs)()); + dbg!(state.padding_round.witness_hook(cs)()); + dbg!(state.completed.witness_hook(cs)()); + dbg!(state + .precompile_call_params + .input_memory_byte_offset + .witness_hook(cs)()); + dbg!(state + .precompile_call_params + .input_memory_byte_length + .witness_hook(cs)()); + dbg!(precompile_calls_queue.length.witness_hook(cs)()); + if let Ok(witness) = precompile_calls_queue.witness.elements.read() { + dbg!(witness.len()); + } + } + + if ::DebugConfig::PERFORM_RUNTIME_ASSERTS == true { + use zkevm_opcode_defs::sha3::Digest; + if state.read_precompile_call.witness_hook(cs)().unwrap() == true { + *keccak_self_verifier.as_mut().unwrap() = + (true, zkevm_opcode_defs::sha3::Keccak256::new()); + } + } + // if we are in a proper state then get the ABI from the queue let (precompile_call, _) = precompile_calls_queue.pop_front(cs, state.read_precompile_call); @@ -178,6 +284,15 @@ where let params_encoding = precompile_call.key; let call_params = Keccak256PrecompileCallParams::from_encoding(cs, params_encoding); + if crate::config::CIRCUIT_VERSOBE { + if state.read_precompile_call.witness_hook(cs)().unwrap() == true { + println!( + "New request for params {:?}", + call_params.witness_hook(cs)().unwrap() + ); + } + } + state.precompile_call_params = Keccak256PrecompileCallParams::conditionally_select( cs, state.read_precompile_call, @@ -204,64 +319,119 @@ where // and do some work! keccak256 is expensive let reset_buffer = Boolean::multi_or(cs, &[state.read_precompile_call, state.completed]); + // if we just have read a precompile call with zero length input, we want to perform only one padding round + let new_request_is_input_length_zero = call_params.input_memory_byte_length.is_zero(cs); + let new_request_with_non_zero_length = new_request_is_input_length_zero.negated(cs); + let have_read_zero_length_call = Boolean::multi_and( + cs, + &[state.read_precompile_call, new_request_is_input_length_zero], + ); + // otherwise we proceed with reading the input and follow the logic of padding round based on the precomputed + // padding round needed/not needed in the params + let have_read_non_zero_length_call = Boolean::multi_and( + cs, + &[state.read_precompile_call, new_request_with_non_zero_length], + ); + + state.read_precompile_call = boolean_false; state.read_unaligned_words_for_round = Boolean::multi_or( cs, &[ - state.read_precompile_call, state.read_unaligned_words_for_round, + have_read_non_zero_length_call, ], ); - state.read_precompile_call = boolean_false; + state.padding_round = + Boolean::multi_or(cs, &[state.padding_round, have_read_zero_length_call]); + + if crate::config::CIRCUIT_VERSOBE { + dbg!(state.read_precompile_call.witness_hook(cs)()); + dbg!(state.read_unaligned_words_for_round.witness_hook(cs)()); + dbg!(state.padding_round.witness_hook(cs)()); + } // --------------------------------- // Now perform few memory queries to read content - for el in state.u64_words_buffer_markers.iter_mut() { - *el = Boolean::conditionally_select(cs, reset_buffer, &boolean_false, el); - } + state.buffer = ByteBuffer::::conditionally_select( + cs, + reset_buffer, + &empty_buffer, + &state.buffer, + ); + + // conditionally reset state. Keccak256 empty state is just all 0s - // even though it's not important, we cleanup the buffer too - for el in state.u8_words_buffer.iter_mut() { - *el = UInt8::conditionally_select(cs, reset_buffer, &zero_u8, el); + for dst in state.keccak_internal_state.iter_mut() { + for dst in dst.iter_mut() { + for dst in dst.iter_mut() { + *dst = dst.mask_negated(cs, reset_buffer); + } + } } - let initial_buffer_len = { - let lc: Vec<_> = state - .u64_words_buffer_markers - .iter() - .map(|el| (el.get_variable(), F::ONE)) - .collect(); - let lc = Num::linear_combination(cs, &lc); + let no_more_bytes = state + .precompile_call_params + .input_memory_byte_length + .is_zero(cs); + let have_leftover_bytes = no_more_bytes.negated(cs); + let should_read_in_general = Boolean::multi_and( + cs, + &[have_leftover_bytes, state.read_unaligned_words_for_round], + ); - unsafe { UInt16::from_variable_unchecked(lc.get_variable()) } + let mapping_function = |cs: &mut CS, + bytes_to_consume: UInt8, + current_fill_factor: UInt8, + _unused: [(); 32]| { + trivial_mapping_function::( + cs, + &bytes_to_consume, + ¤t_fill_factor, + _unused, + ) }; - // we can fill the buffer as soon as it's length <= MAX - NEW_WORDS_PER_CYCLE - let (_, of) = initial_buffer_len.overflowing_sub(cs, &buffer_len_bound); - let can_fill = of; - let can_not_fill = can_fill.negated(cs); - let zero_rounds_left = state.precompile_call_params.num_rounds.is_zero(cs); - // if we can not fill then we should (sanity check) be in a state of reading new words - // and have >0 rounds left - - state - .read_unaligned_words_for_round - .conditionally_enforce_true(cs, can_not_fill); - zero_rounds_left.conditionally_enforce_false(cs, can_not_fill); - let non_zero_rounds_left = zero_rounds_left.negated(cs); - - let should_read = Boolean::multi_and( - cs, - &[ - non_zero_rounds_left, - state.read_unaligned_words_for_round, - can_fill, - ], - ); + let mut bias_variable = should_read_in_general.get_variable(); + // logic in short - we always try to read from memory into buffer, + // and every time execute 1 keccak256 round function + for _ in 0..MEMORY_QUERIES_PER_CYCLE { + // we have a little more complex logic here, but it's homogenious + let (aligned_memory_index, unalignment) = state + .precompile_call_params + .input_memory_byte_offset + .div_by_constant(cs, 32); + let at_most_meaningful_bytes_in_query = UInt32::allocated_constant(cs, 32) + .into_num() + .sub(cs, &unalignment.into_num()); + let at_most_meaningful_bytes_in_query = unsafe { + UInt32::from_variable_unchecked(at_most_meaningful_bytes_in_query.get_variable()) + }; + let (_, uf) = state + .precompile_call_params + .input_memory_byte_length + .overflowing_sub(cs, at_most_meaningful_bytes_in_query); + let meaningful_bytes_in_query = UInt32::conditionally_select( + cs, + uf, + &state.precompile_call_params.input_memory_byte_length, + &at_most_meaningful_bytes_in_query, + ); + + let nothing_to_read = meaningful_bytes_in_query.is_zero(cs); + let have_something_to_read = nothing_to_read.negated(cs); + let bytes_to_fill = + unsafe { UInt8::from_variable_unchecked(meaningful_bytes_in_query.get_variable()) }; + let enough_buffer_space = state.buffer.can_fill_bytes(cs, bytes_to_fill); + let should_read = Boolean::multi_and( + cs, + &[ + have_something_to_read, + enough_buffer_space, + state.read_unaligned_words_for_round, + ], + ); - let mut new_bytes_to_read = [zero_u8; NEW_BYTES_PER_CYCLE]; - let mut bias_variable = should_read.get_variable(); - for dst in new_bytes_to_read.array_chunks_mut::<32>() { let read_query_value = memory_read_witness.conditionally_allocate_biased(cs, should_read, bias_variable); bias_variable = read_query_value.inner[0].get_variable(); @@ -269,114 +439,188 @@ where let read_query = MemoryQuery { timestamp: state.timestamp_to_use_for_read, memory_page: state.precompile_call_params.input_page, - index: state.precompile_call_params.input_offset, + index: aligned_memory_index, rw_flag: boolean_false, is_ptr: boolean_false, value: read_query_value, }; - let may_be_new_offset = unsafe { - state - .precompile_call_params - .input_offset - .increment_unchecked(cs) - }; - state.precompile_call_params.input_offset = UInt32::conditionally_select( + // perform read + memory_queue.push(cs, read_query, should_read); + + // update state variables + let may_be_new_input_memory_byte_offset = state + .precompile_call_params + .input_memory_byte_offset + .add_no_overflow(cs, meaningful_bytes_in_query); + let may_be_new_input_memory_byte_length = state + .precompile_call_params + .input_memory_byte_length + .sub_no_overflow(cs, meaningful_bytes_in_query); + + state.precompile_call_params.input_memory_byte_offset = UInt32::conditionally_select( cs, should_read, - &may_be_new_offset, - &state.precompile_call_params.input_offset, + &may_be_new_input_memory_byte_offset, + &state.precompile_call_params.input_memory_byte_offset, + ); + state.precompile_call_params.input_memory_byte_length = UInt32::conditionally_select( + cs, + should_read, + &may_be_new_input_memory_byte_length, + &state.precompile_call_params.input_memory_byte_length, ); - // perform read - memory_queue.push(cs, read_query, should_read); + // update if we do not read + let bytes_to_fill = bytes_to_fill.mask(cs, should_read); - // we need to change endianess. Memory is BE, and each of 4 byte chunks should be interpreted as BE u32 for sha256 + // fill the buffer let be_bytes = read_query_value.to_be_bytes(cs); - *dst = be_bytes; - } + // if crate::config::CIRCUIT_VERSOBE { + // dbg!(be_bytes.witness_hook(cs)().map(|el| hex::encode(&el))); + // } + let offset = unsafe { UInt8::from_variable_unchecked(unalignment.get_variable()) }; + + if crate::config::CIRCUIT_VERSOBE { + dbg!(hex::encode(&state.buffer.bytes.witness_hook(cs)().unwrap())); + dbg!(hex::encode(&be_bytes.witness_hook(cs)().unwrap())); + dbg!(bytes_to_fill.witness_hook(cs)().unwrap()); + } - // our buffer len fits at least to push new elements and get enough for round function - // this is quadratic complexity, but we it's easier to handle and cheap compared to round function - let should_push = should_read; + state + .buffer + .fill_with_bytes(cs, &be_bytes, offset, bytes_to_fill, mapping_function); - for src in new_bytes_to_read.array_chunks::<8>() { - let mut should_push = should_push; - for (is_busy, dst) in state - .u64_words_buffer_markers - .iter_mut() - .zip(state.u8_words_buffer.array_chunks_mut::<8>()) - { - let is_free = is_busy.negated(cs); - let update = Boolean::multi_and(cs, &[is_free, should_push]); - let should_not_update = update.negated(cs); - *dst = UInt8::parallel_select(cs, update, src, dst); - *is_busy = Boolean::multi_or(cs, &[update, *is_busy]); - should_push = Boolean::multi_and(cs, &[should_push, should_not_update]); + if crate::config::CIRCUIT_VERSOBE { + dbg!(hex::encode(&state.buffer.bytes.witness_hook(cs)().unwrap())); } - - Boolean::enforce_equal(cs, &should_push, &boolean_false); } - - let may_be_new_num_rounds = unsafe { - state - .precompile_call_params - .num_rounds - .decrement_unchecked(cs) - }; - state.precompile_call_params.num_rounds = UInt32::conditionally_select( + // now actually run keccak permutation + + // we either mask for padding, or mask in full if it's full padding round + let zero_bytes_left = state + .precompile_call_params + .input_memory_byte_length + .is_zero(cs); + + let currently_filled = state.buffer.filled; + let almost_filled = UInt8::allocated_constant(cs, (KECCAK_RATE_BYTES - 1) as u8); + let do_one_byte_of_padding = UInt8::equals(cs, ¤tly_filled, &almost_filled); + // NOTE: we have already precomputed if we will need a full padding round, so we just take something form buffer + // and run keccak premutation + let mut input = state + .buffer + .consume::(cs, boolean_true); + let buffer_now_empty = state.buffer.filled.is_zero(cs); + let no_extra_padding_round_required = state + .precompile_call_params + .needs_full_padding_round + .negated(cs); + let apply_padding = Boolean::multi_and( cs, - state.read_unaligned_words_for_round, - &may_be_new_num_rounds, - &state.precompile_call_params.num_rounds, + &[ + zero_bytes_left, + buffer_now_empty, + state.read_unaligned_words_for_round, + no_extra_padding_round_required, + ], ); - // absorb - - // compute shifted buffer that removes first RATE elements and padds with something - - // take some work - let mut input = [zero_u8; keccak256::KECCAK_RATE_BYTES]; - input.copy_from_slice(&state.u8_words_buffer[..keccak256::KECCAK_RATE_BYTES]); - - // keep the rest - let mut tmp_buffer = [zero_u8; BYTES_BUFFER_SIZE]; - tmp_buffer[..(BYTES_BUFFER_SIZE - keccak256::KECCAK_RATE_BYTES)] - .copy_from_slice(&state.u8_words_buffer[keccak256::KECCAK_RATE_BYTES..]); - - // also reset markers - let mut tmp_buffer_markers = [boolean_false; BUFFER_SIZE_IN_U64_WORDS]; - tmp_buffer_markers[..(BUFFER_SIZE_IN_U64_WORDS - KECCAK256_RATE_IN_U64_WORDS)] - .copy_from_slice(&state.u64_words_buffer_markers[KECCAK256_RATE_IN_U64_WORDS..]); + if ::DebugConfig::PERFORM_RUNTIME_ASSERTS == true { + use zkevm_opcode_defs::sha3::Digest; + if state.padding_round.witness_hook(cs)().unwrap() == false { + if apply_padding.witness_hook(cs)().unwrap() == true { + let bytes_to_feed = currently_filled.witness_hook(cs)().unwrap(); + let buffer_to_feed = input.witness_hook(cs)().unwrap(); + dbg!(hex::encode(&buffer_to_feed[..(bytes_to_feed as usize)])); + keccak_self_verifier + .as_mut() + .unwrap() + .1 + .update(&buffer_to_feed[..(bytes_to_feed as usize)]); + } else { + let buffer_to_feed = input.witness_hook(cs)().unwrap(); + dbg!(hex::encode(&buffer_to_feed[..])); + keccak_self_verifier + .as_mut() + .unwrap() + .1 + .update(&buffer_to_feed[..]); + } + } else { + // we absorb nothing, and "finalize" will take care of the rest + } + } - // update buffers - state.u8_words_buffer = tmp_buffer; - state.u64_words_buffer_markers = tmp_buffer_markers; + let mut tmp = currently_filled.into_num(); + let pad_constant = UInt8::allocated_constant(cs, 0x01); + for dst in input[..(KECCAK_RATE_BYTES - 1)].iter_mut() { + let pad_this_byte = tmp.is_zero(cs); + let apply_padding = Boolean::multi_and(cs, &[apply_padding, pad_this_byte]); + *dst = UInt8::conditionally_select(cs, apply_padding, &pad_constant, &*dst); + tmp = tmp.sub(cs, &one_num); + } - // conditionally reset state. Keccak256 empty state is just all 0s + let normal_last_byte_padding_value = UInt8::allocated_constant(cs, 0x80); + let special_last_byte_paddings_value = UInt8::allocated_constant(cs, 0x81); + let last_byte_padding_value = UInt8::conditionally_select( + cs, + do_one_byte_of_padding, + &special_last_byte_paddings_value, + &normal_last_byte_padding_value, + ); + input[KECCAK_RATE_BYTES - 1] = UInt8::conditionally_select( + cs, + apply_padding, + &last_byte_padding_value, + &input[KECCAK_RATE_BYTES - 1], + ); - for dst in state.keccak_internal_state.iter_mut() { - for dst in dst.iter_mut() { - for dst in dst.iter_mut() { - *dst = dst.mask_negated(cs, reset_buffer); - } - } + let input = + UInt8::::parallel_select(cs, state.padding_round, &full_padding_buffer, &input); + if crate::config::CIRCUIT_VERSOBE { + dbg!(input.witness_hook(cs)().map(|el| hex::encode(&el))); } // manually absorb and run round function let squeezed = keccak256_absorb_and_run_permutation(cs, &mut state.keccak_internal_state, &input); - let no_rounds_left = state.precompile_call_params.num_rounds.is_zero(cs); - let write_result = - Boolean::multi_and(cs, &[state.read_unaligned_words_for_round, no_rounds_left]); + let absorbed_and_padded = apply_padding; + // dbg!(absorbed_and_padded.witness_hook(cs)()); + // dbg!(state.padding_round.witness_hook(cs)()); + let finished_processing_current_request = + Boolean::multi_or(cs, &[absorbed_and_padded, state.padding_round]); + let write_result = finished_processing_current_request; + + if ::DebugConfig::PERFORM_RUNTIME_ASSERTS == true { + use zkevm_opcode_defs::sha3::Digest; + if write_result.witness_hook(cs)().unwrap() == true { + if keccak_self_verifier.as_mut().unwrap().0 == true { + keccak_self_verifier.as_mut().unwrap().0 = false; + let mut output = [0u8; 32]; + let internal_state = std::mem::replace( + &mut keccak_self_verifier.as_mut().unwrap().1, + zkevm_opcode_defs::sha3::Keccak256::new(), + ); + output.copy_from_slice(internal_state.finalize().as_slice()); + let circuit_result = squeezed.witness_hook(cs)().unwrap(); + assert_eq!(output, circuit_result); + } + } + } let result = UInt256::from_be_bytes(cs, squeezed); + if crate::config::CIRCUIT_VERSOBE { + if finished_processing_current_request.witness_hook(cs)().unwrap() { + dbg!(result.witness_hook(cs)()); + } + } let write_query = MemoryQuery { timestamp: state.timestamp_to_use_for_write, memory_page: state.precompile_call_params.output_page, - index: state.precompile_call_params.output_offset, + index: state.precompile_call_params.output_word_offset, rw_flag: boolean_true, is_ptr: boolean_false, value: result, @@ -387,7 +631,7 @@ where // --------------------------------- - // update call props + // update FSM state let input_is_empty = precompile_calls_queue.is_empty(cs); let input_is_not_empty = input_is_empty.negated(cs); let nothing_left = Boolean::multi_and(cs, &[write_result, input_is_empty]); @@ -395,7 +639,28 @@ where state.read_precompile_call = process_next; state.completed = Boolean::multi_or(cs, &[nothing_left, state.completed]); - let t = Boolean::multi_or(cs, &[state.read_precompile_call, state.completed]); + + // now we need to decide on full padding round + let needs_full_padding = Boolean::multi_and( + cs, + &[ + state.read_unaligned_words_for_round, + zero_bytes_left, + buffer_now_empty, + state.precompile_call_params.needs_full_padding_round, + ], + ); + state.padding_round = needs_full_padding; + + // otherwise we just continue + let t = Boolean::multi_or( + cs, + &[ + state.read_precompile_call, + state.padding_round, + state.completed, + ], + ); state.read_unaligned_words_for_round = t.negated(cs); } @@ -571,3 +836,310 @@ pub(crate) fn keccak256_absorb_and_run_permutation CSReferenceImplementation< + GoldilocksField, + GoldilocksField, + DevCSConfig, + impl GateConfigurationHolder, + impl StaticToolboxHolder, + > { + let geometry = CSGeometry { + num_columns_under_copy_permutation: 100, + num_witness_columns: 0, + num_constant_columns: 8, + max_allowed_constraint_degree: 4, + }; + + fn configure< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + let builder = builder.allow_lookup( + LookupParameters::UseSpecializedColumnsWithTableIdAsConstant { + width: 3, + num_repetitions: 8, + share_table_id: true, + }, + ); + let builder = ConstantsAllocatorGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = FmaGateInBaseFieldWithoutConstant::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ReductionGate::::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = BooleanConstraintGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<32>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<16>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<8>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = SelectionGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ZeroCheckGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + false, + ); + let builder = DotProductGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = MatrixMultiplicationGate::::configure_builder(builder,GatePlacementStrategy::UseGeneralPurposeColumns); + let builder = MatrixMultiplicationGate::::configure_builder(builder,GatePlacementStrategy::UseGeneralPurposeColumns); + let builder = NopGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + + builder + } + + use boojum::cs::cs_builder_reference::CsReferenceImplementationBuilder; + + let builder_impl = + CsReferenceImplementationBuilder::::new(geometry, 1 << 20); + use boojum::cs::cs_builder::new_builder; + let builder = new_builder::<_, F>(builder_impl); + + let builder = configure(builder); + let mut owned_cs = builder.build(1 << 26); + + // add tables for keccak + let table = create_xor8_table(); + owned_cs.add_lookup_table::(table); + + let table = create_and8_table(); + owned_cs.add_lookup_table::(table); + + let table = create_byte_split_table::(); + owned_cs.add_lookup_table::, 3>(table); + let table = create_byte_split_table::(); + owned_cs.add_lookup_table::, 3>(table); + let table = create_byte_split_table::(); + owned_cs.add_lookup_table::, 3>(table); + let table = create_byte_split_table::(); + owned_cs.add_lookup_table::, 3>(table); + + owned_cs + } + + fn bytes_to_u256_words(input: Vec, unalignement: usize) -> Vec { + let mut result = vec![]; + let mut it = std::iter::repeat(0xffu8) + .take(unalignement) + .chain(input.into_iter()); + 'outer: loop { + let mut done = false; + let mut buffer = [0u8; 32]; + for (idx, dst) in buffer.iter_mut().enumerate() { + if let Some(src) = it.next() { + *dst = src; + } else { + done = true; + if idx == 0 { + break 'outer; + } + break; + } + } + let el = U256::from_big_endian(&buffer); + result.push(el); + if done { + break 'outer; + } + } + + result + } + + fn test_for_length_and_unalignment(length: usize, unalignement: usize) { + use rand_new::{Rng, SeedableRng}; + let mut rng = rand_new::rngs::StdRng::from_seed([1u8; 32]); + let input: Vec = (0..length).map(|_| rng.gen()).collect(); + dbg!(hex::encode(&input)); + let input_witness = bytes_to_u256_words(input.clone(), unalignement); + + use boojum::sha3::Digest; + let reference: [u8; 32] = boojum::sha3::Keccak256::digest(&input) + .as_slice() + .try_into() + .unwrap(); + + let mut owned_cs = create_test_cs(); + let cs = &mut owned_cs; + let mut memory_queue = MemoryQueue::::empty(cs); + + let precompile_abi = PrecompileCallABI { + input_memory_offset: unalignement as u32, + input_memory_length: length as u32, + output_memory_offset: 0, + output_memory_length: 1, + memory_page_to_read: 123, + memory_page_to_write: 456, + precompile_interpreted_data: 0, + }; + let encoded_precompile_abi = precompile_abi.to_u256(); + let boolean_true = Boolean::allocated_constant(cs, true); + + let mut precompile_calls_queue = StorageLogQueue::::empty(cs); + let el = LogQueryWitness { + address: *zkevm_opcode_defs::system_params::KECCAK256_ROUND_FUNCTION_PRECOMPILE_FORMAL_ADDRESS, + key: encoded_precompile_abi, + read_value: U256::zero(), + written_value: U256::zero(), + aux_byte: PRECOMPILE_AUX_BYTE, + rw_flag: true, + rollback: false, + is_service: false, + shard_id: 0, + tx_number_in_block: 0, + timestamp: 0, + }; + let el = LogQuery::allocate(cs, el); + precompile_calls_queue.push(cs, el, boolean_true); + + let mut state = Keccak256RoundFunctionFSM::placeholder_witness(); + state.read_precompile_call = true; + state.timestamp_to_use_for_read = 1; + state.timestamp_to_use_for_write = 2; + + let state = Keccak256RoundFunctionFSM::allocate(cs, state); + let round_function = Poseidon2Goldilocks; + + let memory_read_witness = ConditionalWitnessAllocator::> { + witness_source: std::sync::Arc::new(std::sync::RwLock::new(input_witness.into())), + }; + + let new_state = keccak256_precompile_inner( + cs, + &mut memory_queue, + &mut precompile_calls_queue, + memory_read_witness, + state, + &round_function, + 2, + ); + + dbg!(new_state.witness_hook(cs)().unwrap()); + + drop(cs); + + let output = memory_queue + .witness + .elements + .read() + .unwrap() + .back() + .unwrap() + .clone(); + let mut buffer = [0u8; 32]; + assert!(output.0.rw_flag); + output.0.value.to_big_endian(&mut buffer); + + dbg!(hex::encode(&reference)); + dbg!(hex::encode(&buffer)); + + assert_eq!(buffer, reference); + + let _ = owned_cs.pad_and_shrink(); + let mut assembly = owned_cs.into_assembly::(); + let worker = Worker::new(); + let is_satisfied = assembly.check_if_satisfied(&worker); + assert!(is_satisfied); + } + + #[test] + fn keccak_256_aligned_one_round() { + test_for_length_and_unalignment(50, 0); + } + + #[test] + fn keccak_256_aligned_one_round_to_the_end() { + test_for_length_and_unalignment(135, 0); + } + + #[test] + fn keccak_256_aligned_two_rounds() { + test_for_length_and_unalignment(200, 0); + } + + #[test] + fn keccak_256_aligned_two_rounds_but_one_read_round() { + test_for_length_and_unalignment(180, 0); + } + + #[test] + fn keccak_256_aligned_one_round_and_padding_round() { + test_for_length_and_unalignment(136, 0); + } + + #[test] + fn keccak_256_unaligned_one_round() { + test_for_length_and_unalignment(50, 31); + } + + #[test] + fn keccak_256_unaligned_one_round_to_the_end() { + test_for_length_and_unalignment(135, 31); + } + + #[test] + fn keccak_256_unaligned_one_round_and_padding_round() { + test_for_length_and_unalignment(136, 31); + } + + #[test] + fn keccak_256_unaligned_two_rounds() { + test_for_length_and_unalignment(200, 31); + } + + #[test] + fn keccak_256_unaligned_two_rounds_but_one_read_round() { + test_for_length_and_unalignment(166, 22); + } +} diff --git a/crates/zkevm_circuits/src/lib.rs b/crates/zkevm_circuits/src/lib.rs index ddc2dcf..fe4420c 100644 --- a/crates/zkevm_circuits/src/lib.rs +++ b/crates/zkevm_circuits/src/lib.rs @@ -5,6 +5,7 @@ #![feature(generic_const_exprs)] #![feature(array_chunks)] #![feature(more_qualified_paths)] +#![feature(allocator_api)] use derivative::*; @@ -17,6 +18,7 @@ pub mod base_structures; pub mod code_unpacker_sha256; pub mod demux_log_queue; pub mod ecrecover; +pub mod eip_4844; pub mod fsm_input_output; pub mod keccak256_round_function; pub mod linear_hasher; diff --git a/crates/zkevm_circuits/src/log_sorter/mod.rs b/crates/zkevm_circuits/src/log_sorter/mod.rs index b29ccc9..be217ba 100644 --- a/crates/zkevm_circuits/src/log_sorter/mod.rs +++ b/crates/zkevm_circuits/src/log_sorter/mod.rs @@ -470,6 +470,8 @@ pub fn prepacked_long_comparison>( #[cfg(test)] mod tests { + use std::alloc::Global; + use super::*; use boojum::algebraic_props::poseidon2_parameters::Poseidon2GoldilocksExternalMatrix; use boojum::cs::implementations::reference_cs::CSDevelopmentAssembly; @@ -563,12 +565,12 @@ mod tests { use boojum::cs::cs_builder_reference::CsReferenceImplementationBuilder; let builder_impl = - CsReferenceImplementationBuilder::::new(geometry, 1 << 26, 1 << 20); + CsReferenceImplementationBuilder::::new(geometry, 1 << 20); use boojum::cs::cs_builder::new_builder; let builder = new_builder::<_, F>(builder_impl); let builder = configure(builder); - let mut owned_cs = builder.build(()); + let mut owned_cs = builder.build(1 << 26); // add tables let table = create_xor8_table(); @@ -628,7 +630,7 @@ mod tests { cs.pad_and_shrink(); let worker = Worker::new(); - let mut owned_cs = owned_cs.into_assembly(); + let mut owned_cs = owned_cs.into_assembly::(); owned_cs.print_gate_stats(); assert!(owned_cs.check_if_satisfied(&worker)); } diff --git a/crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/far_call.rs b/crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/far_call.rs index 125ee24..094a864 100644 --- a/crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/far_call.rs +++ b/crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/far_call.rs @@ -1007,6 +1007,15 @@ where let new_r1 = final_fat_ptr.into_register(cs); + if crate::config::CIRCUIT_VERSOBE { + if (execute.witness_hook(&*cs))().unwrap_or(false) { + println!( + "R1 value after far call is {:?}", + new_r1.witness_hook(cs)().unwrap() + ); + } + } + let one = Num::allocated_constant(cs, F::ONE); let r2_low = Num::fma( diff --git a/crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/ret.rs b/crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/ret.rs index 6f9773e..f33bb2e 100644 --- a/crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/ret.rs +++ b/crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/ret.rs @@ -98,6 +98,10 @@ where } } + // on panic, we should never return any data. in this case, zero out src0 data + let mut src0 = common_opcode_state.src0.clone(); + src0.conditionally_erase(cs, is_ret_panic); + let current_callstack_entry = draft_vm_state.callstack.current_context.saved_context; // we may want to return to label @@ -172,7 +176,7 @@ where let mut non_local_frame_exceptions = ArrayVec::, 4>::new(); let forward_fat_pointer = forwarding_data.forward_fat_pointer; - let src0_is_integer = common_opcode_state.src0_view.is_ptr.negated(cs); + let src0_is_integer = src0.is_pointer.negated(cs); let is_far_return = is_local_frame.negated(cs); // resolve returndata pointer if forwarded @@ -294,6 +298,18 @@ where ergs_left_after_growth.add_no_overflow(cs, new_callstack_entry.ergs_remaining); new_callstack_entry.ergs_remaining = new_ergs_left; + new_callstack_entry.heap_upper_bound = Selectable::conditionally_select( + cs, + is_local_frame, + &heap_bound, + &new_callstack_entry.heap_upper_bound, + ); + new_callstack_entry.aux_heap_upper_bound = Selectable::conditionally_select( + cs, + is_local_frame, + &aux_heap_bound, + &new_callstack_entry.aux_heap_upper_bound, + ); // resolve merging of the queues diff --git a/crates/zkevm_circuits/src/main_vm/opcodes/log.rs b/crates/zkevm_circuits/src/main_vm/opcodes/log.rs index 83b3338..f3aaf83 100644 --- a/crates/zkevm_circuits/src/main_vm/opcodes/log.rs +++ b/crates/zkevm_circuits/src/main_vm/opcodes/log.rs @@ -107,18 +107,22 @@ pub(crate) fn apply_log< }; // modify the key by replacing parts for precompile call + let read_page_is_zero = key.inner[4].is_zero(cs); + let write_page_is_zero = key.inner[5].is_zero(cs); let precompile_memory_page_to_read = opcode_carry_parts.heap_page; let precompile_memory_page_to_write = opcode_carry_parts.heap_page; + let should_swap_read_page = Boolean::multi_and(cs, &[read_page_is_zero, is_precompile]); + let should_swap_write_page = Boolean::multi_and(cs, &[write_page_is_zero, is_precompile]); // replace bits 128..160 and 160..192 key.inner[4] = UInt32::conditionally_select( cs, - is_precompile, + should_swap_read_page, &precompile_memory_page_to_read, &key.inner[4], ); key.inner[5] = UInt32::conditionally_select( cs, - is_precompile, + should_swap_write_page, &precompile_memory_page_to_write, &key.inner[5], ); diff --git a/crates/zkevm_circuits/src/main_vm/pre_state.rs b/crates/zkevm_circuits/src/main_vm/pre_state.rs index ff7ecc9..fb4c505 100644 --- a/crates/zkevm_circuits/src/main_vm/pre_state.rs +++ b/crates/zkevm_circuits/src/main_vm/pre_state.rs @@ -448,8 +448,38 @@ pub fn create_prestate< let selected_src0 = src0; let selected_src1 = src1_register; - let src0 = VMRegister::conditionally_select(cs, swap_operands, &selected_src1, &selected_src0); - let src1 = VMRegister::conditionally_select(cs, swap_operands, &selected_src0, &selected_src1); + let mut src0 = + VMRegister::conditionally_select(cs, swap_operands, &selected_src1, &selected_src0); + let mut src1 = + VMRegister::conditionally_select(cs, swap_operands, &selected_src0, &selected_src1); + + // Potentially erase fat pointer data if opcode shouldn't take pointers and we're not in kernel + // mode + let not_kernel_mode = is_kernel_mode.negated(cs); + let should_erase_src0_ptr_data = { + use zkevm_opcode_defs::*; + let is_ret = decoded_opcode + .properties_bits + .boolean_for_opcode(Opcode::Ret(RetOpcode::Ok)); + let is_ptr = decoded_opcode + .properties_bits + .boolean_for_opcode(Opcode::Ptr(PtrOpcode::Add)); + let is_uma = decoded_opcode + .properties_bits + .boolean_for_opcode(Opcode::UMA(UMAOpcode::AuxHeapRead)); + let is_far_call = decoded_opcode + .properties_bits + .boolean_for_opcode(Opcode::FarCall(FarCallOpcode::Delegate)); + + let should_erase = + Boolean::multi_or(cs, &[is_ret, is_ptr, is_uma, is_far_call]).negated(cs); + Boolean::multi_and(cs, &[src0.is_pointer, should_erase, not_kernel_mode]) + }; + // We erase fat pointer data from src1 if it exists in non-kernel mode + let should_erase_src1_ptr_data = Boolean::multi_and(cs, &[src1.is_pointer, not_kernel_mode]); + + src0.conditionally_erase_fat_pointer_data(cs, should_erase_src0_ptr_data); + src1.conditionally_erase_fat_pointer_data(cs, should_erase_src1_ptr_data); let src0_view = RegisterInputView::from_input_value(cs, &src0); let src1_view = RegisterInputView::from_input_value(cs, &src1); diff --git a/crates/zkevm_circuits/src/main_vm/utils.rs b/crates/zkevm_circuits/src/main_vm/utils.rs index 9463d6e..cf04d7b 100644 --- a/crates/zkevm_circuits/src/main_vm/utils.rs +++ b/crates/zkevm_circuits/src/main_vm/utils.rs @@ -356,7 +356,7 @@ pub fn resolve_memory_region_and_index_for_dest, const N: usize #[cfg(test)] mod tests { + use std::alloc::Global; + use super::*; use boojum::algebraic_props::poseidon2_parameters::Poseidon2GoldilocksExternalMatrix; use boojum::cs::gates::*; @@ -487,12 +489,12 @@ mod tests { use boojum::cs::cs_builder_reference::CsReferenceImplementationBuilder; let builder_impl = - CsReferenceImplementationBuilder::::new(geometry, 1 << 26, 1 << 20); + CsReferenceImplementationBuilder::::new(geometry, 1 << 20); use boojum::cs::cs_builder::new_builder; let builder = new_builder::<_, F>(builder_impl); let builder = configure(builder); - let mut owned_cs = builder.build(()); + let mut owned_cs = builder.build(1 << 26); // add tables let table = create_xor8_table(); @@ -549,7 +551,7 @@ mod tests { cs.pad_and_shrink(); let worker = Worker::new(); - let mut owned_cs = owned_cs.into_assembly(); + let mut owned_cs = owned_cs.into_assembly::(); owned_cs.print_gate_stats(); assert!(owned_cs.check_if_satisfied(&worker)); } diff --git a/crates/zkevm_circuits/src/scheduler/auxiliary.rs b/crates/zkevm_circuits/src/scheduler/auxiliary.rs index 08c66b2..39ec706 100644 --- a/crates/zkevm_circuits/src/scheduler/auxiliary.rs +++ b/crates/zkevm_circuits/src/scheduler/auxiliary.rs @@ -14,6 +14,7 @@ use boojum::gadgets::traits::round_function::CircuitRoundFunction; use boojum::gadgets::{boolean::Boolean, num::Num, queue::*, traits::selectable::Selectable}; use crate::base_structures::precompile_input_outputs::*; +use crate::eip_4844::input::EIP4844OutputData; use crate::log_sorter::input::*; use crate::storage_application::input::*; use boojum::gadgets::u8::UInt8; diff --git a/crates/zkevm_circuits/src/scheduler/block_header/mod.rs b/crates/zkevm_circuits/src/scheduler/block_header/mod.rs index c54d2a6..011593c 100644 --- a/crates/zkevm_circuits/src/scheduler/block_header/mod.rs +++ b/crates/zkevm_circuits/src/scheduler/block_header/mod.rs @@ -20,6 +20,7 @@ use boojum::serde_utils::BigArraySerde; use boojum::gadgets::keccak256; pub const NUM_SHARDS: usize = 2; +pub const MAX_4844_BLOBS_PER_BLOCK: usize = 2; // Data that represents a pure state #[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] @@ -54,6 +55,8 @@ pub struct BlockAuxilaryOutput { pub rollup_state_diff_for_compression: [UInt8; 32], pub bootloader_heap_initial_content: [UInt8; 32], pub events_queue_state: [UInt8; 32], + pub eip4844_linear_hashes: [[UInt8; 32]; MAX_4844_BLOBS_PER_BLOCK], + pub eip4844_output_commitment_hashes: [[UInt8; 32]; MAX_4844_BLOBS_PER_BLOCK], } #[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] @@ -123,6 +126,14 @@ impl BlockAuxilaryOutput { result.extend_from_slice(&self.rollup_state_diff_for_compression); result.extend_from_slice(&self.bootloader_heap_initial_content); result.extend_from_slice(&self.events_queue_state); + for (linear_hash, blob_opening_commitment) in self + .eip4844_linear_hashes + .iter() + .zip(self.eip4844_output_commitment_hashes.iter()) + { + result.extend_from_slice(linear_hash); + result.extend_from_slice(blob_opening_commitment); + } result } diff --git a/crates/zkevm_circuits/src/scheduler/input.rs b/crates/zkevm_circuits/src/scheduler/input.rs index 1263b63..7d4f314 100644 --- a/crates/zkevm_circuits/src/scheduler/input.rs +++ b/crates/zkevm_circuits/src/scheduler/input.rs @@ -74,6 +74,10 @@ pub struct SchedulerCircuitInstanceWitness< pub previous_block_meta_hash: [u8; 32], pub previous_block_aux_hash: [u8; 32], + // eip4844 witnesses + pub eip4844_witnesses: Option<[EIP4844OutputDataWitness; MAX_4844_BLOBS_PER_BLOCK]>, + pub eip4844_proofs: VecDeque>, + // proofs for every individual circuit type's aggregation subtree #[derivative(Debug = "ignore")] pub proof_witnesses: VecDeque>, @@ -122,6 +126,9 @@ impl>, EXT: FieldExtension<2, Ba previous_block_meta_hash: [0u8; 32], previous_block_aux_hash: [0u8; 32], + eip4844_witnesses: None, + eip4844_proofs: VecDeque::new(), + proof_witnesses: VecDeque::new(), node_layer_vk_witness: VerificationKey::default(), leaf_layer_parameters: std::array::from_fn(|_| { diff --git a/crates/zkevm_circuits/src/scheduler/mod.rs b/crates/zkevm_circuits/src/scheduler/mod.rs index 817bf82..36dfb5c 100644 --- a/crates/zkevm_circuits/src/scheduler/mod.rs +++ b/crates/zkevm_circuits/src/scheduler/mod.rs @@ -11,6 +11,7 @@ pub use auxiliary as aux; use boojum::cs::implementations::proof::Proof; +use boojum::cs::implementations::verifier::VerificationKey; use boojum::cs::traits::cs::ConstraintSystem; use boojum::field::SmallField; @@ -36,6 +37,7 @@ use crate::fsm_input_output::circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH; use crate::linear_hasher::input::LinearHasherOutputData; use crate::recursion::VK_COMMITMENT_LENGTH; use crate::scheduler::auxiliary::NUM_CIRCUIT_TYPES_TO_SCHEDULE; +use crate::utils::is_equal_queue_state; use boojum::gadgets::num::Num; use boojum::gadgets::recursion::recursive_tree_hasher::RecursiveTreeHasher; @@ -56,6 +58,7 @@ use std::collections::HashMap; use crate::base_structures::vm_state::*; use crate::code_unpacker_sha256::input::*; use crate::demux_log_queue::input::*; +use crate::eip_4844::input::*; use crate::fsm_input_output::circuit_inputs::main_vm::*; use crate::fsm_input_output::*; use crate::log_sorter::input::*; @@ -71,6 +74,7 @@ pub const SCHEDULER_TIMESTAMP: u32 = 1; pub const NUM_SCHEDULER_PUBLIC_INPUTS: usize = 4; pub const LEAF_LAYER_PARAMETERS_COMMITMENT_LENGTH: usize = 4; pub const QUEUE_FINAL_STATE_COMMITMENT_LENGTH: usize = 4; +pub const IMPLEMENT_4844_FUNCTIONALITY: bool = false; pub const SEQUENCE_OF_CIRCUIT_TYPES: [BaseLayerCircuitType; NUM_CIRCUIT_TYPES_TO_SCHEDULE] = [ BaseLayerCircuitType::VM, @@ -115,12 +119,17 @@ pub fn scheduler_function< TransciptParameters = TR::TransciptParameters, >, POW: RecursivePoWRunner, + const USE_4844: bool, >( cs: &mut CS, mut witness: SchedulerCircuitInstanceWitness, round_function: &R, config: SchedulerConfig, verifier_builder: Box>, + eip4844_proof_config: Option, + eip4844_vk_fixed_parameters: Option, + eip4844_vk: Option>, + eip4844_verifier_builder: Option>>, transcript_params: TR::TransciptParameters, ) where [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, @@ -566,48 +575,112 @@ pub fn scheduler_function< // we can potentially skip some circuits let mut skip_flags = [None; NUM_CIRCUIT_TYPES_TO_SCHEDULE]; // we can skip everything except VM - skip_flags[(BaseLayerCircuitType::DecommitmentsFilter as u8 as usize) - 1] = Some( - decommittments_sorter_circuit_input + // and if we skip, then we should ensure some invariants over outputs! + + // decommits sorter must output empty queue + { + let should_skip = decommittments_sorter_circuit_input .initial_queue_state .tail .length - .is_zero(cs), - ); - skip_flags[(BaseLayerCircuitType::Decommiter as u8 as usize) - 1] = Some( - code_decommitter_circuit_input + .is_zero(cs); + + let output_queue_is_empty = decommits_sorter_observable_output + .final_queue_state + .tail + .length + .is_zero(cs); + output_queue_is_empty.conditionally_enforce_true(cs, should_skip); + + skip_flags[(BaseLayerCircuitType::DecommitmentsFilter as u8 as usize) - 1] = + Some(should_skip); + } + + // decommitter should produce the same memory sequence + { + let should_skip = code_decommitter_circuit_input .sorted_requests_queue_initial_state .tail .length - .is_zero(cs), - ); - skip_flags[(BaseLayerCircuitType::LogDemultiplexer as u8 as usize) - 1] = Some( - log_demux_circuit_input + .is_zero(cs); + + let input_state = code_decommitter_circuit_input.memory_queue_initial_state; + let output_state = code_decommitter_observable_output.memory_queue_final_state; + + let same_state = is_equal_queue_state(cs, &input_state, &output_state); + same_state.conditionally_enforce_true(cs, should_skip); + + skip_flags[(BaseLayerCircuitType::Decommiter as u8 as usize) - 1] = Some(should_skip); + } + + // demux must produce empty outputs + { + let should_skip = log_demux_circuit_input .initial_log_queue_state .tail .length - .is_zero(cs), - ); - skip_flags[(BaseLayerCircuitType::KeccakPrecompile as u8 as usize) - 1] = Some( - log_demuxer_observable_output + .is_zero(cs); + + for subqueue in log_demuxer_observable_output + .all_output_queues_refs() + .into_iter() + { + let output_queue_is_empty = subqueue.tail.length.is_zero(cs); + output_queue_is_empty.conditionally_enforce_true(cs, should_skip); + } + + skip_flags[(BaseLayerCircuitType::LogDemultiplexer as u8 as usize) - 1] = Some(should_skip); + } + + // keccak, sha256 and ecrecover must not modify memory + { + let should_skip = log_demuxer_observable_output .keccak256_access_queue_state .tail .length - .is_zero(cs), - ); - skip_flags[(BaseLayerCircuitType::Sha256Precompile as u8 as usize) - 1] = Some( - log_demuxer_observable_output + .is_zero(cs); + + let input_state = code_decommitter_observable_output.memory_queue_final_state; + let output_state = keccak256_observable_output.final_memory_state; + + let same_state = is_equal_queue_state(cs, &input_state, &output_state); + same_state.conditionally_enforce_true(cs, should_skip); + + skip_flags[(BaseLayerCircuitType::KeccakPrecompile as u8 as usize) - 1] = Some(should_skip); + } + { + let should_skip = log_demuxer_observable_output .sha256_access_queue_state .tail .length - .is_zero(cs), - ); - skip_flags[(BaseLayerCircuitType::EcrecoverPrecompile as u8 as usize) - 1] = Some( - log_demuxer_observable_output + .is_zero(cs); + + let input_state = keccak256_observable_output.final_memory_state; + let output_state = sha256_observable_output.final_memory_state; + + let same_state = is_equal_queue_state(cs, &input_state, &output_state); + same_state.conditionally_enforce_true(cs, should_skip); + + skip_flags[(BaseLayerCircuitType::Sha256Precompile as u8 as usize) - 1] = Some(should_skip); + } + { + let should_skip = log_demuxer_observable_output .ecrecover_access_queue_state .tail .length - .is_zero(cs), - ); + .is_zero(cs); + + let input_state = sha256_observable_output.final_memory_state; + let output_state = ecrecover_observable_output.final_memory_state; + + let same_state = is_equal_queue_state(cs, &input_state, &output_state); + same_state.conditionally_enforce_true(cs, should_skip); + + skip_flags[(BaseLayerCircuitType::EcrecoverPrecompile as u8 as usize) - 1] = + Some(should_skip); + } + + // well, in the very unlikely case of no RAM requests (that is unreachable because VM always starts) we just skip it as is skip_flags[(BaseLayerCircuitType::RamValidation as u8 as usize) - 1] = Some( ram_validation_circuit_input .unsorted_queue_initial_state @@ -615,24 +688,93 @@ pub fn scheduler_function< .length .is_zero(cs), ); - skip_flags[(BaseLayerCircuitType::StorageFilter as u8 as usize) - 1] = - Some(storage_queues_state[0].tail.length.is_zero(cs)); - skip_flags[(BaseLayerCircuitType::StorageApplicator as u8 as usize) - 1] = - Some(filtered_storage_queues_state[0].tail.length.is_zero(cs)); - skip_flags[(BaseLayerCircuitType::EventsRevertsFilter as u8 as usize) - 1] = Some( - log_demuxer_observable_output + // storage filter must produce an empty output + { + let should_skip = storage_queues_state[0].tail.length.is_zero(cs); + + let output_queue_is_empty = filtered_storage_queues_state[0].tail.length.is_zero(cs); + output_queue_is_empty.conditionally_enforce_true(cs, should_skip); + + skip_flags[(BaseLayerCircuitType::StorageFilter as u8 as usize) - 1] = Some(should_skip); + } + // storage application must leave root untouched + { + let should_skip = filtered_storage_queues_state[0].tail.length.is_zero(cs); + + let initial_root = initial_state_roots[0]; + let initial_enumeration_counter = initial_enumeration_counters[0]; + let final_root = final_state_roots[0]; + let final_enumeration_counter = final_enumeration_counters[0]; + + let diffs_hash = storage_diffs_for_compression[0]; + + let root_parts_are_equal: [Boolean; 32] = + std::array::from_fn(|i| UInt8::equals(cs, &initial_root[i], &final_root[i])); + let roots_are_equal = Boolean::multi_and(cs, &root_parts_are_equal); + + let enumeration_counters_are_equal_low = UInt32::equals( + cs, + &initial_enumeration_counter[0], + &final_enumeration_counter[0], + ); + let enumeration_counters_are_equal_high = UInt32::equals( + cs, + &initial_enumeration_counter[1], + &final_enumeration_counter[1], + ); + + let diffs_parts_are_zero: [Boolean; 32] = diffs_hash.map(|el| el.is_zero(cs)); + let diffs_hash_is_zero = Boolean::multi_and(cs, &diffs_parts_are_zero); + + let root_is_unchanged = Boolean::multi_and( + cs, + &[ + roots_are_equal, + enumeration_counters_are_equal_low, + enumeration_counters_are_equal_high, + diffs_hash_is_zero, + ], + ); + root_is_unchanged.conditionally_enforce_true(cs, should_skip); + + skip_flags[(BaseLayerCircuitType::StorageApplicator as u8 as usize) - 1] = + Some(should_skip); + } + // events and l2 to l1 messages filters should produce empty output + { + let should_skip = log_demuxer_observable_output .events_access_queue_state .tail .length - .is_zero(cs), - ); - skip_flags[(BaseLayerCircuitType::L1MessagesRevertsFilter as u8 as usize) - 1] = Some( - log_demuxer_observable_output + .is_zero(cs); + + let output_queue_is_empty = events_sorter_observable_output + .final_queue_state + .tail + .length + .is_zero(cs); + output_queue_is_empty.conditionally_enforce_true(cs, should_skip); + + skip_flags[(BaseLayerCircuitType::EventsRevertsFilter as u8 as usize) - 1] = + Some(should_skip); + } + { + let should_skip = log_demuxer_observable_output .l1messages_access_queue_state .tail .length - .is_zero(cs), - ); + .is_zero(cs); + + let output_queue_is_empty = l1messages_sorter_observable_output + .final_queue_state + .tail + .length + .is_zero(cs); + output_queue_is_empty.conditionally_enforce_true(cs, should_skip); + + skip_flags[(BaseLayerCircuitType::L1MessagesRevertsFilter as u8 as usize) - 1] = + Some(should_skip); + } // for (idx, el) in skip_flags.iter().enumerate() { // if let Some(el) = el { @@ -978,12 +1120,93 @@ pub fn scheduler_function< dst.reverse(); } + let (eip4844_linear_hashes, eip4844_output_commitment_hashes) = if USE_4844 { + // eip4844 circuit + let verifier_builder = + eip4844_verifier_builder.expect("if EIP 4844 is used then builder must be provided"); + let verifier = verifier_builder.create_recursive_verifier(cs); + let proof_config = + eip4844_proof_config.expect("if EIP 4844 is used then proof config must be provided"); + let vk_fixed_parameters = eip4844_vk_fixed_parameters + .expect("if EIP 4844 is used then vk fixed parameters must be provided"); + let vk = eip4844_vk.expect("if EIP 4844 is used then VK must be provided"); + + let eip4844_vk = AllocatedVerificationKey::::allocate_constant(cs, vk); + + let mut eip4844_linear_hashes = [[zero_u8; 32]; MAX_4844_BLOBS_PER_BLOCK]; + let mut eip4844_output_commitment_hashes = [[zero_u8; 32]; MAX_4844_BLOBS_PER_BLOCK]; + for i in 0..MAX_4844_BLOBS_PER_BLOCK { + let observable_output_data_witness = witness + .eip4844_witnesses + .as_ref() + .expect("if EIP 4844 is used then witness must be provided") + .get(i) + .cloned() + .unwrap_or(EIP4844OutputData::placeholder_witness()); + let observable_output_data = + EIP4844OutputData::allocate(cs, observable_output_data_witness); + let zeroes = observable_output_data.linear_hash.map(|el| el.is_zero(cs)); + let skip_verification = Boolean::multi_and(cs, &zeroes); + let should_verify = skip_verification.negated(cs); + let structured_input = EIP4844InputOutput { + start_flag: boolean_true, + completion_flag: boolean_true, + observable_input: (), + observable_output: observable_output_data, + hidden_fsm_input: (), + hidden_fsm_output: (), + }; + + let closed_form_input = + ClosedFormInputCompactForm::from_full_form(cs, &structured_input, round_function); + let expected_input_commitment: [_; INPUT_OUTPUT_COMMITMENT_LENGTH] = + commit_variable_length_encodable_item(cs, &closed_form_input, round_function); + + let proof_witness = witness.eip4844_proofs.pop_front(); + + let proof = AllocatedProof::allocate_from_witness( + cs, + proof_witness, + &verifier, + &vk_fixed_parameters, + &proof_config, + ); + + let (is_valid, inputs) = verifier.verify::( + cs, + transcript_params.clone(), + &proof, + &vk_fixed_parameters, + &proof_config, + &eip4844_vk, + ); + is_valid.conditionally_enforce_true(cs, should_verify); + assert_eq!(inputs.len(), expected_input_commitment.len()); + + for (a, b) in inputs.iter().zip(expected_input_commitment.iter()) { + Num::conditionally_enforce_equal(cs, should_verify, a, b); + } + + eip4844_linear_hashes[i] = observable_output_data.linear_hash; + eip4844_output_commitment_hashes[i] = observable_output_data.output_hash; + } + + (eip4844_linear_hashes, eip4844_output_commitment_hashes) + } else { + ( + [[zero_u8; 32]; MAX_4844_BLOBS_PER_BLOCK], + [[zero_u8; 32]; MAX_4844_BLOBS_PER_BLOCK], + ) + }; + let aux_data = BlockAuxilaryOutput { rollup_state_diff_for_compression: storage_application_observable_output .state_diffs_keccak256_hash, bootloader_heap_initial_content, events_queue_state, l1_messages_linear_hash: l1messages_linear_hasher_observable_output.keccak256_hash, + eip4844_linear_hashes: eip4844_linear_hashes, + eip4844_output_commitment_hashes: eip4844_output_commitment_hashes, }; let block_content_header = BlockContentHeader { diff --git a/crates/zkevm_circuits/src/sort_decommittment_requests/mod.rs b/crates/zkevm_circuits/src/sort_decommittment_requests/mod.rs index 9c5b51b..4b9950d 100644 --- a/crates/zkevm_circuits/src/sort_decommittment_requests/mod.rs +++ b/crates/zkevm_circuits/src/sort_decommittment_requests/mod.rs @@ -398,6 +398,8 @@ fn concatenate_key>( #[cfg(test)] mod tests { + use std::alloc::Global; + use super::*; use crate::ethereum_types::U256; use boojum::algebraic_props::poseidon2_parameters::Poseidon2GoldilocksExternalMatrix; @@ -489,12 +491,12 @@ mod tests { use boojum::cs::cs_builder_reference::CsReferenceImplementationBuilder; let builder_impl = - CsReferenceImplementationBuilder::::new(geometry, 1 << 26, 1 << 20); + CsReferenceImplementationBuilder::::new(geometry, 1 << 20); use boojum::cs::cs_builder::new_builder; let builder = new_builder::<_, F>(builder_impl); let builder = configure(builder); - let mut owned_cs = builder.build(()); + let mut owned_cs = builder.build(1 << 26); // add tables let table = create_xor8_table(); @@ -556,7 +558,7 @@ mod tests { cs.pad_and_shrink(); let worker = Worker::new(); - let mut owned_cs = owned_cs.into_assembly(); + let mut owned_cs = owned_cs.into_assembly::(); owned_cs.print_gate_stats(); assert!(owned_cs.check_if_satisfied(&worker)); } diff --git a/crates/zkevm_circuits/src/storage_validity_by_grand_product/mod.rs b/crates/zkevm_circuits/src/storage_validity_by_grand_product/mod.rs index 356c481..9dee43f 100644 --- a/crates/zkevm_circuits/src/storage_validity_by_grand_product/mod.rs +++ b/crates/zkevm_circuits/src/storage_validity_by_grand_product/mod.rs @@ -655,8 +655,9 @@ where { let not_keys_are_equal = keys_are_equal.negated(cs); if _cycle == 0 { - // it must always be true if we start - not_keys_are_equal.conditionally_enforce_true(cs, is_start); + // it must always be true if we start and if we have items to work with + let enforce = is_start.and(cs, should_pop); + not_keys_are_equal.conditionally_enforce_true(cs, enforce); } // finish with the old one // if somewhere along the way we did encounter a read at rollback depth zero (not important if there were such), @@ -944,6 +945,8 @@ pub fn unpacked_long_comparison, const N: #[cfg(test)] mod tests { + use std::alloc::Global; + use super::*; use boojum::algebraic_props::poseidon2_parameters::Poseidon2GoldilocksExternalMatrix; use boojum::cs::implementations::reference_cs::{ @@ -1041,12 +1044,12 @@ mod tests { use boojum::cs::cs_builder_reference::*; let builder_impl = - CsReferenceImplementationBuilder::::new(geometry, 1 << 26, 1 << 20); + CsReferenceImplementationBuilder::::new(geometry, 1 << 20); use boojum::cs::cs_builder::new_builder; let builder = new_builder::<_, F>(builder_impl); let builder = configure(builder); - let mut owned_cs = builder.build(()); + let mut owned_cs = builder.build(1 << 26); // add tables let table = create_xor8_table(); @@ -1126,7 +1129,7 @@ mod tests { cs.pad_and_shrink(); let worker = Worker::new(); - let mut owned_cs = owned_cs.into_assembly(); + let mut owned_cs = owned_cs.into_assembly::(); owned_cs.print_gate_stats(); assert!(owned_cs.check_if_satisfied(&worker)); } diff --git a/crates/zkevm_circuits/src/utils.rs b/crates/zkevm_circuits/src/utils.rs index d0356d5..dbf94fe 100644 --- a/crates/zkevm_circuits/src/utils.rs +++ b/crates/zkevm_circuits/src/utils.rs @@ -4,7 +4,7 @@ use boojum::cs::Variable; use boojum::field::SmallField; use boojum::gadgets::boolean::Boolean; use boojum::gadgets::num::Num; -use boojum::gadgets::queue::QueueTailState; +use boojum::gadgets::queue::{QueueState, QueueTailState}; use boojum::gadgets::traits::round_function::CircuitRoundFunction; use boojum::gadgets::traits::selectable::Selectable; use boojum::gadgets::u32::UInt32; @@ -135,3 +135,21 @@ pub fn accumulate_grand_products< *rhs = Num::conditionally_select(cs, should_accumulate, &new_rhs, &rhs); } } + +pub fn is_equal_queue_state, const N: usize>( + cs: &mut CS, + a: &QueueState, + b: &QueueState, +) -> Boolean { + let head_parts_are_equal: [Boolean; N] = + std::array::from_fn(|i| Num::equals(cs, &a.head[i], &b.head[i])); + let heads_are_equal = Boolean::multi_and(cs, &head_parts_are_equal); + + let tail_parts_are_equal: [Boolean; N] = + std::array::from_fn(|i| Num::equals(cs, &a.tail.tail[i], &b.tail.tail[i])); + let tail_are_equal = Boolean::multi_and(cs, &tail_parts_are_equal); + + let lengths_are_equal = UInt32::equals(cs, &a.tail.length, &b.tail.length); + + Boolean::multi_and(cs, &[heads_are_equal, tail_are_equal, lengths_are_equal]) +} diff --git a/crates/zkevm_opcode_defs/Cargo.toml b/crates/zkevm_opcode_defs/Cargo.toml index 10e0c12..ae50bb5 100644 --- a/crates/zkevm_opcode_defs/Cargo.toml +++ b/crates/zkevm_opcode_defs/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zkevm_opcode_defs" -version = "0.132.0" +version = "0.141.0" edition = "2021" authors = ["The Matter Labs Team "] homepage = "https://zksync.io/" @@ -22,7 +22,7 @@ path = "src/circuit_pricing_generator/main.rs" bitflags = "2" lazy_static = "1.4" ethereum-types = "=0.14.1" -sha2 = { package = "sha2_ce", version = "=0.10.6" } -sha3 = { package = "sha3_ce", version = "=0.10.6" } -blake2 = { package = "blake2", version = "=0.10.6" } -k256 = { version = "0.11.6", features = ["arithmetic", "ecdsa"] } +sha2 = "=0.10.8" +sha3 = "=0.10.8" +blake2 = "0.10.*" +k256 = { version = "0.13.*", features = ["arithmetic", "ecdsa"] } diff --git a/crates/zkevm_opcode_defs/deny.toml b/crates/zkevm_opcode_defs/deny.toml index 77d7d23..a957d98 100644 --- a/crates/zkevm_opcode_defs/deny.toml +++ b/crates/zkevm_opcode_defs/deny.toml @@ -72,9 +72,7 @@ skip-tree = [ unknown-registry = "deny" unknown-git = "deny" allow-registry = ["https://github.com/rust-lang/crates.io-index"] -allow-git = [ - "https://github.com/RustCrypto/hashes.git", -] +allow-git = [] [sources.allow-org] #github = ["matter-labs"] diff --git a/crates/zkevm_opcode_defs/src/definitions/abi/precompile_call.rs b/crates/zkevm_opcode_defs/src/definitions/abi/precompile_call.rs index 9d62111..b20f24a 100644 --- a/crates/zkevm_opcode_defs/src/definitions/abi/precompile_call.rs +++ b/crates/zkevm_opcode_defs/src/definitions/abi/precompile_call.rs @@ -1,37 +1,9 @@ use super::*; +// Note: offsets and length params below can be byte or word, or in general +// callee's interpreted #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct PrecompileCallABI { - pub input_memory_offset: u32, - pub input_memory_length: u32, - pub output_memory_offset: u32, - pub output_memory_length: u32, - pub per_precompile_interpreted: u64, -} - -impl PrecompileCallABI { - pub const fn from_u256(raw_value: U256) -> Self { - let raw = raw_value.0; - let input_memory_offset = raw[0] as u32; - let input_memory_length = (raw[0] >> 32) as u32; - - let output_memory_offset = raw[1] as u32; - let output_memory_length = (raw[1] >> 32) as u32; - - let per_precompile_interpreted = raw[3]; - - Self { - input_memory_offset, - input_memory_length, - output_memory_offset, - output_memory_length, - per_precompile_interpreted, - } - } -} - -#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct PrecompileCallInnerABI { pub input_memory_offset: u32, pub input_memory_length: u32, pub output_memory_offset: u32, @@ -41,7 +13,7 @@ pub struct PrecompileCallInnerABI { pub precompile_interpreted_data: u64, } -impl PrecompileCallInnerABI { +impl PrecompileCallABI { pub const fn from_u256(raw_value: U256) -> Self { let raw = raw_value.0; let input_memory_offset = raw[0] as u32; diff --git a/crates/zkevm_opcode_defs/src/definitions/add.rs b/crates/zkevm_opcode_defs/src/definitions/add.rs index c307330..e33f734 100644 --- a/crates/zkevm_opcode_defs/src/definitions/add.rs +++ b/crates/zkevm_opcode_defs/src/definitions/add.rs @@ -68,4 +68,12 @@ impl OpcodeProps for AddOpcode { fn can_be_used_in_static_context(&self) -> bool { true } + + fn src0_can_be_pointer(&self) -> bool { + false + } + + fn src1_can_be_pointer(&self) -> bool { + false + } } diff --git a/crates/zkevm_opcode_defs/src/definitions/all.rs b/crates/zkevm_opcode_defs/src/definitions/all.rs index bde4025..c3a28b2 100644 --- a/crates/zkevm_opcode_defs/src/definitions/all.rs +++ b/crates/zkevm_opcode_defs/src/definitions/all.rs @@ -268,4 +268,46 @@ impl Opcode { Opcode::UMA(sub) => sub.output_operands(version), } } + + pub fn src0_can_be_pointer(&self) -> bool { + match self { + Opcode::Invalid(sub) => sub.src0_can_be_pointer(), + Opcode::Nop(sub) => sub.src0_can_be_pointer(), + Opcode::Add(sub) => sub.src0_can_be_pointer(), + Opcode::Sub(sub) => sub.src0_can_be_pointer(), + Opcode::Mul(sub) => sub.src0_can_be_pointer(), + Opcode::Div(sub) => sub.src0_can_be_pointer(), + Opcode::Jump(sub) => sub.src0_can_be_pointer(), + Opcode::Context(sub) => sub.src0_can_be_pointer(), + Opcode::Shift(sub) => sub.src0_can_be_pointer(), + Opcode::Binop(sub) => sub.src0_can_be_pointer(), + Opcode::Ptr(sub) => sub.src0_can_be_pointer(), + Opcode::NearCall(sub) => sub.src0_can_be_pointer(), + Opcode::Log(sub) => sub.src0_can_be_pointer(), + Opcode::FarCall(sub) => sub.src0_can_be_pointer(), + Opcode::Ret(sub) => sub.src0_can_be_pointer(), + Opcode::UMA(sub) => sub.src0_can_be_pointer(), + } + } + + pub fn src1_can_be_pointer(&self) -> bool { + match self { + Opcode::Invalid(sub) => sub.src1_can_be_pointer(), + Opcode::Nop(sub) => sub.src1_can_be_pointer(), + Opcode::Add(sub) => sub.src1_can_be_pointer(), + Opcode::Sub(sub) => sub.src1_can_be_pointer(), + Opcode::Mul(sub) => sub.src1_can_be_pointer(), + Opcode::Div(sub) => sub.src1_can_be_pointer(), + Opcode::Jump(sub) => sub.src1_can_be_pointer(), + Opcode::Context(sub) => sub.src1_can_be_pointer(), + Opcode::Shift(sub) => sub.src1_can_be_pointer(), + Opcode::Binop(sub) => sub.src1_can_be_pointer(), + Opcode::Ptr(sub) => sub.src1_can_be_pointer(), + Opcode::NearCall(sub) => sub.src1_can_be_pointer(), + Opcode::Log(sub) => sub.src1_can_be_pointer(), + Opcode::FarCall(sub) => sub.src1_can_be_pointer(), + Opcode::Ret(sub) => sub.src1_can_be_pointer(), + Opcode::UMA(sub) => sub.src1_can_be_pointer(), + } + } } diff --git a/crates/zkevm_opcode_defs/src/definitions/binop.rs b/crates/zkevm_opcode_defs/src/definitions/binop.rs index 76884eb..9ff6879 100644 --- a/crates/zkevm_opcode_defs/src/definitions/binop.rs +++ b/crates/zkevm_opcode_defs/src/definitions/binop.rs @@ -72,4 +72,12 @@ impl OpcodeProps for BinopOpcode { fn can_be_used_in_static_context(&self) -> bool { true } + + fn src0_can_be_pointer(&self) -> bool { + false + } + + fn src1_can_be_pointer(&self) -> bool { + false + } } diff --git a/crates/zkevm_opcode_defs/src/definitions/context.rs b/crates/zkevm_opcode_defs/src/definitions/context.rs index 760e79d..897b31b 100644 --- a/crates/zkevm_opcode_defs/src/definitions/context.rs +++ b/crates/zkevm_opcode_defs/src/definitions/context.rs @@ -124,4 +124,12 @@ impl OpcodeProps for ContextOpcode { _ => true, } } + + fn src0_can_be_pointer(&self) -> bool { + false + } + + fn src1_can_be_pointer(&self) -> bool { + false + } } diff --git a/crates/zkevm_opcode_defs/src/definitions/div.rs b/crates/zkevm_opcode_defs/src/definitions/div.rs index 156cd2b..4f7435d 100644 --- a/crates/zkevm_opcode_defs/src/definitions/div.rs +++ b/crates/zkevm_opcode_defs/src/definitions/div.rs @@ -68,4 +68,12 @@ impl OpcodeProps for DivOpcode { fn can_be_used_in_static_context(&self) -> bool { true } + + fn src0_can_be_pointer(&self) -> bool { + false + } + + fn src1_can_be_pointer(&self) -> bool { + false + } } diff --git a/crates/zkevm_opcode_defs/src/definitions/far_call.rs b/crates/zkevm_opcode_defs/src/definitions/far_call.rs index 7afe829..49151eb 100644 --- a/crates/zkevm_opcode_defs/src/definitions/far_call.rs +++ b/crates/zkevm_opcode_defs/src/definitions/far_call.rs @@ -96,4 +96,12 @@ impl OpcodeProps for FarCallOpcode { fn can_be_used_in_static_context(&self) -> bool { true } + + fn src0_can_be_pointer(&self) -> bool { + true + } + + fn src1_can_be_pointer(&self) -> bool { + false + } } diff --git a/crates/zkevm_opcode_defs/src/definitions/invalid_opcode.rs b/crates/zkevm_opcode_defs/src/definitions/invalid_opcode.rs index 99c4481..4f3dada 100644 --- a/crates/zkevm_opcode_defs/src/definitions/invalid_opcode.rs +++ b/crates/zkevm_opcode_defs/src/definitions/invalid_opcode.rs @@ -62,4 +62,12 @@ impl OpcodeProps for InvalidOpcode { fn can_be_used_in_static_context(&self) -> bool { true } + + fn src0_can_be_pointer(&self) -> bool { + false + } + + fn src1_can_be_pointer(&self) -> bool { + false + } } diff --git a/crates/zkevm_opcode_defs/src/definitions/jump.rs b/crates/zkevm_opcode_defs/src/definitions/jump.rs index 5348766..28b3ec9 100644 --- a/crates/zkevm_opcode_defs/src/definitions/jump.rs +++ b/crates/zkevm_opcode_defs/src/definitions/jump.rs @@ -62,4 +62,12 @@ impl OpcodeProps for JumpOpcode { fn can_be_used_in_static_context(&self) -> bool { true } + + fn src0_can_be_pointer(&self) -> bool { + false + } + + fn src1_can_be_pointer(&self) -> bool { + false + } } diff --git a/crates/zkevm_opcode_defs/src/definitions/log.rs b/crates/zkevm_opcode_defs/src/definitions/log.rs index f6fead7..5e7fcc2 100644 --- a/crates/zkevm_opcode_defs/src/definitions/log.rs +++ b/crates/zkevm_opcode_defs/src/definitions/log.rs @@ -145,11 +145,13 @@ impl OpcodeProps for LogOpcode { } fn input_operands(&self, _version: ISAVersion) -> Vec { match self { - LogOpcode::StorageWrite | LogOpcode::Event | LogOpcode::ToL1Message => { + LogOpcode::StorageWrite + | LogOpcode::Event + | LogOpcode::ToL1Message + | LogOpcode::PrecompileCall => { vec![Operand::RegOnly, Operand::RegOnly] } LogOpcode::StorageRead => vec![Operand::RegOnly], - LogOpcode::PrecompileCall => vec![Operand::RegOnly], } } fn output_operands(&self, _version: ISAVersion) -> Vec { @@ -171,4 +173,12 @@ impl OpcodeProps for LogOpcode { _ => true, } } + + fn src0_can_be_pointer(&self) -> bool { + false + } + + fn src1_can_be_pointer(&self) -> bool { + false + } } diff --git a/crates/zkevm_opcode_defs/src/definitions/mul.rs b/crates/zkevm_opcode_defs/src/definitions/mul.rs index 6b7fb39..c237d00 100644 --- a/crates/zkevm_opcode_defs/src/definitions/mul.rs +++ b/crates/zkevm_opcode_defs/src/definitions/mul.rs @@ -68,4 +68,12 @@ impl OpcodeProps for MulOpcode { fn can_be_used_in_static_context(&self) -> bool { true } + + fn src0_can_be_pointer(&self) -> bool { + false + } + + fn src1_can_be_pointer(&self) -> bool { + false + } } diff --git a/crates/zkevm_opcode_defs/src/definitions/near_call.rs b/crates/zkevm_opcode_defs/src/definitions/near_call.rs index 2a941e3..a9f7d30 100644 --- a/crates/zkevm_opcode_defs/src/definitions/near_call.rs +++ b/crates/zkevm_opcode_defs/src/definitions/near_call.rs @@ -62,4 +62,12 @@ impl OpcodeProps for NearCallOpcode { fn can_be_used_in_static_context(&self) -> bool { true } + + fn src0_can_be_pointer(&self) -> bool { + false + } + + fn src1_can_be_pointer(&self) -> bool { + false + } } diff --git a/crates/zkevm_opcode_defs/src/definitions/noop.rs b/crates/zkevm_opcode_defs/src/definitions/noop.rs index 072b8d5..67ea83e 100644 --- a/crates/zkevm_opcode_defs/src/definitions/noop.rs +++ b/crates/zkevm_opcode_defs/src/definitions/noop.rs @@ -62,4 +62,12 @@ impl OpcodeProps for NopOpcode { fn can_be_used_in_static_context(&self) -> bool { true } + + fn src0_can_be_pointer(&self) -> bool { + false + } + + fn src1_can_be_pointer(&self) -> bool { + false + } } diff --git a/crates/zkevm_opcode_defs/src/definitions/opcode_trait.rs b/crates/zkevm_opcode_defs/src/definitions/opcode_trait.rs index a71ee48..c4b010e 100644 --- a/crates/zkevm_opcode_defs/src/definitions/opcode_trait.rs +++ b/crates/zkevm_opcode_defs/src/definitions/opcode_trait.rs @@ -83,6 +83,8 @@ pub trait OpcodeProps: 'static + Send + Sync { } } } + fn src0_can_be_pointer(&self) -> bool; + fn src1_can_be_pointer(&self) -> bool; } pub trait OpcodeVariantProps: Sized + 'static + Send + Sync { diff --git a/crates/zkevm_opcode_defs/src/definitions/ptr.rs b/crates/zkevm_opcode_defs/src/definitions/ptr.rs index 609ba64..841cf4c 100644 --- a/crates/zkevm_opcode_defs/src/definitions/ptr.rs +++ b/crates/zkevm_opcode_defs/src/definitions/ptr.rs @@ -82,4 +82,12 @@ impl OpcodeProps for PtrOpcode { fn can_be_used_in_static_context(&self) -> bool { true } + + fn src0_can_be_pointer(&self) -> bool { + true + } + + fn src1_can_be_pointer(&self) -> bool { + false + } } diff --git a/crates/zkevm_opcode_defs/src/definitions/ret.rs b/crates/zkevm_opcode_defs/src/definitions/ret.rs index ba73ca3..ed506fc 100644 --- a/crates/zkevm_opcode_defs/src/definitions/ret.rs +++ b/crates/zkevm_opcode_defs/src/definitions/ret.rs @@ -79,4 +79,12 @@ impl OpcodeProps for RetOpcode { fn can_be_used_in_static_context(&self) -> bool { true } + + fn src0_can_be_pointer(&self) -> bool { + true + } + + fn src1_can_be_pointer(&self) -> bool { + false + } } diff --git a/crates/zkevm_opcode_defs/src/definitions/shift.rs b/crates/zkevm_opcode_defs/src/definitions/shift.rs index 7e74b2a..d41fda9 100644 --- a/crates/zkevm_opcode_defs/src/definitions/shift.rs +++ b/crates/zkevm_opcode_defs/src/definitions/shift.rs @@ -79,4 +79,12 @@ impl OpcodeProps for ShiftOpcode { fn can_be_used_in_static_context(&self) -> bool { true } + + fn src0_can_be_pointer(&self) -> bool { + false + } + + fn src1_can_be_pointer(&self) -> bool { + false + } } diff --git a/crates/zkevm_opcode_defs/src/definitions/sub.rs b/crates/zkevm_opcode_defs/src/definitions/sub.rs index b67a404..255a593 100644 --- a/crates/zkevm_opcode_defs/src/definitions/sub.rs +++ b/crates/zkevm_opcode_defs/src/definitions/sub.rs @@ -68,4 +68,12 @@ impl OpcodeProps for SubOpcode { fn can_be_used_in_static_context(&self) -> bool { true } + + fn src0_can_be_pointer(&self) -> bool { + false + } + + fn src1_can_be_pointer(&self) -> bool { + false + } } diff --git a/crates/zkevm_opcode_defs/src/definitions/uma.rs b/crates/zkevm_opcode_defs/src/definitions/uma.rs index 3ac129e..9b805cb 100644 --- a/crates/zkevm_opcode_defs/src/definitions/uma.rs +++ b/crates/zkevm_opcode_defs/src/definitions/uma.rs @@ -139,4 +139,12 @@ impl OpcodeProps for UMAOpcode { fn can_be_used_in_static_context(&self) -> bool { true } + + fn src0_can_be_pointer(&self) -> bool { + true + } + + fn src1_can_be_pointer(&self) -> bool { + false + } } diff --git a/crates/zkevm_opcode_defs/src/utils.rs b/crates/zkevm_opcode_defs/src/utils.rs index e265f23..fcf246a 100644 --- a/crates/zkevm_opcode_defs/src/utils.rs +++ b/crates/zkevm_opcode_defs/src/utils.rs @@ -1,4 +1,5 @@ use crate::decoding::{EncodingModeProduction, VmEncodingMode}; +use ethereum_types::U256; pub const fn split_as_u4(value: u8) -> (u8, u8) { (value & ((1u8 << 4) - 1), value >> 4) @@ -59,3 +60,12 @@ pub fn bytecode_to_code_hash_for_mode>( Ok(versioned_hash_bytes) } + +/// Erase start and page number from a fat pointer. To be used in the case of a fat pointer +/// being passed to an opcode which shouldn't receive one. +pub fn erase_fat_pointer_metadata(ptr: &mut U256) { + // Memory page is at 1<<32 - 1<<64, start is at 1<<64 - 1<<96 + // We also need to preserve the top 128 bits of the value + ptr.0[0] &= 0x00000000_ffffffffu64; + ptr.0[1] &= 0xffffffff_00000000u64; +} From 9975a647bac6e96db077dddcb9a65c2bcd1249a0 Mon Sep 17 00:00:00 2001 From: Igor Aleksanov Date: Thu, 15 Aug 2024 14:24:50 +0400 Subject: [PATCH 5/7] Historical release: v0.142.1 --- crates/circuit_encodings/Cargo.toml | 2 +- crates/circuit_sequencer_api/Cargo.toml | 12 ++++++------ crates/circuit_sequencer_api/src/lib.rs | 6 ++++++ 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/crates/circuit_encodings/Cargo.toml b/crates/circuit_encodings/Cargo.toml index c8a0b51..004a1ff 100644 --- a/crates/circuit_encodings/Cargo.toml +++ b/crates/circuit_encodings/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "circuit_encodings" -version = "0.141.1" +version = "0.142.1" edition = "2021" authors = ["The Matter Labs Team "] homepage = "https://zksync.io/" diff --git a/crates/circuit_sequencer_api/Cargo.toml b/crates/circuit_sequencer_api/Cargo.toml index dff6e06..642740d 100644 --- a/crates/circuit_sequencer_api/Cargo.toml +++ b/crates/circuit_sequencer_api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "circuit_sequencer_api" -version = "0.141.1" +version = "0.142.1" edition = "2021" authors = ["The Matter Labs Team "] homepage = "https://zksync.io/" @@ -10,17 +10,17 @@ keywords = ["blockchain", "zksync"] categories = ["cryptography"] description = "ZKsync Era circuits API for sequencer" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] +circuit_encodings = { version = "0.142", path = "../circuit_encodings"} # Not pinned, because it's an old dependency used by MultiVM + +zk_evm = { version = "0.141", path = "../zk_evm" } +bellman = { package = "bellman_ce", version = "0" } # Not pinned, because it's an old dependency used by MultiVM -circuit_encodings = { version = "0.141", path = "../circuit_encodings" } # Not pinned, because it's an old dependency used by MultiVM -zk_evm = { version = "0.141", path = "../zk_evm" } # Not pinned, because it's an old dependency used by MultiVM -bellman = { package = "bellman_ce", version = "0" } # Not pinned, because it's an old dependency used by MultiVM derivative = "2.2" serde = {version = "1", features = ["derive"]} rayon = "1.10" + [features] default = [] diff --git a/crates/circuit_sequencer_api/src/lib.rs b/crates/circuit_sequencer_api/src/lib.rs index e12ff3b..03f154d 100644 --- a/crates/circuit_sequencer_api/src/lib.rs +++ b/crates/circuit_sequencer_api/src/lib.rs @@ -11,3 +11,9 @@ pub mod utils; pub use circuit_encodings::boojum; pub const INITIAL_MONOTONIC_CYCLE_COUNTER: u32 = 1024; + +// Export parameters needed for 4844 blobs. +pub use circuit_encodings::zkevm_circuits::eip_4844::input::{ + BLOB_CHUNK_SIZE, ELEMENTS_PER_4844_BLOCK, +}; +pub use circuit_encodings::zkevm_circuits::scheduler::block_header::MAX_4844_BLOBS_PER_BLOCK; From b02c383f0e41ba8d49be70e382024f0d96b22e64 Mon Sep 17 00:00:00 2001 From: Igor Aleksanov Date: Thu, 15 Aug 2024 14:54:33 +0400 Subject: [PATCH 6/7] Historical release: v0.150.2 --- .cargo/config.toml | 2 + .config/nextest.toml | 3 + crates/circuit_definitions/.gitignore | 4 + crates/circuit_definitions/Cargo.toml | 27 + crates/circuit_definitions/README.md | 55 + .../circuit_definitions/rust-toolchain.toml | 2 + .../src/aux_definitions/mod.rs | 1 + .../src/aux_definitions/witness_oracle.rs | 641 +++ .../aux_layer/compression.rs | 181 + .../aux_layer/compression_modes/mod.rs | 73 + .../aux_layer/compression_modes/mode_1.rs | 115 + .../compression_modes/mode_1_for_wrapper.rs | 115 + .../aux_layer/compression_modes/mode_2.rs | 118 + .../compression_modes/mode_2_for_wrapper.rs | 117 + .../aux_layer/compression_modes/mode_3.rs | 118 + .../compression_modes/mode_3_for_wrapper.rs | 118 + .../aux_layer/compression_modes/mode_4.rs | 121 + .../compression_modes/mode_4_for_wrapper.rs | 121 + .../aux_layer/compression_modes/mode_5.rs | 113 + .../compression_modes/mode_5_for_wrapper.rs | 111 + .../src/circuit_definitions/aux_layer/mod.rs | 669 +++ .../circuit_definitions/aux_layer/wrapper.rs | 105 + .../base_layer/code_decommitter.rs | 149 + .../base_layer/ecrecover.rs | 181 + .../circuit_definitions/base_layer/eip4844.rs | 178 + .../base_layer/events_sort_dedup.rs | 137 + .../base_layer/keccak256_round_function.rs | 153 + .../base_layer/linear_hasher.rs | 149 + .../base_layer/log_demux.rs | 137 + .../src/circuit_definitions/base_layer/mod.rs | 571 +++ .../base_layer/ram_permutation.rs | 137 + .../base_layer/secp256r1_verify.rs | 173 + .../base_layer/sha256_round_function.rs | 145 + .../base_layer/sort_code_decommits.rs | 137 + .../base_layer/storage_apply.rs | 151 + .../base_layer/storage_sort_dedup.rs | 139 + .../base_layer/transient_storage_sort.rs | 144 + .../circuit_definitions/base_layer/vm_main.rs | 189 + .../src/circuit_definitions/mod.rs | 235 + .../recursion_layer/circuit_def.rs | 138 + .../recursion_layer/leaf_layer.rs | 162 + .../recursion_layer/mod.rs | 918 ++++ .../recursion_layer/node_layer.rs | 157 + .../recursion_layer/recursion_tip.rs | 154 + .../recursion_layer/scheduler.rs | 224 + .../recursion_layer/verifier_builder.rs | 52 + .../circuit_definitions/verifier_builder.rs | 182 + crates/circuit_definitions/src/lib.rs | 59 + crates/circuit_encodings/Cargo.toml | 8 +- .../circuit_encodings/src/callstack_entry.rs | 118 +- .../src/decommittment_request.rs | 19 +- crates/circuit_encodings/src/lib.rs | 132 +- crates/circuit_encodings/src/log_query.rs | 37 +- crates/circuit_encodings/src/memory_query.rs | 19 + crates/circuit_sequencer_api/Cargo.toml | 12 +- .../src/geometry_config.rs | 4 +- .../src/sort_storage_access.rs | 44 +- crates/circuit_sequencer_api/src/toolset.rs | 2 + crates/circuit_sequencer_api/src/utils.rs | 2 +- crates/kzg/.gitignore | 4 + crates/kzg/Cargo.toml | 32 + crates/kzg/README.md | 9 + crates/kzg/src/consts.rs | 4099 ++++++++++++++++ crates/kzg/src/kzg_info.rs | 284 ++ crates/kzg/src/lib.rs | 464 ++ crates/kzg/src/tests/kzg_test_0.json | 12 + crates/kzg/src/tests/mod.rs | 137 + crates/kzg/src/trusted_setup.json | 4100 +++++++++++++++++ crates/kzg/src/trusted_setup.rs | 37 + .../.github/ISSUE_TEMPLATE/bug_report.md | 39 + .../.github/ISSUE_TEMPLATE/feature_request.md | 21 + .../.github/pull_request_template.md | 20 + .../.github/workflows/cargo-license.yaml | 8 + .../zkEVM-assembly/.github/workflows/ci.yaml | 26 + .../.github/workflows/secrets_scanner.yaml | 17 + crates/zkEVM-assembly/.gitignore | 15 + crates/zkEVM-assembly/CONTRIBUTING.md | 9 + crates/zkEVM-assembly/Cargo.toml | 26 + crates/zkEVM-assembly/LICENSE-APACHE | 176 + crates/zkEVM-assembly/LICENSE-MIT | 21 + crates/zkEVM-assembly/README.md | 34 + crates/zkEVM-assembly/SECURITY.md | 74 + crates/zkEVM-assembly/assemble.sh | 5 + crates/zkEVM-assembly/deny.toml | 78 + crates/zkEVM-assembly/eraLogo.png | Bin 0 -> 79091 bytes .../zkEVM-assembly/examples/arithmetic.sasm | 59 + crates/zkEVM-assembly/examples/bitwise.sasm | 36 + crates/zkEVM-assembly/examples/brcc.sasm | 93 + crates/zkEVM-assembly/examples/brcond.sasm | 18 + .../examples/calling-convensions.sasm | 42 + crates/zkEVM-assembly/examples/diamond.sasm | 19 + crates/zkEVM-assembly/examples/factorial.sasm | 26 + crates/zkEVM-assembly/examples/fibonacci.sasm | 39 + .../zkEVM-assembly/examples/frame_memory.sasm | 49 + crates/zkEVM-assembly/examples/intrinsic.sasm | 30 + crates/zkEVM-assembly/examples/ret.sasm | 19 + crates/zkEVM-assembly/run.sh | 39 + .../src/assembly/constants/mod.rs | 30 + .../src/assembly/instruction/add.rs | 119 + .../src/assembly/instruction/bitwise.rs | 137 + .../src/assembly/instruction/condition.rs | 37 + .../src/assembly/instruction/context.rs | 173 + .../src/assembly/instruction/div.rs | 125 + .../src/assembly/instruction/far_call.rs | 152 + .../src/assembly/instruction/invalid.rs | 60 + .../src/assembly/instruction/jump.rs | 98 + .../src/assembly/instruction/log.rs | 144 + .../src/assembly/instruction/mod.rs | 463 ++ .../src/assembly/instruction/mul.rs | 114 + .../src/assembly/instruction/near_call.rs | 117 + .../src/assembly/instruction/nop.rs | 110 + .../src/assembly/instruction/ptr.rs | 142 + .../src/assembly/instruction/ret.rs | 155 + .../src/assembly/instruction/set_flags.rs | 22 + .../src/assembly/instruction/shift.rs | 138 + .../src/assembly/instruction/sub.rs | 128 + .../src/assembly/instruction/uma.rs | 190 + .../src/assembly/instruction/utils.rs | 43 + .../src/assembly/linking/mod.rs | 360 ++ .../src/assembly/mnemonic/add.rs | 8 + .../src/assembly/mnemonic/binop.rs | 82 + .../src/assembly/mnemonic/call.rs | 83 + .../src/assembly/mnemonic/context.rs | 38 + .../src/assembly/mnemonic/log.rs | 94 + .../src/assembly/mnemonic/mod.rs | 573 +++ .../src/assembly/mnemonic/nop.rs | 125 + .../src/assembly/mnemonic/set_flags.rs | 28 + .../src/assembly/mnemonic/shift.rs | 66 + .../src/assembly/mnemonic/sub.rs | 15 + .../src/assembly/mnemonic/uma.rs | 86 + crates/zkEVM-assembly/src/assembly/mod.rs | 423 ++ .../src/assembly/operand/mod.rs | 424 ++ .../src/assembly/parse/addressing.rs | 764 +++ .../src/assembly/parse/code_element.rs | 469 ++ .../src/assembly/parse/constant_operand.rs | 74 + .../src/assembly/parse/data_element.rs | 204 + .../zkEVM-assembly/src/assembly/parse/mod.rs | 544 +++ .../src/assembly/section/mod.rs | 103 + crates/zkEVM-assembly/src/error.rs | 167 + crates/zkEVM-assembly/src/lib.rs | 84 + crates/zkEVM-assembly/src/reader/arguments.rs | 36 + crates/zkEVM-assembly/src/reader/main.rs | 46 + crates/zkEVM-assembly/src/tests/assembly.rs | 849 ++++ crates/zkEVM-assembly/src/tests/binary.rs | 830 ++++ crates/zkEVM-assembly/src/tests/mod.rs | 4 + .../zkEVM-assembly/src/tests/new_assembly.rs | 33 + crates/zk_evm/Cargo.toml | 5 +- crates/zk_evm/src/block_properties/mod.rs | 1 + crates/zk_evm/src/lib.rs | 13 +- crates/zk_evm/src/opcodes/execution/add.rs | 2 +- crates/zk_evm/src/opcodes/execution/binop.rs | 4 +- .../zk_evm/src/opcodes/execution/context.rs | 24 +- crates/zk_evm/src/opcodes/execution/div.rs | 2 +- .../zk_evm/src/opcodes/execution/far_call.rs | 405 +- crates/zk_evm/src/opcodes/execution/jump.rs | 16 +- crates/zk_evm/src/opcodes/execution/log.rs | 380 +- crates/zk_evm/src/opcodes/execution/mod.rs | 4 +- crates/zk_evm/src/opcodes/execution/mul.rs | 2 +- .../zk_evm/src/opcodes/execution/near_call.rs | 17 +- crates/zk_evm/src/opcodes/execution/ptr.rs | 2 +- crates/zk_evm/src/opcodes/execution/ret.rs | 39 +- crates/zk_evm/src/opcodes/execution/shift.rs | 4 +- crates/zk_evm/src/opcodes/execution/sub.rs | 2 +- crates/zk_evm/src/opcodes/execution/uma.rs | 23 +- crates/zk_evm/src/opcodes/parsing.rs | 8 +- .../zk_evm/src/reference_impls/decommitter.rs | 155 +- .../zk_evm/src/reference_impls/event_sink.rs | 2 +- crates/zk_evm/src/reference_impls/memory.rs | 1054 ++--- crates/zk_evm/src/testing/storage.rs | 66 +- .../testing/tests/precompiles/ecrecover.rs | 178 +- .../testing/tests/precompiles/keccak256.rs | 11 +- .../src/testing/tests/precompiles/mod.rs | 2 +- crates/zk_evm/src/tracing.rs | 2 +- crates/zk_evm/src/utils.rs | 4 +- crates/zk_evm/src/vm_state/aux_data.rs | 7 - crates/zk_evm/src/vm_state/cycle.rs | 153 +- crates/zk_evm/src/vm_state/execution_stack.rs | 38 +- crates/zk_evm/src/vm_state/helpers.rs | 206 +- crates/zk_evm/src/vm_state/mem_ops.rs | 18 +- crates/zk_evm/src/vm_state/mod.rs | 19 +- crates/zk_evm/src/witness_trace/mod.rs | 26 +- crates/zk_evm_abstractions/Cargo.toml | 4 +- crates/zk_evm_abstractions/src/auxiliary.rs | 3 + crates/zk_evm_abstractions/src/lib.rs | 2 + .../src/precompiles/ecrecover.rs | 67 +- .../src/precompiles/mod.rs | 30 +- .../src/precompiles/secp256r1_verify.rs | 308 ++ .../src/precompiles/sha256.rs | 2 - crates/zk_evm_abstractions/src/queries.rs | 4 +- crates/zk_evm_abstractions/src/vm.rs | 74 +- .../zkevm_circuits/.github/workflows/ci.yaml | 3 - crates/zkevm_circuits/Cargo.toml | 10 +- crates/zkevm_circuits/rust-toolchain.toml | 3 +- .../src/base_structures/decommit_query/mod.rs | 10 +- .../src/base_structures/log_query/mod.rs | 13 +- .../precompile_input_outputs/mod.rs | 19 +- .../src/base_structures/register/mod.rs | 10 +- .../src/base_structures/vm_state/callstack.rs | 13 +- .../src/base_structures/vm_state/mod.rs | 32 +- .../base_structures/vm_state/saved_context.rs | 149 +- .../src/code_unpacker_sha256/input.rs | 46 +- .../src/code_unpacker_sha256/mod.rs | 392 +- .../src/demux_log_queue/input.rs | 122 +- .../zkevm_circuits/src/demux_log_queue/mod.rs | 500 +- .../zkevm_circuits/src/ecrecover/baseline.rs | 26 +- .../src/ecrecover/decomp_table.rs | 4 +- crates/zkevm_circuits/src/ecrecover/input.rs | 13 +- crates/zkevm_circuits/src/ecrecover/mod.rs | 37 +- .../src/ecrecover/naf_abs_div2_table.rs | 4 +- .../src/ecrecover/new_optimized.rs | 478 +- .../secp256k1/fixed_base_mul_table.rs | 2 +- .../src/ecrecover/secp256k1/mod.rs | 1 - crates/zkevm_circuits/src/eip_4844/input.rs | 23 +- crates/zkevm_circuits/src/eip_4844/mod.rs | 38 +- .../circuit_inputs/main_vm.rs | 18 +- .../src/fsm_input_output/mod.rs | 114 +- .../keccak256_round_function/buffer/mod.rs | 9 +- .../src/keccak256_round_function/input.rs | 19 +- .../src/keccak256_round_function/mod.rs | 17 +- crates/zkevm_circuits/src/lib.rs | 4 +- .../zkevm_circuits/src/linear_hasher/input.rs | 27 +- .../zkevm_circuits/src/linear_hasher/mod.rs | 25 +- crates/zkevm_circuits/src/log_sorter/input.rs | 31 +- crates/zkevm_circuits/src/log_sorter/mod.rs | 6 +- crates/zkevm_circuits/src/main_vm/cycle.rs | 63 +- crates/zkevm_circuits/src/main_vm/loading.rs | 100 +- .../src/main_vm/opcode_bitmask.rs | 2 +- .../src/main_vm/opcodes/call_ret.rs | 151 +- .../main_vm/opcodes/call_ret_impl/far_call.rs | 760 ++- .../src/main_vm/opcodes/call_ret_impl/mod.rs | 4 +- .../opcodes/call_ret_impl/near_call.rs | 40 +- .../src/main_vm/opcodes/call_ret_impl/ret.rs | 90 +- .../src/main_vm/opcodes/context.rs | 45 +- .../src/main_vm/opcodes/jump.rs | 19 +- .../zkevm_circuits/src/main_vm/opcodes/log.rs | 520 ++- .../zkevm_circuits/src/main_vm/opcodes/mod.rs | 21 +- .../zkevm_circuits/src/main_vm/opcodes/uma.rs | 77 +- .../zkevm_circuits/src/main_vm/pre_state.rs | 12 +- .../zkevm_circuits/src/main_vm/state_diffs.rs | 24 +- crates/zkevm_circuits/src/main_vm/utils.rs | 2 +- .../src/main_vm/witness_oracle.rs | 28 +- .../src/ram_permutation/input.rs | 22 +- .../zkevm_circuits/src/ram_permutation/mod.rs | 13 +- .../src/recursion/compression/input.rs | 1 - .../src/recursion/compression/mod.rs | 5 +- .../src/recursion/interblock/mod.rs | 5 +- .../src/recursion/leaf_layer/input.rs | 34 +- .../src/recursion/leaf_layer/mod.rs | 14 +- crates/zkevm_circuits/src/recursion/mod.rs | 3 +- .../src/recursion/node_layer/mod.rs | 14 +- .../src/recursion/recursion_tip/input.rs | 63 + .../src/recursion/recursion_tip/mod.rs | 184 + .../zkevm_circuits/src/scheduler/auxiliary.rs | 55 +- .../src/scheduler/block_header/mod.rs | 4 +- crates/zkevm_circuits/src/scheduler/input.rs | 23 +- crates/zkevm_circuits/src/scheduler/mod.rs | 557 ++- .../src/secp256r1_verify/baseline.rs | 780 ++++ .../secp256r1_verify/fixed_base_mul_table.rs | 59 + .../src/secp256r1_verify/input.rs | 59 + .../src/secp256r1_verify/mod.rs | 63 + .../src/secp256r1_verify/secp256r1/fq.rs | 7 + .../src/secp256r1_verify/secp256r1/fr.rs | 7 + .../src/secp256r1_verify/secp256r1/mod.rs | 688 +++ .../src/sha256_round_function/input.rs | 19 +- .../src/sha256_round_function/mod.rs | 10 +- .../src/sort_decommittment_requests/input.rs | 33 +- .../src/sort_decommittment_requests/mod.rs | 14 +- .../src/storage_application/input.rs | 31 +- .../src/storage_application/mod.rs | 6 + .../input.rs | 36 +- .../storage_validity_by_grand_product/mod.rs | 33 +- .../test_input.rs | 2 +- .../src/tables/call_costs_and_stipends.rs | 35 + crates/zkevm_circuits/src/tables/mod.rs | 6 + .../src/tables/pubdata_cost_validity.rs | 34 + crates/zkevm_circuits/src/tables/test_bit.rs | 44 + .../input.rs | 121 + .../mod.rs | 797 ++++ crates/zkevm_opcode_defs/Cargo.toml | 4 +- .../zkevm_opcode_defs/src/circuit_prices.rs | 1 + .../src/definitions/abi/meta.rs | 4 +- .../src/definitions/abi/precompile_call.rs | 26 + .../zkevm_opcode_defs/src/definitions/add.rs | 3 + .../src/definitions/binop.rs | 3 + .../src/definitions/context.rs | 19 +- .../zkevm_opcode_defs/src/definitions/div.rs | 3 + .../src/definitions/far_call.rs | 6 +- .../src/definitions/invalid_opcode.rs | 3 + .../zkevm_opcode_defs/src/definitions/jump.rs | 5 +- .../zkevm_opcode_defs/src/definitions/log.rs | 206 +- .../zkevm_opcode_defs/src/definitions/mod.rs | 30 +- .../zkevm_opcode_defs/src/definitions/mul.rs | 3 + .../src/definitions/near_call.rs | 3 + .../zkevm_opcode_defs/src/definitions/noop.rs | 3 + .../src/definitions/opcode_trait.rs | 5 +- .../zkevm_opcode_defs/src/definitions/ptr.rs | 3 + .../zkevm_opcode_defs/src/definitions/ret.rs | 3 + .../src/definitions/shift.rs | 3 + .../zkevm_opcode_defs/src/definitions/sub.rs | 3 + .../zkevm_opcode_defs/src/definitions/uma.rs | 50 +- .../src/definitions/versioned_hash/mod.rs | 214 + crates/zkevm_opcode_defs/src/lib.rs | 24 +- crates/zkevm_opcode_defs/src/system_params.rs | 73 +- .../.github/ISSUE_TEMPLATE/bug_report.md | 39 + .../.github/ISSUE_TEMPLATE/feature_request.md | 21 + .../.github/pull_request_template.md | 20 + .../workflows/geometry-config-generator.yml | 80 + .../.github/workflows/cargo-license.yaml | 8 + .../.github/workflows/ci.yaml | 68 + .../.github/workflows/secrets_scanner.yaml | 17 + crates/zkevm_test_harness/.gitignore | 10 + crates/zkevm_test_harness/CONTRIBUTING.md | 10 + crates/zkevm_test_harness/Cargo.toml | 65 + crates/zkevm_test_harness/LICENSE-APACHE | 177 + crates/zkevm_test_harness/LICENSE-MIT | 22 + crates/zkevm_test_harness/README.md | 67 + crates/zkevm_test_harness/SECURITY.md | 74 + crates/zkevm_test_harness/config.json | 14 + crates/zkevm_test_harness/deny.toml | 79 + crates/zkevm_test_harness/eraLogo.png | Bin 0 -> 79091 bytes crates/zkevm_test_harness/rust-toolchain.toml | 3 + .../setup/aux_layer/wrapper_vk_1.key | Bin 0 -> 1728 bytes .../setup/base_layer/finalization_hint_1.json | 188 + .../base_layer/finalization_hint_10.json | 140 + .../base_layer/finalization_hint_11.json | 68 + .../base_layer/finalization_hint_12.json | 68 + .../base_layer/finalization_hint_13.json | 128 + .../base_layer/finalization_hint_14.json | 68 + .../base_layer/finalization_hint_15.json | 3152 +++++++++++++ .../setup/base_layer/finalization_hint_2.json | 68 + .../base_layer/finalization_hint_255.json | 117 + .../setup/base_layer/finalization_hint_3.json | 116 + .../setup/base_layer/finalization_hint_4.json | 68 + .../setup/base_layer/finalization_hint_5.json | 128 + .../setup/base_layer/finalization_hint_6.json | 116 + .../setup/base_layer/finalization_hint_7.json | 3200 +++++++++++++ .../setup/base_layer/finalization_hint_8.json | 68 + .../setup/base_layer/finalization_hint_9.json | 68 + .../setup/base_layer/vk_1.json | 283 ++ .../setup/base_layer/vk_10.json | 257 ++ .../setup/base_layer/vk_11.json | 257 ++ .../setup/base_layer/vk_12.json | 257 ++ .../setup/base_layer/vk_13.json | 244 + .../setup/base_layer/vk_14.json | 257 ++ .../setup/base_layer/vk_15.json | 257 ++ .../setup/base_layer/vk_2.json | 257 ++ .../setup/base_layer/vk_255.json | 244 + .../setup/base_layer/vk_3.json | 244 + .../setup/base_layer/vk_4.json | 257 ++ .../setup/base_layer/vk_5.json | 244 + .../setup/base_layer/vk_6.json | 244 + .../setup/base_layer/vk_7.json | 270 ++ .../setup/base_layer/vk_8.json | 257 ++ .../setup/base_layer/vk_9.json | 257 ++ .../recursion_layer/finalization_hint_1.json | 128 + .../recursion_layer/finalization_hint_10.json | 37 + .../recursion_layer/finalization_hint_11.json | 37 + .../recursion_layer/finalization_hint_12.json | 37 + .../recursion_layer/finalization_hint_13.json | 37 + .../recursion_layer/finalization_hint_14.json | 37 + .../recursion_layer/finalization_hint_15.json | 37 + .../recursion_layer/finalization_hint_16.json | 37 + .../recursion_layer/finalization_hint_17.json | 37 + .../recursion_layer/finalization_hint_18.json | 37 + .../recursion_layer/finalization_hint_3.json | 37 + .../recursion_layer/finalization_hint_4.json | 37 + .../recursion_layer/finalization_hint_5.json | 37 + .../recursion_layer/finalization_hint_6.json | 37 + .../recursion_layer/finalization_hint_7.json | 37 + .../recursion_layer/finalization_hint_8.json | 37 + .../recursion_layer/finalization_hint_9.json | 37 + .../finalization_hint_node.json | 37 + .../finalization_hint_recursion_tip.json | 37 + .../setup/recursion_layer/vk_1.json | 270 ++ .../setup/recursion_layer/vk_10.json | 262 ++ .../setup/recursion_layer/vk_11.json | 262 ++ .../setup/recursion_layer/vk_12.json | 262 ++ .../setup/recursion_layer/vk_13.json | 262 ++ .../setup/recursion_layer/vk_14.json | 262 ++ .../setup/recursion_layer/vk_15.json | 262 ++ .../setup/recursion_layer/vk_16.json | 262 ++ .../setup/recursion_layer/vk_17.json | 262 ++ .../setup/recursion_layer/vk_18.json | 262 ++ .../setup/recursion_layer/vk_3.json | 262 ++ .../setup/recursion_layer/vk_4.json | 262 ++ .../setup/recursion_layer/vk_5.json | 262 ++ .../setup/recursion_layer/vk_6.json | 262 ++ .../setup/recursion_layer/vk_7.json | 262 ++ .../setup/recursion_layer/vk_8.json | 262 ++ .../setup/recursion_layer/vk_9.json | 262 ++ .../setup/recursion_layer/vk_node.json | 262 ++ .../recursion_layer/vk_recursion_tip.json | 249 + .../src/capacity_estimator.rs | 267 ++ .../src/circuit_limit_estimator/main.rs | 31 + .../src/circuit_limit_estimator/mod.rs | 200 + .../main.rs | 49 + .../zkevm_test_harness/src/compute_setups.rs | 725 +++ .../src/data_source/in_memory_data_source.rs | 507 ++ .../src/data_source/local_file_data_source.rs | 482 ++ .../zkevm_test_harness/src/data_source/mod.rs | 154 + crates/zkevm_test_harness/src/debug.rs | 167 + crates/zkevm_test_harness/src/entry_point.rs | 53 + .../zkevm_test_harness/src/external_calls.rs | 86 + .../src/geometry_config_generator/main.rs | 156 + .../src/helper/artifact_utils.rs | 89 + crates/zkevm_test_harness/src/helper/mod.rs | 2 + .../src/helper/serialize_utils.rs | 55 + crates/zkevm_test_harness/src/lib.rs | 60 + .../src/proof_wrapper_utils/README.md | 19 + .../src/proof_wrapper_utils/compression.rs | 143 + .../compression_for_wrapper.rs | 153 + .../src/proof_wrapper_utils/mod.rs | 184 + .../proof_compression_test.rs | 398 ++ .../compression_for_wrapper_proof_2.json | 1 + .../compression_for_wrapper_vk_2.json | 275 ++ .../aux_layer/compression_proof_1.json | 1 + .../aux_layer/compression_proof_2.json | 1 + .../aux_layer/compression_proof_3.json | 1 + .../aux_layer/compression_proof_4.json | 1 + .../aux_layer/compression_vk_1.json | 262 ++ .../aux_layer/compression_vk_2.json | 275 ++ .../aux_layer/compression_vk_3.json | 275 ++ .../aux_layer/compression_vk_4.json | 1741 +++++++ .../recursion_layer/scheduler_proof.json | 1 + .../recursion_layer/vk_1.json | 270 ++ .../src/proof_wrapper_utils/utils.rs | 74 + .../src/proof_wrapper_utils/wrapper.rs | 278 ++ crates/zkevm_test_harness/src/prover_utils.rs | 903 ++++ crates/zkevm_test_harness/src/run_vms.rs | 638 +++ .../src/snark_wrapper_test/mod.rs | 115 + .../tests/complex_tests/invididual_debugs.rs | 54 + .../src/tests/complex_tests/mod.rs | 1396 ++++++ .../test_artifacts/basic_test.json | 1 + .../test_artifacts/basic_test_commit_hash | 1 + .../test_artifacts/compiler_metadata | 1 + .../test_artifacts/empty_proof.bin | Bin 0 -> 716417 bytes .../system_contracts_commit_hash | 1 + .../src/tests/complex_tests/test_synthesis.rs | 36 + .../tests/complex_tests/testing_wrapper.rs | 139 + .../src/tests/complex_tests/utils.rs | 24 + .../complex_tests/wrapper_negative_tests.rs | 205 + crates/zkevm_test_harness/src/tests/mod.rs | 426 ++ .../src/tests/run_manually.rs | 366 ++ .../src/tests/simple_tests/README.md | 35 + .../src/tests/simple_tests/asm_tests.rs | 86 + .../src/tests/simple_tests/context.rs | 12 + .../src/tests/simple_tests/eip4844.rs | 46 + .../src/tests/simple_tests/far_call.rs | 67 + .../src/tests/simple_tests/kernel_ops.rs | 27 + .../src/tests/simple_tests/log.rs | 93 + .../src/tests/simple_tests/memory_growth.rs | 136 + .../src/tests/simple_tests/mod.rs | 17 + .../src/tests/simple_tests/near_call.rs | 50 + .../src/tests/simple_tests/ptr.rs | 251 + .../src/tests/simple_tests/stack.rs | 20 + .../src/tests/simple_tests/storage.rs | 55 + .../far_call/fail_on_decommit/65536.asm | 12 + .../far_call/fail_on_decommit/entry.asm | 36 + .../panic_on_return_large_data/65536.asm | 24 + .../panic_on_return_large_data/entry.asm | 49 + .../far_call/pay_for_memory_growth/65536.asm | 59 + .../far_call/pay_for_memory_growth/65537.asm | 19 + .../far_call/pay_for_memory_growth/entry.asm | 34 + .../far_call/read_fat_pointer/65535.asm | 50 + .../far_call/read_fat_pointer/entry.asm | 48 + .../far_call/return_large_data/65536.asm | 25 + .../far_call/return_large_data/entry.asm | 49 + .../testdata/log/decommit_invalid/800000.asm | 10 + .../testdata/log/decommit_invalid/entry.asm | 13 + .../testdata/log/decommit_ok/800000.asm | 10 + .../testdata/log/decommit_ok/entry.asm | 38 + .../testdata/log/decommit_ok_twice/800000.asm | 10 + .../testdata/log/decommit_ok_twice/entry.asm | 59 + .../log/decommit_ok_with_panic/800000.asm | 10 + .../log/decommit_ok_with_panic/entry.asm | 29 + .../entry.asm | 45 + .../log/l1_message_out_of_gas/entry.asm | 51 + .../log/precompile_invalid_address/65399.asm | 62 + .../log/precompile_invalid_address/entry.asm | 32 + .../log/precompile_out_of_gas/entry.asm | 36 + .../log/storage/storage_clear_slot/entry.asm | 25 + .../storage/storage_pubdata_refunds/entry.asm | 64 + .../log/storage/storage_reads/entry.asm | 84 + .../storage_write_after_panic/entry.asm | 26 + .../storage_write_rollback_no_reads/entry.asm | 24 + .../storage_write_rollback_reads/entry.asm | 35 + .../log/storage/storage_writes/entry.asm | 98 + .../testdata/memory_growth/far_call/dummy.asm | 9 + .../testdata/memory_growth/far_call/entry.asm | 30 + .../memory_growth/far_call/far_call_test.asm | 117 + .../memory_growth/heap_write/entry.asm | 30 + .../heap_write/heaps_grows_test.asm | 103 + .../memory_growth/ret/aux_heap_test.asm | 47 + .../testdata/memory_growth/ret/entry.asm | 45 + .../testdata/memory_growth/ret/heap_test.asm | 47 + .../ret_out_of_ergs/aux_heap_test.asm | 49 + .../memory_growth/ret_out_of_ergs/entry.asm | 51 + .../ret_out_of_ergs/heap_test.asm | 49 + .../testdata/meta_opcode/entry.asm | 23 + .../testdata/near_call/limited_ergs/65536.asm | 32 + .../testdata/near_call/limited_ergs/entry.asm | 25 + .../near_call/memory_growth_ret_ok/65536.asm | 76 + .../near_call/memory_growth_ret_ok/entry.asm | 25 + .../near_call/not_rollback_memory/65536.asm | 56 + .../near_call/not_rollback_memory/entry.asm | 25 + .../testdata/near_call/resets_flags/entry.asm | 60 + .../testdata/near_call/resets_sp/entry.asm | 48 + .../ptr/ptr_add_invalid_1_pointer/entry.asm | 21 + .../ptr/ptr_add_src0_erasure/65537.asm | 19 + .../ptr/ptr_add_src0_erasure/entry.asm | 33 + .../ptr/ptr_add_valid_input/entry.asm | 17 + .../testdata/ptr/ptr_erasure_kernel/65533.asm | 57 + .../testdata/ptr/ptr_erasure_kernel/65534.asm | 18 + .../testdata/ptr/ptr_erasure_kernel/entry.asm | 32 + .../ptr/ptr_erasure_not_kernel/65534.asm | 19 + .../ptr/ptr_erasure_not_kernel/65536.asm | 69 + .../ptr/ptr_erasure_not_kernel/entry.asm | 34 + .../testdata/stack/addressing/entry.asm | 88 + .../testdata/stack/overflow/entry.asm | 46 + .../uma/kernel_static_reads/entry.asm | 14 + .../testdata/uma/reads_and_writes/800000.asm | 52 + .../testdata/uma/reads_and_writes/entry.asm | 81 + .../testdata/uma/static_reads/800000.asm | 16 + .../testdata/uma/static_reads/entry.asm | 28 + .../src/tests/simple_tests/uma.rs | 44 + .../zkevm_test_harness/src/tests/storage.rs | 98 + .../zkevm_test_harness/src/tests/utils/mod.rs | 2 + .../src/tests/utils/preprocess_asm.rs | 458 ++ .../src/tests/utils/testing_tracer.rs | 348 ++ crates/zkevm_test_harness/src/toolset.rs | 102 + crates/zkevm_test_harness/src/utils.rs | 214 + .../src/witness/artifacts.rs | 178 + .../src/witness/aux_data_structs/mod.rs | 30 + .../one_per_circuit_accumulator.rs | 195 + .../per_circuit_accumulator.rs | 281 ++ .../data_hasher_and_merklizer.rs | 71 + .../individual_circuits/eip4844_repack.rs | 47 + .../individual_circuits/events_sort_dedup.rs | 578 +++ .../witness/individual_circuits/log_demux.rs | 420 ++ .../witness/individual_circuits/main_vm.rs | 543 +++ .../memory_related/decommit_code.rs | 439 ++ .../memory_related/ecrecover.rs | 233 + .../keccak256_round_function.rs | 601 +++ .../individual_circuits/memory_related/mod.rs | 229 + .../memory_related/ram_permutation.rs | 646 +++ .../memory_related/secp256r1_verify.rs | 238 + .../memory_related/sha256_round_function.rs | 354 ++ .../memory_related/sort_decommit_requests.rs | 457 ++ .../src/witness/individual_circuits/mod.rs | 23 + .../storage_application.rs | 283 ++ .../individual_circuits/storage_sort_dedup.rs | 674 +++ .../transient_storage_sorter.rs | 506 ++ crates/zkevm_test_harness/src/witness/mod.rs | 15 + .../zkevm_test_harness/src/witness/oracle.rs | 1810 ++++++++ .../src/witness/postprocessing/mod.rs | 549 +++ .../postprocessing/observable_witness.rs | 40 + .../src/witness/recursive_aggregation.rs | 412 ++ .../src/witness/tracer/callstack_handler.rs | 462 ++ .../src/witness/tracer/mod.rs | 3 + .../src/witness/tracer/tracer.rs | 424 ++ .../src/witness/tracer/vm_snapshot.rs | 18 + .../src/witness/tree/mod.rs | 832 ++++ .../zkevm_test_harness/src/witness/utils.rs | 837 ++++ .../src/witness/vk_set_generator.rs | 310 ++ .../compression_for_wrapper_proof_1.json | 1 + .../aux_layer/wrapper_proof_1.proof | Bin 0 -> 1624 bytes 566 files changed, 84551 insertions(+), 3384 deletions(-) create mode 100644 .cargo/config.toml create mode 100644 .config/nextest.toml create mode 100644 crates/circuit_definitions/.gitignore create mode 100644 crates/circuit_definitions/Cargo.toml create mode 100644 crates/circuit_definitions/README.md create mode 100644 crates/circuit_definitions/rust-toolchain.toml create mode 100644 crates/circuit_definitions/src/aux_definitions/mod.rs create mode 100644 crates/circuit_definitions/src/aux_definitions/witness_oracle.rs create mode 100644 crates/circuit_definitions/src/circuit_definitions/aux_layer/compression.rs create mode 100644 crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mod.rs create mode 100644 crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_1.rs create mode 100644 crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_1_for_wrapper.rs create mode 100644 crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_2.rs create mode 100644 crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_2_for_wrapper.rs create mode 100644 crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_3.rs create mode 100644 crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_3_for_wrapper.rs create mode 100644 crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_4.rs create mode 100644 crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_4_for_wrapper.rs create mode 100644 crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_5.rs create mode 100644 crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_5_for_wrapper.rs create mode 100644 crates/circuit_definitions/src/circuit_definitions/aux_layer/mod.rs create mode 100644 crates/circuit_definitions/src/circuit_definitions/aux_layer/wrapper.rs create mode 100644 crates/circuit_definitions/src/circuit_definitions/base_layer/code_decommitter.rs create mode 100644 crates/circuit_definitions/src/circuit_definitions/base_layer/ecrecover.rs create mode 100644 crates/circuit_definitions/src/circuit_definitions/base_layer/eip4844.rs create mode 100644 crates/circuit_definitions/src/circuit_definitions/base_layer/events_sort_dedup.rs create mode 100644 crates/circuit_definitions/src/circuit_definitions/base_layer/keccak256_round_function.rs create mode 100644 crates/circuit_definitions/src/circuit_definitions/base_layer/linear_hasher.rs create mode 100644 crates/circuit_definitions/src/circuit_definitions/base_layer/log_demux.rs create mode 100644 crates/circuit_definitions/src/circuit_definitions/base_layer/mod.rs create mode 100644 crates/circuit_definitions/src/circuit_definitions/base_layer/ram_permutation.rs create mode 100644 crates/circuit_definitions/src/circuit_definitions/base_layer/secp256r1_verify.rs create mode 100644 crates/circuit_definitions/src/circuit_definitions/base_layer/sha256_round_function.rs create mode 100644 crates/circuit_definitions/src/circuit_definitions/base_layer/sort_code_decommits.rs create mode 100644 crates/circuit_definitions/src/circuit_definitions/base_layer/storage_apply.rs create mode 100644 crates/circuit_definitions/src/circuit_definitions/base_layer/storage_sort_dedup.rs create mode 100644 crates/circuit_definitions/src/circuit_definitions/base_layer/transient_storage_sort.rs create mode 100644 crates/circuit_definitions/src/circuit_definitions/base_layer/vm_main.rs create mode 100644 crates/circuit_definitions/src/circuit_definitions/mod.rs create mode 100644 crates/circuit_definitions/src/circuit_definitions/recursion_layer/circuit_def.rs create mode 100644 crates/circuit_definitions/src/circuit_definitions/recursion_layer/leaf_layer.rs create mode 100644 crates/circuit_definitions/src/circuit_definitions/recursion_layer/mod.rs create mode 100644 crates/circuit_definitions/src/circuit_definitions/recursion_layer/node_layer.rs create mode 100644 crates/circuit_definitions/src/circuit_definitions/recursion_layer/recursion_tip.rs create mode 100644 crates/circuit_definitions/src/circuit_definitions/recursion_layer/scheduler.rs create mode 100644 crates/circuit_definitions/src/circuit_definitions/recursion_layer/verifier_builder.rs create mode 100644 crates/circuit_definitions/src/circuit_definitions/verifier_builder.rs create mode 100644 crates/circuit_definitions/src/lib.rs create mode 100644 crates/kzg/.gitignore create mode 100644 crates/kzg/Cargo.toml create mode 100644 crates/kzg/README.md create mode 100644 crates/kzg/src/consts.rs create mode 100644 crates/kzg/src/kzg_info.rs create mode 100644 crates/kzg/src/lib.rs create mode 100644 crates/kzg/src/tests/kzg_test_0.json create mode 100644 crates/kzg/src/tests/mod.rs create mode 100644 crates/kzg/src/trusted_setup.json create mode 100644 crates/kzg/src/trusted_setup.rs create mode 100644 crates/zkEVM-assembly/.github/ISSUE_TEMPLATE/bug_report.md create mode 100644 crates/zkEVM-assembly/.github/ISSUE_TEMPLATE/feature_request.md create mode 100644 crates/zkEVM-assembly/.github/pull_request_template.md create mode 100644 crates/zkEVM-assembly/.github/workflows/cargo-license.yaml create mode 100644 crates/zkEVM-assembly/.github/workflows/ci.yaml create mode 100644 crates/zkEVM-assembly/.github/workflows/secrets_scanner.yaml create mode 100644 crates/zkEVM-assembly/.gitignore create mode 100644 crates/zkEVM-assembly/CONTRIBUTING.md create mode 100644 crates/zkEVM-assembly/Cargo.toml create mode 100644 crates/zkEVM-assembly/LICENSE-APACHE create mode 100644 crates/zkEVM-assembly/LICENSE-MIT create mode 100644 crates/zkEVM-assembly/README.md create mode 100644 crates/zkEVM-assembly/SECURITY.md create mode 100755 crates/zkEVM-assembly/assemble.sh create mode 100644 crates/zkEVM-assembly/deny.toml create mode 100644 crates/zkEVM-assembly/eraLogo.png create mode 100644 crates/zkEVM-assembly/examples/arithmetic.sasm create mode 100644 crates/zkEVM-assembly/examples/bitwise.sasm create mode 100644 crates/zkEVM-assembly/examples/brcc.sasm create mode 100644 crates/zkEVM-assembly/examples/brcond.sasm create mode 100644 crates/zkEVM-assembly/examples/calling-convensions.sasm create mode 100644 crates/zkEVM-assembly/examples/diamond.sasm create mode 100644 crates/zkEVM-assembly/examples/factorial.sasm create mode 100644 crates/zkEVM-assembly/examples/fibonacci.sasm create mode 100644 crates/zkEVM-assembly/examples/frame_memory.sasm create mode 100644 crates/zkEVM-assembly/examples/intrinsic.sasm create mode 100644 crates/zkEVM-assembly/examples/ret.sasm create mode 100755 crates/zkEVM-assembly/run.sh create mode 100644 crates/zkEVM-assembly/src/assembly/constants/mod.rs create mode 100644 crates/zkEVM-assembly/src/assembly/instruction/add.rs create mode 100644 crates/zkEVM-assembly/src/assembly/instruction/bitwise.rs create mode 100644 crates/zkEVM-assembly/src/assembly/instruction/condition.rs create mode 100644 crates/zkEVM-assembly/src/assembly/instruction/context.rs create mode 100644 crates/zkEVM-assembly/src/assembly/instruction/div.rs create mode 100644 crates/zkEVM-assembly/src/assembly/instruction/far_call.rs create mode 100644 crates/zkEVM-assembly/src/assembly/instruction/invalid.rs create mode 100644 crates/zkEVM-assembly/src/assembly/instruction/jump.rs create mode 100644 crates/zkEVM-assembly/src/assembly/instruction/log.rs create mode 100644 crates/zkEVM-assembly/src/assembly/instruction/mod.rs create mode 100644 crates/zkEVM-assembly/src/assembly/instruction/mul.rs create mode 100644 crates/zkEVM-assembly/src/assembly/instruction/near_call.rs create mode 100644 crates/zkEVM-assembly/src/assembly/instruction/nop.rs create mode 100644 crates/zkEVM-assembly/src/assembly/instruction/ptr.rs create mode 100644 crates/zkEVM-assembly/src/assembly/instruction/ret.rs create mode 100644 crates/zkEVM-assembly/src/assembly/instruction/set_flags.rs create mode 100644 crates/zkEVM-assembly/src/assembly/instruction/shift.rs create mode 100644 crates/zkEVM-assembly/src/assembly/instruction/sub.rs create mode 100644 crates/zkEVM-assembly/src/assembly/instruction/uma.rs create mode 100644 crates/zkEVM-assembly/src/assembly/instruction/utils.rs create mode 100644 crates/zkEVM-assembly/src/assembly/linking/mod.rs create mode 100644 crates/zkEVM-assembly/src/assembly/mnemonic/add.rs create mode 100644 crates/zkEVM-assembly/src/assembly/mnemonic/binop.rs create mode 100644 crates/zkEVM-assembly/src/assembly/mnemonic/call.rs create mode 100644 crates/zkEVM-assembly/src/assembly/mnemonic/context.rs create mode 100644 crates/zkEVM-assembly/src/assembly/mnemonic/log.rs create mode 100644 crates/zkEVM-assembly/src/assembly/mnemonic/mod.rs create mode 100644 crates/zkEVM-assembly/src/assembly/mnemonic/nop.rs create mode 100644 crates/zkEVM-assembly/src/assembly/mnemonic/set_flags.rs create mode 100644 crates/zkEVM-assembly/src/assembly/mnemonic/shift.rs create mode 100644 crates/zkEVM-assembly/src/assembly/mnemonic/sub.rs create mode 100644 crates/zkEVM-assembly/src/assembly/mnemonic/uma.rs create mode 100644 crates/zkEVM-assembly/src/assembly/mod.rs create mode 100644 crates/zkEVM-assembly/src/assembly/operand/mod.rs create mode 100644 crates/zkEVM-assembly/src/assembly/parse/addressing.rs create mode 100644 crates/zkEVM-assembly/src/assembly/parse/code_element.rs create mode 100644 crates/zkEVM-assembly/src/assembly/parse/constant_operand.rs create mode 100644 crates/zkEVM-assembly/src/assembly/parse/data_element.rs create mode 100644 crates/zkEVM-assembly/src/assembly/parse/mod.rs create mode 100644 crates/zkEVM-assembly/src/assembly/section/mod.rs create mode 100644 crates/zkEVM-assembly/src/error.rs create mode 100644 crates/zkEVM-assembly/src/lib.rs create mode 100644 crates/zkEVM-assembly/src/reader/arguments.rs create mode 100644 crates/zkEVM-assembly/src/reader/main.rs create mode 100644 crates/zkEVM-assembly/src/tests/assembly.rs create mode 100644 crates/zkEVM-assembly/src/tests/binary.rs create mode 100644 crates/zkEVM-assembly/src/tests/mod.rs create mode 100644 crates/zkEVM-assembly/src/tests/new_assembly.rs delete mode 100644 crates/zk_evm/src/vm_state/aux_data.rs create mode 100644 crates/zk_evm_abstractions/src/precompiles/secp256r1_verify.rs create mode 100644 crates/zkevm_circuits/src/recursion/recursion_tip/input.rs create mode 100644 crates/zkevm_circuits/src/recursion/recursion_tip/mod.rs create mode 100644 crates/zkevm_circuits/src/secp256r1_verify/baseline.rs create mode 100644 crates/zkevm_circuits/src/secp256r1_verify/fixed_base_mul_table.rs create mode 100644 crates/zkevm_circuits/src/secp256r1_verify/input.rs create mode 100644 crates/zkevm_circuits/src/secp256r1_verify/mod.rs create mode 100644 crates/zkevm_circuits/src/secp256r1_verify/secp256r1/fq.rs create mode 100644 crates/zkevm_circuits/src/secp256r1_verify/secp256r1/fr.rs create mode 100644 crates/zkevm_circuits/src/secp256r1_verify/secp256r1/mod.rs create mode 100644 crates/zkevm_circuits/src/tables/call_costs_and_stipends.rs create mode 100644 crates/zkevm_circuits/src/tables/pubdata_cost_validity.rs create mode 100644 crates/zkevm_circuits/src/tables/test_bit.rs create mode 100644 crates/zkevm_circuits/src/transient_storage_validity_by_grand_product/input.rs create mode 100644 crates/zkevm_circuits/src/transient_storage_validity_by_grand_product/mod.rs create mode 100644 crates/zkevm_test_harness/.github/ISSUE_TEMPLATE/bug_report.md create mode 100644 crates/zkevm_test_harness/.github/ISSUE_TEMPLATE/feature_request.md create mode 100644 crates/zkevm_test_harness/.github/pull_request_template.md create mode 100644 crates/zkevm_test_harness/.github/workflows/.github/workflows/geometry-config-generator.yml create mode 100644 crates/zkevm_test_harness/.github/workflows/cargo-license.yaml create mode 100644 crates/zkevm_test_harness/.github/workflows/ci.yaml create mode 100644 crates/zkevm_test_harness/.github/workflows/secrets_scanner.yaml create mode 100644 crates/zkevm_test_harness/.gitignore create mode 100644 crates/zkevm_test_harness/CONTRIBUTING.md create mode 100644 crates/zkevm_test_harness/Cargo.toml create mode 100644 crates/zkevm_test_harness/LICENSE-APACHE create mode 100644 crates/zkevm_test_harness/LICENSE-MIT create mode 100644 crates/zkevm_test_harness/README.md create mode 100644 crates/zkevm_test_harness/SECURITY.md create mode 100644 crates/zkevm_test_harness/config.json create mode 100644 crates/zkevm_test_harness/deny.toml create mode 100644 crates/zkevm_test_harness/eraLogo.png create mode 100644 crates/zkevm_test_harness/rust-toolchain.toml create mode 100644 crates/zkevm_test_harness/setup/aux_layer/wrapper_vk_1.key create mode 100644 crates/zkevm_test_harness/setup/base_layer/finalization_hint_1.json create mode 100644 crates/zkevm_test_harness/setup/base_layer/finalization_hint_10.json create mode 100644 crates/zkevm_test_harness/setup/base_layer/finalization_hint_11.json create mode 100644 crates/zkevm_test_harness/setup/base_layer/finalization_hint_12.json create mode 100644 crates/zkevm_test_harness/setup/base_layer/finalization_hint_13.json create mode 100644 crates/zkevm_test_harness/setup/base_layer/finalization_hint_14.json create mode 100644 crates/zkevm_test_harness/setup/base_layer/finalization_hint_15.json create mode 100644 crates/zkevm_test_harness/setup/base_layer/finalization_hint_2.json create mode 100644 crates/zkevm_test_harness/setup/base_layer/finalization_hint_255.json create mode 100644 crates/zkevm_test_harness/setup/base_layer/finalization_hint_3.json create mode 100644 crates/zkevm_test_harness/setup/base_layer/finalization_hint_4.json create mode 100644 crates/zkevm_test_harness/setup/base_layer/finalization_hint_5.json create mode 100644 crates/zkevm_test_harness/setup/base_layer/finalization_hint_6.json create mode 100644 crates/zkevm_test_harness/setup/base_layer/finalization_hint_7.json create mode 100644 crates/zkevm_test_harness/setup/base_layer/finalization_hint_8.json create mode 100644 crates/zkevm_test_harness/setup/base_layer/finalization_hint_9.json create mode 100644 crates/zkevm_test_harness/setup/base_layer/vk_1.json create mode 100644 crates/zkevm_test_harness/setup/base_layer/vk_10.json create mode 100644 crates/zkevm_test_harness/setup/base_layer/vk_11.json create mode 100644 crates/zkevm_test_harness/setup/base_layer/vk_12.json create mode 100644 crates/zkevm_test_harness/setup/base_layer/vk_13.json create mode 100644 crates/zkevm_test_harness/setup/base_layer/vk_14.json create mode 100644 crates/zkevm_test_harness/setup/base_layer/vk_15.json create mode 100644 crates/zkevm_test_harness/setup/base_layer/vk_2.json create mode 100644 crates/zkevm_test_harness/setup/base_layer/vk_255.json create mode 100644 crates/zkevm_test_harness/setup/base_layer/vk_3.json create mode 100644 crates/zkevm_test_harness/setup/base_layer/vk_4.json create mode 100644 crates/zkevm_test_harness/setup/base_layer/vk_5.json create mode 100644 crates/zkevm_test_harness/setup/base_layer/vk_6.json create mode 100644 crates/zkevm_test_harness/setup/base_layer/vk_7.json create mode 100644 crates/zkevm_test_harness/setup/base_layer/vk_8.json create mode 100644 crates/zkevm_test_harness/setup/base_layer/vk_9.json create mode 100644 crates/zkevm_test_harness/setup/recursion_layer/finalization_hint_1.json create mode 100644 crates/zkevm_test_harness/setup/recursion_layer/finalization_hint_10.json create mode 100644 crates/zkevm_test_harness/setup/recursion_layer/finalization_hint_11.json create mode 100644 crates/zkevm_test_harness/setup/recursion_layer/finalization_hint_12.json create mode 100644 crates/zkevm_test_harness/setup/recursion_layer/finalization_hint_13.json create mode 100644 crates/zkevm_test_harness/setup/recursion_layer/finalization_hint_14.json create mode 100644 crates/zkevm_test_harness/setup/recursion_layer/finalization_hint_15.json create mode 100644 crates/zkevm_test_harness/setup/recursion_layer/finalization_hint_16.json create mode 100644 crates/zkevm_test_harness/setup/recursion_layer/finalization_hint_17.json create mode 100644 crates/zkevm_test_harness/setup/recursion_layer/finalization_hint_18.json create mode 100644 crates/zkevm_test_harness/setup/recursion_layer/finalization_hint_3.json create mode 100644 crates/zkevm_test_harness/setup/recursion_layer/finalization_hint_4.json create mode 100644 crates/zkevm_test_harness/setup/recursion_layer/finalization_hint_5.json create mode 100644 crates/zkevm_test_harness/setup/recursion_layer/finalization_hint_6.json create mode 100644 crates/zkevm_test_harness/setup/recursion_layer/finalization_hint_7.json create mode 100644 crates/zkevm_test_harness/setup/recursion_layer/finalization_hint_8.json create mode 100644 crates/zkevm_test_harness/setup/recursion_layer/finalization_hint_9.json create mode 100644 crates/zkevm_test_harness/setup/recursion_layer/finalization_hint_node.json create mode 100644 crates/zkevm_test_harness/setup/recursion_layer/finalization_hint_recursion_tip.json create mode 100644 crates/zkevm_test_harness/setup/recursion_layer/vk_1.json create mode 100644 crates/zkevm_test_harness/setup/recursion_layer/vk_10.json create mode 100644 crates/zkevm_test_harness/setup/recursion_layer/vk_11.json create mode 100644 crates/zkevm_test_harness/setup/recursion_layer/vk_12.json create mode 100644 crates/zkevm_test_harness/setup/recursion_layer/vk_13.json create mode 100644 crates/zkevm_test_harness/setup/recursion_layer/vk_14.json create mode 100644 crates/zkevm_test_harness/setup/recursion_layer/vk_15.json create mode 100644 crates/zkevm_test_harness/setup/recursion_layer/vk_16.json create mode 100644 crates/zkevm_test_harness/setup/recursion_layer/vk_17.json create mode 100644 crates/zkevm_test_harness/setup/recursion_layer/vk_18.json create mode 100644 crates/zkevm_test_harness/setup/recursion_layer/vk_3.json create mode 100644 crates/zkevm_test_harness/setup/recursion_layer/vk_4.json create mode 100644 crates/zkevm_test_harness/setup/recursion_layer/vk_5.json create mode 100644 crates/zkevm_test_harness/setup/recursion_layer/vk_6.json create mode 100644 crates/zkevm_test_harness/setup/recursion_layer/vk_7.json create mode 100644 crates/zkevm_test_harness/setup/recursion_layer/vk_8.json create mode 100644 crates/zkevm_test_harness/setup/recursion_layer/vk_9.json create mode 100644 crates/zkevm_test_harness/setup/recursion_layer/vk_node.json create mode 100644 crates/zkevm_test_harness/setup/recursion_layer/vk_recursion_tip.json create mode 100644 crates/zkevm_test_harness/src/capacity_estimator.rs create mode 100644 crates/zkevm_test_harness/src/circuit_limit_estimator/main.rs create mode 100644 crates/zkevm_test_harness/src/circuit_limit_estimator/mod.rs create mode 100644 crates/zkevm_test_harness/src/circuit_synthesis_performance_test/main.rs create mode 100644 crates/zkevm_test_harness/src/compute_setups.rs create mode 100644 crates/zkevm_test_harness/src/data_source/in_memory_data_source.rs create mode 100644 crates/zkevm_test_harness/src/data_source/local_file_data_source.rs create mode 100644 crates/zkevm_test_harness/src/data_source/mod.rs create mode 100644 crates/zkevm_test_harness/src/debug.rs create mode 100644 crates/zkevm_test_harness/src/entry_point.rs create mode 100644 crates/zkevm_test_harness/src/external_calls.rs create mode 100644 crates/zkevm_test_harness/src/geometry_config_generator/main.rs create mode 100644 crates/zkevm_test_harness/src/helper/artifact_utils.rs create mode 100644 crates/zkevm_test_harness/src/helper/mod.rs create mode 100644 crates/zkevm_test_harness/src/helper/serialize_utils.rs create mode 100644 crates/zkevm_test_harness/src/lib.rs create mode 100644 crates/zkevm_test_harness/src/proof_wrapper_utils/README.md create mode 100644 crates/zkevm_test_harness/src/proof_wrapper_utils/compression.rs create mode 100644 crates/zkevm_test_harness/src/proof_wrapper_utils/compression_for_wrapper.rs create mode 100644 crates/zkevm_test_harness/src/proof_wrapper_utils/mod.rs create mode 100644 crates/zkevm_test_harness/src/proof_wrapper_utils/proof_compression_test.rs create mode 100644 crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_for_wrapper_proof_2.json create mode 100644 crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_for_wrapper_vk_2.json create mode 100644 crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_proof_1.json create mode 100644 crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_proof_2.json create mode 100644 crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_proof_3.json create mode 100644 crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_proof_4.json create mode 100644 crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_vk_1.json create mode 100644 crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_vk_2.json create mode 100644 crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_vk_3.json create mode 100644 crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_vk_4.json create mode 100644 crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/recursion_layer/scheduler_proof.json create mode 100644 crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/recursion_layer/vk_1.json create mode 100644 crates/zkevm_test_harness/src/proof_wrapper_utils/utils.rs create mode 100644 crates/zkevm_test_harness/src/proof_wrapper_utils/wrapper.rs create mode 100644 crates/zkevm_test_harness/src/prover_utils.rs create mode 100644 crates/zkevm_test_harness/src/run_vms.rs create mode 100644 crates/zkevm_test_harness/src/snark_wrapper_test/mod.rs create mode 100644 crates/zkevm_test_harness/src/tests/complex_tests/invididual_debugs.rs create mode 100644 crates/zkevm_test_harness/src/tests/complex_tests/mod.rs create mode 100644 crates/zkevm_test_harness/src/tests/complex_tests/test_artifacts/basic_test.json create mode 100644 crates/zkevm_test_harness/src/tests/complex_tests/test_artifacts/basic_test_commit_hash create mode 100644 crates/zkevm_test_harness/src/tests/complex_tests/test_artifacts/compiler_metadata create mode 100644 crates/zkevm_test_harness/src/tests/complex_tests/test_artifacts/empty_proof.bin create mode 100644 crates/zkevm_test_harness/src/tests/complex_tests/test_artifacts/system_contracts_commit_hash create mode 100644 crates/zkevm_test_harness/src/tests/complex_tests/test_synthesis.rs create mode 100644 crates/zkevm_test_harness/src/tests/complex_tests/testing_wrapper.rs create mode 100644 crates/zkevm_test_harness/src/tests/complex_tests/utils.rs create mode 100644 crates/zkevm_test_harness/src/tests/complex_tests/wrapper_negative_tests.rs create mode 100644 crates/zkevm_test_harness/src/tests/mod.rs create mode 100644 crates/zkevm_test_harness/src/tests/run_manually.rs create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/README.md create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/asm_tests.rs create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/context.rs create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/eip4844.rs create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/far_call.rs create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/kernel_ops.rs create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/log.rs create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/memory_growth.rs create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/mod.rs create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/near_call.rs create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/ptr.rs create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/stack.rs create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/storage.rs create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/fail_on_decommit/65536.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/fail_on_decommit/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/panic_on_return_large_data/65536.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/panic_on_return_large_data/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/pay_for_memory_growth/65536.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/pay_for_memory_growth/65537.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/pay_for_memory_growth/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/read_fat_pointer/65535.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/read_fat_pointer/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/return_large_data/65536.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/return_large_data/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/decommit_invalid/800000.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/decommit_invalid/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/decommit_ok/800000.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/decommit_ok/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/decommit_ok_twice/800000.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/decommit_ok_twice/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/decommit_ok_with_panic/800000.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/decommit_ok_with_panic/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/l1_message_has_zero_pubdata_cost/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/l1_message_out_of_gas/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/precompile_invalid_address/65399.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/precompile_invalid_address/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/precompile_out_of_gas/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/storage/storage_clear_slot/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/storage/storage_pubdata_refunds/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/storage/storage_reads/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/storage/storage_write_after_panic/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/storage/storage_write_rollback_no_reads/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/storage/storage_write_rollback_reads/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/storage/storage_writes/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/far_call/dummy.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/far_call/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/far_call/far_call_test.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/heap_write/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/heap_write/heaps_grows_test.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/ret/aux_heap_test.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/ret/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/ret/heap_test.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/ret_out_of_ergs/aux_heap_test.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/ret_out_of_ergs/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/ret_out_of_ergs/heap_test.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/meta_opcode/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/near_call/limited_ergs/65536.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/near_call/limited_ergs/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/near_call/memory_growth_ret_ok/65536.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/near_call/memory_growth_ret_ok/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/near_call/not_rollback_memory/65536.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/near_call/not_rollback_memory/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/near_call/resets_flags/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/near_call/resets_sp/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_add_invalid_1_pointer/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_add_src0_erasure/65537.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_add_src0_erasure/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_add_valid_input/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_erasure_kernel/65533.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_erasure_kernel/65534.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_erasure_kernel/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_erasure_not_kernel/65534.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_erasure_not_kernel/65536.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_erasure_not_kernel/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/stack/addressing/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/stack/overflow/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/uma/kernel_static_reads/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/uma/reads_and_writes/800000.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/uma/reads_and_writes/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/uma/static_reads/800000.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/testdata/uma/static_reads/entry.asm create mode 100644 crates/zkevm_test_harness/src/tests/simple_tests/uma.rs create mode 100644 crates/zkevm_test_harness/src/tests/storage.rs create mode 100644 crates/zkevm_test_harness/src/tests/utils/mod.rs create mode 100644 crates/zkevm_test_harness/src/tests/utils/preprocess_asm.rs create mode 100644 crates/zkevm_test_harness/src/tests/utils/testing_tracer.rs create mode 100644 crates/zkevm_test_harness/src/toolset.rs create mode 100644 crates/zkevm_test_harness/src/utils.rs create mode 100644 crates/zkevm_test_harness/src/witness/artifacts.rs create mode 100644 crates/zkevm_test_harness/src/witness/aux_data_structs/mod.rs create mode 100644 crates/zkevm_test_harness/src/witness/aux_data_structs/one_per_circuit_accumulator.rs create mode 100644 crates/zkevm_test_harness/src/witness/aux_data_structs/per_circuit_accumulator.rs create mode 100644 crates/zkevm_test_harness/src/witness/individual_circuits/data_hasher_and_merklizer.rs create mode 100644 crates/zkevm_test_harness/src/witness/individual_circuits/eip4844_repack.rs create mode 100644 crates/zkevm_test_harness/src/witness/individual_circuits/events_sort_dedup.rs create mode 100644 crates/zkevm_test_harness/src/witness/individual_circuits/log_demux.rs create mode 100644 crates/zkevm_test_harness/src/witness/individual_circuits/main_vm.rs create mode 100644 crates/zkevm_test_harness/src/witness/individual_circuits/memory_related/decommit_code.rs create mode 100644 crates/zkevm_test_harness/src/witness/individual_circuits/memory_related/ecrecover.rs create mode 100644 crates/zkevm_test_harness/src/witness/individual_circuits/memory_related/keccak256_round_function.rs create mode 100644 crates/zkevm_test_harness/src/witness/individual_circuits/memory_related/mod.rs create mode 100644 crates/zkevm_test_harness/src/witness/individual_circuits/memory_related/ram_permutation.rs create mode 100644 crates/zkevm_test_harness/src/witness/individual_circuits/memory_related/secp256r1_verify.rs create mode 100644 crates/zkevm_test_harness/src/witness/individual_circuits/memory_related/sha256_round_function.rs create mode 100644 crates/zkevm_test_harness/src/witness/individual_circuits/memory_related/sort_decommit_requests.rs create mode 100644 crates/zkevm_test_harness/src/witness/individual_circuits/mod.rs create mode 100644 crates/zkevm_test_harness/src/witness/individual_circuits/storage_application.rs create mode 100644 crates/zkevm_test_harness/src/witness/individual_circuits/storage_sort_dedup.rs create mode 100644 crates/zkevm_test_harness/src/witness/individual_circuits/transient_storage_sorter.rs create mode 100644 crates/zkevm_test_harness/src/witness/mod.rs create mode 100644 crates/zkevm_test_harness/src/witness/oracle.rs create mode 100644 crates/zkevm_test_harness/src/witness/postprocessing/mod.rs create mode 100644 crates/zkevm_test_harness/src/witness/postprocessing/observable_witness.rs create mode 100644 crates/zkevm_test_harness/src/witness/recursive_aggregation.rs create mode 100644 crates/zkevm_test_harness/src/witness/tracer/callstack_handler.rs create mode 100644 crates/zkevm_test_harness/src/witness/tracer/mod.rs create mode 100644 crates/zkevm_test_harness/src/witness/tracer/tracer.rs create mode 100644 crates/zkevm_test_harness/src/witness/tracer/vm_snapshot.rs create mode 100644 crates/zkevm_test_harness/src/witness/tree/mod.rs create mode 100644 crates/zkevm_test_harness/src/witness/utils.rs create mode 100644 crates/zkevm_test_harness/src/witness/vk_set_generator.rs create mode 100644 crates/zkevm_test_harness/test_proofs/aux_layer/compression_for_wrapper_proof_1.json create mode 100644 crates/zkevm_test_harness/test_proofs/aux_layer/wrapper_proof_1.proof diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..7640dbc --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,2 @@ +[env] +RUST_MIN_STACK = "8388608" \ No newline at end of file diff --git a/.config/nextest.toml b/.config/nextest.toml new file mode 100644 index 0000000..e24c532 --- /dev/null +++ b/.config/nextest.toml @@ -0,0 +1,3 @@ +[profile.default] +slow-timeout = { period = "180s", terminate-after = 5, grace-period = "30s" } + diff --git a/crates/circuit_definitions/.gitignore b/crates/circuit_definitions/.gitignore new file mode 100644 index 0000000..37a4f98 --- /dev/null +++ b/crates/circuit_definitions/.gitignore @@ -0,0 +1,4 @@ +/target +Cargo.lock +.idea +.DS_Store \ No newline at end of file diff --git a/crates/circuit_definitions/Cargo.toml b/crates/circuit_definitions/Cargo.toml new file mode 100644 index 0000000..33ea253 --- /dev/null +++ b/crates/circuit_definitions/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "circuit_definitions" +version = "0.150.2" +edition = "2021" +authors = ["The Matter Labs Team "] +homepage = "https://zksync.io/" +repository = "https://github.com/matter-labs/era-zkevm_test_harness/" +license = "MIT OR Apache-2.0" +keywords = ["blockchain", "zksync"] +categories = ["cryptography"] +description = "ZKsync Era circuits definitions" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +circuit_encodings = { version = "0.150.2", path = "../circuit_encodings" } +snark_wrapper = "=0.1.2" + +derivative = "2.2" +serde = {version = "1", features = ["derive"]} +crossbeam = "0.8" +seq-macro = "0.3.5" + +[features] +default = [] +log_tracing = ["circuit_encodings/log_tracing"] +verbose_circuits = ["circuit_encodings/verbose_circuits"] diff --git a/crates/circuit_definitions/README.md b/crates/circuit_definitions/README.md new file mode 100644 index 0000000..28bf271 --- /dev/null +++ b/crates/circuit_definitions/README.md @@ -0,0 +1,55 @@ +# Circuits definitions crate + +This crate contains the 'outer layer' for multiple circuits. The concrete circuits code is in `era-zkevm_circuits` +repository. + +## Code structure + +We have 13 different 'base layer' circuits (for example MainVM, Decomitter), and 3 recursive circuits (Leaf, Node and +Scheduler). + +Base layer circuits are located in `src/base_layer`, Recursive circuits are in `src/recursion_layer`. + +We also have 'AUX' circuits: compressors and wrapper, that are run on top of the final Scheduler proof, and they are +located in `src/aux_layer`. + +![circuits](https://user-images.githubusercontent.com/128217157/275817097-0a543476-52e5-437b-a7d3-10603d5833fa.png) + +`src/encodings` directory contain some helper structs that are used by the test harness (and should match the ones used +in circuits themselves). + +## Circuit types + +We have 12 different circuit types (in witness, you might notice 13, as one circuit (events_dedup_and_sort) is used for +both L1 messages and events). + +| Circuit name | Location | Description | +| ------------------------ | ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Main VM | vm_main.rs | Executes OpCodes from the VM | +| CodeDecommittmentsSorter | sort_code_decommit.rs | Verifies the order of requests for code decommitment (fetching bytecode based on hash). | +| CodeDecommiter | code_decommiter.rs | Unpacks the bytecode matching a given hash into memory. | +| LogDemuxer | log_demux.rs | Splits the queue into 6 output ones (like keccak, sha, storage). | +| KeccakRoundFunction | keccak256_round_functions.rs | Round of the keccak hash | +| Sha256RoundFunction | sha256_round_function.rs | Round of sha256 hash | +| ECRecover | ecrecover.rs | Verifies ECRecover | +| RAMPermutation | ram_permutation.rs | Verifies the correctness of the RAM accesses - looking at the access queue, and checking that correct bytes values were read | +| StorageSorter | storage_sort_dedup.rs | Similar to RAM permutation, but for storage - checking that correct bytes were stored / read. | +| StorageApplication | storage_apply.rs | Verifies the final merkle root and storage diffs based on the data that was written during computation. | +| EventsSorter | events_sort_dedup.rs | Verifies that a given 'unsorted' queue is matching the sorted one, without any repetitions. In this case, used for System Events. | +| L1MessagesSorter | events_sort_dedup.rs | It reuses the circuit above, but this time to sort user generated events (L2 -> L1 messages). | +| L1MessageHasher | linear_hasher.rs | Verifies that linear hash of L1 messages matches the content of the queue. | + +3 recursive circuits: + +| Circuit name | Location | Description | +| ------------ | ------------- | --------------------------------------------------------- | +| Leaf | leaf_layer.rs | Aggregates 32 basic circuits of the same type | +| Node | node_layer.rs | Aggregates 32 leaf (or node) circruits of the same type | +| Scheduler | scheduler.rs | Aggregates 13 nodes (1 from each type) into a final proof | + +And 'wrapper'/AUX circuits on top: + +| Circuit name | Location | Description | +| ------------ | -------------- | ---------------------------------------------------------------------------------------- | +| Compression | compression.rs | Compresses the final scheduler proof | +| Wrapper | wrapper.rs | Wraps the compressed proof into a SNARK to be verifierd on L1. (This is a SNARK circuit) | diff --git a/crates/circuit_definitions/rust-toolchain.toml b/crates/circuit_definitions/rust-toolchain.toml new file mode 100644 index 0000000..bc5d1d6 --- /dev/null +++ b/crates/circuit_definitions/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +channel = "nightly-2024-08-01" diff --git a/crates/circuit_definitions/src/aux_definitions/mod.rs b/crates/circuit_definitions/src/aux_definitions/mod.rs new file mode 100644 index 0000000..7b71541 --- /dev/null +++ b/crates/circuit_definitions/src/aux_definitions/mod.rs @@ -0,0 +1 @@ +pub mod witness_oracle; diff --git a/crates/circuit_definitions/src/aux_definitions/witness_oracle.rs b/crates/circuit_definitions/src/aux_definitions/witness_oracle.rs new file mode 100644 index 0000000..fb9c102 --- /dev/null +++ b/crates/circuit_definitions/src/aux_definitions/witness_oracle.rs @@ -0,0 +1,641 @@ +use crate::boojum::field::SmallField; +use crate::boojum::gadgets::traits::allocatable::CSAllocatable; +use crate::encodings::callstack_entry::*; +use crate::ethereum_types::U256; +use crate::zk_evm::{ + aux_structures::{DecommittmentQuery, LogQuery, MemoryQuery, PubdataCost}, + vm_state::CallStackEntry, +}; +use crate::zkevm_circuits::base_structures::vm_state::QUEUE_STATE_WIDTH; +use derivative::*; +use std::collections::VecDeque; + +pub fn u128_as_u32_le(value: u128) -> [u32; 4] { + [ + value as u32, + (value >> 32) as u32, + (value >> 64) as u32, + (value >> 96) as u32, + ] +} + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Default(bound = ""), Clone(bound = ""))] +#[serde(bound = "")] +pub struct VmWitnessOracle { + pub initial_cycle: u32, + pub final_cycle_inclusive: u32, + pub memory_read_witness: VecDeque<(u32, MemoryQuery)>, + pub memory_write_witness: Option>, + pub rollback_queue_head_segments: VecDeque<(u32, [F; QUEUE_STATE_WIDTH])>, + pub decommittment_requests_witness: VecDeque<(u32, DecommittmentQuery)>, + pub rollback_queue_initial_tails_for_new_frames: VecDeque<(u32, [F; QUEUE_STATE_WIDTH])>, + pub storage_queries: VecDeque<(u32, LogQuery)>, // cycle, query + pub storage_access_cold_warm_refunds: VecDeque<(u32, LogQuery, u32)>, // cycle, query, refund + pub storage_pubdata_queries: VecDeque<(u32, LogQuery, PubdataCost)>, // cycle, query, pubdata cost + pub callstack_new_frames_witnesses: VecDeque<(u32, CallStackEntry)>, + pub callstack_values_witnesses: + VecDeque<(u32, (ExtendedCallstackEntry, CallstackSimulatorState))>, +} + +use crate::zkevm_circuits::base_structures::decommit_query::DecommitQueryWitness; +use crate::zkevm_circuits::base_structures::log_query::LogQueryWitness; +use crate::zkevm_circuits::base_structures::memory_query::MemoryQueryWitness; +use crate::zkevm_circuits::base_structures::vm_state::saved_context::ExecutionContextRecordWitness; +use crate::zkevm_circuits::main_vm::witness_oracle::MemoryWitness; +use crate::zkevm_circuits::main_vm::witness_oracle::WitnessOracle; + +impl WitnessOracle for VmWitnessOracle { + fn get_memory_witness_for_read( + &mut self, + timestamp: u32, + memory_page: u32, + index: u32, + execute: bool, + ) -> MemoryWitness { + if execute { + if self.memory_read_witness.is_empty() { + panic!( + "should have a witness to read at timestamp {}, page {}, index {}", + timestamp, memory_page, index, + ); + } + let (_cycle, query) = self.memory_read_witness.pop_front().unwrap(); + + // tracing::debug!("Query value = 0x{:064x}", query.value); + assert_eq!( + timestamp, + query.timestamp.0, + "invalid memory access location at cycle {:?}: VM asks at timestamp {}, witness has timestamp {}. VM reads page = {}, index = {}, witness query = {:?}", + _cycle, + timestamp, + query.timestamp.0, + memory_page, + index, + query, + ); + + assert_eq!( + memory_page, + query.location.page.0, + "invalid memory access location at timestamp {:?}: VM asks for page {}, witness has page {}", + timestamp, + memory_page, + query.location.page.0, + ); + assert_eq!( + index, + query.location.index.0, + "invalid memory access location at timestamp {:?}: VM asks for index {}, witness has index {}", + timestamp, + index, + query.location.index.0, + ); + + // tracing::debug!("memory word = 0x{:x}", query.value); + + MemoryWitness { + value: query.value, + is_ptr: query.value_is_pointer, + } + } else { + MemoryWitness { + value: U256::zero(), + is_ptr: false, + } + } + } + fn push_memory_witness(&mut self, memory_query: &MemoryQueryWitness, execute: bool) { + if let Some(write_witness) = self.memory_write_witness.as_mut() { + if execute { + let wit = memory_query; + + if write_witness.is_empty() { + panic!( + "should have a self-check witness to write at timestamp {}, page {}, index {}", + wit.timestamp, + wit.memory_page, + wit.index, + ); + } + let (_cycle, query) = write_witness.pop_front().unwrap(); + + assert_eq!( + wit.timestamp, + query.timestamp.0, + "invalid memory access location at timestamp {:?}: VM writes into timestamp {}, witness has timestamp {}", + wit.timestamp, + wit.timestamp, + query.timestamp.0, + ); + + assert_eq!( + wit.memory_page, + query.location.page.0, + "invalid memory access location at timestamp {:?}: VM writes into page {}, witness has page {}", + wit.timestamp, + wit.memory_page, + query.location.page.0, + ); + + assert_eq!( + wit.index, + query.location.index.0, + "invalid memory access location at timestamp {:?}: VM writes into index {}, witness has index {}", + wit.timestamp, + wit.index, + query.location.index.0, + ); + + // compare values + assert_eq!( + wit.value, + query.value, + "invalid memory access location at timestamp {:?}: VM writes value {}, witness has value {}", + wit.timestamp, + wit.value, + query.value, + ); + + assert_eq!( + wit.is_ptr, + query.value_is_pointer, + "invalid memory access location at timestamp {:?}: VM writes pointer {}, witness has pointer {}", + wit.timestamp, + wit.is_ptr, + query.value_is_pointer, + ); + } + } + } + fn get_storage_read_witness( + &mut self, + key: &LogQueryWitness, + needs_witness: bool, + execute: bool, + ) -> U256 { + if execute && needs_witness { + if self.storage_queries.is_empty() { + panic!("should have a witness for storage read at {:?}", key); + } + let (_cycle, query) = self.storage_queries.pop_front().unwrap(); + + let record = key; + assert_eq!(record.aux_byte, query.aux_byte); + assert_eq!(record.address, query.address); + assert_eq!(record.key, query.key); + assert_eq!(record.rw_flag, query.rw_flag); + if record.rw_flag == true { + // check written value + assert_eq!(record.written_value, query.written_value); + } + assert_eq!(record.rollback, false); + assert_eq!(record.rollback, query.rollback); + assert_eq!(record.is_service, query.is_service); + assert_eq!(record.shard_id, query.shard_id); + assert_eq!(record.tx_number_in_block, query.tx_number_in_block as u32); + assert_eq!(record.timestamp, query.timestamp.0); + + query.read_value + } else { + U256::zero() + } + } + fn get_cold_warm_refund( + &mut self, + query: &LogQueryWitness, + is_write: bool, + execute: bool, + ) -> u32 { + if execute { + if self.storage_access_cold_warm_refunds.is_empty() { + panic!( + "should have a cold/warm refund witness for storage write attempt at {:?}", + query, + ); + } + let (_cycle, query, refund) = + self.storage_access_cold_warm_refunds.pop_front().unwrap(); + let record = query; + assert_eq!(record.aux_byte, query.aux_byte); + assert_eq!(record.address, query.address); + assert_eq!(record.key, query.key); + assert_eq!(record.rw_flag, query.rw_flag); + assert_eq!(record.rw_flag, is_write); + assert_eq!(record.written_value, query.written_value); + assert_eq!(record.rollback, false); + assert_eq!(record.rollback, query.rollback); + assert_eq!(record.shard_id, query.shard_id); + // the rest are not filled in out-of-circuit implementations + assert_eq!(record.is_service, query.is_service); + + refund + } else { + 0u32 + } + } + fn get_pubdata_cost_for_query( + &mut self, + query: &LogQueryWitness, + is_write: bool, + execute: bool, + ) -> u32 { + if execute { + if self.storage_pubdata_queries.is_empty() { + panic!( + "should have a pubdata cost witness for storage write attempt at {:?}", + query, + ); + } + let (_cycle, query, cost) = self.storage_pubdata_queries.pop_front().unwrap(); + let record = query; + assert_eq!(record.aux_byte, query.aux_byte); + assert_eq!(record.address, query.address); + assert_eq!(record.key, query.key); + assert_eq!(record.rw_flag, query.rw_flag); + assert_eq!(record.rw_flag, is_write); + assert_eq!(record.written_value, query.written_value); + assert_eq!(record.rollback, false); + assert_eq!(record.rollback, query.rollback); + assert_eq!(record.shard_id, query.shard_id); + // the rest are not filled in out-of-circuit implementations + assert_eq!(record.is_service, query.is_service); + + let cost_two_complement = cost.0 as u32; // two-complement + + if is_write == false { + assert_eq!(cost_two_complement, 0); + } + + cost_two_complement + } else { + 0u32 + } + } + fn push_storage_witness(&mut self, _key: &LogQueryWitness, _execute: bool) { + // logic is captured in read for a reason that we NEED + // previous value of the cell for rollback to work + unreachable!() + } + fn get_rollback_queue_witness(&mut self, _key: &LogQueryWitness, execute: bool) -> [F; 4] { + if execute { + let (_cycle, head) = self.rollback_queue_head_segments.pop_front().unwrap(); + // dbg!(head); + + head + } else { + [F::ZERO; 4] + } + } + fn get_rollback_queue_tail_witness_for_call( + &mut self, + _timestamp: u32, + execute: bool, + ) -> [F; 4] { + if execute { + let (_cycle_idx, tail) = self + .rollback_queue_initial_tails_for_new_frames + .pop_front() + .unwrap(); + // dbg!(tail); + + tail + } else { + [F::ZERO; 4] + } + } + fn push_callstack_witness( + &mut self, + current_record: &ExecutionContextRecordWitness, + current_depth: u32, + execute: bool, + ) { + // we do not care, but we can do self-check + + if execute { + let (_cycle_idx, (extended_entry, internediate_info)) = + self.callstack_values_witnesses.pop_front().unwrap(); + + let CallstackSimulatorState { + is_push, + previous_state: _, + new_state: _, + depth: witness_depth, + round_function_execution_pairs: _, + } = internediate_info; + // compare + let witness = current_record; + + assert!( + is_push, + "divergence at callstack push at cycle {}:\n pushing {:?}\n in circuit, but got POP of \n{:?}\n in oracle", + _cycle_idx, + &witness, + &extended_entry, + ); + + assert_eq!( + current_depth + 1, + witness_depth as u32, + "depth diverged at callstack push at cycle {}:\n pushing {:?}\n, got \n{:?}\n in oracle", + _cycle_idx, + &witness, + &extended_entry, + ); + + let ExtendedCallstackEntry { + callstack_entry: entry, + rollback_queue_head, + rollback_queue_tail, + rollback_queue_segment_length, + } = extended_entry; + + assert_eq!(entry.this_address, witness.this); + assert_eq!(entry.msg_sender, witness.caller); + assert_eq!(entry.code_address, witness.code_address); + + assert_eq!(entry.code_page.0, witness.code_page); + assert_eq!(entry.base_memory_page.0, witness.base_page); + + assert_eq!(rollback_queue_head, witness.reverted_queue_head); + assert_eq!(rollback_queue_tail, witness.reverted_queue_tail); + assert_eq!( + rollback_queue_segment_length, + witness.reverted_queue_segment_len + ); + + assert_eq!(entry.pc, witness.pc); + assert_eq!(entry.sp, witness.sp); + + assert_eq!(entry.heap_bound, witness.heap_upper_bound); + assert_eq!(entry.aux_heap_bound, witness.aux_heap_upper_bound); + + assert_eq!( + entry.exception_handler_location, + witness.exception_handler_loc + ); + assert_eq!(entry.ergs_remaining, witness.ergs_remaining); + + assert_eq!(entry.is_static, witness.is_static_execution); + assert_eq!(entry.is_kernel_mode(), witness.is_kernel_mode); + + assert_eq!(entry.this_shard_id, witness.this_shard_id); + assert_eq!(entry.caller_shard_id, witness.caller_shard_id); + assert_eq!(entry.code_shard_id, witness.code_shard_id); + + assert_eq!(entry.stipend, witness.stipend); + assert_eq!( + entry.total_pubdata_spent.0 as u32, + witness.total_pubdata_spent + ); + + let witness_composite = [ + (witness.context_u128_value_composite[0] as u64) + + ((witness.context_u128_value_composite[1] as u64) << 32), + (witness.context_u128_value_composite[2] as u64) + + ((witness.context_u128_value_composite[3] as u64) << 32), + ]; + + assert_eq!( + [ + entry.context_u128_value as u64, + (entry.context_u128_value >> 64) as u64 + ], + witness_composite + ); + + assert_eq!(entry.is_local_frame, witness.is_local_call); + } + } + fn get_callstack_witness( + &mut self, + execute: bool, + depth: u32, + ) -> (ExecutionContextRecordWitness, [F; 12]) { + if execute { + let (_cycle_idx, (extended_entry, internediate_info)) = + self.callstack_values_witnesses.pop_front().unwrap(); + let CallstackSimulatorState { + is_push, + previous_state: _, + new_state, + depth: witness_depth, + round_function_execution_pairs: _, + } = internediate_info; + + assert!( + is_push == false, + "divergence at callstack pop at cycle {}: POP in circuit, but we expect PUSH of \n{:?}\n in oracle", + _cycle_idx, + &extended_entry, + ); + + assert_eq!( + depth - 1, + witness_depth as u32, + "depth diverged at callstack pop at cycle {}, got \n{:?}\n in oracle", + _cycle_idx, + &extended_entry, + ); + + // dbg!(new_state); + + let ExtendedCallstackEntry { + callstack_entry: entry, + rollback_queue_head, + rollback_queue_tail, + rollback_queue_segment_length, + } = extended_entry; + + let witness = ExecutionContextRecordWitness { + this: entry.this_address, + caller: entry.msg_sender, + code_address: entry.code_address, + code_page: entry.code_page.0, + base_page: entry.base_memory_page.0, + reverted_queue_head: rollback_queue_head, + reverted_queue_tail: rollback_queue_tail, + reverted_queue_segment_len: rollback_queue_segment_length, + pc: entry.pc, + sp: entry.sp, + exception_handler_loc: entry.exception_handler_location, + ergs_remaining: entry.ergs_remaining, + is_static_execution: entry.is_static, + is_kernel_mode: entry.is_kernel_mode(), + this_shard_id: entry.this_shard_id, + caller_shard_id: entry.caller_shard_id, + code_shard_id: entry.code_shard_id, + context_u128_value_composite: u128_as_u32_le(entry.context_u128_value), + heap_upper_bound: entry.heap_bound, + aux_heap_upper_bound: entry.aux_heap_bound, + is_local_call: entry.is_local_frame, + stipend: entry.stipend, + total_pubdata_spent: entry.total_pubdata_spent.0 as u32, // two-complement + }; + + (witness, new_state) + } else { + use crate::zkevm_circuits::base_structures::vm_state::saved_context::ExecutionContextRecord; + + (ExecutionContextRecord::placeholder_witness(), [F::ZERO; 12]) + } + } + fn report_new_callstack_frame( + &mut self, + new_record: &ExecutionContextRecordWitness, + _new_depth: u32, + is_call: bool, + execute: bool, + ) { + if execute && is_call { + let (_cycle_idx, entry) = self.callstack_new_frames_witnesses.pop_front().unwrap(); + + // compare + let witness = new_record; + + assert_eq!(entry.this_address, witness.this); + assert_eq!(entry.msg_sender, witness.caller); + assert_eq!(entry.code_address, witness.code_address); + + assert_eq!(entry.code_page.0, witness.code_page); + assert_eq!(entry.base_memory_page.0, witness.base_page); + + assert_eq!(entry.pc, witness.pc); + assert_eq!(entry.sp, witness.sp); + + assert_eq!(entry.heap_bound, witness.heap_upper_bound); + assert_eq!(entry.aux_heap_bound, witness.aux_heap_upper_bound); + + assert_eq!( + entry.exception_handler_location, + witness.exception_handler_loc + ); + assert_eq!(entry.ergs_remaining, witness.ergs_remaining); + + assert_eq!(entry.is_static, witness.is_static_execution); + assert_eq!(entry.is_kernel_mode(), witness.is_kernel_mode); + + assert_eq!(entry.this_shard_id, witness.this_shard_id); + assert_eq!(entry.caller_shard_id, witness.caller_shard_id); + assert_eq!(entry.code_shard_id, witness.code_shard_id); + + assert_eq!( + u128_as_u32_le(entry.context_u128_value), + witness.context_u128_value_composite + ); + + assert_eq!(entry.is_local_frame, witness.is_local_call); + } + } + fn get_decommittment_request_suggested_page( + &mut self, + request: &DecommitQueryWitness, + execute: bool, + ) -> u32 { + if execute { + if self.decommittment_requests_witness.is_empty() { + panic!("Witness value is missing for {:?}", request); + } + + let (_frame_idx, query) = self + .decommittment_requests_witness + .pop_front() + .unwrap_or_else(|| { + panic!("Witness value is missing for {:?}", request); + }); + + assert_eq!(request.timestamp, query.timestamp.0); + let mut normalized_hash_buffer = [0u8; 32]; + normalized_hash_buffer[4..].copy_from_slice(&query.normalized_preimage.0[..]); + let query_hash = U256::from_big_endian(&normalized_hash_buffer); + assert!( + request.code_hash == query_hash, + "circuit expected hash 0x{:064x}, while witness had 0x{:064x}", + request.code_hash, + query_hash, + ); + + query.memory_page.0 + } else { + 0 + } + } + fn at_completion(self) { + if self.memory_read_witness.is_empty() == false { + panic!( + "Too many memory queries in witness over cycles range {}..={}: have left\n{:?}", + self.initial_cycle, self.final_cycle_inclusive, self.memory_read_witness + ); + } + + if let Some(memory_write_witness) = self.memory_write_witness { + if memory_write_witness.is_empty() == false { + panic!( + "Too many memory write queries in witness over cycles range {}..={}: have left\n{:?}", + self.initial_cycle, + self.final_cycle_inclusive, + memory_write_witness + ); + } + } + + if self.storage_queries.is_empty() == false { + panic!( + "Too many storage queries in witness over cycles range {}..={}: have left\n{:?}", + self.initial_cycle, self.final_cycle_inclusive, self.storage_queries + ); + } + + if self.storage_access_cold_warm_refunds.is_empty() == false { + panic!( + "Too many storage queries for refunds in witness over cycles range {}..={}: have left\n{:?}", + self.initial_cycle, + self.final_cycle_inclusive, + self.storage_access_cold_warm_refunds + ); + } + + if self.storage_pubdata_queries.is_empty() == false { + panic!( + "Too many storage queries for pubdata in witness over cycles range {}..={}: have left\n{:?}", + self.initial_cycle, + self.final_cycle_inclusive, + self.storage_pubdata_queries + ); + } + + if self.callstack_values_witnesses.is_empty() == false { + panic!( + "Too many callstack sponge witnesses over cycles range {}..={}: have left\n{:?}", + self.initial_cycle, self.final_cycle_inclusive, self.callstack_values_witnesses + ); + } + + if self.decommittment_requests_witness.is_empty() == false { + panic!( + "Too many decommittment request witnesses over cycles range {}..={}: have left\n{:?}", + self.initial_cycle, + self.final_cycle_inclusive, + self.decommittment_requests_witness + ); + } + + if self.rollback_queue_head_segments.is_empty() == false { + panic!( + "Too many rollback queue heads in witnesses over cycles range {}..={}: have left\n{:?}", + self.initial_cycle, + self.final_cycle_inclusive, + self.rollback_queue_head_segments + ); + } + + if self.rollback_queue_initial_tails_for_new_frames.is_empty() == false { + panic!( + "Too many rollback queue heads new stack frames in witnesses over cycles range {}..={}: have left\n{:?}", + self.initial_cycle, + self.final_cycle_inclusive, + self.rollback_queue_initial_tails_for_new_frames + ); + } + } +} diff --git a/crates/circuit_definitions/src/circuit_definitions/aux_layer/compression.rs b/crates/circuit_definitions/src/circuit_definitions/aux_layer/compression.rs new file mode 100644 index 0000000..e670dbe --- /dev/null +++ b/crates/circuit_definitions/src/circuit_definitions/aux_layer/compression.rs @@ -0,0 +1,181 @@ +use crate::boojum::algebraic_props::round_function::AbsorptionModeOverwrite; +use crate::boojum::algebraic_props::sponge::GoldilocksPoseidon2Sponge; + +use crate::boojum::cs::implementations::transcript::GoldilocksPoisedon2Transcript; +use crate::boojum::cs::implementations::transcript::Transcript; +use crate::boojum::field::goldilocks::GoldilocksExt2; +use crate::boojum::field::goldilocks::GoldilocksField; +use crate::boojum::gadgets::recursion::circuit_pow::*; +use crate::boojum::gadgets::recursion::recursive_transcript::*; +use crate::boojum::gadgets::recursion::recursive_tree_hasher::CircuitGoldilocksPoseidon2Sponge; + +use crate::circuit_definitions::implementations::pow::PoWRunner; +use crate::circuit_definitions::implementations::proof::Proof; + +use crate::circuit_definitions::traits::circuit::ErasedBuilderForRecursiveVerifier; + +use crate::zkevm_circuits::boojum::cs::implementations::prover::ProofConfig; +use crate::zkevm_circuits::boojum::cs::oracle::TreeHasher; +use crate::zkevm_circuits::recursion::compression::*; +use derivative::*; + +use super::compression_modes::*; + +use super::*; + +type F = GoldilocksField; +type TR = GoldilocksPoisedon2Transcript; +type R = Poseidon2Goldilocks; +type CTR = CircuitAlgebraicSpongeBasedTranscript; +type EXT = GoldilocksExt2; +type H = GoldilocksPoseidon2Sponge; +type RH = CircuitGoldilocksPoseidon2Sponge; + +// trait to enumerate different compression modes +pub trait ProofCompressionFunction { + type PreviousLayerPoW: RecursivePoWRunner; + + type ThisLayerPoW: PoWRunner; + type ThisLayerHasher: TreeHasher< + F, + Output = >::CompatibleCap, + >; + type ThisLayerTranscript: Transcript; + + fn this_layer_transcript_parameters( + ) -> >::TransciptParameters; + + fn description_for_compression_step() -> String; + + fn size_hint_for_compression_step() -> (usize, usize); + + fn geometry_for_compression_step() -> CSGeometry; + + fn lookup_parameters_for_compression_step() -> LookupParameters; + + fn configure_builder_for_compression_step< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder>; + + fn previous_step_builder_for_compression + 'static>( + ) -> Box>; + + fn proof_config_for_compression_step() -> ProofConfig; +} + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Debug(bound = ""))] +#[serde(bound = "")] +pub struct CompressionLayerCircuit { + pub witness: Option>, + pub config: CompressionRecursionConfig, + pub transcript_params: >::TransciptParameters, + pub _marker: std::marker::PhantomData, +} + +impl crate::boojum::cs::traits::circuit::CircuitBuilder + for CompressionLayerCircuit +{ + fn geometry() -> CSGeometry { + CF::geometry_for_compression_step() + } + + fn lookup_parameters() -> LookupParameters { + CF::lookup_parameters_for_compression_step() + } + + fn configure_builder< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + CF::configure_builder_for_compression_step(builder) + } +} + +impl CompressionLayerCircuit { + pub fn description() -> String { + CF::description_for_compression_step() + } + + pub fn geometry(&self) -> CSGeometry { + CF::geometry_for_compression_step() + } + + pub fn size_hint(&self) -> (Option, Option) { + let (trace_len, max_variables) = CF::size_hint_for_compression_step(); + (Some(trace_len), Some(max_variables)) + } + + pub fn configure_builder_proxy< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + &self, + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + >::configure_builder(builder) + } + + pub fn add_tables>(&self, _cs: &mut CS) {} + + pub fn synthesize_into_cs + 'static>(self, cs: &mut CS) { + let Self { + witness, + config, + transcript_params, + .. + } = self; + + let verifier_builder = CF::previous_step_builder_for_compression::(); + let compression_witness = CompressionCircuitInstanceWitness { + proof_witness: witness, + }; + + proof_compression_function::( + cs, + compression_witness, + config, + verifier_builder, + transcript_params, + ) + } +} + +pub type CompressionMode1Circuit = CompressionLayerCircuit; +pub type CompressionMode2Circuit = CompressionLayerCircuit; +pub type CompressionMode3Circuit = CompressionLayerCircuit; +pub type CompressionMode4Circuit = CompressionLayerCircuit; +pub type CompressionMode5Circuit = CompressionLayerCircuit; + +pub type CompressionMode1ForWrapperCircuit = CompressionLayerCircuit; +pub type CompressionMode2ForWrapperCircuit = CompressionLayerCircuit; +pub type CompressionMode3ForWrapperCircuit = CompressionLayerCircuit; +pub type CompressionMode4ForWrapperCircuit = CompressionLayerCircuit; +pub type CompressionMode5ForWrapperCircuit = CompressionLayerCircuit; + +use crate::circuit_definitions::traits::circuit::CircuitBuilderProxy; + +pub type CompressionMode1CircuitBuilder = CircuitBuilderProxy; +pub type CompressionMode2CircuitBuilder = CircuitBuilderProxy; +pub type CompressionMode3CircuitBuilder = CircuitBuilderProxy; +pub type CompressionMode4CircuitBuilder = CircuitBuilderProxy; +pub type CompressionMode5CircuitBuilder = CircuitBuilderProxy; + +pub type CompressionMode1ForWrapperCircuitBuilder = + CircuitBuilderProxy; +pub type CompressionMode2ForWrapperCircuitBuilder = + CircuitBuilderProxy; +pub type CompressionMode3ForWrapperCircuitBuilder = + CircuitBuilderProxy; +pub type CompressionMode4ForWrapperCircuitBuilder = + CircuitBuilderProxy; +pub type CompressionMode5ForWrapperCircuitBuilder = + CircuitBuilderProxy; diff --git a/crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mod.rs b/crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mod.rs new file mode 100644 index 0000000..f583496 --- /dev/null +++ b/crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mod.rs @@ -0,0 +1,73 @@ +use super::*; + +use crate::boojum::algebraic_props::round_function::AbsorptionModeOverwrite; +use crate::boojum::algebraic_props::sponge::GoldilocksPoseidon2Sponge; +use crate::boojum::cs::implementations::pow::NoPow; +use crate::boojum::cs::implementations::transcript::GoldilocksPoisedon2Transcript; +use crate::boojum::cs::implementations::transcript::Transcript; +use crate::boojum::field::goldilocks::GoldilocksExt2; +use crate::boojum::field::goldilocks::GoldilocksField; + +use crate::circuit_definitions::gates::*; + +use crate::circuit_definitions::recursion_layer::scheduler::SchedulerCircuitBuilder; +use crate::circuit_definitions::traits::circuit::ErasedBuilderForRecursiveVerifier; +use crate::circuit_definitions::traits::gate::GatePlacementStrategy; + +use snark_wrapper::franklin_crypto::bellman::pairing::bn256::{Bn256, Fr}; +use snark_wrapper::implementations::poseidon2::tree_hasher::AbsorptionModeReplacement; +use snark_wrapper::rescue_poseidon::poseidon2::transcript::Poseidon2Transcript; +use snark_wrapper::rescue_poseidon::poseidon2::*; + +use crate::zkevm_circuits::boojum::cs::implementations::prover::ProofConfig; + +use crate::circuit_definitions::aux_layer::compression::ProofCompressionFunction; + +type F = GoldilocksField; +type TR = GoldilocksPoisedon2Transcript; +type R = Poseidon2Goldilocks; +type EXT = GoldilocksExt2; +type H = GoldilocksPoseidon2Sponge; + +pub type CompressionTreeHasherForWrapper = + Poseidon2Sponge, 2, 3>; +pub type CompressionTranscriptForWrapper = + Poseidon2Transcript, 2, 3>; + +// We should balance the final verification cost that would be a complex function of: +// - rate. It decreases number of queries, but increases query depth. Although in practice we +// always win, e.g. for before-extension depth 16, if we aim for 80 bits of security, and use LDE of 2^5 +// we do 16 queries of depth 21 (assuming cap at 64, it's ~240 hashes), and with LDE of 2^8 we do 10 queries +// of depth 24 (assuming cap at 64, it's 180 hashes) +// - circuit surface area. If we have circuit 2x more narrow, and 2x longer we have +1 to query depth (don't forget to +// multiply by number of queries), but we also have 2x smaller number of elements in the leaf (also mul by number of queries, so we can just compare +// one against another) +// - number of columns under copy-permutation. Every such column increases leaf size for setup by 1, and also roughly 2 columns per 8 copied columns +// in stage 2 of the proof. E.g if we have a circuit with 40 copiable + 90 non-copiable of size 2^14, and one with 48 copiable of 2^16, +// then we would have witness of 130 in leafs (17 round functions) in witness, 5 round functions from setup, 5 from stage 2 - so 27 round functions +// in leafs. For 48 x 2^16 case we have 6 round functions in leafs, 6 in setup, and 6 from stage 2 - 18 in total. For that we pay with extra depth +// in each of those oracles, so +6 more. We still marginally win, but also usually we have "simpler" gates in this case, so we have +// less terms in quotient + +pub mod mode_1; +pub mod mode_1_for_wrapper; +pub mod mode_2; +pub mod mode_2_for_wrapper; +pub mod mode_3; +pub mod mode_3_for_wrapper; +pub mod mode_4; +pub mod mode_4_for_wrapper; +pub mod mode_5; +pub mod mode_5_for_wrapper; + +pub use self::mode_1::*; +pub use self::mode_2::*; +pub use self::mode_3::*; +pub use self::mode_4::*; +pub use self::mode_5::*; + +pub use self::mode_1_for_wrapper::*; +pub use self::mode_2_for_wrapper::*; +pub use self::mode_3_for_wrapper::*; +pub use self::mode_4_for_wrapper::*; +pub use self::mode_5_for_wrapper::*; diff --git a/crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_1.rs b/crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_1.rs new file mode 100644 index 0000000..749e232 --- /dev/null +++ b/crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_1.rs @@ -0,0 +1,115 @@ +use super::*; + +pub struct CompressionMode1; + +impl ProofCompressionFunction for CompressionMode1 { + // no PoW from the previous step + type PreviousLayerPoW = NoPow; + + // no PoW on this step too + type ThisLayerPoW = NoPow; + type ThisLayerHasher = H; + type ThisLayerTranscript = TR; + + fn this_layer_transcript_parameters( + ) -> >::TransciptParameters { + (); + } + + fn description_for_compression_step() -> String { + "Compression mode 1: no lookup, just enough copiable width, moderate LDE factor, still special boolean column, and Poseidon2 gate" + .to_string() + } + + fn size_hint_for_compression_step() -> (usize, usize) { + (1 << 16, 1 << 24) + } + + fn geometry_for_compression_step() -> CSGeometry { + CSGeometry { + num_columns_under_copy_permutation: 52, + num_witness_columns: 78, + num_constant_columns: 4, + max_allowed_constraint_degree: 8, + } + } + + fn lookup_parameters_for_compression_step() -> LookupParameters { + LookupParameters::NoLookup + } + + fn configure_builder_for_compression_step< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + let builder = ConstantsAllocatorGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = BooleanConstraintGate::configure_builder( + builder, + GatePlacementStrategy::UseSpecializedColumns { + num_repetitions: 1, + share_constants: false, + }, + ); + let builder = + R::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + let builder = ZeroCheckGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + true, + ); + let builder = FmaGateInBaseFieldWithoutConstant::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = FmaGateInExtensionWithoutConstant::::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = SelectionGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ParallelSelectionGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ConditionalSwapGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = PublicInputGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ReductionGate::<_, 4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = + NopGate::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + + builder + } + + fn proof_config_for_compression_step() -> ProofConfig { + ProofConfig { + fri_lde_factor: 32, + merkle_tree_cap_size: 16, + fri_folding_schedule: None, + security_level: crate::L1_SECURITY_BITS, + pow_bits: 0, + } + } + + fn previous_step_builder_for_compression + 'static>( + ) -> Box> { + SchedulerCircuitBuilder::::dyn_recursive_verifier_builder::( + ) + } +} diff --git a/crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_1_for_wrapper.rs b/crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_1_for_wrapper.rs new file mode 100644 index 0000000..7ea09ba --- /dev/null +++ b/crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_1_for_wrapper.rs @@ -0,0 +1,115 @@ +use super::*; + +pub struct CompressionMode1ForWrapper; + +impl ProofCompressionFunction for CompressionMode1ForWrapper { + // no PoW from the previous step + type PreviousLayerPoW = NoPow; + + // no PoW on this step too + type ThisLayerPoW = NoPow; + type ThisLayerHasher = CompressionTreeHasherForWrapper; + type ThisLayerTranscript = CompressionTranscriptForWrapper; + + fn this_layer_transcript_parameters( + ) -> >::TransciptParameters { + (); + } + + fn description_for_compression_step() -> String { + "Compression mode 1: no lookup, just enough copiable width, moderate LDE factor, still special boolean column, and Poseidon2 gate" + .to_string() + } + + fn size_hint_for_compression_step() -> (usize, usize) { + (1 << 16, 1 << 24) + } + + fn geometry_for_compression_step() -> CSGeometry { + CSGeometry { + num_columns_under_copy_permutation: 52, + num_witness_columns: 78, + num_constant_columns: 4, + max_allowed_constraint_degree: 8, + } + } + + fn lookup_parameters_for_compression_step() -> LookupParameters { + LookupParameters::NoLookup + } + + fn configure_builder_for_compression_step< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + let builder = ConstantsAllocatorGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = BooleanConstraintGate::configure_builder( + builder, + GatePlacementStrategy::UseSpecializedColumns { + num_repetitions: 1, + share_constants: false, + }, + ); + let builder = + R::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + let builder = ZeroCheckGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + true, + ); + let builder = FmaGateInBaseFieldWithoutConstant::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = FmaGateInExtensionWithoutConstant::::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = SelectionGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ParallelSelectionGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ConditionalSwapGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = PublicInputGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ReductionGate::<_, 4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = + NopGate::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + + builder + } + + fn proof_config_for_compression_step() -> ProofConfig { + ProofConfig { + fri_lde_factor: 2, + merkle_tree_cap_size: 16, + fri_folding_schedule: None, + security_level: crate::L1_SECURITY_BITS, + pow_bits: 0, + } + } + + fn previous_step_builder_for_compression + 'static>( + ) -> Box> { + SchedulerCircuitBuilder::::dyn_recursive_verifier_builder::( + ) + } +} diff --git a/crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_2.rs b/crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_2.rs new file mode 100644 index 0000000..457ff1e --- /dev/null +++ b/crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_2.rs @@ -0,0 +1,118 @@ +use super::*; + +pub struct CompressionMode2; + +impl ProofCompressionFunction for CompressionMode2 { + // no PoW from the previous step + type PreviousLayerPoW = NoPow; + + // no PoW on this step too + type ThisLayerPoW = NoPow; + type ThisLayerHasher = H; + type ThisLayerTranscript = TR; + + fn this_layer_transcript_parameters( + ) -> >::TransciptParameters { + (); + } + + fn description_for_compression_step() -> String { + "Compression mode 2: no lookup, just enough copiable width, moderate-high LDE factor, Poseidon gate" + .to_string() + } + + fn size_hint_for_compression_step() -> (usize, usize) { + (1 << 13, 1 << 22) + } + + fn geometry_for_compression_step() -> CSGeometry { + CSGeometry { + num_columns_under_copy_permutation: 56, + // num_witness_columns: 0, + num_witness_columns: 74, + num_constant_columns: 4, + max_allowed_constraint_degree: 8, + } + } + + fn lookup_parameters_for_compression_step() -> LookupParameters { + LookupParameters::NoLookup + } + + fn configure_builder_for_compression_step< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + let builder = ConstantsAllocatorGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + // let builder = BooleanConstraintGate::configure_builder( + // builder, + // GatePlacementStrategy::UseGeneralPurposeColumns, + // ); + // This reduces quotient complexity + let builder = BoundedBooleanConstraintGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + 10, + ); + let builder = + R::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + let builder = ZeroCheckGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + true, + ); + let builder = FmaGateInBaseFieldWithoutConstant::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = FmaGateInExtensionWithoutConstant::::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = SelectionGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ParallelSelectionGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ConditionalSwapGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = PublicInputGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ReductionGate::<_, 4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = + NopGate::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + + builder + } + + fn proof_config_for_compression_step() -> ProofConfig { + ProofConfig { + fri_lde_factor: 512, + merkle_tree_cap_size: 16, + fri_folding_schedule: None, + security_level: crate::L1_SECURITY_BITS, + pow_bits: 0, + } + } + + fn previous_step_builder_for_compression + 'static>( + ) -> Box> { + CompressionMode1CircuitBuilder::dyn_recursive_verifier_builder::() + } +} diff --git a/crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_2_for_wrapper.rs b/crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_2_for_wrapper.rs new file mode 100644 index 0000000..bcc9d43 --- /dev/null +++ b/crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_2_for_wrapper.rs @@ -0,0 +1,117 @@ +use super::*; +pub struct CompressionMode2ForWrapper; + +impl ProofCompressionFunction for CompressionMode2ForWrapper { + // no PoW from the previous step + type PreviousLayerPoW = NoPow; + + // no PoW on this step too + type ThisLayerPoW = NoPow; + type ThisLayerHasher = CompressionTreeHasherForWrapper; + type ThisLayerTranscript = CompressionTranscriptForWrapper; + + fn this_layer_transcript_parameters( + ) -> >::TransciptParameters { + (); + } + + fn description_for_compression_step() -> String { + "Compression mode 2: no lookup, just enough copiable width, moderate-high LDE factor, Poseidon gate" + .to_string() + } + + fn size_hint_for_compression_step() -> (usize, usize) { + (1 << 13, 1 << 22) + } + + fn geometry_for_compression_step() -> CSGeometry { + CSGeometry { + num_columns_under_copy_permutation: 56, + // num_witness_columns: 0, + num_witness_columns: 74, + num_constant_columns: 4, + max_allowed_constraint_degree: 8, + } + } + + fn lookup_parameters_for_compression_step() -> LookupParameters { + LookupParameters::NoLookup + } + + fn configure_builder_for_compression_step< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + let builder = ConstantsAllocatorGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + // let builder = BooleanConstraintGate::configure_builder( + // builder, + // GatePlacementStrategy::UseGeneralPurposeColumns, + // ); + // This reduces quotient complexity + let builder = BoundedBooleanConstraintGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + 10, + ); + let builder = + R::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + let builder = ZeroCheckGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + true, + ); + let builder = FmaGateInBaseFieldWithoutConstant::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = FmaGateInExtensionWithoutConstant::::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = SelectionGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ParallelSelectionGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ConditionalSwapGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = PublicInputGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ReductionGate::<_, 4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = + NopGate::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + + builder + } + + fn proof_config_for_compression_step() -> ProofConfig { + ProofConfig { + fri_lde_factor: 512, + merkle_tree_cap_size: 16, + fri_folding_schedule: None, + security_level: crate::L1_SECURITY_BITS, + pow_bits: 0, + } + } + + fn previous_step_builder_for_compression + 'static>( + ) -> Box> { + CompressionMode1CircuitBuilder::dyn_recursive_verifier_builder::() + } +} diff --git a/crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_3.rs b/crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_3.rs new file mode 100644 index 0000000..b5ee55f --- /dev/null +++ b/crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_3.rs @@ -0,0 +1,118 @@ +use super::*; + +pub struct CompressionMode3; + +impl ProofCompressionFunction for CompressionMode3 { + // no PoW from the previous step + type PreviousLayerPoW = NoPow; + + // no PoW on this step too + type ThisLayerPoW = NoPow; + type ThisLayerHasher = H; + type ThisLayerTranscript = TR; + + fn this_layer_transcript_parameters( + ) -> >::TransciptParameters { + (); + } + + fn description_for_compression_step() -> String { + "Compression mode 3: no lookup, just enough copiable width, moderate-high LDE factor, Poseidon gate" + .to_string() + } + + fn size_hint_for_compression_step() -> (usize, usize) { + (1 << 12, 1 << 22) + } + + fn geometry_for_compression_step() -> CSGeometry { + CSGeometry { + num_columns_under_copy_permutation: 68, + // num_witness_columns: 0, + num_witness_columns: 62, + num_constant_columns: 4, + max_allowed_constraint_degree: 8, + } + } + + fn lookup_parameters_for_compression_step() -> LookupParameters { + LookupParameters::NoLookup + } + + fn configure_builder_for_compression_step< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + let builder = ConstantsAllocatorGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + // let builder = BooleanConstraintGate::configure_builder( + // builder, + // GatePlacementStrategy::UseGeneralPurposeColumns, + // ); + // This reduces quotient complexity + let builder = BoundedBooleanConstraintGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + 10, + ); + let builder = + R::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + let builder = ZeroCheckGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + true, + ); + let builder = FmaGateInBaseFieldWithoutConstant::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = FmaGateInExtensionWithoutConstant::::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = SelectionGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ParallelSelectionGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ConditionalSwapGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = PublicInputGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ReductionGate::<_, 4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = + NopGate::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + + builder + } + + fn proof_config_for_compression_step() -> ProofConfig { + ProofConfig { + fri_lde_factor: 1024, + merkle_tree_cap_size: 16, + fri_folding_schedule: None, + security_level: crate::L1_SECURITY_BITS, + pow_bits: 0, + } + } + + fn previous_step_builder_for_compression + 'static>( + ) -> Box> { + CompressionMode2CircuitBuilder::dyn_recursive_verifier_builder::() + } +} diff --git a/crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_3_for_wrapper.rs b/crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_3_for_wrapper.rs new file mode 100644 index 0000000..f7edb91 --- /dev/null +++ b/crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_3_for_wrapper.rs @@ -0,0 +1,118 @@ +use super::*; + +pub struct CompressionMode3ForWrapper; + +impl ProofCompressionFunction for CompressionMode3ForWrapper { + // no PoW from the previous step + type PreviousLayerPoW = NoPow; + + // no PoW on this step too + type ThisLayerPoW = NoPow; + type ThisLayerHasher = CompressionTreeHasherForWrapper; + type ThisLayerTranscript = CompressionTranscriptForWrapper; + + fn this_layer_transcript_parameters( + ) -> >::TransciptParameters { + (); + } + + fn description_for_compression_step() -> String { + "Compression mode 3: no lookup, just enough copiable width, moderate-high LDE factor, Poseidon gate" + .to_string() + } + + fn size_hint_for_compression_step() -> (usize, usize) { + (1 << 12, 1 << 22) + } + + fn geometry_for_compression_step() -> CSGeometry { + CSGeometry { + num_columns_under_copy_permutation: 68, + // num_witness_columns: 0, + num_witness_columns: 62, + num_constant_columns: 4, + max_allowed_constraint_degree: 8, + } + } + + fn lookup_parameters_for_compression_step() -> LookupParameters { + LookupParameters::NoLookup + } + + fn configure_builder_for_compression_step< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + let builder = ConstantsAllocatorGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + // let builder = BooleanConstraintGate::configure_builder( + // builder, + // GatePlacementStrategy::UseGeneralPurposeColumns, + // ); + // This reduces quotient complexity + let builder = BoundedBooleanConstraintGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + 10, + ); + let builder = + R::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + let builder = ZeroCheckGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + true, + ); + let builder = FmaGateInBaseFieldWithoutConstant::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = FmaGateInExtensionWithoutConstant::::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = SelectionGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ParallelSelectionGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ConditionalSwapGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = PublicInputGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ReductionGate::<_, 4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = + NopGate::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + + builder + } + + fn proof_config_for_compression_step() -> ProofConfig { + ProofConfig { + fri_lde_factor: 1024, + merkle_tree_cap_size: 16, + fri_folding_schedule: None, + security_level: crate::L1_SECURITY_BITS, + pow_bits: 0, + } + } + + fn previous_step_builder_for_compression + 'static>( + ) -> Box> { + CompressionMode2CircuitBuilder::dyn_recursive_verifier_builder::() + } +} diff --git a/crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_4.rs b/crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_4.rs new file mode 100644 index 0000000..c2ef031 --- /dev/null +++ b/crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_4.rs @@ -0,0 +1,121 @@ +use super::*; +use crate::boojum::gadgets::traits::configuration::ConfigurationFunction; + +// no lookup, just enough copiable width, moderate LDE factor, +// and matrix multiplication gate, +pub struct CompressionMode4; + +impl ProofCompressionFunction for CompressionMode4 { + // no PoW from the previous step + type PreviousLayerPoW = NoPow; + + // no PoW on this step too + type ThisLayerPoW = NoPow; + type ThisLayerHasher = H; + type ThisLayerTranscript = TR; + + fn this_layer_transcript_parameters( + ) -> >::TransciptParameters { + (); + } + + fn description_for_compression_step() -> String { + "Compression mode 4: no lookup, just enough copiable width, moderate-high LDE factor, matrix multiplication gate + non-linearity gate" + .to_string() + } + + fn size_hint_for_compression_step() -> (usize, usize) { + (1 << 15, 1 << 22) + } + + fn geometry_for_compression_step() -> CSGeometry { + CSGeometry { + num_columns_under_copy_permutation: 48, + num_witness_columns: 0, + num_constant_columns: 4, + max_allowed_constraint_degree: 8, + } + } + + fn lookup_parameters_for_compression_step() -> LookupParameters { + LookupParameters::NoLookup + } + + fn configure_builder_for_compression_step< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + let builder = ConstantsAllocatorGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + // let builder = BooleanConstraintGate::configure_builder( + // builder, + // GatePlacementStrategy::UseGeneralPurposeColumns, + // ); + // This reduces quotient complexity + let builder = BoundedBooleanConstraintGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + 10, + ); + let configuration_function = R::make_specialization_function_0(); + let builder = configuration_function + .configure_proxy(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + let builder = ZeroCheckGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + false, + ); + let builder = FmaGateInBaseFieldWithoutConstant::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = FmaGateInExtensionWithoutConstant::::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = SelectionGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ParallelSelectionGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ConditionalSwapGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = PublicInputGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ReductionGate::<_, 4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = + NopGate::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + + builder + } + + fn proof_config_for_compression_step() -> ProofConfig { + ProofConfig { + fri_lde_factor: 2048, + merkle_tree_cap_size: 256, + fri_folding_schedule: None, + security_level: crate::L1_SECURITY_BITS, + pow_bits: 0, + } + } + + fn previous_step_builder_for_compression + 'static>( + ) -> Box> { + CompressionMode3CircuitBuilder::dyn_recursive_verifier_builder::() + } +} diff --git a/crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_4_for_wrapper.rs b/crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_4_for_wrapper.rs new file mode 100644 index 0000000..0167ddf --- /dev/null +++ b/crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_4_for_wrapper.rs @@ -0,0 +1,121 @@ +use super::*; +use crate::boojum::gadgets::traits::configuration::ConfigurationFunction; + +// no lookup, just enough copiable width, moderate LDE factor, +// and matrix multiplication gate, +pub struct CompressionMode4ForWrapper; + +impl ProofCompressionFunction for CompressionMode4ForWrapper { + // no PoW from the previous step + type PreviousLayerPoW = NoPow; + + // no PoW on this step too + type ThisLayerPoW = NoPow; + type ThisLayerHasher = CompressionTreeHasherForWrapper; + type ThisLayerTranscript = CompressionTranscriptForWrapper; + + fn this_layer_transcript_parameters( + ) -> >::TransciptParameters { + (); + } + + fn description_for_compression_step() -> String { + "Compression mode 4: no lookup, just enough copiable width, moderate-high LDE factor, matrix multiplication gate + non-linearity gate" + .to_string() + } + + fn size_hint_for_compression_step() -> (usize, usize) { + (1 << 15, 1 << 22) + } + + fn geometry_for_compression_step() -> CSGeometry { + CSGeometry { + num_columns_under_copy_permutation: 48, + num_witness_columns: 0, + num_constant_columns: 4, + max_allowed_constraint_degree: 8, + } + } + + fn lookup_parameters_for_compression_step() -> LookupParameters { + LookupParameters::NoLookup + } + + fn configure_builder_for_compression_step< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + let builder = ConstantsAllocatorGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + // let builder = BooleanConstraintGate::configure_builder( + // builder, + // GatePlacementStrategy::UseGeneralPurposeColumns, + // ); + // This reduces quotient complexity + let builder = BoundedBooleanConstraintGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + 10, + ); + let configuration_function = R::make_specialization_function_0(); + let builder = configuration_function + .configure_proxy(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + let builder = ZeroCheckGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + false, + ); + let builder = FmaGateInBaseFieldWithoutConstant::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = FmaGateInExtensionWithoutConstant::::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = SelectionGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ParallelSelectionGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ConditionalSwapGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = PublicInputGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ReductionGate::<_, 4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = + NopGate::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + + builder + } + + fn proof_config_for_compression_step() -> ProofConfig { + ProofConfig { + fri_lde_factor: 2048, + merkle_tree_cap_size: 256, + fri_folding_schedule: None, + security_level: crate::L1_SECURITY_BITS, + pow_bits: 0, + } + } + + fn previous_step_builder_for_compression + 'static>( + ) -> Box> { + CompressionMode3CircuitBuilder::dyn_recursive_verifier_builder::() + } +} diff --git a/crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_5.rs b/crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_5.rs new file mode 100644 index 0000000..bb55a40 --- /dev/null +++ b/crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_5.rs @@ -0,0 +1,113 @@ +use super::*; +use crate::boojum::gadgets::traits::configuration::ConfigurationFunction; +use crate::boojum::sha3::Keccak256; +use crate::circuit_definitions::implementations::transcript::Keccak256Transcript; + +// no lookup, just enough copiable width, moderate LDE factor, +// and matrix multiplication gate, +pub struct CompressionMode5; + +impl ProofCompressionFunction for CompressionMode5 { + // no PoW from the previous step + type PreviousLayerPoW = NoPow; + + // no PoW on this step too + type ThisLayerPoW = Keccak256; + type ThisLayerHasher = Keccak256; + type ThisLayerTranscript = Keccak256Transcript; + + fn this_layer_transcript_parameters( + ) -> >::TransciptParameters { + (); + } + + fn description_for_compression_step() -> String { + "Compression mode to L1: no lookup, just enough copiable width, large LDE factor, PoW" + .to_string() + } + + fn size_hint_for_compression_step() -> (usize, usize) { + (1 << 18, 1 << 22) + } + + fn geometry_for_compression_step() -> CSGeometry { + CSGeometry { + num_columns_under_copy_permutation: 28, + num_witness_columns: 0, + num_constant_columns: 4, + max_allowed_constraint_degree: 4, + } + } + + fn lookup_parameters_for_compression_step() -> LookupParameters { + LookupParameters::NoLookup + } + + fn configure_builder_for_compression_step< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + let builder = ConstantsAllocatorGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = BooleanConstraintGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let configuration_function = R::make_specialization_function_0(); + let builder = configuration_function + .configure_proxy(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + let builder = ZeroCheckGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + false, + ); + let builder = FmaGateInBaseFieldWithoutConstant::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = FmaGateInExtensionWithoutConstant::::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = SelectionGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ParallelSelectionGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = PublicInputGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ReductionGate::<_, 4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = + NopGate::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + + builder + } + + fn proof_config_for_compression_step() -> ProofConfig { + ProofConfig { + fri_lde_factor: 4096, + merkle_tree_cap_size: 8, + fri_folding_schedule: None, + security_level: crate::L1_SECURITY_BITS, + pow_bits: 28, + } + } + + fn previous_step_builder_for_compression + 'static>( + ) -> Box> { + CompressionMode4CircuitBuilder::dyn_recursive_verifier_builder::() + } +} diff --git a/crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_5_for_wrapper.rs b/crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_5_for_wrapper.rs new file mode 100644 index 0000000..31b512e --- /dev/null +++ b/crates/circuit_definitions/src/circuit_definitions/aux_layer/compression_modes/mode_5_for_wrapper.rs @@ -0,0 +1,111 @@ +use super::*; +use crate::boojum::gadgets::traits::configuration::ConfigurationFunction; + +// no lookup, just enough copiable width, moderate LDE factor, +// and matrix multiplication gate, +pub struct CompressionMode5ForWrapper; + +impl ProofCompressionFunction for CompressionMode5ForWrapper { + // no PoW from the previous step + type PreviousLayerPoW = NoPow; + + // no PoW on this step too + type ThisLayerPoW = NoPow; + type ThisLayerHasher = CompressionTreeHasherForWrapper; + type ThisLayerTranscript = CompressionTranscriptForWrapper; + + fn this_layer_transcript_parameters( + ) -> >::TransciptParameters { + (); + } + + fn description_for_compression_step() -> String { + "Compression mode to L1: no lookup, just enough copiable width, large LDE factor, PoW" + .to_string() + } + + fn size_hint_for_compression_step() -> (usize, usize) { + (1 << 18, 1 << 22) + } + + fn geometry_for_compression_step() -> CSGeometry { + CSGeometry { + num_columns_under_copy_permutation: 28, + num_witness_columns: 0, + num_constant_columns: 4, + max_allowed_constraint_degree: 4, + } + } + + fn lookup_parameters_for_compression_step() -> LookupParameters { + LookupParameters::NoLookup + } + + fn configure_builder_for_compression_step< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + let builder = ConstantsAllocatorGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = BooleanConstraintGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let configuration_function = R::make_specialization_function_0(); + let builder = configuration_function + .configure_proxy(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + let builder = ZeroCheckGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + false, + ); + let builder = FmaGateInBaseFieldWithoutConstant::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = FmaGateInExtensionWithoutConstant::::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = SelectionGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ParallelSelectionGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = PublicInputGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ReductionGate::<_, 4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = + NopGate::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + + builder + } + + fn proof_config_for_compression_step() -> ProofConfig { + ProofConfig { + fri_lde_factor: 4096, + merkle_tree_cap_size: 8, + fri_folding_schedule: None, + security_level: crate::L1_SECURITY_BITS, + pow_bits: 0, + } + } + + fn previous_step_builder_for_compression + 'static>( + ) -> Box> { + CompressionMode4CircuitBuilder::dyn_recursive_verifier_builder::() + } +} diff --git a/crates/circuit_definitions/src/circuit_definitions/aux_layer/mod.rs b/crates/circuit_definitions/src/circuit_definitions/aux_layer/mod.rs new file mode 100644 index 0000000..3556ff4 --- /dev/null +++ b/crates/circuit_definitions/src/circuit_definitions/aux_layer/mod.rs @@ -0,0 +1,669 @@ +use super::*; + +pub mod compression; +pub mod compression_modes; +pub mod wrapper; + +use crate::boojum::config::ProvingCSConfig; +use crate::boojum::field::traits::field_like::PrimeFieldLikeVectorized; +use crate::circuit_definitions::aux_layer::compression::*; +use crate::circuit_definitions::aux_layer::compression_modes::*; +use crate::circuit_definitions::cs_builder_reference::CsReferenceImplementationBuilder; +use crate::circuit_definitions::implementations::reference_cs::CSReferenceAssembly; + +use crate::recursion_layer_proof_config; +use crate::zkevm_circuits::recursion::compression::CompressionRecursionConfig; +use snark_wrapper::boojum::config::CSConfig; +use snark_wrapper::boojum::dag::CircuitResolver; +use snark_wrapper::boojum::dag::StCircuitResolver; + +use crate::ProofConfig; + +type F = GoldilocksField; +type EXT = GoldilocksExt2; +type H = GoldilocksPoseidon2Sponge; + +#[derive(derivative::Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone(bound = ""))] +#[serde(bound = "")] +pub enum ZkSyncCompressionLayerCircuit { + CompressionMode1Circuit(CompressionMode1Circuit), + CompressionMode2Circuit(CompressionMode2Circuit), + CompressionMode3Circuit(CompressionMode3Circuit), + CompressionMode4Circuit(CompressionMode4Circuit), + CompressionMode5Circuit(CompressionMode5Circuit), +} + +#[derive(derivative::Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone(bound = ""), Copy, Debug)] +#[serde(bound = "")] +#[repr(u8)] +pub enum ZkSyncCompressionLayerStorageType { + CompressionMode1Circuit = 1, + CompressionMode2Circuit = 2, + CompressionMode3Circuit = 3, + CompressionMode4Circuit = 4, + CompressionMode5Circuit = 5, +} + +impl ZkSyncCompressionLayerCircuit { + pub fn short_description(&self) -> &'static str { + match &self { + Self::CompressionMode1Circuit(..) => "Compression mode 1", + Self::CompressionMode2Circuit(..) => "Compression mode 2", + Self::CompressionMode3Circuit(..) => "Compression mode 3", + Self::CompressionMode4Circuit(..) => "Compression mode 4", + Self::CompressionMode5Circuit(..) => "Compression mode 5", + } + } + + pub fn numeric_circuit_type(&self) -> u8 { + match &self { + Self::CompressionMode1Circuit(..) => { + ZkSyncCompressionLayerStorageType::CompressionMode1Circuit as u8 + } + Self::CompressionMode2Circuit(..) => { + ZkSyncCompressionLayerStorageType::CompressionMode2Circuit as u8 + } + Self::CompressionMode3Circuit(..) => { + ZkSyncCompressionLayerStorageType::CompressionMode3Circuit as u8 + } + Self::CompressionMode4Circuit(..) => { + ZkSyncCompressionLayerStorageType::CompressionMode4Circuit as u8 + } + Self::CompressionMode5Circuit(..) => { + ZkSyncCompressionLayerStorageType::CompressionMode5Circuit as u8 + } + } + } + + pub fn size_hint(&self) -> (Option, Option) { + match &self { + Self::CompressionMode1Circuit(inner) => inner.size_hint(), + Self::CompressionMode2Circuit(inner) => inner.size_hint(), + Self::CompressionMode3Circuit(inner) => inner.size_hint(), + Self::CompressionMode4Circuit(inner) => inner.size_hint(), + Self::CompressionMode5Circuit(inner) => inner.size_hint(), + } + } + + pub fn geometry(&self) -> CSGeometry { + use crate::boojum::cs::traits::circuit::CircuitBuilder; + match &self { + Self::CompressionMode1Circuit(..) => { + >::geometry() + } + Self::CompressionMode2Circuit(..) => { + >::geometry() + } + Self::CompressionMode3Circuit(..) => { + >::geometry() + } + Self::CompressionMode4Circuit(..) => { + >::geometry() + } + Self::CompressionMode5Circuit(..) => { + >::geometry() + } + } + } + + pub fn proof_config_for_compression_step(&self) -> ProofConfig { + match &self { + Self::CompressionMode1Circuit(..) => { + CompressionMode1::proof_config_for_compression_step() + } + Self::CompressionMode2Circuit(..) => { + CompressionMode2::proof_config_for_compression_step() + } + Self::CompressionMode3Circuit(..) => { + CompressionMode3::proof_config_for_compression_step() + } + Self::CompressionMode4Circuit(..) => { + CompressionMode4::proof_config_for_compression_step() + } + Self::CompressionMode5Circuit(..) => { + CompressionMode5::proof_config_for_compression_step() + } + } + } + + pub fn verification_key(&self) -> VerificationKey { + match &self { + Self::CompressionMode1Circuit(inner) => inner.config.verification_key.clone(), + Self::CompressionMode2Circuit(inner) => inner.config.verification_key.clone(), + Self::CompressionMode3Circuit(inner) => inner.config.verification_key.clone(), + Self::CompressionMode4Circuit(inner) => inner.config.verification_key.clone(), + Self::CompressionMode5Circuit(inner) => inner.config.verification_key.clone(), + } + } + + fn synthesis_inner( + inner: &CompressionLayerCircuit, + hint: &FinalizationHintsForProver, + ) -> CSReferenceAssembly + where + P: PrimeFieldLikeVectorized, + CF: ProofCompressionFunction, + CR: CircuitResolver< + F, + crate::boojum::config::Resolver, + >, + usize: Into<::ResolverConfig>>::Arg>, + { + let geometry = inner.geometry(); + let (max_trace_len, num_vars) = inner.size_hint(); + let builder_impl = + CsReferenceImplementationBuilder::::new( + geometry, + max_trace_len.unwrap(), + ); + let cs_builder = new_builder::<_, GoldilocksField>(builder_impl); + let builder = inner.configure_builder_proxy(cs_builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables(&mut cs); + inner.clone().synthesize_into_cs(&mut cs); + cs.pad_and_shrink_using_hint(hint); + cs.into_assembly() + } + + pub fn synthesis>( + &self, + hint: &FinalizationHintsForProver, + ) -> CSReferenceAssembly { + self.synthesis_wrapped::< + P, + StCircuitResolver::ResolverConfig> + >(hint) + } + + pub fn synthesis_wrapped( + &self, + hint: &FinalizationHintsForProver, + ) -> CSReferenceAssembly + where + P: PrimeFieldLikeVectorized, + CR: CircuitResolver< + F, + crate::boojum::config::Resolver, + >, + usize: Into<::ResolverConfig>>::Arg>, + { + match &self { + Self::CompressionMode1Circuit(inner) => Self::synthesis_inner::<_, _, CR>(inner, hint), + Self::CompressionMode2Circuit(inner) => Self::synthesis_inner::<_, _, CR>(inner, hint), + Self::CompressionMode3Circuit(inner) => Self::synthesis_inner::<_, _, CR>(inner, hint), + Self::CompressionMode4Circuit(inner) => Self::synthesis_inner::<_, _, CR>(inner, hint), + Self::CompressionMode5Circuit(inner) => Self::synthesis_inner::<_, _, CR>(inner, hint), + } + } + + pub fn into_dyn_verifier_builder( + &self, + ) -> Box> { + match &self { + Self::CompressionMode1Circuit(..) => { + CompressionMode1ForWrapperCircuitBuilder::dyn_verifier_builder() + } + Self::CompressionMode2Circuit(..) => { + CompressionMode2ForWrapperCircuitBuilder::dyn_verifier_builder() + } + Self::CompressionMode3Circuit(..) => { + CompressionMode3ForWrapperCircuitBuilder::dyn_verifier_builder() + } + Self::CompressionMode4Circuit(..) => { + CompressionMode4ForWrapperCircuitBuilder::dyn_verifier_builder() + } + Self::CompressionMode5Circuit(..) => { + CompressionMode5ForWrapperCircuitBuilder::dyn_verifier_builder() + } + } + } + + pub fn from_witness_and_vk( + witness: Option>, + vk: VerificationKey, + circuit_type: u8, + ) -> Self { + match circuit_type { + 1 => Self::CompressionMode1Circuit(CompressionMode1Circuit { + witness, + config: CompressionRecursionConfig { + proof_config: recursion_layer_proof_config(), + verification_key: vk, + _marker: std::marker::PhantomData, + }, + transcript_params: (), + _marker: std::marker::PhantomData, + }), + 2 => Self::CompressionMode2Circuit(CompressionMode2Circuit { + witness, + config: CompressionRecursionConfig { + proof_config: CompressionMode1::proof_config_for_compression_step(), + verification_key: vk, + _marker: std::marker::PhantomData, + }, + transcript_params: (), + _marker: std::marker::PhantomData, + }), + 3 => Self::CompressionMode3Circuit(CompressionMode3Circuit { + witness, + config: CompressionRecursionConfig { + proof_config: CompressionMode2::proof_config_for_compression_step(), + verification_key: vk, + _marker: std::marker::PhantomData, + }, + transcript_params: (), + _marker: std::marker::PhantomData, + }), + 4 => Self::CompressionMode4Circuit(CompressionMode4Circuit { + witness, + config: CompressionRecursionConfig { + proof_config: CompressionMode3::proof_config_for_compression_step(), + verification_key: vk, + _marker: std::marker::PhantomData, + }, + transcript_params: (), + _marker: std::marker::PhantomData, + }), + 5 => Self::CompressionMode5Circuit(CompressionMode5Circuit { + witness, + config: CompressionRecursionConfig { + proof_config: CompressionMode4::proof_config_for_compression_step(), + verification_key: vk, + _marker: std::marker::PhantomData, + }, + transcript_params: (), + _marker: std::marker::PhantomData, + }), + _ => panic!("wrong circuit_type for compression layer: {}", circuit_type), + } + } + + pub fn clone_without_witness(&self) -> Self { + let circuit_type = self.numeric_circuit_type(); + let vk = self.verification_key(); + Self::from_witness_and_vk(None, vk, circuit_type) + } +} + +#[derive(derivative::Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone(bound = ""), Debug)] +#[serde(bound = "")] +#[repr(u8)] +pub enum ZkSyncCompressionLayerStorage< + T: Clone + std::fmt::Debug + serde::Serialize + serde::de::DeserializeOwned, +> { + CompressionMode1Circuit(T) = 1, + CompressionMode2Circuit(T) = 2, + CompressionMode3Circuit(T) = 3, + CompressionMode4Circuit(T) = 4, + CompressionMode5Circuit(T) = 5, +} + +impl + ZkSyncCompressionLayerStorage +{ + pub fn short_description(&self) -> &'static str { + match &self { + ZkSyncCompressionLayerStorage::CompressionMode1Circuit(..) => "Compression mode 1", + ZkSyncCompressionLayerStorage::CompressionMode2Circuit(..) => "Compression mode 2", + ZkSyncCompressionLayerStorage::CompressionMode3Circuit(..) => "Compression mode 3", + ZkSyncCompressionLayerStorage::CompressionMode4Circuit(..) => "Compression mode 4", + ZkSyncCompressionLayerStorage::CompressionMode5Circuit(..) => "Compression mode 5", + } + } + + pub fn numeric_circuit_type(&self) -> u8 { + match &self { + ZkSyncCompressionLayerStorage::CompressionMode1Circuit(..) => { + ZkSyncCompressionLayerStorageType::CompressionMode1Circuit as u8 + } + ZkSyncCompressionLayerStorage::CompressionMode2Circuit(..) => { + ZkSyncCompressionLayerStorageType::CompressionMode2Circuit as u8 + } + ZkSyncCompressionLayerStorage::CompressionMode3Circuit(..) => { + ZkSyncCompressionLayerStorageType::CompressionMode3Circuit as u8 + } + ZkSyncCompressionLayerStorage::CompressionMode4Circuit(..) => { + ZkSyncCompressionLayerStorageType::CompressionMode4Circuit as u8 + } + ZkSyncCompressionLayerStorage::CompressionMode5Circuit(..) => { + ZkSyncCompressionLayerStorageType::CompressionMode5Circuit as u8 + } + } + } + + pub fn into_inner(self) -> T { + match self { + Self::CompressionMode1Circuit(inner) => inner, + Self::CompressionMode2Circuit(inner) => inner, + Self::CompressionMode3Circuit(inner) => inner, + Self::CompressionMode4Circuit(inner) => inner, + Self::CompressionMode5Circuit(inner) => inner, + } + } + + pub fn from_inner(numeric_type: u8, inner: T) -> Self { + match numeric_type { + a if a == ZkSyncCompressionLayerStorageType::CompressionMode1Circuit as u8 => { + Self::CompressionMode1Circuit(inner) + } + a if a == ZkSyncCompressionLayerStorageType::CompressionMode2Circuit as u8 => { + Self::CompressionMode2Circuit(inner) + } + a if a == ZkSyncCompressionLayerStorageType::CompressionMode3Circuit as u8 => { + Self::CompressionMode3Circuit(inner) + } + a if a == ZkSyncCompressionLayerStorageType::CompressionMode4Circuit as u8 => { + Self::CompressionMode4Circuit(inner) + } + a if a == ZkSyncCompressionLayerStorageType::CompressionMode5Circuit as u8 => { + Self::CompressionMode5Circuit(inner) + } + _ => panic!("wrong numeric_type for inner: {}", numeric_type), + } + } +} + +#[derive(derivative::Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone(bound = ""))] +#[serde(bound = "")] +pub enum ZkSyncCompressionForWrapperCircuit { + CompressionMode1Circuit(CompressionMode1ForWrapperCircuit), + CompressionMode2Circuit(CompressionMode2ForWrapperCircuit), + CompressionMode3Circuit(CompressionMode3ForWrapperCircuit), + CompressionMode4Circuit(CompressionMode4ForWrapperCircuit), + CompressionMode5Circuit(CompressionMode5ForWrapperCircuit), +} + +impl ZkSyncCompressionForWrapperCircuit { + pub fn short_description(&self) -> &'static str { + match &self { + Self::CompressionMode1Circuit(..) => "Compression mode 1 for wrapper", + Self::CompressionMode2Circuit(..) => "Compression mode 2 for wrapper", + Self::CompressionMode3Circuit(..) => "Compression mode 3 for wrapper", + Self::CompressionMode4Circuit(..) => "Compression mode 4 for wrapper", + Self::CompressionMode5Circuit(..) => "Compression mode 5 for wrapper", + } + } + + pub fn numeric_circuit_type(&self) -> u8 { + match &self { + Self::CompressionMode1Circuit(..) => { + ZkSyncCompressionLayerStorageType::CompressionMode1Circuit as u8 + } + Self::CompressionMode2Circuit(..) => { + ZkSyncCompressionLayerStorageType::CompressionMode2Circuit as u8 + } + Self::CompressionMode3Circuit(..) => { + ZkSyncCompressionLayerStorageType::CompressionMode3Circuit as u8 + } + Self::CompressionMode4Circuit(..) => { + ZkSyncCompressionLayerStorageType::CompressionMode4Circuit as u8 + } + Self::CompressionMode5Circuit(..) => { + ZkSyncCompressionLayerStorageType::CompressionMode5Circuit as u8 + } + } + } + + pub fn size_hint(&self) -> (Option, Option) { + match &self { + Self::CompressionMode1Circuit(inner) => inner.size_hint(), + Self::CompressionMode2Circuit(inner) => inner.size_hint(), + Self::CompressionMode3Circuit(inner) => inner.size_hint(), + Self::CompressionMode4Circuit(inner) => inner.size_hint(), + Self::CompressionMode5Circuit(inner) => inner.size_hint(), + } + } + + pub fn geometry(&self) -> CSGeometry { + use crate::boojum::cs::traits::circuit::CircuitBuilder; + match &self { + Self::CompressionMode1Circuit(..) => { + >::geometry() + } + Self::CompressionMode2Circuit(..) => { + >::geometry() + } + Self::CompressionMode3Circuit(..) => { + >::geometry() + } + Self::CompressionMode4Circuit(..) => { + >::geometry() + } + Self::CompressionMode5Circuit(..) => { + >::geometry() + } + } + } + + pub fn proof_config_for_compression_step(&self) -> ProofConfig { + match &self { + Self::CompressionMode1Circuit(..) => { + CompressionMode1ForWrapper::proof_config_for_compression_step() + } + Self::CompressionMode2Circuit(..) => { + CompressionMode2ForWrapper::proof_config_for_compression_step() + } + Self::CompressionMode3Circuit(..) => { + CompressionMode3ForWrapper::proof_config_for_compression_step() + } + Self::CompressionMode4Circuit(..) => { + CompressionMode4ForWrapper::proof_config_for_compression_step() + } + Self::CompressionMode5Circuit(..) => { + CompressionMode5ForWrapper::proof_config_for_compression_step() + } + } + } + + pub fn verification_key(&self) -> VerificationKey { + match &self { + Self::CompressionMode1Circuit(inner) => inner.config.verification_key.clone(), + Self::CompressionMode2Circuit(inner) => inner.config.verification_key.clone(), + Self::CompressionMode3Circuit(inner) => inner.config.verification_key.clone(), + Self::CompressionMode4Circuit(inner) => inner.config.verification_key.clone(), + Self::CompressionMode5Circuit(inner) => inner.config.verification_key.clone(), + } + } + + fn synthesis_inner< + P: PrimeFieldLikeVectorized, + CF: ProofCompressionFunction, + >( + inner: &CompressionLayerCircuit, + hint: &FinalizationHintsForProver, + ) -> CSReferenceAssembly { + let geometry = inner.geometry(); + let (max_trace_len, num_vars) = inner.size_hint(); + let builder_impl = + CsReferenceImplementationBuilder::::new( + geometry, + max_trace_len.unwrap(), + ); + let cs_builder = new_builder::<_, GoldilocksField>(builder_impl); + let builder = inner.configure_builder_proxy(cs_builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables(&mut cs); + inner.clone().synthesize_into_cs(&mut cs); + cs.pad_and_shrink_using_hint(hint); + cs.into_assembly() + } + + pub fn synthesis>( + &self, + hint: &FinalizationHintsForProver, + ) -> CSReferenceAssembly { + match &self { + Self::CompressionMode1Circuit(inner) => Self::synthesis_inner(inner, hint), + Self::CompressionMode2Circuit(inner) => Self::synthesis_inner(inner, hint), + Self::CompressionMode3Circuit(inner) => Self::synthesis_inner(inner, hint), + Self::CompressionMode4Circuit(inner) => Self::synthesis_inner(inner, hint), + Self::CompressionMode5Circuit(inner) => Self::synthesis_inner(inner, hint), + } + } + + pub fn into_dyn_verifier_builder( + &self, + ) -> Box> { + match &self { + Self::CompressionMode1Circuit(..) => { + CompressionMode1ForWrapperCircuitBuilder::dyn_verifier_builder() + } + Self::CompressionMode2Circuit(..) => { + CompressionMode2ForWrapperCircuitBuilder::dyn_verifier_builder() + } + Self::CompressionMode3Circuit(..) => { + CompressionMode3ForWrapperCircuitBuilder::dyn_verifier_builder() + } + Self::CompressionMode4Circuit(..) => { + CompressionMode4ForWrapperCircuitBuilder::dyn_verifier_builder() + } + Self::CompressionMode5Circuit(..) => { + CompressionMode5ForWrapperCircuitBuilder::dyn_verifier_builder() + } + } + } + + pub fn from_witness_and_vk( + witness: Option>, + vk: VerificationKey, + circuit_type: u8, + ) -> Self { + match circuit_type { + 1 => Self::CompressionMode1Circuit(CompressionMode1ForWrapperCircuit { + witness, + config: CompressionRecursionConfig { + proof_config: recursion_layer_proof_config(), + verification_key: vk, + _marker: std::marker::PhantomData, + }, + transcript_params: (), + _marker: std::marker::PhantomData, + }), + 2 => Self::CompressionMode2Circuit(CompressionMode2ForWrapperCircuit { + witness, + config: CompressionRecursionConfig { + proof_config: CompressionMode1::proof_config_for_compression_step(), + verification_key: vk, + _marker: std::marker::PhantomData, + }, + transcript_params: (), + _marker: std::marker::PhantomData, + }), + 3 => Self::CompressionMode3Circuit(CompressionMode3ForWrapperCircuit { + witness, + config: CompressionRecursionConfig { + proof_config: CompressionMode2::proof_config_for_compression_step(), + verification_key: vk, + _marker: std::marker::PhantomData, + }, + transcript_params: (), + _marker: std::marker::PhantomData, + }), + 4 => Self::CompressionMode4Circuit(CompressionMode4ForWrapperCircuit { + witness, + config: CompressionRecursionConfig { + proof_config: CompressionMode3::proof_config_for_compression_step(), + verification_key: vk, + _marker: std::marker::PhantomData, + }, + transcript_params: (), + _marker: std::marker::PhantomData, + }), + 5 => Self::CompressionMode5Circuit(CompressionMode5ForWrapperCircuit { + witness, + config: CompressionRecursionConfig { + proof_config: CompressionMode4::proof_config_for_compression_step(), + verification_key: vk, + _marker: std::marker::PhantomData, + }, + transcript_params: (), + _marker: std::marker::PhantomData, + }), + _ => panic!("wrong circuit_type for compression layer: {}", circuit_type), + } + } + + pub fn clone_without_witness(&self) -> Self { + let circuit_type = self.numeric_circuit_type(); + let vk = self.verification_key(); + Self::from_witness_and_vk(None, vk, circuit_type) + } +} + +pub type ZkSyncCompressionLayerCircuitInput = + ZkSyncCompressionLayerStorage<[F; INPUT_OUTPUT_COMMITMENT_LENGTH]>; + +use crate::zkevm_circuits::fsm_input_output::ClosedFormInputCompactFormWitness; + +pub type ZkSyncCompressionLayerClosedFormInput = + ZkSyncCompressionLayerStorage>; + +use crate::boojum::algebraic_props::round_function::AbsorptionModeOverwrite; +use crate::boojum::algebraic_props::sponge::GoldilocksPoseidon2Sponge; +use crate::boojum::field::goldilocks::{GoldilocksExt2, GoldilocksField}; +use crate::circuit_definitions::implementations::proof::Proof; +use crate::circuit_definitions::implementations::setup::FinalizationHintsForProver; + +use snark_wrapper::franklin_crypto::bellman::pairing::bn256::{Bn256, Fr}; +use snark_wrapper::implementations::poseidon2::tree_hasher::AbsorptionModeReplacement; +use snark_wrapper::rescue_poseidon::poseidon2::Poseidon2Sponge; + +pub type CompressionProofsTreeHasher = GoldilocksPoseidon2Sponge; +pub type CompressionProofsTreeHasherForWrapper = + Poseidon2Sponge, 2, 3>; +pub type ZkSyncCompressionProof = + Proof; +pub type ZkSyncCompressionProofForWrapper = + Proof; + +pub type ZkSyncCompressionLayerProof = ZkSyncCompressionLayerStorage; +pub type ZkSyncCompressionForWrapperProof = + ZkSyncCompressionLayerStorage; + +pub type ZkSyncCompressionLayerFinalizationHint = + ZkSyncCompressionLayerStorage; +pub type ZkSyncCompressionForWrapperFinalizationHint = + ZkSyncCompressionLayerStorage; + +use crate::boojum::cs::implementations::verifier::VerificationKey; +pub type ZkSyncCompressionVerificationKey = + VerificationKey; +pub type ZkSyncCompressionVerificationKeyForWrapper = + VerificationKey; + +pub type ZkSyncCompressionLayerVerificationKey = + ZkSyncCompressionLayerStorage; + +pub type ZkSyncCompressionForWrapperVerificationKey = + ZkSyncCompressionLayerStorage; + +use crate::circuit_definitions::aux_layer::wrapper::ZkSyncCompressionWrapper; +use snark_wrapper::franklin_crypto::bellman::plonk::better_better_cs::proof::Proof as SnarkProof; +use snark_wrapper::franklin_crypto::bellman::plonk::better_better_cs::setup::Setup as SnarkSetup; +use snark_wrapper::franklin_crypto::bellman::plonk::better_better_cs::setup::VerificationKey as SnarkVK; +use snark_wrapper::implementations::poseidon2::transcript::CircuitPoseidon2Transcript; +use snark_wrapper::implementations::poseidon2::CircuitPoseidon2Sponge; +use snark_wrapper::verifier::WrapperCircuit; + +pub type ZkSyncSnarkWrapperCircuit = WrapperCircuit< + Bn256, + Poseidon2Sponge, 2, 3>, + CircuitPoseidon2Sponge, + CircuitPoseidon2Transcript, + ZkSyncCompressionWrapper, +>; + +use std::sync::Arc; +pub type ZkSyncSnarkWrapperProof = + ZkSyncCompressionLayerStorage>; +pub type ZkSyncSnarkWrapperSetup = + ZkSyncCompressionLayerStorage>>; +pub type ZkSyncSnarkWrapperVK = + ZkSyncCompressionLayerStorage>; + +pub type EIP4844VerificationKey = + VerificationKey>; diff --git a/crates/circuit_definitions/src/circuit_definitions/aux_layer/wrapper.rs b/crates/circuit_definitions/src/circuit_definitions/aux_layer/wrapper.rs new file mode 100644 index 0000000..6a17fe3 --- /dev/null +++ b/crates/circuit_definitions/src/circuit_definitions/aux_layer/wrapper.rs @@ -0,0 +1,105 @@ +use super::*; + +use crate::circuit_definitions::aux_layer::compression_modes::*; +use snark_wrapper::franklin_crypto::bellman::pairing::Engine; +use snark_wrapper::franklin_crypto::bellman::plonk::better_better_cs::cs::ConstraintSystem as SnarkConstraintSystem; +use snark_wrapper::traits::circuit::ErasedBuilderForWrapperVerifier; +use snark_wrapper::traits::circuit::ProofWrapperFunction; + +use crate::ProofConfig; + +#[derive(Clone, PartialEq, Eq, Debug)] +pub enum ZkSyncCompressionWrapper { + CompressionMode1Circuit, + CompressionMode2Circuit, + CompressionMode3Circuit, + CompressionMode4Circuit, + CompressionMode5Circuit, +} + +impl ZkSyncCompressionWrapper { + pub fn from_numeric_circuit_type(num_type: u8) -> Self { + match num_type { + a if a == ZkSyncCompressionLayerStorageType::CompressionMode1Circuit as u8 => { + Self::CompressionMode1Circuit + } + a if a == ZkSyncCompressionLayerStorageType::CompressionMode2Circuit as u8 => { + Self::CompressionMode2Circuit + } + a if a == ZkSyncCompressionLayerStorageType::CompressionMode3Circuit as u8 => { + Self::CompressionMode3Circuit + } + a if a == ZkSyncCompressionLayerStorageType::CompressionMode4Circuit as u8 => { + Self::CompressionMode4Circuit + } + a if a == ZkSyncCompressionLayerStorageType::CompressionMode5Circuit as u8 => { + Self::CompressionMode5Circuit + } + a => panic!("Unknown numeric circuit type: {}", a), + } + } + + pub fn numeric_circuit_type(&self) -> u8 { + match &self { + Self::CompressionMode1Circuit => { + ZkSyncCompressionLayerStorageType::CompressionMode1Circuit as u8 + } + Self::CompressionMode2Circuit => { + ZkSyncCompressionLayerStorageType::CompressionMode2Circuit as u8 + } + Self::CompressionMode3Circuit => { + ZkSyncCompressionLayerStorageType::CompressionMode3Circuit as u8 + } + Self::CompressionMode4Circuit => { + ZkSyncCompressionLayerStorageType::CompressionMode4Circuit as u8 + } + Self::CompressionMode5Circuit => { + ZkSyncCompressionLayerStorageType::CompressionMode5Circuit as u8 + } + } + } +} + +impl ProofWrapperFunction for ZkSyncCompressionWrapper { + fn builder_for_wrapper + 'static>( + &self, + ) -> Box> { + match &self { + Self::CompressionMode1Circuit => { + Box::new(CompressionMode1ForWrapperCircuitBuilder::default()) + } + Self::CompressionMode2Circuit => { + Box::new(CompressionMode2ForWrapperCircuitBuilder::default()) + } + Self::CompressionMode3Circuit => { + Box::new(CompressionMode3ForWrapperCircuitBuilder::default()) + } + Self::CompressionMode4Circuit => { + Box::new(CompressionMode4ForWrapperCircuitBuilder::default()) + } + Self::CompressionMode5Circuit => { + Box::new(CompressionMode5ForWrapperCircuitBuilder::default()) + } + } + } + + fn proof_config_for_compression_step(&self) -> ProofConfig { + match &self { + Self::CompressionMode1Circuit => { + CompressionMode1ForWrapper::proof_config_for_compression_step() + } + Self::CompressionMode2Circuit => { + CompressionMode2ForWrapper::proof_config_for_compression_step() + } + Self::CompressionMode3Circuit => { + CompressionMode3ForWrapper::proof_config_for_compression_step() + } + Self::CompressionMode4Circuit => { + CompressionMode4ForWrapper::proof_config_for_compression_step() + } + Self::CompressionMode5Circuit => { + CompressionMode5ForWrapper::proof_config_for_compression_step() + } + } + } +} diff --git a/crates/circuit_definitions/src/circuit_definitions/base_layer/code_decommitter.rs b/crates/circuit_definitions/src/circuit_definitions/base_layer/code_decommitter.rs new file mode 100644 index 0000000..a117f60 --- /dev/null +++ b/crates/circuit_definitions/src/circuit_definitions/base_layer/code_decommitter.rs @@ -0,0 +1,149 @@ +use derivative::*; + +use super::*; +use crate::boojum::cs::traits::circuit::CircuitBuilder; + +type F = GoldilocksField; +type R = Poseidon2Goldilocks; + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Copy, Debug, Default(bound = ""))] +pub struct CodeDecommitterInstanceSynthesisFunction { + _marker: std::marker::PhantomData<(F, R)>, +} + +use crate::zkevm_circuits::code_unpacker_sha256::input::*; +use crate::zkevm_circuits::code_unpacker_sha256::unpack_code_into_memory_entry_point; + +impl CircuitBuilder for CodeDecommitterInstanceSynthesisFunction +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + fn geometry() -> CSGeometry { + CSGeometry { + num_columns_under_copy_permutation: 108, + num_witness_columns: 0, + num_constant_columns: 4, + max_allowed_constraint_degree: 8, + } + } + + fn lookup_parameters() -> LookupParameters { + LookupParameters::UseSpecializedColumnsWithTableIdAsConstant { + width: 4, + num_repetitions: 11, + share_table_id: true, + } + } + + fn configure_builder< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + let builder = builder.allow_lookup(>::lookup_parameters()); + + let builder = ConstantsAllocatorGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = BooleanConstraintGate::configure_builder( + builder, + GatePlacementStrategy::UseSpecializedColumns { + num_repetitions: 1, + share_constants: false, + }, + ); + let builder = FmaGateInBaseFieldWithoutConstant::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ReductionGate::::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = SelectionGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ParallelSelectionGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = PublicInputGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<32>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<16>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ZeroCheckGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + false, + ); + + let builder = + NopGate::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + + builder + } +} + +impl ZkSyncUniformSynthesisFunction for CodeDecommitterInstanceSynthesisFunction +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + type Witness = CodeDecommitterCircuitInstanceWitness; + type Config = usize; + type RoundFunction = R; + + fn description() -> String { + "Code decommitter".to_string() + } + + fn size_hint() -> (Option, Option) { + (Some(TARGET_CIRCUIT_TRACE_LENGTH), Some(1 << 26)) + } + + fn add_tables>(cs: &mut CS) { + let table = create_tri_xor_table(); + cs.add_lookup_table::(table); + + let table = create_ch4_table(); + cs.add_lookup_table::(table); + + let table = create_maj4_table(); + cs.add_lookup_table::(table); + + let table = create_4bit_chunk_split_table::(); + cs.add_lookup_table::, 4>(table); + + let table = create_4bit_chunk_split_table::(); + cs.add_lookup_table::, 4>(table); + } + + fn synthesize_into_cs_inner>( + cs: &mut CS, + witness: Self::Witness, + round_function: &Self::RoundFunction, + config: Self::Config, + ) -> [Num; INPUT_OUTPUT_COMMITMENT_LENGTH] { + unpack_code_into_memory_entry_point(cs, witness, round_function, config) + } +} diff --git a/crates/circuit_definitions/src/circuit_definitions/base_layer/ecrecover.rs b/crates/circuit_definitions/src/circuit_definitions/base_layer/ecrecover.rs new file mode 100644 index 0000000..ab930ea --- /dev/null +++ b/crates/circuit_definitions/src/circuit_definitions/base_layer/ecrecover.rs @@ -0,0 +1,181 @@ +use derivative::*; + +use super::*; +use crate::boojum::cs::traits::circuit::CircuitBuilder; + +type F = GoldilocksField; +type R = Poseidon2Goldilocks; + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Copy, Debug, Default(bound = ""))] +pub struct ECRecoverFunctionInstanceSynthesisFunction { + _marker: std::marker::PhantomData<(F, R)>, +} + +use crate::zkevm_circuits::ecrecover::input::*; +use crate::zkevm_circuits::ecrecover::{ + ecrecover_function_entry_point, secp256k1::fixed_base_mul_table::*, +}; + +impl CircuitBuilder for ECRecoverFunctionInstanceSynthesisFunction +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, +{ + fn geometry() -> CSGeometry { + CSGeometry { + num_columns_under_copy_permutation: 80, + num_witness_columns: 0, + num_constant_columns: 4, + max_allowed_constraint_degree: 8, + } + } + + fn lookup_parameters() -> LookupParameters { + LookupParameters::UseSpecializedColumnsWithTableIdAsConstant { + width: 3, + num_repetitions: 16, + share_table_id: true, + } + } + + fn configure_builder< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + let builder = builder.allow_lookup(>::lookup_parameters()); + + let builder = ConstantsAllocatorGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = BooleanConstraintGate::configure_builder( + builder, + GatePlacementStrategy::UseSpecializedColumns { + num_repetitions: 1, + share_constants: false, + }, + ); + let builder = U8x4FMAGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ZeroCheckGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + false, + ); + let builder = FmaGateInBaseFieldWithoutConstant::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<32>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<16>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<8>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = DotProductGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = SelectionGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ParallelSelectionGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = PublicInputGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ReductionGate::<_, 4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = + NopGate::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + + builder + } +} + +impl ZkSyncUniformSynthesisFunction for ECRecoverFunctionInstanceSynthesisFunction +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, +{ + type Witness = EcrecoverCircuitInstanceWitness; + type Config = usize; + type RoundFunction = R; + + fn description() -> String { + "ECRecover".to_string() + } + + fn size_hint() -> (Option, Option) { + (Some(TARGET_CIRCUIT_TRACE_LENGTH), Some(1 << 26)) + } + + fn add_tables>(cs: &mut CS) { + let table = create_xor8_table(); + cs.add_lookup_table::(table); + + let table = create_and8_table(); + cs.add_lookup_table::(table); + + seq_macro::seq!(C in 0..32 { + let table = create_fixed_base_mul_table::(); + cs.add_lookup_table::, 3>(table); + let table = create_fixed_base_mul_table::(); + cs.add_lookup_table::, 3>(table); + let table = create_fixed_base_mul_table::(); + cs.add_lookup_table::, 3>(table); + let table = create_fixed_base_mul_table::(); + cs.add_lookup_table::, 3>(table); + let table = create_fixed_base_mul_table::(); + cs.add_lookup_table::, 3>(table); + let table = create_fixed_base_mul_table::(); + cs.add_lookup_table::, 3>(table); + let table = create_fixed_base_mul_table::(); + cs.add_lookup_table::, 3>(table); + let table = create_fixed_base_mul_table::(); + cs.add_lookup_table::, 3>(table); + }); + + let table = create_byte_split_table::(); + cs.add_lookup_table::, 3>(table); + let table = create_byte_split_table::(); + cs.add_lookup_table::, 3>(table); + let table = create_byte_split_table::(); + cs.add_lookup_table::, 3>(table); + let table = create_byte_split_table::(); + cs.add_lookup_table::, 3>(table); + } + + fn synthesize_into_cs_inner>( + cs: &mut CS, + witness: Self::Witness, + round_function: &Self::RoundFunction, + config: Self::Config, + ) -> [Num; INPUT_OUTPUT_COMMITMENT_LENGTH] { + ecrecover_function_entry_point(cs, witness, round_function, config) + } +} diff --git a/crates/circuit_definitions/src/circuit_definitions/base_layer/eip4844.rs b/crates/circuit_definitions/src/circuit_definitions/base_layer/eip4844.rs new file mode 100644 index 0000000..ba224b4 --- /dev/null +++ b/crates/circuit_definitions/src/circuit_definitions/base_layer/eip4844.rs @@ -0,0 +1,178 @@ +use crate::boojum::config::CSConfig; +use crate::boojum::config::ProvingCSConfig; +use crate::boojum::cs::cs_builder_reference::CsReferenceImplementationBuilder; +use crate::boojum::cs::implementations::reference_cs::CSReferenceAssembly; +use crate::boojum::cs::implementations::setup::FinalizationHintsForProver; +use crate::boojum::dag::CircuitResolver; +use crate::boojum::field::traits::field_like::PrimeFieldLikeVectorized; +use derivative::*; + +use super::*; +use crate::boojum::cs::traits::circuit::CircuitBuilder; +use crate::boojum::gadgets::tables::create_and8_table; +use crate::boojum::gadgets::tables::create_byte_split_table; +use crate::boojum::gadgets::tables::create_xor8_table; +use crate::boojum::gadgets::tables::And8Table; +use crate::boojum::gadgets::tables::ByteSplitTable; +use crate::boojum::gadgets::tables::Xor8Table; +use crate::circuit_definitions::base_layer::TARGET_CIRCUIT_TRACE_LENGTH; +use crate::circuit_definitions::traits::gate::GatePlacementStrategy; + +type F = GoldilocksField; +type R = Poseidon2Goldilocks; + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Copy, Debug, Default(bound = ""))] +pub struct EIP4844InstanceSynthesisFunction { + _marker: std::marker::PhantomData<(F, R)>, +} + +use crate::zkevm_circuits::eip_4844::eip_4844_entry_point; +use crate::zkevm_circuits::eip_4844::input::*; + +impl CircuitBuilder for EIP4844InstanceSynthesisFunction +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, +{ + fn geometry() -> CSGeometry { + CSGeometry { + num_columns_under_copy_permutation: 60, + num_witness_columns: 0, + num_constant_columns: 8, + max_allowed_constraint_degree: 4, + } + } + + fn lookup_parameters() -> LookupParameters { + LookupParameters::UseSpecializedColumnsWithTableIdAsConstant { + width: 3, + num_repetitions: 20, + share_table_id: true, + } + } + + fn configure_builder< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + let builder = builder.allow_lookup(>::lookup_parameters()); + + let builder = ConstantsAllocatorGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = PublicInputGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = FmaGateInBaseFieldWithoutConstant::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ReductionGate::::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = BooleanConstraintGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<32>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<16>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = SelectionGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = DotProductGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = + NopGate::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + + builder + } +} + +impl ZkSyncUniformSynthesisFunction for EIP4844InstanceSynthesisFunction +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, +{ + type Witness = EIP4844CircuitInstanceWitness; + type Config = usize; + type RoundFunction = R; + + fn description() -> String { + "EIP4844".to_string() + } + + fn size_hint() -> (Option, Option) { + (Some(TARGET_CIRCUIT_TRACE_LENGTH), Some(1 << 26)) + } + + fn add_tables>(cs: &mut CS) { + let table = create_xor8_table(); + cs.add_lookup_table::(table); + + let table = create_and8_table(); + cs.add_lookup_table::(table); + + let table = create_byte_split_table::(); + cs.add_lookup_table::, 3>(table); + let table = create_byte_split_table::(); + cs.add_lookup_table::, 3>(table); + let table = create_byte_split_table::(); + cs.add_lookup_table::, 3>(table); + let table = create_byte_split_table::(); + cs.add_lookup_table::, 3>(table); + } + + fn synthesize_into_cs_inner>( + cs: &mut CS, + witness: Self::Witness, + round_function: &Self::RoundFunction, + config: Self::Config, + ) -> [Num; INPUT_OUTPUT_COMMITMENT_LENGTH] { + eip_4844_entry_point(cs, witness, round_function, config) + } +} + +pub fn synthesis( + circuit: EIP4844Circuit, + hint: &FinalizationHintsForProver, +) -> CSReferenceAssembly +where + P: PrimeFieldLikeVectorized, + CR: CircuitResolver< + F, + crate::boojum::config::Resolver, + >, + usize: Into<::ResolverConfig>>::Arg>, + + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, +{ + let geometry = circuit.geometry_proxy(); + let (max_trace_len, num_vars) = circuit.size_hint(); + let builder_impl = CsReferenceImplementationBuilder::::new( + geometry, + max_trace_len.unwrap(), + ); + let cs_builder = new_builder::<_, F>(builder_impl); + let builder = circuit.configure_builder_proxy(cs_builder); + let mut cs = builder.build(num_vars.unwrap()); + circuit.add_tables_proxy(&mut cs); + circuit.clone().synthesize_proxy(&mut cs); + cs.pad_and_shrink_using_hint(hint); + cs.into_assembly() +} diff --git a/crates/circuit_definitions/src/circuit_definitions/base_layer/events_sort_dedup.rs b/crates/circuit_definitions/src/circuit_definitions/base_layer/events_sort_dedup.rs new file mode 100644 index 0000000..53147d7 --- /dev/null +++ b/crates/circuit_definitions/src/circuit_definitions/base_layer/events_sort_dedup.rs @@ -0,0 +1,137 @@ +use derivative::*; + +use super::*; +use crate::boojum::cs::traits::circuit::CircuitBuilder; + +type F = GoldilocksField; +type R = Poseidon2Goldilocks; + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Copy, Debug, Default(bound = ""))] +pub struct EventsAndL1MessagesSortAndDedupInstanceSynthesisFunction { + _marker: std::marker::PhantomData<(F, R)>, +} + +use crate::zkevm_circuits::log_sorter::input::*; +use crate::zkevm_circuits::log_sorter::sort_and_deduplicate_events_entry_point; + +impl CircuitBuilder for EventsAndL1MessagesSortAndDedupInstanceSynthesisFunction +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + fn geometry() -> CSGeometry { + CSGeometry { + num_columns_under_copy_permutation: 130, + num_witness_columns: 0, + num_constant_columns: 4, + max_allowed_constraint_degree: 18, + } + } + + fn lookup_parameters() -> LookupParameters { + LookupParameters::UseSpecializedColumnsWithTableIdAsConstant { + width: 1, + num_repetitions: 8, + share_table_id: true, + } + } + + fn configure_builder< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + let builder = builder.allow_lookup(>::lookup_parameters()); + + let builder = ConstantsAllocatorGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = BooleanConstraintGate::configure_builder( + builder, + GatePlacementStrategy::UseSpecializedColumns { + num_repetitions: 1, + share_constants: false, + }, + ); + let builder = + R::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + let builder = ZeroCheckGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + false, + ); + let builder = FmaGateInBaseFieldWithoutConstant::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<32>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = SelectionGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ParallelSelectionGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = PublicInputGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ReductionGate::<_, 4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = + NopGate::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + + builder + } +} + +impl ZkSyncUniformSynthesisFunction for EventsAndL1MessagesSortAndDedupInstanceSynthesisFunction +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + type Witness = EventsDeduplicatorInstanceWitness; + type Config = usize; + type RoundFunction = R; + + fn description() -> String { + "Event/L1 messages sort and dedup".to_string() + } + + fn size_hint() -> (Option, Option) { + ( + Some(TARGET_CIRCUIT_TRACE_LENGTH), + Some((1 << 26) + (1 << 25)), + ) + } + + fn add_tables>(cs: &mut CS) { + let table = create_range_check_table::(); + cs.add_lookup_table::, 1>(table); + } + + fn synthesize_into_cs_inner>( + cs: &mut CS, + witness: Self::Witness, + round_function: &Self::RoundFunction, + config: Self::Config, + ) -> [Num; INPUT_OUTPUT_COMMITMENT_LENGTH] { + sort_and_deduplicate_events_entry_point(cs, witness, round_function, config) + } +} diff --git a/crates/circuit_definitions/src/circuit_definitions/base_layer/keccak256_round_function.rs b/crates/circuit_definitions/src/circuit_definitions/base_layer/keccak256_round_function.rs new file mode 100644 index 0000000..07427a8 --- /dev/null +++ b/crates/circuit_definitions/src/circuit_definitions/base_layer/keccak256_round_function.rs @@ -0,0 +1,153 @@ +use derivative::*; + +use super::*; +use crate::boojum::cs::traits::circuit::CircuitBuilder; + +type F = GoldilocksField; +type R = Poseidon2Goldilocks; + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Copy, Debug, Default(bound = ""))] +pub struct Keccak256RoundFunctionInstanceSynthesisFunction { + _marker: std::marker::PhantomData<(F, R)>, +} + +use crate::zkevm_circuits::keccak256_round_function::input::Keccak256RoundFunctionCircuitInstanceWitness; +use crate::zkevm_circuits::keccak256_round_function::keccak256_round_function_entry_point; + +impl CircuitBuilder for Keccak256RoundFunctionInstanceSynthesisFunction +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, +{ + fn geometry() -> CSGeometry { + CSGeometry { + num_columns_under_copy_permutation: 86, + num_witness_columns: 0, + num_constant_columns: 4, + max_allowed_constraint_degree: 8, + } + } + + fn lookup_parameters() -> LookupParameters { + LookupParameters::UseSpecializedColumnsWithTableIdAsConstant { + width: 3, + num_repetitions: 14, + share_table_id: true, + } + } + + fn configure_builder< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + let builder = builder.allow_lookup(>::lookup_parameters()); + + let builder = ConstantsAllocatorGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = BooleanConstraintGate::configure_builder( + builder, + GatePlacementStrategy::UseSpecializedColumns { + num_repetitions: 1, + share_constants: false, + }, + ); + + let builder = ZeroCheckGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + false, + ); + let builder = FmaGateInBaseFieldWithoutConstant::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<32>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<16>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<8>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = SelectionGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ParallelSelectionGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = PublicInputGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ReductionGate::<_, 4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = + NopGate::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + + builder + } +} + +impl ZkSyncUniformSynthesisFunction for Keccak256RoundFunctionInstanceSynthesisFunction +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, +{ + type Witness = Keccak256RoundFunctionCircuitInstanceWitness; + type Config = usize; + type RoundFunction = R; + + fn description() -> String { + "Keccak256 round function".to_string() + } + + fn size_hint() -> (Option, Option) { + (Some(TARGET_CIRCUIT_TRACE_LENGTH), Some(1 << 26)) + } + + fn add_tables>(cs: &mut CS) { + let table = create_xor8_table(); + cs.add_lookup_table::(table); + + let table = create_and8_table(); + cs.add_lookup_table::(table); + + let table = create_byte_split_table::(); + cs.add_lookup_table::, 3>(table); + let table = create_byte_split_table::(); + cs.add_lookup_table::, 3>(table); + let table = create_byte_split_table::(); + cs.add_lookup_table::, 3>(table); + let table = create_byte_split_table::(); + cs.add_lookup_table::, 3>(table); + } + + fn synthesize_into_cs_inner>( + cs: &mut CS, + witness: Self::Witness, + round_function: &Self::RoundFunction, + config: Self::Config, + ) -> [Num; INPUT_OUTPUT_COMMITMENT_LENGTH] { + keccak256_round_function_entry_point(cs, witness, round_function, config) + } +} diff --git a/crates/circuit_definitions/src/circuit_definitions/base_layer/linear_hasher.rs b/crates/circuit_definitions/src/circuit_definitions/base_layer/linear_hasher.rs new file mode 100644 index 0000000..cbd4d9b --- /dev/null +++ b/crates/circuit_definitions/src/circuit_definitions/base_layer/linear_hasher.rs @@ -0,0 +1,149 @@ +use derivative::*; + +use super::*; +use crate::boojum::cs::traits::circuit::CircuitBuilder; + +type F = GoldilocksField; +type R = Poseidon2Goldilocks; + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Copy, Debug, Default(bound = ""))] +pub struct LinearHasherInstanceSynthesisFunction { + _marker: std::marker::PhantomData<(F, R)>, +} + +use crate::zkevm_circuits::linear_hasher::input::LinearHasherCircuitInstanceWitness; +use crate::zkevm_circuits::linear_hasher::linear_hasher_entry_point; + +impl CircuitBuilder for LinearHasherInstanceSynthesisFunction +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, +{ + fn geometry() -> CSGeometry { + CSGeometry { + num_columns_under_copy_permutation: 66, + num_witness_columns: 0, + num_constant_columns: 4, + max_allowed_constraint_degree: 8, + } + } + + fn lookup_parameters() -> LookupParameters { + LookupParameters::UseSpecializedColumnsWithTableIdAsConstant { + width: 3, + num_repetitions: 26, + share_table_id: true, + } + } + + fn configure_builder< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + let builder = builder.allow_lookup(>::lookup_parameters()); + + let builder = ConstantsAllocatorGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = BooleanConstraintGate::configure_builder( + builder, + GatePlacementStrategy::UseSpecializedColumns { + num_repetitions: 1, + share_constants: false, + }, + ); + + let builder = ZeroCheckGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + false, + ); + let builder = FmaGateInBaseFieldWithoutConstant::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<32>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<16>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = SelectionGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ParallelSelectionGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = PublicInputGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ReductionGate::<_, 4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = + NopGate::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + + builder + } +} + +impl ZkSyncUniformSynthesisFunction for LinearHasherInstanceSynthesisFunction +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, +{ + type Witness = LinearHasherCircuitInstanceWitness; + type Config = usize; + type RoundFunction = R; + + fn description() -> String { + "Linear hasher".to_string() + } + + fn size_hint() -> (Option, Option) { + (Some(TARGET_CIRCUIT_TRACE_LENGTH), Some(1 << 26)) + } + + fn add_tables>(cs: &mut CS) { + let table = create_xor8_table(); + cs.add_lookup_table::(table); + + let table = create_and8_table(); + cs.add_lookup_table::(table); + + let table = create_byte_split_table::(); + cs.add_lookup_table::, 3>(table); + let table = create_byte_split_table::(); + cs.add_lookup_table::, 3>(table); + let table = create_byte_split_table::(); + cs.add_lookup_table::, 3>(table); + let table = create_byte_split_table::(); + cs.add_lookup_table::, 3>(table); + } + + fn synthesize_into_cs_inner>( + cs: &mut CS, + witness: Self::Witness, + round_function: &Self::RoundFunction, + config: Self::Config, + ) -> [Num; INPUT_OUTPUT_COMMITMENT_LENGTH] { + linear_hasher_entry_point(cs, witness, round_function, config) + } +} diff --git a/crates/circuit_definitions/src/circuit_definitions/base_layer/log_demux.rs b/crates/circuit_definitions/src/circuit_definitions/base_layer/log_demux.rs new file mode 100644 index 0000000..333872d --- /dev/null +++ b/crates/circuit_definitions/src/circuit_definitions/base_layer/log_demux.rs @@ -0,0 +1,137 @@ +use derivative::*; + +use super::*; +use crate::boojum::cs::traits::circuit::CircuitBuilder; + +type F = GoldilocksField; +type R = Poseidon2Goldilocks; + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Copy, Debug, Default(bound = ""))] +pub struct LogDemuxInstanceSynthesisFunction { + _marker: std::marker::PhantomData<(F, R)>, +} + +use crate::zkevm_circuits::demux_log_queue::demultiplex_storage_logs_enty_point; +use crate::zkevm_circuits::demux_log_queue::input::LogDemuxerCircuitInstanceWitness; + +impl CircuitBuilder for LogDemuxInstanceSynthesisFunction +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, +{ + fn geometry() -> CSGeometry { + CSGeometry { + num_columns_under_copy_permutation: 136, + num_witness_columns: 0, + num_constant_columns: 4, + max_allowed_constraint_degree: 8, + } + } + + fn lookup_parameters() -> LookupParameters { + LookupParameters::UseSpecializedColumnsWithTableIdAsConstant { + width: 1, + num_repetitions: 14, + share_table_id: true, + } + } + + fn configure_builder< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + let builder = builder.allow_lookup(>::lookup_parameters()); + + let builder = ConstantsAllocatorGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = BooleanConstraintGate::configure_builder( + builder, + GatePlacementStrategy::UseSpecializedColumns { + num_repetitions: 1, + share_constants: false, + }, + ); + let builder = + R::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + let builder = ZeroCheckGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + false, + ); + let builder = FmaGateInBaseFieldWithoutConstant::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<32>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = SelectionGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ParallelSelectionGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = PublicInputGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ReductionGate::<_, 4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = + NopGate::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + + builder + } +} + +impl ZkSyncUniformSynthesisFunction for LogDemuxInstanceSynthesisFunction +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, +{ + type Witness = LogDemuxerCircuitInstanceWitness; + type Config = usize; + type RoundFunction = R; + + fn description() -> String { + "Log demuxer".to_string() + } + + fn size_hint() -> (Option, Option) { + ( + Some(TARGET_CIRCUIT_TRACE_LENGTH), + Some((1 << 26) + (1 << 25)), + ) + } + + fn add_tables>(cs: &mut CS) { + let table = create_range_check_table::(); + cs.add_lookup_table::, 1>(table); + } + + fn synthesize_into_cs_inner>( + cs: &mut CS, + witness: Self::Witness, + round_function: &Self::RoundFunction, + config: Self::Config, + ) -> [Num; INPUT_OUTPUT_COMMITMENT_LENGTH] { + demultiplex_storage_logs_enty_point(cs, witness, round_function, config) + } +} diff --git a/crates/circuit_definitions/src/circuit_definitions/base_layer/mod.rs b/crates/circuit_definitions/src/circuit_definitions/base_layer/mod.rs new file mode 100644 index 0000000..ec6e732 --- /dev/null +++ b/crates/circuit_definitions/src/circuit_definitions/base_layer/mod.rs @@ -0,0 +1,571 @@ +use crate::boojum::cs::gates::*; +use crate::boojum::cs::implementations::proof::Proof; +use crate::boojum::cs::implementations::setup::FinalizationHintsForProver; +use crate::boojum::cs::traits::gate::GatePlacementStrategy; +use crate::boojum::field::goldilocks::{GoldilocksExt2, GoldilocksField}; +use crate::boojum::gadgets::tables::*; +use crate::zkevm_circuits::base_structures::vm_state::saved_context::ExecutionContextRecord; +use crate::zkevm_circuits::boojum::config::CSConfig; +use crate::zkevm_circuits::boojum::dag::CircuitResolver; +use crate::zkevm_circuits::storage_validity_by_grand_product::TimestampedStorageLogRecord; +use crate::zkevm_circuits::tables::*; +use snark_wrapper::boojum::dag::StCircuitResolver; + +use super::*; + +pub const TARGET_CIRCUIT_TRACE_LENGTH: usize = 1 << 20; + +// should follow in the same sequence as we will logically process sequences +pub mod code_decommitter; +pub mod ecrecover; +pub mod events_sort_dedup; +pub mod keccak256_round_function; +pub mod log_demux; +pub mod ram_permutation; +pub mod secp256r1_verify; +pub mod sha256_round_function; +pub mod sort_code_decommits; +pub mod storage_apply; +pub mod storage_sort_dedup; +pub mod transient_storage_sort; +pub mod vm_main; +// pub mod l1_messages_sort_dedup; // equal to one above +pub mod eip4844; +pub mod linear_hasher; + +pub use self::code_decommitter::CodeDecommitterInstanceSynthesisFunction; +pub use self::ecrecover::ECRecoverFunctionInstanceSynthesisFunction; +pub use self::eip4844::EIP4844InstanceSynthesisFunction; +pub use self::events_sort_dedup::EventsAndL1MessagesSortAndDedupInstanceSynthesisFunction; +pub use self::keccak256_round_function::Keccak256RoundFunctionInstanceSynthesisFunction; +pub use self::linear_hasher::LinearHasherInstanceSynthesisFunction; +pub use self::log_demux::LogDemuxInstanceSynthesisFunction; +pub use self::ram_permutation::RAMPermutationInstanceSynthesisFunction; +pub use self::secp256r1_verify::Secp256r1VerifyFunctionInstanceSynthesisFunction; +pub use self::sha256_round_function::Sha256RoundFunctionInstanceSynthesisFunction; +pub use self::sort_code_decommits::CodeDecommittmentsSorterSynthesisFunction; +pub use self::storage_apply::StorageApplicationInstanceSynthesisFunction; +pub use self::storage_sort_dedup::StorageSortAndDedupInstanceSynthesisFunction; +pub use self::transient_storage_sort::TransientStorageSortAndDedupInstanceSynthesisFunction; +pub use self::vm_main::VmMainInstanceSynthesisFunction; + +// Type definitions for circuits, so one can easily form circuits with witness, and their definition +// will take care of particular synthesis function. There is already an implementation of Circuit for ZkSyncUniformCircuitInstance, +// so as soon as the structure is instantiated it is ready for proving +pub type VMMainCircuit = + ZkSyncUniformCircuitInstance; +pub type CodeDecommittsSorterCircuit = + ZkSyncUniformCircuitInstance; +pub type CodeDecommitterCircuit = + ZkSyncUniformCircuitInstance; +pub type LogDemuxerCircuit = + ZkSyncUniformCircuitInstance; +pub type Keccak256RoundFunctionCircuit = + ZkSyncUniformCircuitInstance; +pub type Sha256RoundFunctionCircuit = + ZkSyncUniformCircuitInstance; +pub type ECRecoverFunctionCircuit = + ZkSyncUniformCircuitInstance; +pub type RAMPermutationCircuit = + ZkSyncUniformCircuitInstance; +pub type StorageSorterCircuit = + ZkSyncUniformCircuitInstance; +pub type StorageApplicationCircuit = + ZkSyncUniformCircuitInstance; +pub type EventsSorterCircuit = ZkSyncUniformCircuitInstance< + GoldilocksField, + EventsAndL1MessagesSortAndDedupInstanceSynthesisFunction, +>; +pub type L1MessagesSorterCircuit = ZkSyncUniformCircuitInstance< + GoldilocksField, + EventsAndL1MessagesSortAndDedupInstanceSynthesisFunction, +>; +pub type L1MessagesHasherCircuit = + ZkSyncUniformCircuitInstance; +pub type TransientStorageSorterCircuit = ZkSyncUniformCircuitInstance< + GoldilocksField, + TransientStorageSortAndDedupInstanceSynthesisFunction, +>; +pub type Secp256r1VerifyCircuit = + ZkSyncUniformCircuitInstance; +pub type EIP4844Circuit = + ZkSyncUniformCircuitInstance; + +#[derive(derivative::Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone(bound = ""), Debug)] +#[serde(bound = "")] +pub enum ZkSyncBaseLayerStorage< + T: Clone + std::fmt::Debug + serde::Serialize + serde::de::DeserializeOwned, +> { + MainVM(T), + CodeDecommittmentsSorter(T), + CodeDecommitter(T), + LogDemuxer(T), + KeccakRoundFunction(T), + Sha256RoundFunction(T), + ECRecover(T), + RAMPermutation(T), + StorageSorter(T), + StorageApplication(T), + EventsSorter(T), + L1MessagesSorter(T), + L1MessagesHasher(T), + TransientStorageSorter(T), + Secp256r1Verify(T), + EIP4844Repack(T), +} + +impl + ZkSyncBaseLayerStorage +{ + pub fn short_description(&self) -> &'static str { + match &self { + ZkSyncBaseLayerStorage::MainVM(..) => "Main VM", + ZkSyncBaseLayerStorage::CodeDecommittmentsSorter(..) => "Decommitts sorter", + ZkSyncBaseLayerStorage::CodeDecommitter(..) => "Code decommitter", + ZkSyncBaseLayerStorage::LogDemuxer(..) => "Log demuxer", + ZkSyncBaseLayerStorage::KeccakRoundFunction(..) => "Keccak", + ZkSyncBaseLayerStorage::Sha256RoundFunction(..) => "SHA256", + ZkSyncBaseLayerStorage::ECRecover(..) => "ECRecover", + ZkSyncBaseLayerStorage::RAMPermutation(..) => "RAM permutation", + ZkSyncBaseLayerStorage::StorageSorter(..) => "Storage sorter", + ZkSyncBaseLayerStorage::StorageApplication(..) => "Storage application", + ZkSyncBaseLayerStorage::EventsSorter(..) => "Events sorter", + ZkSyncBaseLayerStorage::L1MessagesSorter(..) => "L1 messages sorter", + ZkSyncBaseLayerStorage::L1MessagesHasher(..) => "L1 messages rehasher", + ZkSyncBaseLayerStorage::TransientStorageSorter(..) => "Transient storage sorter", + ZkSyncBaseLayerStorage::Secp256r1Verify(..) => "Secp256r1 signature verifier", + ZkSyncBaseLayerStorage::EIP4844Repack(..) => "EIP4844 repacker", + } + } + + pub fn numeric_circuit_type(&self) -> u8 { + use crate::zkevm_circuits::scheduler::aux::BaseLayerCircuitType; + + match &self { + ZkSyncBaseLayerStorage::MainVM(..) => BaseLayerCircuitType::VM as u8, + ZkSyncBaseLayerStorage::CodeDecommittmentsSorter(..) => { + BaseLayerCircuitType::DecommitmentsFilter as u8 + } + ZkSyncBaseLayerStorage::CodeDecommitter(..) => BaseLayerCircuitType::Decommiter as u8, + ZkSyncBaseLayerStorage::LogDemuxer(..) => BaseLayerCircuitType::LogDemultiplexer as u8, + ZkSyncBaseLayerStorage::KeccakRoundFunction(..) => { + BaseLayerCircuitType::KeccakPrecompile as u8 + } + ZkSyncBaseLayerStorage::Sha256RoundFunction(..) => { + BaseLayerCircuitType::Sha256Precompile as u8 + } + ZkSyncBaseLayerStorage::ECRecover(..) => { + BaseLayerCircuitType::EcrecoverPrecompile as u8 + } + ZkSyncBaseLayerStorage::RAMPermutation(..) => BaseLayerCircuitType::RamValidation as u8, + ZkSyncBaseLayerStorage::StorageSorter(..) => BaseLayerCircuitType::StorageFilter as u8, + ZkSyncBaseLayerStorage::StorageApplication(..) => { + BaseLayerCircuitType::StorageApplicator as u8 + } + ZkSyncBaseLayerStorage::EventsSorter(..) => { + BaseLayerCircuitType::EventsRevertsFilter as u8 + } + ZkSyncBaseLayerStorage::L1MessagesSorter(..) => { + BaseLayerCircuitType::L1MessagesRevertsFilter as u8 + } + ZkSyncBaseLayerStorage::L1MessagesHasher(..) => { + BaseLayerCircuitType::L1MessagesHasher as u8 + } + ZkSyncBaseLayerStorage::TransientStorageSorter(..) => { + BaseLayerCircuitType::TransientStorageChecker as u8 + } + ZkSyncBaseLayerStorage::Secp256r1Verify(..) => { + BaseLayerCircuitType::Secp256r1Verify as u8 + } + ZkSyncBaseLayerStorage::EIP4844Repack(..) => BaseLayerCircuitType::EIP4844Repack as u8, + } + } + + pub fn into_inner(self) -> T { + match self { + ZkSyncBaseLayerStorage::MainVM(inner) => inner, + ZkSyncBaseLayerStorage::CodeDecommittmentsSorter(inner) => inner, + ZkSyncBaseLayerStorage::CodeDecommitter(inner) => inner, + ZkSyncBaseLayerStorage::LogDemuxer(inner) => inner, + ZkSyncBaseLayerStorage::KeccakRoundFunction(inner) => inner, + ZkSyncBaseLayerStorage::Sha256RoundFunction(inner) => inner, + ZkSyncBaseLayerStorage::ECRecover(inner) => inner, + ZkSyncBaseLayerStorage::RAMPermutation(inner) => inner, + ZkSyncBaseLayerStorage::StorageSorter(inner) => inner, + ZkSyncBaseLayerStorage::StorageApplication(inner) => inner, + ZkSyncBaseLayerStorage::EventsSorter(inner) => inner, + ZkSyncBaseLayerStorage::L1MessagesSorter(inner) => inner, + ZkSyncBaseLayerStorage::L1MessagesHasher(inner) => inner, + ZkSyncBaseLayerStorage::TransientStorageSorter(inner) => inner, + ZkSyncBaseLayerStorage::Secp256r1Verify(inner) => inner, + ZkSyncBaseLayerStorage::EIP4844Repack(inner) => inner, + } + } + + pub fn from_inner(numeric_type: u8, inner: T) -> Self { + use crate::zkevm_circuits::scheduler::aux::BaseLayerCircuitType; + + match numeric_type { + a if a == BaseLayerCircuitType::VM as u8 => Self::MainVM(inner), + a if a == BaseLayerCircuitType::DecommitmentsFilter as u8 => { + Self::CodeDecommittmentsSorter(inner) + } + a if a == BaseLayerCircuitType::Decommiter as u8 => Self::CodeDecommitter(inner), + a if a == BaseLayerCircuitType::LogDemultiplexer as u8 => Self::LogDemuxer(inner), + a if a == BaseLayerCircuitType::KeccakPrecompile as u8 => { + Self::KeccakRoundFunction(inner) + } + a if a == BaseLayerCircuitType::Sha256Precompile as u8 => { + Self::Sha256RoundFunction(inner) + } + a if a == BaseLayerCircuitType::EcrecoverPrecompile as u8 => Self::ECRecover(inner), + a if a == BaseLayerCircuitType::RamValidation as u8 => Self::RAMPermutation(inner), + a if a == BaseLayerCircuitType::StorageFilter as u8 => Self::StorageSorter(inner), + a if a == BaseLayerCircuitType::StorageApplicator as u8 => { + Self::StorageApplication(inner) + } + a if a == BaseLayerCircuitType::EventsRevertsFilter as u8 => Self::EventsSorter(inner), + a if a == BaseLayerCircuitType::L1MessagesRevertsFilter as u8 => { + Self::L1MessagesSorter(inner) + } + a if a == BaseLayerCircuitType::L1MessagesHasher as u8 => Self::L1MessagesHasher(inner), + a if a == BaseLayerCircuitType::TransientStorageChecker as u8 => { + Self::TransientStorageSorter(inner) + } + a if a == BaseLayerCircuitType::Secp256r1Verify as u8 => Self::Secp256r1Verify(inner), + a if a == BaseLayerCircuitType::EIP4844Repack as u8 => Self::EIP4844Repack(inner), + a @ _ => panic!("unknown numeric type {}", a), + } + } +} + +type F = GoldilocksField; + +#[derive(derivative::Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone(bound = ""))] +#[serde(bound = "")] +pub enum ZkSyncBaseLayerCircuit +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + MainVM(VMMainCircuit), + CodeDecommittmentsSorter(CodeDecommittsSorterCircuit), + CodeDecommitter(CodeDecommitterCircuit), + LogDemuxer(LogDemuxerCircuit), + KeccakRoundFunction(Keccak256RoundFunctionCircuit), + Sha256RoundFunction(Sha256RoundFunctionCircuit), + ECRecover(ECRecoverFunctionCircuit), + RAMPermutation(RAMPermutationCircuit), + StorageSorter(StorageSorterCircuit), + StorageApplication(StorageApplicationCircuit), + EventsSorter(EventsSorterCircuit), + L1MessagesSorter(L1MessagesSorterCircuit), + L1MessagesHasher(L1MessagesHasherCircuit), + TransientStorageSorter(TransientStorageSorterCircuit), + Secp256r1Verify(Secp256r1VerifyCircuit), + EIP4844Repack(EIP4844Circuit), +} + +impl ZkSyncBaseLayerCircuit +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + pub fn short_description(&self) -> &'static str { + match &self { + ZkSyncBaseLayerCircuit::MainVM(..) => "Main VM", + ZkSyncBaseLayerCircuit::CodeDecommittmentsSorter(..) => "Decommitts sorter", + ZkSyncBaseLayerCircuit::CodeDecommitter(..) => "Code decommitter", + ZkSyncBaseLayerCircuit::LogDemuxer(..) => "Log demuxer", + ZkSyncBaseLayerCircuit::KeccakRoundFunction(..) => "Keccak", + ZkSyncBaseLayerCircuit::Sha256RoundFunction(..) => "SHA256", + ZkSyncBaseLayerCircuit::ECRecover(..) => "ECRecover", + ZkSyncBaseLayerCircuit::RAMPermutation(..) => "RAM permutation", + ZkSyncBaseLayerCircuit::StorageSorter(..) => "Storage sorter", + ZkSyncBaseLayerCircuit::StorageApplication(..) => "Storage application", + ZkSyncBaseLayerCircuit::EventsSorter(..) => "Events sorter", + ZkSyncBaseLayerCircuit::L1MessagesSorter(..) => "L1 messages sorter", + ZkSyncBaseLayerCircuit::L1MessagesHasher(..) => "L1 messages rehasher", + ZkSyncBaseLayerCircuit::TransientStorageSorter(..) => "Transient storage sorter", + ZkSyncBaseLayerCircuit::Secp256r1Verify(..) => "Secp256r1 verify", + ZkSyncBaseLayerCircuit::EIP4844Repack(..) => "EIP4844 repacker", + } + } + + pub fn size_hint(&self) -> (Option, Option) { + match &self { + ZkSyncBaseLayerCircuit::MainVM(inner) => inner.size_hint(), + ZkSyncBaseLayerCircuit::CodeDecommittmentsSorter(inner) => inner.size_hint(), + ZkSyncBaseLayerCircuit::CodeDecommitter(inner) => inner.size_hint(), + ZkSyncBaseLayerCircuit::LogDemuxer(inner) => inner.size_hint(), + ZkSyncBaseLayerCircuit::KeccakRoundFunction(inner) => inner.size_hint(), + ZkSyncBaseLayerCircuit::Sha256RoundFunction(inner) => inner.size_hint(), + ZkSyncBaseLayerCircuit::ECRecover(inner) => inner.size_hint(), + ZkSyncBaseLayerCircuit::RAMPermutation(inner) => inner.size_hint(), + ZkSyncBaseLayerCircuit::StorageSorter(inner) => inner.size_hint(), + ZkSyncBaseLayerCircuit::StorageApplication(inner) => inner.size_hint(), + ZkSyncBaseLayerCircuit::EventsSorter(inner) => inner.size_hint(), + ZkSyncBaseLayerCircuit::L1MessagesSorter(inner) => inner.size_hint(), + ZkSyncBaseLayerCircuit::L1MessagesHasher(inner) => inner.size_hint(), + ZkSyncBaseLayerCircuit::TransientStorageSorter(inner) => inner.size_hint(), + ZkSyncBaseLayerCircuit::Secp256r1Verify(inner) => inner.size_hint(), + ZkSyncBaseLayerCircuit::EIP4844Repack(inner) => inner.size_hint(), + } + } + + fn synthesis_inner( + inner: &ZkSyncUniformCircuitInstance>, + hint: &FinalizationHintsForProver, + ) -> CSReferenceAssembly + where + P: PrimeFieldLikeVectorized, + CR: CircuitResolver< + F, + crate::boojum::config::Resolver, + >, + usize: Into<::ResolverConfig>>::Arg>, + { + let geometry = inner.geometry_proxy(); + let (max_trace_len, num_vars) = inner.size_hint(); + let builder_impl = CsReferenceImplementationBuilder::::new( + geometry, + max_trace_len.unwrap(), + ); + let cs_builder = new_builder::<_, F>(builder_impl); + let builder = inner.configure_builder_proxy(cs_builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables_proxy(&mut cs); + inner.clone().synthesize_proxy(&mut cs); + cs.pad_and_shrink_using_hint(hint); + cs.into_assembly() + } + + pub fn synthesis>( + &self, + hint: &FinalizationHintsForProver, + ) -> CSReferenceAssembly { + self.synthesis_wrapped::< + P, + StCircuitResolver::ResolverConfig> + >(hint) + } + + pub fn synthesis_wrapped( + &self, + hint: &FinalizationHintsForProver, + ) -> CSReferenceAssembly + where + P: PrimeFieldLikeVectorized, + CR: CircuitResolver< + F, + crate::boojum::config::Resolver, + >, + usize: Into<::ResolverConfig>>::Arg>, + { + match &self { + ZkSyncBaseLayerCircuit::MainVM(inner) => Self::synthesis_inner::<_, CR>(inner, hint), + ZkSyncBaseLayerCircuit::CodeDecommittmentsSorter(inner) => { + Self::synthesis_inner::<_, CR>(inner, hint) + } + ZkSyncBaseLayerCircuit::CodeDecommitter(inner) => { + Self::synthesis_inner::<_, CR>(inner, hint) + } + ZkSyncBaseLayerCircuit::LogDemuxer(inner) => { + Self::synthesis_inner::<_, CR>(inner, hint) + } + ZkSyncBaseLayerCircuit::KeccakRoundFunction(inner) => { + Self::synthesis_inner::<_, CR>(inner, hint) + } + ZkSyncBaseLayerCircuit::Sha256RoundFunction(inner) => { + Self::synthesis_inner::<_, CR>(inner, hint) + } + ZkSyncBaseLayerCircuit::ECRecover(inner) => Self::synthesis_inner::<_, CR>(inner, hint), + ZkSyncBaseLayerCircuit::RAMPermutation(inner) => { + Self::synthesis_inner::<_, CR>(inner, hint) + } + ZkSyncBaseLayerCircuit::StorageSorter(inner) => { + Self::synthesis_inner::<_, CR>(inner, hint) + } + ZkSyncBaseLayerCircuit::StorageApplication(inner) => { + Self::synthesis_inner::<_, CR>(inner, hint) + } + ZkSyncBaseLayerCircuit::EventsSorter(inner) => { + Self::synthesis_inner::<_, CR>(inner, hint) + } + ZkSyncBaseLayerCircuit::L1MessagesSorter(inner) => { + Self::synthesis_inner::<_, CR>(inner, hint) + } + ZkSyncBaseLayerCircuit::L1MessagesHasher(inner) => { + Self::synthesis_inner::<_, CR>(inner, hint) + } + ZkSyncBaseLayerCircuit::TransientStorageSorter(inner) => { + Self::synthesis_inner::<_, CR>(inner, hint) + } + ZkSyncBaseLayerCircuit::Secp256r1Verify(inner) => { + Self::synthesis_inner::<_, CR>(inner, hint) + } + ZkSyncBaseLayerCircuit::EIP4844Repack(inner) => { + Self::synthesis_inner::<_, CR>(inner, hint) + } + } + } + + pub fn geometry(&self) -> CSGeometry { + match &self { + ZkSyncBaseLayerCircuit::MainVM(inner) => inner.geometry_proxy(), + ZkSyncBaseLayerCircuit::CodeDecommittmentsSorter(inner) => inner.geometry_proxy(), + ZkSyncBaseLayerCircuit::CodeDecommitter(inner) => inner.geometry_proxy(), + ZkSyncBaseLayerCircuit::LogDemuxer(inner) => inner.geometry_proxy(), + ZkSyncBaseLayerCircuit::KeccakRoundFunction(inner) => inner.geometry_proxy(), + ZkSyncBaseLayerCircuit::Sha256RoundFunction(inner) => inner.geometry_proxy(), + ZkSyncBaseLayerCircuit::ECRecover(inner) => inner.geometry_proxy(), + ZkSyncBaseLayerCircuit::RAMPermutation(inner) => inner.geometry_proxy(), + ZkSyncBaseLayerCircuit::StorageSorter(inner) => inner.geometry_proxy(), + ZkSyncBaseLayerCircuit::StorageApplication(inner) => inner.geometry_proxy(), + ZkSyncBaseLayerCircuit::EventsSorter(inner) => inner.geometry_proxy(), + ZkSyncBaseLayerCircuit::L1MessagesSorter(inner) => inner.geometry_proxy(), + ZkSyncBaseLayerCircuit::L1MessagesHasher(inner) => inner.geometry_proxy(), + ZkSyncBaseLayerCircuit::TransientStorageSorter(inner) => inner.geometry_proxy(), + ZkSyncBaseLayerCircuit::Secp256r1Verify(inner) => inner.geometry_proxy(), + ZkSyncBaseLayerCircuit::EIP4844Repack(inner) => inner.geometry_proxy(), + } + } + + pub fn debug_witness(&self) { + match &self { + ZkSyncBaseLayerCircuit::MainVM(inner) => { + inner.debug_witness(); + } + ZkSyncBaseLayerCircuit::CodeDecommittmentsSorter(inner) => { + inner.debug_witness(); + } + ZkSyncBaseLayerCircuit::CodeDecommitter(inner) => { + inner.debug_witness(); + } + ZkSyncBaseLayerCircuit::LogDemuxer(inner) => { + inner.debug_witness(); + } + ZkSyncBaseLayerCircuit::KeccakRoundFunction(inner) => { + inner.debug_witness(); + } + ZkSyncBaseLayerCircuit::Sha256RoundFunction(inner) => { + inner.debug_witness(); + } + ZkSyncBaseLayerCircuit::ECRecover(inner) => { + inner.debug_witness(); + } + ZkSyncBaseLayerCircuit::RAMPermutation(inner) => { + inner.debug_witness(); + } + ZkSyncBaseLayerCircuit::StorageSorter(inner) => { + inner.debug_witness(); + } + ZkSyncBaseLayerCircuit::StorageApplication(inner) => { + inner.debug_witness(); + } + ZkSyncBaseLayerCircuit::EventsSorter(inner) => { + inner.debug_witness(); + } + ZkSyncBaseLayerCircuit::L1MessagesSorter(inner) => { + inner.debug_witness(); + } + ZkSyncBaseLayerCircuit::L1MessagesHasher(inner) => { + inner.debug_witness(); + } + ZkSyncBaseLayerCircuit::TransientStorageSorter(inner) => { + inner.debug_witness(); + } + ZkSyncBaseLayerCircuit::Secp256r1Verify(inner) => { + inner.debug_witness(); + } + ZkSyncBaseLayerCircuit::EIP4844Repack(inner) => { + inner.debug_witness(); + } + }; + + () + } + + pub fn numeric_circuit_type(&self) -> u8 { + use crate::zkevm_circuits::scheduler::aux::BaseLayerCircuitType; + + match &self { + ZkSyncBaseLayerCircuit::MainVM(..) => BaseLayerCircuitType::VM as u8, + ZkSyncBaseLayerCircuit::CodeDecommittmentsSorter(..) => { + BaseLayerCircuitType::DecommitmentsFilter as u8 + } + ZkSyncBaseLayerCircuit::CodeDecommitter(..) => BaseLayerCircuitType::Decommiter as u8, + ZkSyncBaseLayerCircuit::LogDemuxer(..) => BaseLayerCircuitType::LogDemultiplexer as u8, + ZkSyncBaseLayerCircuit::KeccakRoundFunction(..) => { + BaseLayerCircuitType::KeccakPrecompile as u8 + } + ZkSyncBaseLayerCircuit::Sha256RoundFunction(..) => { + BaseLayerCircuitType::Sha256Precompile as u8 + } + ZkSyncBaseLayerCircuit::ECRecover(..) => { + BaseLayerCircuitType::EcrecoverPrecompile as u8 + } + ZkSyncBaseLayerCircuit::RAMPermutation(..) => BaseLayerCircuitType::RamValidation as u8, + ZkSyncBaseLayerCircuit::StorageSorter(..) => BaseLayerCircuitType::StorageFilter as u8, + ZkSyncBaseLayerCircuit::StorageApplication(..) => { + BaseLayerCircuitType::StorageApplicator as u8 + } + ZkSyncBaseLayerCircuit::EventsSorter(..) => { + BaseLayerCircuitType::EventsRevertsFilter as u8 + } + ZkSyncBaseLayerCircuit::L1MessagesSorter(..) => { + BaseLayerCircuitType::L1MessagesRevertsFilter as u8 + } + ZkSyncBaseLayerCircuit::L1MessagesHasher(..) => { + BaseLayerCircuitType::L1MessagesHasher as u8 + } + ZkSyncBaseLayerCircuit::TransientStorageSorter(..) => { + BaseLayerCircuitType::TransientStorageChecker as u8 + } + ZkSyncBaseLayerCircuit::Secp256r1Verify(..) => { + BaseLayerCircuitType::Secp256r1Verify as u8 + } + ZkSyncBaseLayerCircuit::EIP4844Repack(..) => BaseLayerCircuitType::EIP4844Repack as u8, + } + } +} + +pub type ZkSyncBaseLayerCircuitInput = + ZkSyncBaseLayerStorage<[F; INPUT_OUTPUT_COMMITMENT_LENGTH]>; + +use crate::zkevm_circuits::fsm_input_output::ClosedFormInputCompactFormWitness; + +pub type ZkSyncBaseLayerClosedFormInput = + ZkSyncBaseLayerStorage>; + +use crate::boojum::algebraic_props::round_function::AbsorptionModeOverwrite; +use crate::boojum::algebraic_props::sponge::GoldilocksPoseidon2Sponge; +use crate::boojum::config::ProvingCSConfig; +use crate::boojum::cs::cs_builder_reference::CsReferenceImplementationBuilder; +use crate::boojum::cs::implementations::reference_cs::CSReferenceAssembly; + +pub type BaseProofsTreeHasher = GoldilocksPoseidon2Sponge; +pub type ZkSyncBaseProof = Proof; + +pub type ZkSyncBaseLayerProof = ZkSyncBaseLayerStorage; + +pub type ZkSyncBaseLayerFinalizationHint = ZkSyncBaseLayerStorage; + +use crate::boojum::cs::implementations::verifier::VerificationKey; +use crate::boojum::field::traits::field_like::PrimeFieldLikeVectorized; + +pub type ZkSyncBaseVerificationKey = VerificationKey; + +pub type ZkSyncBaseLayerVerificationKey = ZkSyncBaseLayerStorage; diff --git a/crates/circuit_definitions/src/circuit_definitions/base_layer/ram_permutation.rs b/crates/circuit_definitions/src/circuit_definitions/base_layer/ram_permutation.rs new file mode 100644 index 0000000..b86b2f4 --- /dev/null +++ b/crates/circuit_definitions/src/circuit_definitions/base_layer/ram_permutation.rs @@ -0,0 +1,137 @@ +use derivative::*; + +use super::*; +use crate::boojum::cs::traits::circuit::CircuitBuilder; + +type F = GoldilocksField; +type R = Poseidon2Goldilocks; + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Copy, Debug, Default(bound = ""))] +pub struct RAMPermutationInstanceSynthesisFunction { + _marker: std::marker::PhantomData<(F, R)>, +} + +use crate::zkevm_circuits::ram_permutation::input::*; +use crate::zkevm_circuits::ram_permutation::ram_permutation_entry_point; + +impl CircuitBuilder for RAMPermutationInstanceSynthesisFunction +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + fn geometry() -> CSGeometry { + CSGeometry { + num_columns_under_copy_permutation: 133, + num_witness_columns: 0, + num_constant_columns: 4, + max_allowed_constraint_degree: 8, + } + } + + fn lookup_parameters() -> LookupParameters { + LookupParameters::UseSpecializedColumnsWithTableIdAsConstant { + width: 1, + num_repetitions: 15, + share_table_id: true, + } + } + + fn configure_builder< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + let builder = builder.allow_lookup(>::lookup_parameters()); + + let builder = ConstantsAllocatorGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = BooleanConstraintGate::configure_builder( + builder, + GatePlacementStrategy::UseSpecializedColumns { + num_repetitions: 1, + share_constants: false, + }, + ); + let builder = + R::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + let builder = ZeroCheckGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + false, + ); + let builder = FmaGateInBaseFieldWithoutConstant::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<32>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = SelectionGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ParallelSelectionGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = PublicInputGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ReductionGate::<_, 4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = + NopGate::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + + builder + } +} + +impl ZkSyncUniformSynthesisFunction for RAMPermutationInstanceSynthesisFunction +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + type Witness = RamPermutationCircuitInstanceWitness; + type Config = usize; + type RoundFunction = R; + + fn description() -> String { + "RAM permutation".to_string() + } + + fn size_hint() -> (Option, Option) { + ( + Some(TARGET_CIRCUIT_TRACE_LENGTH), + Some((1 << 26) + (1 << 25)), + ) + } + + fn add_tables>(cs: &mut CS) { + let table = create_range_check_table::(); + cs.add_lookup_table::, 1>(table); + } + + fn synthesize_into_cs_inner>( + cs: &mut CS, + witness: Self::Witness, + round_function: &Self::RoundFunction, + config: Self::Config, + ) -> [Num; INPUT_OUTPUT_COMMITMENT_LENGTH] { + ram_permutation_entry_point(cs, witness, round_function, config) + } +} diff --git a/crates/circuit_definitions/src/circuit_definitions/base_layer/secp256r1_verify.rs b/crates/circuit_definitions/src/circuit_definitions/base_layer/secp256r1_verify.rs new file mode 100644 index 0000000..9cdf3d6 --- /dev/null +++ b/crates/circuit_definitions/src/circuit_definitions/base_layer/secp256r1_verify.rs @@ -0,0 +1,173 @@ +use derivative::*; + +use super::*; +use crate::boojum::cs::traits::circuit::CircuitBuilder; + +type F = GoldilocksField; +type R = Poseidon2Goldilocks; + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Copy, Debug, Default(bound = ""))] +pub struct Secp256r1VerifyFunctionInstanceSynthesisFunction { + _marker: std::marker::PhantomData<(F, R)>, +} + +use crate::zkevm_circuits::secp256r1_verify::fixed_base_mul_table::*; +use crate::zkevm_circuits::secp256r1_verify::input::*; +use crate::zkevm_circuits::secp256r1_verify::secp256r1_verify_function_entry_point; + +impl CircuitBuilder for Secp256r1VerifyFunctionInstanceSynthesisFunction +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, +{ + fn geometry() -> CSGeometry { + CSGeometry { + num_columns_under_copy_permutation: 80, + num_witness_columns: 0, + num_constant_columns: 4, + max_allowed_constraint_degree: 8, + } + } + + fn lookup_parameters() -> LookupParameters { + LookupParameters::UseSpecializedColumnsWithTableIdAsConstant { + width: 3, + num_repetitions: 16, + share_table_id: true, + } + } + + fn configure_builder< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + let builder = builder.allow_lookup(>::lookup_parameters()); + + let builder = ConstantsAllocatorGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = BooleanConstraintGate::configure_builder( + builder, + GatePlacementStrategy::UseSpecializedColumns { + num_repetitions: 1, + share_constants: false, + }, + ); + let builder = ZeroCheckGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + false, + ); + let builder = FmaGateInBaseFieldWithoutConstant::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<32>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<16>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<8>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = DotProductGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = SelectionGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ParallelSelectionGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = PublicInputGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ReductionGate::<_, 4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = + NopGate::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + + builder + } +} + +impl ZkSyncUniformSynthesisFunction for Secp256r1VerifyFunctionInstanceSynthesisFunction +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, +{ + type Witness = Secp256r1VerifyCircuitInstanceWitness; + type Config = usize; + type RoundFunction = R; + + fn description() -> String { + "Secp256r1 verify".to_string() + } + + fn size_hint() -> (Option, Option) { + (Some(TARGET_CIRCUIT_TRACE_LENGTH), Some(1 << 26)) + } + + fn add_tables>(cs: &mut CS) { + // let table = create_range_check_table::(); + // cs.add_lookup_table::, 1>(table); + + // let table = create_range_check_16_bits_table::(); + // cs.add_lookup_table::(table); + + let table = create_xor8_table(); + cs.add_lookup_table::(table); + + seq_macro::seq!(C in 0..32 { + let table = create_secp256r1_fixed_base_mul_table::(); + cs.add_lookup_table::, 3>(table); + let table = create_secp256r1_fixed_base_mul_table::(); + cs.add_lookup_table::, 3>(table); + let table = create_secp256r1_fixed_base_mul_table::(); + cs.add_lookup_table::, 3>(table); + let table = create_secp256r1_fixed_base_mul_table::(); + cs.add_lookup_table::, 3>(table); + let table = create_secp256r1_fixed_base_mul_table::(); + cs.add_lookup_table::, 3>(table); + let table = create_secp256r1_fixed_base_mul_table::(); + cs.add_lookup_table::, 3>(table); + let table = create_secp256r1_fixed_base_mul_table::(); + cs.add_lookup_table::, 3>(table); + let table = create_secp256r1_fixed_base_mul_table::(); + cs.add_lookup_table::, 3>(table); + }); + + let table = create_byte_split_table::(); + cs.add_lookup_table::, 3>(table); + } + + fn synthesize_into_cs_inner>( + cs: &mut CS, + witness: Self::Witness, + round_function: &Self::RoundFunction, + config: Self::Config, + ) -> [Num; INPUT_OUTPUT_COMMITMENT_LENGTH] { + secp256r1_verify_function_entry_point(cs, witness, round_function, config) + } +} diff --git a/crates/circuit_definitions/src/circuit_definitions/base_layer/sha256_round_function.rs b/crates/circuit_definitions/src/circuit_definitions/base_layer/sha256_round_function.rs new file mode 100644 index 0000000..96b758e --- /dev/null +++ b/crates/circuit_definitions/src/circuit_definitions/base_layer/sha256_round_function.rs @@ -0,0 +1,145 @@ +use derivative::*; + +use super::*; +use crate::boojum::cs::traits::circuit::CircuitBuilder; + +type F = GoldilocksField; +type R = Poseidon2Goldilocks; + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Copy, Debug, Default(bound = ""))] +pub struct Sha256RoundFunctionInstanceSynthesisFunction { + _marker: std::marker::PhantomData<(F, R)>, +} + +use crate::zkevm_circuits::sha256_round_function::input::*; +use crate::zkevm_circuits::sha256_round_function::sha256_round_function_entry_point; + +impl CircuitBuilder for Sha256RoundFunctionInstanceSynthesisFunction +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, +{ + fn geometry() -> CSGeometry { + CSGeometry { + num_columns_under_copy_permutation: 116, + num_witness_columns: 0, + num_constant_columns: 4, + max_allowed_constraint_degree: 8, + } + } + + fn lookup_parameters() -> LookupParameters { + LookupParameters::UseSpecializedColumnsWithTableIdAsConstant { + width: 4, + num_repetitions: 9, + share_table_id: true, + } + } + + fn configure_builder< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + let builder = builder.allow_lookup(>::lookup_parameters()); + + let builder = ConstantsAllocatorGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = BooleanConstraintGate::configure_builder( + builder, + GatePlacementStrategy::UseSpecializedColumns { + num_repetitions: 1, + share_constants: false, + }, + ); + let builder = FmaGateInBaseFieldWithoutConstant::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ReductionGate::::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = SelectionGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ParallelSelectionGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = PublicInputGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<32>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ZeroCheckGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + false, + ); + + let builder = + NopGate::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + + builder + } +} + +impl ZkSyncUniformSynthesisFunction for Sha256RoundFunctionInstanceSynthesisFunction +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, +{ + type Witness = Sha256RoundFunctionCircuitInstanceWitness; + type Config = usize; + type RoundFunction = R; + + fn description() -> String { + "SHA256 round function".to_string() + } + + fn size_hint() -> (Option, Option) { + (Some(TARGET_CIRCUIT_TRACE_LENGTH), Some(1 << 26)) + } + + fn add_tables>(cs: &mut CS) { + let table = create_tri_xor_table(); + cs.add_lookup_table::(table); + + let table = create_ch4_table(); + cs.add_lookup_table::(table); + + let table = create_maj4_table(); + cs.add_lookup_table::(table); + + let table = create_4bit_chunk_split_table::(); + cs.add_lookup_table::, 4>(table); + + let table = create_4bit_chunk_split_table::(); + cs.add_lookup_table::, 4>(table); + } + + fn synthesize_into_cs_inner>( + cs: &mut CS, + witness: Self::Witness, + round_function: &Self::RoundFunction, + config: Self::Config, + ) -> [Num; INPUT_OUTPUT_COMMITMENT_LENGTH] { + sha256_round_function_entry_point(cs, witness, round_function, config) + } +} diff --git a/crates/circuit_definitions/src/circuit_definitions/base_layer/sort_code_decommits.rs b/crates/circuit_definitions/src/circuit_definitions/base_layer/sort_code_decommits.rs new file mode 100644 index 0000000..6f9c8ce --- /dev/null +++ b/crates/circuit_definitions/src/circuit_definitions/base_layer/sort_code_decommits.rs @@ -0,0 +1,137 @@ +use derivative::*; + +use super::*; +use crate::boojum::cs::traits::circuit::CircuitBuilder; + +type F = GoldilocksField; +type R = Poseidon2Goldilocks; + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Copy, Debug, Default(bound = ""))] +pub struct CodeDecommittmentsSorterSynthesisFunction { + _marker: std::marker::PhantomData<(F, R)>, +} + +use crate::zkevm_circuits::sort_decommittment_requests::input::*; +use crate::zkevm_circuits::sort_decommittment_requests::sort_and_deduplicate_code_decommittments_entry_point; + +impl CircuitBuilder for CodeDecommittmentsSorterSynthesisFunction +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + fn geometry() -> CSGeometry { + CSGeometry { + num_columns_under_copy_permutation: 130, + num_witness_columns: 0, + num_constant_columns: 4, + max_allowed_constraint_degree: 8, + } + } + + fn lookup_parameters() -> LookupParameters { + LookupParameters::UseSpecializedColumnsWithTableIdAsConstant { + width: 1, + num_repetitions: 18, + share_table_id: true, + } + } + + fn configure_builder< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + let builder = builder.allow_lookup(>::lookup_parameters()); + + let builder = ConstantsAllocatorGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = BooleanConstraintGate::configure_builder( + builder, + GatePlacementStrategy::UseSpecializedColumns { + num_repetitions: 1, + share_constants: false, + }, + ); + let builder = + R::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + let builder = ZeroCheckGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + false, + ); + let builder = FmaGateInBaseFieldWithoutConstant::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<32>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = SelectionGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ParallelSelectionGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = PublicInputGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ReductionGate::<_, 4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = + NopGate::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + + builder + } +} + +impl ZkSyncUniformSynthesisFunction for CodeDecommittmentsSorterSynthesisFunction +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + type Witness = CodeDecommittmentsDeduplicatorInstanceWitness; + type Config = usize; + type RoundFunction = R; + + fn description() -> String { + "Decommittment requests sorter".to_string() + } + + fn size_hint() -> (Option, Option) { + ( + Some(TARGET_CIRCUIT_TRACE_LENGTH), + Some((1 << 26) + (1 << 25)), + ) + } + + fn add_tables>(cs: &mut CS) { + let table = create_range_check_table::(); + cs.add_lookup_table::, 1>(table); + } + + fn synthesize_into_cs_inner>( + cs: &mut CS, + witness: Self::Witness, + round_function: &Self::RoundFunction, + config: Self::Config, + ) -> [Num; INPUT_OUTPUT_COMMITMENT_LENGTH] { + sort_and_deduplicate_code_decommittments_entry_point(cs, witness, round_function, config) + } +} diff --git a/crates/circuit_definitions/src/circuit_definitions/base_layer/storage_apply.rs b/crates/circuit_definitions/src/circuit_definitions/base_layer/storage_apply.rs new file mode 100644 index 0000000..fc34257 --- /dev/null +++ b/crates/circuit_definitions/src/circuit_definitions/base_layer/storage_apply.rs @@ -0,0 +1,151 @@ +use derivative::*; + +use super::*; +use crate::boojum::cs::traits::circuit::CircuitBuilder; + +type F = GoldilocksField; +type R = Poseidon2Goldilocks; + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Copy, Debug, Default(bound = ""))] +pub struct StorageApplicationInstanceSynthesisFunction { + _marker: std::marker::PhantomData<(F, R)>, +} + +use crate::zkevm_circuits::storage_application::input::StorageApplicationCircuitInstanceWitness; +use crate::zkevm_circuits::storage_application::storage_applicator_entry_point; + +impl CircuitBuilder for StorageApplicationInstanceSynthesisFunction +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, +{ + fn geometry() -> CSGeometry { + CSGeometry { + num_columns_under_copy_permutation: 60, + num_witness_columns: 0, + num_constant_columns: 4, + max_allowed_constraint_degree: 8, + } + } + + fn lookup_parameters() -> LookupParameters { + LookupParameters::UseSpecializedColumnsWithTableIdAsConstant { + width: 3, + num_repetitions: 26, + share_table_id: true, + } + } + + fn configure_builder< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + let builder = builder.allow_lookup(>::lookup_parameters()); + + let builder = ConstantsAllocatorGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = BooleanConstraintGate::configure_builder( + builder, + GatePlacementStrategy::UseSpecializedColumns { + num_repetitions: 1, + share_constants: false, + }, + ); + + let builder = ZeroCheckGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + false, + ); + let builder = FmaGateInBaseFieldWithoutConstant::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<32>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = U32TriAddCarryAsChunkGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = SelectionGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ParallelSelectionGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = PublicInputGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ReductionGate::<_, 4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = + NopGate::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + + builder + } +} + +impl ZkSyncUniformSynthesisFunction for StorageApplicationInstanceSynthesisFunction +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, +{ + type Witness = StorageApplicationCircuitInstanceWitness; + type Config = usize; + type RoundFunction = R; + + fn description() -> String { + "Storage application".to_string() + } + + fn size_hint() -> (Option, Option) { + (Some(TARGET_CIRCUIT_TRACE_LENGTH), Some(1 << 26)) + } + + fn add_tables>(cs: &mut CS) { + let table = create_xor8_table(); + cs.add_lookup_table::(table); + + let table = create_and8_table(); + cs.add_lookup_table::(table); + + let table = create_byte_split_table::(); + cs.add_lookup_table::, 3>(table); + let table = create_byte_split_table::(); + cs.add_lookup_table::, 3>(table); + let table = create_byte_split_table::(); + cs.add_lookup_table::, 3>(table); + let table = create_byte_split_table::(); + cs.add_lookup_table::, 3>(table); + let table = create_byte_split_table::(); + cs.add_lookup_table::, 3>(table); + } + + fn synthesize_into_cs_inner>( + cs: &mut CS, + witness: Self::Witness, + round_function: &Self::RoundFunction, + config: Self::Config, + ) -> [Num; INPUT_OUTPUT_COMMITMENT_LENGTH] { + storage_applicator_entry_point(cs, witness, round_function, config) + } +} diff --git a/crates/circuit_definitions/src/circuit_definitions/base_layer/storage_sort_dedup.rs b/crates/circuit_definitions/src/circuit_definitions/base_layer/storage_sort_dedup.rs new file mode 100644 index 0000000..8d4728b --- /dev/null +++ b/crates/circuit_definitions/src/circuit_definitions/base_layer/storage_sort_dedup.rs @@ -0,0 +1,139 @@ +use derivative::*; + +use super::*; +use crate::boojum::cs::traits::circuit::CircuitBuilder; + +type F = GoldilocksField; +type R = Poseidon2Goldilocks; + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Copy, Debug, Default(bound = ""))] +pub struct StorageSortAndDedupInstanceSynthesisFunction { + _marker: std::marker::PhantomData<(F, R)>, +} + +use crate::zkevm_circuits::storage_validity_by_grand_product::input::*; +use crate::zkevm_circuits::storage_validity_by_grand_product::sort_and_deduplicate_storage_access_entry_point; + +impl CircuitBuilder for StorageSortAndDedupInstanceSynthesisFunction +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + fn geometry() -> CSGeometry { + CSGeometry { + num_columns_under_copy_permutation: 132, + num_witness_columns: 0, + num_constant_columns: 4, + max_allowed_constraint_degree: 8, + } + } + + fn lookup_parameters() -> LookupParameters { + LookupParameters::UseSpecializedColumnsWithTableIdAsConstant { + width: 1, + num_repetitions: 16, + share_table_id: true, + } + } + + fn configure_builder< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + let builder = builder.allow_lookup(>::lookup_parameters()); + + let builder = ConstantsAllocatorGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = BooleanConstraintGate::configure_builder( + builder, + GatePlacementStrategy::UseSpecializedColumns { + num_repetitions: 1, + share_constants: false, + }, + ); + let builder = + R::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + let builder = ZeroCheckGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + false, + ); + let builder = FmaGateInBaseFieldWithoutConstant::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<32>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = SelectionGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ParallelSelectionGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = PublicInputGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ReductionGate::<_, 4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = + NopGate::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + + builder + } +} + +impl ZkSyncUniformSynthesisFunction for StorageSortAndDedupInstanceSynthesisFunction +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + type Witness = StorageDeduplicatorInstanceWitness; + type Config = usize; + type RoundFunction = R; + + fn description() -> String { + "Storage access sort and dedup".to_string() + } + + fn size_hint() -> (Option, Option) { + ( + Some(TARGET_CIRCUIT_TRACE_LENGTH), + Some((1 << 26) + (1 << 25)), + ) + } + + fn add_tables>(cs: &mut CS) { + let table = create_range_check_table::(); + cs.add_lookup_table::, 1>(table); + } + + fn synthesize_into_cs_inner>( + cs: &mut CS, + witness: Self::Witness, + round_function: &Self::RoundFunction, + config: Self::Config, + ) -> [Num; INPUT_OUTPUT_COMMITMENT_LENGTH] { + sort_and_deduplicate_storage_access_entry_point(cs, witness, round_function, config) + } +} diff --git a/crates/circuit_definitions/src/circuit_definitions/base_layer/transient_storage_sort.rs b/crates/circuit_definitions/src/circuit_definitions/base_layer/transient_storage_sort.rs new file mode 100644 index 0000000..92a53ae --- /dev/null +++ b/crates/circuit_definitions/src/circuit_definitions/base_layer/transient_storage_sort.rs @@ -0,0 +1,144 @@ +use derivative::*; + +use super::*; +use crate::boojum::cs::traits::circuit::CircuitBuilder; + +type F = GoldilocksField; +type R = Poseidon2Goldilocks; + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Copy, Debug, Default(bound = ""))] +pub struct TransientStorageSortAndDedupInstanceSynthesisFunction { + _marker: std::marker::PhantomData<(F, R)>, +} + +use crate::zkevm_circuits::transient_storage_validity_by_grand_product::input::*; +use crate::zkevm_circuits::transient_storage_validity_by_grand_product::sort_and_deduplicate_transient_storage_access_entry_point; + +impl CircuitBuilder for TransientStorageSortAndDedupInstanceSynthesisFunction +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + fn geometry() -> CSGeometry { + CSGeometry { + num_columns_under_copy_permutation: 132, + num_witness_columns: 0, + num_constant_columns: 4, + max_allowed_constraint_degree: 8, + } + } + + fn lookup_parameters() -> LookupParameters { + LookupParameters::UseSpecializedColumnsWithTableIdAsConstant { + width: 1, + num_repetitions: 16, + share_table_id: true, + } + } + + fn configure_builder< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + let builder = builder.allow_lookup(>::lookup_parameters()); + + let builder = ConstantsAllocatorGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = BooleanConstraintGate::configure_builder( + builder, + GatePlacementStrategy::UseSpecializedColumns { + num_repetitions: 1, + share_constants: false, + }, + ); + let builder = + R::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + let builder = ZeroCheckGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + false, + ); + let builder = FmaGateInBaseFieldWithoutConstant::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<32>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = SelectionGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ParallelSelectionGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = PublicInputGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ReductionGate::<_, 4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = + NopGate::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + + builder + } +} + +impl ZkSyncUniformSynthesisFunction for TransientStorageSortAndDedupInstanceSynthesisFunction +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + type Witness = TransientStorageDeduplicatorInstanceWitness; + type Config = usize; + type RoundFunction = R; + + fn description() -> String { + "Transient storage access sort and dedup".to_string() + } + + fn size_hint() -> (Option, Option) { + ( + Some(TARGET_CIRCUIT_TRACE_LENGTH), + Some((1 << 26) + (1 << 25)), + ) + } + + fn add_tables>(cs: &mut CS) { + let table = create_range_check_table::(); + cs.add_lookup_table::, 1>(table); + } + + fn synthesize_into_cs_inner>( + cs: &mut CS, + witness: Self::Witness, + round_function: &Self::RoundFunction, + config: Self::Config, + ) -> [Num; INPUT_OUTPUT_COMMITMENT_LENGTH] { + sort_and_deduplicate_transient_storage_access_entry_point( + cs, + witness, + round_function, + config, + ) + } +} diff --git a/crates/circuit_definitions/src/circuit_definitions/base_layer/vm_main.rs b/crates/circuit_definitions/src/circuit_definitions/base_layer/vm_main.rs new file mode 100644 index 0000000..2636639 --- /dev/null +++ b/crates/circuit_definitions/src/circuit_definitions/base_layer/vm_main.rs @@ -0,0 +1,189 @@ +use derivative::*; + +use super::*; +use crate::aux_definitions::witness_oracle::VmWitnessOracle; +use crate::boojum::cs::traits::circuit::CircuitBuilder; + +type F = GoldilocksField; +type R = Poseidon2Goldilocks; + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Copy, Debug, Default(bound = ""))] +#[serde(bound = "")] +pub struct VmMainInstanceSynthesisFunction { + _marker: std::marker::PhantomData<(F, R)>, +} + +use crate::zkevm_circuits::fsm_input_output::circuit_inputs::main_vm::VmCircuitWitness; +use crate::zkevm_circuits::main_vm::main_vm_entry_point; + +impl CircuitBuilder for VmMainInstanceSynthesisFunction +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + fn geometry() -> CSGeometry { + CSGeometry { + num_columns_under_copy_permutation: 26 * 5, // 26 is a width of u32 FMA gate + num_witness_columns: 0, + num_constant_columns: 4, + max_allowed_constraint_degree: 8, + } + } + + fn lookup_parameters() -> LookupParameters { + LookupParameters::UseSpecializedColumnsWithTableIdAsConstant { + width: 3, + num_repetitions: 8, + share_table_id: true, + } + } + + fn configure_builder< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + let builder = builder.allow_lookup(>::lookup_parameters()); + + let builder = ConstantsAllocatorGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = BooleanConstraintGate::configure_builder( + builder, + GatePlacementStrategy::UseSpecializedColumns { + num_repetitions: 1, + share_constants: false, + }, + ); + let builder = U8x4FMAGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = + R::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + // let builder = SimpleNonlinearityGate::::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + let builder = DotProductGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ZeroCheckGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + false, + ); + let builder = FmaGateInBaseFieldWithoutConstant::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<32>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<16>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<8>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = SelectionGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ParallelSelectionGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = PublicInputGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ReductionGate::<_, 4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = + NopGate::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + + builder + } +} + +impl ZkSyncUniformSynthesisFunction for VmMainInstanceSynthesisFunction +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + type Witness = VmCircuitWitness>; + type Config = usize; + type RoundFunction = R; + + fn description() -> String { + "VM main circuit".to_string() + } + + fn size_hint() -> (Option, Option) { + (Some(TARGET_CIRCUIT_TRACE_LENGTH), Some(1 << 26)) + } + + fn add_tables>(cs: &mut CS) { + let table = create_binop_table(); + cs.add_lookup_table::(table); + + let subpc_to_mask_table = create_subpc_bitmask_table::(); + cs.add_lookup_table::(subpc_to_mask_table); + + let opcode_decoding_table = create_opcodes_decoding_and_pricing_table::(); + cs.add_lookup_table::(opcode_decoding_table); + + let conditions_resolution_table = create_conditionals_resolution_table::(); + cs.add_lookup_table::(conditions_resolution_table); + + let integer_to_bitmask_table = create_integer_to_bitmask_table::( + 15u32.next_power_of_two().trailing_zeros() as usize, + REG_IDX_TO_BITMASK_TABLE_NAME, + ); + cs.add_lookup_table::(integer_to_bitmask_table); + + let shifts_table = create_shift_to_num_converter_table::(); + cs.add_lookup_table::(shifts_table); + + let uma_unaligned_access_table = + create_integer_set_ith_bit_table::(5, UMA_SHIFT_TO_BITMASK_TABLE_NAME); + cs.add_lookup_table::(uma_unaligned_access_table); + + let uma_ptr_read_cleanup_table = create_uma_ptr_read_bitmask_table::(); + cs.add_lookup_table::(uma_ptr_read_cleanup_table); + + let test_bit_table = create_test_bit_table::(); + cs.add_lookup_table::(test_bit_table); + + let stipends_table = create_call_costs_and_stipends_table::(); + cs.add_lookup_table::(stipends_table); + + let pubdata_cost_validity_table = create_pubdata_cost_validity_table::(); + cs.add_lookup_table::(pubdata_cost_validity_table); + } + + fn synthesize_into_cs_inner>( + cs: &mut CS, + witness: Self::Witness, + round_function: &Self::RoundFunction, + config: Self::Config, + ) -> [Num; INPUT_OUTPUT_COMMITMENT_LENGTH] { + main_vm_entry_point(cs, witness, round_function, config) + } +} diff --git a/crates/circuit_definitions/src/circuit_definitions/mod.rs b/crates/circuit_definitions/src/circuit_definitions/mod.rs new file mode 100644 index 0000000..25dcc3b --- /dev/null +++ b/crates/circuit_definitions/src/circuit_definitions/mod.rs @@ -0,0 +1,235 @@ +use crate::boojum::algebraic_props::round_function::AlgebraicRoundFunction; +use crate::boojum::cs::cs_builder::*; +use crate::boojum::cs::traits::cs::ConstraintSystem; +use crate::boojum::cs::CSGeometry; +use crate::boojum::cs::*; +use crate::boojum::field::SmallField; +use crate::boojum::gadgets::num::Num; +use crate::boojum::gadgets::traits::allocatable::*; +use crate::boojum::gadgets::traits::round_function::*; +use crate::boojum::gadgets::traits::witnessable::WitnessHookable; +use crate::boojum::gadgets::u256::UInt256; +use crate::boojum::implementations::poseidon2::Poseidon2Goldilocks; +use circuit_encodings::zkevm_circuits::{ + base_structures::{ + decommit_query::DecommitQuery, log_query::LogQuery, memory_query::MemoryQuery, + vm_state::saved_context::ExecutionContextRecord, + }, + fsm_input_output::circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH, + storage_validity_by_grand_product::TimestampedStorageLogRecord, +}; +use crossbeam::atomic::AtomicCell; + +pub mod aux_layer; +pub mod base_layer; +pub mod recursion_layer; +pub mod verifier_builder; + +pub trait ZkSyncUniformSynthesisFunction: + crate::boojum::cs::traits::circuit::CircuitBuilder + + 'static + + Clone + + serde::Serialize + + serde::de::DeserializeOwned +{ + type Witness: Clone + + std::fmt::Debug + + serde::Serialize + + serde::de::DeserializeOwned + + std::default::Default; + type Config: Clone + std::fmt::Debug + serde::Serialize + serde::de::DeserializeOwned; + type RoundFunction: BuildableCircuitRoundFunction + + AlgebraicRoundFunction + + serde::Serialize + + serde::de::DeserializeOwned; + + fn description() -> String; + + fn size_hint() -> (Option, Option) { + (Some(1 << 20), Some(1 << 26)) + } + + fn add_tables>(cs: &mut CS); + + fn synthesize_into_cs_inner>( + cs: &mut CS, + witness: Self::Witness, + round_function: &Self::RoundFunction, + config: Self::Config, + ) -> [Num; INPUT_OUTPUT_COMMITMENT_LENGTH]; + + // fn get_synthesis_function_dyn< + // 'a, + // CS: ConstraintSystem + 'a, + // >() -> Box [Num; INPUT_OUTPUT_COMMITMENT_LENGTH] + 'a> + // where Self: 'a { + // Box::new(Self::synthesize_into_cs_inner) + // } +} + +#[derive(serde::Serialize, serde::Deserialize)] +#[serde(bound = "")] +pub struct ZkSyncUniformCircuitInstance> { + #[serde(serialize_with = "serialize_atomic_cell")] + #[serde(deserialize_with = "deserialize_atomic_cell")] + pub witness: AtomicCell>, + #[serde(serialize_with = "serialize_arc")] + #[serde(deserialize_with = "deserialize_arc")] + pub config: std::sync::Arc, + #[serde(serialize_with = "serialize_arc")] + #[serde(deserialize_with = "deserialize_arc")] + #[serde(bound(serialize = "S::RoundFunction: serde::Serialize"))] + #[serde(bound(deserialize = "S::RoundFunction: serde::de::DeserializeOwned"))] + pub round_function: std::sync::Arc, + + pub expected_public_input: Option<[F; INPUT_OUTPUT_COMMITMENT_LENGTH]>, +} + +impl> ZkSyncUniformCircuitInstance { + pub fn new( + witness: Option, + config: S::Config, + round_function: S::RoundFunction, + expected_public_input: Option<[F; INPUT_OUTPUT_COMMITMENT_LENGTH]>, + ) -> Self { + Self { + witness: AtomicCell::new(witness), + config: std::sync::Arc::new(config), + round_function: std::sync::Arc::new(round_function), + expected_public_input, + } + } + + pub fn debug_witness(&self) { + let wit = self.witness.take(); + dbg!(&wit); + self.witness.store(wit); + } + + pub fn clone_witness(&self) -> Option { + let wit = self.witness.take(); + let ww = wit.clone(); + self.witness.store(wit); + + ww + } + + pub fn erase_witness(&self) { + let _ = self.witness.take(); + } + + pub fn geometry_proxy(&self) -> CSGeometry { + S::geometry() + } + + pub fn size_hint(&self) -> (Option, Option) { + S::size_hint() + } + + pub fn synthesize_proxy>(self, cs: &mut CS) { + let Self { + witness, + config, + round_function, + expected_public_input, + } = self; + let witness = witness.take(); + let ww = witness.unwrap_or_default(); + let config: S::Config = (*config).clone(); + let public_input_var = S::synthesize_into_cs_inner(cs, ww, &round_function, config); + + if let Some(expected_input) = expected_public_input.as_ref() { + if let Some(wit_value) = public_input_var.witness_hook(&*cs)() { + assert_eq!( + *expected_input, wit_value, + "we expected public input to be {:?}, but circuit returned {:?}", + expected_input, wit_value + ); + } + } + } + + pub fn add_tables_proxy>(&self, cs: &mut CS) { + S::add_tables(cs); + } + + pub fn configure_builder_proxy< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + &self, + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + S::configure_builder(builder) + } +} + +fn serialize_atomic_cell( + t: &AtomicCell>, + serializer: S, +) -> Result +where + S: serde::Serializer, +{ + let el = t.take(); + let res = match &el { + Some(el) => serializer.serialize_some(el), + None => serializer.serialize_none(), + }; + + t.store(el); + + res +} + +fn serialize_arc( + t: &std::sync::Arc, + serializer: S, +) -> Result +where + S: serde::Serializer, +{ + (*t).serialize(serializer) +} + +fn deserialize_atomic_cell<'de, D, T: serde::Deserialize<'de>>( + deserializer: D, +) -> Result, D::Error> +where + D: serde::Deserializer<'de>, +{ + let res = T::deserialize(deserializer)?; + let cell = AtomicCell::new(res); + + Ok(cell) +} + +fn deserialize_arc<'de, D, T: serde::Deserialize<'de>>( + deserializer: D, +) -> Result, D::Error> +where + D: serde::Deserializer<'de>, +{ + let res = T::deserialize(deserializer)?; + let arc = std::sync::Arc::new(res); + + Ok(arc) +} + +impl> Clone + for ZkSyncUniformCircuitInstance +{ + fn clone(&self) -> Self { + let wit = self.witness.take(); + let ww = wit.clone(); + self.witness.store(wit); + + Self { + witness: AtomicCell::new(ww), + config: std::sync::Arc::clone(&self.config), + round_function: std::sync::Arc::clone(&self.round_function), + expected_public_input: self.expected_public_input.clone(), + } + } +} diff --git a/crates/circuit_definitions/src/circuit_definitions/recursion_layer/circuit_def.rs b/crates/circuit_definitions/src/circuit_definitions/recursion_layer/circuit_def.rs new file mode 100644 index 0000000..f3115c2 --- /dev/null +++ b/crates/circuit_definitions/src/circuit_definitions/recursion_layer/circuit_def.rs @@ -0,0 +1,138 @@ +use crate::boojum::cs::cs_builder::*; +use crate::boojum::cs::*; +use crate::boojum::field::goldilocks::{GoldilocksExt2, GoldilocksField}; +use crate::boojum::gadgets::traits::round_function::BuildableCircuitRoundFunction; +use crate::boojum::implementations::poseidon2::Poseidon2Goldilocks; + +type F = GoldilocksField; +type R = Poseidon2Goldilocks; +type EXT = GoldilocksExt2; + +use crate::boojum::cs::gates::*; +use crate::boojum::cs::traits::gate::GatePlacementStrategy; + +pub fn geometry_for_recursion_step() -> CSGeometry { + CSGeometry { + num_columns_under_copy_permutation: 140, + num_witness_columns: 0, + num_constant_columns: 4, + max_allowed_constraint_degree: 8, + } +} + +pub fn lookup_parameters_recursion_step() -> LookupParameters { + LookupParameters::NoLookup +} + +pub fn configure_builder_recursion_step< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, +>( + builder: CsBuilder, +) -> CsBuilder, impl StaticToolboxHolder> { + // let builder = builder.allow_lookup(>::lookup_parameters()); + + let builder = ConstantsAllocatorGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = BooleanConstraintGate::configure_builder( + builder, + GatePlacementStrategy::UseSpecializedColumns { + num_repetitions: 1, + share_constants: false, + }, + ); + let builder = R::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + let builder = ZeroCheckGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + false, + ); + let builder = FmaGateInBaseFieldWithoutConstant::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = FmaGateInExtensionWithoutConstant::::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<32>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = + SelectionGate::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + let builder = ParallelSelectionGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = PublicInputGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ReductionGate::<_, 4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = + NopGate::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + + builder +} + +// recursion tip is simple and doesnt' need integer ops +pub fn configure_builder_recursion_tip< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, +>( + builder: CsBuilder, +) -> CsBuilder, impl StaticToolboxHolder> { + // let builder = builder.allow_lookup(>::lookup_parameters()); + + let builder = ConstantsAllocatorGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = BooleanConstraintGate::configure_builder( + builder, + GatePlacementStrategy::UseSpecializedColumns { + num_repetitions: 1, + share_constants: false, + }, + ); + let builder = R::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + let builder = ZeroCheckGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + false, + ); + let builder = FmaGateInBaseFieldWithoutConstant::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = FmaGateInExtensionWithoutConstant::::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = + SelectionGate::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + let builder = ParallelSelectionGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = PublicInputGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ReductionGate::<_, 4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = + NopGate::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + + builder +} diff --git a/crates/circuit_definitions/src/circuit_definitions/recursion_layer/leaf_layer.rs b/crates/circuit_definitions/src/circuit_definitions/recursion_layer/leaf_layer.rs new file mode 100644 index 0000000..e95a574 --- /dev/null +++ b/crates/circuit_definitions/src/circuit_definitions/recursion_layer/leaf_layer.rs @@ -0,0 +1,162 @@ +use crate::boojum::cs::implementations::pow::NoPow; +use crate::zkevm_circuits::boojum::cs::gates::PublicInputGate; +use derivative::*; + +use super::circuit_def::*; +use crate::boojum::cs::implementations::transcript::GoldilocksPoisedon2Transcript; +use crate::boojum::cs::implementations::transcript::Transcript; +use crate::boojum::gadgets::recursion::circuit_pow::*; +use crate::circuit_definitions::base_layer::TARGET_CIRCUIT_TRACE_LENGTH; +use crate::zkevm_circuits::{ + base_structures::recursion_query::RecursionQuery, + recursion::leaf_layer::{input::*, *}, +}; + +use super::*; + +type F = GoldilocksField; +type TR = GoldilocksPoisedon2Transcript; +type R = Poseidon2Goldilocks; +type CTR = CircuitAlgebraicSpongeBasedTranscript; +type EXT = GoldilocksExt2; +type H = GoldilocksPoseidon2Sponge; +type RH = CircuitGoldilocksPoseidon2Sponge; + +/// Leaf layer circuit is aggreagating a bunch (in practice 32) basic circuits of the same type into one. +/// The code in this file is the 'outer' stage - the actual code for the circuit is in +/// ``leaf_layer_recursion_entry_point`` in era-zkevm_circuits repo. +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Debug(bound = ""))] +#[serde(bound = "")] +pub struct LeafLayerRecursiveCircuit> { + pub witness: RecursionLeafInstanceWitness, + pub config: LeafLayerRecursionConfig, + pub transcript_params: >::TransciptParameters, + pub base_layer_circuit_type: BaseLayerCircuitType, + pub _marker: std::marker::PhantomData<(R, POW)>, +} + +impl> crate::boojum::cs::traits::circuit::CircuitBuilder + for LeafLayerRecursiveCircuit +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + fn geometry() -> CSGeometry { + geometry_for_recursion_step() + } + + fn lookup_parameters() -> LookupParameters { + lookup_parameters_recursion_step() + } + + fn configure_builder< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + configure_builder_recursion_step(builder) + } +} + +impl> LeafLayerRecursiveCircuit +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + pub fn description(&self) -> String { + format!( + "Leaf layer circuit for circuit id {}", + self.base_layer_circuit_type as u8 + ) + } + + /// Returns maximum trace length, and number of variables. + pub fn size_hint(&self) -> (Option, Option) { + ( + Some(TARGET_CIRCUIT_TRACE_LENGTH), + Some((1 << 26) + (1 << 25)), + ) + } + + pub fn configure_builder_proxy< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + &self, + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + >::configure_builder(builder) + } + + pub fn add_tables>(&self, _cs: &mut CS) {} + + pub fn synthesize_into_cs + 'static>( + self, + cs: &mut CS, + round_function: &R, + ) -> [Num; INPUT_OUTPUT_COMMITMENT_LENGTH] { + let Self { + witness, + config, + transcript_params, + .. + } = self; + + use crate::circuit_definitions::verifier_builder::dyn_recursive_verifier_builder_for_circuit_type; + let verifier_builder = dyn_recursive_verifier_builder_for_circuit_type::( + self.base_layer_circuit_type as u8, + ); + + // reserve enough fixed locations for public inputs + for _ in 0..INPUT_OUTPUT_COMMITMENT_LENGTH { + PublicInputGate::reserve_public_input_location(cs); + } + + let input_commitments = leaf_layer_recursion_entry_point::( + cs, + witness, + round_function, + config, + verifier_builder, + transcript_params, + ); + + // use reserved_locations + for el in input_commitments.iter() { + PublicInputGate::use_reserved_public_input_location(cs, el.get_variable()) + } + + input_commitments + } +} + +pub type ZkSyncLeafLayerRecursiveCircuit = LeafLayerRecursiveCircuit< + // GoldilocksField, + // GoldilocksExt2, + // ZkSyncDefaultRoundFunction, + // CircuitGoldilocksPoseidon2Sponge, + // GoldilocksPoisedon2Transcript, + // CircuitAlgebraicSpongeBasedTranscript, + NoPow, +>; + +use crate::boojum::cs::traits::circuit::CircuitBuilderProxy; + +pub type LeafLayerCircuitBuilder = CircuitBuilderProxy>; +pub type ConcreteLeafLayerCircuitBuilder = LeafLayerCircuitBuilder; diff --git a/crates/circuit_definitions/src/circuit_definitions/recursion_layer/mod.rs b/crates/circuit_definitions/src/circuit_definitions/recursion_layer/mod.rs new file mode 100644 index 0000000..996e330 --- /dev/null +++ b/crates/circuit_definitions/src/circuit_definitions/recursion_layer/mod.rs @@ -0,0 +1,918 @@ +use std::iter::once; + +use super::*; +use crate::boojum::cs::implementations::proof::Proof; +use crate::boojum::field::goldilocks::{GoldilocksExt2, GoldilocksField}; +use crate::boojum::gadgets::recursion::recursive_transcript::CircuitAlgebraicSpongeBasedTranscript; +use crate::boojum::gadgets::recursion::recursive_tree_hasher::CircuitGoldilocksPoseidon2Sponge; +use crate::zkevm_circuits::{ + base_structures::vm_state::saved_context::ExecutionContextRecord, + boojum::cs::traits::circuit::CircuitBuilder, + recursion::leaf_layer::input::RecursionLeafParametersWitness, + scheduler::aux::BaseLayerCircuitType, + storage_validity_by_grand_product::TimestampedStorageLogRecord, +}; +use snark_wrapper::boojum::config::CSConfig; +use snark_wrapper::boojum::dag::{CircuitResolver, StCircuitResolver}; + +pub mod circuit_def; +pub mod leaf_layer; +pub mod node_layer; +pub mod recursion_tip; +pub mod scheduler; +pub mod verifier_builder; + +use self::leaf_layer::*; +use self::node_layer::*; +use self::recursion_tip::*; +use self::scheduler::*; + +pub const RECURSION_ARITY: usize = 32; +// Maximum amount of basic circuits that a scheduler can handle. +// The value was selected in such a way, that the scheduler circuit +// fits into 2^20 trace size (currently it uses around 1'043'000) +// The quick approximate way to see how many locations are used, is to look at the public_input_locations +// in the recursion_layer/vk_1.json (which is a VK for this circuit). +// This value must be below the domain size (which is currently 1048576). +// And with the current scheduler code, and SCHEDULER_CAPACITY set to 34100, the value is 1043851. +pub const SCHEDULER_CAPACITY: usize = 34100; + +pub use crate::zkevm_circuits::recursion::recursion_tip::input::RECURSION_TIP_ARITY; + +#[derive(derivative::Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone(bound = ""))] +#[serde(bound = "")] +pub enum ZkSyncRecursiveLayerCircuit { + SchedulerCircuit(ZkSyncSchedulerCircuit), + NodeLayerCircuit(ZkSyncNodeLayerRecursiveCircuit), + LeafLayerCircuitForMainVM(ZkSyncLeafLayerRecursiveCircuit), + LeafLayerCircuitForCodeDecommittmentsSorter(ZkSyncLeafLayerRecursiveCircuit), + LeafLayerCircuitForCodeDecommitter(ZkSyncLeafLayerRecursiveCircuit), + LeafLayerCircuitForLogDemuxer(ZkSyncLeafLayerRecursiveCircuit), + LeafLayerCircuitForKeccakRoundFunction(ZkSyncLeafLayerRecursiveCircuit), + LeafLayerCircuitForSha256RoundFunction(ZkSyncLeafLayerRecursiveCircuit), + LeafLayerCircuitForECRecover(ZkSyncLeafLayerRecursiveCircuit), + LeafLayerCircuitForRAMPermutation(ZkSyncLeafLayerRecursiveCircuit), + LeafLayerCircuitForStorageSorter(ZkSyncLeafLayerRecursiveCircuit), + LeafLayerCircuitForStorageApplication(ZkSyncLeafLayerRecursiveCircuit), + LeafLayerCircuitForEventsSorter(ZkSyncLeafLayerRecursiveCircuit), + LeafLayerCircuitForL1MessagesSorter(ZkSyncLeafLayerRecursiveCircuit), + LeafLayerCircuitForL1MessagesHasher(ZkSyncLeafLayerRecursiveCircuit), + LeafLayerCircuitForTransientStorageSorter(ZkSyncLeafLayerRecursiveCircuit), + LeafLayerCircuitForSecp256r1Verify(ZkSyncLeafLayerRecursiveCircuit), + LeafLayerCircuitForEIP4844Repack(ZkSyncLeafLayerRecursiveCircuit), + RecursionTipCircuit(ZkSyncRecursionTipCircuit), +} + +#[derive(derivative::Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone(bound = ""), Copy, Debug)] +#[serde(bound = "")] +#[repr(u8)] +pub enum ZkSyncRecursionLayerStorageType { + SchedulerCircuit = 1, + NodeLayerCircuit = 2, + LeafLayerCircuitForMainVM = 3, + LeafLayerCircuitForCodeDecommittmentsSorter = 4, + LeafLayerCircuitForCodeDecommitter = 5, + LeafLayerCircuitForLogDemuxer = 6, + LeafLayerCircuitForKeccakRoundFunction = 7, + LeafLayerCircuitForSha256RoundFunction = 8, + LeafLayerCircuitForECRecover = 9, + LeafLayerCircuitForRAMPermutation = 10, + LeafLayerCircuitForStorageSorter = 11, + LeafLayerCircuitForStorageApplication = 12, + LeafLayerCircuitForEventsSorter = 13, + LeafLayerCircuitForL1MessagesSorter = 14, + LeafLayerCircuitForL1MessagesHasher = 15, + LeafLayerCircuitForTransientStorageSorter = 16, + LeafLayerCircuitForSecp256r1Verify = 17, + LeafLayerCircuitForEIP4844Repack = 18, + RecursionTipCircuit = 255, +} + +impl ZkSyncRecursionLayerStorageType { + pub fn as_iter_u8() -> impl Iterator { + (ZkSyncRecursionLayerStorageType::SchedulerCircuit as u8 + ..=ZkSyncRecursionLayerStorageType::NodeLayerCircuit as u8) + .chain(Self::leafs_as_iter_u8()) + .chain(once( + ZkSyncRecursionLayerStorageType::RecursionTipCircuit as u8, + )) + } + + pub fn leafs_as_iter_u8() -> impl Iterator { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForMainVM as u8 + ..=ZkSyncRecursionLayerStorageType::LeafLayerCircuitForEIP4844Repack as u8 + } + + pub fn from_leaf_u8_to_basic_u8(value: u8) -> u8 { + match value { + a if a == Self::LeafLayerCircuitForMainVM as u8 => BaseLayerCircuitType::VM as u8, + a if a == Self::LeafLayerCircuitForCodeDecommittmentsSorter as u8 => { + BaseLayerCircuitType::DecommitmentsFilter as u8 + } + a if a == Self::LeafLayerCircuitForCodeDecommitter as u8 => { + BaseLayerCircuitType::Decommiter as u8 + } + a if a == Self::LeafLayerCircuitForLogDemuxer as u8 => { + BaseLayerCircuitType::LogDemultiplexer as u8 + } + a if a == Self::LeafLayerCircuitForKeccakRoundFunction as u8 => { + BaseLayerCircuitType::KeccakPrecompile as u8 + } + a if a == Self::LeafLayerCircuitForSha256RoundFunction as u8 => { + BaseLayerCircuitType::Sha256Precompile as u8 + } + a if a == Self::LeafLayerCircuitForECRecover as u8 => { + BaseLayerCircuitType::EcrecoverPrecompile as u8 + } + a if a == Self::LeafLayerCircuitForRAMPermutation as u8 => { + BaseLayerCircuitType::RamValidation as u8 + } + a if a == Self::LeafLayerCircuitForStorageSorter as u8 => { + BaseLayerCircuitType::StorageFilter as u8 + } + a if a == Self::LeafLayerCircuitForStorageApplication as u8 => { + BaseLayerCircuitType::StorageApplicator as u8 + } + a if a == Self::LeafLayerCircuitForEventsSorter as u8 => { + BaseLayerCircuitType::EventsRevertsFilter as u8 + } + a if a == Self::LeafLayerCircuitForL1MessagesSorter as u8 => { + BaseLayerCircuitType::L1MessagesRevertsFilter as u8 + } + a if a == Self::LeafLayerCircuitForL1MessagesHasher as u8 => { + BaseLayerCircuitType::L1MessagesHasher as u8 + } + a if a == Self::LeafLayerCircuitForTransientStorageSorter as u8 => { + BaseLayerCircuitType::TransientStorageChecker as u8 + } + a if a == Self::LeafLayerCircuitForSecp256r1Verify as u8 => { + BaseLayerCircuitType::Secp256r1Verify as u8 + } + a if a == Self::LeafLayerCircuitForEIP4844Repack as u8 => { + BaseLayerCircuitType::EIP4844Repack as u8 + } + _ => { + panic!( + "could not map recursive circuit type {} to a basic circuit", + value + ) + } + } + } +} + +#[derive(derivative::Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone(bound = ""), Debug)] +#[serde(bound = "")] +#[repr(u8)] +pub enum ZkSyncRecursionLayerStorage< + T: Clone + std::fmt::Debug + serde::Serialize + serde::de::DeserializeOwned, +> { + SchedulerCircuit(T) = 1, + NodeLayerCircuit(T) = 2, + LeafLayerCircuitForMainVM(T) = 3, + LeafLayerCircuitForCodeDecommittmentsSorter(T) = 4, + LeafLayerCircuitForCodeDecommitter(T) = 5, + LeafLayerCircuitForLogDemuxer(T) = 6, + LeafLayerCircuitForKeccakRoundFunction(T) = 7, + LeafLayerCircuitForSha256RoundFunction(T) = 8, + LeafLayerCircuitForECRecover(T) = 9, + LeafLayerCircuitForRAMPermutation(T) = 10, + LeafLayerCircuitForStorageSorter(T) = 11, + LeafLayerCircuitForStorageApplication(T) = 12, + LeafLayerCircuitForEventsSorter(T) = 13, + LeafLayerCircuitForL1MessagesSorter(T) = 14, + LeafLayerCircuitForL1MessagesHasher(T) = 15, + LeafLayerCircuitForTransientStorageSorter(T) = 16, + LeafLayerCircuitForSecp256r1Verify(T) = 17, + LeafLayerCircuitForEIP4844Repack(T) = 18, + RecursionTipCircuit(T) = 255, +} + +impl + ZkSyncRecursionLayerStorage +{ + pub fn short_description(&self) -> &'static str { + match &self { + ZkSyncRecursionLayerStorage::SchedulerCircuit(..) => "Scheduler", + ZkSyncRecursionLayerStorage::NodeLayerCircuit(..) => "Node", + ZkSyncRecursionLayerStorage::LeafLayerCircuitForMainVM(..) => "Leaf for Main VM", + ZkSyncRecursionLayerStorage::LeafLayerCircuitForCodeDecommittmentsSorter(..) => { + "Leaf for Decommitts sorter" + } + ZkSyncRecursionLayerStorage::LeafLayerCircuitForCodeDecommitter(..) => { + "Leaf for Code decommitter" + } + ZkSyncRecursionLayerStorage::LeafLayerCircuitForLogDemuxer(..) => { + "Leaf for Log demuxer" + } + ZkSyncRecursionLayerStorage::LeafLayerCircuitForKeccakRoundFunction(..) => { + "Leaf for Keccak" + } + ZkSyncRecursionLayerStorage::LeafLayerCircuitForSha256RoundFunction(..) => { + "Leaf for SHA256" + } + ZkSyncRecursionLayerStorage::LeafLayerCircuitForECRecover(..) => "Leaf for ECRecover", + ZkSyncRecursionLayerStorage::LeafLayerCircuitForRAMPermutation(..) => { + "Leaf for RAM permutation" + } + ZkSyncRecursionLayerStorage::LeafLayerCircuitForStorageSorter(..) => { + "Leaf for Storage sorter" + } + ZkSyncRecursionLayerStorage::LeafLayerCircuitForStorageApplication(..) => { + "Leaf for Storage application" + } + ZkSyncRecursionLayerStorage::LeafLayerCircuitForEventsSorter(..) => { + "Leaf for Events sorter" + } + ZkSyncRecursionLayerStorage::LeafLayerCircuitForL1MessagesSorter(..) => { + "Leaf for L1 messages sorter" + } + ZkSyncRecursionLayerStorage::LeafLayerCircuitForL1MessagesHasher(..) => { + "Leaf for L1 messages hasher" + } + ZkSyncRecursionLayerStorage::LeafLayerCircuitForTransientStorageSorter(..) => { + "Leaf for Transient storage sorter" + } + ZkSyncRecursionLayerStorage::LeafLayerCircuitForSecp256r1Verify(..) => { + "Leaf for Secp256r1 verify" + } + ZkSyncRecursionLayerStorage::LeafLayerCircuitForEIP4844Repack(..) => { + "Leaf for EIP4844 repack" + } + ZkSyncRecursionLayerStorage::RecursionTipCircuit(..) => "Recursion tip", + } + } + + pub fn numeric_circuit_type(&self) -> u8 { + match &self { + ZkSyncRecursionLayerStorage::SchedulerCircuit(..) => { + ZkSyncRecursionLayerStorageType::SchedulerCircuit as u8 + } + ZkSyncRecursionLayerStorage::NodeLayerCircuit(..) => { + ZkSyncRecursionLayerStorageType::NodeLayerCircuit as u8 + } + ZkSyncRecursionLayerStorage::LeafLayerCircuitForMainVM(..) => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForMainVM as u8 + } + ZkSyncRecursionLayerStorage::LeafLayerCircuitForCodeDecommittmentsSorter(..) => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForCodeDecommittmentsSorter as u8 + } + ZkSyncRecursionLayerStorage::LeafLayerCircuitForCodeDecommitter(..) => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForCodeDecommitter as u8 + } + ZkSyncRecursionLayerStorage::LeafLayerCircuitForLogDemuxer(..) => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForLogDemuxer as u8 + } + ZkSyncRecursionLayerStorage::LeafLayerCircuitForKeccakRoundFunction(..) => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForKeccakRoundFunction as u8 + } + ZkSyncRecursionLayerStorage::LeafLayerCircuitForSha256RoundFunction(..) => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForSha256RoundFunction as u8 + } + ZkSyncRecursionLayerStorage::LeafLayerCircuitForECRecover(..) => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForECRecover as u8 + } + ZkSyncRecursionLayerStorage::LeafLayerCircuitForRAMPermutation(..) => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForRAMPermutation as u8 + } + ZkSyncRecursionLayerStorage::LeafLayerCircuitForStorageSorter(..) => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForStorageSorter as u8 + } + ZkSyncRecursionLayerStorage::LeafLayerCircuitForStorageApplication(..) => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForStorageApplication as u8 + } + ZkSyncRecursionLayerStorage::LeafLayerCircuitForEventsSorter(..) => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForEventsSorter as u8 + } + ZkSyncRecursionLayerStorage::LeafLayerCircuitForL1MessagesSorter(..) => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForL1MessagesSorter as u8 + } + ZkSyncRecursionLayerStorage::LeafLayerCircuitForL1MessagesHasher(..) => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForL1MessagesHasher as u8 + } + ZkSyncRecursionLayerStorage::LeafLayerCircuitForTransientStorageSorter(..) => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForTransientStorageSorter as u8 + } + ZkSyncRecursionLayerStorage::LeafLayerCircuitForSecp256r1Verify(..) => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForSecp256r1Verify as u8 + } + ZkSyncRecursionLayerStorage::LeafLayerCircuitForEIP4844Repack(..) => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForEIP4844Repack as u8 + } + ZkSyncRecursionLayerStorage::RecursionTipCircuit(..) => { + ZkSyncRecursionLayerStorageType::RecursionTipCircuit as u8 + } + } + } + + pub fn into_inner(self) -> T { + match self { + Self::SchedulerCircuit(inner) => inner, + Self::NodeLayerCircuit(inner) => inner, + Self::LeafLayerCircuitForMainVM(inner) => inner, + Self::LeafLayerCircuitForCodeDecommittmentsSorter(inner) => inner, + Self::LeafLayerCircuitForCodeDecommitter(inner) => inner, + Self::LeafLayerCircuitForLogDemuxer(inner) => inner, + Self::LeafLayerCircuitForKeccakRoundFunction(inner) => inner, + Self::LeafLayerCircuitForSha256RoundFunction(inner) => inner, + Self::LeafLayerCircuitForECRecover(inner) => inner, + Self::LeafLayerCircuitForRAMPermutation(inner) => inner, + Self::LeafLayerCircuitForStorageSorter(inner) => inner, + Self::LeafLayerCircuitForStorageApplication(inner) => inner, + Self::LeafLayerCircuitForEventsSorter(inner) => inner, + Self::LeafLayerCircuitForL1MessagesSorter(inner) => inner, + Self::LeafLayerCircuitForL1MessagesHasher(inner) => inner, + Self::LeafLayerCircuitForTransientStorageSorter(inner) => inner, + Self::LeafLayerCircuitForSecp256r1Verify(inner) => inner, + Self::LeafLayerCircuitForEIP4844Repack(inner) => inner, + Self::RecursionTipCircuit(inner) => inner, + } + } + + pub fn from_inner(numeric_type: u8, inner: T) -> Self { + match numeric_type { + a if a == ZkSyncRecursionLayerStorageType::SchedulerCircuit as u8 => { + Self::SchedulerCircuit(inner) + } + a if a == ZkSyncRecursionLayerStorageType::NodeLayerCircuit as u8 => { + Self::NodeLayerCircuit(inner) + } + a if a == ZkSyncRecursionLayerStorageType::LeafLayerCircuitForMainVM as u8 => { + Self::LeafLayerCircuitForMainVM(inner) + } + a if a + == ZkSyncRecursionLayerStorageType::LeafLayerCircuitForCodeDecommittmentsSorter + as u8 => + { + Self::LeafLayerCircuitForCodeDecommittmentsSorter(inner) + } + a if a == ZkSyncRecursionLayerStorageType::LeafLayerCircuitForCodeDecommitter as u8 => { + Self::LeafLayerCircuitForCodeDecommitter(inner) + } + a if a == ZkSyncRecursionLayerStorageType::LeafLayerCircuitForLogDemuxer as u8 => { + Self::LeafLayerCircuitForLogDemuxer(inner) + } + a if a + == ZkSyncRecursionLayerStorageType::LeafLayerCircuitForKeccakRoundFunction + as u8 => + { + Self::LeafLayerCircuitForKeccakRoundFunction(inner) + } + a if a + == ZkSyncRecursionLayerStorageType::LeafLayerCircuitForSha256RoundFunction + as u8 => + { + Self::LeafLayerCircuitForSha256RoundFunction(inner) + } + a if a == ZkSyncRecursionLayerStorageType::LeafLayerCircuitForECRecover as u8 => { + Self::LeafLayerCircuitForECRecover(inner) + } + a if a == ZkSyncRecursionLayerStorageType::LeafLayerCircuitForRAMPermutation as u8 => { + Self::LeafLayerCircuitForRAMPermutation(inner) + } + a if a == ZkSyncRecursionLayerStorageType::LeafLayerCircuitForStorageSorter as u8 => { + Self::LeafLayerCircuitForStorageSorter(inner) + } + a if a + == ZkSyncRecursionLayerStorageType::LeafLayerCircuitForStorageApplication as u8 => + { + Self::LeafLayerCircuitForStorageApplication(inner) + } + a if a == ZkSyncRecursionLayerStorageType::LeafLayerCircuitForEventsSorter as u8 => { + Self::LeafLayerCircuitForEventsSorter(inner) + } + a if a + == ZkSyncRecursionLayerStorageType::LeafLayerCircuitForL1MessagesSorter as u8 => + { + Self::LeafLayerCircuitForL1MessagesSorter(inner) + } + a if a + == ZkSyncRecursionLayerStorageType::LeafLayerCircuitForL1MessagesHasher as u8 => + { + Self::LeafLayerCircuitForL1MessagesHasher(inner) + } + a if a + == ZkSyncRecursionLayerStorageType::LeafLayerCircuitForTransientStorageSorter + as u8 => + { + Self::LeafLayerCircuitForTransientStorageSorter(inner) + } + a if a == ZkSyncRecursionLayerStorageType::LeafLayerCircuitForSecp256r1Verify as u8 => { + Self::LeafLayerCircuitForSecp256r1Verify(inner) + } + a if a == ZkSyncRecursionLayerStorageType::LeafLayerCircuitForEIP4844Repack as u8 => { + Self::LeafLayerCircuitForEIP4844Repack(inner) + } + a if a == ZkSyncRecursionLayerStorageType::RecursionTipCircuit as u8 => { + Self::RecursionTipCircuit(inner) + } + a @ _ => panic!("unknown numeric type {}", a), + } + } + + pub fn leaf_circuit_from_base_type(base_type: BaseLayerCircuitType, inner: T) -> Self { + match base_type { + BaseLayerCircuitType::VM => Self::LeafLayerCircuitForMainVM(inner), + BaseLayerCircuitType::DecommitmentsFilter => { + Self::LeafLayerCircuitForCodeDecommittmentsSorter(inner) + } + BaseLayerCircuitType::Decommiter => Self::LeafLayerCircuitForCodeDecommitter(inner), + BaseLayerCircuitType::LogDemultiplexer => Self::LeafLayerCircuitForLogDemuxer(inner), + BaseLayerCircuitType::KeccakPrecompile => { + Self::LeafLayerCircuitForKeccakRoundFunction(inner) + } + BaseLayerCircuitType::Sha256Precompile => { + Self::LeafLayerCircuitForSha256RoundFunction(inner) + } + BaseLayerCircuitType::EcrecoverPrecompile => Self::LeafLayerCircuitForECRecover(inner), + BaseLayerCircuitType::RamValidation => Self::LeafLayerCircuitForRAMPermutation(inner), + BaseLayerCircuitType::StorageFilter => Self::LeafLayerCircuitForStorageSorter(inner), + BaseLayerCircuitType::StorageApplicator => { + Self::LeafLayerCircuitForStorageApplication(inner) + } + BaseLayerCircuitType::EventsRevertsFilter => { + Self::LeafLayerCircuitForEventsSorter(inner) + } + BaseLayerCircuitType::L1MessagesRevertsFilter => { + Self::LeafLayerCircuitForL1MessagesSorter(inner) + } + BaseLayerCircuitType::L1MessagesHasher => { + Self::LeafLayerCircuitForL1MessagesHasher(inner) + } + BaseLayerCircuitType::TransientStorageChecker => { + Self::LeafLayerCircuitForTransientStorageSorter(inner) + } + BaseLayerCircuitType::Secp256r1Verify => { + Self::LeafLayerCircuitForSecp256r1Verify(inner) + } + BaseLayerCircuitType::EIP4844Repack => Self::LeafLayerCircuitForEIP4844Repack(inner), + circuit_type => { + panic!("unknown base circuit type for leaf: {:?}", circuit_type); + } + } + } +} + +use crate::boojum::cs::implementations::setup::FinalizationHintsForProver; + +pub type ZkSyncRecursionLayerFinalizationHint = + ZkSyncRecursionLayerStorage; + +use crate::boojum::algebraic_props::round_function::AbsorptionModeOverwrite; +use crate::boojum::algebraic_props::sponge::GoldilocksPoseidon2Sponge; +use crate::boojum::config::ProvingCSConfig; +use crate::boojum::cs::cs_builder_reference::CsReferenceImplementationBuilder; +use crate::boojum::cs::implementations::reference_cs::CSReferenceAssembly; + +pub type RecursiveProofsTreeHasher = GoldilocksPoseidon2Sponge; + +pub type ZkSyncRecursionProof = Proof; + +pub type ZkSyncRecursionLayerProof = ZkSyncRecursionLayerStorage; + +use crate::boojum::cs::implementations::verifier::VerificationKey; +use crate::boojum::field::traits::field_like::PrimeFieldLikeVectorized; +use crate::ZkSyncDefaultRoundFunction; + +pub type ZkSyncRecursionVerificationKey = + VerificationKey; + +pub type ZkSyncRecursionLayerVerificationKey = + ZkSyncRecursionLayerStorage; + +pub type ZkSyncRecursionLayerLeafParameters = + ZkSyncRecursionLayerStorage>; + +type F = GoldilocksField; +type EXT = GoldilocksExt2; + +impl ZkSyncRecursiveLayerCircuit { + pub fn short_description(&self) -> &'static str { + match &self { + Self::SchedulerCircuit(..) => "Scheduler", + Self::NodeLayerCircuit(..) => "Node", + Self::LeafLayerCircuitForMainVM(..) => "Leaf for Main VM", + Self::LeafLayerCircuitForCodeDecommittmentsSorter(..) => "Leaf for Decommitts sorter", + Self::LeafLayerCircuitForCodeDecommitter(..) => "Leaf for Code decommitter", + Self::LeafLayerCircuitForLogDemuxer(..) => "Leaf for Log demuxer", + Self::LeafLayerCircuitForKeccakRoundFunction(..) => "Leaf for Keccak", + Self::LeafLayerCircuitForSha256RoundFunction(..) => "Leaf for SHA256", + Self::LeafLayerCircuitForECRecover(..) => "Leaf for ECRecover", + Self::LeafLayerCircuitForRAMPermutation(..) => "Leaf for RAM permutation", + Self::LeafLayerCircuitForStorageSorter(..) => "Leaf for Storage sorter", + Self::LeafLayerCircuitForStorageApplication(..) => "Leaf for Storage application", + Self::LeafLayerCircuitForEventsSorter(..) => "Leaf for Events sorter", + Self::LeafLayerCircuitForL1MessagesSorter(..) => "Leaf for L1 messages sorter", + Self::LeafLayerCircuitForL1MessagesHasher(..) => "Leaf for L1 messages hasher", + Self::LeafLayerCircuitForTransientStorageSorter(..) => { + "Leaf for transient storage sorter" + } + Self::LeafLayerCircuitForSecp256r1Verify(..) => "Leaf for Secp256r1 verify", + Self::LeafLayerCircuitForEIP4844Repack(..) => "Leaf for EIP4844 repack", + Self::RecursionTipCircuit(..) => "Recursion tip", + } + } + + pub fn numeric_circuit_type(&self) -> u8 { + match &self { + Self::SchedulerCircuit(..) => ZkSyncRecursionLayerStorageType::SchedulerCircuit as u8, + Self::NodeLayerCircuit(..) => ZkSyncRecursionLayerStorageType::NodeLayerCircuit as u8, + Self::LeafLayerCircuitForMainVM(..) => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForMainVM as u8 + } + Self::LeafLayerCircuitForCodeDecommittmentsSorter(..) => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForCodeDecommittmentsSorter as u8 + } + Self::LeafLayerCircuitForCodeDecommitter(..) => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForCodeDecommitter as u8 + } + Self::LeafLayerCircuitForLogDemuxer(..) => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForLogDemuxer as u8 + } + Self::LeafLayerCircuitForKeccakRoundFunction(..) => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForKeccakRoundFunction as u8 + } + Self::LeafLayerCircuitForSha256RoundFunction(..) => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForSha256RoundFunction as u8 + } + Self::LeafLayerCircuitForECRecover(..) => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForECRecover as u8 + } + Self::LeafLayerCircuitForRAMPermutation(..) => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForRAMPermutation as u8 + } + Self::LeafLayerCircuitForStorageSorter(..) => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForStorageSorter as u8 + } + Self::LeafLayerCircuitForStorageApplication(..) => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForStorageApplication as u8 + } + Self::LeafLayerCircuitForEventsSorter(..) => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForEventsSorter as u8 + } + Self::LeafLayerCircuitForL1MessagesSorter(..) => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForL1MessagesSorter as u8 + } + Self::LeafLayerCircuitForL1MessagesHasher(..) => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForL1MessagesHasher as u8 + } + Self::LeafLayerCircuitForTransientStorageSorter(..) => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForTransientStorageSorter as u8 + } + Self::LeafLayerCircuitForSecp256r1Verify(..) => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForSecp256r1Verify as u8 + } + Self::LeafLayerCircuitForEIP4844Repack(..) => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForEIP4844Repack as u8 + } + Self::RecursionTipCircuit(..) => { + ZkSyncRecursionLayerStorageType::RecursionTipCircuit as u8 + } + } + } + + pub fn size_hint(&self) -> (Option, Option) { + match &self { + Self::SchedulerCircuit(inner) => inner.size_hint(), + Self::NodeLayerCircuit(inner) => inner.size_hint(), + Self::LeafLayerCircuitForMainVM(inner) + | Self::LeafLayerCircuitForCodeDecommittmentsSorter(inner) + | Self::LeafLayerCircuitForCodeDecommitter(inner) + | Self::LeafLayerCircuitForLogDemuxer(inner) + | Self::LeafLayerCircuitForKeccakRoundFunction(inner) + | Self::LeafLayerCircuitForSha256RoundFunction(inner) + | Self::LeafLayerCircuitForECRecover(inner) + | Self::LeafLayerCircuitForRAMPermutation(inner) + | Self::LeafLayerCircuitForStorageSorter(inner) + | Self::LeafLayerCircuitForStorageApplication(inner) + | Self::LeafLayerCircuitForEventsSorter(inner) + | Self::LeafLayerCircuitForL1MessagesSorter(inner) + | Self::LeafLayerCircuitForL1MessagesHasher(inner) + | Self::LeafLayerCircuitForTransientStorageSorter(inner) + | Self::LeafLayerCircuitForSecp256r1Verify(inner) + | Self::LeafLayerCircuitForEIP4844Repack(inner) => inner.size_hint(), + Self::RecursionTipCircuit(inner) => inner.size_hint(), + } + } + + pub fn geometry(&self) -> CSGeometry { + match &self { + Self::SchedulerCircuit(..) => ZkSyncSchedulerCircuit::geometry(), + Self::NodeLayerCircuit(..) => ZkSyncNodeLayerRecursiveCircuit::geometry(), + Self::LeafLayerCircuitForMainVM(..) + | Self::LeafLayerCircuitForCodeDecommittmentsSorter(..) + | Self::LeafLayerCircuitForCodeDecommitter(..) + | Self::LeafLayerCircuitForLogDemuxer(..) + | Self::LeafLayerCircuitForKeccakRoundFunction(..) + | Self::LeafLayerCircuitForSha256RoundFunction(..) + | Self::LeafLayerCircuitForECRecover(..) + | Self::LeafLayerCircuitForRAMPermutation(..) + | Self::LeafLayerCircuitForStorageSorter(..) + | Self::LeafLayerCircuitForStorageApplication(..) + | Self::LeafLayerCircuitForEventsSorter(..) + | Self::LeafLayerCircuitForL1MessagesSorter(..) + | Self::LeafLayerCircuitForL1MessagesHasher(..) + | Self::LeafLayerCircuitForTransientStorageSorter(..) + | Self::LeafLayerCircuitForSecp256r1Verify(..) + | Self::LeafLayerCircuitForEIP4844Repack(..) => { + ZkSyncLeafLayerRecursiveCircuit::geometry() + } + Self::RecursionTipCircuit(..) => ZkSyncRecursionTipCircuit::geometry(), + } + } + + fn synthesis_inner( + inner: &ZkSyncLeafLayerRecursiveCircuit, + hint: &FinalizationHintsForProver, + ) -> CSReferenceAssembly + where + P: PrimeFieldLikeVectorized, + CR: CircuitResolver< + F, + crate::zkevm_circuits::boojum::config::Resolver< + crate::zkevm_circuits::boojum::config::DontPerformRuntimeAsserts, + >, + >, + usize: Into<::ResolverConfig>>::Arg>, + { + let geometry = ZkSyncLeafLayerRecursiveCircuit::geometry(); + let (max_trace_len, num_vars) = inner.size_hint(); + let builder_impl = CsReferenceImplementationBuilder::::new( + geometry, + max_trace_len.unwrap(), + ); + let cs_builder = new_builder::<_, F>(builder_impl); + let builder = inner.configure_builder_proxy(cs_builder); + let mut cs = builder.build(num_vars.unwrap()); + let round_function = ZkSyncDefaultRoundFunction::default(); + inner.add_tables(&mut cs); + inner.clone().synthesize_into_cs(&mut cs, &round_function); + cs.pad_and_shrink_using_hint(hint); + cs.into_assembly() + } + + pub fn synthesis>( + &self, + hint: &FinalizationHintsForProver, + ) -> CSReferenceAssembly { + self.synthesis_wrapped::< + P, + StCircuitResolver::ResolverConfig> + >(hint) + } + + pub fn synthesis_wrapped( + &self, + hint: &FinalizationHintsForProver, + ) -> CSReferenceAssembly + where + P: PrimeFieldLikeVectorized, + CR: CircuitResolver< + F, + crate::boojum::config::Resolver, + >, + usize: Into<::ResolverConfig>>::Arg>, + { + match &self { + Self::SchedulerCircuit(inner) => { + let geometry = ZkSyncSchedulerCircuit::geometry(); + let (max_trace_len, num_vars) = inner.size_hint(); + let builder_impl = CsReferenceImplementationBuilder::::new( + geometry, + max_trace_len.unwrap(), + ); + let cs_builder = new_builder::<_, F>(builder_impl); + let builder = inner.configure_builder_proxy(cs_builder); + let mut cs = builder.build(num_vars.unwrap()); + let round_function = ZkSyncDefaultRoundFunction::default(); + inner.add_tables(&mut cs); + inner.clone().synthesize_into_cs(&mut cs, &round_function); + cs.pad_and_shrink_using_hint(hint); + cs.into_assembly() + } + Self::NodeLayerCircuit(inner) => { + let geometry = ZkSyncNodeLayerRecursiveCircuit::geometry(); + let (max_trace_len, num_vars) = inner.size_hint(); + let builder_impl = CsReferenceImplementationBuilder::::new( + geometry, + max_trace_len.unwrap(), + ); + let cs_builder = new_builder::<_, F>(builder_impl); + let builder = inner.configure_builder_proxy(cs_builder); + let mut cs = builder.build(num_vars.unwrap()); + let round_function = ZkSyncDefaultRoundFunction::default(); + inner.add_tables(&mut cs); + inner.clone().synthesize_into_cs(&mut cs, &round_function); + cs.pad_and_shrink_using_hint(hint); + cs.into_assembly() + } + Self::LeafLayerCircuitForMainVM(inner) + | Self::LeafLayerCircuitForCodeDecommittmentsSorter(inner) + | Self::LeafLayerCircuitForCodeDecommitter(inner) + | Self::LeafLayerCircuitForLogDemuxer(inner) + | Self::LeafLayerCircuitForKeccakRoundFunction(inner) + | Self::LeafLayerCircuitForSha256RoundFunction(inner) + | Self::LeafLayerCircuitForECRecover(inner) + | Self::LeafLayerCircuitForRAMPermutation(inner) + | Self::LeafLayerCircuitForStorageSorter(inner) + | Self::LeafLayerCircuitForStorageApplication(inner) + | Self::LeafLayerCircuitForEventsSorter(inner) + | Self::LeafLayerCircuitForL1MessagesSorter(inner) + | Self::LeafLayerCircuitForL1MessagesHasher(inner) + | Self::LeafLayerCircuitForTransientStorageSorter(inner) + | Self::LeafLayerCircuitForSecp256r1Verify(inner) + | Self::LeafLayerCircuitForEIP4844Repack(inner) => { + Self::synthesis_inner::<_, CR>(inner, hint) + } + Self::RecursionTipCircuit(inner) => { + let geometry = ZkSyncRecursionTipCircuit::geometry(); + let (max_trace_len, num_vars) = inner.size_hint(); + let builder_impl = CsReferenceImplementationBuilder::::new( + geometry, + max_trace_len.unwrap(), + ); + let cs_builder = new_builder::<_, F>(builder_impl); + let builder = inner.configure_builder_proxy(cs_builder); + let mut cs = builder.build(num_vars.unwrap()); + let round_function = ZkSyncDefaultRoundFunction::default(); + inner.add_tables(&mut cs); + inner.clone().synthesize_into_cs(&mut cs, &round_function); + cs.pad_and_shrink_using_hint(hint); + cs.into_assembly() + } + } + } + + pub fn into_dyn_verifier_builder( + &self, + ) -> Box> { + match &self { + Self::SchedulerCircuit(..) => { + ConcreteSchedulerCircuitBuilder::dyn_verifier_builder::() + } + Self::NodeLayerCircuit(..) => { + ConcreteLeafLayerCircuitBuilder::dyn_verifier_builder::() + } + Self::LeafLayerCircuitForMainVM(..) + | Self::LeafLayerCircuitForCodeDecommittmentsSorter(..) + | Self::LeafLayerCircuitForCodeDecommitter(..) + | Self::LeafLayerCircuitForLogDemuxer(..) + | Self::LeafLayerCircuitForKeccakRoundFunction(..) + | Self::LeafLayerCircuitForSha256RoundFunction(..) + | Self::LeafLayerCircuitForECRecover(..) + | Self::LeafLayerCircuitForRAMPermutation(..) + | Self::LeafLayerCircuitForStorageSorter(..) + | Self::LeafLayerCircuitForStorageApplication(..) + | Self::LeafLayerCircuitForEventsSorter(..) + | Self::LeafLayerCircuitForL1MessagesSorter(..) + | Self::LeafLayerCircuitForL1MessagesHasher(..) + | Self::LeafLayerCircuitForTransientStorageSorter(..) + | Self::LeafLayerCircuitForSecp256r1Verify(..) + | Self::LeafLayerCircuitForEIP4844Repack(..) => { + ConcreteNodeLayerCircuitBuilder::dyn_verifier_builder::() + } + Self::RecursionTipCircuit(..) => { + ConcreteRecursionTipCircuitBuilder::dyn_verifier_builder::() + } + } + } + + pub fn into_dyn_recursive_verifier_builder + 'static>( + &self, + ) -> Box> + { + match &self { + Self::SchedulerCircuit(..) => { + ConcreteSchedulerCircuitBuilder::dyn_recursive_verifier_builder::() + } + Self::NodeLayerCircuit(..) => { + ConcreteLeafLayerCircuitBuilder::dyn_recursive_verifier_builder::() + } + Self::LeafLayerCircuitForMainVM(..) + | Self::LeafLayerCircuitForCodeDecommittmentsSorter(..) + | Self::LeafLayerCircuitForCodeDecommitter(..) + | Self::LeafLayerCircuitForLogDemuxer(..) + | Self::LeafLayerCircuitForKeccakRoundFunction(..) + | Self::LeafLayerCircuitForSha256RoundFunction(..) + | Self::LeafLayerCircuitForECRecover(..) + | Self::LeafLayerCircuitForRAMPermutation(..) + | Self::LeafLayerCircuitForStorageSorter(..) + | Self::LeafLayerCircuitForStorageApplication(..) + | Self::LeafLayerCircuitForEventsSorter(..) + | Self::LeafLayerCircuitForL1MessagesSorter(..) + | Self::LeafLayerCircuitForL1MessagesHasher(..) + | Self::LeafLayerCircuitForTransientStorageSorter(..) + | Self::LeafLayerCircuitForSecp256r1Verify(..) + | Self::LeafLayerCircuitForEIP4844Repack(..) => { + ConcreteNodeLayerCircuitBuilder::dyn_recursive_verifier_builder::() + } + Self::RecursionTipCircuit(..) => { + ConcreteRecursionTipCircuitBuilder::dyn_recursive_verifier_builder::() + } + } + } + + pub fn leaf_circuit_from_base_type( + base_type: BaseLayerCircuitType, + inner: ZkSyncLeafLayerRecursiveCircuit, + ) -> Self { + match base_type { + BaseLayerCircuitType::VM => Self::LeafLayerCircuitForMainVM(inner), + BaseLayerCircuitType::DecommitmentsFilter => { + Self::LeafLayerCircuitForCodeDecommittmentsSorter(inner) + } + BaseLayerCircuitType::Decommiter => Self::LeafLayerCircuitForCodeDecommitter(inner), + BaseLayerCircuitType::LogDemultiplexer => Self::LeafLayerCircuitForLogDemuxer(inner), + BaseLayerCircuitType::KeccakPrecompile => { + Self::LeafLayerCircuitForKeccakRoundFunction(inner) + } + BaseLayerCircuitType::Sha256Precompile => { + Self::LeafLayerCircuitForSha256RoundFunction(inner) + } + BaseLayerCircuitType::EcrecoverPrecompile => Self::LeafLayerCircuitForECRecover(inner), + BaseLayerCircuitType::RamValidation => Self::LeafLayerCircuitForRAMPermutation(inner), + BaseLayerCircuitType::StorageFilter => Self::LeafLayerCircuitForStorageSorter(inner), + BaseLayerCircuitType::StorageApplicator => { + Self::LeafLayerCircuitForStorageApplication(inner) + } + BaseLayerCircuitType::EventsRevertsFilter => { + Self::LeafLayerCircuitForEventsSorter(inner) + } + BaseLayerCircuitType::L1MessagesRevertsFilter => { + Self::LeafLayerCircuitForL1MessagesSorter(inner) + } + BaseLayerCircuitType::L1MessagesHasher => { + Self::LeafLayerCircuitForL1MessagesHasher(inner) + } + BaseLayerCircuitType::TransientStorageChecker => { + Self::LeafLayerCircuitForTransientStorageSorter(inner) + } + BaseLayerCircuitType::Secp256r1Verify => { + Self::LeafLayerCircuitForSecp256r1Verify(inner) + } + BaseLayerCircuitType::EIP4844Repack => Self::LeafLayerCircuitForEIP4844Repack(inner), + circuit_type => { + panic!("unknown base circuit type for leaf: {:?}", circuit_type); + } + } + } +} + +pub fn base_circuit_type_into_recursive_leaf_circuit_type( + value: BaseLayerCircuitType, +) -> ZkSyncRecursionLayerStorageType { + match value { + BaseLayerCircuitType::None => { + panic!("None is not a proper type") + } + BaseLayerCircuitType::VM => ZkSyncRecursionLayerStorageType::LeafLayerCircuitForMainVM, + BaseLayerCircuitType::DecommitmentsFilter => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForCodeDecommittmentsSorter + } + BaseLayerCircuitType::Decommiter => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForCodeDecommitter + } + BaseLayerCircuitType::LogDemultiplexer => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForLogDemuxer + } + BaseLayerCircuitType::KeccakPrecompile => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForKeccakRoundFunction + } + BaseLayerCircuitType::Sha256Precompile => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForSha256RoundFunction + } + BaseLayerCircuitType::EcrecoverPrecompile => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForECRecover + } + BaseLayerCircuitType::RamValidation => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForRAMPermutation + } + BaseLayerCircuitType::StorageFilter => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForStorageSorter + } + BaseLayerCircuitType::StorageApplicator => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForStorageApplication + } + BaseLayerCircuitType::EventsRevertsFilter => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForEventsSorter + } + BaseLayerCircuitType::L1MessagesRevertsFilter => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForL1MessagesSorter + } + BaseLayerCircuitType::L1MessagesHasher => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForL1MessagesHasher + } + BaseLayerCircuitType::TransientStorageChecker => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForTransientStorageSorter + } + BaseLayerCircuitType::Secp256r1Verify => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForSecp256r1Verify + } + BaseLayerCircuitType::EIP4844Repack => { + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForEIP4844Repack + } + } +} diff --git a/crates/circuit_definitions/src/circuit_definitions/recursion_layer/node_layer.rs b/crates/circuit_definitions/src/circuit_definitions/recursion_layer/node_layer.rs new file mode 100644 index 0000000..7839953 --- /dev/null +++ b/crates/circuit_definitions/src/circuit_definitions/recursion_layer/node_layer.rs @@ -0,0 +1,157 @@ +use crate::boojum::cs::implementations::pow::NoPow; +use crate::zkevm_circuits::boojum::cs::gates::PublicInputGate; +use derivative::*; + +use super::circuit_def::*; +use crate::boojum::cs::implementations::transcript::GoldilocksPoisedon2Transcript; +use crate::boojum::cs::implementations::transcript::Transcript; +use crate::boojum::gadgets::recursion::circuit_pow::*; +use crate::circuit_definitions::base_layer::TARGET_CIRCUIT_TRACE_LENGTH; +use crate::zkevm_circuits::{ + base_structures::recursion_query::RecursionQuery, + recursion::node_layer::{input::*, *}, +}; + +use super::*; + +type F = GoldilocksField; +type TR = GoldilocksPoisedon2Transcript; +type R = Poseidon2Goldilocks; +type CTR = CircuitAlgebraicSpongeBasedTranscript; +type EXT = GoldilocksExt2; +type H = GoldilocksPoseidon2Sponge; +type RH = CircuitGoldilocksPoseidon2Sponge; + +/// 'Outer' layer for the node recursive circuit, that aggregates up to 32 children (leafs or other nodes) of the same type. +/// The circuit logic is in ``node_layer_recursion_entry_point`` method (in era-zkevm_circuits repo). +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Debug(bound = ""))] +#[serde(bound = "")] +// #[serde(bound = "RecursionNodeInstanceWitness: serde::Serialize + serde::de::DeserializeOwned, +// NodeLayerRecursionConfig: serde::Serialize + serde::de::DeserializeOwned, +// TR::TransciptParameters: serde::Serialize + serde::de::DeserializeOwned")] +pub struct NodeLayerRecursiveCircuit> { + pub witness: RecursionNodeInstanceWitness, + pub config: NodeLayerRecursionConfig, + pub transcript_params: >::TransciptParameters, + pub _marker: std::marker::PhantomData<(R, POW)>, +} + +impl> crate::boojum::cs::traits::circuit::CircuitBuilder + for NodeLayerRecursiveCircuit +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + fn geometry() -> CSGeometry { + geometry_for_recursion_step() + } + + fn lookup_parameters() -> LookupParameters { + lookup_parameters_recursion_step() + } + + fn configure_builder< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + configure_builder_recursion_step(builder) + } +} + +impl> NodeLayerRecursiveCircuit +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + pub fn description() -> String { + "Node layer circuit".to_string() + } + + pub fn size_hint(&self) -> (Option, Option) { + ( + Some(TARGET_CIRCUIT_TRACE_LENGTH), + Some((1 << 26) + (1 << 25)), + ) + } + + pub fn configure_builder_proxy< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + &self, + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + >::configure_builder(builder) + } + + pub fn add_tables>(&self, _cs: &mut CS) {} + + pub fn synthesize_into_cs + 'static>( + self, + cs: &mut CS, + round_function: &R, + ) -> [Num; INPUT_OUTPUT_COMMITMENT_LENGTH] { + let Self { + witness, + config, + transcript_params, + .. + } = self; + + let verifier_builder = + LeafLayerCircuitBuilder::::dyn_recursive_verifier_builder::(); + + // reserve enough fixed locations for public inputs + for _ in 0..INPUT_OUTPUT_COMMITMENT_LENGTH { + PublicInputGate::reserve_public_input_location(cs); + } + + let input_commitments = node_layer_recursion_entry_point::( + cs, + witness, + round_function, + config, + verifier_builder, + transcript_params, + ); + + // use reserved_locations + for el in input_commitments.iter() { + PublicInputGate::use_reserved_public_input_location(cs, el.get_variable()) + } + + input_commitments + } +} + +pub type ZkSyncNodeLayerRecursiveCircuit = NodeLayerRecursiveCircuit< + // GoldilocksField, + // GoldilocksExt2, + // ZkSyncDefaultRoundFunction, + // CircuitGoldilocksPoseidon2Sponge, + // GoldilocksPoisedon2Transcript, + // CircuitAlgebraicSpongeBasedTranscript, + NoPow, +>; + +use crate::boojum::cs::traits::circuit::CircuitBuilderProxy; + +pub type NodeLayerCircuitBuilder = CircuitBuilderProxy>; +pub type ConcreteNodeLayerCircuitBuilder = NodeLayerCircuitBuilder; diff --git a/crates/circuit_definitions/src/circuit_definitions/recursion_layer/recursion_tip.rs b/crates/circuit_definitions/src/circuit_definitions/recursion_layer/recursion_tip.rs new file mode 100644 index 0000000..8626b62 --- /dev/null +++ b/crates/circuit_definitions/src/circuit_definitions/recursion_layer/recursion_tip.rs @@ -0,0 +1,154 @@ +use crate::boojum::cs::implementations::pow::NoPow; +use crate::zkevm_circuits::boojum::cs::gates::PublicInputGate; +use derivative::*; + +use super::circuit_def::*; +use crate::boojum::cs::implementations::transcript::GoldilocksPoisedon2Transcript; +use crate::boojum::cs::implementations::transcript::Transcript; +use crate::boojum::gadgets::recursion::circuit_pow::*; +use crate::circuit_definitions::base_layer::TARGET_CIRCUIT_TRACE_LENGTH; +use crate::zkevm_circuits::{ + base_structures::recursion_query::RecursionQuery, + recursion::recursion_tip::{input::*, *}, +}; + +use super::*; + +type F = GoldilocksField; +type TR = GoldilocksPoisedon2Transcript; +type R = Poseidon2Goldilocks; +type CTR = CircuitAlgebraicSpongeBasedTranscript; +type EXT = GoldilocksExt2; +type H = GoldilocksPoseidon2Sponge; +type RH = CircuitGoldilocksPoseidon2Sponge; + +/// 'Outer' layer for the node recursive circuit, that aggregates up to 32 children (leafs or other nodes) of the same type. +/// The circuit logic is in ``node_layer_recursion_entry_point`` method (in era-zkevm_circuits repo). +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Debug(bound = ""))] +#[serde(bound = "")] +pub struct RecursionTipCircuit> { + pub witness: RecursionTipInstanceWitness, + pub config: RecursionTipConfig, + pub transcript_params: >::TransciptParameters, + pub _marker: std::marker::PhantomData<(R, POW)>, +} + +impl> crate::boojum::cs::traits::circuit::CircuitBuilder + for RecursionTipCircuit +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + fn geometry() -> CSGeometry { + geometry_for_recursion_step() + } + + fn lookup_parameters() -> LookupParameters { + lookup_parameters_recursion_step() + } + + fn configure_builder< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + configure_builder_recursion_tip(builder) + } +} + +impl> RecursionTipCircuit +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + pub fn description() -> String { + "Recursion tip circuit".to_string() + } + + pub fn size_hint(&self) -> (Option, Option) { + ( + Some(TARGET_CIRCUIT_TRACE_LENGTH), + Some((1 << 26) + (1 << 25)), + ) + } + + pub fn configure_builder_proxy< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + &self, + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + >::configure_builder(builder) + } + + pub fn add_tables>(&self, _cs: &mut CS) {} + + pub fn synthesize_into_cs + 'static>( + self, + cs: &mut CS, + round_function: &R, + ) -> [Num; INPUT_OUTPUT_COMMITMENT_LENGTH] { + let Self { + witness, + config, + transcript_params, + .. + } = self; + + let verifier_builder = + LeafLayerCircuitBuilder::::dyn_recursive_verifier_builder::(); + + // reserve enough fixed locations for public inputs + for _ in 0..INPUT_OUTPUT_COMMITMENT_LENGTH { + PublicInputGate::reserve_public_input_location(cs); + } + + let input_commitments = recursion_tip_entry_point::( + cs, + witness, + round_function, + config, + verifier_builder, + transcript_params, + ); + + // use reserved_locations + for el in input_commitments.iter() { + PublicInputGate::use_reserved_public_input_location(cs, el.get_variable()) + } + + input_commitments + } +} + +pub type ZkSyncRecursionTipCircuit = RecursionTipCircuit< + // GoldilocksField, + // GoldilocksExt2, + // ZkSyncDefaultRoundFunction, + // CircuitGoldilocksPoseidon2Sponge, + // GoldilocksPoisedon2Transcript, + // CircuitAlgebraicSpongeBasedTranscript, + NoPow, +>; + +use crate::boojum::cs::traits::circuit::CircuitBuilderProxy; + +pub type RecursionTipCircuitBuilder = CircuitBuilderProxy>; +pub type ConcreteRecursionTipCircuitBuilder = RecursionTipCircuitBuilder; diff --git a/crates/circuit_definitions/src/circuit_definitions/recursion_layer/scheduler.rs b/crates/circuit_definitions/src/circuit_definitions/recursion_layer/scheduler.rs new file mode 100644 index 0000000..9ab9f7a --- /dev/null +++ b/crates/circuit_definitions/src/circuit_definitions/recursion_layer/scheduler.rs @@ -0,0 +1,224 @@ +use crate::boojum::cs::implementations::pow::NoPow; +use derivative::*; + +use crate::boojum::cs::gates::*; +use crate::boojum::cs::implementations::transcript::GoldilocksPoisedon2Transcript; +use crate::boojum::cs::implementations::transcript::Transcript; +use crate::boojum::cs::traits::gate::GatePlacementStrategy; +use crate::boojum::gadgets::recursion::circuit_pow::*; +use crate::boojum::gadgets::tables::*; +use crate::circuit_definitions::base_layer::TARGET_CIRCUIT_TRACE_LENGTH; +use crate::zkevm_circuits::{ + base_structures::recursion_query::RecursionQuery, + scheduler::{input::SchedulerCircuitInstanceWitness, *}, +}; + +use super::*; + +type F = GoldilocksField; +type TR = GoldilocksPoisedon2Transcript; +type R = Poseidon2Goldilocks; +type CTR = CircuitAlgebraicSpongeBasedTranscript; +type EXT = GoldilocksExt2; +type H = GoldilocksPoseidon2Sponge; +type RH = CircuitGoldilocksPoseidon2Sponge; + +pub const USE_4844: bool = true; + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Debug(bound = ""))] +#[serde(bound = "")] +// #[serde(bound = "RecursionNodeInstanceWitness: serde::Serialize + serde::de::DeserializeOwned, +// NodeLayerRecursionConfig: serde::Serialize + serde::de::DeserializeOwned, +// TR::TransciptParameters: serde::Serialize + serde::de::DeserializeOwned")] +pub struct SchedulerCircuit, const USE_4844: bool> { + pub witness: SchedulerCircuitInstanceWitness, + pub config: SchedulerConfig, + pub transcript_params: >::TransciptParameters, + pub _marker: std::marker::PhantomData<(R, POW)>, +} + +impl, const USE_4844: bool> + crate::boojum::cs::traits::circuit::CircuitBuilder for SchedulerCircuit +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + fn geometry() -> CSGeometry { + CSGeometry { + num_columns_under_copy_permutation: 26 * 5, // 26 is a width of u32 FMA gate + num_witness_columns: 0, + num_constant_columns: 4, + max_allowed_constraint_degree: 8, + } + } + + fn lookup_parameters() -> LookupParameters { + LookupParameters::UseSpecializedColumnsWithTableIdAsConstant { + width: 3, + num_repetitions: 4, + share_table_id: true, + } + } + + fn configure_builder< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + let builder = builder.allow_lookup( + >::lookup_parameters(), + ); + + let builder = ConstantsAllocatorGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = BooleanConstraintGate::configure_builder( + builder, + GatePlacementStrategy::UseSpecializedColumns { + num_repetitions: 1, + share_constants: false, + }, + ); + let builder = + R::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + let builder = ZeroCheckGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + false, + ); + let builder = FmaGateInBaseFieldWithoutConstant::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = FmaGateInExtensionWithoutConstant::::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<32>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = SelectionGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ParallelSelectionGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = PublicInputGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ReductionGate::<_, 4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = + NopGate::configure_builder(builder, GatePlacementStrategy::UseGeneralPurposeColumns); + + builder + } +} + +impl, const USE_4844: bool> SchedulerCircuit +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + pub fn description() -> String { + "Scheduler circuit".to_string() + } + + pub fn size_hint(&self) -> (Option, Option) { + ( + Some(TARGET_CIRCUIT_TRACE_LENGTH), + Some((1 << 26) + (1 << 25)), + ) + } + + pub fn configure_builder_proxy< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + &self, + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + >::configure_builder(builder) + } + + pub fn add_tables>(&self, cs: &mut CS) { + let table = create_xor8_table(); + cs.add_lookup_table::(table); + + let table = create_and8_table(); + cs.add_lookup_table::(table); + + let table = create_byte_split_table::(); + cs.add_lookup_table::, 3>(table); + let table = create_byte_split_table::(); + cs.add_lookup_table::, 3>(table); + let table = create_byte_split_table::(); + cs.add_lookup_table::, 3>(table); + let table = create_byte_split_table::(); + cs.add_lookup_table::, 3>(table); + } + + pub fn synthesize_into_cs + 'static>( + self, + cs: &mut CS, + round_function: &R, + ) { + let Self { + witness, + config, + transcript_params, + .. + } = self; + + let verifier_builder = + RecursionTipCircuitBuilder::::dyn_recursive_verifier_builder::(); + + scheduler_function::( + cs, + witness, + round_function, + config, + verifier_builder, + transcript_params, + ) + } +} + +pub type ZkSyncSchedulerCircuit = SchedulerCircuit< + // GoldilocksField, + // GoldilocksExt2, + // ZkSyncDefaultRoundFunction, + // CircuitGoldilocksPoseidon2Sponge, + // GoldilocksPoisedon2Transcript, + // CircuitAlgebraicSpongeBasedTranscript, + NoPow, + USE_4844, +>; + +use crate::boojum::cs::traits::circuit::CircuitBuilderProxy; + +pub type SchedulerCircuitBuilder = CircuitBuilderProxy>; +pub type ConcreteSchedulerCircuitBuilder = SchedulerCircuitBuilder; diff --git a/crates/circuit_definitions/src/circuit_definitions/recursion_layer/verifier_builder.rs b/crates/circuit_definitions/src/circuit_definitions/recursion_layer/verifier_builder.rs new file mode 100644 index 0000000..5cc6b30 --- /dev/null +++ b/crates/circuit_definitions/src/circuit_definitions/recursion_layer/verifier_builder.rs @@ -0,0 +1,52 @@ +use super::*; + +type F = GoldilocksField; +type EXT = GoldilocksExt2; + +pub fn dyn_verifier_builder_for_recursive_circuit_type( + circuit_type: ZkSyncRecursionLayerStorageType, +) -> Box> +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + match circuit_type { + ZkSyncRecursionLayerStorageType::SchedulerCircuit => { + ConcreteSchedulerCircuitBuilder::dyn_verifier_builder::() + } + ZkSyncRecursionLayerStorageType::NodeLayerCircuit => { + ConcreteNodeLayerCircuitBuilder::dyn_verifier_builder::() + } + _ => ConcreteLeafLayerCircuitBuilder::dyn_verifier_builder::(), + } +} + +pub fn dyn_recursive_verifier_builder_for_recursive_circuit_type< + CS: ConstraintSystem + 'static, +>( + circuit_type: ZkSyncRecursionLayerStorageType, +) -> Box> +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + match circuit_type { + ZkSyncRecursionLayerStorageType::SchedulerCircuit => { + ConcreteSchedulerCircuitBuilder::dyn_recursive_verifier_builder::() + } + ZkSyncRecursionLayerStorageType::NodeLayerCircuit => { + ConcreteNodeLayerCircuitBuilder::dyn_recursive_verifier_builder::() + } + _ => ConcreteLeafLayerCircuitBuilder::dyn_recursive_verifier_builder::(), + } +} diff --git a/crates/circuit_definitions/src/circuit_definitions/verifier_builder.rs b/crates/circuit_definitions/src/circuit_definitions/verifier_builder.rs new file mode 100644 index 0000000..9078ec1 --- /dev/null +++ b/crates/circuit_definitions/src/circuit_definitions/verifier_builder.rs @@ -0,0 +1,182 @@ +use snark_wrapper::boojum::field::goldilocks::{GoldilocksExt2, GoldilocksField}; + +use super::*; + +use crate::boojum::cs::traits::circuit::CircuitBuilderProxy; +use crate::circuit_definitions::base_layer::*; + +pub type VMMainCircuitVerifierBuilder = + CircuitBuilderProxy; +pub type CodeDecommittsSorterVerifierBuilder = + CircuitBuilderProxy; +pub type CodeDecommitterVerifierBuilder = + CircuitBuilderProxy; +pub type LogDemuxerVerifierBuilder = + CircuitBuilderProxy; +pub type Keccak256RoundFunctionVerifierBuilder = + CircuitBuilderProxy; +pub type Sha256RoundFunctionVerifierBuilder = + CircuitBuilderProxy; +pub type ECRecoverFunctionVerifierBuilder = + CircuitBuilderProxy; +pub type RAMPermutationVerifierBuilder = + CircuitBuilderProxy; +pub type StorageSorterVerifierBuilder = + CircuitBuilderProxy; +pub type StorageApplicationVerifierBuilder = + CircuitBuilderProxy; +pub type EventsSorterVerifierBuilder = + CircuitBuilderProxy; +pub type L1MessagesSorterVerifierBuilder = + CircuitBuilderProxy; +pub type L1MessagesHaherVerifierBuilder = + CircuitBuilderProxy; +pub type TransientStorageSorterVerifierBuilder = + CircuitBuilderProxy; +pub type Secp256r1VerifyVerifierBuilder = + CircuitBuilderProxy; +pub type EIP4844VerifierBuilder = + CircuitBuilderProxy; + +type F = GoldilocksField; +type EXT = GoldilocksExt2; + +pub fn dyn_verifier_builder_for_circuit_type( + circuit_type: u8, +) -> Box> +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + use circuit_encodings::zkevm_circuits::scheduler::aux::BaseLayerCircuitType; + + match circuit_type { + i if i == BaseLayerCircuitType::VM as u8 => { + VMMainCircuitVerifierBuilder::dyn_verifier_builder() + } + i if i == BaseLayerCircuitType::DecommitmentsFilter as u8 => { + CodeDecommittsSorterVerifierBuilder::dyn_verifier_builder() + } + i if i == BaseLayerCircuitType::Decommiter as u8 => { + CodeDecommitterVerifierBuilder::dyn_verifier_builder() + } + i if i == BaseLayerCircuitType::LogDemultiplexer as u8 => { + LogDemuxerVerifierBuilder::dyn_verifier_builder() + } + i if i == BaseLayerCircuitType::KeccakPrecompile as u8 => { + Keccak256RoundFunctionVerifierBuilder::dyn_verifier_builder() + } + i if i == BaseLayerCircuitType::Sha256Precompile as u8 => { + Sha256RoundFunctionVerifierBuilder::dyn_verifier_builder() + } + i if i == BaseLayerCircuitType::EcrecoverPrecompile as u8 => { + ECRecoverFunctionVerifierBuilder::dyn_verifier_builder() + } + i if i == BaseLayerCircuitType::RamValidation as u8 => { + RAMPermutationVerifierBuilder::dyn_verifier_builder() + } + i if i == BaseLayerCircuitType::StorageFilter as u8 => { + StorageSorterVerifierBuilder::dyn_verifier_builder() + } + i if i == BaseLayerCircuitType::StorageApplicator as u8 => { + StorageApplicationVerifierBuilder::dyn_verifier_builder() + } + i if i == BaseLayerCircuitType::EventsRevertsFilter as u8 => { + EventsSorterVerifierBuilder::dyn_verifier_builder() + } + i if i == BaseLayerCircuitType::L1MessagesRevertsFilter as u8 => { + L1MessagesSorterVerifierBuilder::dyn_verifier_builder() + } + i if i == BaseLayerCircuitType::L1MessagesHasher as u8 => { + L1MessagesHaherVerifierBuilder::dyn_verifier_builder() + } + i if i == BaseLayerCircuitType::TransientStorageChecker as u8 => { + TransientStorageSorterVerifierBuilder::dyn_verifier_builder() + } + i if i == BaseLayerCircuitType::Secp256r1Verify as u8 => { + Secp256r1VerifyVerifierBuilder::dyn_verifier_builder() + } + i if i == BaseLayerCircuitType::EIP4844Repack as u8 => { + EIP4844VerifierBuilder::dyn_verifier_builder() + } + _ => { + panic!("unknown circuit type = {}", circuit_type); + } + } +} + +pub fn dyn_recursive_verifier_builder_for_circuit_type< + CS: ConstraintSystem + 'static, +>( + circuit_type: u8, +) -> Box> +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + use circuit_encodings::zkevm_circuits::scheduler::aux::BaseLayerCircuitType; + + match circuit_type { + i if i == BaseLayerCircuitType::VM as u8 => { + VMMainCircuitVerifierBuilder::dyn_recursive_verifier_builder() + } + i if i == BaseLayerCircuitType::DecommitmentsFilter as u8 => { + CodeDecommittsSorterVerifierBuilder::dyn_recursive_verifier_builder() + } + i if i == BaseLayerCircuitType::Decommiter as u8 => { + CodeDecommitterVerifierBuilder::dyn_recursive_verifier_builder() + } + i if i == BaseLayerCircuitType::LogDemultiplexer as u8 => { + LogDemuxerVerifierBuilder::dyn_recursive_verifier_builder() + } + i if i == BaseLayerCircuitType::KeccakPrecompile as u8 => { + Keccak256RoundFunctionVerifierBuilder::dyn_recursive_verifier_builder() + } + i if i == BaseLayerCircuitType::Sha256Precompile as u8 => { + Sha256RoundFunctionVerifierBuilder::dyn_recursive_verifier_builder() + } + i if i == BaseLayerCircuitType::EcrecoverPrecompile as u8 => { + ECRecoverFunctionVerifierBuilder::dyn_recursive_verifier_builder() + } + i if i == BaseLayerCircuitType::RamValidation as u8 => { + RAMPermutationVerifierBuilder::dyn_recursive_verifier_builder() + } + i if i == BaseLayerCircuitType::StorageFilter as u8 => { + StorageSorterVerifierBuilder::dyn_recursive_verifier_builder() + } + i if i == BaseLayerCircuitType::StorageApplicator as u8 => { + StorageApplicationVerifierBuilder::dyn_recursive_verifier_builder() + } + i if i == BaseLayerCircuitType::EventsRevertsFilter as u8 => { + EventsSorterVerifierBuilder::dyn_recursive_verifier_builder() + } + i if i == BaseLayerCircuitType::L1MessagesRevertsFilter as u8 => { + L1MessagesSorterVerifierBuilder::dyn_recursive_verifier_builder() + } + i if i == BaseLayerCircuitType::L1MessagesHasher as u8 => { + L1MessagesHaherVerifierBuilder::dyn_recursive_verifier_builder() + } + i if i == BaseLayerCircuitType::TransientStorageChecker as u8 => { + TransientStorageSorterVerifierBuilder::dyn_recursive_verifier_builder() + } + i if i == BaseLayerCircuitType::Secp256r1Verify as u8 => { + Secp256r1VerifyVerifierBuilder::dyn_recursive_verifier_builder() + } + i if i == BaseLayerCircuitType::EIP4844Repack as u8 => { + EIP4844VerifierBuilder::dyn_recursive_verifier_builder() + } + _ => { + panic!("unknown circuit type = {}", circuit_type); + } + } +} diff --git a/crates/circuit_definitions/src/lib.rs b/crates/circuit_definitions/src/lib.rs new file mode 100644 index 0000000..00102b2 --- /dev/null +++ b/crates/circuit_definitions/src/lib.rs @@ -0,0 +1,59 @@ +#![allow(clippy::drop_ref)] +#![feature(array_chunks)] +#![feature(stmt_expr_attributes)] +#![feature(generic_const_exprs)] +#![feature(iter_array_chunks)] +#![feature(iter_next_chunk)] +#![feature(associated_type_defaults)] + +pub type Field = GoldilocksField; +pub type RoundFunction = Poseidon2Goldilocks; + +pub const BASE_LAYER_FRI_LDE_FACTOR: usize = 2; +pub const BASE_LAYER_CAP_SIZE: usize = 16; +pub const SECURITY_BITS_TARGET: usize = 100; + +pub const RECURSION_LAYER_FRI_LDE_FACTOR: usize = 2; +pub const RECURSION_LAYER_CAP_SIZE: usize = 16; + +pub const L1_SECURITY_BITS: usize = 80; + +pub const EIP4844_CYCLE_LIMIT: usize = 4096; + +pub use snark_wrapper; +use snark_wrapper::boojum::field::goldilocks::GoldilocksField; + +use crate::boojum::cs::implementations::prover::ProofConfig; + +pub fn base_layer_proof_config() -> ProofConfig { + ProofConfig { + fri_lde_factor: BASE_LAYER_FRI_LDE_FACTOR, + merkle_tree_cap_size: BASE_LAYER_CAP_SIZE, + fri_folding_schedule: None, + security_level: SECURITY_BITS_TARGET, + pow_bits: 0, + } +} + +pub fn recursion_layer_proof_config() -> ProofConfig { + ProofConfig { + fri_lde_factor: RECURSION_LAYER_FRI_LDE_FACTOR, + merkle_tree_cap_size: RECURSION_LAYER_CAP_SIZE, + fri_folding_schedule: None, + security_level: SECURITY_BITS_TARGET, + pow_bits: 0, + } +} + +pub mod aux_definitions; +pub mod circuit_definitions; +pub use circuit_encodings as encodings; + +use crate::boojum::implementations::poseidon2::Poseidon2Goldilocks; +pub use zk_evm::ethereum_types; + +pub type ZkSyncDefaultRoundFunction = Poseidon2Goldilocks; + +pub use crate::zkevm_circuits::boojum; +pub use circuit_encodings::zk_evm; +pub use circuit_encodings::zkevm_circuits; diff --git a/crates/circuit_encodings/Cargo.toml b/crates/circuit_encodings/Cargo.toml index 004a1ff..c4324e0 100644 --- a/crates/circuit_encodings/Cargo.toml +++ b/crates/circuit_encodings/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "circuit_encodings" -version = "0.142.1" +version = "0.150.2" edition = "2021" authors = ["The Matter Labs Team "] homepage = "https://zksync.io/" @@ -13,9 +13,8 @@ description = "ZKsync Era circuits encodings" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -zkevm_circuits = { version = "0.141", path = "../zkevm_circuits" } # Not pinned, because it's an old dependency used by MultiVM -zk_evm = { version = "0.141", path = "../zk_evm" } # Not pinned, because it's an old dependency used by MultiVM - +zkevm_circuits = { version = "=0.150.3", path = "../zkevm_circuits" } +zk_evm = { version = "=0.150.0", path = "../zk_evm" } derivative = "2.2" serde = {version = "1", features = ["derive"]} @@ -24,3 +23,4 @@ serde = {version = "1", features = ["derive"]} [features] default = [] log_tracing = ["zkevm_circuits/log_tracing"] +verbose_circuits = ["zkevm_circuits/verbose_circuits"] diff --git a/crates/circuit_encodings/src/callstack_entry.rs b/crates/circuit_encodings/src/callstack_entry.rs index e2fdfda..106ec70 100644 --- a/crates/circuit_encodings/src/callstack_entry.rs +++ b/crates/circuit_encodings/src/callstack_entry.rs @@ -84,106 +84,80 @@ impl OutOfCircuitFixedLengthEncodable = FullWidthStackSimulator< F, ExtendedCallstackEntry, EXECUTION_CONTEXT_RECORD_ENCODING_WIDTH, FULL_SPONGE_QUEUE_STATE_WIDTH, - 4, + CALLSTACK_SIMULATOR_USED_SPONGES, +>; +pub type CallstackSimulatorState = FullWidthStackIntermediateStates< + F, + FULL_SPONGE_QUEUE_STATE_WIDTH, + CALLSTACK_SIMULATOR_USED_SPONGES, >; -pub type CallstackSimulatorState = - FullWidthStackIntermediateStates; diff --git a/crates/circuit_encodings/src/decommittment_request.rs b/crates/circuit_encodings/src/decommittment_request.rs index a00ac5a..41e83ee 100644 --- a/crates/circuit_encodings/src/decommittment_request.rs +++ b/crates/circuit_encodings/src/decommittment_request.rs @@ -1,15 +1,26 @@ use super::*; -use zk_evm::aux_structures::DecommittmentQuery; +use crate::ethereum_types::U256; +use zk_evm::{ + aux_structures::DecommittmentQuery, zkevm_opcode_defs::VersionedHashNormalizedPreimage, +}; use zkevm_circuits::base_structures::decommit_query::DECOMMIT_QUERY_PACKED_WIDTH; +pub fn normalized_preimage_as_u256(normalized_preimage: &VersionedHashNormalizedPreimage) -> U256 { + let mut buffer = [0u8; 32]; + buffer[4..].copy_from_slice(&normalized_preimage.0[..]); + + U256::from_big_endian(&buffer) +} + impl OutOfCircuitFixedLengthEncodable for DecommittmentQuery { fn encoding_witness(&self) -> [F; DECOMMIT_QUERY_PACKED_WIDTH] { debug_assert!(F::CAPACITY_BITS >= 56); - let code_hash = decompose_u256_as_u32x8(self.hash); + let hash = normalized_preimage_as_u256(&self.normalized_preimage); + let code_hash = decompose_u256_as_u32x8(hash); // we assume that page bytes are known, so it'll be nop anyway let page_bytes = self.memory_page.0.to_le_bytes(); @@ -88,9 +99,11 @@ impl CircuitEquivalentReflection for DecommittmentQuery { fn reflect(&self) -> >::Witness { use zkevm_circuits::base_structures::decommit_query::DecommitQueryWitness; + let hash = normalized_preimage_as_u256(&self.normalized_preimage); + DecommitQueryWitness { timestamp: self.timestamp.0, - code_hash: self.hash, + code_hash: hash, is_first: self.is_fresh, page: self.memory_page.0, } diff --git a/crates/circuit_encodings/src/lib.rs b/crates/circuit_encodings/src/lib.rs index 6565a1b..e9f4c31 100644 --- a/crates/circuit_encodings/src/lib.rs +++ b/crates/circuit_encodings/src/lib.rs @@ -2,6 +2,8 @@ use crate::boojum::algebraic_props::round_function::{ absorb_multiple_rounds, AbsorptionModeOverwrite, AlgebraicRoundFunction, }; use crate::boojum::field::SmallField; +use crate::boojum::gadgets::queue::QueueStateWitness; +use crate::boojum::gadgets::queue::QueueTailStateWitness; use crate::boojum::gadgets::traits::allocatable::CSAllocatable; use crate::boojum::gadgets::traits::round_function::*; use crate::boojum::gadgets::u160::decompose_address_as_u32x5; @@ -119,6 +121,12 @@ impl< } } + pub fn with_capacity(capacity: usize) -> Self { + let mut new = Self::empty(); + new.witness.reserve_exact(capacity); + new + } + pub fn split(mut self, at: u32) -> (Self, Self) { if at >= self.num_items { let mut artificial_empty = Self::empty(); @@ -308,8 +316,6 @@ impl< pub struct FullWidthQueueIntermediateStates { pub head: [F; SW], pub tail: [F; SW], - pub old_head: [F; SW], - pub old_tail: [F; SW], pub num_items: u32, pub round_function_execution_pairs: [([F; SW], [F; SW]); ROUNDS], } @@ -362,6 +368,12 @@ impl< } } + pub fn with_capacity(capacity: usize) -> Self { + let mut new = Self::empty(); + new.witness.reserve_exact(capacity); + new + } + pub fn merge(first: Self, second: Self) -> Self { assert_eq!(first.tail, second.head); @@ -419,8 +431,6 @@ impl< let intermediate_info = FullWidthQueueIntermediateStates { head: self.head, tail: new_tail, - old_head: self.head, - old_tail, num_items: self.num_items, round_function_execution_pairs: states, }; @@ -459,8 +469,6 @@ impl< let intermediate_info = FullWidthQueueIntermediateStates { head: self.head, tail: self.tail, - old_head, - old_tail: self.tail, num_items: self.num_items, round_function_execution_pairs: states, }; @@ -506,6 +514,105 @@ impl< } } +pub trait ContainerForSimulator { + fn push(&mut self, val: T); +} + +use core::marker::PhantomData; +/// Simplified version of FullWidthQueueSimulator with custom container instead of VecDeque +pub struct FullWidthMemoryQueueSimulator< + F: SmallField, + I, + C: ContainerForSimulator<([F; N], [F; SW], I)>, + const N: usize, + const SW: usize, + const ROUNDS: usize, +> where + I: OutOfCircuitFixedLengthEncodable, +{ + pub head: [F; SW], + pub tail: [F; SW], + pub num_items: u32, + pub witness: C, + _marker: PhantomData, +} + +impl< + F: SmallField, + I: OutOfCircuitFixedLengthEncodable, + C: ContainerForSimulator<([F; N], [F; SW], I)>, + const N: usize, + const SW: usize, + const ROUNDS: usize, + > FullWidthMemoryQueueSimulator +{ + pub fn using_container(container: C) -> Self { + Self { + head: [F::ZERO; SW], + tail: [F::ZERO; SW], + num_items: 0, + witness: container, + _marker: Default::default(), + } + } + + pub fn replace_container(mut self, container: C) -> (Self, C) { + let prev_container = self.witness; + self.witness = container; + (self, prev_container) + } + + pub fn take_sponge_like_queue_state(&self) -> QueueStateWitness { + let result = QueueStateWitness { + head: self.head, + tail: QueueTailStateWitness { + tail: self.tail, + length: self.num_items, + }, + }; + + result + } + + pub fn push_and_output_intermediate_data< + R: CircuitRoundFunction + AlgebraicRoundFunction, + const AW: usize, + const CW: usize, + >( + &mut self, + element: I, + _round_function: &R, + ) -> ( + [F; SW], // old tail + FullWidthQueueIntermediateStates, + ) { + let old_tail = self.tail; + assert!(N % AW == 0); + let encoding = element.encoding_witness(); + + let mut state = old_tail; + let states = absorb_multiple_rounds::( + &mut state, &encoding, + ); + let new_tail = state; + + let states = make_round_function_pairs(old_tail, states); + + self.witness.push((encoding, new_tail, element)); + self.num_items += 1; + self.tail = new_tail; + + let intermediate_info = FullWidthQueueIntermediateStates { + head: self.head, + tail: new_tail, + num_items: self.num_items, + round_function_execution_pairs: states, + }; + + (old_tail, intermediate_info) + } +} + #[derive(Derivative, serde::Serialize, serde::Deserialize)] #[derivative(Debug, Clone(bound = ""), Copy(bound = ""))] #[serde(bound = "")] @@ -535,7 +642,7 @@ pub struct FullWidthStackSimulator< > { pub state: [F; SW], pub num_items: u32, - pub witness: Vec<([F; N], [F; SW], I)>, + pub witness: Vec<([F; SW], I)>, } impl< @@ -588,7 +695,7 @@ impl< let states = make_round_function_pairs(old_state, states); - self.witness.push((encoding, self.state, element)); + self.witness.push((self.state, element)); self.num_items += 1; self.state = new_state; @@ -618,7 +725,7 @@ impl< let popped = self.witness.pop().unwrap(); self.num_items -= 1; - let (_element_encoding, previous_state, element) = popped; + let (previous_state, element) = popped; let encoding = element.encoding_witness(); let mut state = previous_state; @@ -758,6 +865,9 @@ mod tests { } assert_eq!(queue.num_items, 10); + let old_head = queue.head; + let old_tail = queue.tail; + // pop one element let (element, data) = queue.pop_and_output_intermediate_data(&round_function); // it should return the first one that we entered (with circuit 0). @@ -767,8 +877,8 @@ mod tests { assert_eq!(data.num_items, 9); assert_eq!(data.head, tail_after_first); - assert_eq!(data.old_head, empty_head); - assert_eq!(data.old_tail, data.tail); + assert_eq!(old_head, empty_head); + assert_eq!(data.tail, old_tail); let mut parts = queue.split_by(3, &round_function); diff --git a/crates/circuit_encodings/src/log_query.rs b/crates/circuit_encodings/src/log_query.rs index 12e2a50..5e401fe 100644 --- a/crates/circuit_encodings/src/log_query.rs +++ b/crates/circuit_encodings/src/log_query.rs @@ -6,6 +6,7 @@ use zk_evm::ethereum_types::U256; // Proxy, as we just need read-only pub trait LogQueryLike: 'static + Clone + Send + Sync + std::fmt::Debug { fn shard_id(&self) -> u8; + fn tx_number_in_block(&self) -> u32; fn address(&self) -> H160; fn key(&self) -> U256; fn rw_flag(&self) -> bool; @@ -26,6 +27,9 @@ impl LogQueryLike for LogQuery { fn shard_id(&self) -> u8 { self.shard_id } + fn tx_number_in_block(&self) -> u32 { + self.tx_number_in_block as u32 + } fn address(&self) -> H160 { self.address } @@ -77,9 +81,9 @@ pub struct LogQueryLikeWithExtendedEnumeration { use super::*; -use zkevm_circuits::storage_validity_by_grand_product::input::PACKED_KEY_LENGTH; +use zkevm_circuits::storage_validity_by_grand_product::input::STORAGE_VALIDITY_CHECK_PACKED_KEY_LENGTH; -pub fn comparison_key(query: &LogQuery) -> Key { +pub fn comparison_key(query: &LogQuery) -> Key { let key = decompose_u256_as_u32x8(query.key); let address = decompose_address_as_u32x5(query.address); @@ -97,6 +101,35 @@ pub fn event_comparison_key(query: &LogQuery) -> Key<1> { Key(le_words) } +use zkevm_circuits::transient_storage_validity_by_grand_product::input::TRANSIENT_STORAGE_VALIDITY_CHECK_PACKED_KEY_LENGTH; + +pub fn transient_storage_comparison_key( + query: &LogQuery, +) -> Key { + let key = decompose_u256_as_u32x8(query.key); + let address = decompose_address_as_u32x5(query.address); + + let le_words = [ + key[0], + key[1], + key[2], + key[3], + key[4], + key[5], + key[6], + key[7], + address[0], + address[1], + address[2], + address[3], + address[4], + query.shard_id as u32, + query.tx_number_in_block as u32, + ]; + + Key(le_words) +} + use zkevm_circuits::base_structures::log_query::LOG_QUERY_PACKED_WIDTH; impl OutOfCircuitFixedLengthEncodable for LogQuery { diff --git a/crates/circuit_encodings/src/memory_query.rs b/crates/circuit_encodings/src/memory_query.rs index 7db7e63..19a6994 100644 --- a/crates/circuit_encodings/src/memory_query.rs +++ b/crates/circuit_encodings/src/memory_query.rs @@ -124,6 +124,21 @@ pub type MemoryQueueSimulator = FullWidthQueueSimulator< FULL_SPONGE_QUEUE_STATE_WIDTH, 1, >; +pub type CustomMemoryQueueSimulator = FullWidthMemoryQueueSimulator< + F, + MemoryQuery, + C, + MEMORY_QUERY_PACKED_WIDTH, + FULL_SPONGE_QUEUE_STATE_WIDTH, + 1, +>; + +pub type QueueWitness = ( + [F; MEMORY_QUERY_PACKED_WIDTH], + [F; FULL_SPONGE_QUEUE_STATE_WIDTH], + MemoryQuery, +); + pub type MemoryQueueState = FullWidthQueueIntermediateStates; @@ -142,3 +157,7 @@ impl CircuitEquivalentReflection for MemoryQuery { } } } + +use zkevm_circuits::base_structures::memory_query::MemoryQueryWitness; +pub type MemoryQueueStateWitnesses = + Vec<(MemoryQueryWitness, [F; FULL_SPONGE_QUEUE_STATE_WIDTH])>; diff --git a/crates/circuit_sequencer_api/Cargo.toml b/crates/circuit_sequencer_api/Cargo.toml index 642740d..a281499 100644 --- a/crates/circuit_sequencer_api/Cargo.toml +++ b/crates/circuit_sequencer_api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "circuit_sequencer_api" -version = "0.142.1" +version = "0.150.2" edition = "2021" authors = ["The Matter Labs Team "] homepage = "https://zksync.io/" @@ -8,13 +8,14 @@ repository = "https://github.com/matter-labs/era-zkevm_test_harness/" license = "MIT OR Apache-2.0" keywords = ["blockchain", "zksync"] categories = ["cryptography"] -description = "ZKsync Era circuits API for sequencer" +description = "ZKsync Era circuit API for sequencer" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -circuit_encodings = { version = "0.142", path = "../circuit_encodings"} # Not pinned, because it's an old dependency used by MultiVM -zk_evm = { version = "0.141", path = "../zk_evm" } -bellman = { package = "bellman_ce", version = "0" } # Not pinned, because it's an old dependency used by MultiVM +circuit_encodings = { version = "=0.150.2", path = "../circuit_encodings"} +bellman = { package = "bellman_ce", version = "=0.7.0" } derivative = "2.2" @@ -24,3 +25,4 @@ rayon = "1.10" [features] default = [] +verbose_circuits = ["circuit_encodings/verbose_circuits"] diff --git a/crates/circuit_sequencer_api/src/geometry_config.rs b/crates/circuit_sequencer_api/src/geometry_config.rs index 9c3ff16..57a7223 100644 --- a/crates/circuit_sequencer_api/src/geometry_config.rs +++ b/crates/circuit_sequencer_api/src/geometry_config.rs @@ -4,7 +4,7 @@ use crate::toolset::GeometryConfig; pub const fn get_geometry_config() -> GeometryConfig { GeometryConfig { - cycles_per_vm_snapshot: 5585, + cycles_per_vm_snapshot: 5390, cycles_code_decommitter_sorter: 117500, cycles_per_log_demuxer: 58750, cycles_per_storage_sorter: 46921, @@ -16,5 +16,7 @@ pub const fn get_geometry_config() -> GeometryConfig { cycles_per_sha256_circuit: 2206, cycles_per_ecrecover_circuit: 7, limit_for_l1_messages_pudata_hasher: 774, + cycles_per_transient_storage_sorter: 50875, + cycles_per_secp256r1_verify_circuit: 4, } } diff --git a/crates/circuit_sequencer_api/src/sort_storage_access.rs b/crates/circuit_sequencer_api/src/sort_storage_access.rs index fece565..ab0e2c2 100644 --- a/crates/circuit_sequencer_api/src/sort_storage_access.rs +++ b/crates/circuit_sequencer_api/src/sort_storage_access.rs @@ -1,11 +1,10 @@ +use circuit_encodings::{ + zk_evm::ethereum_types::U256, LogQueryLike, LogQueryLikeWithExtendedEnumeration, +}; use derivative::Derivative; use rayon::prelude::*; use std::cmp::Ordering; use std::iter::IntoIterator; -use zk_evm::ethereum_types::U256; - -use circuit_encodings::LogQueryLike; -use circuit_encodings::LogQueryLikeWithExtendedEnumeration; #[derive(Derivative)] #[derivative(Default(bound = ""), Debug)] @@ -29,7 +28,7 @@ pub fn sort_storage_access_queries<'a, L: LogQueryLike, I: IntoIterator match a.raw_query.address().cmp(&b.raw_query.address()) { Ordering::Equal => match a.raw_query.key().cmp(&b.raw_query.key()) { Ordering::Equal => a.extended_timestamp.cmp(&b.extended_timestamp), @@ -258,3 +257,38 @@ pub fn sort_storage_access_queries<'a, L: LogQueryLike, I: IntoIterator>( + unsorted_storage_queries: I, +) -> Vec> { + let mut sorted_storage_queries_with_extra_timestamp: Vec<_> = unsorted_storage_queries + .into_iter() + .enumerate() + .map(|(i, el)| LogQueryLikeWithExtendedEnumeration { + raw_query: el.clone(), + extended_timestamp: i as u32, + }) + .collect(); + + sorted_storage_queries_with_extra_timestamp.par_sort_by(|a, b| { + match a + .raw_query + .tx_number_in_block() + .cmp(&b.raw_query.tx_number_in_block()) + { + Ordering::Equal => match a.raw_query.shard_id().cmp(&b.raw_query.shard_id()) { + Ordering::Equal => match a.raw_query.address().cmp(&b.raw_query.address()) { + Ordering::Equal => match a.raw_query.key().cmp(&b.raw_query.key()) { + Ordering::Equal => a.extended_timestamp.cmp(&b.extended_timestamp), + r @ _ => r, + }, + r @ _ => r, + }, + r @ _ => r, + }, + r @ _ => r, + } + }); + + sorted_storage_queries_with_extra_timestamp +} diff --git a/crates/circuit_sequencer_api/src/toolset.rs b/crates/circuit_sequencer_api/src/toolset.rs index 905beca..7407b67 100644 --- a/crates/circuit_sequencer_api/src/toolset.rs +++ b/crates/circuit_sequencer_api/src/toolset.rs @@ -14,6 +14,8 @@ pub struct GeometryConfig { pub cycles_per_keccak256_circuit: u32, pub cycles_per_sha256_circuit: u32, pub cycles_per_ecrecover_circuit: u32, + pub cycles_per_secp256r1_verify_circuit: u32, + pub cycles_per_transient_storage_sorter: u32, pub limit_for_l1_messages_pudata_hasher: u32, } diff --git a/crates/circuit_sequencer_api/src/utils.rs b/crates/circuit_sequencer_api/src/utils.rs index a513504..803dd52 100644 --- a/crates/circuit_sequencer_api/src/utils.rs +++ b/crates/circuit_sequencer_api/src/utils.rs @@ -4,9 +4,9 @@ use crate::boojum::{ }; use circuit_encodings::{ boojum::{algebraic_props::round_function::AbsorptionModeOverwrite, field::SmallField}, + zk_evm::ethereum_types::U256, zkevm_circuits::scheduler::QUEUE_FINAL_STATE_COMMITMENT_LENGTH, }; -use zk_evm::ethereum_types::U256; pub fn calldata_to_aligned_data(calldata: &Vec) -> Vec { if calldata.len() == 0 { diff --git a/crates/kzg/.gitignore b/crates/kzg/.gitignore new file mode 100644 index 0000000..37a4f98 --- /dev/null +++ b/crates/kzg/.gitignore @@ -0,0 +1,4 @@ +/target +Cargo.lock +.idea +.DS_Store \ No newline at end of file diff --git a/crates/kzg/Cargo.toml b/crates/kzg/Cargo.toml new file mode 100644 index 0000000..da02ec7 --- /dev/null +++ b/crates/kzg/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "zksync_kzg" +version = "0.150.2" +edition = "2021" +authors = ["The Matter Labs Team "] +homepage = "https://zksync.io/" +repository = "https://github.com/matter-labs/era-zkevm_test_harness/" +license = "MIT OR Apache-2.0" +keywords = ["blockchain", "zksync"] +categories = ["cryptography"] +description = "ZKsync Era KZG implementation" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] + +derivative = "2.2" +serde = {version = "1", features = ["derive"]} +serde_json = "1.0" +rayon = "1.10" +hex = "0.4" +once_cell = "1" +serde_with = {version = "1", features = ["hex"]} + +boojum = "=0.2.2" +zkevm_circuits = { version = "=0.150.3", path = "../zkevm_circuits" } + +[dev-dependencies] +rand = "0.4" + +[features] +default = [] diff --git a/crates/kzg/README.md b/crates/kzg/README.md new file mode 100644 index 0000000..57c9c18 --- /dev/null +++ b/crates/kzg/README.md @@ -0,0 +1,9 @@ +# Kzg crate + +This crate contains functions related to kzg commitment that is used for 4844 blobs. + +There are 3 methods that are used by era from this crate: + +* pubdata_to_blob_commitments - computes the blob commitments for given pub data +* KzgInfo - holds all the methods for converting bytes into blobs +* ZK_SYNC_BYTES_PER_BLOB - information on how much data is stored per blob. \ No newline at end of file diff --git a/crates/kzg/src/consts.rs b/crates/kzg/src/consts.rs new file mode 100644 index 0000000..5665169 --- /dev/null +++ b/crates/kzg/src/consts.rs @@ -0,0 +1,4099 @@ +/// Taken from https://seq.ceremony.ethereum.org/info/current_state +pub const SETUP_HEX: [&str; 4096] = [ + "97f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb", + "ad3eb50121139aa34db1d545093ac9374ab7bca2c0f3bf28e27c8dcd8fc7cb42d25926fc0c97b336e9f0fb35e5a04c81", + "8029c8ce0d2dce761a7f29c2df2290850c85bdfaec2955626d7acc8864aeb01fe16c9e156863dc63b6c22553910e27c1", + "b1386c995d3101d10639e49b9e5d39b9a280dcf0f135c2e6c6928bb3ab8309a9da7178f33925768c324f11c3762cfdd5", + "9596d929610e6d2ed3502b1bb0f1ea010f6b6605c95d4859f5e53e09fa68dc71dfd5874905447b5ec6cd156a76d6b6e8", + "851e3c3d4b5b7cdbba25d72abf9812cf3d7c5a9dbdec42b6635e2add706cbeea18f985afe5247459f6c908620322f434", + "b10f4cf8ec6e02491bbe6d9084d88c16306fdaf399fef3cd1453f58a4f7633f80dc60b100f9236c3103eaf727468374f", + "ade11ec630127e04d17e70db0237d55f2ff2a2094881a483797e8cddb98b622245e1f608e5dcd1172b9870e733b4a32f", + "af58c8a2f58f904ce20db81005331bf2d251e227e7d1bef575d691bdca842e6233eb2e26c2e116a61a78594772b38d25", + "b3c1313c31ec82da5a7a09e9cf6656ca598c243345fe8d4828e520ade91787ffb8b9867db789b34ad67cef47b26ff86d", + "a8ed8a235355948e0b04be080b7b3e145293accefb4704d1da9050796b2f6870516c1ebf77ae6a65359edcfd016c0f36", + "80e792d5ba24b8058f6d7291a2ec5cb68aab1e16e96d793128e86815631baf42c56b6205c19e25ce9727bd1fd6f9defb", + "816288c5d726b094e3fdf95cb8882f442c4d9d1101b92c7938a7dfd49bc50636d73ea1b05f75eb731c908c8fd8dee717", + "ae009128d128ba2e1519bfa7a0c01ed494a7d461c3aba60f8a301701fed61fe4e31d6c79ce189542ae51df91e73ce1b3", + "96a866d60a9007d05825c332476a83e869e15b11d7257172a67690ea9bd3efea44bf9c8d42191454eb04fcf110b16396", + "8b250a2a06419adb9b611e89f7f8f2990aa301949b533ad3bf17c4a61ab5f5be0b1d5e2b571864d13f1bb75805c7795d", + "8450f49facf2e620fa45ee90e1801178842d927a2a25fc6ed7ba99a4eec7ae40eebfee41028eaa84f107f4a777694976", + "91049080cf659c0985a22d1366e59191bb89663f922e8168b9b7d85c8a73d74a6d9dceefd855d3d858b493670c750581", + "a1e167aeb2008087f3195926f1985c0a459d6ec57237255b1473a96de4e2c1cf766127c862c7dc853a6909e67cb06cf7", + "b667c0d4e26e20698b07567358625d5f003839c92de8088e12dbd74a6f6a3156b4ea8d252c9ad62af5f6c4fec1cf6cc7", + "8e4b5e304c0b1b161ae3e4b68b5e3ac66c42acd7c1ee2458044f6527c508a93995e50894d72d57c1350f91afe72775ff", + "8c642640aa7915421cdc21fd639f88a42052b1cfa358ff7702e60793a92b7b5926dae15a0c8f8f59cd3013f01c159ba3", + "a356f35e713cfc283056bf539de54a21731e61efb4c47319f20de4a4b723d76a33b65f4a67d298b9ec5c2a1579418657", + "93ce204146ce95f484dc79c27919a16c9e3fc14a9111c6c63d44491158d5838117d20851cc3227a5e8ba6ccf79e77f39", + "b585664cbb9a84b52f89114e1cf0cf1171bea78a136dc1404ac88a11210b2debc3b7a55e702da93ff629095c134a295e", + "b6dfd444ec7fdceb14c6328f26ca12c3f9fc4327d8d8c68948e92e7e61262b82d833a65a9e3af6353ffa832b6da25705", + "b4d4b8eb9ecfffe3f0d48fb4149c7b31aec1da7041ec03bd0750c52a2a7cbc3a7cfbf09d5bfdc56e3860826a62d0bb91", + "a4e248e3d61db52da9683fef188579c470d65e2df9064726847b1599fc774049ffdc6ef2ae578d5ed7874f1298ecdf69", + "a68a0fffc2e37d3183feb01b42234c0f4e510f9dc29d09c571e6da00fecad9da224cd0f31550070148667e226c4ca413", + "86adda2ffecb77236c18005051f31f9657a0d50fef2a1175dfda32e74d5d53df825c10f289eb0ad39df0c64fc9bc7729", + "998266d5c9c3764ed97d66fa9ed176af043999652bae19f0657c8328629d30af453230e3681c5a38e2f01e389ed8d825", + "a05261554d3c620af0c914cf27ab98f5d3593c33ab313c198e0c40d6c72022eb5943778cd4f73e9fe8383392a7004976", + "ad243fb3631bf90fedb9d679fd71fc0cf06bda028591ded2bd4c634ea7b3c2bd22eca2ab318fcdaa6c2cda1e63e1c57b", + "89b9859a04f903c95e97fb2951f01cc6418a2505eee0b5bc7266b4d33e01b69b9fe7dc56fa9ebb5856095be0925a422d", + "a68d118343a5bbfbbab95ff9bfe53aeb7fdbaf16db983e6f4456366df2aa01fbdb6ee9901cb102fc7d2bd099be2f1f3e", + "b49301f25d5a9dd2ec60ddb0b4b477291958487efea9e54dc0e4ef388f03b8bbadd13259d191f7a0b7513876767d8282", + "8b93df7fb4513f67749905fd43db78f7026589b704ebb9ea3255d0ad6415437799f40f02e07efccda1e6fd5e8cd0a721", + "ad88769ace96455da37c3c9019a9f523c694643be3f6b37b1e9dcc5053d1fe8e463abebdb1b3ef2f2fb801528a01c47c", + "80f0eb5dcbfaaf421bf59a8b9bd5245c4823c94510093e23e0b0534647fb5525a25ea3aeea0a927a1ee20c057f2c9234", + "b10ad82ea6a5aeabe345d00eb17910d6942b6862f7f3773c7d321194e67c9cced0b3310425662606634dcd7f8b976c04", + "82f6fd91f87822f6cc977808eeac77889f4a32fb0d618e784b2331263d0ffa820b3f70b069d32e0319c9e033ab75d3b4", + "9436d3dc6b5e25b1f695f8c6c1c553dab312ccace4dac3afddc141d3506467cd50cb04a49ea96ea7f5a8a7b0fc65ef37", + "8e0a9491651d52be8ebf4315fbbb410272f9a74b965d33b79ff1b9e1be3be59e43d9566773560e43280549c348e48f01", + "8809137e5d3a22400d6e645a9bd84e21c492371736c7e62c51cef50fee3aa7f2405724367a83fd051ff702d971167f67", + "b536a24f31a346de7f9863fc351fa602158404d2f94747eebe43abf1f21bf8f95a64146c02a4bec27b503f546789a388", + "b5cdf5a04fc12a0e0ef7545830061dff7fd8abea46e48fbe6235109e6c36ee6bffcb9529e2f3d0d701cf58bbfb6a4197", + "ab15377525753467d042b7931f66f862cbbb77464212c9aa72d4e5c04375ef55f619b3a446091c1ba1a3b5d9f05e538f", + "905a75b943ad017ff78ea6ddd1d28a45c7273ee1c2e5e3353685813793ead3370c09cabd903fcab9d8b1c6961372d486", + "8147df4324faddc02fb0896367a7647b719b6499a361aecfdd3a34296fa6768ad31c34f9e873fd1e683386c44651883e", + "ac91d08570dd91f89d2e01dca67cdc83b640e20f073ea9f0734759c92182bb66c5d645f15ebd91ed705b66486ed2088d", + "ac6295ef2513bbea7ef4cdcf37d280300c34e63c4b9704663d55891a61bf5c91b04cc1d202a3a0a7c4520c30edc277c7", + "b604be776a012095c0d4ebc77797dd8dec62a54c0559fb2185d7bac6b50d4e5fd471ac2d7f4523206d5d8178eabd9a87", + "80ead68def272ce3f57951145e71ed6dc26da98e5825ef439af577c0c5de766d4e39207f205d5d21db903d89f37bbb02", + "9950b4a830388c897158c7fe3921e2fe24beedc7c84e2024e8b92b9775f8f99593b54a86b8870ec5087734295ba06032", + "b89ba714adabf94e658a7d14ac8fc197376a416841c2a80e1a6dde4f438d5f747d1fb90b39e8ea435c59d6ecda13dea1", + "b0c78e7cc60bd05be46d48fbb0421a678c7f14b8d93730deb66fbe1647613b2c62b5075126d917047820c57fc3509cb9", + "a860c4acc5444e9ae987e8c93cb9a5f17d954d63c060cc616f724e26bc73d2c54cd36e0492d1fde173847278e55942ba", + "8fb8269c9d5c15428e8d45da1251e4c4a4b600d47da0caea29fef246854d8fb6acae86a8e6440d0c429d8dd9c2dfee0c", + "96c5d8eb6fd5c525b348ee4335d200139e437e4be83690af0f35b7f336a7cda8c6d2958647988b84da9f2dd7bbb7710b", + "a7f62141c4346cc14e9823dc38ac7d587b0427022afc1498d12ee2c43f6ac3a82167057e670dd524b74137f8c3ceb56d", + "956aac50d06b46a3e94397f163f593f5010d366aa2d816c2205c7d0f47f90cf0f36c169e964f9bcf698d49182d47d91f", + "b812899bcdc0e70d79ca729cb01104bf60e1357b9085a10f64f3ba9865d57e9abd0a505a502d4de07afb46f4d266be2f", + "abce02c7e1372e25d40944dc9ece2904a8f59c8854c5f2875fe63ace8ce37d97881f4f9ab4f7bad070ec8e0daee58d3f", + "8fb13c515b2d6abb4e14ed753fad5cc36c3631dfe21a23d0f603aad719423dd5423157eefcbd9a9c6074e155b79eb38d", + "a9ef67304dc297ab5af778cf8afa849eeac27db4b6978963e97b95ef7a8d3264d0d07775f728c298a2b6daed2ecf5053", + "a9b975520adb066e2ff2a4cde53284c23bc84261a22dc43b1634d99eff8e7892e46bb6e6da7319c9e72788aa9ea7a1ea", + "a6eaea4ab4206294474d9b956d9d3188d558a5633de2bd05df0d3bac03dbcbe4ed85406349c1d2e660b77c6da1f5bf8c", + "af4a19f77290dddee762e1e0d4bc9945aacea3f75756ae46cd3e58a8f74d1b5db73e4834687946b0f39191e32f2fed0c", + "aafa6523f58f1a4cabc924c86d842816d606afeea21fa4b2b8b9573425810fdcc41c98888318e868f9c05e2be12178a3", + "8ef38fba0a3fa4ebe985239c8b759c22aaef0c57e6f39050a651c869487803b0d1e389c3d958fb5a7f37740f050ac69e", + "b07dfc9f85913c608ca7596a2e361f05e4853fad00e796fd492d247de6414892ce160f627669b1ba933b6ad726415d4e", + "94da679ad1d78b2bff5283c938f17b2a7d6e9cbcdf59d340e6dfb652951c7a9e852ac0590f99cfee9631b9410f6f00ea", + "98a907c9c021a5b034d3720197c160a82c4b7146cb73d48efeed99b9d0c6b831812cf80ac7e19e85a676a8cd3ead72de", + "adb746595466a12929019d0048cea33236b05c1229d2eba73b259a18a786f2bc3f05fc0598d8ce253cecb80bdf679aaf", + "a2fbac016996d68f9027a157b0a3f6a336144a798d6113adfcda3a5d05b62c31f108f112aa915906aef22b7f83b9228b", + "81841dea1904406d1b6fa49b4b3f7f6cb40b7646cf44d36c9fa07e3dee29f8e47324b40d8356ddf653109673c3374e9b", + "a3edbb8aac5e60c775775cbdb19067341b2e2530de48738e84c2c07151241ee31f0d8333bf20c2bc9dcb7b2e638a6b5e", + "b8aa6890e22964828787ce86460d3a32f12a655bb5c28de500f2fcf6b61e3334640ec6ba96029a4912af0d18df4b4139", + "8ca43169f04243ad0fdb0152de17c60d9e31ee0ab520970fccd98590e05508821a183b4b367967e60d53c2c826ec5dbd", + "b179fffd9df8c00486c5a8b9327d599f5a11745ef564f06e126849b06fe2f99273c81f65bc941efb0debaadfecbfec1c", + "acf068f1c2b1926279cc82750ce21b0d6b0bfd0406f0d8bbfa959bd83935932957c7f6b8de318315bf0b75f6ee41a0f2", + "b97831da260919c856e9f71a41687f5979bc16f8a53b1037285b4a2f9ce93af5cfe70bf0ad484744827fb55c847b58eb", + "aff50b0bd907383b0c241727af364fe084d021221bfb1b09fb6c1a7752eeba45d662493d590f1f182764b90b25f17906", + "aeeef044c14e3ad41e1235c9e816e1eb49087fd3abe877b89b3bade74459186126e160bb569bcd77779e701b19b5f71a", + "8483deb2b7001ca7c438fcdca8ca6aba96c9cbc4becfd9b16a6062705eae270011bcaedcae69bb54630d8c78129e57c7", + "aeee8d24be4ac0d9784c029e239fb5e64316ce29b88f47394cfaaa8bb966a72061bff72f99d02dc51c9705854686e77f", + "90ae09525a16bb2422169e15d6831c87968a14ebc0d1d27e11a759839c73c655b9d33ee5b12f275d6f440688146fbd2f", + "a3a41fc7fefef101422465e506bea7f3ff23c26fe35f5732b86f5f2471fb93b37ebc339f84c6be1e8d22abc812c2e212", + "86f4b5293e8aea4af1f1fb05dcf99714cb3aff1cfc849b1bb73524061c921c9da9ad92579a852e1889da29d952f02fe5", + "8932ef39d4050a1e9dc0fd8afeaf159472d71c5c27f458c69d2730836606ea56e19c8c4febf2535f930d3260e9bc7637", + "86307b9f3696bb21c20e4558e30310389e7367803c353d437e9b696039a0ff054d9a4953b75237ab1d1dd6f71118c189", + "96e57730e683ef5b550c91de18b19ac73879f3e26234297db68d28747ed0953beb0f3913cfb720c602720bf9330685d8", + "b04a19ee70123782e47b238abde55baf60ac0c66292a998af0d14afc8bbeb1134e557b94cd17a020084631c09a0d3c02", + "829abc8718be8139569fcb2c398962f38f4201114d30e2b2fb23566f8a27a5c380f5605cec543415202a12ed859e33f6", + "a0744fa488c8fa92a722c5fc4ef5a47dfe824eccd87d26c8bab9c174cbb151d44b1b29082c48652f03d3177e5ec86001", + "81d4035ae9fd28bdcd78b135cb54955d3b685a527319df6ee7e904b8e6d796f5f5a5f5035ee1de750c4cb6050e452b9e", + "b205e8c2ec24d7104fa0106c09ad34b5a912c1adef553fb718838dd627355993c2ec01055c11d00b2c75b68e9516d44b", + "b12d09da7968fa7394e449624fc7174d1d76c069ccb03e140d4d87a2d3f6d1f7b9cfc930f0c80becc673406ebe63f08e", + "b23752c158695da85048fdf38b395681cc0e8998630af8a9ed41efbda08c9964c2dc8ae6e53377264be4467d702c0de4", + "b0d84582fd73628d96b8c1ec96197697c41a963542451a2ade0890af0d33c7161d0f18e1a1ce2c168ca2dc1e9119d55e", + "8b877e618b469aa187632e410b125d2999d5738fd66d482000706b51fd904a0c7e7daa8c9b729fa33817bbc4154cba2a", + "b1cfc8a7551b601723b937d497d01dec3ee7614c2bf13d430b1058d5ebc1406045009ff02c2ac15bf8cf16f860193d1e", + "b6d9da84f97b21e13175bbb0b5cc8e79e88b470c87a3e115726c1bd98e0288526c58f3faaa8aa170ace0cd6a60852525", + "ad2e773c2d527671ca5fab7085dde4da31cd35f45d4315dd95d8893ff5fb900494dca08eccfc1a2fc7bf7c7fd2fcab97", + "8d5a79b34aeb761d4a0c73f09f02e9548e6d382c33ee6887a759ab05762b490b8a549ef2933c7e3a46415c154c0221c0", + "b6f2cbe81bd0a7298403be392f8456bed30aed7ef30216959357698f789affd2942ae5fbaf3f48ecebeb7c273b20cb57", + "b5b6c45d99cea7ce6a1dc134aff4a8f630f299b42bd59592a7592345f8cd35bcbee944e61b0723de732fcad6e4425b63", + "8077d64dfcb2418974e956ea6dbf8a4c05b25d2a025333ad7e2a379f1976dc036771403383a51bfa3476c9c619ef8bef", + "ad2e0a9d479c77a5fb73b3613a177fdaad50dcb50fed50e756ba18164c153af30b07fb2565e80ff7469f1b0338b7b5de", + "81017d1d80a6b6df4e99d0d7f85a8180b5523e8fa2ea2672fddff604933f8a113cab27fce098dcb454d7d1f7ed266e04", + "852355479d68e76c7febf6dfe2ef8e80d575c0d3bd52c983803592021cfa898c571c0b884412c21e66f0dbfe03167b53", + "98e1bf8ad48421467c93b9f72b47dded7c41b4fcd36ea55ca43ab24b0d0b876f5a731f422579b7167c7138fad2121266", + "803369314abd5422019ed4b0ef652b4dbe97ef5a87b0ea373eec9628b64a12120b2c3d4eb53db405131ff786d14c7ac6", + "adf2613fc34f73e1160975c140e925ed84d254e03cc3bc7fc1d19957b499c9ba9d9e4c1639981b594a7095c0a52c6757", + "a2f6a68efdff6e4173c00692abcfdfcdaf6f8b62369afad3dafaae4f2f38c4860780b4624d185e20e4f4498b75b5fe94", + "8b1658aa0e119fb8401d486ed08d60240d26a8623ef9788e3b45ad09ae31259395b021bd16be395139cbb7149714e764", + "a7dd8bf21121285e00672ee8bb84e0cb39b2496fb53a26e35dfbca7f2b04e9a9ff9db15f53fe63fcbeafeb2deeaf2ca4", + "b6d8d709e44bc18f3b41d69608edce60c02bcba48d3b7e2fd420842657f0665a7343246dea149a25e8f3416284abae66", + "aaf744ca5e9bcb63e3e2939b7a1e96e4a93c88c76bec0cf4294dd7db95cdd3f6a7d92196e352d08680e2328bc4592899", + "84434b015a7c398d35f1ec71fce455d62ba4ed4f62da042ec31bb2b4db47073314354cd50bc322297a1cfe35138bf490", + "8d70b3a3cd9d5dfefdacfa418c0b775a112a47ce538d33a560a519660009c3f141fd6221c18539129e9c0acdaceeeb80", + "b8c6903412a800ec78a4c15f31c24385a267b0c0ece32fd31bbbb557fd70c3b2d60d8fc0f90fbd70f43baa1928ea30ba", + "8e391dd445ea06cabb433f057853f8159511b2f9bef41aed9ccd14e0a6fcd912bbaebd38fd5fb736cfde0fa34b7a4874", + "a40cd988f70613df32babbd1bbc2f1b29ff1ab0147b01161555a81d56c9621657999bcdb1df38485f687afc51d5d0f23", + "b6a008b4426b3d7b28ae04eee4698fc8ef6a35d89008ef5394da39ce582ce1a45dcfae9a33b90f6fa4237f3667803873", + "8987280debfb175c3b44a2f152ea82548e4f680966f1fcbee9bf7d714e31bf8080c33f52705ef3aeee70544b22516aba", + "a78a51a2c11eea7680a5a0ae417a2981f8c69c396e06da621eadd7510a3664ade49d065617bec67b3de779548a4f4509", + "a4d9163f0a1bc048385e94d5e0bcafeee1b18f28eb23505623b9e8ef16f3df76408254dfbe790e45f2884198060d388d", + "83dcae2568a0c518793c0f6e38b42f9ceb50673d100b556a17ec8bd9faeec84afe50b8d72422c6b2356959667bb8e2de", + "874731941be4474b4576226e5906b5dee89fc9b56a9870dcc7289c1a7d494d345ba6aba31f7546a16f9963283c05f744", + "82c1cfab1f501189ac20147fc4631075dbf1abf9125b7d42fcb4f31cf73f3d6461b1bd08fdf6e45cc54bc08a7d5d51d1", + "b978228286f5d4a10ce027b6bea3021affcaa805340ca4b5192c69e8c56db59f48e4a14a284ec015f53baf97389f62b2", + "af125f4fdccd1c1b64fdffecb5ec7cf8c7392bbe476e1b89a5b5329c5ba4a526e58c11e72ab9de8a38d60af648d75adc", + "8411a41ec14295acab0d36389013535a80dfff6e024bffeb32fb3070762f61256419e8c51b2ad6de9dbe4f1e8e286912", + "8ea67a91112a41f9c65515cd496f4b0cdefa1400fc06568eef000c9eae6dc250fb7622eb3f2deca10b37287cd96fa463", + "8da99b6c55c31dee6a49aabb54da249d348a31d4416201a10c45a3b04b11e99d4ae9813632f0ee36c523b5cca62f6f49", + "8b44656341e039e2bd83a19c3bb9a88f6209482e274f8cd4f8557b728e5948dd80b5745f621b96f4562928689314e8c2", + "a02d424a615ba0dce8ed91f477e79852215a3a39d025059826fa278e7eebef19824b2a2844f5b3865a0f471b609a23f5", + "a1f115cebc3fff3bcf233da27cef19eae791660f155d088003460f75567a550bef0722885010ddc384acdeac635939dc", + "b61a55ce9d143c17876776e064b58a10baf0ba13553c785c1e47f57b5f94c0cda8bc89d43d73386e57816c15b61a8ec8", + "b4073f47041e20a8e548c7fb00e07ba3b9056c34eb4ab63bb0e7b48f8e338e8b56a17611a1b5f4c03b352450b86f1d69", + "a7b1a07b213205b682fc5b6acb7e76fdf97b280c26621d8f3b76b7c1deb3511957da33a4e358c8e8f3d98b2a8855d67e", + "b797e67c2670fbd9844e8a68c585f404b035dc14bd4ec75c3f95f932c777f9db5d5f5df7629164af488fc1213035cc5f", + "99618200797b945f595794d6468e5c618649554ad9ba896330f1cc844090eb956ae9fc23132912f9047085c5f0c3bf7b", + "81194aa1319abf534cb3927af9adfb178a99d0e3e8c99ab1105f1d3b4fed40ec2971caf1d6647acb0c8d681eca53097b", + "80673f18e4978dbc226a6cd4b128a1259d9a7f833879c6e2fbe24d69fef2c3c23a51a4f3e8d88fa4533434bbb0723661", + "8125bf6c7dbb2fb63aaa3f53283559f172c788223674adbeb6d5bd17cfe888e6b87a79aec774917f20ce911c1f85f8e7", + "884bcdb1878b14fc38adc9fb8b4dd0b3afde404fbeb664f26ddfebc81736018551f23e75ce4cfe4865f610bcd454fbd7", + "aec65c8d4be8316e98aa54888af01bc6703a0c5d04b69756ff39a0a947b66817ec59d76afe9f61a25749b5e890f03e02", + "aa457aaa1b014a4c5a8992847a187a23321bb43452c98745987d038e3b04046102ae859b7a8e980eea978a39d76a88ef", + "a9832ee63b08e19123f719bfe2fe742125f32463efa966c7709a98ebfc65277670e9ea1fa2d2d78b96bdc7523b0c4c3e", + "a87b6b1b7858f96d55064274f29fbde56067064962cf3c3e2ba3110b22ea633bc037a74d23543ce3307a46208855d74f", + "897cbe4ab68a753020fec732dfcc052c7ed9905342b5a6fe0aa25c631f9ad9b659e0ee75d46f0df6507b6720675ee28c", + "97c3b5f0d54c1fc45e79445c3ff30458959e406a069f5bbf7979d684195b4fa0406b87c1c008f4075bc9e602ed863152", + "921e65d582ea9322ddfad1c855331c3cac81f53c700b96db5305a643c084eb6793094e07944bfd41dc02c3b3cf671530", + "8f23ef1aca02a260a3b65d25b110f28d3bafca44727448c8f2d03c5e77eda620c1721b06681bd816ee6027664d76352a", + "946a89b132ec0795aea9ff9dde7b77e7feafffe6e4a2f093042a7e6c71cd6ab87ce0ca914a1b5fabad4e1f96a795f163", + "a01e2de9db33df6511172123ad6f7c64074237471df646b32dd9aff8c15278e2723108e4facaedca97e9f49503f8c792", + "99dcdcde45b2ea3f15279936feede5f7d3b63ca4972f335b0559c2fa6f9faabd8127aa892a36deb114357ca906553ed8", + "a3f8af37bfcf66b04d1896a4bd5d343f4733d4c3305369ac7e75a08f20f2004c10c642d2c7577f4e5c4d1f2cd851ac3b", + "b7294d15a3d674a56099f97a1adc9e82c15e90832eaf1722df110fc2abc8634c51515e5ad8522015498a3753b1fa8c49", + "b4f27f5062ba7a04ea0048b3025b5e3d5b5d319a9e80310c808a5fb4e8e77b38c10a0f3172cb805cadbcc8bc66d36ec7", + "aefe5decee0ae2dc372cc6cf4217daf97c4c908d145f100f0daf1ccdfdf641c78432c2e473e7e4b77dcdf2d4c2bb05f0", + "acc84af7648a535ffd218c0cc95c8f7b092418c548815f1bafc286b1fe14f6ccb51b2044db3bff864d0bb70e88604084", + "84d8e3dac0df6a22beb03742e1d4af684f139f07e2ea0f7fb27fc2d7d4f1e89b5e89f71af32ff115ed5e6092133535f0", + "8ada001e1a03a823c4c056f636e77adc0f9dc08689d28de0d99e0feecab5db13abf37b41ec268dbdb42c75419a046c68", + "87dac6c798d1744dff81d8bc3e0e04f3c9bf260e811685ddb9a9a8d6eda73927439b344f9a818d2103fad633de5a4a17", + "ad9929a7d8a7d5d5954e48281a87e5c84f67e19110d73296b9989a09c76767a57a8115629239ffb4d99dfdf9c52ef6d9", + "81ac7cbeef8ec35a5c3b61cc887080c29e6cd3e08af37e45830d17400dbacfb374dd07bf370b979828c3875b2027d5c6", + "97f92c9182953b7e10f7a1bbb6b5b5c40b8275eb5a6eec1e29874c4712814749aa8c409651380216e1ff01d7b8511041", + "a09794d0bbe7db013045d3fd857c1544fe6231d21afa3495fa300371f6301a3a0f4b8ea175b281503dd06078ff371ae4", + "839bb58d320aa08116dd387a57a2b9bd9efc89c4cdfd82d0e47a00cabe644631d09be5436bd485df3b61b75ddf81a3ef", + "b1cdaa344f783757e8b9c1f84421da3c5be4c69f019a8fd4c1aa5bf1a63e8970c99e35c22cf3b48a0e6738bc6ba7ce8d", + "92af68e3216c78998208fb24b5ba0e645d0d3f5e28222b805668d7e9cdd6c033d3b22fd6df4c2d745d7f910d133cd226", + "87640a4ea4e605e2204e5232b29a6c1c31152d83547eef14122cb76a0da52b8653801af48455a3ed713b9dcfee7b1ef1", + "8147e5bf0c8f4731155ca0517ef3fae5a32b4d5d2d98ed0007b23893d8dbb7f8a1199c50c1750c2fa7c9cebe594b1bb0", + "a76b4473c63c3ab6103c729afd2482822e4150f3155af39983b0ff0766c71cb622455ce6304e23853661eaa322219d18", + "b3e2f05ca551bc3adec0067e4034aaffd72e0b64ac18ae25452c996927976c6727966e26d213b032521889be2170800d", + "a8414cd14cb3be658e9e0004ce511ef7063439b1cbc3166a11de030613fde4b59caad4e91d426927863c55382afbf476", + "b2f0f8ab99f4d0ea785ac84fdbc00b20217b1df59b30b51d9d209d489d53b69dd5d82cdacc16fd1dd15c3a4001595f50", + "8b2025d5fd658c9bbed619f3e3f6ac8efe7aeff8aa9401bd66a7ceb0062c44b353608ca073f95be99204f0a913bb77eb", + "94a46bc5a87291b42024b2137e623c70115b9c6b196604106bfbfa20f3f56ac7779763f56b580190d3cb2f1c648cada1", + "aca9355545118d0769cacf69c4b23d6d68d229cd8f68f1bc0c847c05569c5af6bbbd8c4dceb637b4a6b3b5c83841bf5e", + "b0731992cab87c7116406b283a84707a34838bfa3284b0f6082dfabeaf41c5ac2b0ddc1b420547a1b0955aee92de2dc0", + "b671f77588c0f69f6830a5b28e7d07ed161b81fa9791bb3a24aae6638e3aa5e186df74978a82549c370c18ebee04d4f0", + "b5621ed841780f3e6681d880a76cf519cdd20d35197b112eeaa686764d57b5dfa78ffe1a294b6bc76b6e3949cd2a2369", + "afeba2524659d00caecf089645611553187a6ed7102050f6dd20f5a19bed08ac7065912d88371ee06242897d58d652a4", + "b78bfb83d44ced14a20135804aba3f00128c3ce1f302e95567ce4097b0d973414153fb305b9f156882a5a0554bf25973", + "98510aede95d26b1adf214053eae051ffaf24894e2fa37961a91d0ff5392dd09388196648d95b73e90bd88f2587cc4bf", + "b35c682d49c295946b9f120fbc47b95abd9ee86d294abb003a92139fb825b509209562575015856a270eb3eea86397a7", + "b9641bf685571dd9c478dd2033a1f1b11cd3a662b26502c78595863b8e536a189674a9a85f7a253453ebfd1b99fbd841", + "b2ad37036a59b1c9b8457972665720a6868422ed8157b6810a9c0783006103be34ab732d7aeb8629653edd18fd0f1717", + "af0920cff05179a3896ea6ea322c39adf91ada5bc40fe3f6fb1b1b4e121e907c904bbaa8ca00468b3749f3da144d71f3", + "8e269672818ef1e2f9e0c8aa65c84442fcd9151d74bb8e870cee8c0e3fe24526e1a5388b430cef47b67f79b4e4056bcc", + "aa29a16fe00ea3d143b1032b1dd26b8ce638f37f95c085c7e777e8e2784bd724bd5c38b1583c61a6ec7c451dd78fd3fb", + "87452b7435911cc5f513b0c81b15aa04972ecbe3d7bbd0a5d676c96a8a311301c0e07fac925c53a350b46fbd3d4d0fc1", + "869a81c351096f47748e41566ae7b77a454b1cdfaa41d34a5742f80df38fbf5cbb08924b6fdff58e3b18f05c62bbbbb1", + "8b7bc1b0486300981147a40a449ada9a41afc06d735cce8bf0fab3ee94ba2e2ea57b1397e3cd31bc295352beb8334ef7", + "93e93fc41adb2df279d95654921b4c2edf0d293dab58d0afefb221f777349ef88d0985b3447e3b935954a81f1580a92c", + "970fa7cdca8324faf3e62348bb50d78f580b4f43f2e1c11bd8382d48d0074a3c55c6407203a0c9cb1c5f2163ba421ef4", + "924983929e608d27e4a36d4ed919297869e3c64de51aca794d32d6e90aea546bf898d98ceca28a0b2187734821b78504", + "8d395332529c703d943d68415d443332b5c1342ca9d9a59bfa8bd4ab63e93358c4b0dde6ce1f2e8ea9dc8f52ad7ebd95", + "80200dda853e588256599e7f905add5d5ee7c74272780317694fbae39318ae9be05d5bcd7b20cf460069743f3d4ef240", + "a287d51d6359c9ef7c7ac1b20e479ce7d0146dba5606397bd04b7a622cec642508d5b45d51b31de71f9763595b6ac88e", + "a320396c075175d6599225cf2e1de8c7cab549f6316c07feb0f6eaa21f06b2dd29ab14fbdf2af4543b4890ec0fd08a4d", + "b1e9fe230418d20368691058adcbbe30011bab3000422f0371015ff8bd09c60fb5fa85d18550d35b1c900977ca48f58b", + "9718fc26a51783b971744933f20490e9b5cd9162f86b84788c4c5217f5409e37b5a39d628b18e5b35a757acf67596321", + "a0cf81fdb161f4f1b419c5e4caa36d4bdca2325f0cd25b119a30178016f171bd6fb88403e4e3aec026c4089f180d540e", + "8ab1e36bd04625ee794ef04c4dcb8e004d61aceb2b62438377f49ad95dcf025ba25eb799280004941e555bf7172af6fe", + "9257b9e3d14d37fc7efae49b0c68d36eaac546035f4a2654d566b3ce1b2c4564cbb03dc8ec66efceb768559a8a507a18", + "945d1123b839637ab5154a1972c3c83a0ff34a3b1a3465de6ef0416b1950f649869a3ef88d7f1036648ee385265ce2df", + "81449639d708860fc0229c94f754f7262e8a3c7f67960ff12dfd15df95f57a9ffcee2013e81978b7703dd42bd5d0816f", + "a865481deaae5a690fd53892791e5fa729db283b75a525a11cdfee1ce17e8e7f0b449d25f20b3c1b43da128dbdf98a8b", + "98766812a65fcd25b853546e3bba618a3edc9fd61510e4f8ab60c038a7fa50d197abeec8776109df0f2119be9445ad00", + "b1b8dd5379d903dc41d74e999b1ab693607a0d2905692f4fb96adf08f738e5d31f9d00df28ccb8b5856145ca552c3e3c", + "99d20be7b511bec78a8ed03c207aa4aa9097ba39d85e18f1b8d52f65431ab7e9a773c7b9ac3e8d8b25458bc91bd00703", + "b1b7c3563fe8cb33c7d3e0b89d00bdd13e86452ff507c2e69db7b3af06f247f139155396e9b0278753310dc63940a10b", + "b3dc9c08451b1de7c9969b1e47574bffff50490f4a16c51e12390195d9e9c72f794790caf7b0a835d64e01fec995d3ac", + "aaaa4761a00022ede0809d7063d3532b7bfae90ff16f45e17a340ad4ebaa2fbac40728ccc5fbe36a67ab0e707566c5dc", + "8319a1903314eab01f5442d2aee6ae9c3f6edfda0d9a88b416d0f874d7d1d05d08bb482102f8ca70a4fa34836d0840c1", + "932949a6e9edfec344932a74d4f81eec3667ece1e8b8ca840ce07ffd4b5d6d8f01657c764d64ac1b9190f876b136490e", + "904db1568128487e312fe629dd8bb920cecafd3bb9cad8b63e269ae0129f2f5c80cd82f0d81e7feca9835c3945a72d28", + "a17280693d30dcd43c85de8f6b02d5f30cb9097274ad680cede1ef105c903615b4c40f3c6aaca478642de324972514e0", + "8d5f76e093aee71d0cdeb017fdfcb13bd068039746de90690ce150a0bfdbe7ddc4d539df0f82c2d2890a40b191900594", + "96fa1f2196a3883cdd73c66d28403cbbb58f6a939a3697ee0d308d8a076393cbb4be86255af986869230ee410c01bcfa", + "a8b74438dc5cabd70a91bf25601af915c4418d074327a9b01e0190c27d3922c89bb9b41e0b366e82e313edda8f21983d", + "ac9fdc1a9b2e3ff379eb2370979372e13c4177bf4574f1490fadf05a7073e6d61e703e2d8eed9ce984aba317d411e219", + "a45a6c9b958169f2f8df70143e6ac3e2f6f969a4eed6fd9f1c620711bc2454739bb69f0094079464790c5429c0d8aedd", + "8901cbdd1009864386577842c1e3d37835fddf834064d9613b4559ea9aef3084204e1f863c4306f874141f4374f449ff", + "b6c582161691e3635536686825be9c4d7399d668a7675738417e0363e064dfd28acdbd8dbc9e34c1dab8a1990f1f0eba", + "89e89ddaf3cacc78428f3168549c161283ca8337345750667c98212717b21e7d994eae4e45bbddacc832a18df1d79276", + "84be275627eed8e1a73c7af8a20cee1ef5cc568cfeea7ec323d7f91b44e9653e9aeed47c1896a8240b99dde545f0e1fa", + "a779a54ab4f40228f6e2539595fb8d509b70aab7c19e1928c1be69ec1dc19285c3898cf15e5f8b8bc725e13af177fe17", + "92e2a49d2b9b36349d442283b17d46f8f9bf5932c34223015ce62d2f285e7363b2c12232be4a838b5b6cf08e694c094c", + "8b4e28c6f3f36caa2cfb82ba88066c830f8017bd35608b077143dff236f3181230166f5a5c02fa0e5272297331726aed", + "85fd77d46162ffac4b8adb25baff0eb0512a53a3d01638b3a376ea34702279ce21c8e7d8884308c03e00c9bcc1a9fd29", + "aad5e46916ff1be29009b595d1d8fa160cc7aa01c7fbf3a68f445c87615790dcab1fcdbdceda533d182b6541f09f2f73", + "948df7654726250dae393325addd3c0a20431c81f00470962190335ea4b6d9f7463d6f308cda46b92084c1f24390b1da", + "8f577474dea132676504376c5542b730b6604fe3d965eaa194659fd11c52233bd0b11ab62e198c0f442327ff1c00e501", + "ae2f1001546db3e0c19700adad997cd9f765fe7a51a502cbcd9a2a07a3a5db79c8f603e05cf96d80b688cb6c9b6cd3ae", + "953b68e5d9561088dd20406ea7fb6894cba33868a38ace38fc30b5813140cb15dd6dd2171befae5b4df2e4a9658889d8", + "86c52901655ff11419b084a04da8fc3596eae59d81d3461601c0baff59ba59e3d1dd0b7ce719e741a3e97c013e898579", + "b9a72dd5eff73f9912a28b55de073568efb3eb0241a10b77a2bfd4f30c2aa4fbfe0c89eb345c9f07fb725660873cb515", + "8e7353f5f2932e4ffd95811caf46c9bd1a53643c27eb41a4ebd211f230955cd71a8b27e17cfe8aa708d8514c0de67a66", + "a096b8e66312a92fb10839ebe60189a8d1bd34dff55f7dfae85e4d2f53a1a4a88211c19fc84494f066358ddce82be131", + "931c5cd82719d76596832b007969b5f75d65cffabb41b9dac7910300db677c1309abe77eeb9837a68c760bb72013b73a", + "8ba10f5118d778085122065b55dd1918fddb650cce7854d15a8f0da747da44d7b12d44fc29ad7dc38f174be803db74c6", + "8c971deec679372a328587d91fd24ab91043e936ca709c333453d7afd43ee256d08c71cb89f0ab0e89ae119831df6d86", + "a2ac28a58034fbd8fd518f409221bad0efec52670880f202e09c0530e2aabc2171ed95e99891790596ffad163d86c110", + "b3354e3dfa8068aba4f3741152b9204baa4e342c1cc77e6dd1419cbaf8da1d118be605846b8609e997d6a62a11f3423a", + "a12ab65a213c9d95c24865fddc2dffe0cf9fc527dd6bcdacc1bd7271e79929a4ab3427a231f4f49d0530474e6cbc88f9", + "90afd65b7e6973f8aafbe74da0f42441840d3c93bd69bc1bec8fa56824e7ca97ad1b427c8a85da7d588469bd4ccc50c3", + "a09175940c59489bac3d3da3a4091270d9118948cbbdd57f2bcc63fbf45b8010651c801d3e58dccf42733ce1d6b446a3", + "a843bbf286e3cecc1fe370ff1bcf5f1001bc2e95b34246625ff50d48ee62343e82fba2d25b8a4bd5f7b5ffe90920efa2", + "a3c4d1003219157fdbee2707ce07afa6c2a64ae8e450182c307ed7f070024071f30b12c4b0032960ff913c74e73a9976", + "b24af3f68d66f825d06fc3ff94fcccebe28b1a0d4ba29c48d3a3c953b9bf7ae6707f193fef25e2dcbd2b74e483c774f0", + "b0f657f7723184ef7d7e4381143f1ac8020d8c6c6f2dcbebb0eaf9870d61a81f2d452596503311e46d1b38f625d4756b", + "b90091004fc8f6205c51bec68547ac82dba0f5525631e7632cf6efe54eecd9020729fbee6105d1b8012402d3b79c54aa", + "8e3fa187713c60eb0a416d6900a894cdf81e6b6b69dae0bb64f6287f3c3f030cfa85c665f7aace1eab4937f380b8f728", + "879bf0784ccf6725c9cd1ea8c49fde31c91c605de1ea664a33c2ce24c277ee45d20b66309f98d989acb2ff3b77e13101", + "af3f3a3ddc4e11abd627d5aef8adffa91c25df5f0c68b4d2b5d51e7d9af3395ba4f6f7ae2325a6672847e1ecc6cad628", + "973e667289e796d3a40f072e6fea575a9b371a9997cf8961677f8dd934619ddc47c1a3efe91bae9ef95acb11a8fe6d09", + "afa81c5606de82f46b93f4bb6db3fc0670f4e0d1091388b138a66b3827322d95a56168c951c30831d59eeadc227500bd", + "b83eff77db5b4c18574662942eb36f6261c59f655f8a9c3d3731412d0f257c8e80aacc995c4b2303058a1ba32522a434", + "912e5ac9234b9445be8260393ff08e4859a7a385e800b74d1534eeb971f58f74cfb518dfdb89f8705d89fbf721439129", + "ab27c8ece4a51d23e22c2e22efa43487c941139b37ea1182e96efb54ca4809d8245eae0ebe8ba94f0ed4457896fe11b1", + "a6630585d104a745bc79dba266d9292bbdad346449c8ee8140a5e6e8a6194411df9cdbf3d3ef83468a536d4f052e9335", + "8b8c128244da48e7fec641a882d0005a2d05c7138d86a293e6a0a97c76bf632b44767d0ce44663c975e7f9f9679e25e3", + "87dbcaca67351a4e7d2297d7cdba4796d12f58857e7ee4abd0645563577ff33544a44cd84e50b3a3b420d6998de9b57c", + "b859ba43df259d7f8e7fac70bfd7aae546d57a5dc90e107b174a95bf7fd3cf00f740c4434848e69b2a7e6061f66c1ef1", + "99d6e20978fefc40c6d310187eb2ad3a39296f189ee122ed64d74f81033c3069d44f7a9d3988a1df635b609603a17272", + "99a5ddf3420cc0c92b21f71a805245608d4995ead447d8f73a670d26d33e26920d5f07bfe1f6230bd5f15978055b4253", + "b936ac0944d3c5e4b494f48f158000abb37b80b5c763f77fe856398c664b0f1ddbcc0a9a2a672db9278f08b4bafbe2ec", + "b4af85fbf4040e35a686dd016adec037c99b47cc2e4dfccaf7870ee9e8c97bff30f3035992def2a9d4af323c0b3af8ae", + "a5ee32b8bd5f8fa9000da4da0bf00565659a43285393d37080b555d0166bde64d87317b2eab2d48a0e7b287caa989be2", + "894d4ad58ecb1c9ebc4f5a97407082e56cb7358d7a881ba7da72321c5027498454f2c7fa2bd5f67a4b11d38c7f14344a", + "965be9eeaa0d450dacc1b1cc2fbf0d5d4b0dd188f2c89aaa9260e7307a2a1eb22db6092fccb662269e9a1abfc547cabb", + "805893c424aec206260c1c2d2509d2cb9e67ee528bd5179a8417a667aa216a3f318ed118b50d28da18e36c01f0805e3f", + "972d7040d4963b35260ef0cc37cd01746f1a2a87cedc0dc7b0ee7e838c9e4573784ea743f563b5267eb3905d4fa961ba", + "8c7156991d4c2e561888feaecf501f721b4174e7d14109e9deeac5a9d748301c07e11fb2b04b09799f0d34ff42cb77d1", + "894722ac35af3d507e81d737d21e16c5ba04686f8f004aa75934aae5e17acd3e065b96e229eb011c2f34096f4c62048b", + "81237937c247c88e8e31e2c72412189fe59c1daf65c5513489d86cf29ee922c0bb08e5f7890f09f4ada7e5262083d266", + "8cf62cda2fe0d9a6b42aa2a1c483f4ad26378c7cc2c2d1510a76df7560b07dba8528b33aaacb15f7f20b9d4c7c9f61f6", + "aaf0921fb3e1920eee5d0acb59dcc268b42f4b435d60d25d30357edd7dd758d035919691bd15311d85489dfa2e5ee696", + "92cec07be2247ef42002ebcaf65ec855611b8e893a5675796f2225f55412201b0bf9f4761924d0c8377b9f131e09e39f", + "8e514a62ac1e91773d99588415426c97ad63e917c10d762fe06ace5277a5c3bf3730e4b9e5d116f8493b9ab8687b70e3", + "83932df2d923a5052468a3ea87f7b55c6a80ede3594046ee4fe233046570921822bc16555b92ba6aeabaef9b1dc0805a", + "a2b5bfb249de3472113fd3f35bfabf3c21d5609da62a27ea6aab5f309c9068d94bc58ba03efb4ec11be06306d59e60e8", + "8106cf3ebe6f0507be8c6e8d137987315fe3689ecb75bb27980f36ba5efac504baccea0e7603549b6d126beccc278804", + "a73ee70b6fe8c082443972102c453fc0e386852476cf22224fc0bfe554735c12f96037fbf10922795f4502c4f052b5f4", + "932b27e175440169958504f3ed6400e7d6dcd5e716c19dcd0f15c56c04503ed133d5a993e111c016f141e32d68b29886", + "96f7ce4595318e0b4a6b368f788ff82226aac676aed4ace343867f751de414453a9aaaabef6e6224ce5aedc3d5cf77c4", + "a950c1e3bc9a14484997013d44d876374b939af437ae7c821c131fb886063ee9fe7214a25a0c7084f0b07b99412eff75", + "a9dba3886ed6855303106a1bdd26010f294218684e1c178afcfea3f37a2f04fd01724a31d82de3449046617e3507a115", + "87a2f776b32a6b550cf3ceeaf78db02819be74968d228b1d14e0d74a1cdf994bb500b7abef6619455e98d728701fac5c", + "8cd887b07e335edc0b27e6a660cebb64d210741395be431d79d570139687b056557159407459799a8197b6079644f666", + "b81a61fce00588909c13a90c1caa150f15788786af443ff60ce654b57147601f7e70b95659e01f470334a220b547611b", + "8aebc51141544c5f3d3b99422250424b9800031a8fdfbf22c430907a3a446fecaa2392105d66d64b1c8e847240da4a6a", + "90db7dc12baa02f3f86d3edadf9434e2b9318d4f6f0eca08276b765dbb38d8eb0d08be2fe70adf2bf16ceda5db08d3ca", + "aa1839894152d548cc6ad963de20fb6fcc843bc9af2a2bf967c63626b8ad19e900894d6106265f38f3afccca317c22f0", + "848e27b741496988a582515c0c8847b2bfc6a001259396cdeea1e1b1d2828ca3a626693a1bf4adf3a3d7f8b1fa3d75fe", + "a0aa11754d4ee136ac3ca609b17bcae77758763b2016544ca7921dddedd8aafcc7ad5f2b337c8bf53084eb8e43ea41fb", + "b8713b7aa1c112178195fdcc9b7024f46e6bc04c4e76c41abe620aa265287809200d98eaed6c9703fa97e81d6964f0ec", + "8605b5b33309e9ea6823542b85383c496794b8481c577497aaf99ba90496e794dce405be615bf92c7b6361460e6b82e3", + "826fa34faa7f83e063a7bf172addfc07badabada59cfc6604fdf481d29085251c0a67a1355b2cbd374e2975934b84cb6", + "b45d131082dc16fa53af010d43eefb79200dc23d2f3ee26af95ac6a5cebc49c84a9ed293e534ed16ff3ef9a4a25456ec", + "91bd6ce3c5396a7a0de489e49f0cdf6dce1cd2d0be7a410326423c3185bd1125ce1e610768be7f15f4e44b62f8834fc3", + "903ffbe3d33fbf106c01c727dc3a385201a67ded70d4df623934882f69a3a96c909b027a124f3d70cb072b0046a149e8", + "b405359db9d9ef4821a181b440ef2918c240595141d861d19a85867a5afa74d2972d22c988775eab441e734700bae4a3", + "8abb756d027233c83751910a832b0ef4d28d100077f1c5d656720c94906f91d85dd0ea94b1cc0ed95b692efee14c786e", + "a78ee77ab476a41a3454160ba7ca4085d8b1f7057c63e76db8b07cf20afdeddd2250cd00771a6329133bb4ad48ccc20a", + "a41810271d8c37197aa9b3dfcefe3498e42f5978d3f3d59defff4676d6402d8575b40683834f184f143b6cfbfc859b3a", + "90c24a0750242660bcc6d487358a3cc015730538a0a8beb00ad5ac2ef33cb8ca8a62121e50bec8f3d2f43900f8e3134a", + "8b96c39695d864ef5796941754978a1fd612b369f6b77fe5ae6587beac936ee28190af8f0a3822b63060af35e49a5c8b", + "acde2548883d0e63c0fc257bb9dadd919aba60a985b69ebcfa1bca78acca42fc1322ec30bcc8e7c188818f858d04ad33", + "895c86ae9ff8d95f2707d4838a3bc8ddb05b2611f0476f014b9c150d0e8332bc73285037a747426f09ac8179ba4e19fc", + "821761fe406e18bd86fa9ca9db99d382cd3b5c70c456f471fa3706d57763d147706304c75d54f51ce8f3115aa26e59d9", + "a803a80e3e8f47dc3c59ea23eafdec017458eac648b360cd42cbd075e0dde6f6f450b48c7646fb1e178c04f82ae51a12", + "91f40e1b6f588bd592829ce937996452c40be0fd6c43793c607866701ac6a8c7227e0891d45c6e7b1599382b0a3fbdbb", + "9408246d996a634a58689337f2526dfb3ba9ffef1d3ff91c32aa8cbbed900861ef25d6477308b67d76491edfcc70d65e", + "a492325a427f3df1c9c690c5b553daa8ac41f62f5ae55f425539222bacf959e2f67afabbba1732e120d3e7a6dcdf7049", + "8fd0c3e15477cae228613a171b6e9ec29ddc63ef74854d99b638adeffe39f89f34346a42851e8445e855a9f2bbef0f57", + "b735ed01fafa051004dbaad5e8c9e2faca8f6049ef9b590f256ea4d75b04594af12764ad4e6031735eae36f83179db93", + "a7d35f43fca06c86b3425dcb68a87186834ba9740664fd657915771beca4cdc0fa2fc9b4c2e9d9bdad8ec33543ddfa59", + "a1156e71e2db1b17df5da28747c88e091bd687bfee59d89096437ab4dc9a543fe5c5272d5023d72adbaab397a6fc94d1", + "ab06a58bd81b33a411bade8d8c5232d38fadc2e38507159edea6e2e104b8ebd65ca02b05335118f691d44197b847a4dd", + "848b67a10f1e6ff8f5c228f226ef2ffeb67fb8f50925fc94cbb588d61896d9dc79726959e649898fd3354fe3ff7b7ee3", + "aa933397361f32b388edcf832f0db172a38e756b34d5f7a4a050fa7325058006c22cede26ee27917e8f1b0f301792bd7", + "89e49e7f02cfaae4a4b9c4180c9f6559d76e3a45774955859d4147970b1470dac37bdc9aedca1c32a20b045049161590", + "adc1825d5ab94fc719f25d8c9773f4d518134ed88eb13ac33cb910b2be3523ef9ef88d9e4aea2418b806e20108317bf6", + "96c4b444c8a023da644f3a343ebeeed19a8392d2ce175992461451c318a54273b76c3574d8f2dceda2947ddd34d1a674", + "8aa7e97e87c8c5b29bbd51a6d30396a6be1fb82b716ef83800f2c36d5b85467ade7e0f59d2db82c310fa92a9265f0b03", + "9146c32d99f02c3a6f764dcd9b4807f1585f528ac69dc4f84e4380f6fda4f9d5057c375671d51e7aca2b2b4140e83da0", + "a10760a533d9bc57536bcaf65f080302086aa50225437efd64e176841544711828c23a15c49c0dd1f357d3f10722ab72", + "acb0811777e17f7ae7aaba5f6fce81b759c067a4908730916195a2505c7450d0e6e2194c2ef0f241090597d58e70de47", + "b24f161e9bcdbad56665e2490b5e4c7768390d4668cd69a04ed74739062dbe832636dd33cda89e9b0afa8c77e93fc641", + "96b4d01106b831868a88ef016500ef2fa42d0ce87a37ca8ca4194a92a22c113edfe04eb2ca037329f3c1acc635148f55", + "aebbb95fb4f7adcc8e7a217aeb73f9e037cbb873d08c1cd9d68c6c6834511adf1af8b44567fee84327599bdcb734dedb", + "a9bd8b17300532fb94d028659bcafbe7bbdf32f8945baf5db4cfaa1bac09e57c94cad0ba046b4514044b8fe81ea8596d", + "a5557cbda599857c512533e7cadcf27bf8444daa0602aa7499cafc1cf1cf21f9d16429915db7485f0e9a1b5046cf01c5", + "8810307c40bc661c478a9747ebf2a30e5a5ead942d1ac0418db36ba5db0709c476f7d19685cabe6959e33ec1f3bff914", + "8829b741f41f2c32e10b252d9338deb486dba2f23996a44cf1dd888ad967a589d51329be34d764139f372a1043f6c2e5", + "a6b4728d18857c5fa082fa67bfb3b1d801e76b251b1e211a19c87cea5fe7ce757f943c85071f7a03a718388cd5690e95", + "86da7f397e2533cd487f962ae58e87bea2cd50af70ef2df9ea0f29f70b5843cde664d30ec207ab84fc817f3851277e02", + "8085776ef4ac6d42ab85b9d9135ecc6380720efd274f966544eeedf4684028197de76ecab919fa5414302597e1962bca", + "b05a065c733033d223ba13d16baa7a97bd8c8b8b1f0e59a9bdd36ee17e9922d48eb39bd180c168b122088a77f0bf321a", + "a89343fe44a93023dcc7ef71bd3bcb6786f68e1885ad260edc56a52445d34757f476395ba7ad35437f89bc573c7618dc", + "a114a9cd6105b524f3969c69faa2e09afe21753a93361a296f9e0e3b4e3e63726ddf2e6bfd3ddc046043e50bd44e539e", + "8a5611fec539cf681c05636bb580f29acc06f628bb012649ffa41ea6c1521194a5643d5dd843f09b6eb2c3bdb4d41acd", + "ade247c4011ec73ec90b72f35afa59a999e64ba5a7e664a4b30874fea53ba6a14a76a41b58a5f891a20d019e5f091bdb", + "905b5d96df388160ade1ffe210d0c6d1979081bc3de3b8d93ac0d677cc2fc2dc1ef6dcd49d3947055514292a3fa2932e", + "a9520796ca9fccd11b7524d866507f731f0f88976f0de04286e68d7cf6dbd192d0d269f0cd60fd3d34011a9fe9e144c2", + "989a1edf4d7dae811eb57a865c8e64297837ffeeaae6ee6ac3af0f1044f023f1ca552bf00f1642491f0f0f20e820632e", + "879c8e63713f4935ed6e020559e140ea3073ced79d3096c152c430141272117b4fd9a9fc3eef012e81262df02ea14bd7", + "95074738ac1540c0312274333acd1ecad9c5509fee883c4d9295fa8d8200f6e637c363de395f9fa612f05c0dc58fae88", + "a770e4fc595269eb806b113ab3187ea75c8f96b57bf9fcfaf535f3eedc1d4d7e6285a20990575de0ff09f62d06ed0692", + "81283e5dfb6423439ff513eca1cc316941d196df8da2d1069d2d0b63f5289e630af2fd4119bc0144c002d33313372dab", + "abd1b108e743887b78f698f2aba9d5492f87a22868d1351d705d93a1084fd45be67170c68a6e18b07f400d9a01cda8c2", + "8509c3f67b92908cea8144f4e2a71631a66a61ac3547601c788907e52e380e5fe8ae4110aed95d13c67d3bcdd5b55a61", + "8fa5a790ec5cce6d4114128c295390120869aac5490a82feebd3c37a167120df2e7fdfaf2a4050a7dfebf48fb093212f", + "944753e1ea7d8bc727d46a7702077dc01dc0c6574e8263a16579b57ee155ca5901f71bb347a01a9a922b329d3ff75135", + "b46bc1fd4590b7a6275e20036d247c5909fc549c78e95b64ae7ed96e3b05bb044840f19f7650ebfe7008ba09fa83c3c9", + "b1e47e4d88e59a06c465348c6cc4181d40f45b91e5e883966d370c26622c328415c6144aa2f61ddb88ec752482c550ca", + "8bd4f8e293e3f1815c7e67167618fb3b0ea76424bc0985908957cfcede36109378e41b4d89555b8c2541b4c447e00461", + "a70589a867b2bfb63d0106083d58475d506637148549ed35c83f14e5c8de996e1b1f3447ecc80cf5cd134ef4db9d2fb6", + "8048b80ba6131d07370162724127b0f7cb17fa7f71855e55e5a75bd0a9e4fd71b0d0ea2d16ec98858e458528df8d06b5", + "97326cb94bae7530f4ec3235770c5a7ba042759e789d91c31fedbd979e3c0e6a2c69e2af3c1979c6fe0094274dbd53ce", + "a18e9c1d3eabd62af4e31a4b8e08494f4167fd4598c95d0123f39c46c53f9e93f76615900246e81a286c782ac37c569f", + "80309c59d4522b15aba617cd3c6238663e8b1c7ad84456346082c8f281140fc0edf9caa19de411c7e7fb809ca4fa3f4d", + "8e450c0990e2f65923f252311623038899eeff7b5c2da85b3a224e0ef7132588b291b782d53c477ecb70f34501466178", + "87843f96f41484e254e754c681a65681b9ae5c96c292140368743df9e60f7e2ada58ca2bb95fa39abe064b2ebf21eeba", + "858e8d5bf2a1cf26d8af5036b28b831d450a446026f58a1734b696c18f1f41482796b91cab0e5b443dd2f0b9cffa52b4", + "99627dd6bad8c05c5904cd23aa667d664da846496dbbb8452705c4ec01e1480e9c7295504a5a8529e4a0c842306b038d", + "b64b33256c18b2c886a837a0c0730fdfe73befb0e2796207c4dc592c5a33cd51f8c2ef47c584dd5773abf9ce9c1b0082", + "944f6da2a1546f0bfc4d98c3e73c79e935e33d208b6be26b0b5f8df6d0e3b74a5bda649853b99281bd3a3ec799a7dd04", + "a266d165435784d4e884640155e35b2a911b3f89e1e715986de419b166a36a341ba724877d80583fa3da566f6a828971", + "adff2698409d0756e78c534032ee926560c13d578cb178d5073172d049ebbce32a92692f7e2033ec781b9b0d894ddce0", + "a91933f110756c699c28bf9e24fd405bf432002a28c4349e0ca995528e56a5a2d101b8d78afa90a178ff1a9bf2ba515c", + "8e77839c0eb4da2d01e4053912cd823eddffbdc6b9c42199fba707ca6ab49fc324288b57be959fbfb11d59085d49324a", + "aa124517c76692036c737e987f27c2660514e12a953e63ff4bcb269dd18fc44dae95e282de8444bed09639ef6577af88", + "b285deae99688f1bd80f338772472fa2b35e68887c7eb52c4ef30fc733812444c5cd110050275ad999d5a9b57f782911", + "8877b0fa85b44ef31f50bdb70b879fa6df5eb1940e2b304fd0c8f08abb65f3118fa3d97ff93919038c1e452fb1160334", + "8a89f3b50dcbca655024542ca7d93df17deff5c7d01c7da2bdb69e76b3e0b4490d85c800fb3debb4b0b4d20c9527f7ad", + "b7e5dbe36e985354ac2f4ab7730fea01b850af00767a6c4d8ee72e884d0fe539bb81f2e34638fcf5d07b7c8d605f4c06", + "a85a1d78f6d4f9d5d83ec0f2a426708342d4e4a5d15625554e8452f6a843d9aa4db0c7e68caebdaf767c5b3a6a6b2124", + "a518078a9dac63c5bf511b21ed8e50d1ccede27ebfe9d240937be813f5ee56aef93dc3bf7c08606be1e6172f13f352ce", + "91144eedebda4d1ad801654ef4ecd46683489b177ba1de7259f7dd8242c8c1700e15938e06c5d29aa69f4660564209a0", + "a16c4657bc29d1d3271f507847b5a4f6401cee4ad35583ad6b7a68e6c2b9b462d77b5dd359fd88ea91ce93bb99130173", + "85b855778f4b506880a2833b8468871c700440a87112fa6a83fd3ddb7e294b3a232d045dc37dfc7100b36f910d93c2ae", + "8d86bb149d31bfbf1fabcae1b8183d19087fd601c3826a72a95d2f9cedb8bb0203d1136a754aa2dd61f84b7f515acfa9", + "acfe7264eee24e14e9f95251cbcfdd7e7f7112955a1972058444df3c2d2a1070627baefada3574ebd39600f7f2ea7595", + "906bd14ecca20ac4ae44bff77cc94eb5a4ecc61eba130de9838e066e8766ed3b58705f32c650e1e222b3100691b3806b", + "8f2cbc7b8593c4be941dd01b80dc406fe9dfdf813ef87df911763f644f6309d659ea9e3830ff9155e21b195fc3c01c57", + "a68eb15ed78fae0060c6d20852db78f31bebb59d4ddc3c5bdd9a38dbe4efa99141b311473033ff8f8ea23af219bc8125", + "a95cb76c9d23fc478c7e8a73161f2ff409c1e28a2624c7d5e026e3cee9e488f22225a0c5907264545a73e83260e3a4ec", + "b76f90e55fa37c9e2732fd6eba890dd9f1958c1a3e990bd0ce26055e22fe422d6f0bcc57a8a9890585717f0479180905", + "b80cc95f365fabd9602ec370ca67aa4fb1219a46e44adf039d63c432e786835bb6b80756b38f80d0864ecb80e4acb453", + "b753c86c82d98a5b04e89de8d005f513f5ea5ea5cf281a561d881ed9ad9d9a4be5febb6438e0dba3d377a7509d839df0", + "a664733f3b902fac4d1a65ea0d479bb2b54a4f0e2140ed258570da2e5907746e2ac173ace9120d8de4a5e29657ae6e05", + "9479722da1a53446e2559bb0e70c4e5bf3f86c0ce478eede6f686db23be97fcd496f00a9e174ceb89ab27f80621f9b80", + "b707fd21b75a8d244d8d578f3302d1b32bb2d09f2bd5247dff638d8b8b678c87d4feab83fe275c5553720a059d403836", + "93214c16831c6e1d6e5a1266f09f435bbed5030c3c4c96794b38d4a70871782002e558d960778e4465b1ff296ffedad8", + "8648f84e18eb63dad624e5fa0e7a28af2ee6d47c28f191be0918c412bf24b5460c04bf2b7a127c472914a0741843f78b", + "b67f61e75d6b773a6b58b847d87084b94f3cdac3daa7bef75c2238903a84250355a986b158ff96ba276ca13a6035fdd6", + "ae9b094b7b5359ee4239d0858d3755a51aba19fce8ad82b0936cca48017523319c3309409ea6e9883a41bece2077e4d8", + "8d1d8e1fba8cebd7a0e1effea785a35e16b1a10842f43e2b161d75add11eccf8f942d2ae91c20eef6c1a0c813731ea9a", + "b82bd387458e3603782d5e2dec32ae03890a3fc156d7138d953f98eff4200de27c224f626e3648e80cd3dfc684c4790f", + "a6dd02a89ad1c84e25e91176c26355e21a01b126c1df4d22546159dab9d502dbc69bc0d793a017c1456516e4aa5fa53f", + "a9ab74a5c5459b8500beb0ad13e9cfe2656e966dc9b4f3f98bec7588023b4ddebf74e4fc722d30423f639f4ee1b2587f", + "b03e5f33ab7ecec12cbc547038d3fa4f7ea0437e571891c39660c38d148212d191be29e04eb2dc001b674219b7a15a9c", + "925df4fc6e898ca55090ad1a8f756cc5014167a042affda5b24896eeb6aac408545134920586a8e1a2b997de9758b78a", + "98c8580fb56ed329fad9665bdf5b1676934ddfb701a339cc52c2c051e006f8202e1b2b0f5de01127c2cacf3b84deb384", + "afc3765d374c60fac209abd976fe2c6f03ce5cc5c392f664bb8fac01be6d5a6e6251ac5fb54cfcd73e3b2db6af587cbb", + "8e7e98fb5a0b5b50d1a64a411f216c6738baaca97e06d1eba1c561e5c52809b9dab1da9f378b5f7d56a01af077e4f8cf", + "b724bf90309651afb2c5babaa62dc6eac2b8a565701520fe0508cee937f4f7b6f483fc164b15d4be4e29414ce5d3c7d4", + "9665160e7bf73c94f956ecb8ba8c46fe43ae55c354ce36da40ccc7594beae21d48d9c34d1af15228c42d062a84353a0c", + "8600ab3aa86b408ee6e477c55572573ed8cfb23689bbdadf9fccb00161b921ec66427d9988763a7009b823fa79f8a187", + "b0d8d19fd1022e7bc628d456b9bd1a2584dce504eb0bf0802bdb1abd7a069abbeeccdb97ce688f3f84a229342dbc1c33", + "8f447d5e5a65bb4b717d6939cbd06485b1d9870fe43d12f2da93ca3bb636133a96e49f46d2658b6c59f0436d4eede857", + "b94e327d408d8553a54e263f6daa5f150f9067364ded7406dcb5c32db3c2dffd81d466ee65378db78d1c90bc20b08ab3", + "b58c02781b74ef6f57f9d0714a96161d6bfa04aa758473fb4d67cc02094cd0c0f29d0527c37679a62b98771420cf638b", + "8cfa0a687ea51561713e928271c43324b938aa11bb90f7ffaa0e4a779b3e98899f2af59364ce67b73a46a88748c76efa", + "95d6d39c814c5362df69116558d81ce6f1c65fb400fc62de037f670d85f23f392c1451d43341c59bc342bc31842c8582", + "af888b384c52d9e04e4db6c4e507c2037eb5857e9bcc33acf84fc3a02d93cbde8cce32141fce9f5fec715b5f24d56356", + "a7822bbc3c236fd58bd978f0fc15fe0b60933a0c953db6436a233441219418090ae0c07c490a6548e319029771cdaba7", + "8c53729f750922e5eb461774be8851a3f40fe42eed170881cc8024d590bf0a161d861f5c967144d15cdcdc3dc6b5cf88", + "a052a25a4aeab0d5bb79bc92a6ae14b5ad07d1baca73f4f6684ccecfc7ea69bc21eadeb9510452fdba116c0502dd698f", + "923946b83d37f60555dbac99f141f5a232728c6eb819a37e568c8c6e4d9e97a4229fb75d1de7e9d81f3356f69e6d36f1", + "8cab82cf7e415b64a63bd272fe514d8b1fa03ba29852ec8ef04e9c73d02a2b0d12092a8937756fdec02d27c8080fb125", + "b1123314852495e8d2789260e7b3c6f3e38cb068a47bdf54ed05f963258d8bcabaa36ccbea095ba008e07a2678ec85a7", + "a685b779514961e2652155af805996ceb15fb45c7af89c5896f161cac18e07b78c9776047c95b196362c9ad5430bcb22", + "b734dd88f6cc6329c1cb0316c08ade03369a11dc33191086c6a177cf24540c7ceee8199b7afa86c344d78d513f828e81", + "b0bf492fb136ecdb602c37636ed4deef44560ab752c0af5080a79c9f76a1f954eba60a0bf6ba8bd7b8cac21848c29741", + "a5c74682323e85ac20f912ab9c1d6e1b9246c4c829dca40c8a7d58ec07ea0ad3524be30623f351269552f49b65a1245c", + "837403b9cf830fb33ecc11a7c8433e07745973c36acdeb3fc9ea8f7d8d690d462e1250b7410f79f2f4180fe8f3962a4f", + "b03d64b944d49c83608f2c5b9c14070c025f7568c4c33d4eeb1da31d07f0bc5897e498b35b50d557ee129f0c3c68e254", + "827272aab8bf757e2483156e00fbebe1093a58070dd3af9855bbf946c7abfb9c8a850a6a8acda8c620902f391f968b8f", + "84c4eb863a865282d321302d06b362f8bd11c2bb0090f90ebffedd3eb3e7af704cff00d39a6d48cbea4262942e95200b", + "b044eb91653dc55dce75c8d636308a5a0dae1298de4382d318e934140a21ca90e8a210e06fdf93aadbbeab1c2ef3904a", + "a8c08955a4378522e09a351ecb21b54025a90f2936b974068e80862803e7da2b5380c4b83b4b4aad0409df8d6c8cc0cb", + "a763a5fb32bd6cb7d7c6199041f429782deacac22b6a8467077fab68824dd69343ebca63a11004c637b9cb3129dbf493", + "8c44c8afa9a623f05c2e2aba12e381abdb6753bb494da81f238452f24c758c0a0d517982f3999d2537b7279d381625ed", + "8613f47fda577cd3bda7c99b80cf4b2dd40699edfd3df78acb5e456dd41fd0773bc8da6c5e8cbf726a519b9fb7646ccc", + "b21a30d49d7e1c52068482b837a4475568d0923d38e813cea429c1000b5f79b8905b08f6db237e2eccf7ef3e29848162", + "b9bdf4915f3fbb8d84cdfd0deedf2c9dc5b14f52bf299ef5dca2f816988e66322df078da2c54b934b69728fd3bef40b5", + "993b45f389f55eba8e5ba1042d9a87242c383a066cbf19bc871b090abe04de9ff6c1438cb091875d21b8c10fac51db58", + "a85a95d14633d52d499727f3939979a498c154fd7ebb444b08f637b32c1caf5cca5e933a2f5d94f26851ae162707b77d", + "b9874c7c4be1c88a9646e0c2f467cd76bc21765b5ab85d551305f5ec0b4419e39d90703d4ac1bb01feb3b160517e97b7", + "ad6771177fc78812904c90594712956357de1533a07fec3082ba707f19c5866596d624efc3e11773b3100547d8f6c202", + "a79f31921134f7197f79c43a4b5d5b86736a8d3ad5af1bdf4ad8789c2bfe1c905199c5e9f21e9f446247224f82b334f8", + "a7f1b6c45321222a350a86543162c6e4e3d2a7c2dce41aeb94c42c02418f0892dbd70c31700245d78c4d125163b2cd5e", + "92abafe3ec9dbe55c193fb69042500067eb8f776e9bf0f1cb5ab8eb12e3d34986d1204136856fb115c12784c3b8dea6e", + "89bc761238a4d989006ca5af5303c910c584fe7e6f22aa9f65f0718a1bc171e452c43695e9f5a591725e870770c0eceb", + "aa0e44c2b006a27d35e8087779411ba2f9f1966a0f5646ff6871bcf63a8b1a4a7638751b94c9b9798ccd491c940bc53f", + "8736fe82862b8106e7fdab7b5a964d87ec291a74b8eb1cb5a6c046a648c1b686064ef3d52297043b8940bfe870c712f8", + "956a3def1942f05144d8e9c3a82fd2d3610064b53b9eefde3d5594a8f705bf8f6849eb2c22181796beffeba43cc74ee4", + "af27416d00cf97d5a1f4a1b6b51c010884cceca294f1151c3b684a3f83c3c8a3c30771df1166d833cbddf6c873c400c3", + "aac3b8dca2336fc4ffc63c362df461289e4bbd3418c621bde6c581d3ecedf66e2b3e523d4db39e3d8ba014577bf85efd", + "94c3a8167f62074e5b28c2bffe4b6ce645439a9a0c5da3ca1b3ee956590a465d6f84a8a4dbbe9070ffbd6bbc734e4d62", + "95e23ba6986d25ed4451215da05bd72c5491528271726d79a94c8cb16aef1c85b190d6c5b8a3a1191c7cafbab1dccf0c", + "953e3dadb5ad68f7de31ac09692948655d174fe16d88b96930ef35b331da7f1dbc4c17863cd07b4ec3135b5205891a27", + "915d018f18b5d63cb3301c2bb5c6e85e75a88ba80663c964d06575b6bacbbe59139d030b218ce0998271d5b28c00b26d", + "8c871ba3dd138a908b2f7effeea0e71df096b23e0dd47cab10b9762b250abfd1221da94a8ee884e05bdf02271fb85a04", + "96bad5c6ebc3080ecbe337409ae398bbeada651221c42a43ea3b7c08c21841ddbcfde544c9b8d4772de6f2ce92c0b963", + "b5dbcd0b1c44c62108841558ec0a48df4b327a741e208c38b1c052321eda6e6ad01af71d49dfcdd445ab6fa6f0c34e6d", + "97dba59219b69e8aef2659d1f10bbea98d74aefff1f6451de3f41be39acbac0122b8ff58b02e90554469e88911ec3547", + "b7e5682ec306478be4858296f5d03364a61f3260636a4242f984d351a02e8723378496beb30c4ca22def9c9ca193ea70", + "9656a7a3df4d11df3d8bc35930dff70a5e78a488ca57bba20bb06814fc390fc6c7cb3f39b22134992aad196cced577de", + "8b269695aa63eb56d0324ba984279dc4c88e565321f1d61d553622bd4f1910d5eff68393d3a830eb924472bd478c2aa3", + "9177bcd04b28c87bc0440268b4c8995c6790cad6039594971b2c177f0e197055231e776927d3fa30d98fb897a2ba401f", + "ae0e943973482001c4f214b9da82e1c27e38aa254d0555e016095c537c835d3702bc2de5c67b234ab151e02b3b7a43a6", + "82fc719a7d38bf4787fe1888019ad89fbf29beb951d2fece8686d2beb9119d0c8c6d13bc598748c72c70d73d488140ca", + "b716dc66f87eb16b95df8066877353962d91bf98cf7346a7f27056c2a4956fb65e55cb512af278783887ab269e91cd76", + "81d58cd8bc6657362d724b966321cd29a1b5cdc4601a49fa06e07e1ad13b05e9f387ca4f053ed42396c508cd065c5219", + "b32ad0280df6651c27bb6ddbdc61d5eb8246722140a2e29c02b8b52127de57a970e1ded5c2a67f9491ae9667349f4c46", + "b68a2eb64cc43f423be8985b1a068e3814b0d6217837fb8fbfd9c786db9cca91885c86899c50a1242040b53bf304ced9", + "85887515d4e371eabb81194cbc070e0c422179e01dbda050b359bd5870449c7950e6b3947b7a4a0eb68199341cc89fc3", + "ac5fff3c27dfbab78eb8aad37ac31cc747a82401ebf3644a4f4f5aa98d37b8bf3b3f4bd8a3428b32a127c25c9e19d239", + "86fceaa6fbf8913553a9e1e907fcb1f1986d5e401a7eafd353beefd1899d571454fea96ff5b2a21254d9fb693ec94951", + "b6778bb296d3f0de2531b67d36fdbfa21475be0ca48b9dfcc38f396c41b557823735ed0b583e525a2bae1fe06e04058c", + "898088babeb5b9866537d6489f7514524c118704abd66b54210dc40a1c1ddb0a1edf7fe0b6e0db53b836f1828ecf939e", + "b27854364b97274765f0fb8d1f80d3660d469785d1b68da05e2bd1e4b8cbbe04304804d4c8aabb44cf030eba6c496510", + "8c55bbf3603dc11cb78b6395ccbc01e08afcef13611f7c52956b7a65ccf9c70551bff3ae274367200be9fc2d5cb26506", + "947726f73cd6281cd448d94f21d3b91b96de7ad3ff039f9153befbb5f172db9f53cacb4f88c80a3db26e6a0f7a846eb0", + "a7b733a05e97528812d71cecb4f638a90d51acf6b8fcbc054787d6deb7e2595b7b8d1cbe1aa09d78375b5e684a2019bc", + "8d5ca6d161341461544c533314fe0a6655cde032c2d96f0e4ea7e41098b8b39fa075d38e2d8c74e2d0308f250d6cf353", + "b960e9f081393e2260b41f988935285586a26657a3d00b0692ea85420373b9f279b2f1bb2da2caae72dd2e314045f1bd", + "852a49c7388c10821b387c6d51617add97ba72485f52be95d347bac44c638c92e9c6a44ba0d32afc4d59178a497d944a", + "8412162a65147e1334ad5af512982b2b48eef565682b3f3e0bbe93fbc5e1103db9375a0c486bdb1b2c57e4cb3a8e7851", + "8f52c3eb5d4f1e1e82cfd2b291d4910195427603b796f6c311deb35ef14a01a57a9e6cad39619ad108f3e86f384f9e1c", + "88d221088f2bf0103c53e44d0d96cd7881ec2b0a965db9121a47481771a8b796edd5ac23c4f9c208a171dab301f7d3bb", + "b49c3235e8b3617ed08a1891b9e2bcb33dbdacceb94ca96330555b7e00904fe6a749ced9312b8634f88bcb4e76f91cb1", + "a85834215e32f284d6dfb0cbfd97f6cffc7b9d354e8f8126d54598bb42d7f858a2b914cf84fa664069632db2ff89a332", + "aa3d48eb483c6120c27d9b3e3d0178c1c942632ff54b69f5b3cfbc6ad4ff5b2b9ce6eb771fd1eea8edf4a74c97027265", + "a446cfded353cdd9487783b45846402b973cdeddf87e2bf10cf4661610fff35743cc25e8d3b5771dcedfb46b018a5d18", + "80998377b3b393ef3073f1a655ad9d1e34980750e9a5cfb95f53a221b053ddb4d6985747217e9c920735b0c851d7551f", + "a35ac469790fac6b8b07b486f36d0c02421a5f74ea2f0a20ffc5da8b622ac45dfccabfb737efa6e1689b4bd908234536", + "8fb1f6d8e9c463b16ac1d0f36e04544320d5a482dd6ffaec90ea0f02b4611aaca984828bf67f84dcc3506b69af0a00a1", + "b6e818d61aea62c5ed39c0a22ccbb327178feebdabda0c9927aa1549d2c5bb0637785c4aed2a6d9a7b4989fa8634c64a", + "b4e7208d16018bf67caafe996d436113eac619732e3f529a6efb7e6f094d8ebea55b7be0e122be075770f5957b6ea6f0", + "b691d38b552befac61f6d367287c38d01fec73b7f2efdb6713ca30314a37fb7c177eb111fe6bee657f2681014e07630a", + "9817587e418e6e7e8e97ae27067f17b55d25dfb14e98f63f530620c855d9a348c9fa571c8508e2741f902f8b9fdc0c5c", + "b6a6e5ca779ba140bf1d84cd5394ede8262f7479637ec0087a4b152243a1774ba916d8115ce759a3bebd1b409de5f2fc", + "b53d1c84ad766ff794bf497db3228efd2cc8ed5fc1958d89c1126efdff361610ecb45ea8e329b39035ab00a66c1259c7", + "adc31333c507c8e0f4aa2934fcdca57fd9c786722a50dbd5404e129541f7ac182cc7373bf14e1e4e06e6cf94b31b90eb", + "a82b7fde4642d982d95cec669efee140ad797a2442c7f6620580527d163accbf021b893446cbb8038ea82fe25b15d029", + "91f7acf8a8903979afa281646fdecb54aa4d2ed905748e156e92f0910de268fa29d67107d40863935d677d1de8039be2", + "86fea71c6d43a7d93216a92fc24dfce8521fd4534a9558b33762d002081247867a6eff54cad7116023277fb4049403ad", + "8ae5369a7f9f4c91f3be44b98089efd9c97c08f5bb4cd8b3150c115ecd86288fa0865a046a489c782973a111eb93966e", + "b6fb9e829aa2c81c2d9eac72bb2fd7f3a08e0cd763532c2ce3287444d33cf48b3621f205e9603ec58525934b61a795a9", + "83e35ca808d84e41fc92115e9f6e283e928c3a614e6dfc48fe78c33b6411262e7bfa731eadb1e1937bc03cff60032e1d", + "832fca5196c95098ad47b7d24ba2f9d042e1c73ad2273edd1c2ce36386796ccc26e8567847697f3fcc2a0536a2a2087a", + "8fdb7038bc8f462ab2b76bf7053362f9c030019f1b6105cf42219a4e620ecc961e3eacb16a8e581a562a97f1418b0128", + "8d3a5a404b51b1ad8ce3b23970e0d5cc57b573922341008e3a952a1dd24a135e19e55b79d86a70cfd82e1c0e9630f874", + "ba00c025c1c21c57c03cdfc0bfd094b35422281ff0a64b68b240617aa58c6b18800af5f2047d3ff9068bbe987d6c7980", + "b468f0dd51964b3806b0aa04f3fe28a035e8f5567fc7d27555be33d02701a838b8dbfe1348b6422c4eac46d2c75c40c7", + "8a73a18c97da9958903c38584b08d0e7e26993a5d9b068a5e0e1ee0d8a873942745cf795f94f7a3d3ba88790a9fbb2f6", + "953a0a40c2c8102723736854d13b228698c14a02d85c8d2e61db1a768019ac305faf0d5db62ac976430ce087a5b20f1e", + "8998219da6b34f657cb8a621c890a52cb98c2bc0f26f26e2af666eebeadadc5e8bdf4f830a91d04aca8ce186190152c8", + "8941e08c3155ad432236ed05460420a05dd0aaab30477493ffb364b14c00ea5b9183d30d3442b6321d2d20c36e4f5c7e", + "93f293ff7fb56cf5b03aee6f3ad2ad78444398ed5b3be56d7bf5b56b5aa5a2b980d13895dd57a5726d1b067c20cc55e2", + "84a16f313e3f75e31824f58d19ab24c6611fb4c75140a7cadc3c166f68819547c1d0ff7f7d13f5d8ae30dff1d80e2aa4", + "b6e3e830b15039d3e28b08f5465bb089eade11ee3bd80afe39e010df7db1fcf0c56d698717677a41ddbc91eeaf6544d3", + "95e928e6dfff51351281568ae72da7d1edeb6e9fe01f30af0499e7505ba35a22b5bb919d41bb809a432dce83f3977663", + "aabeeb60ca46f9b0232ff82ea7766dcab8cc5aaf9d23539f30174f9486640bc9312868ca493b59b314519fc399973e47", + "b393a11e957d0bbb3ecf617b075b5906a3450b348e62916c04791b366f0a7397cccd6648440ac544bc30526e1f95aad8", + "abb5bfc3964a6d246da60bd809d0ea6daf4f8222efdc12ceb6730194e85f413ee7eb03bae300abf7ea900dbbc3d08971", + "96c1bd1d1d216a4bfbcf000c123f296c0d31e1684e9e3884c14df23bf528c8d599f82bb98fcea491716b617216a8e0be", + "92d1e570a56f1741fd9f3d9f488cc336421c6256c14a08d340a63720be49b0029e3780e3e193a2e22bf66cc652fa22a3", + "8769c08551e3a730e46f8e5d0db9cf38e565a001dfb50db3c30fa7fa0e98b19438edc23c6e03c8c144581b720d7b33a4", + "b850bd67fdf5d77d9288680b2f6b3bc0f210580447fb6c404eb01139a43fccb7ed20051999ae2323ea5a58de9676bfb4", + "80285da7a0aaf72c4528a137182d89a4db22a446e6c4a488cf3411937f4e83f7b00ec7549b0b4417682e283f91225dfe", + "80520368a80b97d80feb09dbc6908096c40ff7120f415702c1614d7112b0b57f6729581c71f4a3ce794ac959a46494ff", + "9817b4c27a490b1cd5a6337e7bc7e8005fa075dd980c6bf075ddfa46cd51cc307ad1d9f24e613b762a20fc6c877eab41", + "ad66bda1a3034ec5e420b78107896ecf36126ce3ef9705163db259072dfa438c6107717a33572272062b9f60cb89557c", + "876114ef078c2915288e29c9abe6b0ad6a756b5ee2930ba1b8a17257f3f0557602d1225e8aa41ce8606af71ada2a971b", + "aa3d6cde4c3b9d3d5d0c77a33e67f182a3e1cf89b0921423b2024236171955b34afc52b1f25b1dad9da9b001371771d7", + "984d3e3a72412d290e3459339757af7520d1739c7af0cbcf659c71999328db44f407d92e8a69fea11625612c49eac927", + "ae890d0faf5bd3280dcad20a5f90e23a206661be8842375fea2ab22aadc500849ffbc52fe743b376d46bb926cedae6a6", + "b1f231f3f4d710c3fe80099faeb56dac67c1baf53b8fe67a9920fe4f90e52cb9a4bf19211249a6456613b28efe337f18", + "8caa54b418ba609d16520af3dff2e96d5f2eeb162c065a1763beb926547b2cfb3ae41d738db2c5681a9bc8bc9e6b9a1a", + "932157ff56c5ac29cf6cf44f450c882b3acfbb9f43d12d118da3d6256bde4e6eb3183aea304ab6967f37baa718ffec99", + "9360bed8fc5b6aac36aa69473040689bfc30411d20ffb7275ef39b9ff5789f9055d149383ce9f0f7709a1f9d683adbfe", + "98b5b33209068335da72782179d0c7aeeabe94b5560a19d72088fe8323e56db7ce65debe37a97536b6b8a0ca3b840b61", + "89a385c11be40064160b030a1bb28c3921fc8078522618a238c7ea0f86f34717ed9af9b4e2e20f5128e5f7fc66ad841e", + "b615703cbc64b4192990cc7e4903b74aed6a0076ce113b59ef7719197ffa46fb29eb78ca56b49873487432d0625c0faa", + "90f0d77abae9d3ad73a218e5ccec505ad108ea098451461567ae8ef9661606ca8e78df53b5d628b20b7037bd24622330", + "92e0e7cc4dfadc5fa0ee6da0c8de0493030db6e54ba0317f52f232a6708b732068b6077bd13a17eb7eb40b88368085b5", + "a24dad20094985bfccc6df1343506ed3bf9dcbdf4b2085a87627a5d71f7568db067304e465f8f380c5c88e8a27291a01", + "8629a45a10619354c84bdc2f6c42f540eab5a46f53f2ae11970433d7a2aef007897590bf31dfba1c921614c6d6fe1687", + "84ac64040d4206f82b08c771f375da4b7d752e41d2aa0da20ce845f6bc1b880a855d3ee966bca19b8ec327b4b43e7f0e", + "9608e6050c25996c052509f43f24a85cdf184135f46eaac520a9a6e78e0d44a6cee50ebc054048c708aefde8cd6651c2", + "a32032b0e0d7cc35e480c328f315327f9385adb102a708c9ba637878deb74582ae26bb6d6e5f8c9e3a839b0e0154b82a", + "b7e3c78d63acc6564a49e9f00b0a820b56d4f37a2374af1f7f1d016268011df9e7af0670ed2b0eee961f15aa948328dd", + "8b88bfdd353acc91ad0d308a43e5fb40da22c228f2fe093c6d6904d70f69c6203f56636ed898b05df51d33f1095ef609", + "b1d7a430c51fc857af55047683fc18c453b013527196c5e1bf776819a3dffca802217e9249ae03f084e2ea03ad67fcc2", + "80558e28a819ddb5e72e97c54be0f57c173ccf78038d360d190b7f1350a19577b8e3f43fa2f7bf113a228cd3b965b2e4", + "b4b2ec44e746c00dfc5661ba2514930934fc805cdc29adc531c02d28ce3cc754414b0485d4ee593232cd1175f357ad66", + "b57cee5d32835f76572330f61ccd25a203f0e4a7e5053d32965db283aad92f287645533e8e615137208383ec51b1fd99", + "930256086b419a8a6581c52590d0dbd9f8a3564c79424198fca3866b786df2f6098a18c50dc4abd20853a7184b1ce15d", + "8e75fd01181cffcd618a983492390f486e8c889972a46c1f34a4e1b38f384e8e4efc7e3c18533aa2057da9f9623e2238", + "b375d927dd988429f9e2764e5943916131092c394fce13b311baa10f34b023dd3571da02553176091a0738cc23771b9a", + "b9e28e4c0d0477518034d000e32464852e6951c8db6f64ccdb1d2566f5094716213fbf2fc0e29ac88d0e79f725e3c926", + "963981e99392afbd2b8318d5a6b2b0cc69c7f2f2f13f4b38dddbfedb2b0eaf0584aecfcbda20a4c60789c15d77970a58", + "a7804e1977aa77c263c7c001afa6cf568032dea940e350d6a58ce4614f1a91c13ae1c78bfea740c229dce2444556976a", + "8787204177da3cde6d35cd3497fa8774d244f9faa9f4bd91b636a613a32ce2ea0326378cf9c4cf475e73ef751b355c4b", + "895aeef46a07152a04ec812f1aa1fd431389fa0ef6c6e96a5b833e70ea14073bc9984757a8ee456dbec9788e74e6f0ca", + "8d17f0e5826783440d1f0ec868003510a4d9952bfe4a638e44a36d94482ac18ba70ef7ff773bdf7a3b62d714dcf0fcba", + "810d5e36b31310b2e054a666d3b3f7ed16dfcb1765532d87ca2a3920316f0187303c27dd113db145d47e8961062a6c03", + "b4e2fb48ae04cf8580bb6a28095076c9b95e5f13122b917328f334d4ac8a8648ce442919e28319a40148987350ab5303", + "b85549a313544fa1eb3ceb78473b7d3d717fc85b808de7b79db7dbd0af838ebb020622a7503f1cbacab688dddb648f84", + "80665adee057088eae827a5fe904ec3ad77d8843cdce0322d535e0659b4abc74a4d7ddd8a94c27f2def5c34ac2c038ee", + "ad72fc19c2ce99b5b717e35528fe7d3ac8add340b02ebeb4889d9a94c32f312a0b45ea84d21c54f84cc40ee4958b72e1", + "99d530c843dff89a47a5ee8c87303ab18f8a82b0d5b808fca050354b35da5c5a5594d55921c6362d6cc917d75bdc18dc", + "99c7286c293e1be21c5b2a669dfdfcd5aa587105d2886fc5a8eaf8984da4e907f7d7b8c2362d64a4f1621b077a2a08a0", + "b4a39e1a9ed5d80c9563c3ca3fadf76f5478c63a98f4346a61b930c9c733e002f3ff02bc16abfdb53d776184cc3f87ba", + "9378ea71b941979404c92d01fb70b33fa68d085bf15d60eb1c9fc2b5fcdee6379f5583389a3660a756a50019a2f19a69", + "b68e17344a2bc45b8e2e19466b86dc139afefbf9bad2e2e28276a725099ebac7f5763f3cb52002261e3abe45ef51eb1a", + "819e64dc412b2d194d693b9b3157c1070a226af35c629837df145ea12ad52fa8eabd65b025a63c1fb0726207a58cdde8", + "a5e8ff8748419466ff6df5d389125f3d46aedacf44eaf12cbfe2f68d218c7d5ab6de4a8279d13aecc25f3b1d98230894", + "91560d54a9715cfda9cf7133ae51c432d0bf7fcbaeb468004994e6838bfc5ddcfa30e4e780667d0c4c0376780b083017", + "ae8adb3309cc89d79a55ff74f129bb311fe4f5351a8b87600a87e0c3ba60825f71fccf67eadcf7e4b243c619417540fd", + "8d92cc1a6baa7bfa96fbce9940e7187b3d142f1888bdcb09bb5c8abf63355e9fb942ac4b4819d9be0e0e822d3e8e2e08", + "a6e8b79fdd90c34735bb8fbef02165ccbe55ea726dc203b15e7a015bf311c9cac56efd84d221cc55eaa710ee749dbdfe", + "a409b151de37bddf39ce5f8aa3def60ee91d6f03ddd533fce9bf7bdbeac618cc982c4f1ffbf6e302b8353d8f28f8c479", + "b9693975ef82171b3b9fc318ca296e4fe6110b26cbdfd653418f7754563fa7b6e22d64f8025ee4243483fa321572bfe4", + "a039ebe0d9ee4a03ade08e2104ffd7169975b224061924cca2aae71464d250851e9f5f6f6cb288b5bf15df9e252712a6", + "b27834db422395bd330e53736a001341ce02c9b148c277dabac67dc422741bfa983c28d47c27e8214cd861f2bad8c6f6", + "a2bafaf4e2daf629fd27d7d5ac09fb5efc930ff2ae610f37519808683aa583fe1c6f37207daf73de1d8a164f79a0c981", + "b856cee1cfcf5e50db9af4ab0aed3db2f43c936eaea369b5bba65582f61f383c285efbda97b1c068c5d230cbe94f7722", + "a61ab205554c0550fa267e46a3d454cd1b0a631646b3df140623ff1bfffaa118e9abe6b62814968cc2a506e9c03ea9a0", + "8c78edcd106377b9cbdfa2abd5278724aed0d9e4ae5869b5d2b568fdabb7804c953bae96294fcc70ef3cd52ba2cbe4ed", + "8570869a9bbf6cc84966545a36586a60be4d694839f367b73dfc40b5f623fc4e246b39b9a3090694aa2e17e652d07fd1", + "a905b82c4da8d866a894da72315a95dc98faa3c7b3d809aef18f3b2be4801e736a1b79a406179e8cac8f74d27e71ac52", + "a8eb8679ff1a64908515f6720ff69434cb33d63aeb22d565fde506618908b1d37585e3bd4d044fd0838b55787af06b42", + "af4d86b2fbd1684a657dffe4210321a71e6ae560c144d44668d1f324dc9630e98348c3d444622a689327c1a59cc169dd", + "80359c6eab16954559ab0e6a1fee9a0526c45d3cae1a371159a2e3aa9b893afdc3a785c9559a5fd9cd8cd774234bf819", + "8d4e5ff81eb5d17bbe8ae6416538ca51a9427ce142b311f5cbb14febbbbb9c1ffc6489fd625b9266264c366c12a9d997", + "92e181c66489c5fa063ba2a1a354b6fd3439b8b4365a8c90e42e169bfaa1fb5766bf3e0fe804399d18bc8fbcafb5c3b1", + "a9ddf229360a095393885083716cb69c819b2d7cfb100e459c2e6beb999ff04446d1e4a0534832ae3b178cbe29f4f1d3", + "8e085ef7d919302a1cc797857b75cff194bdbc1c5216434fa808c3dea0cf666f39d9b00f6d12b409693d7a9bd50a912c", + "916dc4dc89e5e6acf69e4485a09fc66968f9b292eac61a146df1b750aa3da2425a0743d492179f90a543a0d4cd72c980", + "b9cbf17e32c43d7863150d4811b974882da338cf0ed1313765b431b89457021dd1e421eeaa52840ef00551bb630962dc", + "a6fb875786daec1a91484481787093d8d691dd07e15c9c0c6ae0404bf9dc26083ed15d03c6d3fe03e29f28e20da21269", + "a870fcb54b9a029e8086de9b08da8782c64ad2cc2e7fdf955b913d294038bb8136193256b85267e75a4ca205808a76b4", + "99883f057e09b88bf0e316f9814c091837fd5c26eeb16fec108c9fed4b7a2bd1c783dac0e4242b5a906621ab606c1e50", + "85d89069ca3190577dab39bbec43c16bf6dbca439ad3eebd8f5e9f507d84c3c43e77fd6323224582566a3aa2c8018951", + "9363ba219e0003f6e8a9d8937b9e1449e4b2c5cd57194563b758bea39deab88778e8f8e4f7816970a617fb077e1e1d42", + "820622f25553c035326145c1d2d537dc9cfd064c2f5bdf6d4ec97814de5fe9a0fbd443345fa2ea0a9d40d81d3936aa56", + "87e31110aaf447e70c3316459250e4f7f8c24420c97828f9eb33b22107542c5535bdb48b0e58682dd842edea2886ff08", + "95bf80cac6f42029d843d1246588acb40a74802f9e94b2bf69b1833936767e701ef7b0e099e22ab9f20f8c0c4a794b6c", + "a46ecf612b2763d099b27fb814bd8fdbaee51d6b9ac277ad6f28350b843ce91d701371adfaaf4509400dc11628089b58", + "8604decf299fb17e073969708be5befeb1090ab688ad9f3f97a0847a40ea9a11bbcfc7a91e8dc27bc67a155123f3bd02", + "8eb765c8dc509061825f3688cb2d78b6fef90cf44db33783d256f09be284bc7282205279725b78882688a514247c4976", + "b5c30b2244fa109d66b3a5270b178960fdec47d31e63db0b374b80d2b626409eb76d2e8d1ebf47ef96c166743032fc5e", + "aab01e76290a7e936989530221646160bf8f64e61e79282e980c8c5dcaaa805ff096efd01d075a2c75917a3f4bf15041", + "b9d79671debd0b83d0c7c7c3e64c0fb1274300564b262771f839b49218501e7f38ef80cae1f7e5a3c34acdc74c89dab6", + "92c0eaceadf036b3b9dfd2712013aba3dd7c30b7760f501f52141618265baa31840fe77850a7014dc528f71f8cf39ce6", + "b3cdd098059980455dd5b1c04182df1bd12fa844a866f02a9f8a86aab95b59945baa9af99f687410bffc5b07153cb23c", + "b361b73a62f71256b7f6ea8e0f6615e14fc5a06ee98b928ab3c9dd3eef9d9d30070e9855c82b7facb639cacb3401e01f", + "b9c85fc0f25a3271cf28b1ca900078eaaa66cbab0a3e677606e898ac32781a2dfce4d9cbd07404599e2c3c02fa161c9d", + "ac5b4fdac2a0b2e6430d9fc72bde4249d72183b197fc7347bb1546ae6f544426686bbe0caec3ee973b6836da5e831c44", + "b675aebf24b92e398e166f171a6df442b3f5919b6bee192f31675a5e8eeb77d34c6590a6f0c0857417e0f78cfb085db8", + "a9bef942044d8d62e6a40169f7dc7b49e40cd0d77f8678dd7c7bae6f46c46786f9b1e319a3fa408f22a54fd2a4d70804", + "a20d19cd917d5102ae9ca0cf532127d2b953aa3303310e8a8c4b3da025dded993a47e3a28e6b02acfadb6d65dc2d41a3", + "a47fdb04059b83b2afb86a47b2368bbd7247c337a36d3333b6e5ef2cc9476a92c4907e4c58a845c9ef9b497621e0b714", + "94a9e9ffc14b411e11a4ffa59878d59460263589003dc7b6915247c549f67feede279bf3645fdd92379022fb21e3caeb", + "b92e1177dd9ecdaf1370c71b14954219cf0851f309bc216d5907a4e2e84e0df3457018224150c142cc6bf86644bb4b73", + "8bc57fadd68a265b7df9b42227a9c0968db7b1bb50dc12f7d755505779f1ff2c408672b3091e903366acc9ce15d19fb6", + "b6b5efbe1ac4e1bd2e8447c45000d09397b772ca5496acc447b881022608a41c4f60388814607a01890190105bee7be3", + "95f7c85fd614df968f8ccf8d086579c9e1cec4644ecf06da26e3511cb39635a7326b3cec47bd51cf5646f1c660425e9c", + "b81765fb319bcdc74b4d608383ccb4af7dd84413b23af637be12e2827a75f7e4bcd14441cf979ed9038ae366fbb6f022", + "a120ea76cda8c6c50c97035078f6648afe6537809bdba26e7c9e61de8f3070d2347160f9d34010effbf2ec7e94f5749f", + "92c1b8631953b40d3cc77eee2c72a064b999c09a9b92c11d8fa7b4072966273901c9dba25f9f79f384d9f11a56f3fc7a", + "a4b00dc0ab67b2300abc9c516e34daf444d6497b066a90cfe3381ed2812304ed37b14f3b948990443dc6c1cf1bed460c", + "a9e9f7e13c9f031bc7b9e6f1417c7abcc38894fe7d3f54869ee277afd2efa3e6fb50757dd36c8c94d591e0abdea322cc", + "84f3e98f831792b5ad14bcfe62a4c9f296476c6087c4c1ec7767fc642fbca141ff6a3deeb8b4d4106a9cda5a9937eea0", + "8eb1a7931bbea9a714226fd74b0100ab88355287d9b0a349c095e9b5809b98f237ffd706bce7d67a770da355fb9cec7b", + "9738ef8739e1742c1f26b51a1621be0b89d37406a370c531e236f635c7064c661818817bb3858908986aa687b28b21be", + "a9cf3ce8501b003ccaf57552a4c4ec31081e44526d3aa3791d3dc4a7e438a357c0956f93c500356186d8fd4588ffac5e", + "a7af6a219cca59225839a9de5b19263cb23d75557d448bc7d677b62591a2e068c45e5f4457cceb3e9efa01d0601fc18a", + "972a24ece5eda7692cbb6fb727f92740451bc1281835e2a02931b2b05824a16b01dbe5edd03a0ed5b441ff25a5cc0188", + "b21d1ec7597ce95a42f759c9a8d79c8275d7e29047a22e08150f0f65014702f10b7edce8c03f6e7ab578ce8c3b0ec665", + "a13a1c7df341bd689e1f8116b7afc149c1ef39161e778aa7903e3df2569356ad31834fa58ceb191485585ce5ef6835c3", + "a57bdb08119dc3bc089b5b2b5383455c4de0c2fcdac2dcfa21c7ac5071a61635ff83eceb7412f53fab42d1a01991de32", + "b2968748fa4a6921ee752d97aa225d289f599a7db7a222450e69706533573ded450380c87f8cdd4a8b8c8db1b42b5c97", + "8718ec04e0d5f38e3034ecd2f13dfde840add500f43a5e13457a1c73db0d18138f938690c8c315b5bcbeb51e8b9a2781", + "82094789e26c4a04f2f30bdb97b9aecca9b756cbd28d22ab3c8bed8afc5b2963340ddfc5a5f505e679bf058cbc5dcbb8", + "a35b8a566dd6ab67eddc2467906bffc76c345d508e52e9e4bb407b4f2b2c5f39b31d5a4bf5022f87bf7181dc6be2fe41", + "a8c93b1e893d4777c0e3a1b4bef3be90c215781501407c4011457fc3240e13524b4d2bea64a6d0a3efe3f3b0dae9b8ab", + "877095ad18b1e5870818f7a606127ba1736a0b55b0dbcd281ec307c84b08afc0c9117e3a880fe48bfc225fbf37671a97", + "84405ee0421ed2db1add3593df8426a9c1fcc8063e875f5311a917febc193748678dd63171d0c21665fb68b6d786c378", + "a52cdc8209c3c310bed15a5db260c4f4d4857f19c10e4c4a4cfe9dfc324dfac851421bb801509cf8147f65068d21603c", + "8f8a028a70dda7285b664722387666274db92230b09b0672f1ead0d778cee79aae60688c3dfd3a8ed1efdeda5784c9d4", + "a0be42fecc86f245a45a8ed132d6efc4a0c4e404e1880d14601f5dce3f1c087d8480bad850d18b61629cf0d7b98e0ae0", + "83d157445fc45cb963b063f11085746e93ab40ece64648d3d05e33e686770c035022c14fdf3024b32b321abf498689ad", + "8a72bbf5a732e2d4f02e05f311027c509f228aef3561fc5edac3ef4f93313845d3a9f43c69f42e36f508efcc64a20be0", + "b9ca29b0ec8e41c6a02f54d8c16aebf377982488cbe2ed1753090f2db4f804f6269af03e015d647a82ef06ffaa8cba6c", + "b4df3858d61bbb5ded1cf0be22a79df65ae956e961fbb56c883e1881c4c21fe642e3f5a0c108a882e553ac59595e3241", + "86457d8890ac8858d7bab180ef66851247c2bf5e52bf69a4051d1d015252c389684fcc30bb4b664d42fbf670574ab3a3", + "86d5576ea6dfa06d9ebce4cd885450f270c88a283e1e0d29cab27851c14ed2f00355e167b52e1539f1218ad11d8f13dd", + "883ad1364dc2a92388bfafaa9bc943c55b2f813525831e817a6208c666829a40455dde494eba054b2495a95f7ce69e8a", + "8942371e6925231c2c603b5f5a882d8404d39f0c7c4232557c2610b21c2c07f145466da798ea78b7932da2b774aa3128", + "a799eb71496783cc7faf12c9d9804bf6180699a004b2f07fc5cc36840f63ce7eee7dde9275819a9aa3f8d92dc0d47557", + "8eb3fb5c769548ee38c7882f51b959c5d5a42b5935269ccf987d6ddbb25a206e80c6000bcc328af149e0727c0b7c02c0", + "8f3910d64e421a8f2d8db4c7b352ba5b3fc519d5663973fea5962efe4364fb74448770df944ef37ffe0382648fb56946", + "b41413e0c26ff124cf334dab0dc8e538293d8d519d11cc2d10895a96b2064ac60c7da39f08589b38726cffa4c3f0bfef", + "b46ef2eb10abae0f35fa4c9c7ee2665e8044b8d9f91988a241da40fd5bbc63166925582151941b400006e28bbc5ba22a", + "b8baa8b4c420bb572a3b6b85479b67d994c49a7ebfe1274687d946a0d0b36dfed7630cfb897350fa166f5e2eff8f9809", + "964b46d359c687e0dcfbdab0c2797fc2bd1042af79b7418795b43d32ffca4de89358cee97b9b30401392ff54c7834f9f", + "8410d0203d382ebf07f200fd02c89b80676957b31d561b76563e4412bebce42ca7cafe795039f46baf5e701171360a85", + "b1a8d5d473c1a912ed88ea5cfa37c2aea5c459967546d8f2f5177e04e0813b8d875b525a79c29cb3009c20e7e7292626", + "afaab9a1637429251d075e0ba883380043eaf668e001f16d36737028fded6faa6eeed6b5bb340f710961cee1f8801c41", + "aef17650003b5185d28d1e2306b2f304279da50925f2704a6a3a68312f29fe5c2f2939f14e08b0ba9dee06ea950ad001", + "97bcc442f370804aa4c48c2f8318d6f3452da8389af9335e187482d2e2b83b9382e5c297dce1a0f02935e227b74e09a3", + "8a67a27b199f0bcd02d52a3e32f9b76a486b830ec481a49a4e11807e98408b7052b48581b5dd9f0b3e93052ec45dfb68", + "b113bf15f430923c9805a5df2709082ab92dcdf686431bbad8c5888ca71cc749290fa4d4388a955c6d6ee3a3b9bc3c53", + "8629ca24440740ce86c212afed406026f4ea077e7aa369c4151b6fa57bca7f33f9d026900e5e6e681ae669fd2bd6c186", + "933a528371dcecc1ec6ded66b1c7b516bd691b3b8f127c13f948bfbcda3f2c774c7e4a8fbee72139c152064232103bdf", + "8568ddd01f81a4df34e5fa69c7f4bb8c3c04274147498156aec2e3bd98ea3e57c8a23503925de8fa3de4184563a2b79e", + "8160874ec030f30fda8f55bcf62613994ff7ed831e4901c7560eac647182b4a9b43bfaff74b916602b9d6ae3bfcaf929", + "ae71c48d48cf9459800cdf9f8e96bc22e2d4e37259e5c92a2b24fbe2c6ca42675e312288603c81762f6ceb15400bc4c9", + "b05f39bb83fda73e0559db1fd4a71423938a87ad9f060d616d4f4a6c64bf99472a2cbfb95f88b9257c9630fc21a0b81f", + "80c8479a640ed7a39e67f2db5ad8dfd28979f5443e8e6c23da8087fc24134d4b9e7c94320ffa4154163270f621188c27", + "9969ba20ee29c64cb3285a3433a7e56a0fe4ddc6f3d93e147f49fe021bed4a9315266ebb2fb0eb3036bb02001ae015e6", + "a198c89fef2ab88e498703b9021becc940a80e32eb897563d65db57cc714eaa0e79092b09dd3a84cfab199250186edcc", + "8df14a3db8fe558a54d6120bad87405ba9415a92b08c498812c20416c291b09fed33d1e2fcf698eb14471f451e396089", + "81e245ef2649b8a5c8d4b27188dd7e985ef6639090bdc03462c081396cf7fc86ed7d01bfe7e649d2b399255e842bdc21", + "8659f622c7ab7b40061bcf7a10144b51ad3ab5348567195924f2944e8c4ce137a37f1ba328e4716c10806f3fb7271689", + "a575d610fc8fe09334ca619ecdadf02d468ca71dd158a5a913252ca55ea8d8f9ce4548937c239b9cb8ab752a4d5af24a", + "94744549cd9f29d99f4c8c663997bdfa90e975b31f1086214245de9c87b0c32209f515a0de64d72d5ef49c09b0a031fa", + "80a8677862b056df59e350c967a27436c671b65d58854e100115bac9824ba177e94c2a1bfcaa191a071b9cefdbee3989", + "91be9a5504ec99922440f92a43fe97ddce2f21b9d94cd3a94c085a89b70c903696cec203bbab6d0a70693ba4e558fb01", + "8c5a0087bcd370734d12d9b3ab7bc19e9a336d4b49fc42825b2bfedcd73bb85eb47bf8bb8552b9097cc0790e8134d08c", + "933aa9e6bd86df5d043e0577a48e17eea3352e23befdbb7d7dcac33b5703d5ace230443ac0a40e23bf95da4cc2313478", + "984b7ee4bd081ee06c484db6114c2ce0ba356988efb90f4c46ff85ed2865fb37f56a730166c29ef0ae3345a39cdeae7a", + "ae830f908ea60276c6c949fb8813e2386cf8d1df26dcf8206aa8c849e4467243e074471380ed433465dc8925c138ea4c", + "874c1df98d45b510b4f22feff46a7e8ed22cfc3fad2ac4094b53b9e6477c8dfc604976ca3cee16c07906dece471aa6c6", + "a603eb60d4c0fb90fa000d2913689126849c0261e6a8649218270e22a994902965a4e7f8c9462447259495fe17296093", + "a7c73d759a8ad5e3a64c6d050740d444e8d6b6c9ade6fb31cb660fa93dc4a79091230baccb51c888da05c28cb26f6f3f", + "a4411b79b6a85c79ea173bd9c23d49d19e736475f3d7d53213c5349ebb94a266d510d12ba52b2ac7a62deaaaec7339b8", + "943b84f8bbcee53b06266b5c4cd24d649d972593837fe82b0bf5d5e1bbc1a2bf148e1426c366d7c39ab566b10224cadc", + "8300012096a8b4cefecc080054bf3ceb0918162ba263c6848860423407796b5eb517170c0bad8e4905ac69a383055a21", + "8244a1e3ad41908c6f037e2f8db052e81f281646141334829f36c707f307448b9ab79a7f382a1e8d86f877c90b59271c", + "8eca1b74687802ecc36a5d39e4516a9dee3de61a2047252d9ed737b49e0090c386e9d792ac004c96337681c7f29a16ad", + "b70fa47535f0524835039a20036c61e77f66146ad79d3d339214d8744742db41ceeb577c829d000011aeafbb12e09579", + "84b3abbce48689f3adbb99889c7fd1f3e15ab455d477e34f5151c5c1c358ed77a5b6a581879f7e0f1f34106e0792e547", + "ab45ecb58c0ef0dbce3d16afc6ac281e0d90ec48741ea96a141152647e98fcc87f3a3ff07ba81f3179118453ce123156", + "90d231a145ba36a59087e259bbfc019fa369201fcfeaa4347d5fd0a22cd8a716e5a797f3cc357f2779edb08f3b666169", + "a4f6074d23c6c97e00130bc05f25213ca4fa76c69ca1ace9dece904a2bdd9d987661f5d55023b50028c444af47ff7a08", + "933af884939ad0241f3f1f8e8be65f91d77ac0fb234e1134d92713b7cfb927f1933f164aec39177daa13b39c1370fac8", + "80d1db6933ce72091332ae47dc691acb2a9038f1239327b26d08ea9d40aa8f2e44410bbda64f2842a398cbe8f74f770f", + "a7a08605be2241ccc00151b00b3196d9c0717c4150909a2e9cd05538781231762b6cc6994bebbd4cddae7164d048e7b2", + "96db0d839765a8fdbbac03430fa800519e11e06c9b402039e9ae8b6503840c7ecac44123df37e3d220ac03e77612f4e4", + "96d70f8e9acd5a3151a8a9100ad94f16c289a31d61df681c23b17f21749c9062622d0a90f6d12c52397b609c6e997f76", + "8cf8e22273f7459396ff674749ab7e24c94fe8ab36d45d8235e83be98d556f2b8668ba3a4ec1cb98fac3c0925335c295", + "97b7e796a822262abc1a1f5a54cb72a1ea12c6c5824ac34cd1310be02d858a3c3aa56a80f340439b60d100e59c25097d", + "a48208328b08769737aa1a30482563a4a052aea736539eceab148fa6653a80cb6a80542e8b453f1f92a33d0480c20961", + "b612184941413fd6c85ff6aa517b58303b9938958aa85a85911e53ed308778624d77eadb27ccf970573e25d3dfd83df7", + "b3717068011648c7d03bbd1e2fc9521a86d2c3ae69113d732c2468880a3b932ebec93596957026477b02842ed71a331b", + "a0ad363e1352dcf035b03830fef4e27d5fd6481d29d5e8c9d51e851e3862d63cdcbaf8e330d61c1b90886921dac2c6fd", + "8db409fdacfa4bfdaf01cc87c8e97b53ca3a6e3a526d794eaad1c2023f3df4b888f1bf19fee9a990fe6d5c7c3063f30c", + "b34d6975310ab15938b75ef15020a165fc849949065d32d912554b51ffa1d3f428a6d1a396cb9329367670391de33842", + "9117285e9e6762853fc074b8a92b3923864de2c88c13cea7bab574aaf8cdd324843455d2c3f83c00f91f27c7ecc5592a", + "b4b2e8f190ea0b60819894710c866bf8578dd1b231ae701d430797cc7ede6e216e8ca6a304f3af9484061563645bf2ab", + "8c493c6853ab135d96a464815dd06cad8b3e8b163849cdefc23d1f20211685753b3d3e147be43e61e92e35d35a0a0697", + "9864d7880f778c42d33cf102c425e380d999d55a975a29c2774cad920dfddb80087a446c4f32ed9a6ab5f22ec6f82af0", + "90f67fe26f11ca13e0c72b2c2798c0d0569ed6bc4ce5bbaf517c096e7296d5dd5685a25012f6c6d579af5b4f5d400b37", + "a228872348966f26e28a962af32e8fa7388d04bc07cfc0224a12be10757ac7ab16a3387c0b8318fcb0c67384b0e8c1a4", + "a9d9d64bba3c03b51acf70aeb746a2712ddafe3b3667ae3c25622df377c2b5504e7ab598263bec835ab972283c9a168b", + "932128971c9d333f32939a1b46c4f7cf7e9d8417bd08dc5bd4573ccbd6ec5b460ac8880fb7f142f7ef8a40eef76d0c6d", + "964115e7838f2f197d6f09c06fbb2301d6e27c0ecdf208350cf3b36c748436dac50f47f9f9ac651c09ab7ad7221c7e43", + "a5941f619e5f55a9cf6e7f1499b1f1bcddcc7cf5e274efedaaad73a75bc71b1fc5c29cd903f6c69dc9a366a6933ca9d1", + "a154bf5eaec096029e5fe7c8bf6c695ae51ace356bb1ad234747776c7e1b406dee2d58864c3f4af84ed69f310974125e", + "b504e6209d48b0338ab1e4bdab663bac343bb6e0433466b70e49dc4464c1ec05f4a98111fd4450393607510ae467c915", + "813411918ea79bdde295393284dc378b9bdc6cfcb34678b9733ea8c041ac9a32c1e7906e814887469f2c1e39287e80f8", + "8be0369f94e4d72c561e6edb891755368660208853988647c55a8eed60275f2dd6ee27db976de6ecf54ac5c66aaf0ae6", + "a7e2701e55b1e7ea9294994c8ad1c080db06a6fc8710cd0c9f804195dce2a97661c566089c80652f27b39018f774f85e", + "956b537703133b6ddf620d873eac67af058805a8cc4beb70f9c16c6787bf3cc9765e430d57a84a4c3c9fbdd11a007257", + "835ae5b3bb3ee5e52e048626e3ddaa49e28a65cb94b7ecdc2e272ff603b7058f1f90b4c75b4b9558f23851f1a5547a35", + "85d67c371d1bf6dc72cca7887fa7c886ce988b5d77dc176d767be3205e80f6af2204d6530f7060b1f65d360a0eaeff30", + "a84a6647a10fcef8353769ef5f55a701c53870054691a6e9d7e748cbe417b3b41dbb881bae67adc12cb6596c0d8be376", + "87ffe271fc0964cb225551c7a61008d8bcb8b3d3942970dbcc2b9f4f9045a767971880368ea254e2038a3a0b94ecf236", + "964bb721c51d43ee7dd67c1a2b7dd2cc672ce8fad78c22dcddb43e6aab48d9a4a7dc595d702aa54a6fb0ffabf01f2780", + "a89b3f84bb7dcbe3741749776f5b78a269f6b1bebb8e95d3cc80b834fd2177c6be058d16cacfd0d5e1e35e85cde8b811", + "b4314538e003a1587b5592ff07355ea03239f17e75c49d51f32babe8e048b90b046a73357bcb9ce382d3e8fbe2f8e68b", + "86daf4bf201ae5537b5d4f4d734ed2934b9cf74de30513e3280402078f1787871b6973aa60f75858bdf696f19935a0e2", + "b1adf5d4f83f089dc4f5dae9dbd215322fa98c964e2eaa409bf8ca3fa5c627880a014ed209492c3894b3df1c117236c4", + "b508d52382c5bac5749bc8c89f70c650bb2ed3ef9dc99619468c387c1b6c9ff530a906dfa393f78f34c4f2f31478508a", + "a8349a5865cb1f191bebb845dfbc25c747681d769dbffd40d8cedf9c9a62fa2cbc14b64bb6121120dab4e24bef8e6b37", + "af0500d4af99c83db8890a25f0be1de267a382ec5e9835e2f3503e1bac9412acf9ff83a7b9385708ef8187a38a37bc77", + "b76d57a1c1f85b8a8e1722a47057b4c572800957a6b48882d1fc21309c2e45f648a8db0fcff760d1dbc7732cf37c009b", + "b93c996cec0d3714667b5a5a5f7c05a7dc00bbc9f95ac8e310626b9e41ae4cc5707fac3e5bd86e1e1f2f6d9627b0da94", + "93216fdb864217b4c761090a0921cf8d42649ab7c4da1e009ec5450432564cb5a06cb6e8678579202d3985bd9e941cef", + "8b8be41105186a339987ae3a5f075fbc91f34b9984d222dfed0f0f85d2f684b56a56ab5dc812a411570491743d6c8b18", + "959b72782a6b2469e77fe4d492674cc51db148119b0671bd5d1765715f49fa8a87e907646671161586e84979ef16d631", + "86b7fc72fb7e7904ea71d5e66ba0d5d898ace7850985c8cc4a1c4902c5bf94351d23ce62eed45e24321fb02adfa49fc8", + "a2f244e7c9aa272cb0d067d81d25e5a3045b80b5a520b49fd5996ece267a7f1bea42e53147bbf153d9af215ea605fc9e", + "81aa2efa5520eebc894ce909ba5ce3250f2d96baa5f4f186a0637a1eea0080dd3a96c2f9fadf92262c1c5566ddb79bab", + "b607dd110cfe510d087bcff9a18480ba2912662256d0ab7b1d8120b22db4ad036b2266f46152754664c4e08d0fc583f6", + "8f588d5f4837e41312744caac5eee9ddc3ad7085871041694f0b5813edf83dc13af7970f7c9b6d234a886e07fa676a04", + "924921b903207783b31016cbec4e6c99e70f5244e775755c90d03a8b769738be3ba61577aca70f706a9c2b80040c9485", + "ae0a42a222f1a71cd0d3c69ffb2f04c13e1940cce8efabe032629f650be3ceed6abb79651dbb81cb39a33286eb517639", + "a07d7d76460f31f5f0e32e40a5ea908d9d2aebf111ac4fadee67ef6540b916733c35a777dcdc05f6417726ca1f2d57dd", + "88d7f8a31f8c99794291847d28745e5d0b5d3b9684ca4170b686ffbb5bb521a3ef6746c3c8db22e4250a0cdff7939d96", + "849573071fd98c020dc9a8622a9eff221cb9f889bde259e7127a8886b73bef7ad430b87750915658918dcfb6b7b4d8d3", + "b12d59f732fa47fad175d6263734da8db89230fd340a46ad1cdee51e577041a5c80bf24cd195593e637daf1a66ef5a98", + "abbcfb8a4a6d5e269ee1ac5e277df84416c73ca55ec88317f73608201af25af0cb65b943c54684a5651df3a26e3daca2", + "ab157f589bdbaf067a6a7ba7513df0492933855d39f3a081196cf2352e0ddc0162d476c433320366e3df601e0556278d", + "a86c0619b92e5ae4f7daa876a2abc5ba189156afc2fa05eef464dfa342ba37fc670d0dc308ad3822fcb461ab001bac30", + "a3f292946476cfe8d5e544a5325439a00e0165a5f9bf3bb6a53f477baeac7697cc0377745536681aa116f326ce911390", + "8aecbbfd442a6a0f01c1c09db5d9d50213eb6f1ff6fab674cde3da06a4edff3ed317e804f78300c22ef70c336123e05d", + "834ed4b58211fcd647d7bf7c0a3ba9085184c5c856b085e8a0fcd5215c661ef43d36f3f0f6329a9f1370501b4e73b6e4", + "a114ea5ad2b402a0de6105e5730907f2f1e458d28ae35144cf49836e0ad21325fe3e755cfb67984ae0a32e65402aad1e", + "a005f12bed97d71cee288b59afe9affb4d256888727343944a99913980df2c963fe02f218e6ea992f88db693a4498066", + "a010f286ab06b966e3b91ff8f1bdbe2fe9ab41a27bc392d5787aa02a46e5080e58c62c7d907818caae9f6a8b8123e381", + "857bd6df2ddef04dbc7c4f923e0b1696d3016c8bfed07fdfa28a3a3bd62d89b0f9df49aae81cbb6883d5e7b4fadae280", + "b3927030da445bc4756ac7230a5d87412a4f7510581fb422212ce2e8cf49689aca7ba71678743af06d4de4914c5aa4a0", + "b86403182c98fcce558d995f86752af316b3b2d53ba32075f71c7da2596747b7284c34a1a87de604fcc71e7e117a8add", + "98dd19b5527733041689b2a4568edaf6aa0fe1a3dd800c290cda157b171e053648a5772c5d3d4c80e5a795bc49adf12e", + "88a3c227bb7c9bff383f9ad3f7762245939a718ab85ae6e5e13180b12bf724d42054d3852b421c1cd1b3670baddecb63", + "b3cfd9ad66b52bbe57b5fff0fad723434d23761409b92c4893124a574acc1e6b1e14b4ec507661551cbbe05e16db362e", + "923e1bb482cf421dd77801f9780f49c3672b88508a389b94015fd907888dc647ee9ea8ec8d97131d235d066daf1f42b7", + "8d5e16240f04f92aa948181d421006bdbc7b215648fb6554193224d00cf337ebbb958f7548cf01b4d828acffb9fbc452", + "8b2b8f18ad0559746f6cda3acca294a1467fb1a3bc6b6371bc3a61a3bfe59418934fa8706f78b56005d85d9cb7f90454", + "a9316e2a94d6e31426d2ae7312878ba6baaac40f43e2b8a2fa3ab5a774c6918551554b2dbb23dc82f70ba3e0f60b5b0d", + "9593116d92cf06b8cd6905a2ce569ee6e69a506c897911f43ae80fc66c4914da209fc9347962034eebbc6e3e0fe59517", + "887d89d2b2d3c82b30e8f0acf15f0335532bd598b1861755498610cb2dd41ff5376b2a0bb757cb477add0ce8cfe7a9fc", + "b514cfe17875ecb790ad055271cc240ea4bda39b6cfa6a212908849c0875cb10c3a07826550b24c4b94ea68c6bb9e614", + "a563d5187966d1257d2ed71d53c945308f709bcc98e3b13a2a07a1933dc17bcb34b30796bd68c156d91811fbd49da2cb", + "a7195ccc53b58e65d1088868aeeb9ee208103e8197ad4c317235bb2d0ad3dc56cb7d9a7186416e0b23c226078095d44c", + "a838e7a368e75b73b5c50fbfedde3481d82c977c3d5a95892ac1b1a3ea6234b3344ad9d9544b5a532ccdef166e861011", + "9468ed6942e6b117d76d12d3a36138f5e5fb46e3b87cf6bb830c9b67d73e8176a1511780f55570f52d8cdb51dcf38e8c", + "8d2fc1899bc3483a77298de0e033085b195caf0e91c8be209fd4f27b60029cbe1f9a801fbd0458b4a686609762108560", + "8f4e44f8ca752a56aa96f3602e9234ad905ad9582111daf96a8c4d6f203bf3948f7ce467c555360ad58376ee8effd2ba", + "8fb88640b656e8f1c7c966c729eb2ba5ccf780c49873f8b873c6971840db7d986bdf1332ba80f8a0bb4b4ee7401468fa", + "b72aa3235868186913fb5f1d324e748cd3ce1a17d3d6e6ea7639a5076430fe0b08841c95feb19bb94181fe59c483a9eb", + "b8b102690ebb94fc4148742e7e3fd00f807b745b02cbe92cd92992c9143b6db7bb23a70da64a8b2233e4a6e572fc2054", + "8c9ae291f6cd744e2c6afe0719a7fc3e18d79307f781921fb848a0bf222e233879c1eca8236b4b1be217f9440859b6ce", + "a658ede47e14b3aad789e07f5374402f60e9cacb56b1b57a7c6044ca2418b82c98874e5c8c461898ebd69e38fecd5770", + "89c0cb423580e333923eb66bda690f5aca6ec6cba2f92850e54afd882ba608465a7dbb5aa077cd0ca65d9d00909348ab", + "aed8e28d98d5508bd3818804cf20d296fe050b023db2ed32306f19a7a3f51c7aaafed9d0847a3d2cd5ba5b4dabbc5401", + "96a0fcd6235f87568d24fb57269a94402c23d4aa5602572ad361f3f915a5f01be4e6945d576d51be0d37c24b8b0f3d72", + "935d0c69edd5dfa8ed07c49661b3e725b50588f814eb38ea31bcc1d36b262fae40d038a90feff42329930f8310348a50", + "900518288aa8ea824c7042f76710f2ea358c8bb7657f518a6e13de9123be891fa847c61569035df64605a459dad2ecc8", + "947d743a570e84831b4fb5e786024bd752630429d0673bf12028eb4642beb452e133214aff1cfa578a8856c5ebcb1758", + "a787266f34d48c13a01b44e02f34a0369c36f7ec0aae3ec92d27a5f4a15b3f7be9b30b8d9dd1217d4eeedff5fd71b2e5", + "a24b797214707ccc9e7a7153e94521900c01a1acd7359d4c74b343bfa11ea2cdf96f149802f4669312cd58d5ab159c93", + "97f5ee9c743b6845f15c7f0951221468b40e1edaef06328653a0882793f91e8146c26ac76dd613038c5fdcf5448e2948", + "80abd843693aed1949b4ea93e0188e281334163a1de150c080e56ca1f655c53eb4e5d65a67bc3fc546ed4445a3c71d00", + "908e499eb3d44836808dacff2f6815f883aeced9460913cf8f2fbbb8fe8f5428c6fc9875f60b9996445a032fd514c70f", + "ae1828ef674730066dc83da8d4dd5fa76fc6eb6fa2f9d91e3a6d03a9e61d7c3a74619f4483fe14cddf31941e5f65420a", + "a9f4dbe658cd213d77642e4d11385a8f432245b098fccd23587d7b168dbeebe1cca4f37ee8d1725adb0d60af85f8c12f", + "93e20ee8a314b7772b2439be9d15d0bf30cd612719b64aa2b4c3db48e6df46cea0a22db08ca65a36299a48d547e826a7", + "a8746a3e24b08dffa57ae78e53825a9ddbbe12af6e675269d48bff4720babdc24f907fde5f1880a6b31c5d5a51fbb00e", + "b5e94dfab3c2f5d3aea74a098546aa6a465aa1e3f5989377d0759d1899babf543ad688bb84811d3e891c8713c45886c5", + "a3929bada828bd0a72cda8417b0d057ecb2ddd8454086de235540a756e8032f2f47f52001eb1d7b1355339a128f0a53b", + "b684231711a1612866af1f0b7a9a185a3f8a9dac8bde75c101f3a1022947ceddc472beb95db9d9d42d9f6ccef315edbc", + "af7809309edbb8eb61ef9e4b62f02a474c04c7c1ffa89543d8c6bf2e4c3d3e5ecbd39ec2fc1a4943a3949b8a09d315a6", + "b6f6e224247d9528ef0da4ad9700bee6e040bbf63e4d4c4b5989d0b29a0c17f7b003c60f74332fefa3c8ddbd83cd95c1", + "adbcec190a6ac2ddd7c59c6933e5b4e8507ce5fd4e230effc0bd0892fc00e6ac1369a2115f3398dfc074987b3b005c77", + "8a735b1bd7f2246d3fa1b729aecf2b1df8e8c3f86220a3a265c23444bdf540d9d6fe9b18ed8e6211fad2e1f25d23dd57", + "96b1bf31f46766738c0c687af3893d098d4b798237524cb2c867ed3671775651d5852da6803d0ea7356a6546aa9b33f2", + "8036e4c2b4576c9dcf98b810b5739051de4b5dde1e3e734a8e84ab52bc043e2e246a7f6046b07a9a95d8523ec5f7b851", + "8a4f4c32ee2203618af3bb603bf10245be0f57f1cfec71037d327fa11c1283b833819cb83b6b522252c39de3ce599fa5", + "ad06ed0742c9838e3abaaffdb0ac0a64bad85b058b5be150e4d97d0346ed64fd6e761018d51d4498599669e25a6e3148", + "8d91cb427db262b6f912c693db3d0939b5df16bf7d2ab6a7e1bc47f5384371747db89c161b78ff9587259fdb3a49ad91", + "ae0a3f84b5acb54729bcd7ef0fbfdcf9ed52da595636777897268d66db3de3f16a9cf237c9f8f6028412d37f73f2dfad", + "8f774109272dc387de0ca26f434e26bc5584754e71413e35fa4d517ee0f6e845b83d4f503f777fe31c9ec05796b3b4bc", + "a8670e0db2c537ad387cf8d75c6e42724fae0f16eca8b34018a59a6d539d3c0581e1066053a2ec8a5280ffabad2ca51f", + "ac4929ed4ecad8124f2a2a482ec72e0ef86d6a4c64ac330dab25d61d1a71e1ee1009d196586ce46293355146086cabba", + "845d222cb018207976cc2975a9aa3543e46c861486136d57952494eb18029a1ebb0d08b6d7c67c0f37ee82a5c754f26f", + "b99fa4a29090eac44299f0e4b5a1582eb89b26ed2d4988b36338b9f073851d024b4201cd39a2b176d324f12903c38bee", + "9138823bc45640b8f77a6464c171af2fe1700bdc2b7b88f4d66b1370b3eafe12f5fbb7b528a7e1d55d9a70ca2f9fc8e6", + "8ac387dc4cf52bc48a240f2965ab2531ae3b518d4d1f99c0f520a3d6eb3d5123a35ef96bed8fa71ee2f46793fa5b33b3", + "864adec6339d4c2ba2525621fceabd4c455902f6f690f31a26e55413e0722e5711c509dc47ce0bcc27bbdc7651768d2d", + "a0a52edb72268a15201a968dabc26a22909620bda824bd548fb8c26cc848f704166ed730d958f0173bd3b0a672f367bd", + "949e445b0459983abd399571a1a7150aab3dd79f4b52a1cd5d733e436c71c1d4b74287c6b0ce6cc90c6711ba4c541586", + "858966355dac11369e3b6552f2b381665181693d5a32e596984da3314021710b25a37d8c548b08700eea13d86cb22f21", + "974bcbb8d38c5e6518745cc03ad436e585b61f31d705e7e2e5085da9655d768ac4d800904f892c3dab65d6223e3f1fd6", + "8092b6506b01308bf6187fde5ebd4fa7448c9a640961ba231be22ac5fa2c7635ef01e8b357722c7695d09b723101ea2a", + "a5b8ef360bf28533ee17d8cd131fff661d265f609db49599085c0c7d83b0af409a1b5c28e3a5e5d7f8459a368aa121e8", + "b031b6d5e3ceab0f0c93314b3b675f55cf18cbc86f70444af266fe39cb22fd7dad75d8c84e07f1c1bfa2cb8283e1361a", + "93ad489e4f74658320c1cceed0137c023d3001a2c930ed87e6a21dbf02f2eb6ad1c1d8bcb3739c85dcfbecb040928707", + "b15e4ec2cdab0d34aec8d6c50338812eb6ecd588cf123a3e9d22a7ca23b5a98662af18289f09e6cdd85a39a2863c945c", + "b304f71a9717cf40c22073f942618b44bf27cd5e2ed4a386ad45d75b0fcb5a8dafd35158211eaf639495c6f1a651cedb", + "b82d78d3eaaa7c5101b7a5aae02bd4f002cd5802d18c3abcda0dd53b036661c6d3c8b79e0abe591eab90b6fdc5fef5e3", + "abbd1884243a35578b80914a5084449c237ee4e4660c279d1073a4d4217d1b55c6b7e9c087dfd08d94ac1416273d8d07", + "92f4b61c62502745e3e198ec29bca2e18696c69dcb914d1f3a73f4998d012b90caf99df46e9bb59942e43cce377fe8fd", + "906e79df98185820c8208844e1ba6bd86cb96965814b01310bd62f22cbec9b5d379b2ef16772d6fc45a421b60cfd68fe", + "a0eae2784ef596e2eb270dd40c48d6c508e4394c7d6d08d4cc1b56fde42b604d10ba752b3a80f2c4a737e080ef51b44f", + "94c084985e276dc249b09029e49a4ef8a369cd1737b51c1772fbb458d61e3fe120d0f517976eba8ffa5711ba93e46976", + "83619a0157eff3f480ab91d1d6225fead74c96a6fd685333f1e8e4d746f6273e226bad14232f1d1168a274e889f202f1", + "a724fe6a83d05dbbf9bb3f626e96db2c10d6d5c650c0a909415fbda9b5711c8b26e377201fb9ce82e94fa2ab0bf99351", + "a8a10c1b91a3a1fa2d7fd1f78a141191987270b13004600601d0f1f357042891010717319489f681aa8a1da79f7f00d5", + "a398a2e95b944940b1f8a8e5d697c50e7aa03994a8a640dfad4ea65cfb199a4d97861a3ec62d1c7b2b8d6e26488ca909", + "a2eedfe5452513b2a938fffd560798ef81379c5a5032d5b0da7b3bb812addbaad51f564c15d9acbbfc59bb7eddd0b798", + "ab31c572f6f145a53e13b962f11320a1f4d411739c86c88989f8f21ab629639905b3eedb0628067942b0dc1814b678ca", + "ad032736dd0e25652d3566f6763b48b34ea1507922ed162890cd050b1125ec03b6d41d34fccba36ec90336f7cdf788ed", + "83028a558a5847293147c483b74173eca28578186137df220df747fccd7d769528d7277336ea03c5d9cdd0bc5ae3d666", + "ab5d182cd1181de8e14d3ef615580217c165e470b7a094a276b78a3003089123db75c6e1650bf57d23e587c587cd7472", + "a4793e089fbdb1597654f43b4f7e02d843d4ab99ee54099c3d9f0bd5c0c5657c90bb076379a055b00c01b12843415251", + "98bdc52ee062035356fb2b5c3b41673198ddc60b2d1e546cb44e3bb36094ef3c9cf2e12bbc890feb7d9b15925439d1ea", + "a4f90cca6f48024a0341bd231797b03693b34e23d3e5b712eb24aba37a27827319b2c16188f97c0636a0c115381dc659", + "8888e6c2e4a574d04ba5f4264e77abc24ccc195f1a7e3194169b8a2ceded493740c52db4f9833b3dbf4d67a3c5b252cb", + "83dc4e302b8b0a76dc0292366520b7d246d73c6aebe1bdd16a02f645c082197bcff24a4369deda60336172cefbcf09af", + "a4eb2741699febfeb793914da3054337cc05c6fa00d740e5f97cb749ae16802c6256c9d4f0f7297dcdbb8b9f22fc0afa", + "8b65557d5be273d1cb992a25cfce40d460c3f288d5cb0a54bdef25cbd17cdea5c32ec966e493addf5a74fd8e95b23e63", + "97c6577e76c73837bcb398b947cb4d3323d511141e0ddd0b456f59fbb1e8f920a5c20d7827a24309145efddee786140f", + "abcc0849ffe2a6a72157de907907b0a52deece04cf8317bee6fe1d999444b96e461eac95b6afde3d4fe530344086a625", + "9385c0115cb826a49df1917556efa47b5b5e4022b6a0d2082053d498ec9681da904ecf375368bb4e385833116ea61414", + "8b868c1841f0cdc175c90a81e610b0652c181db06731f5c8e72f8fafa0191620742e61a00db8215a991d60567b6a81ca", + "a8df15406f31b8fcf81f8ff98c01f3df73bf9ec84544ddec396bdf7fafa6fe084b3237bf7ef08ad43b26517de8c3cd26", + "a9943d21e35464ce54d4cc8b135731265a5d82f9ccf66133effa460ffdb443cdb694a25320506923eede88d972241bf2", + "a1378ee107dd7a3abcf269fd828887c288363e9b9ca2711377f2e96d2ed5e7c5ec8d3f1da995a3dcbedf1752d9c088fc", + "8a230856f9227b834c75bdebc1a57c7298a8351874bf39805c3e0255d6fd0e846f7ad49709b65ec1fd1a309331a83935", + "877bcf42549d42610e1780e721f5800972b51ba3b45c95c12b34cb35eeaf7eac8fa752edd7b342411820cf9093fea003", + "84c7a0b63842e50905624f1d2662506b16d1f3ea201877dfc76c79181c338b498eceb7cad24c2142c08919120e62f915", + "8e18b1bd04b1d65f6ed349b5d33a26fe349219043ead0e350b50ae7a65d6ff5f985dd9d318d3b807d29faa1a7de4fe42", + "8ea7b5a7503e1f0b3c3cd01f8e50207044b0a9c50ed1697794048bbe8efd6659e65134d172fb22f95439e1644f662e23", + "b1954a2818cad1dad6d343a7b23afa9aa8ad4463edc4eb51e26e087c2010927535020d045d97d44086d76acdb5818cbf", + "a5271ea85d0d21fa1ff59b027cf88847c0f999bbf578599083ff789a9b5228bc161e1c81deb97e74db1a82a0afd61c50", + "aa2fa4c05af3387e2c799315781d1910f69977ec1cfea57a25f1a37c63c4daaa3f0ecd400884a1673e17dd5300853bcf", + "b1cd2a74ca0b8e6090da29787aef9b037b03b96607983a308b790133bd21297b21ca4e2edec890874096dbf54e9d04c3", + "801931607ec66a81272feaa984f0b949ad12d75ecf324ba96627bd4dc5ddead8ebf088f78e836b6587c2b6c0b3366b6c", + "95d79504710bdf0ad9b9c3da79068c30665818c2f0cdbba02cc0a5e46e29d596032ac984441b429bd62e34535c8d55b0", + "9857d41e25e67876510ff8dadf0162019590f902da1897da0ef6fc8556e3c98961edb1eb3a3a5c000f6c494413ded15e", + "8740c9ffe6bd179c19a400137c3bd3a593b85bd4c264e26b4dfb9e2e17ac73e5b52dfacc1dcb4033cfc0cd04785f4363", + "977f98f29d948b4097a4abdf9345f4c1fb0aa94ba0c6bf6faa13b76f3a3efc8f688e1fe96099b71b3e1c05041118c8d1", + "a364422b1239126e3e8d7b84953ce2181f9856319b0a29fcab81e17ac27d35798088859c1cfc9fc12b2dbbf54d4f70b3", + "a0f6ba637f0db7a48e07439bb92ddb20d590ce9e2ed5bab08d73aa22d82c32a9a370fe934cbe9c08aeb84b11adcf2e0e", + "a2c548641bd5b677c7748327cca598a98a03a031945276be6d5c4357b6d04f8f40dd1c942ee6ec8499d56a1290ac134d", + "9863e9cc5fbcdbd105a41d9778d7c402686bfd2d81d9ed107b4fda15e728871c38647529693306855bee33a00d257a7e", + "a54173bf47b976290c88fd41f99300135de222f1f76293757a438450880e6f13dbde3d5fe7afc687bdfbcfc4fbc1fc47", + "b8db413917c60907b73a997b5ab42939abd05552c56a13525e3253eb72b83f0d5cc52b695968a10005c2e2fe13290e61", + "a1f8388ef21697c94ba90b1a1c157f0dc138e502379e6fc5dc47890d284563e5db7716266e1b91927e5adf3cde4c0a72", + "9949013a59d890eb358eab12e623b2b5edb1acbee238dfad8b7253102abc6173922e188d5b89ec405aa377be8be5f16d", + "a00fdb7710db992041f6ddb3c00099e1ce311dea43c252c58f560c0d499983a89de67803a8e57baa01ee9d0ee6fa1e44", + "a8b1bcbed1951c9cdb974b61078412881b830b48cd6b384db0c00fa68bcc3f4312f8e56c892ea99d3511857ef79d3db9", + "8f3ee78404edc08af23b1a28c2012cee0bdf3599a6cb4ea689fc47df4a765ef519191819a72562b91a0fbcdb896a937e", + "8155bbb7fa8d386848b0a87caae4da3dec1f3dade95c750a64a8e3555166ccc8799f638bd80ed116c74e3a995541587a", + "abfe30adbc0a6f1fd95c630ed5dac891b85384fa9331e86b83217f29dff0bd7cad19d328485715a7e3df9a19069d4d2f", + "89d0783e496ee8dbb695764b87fb04cee14d4e96c4ba613a19736971c577d312079048142c12ce5b32b21e4d491d281b", + "856b8dbc9c5d8f56b6bb7d909f339ca6da9a8787bba91f09130a025ab6d29b64dbf728ba6ed26e160a23c1cdb9bc037b", + "8a30dd2ea24491141047a7dfe1a4af217661c693edf70b534d52ca547625c7397a0d721e568d5b8398595856e80e9730", + "ae7e1412feb68c5721922ed9279fb05549b7ef6812a4fd33dbbbd7effab756ab74634f195d0c072143c9f1fd0e1ee483", + "b7ce970e06fa9832b82eef572f2902c263fda29fdce9676f575860aae20863046243558ede2c92343616be5184944844", + "85ed0531f0e5c1a5d0bfe819d1aa29d6d5ff7f64ad8a0555560f84b72dee78e66931a594c72e1c01b36a877d48e017ca", + "b8595be631dc5b7ea55b7eb8f2982c74544b1e5befc4984803b1c69727eac0079558182f109e755df3fd64bee00fcaa5", + "99e15a66e5b32468ef8813e106271df4f8ba43a57629162832835b8b89402eb32169f3d2c8de1eb40201ce10e346a025", + "844c6f5070a8c73fdfb3ed78d1eddca1be31192797ad53d47f98b10b74cc47a325d2bc07f6ee46f05e26cf46a6433efb", + "974059da7f13da3694ad33f95829eb1e95f3f3bfc35ef5ef0247547d3d8ee919926c3bd473ab8b877ff4faa07fcc8580", + "b6f025aecc5698f6243cc531782b760f946efebe0c79b9a09fe99de1da9986d94fa0057003d0f3631c39783e6d84c7d5", + "b0c5358bc9c6dfe181c5fdf853b16149536fbb70f82c3b00db8d854aefe4db26f87332c6117f017386af8b40288d08f9", + "a3106be5e52b63119040b167ff9874e2670bd059b924b9817c78199317deb5905ae7bff24a8ff170de54a02c34ff40a4", + "ad846eb8953a41c37bcd80ad543955942a47953cbc8fb4d766eac5307892d34e17e5549dc14467724205255bc14e9b39", + "b16607e7f0f9d3636e659e907af4a086ad4731488f5703f0917c4ce71a696072a14a067db71a3d103530920e1ec50c16", + "8ed820e27116e60c412c608582e9bb262eaaf197197c9b7df6d62b21a28b26d49ea6c8bb77dfde821869d9b58025f939", + "97bc25201d98cde389dd5c0c223a6f844393b08f75d3b63326343073e467ac23aacef630ddc68545ea874299ba4a3b4f", + "b73c9695ad2eefd6cc989a251c433fab7d431f5e19f11d415a901762717d1004bb61e0cc4497af5a8abf2d567e59fef4", + "adaabe331eea932533a7cc0cf642e2a5e9d60bbc92dd2924d9b429571cbf0d62d32c207b346607a40643c6909b8727e2", + "a7b1bbfe2a5e9e8950c7cb4daab44a40c3ffab01dc012ed7fe445f4af47fa56d774a618fafe332ab99cac4dfb5cf4794", + "b4a3c454dcd5af850212e8b9ba5fe5c0d958d6b1cabbf6c6cfe3ccbc4d4c943309c18b047256867daf359006a23f3667", + "a5c0b32f6cef993834c1381ec57ad1b6f26ae7a8190dd26af0116e73dadc53bb0eeb1911419d609b79ce98b51fdc33bc", + "ac2f52de3ecf4c437c06c91f35f7ac7d171121d0b16d294a317897918679f3b9db1cef3dd0f43adb6b89fe3030728415", + "94722ae6d328b1f8feaf6f0f78804e9b0219de85d6f14e8626c2845681841b2261d3e6a2c5b124086b7931bf89e26b46", + "a841a0602385d17afabca3a1bb6039167d75e5ec870fea60cfcaec4863039b4d745f1a008b40ec07bca4e42cb73f0d21", + "8c355f0a1886ffced584b4a002607e58ff3f130e9de827e36d38e57cb618c0cb0b2d2dea2966c461cb3a3887ede9aef1", + "a6a9817b0fc2fd1786f5ba1a7b3d8595310987fb8d62f50a752c6bb0b2a95b67d03a4adfd13e10aa6190a280b7ee9a67", + "a1d2e552581ecbafeaef08e389eaa0b600a139d446e7d0648ac5db8bbbf3c438d59497e3a2874fc692b4924b87ff2f83", + "a1b271c55389f25639fe043e831e2c33a8ba045e07683d1468c6edd81fedb91684e4869becfb164330451cfe699c31a8", + "8c263426e7f7e52f299d57d047a09b5eeb893644b86f4d149535a5046afd655a36d9e3fdb35f3201c2ccac2323a9582e", + "b41c242a7f7880c714241a97d56cce658ee6bcb795aec057a7b7c358d65f809eb901e0d51256826727dc0dc1d1887045", + "93001b9445813c82f692f94c0dc1e55298f609936b743cf7aae5ebfa86204f38833d3a73f7b67314be67c06a1de5682d", + "82087536dc5e78422ad631af6c64c8d44f981c195ddea07d5af9bb0e014cdc949c6fa6e42fce823e0087fdb329d50a34", + "8e071861ceba2737792741c031f57e0294c4892684506b7c4a0fc8b2f9a0a6b0a5635de3d1e8716c34df0194d789ae86", + "b471c997e1e11774bd053f15609d58838a74073a6c089a7a32c37dd3f933badf98c7e5833263f3e77bc0d156a62dd750", + "8d2d8686fb065b61714414bb6878fff3f9e1e303c8e02350fd79e2a7f0555ded05557628152c00166ce71c62c4d2feaa", + "ae4c75274d21c02380730e91de2056c0262ffcecf0cbdb519f0bdb0b5a10ae2d4996b3dc4b3e16dbaea7f0c63d497fef", + "97140d819e8ca6330e589c6debdee77041c5a9cedb9b8cbd9c541a49207eeb7f6e6b1c7e736ec8ba6b3ab10f7fcd443a", + "af6659f31f820291a160be452e64d1293aa68b5074b4c066dac169b8d01d0179139504df867dc56e2a6120354fc1f5be", + "a5e5d8088a368024617bfde6b731bf9eee35fc362bed3f5dfdd399e23a2495f97f17728fec99ca945b3282d1858aa338", + "a59cfc79d15dbdde51ab8e5129c97d3baba5a0a09272e6d2f3862370fdbaf90994e522e8bd99d6b14b3bb2e9e5545c6f", + "a30499b068083b28d6c7ddcc22f6b39b5ec84c8ee31c5630822c50ea736bb9dca41c265cffc6239f1c9ef2fd21476286", + "88ffe103eca84bbe7d1e39a1aa599a5c7c9d5533204d5c4e085402a51441bb8efb8971efe936efbbfa05e5cb0d4b8017", + "b202356fbf95a4d699154639e8cb03d02112c3e0128aab54d604645d8510a9ba98936028349b661672c3a4b36b9cb45d", + "8b89bb6574bf3524473cff1ff743abcf1406bd11fb0a72070ccd7d8fce9493b0069fb0c6655252a5164aee9e446ea772", + "93247b1038fa7e26667ee6446561d4882dc808d1015daafb705935ddc3598bb1433182c756465960480f7b2de391649e", + "b027f94d3358cbb8b6c8c227300293a0dee57bf2fee190a456ad82ecfb6c32f8090afa783e2ab16f8139805e1fb69534", + "a18bb1849b2f06c1d2214371031d41c76ffa803ee3aa60920d29dbf3db5fbfac2b7383d5d0080ba29ce25c7baa7c306b", + "827bf9fd647e238d5ac961c661e5bbf694b4c80b3af8079f94a2484cb8fba2c8cf60e472ebcd0b0024d98ae80ad2ff5a", + "838e891218c626a7f39b8fd546b013587408e8e366ecc636b54f97fa76f0a758bc1effa1d0f9b6b3bc1a7fcc505970a0", + "836523b5e8902d6e430c6a12cff01e417d2bd7b402e03904034e3b39755dee540d382778c1abe851d840d318ebedce7f", + "850a77dda9ac6c217e2ef00bf386a1adec18b7f462f52801c4f541215690502a77ef7519b690e22fdf54dc2109e0ca38", + "a8265c6ae7b29fc2bda6a2f99ced0c1945dd514b1c6ca19da84b5269514f48a4f7b2ccbab65c9107cfd5b30b26e5462f", + "ab3d02ee1f1267e8d9d8f27cc388e218f3af728f1de811242b10e01de83471a1c8f623e282da5a284d77884d9b8cde0e", + "831edaf4397e22871ea5ddee1e7036bab9cc72f8d955c7d8a97f5e783f40532edbbb444d0520fefcffeab75677864644", + "80484487977e4877738744d67b9a35b6c96be579a9faa4a263e692295bb6e01f6e5a059181f3dd0278e2c3c24d10a451", + "aae65a18f28c8812617c11ecf30ad525421f31fb389b8b52d7892415e805a133f46d1feca89923f8f5b8234bd233486a", + "b3a36fd78979e94288b4cefed82f043a7e24a4a8025479cc7eb39591e34603048a41ee606ee03c0b5781ebe26a424399", + "b748b3fc0d1e12e876d626a1ba8ad6ad0c1f41ea89c3948e9f7d2666e90173eb9438027fadcd741d3ae0696bd13840f1", + "acdd252d7c216c470683a140a808e011c4d5f1b4e91aeb947f099c717b6a3bad6651142cde988330827eb7d19d5fb25c", + "b9a25556a6ca35db1ed59a1ec6f23343eab207a3146e4fc3324136e411c8dba77efd567938c63a39c2f1c676b07d8cdb", + "a8db6aef8f5680d2bdb415d7bcaae11de1458678dcb8c90c441d5986c44f83a9e5855662d0c1aace999172d8628d8fe1", + "af58147108e9909c3a9710cc186eab598682dca4bfd22481e040b8c000593ecb22c4ede4253ac9504e964dfa95a9b150", + "8dd8bb70f1c9aec0fcc9478f24dfc9c3c36c0bf5ff7a67c017fa4dab2ec633fbd7bc9d8aa41ea63e2696971ed7e375f5", + "aa98d600b22aff993a4d7a3ccabd314e1825b200cb598f6b797d7e4d6a76d89e34a4d156c06bddfc62f2ef9b4c809d1d", + "8a8fc960d6c51294b8205d1dabe430bef59bda69824fa5c3c3105bef22ac77c36d2d0f38ffc95ce63731de5544ccbeff", + "b6d1020efe01dc8032bd1b35e622325d7b9af9dcd5c9c87c48d7d6ebc58644454294c59b7f4b209204b5b1f899f473bf", + "8a750dc9fe4891f2dfe5759fb985939810e4cdc0b4e243ff324b6143f87676d8cb4bcb9dfb01b550801cedcaaa5349e2", + "98c13142d3a9c5f8d452245c40c6dae4327dd958e0fda85255ea0f87e0bcbaa42a3a0bd50407ed2b23f9f6317a8a4bc5", + "99f2b83d9ec4fc46085a6d2a70fd0345df10f4a724c1ba4dee082a1fde9e642e3091992ebf5f90a731abcb6ec11f6d9b", + "b218546ab2db565b2489ea4205b79daa19ef2acbf772ccaaa5e40150e67ea466090d07198444b48e7109939aa2319148", + "84f9d1d868e4b55e535f1016558f1789df0daa0ead2d13153e02f715fe8049b1ce79f5bc1b0bbbb0b7e4dd3c04783f3f", + "80d870d212fbddfdda943e90d35a5a8aa0509a7a1e7f8909f2fcb09c51c3026be47cc7a22620a3063406872105b4f81a", + "b5b15138ff6551fac535d4bbce2ea6adc516b6b7734b4601c66ec029da2615e3119dc9ad6a937344acfd7b50e4a1a2ae", + "95d2f97652086e7ceb54e1d32692b1c867ffba23c4325740c7f10d369283d1b389e8afa0df967831ade55696931e7934", + "8a5b580403e1a99cd208f707e8ce0d3f658c8280417683f69008d09cc74d835a85f7380f391b36ead9ac66d9eedd1cbe", + "a8b0c90bff34c86720637b5a2081f0f144cfe2205c1176cacd87d348609bc67af68aed72414dc9aa6f44a82c92c2a890", + "865abbdd96c496892c165a8de0f9e73348bf24fce361d7a9048710178a3625881afb0006e9f5ee39124866b87904c904", + "ace67bb994adef4b6f841cdf349195608030044562780a7e9b00b58a4ff117268a03ff01e5a3a9d9d7eff1dd01f5f4bf", + "b9371d59185b3d2d320d3fefeadb06ba2aa7d164352fb8dc37571509509fa214d736d244ac625a09a033a10d51611e2e", + "a8ef992771422dcf2d6d84386fde9fe5dba88bfded3dfcd14074ca04331b4fd53a7f316615cdfaf10ed932cbb424a153", + "868cbc75f8f789ea45eded2768a1dac0763347e0d8e8028d316a21005f17be179d26d5965903e51b037f2f57fe41765d", + "b607111bcdfd05fa144aa0281b13ee736079ebbbf384d938a60e5e3579639ed8ef8eb9ca184868cdb220a8e130d4a952", + "aca55702af5cae4cae65576769effd98858307a71b011841c563b97c2aa5aeb5c4f8645d254f631ed1582df3dbbf17da", + "b9b5cbace76246e80c20dfcc6f1e2c757a22ab53f7fd9ff8a1d309538b55174e55e557a13bf68f095ff6a4fa637ef21a", + "8571b0a96871f254e2397c9be495c76379faf347801cb946b94e63212d6a0da61c80e5d7bebbabcd6eaa7f1029172fe5", + "902540326281e6dc9c20d9c4deaaf6fbbbcc3d1869bd0cf7f081c0525bea33df5cfa24ead61430fda47fb964fcc7994b", + "841af09279d3536a666fa072278950fabf27c59fc15f79bd52acb078675f8087f657929c97b4bc761cbade0ecb955541", + "a1f958b147ddf80ab2c0746ba11685c4bae37eb25bfa0442e7e1078a00d5311d25499da30f6d168cb9302ea1f2e35091", + "863d939381db37d5a5866964be3392a70be460f0353af799d6b3ed6307176972686bd378f8ad457435a4094d27e8dfb7", + "835cd4d7f36eff553d17483eb6c041b14280beb82c7c69bca115929658455a1931212976c619bafb8179aed9940a8cc6", + "8d0770e3cb8225e39c454a1fc76954118491b59d97193c72c174ecc7613051e5aed48a534016a8cf0795c524f771a010", + "91aa4edb82f6f40db2b7bd4789cc08786f6996ebed3cb6f06248e4884bc949793f04a4c5ea6eefe77984b1cc2a45d699", + "8fb494ca2449f659ff4838833507a55500a016be9293e76598bbae0a7cb5687e4693757c2b6d76e62bd6c7f19ed080bb", + "b59b104449a880a282c1dd6a3d8debb1d8814ef35aab5673c1e500ee4cb0e840fb23e05fa5a0af92509c26b97f098f90", + "aca908e3bad65e854ae6be6c5db441a06bcd47f5abafdfa8f5a83c8cd3c6e08c33cab139c45887887a478338e19ceb9f", + "806f5d802040313a31964fc3eb0ee18ac91b348685bed93c13440984ee46f3d2da7194af18c63dea4196549129660a4e", + "ae4b2dca75c28d8f23b3ab760b19d839f39ff5a3112e33cb44cff22492604a63c382b88ec67be4b0266924dd438c3183", + "99d1c29c6bd8bf384e79cd46e30b8f79f9cbc7d3bf980e9d6ffba048f0fc487cac45c364a8a44bb6027ad90721475482", + "a16e861c1af76d35528c25bf804bfc41c4e1e91b2927d07d8e96bffe3a781b4934e9d131ecf173be9399800b8269efac", + "a253303234fb74f5829060cdcef1d98652441ab6db7344b1e470d195a95722675988048d840201c3b98e794b1e8b037c", + "905ac8a0ea9ce0eb373fb0f83dd4cbe20afb45b9d21ae307846fd4757d4d891b26a6711924e081e2b8151e14a496da18", + "b485315791e775b9856cc5a820b10f1fa5028d5b92c2f0e003ba55134e1eddb3eb25f985f2611a2257acf3e7cfdfab5e", + "b6189c0458b9a043ebc500abc4d88083a3487b7ac47ed5e13ab2a41e0a1bee50d54a406063f92bc96959f19e822a89a7", + "a30e15f995fd099a223fc6dc30dad4b8d40bee00caa2bc3223ba6d53cd717c4968a3e90c4618c711ed37cc4cd4c56cf3", + "a1b1ed07fcc350bb12a09cd343768d208fc51a6b3486f0ece8f5a52f8a5810b4bc7ab75582ec0bc2770aed52f68eace5", + "88aa739fbae4bece147ba51a863e45d5f7203dbc3138975dc5aef1c32656feb35f014d626e0d5b3d8b1a2bda6f547509", + "ab570f3c8eabfca325b3a2ea775ef6b0c6e6138c39d53c2310329e8fb162869fde22b0e55688de9eb63d65c37598fca3", + "89d274762c02158e27cb37052e296a78f2b643eb7f9ae409f8dac5c587d8b4d82be4ef7c79344a08ebec16ac4a895714", + "99c411d2ad531e64f06e604d44c71c7c384424498ecd0a567d31ec380727fb605af76643d0d5513dd0a8d018076dd087", + "80d0777fa9f79f4a0f0f937d6de277eec22b3507e2e398f44b16e11e40edf5feff55b3b07a69e95e7e3a1621add5ed58", + "b2430a460783f44feb6e4e342106571ef81ad36e3ddd908ec719febeb7acaf4b833de34998f83a1dab8f0137a3744c11", + "b8f38ccfc7279e1e30ad7cefc3ea146b0e2dff62430c50a5c72649a4f38f2bac2996124b03af2079d942b47b078cc4f8", + "a178a450a62f30ec2832ac13bbc48789549c64fc9d607b766f6d7998558a0e2fad007ae0148fc5747189b713f654e6ba", + "98c5ede296f3016f6597f7ccc5f82c88fd38ed6dc3d6da3e4a916bfd7c4c95928722a1d02534fe89387c201d70aa6fd2", + "a8cc5e98573705d396576e022b2ba2c3e7c7ece45cd8605cb534b511763682582299e91b4bb4100c967019d9f15bbfaf", + "848480ea7b7d9536e469da721236d932870b7bbee31ccf7ae31b4d98d91413f59b94a1e0d1786ee7342295aa3734969c", + "b88ea38f9ee432f49e09e4e013b19dff5a50b65453e17caf612155fff6622198f3cba43b2ea493a87e160935aaaf20a9", + "949376934a61e0ef8894339c8913b5f3b228fa0ae5c532ad99b8d783b9e4451e4588541f223d87273c0e96c0020d5372", + "96f90bb65ca6b476527d32c415814b9e09061648d34993f72f28fae7dc9c197e04ef979f804076d107bb218dfd9cb299", + "a4402da95d9942c8f26617e02a7cef0ebc4b757fac72f222a7958e554c82cc216444de93f659e4a1d643b3e55a95d526", + "81179cbc26a33f6d339b05ea3e1d6b9e1190bd44e94161ae36357b9cdf1e37d745d45c61735feed64371fe5384102366", + "ad4dc22bdbd60e147fdac57d98166de37c727f090059cfc33e5ee6cf85e23c2643996b75cf1b37c63f3dc9d3c57ffa18", + "8a9b1b93dc56e078ce3bb61c2b0088fd6c3e303ba6b943231cc79d4a8e8572f4109bbde5f5aa7333aae3287909cb0fe2", + "8876ef583bc1513322457a4807d03381ba1f4d13e179260eaa3bddfede8df677b02b176c6c9f74c8e6eab0e5edee6de6", + "b6c67e228bf190fbaeb2b7ec34d4717ce710829c3e4964f56ebb7e64dc85058c30be08030fa87cc94f1734c5206aef5f", + "a00cb53b804ee9e85ce12c0103f12450d977bc54a41195819973c8a06dcb3f46f2bf83c3102db62c92c57ab4dd1e9218", + "a7675a64772eefddf8e94636fb7d1d28f277074327c02eea8fae88989de0c5f2dc1efed010f4992d57b5f59a0ab40d69", + "8d42bb915e0bf6a62bcdf2d9330eca9b64f9ec36c21ae14bf1d9b0805e5e0228b8a5872be61be8133ad06f11cb77c363", + "a5b134de0d76df71af3001f70e65c6d78bed571bc06bfddf40d0baad7ea2767608b1777b7ef4c836a8445949877eeb34", + "aeadbc771eaa5de3a353229d33ed8c66e85efbd498e5be467709cb7ff70d3f1a7640002568b0940e3abd7b2da81d2821", + "8c28da8e57a388007bd2620106f6226b011ee716a795c5d9f041c810edf9cf7345b2e2e7d06d8a6b6afa1ee01a5badc1", + "8ed070626a4d39ffd952ddb177bc68fd35b325312e7c11694c99b691f92a8ea7734aeb96cf9cc73e05b3c1b1dcad6978", + "ada83e18e4842f3d8871881d5dbc81aed88a1328298bfdc9e28275094bd88d71b02e7b8501c380fa8d93096cbc62f4fb", + "8befc3bec82dcf000a94603b4a35c1950ba5d00d4bed12661e4237afa75062aa5dcef8eac0b9803136c76d2dd424a689", + "97c6f36c91ca5ca9230bfcbf109d813728b965a29b62e5f54c8e602d14a52ac38fa1270de8bfe1ab365426f3fc3654c7", + "b01d192af3d8dbce2fe2fece231449e70eb9ac194ec98e758da11ca53294a0fa8c29b1d23a5d9064b938b259ea3b4fb5", + "819a2c20646178f2f02865340db1c3c6ebc18f4e6559dd93aa604388796a34bd9fed28ad3ccc8afc57a5b60bb5c4e4ec", + "a9ffc877470afc169fecf9ec2dc33253b677371938b0c4ffa10f77bb80089afa2b4488437be90bb1bcf7586a6f4286e3", + "b533051c7ce7107176bcb34ad49fdb41fac32d145854d2fe0a561c200dcf242da484156177e2c8f411c3fdf1559ecf83", + "8fe2caff2e4241d353110a3618832f1443f7afe171fd14607009a4a0aa18509a4f1367b67913e1235ac19de15e732eb1", + "84705c6370619403b9f498059f9869fdf5f188d9d9231a0cb67b1da2e8c906ead51b934286497293698bba269c48aa59", + "899dddf312a37e3b10bdaaacc1789d71d710994b6ee2928ac982ad3fd8a4f6167672bc8bf3419412711c591afe801c28", + "b2f7916d946b903ded57b9d57025386143410a41a139b183b70aeca09cf43f5089ead1450fce4e6eb4fba2c8f5c5bbe5", + "8d5f742fe27a41623b5820914c5ca59f82246010fa974304204839880e5d0db8bc45ebab2ad19287f0de4ac6af25c09e", + "b93d4a1f6f73ac34da5ffbd2a4199cf1d51888bc930dc3e481b78806f454fcb700b4021af7525b108d49ebbbaa936309", + "8606f8d9121512e0217a70249937e5c7f35fbfe019f02248b035fa3a87d607bc23ae66d0443e26a4324f1f8e57fd6a25", + "b21312cdec9c2c30dd7e06e9d3151f3c1aceeb0c2f47cf9800cce41521b9d835cb501f98b410dc1d49a310fdda9bc250", + "a56420b64286bdddda1e212bba268e9d1ba6bdb7132484bf7f0b9e38099b94a540884079b07c501c519b0813c184f6b4", + "80b2cf0e010118cb2260f9c793cef136f8fa7b5e2711703735524e71d43bce2d296c093be41f2f59118cac71f1c5a2ff", + "adcb12d65163804d2f66b53f313f97152841c3625dbbda765e889b9937195c6fcd55d45cc48ebffabb56a5e5fe041611", + "8b8a42e50dc6b08ab2f69fc0f6d45e1ea3f11ba0c1008ee48448d79d1897356599e84f7f9d8a100329ed384d6787cfc4", + "aaa9c74afa2dec7eccfbd8bb0fc6f24ed04e74c9e2566c0755a00afdfdf3c4c7c59e2a037ec89c2f20af3fae1dd83b46", + "aa9f6e8fd59187171c6083ae433627d702eb78084f59010ff07aff8f821f7022ef5fbbe23d76814d811b720a8bfa6cc3", + "a56a3ded501659ad006d679af3287080b7ee8449e579406c2cae9706ef8bf19c1fc2eb2a6f9eaf2d3c7582cded73e477", + "81971e077c1da25845840222b4191e65f6d242b264af4e86800f80072d97d2a27a6adc87c3a1cb1b0dd63d233fbafa81", + "a6fa5453c4aaad2947969ee856616bf6448224f7c5bf578f440bcfc85a55beb40bef79df8096c4db59d1bd8ef33293ea", + "87c545adbfaaf71e0ab4bac9ae4e1419718f52b0060e8bb16b33db6d71b7248ae259d8dd4795b36a4bbb17f8fae9fd86", + "b4c7a9bc0910e905713291d549cec5309e2d6c9b5ea96954489b1dff2e490a6c8b1fa1e392232575f0a424ba94202f61", + "802350b761bcaba21b7afe82c8c6d36ee892b4524ab67e2161a91bbfa1d8e92e7e771efb1f22c14126218dd2cb583957", + "b4e7ddb9143d4d78ea8ea54f1c908879877d3c96ee8b5e1cb738949dcfceb3012a464506d8ae97aa99ea1de2abf34e3d", + "a49a214065c512ad5b7cc45154657a206ef3979aa753b352f8b334411f096d28fd42bca17e57d4baaafb014ac798fc10", + "8a80c70a06792678a97fe307520c0bf8ed3669f2617308752a2ab3c76fdf3726b014335a9b4c9cbcfc1df3b9e983c56f", + "a34721d9e2a0e4d08995a9d986dc9c266c766296d8d85e7b954651ad2ca07e55abb1b215898ee300da9b67114b036e0d", + "8cfce4564a526d7dca31e013e0531a9510b63845bbbd868d5783875ed45f92c1c369ce4a01d9d541f55f83c2c0a94f03", + "ab3f5f03a5afc727778eb3edf70e4249061810eba06dc3b96b718e194c89429c5bfbec4b06f8bce8a2118a2fdce67b59", + "aa80c2529fc19d428342c894d4a30cb876169b1a2df81a723ab313a071cba28321de3511a4de7846207e916b395abcc9", + "82b7828249bf535ef24547d6618164b3f72691c17ca1268a5ee9052dba0db2fdd9987c8e083307a54399eab11b0f76b1", + "8fbcb56b687adad8655a6cf43364a18a434bf635e60512fad2c435cf046f914228fb314f7d8d24d7e5e774fb5ffb1735", + "a3010a61a2642f5ebbce7b4bc5d6ecb3df98722a49eb1655fe43c1d4b08f11dfad4bcec3e3f162d4cc7af6a504f4d47c", + "b3dcc0fdf531478e7c9ef53190aa5607fd053a7d2af6c24a15d74c279dbb47e3c803a1c6517d7e45d6534bb59e3527f5", + "8648f6316c898baaca534dff577c38e046b8dfa8f5a14ee7c7bc95d93ae42aa7794ba0f95688a13b554eeb58aeedf9ba", + "89fca6fc50407695e9315483b24f8b4e75936edf1475bcf609eed1c4370819abac0e6a7c3c44f669560367d805d9ba63", + "a367a17db374f34cd50f66fb31ba5b7de9dbe040f23db2dcc1d6811c0e863606f6c51850af203956f3399000f284d05f", + "91030f9ca0fff3e2dbd5947dcf2eba95eb3dbca92ee2df0ed83a1f73dbf274611af7daf1bb0c5c2ee46893ab87013771", + "84d56181f304ce94015ea575afeef1f84ea0c5dbb5d29fb41f25c7f26077b1a495aff74bd713b83bce48c62d7c36e42d", + "8fe2f84f178739c3e2a2f7dcac5351c52cbed5fa30255c29b9ae603ffd0c1a181da7fb5da40a4a39eec6ce971c328fcf", + "a6f9b77b2fdf0b9ee98cb6ff61073260b134eb7a428e14154b3aa34f57628e8980c03664c20f65becfe50d2bdd2751d4", + "8c6760865445b9327c34d2a1247583694fbeb876055a6a0a9e5cb460e35d0b2c419e7b14768f1cc388a6468c94fd0a0f", + "af0350672488a96fe0089d633311ac308978a2b891b6dbb40a73882f1bda7381a1a24a03e115ead2937bf9dcd80572ad", + "a8e528ec2ee78389dd31d8280e07c3fdd84d49556a0969d9d5c134d9a55cd79e1d65463367b9512389f125ed956bc36a", + "942c66589b24f93e81fe3a3be3db0cd4d15a93fb75260b1f7419f58d66afaa57c8d2d8e6571536790e2b415eec348fd9", + "83fe4184b4b277d8bf65fb747b3c944170824b5832751057e43465526560f60da6e5bbee2f183cb20b896a20197168c7", + "88a71aada494e22c48db673d9e203eef7a4e551d25063b126017066c7c241ee82bedaa35741de4bd78a3dd8e21a8af44", + "8c642a3186ca264aac16ee5e27bd8da7e40e9c67ae159b5d32daa87b7de394bf2d7e80e7efb1a5506c53bfd6edd8c2c3", + "81855d6de9a59cef51bef12c72f07f1e0e8fe324fcc7ec3f850a532e96dcd434c247130610aaee413956f56b31cbb0dc", + "a01e61390dcd56a58ad2fcdb3275704ddfbedef3ba8b7c5fce4814a6cdd03d19d985dba6fd3383d4db089444ea9b9b4d", + "96494e89cbf3f9b69488a875434302000c2c49b5d07e5ff048a5b4a8147c98291ae222529b61bb66f1903b2e988e5425", + "b9689b3e8dddc6ec9d5c42ba9877f02c1779b2c912bba5183778dc2f022b49aed21c61c8ec7e3c02d74fe3f020a15986", + "a2a85e213b80b0511395da318cbb9935c87b82c305f717a264155a28a2ea204e9e726bae04ce6f012e331bd6730cbb9d", + "91b70f44c7d8c5980ce77e9033a34b05781cbe773854d3f49d2905cc711a3d87c20d5d496801ad6fd82438874ce732b8", + "884596417ff741bb4d11925d73852ffeea7161c7f232be3bdce9e6bbe7884c3a784f8f1807356ae49d336b7b53a2b495", + "ae2aed8ab6951d8d768789f5bc5d638838d290d33ccc152edfb123e88ba04c6272b44294b0c460880451ad7b3868cc6a", + "89d8ebfb9beebc77189d27de31c55f823da87798a50bca21622cbf871e5d9f1d3182cf32ee9b90f157e6ce298e9efccf", + "afd00a4db4c2ed93cf047378c9402914b6b3255779f3bb47ded4ab206acb7eaebba0fd7762928e681b1aebcfee994adc", + "a2e49b6cd32e95d141ebc29f8c0b398bb5e1a04945f09e7e30a4062142111cd7aa712ac0e3e6394cfb73dd854f41ad77", + "ae8e714ab6e01812a4de5828d84060f626358bb2b955f6fb99ae887b0d5ce4f67ebc079ab9e27d189bf1d3f24f7c2014", + "a3100c1eebf46d604e75ebf78569c25acf938d112b29ccbe1a91582f6bd8ef5548ae3961c808d3fb73936ac244e28dbc", + "a9a02dcff0e93d47ead9cdddc4759971c2d848580bf50e117eb100cafca6afeaa7b87208513d5f96b1e1440ffc1b0212", + "894ab01462137e1b0db7b84920a3b677fbb46c52b6f4c15320ef64f985e0fc05cec84cd48f389ce039779d5376966ea3", + "b1e40e8399ee793e5f501c9c43bde23538e3ce473c20a9f914f4a64f5b565748d13ab2406efe40a048965ee4476113e4", + "a5a7d97a19e636238968670a916d007bf2ce6ae8e352345d274101d0bbe3ac9b898f5b85814a7e4c433dd22ac2e000ff", + "b6394c43b82923231d93fd0aa8124b757163ba62df369898b9481f0118cb85375d0caac979a198ece432dbb4eb7cc357", + "82d522ae3ff4fe2c607b34b42af6f39c0cf96fcfe1f5b1812fca21c8d20cece78376da86dcbd6cdb140e23c93ae0bcb2", + "b6e0d986383bc4955508d35af92f2993e7e89db745f4525948c5274cfd500880cb5a9d58a5b13d96f6368bb266a4433e", + "b0b4325772ec156571d740c404e1add233fb693579f653b0fae0042b03157d3b904838f05c321d2d30f2dbd27c4d08ad", + "ac41367250263a2099006ef80c30bac1d2f25731d4874be623b6e315c45b0dc9a65f530fce82fb3dc25bd0610008c760", + "b6c0b1ed7df53da04a6f3e796d3bfa186f9551c523bc67898bc0ecfc6b4a4a22f8c4d3bfc740ebf7b9fa5b0ea9431808", + "8e78fca17346601219d01e5cd6a4837161a7c8f86fe2a8d93574d8006da5f06ae7c48eea7d2b70992c2a69184619663c", + "a21f91f47e04fafbfafacf3185b6863766a2d0c324ccac2c3853a4748af5897dbbe31d91473b480f646121339c9bae2d", + "a464d68786ab1fc64bd8734fce0be6fbe8dc021d3e771ff492ada76eedff466577c25e282b7c8ab4c1fd95ef5ff3631e", + "829a24badc7714081e03509ccfb00818ce40430682c1c0e4a399cd10b690bda1f921aabcbf1edfb1d8a2e98e6c0cedd6", + "87ccf7e4bbcb818ef525435e7a7f039ecbb9c6670b0af163173da38cbdb07f18bc0b40b7e0c771a74e5a4bc8f12dfe2c", + "94087bd2af9dbeb449eb7f014cfbf3ee4348c0f47cde7dc0ad401a3c18481a8a33b89322227dee0822244965ae5a2abb", + "896b83ed78724dac8a3d5a75a99de8e056a083690152c303326aa833618b93ef9ec19ab8c6ef0efe9da2dbcccac54431", + "821e6a0d7ccf3c7bd6a6cc67cde6c5b92fb96542cb6b4e65a44bbc90bbc40c51ff9e04702cb69dd2452f39a2ff562898", + "b35b2096cda729090663a49cb09656c019fef1fc69a88496028d3a258ad2b3fd6d91ab832163eaa0077989f647e85e7e", + "b7857ef62c56d8bce62476cdb2ab965eddff24d932e20fc992bd820598686defe6cc0a7232d2be342696c2990d80721a", + "b343d974dfda3f6589043acd25d53aecf7c34b1e980ae135a55cda554ff55e531bc7c2dfe89b0d2c30e523c7b065dad1", + "8d139e16a73cd892b75f3f4e445a10d55d1118f8eeafc75b259d098338419e72e950df6ca49cb45677a3c4e16fb19cdc", + "817b8535bd759da392b2c5760c51b3952ecf663662a137c997f595c533cd561ed7e655673c11144242160e41d1f2dd71", + "817ee0f0819b0ccb794df17982d5b4332abff5fec5e23b69579db2767855642156d9b9acccf6ceab43332ccc8d2744dc", + "9835d2b652aec9b0eba0c8e3b6169567e257a6a3f274ec705dbc250ee63f0f8e4b342e47b9e0c280c778208483d47af8", + "b78c40177f54f0e6d03083a4f50d8e56b5aafdb90f1b047bb504777d6e27be5a58170330aee12fbaa5f1e9d4f944acfc", + "ab8eebacf3806fac7ab951f6a9f3695545e2e3b839ca399a4ef360a73e77f089bb53d3d31dbd84ddfde55e5f013626e0", + "96c411fc6aecca39d07d2aff44d94b40814d8cfc4ee5a192fd23b54589b2801694d820a0dd217e44863ccff31dda891b", + "8249c424a0caf87d4f7ff255950bbc64064d4d1b093324bfe99583e8457c1f50e6996e3517bf281aa9b252c2a7c5a83a", + "acf6ed86121821a3dd63f3875b185c5ebe024bdb37878c8a8d558943d36db0616545a60db90789c0925295f45d021225", + "a37f155621a789f774dd13e57016b8e91b3a2512b5c75377ec8871b22a66db99655d101f57acaecd93115297caabfc21", + "92e60ee245bd4d349f1c656e034b1a7f0c6415a39ac4c54d383112734305488b3b90b0145024255735e0a32f38dba656", + "acec614e562ccfc93366309cfdc78c7d7ee0a23e3a7782a4fc4807b8803e6ebfb894a489d03e9a3c817ff2ec14813eba", + "b912f9dd26ed552cb14b007b893e6ed2494d12517e5761dbeb88521270144f8c3eb9571a0ad444b30a8a65e80bd95996", + "8375408dae79c547a29e9a9e5d4ec8241b36b82e45e4ca3b0c36d2227c02d17bb171528d3778eac3bbdc75d6c4e8a367", + "8c2d0e6e4406836da112edbbb63996408bb3cda4a2712fd245e4bb29a0100fdc89a2746d859b84a94565bc1cfa681813", + "a7431bf59e111c072d28c97626cd54fcdf018421d053a787d2aef454b91251ee8ff9d3702d06b088f92b9ad2bbebff15", + "8f3659b0fbeb90b7f30b7a49233325e806551a32911a654dca86e290b314483bbb33fe6482387bc48c35d85c1dd0441c", + "8dca5ba23f0bb76f7dacabf12886053552ba829a72827b472a2f01e19a893155cdce65f1fb670000f43e8c75ba015a31", + "8c1514c083c77624eeb5d995d60994a2866192e15c4474d0be4189fae0e9dbd62494ebb4c02fbc176b53be548abbc5a1", + "80498d2ed153381baf3b0f81da839ed0eea6af5796c422b8e59be805dba48c4395bb97824ac308170bb4f14f319c5ddf", + "84f5ebc3bf96362457993e9fa31493c31c4283075e2403f63d581b6b0db8a3df294b2085643f2007f4de38cb5d627776", + "958e6e38774da518193a98397978dbc73d1c3827b4996ec00b4183da2c305a187a0ada9aa306242814b229a395be83c9", + "ab8b8fbf73845615e7fab3e09e96cc181159eab09f36b4c1239b3c03313c9aeb4bbb51e16316fe338b2319ed2571b810", + "977e4e33b33bd53394e591eba4f9a183e13704c61e467d74b28f4ad0b69aa51501a5221cb1e0e42bcb548ca518caa619", + "a9bb7ecb9846cc30d04aad56d253c3df7004cebb272f6adf7b40a84adef9f57291e0d08d64c961b9fc406cdb198aab9b", + "8d2b72dc36406a545a9da44e1fddfb953d4894710ca026d6421a4ac91e02d0373a599f2acfe41d8258bc9679cf6f43d3", + "904192fc8fe250f61ecb8a36abbbccae85f592bbf00c10039c30b5a1c733d752a04e4fd8a1000c6578616f8a16aa83a3", + "87f5fdfe20bbbf931b529ec9be77bbfcc398cad9d932d29f62c846e08a91d2f47ae56ad5345122d62a56f629f9a76c4d", + "84cc3a53b2e7b7e03015f796b6cb7c32d6ded95c5b49c233ac27fafa792994b43c93cda6e618b66fce381f3db69838ba", + "aab58da10d7bbe091788988d43d66a335644f3d0897bbc98df27dcc0c0fcee0ac72e24f1abdd77e25196a1d0d0728e98", + "a10ea8677c2b7da563d84aa91a314a54cab27bb417c257826ebdd3b045d2a0f12729fe630bbbf785d04874f99f26bee8", + "acc4970ef2a4435937a9b8a5a5a311226ca188d8f26af1adfcd6efb2376a59155b9a9ff1cff591bde4b684887d5da6e5", + "8dc7cf6fcca483c44eb55e7fb924bf3f76cf79b411ae4b01c6c968910877ac9c166b71350f4d935f19bdffb056477961", + "ac2dd1182ded2054c2f4dbf27b71a0b517fb57193733a4e4e56aca8a069cff5078ffd3fd033683d076c1c639a4de63c7", + "932ec87c450cd0dc678daf8c63cd1bf46124fa472934e517fbbfb78199f288ff7f354b36e0cc6c8739d3f496cfe0913b", + "b0d631ced213e8492be60ea334dbe3b7799b86d85d5e8e70d02beef3ae87b1d76e1df3bdb5f7ba8a41904c96f6a64455", + "929d7239ead7575867e26b536b8badf2e11ca37840034d0e5c77039f8cce122eff5a1bf6e0bcadde6b3858e9f483d475", + "aaae5d372d02ee25b14de585af6fbc48f2c7cd2a6af4f08352951b45aa469599eff41e820df642ca1a0f881120e89dbe", + "b23c411741a6b059f04fa4f5fd9dd10e2a64915f2de6ea31e39c32f2f347a776a953320e5f7613fcb1167efe502f5c5c", + "a4581b0ae633fe29c6f09928e5efb16db019eeac57f79fef2fa1d3c9bee42ce0e852bc60b9d0133265373747e52a67a4", + "81b33afffd7b2575d4a9a1c5dd6eee675c084f82e06b9b3a52a3c9f76e087f12dca6e0ffddc42fb81ce1adb559d47a38", + "89cc890f06b424591556aabdfdbb36d7a23700425e90c9cfed7d3da226b4debe414ac5bdf175273828ce6c5355712514", + "a4399438be75cfae2bf825496704da5ed9001bed8538d8ac346c8cf0d4407808e9ee67573eb95fe1c6872ac21f639aaa", + "ad537f7ce74a1ca9a46fc06f15c1c8a6c32363bd6ac78a3c579ed8f84252e38a914cac16709fe65360e822ef47896de4", + "8e53b69f5e3e86b86299452e20ea8068b49565d0d0ab5d50ce00158a18403ae44e1b078a3cfd3f919aa81eb049a30c6e", + "a59f2542c67a430fd3526215c60c02353ee18af2ff87cb6231a2564fe59b8efec421f18d8b8cc7f084675ecf57b3fd05", + "b8d9bac93ef56cb4026dd1c731d92260a608fd55b8321e39166678e1dab834d0efddb717685da87786caeb1aaf258089", + "aa2df56f4c6fe9e0f899116c37302675f796a1608338700f05a13e779eb7cf278e01947864a8c2c74cc9d9a763804446", + "b0108ff2e327dcb6982961232bf7a9a0356d4297902f4b38d380ff1b954bfbcae0093df0f133dd9e84d5966c7b1aada7", + "b06b813b01fe7f8cf05b79dc95006f0c01d73101583d456278d71cd78638df2b1115897072b20947943fa263ddab0cd6", + "aa41e6c4d50da8abf0ea3c3901412fe9c9dff885383e2c0c0c50ed2f770ada888a27ea08bbb5342b5ff402e7b1230f12", + "a48635dbb7debac10cb93d422c2910e5358ba0c584b73f9845028af4a763fd20da8f928b54b27782b27ca47e631ebf38", + "80a574c208e994799e4fa9ef895163f33153bc6487491d817c4049e376054c641c4717bda8efbeb09152fa421a7268a7", + "b592bfd78ae228afc219c186589b9b0b5c571e314976d1ed5c1642db9159d577679a73c049cfc3dcfefcd5a4f174eeea", + "aa1f08af3918c61eadf567a5b1a3cdcdfb1b925f23f1f9e3c47889762f4d979d64686ce1ce990055ef8c1030d98daa3b", + "857df4cfd56d41c6d0c7fcc1c657e83c888253bae58d33b86e0803a37461be5a57140a77fb4b61108d1d8565091ada1c", + "8fae66a72361df509d253012a94160d84d0b2260822c788927d32fd3c89500500908c8f850ef70df68ddaeb077fd0820", + "aa1dbefc9aef1e7b896ff7303837053c63cfb5c8a3d8204680d3228ac16c23636748fe59286468c99699ae668e769a0c", + "b64b1cb2ba28665ed10bad1dddc42f3f97383c39bad463c6615b527302e2aaf93eb6062946d2150bd41c329697d101be", + "b6d35e3b524186e9065cee73ea17c082feff1811b5ab5519dd7991cdff2f397e3a79655969755309bd08c7d5a66f5d78", + "a4dae7f584270743bbba8bb633bdb8bc4dcc43580e53d3e9e509ff6c327e384f14104b5bdfe5c662dc6568806950da37", + "aae84d3d9ad4e237b07c199813a42ed2af3bf641339c342d9abf7ebec29b5bd06249c4488ce5c9277d87f7b71b3ddd37", + "b82a463cf643821618a058bddf9f2acb34ac86a8de42a0fa18c9626e51c20351d27a9575398a31227e21e291b0da183e", + "8b6c921e8707aded3ea693f490322971b1a7f64786ef071bc9826c73a06bd8ae6bf21bc980425769627b529d30b253ce", + "80724937b27fc50f033c11c50835c632369f0905f413b1713a2b0a2274bec5d7a30438e94193d479ba6679dbe09a65ef", + "a1d9b259a2ca9cff8af6678b3af0a290c2f51e9cf26d5fe3c6a4fa3d28cbf33cb709b7f78b4f61cb9419427983c61925", + "96a3e69a5ed7a98ce59c4481f2ffb75be9542122ad0eb4952c84d4536760df217854d4ec561ce2f4a79d3793c22fa4f4", + "990c4d9a4a22d63a8976d34833cafc35936b165f04aed3504e9b435f0de1be4c83b097bbaa062483cf3dee3833b4f5b6", + "b9bf5e4b270aec4a0dc219457b5fed984b548892c4b700482525ba1a7df19284464f841dab94abfabcaa9a7b7a757484", + "acaecf49cb4786d17cf867d7a93bd4ffee0781766e11b5c1b29089ae0024c859d11b45828fbff5330b888543264d74a9", + "b0e1a0865b1e6f9e4a0e31d0c885526ac06678acc526fda5124742a2c303bd0e8871a0cb7951ec8ed9540fc247c8d844", + "82b3d327b3d1a631758451e12870816956cd0cef91fcf313a90dd533d5291193a0ff3cc447054564ce68c9b027a7ffd7", + "a2843602abb98f0f83e000f3415039788da1e9a096bfe8fed6b99bab96df948c814560424ffebe755cb72f40436fb590", + "ab1c7b43cf838798d1e314bc26e04fc021e99a7bfbfc8ffde62fa8d7f92139de86a377289d5177021154229de01ede15", + "95e5cf5dd87ae3aed41b03c6c55f9dfad38dc126b17e7e587c156f7745c8da0bd1d60acb718fc1a03b61344f01e3de4d", + "86f021a3762bb47167f80d4ef1b1c873a91fe83409f9704f192efeebbc3ece0729cd2f92f63419907ea38ae47bc907d2", + "aaa1445dafbbcd645d4332d9806225e9346ee5ac6b22ad45e8922134fe12f3d433f567a6a4c19efdd9d5775a7de1e92f", + "8fd7e15688eef75df7b8bca3d61bc9fca4f56e047cdb6d0b864e7d1c4966eac27d6094b0c8482b49739f83ec51050198", + "80aab8b4d394eb011d4ec6a4c2815617308c9b847c6fa6a3d7e6af1c79420ef6ff2a13934a398581c40ee4cf1cac02ac", + "8970b97ac076a1d8a321ce00eada0edf974a46bf3cc26f6854e4218cdfc8d2b0c32199d9658f254b4fbae5a2c5535f41", + "a1aa2ec5b03df0a630e73dd048680ed6d3032c324941423f45cd1f16038789e5e75b876a13948732e9079a422f66a9fc", + "b5fe5f5e2f2ae2beeb8e95859a02fc45f01f9fb0ebb2bd8ec9ec976b3e806228821a9775096d341d662bc536c4d89452", + "a2bc1f170b62d0d5788b02391337b2ab157c38e725694e80aeead7383e05599be0e2f0fa27ef05db007061809356e147", + "a8a69701d4a8d0d972390e9f831fd8e9f424b2c2ef069e56bd763e9e835b3ce5f7cf5de5e5c297c06ace4aa74df1067c", + "b43d551af4ff3873557efe3f3fb98e5ede9008492f181f4796dd1a6bcda8b9445c155e8146966baa812afae1abe06b48", + "b4b1dae44fd596813f30602ab20e9b1fb20cb1bd650daacc97b7e054e5c0178b8131d439a9e5b142ca483cc012a362b3", + "b95b8a94c30a831eaaebea98c65cc5d0228c78afd6603d4aa426d8186aecc951f1a11c33951f51df04c7e6fa43ffb5ae", + "b100059624cf9db371bec80013a57a8f296d006c139a8766308f1ea821c7eccc26cad65bc640ab3f6cef9062653bf17d", + "8e5a2cb76716e0000d13bce5ef87acac307362a6096f090f5f64e5c5c71a10fddfdee8435e7166ba8c3ad8c3f540f3e4", + "93d2c43e21588c1e83c4255c52604b4ac3f40e656352d1827e95dd5222a45aebff9674e34fbbe7ed21eca77bd9b8dcbc", + "8aeaed611546bb9073b07512a9a1f38a7f436ab45e11775a0f9754baaf63e9bcc7bb59b47546a5ded5e4ba2f698e3b5f", + "af9e6792e74a1163fe27612f999a2f3cfa9048914c5bef69e3b2a75162bb0ce6ece81af699ad7f0c5278a8df0ba000d2", + "850bf2d5d34791c371a36404036ad6fdcd8fb62d1bb17a57e88bda7a78ea322397ce24d1abf4d0c89b9cf0b4cc42feb3", + "87f7e2a1625e2b7861b11d593aaac933ed08a7c768aebd00a45d893ed295bbb6ed865037b152bb574d70be006ddc1791", + "8dcce8f4ad163b29a2348ea15431c2c6ea1189ece88d2790e9f46b9125bd790b22503ec391bc2dee8f35419863b2c50c", + "b4bf5266c37f12421dd684b29517982d5e4b65dfdfba5fc7bd7479fd854aabf250627498f1e1188a51c0a88d848ec951", + "8651623c690247f747af8fdffdc3e5f73d0662bc3279fa2423a3c654af9b6433b9e5e0155f1ce53857e67388e7e3401d", + "b155120f196d52760129dde2e2b1990039b99484cdc948fa98095cd23da87679850f522e5955eae34ac267d2144160d3", + "aec8115e8d7b6601fbceeccf92e35845a06706d46acd188452c9f7d49abef14c6b3a9a9369a8bab2fd4eb9288e2aaca5", + "998a8ca4dc0f145f67a8c456f1d6a7323c4836fe036dcbb0f27eb1c596d121eb97369638a9908cfaf218c7706f266245", + "b235fbafac62802742ee3d26b1f4e887f7d2da4d711ba7f9bb6ca024de7beec1de66bb830ce96d69538f7dcb93c51b26", + "9258d2ddc21ab4e3edcde7eb7f6a382a29f1b626003cc6fdd8858be90f4ad13240072d8a8d44ef8de51ca4f477fa6c45", + "99d038487821c948142c678acd8c792960993dd8cb5e02cb229153a1ee9f88249f4ad9007f08e5d82e2a71fb96bb5f32", + "a88ee9dbc73d3d8e0f447b76fdb3a27936bde479a58d5799176885583dc93830ac58bca9087075950ea75100cf51af23", + "88b9b15816e5a0387153c1f4b90f613beb3ea4596037da01a81fdd2bcbd0baf5598db99f77e7694e5a0d35e822758108", + "907ae4b637d06b15846ee27d08c9c9af42df261c5bdd10cf5bc71f8e5ca34b33ac2405307023c50bdb8dc7b98a2cd5fe", + "9393d6900e1d2d1a1e42412fefd99578d9ac1d855c90a3e7930a739085496448609d674ca9b34016ad91f22d1cac538e", + "a28ac56b216730b7dcdb5ab3fc22d424c21a677db99a9897a89ed253ea83acfd9d83125133f5be6d9cd92298df110af8", + "b027590ee8766f1e352f831fda732adbaf77152485223ad5489ef3b0ce2d2e9f98d547c111fe133847ebb738987fb928", + "a9cc08fbd5c3fee8f77cf6eb996a5cafa195df5134dab000e4d0312f970a5577942ee89794e618074f49841f1f933a42", + "a8b3535c3df0b1a409d3fc740527ee7dd5ac21756115cde6f87f98cc7623f50cfcf16790689cab113ee7c35a5bd4879f", + "b61420227b97e5603ae8a716c6759b619f02b8fdc48acbf854352aa6519dad74b97bacc1723ca564cbf3ca48539ed773", + "853762498de80eebf955a6c8ddd259af463e4e25f0b6ba7b6a27b19bdbf4c585de55760a16e2d9345cdba6b2a02610f3", + "a711c1b13fc6c30745203c5d06390e6c82bd7c50f61734aa8d99c626faba30119bc910be63ec916c91ba53f8483c05a8", + "b488c0a793f4481f46b5875d96eecd73e46209a91677769f0890c5e002ecd7d4b1c9f4ba68c47fbed40e3857b1d8717a", + "a651c5e812ae65b1c66d92c607e80be330737ea49c1dcfe019c0ecea0f41a320406935bb09206a4abff0d1c24599b9ad", + "85e34e7d96e4b97db98a43247b6c244383b11ca10bf4777364acf509a6faa618bc973e2136a4693fbc8ab597e308fd5a", + "99837214102b394fffa7f3883759554c6bb7a070f5c809303595a44195e02b9a169460dc6bbffb62bdc0e7ced5f0a5c1", + "a952f89c0afb4bdae8c62b89cc3cfb60d0576ba4fe01a5d99534792f38d8848d919b3fc7577435d8443a044d2ee0bcfa", + "a1ac1f81acb29798acdfc493854663519e2d1b0e9d23d286ce33882c34b4c1c0bb43dd9638166d8026315a44d9ec92a8", + "ac9c58aa38219ae659d23007cc7b97fd25b7b610b2d81a8f9f94ddb089efc49c049a8ea4c56e6eaf7b6498f422a97b3c", + "87e61d501c242b484fb9a937ef21d485f6678d75257fc8fe831b528979068cadbe7e12b49c34058ec96d70a9d179ab14", + "aa45f6852f35cc8b65a4a8b5380641d2602a4fa4e3a035db9664df3ac2e170b1280c4a8b7b55161430063e54de4158a6", + "a46975614ddde6d134753c8d82c381966f87203d6e5a5fb99a93b0d43aa461466b37f07b8d0973a1abd6ee2b40f24348", + "8d35f97297773422351f4d99564c1359ef1a10cfb60aa0e6c8985a78f39b4268486312c8ebf9dd2ef50a771aa03158eb", + "8497c6242102d21e8b3ade9a9896c96308ab39171ab74cbd94e304c47598e2c2a7b0a0822492ac5c076ba91d4176481d", + "973f8fcb5f26915b3a3ef6fe58cc44bc7f4e115cd0ad9727d8d1b8113e126ae2e253a19922c5433be4ab2311a839c214", + "ae3ee9f1d765a9baf54b4617a289c3b24930aa8d57658a6b0b113bbf9b000c4a78499296c6f428bbb64755dfd4f795d2", + "a5be7a8e522ef3dcf9d2951220faf22bb865d050f4af2880b8483222ff7aad7c0866219fcc573df9d829c6efbb517f98", + "a5f3c7fabd7853a57695c5ad6d5b99167d08b5414e35ed1068ae386e0cb1ee2afbbe4d2b9024379b6fc3b10c39024d36", + "978d5592d4798c9e6baceff095413589461267d6a5b56cd558ec85011342da16f4365d879b905168256f61d36d891b1f", + "b7b6eaffa095ecbd76d6e1e88ceebabaf674d9ef7e331e875c6d9b9faa1762c800ff1ea597c214c28080f67a50a96c1e", + "8a1ab53ae5ceaa42e06e58dd8faf6c215fc09ba111ca9eeb800612334d30d5971448be90fec62ed194328aadd8c8eecc", + "a9ca532cac8ace9a9e845382f8a7840bf40cb426f2fcad8a2f40aadbb400b3a74021627cc9351b0966b841b30284962e", + "8dddeda8854c8e7ddc52676dd1d0fed1da610ed5415ddd7d25b835bd8420a6f83d7b67ec682270c9648b2e2186343591", + "888906aac64fd41d5c518a832d4e044fdc430cfe142fd431caf4676cafc58853ce576f098910d729011be0a9d50d67b5", + "96a3f886a2824e750b1e2ea5c587132f52a0c5e3ff192260d8783c666206bd8ebd539933816d7cdd97e4bc374e0b1edf", + "a150a29ffb2632cc7ec560983d9804cd6da3596c0c25956d27eb04776508eae809659fc883834269437871735de5f9ed", + "81f7ad4d2959d9d4009d1dfbc6fee38f930f163eb5eac11e98dc38bd2f7f224e3f5c767583f8e52d58d34f3417a6cf90", + "97ccac905ea7d9c6349132dd0397b6a2de9e57fd2d70f55e50860e019de15c20171a50b28a5c00ef90d43b838253b3d1", + "95694f00c21e8a205d6cbda09956b5b6ec9242ec8c799a91f515b07dcc7de3b6f573e2c0ba149f5a83700cda2d1df0f5", + "82bbc3c4a3b3997584903db30fffd182a266c7d1df3e913f908d5a53122fa12cf5acd11d915d85d5bd110fcc43cee736", + "8d3f24b4949aa1b4162c28dfbb9f813dd1d8b330f71325448dc45ea34d59b69ca95059402aae011e1b5aba6e536bc6ec", + "92c734c19752d24782331e74c9af97a8399ddfdd32954e91cda7363dba876aca4f730b451c50a8913950420682da8121", + "8653d2c79f77b8c7dcdf7e8dee42433998aeedf1b583abfca686d47a854de1b75e9a4351580c96d1a2a9532659203361", + "886f0e414cb558c1a534a1916d3531320a9b6024639712ffe18164ce6313993a553e2b9aafe9c0716318f81a5d0bb1da", + "b31b5efaba5a5020c3bcea0f54860e0688c2c3f27b9b0e44b45d745158f484e474d5d3b1a0044dd6753c7fb4bf8ace34", + "b2d615bbdfdc042d6f67a6170127392d99f0e77ae17b0e1be6786ff2f281795f1bf11f83f2e0f8723b5cdd1db1856e09", + "a6e014cca531e6ac2922239b5bee39d69d9ba6d0fa96a4b812217dd342657d35606f0b9c5a317efd423cdb1047815e3d", + "a8921736b69c9fbb29f443715174bac753e908251804620c542fad6cfbfda7bdfe287f2902f30b043a8a4b4818cfdeef", + "8d73a9949a042ec2dcefa476e454cd9877eee543b1a6b3b96a78ffcff87421e8b26dd54d5b3192ac32073cb36497acc3", + "b936a71ee8df0e48867f3790adf55dc8efc6585024128de2495f8873bd00fd9fa0984472125e801ed9c3cdce6698f160", + "82f69c06209c28f64874e850601dda56af44ffc864f42efa8f9c6a0758207bf0a00f583840982dec0a517ab899a98e5b", + "b7a0a14411101473406f30e82f14b13e6efc9699e7193c0be04bb43d1b49e8c54812ce0f9b39131a20379c4c39d3bbe3", + "81159c969f38107af3b858d7582b22925a7ccced02fae3698482d7e9cdc6c568e959651991c6cf16c53a997442054b61", + "8bf1116a206e0ce9199fcab6ed2b44a9e46e8143bff3ed3f1431f8d55508fe2728b8902670cfd8d9b316f575f288ed9d", + "a279b2149824b64144eb92f5a36b22036d34a52bd5a66e5da4b61fbc95af6eda8e485c7914f448abd8674fc14d268d9d", + "8b98279b5f3588d1a2f8589d2756458690a502728800f8d94b28e00df842a101c96ab9c5aee87c5bbe65552c0c383b80", + "b4a27a351ec54420f94e0a0a79d7c7a7337940399646631baca93eeab5fd429d7fb39428be77dcbce64a13eaa3c8ca1d", + "90c08baa29ec8338ffce381eae3d23ce3f6ba54e5242dec21dc3caaed69cac13f2ab5e8d9d719bc95720fa182eee399c", + "85156d65bb4fef69ffd539ab918b3286105ca6f1c36a74351ab3310b339727483433e8f8784791f47b4ba35ca933c379", + "923005013c27209d07c06a6b92b0cbb248a69c5e15c600bbcc643e8dcd2402adebd94dd4cafb44ec422a127e9780aaec", + "863b23eb5463a6ef5a12039edc2f8e18e3c97b244841bc50af02459b1bcc558367edf2f6e4fe69f45f37887469dd536d", + "87a4a7708a112724ff9b69ebb25d623b5cae362ae0946daed2ec80e917800dbfcd69f999c253542533242e7b9a5cc959", + "8bf4347ceea7f94b53564f26b1a4749a16f13bf71a9e03a546f906f7c423089820ff217066159b0637d9d6824e9c101c", + "ab07eef925d264145971628a39e4dd93ff849767f68ed06065802cf22756fc6bf384cf6d9ab174bfc1a87bcc37b037aa", + "8e3f10a42fad43887d522dc76b1480063267991c2457c39f1e790e0c16c03e38a4c8e79a0b7622892464957bf517ebd8", + "a8722fc7b1acf0be18f6ddf3ee97a5a9b02a98da5bc1126a8b7bf10d18ee415be9a85668eb604ef5a1f48659bc447eb5", + "878d6b2a9c0aca8e2bc2a5eb7dd8d842aa839bbd7754860c396a641d5794eab88a55f8448de7dbddf9e201cbc54fe481", + "ada881c167d39d368c1e9b283cf50491c6bfc66072815608ba23ab468cfbd31ca1bd7f140e158e0d9e4d7ebfa670bc2d", + "a2b48578fa899d77a7ee1b9cb1e228b40c20b303b3d403fd6612649c81e7db5a7313ba9702adc89627b5fd7439f8b754", + "8e051280e10551558dcb5522120ac9216281c29071c0371aaa9bde52961fe26b21d78de3f98cb8cd63e65cff86d1b25c", + "a7c5022047930c958e499e8051056c5244ae03beb60d4ba9fe666ab77a913a067324dfb6debcb4da4694645145716c9d", + "95cff6ec03e38c5ab0f6f8dccde252d91856093d8429b7494efc7772996e7985d2d6965307c7fdfa484559c129cca9f9", + "993eb550d5e8661791f63e2fa259ab1f78a0e3edad467eb419b076a70923fede2e00ddc48a961d20001aaae89fad11e8", + "abb2826e4d4b381d64787a09934b9c4fe1d5f5742f90858228e484f3c546e16ee8a2a0b0a952d834a93154a8b18f3d16", + "a922ca9f2061996e65ef38a7c5c7755e59d8d5ce27d577abcdd8165b23b4877398d735f9cb470a771335fc7d99ecb7fc", + "90f22862216f6bc1bbf5437740a47605d1ff5147b1f06f7b13fec446e4c5a4a4a84792cb244a1905f3478a36f8d7065b", + "87f3d9a86afef5b79ea1ca690ee1ee4bb9754b66f7c50a42ad6b99af7c222c853ca161f440a0a2a60b3b5a54e3493240", + "80a9ca9a2d33b9cf61976b3860d79f5d00de89a06ef043d2a52931809018aeb4ce70423cbef375b29c2c750c2c8704c2", + "b4e798ef1d615896108dae37ac50c1e859216ab6dbac11653e44d06ce5209057b4b0dd6d31dcfcda87664a23c8ef1cbd", + "aaed6d1e7c5b1db06f80dae6c24857daadfb0268f20e48a98fba4b76de1ebf65fb84c3be95fd6a418b498f8285ec63bd", + "aeceaa316c6369492c939f94809bc80e0857abac86c0d85be8066bbf61afbaaec67e28c572437a8d35c49dd596b3134f", + "b791c3d53ed34a7d1c8aa89b7953e3684c3cd529230824dc529739a5fbe74b58b87f01e56e7a169f61c508237ef67160", + "9351f8c80634386c45c0050d2f813193f9d839173be941e2092d729be5403632a2f18dffdc323d69eb0dc31fa31c5866", + "97693184d5c0056ae244dfb6709cafa23a795dc22d497a307a7f9cf442d7452024023c54a8d6bda5d90a355ba2c84f3a", + "85362daa003d23511ca174a8caafe83d52b6436dc4e43c4c049e5388d9211b5cbef3885896914d86d39be0dd1f910511", + "a2511b5fa34b24eeb0e1bcbcf872a569d1ff5570fe7b0fb48f5542f7fe57bad808d34b50afa87580866a6cb0eba02f27", + "b382e3327eb1401f2d378dbb56ac7250adde0961bd718575a64d264ffd44772c20752d4035c3ba60eb435e160b375e20", + "afad8a5d40b536c0720556845a6b257ed42165c14fb4b4a874717d107752f49ed9380c5b048df3aca67287bb8fc411a8", + "8fad0c98434ca5373c2d767868f679b76b4a8d04bca8240ea3f388558262c2d61b73b16fc1160932652b5688c25fffcf", + "83898008b5cbb6f08f8ef3ec179427869682bb4e8d38f6e6a687a214d4a307436afc64ee67d70a5a8ba9730bf839aecc", + "b85232e79913785fd82b06890706972b4ad7a309489930ae23390d51aa5189731f8a2df24800409a8c36b3dd6fc91275", + "a24ff26ec792f3701da4c5638c1fca4fa4dae95b01827d6200d583c4caf17ea3171393ba2a8c23d1ee8b88402916f176", + "adc5c7a7ff6b41d6cc386b7fc69d7bb04179bdf267864f9aa577f0f6a88438191fa81ebaf13055c2f2d7290be6421ace", + "a05e835abd502d31454d40a019010ff90b6b0b1f993075a35c9907aeab7a342ac0ba6144dc9379aada6119157970e9b2", + "85ff07ba58463e7f153fc83f11302e9061e648a5cbd272bb0545030b20e11facd8b3ff90c9ac8c280a704fbda5c9d1b0", + "a6c735ada8f4587da8cdad7ea3ada01650b5a3ecab8d81daa7a5f5de51ef4a6592b524692584306f06be3f6701f2870c", + "b138deee4e53ae8d677fae104f713ef1b8babfecec16b6a85785a66a72784eb09d44c3b63567222ade714e98f7d1604e", + "ae79c1a49dafcdd972acd95d8ad0a35c02adc7fd736d4c44c3cd13df5789d339b5ea16bddbbd43e486a061ab31baa5c0", + "ab3cf2371a1d7dcd0ffe3869a0178230964b06694bf258b2073ea66a2afccd845b38485da83d02e1d607d4c5c36b78a8", + "ab9609f28a325fd01cb39540e3a714506c44e52ef28ee640f361deb5760aadbb23e804663b0fa20a66e239c33f8d8bb8", + "8ed95ea8e76e1b42823d7915a6aae77d93746f846bf602841dfce0e47543a36efb9ee7e5b42c73c3209d911225cc471b", + "a80b6162036d43811482323f0ce59eb18740e33a63d7c7bbbf3be206985919e5342d53a69df537d43e8b7d7f51e8892f", + "93c03d0a5083408ba00c125a8a9385213d4c860072f0297857b1235045819b904e07f2425c13a661d0a01d2e53347f4b", + "a6581200f00f96c461621e1d26b14a23687dd97eb9f7df4ba641a84340ee7306dc1796248fba4804f185947ad13b4385", + "8be174018fa40f7e0cedc5ae68f38969eb7695f2205e9c573641e533d56f68c20abf38a23d2f0dcac371e60b21b18615", + "857ad4ee3218c647c58f09b8ab22bcc8976f00a768ab1f708618e868e6143474be846422ce2710a0ed39b5155b6f13a1", + "a490bec40f322d599f26bcefcdddd8f2ef6576aa737d5ce7e8d5d422741abe749e3e6a48489aed8c560633f72857e3c2", + "a9c0ee339621f1c4a2410f9b4d2f03f1b558dae2973807b8bccd920e8feb7f65dfde3e79986b72ad21fcc4567240381d", + "8592251568e750a430f7d2c6ddbb3ec82a4dd9fd83efe389e69aa177fd97ac2c96c59a6e86db20d8e6f125d65b46c4d3", + "a4e2f4aa6a682913b423b097c4069c4e46a1f3af9556b1bfd0580d0fc01e3991488458049e0735b2a629684a79271c8f", + "8c4f6a3e738cf74112b08b1680be08158013ef8a515a81215d8a36c9b756786d1b4cb4563923463f3329292f4b48bf6d", + "8bace547353c02ea00dd547eeda7259aa354d4772dd5e0c486c723cf88627b7112e196b879c3c92a9561b674d9fc486d", + "8d372f4901e25e8db64fa098148d4a4e709b0e9dcb756d0f90dad99dea393054193ae1a33d292a3dd772ff7ba05e4b71", + "a8c7ea6a6a031ed23d65639f01f5423190775558f479700597df7ae7e338a6ae5e9b32f470aff20787ac8b7eec84df6c", + "b6e9dcba240fdbbf66033410a79a2dd3e9e1ffdf2eae949b3a9ed720e939d92339991dc3e70a5ac7d5253f317daf0b7d", + "974dec4cd61af75721071752c664d9c2a5121f06ff1515c56139a177a3ca825f763b69d431d4607e393fa74dcc91cc58", + "958863e6ad583a9d370a6db3639066982e44766904e7afa849b132f6666b7d08ab931131b3bec7a506d6583e93d56767", + "8b93a33b5da9b3300c20a96d80b894e3789c77041183c2cb21751579c8c96857f60cfc2f075201b64e95a78985c5b321", + "b726cb9f7ef34ddbc2fad82b3b0af0b30cc913e26c5a614ae5c19cc9c55c8e6dae069db5315a8dcb6d987415bb550ca8", + "a730f515398a71bddd66cab2ff996659d4e47dfbb08ce7958a41021f76d269b91c7498b708cd14b183a8ef469c772803", + "a4eb3b18132eb0f5337f14e01d63ca0bec0db6a43870f800e5491db756c2f5fce519d8dba5528b4bcef550d06b33699c", + "b1ab6621eec1ee6784e632e214693f39a14f3715991996b883d66200963e065c86fa0667f7bc36b93b40b5d90ff708c2", + "80486a26c3532ad6e19f76d8c9344e2626c07363fd495264927cb5935fa9565ece670dc98767afb04af6a9a5c9231075", + "8ee20e0df3c84a1c6b0e21bcc325cf99235b747ffe47f17fdfba548a358ca75cbcc331dd50db2311b400ae882256a608", + "aef4268959e5541e7ec69c921a1e81a8374d7e44bf1bb2debf4101cf3cd6b7d6ca7f441758b388de96b3e0edb5b97be9", + "8793629bd29d689ec94b016de8886cac6e2ca6638911babb22db4a787661422da0639a4e4089ebeb689d173abfe75950", + "b487b3551c20a29e9a5abbda8c50ff594826283e443c09e3ae09b914e46060b3f9abf70434444ce1487e2a74e562616b", + "8f11531cfc5997dd04b997cb87ba1831aa7041d5434fe72de66304e3f165d882fac891391fbb1eb955c65319e65293b6", + "b195136875fd02a75676c33cb3e60504d5964f7a9e81f4c8c8fd38af62e2145c55f765b3158664566191188ac678f381", + "b374174b0b3eb04fa49eb4ece45173f0db5d829eac370a20a62309566e0f98b18f72f3633626893c053b7be6bfbd2366", + "b2a2f6b0cf652775679b2d677048f2ed8c31a3269e6cddcc7a10e3e6fee89e486b50d9d55fbe452b79c4157c0270fb77", + "892177c364dc59032594e7a6fd032286ffdf4fa0b9e3baeb37ec839faebfd2fd46c57b2c9bfe9977b59c93a9cc0ead1d", + "8ab7c0038a7dbb2ef200dbbe9acbc875829ecad4883792d5c6ce283de67ccd9aa935a9cc7b30b2bd9de7fca7bf2a9a05", + "83745cfc78ca709835aa6c6a233c2b86fb31e3f9f6a8becf63e501f2841c4366fb7d131b746c9d3291afda714ff05579", + "a723dcb67925ef007e8339dc578d2622d9bb77cfda87cca0088854a59414c02338752c56116a6c1281917842e8467c38", + "8a098142da0af2254c425fdbbd0d1b1a17b2bd781391ab37f181775524b8563c64ab8a1602aee2ac6c0a82ba11a8b1d1", + "b13bd7529a9b351c5d395c794c28bcb0a3167f1c992e8c062eef47be9be27895945231d249c73a0b6949daa295e14944", + "a20dcd2fc2222eaae467d9f5db861040f58bcb991a26e5663ac3aa5e1ff13d0010657c5af586cc4621757add2b905073", + "b818f660c3cc4e9f273c25ceeabe562c8afa8ff88529c26f2cf45ae6b2813cca5f350e3cbd56f6257c4df41722dabd25", + "b225d5987108b24411bc389276f12509a45e86d5ad6b6d929af5274df0be11109c0fed329669a0acafdf3b0beaa8f2ec", + "91fcb6d04576d3c6bae947bb7843b430e5fb0592ae49b0a65dfa5791f4eaa4bf2c7f436c8de7360f217001c2b4e5c67a", + "8821f7a1424ca3fdc5d4a5606ad10dfaba6094cf36669fa9f84cf7617e50425405d14980780e1e18a1ecea7913cda896", + "990dcb7f38f56521a70cb71bf4522649fcd46ac052c7feabb0748dfcac9f9c0f95d29e070d32af3cd0adbf869535e17b", + "b0fac1029fe2c1100f24e2f4bf10c7672199fce53513c7dde2e8d9b00702edf0143e0e1dc7ceae7dcc6994edc2422b6f", + "a514ebb1a33451b4915c05114db0b10168393613744df848b24e43e09f0bda23baefd9d731075198aace586615ac7911", + "8b77f7953c2e67049fdca3653b8d8cf3f799677f79b954da02bdad8cc4d6c855c1c7c16b4f6f9ba35f46426ec28b2d84", + "875520cfbda16ec5b1d1d00f578a910d0fc052f17870ba093e22e310bb07648d34817cc2b8811b6f52de535f7046a0d0", + "b8c77b4be0b430851c4ff69e91cb770db1935d848198601393810ef395efab52deb9d5c6525472bab720273d5e0e7a79", + "b6d4d437146671bdea62fb6545395ea3df39f1cdef21b8476b68e7a25aa7354f847740576d6c9f187bbae9941f0ae450", + "95c642f1bccdb62cd6a2212dcdd6ff8d49aee426ca08b7cf3a9d15249d24a9eed5533f92a70c84498c0797f8a57efa27", + "b617978047ed0f748c305aa7f30c2dacd0db00baa67fe0c5ce346ef0e6991dc7e05f18dcb2702467421f8390f27aa815", + "86411c7a00b3e8b43bf22fb061b1f54ad9bbf632cd74395a478218389c0f544668acf3dd7726532d080ca7da9a5f8608", + "97bf684a8849626c4710a6992f6c11f6b5406fd4dfe9e6aa502425aaafe9827e2c435aaf9a5d3d2ba3a4c0e8aec79ba4", + "8b178e2a125b461d3180906ffba0af3dce614c64058501fdd35243ababf892d6fcdea4834ce42c25d5569452b782a709", + "8ebed2c8a25c61da6a6a8cb0d8f5ea179e28869753eacc728f2c076f7aed8598cd3aa0981f120f9e7ea55b3a689ae882", + "a6f235b8e655ca3d634740b53d8c0a757ecc75d2b8838b7948997c1985473d01943d935f687b86cee56cd47c8e773443", + "a7959c465a9646908b9d8032a589e41a7dd999f2ffc54bb42f22e5f8a4d8c493a31bcc7ea2cac6c8dbcc59acace7181b", + "96d0532df2e12da20a57cadb6cf5f6c4ee1aa4775629358c25f1d51677a3e96d1fe3b232532324b4f02f941952d4cc68", + "90f493473d686b639a30d1ddc9c72eae6e983f1236e162e58e967a477c0654973ea2e1bdf4ba1a44d7247bc1befc2cab", + "8b2d87876d9c4085102a07ebb41c565ba69acab99ffc03efc18f20e48d3f3bbe4fc6ddab9c78fe479d9ada80504d85ba", + "829a0fb3200a28e09cacd6c5346000e7786116ddfd898f37dfd17bef454a8abc0fe939ed8735c00769f7f2f33cd4f906", + "86194ec9e88ddb7150e8b03e7a535b6e99863fc6762835601efd03615aa97aaeb413cb210e86035086ed852b39c9d019", + "b02efd116a7189cb317ceae392bc301ae55470f0489fa89934e182aeb8c67e280299b975786fe9a470bff46827defb9b", + "87d7c3903bd22b12d815506f150373f518d47dfc6e5fd74347d88b518124c9923d1e4c98defeb3a45d53d50b423e2175", + "a1a430406b28254a7d6348bc98e697e9bab43839aa05d53faee97546f84541ea0b559162619b2045182938f69bf61cae", + "99d243c226c61c6697fb3d2594f3533fa5dfd7cfc87107908cacde337d7a077fa5a9dc702d26081b065edb1227498e65", + "800ee5006ab6217161f42db0cfc552a81728bb4fbd7af6e4620ea099a65ef6664184af3f65a07fcec7e965529c5b49bf", + "91bfd307579cadc8f81009558605be3edbcb8dbba271475803484017f40130b2b216aef4f620d960193be681877d3a53", + "96a060459dec458d19a6f8af6e49dc6c7c58c55dd18915c5fce5e0f4b4a422fce3b9632f6059388fe760289abf70f173", + "9921a37f3e657222c7fda3588418a9071409711d9f1fccede7494429f02a45fbc52d79fbb64e9ccd518f60d06d0520d3", + "81052b0d15773cb75975ca9230ebb2579700e489c7e3f07cd9cde206fef38b8139bd4976d2b4a7840495fc645f96df03", + "88ac37ba66d1de5e23878c992e4d54023729e97e77351f50dc5918d738b5a73faf1dc6feec7e85784761836ba1c6f778", + "ae1e6072c13060775f6086d1ae1f88b627ffcb810fc0e0e97deea1f3a15ef0aaa52a6dce2563e4beedadc131af2a8281", + "8b60a340f5e4f90badf83001b495ac9f13974c3d2054ddcb3e6b8ca99dec5cd63a263e05c282454191ab2e087d5a2911", + "832e2d56ba69dbf817b2b9dbd25c1538d5b8dbf5d9bc05e6be85054a423ebb66a71b157e166e0b9444ac171b34b7ccc9", + "8586036fc7dde1e7e3ecb61663130c4529866ae9f5f5095b9fccd24a4c70eea899aae5f10ea1ba66d1665b2d83be35b0", + "a77969453b5c083a207913272b5b69d4ccbd8718bdf54be8fbe11b4bd0a2168aae3ba8f9362afa69c0ffa28d7e5a2340", + "b7fe9568c214baad0ac5f83745611b481f744ec1c4fa78a549b180dcf79633e5ba75dc20055012a13d849eb7a9be57d3", + "b01cad1d2a6c51c0ce88243d1f52f95fb5ee315a905079688027511f0c4ecd0563a3a81846709d272fa5ccb9665e8043", + "8eae0a21adfc569aa57237654021c2bdb2c6f0f52ccc90a126682c21a1f9413c63d285f92b2b2f8649150a9284bf70b7", + "942acc947192b5f3cf60e92383e5d35f79e7a5904e8e9fd1c8a351676c83ad29b0afb6578d555457cf909f8f4d27adfd", + "a74e092f8628fba9abcabc27e2e9f3d5a9a941dfe50a2dfde2ad179aabc73afd196676925c2d98643ab8b3d02bdb66ad", + "896159daa2afd757cf3f9d34af248ad68bb3c62e4c9ac49919422727479cf669098f270b9e645607a7d11adad4c889b2", + "a428d8370813d78e7a2a24eebd36e9da2f8bb3605e5a39b5fcda939b531c35a8ebaaa642ba556250a37bddeec90326fb", + "a5fa04eb60a1d5ee9820e78f42f7be15e1c02757b539aead995768c6209684d6c183c71d282e0c12a4c15c03f9a89d4d", + "93c77d5d220e40affa7269a6915c076c9aef4db552c643ae5d560a79c955b491c6346ca4cf11cbb7fe1894e28d47b065", + "802e605d2de745eef6981d88e7a57ef4046a2062725e8080995374cea2b3273c27f35b7774d0dcba014710d8d6c501f2", + "82f7169e6ec9b3e2bd450f35ea2e66d06bcf900acf5b73139677b48e078ce2e16599103027b2326770c99c0a690f2015", + "b0c8581879439f9b997551233fe2de71aa03604f9cec37a7b18c5854342d9b67be468f3cac4bf6f64fe8a0066248c498", + "a3f626848a4db6e9fb01cac90d3362ec521e969ebd5228af694ea3671061476149f13d652942ac1e39f65591fed740f9", + "88a8e759b9cbe16a7c16e43f4afa2de6100d2eafa4dee75ccd653ec38c919013d0a6b35c1ee1eaee7c1985b58bcc9e92", + "a3d5fc7aaea072798490616552d947e95f49cf02a420314307aafb555287ec607d75589ba24b009cd68299dc6f7942fa", + "a809cceeb84f9bcf3c3ddafde3041e7bc3b1d14df8830ab849002176a0725e6f16f70774d8962cb0b8ac0dc43c4ac66f", + "b8f2e46c031cc8fa160a08c2ebdfa85345ed14771b06daa9636b0e7792b7fddbc501dfc85cc626a01104a43a7d3230c3", + "b5367e2a521c318b802ce16ceac80c4b8139f73ddb10ddf38433397cda70a86ea1f051cc55626a4e99d27f30f3975ff5", + "96d963660121c1441cd13141279cd371a6a0aa18b6a20761b18df60aa9c14e13489afd83695a0921d5232efe72045f07", + "80818d492fd85d666bd91aaf6257b86527fdd796773c793407df1d4a0f91d74649a6bab4d15155c36ed4c6e0a32c5636", + "931e22918905fd6c230d3d867ea42861f3074d320d14e1929031924c8ac209a5c552b679b24563bb12f9749b4ee983bd", + "a4de2c333e74ed9bfa3c0bf6a0beb90427abd9aa4221294cda74331646b58ef46ed57cccc8798ba2b9309894b17cfd69", + "883881554c1d88c0ed8d3b6dec3d200f6fea69a77ace3e4d6f86b41506a23724b4394ec8384075f9c75c3868ba8a8e8e", + "aa0539ecf6ec9bf06f24443027f8f24b6b3d8c5b2084248eecd4bcad3c9a69716e1a0d01057f09a65bff1006ac5e157a", + "856d74d44c943c9e809b42dc493dff20eca03cb0cf5ed45108c69b1f90d8592a53ae8100e99380a274fafad23e74cdfc", + "9188257446661c88da093b7c5ce998135913f63842d7c1586065377b169ee35b062d925367fb9b909ca971f1188667b1", + "8d3aa57cdafbe998938787479f5d590c1484c6dbe94e6c487e57a746ef5252be0eaa5976d6270de7db64b6b92e57a0f7", + "b8f4d6997240f9eda5aca0c43323a828d1563c491b3db2087f60ac4120a3fcd06075fb42bb19d0339ab5ee3fb7db25d2", + "ad247ea94b8ae1e81eae4c9fd7b39e6601b53cff47b2547ff90a3cca87192eae28408082774a1fd14bf9ab459b7a4f1f", + "9598598070f8bdbcc49056c40971e673726cd8c1bc4baa0b5124dfb5fb750e7baa7a7df18eae2bd91955ddcb1ec67955", + "b874131ab1608667fa60ea29092d090859eed1812e90c609afff96d79e82c5ba546f617f4c96fc32c9bba97431c1e9af", + "b00750a9cdc75c2a54f0d3cc99b0fe02300754f25166f7ac85ff41ab5e9cfcca33a29be76a480f12a2d410c7cd5032e5", + "84b5bd1c90bb6c66755b28ba4af493ca1b0c3a4df9f436aac67d2e07289053f925cf6a149a84e74e1027dc8758150179", + "99caf64bd9d193ff306e8ab5da3f1bb2a190a60c3a82099b8d03d17fa810dc53d176c21379f479e828f60d25beb3ffd0", + "a8fd9de502f1c261d5733430e5a18d8b7892a98c9529a016fc2ee53892ae965dcd9c75850bcda4c7edb980b8d88e60ea", + "848c02cac636e047028a3fe8c1bf4066fb7591b96b0340f8fbd476ff01b35fa3e37d309333771a134f24800e5f3f9289", + "a1eab1a06dcca3439f0166441e7e7f2f5b56f5f8aa9f45e411c561f556e0fb71c514c06c26ac53b49a576caca5faac3d", + "aa603f970dcbe953e700e61c151182c8d32cbbb53ceef572ac93383db33a4b098b5c7b267e42d514ca66b740c0925efe", + "b55fd5301bd700ddb0b4f72fabe9a91ad49759506101fa802ed1677e9553595aa4d2c66f7574e78d21ce882ce0120ae7", + "829137bc4da7b4886d3d04d2c39cbf4b1dc40c813ac1adb425c7b9abf9142b516314cab79c68454df5d71994ce416144", + "b83a3a22735001f783dd48a01c4fb3598a51ff3987e842b8045c71c035b9e43645a55254ca5911a5676ef4a8af12d056", + "8ca8d463deb13f9eef5e533bc39efaeb0c15631282c5c0deee1673b0053a7cccd514af09801dd6c158caa159fe9351ac", + "a9ffb1427828f3c456b9c8cc50782de1ab0029b9233a0fd998bad0fd014d27e15c4a32d1e16ad41bff748378b5abdf49", + "9627e29f725ddd86456aff813976bbc4a836f4deabf5ad9f73d1a260ceb30948824df9c8841e6b3c529652202be181b3", + "b52c988647fe3d9276eed3c262e1044f57fbb116c64cf4f207235c205b3fda0f3d789bf90f5217401b468d85fdfda404", + "833bbd6e2924f5c4446cb76b881d1434a5badce9eb9b003f85d076e297ad7ef45b822069fe54d17427a348c3263fb838", + "a067a36352db6f82a116cb87d3db5f60b18576852409e2076cbbfc7843af78866313a4969385a40271051dd195d51116", + "902b99545971f9a103f99d7399acc347ac46fe156166e51deefc0e92aebf5893460c69aeeae11f5af9f49418e289ce6c", + "9206a0e9ce9b9880f29ef0417c96931985f5d83bb17cebdbba4ff2af81a3d37155b04649426f698aed372e4f669599e6", + "b54a5d7c976e45c0b1d44433595eae9d1ae9aeabfd58cd5ecb0c5804756a7b01c9a517754423b4714a3695533a3114c8", + "91b612131e84580ece228b81ace83da0269b53f94d3c02a1a0879ebbd81bdc252064b3d03a7e140b43a90f237d9a45a0", + "a6cead3b8607eaeafe37135bd6de8fbd16f806c131eb71c8d36bfbe295d45b070255e50dabf076e2c3f6b8699be71d6a", + "931da21e67b11ba6ce438546a24d063bcd51aebe39b4220a78d9c0aab88b2d37969b5ef3502d835507f9c8d6d006714c", + "8fda408caa9daf01122a2308b7b9d328f52e1e2f138a8bec30492488f4d710e5e52524a6455a3a2ae2818ec8a610b650", + "ad8ad5c189644352d90c462731c46145410e5adf38682bb80f95495dd64d9d13782537d68690847bbb06c6be7175dbc7", + "87bb5cc466ade60feb0961421c3fabdc8a7e20f11df8437bfff63d3f8bd25305002a396c9d0fa4fb9a9986d4717f12c4", + "827cff72870ba00c29064a7d2b4973f322d6b6de7924c93d8bf8825e7a0e8478c7748f90f5c716bf83c55b2795d315d8", + "a225895a8e94229776ceb51b05356291f2dce748be17a60d5aeb33ef8507c368bafe5d1d6eea927f28b9d1422b661b9a", + "8e011323ce670ff51c964241a6b72e0e0ffbb3ff9bb2762492323fc3a4abf4718091be0945287c7329850e4f74462cde", + "a2c03c2e5f4e9d3ef361f68b188451994ad1b24de9f323370559c8abfcdc7bffd289d92e78a5f6b104b0a12c84dab2ef", + "a22b4771116ce22276fab1fec6826610707ce8a342f9f60b079c4e0259dac3cc41c96c560dfd0ada6edd2828f7c0e8d6", + "97c17441d0af9be83b42097aa8b7cec84a253b9a2b957214b8fa93c26d2add46144faffa7b8a55312059b10690f711f1", + "94bdf348849f31a2737cbae5e5848aee711067bac85c11c2e68b44c398cfafbf3493a3226cd1ddf7a916e7613fc7b6f6", + "838f59c6e8469a8ec6fd40b978a3607439aaebe1e50ff707eec72c0b8278af05b477bf12a384b56d03e3d4eb91e56f67", + "a1940f0db58185e2b3aedd2b0bc2b73b4a65c68e09b046f38e9dcd4e13c94f5406bea92635190bf315e48ec64eceef2f", + "b2f4e0ae44e1f1210a91d8f280f17091fa994034ba8c991583f8182a323e9b3001a712e3584fc2d64ecbf2d319d076b2", + "9342b89c721338d02c7854cd7466fb24d93d7313b6114ea591e6607439c8ddb911d1cf35f01898e9c557982bdff8f9b6", + "8583fcab15be1dd14d5a415f4b14d706c8c62f058500f1344b37730c8be6741779691f87ded3cbcf6516468b373cafb0", + "8fa9587c7989646571ad9032f34cedd353caee14f5be5cde1e9e0a1710f90c08faf6fa96a60e1f150f761c9c8ae7417d", + "8d9ff904cc08141f5a9879f5f77dc600e6edbe859082231a4d819953890199bcc5f940b730ea688332f07e5279d49e1c", + "b5f82b46e5ef9a2df8d144202d6e2e4f3bdae8e2048d2af5ea7deb3f722fbe6d370401954e74ff0d8cb1010ffb1f38d5", + "a3b5b57d435b06ed70530e060002a8fea71746ad07d969ca23f22b5e52624527595b6a6d54b4e953fb7b7596bac378f0", + "b90f89390df6d4b7879b915aa3c29b8d779d035033f8873bb7ac54a14ec98f0d08c0e3bf696e2ffa7b5730d736f571f8", + "8e81e371b92887e43d95c0dbdcc9575282b26ccebdc8cbf46587e4f2a83b61e9bc0c6d7d1f114b9d21e04fd6c180b12a", + "8d682947c51dffc6e0fe0a486293c9ed121f441805168236393087cf62f2a429cca60bf0e472564844347d32c6bea27e", + "a8341ec7dd189fa7168759240224192c58209b53fc961c18082deba217928c399bde08ceae42bffd37c1135b4d14a845", + "a94bb076dcc5ee5ec82fac57c5b384c690df12631882bd1b960e1eb8c04f787bc22b7bac315b9dc5a8a098f17f051a0b", + "ab64e1c6f01b87706c88a3bd974454a438722768de7340b834ccf93ea9880c14ee7c2181432acf51f980d56de73832ee", + "b7b0058bb724d879e5ad7aed6230297c54cb599ef659e86bf2cc84c38225899fb388391df9b2e6fdf063171937fd8c72", + "ae856f4fb74c27cc98b67429186e7df4feb01278cd57bfd3170af6e52e0a23b9e926bf9565a890cfb4ae8f2d590b2cd5", + "804b9c6702f0596d328f92fc1ed5a30a7ba17b9204524135001b569233fc4937035031d079f52fd04968f37c24013898", + "84274ed1af6bd6a968583995622b4d18c6a2bc703ce0d0edce45bb736529b4836343dcd11911a94a134dca7877e6cab8", + "88808098463f7505034c3b6328c8a08186b33f7a981c08376e429dd64b79b97753170531ed078dd265ded4ec0a1ed8d5", + "92823bfb23a4eb84d3759e7d717f0c8641ece0927cd2ba8c728c26bb35df2629a838002f353c8d3d75eb19520aab5f25", + "8db36bae4d960cdb9c51f419d7ddc81f372e56be605bc96a9d4072b829f05527c37c8f255cc6115300a2a0d2e6568d89", + "a8fcdbd7f3b4d7ff04149a209feb75e97149e7efceaa42d66a6b8e432590fe7bd01f1a77fa8b47108f670b612e33fee9", + "a9f4c53c62db7e5dbdea6918862d3c6d24b5bd8732a218edf0ba61e9d1861182323d8ecd7bef8f895b42970b492f6e40", + "8b95bc7f07818f4d7b409aff8da0b2c2ae136cde386f53a71565cae9fd14c73c13cc1cfd79c0f97cd77839fb738c5b9a", + "adbd1d11adc756b51a571ddbcbf4392415231ddad93da09acfafee03a9e4f9e1ce3826110619e5271feadfaffce3e793", + "95d327c8bb195cdf25fd79c98f9406a6b0316214b1630ebcce95bdaeffafa36fc1accc6882e0e5d13a8db5c0f3c0e61c", + "8cb2f1e2fb25558869afdacc7bb866544cfdd566cefcd048b48d458a886130bd086ecb7600a960a7f2563c61cb326510", + "b3aa8c4bf5b933d89cd74ca7f7176d6624d562d7d58b041328b49d7562a30b489cb606abb3c49e85baf04c28e9cd1f44", + "97f9053a85250c420599827297453c2cfde087065b823d9e43139e6a9cac3a2ec40a1b6e2f0726bdc870fff215462f0b", + "878d5dbe6b881389c2ca126ff66d87127c9aaa3f62f0d2c1ec0ea2b279ac95f8a06710dce166415db227655e2345a04d", + "b2c33a6b4203e3ca5247f0890e475518317ffc44cfbb1da9a1ba02114e8b752bea618050b876de5cf3b1906140a64471", + "a56170c8313d2b5541a795bea9934d4425b185b5c409f0484df6f44f0e4bcbf50b860ff46b7245cd99c1cfa8fc1965b7", + "96e2b658e2876a14147385fc423d2702a3cb76962b6b437222cf9cea39ebf4bdc03bbf434b747866d4bf72b4ceefa639", + "89c4a74fa2f067e7ae49c84ef782c331bcc9245db7e941804e2e99d12e987b4d25cb827778ad4c3566c4fc68018650b6", + "a01d30cea7d01c80ff26650020fab02e78fc3842e2398a81b44b21d58d4e9816166ff4ed2418831fa995a28ff35cb6f1", + "b960c80b55a8845bbf24bc3f23b0110ca701f9544ab6a5bb7929330213cb471321e55c390ceca3e24bff69bdb0d331c0", + "802c5b13f22be7be0e5db11eb3be0f0ea7f9182c932265060ba05fba20ea093dd2810d3b969ee3e387e60fe6ee834e8d", + "92478f88ef7435d15e39a97916c736abb28ea318394b88678fddbbaab3eaf31776110936abad116a8ff6ca632dd12043", + "a6d3da0370c303001d5ed99d1db8bce1f26b0e442f0f042e36db9674e92dcd6e80465e772f1e669f99221caee3392fe9", + "938f04f70a8f947d6df2f0c0e9af3cce0c06edbb3c131970dd60884fc0b0a0959c504a2a36c3ff76dfe919905671626a", + "a7117e55224230822e9983df2132347eb7208cb6798f291df926ab51e04b1a1f78d5568c9a8924ee6f57426134360f20", + "b91074c77ad93fe48dc2b10c0c5a62ca3ab7d98345b919c52d84a9dc419b59fc1b267e1c2d4b2e120016ef84bbdb0cbe", + "aa175c6b6edf02fe8778762c9575581c0ee6efc9dbf99c291a41444a23a056b893be6c45333d907d0bbe9fb0eef84d08", + "ad36dcb4e2ab425aa339ae464b038d550cb11186741dcf257f1b8b80ed4f32ffabbece45e2dc1525d4c3eeed819ea04f", + "91cb35c1ffa9cd5aebef523edb8325078da3eb5cf9e95c675a76446fc7692aaee6f949de064ca2f3e0f082cc3fa93e20", + "82622f9410c143a86bc4d756b3c7b324dc295231ce865de020d61cc0868f2c150a473cea3a5b756b36771ce1032415a5", + "a5c29996ad3a53468ece9356a5b4ccb68971ea1c89cf39644f1da2d4a477c2ea99bf791ef902b87c225d8c53d67c4c92", + "92893eceed1af34fa92b23dcbab175b6a0188a27dbac9ad3317c4e39955a763cb383ab13fb1c519cde311d8a4d12e8b3", + "8a093cb191b94b0200e38d31955f9d240e2be1edcd6810a2396a061f17c3ddc9c4f4d56766ddff4e121be7110e03b869", + "93981473df0cb1f4b47c7d9b64e3123dcf1593845b401e619f5d7c70b5dbea375d1ca43fca65845fcf0a6b2e0af43791", + "a6beb6b0697070f9562910add88d9ba91992f8da127b27be81868b1596d1012f09ea7ed601b4a6474c921a1a1a6d866c", + "92026b1ee30f2ed61c9f30337c3356844217926aabdff383c19ca3c21e0bc49811ca5b308012bee4ef250cfae1615800", + "ac0ebaea6d35f84dac4ce648af096305ba68a7a0aea0a11ab2fbe3162075444a158433c98141bc92ef3b3400d6deb46a", + "83046f482dee24ac3ca83373f0d1b82ac1c4beda0f229a9011a81ec659ff5fc1fb105e219975b5c744308c77a24f71e4", + "aa5a312c47ff7248dcb9c6ffbe5a0628ccd565c07365c4413734d415cd4fb35772622ed833862dddff520a67c509c6a5", + "a02fb88805c34018ac33582e19ed0a7e4616acc3dd0867e5f21914c2031c05c6dca30b8b35b57c2b137750f3878a6f8c", + "a60528f1f14bf0c496491d46a0fbbd6c343e4eb3f1631e92f96a3c5e5c684091aabe5801df7a67f7c6dfd1b0d35269d4", + "a1fd8e7fad8ca05a340c05a051bb0eb4197eed345f4104629a9e38e234b09d789cc5537024615feb4a6177d32d39e39e", + "8e70e36c1aa070815440e19443f1f04aae23b1b59fdbcba43b47b94a026c82c8f66c5dfe54f826f4d95ee1930cdb8008", + "8234c1969fa7e9079661e4ca309b71b1aaa10f4372be0b963205c23a81f5a3d52ec08ba9ff65b37f832b52d631580d61", + "a18cb4134127fb37c4abca328cd0047378a2e1423490af2bd3eba9ffcc99ca81a3c22404c0886f21f65c7b93c41d7981", + "b46fa45fe538816de776eec086e040005706cb3eca097e290abfb6864e745c879868aac8361894f3c3564373ef9ad55c", + "b96ca43b96c59e95439f75d1e726a35a9362f0dbd34963b156e103e080a8126a8dc3501f9fd541ff3bcf4677f5c4a86b", + "a8e8c87c7301613818d57387009e601a7ab5cbdc2890f63d985c30c74f9cea2d0584c116baf0d9cd5594386ee93fc661", + "b47e4f1b9153ef0981f813948150f283b47a7346fd9921d51fe8e4daedaef78ddeb4fd467c2ccb7cebd9816243da1c6e", + "a370c202a99c8441ffe96fad0f801086d4d7cc7b960f6e98cca29ceedf492afddfd0f351c9c4d29ac008bc255ec1a2a8", + "8f5e6ce1655d1c059b006174e3f5a55c88e1821c97f9702ad8e8455d46c2a83ae4482f2d43edda74a835686ec45a8a15", + "a30421e694930a3b65d397b2720d5f8e1eec2b6e2bb5a28d3f9b0a84db9aabd83850268bae64c2b10e313cccf120151b", + "8abe87163046f7a9b18e2a3c0b66e258facc1b31431420e0b70354b7a60ebd250a784634a76692e7d6f4330b62114945", + "894f033cf077d4eb312e3258d9dca414356271abce1d6094ecce6d018c5fadb1c15d8d69451574ad0701a2876db191c5", + "b0923d64f88ffc872654e1a294bb1af8681689c21cf08f39afe51448a68e60a9a0a74ccce9969276a932a52c07d095a3", + "b9ca23b5be8725fae7fa710eefd45522889c50c29c26384e00b78a962384f0aeff9d15cb5910e9565da12a577eb7e5ba", + "b242ccf292757197a9f470f2d80ccddc48c7f1235ba026bc68a93be2738bc968e8a200aff3e2f4807216442eb3fc50dc", + "adc2c3b375b308524b79a024ff87d122055440643fea6fc0a651bdb312c7cbe6a456afa9d342bc76446d77d8daf08bc2", + "ab645955356c2ebf2f3df9da275e01daf0b44a52afc309277d6d9ad1b05484e5ae0d9d41ad485fe481e5e362826a86ae", + "8de96ac587a4449fcc8b7fd0a51b4b5185d9c2eb3434f94cbadd092de1e26b0f6b3f7b15a37e8424b1429121ddca0ecd", + "94c70ad4e9b871566f3da98170b665a09788d421818299857cde0853789fb943cbcf7d4b2c95246ea7b72edc56a8e36c", + "b2574be63497843340700b701d5cc8be6d23125bd62058802ee67cce1f3b5f5602b27c93fea5611f27dc695ac563f042", + "869ec89da7850cedd88bcb3a50a15cece233119b31b64a61bf6b2310892ce42d8b473b584b11e61db29ed24ce8033f83", + "8fbaa269da8e28e9adf4c1b08f109da786dbe9cba871c32eecbfb10619b7a5d65a26f9bb33e201a8ed20b3de94003fbb", + "8bf7a059c37242caf7f821a6314e4e4adf799e0dd86b37892a7172598892c07272acebd05b534755c57b51556b2d610f", + "b4e72645fca459898cdd9214892ed08b5c99f82049c0a30d72bac0b9717caa9c6cc16c3dc7aa6ea4d42dcd2a6c175df6", + "a39170da87a3495da55bbb9701c5461f3403447174ed6a4af75712f7ba4ac35f51a4234bc4b94da888a0959ee109c0c7", + "b45675b2774ea7696089dbf7a0afe6c22e85fd0e4ef3db508fbaf96c9d07f700c991789206da9309fd291be696357c5f", + "b52899e3e3f6341eefcbe1291db6664bf3b6e8021d32fb9c3e37b6258a35c1da927747b2ce990937d6f4c6c3e7d020d2", + "84e5bdb3dfe19700d79dd3fabb0159ccfa084f7288db836c855b827613ce8071067c8d7ac5cc2b4e88ed7f84b690f6e1", + "801477d200b6d12fc6e0a9bab1c8211193ab06e44551e037a9b4c36fc2d4f67760b9ff4eba9a3bc7b6e177e891f64ff6", + "b6b71a5116d3c22af26a7530f535e9b7851f25a84e562a8f17a125d55b9b3fc1bd8cfe65bdcbeeb328409521e802051c", + "8687e21c34d7804c12489d30680d131ce2133e2981bfa993afd8a8eeda958ebd5e6881d342d725338659882d9f21cf98", + "a024e97a7c4de32b6383c34431994abc533ecdbd6be9bff836ec1af022f5a86773bf345c6f33273797a61fb70a8fd5d6", + "83f784f095da20ce5b31f54d6cb14b32a8a12675f0029289c9cd036b7c87a8077be2d04a62618685720e6ee69c875e97", + "b4e9dfe7cb9d9efd3fe00d99ae5e48769d4af4bf43d4e05c0b54c9cfd8bc854de96b8d3ebf4dcc06b9dac66b7471a0de", + "a08b79f9d4673afcf7f38b57f484f88feb7c908f597663a2417f92c348150c2be6b5603f914eba0d9d5bdd4e5c5572c1", + "b0eaf919589988798cb01ba0610cd1b7fa3c08715675ece8ecd5f9ef6d5d7b2c4c8ae1ea7dfd202237171aa3e6f9de74", + "abff99a98baae4dd0954052503ce81827781694a5ea8c1149f96a3adde75dc2d630e138598cd2ae7fdc7a654aa17df8f", + "83e369b8680d8b9d995222b033b4f4f3e3b20e782113c941325c7fa9c742feef8747e4a212d9aa23285a259cc4faef8d", + "b16d5855dd2716613697eba36e2fae0872aaea6999e91cf6552f93f9a0b85ed4f6ff922a91b50816bd6cf8e7a4513fc9", + "848373db600e32e741aa1d37726bbb28956783f89ce2d781e95fb1ee1adf4359968a141678af268077eae4c25503204e", + "93a0dd0fdac18a31875564505b4e28f9e8bb2915faae666538597731ac56cd77f23f2456461e2f672983fb24ad91f6e0", + "ab1ebbe49fa56524b564bc2e43784147073e6ea5d27a9540fbf2e04d0f87c645ed2fd28b3e4982cc4c0af1734ee47a6f", + "b3ee30b733839edab6f61f0738e3f4afaeccf700d8dc7415684f193b36d70d07acd5780cf539f12e0fbf8d4683be773a", + "88388f2cbdec47a6b3ae460b69eb0d2130ac14de950c22fd86de03e40d02292bb93cebe62432da39d509c1289f785fef", + "9370c41a54b68ff486b4cc6329c3a851716ebf1d088d77a6c56dec93a18b8a77b596cde74cc17d2adb2b2f411a2e4bbb", + "b9083b60dc16531f77b05a955b51a237a8f8c0173d72c352c5ca441b55abbc890b14937e457aaec4be5cbbf80cae0099", + "aafff8f6c6ebaad952c65054dfc7c829453ec735331bf8135e06406b7a9f740c9a200dc48bb2175516b41f77dc160121", + "b43d31fbbaf10526809e9e5bd8bb47a76e0fabd7852ee7744404559ab89f0f215ff518f3271a6aa972a459cab82ac558", + "b581ede48c6ef34e678f91dc4b89507413e00e70712e3e8c32a80eed770ec8d8b98caee9702d068aeaca6f704be57bd8", + "8cb0a137e68b001a5ccac61de27cac9fb78d4af7b2f5a00b8d95d33ac19cc50c69e760c5e0330a85c0ded1edce0fe6f9", + "b947fca07c7aa6c2bf13048275402b00b77b28f1d0ba4b589fbcede13f93b5b931c588560ab8ceba23bb8e748031b55d", + "81753cced5ff819901740a9a584334e355b497cb699f0be5a52cd555a4c9f149535c7bb355b54407f7f0ec27de6c2e19", + "b3d59273951ce97838c4853ec329782a255b5fc7c848e7992ded1be28a5ada7fa3254123afe32607b9991ec6e0659b08", + "86b253de246f82be1cb0cef01e87c3d022ca1829d2cc7e6a160a5afbd3ca6b94d75739b122e3bb16f8bde28a8f3223ba", + "b728b659fa2d8487e061a37f7d14a4c2d70cc37497a8715695d8d332cb274deee2ce23b9b5f6a7408516c02c3d526a49", + "81277b46d98848a45abfbe39842495659dcbb80dee985a4fc91d77d52b815487aa8bb455f411fcce4c3879c7a075a93f", + "b05b6f1fb4a6e654f0ee6b83e08b58b57059bb0b7c490405bc8d963c4a2d6be39c558917977e554e1e9e3169961cbf3e", + "88f75fa7d016fb6442551ec071cc1e2beeb3ccd213d16d744f573a82f5d70f41dd1b18af71d5f9e73d87f2f6b7dbe889", + "81a46434f1bbd65a661a0ff45a0295b8fd8a42a7969c5953721bc98698b64bddee3f806876d1e9983063fdd0c11f99df", + "8b4f6d33c510a4c9c7d623d9ae0c9aa631fcb987704726b2a4d8519372123bce3c439202f25b5b47045ec14ce39a21a8", + "8d5112b330fb63cf6ef3d2164b404c14ff9907d685015701399a260951912b19b8f270f869df317e9050a127763d7980", + "aadab394e84dfb82db15ecd2427f39b62352c3e1647c3bcd14fb24ae830ad0116f0fed87ddb63963b424a4741961386e", + "81ca4e5600d00a3bda24cbdea7a532a4cbbd893c10e7ff10667c15ffa8138b91667abe5466b31a3dcdd60155c48538c1", + "ad943af1b8a5fcfcf309ed8f2f916339f254cd555c71a407a47365a139306286a05a8314e1c70e20a65fccd75d36fa12", + "b16597a0b437060a390467bbfab94c0bdd695ae898894f4689f939e30cc2119cc08ecb594546304adf876f4e275ebcd9", + "a44a4e0a6693be356065891c27eefa040a1a79475be53d54d5fdcea7e0668ff9b35f850974000ed119f6865aa6faa721", + "adef27d1b6e6921f4eaf69c79e2e01f5174f7033eaafdd33edcfa5119af23f3a834ffe1bdf19576581b797abd1865b34", + "90c1e9202f3ffe28f8e1f58e9650dc4ff4dbc158005b6f2296ec36147e524b4f2f87f8aafc39db5b006fe0c491c92f45", + "ac817cd54288b6f7fe6338415344fc9e7b669414051631ab2f27851c052c044be06bf7235d668e194bef695923256368", + "ab14944ef653a14456d4ebc12e3196df3f1b4707c4e50b317b5ccc8ca3a0720f0330609f0e7e71793f6ca01583f38c70", + "ad5353f2f380837e5ffdf079350b3d42935a0517861d03af98db5ed3ea8501abd68885c8c65f5a66e944b1874826a450", + "8b5583863f84af8443ce8970b02e26cc5d959e47efbf8a66a54106ab165f1f76b36423aee74c7b5402fd1c4d7c1adfe6", + "b3b46037eed9fc30e4f8f0da8bdbdcc40a38e22e876ce9fde981883017854aba82c18eb00887d92ad847d30082fe7271", + "98a2b6fc90b7ad172e4368c1e54675b75c8bf2096d91c9f2b60b3397d3be3b705aed5389845dbd68f0f84438cd0f7687", + "b155e800852a5f90a2eac69cc4483428da1dc2c31588a13c924e60a7616ce9baeb7d4b829c772b260277cadd8ed84719", + "b8b92c520a1302b0cf7d993a52e1dacd7f27bda9868d59c55687d995ae676b7070af4c0792a9bc1c2635d44a4fee01bb", + "96dfe9bde526b8fc829eda825f55168b88e8f4e43d4d708cc3060df03437b46e12a8ac70d7788aa75760f6294d3e84d8", + "a3fa66c54e2fa084ced3bd838614c6c33042f492a5745d167a723c60d5e7d6020ffd1747981a23f8b68df21ad8f0fa77", + "b573ca10cc41fc04a642f6f62c355a4fda69b94b8e95dbb02fd1ccce4bce1191356e1fd66d372159944eb36a7071f005", + "acd0a1c9abddfd0ea223eda1722aaada362d34234455bd1c6be115d41e535b16f12ca428da7820a757fa4c98884a385d", + "96f242eee99c4db383b8754fa7987c0c159652e1866faec905a8d3f010e0a1ad05bd77b9ea8dfd653738959180f58430", + "9215a9b672a5d6e435e0e0a45156e0e20f75cbbdf1d14940fed3ddb63d433bef643796c7a4fff881829ebb2b2eba9460", + "b8ad9bfceaf08dc5a874387219ddd1170bc3a5e25ed72d321d59ae713be5ddf9fdfbd3aa7ab163be28dfa0dd14614e19", + "a19a1050590bc500b32c502f393e407abc3d8e683d6f6b978873aff3e3299b18b1f6b59e2b0fe237d819dbdfcfdc98ca", + "a6870fb11d4429686e52e1f44c8dcfc7ea24a020df9570c021578dbc1f9bdc8cf797cb3a72d7fc52805dba35d59f2cd0", + "a7be733b64d5c06c127bd1c87250e42bfe30ca91ed8ce51e0b6e377f454e8f6fef7f99bff650695df2fd10c375da349b", + "a1b97145dab30330eea2cdc8739b2446a3704b64505fcea3dd8a9b4a72edf222e98d967d6fd7f76794acfd97aa091065", + "b2127049907d2a3b654d1c940b740bfba3dbaf660f86ea79c2f909af7c9fe2a07a1caeb1be12370aeffaf8faa50f1582", + "8a207701214bb28e99b0784e9228b1c34afa701966267fe7110f6f29f5bb41eaae6cdb98844d0400787978fabd224de8", + "9925147a383b6f5f814520220ffdbf20b214225882c3ef49b1a1ca677709176ec82466fb9c4be2dfbe5640afb63b014a", + "8416ad93871623fb555b5390b80de99edaaf317350cc0c1ae9d54d59517074d40061f315cce8ba2026d9c1e6f6a1009f", + "a315f943deebbf0a2cdbcf3f8323e215a406e9cbfbcc3f6288714cb3a6befb1bf71b2a21ff7a2ec4731c65044c45b6b5", + "8213e0c2539c24efd186ffa8b6dd401ad2233bc19166a0623b26dd1e93614bbf792823f5599ac116231e2efde9885709", + "8e5cafd2f34a127a4a896f05e4d929eef06972a1826b3566446942198df26d62f7679b987db2b3765d9d8058b1cd85c2", + "b5302b399c9cdf912fd59007ad4737255552663b1e56dbe64a7b2ddd88d2093c73ea319b45db2dd49d1e03f5bef1a0ae", + "a0c2bcfbed4b008e1a56e5d2f2419aa59d7dd0ebd990f1c18588de702ad0fa79f445d69965fa9381e700eda13b309378", + "80a44eea1ffe24c26b16b8e2e70ee519258b9ad4b3e83cc4e5cca88ebc48d0160066f8b91d0581095b0de2428390c8b3", + "84a90cb9c7d2f799f1c4ed060387a4b793ab41c5c3eaffd3b60face9b9c3bae93cd2017283bf3de1e3dac63d0d84dd42", + "81d22febca276a05ba9bbc5591ee087b0491beb35b4d9f8fc0d041d642a574667ddc57660b20f5c568f7d61fdcb41bda", + "a3ac965ac27a28e102a439b74fbfc157e75fd57620e4c0750a466165f8aeecb2191dcf8e656f7525aa50d9c7c69b0b5c", + "913c17434ff0d9fc52e2ece4fec71b37d4474a18f3ea26925c1be2b250434d49759f58033ba0fce1c6862c6197930dc4", + "ac430559c151a5e461f67b49c7786c97e1653fa8698e9759ddbdd99f5daf17fc5a012ae6330739440880728f24eba7c9", + "b10d8e9f8aed9361b042d1398ec74364f7c7c1cc5c7f917060572761138bdbe89bf409389ee3879f93bc8032dd67b308", + "937271005a4cc6a6ec134870c1b56471aa84ed4f4af1b3d5f334bc0c42762fae0c9a6a2828d3de6151a76dad7b72781c", + "a10e4dcf51889f69e6bd4c052f8d4036b9571ced98a3d7d779cbcb9fa5c3a82228566ea7cc1d012bf56dea0a40c5a64c", + "a0ed026528d9a8bb3201bc9dcd20598933e8c72fd315deea8da63d06e97392aa729d98a55a8a60fa4d5573513ba5c9fe", + "b723fcd04cddbd4c36feae827a03746ffef251c4f4c55a88beedaeeee194430a99f566f483668a0d88b13e7a4a37f1de", + "84a2cdceed44828c7c05a6a762edec0165e434e7029df617d6646aba48776e6c3b823f40689cee136536f8c93e08a629", + "b786264e3a237ac3a1d56c9f4e87438dfed620c867100fd38b01287f5b755c7820937403bfb86644e082094d3e410a00", + "92cc35b2065fca157c7bba54410f8bd85907a01c9f760aa0ddb7a82cb55811d24cb4dc6b725367a6a1c293b809a48ead", + "a12bbf22b117f00164a42515bc57cc9e6c43cc77fb737ee3d0c0cad94cb50cd3847d61cab469cf8ca76f7958bdcfc771", + "85985b00de533bde2a757eddf53be79ea39091d16af3fc92327bcd1cd59bf2bf4411a334da29ad775e8ffaf3cea7d7b8", + "af9eb24185b0d330d0ea1d0b0fa78af0dcf42ced81cb0128f16cafdea687a9c5582bb6d7c5744117b271cd0b3303f0b5", + "8c8aaa1d85ed6327f85d579767c7a9158d209171b3efcb3e8a9d9e534c078e821b6aade255101d2c9ef6d67ba66f10be", + "a450518a03ffb40e1df89e0f88fd55b5b06f4872cdfb7ec55f40dc40d9424b3b289866336c195bdd54597d95569e0096", + "81e61cc69f93c435bd77f155e80626a9c764dd92b6c76af15c41346527948d8a6ca87d6351a0fe7987e2ee3aa66a9625", + "b615e0cebf4fdff4cb23a20c8389c370915ba26aa703b28efe4ab070b1603d1c5b6541684acf46b52a915f6aee447539", + "a7f51885c7a71885cc84ef734ecd107e8bf5f7a25131415f671d143cc1de92859e65001125323c7985799993af6c410d", + "abfbf7a46f32066989c32f774edcc68163f085ca81e94fe8c9fb32f8d451bbb2c20ac45cd8d97f9e618ab40186933b1a", + "8cf35a522b5cac1934004aa9dd236bc77198d43272888afa860cfc79b4b28dabf7a3c74098f84510897566fdd609aa45", + "86aa927df78f7a06a4985eb0a4f0b93529cef14f9fd2812d46abffbf25e618ead14d99c70e3c3bb2e17f3f7fabc9c264", + "860f1b4f4a398e9a8bb4739587cf96979cfbbe1687b7e91e5bd1198db726391b09b1a261bf12e96698818f60b5bd3537", + "8e7c4ee19ff115881051e8637dce1f5d6c65e865d0c757e8ce41b6d7bcd86c7070cce60649692bbf28c868c7e2e1e2f4", + "acf7ba01b0220419f09169ac8d16e5cc13dce08e88c90b8fdfaa33aab417f011a20b79a178d8a9f7211589d2e0affd7d", + "b404bde8e715aefbb9f20a353b911b79173ef3e2cf0aba98b5ae6190b90597d65043b0b4e014ad9ea6c77da2d213ea12", + "97e3615d1c77a402253bb55da2d1cdf82de316cefffe42b1022c94b4818d6dc4a313731db85321c537914bdf716a875c", + "940e950b96a4096a578c6874d747515936652b9b113a5f27f5a834a610867b05f9881e2679b0b289b8527baa0009b6dd", + "8de15a13ca236a3a285ce6e6826c502ae7365bbe468b6e8ac67b15b0bb49be0e996f1eec81ef69e4b7f54f8e4779a054", + "a12244777eacb08ecd42b5676b3a51153022ab97e9353ace0f47c6054c22de9ba60d2a60f59a36841c2a791cb1b7c288", + "94f7580203e39a2642ee2e7c969b9911f011d7f3a90c398e1302d26edb3df03df1d0c43baa1c6cf90dde95296d49e742", + "82ead33144aaecab965faf63af384565992f38fc1066e71e33d53f43ac93892e27fe78c4eaca1cccbc53364e26ff31e9", + "a0c129e9706d354249a7f8aa664ccd7ede89aa1445c5547410814b56d10dc086720953363ab1da8ff5f1ed5d8e575104", + "93b3057bf3f74edc95237781ae012cc4b1d3fd0455565ceaac7110290aa518ac32478ba4eb9851555fa87270fcc84f1f", + "949c2fd0b94f31f7cbf00c679bd3f6ec1a2f4056654708d39edf1a450b4e19a6e251d0bb24eb765087e698f61d3fca2c", + "99fd2e50e211ccb66b895eb2fc42f260f3ad5767f04c2fe238b81dae98aa6e3977443a51f4fe7b43f499caabe45699a5", + "84fe19626503218f327b5325bfd7c0c3d2614b47d34964aa0259d564e769c6c81502132cc1765b0b31fbe39852706927", + "b43287ec29d9010bec4284de58fed48dd1e129bac79f09d45153c9949131782f77b11b0c9f8ee06a39e5e9bbaa8e2c6d", + "908902f3ed45482df2f94415fc8e5a308057a40c8905d7cbbd58ec4848e19276577b7f7e69e5e684a8b981738e10f7ef", + "85cc7d9c1eae372b4f88758cd6e21604b4bc9f0794e1e74b6d9de96347f81944d01331385fae7a38e5f6096c1dc23465", + "af60288c702082fc258b3dbd6952c6b75c1641a623905f491b1e72f49b9d39b33d150a336450abd3911a4c128166acdf", + "a7d8ac7e589558c4014369ab6f4c1f2196205b03e4278152ec0dbbd7ba54e803c3369a71d364a773aac8dbbd117e4a13", + "9833aed34e48c206e9328073597aee1123f5bec085339b4e6839a389a429bf3042798a31fac1464ce963204adface76b", + "84631a4f012bbb62133030224b57deb32dcf464cacc8ffde7775adbe68707263ab5527a1c75e597e03aa703ba658b889", + "a686a61f6467858a2a4c13e70ad81b1901290d3e51bbc0c6e366f9e652f575e91b11c75f640ccef8b0c6c1b05a43c9a0", + "b585f0ffd5144907703b41539bfad7f9f058f5985f63db911064ba6b07af8da2796b84b16db42b8d11135c3f846cd9e2", + "b525539516c7bb25f1d7e165f269dc8c9eedbba74df44887e178ab8fd798e2a31f39812ca922d6b64d91564f14012a64", + "91e480d7568fd2fae39c35b0a8d623e66a3160fee1dd4e9097255004938b11ac1cd3918dc6a1e5fbcb700c95a547e5e8", + "936ef55c69b842b6177de71fa48dc5442bf5132116b214302f8f242ca36a273a6bbfbfaf373777104dadbe8e7da5e970", + "8e950c0f6688abdff8a3b8bd77be6da6f2565c7b55711f5860ea62a3ab1d51aac31821c602bc11a45e33c69e7dde3ea4", + "90eed4595104a0527f8db1e028ff622ff70db4eae99cf47f6c2a0246ec7b103570a6a9a877e32e9647cc74969006743d", + "b756344f6c4ea05b792e416d9bd9ce9dd4bd904e7622761f28a85628506bfc9d88a25e5f04db62fad30a92fb1d8d8556", + "ad79ba76534c1a02ac3e9b7308d390792984cd75b7e1d0e5e4ff123642d99d4ea1825643091aa8117336333c40d5bd94", + "832b08144887de0c0341d84f6945450af8d7a4eb32367d7703118186c1be525df9382ce61fed5f3b65a0bb3449185f7f", + "a322fb944e46d8e47994820890c94af423674716da810ea1da71e0a7733ad72c22114ca39a4b59c98ce4291a5684c154", + "b982851a65140dbea79bd3b5487e236feccee051deddcc17c2853032efca289ddb6eaf64be3dd85a73012fdbe9d2d4f3", + "8eed5e230e201830b44b9fadca4e156fe1a16bf840cf29da0f381ea0587b20c226de2465c67e6268973e776809af68e1", + "81c8f1c04490f36e41a53ee1b5185cb8adbb37c258fd6c3be8c56835bf574c37183a94d55b6554fca35d6e6dd9af0133", + "8c4928724107cc16d36f2976677eac0b852fc4c3c0bb2f9cd4d59cd24a113faf33b2faf405c3fcce25be51d41e42c2c4", + "8e4ba842636fdfc4d71f0983538ea5037d420acd26abd12efca48c252eea85544b2fa9fccdfec4e7c2a6359baffa112d", + "b4315b84700e26dec26f3488d308430fdff4809c10d4c24309627911cbb769ffaad0d1ecccd622dd02194eaf5ba59f91", + "ab888308f757faef32648c1db01650dbc9aea248b09d06e6efcc996d395f48ec96f2d54a02de441d753fe8737862d991", + "805094cfd77e207d5c75f3cad99f41f763ec15443052cfd758c6a82ba422d831a1103a7f9b100da49c28198279c3d3dc", + "ad857f33243e4a2cd2a773700def21fc7f94939d1a6d2c2125ecd58fc206ccafb07a2c02a1cfce19857d3654aca2c70c", + "a4d12d40149953daa70b89a329e918e9d93efb4e8004a9357fe76682dab9662c8507e16db83e849340f05cdb4933a373", + "a0dbac2ed4b5d03606524245e8a31080eb5bd3e9a0c51dad88c3b18e3e6bc5d64953a81c8e60425b80107ee6b62b1fb4", + "86da05355900f327164a78901f6e3db857531b33b1e855df1a67a9ba222c6b05fdb6b0ffbacaeb1ba5b45ff8979b6b68", + "932c9873aa3e226dd922b5a616c75153bd0390ce8f332a414b9c8cb6606c2501a37a2aa88097bc7d8e2c4261706eb38c", + "accd9cdf07ccdd42033ce3b105e00bfd39e2304b1e3d66f8b1128645634452c20f759ec45adcef2fdf04408f62c4cc04", + "b75cfdfc1cb48918752eab17eb579820ee6e71e6667abdb64df834ffc8c1362fbbc23ca2c80dee248fe1fbb72d87dfc8", + "88b998c73b00638fde7d3dd650a08c5ab996dac6ac34251337fbff3fb5ae4a25dd20c1a16c987ad7ded19eca23cea891", + "8afef0956c942571a27f504553fb312cca9e50ce41b44e0466d0516c5abe4d8acf4594cdb03b1ccdbe3f2e6a9093b713", + "9042cd83c5ff261e9ebda26398caa16cac2cb840d19062fa8ae50e044c27104972948318f4c866dc4d578798272d3e49", + "ad536719a64570a2cd1d72b6590ea1d02c8c49f259a7867be26c8191445165954bcfad50ea12688ace3fdfb0e98143bd", + "97c86328d63d297b6bc9718dc1ad5a05b908a750d1c455c700d84315589128ce4eea958aef2bcf0fcf4adbd8e3ce58d1", + "8e592cf0802e6a9541eeb654dc55055e11f3d757847285197132935ca35bbb1a9156829a39384dfa6f645ff89eb36738", + "ac16c614998944f77590bf3913a010e13f2d3bbf6a172293baf5983506c1a2d89989fb72e598f5bba1ea10a691377c93", + "ab8e6f5b46baa6632de3621497bcbdd584decb999fe7d8a3364843a1e0b76497600630b6a24dd30119d8bcbfca29f335", + "abe1d3af5279e60122d9cea8cc6581c819d7a0e20e3715da0f6da7e02d13a7653db643bd946e2fa9ba338eca81fbe140", + "8c33bd831ecfb18d1d0713e16beba768e9c42df62170c1f8a16764912be77f2ac5915623d1d25e8c462aa9c2f6669ca4", + "903692becae4a6409f7bdb127d9b11de57a5739fe24218dcbaa0092648d5332dfeef29a908ee9e43e5e0a51a4c3639bc", + "92591e90347ae286acd365eba32cd9ad8f20f4c9cad2dc579b195147ff290adf0d776bcb3d4b04a25d68a941fc0c781b", + "b64bbccf860299aec16e1f95c768a1f337c740bde612e6ba260e393edb8b04540127194761c42597abb9bcb771c576c3", + "9194f056ccfdfeb78a11c5347e2255d7a7ebd1251f9aebc0b58feb68d3e03a7dbbb74e3ef7309455853adfb4694bd01a", + "aa4f15f6d6a53ae65b7f6f91e8981d07a5919d2138679a561f7bb608dc4596e45ca06c9441d51fb678b2ad89ae7a17ae", + "90e3d18507beb30bde08c5001faf489a19ab545c177efb3f73fbf5605f9a0abcdc8bfbc44f832d6028e3e0a834bea98f", + "8f31dc0118c8c88a6e79e502d10e57652b7aba8409a5bf572ca63fed6b7cbad7f28bbc92ac2264f649792fc1d0715085", + "a307d1067ea4c56437b6f8913aa8fcbf4a24580fc1e3336e7f6518f0f3adb9c4733090e459a3f737414ec0048179c30a", + "b7cc41fdf89595cd81a821669be712cd75f3a6c7a18f95da7d7a73de4f51bb0b44771c1f7cd3cd949e6f711313308716", + "a9dc74e197fe60e8c0db06b18f8fe536381946edecdf31e9bd90e1ebfcad7f361544884e2fe83c23b5632912ec284faf", + "8b3e1e81326d611567e26ed29108f33ddb838c45bbd1355b3ae7e5d463612af64b63fff9fa8e6f2c14c8806021a5a080", + "92f6537bca12778866335acc1eb4c3dfc2c8e7e5cf03399743dcea46aa66cac92ac2963b0892784263ad0ebe26ffdbf6", + "b5cc0061f7a3e41513199c7dd91ac60d727366482a4c7328527f7bd4fc3509412f711bb722b4413b3736a219b843d15d", + "b3e9711d68d2c6f6e2cc27e385d5f603d9a1c9a96edeefa1ffdf390439954d19504d6aadc566b47e229ad4940ef020d2", + "a09d0d3f0e5dc73a4a0827b72710b514bbfce4a7fcd5141d498a5aad6c38071077f50d3f91af897d9ab677b7041dedda", + "b177fe260f3b86e9ac21f1bfbe2682ae5dd8c9aecebb84f37054bdab6e39094e611ce582210ceeddde66adf759dadb6d", + "b0ac6595eba9f5dc4b2fd21856267cfbcfb5b12aa34ec69ca32b80071c5b652e85c25a224d80443d503bf25fbbfe07e9", + "81f3c0e11b196bd4a2e8f07f8c037002566dc9037da81f3988add458a520c24dd1be3d43d851e28c0c6a85de4b57a542", + "a44308c95615f7fedb2d2127012924468c015df9f48359cc2e36ab4223870b0bfc1e9040baabefdf5266f93afaad896b", + "8493ec4c32d5a13b81039f1b436eb83f259945dc950e3c6c2ccf5087ec56dd2f60890ed4edf01728b6a54950e19b35c6", + "a1a439ec2a6a95bdac9aaa925ff337ba956c0d236ab5318354270e73ed6b73b4ae2d27b4c1686cf97b6526d04e65be81", + "b4659b7b53c55a4b2bbe210b53520b392f893500e18990d843b72d7379d45fb44dd1dd2184348d6fd853d6b9ecc6b7c6", + "afb2c68d75d00130b0e1b4f250001920213121791698ec04262db714cf7b1408d39f6cc10421f954845aad5b8250b77e", + "b22b843b40a97210f94043b552f348f66743055a3f274856a738e7d90a625b80e9bbb80cbbb450e1666eb56b8bd5c60f", + "800895ced82fe13d5fff65a93b0051c3df698bf1221b682accfdb63e3970f669ca37025750697f4e8ff2a3322ad57be4", + "b21f598c50d7b9f4a584d548f85e42055ef8e24991906d973749090261584c7f4f5e984b528926f7e75375dd84d51af8", + "849b1c68192d18274598dd6d0bf48fb5ee3b1ba25b331cff2d06f345bef3bed49760ca5690848cf33388f6a9a32cd646", + "aeb6fd9478b10ef456f6bbb1e6dd19b14475e65497772d12cfc097948383d3fbd191bf95f046b8bf1989954118e483d0", + "b1b5e0ea2835f7fc8b66e7731e392b43d16cbce04b52906b6751ab1b91978899db5fecbdabc23a19dabb253005468136", + "91b6b1284770cf6f7ef35bc0b872b76c7763ffcfa68f9c8cfabcb2f264a66d47598bb9293f6a40f4c3dd33c265f45176", + "b9ffed029846487c2cfb8a4bb61782bd8a878f3afdb73c377a0ebe63139fa070e3fcdc583eec3a53fdc5a421ff1fa877", + "998007249d041b0b40ff546131cfc86d0b3598dcedf9a8778a223f7ed68ba4833b97324cbb1de91292b8ff51beab44b3", + "8eb77ce9e0e406bf6f002870fb2fd1447646dd240df9bd485f8e0869298a1fc799d8a41b130c04370e9a9cc5c7540ca5", + "853db8157462c46f2af7e8f94f2ed1c9b9a7ba2896b4973296898ff3d523d6e29e0b63a5d26cecd5e490b33c87a4cecf", + "b1436b6f3278768f0979ee852944258f2599977d255bea6fc912ba17c5dff5bdc850cf3e1fc52be9d6d188e868670f4f", + "a76acbc5832019b3b35667ab027feff49f01199a80016620f5c463dfcbfb51bf276ed17b7b683158ba450660cc7973eb", + "94540cdb051faf3ae8b8c52662868c2dab66bd02505c4f5f8eb4d6b2e2e5fd9a610890c5dcf8fd887eee796d2b5753a8", + "aa35099666bceccf4eb3b65b13bba88e30a8be93693ab6761d8e5523343e8d6dd42d977e66499352fe4e9e9784a1dd0d", + "894471aad17be54319083c4b5e40adcfacf7c36c4aab0b671030b7ef321c53590a25eccd836efd20f32a93185fd315bb", + "8f52a9f705bb0dea958fcfbd52e2b6c08ad0f89a07a6b2942c1b4c37eead0d97a38a9e9aeb08d5d59b7fa2a9347f738b", + "9031c16b4f936c9cab55585dc5064739f696c3347ee2c0792320c9f749e760d120e396e8485ffc79d81c9f3337ad3d1c", + "82090a0d0d9b05459ec1c328ecd4707c333b784e3aaa0ef0072cee1eac83f9a653a75d83b9f63512a8c41200494826b4", + "92c3a9553001f9ea4d67236b8ad1a33275378202cc1babc03f313895458f4b2549bfbbbdd37bfb8fbff0decb6b9f820a", + "88651868f4da37338a22bc553388df5dd1dd0cb78c4d7d07c637d8f6faef4bed72476fdcd4304d5bedf3514011135f08", + "83fa0141bfebd88063f1d787719721b4c6b19ecf565b866de9d7d5d1a890e0e3d859b364bb65f8f8e688654456a40263", + "90a7fab753e5d56dfc0e53a6b4e6ab14508220f3a62b3f3f30570c4c9ad225e74122635826c92e8e3227ec45e551432a", + "8fa375b0345bf6e5e062d108f9feaec91029345ecac67ccf1264eac77b8654cbfdda1f10579f481889c0e210254eadde", + "b83f06116da9daebdb013b26724523f077debaf6bc618b48a7a68858a98d275f7899c4ec73a0a827219b9248dd81c8c9", + "8be1cada55e0c5ebb4fd460b2d209ae5326285a20c8bdd54ed9d1a87302f4063c8730bfda52d9d40e0d6fe43a0628465", + "a68ad6f813743ec13a811f2ef3982c82d9d9ac1f7733936aa1e122f8dc7f4a305cc221579ab8fc170c3f123a1576f9ab", + "8878f1128214fdbbb8a0edd85223741e021508ab6d36c50d38680f2951ee713ea056ed03f62b9461897963d50ceefe0b", + "acc0d43d1b0260528b7425b260a5dea445b232b37240759fc65fe26f7c9d8e51569c5722bc33e94de6492f4ba1783504", + "ad80b1dd717b076910ee5ceabcb762e75e4d094dc83b93b65c16de1f75bc712cef223c05d5579c1561829406c07a97d9", + "a6fc9803f9c09d95fc326cc284f42ea5566255eb215dba8a9afb0be155ea11bcc55938b2d16f01cd2f2eda218c715efb", + "83ad733dbdfbaae8095a403dbf09130513f4ed4f08dcf8dd76ce83d1ea72999b7eea3a7b731da0d2bc80a83c6ee0e3e0", + "8748912fbd08cb34a85416b0937d9c4327e9eed20d6e30aeb024a7253f14f1e0d774f3326e54738d71aae080e28da0fe", + "8997e78d8acf23051428af67183ae9b2c4aa42b503745ffe33df35a35103c589987e1473ab14dcd28ee78ebcb10d8e95", + "a2f340502a7eb3c4a36412e6f028321372c4fa18a4743945607424e932af1271fa3e6598a162c872072529576eba6283", + "868ccf19b5044ab93b45c9ed3ae34fcb504fe1453d6c4a1d12c325032cf01eb90356de82080ed897e97dba13cae33a02", + "ac8867005fe4354d67aa37b866a7e581d2f94f7bd0b9f4efb5c2d1370ec13147a60692051b02fd00ae60b512bce9b1ff", + "8fd01886b046819c83c12bb779e432b25ba13713f9227be702074ec3abb2bba6be37220a0a26a4bd4171b99b14e32bc4", + "a128981ed199f92b5959975c150a93a62fec50b61c80a3fa0634d90fc8058f76f5cbee77aae6889af12d296b30e613cd", + "81fe618552ff7a36c9235c6d4066cf2f930b5b38de4089e18166e4a06ca5723eadd1976d25e34b74b3ce942300b23e5b", + "ab1223ea049e6e0fbf9b611de7fd7c15e5e9637cbd73aa0e36aea08a7503ba6804f2aa807186fdc9aa7f4f9195f72e24", + "b97285286981b2665f898abc13f3243b63005bef8db4cab3f658bf6167036b61af400f08db0fc3c640a9c623b760690d", + "ae3ddff7c1f0fbb6a13dbbc667a61e863c2c7c51c2051e33cd61620142e7e30a7e0c4c1f8fbb512aa3a8640267c6ac26", + "99c2a89d5bef236060e51c4f952664094c20fbfca647e5d24a55c1fb8df2f3df58244fbbf3635db07b1c29ee3234fa6f", + "a5010764d4b9cd3b410638334d1f70c5f4843f45b4f4a9316aaea5fbb2c510a97449dd7a07b49f47334a69d37d9955d3", + "86706d011dcdc9e9d165d01fea1df68dd74bedaf15a39f92893c030cafe96f4498c4c1fec2d2136354341b3f440a1462", + "88fd57eb62bd7dc35722f3a0576c2138403a2f663a2603482e8974a895cf56ddbb02657dc6b89eb2cf5c1f9d1aff6426", + "b0dfd4c68e3acb6bb8a776adaa421fc5e268ed4d5964bb90a727091e5113b55b3f9c6d33cedb3ee47ff7acc5df8b1749", + "93b92bc942e1a636fc5c2dc1840de5faf158a113d640d5a475b48e2c56ccccaf9db0e37e90ce74c4b3f5c9ac3b2eb523", + "b29a16fa1ea95cbfc1873c435ad40dc8495ba6341801b72bd95d908147dcffb1b4bb426dd635f3af4c88984f56594dd8", + "b8f367105e1a2d554ac30200c66aeb579d3d30a8953d20fb6ebba2d876ec39c52ea5d654f1bb89b8ddf3d9d651f31cdf", + "b5fbc228c983d08adf8612eba5b3db3acff604439226f86aa133b02cce4ffde2f977c8dbb8b446b4375673f71634c89d", + "a399bea37d3056e0559f6644faa0af93063b4b545d504d7e228d3dbbc294af83d3c4cf37fe026b63899b4e7d50fd08f5", + "928ef411a36414b24aea26fdbed4bdb1bb6bdc2d967e2553ce54c7c4e077e76869cea590257645c9129dd55ce025295c", + "9684a4adeed416a9ce82ad79b55c4a3adcfbd43950bc442ed8a340381caedb70f4baaaf821e3a152f483f965d8f56162", + "92558a37f214d6f4cb6d72cd2f4ad24dff9d17611b9e4a41ee5c741a5d1ca9e4053b0584533ef4da206110b5dc3e2a35", + "973bf0724d1785cc5e85d2a8ee8c354ad4cf557217ced0b7940f6f064024c20b2bfc5b144c820b5083da4bf70690de4d", + "adaf1389dfa528210ca9c2657c5ff10d51f7e3b18e93a59c37211be0506c3576cb2c04ec80cd0f82605e53c5a3556620", + "85b58b223b09fda6f3ab674d75e780c49eb2167837243df049281e8f4fed653811138b398db9cdfe7405fdb8485602fe", + "849504d3db408d80745a07e850b0a804607b91a59922a5d3bc40da2748c029c029419cda38d2a4485cc0824c6b2504f0", + "a3f4afcb353bc2582a02be758ebf0cd18752410ca2e64231176bfa23828423e0a450a65f241a9ed8eab36cae8d9c567b", + "ae362786cdf121206537af9590d330abbc6dc328b53cdd145dbed0e5df1364c816aae757c4c81f9d619e3698dd32bcdf", + "9024cfa5b0101eb02ab97866d5a3832944e5aa6888484cfba3d856576b920787b364fba5956bd7c68a305afedc958201", + "8a116df09fed923acefb2aecf38a4fbc4b973ee964d67f03791d70bee6356af43ffca117d4e9463ffaf0e0d5d5e5a69f", + "9163016175c73f1bbc912ddfe03bd4e1db19c64951c8909ee6befe71a1249d838e0db49f03670bb4c5c9b2ab0fb4fef3", + "8f6357318d8d16e7240a02b05ce5a4976b6079d49daa258789c6dbf4a47950ebe9de6411780fab06c7c1f35651433380", + "8e63cbae8be7341892dbedee3111adf0307c4ee9e375181aa53478f5ba9cdce164d6ae890e5f480119a3a51c6e989165", + "a9782f30674a4874d91bfba7eda63aeb5dbe66b040c768d6a925d8ee135f0655ea56276b105239cc0668fc91ddb68cd1", + "8d9d94b61ab84ec08665cbe0244ea41756785df019e453ef078c19380bd44c39d2958e8465c72eacf41eed5696037805", + "b1470e6f5d2e314474937cb5a3bc30c8bf5fc3f79014945f6ee895fe20028ffc272f9d3a7320aac93e36c96d8a5454e3", + "a444911bbafc71179766594f3606b6eaff041826607fd3192f62dec05cd0f01b78598609a530f6930e8440db66f76713", + "a9823d44e2638fca7bcc8796cc91c3eb17f46ad6db9f7f6510e093727614aa3a4f9b2c4011ef91dc1c2d224d08d8d05b", + "ab86020972c359ab98294212558b4b14862040139876c67fc494184b5c9bcea1dbe32fe0c8dd9e60be9daa304acd599a", + "b7e5cb685bbdcfdb1e48259a5d68d047846c8a35c5b3f90172fb183d1df40d22eaf0edaca2761a07c29c577000ccfed0", + "8c88319dae4b28989817e79e6667fd891181e8d2ed91b9c6b614985bca14b12982462ec58b17be0463c24bbb79dd62a1", + "8c1c6867e7107fb2178157c991b9c8b0f90c8d57a51220bf3650438ccabccf62da4db8a9916491e730ff3d0c106496e3", + "a00a79bd58da6528b9af033087260f9f3d00519eafb4746b355204ee994e89481591b508eaa5402821083e250d38467b", + "8785abd7c37690f6aa870ee5c799eef72e398a7898b6767f698515be277b9c2fc1af12ea89b0620a848221343a3b5ec3", + "8aadae68543db65cef71d0e230a09508d72061398ef2fabec0f856aacff2125b79c70e620744aaf331faf3dfc8afb9bc", + "8ff0cd437fcad9630b8a2333176a55e178db4142ec841581590594d74d5b53baeac5fb903fdf7bcf83e245b95b58285e", + "af274e8fad6b190be4e5dc92d2705ba6ac0d7e1ea29e958a5cdd4cb764de46a56d9eef62c999a16e7c50a50b2d9fe3a8", + "865e6ec7d1aa848786d6a7a4e87a24d442311f0810b01ef5a74928ab59fdfd651e48880b49680047e5b0df6b3c7c2ecc", + "800706baaeb35bf3bc33bdea9a8b5cb00d82df407b3b7e1b781a9359cf44fb410ed311591080181b768aae223d9246aa", + "a9496389d0780b309c6998374ae159f58a8d0fe9a1c24c36cebcb45b27d818e653b51a8ee1f01e30a9b2c46a548126ef", + "b5fccf4fc3186661939fbee2e89c2aa0e3a6ad4907bcc98c7750520540c4c183b1bbfcdf47f2f1c5e75c3a30cdf30c75", + "a90028e39081b736e628c2230cc1338f9210ed01309a40fdf08d39c10cced2cdf71271013bea6dba3a0444fe47963106", + "a0815cbb325a8fecf2e1bcc5046644be32d43a8001bd5d8cf0022e4572cd0d481b3e717002f7ab21e16da5f5d16886d6", + "b2024787fcda52abc4138150f15e81f4a5be442929b1651ddccbfd558029912be4d61c3c9b467605fff640edf7392494", + "ab5aa60032304a584cc9245a33f528eae7157808dedd1ad83ebae00aadc25dbe1cd5917eb8b6b2c800df15e67bdd4c4d", + "866643847ef512c5119f2f6e4e3b8d3f4abb885f530bb16fcef0edb698a5b0768905e51536283925b6795a5e68b60ddc", + "806aa99c9a46ee11cc3ebf0db2344b7515db8c45b09a46a85f8b2082940a6f7263f3c9b12214116c88310e706f8e973a", + "a6eada8b9ff3cd010f3174f3d894eb8bb19efdbff4c6d88976514a5b9968b0f1827d8ac4fe510fb0ba92b64583734a1e", + "98480db817c3abbc8b7baedf9bf5674ec4afcfd0cd0fd670363510a426dad1bcf1b1cb3bf0f1860e54530deb99460291", + "81ab480187af4a3dfbc87be29eca39b342a7e8e1d1df3fc61985e0e43d8d116b8eac2f1021bde4ae4e5e3606c1b67a21", + "8a37df12dc997bf9b800f8fd581a614a1d5e32b843f067d63d1ca7fde2e229d24413d3a8308ec1e8389bf88154adb517", + "b045a55ca0bb505bd5e8fcc4cfdd5e9af1a7d5fe7a797c7ede3f0b09712b37f493d3fcf6ef0e759d7e0157db1f583c95", + "ad502e53a50691238323642e1d8b519b3c2c2f0fd6a0dd29de231f453be730cf1adc672887d97df42af0a300f7631087", + "80597648f10c6d8fcd7421caf4e7f126179633078a1724817d2adc41b783723f302eabc947a7ba7767166dacf4ce8fa1", + "aefb56427966c81081999dffbe89f8a0c402041929cd4e83d6612866cfbb97744f4ab802578349fbecc641fa9955e81b", + "a340e493fb3fb604eab864d4b18a6e40ba657003f1f88787e88e48b995da3d0ab4926ce438bdc8d100a41912a47dace0", + "a6d777bfc0895eac541a092e14499ff8bf7156689d916a678b50a1460583b38e68158984bea113a0a8e970d8a6799a85", + "90ce469410f0e8cfff40472817eb445770833cdcf2895a69bc32bcf959854d41712599ceb2b0422008d7300b05e62e02", + "815c51be91d8516d5adc2fd61b6600957ed07cf5fdc809aa652b059bea8ed179638a19077a3f040334032f0e7900ac8b", + "b3ec6c0c3c007c49c6b7f7fc2ffd3d3a41cdff5ad3ac40831f53bfc0c799ffeed5f440a27acc5f64432e847cc17dd82e", + "823637abeab5fb19e4810b045254558d98828126e9a2d5895a34b9e4b4f49ab0a5b3ee2422f1f378995ea05df5516057", + "ac05412bcf46c254f6548d8107a63928bba19ab6889de5d331eb68cf4d8ce206055b83af4cb7c6c23b50188391e93f84", + "88514163c587068178302bc56e9a8b3ad2fa62afd405db92f2478bb730101358c99c0fe40020eeed818c4e251007de9c", + "b1e657d0f7772795b3f5a84317b889e8ded7a08ea5beb2ab437bebf56bcb508ae7215742819ed1e4ae3969995fe3b35d", + "a727d4f03027fe858656ca5c51240a65924915bd8bd7ffa3cfc8314a03594738234df717e78bb55a7add61a0a4501836", + "b601682830fc4d48ece2bdc9f1a1d5b9a2879c40c46135f00c2c3ae1187c821412f0f0cfbc83d4e144ddd7b702ca8e78", + "b5cfea436aa1f29c4446979272a8637cb277f282825674ddb3acac2c280662fb119e6b2bdd52c4b8dbf2c39b1d2070d6", + "85c211645ff746669f60aa314093703b9045966604c6aa75aae28422621b256c0c2be835b87e87a00d3f144e8ab7b5f0", + "867628d25bab4cb85d448fd50fdd117be1decdd57292e194a8baa0655978fae551912851660a1d5b9de7a2afbb88ef5c", + "a4e79c55d1b13c959ff93ddcf1747722c6312a7941a3b49f79006b3165334bab369e5469f1bddebadb12bfaff53806d5", + "ac61f0973e84546487c5da7991209526c380e3731925b93228d93a93bce1283a3e0807152354f5fe7f3ea44fc447f8fe", + "a1aa676735a73a671a4e10de2078fd2725660052aa344ca2eb4d56ee0fd04552fe9873ee14a85b09c55708443182183a", + "8e2f13269f0a264ef2b772d24425bef5b9aa7ea5bbfbefbcc5fd2a5efd4927641c3d2374d0548439a9f6302d7e4ba149", + "b0aacdaf27548d4f9de6e1ec3ad80e196761e3fb07c440909524a83880d78c93465aea13040e99de0e60340e5a5503cd", + "a41b25ae64f66de4726013538411d0ac10fdb974420352f2adb6ce2dcad7b762fd7982c8062a9bac85cdfcc4b577fd18", + "b32d87d5d551f93a16ec983fd4ef9c0efcdae4f5e242ce558e77bcde8e472a0df666875af0aeec1a7c10daebebab76ea", + "b8515795775856e25899e487bf4e5c2b49e04b7fbe40cb3b5c25378bcccde11971da280e8b7ba44d72b8436e2066e20f", + "91769a608c9a32f39ca9d14d5451e10071de2fd6b0baec9a541c8fad22da75ed4946e7f8b081f79cc2a67bd2452066a9", + "87b1e6dbca2b9dbc8ce67fd2f54ffe96dfcce9609210a674a4cb47dd71a8d95a5a24191d87ba4effa4a84d7db51f9ba0", + "a95accf3dbcbf3798bab280cabe46e3e3688c5db29944dbe8f9bd8559d70352b0cfac023852adc67c73ce203cbb00a81", + "a835f8ce7a8aa772c3d7cfe35971c33fc36aa3333b8fae5225787533a1e4839a36c84c0949410bb6aace6d4085588b1e", + "8ef7faa2cf93889e7a291713ab39b3a20875576a34a8072a133fed01046f8093ace6b858463e1e8a7f923d57e4e1bc38", + "969ecd85643a16d937f148e15fb56c9550aefd68a638425de5058333e8c0f94b1df338eaab1bd683190bfde68460622b", + "8982f4c76b782b9b47a9c5aeb135278e5c991b1558e47b79328c4fae4b30b2b20c01204ff1afb62b7797879d9dee48e2", + "b5098b7ba813178ced68f873c8c223e23a3283d9f1a061c95b68f37310bca4b2934a3a725fff1de1341c79bb3ba6007e", + "97b160787009f7b9649ed63db9387d48a669e17b2aba8656792eb4f5685bb8e6386f275476b4dfbb1b4cb0c2a69bc752", + "88b69369c71daad6b84fa51a0f64a6962d8c77e555b13c035ad6fa1038e7190af455b1bd61ae328b65d6a14cf3d5f0d5", + "af88b87801361f0de26bd2533554ee6f4d8067e3122b54161c313c52cc9eafea00661c5c43e2d533485d1f26da4e5510", + "98ab18e3bbcb23ac1e34439849e56009bb765ab2f2558ebfd0a57cbe742169f114bceb930533fb911b22cb5a8fe172bc", + "9027507f1725d81e5ac0f0854c89ab627df3020fe928cb8745f887bf3310086c58fca1119fd5cd18a7d3561c042d58de", + "a676583f8a26e6f8991a0791916ce785b596ce372812f5eb7b4243ba9367ea95c797170fdac5b0c5e6b7f6519cc2b026", + "b91b0ab32638aef3365035a41c6068e36d2303bfee8640565e16c9a56c21703270fd45946ce663238a72c053eb3f2230", + "aaf4cd1ac0a30906dcd2b66b37848c6cc443da511e0b0367fd792887fdaf1500551590440e61d837dbee9d24c9801108", + "a06f20a02d3cd76029baad5a12592f181738378a83a95e90470fa7cc82a5ae9d2ed824a20eeb1e96e6edc0619f298688", + "a465d379c3481b294efc3f2f940b651c45579607cf72d143b99705eae42103a0279eb3595966453130e18935265e35d6", + "892a8af7816a806295278027a956663ea1297118ede0f2a7e670483b81fb14dccacc7a652e12f160e531d806ca5f2861", + "b480917c0e8b6e00de11b4416a20af6c48a343450a32ee43224559d30e1fecdece52cc699493e1754c0571b84f6c02c2", + "b3182da84c81e5a52e22cebed985b0efc3056350ec59e8646e7fd984cdb32e6ac14e76609d0ffaca204a7a3c20e9f95d", + "a04ea6392f3b5a176fa797ddec3214946962b84a8f729ffbd01ca65767ff6237da8147fc9dc7dd88662ad0faefdb538c", + "95c0d10a9ba2b0eb1fd7aa60c743b6cf333bb7f3d7adedce055d6cd35b755d326bf9102afabb1634f209d8dacfd47f1a", + "a1a583d28b07601541fa666767f4f45c954431f8f3cc3f96380364c5044ff9f64114160e5002fb2bbc20812b8cbd36cb", + "a1a0708af5034545e8fcc771f41e14dff421eed08b4606f6d051f2d7799efd00d3a59a1b9a811fa4eddf5682e63102ea", + "ab27c7f54096483dd85c866cfb347166abe179dc5ffaca0c29cf3bfe5166864c7fa5f954c919b3ba00bdbab38e03407d", + "ac8c82271c8ca71125b380ed6c61b326c1cfe5664ccd7f52820e11f2bea334b6f60b1cf1d31599ed94d8218aa6fbf546", + "a015ea84237d6aa2adb677ce1ff8a137ef48b460afaca20ae826a53d7e731320ebdd9ee836de7d812178bec010dd6799", + "925418cda78a56c5b15d0f2dc66f720bda2885f15ffafb02ce9c9eed7167e68c04ad6ae5aa09c8c1c2f387aa39ad6d1b", + "87c00bba80a965b3742deacafb269ca94ead4eb57fdb3ed28e776b1d0989e1b1dba289019cfb1a0f849e58668a4f1552", + "948d492db131ca194f4e6f9ae1ea6ebc46ebbed5d11f1f305d3d90d6b4995b1218b9606d114f48282a15661a8a8051ca", + "8179617d64306417d6865add8b7be8452f1759721f97d737ef8a3c90da6551034049af781b6686b2ea99f87d376bce64", + "918e3da425b7c41e195ed7b726fa26b15a64299fe12a3c22f51a2a257e847611ac6cfcc99294317523fc491e1cbe60c4", + "a339682a37844d15ca37f753599d0a71eedfbbf7b241f231dd93e5d349c6f7130e0d0b97e6abd2d894f8b701da37cb11", + "8fc284f37bee79067f473bc8b6de4258930a21c28ac54aaf00b36f5ac28230474250f3aa6a703b6057f7fb79a203c2c1", + "a2c474e3a52a48cd1928e755f610fefa52d557eb67974d02287dbb935c4b9aab7227a325424fed65f8f6d556d8a46812", + "99b88390fa856aa1b8e615a53f19c83e083f9b50705d8a15922e7c3e8216f808a4cc80744ca12506b1661d31d8d962e4", + "a1cbd03e4d4f58fc4d48fa165d824b77838c224765f35d976d3107d44a6cf41e13f661f0e86f87589292721f4de703fb", + "b3a5dde8a40e55d8d5532beaa5f734ee8e91eafad3696df92399ae10793a8a10319b6dc53495edcc9b5cfd50a389a086", + "996e25e1df5c2203647b9a1744bd1b1811857f742aee0801508457a3575666fcc8fc0c047c2b4341d4b507008cd674c2", + "93e0a66039e74e324ee6c38809b3608507c492ef752202fff0b2c0e1261ca28f1790b3af4fdb236f0ed7e963e05c1ec0", + "b6084e5818d2d860ac1606d3858329fbad4708f79d51a6f072dc370a21fdb1e1b207b74bc265a8547658bfb6a9569bb3", + "a5336126a99c0ecfc890584b2a167922a26cae652dfc96a96ab2faf0bf9842f166b39ceaf396cd3d300d0ebb2e6e0ebf", + "b8b6f13ce9201decaba76d4eca9b9fa2e7445f9bc7dc9f82c262f49b15a40d45d5335819b71ff2ee40465da47d015c47", + "b45df257b40c68b7916b768092e91c72b37d3ed2a44b09bf23102a4f33348849026cb3f9fbb484adfea149e2d2a180ff", + "a50d38ee017e28021229c4bb7d83dd9cdad27ab3aa38980b2423b96aa3f7dc618e3b23895b0e1379ca20299ff1919bbf", + "97542cf600d34e4fdc07d074e8054e950708284ed99c96c7f15496937242365c66e323b0e09c49c9c38113096640a1b6", + "822d198629697dcd663be9c95ff1b39419eae2463fa7e6d996b2c009d746bedc8333be241850153d16c5276749c10b20", + "9217bc14974766ebdfbf6b434dd84b32b04658c8d8d3c31b5ff04199795d1cfad583782fd0c7438df865b81b2f116f9c", + "93477879fa28a89471a2c65ef6e253f30911da44260833dd51030b7a2130a923770ebd60b9120f551ab373f7d9ed80aa", + "87d89ff7373f795a3a798f03e58a0f0f0e7deab8db2802863fab84a7be64ae4dcf82ece18c4ddbefccd356262c2e8176", + "a3ba26bd31d3cc53ceeced422eb9a63c0383cde9476b5f1902b7fe2b19e0bbf420a2172ac5c8c24f1f5c466eecc615d4", + "a0fe061c76c90d84bd4353e52e1ef4b0561919769dbabe1679b08ef6c98dcfb6258f122bb440993d976c0ab38854386b", + "b3070aa470185cb574b3af6c94b4069068b89bb9f7ea7db0a668df0b5e6aabdfe784581f13f0cf35cd4c67726f139a8c", + "9365e4cdf25e116cbc4a55de89d609bba0eaf0df2a078e624765509f8f5a862e5da41b81883df086a0e5005ce1576223", + "a9036081945e3072fa3b5f022df698a8f78e62ab1e9559c88f9c54e00bc091a547467d5e2c7cbf6bc7396acb96dd2c46", + "8309890959fcc2a4b3d7232f9062ee51ece20c7e631a00ec151d6b4d5dfccf14c805ce5f9aa569d74fb13ae25f9a6bbe", + "b1dc43f07303634157f78e213c2fae99435661cc56a24be536ccbd345ef666798b3ac53c438209b47eb62b91d6fea90a", + "84eb451e0a74ef14a2c2266ff01bd33d9a91163c71f89d0a9c0b8edfcfe918fc549565509cd96eed5720a438ff55f7f2", + "9863b85a10db32c4317b19cc9245492b9389b318cf128d9bbc7ec80a694fcbbd3c0d3189a8cad00cc9290e67e5b361ee", + "8a150ee474ebe48bdfcac1b29e46ac90dcded8abbe4807a165214e66f780f424be367df5ef1e94b09acf4a00cd2e614d", + "a6677a373130b83e30849af12475e192f817ba4f3226529a9cca8baaefb8811db376e4a044b42bf1481268c249b1a66e", + "b969cbf444c1297aa50d1dfa0894de4565161cb1fc59ba03af9655c5bf94775006fe8659d3445b546538a22a43be6b93", + "8383167e5275e0707e391645dc9dea9e8a19640ecfa23387f7f6fcaddff5cde0b4090dfad7af3c36f8d5c7705568e8d8", + "a353ddbc6b6837773e49bb1e33a3e00ca2fb5f7e1dba3a004b0de75f94a4e90860d082a455968851ef050ae5904452e0", + "adeccf320d7d2831b495479b4db4aa0e25c5f3574f65a978c112e9981b2663f59de4c2fa88974fdcabb2eedb7adab452", + "afa0eacc9fdbe27fb5e640ecad7ecc785df0daf00fc1325af716af61786719dd7f2d9e085a71d8dc059e54fd68a41f24", + "a5b803a5bbe0ca77c8b95e1e7bacfd22feae9f053270a191b4fd9bca850ef21a2d4bd9bcd50ecfb971bb458ff2354840", + "b023c9c95613d9692a301ef33176b655ba11769a364b787f02b42ceb72338642655ea7a3a55a3eec6e1e3b652c3a179e", + "8fa616aa7196fc2402f23a19e54620d4cf4cf48e1adfb7ea1f3711c69705481ddcc4c97236d47a92e974984d124589e5", + "a49e11e30cb81cb7617935e8a30110b8d241b67df2d603e5acc66af53702cf1e9c3ef4a9b777be49a9f0f576c65dcc30", + "8df70b0f19381752fe327c81cce15192389e695586050f26344f56e451df2be0b1cdf7ec0cba7ce5b911dcff2b9325ae", + "8fbbc21a59d5f5a14ff455ca78a9a393cab91deb61cf1c25117db2714d752e0054ed3e7e13dd36ad423815344140f443", + "a9a03285488668ab97836a713c6e608986c571d6a6c21e1adbd99ae4009b3dde43721a705d751f1bd4ebf1ea7511dfed", + "b2f32b8e19e296e8402251df67bae6066aeefd89047586d887ffa2eacdf38e83d4f9dc32e553799024c7a41818945755", + "942cf596b2278ad478be5c0ab6a2ad0ceafe110263cc93d15b9a3f420932104e462cf37586c374f10b1040cb83b862e0", + "aaa077a55f501c875ceae0a27ef2b180be9de660ef3d6b2132eb17256771ce609d9bc8aaf687f2b56ae46af34ad12b30", + "90ac74885be1448101cf3b957d4486e379673328a006ea42715c39916e9334ea77117ff4a60d858e2ccce9694547a14f", + "9256cdfc2339e89db56fd04bd9b0611be0eefc5ee30711bcece4aadf2efcc5a6dcc0cfd5f733e0e307e3a58055dff612", + "a4c7384e208a0863f4c056248f595473dcde70f019ddaede45b8caf0752575c241bac6e436439f380ac88eee23a858e9", + "a3aa67391781e0736dddc389f86b430b2fc293b7bd56bfd5a8ec01d1dd52ed940593c3ad4ce25905061936da062b0af6", + "80299275ec322fbb66cc7dce4482ddd846534e92121186b6906c9a5d5834346b7de75909b22b98d73120caec964e7012", + "aa3a6cd88e5f98a12738b6688f54478815e26778357bcc2bc9f2648db408d6076ef73cced92a0a6b8b486453c9379f18", + "b07c444681dc87b08a7d7c86708b82e82f8f2dbd4001986027b82cfbed17b9043e1104ade612e8e7993a00a4f8128c93", + "af40e01b68d908ac2a55dca9b07bb46378c969839c6c822d298a01bc91540ea7a0c07720a098be9a3cfe9c27918e80e8", + "abd8947c3bbc3883c80d8c873f8e2dc9b878cbbb4fc4a753a68f5027de6d8c26aa8fbbafeb85519ac94e2db660f31f26", + "a234f9d1a8f0cb5d017ccca30b591c95ec416c1cb906bd3e71b13627f27960f61f41ed603ffbcf043fd79974ec3169a8", + "835aaf52a6af2bc7da4cf1586c1a27c72ad9de03c88922ad172dce7550d70f6f3efcc3820d38cd56ae3f7fc2f901f7a0", + "ae75db982a45ad01f4aa7bc50d642ff188219652bb8d521d13a9877049425d57852f3c9e4d340ffec12a4d0c639e7062", + "b88884aa9187c33dc784a96832c86a44d24e9ffe6315544d47fc25428f11337b9ffd56eb0a03ad709d1bf86175059096", + "8492ca5afcc6c0187b06453f01ed45fd57eb56facbeea30c93686b9e1dab8eaabd89e0ccb24b5f35d3d19cd7a58b5338", + "9350623b6e1592b7ea31b1349724114512c3cce1e5459cd5bddd3d0a9b2accc64ab2bf67a71382d81190c3ab7466ba08", + "98e8bf9bed6ae33b7c7e0e49fc43de135bffdba12b5dcb9ff38cb2d2a5368bb570fe7ee8e7fbe68220084d1d3505d5be", + "ab56144393f55f4c6f80c67e0ab68f445568d68b5aa0118c0c666664a43ba6307ee6508ba0bb5eb17664817bc9749af0", + "827d5717a41b8592cfd1b796a30d6b2c3ca2cdc92455f9f4294b051c4c97b7ad6373f692ddafda67884102e6c2a16113", + "8445ce2bb81598067edaa2a9e356eda42fb6dc5dd936ccf3d1ff847139e6020310d43d0fec1fe70296e8f9e41a40eb20", + "9405178d965ee51e8d76d29101933837a85710961bb61f743d563ef17263f3c2e161d57e133afac209cdb5c46b105e31", + "b209f9ed324c0daa68f79800c0a1338bbaf6d37b539871cb7570f2c235caca238a2c4407961fcb7471a103545495ef2c", + "92ae6437af6bbd97e729b82f5b0d8fb081ca822f340e20fae1875bdc65694cd9b8c037a5a1d49aa9cae3d33f5bad414e", + "9445bdb666eae03449a38e00851629e29a7415c8274e93343dc0020f439a5df0009cd3c4f5b9ce5c0f79aefa53ceac99", + "93fdab5f9f792eada28f75e9ac6042a2c7f3142ba416bfdb1f90aa8461dbe4af524eee6db4f421cb70c7bc204684d043", + "a7f4dc949af4c3163953320898104a2b17161f7be5a5615da684f881633174fb0b712d0b7584b76302e811f3fac3c12f", + "a8ac84da817b3066ba9789bf2a566ccf84ab0a374210b8a215a9dcf493656a3fa0ecf07c4178920245fee0e46de7c3ec", + "8e6a0ae1273acda3aa50d07d293d580414110a63bc3fb6330bb2ee6f824aff0d8f42b7375a1a5ba85c05bfbe9da88cb5", + "a5dea98852bd6f51a84fa06e331ea73a08d9d220cda437f694ad9ad02cf10657882242e20bdf21acbbaa545047da4ce5", + "b13f410bf4cfce0827a5dfd1d6b5d8eabc60203b26f4c88238b8000f5b3aaf03242cdeadc2973b33109751da367069e1", + "a334315a9d61b692ad919b616df0aa75a9f73e4ea6fc27d216f48964e7daebd84b796418580cf97d4f08d4a4b51037cd", + "8901ba9e963fcd2f7e08179b6d19c7a3b8193b78ca0e5cf0175916de873ca0d000cd7ac678c0473be371e0ac132f35a2", + "b11a445433745f6cb14c9a65314bbf78b852f7b00786501b05d66092b871111cd7bee25f702d9e550d7dd91601620abb", + "8c2f7b8e7b906c71f2f154cc9f053e8394509c37c07b9d4f21b4495e80484fc5fc8ab4bdc525bd6cfa9518680ba0d1a2", + "b9733cebe92b43b899d3d1bfbf4b71d12f40d1853b2c98e36e635fdd8a0603ab03119890a67127e6bc79afae35b0bef2", + "a560f6692e88510d9ba940371e1ada344caf0c36440f492a3067ba38e9b7011caac37ba096a8a4accb1c8656d3c019b3", + "ac18624339c1487b2626eef00d66b302bdb1526b6340d6847befe2fdfb2b410be5555f82939f8707f756db0e021ed398", + "afd9a3b8866a7fe4f7bc13470c0169b9705fcd3073685f5a6dcff3bdbbc2be50ac6d9908f9a10c5104b0bffc2bc14dad", + "97f15c92fe1f10949ed9def5dd238bc1429706e5037a0e0afb71c2d0e5845e2fed95a171c393e372077a7c7059f8c0e0", + "9453a1d4d09c309b70968ea527007d34df9c4cfd3048e5391aac5f9b64ca0c05dde5b8c949c481cfc83ef2e57b687595", + "b80e4b7c379ad435c91b20b3706253b763cbc980db78f782f955d2516af44c07bbfa5888cbf3a8439dc3907320feb25a", + "8939f458d28fefe45320b95d75b006e98330254056d063e4a2f20f04bcb25936024efe8d436d491ed34b482f9b9ae49c", + "a9ead2e833f71f7e574c766440c4b3c9c3363698c7ade14499a56003a272832ee6d99440887fa43ccdf80265b9d56b97", + "b6547a36934f05ce7b779e68049d61351cf229ae72dc211cc96a2a471b2724782f9355fdb415ea6f0ea1eb84fe00e785", + "828bfb3099b7b650b29b0f21279f829391f64520a6ab916d1056f647088f1e50fac9253ef7464eceab5380035c5a59c4", + "8d714b9ea650be4342ff06c0256189e85c5c125adf6c7aeca3dba9b21d5e01a28b688fc2116ce285a0714a8f1425c0b8", + "8a82eda041b2e72a3d73d70d85a568e035fbd6dc32559b6c6cfdf6f4edcb59a6ba85b6294a721aa0a71b07714e0b99ae", + "af5665ebc83d027173b14ffb0e05af0a192b719177889fadc9ac8c082fda721e9a75d9ce3f5602dbfd516600ee3b6405", + "a68fdddf03d77bebdb676e40d93e59bd854408793df2935d0a5600601f7691b879981a398d02658c2da39dbbf61ef96c", + "8c001ebc84fcf0470b837a08a7b6125126b73a2762db47bbdc38c0e7992b1c66bac7a64faa1bf1020d1c63b40adc3082", + "8553889b49f9491109792db0a69347880a9cf2911b4f16f59f7f424e5e6b553687d51282e8f95be6a543635247e2e2c2", + "a2c269d6370b541daf1f23cc6b5d2b03a5fa0c7538d53ae500ef875952fe215e74a5010329ff41461f4c58b32ad97b3d", + "a5dae097285392b4eba83a9fd24baa03d42d0a157a37fae4b6efc3f45be86024b1182e4a6b6eadcf5efe37704c0a1ae5", + "89871a77d2032387d19369933cd50a26bda643e40cfd0ce73febe717a51b39fae981406fd41e50f4a837c02a99524ef9", + "8a76d495e90093ec2ac22f53759dc1cf36fbb8370fb586acbd3895c56a90bbf3796bcc4fc422ca4058adf337ead1402e", + "ad4eb7576c4954d20623c1336c63662c2a6fb46ec6ef99b7f8e946aa47488dcb136eab60b35600f98c78c16c10c99013", + "894c2b120cec539feb1d281baaadde1e44beafedeeec29b804473fe024e25c1db652f151c956e88d9081fb39d27e0b19", + "9196bd5c100878792444c573d02b380a69e1b4b30cb59a48114852085058a5fd952df4afee3ecceb5c4ede21e1ed4a1a", + "a996fffc910764ea87a1eedc3a3d600e6e0ff70e6a999cb435c9b713a89600fc130d1850174efe9fc18244bb7c6c5936", + "8591bb8826befa8bee9663230d9a864a5068589f059e37b450e8c85e15ce9a1992f0ce1ead1d9829b452997727edcf9d", + "9465e20bb22c41bf1fa728be8e069e25cda3f7c243381ca9973cbedad0c7b07d3dd3e85719d77cf80b1058ce60e16d68", + "926b5ce39b6e60b94878ffeae9ff20178656c375fb9cfe160b82318ca500eb3e2e3144608b6c3f8d6c856b8fe1e2fbcf", + "a1ef29cbc83c45eb28ad468d0ce5d0fdd6b9d8191ba5ffa1a781c2b232ed23db6b7b04de06ef31763a6bfe377fa2f408", + "9328e63a3c8acf457c9f1f28b32d90d0eeadb0f650b5d43486a61d7374757a7ada5fc1def2a1e600fa255d8b3f48036f", + "a9c64880fcb7654f4dd08f4c90baac95712dd6dd407e17ea60606e9a97dc8e54dd25cb72a9bf3fc61f8d0ad569fe369d", + "a908eb7b940c1963f73046d6b35d40e09013bfbfbeb2ccd64df441867e202b0f3b625fa32dd04987c3d7851360abdffc", + "b3947b5ed6d59e59e4472cdb1c3261de1b5278fb7cb9b5fca553f328b3b3e094596861ea526eca02395f7b7358155b7b", + "99da7f190d37bc58945f981cf484d40fcf0855cf8178e2ce8d057c7f0a9d9f77425fdbce9ef8366f44f671b20fd27d0b", + "913976d77d80e3657977df39571577fdf0be68ba846883705b454f8493578baa741cfaede53783e2c97cc08964395d83", + "8d754a61e5164a80b5090c13f3e936056812d4ae8dc5cc649e6c7f37464777249bc4ae760a9806939131f39d92cca5bf", + "82ffd098480828a90cb221a8c28584e15904bad477c13b2e2d6ef0b96a861ce4a309a328fe44342365349456ad7c654f", + "89ae3ce4b0357044579ca17be85d8361bb1ce3941f87e82077dd67e43ec0f95edd4bd3426225c90994a81a99e79490b7", + "a170892074016d57c9d8e5a529379d7e08d2c1158b9ac4487ac9b95266c4fd51cb18ae768a2f74840137eec05000dd5a", + "aafd8acd1071103c7af8828a7a08076324d41ea530df90f7d98fafb19735fc27ead91b50c2ca45851545b41d589d0f77", + "8623c849e61d8f1696dc9752116a26c8503fd36e2cbbc9650feffdd3a083d8cdbb3b2a4e9743a84b9b2ad91ac33083f2", + "ac7166ddd253bb22cdbd8f15b0933c001d1e8bc295e7c38dc1d2be30220e88e2155ecd2274e79848087c05e137e64d01", + "a5276b216d3df3273bbfa46210b63b84cfe1e599e9e5d87c4e2e9d58666ecf1af66cb7ae65caebbe74b6806677215bd0", + "88792f4aa3597bb0aebadb70f52ee8e9db0f7a9d74f398908024ddda4431221a7783e060e0a93bf1f6338af3d9b18f68", + "8f5fafff3ecb3aad94787d1b358ab7d232ded49b15b3636b585aa54212f97dc1d6d567c180682cca895d9876cacb7833", + "ab7cb1337290842b33e936162c781aa1093565e1a5b618d1c4d87dd866daea5cebbcc486aaa93d8b8542a27d2f8694c7", + "88480a6827699da98642152ebc89941d54b4791fbc66110b7632fb57a5b7d7e79943c19a4b579177c6cf901769563f2f", + "a725ee6d201b3a610ede3459660658ee391803f770acc639cfc402d1667721089fb24e7598f00e49e81e50d9fd8c2423", + "98924372da8aca0f67c8c5cad30fa5324519b014fae7849001dcd51b6286118f12b6c49061219c37714e11142b4d46de", + "a62c27360221b1a7c99697010dfe1fb31ceb17d3291cf2172624ebeff090cbaa3c3b01ec89fe106dace61d934711d42d", + "825173c3080be62cfdc50256c3f06fe190bc5f190d0eb827d0af5b99d80936e284a4155b46c0d462ee574fe31d60983d", + "a28980b97023f9595fadf404ed4aa36898d404fe611c32fd66b70252f01618896f5f3fda71aea5595591176aabf0c619", + "a50f5f9def2114f6424ff298f3b128068438f40860c2b44e9a6666f43c438f1780be73cf3de884846f1ba67f9bef0802", + "b1eee2d730da715543aeb87f104aff6122cb2bf11de15d2519ff082671330a746445777924521ec98568635f26988d0c", + "862f6994a1ff4adfd9fb021925cccf542fca4d4b0b80fb794f97e1eb2964ef355608a98eec6e07aadd4b45ee625b2a21", + "8ce69a18df2f9b9f6e94a456a7d94842c61dea9b00892da7cf5c08144de9be39b8c304aeca8b2e4222f87ba367e61006", + "b5f325b1cecd435f5346b6bc562d92f264f1a6d91be41d612df012684fdd69e86063db077bc11ea4e22c5f2a13ae7bee", + "85526870a911127835446cb83db8986b12d5637d59e0f139ad6501ac949a397a6c73bd2e7fba731b1bb357efe068242c", + "8552247d3f7778697f77389717def5a149fc20f677914048e1ed41553b039b5427badc930491c0bae663e67668038fd1", + "a545640ee5e51f3fe5de7050e914cfe216202056cd9d642c90e89a166566f909ee575353cb43a331fde17f1c9021414e", + "8b51229b53cff887d4cab573ba32ec52668d197c084414a9ee5589b285481cea0c3604a50ec133105f661321c3ca50f5", + "8cdc0b960522bed284d5c88b1532142863d97bbb7dc344a846dc120397570f7bd507ceb15ed97964d6a80eccfef0f28e", + "a40683961b0812d9d53906e795e6470addc1f30d09affebf5d4fbbd21ddfa88ce441ca5ea99c33fd121405be3f7a3757", + "a527875eb2b99b4185998b5d4cf97dd0d4a937724b6ad170411fc8e2ec80f6cee2050f0dd2e6fee9a2b77252d98b9e64", + "84f3a75f477c4bc4574f16ebc21aaa32924c41ced435703c4bf07c9119dd2b6e066e0c276ff902069887793378f779e0", + "a3544bc22d1d0cab2d22d44ced8f7484bfe391b36991b87010394bfd5012f75d580596ffd4f42b00886749457bb6334b", + "b81f6eb26934b920285acc20ceef0220dd23081ba1b26e22b365d3165ce2fbae733bbc896bd0932f63dcc84f56428c68", + "95e94d40a4f41090185a77bf760915a90b6a3e3ace5e53f0cb08386d438d3aa3479f0cd81081b47a9b718698817265cd", + "b69bd1625b3d6c17fd1f87ac6e86efa0d0d8abb69f8355a08739109831baeec03fd3cd4c765b5ff8b1e449d33d050504", + "8448f4e4c043519d98552c2573b76eebf2483b82d32abb3e2bfc64a538e79e4f59c6ca92adff1e78b2f9d0a91f19e619", + "8f11c42d6a221d1fda50887fb68b15acdb46979ab21d909ed529bcad6ae10a66228ff521a54a42aca0dad6547a528233", + "a3adb18d7e4a882b13a067784cf80ea96a1d90f5edc61227d1f6e4da560c627688bdf6555d33fe54cab1bca242986871", + "a24d333d807a48dc851932ed21cbdd7e255bad2699909234f1706ba55dea4bb6b6f8812ffc0be206755868ba8a4af3f9", + "a322de66c22a606e189f7734dbb7fda5d75766d5e69ec04b4e1671d4477f5bcb9ff139ccc18879980ebc3b64ab4a2c49", + "88f54b6b410a1edbf125db738d46ee1a507e69bc5a8f2f443eb787b9aa7dbd6e55014ec1e946aabeb3e27a788914fb04", + "b32ee6da1dcd8d0a7fd7c1821bb1f1fe919c8922b4c1eeed56e5b068a5a6e68457c42b192cbaef5dc6d49b17fa45bc0f", + "8a44402da0b3a15c97b0f15db63e460506cb8bef56c457166aea5e8881087d8202724c539ef0feb97131919a73aefca8", + "b967e3fead6171fa1d19fd976535d428b501baff59e118050f9901a54b12cc8e4606348454c8f0fc25bd6644e0a5532e", + "b7a0c9e9371c3efbbb2c6783ce2cc5f149135175f25b6d79b09c808bce74139020e77f0c616fa6dcb3d87a378532529d", + "a54207782ffc909cd1bb685a3aafabbc4407cda362d7b3c1b14608b6427e1696817aeb4f3f85304ac36e86d3d8caa65b", + "98c1da056813a7bfebc81d8db7206e3ef9b51f147d9948c088976755826cc5123c239ca5e3fe59bed18b5d0a982f3c3f", + "ae1c86174dfafa9c9546b17b8201719aecd359f5bbeb1900475041f2d5b8a9600d54d0000c43dd061cfda390585726ff", + "a8ee5a8be0bd1372a35675c87bfd64221c6696dc16e2d5e0996e481fec5cdbcb222df466c24740331d60f0521285f7d3", + "8ddadbe3cf13af50d556ce8fc0dd77971ac83fad9985c3d089b1b02d1e3afc330628635a31707b32595626798ea22d45", + "a5c80254baf8a1628dc77c2445ebe21fbda0de09dd458f603e6a9851071b2b7438fe74214df293dfa242c715d4375c95", + "b9d83227ed2600a55cb74a7052003a317a85ca4bea50aa3e0570f4982b6fe678e464cc5156be1bd5e7bba722f95e92c5", + "b56085f9f3a72bea9aa3a8dc143a96dd78513fa327b4b9ba26d475c088116cab13843c2bff80996bf3b43d3e2bddb1d6", + "8fa9b39558c69a9757f1e7bc3f07295e4a433da3e6dd8c0282397d26f64c1ecd8eb3ba9824a7cacfb87496ebbb45d962", + "879c6d0cb675812ed9dee68c3479a499f088068501e2677caeae035e6f538da91a49e245f5fcce135066169649872bee", + "91aa9fd3fed0c2a23d1edda8a6542188aeb8abee8772818769bdee4b512d431e4625a343af5d59767c468779222cf234", + "a6be0bb2348c35c4143482c7ef6da9a93a5356f8545e8e9d791d6c08ed55f14d790d21ee61d3a56a2ae7f888a8fd46ca", + "808ee396a94e1b8755f2b13a6ffbedef9e0369e6c2e53627c9f60130c137299d0e4924d8ef367e0a7fad7f68a8c9193c", + "ad1086028fcdac94d5f1e7629071e7e47e30ad0190ae59aaebfb7a7ef6202ab91323a503c527e3226a23d7937af41a52", + "9102bdaf79b907d1b25b2ec6b497e2d301c8eac305e848c6276b392f0ad734131a39cc02ed42989a53ca8da3d6839172", + "8c976c48a45b6bc7cd7a7acea3c2d7c5f43042863b0661d5cd8763e8b50730552187a8eecf6b3d17be89110208808e77", + "a2624c7e917e8297faa3af89b701953006bf02b7c95dfba00c9f3de77748bc0b13d6e15bb8d01377f4d98fb189538142", + "a405f1e66783cdcfe20081bce34623ec3660950222d50b7255f8b3cc5d4369aeb366e265e5224c0204911539f0fa165e", + "8d69bdcaa5d883b5636ac8f8842026fcc58c5e2b71b7349844a3f5d6fbecf44443ef4f768eac376f57fb763606e92c9f", + "82fce0643017d16ec1c3543db95fb57bfa4855cc325f186d109539fcacf8ea15539be7c4855594d4f6dc628f5ad8a7b0", + "8860e6ff58b3e8f9ae294ff2487f0d3ffae4cf54fd3e69931662dabc8efd5b237b26b3def3bcd4042869d5087d22afcf", + "88c80c442251e11c558771f0484f56dc0ed1b7340757893a49acbf96006aa73dfc3668208abea6f65375611278afb02a", + "8be3d18c6b4aa8e56fcd74a2aacb76f80b518a360814f71edb9ccf3d144bfd247c03f77500f728a62fca7a2e45e504c5", + "8b8ebf0df95c3f9b1c9b80469dc0d323784fd4a53f5c5357bb3f250a135f4619498af5700fe54ad08744576588b3dfff", + "a8d88abdaadd9c2a66bc8db3072032f63ed8f928d64fdb5f810a65074efc7e830d56e0e738175579f6660738b92d0c65", + "a0a10b5d1a525eb846b36357983c6b816b8c387d3890af62efb20f50b1cb6dd69549bbef14dab939f1213118a1ae8ec2", + "8aadf9b895aeb8fdc9987daa937e25d6964cbd5ec5d176f5cdf2f0c73f6f145f0f9759e7560ab740bf623a3279736c37", + "99aeda8a495031cc5bdf9b842a4d7647c55004576a0edc0bd9b985d60182608361ed5459a9d4b21aa8e2bd353d10a086", + "832c8b3bfcd6e68eee4b100d58014522de9d4cefa99498bc06c6dca83741e4572e20778e0d846884b33439f160932bca", + "841f56ebefc0823ab484fc445d62f914e13957e47904419e42771aa605e33ab16c44f781f6f9aa42e3a1baf377f54b42", + "a6e40271d419e295a182725d3a9b541ffd343f23e37549c51ecaa20d13cf0c8d282d6d15b24def5702bfee8ba10b12ac", + "8ac00925ac6187a4c5cde48ea2a4eaf99a607e58b2c617ee6f01df30d03fafada2f0469178dd960d9d64cbd33a0087d8", + "b6b80916b540f8a0fe4f23b1a06e2b830008ad138271d5ba3cd16d6619e521fe2a7623c16c41cba48950793386eea942", + "8412c0857b96a650e73af9d93087d4109dd092ddf82188e514f18fcac644f44d4d62550bfa63947f2d574a2e9d995bbb", + "b871395baa28b857e992a28ac7f6d95ec461934b120a688a387e78498eb26a15913b0228488c3e2360391c6b7260b504", + "926e2d25c58c679be77d0e27ec3b580645956ba6f13adcbc2ea548ee1b7925c61fcf74c582337a3b999e5427b3f752f2", + "a165fa43fecae9b913d5dcfc232568e3e7b8b320ce96b13800035d52844c38fd5dbf7c4d564241d860c023049de4bcbc", + "b4976d7572fd9cc0ee3f24888634433f725230a7a2159405946a79315bc19e2fc371448c1c9d52bf91539fd1fe39574b", + "a6b461eb72e07a9e859b9e16dfa5907f4ac92a5a7ca4368b518e4a508dc43f9b4be59db6849739f3ef4c44967b63b103", + "b976606d3089345d0bc501a43525d9dca59cf0b25b50dfc8a61c5bd30fac2467331f0638fab2dc68838aa6ee8d2b6bc9", + "b16ea61c855da96e180abf7647fa4d9dd6fd90adebadb4c5ed4d7cd24737e500212628fca69615d89cb40e9826e5a214", + "95a3e3162eb5ea27a613f8c188f2e0dcc5cbd5b68c239858b989b004d87113e6aa3209fa9fad0ee6ecef42814ba9db1a", + "b6a026ab56d3224220e5bce8275d023c8d39d1bdf7eec3b0923429b7d5ef18cf613a3591d364be8727bb1fa0ba11eabb", + "949f117e2e141e25972ee9ccdd0b7a21150de7bbf92bbd89624a0c5f5a88da7b2b172ba2e9e94e1768081f260c2a2f8d", + "b7c5e9e6630287d2a20a2dfb783ffe6a6ff104ff627c6e4e4342acc2f3eb6e60e9c22f465f8a8dc58c42f49840eca435", + "872be5a75c3b85de21447bb06ac9eb610f3a80759f516a2f99304930ddf921f34cbffc7727989cdd7181d5fc62483954", + "a50976ea5297d797d220932856afdd214d1248230c9dcd840469ecc28ea9f305b6d7b38339fedb0c00b5251d77af8c95", + "80b360f8b44914ff6f0ffbd8b5360e3cabe08639f6fe06d0c1526b1fe9fe9f18c497f1752580b30e950abd3e538ad416", + "a2f98f9bf7fac78c9da6bb41de267742a9d31cf5a04b2fb74f551084ec329b376f651a59e1ae919b2928286fb566e495", + "8b9d218a8a6c150631548e7f24bbd43f132431ae275c2b72676abbea752f554789c5ff4aac5c0eeee5529af7f2b509ef", + "aa21a243b07e9c7b169598bf0b102c3c280861780f83121b2ef543b780d47aaa4b1850430ee7927f33ece9847c4e0e1a", + "8a6f90f4ce58c8aa5d3656fe4e05acccf07a6ec188a5f3cde7bf59a8ae468e66f055ac6dfc50b6e8e98f2490d8deedc5", + "8e39f77ca4b5149ffe9945ceac35d068760ba338d469d57c14f626dd8c96dbe993dd7011beff727c32117298c95ee854", + "83bd641c76504222880183edd42267e0582642c4993fe2c7a20ce7168e4c3cbf7586e1d2d4b08c84d9b0bf2f6b8800b8", + "a9d332993cf0c1c55130e5cf3a478eb5e0bfb49c25c07538accc692ef03d82b458750a7b991cc0b41b813d361a5d31e3", + "a0fc60e6a6015df9bee04cea8f20f01d02b14b6f7aa03123ab8d65da071b2d0df5012c2a69e7290baae6ed6dd29ebe07", + "a2949dde2e48788ceaac7ec7243f287ffe7c3e788cdba97a4ab0772202aeef2d50382bed8bf7eff5478243f7eabe0bda", + "a7879373ea18572dba6cf29868ca955ffa55b8af627f29862f6487ee398b81fe3771d8721ca8e06716c5d91b9ac587cb", + "b3c7081e2c5306303524fbe9fe5645111a57dffd4ec25b7384da12e56376a0150ab52f9d9cc6ca7bdd950695e39b766d", + "a634a6a19d52dcb9f823352b36c345d2de54b75197bcd90528d27830bd6606d1a9971170de0849ed5010afa9f031d5be", + "88f2062f405fa181cfdb8475eaf52906587382c666ca09a9522537cfebbc7de8337be12a7fd0db6d6f2f7ab5aefab892", + "b1f0058c1f273191247b98783b2a6f5aa716cf799a8370627fc3456683f03a624d0523b63a154fe9243c0dfd5b37c460", + "ae39a227cc05852437d87be6a446782c3d7fbe6282e25cf57b6b6e12b189bdc0d4a6e2c3a60b3979256b6b5baf8f1c5f", + "802a1af228ab0c053b940e695e7ef3338f5be7acf4e5ed01ac8498e55b492d3a9f07996b1700a84e22f0b589638909cd", + "a36490832f20e4b2f9e79ee358b66d413f034d6a387534b264cdeac2bca96e8b5bcbdd28d1e98c44498032a8e63d94d2", + "8728c9a87db2d006855cb304bba54c3c704bf8f1228ae53a8da66ca93b2dac7e980a2a74f402f22b9bc40cd726e9c438", + "a08f08ab0c0a1340e53b3592635e256d0025c4700559939aeb9010ed63f7047c8021b4210088f3605f5c14fb51d1c613", + "9670fd7e2d90f241e8e05f9f0b475aa260a5fb99aa1c9e61cd023cbad8ed1270ae912f168e1170e62a0f6d319cf45f49", + "a35e60f2dd04f098bf274d2999c3447730fe3e54a8aff703bc5a3c274d22f97db4104d61a37417d93d52276b27ef8f31", + "859df7a21bc35daec5695201bd69333dc4f0f9e4328f2b75a223e6615b22b29d63b44d338413ca97eb74f15563628cb7", + "b2b44ad3e93bc076548acdf2477803203108b89ecc1d0a19c3fb9814d6b342afc420c20f75e9c2188ad75fdb0d34bb2d", + "941173ee2c87765d10758746d103b667b1227301e1bcfecef2f38f9ab612496a9abd3050cef5537bf28cfecd2aacc449", + "92b0bea30ebed20ac30648efb37bac2b865daaa514316e6f5470e1de6cb84651ff77c127aa7beed4521bda5e8fc81122", + "af17bf813bb238cf8bb437433f816786612209180a6c0a1d5141292dc2d2c37164ef13bfc50c718bfcc6ce26369298a2", + "8461fd951bdfda099318e05cc6f75698784b033f15a71bce26165f0ce421fd632d50df9eeced474838c0050b596e672c", + "83281aa18ae4b01e8201e1f64248cc6444c92ee846ae72adb178cef356531558597d84ff93a05abf76bfe313eb7dbe86", + "b62b150f73999c341daa4d2f7328d2f6ca1ef3b549e01df58182e42927537fc7971c360fe8264af724f4c0247850ef12", + "a7022a201f79c012f982b574c714d813064838a04f56964d1186691413757befeeaada063e7884297606e0eea1b1ed43", + "a42ac9e8be88e143853fd8e6a9ff21a0461801f0ac76b69cca669597f9af17ecb62cccdcdcbe7f19b62ab93d7f838406", + "80f1ca73b6ba3a2fbae6b79b39c0be8c39df81862d46c4990c87cbf45b87996db7859d833abc20af2fcb4faf059c436a", + "b355943e04132d5521d7bbe49aea26f6aa1c32f5d0853e77cc2400595325e923a82e0ff7601d1aee79f45fd8a254f6ae", + "87142c891d93e539b31d0b5ead9ea600b9c84db9be9369ff150a8312fe3d10513f4c5b4d483a82b42bc65c45dd9dd3bd", + "823c3d7f6dda98a9d8c42b3fee28d3154a95451402accadb6cf75fc45d2653c46a569be75a433094fa9e09c0d5cf1c90", + "b3c3497fe7356525c1336435976e79ec59c5624c2fb6185ee09ca0510d58b1e392965e25df8a74d90d464c4e8bb1422b", + "88c48d83e8ddc0d7eea051f3d0e21bc0d3a0bb2b6a39ece76750c1c90c382a538c9a35dc9478b8ceb8157dcccbbf187a", + "93da81a8939f5f58b668fefdc6f5f7eca6dc1133054de4910b651f8b4a3267af1e44d5a1c9e5964dc7ab741eb146894b", + "8b396e64985451ac337f16be61105106e262e381ea04660add0b032409b986e1ac64da3bc2feae788e24e9cb431d8668", + "9472068b6e331ea67e9b5fbf8057672da93c209d7ded51e2914dbb98dccd8c72b7079b51fd97a7190f8fc8712c431538", + "ac47e1446cb92b0a7406f45c708567f520900dfa0070d5e91783139d1bfc946d6e242e2c7b3bf4020500b9f867139709", + "896053706869fb26bb6f7933b3d9c7dd6db5c6bd1269c7a0e222b73039e2327d44bda7d7ae82bf5988808b9831d78bcd", + "a55e397fa7a02321a9fe686654c86083ecedb5757586d7c0250ec813ca6d37151a12061d5feca4691a0fd59d2f0fdd81", + "ae23f08ac2b370d845036518f1bddb7fea8dc59371c288a6af310486effeb61963f2eef031ca90f9bdbcf0e475b67068", + "b5462921597a79f66c0fec8d4c7cfd89f427692a7ce30d787e6fd6acd2377f238ec74689a0fdbe8ef3c9c9bd24b908dc", + "ae67e8ea7c46e29e6aae6005131c29472768326819aa294aaf5a280d877de377b44959adb1348fa3e929dcbc3ae1f2c0", + "84962b4c66500a20c4424191bdfb619a46cda35bdb34c2d61edcb0b0494f7f61dd5bf8f743302842026b7b7d49edd4b5", + "846f76286dc3cc59cb15e5dabb72a54a27c78190631df832d3649b2952fa0408ecde7d4dfdae7046c728efa29879fb51", + "8f76c854eaee8b699547e07ad286f7dadfa6974c1328d12502bd7630ae619f6129272fdd15e2137ffef0143c42730977", + "8007b163d4ea4ec6d79e7a2aa19d06f388da0b3a56f3ee121441584e22a246c0e792431655632bf6e5e02cb86914eebf", + "ac4d2cecc1f33e6fb73892980b61e62095ddff5fd6167f53ca93d507328b3c05440729a277dc3649302045b734398af1", + "92d2a88f2e9c9875abaff0d42624ccb6d65401de7127b5d42c25e6adccd7a664504c5861618f9031ced8aeb08b779f06", + "a832c1821c1b220eb003fc532af02c81196e98df058cdcc9c9748832558362915ea77526937f30a2f74f25073cb89afb", + "b6f947ab4cc2baec100ed8ec7739a2fd2f9504c982b39ab84a4516015ca56aea8eef5545cfc057dd44c69b42125fb718", + "b24afacf2e90da067e5c050d2a63878ee17aaf8fd446536f2462da4f162de87b7544e92c410d35bf2172465940c19349", + "b7a0aa92deac71eaab07be8fa43086e071e5580f5dbf9b624427bdd7764605d27303ae86e5165bed30229c0c11958c38", + "b0d1d5bfa1823392c5cf6ed927c1b9e84a09a24b284c2cd8fcb5fda8e392c7c59412d8f74eb7c48c6851dff23ae66f58", + "a24125ef03a92d2279fb384186ca0274373509cfec90b34a575490486098438932ee1be0334262d22d5f7d3db91efe67", + "83e08e5fba9e8e11c164373794f4067b9b472d54f57f4dbe3c241cf7b5b7374102de9d458018a8c51ab3aed1dddf146f", + "9453101b77bb915ed40990e1e1d2c08ea8ec5deb5b571b0c50d45d1c55c2e2512ec0ceca616ff0376a65678a961d344d", + "92a0516e9eb6ad233d6b165a8d64a062ce189b25f95d1b3264d6b58da9c8d17da2cd1f534800c43efcf2be73556cd2ff", + "958d0b5d7d8faf25d2816aa6a2c5770592ad448db778dd9b374085baa66c755b129822632eaabcb65ee35f0bf4b73634", + "90a749de8728b301ad2a6b044e8c5fd646ccd8d20220e125cba97667e0bb1d0a62f6e3143b28f3d93f69cdc6aa04122a", + "84bd34c8d8f74dec07595812058db24d62133c11afed5eb2a8320d3bfc28e442c7f0cfd51011b7b0bb3e5409cb7b6290", + "aecc250b556115d97b553ad7b2153f1d69e543e087890000eaa60f4368b736921d0342ce5563124f129096f5d5e2ca9d", + "977f17ac82ed1fbf422f9b95feb3047a182a27b00960296d804fd74d54bb39ad2c055e665c1240d2ad2e06a3d7501b00", + "af5be9846bd4879ebe0af5e7ad253a632f05aedfe306d31fe6debe701ba5aa4e33b65efc05043bc73aadb199f94baed4", + "9199e12ec5f2aaaeed6db5561d2dcc1a8fe9c0854f1a069cba090d2dff5e5ba52b10c841ccbd49006a91d881f206150d", + "8f4a96a96ed8ceaf3beba026c89848c9ca4e6452ce23b7cf34d12f9cc532984a498e051de77745bdc17c7c44c31b7c30", + "af3f2a3dbe8652c4bfca0d37fb723f0e66aab4f91b91a625114af1377ad923da8d36da83f75deb7a3219cd63135a3118", + "a6d46963195df8962f7aa791d104c709c38caa438ddd192f7647a884282e81f748c94cdf0bb25d38a7b0dc1b1d7bbcf7", + "86f3de4b22c42d3e4b24b16e6e8033e60120af341781ab70ae390cb7b5c5216f6e7945313c2e04261a51814a8cb5db92", + "b9f86792e3922896cfd847d8ff123ff8d69ecf34968fb3de3f54532f6cd1112b5d34eeabdca46ae64ad9f6e7e5b55edc", + "83edfbcbc4968381d1e91ab813b3c74ab940eaf6358c226f79182f8b21148ec130685fd91b0ea65916b0a50bccf524ea", + "93b61daca7a8880b7926398760f50016f2558b0bab74c21181280a1baf3414fc539911bb0b79c4288d29d3c4ad0f4417", + "ad541aeb83a47526d38f2e47a5ce7e23a9adabe5efeae03541026881e6d5ef07da3ac1a6ed466ca924fa8e7a91fcff88", + "ac4bba31723875025640ed6426003ed8529215a44c9ffd44f37e928feef9fc4dfa889088131c9be3da87e8f3fdf55975", + "88fa4d49096586bc9d29592909c38ea3def24629feacd378cc5335b70d13814d6dac415f8c699ee1bf4fe8b85eb89b38", + "b67d0b76cbd0d79b71f4673b96e77b6cda516b8faa1510cfe58ff38cc19000bb5d73ff8418b3dab8c1c7960cb9c81e36", + "98b4f8766810f0cfecf67bd59f8c58989eb66c07d3dfeee4f4bbce8fd1fce7cc4f69468372eaec7d690748543bd9691d", + "8445891af3c298b588dec443beacdf41536adb84c812c413a2b843fd398e484eb379075c64066b460839b5fe8f80177c", + "b603635c3ed6fdc013e2a091fc5164e09acf5f6a00347d87c6ebadb1f44e52ff1a5f0466b91f3f7ffc47d25753e44b75", + "87ec2fc928174599a9dafe7538fec7dcf72e6873b17d953ed50708afff0da37653758b52b7cafa0bf50dfcf1eafbb46c", + "b9dbd0e704d047a457d60efe6822dc679e79846e4cbcb11fa6c02079d65673ee19bbf0d14e8b7b200b9205f4738df7c7", + "9591ec7080f3f5ba11197a41f476f9ba17880f414d74f821a072ec5061eab040a2acba3d9856ff8555dfe5eaeb14ca19", + "b34c9d1805b5f1ce38a42b800dec4e7f3eb8c38e7d2b0a525378e048426fed150dbfe9cc61f5db82b406d1b9ff2d10bf", + "a36fdc649dc08f059dfa361e3969d96b4cc4a1ebf10b0cd01a7dd708430979e8d870961fef85878f8779b8e23caafb18", + "88dfc739a80c16c95d9d6f73c3357a92d82fa8c3c670c72bee0f1e4bac9ec338e1751eb786eda3e10f747dd7a686900f", + "84a535ad04f0961756c61c70001903a9adf13126983c11709430a18133c4b4040d17a33765b4a06968f5d536f4bfb5c5", + "8c86d695052a2d2571c5ace744f2239840ef21bb88e742f050c7fa737cd925418ecef0971333eb89daa6b3ddfede268c", + "8e9a700157069dc91e08ddcbdde3a9ad570272ad225844238f1015004239c542fceb0acce6d116c292a55f0d55b6175e", + "84d659e7f94e4c1d15526f47bc5877a4ef761c2a5f76ec8b09c3a9a30992d41b0e2e38ed0c0106a6b6c86d670c4235f3", + "a99253d45d7863db1d27c0ab561fb85da8c025ba578b4b165528d0f20c511a9ca9aff722f4ff7004843f618eb8fced95", + "89a3cacb15b84b20e95cd6135550146bbe6c47632cc6d6e14d825a0c79b1e02b66f05d57d1260cb947dc4ae5b0283882", + "8385b1555e794801226c44bd5e878cbe68aeac0a19315625a8e5ea0c3526b58cdd4f53f9a14a167a5e8a293b530d615a", + "b68c729e9df66c5cd22af4909fb3b0057b6a231c4a31cd6bf0fa0e53c5809419d15feb483de6e9408b052458e819b097", + "924f56eda269ec7ec2fc20c5731bf7f521546ddf573ccbe145592f1c9fee5134747eb648d9335119a8066ca50a1f7e50", + "b2100a26b9c3bec7ec5a53f0febbf56303f199be2f26b2d564cfee2adc65483b84192354f2865c2f4c035fa16252ae55", + "8f64dbed62e638563967ec1605a83216aed17eb99aa618c0543d74771ea8f60bbb850c88608d4f8584f922e30a8a0a72", + "b31b9e1ffe8d7260479c9413f8e680f3fe391ae8fcf44fcca3000d9b2473a40c1d32299f8f63865a57579a2d6c7e9f08", + "a5b1d136142eb23e322c6c07cb838a3f58ab6925472352ebd0bb47041a0d8729e1074ca223922f3a7a672ced7a1e562d", + "8d9470a5a15d833a447b5f108333d50f30aa7659e331c3f8080b1e928a99922edc650466a2f54f3d48afdb34bff42142", + "866368f5891564e5b2de37ad21ff0345c01129a14ea5667f9b64aad12d13ec034622872e414743af0bf20adb2041b497", + "88ef9c2ebf25fd0c04b7cfa35fbac2e4156d2f1043fa9f98998b2aa402c8f9a4f1039e782451a46840f3e0e4b3fa47d3", + "94ba04a4859273697e264a2d238dc5c9ff573ebc91e4796ea58eebe4080c1bf991255ab2ad8fb1e0301ce7b79cc6e69b", + "86b6bd0953309a086e526211bf1a99327269304aa74d8cdc994cee63c3a2d4b883e832b0635888dff2a13f1b02eb8df4", + "843ea6ea5f2c7a1fd50be56a5765dcce3ea61c99b77c1a729ee0cd8ec706385ac7062e603479d4c8d3527f030762d049", + "8d3675195a3b06f2d935d45becc59f9fa8fa440c8df80c029775e47fe9c90e20f7c8e4cc9a2542dd6bfe87536c428f0d", + "8978580b0c9b0aa3ab2d47e3cfd92fa891d3ddee57829ee4f9780e8e651900457d8e759d1a9b3e8f6ae366e4b57f2865", + "890112ec81d0f24b0dfbb4d228e418eff02ae63dc691caf59c1d103e1d194e6e2550e1bec41c0bfdb74fed454f621d0c", + "97da00bd4b19d1e88caff7f95b8b9a7d29bc0afe85d0c6a163b4b9ef336f0e90e2c49ce6777024bb08df908cc04ea1ca", + "b458268d275a5211106ccaa8333ce796ef2939b1c4517e502b6462e1f904b41184a89c3954e7c4f933d68b87427a7bfd", + "aac9c043ba8ba9283e8428044e6459f982413380ee7005a996dc3cc468f6a21001ecaa3b845ce2e73644c2e721940033", + "82145013c2155a1200246a1e8720adf8a1d1436b10d0854369d5b1b6208353e484dd16ce59280c6be84a223f2d45e5e2", + "b301bafa041f9b203a46beab5f16160d463aa92117c77a3dc6a9261a35645991b9bafcc186c8891ca95021bd35f7f971", + "a531b8d2ac3de09b92080a8d8857efa48fb6a048595279110e5104fee7db1dd7f3cfb8a9c45c0ed981cbad101082e335", + "a22ac1d627d08a32a8abd41504b5222047c87d558ffae4232cefdeb6a3dc2a8671a4d8ddfba2ff9068a9a3ffb0fe99b1", + "b8d9f0e383c35afb6d69be7ff04f31e25c74dd5751f0e51290c18814fbb49ee1486649e64355c80e93a3d9278bd21229", + "8165babccd13033a3614c878be749dfa1087ecbeee8e95abcfffe3aa06695711122cb94477a4d55cffd2febf0c1173de", + "a4c1bc84ecb9d995d1d21c2804adf25621676d60334bd359dac3a2ec5dc8de567aa2831c10147034025fb3e3afb33c4b", + "b77307cab8e7cb21e4038493058fb6db9e2ec91dda9d7f96f25acbc90309daf7b6d8a205682143ee35d675e9800c3b08", + "aaf7466083cd1f325ba860efe3faf4cebe6a5eecf52c3e8375d72043a5cfc8e6cb4b40f8e48f97266e84f0d488e8badf", + "9264a05a3abc2a5b4958f957f3a486a5eb3ddd10ff57aa6943c9430d0cfa01d63b72695b1ade50ac1b302d312175e702", + "b3f9e4c589ad28b1eceed99dc9980fac832524cfcbe4a486dfeedb4b97c080e24bdb3967e9ca63d2240e77f9addfaefd", + "b2c1e253a78e7179e5d67204422e0debfa09c231970b1bfb70f31a8d77c7f5059a095ca79d2e9830f12c4a8f88881516", + "81865a8a25913d1072cb5fd9505c73e0fde45e4c781ddd20fb0a7560d8b1cd5e1f63881c6efc05360e9204dfa6c3ce16", + "ab71c2ea7fa7853469a2236dedb344a19a6130dc96d5fd6d87d42d3fffda172557d203b7688ce0f86acd913ce362e6cd", + "8aa2051bc3926c7bd63565f3782e6f77da824cb3b22bb056aa1c5bccfa274c0d9e49a91df62d0e88876e2bd7776e44b9", + "b94e7074167745323d1d353efe7cfb71f40a390e0232354d5dfd041ef523ac8f118fb6dcc42bf16c796e3f61258f36f8", + "8210fcf01267300cb1ccf650679cf6e1ee46df24ae4be5364c5ff715332746c113d680c9a8be3f17cacaeb3a7ba226ce", + "905ac223568eedc5acd8b54e892be05a21abbb4083c5dbec919129f9d9ffa2c4661d78d43bf5656d8d7aafa06f89d647", + "a6e93da7e0c998e6ce2592d1aa87d12bf44e71bec12b825139d56682cdce8f0ba6dbfe9441a9989e10578479351a3d9d", + "acde928a5e2df0d65de595288f2b81838155d5673013100a49b0cb0eb3d633237af1378148539e33ccd1b9a897f0fec3", + "a6e1a47e77f0114be6ae7acd2a51e6a9e38415cce7726373988153cdd5d4f86ef58f3309adc5681af4a159300ed4e5b5", + "ad2b6a0d72f454054cb0c2ebc42cd59ff2da7990526bd4c9886003ba63b1302a8343628b8fe3295d3a15aa85150e0969", + "b0bc3aea89428d7918c2ee0cc57f159fba134dad224d0e72d21a359ca75b08fbb4373542f57a6408352033e1769f72c6", + "aad0497525163b572f135fad23fdd8763631f11deeaf61dea5c423f784fe1449c866040f303555920dc25e39cdb2e9b4", + "8ce5d8310d2e17342bf881d517c9afc484d12e1f4b4b08ad026b023d98cba410cd9a7cc8e2c3c63456652a19278b6960", + "8d9d57dbb24d68b6152337872bd5d422198da773174ade94b633f7c7f27670ff91969579583532ae7d8fe662c6d8a3b0", + "855a1c2d83becb3f02a8f9a83519d1cb112102b61d4cdd396844b5206e606b3fefdbcc5aa8751da2b256d987d74d9506", + "90eb7e6f938651f733cf81fcd2e7e8f611b627f8d94d4ac17ac00de6c2b841e4f80cada07f4063a13ae87b4a7736ca28", + "8161459a21d55e7f5f1cecfc1595c7f468406a82080bfa46d7fb1af4b5ec0cd2064c2c851949483db2aa376e9df418e6", + "8344ccd322b2072479f8db2ab3e46df89f536408cba0596f1e4ec6c1957ff0c73f3840990f9028ae0f21c1e9a729d7df", + "929be2190ddd54a5afe98c3b77591d1eae0ab2c9816dc6fe47508d9863d58f1ea029d503938c8d9e387c5e80047d6f1e", + "856e3d1f701688c650c258fecd78139ce68e19de5198cf1cd7bb11eba9d0f1c5af958884f58df10e3f9a08d8843f3406", + "8490ae5221e27a45a37ca97d99a19a8867bcc026a94f08bdccfbb4b6fa09b83c96b37ec7e0fd6ee05f4ae6141b6b64a8", + "b02dbd4d647a05ac248fda13708bba0d6a9cd00cae5634c1938b4c0abbb3a1e4f00f47aa416dcd00ffcdf166330bff9a", + "9076164bb99ca7b1a98d1e11cb2f965f5c22866658e8259445589b80e3cb3119c8710ede18f396ba902696785619079c", + "aacf016920936dae63778ad171386f996f65fe98e83cfcdd75e23774f189303e65cc8ad334a7a62f9230ed2c6b7f6fa4", + "a8031d46c7f2474789123469ef42e81c9c35eb245d38d8f4796bba406c02b57053f5ec554d45373ab437869a0b1af3f0", + "a4b76cd82dc1f305a0ee053e9a4212b67f5acc5e69962a8640d190a176b73fbc2b0644f896ff3927cd708d524668ed09", + "b00b029c74e6fdf7fb94df95ef1ccad025c452c19cddb5dccfb91efdcb8a9a1c17847cfa4486eae4f510e8a6c1f0791a", + "9455e5235f29a73e9f1a707a97ddb104c55b9d6a92cc9952600d49f0447d38ea073ee5cf0d13f7f55f12b4a5132f4b10", + "ae118847542ed1084d269e8f3b503d0b6571a2c077def116ad685dcca2fca3dcb3f86e3f244284bdcd5ae7ac968d08a5", + "8dcb4965cd57e8b89cd71d6fc700d66caa805bfd29ab71357961527a7894e082d49145c2614b670dcb231ab9050d0663", + "add6ed14f3183f4acc73feea19b22c9a330e431c674e5034924da31b69e8c02d79b570d12ef771a04215c4809e0f8a80", + "96ae7e110412ee87d0478fdbdbaab290eb0b6edd741bb864961845e87fd44bcbe630371060b8104d8bf17c41f2e3fca0", + "a20db17f384e9573ca0928af61affab6ff9dd244296b69b026d737f0c6cd28568846eca8dadf903ee0eecbb47368351d", + "937bfdf5feb0797863bc7c1be4dcc4f2423787952a3c77dfa3bfe7356f5dbcc4daebde976b84fc6bd97d5124fb8f85c9", + "a7050cc780445c124e46bba1acc0347ddcfa09a85b35a52cc5808bf412c859c0c680c0a82218f15a6daeefe73f0d0309", + "a9d9b93450e7630f1c018ea4e6a5ca4c19baa4b662eadfbe5c798fe798d8a3775ed1eb12bd96a458806b37ab82bdc10a", + "a52a4d5639e718380915daaefad7de60764d2d795443a3db7aeab5e16a1b8faa9441a4ccc6e809d8f78b0ac13eef3409", + "8e6f72b6664a8433b032849b03af68f9376b3c16c0bc86842c43fc7bf31e40bc9fc105952d5c5780c4afa19d7b802caa", + "a107ae72f037000c6ee14093de8e9f2c92aa5f89a0a20007f4126419e5cb982469c32187e51a820f94805c9fccd51365", + "9708218f9a984fe03abc4e699a4f3378a06530414a2e95e12ca657f031ef2e839c23fd83f96a4ba72f8203d54a1a1e82", + "b9129770f4c5fcac999e98c171d67e148abd145e0bf2a36848eb18783bb98dff2c5cef8b7407f2af188de1fae9571b1c", + "88cc9db8ff27eb583871eeeb517db83039b85404d735517c0c850bdfa99ae1b57fd24cf661ab60b4726878c17e047f37", + "a358c9aadc705a11722df49f90b17a2a6ba057b2e652246dc6131aaf23af66c1ca4ac0d5f11073a304f1a1b006bc0aa5", + "ac79f25af6364a013ba9b82175ccee143309832df8f9c3f62c193660253679284624e38196733fb2af733488ab1a556e", + "82338e3ed162274d41a1783f44ae53329610134e6c62565353fbcc81131e88ce9f8a729d01e59e6d73695a378315111b", + "aa5ddcabf580fd43b6b0c3c8be45ffd26c9de8fa8d4546bb92d34f05469642b92a237d0806a1ad354f3046a4fcf14a92", + "b308d2c292052a8e17862c52710140ffafa0b3dbedd6a1b6334934b059fe03e49883529d6baf8b361c6e67b3fbf70100", + "96d870a15c833dddd8545b695139733d4a4c07d6206771a1524500c12607048731c49ec4ac26f5acc92dd9b974b2172c", + "8e99ee9ed51956d05faaf5038bffd48a2957917a76d9974a78df6c1ff3c5423c5d346778f55de07098b578ad623a390e", + "a19052d0b4b89b26172c292bbf6fd73e7486e7fd3a63c7a501bbd5cf7244e8e8ce3c1113624086b7cdf1a7693fdad8b5", + "958957caf99dc4bb6d3c0bc4821be10e3a816bd0ba18094603b56d9d2d1383ccc3ee8bc36d2d0aea90c8a119d4457eb4", + "8482589af6c3fc4aa0a07db201d8c0d750dd21ae5446ff7a2f44decf5bff50965fd6338745d179c67ea54095ecd3add4", + "8a088cc12cf618761eaa93da12c9158b050c86f10cd9f865b451c69e076c7e5b5a023e2f91c2e1eed2b40746ca06a643", + "85e81101590597d7671f606bd1d7d6220c80d3c62e9f20423e734482c94547714a6ac0307e86847cce91de46503c6a8a", + "b1bd39b481fc452d9abf0fcb73b48c501aaae1414c1c073499e079f719c4e034da1118da4ff5e0ce1c5a71d8af3f4279", + "942ae5f64ac7a5353e1deb2213f68aa39daa16bff63eb5c69fc8d9260e59178c0452227b982005f720a3c858542246c8", + "99fea18230e39df925f98e26ff03ab959cae7044d773de84647d105dfa75fd602b4f519c8e9d9f226ec0e0de0140e168", + "97b9841af4efd2bfd56b9e7cd2275bc1b4ff5606728f1f2b6e24630dbe44bc96f4f2132f7103bca6c37057fc792aeaab", + "94cdad044a6ab29e646ed30022c6f9a30d259f38043afcea0feceef0edc5f45297770a30718cbfec5ae7d6137f55fe08", + "a533a5efa74e67e429b736bb60f2ccab74d3919214351fe01f40a191e3ec321c61f54dd236f2d606c623ad556d9a8b63", + "b7bd0bb72cd537660e081f420545f50a6751bb4dd25fde25e8218cab2885dd81ffe3b888d608a396dfcb78d75ba03f3f", + "b1479e7aa34594ec8a45a97611d377206597149ece991a8cef1399738e99c3fa124a40396a356ab2ea135550a9f6a89f", + "b75570fc94b491aef11f70ef82aeb00b351c17d216770f9f3bd87f3b5ac90893d70f319b8e0d2450dc8e21b57e26df94", + "a5e3f3ab112530fe5c3b41167f7db5708e65479b765b941ce137d647adb4f03781f7821bb4de80c5dc282c6d2680a13d", + "b9b9c81b4cac7aca7e7c7baac2369d763dd9846c9821536d7467b1a7ec2e2a87b22637ab8bbeddb61879a64d111aa345", + "b1e3ee2c4dd03a60b2991d116c372de18f18fe279f712829b61c904103a2bd66202083925bc816d07884982e52a03212", + "a13f0593791dbbd360b4f34af42d5cc275816a8db4b82503fe7c2ff6acc22ae4bd9581a1c8c236f682d5c4c02cc274cc", + "86ba8238d3ed490abcc3f9ecc541305876315fb71bca8aaf87538012daab019992753bf1e10f8670e33bff0d36db0bf0", + "b65fbb89fafb0e2a66fe547a60246d00b98fe2cb65db4922d9cef6668de7b2f4bb6c25970f1e112df06b4d1d953d3f34", + "abb2d413e6f9e3c5f582e6020f879104473a829380b96a28123eb2bdd41a7a195f769b6ac70b35ba52a9fee9d6a289c3", + "88ec764573e501c9d69098a11ea1ad20cdc171362f76eb215129cfcca43460140741ea06cee65a1f21b708afb6f9d5b0", + "a7aaec27246a3337911b0201f4c5b746e45780598004dac15d9d15e5682b4c688158adffdef7179abb654f686e4c6adc", + "a1128589258f1fbfa33341604c3cb07f2a30c651086f90dce63ae48b4f01782e27c3829de5102f847cde140374567c58", + "aaf2b149c1ca9352c94cc201125452b1ed7ca7c361ed022d626899426cb2d4cc915d76c58fa58b3ad4a6284a9ae1bc45", + "aaf5c71b18b27cd8fe1a9028027f2293f0753d400481655c0d88b081f150d0292fb9bd3e6acabb343a6afb4afdb103b5", + "947c0257d1fb29ecc26c4dc5eab977ebb47d698b48f9357ce8ff2d2ed461c5725228cc354a285d2331a60d20de09ff67", + "b73e996fa30f581699052ed06054c474ebdf3ae662c4dc6f889e827b8b6263df67aeff7f2c7f2919df319a99bdfdceb1", + "b696355d3f742dd1bf5f6fbb8eee234e74653131278861bf5a76db85768f0988a73084e1ae03c2100644a1fa86a49688", + "b0abca296a8898ac5897f61c50402bd96b59a7932de61b6e3c073d880d39fc8e109998c9dba666b774415edddcff1997", + "b7abe07643a82a7cb409ee4177616e4f91ec1cf733699bf24dec90da0617fe3b52622edec6e12f54897c4b288278e4f3", + "8a3fae76993edbc81d7b47f049279f4dd5c408133436605d934dee0eadde187d03e6483409713db122a2a412cd631647", + "82eb8e48becfdf06b2d1b93bf072c35df210cf64ed6086267033ad219bf130c55ee60718f28a0e1cad7bc0a39d940260", + "a88f783e32944a82ea1ea4206e52c4bcf9962b4232e3c3b45bd72932ee1082527bf80864ce82497e5a8e40f2a60962d0", + "830cf6b1e99430ae93a3f26fbfb92c741c895b017924dcd9e418c3dc4a5b21105850a8dd2536fa052667e508b90738f2", + "990dce4c2c6f44bb6870328fba6aa2a26b0b8b2d57bfb24acf398b1edc0f3790665275f650884bd438d5403973469fa2", + "a2e5b6232d81c94bcb7fed782e2d00ff70fc86a3abddbe4332cb0544b4e109ae9639a180ae4c1f416752ed668d918420", + "b4cdf7c2b3753c8d96d92eb3d5fa984fef5d346a76dc5016552069e3f110356b82e9585b9c2f5313c76ffaecef3d6fd8", + "83b23b87f91d8d602bff3a4aa1ead39fcc04b26cf113a9da6d2bd08ba7ea827f10b69a699c16911605b0126a9132140f", + "8aae7a2d9daa8a2b14f9168fe82933b35587a3e9ebf0f9c37bf1f8aa015f18fb116b7fba85a25c0b5e9f4b91ba1d350b", + "80d1163675145cc1fab9203d5581e4cd2bed26ad49f077a7927dec88814e0bed7912e6bbe6507613b8e393d5ee3be9be", + "93ddeb77b6a4c62f69b11cf36646ed089dcaa491590450456a525faf5659d810323b3effa0b908000887c20ac6b12c80", + "9406360a2b105c44c45ba440055e40da5c41f64057e6b35a3786526869b853472e615e6beb957b62698a2e8a93608e13", + "93bfc435ab9183d11e9ad17dac977a5b7e518db720e79a99072ce7e1b8fcb13a738806f414df5a3caa3e0b8a6ce38625", + "8a12402c2509053500e8456d8b77470f1bbb9785dd7995ebbbe32fd7171406c7ce7bd89a96d0f41dbc6194e8f7442f42", + "aab901e35bf17e6422722c52a9da8b7062d065169bf446ef0cbf8d68167a8b92dab57320c1470fee1f4fc6100269c6e2", + "8cad277d9e2ba086378190d33f1116ba40071d2cb78d41012ec605c23f13009e187d094d785012b9c55038ec96324001", + "85511c72e2894e75075436a163418279f660c417e1d7792edce5f95f2a52024d1b5677e2e150bf4339ad064f70420c60", + "85549ca8dcbe49d16d4b3e2b8a30495f16c0de35711978ada1e2d88ad28e80872fca3fb02deb951b8bcb01b6555492e4", + "8d379ab35194fe5edf98045a088db240a643509ddc2794c9900aa6b50535476daa92fd2b0a3d3d638c2069e535cd783b", + "b45cfebe529556b110392cb64059f4eb4d88aaf10f1000fdd986f7f140fdd878ce529c3c69dfd2c9d06f7b1e426e38f3", + "ac009efd11f0c4cdd07dd4283a8181420a2ba6a4155b32c2fed6b9f913d98e057d0f5f85e6af82efc19eb4e2a97a82df", + "b2c2cdffa82f614e9cb5769b7c33c7d555e264e604e9b6138e19bcfc49284721180b0781ecbf321d7e60259174da9c3c", + "95789960f848797abbe1c66ef05d01d920228ca1f698130c7b1e6ca73bfda82cee672d30a9787688620554e8886554ee", + "98444018fa01b7273d3370eeb01adc8db902d5a69b9afc0aa9eadfeb43c4356863f19078d3c0d74e80f06ecf5a5223f4", + "87d20b058050542f497c6645de59b8310f6eeec53acbc084e38b85414c3ea3016da3da690853498bde1c14de1db6f391", + "a5c12b3a40e54bee82a315c503c1ce431309a862458030dde02376745ec1d6b9c1dbeea481ae6883425e9dae608e444e", + "b9daa3bf33f0a2979785067dcece83250e7bf6deb75bb1dbbab4af9e95ddfb3d38c288cbef3f80519a8916a77a43b56c", + "b682ec3118f71bde6c08f06ea53378ea404f8a1c4c273dd08989f2df39d6634f6463be1d172ac0e06f0fa19ac4a62366", + "a4f94fd51ecf9d2065177593970854d3dce745eebb2a6d49c573cbf64a586ae949ddfa60466aaef0c0afb22bd92e0b57", + "86cd5609efd570c51adbc606c1c63759c5f4f025fcbefab6bc3045b6ad2423628c68f5931ff56fdda985168ce993cc24", + "981192e31e62e45572f933e86cdd5b1d28b1790b255c491c79bd9bb4964359b0e5f94f2ae0e00ef7fe7891b5c3904932", + "9898f52b57472ebc7053f7bf7ab6695ce8df6213fc7f2d6f6ea68b5baad86ec1371a29304cae1baadf15083296958d27", + "b676c4a8a791ae00a2405a0c88b9544878749a7235d3a5a9f53a3f822e0c5c1b147a7f3f0fc228049dc46e87aa6b6368", + "9976e10beff544e5c1645c81a807739eff90449df58ffdd8d1aa45dd50b4c62f9370538b9855a00dd596480f38ebe7a5", + "a0e91404894187ec23c16d39d647ada912a2c4febfd050a1ea433c4bfdc1568b4e97a78a89ba643aca3e2782033c3c58", + "91a6ea9a80476ed137eb81558ff1d55b8581663cccd41db4fc286876226b6515fd38661557419e1e46b6a3bc9cda3741", + "b9e8a1e23c60335a37a16f8085f80178a17d5e055d87ffe8cf63c532af923e5a5a2d76cf078164fb577996683796caa6", + "ad8e151d87a37e8df438d0a6a7c02c3f511143efb93fde8aef334d218cb25932baf9e97c2f36c633620a024a5626af3d", + "978f942f210e8a482015e6fdc35a4c967c67b66e6e2a17a05cc7a0f2163aed227b775d4352b0c3cca6cbf4bd5bafaf75", + "b5e2e3d8b2e871c07f5899e108e133f87479959b80cb8a103fbecde00ccdbfbd997540eef33079c5cc14b1c00c009fd1", + "88a164b3fefd36857f429ab10002243b053f5d386466dbb9e5135ed3c72dd369a5a25e5e2aaa11f25488535e044e2f12", + "a66091c0db4e7cf05a089ec2b9ff74744354d0196968201f5e201699144b52bb13b4e68e12502727163e6db96e3565f2", + "8e65aff8e37240461b7374c20bfd1d58b73a525c28994a98f723daed9486130b3189f8efe5c5efcd7f5390cc366038da", + "8b37c21dd7304c3aa366959ba8c77ea8b22164a67e136808b6f8e48604297f7429a6c6ecf67b1d09b8b7ec083eacd7e0", + "b689b1277ad050f53da91a702516a06d7406ff33a4714ea859b3b2b69f8d0aa8f983c7e039b19c0759a3815d841fa409", + "b17f7a0a182ed4937f88489e4c4e6163dcf49fd2ea4d9efbba8126c743bea951cd769752acd02e921774dc8ebcfae33b", + "8b7fab4f90be825ac5d782a438e55c0a86be1c314a5dbc3cc6ed60760a8a94ef296391f1f6363652200cce4c188dae67", + "ab8410c4eaa2bb43b0dd271aa2836061bc95cb600b0be331dada76ddb46711ff7a4ad8c466cc1078b9f9131f0dc9d879", + "9194bd7b3cc218624459d51c4d6dbc13da5d3de313448f8175650fa4cfab7cc4afcda5427b6676c3c13897dc638b401e", + "980f61a0f01349acd8fc9fdc88fc2c5813610c07eecb6ab14af0845a980792a60dadf13bb4437b0169ae3eff8f5984ce", + "b783bee24acea9c99d16434195c6940cf01fc2db135e21f16acae45a509eca3af6b9232a8aa3a86f9715c5f6a85cb1c3", + "a3079931c4b90966d1faa948db847741878b5828bc60325f5ebe554dcab4adcc19ee8bce645e48a8f4a9413bb3c6a093", + "801f61ac9318f6e033a99071a46ae06ed249394638c19720831fff850226363a4ae8486dd00967746298ee9f1d65462f", + "b34dbbed4f3bb91f28285c40f64ce60c691737cc2b2d2be5c7d0210611cd58341bb5bda51bb642d3ee2d80882e642a13", + "8750af19abfb915e63c81542b13d84526a0c809179bbcc1cd8a52b29f3aba3ae0f7cf6f4f01790bf64ef7db01d8ee887", + "a6ea10000eb2dd4efc242ac95bc3b3873cdd882fbeb7c9538c87e3143a263ca3a2e192b2159316a625cfb5fb0b6cdcb3", + "aa40ca54bc758a6c64cb932924917581062e088b3ad43976b28f2e11d8a7dea73f1fb50aeaa0e70182bb2dc07d805bb9", + "a4779dfd25b5ec9d75dfb54a4bb030364899a5e75c1492403acb19f2adc782c7ac4daeb66d2f5aeb74135afe9f318e3f", + "b4551e2805d63ca453f4f38b1921ac87ff687e1d70575ad38f3469d6f0608ef76b7b1b98ae1e6b1e7d928773aaab6e3b", + "99490ee722f96aad2743b08dd37bfeb75a8c59efaee4c9b694eaa05eb8a6bb23861a4480544c7617d04d23fd5e2543b4", + "8a7050d964d295fff98ae30d77ce730a055719313457e773fcce94c4d71a9b7cf63db67e54a8aab20fb1335b0130b5d5", + "903144e6bbee0a4fec17ff80fef0d2103981140c3d41776cfb184ced17f480a687dd093f6b538584327e6142812e3cd5", + "a5b30f7c6939bdc24a84ae784add927fec798b5a5ee3dd156c652df020728dd6d43898be364cf5ee181725fbcffc0964", + "b43d97ec2bc66af92d921a5c5c20a03ef2be2bc2c9b345f46d8287409fcbfd88ebc49d4509d64468222cd1d2021bf236", + "82dc23c7f5086c9ac6b4566359bfb830d203544b0d8332a210775670f899cd9ff48b94bfeba40040c25664ebdd5cfad8", + "9294cd017fea581dabb73dcc8c619904d7e022b664b0a8502c9d30f3807668af279948e7e41030ae296d492225297e95", + "8d6c9dc636c8e884f9a4299e5cff06d044ebc94ad783a4b71788347ea4a336d4d048b8a9ecabae789e8fcdc459723dfb", + "801a80bc49e882ec81b04e37407713f033f7bdac79252dfa3dc8c5bd0229fcbd4019890e402cf843b9378df08f72ab84", + "b4313ca32569d973900f6196363c0b280ddfa1b47c88d019e5f399b805b444a777950fc21ae198fc23ece52674b94abf", + "96f06056fd255fdabf78986e315e7c4fdf5495cf850536b7976baa97a994cc6a99c34609c33a0f2facba5e6f1026dce6", + "983ed80220a5545ffd70ef5e6ac10217d82ec9cd8f9a27ee77a5ff4074092308c0e6396fc4e9932a77ddd474e61f8b55", + "872a059aa630af73c4abbd076e8b333a973ffc5bdecf5dcc0600b00162184213cb19d4f601795030033beb808d5810ce", + "b040f318d9d3b8833da854014a44296dbd6762dd17cab13f91987256c54353b7f0800547cb645a7cc231997454209fdd", + "a8c4731a555308e8ce0b8325eb7a4cbf6113d07e9f41932df04480b72628d313b941c7055f1cc2ac45c7353b56e96ca9", + "8c24031440b77637e045a52e5ea3f488926ab0b426148975edf066c40a4581beecc1bfb18fc4cf5f9f96dc6681b4bd28", + "b39254b475abf342f301298feaa17a4b3051f30ea23a18acf59e003e2704ac96fe40691f1da387913bdf7aee6389f9a8", + "a1dbf938b604ccc6d60881cc71f38df568aa02752aa44d123514154017503f6c1c335ae43e359f1487bc8934073cd9c1", + "8d52aa1be9f429ece0580498d8fe9fef46d4a11f49436a82b8927f9503dacc41245907f126594c1cd30701286f8c092c", + "b826f396486942c0326d16f30a01b00a682c30a75553dc6ac34fd5b3e96b13c33b94738f522eebaffb59ff8c571c76e9", + "aa89f51cbf6e6c3e2aa2806187b69ab3361c84e89f393f3ed284fe84db46fc3944aa44f8928e3964f9c1a1ec27048f68", + "a254df0efa4203fb92b42a1cd81ca955922e14bf408262c8f7cb7dc703da0ca2c71556bd2d05b22ce9a90ad77309833d", + "93263c507e4d5f4e5df88e85b3d85c46ea729fb542a718b196333e2d9fb8a2e62dc1347cf146466a54ba12d200ef09d9", + "922e3c4a84246d89a07aa3e90f02e04b2cea9bebc0e68b742156f702aed31b28c6dfa7ac936ea2fc2e029adf68361f98", + "9a00628eeeda4ccbed3ef7834149aec4c77aac1a14bc2491ba5d1a4a2c5d29afb82ceaa5aac1c5ce1e42cdcaf53e30ba", + "ab3a88df36d703920f6648a295a70ffa5316c96044f39ff132937bfda768937cb6a479e9ba4a4e66b377f3a9996a88c4", + "966b11526ab099d550ab33c6a9667e5cfdedf255da17a80a519d09acd78d2ea24ec18bd1ea7d8d63cf0a408f1c1fe0b3", + "b5c21b9817dc32f3df9d9988aa3560e1e840d586d01cd596bc0f850ab416b6013cbf7dbfd05ac981f26014c74bd2d2b2", + "9040abef5e2523e7f139c9f744a64b98fea3a57952059ffe4d5ed77fa87068203c090ef4e7f52c88fb82ea8a6fdca33e", + "a0dcdaeb7d3f5d30d49c004c5f478818c470187f4b0b4856812dcd1b3a86de58a99acb8ceb44c6b80c3060cf967c43a4", + "b5f4be9a69e4a6719ea91104820df8623b6d1073e8ee4168de10a7e49c8babea772bcbc6b0908185e98d607e49cd3609", + "8634020a5a78650015763c06121c606d2dd7b324aa17387910513dd6480fb797df541fc15b70d269b2794ad190595084", + "9504d1d0fb31ff1926c89040c04d51fd1f5cddf9d7ca3d036e7fd17e7a0f767ef33cee1d8bf7e17e2bc40949e7630417", + "812c72846ef6d692cf11d8f8c3de8fa78cc287303315114492667b19c702cd24d462020f1276895df26e937c38f361f8", + "8c97aa5e9ef2aa9a1435ef9ddfe62e850f0360864ed5fb82bf9fef4ef04d8fb4f827dc078bc911ee275e4501edd6617c", + "ac5f7af5e23c8e429aaa6b6825129922b59d25b4608f07b65f21388a9ac3aa89096712f320afe6d56e44e1f0d51a4eb9", + "a8c84d9a8593a0cb5be1e450960f59878a4e6b70da54a7613dfc25911b7cc9e6d789d39401b0a0d6471ab9dcdc707976", + "8c9d5fd89611392c0f085ffa4fa642a181f0b9b23593deb5e10fdd1642722ca75ef34a037e88a8d03f2888fe7461f27c", + "8c74b05f91fb95c85e7bd41f6d9a1e41e667e68f3d19b325c1f25df1767019919edab89b92af237896cbc4e6d6dc1854", + "a3caecb91640821f0b2c4981b23f2069df8d2b98ce026c1538bc096b292f5f956a5d52c1c8d6a8165a1608083ba6494b", + "8ae8e0c36f8b79a69176ff29855df45d0fcd9e4d1dbaed8899f8fcdece676e418ec034a6c161e2a894f0c834aaecbfd1", + "b88d18c67dc3b1b6ed60ee437c441c1ed14ecddebccf43683605716f30058b1aa4ba05ff10cd8171ee97d8f58d70c094", + "94f43d84dcdfd9cd19115c7d8e9c1e856828eafbfdec93b876cf0007e317e30b2ad951dbabc186aa6ef90fdee4d91990", + "b44e4723f41fc1d5b0057f371e3381ae02566590b3f964b6eb07b2104f66ff78410c407235fa98d04f635694f3baca09", + "addd8390173d29ca0811534d389253831fed75fed135398617836b6e70767269eacb1560b39a58f02042ca3b97fe59c4", + "80bdbdacc0c358c7ea52aeacdc5f9ceb6928bcf6e7dee7c17d8ae3bf7c2372aa7a0372363888968fc0921aaf4776d5d0", + "a486e2b6f04f403f9e609d69dfb3cfb992af56ecad1683271df3e3faa3b86638b81e73b39978fb829ee7133d72901f2d", + "a19472da57457e10c6a6307895393ddaec8f523760d66937fe26a025817319e234eaf69756ffdf1b84c81733424a96d7", + "ad6a195397cbc2d75171f5e82090441eed60bd1ba42c39ef565b8b5a8281b04400678625b1dc46d617f694a7652a8e5d", + "8f98e721c06cec432e2221f2e1b06bb1469d916a8d88d6973acf68d1e003441d00390dafcead8ecdbf9eae4509baf5aa", + "91d62a0f9d13c59adfe1376ed6d057eae244d13c6b3d99be49a49e0075cf20f4085cf127774644ac93615be9ac9e5db6", + "af45dec199245e2b326a0d79c4899ed44b1c0219db42602a4a6184ace0ff831a3276297af28f92e8b008ba412318e33e", + "8754bde54e8d2d169e6a7d6f0eae6097bc0461c395192bd00dd6f105677ea56ab384c02553ea5eeac0a65adcb0df77ee", + "b676afd2f5afc37a314c943d496e31b4885efcbcc2061036e370a74cfde5642bb035622d78d693bfc3136fc036c7edb4", + "aab6ffe6cc234397cf1822e02912bc282dfb314e92fb5a9e10d0c34ee9b5856d4b76e166bc2bb6fcdd66aabea35ec4ef", + "ada6e62f90ee6b852ec4b72b22367acac2896f0df2c105beda27096583ddbedddc710d171330569f111c6e44a5b57ae7", + "802139dd15241a6de663d9b810121bdd9cf11f7f8c8ca6de63f4f8e731409e40d1fd3558b4f619ed42ee54929dff1c7e", + "ad8e70531cec21b4e6f55be1751c2d025bd2d7d8158269b054cfe57fa29252d052ce4478ec7db6ec705789e2118d63b3", + "a8e4a4271769480e1b33a28c87a150ecc0b48bfe8a15ae04152197881de4ce4b03453aefe574842424edbbe4173e1a3a", + "b98c65726296610cef16c5b58da5491acd33bd5c5c5af4d934a9840649ef85730fbce8018dee09ded14e278009ed094a", + "8e213a7861223287b860f040e5caaa563daa0b681e4e09ec79ad00cc459238e70bbeaf7486bbe182fc12650700034ec5", + "a2879f9e1a556cf89b9b5b3bd8646a8cce6b60bcbc8095df44637f66a2da5858eee2dc9091475a8f64bb5aff849389cd", + "8a17cdb4077b9b0bcf28b93294ac5ae4c8bba8839fce0f1012b53187ac008f9858b02925fbfc421f1123afcdbd8b7753", + "86fd9c11528aa43946e4415ff64a3ca6409ee6f807368c68997b18605da65e415ccd85ad913820d450cb386593de666d", + "8ed55923b963c3d85a91aca11c40ff9c6c7f1e2b9bc199d1a270e5fb16aa62dec0136e97866145ae9d58a493e8b1cbbb", + "ae32af5b5d418668ae123c639b149e5eed602404e8516da4a61db944b537a3620545e8e3d38cf10cdaea980ab2f80973", + "95cb8d9e9d6762d78dde0ad73869ffaca904a7d763a378b8cc11a7933d3e7d1c8aec4271a079b1b00f8887ee5b1ea21f", + "b5ea20b42a3ca247f00ab5328c05f0cf194973d5f7271c66c41c5055b1ffdca136be179709e0c1de209fbe07b9820bf3", + "98682f7cce471c92a8d6d15fee4ddf4d43dd97c3e3811d2913618ecacc6440b737717c07736ae4558c910e11ee98104e", + "a67da2c7cbba48e929ca4e4b9a6299fe01ef79eff8cc5cd3fdbdc0721a68130e4079f30ae151a573a7dcca8ecf2e684e", + "a9981c9f9dcbb3b0f6996f664fb2acd7573189f203be37b2b714662aa273551396abfb1f612ccde4e4c8127a050dbe4b", + "92d55eff8da600f886da9bf68e8eecf482faa4b268f3f286b3b3e5cc91b19604081498d4905b201bb4ec68e32b5591d9", + "963e3f1728de9d719c86d390f3eb9c3f99d1928347fab0abf10dbb37d76b59ddb64d4734c977863a6cd03ffece5ca895", + "93480e2de83c921056b6d8628ac37cd5ef7555ba43b0308fc13386cb0515d42c12ecd06057137aa71a7931beaf90b9ce", + "8feae57ff0e6a162cc81c99f45c6187d268fc0bee8c2bffc92142ef76c253d201f0e932943cf2fa312982b281ce1066b", + "8f8f4bd4200fb87afcd743274480220d77571928000d4197410dbb75439d368df6a06d941a6152206371d2ca9cac99e4", + "8ee7f11e79af4478e0a70eb424fe8078237ad99ba6d7e6bf1a8d5e44e40abd22d404bd39b718ad6fdf4c6601f2a47665", + "a98acfcec612b574943195b9ba95bebcc9c0b945c9f6b3e8760b2a4635909246a9d73b0b095c27b4ecb3339704e389b7", + "b520efd19f65e81dc285031ea3593f8c5dad793e4426beb9196ab46e45346f265fd71e50adb0da657977c60ed5724128", + "a3d9d0b7415280ce4dfa2429d47b2b8e37604a5157280a72cc81d541ffe44612dbb3ef7d03693fc42a569169d5842dc3", + "8c29e2d0b33801f6d9a9c065a76c5cad1fb0a001506b970307e21765ee97c732a4cbf1d7c1b72d95e0ad340b3b075224", + "839e21f292892a6eb596b9b1e9c4bd7c22a6fe71d3d04487c77840028d48392c5cbe73140a4e742338e0c8475cd0c1ad", + "8bea5c68e7743998619185bb662e958f1b4d3ca81019d84ac43c88911aab3abe4ee9bcc73cb95aa3ae87c0138801bde3", + "b8f262d21a94604049e008ce03dc857848168e1efca4522acb0ccc827ffb37f545e1947843a356563a76bc6489605b66", + "a7bd0842b0bb38d9943b82aa883f36f4eb8a6e8a7790d4f87faf306608f51d250a19b73984f1156cef5dd2581664614b", + "a993e649bd953627a88a2539dac3a12ec7f37a4c65b01425d9d34edf7ee10a71aa98f65c9e013107f824faf8aee041a9", + "8e07eced75c67cb4d2ec01857f6ac1408482e6b31cb2faa249e8cf99f180575587df530c7782a7539b5221121ef48aa0", + "b2f4578f26c05ecb9e2669ca744eb19d4f737321ac7d04fafd18beb7866e0fec9dd063953ae1f077b44b9c6f54db1279", + "b6b3788a6c7bcaf467d19daf6ab884d549aa866970c05a9181f544ff190d043192c84fe437a75a30b78b425461cca062", + "a270684903c61544b85a7041e81f65e787e1c1e23e57538fa8a69836bed0ca1673861dd29f743a1280f2f38eddd3aa83", + "a9c2397c4773dcad2821266dadfd2401d013d9f35de6744f2ec201f3507700adb1e6ec4f5a453be4764da8bf68543f26", + "83a3025ed6fd5df9d98be32a74e10a0d9728b560942d33ba028536fb148fc34ae87e92be2df3e420a8dfec08da495982", + "90dc70c183a90bab988b4a85b7b921c8070af0e5f220364fe11afa0722990b2c971e1e98eef62d3287fedfd9411f1df7", + "82d940937a6c636224d04f8e2536f93dcf20dc97a5f188875ad76c21b804aef9af10839419b61143c1f88a695959a6b4", + "8017f9473ce49d498d6f168137e77e62fe553e5a51e75b519cf2cbd1ab9afdafad80fd5e6fd0860e640b0d78ca8ed947", + "80573a0ec049fe1f7b3013b2839e145cd87e07c0e43826a29ef8c92516f9a30896c2ffcf3ed77ed22a6cf3101b1789d5", + "953349abd2559f9824db07cec857ad54f1a05018f3076425f8dbae37f8d92a46af2c04ab7c8ec0250449541187696e98", + "ab7bd2c4f05ee9a9f252c4e16a20993a12c535c3809d124bae24642616521a9768d3f19eceaf8524583f47ae1f527684", + "9883b77ee834ee0112ca2f366d2a6fc213e0cf454e061438c2901a5ba35b7378f64da8adf6a476eb1562991ef5b4a5bc", + "89291811db308637356dbf7ed22cf07bfce33eb977734ee346e8c15a231b35d8b4443574f3fa97a40867b3e23b0bbfa4", + "93d753849d7d9588d39e38217500b123a6b628a873876612d9f98b5d611f52c89c573432d2176752b5d1cc2d94899b8b", + "a45add3c4844db3b7a237295fc85fddc788ac1ec395a0524d2fc90a539571a247146aea4aa10eec30a95e9617c85b98d", + "90f94578842db7a4de672da1e483858ece5e466c73c12f725a0fc71f42ff880c9447a33fa9096839bee817536f2591e2", + "b2c1b6fb031bb30460f157356562b44b4de096a0a112eab4fb3cc500aad38bc770da1fc2e73caf687a0da5e8537049c0", + "afb15e15fd930929c0e3c66482068a5afe0c7b7f82e216a76c5eb1113625bfa0b045a52259d472284cfbaf4796c71456", + "ad222a9a3d907713418c151b8793d5e37634354322068f8206b9d0da1a3f53b0004193713d23ec35990639a1b6c2e075", + "b44a128dce97e8c4b178cdbca0a5c1b3f6e164490fac0fd68dbfe0aafa89920bb4ea420a8527e06c80dd19c2f135e3ef", + "8596e993ef18b8d94e9c42a90cb7060affc586b8e9b526820d25124285de5590134e2e86592e9dc4dd45ccf5d578fa60", + "b71bb0ad138141ed506b2253e84110d2db97cc2d24a3fd0d096b0022d9f38f87aa74e2f505074632d64e90bcc491aa30", + "84841eafd357309de47b92ca5ec163dec094a2e5271bc65898c31932e0160bee165e4decb23af339cfe09c83e1cc5441", + "8a2915ee39a6fd4a240b98533d7690ef1773ce578ed1fb05ed414ebe36f7ef289fa46f41768df57190438c356331e329", + "90bb337165386f1990cbd8ed2e8321ef21bc18125b015b4da0c37e5fcc446b26005379ee4fad8ce9348ceb4ab49e82e2", + "b707b50ea2ab05c6d183671587f25fe29eef23fe569d731459a1ac111a0b83a2cd65b88242876b34aeead3b05a15d745", + "ae1f159f79b7996315c4f9acce7e21a6ed59d4ef76331196fc86911fda3035edd5c11d568b105175a36c948d0263b382", + "922bc525bace05e5dff6b5cabde5469ddd2c1c601f7131abc04ecefdd35095e6ac015b1aec3c3b25c5dee8d139baf60d", + "a7b060405b2740f82db64683187b1bb89e5f40c8438663c7cbc8ef2513929fe5f92625667a7f2f599a72a96b1fc8f08a", + "b9dfe94a08651db5efefbb813269bce80d814e3089b80c0654491e438d820bf521f8a4a4477909344ba88f7683eebb43", + "841817a9729465743576950b6e8eea32ebf39cca99ace86c4792f9f35926e2d6830c52854a3b2eaeb61694e6845008bd", + "934128034bde8fc7b93b952aa56e0ed28b36cfa04cfa1f0d5b38266dd40beedff5e0bab86e4717b0fb56c56be2eae26b", + "aee9d64caf28596308782cd8f3cf819506daf3378f86157ff775e618596411adf94efd0e9542787ca942066f02cbd332", + "85871184db314411a49575fee088c52ed5dba4e916ee001ec24d90898a0154d9790a06aa8a707ca7a8b986c0293b8d89", + "8d3d87edcc0187a099c97b581a598d357a41ac152303bb27c849eb78e72e15cb97cf9a0468fc36f245c3e152c76bb7dd", + "900475d165dec18b99eb7b5f9e9ad1d2d4f632e55fdcc4c5ecd7775fed462990e6aaafe9c669f40508f9b15f00bda31f", + "a25b5954edd57e7811a0d18532043d975c7b44b80f65cd630935d7b16ada05f30fe2b7be7ae8a2f54c25957faf3f1950", + "a089019afa3a7a15f7e7874e73b6773c0a824e6d3379b4c928e173321fb165ad979a6be004d394c28d19d410b2655d3e", + "b28f46797dee0c538bd3de815df641a0ef718ad3e52b2764aec380d6905b38b50ad6f60d0f68e096ca39960ba7734355", + "b0ac155d3d05851b04104e6b459f1a68e9e155437c92421a7c0e4dd511ef89cf71dfa3cc920769492ee283a65ebf029e", + "813c69a810745580d43d5b5480f0ba81000fbef0071e6b655c7346bef5ed774e9214a7816d40eb1774a5bd033767a046", + "b176345ca75c64f10ec33daa0dcf1f282b66a862fcd3d8d66c913f9a02db4c9d283dadc02eff13aaab94bc932a42234e", + "92560f67e5b995db4a489bb86ee78b4aee0800143b3535ad557a53e9e08716bd0202d9f5714722c2a5e8310046e3f5b3", + "8adb427bad9cc15fc6c457a96a6750dda8c46d859c5f69bf0e7ab8fc0964430b33967fd47cf0675b6ba1757f91255e6e", + "b120f723b80389a025b2daa891b140b3d7b8d520ae2a6a313f6e3d365a217af73292dcb249dca1f414ec05e865e3cdc7", + "a61a5d261a8dfe5996c42ea0a5ae703a2adcfda80e86837074d868eee16f87d38da19596c48b55dbd7a7cbec1a9b4996", + "99dc921eacc6bb867c5825ad4c83bc4af9dd78a18b3d0e1a60ad493e3805b8fb9b7922b577da1adb3d805edfc128d51d", + "85455fa165a07282aaab4a5bfb88027f47b9532e4af8195c048515f88b0db7e80f42e7a385fd4944faaa7f2a6544ad17", + "96dff2d1c8a879d443fe576d46bcceaf5f4551d2e8aad9c1a30883637c91090de99ad5eec228eb5febf93911502d3cbb", + "a87eb7f439377fb26c6bfe779701f4aea78dd7980b452a386afec62905e75217a1996c5234853432a62ef8bab21c31c3", + "b598278293823e9ccb638232a799211173b906444376337fdf044d0227d28fcc4c5867e6ecb3200e59ca0b139e71cac9", + "aa6fe147edc95027654d68140f428ec53cede3552c5f49c09d18bc6f6ae8c739a63042eb7291d14d717a4e1f0778abcb", + "ae8ee18913d328b2fba71efe65526d3ee9c81beda53cf776baec4019ea30212010758cbb5dc85ed6620ce04b189f01f2", + "ae9fb686777e88dffdd42805fe4114aa0da1b350d92a27ff3f8a817fb25af1fcfc9a06155affe0273bf13caad16a5351", + "95d372ba3a2ee38371538f34aae91b4844488e273f70c02f1992370f89fc2343eff95692d52ce9f21206abbee4959958", + "b15260376f0a34ca2827ff53acd7eaaef94c9acc2f244b36500423069cb1cdaa57ac8dd74adb5b53d0fd4265fcbb28ea", + "b0ffce6a8059537ef6affdbbc300547ef86e00109289239b0c6930456c562b4ed97f2e523963af17736dd71b46c44ac7", + "b5499a1277d34f9892f7579731ff53f423f2ffffa9ea43a6e929df8c525e301396249a2324818a6a03daa0e71fcd47b3", + "98dbfb8e97a377a25605a7665d4d53e66146204d8953afda661ae506858c5cd77ff7f21f5f10232e06dbc37378638948", + "84177e27e6da0e900c51f17077f5991e0e61bff00ca62c1623e627c5aea1b743f86eef6d55b13219a1947515150bade6", + "b50407bb5c61b057ab8935df94fd43ca04870015705b4f30ceac85c1035db0eb8293babc3d40e513b6fb6792ecbc27a9", + "988699a16917514e37f41ab5c24f4835ed8a2ca85d99972646fcc47c7e2a83c2816011144a8968a119657c4cda78d517", + "920c43fdcb738239ad542cb6504ab34498bce892311c781971d7db4dec70e288676de4d8697024b108cfa8757fa74035", + "aaa106329aac882e8d46b523f126a86d3cee2d888035ce65c0be4eaae3e92fd862f6ac2da458a835539cccafaba9e626", + "96e4c1562d14b7556f3d3e8a1b34ea4addc5a8170e1df541dc344728bcb74cd1630eb7ba4c70e9c68fd23c5c5d5a729b", + "a616ac5016d4e68e03074273cd3df9693ee0ce3458e8758b117a5c1bc6306dd2c7fad96b1bb37219c57ac62c78ad7a3e", + "8db7d9b20abfb1445babd484ae9e38ff9153ac8492230d7591e14e3fca7388a5ca6ef7d92ed445c8943cf5263e4a6ad7", + "88464134221aa7134878eb10928f31c8bd752ab68c27c9061c1de3f145c85731a4b76acdc7e939b399b6e497f9e6c136", + "a5f7c794f70b7c191c835dded21d442b6514bab5e4d19b56f630b6a2f1a84a1d69102d7a0dcca256aab5882d3f30f3ca", + "b96b6f98b6817b5fa6b1b1044e2411bdf08bf3ffaa9f38915d59e1d2b9bed8b3d645eee322ee611102ce308be19dbc15", + "92c26ade2e57257f498ac4ff0672d60b7ea26dad3eb39ed9a265162ccd205c36b882dba3689758c675f29e20836b62d9", + "8379a0299e75774930577071d258e89e471951642b98e5e664c148af584d80df4caa4bd370174dae258848c306f44be5", + "a0e53beda02bd82bf3d24bd1b65b656238128e734b6c7a65e3e45d3658d934f909c86ca4c3f2d19e0ac3c7aae58b342e", + "8ca5ceaeaf139188afd48f9bf034d8baf77bbf9669791c7e56ebf783394d7fcdf2a25fa4bdfcddfde649aa0dc67ccccd", + "a8060e6448844e9db4e9fb4da1c04bcf88fda4542def5d223f62c161490cf1408a85b7c484341929c0f9ce2a1d63e84b", + "af6e1a5ecf50b754bb9eb2723096c9e9a8e82c29e9dcaa8856ab70074430534c5395534e1c0ed9ce98f4b84d4082fa67", + "81c8dbbef98f1b561e531683d5ae0f9b27b7f45dc6b2f6d61119ca0d559bf4ceb676d320afc5aba1811eeef7547a59d8", + "85b46cd64d605c7090a2faf1a2aadf22403b3692b3de1d83e38b2de0108d90ac56be35b0dca92c7a41c4b179a3567268", + "8dd3cc3062ddbe17fd962c2452c2968c73739608f007ad81fa1788931c0e0dda65032f344a12249d743852eb1a6d52a9", + "8630f1707aea9c90937b915f1f3d9d7ba6bda6d7fdef7a40877a40c1ee52471fd888f84c2b2c30b125451b2834f90d3b", + "b4a747e0bd4e1e0357861184dacec6714b2b7e4ee52fa227724369334cf54861d2f61724a4666dae249aa967d8e3972f", + "a72de682e6f9490b808d58f34a0d67f25db393c6941f9342a375de9ca560e4c5825c83797d7df6ed812b71a25e582fff", + "8d5ea7d5c01f1f41fffe282a334262cc4c31b5dcf31f42cc31d6c8e37c9bd2f1620a45519dab71e108fe21211c275b6c", + "8ccdc7e3642c2894acbf9367f3e99c85963cea46dc5473d175339a2391be57dd8815feacadec766e13645971213b9eb8", + "858e9b5fc8c13b651ff8eb92324bdda281db4cf39f7e7bd0472908b3e50b761fa06687f3d46f4047643029dc3e0ceeaa", + "ae20d36c70cd754128c07cbc18dcb8d58b17d7e83416e84964b71ccff9701f63d93b2b44ec3fddc13bbe42ebdd66221e", + "860dbf7013da7709e24b491de198cb2fa2ffd49a392a7714ad2ab69a656ca23f6eafa90d6fdc2aa04a70f2c056af2703", + "8f809e5119429840cb464ed0a1428762ba5e177a16c92581679d7a63f59e510fdc651c6cc84d11e3f663834fcafeafdd", + "8d8a8dce82c3c8ea7d1cb771865c618d1e3da2348e5d216c4cbbd0ac541107e19b8f8c826220ca631d6f0a329215a8d6", + "86e3115c895ae965b819e9161511540445e887815502562930cedc040b162ecb1e8bdc1b6705f74d52bf3e927bc6b057", + "b9833b81a14115865ca48c9c6a3855f985228e04cbc285f59bf163dca5e966d69579ea4dba530b1e53f20bd4dccdc919", + "a71f5801838a6dbb162aa6f0be7beea56fadac1a4bcd8113a0a74ab14fc470a03775908c76822d64eb52a79b35530c05", + "a77ab73ae94b6d3378884f57eee400eff4a2969aa26e76281f577a61257347de704794761ea1465dd22a6cc6304fbc4a", + "acd1c5df3c487c04cf27f002e81f2348a0119349b3691012526a7b0d3bf911cdd3accbc9883112ed2ba852145e57fe68", + "8a28515a48832ac9eaf8a3fb3ad0829c46c944b4cb28acbcdbca1d0d4c3c623a36cda53a29291b8f2e0ea8ee056b1dee", + "846bafca11a7f45b674237359b2966b7bf5161916a18cf69f3ec42c855792d967d3bf3f3799b72d008766206bb7a1aa3", + "b24b341675b1db9a72c3405bbe4a95ccdfd18fa96f876ec946ccb5108f73e8816019998218a036b005ef9a458e75aeb3", + "b99c267b4a09193f3448bc8c323e91ef5b97e23aeff227033fe5f00e19bab5583f6e5fcb472ec84f12b13a54d5c0e286", + "a088aa478dbe45973b04ecafbcbd7ee85c9a77f594046545cdb83697a0c2b01b22b1af0b97dd75d387bb889e17f17aa7", + "a0c6b0cdff2d69964134a014e36c3709d9e63f6463c5cd7b01b6f0be673731b202d577539d89dd57a888326da1df95af", + "b4e6dc4ef11b2b41794ece70a8968e56705199d183366759568b6fa845d2cae127486e926b5b27ae9118bb21d1682c1d", + "a007804353f174098f02540a57e96227232444d5ae0a24232c244647148b6c049848cbd2b50d0a25af3ca9164bfff8ee", + "873fb034cc39c9cee553ece908fbf315f62efbc412b9afdde6a1889326b7f6f813e050b0601ba9921688e958cb75942e", + "b5676c90f0106c40d8683299e59d564f505ec990230cb076caef3ae33f2021e6aa5c9b27bb8fead05fc076df034c28f5", + "b5a67fc4c5539ad1ddf946a063110f824f7f08d2e4d30762c9d437748c96c9147a88efc22260573803ab545c18b108f2", + "817ff2b748a949973a91b69b0ec38efbd945aeb26a176d19f0fb76e261c7526c759e6f5516f9ed34de6eb1ac7838c9cb", + "99b76bda3526a5d841e059010fdb14eb2fa035a7d10463373a062a98c3c1a123e2da0848421dd7546d776438fd05e304", + "aa0d363270f90d56bbee7ea577b0c358532bda36d9247af6c57d000044a97ba41e35bb0db438f4c94551c6350e4e0674", + "acdae205d05f54b9544be96c9032350511895ccf413dbbc56d1f03053185df22a6d5b7ffcc3fbe96c3e2ce898ccfa73e", + "b091c220a1de18d384f50dd071dca4648ca4e708162c52a60e2cedc0188e77c54639f75bce9a468a64b2549119c07ded", + "878676133e5c700b1d4844564fa92a9930badb5293d882aa25ee6721a9f2cfab02088c31d62cf1342ae3edaea99a1ea0", + "9756d0793e6aba3b4dff48100bb49a5ec08ec733f966cb438379b91caf52fc2a5930830ec3f49aa15a02c82c1914dc7a", + "9722f760184d3b2d67cb2cea7fa41b1ff920a63446006bd98c6347c03d224d2d8328fa20ccd057690093d284b9a80360", + "b5a68489de4f253715a67f0879437bfe8f4dfc4e655ca344848980e6153b1d728acde028bb66fd626fa72eedd46ff683", + "a8cfc900b34835d9fd3add08044636f69614eff9ae929eac616c39bd760fd275ee89bf24b0f275dd77a66e54fd6b94e5", + "89967479bebf70b2893cad993bf7236a9efe4042d4408022fdbb47788fabedcec27d3bba99db778fcde41e43887e45af", + "889235938fcec60275c2cf0f19d73a44d03877d817b60bb26f4cbce09db0afae86d42d6847b21f07b650af9b9381fa82", + "b7fc321fa94557d8fbdd9fff55ab5c8788764614c1300d5ef1024290b2dbb9216bce15cb125da541f47b411a2e7e3c2d", + "b11b0c4dc9477176b3cda6b17858dbd8c35a933ed31364801093f310af082cb5a61700f36851e94835c5d4625bf89e32", + "9874e54d2939ee0600f4194f183877c30da26d7515e9e268fea8d24a675dd2945d1565d9016b62b1baab875ac892f4d2", + "90df3a77280d6f1fa25a986309bba9d5b89c3cf13656c933069bc78e6c314058716b62eacfa7ab4aff43518b8b815698", + "962b08299a287d77f28d3609f39fd31bc0069f7d478de17539e61fcc517045050644b0307c917208b300ce5d32affcca", + "b30eedca41afb6f083442aaa00f2e4d5dc0fda58e66aaf0f44e93d4af5c4bf8ea22afec888cacbf3fae26d88e8d344cc", + "847747a22fab3fe3c8cd67f3f1d54440f0b34ce7b513225dc8eb4fa789d7d9f3577631c0890a3d251e782a78418fecfa", + "8d1ef3cb5836e4039b34ee4e1b4820128eb1e8540e350309e4b8fea80f3ae803d1f25f4b9c115482b324adf7c8178bc7", + "8f8a2b0b0f24f09920b58c76f7d99ec2eb2e780b5a66f2f30a9ed267dcaea0ec63b472282076c7bf8548211376c72f6e", + "831ee6dc8889bbf4d345eaeb2f425959c112d2190764abbbe33bc44e1d9698af87ff5a54d01fac00cfee5878dee7c0f6", + "a7eb2479ac80d0ee23f2648fd46c5e819ad3a1f4752b613607ae712961b300e37f98704880ac0a75f700f87d67853c7a", + "aa4d1b9cec62db549833000d51e83b930db21af1d37c250fdc15d97bc98de7a5af60dbf7268c8ec9c194d5d5ccda3c1d", + "87396fd7e78c4bcf270369c23bc533b7fb363ca50d67262937dab40c7f15bd8448a8ba42e93cf35fb8b22af76740d5e1", + "a958b2a9ffccbca13c0c408f41afcfc14d3c7a4d30ea496ce786927399baaf3514ff70970ef4b2a72740105b8a304509", + "a5963a9dd3fe5507e3453b3b8ed4b593a4d2ced75293aee21bfed7280283348d9e08bf8244c1fce459aa2470211d41ea", + "8b06ddc3359827558b2bb57caf78b3e5a319504f8047735fcc8ec0becf099c0104a60d4d86773e7b841eb5b6b3c0cc03", + "9437e7278283f6d4d1a53d976c3c2c85c5fe9b5aec7e29d54a5423e425b4be15400ed314f72e22e7c44ee4bacf0e681c", + "b56067ee26a485ed532c16ec622bb09135a36c29b0451949aa36fee0b0954d4bf012e30d7e3fc56e9f153616b19349bc", + "a5c72f7f5d9f5b35e789830a064a59c10175093a0ce17654da7048827d0b9709b443a947346b0e5d96b5ea89b8d7c575", + "a8318d01182d4c9af2847a29a6b947feef5795fc12e487a30001cc1ec482b48450c77af4837edfa1aedf69f0642c7e5e", + "82ea421c091552d3dafa7da161420cb5601b819e861dd2ba1a788c3d1b5e8fa75cc3f2b0db125dde8742eb45b335efa2", + "8679fd1c7771ea3b12006d4a972f4f2892e61f108107d4586f58ee7f2533d95d89b9695d369cdace665f19c6bc3bc85e", + "b5ab3e8adee4c950fce4d33a0e2f85d3d886e60a6e2f4454b57bc68725f0cf246372d863167482cce1ea10a7c67c3af2", + "a85696927075ec188979180326c689016a0dc7a2f14ae02ea27c39ef91418cd44177d3fca5752cf6b298fd75fa012e26", + "a44f87b7232f102cd092f86c952a88afb635484a984da90a41a57a3d883c9469064bf105b9026024090486b6c6baa939", + "866ac91a437db945bbfdc11fcee583f3669fa0a78a7cecf50fbfa6ed1026d63ad6125deba8291452bf0c04f2a50e5981", + "b780d5a1e278fd4eef6139982e093ceafea16cb71d930768dea07c9689369ff589d0c7f47d5821d75fe93b28c5f41575", + "b025d0046e643506e66642c2c6a5397a8117bbfe086cee4175ff8b7120e4f1e6794e1e3f6ec11390993cca26d207ae43", + "a04a22b6e28c959ab265c7f48cde42bb6a00832c6beb2595b5df2879080a9424890960417d7d7ceb013d697d0ebf7267", + "81de9c656ac27f54d60d0252e33aff4e9e9e9c3363a50740baf15a2b9061f730a51ae1704e8c4a626153cf66d47f19b1", + "a15fab90599df889df11fa60c752948b68fba54005491180dafb66c5775547976d0eef33945e55d4818653e0818c6f92", + "b06f9be44ddb103a72fa4ebc242c8ee1975fe9bf9ef7124afeda9967ff3db644dbf31440151b824869406851a90984a2", + "99abdfe6806ae5efa2d11577da17bd874d847c5f810460148bc045bcf38c4fd564917eacb6ed61bb9164ed58055cd684", + "ac53231077f83f0ae5f25e52b70bb6105d561c0ba178040c11c3df8450c508ed5df34f067fdaacf716f90b4926f36df5", + "99e3f509af44fc8d4ebc693d3682db45fd282971659f142c1b9c61592573a008fc00502c6af296c59c2e3e43ed31ec7a", + "98f2f5819670aff9a344e1c401f9faf5db83f5c0953d3244cfa760762560e1c3a3c7692bb7107ea6eaf5247ac6fd7cc8", + "b5b9f90391cec935db8d2b142571650fcbb6f6eb65b89c9329e84b10bfa1c656026674d70280ade4ba87eeaf9333714d", + "b0696b77ca8a0cdbe86cad12f358880926906fb50e14f55b1afc1e08478ae6376215cbb79bc9035de2808c7cd2b13b85", + "a51d746833062a65fd458a48a390631d5d59e98e2230b80d8f852cfc57d77f05eefcfd3c395ade1e86d4a39c2141365c", + "812d67654319f4ef3c9e4a2d4f027a4cb7768f1ea3f5fdde8d1b79187a4b874ff9a5c70f15b7efa079c2dc69d1b9b1fe", + "968978b653c6416bf810f6c2ffa3d1abbefbd06f66b6686e9a4fdce3f869e0ab1e43cce14dc83786596761c100ae17e1", + "98e1e6ab562ca7743783b802faeb0a24f1341abfb9655f106920aef08964a3c0e8083e1acda7ae28fed7cdd5478decb6", + "a91c0b982a0a7085a103600edf99e9d0bee4c4e7db6d9f8f376c215c7d42476218462a3765f2928e12c3dd49d688e4fd", + "8a43395b3124fab9e2438635bf88952e8e3084dad7ecb3a9927f9af0e0887bce4707084043671fc98ad03621e40a149e", + "b0b37626143d4a8c6f5693d5f1fe871525b4dd946c4239cde032b91f60a4d7a930d7ba28959737550d71c4a870a3a3be", + "b01c74acae1715c19df08d5f4a10e0c19d1356264eb17938d97127bf57e09ced05ba30d0fc1a9f32d6cff8b0d5f91c9a", + "b4c2328eb8a5a673406faed8f0aebb8540d2791646e37ce46e0e382506570ca276eb6f8e166dbbf9e0a84064873473b9", + "85cb9f769a185e3538e4a4beda9a008694e1bf8dfeea9dc07c5c40a9ceb1d31fcb13cacfaa52849ba1894b5027cb8c30", + "8742f91cddc9a115ddc73982f980f750d82d3760f2d46ee4490d5b17c6c3bb57c7d4c7b8d6311b7b41e59464c009b6a5", + "948ef86d17128a061e1bdd3ea7fcc7348e3ec87ec35dc20a58dd757d5d18037fe5e052bb359e27ab4c2320d9a52a6a0b", + "a70f6a214097c271e0d2d95e30fce72d38c30a2f186271fdff0e38e005aff5baed53739b8c4f9501aa7f529c5cb2da59", + "892a7574cf6704ad75b346c95ae6f2668904f1218c35b89b07a0c2dbf3c62173c348f6fd9473926eef56a37c0f635c04", + "837e85a41f39b4ded1420aa8fc3be46a7adb99305e0928c6d7643b7c44434b72984cea08eb68f5f803661df0db78c87d", + "94e495329f2aab3eeb68f347961d1006e69d990095877a4dcc376546233adf29a14bf6b16a0c39aa477e15368e87014c", + "851860a8fdf76a97048396553262637dade27f1f63f926997e74c7c72b14b10293eae7824e8dedffad1aead57c124f79", + "90481017a250972055ab1cf45ff17d2469517f10f18c9d4ef79a9bdc97a49093289bbacfefa8a1e491bbb75388b34ac0", + "983db15f7463df28091c691608ca9c51095530fa6b1b7b5b099c612e673d29e16787cc9ae1c64370ba6560582ce623c0", + "a477dab41014c778a1b78a7ce5936b7b842124509424e3bfc02cc58878c841c45f9e04ccc58b4f2ff8231488fff0b627", + "868ebba1c85d1f2a3bf34c0ab18721ea725378b24f6b6785637ee4019e65d4850e051c8408fe94a995cc918c7b193089", + "93cbf4238a37ccd4c8654f01a96af809a7d5b81b9e1eab04be2f861d9d2470996fb67367e5bf9dcd602dc11a3e4cf185", + "83113f4e696030cca9fdc2efc96ba179cf26887c677f76cde13820940ad6891cb106bb5b436d6b0f8867f2fd03933f7d", + "90c709f4e3359a6d215d03f45ad5cf8067aedd4aab03512dd62229696485a41dcd64e2acce327fda390e0352152fce13", + "9945cfced107a36f3cf028ba04c653360afc5013858b9a12fac48802efcbc198c9baf3a7f9b23dfdd5036e88bc7274c8", + "832ae60192b47fc735a8ddeaf68314b16256c90ab68099f58e43073e249c6939895c544a02fa34e40805bc6b5db33461", + "8b12c335818b643c1d22cbc2869606cf64e7ae54a7713617fc4dd3b2f052ebd6b920ca59ba2e9c7aa8cf71bb4f40f9e8", + "a2033eb7a373931c65d66989644aa0892ac3778b9a811b2f413d8bf534e282c339717979f9aa742162abb3468c195f87", + "aba2b4c37dea36bed6d39323e5f628ab607699c66767f9bf24ef5df1bfcad00c2664123c0d8d5bd782f1e14a06f4c769", + "b71963777535b4d407286d08f6f55da8f50418486392a0018ee10f9ae007a377b8b8336f33386b0eb01c45695c3ed2da", + "88dc87826941340913b564a4f9b74985a311371c8e7b47881235d81c081f1682bef313c2f86561a038757fb7d6a1a8dc", + "869e13e3fcf91396750150f9dc9307460494c1d365f57893fd06fb8acf87ac7dddc24e4320d9cad0414119013ea739b8", + "92194e292303d32b91ae9cecb8d6367c8799c2d928b2e2846dab1b901371a4e522fc4089aad8f4ee676f0614ff8b19d7", + "aa589a3e512cb4f8589bc61e826a06d9f9cb9fdfd57cf5c8a5a63841435b0548e30a424ca3d9ef52bf82cc83c6cb1134", + "81802e0194bc351b9a5e7a0a47911d3a0a331b280cf1936c6cf86b839d3a4ab64e800a3fe80ea6c72c3751356005a38b", + "88e5e9e3c802314ddd21cb86f2014948b7618502a70321c1caf72401654e361aac6990a674239afa1f46698545614c93", + "abac1e0f85d5c3ff6d54ed94930c81716d0ac92be49e3d393bed858833f4796c2b80bf7c943e7110de7b2d148463bfbf", + "b7eb416004febd574aef281745464f93ef835fd65b77d460b6ad5d5a85a24b536b4dec800cfe80ae98489e54447e8bb6", + "b3fd8ed1c30e7c15b0bc0baf0d9d1ecad266bafb281cd4e37c55edc76c202fb1e4ea315a91a2848f40f481793ae35058", + "86ef674ddf4b7d303c68bbfb53db00b925ccbf11d7d775ca09e458f4ecd868ca828103e8e7cd9d99672a193e81b83923", + "95ef414e9f7e93f0aaaeb63cd84eb37fc059eb8b6eced2f01b24835b043b1afb3458069c45218da790c44de7246860c9", + "93ec8f84c20b7752bfc84bb88c11d5f76456136377272b9ac95d46c34fce6dcfc54c0e4f45186dd8df6e2f924f7726ab", + "95df5f3f677c03a238a76582d7cb22ed998b9f89aecf701475467616335c18e435283764fb733fb7099810fec35932ae", + "8cda640695c6bc1497d19b9edc5ff4ea94c1c135d86f573d744358758f6066c1458901f9367190dcd24432ae41684cf0", + "b19aedf5569435ff62019d71baa5e0a970c6d95fe4758081604f16b8e6120e6b557209cdea0ccd2efec6ff9e902d6ce6", + "b3041f21f07d52e6bd723068df610aa894dfdde88094897593e50c5694c23025e412ef87a9d16cadd1adbb1c6e89ced4", + "a7f8d6ab0a7beb4f8d1cfef6960ebdaa364239eca949b535607dee5caeff8e5dfc2a9cfb880cc4466780c696cff2c3a6", + "99a565b4796e2b990bfcb234772d93c5ffdbe10453b5aa94662272009a606ba6ea30cc0c3c26aa22982c1e90738418a5", + "90c54b55ff19157c1e679d8d4f7f0687a70a27d88f123179a973c62565adfcc9347cfe31f54539038cf2f34556c86870", + "8612f34bcd018d742202d77d7ce26cf9bc4e0d78e50ddf75250b9944583b2c6648f992b635ea13fdaae119764e7c28d5", + "a04fb38e5529bf9c76ec2b5e3a1ef3c6f9effb6246c7f67301cfed707356ba1bf774f2867c77a5805933f0c8ad0ec644", + "b4800e7b503da0164885d253135c3b989690794d145182572181995e6fa1989f3d0324993e871bbd5f48fadd869d8a18", + "9981cd4f28ae7b7dadf454fb3aec29746dc2e0ca3bd371b2a57cd2135a7d93559e02132528ccd2d305b639d7ac51613d", + "a3ceec012dd1fbad3ef9f9f1d6fe7618e13d4d59e3f50540d2a57010d651092979c75442ec8b38a1ab678505e30b710d", + "8b97b8654d067fb4319a6e4ee439fb8de0f22fd9db5569ba0935a02235cb4edd40a4740836c303ec2394c59a0b96308b", + "b3d1bf4410fec669a269622c3ce63282c9ac864620d7b46c9dfcec52d8e79b90c4c90a69c32763136a7f2d148493524e", + "93174eba1e03f879e44921084aa0ee3562e48c2be49085de96ed7621c768ff52324d14c8cc81f17d7ed50c38ffb2c964", + "aa2194cd0fb7aec3dac9a1bd8ea08be785926ed6812538be6d3c54218ea4b563646af1f5c5f95cb914f37edfae55137d", + "93f2c0dd59364f6061d3da189e04d6c64389a3563b062e8f969a982cd68cc55b4f38b21546c8a67c8df466ff4f61f9c5", + "aa7dd497cc949c10209c7010ba4ce8a1efd3cd806a849971e3e01716ea06a62e9d5e122ad1d2b8e5a535fae0a01a7761", + "ad402424b2a32bca775a66aa087580d7a81f0867f293f1c35580b9e87ccc5a2bab00c29a50fd0d7bd711085ae2248965", + "96237843d8e29ac77fc6ebf4acc12946ad11697de8e5f152fe5776f2475b790226a7d156ac48968dd68b89512dc55943", + "a45c25cdbb9fc327cc49a1666988af9ab4c5f79cea751437d576793a01c3eeea4c962c05c0947852fe0e4c63e1c84771", + "93dcf834a614a6f5484cc4ba059e733ab5dcc54253229df65ff5ad57b447353ebbc930736a4c96322e264e65736948dc", + "b9a94f82a82c0c5a26f2c1d5381afec3645e8ee04c947dc3b7ad59a73018db1e9965ab3642f2bbf60f32c430b074fb22", + "94eab29b3524ccbe0c4b928e5fa5dd8f684074b332fcf301c634d11083653ffee4f7e92ddbcb87ed038024954ad1747b", + "b8dca5f679931d6abef0674bad0639aefad64c2b80572d646aaab17adf5ca1ab2ebeecd5a526cadc230bec92ed933fc2", + "944d394958e539251b475c4304f103a09f62448b7d8a8eaef2f58e7de4f6e2e657d58d5b38e8513474115f323f6ec601", + "8a5ae1f13d433962d05df79d049b28e63fe72688fc3e6660aa28e0876a860c3dbc5fc889d79f5c4dec4b3a34cdf89277", + "afa5278724998eced338bb5932ecf1043d2be5dd93f4d231d05d2ea05b4455f2ffdc0eadcb335dcace96dd8b2b4926fb", + "b91153a2f4647ae82fc4ee7396d2ca23270ec7f8884ce9eead7e9376270678edd42dd3d4d6c003dfc2dde9fd88cc6e7c", + "adc932f1c679bf7889cb1ff4a2d2897d7973483fa283979a0ea3640c80ed106ea0934c1961dd42d74b22504be49851f2", + "a82e90761fae684d1415cee0649bb031bcb325ae0b28f128ab8e3650bccedd302a70de1a341ca8decfdda76f3349cad0", + "8ae353188b4b98835f4ef0333cccb9e29e1ac3ec11d554bc96f5880c101cb3c84b8eefe72f2287b0812735339fe66cfa", + "b8b41135bb1a1ffb64afbd83e2189e755f2c350e1273cf47c38ae9b8c4800d831436a69458b8ef9fa8b95a148d8ec9fd", + "96f75a04d8752fa93dc1eaf85ad333cff4eeec902a345576139e16de3a88eeb71b6726224349bb9844065cc454d959e9", + "ab82b05e3923ad4c26f5727c60dc0d23063c03f5a4fd8077da66aa87042cad1bd99586d4ab35aa5e4ce6f4da6fecf3c1", + "a50c83db91c26ef7bf1720d8815b41bd056b49fd99710943679a162ccf46097a7a24585750ece886e38eb4fdb866fa37", + "a719f667914a84f62350dcc6f4f30b9ab428eac6837b70318c3ac491c1e69d48af5e1656c021818f377d911fe947c113", + "a148807aafddfa0a5624c7cb9e42468219e4bdb9994ec36bc19b6e6d7c4a54d3a0763d13ca80624af48bbd96d73afca5", + "aa012f205daf22a03e9fb13a63783dda7666f788a237232598d02a4d4becec7a699ab493f78d722ce68519262924c708", + "97fc15fab5952c5a2d698fd6f7ad48aff1c8aa589f7d3b14285fea5e858c471cf72f09a892e814104fa2b27eb9771e73", + "8da8840236812667c4c51c8fc8ab96d20dae8e2025290b9cde0147570a03384370b0fcbe20339c6aff09cca5d63e726f", + "b477d85359a8e423fed73409f61417a806cb89c9a401967622aba32bf85b569e82bca1b3394c79e180114a0d60b97316", + "b3d6ee2ed1e4c5cf8ba2c3a4f329832e41c7fdcbcda8a3fcbe8f60967fdb1717665610b7c1ac65582534d269d762aa09", + "a0b3b30b1b830b8331ee19f96b4a4321a6b93a3395b95d3a895682c65ec6ea64774b878b93514eaf353f2e4be28617b8", + "a2b88e9617f4d30ef4e686d1932ad43cd555fadcb5102e51bea19e6fca649284ccf4debb37b5cb2090ef386fa5bf5327", + "8a4446f7e8463ea977a68d6217a9046ad4356d6fc1c18d46c5d2ab681ea977b8faff136d65abea6bbf8936369cb33117", + "91e7464bc56e03f436228104939ddd50caace5a38f68817bb2991e193b57adf6835152bbf3dbcdebf0382ac9823f60c9", + "961a441e6cdf8106c4f45e5b47190d35644faec701c9cfc41ced40cfdd1fa83752fd56c1ac49131a47f1970a8f825904", + "94b7b165cc71c2ae82976b8f03c035fb70e90028992b853aa902c0467b384c7bcf01d56166bec5def4453e4d0c907e52", + "a5d32cffabbf547f900026b34ef46f08075b7a244565f615370d2f04edf50b094c95088a4a139ce07caf55bcd99afa07", + "b4e06e73660745f75ab2f34d9f6d2675b58f80f911ab6dd4c5a6ce1095f9a2b50d86f6ff9a05394190bdf96af0827920", + "ad3fd8f83c0103b29d41319209dffca201d2b98094362da08da3fd6ff0ba96796b49d6bed525c9adb96c2954858e7f48", + "b0c27430695f0fd20ae31e1ec621da090094f2203e17411db9384695ffcf5c7c6badf461ba49ba70164aacebd6f278ee", + "b9bc6e972fc3b532fd2b1eeafc4bceb77604885f32132af6a9a842fa2440df452f49ec0cd9d86da1180e8deb0723b260", + "9729e22d6104b0174c136a854920f542b384d375040adcebe36acc253bdb55845eb43e34dc5a7cc27d22c417973c24d0", + "a8b420b36d48786c9231d454468a6e855dd7f71dcfd095efc9855ee70dbece0f06ad277f7829c5813fc30524c3e40308", + "8757dff5499668c93fc5d9cea0a8db61817b8ed407200d623030b5849a913d12f8371b667cfde8d8082026eda7407e8c", + "b859ad747ca5af661fbd03a1a282df6e84c224ecea645bc2d4ba5e35fa06cbf047387319fca0cbc76b712398c0798968", + "8e3173c27875f1460297af0fa736c945dc842ec3e476a973d3d5f790bf183ad3ffe96ac13868c5101d8e299890791864", + "a9d725e2b92c878be42b5eecc2c3081c63c7231ccc7e2dee17ca6a4caaeae22788fab1f1465fcbd7fc236613fc2bae4c", + "86f6c4f04a354cb2470ef91914816fd740f8d5795ce7ff981f55a2634695fde5951bbae7a4bbc4c63747040f8644170a", + "851773cb26f320f0c3f252d95ea7e058ffcc795dd0dc35e459aa1b6b448238909230d809e82022e64b7fca5d40b8324c", + "8962641e0306220d9892fe2d452caa286301a3c465185757be7bce2d9b2c9beb3040280099606cc86773e43941fd3439", + "8beb6e08c440b0de5fb85251d39d9e72db4e556a2dfe3dae59efd8b359d08492064cebd8d8993254b43bde8bd67d969a", + "a7e047894466ffe3dec4ab8d5462f2b1d8ac0df006b1d2dd26caf499ea857d93a811cf42233f9e948c9cb903beec004c", + "92eedd95557a91691a5e2835170390ce2401e223da43b78615a804c49566f9d31cbb7f10c8a8390c4bdcf691544fdba9", + "a5e5b5d8fa65824e958bbae98d146b4b332f97ed50e0bc2c58851dc2c174ab71bcbb1ae015cd2955c26b368487dd862f", + "853a494eafb308175629d581ed04bed71bbc3af9ca4c0dc483d03d27c993a2bbd88cea47c2085a6928d166fe6938fb77", + "83f06b88d29afbfbe8f61811690322ac4fdd6abb9a23612162e7a2dd6bcbb5f14cee298ebebc1a382484f7346dc51e60", + "8c9cf05735ea5a0e563490bdc7ed29a4426643711c651e35c8551ca6f855c8458ae8f0933a022d0bb9a952edfed411f6", + "b906b48d807748a26cc2a8848455a76ce502261afe31f61777b71917bdf7de2fece419db636439478c7582058f626c29", + "97efe1fa7c9b25d8bea79d74b6cdcf88f63f1e865f54b58512a2e60428630b0b40b8b6af1b5f71df47520507548c3cad", + "8ef5ca6e753818906bb3fc71405928d8e4108854ef0ef01c1009071b353bc2852e771fcb619d5fea45590e8f61003d7f", + "8e4d901661e2913740d70ba4d0745df5e8c9c0a260149d9362beadc7e669630ba909ff0e8a6cc85c54d6b7435d0d351e", + "b7c6ba3bebbd9592967954e3a480ee8df1d9f5965f04e7d78a5415b645128deae7ddaf6ed507c8877bfca91ce078e529", + "840bedb0ad4e25acf6cd25dee4f98fea495b2312dc5cb7a8388c5ab00b2acb9cd25da08e9fbead145a3107972b1ccd5d", + "a8d4578dbafdb27f3911af59962d89e75dea74db55346720357790da677312c203107d9c7911535aa563446fde7d4c47", + "86d3b77f231bfa09251b7fd2ce09c27ac520ec35d783e912476f9a4863f83d269eb175790d6e735da9260293d707f8ee", + "b34909f1cc033232652da0c34051a769dc76adb1aee00674a59dc1b860f6e610974c3b4bb69a69ccc73e01f042431242", + "90799854d0cf34e1d91ff8e101bc7c5007423d34d2f3bd9adea2ecac57e83f3a65a506bb93d4caea49b29f6d18149957", + "8ef94cde29b037e19a1ce7bf4418ad3c95cd9457412796ea385750c19a6690f13a3bb5bb6a9ee81e7a40face1e0a8bca", + "97053d21ae8d75972fb37f6fe516c38c32ab162fb56b9f510f954858f4e3ef6ac8c3a9557ed3f41b7b6aef05fe97f931", + "90a9f9f0f40991f3bddc58b92d40382147db22cce50d092d4a05aad251b46b94e71ec9f7107a180243288059fcc5ce29", + "a14265b1344ac2921b0f890d13bcfc432e4f648ce403e261fce4d3bb32ffee9e2794c02830346054f998e82784c77040", + "91928402ae121e56a3e64cd6f390127e6e92fbfb1967ec6efa4f52f3e8058f1f41a0f4fe96b5bcc11641c1139e790b2b", + "921c8c92b6d40da6c5a7b592acc74fc0f577d93767b9aa4a1cd302a72dbf503a1ea5b2c29fa0d0359bff3b8f252246d1", + "93ae0ebe0e8e133fd80cf67a499047e30ec4c4660ccec9d49098717ef57721a030f423e00c5e74af4ff4acf014a10497", + "82c865e21905aebfe0496af1c6ac7e342b5f446a9edb4f7da0f2fb0340abfd8e6fc545da874459d9aabe6bce0dd9bfcb", + "aee3961d8d2687c0f134b9c28b920bdc4021d925fbe14323c84224a9fe161248789249fb85436a5891d0bbff42c2a3e9", + "91aee420b98b6949482b8ff4be996b97245b4e8f583a6e085226539074f42aa89818395efd1a6699735a569bfe19d623", + "a48eec22c192e495b01722d0016a54acc45ff837e2a95c4294ce81d5a4e43e0053a6f0ead8a4fb3ddd35faf6607275b0", + "a26e15937c11faa30ffa64817f035e294cab0e839f73d29de8a244ad039be4e221eb47ea08d9a4658b0152fc3caf6110", + "b84450f948aa7c8682fccb9cae84d8e3558adf2d0ca5fb81eb200415291158720f8f3470542ab5b88c6873ad08e7fa9a", + "a8e8ec27d0608d020169a85d6ecdb40eb402f006a3b97afe32cc01987721b3a68a92ec693aeb4d357e189e05fadf699e", + "ac87cd535ef5699312cc26f86adb71baa0be42e858bd5a2d94ac05737dac63430691e29b9a30d2559ad581a172519b2c", + "a4481e67b524f8cddf2046625efd3d75efee6aab87ddd2c1b22835647e918157e5e924ac760db2195c86d326f3db1615", + "891f29ded231486ee826840c8895cb325f7e84a5a6d2eac246cb3573612cde274720233b1978318a57ed337a046330a6", + "906b6e750e6178289012769807d2598925d7e51c260c14497d8af978b1695990e3352e6e809a752f376597a68083870c", + "b7a056898ee1e46f7f29702fb39232f678ec173eccd170303b3b0a30c8d8cf1a5321384e3513e3b03bb742c238deaa54", + "8f2f035fd96c3a336354c89ec9b8222803bf42e95fb2412c28d4e75eec99c1d4d402501ccae17357b757db8bdb0bfeab", + "81228625ffcedf977fba9cfa13f6edead3985e2651d5974789c394a69401cd7face9e20ae6694be4c0d4bab5e99c61a8", + "885a83eae25e61439ad809567a2ab148583402e01cfdd77b0e37ab4038935425c64b4e0886949bf06438c35e80aa13f4", + "8926387f48752f6933899c48e038cf14e7941ec6a58bcc0a436614b396296a17aa53e6873803dd3041dae470bd493fcb", + "95d0d3fa061f4d856eca78a569aa132db14cede7646f97e2aceb6da0c8ea53195d3b7a566fe5ec8c41b95ecdd89a1c6b", + "a3c817f4062ed6aa94064ea695d76c1825f3bf77b310fe1db28b8bedc9aaacbf1019dbd128adfd53042fb943d863a2b7", + "af1208417aa584052da309169854149ede38a3ad63c76cad6e43afb6f1a7b854edf8310a0b00088c039259cedf0f859b", + "8b713fc3196bad35dbf364089049ada5477e540d78d76a5f0a9df98f7ba4a0e65dd0644509c149f9b07887298bf74b04", + "89c09c43c5b733c4a417cd9ebc0795cc3348b72778d31828a9171427779a82ef023c1a4fcfcdc919ae25056f9c826fde", + "a0759c850ed320c8c874435e90ace6edfb8e7b3f2a09d942b8ad8339c508044ee2ee26c70f1b626ec49a77971433b6a8", + "b85cbc58d4fd52286e714ac4eaaa0b2743a1de06fa03ddf8f6668ec6f1d204acccce93b10620272afb8c0b49bc4b0a43", + "814e0a87384e159892a8d23036985fa3f489c53bce192e107bd2d64f57b1bf5ea0acc1ef46c7a42bbc5cd0924d92b4a0", + "aa6821da96ad89d7881b878e141076522f104ea9a5bbdd1fce9f641898f7d6232c518a87a0f666871d7e3165c26081e4", + "a9041d714bfc067b5427252186fa3557bad598fc0067dc8521aa9bc1ae298f6e96113db5ac9f6bade9a85d5a950c9755", + "b8669340f3064692625e1bf682d34fbe69a61689e3aa6d6a3e822c781d406b0300dba9c3f7b8152a8c2513f1310d4291", + "a78c53316ce768a1dc5968030bf4fc885f4029b1ddb6a5d84a61c85af686c73727f62823891edfcb6ccf4545de366cff", + "ad1d3aa29ea28292ddd438c865e2b5d93f32cdf009e6d5f5dc726de996583925727e6348bf1c28c22dec0bd86aaf867f", + "ae1447a2062e9e28af5f38aecc60fe150cd10c2edeaf2110034aa144f6235ed7fbce432a58805d4fe1f6b12652d6e1cd", + "a32146634332d3303934550705353c6d4fae5fa5985105bba35041e74cd71e2aad67b45da171221f6ed80f36bf6dffa3", + "a232e8286184196ea77427b53d8b52c44d758ecc42d22556529db3136379b4989dec61cff610cc6cf6700a450a847a94", + "8a72c7255125a736da52dff5f77e44c3de29f88fc05f5ff9227c69df296930caaa11446595e6bea3bd946baac5ef957c", + "9688a981a9457678067f629f8efa6b522e7318b529f88d37ef56c5bf8f1c34fb9bb3a918ab73caab82bf5abb0c03518b", + "88286f3eabd71115fc3b17a6bf6981340a81cf7e5f96b0a1a016d4ec8c18fb486d46c70919123d0c189a6f5d6ff29a1e", + "b535e701b40d793c02ac0d625ca91620d3f4a512aa9741f71389e58381008b2f93d597586d06213c4e103d67d0ddf6c5", + "80d0c9dd941e8d8d3700cc51a434a5aaa3308cf8ebfd14128ccfd258f826b27cc3cf5c3ad7851340393abb1eeab3a157", + "87049225fa2380d93f18d3d90cb0697a56b373b66d7f24ab209966aed8b55a2790194d5885399db29dd5b1f189eda64f", + "a52df158ce8670e0290551e8878d63dd33b4759d6f50e448e63fc7fe6ea99dddb6f180be5fc0fc3918ce54c05f80b356", + "8b2a728b39c465fb0f60b0c486e5dc8d5845ccec03d3dd93b393cedeeb3fe1b44518359f1ed55fc770a8f74bfeb9923d", + "91fc05419dba718fa4a910dcf256ebea356bbea00522d8d5ec3e7ba4271a26035aac15e8d9f707969df1d655d92dac55", + "97c8779ae80c24c1f82d5a714762d6ee81069224e39515e41d8a71c9310dc5d1c55cc92bc5c6a4bd391ae4c321d1d4d2", + "b5e5aedba378c4484e3a7a4ed41b75b0844f674261c2501497de6f91f7274b5a4c1be0e055f2e0c0cab843d891169fbf", + "8a26212f27211b295beea500abc8e9d430a8500d3a350cc62f895d39e8b4668aa638c17633804ba353010000165637ae", + "864a95118e5d394e00e99efebd505df0125525c9ebe165764c453b80ad3edc730feebde3d93850745dfd88a27bb8f20b", + "a092e0b78290e826cc1ae56afffdd08f7c10954f549a3ea6666f3db1b6cdaeb7df53db28dd2a92446342930fe60a27ce", + "a1720224c0626a081b6c637b2a6d37da85d9a82241e5efef3bc15699b02a69f6304e43d8ff3144d60c16e00225d6b39e", + "a7b3d098cebea9cf32e19c5195608182b6afe9d4af6b9df532c047eb7a941a971279b2ae6a4b80f2f9d9313a6d788ce3", + "a3d2451e6788944802c5077a778d7b7299dbb9d1612676bb6baae78f39976e0fd879493cc4a4d737b8174b472a456850", + "930121b73da844571b1411d56760e80923a4ee09917b3e9cff4d3dcb0bc27026ff2c4e2c44e7aca7d3f8383f129c7f9b", + "b4b0119d163ee00a2b74bdf188a5cdcf054daaa48c483b94bbb4d09ff615afb4a91347db6363bc7535e2af9054ec2214", + "a5846decee706780201095a8cdd48fbf3d3a2eac8d089a818e5e22c29457494bbfb4399323b067f3d2be2197c33dbd98", + "96ba600df10ee7af5a9df29c0ca31dbed275d647faf9c66c7342de927ceb25b5bdd852dd7aae0228b27897f90fdd5d62", + "b6ac51ddc98edd9fb9f54ef84bf372a041d58dfdf0dfdbdc4b08ddc1a7ba93ddbb1413dda3c1545a3fd7386c6b85975c", + "b35f3efd91a0723e0d486188ea9675a3462106470455118392d7610470b623caca2fa33829721c05fbeb0fabcf570bfc", + "87f49e85df5f8055714a8ce7adf37f6a278e64e76ed74c60abe3edfc3611ef5b0426d4c6da45e5f3b74d30be1dc6f539", + "8ff8bb06902a71b1e9177a77367318b2e3e0a88f5d74d6907ca9943f4f9f1ceb5f297132c2a025259d17a67e880d1bad", + "85eb6de6c70fe5c53ab0ab27aa0fec439f136c979c557d317337cafa6e6c5cb3169679c9169567dec5f6c72b3c057d83", + "ac18715ed1080771d760cb7066c6328faf65d9b30517903f8a5cad8d66d5c6381156b521107d7cd75ebb8c30e250706c", + "b95b9eae4703727e4ac9ddf2ae675906487bb78905a5f9cba74a4cbfd118d96b7afb6ef3ed5edf14fd963b830d71338c", + "a3b47b52fda16b62b11c8aa4daa56b0b669c4d5c56a3059b7d063284d8a91f6fff9ccccab23d6ceb9650483b2d353039", + "96a95b3f327df94c85e92f2e406f1649ac621533c256b062738f3c3ee137059a735a3e6072247acf57b1b0d8c219bd7f", + "b19b33cc04570be94eae8e943d5bb17bb0c96e9de4ca84f9f41b37320a1a03d397d53747dc13275fef1b356de557214f", + "a1faa3dcb931dd91507f3f12a17c43f6627fa2bc5c71fbdd27548e091eaaaba262477949cd51290e81196bffb954a492", + "b060a16079dca1d28a1fb33cbc26f368630ee042d980ce305230005d5b9ab533a7a695281ab76e9214458303932d8bbc", + "b303783196a858fe45d67e0520c30576da605fd69964449c20009fbd5099cf1de52a32d326d7c3b864de07440195ef40", + "aa550a4c20d1003d137ffd8fbdc1196d09ad53cfa0e202302093a80fa3bbc4c9aff83f34f2151785cc1ce5f30255693b", + "a7f8585f45566a351058e10c6f1ff4a7ba24811f1482a47202f581525615ca770da93f2f58878788b45b92cb446ef4ec", + "8206f63a9a5b59bd68e64a843e68fcdf706f4c13bbfcdfa9928298e5b9251006ae0bbd80c715aa3c9957d2c0148b5059", + "ac9490abe1241319658f1c2c645cfa01296f5d4106020c7894b7ba4a65cdd52f6c5401bd3b3cf1c9863e088cd8c9a16f", + "85dd6d9c80a1b58c24c4d2cb7590d33d2454f381f58e820979948e5831972360cde67bbd56e1860077ef5192fcacb904", + "8b0285944c676fe2519cb68da0973275fa29c0718d838d363ce46651b068d29f867cf9fe579ff8da0bb8b37d202bb23c", + "95147275da658d43a758b203b9ca1f1c1478853e9bf77b5218593142e2bd9c0bf46d2206ab64cef99295de6e9a268edc", + "b8efa187fdd3e1f46c15cd596e9567690c10e253b5beaa5be8074b6ea4e6d3d06e0f2b05323453239e419ae1e7128521", + "8340464f52c92e31806fd3e8e65f56e27194d1f6daa4a0f0b3831e8102aba16f88bb5a621633ddb7dd0342e1d2d12343", + "8615d87dcab85a78dc052f05a01e751176b756b5dc9985014347454ce5752f459dd6464e1c5aff36cb6c51b783fa2692", + "80c6e35c0d3defbe4d3968792724a23f0b8830dd2fac58663583a49339ea20f1812cc4140e3ee867c7e716177319bbbe", + "a7aa63dbfc201dde8f29bb6e23d7aa5020dd35bd18a0cc93c8a10c35d695913fe25b9e8cf9b5fd1899e9657b22bc8863", + "97c2a4ba80c4caba2e729a603d2faa0120915e3fe64cbb065f7ff33de5f877f1ec9461cf455e88ec9e9ded9393939dba", + "a54bd1419f0e2d2d87757870f37c476c7e3a13502f1ada82fd7394fd29f8a00c4986473d753034d0954a2550badbac0b", + "8d3e2bf900d0d2b9b46e6e2f37620f0cc90526dbbcfaad4e4a37ed53f39fdd23bd3a6f21aa7e800eaec937d9710dd6e3", + "a88d2b1c7802b2dc216c2b6532406c091bfb12f29121b9a82c1154470e250188413ddd3e79f7e009ea987a4c45b332e5", + "8c552c2101dfdc3f99c2da436115452e4d364eefe029b12946f05673c5ce1cfb48d39a579625849236dc6c8e7277dd30", + "8415c252d52a26a6400c3189c928a98559bf24162ecf3eef1d10e439269c31d854b0b4f6ec7a2430e3f11b5d77de78d6", + "8b38905bad93a8d42339dbdb5e510003c51fcaf05e04f88fd7083753353bc1c4c00a5dd4a67431cd4456d0669c7040e2", + "b1d0ed8862250d0f0d9ef9dcf0cd16d84313d1a795dc0c08e0b150dadf9ce73d32d735e04632b289cafa69a6ee75dc89", + "9434e18a5fb631b10edb02057f2d1fe16000ee55ada3c26a079c9fc3943e29d6de99e52829fe7b333e962270c712e51e", + "b1b9f3914007e6fca8ad3e7e848a1108988cb2318da36df24767d804e95d1272943fda948451135cc1b5052a3953b081", + "8c02947a76d7b6c0a700a83dfb971dc105bfe996e18c521445f036310914b349ab28e57571e36ae08d13a46fb01c2f43", + "893472fbc225f973a0ac6a0a0130b9cfb7ab6869dff80df71a62b1f6beb4afd069bbf35b4f327165bc31dff39e4fcaa4", + "a7c176c0903175f3540d62f9afee994d5d9bf37081e094644b22f017e94c515afefde7bb07f638342abef7de657f8848", + "860186c2b1d3b1e657729bc804275fb5f5ee89eaa60848fcabd3871289665ea9f0efc8a95792d884972bcfa2de96223b", + "865b38aea6386d0ac8f501a7d934e23d01dc50105324e354d4c4fa3cb1d4c29c26f4566df7b1a728e10cfaa9d24552e6", + "b4eea5548de6969dada658df604b5d9c49002e2258352838003e0fdf7b299d81fb025807a7f37cf5b547cebd7f2c1f93", + "8982de11ba68d63a649a3b296d4d56c71e3c3eec016db250d733ab7c3b9a620c09c5a5d0b64fd30d3bc03037ca4b17c9", + "84d8b8a10d67eda4716673167c360fc9b95717cf36ef1d5bc6f2ef5b9d2624f0e76c2a704d016adf03e775ea8e28d83a", + "834d03ebd51aff4d777714783e750b84c16cb6627f8311bd8ff17c3b97fc4a5bba57d6c8f6d74f195d3030bcb5f07612", + "aaf49e0def0c4d5f2c1e9c17b51e931d2f754b19e80070954980b6c160178349f6d3c8d4808801d362e77f41a0008918", + "8ef4115edec841854e89f2bbd11498dac7396bca35dda554290d3db1c459ffc17be671f4a46d29fa78cbd6064cc2da20", + "9641dc8a64f4acd38e343a3062787c48c312f1382f7e310ccea3e95e066ab6dc980f6ed90a633236a435e68bf6b3c625", + "8a84cfc2cbeb18a11dd6c2a0aebb3f6fd58a33bb4b26101e826add03748595022e816afac79a4e7c20b3805252839dca", + "9770782d729017659844421e1639ffcda66a2044df9e19769b90292df87dcb146b20c6b9141bb2302029d84a5310665d", + "98c7ec9696454868ac52799d1c098c15ec4e08b34884dda186ebfe87d32840b81fd3282295df141c91137faf4cc02da8", + "a3f6eb921247617292162dfc8eec5b830ddc294a0fb92f5b4828a541091ffdaff34c392c1d7168259d6204405d90ec72", + "b185f77a468f07a54222d968a95635234e74fc942485604909308a9028ed2753b15902b9134749f381f7cd6b89cc8c3d", + "867608a682d53bd691dbc92eeb460d1c300b362ca49c11a280f6768ccec217f1145f9d59fe50d994f715ce89d38a74e1", + "afaad630ad8827cd71aade80edf3d7aeb65a344878db12fa848759e6233f6fceca563aa437e506ea9e0f1e47b126d45b", + "a12afbc84e3441594aecf85d089423dd3bb8bb33a1a384ddf7cc14caa72284caaa56aa179c15e3140fd56bb532491a67", + "98757b0b5e5837ddc156a4a01ce78f33bb1fce51e0c1254ee9b6d3942268d0feb50b93edbf6aa88f9ea7b3c0309830d8", + "89573f4a4ae752e9f964e42bec77d28a41840c28e4bcdf86a98a131d0b85367b885077823a6f916972de6ac110821bd2", + "a17f2745052de5de9c059307308fc49f56cb5230e7a41cb7e14a61c9efa742ee14c41023ce90c7f2261adc71e31045f8", + "914b07c53a41c0d480083f41a61c10429ea42dafea9a0db93862d2269ff69c41db8b110b4768687b88089b5e095523cf", + "b380cc3e0d26370976fe891d24ea4eeb1b6be8cfce01f47fd68838a27190e644fd57b049d3aa0a9589370de20e276944", + "906385fdfad60feec79eb1c303e750c659ceb22d9c16a95faaae093daadd53e7aa039a45d57e20951d6e1ca0dc899ef2", + "b5211ceee31b194dba60b616bfd91536e71b9213a3aaaf5aaf9b2f4cbdeb05191861d78b97eec58e3c81abe4f0488c04", + "97878e9e38c2f69d697800e7a2f132fc4babaacf471c79c26a757f771606e55fe696ece68a3163a0ffeb2f72274cf214", + "959431c1f54c46500c05aaa9a2bc4230531dad97ae768fa92bb85436c0ecc6374cf20fb0ef82d122db116820a943b401", + "b69e5a1c6798f30d33e42cb8d124f025d2c77c993c4c7107a539aacddf44d8d4d2239e802ece32e60ee4dbfdce201bdb", + "a8b09e5e9f802ad273b2efa02bcbc3d4a65ac68510510b9400a08d75b47b31c6f61ffdb3704abf535a3d6d9362fc6244", + "a41ace7f1efa930564544af9aa7d42a9f50f8ba834badcaf64b0801aaed0f1616b295284e74ca00c29a1e10c3de68996", + "a8f2aa0bbbc19420a7c7cec3e8d4229129b4eb08fff814d959300cd7a017ddb6548c9a6efebad567d5a6fde679a6ac6a", + "9683da74490a2161252d671d0bc16eb07110f7af171a1080dc4d9e4684854336a44c022efe3074eb29958ae8a1a14ace", + "8ef44d78d10795050c161b36afa9ab2f2f004ccf50fdeef42fe9cdc72ebb15a09389ca72a00001cd6d9b1d7b3bb766c3", + "adca54f3b14fb18298098970b0267301b7312afb75894deea1b2afa3e85b7a3b4efac9971ab54c5cbecba2da9f18507e", + "ac5d4528f06fdccfc1370d5c3d03ed982fed0861a93a3f6453aa64e99360b124926d1892faaf72d89459e663721dfa99", + "98aa1c801bd615b8cba728fa993021e181e0ad717ba01c0290e7355694155407083eb53cb70819c4775da39d33224db7", + "8b3aea4c7c2bfe1020de3261ec085d79c7bf8a7903b825d2c70ebbb84af197bcc54e3653c5373a2045c3021526b63b66", + "a29f3de4cb3d99afff1daf7d431b38a33a9804fedc41626618928ed059df6f6fe9f298a046b594ffee951ed4d4e1400f", + "803fd346be540c5242667c18ee41b26bc812456ab13ff117196ed69b90ee608c8cb6554396b64066a546ec87a71ed6a9", + "a9c18d81ffd029c0339c72c499bb51685392253b996b6eabd8b76f05c6191ed8444a1397d63b9923743661a319517f7e", + "a048d5c390d08f07161faac71c5994baf152c883b205f3bb10d3501709d6516ae54d491b486303a11b751857a31f0052", + "9156fb4803e40e28d8d57d928481a8de4373687288da44fe88c5676a8ae013ed1fcc09d56a31140bf74e7f767253810e", + "98e289c725b18e0085afdfaf2acbc674dae7b0a2ecc2537a7d0b87e20eb785404ab05973a787f0495d2adb3e5565c09b", + "8a7237b249325bd67cdc1f9fb278710069033c304afbf270b7ea24dbc10c8eabe559a484d3edc733c77b4384932deb41", + "9056f2e5b02e5c2e04a69fa1323bbf1859d143761268d18e74632e43800a2a9c76fd681e924a19bc141de0e128d3e462", + "b9f2bf9e4e7263014296a82b9ecbb05d3f1efa4b2e675e3b38d3eace59da06a89c859256e1b77847886d6aa15f98f649", + "83b22949cca19030289bbf7cd2a0d8b84e1d468e78bc85271a6753241b89122627632723bc293cf904a5eb2b5dc6c3ae", + "a919aaf35dd0116168d2ee845122026416bec9633df113fbd913d8db5996221e234f98470d029a8ff182825b59fda20a", + "91726901f49d32b41afa15219073842278f60dcee223640903d871e318a1c2b541136b7b38a7b2ab7d31e4242fc29674", + "942b77666545bc9a858d36cfe857ab1a787c9528f4a0b87918a06bf510793264dcafd12ae6bd3ee300179dab7f40aed0", + "80adc1f2f9c47a96d416e44fcba41628abc0fae1f88f6a26aea4648419ab726f7fcc2187c7d5145e3d8f5a75c03937f4", + "8041e0f66ba9dcee01e336dd4d16ae5e4e1618512fc147cc8230003aa2940848162dc2187d4130bf550dc1f3559849d4", + "999e8adc51bab54386af1c5e8822986ad1b7ecaf1f8a4c2baa5bb2fe9d10710e49545c5a8bd89ed0e61a3d73a908e5ef", + "89272ffd39b6e9f99fafdd58bd9dc00f66f26a1d36b38a1ac6215e3546d966739eecda7fc236335479207cef95cce484", + "b8e0b7532af13f15dc04a0eb4ea8abd67e58f1b1c6ad2e70c0ffa04a5c18ec2018b5d7f4be2f9f86db5e0b3986f639d9", + "b96bd11b0f6ead4abd5fe1e4c6e995da7583b901afd01cc05e87d04663fb997997d6d39dd9fb067c62cb1b1cbb67516f", + "94ab08914088b973e8dbd5685decb95f3bf9e7e4700d50a05dbf5aaac9aea4be2c10c83096c02252e9238ceea1351d05", + "a188de419b062af21275d976494c131ba18d2b2ead8bdbfa38a777832448e64d4d9725c6a1d530ffb6513f18d5b68d9d", + "8f73c8c118fa25c76a4ec5611351953c491452743056a819c8c82ba4737a37d88da0b55f837e7239a5f46d2c05a1bbba", + "894a44769e0be1c26648b0d89c4c9f46dbdeb3a71b90c493093bee372bb9f2d3f319850fd886d51f4f58db0de5641742", + "87d239923b0db024a8d9b0281111d47b0761d81c50652268b074efa3ea70d793e30f874a91ce33a4acecd0cf38c01951", + "b1b48b75a97f9fc2dc9530dc69f6268829dd0ddd574516e7eb1b9f5c3a90058889a7bcf3d378738e6d4b02f5fbfa44db", + "83e3ee9526ffcb60c6e75b75550fc017912ec0daf96d0a0d5f58c1b229cce90c684ac7c3e17fb998def8e7e2e155d750", + "b9b7bba579e474b0abdc7775ff5f84c9f117c6ca17788cf5a5f01b2c35a14aa39036031c8d799fec2cfb371d9f7471fd", + "90d7faf4891fbc368a32f575dfb69f13e37161ab4f63a7139be103285a49490c2851a907f8d36e09e7d1a190dddbc6cd", + "968c8b9affe18fc34a4e21f0d8c5518341c566099e6b45b8721c9912bab3693c9cc343406fe90279692a1eef2a3f7311", + "8735baaf4704207550f77df73fb701d9a63329993a8cb355ccc0d80daf950145f37e9b4b22be2aba29898e974f9fd552", + "90f52b2dccf525b9191d836b205ffe966d9a94f6c5800f8f51f51f6c822619e5abdf1257ee523597858032d2e21014ec", + "831209f8f5257bb3eb452d3ee643d5f063299f8e4bfea91b47fc27453ac49fd0ba3cf9d493c24f2ca10d3c06d7c51cd6", + "a5a4db4571f69b0f60fb3e63af37c3c2f99b2add4fc0e5baf1a22de24f456e6146c8dc66a2ecaafeb71dce970083cd68", + "b63da69108fad437e48bd5c4fc6f7a06c4274afc904b77e3993db4575d3275fce6cffa1246de1346c10a617074b57c07", + "a449448d4156b6b701b1fa6e0fe334d7d5dd758432a0f91d785b4d45fb8a78e29d42631bc22aaa4ea26f8669e531fed7", + "aabe43de1350b6831ef03b0eef52c49ffb0ccd6189cce6f87f97c57a510ac0440806700ce2902e2e0b7a57b851405845", + "91015f144fe12d5d0b0808c61fa03efe0249058e1829bb18770242f5fb3811e4c8b57ff9cb43deccfc70552e4993892f", + "8e9c570811ce44133ce3e0a208053acb2493ef18aade57c319276ad532578a60d939ed0bde92f98b0e6a8d8aabd60111", + "8b21839b5dc1c9a38515c1076b45cedec245d1c185c0faac1d3d317f71f1bfebba57c2559bcdb413d9d7f0a2b07f3563", + "90413bbd162be1b711e9355d83769e6aac52fdfa74802d628ff009325aa174c68f5329ddd552ef93e8fdcb9b03b34af3", + "8b6b02e3f9dd1031ebd3df9a30432a3c86e64306062ef00a6d1243620d0cb66dc76f8d0d412eceff877ff8768c2696ce", + "9894b41d9fc715f8f6addace65451f41dc5ce7b983dd8cb33757b4d7259bef12f144e0077d0b662aa847d5a45f33c563", + "a353a9740f6188d73aa4175a6c5f97898a05ed7aae9d2a365f15b91dfa7c28b921fdef0a32d90b6fb82718b33d3ddb8d", + "984eab8faed87c403c9979f2d2340fb090cc26d00cb4092aeb187c3f4ee1df3f57cb8363f7764073188790b16dfc464b", + "a5c5ae0ba435fb7f3ddd5ad962358da326239ff236fc3b51bd22e88296236b109951cee1b98f444302badc58d1b5bfbe", + "880be1006b0156f2788813432f450f613d235f41aba52a6000d2ad310408ad73d86b79f6081aef1e8c51010d404ba670", + "937da751aae68f865c7a33fa38d718f20e2a1c65cb18c8e08f8441f0cdc77662789d2793794dd0a427cad30cd0b33f42", + "9496fde66c834ff86f205897db12bbf9a9bb78d9ba8b5fb539cd0a2c927cc6b4120c017b0a652750b45edbe5f650e5dd", + "97a6f409ffeb593e149307a14bc47befb632412d70565c5f13d6b7d032acd2e3ed0f7b6af701b387f11d69ee4a8094d7", + "97ed94934263dc0260f4f7513745ed3483cdddb9adb85dc33193c3a8b4d52affaf1ded23b59c34651afbffe80d40dc36", + "b2b26378d44f916bcf999db218b9892e06de8075f205c7dafd6d37a252185c2d1b58e2e809c717963d25627e31f068e4", + "b8f9fa1fb45fb19a45223f7be06c37d3a3501dd227c3e15999d1c34b605f888123026590697d0ae24d6c421df8112520", + "997aa71e3b2e8c780f6855e94453c682bee1356b5ce804619ef14834475511105b1e4d01470fe4e2215dc72182d9909c", + "ac2cb2a7cf55aaf990cfada0218453853047e813d3f51f5a623d09f4714da79de6592671358a5edf938a67f905b6cb5b", + "8d8340d0c3081cd30d34f3ff6191e1ff6ad7994b4ebac19e5936f1157ca84e1813228b7605ee226366d6bab1e2bf62a2", + "9693b17669086003cb46c75fed26ea83914a54901a145e18c799a777db1df9c9ca6b2ea3ee91e7b0ab848dc89cf77f19", + "a6b6b2a6cd8c4922d78c8ba379373b375d66ac6ea04b830a23d5a496cf714a9439d81c865da92d52600aa4e2e43afcf1", + "89cb665020abc3f5e11a03c7ba5ec9d890fa9ed2630f1443a8e45a28c32786ed980b5343ffffaea60eeff5b313bc0d66", + "b37b989106594221bc6cf33a1a83c3e65ecdef279e90333a9e105b8139dc28384bb2277edd4b77c9e59d15e6afe074c5", + "98ce5aee5918d18b2326b30c1ba41669cce20bc7a1d1b585363305fbdea66055164a7ac398ca0f0e670291a3061022eb", + "b57f472d5f34beb4cf430d7c0f8ac5bd1c0621a284633ed36e6f7804bc2b7847f54b469c7ea163a436510d9e3b32f97e", + "ae673a6579dbf0504c8fd0c8fc0252d2f7ae8da615a06f4d215c2f8a8f516201f24e5cc42967630c252905e5dbbd6377", + "97c1501835a31091a5a83f0546e01c85ee847a0ca52fb3cc0653f6a826e13d25ddc623a5dea139108f7270a1fd7043ea", + "9376ee667f3834f6c0da4324fdcca5c04712e0649877ee19da79a2d23be24640c38758fce562470ce2134ca34148ffe3", + "818af89c40379a10074cfaba6d5968ecf667f1a68a7edaa18e8977ccb34e0829f237c5634fbd079e7f22928b277f1096", + "b8e0af0be0a252b28df25d4a509f31878bcddf702af0e5553393c3dfd4a1f1247ad8dc2668bc8dedc9b41f6ad8e71b15", + "811667ffb60bc4316e44bd04573503f5b4dc44d1ec824393a699c950e5fa085b146537ddd6a08a3fede7700396a0df7d", + "ad834cbf850b2f61ce799c4a0f8ab0c57039d4e1113933c50b0c00175171aadee84894d1376cf325bfd434c3deb44315", + "a8b7dfcdb40373ba4d55e751ccfb9070554434df9e359fc165284ee3dc35db6fb6055657ecf5a9e9b7b8e2e1abea4375", + "b56a5b9fd41c9d3f65532aa58bf71a38fcf07782e1ae0084dc537862fa02e6d66658b19d6f71c39cd5dbfac418da1837", + "a935af5ed224b9533b41a7e79f872f6851591da9e9d906050ccd1b2c772a1d6d010c5fc7160c4f8cd7d3aa14c3bcdc26", + "a81e580fc98692567b28323fc746f70c3139d989fb6aabf3529504d42d0620f05327e3385c2bd5faea010d60dd5c8bdf", + "a8b352054cdcde8ddb24989329a249b71498a5593a13edad1e913c795dcad3d24789abca9c7ed1d57efcc9e3156da479", + "b0de8a2bd7f93284b2bc700e442f52ada16a22ad8d86329591547411c23fff0333b2ab0c9edf82bf7903ebf69916eed1", + "843e9781b653d1a427f3534b2e86add49d308ca247546f9fcf565f9e08df921e4d969e1b8ed83f3f849e98c0f63e39be", + "84a4098c5dca9f73e827d44025473096101affd7193c40a0307e3215e850e753e9a08e6e74a442d57626ff26df77faac", + "b463eaaa2f3315b511c22a97fad353014d840a6a95fe0d457d0677e63e571407d7f5268f8775381a5e7adc3b4163eb88", + "ad0417edaa16cfddc288eef4173aa7057ca4f81e815541ac588ef5f24b98d56fed6845deb6ae1a9740a28bb1cd8780a7", + "9271963b8fb2288a96e07eac13c0543ec41abdc6d978bd7c44ae08251ea49994412b542c77c8208cd71fd8e7852d4a70", + "8b68b6db9044d8bafc155d69e0daba95cd59d6afebb085791e999afed4f33a2479c633d31d534ff767b8cd433d591a23", + "a6a06a0e433e385437d9996ce823abda9848754aa9cdd25ec8701af35c9ec15df999825669bbc2e17cedb597a96e8eeb", + "94d414bff8b6b8597634b77a77d1060db8e1af0d0ddfb737a9bf1c66c8430e93a425510af2464bce4a7b29bc66cf325b", + "b6514049562af1c6fb7d0e8df6987b020f0b7a6e721f4862e36b1ba0e19af19414ede04b346be22d348b50875803d1bf", + "a42c7fb34f2fbee8aaccd1d86672d0acdf4e6bb083ff0456512d7e1e43be041cc0924322fcd986e6e1bce5d5ecce6f92", + "867cbdd169a52440ae0a75d33a28c7d00aa92b4b65aaac5e62aa53a8fc367c08ab8828cc8fa18b6e7d1f908d158e3382", + "a6fe0b768fff3e4a6153e59a7b7508eb2ee8165eaf5274d41ac2812bd4563c4ca2b132f0e27ea2f1c98759cc3589b61c", + "b3eb1dba43d10b9e17ffec8def053fc96f9883bacb49330a089a0ca5b9ab0182e8b5111ad4aa55c1ce1b6f4afa5c70a3", + "a1531351098bdfcda566ff4d811301c0305626c77f954a38420c490e7c684f517eb1a4e4bd2c3904a10bac889cba314a", + "92278d106ad2f27eacdb86bdb1faa0a07a93765bb79dcff191873c52253af83480114b2299ffe5324f9c31d0abbdbbd1", + "8900ba95a90c447fb6fa1f528af3d7a378aec25feb0620516b6b97e54b328fc31af42e46a8ad5e6e3029d83a6f2bbe5f", + "86053d481179c1ac910d5e7b9a5de82794b442f20e854583512ce1f9c3f09e71d1bf97d6700fe776debfe1527ab97a82", + "a32a60de492fc4340336416bccbd2591b5e414fca0aead82281212e24490acc01747537b3da783684e27aeb987245cc8", + "9820fe8e0338f21797143f368177e3669a1f3894b40ae9fa3b353125f7c8e85cc424dcf89878f2c7667f65db3b1e4165", + "934d64711b4348ac5e1395cc6a3215e5643b540f591380d254165486b0ec2a1d0d21c7d2c6310f9e0eed3d08ecf4b57c", + "b9fd32d589432eddcb66dc30ad78981360915854cc44b2afeb826b5d48a08e377dc91be66f5bf1e783d1a8bb320f7ccb", + "98c972cf01efff4fc2e485b47572e2d8dde22461d127ef401b71a111b0603203971e3cde40912643affd7341cd27e57a", + "8db6c1620760063edabd376f4399b6e1355462e04f5c81cdcb3989fdc00f9a466bc85ed899e886c89c149adad69edbad", + "ad7b7fda0aa6e2aa66a27235ac5cc680aa04b85dce329fc4be84f75c9c961120a3d9e446aa44539aaac8ea203eecb4eb", + "8ccb01eaf41d816ce69ebd57754859e263530915e775c4e7d9dac37b2457a9099b9ae9b4c6cb09eb5ff246e3c9320c59", + "b895b83b5f7ca46e02697dbaa6157df6c7571864c83e504a8c77d965bc2ba97bf9353a71c56a020df64498bd40e30b21", + "8018c07a81c522fbc25f2cb14f2321c61b98bd8962ed8eb7d5823dbe5d1958a5ec2fb5622fd0868e991bcb6cae016ea1", + "95b16364e94d01b3664812264d7185032722a4afc23bdd33bc16ae87ee61816c741657c37138d9312cebfb5fcfbb3b2d", + "94a709209990a8b09bfb4b9581ab471aae3a29526eae861108b28edb84aab6d28f1d7a25dddd8150b70af34bee4ca2e4", + "ae06c80839c5a13269b984ff4d8a5938c6f4d8d647b1b1daa8cf7f6145340b76a286cd615ec251a65501e6290162da50", + "875cbd0694eeb90d3567da9dc7f570d97b02bd9cf17bfa011efdd48f1d580608a3213bff4006603b8b4079fa66bded10", + "b27f88c455f025e1cd902097d6a224d76bdf9c9195adee30bef4a0b0411fff980787285896e1943a62271d0aca531446", + "8024880cde783cdb2b863e3dd856be92bacc5b2a1347e96e039fe34279ce528560d2df7d4d1624a4595dbafb40529697", + "8883d02c2a5c0e026d941c785128d4ac6f7a9de625ea735b7d6ff27a5ba10fa4d6370d450d99a855d919f40d64f86afc", + "a1beb985c45fdc30ac536f1c385b40b6113ef6fabc2f76d255490fe529468847a776efa674ba8fed72180f07d3f701f1", + "ab83bd9b007561695210e3276fde72e507456ba277ad4c348a2aec7a6e9ebdc2277cb4bd0bca73bd79bd2240a1fc4456", + "8db27f516153812149854fd6bb1250e843a3ae1c9637df818b08bd016a769d0497ab6087fe3b2fd4080882713607bf46", + "b3891dde4e00d60386aeff161b4a0fbc30bb31ee7918ce5fc0b49aac3238a000ced192c9c4c08d90de3a0ba973d7cfd6", + "90a2049a15c02e59024a7a1cb0adea97501c60b1c7442fbbe560054c3d69264e69627ac57b7d9be01bef498bb2a60198", + "87df67a4bd72444b5faa4f3b067204c4927c869dd3b29ad192d859589a9b2c1d6d35ed68310081e140add254a9463092", + "8f80986a8dc8a0d6408ebbcb4f234e76413c11cb0d66067f9436bb232373100f20a4fded60f08dec3525315abfaa8523", + "b061e10beb12ba3683688a4ae3a91600d14878ef78a308d01b93e4918efc666450e3f7b0e56283468e218934231df98c", + "86b9e55f3783d62e381659d3e06699d788b88aab1ff99848db328a83c97d223f602201bf2127c5ecf419752fed0a224d", + "858d878e29925c87243e010020007f96fa33264e89c8693af12857b362aee3fac2244057e159651c476ebe1dfbd67bcb", + "8fd47cdef87d7a569ffce806d2c2dad100692d6c53e5f5dfc6e274f897dccadcee30fc6c6e61373961bbc1f3ecbfa698", + "892f2822daf3df3a759bef03168c1cb07408df62e024747a788e94d2da325f880bb9c6e136c7f6643f45b021c6ccb654", + "8714e37ac24f5a198f219e7c88a92172fc3db129e044e914663ac708d8101851e7c53fce79d32d0e6da74f2ccd1d30ff", + "ae95e1dbba8b9e2c8dfbe1c202e9ccfd04fa396470035a699b902fbd86d5e6a31732a7c8cae00b9a4f6e51c8d560c7c3", + "b0cd058e77498e860fa20c5f8d9bd09bb249add1badf84ba8d1bd49e704b9b4bcd67a5c3d211840a2c8fefab3fea639b", + "b78e468d3a7da0dd481f333ae56534e2ef97587be2e259a458e25aa37952aed1cc5f835640f812d8052f5bada8f57b12", + "835de7965c6b26e7ad1b92eb6f0261d1f376fa12d61eb618d9b342b597c9c117a5a8f6a36269aeea88072b4641e6b5bf", + "b4d0eb99136b3643468c9c48a20fad62785a60fbdd3c054efac4bd1fa7979b4c9ca6c2c0b18069c0912bea2f19832790", + "a00c47315dc0700a850966836a95f3cebfde04dd094bde0742dee77b89a05b5ad655921f86fafd1e902938ff34d4c58d", + "ab13fa0afaa92229a71ee91efae6d1b15f14b6eacefffb7401d41d0d6db24e24a8dbe8ee19b4680ecb69d2a0cb4e84e7", + "aa56c0fb18401210062dbc653df8e3732aa8921a1280e9737e99b26a0100a13a9cba8ad0317a69bba16193362ee0f030", + "8b410324a6406b345df0fa25f541ac20b7313fa55832752f70cf4c79f43b0bd3d5b4cdc447e6ba7bca08d0edffa8e29c", + "893362241ae412d9e5df46506407595c58ffbd7fb1fdaf0694c3432470599291238997abe118bf7737e56a4f5c9dc292", + "921618194a756be81cb49d6357cb392b32cc62d96c8ffb7e16d9659a0f226a0436bd378da7b835054dbe0de2c6372ef2", + "94a2904f10994928ff5367b777e1430047736fbece33442cf452018bfdeae62e84cd75cf80f8468285e347d504c94111", + "b4b81545b767f380bfe10e0fea9c3cc62ca8db40b43c83ffb245259378731298e3eb6c3bdc3a16932f88f5d8a86edc4d", + "936203c2453ff01c6fc635e4d54320d69e60047d805daae3b75633c2259108497b778f011e5a057249f11b2b888ea76c", + "b90bf6378d29339443c3f2008b1e2b5f0345f86e393027f14a295e583bf6e6c2b10f54b6dcc42079ff0d356c405b03bb", + "916913f550d327de2d8d6c7723dcef2e3869efaf95fd963d95c8980b97748c61ad8e2e629cead8577266d93fe39203bd", + "a033c6f3d5ecbabeb83eb363e54e5faa7ed2d7f4fb771b161762c4f003eac4e1afb236806b784baf2222cad54e2d3cd9", + "ab289d4a5771147e6c29ff9ac2bf65d70081ea6c6af2d9b728c3c144574a31b5fd8632af57c18c389aa2cd994938bb0b", + "9488da2019ff13e290eeac132b491df58b5b7b23c2898ff1a67bffd7e9c9464c39bc8177a57950fd28589e3d9ff9c6c4", + "a5abe42b2e0891851440fb2aa6c1d8a86b571bce8b80c8e9e2692e5cb6d45a1b2f055c9fc4c74a7cd292871604129ea9", + "90bfef698e83c2ba4dc9304aa01edd274169a978b7154bca518daef394f55857d0d1922ebef3d91fc5ecb3b895d9e0ec", + "92328f1372b6406ec80786041b6d57018b8507e3881a08727aadfecfdfcfb0824394cbb1150117ac5da5d71b89e895ae", + "9719751c5f7a65ae2bed8aff7b4b8c34539ff011b259b7ff54f63f9d987b3fbdce5c99534ed561aadaf07bb6e939e208", + "a151816774aa9379fccec21cf212429a1c68cf91b055cbb9d931f461a8d5616c693331a11ac5c6fcfbd17d84ee0b44e4", + "a72977b1285618a45943ad00f33f37102e2885eccd2f76785254eeca495068fb1d8d49865343e9e8313c6c2c3b2024da", + "a6f5ad2e023a1585d90625c9f7094f0e8851c79f0eede8ec582ee8e063407cc5b8298e5fdc4c786e4fbbcecaf33e787e", + "82901e008febcea0c0a14ae21d985a397630e18ee6e346f4a449f23be228e8f338df567d30211a11180b94fbc5204bec", + "b9b57fdb8d14d1be87a25f89553b3966eb7869e0519ffdf4cc4d51f4cec90d68f7b81cdc0450e04207276e9c63ace721", + "a06eabcf43585a001448f3dc30411f3d5b74fd0a695c81eda9981842ba2bb0081d3f5a8360aa18b6d43ef13ea78b293d", + "926fe48a7e8f07559b7237beff9504476dd97b5b4d67acd01a3633358a6ba4c7abed5c87683a11209aa2ee759888e00e", + "a716cd3a84a963e2a5a46145b6ef4ebce705de52bf2945c374152a1e41c228a9c4eae0b6d1e222c1eea8b9c13c002177", + "8a9b5985df6fb32cdb06ba1591a977545444478f2fe985ed1b10de61c630f0a4693c2185d63f0dc0256b208072c43b17", + "a8eab26ae0ebcdf96a59fad1dc2d5e83b94abb2ea1774b607023f9d9e0fe065853b1e2242e794f989a80a47f550c0bd9", + "84adbf38164cd04f3d770a7f4b8eae7a5d25b4a803fb63c02b95b71b33e454319c44e07a760d22bf5f58e7e372d09a16", + "90f443a3ba1b9129a0bee400b5b29d42e50bb2aa56b0022bbfc3c6f8d69db40299871ec7c1b68421cc89e1af6b13a39a", + "81c5a94b379eb98c494a8d0067c748ba47e87a2ada0105202ed7651eb4e5111a0cd8569b06ae68d392c4fd74a37833d2", + "8f92324b14a1549ee0b186073a26691088e41556d33b54258fc6e0b000e9624156db4e97861a0ec22960e6c47ca8a1dd", + "8b021cd0fffe055068cc460aec3cc455952e2ac32be5fa060e0d1b6cf30ed15381618f801249e893b1b9f10dd82077b0", + "b3e9f0dcb3d6f0b138f589fa54dfb01f849890ab97016372d004aac55103f363a64bc0e606ddf75430f1534a30fc522d", + "8fdfe64af891db89b25daa859864d479cb7599486bd6f36e593f8f2f839f942261ffc3eed5001a93fde44cbcdc24c583", + "a9e4554373c5073e135874e2bacbee69c65308eb0785532fec6a37834e8d0b437b77a2f11cc63c87d7183b82cd9b6bc9", + "b4c47daca723ad7193ac5098cad4dcab654186ec5ea5c0fd014a3ac39726be954565a901694ba211820c011fa1c59e18", + "8835427e86cdceb4c11cbea331ed724e4e78af15e3bab5be54f6b926bf66b5d99bcc40dbc456d86342c9fa83a033c2d5", + "8ea84590a400cedba047c2661378921a42f5ca0421da58c1bcb37bc686a2aed98afab3fa5e6ba3a51029390ef3cdf4d4", + "b48551170fc479d69fffb00fae4fba301e92e37cae08f596db6f6489c3b7020edc074f9e8d7465b84e9dcef1b6b3aecc", + "a6f318b1eaab00836a330710e88bfe400395b3081485f6a212e3cba9463f6fe7864ba4f71e57a411ecdf2bcb4d189f96", + "848d5137a39999141a79f4bdf91150796ba36352d8525821bf3bd6e070b352792d79147341b8254dd60fa8c36e9e2618", + "a8526f8904b1eac4ae2a25534aa91e8031e9aac7b8f58d8f49897e920c36c0232f4a30aa6eed305deb0f7793c115b267", + "b8b6a727c44c37a8388383e959d195d1d0e51a657d4ba360633d219d43c5df645383e2406c25f1d418e72b862c3a6e9b", + "92e64adf65b42c978f36dd03ab22ba983bfbb61944efccdb45b337ceb486beda99818bf20d32a545503c4572bb0a4983", + "9653bb83df66260a0bd059cd4244ef7c661b089e403d26ba777d2090783ff31f963f5d3a9c125b1ad1a1d19134f3fc8d", + "a74e72355e71ae5eb36dc75191643500ca3e67f18833ee981010e7e7e60a68e1b01b05901eff05014b9ef29aa4829f45", + "8b2139a5da14524cf6acc593144db23db424b95b8c7041d8f6c7a14a6725dda1cd09c42bb3ae26a5a3650affaa742800", + "a60ddff4300ca44a7c7a00a1f98441ad1438e07c30275bc46551cee1b681926d2c825cc8f90399ee5f36bb9fbd07d3dd", + "a04e5e9958867a5acc15fdea0d88951cfebd37c657102f6ba1dcdaa5e46cf1c823ad0d98718e88e436f260b770599102", + "95e977abeb70d46fe8d7584204770f14c856a77680607304ce58077550152733758e7a8b98b11b378540542b1175fecd", + "8c9ec93ed35a25ce00d61609e92d567459a45e39922ccd1c64ab512e292787125bd4164c00af4cf89fd3cf9deddcd8bb", + "819819ad0338250d9c89aceda9e217df12ac54e940c77fb8420575caa3fa78930689d0377ba88f16d38179a807135dc6", + "8baafb379d4150ac382b14a64788d819146480d7a1dccd3deef6889686ded375900f5df069843ef14d754ad3d7540401", + "ab827236996bb79b447714c6993af941c5ae66248df4d9a6f3650d44b853badb5c0cb67804210e07a7b9d66ca43092f6", + "927656c3eac8d2eb575e3daeb77f9605771170c325bee6aeade10c083d42bd8dcbf3bcc3d929ea437001c7cf9a95e2da", + "af22b212d5ee44fd4197966b9690487c38a119cd6536cfb8c181f38a94610dd9e057f95774047a446504dd96dd11e326", + "a44bd94b9e01e3ba36340f2ac2201ecb477495d4f1fb6726a6b439302deabb5a35d237c6a6aeb7e3b0a65649f8656716", + "af367aeeae3bba14fbdb05bcc1a521000dd9d37f5c34ae56fb306d3dfda201d0329a8b6e89d98e15825cb3c6bfdb1194", + "abcc4fbdea43e50ded9e2fb01464f4e87fb136e960141e8d39214f92794cfab5634f22cd40b18d8c0e501f2307aad23e", + "920786cbd674348b9853689915dfcab02cce2a4596d117962bce36aadddf4bdd143891e22f2c8015517039a64e8aede3", + "8cde63b9bd57cb3ef743f1f3e8250669eed739e5fbd68c500a3cc0c12f93862a69aebcdbc69dd8f476c2eb307f572a53", + "b967e65a5f1cd8d5d570f5e87e7e186fba51b9504f8e466392a76d8a971fb91fd9b7565bcc1647f50d7d15e48b93bc95", + "8d5a87b25fedf5edd57d870304bfd9081dc78c3e3e3b38b997260a92edac7feccdaf24feb51822d2edc223b70bb4ed5f", + "b6cd5d340a57f8ec73723c4f3ecd6601620dc8137a3e75a5d3c578bc79a9cae86b379950c644dee2ff99dad780d025c1", + "b6f0a8e754b7f52a85a2a2e6512cfd017f7fb0418d19bb318308951c4e242d3c65bbcb9748da9cbc91a738f9ca577332", + "a89dcf7d410bccec385400dd96b1cc6af89026a431d0f531aa992cbd7bc8bfd7c5f360bcb665bda1d72efa17bb982551", + "97788e7522427a46c4b6258d15623ef7a565712812fa80d001e1de8dc1791392702f3fa3cce5a8cd1c5755625a0ad10a", + "b5338fb5e137ff625b27c5148298f27ce8f493e2527c5d0facaa49f29cae34580d0d6c3c1074a2e46cd8db3f56004ea9", + "8962f006d7b1095dd0dd132ffe7e87e328510c95ad893cf3b2ab21c177c5cf2c27f47d8856f87e9762c547be009d25c0", + "87fee9ce9c26aa476e67e0791a809e0a06a8a98facf3faea730d438d3e516cdf75d645fa75c906e4e44ab9237a22c016", + "b75ab972e1a1214bab0b38cc3e973d44bb233acda5b4291f5e110b6fb78fdcab93dc63f01168debd898e165f615be1f7", + "b5a0fb52bca279d3853761a94b206acaf313df33ae6303d9b71edae90b66fc507adbc60fb11e758888736c81d5d80c0a", + "849b8f0005010e684701cd3a4e59e8c89e5fec59af6d2de5b6332cde03b865ea84f07f0b80ec3404380b0e148fbd2c24", + "96e2b0b6fe78408f9208f809f5c40398100b2dac202c8c5c33c2189560dea868270a598c419871a5a2b67783354f6014", + "b234b81f996142d0df2c719760bf996544820a03195a6dc0ff6a72543692f5a369bf63d1f0b477ef2fe7b3234e41f685", + "b85e39bcf40da1a12a535740176f4de749a93824079deb5fdaa004f3282fdefaf5275e3418c88c419bd42a3dd2ed2b3b", + "a27279304b89a18a4e2b443246f2368fb8b15f46a34533179b6bd2ef683f6e98e222b7a32880b39b8fac1afa90133803", + "8923c22cf15c9c1964213d725b337ece9ea854775a06f75f232c4859c7142a3942f418354e33066298aedfba3cb27e62", + "b109f714311fb9bc431ef57911e2cad6a3949455b9f23255cd7edea35be629e07f845fe53e2b12a32305ee2f4f264f27", + "b51e82ae5c7d48050e405897d0053e9ea4b2714d002e88f78c9a307cd50b9c6b3ee7cb86f86527be9d964b01895fab20", + "90db256931c7f98bcf3bffff4d496739185e7a20f329ee7bffd4e0850a37739948ec745285703967f4ca50ec370cf68b", + "a0485ac0445d88dafac56bfba2563b020cfc370f54c1606c89d12cfd8a4d1336d2ba50306e476155a6f5b0e0a1f2d092", + "a00754c3462e74bda928da855bbf90f9077db395e32f03cce9b2955546d900b72330d247b7d607b65e130f5b0d883de0", + "8547d56727c3ad8b5c8ce622ed9ad86fe8cd78e6e4848c9845914b5063b17330bd10b46d8d3f18f83ca09ecb28d1afb2", + "95b937b2a979bce0e159ac75c7d5d659be8599c92305e73e942aab414793364a3ec28c7c1c8491a5750ba84a29828d8d", + "b011e150f0294e45a0f4c69409999d0c2e602449dbd67ab95e8258466687cd733a0329083a31b03722f4e2580ddc95e9", + "924651a733ad5e5d9adadad3ea6a6babb8e455c8d5f2cb5bdc83fa422e7752592190ccedaa827b866861e73506a6968e", + "a4d5180122f8e31503ae027e54da50f72f5cfb910a6f7309bd882b5cd666f454672591f1f20e461e182a47d03b47052a", + "ab19ae659c4f73ea3d21895269dbec583c7029955a36469124ebe295027010faab56c4a475973497f28e9a77c03b8fd0", + "ae7ea1a803d0f439e91494f8f35fc1167dae23834c0c699ffe65d3da8b09f8df5a53195a99ca7b8558242279e69578fa", + "b9d63cf0e30f9800101b43b980bcd2f229758e74b21ad5354866b4e684791c08a184330dc316228a0d67fe0210f2bc4d", + "8c41629744391ddb96dcbbf9cd99b13d36e57d65962e0aeb92ebccf1c4cc769626feb3ec0363def08eceb102b3dd4ad6", + "b2848ff24faf9e667a8c19d050a93896e9e75b86595f7b762c7c74ccdfb9db126ae094961fee7f5d1192776c1ac1a524", + "af013bc29206743ce934d5887b8d0fb3667c89bda465d2321835a3618513fba6a459dd7566268220ffce7e0c97e22b2c", + "8bb799e36db1132da8e8b028ea8487dd3266b4628c56dfae4ea275f3c47c78e3d7445ab8d0aaee4cbf42148b3a148175", + "ae2b81fd47c038b5195a52ab8431f0d3cab4cf24c4237252d955aad2156adc16dda9d3270157e0bfe5a44022e5c051ef", + "8e0129213b1698d2ec6df132356805a8633ba79e672e586dfef664ffccca71834253ba14f296da962651fcba2c002622", + "a1ae30b500ae77cd9bbb803d737b4a5991cc780618ac22b5cc179efd8fe10afb8c135457f2e7b86ded485ea12eae70e5", + "8a39723077b7c0df6e3bf6548afa3910c214ee275951fbe5155a39473be98099626ea14d844630a6fa90292b9594665d", + "a628386c79b61aa7314b01d9814aeec20c2a66e3deda322a39957e7135c2e52b1da486d1b9cd61c87afb22c1d10f6462", + "97867f469b01249820aadd9a54e12d4fdadd4555f2d530450e1f8f6d2dae57360578e2c2c8ba41e3b5950df596537a98", + "97f192d0457c217affa5a24267dd16cb4c01de8fefde9df4884e1906d2f22e73382dcee6c7d910bf6430bb03f4a4f1e1", + "86d5b5739de8442dc74d0d8dc78e49210fe11bf8c6ff0f0faecbc47b64812d6b28c8afddf6d9c0212f1988451d6ccb1c", + "8ff3312ce9693cd4a9f4b8e75bd805f65b0790ee43fd9e075fe4cebc87185bdf161335049819f22530f54fed2779a5b9", + "8dc41d85548bee5d51941d55752a500bde3c5a8f3b362da4eec307a963968e26605048a111c9166d448b8dddf6f53892", + "996bdfd004b534151e309ac925fa5ee7801c9da4f6b4c43e156d1158b134535a2a3956e1255e0dd72ac2af6bddaebcaf", + "aead652704b788bf4983c8f725c644c327a6e9f6683215f5c826c09f82fd2e40631791f51d14e6aded91fdc018d45501", + "991ffab58a82b98ed8fc7b00c3faca153589fe09cebf6a137ad506387a1ca4dba475b0e4a1b9bdad829f1422facaec39", + "9652e6c4ae084221d6bad855ec0bc11b5f855c6efba67f644e0902ab790a98861cecc6ce047c68273c3aa7eeb2f4c7d9", + "b88b816507aaeea6dc92b861eabdc96988b74d7883f20a4b30ba249158acaff3c50d261742fc9ad2e9eba888a8d59065", + "acd028a51e16c07a10d2073b9d03070457ac5f1246365295a1359d015c460b92b4861125fabe6f114de8197045df408d", + "806d3cd9d02d41c49179fe7dac5b05dcfc9a205a283135d4f008d0771c58e6f963d7ad0f6798606edda718eb5c7ff3ed", + "b9b71f1657a6b206fc40159a941e127f252a7b324dea864ecd804f48c0ed86da9778a925fb65491204a92bc2a26fef32", + "80ed67bd0e74350c875abedc0e07fd42ce7cb926f0f3fb1949c6ac73f2300b5a14a5c6f6ff8aed99d5ea5029bb8e7ae6", + "9875f67a7a473714e4dd75ee0c763ddf88101532d9680724b3848fef69e218b04a96b90f88e0f4409aa40b9a21507ecc", + "b4a2bb1b421e5243e5e7576a0672dc19f9f70315a03f6411c19f76616ffbb70fc5dc0e57fd4ab85e24ea2261b7ce38ab", + "879723002ce43e6c75ba2246f51436efe3376242beff987d025c3c4476495af32d52a54fad5d9ec329a442b93bcff1ce", + "a4121efbefd9c3eb143619afa52a916f199c75024908047763b29466cdfc837c2fcc894aca63044c33c41c777e529b5b", + "895f637b497a9766714a3d9e3c275a1f0c9ddab105bf4c8b7e663f36cd79492022415bb4938c1a4849bda73106ace77c", + "b119acb8b161ce4384a924645a248a656a831af526cd337d97e08405415b9dd22060849c76b88a4785eb5e7214961759", + "802e712f4c0a17009c4be6c1e5ba2ca3b82adcb68793ec81f4489b7985babd8a3873d544de63d5e5de0cb4dc5048c030", + "ab111051e4651b910c68ecfdc33f2d99e7bf4182df68cedbdbbcac219a543e04d93ecb2763fe32b40c095c7ca193c331", + "855c73ef6afc6bcaab4c1e6388519fd5cbb682f91995bebd558167715db454f38012291beccea8186a3fb7045c685b67", + "a29d02ec6d9baf84c19dfd0eb378307703bfafc0744b73335550f3cd1b647275e70215f02d1f4ab82a5df4d4e12dd938", + "91510a45b8a50cac982d2db8faf8318352418c3f1c59bc6bc95eab0089d5d3a3a215533c415380e50b7928b9d388ff89", + "8286e7a2751ca4e23ea7a15851ad96d2cadf5b47f39f43165dde40d38ddb33f63a07bc00600c22e41d68a66fd8a0fa51", + "a413d4e619b63799dd0f42ac57e99628d338b676d52aec2bb0d1bb39155ad9344b50cdfe1fe643ff041f1bc9e2cec833", + "85524e5bb43ae58784d7e0966a664717289e541c8fcaff651541718d79a718f040a70aa8daf735f6635dabfc85c00663", + "97f0d48a4028ff4266faf1c6997b6ad27404daa50ca4420c00b90f0b3e2d82ef8134d0a04108a74955e61e8dfeac082c", + "8df6145c6cc39034c2f7331d488b8a411931c8faa25d99c5432831292637fd983d4f6b1a6f55522b4a42a462d63c6845", + "98c2060f67a916991b391e67fcf23e5f305112807fe95bdddb8ce6c4084126557e4c5f003afb32e30bc6808b30d4b526", + "8964246b3c2b8f7312f0a99647c38ef41daf70d2b99b112412356e680185da6810ab8ee0855ad7409d334173bcc4438f", + "b56c2c416a7069c14bdb3f2e208c5a6ad5aac1cbe5b1faf99dc89c7141d0259d1c6250be9d9195500c4a41182ad2ec3d", + "b7864583a4cae3b1083dcdcff7f123d24a69920a57d6594d0b7219e31bf0e236682442b6499a1f6795cfeb4f5f236695", + "a064f94139bf1b70d476bde97099631b1284aa6b4d87f16bfc65c075e58b2f1b3c2d057605259f806e545674a1169881", + "80d1bc4acf14c0f487cd57c5d6157b7f38917e93cb660f1c25e474fcdcac3c3dfda50f6bcccfd6676bae25c4b6b5014e", + "8ad9a4976c4e3e282843518149fcf5d454240740f4b91466f6310b7216d23d70b9b47c42870293252f29f092f330967a", + "914197593d2d99d784c704cad7ecd3f0b9f55dce03fc928d13e1a1034566c4de754f1c2a5ade047b0956415fe40399ec", + "8d77f5e29c572ec3c0ca39cbae2072ba4102403265b3d8c347a00386da9c0b8688d6e3280c96037c300d57b3545f3773", + "abfdf79d935fd4f06a04938d6580a8cbf9735f0d498f49677f26e73d3b34b7075d525afcb4f14ef1632cb375bef7dd55", + "a97a8c446e3edc86efac7bda5e2e5d0158c909552a3bf86151df20ece63b8d18b608f477286fb1c7f05605ab7e6a7c2c", + "8618d946c7fd62486551c35486fa466bdfcdc63c941e4cff5a01fbbe566b7ea9dc763cbe73e2acae063060b619a212a9", + "8d03ee468070936004b06acf64b868963f721f37faa09887f8a82c155ad5c5732572a6855b531db58af03b1afe034a18", + "8d3247f75966ea63935ef6049f7c889c1651374adb446f49499fc9191dbcde7ea33cbc1f1e2d3d1756b6e69870404643", + "afc853c3a3facb4ba0267512b8242327cd88007cef3bf549184ee891b5ddc8c27267bae7700758ad5bc32753ebf55dae", + "80df863eaea289de5a2101f2288046fdbfaa64f2cf1d6419a0e0eb8c93e3880d3a3fdf4940f7524ea1514eef77fb514e", + "8434b5888c2b51d12d57da6fb7392fff29393c2e3bfee8e3f9d395e23ddc016f10ebe3e3182d9584fddbd93a6effcefc", + "b78cbb4c9e80e3808c8f006dc3148a59a9cace55bcbb20dd27597557f931e5df7eb3efd18d880fe63466636701a8925e", + "acb140e44098414ae513b6ef38480e4f6180c6d5f9d1ca40ae7fbadb8b046829f79c97fe2cc663cbccd5ccf3994180c6", + "936cb8dc959e1fc574f6bb31f28b756499532ebb79b2c97ff58b720d1cd50dc24b1c17d3beb853ba76cb8334106ce807", + "adda2116d9fab2c214ec10c0b75f7f1d75e0dd01e9c3e295a0a126af0ea2c66373d977f0aefdda2e569c0a25f4921d0e", + "89a5cefb80c92dcad7653b1545f11701d6312aef392986835d048f39d5bc062cabc8a9501c5439c2b922efc5f04954d0", + "b9acb52747ce7f759b9cdc781f54938968c7eeacb27c1a080474e59394a55ae1d5734caf22d80289d3392aab76441e89", + "8564f72ce60f15a4225f1a223d757ebd19300e341fd9c1fe5a8ece8776c69c601938fa2d5c21b0935bd2bb593293272b", + "a5567d7b277c4ebf80e09c7e200c20d6cb27acbaa118c66ef71cbccb33ee3ddce0e0f57b77277ae1db9c66ed6e2d8f30", + "b82e9c2d8df1cdd3b2417bf316d53e9f3cb58473c4cb5383f521ef53e0af961ef916e4f6557a6d8b4655ec01415231cd", + "aa816dfd2814c8a25bd2cbaf66303ee49784df471bac4b3188074ea30816f00f425234454d40d8ad8035aa925d74da36", + "9919f384df20faaa2d226b521cab207dd2b62420d25ebbda28c9b2ca76a2a52203b2ad7844c1a25f5c75f005c5a83149", + "b24a6aa35c2d0f87e36598b36224c64427cd69642b6f9c1bd478a62c70f8ee69f85028648f6603b4f04fb21355f2afb1", + "892e044bdb1276b455eac2204be105e1821f987c2570494b1f32aa09506caba7ed343cd09b1bc126fed5e0fda3d0eaad", + "af0e01a3ad954dc048de18bc46bb1c4971db2467e839698e4dd05cd1adcb9261013fe9fd0cafb946c0b586f6aad86d4e", + "ac152f0a9ace425378daf02510eb7923ff1ed2c0f8d1deb918e4efb63655de1ba58c96438e9aa23abdf2431dc771370d", + "ad8c7419c097709347e2394195924e09617b47ac5c7a84aeb9deab8975f22155de0f70cf20d8a976551b14e3a2683a2b", + "808f14f67ae801536fb70a5898ab86e50ad35340cffd0648daed2f2c4564c9ad538034b2a179a6a8bfa27e9d93b4cbe0", + "80a74ab7ce4769db93cfa695a166db95f0a9c47885ff826ad5d93310f36d6b18b5351c67c858b9837b925e85a1995b63", + "95b88c3cdd64401c345828f4e4754b1a88b4875a14c08a668b90acd499b3b858842669ecd73a46c5d9f1de32ec1a0120", + "8ddbd770b7b18a5917eb43926fa05004e819f1d1ead05b915269e4a86b53e0633a90559007e59f6705a3769e2126ac56", + "ab6db5fc220754f19948bef98844e6e38dd623565d1695e1198040c228ac4fd863c1f168cac1d036bbfb718d9d8dd036", + "97bef628e977c069e60c395a17740e0e1bc1828f5607ae7f30ce5a0c95f02b53af2ad062700a75212e462aa22c3c5465", + "b68d465e04fd17ca98501e61eccb0ce30401855e98046e0c1debba71c2153d6a7a704aa36a6f12454696e78e87181cdc", + "a79cfdd048f4181e005bd0fbac0a8424495474956b58ce858d2b700fb0f931c406282bd33bfa25c8991bc528d12a69c1", + "843f55fa0a6a0969daf2b48080738f30b269b2e7ec123a799e5b203c0b3b4b956dc95d095bc6550b0013918cdff8a225", + "b683cdf2823036827e5b454bfe04af9bec1850d25a7a7a44aee7696b6ff0468b7ed6885a41dde2b8f3ecc4aec880c3d2", + "8b500796e82acdc89778e0c0f230f744fb05f762000fee877bcf57e8fb703d212dbc2374887bdc2e7b7a273d83a85798", + "ac35a8ee87bafecb1a87f15abc7ccf4109aab4ac91d357821e417f9b1474d196c38cc41cd13667f68d1ffab5e79a6e92", + "b6e517739390cfed5b395d33b14bce7cd7aaece57fe79a7eb3cbf150dc10765c3ea9fef7976a21a2243687e6eea38ef6", + "b53901eeee26692273365b789f2a60afc9b5f0df229c6d21b07016cf4c0e7985beec748aeca52262f68084393ab038e1", + "ac4804f33d8ba2b4854ca3537bd8bf2dda72d4e94ff7ecaaf9bd3b7f098343d74d765471ef80072ae34f860b052cbfb1", + "8c6a30a93f1dde18039bbdd1ef294552bf79856e20bce863e4b8dd72d906be3ff22468ff3610e06b5a7d1745dde7ead9", + "88f0607fa3b7cefe20a02115572b16fc3222be86bb19e592c86c48afbe7e0dd523492b0c29a3bceb9a20f5538bc3134c", + "a660b801bbddad725975ddf9a8f606f76ecef831f954be224d6178c368e1c72d346f00c4a4c95c289b62d36f2af323cf", + "a75b9a6aea9542b698938dcd6cc2f6fe0c43e29f64b2f54aeb05d35fac73d41aa7fd750af4fa9333644aab8db90775b9", + "83e1b7129d963d1cd076c3baa5fe422148e939273db173e4d59d1858a7d841eacac7fe817d15ab8f8a493bf46c2045e6", + "9060a2e9c24de11f9c70e039b5ffe9e6d32f1ae39f3dda263610df2265d917679e689898e4a8bd84ad34613dca5e3761", + "b42fc8b863a2af15e04d1fe6693c09b46007c0b8298973fb4762b45b4590ad7fe0aa758918b2fe5ed1ed0359754fd955", + "83e6de7860fb256ecf7b47506a5e557d0fb0aefe57fb513c7dee2bd9604712d08ca26adca7ba9a54b712372a7c585a26", + "90586e9cbbf71475ecd3e7b5753b286804dcce61e165502a82b960099e79272de8b7494b8877b54ae838eb5d0f71af2f", + "b2e4b0d21208f73b7b75e08df80cde20c4578e117d37092a490af82354e2afd3a7dbab46fa2d12fcb731cdaece69c2ba", + "a010961239bb8809fc7fb4aa08fa30d33a130f9f417ee9ea60f587dcc5ef4e1b7abcdcbf8e848ecdcb7972ef6af46e78", + "8f511fd58d1e3403a5eefdc0a4ba6b8af848c7efddbf9575ee84449facde05ae9a24aa41a5725416467f6fbd11369c52", + "b24ebbd2d4482eb618cea1ac4fbfd9ed8c46c0988a27259300a7ce5ce1bb256aeca0357828cbbc4cf0dfafbf586040e1", + "b3ea29e9cca55250e9b7b9bd854edae40f0f0cc65fe478cd468795d1288cc20d7b34ced33bd1356f1f54a4291faa877d", + "8a8b20f222d9e65bbde33638033972e7d44c6a310b92a9d9c5273b324c4ad1a94f2a10cbce8300c34dbd9beb618c877d", + "b2436a9a647dc3f12c550e4ddc5b010e6f9cb3f3504742d377384b625fc38f5b71710a49fb73ffaf95b9856047c98201", + "a13f8b77c70621e421be94c7412454adc1937b9e09845c2853ef72cdbe500e5c1bf08e3c8b8d6b8eff4bce5b8dec9213", + "b25de8780c80d779e6c2e3c4e839a5a107d55b9cccc3ad7c575f9fe37ef44b35db4c1b58f6114a5f2f9ca11e1eb9c5fa", + "96ba6ad4358c7a645e5edb07d23836cbd35c47d9a66937d09486570e68da3c8f72a578bd2e14188d3acc17e563a652d7", + "a7f55989814051fda73f83b5f1a3d5385cd31dc34baf94b37c208b3eaca008ff696fd7f41e2ecffc2dd586de905bf613", + "882d0c7c81e58eb9560349f35c35e4498dcde7af7be8d7974b79d262304c26ab67ffa5ed287bb193d5f0ab46b4096015", + "a607158f0c1fd0377a8ee5e9715ac230abf97406c19b233d22f5911ebe716967cc10425546dc44e40c38bd6c2b4bca2e", + "87e8cde50e5d852d3f073a43d652f7186bac7354612517cfaecd4a1b942f06fef6f14546279c0dc0262e2997b835b2a4", + "a1c93acc6db9d5ee426fb4a0b846bb7a7b8d5915bec777a9fe6907246b0beafb8938941c8c79ed6082155f75dbc1e332", + "b1e4f61457b86f76cd93eafd7536f72baf239ce5a62bd5a8085a34e90576b1e118e25002d2de49b01d6e9a245ee7d3a2", + "a0435fe9a4bd1031ec5973a103ec9396b2ce9fd982f6d9ed780fa80ac06a6e47a0a6eb2daf52df1dc9292db622ee9fa3", + "b66d8e8a1717e4bfa42083b6ef4490e090a73168b2912f2111743e089027be0a4945a229ecf5d0b5eec11b23f0e11303", + "8eb764f26904eea4f4169be6e75beaa6a39e4eb524625a15a78befe3d8e3cc82692d9b135590c20ed460d6e4ba630ef7", + "b7e4aea6bb09829e53fe83e53f49a7a331a6d7bf76e0073d758577e6d6fbe63dab642b23657355cad48896ad8715119c", + "8f94207982373a99ffa282673f192aa98d0c4461fb77c31dc4549628bd9687a249f1b3c66b1840929341e42516c5c64a", + "a9c673cb247b13e17fa5e616f0399b7f5c7ad043e143e44ae68855a840870ab3d2aad737ebcf74c2cc9688d17ef3a794", + "b02635104dd28c02068985256975c0af783899eb996e37d021d9a35238deeea9e836760db21869be7b6c82aa687ded29", + "b33bc0966389710812b5f6698afa3e9c84839a1b85492ba11e6ded26695260abf66be6fb355d12d3a8524966f0f89e0f", + "a79c0dd09506951c33da3cbc23843fd02d641fc24c640a205e6e8150240372847312b9381fb03c5d301fe4dbee8d0da2", + "b74de6f3a2c502b5b658ebe8a9b7edd78afd036f5a2736aa06502863b6865d131b9e3542e72a86fa2e1d2db4927661ed", + "99e365def1452ff9fb4b9eccd36ff4154d128469ba5bd73e83ae457ab53977cf6fc04a5d05bdcde357ab539e34bd9fe0", + "b4f2bfb95abb47c67870aa6ca38ac8f3ae1b1a2bed064b1be7ff90865ea12e4930fcf66429c7ecd1183fae4a01539386", + "ae4bde87f36b912e92398bf72e11d5389e93b2de1b277d7ed4b6fb5a9ab9f71a959ec3bcb734c11079440fe42b86fafd", + "b826459e568efdeeb66688482b67ef5020787275123fd3192f979b6175e3b0ed59e17cb734a0a052bf13f0afc7bd237c", + "a99dd735f4a7c85cb23dcc7f4835f9ab32026886909aaa95876b98029c37dc4d621726c872d3a9e50403443c958f4029", + "99083545034768010988bf8a9f34486c2cd9da27a1d10db3ab86eb69a1dd9c8ee723e7da4ef2aced63c1dbd53ccc52cb", + "8ac3209349f0142546c714ef7e9d1b094aab5469b8f080c0a37cb0362da5349e108760f272fbba770aa468e48d9a34c4", + "af5f48ed74b21e3f2c1430192adb4b804dc873cd7e8f07130c556c30e7b78df0ef5a14b205368848fa9185e5a68dee0d", + "b8b741b65d68df89443523ba74203226f1e0d13bab073d183662d124e83e76cd318b2bfff09879c04d81b577ac895638", + "914abe4282d11176d4f2f08c6f15e6c2d0cde1ab4de00bbe888015c205f51929d97296a0a8d3ca5641f085a29ea89505", + "83ec306b2a9a6780efafe799df90b1aebdbff7d47921a136ea8a5648b9708a97231245a1082fea38e47ecafbbe000528", + "95d6b58d70b388dfcee4eda0c9805362ccfb60a87603add565b175b2c14ed92999dfdb0d3724ee3e5d30535f282641e9", + "97eeb4de607c8306e1d4e494f0d5db126d53fd04983ab5674ec5996b971899e734fa4011f2c889da21154ea1e76dbd2f", + "84ff21977fbd873ea06bec444d4ec9ff0e3902edc29dfa25f3bed269b3709e3116e99dc06cc3e77f53c53b736bf8fc29", + "8ecf483874a040a4a1c293af145094fedf203a5eb37c3e165857e108cce3e1210e0bfc0f26f4ae5e2194024929ba034d", + "97d9b92b2ef34609d69402167f81bce225ed3a95718a3b403f702b93e96a121a8f7f072d0ff47e8b25164e204d1576bf", + "ab87c39cca1803b4e84b32e40ff30289e3cbbcfbe16a70f9e025643824752359be1f10c3e5398df402b6fec64d5a3537", + "af84ca57e6944332884b5c84750afe0d5950015e127acec161853d55d48fd864c7da8d59cc5aba4ceceac650b813fcc0", + "b1d23d98edbe7089ce0a8432e0eb3b427c350fb4bb39eb2aca3c2bef68c432078cb9b4b2c4966255e00e734fa616638b", + "8e2b5252e0ea96d40835ebfb5693af49946509975682d68651396d6bb1463f09e75fd0afa04ccea49893b5b9c3e77e40", + "8db25e762f1d4a89a9a1cbc61c01698e775906bc88a921b2905735457a35df9ab84bae12e1b1b8dafadd50212f1acda1", + "b5f7cd163a801770a4034e2b837e00191b0ac63a2b91032ae9a99ec182d748798df48a14644935fabdbac9a43a26749a", + "998e7232e5906843d6272d4e04f3f00ca41a57e6dcc393c68b5b5899e6d3f23001913a24383ed00955d5ec823dbd3844", + "ab2110a5174ae55ebb0a788f753597bd060ee8d6beafc5f7ce25046ea036dba939d67104bba91103d7838b50e36703d1", + "a211972a4f6a0303bec6c86f5c23c0d25ab4df0ba25876cbaad66ae010b5a00aa0c5daded85e4326261a17a563508a25", + "a49f53496a4041a01e07f2c2cf1e84e2ee726917bb103fd267451b9b7bb1331c0afde85a79a55409bfde27328b2a4745", + "934e915c67c7fc47adeabdde49f63f04644fe234672003be2aa0a2454dc8d9288f94293478936a450f2e3f249d395b5b", + "b6e69e9d6808ff7f60a01b7aea6781495d7a20f5b547852d3f0af727a7434209d3015a9dd04cbe3e272918e32e345508", + "b348d3462092b5c6fead7e515e09611438db8d69650876dd3b56226e303252bbeb9e9f3b888fb911445b0c87132a1d0e", + "8d6510334a905efe5a32001e167f1ba06f9bc4af7ffbf11b7f7bf3c0076b5cca373d8c47e98c1ba8755bb22632bfe0e7", + "a2d5200f20985dcd473d119ee97e1c0fafafa0f191185bfed9cac429cef8198d17665dac4f70342eea66e6e4a7370d58", + "8dd7eb6b1841b3f33425a158d33a172b79b2dc8a01378e4174e67a1a4c8f4b887f02c7c3a8f354ed9eac718155bcdf37", + "b16ca19388642f71afcd9f7007b490d82f83210ac1a989da9d4bf4c419de07af8c048cd301ec7e01b9d06abda7c169d5", + "93cb2d847d1a88de8c1c9d5b3c83efd0b7afb3682942bd2c8ab5ef35b33dc31a097a3e181daab8630d4e840b677216dc", + "a8b648c769e77a7b41c0c689fe2fba9bc585067e004bcb1732cb7b1618e97b317781c36c23a00680fc780b58c301a789", + "918c321100d57712866bdae84edf7e42df30a32853af257e0cb4da028842a43b49e775f3cecb85cd817269c728de7319", + "a7b0f6ce42e00c519e69b2c78fd9b75a2e7103e5892d3c1afd70c9b5b9e706180a4bf73dbb2d3eed52bfd521103ec5b3", + "90041994af3322b010891356afd8115340bd7fd7ba328716fbc4fe458236c8cad8c7564ae473d6091ec3a54bdab524c0", + "acb1ac83809573846231f9be2dc5f3e986cc36dd9574a620b1cced45bad0b11ea957ce8c6cbf964a0af916781c574f05", + "ac54677dc002698fc4d454c7beb862ad085d0514f92576f3485a44c0cb47afb9db2c085058918a3508f9b3de0137d97c", + "8dea56e1bfa150e442f8484b2952b116781d08cfa3072d08657cc09b0217276efc4ab6f5fd726bfd826f6976ced8da29", + "a2b09e25baf01d4364b5205fa0c4dea84ef8fe03709113b034f88a0f0a502a81bf92c1d4641e2ac9f3a6f4203d3645ee", + "b95fe37aa351b4292691a9c2e547224c37ec2751a31ecce59810cb2ae0993da6fbe5efe0ab82f164462fa3764b6eb20f", + "a3498947e91a3a540e86940be664fc82f1e83ff41a0d95eb84b925e820602a41b7393c8b458bd4ebbe574a754586787a", + "aa2516d3620c832e5728fefdb1af0be30c871cbad4b166a7a4565af676e73bddc2f2f51acc603b3a022056daad2b330e", + "a9251b56467fb55f64c70729e2ec77a59d7eac79cc0b4b25ee405ac02aea46bf1cbc858bc773934a6d9bea57cb528185", + "ae8c0a4ca7ba6bdca8764bac98df0581f00358db904e57867e6ffdf15542e55f7bad2dedac152ef88038b466ed901934", + "b0881e27e52cc6a57c4f3f278dffc7f63a9174b68bc867c16d8a151d9cc4d0aeb703d1074d1927faa9ffb43e10912c9a", + "b67138465d6654ded486d18e682f11a238d6a65d90f23d6b13eb6a1b7471efbac9ada6345dfb13e5432196d2a256829a", + "944c69a6f1126edd38f6eef60b8a5bd17147ab511e44e8e0a442e87244d8f35236ee0b8d3dac0631f8598f16486a5f74", + "995679dbe03dec775da26708cb9200dabcad983825f1ba601eb9395f9da350ca71e8af61dbff4c668fd0eebac7e4e356", + "89de362f02dc14de6995d43cdea3c854a0986c605ba5eb5dacf24e3a85983229bc99a2fcf50aba3df59f0fb20daffe29", + "84607f0e2d078df22d0866285614f5d78cf7697c94a7d1b5e02b770101ceecbfd53806b377b124a7320d9fed65000b97", + "93e3faab60050dac76ab44a29bcd521813e76ec8e4ae22712d77bb489bb49f98f9087acfd6a77016a09a42ddedab2d73", + "b7d64a7a35f21747b8e6a874be31ba770c0d13cbd41448411994e8cebb59591295a26bacbf74ee91e248a5b111aacca0", + "8dcad429a2b0d66b9eb8c1c3924d7a72979727db6a535526a3518bed2a9532d12aad1c5a778824ca4cb98e3e513f85f8", + "980882895faa347bd2fd1dda7b8ee7ed49e69843afe646f677b371eecc7a10e0f4e40bb55f28995a40080df471876816", + "89e8e7fb51df79971e2f7bf65783614abbb0d7f3f1b4a15d3f0d160deafa7ed1c446d9a5ae1a77160d4dd94ceed8af13", + "93fda8d350392e9c4d4ffe6534f7e7be53f32483d9319093e8436fbb8166a3c01085dc858373e65c7f4d014e0dc2bab7", + "897521a87b7ebf7152de5260c0875e3c7df1c53e734c672569219ee6f9bd196c5ecef159b6a1d3b7cd95e91b9b8803ff", + "b59affa408a0f7bd7930fa3b88750fd043ce672c10a3adeba95a12f23f0dda1793f761a86f7409ce1e6fd3b3b7195381", + "b4422ccc12f4fe99c530cda610053af9ffe635b633d52492fd81271d1f6f91b87171d572d5bd0e46ff63e221fb2fc4a5", + "a4542cdf3346ee0867c08d630c2aefc57442f1c05c0eba52d223bfdca5e9d0bb80775cff6ce2e28aa2730231fd7b1bb1", + "a7d297bb09118b914d286e5d1e87bdf13f7d174b988e38fb5427902e8e8c674072f36b19055a1070abcf357f8668f35b", + "9213b0ae24b7cb43ae95e25c09fead8bdbac55141694137d67eb5eab5e90a348a13d4d4d2cbc6436fc4f4f9f7334ced2", + "8aed71a0d116d832a372b42a0bb92a1980f3edf8189bdbaed7cde89fc0418b3ab21a04f5c6e1d3b8edf73f1f62bd6b15", + "a6c47d77d714c285c84c6b9458cbec5e3b191c0502dffd10ce049cf1ea27ddf868ef0cff13a2377289fa6c932b8e4f28", + "92f45622ec02483f2c1e07075a6695416d3768c8984856f284f40734346d56cb5b3322f20c2c9f0ef8e58ddc294a309a", + "af6450d02b79ac9fc79f35655b58fd3619cd5d38c5317564b453f5f2d79d7a030bf767e399fe01b658a72fbd2cac2356", + "a3c01fed5240eb8a61ffa8ff4a120dbcebb53b8e19845949c77fb4f9b2c3dd52c7001df6219ad2f76c785a4ee0f64a2a", + "af3136bfe8f774187bdf87555a1ac505322a956229a285d28bab1c88d4f4d12245af8dff35914a62e90e49f3dce6acb0", + "b20e21d28444fc96737958cd951858fda324b924b4d3d08932540fd4b87150f053db6985b96903906ce83dde0578cbb2", + "b7978101071268d1f485134b4dfd1e35f89b82c7d99ae91f58b6745f5e0273b7e06f3b23009033ecc3e41b2e9e85219b", + "9104b7d75245b784187175912cc0ad869e12f1983b98e052710fb33663224362bffd69ceed43e7d4ad7f998c0a699eb7", + "a7624cd71b92699ce3fde0e747976ee04ee820032ac45dd27d769edf3b3379a4b8db358e50c9d057c63b5a9b13d76bcd", + "9354a76f294005de8c59db10e638ae6e8c6d6b86a699d8da93143da8478d36116211c788d8285d8e01ea6647dfcaa1aa", + "b85935c04cae14af9848db5339ab6420122c041075ec1549314e3c9c5a610d9b794ea3617c50ca7af6b4aec8b06bc7dd", + "ad6835a62311c84b30ce90e86c91c0f31c4a44bf0a1db65bf331b7cf530cca0488efaac009ab9ed14c1d487da9e88feb", + "80339f0245cc37a42bd14cd58d2a8d50c554364d3a8485d0520ea6d2c83db3597bf51a858b10c838bfc8b6bc35619638", + "b370420ac1a011f6d8f930511b788708ccf2fe23ca7b775b65faa5f5a15c112a4667ed6496ae452baf2204e9ce0dbf09", + "8ceab3dadca807a1c8de58ac5788313419c37bc89603692c7a4d96e2311b7fe9e813cc691a7e25a242828cdf98f8bbcd", + "ac1526ebc6bd4ac92ee1b239f915e494d0279fbd065e4cab1f1b8a1663f67daa89560f6c99bbc3e63fa845520316d2e6", + "8240ab0bc36a29d43ec3059c7e6355ff39567e135f93b243145d3ada97fd1c970743819e0d58bd5171967daec144e7a1", + "a99743192a6f1967511b2d3038cc73edacb7e85f84b2926d8880d932d2fa12f5215592311a7548494b68a87ec70c93eb", + "8ffffc31c235997e59ab33c2f79f468399eb52b776fd7968f37a73e41949111957434f2c0a27645ab34c741eb627cd1f", + "8949d955309415d6d2cf6ee682ccd0427565142c1bfe43b17c38de05cd7185c48549a35b67665a0380f51aef10b62a8e", + "9614f727a9dac8ecd22b5b81b6e14d34f516db23a1a7d81771ddaa11f516ed04d4e78b78fda5dc9c276a55372f44c4d4", + "aa85d3ef157407bd8aa74032f66bc375fddaff90c612470b5ff5d93659f8c3523b2d1b6937b3cc4201c2aa339621180e", + "86f8fe8bf4c262dc6a04620a848e3844f5e39a2e1700c960f20ee66d4a559a90141ef4e5091d0f32acb1e915af1e0472", + "b3af2eb785b00588371beb3b49536b7919a3f2175d4817de5dcbf7fcc20c512852ef0f313327fd0589b10173f77b92e0", + "8388703c512eea59190351f3bd2cce83ff8bcb3c5aefc114cccf9e9b3f78200d8034c3ebe60448aaf6c912f0ff8f0cc4", + "95d0dbbbf08ec1ed3975fe7dd542be0a05156a2b3db5092825d918a849411ee536ed958201f74a5513e9743674d6658d", + "8d1a48802f1a2db247e633ddf61d3ef7a2c062c48dda59bf858916e04f56651a7d51e367d6535964ebf3ae6d2b21b421", + "971436871bfe868f25247145a55802945409b3150008535b372c949760d7949dd2fdb40d9b96ae7473bc8f6e9b83ecdb", + "8ca431728ac0f156763090828a7b6d860bf591e5b9dd3bb3b7f3ba0ca74191f9710ee55efd32db7d18eab5b479cee8a4", + "81e28f1a506e84c2b9aba1df720cb50e0b597b2c22f98acc34e710c934cc6f97dcaf33d589e845c2c1f6d8716d05ccac", + "8f43b11d3f00c41d16c9bc9bc0c44227c056bd77de4f1ca9a799418c5601e744f99066bef47da2d9088ae88eb259327c", + "8d330aa52744c08ef98cc5599eec8b9b4dd18aa01b803f1d1ca0e29b74f1aa2886ed0224390fc377af25852851fbee03", + "a06f5b203b67134c685039ec2bdbcc787353e2575ce73a415db24a517c0c31b59d1de89f12b97cbef0219fb6a1e90a20", + "9269a5f49bbb8fec1a387b5d105df88a027de615d5ca6afae20fe89b11746f8d23880db78dac238c955fc8bb3de18046", + "af5074b3bc0656421c314547b45b5abd3045ca1b17f5e34ba39d8c1f7928a55d4ca5ea9c2ab59a55909b25255233e04e", + "8e7ee5d733c8e08f3fb7d85f0628de3de6835121672c65374905dc6d19e02fa2df14c13d5e9835dacd609a4df09abd26", + "a9b9aaf83d31e879dfb8e73a0708801b4dbdb5d7c8654b27d2c0f5797ebcacc8d00a82143e2060f0917c9d41f1a03de6", + "904872aa1c093cb00e1c8e369a3bdae6931c5b1ed705dd3bffba243dc4f42df3e7d7cf70303d513b34d2245743d765cf", + "8a4d6b3b1d6afe67383c66693f70b397e510be28e3d97dbc8ec543d699b6cbb0e72eb90a7f65e83cf9f7ef50fb18b128", + "a914de13916e6a0dc0e0fefecb3a443cca80d83276513b70c22c6e566a2d41acbd33a0e2836ee09abeffd3a4894e437e", + "b9c408f5f05934b0aefab301ba22f8254c5ebbf5405b6aa788f76e4b328c150b395f441e3566015a0deb3eca89afe9ff", + "8d32aa2c81b2a8b89f347c2e0b6567b2117ddbb778fda8a3f19004b7f5aa9dd814b9b3ad35f9223715d2447b2d12f159", + "8230e8b9c84cada1bf14ea6aa9ecdadd978d893cf5962fee6c7167ed21239210ea491987f2c8f2e8cfea8c140704ca28", + "a5d7b6285fea51c6f21d0976a7c3a97baa3d733a201bfaac0994db6c65611d91c5fc0ebc2a7724ee02b371e575573649", + "a54f00a9530f6930069f5e3a8b8b1d52ee1def0aad1763e3c609ec07f25410969b43d5943a94c235ed5eb207b33a402e", + "a8dc6e96399b81397734c61c3a8154e55a670fa25fa5854b3c66734cbb4ec0d8f6ba650ee3c71da3773ffc9e37abf8bd", + "8841fbfae1af4d400d49f74495f864804f043416c09c64705251d021b3ab7881f134a00b0241e61010617d04979d747d", + "95acea7ff4861cc969c1d8cc8775c5eae014ad6e2e0e2d0a911dd916c34ae69f53eef779cc24ff1eac18c2b478d3ba2b", + "a5dce74abcfb8c68031b47364bd9baf71a91db01e45514ab6216f5eb582ef8fe9b06aaa02f17be8b93392d9b19ab9c06", + "89e111169e4ae2f4016c07c574a3bdacd8d2f359561fbbdaa3474de9bc24ef8936784dfe6fe0e29a13cac85a3e622b61", + "a4c511af6bdf3892939aab651828259e4ef6ebecfdd503ecc14e61001575b313a89e209cb55a77ec19a64d29ada066ef", + "923c62156fbf3a44926ffb5dc71f7cef602dbe941a98c61f019a27a18a50c16b6135b6099fe04a2e1dc88a6cad989fb7", + "afb9191c541b61afa0ef14652e563cc5a557842ce2afea13e21507dde0ebbe6da5233af949c998c00865c79bb3d45ec8", + "8a1f0ad65cb2b225931f41dc53547d756111ecbf5bc57c5ee2cc1ffd61b126d0389d311ffe26cf06eaead95af09c5ca3", + "9040b20b5ac2e1a9d30abf7a4eea1ec2db8f3077cb2cfc8736b37222d8d3937f5d9f421167086dc5551e9f0bd2522d07", + "b6d888b8c6bd448dccaf99c3f690d47f802e134709ce102fb6f6fc68156943c0762be6f386338163e01eed2d1dd5f734", + "b94f0e27bbcda793e4a272603b3dcc739d3bf3207798df7319f8dc9d37cbd850e3724bdd30498c929debad971950223c", + "9769827767be9d7bacba1b687289e0794c6fe630d33c9b607da1f6a65e3f34cb8bd65327d9287c8c5f3c8b5f6d3d133e", + "aaac72c993aa2356c9a6a030950441de42b2d746bace29865382f0ef54835bc96958b2f00237d805ee6a69ca82117c1b", + "a2b1f027d80c1b0e79bfc7dd252e095b436fba23a97a1b2b16cdd39fd39a49e06a1ca9a1345c4dbb3d601ffa99f42bdc", + "b3fa0ad1478ca571e8aa230921f95d81aed7eca00275a51b33aadabd5cb9c530030691d1242a6ff24e2d4cfd72a47203", + "a43ed4368e78daad51b9bf1a685b1e1bfe05bed7340d4a00df718133f686690c99198b60031513328fc353c6825a5f2f", + "965e145711ecf998b01a18843cbb8db6b91ff46f668229281d4ca52236c4d40804ebc54276e9c168d2a2bfc299bcf397", + "ae18e6efc6f54c1d9230210ac859c2f19180f31d2e37a94da2983a4264dbb58ad328ab3cbc6884ce4637c8c2390f7fc1", + "83a9200486d4d85f5671643b6daf3d0290b2e41520fb7ea7030e7e342d7789023da6a293a3984308b27eb55f879ad99d", + "b925fb6ca83479355a44abbcdf182bfac8a3c7cce6cfc7962be277ce34460eb837c561257569be3cb28023208dea80dd", + "9583dd991b62ae4bd5f379ccd3cec72cfae1c08137ddfbacc659a9641e7d5a82083de60005f74fc807bd2acd218d0789", + "ae73bc32e9ff5926e1e06c07a3963080881b976c9875777f8e4cf96af91bf41bdbed4bd77e91253b8ec3c15b4a6d3977", + "b2a3ea90aa398717ba7d8c46743e4c487b63c5abb140555d8d20e5115df2f70d3c84a2cb9a5e0536b2d93d24f271b38d", + "91d119d3bf1d34cd839eb69c6de998b78482ab66bc93fa97e31fb9592f36cdfcd673f52366f8c8e8877e313b92d4a2ad", + "a1907e20120902cf68912cc3046f8806cabbd7673e80218814cb088e080dd93b5dccba395b13e0025f5755c183276c3a", + "b2e2011df72504065ec4c12cbc2137b95cfcd1355509671feb7b00dbf7f8d500476a49754cb7fb9219cb5cba7c8afe01", + "a48589fb7a74a3dfd782cb3503e6294a81dbb6adb412887569f9408e9079371edbd9822388e0b7ec8d3297ba270f53ef", + "a203909bfe196ac65ed3e6800d577b6ca5c8fe1d40f7f925a43852951e38883f2ffd250a9e16fab3ed3dc1249650247b", + "997ac293722a8b98f7e819f8e6c2d4c5bd1103b82d489d8b8aabeb905e95450b9b75bd61442cf68cc957212ec1c55617", + "9895a3de62395c33509b153b7820bd94fd2b011f0cac135fcf916482f1eda272ecc79f83a61837e99c3a3c4ab2c5c2a2", + "98c2ece4d49a64ec8e06407a0585081003bcef88af35210e22eab91169f8f0c044d611494b755e5bd915804b1d857747", + "8bc6dd083b36d076ddf0e0bb1bb87cfd059283ddabb3886f02eb7e27f1f0539b2819527b56b5c13436523c4603ac1d12", + "85ab8b7a696333c82dd5e179e12b2e127e67d911de609ff9a03cab95cbeedb1f364aa1f2b5e59353e4ba0d177f996151", + "a9478e214afa68c395aa2c7daf8ba1627feb71ad6d8bc7339734cdcdd5a42838e032736c28e6251c808d5a4875ef0d06", + "8c53f62cf06a35321c8af3871ee4459768d0745ebf48942b9f464206309f42fc7b2c50f196ae1e43b664f0e2e718a23a", + "8ba80662f6642d8866e832ec8082a4204ebc993fc304c4b794666856de0407620131a18dc053597bb40a3de0bf8aca22", + "8c8fac6b911785d1561a985580c03fb2ebc613ae33e486a92638aa7d4493374118d9a6d9d99121e29c68c3d67ee4e3f3", + "90f2c793eee07ad90157040b30558bb3b0164e8ddf856389d6742cf5bd1c712e4c6a8e5678da70a8e9e242ec7864117e", + "954abed8f6d58896b7f6438c9780236c1c83b02d60a29fa7361559e619e5bc9d67b3646ee39ffafe2b3019bb3357fb50", + "b79874f757a33085e1e751544de8fe3afbea92e0234f9c00254c2b36115a16ee46f085f22aa66e0c9177e5106f51b03b", + "aa148b287cf4f60c64f774282b421aae075f0eaa93a45aab4927750f47e2ef0b811d1846bbb15eeb2f293c80a7612e83", + "a588d8825e7b0168d45499dcff6faf0dfe1ba4f090fdc7c06d50344960c0121f10ad109b0b9d13b06ef22de5a04eef87", + "8f61ec93d14ebfa9c31731f9ef0fb8907505fedc79378e9a3f65c27bed4d74b41e129c97672ce5f567d897befbceec8c", + "a008218633f1da10efd01c155f7ed739faec902da6dc48e9f19ccbc8d32bb318d71806285cf2003de2c907bbdd4f8b22", + "88ad82c66f7085632d7e348d69da84200c53594553acf5432b50dd1e87f410c802dfea91be3cf804e3117ce13103f23e", + "8498dba17de0318af227a3f9ed86df37a5c33f9a538be9823f8dce4efc3579e8296cb3b7200cee7c5e0bfd9da23a4b69", + "b3c0342231dffe4c9bc7d9265597bc8cc4a82e2980ac6d1407108db5b00349dc91d5116fab51cf2802d58f05f653861d", + "b3f2730455f9bf5a058598bc60f47740117ba51f6a767e1134516a4e42338b513f377027acf8825da5c4d047a62984fd", + "816360914fbc9d8b865157bfab07aeb7b90bb5a7c5cd64847b1c3184a52266cd3f8f8f3ef99309ba2edc4622304bacc0", + "8fd21b2315b44a52d60b39ebc45970a47b9495f42b88217ae057bebcd3ea0e2476c0c3d13de7f72016ae12ae966a008d", + "b62014485bc217a0fe892ef1aef0e59604ad5a868face7a93f77a70ba3d7413443fbe7a44552a784d8eae1acb1d1c52b", + "a905822507e431b35f56724f6c8d2e93b0607ed7a4533073a99cce2b7c1c35367382447073a53036dfdb0d04978ccf2a", + "81672e39c2b31845142963351de3d9cd04c67c806fdfe77467867463dbbd8a9b0e2400ccc55016e57cbedb02d83a0544", + "90919c970ec668de8ec48a2a73bb75cb94f0f8380c79a7909fd8084df61ecd631476ddd474b27103c6817c8f3f260db9", + "8fbe37dfb04bf1d3029f8070fd988fc5e4b585e61eab6a8b66caf0ffef979d3ed6a662cd99468ce98ec802e985da5fad", + "950939aabb90b57a3d667f9820880eb0c4fee5c27fe211ce8ecd34663c21b5543c810b3676111d079ac98644c75ee0ae", + "b06201ec3c3cfdaf864a66af128effee8ec42d25f1e173c1edf9207979fa52c871757000c591d71a9b6cde40f5001a06", + "a79054e8febd0450c96ac7a5fd6bf419c4b17a5926f3bc23a8616f0cfbc2849d97470174cd1baa7c739b12615334b6b7", + "81c7391b2a1844ed26a84f054b5f03865b442b7a8d614cd44805b5705fe6a356ac182b66a3c8d415132e389efac5f6b2", + "825af1563d0fe53925ec9ac0df65d8211b333474e59359bf1bde8861eecd03f2ac74534d34b7e61031227c2fa7a74e1e", + "b60dd9bf036f1825295cd2014ef1f6d520cf729b4d6cee0b42cb871b60ae539b27c83aa3f96ee3d490ec27ce7e915115", + "89ca43d5b7f3622b42df7887572297a7f52d5204d85e2e1ac6e5d7aa7f8aaea5e3a07280477d910db025d17cd2e7373b", + "b93a2bc9b1b597f0e514fde76ce5bfb6e61eee39cbf1971ea6db38c3ecb055e7913ec8cd07fb0b0ffae3ca345883101c", + "8d45546bc30266b20c6c59fc4339eb633155aa58f115a8f976d13789eaae20a95b064fedead247c46665cc13ba856663", + "aa8eacfe00e8a4d9815de3f7619d9c420629ada6489933ca66a571bf6c044d08b391e0d9eec7d1cbebe8def1e7523f1e", + "b32fefc59a0d0319ccb1946b351ed70445d78d9fbb536fa710d3162b9659f10288f12d82b32ecc026d55f16cbad55441", + "99c7c45c34044c056b24e8f57123ba5e2c2c039e9f038a66899362840cffe021733e078866a8708504cdc35816cb335d", + "80def162c134540d5ec071b25ccc3eef4efe158be453af41a310b7916c49ec0ce06bb43dfee96b6d77339e11587de448", + "b5f2fa4f68f6a26bcb70d8eab62ad73509c08ee7aa622a14b3d16973ffff508ce6f1aff9ced77b8dcfef7319245cf2de", + "b4d0436019e779c789464716e1741c189e8945dab7f3072720bd9aa89882fa5b085a1755c48da21541f3cd70a41b0a71", + "931e798ef672e1472f4f84c727a101e70d77b3a9f0c0803a5220958d6bbeb8aeeb56c769ab472a3d6451249a13a3f56e", + "918c10a84de268aa8f1ba24b38fe55ff907be07b1e86b4a4adbf305c0d705c1cf5f65ce99e03e11676cedc89f1a4f331", + "8e55a8413b823715ccd92daee357cedd797e69a0e78b6fcdacb7318646b9903dfe05e5501f47b3c52e74055b9eb619a4", + "8b329bb63e6c985d7d072dff4680b3f8b1217ed20543277386bd30ec25240d9dc378837dcd5cf4fd9548658635f4c537", + "8c2be5386052b22986b33dbc63c5afacb6d0095495564ba4aa28fc8c880a3c78242fb083248d788ed928deb1e30a82c2", + "83a2b7bdfcbd25d6b059f27218e009ecb5ecc4da68ead885e00216411d8222062ca42f21c4d9cfa19c31522080af677b", + "9620334d2633e85646b2e2fc48dc6c3f09c64ef1706ed78a3bb6ce1f6b274a727364df71e97531dfdcb392f70f27f536", + "b6c84970ec04545121ec3b79376f4e45053c97e8bf2b11922cc2490a429c38735466097ecb81cc9d9692c74d2fb8abc8", + "8e55d707dcf265c5ae29a32c27ce66f200fddb724faa5bbf145ef42280ef645fa2f0cc3cfe2db8599b26c83b91e077df", + "b910b96b763966402bbebd68a32c15a225ec21e1357fa298478c5981a4310e556103fef0c73bd8903e11c4ed2c065647", + "a8fd933a0e9fe8c459809bd93b8ce153e2af55df94b61a1490736b19c89469954da8b72dbd072d798fc06fc3d7a3d60a", + "811b279c113828e114fd82c2070caa7eb089a46c8cabf865f9c77354a77ebebe0c4c6400dda0e66dd017cfc44d76851d", + "8ed03e91c331afb3ad6e42767e1b3e8d3a35fb831805ff1b5fd3e91878e04027ff5af1165a3ac295f1578faf2c83b581", + "95bf53683d64a0621bf1ca6ee17446783f6c535b7a54d6ea57723487a215759a54f886597a55dfdd560424e368ab2759", + "a9bea378768fb1d7ba365a16531c51fc1975f1c73caf2a0891da28509805fa84e2a8db7c6ccfbc620e9002317abf174c", + "b8308250891015deaf851c4e5a4cf4704d104f94064418488d7e3076d49f36240dcf6fdcf83f45fe8a1d97fb02e3db59", + "adcda6b63da21f4074f142f8e7f3a2274f624c733e3a4001054a1809711529c61356aa087f73aed877a58ccb41d38d12", + "b80e7869239ae26d1da2e6683f064d1dc93cf4a2b66e9439b3ad9b25324e969bf98014760d29e6b8de7ff152ef498d0f", + "8e9bf968911df3bb5e3a7655e9d8143e91ee87f14464d7ba9c86e1e31b03ab31b91eda121281b79cd974d9ed2657e33e", + "9007277e8335a43e6bc3c2f5f98c0ba7024a679b7156aeefe964f1a962e5ac82154ac39d1ffbad85a8f2440f3c1e354b", + "9422b9d670e997b7c919a429499f38e863c69c6a4d2bb28d85e36ae0895c620f68b71e39eba785e3d39a45be91507757", + "926094e01132938000d82dd9a571fef5ef104cd25b4015a25e3442af0329e585aaad5472f0e7a69899ba2d6f734b40aa", + "95552d8057f7e32c24d69e4d6c51c98403f198a20c5be8826254d19cab2f84d5758e2220cea7e38b7c8a7a23178fd564", + "8abcf8dcc8488bcc9ab23c51b9e7a0d91dfc7bebe88b7ed370ee68eceba643e939c5eae66a4aa5fe85120751780e351c", + "a91bf8198f029e6a4cf6f0cc39b629e9aeff1c77b8739e1d5c73d8c1d3fb5c8f6f23e27b435bf10b5b4ec1cf6a7249ed", + "b932d87ee3a4b81341511f90fe5aa36c571e8b914f25abcc33dd40ca67a3f6444fe9362c1434744e4af18d6e045c54a3", + "a8e960c2be9b1d805d387b3ebe2134d421a65f1fd4c1b4cccdce78f9926f139eea78e3afb449b3d6dd19b5d16ace48fe", + "a7e2f57cce509fe66707eaba9b4c042c1be93fd6034a9b51d1d30c45c4363eac79d54663d525c9873ab0eec0b1cc4ed3", + "aa162a31c2078f4b080199debf24494a8dfdfb9d8fc85b198a861b12a629c73128c55a883e4c2de3dfed6e0e1b83eeab", + "b5a4d075433eaf4115717a84b4dc37f843d44bba0bf820c92ecdedd5afb61be60f7708c8a151a678d9d5c0ae531bffb7", + "b56ab96f7a463c0079e05dc766f3a6a31cae5c5044947734ebe0a26e01367c6763cc8de6c2ee2f3b8218f05bef217474", + "b60792ac506b901065a8bc0180a86e028fe34b62ceae1ad640c759538ebf3a2ad9c8c927d662deed6f489ff3ff7813c4", + "8c8c2cdf075504d12d441a58542e1f8e4bdf92b3ee4775e836b2734c5ec1e3df919b931386417d04489a1dca806c87d2", + "8ed78e91e5c4a68894cefc2f7fa71f02e5e12d40f1bb74332139bc7be4d92c24e07d5ece0e82150ed474aa1337af4c18", + "87119c22ff8aa31150bde537d863cad661cc5159b12f084cc319224c533f0deb28526ed8568d00a1441e7d8bb4f05673", + "83a60ba5a9cccf22cebadf7318b706c9f29abd25db0e2fc1c802965351b53cbf316df72ee3e9b2d3ae7f3c4494cfdff1", + "b73b6a9fdd3e7463fbdaabc9a885b7c82201ad867d1bced1c2484300a01cbbb3f1e21afa95d4c7cbb6cb983416b63b90", + "b1d89ad16981ff9217708090d4017662d8838f21f3a3296cffe14590b533905fa06a20e40dd497bd291fa4dfd1bfc511", + "8abde560083e071a402e3c7bf31930f537f67d2a7bbc734a7480b1b760aa712ebd1cbcb65b00e11e384e980222fe14a9", + "89c731d8f31afea8bdc9c32527bdca257f2a840764d40f6e49403b8e75ae51017d505ea4fff91bf28b6f3a1bc65b8bbc", + "80e9ac8e077e86ad050ee73dfce268a69564ff1b8419e9c236d981fe7a5f0c2bc756e8603ec604b3b9e36da8fe10a49c", + "b4f1eea0f304898b1323c6382732e6f40e556bfc68af9ce73f6d54e92f5f23cc4f78eb3f43d578d81e7627fb40f092b3", + "a0e3a8d1348f8f153e08ac4839232d75d1d6e81b5de184ec4724f8213baf98d3fe739a96f6b39d79a053b628c3a09981", + "a6915ba0b52ffe4a381bbb8ff3791d9d3b848bf89b3bacbb2a7d2e5ae21f1353cdc304b3cb6e82416f7e604035c27d7e", + "b2c4c9cdfdd2fc9a340ba3ade9423344b9f429e8c7e20a8abbf26400376e312f3ae35d1c456be99dfb5c02fc8a36cbfa", + "9657d57ca0641825a0aa5687f3f87659d893f33aee819bafa5b1ca1db554811c1c844f971e278606e3a2f096defdc67c", + "a4ad24d0a557704ada24d8e27a15604bca28679e260b2c69ccc8e6cae5499866724b700605a90df7dfb35130756939b9", + "b18d9ea6682f73a1f99a9a4fc98c38fcda02c1a18e8c5fc080cf935a2ac877dc5223fca273dcde190b906178d0fd05bc", + "8ea5fefad0799c885f50ff10d94bd0af5b99b0a446cd1f367ae5ff529cc47e09f3018115f3c0ccac2fa05bb65b84945e", + "92450d52e6c7d13ebfcdf5674d6761bbae2fc5aabc865d35d031b588c383e0a64cf69a73dc93948632e2b98f74a5ed86", + "a356f171a98df4ec5a96d556eaccc6ad34b4238aafcf0e94ece27cdbb491749fc9692e78b84dfe80bdef2914079d34b5", + "b918703a4d3507d266414712ba8eb7ad17da07cc5f952b5c62ef130cc6ed1ae3bf01237fc8848c179725bdddd465b301", + "ad2b0554570bfc9d97510cf59bc38e10ca54a93649c30ac9919bd0255e43bf525ab11b74f78a51ac0973cd0c5a5dcb54", + "a7ecaf4b631d179d32ac1632390d95196a0035e00da6c0e6e13b5c09ae44b15ae6c21538b5a31b73bc5f650ecd979b59", + "a37704eb4d728df2a367e59fcb6c26023136230e37f3b8a2f3ceeb1467f5cd30186fc0116f98b64a8146fd2c5903e8d9", + "b09373ce92314678299ae10ec1f93c702911beb4115c6b5ba6efbcab9c7afb599f59793912df70a98868bce6545a33dd", + "b52a878a1393094fd2b93f2d1eccabf2830ab10800ba4cc24dcc7849cd0978733263aef2fcb766a7cb575a7a99383db8", + "8dac097e006fda4fb9d6d7ae52adabd9448ebc8d5bd5b38ac0c4ed38ceb510763174f7adfb0b473c38e52147ccab4239", + "86b19c41efb949937d74a7875549ee5e997f9fdac7f7198085afda233cf74341a38d0ca3767c76cd35f875b89a35f78c", + "99f0d927e5ad25cd134f1c70b72631cc6b5cb4ddb86c0642b900464e33d971213a5239dddaf71f7a42f2d6d02a12dcc6", + "8355c38806c335d747d4e97f0083fb96585677da18b409a85175ec35dc3f74671817b34203eb18c2f729717ce083ede8", + "abb3603adb061a036eae0afa5f23d79c3b62442e0e3bcdeef896f88995585c1105cd3065410368456a4d36b5b0485a83", + "9051c5c0011784885187d04749f774b9b4f6bc594b0e4e18226de79dedc4d7aefa3529c3d2c728e180f96f3e204d578b", + "91888213e7d321d0bfac884edbd5cb756b280753bb5f8bc6acfc208f525757beca24bdf86fc68d3d8736ef176a960b49", + "91258bd7ce6e3b7516fe2f5391a368d826da299e0e99b1f82eaa44b62b110ab696adc92debab8ba098a52f38dfb3c5d8", + "96e3907340dffa9da3602d3b94bacff7e1bb8649edd3b9bbd06e1bc6781e78f91ababab12c0b9be7c66dfedc7001b66e", + "9513555688fcfb12ba63952ab36a67b36affdd71f7b843e8eb99ccbd45421698024608233efbdc905eaeb26b334b33af", + "9913ca9bcf11eeb408da02e4317c5ca0010fb2f4490b282ddb758001c08b438c3b35351a8cbe10b7fffc1293ccd22d4b", + "85dc2471860ebca88e5a2766161fdd77f926d2a34825d1134a30418f91a741759668e32fd1e37c415d07ab5824338e8a", + "8b128917e828a0b5eb6fa8ed72b52fae2dfaf74febee69a2e2f87e8df702f0c5bc0fb620c8d1d2a07f35a15ec9c0f5a8", + "964c39e7840c130b01bb481ae7bfc92682b0f124c9c383f9dbf3027f2249151925f4faf36905af476a54778d69da3f48", + "80671ece658cf850e522d46d25678f934ce6df043f25f8707235125765d40c2eaaf39eda6092f75039b22cb58bf2c29d", + "ad4bb0e79fdaa340b1347a46b0f64e801c72a89770dda0a6e4bfd35f2df5146fce9934e4baecb1c2671077c771eb8089", + "80b3bd3adc6cf198fcd997f8867d2839a2eb28f57390352ec423b8a14cc1f2ab21c6e286505d6a21fb134dcd8d8f11cf", + "a26d46a6b8a75748895a1d599e7fd120d896340e79813167a400b2fe463452532a4cab419074663fe1d29fa716b76a33", + "82b1f3a8a1df29207d7ff020809113ab06080a7f0c631f76ad33f47cdfb6a567143144df97b4ed7f676d929195b04bba", + "ad96633a3744648ff0a2e4491e8219c9c6ba6e655cb058c36320a8f72cd5f72c00bddf97083d07650ea9ddc005fc1ff4", + "91d0783788626c91662359dc3ff36a8bcc6831e3f4114f85c99910256b1d8f88a8612f53c7c417d55581dea486f38926", + "84edd9e87ff3d193ebb25f43474c33fe502a1e2100fd3f93fda6520f5e42214cc12e9f8045f99aa2423a0ee35e671854", + "b55e06a4b1fc3ff9a5520e0b7c8b5ac11b28385cce78d91ce93b82f1bd7f7afdd4195d0c13a76e80d0ed5a4f12325fa7", + "b0b15c7ddede2b81d9c835ecaa887650622e75d0d85f81b8bbec7ef24e9a31a9c9e3de1f382d8c76d878d1b01373f6c8", + "b1adb47c20f29784116b80f3670182d01b17612d5d91bd6502b0dcecdcf072541f582aafc5e7dd9a765cad52151684f4", + "8efd1018df9c9e9814a9c48f68c168551b999914a6719229f0c5bf0f20a288a2f5ba4a48ba966c5bffb0fbd346a4fcc6", + "b34ea2bd3269a4ddb2fbf2514401d2712fc46c22642f3557e3b9c7acbce9b454dcf789573ede9aa14f39605fdd03f8c4", + "a9e1428ce24eacfc460aec2e787c053327ba612f50d93510d58b2cb0f13291ca3d16358325ab3e86693fe686e4f526f7", + "91eac7361af4c66f725c153da665a3c55aca9ae73ead84ca2662cf736fe6a348a301be1954723206dda4a2120202954b", + "a6f02db89739c686407825fa7e84000ceedb9bd943e8a0908fef6f0d35dbc33c336072ba65e33e15ecfcd5714d01c2f0", + "a25666faa12e843a80365c0fef7d328a480c6e3cb7f224763c11d8cbabd0e7e91a5b647585ee905cc036afca14842bae", + "b4348576439cd2e48c01cb9cded7cc4a0ea364ab936dd679ddc7d58b48807e7fab070f2f1ea88595b11af4500849026a", + "a8c6c731e0d0464ef7e4fc1b049065eb4ce100c01e1a376365c636a0b23851022bf55805963bc15eb57434a837e81167", + "b0952937b154e3a4c206f96cd96c76ba37624956b0e4d43470bdd97b4af878326b589e3eaee82fc192437123096799a2", + "97d07ec31ecc9923192e48d37df2cf08750050fb452dcfbdb350fbc43e146bae3590c5b732b31ebfa1ce5d884ad5ad57", + "a69359aebbfe4cbc4d39d178150039fbf284cbc0edc68a6bd635ee3a1c76569a4a575c907fff691b2a4d82a384c2945f", + "b321c2c0f6b5902ee9056cce7404d858da9a573d27348c1a6bfea29b2746f2aee7abcb6192504e5a583b0caeaba117d7", + "a74e738aa6eb4eea58855ae6f422af22812fb388c83aacca5bd5fa4a88d4c01463174a229aea2830c348dd9ab9307854", + "94306a3b106bc1644346bc45c05cdc8287811d5c86cad691bde0c65d6a686eb9c0ce79ad91baa4547e5d058ae8bf7310", + "b64140fd77a07633e4ca8d60786452311dcdb8ce7095ba51dad8486f57c3bf4e69bced92603f71da992a48ad817ab275", + "affe7f4310f1dc68e5e3cd640bedf864f51bfb46bb752063bfc18e95930021f784e509261ff9c560f53000c361b142d1", + "b0d2fee222c6f963ba3385547f921a48964da031d737892604f8f2677d4905dbf615046db57eae6c6dd756709ae6932a", + "81700c66aad7c2e51168e028b0fe086dea75d3b17d93a4dc1f47a6a0f025df0bae1c8c997901837ad859a84197e7bb00", + "aa4ac5fdd602f8b79cace18690e67bad557a93d00c0e295074185e8c6b4059a65495d9971685de2fc01d2171ac8b706a", + "a8becb3a64fdf35d65d2857898dcf8053b5057a73ab8c5bb5324af1a8015cff47efb85dc3eae7364cd5c850b7962bedf", + "b72ea09bd0b72f8cde3466f359ea69b194ede93dced534efba1b9ebc6f3bd53942fe2965e992e82edb6050cac4ed88dd", + "85bb8dd7eef023a251fb6f220af54687747f4c91983ff728163c4618ffac40ee6edc29a0aa6d455276bbe017f63757c2", + "85a485254a11b4c4a943d9ec509c0dd1cbfc0ff5273a00cf5c9f0babec973efb15348e5d9451b548293d778e3a2b62a5", + "b109f3ac809391e772b589c196b013db69a9b2b10ac3898feb70b986973731f30722b573cd0c9324158ec20416825385", + "8a4eb579a840d438bed008644f373ea9ba2f28470d50cf1d70af38ba0e17326c948527b1719dd1bd9ac656ebd5aedd10", + "a52e9d66ead5ee1e02ce6108e4ded790d8ec83164a0fa275ab1f89a32200726c8e988d66df131df9e62dd80203c13dce", + "b541cee9febf15d252475507e11d65c4b7819c26cf6d90352f5e8a8f5c63e254eddf22df0c35a7be5b244233e8e4ee5e", + "8153c297772adf4603c39349142f98cc15baeccaeae10c3230ee87d62255f6814d88d6ed208c368d2c02332426589748", + "970dc9782f1828474e9fab7dcdec19aa106725465a5844caed948eef5c9e48199c1b6bc1a637ed7864116927e84bc65a", + "a975a920624967f4ecc77ea5d9869c434caa64c330024194615a8d0640c5d4d4fb139ea11a0c73a5c6ae6dd3fbf0ab5d", + "811f0f9e0c12acfb4b9dca359eaef3bed18083bad96188befc036ad3143b121fff4777ca6dc70a835bbc4921bd25f5ff", + "82341c6ebdb97c8b72910da95c7eebccd1308b6a92999886aab552f0642882d5c7cc60931577d200efd6066530c998dd", + "860f7162c2f5fd1c0953c6ce75bd8c52eaa48032b914410681b8cc05e00b64130d1f96ec5a52df66a04c78a9f9f42981", + "8a578e674875571fe1a0459843495a5ee1d9fb6cd684b244feb9488f999a46f43363938cd0542879ea18ed14fba10a6e", + "8df217aba4da6781f0f5139aced472025523ed6e17e504511c04b677ca8197488e237d8bb5dff7b6b3898cd5a6393dd5", + "b2c9230ad35d7b471d3aee6f771517cf3145ad26200bd6fe9c7cf28120e2945fed402e212d2330a692f97bb9ac4dcf12", + "b78b89e29e8b782603b222cc8724eeb83b2d9d56bc02f59a3c899ab76429dc721358b07dcdaf422f59520b7e7ab4fb55", + "82682a5617843c4ac8d4efb4c3ce715c76c1da2c3bab1ede387db503f3489c1bfdfc07d9231d96f955df84fd225bc81b", + "b0f53725cc610e78b8e8a4e6823a2ffe44dd15a9a5bc8151ab7a3787ddd97e1d7f2f0e6efd2876e5f96417157143e3bf", + "92c5a93233085e2b244519078770c7192af62f3562113abc8902f9d72591eacf52bd15ce78653ab9170d5067606287f8", + "a43ef97dcd9b6ad288846bf31fccf78df72f94bc7ad768baf5bf0d5dfa27bd74ffcc6b6c6ed1d1f09e09be3afa5eaedf", + "817d43bd684a261fb30f709f7926cc4e1a31fd3a1a5e7e53ba4d664856827b340d7867e23d55617ab3514c8a26a7040d", + "a599e22d3286b32fafaaf79bd5b0c5b72f6bf266ec68948478f055391336d756b58f9afea0167b961fd94234989f0f02", + "b70db7d8e8356df2e2070f8d658e560081442f3f3b95e20f4bf30106835d76161101163659d5d12cc0f335fb042dc66e", + "b8f725b70c957aa3cd6b4bef0d9647393f7c9e0b7343e92439372f0e9aa3ceddd0cb9c30be331742b87c53f2eb030593", + "b2fb5e7762f26036e7e966f4454f886758804d1f4c2da17f3d13b0b67ca337f1fd89fd3cc798b07da6e05e8582c9537b", + "a377f944dccc300921e238ed67989872338137fe57f04cb5a913c787842e08b8a1adcfb4d2200abdc911fc1c766a7092", + "b82e98a606071c2a33f2ad44e7ace6d9471d5434500de8307b5d4e0083e3a5cbc67f0609ca8055f0ea0ee7501b9ed916", + "8e58f9a04d33a41ace4944615041662dc35057e645f63e127cf0d70f96ac307d33a62ce98f164d6eed8536c1a747dcbe", + "b5b11388071ffbf57ac47fc195736613b964ebb91cc8e2c17b32646f91d64ea506282b881897fca96c317364d3290de2", + "a40ee9b7551133856cfb3904837f9949a9558e59a418898affb78adf1500fd6ef6328fc4422161909aea2c79ad08c14b", + "81f9eb4ef28aacdb43e11dfc9aa92ba990be4d3c14b484fa677edad3a3fbfeaa859a7f9322b5e95818240d7326215abf", + "84939b2b6bc859437d1a7a8d6ec9a357c6b716c4b4cc22abc274af872655940cfc72c99f5d0283d90e05191fcdb1c232", + "b78a5b74a90a805410b6225fb9576d6d73752520f25cc3fd1edf8ea9f6559d3080f9acaa2246809b6a66879cd2ae446b", + "8d0a92baa88bf38dce5385ccf15d345b28e2e5d0a2d469e689353d80eaed8e8408933816d70ad752f226c59a0d5b5f0c", + "a7e15f8a8c1655b7b346c9488cff278c793505379b781b31b273b4bf09b3bdfca1c8ab2334746075d636b2e05859f215", + "b70daf14f2adce03c7b92d6aa181f0c507a80a37493d8dd12419d5ed5f943a98099fefb46ac827d6e4efb9b8233c99d6", + "8c2480814661744d116fba7355bc6b1914975e44cf0e976d50b6a20092bb1c636b7b44ed3fe8d63b5555ffc89fa759d6", + "a6059528a4fed36abb74ab992b22a4f9bf1d05c5de2bfe6837b9af1adfed98bc37ed7481b5a99675d432743021fcfdb3", + "b7e19f1b25bc159e5a769811e773c3a8ffe8be8ac77ed0b711540915e5c6e7bafdb407cf9b85c551f67fd621ce8142a5", + "a2f66d4f7d16ed3e7ef5fc90b42676c61a98ff18bd26ccce91de03b6a0130c1db17a6bc57be135e410a76d2255b15813", + "a139c916927dc3d3fb83598da9217ca64f0ae127215332e9a7ed82be923b89a801c44580d5617297175f9dafb1c4eaf3", + "af08e1e1b04ec95366a12d99c80a9a9ac40ac984a575dd0230cdf4eb346a7686da55ef0a276f3356f814af31f9cbf1aa", + "98840aefe287369221c0721cd7c1b15b1d670c3cbbfda191cdb5434bcad757e59c30ec82b2d8c75947405888d44da435", + "b7c61c8d42daf2e278a12d8f6eed76090b71c82275f8b33504aba75d95103840e8acd083e97a5a5aa79897876a68940d", + "a0264048d2a2061d32eee4f661957ff351e78436bf49ef973c059612874ce9c91970869d011dc13a5b7c754476880a68", + "897199a4d8db8aa2db5d9be3d4f4312e41fa0739eb06c62e2e046c4b9be829a447e5d47227e2d96195d3b7b66eb59da6", + "b512a9082881f5dc90b02f8bc4f38b133348c2e933813852f6a8e7d8c270c9ce68a5524af7d1d3123e53b2d02a53d465", + "80b332469254a96f53c95ec79bb5a8bb1c387d40e58b73d72f84384c696ba0d3c81d6ac90be2979c364c44294e90432e", + "ab680c2e547ea5cbf95bf813020beb461d50ee4341dea944eb48f6a8584d35682d20186e3b190b849a1ba25625a7f499", + "9070581993a0531d6be372d370c2e4ab2ee53f30e04a75ae61ea0fc2c320914506c4d2d4b4487c1f8fa88356fc45c895", + "8424303dad6b4051ab633ad27ee51783b2ead61c5a6dae1eb3ed72fc1f36e2a9b1f315504a4bd90f9664091f2f403d4c", + "82225611eee626556553b9316dab4043aff241a81826a33aebd9864a91e299b765ba1fb43eea2c2047e6b75b6d7fe3de", + "8a3fb221c616ad55c352dd5e0c09ee892022013d6965aef40d4f277a42e9fa01226fe973cb99aaf6ffe4f4f348fb54d1", + "b07c07679aa51713e8a7d7bc304dc15ed5664b66bd371877023f3b110b3927e09e259ef22895c4001421a69c6c013cc6", + "83556c76bdac0dd8db6da231b863c335be076e7299802eebc259e0818c369f933a4a4b18e2df8ca07e82f60767b462e0", + "a516f659b7915d2f7cd0f0f5ea2491b15f0c84dcb191e7671b28adf7cf14a56d42cfc0da94b3c269b45c535f6eeded49", + "80d7cc6f26066f753041b17ff1bd27f6d4b5603a43729d33d596e21a67356db84ca9710158089def425f6afaf3207f9e", + "b802a47f9009dbd48851209ea1e2739020e717f0ae80671d9f97a0e43de923273f66b7fcc136a064c8467372a5b02d28", + "ac92fec1864a8a911633f377df87aab56713876316d48240fefeee49ab97f7406c22e70f4938b5912c5c4e766146b7a5", + "89224225b9835d04428b0a74edbff53dee2be285ddd1e5a3a8c37307c0500578155f0c4052e4bc8be04c56862fac099d", + "b1d3c8492fbf22ea60732745edd3b0163ba5a20d1a3315e3773f2540ee38cf308d42ec72cbb3e3dcea457d1d132c3904", + "8bd00e38ec30ee6c44a0e5b222f1f737c9ed2a4bb9225f1741d6334df966318c8a0fd2fbb109557fe8c9479694b8d8dc", + "a930ce5454efc0b247dc148aff869963fc5c240241d5590415cbd36634801a04d3873d93635911bb9c0c42ecb005cc63", + "b83d4f80e9e0fa47b42175df74935ba8aad2e559b80e84478ab1685bc3eb65d51b93e5738d5ca968cc055ca0c552a03c", + "b3ae21258f98051f13af3878b8103bc541fe6f20b1c3f8fb4689ddb8800b3c25cca9b55f0a4104bdf15dc4d5844abb8c", + "831ef8684c1cd446c58c59d0152aeade5cc305bca6aa296b92162615f052ba280fe289edd62fda6d9f0667c186445f52", + "97bf9659b14f133885916733b7d4ac7e215495953caba970fa259f7bf6b79e661090ec8d79e1c9ce8dfb17e8552f93af", + "84d5a89cc2332baaaf3d19627a65f4b107f8dd9228a1434b327732f59883bb54fb8ce60d6acd026ed4b0e94e545d1c33", + "8e66cb743f95ca5486400b0d89d02e20b98044be1e3a12983ff9fe086179e5a0ebf4dcd5098703191552e9aa660a6de5", + "87b4cfb35bacec805f8148786788db84eb8f4bcecdd0570ecb592c705450ce1a90b6d183d37ef58780ede3995be67497", + "a72a4fece5478011973afa543f6d8a8ea06a64b241cf7d8bd81fa3740ac2a4cf10e5120abcc1c1101f94da89507a40ca", + "89dc6001a96adcd2679916f43dd19ea00508c8d5dd6b0090eab7982fd2f3571b62f3029588a0649e73f49124525407ea", + "8ca75edf1259599e873530eff6151c822a4018e71a340534219ef8641cb6683215891df41d4e3c0ca2560e57a7aa913e", + "9282d32f868e5ee6f7fc229dda5b94b603476de30cec0a44a30edf396b52dc0ebd472b8f726d4b67d76179fecc1666a1", + "afa24704223707db89690bcf9761f07a093f6009ca9fc945e0a8801fc29f9f51292bf95243e466fe736088af36c55ca6", + "b51332508ddd9a2610edd2b0ad120272ca342e96c28baae37a2c4f07e689303a46c237712d07e446b1d67c75aa8ce32f", + "9219249f3799dfa4eb4770ee323f821e559e7406bb11b1f1889286221b22c8b40ccacbd9ac50ea3fa9ed754860bc24f0", + "993515270c128ede64fe6f06755259105d0ec74947b7eb05924a375fa5c6d14822f3d7d41dd04fa5df8aa2aa205a1dec", + "a83be4c2511bae430034ab15b194ac719d7b7041f9c0e321317f513a97db39e97b9ee1df92a1962f265b7a3e98cdd753", + "8ac7feaecd26f7b99fda3ed0b8a08bd6dd33ed5ba687c913ec0ffc64bbbefcda6f265072add4d944f2005634601ce68b", + "b4e3ac6b09299db9e1a469f3a0b2d8d724ee47a417a517bebc4c2ac3efc5cde086b57b9aa4efccdef2bcf8f456d973f6", + "9262a24a84fb7b2a84d700f98dcf3fefab8b47293778c20bfc356860cb84e0bf102bae9facd9986d92d1762e0a955836", + "97be2041c42bd25e5eb519279163b0857f8bef627492c27b1182f8bf0033769246be5886422cbd2409c08a2615352465", + "b0b87d059a00e3effa2e5e4925da913b245785f2932ac3ed364ad19a064d3561b8aa6afea22c951316074f0df179af36", + "891644b7b3321b06a2a40cd96c2b8b29d81cde5b48546483fdda439000982a9cbf1f6333fb6c089d39da6492cdfaefe9", + "8da9149b7f4783a24240b7b9c7e6df4abf8d699d3834e31ee591489bf4744141ab199c173db64397c1f9bd5f9c862ca1", + "8ad7f9fb2742654aa2964fd468e7645436cefd1308b064fd63fdf0d3adb4caf6cfe5426354f6cc284f208b03d6b2d918", + "8435e4668f7aeb027100d21e4e0b6ee22b401d21966a3736b95610de86c7e2f2c9ee5d0f901353675eee5ff458dad69e", + "9010895f045538bd11b47bb8996f27198c8d6cffd3220569e6b7407f68f35c47d1efdbcecbf9b5e241c3c2879a4f6936", + "92a9aa443b5ee7bf13b6f43f2d8d8db7f6f33fd4073a606ec5772421a55f464831419726130dd97829a7d4bfeb1ab078", + "843f3266560be6dcbe0258c3c7d7e332330e10630c069892954290288eda301e247f479505a8a1bf7e59c99ccafd104f", + "915bd1dad808f8a568725bd243f80b5476a2999d0ef60ea3ef6e754155bc4121b2b879d01570725b510c5a3f09cd83ef", + "97250d781815b1825be192714884630e9f564b9bd737d55b8ac79ab48d0fb3ca53bd21ead7b2fa82a05f24083f25645d", + "81e2d52333391ff2faab39611689a62d6ead77039e8703f4e012d53eea17a4d46f2e3342e44b6edbe73a542b461bda45", + "89c9f9fd5f638156b018831c1bb70c91215f4a2f5a73c84b1208bdf6ad652a55df7213336ce12bd910a0e1a726474f95", + "92bd02984d090ea7e2f3eb7d36d1e7b9d731b6b047e3cdd4af7cc4ee177415fea7a145205e484b366d84191f06af85c9", + "85a86fc61d5d916ccbb219db52953e1495230aaaca63237e9165276405f07ad9644e253ae394f1ccdd231944e7143313", + "a2ca5b3fbc9f3530f88c0ed7071ec3d89b272174c366eedb5d15d2b648c65d23c0faa4e92c776357e7c6883a0084d03c", + "ad171f5badcc99c8ffc9d8b707d792046f86cd0aa478e0e2fbb32fe095f96cd134ca548d1f7713057694dc6b26465315", + "96bd15d57da9980870fbadc98c68db76824407dff2700c45b859bb70d98374d4a4ba99e3ed0b0c17f480fe08f16c6b8a", + "8300bac69ca088c3ff35749b437215e9e35a16393e9dc094f520516ba57a485def7029d30adfc72bca36eeb285c19301", + "8a09e20be64f346668fcc7b07fee9c0ea8094c935cbf4f3a4cdbb613d4b936c1edb9256b7c884efb72393d97c0da00e1", + "b1f85827ee6f041f93ab174d847a55710824fa131c9ade9561168c3962a25c617475ebc4105eba6e738961a754442bc8", + "a131558f92e215969f41b6a57d1e2f424149eea531723821dd4cf8c54325cbe66b002de2c8287de6b41ab4b5c35f060a", + "81ba492b8956f73557f361a856c6c884ebb300d828287d5699e22e0cfa75c8e77a61616551d0be5178263898c461d6f7", + "b2608f44d3c22fac8e13cb59e4ade8b9a98c4eb1ec0959ea400c97eb937ae3f66837e91917057148befade8389af2f6a", + "a6ff0323b5a18a4becb2cc6b376086b47cb2baffbfd1b0f2229ef2286fb4a34c5cd83a5faed5def7bbad519fcab8a856", + "857d879cb9eff22501d883071382832730704bfcc5cd5b07cdce7ab8dc41c565a1eb0e7e4befce8e0e03a4975d3f11ef", + "a2879a20c0360c516811c490289be7dfbf7dbd41d2f172c9239f99e3d091957e0446854f9d0f753d90384a80feb6fa56", + "83518624f33f19f87096a47d7b8e5f2d019b927e935a9021823fac6564c4f2328dcb172e25bb052748191e75ac682bd0", + "817ec79132faa4e2950665712b2c503d7fb542aa57b7b36e324f77cda79f8b77bde12314e2df65c5b5296a6bca9bb0b4", + "b2abf8fb7c3690816fa133d5b4aa509cd5a6e3257cfeb7513d1408b12371c4d58c44d123ac07360be0d0dd378e5bcf99", + "a9fe1e4fb1574c1affac5560939face1af6657f5d6abce08d32fc9d98ef03186dbb2dbb9fd1decd6d8f4e4687afecce9", + "89b2f41e51f33c3ca3e44b692e8a6681eb42a7f90b81c9e0a0bc538341df9e2039ee61f26d2ebe9e68df5ed1bccf8cdf", + "8b35aa7b1d9e2135b35a1d801f6c9f47c08a80e48603f3850b425f64e7fb9860d1adda04f92a1ba22d00dd0a26e781ca", + "960574978cadedbd4cd9f764bee92f94e08b7af65403de36b21bffc9424bcee845b3b028af2e9e545dd77cf1e69a6a7d", + "840aa0f34b5b6c39471f54d9e85f1eb946468c4fc01963a9027cd7864df01f73c2e864f1f07aeed4b1b1af72808dfa07", + "834464a84a11200e3c60f816044c254a7d9baed64aed45a17325cef7fd62338e0a26da78d199d30ac3411714dc813223", + "b4ac6fe2f5059546f4ad9a361426ead33237b6b9030b129bf0122085c85fe4ccb33cf90f5a7f23c5b708a5ac64b487f6", + "a12aa9035464795f2a67f3eaba478d5ebc838ed9e997c7dfa241e1ed60a94b367d3f969ccf0ef02028c35215698b309f", + "ac8d926492ec2bb68c6d8aa9bce49085d3d266f3d5f1f924032b87c42b44e41da7c047eeb01e4618f9d0f123dcaa537d", + "a5142425825d813ed8ce1849d81aa40b11f1cc3daa89a9f798dd83065c74820b4da6122b3308f528b074531df66e1a5e", + "87ff55c9f5aae079e7bf24084dd9c6b3bc260727d942d79cbe8dc13341d98525b4ece3ed8169994b56a387642f09134a", + "88e680f148ef2ecdcfed33b61f9e0224790fddc9069bd6999e9bede1791e761637c0fd60b52990b6c93e6e5429e483ce", + "94bc20bf5aac6e9f1060d02eacd06c42aeac9a1c5635b15a83985dfb03938ddb4999a822e865635201489c7f75601b29", + "849221cab7599f25f0b114df092bd5e8c2430503ae959bef1543a101de0790a78245db6a145e26f40b5f9bcf533219a3", + "88b6f2c2e7a7954fad11009d839ce50780921f80292320868d481e38d26aecd80fa607e82219a99532d88cf33b39f562", + "b0d82947dc23c0b88b86c321b582c15decdb825ed909a731b42d46bc895009515a3dc646c98dbec7d71b0722df82392e", + "a2cfb9f7c1a76c8073363c1c3bebe5dc29fa76533caea41046c51ea9bbdc693a121b957cd96be5b6da18704d1865cff7", + "8f0ffab9a83355a22683a9d998d1c1089449eb308711eaad4265f05927ec6d0d1ca39217082a0b372e02234e78dbaaad", + "ab024661e2b2937ad374c8cf2e3669f1dc55558a3a881e9ec4d461f27e0fa92e2bc88230f038bfb051cf2145ca747a07", + "b98d9b9ec9eefa56d38cca959ce1aee7b6d4b41a8dbbd34b3f50c0a5f97f84ed2502ded1ce8cdb5895872360d4ba6d61", + "851244158b3184a62d2c98d148e2b1102cf0d5500906bbc2deda95acc5e3bc4b4a3344febbb31ce05a56dfee86a74913", + "860d9e2cb886bd3620b5d7499d14b415532482569bd45fd76e3e8052d78a73ae4b2b41f139f9cfb136564108cd93c0f3", + "8305a052a0fb2bcd41f3aca075c5f7f233bd8f861451d03f3a6e6e31f7d08dd89fe1eb4dd7b238a78b12ddceaad9768c", + "adb703e4778c7e14fb83541ab00b5fc344108243ec6827c5d9b302ee68321aa569da1718424e6a57979ab7536d5eb43b", + "b1a754b87b9e21aeb86217ec5b4fadb7535344567f1bd15e88ec12a833fed68e26bfbe03b7709ce24ba6c925ea0a0e07", + "8c1e2f6bf820e1653f3b8213e9d959d8649196223c2aab57b7ebda094f4919f88d883bcc6a0cd0be335f26f5a2a9c962", + "a082deb9865fe8668e91db0e4fd7fb50fb3fdae3e7bf1217ce0aa6f286a624624cf936d762bb2b6c3fead6826694f846", + "a10540ca05fbcccdd0a2a66aabab3b36e9bb525794cbae68bc3dace6116f58942218e9d5e9af10d67b5f6fb6c774fdd4", + "b81d22c4ab0ccaf447cc5fc2ff3bd21746617e6773bf43257c0d80331be2e8437b88c9c45309ee46402b38d3d4911caf", + "84c7c6e924713cab3b149f641dabf63ad5abbc17c1d8ee7802a6630507aa1137f7e034ba1d12ec13f1e31efbab79bf13", + "8773b9d236e5fcfa8c32e471b555264692006bf9a869a3c327aed33da22dfbf5780ecea7158904d4d6ac4acfe9789388", + "a4c2c1bb7290eb7af2013f7dde78282148593f066b09faf42e61a3fcf81297caa5a00fdbf6b93609c8c5782a0f25341a", + "a7bfa6e3f273da3dcfac7cb9906bbe9fa4fc2872b184d79813ee273e6cc4d7f37f46164362707a1976f5b6a2c5d7ed1a", + "8b71502019e4263fcda354a0fd10aaa7da47f4abb7a0c715c7b017e9eea14f2b64009b29b467394668c7ca995adedf82", + "ad7460fba7deccc3f9a7d204233de47ce30ffa55e1e164975cdf06480a6108720bc397b93ca8c959df77d44a1e1f05f4", + "a5b8df96ccb7b078a3918e74b1b10da21df982538d2c9313f5129b2797c8a6db9ff8707241ff72d3e9d5983397321736", + "aa6cfa6386660c01879656da6c4e72497690708bae6c5cd1d088f443cb5bbbe75561d6eec256a72b9728377eb83ef973", + "b9699ce7c5c878e44114ab7a598646c6c7616b8e08a9ef8ec291189ef9945c1a538d2abf1ce3b0da0f8eecb303b81b43", + "b8d0fd1d278f53c455de92ec4357885fc6648dc5f276930263da7dc885b4a9628a2113e28b66b1e64fd08189427c614f", + "84ad8d262f6ef5d93e82ff6f4af995148eedf6d8e079124daee9b99f506e2968922eac2c7d4aea741fceb7733f20b2d2", + "ab5e30ab54641e3a44450118b8235554e0fcfffdfbe1430ceb3f7ef33325725741995fbbbb0c16f0875aef0f1e0c98ec", + "80e2cf8bf386ebda46045852751611f2af80eca2e910d9ec5f6e2c7376611534604ceafa639272b3d503b02bd66525a6", + "aaac69af8fbb87da1c1b7c1b9e59942887ae839a91f0c1d191c40fe8163d7f1dbe984e4fd33619c73e63abfa7058f1e3", + "a6194224ad838ab86e84dc80e9b8abb121ae6c3c7fddc476463d81f14168131e429a9757e18219b3896a667edda2c751", + "b68f36aa57aedc7d65752b74761e49127afa65466005a42556230dd608ecc8f5efdb2ce90bb445a8466e1fc780eea8c3", + "886c3fa235d6977822846b3d6eccb77f1e2cd8ba3dc04780666cf070cae208b7513dc4525d19a3fb6385cb55f5048e2a", + "a9801273ef850b99eb28f3dee84ba4c4017c95398730c447efe8c1146b0719f252709d3397ce60509e05da74ed0f373f", + "a58c2a5dd13e08ffa26a6c5e5eb18bd8f761ab64a711e928e6101512401ef2b1c41f67ba6d0823e16e89395d6b03ebb7", + "91318b564ec8b2d8c347ca827d4d3a060272aec585e1acd693b2bafa750565c72fec6a52c73bb3ae964fdaa479700532", + "a058db5d76f329c7e6873e80c7b6a088974522390ccaf171896066f0476742fd87a12fe9606c20d80920786a88d42cec", + "9838e07f9ed8b3fbca701be0ef32a3f90752bbe325aca4eaea5150d99eb2243332745c9e544fd1bb17e7e917202edab9", + "85a9ae7dd354f36e73baa5ecf8465d03f0c53b24caf510036b3e796e4764a2bc17f0373013af5b9f1b8973226eb58cd1", + "896a4ff4508d069a7da6ef7bed66e1080991daee8b227f3c959b4f47feaf75fd1b9e03d0917b247c2db11e105395d685", + "a36d9a6a037bf498dfc0e535f2034e6cd433c7b52e520469811eb2e9f04499a6ce40257d2905300df7d81f38d1bba075", + "97aac3c5492aca879b4c06db1834b30b8850a244d29296046a84c637d9580c8521ab4752ef814c96f255a139660d7639", + "8552bf592a84ab4b356d01643c90347377ebf1f2b38a8c2e55a3f34537b8c7dcbd62e6776d6c2114f2bc2d4344d1567c", + "84474ad163db8e590943ccd1dc50b4f444beb8275919b33f53d42cba89831e9d42ce2de52b26f4412e2a0676ce913277", + "900799dfaf5eafeb297c7b4f892438bf2a65ce04034d66f8e5cc3836e4eaffe782fba4f4455a0fcab49102a240d1780e", + "817176415e35ad4a204b9fd5771bae6cc270f6ff050996cec89efbe461b2940ae5dd3c6c7d7e31b1da5285b207efed27", + "965e5791c927d47569bc54ec9b4c5305788aecd87a26e402aabeaeccc03480df46f0586ca2e2a9918885cd03332af166", + "b96d9ada4b5a04a94807d71726bd557de94fbd44042d7dba40560eebe8658d1da49eba54499360619f3b2c38e8b5ed6a", + "a07b6d641a43e02e7868f30db4dd5069a2f221b4f122ce9b11eac04abadc4f25f3207f1d2d86c7935b1a3d9992ea9814", + "8250d4d8ccac846a4b1a9fa392d9279b5bf2283c8b95d8164c3c0d199fec8849eab85755f2a2a99d584a0407742e3200", + "8324cf49f56fc14162f9a9ebda1ebda0388d09d8688f1938aef7dbf9505fc119069efc552f68cc7cd9213f96fda2c6de", + "a98e6f1e85268dccbe3bf4e92c9f455c58dcb53de1dba3b78589adf2e50e79f8e245f956e0d098eb46f5d3746826c6dd", + "b103ec12f266b4153d67b54d8fc079357ee342cbe5008adc3e0689a7f788534c4601e60e939731f49e4a1e24fd589f82", + "b2d7681e866420413cc98eae67614d383943e3762d5742cb3c57e26157633c20880eea1209feaf68402d5d33dd699708", + "99fed0ae4112ec9ed74baac70d202a885aa51cb555a3886b49016744dd4017640dd5dd564998c4d842a9f38f3e004e68", + "95c35401314467219c8bfb1ccd1f1eae6ef4fa9e48fbea14f70d5315e67b16c46cd03554471840e4a5030b077d2a3856", + "8d029380e0c294400d6b8673a23aed43697cb6460fc1bcf217aca3b47cf240886644ed09521d6a05f6abf56f99722d84", + "8ef54d1dc0b84575d3a01ecba8a249739edfd25513714dd4d1941fbde99dbbc392f7eb9fb96690d7052609af23aa57f7", + "b8ad2b7af4812417aa8de8f33a26547f84bb84f39501d4b7c484cc8bb54c7e166c849b95240fbe459a4719a6e3bf1651", + "9858545de898721d19930d8b360cacc5ce262c8e004867a050f849f7a2f2aba968c28d51f24a9af56aaba23a9ded4349", + "94ea5043b70df1db63f9b66b4f9d8082776f721b559f27d37b45e0a84faf47f948d7c4532dfd854a4bac49fb2ec8e69e", + "a2fd88d7b15e3c2778f6c74470d0f9e1a1f979a4d58bd205361eacadab9973d585a6508e685e640b272d6f8a448eae05", + "88defd6bccd55db8ca84e3c8d0fc55a3456b41788f1e209d0aec19c9c70febebf3ae32cacaa1dbbf796d7ddea4b17995", + "88b8cde2449d5ee7de2ee2f32e845d27e171a51ef64f1d3d8a5fd7dbb9f898ea70eb7f6410cddfd7b7ae70ea8073cc2e", + "8e044fff6ec557824866ac76301b6d93ed19b7177aa6baa95046330f5d69b572b59200e3653cf2f2b559455e782e8960", + "b5446b4d6741c824885790d2d26258729dc0ba2f469c85a47d38886d933b785a4f38a951d37f3ef4bd5091c03fa3a071", + "956c8afa8056e9a71ab2e8be5241ddbb3a8b3cff2110cb0e7389493d9fa45e6c4b769ebef540a952db6dcd8bd55baf64", + "925950cae25615246e29d594ebf34fa7d52f78a9867338648158f2131e6eb4dc17e18f9db8a5fdd76d017b3a9798b3a7", + "a17ea4b43211ba990270c21562690b3ef154a46c3d669c4674c80bd424cdfa95d8850c8e882b8d06504f929cba3d93af", + "b315ec723973a138508afc387ef651fd8a8804f93975fc36c2eeb796a304eeb1508518d8703e666a74d14318253f526f", + "a995742d7433b3f230e622de23cb2d81cac76de54831491cc29768eb4a56da60a5cbd573e1da81fddc359b489a98f85c", + "adb2e89f0d15294d7118fc06d4fdbd9c51d3ecbcc23c69797e5b8197eea0d6cd1240910cf22fcab4ef1e2dc2dd99da91", + "b5ec9f9fcd0b5d176b643df989bb4c4c1c167112373d662fb414875662d1a93160dc0b5cdf540e8a30e5fcbe6cfbbd49", + "b1291b53f90aed275df8b540c74a1f9c6f582e16c5df9f5393a453a3e95624ab7552e93d6e2999784e164046e92ef219", + "8bc7b7b1a584a12d5ae63d0bbe4dc1b63c9df9c89bdd1095ff4b8e7c822bf8c1994c92310a3644033c7c9689f4b7d2b0", + "ad7fc45506a10ca48f991714ecc055cea376c0cbe667f3b40ee8dad8446218835439ae59bccc474cf47b053748ceba6d", + "b134756828a5f5725c0b95109e09ca450e3834b127163a0aeeb544e63cc0cdcdf66f8ed98c331c7c98758f46af369a84", + "94535bf1636be0974b112fcec480ed8eafc529933f3065c40e417e608e43a392206cfde8bb5a87b720263446c90de663", + "a4df4f6efbc3701000fb072e5cbed2754b9ef5618386c51ff12f95d281d1b700fea81fc1365f4afc66a7c83bd0228fbf", + "b0336b3552b721087c7e2194976a9119aee13ebed9f1c3c494353707fffde52d004a712965f460062ec9443620716302", + "99a39d1d1ee4283b75fa8c1fa42b6a3836b734be48bdd48050f9b05e48db6354fef509623c6ec8d447d630a9b3352b77", + "8e3dc3583d40956f9e784e8bbd0b5e65671d2ff2a7c387b20fcb7da9b969f2d122aaf7f054d450dc611737604548c03a", + "b5068ec5b7bcb5d8583d51cb25345990f50d1f7b82fe535a6a6b17756355885047916f466ea3ab09eef5516bbf2dda90", + "a8284ec1eb1d21e693f31a6c074199ee85d8a8da2167bffab5fe240defa2773971c8437e358a18f7e58d1e2954f57f6f", + "aa7415639d29081acbaac3e9c6b059d68e8702db3f430b86bb6e220d476fa74841c875e9d471c8a5423c58b6fee3cb54", + "8afcfe6f65fa6e07c2cb3e1756c0ef2c589830be96edd50c3c248e3b17f51a4b08ba92ef7eed7991d81667ddfbf2bf7f", + "83b9c8dec8ca8f9b85f0e36c08c5523cfeafb15a544398e6f93b48b5fc4b15a0bd05c0f176a9c2469664acab8dffb0a8", + "82a128a89ea46b9debe5c903b950c0ab30cd7570b979ca911500b5c2cca5c4ee6b2c2fa414b5f28e367f4671ffce60f4", + "b79fd0ccd2629a361cd6f9307c02ecd4d1f07e4ee03ce4b542997e055b07a026cbc0ba05fe3da309efc58db2e401a8fe", + "b190751141093823b4b5324cc26c4f3258552f7893241201f2fca1ae9b1a1d4d4964a9abdde8642cf308ded61ce5ef09", + "935fd48b95aa6f9eada0cf9a25a573f0ffe039888b3410788c41d173747bf384c0ec40371bb4383ddcc7d9f2db3d386b", + "b9affe100d878491ff345636ffd874ce1f27852a92417694afce4163e6a80c78b2f28d78102fd06c3283ef273ad37642", + "a877670276d49ec1d16c9f1671e43ade11c0c1a1413755f6b92be9ad56bc283e4bd2ad860367c675d5b32ff567301fc4", + "8c660d16464878590761bd1990fd0fc30766e7e49e97b82ec24346937856f43990e45aa8ad37283cb83fa16080d4a818", + "ae1412087da5a88f3ccc45b1483096aeb4dcf4f519ff3dbe613f63712f484bdd8b2c98a152a9db54cf1a239ae808f075", + "ad83cead97a9c3d26a141604268f8a627a100c3db7e5eefaf55a1787ddc1dd5ffc7544e4947784cb73b90d1729003c8f", + "97c3140ce435512a509e6ff3150da385fdf9e0883a5dc7cb83d616ec8d0a0014e4e0fa57a4d12c7997cd84e07d49a303", + "a353773ff68f1615454555bf658eabdcca40a9c7bced8537ea6fa8d54764fd1f032889e910d2a2a342835513352e2d2e", + "89e8df0c17a36ffe08149c2ef8b27306d04cdf437135aaeba697abc65e3c8e91bcf1817919a8a826acdbbe7dce79a18a", + "9928c2da15ac6cb20b15859c22508cfcd452c5643cd22eb84abf5f0a1a694fdefcd8fc329c9b40babc52630743d6b65a", + "99d837b556f8d13108eef6c26333a183f59383b39958dd807b10590c3d37f62ade6c4a320ca2e70567e0218b0ad5807d", + "9272da080e4aa18720b634640b01bf1fe506c7c8a89dee8759a53e2ca5cdbbd4a4f3aca54924c46b935362cf1eca066e", + "b4d39752c882de1c1daf3854202c1d58c2bcf35c882006eb640fe54a97be2655281cdb91c30d1a41c698617c2cf64b01", + "8bf827f4a7d47e07374d338a3d8b5c2cc3183015b5a474b64b6086fcf0cdcf4852046c9e34d7917d69caa65a9f80346c", + "901bffc7db9c9416e06f593a76d14f6d9e5dea1c5f9557bd8c93b9e70aa4782bab3518775c2a5b285739323579f7cf0a", + "af7e204388568627ca23e517bcf95112ca8afd4c6056b7f2c77c4da4b838c48791191565fd38398587761c8047d11c47", + "ab2576b5366e6bd88b347703f9549da7947520d4e9de95d7e49966d98249406ed9270fe69347c7752dad47e42c4ea2f4", + "b12e3b228b761dedd99d02928105494ded6d4fea3026d73d65ebffa2e85e2cd75b6d091135d418dd95ac102c22b5ee31", + "a20b4a752685d5e31ee7e2353c8a1b9a5265f12bb775004d282a3ecd9deda44831bac1ac5151646428b66909b2a423f5", + "91a1d4bc0062a86cc6786a96fd3eb4436d8a4a187b7cbba02190d1cd6ed3c3797d9ae7d6ddc413f1c94a21f62bd04ef5", + "977f18da1a5df5cfdd0276f583cfba2b2a0fc6139520664e20068f8dfdde33e29d179abfd722f142448f4677aa47be6c", + "abc3ece90f0f7b1d80fd917de27ab0d88cca584ef959da520825e54cb5a71336b15f8b348532d08d47a6fa600527ef25", + "888d36a2c7cc13a1c1aa338a183a74a1f57713e76cb825f9837f43279ce4741999b76a16928147537bcc20f2e0195b0f", + "af3f5dfdc2dcfe19de893f385f39f550cb1dab67c2e97f1d5fa735e5ec96d6680066803e8a0eb010dd4399f654195513", + "a0fb4e08ff56530a940a86c28830956eb6dec2f020f7faaea7566faf0a4fafe0cffe01480e87763ec22f201be51a6451", + "92343c5b107910b203c64a79c93d354f7ee5b7d1e62e56732386776e275285561cb887019cc00d3fdbe3b5d54460bec1", + "acfe7df83c4624188a1011ad88c1e1490d31a8a8c8016b40aebcdd7590d9c0793e80d2d7ce6a7048876621c252a06a5e", + "a7da001dc1e33e0e129c192d469d2bd6e5d2982eb38f3ba78bae0670690c8e70f40e8114a57bd0718c870ca5dd25b648", + "a903de5ff97dc83628290d781e206ef9d7c6b6d00cadc5bacffb31dc8935623ab96ade616413cb196a50f533e63641d6", + "8f9658d42ad14a60bbf7263f6bd516cfee6b37b91a8f53715d69f718a090ad92484061c2cef999816760a78552fae45b", + "8c15b72b3d5fcb9ffd377fd67d9dfbdd706593fba9629002639973db12aac987bd1db70250ded31c88e19efff612cdb8", + "88a2a4034decd854fb557960194ff3404e239953818a8a891bf72a0b26a8e570a65c4a630884de991ae7452b3234f31a", + "a09cae5c4c190537bf1dd75bd7bce56f7b799762af865bb9d1ee970f6a133c27cce0dd0f14a0e0516ceac41054e6998f", + "9760ebb1b40f9a97530c3b940d4ef772a225e5b63bf18283f8e302b9436c5209f6294980fd37058060e429fb7fdc3a56", + "adaa9400eb86d857dc591b25dbe3bc8f207b69e77b03cb5ee01f7e4b006b5c8f6ba2b51b5a45687479885708509363de", + "949efe6b00b3248846747a9ad4a934d6e4255994c2b540a59fbbde395fe96d69bb67908441cfadd8c8bbb561fe52da03", + "a19a45504b6b1dc3a0fe0e6a1384734a3dcd5a7cb8fb59eb70e49426c4fc44946547443d558e5719a04884ab3a2811ca", + "8934c9ee21e8d1435426fd0f64232a0670a7946ec524c054cd4f2cc8b1be9f89cc11002ca8aebae646a2050d91716b10", + "b1150ff8ffb34ffdcf7d603348c0aed61e5f90ee0a1b814079fc2a41325c75f2f9ee81542797ede3f947884266a772e0", + "86ce8cc7c1f92af68de2bca96ccb732f9b3374dad6657dfd523a95e8a931a0af2a80df74098514a06174406a40c16ba5", + "90faabb9ace9e13fd9584932846ab28a618f50958d2ce0d50310a50c3bc6b0da4338288e06e5fcbaa499f24a42c000d5", + "af4a935c2d8df73332a16dc6da490075cf93365bd0e53e2374ef397514c30c250bcac569b6df443985cf3720a4534889", + "b7f948ee90f394789eb0644d9f5ad0b700c8e44e5e9ed0e49da4cc18483676d25740710b1c15a557965da635f425b62e", + "a917913091245beed6a997ff7043ecf60c4d655c4db0b1ef1c704fd9b0e1ea1335ce8b9f45d6e120f81805ce31555e30", + "a48099da8406399bfb1ba834f6f7d864111d0036969a5cb64089947a63dd9467d3857b605e9f57f5ad5f4ec915088d9b", + "9784c3f9be42eed354542b1446d734521f8e3f01cd9d495ae98f2e4a3a16767fe2ad909e0def5d9a6267f3fc6a172cd2", + "8d9afaa323847a3226ad7d7b60d87322ffcda2e4a8df89f58a076f7972d896588de685a2e155e243bcf9456b0a0d6d1f", + "994413faf0b843f4ec1842c706c45ea5f24351c68674a27887bc8b182eda756856e507a4e8bbfd937e2c4c581b629ee6", + "b3e72d9d1ddaa00c7d22f25462d6e9f2faf55e30d138dce8bb1517eb0b67132db758668aac26164fd934d732633bdea5", + "8e95875e338f714e9e293df104f0ad66833bbd7a49d53a4f7f5fd5b18a66a61aa0a0f65cc31d55e0c075e0d3e412cb90", + "b980091862b1a9f9334b428eae14bbf1cecb4849e3a5809773b0d071d609727270f6ad97f329eca896c178ce65883db9", + "915d7ae5ae780bdba27ba51a9788a8852a15355b569581d1f18f0d94bcdfed2c1ed5a4f58e049e9825cda11f92b2c2d4", + "83e581058edf9259d0b06128282327cacbb6afc939578223cbf93544599f799a8dce1fb21d52464f990a877086f42506", + "803612a38b6f6efb97941997e101ac1878e192456f8fbddb3359aa7f3023434ed8fa92e60ec8e7b4473b1948850e4311", + "864a1bf4ac046161617dde282e44ab3cc1843da01a09ca58aa00ed00eaea9351a07a9ec16d910819e7dcc28b8d2c8ada", + "922eb142845975d5f6f7dcfee6cac8c299b3730400e6bf82cc0bdd9888de21de9d9f1530640f702c003e1ed63b140cc7", + "a7db03c5be647dce1385ebc02f4825a654447fa8c4c8d4b22e635dbdd2b3ccdf219384e49a80cfb1e9e6182b6e4227ed", + "a167289ff0f0967bbab6479e4a8a6f508b001bbe0d16cad36ab4c105ad44f3f180e39a6694e6cd53bc300fe64dac1e8c", + "b7766431f6379ce62cba22ab938cdbb1b0c7903dfb43980a417e0ee96c10b86b447241e9dd4722fa716283061b847fb3", + "90cda18c5d66f5945c07c8c7dc453dee1370217ccb851bbea32578599aa669b4dd245dd8a9711b27c5df918eadf9746c", + "ac690cd2af39932874385fbf73c22b5d0162f371c2d818ec8a83761e0a57d2db2fca1d757343e141e1a0348016d5fc44", + "abac820f170ae9daa820661f32a603ed81013c6130d1ca1659137d94835e1546c39a2be898b187108662cdcbb99d24fe", + "b2ea5a5950096772f2b210d9f562f1a4cfacc021c2e3801ac3a935f2120d537471307d27b13d538dcbf877a35ff79a2e", + "ad94af4d0699cd49ba8ca3f15945bd09f3f7d20c3aa282a3113cdf89f943d7793e59468386b067e3c1d53425dfe84db4", + "83788367ec97cc4bbc18241cbed465b19baa76fab51759355d5618067009298c79d0a62a22e2a1e6dc63c7b90f21a4a5", + "a3e142d879096d90b1e0a778e726351fa71996466c39ee58a964e6b5a29855123d4a8af47e159027e8e6be0ca93d9955", + "860831f8d3edaabd41be5d4d79c94921625252aaec806251fb508e364e39fde8808d38b10d557e487603a1b274c9bc3a", + "88da39f334bd656a73c414ec17dda532059183664bbbac44eb4686c2601629ef8ff9da992c337a842e3885b684dd0032", + "b50addbdf7164e8303f33de5ce854d6f023d39c1c1984b214d9e5fb6f6001cd5bdda816f048a438ff3d696872672f805", + "999e58c4c69a912b84561cb09610e415b43832beeb95897eca8c403ef4754f4277754d492eef3673afd4362f50060fc9", + "b88ea0f60f8119c5a1fd9294796d387472dfad22442b29659713d1d88e7d854cb7cf5c9ef773627781188626bb2fb573", + "a068b3844e9dbcf74b54fd55904d56af754d8ce4c619fead7a07f9bfb9d02118db7c512ccec2489d2a84374ec1d1fb6d", + "871dee023768636003c799e6f6fd8d31315a4c0da7286345cd64264a016693b3485e0732be1bbd34dd5fa04dfa58a983", + "8021e8f508680df12e4a5a1bd49f2d7142df65158b0a7198ffa83abd16053a542fb93ffc33e5279020ba8c6a26feacf2", + "b5d3cd64df5bc965228b0bd4ce9e5797c409f7b64a172ba165e44a8e4b38e3d5fabc3e0b9a19afbfe427f887c40a315d", + "a54fdebbb594bafcefb1a03697711e0091c072e1cc24fb441fefd4e0a0518675a1d7b0966cb8294051d7ec0ac175d0cd", + "93922202337f72969d6d6e14a29c9c75e0420dfba712029941d1504b9f6f9761d706cbc0652cd09a1aa5d22aec766af1", + "9711ebf1c7c7426190d4afd5dd03b014a456bbd9d90ed101623866a280550df26a629dde400c03ee3699f7d827dc0bb9", + "b4d686d8bc5c1e822a50124c1cc23c6bc3a1577a3d0b8d4b70d1797418aaa763283c09e8a0d31ae6d4e6115f39e713c4", + "a533ea2ac683e4ba07e320501a5d82a1cfc4fa1d65451000c3043f0fdac0a765cc1125d6cc14fe69975f3b346be0fdde", + "94ee563134fe233a4a48cf1380df55ead2a8ec3bf58313c208659003fb615a71477e5c994dc4dcfb2a8c6f2d0cb27594", + "93e97d3f3f70664d0925be7aee3a358e95ae7da394220928ae48da7251e287a6dfbd3e04003a31fab771c874328ae005", + "b57440d34615e2e7b1f676f2a8e379e1d961209fe00a0cf6798f42b7c28dbd03172fce689305e5b83e54424bc3f4a47c", + "97644084c6f7b4162bc098bed781dd3af6e49e7661db510975528f1dea8154f3d87e979bcae90c3df3a7752eb0752889", + "a923b27b225b2a6dd5bdc2e3d295b101cac5b629a86c483577e073cea1c7d942c457d7ff66b42fcf33e26c510b180bc2", + "86698d3b3873ed3f8ab3269556f03ac8d53c6e2c47e5174ec5d14b3ed5c939750245441c00e2e9bb4d6f604179f255ef", + "87946826d3aa6c7d53435c78005509b178fdb9befc191c107aee0b48fbe4c88a54cebf1aae08c32c3df103c678bad0ca", + "860864896c32b5d4cb075176f4755ea87fea6b9cb541c255a83d56c0a4092f92396a3e2b357c71833979b23508865457", + "b78fa75d687349e28b4ddfe9e2d32bb6a3be13220b8f3ff1ded712088bd0643da9b72778bcca9e3b103b80097f48bdd0", + "8a188b940446598d1f0e8c6d81d3cada34c4c1ae0118ec7e0eacc70d1bced28ae34b99667d5793d9d315a414601c3b22", + "842ac6f7dc14191ab6dddffcbc7cb9effba42700a77584aa6a8e17a855cd444c5d138f9d61bf55f43c6ffbcc83f92bc9", + "b6742902c3d145a6af9738c01cf9880dd05c85f0d0ef7dbe93c06fdd6493333d218339ebc2a02be1895436a2f734a866", + "98bf18488483c627b7181b049d3e6f849fce1f15794de59dcde6e5a9b0d76fd484a46e48822a6a93001d3aa12f48bc6d", + "8769cac10bda8c53a1c19419ef073a5998f73dcf2ba1b849561615a17cbc0a49bfe3eb4ff8801dd36a22fa34b9a3a7e2", + "b45c084d58028fdfae792210fcd183abc4ffddeb4cf52ebf3f8a50e4c4eec2a2758f1241b0920bebcb24b757c778577c", + "85c1216eec8e1fbc1af9b36b93c5d073a81d5fba86a6daae38748ec1573eacc6bef209e76c87a6efbd7a3f80e11d4c3c", + "b8007e34bb3f927ec06a050b51e633d7eb9e9a44715d5b39712e69c36177a03cd68391090cc3293098e54f6cf65f6caf", + "8e85527b27c9152b1ba3fdd532a76a79064ab097570508f233e09978761dfe3012d537411b47d0e4b65265eb32cea2ae", + "899779f3c31a20b76068ec8d59d97a64d2249588ddfd69dcbaac6bfaee8ce0ff3c5afc4e17c934ae7cd041b760eb555d", + "a5dac3d8f5fbef018509612e25d179f60d2a62451c76426bf546e9666fcdc73263d34aa6fa7e2bfd4c9947bbf5095eff", + "896900eeef9be2b2e755128e7b1c436af6fb3984f1e66c444bc15fcf3959013b4902c381f0eab1247f878a6ebd1f4ee0", + "8cb17f4b0af2e9b2cbb56f46e6a5d6874ea0daf147aae77303020b4e592ddc92e0dd058def7da96258b3a68b223bf22d", + "a1b6d3f09a9fa7ecc021ab7c5396541895da6e9bf1f9a156c08fc6f2b815a57f18c337ccfe540b62d79e0d261facb2be", + "ae70888811434ef93da60aeee44f113510069fd21161e5bb787295492eb8df85103794663fc9305f04adcbcf11ff0c5e", + "a84bbc8624100acfae080ba8cfb48fd4d0229a60b62d070bd08fade709efc6914dc232d3f7bed76a59204f9252321aad", + "aea47d54652abd8ca213cfc623c8e30780f37b095b59ac4795252a29c2b6bc703a5203acff8831314478b8ee8771d4d7", + "8dd438eb8be14935f759aa93021c2b24e1d588f7a162c42c90ec3a647b0ff857f60e24c0a8953eb7bb04e04be70f11ce", + "922b07b5469680a10e7532766e099896f4dc3d70c522d8add18f5f7765d4ddb840df109146607b51ceddd2189fa7b9c0", + "83ef6ebd0ae6c569d580093e8b0b78daa964760556272d202d343e824c38eccb424262e5b7809d3c586f9e2e9c5c5f22", + "97f98bd357db6e093e967fe180cf67ed09fa711580a5ad48f07cf095b2e8fabbe6319f97d1f15d62c0ec2227569d8dbf", + "a1953a4a22fe6c2beaf2a5e39666b0eb53018af6976e3a7aab5515550ff2efa89400605a43fb2c4ac1e51961dbd271d8", + "a5cbd67f4c0bc98e20aa74c09e6f5fb6f42c08e59aaa477b4b4e61434c8884bc14f17cf11faecf46dc4b6c055affbad2", + "87d96818f2c4f12fd7705cf4060a97bd28037c5ac0f0cc38f71189ec49361e438ce863e6617651977708094d5336d1da", + "85e7c2daae5fe59f8a1541c94df50402a671a17dbb8838113fa4b7aaff6114cf2bb5969410cf21e6a162857f2f7a83a8", + "a19575083e1731bb04bb4a49414e97aaadb36d883aa993d1f6847db50007315444814740e67e10177a14e0e074fd4c7d", + "a00ebfb5bcc3a6da835078189038a1e56b7dab6be74332b5ff7440e53b0f9e1eb9973effecbbf37000021fcf50c7c1ff", + "8969d7943abd3b1375fdfc7d6124dde82b0f7193068ed6ec83bcf908734daf3487a6a30f7b322e54a4818ae5f86d91c0", + "b959c8d210fa43af9b20d1fe0ea8c4921280eb4544ef6ea913309ff9d61c9327096707e84dc1662960519be8e7d080a4", + "9011d8ac651c42e0cb03931a9e960f58e02524c6b666047525e3b9097e9f35fb2b4b278efcce2bd5ad463c6d7fd56694", + "937e3b22ed0fcdbd9ea5a1b97b84bbe86b7f5b2de3866a930611112f2217f4ee7d9822c4ab1253823f77bceeae0c8e10", + "828997e5d121f4c305e018a0a0ba338bd6a34a7b4dc3c5ceab098ee57490311c130e2c045b9238a83908d07098d9fc32", + "8d114808eac0f2e1a942d80dad16756ec24f0276763cd6771acb6049472e05a9bb1d3bbd5957f092936b415d25c746b0", + "a063c5c26267ae12887387cbebbe51fd31bc604630b3a6e8e177e71d4f26263be89112cd12d139dd4c39f55f0e496be0", + "ab1e1582c8d67196d10f969eeb44e6e16214f1316aa4a2a821f65ba5834326da6cba04373eabfd3b3072e79e5c9717e6", + "a17b1dbaa11d41457e71a9d45d032448091df7a006c1a7836557923ab1a8d7290ec92a7a02b7e2a29fcea8f8e374c096", + "a1ed7198da3591771c7c6802a1d547cf4fcd055ca9010756d2a89a49a3581dfe9886e02ee08c4a2f00b2688d0600509a", + "af09aa60c0a185e19b3d99ffdc8c6196d8806169086c8ff577bf3801c8ab371e74165ba0f7329981e9252bfe965be617", + "98c04cc8bb26ffce187fa0051d068977c8f09303a08a575175072744e0a5fb61191b1769f663a426c30d405515329986", + "a542bf1c9c3262d488ea896f973d62923be982e572172e2461e0146190f2a531f62acd44a5e955a9f1e242b3e46d63ae", + "aef7b7f30efd50e4a66c87482386f39f095bff6108e68f74fd3bb92156c71c75757912b111060cdee46a6b3452eed657", + "8afe1e0ccd00079702f16ab364a23bbbd3da1889d07c4f8cb04fd994bf9353216360dbd364492932bfe20b8b69ae8028", + "9896c690999db3c08cd7b25efb1b912c3e0f976db98a3e830f086aef93222d06ce570a7b2babcd7c81d8f9955169669c", + "ac7bcab6a281468907ef1ea8a6c1cd624159c88839131bef6aa0c22f331fc87ec6128a2c2a333fb79df549e4587e1a12", + "987935c08a30b099d19f96901315a2e60591baf898581c40bf5eddcda806ff24a4536e30ed1e6c0b128a83fc77b6e81d", + "a0a6945bbede3bb09a4a09ef27baa20619d3e15af5673b9350601bcebe952597c989870746cf75767ffb73b32c6c9c6f", + "b0f5590079f0a0302b08a0cc1b7a5f39cc6900c2a5cdc7baa333d8328a731b2df5dbb67e27a154d3c44ed1a795fc4adb", + "a7294bdeea210e528f277f3d50e89e6d79950494478998181ecb38de675020130256f2f2a075899170be964d478458b0", + "8ab3041b895a631869b439d5599a66facba919226ca9b39d915f19d59f9fc82393ea781377e9bd3bcc5a310e41376914", + "8da399b59151fd48b2579948bb82698e3c9804d70ec7d6f3cc7e82901f9f2de5ee850349a7d6f43e5e9ebd47bd78620f", + "80e8c32de83d1083916d768b11a982955614a345d26d85b457f2280ff6c52bb776958add7c1c8878f7d520d815b8e014", + "81bbec7bd99d2917d2dcd8a288722fb33ad5a4bf5416fba8609fa215fb80e0f873535349e7dc287f892aa56eb9e39c4a", + "9665796fe04c8519206fba58496bc84a8b9113e7ea8e152b65f7f732e88beea271dc97b1ea420dbc8257cc4b18a77463", + "a97e342aaaf693ddc87e02790278e4bb50117af4413cd703bdf3b7cad2d1facf31fde1303b43ab2e0265467474f97a8a", + "925549ebebed348886e37773b05cd8ad04906eca4536bfed951d1ee41b3d362ddc6e1a302c21ff3a2d1e70e95117922c", + "818fdf74d7903502101551bbf48d3c7819786b04b192d9e94362d2fcb85760d8b6f45165a5443aa5221bef400525ddb4", + "a9d29de7e8fd31b59f4a087168d062a478b1329cd3c81c31e56de4fb40de7a5be9a5269ef0be452c487443a0b097dd50", + "a85286ad573db4c9aa56221135da1e31d742e0f6ff01d6b159086d7258f78b08dad55ec8eb5c91ee9d3404b2eeb67e1e", + "92a79b37db5e777f9ebbebde24a95430a199e866e56597c7d0b0e7fb54c7b092c2f6cf61fb24470ddf250cf609898281", + "8d79f5ca67ed67d52c82949af342a9fc60fb793c47c76d84b4863c550796fcae2dd59e285897c6fb96fe31cee1efa62c", + "8ad2e0bda03415ab86324992bb62dfa3612d2d003765bcad1468087c27971d08bdbae5252681f0115a184f4885d444e4", + "a08815af979286538c31b4aa5ec805053790af1ca58a8c4341be51136d094a8a05e569d876a079033298ad355ccb7ca8", + "b96c2978d0165d619d08281d295e90df78bc2375d0afbc3142ebff9c2cd4b0f0aa97a9a0e3740bc4dce0ff8a9fac8252", + "b7752cd0e582f35ab0d0036ca9c0a9fe893a6ad325164d78d865a604a85d3d23729e0362553e8b8a3d51816beeaa30cf", + "99cef1fafc29e7adfe247c753c475ad4bda7a5f9558b79c86e8a65968ede67adb38dc30071925c9d66a13860027a6735", + "b9f6c65af178c791b6137d71980651fb09cb5b42f268999c728c6e129985a9c7d77b3dc3b50751bd29ec9ee0b3111dfc", + "8d73ae61fff5be883a281782698075c5650083f00399992688738856d76d159803be0059fbd9dec48f4f0432f0590bbb", + "a8a4a2865226de9bbf19e12c7e75318439fa6cf1cbf344d5e79a8f363439d3bc5bcf4df91b54581e7866e46db04eaf0d", + "894582aeff222e145f092ba15c60d3207340c38f2c6792ee2ab4d82d50fb544ae366c2985cc2b6c2f970bcc5f4b46385", + "956014ba2d20a056fd86cb8c7ceeab9a2c6f905dae24fc1c5278fa5b84335148ebdefec5dcde8eb9b084700724fc93d7", + "af217fe2b654eff6d11a2a79fe0339a1d4cb3708b7be9f09d852158b5a44b4f9b04406d6d67c4f144fb6b69a41ae9d0f", + "a90752a784bc00df94d960e523f5596695d16a534fc806179e0f878fc0e82a91b25e758e91a165debd815dd1af5f1028", + "a697606fb32979549ad822b31df8eaaf50de4ead984439a0a33e955937d326519bb9f62c8243ad37f764655f8d32cc80", + "a3ad4a30922e45a3e665551e5611384f1c2d414f6fa806184b0c826af05f014dc872585e255543794ee41e43cdadd856", + "b29c255843a82ea74a013bac6c36a694646e61e6b9cefc4c130e2ee261e3bb5da3e0fe3ee7e6fbb009deed0530bc1c82", + "87e1cc7febefa829cf050aa2aea59385d1048f8617abba691f7ea9ef58eb90ad12eeb9c439af228b0e34897ba1cf1b47", + "994d3222f89e9c8c154362190be7167c8c2662f0cfa9d50eb4d8175b255ff0de09dc548ee312fc8226963c8c16f43e8b", + "8f1a980be640820f2d1e953264ca4c30330878971669852be3d5d6b41c488be1628b935388bfa2bd4de484acb0fe661d", + "854d90d0721579c8c88e147a4aa83553c960617b18075f8224b975562dccb30b0e02e81fa9df7070f356a0eeffc3b14f", + "8e156da9d4330a03e32a25a2f0b861fd3ea5c719fa4f834119baab6e5fa5236a9baaf0d44147bf0841418900037f6eac", + "96586fc49e53a6799242ddf617000db5a0ad20c6cb1686af2102623d64a71aaddb8e468b15fa6d100d0384e448548db4", + "b44d8d85c8df95d504f82d597f8c515866d4d4a326fa1b816dcc5bb0cc4ef1a52647aa5d2e84c62e194c01cae0885d21", + "b75c43e676a7efd199f8b32ae31f176ec667e714df355e9eecee97246f72af5bef9c5b04c11e7e90fc37bb9163f957ec", + "a49835ac0565a79f6a9078cf0443c5be20561a68b448289589721fded55188583f1d301925a34eea647f90a6e66c6774", + "b47c17ff6824a00b8f29df0adb7f06223208d062bd703b0f763c6eee4ae62d4217eef2da4f4dde33f0b469c2f2db9e42", + "957cf039cea6f6d41e368e2bd0cf77315938a0738f15ed9ca342f0a28658b763659ac1d1a85ecb362f13de12b77bb582", + "903a52f8d2439fa63f59e1e9aba864d87b0464ded63814474947112375236a6f84e8fa003cc4433c8208d80e05fbd1b0", + "8afd524209ff08d1eb6312b078f7afeb8e1155af649e930ab711dedda226dc2db6b0354aab9652eea7f433f90015bf7b", + "a95c3c9277b11bc8fe191773bf567641be57c0549913b973fb18740ff9cd7b3f7ce198fa4dc1086b2b8a446012459193", + "9455ce8163fce04aeff61e7808ef3aac4725e51404f0858fe5d39d7344f55dcc7871ca332aa5cb1a63a4399529e48907", + "809fa35b6958f94e781f2c584438b33f5ed528a6b492d08960cf22ecf63ea3aa1e2d29bc879e17296e0a6cc495439cb6", + "b0f50774de212dd33e5837f6b496556215c665437e657f674fc5117e5c07dadbd0d057e6ac4c42d50a8eb81edfebf315", + "844c65e263891d0b2fea7db6934cc4b7fb6bee2c1d0b9ab4c47f2eb3e9c5d7197dad828d38c54139123740151420280b", + "b13c78c9efcbb3b28eb3fe0b971380b7d5151c80948a99cd93c78b4c3ab0e86df6226a64d91e0a2ea4a1c0a46bc0404e", + "90300a541decad460c348b8f4257f7a29687b2362ebee8d92fd03cc0e85b285ccb0ab1cb2ff5e29c5cc5295e351017cd", + "ac49b409ded770c6d74f6e70104c2cdc95b7b90609da0743c9923179e8e5201ead03becc0ab10d65b3d91a5be0d52371", + "a257b815bd8289dfdfc21af218aaba12ccfd84ebf77642cc4cf744d9b0174ca0b0d7ab2a545c2a314fd5f63c140f41ab", + "a34778d8446e4d74d8fe33de64b2694ef1e50bc140e252af6eff3ce7b57acf8b6577a02ba94b74a8ae32e5113cf0a29b", + "ab9e935bcf0d8607e3d66f013d9bce7909962cb7a81174923db02dc89e485c2b1c33d6065bdc7bbbe0450b5c49fbe640", + "94d2c5c5c309c9eac04be4636f61bc47fd9579b47aded57cc6c736fefb8dfd8f8a5de32210f7baf2052d04c0219d3b4b", + "b8dda9046ae265214086355101be3460421f7cd0ed01bde9c1621da510941d42bc93cd8060fd73f374fb1b0a5f38d45e", + "a6674649dab5f92ab9fa811d9da1d342cf89ff6eff13ad49f4d81de45438e81a384098d3ae5ccce4c67bda5dbe246d95", + "8d619f7564677bacba29c346c4ef67c211f7a3a14c73433dd1a7692e16a7e2562f1d0532454af62fc04c2fd2bb1789b0", + "a2b93d2fd4c707f5908f624a0fc889e20164d3c61850af9125f47a1719757a6ce6375aa1910eafa4c1e8b6e20c312775", + "a07d5585447654d82817ef4d199984542328b238157976eb9a267f0bdb2229acc25aee510be68f65a312b68fdd9e0447", + "8ef55cf95e2b24d8ec88e4136399a7763bd1b73d5e90ea45e9845123e9d39a625cc336e9b67988374b8ebcbc75f2ed21", + "b62c1fc32e27c767c461411b02fe9aa44a86586e1427406f4ef0b346d077db91952abce79318b382ec75b7be23058cac", + "b252900345f5fa15a4b77fb6af6a2d04db16e878b7bd98005333f7f6e3c8e6e46cf38fc5d1b2bc399c5c2ff4af730dc6", + "a4ab5ac0cc15d3d17b1747c6e3133d586870eae0a0d9c8fa7fd990ebd4fbb62e9090557ca2792a6bc6271856aa3c9a05", + "8e706b3f2e902faee10b22742c6c33bea6f670a8937c243db96885143c1db5c979e33ab73a38359b52b8d668ccd092a9", + "8a6792190ee6c959d79f60c22980ca140c638d88d75660adaf9bcbe6dc4692ab5f01e0c460170f09f74d5e582e85ff1f", + "97ffeedfc94c98ec85ea937e064d7b290a326838e62cebd407facd1ab4f08d9c0c109d79af7cb6170fccfa6c8243c127", + "b79970b67c09453614ffd83a0c923c17f857c6ce3c87a356298f8351cab0def7ed83efd4f6638f48df67e07bef4ad9d8", + "b90f1931c7cf1822cc0a97401119910cdfd0482daf09a4d7612e4e05046295cfb4cc50d5214b31676bb1a1c9d15f9c7f", + "922921ad813c01fb5d12fa7fb7ed8e0b0abbf7b19affa190b36013c55b88fe3c7df0ae663c970eec7725ba37b95a7cb7", + "a124f33e7f28feabb4089a063a08d52b7395d24eecd06857a720439dd9414b7073bb86fbd0b04e7bfac62d3dc0fdb2f2", + "b252fe50bc6677c004550f240fe670974a33ffe7191ed7675da6ac36c780c2f8d02be7da5d92cbe2d0ce90147847f8b1", + "ae5f8c9c56070f919f3df2d2284348fa4b2e39881f7bc42c9b2f5b7cb1ebeef8ecac000f37329bbe04cc1680cefc7f4e", + "b432a4575caf7337f11eecfcbd34a6705d0f82c216301725ceae2b3c9df20fa53d1ebef65513e305013d1e0c2df522b6", + "b7c016fbbc4614cdbb12db1c9ac41f9a45d5e5ce82594d568a30cd2c66c3cc9d91a2c959697b67c582a0913de661505d", + "8f6f3e5e0347dddc1b2a34ec0dbbbb7cafbf976f19c9c902efb5c1427d1bbd4b71abd9f3fba20dda75c35a39393c989f", + "b0042a1d33a1ee9fdf3fad2299b8d70c4f1862d8393b5ebe3ac2189a2c5a58bb826128cd7a39b70d524a6dd976097e26", + "85297c4e8ae8d9b44c3fe51aa926c77d55db766c2a9f91b659040de36e34c9a4fc6f44380f8d61704498f6fd52395a49", + "8c61a988b6a00fe5a277450f30bf6daa932e42a2eae844568e3babf8815e09311f3c352dae6eb2d57a98d16b7beb2d22", + "990be28aaecd932e7edb2a97b9be2789a3905cb88737b1c79881302585801c69a3dd5fb230808b39db1352fc06e0b4a8", + "82fd14bdb335aa46f022dfe0ed4d631911e6b6f5eefb10d11e9e2e02a7df55012ed8162249d10b58eb76ced5a7b06cda", + "ac39cb058df764e161db9c39b185f09aa210bddbd66f681f1697ddbe6b305735612d5dd321d3ffbb4876771bdb321e2f", + "858a3f7e57ccb81387caf8e89f9b6039e9aadeab06886d8688fe6427151a59ab2e77e85ba850c67d099965426c97779a", + "b57fb9ea623cec432946819937c6bded0b5d03c8c67b52b44a4b67d34adfb055e6cabca67a48e4d859b4be45162c5083", + "b84d2990b563d6d7fe1f4c1894989db25b81745090b94b1fe2ef708ac3b2110ef93d647820b2a51fcf78e3f00fef5412", + "817d85b9f5e1521733d2b1fa6d4f4957ac445dc803f97fc495e20b819b14e651332f9e0573d684b854fd47824c53f0e8", + "b09e18e97e93a8523101af594422fb71afc5b8826002314269016fcc1b44002d91bcb7c90d923d460f0cc03bddfe9af1", + "b867cbede82102de7cf6cd0dae68506869576eaa66c3fc806e73585310602682fc912dc37adf5ff6f0f34a07831735b1", + "b1126255798368b692f2796a3470ed16e5ffdee2d8c9e0f7ee3d2e92950c3e6365c32895171c3494aff2a6d6356f7e25", + "b05f0a0996dec16335c770a5df3f0b08e20020c838c2caaa1d3a4a2490ede98552f5de349de2ce6e4c4a839731d80919", + "98c512bb91c8fa191120ddf5d63c88076581cf41e15eec3c168822f12b3dd0ce4d6df74a7e3093d3e35cad1cb3135421", + "84ce38fd97f7f90012c2c1e59a67bf9f465a7ccfb6f308bdd0446cc82b8a26ff7c30e5c7cc375011718cad1b31adaa9f", + "93139db52c9fb96dee97a0825f21e34c5d6d36838e1e42f4d12d01eacbe94426c85a811fe16ca78e89e08f1c27383d28", + "81454037b1e7a1765f67e4288b8742eebf6d864d9b0f508ab44fa3243168ce0ed30cb5f33dfcdb995cd2c2710ff97a6d", + "828deb2a26efb2ff1842f735e2cc27162360f619b6e3e27a85bedf384912d4726bb2759a3016937973092ece1bf90540", + "87e5a7d4e7bd301078f625d9a99b99e6e8e1207c9f8a679f8ebbbfb467bfa0b5f7ef4a4d577c7d2670efa88221153012", + "b9dc9d0ea48deee201e34379447bec789c8924aecd030eeb93db159af77eff230976ef60ea9f4b4a9e9e95c1f9f4284e", + "aa6528268d46bf0627d87d58e243d3ac34b863513c725908a2617e4c6a46ccb1d8c8334bd6dd0eea7ffebec44259dae5", + "8d26c9ce07293f6a32a664d31e6df9a7ace47e6c38001635918efd9872aceab62de7757b13b783d422eb67bd28ce7bbb", + "b0d3ca88d9829a7459b89b0dcbdb8bbb5180b00d750bd959bd110f53c2dd5d4db554b6005c4765fbe7ec5903669e5ebc", + "a94d1c72bf3b2dc6bfebc9dee40f6a89a516b252bd9f4fad96f156e3dbfc151a9b8a02324d764c7656d59230a18eb61f", + "88996e79171e30b16505638d8ecb25afd875e5f3cc3e29860937f2b5e751c66e78dc77f744a0cc454a8a655142a93ffb", + "af4d94f342665fe7ecda318de6cf1bc1c40c37dd83d060fedaf827459728152b5f0e280286ff5e6a0012036f6715f53f", + "96beaa7a2d565ec14a4e5cb895d33624c69da56b75c8d06ac729cb6d0cb64470ed4f9b0387083cd827b1609c8cabde8c", + "96b773fa2fcb7377bf71a7e286f37f1f24ee42cba5b4f33903c4566e5e5bcc501ea360e3c8435749107c3de84e272d8e", + "a69ac6218454c3f40ad0beb48821a218fb0a4f33ebade986d2fffd9a3900d8cfa613bc71676c46cfeaa5f644d1f239a9", + "857f139c08fcc45370f448ce3e4915bcb30f23daa4134407fc6d78efac7d718b2cd89e9a743eec7bf2cc0eccf55eb907", + "adeeba36af137fd3c371a2adbefea614c3ae3a69f8755ce892d0dd7102fb60717f5245d30119c69c582804e7e56f1626", + "afa97ca3548b35aeda6bfed7fbb39af907ed82a09348004d5705b4bb000173270ce44eb5d181819088aa5a2f20a547a2", + "8423bd2d07073b0e87819b4e81997e4d3188b0a5592621a30981dc0a5a9d0578fde1638a364f015078a001afb00891c2", + "b92e9d4ec3966981ee574695d6e4865810b8e75313e48c1e4bc5eebae77eb28740e97ecc3e5c42040f9eb1ee4b13b0ea", + "b07b218321d54cecfcd2ed54a5fd588a6be8d7a5b6a66dff7facfe061222c40553e076e57cbdfa0bdb08e0a009c94ba5", + "a71e1ae4d6096eac9ea4c21f621c875423de7c620544e520fb6ec3cb41a78554aedd79493cbd2c2ba4f0387f902ddd2a", + "807cdac291246a02f60c8937532c8969e689b1cfe811f239bfdee0791e7aa0545e9686cfb9ed0c1df84748e5efa5e3da", + "a1faeb4504c057304d27d54fb3ec681462384a354a4f0b6c759d4fa313253a789250c6b0f44f751b0718592637438a19", + "996bcd3215182d49f1cd15a05e1e0a4bf57e264400bf14f7253c6611d2571de7130cce81fd28e0411e0a80e9054f4f98", + "89d15b38f14bcd46f4b2dcae82b0e7bf9a35e40bf57aa947e9c4a8f87a440b5cea95229708de08ca596762062c34aaa0", + "8d8ddcaf79374c750b8b0b3d196acb6bb921e51b4619876a29d09161ba82a42271066187211ef746f9f40a5ca17b75f7", + "a3dc7f70f3a6c7edc483e712770abbaa94bfa3174cfee872b2cc011b267e0ef9baa1ab49e4a6c6c30dbba0e0a1237117", + "aa9e958bbdcb192b19c43fc6fd34afcd754949fdada98e9f4848e8db0e23acb27d19dd073c951a8819000f2356aa22e1", + "a4714e45ec853eadfe5c3bee7f683b81f97857bbd7833192a48936dd1460aee68f700a21658658b74b737c4fecf90c7f", + "a1ecab4215c1892e4a8ff3405d710163875e5dfef8a8cb84f5cac4e317d89c7696e3f496ed1747ca6f52b304190f4ba1", + "b9b48943eca3686219575026d395b969e6ff8159dc5317005df090e79d26901984e40ae4b1af060ed3ff6f42e0417d76", + "9644b9f90a66edb0396abd8c00066886f978ebf56fc22081031fbc9ce371bf9b04aa5a4ef59e59319b3a05bb7fb88b43", + "b2bb14f1c055a78596488e4e2d4135a6470c1ee43961952160b8498f674a4d23040606e937c02c1fc23dbd47e9bd4633", + "8c61f2fce9a42b94a389c7e52d7d093fc011099d0f4914f6d6f05b631df7b88182826edf9bbb1225971a080ca5c0d15a", + "aa6a7b8499cc7d256043eacad18528d38bf3be970bea4c6d4cb886690280bdb373688ceba3e506471e1d9493dc76f3f4", + "8127703363b3b35b06762c2353d4de82b7b85bb860db1028d3640f46bdb78f2d104fa77ee3e0d9db83833d2b12a966f8", + "b7b01f5909f2c66ae0fab156be5d79954e3a304615e1fe55945049dd4bd95f973bb3821117eb54db7e9ed1ee9a527652", + "8be47ba5dfe212420649193490838670c40540e0ea24adbab18c4a66e7ac3dcf94f068dec2533b60e08c1f64e7533e54", + "905a6c7e24b86aa54a05c329a6b4616d335bb0b1f1e9987562eee0acf82ad302c7c44981a1dd6b24c6121ca12fb92996", + "86969ccfd91deed93b355a2c21319e3bb08cc652b741463bf68c626b7ba2afce3f7cc397f2fb74588c2893477c948ae2", + "b5a9d20eb12c331d0d300fd4b85b0ac0bb74573178a5fac8ec9dce5e95acba07fab444260355ece442a846737a2dcd1c", + "a13497c11df21b11fc1a63b0ffdcf7f432da4dc2c98f8d07d36da4fa68aceb57af2158088e5b05e334fe0f264aeb7a97", + "882e4597cc66498a45e86a2ed9ee24652da4699af00ad35f73b5e74fde6ac3cee70630962d5ddd86162d4aaf11bbc11c", + "b748858c2bafa4a14ce44af35195e9c52aa75e109719243bbe278095acbfd6a7ae7e084caf8dae6939039b5a4e8fd675", + "83a2e0524507e74f51fe976441108f8226ba1b3a33f4e16ec45c5661ce80cb1840a93d17122cb8ca9e0f80d14f69877d", + "846cd2946c93ee5f24243d9ebc69936b3a1a6d59f45fec6c79b1eddf15ce30a8e73ad03cf606ee66baea3d8ff115f70f", + "8d98d0a3a94f6efe158f8423c041b546416145c5c2254bfa157efea0d1c99fe58acc7df6424ef29f75960b18d664ea4e", + "a39fa47e4b79f54dbf59d0b1726f1e78bc219fcfc56ad238c84b4b610e7892ff1e65d537baf5118a32f5e2eb80d5ee0c", + "8c30969a4519131de5e30121c84c04f67b98c8ad109fa4710dd3149cae303d51778add3f258f0482f1c89c169824dffc", + "af7f80d141ceb78b4762015de17fef49d7ff6202d292e9604deb508272ee7569f7fd5be3b2438da1dfecf0c26533ef86", + "97cf82f70128251944d79b8845506975405bd720e150d836205b048ff36ba8801eb74cdcc6425f28f6bc0acec0a81463", + "8c276c876eb88688957d1868bf3a1462375e608ff72b49870a5dac82cbf6584e00e3f36f236f732348a47502ccf9539d", + "964765f1a5c8a41d8025ddf56dc01b78424703d8a64a4e5539e477cb2445cb541c70127c561e717256d13f91a830ba83", + "a2aacd9e21b8c8efaf2319611addea1b9f41430aee42e7f2a640cc693aa395287cc8fdc2806b76b577d84fbd05378ead", + "ab11eabbf5be4345a77323a3b75f9ee93b011fd2a9d0154e88183cafe47f82a7888666af16b40d3cb677c94bcc755ff7", + "a0bfe715a7af5a29b1b6148b8cbee585d2b49fa6ce59bcd173ea3bbc60d71a62f9da27ffcbbd5a6da75502112fe44d70", + "902e6cc38ee42245103d90b65028a471bc7a48b825599d361aa81d8c56e0fcf9fbe8d4c13802040d2cfb85b7e022eea1", + "8832e2b5014fdef4003bdbb87e3298fdbdbbe49673f6b66e2373f1cb2605f9c4af2cdf9bfd45d1993208681d29ee1c9d", + "a7d39d3fa1ec1e0c87730fa43d4900e91932d1cafb36c76b2934907becf7d15a1d84d7234591ad4c322b5a24673bba8d", + "836ed5f09d99624204aa3aa7ac601980fda223f3b4b96b4a8fb235c574a3545d518787c12f81bd5851987f2860d41886", + "94235e94445e6086f6e9331923262070a4c2ed930ec519eabb8a30133bd4fc6debb99185f4b668431fae1b485c5c81b7", + "9828ffe20b9405f117dac044159be2d3c6e2b50ecdd1651d6a73f7633e6e2a7ba3d783ae939973604446d3a1ef0fb20f", + "92f03dc365dfe9154743ca70e6dd2758f064e3286fc543cf8c50f68effdf7c554bd17b3507c6ff4127046d9bbb5522ef", + "91ed07df479d8eb3d31292a0e987672a7f3d45ecafe72935b7abbc3f23493605134ce573f309e226c9efe830b6868220", + "93bee582661e6d6cefeff29002afc2f36dd2c13dbf33f0574c35b290ddc426170a5f7f196369ad592efcd72cfb6f8fc0", + "89a51467d966f48fed15dea5a12dda54d0015f69e2169b5e34f44c7b5a5d4c282d6f138116a0cd06a8476980e420f8d8", + "b8ccebc14b6679ba2399370848864f15f63512fd6139df7359b7b93e82c1007fd85137ecb0597294b46643e1a9e7ab5e", + "841fa301567fc57b2cd09508ce75326684e12bfb8add671dc208f579b2500b93d5b641e9f59bba798ed4ed1259757f7d", + "b3cb45c15eb00b4ccb7013299f761cb8fefc17adf6db50e9ecb8abe927a3bc7f28e359e64693813e078e1dac800ad55b", + "96e55d3b9f445f5679e34fa5425b3e87cb221cfbdd07f8353868c7f7f4ba388ee3841cb9a1d638583bc20d03a9d071f2", + "a7dee9377de740270c5b57cf86699004ba8dc2766af56b388b5cb0814ec71bb99ecf43ee3d82a552733854ecc7def0fe", + "b129dfff23b3c1c95ddb214c4711961fcb129efe2b6557ec9e116ada909593d0d2eec2c628434493393c58c52aa86847", + "aed2670e201cb3e38a8be3c86735a4d76255e1e5a4c67b91df6ed262d09c8d10b0a3891da3e6ab934058cc9a7178931b", + "b20b8921ae52e5b3c94fa3a8b46489044174f7b897779e7763d6eb419e808d76705b7e7ba5131576f425aa81b6b0de53", + "a7e45bbc3ba1bc36617291ba7663806e247f1b57a89e31520c64a90cbf8d426cac2e2f381338baf78c8f92fdbbcb7026", + "a99e651e73a507e9e663e2364fcc193ec77e8afdc08c2bed6ad864e49b537ec31e9114ee72291a7657899f2033a849e2", + "af966033636c2e9e8280d173f556fe07f8b6940bbcf6b2df7e2165c30bea66cced2596f6c17ca7c1aa0e614174953ba9", + "b69ca7a79e3d55ef21e0ebdc6f0c4bd17182d30cf6290cccca7d2551c91c12b966020d8e40e4ee4179488c9809c03ae4", + "b981cd36244e035fef043f70b1d7188d7cd045b4de0581c459fc5730e10eb7f3d5893b54cc4243849c0855e4e621167a", + "b20fea858a36921b35a3051ce787b73f70fdecd3fef283c15a2eb1bffb1dcba5991eee4a047ce4e87802da923fd9457b", + "b040e6f2e56dc1860274c263d4045837456f74b354a679f6b5ea70919835ebe5d32bf1f519e218730096c98ff396dc9d", + "8d2dd60e702c923a7204b530e7d6c193c6f93ca648c4f7bb38f4edbeb0aaed84184213afafb8db6aeb9197c24364276c", + "95dfa7348709e43d71285b28a0bfad3ca805b6ed4ae99753e9f736c79d58a35a3a50b42760ccdd03eda50f6e59494968", + "b8585632a13f18c139a411bb2f02df809591834d127cd1ff081e26d0abfe0e3fbb54abea26538b25a0dcb4d7e969590e", + "b46ba47858a29c6d523c9982660949567666daf2582b93393a4802a9e077eedbc0d49d454731696bc8e46ca50c7caa40", + "84b756b901b98a4404e58d70f39f6ccac877146c866732ae65e7e82727448d1550343bf7cdff1bfd4ee1ed73793db255", + "83e5be888eaf877a2c755897410865f64a6d1169a8ccf0336092f3932abab915e542ab75a35ffe016042340d581ee987", + "8cb274fc39285aed451a7def72cfbf73168ee10be02affe355a2bf87cf361a81ad284e9334cf00c5bf99a13d9f75e116", + "91ff6220924b94ae13f50eeac16a159232e4f16a73fbd5c22c0e185cd1998403904d36bad203baa82b85819ee4a8ac10", + "87f46e08e09aea2ab37b55fc300689d9b58ff3e72f1cffe023386035888f714fac4673c7c5193d3f3f3c568c640694f0", + "835d7d84ca7641e1b15095830114aa6072fe12260d2202456cafe2308c22651af9ffbcf6b7e56af97167dd0c4e2a4cf2", + "91202183f79794f114fd9e3b9bd05553c0e8985919965101a57d97ef666b028863e6cea9735af016dc1864f1542dee51", + "81ab2b02a9b0a490a74ae615ddd4fe560734c1bfdde6b8dd13303c1481ba0e8ab14473535a93cfe4e824a0ab29445f8c", + "8a32d73f4fc006551d4e2c61eec6130355ec9b8c39a65c24ec1edc00e80155ca83a8ef2455e892521a3d47634d82a987", + "af70d7b8f13bc90193cc1cfb0c400c4224cf10f1887848aa93e6380f7087782fc41a159926ab53c53eb95c2383b1a849", + "989bf42f9d357c51774f1c7c0f7c0c46a8cb7398a74497141c32685be098e38b4230ffe833a6d880ec391a35b1a747b6", + "94cb6715ee95700020c630b8c19e35f231de970219bd7e6ba7ced01899197da473b6c45cacfab0d652ddaf547b4ea58c", + "b12e3331f1f7d7458393a785e22e9a5e1d1daea521b4e78c0ee8ca59b41ade1735a29820e18f6afb2f2c3c56fecc16b6", + "ad4b7cf654349d136fb41fb0dd65b588199f68b462b05f5c4e5c2b468bfaa6c26329033e3c3f7873dc8ace89cf873ea5", + "a3279969e1ab596df0559ffc5ac7a6dc849680354e01c3f4fd34c6413a3f9f046f89c1e1be0b315d8b6dfab3d23d5c14", + "ac74cc5562836ed89d09a9ae6a3644c936d64bdda9e77659d9982f1be29541b03ef2723236d5465e398373ea19a4ccc6", + "98138ebce1af531dd8b631b3e74c84f0c700355a2a9bde31e5e51bb10c8bbd766559c63f6041f4002568803fe08438e0", + "9006445da131349fe5714e0777a4f82a82da343612589a0c1596393e8b6894ce1cf42784f95ff67a8384ffe1f1a4ad76", + "88502a84a85e4ce54cfed297b5d355867cc770a8ffd0714a6f23b1ab320a9903c6e42809e034bb67dbf94c4fc0d9c790", + "aa8b4bf123d1a6ccaa44b86be8f980005f2a0a388a76cb111b0e85cd072ef64167fb0c097c7b23c4bca64c0260f6cce0", + "ad49eb35dfea9feabb513a78dd1152ad7eba22fbb02a80cefc494a7037699c8df81202dfec12acc1b9e33ad680cb72d2", + "8694da730231b29afd5196371ddcb15b4dcc499574bdd063f4864ab80749833ea38ab8b0ca1629a367fe378e87a60a86", + "8eca7b488e810c479e7e32e24b8afcd837f7df183fe4f621a0336b53a9ed77603c84bdc365d8be68179a32b71a1deb7e", + "8875cd3e23c7e1af55af1b091025a08255743984186770bcd43f30b4a58d175cfdf1984bad97a15e08dac2da27198c3d", + "abdafcf58ec72997e494d4714645f40d09dcd0fbd0733e640eca44eeea67c25bb0c270299c459991f2fae59d13b4f4d5", + "8f040970141e61489284f3efd907705eae6ec757fe8e1d284eac123d313e9ac1e8dc14ae3f04d281e1effc49d5d2f51d", + "a7ff115f0d2dbf66c0e8770b3d05157b37357b9e33e9a447f0f3fa9da69ad04e371fd1e4848cfb9e8d05e3165bd969d8", + "a39b1a8c39d317fcc97bf6c396e6ed4a85640aeeadbf45166bd02bc3bdfb6266509159c03afd492e642384c635b824c0", + "a2e1b90f3dd2d0038eaa5be52127844ccf35d997143179d95ffd3749c0896398b130094d01eb1bb31ffe80ef34b42b48", + "a2bbe31f89b0c3c375ffaf63c8b7831860a921d5e388eb7907dbf61f2601ea40db86bb3952ecaa26a5eca4317a848ff9", + "87d885bb0f2ce04b40ce94d2557c15f1698dc652e938f9a2d69a73ccf4899e08eafa1a59a20cae92823795f5b94f04b9", + "8f7746370f8a24a2889d351f3e36b8a7d60e75e50e8f5abeea7dafc75441e95915721654e61ceac51bb6f112780d352c", + "a7272847526ed3d9e0d0fea1d8685b07b5b908971490bf8a46748c8b1783c629b8644feb5bac772ae615daae383d5e72", + "978c9aa2996d8bd6fda7e0393fa8b38747f8f99712427705c00f6e9a12c36f8d8b4cedb03fcb9867155cbddb5200e6e1", + "a4dec4a2354b2b32434c5bcdc380bf84580c6f9940f94dc0498a5bfe89c675a0921e66b807a3d859a6059a464cb2a9ac", + "99459ddecc7abce437f68722dae556d8ffaf8ed974f459e52e6d4a64f176caa4d42c2f2ec57e8a5b5f2034638e8acb0a", + "928c68c0c9213fe6258ab5bb0c693d97203d15da359784de7824dec143212da57d062a1fc70a79172cee31adc7aff382", + "aad3f318f1622ea87e12541dfd982d71629b8f1ded4c301f9f6b6af9432716ad057773c33bdaa6f15dc151b0ee4505ea", + "8eb8e978f149a983fd6ad01773f9aacf57bd0cc622d8a301e404184b37e610123dd081faeda571a0ab1f149a3960af10", + "851e7191d7b94bd422bcece5b92609fc1b1c8556229bc53e32963b2d2fd1cacd8ce5da9040b599eca6e610540f8a7987", + "9414157fe9d50e5a0b5a7397417681bcb3a651eec1cab63f2a88d5df68ab1fef6e4c1d7ba657cbaf241a7cb790297633", + "b5cb2dafdc5408959780754a58b2da55b2a9136672ebca42f34da4e329ddc89360e7218cde3efdbf784ddb390deacc57", + "ac6b70f65503a8e94b773fda3e72615745824930114fe72b6d833484285462392617c1b2eea4a250fedbee88f503f3ba", + "b0829a5312f9ac6c06fddee2f835a3452fe994f6d42c9edfc390d7d5b3240ca544433b544cbbddd6516b38a6d5d7c21d", + "95f8e2c59905957e34d53be3d6fb85732f834e2cb9ab4c333fea2f502452a87ccd035fc9075d7c0bd8530bb0a0c96527", + "b93f279b7045f2d97c674495f6e69a3e352f32f43cc60300193b936c2850b2805c15457251f7e3f633f435cb2b60405c", + "915abf16cba1a0b655b92a8a70c03e7fb306b86f3bbfb66967ca63e64c003b59c7a5953675efa4fa0bce9bed536b6700", + "ac2047f50a319d09df1ec44d71afdcec5ac3bd2765dc98aba347734aa780863545df9f6d71214d443e3f37edc0dae45a", + "ad49c74ddb24c8a26b14ec08bc807313c77c5967fbb36237f55994d7511bbac8d7e7b9b8ec53eb1b3b066989f078dbd9", + "961483105f605e959213fe9e8a52b76dac62d7efd2319ec71fc4e92d68fbe44cd2f65d7adefb2eb64d591b91648b8085", + "b67fcafc97d8df2b3075bbff7b3d7471dbf1f3048f309e55d5e2c5bcbc7a73aebcb0697859be9f387cbc7ce98041e154", + "8da70ac16468cab6066992389cb37c79ff5e0babbe67d76878aef9408b9597a3dc2eb5de87428bc761a0d78957b0eb28", + "aec0ce89770d299b631f15ae12f94b1e1014ac57d38fcf037c2c7712d770d074affa06e97c60691bad8733874b6ad2ed", + "8b702c85fa4c915a09fc86507f44d7aeda0993b77af87780d70cc98d580c6e996b64b7c16cdb4dd4562cb0f75da36ee7", + "aaeb43aa472aac2253e211fd1066c3a5422ea041cef20168702d0618a1a742a44f7fb30a76677640fea1a24e7fae1996", + "a8820e92825d6e02b9b4ad5ebc86161d3244cddd3d244333ba1576b6ae10948145b68d9e926bf6b7a2c25dab4cf43f3e", + "8ffdae28a1f1d15d7ffa473628a66ee9a739073f59ba781248286b39cb8f7255f66d62337064246713cbb5017e615174", + "adfc5dd142b7911326d8424881d5d92006f3b17de4cce91674d6ea37f00fbb266c791ac13f6c7a0f61d04f2a952e6a04", + "87f98982444bf661f539bec73a10256f079a4baa88a1cea0351ae3de929e1c500485b2d1b5d933063cd7d9123d5050e4", + "8f217ba4dd404c5ee384f0c9a126686db001ff0344c01c82174c5e5ef89d1a241b146008c534b13a0da6c8afe7450fbb", + "afc85476dddaf1cbb4ba8b22186789f3818c7964f9f613e55010278800cd95422702248bdf9c73760702ef24854795ec", + "a59e0f6ac2ccdfbd01f002008034390c0ea78716f5e0de4e474e3558755705c9c7afb6e3c5c4370e7bbc85958a9c7a63", + "97c0695c58d792ec31d9b86d3b2fc1382f0855057b24d5f6a54c41f76f9e2f52882cadc89a8b2f121530e7f1393faa95", + "8e49112de0b2649c08a96cf737af68fa8055f1af594846a2d0534c94df6f926f200405edaa6e6ac9db7e380707a2571d", + "99a1bd83a7ac5f8d77ddf044c80ebfc5745b998714696d67b94d185c97e9d6db989bacac646d9def463127a8b2febc00", + "aba80725f9f9f7abe10760eca73ba427ca8df864a157122eb9af828a05b0199de3add02019a297750bdab5380e505c58", + "ae18f62573275c1eb268f74c5e54e8958547f9e7d1d36a05b084eb53e5704fafe2200b8aff95cc7e9af5be2391c42b7c", + "908b8031d09d22b2aefeaa876a998e0a97c7a1070aad9e9c97836cc5aa6d2d5ef94230e1222074837b5e21b4e6490f01", + "b3132282e8b41ca6789ec5c43c1fecf3a65b8eefbc2f3d10f746a843b9ba4ce6db664678e75e424f7b11a00c1440de15", + "a1eb49440cc106ebc09cf198c93e8070271eb5a936d31c04858a2b311a037350100c7957d5545c9653f396aa968b91f4", + "81df6ad1bdd5eee4cc2f94318467b8602d15cc1be2b48b09ade12cc46ee05cbaaf77a20397e5015030b1f1db5dd9dac0", + "87236c68a2a93c8442d15d7f1d1dc01d1fd123439c183e1d843f4ddd2bcf638c128f66f1ef9b710e5d1f64a52726007a", + "84f2e7f85563bb2f61b10a712c7605d63f79af5be0dba056814fd3efebc20e9c53227c56577b72c68d185571b775eff6", + "a36d4ae06688ece2927aeb2c7f058a3cd2aa1de1601282d4e688e1d76ef20728b892928deda2314eba41675eba3912f1", + "b8326dcbcdcfce017b263c456c47692fb476c4225c95981666fff0b7d4522fc23b7f12273f0f47cf0442662124e6648f", + "84c66463ab277cda2cc7007d0509269e89cdd41c5e0d3773a92615f0fc5da63811186b05d7a11088048a5d4834a7e0df", + "b20d3571d970712ef4699b0e7034fd269c361f53e1572e2ea2676b4245e992d43b8b5931a801439a44d977a988cc360b", + "94dba6007e6d4998ca1eb84aa8e2a7e9f5c164b9d80df2825f2208ce5640a05aacac2e4f08918268990f43ae1ccab69a", + "a1c25f0b3ef9d1982153207570d9ce8d692e1b6963b509958dc4d9bcd80074bb221c46804a6d9a29e76149cc7787c282", + "8857748fcdab1199fc96084323a81d3bd8b5a7f0b1abc5bc3b5252a19268344e2e7d2d086c90fc9b5fa4b92feedb93a4", + "8b9c1d841447354b6c086549e4d1d435ab64c13933488c34bc30f0f6eb36c5c5b838b7b6bb018542247edd1ada091045", + "8f5b655416da0e719a204fc567e93792c301acb4374cf7bbabc6ce51dbeaaadfd75c2db0e16ce073ab8e91fd3d7ea9d4", + "90f2846b19be46a75c5cd0cafefcf9192e6fd80c479e8d6320c4b8d8d7d96703c9e77ff31a67afa9858e6b7bde1f7cce", + "a53e383947fd98aa1a55ac956214b46b20a52758461e8ba41341a23a835ebb713038bf048edb1202bbfd0b56a96bf292", + "9542d7debbcfb9cda6fa279c699a7b655c03b9a9b456a5d3cfc41a826c94eafa43e01155a29e39ff0bcd965f4c0c512d", + "a43792864ec5fc549f7afc02622454afc0e425c310c4039ba615067243ebb26a4c7ebfd19bd4d57ff412a4bb2a7958a0", + "b85123950e30c048465bf32365d24a5d4b21fffc6183cdbf71643a07b87463989b72dd9a6a47f134856f704909a6b38f", + "944ea689aec1376f855c0bc9c51378ad06ff758a2c075b95a60b535b88b36eca0be11e4edb5152e98cb2137d6e749f27", + "a6bef52cda22325e4c62d323e2a0e3fa91c5552fcfce951edfd52ad6f652bfdcc2341f1cd349e6b5d447924dc569bfe2", + "b56bff8ffe981bfcb30791836da10b87f2ccbe17ed969e7f7a650af07d27ae0223805b1264d985148208483be50578a6", + "8b209cac898dd580c82d854a553e2517497ad1a4cd198e1360b8b50639b380aee70ee4b87625d9b2278228ff644cd25c", + "877cce233fec74c7158b3c5bf108365e98238418b8a71f058f1aca44a0fd3a1021e3e9025bd11fe244d9fe0f5034ce7f", + "b1b871aeedb03d6f6accc99816b89f5958178738d8d8cd9717527d04363c80fdb5f6848122ae19fdbc450cfa11e753c8", + "858aca51b9e5b0a724e88688d5124eb24c9faf01a3d465e74d31de6da315f311143f22f60201ea09f62c92f61f09d889", + "8521d409615dfc8c8289e00f6aaa6297c2c4e1439b25952afd76aac641b81c70b9cef07cd58c1c0198382bddd2bd8544", + "88647c3e41666b88acca42505f1f5da226937e0522b538fe0cebb724e9a99730ca2522989e94a96cac94109aef675c0f", + "b417fdaf719caf38854e89ce52031b30ce61a632e6c3135adec9002280e022d82ab0ea4ac5ebdb21f1f0169e4c37bcda", + "9367a6feb5e23ea2eab8ddd5e7bdf32b4d2419fad1c71a1ed327b77362d8942dad971a1c2e6f7073885149cdf0a0c339", + "a71c5c08d50c57d094d6a4f02e97d3799bada92f238ffc07bd223bbe8379507b7310d20b28f5bbbf331e5e153515e491", + "9630a9a3bcb044b51299c4d3d3388a4ff47308dd27be3229601985478c0f6b55faa7e20815d8694f910611396a9d0d45", + "b0bfaf56a5aa59b48960aa7c1617e832e65c823523fb2a5cd44ba606800501cf873e8db1d0dda64065285743dc40786e", +]; diff --git a/crates/kzg/src/kzg_info.rs b/crates/kzg/src/kzg_info.rs new file mode 100644 index 0000000..3c9e004 --- /dev/null +++ b/crates/kzg/src/kzg_info.rs @@ -0,0 +1,284 @@ +use std::convert::TryInto; + +use crate::trusted_setup::KZG_SETTINGS; + +use super::{compute_commitment, compute_proof, compute_proof_poly}; +use zkevm_circuits::{ + boojum::pairing::{ + bls12_381::{Fr, FrRepr, G1Affine}, + ff::{PrimeField, PrimeFieldRepr}, + CurveAffine, + }, + eip_4844::{ + bitreverse, fft, + input::{BLOB_CHUNK_SIZE, ELEMENTS_PER_4844_BLOCK}, + zksync_pubdata_into_ethereum_4844_data, zksync_pubdata_into_monomial_form_poly, + }, +}; + +use boojum::{ + ethereum_types::H256, + sha2::Sha256, + sha3::{Digest, Keccak256}, +}; + +pub const ZK_SYNC_BYTES_PER_BLOB: usize = BLOB_CHUNK_SIZE * ELEMENTS_PER_4844_BLOCK; +const EIP_4844_BYTES_PER_BLOB: usize = 32 * ELEMENTS_PER_4844_BLOCK; + +/// Packed pubdata commitments. +/// Format: opening point (16 bytes) || claimed value (32 bytes) || commitment (48 bytes) +/// || opening proof (48 bytes)) = 144 bytes +const BYTES_PER_PUBDATA_COMMITMENT: usize = 144; + +const VERSIONED_HASH_VERSION_KZG: u8 = 0x01; + +/// All the info needed for both the network transaction and by our L1 contracts. As part of the network transaction we +/// need to encode the sidecar which contains the: blob, `kzg` commitment, and the blob proof. The transaction payload +/// will utilize the versioned hash. The info needed for `commitBatches` is the `kzg` commitment, opening point, +/// opening value, and opening proof. +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct KzgInfo { + /// 4844 Compatible blob containing pubdata + pub blob: [u8; EIP_4844_BYTES_PER_BLOB], + /// KZG commitment to the blob + pub kzg_commitment: [u8; 48], + /// Point used by the point evaluation precompile + pub opening_point: [u8; 32], + /// Value retrieved by evaluation the `kzg` commitment at the `opening_point` + pub opening_value: [u8; 32], + /// Proof that opening the `kzg` commitment at the opening point yields the opening value + pub opening_proof: [u8; 48], + /// Hash of the `kzg` commitment where the first byte has been substituted for `VERSIONED_HASH_VERSION_KZG` + pub versioned_hash: [u8; 32], + /// Proof that the blob and `kzg` commitment represent the same data. + pub blob_proof: [u8; 48], +} + +/// Given a KZG commitment, calculate the versioned hash. +fn commitment_to_versioned_hash(kzg_commitment: G1Affine) -> [u8; 32] { + let mut versioned_hash = [0u8; 32]; + + let mut versioned_hash_bytes = Sha256::digest(kzg_commitment.into_compressed()); + versioned_hash_bytes[0] = VERSIONED_HASH_VERSION_KZG; + + versioned_hash.copy_from_slice(&versioned_hash_bytes); + versioned_hash +} + +/// Calculate the opening point for a given `linear_hash` and `versioned_hash`. We calculate +/// this point by hashing together the linear hash and versioned hash and only taking the last 16 bytes +fn compute_opening_point(linear_hash: [u8; 32], versioned_hash: [u8; 32]) -> u128 { + let evaluation_point = &Keccak256::digest([linear_hash, versioned_hash].concat())[16..]; + + u128::from_be_bytes(evaluation_point.try_into().expect("should have 16 bytes")) +} + +/// Copies the specified number of bytes from the input into out returning the rest of the data +fn copy_n_bytes_return_rest<'a>(out: &'a mut [u8], input: &'a [u8], n: usize) -> &'a [u8] { + let (bytes, data) = input.split_at(n); + out.copy_from_slice(bytes); + data +} + +impl KzgInfo { + /// Size of `KzgInfo` is equal to size(blob) + size(`kzg_commitment`) + size(bytes32) + size(bytes32) + /// + size(`kzg_proof`) + size(bytes32) + size(`kzg_proof`) + /// Here we use the size of the blob expected for 4844 (4096 elements * 32 bytes per element) and not + /// `BYTES_PER_BLOB_ZK_SYNC` which is (4096 elements * 31 bytes per element) + /// The zksync interpretation of the blob uses 31 byte fields so we can ensure they fit into a field element. + pub const SERIALIZED_SIZE: usize = EIP_4844_BYTES_PER_BLOB + 48 + 32 + 32 + 48 + 32 + 48; + + /// Returns the bytes necessary for pubdata commitment part of batch commitments when blobs are used. + /// Return format: opening point (16 bytes) || claimed value (32 bytes) || commitment (48 bytes) + /// || opening proof (48 bytes) + pub fn to_pubdata_commitment(&self) -> [u8; BYTES_PER_PUBDATA_COMMITMENT] { + let mut res = [0u8; BYTES_PER_PUBDATA_COMMITMENT]; + // The crypto team/batch commitment expects the opening point to be 16 bytes + let mut truncated_opening_point = [0u8; 16]; + truncated_opening_point.copy_from_slice(&self.opening_point.as_slice()[16..]); + res[0..16].copy_from_slice(&truncated_opening_point); + res[16..48].copy_from_slice(self.opening_value.as_slice()); + res[48..96].copy_from_slice(self.kzg_commitment.as_slice()); + res[96..144].copy_from_slice(self.opening_proof.as_slice()); + res + } + + /// Computes the commitment to the blob needed as part of the batch commitment through the aux output + /// Format is: Keccak(versioned hash || opening point || opening value) + pub fn to_blob_commitment(&self) -> [u8; 32] { + let mut commitment = [0u8; 32]; + let hash = &Keccak256::digest( + [ + &self.versioned_hash, + &self.opening_point[16..], + &self.opening_value, + ] + .concat(), + ); + commitment.copy_from_slice(hash); + commitment + } + + /// Deserializes `Self::SERIALIZED_SIZE` bytes into `KzgInfo` struct + pub fn from_slice(data: &[u8]) -> Self { + assert_eq!(data.len(), Self::SERIALIZED_SIZE); + + let mut blob = [0u8; EIP_4844_BYTES_PER_BLOB]; + let data = copy_n_bytes_return_rest(&mut blob, data, EIP_4844_BYTES_PER_BLOB); + + let mut kzg_commitment = [0u8; 48]; + let data = copy_n_bytes_return_rest(&mut kzg_commitment, data, 48); + + let mut opening_point = [0u8; 32]; + let data = copy_n_bytes_return_rest(&mut opening_point, data, 32); + + let mut opening_value = [0u8; 32]; + let data = copy_n_bytes_return_rest(&mut opening_value, data, 32); + + let mut opening_proof = [0u8; 48]; + let data = copy_n_bytes_return_rest(&mut opening_proof, data, 48); + + let mut versioned_hash = [0u8; 32]; + let data = copy_n_bytes_return_rest(&mut versioned_hash, data, 32); + + let mut blob_proof = [0u8; 48]; + let data = copy_n_bytes_return_rest(&mut blob_proof, data, 48); + + assert_eq!(data.len(), 0); + + Self { + blob, + kzg_commitment, + opening_point, + opening_value, + opening_proof, + versioned_hash, + blob_proof, + } + } + + /// Converts `KzgInfo` struct into a byte array + pub fn to_bytes(&self) -> [u8; Self::SERIALIZED_SIZE] { + let mut res = [0u8; Self::SERIALIZED_SIZE]; + + let mut ptr = 0; + + res[ptr..ptr + EIP_4844_BYTES_PER_BLOB].copy_from_slice(self.blob.as_slice()); + ptr += EIP_4844_BYTES_PER_BLOB; + + res[ptr..ptr + 48].copy_from_slice(self.kzg_commitment.as_slice()); + ptr += 48; + + res[ptr..ptr + 32].copy_from_slice(self.opening_point.as_slice()); + ptr += 32; + + res[ptr..ptr + 32].copy_from_slice(self.opening_value.as_slice()); + ptr += 32; + + res[ptr..ptr + 48].copy_from_slice(self.opening_proof.as_slice()); + ptr += 48; + + res[ptr..ptr + 32].copy_from_slice(self.versioned_hash.as_slice()); + ptr += 32; + + res[ptr..ptr + 48].copy_from_slice(self.blob_proof.as_slice()); + ptr += 48; + + assert_eq!(ptr, Self::SERIALIZED_SIZE); + + res + } + + /// Construct all the KZG info we need for turning a piece of zksync pubdata into a 4844 blob. + /// The information we need is: + /// 1. zksync blob <- `pad_right`(pubdata) + /// 2. linear hash <- hash(zksync blob) + /// 3. 4844 blob <- `zksync_pubdata_into_ethereum_4844_data`(zksync blob) + /// 4. `kzg` polynomial <- `zksync_pubdata_into_monomial_form_poly`(zksync blob) + /// 5. 4844 `kzg` commitment <- `compute_commitment`(4844 blob) + /// 6. versioned hash <- hash(4844 `kzg` commitment) + /// 7. opening point <- keccak(linear hash || versioned hash)`[16..]` + /// 8. opening value, opening proof <- `compute_kzg_proof`(4844) + /// 9. blob proof <- `compute_proof_poly`(blob, 4844 `kzg` commitment) + pub fn new(pubdata: &[u8]) -> Self { + assert!(pubdata.len() <= ZK_SYNC_BYTES_PER_BLOB); + + let mut zksync_blob = [0u8; ZK_SYNC_BYTES_PER_BLOB]; + zksync_blob[0..pubdata.len()].copy_from_slice(pubdata); + + let linear_hash: [u8; 32] = Keccak256::digest(zksync_blob).into(); + + // We need to convert pubdata into poly form and apply `fft/bitreverse` transformations + let mut poly = zksync_pubdata_into_monomial_form_poly(&zksync_blob); + fft(&mut poly); + bitreverse(&mut poly); + + let kzg_commitment = compute_commitment(&KZG_SETTINGS, &poly); + let versioned_hash = commitment_to_versioned_hash(kzg_commitment); + let opening_point = compute_opening_point(linear_hash, versioned_hash); + let opening_point_repr = Fr::from_repr(FrRepr([ + opening_point as u64, + (opening_point >> 64) as u64, + 0u64, + 0u64, + ])) + .expect("should have a valid field element from 16 bytes"); + + let (opening_proof, opening_value) = + compute_proof(&KZG_SETTINGS, &poly, &opening_point_repr); + + let blob_proof = compute_proof_poly(&KZG_SETTINGS, &poly, &kzg_commitment); + + let blob_bytes = zksync_pubdata_into_ethereum_4844_data(&zksync_blob); + let mut blob = [0u8; EIP_4844_BYTES_PER_BLOB]; + blob.copy_from_slice(&blob_bytes); + + let mut commitment = [0u8; 48]; + commitment.copy_from_slice(kzg_commitment.into_compressed().as_ref()); + + let mut challenge_point = [0u8; 32]; + challenge_point[16..].copy_from_slice(&opening_point.to_be_bytes()); + + let mut challenge_value = [0u8; 32]; + opening_value + .into_repr() + .write_be(&mut challenge_value[..]) + .unwrap(); + + let mut challenge_proof = [0u8; 48]; + challenge_proof.copy_from_slice(opening_proof.into_compressed().as_ref()); + + let mut commitment_proof = [0u8; 48]; + commitment_proof.copy_from_slice(blob_proof.into_compressed().as_ref()); + + Self { + blob, + kzg_commitment: commitment, + opening_point: challenge_point, + opening_value: challenge_value, + opening_proof: challenge_proof, + versioned_hash, + blob_proof: commitment_proof, + } + } +} + +pub fn pubdata_to_blob_commitments(num_blobs: usize, pubdata_input: &[u8]) -> Vec { + assert!( + pubdata_input.len() <= num_blobs * ZK_SYNC_BYTES_PER_BLOB, + "Pubdata length exceeds size of blobs" + ); + + let mut blob_commitments = pubdata_input + .chunks(ZK_SYNC_BYTES_PER_BLOB) + .map(|blob| { + let kzg_info = KzgInfo::new(blob); + H256(kzg_info.to_blob_commitment()) + }) + .collect::>(); + + // Depending on the length of `pubdata_input`, we will sending the ceiling of + // `pubdata_input / ZK_SYNC_BYTES_PER_BLOB (126976)` blobs. The rest of the blob commitments will be 32 zero bytes. + blob_commitments.resize(num_blobs, H256::zero()); + blob_commitments +} diff --git a/crates/kzg/src/lib.rs b/crates/kzg/src/lib.rs new file mode 100644 index 0000000..0eed569 --- /dev/null +++ b/crates/kzg/src/lib.rs @@ -0,0 +1,464 @@ +//! Implementation based on https://github.com/ethereum/consensus-specs/blob/86fb82b221474cc89387fa6436806507b3849d88/specs/deneb/polynomial-commitments.md +#![feature(array_chunks)] +#![feature(bigint_helper_methods)] +use boojum::{ + blake2::Digest, + pairing::{ + bls12_381::{ + fq12::Fq12, + fr::{Fr, FrRepr}, + Bls12, G1Affine, G1Compressed, G2Affine, G2Compressed, G1, G2, + }, + ff::{Field, PrimeField, PrimeFieldRepr}, + CurveAffine, CurveProjective, EncodedPoint, Engine, + }, + sha2::Sha256, +}; + +use rayon::prelude::*; + +// These are the 3 things that are exposed to the public and used by sequencer. +pub use kzg_info::pubdata_to_blob_commitments; +pub use kzg_info::KzgInfo; +pub use kzg_info::ZK_SYNC_BYTES_PER_BLOB; + +mod kzg_info; +#[cfg(test)] +mod tests; +mod trusted_setup; + +#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] +pub struct TrustedSetup { + g1_lagrange: Vec, +} + +#[derive(Clone, Debug)] +pub struct KzgSettings { + pub roots_of_unity_brp: Box<[Fr; FIELD_ELEMENTS_PER_BLOB]>, + pub setup_g2_1: G2, + pub lagrange_setup_brp: Box<[G1Affine; FIELD_ELEMENTS_PER_BLOB]>, +} + +impl KzgSettings { + pub fn new(settings_file: &str) -> Self { + let setup: TrustedSetup = + serde_json::from_slice(&std::fs::read(settings_file).unwrap()).unwrap(); + + KzgSettings::new_from_trusted_setup(setup) + } + pub fn new_from_trusted_setup(setup: TrustedSetup) -> Self { + let roots_of_unity = { + // 39033254847818212395286706435128746857159659164139250548781411570340225835782 + // 2^12 root of unity for BLS12-381 + let base_root = Fr::from_repr(FrRepr([ + 0xe206da11a5d36306, + 0x0ad1347b378fbf96, + 0xfc3e8acfe0f8245f, + 0x564c0a11a0f704f4, + ])) + .unwrap(); + let mut roots = vec![Fr::one(); FIELD_ELEMENTS_PER_BLOB]; + roots[1] = base_root; + (2..4096).for_each(|i| { + let prev_root = roots[i - 1]; + roots[i] = base_root; + roots[i].mul_assign(&prev_root); + }); + + roots + }; + + let roots_of_unity_brp = { + let mut reversed_roots = Box::new([Fr::one(); FIELD_ELEMENTS_PER_BLOB]); + reversed_roots.copy_from_slice(&roots_of_unity); + bit_reverse_array(&mut (*reversed_roots)); + reversed_roots + }; + + let setup_g2_1 = { + let point = "b5bfd7dd8cdeb128843bc287230af38926187075cbfbefa81009a2ce615ac53d2914e5870cb452d2afaaab24f3499f72185cbfee53492714734429b7b38608e23926c911cceceac9a36851477ba4c60b087041de621000edc98edada20c1def2"; + let bytes = hex_to_bytes(point); + let mut point = G2Compressed::empty(); + let v = point.as_mut(); + v.copy_from_slice(bytes.as_slice()); + point.into_affine().unwrap().into_projective() + }; + + let lagrange_setup_brp = { + let mut base_setup: Vec = setup + .g1_lagrange + .iter() + .map(|hex| { + let bytes = hex_to_bytes(&hex[2..]); + let mut point = G1Compressed::empty(); + let v = point.as_mut(); + v.copy_from_slice(bytes.as_slice()); + point.into_affine().unwrap().into_projective() + }) + .collect::>(); + + // radix-2 ifft + // we break up the powers into smallest chunks and then compose them together with the + // cooley-tukey algorithm. the roots need to be inverted, and all results need to be + // divided by 2^12. + let roots = roots_of_unity + .into_iter() + .take(FIELD_ELEMENTS_PER_BLOB / 2) + .map(|r| { + if r != Fr::one() { + r.inverse().unwrap() + } else { + r + } + }) + .collect::>(); + + // we bit-reverse the powers to perform the IFFT in-place + bit_reverse_array(&mut base_setup); + + // then, we chunk the powers in order to compute the DFTs and combine them + let mut split = 1; + while split < base_setup.len() { + base_setup.chunks_mut(split * 2).for_each(|chunk| { + let (low, high) = chunk.split_at_mut(split); + low.iter_mut() + .zip(high) + .zip(roots.iter().step_by(FIELD_ELEMENTS_PER_BLOB / (split * 2))) + .for_each(|((low, high), root)| { + high.mul_assign(*root); + let mut neg = low.clone(); + neg.sub_assign(high); + low.add_assign(high); + *high = neg; + }); + }); + + split *= 2; + } + + // lastly, we need to divide all the results by 2^12 + let domain_inv = Fr::from_repr(FrRepr([FIELD_ELEMENTS_PER_BLOB as u64, 0, 0, 0])) + .unwrap() + .inverse() + .unwrap(); + let mut lagrange_bases = base_setup + .iter_mut() + .map(|power| { + power.mul_assign(domain_inv); + power.into_affine() + }) + .collect::>(); + + // we re-run the brp since the blobs are interpreted as evaluation form polys in brp + bit_reverse_array(&mut lagrange_bases); + let mut lagrange_setup_brp = [G1Affine::zero(); FIELD_ELEMENTS_PER_BLOB]; + lagrange_setup_brp.copy_from_slice(&lagrange_bases); + Box::new(lagrange_setup_brp) + }; + + Self { + roots_of_unity_brp, + setup_g2_1, + lagrange_setup_brp, + } + } +} + +const BLS_MODULUS: [u64; 4] = [ + 0xffffffff00000001, + 0x53bda402fffe5bfe, + 0x3339d80809a1d805, + 0x73eda753299d7d48, +]; +const FIELD_ELEMENTS_PER_BLOB: usize = 4096; + +// reverse bit order of given number assuming an order of 4096 +fn bit_reverse_4096(n: u64) -> u64 { + n.reverse_bits() >> 52 +} + +fn bit_reverse_array(input: &mut [T]) { + (0..input.len()).for_each(|i| { + let ri = bit_reverse_4096(i as u64) as usize; + if i < ri { + input.swap(ri, i); + } + }); +} + +fn hex_to_bytes(hex_string: &str) -> Vec { + (0..hex_string.len()) + .step_by(2) + .map(|i| u8::from_str_radix(&hex_string[i..i + 2], 16).unwrap()) + .collect::>() +} + +/// Computes a KZG commitment to a EIP4844 blob. +pub fn compute_commitment(settings: &KzgSettings, blob: &[Fr]) -> G1Affine { + assert!(blob.len() <= FIELD_ELEMENTS_PER_BLOB); + multiscalar_mul(&settings.lagrange_setup_brp.as_slice(), blob) +} + +// XXX: this could be sped up but im not sure if its necessary due to always having 4096 elements +/// Performs a naive MSM and compute a polynomial commitment. +pub fn multiscalar_mul(points: &[G1Affine], scalars: &[Fr]) -> G1Affine { + assert!(scalars.len() <= points.len()); + scalars + .par_iter() + .zip(points) + .fold( + || G1::zero(), + |mut acc, (scalar, point)| { + acc.add_assign(&point.mul(*scalar)); + acc + }, + ) + .reduce( + || G1::zero(), + |mut a: G1, b: G1| { + a.add_assign(&b); + a + }, + ) + .into_affine() +} + +/// Computes a KZG opening proof for the given blob and evaluation point. +pub fn compute_proof(settings: &KzgSettings, blob: &[Fr], z: &Fr) -> (G1Affine, Fr) { + let y = eval_poly(settings, blob, z); + let shifted_poly = blob + .into_iter() + .map(|el| { + let mut el = *el; + el.sub_assign(&y); + el + }) + .collect::>(); + let denom_poly = settings + .roots_of_unity_brp + .iter() + .copied() + .map(|mut el| { + el.sub_assign(&z); + el + }) + .collect::>(); + let quotient_poly = shifted_poly + .iter() + .zip(denom_poly.iter()) + .enumerate() + .map(|(i, (shifted, denom))| { + if denom.is_zero() { + compute_quotient_eval(settings, &settings.roots_of_unity_brp[i], blob, &y) + } else { + let mut res = shifted.clone(); + res.mul_assign(&denom.inverse().unwrap()); + res + } + }) + .collect::>(); + + ( + multiscalar_mul(&settings.lagrange_setup_brp.to_vec(), "ient_poly), + y, + ) +} + +/// Verifies a KZG commitment and proof for a given evaluation point and evaluation result. +pub fn verify_kzg_proof( + settings: &KzgSettings, + commitment: &G1Affine, + z: &Fr, + y: &Fr, + proof: &G1Affine, +) -> bool { + let mut t = G2Affine::one().into_projective(); + t.mul_assign(*z); + let mut x_minus_z = settings.setup_g2_1.clone(); + x_minus_z.sub_assign(&t); + + let mut p_minus_y = commitment.into_projective(); + let mut t = G1Affine::one().into_projective(); + t.mul_assign(*y); + p_minus_y.sub_assign(&t); + + let mut g2_neg = G2Affine::one().into_projective(); + g2_neg.negate(); + + let mut p1 = Bls12::pairing(p_minus_y, g2_neg); + p1.mul_assign(&Bls12::pairing(*proof, x_minus_z)); + p1 == Fq12::one() +} + +/// Computes a KZG opening proof for the given polynomial with a deterministic challenge point. +pub fn compute_proof_poly(settings: &KzgSettings, blob: &[Fr], commitment: &G1Affine) -> G1Affine { + let z = compute_challenge(blob, commitment); + compute_proof(settings, blob, &z).0 +} + +/// Verifies a KZG commitment and opening proof for a given polynomial with a deterministic +/// challenge point. +pub fn verify_proof_poly( + settings: &KzgSettings, + blob: &[Fr], + commitment: &G1Affine, + proof: &G1Affine, +) -> bool { + let challenge = compute_challenge(&blob, commitment); + let y = eval_poly(settings, blob, &challenge); + verify_kzg_proof(settings, commitment, &challenge, &y, proof) +} + +fn compute_quotient_eval(settings: &KzgSettings, z: &Fr, poly: &[Fr], y: &Fr) -> Fr { + settings + .roots_of_unity_brp + .iter() + .zip(poly.iter()) + .fold(Fr::zero(), |mut acc, (root, p)| { + if *root == *z { + acc + } else { + let mut p = p.clone(); + let mut z_1 = z.clone(); + let mut z_2 = z.clone(); + p.sub_assign(&y); + p.mul_assign(&root); + z_1.sub_assign(&root); + z_2.mul_assign(&z_1); + p.mul_assign(&z_2.inverse().unwrap()); + acc.add_assign(&p); + acc + } + }) +} + +// barycentric eval +fn eval_poly(settings: &KzgSettings, blob: &[Fr], z: &Fr) -> Fr { + assert!(blob.len() <= FIELD_ELEMENTS_PER_BLOB); + let inverse_width = Fr::from_repr(FrRepr([blob.len() as u64, 0, 0, 0])) + .unwrap() + .inverse() + .unwrap(); + let mut res = { + if let Some(idx) = settings.roots_of_unity_brp.iter().position(|r| r == z) { + blob[idx] + } else { + blob.iter().zip(settings.roots_of_unity_brp.iter()).fold( + Fr::zero(), + |mut acc, (el, root)| { + let mut el = el.clone(); + el.mul_assign(&root); + let mut z_1 = z.clone(); + z_1.sub_assign(&root); + el.mul_assign(&z_1.inverse().unwrap()); + acc.add_assign(&el); + acc + }, + ) + } + }; + + let mut z_1 = z.clone(); + z_1 = z_1.pow([blob.len() as u64]); + z_1.sub_assign(&Fr::one()); + res.mul_assign(&z_1); + res.mul_assign(&inverse_width); + res +} + +fn compute_challenge(blob: &[Fr], commitment: &G1Affine) -> Fr { + let mut data = String::from("FSBLOBVERIFY_V1_").into_bytes(); + let degree_separator: [u8; 16] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10, 0]; + data.extend(°ree_separator); + data.reserve(FIELD_ELEMENTS_PER_BLOB * 32); + blob.iter().for_each(|el| { + el.into_repr() + .write_be(&mut data) + .expect("should be able to write to data vector"); + }); + data.extend(commitment.into_compressed().as_ref()); + + let mut result = [0u8; 32]; + let digest = Sha256::digest(data); + result.copy_from_slice(&digest); + + // reduce to fit within bls scalar field + let mut repr = u8_repr_to_u64_repr_be(result); + while repr_greater_than(repr, BLS_MODULUS) != std::cmp::Ordering::Less { + repr = reduce(repr, BLS_MODULUS); + } + + Fr::from_repr(FrRepr(repr)).unwrap() +} + +fn u8_repr_to_u64_repr_be(bytes: [u8; 32]) -> [u64; 4] { + bytes + .array_chunks::<8>() + .map(|chunk| u64::from_be_bytes(*chunk)) + .rev() + .collect::>() + .try_into() + .expect("should always produce a 4-element vector of u64") +} + +fn repr_greater_than(repr: [u64; 4], modulus: [u64; 4]) -> std::cmp::Ordering { + for (r, m) in repr.into_iter().zip(modulus).rev() { + if r > m { + return std::cmp::Ordering::Greater; + } else if m > r { + return std::cmp::Ordering::Less; + } + } + + std::cmp::Ordering::Equal +} + +fn reduce(repr: [u64; 4], modulus: [u64; 4]) -> [u64; 4] { + let mut res = [0u64; 4]; + + let (v, borrow) = repr[0].borrowing_sub(modulus[0], false); + res[0] = v; + let (v, borrow) = repr[1].borrowing_sub(modulus[1], borrow); + res[1] = v; + let (v, borrow) = repr[2].borrowing_sub(modulus[2], borrow); + res[2] = v; + // we only call reduce if repr is greater than modulus so we dont need the last borrow value + let (v, _) = repr[3].borrowing_sub(modulus[3], borrow); + res[3] = v; + res +} + +#[cfg(test)] +mod local_tests { + use super::*; + use rand::Rand; + + const SETUP_JSON: &str = "src/trusted_setup.json"; + + #[test] + fn test_commit_verify() { + let mut rng = rand::thread_rng(); + let mut blob = [Fr::zero(); FIELD_ELEMENTS_PER_BLOB]; + blob.iter_mut().for_each(|v| *v = Fr::rand(&mut rng)); + + let settings = KzgSettings::new(SETUP_JSON); + + let commitment = compute_commitment(&settings, &blob); + let z = Fr::rand(&mut rng); + let (proof, y) = compute_proof(&settings, &blob, &z); + assert!(verify_kzg_proof(&settings, &commitment, &z, &y, &proof)); + } + + #[test] + fn test_commit_verify_random_challenge() { + let mut rng = rand::thread_rng(); + let mut blob = [Fr::zero(); FIELD_ELEMENTS_PER_BLOB]; + blob.iter_mut().for_each(|v| *v = Fr::rand(&mut rng)); + + let settings = KzgSettings::new(SETUP_JSON); + + let commitment = compute_commitment(&settings, &blob); + let proof = compute_proof_poly(&settings, &blob, &commitment); + assert!(verify_proof_poly(&settings, &blob, &commitment, &proof)); + } +} diff --git a/crates/kzg/src/tests/kzg_test_0.json b/crates/kzg/src/tests/kzg_test_0.json new file mode 100644 index 0000000..e348c5c --- /dev/null +++ b/crates/kzg/src/tests/kzg_test_0.json @@ -0,0 +1,12 @@ +{ + "pubdata": "00000005000100550000000000000000000000000000000000008008000000000000000000000000000000000000000000000000000000000000800a42efd743e554bf21985b562e6b1f3ee3a2ed72f4dd98d76a68a1146cc9a21a86000102290000000000000000000000000000000000008008000000000000000000000000000000000000000000000000000000000000800acda5158c3dbcac23211672d2cc9c3359fc98a11a515a328ff84730ce388e0b29000103170000000000000000000000000000000000008008000000000000000000000000000000000000000000000000000000000000800a034d6369f58fa6f6577da618b1402ae4035b815c468a5e5e120833f35064d7d60001035b0000000000000000000000000000000000008008000000000000000000000000000000000000000000000000000000000000800aab90d8e21f8f6be792eaceaeaf2a7e262b8cd8b1a950cef7856d3c00d3e0fe240001036c000000000000000000000000000000000000800800000000000000000000000011f943b2c77b743ab90f4a0ae7d5a4e7fca3e102e0c3af29edc7fd00e8d0a61d41ed085b5999bd76d0ec57c8b794117edb48006600000005000000386c0960f9e67050e6b7ae575837febf738d9dd205bdd96129000000000000000000000000000000000000000000000000001da2dea1775200000000386c0960f9a255d58fcc01e78bd7f30db1c5d736a19d6de5d5000000000000000000000000000000000000000000000000018df33ae339d000000000386c0960f94f1b62090fc5498593cf8803898feecd5109b2d1000000000000000000000000000000000000000000000000001d9dedfce0a600000000386c0960f9988bf802a450b1a23b01a16361041b8cc4c0096c000000000000000000000000000000000000000000000000001bdd15e065b0000000004c11a2ccc170716ffaffcb4579f8226130d4a8625904162263a0b86991c6218b36c1d19d4a2e9eb0ce3606eb4800000000000000000000000000000000000000000000000000000000138ce2000000000001008d34040102f2e6ed1059ff0ad70d4e11336e3e5ad30e827e008cc2173fcbd003105e10deef0001000117285a242b48c751232df502f6448f1dbf4a1d9132f1cccfce399608c8b90b3a0a1f96e79f02ef0c7d92a6ba1968507b07a357809bf9eaf6ccf0fda94f00010013eff990900684eac2c81359f38c1b0a834d011273ae30310f9c7807464a1db77812daebf491cddd7c2c4af8b712a218f35b8f3ceeba86aad8ee402526c200010000939c0f641c18abe55b3a876a26f1720e4903c3f12e25b8b6214942db9069af66d7b664990e3f84e4633afb9c21a8da0ef39901d9bc286fad7e19d3e6690901c02aa7bf71858e06cbaedda3277e925e055d21c73be1309a36203fe4727785b409018a07091e19392f970a79e422657f4765f3c6498b0e174b862d050c05dcaf5bc50901ffa6d75a531a1505992e4c1ff4ae286f3c5336d1464bc9b25d9178749c5a0fc70901a9729e5ec3b68a9346d3dffbbb2027b1b0f40417a4e59e60fad413467c1e90a40901b4e5bfca3d03904333c9db34f701ee88c866ecab38b47bb219ecac0861ec961b0901adc5ed37ef2f96fcf6b4c8ae77d5dc254da413dcce18fbabba941fbbaeeb46c809024dfdf044fd553fd9ba2ef4251f008ee4cf873fe70182d1b2f75f28c91d282c06a1996a719fbc67f35a4344f73890c1172eb194a88cfb6b291ade6a03a87fceb351b6ccd7a8ba72fd46817f800389c924d23232fcc6a118cd1fc2a93f3a384b0535afd162716154269523f7345e0bc56795149c3dbd12ad80b8d16c271a08ce2873c63cd21f8b28275563390881110a3ecc00415f285ab6f8e3d9ba138242a46510c44a0c83a350067a6ee880f6fdcfb01ee4391e32b4789740000b73f38daa02eca7cdd85642f68cd8cf51fa015d796fc2dbcd1aebabf654bea441016b288c64f0c000bab081a7b6f92a4ec1f02eb005520b7673af201c4ebe79e761538585717fafbb39b59ec022d606f068ebf6717faab388c9c53c18fabe7838c5608820c5d2430989d90b92dd26451e4102c68af0bb1400006f4753c45e67f5311ae7255bf8889f7fe7e58b6af06d9806e5194a1c5c66d05139054ec8fb4b6000bd906f224650fc26515436b3c25a87d68addb31c6a5373f7e00f754d39119486391e3e8744f910003c67eee680524913ae37ae69f0baa481d0e4e6d3484a307479eb229bc30f479e391be3888d7ca00075aa7f75697d3feb547969a0d55f8731fead1e14041729ebd1d392848e7cb2af3914ae1318ecd9020f2f4ddce402fdc9ee7b3c86ecd111dbb325d01422bf470db82108a3abd1e3b34101192d1069581b941d50c402518ad6fdbed21958ed6c5724923454fdd2495cde5abc4bf4516ef98c3923b46bf7fe2000f6d7022ebe58dc19e751106f2cb98fd24bd6e14d8073a53d3f8e11b45c5df48b00a99e289160656884525d83a63124c30e63f37032d635435d92d49995a8f8b408dd140b448cfff621010bc3dd28788ddd82f2bfc323f8b837afc1ac6c5c1580b2091462157e0771f69f064d0d7bf52f7ebb7e91c66e35d4914a9dba6c7e3cd75ce6200914183241104a8b011521fc34fb04dc72026ec296cd803af9bb39e7dd5bf873ba5d191a524bc07d6ca5418464758476f726a9d98e7a81bdf17ac4ec7badc550129a1151b03c194c4b4034b276b9d891a6f4775fe20e1e5cc98babd8744c81e7daa3000b49c7e5c28abda1a47fd53ccec8fe0ec67794aea9e3cd392a49b88e01e96050ca4793360ad636d62a6d89ed1dd50d100393a25b769f51148d33e9c80901df92d744c1917c79c8c38fa95bb485b984c521a4253c1ac6c12035ee61226f5c417bf8114d29f36913853abff5b4c974f781edf65caff6e8293912904b86c909f9559cbfd685c0ba6e491dfafba0f1bd4300000231b5c9c8cae149bd749c383d5bebd9ee775377beb035eb84377eff29f5edac291b6103f419ce028a771a813617dc177b50fd2f2d4ea489a7f9c2b6dfbd7cb0608ff6bb949911d83cc543063aef4cc63829a471bd77f68576941d08cfd681e84f80d3e1645920171f09019ad2dc29fffa2ee724cd419095cff0605b7df10d65420c3f20d7522ab9fb81be2165a6de4ee706aedeba038f6e38ad43723329856ac986583787b60bc1f54a7f570a91b33269294c912982def982794434499fa4ce83d8a32f8629d2c1abf127af5e85f34909aaeb23a7a5450a60ce1493c3bc690643f16943df5367f77aa54a54bc8a8200c68674c041892fd6f77453341b524740e2f87d0a3df7f0ed575478a6b9041b04f0d563c8544007d64a89d51131d5adef571aa36d21bb0f9917c463b5c9906d07f248619a83b48509c798407bc4da757ab7035dcc0901a0703adc7ccba7cd1054340b8b59b73e6b8b455833b8cf427b7beee4a0f02c09a12a9096df9ef41ce9cac50cfaacf1151071f975ad45cc7125fba34a20bffab916ff36625d666f049583117e53406ad65493808667a1d3d91634cf4c04ad1b76ce2c06f7385a897f54d3bb11626357265a0e408c00504dcf29352cc80c19ea774e4a6f1cbe01933d6dbe0901567e3d3f853b2bf658b34a086e56c374fb85eb4c313829401d431924d7465d4aa180115c708e12edd42e504c1cd52aea96c547c05cbe9a44851e30b39b56297fdf090f6bf257d6c5bab3479854a280ba419fb6d5daa180115c708e12edd42e504c1cd52aea96c547c05c76a06ae72e8a8f120cf6b43317b34dba4b119b37e8d01ca2b28c514b97d2887e090171503ac05f8ca52d7cdb786cae95ae5062c8a97dac126ed9272dc7e30eb806c80901fd2e18833a48b67bbaaa3c77c79cbccee2f71b4ce0a92b5e2423c707cce4533aa180115c708e12edd42e504c1cd52aea96c547c05c8bc265e1dc0dcb7c9ecc7cbf5f7c1843c5da43bf586c40fa9560774c5eb1ff080901e8bb18c16a016ed06541ccb16b38473c9357af9322a2ac573175b7b1f9ec07cf090107ca4196285a78fd294c7947fbd5febe8b6ae006c9d658e31b60017ff3f97ae9090166df2a30dddf70b6f44a42de4833a3680b9c5ca958accae9dbf7f0b1600947f40901281c95c77398a8b558c513bea568f8be9be22fa8f1a6d5645573de661f2ee6a0a1c2fd44a8497e2fac310f4fc8418908125546f32efa28383624da04595bf930920bb58bc4b15b5de94ac42056027c1daba69332e0313f2a01718652997cd9436f8f814343cb15afa1919b850b03c4a0d28149ec068207f3c551c6c2090136d8384f8f88b18de18e3ae63b1057cf0772abe2067b98b68446b10ff458fa2e89010000000000000000000000000000000041e13027c1b52df1bd9803cf1545bf4ab94a16d168d9104f09d8766103d550bb0a01bf35d33c89f5e664ae2b92a66a939eb013ac1de6515a57ffea70d56fcf6b706619d057eab78b3a25d00ef7f39c4967eb220327371363098ab55ae8ac283be6cace684d200a01966f1152c6a8a2f9a663c24ed9440e728138744090cde391c63e8e1786df53102106db12ccc6511c9c36ac5967ccae5da01cd21ee0445c43211dd1198302ae036d5e3b2cc60a013abc0472eb8a8849953715f91ecd85ec47ef839e466dc143cd2d32c6b61349410a01a0dc9b0d01fe770f0cbed8572f05d38c58e5551d15c16d5608fc302b7ad49e0a2102a5692aad0f28864b4e3691a85974872a6ce40e6eab98b56b6d3b8236786a0da0292531210f3753091014a4ce05520dbaf7a2654d893c76a471863e356ea366e825fd296753bad41b1962c6ceeb0388076118d3a1e6e25ee9084ef2e74cfaecf782cf4003319c0f335f96911d19b0978b507111c55737118180a4607b2e9f115ff1c10ceb656a32a6f4cfbb21c8c6e0472101726199c58545f9a610de3b4061e87c21f85dd19449ca4aaca2dd868172c540728497bf311d9e0171863e7f0ea5f165f28a75168a2e392f1c22732864565c491a136cfa70189eba027acea12fbef53b81aad68c4727f3329869ee704609ee749f7a7407fb1ba20d656da3c5ff74892871546e61dda8da470c0b99caf78854120901688a021fdf7d14582bf5bd2eb5c93cf86f21171c52b86ca334776c7be06633e9a14aa5cc5f01876266b9a0abca2a77fb4af9425cc3c0f84c80c45a8236856be149391bf75bc23441e7e25070407a08efd97811e33da165d8e9461f9018596fe0ab94fa050ffb3bca242fef613fb876ab1c59ee2b84cb39b85d0df611e9380de6df4f5da1f8f02a925c8d490c944fd8e64880228050aac29f405aaa380863f232d74b43ef4408dd111745f3a9d46bda7ec362ed97a144ef12d4b87c5646869b28e6b62e8aca975afdfa753b08a8b2b9aaf55d8853d07c452777fc4c529029633816d926fdd31689a2ae29680171861aef4adc1342aa75eca6cd65fbec28e32540eeb9cc63c12a4e7fd74288094cc1e10901e9aa2c34ba3c83030e0d8f90d17ac623eb912fbf8cfbee93413bbf7329d959b00a013fec76ab6733aeb76b088570a0023b4fdcb8d0c828e9dcc8f81bb0e75645e6d419f2662152b7f4b7dfc66f12b9afe0f70362b0a6c5b42e041c3e4e9bed9df52f3dacadd60a012f93b53ae541da4ffad8c2e72ea9d77c1860404254cd8cdf8a5bff8708bf99de0a01e63866cab2b4c30eecb868b0dc9f50372b1f79ad7c93e37fb5a0ff411f5cf0c50a0123783ae730d29ee74f13dadbe6201b3063acccbadb0b768d5c80e8ce06a50d7409017282df9bdedfab9ea9fae6c127d63bb89e4c5e2bc6243b231ccdd2a835b1a8ac19a7e215f14e64c035ed9a1f45aa7f9decad368ac1292a3835f448e952b348ed2324b84d21027e577b5763f3ac147822e73df0eb878313e7e55df3db4405eb1db3746083c12f19b9d10a015f06be9c9642a6321a48bd6eb51fb69e85767218915fb4ef3e1ad12115ef907419121c1b961e6a90ac18d287abbe6645e314566d6068483ada0ecc53c1bad6918d130c5009018beba255936bf7debacdf5ae874cf4b74789861b8386733eff99d087b394c6a20a01df4b1208f951cd68e9169a4820678631882ce39999e2b20d20bc94b0f6273ae60a01dd845bf2c9bc9886ac2286d0dd8c08b0e7b227570809e3229895e49f65a298064902bbc099d5fb6d81289a8e412e9c64e1d0237b95f8899e9314631b7abf0fad93881ba7e447abfaadfc0920cc1d27e9ee7f5678cdad1e1140c4d852ca0c64f04346089c0809b48771cc695f090876af4949a5dda017af2fde7eb64989734c48bd449a895b7d22c7e20f4e85b27b0901d1b4ad97ce6833314f1374ed5de8210ccec6ac500552c49b35c486056d5c52580a016a975864c94755cc754e06fc62e04462f62979fbc2df237884199fdef76b8cf7096e352fcea326988173e6d09589571f5522c74e25834abe3e70b4ddddef84c6a603096e5ac400e164e56f8210320bc96798e6e0b5fec0470bca0041c760d46057277ed7210134d6f4e47a623cc0243610a628b008fe34865b98e100fe9c64dbb6aab3df82edfae169210134d6f442dc4493dd70032707de9f746062785a10d98a1fe54541e04a2c3fba6a25770f3904325b0881a86b033ed80ea5f81caf6ea810c94a038363a914e2bfd4bf89397f140896043438f549344692099866068fc7efbc7ca398ad874cfc7be2cfbcf493af177a976e278b076487fa4c23906040af191a524bd08b413cba0ad1f7ae3cdf10fa1a5a78fb0f763e8b958af889d1cc65742a81956906f17c2a1f17621892641e82adf64a6735ab0d469b6222445a27a0509b7334974617b086da6556919cb32bc86d310150969bfade2922350e35eea1b624bc0860fc6d1a88ef8949f6d193932a74f1cdadc3b17ded0901b91f047425ec49fcd708d173677a6a5c4294172167d6b9d3082d475119697f680901de1770af232be79daffa32d59cb27e047f3230375cbb6c6f359115ad2113d99c090101a485d8779c9a044e5957d15aa43aa8206a29204e97e578f6235eb52e23afc23103600171864a9d2c5b32b59cec41409eaccb473a7c1b6816ed36a719b35fa372f988da2d20d4a138f784e67869bbf5aaad5d664dcd05d7a47a9885d224de36f00d582d2a3defab0029281b54c6b681af3517a007ce32b98b6b01a7517f6a4e06b86e198796198f82561983b0e61ebc8b86a629f04ad9d09e9a785c984231c98d0eb041c971d9591415c9488a1690396681007c669c526d4b341486bedb9c3b8635c26b27602f7f0df7a6a0d653a140caac8c39571a923ca04ee1965836020f5cdc7d95a8ec1546ff2b8c7bec15af2af26384f5c96cfe387c870d310c40f9ef7267cee79a8cd93df1aa7d9f40c4e4ae2b7d1d4740f1e5e1ba1e977201cc6af3b0810a01b7b4e11ddfeeef52ca0c336858792be12d31db6c53b00d24a6776f4f08d08b7d392386f26fc100007ef3af95e82367c7180371ab903da968240e8720165f2d6d113d4e10f8d00279413ae5b783aac200009712281cec3fe27aec63dccb979a34e7d86e37e3b3da429e23697846a2ca958e0a011d3984ca7ed5c262e1067856cb7191d87bb7d1e8acf0230d4a600d07ca22bad2418ac7230489e80000c454190d333fcbedadfa7051049955993572cbd63cf42e68aa77b717d073c8a40901fb77b81a76104598d9ffda1152005f97e9820700085c91c332280307da83eae900810972423f7d915b94ae6a76e50f4327fb1e8b9d0e80c318ab05fd0819e639b4fd05e860183b1015058ae32bcb7719855ec7aa4d7200910ee810344e3cf034f9315af3107a4000f006789c75571d41a9aacb4465f684309aa3d0597b2c75366cde06e60bbbedf969012c000002ee00000000000000b9ef0eb0e2d93d6d27b065c20e022506f10a469215692dc4fab8347ccf84682b0061706500000000000000000000000000000000000000000000000000000000063e47078faf6c734bfe7e188b586ade665b4e478038a57f99fccd918751aa2b69006170650000000000000000000000000000000000000000000000000000000006dcbe7fcd0d4a4b51538f54650f1686c598455da5d3d4caf3857d4c6c8c8cce4609011235fc129aa7c102d35b04dc78a7d91183ec8dcebe12c0e5364660bff015328519033ba9f6c2a13297570dce587d6c1fc75835bf680950683a2c355761d8a473af1f2a9f090101acc07e9cf7f84857070a7a1f6320eb97b3e5415aa19cb3dcb262893651b0971903c55efe2aa6546051344415d9136c36d7224b5de88d5f50081448ac9b71fdb50ac10da1149173b9c112466d7bba1f647e2cdcdd6ff184e4275d59e3ff3f1f2321277c45d8ff9326dfa34100857af52b1e5c91a8768b04538139d4793ad35846718f9892a36e8b925b2b8e01b97a36abb0deeeb6503f11c3be5753c9d069dd7fd681798028313bdf09a144e8d30c05e5a2219d5f7e17e7b87e60f6c1353e9a3cd0481a52950a63256e2e403fd76b17c7229e295ecdfc3db33f44b869b3ada16dd28c2c5b91dd63b4d4e78ecac7139878371768686724262c779b02e44e6909c79dda2440adfd1f4e3da630f1b18562762c34594175b37816b749b66b0ca5180a81cdded691fa9475dd73710a0f98169e0077e37dd5bae3a8316c9c220a01fd9ffe9dfd6d0978af66e263e8dc7277c8e21b6a802c63a315f9922d8d43e3a6a10d5328bdfba313310c9d224c25772b6fa751b9d40213977d8228758a54d817457dad5de4b806b939a352c83bbde7f0a36e32e5243107b9017186586ff4762b92786831ba36ed9120db1a885d01d0d763980956b200644c7d26e1230901bce25afb1bddc81d393a7d30c196e5cf3753a0e876d4184457a9806266d3e436290a9d9896c78e9c6203892a9d5862e8511d457c70c7f63f5ba7637eedbb0f4ab76ed8ce64bf290f98114c0f326b8c018ec3ba88d28b7e146a1e3631b33af636c11a656bbe24dc43cbfe2cc429e84fb60e3bff1427493f2900dd9f0aed1df7c1510fa629ad473d2e32bddcbbfafa717a889311ef465c121784579443da935b76be97d7d06fd561934765db9344fea3ec4409d0b31b390d22f86191843d6e37d777cc8e8a5edec34e69d8cd7512f38c4cd1e90d4aab6a46c3433fb68d4b392c8850ad006bf0b94d78ea6081d51ce7b39f9aa65e254f9adb05243550fc4c377edc24663b6d78e10342a9706aaac244d001368b000000000000000000006a89e8b51815f5e8fd9e659eec56c8366856d20501bf14e46707331fc77ff92516e12cb25b0c3a0bf18a9d2882caa41fdfe4eb2119a2459da249b6bc6e3f23d4e12d1ba35abbfb0e961961328a4b2101c9c38047d89ddae6658dfc2fa241515f7b12b8ca79c357bdf4ec4aa0c2c2d6721ffcaf41107d4ec3af4257850cb66c12d0f834afc9b5f4ac808e7d80773c7d420dcdaee1fdd0f2d62e55a40209011b30b332b3d0c14d4041d58ea84b247009dcea5973fc8a3cacc21f7aa99dbcbaa1037119632437119bcd9a6b18ed9ea9ebccfbab7287cbb29a78f07e708e996654f2294c3da7277f0fadd03990d835b3838becdf9f4901f9e8e7ffc272bce3672a4b4cb989f3df5fde6f1604adf28cce47f315c72cf18f697884170e5fd57ae1034712a12495b627ab792d400000000000000000000000000012926a5b6731e66599d907c4913385770f91b103e1b072e98d12483a688f4b19309140090185ba802574057d16e01335eedc59ede451c146aa72c0ae54e419d23a671e5225a15039543c3b1e342da8ba16ea9c7dba464f74edf637dd4224f9cd1eedf6c115dfae7363382984a8772162a8a210da403f22c009203136d80171863947f55b48c65591d2d2fb62ee6858c2ada93941ed7895f9841e9851201a321993090a369ddb839ca0979e7c8c6d7cac3ebda8de4bd7055bbb218b511620d4d17bd55a09090eb9872b456aeeadd7a743ad65a50fe854d7b558990d88caaa2a8ab09b07049d09012afb31d0ff976e745a1ba27500820d92d6fca5b13db5ff96b13f51905046a4d6a1a47fd53ccec8fe0ec67794aea9e3cd392a49b88e7d4ebc6b7d65c7d59842ad93ee1a54e63c5a0df0e01a692bb464e57f6bdbffb30901ee19685744894fdc7f1f2f607e43fa01753c2204690dee07620a2900bffa7fc3312ff8017186165abc764a218ac3636196d9cf8d989974df3f0aa8b4fc13a2252810e20caa0d35312ff9017186226275857c0de7cc3bf2c0006472738b883e0829a6e5637f90a80ba4ddcfa0973f09016248f1313c0bcd995cb8c908eca722a4cdcd3c5f48a6c6db02fe2cb03a3a81e9a165477af971c552412773320c4c567228176872b3328334eab1e5acaedcc39e3f8e5dc1d57e1d9822c549b057678f25cce7fa5fefa17163d25153fe1b2f6f994e0f5fb2d47a84df264f26e63210489eeb2f2a274f2a82f8c61aaac5dd3ba8244d1b90fd32f45fee5310090151810e421c5111fda876cece5c9056080dd972a726a1e4428ab391a8618337020a0181399ee467cf03c8cd376963f8607f6e276a92dd89b19201f2137b4179f5bfaf210171861360ba191ef16d883d699184a191dbf55c7408c1b2f7bcfa70bb1a0a9d4c2de2094101b9eafba6c4c718db591fe422c98b3d9eaab1212c4217d10b7bfa96619c2a30c94f02c3931346ad190736b0fab0139776905c15dbdeeba04817991ad158e3cb31861b82a709ff11224f2415190738f5088b1bc394fb62a4a22daf0dfc14900023e60ec6d4cd59dc14959dd0a57f0d9e1907383578bbe26d685cdd03317abea7e600424a52b0593c10dea4270f7bc57f80bb8825097be8fbcb15cacd4bad0b7e6ab7091480ff8a8e566b9f33f13a09377d12e50a69c3190739b50ff653f4135296911a4f49f84aca85a6c002906ef30b7ee66193a515d32bbf51190765a2fa57d4d6e2f5ae8d1802033116982745fd5e1c51a08b0fe48b1277fac114a4d81909b5bcfe5ac6a61e70b02e52f8be996f9e3e7909aaa27a95efdfa5b528c8c433cf5dba1909130cb5d61b3701314843fc1f3cf26e69dfe568683bf5300908bdaa41da1deba8a5e9111f2dc5150b02810c8f02faceef1a14eaeb104c0864a565534f17a5152ef9eb82dd72116c06808f9ca701e7b88decec88ea71710cde44a2b0496fb2ca008a17da43138b1a3911054f269485e4113f0bc54e4ed3962928dea4ed30dc6e6acb1d28f318a696286a31610a01e98bcf7c91021dec06def30d4da8391f52e36ee64adfabfaebb0f4e31a7d01f7111f24432c1c9a293bb476887074caee2e22a5bc98b2858d6b9412dc667d6d0df38acea1d948da7ba45ba8d119a64e5498b247feaebd8b739b8f0070e47f6cb2d361a6ae2e89f0aaf5de3a5b29947bc280675ceb680c6ec2311af0017186401cd861d51220a7f456584ea2fb9f6001d2ea4c0aff83f825deb6c6de173afeed3904325b0881a86bac268ec7a39f04bd59bfeebad1668b7be705b8e278da30a00a393b6eb780edda79c097ce7bc90715b34b9f10000000001e61955552a75fd44eb3bc8a520617e7626f867c9784b0934d33df13fb0248fb79c097ce7bc90715b34b9f10000000009175577d243744580e4d3eba6d001ae4a52ecf41915633aaefaec812c0b255bc0a016da4f25e21ea9a9da707266a06a38385e4f45a7521d930bf7ac684d28dfc860e090131a49c135824a04a04360f4ecbc6867c746f5ccc530ccb0102622dd71f56c56109013e4006101e0fde5109283e76e0abb0a6496f75a63c979ef7bfe90c55a20c8c8831047cae0f1089b2c416fc546ac82f94a49374c48a6ed2011ad43b0c71cecd92f8990edb9a2db4090175505f6b9b08556a1e16c1c50dbb8c161c3abac8f3f50613e08d71037e0ec6d74170f5f9d3e35fef0d2fba6acb46454534d4fcf1d2027bd50dc1ff77ea016718c670d3def0da26a2a44170f5f9d3e35fef0d0ebfaff93008adcb69843ec9881d6b2e2bcccc3aa4b30bee9ade9a0221fcddc60a011cacced5b6f672ebeeb7e99dd69158424e69b24fa9075218dc525b51fa4c99d029d1adada9f99f1e7b9405b6770849049e59e363dedfa1a73f467405a64edd954f4f0709e6880901d6bc4f049abf9c4b0c663c1f137c302ded9772d4f923840246a2b5c0db47177e0901257acae0efe704629e1552412a67ef32106bf2191fb3dfef4bfeb844d40cc503090117391cd68366e6f2eefeec472aea267d5ed97727327927739f800b924f5d0f5d09016669faf6484b99ccf6b8de37b06ba36ced8277d91d45ddb18926ceb91bad8c700901ad8ec34ec3708e06a44070e9f8f0697fd925fc70d8115fd03b2767c5b02562260901940fea0027879592e27dbd46f7ce4c6c799e2f04415645566c340c0d318ffdbf09013b1d910ca21f4561e426cd233ad98c9a2925154a77cebf3bc5d6847a3d91075b090167b6c29087dac56105580e5f677e349bb179da137ece1d2430fd75ebdc1b22d509010b32db0729a5182cb3ad4f86f2328502c7db024a3656a057b33153f096e6b74f09014835b724a8d30ad18af48320980d1ff38ddc9b3fbdee2a6ac7f9211d9b05631f0901b10ef22029d3990a5edc1775a038412559a0b8194d37476656809d5c84f387eb09016278d477fe67124d3d3aeb8c2f5d726e6cd285bd543a5f827d33c759335b55100901a70ebe30bcfec080f540e96cd54c2b49c7aa18bf7b771b6168582113804bae300901dee3974538ddc7a0866fe26c52a389cc4c96767e5c09d3917ea04bb3395f7c2109014a4d16024ab61163e4442862311bd0fe61b720678d02e03e095437404b4b03e75979861e6a2dad8a248b8c0ea6150af75e4e48b97c1882bcea43aca1b01662ba932e546fe7d5ade1b949871e090190869960b5bd7dcfcf9447b302cd99aee59d882710ef2a0a1299920f7f7c685d09015d6c16992385cb5d833df31f4090ee6825b2c8701f92ce0477b63ce12b75b862005261657374726f0000000000000000000000000000000000000000000000000e46f3883d5c3a2477bda1bbfb8924fc5ecd14869c2d2fc38500a2faba696c14c000a8f6616edf999f5ce01f1fe1b894a726336cb13115a59043494944a072f579a4d1e7217d66d3d43fab8faba493feb42965e80cad570bb29988aab46c3b6153cb00c89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6f47586930205713a6a363a9d06c15d0db51436ec49fd51b8de8900ae32c2b96c096f0d5c261ad9aff66480c7b22a49e9c185589b67131e8e1099d86a3536086637cfa17816a972b63d0679c935879cfaeb6453c7c1c8c9e853ece842d12de2a0d1b7dfde9c9617fba97871e6a3cdc0a9f60f66e0c6c0f1a17816a972b63d0679c935879cfaeb6453c7c1c8c902e961595aeb5c304f2849d4c1a759413a26d8c473fe769319a18e319ace9d3a09026e708a3dc48ed3b38f705bae99f8fef0f0c4881cc5e96537f32f6d703106b50c09016fe4a5488c3854e373bdba93eb4552bfb427e6951995bd65b2c3a55b156d23b6090292e278a79d3343959e9f5c390277e32d556e615e476cf0a108f9b4524688ac47a156abb6a3f25dccdada106191053b1cc54c196deec8507d19a898613091d6415824a6244a7ba6212ee76a9d0a7c6c904a82f3e01b09015aaf9b799076012479363653434fa93b89f2822dd6150e4b56377b207f26fbbc0901f826346b5d717de99d1774a11e6b897315c60845807efda369ac20905b3f64e009012ed7a51071d0844752958bd1d67971666340bab5f8fd15c2d471a0fde4506147a17816a972b63d0679c935879cfaeb6453c7c1c8c9677f8ff1a98b7c11868d0408a7f9ba3d523562b858d34affa57ace4e74caf269a17816a972b63d0679c935879cfaeb6453c7c1c8c9d7219df5808c4bc0854d28b38fb26bbded52e00a9ba02dd85ef8285e6d0c6971a17816a972b63d0679c935879cfaeb6453c7c1c8c91749e7427159f18bb6e298b10b3679b956f41187a25bbcdc4b9b0daee8e3444c00697066733a2f2f516d556a6554533668747756766b51766d6463556372786165f0682fef72a02e4f48fea058e5bd83e1c82630d0db2348003a7514d343b80a61006f665178793452326e636d566f37476f436a666d482f30000000000000000000b589cd787e4d0d1d47e6b6dc38a21581d7a2d99c0a2a61a4db2b0b836149ff04090123f933b221f2747e4f696debdecc366a1de91271d188a260a8215ef3092186cd0901460aedc9249b63a4a2971178bafff352020838fa1fb066b099ddef723a32d3e509012cfec83d80457e553b6c58f546dd5015923eb928e9e020bc002703a6c47129b50901ae2f0a3b41bb84ac766d32c6615da315c2323727e715c6ca7eaf356d3da269c109013295ce215f546349bf345f5f7f8406a76b4a37c24167ba851c5cf449de84b6a03904a4a455de4348ba4bd574f6eaa9f4908c97ddd69ae4939bbbcc78db3a6d2589821800363d06ba21042aa1e8dac60805d1eb0ec310bbb4aa02e9c61feaf4a8879215462a9719f06e271c8d04210182219e1d25a204efca6d46244cce7ad7d2ef46033c6ba0583cf38098dbec0b21040fdd2165a6de4dc6ebcd94d5b43f27e0ec3962ac378a92c79cab9df11395fa083c1d3277c3be9c5922c2c22b62ce831b53bc81395387a23aea94411ae8d026836e206a43364996812a9d53eba32a5b22729ca729227610346e5dbad9b528bf307acda1e21df661b94eef1a5405710aadaf463ecfc73ee1496e0901f10404afee7818eb073f32117a11d500a20c73c046a0e27b52f453bf11beaa46a1a47fd53ccec8fe0ec67794aea9e3cd392a49b88e2109690fd4953c3057fb56444aeba5a904b21a5215cf37c4af87636f187b2b38a178bfec5e4693aee12dedff44f40e5ccce66ddb1c7b9fca3d919f48037bd36a73eee0c506d169bc80a4875fac3ffa2e9d38c491db0901cbac5c7603ae0a7ff05beac2bc7946663fcf627d46749c9a61436fae633ac0520901df0ee468c7b9b9c10d8b28697256da3a2a13433ca96e9d30f22ad3495553b1d2a144ef12d4b87c5646869b28e6b62e8aca975afdfaa29734b9b4680e31e370be9fc36c9b54e6523c48935f7740c3108bc03319ecad296c01718640d645e474f86fe66f2c63f0857e0aff27fb4ce12f94d4fcf320ef56a21720d163090190b19c1f41dddb2f54d53ad0d8f961ec9a866c37b50141da2932ef7f3eedf69f59524d10dbc0a39e7cea39c8626163e80cc225e64719f6c5b9404107acd41f117f495f1157516b47e17a4b8b2165a6de2b483b68e50ca45c31cb92e1d43b79be414335d8e3ae2d72889153d9bd4fdf0b6a31048c2739500077c1fab877047b94ce5b6df69d1a164a0f1164ef29985f833c0b27a6a64747ca2165a6de2b8c838f415041162cdf3cbc028978669046f32675466b835a337dd17b26c742400901313603fbaafd9b9dc2ee76867de15c515ba8a3ddac50b606c0dfc9ef3e9bdb860a014be94257e76c4c0957240e07b32bf0a494b4e72b28ff32e6c51b5660e705ff99313b890171863f8296538c0df71d959117b23991ab81cbf8793b09a2818127cfcfa4826adb86e609015b05d98d465ff9fed32b201bcff0fbf6a2406f6c98dade1505a29b0be6d96630a17163d25153fe1b2f6f994e0f5fb2d47a84df264f0c66ab9e09010b2107ae09010019933f090108afd9f609010806212009010133ae7409010a1ecea20901068018cd09010c64307509010669606409010b2a8fa809010601f0e5090107b21d038901000000000000000000000000000000000677b0eb09010c41cf7909010b8e7b8009020c2c70740901095a7281090109fde82c0901056783de090100579c9a090106bfc71209010c377173090104f1c34c09010077ee580901007444c9090200e76a4a090100564914090106b5d97909010019a3de0901036d2629090208086c30090100041aab09020c67e2ee09020766c88a09030c6805f7093704faaceb090200462b3609010ba8f6710901058faec509010b533a5a09010b6f0909090109f8fa190901056d73660901073f475b0901072886a6090101b8cf1009010264c0440901000290b409020c6709578901000000000000000000000000000000010c09638309010bfeba32090101309dd909010a0b6b9d09010c6808ea09320638faec090106106b0c09010a3b7c1d0901056d5fe9090105ddeaff09010071973209010a17304c0901019ca8c809020b61f03b090100676af40928001478ee09010bd9a6fe09020005e4d3090100327de70901008c6dcb0901004dcf1609010b07c96009020669c2f5090106706ac809010bdbbe9809010561870b0902003bae2609020c68079e0901034021c009010660d93d0901066f19390901032648dd09010aed18af09020a400f7e09030115cc6f090105d6ead3090100e5558109010660ef780901031ded4909010c67fddd09010520bbea09010c67de0c0902086ab54c09010589a7860901070e5651090106eb4b2f090109f9d2270903006593160901001109cd090109efaa8709030b209e2a090203189bd109010c67df880901000a2b32090105fd971c090202009826090100445cd0090109cd4b3a090701c197c909010b4076e1090100053ca909010c6807a009350bd9a3d4090109f07b6e090104d18eb709020491c84209010ba9972c09010b2b2f0509010ad6dcd2090100414751090202ea1dd1090107582da309010c67e4750901074faf5409010b4085a509010bda074b0901029b6ff909010b4bc7a209010b0033660901002a5be50903015e042409010b55111609010775e475090105b091920902002bf77a09010b8f00c709010289e0f509010b39f2b60901060b2d8c0901001d996c090205fcd07f09010046488189010000000000000000000000000000000006aa50d5090107cbf6970901000d9d7209020bd9be60090104e9bb72090106103a1e09010c67db19090302a8b08f0901032bfecc090109cd026a09010c54a109090109c2026209010c22df910902001831a1090205d2c8d50902002689ca0901091fb83c09020567809609010bdde3c709010c677e4609020017b82009010b2ab89909020bcff27209010173ca720901000fa0e2090101ad82dd09010bb3da6a090205a70bb509010b85934209010272cdba0901000e553909010ba8ff2e09010c680481090103fdd1b809020c526e49090107a89cdf09010b096577090109f9c5a409010829ef7b0901002556e6090100079f640901035440a4090107b21d06090205e37a1509010a16ca5c090205f310ae09010ae53901090101af593509010978121d090104eb6451090104f7d30a09060bee7558090100001fa30906060fe9e3090109daec820901023cd82409010010500f090100dc86c10901000f844b09020aff4bb109010afc8d38090100107676090106c0b79e0901089c8bd20901057da16109030a1625f009020233cff309010c614251090103e73810090109d4f6ab0901051778c409010b409e5909010610117c09010389a099090201d1637509010329bc3c090105554ea009010055bdda09020035758e09020c59cfd9090109765dcf09010b77065509010304597e09010693d5ff0902060f661209010c096e9e0901074cc6920901041362c609010c5efeec09010684f20309010bc4c98d09010bc4ebb80901056789be0901031fe67009030b5b499309010a0f25fb090106c0bdf809010ad6158c0901001d5ebe09010b258a7c0902003b5382090103266c4609010b8566d60901099c928e090109f4640f09010ae5292c09010005acd009010860ce950901070e64fc09010033df33090200c29fd20905002745410901065e5d7e09010008644509010bf29a71090300d25ae8090201a1100b09010ae0313d09010a6bd8f409010019f998090109e092b6090106b441fd09010326a3130901005b30060902000003f00901064f91be090101e5a8b2090200001fa4090309a108fa09020c6143f90902049bdf030901002f54ff09010be5f3cf09010643c35a0901009894240902063fcff80902087713c309020b7e71680901001bbbd709010babfa4109010bd0d3a5090109a178db09010017e472090208f489a9090105ce03f8090106eba5b5090100782698090100657ec7090109d42ca6090105e80d1609010b8d46f109010b185fb9090100014ed609010401a1ea090102bf6e1109010848de0e090102f7ea4c09020000f821090105d9f3040901018116d109020ab7244f090109eaed9a09010554bf0b09010c680484091a02a1a2970903012b60e609010a293b5c09010c67d77709020c67f3920903009d1c46090a031392fe0901000429de090107f0739509020c6808ed0931025b4ca309020babde7109010bcff83f090105677ed109010009588509010c67ed1009020a69dc670901036517b009010c67de1209020bd007bb0901088ae94b09060b197ff009010577ab5d0901006b80db090205677ed209010bc7af2509010b500dfa0901018b7176090a0b0f7e6f09010401387209030961737509010c677e490901003ade5f0901000bfe3b0902000b78130901065d17b70901003e69fc09010644dfe30901079dfad70902086ac190090106339b8309010c22f90d090104ec10ea090101c9dfd309010b8d5da709010a2a8e080901003bcb22090400111b3a09010201bd1509010445f9f909040bdb22f6090109310235090103f4df31090105e81baa09010a22e6aa090101af525b09020c1522d4090201f129b30901054756db09010b6f9eaf090100fb09e609020c644564090105678be709010a0502ef09010182b94f09010a6cb63909010c51c6bb0901021f4d3109020c2258a50901008abfcf09010124ab40090109eb2a2f090204ebff3609020b106d04090103a75f4c090109ff727f09010b2b256109010b61acce09010339be860901001fb231090105073d650901090adb6f090109a4f89009010b55e934090105e73d080901005ea21b090109f5f78b0901008b4e4509010567820b0901070e69cc09010c6809ff092f0b8f6b4609020b32ace109010207a1f8090104b4d5ac0902001eb0a2090100146b92090600f0a9c709020c6807a709360c15164e09020000b20f0901003575a5092503fcee1e09010a4127e4090100c6a402090205b0a97f09010064f1a4090205678dc909010069334a09020b955573090109fe7a6909010b2a989c09010687a8e7090107a09c9409010a81c1d509010a5a33bf09010c66bb1209010a32db290901003515870901055f03770901019cd93c090101571730090105678f7d090109cdb2160901000923c8090100e7171f09010030f41609010b17c7d90901054dd2df0905048d7abc090101538ff7090103ff66e709010938ea8309010000002f4201e5111d61f778000c515cc13278fc6fa250000b20d5853902c5a0525826eb00198ea73a01f04119e726ab07dbf5d1323eaf68e46f0008061fa53927c1250c1e32fe0133961d32287da4bef1000a1ecb9b3a06b5ec39cf3965067fea23323b13b95877000c617784322a4cf9fd2d0006625924322a9a3acf63000770e63e3ab017421402cff90b2648ac322811cbdfd90005bb81993a16345d84fd7ba006771350322811cbdfd9000c41cf8c322f58aca323000b8e6e9132d4e04b3c360007649f72391ef1b2e7fe60000c2c69cf3a0743da7c0b1c4708181dd232285e5fd7920009fde3c73914fcc59bb696ff056747893226fde45ecf00005797e4322a18d8824e0006bfae4732356b3cedf3000c376c6d322811cbdfd90004f0967732db65bc758c000073e7b6322f67162a2e0000743752329f7f3d0eb5cb00e75fc533216ac8e375c000561d0932f640e036610006b469933255aa0fed21000019a12d322f67162a2e00036d11ce3a0ec9c052e1baca0800f85c3278a1f544e2000003f9f9324df4f65319000c67df913251da5cb3af000b24ff1939354a6ba7a180020766b1ce3271823e01ea000c68011e3a343b838e24f88903a766c73a01435982a96300052e733531e35fa931a0000046273a322830402975000ba8d5df322f57dc0560000117fee83a0ec0fd33aa32000b44e366322a6c38eeab000b69876a32270b2fcbaa0009a5ad6b323c2d72f73b000556cf6a3a3830032768a0000bb23f913112309ce54000073a596532357a7712c10007287b3c328dd089866400085e6193312d79883d200001b8cbef3229770747e8000a419af53942af372e6f20010264acf732bc926e31bb0000028a8d324bf72208b0000c67077b3a03761b910ee9000c08b8b83917642f7a93e4bd0bfeb0de32c4e6e72ce00000b2c027316d23ad5f800001308cce39124b95997c0aea0957158f32285e5fd7920000903f65390793f3c34e50030c6806043a2f7a8b284b0d220638f2e0323b12d6d9110005d03aba3b37b810daa23fdc0a3b71f539019fdbc389019c056d601332bd2efc5b7f0005dc81003226e74eb8450000af040e390728a1bf38f000007195003b257c71d9d67eae0a16e2143a14f68cc320a078019c89ca3b9a6e7f18365f3902d458a031062f3f95a0000b1d051f32277d0a778400006765e13a26080a264e369000043a133a1b1e27620155000bd9a58732a7db68ec68000005d782322a4c295f6a000032762a322933aba83b00008c61a2322bc5115f26000c67d1c93a1eb22be53345000014300c3a07448a4b8298000b06031e39065bc1c2d7315e05d2adbc32270b2fcbaa0006604aae32b1fee9a95c000bd4cb403234cf082c5e000b951344315af3107a40000561873c33e7dc91cd9228003b993c324dc4ca1fa4000c6800363299e1cdd54f00033f6a0e3a056594fec7584a0b951582312d79883d20000646b60d3a06bb6eb3f15c15066f0be832356e4fb5f70002daf38c3a07231c46551a4a0aed136e3a0643f444b194a50a3fb741326aaf505b940000cdf3843a07cc564ee727180594fcb13a0139dcf5e45bdb0b2850a632b1912dfe130000e522fb326b804190e200065937073a0820accf6a500002b4820c3a2bd23a842363160c67fde23aa03a8b22428f5505209e92322e72af2b4d000c0b3a2e391572c8c51ff82e086a9b313a523ef0b8932d00058884be3a1772f6cb55239806c64f943226e74eb8450006d5dc133a063eae9072467b0c60b8d93903e28a86bcb55901665829390e3b276187c40009f9d0de3941b4e2f9cd009e00658ca03251b4632f30000c5268c73247fc441bc0000010fa7b322a6c38eeab0009d9f5e832715f4b59ad000246170c393822042b7380000ad0d95032f745047b660002da86213a052f09f7852cee0c06e26f3a1710a4c929f0940000214d412b85e64d385c77b30009694f32297636aa250005fd944a32b1d618f7a300020083183a08adfb6136a4b2003c28ac322a2f8bf63d0009cd3d6d3a0101033d331c0001bfacb0323744c4db25000b3f3b9c323d37e08f8e00000532c6322f67162a2e000c6800383a32558ca5c52da10bd9983332b2aa765d240009d628a0322d910c4ed200041209b03249a81d9a880000001cf609020491c5e1323efe56dded000b94ee213902f5d84a4647480ad6a75232fa28e81f6b2f003f05e13a02164b8d282d0002ea1de13236a0e12586000678bd583a04b4106596d6ce0c0e701b3a3cd5042bf7fb20074748003a0d0393910a8a450b9bb088312385416c274a0b40549b3901a305729a68dc0bd9f8c63a02fb5d0e94eb76029b6d39323df73d9e49000b2daa043a13d3fc726a7b3f0af9e1273235e3ae6988000029fa563a02e02b74baa996015dd46f32fa29b8bd2e2f0b5506b63a2421dfc3d1f5eb075444923a037a2968c32800056d1af032e702fbc5e0000055ca393917968e9bddd0080001fea83228203566e4000b8ef68e322f57dc0560000288da51322810fb4216000b39f2c1322701a401500003b7a7853a0d39d8902fa80000066915324dad8d947e0005ba36213a21fb6c3f63a66905c643581102d106aa20eb32407fe232bc0007cb5f9b32c46d7b5a6100000d9aff324da9c2063b000bd9a3e232278e0f90ff000405f1f139037803638fd62f04e946b03a01df501fc3960005d038d13b30f58adea393940c08153e32e5bf87528b7402a7fb26322770127cf70002dc122c3154536ec440f409ccf4583908d0533492945d0c526ac03a01b09b3908ad0009c1f0063934320e8087ff610c1b5e6732f8cf62d450000017e9004101633f21bfaab53405d2c72d32993ddafd1740002678f932271d64e0f800091ba0e4324753be443a000567478e3226fde45ecf000bdddebe3235ada42c9700034a6a64410122129a8a42fe000c1ad0a93946b350891e1386000b1a62410dca9095f543bb890700171f316d23ad5f80000b2ab8a532d9bae8b7d8fe0bcfaee7322f57dc0560000173c42c322f57dc056000000f87383a4763879fd9270001ad5872322a6b6850e8000b31a6333261c4c82ee20005a709c532d114f29e1f00062bb81f32323f7f4bc3000272cc643a04142a767bc011000e503a32356a6c5030000ba8faf6322f58aca323000c68031332ce2977ddb70003e179023a01ea112ef75f5e0c5245b231651e854f700007a7e510327e36e2e51e000badd1c5312d79883d20000b0948c6390e232b7f90b18009f9c0cd3901c981369935a8081d25853a02db4480c5136700250cda328b033b890c000007995632cb246690640002695eb43903ca5465a9e85207ac1aa83a02748344f70b0005e31241322811cbdfd9000a16ba0a324db2e87ca40005f24566322fa33a0b65000a3f3374322add966f10000b8f8651312d79883d200001add144322a5c3421fb000918ccfc3952be7de57809690420d23532270e12e4a60004f7d31d3a01e3662d9197400bee5edb32942c4198ba0000001fa5421fb4f598aec9fbc305d034883b365663bb27bda109dadcc339023b57fab9abc8023b72b7322810fb42160000104d7f322a5b6384380000dc837b32356a6c50300006316c8839237dda214e6008000f702d411c85284fd99258aa0c680a013a1ca575c01115000aff423f3913d173da3cb9ee0afc54c5390a1dd6054868b0001076af322a5b6384380006c0a59e322add966f100007f36510322811cbdfd9000559058d3a0105044d7b72be09e8400c3148c2739500000a15e993390adb2d23d4f1c90053bb7a3229606bab7d000c5dd2f5390496452197357c03e732933231bf70bdc70009d4d8633911a601d552c7be0516fe1e3b2a4015f26990c60b4081df3a47fd952fef7c2f05d036aa3b34c1a6c9bb52fd037490e132b4faaac71f000134ba45322c199bd1750002dbe764328cd77d63f5f105552739322f58aca323000024b54e3a12c21704b811000000f5d1324db205fd3e000c59c9583a23f10a92d0d7000c6803153a2223f0aad3b31f06648fde4102fac121da0b06510b76f9c23a1bd716e4db0900030430af322a5b6384380005d030ba3b2e3fba4a4bd9e30c096cf132356a6c50300006b079ee32270498fbef00041358f5322830402975000c5efd2639dd8b4acbc77a1805be472632270b715c550000002a3b39c060f02190c8000bc4c5d232942b70faf7000bc49f86322810fb421600056749353226fde45ecf00003921e44102ac9ba10837c000031fb92f32718ce7e674000b5b327c3a01a5b28f1525000a0f1880326c95ac800d0006c09a98322add966f10000ad48e973a0d0f9cbaa2203a095834d5411f2178e1a8ab7001001d574f32356a6c5030000b257bc13912ed745f2db6c6003b539b31940307c2800002dbc10f3a03f7f77b2d9cff0b85453e32fa29b8bd2e3b0992c0663b1d0f4231a8990009f462983297ff1385f2000ae4da1a390468b4d98d051c0000745f3229460a76b00008115b7b3a47d8712a5b7f0007014da33226e74eb8450002d9a53e310a1443614f4005413e8f31246139ca80000025e081324df425b5560000c2964632b33c07301000002728623274f1bc97b80006293bac32270b2fcbaa00000861c0322a4cf9fd2d000bf24cd1327160dab3900000c2f2c63a12b83a3fdf3b0001a10d4d39d88c554f4c22000adfd56839042a69f4f3fba00a64d62a322a5c3421fb0000196c88322e90a053930009dc4dea3a0f35b653d0b87406b43e2532357a7712c10002db8b1d3a052baa2d561de20a4c1bcb312d79883d2000005b2e2539333fab2c9c7c6c0000028e328401ab13430005b3148f3a0ce50f476c3e260c355294390a9f639fe0e00101e5a2bf324daf8242520000001e0b41019cef1dba180e34028ed6a039018a0c4092045c099996f53a037afa87bdd0ce0c5dd4fb390333d8242113d502b6623b3232e663e7c300002f4d7f32a857c9b986000be5f07e322be432833f00051223573235b6418bc900009894523a01191a09bdfa00063fbd9f3a012e2a4d79260008771082391179237adc68440b7e6ca93269d57a4088000c515cd039153b43d630197b001ad4053228210604a7000b94459d3229561b2f22000bd0c4be32b911de96b000096b03c632277d0a7784000017e2893273362bc8ad000a4b3fbb312d79883d200004461c2231f5904616e000070017223901ce692d85d0ef08f47ffe322a08981ad40005cc9a453a054440fd31100006eb2c8b3a23d6a64b3bd30000781b5b3a0bdb2f3e28709b00657a0d322967cd231a0009d4263c322f67162a2e0005e7fbfe3a45aeba54a0a7000b85f152322b176c3a44000b1856dd3a21c930528009ac00014c3d4107f67b64c9c589c50401050032abab044e560002bf5a793a0b2f4987b940000820a29032270498fbef0002f7e7c439226a8e88a3cc460000f5e03a2402e3036eac0005d9ce71322ced9fcec700017fe73f411a60757d070cf2000ab2c07232356b3cedf30009eaec2c3902a8c3eef4bdf10536bab93b0bb897ffdea5290c6802073a18b53e98fae366011911c73269bcd814a600011eabad322810fb4216000a291784390398664f09f3a70bfefcb63a02ba5971f628d600b1e4593910bb4b0ad579260c67ee413a023175f84aaf00009d197a3a0985cb050e8a7602c0dea33242a4c825f3000003ff353229770747e8000b1fffae3a04ccd605d8bb0007f05a5b3a0149cead855e000c6803193a2e8727771b48ff0a6de00d312d79883d200001f8aefb326ac4fd8cd7000babb53239bea2a1819f49e20bcfaeef322f57dc056000056745ac3226fde45ecf000009413d322a5b638438000c0e77ca3a3e9c85ae3d7ea606f90fb43118a5981233000a5caff431766e2fc0f63402ce87dc3a14ae70a14d97000c01a96d39122116f028465a0bcfaef2322f57dc056000088ae0f032dc59a05317000b19584b3a172396df85cd780544f49932270b2fcbaa00006b60b33a012db205b6b800056745ad3227b12bf263000b5d01403a075ec9e69360a30b4fface32372b4625be0000f97b5f4207212ca7732656000b0f10aa3905907cb88de7b40400b0ad3271e1f57a1900095fdb52323513db4e6a000c1afa8f393f9808a3ac5731003ada48322f57dc05600000004065422a566631615bb5b800004440324c2a9c9ef300000b6e9c322c91ef7fa50004f62d423944d0e9914ca00406589ac2324a872ada7400003bec053a044295fed86f030644d56432356a6c503000079d46e43b09e6cb6ea4eff2086aa23c3a2af736c9560500063336033a08ba03e4cd19000c22a54d322811cbdfd90003b30853322d858bd6a40001c9c26a322a5b638438000b8d5454322a4cf9fd2d000a2a713532b5f4a848f00000204dbe32912d43f9cc0009e8ae443148c27395000009e8e55c3148c273950000001113e9322b8da1817900018197123a04d45bf4dc3ccc06da451e31020a1f6a7900034a9b4d3a098577d4ae7c000bdb20ed39a5c06a979d684101572437410140500ad528f01f02a835dc322966fc85570003f3970d3241127f3e350005e804de323b2b84f0b5000a22632a3a070aeb2b01585705e8cc8a391930514375200001add14c324df5c6f0dc000c15185432495f5531120001f11b9342018e78b1397ed9000a60083439012d908be563250545776439277c14d8cc4f7c0b358554390843669f6bb4e100fb054b324bfe9b57d10006e346b04104dca0ca6af1c8c50567493a3226fde45ecf000891af2732285f3075550001828d41322fbe7dbf9800092dea034103810f6985c940000a66ea4f32b4e297a855000c517d543259f4be52f500020717fc3a0cc93f03899a000c672eca3358e0ba35b3000c2258b5322811cbdfd90000131b163a06bdd7efdb2a0008127dca313691d6afc0000124a56e322ac972a1cf0009eb1fb43a0159195a41640003b356533266b5a26a77000b103ee939064fe25927e76f039acc16322701a401500006107c5b310345b9830c0009fed9d7323a40f7389b000b61a0ae322beadb349d0002be170b39083b2ffef84aeb0ba7419d3a0e35fa931a0000001f7926329d5411b6b40004a3dbe83b1e7053e20c7ba508feed23324ba179dcbe15099d6cf53a01e664745bc5020b55d8d0323c28f4989a00059174363b072f2bcf9e07bb005e825832285f3075550009f5e22432c17732f229000057c1e2323ba81b62bc000bf6e3fc312d79883d2000056747933226fde45ecf0007016e073226e74eb845000c6804913a2ca0e536ab5d910b8f6b563a039bbf383c98dd0b32ab86322beadb349d000207a211322f7720ecbf0004b4a830390149c21822556400011e7732357a7712c1000013e14732dccdbd29320000eda10c392ea24f4ea033780c68020b3a3348659e826a4a0c14ddc033ed1b17a818340000721f3229596991f000003558e23a04c43bf509890003da1243391069d0b428cac30a410b2139027cae0e8d70d5000dbfc53a05b7b60044e80005aefea23226e74eb84500006145fa32bb77a26489000567493c3226fde45ecf0000233c193904bb4ee9020ecf0c51976739012f0b2ba3a0000b90564932dc877e70890009fe54073902114e1a1519300b2a91993a0104ae509d09000687a60e32d41d81fd4800078f11223251b4632f30000c67d1d73a1e66a2ba70a8000c5268cd3a13a79dca1b67000a78f227390b3c83fe966f7c0a59c3d0322685433432000c66bb1d3ab9fb739325a5000a326b7132730570882000003499fc32ac97e6125400055d1385322f67e6c7f100019ccdb439d88c554f4c2200015704ba322a6b6850e80005674b133226fde45ecf0009cd90283902f25cac4379e4000913ab327db8ecc83c0000e6ba96322a6c38eeab00002ff8bd3ac38f22a3e60a0c0b17a27e3901af152105307305488c9c32f1e2a3064500048d38093a025f94052c290000c52e4a32b433aab01c0003b031e93b0ba92c6de0f24c093898c9323b9b11868c000597bbcf42397f022f767c7a7c0000002489010000000000000000000000000000004d070a5197895200000000000000000000000000000054070a5bd9006d6ddd63ddd4a2157b38227c662e6d7952854772e2f3579dfb6bbe6a81973055070a5bda000709fab9fd95a8a0c200e329921b1b8d6800f788144e4daa7e50acde6057fc94070a5bdb008ffe7c315ac533335a182ac2b299acffe92810b4d5a6f3392b44c18bbac8e384070a5bdc0000f66c0a665811bd0cc14d319339151f8f59ef9ce4205ce2da326a8fbcde8512070a5bdd009fed2925bae3fdcc8e876587ae7d84a49bb7b05a241c01ca8c641ccb28e27fa1070a5bde0056a07be9babf358e6939609d16bdaaf25d0d7d5ece9e955b7e61e0fcbbc512a3070a5bdf0009900c19f7270a23399e2a1cd7a18623ba071b7d024853be75ac912159ebf289070a5be000bd852a8b80acd256fd209287595c4a4b487c82d16bac6a306b9ade6148f8ffcc070a5be1009982bf903474e958933dada56128d7003252a71340d03bd2a93baa1f47f7f4cb070a5be200377be92ff2e22a80607b9682548b57db6a1ff7b4e853f81d79b1e06a8464fc97070a5be30061bd1f1b93743d45db854d7f211309f3eff323ee728152b1b97d956f2c4d3823070a5be4009290725faece0b8804c81b21f62a92b06acf54e28ffe8bdf870aa2ddb7e09130070a5be500697b1c38d6b9582d41b8adf4a41a0ff6c20e15bc81c3899db7a61cc594f448f6070a5be6002efa65cb2ac822400156a605ab9a435e1d3d278e825efa3f2435cfdf652bedf5070a5be700c162bcb089f06c0cfc7f00e2e4863e2badd3e086db45acf08b852b4e5916208f070a5be800d8839e92cd3f6b32e5db6dc273e928e88c3fa42e6aaf46d0798640745bda4712070a5be90074e96903c0088ba0a33ba5f1f3b0df345dcbf84d5a1ab344b56961964430218f070a5bea000f4ffcffbdcf3ede64895966ff0004b664165bbe0c5ac5877fa9a2004cf4e991070a5beb00f9226300947636f58fbbfcc0b2ea48fe6b8926a42fad01ad8bf17222532377b3070a5bec00144e5d780f5e8e63ab026594b2b646aaf4331c29c2aa3a98a8b2a2232586bbf9070a5bed0042c638e91fae55af2f7162c90be63d81e7d2a8d0c9c9b0e188566b1ef0f6d801070a5bee00f856242dda26db04d3bde02025e471aad0ddd5e990d3e0d56f0e963503c03ac4070a5bef005b5ecbc123ea027d3fd8fe859b92ea983a6bb09d02926cbced73163d353188b6070a5bf000c3574ca2d0b213f6580d8f2a4db53f9cf00cf62bc1cbf37bb5ee4aee314f7fb5070a5bf100baa903bbb707977a5dd902a116c217f00a5f5a3ebb4054c9b5912274d5d1e3b4070a5bf20013c90febf653fb0348d9699ddd7d8947d59ddb1bbc32035985a47cbb24a2be60070a5d68007ac4b937f9565187f243c181707b57a59fd1f5f39987b15b33419a63ca72da01070a5d690072d1ade4dba274d2e1ad9455a658036f58bb8e6949f61b8e20420ec2e9d61ec2070a5d6a007188ebb23df5cdde059cc951110a7f73d528063c1605776c43b0eb5770d32928070a5d6b007c0fdbe358890e7bbabd96af73caed7804a97cba21783a050b88674cbb567a65070a5d6c006b4c52b358482aecc9d32e881bc54015fdf330b2c8e9dc2eec54074d684dd39d070a5d6d00b94b9d12fd4bcb411a316ffe858dd56ac6911d118663cc99fb84eafdf7095937070a5d6e00f1c1ccb97fc759e38fa46bed43b4f3be2f317cc73ede6e3143f23eb853e06b7e070a5d6f00e13d13242407f1de4f35d773c34319ff16b3689e44ceed365f6cd63680c3d030070a5d70008c29eb8041bc65d83ab58c2da3211baf91181436a3b63841ad747622faad981f070a5d710090303b47416508494b02ef5bc09d8c5ebd82aeb714ab5dbdb5d3ec2daa8ee5a9070a5d720031cc2923a8c7151887f9ba4ecf0200e239f34e1069e9f965997ddf0cb53b5d22070a5d7300f91229b9061141167361f7434fd4b72bf0d3e96e780c07a772f229e8b92ebf3a070a5d74006b4df17ac3c6cf19bd6c9629fbf2da722dc1170911a1773e6e7893135064f1c9070a5d750097ca97d150a2073e39dc94f8b0d9a9a6f88420fb532854aca77603f1675f37eb070a5d76008582c2e971c1b4a19f2f3fd9c3f4a89e36894a60abae8c4c8b2522027cb15338070a5d7700dcb00fc263f4cc921eee1c92673d6eea3d0b2ef62973104e5e8578ff34684204070a5d78009246e2bfeaa6057a6094f47c3fb865dae8b3c37a14580fcd3b1077175be4052d070a5d79003365ee5d0809baa3b40b430e00295269ac70b3d8a7cf9a7e1495ab27bf27b3c4070a5d7a00c458c29d92e8a8f8794f6feb4cec8fa54472c8b3c3a3a3a3a25ff76f657a08c1070a5d7b00ee18964a3e32fa71b872c951d43e130de1401309ce478cc0b5de678fbaac113e070a5d7c00c90a52fbf38019fafbac330dc28cea28f37ff93d139af7db00f9437ad1c0b042070a5d7d00fafa57de19eba9f28dd376ca2a6536fd93e85c7d833340801e060b5d68959def070a5d7e007069c6eb8fb74dc61c32f9a7a4ee845ea4d2ffd3e64d411e3bd60b72cead5e37070a5d7f00022beaa918accdae2feec5f9237a2ee83d4b82f265ce10a24d772774a1a42400070a5d800062a78e575d55449a5c44085e8d183504e8423d19c22de694a52e50bc5bb1b082070a5d81008cbd7b1bf67f3d8bec0a0414099c3121ec834fc71571065f15eae86df2650ffa070a5f4600d4850de787c7f43b65848bd2704a33411ddaac19bbe343c76f36fbb226c09f7c070a5f47008bd4f9a36128af6473be2cc7f3e6185df45d207b9eb375c4b3896769bb7d9395070a5f4800f8f2044fea300a28e9baf449e9908308b7cf41cc3c94207c7c2cddbd80694a21070a5f490095956db16a70150ea5cc2dce87bcb0bd142a8de3ab43b76e1be7d05b6be6ea09070a5f4a00023c43e4072d5232341c2f8f7105118e040f75b94e8d8514d1897c0d4cf8f374070a5f4b00cb2355cd0e3da87b2fca7f1e10bf45ea7ff04b6823728cfbf3ef28ed50b1b9ea070a5f4c00d0766acdca630024fd9e93dc0faff11e4088f53382b9ab594a3e0216fcf8dcf6070a5f4d00d4af8767239c07c84c2d913447ffbbdd2eb208a6442e2b73b1479ef8052f1c10070a5f4e001031fc14a65bffde9d99bd4217249e0702e3c1292a363dfef4d0df3c87f646c9070a519800040dfcda364264a10250a8351d85760e5f1c792e1b9db6bc5bd1de2942992163070a51990010a917a1b1b18c06b4185c56a71d7324185a40157e4946c2a220c1b8cc6b8125070a519a009143965d07019d59398f22ebc20bd7ec5ec20ce33528047b5f786329a4d37a16070a519b006c01d762f30c93b4c3013d4ecf8a9949439a474ccfe9fa2ff1355ca2abf0a303070a519c00d96f7c034e15beac5793b085f44ef0651af9a93a000a7a4b76b41b951836d264070a519d002b08d63b52cfb758f53ec40ed6b8336fec91385f9314120a481870e9ecb29ea4070a519e0082c62bde8e27cb11b1830685f112856273ecee17840f761b3c1f8d999d49d6ca070a519f00e18edf2dbd13501903870e36b56b5a567aab1cd0cef198c4fba92c2c834c4641070a51a000ec127887571a1cbed8589954e486bafced260a12cc4d64270eedbebc8bb3ad5a070a51a100007808b24cfac2044ffcedf329826092efb7dad9071a3386e34667a8c6e207a9070a51a200ecc041d8572ec21390650cd1cac935a8de9b47e24097071cd8d867f1cbe5db6f070a51a300584739c60fe19e4be6127ae4241430e63758e1b8dd181be3ec1127561e5deeaf070a51a400561f4aaa956190fe717f30152dea97e9a79ccd8f8c5b2641e36bc5abf578303a070a51a50083dd8255250064311b6cdc7447bb2fe2af5734fd9a740e2f7bd7c8ece9a85ad3070a51a600b6a3cc5e298d2d526ba7d457f291f82e1bc23374e50dcd30e89039febcddf767070a51a70008508bc8161c992ddf482fdb73912e60937b8b8276e7befbdd4be54eb506398c070a51a800bbeabe7a3667da4b51a8b94b8ed9a3fcbdbd5b26bde1d58060fe49dfabc0fafa070a5bf7004a280ec902ab384c80401403f27f293f9fb9b64f3bf0312ffb380ba16b32fb25070a5bf8006d20d1f212370912efa1d590db2e560c18886f5c2d74444b3782ff5b0ad86960070a5bf900e35b3c32ee3db94bb7360466f310a021147325bef615b7ebfd4b244046dddee4070a5bfa001e0dbc9f581223db8c0bc92de7823a7c60f3f4c87062364a4f359461f49578e4070a51b489520000000000000000000000000000005404cd9b8b194faed20b243cd9d10b00a0dba8c0fbbba183fffffffffffffffffffffffff95aa3ba0c094696d112972607071247ed9ddf00000000000000000000000006f50b180a44533df10180ffffffffffffffffffffffff8346000000000000c05cdff5d0a500000a44a69449fd6824ad9b95702b410a44a695b10248edd51289e8a7cca89bb648ee14afe9383b6137a30055ca673903bbd58314d3350055ca683913dab918c8fcd300ae069b095b00ae069c29214b5a810600b1fc8b1902388200b33c1c11aa8b00b1e78621014b1f0d0a3f8c060b130c6808fa2102556bc106e2e8ac71060eba4d771d5f2580c4f55af0d806dfe728aa240000000000000023899629915b43fae0e5eb9edb06dfeb88a29854d091fffffffffffffffffffffffff8446d0306dfe72941049f5e4e0000018806e2e8ad1109990c6786d379435fd717081259938d77160532a9ed0c6786d4990682c5a4e34ebeb12fb14d5983e8634a22c20a0c36b9b4792cca63e4bacf5b5cd10324d2a8ac2b0c36b9b5990477339d209eab7ccbf87b6165a05c39e4150602831e4f4202fb6929df376a5102831e504102fbe64019dd65350b8e7d874904e6167b4922d798500bd2b8504918650127cc3dc800000c6807c14a1b1ae4d6e2ef5000000be4a3da4902b5e3af16b18800000b8220b7030afcb38b4a04e6167b4922d7985009e8ae590901022d52a01af3d745022d52a119f419330775cf5e4155fbafdc33c988000a21c72842d1f3c1295de116ad0000015639711dee449a58b305c673c01924259a000f0f3d490193f24bd6d41100000ba74de54901040ac1d852a1a41f0000215041e9251466e89f46320c1608bd03000021c64101c477b9126962cf077630254140ea3a16c0959bba009dc7e9030c6803331303050bc7f393427672bb4157efc3a90a38ff6d291b6103f4190a38ff72f106e1000000000000000855b5b3b66a0000000000000000000000005b8d7f0a3900fd99a05183cfcfaddf218bfb3cdd50c9259c7c08100a3900fe614b8f82b2fea145776931c3580c5ea8a2030c02aebb81c86d6ea56a1115b76e77ff60a3bd7b2f0b98862d893c0000000000000000000000000000000004e468a05103830e756d6e90c1f6840a60470f4921aa81897338b5df6b04c7e4bf5203830e756d6e90c1f68401b401364a21aa81897338b5df6b000f7641490193f24bd6d4110000000f76423a16148d3144922e041f12ecf101810000000000000000000000007cb9ffffffffffffffecf0504b95f11604258eaf5909cdc071e8a2b2a49315ac04258eb0a13b0f43acedbe1a5c683f1d1926ba5391134fa7e00153fa441a2ceb660153fa4539041533775289600153fa46110100015408bc3138682b16a000015408bd5105207a0234ee0d634c000155a137390846e94ae9209502d98b76096b02d98b772914e31dae59039809cc298c39e3218a03980c01292a115dbd4202d9a56e11d83c0542e1f3494efbcb440149940000084b25ca0305c64e50310156768521d40c23b1e742023b4af5ee4800000052ea914a4ef98ffa61d1d121d404cc8e927102a44d95485a4cad0f075164febf04cc81968903feaed71e34638bc44dfb75189dec1a4604c272d4aa0f000000000000000ecec162a8f52c310118b096c304c272d5aa4639526cd70000000000000000000000008c1859f204c272d6410109a3b00000005804cc8e93190186a004cc819731024c57b536340c2cf5c281017c1d7b9875cea9b016f67a025c06d20c2cf5c3992dd01d70de3fd1996b3392218d84b5c6b5506f0c2cf5c481017471f7d38aaa339b93033f17148a8e0c2cf5c5992d26fc22f757aa27d0f6ecadb03b20fff250bd05918767095205918768290fa9a8ac5b05a4deda31058160c9fc6305ae0b3a3102da016d8e4f0597bbf12a04cbcd780d0c680a272a0aa6d5da510c680a28290fa9a8ac5b0b3dc6c70b01072b4fa5211e3a627f0803977d13074a00d1e36022030176dd00d1e3614902b247fa7757ee000009a4f8df090103f40694090103f40695419f325f4a4e0a91d903f40696420b9163762a3984a703f406971117d703f5ca7e5918babe0c3f8264355d065f03f5ca7f5901cd18a7d5250e029941030b81673a09010c680909a2974dfe99c61e93bc863fc8091f8c6948f693b58e03cfea0509020c54a13f030000928a1913ec630000928b3a01d02222f7ee1f0000928c09620000939829900127da480000939949045f1622cf1cb4925c02cef47819a71b5b02cef72d39086727102ac37109c0754f090106534d6a8902cb15f25e1bd992a6be8194dc6fc75d310652ee338937000000000000000000000000000000000c6807dc425aa86fd5c7f81c5c0b2910b641b432ebf0af45b1420c4b625842b432ebf0af45b1420ac1147841eb586625c40c51cc07782a0142eb586625c40c51cc005502ae19766e41005502af3a0ad21d9f971e8d005502b0096c005506dc299139616b28005506dd49046e64158b4d62942c085da0520901085e61ef090100001f3e22138ce20007a8a0941902bb740c43d98f03003b544a21047eaa720c5480a1030b1216cf0b010b2b03d421016d63950775e4de191f5c36074fafaf198a956c06b5d9d91a21a32409e1e459110fc201af5d8e03029b178f194349820c5ec3d8030bac5edf0304cd9c331950755d03d46f17210f91b3590544110e0309a8606522015d537b029ae042210d9d2f72000f851e0305f312ea81ffffffffffffffffffffffffff9da130086ab5a221037bfcd300f1d782194c4b400046083422037bfcd30b0b04e9030b46da6c1a1afa8a0a6742bc22017b46330935bbc6030000219f2137b6a3a401b7ada42202686ee80c6022162101c9c38004c2732f211bdeacda0acb35850305942c2b0300274627194c3af209cd02c81a65f3be001994a919124c0703ff7866211a4fba0a00aceddf1a4c4b4004c7e4ea210f4327ed0a293ba51a2c88020b0ae8c01a75512b07cbf31503036e1acb220129bdd20153fa591a2ceb6602f7eb110300f0aa8f220214a5730102ee0d03025b4ddc0307cebd8d03008ff8922239a47ca60092d30f221dcd6500084bb4c6030687a92f030c67de5919976e6d000092a91913ec6309fde86f030a854f3729010becb92609f83ffd123cb109e1e2c0210301632b000021d11939565500fa05281a74a37b086b56641997a63c00199762220177c8d70a32db7e1a4349820ae031ae1a32442d0c643349030a3bc80019e287c5044b21fa0304b4d64b03088b1ed203034a043a1a53e83a09c179bd21018722430017918721030c4d520b258ace030b7e946d19404db30ac22e420306378d32030c61447913016902bf6eac1974a37b0b2076f01927192409eaf0c22120daf6fd0c680a361a1529de09e0930719a1d339086ac1f02101d42d5d076870660306706b42030c51c6f4194c4b400300f28d1917110a0c67e4af2102985e8609dafc861a1cf36b0ba6b530030018327f0309f9d264030a3bcdc41a170b070548bba821381fe6750728854a2106b5eb9908570d4f03017d0e2a030548b65519121b9c0597c0602286b4dbd405150aac03059ffcc6030339bf551a64a225058a22ed19fdd40100008330190e5aa80c2b4d42030c61447d0bf2007fc4fc030c67dfe219f8c2680c4956af190da9e809eaede21a22e0810b2107fe1a2387070c644247210b4aa8ee08e7907c190f42400829f019191895ec0c680a38220f54816e00e556a52184eb185400c2a10b220d9d2f7207750b59030c67d7d419e3a89400fbefa829012aadcac000a64da7030bf926de03005b4161030a22e712194876e303b209da0a010b90c1be0305fd9627220423714f0389a14119c93f77000040a62901b38092c8060b2df31a09c6490719cb2a0301f71ead0309f1890203056d7414210265b37404b8be370303cda4d821017b463301bb1af9030c67ee6f1a09c6490c558922030542e2442256e6e06c0c1e31270305fcd106210171f8530a09848d21030be47c05d483fd1ab4b3790bed89a21a0f424003bd2b6a19c966870400b3d20307711d662106916061007867af210423714f0b770726210129bdd202a8ec65030c23d02c0303a7fd1421037248d80ae580131a365cd807582e02192ceb66080621c5030b6353d31a0933fa0ba997881a2778340b14abe3030087fd6f2202a5692a0687ac4c2a010becb926002538d4030b209e8b030c38c9e10300147a2a210125a6100bd0d3f1030601f16219f0e4250c5e3ab31a64a2250c6803622102a5692a09f5f7f522138ce2000ba3650021012657db0b6f9f091a61dcbc04083fe21ab85abd079e007e21370b6ea00a69dcd21a0933fa0c680a3c030c680a3d030b9555fb1a2ffcfb0583c73d19a3f3980c67d4e61b08f6910c5b016d2109404e43098895ac03005b096503072296d01a3ca16d0aed19351a4c4b400c680920030007a0372a012aadcac0010e020719277834095fa58203080631ee03099761c11917f6de057dee3d0304c25216220f20476b09d445bc0300b1e84c2101542d7f0ada781d03005502ec19766e41002a6e1711d5c50ad615fa198b00e40c408f11030b60bd1c030b5511b521015d537b0693d68a212050fd28005483bd192fbf8f0572d34e1aaee69a090adbde03000024ee220201652e03420afc1938173909f9c6061a1735df0c6445fd1332bb0c4d126d03074fcb7b2102fbd5750c59d5082101876df40a15d24c1923cdd20bc86bf0210b4022e101a437d60a0109a10adf19204a9502cef4d01104900c680a400305865b30222791efee03798fec2101dfd52d0b33ecad03023a9b01030b54f6cd19d4b5300a2a8e9221012c9fdd01bba05b22032dab8c03fa370921083faf3f0bf8ff1703054757bf0303971d731953e83a09dd5306d1026cfffffffffffeaa06cbc6293affffffffffffaca8f0a9d0b309dd5308b9019945ca261fffffffffffffffffffdf6d885ca3d3875a09ec7a50b120fd2ed5c663fffffffffffffffffd5fe2ef583868390c44f30bb1014c03a6c93dffffffffffffffffffe59395970c4a2409e7ef9ab90176fc97a9905cffffffffffffffffe22811d7b48ed4fc0c4d079b030548b67542c9e3d2c58796218d056816ea59037bd927138600d49b4d90054da50d09270bcfaf66030a46e7f709010a4c1c3509010c5bd888090109dd531342209277a35c2c78a60b9aea8741209277a35c2c78a600fbefbcc99c000000000888a7d3486ee8fc000000000022acbedefb5f5e00fbefbd090100fbefbec21b12dafbfdd0c316fffffffffffffef05a67c16a75940000010863a35316a253dbddd58131cd890c451d92ba08a4df4daa4772ffffffffffffffffa925507d569c417e0c2e5ba34b2c0084229a1569df370c5ad8644b0ad5346741605a9e9e0c2e5badc20208bd18cfd592ddffffffffffffffeb8fad8f6a3a87d0bf088a0e048189944a67fd8887d4068d29134fc834980888d993890cffffffffffffffffffffede8081952df0c5d6a5e930db4fce241dd331254b45955e759b9906c9303d46f36c96100000000001de9d0a296be1400000000000716c5b3a2c19a03d46f38c201698cbb5c309527fffffffffffffff1d706c6154911e07f0c59b2efba1a61815fe4c121fffffffffffffffef77fefeff0aa5724042b6310c2014443fe6005c4b2fffffffffffffff34cd852b7ebecc0bc0c3c7a4faa14c2b90b47ffffffffffffffffffff2fd9791c6c700c5f9f89ba0ae726d98d041bffffffffffffffff92af5393f35e5c3d00906feb1903cd60009027a141053b66e17d45c8c7008ff8c42239a84a060c60fd6b29056986fc3e0c60fd6c29109c5d155b001a667129109c5d155b022d7a9a29056986fc3e04c2642a69029cd0dc9601befc844e95506604c25506891a99f2e294e69eec28fa1a6b7c16767aa104c2524fc1010000010000000000000000fcb116aeffa3332d33f00b0a04c25250aa7433e70f1b0000000000000000000000000000000006ff262b4162ebbefa000020c504c2642b11072404c255073148c27394fff2010f3865030ba64f0709010bb2404f090101053fb3030a64e88f030c68093e030a15fd4e19219c8d07af16c303029b17cb1a42fbfa0c68065a1a06a0980b93a5fd030c68093f0304cd9fb31ac47e710a0352ab1b0c4033060647131a4c4b400c680a59030c68025a1993c4db089ab9a3030b72b260191557fb0c675c0f29010bfbaba90574fbde1a4fc54f029b1a471acb2d600c67e71a030b4cedcd19b8848c0a854f6d2a010bfbaba9086b56cd1a97971d0a629a691942fbfa09f46490191ed0a907209e531a5b8d7f0b40a2c7030a38ffd6195b8d7f0b0966290309f70c441b155dc209cdb28a1a26f6c80ac4d56919debe710c68025b1a06a0980b0b3aed1a4d8e300b0374da1a2ec1ec0548b6ac1a121c1b0c680383198006490a6782ca1a01d3e80a74b18d130c16058bcb9111519008ce49311176c70589dffd210326ced0058bcb9311cf840a46cf031ac96a80022d539f215b6684f709f66f8b1b155dc20c526ed4191e65060b437916030b3cbdef19f8c4c00871fb5b1990b19f0c680a5c0303a7fd3922036a2d9b0903f15e1a93c4db081258dc030b17f0ff1a43236f08cddc0a22026ab6f00a0395bb1a12d6c40a4684f91a20807006dfec2219bb6a710c649e170309851e40030c680a5e030a3e1f4e2102c677480a0f266c1a23d3540bf2a29f030a41b3ba1b0c40330c67fd060305865b6f2127939b3707ab051c030c6806663357f30ffacdaf09e1e3004a02bbc099d5fb6d81280bc3a2e5030a4453cf41c05cdff5d0a500000c680667030bf2a48303005483f3192fbf8f005483f41a2fbf8d005483f511010f0054953531023d3340b4fa00549536310236c03d4e720c50989e0a080b243d32030c23c025090804b56839c2d6dd7ab17898f622ffffffffffffffff2fe802be26151a7504b5683aca02a36f4789fa589414fffffffffffffffadebcacb20b1ca37004cd9cb28952ffffffffffffffffab92170ec0b4ed7e04d06768190364bc0c5f584e0304b56840c99897a77f8874d8e4a400000000000000004f0f3a878a5763b104b56841d105e853ffcd7b1bd168c2000000000000000637c4cedc5e64372e04b56842895a00000000000005e853ffcd7b1bd168c204ccbf0331367f0f4bfb9d04b56849c904fbb05e29a93b2adf00000000000000017bdabc4ad2329b4e04b5684ac90fa55fc849c633e2170000000000000009617f4a280cc9c31b04b5684b89970000000000000001f4abf90938c67c4304d0f752190331710c09470709020c680a6a030c6808193b4139ff1553628200d0e46c3903fa9a0613d57700d1e3c34902cd764c1a0ed7dc560c68081b030c5e8ed2030c680a6d3b4139ff1553628205876e804119d3a06ac81297150748c19e390fea68184f55de0afdf701110f0f0bdbbf2609010c5fc9b8098c0c34d7b909030bd65d4609010b8f018c09a00c41d03109c80ba8fff709910bcff8da09010bbb02fd09a00bcff8dd095a0c160cfd09010c160cfe09c80b859b3d09040ba8f73809a50c22a7d009f90bdbbf2909640b4ba04e09020c2adcc209780bd65d4b09960ba8f73a09010c22fb4b09010c22a7d709010bc564d311012d0b859b3f098c0bdde48509010c5fc9ba09010c41d03709010c2adccf09010c3f69dc09780c34d7c509dc0bcff30909010b4ba05009d20bd00885095a0bcff30a095a0bbb030309010bd9f60609640b8f019409030bdde48809780b72178909010c22fb5309a00c3f69de09010bd9f60b09020bd0088809010b72178a09cd0bc564d709010ba90003090101b402314a21aa81897338b5df6b01b40232390d74cd588d20000c680822030903f17e1a91ae9e0c68094e313086afcfb4f50903f18259045b800d5c97ce6b72ff2d0903f183410f87ac9ab7364f710651176c390c4611e277011400bc17a53907b7a66cca943300bc17a641265ab3c59e3f772100bc0e576964988e2f9ca76382faf3a116e900bc0e584903eb051ef2a61f90a200b1e8a121014b1f0d00bc149a6964988e2f9ca76382faf3a116e90c68095159015c76b8474f383b7749e808e0734169fe412349a007b6375cbbe79c4300bc14a1590182b58557823d4bdad23500bc14a241312772e8ee420f780a3f945639011648c153fbfb0c68082559049f6505903d636cf816d20a3f8ca40b1300bc17ab694e7ca90becece971fd4fdc2b1d065117724902706925fa818562160c68095319191c050c6809542102556bc100b1e54f3910786ceaf8a97f0a3f8ca6590d32a56f7537d7531ed9f9004c69d14101192d1069581b94004c69d209330bf1cd0b09010bf6e4a809010c09473741bfc0251dd96f547a04d01b80c95a0000000000000000000000000000000000000000000000000575ababd1027100000000000000000000000000000000003a6925fc60e0cb057f68a4413b5870af75813c370b243d48b12f47d6f93de7d412d100000000006c8de48162dbfebe057fca93d1027100000000000000000000000000000000000000000000000004d01b83c9530000000000000000000000000000000000000000000000000c5f5872a9438b05bb3e6e93dd000000000021ed231b1b090ac40c67f860a90301b8236a6237e80000000003867715cb273eb69e0c67c289b10c1127813160048abb000000000667b65640bdebec310c23c0455103c530c2b6a7500687aa0575a294c95300000000000000000000000000000000000808ad477f33fb05f3ce5fc99500000000000000000000000000000000000bbcd5e2e44dff0575a3a1c95a00000000000000000000000000000000396e5a6e245acc860b4cee0db111ce59aaf96c4721660000000001a672584024dfb12f0019fb5f1106910019fb601106670b8e452049056bc75e2d631000000b7c17ab4a056bc75e2d631000000a5bbc6603054bb4ede9440000000000000000000000003d74fffffffffffffff69b8ecd66ab61054e942d5901bbcf019b03df3c7f5ef7054e942ea10a6b3d75f2eefc6aa202326efd8f51d74b6abe8c00002156412b85e64d385c77b302db8c563905bb61e44c980004b58913421a67835a763b5b6403d46f524201698cbb5c30952801e36ec70309a4f954391fd7ab9a6e37eb0046088439514dc947af5000000021a342051164cdb739473101b7aea939380d19109f100004c273d34202874b1e2668585904079c00391aa4cb2630f102036e1b56391b0028e44b00000153fb38390415337752896002f689273904bd39622592f2009038bf41053b66e17d45c8c7002f56bc4102b42e2f31b30b910574fc0d39072d8e0e5b01ac029b1abf391292226e1c5da00a21c7ed390b74c7f337512c000092dc3a01d02222f7ee1f00fa0594390aa87bee538000001997f13922482f38a444ea09dd535039019945ca26200001af997c030a38fff6390855b5b3b66a000b7e8cd83a05d7359402c0000300f3143a0217907aa9c46402db89a7410591d35e956cb2000548bc4542051803f39d8e974200ad94b403004b24863af5a61df9971b9404b2453f0302009a06390880740a6b53b200009e8e39017ecd4caaa38408ce4959312d694efcb4000155a23b3102183722066e0589e0193a491f01fe8f8e0705d043e9410b1db9419116800000fbf00e421b12dafbfdd0c31705fd992e3a03e28a86bcb5590597185f392e7a36d85e9d05054bb4f93a0964713299549f0c680524420570a9ec4ff40000041f14093a130fafb46a0eea0087fdc3393db799f395cba60978133103097545af41015c2a7b13fd00000000215731343ab826e82908cddc4839382f51fa27dfab000871f0411b12dafbfdd0c317010e033b3a03947134637b48000024f131122f43d0889706dfec2d3a1100df58f432a904c252ae4101601cdf0989b552005503383a0ad21d9f971e8d0054f28a31689786263000000024f2392ebbb29f84fa31072eabf33a243dbe4b2ae6a30a3e1f9a3a4079d386312e3102cef7e3293abb90b98001bba0d3394f9c26095777f203fa37b83abf35527b40a1e200ae0745490452103a5bf1b02e7f00ae074f095b00bc0f2d490452103a5bf1b02e7f0368c5df0901000040fe422a566631615bb5b8022d53e21af3d7450313f97a1a1e6506000040ff421f8503008a9ac636022d53e319f4193301b4028f4a21aa81897338b5df6b03940b233a12c6b337e1696b022d5696215a90d0ca0313f97b411b2e51a2b6e9dc56000f107d490193f24bd6d411000003940b24490121ca814a8dfd200002649cc51176240283205e4202fb6929df376a51000041002901645ec4560052ebc34a4ef98ffa61d1d121d40283205f4102fbe64019dd653503940b2549076b9d4ab2674d200002649cc611762401b402904a21aa81897338b5df6b01b40291390d74cd588d200000d1e4784902cd764c1a0ed7dc56002fc8fc4270f5f9d3e35fef0d0b835c84410142001cdc61ef77028320604102fbe64019dd65350052ebc42156e6e06c0b835c85410142001cdc61ef77000f77863a16148d3144922e022d53e6215b6684f70394b1ec22047eaa720030075f31144b3e47de000394b1ed490649d2c967d95000000052ebc54a4ef98ffa61d1d121d4000041012901b38092c800d1e4794902b247fa7757ee0000000f7787490193f24bd6d411000000d1e47a22030176dd0b835c86320f30e478b53502649cc73a11d560af29644a003007604270f5f9d3e35fef0d08d99f3919aee69a01aea5494207a8c34d91966e190c527b021140000b835c89320f30e478b5350b835c8a410142001cdc61ef77029b1adee9b2000000000000001292226e1c5d9fffffffffffffffffffffff34d2a002a03ab89910317b59202b2d6e21d33d0732911ead5ea68a02a03ab96107a49cf3be6f948543b4ccc60542e2b6421cb6f85fd2e7522305439e7c7972986ad9ec2171280133565bc1183405439e7e39aad11b19a6df110197db7a030300f320c9d80000000000002671bf58283800000000001ec0b7646c9f9b0300f322ba0217907aa9c463ffffffffffffffffeb0565f44b7d60000304746fba01d6319aea5c25ffffffffffffffffed94ee172678145809f94876b234709d919f80fffffffffffffffffdf222e716e36a6d0c512557b20cee422dc8bdffffffffffffffffff7e54f60e21e13d0030076631144b3e47de00003007674270f5f9d3e35fef0d0052ebc74a4ef98ffa61d1d121d40052ebc82156e6e06c00233b0e6903ba8b37847ef8c3ffc592bcb30019a07189019b7e6885e057cfd94de9a8455396707900198dc6a9030000000000000002f6e8d8c462d415303fb8cb4f001997f7aa072f4327ff0000000000000000000000000000000000198dc741071f5d130000025c00233b0f1133030019a0723116017a24a3e70446096c09010453eede09010589e04fc101fffffbfffffffffffffffc46bc87d924c806938931d1d40589e051610378b0bd195189daed0d205a0589e05211231c0ac46ae3b901c3d46bb287adcef6cd04830000006aac0d08000023570ac46ae4b901c0f8f4becece38ae623e3f0000006a030c1c0000231f0c00e4a23906d70b1e467ff10bf3e4ac3916d589b158c07c010e0342c9a7000000000000490c067e0d4700000000000a24b91278d9a9010e0344ba03947134637b47ffffffffffffffffdc1a47e1fef8c0000229c717ba03947134637b47ffffffffffffffffdc1a47e1fef8c00003971e0cc9c6000000000001fc8ccc254b6700000000001548988fb4860303971e0ec275b37816b749b66affffffffffffffffb3afd9060c1a60000bd60722c201c89324ecbf867bfffffffffffffffffed7f934dae423db03a3cc8fc2322b1eaac33cc0cfffffffffffffffffdf78fc98ec308bfa03c5d197c241bfc647074d6f20ffffffffffffffffd55ee3384505b02c01bba0fbe943000000000000004f9c26095777f1fffffffffffffffffffffcd25474021967c5990613ad4cd34479a71cf4baa64d89aa86b6ea11021967c66102e2b4482a1b2ee4eb879bf8038dbb085103e8523f4cf16f1ed2dd0b625d544a0649d2c967d950000003971e2e4275b37816b749b66b0c67dee11305f003940b8649076b9d4ab2674d20000c67edc25103e8523f4cf16f1ed2dd0c67e2224a0121ca814a8dfd20000b3335bc030548bc6daa160000000000000015fe6b958a1def7b2cf821ff360548c0a861042836d62935a138f80f16550548c0aa11795d0548bc6f3a01152fa1b7813a0548bc70a937b364758d0e8b5f112f00000000273e350000000d08d000b56b0a0fd0cafba3ad4f70e7d61fc008d000b683ee58ddd1b8c2f74c59836726c83e71df08d000b7000100035ecc00000000000000000c69eedb60a6ee1c1836839a00000a2e57af1808c13d946bf79ddf75276a1261d2e8a4010308c13d958a58f4196928a34ef1e38bf9eb6e563960a908c13d9600010064a2c900000000000000013ccd5ffdf7f0100da967dad4000132804b730c09055b19720223674047a2a8812fc88d18197409055b1a8a544052657586fb99171be9ecfa6ba5eeff09055b1b0001006b52a80000000000000001498433241b4acccd421a55860001470d47ecae08e377ed7201d1dcd6d55189793a0ee38e0ec608e377ee8a4885c9fc86ada7510bef25bf71909cfd3508e377ef0001007a995f00000000000000015503947fe177358efb0cb881000176413e64a6090324767201e00c46e709866855c283a59175090324778a4aa365bf20a7829253d7578b234b063f6b09032478000100776396000000000000000153d079eca60d3516f8003da200016c518e770208b722047201b3e0ce972f08a410243fda658d08b722058a4416ffa7197831ba6277e542ecea53978308b722060001007f46ff00000000000000015883aee435fa37cc54002db9000184b7a9f43a08e3886a7201d0385e2708b91b559228c33a9b08e3886b8a485fbde0216f13213f417922fee6b9d68708e3886c0001007acf02000000000000000155f77a5323ed060f907a6318000176e312076308bb0e1f72021c48d97beb9eeadbad85fcec3408bb0e208a534efab3eddd71418465305ccb9ceea7dd08bb0e210001006c582300000000000000014c0467b830910343bd1c33f100014a307ee20e0969582a720225910be4fb3f4c8c90bba311ca0969582b8a5489cf1ee3eb5b7f2dab62b0361a6423d70969582c0001006b1766000000000000000148fecd25bc194a292d88d184000146576fdc5402db89f8410591d35e956cb20002db89f91a24665e02db89fa094802db8c965105fb1c190a119235e19002db8c97292715d230a902db8c984119092b04800c5cf00a6db00609010a6de0d709010aa19645030313f9b01a1e65060313f9b1411b2e51a2b6e9dc560000410431011321bd066c000041052901645ec45600004106421f8503008a9ac63600004107310174f70cbeee001a672829109c5d155b09a2bbf70303f40749419f325f4a4e0a91d90045800f39cccbbc3146ce8f0776079a429fff2b067f516068077603f30308086d3e09f108086d3f09eb08086d406a7996fa92b74084cfbc0180000008086d41f10835000010ec000000f0ffffffffffffff1452f91da725adde013a80000008086d42692e8af4824003cf2d4fcc00000008086d43f1173600002a78000000f10000000000000024f02b92d0e798e0114f40000008d02cf9096e08d02cfa292554ab87ef09093f3811414a09096aaa1113960903f1c21a91ae9e0c680873030bc36da2030c0bcf6a0a010c680996030bc36da403034a0510391719c7cf8f2a0408056dc803005484943a0d22f86191843d078be0f4a205d500a31e181944dac576d7972bbb392118112d04b5893e421a2aed139a1a95d80c67f8a0c904da8c9cf14366ebf8fffffffffffffffffff429dd2cc03f540c23c0a8d10553ccb59180a60ba9e700000000000000000005ab45276bb00904ccd0ccc151b1e495bd8db569000000000000000000000000000000000c67c2cfc908d4a393227c5018f2ffffffffffffffffe5dad340290462b60c67e53a22dbab80ad0591735a09760591735b29280593239805ba423c2101ca15e405ba70301129320597c1083209b6307c9ef40c6806d71b1beb8c08cddc7722026ab6f008cddc7839382f51fa27dfab08cddc79093308cdde5231116faa2d3eba08cdde5351019551bbe22fa1be472c08ce49ab210132320508ce49ac397510d063daac210a854fb3c93600000000002a21baf2469b0a0000000000021560470250760a854fb5caf3baacc5ef4619951effffffffffffff0c52eb6bea66efa0000aed1a22ca056050d42eed289e11fffffffffffffffa9ffbf025b034674e0c5e5208c2164927047cf102a3ffffffffffffffffe9b817330b3535660afaec0fca03760813504663a0cafffffffffffffffc8a29584733bc29b60a854fb9caeace0ab76b959c539effffffffffffff153f0e0c4a77c9d999034a051ad10456fffffffffffb1e59cdfadb8c00000000000566bd9b48d92d034a051cc14c5daf3ddfd8afffffffffffffffffffb3afd83bf3f024640366358eb9349d903cb1fbb7ffffffffffffffffffcb6bc2115c695f03686a39c102aabbc81b6feccbfffffffffffffffffd55bd2c5c15dc930356e057c14957ae340c0a9462ffffffffffffffffb6b55025dc36c2f2034a0524b926a7b17bac3315ffffffffffffffffffd95f27aa471b7e076d04484a01f9e8e7ffc272bce30458953c090103d01fd809010a6c2ff10901097c00680901054140020901052e746509010548532c090103bb90c00901070018080901056c5a8d090104cda0511a0bce710c5f58d9d103919a5f7f294feaedd3ffffffffffffffffffffffffffe19f250b8eab2b09010b9516e709010394b2b222047eaa720394b2b3490649d2c967d950000005865bd0222791efee05865bd12127939b3705865bd20933058bc6fe310bd3b219ac7b058bc6ff310ce03235a917058bcc2a292e761055cd00afaeac09090087fe09c10100000f000000000000000ed816fc6e728422594141ea35008825f9810b6f402e8d0e272e8fb5d3bd03b809d60852cbbeb91faeea7320a15c982557889e0000018f8a41950000844f04d0eac819b4ad700b4cee5cd9015f85daf9d2acb27b5c9b00000000000000000000000000b4ad700bc3a9e90303fa3823e9b6ffffffffffffff40caad84bf5e1e00000000000000000000083faf3f03fa55849910a46349a418ab5b0a0224d1e45227f5c8b91703fa55856107dc4d22178d82fa15c449ac0ba762f2090106bb6a91790e6ea4e5039aa3aae12cb7bb080d0106ba30c589b700000000000000000000000000000000036e1bd8c980ffffffffffffa430d578ee330000000000048a400bccaae0036e1bdab91b0028e44afffffffffffffffffffef134a81ab02db3b40c3496a6b124c297188c93fffffffffffffffffe8f536e0937ec42038aff47b913c2ffdfc4550bffffffffffffffff39ce58e97e69b119036e1bdfb90466e443e5afa6ffffffffffffffffd3da3152f4db9069074b456fb902b18229886eb5ffffffffffffffffe4fcca7033b085ee09e8e64809010c6809b709010b8f6f2f09020b9514db090202649d383a11d560af29644a02649d391176240c5ff8cc03028320874102fbe64019dd6535000021684101b9eafba6c4c7180000216f41e9251466e89f46320000217031343ab826e82900002171096b000021d4599d0409205c3e4991d20274000021d5510889add24f258c858ff1000021d631047aedee1eba000024f4212e1850350c556aac4101b9eafba6c4c7180c556aad3101d0af4b8c110c556ab009010c556ab13929c7d10b73563f00fa0672f108f2000000000000000aa87bee537fffffffffffffffffffffffff8b5c8500fa08af99d082926bbdd876495e4d2fb6317dec698f960a00fa08b061623e58cc4f9e902575730d0a03940c773a12c6b337e1696b03940c78490121ca814a8dfd20000bcfa5c9030b1eaeee122d1a0b17c8fa120c8f0a739ef712762402db8a611a24665e0a445449127cba02649d4e117624054bb595113d75078d41db1167af041f1455117cba0c6809bc030ab89d8712105b06c715ac03072eac8011f06a0bcfa280030a7db2bb0305876ee90b720a3e1fdec96700000000000c0435e82b4c5300000000000265646355344d0a3e1fe0ba4079d386312e30fffffffffffffffd79d5c1e1172380000a3e28f4ba37135f7bd40e4bfffffffffffffffdd80ac5edac06bcfc0a47afa7ba078f75e3ec7266ffffffffffffffffb43b2f1620112bc00c3f0b9faa1ecf3267d2fffffffffffffffffffecb3c045ca24c0a528342ba01d6df573e45abffffffffffffffffed9101a146aef4fa0a46cf6809010a4b40d409010c32a294090100ae07a6094700ae07a72911ad41501500b2155a3115220ce302d900b33dd531065703ddb40d00b1e60e3910786ceaf8a97f065117b1390c4611e2770114005b121f030b82a0e009060b7194b509010bcf6882090108b8450709020c07007e09010a6c4f1a09260a5ad61f0901059188b4e95200000000000000000000000000000000000000000000000000000000059188b5e9460000000000000000000000000000000000000000000000000000000005917581e95a0000000000000000000000000000000000000000000000000000000005917585e9760000000000000000000000000000000000000000000000000000000004f2809c4902117006df65270000049e222b3b14473ca46fac5e06c5b9240a0109fd90710309fd90720309fd90730309fd9075030c67ef2a12485009f421e91158ba0c6783500309e1e370210301632b09e1e3714a02bbc099d5fb6d812809e1e37211017209e1e4f829a6e77c559009e1e4f9519a2c2bda491472f295bc09e1e4fa191f8645004608fe22037bfcd3004608ff39514dc947af50000046090009280054801e3102ed2c26c7c80054801f49443c9c50dcbd675c200b835cea410142001cdc61ef770ba5d886030458957a0901052e74bf090103d020310901097c00e409010700185909010a6c303309010548538709010541404d0901000024fae957000000000000002ebbb29f84fa30fffffffffffffffffffffdfe9ad2000026759907e0e6c231b1c5abd756e3cb1f008c1d3f0645000026766103c0b69ad26b7f2f4913e62f00bcf87f0300ae083603002fc9584270f5f9d3e35fef0d0a21c87df1013b000000000000000b74c7f337512bffffffffffff2e0c3ed6a21ee9530a29749d71112bed02928d501af17b6c3597300a29749e8916927103ab543f0b242e7af7ee27264563029b18e8e94effffffffffffffffffffffbd0406000000000000000000000043498202b27be3794ee242faabd1e8658d4bde25c2d48102b27be4794f1dc83b5b375b1fdf53dd62f6fcfd022d576c29d71734a637022d576d215a90d0ca01aea60e4207a8c34d91966e19022d576e3101035c52116f022d7bb829056986fc3e0c5569380304cc98db6939c2c91aa2d5a9b4bf3f4d5c2004c7e178a96d000000000000000000000002e7cc2b9e42ae0f5304c7e638b10ef70093cc33ffffffffffffffffffffffcc245218d904c7e179421453716ffffffbd004cc98dc1903e83c057005b6a265fb552603d446648c1c202229b94f4bc564cdd4057005b77a0235312ac1af335d27a8ac6c8daabf0574bc0ca1387308e6a4b8eef0007353243e832c19a9a544b00574bc0d712e457710d1a7940319e8f5c7ebee057e18c3a13a83aaea30b52b770e72fb39550265b01f34687a057e18c471365c41a707e69641f4fb8b67750c09a2310b71047cc88526c5259f4fcd6d78fcfd08a6213a69dba95cbdace21dd664ba87d30e086b5809999796e90000000000000000000000000000000009a2310c11099908a6213b1101d603f407a7420b9163762a3984a7078d420f410b9163762a3984a70bf2a7450300bc4e240902000021b22137b6a3a4000021b342051164cdb7394731000021b40948000021da3901033b2e7650dd000021db511796012d3ab7bfa14b19000021dc2102dcb2ee09ea37f2030590b470c90100000000000000000000000000000000000000000000000005d04b102105ac35dd05d056503904a42ab2449f7605d04489410b1db9419116800001f466f30300ff318b03026e527b094f026e527c000004a77024a7e000000000008583b00000000000000000000000003bd209222105876f404119d3a06ac812971505876f410b7205876f4211184506420aa349345346dea2241209ad06420aa4198ba5050748c2a9593d93c0053d3ed733008f5a05876f4409010c242a70410e2715c359ff41840c1672bc420211426309d2f7d00b206baa410211426309d2f7d00c35718403072ecb739105593d58e3fc248eb7e4793283971984f2fc072eceab6972ba271dcc5da04324dea3123f072e9af5a90800000000000000000000000436225502d4b96091072eacd3a172a50ddb00000000000000000000000000000000072e9af642014b3169ffffffac072ecb743104322092fe90072eceac095900001d5dc202c90edcfffffffffba6e944ffffffffffffffffffffffa500001d5e5a053d71ffffffffff1628b80003ca1ab20f6600000000000001f9ffffffffffffffffffffffae0003ca1b4a81000000000000001503a7fe72e934fffffffffffffffffffffc95d26500000000000000000000037248d803b9330279350407badbb2daa07a29d924a0382f03b933037934fbf893929cf7679fd8fcb61df57309e8418509010c680b1f0901064160b5424563918244f4000006416bde424563918244f40000062baeec414563918244f4000004eb76400a010c519e2b1a0494510c52df89030c519e2c030c5973b8030c66990d1238740c519e2e0a010c519e2f030bbc8f632a03976cec230c5e0217030b2002f509010574fd36e94d00000000000000072d8e0e5b01abffffffffffffffffffffffb03ab105752c659906e86ea21b569a723471ac9a2a2e25674ac5e205752c6661035a49b78f46345a266966e807712d2e190f424007712d2f4a01f9e8e7ffc272bce307af4b71410b9163762a3984a70872e8451990b19f07af4b72326eb7f3ec9be0078d42321167af07711e8b3a92fa674c665b28078d42333a0fc0c6843deddf0872e8473a0ced5c4f71eb1207711e8c2106821e2101b72c92a9380d19109f0ffffffffffffffffffffffffd9791180ba6849609010badd37509010b01b8484904e6167b4922d798500afacf5c31048c273950000c680b244107dcad3d7bcb91cc0b97e0f46202af45109a024eb79eff9cf40b8e83d86102af45109a024eb79eff9cf40c680b27030c680b2809010b97e0f63225f9791ce2ed0c680b29091d0bdcf9ed190d59a80b8e83d93125f9791ce2ed09b685b13202499633c34809b42bdc29265627c61409a8729e2942a2fd6d8209a9a4353202412140cd8609a9a437298778adbc3709a861b822015f4fd409a861b922015d537b09a861ba095109b685b229845e3d01ab09a4fa08391fd7ab9a6e37eb09a4fa09391fd7ab9a6e37eb09a4fa0a095b09a4fb7c095109a4fa0c095b09a861bb1901fc59090b8eb80307b23db809010b8e905e09010b8f887e0901", + "expected_outputs": { + "kzg_commitment": "b3155be333f11f4ac0655292d3f7baf6b7c50fe15f2ae7509d8ad93a98c32adb82899f72b32fbcf77898a3e4a082c4b0", + "opening_point": "00000000000000000000000000000000b65574fcce3da68c6d7199110f1b5358", + "opening_value": "2e9ea79020c009e69d1d480ea0726dec69f43ab688f08c7852270dccbc7456c4", + "opening_proof": "ac2355d9a024ee3d77b8577c299b5384adcea34c205231bebb08ffa9fb5e33f2327f11ecde4fe46e0aaadce36b31c87d", + "versioned_hash": "01a70111f6ade45fdff137f00119dd45284d80e1af6bdad336419c07cec93f41", + "blob_proof": "a370bebe32974312600170a180d02aa0f44394b96221f95af357e696fdbc11ef917fe3b643ffc62c98d333385ab25b43", + "pubdata_commitment": "b65574fcce3da68c6d7199110f1b53582e9ea79020c009e69d1d480ea0726dec69f43ab688f08c7852270dccbc7456c4b3155be333f11f4ac0655292d3f7baf6b7c50fe15f2ae7509d8ad93a98c32adb82899f72b32fbcf77898a3e4a082c4b0ac2355d9a024ee3d77b8577c299b5384adcea34c205231bebb08ffa9fb5e33f2327f11ecde4fe46e0aaadce36b31c87d" + } +} diff --git a/crates/kzg/src/tests/mod.rs b/crates/kzg/src/tests/mod.rs new file mode 100644 index 0000000..e2119a5 --- /dev/null +++ b/crates/kzg/src/tests/mod.rs @@ -0,0 +1,137 @@ +//! Tests for KZG commitments. + +use crate::trusted_setup::KZG_SETTINGS; + +use super::{verify_kzg_proof, verify_proof_poly}; +use boojum::pairing::{bls12_381::G1Compressed, EncodedPoint}; +use serde::{Deserialize, Serialize}; +use zkevm_circuits::eip_4844::{ + bitreverse, ethereum_4844_data_into_zksync_pubdata, fft, zksync_pubdata_into_monomial_form_poly, +}; + +use super::*; + +const KZG_TEST_JSON: &str = include_str!("kzg_test_0.json"); + +#[serde_with::serde_as] +#[derive(Debug, Serialize, Deserialize)] +struct ExpectedOutputs { + #[serde_as(as = "serde_with::hex::Hex")] + versioned_hash: Vec, + #[serde_as(as = "serde_with::hex::Hex")] + kzg_commitment: Vec, + #[serde_as(as = "serde_with::hex::Hex")] + opening_point: Vec, + #[serde_as(as = "serde_with::hex::Hex")] + opening_value: Vec, + #[serde_as(as = "serde_with::hex::Hex")] + opening_proof: Vec, + #[serde_as(as = "serde_with::hex::Hex")] + blob_proof: Vec, + #[serde_as(as = "serde_with::hex::Hex")] + pubdata_commitment: Vec, +} + +#[serde_with::serde_as] +#[derive(Debug, Serialize, Deserialize)] +struct KzgTest { + #[serde_as(as = "serde_with::hex::Hex")] + pubdata: Vec, + expected_outputs: ExpectedOutputs, +} + +/// Copy of function from https://github.com/matter-labs/era-zkevm_test_harness/blob/99956050a7705e26e0e5aa0729348896a27846c7/src/kzg/mod.rs#L339 +fn u8_repr_to_fr(bytes: &[u8]) -> Fr { + assert_eq!(bytes.len(), 32); + let mut ret = [0u64; 4]; + + for (i, chunk) in bytes.chunks(8).enumerate() { + let mut repr = [0u8; 8]; + repr.copy_from_slice(chunk); + ret[3 - i] = u64::from_be_bytes(repr); + } + + Fr::from_repr(FrRepr(ret)).unwrap() +} + +fn bytes_to_g1(data: &[u8]) -> G1Affine { + let mut compressed = G1Compressed::empty(); + let v = compressed.as_mut(); + v.copy_from_slice(data); + compressed.into_affine().unwrap() +} + +#[test] +fn kzg_test() { + let kzg_test: KzgTest = serde_json::from_str(KZG_TEST_JSON).unwrap(); + let kzg_info = KzgInfo::new(&kzg_test.pubdata); + + // Verify all the fields were correctly computed + assert_eq!( + hex::encode(kzg_info.kzg_commitment), + hex::encode(kzg_test.expected_outputs.kzg_commitment) + ); + assert_eq!( + hex::encode(kzg_info.opening_point), + hex::encode(kzg_test.expected_outputs.opening_point) + ); + assert_eq!( + hex::encode(kzg_info.opening_value), + hex::encode(kzg_test.expected_outputs.opening_value) + ); + assert_eq!( + hex::encode(kzg_info.opening_proof), + hex::encode(kzg_test.expected_outputs.opening_proof) + ); + assert_eq!( + hex::encode(kzg_info.versioned_hash), + hex::encode(kzg_test.expected_outputs.versioned_hash) + ); + assert_eq!( + hex::encode(kzg_info.blob_proof), + hex::encode(kzg_test.expected_outputs.blob_proof) + ); + + // Verify data we need for blob commitment on L1 returns the correct data + assert_eq!( + hex::encode(kzg_info.to_pubdata_commitment()), + hex::encode(kzg_test.expected_outputs.pubdata_commitment) + ); + + // Verify that the blob, commitment, and proofs are all valid + let blob = ethereum_4844_data_into_zksync_pubdata(&kzg_info.blob); + let mut poly = zksync_pubdata_into_monomial_form_poly(&blob); + fft(&mut poly); + bitreverse(&mut poly); + + let commitment = bytes_to_g1(&kzg_info.kzg_commitment); + let blob_proof = bytes_to_g1(&kzg_info.blob_proof); + + let valid_blob_proof = verify_proof_poly(&KZG_SETTINGS, &poly, &commitment, &blob_proof); + assert!(valid_blob_proof); + + let opening_point = u8_repr_to_fr(&kzg_info.opening_point); + let opening_value = u8_repr_to_fr(&kzg_info.opening_value); + let opening_proof = bytes_to_g1(&kzg_info.opening_proof); + + let valid_opening_proof = verify_kzg_proof( + &KZG_SETTINGS, + &commitment, + &opening_point, + &opening_value, + &opening_proof, + ); + assert!(valid_opening_proof); +} + +#[test] +fn bytes_test() { + let kzg_test: KzgTest = serde_json::from_str(KZG_TEST_JSON).unwrap(); + + let kzg_info = KzgInfo::new(&kzg_test.pubdata); + let encoded_info = kzg_info.to_bytes(); + assert_eq!(KzgInfo::SERIALIZED_SIZE, encoded_info.len()); + + let decoded_kzg_info = KzgInfo::from_slice(&encoded_info); + assert_eq!(kzg_info, decoded_kzg_info); +} diff --git a/crates/kzg/src/trusted_setup.json b/crates/kzg/src/trusted_setup.json new file mode 100644 index 0000000..800e29a --- /dev/null +++ b/crates/kzg/src/trusted_setup.json @@ -0,0 +1,4100 @@ +{ + "g1_lagrange": [ + "0x97f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb", + "0xad3eb50121139aa34db1d545093ac9374ab7bca2c0f3bf28e27c8dcd8fc7cb42d25926fc0c97b336e9f0fb35e5a04c81", + "0x8029c8ce0d2dce761a7f29c2df2290850c85bdfaec2955626d7acc8864aeb01fe16c9e156863dc63b6c22553910e27c1", + "0xb1386c995d3101d10639e49b9e5d39b9a280dcf0f135c2e6c6928bb3ab8309a9da7178f33925768c324f11c3762cfdd5", + "0x9596d929610e6d2ed3502b1bb0f1ea010f6b6605c95d4859f5e53e09fa68dc71dfd5874905447b5ec6cd156a76d6b6e8", + "0x851e3c3d4b5b7cdbba25d72abf9812cf3d7c5a9dbdec42b6635e2add706cbeea18f985afe5247459f6c908620322f434", + "0xb10f4cf8ec6e02491bbe6d9084d88c16306fdaf399fef3cd1453f58a4f7633f80dc60b100f9236c3103eaf727468374f", + "0xade11ec630127e04d17e70db0237d55f2ff2a2094881a483797e8cddb98b622245e1f608e5dcd1172b9870e733b4a32f", + "0xaf58c8a2f58f904ce20db81005331bf2d251e227e7d1bef575d691bdca842e6233eb2e26c2e116a61a78594772b38d25", + "0xb3c1313c31ec82da5a7a09e9cf6656ca598c243345fe8d4828e520ade91787ffb8b9867db789b34ad67cef47b26ff86d", + "0xa8ed8a235355948e0b04be080b7b3e145293accefb4704d1da9050796b2f6870516c1ebf77ae6a65359edcfd016c0f36", + "0x80e792d5ba24b8058f6d7291a2ec5cb68aab1e16e96d793128e86815631baf42c56b6205c19e25ce9727bd1fd6f9defb", + "0x816288c5d726b094e3fdf95cb8882f442c4d9d1101b92c7938a7dfd49bc50636d73ea1b05f75eb731c908c8fd8dee717", + "0xae009128d128ba2e1519bfa7a0c01ed494a7d461c3aba60f8a301701fed61fe4e31d6c79ce189542ae51df91e73ce1b3", + "0x96a866d60a9007d05825c332476a83e869e15b11d7257172a67690ea9bd3efea44bf9c8d42191454eb04fcf110b16396", + "0x8b250a2a06419adb9b611e89f7f8f2990aa301949b533ad3bf17c4a61ab5f5be0b1d5e2b571864d13f1bb75805c7795d", + "0x8450f49facf2e620fa45ee90e1801178842d927a2a25fc6ed7ba99a4eec7ae40eebfee41028eaa84f107f4a777694976", + "0x91049080cf659c0985a22d1366e59191bb89663f922e8168b9b7d85c8a73d74a6d9dceefd855d3d858b493670c750581", + "0xa1e167aeb2008087f3195926f1985c0a459d6ec57237255b1473a96de4e2c1cf766127c862c7dc853a6909e67cb06cf7", + "0xb667c0d4e26e20698b07567358625d5f003839c92de8088e12dbd74a6f6a3156b4ea8d252c9ad62af5f6c4fec1cf6cc7", + "0x8e4b5e304c0b1b161ae3e4b68b5e3ac66c42acd7c1ee2458044f6527c508a93995e50894d72d57c1350f91afe72775ff", + "0x8c642640aa7915421cdc21fd639f88a42052b1cfa358ff7702e60793a92b7b5926dae15a0c8f8f59cd3013f01c159ba3", + "0xa356f35e713cfc283056bf539de54a21731e61efb4c47319f20de4a4b723d76a33b65f4a67d298b9ec5c2a1579418657", + "0x93ce204146ce95f484dc79c27919a16c9e3fc14a9111c6c63d44491158d5838117d20851cc3227a5e8ba6ccf79e77f39", + "0xb585664cbb9a84b52f89114e1cf0cf1171bea78a136dc1404ac88a11210b2debc3b7a55e702da93ff629095c134a295e", + "0xb6dfd444ec7fdceb14c6328f26ca12c3f9fc4327d8d8c68948e92e7e61262b82d833a65a9e3af6353ffa832b6da25705", + "0xb4d4b8eb9ecfffe3f0d48fb4149c7b31aec1da7041ec03bd0750c52a2a7cbc3a7cfbf09d5bfdc56e3860826a62d0bb91", + "0xa4e248e3d61db52da9683fef188579c470d65e2df9064726847b1599fc774049ffdc6ef2ae578d5ed7874f1298ecdf69", + "0xa68a0fffc2e37d3183feb01b42234c0f4e510f9dc29d09c571e6da00fecad9da224cd0f31550070148667e226c4ca413", + "0x86adda2ffecb77236c18005051f31f9657a0d50fef2a1175dfda32e74d5d53df825c10f289eb0ad39df0c64fc9bc7729", + "0x998266d5c9c3764ed97d66fa9ed176af043999652bae19f0657c8328629d30af453230e3681c5a38e2f01e389ed8d825", + "0xa05261554d3c620af0c914cf27ab98f5d3593c33ab313c198e0c40d6c72022eb5943778cd4f73e9fe8383392a7004976", + "0xad243fb3631bf90fedb9d679fd71fc0cf06bda028591ded2bd4c634ea7b3c2bd22eca2ab318fcdaa6c2cda1e63e1c57b", + "0x89b9859a04f903c95e97fb2951f01cc6418a2505eee0b5bc7266b4d33e01b69b9fe7dc56fa9ebb5856095be0925a422d", + "0xa68d118343a5bbfbbab95ff9bfe53aeb7fdbaf16db983e6f4456366df2aa01fbdb6ee9901cb102fc7d2bd099be2f1f3e", + "0xb49301f25d5a9dd2ec60ddb0b4b477291958487efea9e54dc0e4ef388f03b8bbadd13259d191f7a0b7513876767d8282", + "0x8b93df7fb4513f67749905fd43db78f7026589b704ebb9ea3255d0ad6415437799f40f02e07efccda1e6fd5e8cd0a721", + "0xad88769ace96455da37c3c9019a9f523c694643be3f6b37b1e9dcc5053d1fe8e463abebdb1b3ef2f2fb801528a01c47c", + "0x80f0eb5dcbfaaf421bf59a8b9bd5245c4823c94510093e23e0b0534647fb5525a25ea3aeea0a927a1ee20c057f2c9234", + "0xb10ad82ea6a5aeabe345d00eb17910d6942b6862f7f3773c7d321194e67c9cced0b3310425662606634dcd7f8b976c04", + "0x82f6fd91f87822f6cc977808eeac77889f4a32fb0d618e784b2331263d0ffa820b3f70b069d32e0319c9e033ab75d3b4", + "0x9436d3dc6b5e25b1f695f8c6c1c553dab312ccace4dac3afddc141d3506467cd50cb04a49ea96ea7f5a8a7b0fc65ef37", + "0x8e0a9491651d52be8ebf4315fbbb410272f9a74b965d33b79ff1b9e1be3be59e43d9566773560e43280549c348e48f01", + "0x8809137e5d3a22400d6e645a9bd84e21c492371736c7e62c51cef50fee3aa7f2405724367a83fd051ff702d971167f67", + "0xb536a24f31a346de7f9863fc351fa602158404d2f94747eebe43abf1f21bf8f95a64146c02a4bec27b503f546789a388", + "0xb5cdf5a04fc12a0e0ef7545830061dff7fd8abea46e48fbe6235109e6c36ee6bffcb9529e2f3d0d701cf58bbfb6a4197", + "0xab15377525753467d042b7931f66f862cbbb77464212c9aa72d4e5c04375ef55f619b3a446091c1ba1a3b5d9f05e538f", + "0x905a75b943ad017ff78ea6ddd1d28a45c7273ee1c2e5e3353685813793ead3370c09cabd903fcab9d8b1c6961372d486", + "0x8147df4324faddc02fb0896367a7647b719b6499a361aecfdd3a34296fa6768ad31c34f9e873fd1e683386c44651883e", + "0xac91d08570dd91f89d2e01dca67cdc83b640e20f073ea9f0734759c92182bb66c5d645f15ebd91ed705b66486ed2088d", + "0xac6295ef2513bbea7ef4cdcf37d280300c34e63c4b9704663d55891a61bf5c91b04cc1d202a3a0a7c4520c30edc277c7", + "0xb604be776a012095c0d4ebc77797dd8dec62a54c0559fb2185d7bac6b50d4e5fd471ac2d7f4523206d5d8178eabd9a87", + "0x80ead68def272ce3f57951145e71ed6dc26da98e5825ef439af577c0c5de766d4e39207f205d5d21db903d89f37bbb02", + "0x9950b4a830388c897158c7fe3921e2fe24beedc7c84e2024e8b92b9775f8f99593b54a86b8870ec5087734295ba06032", + "0xb89ba714adabf94e658a7d14ac8fc197376a416841c2a80e1a6dde4f438d5f747d1fb90b39e8ea435c59d6ecda13dea1", + "0xb0c78e7cc60bd05be46d48fbb0421a678c7f14b8d93730deb66fbe1647613b2c62b5075126d917047820c57fc3509cb9", + "0xa860c4acc5444e9ae987e8c93cb9a5f17d954d63c060cc616f724e26bc73d2c54cd36e0492d1fde173847278e55942ba", + "0x8fb8269c9d5c15428e8d45da1251e4c4a4b600d47da0caea29fef246854d8fb6acae86a8e6440d0c429d8dd9c2dfee0c", + "0x96c5d8eb6fd5c525b348ee4335d200139e437e4be83690af0f35b7f336a7cda8c6d2958647988b84da9f2dd7bbb7710b", + "0xa7f62141c4346cc14e9823dc38ac7d587b0427022afc1498d12ee2c43f6ac3a82167057e670dd524b74137f8c3ceb56d", + "0x956aac50d06b46a3e94397f163f593f5010d366aa2d816c2205c7d0f47f90cf0f36c169e964f9bcf698d49182d47d91f", + "0xb812899bcdc0e70d79ca729cb01104bf60e1357b9085a10f64f3ba9865d57e9abd0a505a502d4de07afb46f4d266be2f", + "0xabce02c7e1372e25d40944dc9ece2904a8f59c8854c5f2875fe63ace8ce37d97881f4f9ab4f7bad070ec8e0daee58d3f", + "0x8fb13c515b2d6abb4e14ed753fad5cc36c3631dfe21a23d0f603aad719423dd5423157eefcbd9a9c6074e155b79eb38d", + "0xa9ef67304dc297ab5af778cf8afa849eeac27db4b6978963e97b95ef7a8d3264d0d07775f728c298a2b6daed2ecf5053", + "0xa9b975520adb066e2ff2a4cde53284c23bc84261a22dc43b1634d99eff8e7892e46bb6e6da7319c9e72788aa9ea7a1ea", + "0xa6eaea4ab4206294474d9b956d9d3188d558a5633de2bd05df0d3bac03dbcbe4ed85406349c1d2e660b77c6da1f5bf8c", + "0xaf4a19f77290dddee762e1e0d4bc9945aacea3f75756ae46cd3e58a8f74d1b5db73e4834687946b0f39191e32f2fed0c", + "0xaafa6523f58f1a4cabc924c86d842816d606afeea21fa4b2b8b9573425810fdcc41c98888318e868f9c05e2be12178a3", + "0x8ef38fba0a3fa4ebe985239c8b759c22aaef0c57e6f39050a651c869487803b0d1e389c3d958fb5a7f37740f050ac69e", + "0xb07dfc9f85913c608ca7596a2e361f05e4853fad00e796fd492d247de6414892ce160f627669b1ba933b6ad726415d4e", + "0x94da679ad1d78b2bff5283c938f17b2a7d6e9cbcdf59d340e6dfb652951c7a9e852ac0590f99cfee9631b9410f6f00ea", + "0x98a907c9c021a5b034d3720197c160a82c4b7146cb73d48efeed99b9d0c6b831812cf80ac7e19e85a676a8cd3ead72de", + "0xadb746595466a12929019d0048cea33236b05c1229d2eba73b259a18a786f2bc3f05fc0598d8ce253cecb80bdf679aaf", + "0xa2fbac016996d68f9027a157b0a3f6a336144a798d6113adfcda3a5d05b62c31f108f112aa915906aef22b7f83b9228b", + "0x81841dea1904406d1b6fa49b4b3f7f6cb40b7646cf44d36c9fa07e3dee29f8e47324b40d8356ddf653109673c3374e9b", + "0xa3edbb8aac5e60c775775cbdb19067341b2e2530de48738e84c2c07151241ee31f0d8333bf20c2bc9dcb7b2e638a6b5e", + "0xb8aa6890e22964828787ce86460d3a32f12a655bb5c28de500f2fcf6b61e3334640ec6ba96029a4912af0d18df4b4139", + "0x8ca43169f04243ad0fdb0152de17c60d9e31ee0ab520970fccd98590e05508821a183b4b367967e60d53c2c826ec5dbd", + "0xb179fffd9df8c00486c5a8b9327d599f5a11745ef564f06e126849b06fe2f99273c81f65bc941efb0debaadfecbfec1c", + "0xacf068f1c2b1926279cc82750ce21b0d6b0bfd0406f0d8bbfa959bd83935932957c7f6b8de318315bf0b75f6ee41a0f2", + "0xb97831da260919c856e9f71a41687f5979bc16f8a53b1037285b4a2f9ce93af5cfe70bf0ad484744827fb55c847b58eb", + "0xaff50b0bd907383b0c241727af364fe084d021221bfb1b09fb6c1a7752eeba45d662493d590f1f182764b90b25f17906", + "0xaeeef044c14e3ad41e1235c9e816e1eb49087fd3abe877b89b3bade74459186126e160bb569bcd77779e701b19b5f71a", + "0x8483deb2b7001ca7c438fcdca8ca6aba96c9cbc4becfd9b16a6062705eae270011bcaedcae69bb54630d8c78129e57c7", + "0xaeee8d24be4ac0d9784c029e239fb5e64316ce29b88f47394cfaaa8bb966a72061bff72f99d02dc51c9705854686e77f", + "0x90ae09525a16bb2422169e15d6831c87968a14ebc0d1d27e11a759839c73c655b9d33ee5b12f275d6f440688146fbd2f", + "0xa3a41fc7fefef101422465e506bea7f3ff23c26fe35f5732b86f5f2471fb93b37ebc339f84c6be1e8d22abc812c2e212", + "0x86f4b5293e8aea4af1f1fb05dcf99714cb3aff1cfc849b1bb73524061c921c9da9ad92579a852e1889da29d952f02fe5", + "0x8932ef39d4050a1e9dc0fd8afeaf159472d71c5c27f458c69d2730836606ea56e19c8c4febf2535f930d3260e9bc7637", + "0x86307b9f3696bb21c20e4558e30310389e7367803c353d437e9b696039a0ff054d9a4953b75237ab1d1dd6f71118c189", + "0x96e57730e683ef5b550c91de18b19ac73879f3e26234297db68d28747ed0953beb0f3913cfb720c602720bf9330685d8", + "0xb04a19ee70123782e47b238abde55baf60ac0c66292a998af0d14afc8bbeb1134e557b94cd17a020084631c09a0d3c02", + "0x829abc8718be8139569fcb2c398962f38f4201114d30e2b2fb23566f8a27a5c380f5605cec543415202a12ed859e33f6", + "0xa0744fa488c8fa92a722c5fc4ef5a47dfe824eccd87d26c8bab9c174cbb151d44b1b29082c48652f03d3177e5ec86001", + "0x81d4035ae9fd28bdcd78b135cb54955d3b685a527319df6ee7e904b8e6d796f5f5a5f5035ee1de750c4cb6050e452b9e", + "0xb205e8c2ec24d7104fa0106c09ad34b5a912c1adef553fb718838dd627355993c2ec01055c11d00b2c75b68e9516d44b", + "0xb12d09da7968fa7394e449624fc7174d1d76c069ccb03e140d4d87a2d3f6d1f7b9cfc930f0c80becc673406ebe63f08e", + "0xb23752c158695da85048fdf38b395681cc0e8998630af8a9ed41efbda08c9964c2dc8ae6e53377264be4467d702c0de4", + "0xb0d84582fd73628d96b8c1ec96197697c41a963542451a2ade0890af0d33c7161d0f18e1a1ce2c168ca2dc1e9119d55e", + "0x8b877e618b469aa187632e410b125d2999d5738fd66d482000706b51fd904a0c7e7daa8c9b729fa33817bbc4154cba2a", + "0xb1cfc8a7551b601723b937d497d01dec3ee7614c2bf13d430b1058d5ebc1406045009ff02c2ac15bf8cf16f860193d1e", + "0xb6d9da84f97b21e13175bbb0b5cc8e79e88b470c87a3e115726c1bd98e0288526c58f3faaa8aa170ace0cd6a60852525", + "0xad2e773c2d527671ca5fab7085dde4da31cd35f45d4315dd95d8893ff5fb900494dca08eccfc1a2fc7bf7c7fd2fcab97", + "0x8d5a79b34aeb761d4a0c73f09f02e9548e6d382c33ee6887a759ab05762b490b8a549ef2933c7e3a46415c154c0221c0", + "0xb6f2cbe81bd0a7298403be392f8456bed30aed7ef30216959357698f789affd2942ae5fbaf3f48ecebeb7c273b20cb57", + "0xb5b6c45d99cea7ce6a1dc134aff4a8f630f299b42bd59592a7592345f8cd35bcbee944e61b0723de732fcad6e4425b63", + "0x8077d64dfcb2418974e956ea6dbf8a4c05b25d2a025333ad7e2a379f1976dc036771403383a51bfa3476c9c619ef8bef", + "0xad2e0a9d479c77a5fb73b3613a177fdaad50dcb50fed50e756ba18164c153af30b07fb2565e80ff7469f1b0338b7b5de", + "0x81017d1d80a6b6df4e99d0d7f85a8180b5523e8fa2ea2672fddff604933f8a113cab27fce098dcb454d7d1f7ed266e04", + "0x852355479d68e76c7febf6dfe2ef8e80d575c0d3bd52c983803592021cfa898c571c0b884412c21e66f0dbfe03167b53", + "0x98e1bf8ad48421467c93b9f72b47dded7c41b4fcd36ea55ca43ab24b0d0b876f5a731f422579b7167c7138fad2121266", + "0x803369314abd5422019ed4b0ef652b4dbe97ef5a87b0ea373eec9628b64a12120b2c3d4eb53db405131ff786d14c7ac6", + "0xadf2613fc34f73e1160975c140e925ed84d254e03cc3bc7fc1d19957b499c9ba9d9e4c1639981b594a7095c0a52c6757", + "0xa2f6a68efdff6e4173c00692abcfdfcdaf6f8b62369afad3dafaae4f2f38c4860780b4624d185e20e4f4498b75b5fe94", + "0x8b1658aa0e119fb8401d486ed08d60240d26a8623ef9788e3b45ad09ae31259395b021bd16be395139cbb7149714e764", + "0xa7dd8bf21121285e00672ee8bb84e0cb39b2496fb53a26e35dfbca7f2b04e9a9ff9db15f53fe63fcbeafeb2deeaf2ca4", + "0xb6d8d709e44bc18f3b41d69608edce60c02bcba48d3b7e2fd420842657f0665a7343246dea149a25e8f3416284abae66", + "0xaaf744ca5e9bcb63e3e2939b7a1e96e4a93c88c76bec0cf4294dd7db95cdd3f6a7d92196e352d08680e2328bc4592899", + "0x84434b015a7c398d35f1ec71fce455d62ba4ed4f62da042ec31bb2b4db47073314354cd50bc322297a1cfe35138bf490", + "0x8d70b3a3cd9d5dfefdacfa418c0b775a112a47ce538d33a560a519660009c3f141fd6221c18539129e9c0acdaceeeb80", + "0xb8c6903412a800ec78a4c15f31c24385a267b0c0ece32fd31bbbb557fd70c3b2d60d8fc0f90fbd70f43baa1928ea30ba", + "0x8e391dd445ea06cabb433f057853f8159511b2f9bef41aed9ccd14e0a6fcd912bbaebd38fd5fb736cfde0fa34b7a4874", + "0xa40cd988f70613df32babbd1bbc2f1b29ff1ab0147b01161555a81d56c9621657999bcdb1df38485f687afc51d5d0f23", + "0xb6a008b4426b3d7b28ae04eee4698fc8ef6a35d89008ef5394da39ce582ce1a45dcfae9a33b90f6fa4237f3667803873", + "0x8987280debfb175c3b44a2f152ea82548e4f680966f1fcbee9bf7d714e31bf8080c33f52705ef3aeee70544b22516aba", + "0xa78a51a2c11eea7680a5a0ae417a2981f8c69c396e06da621eadd7510a3664ade49d065617bec67b3de779548a4f4509", + "0xa4d9163f0a1bc048385e94d5e0bcafeee1b18f28eb23505623b9e8ef16f3df76408254dfbe790e45f2884198060d388d", + "0x83dcae2568a0c518793c0f6e38b42f9ceb50673d100b556a17ec8bd9faeec84afe50b8d72422c6b2356959667bb8e2de", + "0x874731941be4474b4576226e5906b5dee89fc9b56a9870dcc7289c1a7d494d345ba6aba31f7546a16f9963283c05f744", + "0x82c1cfab1f501189ac20147fc4631075dbf1abf9125b7d42fcb4f31cf73f3d6461b1bd08fdf6e45cc54bc08a7d5d51d1", + "0xb978228286f5d4a10ce027b6bea3021affcaa805340ca4b5192c69e8c56db59f48e4a14a284ec015f53baf97389f62b2", + "0xaf125f4fdccd1c1b64fdffecb5ec7cf8c7392bbe476e1b89a5b5329c5ba4a526e58c11e72ab9de8a38d60af648d75adc", + "0x8411a41ec14295acab0d36389013535a80dfff6e024bffeb32fb3070762f61256419e8c51b2ad6de9dbe4f1e8e286912", + "0x8ea67a91112a41f9c65515cd496f4b0cdefa1400fc06568eef000c9eae6dc250fb7622eb3f2deca10b37287cd96fa463", + "0x8da99b6c55c31dee6a49aabb54da249d348a31d4416201a10c45a3b04b11e99d4ae9813632f0ee36c523b5cca62f6f49", + "0x8b44656341e039e2bd83a19c3bb9a88f6209482e274f8cd4f8557b728e5948dd80b5745f621b96f4562928689314e8c2", + "0xa02d424a615ba0dce8ed91f477e79852215a3a39d025059826fa278e7eebef19824b2a2844f5b3865a0f471b609a23f5", + "0xa1f115cebc3fff3bcf233da27cef19eae791660f155d088003460f75567a550bef0722885010ddc384acdeac635939dc", + "0xb61a55ce9d143c17876776e064b58a10baf0ba13553c785c1e47f57b5f94c0cda8bc89d43d73386e57816c15b61a8ec8", + "0xb4073f47041e20a8e548c7fb00e07ba3b9056c34eb4ab63bb0e7b48f8e338e8b56a17611a1b5f4c03b352450b86f1d69", + "0xa7b1a07b213205b682fc5b6acb7e76fdf97b280c26621d8f3b76b7c1deb3511957da33a4e358c8e8f3d98b2a8855d67e", + "0xb797e67c2670fbd9844e8a68c585f404b035dc14bd4ec75c3f95f932c777f9db5d5f5df7629164af488fc1213035cc5f", + "0x99618200797b945f595794d6468e5c618649554ad9ba896330f1cc844090eb956ae9fc23132912f9047085c5f0c3bf7b", + "0x81194aa1319abf534cb3927af9adfb178a99d0e3e8c99ab1105f1d3b4fed40ec2971caf1d6647acb0c8d681eca53097b", + "0x80673f18e4978dbc226a6cd4b128a1259d9a7f833879c6e2fbe24d69fef2c3c23a51a4f3e8d88fa4533434bbb0723661", + "0x8125bf6c7dbb2fb63aaa3f53283559f172c788223674adbeb6d5bd17cfe888e6b87a79aec774917f20ce911c1f85f8e7", + "0x884bcdb1878b14fc38adc9fb8b4dd0b3afde404fbeb664f26ddfebc81736018551f23e75ce4cfe4865f610bcd454fbd7", + "0xaec65c8d4be8316e98aa54888af01bc6703a0c5d04b69756ff39a0a947b66817ec59d76afe9f61a25749b5e890f03e02", + "0xaa457aaa1b014a4c5a8992847a187a23321bb43452c98745987d038e3b04046102ae859b7a8e980eea978a39d76a88ef", + "0xa9832ee63b08e19123f719bfe2fe742125f32463efa966c7709a98ebfc65277670e9ea1fa2d2d78b96bdc7523b0c4c3e", + "0xa87b6b1b7858f96d55064274f29fbde56067064962cf3c3e2ba3110b22ea633bc037a74d23543ce3307a46208855d74f", + "0x897cbe4ab68a753020fec732dfcc052c7ed9905342b5a6fe0aa25c631f9ad9b659e0ee75d46f0df6507b6720675ee28c", + "0x97c3b5f0d54c1fc45e79445c3ff30458959e406a069f5bbf7979d684195b4fa0406b87c1c008f4075bc9e602ed863152", + "0x921e65d582ea9322ddfad1c855331c3cac81f53c700b96db5305a643c084eb6793094e07944bfd41dc02c3b3cf671530", + "0x8f23ef1aca02a260a3b65d25b110f28d3bafca44727448c8f2d03c5e77eda620c1721b06681bd816ee6027664d76352a", + "0x946a89b132ec0795aea9ff9dde7b77e7feafffe6e4a2f093042a7e6c71cd6ab87ce0ca914a1b5fabad4e1f96a795f163", + "0xa01e2de9db33df6511172123ad6f7c64074237471df646b32dd9aff8c15278e2723108e4facaedca97e9f49503f8c792", + "0x99dcdcde45b2ea3f15279936feede5f7d3b63ca4972f335b0559c2fa6f9faabd8127aa892a36deb114357ca906553ed8", + "0xa3f8af37bfcf66b04d1896a4bd5d343f4733d4c3305369ac7e75a08f20f2004c10c642d2c7577f4e5c4d1f2cd851ac3b", + "0xb7294d15a3d674a56099f97a1adc9e82c15e90832eaf1722df110fc2abc8634c51515e5ad8522015498a3753b1fa8c49", + "0xb4f27f5062ba7a04ea0048b3025b5e3d5b5d319a9e80310c808a5fb4e8e77b38c10a0f3172cb805cadbcc8bc66d36ec7", + "0xaefe5decee0ae2dc372cc6cf4217daf97c4c908d145f100f0daf1ccdfdf641c78432c2e473e7e4b77dcdf2d4c2bb05f0", + "0xacc84af7648a535ffd218c0cc95c8f7b092418c548815f1bafc286b1fe14f6ccb51b2044db3bff864d0bb70e88604084", + "0x84d8e3dac0df6a22beb03742e1d4af684f139f07e2ea0f7fb27fc2d7d4f1e89b5e89f71af32ff115ed5e6092133535f0", + "0x8ada001e1a03a823c4c056f636e77adc0f9dc08689d28de0d99e0feecab5db13abf37b41ec268dbdb42c75419a046c68", + "0x87dac6c798d1744dff81d8bc3e0e04f3c9bf260e811685ddb9a9a8d6eda73927439b344f9a818d2103fad633de5a4a17", + "0xad9929a7d8a7d5d5954e48281a87e5c84f67e19110d73296b9989a09c76767a57a8115629239ffb4d99dfdf9c52ef6d9", + "0x81ac7cbeef8ec35a5c3b61cc887080c29e6cd3e08af37e45830d17400dbacfb374dd07bf370b979828c3875b2027d5c6", + "0x97f92c9182953b7e10f7a1bbb6b5b5c40b8275eb5a6eec1e29874c4712814749aa8c409651380216e1ff01d7b8511041", + "0xa09794d0bbe7db013045d3fd857c1544fe6231d21afa3495fa300371f6301a3a0f4b8ea175b281503dd06078ff371ae4", + "0x839bb58d320aa08116dd387a57a2b9bd9efc89c4cdfd82d0e47a00cabe644631d09be5436bd485df3b61b75ddf81a3ef", + "0xb1cdaa344f783757e8b9c1f84421da3c5be4c69f019a8fd4c1aa5bf1a63e8970c99e35c22cf3b48a0e6738bc6ba7ce8d", + "0x92af68e3216c78998208fb24b5ba0e645d0d3f5e28222b805668d7e9cdd6c033d3b22fd6df4c2d745d7f910d133cd226", + "0x87640a4ea4e605e2204e5232b29a6c1c31152d83547eef14122cb76a0da52b8653801af48455a3ed713b9dcfee7b1ef1", + "0x8147e5bf0c8f4731155ca0517ef3fae5a32b4d5d2d98ed0007b23893d8dbb7f8a1199c50c1750c2fa7c9cebe594b1bb0", + "0xa76b4473c63c3ab6103c729afd2482822e4150f3155af39983b0ff0766c71cb622455ce6304e23853661eaa322219d18", + "0xb3e2f05ca551bc3adec0067e4034aaffd72e0b64ac18ae25452c996927976c6727966e26d213b032521889be2170800d", + "0xa8414cd14cb3be658e9e0004ce511ef7063439b1cbc3166a11de030613fde4b59caad4e91d426927863c55382afbf476", + "0xb2f0f8ab99f4d0ea785ac84fdbc00b20217b1df59b30b51d9d209d489d53b69dd5d82cdacc16fd1dd15c3a4001595f50", + "0x8b2025d5fd658c9bbed619f3e3f6ac8efe7aeff8aa9401bd66a7ceb0062c44b353608ca073f95be99204f0a913bb77eb", + "0x94a46bc5a87291b42024b2137e623c70115b9c6b196604106bfbfa20f3f56ac7779763f56b580190d3cb2f1c648cada1", + "0xaca9355545118d0769cacf69c4b23d6d68d229cd8f68f1bc0c847c05569c5af6bbbd8c4dceb637b4a6b3b5c83841bf5e", + "0xb0731992cab87c7116406b283a84707a34838bfa3284b0f6082dfabeaf41c5ac2b0ddc1b420547a1b0955aee92de2dc0", + "0xb671f77588c0f69f6830a5b28e7d07ed161b81fa9791bb3a24aae6638e3aa5e186df74978a82549c370c18ebee04d4f0", + "0xb5621ed841780f3e6681d880a76cf519cdd20d35197b112eeaa686764d57b5dfa78ffe1a294b6bc76b6e3949cd2a2369", + "0xafeba2524659d00caecf089645611553187a6ed7102050f6dd20f5a19bed08ac7065912d88371ee06242897d58d652a4", + "0xb78bfb83d44ced14a20135804aba3f00128c3ce1f302e95567ce4097b0d973414153fb305b9f156882a5a0554bf25973", + "0x98510aede95d26b1adf214053eae051ffaf24894e2fa37961a91d0ff5392dd09388196648d95b73e90bd88f2587cc4bf", + "0xb35c682d49c295946b9f120fbc47b95abd9ee86d294abb003a92139fb825b509209562575015856a270eb3eea86397a7", + "0xb9641bf685571dd9c478dd2033a1f1b11cd3a662b26502c78595863b8e536a189674a9a85f7a253453ebfd1b99fbd841", + "0xb2ad37036a59b1c9b8457972665720a6868422ed8157b6810a9c0783006103be34ab732d7aeb8629653edd18fd0f1717", + "0xaf0920cff05179a3896ea6ea322c39adf91ada5bc40fe3f6fb1b1b4e121e907c904bbaa8ca00468b3749f3da144d71f3", + "0x8e269672818ef1e2f9e0c8aa65c84442fcd9151d74bb8e870cee8c0e3fe24526e1a5388b430cef47b67f79b4e4056bcc", + "0xaa29a16fe00ea3d143b1032b1dd26b8ce638f37f95c085c7e777e8e2784bd724bd5c38b1583c61a6ec7c451dd78fd3fb", + "0x87452b7435911cc5f513b0c81b15aa04972ecbe3d7bbd0a5d676c96a8a311301c0e07fac925c53a350b46fbd3d4d0fc1", + "0x869a81c351096f47748e41566ae7b77a454b1cdfaa41d34a5742f80df38fbf5cbb08924b6fdff58e3b18f05c62bbbbb1", + "0x8b7bc1b0486300981147a40a449ada9a41afc06d735cce8bf0fab3ee94ba2e2ea57b1397e3cd31bc295352beb8334ef7", + "0x93e93fc41adb2df279d95654921b4c2edf0d293dab58d0afefb221f777349ef88d0985b3447e3b935954a81f1580a92c", + "0x970fa7cdca8324faf3e62348bb50d78f580b4f43f2e1c11bd8382d48d0074a3c55c6407203a0c9cb1c5f2163ba421ef4", + "0x924983929e608d27e4a36d4ed919297869e3c64de51aca794d32d6e90aea546bf898d98ceca28a0b2187734821b78504", + "0x8d395332529c703d943d68415d443332b5c1342ca9d9a59bfa8bd4ab63e93358c4b0dde6ce1f2e8ea9dc8f52ad7ebd95", + "0x80200dda853e588256599e7f905add5d5ee7c74272780317694fbae39318ae9be05d5bcd7b20cf460069743f3d4ef240", + "0xa287d51d6359c9ef7c7ac1b20e479ce7d0146dba5606397bd04b7a622cec642508d5b45d51b31de71f9763595b6ac88e", + "0xa320396c075175d6599225cf2e1de8c7cab549f6316c07feb0f6eaa21f06b2dd29ab14fbdf2af4543b4890ec0fd08a4d", + "0xb1e9fe230418d20368691058adcbbe30011bab3000422f0371015ff8bd09c60fb5fa85d18550d35b1c900977ca48f58b", + "0x9718fc26a51783b971744933f20490e9b5cd9162f86b84788c4c5217f5409e37b5a39d628b18e5b35a757acf67596321", + "0xa0cf81fdb161f4f1b419c5e4caa36d4bdca2325f0cd25b119a30178016f171bd6fb88403e4e3aec026c4089f180d540e", + "0x8ab1e36bd04625ee794ef04c4dcb8e004d61aceb2b62438377f49ad95dcf025ba25eb799280004941e555bf7172af6fe", + "0x9257b9e3d14d37fc7efae49b0c68d36eaac546035f4a2654d566b3ce1b2c4564cbb03dc8ec66efceb768559a8a507a18", + "0x945d1123b839637ab5154a1972c3c83a0ff34a3b1a3465de6ef0416b1950f649869a3ef88d7f1036648ee385265ce2df", + "0x81449639d708860fc0229c94f754f7262e8a3c7f67960ff12dfd15df95f57a9ffcee2013e81978b7703dd42bd5d0816f", + "0xa865481deaae5a690fd53892791e5fa729db283b75a525a11cdfee1ce17e8e7f0b449d25f20b3c1b43da128dbdf98a8b", + "0x98766812a65fcd25b853546e3bba618a3edc9fd61510e4f8ab60c038a7fa50d197abeec8776109df0f2119be9445ad00", + "0xb1b8dd5379d903dc41d74e999b1ab693607a0d2905692f4fb96adf08f738e5d31f9d00df28ccb8b5856145ca552c3e3c", + "0x99d20be7b511bec78a8ed03c207aa4aa9097ba39d85e18f1b8d52f65431ab7e9a773c7b9ac3e8d8b25458bc91bd00703", + "0xb1b7c3563fe8cb33c7d3e0b89d00bdd13e86452ff507c2e69db7b3af06f247f139155396e9b0278753310dc63940a10b", + "0xb3dc9c08451b1de7c9969b1e47574bffff50490f4a16c51e12390195d9e9c72f794790caf7b0a835d64e01fec995d3ac", + "0xaaaa4761a00022ede0809d7063d3532b7bfae90ff16f45e17a340ad4ebaa2fbac40728ccc5fbe36a67ab0e707566c5dc", + "0x8319a1903314eab01f5442d2aee6ae9c3f6edfda0d9a88b416d0f874d7d1d05d08bb482102f8ca70a4fa34836d0840c1", + "0x932949a6e9edfec344932a74d4f81eec3667ece1e8b8ca840ce07ffd4b5d6d8f01657c764d64ac1b9190f876b136490e", + "0x904db1568128487e312fe629dd8bb920cecafd3bb9cad8b63e269ae0129f2f5c80cd82f0d81e7feca9835c3945a72d28", + "0xa17280693d30dcd43c85de8f6b02d5f30cb9097274ad680cede1ef105c903615b4c40f3c6aaca478642de324972514e0", + "0x8d5f76e093aee71d0cdeb017fdfcb13bd068039746de90690ce150a0bfdbe7ddc4d539df0f82c2d2890a40b191900594", + "0x96fa1f2196a3883cdd73c66d28403cbbb58f6a939a3697ee0d308d8a076393cbb4be86255af986869230ee410c01bcfa", + "0xa8b74438dc5cabd70a91bf25601af915c4418d074327a9b01e0190c27d3922c89bb9b41e0b366e82e313edda8f21983d", + "0xac9fdc1a9b2e3ff379eb2370979372e13c4177bf4574f1490fadf05a7073e6d61e703e2d8eed9ce984aba317d411e219", + "0xa45a6c9b958169f2f8df70143e6ac3e2f6f969a4eed6fd9f1c620711bc2454739bb69f0094079464790c5429c0d8aedd", + "0x8901cbdd1009864386577842c1e3d37835fddf834064d9613b4559ea9aef3084204e1f863c4306f874141f4374f449ff", + "0xb6c582161691e3635536686825be9c4d7399d668a7675738417e0363e064dfd28acdbd8dbc9e34c1dab8a1990f1f0eba", + "0x89e89ddaf3cacc78428f3168549c161283ca8337345750667c98212717b21e7d994eae4e45bbddacc832a18df1d79276", + "0x84be275627eed8e1a73c7af8a20cee1ef5cc568cfeea7ec323d7f91b44e9653e9aeed47c1896a8240b99dde545f0e1fa", + "0xa779a54ab4f40228f6e2539595fb8d509b70aab7c19e1928c1be69ec1dc19285c3898cf15e5f8b8bc725e13af177fe17", + "0x92e2a49d2b9b36349d442283b17d46f8f9bf5932c34223015ce62d2f285e7363b2c12232be4a838b5b6cf08e694c094c", + "0x8b4e28c6f3f36caa2cfb82ba88066c830f8017bd35608b077143dff236f3181230166f5a5c02fa0e5272297331726aed", + "0x85fd77d46162ffac4b8adb25baff0eb0512a53a3d01638b3a376ea34702279ce21c8e7d8884308c03e00c9bcc1a9fd29", + "0xaad5e46916ff1be29009b595d1d8fa160cc7aa01c7fbf3a68f445c87615790dcab1fcdbdceda533d182b6541f09f2f73", + "0x948df7654726250dae393325addd3c0a20431c81f00470962190335ea4b6d9f7463d6f308cda46b92084c1f24390b1da", + "0x8f577474dea132676504376c5542b730b6604fe3d965eaa194659fd11c52233bd0b11ab62e198c0f442327ff1c00e501", + "0xae2f1001546db3e0c19700adad997cd9f765fe7a51a502cbcd9a2a07a3a5db79c8f603e05cf96d80b688cb6c9b6cd3ae", + "0x953b68e5d9561088dd20406ea7fb6894cba33868a38ace38fc30b5813140cb15dd6dd2171befae5b4df2e4a9658889d8", + "0x86c52901655ff11419b084a04da8fc3596eae59d81d3461601c0baff59ba59e3d1dd0b7ce719e741a3e97c013e898579", + "0xb9a72dd5eff73f9912a28b55de073568efb3eb0241a10b77a2bfd4f30c2aa4fbfe0c89eb345c9f07fb725660873cb515", + "0x8e7353f5f2932e4ffd95811caf46c9bd1a53643c27eb41a4ebd211f230955cd71a8b27e17cfe8aa708d8514c0de67a66", + "0xa096b8e66312a92fb10839ebe60189a8d1bd34dff55f7dfae85e4d2f53a1a4a88211c19fc84494f066358ddce82be131", + "0x931c5cd82719d76596832b007969b5f75d65cffabb41b9dac7910300db677c1309abe77eeb9837a68c760bb72013b73a", + "0x8ba10f5118d778085122065b55dd1918fddb650cce7854d15a8f0da747da44d7b12d44fc29ad7dc38f174be803db74c6", + "0x8c971deec679372a328587d91fd24ab91043e936ca709c333453d7afd43ee256d08c71cb89f0ab0e89ae119831df6d86", + "0xa2ac28a58034fbd8fd518f409221bad0efec52670880f202e09c0530e2aabc2171ed95e99891790596ffad163d86c110", + "0xb3354e3dfa8068aba4f3741152b9204baa4e342c1cc77e6dd1419cbaf8da1d118be605846b8609e997d6a62a11f3423a", + "0xa12ab65a213c9d95c24865fddc2dffe0cf9fc527dd6bcdacc1bd7271e79929a4ab3427a231f4f49d0530474e6cbc88f9", + "0x90afd65b7e6973f8aafbe74da0f42441840d3c93bd69bc1bec8fa56824e7ca97ad1b427c8a85da7d588469bd4ccc50c3", + "0xa09175940c59489bac3d3da3a4091270d9118948cbbdd57f2bcc63fbf45b8010651c801d3e58dccf42733ce1d6b446a3", + "0xa843bbf286e3cecc1fe370ff1bcf5f1001bc2e95b34246625ff50d48ee62343e82fba2d25b8a4bd5f7b5ffe90920efa2", + "0xa3c4d1003219157fdbee2707ce07afa6c2a64ae8e450182c307ed7f070024071f30b12c4b0032960ff913c74e73a9976", + "0xb24af3f68d66f825d06fc3ff94fcccebe28b1a0d4ba29c48d3a3c953b9bf7ae6707f193fef25e2dcbd2b74e483c774f0", + "0xb0f657f7723184ef7d7e4381143f1ac8020d8c6c6f2dcbebb0eaf9870d61a81f2d452596503311e46d1b38f625d4756b", + "0xb90091004fc8f6205c51bec68547ac82dba0f5525631e7632cf6efe54eecd9020729fbee6105d1b8012402d3b79c54aa", + "0x8e3fa187713c60eb0a416d6900a894cdf81e6b6b69dae0bb64f6287f3c3f030cfa85c665f7aace1eab4937f380b8f728", + "0x879bf0784ccf6725c9cd1ea8c49fde31c91c605de1ea664a33c2ce24c277ee45d20b66309f98d989acb2ff3b77e13101", + "0xaf3f3a3ddc4e11abd627d5aef8adffa91c25df5f0c68b4d2b5d51e7d9af3395ba4f6f7ae2325a6672847e1ecc6cad628", + "0x973e667289e796d3a40f072e6fea575a9b371a9997cf8961677f8dd934619ddc47c1a3efe91bae9ef95acb11a8fe6d09", + "0xafa81c5606de82f46b93f4bb6db3fc0670f4e0d1091388b138a66b3827322d95a56168c951c30831d59eeadc227500bd", + "0xb83eff77db5b4c18574662942eb36f6261c59f655f8a9c3d3731412d0f257c8e80aacc995c4b2303058a1ba32522a434", + "0x912e5ac9234b9445be8260393ff08e4859a7a385e800b74d1534eeb971f58f74cfb518dfdb89f8705d89fbf721439129", + "0xab27c8ece4a51d23e22c2e22efa43487c941139b37ea1182e96efb54ca4809d8245eae0ebe8ba94f0ed4457896fe11b1", + "0xa6630585d104a745bc79dba266d9292bbdad346449c8ee8140a5e6e8a6194411df9cdbf3d3ef83468a536d4f052e9335", + "0x8b8c128244da48e7fec641a882d0005a2d05c7138d86a293e6a0a97c76bf632b44767d0ce44663c975e7f9f9679e25e3", + "0x87dbcaca67351a4e7d2297d7cdba4796d12f58857e7ee4abd0645563577ff33544a44cd84e50b3a3b420d6998de9b57c", + "0xb859ba43df259d7f8e7fac70bfd7aae546d57a5dc90e107b174a95bf7fd3cf00f740c4434848e69b2a7e6061f66c1ef1", + "0x99d6e20978fefc40c6d310187eb2ad3a39296f189ee122ed64d74f81033c3069d44f7a9d3988a1df635b609603a17272", + "0x99a5ddf3420cc0c92b21f71a805245608d4995ead447d8f73a670d26d33e26920d5f07bfe1f6230bd5f15978055b4253", + "0xb936ac0944d3c5e4b494f48f158000abb37b80b5c763f77fe856398c664b0f1ddbcc0a9a2a672db9278f08b4bafbe2ec", + "0xb4af85fbf4040e35a686dd016adec037c99b47cc2e4dfccaf7870ee9e8c97bff30f3035992def2a9d4af323c0b3af8ae", + "0xa5ee32b8bd5f8fa9000da4da0bf00565659a43285393d37080b555d0166bde64d87317b2eab2d48a0e7b287caa989be2", + "0x894d4ad58ecb1c9ebc4f5a97407082e56cb7358d7a881ba7da72321c5027498454f2c7fa2bd5f67a4b11d38c7f14344a", + "0x965be9eeaa0d450dacc1b1cc2fbf0d5d4b0dd188f2c89aaa9260e7307a2a1eb22db6092fccb662269e9a1abfc547cabb", + "0x805893c424aec206260c1c2d2509d2cb9e67ee528bd5179a8417a667aa216a3f318ed118b50d28da18e36c01f0805e3f", + "0x972d7040d4963b35260ef0cc37cd01746f1a2a87cedc0dc7b0ee7e838c9e4573784ea743f563b5267eb3905d4fa961ba", + "0x8c7156991d4c2e561888feaecf501f721b4174e7d14109e9deeac5a9d748301c07e11fb2b04b09799f0d34ff42cb77d1", + "0x894722ac35af3d507e81d737d21e16c5ba04686f8f004aa75934aae5e17acd3e065b96e229eb011c2f34096f4c62048b", + "0x81237937c247c88e8e31e2c72412189fe59c1daf65c5513489d86cf29ee922c0bb08e5f7890f09f4ada7e5262083d266", + "0x8cf62cda2fe0d9a6b42aa2a1c483f4ad26378c7cc2c2d1510a76df7560b07dba8528b33aaacb15f7f20b9d4c7c9f61f6", + "0xaaf0921fb3e1920eee5d0acb59dcc268b42f4b435d60d25d30357edd7dd758d035919691bd15311d85489dfa2e5ee696", + "0x92cec07be2247ef42002ebcaf65ec855611b8e893a5675796f2225f55412201b0bf9f4761924d0c8377b9f131e09e39f", + "0x8e514a62ac1e91773d99588415426c97ad63e917c10d762fe06ace5277a5c3bf3730e4b9e5d116f8493b9ab8687b70e3", + "0x83932df2d923a5052468a3ea87f7b55c6a80ede3594046ee4fe233046570921822bc16555b92ba6aeabaef9b1dc0805a", + "0xa2b5bfb249de3472113fd3f35bfabf3c21d5609da62a27ea6aab5f309c9068d94bc58ba03efb4ec11be06306d59e60e8", + "0x8106cf3ebe6f0507be8c6e8d137987315fe3689ecb75bb27980f36ba5efac504baccea0e7603549b6d126beccc278804", + "0xa73ee70b6fe8c082443972102c453fc0e386852476cf22224fc0bfe554735c12f96037fbf10922795f4502c4f052b5f4", + "0x932b27e175440169958504f3ed6400e7d6dcd5e716c19dcd0f15c56c04503ed133d5a993e111c016f141e32d68b29886", + "0x96f7ce4595318e0b4a6b368f788ff82226aac676aed4ace343867f751de414453a9aaaabef6e6224ce5aedc3d5cf77c4", + "0xa950c1e3bc9a14484997013d44d876374b939af437ae7c821c131fb886063ee9fe7214a25a0c7084f0b07b99412eff75", + "0xa9dba3886ed6855303106a1bdd26010f294218684e1c178afcfea3f37a2f04fd01724a31d82de3449046617e3507a115", + "0x87a2f776b32a6b550cf3ceeaf78db02819be74968d228b1d14e0d74a1cdf994bb500b7abef6619455e98d728701fac5c", + "0x8cd887b07e335edc0b27e6a660cebb64d210741395be431d79d570139687b056557159407459799a8197b6079644f666", + "0xb81a61fce00588909c13a90c1caa150f15788786af443ff60ce654b57147601f7e70b95659e01f470334a220b547611b", + "0x8aebc51141544c5f3d3b99422250424b9800031a8fdfbf22c430907a3a446fecaa2392105d66d64b1c8e847240da4a6a", + "0x90db7dc12baa02f3f86d3edadf9434e2b9318d4f6f0eca08276b765dbb38d8eb0d08be2fe70adf2bf16ceda5db08d3ca", + "0xaa1839894152d548cc6ad963de20fb6fcc843bc9af2a2bf967c63626b8ad19e900894d6106265f38f3afccca317c22f0", + "0x848e27b741496988a582515c0c8847b2bfc6a001259396cdeea1e1b1d2828ca3a626693a1bf4adf3a3d7f8b1fa3d75fe", + "0xa0aa11754d4ee136ac3ca609b17bcae77758763b2016544ca7921dddedd8aafcc7ad5f2b337c8bf53084eb8e43ea41fb", + "0xb8713b7aa1c112178195fdcc9b7024f46e6bc04c4e76c41abe620aa265287809200d98eaed6c9703fa97e81d6964f0ec", + "0x8605b5b33309e9ea6823542b85383c496794b8481c577497aaf99ba90496e794dce405be615bf92c7b6361460e6b82e3", + "0x826fa34faa7f83e063a7bf172addfc07badabada59cfc6604fdf481d29085251c0a67a1355b2cbd374e2975934b84cb6", + "0xb45d131082dc16fa53af010d43eefb79200dc23d2f3ee26af95ac6a5cebc49c84a9ed293e534ed16ff3ef9a4a25456ec", + "0x91bd6ce3c5396a7a0de489e49f0cdf6dce1cd2d0be7a410326423c3185bd1125ce1e610768be7f15f4e44b62f8834fc3", + "0x903ffbe3d33fbf106c01c727dc3a385201a67ded70d4df623934882f69a3a96c909b027a124f3d70cb072b0046a149e8", + "0xb405359db9d9ef4821a181b440ef2918c240595141d861d19a85867a5afa74d2972d22c988775eab441e734700bae4a3", + "0x8abb756d027233c83751910a832b0ef4d28d100077f1c5d656720c94906f91d85dd0ea94b1cc0ed95b692efee14c786e", + "0xa78ee77ab476a41a3454160ba7ca4085d8b1f7057c63e76db8b07cf20afdeddd2250cd00771a6329133bb4ad48ccc20a", + "0xa41810271d8c37197aa9b3dfcefe3498e42f5978d3f3d59defff4676d6402d8575b40683834f184f143b6cfbfc859b3a", + "0x90c24a0750242660bcc6d487358a3cc015730538a0a8beb00ad5ac2ef33cb8ca8a62121e50bec8f3d2f43900f8e3134a", + "0x8b96c39695d864ef5796941754978a1fd612b369f6b77fe5ae6587beac936ee28190af8f0a3822b63060af35e49a5c8b", + "0xacde2548883d0e63c0fc257bb9dadd919aba60a985b69ebcfa1bca78acca42fc1322ec30bcc8e7c188818f858d04ad33", + "0x895c86ae9ff8d95f2707d4838a3bc8ddb05b2611f0476f014b9c150d0e8332bc73285037a747426f09ac8179ba4e19fc", + "0x821761fe406e18bd86fa9ca9db99d382cd3b5c70c456f471fa3706d57763d147706304c75d54f51ce8f3115aa26e59d9", + "0xa803a80e3e8f47dc3c59ea23eafdec017458eac648b360cd42cbd075e0dde6f6f450b48c7646fb1e178c04f82ae51a12", + "0x91f40e1b6f588bd592829ce937996452c40be0fd6c43793c607866701ac6a8c7227e0891d45c6e7b1599382b0a3fbdbb", + "0x9408246d996a634a58689337f2526dfb3ba9ffef1d3ff91c32aa8cbbed900861ef25d6477308b67d76491edfcc70d65e", + "0xa492325a427f3df1c9c690c5b553daa8ac41f62f5ae55f425539222bacf959e2f67afabbba1732e120d3e7a6dcdf7049", + "0x8fd0c3e15477cae228613a171b6e9ec29ddc63ef74854d99b638adeffe39f89f34346a42851e8445e855a9f2bbef0f57", + "0xb735ed01fafa051004dbaad5e8c9e2faca8f6049ef9b590f256ea4d75b04594af12764ad4e6031735eae36f83179db93", + "0xa7d35f43fca06c86b3425dcb68a87186834ba9740664fd657915771beca4cdc0fa2fc9b4c2e9d9bdad8ec33543ddfa59", + "0xa1156e71e2db1b17df5da28747c88e091bd687bfee59d89096437ab4dc9a543fe5c5272d5023d72adbaab397a6fc94d1", + "0xab06a58bd81b33a411bade8d8c5232d38fadc2e38507159edea6e2e104b8ebd65ca02b05335118f691d44197b847a4dd", + "0x848b67a10f1e6ff8f5c228f226ef2ffeb67fb8f50925fc94cbb588d61896d9dc79726959e649898fd3354fe3ff7b7ee3", + "0xaa933397361f32b388edcf832f0db172a38e756b34d5f7a4a050fa7325058006c22cede26ee27917e8f1b0f301792bd7", + "0x89e49e7f02cfaae4a4b9c4180c9f6559d76e3a45774955859d4147970b1470dac37bdc9aedca1c32a20b045049161590", + "0xadc1825d5ab94fc719f25d8c9773f4d518134ed88eb13ac33cb910b2be3523ef9ef88d9e4aea2418b806e20108317bf6", + "0x96c4b444c8a023da644f3a343ebeeed19a8392d2ce175992461451c318a54273b76c3574d8f2dceda2947ddd34d1a674", + "0x8aa7e97e87c8c5b29bbd51a6d30396a6be1fb82b716ef83800f2c36d5b85467ade7e0f59d2db82c310fa92a9265f0b03", + "0x9146c32d99f02c3a6f764dcd9b4807f1585f528ac69dc4f84e4380f6fda4f9d5057c375671d51e7aca2b2b4140e83da0", + "0xa10760a533d9bc57536bcaf65f080302086aa50225437efd64e176841544711828c23a15c49c0dd1f357d3f10722ab72", + "0xacb0811777e17f7ae7aaba5f6fce81b759c067a4908730916195a2505c7450d0e6e2194c2ef0f241090597d58e70de47", + "0xb24f161e9bcdbad56665e2490b5e4c7768390d4668cd69a04ed74739062dbe832636dd33cda89e9b0afa8c77e93fc641", + "0x96b4d01106b831868a88ef016500ef2fa42d0ce87a37ca8ca4194a92a22c113edfe04eb2ca037329f3c1acc635148f55", + "0xaebbb95fb4f7adcc8e7a217aeb73f9e037cbb873d08c1cd9d68c6c6834511adf1af8b44567fee84327599bdcb734dedb", + "0xa9bd8b17300532fb94d028659bcafbe7bbdf32f8945baf5db4cfaa1bac09e57c94cad0ba046b4514044b8fe81ea8596d", + "0xa5557cbda599857c512533e7cadcf27bf8444daa0602aa7499cafc1cf1cf21f9d16429915db7485f0e9a1b5046cf01c5", + "0x8810307c40bc661c478a9747ebf2a30e5a5ead942d1ac0418db36ba5db0709c476f7d19685cabe6959e33ec1f3bff914", + "0x8829b741f41f2c32e10b252d9338deb486dba2f23996a44cf1dd888ad967a589d51329be34d764139f372a1043f6c2e5", + "0xa6b4728d18857c5fa082fa67bfb3b1d801e76b251b1e211a19c87cea5fe7ce757f943c85071f7a03a718388cd5690e95", + "0x86da7f397e2533cd487f962ae58e87bea2cd50af70ef2df9ea0f29f70b5843cde664d30ec207ab84fc817f3851277e02", + "0x8085776ef4ac6d42ab85b9d9135ecc6380720efd274f966544eeedf4684028197de76ecab919fa5414302597e1962bca", + "0xb05a065c733033d223ba13d16baa7a97bd8c8b8b1f0e59a9bdd36ee17e9922d48eb39bd180c168b122088a77f0bf321a", + "0xa89343fe44a93023dcc7ef71bd3bcb6786f68e1885ad260edc56a52445d34757f476395ba7ad35437f89bc573c7618dc", + "0xa114a9cd6105b524f3969c69faa2e09afe21753a93361a296f9e0e3b4e3e63726ddf2e6bfd3ddc046043e50bd44e539e", + "0x8a5611fec539cf681c05636bb580f29acc06f628bb012649ffa41ea6c1521194a5643d5dd843f09b6eb2c3bdb4d41acd", + "0xade247c4011ec73ec90b72f35afa59a999e64ba5a7e664a4b30874fea53ba6a14a76a41b58a5f891a20d019e5f091bdb", + "0x905b5d96df388160ade1ffe210d0c6d1979081bc3de3b8d93ac0d677cc2fc2dc1ef6dcd49d3947055514292a3fa2932e", + "0xa9520796ca9fccd11b7524d866507f731f0f88976f0de04286e68d7cf6dbd192d0d269f0cd60fd3d34011a9fe9e144c2", + "0x989a1edf4d7dae811eb57a865c8e64297837ffeeaae6ee6ac3af0f1044f023f1ca552bf00f1642491f0f0f20e820632e", + "0x879c8e63713f4935ed6e020559e140ea3073ced79d3096c152c430141272117b4fd9a9fc3eef012e81262df02ea14bd7", + "0x95074738ac1540c0312274333acd1ecad9c5509fee883c4d9295fa8d8200f6e637c363de395f9fa612f05c0dc58fae88", + "0xa770e4fc595269eb806b113ab3187ea75c8f96b57bf9fcfaf535f3eedc1d4d7e6285a20990575de0ff09f62d06ed0692", + "0x81283e5dfb6423439ff513eca1cc316941d196df8da2d1069d2d0b63f5289e630af2fd4119bc0144c002d33313372dab", + "0xabd1b108e743887b78f698f2aba9d5492f87a22868d1351d705d93a1084fd45be67170c68a6e18b07f400d9a01cda8c2", + "0x8509c3f67b92908cea8144f4e2a71631a66a61ac3547601c788907e52e380e5fe8ae4110aed95d13c67d3bcdd5b55a61", + "0x8fa5a790ec5cce6d4114128c295390120869aac5490a82feebd3c37a167120df2e7fdfaf2a4050a7dfebf48fb093212f", + "0x944753e1ea7d8bc727d46a7702077dc01dc0c6574e8263a16579b57ee155ca5901f71bb347a01a9a922b329d3ff75135", + "0xb46bc1fd4590b7a6275e20036d247c5909fc549c78e95b64ae7ed96e3b05bb044840f19f7650ebfe7008ba09fa83c3c9", + "0xb1e47e4d88e59a06c465348c6cc4181d40f45b91e5e883966d370c26622c328415c6144aa2f61ddb88ec752482c550ca", + "0x8bd4f8e293e3f1815c7e67167618fb3b0ea76424bc0985908957cfcede36109378e41b4d89555b8c2541b4c447e00461", + "0xa70589a867b2bfb63d0106083d58475d506637148549ed35c83f14e5c8de996e1b1f3447ecc80cf5cd134ef4db9d2fb6", + "0x8048b80ba6131d07370162724127b0f7cb17fa7f71855e55e5a75bd0a9e4fd71b0d0ea2d16ec98858e458528df8d06b5", + "0x97326cb94bae7530f4ec3235770c5a7ba042759e789d91c31fedbd979e3c0e6a2c69e2af3c1979c6fe0094274dbd53ce", + "0xa18e9c1d3eabd62af4e31a4b8e08494f4167fd4598c95d0123f39c46c53f9e93f76615900246e81a286c782ac37c569f", + "0x80309c59d4522b15aba617cd3c6238663e8b1c7ad84456346082c8f281140fc0edf9caa19de411c7e7fb809ca4fa3f4d", + "0x8e450c0990e2f65923f252311623038899eeff7b5c2da85b3a224e0ef7132588b291b782d53c477ecb70f34501466178", + "0x87843f96f41484e254e754c681a65681b9ae5c96c292140368743df9e60f7e2ada58ca2bb95fa39abe064b2ebf21eeba", + "0x858e8d5bf2a1cf26d8af5036b28b831d450a446026f58a1734b696c18f1f41482796b91cab0e5b443dd2f0b9cffa52b4", + "0x99627dd6bad8c05c5904cd23aa667d664da846496dbbb8452705c4ec01e1480e9c7295504a5a8529e4a0c842306b038d", + "0xb64b33256c18b2c886a837a0c0730fdfe73befb0e2796207c4dc592c5a33cd51f8c2ef47c584dd5773abf9ce9c1b0082", + "0x944f6da2a1546f0bfc4d98c3e73c79e935e33d208b6be26b0b5f8df6d0e3b74a5bda649853b99281bd3a3ec799a7dd04", + "0xa266d165435784d4e884640155e35b2a911b3f89e1e715986de419b166a36a341ba724877d80583fa3da566f6a828971", + "0xadff2698409d0756e78c534032ee926560c13d578cb178d5073172d049ebbce32a92692f7e2033ec781b9b0d894ddce0", + "0xa91933f110756c699c28bf9e24fd405bf432002a28c4349e0ca995528e56a5a2d101b8d78afa90a178ff1a9bf2ba515c", + "0x8e77839c0eb4da2d01e4053912cd823eddffbdc6b9c42199fba707ca6ab49fc324288b57be959fbfb11d59085d49324a", + "0xaa124517c76692036c737e987f27c2660514e12a953e63ff4bcb269dd18fc44dae95e282de8444bed09639ef6577af88", + "0xb285deae99688f1bd80f338772472fa2b35e68887c7eb52c4ef30fc733812444c5cd110050275ad999d5a9b57f782911", + "0x8877b0fa85b44ef31f50bdb70b879fa6df5eb1940e2b304fd0c8f08abb65f3118fa3d97ff93919038c1e452fb1160334", + "0x8a89f3b50dcbca655024542ca7d93df17deff5c7d01c7da2bdb69e76b3e0b4490d85c800fb3debb4b0b4d20c9527f7ad", + "0xb7e5dbe36e985354ac2f4ab7730fea01b850af00767a6c4d8ee72e884d0fe539bb81f2e34638fcf5d07b7c8d605f4c06", + "0xa85a1d78f6d4f9d5d83ec0f2a426708342d4e4a5d15625554e8452f6a843d9aa4db0c7e68caebdaf767c5b3a6a6b2124", + "0xa518078a9dac63c5bf511b21ed8e50d1ccede27ebfe9d240937be813f5ee56aef93dc3bf7c08606be1e6172f13f352ce", + "0x91144eedebda4d1ad801654ef4ecd46683489b177ba1de7259f7dd8242c8c1700e15938e06c5d29aa69f4660564209a0", + "0xa16c4657bc29d1d3271f507847b5a4f6401cee4ad35583ad6b7a68e6c2b9b462d77b5dd359fd88ea91ce93bb99130173", + "0x85b855778f4b506880a2833b8468871c700440a87112fa6a83fd3ddb7e294b3a232d045dc37dfc7100b36f910d93c2ae", + "0x8d86bb149d31bfbf1fabcae1b8183d19087fd601c3826a72a95d2f9cedb8bb0203d1136a754aa2dd61f84b7f515acfa9", + "0xacfe7264eee24e14e9f95251cbcfdd7e7f7112955a1972058444df3c2d2a1070627baefada3574ebd39600f7f2ea7595", + "0x906bd14ecca20ac4ae44bff77cc94eb5a4ecc61eba130de9838e066e8766ed3b58705f32c650e1e222b3100691b3806b", + "0x8f2cbc7b8593c4be941dd01b80dc406fe9dfdf813ef87df911763f644f6309d659ea9e3830ff9155e21b195fc3c01c57", + "0xa68eb15ed78fae0060c6d20852db78f31bebb59d4ddc3c5bdd9a38dbe4efa99141b311473033ff8f8ea23af219bc8125", + "0xa95cb76c9d23fc478c7e8a73161f2ff409c1e28a2624c7d5e026e3cee9e488f22225a0c5907264545a73e83260e3a4ec", + "0xb76f90e55fa37c9e2732fd6eba890dd9f1958c1a3e990bd0ce26055e22fe422d6f0bcc57a8a9890585717f0479180905", + "0xb80cc95f365fabd9602ec370ca67aa4fb1219a46e44adf039d63c432e786835bb6b80756b38f80d0864ecb80e4acb453", + "0xb753c86c82d98a5b04e89de8d005f513f5ea5ea5cf281a561d881ed9ad9d9a4be5febb6438e0dba3d377a7509d839df0", + "0xa664733f3b902fac4d1a65ea0d479bb2b54a4f0e2140ed258570da2e5907746e2ac173ace9120d8de4a5e29657ae6e05", + "0x9479722da1a53446e2559bb0e70c4e5bf3f86c0ce478eede6f686db23be97fcd496f00a9e174ceb89ab27f80621f9b80", + "0xb707fd21b75a8d244d8d578f3302d1b32bb2d09f2bd5247dff638d8b8b678c87d4feab83fe275c5553720a059d403836", + "0x93214c16831c6e1d6e5a1266f09f435bbed5030c3c4c96794b38d4a70871782002e558d960778e4465b1ff296ffedad8", + "0x8648f84e18eb63dad624e5fa0e7a28af2ee6d47c28f191be0918c412bf24b5460c04bf2b7a127c472914a0741843f78b", + "0xb67f61e75d6b773a6b58b847d87084b94f3cdac3daa7bef75c2238903a84250355a986b158ff96ba276ca13a6035fdd6", + "0xae9b094b7b5359ee4239d0858d3755a51aba19fce8ad82b0936cca48017523319c3309409ea6e9883a41bece2077e4d8", + "0x8d1d8e1fba8cebd7a0e1effea785a35e16b1a10842f43e2b161d75add11eccf8f942d2ae91c20eef6c1a0c813731ea9a", + "0xb82bd387458e3603782d5e2dec32ae03890a3fc156d7138d953f98eff4200de27c224f626e3648e80cd3dfc684c4790f", + "0xa6dd02a89ad1c84e25e91176c26355e21a01b126c1df4d22546159dab9d502dbc69bc0d793a017c1456516e4aa5fa53f", + "0xa9ab74a5c5459b8500beb0ad13e9cfe2656e966dc9b4f3f98bec7588023b4ddebf74e4fc722d30423f639f4ee1b2587f", + "0xb03e5f33ab7ecec12cbc547038d3fa4f7ea0437e571891c39660c38d148212d191be29e04eb2dc001b674219b7a15a9c", + "0x925df4fc6e898ca55090ad1a8f756cc5014167a042affda5b24896eeb6aac408545134920586a8e1a2b997de9758b78a", + "0x98c8580fb56ed329fad9665bdf5b1676934ddfb701a339cc52c2c051e006f8202e1b2b0f5de01127c2cacf3b84deb384", + "0xafc3765d374c60fac209abd976fe2c6f03ce5cc5c392f664bb8fac01be6d5a6e6251ac5fb54cfcd73e3b2db6af587cbb", + "0x8e7e98fb5a0b5b50d1a64a411f216c6738baaca97e06d1eba1c561e5c52809b9dab1da9f378b5f7d56a01af077e4f8cf", + "0xb724bf90309651afb2c5babaa62dc6eac2b8a565701520fe0508cee937f4f7b6f483fc164b15d4be4e29414ce5d3c7d4", + "0x9665160e7bf73c94f956ecb8ba8c46fe43ae55c354ce36da40ccc7594beae21d48d9c34d1af15228c42d062a84353a0c", + "0x8600ab3aa86b408ee6e477c55572573ed8cfb23689bbdadf9fccb00161b921ec66427d9988763a7009b823fa79f8a187", + "0xb0d8d19fd1022e7bc628d456b9bd1a2584dce504eb0bf0802bdb1abd7a069abbeeccdb97ce688f3f84a229342dbc1c33", + "0x8f447d5e5a65bb4b717d6939cbd06485b1d9870fe43d12f2da93ca3bb636133a96e49f46d2658b6c59f0436d4eede857", + "0xb94e327d408d8553a54e263f6daa5f150f9067364ded7406dcb5c32db3c2dffd81d466ee65378db78d1c90bc20b08ab3", + "0xb58c02781b74ef6f57f9d0714a96161d6bfa04aa758473fb4d67cc02094cd0c0f29d0527c37679a62b98771420cf638b", + "0x8cfa0a687ea51561713e928271c43324b938aa11bb90f7ffaa0e4a779b3e98899f2af59364ce67b73a46a88748c76efa", + "0x95d6d39c814c5362df69116558d81ce6f1c65fb400fc62de037f670d85f23f392c1451d43341c59bc342bc31842c8582", + "0xaf888b384c52d9e04e4db6c4e507c2037eb5857e9bcc33acf84fc3a02d93cbde8cce32141fce9f5fec715b5f24d56356", + "0xa7822bbc3c236fd58bd978f0fc15fe0b60933a0c953db6436a233441219418090ae0c07c490a6548e319029771cdaba7", + "0x8c53729f750922e5eb461774be8851a3f40fe42eed170881cc8024d590bf0a161d861f5c967144d15cdcdc3dc6b5cf88", + "0xa052a25a4aeab0d5bb79bc92a6ae14b5ad07d1baca73f4f6684ccecfc7ea69bc21eadeb9510452fdba116c0502dd698f", + "0x923946b83d37f60555dbac99f141f5a232728c6eb819a37e568c8c6e4d9e97a4229fb75d1de7e9d81f3356f69e6d36f1", + "0x8cab82cf7e415b64a63bd272fe514d8b1fa03ba29852ec8ef04e9c73d02a2b0d12092a8937756fdec02d27c8080fb125", + "0xb1123314852495e8d2789260e7b3c6f3e38cb068a47bdf54ed05f963258d8bcabaa36ccbea095ba008e07a2678ec85a7", + "0xa685b779514961e2652155af805996ceb15fb45c7af89c5896f161cac18e07b78c9776047c95b196362c9ad5430bcb22", + "0xb734dd88f6cc6329c1cb0316c08ade03369a11dc33191086c6a177cf24540c7ceee8199b7afa86c344d78d513f828e81", + "0xb0bf492fb136ecdb602c37636ed4deef44560ab752c0af5080a79c9f76a1f954eba60a0bf6ba8bd7b8cac21848c29741", + "0xa5c74682323e85ac20f912ab9c1d6e1b9246c4c829dca40c8a7d58ec07ea0ad3524be30623f351269552f49b65a1245c", + "0x837403b9cf830fb33ecc11a7c8433e07745973c36acdeb3fc9ea8f7d8d690d462e1250b7410f79f2f4180fe8f3962a4f", + "0xb03d64b944d49c83608f2c5b9c14070c025f7568c4c33d4eeb1da31d07f0bc5897e498b35b50d557ee129f0c3c68e254", + "0x827272aab8bf757e2483156e00fbebe1093a58070dd3af9855bbf946c7abfb9c8a850a6a8acda8c620902f391f968b8f", + "0x84c4eb863a865282d321302d06b362f8bd11c2bb0090f90ebffedd3eb3e7af704cff00d39a6d48cbea4262942e95200b", + "0xb044eb91653dc55dce75c8d636308a5a0dae1298de4382d318e934140a21ca90e8a210e06fdf93aadbbeab1c2ef3904a", + "0xa8c08955a4378522e09a351ecb21b54025a90f2936b974068e80862803e7da2b5380c4b83b4b4aad0409df8d6c8cc0cb", + "0xa763a5fb32bd6cb7d7c6199041f429782deacac22b6a8467077fab68824dd69343ebca63a11004c637b9cb3129dbf493", + "0x8c44c8afa9a623f05c2e2aba12e381abdb6753bb494da81f238452f24c758c0a0d517982f3999d2537b7279d381625ed", + "0x8613f47fda577cd3bda7c99b80cf4b2dd40699edfd3df78acb5e456dd41fd0773bc8da6c5e8cbf726a519b9fb7646ccc", + "0xb21a30d49d7e1c52068482b837a4475568d0923d38e813cea429c1000b5f79b8905b08f6db237e2eccf7ef3e29848162", + "0xb9bdf4915f3fbb8d84cdfd0deedf2c9dc5b14f52bf299ef5dca2f816988e66322df078da2c54b934b69728fd3bef40b5", + "0x993b45f389f55eba8e5ba1042d9a87242c383a066cbf19bc871b090abe04de9ff6c1438cb091875d21b8c10fac51db58", + "0xa85a95d14633d52d499727f3939979a498c154fd7ebb444b08f637b32c1caf5cca5e933a2f5d94f26851ae162707b77d", + "0xb9874c7c4be1c88a9646e0c2f467cd76bc21765b5ab85d551305f5ec0b4419e39d90703d4ac1bb01feb3b160517e97b7", + "0xad6771177fc78812904c90594712956357de1533a07fec3082ba707f19c5866596d624efc3e11773b3100547d8f6c202", + "0xa79f31921134f7197f79c43a4b5d5b86736a8d3ad5af1bdf4ad8789c2bfe1c905199c5e9f21e9f446247224f82b334f8", + "0xa7f1b6c45321222a350a86543162c6e4e3d2a7c2dce41aeb94c42c02418f0892dbd70c31700245d78c4d125163b2cd5e", + "0x92abafe3ec9dbe55c193fb69042500067eb8f776e9bf0f1cb5ab8eb12e3d34986d1204136856fb115c12784c3b8dea6e", + "0x89bc761238a4d989006ca5af5303c910c584fe7e6f22aa9f65f0718a1bc171e452c43695e9f5a591725e870770c0eceb", + "0xaa0e44c2b006a27d35e8087779411ba2f9f1966a0f5646ff6871bcf63a8b1a4a7638751b94c9b9798ccd491c940bc53f", + "0x8736fe82862b8106e7fdab7b5a964d87ec291a74b8eb1cb5a6c046a648c1b686064ef3d52297043b8940bfe870c712f8", + "0x956a3def1942f05144d8e9c3a82fd2d3610064b53b9eefde3d5594a8f705bf8f6849eb2c22181796beffeba43cc74ee4", + "0xaf27416d00cf97d5a1f4a1b6b51c010884cceca294f1151c3b684a3f83c3c8a3c30771df1166d833cbddf6c873c400c3", + "0xaac3b8dca2336fc4ffc63c362df461289e4bbd3418c621bde6c581d3ecedf66e2b3e523d4db39e3d8ba014577bf85efd", + "0x94c3a8167f62074e5b28c2bffe4b6ce645439a9a0c5da3ca1b3ee956590a465d6f84a8a4dbbe9070ffbd6bbc734e4d62", + "0x95e23ba6986d25ed4451215da05bd72c5491528271726d79a94c8cb16aef1c85b190d6c5b8a3a1191c7cafbab1dccf0c", + "0x953e3dadb5ad68f7de31ac09692948655d174fe16d88b96930ef35b331da7f1dbc4c17863cd07b4ec3135b5205891a27", + "0x915d018f18b5d63cb3301c2bb5c6e85e75a88ba80663c964d06575b6bacbbe59139d030b218ce0998271d5b28c00b26d", + "0x8c871ba3dd138a908b2f7effeea0e71df096b23e0dd47cab10b9762b250abfd1221da94a8ee884e05bdf02271fb85a04", + "0x96bad5c6ebc3080ecbe337409ae398bbeada651221c42a43ea3b7c08c21841ddbcfde544c9b8d4772de6f2ce92c0b963", + "0xb5dbcd0b1c44c62108841558ec0a48df4b327a741e208c38b1c052321eda6e6ad01af71d49dfcdd445ab6fa6f0c34e6d", + "0x97dba59219b69e8aef2659d1f10bbea98d74aefff1f6451de3f41be39acbac0122b8ff58b02e90554469e88911ec3547", + "0xb7e5682ec306478be4858296f5d03364a61f3260636a4242f984d351a02e8723378496beb30c4ca22def9c9ca193ea70", + "0x9656a7a3df4d11df3d8bc35930dff70a5e78a488ca57bba20bb06814fc390fc6c7cb3f39b22134992aad196cced577de", + "0x8b269695aa63eb56d0324ba984279dc4c88e565321f1d61d553622bd4f1910d5eff68393d3a830eb924472bd478c2aa3", + "0x9177bcd04b28c87bc0440268b4c8995c6790cad6039594971b2c177f0e197055231e776927d3fa30d98fb897a2ba401f", + "0xae0e943973482001c4f214b9da82e1c27e38aa254d0555e016095c537c835d3702bc2de5c67b234ab151e02b3b7a43a6", + "0x82fc719a7d38bf4787fe1888019ad89fbf29beb951d2fece8686d2beb9119d0c8c6d13bc598748c72c70d73d488140ca", + "0xb716dc66f87eb16b95df8066877353962d91bf98cf7346a7f27056c2a4956fb65e55cb512af278783887ab269e91cd76", + "0x81d58cd8bc6657362d724b966321cd29a1b5cdc4601a49fa06e07e1ad13b05e9f387ca4f053ed42396c508cd065c5219", + "0xb32ad0280df6651c27bb6ddbdc61d5eb8246722140a2e29c02b8b52127de57a970e1ded5c2a67f9491ae9667349f4c46", + "0xb68a2eb64cc43f423be8985b1a068e3814b0d6217837fb8fbfd9c786db9cca91885c86899c50a1242040b53bf304ced9", + "0x85887515d4e371eabb81194cbc070e0c422179e01dbda050b359bd5870449c7950e6b3947b7a4a0eb68199341cc89fc3", + "0xac5fff3c27dfbab78eb8aad37ac31cc747a82401ebf3644a4f4f5aa98d37b8bf3b3f4bd8a3428b32a127c25c9e19d239", + "0x86fceaa6fbf8913553a9e1e907fcb1f1986d5e401a7eafd353beefd1899d571454fea96ff5b2a21254d9fb693ec94951", + "0xb6778bb296d3f0de2531b67d36fdbfa21475be0ca48b9dfcc38f396c41b557823735ed0b583e525a2bae1fe06e04058c", + "0x898088babeb5b9866537d6489f7514524c118704abd66b54210dc40a1c1ddb0a1edf7fe0b6e0db53b836f1828ecf939e", + "0xb27854364b97274765f0fb8d1f80d3660d469785d1b68da05e2bd1e4b8cbbe04304804d4c8aabb44cf030eba6c496510", + "0x8c55bbf3603dc11cb78b6395ccbc01e08afcef13611f7c52956b7a65ccf9c70551bff3ae274367200be9fc2d5cb26506", + "0x947726f73cd6281cd448d94f21d3b91b96de7ad3ff039f9153befbb5f172db9f53cacb4f88c80a3db26e6a0f7a846eb0", + "0xa7b733a05e97528812d71cecb4f638a90d51acf6b8fcbc054787d6deb7e2595b7b8d1cbe1aa09d78375b5e684a2019bc", + "0x8d5ca6d161341461544c533314fe0a6655cde032c2d96f0e4ea7e41098b8b39fa075d38e2d8c74e2d0308f250d6cf353", + "0xb960e9f081393e2260b41f988935285586a26657a3d00b0692ea85420373b9f279b2f1bb2da2caae72dd2e314045f1bd", + "0x852a49c7388c10821b387c6d51617add97ba72485f52be95d347bac44c638c92e9c6a44ba0d32afc4d59178a497d944a", + "0x8412162a65147e1334ad5af512982b2b48eef565682b3f3e0bbe93fbc5e1103db9375a0c486bdb1b2c57e4cb3a8e7851", + "0x8f52c3eb5d4f1e1e82cfd2b291d4910195427603b796f6c311deb35ef14a01a57a9e6cad39619ad108f3e86f384f9e1c", + "0x88d221088f2bf0103c53e44d0d96cd7881ec2b0a965db9121a47481771a8b796edd5ac23c4f9c208a171dab301f7d3bb", + "0xb49c3235e8b3617ed08a1891b9e2bcb33dbdacceb94ca96330555b7e00904fe6a749ced9312b8634f88bcb4e76f91cb1", + "0xa85834215e32f284d6dfb0cbfd97f6cffc7b9d354e8f8126d54598bb42d7f858a2b914cf84fa664069632db2ff89a332", + "0xaa3d48eb483c6120c27d9b3e3d0178c1c942632ff54b69f5b3cfbc6ad4ff5b2b9ce6eb771fd1eea8edf4a74c97027265", + "0xa446cfded353cdd9487783b45846402b973cdeddf87e2bf10cf4661610fff35743cc25e8d3b5771dcedfb46b018a5d18", + "0x80998377b3b393ef3073f1a655ad9d1e34980750e9a5cfb95f53a221b053ddb4d6985747217e9c920735b0c851d7551f", + "0xa35ac469790fac6b8b07b486f36d0c02421a5f74ea2f0a20ffc5da8b622ac45dfccabfb737efa6e1689b4bd908234536", + "0x8fb1f6d8e9c463b16ac1d0f36e04544320d5a482dd6ffaec90ea0f02b4611aaca984828bf67f84dcc3506b69af0a00a1", + "0xb6e818d61aea62c5ed39c0a22ccbb327178feebdabda0c9927aa1549d2c5bb0637785c4aed2a6d9a7b4989fa8634c64a", + "0xb4e7208d16018bf67caafe996d436113eac619732e3f529a6efb7e6f094d8ebea55b7be0e122be075770f5957b6ea6f0", + "0xb691d38b552befac61f6d367287c38d01fec73b7f2efdb6713ca30314a37fb7c177eb111fe6bee657f2681014e07630a", + "0x9817587e418e6e7e8e97ae27067f17b55d25dfb14e98f63f530620c855d9a348c9fa571c8508e2741f902f8b9fdc0c5c", + "0xb6a6e5ca779ba140bf1d84cd5394ede8262f7479637ec0087a4b152243a1774ba916d8115ce759a3bebd1b409de5f2fc", + "0xb53d1c84ad766ff794bf497db3228efd2cc8ed5fc1958d89c1126efdff361610ecb45ea8e329b39035ab00a66c1259c7", + "0xadc31333c507c8e0f4aa2934fcdca57fd9c786722a50dbd5404e129541f7ac182cc7373bf14e1e4e06e6cf94b31b90eb", + "0xa82b7fde4642d982d95cec669efee140ad797a2442c7f6620580527d163accbf021b893446cbb8038ea82fe25b15d029", + "0x91f7acf8a8903979afa281646fdecb54aa4d2ed905748e156e92f0910de268fa29d67107d40863935d677d1de8039be2", + "0x86fea71c6d43a7d93216a92fc24dfce8521fd4534a9558b33762d002081247867a6eff54cad7116023277fb4049403ad", + "0x8ae5369a7f9f4c91f3be44b98089efd9c97c08f5bb4cd8b3150c115ecd86288fa0865a046a489c782973a111eb93966e", + "0xb6fb9e829aa2c81c2d9eac72bb2fd7f3a08e0cd763532c2ce3287444d33cf48b3621f205e9603ec58525934b61a795a9", + "0x83e35ca808d84e41fc92115e9f6e283e928c3a614e6dfc48fe78c33b6411262e7bfa731eadb1e1937bc03cff60032e1d", + "0x832fca5196c95098ad47b7d24ba2f9d042e1c73ad2273edd1c2ce36386796ccc26e8567847697f3fcc2a0536a2a2087a", + "0x8fdb7038bc8f462ab2b76bf7053362f9c030019f1b6105cf42219a4e620ecc961e3eacb16a8e581a562a97f1418b0128", + "0x8d3a5a404b51b1ad8ce3b23970e0d5cc57b573922341008e3a952a1dd24a135e19e55b79d86a70cfd82e1c0e9630f874", + "0xba00c025c1c21c57c03cdfc0bfd094b35422281ff0a64b68b240617aa58c6b18800af5f2047d3ff9068bbe987d6c7980", + "0xb468f0dd51964b3806b0aa04f3fe28a035e8f5567fc7d27555be33d02701a838b8dbfe1348b6422c4eac46d2c75c40c7", + "0x8a73a18c97da9958903c38584b08d0e7e26993a5d9b068a5e0e1ee0d8a873942745cf795f94f7a3d3ba88790a9fbb2f6", + "0x953a0a40c2c8102723736854d13b228698c14a02d85c8d2e61db1a768019ac305faf0d5db62ac976430ce087a5b20f1e", + "0x8998219da6b34f657cb8a621c890a52cb98c2bc0f26f26e2af666eebeadadc5e8bdf4f830a91d04aca8ce186190152c8", + "0x8941e08c3155ad432236ed05460420a05dd0aaab30477493ffb364b14c00ea5b9183d30d3442b6321d2d20c36e4f5c7e", + "0x93f293ff7fb56cf5b03aee6f3ad2ad78444398ed5b3be56d7bf5b56b5aa5a2b980d13895dd57a5726d1b067c20cc55e2", + "0x84a16f313e3f75e31824f58d19ab24c6611fb4c75140a7cadc3c166f68819547c1d0ff7f7d13f5d8ae30dff1d80e2aa4", + "0xb6e3e830b15039d3e28b08f5465bb089eade11ee3bd80afe39e010df7db1fcf0c56d698717677a41ddbc91eeaf6544d3", + "0x95e928e6dfff51351281568ae72da7d1edeb6e9fe01f30af0499e7505ba35a22b5bb919d41bb809a432dce83f3977663", + "0xaabeeb60ca46f9b0232ff82ea7766dcab8cc5aaf9d23539f30174f9486640bc9312868ca493b59b314519fc399973e47", + "0xb393a11e957d0bbb3ecf617b075b5906a3450b348e62916c04791b366f0a7397cccd6648440ac544bc30526e1f95aad8", + "0xabb5bfc3964a6d246da60bd809d0ea6daf4f8222efdc12ceb6730194e85f413ee7eb03bae300abf7ea900dbbc3d08971", + "0x96c1bd1d1d216a4bfbcf000c123f296c0d31e1684e9e3884c14df23bf528c8d599f82bb98fcea491716b617216a8e0be", + "0x92d1e570a56f1741fd9f3d9f488cc336421c6256c14a08d340a63720be49b0029e3780e3e193a2e22bf66cc652fa22a3", + "0x8769c08551e3a730e46f8e5d0db9cf38e565a001dfb50db3c30fa7fa0e98b19438edc23c6e03c8c144581b720d7b33a4", + "0xb850bd67fdf5d77d9288680b2f6b3bc0f210580447fb6c404eb01139a43fccb7ed20051999ae2323ea5a58de9676bfb4", + "0x80285da7a0aaf72c4528a137182d89a4db22a446e6c4a488cf3411937f4e83f7b00ec7549b0b4417682e283f91225dfe", + "0x80520368a80b97d80feb09dbc6908096c40ff7120f415702c1614d7112b0b57f6729581c71f4a3ce794ac959a46494ff", + "0x9817b4c27a490b1cd5a6337e7bc7e8005fa075dd980c6bf075ddfa46cd51cc307ad1d9f24e613b762a20fc6c877eab41", + "0xad66bda1a3034ec5e420b78107896ecf36126ce3ef9705163db259072dfa438c6107717a33572272062b9f60cb89557c", + "0x876114ef078c2915288e29c9abe6b0ad6a756b5ee2930ba1b8a17257f3f0557602d1225e8aa41ce8606af71ada2a971b", + "0xaa3d6cde4c3b9d3d5d0c77a33e67f182a3e1cf89b0921423b2024236171955b34afc52b1f25b1dad9da9b001371771d7", + "0x984d3e3a72412d290e3459339757af7520d1739c7af0cbcf659c71999328db44f407d92e8a69fea11625612c49eac927", + "0xae890d0faf5bd3280dcad20a5f90e23a206661be8842375fea2ab22aadc500849ffbc52fe743b376d46bb926cedae6a6", + "0xb1f231f3f4d710c3fe80099faeb56dac67c1baf53b8fe67a9920fe4f90e52cb9a4bf19211249a6456613b28efe337f18", + "0x8caa54b418ba609d16520af3dff2e96d5f2eeb162c065a1763beb926547b2cfb3ae41d738db2c5681a9bc8bc9e6b9a1a", + "0x932157ff56c5ac29cf6cf44f450c882b3acfbb9f43d12d118da3d6256bde4e6eb3183aea304ab6967f37baa718ffec99", + "0x9360bed8fc5b6aac36aa69473040689bfc30411d20ffb7275ef39b9ff5789f9055d149383ce9f0f7709a1f9d683adbfe", + "0x98b5b33209068335da72782179d0c7aeeabe94b5560a19d72088fe8323e56db7ce65debe37a97536b6b8a0ca3b840b61", + "0x89a385c11be40064160b030a1bb28c3921fc8078522618a238c7ea0f86f34717ed9af9b4e2e20f5128e5f7fc66ad841e", + "0xb615703cbc64b4192990cc7e4903b74aed6a0076ce113b59ef7719197ffa46fb29eb78ca56b49873487432d0625c0faa", + "0x90f0d77abae9d3ad73a218e5ccec505ad108ea098451461567ae8ef9661606ca8e78df53b5d628b20b7037bd24622330", + "0x92e0e7cc4dfadc5fa0ee6da0c8de0493030db6e54ba0317f52f232a6708b732068b6077bd13a17eb7eb40b88368085b5", + "0xa24dad20094985bfccc6df1343506ed3bf9dcbdf4b2085a87627a5d71f7568db067304e465f8f380c5c88e8a27291a01", + "0x8629a45a10619354c84bdc2f6c42f540eab5a46f53f2ae11970433d7a2aef007897590bf31dfba1c921614c6d6fe1687", + "0x84ac64040d4206f82b08c771f375da4b7d752e41d2aa0da20ce845f6bc1b880a855d3ee966bca19b8ec327b4b43e7f0e", + "0x9608e6050c25996c052509f43f24a85cdf184135f46eaac520a9a6e78e0d44a6cee50ebc054048c708aefde8cd6651c2", + "0xa32032b0e0d7cc35e480c328f315327f9385adb102a708c9ba637878deb74582ae26bb6d6e5f8c9e3a839b0e0154b82a", + "0xb7e3c78d63acc6564a49e9f00b0a820b56d4f37a2374af1f7f1d016268011df9e7af0670ed2b0eee961f15aa948328dd", + "0x8b88bfdd353acc91ad0d308a43e5fb40da22c228f2fe093c6d6904d70f69c6203f56636ed898b05df51d33f1095ef609", + "0xb1d7a430c51fc857af55047683fc18c453b013527196c5e1bf776819a3dffca802217e9249ae03f084e2ea03ad67fcc2", + "0x80558e28a819ddb5e72e97c54be0f57c173ccf78038d360d190b7f1350a19577b8e3f43fa2f7bf113a228cd3b965b2e4", + "0xb4b2ec44e746c00dfc5661ba2514930934fc805cdc29adc531c02d28ce3cc754414b0485d4ee593232cd1175f357ad66", + "0xb57cee5d32835f76572330f61ccd25a203f0e4a7e5053d32965db283aad92f287645533e8e615137208383ec51b1fd99", + "0x930256086b419a8a6581c52590d0dbd9f8a3564c79424198fca3866b786df2f6098a18c50dc4abd20853a7184b1ce15d", + "0x8e75fd01181cffcd618a983492390f486e8c889972a46c1f34a4e1b38f384e8e4efc7e3c18533aa2057da9f9623e2238", + "0xb375d927dd988429f9e2764e5943916131092c394fce13b311baa10f34b023dd3571da02553176091a0738cc23771b9a", + "0xb9e28e4c0d0477518034d000e32464852e6951c8db6f64ccdb1d2566f5094716213fbf2fc0e29ac88d0e79f725e3c926", + "0x963981e99392afbd2b8318d5a6b2b0cc69c7f2f2f13f4b38dddbfedb2b0eaf0584aecfcbda20a4c60789c15d77970a58", + "0xa7804e1977aa77c263c7c001afa6cf568032dea940e350d6a58ce4614f1a91c13ae1c78bfea740c229dce2444556976a", + "0x8787204177da3cde6d35cd3497fa8774d244f9faa9f4bd91b636a613a32ce2ea0326378cf9c4cf475e73ef751b355c4b", + "0x895aeef46a07152a04ec812f1aa1fd431389fa0ef6c6e96a5b833e70ea14073bc9984757a8ee456dbec9788e74e6f0ca", + "0x8d17f0e5826783440d1f0ec868003510a4d9952bfe4a638e44a36d94482ac18ba70ef7ff773bdf7a3b62d714dcf0fcba", + "0x810d5e36b31310b2e054a666d3b3f7ed16dfcb1765532d87ca2a3920316f0187303c27dd113db145d47e8961062a6c03", + "0xb4e2fb48ae04cf8580bb6a28095076c9b95e5f13122b917328f334d4ac8a8648ce442919e28319a40148987350ab5303", + "0xb85549a313544fa1eb3ceb78473b7d3d717fc85b808de7b79db7dbd0af838ebb020622a7503f1cbacab688dddb648f84", + "0x80665adee057088eae827a5fe904ec3ad77d8843cdce0322d535e0659b4abc74a4d7ddd8a94c27f2def5c34ac2c038ee", + "0xad72fc19c2ce99b5b717e35528fe7d3ac8add340b02ebeb4889d9a94c32f312a0b45ea84d21c54f84cc40ee4958b72e1", + "0x99d530c843dff89a47a5ee8c87303ab18f8a82b0d5b808fca050354b35da5c5a5594d55921c6362d6cc917d75bdc18dc", + "0x99c7286c293e1be21c5b2a669dfdfcd5aa587105d2886fc5a8eaf8984da4e907f7d7b8c2362d64a4f1621b077a2a08a0", + "0xb4a39e1a9ed5d80c9563c3ca3fadf76f5478c63a98f4346a61b930c9c733e002f3ff02bc16abfdb53d776184cc3f87ba", + "0x9378ea71b941979404c92d01fb70b33fa68d085bf15d60eb1c9fc2b5fcdee6379f5583389a3660a756a50019a2f19a69", + "0xb68e17344a2bc45b8e2e19466b86dc139afefbf9bad2e2e28276a725099ebac7f5763f3cb52002261e3abe45ef51eb1a", + "0x819e64dc412b2d194d693b9b3157c1070a226af35c629837df145ea12ad52fa8eabd65b025a63c1fb0726207a58cdde8", + "0xa5e8ff8748419466ff6df5d389125f3d46aedacf44eaf12cbfe2f68d218c7d5ab6de4a8279d13aecc25f3b1d98230894", + "0x91560d54a9715cfda9cf7133ae51c432d0bf7fcbaeb468004994e6838bfc5ddcfa30e4e780667d0c4c0376780b083017", + "0xae8adb3309cc89d79a55ff74f129bb311fe4f5351a8b87600a87e0c3ba60825f71fccf67eadcf7e4b243c619417540fd", + "0x8d92cc1a6baa7bfa96fbce9940e7187b3d142f1888bdcb09bb5c8abf63355e9fb942ac4b4819d9be0e0e822d3e8e2e08", + "0xa6e8b79fdd90c34735bb8fbef02165ccbe55ea726dc203b15e7a015bf311c9cac56efd84d221cc55eaa710ee749dbdfe", + "0xa409b151de37bddf39ce5f8aa3def60ee91d6f03ddd533fce9bf7bdbeac618cc982c4f1ffbf6e302b8353d8f28f8c479", + "0xb9693975ef82171b3b9fc318ca296e4fe6110b26cbdfd653418f7754563fa7b6e22d64f8025ee4243483fa321572bfe4", + "0xa039ebe0d9ee4a03ade08e2104ffd7169975b224061924cca2aae71464d250851e9f5f6f6cb288b5bf15df9e252712a6", + "0xb27834db422395bd330e53736a001341ce02c9b148c277dabac67dc422741bfa983c28d47c27e8214cd861f2bad8c6f6", + "0xa2bafaf4e2daf629fd27d7d5ac09fb5efc930ff2ae610f37519808683aa583fe1c6f37207daf73de1d8a164f79a0c981", + "0xb856cee1cfcf5e50db9af4ab0aed3db2f43c936eaea369b5bba65582f61f383c285efbda97b1c068c5d230cbe94f7722", + "0xa61ab205554c0550fa267e46a3d454cd1b0a631646b3df140623ff1bfffaa118e9abe6b62814968cc2a506e9c03ea9a0", + "0x8c78edcd106377b9cbdfa2abd5278724aed0d9e4ae5869b5d2b568fdabb7804c953bae96294fcc70ef3cd52ba2cbe4ed", + "0x8570869a9bbf6cc84966545a36586a60be4d694839f367b73dfc40b5f623fc4e246b39b9a3090694aa2e17e652d07fd1", + "0xa905b82c4da8d866a894da72315a95dc98faa3c7b3d809aef18f3b2be4801e736a1b79a406179e8cac8f74d27e71ac52", + "0xa8eb8679ff1a64908515f6720ff69434cb33d63aeb22d565fde506618908b1d37585e3bd4d044fd0838b55787af06b42", + "0xaf4d86b2fbd1684a657dffe4210321a71e6ae560c144d44668d1f324dc9630e98348c3d444622a689327c1a59cc169dd", + "0x80359c6eab16954559ab0e6a1fee9a0526c45d3cae1a371159a2e3aa9b893afdc3a785c9559a5fd9cd8cd774234bf819", + "0x8d4e5ff81eb5d17bbe8ae6416538ca51a9427ce142b311f5cbb14febbbbb9c1ffc6489fd625b9266264c366c12a9d997", + "0x92e181c66489c5fa063ba2a1a354b6fd3439b8b4365a8c90e42e169bfaa1fb5766bf3e0fe804399d18bc8fbcafb5c3b1", + "0xa9ddf229360a095393885083716cb69c819b2d7cfb100e459c2e6beb999ff04446d1e4a0534832ae3b178cbe29f4f1d3", + "0x8e085ef7d919302a1cc797857b75cff194bdbc1c5216434fa808c3dea0cf666f39d9b00f6d12b409693d7a9bd50a912c", + "0x916dc4dc89e5e6acf69e4485a09fc66968f9b292eac61a146df1b750aa3da2425a0743d492179f90a543a0d4cd72c980", + "0xb9cbf17e32c43d7863150d4811b974882da338cf0ed1313765b431b89457021dd1e421eeaa52840ef00551bb630962dc", + "0xa6fb875786daec1a91484481787093d8d691dd07e15c9c0c6ae0404bf9dc26083ed15d03c6d3fe03e29f28e20da21269", + "0xa870fcb54b9a029e8086de9b08da8782c64ad2cc2e7fdf955b913d294038bb8136193256b85267e75a4ca205808a76b4", + "0x99883f057e09b88bf0e316f9814c091837fd5c26eeb16fec108c9fed4b7a2bd1c783dac0e4242b5a906621ab606c1e50", + "0x85d89069ca3190577dab39bbec43c16bf6dbca439ad3eebd8f5e9f507d84c3c43e77fd6323224582566a3aa2c8018951", + "0x9363ba219e0003f6e8a9d8937b9e1449e4b2c5cd57194563b758bea39deab88778e8f8e4f7816970a617fb077e1e1d42", + "0x820622f25553c035326145c1d2d537dc9cfd064c2f5bdf6d4ec97814de5fe9a0fbd443345fa2ea0a9d40d81d3936aa56", + "0x87e31110aaf447e70c3316459250e4f7f8c24420c97828f9eb33b22107542c5535bdb48b0e58682dd842edea2886ff08", + "0x95bf80cac6f42029d843d1246588acb40a74802f9e94b2bf69b1833936767e701ef7b0e099e22ab9f20f8c0c4a794b6c", + "0xa46ecf612b2763d099b27fb814bd8fdbaee51d6b9ac277ad6f28350b843ce91d701371adfaaf4509400dc11628089b58", + "0x8604decf299fb17e073969708be5befeb1090ab688ad9f3f97a0847a40ea9a11bbcfc7a91e8dc27bc67a155123f3bd02", + "0x8eb765c8dc509061825f3688cb2d78b6fef90cf44db33783d256f09be284bc7282205279725b78882688a514247c4976", + "0xb5c30b2244fa109d66b3a5270b178960fdec47d31e63db0b374b80d2b626409eb76d2e8d1ebf47ef96c166743032fc5e", + "0xaab01e76290a7e936989530221646160bf8f64e61e79282e980c8c5dcaaa805ff096efd01d075a2c75917a3f4bf15041", + "0xb9d79671debd0b83d0c7c7c3e64c0fb1274300564b262771f839b49218501e7f38ef80cae1f7e5a3c34acdc74c89dab6", + "0x92c0eaceadf036b3b9dfd2712013aba3dd7c30b7760f501f52141618265baa31840fe77850a7014dc528f71f8cf39ce6", + "0xb3cdd098059980455dd5b1c04182df1bd12fa844a866f02a9f8a86aab95b59945baa9af99f687410bffc5b07153cb23c", + "0xb361b73a62f71256b7f6ea8e0f6615e14fc5a06ee98b928ab3c9dd3eef9d9d30070e9855c82b7facb639cacb3401e01f", + "0xb9c85fc0f25a3271cf28b1ca900078eaaa66cbab0a3e677606e898ac32781a2dfce4d9cbd07404599e2c3c02fa161c9d", + "0xac5b4fdac2a0b2e6430d9fc72bde4249d72183b197fc7347bb1546ae6f544426686bbe0caec3ee973b6836da5e831c44", + "0xb675aebf24b92e398e166f171a6df442b3f5919b6bee192f31675a5e8eeb77d34c6590a6f0c0857417e0f78cfb085db8", + "0xa9bef942044d8d62e6a40169f7dc7b49e40cd0d77f8678dd7c7bae6f46c46786f9b1e319a3fa408f22a54fd2a4d70804", + "0xa20d19cd917d5102ae9ca0cf532127d2b953aa3303310e8a8c4b3da025dded993a47e3a28e6b02acfadb6d65dc2d41a3", + "0xa47fdb04059b83b2afb86a47b2368bbd7247c337a36d3333b6e5ef2cc9476a92c4907e4c58a845c9ef9b497621e0b714", + "0x94a9e9ffc14b411e11a4ffa59878d59460263589003dc7b6915247c549f67feede279bf3645fdd92379022fb21e3caeb", + "0xb92e1177dd9ecdaf1370c71b14954219cf0851f309bc216d5907a4e2e84e0df3457018224150c142cc6bf86644bb4b73", + "0x8bc57fadd68a265b7df9b42227a9c0968db7b1bb50dc12f7d755505779f1ff2c408672b3091e903366acc9ce15d19fb6", + "0xb6b5efbe1ac4e1bd2e8447c45000d09397b772ca5496acc447b881022608a41c4f60388814607a01890190105bee7be3", + "0x95f7c85fd614df968f8ccf8d086579c9e1cec4644ecf06da26e3511cb39635a7326b3cec47bd51cf5646f1c660425e9c", + "0xb81765fb319bcdc74b4d608383ccb4af7dd84413b23af637be12e2827a75f7e4bcd14441cf979ed9038ae366fbb6f022", + "0xa120ea76cda8c6c50c97035078f6648afe6537809bdba26e7c9e61de8f3070d2347160f9d34010effbf2ec7e94f5749f", + "0x92c1b8631953b40d3cc77eee2c72a064b999c09a9b92c11d8fa7b4072966273901c9dba25f9f79f384d9f11a56f3fc7a", + "0xa4b00dc0ab67b2300abc9c516e34daf444d6497b066a90cfe3381ed2812304ed37b14f3b948990443dc6c1cf1bed460c", + "0xa9e9f7e13c9f031bc7b9e6f1417c7abcc38894fe7d3f54869ee277afd2efa3e6fb50757dd36c8c94d591e0abdea322cc", + "0x84f3e98f831792b5ad14bcfe62a4c9f296476c6087c4c1ec7767fc642fbca141ff6a3deeb8b4d4106a9cda5a9937eea0", + "0x8eb1a7931bbea9a714226fd74b0100ab88355287d9b0a349c095e9b5809b98f237ffd706bce7d67a770da355fb9cec7b", + "0x9738ef8739e1742c1f26b51a1621be0b89d37406a370c531e236f635c7064c661818817bb3858908986aa687b28b21be", + "0xa9cf3ce8501b003ccaf57552a4c4ec31081e44526d3aa3791d3dc4a7e438a357c0956f93c500356186d8fd4588ffac5e", + "0xa7af6a219cca59225839a9de5b19263cb23d75557d448bc7d677b62591a2e068c45e5f4457cceb3e9efa01d0601fc18a", + "0x972a24ece5eda7692cbb6fb727f92740451bc1281835e2a02931b2b05824a16b01dbe5edd03a0ed5b441ff25a5cc0188", + "0xb21d1ec7597ce95a42f759c9a8d79c8275d7e29047a22e08150f0f65014702f10b7edce8c03f6e7ab578ce8c3b0ec665", + "0xa13a1c7df341bd689e1f8116b7afc149c1ef39161e778aa7903e3df2569356ad31834fa58ceb191485585ce5ef6835c3", + "0xa57bdb08119dc3bc089b5b2b5383455c4de0c2fcdac2dcfa21c7ac5071a61635ff83eceb7412f53fab42d1a01991de32", + "0xb2968748fa4a6921ee752d97aa225d289f599a7db7a222450e69706533573ded450380c87f8cdd4a8b8c8db1b42b5c97", + "0x8718ec04e0d5f38e3034ecd2f13dfde840add500f43a5e13457a1c73db0d18138f938690c8c315b5bcbeb51e8b9a2781", + "0x82094789e26c4a04f2f30bdb97b9aecca9b756cbd28d22ab3c8bed8afc5b2963340ddfc5a5f505e679bf058cbc5dcbb8", + "0xa35b8a566dd6ab67eddc2467906bffc76c345d508e52e9e4bb407b4f2b2c5f39b31d5a4bf5022f87bf7181dc6be2fe41", + "0xa8c93b1e893d4777c0e3a1b4bef3be90c215781501407c4011457fc3240e13524b4d2bea64a6d0a3efe3f3b0dae9b8ab", + "0x877095ad18b1e5870818f7a606127ba1736a0b55b0dbcd281ec307c84b08afc0c9117e3a880fe48bfc225fbf37671a97", + "0x84405ee0421ed2db1add3593df8426a9c1fcc8063e875f5311a917febc193748678dd63171d0c21665fb68b6d786c378", + "0xa52cdc8209c3c310bed15a5db260c4f4d4857f19c10e4c4a4cfe9dfc324dfac851421bb801509cf8147f65068d21603c", + "0x8f8a028a70dda7285b664722387666274db92230b09b0672f1ead0d778cee79aae60688c3dfd3a8ed1efdeda5784c9d4", + "0xa0be42fecc86f245a45a8ed132d6efc4a0c4e404e1880d14601f5dce3f1c087d8480bad850d18b61629cf0d7b98e0ae0", + "0x83d157445fc45cb963b063f11085746e93ab40ece64648d3d05e33e686770c035022c14fdf3024b32b321abf498689ad", + "0x8a72bbf5a732e2d4f02e05f311027c509f228aef3561fc5edac3ef4f93313845d3a9f43c69f42e36f508efcc64a20be0", + "0xb9ca29b0ec8e41c6a02f54d8c16aebf377982488cbe2ed1753090f2db4f804f6269af03e015d647a82ef06ffaa8cba6c", + "0xb4df3858d61bbb5ded1cf0be22a79df65ae956e961fbb56c883e1881c4c21fe642e3f5a0c108a882e553ac59595e3241", + "0x86457d8890ac8858d7bab180ef66851247c2bf5e52bf69a4051d1d015252c389684fcc30bb4b664d42fbf670574ab3a3", + "0x86d5576ea6dfa06d9ebce4cd885450f270c88a283e1e0d29cab27851c14ed2f00355e167b52e1539f1218ad11d8f13dd", + "0x883ad1364dc2a92388bfafaa9bc943c55b2f813525831e817a6208c666829a40455dde494eba054b2495a95f7ce69e8a", + "0x8942371e6925231c2c603b5f5a882d8404d39f0c7c4232557c2610b21c2c07f145466da798ea78b7932da2b774aa3128", + "0xa799eb71496783cc7faf12c9d9804bf6180699a004b2f07fc5cc36840f63ce7eee7dde9275819a9aa3f8d92dc0d47557", + "0x8eb3fb5c769548ee38c7882f51b959c5d5a42b5935269ccf987d6ddbb25a206e80c6000bcc328af149e0727c0b7c02c0", + "0x8f3910d64e421a8f2d8db4c7b352ba5b3fc519d5663973fea5962efe4364fb74448770df944ef37ffe0382648fb56946", + "0xb41413e0c26ff124cf334dab0dc8e538293d8d519d11cc2d10895a96b2064ac60c7da39f08589b38726cffa4c3f0bfef", + "0xb46ef2eb10abae0f35fa4c9c7ee2665e8044b8d9f91988a241da40fd5bbc63166925582151941b400006e28bbc5ba22a", + "0xb8baa8b4c420bb572a3b6b85479b67d994c49a7ebfe1274687d946a0d0b36dfed7630cfb897350fa166f5e2eff8f9809", + "0x964b46d359c687e0dcfbdab0c2797fc2bd1042af79b7418795b43d32ffca4de89358cee97b9b30401392ff54c7834f9f", + "0x8410d0203d382ebf07f200fd02c89b80676957b31d561b76563e4412bebce42ca7cafe795039f46baf5e701171360a85", + "0xb1a8d5d473c1a912ed88ea5cfa37c2aea5c459967546d8f2f5177e04e0813b8d875b525a79c29cb3009c20e7e7292626", + "0xafaab9a1637429251d075e0ba883380043eaf668e001f16d36737028fded6faa6eeed6b5bb340f710961cee1f8801c41", + "0xaef17650003b5185d28d1e2306b2f304279da50925f2704a6a3a68312f29fe5c2f2939f14e08b0ba9dee06ea950ad001", + "0x97bcc442f370804aa4c48c2f8318d6f3452da8389af9335e187482d2e2b83b9382e5c297dce1a0f02935e227b74e09a3", + "0x8a67a27b199f0bcd02d52a3e32f9b76a486b830ec481a49a4e11807e98408b7052b48581b5dd9f0b3e93052ec45dfb68", + "0xb113bf15f430923c9805a5df2709082ab92dcdf686431bbad8c5888ca71cc749290fa4d4388a955c6d6ee3a3b9bc3c53", + "0x8629ca24440740ce86c212afed406026f4ea077e7aa369c4151b6fa57bca7f33f9d026900e5e6e681ae669fd2bd6c186", + "0x933a528371dcecc1ec6ded66b1c7b516bd691b3b8f127c13f948bfbcda3f2c774c7e4a8fbee72139c152064232103bdf", + "0x8568ddd01f81a4df34e5fa69c7f4bb8c3c04274147498156aec2e3bd98ea3e57c8a23503925de8fa3de4184563a2b79e", + "0x8160874ec030f30fda8f55bcf62613994ff7ed831e4901c7560eac647182b4a9b43bfaff74b916602b9d6ae3bfcaf929", + "0xae71c48d48cf9459800cdf9f8e96bc22e2d4e37259e5c92a2b24fbe2c6ca42675e312288603c81762f6ceb15400bc4c9", + "0xb05f39bb83fda73e0559db1fd4a71423938a87ad9f060d616d4f4a6c64bf99472a2cbfb95f88b9257c9630fc21a0b81f", + "0x80c8479a640ed7a39e67f2db5ad8dfd28979f5443e8e6c23da8087fc24134d4b9e7c94320ffa4154163270f621188c27", + "0x9969ba20ee29c64cb3285a3433a7e56a0fe4ddc6f3d93e147f49fe021bed4a9315266ebb2fb0eb3036bb02001ae015e6", + "0xa198c89fef2ab88e498703b9021becc940a80e32eb897563d65db57cc714eaa0e79092b09dd3a84cfab199250186edcc", + "0x8df14a3db8fe558a54d6120bad87405ba9415a92b08c498812c20416c291b09fed33d1e2fcf698eb14471f451e396089", + "0x81e245ef2649b8a5c8d4b27188dd7e985ef6639090bdc03462c081396cf7fc86ed7d01bfe7e649d2b399255e842bdc21", + "0x8659f622c7ab7b40061bcf7a10144b51ad3ab5348567195924f2944e8c4ce137a37f1ba328e4716c10806f3fb7271689", + "0xa575d610fc8fe09334ca619ecdadf02d468ca71dd158a5a913252ca55ea8d8f9ce4548937c239b9cb8ab752a4d5af24a", + "0x94744549cd9f29d99f4c8c663997bdfa90e975b31f1086214245de9c87b0c32209f515a0de64d72d5ef49c09b0a031fa", + "0x80a8677862b056df59e350c967a27436c671b65d58854e100115bac9824ba177e94c2a1bfcaa191a071b9cefdbee3989", + "0x91be9a5504ec99922440f92a43fe97ddce2f21b9d94cd3a94c085a89b70c903696cec203bbab6d0a70693ba4e558fb01", + "0x8c5a0087bcd370734d12d9b3ab7bc19e9a336d4b49fc42825b2bfedcd73bb85eb47bf8bb8552b9097cc0790e8134d08c", + "0x933aa9e6bd86df5d043e0577a48e17eea3352e23befdbb7d7dcac33b5703d5ace230443ac0a40e23bf95da4cc2313478", + "0x984b7ee4bd081ee06c484db6114c2ce0ba356988efb90f4c46ff85ed2865fb37f56a730166c29ef0ae3345a39cdeae7a", + "0xae830f908ea60276c6c949fb8813e2386cf8d1df26dcf8206aa8c849e4467243e074471380ed433465dc8925c138ea4c", + "0x874c1df98d45b510b4f22feff46a7e8ed22cfc3fad2ac4094b53b9e6477c8dfc604976ca3cee16c07906dece471aa6c6", + "0xa603eb60d4c0fb90fa000d2913689126849c0261e6a8649218270e22a994902965a4e7f8c9462447259495fe17296093", + "0xa7c73d759a8ad5e3a64c6d050740d444e8d6b6c9ade6fb31cb660fa93dc4a79091230baccb51c888da05c28cb26f6f3f", + "0xa4411b79b6a85c79ea173bd9c23d49d19e736475f3d7d53213c5349ebb94a266d510d12ba52b2ac7a62deaaaec7339b8", + "0x943b84f8bbcee53b06266b5c4cd24d649d972593837fe82b0bf5d5e1bbc1a2bf148e1426c366d7c39ab566b10224cadc", + "0x8300012096a8b4cefecc080054bf3ceb0918162ba263c6848860423407796b5eb517170c0bad8e4905ac69a383055a21", + "0x8244a1e3ad41908c6f037e2f8db052e81f281646141334829f36c707f307448b9ab79a7f382a1e8d86f877c90b59271c", + "0x8eca1b74687802ecc36a5d39e4516a9dee3de61a2047252d9ed737b49e0090c386e9d792ac004c96337681c7f29a16ad", + "0xb70fa47535f0524835039a20036c61e77f66146ad79d3d339214d8744742db41ceeb577c829d000011aeafbb12e09579", + "0x84b3abbce48689f3adbb99889c7fd1f3e15ab455d477e34f5151c5c1c358ed77a5b6a581879f7e0f1f34106e0792e547", + "0xab45ecb58c0ef0dbce3d16afc6ac281e0d90ec48741ea96a141152647e98fcc87f3a3ff07ba81f3179118453ce123156", + "0x90d231a145ba36a59087e259bbfc019fa369201fcfeaa4347d5fd0a22cd8a716e5a797f3cc357f2779edb08f3b666169", + "0xa4f6074d23c6c97e00130bc05f25213ca4fa76c69ca1ace9dece904a2bdd9d987661f5d55023b50028c444af47ff7a08", + "0x933af884939ad0241f3f1f8e8be65f91d77ac0fb234e1134d92713b7cfb927f1933f164aec39177daa13b39c1370fac8", + "0x80d1db6933ce72091332ae47dc691acb2a9038f1239327b26d08ea9d40aa8f2e44410bbda64f2842a398cbe8f74f770f", + "0xa7a08605be2241ccc00151b00b3196d9c0717c4150909a2e9cd05538781231762b6cc6994bebbd4cddae7164d048e7b2", + "0x96db0d839765a8fdbbac03430fa800519e11e06c9b402039e9ae8b6503840c7ecac44123df37e3d220ac03e77612f4e4", + "0x96d70f8e9acd5a3151a8a9100ad94f16c289a31d61df681c23b17f21749c9062622d0a90f6d12c52397b609c6e997f76", + "0x8cf8e22273f7459396ff674749ab7e24c94fe8ab36d45d8235e83be98d556f2b8668ba3a4ec1cb98fac3c0925335c295", + "0x97b7e796a822262abc1a1f5a54cb72a1ea12c6c5824ac34cd1310be02d858a3c3aa56a80f340439b60d100e59c25097d", + "0xa48208328b08769737aa1a30482563a4a052aea736539eceab148fa6653a80cb6a80542e8b453f1f92a33d0480c20961", + "0xb612184941413fd6c85ff6aa517b58303b9938958aa85a85911e53ed308778624d77eadb27ccf970573e25d3dfd83df7", + "0xb3717068011648c7d03bbd1e2fc9521a86d2c3ae69113d732c2468880a3b932ebec93596957026477b02842ed71a331b", + "0xa0ad363e1352dcf035b03830fef4e27d5fd6481d29d5e8c9d51e851e3862d63cdcbaf8e330d61c1b90886921dac2c6fd", + "0x8db409fdacfa4bfdaf01cc87c8e97b53ca3a6e3a526d794eaad1c2023f3df4b888f1bf19fee9a990fe6d5c7c3063f30c", + "0xb34d6975310ab15938b75ef15020a165fc849949065d32d912554b51ffa1d3f428a6d1a396cb9329367670391de33842", + "0x9117285e9e6762853fc074b8a92b3923864de2c88c13cea7bab574aaf8cdd324843455d2c3f83c00f91f27c7ecc5592a", + "0xb4b2e8f190ea0b60819894710c866bf8578dd1b231ae701d430797cc7ede6e216e8ca6a304f3af9484061563645bf2ab", + "0x8c493c6853ab135d96a464815dd06cad8b3e8b163849cdefc23d1f20211685753b3d3e147be43e61e92e35d35a0a0697", + "0x9864d7880f778c42d33cf102c425e380d999d55a975a29c2774cad920dfddb80087a446c4f32ed9a6ab5f22ec6f82af0", + "0x90f67fe26f11ca13e0c72b2c2798c0d0569ed6bc4ce5bbaf517c096e7296d5dd5685a25012f6c6d579af5b4f5d400b37", + "0xa228872348966f26e28a962af32e8fa7388d04bc07cfc0224a12be10757ac7ab16a3387c0b8318fcb0c67384b0e8c1a4", + "0xa9d9d64bba3c03b51acf70aeb746a2712ddafe3b3667ae3c25622df377c2b5504e7ab598263bec835ab972283c9a168b", + "0x932128971c9d333f32939a1b46c4f7cf7e9d8417bd08dc5bd4573ccbd6ec5b460ac8880fb7f142f7ef8a40eef76d0c6d", + "0x964115e7838f2f197d6f09c06fbb2301d6e27c0ecdf208350cf3b36c748436dac50f47f9f9ac651c09ab7ad7221c7e43", + "0xa5941f619e5f55a9cf6e7f1499b1f1bcddcc7cf5e274efedaaad73a75bc71b1fc5c29cd903f6c69dc9a366a6933ca9d1", + "0xa154bf5eaec096029e5fe7c8bf6c695ae51ace356bb1ad234747776c7e1b406dee2d58864c3f4af84ed69f310974125e", + "0xb504e6209d48b0338ab1e4bdab663bac343bb6e0433466b70e49dc4464c1ec05f4a98111fd4450393607510ae467c915", + "0x813411918ea79bdde295393284dc378b9bdc6cfcb34678b9733ea8c041ac9a32c1e7906e814887469f2c1e39287e80f8", + "0x8be0369f94e4d72c561e6edb891755368660208853988647c55a8eed60275f2dd6ee27db976de6ecf54ac5c66aaf0ae6", + "0xa7e2701e55b1e7ea9294994c8ad1c080db06a6fc8710cd0c9f804195dce2a97661c566089c80652f27b39018f774f85e", + "0x956b537703133b6ddf620d873eac67af058805a8cc4beb70f9c16c6787bf3cc9765e430d57a84a4c3c9fbdd11a007257", + "0x835ae5b3bb3ee5e52e048626e3ddaa49e28a65cb94b7ecdc2e272ff603b7058f1f90b4c75b4b9558f23851f1a5547a35", + "0x85d67c371d1bf6dc72cca7887fa7c886ce988b5d77dc176d767be3205e80f6af2204d6530f7060b1f65d360a0eaeff30", + "0xa84a6647a10fcef8353769ef5f55a701c53870054691a6e9d7e748cbe417b3b41dbb881bae67adc12cb6596c0d8be376", + "0x87ffe271fc0964cb225551c7a61008d8bcb8b3d3942970dbcc2b9f4f9045a767971880368ea254e2038a3a0b94ecf236", + "0x964bb721c51d43ee7dd67c1a2b7dd2cc672ce8fad78c22dcddb43e6aab48d9a4a7dc595d702aa54a6fb0ffabf01f2780", + "0xa89b3f84bb7dcbe3741749776f5b78a269f6b1bebb8e95d3cc80b834fd2177c6be058d16cacfd0d5e1e35e85cde8b811", + "0xb4314538e003a1587b5592ff07355ea03239f17e75c49d51f32babe8e048b90b046a73357bcb9ce382d3e8fbe2f8e68b", + "0x86daf4bf201ae5537b5d4f4d734ed2934b9cf74de30513e3280402078f1787871b6973aa60f75858bdf696f19935a0e2", + "0xb1adf5d4f83f089dc4f5dae9dbd215322fa98c964e2eaa409bf8ca3fa5c627880a014ed209492c3894b3df1c117236c4", + "0xb508d52382c5bac5749bc8c89f70c650bb2ed3ef9dc99619468c387c1b6c9ff530a906dfa393f78f34c4f2f31478508a", + "0xa8349a5865cb1f191bebb845dfbc25c747681d769dbffd40d8cedf9c9a62fa2cbc14b64bb6121120dab4e24bef8e6b37", + "0xaf0500d4af99c83db8890a25f0be1de267a382ec5e9835e2f3503e1bac9412acf9ff83a7b9385708ef8187a38a37bc77", + "0xb76d57a1c1f85b8a8e1722a47057b4c572800957a6b48882d1fc21309c2e45f648a8db0fcff760d1dbc7732cf37c009b", + "0xb93c996cec0d3714667b5a5a5f7c05a7dc00bbc9f95ac8e310626b9e41ae4cc5707fac3e5bd86e1e1f2f6d9627b0da94", + "0x93216fdb864217b4c761090a0921cf8d42649ab7c4da1e009ec5450432564cb5a06cb6e8678579202d3985bd9e941cef", + "0x8b8be41105186a339987ae3a5f075fbc91f34b9984d222dfed0f0f85d2f684b56a56ab5dc812a411570491743d6c8b18", + "0x959b72782a6b2469e77fe4d492674cc51db148119b0671bd5d1765715f49fa8a87e907646671161586e84979ef16d631", + "0x86b7fc72fb7e7904ea71d5e66ba0d5d898ace7850985c8cc4a1c4902c5bf94351d23ce62eed45e24321fb02adfa49fc8", + "0xa2f244e7c9aa272cb0d067d81d25e5a3045b80b5a520b49fd5996ece267a7f1bea42e53147bbf153d9af215ea605fc9e", + "0x81aa2efa5520eebc894ce909ba5ce3250f2d96baa5f4f186a0637a1eea0080dd3a96c2f9fadf92262c1c5566ddb79bab", + "0xb607dd110cfe510d087bcff9a18480ba2912662256d0ab7b1d8120b22db4ad036b2266f46152754664c4e08d0fc583f6", + "0x8f588d5f4837e41312744caac5eee9ddc3ad7085871041694f0b5813edf83dc13af7970f7c9b6d234a886e07fa676a04", + "0x924921b903207783b31016cbec4e6c99e70f5244e775755c90d03a8b769738be3ba61577aca70f706a9c2b80040c9485", + "0xae0a42a222f1a71cd0d3c69ffb2f04c13e1940cce8efabe032629f650be3ceed6abb79651dbb81cb39a33286eb517639", + "0xa07d7d76460f31f5f0e32e40a5ea908d9d2aebf111ac4fadee67ef6540b916733c35a777dcdc05f6417726ca1f2d57dd", + "0x88d7f8a31f8c99794291847d28745e5d0b5d3b9684ca4170b686ffbb5bb521a3ef6746c3c8db22e4250a0cdff7939d96", + "0x849573071fd98c020dc9a8622a9eff221cb9f889bde259e7127a8886b73bef7ad430b87750915658918dcfb6b7b4d8d3", + "0xb12d59f732fa47fad175d6263734da8db89230fd340a46ad1cdee51e577041a5c80bf24cd195593e637daf1a66ef5a98", + "0xabbcfb8a4a6d5e269ee1ac5e277df84416c73ca55ec88317f73608201af25af0cb65b943c54684a5651df3a26e3daca2", + "0xab157f589bdbaf067a6a7ba7513df0492933855d39f3a081196cf2352e0ddc0162d476c433320366e3df601e0556278d", + "0xa86c0619b92e5ae4f7daa876a2abc5ba189156afc2fa05eef464dfa342ba37fc670d0dc308ad3822fcb461ab001bac30", + "0xa3f292946476cfe8d5e544a5325439a00e0165a5f9bf3bb6a53f477baeac7697cc0377745536681aa116f326ce911390", + "0x8aecbbfd442a6a0f01c1c09db5d9d50213eb6f1ff6fab674cde3da06a4edff3ed317e804f78300c22ef70c336123e05d", + "0x834ed4b58211fcd647d7bf7c0a3ba9085184c5c856b085e8a0fcd5215c661ef43d36f3f0f6329a9f1370501b4e73b6e4", + "0xa114ea5ad2b402a0de6105e5730907f2f1e458d28ae35144cf49836e0ad21325fe3e755cfb67984ae0a32e65402aad1e", + "0xa005f12bed97d71cee288b59afe9affb4d256888727343944a99913980df2c963fe02f218e6ea992f88db693a4498066", + "0xa010f286ab06b966e3b91ff8f1bdbe2fe9ab41a27bc392d5787aa02a46e5080e58c62c7d907818caae9f6a8b8123e381", + "0x857bd6df2ddef04dbc7c4f923e0b1696d3016c8bfed07fdfa28a3a3bd62d89b0f9df49aae81cbb6883d5e7b4fadae280", + "0xb3927030da445bc4756ac7230a5d87412a4f7510581fb422212ce2e8cf49689aca7ba71678743af06d4de4914c5aa4a0", + "0xb86403182c98fcce558d995f86752af316b3b2d53ba32075f71c7da2596747b7284c34a1a87de604fcc71e7e117a8add", + "0x98dd19b5527733041689b2a4568edaf6aa0fe1a3dd800c290cda157b171e053648a5772c5d3d4c80e5a795bc49adf12e", + "0x88a3c227bb7c9bff383f9ad3f7762245939a718ab85ae6e5e13180b12bf724d42054d3852b421c1cd1b3670baddecb63", + "0xb3cfd9ad66b52bbe57b5fff0fad723434d23761409b92c4893124a574acc1e6b1e14b4ec507661551cbbe05e16db362e", + "0x923e1bb482cf421dd77801f9780f49c3672b88508a389b94015fd907888dc647ee9ea8ec8d97131d235d066daf1f42b7", + "0x8d5e16240f04f92aa948181d421006bdbc7b215648fb6554193224d00cf337ebbb958f7548cf01b4d828acffb9fbc452", + "0x8b2b8f18ad0559746f6cda3acca294a1467fb1a3bc6b6371bc3a61a3bfe59418934fa8706f78b56005d85d9cb7f90454", + "0xa9316e2a94d6e31426d2ae7312878ba6baaac40f43e2b8a2fa3ab5a774c6918551554b2dbb23dc82f70ba3e0f60b5b0d", + "0x9593116d92cf06b8cd6905a2ce569ee6e69a506c897911f43ae80fc66c4914da209fc9347962034eebbc6e3e0fe59517", + "0x887d89d2b2d3c82b30e8f0acf15f0335532bd598b1861755498610cb2dd41ff5376b2a0bb757cb477add0ce8cfe7a9fc", + "0xb514cfe17875ecb790ad055271cc240ea4bda39b6cfa6a212908849c0875cb10c3a07826550b24c4b94ea68c6bb9e614", + "0xa563d5187966d1257d2ed71d53c945308f709bcc98e3b13a2a07a1933dc17bcb34b30796bd68c156d91811fbd49da2cb", + "0xa7195ccc53b58e65d1088868aeeb9ee208103e8197ad4c317235bb2d0ad3dc56cb7d9a7186416e0b23c226078095d44c", + "0xa838e7a368e75b73b5c50fbfedde3481d82c977c3d5a95892ac1b1a3ea6234b3344ad9d9544b5a532ccdef166e861011", + "0x9468ed6942e6b117d76d12d3a36138f5e5fb46e3b87cf6bb830c9b67d73e8176a1511780f55570f52d8cdb51dcf38e8c", + "0x8d2fc1899bc3483a77298de0e033085b195caf0e91c8be209fd4f27b60029cbe1f9a801fbd0458b4a686609762108560", + "0x8f4e44f8ca752a56aa96f3602e9234ad905ad9582111daf96a8c4d6f203bf3948f7ce467c555360ad58376ee8effd2ba", + "0x8fb88640b656e8f1c7c966c729eb2ba5ccf780c49873f8b873c6971840db7d986bdf1332ba80f8a0bb4b4ee7401468fa", + "0xb72aa3235868186913fb5f1d324e748cd3ce1a17d3d6e6ea7639a5076430fe0b08841c95feb19bb94181fe59c483a9eb", + "0xb8b102690ebb94fc4148742e7e3fd00f807b745b02cbe92cd92992c9143b6db7bb23a70da64a8b2233e4a6e572fc2054", + "0x8c9ae291f6cd744e2c6afe0719a7fc3e18d79307f781921fb848a0bf222e233879c1eca8236b4b1be217f9440859b6ce", + "0xa658ede47e14b3aad789e07f5374402f60e9cacb56b1b57a7c6044ca2418b82c98874e5c8c461898ebd69e38fecd5770", + "0x89c0cb423580e333923eb66bda690f5aca6ec6cba2f92850e54afd882ba608465a7dbb5aa077cd0ca65d9d00909348ab", + "0xaed8e28d98d5508bd3818804cf20d296fe050b023db2ed32306f19a7a3f51c7aaafed9d0847a3d2cd5ba5b4dabbc5401", + "0x96a0fcd6235f87568d24fb57269a94402c23d4aa5602572ad361f3f915a5f01be4e6945d576d51be0d37c24b8b0f3d72", + "0x935d0c69edd5dfa8ed07c49661b3e725b50588f814eb38ea31bcc1d36b262fae40d038a90feff42329930f8310348a50", + "0x900518288aa8ea824c7042f76710f2ea358c8bb7657f518a6e13de9123be891fa847c61569035df64605a459dad2ecc8", + "0x947d743a570e84831b4fb5e786024bd752630429d0673bf12028eb4642beb452e133214aff1cfa578a8856c5ebcb1758", + "0xa787266f34d48c13a01b44e02f34a0369c36f7ec0aae3ec92d27a5f4a15b3f7be9b30b8d9dd1217d4eeedff5fd71b2e5", + "0xa24b797214707ccc9e7a7153e94521900c01a1acd7359d4c74b343bfa11ea2cdf96f149802f4669312cd58d5ab159c93", + "0x97f5ee9c743b6845f15c7f0951221468b40e1edaef06328653a0882793f91e8146c26ac76dd613038c5fdcf5448e2948", + "0x80abd843693aed1949b4ea93e0188e281334163a1de150c080e56ca1f655c53eb4e5d65a67bc3fc546ed4445a3c71d00", + "0x908e499eb3d44836808dacff2f6815f883aeced9460913cf8f2fbbb8fe8f5428c6fc9875f60b9996445a032fd514c70f", + "0xae1828ef674730066dc83da8d4dd5fa76fc6eb6fa2f9d91e3a6d03a9e61d7c3a74619f4483fe14cddf31941e5f65420a", + "0xa9f4dbe658cd213d77642e4d11385a8f432245b098fccd23587d7b168dbeebe1cca4f37ee8d1725adb0d60af85f8c12f", + "0x93e20ee8a314b7772b2439be9d15d0bf30cd612719b64aa2b4c3db48e6df46cea0a22db08ca65a36299a48d547e826a7", + "0xa8746a3e24b08dffa57ae78e53825a9ddbbe12af6e675269d48bff4720babdc24f907fde5f1880a6b31c5d5a51fbb00e", + "0xb5e94dfab3c2f5d3aea74a098546aa6a465aa1e3f5989377d0759d1899babf543ad688bb84811d3e891c8713c45886c5", + "0xa3929bada828bd0a72cda8417b0d057ecb2ddd8454086de235540a756e8032f2f47f52001eb1d7b1355339a128f0a53b", + "0xb684231711a1612866af1f0b7a9a185a3f8a9dac8bde75c101f3a1022947ceddc472beb95db9d9d42d9f6ccef315edbc", + "0xaf7809309edbb8eb61ef9e4b62f02a474c04c7c1ffa89543d8c6bf2e4c3d3e5ecbd39ec2fc1a4943a3949b8a09d315a6", + "0xb6f6e224247d9528ef0da4ad9700bee6e040bbf63e4d4c4b5989d0b29a0c17f7b003c60f74332fefa3c8ddbd83cd95c1", + "0xadbcec190a6ac2ddd7c59c6933e5b4e8507ce5fd4e230effc0bd0892fc00e6ac1369a2115f3398dfc074987b3b005c77", + "0x8a735b1bd7f2246d3fa1b729aecf2b1df8e8c3f86220a3a265c23444bdf540d9d6fe9b18ed8e6211fad2e1f25d23dd57", + "0x96b1bf31f46766738c0c687af3893d098d4b798237524cb2c867ed3671775651d5852da6803d0ea7356a6546aa9b33f2", + "0x8036e4c2b4576c9dcf98b810b5739051de4b5dde1e3e734a8e84ab52bc043e2e246a7f6046b07a9a95d8523ec5f7b851", + "0x8a4f4c32ee2203618af3bb603bf10245be0f57f1cfec71037d327fa11c1283b833819cb83b6b522252c39de3ce599fa5", + "0xad06ed0742c9838e3abaaffdb0ac0a64bad85b058b5be150e4d97d0346ed64fd6e761018d51d4498599669e25a6e3148", + "0x8d91cb427db262b6f912c693db3d0939b5df16bf7d2ab6a7e1bc47f5384371747db89c161b78ff9587259fdb3a49ad91", + "0xae0a3f84b5acb54729bcd7ef0fbfdcf9ed52da595636777897268d66db3de3f16a9cf237c9f8f6028412d37f73f2dfad", + "0x8f774109272dc387de0ca26f434e26bc5584754e71413e35fa4d517ee0f6e845b83d4f503f777fe31c9ec05796b3b4bc", + "0xa8670e0db2c537ad387cf8d75c6e42724fae0f16eca8b34018a59a6d539d3c0581e1066053a2ec8a5280ffabad2ca51f", + "0xac4929ed4ecad8124f2a2a482ec72e0ef86d6a4c64ac330dab25d61d1a71e1ee1009d196586ce46293355146086cabba", + "0x845d222cb018207976cc2975a9aa3543e46c861486136d57952494eb18029a1ebb0d08b6d7c67c0f37ee82a5c754f26f", + "0xb99fa4a29090eac44299f0e4b5a1582eb89b26ed2d4988b36338b9f073851d024b4201cd39a2b176d324f12903c38bee", + "0x9138823bc45640b8f77a6464c171af2fe1700bdc2b7b88f4d66b1370b3eafe12f5fbb7b528a7e1d55d9a70ca2f9fc8e6", + "0x8ac387dc4cf52bc48a240f2965ab2531ae3b518d4d1f99c0f520a3d6eb3d5123a35ef96bed8fa71ee2f46793fa5b33b3", + "0x864adec6339d4c2ba2525621fceabd4c455902f6f690f31a26e55413e0722e5711c509dc47ce0bcc27bbdc7651768d2d", + "0xa0a52edb72268a15201a968dabc26a22909620bda824bd548fb8c26cc848f704166ed730d958f0173bd3b0a672f367bd", + "0x949e445b0459983abd399571a1a7150aab3dd79f4b52a1cd5d733e436c71c1d4b74287c6b0ce6cc90c6711ba4c541586", + "0x858966355dac11369e3b6552f2b381665181693d5a32e596984da3314021710b25a37d8c548b08700eea13d86cb22f21", + "0x974bcbb8d38c5e6518745cc03ad436e585b61f31d705e7e2e5085da9655d768ac4d800904f892c3dab65d6223e3f1fd6", + "0x8092b6506b01308bf6187fde5ebd4fa7448c9a640961ba231be22ac5fa2c7635ef01e8b357722c7695d09b723101ea2a", + "0xa5b8ef360bf28533ee17d8cd131fff661d265f609db49599085c0c7d83b0af409a1b5c28e3a5e5d7f8459a368aa121e8", + "0xb031b6d5e3ceab0f0c93314b3b675f55cf18cbc86f70444af266fe39cb22fd7dad75d8c84e07f1c1bfa2cb8283e1361a", + "0x93ad489e4f74658320c1cceed0137c023d3001a2c930ed87e6a21dbf02f2eb6ad1c1d8bcb3739c85dcfbecb040928707", + "0xb15e4ec2cdab0d34aec8d6c50338812eb6ecd588cf123a3e9d22a7ca23b5a98662af18289f09e6cdd85a39a2863c945c", + "0xb304f71a9717cf40c22073f942618b44bf27cd5e2ed4a386ad45d75b0fcb5a8dafd35158211eaf639495c6f1a651cedb", + "0xb82d78d3eaaa7c5101b7a5aae02bd4f002cd5802d18c3abcda0dd53b036661c6d3c8b79e0abe591eab90b6fdc5fef5e3", + "0xabbd1884243a35578b80914a5084449c237ee4e4660c279d1073a4d4217d1b55c6b7e9c087dfd08d94ac1416273d8d07", + "0x92f4b61c62502745e3e198ec29bca2e18696c69dcb914d1f3a73f4998d012b90caf99df46e9bb59942e43cce377fe8fd", + "0x906e79df98185820c8208844e1ba6bd86cb96965814b01310bd62f22cbec9b5d379b2ef16772d6fc45a421b60cfd68fe", + "0xa0eae2784ef596e2eb270dd40c48d6c508e4394c7d6d08d4cc1b56fde42b604d10ba752b3a80f2c4a737e080ef51b44f", + "0x94c084985e276dc249b09029e49a4ef8a369cd1737b51c1772fbb458d61e3fe120d0f517976eba8ffa5711ba93e46976", + "0x83619a0157eff3f480ab91d1d6225fead74c96a6fd685333f1e8e4d746f6273e226bad14232f1d1168a274e889f202f1", + "0xa724fe6a83d05dbbf9bb3f626e96db2c10d6d5c650c0a909415fbda9b5711c8b26e377201fb9ce82e94fa2ab0bf99351", + "0xa8a10c1b91a3a1fa2d7fd1f78a141191987270b13004600601d0f1f357042891010717319489f681aa8a1da79f7f00d5", + "0xa398a2e95b944940b1f8a8e5d697c50e7aa03994a8a640dfad4ea65cfb199a4d97861a3ec62d1c7b2b8d6e26488ca909", + "0xa2eedfe5452513b2a938fffd560798ef81379c5a5032d5b0da7b3bb812addbaad51f564c15d9acbbfc59bb7eddd0b798", + "0xab31c572f6f145a53e13b962f11320a1f4d411739c86c88989f8f21ab629639905b3eedb0628067942b0dc1814b678ca", + "0xad032736dd0e25652d3566f6763b48b34ea1507922ed162890cd050b1125ec03b6d41d34fccba36ec90336f7cdf788ed", + "0x83028a558a5847293147c483b74173eca28578186137df220df747fccd7d769528d7277336ea03c5d9cdd0bc5ae3d666", + "0xab5d182cd1181de8e14d3ef615580217c165e470b7a094a276b78a3003089123db75c6e1650bf57d23e587c587cd7472", + "0xa4793e089fbdb1597654f43b4f7e02d843d4ab99ee54099c3d9f0bd5c0c5657c90bb076379a055b00c01b12843415251", + "0x98bdc52ee062035356fb2b5c3b41673198ddc60b2d1e546cb44e3bb36094ef3c9cf2e12bbc890feb7d9b15925439d1ea", + "0xa4f90cca6f48024a0341bd231797b03693b34e23d3e5b712eb24aba37a27827319b2c16188f97c0636a0c115381dc659", + "0x8888e6c2e4a574d04ba5f4264e77abc24ccc195f1a7e3194169b8a2ceded493740c52db4f9833b3dbf4d67a3c5b252cb", + "0x83dc4e302b8b0a76dc0292366520b7d246d73c6aebe1bdd16a02f645c082197bcff24a4369deda60336172cefbcf09af", + "0xa4eb2741699febfeb793914da3054337cc05c6fa00d740e5f97cb749ae16802c6256c9d4f0f7297dcdbb8b9f22fc0afa", + "0x8b65557d5be273d1cb992a25cfce40d460c3f288d5cb0a54bdef25cbd17cdea5c32ec966e493addf5a74fd8e95b23e63", + "0x97c6577e76c73837bcb398b947cb4d3323d511141e0ddd0b456f59fbb1e8f920a5c20d7827a24309145efddee786140f", + "0xabcc0849ffe2a6a72157de907907b0a52deece04cf8317bee6fe1d999444b96e461eac95b6afde3d4fe530344086a625", + "0x9385c0115cb826a49df1917556efa47b5b5e4022b6a0d2082053d498ec9681da904ecf375368bb4e385833116ea61414", + "0x8b868c1841f0cdc175c90a81e610b0652c181db06731f5c8e72f8fafa0191620742e61a00db8215a991d60567b6a81ca", + "0xa8df15406f31b8fcf81f8ff98c01f3df73bf9ec84544ddec396bdf7fafa6fe084b3237bf7ef08ad43b26517de8c3cd26", + "0xa9943d21e35464ce54d4cc8b135731265a5d82f9ccf66133effa460ffdb443cdb694a25320506923eede88d972241bf2", + "0xa1378ee107dd7a3abcf269fd828887c288363e9b9ca2711377f2e96d2ed5e7c5ec8d3f1da995a3dcbedf1752d9c088fc", + "0x8a230856f9227b834c75bdebc1a57c7298a8351874bf39805c3e0255d6fd0e846f7ad49709b65ec1fd1a309331a83935", + "0x877bcf42549d42610e1780e721f5800972b51ba3b45c95c12b34cb35eeaf7eac8fa752edd7b342411820cf9093fea003", + "0x84c7a0b63842e50905624f1d2662506b16d1f3ea201877dfc76c79181c338b498eceb7cad24c2142c08919120e62f915", + "0x8e18b1bd04b1d65f6ed349b5d33a26fe349219043ead0e350b50ae7a65d6ff5f985dd9d318d3b807d29faa1a7de4fe42", + "0x8ea7b5a7503e1f0b3c3cd01f8e50207044b0a9c50ed1697794048bbe8efd6659e65134d172fb22f95439e1644f662e23", + "0xb1954a2818cad1dad6d343a7b23afa9aa8ad4463edc4eb51e26e087c2010927535020d045d97d44086d76acdb5818cbf", + "0xa5271ea85d0d21fa1ff59b027cf88847c0f999bbf578599083ff789a9b5228bc161e1c81deb97e74db1a82a0afd61c50", + "0xaa2fa4c05af3387e2c799315781d1910f69977ec1cfea57a25f1a37c63c4daaa3f0ecd400884a1673e17dd5300853bcf", + "0xb1cd2a74ca0b8e6090da29787aef9b037b03b96607983a308b790133bd21297b21ca4e2edec890874096dbf54e9d04c3", + "0x801931607ec66a81272feaa984f0b949ad12d75ecf324ba96627bd4dc5ddead8ebf088f78e836b6587c2b6c0b3366b6c", + "0x95d79504710bdf0ad9b9c3da79068c30665818c2f0cdbba02cc0a5e46e29d596032ac984441b429bd62e34535c8d55b0", + "0x9857d41e25e67876510ff8dadf0162019590f902da1897da0ef6fc8556e3c98961edb1eb3a3a5c000f6c494413ded15e", + "0x8740c9ffe6bd179c19a400137c3bd3a593b85bd4c264e26b4dfb9e2e17ac73e5b52dfacc1dcb4033cfc0cd04785f4363", + "0x977f98f29d948b4097a4abdf9345f4c1fb0aa94ba0c6bf6faa13b76f3a3efc8f688e1fe96099b71b3e1c05041118c8d1", + "0xa364422b1239126e3e8d7b84953ce2181f9856319b0a29fcab81e17ac27d35798088859c1cfc9fc12b2dbbf54d4f70b3", + "0xa0f6ba637f0db7a48e07439bb92ddb20d590ce9e2ed5bab08d73aa22d82c32a9a370fe934cbe9c08aeb84b11adcf2e0e", + "0xa2c548641bd5b677c7748327cca598a98a03a031945276be6d5c4357b6d04f8f40dd1c942ee6ec8499d56a1290ac134d", + "0x9863e9cc5fbcdbd105a41d9778d7c402686bfd2d81d9ed107b4fda15e728871c38647529693306855bee33a00d257a7e", + "0xa54173bf47b976290c88fd41f99300135de222f1f76293757a438450880e6f13dbde3d5fe7afc687bdfbcfc4fbc1fc47", + "0xb8db413917c60907b73a997b5ab42939abd05552c56a13525e3253eb72b83f0d5cc52b695968a10005c2e2fe13290e61", + "0xa1f8388ef21697c94ba90b1a1c157f0dc138e502379e6fc5dc47890d284563e5db7716266e1b91927e5adf3cde4c0a72", + "0x9949013a59d890eb358eab12e623b2b5edb1acbee238dfad8b7253102abc6173922e188d5b89ec405aa377be8be5f16d", + "0xa00fdb7710db992041f6ddb3c00099e1ce311dea43c252c58f560c0d499983a89de67803a8e57baa01ee9d0ee6fa1e44", + "0xa8b1bcbed1951c9cdb974b61078412881b830b48cd6b384db0c00fa68bcc3f4312f8e56c892ea99d3511857ef79d3db9", + "0x8f3ee78404edc08af23b1a28c2012cee0bdf3599a6cb4ea689fc47df4a765ef519191819a72562b91a0fbcdb896a937e", + "0x8155bbb7fa8d386848b0a87caae4da3dec1f3dade95c750a64a8e3555166ccc8799f638bd80ed116c74e3a995541587a", + "0xabfe30adbc0a6f1fd95c630ed5dac891b85384fa9331e86b83217f29dff0bd7cad19d328485715a7e3df9a19069d4d2f", + "0x89d0783e496ee8dbb695764b87fb04cee14d4e96c4ba613a19736971c577d312079048142c12ce5b32b21e4d491d281b", + "0x856b8dbc9c5d8f56b6bb7d909f339ca6da9a8787bba91f09130a025ab6d29b64dbf728ba6ed26e160a23c1cdb9bc037b", + "0x8a30dd2ea24491141047a7dfe1a4af217661c693edf70b534d52ca547625c7397a0d721e568d5b8398595856e80e9730", + "0xae7e1412feb68c5721922ed9279fb05549b7ef6812a4fd33dbbbd7effab756ab74634f195d0c072143c9f1fd0e1ee483", + "0xb7ce970e06fa9832b82eef572f2902c263fda29fdce9676f575860aae20863046243558ede2c92343616be5184944844", + "0x85ed0531f0e5c1a5d0bfe819d1aa29d6d5ff7f64ad8a0555560f84b72dee78e66931a594c72e1c01b36a877d48e017ca", + "0xb8595be631dc5b7ea55b7eb8f2982c74544b1e5befc4984803b1c69727eac0079558182f109e755df3fd64bee00fcaa5", + "0x99e15a66e5b32468ef8813e106271df4f8ba43a57629162832835b8b89402eb32169f3d2c8de1eb40201ce10e346a025", + "0x844c6f5070a8c73fdfb3ed78d1eddca1be31192797ad53d47f98b10b74cc47a325d2bc07f6ee46f05e26cf46a6433efb", + "0x974059da7f13da3694ad33f95829eb1e95f3f3bfc35ef5ef0247547d3d8ee919926c3bd473ab8b877ff4faa07fcc8580", + "0xb6f025aecc5698f6243cc531782b760f946efebe0c79b9a09fe99de1da9986d94fa0057003d0f3631c39783e6d84c7d5", + "0xb0c5358bc9c6dfe181c5fdf853b16149536fbb70f82c3b00db8d854aefe4db26f87332c6117f017386af8b40288d08f9", + "0xa3106be5e52b63119040b167ff9874e2670bd059b924b9817c78199317deb5905ae7bff24a8ff170de54a02c34ff40a4", + "0xad846eb8953a41c37bcd80ad543955942a47953cbc8fb4d766eac5307892d34e17e5549dc14467724205255bc14e9b39", + "0xb16607e7f0f9d3636e659e907af4a086ad4731488f5703f0917c4ce71a696072a14a067db71a3d103530920e1ec50c16", + "0x8ed820e27116e60c412c608582e9bb262eaaf197197c9b7df6d62b21a28b26d49ea6c8bb77dfde821869d9b58025f939", + "0x97bc25201d98cde389dd5c0c223a6f844393b08f75d3b63326343073e467ac23aacef630ddc68545ea874299ba4a3b4f", + "0xb73c9695ad2eefd6cc989a251c433fab7d431f5e19f11d415a901762717d1004bb61e0cc4497af5a8abf2d567e59fef4", + "0xadaabe331eea932533a7cc0cf642e2a5e9d60bbc92dd2924d9b429571cbf0d62d32c207b346607a40643c6909b8727e2", + "0xa7b1bbfe2a5e9e8950c7cb4daab44a40c3ffab01dc012ed7fe445f4af47fa56d774a618fafe332ab99cac4dfb5cf4794", + "0xb4a3c454dcd5af850212e8b9ba5fe5c0d958d6b1cabbf6c6cfe3ccbc4d4c943309c18b047256867daf359006a23f3667", + "0xa5c0b32f6cef993834c1381ec57ad1b6f26ae7a8190dd26af0116e73dadc53bb0eeb1911419d609b79ce98b51fdc33bc", + "0xac2f52de3ecf4c437c06c91f35f7ac7d171121d0b16d294a317897918679f3b9db1cef3dd0f43adb6b89fe3030728415", + "0x94722ae6d328b1f8feaf6f0f78804e9b0219de85d6f14e8626c2845681841b2261d3e6a2c5b124086b7931bf89e26b46", + "0xa841a0602385d17afabca3a1bb6039167d75e5ec870fea60cfcaec4863039b4d745f1a008b40ec07bca4e42cb73f0d21", + "0x8c355f0a1886ffced584b4a002607e58ff3f130e9de827e36d38e57cb618c0cb0b2d2dea2966c461cb3a3887ede9aef1", + "0xa6a9817b0fc2fd1786f5ba1a7b3d8595310987fb8d62f50a752c6bb0b2a95b67d03a4adfd13e10aa6190a280b7ee9a67", + "0xa1d2e552581ecbafeaef08e389eaa0b600a139d446e7d0648ac5db8bbbf3c438d59497e3a2874fc692b4924b87ff2f83", + "0xa1b271c55389f25639fe043e831e2c33a8ba045e07683d1468c6edd81fedb91684e4869becfb164330451cfe699c31a8", + "0x8c263426e7f7e52f299d57d047a09b5eeb893644b86f4d149535a5046afd655a36d9e3fdb35f3201c2ccac2323a9582e", + "0xb41c242a7f7880c714241a97d56cce658ee6bcb795aec057a7b7c358d65f809eb901e0d51256826727dc0dc1d1887045", + "0x93001b9445813c82f692f94c0dc1e55298f609936b743cf7aae5ebfa86204f38833d3a73f7b67314be67c06a1de5682d", + "0x82087536dc5e78422ad631af6c64c8d44f981c195ddea07d5af9bb0e014cdc949c6fa6e42fce823e0087fdb329d50a34", + "0x8e071861ceba2737792741c031f57e0294c4892684506b7c4a0fc8b2f9a0a6b0a5635de3d1e8716c34df0194d789ae86", + "0xb471c997e1e11774bd053f15609d58838a74073a6c089a7a32c37dd3f933badf98c7e5833263f3e77bc0d156a62dd750", + "0x8d2d8686fb065b61714414bb6878fff3f9e1e303c8e02350fd79e2a7f0555ded05557628152c00166ce71c62c4d2feaa", + "0xae4c75274d21c02380730e91de2056c0262ffcecf0cbdb519f0bdb0b5a10ae2d4996b3dc4b3e16dbaea7f0c63d497fef", + "0x97140d819e8ca6330e589c6debdee77041c5a9cedb9b8cbd9c541a49207eeb7f6e6b1c7e736ec8ba6b3ab10f7fcd443a", + "0xaf6659f31f820291a160be452e64d1293aa68b5074b4c066dac169b8d01d0179139504df867dc56e2a6120354fc1f5be", + "0xa5e5d8088a368024617bfde6b731bf9eee35fc362bed3f5dfdd399e23a2495f97f17728fec99ca945b3282d1858aa338", + "0xa59cfc79d15dbdde51ab8e5129c97d3baba5a0a09272e6d2f3862370fdbaf90994e522e8bd99d6b14b3bb2e9e5545c6f", + "0xa30499b068083b28d6c7ddcc22f6b39b5ec84c8ee31c5630822c50ea736bb9dca41c265cffc6239f1c9ef2fd21476286", + "0x88ffe103eca84bbe7d1e39a1aa599a5c7c9d5533204d5c4e085402a51441bb8efb8971efe936efbbfa05e5cb0d4b8017", + "0xb202356fbf95a4d699154639e8cb03d02112c3e0128aab54d604645d8510a9ba98936028349b661672c3a4b36b9cb45d", + "0x8b89bb6574bf3524473cff1ff743abcf1406bd11fb0a72070ccd7d8fce9493b0069fb0c6655252a5164aee9e446ea772", + "0x93247b1038fa7e26667ee6446561d4882dc808d1015daafb705935ddc3598bb1433182c756465960480f7b2de391649e", + "0xb027f94d3358cbb8b6c8c227300293a0dee57bf2fee190a456ad82ecfb6c32f8090afa783e2ab16f8139805e1fb69534", + "0xa18bb1849b2f06c1d2214371031d41c76ffa803ee3aa60920d29dbf3db5fbfac2b7383d5d0080ba29ce25c7baa7c306b", + "0x827bf9fd647e238d5ac961c661e5bbf694b4c80b3af8079f94a2484cb8fba2c8cf60e472ebcd0b0024d98ae80ad2ff5a", + "0x838e891218c626a7f39b8fd546b013587408e8e366ecc636b54f97fa76f0a758bc1effa1d0f9b6b3bc1a7fcc505970a0", + "0x836523b5e8902d6e430c6a12cff01e417d2bd7b402e03904034e3b39755dee540d382778c1abe851d840d318ebedce7f", + "0x850a77dda9ac6c217e2ef00bf386a1adec18b7f462f52801c4f541215690502a77ef7519b690e22fdf54dc2109e0ca38", + "0xa8265c6ae7b29fc2bda6a2f99ced0c1945dd514b1c6ca19da84b5269514f48a4f7b2ccbab65c9107cfd5b30b26e5462f", + "0xab3d02ee1f1267e8d9d8f27cc388e218f3af728f1de811242b10e01de83471a1c8f623e282da5a284d77884d9b8cde0e", + "0x831edaf4397e22871ea5ddee1e7036bab9cc72f8d955c7d8a97f5e783f40532edbbb444d0520fefcffeab75677864644", + "0x80484487977e4877738744d67b9a35b6c96be579a9faa4a263e692295bb6e01f6e5a059181f3dd0278e2c3c24d10a451", + "0xaae65a18f28c8812617c11ecf30ad525421f31fb389b8b52d7892415e805a133f46d1feca89923f8f5b8234bd233486a", + "0xb3a36fd78979e94288b4cefed82f043a7e24a4a8025479cc7eb39591e34603048a41ee606ee03c0b5781ebe26a424399", + "0xb748b3fc0d1e12e876d626a1ba8ad6ad0c1f41ea89c3948e9f7d2666e90173eb9438027fadcd741d3ae0696bd13840f1", + "0xacdd252d7c216c470683a140a808e011c4d5f1b4e91aeb947f099c717b6a3bad6651142cde988330827eb7d19d5fb25c", + "0xb9a25556a6ca35db1ed59a1ec6f23343eab207a3146e4fc3324136e411c8dba77efd567938c63a39c2f1c676b07d8cdb", + "0xa8db6aef8f5680d2bdb415d7bcaae11de1458678dcb8c90c441d5986c44f83a9e5855662d0c1aace999172d8628d8fe1", + "0xaf58147108e9909c3a9710cc186eab598682dca4bfd22481e040b8c000593ecb22c4ede4253ac9504e964dfa95a9b150", + "0x8dd8bb70f1c9aec0fcc9478f24dfc9c3c36c0bf5ff7a67c017fa4dab2ec633fbd7bc9d8aa41ea63e2696971ed7e375f5", + "0xaa98d600b22aff993a4d7a3ccabd314e1825b200cb598f6b797d7e4d6a76d89e34a4d156c06bddfc62f2ef9b4c809d1d", + "0x8a8fc960d6c51294b8205d1dabe430bef59bda69824fa5c3c3105bef22ac77c36d2d0f38ffc95ce63731de5544ccbeff", + "0xb6d1020efe01dc8032bd1b35e622325d7b9af9dcd5c9c87c48d7d6ebc58644454294c59b7f4b209204b5b1f899f473bf", + "0x8a750dc9fe4891f2dfe5759fb985939810e4cdc0b4e243ff324b6143f87676d8cb4bcb9dfb01b550801cedcaaa5349e2", + "0x98c13142d3a9c5f8d452245c40c6dae4327dd958e0fda85255ea0f87e0bcbaa42a3a0bd50407ed2b23f9f6317a8a4bc5", + "0x99f2b83d9ec4fc46085a6d2a70fd0345df10f4a724c1ba4dee082a1fde9e642e3091992ebf5f90a731abcb6ec11f6d9b", + "0xb218546ab2db565b2489ea4205b79daa19ef2acbf772ccaaa5e40150e67ea466090d07198444b48e7109939aa2319148", + "0x84f9d1d868e4b55e535f1016558f1789df0daa0ead2d13153e02f715fe8049b1ce79f5bc1b0bbbb0b7e4dd3c04783f3f", + "0x80d870d212fbddfdda943e90d35a5a8aa0509a7a1e7f8909f2fcb09c51c3026be47cc7a22620a3063406872105b4f81a", + "0xb5b15138ff6551fac535d4bbce2ea6adc516b6b7734b4601c66ec029da2615e3119dc9ad6a937344acfd7b50e4a1a2ae", + "0x95d2f97652086e7ceb54e1d32692b1c867ffba23c4325740c7f10d369283d1b389e8afa0df967831ade55696931e7934", + "0x8a5b580403e1a99cd208f707e8ce0d3f658c8280417683f69008d09cc74d835a85f7380f391b36ead9ac66d9eedd1cbe", + "0xa8b0c90bff34c86720637b5a2081f0f144cfe2205c1176cacd87d348609bc67af68aed72414dc9aa6f44a82c92c2a890", + "0x865abbdd96c496892c165a8de0f9e73348bf24fce361d7a9048710178a3625881afb0006e9f5ee39124866b87904c904", + "0xace67bb994adef4b6f841cdf349195608030044562780a7e9b00b58a4ff117268a03ff01e5a3a9d9d7eff1dd01f5f4bf", + "0xb9371d59185b3d2d320d3fefeadb06ba2aa7d164352fb8dc37571509509fa214d736d244ac625a09a033a10d51611e2e", + "0xa8ef992771422dcf2d6d84386fde9fe5dba88bfded3dfcd14074ca04331b4fd53a7f316615cdfaf10ed932cbb424a153", + "0x868cbc75f8f789ea45eded2768a1dac0763347e0d8e8028d316a21005f17be179d26d5965903e51b037f2f57fe41765d", + "0xb607111bcdfd05fa144aa0281b13ee736079ebbbf384d938a60e5e3579639ed8ef8eb9ca184868cdb220a8e130d4a952", + "0xaca55702af5cae4cae65576769effd98858307a71b011841c563b97c2aa5aeb5c4f8645d254f631ed1582df3dbbf17da", + "0xb9b5cbace76246e80c20dfcc6f1e2c757a22ab53f7fd9ff8a1d309538b55174e55e557a13bf68f095ff6a4fa637ef21a", + "0x8571b0a96871f254e2397c9be495c76379faf347801cb946b94e63212d6a0da61c80e5d7bebbabcd6eaa7f1029172fe5", + "0x902540326281e6dc9c20d9c4deaaf6fbbbcc3d1869bd0cf7f081c0525bea33df5cfa24ead61430fda47fb964fcc7994b", + "0x841af09279d3536a666fa072278950fabf27c59fc15f79bd52acb078675f8087f657929c97b4bc761cbade0ecb955541", + "0xa1f958b147ddf80ab2c0746ba11685c4bae37eb25bfa0442e7e1078a00d5311d25499da30f6d168cb9302ea1f2e35091", + "0x863d939381db37d5a5866964be3392a70be460f0353af799d6b3ed6307176972686bd378f8ad457435a4094d27e8dfb7", + "0x835cd4d7f36eff553d17483eb6c041b14280beb82c7c69bca115929658455a1931212976c619bafb8179aed9940a8cc6", + "0x8d0770e3cb8225e39c454a1fc76954118491b59d97193c72c174ecc7613051e5aed48a534016a8cf0795c524f771a010", + "0x91aa4edb82f6f40db2b7bd4789cc08786f6996ebed3cb6f06248e4884bc949793f04a4c5ea6eefe77984b1cc2a45d699", + "0x8fb494ca2449f659ff4838833507a55500a016be9293e76598bbae0a7cb5687e4693757c2b6d76e62bd6c7f19ed080bb", + "0xb59b104449a880a282c1dd6a3d8debb1d8814ef35aab5673c1e500ee4cb0e840fb23e05fa5a0af92509c26b97f098f90", + "0xaca908e3bad65e854ae6be6c5db441a06bcd47f5abafdfa8f5a83c8cd3c6e08c33cab139c45887887a478338e19ceb9f", + "0x806f5d802040313a31964fc3eb0ee18ac91b348685bed93c13440984ee46f3d2da7194af18c63dea4196549129660a4e", + "0xae4b2dca75c28d8f23b3ab760b19d839f39ff5a3112e33cb44cff22492604a63c382b88ec67be4b0266924dd438c3183", + "0x99d1c29c6bd8bf384e79cd46e30b8f79f9cbc7d3bf980e9d6ffba048f0fc487cac45c364a8a44bb6027ad90721475482", + "0xa16e861c1af76d35528c25bf804bfc41c4e1e91b2927d07d8e96bffe3a781b4934e9d131ecf173be9399800b8269efac", + "0xa253303234fb74f5829060cdcef1d98652441ab6db7344b1e470d195a95722675988048d840201c3b98e794b1e8b037c", + "0x905ac8a0ea9ce0eb373fb0f83dd4cbe20afb45b9d21ae307846fd4757d4d891b26a6711924e081e2b8151e14a496da18", + "0xb485315791e775b9856cc5a820b10f1fa5028d5b92c2f0e003ba55134e1eddb3eb25f985f2611a2257acf3e7cfdfab5e", + "0xb6189c0458b9a043ebc500abc4d88083a3487b7ac47ed5e13ab2a41e0a1bee50d54a406063f92bc96959f19e822a89a7", + "0xa30e15f995fd099a223fc6dc30dad4b8d40bee00caa2bc3223ba6d53cd717c4968a3e90c4618c711ed37cc4cd4c56cf3", + "0xa1b1ed07fcc350bb12a09cd343768d208fc51a6b3486f0ece8f5a52f8a5810b4bc7ab75582ec0bc2770aed52f68eace5", + "0x88aa739fbae4bece147ba51a863e45d5f7203dbc3138975dc5aef1c32656feb35f014d626e0d5b3d8b1a2bda6f547509", + "0xab570f3c8eabfca325b3a2ea775ef6b0c6e6138c39d53c2310329e8fb162869fde22b0e55688de9eb63d65c37598fca3", + "0x89d274762c02158e27cb37052e296a78f2b643eb7f9ae409f8dac5c587d8b4d82be4ef7c79344a08ebec16ac4a895714", + "0x99c411d2ad531e64f06e604d44c71c7c384424498ecd0a567d31ec380727fb605af76643d0d5513dd0a8d018076dd087", + "0x80d0777fa9f79f4a0f0f937d6de277eec22b3507e2e398f44b16e11e40edf5feff55b3b07a69e95e7e3a1621add5ed58", + "0xb2430a460783f44feb6e4e342106571ef81ad36e3ddd908ec719febeb7acaf4b833de34998f83a1dab8f0137a3744c11", + "0xb8f38ccfc7279e1e30ad7cefc3ea146b0e2dff62430c50a5c72649a4f38f2bac2996124b03af2079d942b47b078cc4f8", + "0xa178a450a62f30ec2832ac13bbc48789549c64fc9d607b766f6d7998558a0e2fad007ae0148fc5747189b713f654e6ba", + "0x98c5ede296f3016f6597f7ccc5f82c88fd38ed6dc3d6da3e4a916bfd7c4c95928722a1d02534fe89387c201d70aa6fd2", + "0xa8cc5e98573705d396576e022b2ba2c3e7c7ece45cd8605cb534b511763682582299e91b4bb4100c967019d9f15bbfaf", + "0x848480ea7b7d9536e469da721236d932870b7bbee31ccf7ae31b4d98d91413f59b94a1e0d1786ee7342295aa3734969c", + "0xb88ea38f9ee432f49e09e4e013b19dff5a50b65453e17caf612155fff6622198f3cba43b2ea493a87e160935aaaf20a9", + "0x949376934a61e0ef8894339c8913b5f3b228fa0ae5c532ad99b8d783b9e4451e4588541f223d87273c0e96c0020d5372", + "0x96f90bb65ca6b476527d32c415814b9e09061648d34993f72f28fae7dc9c197e04ef979f804076d107bb218dfd9cb299", + "0xa4402da95d9942c8f26617e02a7cef0ebc4b757fac72f222a7958e554c82cc216444de93f659e4a1d643b3e55a95d526", + "0x81179cbc26a33f6d339b05ea3e1d6b9e1190bd44e94161ae36357b9cdf1e37d745d45c61735feed64371fe5384102366", + "0xad4dc22bdbd60e147fdac57d98166de37c727f090059cfc33e5ee6cf85e23c2643996b75cf1b37c63f3dc9d3c57ffa18", + "0x8a9b1b93dc56e078ce3bb61c2b0088fd6c3e303ba6b943231cc79d4a8e8572f4109bbde5f5aa7333aae3287909cb0fe2", + "0x8876ef583bc1513322457a4807d03381ba1f4d13e179260eaa3bddfede8df677b02b176c6c9f74c8e6eab0e5edee6de6", + "0xb6c67e228bf190fbaeb2b7ec34d4717ce710829c3e4964f56ebb7e64dc85058c30be08030fa87cc94f1734c5206aef5f", + "0xa00cb53b804ee9e85ce12c0103f12450d977bc54a41195819973c8a06dcb3f46f2bf83c3102db62c92c57ab4dd1e9218", + "0xa7675a64772eefddf8e94636fb7d1d28f277074327c02eea8fae88989de0c5f2dc1efed010f4992d57b5f59a0ab40d69", + "0x8d42bb915e0bf6a62bcdf2d9330eca9b64f9ec36c21ae14bf1d9b0805e5e0228b8a5872be61be8133ad06f11cb77c363", + "0xa5b134de0d76df71af3001f70e65c6d78bed571bc06bfddf40d0baad7ea2767608b1777b7ef4c836a8445949877eeb34", + "0xaeadbc771eaa5de3a353229d33ed8c66e85efbd498e5be467709cb7ff70d3f1a7640002568b0940e3abd7b2da81d2821", + "0x8c28da8e57a388007bd2620106f6226b011ee716a795c5d9f041c810edf9cf7345b2e2e7d06d8a6b6afa1ee01a5badc1", + "0x8ed070626a4d39ffd952ddb177bc68fd35b325312e7c11694c99b691f92a8ea7734aeb96cf9cc73e05b3c1b1dcad6978", + "0xada83e18e4842f3d8871881d5dbc81aed88a1328298bfdc9e28275094bd88d71b02e7b8501c380fa8d93096cbc62f4fb", + "0x8befc3bec82dcf000a94603b4a35c1950ba5d00d4bed12661e4237afa75062aa5dcef8eac0b9803136c76d2dd424a689", + "0x97c6f36c91ca5ca9230bfcbf109d813728b965a29b62e5f54c8e602d14a52ac38fa1270de8bfe1ab365426f3fc3654c7", + "0xb01d192af3d8dbce2fe2fece231449e70eb9ac194ec98e758da11ca53294a0fa8c29b1d23a5d9064b938b259ea3b4fb5", + "0x819a2c20646178f2f02865340db1c3c6ebc18f4e6559dd93aa604388796a34bd9fed28ad3ccc8afc57a5b60bb5c4e4ec", + "0xa9ffc877470afc169fecf9ec2dc33253b677371938b0c4ffa10f77bb80089afa2b4488437be90bb1bcf7586a6f4286e3", + "0xb533051c7ce7107176bcb34ad49fdb41fac32d145854d2fe0a561c200dcf242da484156177e2c8f411c3fdf1559ecf83", + "0x8fe2caff2e4241d353110a3618832f1443f7afe171fd14607009a4a0aa18509a4f1367b67913e1235ac19de15e732eb1", + "0x84705c6370619403b9f498059f9869fdf5f188d9d9231a0cb67b1da2e8c906ead51b934286497293698bba269c48aa59", + "0x899dddf312a37e3b10bdaaacc1789d71d710994b6ee2928ac982ad3fd8a4f6167672bc8bf3419412711c591afe801c28", + "0xb2f7916d946b903ded57b9d57025386143410a41a139b183b70aeca09cf43f5089ead1450fce4e6eb4fba2c8f5c5bbe5", + "0x8d5f742fe27a41623b5820914c5ca59f82246010fa974304204839880e5d0db8bc45ebab2ad19287f0de4ac6af25c09e", + "0xb93d4a1f6f73ac34da5ffbd2a4199cf1d51888bc930dc3e481b78806f454fcb700b4021af7525b108d49ebbbaa936309", + "0x8606f8d9121512e0217a70249937e5c7f35fbfe019f02248b035fa3a87d607bc23ae66d0443e26a4324f1f8e57fd6a25", + "0xb21312cdec9c2c30dd7e06e9d3151f3c1aceeb0c2f47cf9800cce41521b9d835cb501f98b410dc1d49a310fdda9bc250", + "0xa56420b64286bdddda1e212bba268e9d1ba6bdb7132484bf7f0b9e38099b94a540884079b07c501c519b0813c184f6b4", + "0x80b2cf0e010118cb2260f9c793cef136f8fa7b5e2711703735524e71d43bce2d296c093be41f2f59118cac71f1c5a2ff", + "0xadcb12d65163804d2f66b53f313f97152841c3625dbbda765e889b9937195c6fcd55d45cc48ebffabb56a5e5fe041611", + "0x8b8a42e50dc6b08ab2f69fc0f6d45e1ea3f11ba0c1008ee48448d79d1897356599e84f7f9d8a100329ed384d6787cfc4", + "0xaaa9c74afa2dec7eccfbd8bb0fc6f24ed04e74c9e2566c0755a00afdfdf3c4c7c59e2a037ec89c2f20af3fae1dd83b46", + "0xaa9f6e8fd59187171c6083ae433627d702eb78084f59010ff07aff8f821f7022ef5fbbe23d76814d811b720a8bfa6cc3", + "0xa56a3ded501659ad006d679af3287080b7ee8449e579406c2cae9706ef8bf19c1fc2eb2a6f9eaf2d3c7582cded73e477", + "0x81971e077c1da25845840222b4191e65f6d242b264af4e86800f80072d97d2a27a6adc87c3a1cb1b0dd63d233fbafa81", + "0xa6fa5453c4aaad2947969ee856616bf6448224f7c5bf578f440bcfc85a55beb40bef79df8096c4db59d1bd8ef33293ea", + "0x87c545adbfaaf71e0ab4bac9ae4e1419718f52b0060e8bb16b33db6d71b7248ae259d8dd4795b36a4bbb17f8fae9fd86", + "0xb4c7a9bc0910e905713291d549cec5309e2d6c9b5ea96954489b1dff2e490a6c8b1fa1e392232575f0a424ba94202f61", + "0x802350b761bcaba21b7afe82c8c6d36ee892b4524ab67e2161a91bbfa1d8e92e7e771efb1f22c14126218dd2cb583957", + "0xb4e7ddb9143d4d78ea8ea54f1c908879877d3c96ee8b5e1cb738949dcfceb3012a464506d8ae97aa99ea1de2abf34e3d", + "0xa49a214065c512ad5b7cc45154657a206ef3979aa753b352f8b334411f096d28fd42bca17e57d4baaafb014ac798fc10", + "0x8a80c70a06792678a97fe307520c0bf8ed3669f2617308752a2ab3c76fdf3726b014335a9b4c9cbcfc1df3b9e983c56f", + "0xa34721d9e2a0e4d08995a9d986dc9c266c766296d8d85e7b954651ad2ca07e55abb1b215898ee300da9b67114b036e0d", + "0x8cfce4564a526d7dca31e013e0531a9510b63845bbbd868d5783875ed45f92c1c369ce4a01d9d541f55f83c2c0a94f03", + "0xab3f5f03a5afc727778eb3edf70e4249061810eba06dc3b96b718e194c89429c5bfbec4b06f8bce8a2118a2fdce67b59", + "0xaa80c2529fc19d428342c894d4a30cb876169b1a2df81a723ab313a071cba28321de3511a4de7846207e916b395abcc9", + "0x82b7828249bf535ef24547d6618164b3f72691c17ca1268a5ee9052dba0db2fdd9987c8e083307a54399eab11b0f76b1", + "0x8fbcb56b687adad8655a6cf43364a18a434bf635e60512fad2c435cf046f914228fb314f7d8d24d7e5e774fb5ffb1735", + "0xa3010a61a2642f5ebbce7b4bc5d6ecb3df98722a49eb1655fe43c1d4b08f11dfad4bcec3e3f162d4cc7af6a504f4d47c", + "0xb3dcc0fdf531478e7c9ef53190aa5607fd053a7d2af6c24a15d74c279dbb47e3c803a1c6517d7e45d6534bb59e3527f5", + "0x8648f6316c898baaca534dff577c38e046b8dfa8f5a14ee7c7bc95d93ae42aa7794ba0f95688a13b554eeb58aeedf9ba", + "0x89fca6fc50407695e9315483b24f8b4e75936edf1475bcf609eed1c4370819abac0e6a7c3c44f669560367d805d9ba63", + "0xa367a17db374f34cd50f66fb31ba5b7de9dbe040f23db2dcc1d6811c0e863606f6c51850af203956f3399000f284d05f", + "0x91030f9ca0fff3e2dbd5947dcf2eba95eb3dbca92ee2df0ed83a1f73dbf274611af7daf1bb0c5c2ee46893ab87013771", + "0x84d56181f304ce94015ea575afeef1f84ea0c5dbb5d29fb41f25c7f26077b1a495aff74bd713b83bce48c62d7c36e42d", + "0x8fe2f84f178739c3e2a2f7dcac5351c52cbed5fa30255c29b9ae603ffd0c1a181da7fb5da40a4a39eec6ce971c328fcf", + "0xa6f9b77b2fdf0b9ee98cb6ff61073260b134eb7a428e14154b3aa34f57628e8980c03664c20f65becfe50d2bdd2751d4", + "0x8c6760865445b9327c34d2a1247583694fbeb876055a6a0a9e5cb460e35d0b2c419e7b14768f1cc388a6468c94fd0a0f", + "0xaf0350672488a96fe0089d633311ac308978a2b891b6dbb40a73882f1bda7381a1a24a03e115ead2937bf9dcd80572ad", + "0xa8e528ec2ee78389dd31d8280e07c3fdd84d49556a0969d9d5c134d9a55cd79e1d65463367b9512389f125ed956bc36a", + "0x942c66589b24f93e81fe3a3be3db0cd4d15a93fb75260b1f7419f58d66afaa57c8d2d8e6571536790e2b415eec348fd9", + "0x83fe4184b4b277d8bf65fb747b3c944170824b5832751057e43465526560f60da6e5bbee2f183cb20b896a20197168c7", + "0x88a71aada494e22c48db673d9e203eef7a4e551d25063b126017066c7c241ee82bedaa35741de4bd78a3dd8e21a8af44", + "0x8c642a3186ca264aac16ee5e27bd8da7e40e9c67ae159b5d32daa87b7de394bf2d7e80e7efb1a5506c53bfd6edd8c2c3", + "0x81855d6de9a59cef51bef12c72f07f1e0e8fe324fcc7ec3f850a532e96dcd434c247130610aaee413956f56b31cbb0dc", + "0xa01e61390dcd56a58ad2fcdb3275704ddfbedef3ba8b7c5fce4814a6cdd03d19d985dba6fd3383d4db089444ea9b9b4d", + "0x96494e89cbf3f9b69488a875434302000c2c49b5d07e5ff048a5b4a8147c98291ae222529b61bb66f1903b2e988e5425", + "0xb9689b3e8dddc6ec9d5c42ba9877f02c1779b2c912bba5183778dc2f022b49aed21c61c8ec7e3c02d74fe3f020a15986", + "0xa2a85e213b80b0511395da318cbb9935c87b82c305f717a264155a28a2ea204e9e726bae04ce6f012e331bd6730cbb9d", + "0x91b70f44c7d8c5980ce77e9033a34b05781cbe773854d3f49d2905cc711a3d87c20d5d496801ad6fd82438874ce732b8", + "0x884596417ff741bb4d11925d73852ffeea7161c7f232be3bdce9e6bbe7884c3a784f8f1807356ae49d336b7b53a2b495", + "0xae2aed8ab6951d8d768789f5bc5d638838d290d33ccc152edfb123e88ba04c6272b44294b0c460880451ad7b3868cc6a", + "0x89d8ebfb9beebc77189d27de31c55f823da87798a50bca21622cbf871e5d9f1d3182cf32ee9b90f157e6ce298e9efccf", + "0xafd00a4db4c2ed93cf047378c9402914b6b3255779f3bb47ded4ab206acb7eaebba0fd7762928e681b1aebcfee994adc", + "0xa2e49b6cd32e95d141ebc29f8c0b398bb5e1a04945f09e7e30a4062142111cd7aa712ac0e3e6394cfb73dd854f41ad77", + "0xae8e714ab6e01812a4de5828d84060f626358bb2b955f6fb99ae887b0d5ce4f67ebc079ab9e27d189bf1d3f24f7c2014", + "0xa3100c1eebf46d604e75ebf78569c25acf938d112b29ccbe1a91582f6bd8ef5548ae3961c808d3fb73936ac244e28dbc", + "0xa9a02dcff0e93d47ead9cdddc4759971c2d848580bf50e117eb100cafca6afeaa7b87208513d5f96b1e1440ffc1b0212", + "0x894ab01462137e1b0db7b84920a3b677fbb46c52b6f4c15320ef64f985e0fc05cec84cd48f389ce039779d5376966ea3", + "0xb1e40e8399ee793e5f501c9c43bde23538e3ce473c20a9f914f4a64f5b565748d13ab2406efe40a048965ee4476113e4", + "0xa5a7d97a19e636238968670a916d007bf2ce6ae8e352345d274101d0bbe3ac9b898f5b85814a7e4c433dd22ac2e000ff", + "0xb6394c43b82923231d93fd0aa8124b757163ba62df369898b9481f0118cb85375d0caac979a198ece432dbb4eb7cc357", + "0x82d522ae3ff4fe2c607b34b42af6f39c0cf96fcfe1f5b1812fca21c8d20cece78376da86dcbd6cdb140e23c93ae0bcb2", + "0xb6e0d986383bc4955508d35af92f2993e7e89db745f4525948c5274cfd500880cb5a9d58a5b13d96f6368bb266a4433e", + "0xb0b4325772ec156571d740c404e1add233fb693579f653b0fae0042b03157d3b904838f05c321d2d30f2dbd27c4d08ad", + "0xac41367250263a2099006ef80c30bac1d2f25731d4874be623b6e315c45b0dc9a65f530fce82fb3dc25bd0610008c760", + "0xb6c0b1ed7df53da04a6f3e796d3bfa186f9551c523bc67898bc0ecfc6b4a4a22f8c4d3bfc740ebf7b9fa5b0ea9431808", + "0x8e78fca17346601219d01e5cd6a4837161a7c8f86fe2a8d93574d8006da5f06ae7c48eea7d2b70992c2a69184619663c", + "0xa21f91f47e04fafbfafacf3185b6863766a2d0c324ccac2c3853a4748af5897dbbe31d91473b480f646121339c9bae2d", + "0xa464d68786ab1fc64bd8734fce0be6fbe8dc021d3e771ff492ada76eedff466577c25e282b7c8ab4c1fd95ef5ff3631e", + "0x829a24badc7714081e03509ccfb00818ce40430682c1c0e4a399cd10b690bda1f921aabcbf1edfb1d8a2e98e6c0cedd6", + "0x87ccf7e4bbcb818ef525435e7a7f039ecbb9c6670b0af163173da38cbdb07f18bc0b40b7e0c771a74e5a4bc8f12dfe2c", + "0x94087bd2af9dbeb449eb7f014cfbf3ee4348c0f47cde7dc0ad401a3c18481a8a33b89322227dee0822244965ae5a2abb", + "0x896b83ed78724dac8a3d5a75a99de8e056a083690152c303326aa833618b93ef9ec19ab8c6ef0efe9da2dbcccac54431", + "0x821e6a0d7ccf3c7bd6a6cc67cde6c5b92fb96542cb6b4e65a44bbc90bbc40c51ff9e04702cb69dd2452f39a2ff562898", + "0xb35b2096cda729090663a49cb09656c019fef1fc69a88496028d3a258ad2b3fd6d91ab832163eaa0077989f647e85e7e", + "0xb7857ef62c56d8bce62476cdb2ab965eddff24d932e20fc992bd820598686defe6cc0a7232d2be342696c2990d80721a", + "0xb343d974dfda3f6589043acd25d53aecf7c34b1e980ae135a55cda554ff55e531bc7c2dfe89b0d2c30e523c7b065dad1", + "0x8d139e16a73cd892b75f3f4e445a10d55d1118f8eeafc75b259d098338419e72e950df6ca49cb45677a3c4e16fb19cdc", + "0x817b8535bd759da392b2c5760c51b3952ecf663662a137c997f595c533cd561ed7e655673c11144242160e41d1f2dd71", + "0x817ee0f0819b0ccb794df17982d5b4332abff5fec5e23b69579db2767855642156d9b9acccf6ceab43332ccc8d2744dc", + "0x9835d2b652aec9b0eba0c8e3b6169567e257a6a3f274ec705dbc250ee63f0f8e4b342e47b9e0c280c778208483d47af8", + "0xb78c40177f54f0e6d03083a4f50d8e56b5aafdb90f1b047bb504777d6e27be5a58170330aee12fbaa5f1e9d4f944acfc", + "0xab8eebacf3806fac7ab951f6a9f3695545e2e3b839ca399a4ef360a73e77f089bb53d3d31dbd84ddfde55e5f013626e0", + "0x96c411fc6aecca39d07d2aff44d94b40814d8cfc4ee5a192fd23b54589b2801694d820a0dd217e44863ccff31dda891b", + "0x8249c424a0caf87d4f7ff255950bbc64064d4d1b093324bfe99583e8457c1f50e6996e3517bf281aa9b252c2a7c5a83a", + "0xacf6ed86121821a3dd63f3875b185c5ebe024bdb37878c8a8d558943d36db0616545a60db90789c0925295f45d021225", + "0xa37f155621a789f774dd13e57016b8e91b3a2512b5c75377ec8871b22a66db99655d101f57acaecd93115297caabfc21", + "0x92e60ee245bd4d349f1c656e034b1a7f0c6415a39ac4c54d383112734305488b3b90b0145024255735e0a32f38dba656", + "0xacec614e562ccfc93366309cfdc78c7d7ee0a23e3a7782a4fc4807b8803e6ebfb894a489d03e9a3c817ff2ec14813eba", + "0xb912f9dd26ed552cb14b007b893e6ed2494d12517e5761dbeb88521270144f8c3eb9571a0ad444b30a8a65e80bd95996", + "0x8375408dae79c547a29e9a9e5d4ec8241b36b82e45e4ca3b0c36d2227c02d17bb171528d3778eac3bbdc75d6c4e8a367", + "0x8c2d0e6e4406836da112edbbb63996408bb3cda4a2712fd245e4bb29a0100fdc89a2746d859b84a94565bc1cfa681813", + "0xa7431bf59e111c072d28c97626cd54fcdf018421d053a787d2aef454b91251ee8ff9d3702d06b088f92b9ad2bbebff15", + "0x8f3659b0fbeb90b7f30b7a49233325e806551a32911a654dca86e290b314483bbb33fe6482387bc48c35d85c1dd0441c", + "0x8dca5ba23f0bb76f7dacabf12886053552ba829a72827b472a2f01e19a893155cdce65f1fb670000f43e8c75ba015a31", + "0x8c1514c083c77624eeb5d995d60994a2866192e15c4474d0be4189fae0e9dbd62494ebb4c02fbc176b53be548abbc5a1", + "0x80498d2ed153381baf3b0f81da839ed0eea6af5796c422b8e59be805dba48c4395bb97824ac308170bb4f14f319c5ddf", + "0x84f5ebc3bf96362457993e9fa31493c31c4283075e2403f63d581b6b0db8a3df294b2085643f2007f4de38cb5d627776", + "0x958e6e38774da518193a98397978dbc73d1c3827b4996ec00b4183da2c305a187a0ada9aa306242814b229a395be83c9", + "0xab8b8fbf73845615e7fab3e09e96cc181159eab09f36b4c1239b3c03313c9aeb4bbb51e16316fe338b2319ed2571b810", + "0x977e4e33b33bd53394e591eba4f9a183e13704c61e467d74b28f4ad0b69aa51501a5221cb1e0e42bcb548ca518caa619", + "0xa9bb7ecb9846cc30d04aad56d253c3df7004cebb272f6adf7b40a84adef9f57291e0d08d64c961b9fc406cdb198aab9b", + "0x8d2b72dc36406a545a9da44e1fddfb953d4894710ca026d6421a4ac91e02d0373a599f2acfe41d8258bc9679cf6f43d3", + "0x904192fc8fe250f61ecb8a36abbbccae85f592bbf00c10039c30b5a1c733d752a04e4fd8a1000c6578616f8a16aa83a3", + "0x87f5fdfe20bbbf931b529ec9be77bbfcc398cad9d932d29f62c846e08a91d2f47ae56ad5345122d62a56f629f9a76c4d", + "0x84cc3a53b2e7b7e03015f796b6cb7c32d6ded95c5b49c233ac27fafa792994b43c93cda6e618b66fce381f3db69838ba", + "0xaab58da10d7bbe091788988d43d66a335644f3d0897bbc98df27dcc0c0fcee0ac72e24f1abdd77e25196a1d0d0728e98", + "0xa10ea8677c2b7da563d84aa91a314a54cab27bb417c257826ebdd3b045d2a0f12729fe630bbbf785d04874f99f26bee8", + "0xacc4970ef2a4435937a9b8a5a5a311226ca188d8f26af1adfcd6efb2376a59155b9a9ff1cff591bde4b684887d5da6e5", + "0x8dc7cf6fcca483c44eb55e7fb924bf3f76cf79b411ae4b01c6c968910877ac9c166b71350f4d935f19bdffb056477961", + "0xac2dd1182ded2054c2f4dbf27b71a0b517fb57193733a4e4e56aca8a069cff5078ffd3fd033683d076c1c639a4de63c7", + "0x932ec87c450cd0dc678daf8c63cd1bf46124fa472934e517fbbfb78199f288ff7f354b36e0cc6c8739d3f496cfe0913b", + "0xb0d631ced213e8492be60ea334dbe3b7799b86d85d5e8e70d02beef3ae87b1d76e1df3bdb5f7ba8a41904c96f6a64455", + "0x929d7239ead7575867e26b536b8badf2e11ca37840034d0e5c77039f8cce122eff5a1bf6e0bcadde6b3858e9f483d475", + "0xaaae5d372d02ee25b14de585af6fbc48f2c7cd2a6af4f08352951b45aa469599eff41e820df642ca1a0f881120e89dbe", + "0xb23c411741a6b059f04fa4f5fd9dd10e2a64915f2de6ea31e39c32f2f347a776a953320e5f7613fcb1167efe502f5c5c", + "0xa4581b0ae633fe29c6f09928e5efb16db019eeac57f79fef2fa1d3c9bee42ce0e852bc60b9d0133265373747e52a67a4", + "0x81b33afffd7b2575d4a9a1c5dd6eee675c084f82e06b9b3a52a3c9f76e087f12dca6e0ffddc42fb81ce1adb559d47a38", + "0x89cc890f06b424591556aabdfdbb36d7a23700425e90c9cfed7d3da226b4debe414ac5bdf175273828ce6c5355712514", + "0xa4399438be75cfae2bf825496704da5ed9001bed8538d8ac346c8cf0d4407808e9ee67573eb95fe1c6872ac21f639aaa", + "0xad537f7ce74a1ca9a46fc06f15c1c8a6c32363bd6ac78a3c579ed8f84252e38a914cac16709fe65360e822ef47896de4", + "0x8e53b69f5e3e86b86299452e20ea8068b49565d0d0ab5d50ce00158a18403ae44e1b078a3cfd3f919aa81eb049a30c6e", + "0xa59f2542c67a430fd3526215c60c02353ee18af2ff87cb6231a2564fe59b8efec421f18d8b8cc7f084675ecf57b3fd05", + "0xb8d9bac93ef56cb4026dd1c731d92260a608fd55b8321e39166678e1dab834d0efddb717685da87786caeb1aaf258089", + "0xaa2df56f4c6fe9e0f899116c37302675f796a1608338700f05a13e779eb7cf278e01947864a8c2c74cc9d9a763804446", + "0xb0108ff2e327dcb6982961232bf7a9a0356d4297902f4b38d380ff1b954bfbcae0093df0f133dd9e84d5966c7b1aada7", + "0xb06b813b01fe7f8cf05b79dc95006f0c01d73101583d456278d71cd78638df2b1115897072b20947943fa263ddab0cd6", + "0xaa41e6c4d50da8abf0ea3c3901412fe9c9dff885383e2c0c0c50ed2f770ada888a27ea08bbb5342b5ff402e7b1230f12", + "0xa48635dbb7debac10cb93d422c2910e5358ba0c584b73f9845028af4a763fd20da8f928b54b27782b27ca47e631ebf38", + "0x80a574c208e994799e4fa9ef895163f33153bc6487491d817c4049e376054c641c4717bda8efbeb09152fa421a7268a7", + "0xb592bfd78ae228afc219c186589b9b0b5c571e314976d1ed5c1642db9159d577679a73c049cfc3dcfefcd5a4f174eeea", + "0xaa1f08af3918c61eadf567a5b1a3cdcdfb1b925f23f1f9e3c47889762f4d979d64686ce1ce990055ef8c1030d98daa3b", + "0x857df4cfd56d41c6d0c7fcc1c657e83c888253bae58d33b86e0803a37461be5a57140a77fb4b61108d1d8565091ada1c", + "0x8fae66a72361df509d253012a94160d84d0b2260822c788927d32fd3c89500500908c8f850ef70df68ddaeb077fd0820", + "0xaa1dbefc9aef1e7b896ff7303837053c63cfb5c8a3d8204680d3228ac16c23636748fe59286468c99699ae668e769a0c", + "0xb64b1cb2ba28665ed10bad1dddc42f3f97383c39bad463c6615b527302e2aaf93eb6062946d2150bd41c329697d101be", + "0xb6d35e3b524186e9065cee73ea17c082feff1811b5ab5519dd7991cdff2f397e3a79655969755309bd08c7d5a66f5d78", + "0xa4dae7f584270743bbba8bb633bdb8bc4dcc43580e53d3e9e509ff6c327e384f14104b5bdfe5c662dc6568806950da37", + "0xaae84d3d9ad4e237b07c199813a42ed2af3bf641339c342d9abf7ebec29b5bd06249c4488ce5c9277d87f7b71b3ddd37", + "0xb82a463cf643821618a058bddf9f2acb34ac86a8de42a0fa18c9626e51c20351d27a9575398a31227e21e291b0da183e", + "0x8b6c921e8707aded3ea693f490322971b1a7f64786ef071bc9826c73a06bd8ae6bf21bc980425769627b529d30b253ce", + "0x80724937b27fc50f033c11c50835c632369f0905f413b1713a2b0a2274bec5d7a30438e94193d479ba6679dbe09a65ef", + "0xa1d9b259a2ca9cff8af6678b3af0a290c2f51e9cf26d5fe3c6a4fa3d28cbf33cb709b7f78b4f61cb9419427983c61925", + "0x96a3e69a5ed7a98ce59c4481f2ffb75be9542122ad0eb4952c84d4536760df217854d4ec561ce2f4a79d3793c22fa4f4", + "0x990c4d9a4a22d63a8976d34833cafc35936b165f04aed3504e9b435f0de1be4c83b097bbaa062483cf3dee3833b4f5b6", + "0xb9bf5e4b270aec4a0dc219457b5fed984b548892c4b700482525ba1a7df19284464f841dab94abfabcaa9a7b7a757484", + "0xacaecf49cb4786d17cf867d7a93bd4ffee0781766e11b5c1b29089ae0024c859d11b45828fbff5330b888543264d74a9", + "0xb0e1a0865b1e6f9e4a0e31d0c885526ac06678acc526fda5124742a2c303bd0e8871a0cb7951ec8ed9540fc247c8d844", + "0x82b3d327b3d1a631758451e12870816956cd0cef91fcf313a90dd533d5291193a0ff3cc447054564ce68c9b027a7ffd7", + "0xa2843602abb98f0f83e000f3415039788da1e9a096bfe8fed6b99bab96df948c814560424ffebe755cb72f40436fb590", + "0xab1c7b43cf838798d1e314bc26e04fc021e99a7bfbfc8ffde62fa8d7f92139de86a377289d5177021154229de01ede15", + "0x95e5cf5dd87ae3aed41b03c6c55f9dfad38dc126b17e7e587c156f7745c8da0bd1d60acb718fc1a03b61344f01e3de4d", + "0x86f021a3762bb47167f80d4ef1b1c873a91fe83409f9704f192efeebbc3ece0729cd2f92f63419907ea38ae47bc907d2", + "0xaaa1445dafbbcd645d4332d9806225e9346ee5ac6b22ad45e8922134fe12f3d433f567a6a4c19efdd9d5775a7de1e92f", + "0x8fd7e15688eef75df7b8bca3d61bc9fca4f56e047cdb6d0b864e7d1c4966eac27d6094b0c8482b49739f83ec51050198", + "0x80aab8b4d394eb011d4ec6a4c2815617308c9b847c6fa6a3d7e6af1c79420ef6ff2a13934a398581c40ee4cf1cac02ac", + "0x8970b97ac076a1d8a321ce00eada0edf974a46bf3cc26f6854e4218cdfc8d2b0c32199d9658f254b4fbae5a2c5535f41", + "0xa1aa2ec5b03df0a630e73dd048680ed6d3032c324941423f45cd1f16038789e5e75b876a13948732e9079a422f66a9fc", + "0xb5fe5f5e2f2ae2beeb8e95859a02fc45f01f9fb0ebb2bd8ec9ec976b3e806228821a9775096d341d662bc536c4d89452", + "0xa2bc1f170b62d0d5788b02391337b2ab157c38e725694e80aeead7383e05599be0e2f0fa27ef05db007061809356e147", + "0xa8a69701d4a8d0d972390e9f831fd8e9f424b2c2ef069e56bd763e9e835b3ce5f7cf5de5e5c297c06ace4aa74df1067c", + "0xb43d551af4ff3873557efe3f3fb98e5ede9008492f181f4796dd1a6bcda8b9445c155e8146966baa812afae1abe06b48", + "0xb4b1dae44fd596813f30602ab20e9b1fb20cb1bd650daacc97b7e054e5c0178b8131d439a9e5b142ca483cc012a362b3", + "0xb95b8a94c30a831eaaebea98c65cc5d0228c78afd6603d4aa426d8186aecc951f1a11c33951f51df04c7e6fa43ffb5ae", + "0xb100059624cf9db371bec80013a57a8f296d006c139a8766308f1ea821c7eccc26cad65bc640ab3f6cef9062653bf17d", + "0x8e5a2cb76716e0000d13bce5ef87acac307362a6096f090f5f64e5c5c71a10fddfdee8435e7166ba8c3ad8c3f540f3e4", + "0x93d2c43e21588c1e83c4255c52604b4ac3f40e656352d1827e95dd5222a45aebff9674e34fbbe7ed21eca77bd9b8dcbc", + "0x8aeaed611546bb9073b07512a9a1f38a7f436ab45e11775a0f9754baaf63e9bcc7bb59b47546a5ded5e4ba2f698e3b5f", + "0xaf9e6792e74a1163fe27612f999a2f3cfa9048914c5bef69e3b2a75162bb0ce6ece81af699ad7f0c5278a8df0ba000d2", + "0x850bf2d5d34791c371a36404036ad6fdcd8fb62d1bb17a57e88bda7a78ea322397ce24d1abf4d0c89b9cf0b4cc42feb3", + "0x87f7e2a1625e2b7861b11d593aaac933ed08a7c768aebd00a45d893ed295bbb6ed865037b152bb574d70be006ddc1791", + "0x8dcce8f4ad163b29a2348ea15431c2c6ea1189ece88d2790e9f46b9125bd790b22503ec391bc2dee8f35419863b2c50c", + "0xb4bf5266c37f12421dd684b29517982d5e4b65dfdfba5fc7bd7479fd854aabf250627498f1e1188a51c0a88d848ec951", + "0x8651623c690247f747af8fdffdc3e5f73d0662bc3279fa2423a3c654af9b6433b9e5e0155f1ce53857e67388e7e3401d", + "0xb155120f196d52760129dde2e2b1990039b99484cdc948fa98095cd23da87679850f522e5955eae34ac267d2144160d3", + "0xaec8115e8d7b6601fbceeccf92e35845a06706d46acd188452c9f7d49abef14c6b3a9a9369a8bab2fd4eb9288e2aaca5", + "0x998a8ca4dc0f145f67a8c456f1d6a7323c4836fe036dcbb0f27eb1c596d121eb97369638a9908cfaf218c7706f266245", + "0xb235fbafac62802742ee3d26b1f4e887f7d2da4d711ba7f9bb6ca024de7beec1de66bb830ce96d69538f7dcb93c51b26", + "0x9258d2ddc21ab4e3edcde7eb7f6a382a29f1b626003cc6fdd8858be90f4ad13240072d8a8d44ef8de51ca4f477fa6c45", + "0x99d038487821c948142c678acd8c792960993dd8cb5e02cb229153a1ee9f88249f4ad9007f08e5d82e2a71fb96bb5f32", + "0xa88ee9dbc73d3d8e0f447b76fdb3a27936bde479a58d5799176885583dc93830ac58bca9087075950ea75100cf51af23", + "0x88b9b15816e5a0387153c1f4b90f613beb3ea4596037da01a81fdd2bcbd0baf5598db99f77e7694e5a0d35e822758108", + "0x907ae4b637d06b15846ee27d08c9c9af42df261c5bdd10cf5bc71f8e5ca34b33ac2405307023c50bdb8dc7b98a2cd5fe", + "0x9393d6900e1d2d1a1e42412fefd99578d9ac1d855c90a3e7930a739085496448609d674ca9b34016ad91f22d1cac538e", + "0xa28ac56b216730b7dcdb5ab3fc22d424c21a677db99a9897a89ed253ea83acfd9d83125133f5be6d9cd92298df110af8", + "0xb027590ee8766f1e352f831fda732adbaf77152485223ad5489ef3b0ce2d2e9f98d547c111fe133847ebb738987fb928", + "0xa9cc08fbd5c3fee8f77cf6eb996a5cafa195df5134dab000e4d0312f970a5577942ee89794e618074f49841f1f933a42", + "0xa8b3535c3df0b1a409d3fc740527ee7dd5ac21756115cde6f87f98cc7623f50cfcf16790689cab113ee7c35a5bd4879f", + "0xb61420227b97e5603ae8a716c6759b619f02b8fdc48acbf854352aa6519dad74b97bacc1723ca564cbf3ca48539ed773", + "0x853762498de80eebf955a6c8ddd259af463e4e25f0b6ba7b6a27b19bdbf4c585de55760a16e2d9345cdba6b2a02610f3", + "0xa711c1b13fc6c30745203c5d06390e6c82bd7c50f61734aa8d99c626faba30119bc910be63ec916c91ba53f8483c05a8", + "0xb488c0a793f4481f46b5875d96eecd73e46209a91677769f0890c5e002ecd7d4b1c9f4ba68c47fbed40e3857b1d8717a", + "0xa651c5e812ae65b1c66d92c607e80be330737ea49c1dcfe019c0ecea0f41a320406935bb09206a4abff0d1c24599b9ad", + "0x85e34e7d96e4b97db98a43247b6c244383b11ca10bf4777364acf509a6faa618bc973e2136a4693fbc8ab597e308fd5a", + "0x99837214102b394fffa7f3883759554c6bb7a070f5c809303595a44195e02b9a169460dc6bbffb62bdc0e7ced5f0a5c1", + "0xa952f89c0afb4bdae8c62b89cc3cfb60d0576ba4fe01a5d99534792f38d8848d919b3fc7577435d8443a044d2ee0bcfa", + "0xa1ac1f81acb29798acdfc493854663519e2d1b0e9d23d286ce33882c34b4c1c0bb43dd9638166d8026315a44d9ec92a8", + "0xac9c58aa38219ae659d23007cc7b97fd25b7b610b2d81a8f9f94ddb089efc49c049a8ea4c56e6eaf7b6498f422a97b3c", + "0x87e61d501c242b484fb9a937ef21d485f6678d75257fc8fe831b528979068cadbe7e12b49c34058ec96d70a9d179ab14", + "0xaa45f6852f35cc8b65a4a8b5380641d2602a4fa4e3a035db9664df3ac2e170b1280c4a8b7b55161430063e54de4158a6", + "0xa46975614ddde6d134753c8d82c381966f87203d6e5a5fb99a93b0d43aa461466b37f07b8d0973a1abd6ee2b40f24348", + "0x8d35f97297773422351f4d99564c1359ef1a10cfb60aa0e6c8985a78f39b4268486312c8ebf9dd2ef50a771aa03158eb", + "0x8497c6242102d21e8b3ade9a9896c96308ab39171ab74cbd94e304c47598e2c2a7b0a0822492ac5c076ba91d4176481d", + "0x973f8fcb5f26915b3a3ef6fe58cc44bc7f4e115cd0ad9727d8d1b8113e126ae2e253a19922c5433be4ab2311a839c214", + "0xae3ee9f1d765a9baf54b4617a289c3b24930aa8d57658a6b0b113bbf9b000c4a78499296c6f428bbb64755dfd4f795d2", + "0xa5be7a8e522ef3dcf9d2951220faf22bb865d050f4af2880b8483222ff7aad7c0866219fcc573df9d829c6efbb517f98", + "0xa5f3c7fabd7853a57695c5ad6d5b99167d08b5414e35ed1068ae386e0cb1ee2afbbe4d2b9024379b6fc3b10c39024d36", + "0x978d5592d4798c9e6baceff095413589461267d6a5b56cd558ec85011342da16f4365d879b905168256f61d36d891b1f", + "0xb7b6eaffa095ecbd76d6e1e88ceebabaf674d9ef7e331e875c6d9b9faa1762c800ff1ea597c214c28080f67a50a96c1e", + "0x8a1ab53ae5ceaa42e06e58dd8faf6c215fc09ba111ca9eeb800612334d30d5971448be90fec62ed194328aadd8c8eecc", + "0xa9ca532cac8ace9a9e845382f8a7840bf40cb426f2fcad8a2f40aadbb400b3a74021627cc9351b0966b841b30284962e", + "0x8dddeda8854c8e7ddc52676dd1d0fed1da610ed5415ddd7d25b835bd8420a6f83d7b67ec682270c9648b2e2186343591", + "0x888906aac64fd41d5c518a832d4e044fdc430cfe142fd431caf4676cafc58853ce576f098910d729011be0a9d50d67b5", + "0x96a3f886a2824e750b1e2ea5c587132f52a0c5e3ff192260d8783c666206bd8ebd539933816d7cdd97e4bc374e0b1edf", + "0xa150a29ffb2632cc7ec560983d9804cd6da3596c0c25956d27eb04776508eae809659fc883834269437871735de5f9ed", + "0x81f7ad4d2959d9d4009d1dfbc6fee38f930f163eb5eac11e98dc38bd2f7f224e3f5c767583f8e52d58d34f3417a6cf90", + "0x97ccac905ea7d9c6349132dd0397b6a2de9e57fd2d70f55e50860e019de15c20171a50b28a5c00ef90d43b838253b3d1", + "0x95694f00c21e8a205d6cbda09956b5b6ec9242ec8c799a91f515b07dcc7de3b6f573e2c0ba149f5a83700cda2d1df0f5", + "0x82bbc3c4a3b3997584903db30fffd182a266c7d1df3e913f908d5a53122fa12cf5acd11d915d85d5bd110fcc43cee736", + "0x8d3f24b4949aa1b4162c28dfbb9f813dd1d8b330f71325448dc45ea34d59b69ca95059402aae011e1b5aba6e536bc6ec", + "0x92c734c19752d24782331e74c9af97a8399ddfdd32954e91cda7363dba876aca4f730b451c50a8913950420682da8121", + "0x8653d2c79f77b8c7dcdf7e8dee42433998aeedf1b583abfca686d47a854de1b75e9a4351580c96d1a2a9532659203361", + "0x886f0e414cb558c1a534a1916d3531320a9b6024639712ffe18164ce6313993a553e2b9aafe9c0716318f81a5d0bb1da", + "0xb31b5efaba5a5020c3bcea0f54860e0688c2c3f27b9b0e44b45d745158f484e474d5d3b1a0044dd6753c7fb4bf8ace34", + "0xb2d615bbdfdc042d6f67a6170127392d99f0e77ae17b0e1be6786ff2f281795f1bf11f83f2e0f8723b5cdd1db1856e09", + "0xa6e014cca531e6ac2922239b5bee39d69d9ba6d0fa96a4b812217dd342657d35606f0b9c5a317efd423cdb1047815e3d", + "0xa8921736b69c9fbb29f443715174bac753e908251804620c542fad6cfbfda7bdfe287f2902f30b043a8a4b4818cfdeef", + "0x8d73a9949a042ec2dcefa476e454cd9877eee543b1a6b3b96a78ffcff87421e8b26dd54d5b3192ac32073cb36497acc3", + "0xb936a71ee8df0e48867f3790adf55dc8efc6585024128de2495f8873bd00fd9fa0984472125e801ed9c3cdce6698f160", + "0x82f69c06209c28f64874e850601dda56af44ffc864f42efa8f9c6a0758207bf0a00f583840982dec0a517ab899a98e5b", + "0xb7a0a14411101473406f30e82f14b13e6efc9699e7193c0be04bb43d1b49e8c54812ce0f9b39131a20379c4c39d3bbe3", + "0x81159c969f38107af3b858d7582b22925a7ccced02fae3698482d7e9cdc6c568e959651991c6cf16c53a997442054b61", + "0x8bf1116a206e0ce9199fcab6ed2b44a9e46e8143bff3ed3f1431f8d55508fe2728b8902670cfd8d9b316f575f288ed9d", + "0xa279b2149824b64144eb92f5a36b22036d34a52bd5a66e5da4b61fbc95af6eda8e485c7914f448abd8674fc14d268d9d", + "0x8b98279b5f3588d1a2f8589d2756458690a502728800f8d94b28e00df842a101c96ab9c5aee87c5bbe65552c0c383b80", + "0xb4a27a351ec54420f94e0a0a79d7c7a7337940399646631baca93eeab5fd429d7fb39428be77dcbce64a13eaa3c8ca1d", + "0x90c08baa29ec8338ffce381eae3d23ce3f6ba54e5242dec21dc3caaed69cac13f2ab5e8d9d719bc95720fa182eee399c", + "0x85156d65bb4fef69ffd539ab918b3286105ca6f1c36a74351ab3310b339727483433e8f8784791f47b4ba35ca933c379", + "0x923005013c27209d07c06a6b92b0cbb248a69c5e15c600bbcc643e8dcd2402adebd94dd4cafb44ec422a127e9780aaec", + "0x863b23eb5463a6ef5a12039edc2f8e18e3c97b244841bc50af02459b1bcc558367edf2f6e4fe69f45f37887469dd536d", + "0x87a4a7708a112724ff9b69ebb25d623b5cae362ae0946daed2ec80e917800dbfcd69f999c253542533242e7b9a5cc959", + "0x8bf4347ceea7f94b53564f26b1a4749a16f13bf71a9e03a546f906f7c423089820ff217066159b0637d9d6824e9c101c", + "0xab07eef925d264145971628a39e4dd93ff849767f68ed06065802cf22756fc6bf384cf6d9ab174bfc1a87bcc37b037aa", + "0x8e3f10a42fad43887d522dc76b1480063267991c2457c39f1e790e0c16c03e38a4c8e79a0b7622892464957bf517ebd8", + "0xa8722fc7b1acf0be18f6ddf3ee97a5a9b02a98da5bc1126a8b7bf10d18ee415be9a85668eb604ef5a1f48659bc447eb5", + "0x878d6b2a9c0aca8e2bc2a5eb7dd8d842aa839bbd7754860c396a641d5794eab88a55f8448de7dbddf9e201cbc54fe481", + "0xada881c167d39d368c1e9b283cf50491c6bfc66072815608ba23ab468cfbd31ca1bd7f140e158e0d9e4d7ebfa670bc2d", + "0xa2b48578fa899d77a7ee1b9cb1e228b40c20b303b3d403fd6612649c81e7db5a7313ba9702adc89627b5fd7439f8b754", + "0x8e051280e10551558dcb5522120ac9216281c29071c0371aaa9bde52961fe26b21d78de3f98cb8cd63e65cff86d1b25c", + "0xa7c5022047930c958e499e8051056c5244ae03beb60d4ba9fe666ab77a913a067324dfb6debcb4da4694645145716c9d", + "0x95cff6ec03e38c5ab0f6f8dccde252d91856093d8429b7494efc7772996e7985d2d6965307c7fdfa484559c129cca9f9", + "0x993eb550d5e8661791f63e2fa259ab1f78a0e3edad467eb419b076a70923fede2e00ddc48a961d20001aaae89fad11e8", + "0xabb2826e4d4b381d64787a09934b9c4fe1d5f5742f90858228e484f3c546e16ee8a2a0b0a952d834a93154a8b18f3d16", + "0xa922ca9f2061996e65ef38a7c5c7755e59d8d5ce27d577abcdd8165b23b4877398d735f9cb470a771335fc7d99ecb7fc", + "0x90f22862216f6bc1bbf5437740a47605d1ff5147b1f06f7b13fec446e4c5a4a4a84792cb244a1905f3478a36f8d7065b", + "0x87f3d9a86afef5b79ea1ca690ee1ee4bb9754b66f7c50a42ad6b99af7c222c853ca161f440a0a2a60b3b5a54e3493240", + "0x80a9ca9a2d33b9cf61976b3860d79f5d00de89a06ef043d2a52931809018aeb4ce70423cbef375b29c2c750c2c8704c2", + "0xb4e798ef1d615896108dae37ac50c1e859216ab6dbac11653e44d06ce5209057b4b0dd6d31dcfcda87664a23c8ef1cbd", + "0xaaed6d1e7c5b1db06f80dae6c24857daadfb0268f20e48a98fba4b76de1ebf65fb84c3be95fd6a418b498f8285ec63bd", + "0xaeceaa316c6369492c939f94809bc80e0857abac86c0d85be8066bbf61afbaaec67e28c572437a8d35c49dd596b3134f", + "0xb791c3d53ed34a7d1c8aa89b7953e3684c3cd529230824dc529739a5fbe74b58b87f01e56e7a169f61c508237ef67160", + "0x9351f8c80634386c45c0050d2f813193f9d839173be941e2092d729be5403632a2f18dffdc323d69eb0dc31fa31c5866", + "0x97693184d5c0056ae244dfb6709cafa23a795dc22d497a307a7f9cf442d7452024023c54a8d6bda5d90a355ba2c84f3a", + "0x85362daa003d23511ca174a8caafe83d52b6436dc4e43c4c049e5388d9211b5cbef3885896914d86d39be0dd1f910511", + "0xa2511b5fa34b24eeb0e1bcbcf872a569d1ff5570fe7b0fb48f5542f7fe57bad808d34b50afa87580866a6cb0eba02f27", + "0xb382e3327eb1401f2d378dbb56ac7250adde0961bd718575a64d264ffd44772c20752d4035c3ba60eb435e160b375e20", + "0xafad8a5d40b536c0720556845a6b257ed42165c14fb4b4a874717d107752f49ed9380c5b048df3aca67287bb8fc411a8", + "0x8fad0c98434ca5373c2d767868f679b76b4a8d04bca8240ea3f388558262c2d61b73b16fc1160932652b5688c25fffcf", + "0x83898008b5cbb6f08f8ef3ec179427869682bb4e8d38f6e6a687a214d4a307436afc64ee67d70a5a8ba9730bf839aecc", + "0xb85232e79913785fd82b06890706972b4ad7a309489930ae23390d51aa5189731f8a2df24800409a8c36b3dd6fc91275", + "0xa24ff26ec792f3701da4c5638c1fca4fa4dae95b01827d6200d583c4caf17ea3171393ba2a8c23d1ee8b88402916f176", + "0xadc5c7a7ff6b41d6cc386b7fc69d7bb04179bdf267864f9aa577f0f6a88438191fa81ebaf13055c2f2d7290be6421ace", + "0xa05e835abd502d31454d40a019010ff90b6b0b1f993075a35c9907aeab7a342ac0ba6144dc9379aada6119157970e9b2", + "0x85ff07ba58463e7f153fc83f11302e9061e648a5cbd272bb0545030b20e11facd8b3ff90c9ac8c280a704fbda5c9d1b0", + "0xa6c735ada8f4587da8cdad7ea3ada01650b5a3ecab8d81daa7a5f5de51ef4a6592b524692584306f06be3f6701f2870c", + "0xb138deee4e53ae8d677fae104f713ef1b8babfecec16b6a85785a66a72784eb09d44c3b63567222ade714e98f7d1604e", + "0xae79c1a49dafcdd972acd95d8ad0a35c02adc7fd736d4c44c3cd13df5789d339b5ea16bddbbd43e486a061ab31baa5c0", + "0xab3cf2371a1d7dcd0ffe3869a0178230964b06694bf258b2073ea66a2afccd845b38485da83d02e1d607d4c5c36b78a8", + "0xab9609f28a325fd01cb39540e3a714506c44e52ef28ee640f361deb5760aadbb23e804663b0fa20a66e239c33f8d8bb8", + "0x8ed95ea8e76e1b42823d7915a6aae77d93746f846bf602841dfce0e47543a36efb9ee7e5b42c73c3209d911225cc471b", + "0xa80b6162036d43811482323f0ce59eb18740e33a63d7c7bbbf3be206985919e5342d53a69df537d43e8b7d7f51e8892f", + "0x93c03d0a5083408ba00c125a8a9385213d4c860072f0297857b1235045819b904e07f2425c13a661d0a01d2e53347f4b", + "0xa6581200f00f96c461621e1d26b14a23687dd97eb9f7df4ba641a84340ee7306dc1796248fba4804f185947ad13b4385", + "0x8be174018fa40f7e0cedc5ae68f38969eb7695f2205e9c573641e533d56f68c20abf38a23d2f0dcac371e60b21b18615", + "0x857ad4ee3218c647c58f09b8ab22bcc8976f00a768ab1f708618e868e6143474be846422ce2710a0ed39b5155b6f13a1", + "0xa490bec40f322d599f26bcefcdddd8f2ef6576aa737d5ce7e8d5d422741abe749e3e6a48489aed8c560633f72857e3c2", + "0xa9c0ee339621f1c4a2410f9b4d2f03f1b558dae2973807b8bccd920e8feb7f65dfde3e79986b72ad21fcc4567240381d", + "0x8592251568e750a430f7d2c6ddbb3ec82a4dd9fd83efe389e69aa177fd97ac2c96c59a6e86db20d8e6f125d65b46c4d3", + "0xa4e2f4aa6a682913b423b097c4069c4e46a1f3af9556b1bfd0580d0fc01e3991488458049e0735b2a629684a79271c8f", + "0x8c4f6a3e738cf74112b08b1680be08158013ef8a515a81215d8a36c9b756786d1b4cb4563923463f3329292f4b48bf6d", + "0x8bace547353c02ea00dd547eeda7259aa354d4772dd5e0c486c723cf88627b7112e196b879c3c92a9561b674d9fc486d", + "0x8d372f4901e25e8db64fa098148d4a4e709b0e9dcb756d0f90dad99dea393054193ae1a33d292a3dd772ff7ba05e4b71", + "0xa8c7ea6a6a031ed23d65639f01f5423190775558f479700597df7ae7e338a6ae5e9b32f470aff20787ac8b7eec84df6c", + "0xb6e9dcba240fdbbf66033410a79a2dd3e9e1ffdf2eae949b3a9ed720e939d92339991dc3e70a5ac7d5253f317daf0b7d", + "0x974dec4cd61af75721071752c664d9c2a5121f06ff1515c56139a177a3ca825f763b69d431d4607e393fa74dcc91cc58", + "0x958863e6ad583a9d370a6db3639066982e44766904e7afa849b132f6666b7d08ab931131b3bec7a506d6583e93d56767", + "0x8b93a33b5da9b3300c20a96d80b894e3789c77041183c2cb21751579c8c96857f60cfc2f075201b64e95a78985c5b321", + "0xb726cb9f7ef34ddbc2fad82b3b0af0b30cc913e26c5a614ae5c19cc9c55c8e6dae069db5315a8dcb6d987415bb550ca8", + "0xa730f515398a71bddd66cab2ff996659d4e47dfbb08ce7958a41021f76d269b91c7498b708cd14b183a8ef469c772803", + "0xa4eb3b18132eb0f5337f14e01d63ca0bec0db6a43870f800e5491db756c2f5fce519d8dba5528b4bcef550d06b33699c", + "0xb1ab6621eec1ee6784e632e214693f39a14f3715991996b883d66200963e065c86fa0667f7bc36b93b40b5d90ff708c2", + "0x80486a26c3532ad6e19f76d8c9344e2626c07363fd495264927cb5935fa9565ece670dc98767afb04af6a9a5c9231075", + "0x8ee20e0df3c84a1c6b0e21bcc325cf99235b747ffe47f17fdfba548a358ca75cbcc331dd50db2311b400ae882256a608", + "0xaef4268959e5541e7ec69c921a1e81a8374d7e44bf1bb2debf4101cf3cd6b7d6ca7f441758b388de96b3e0edb5b97be9", + "0x8793629bd29d689ec94b016de8886cac6e2ca6638911babb22db4a787661422da0639a4e4089ebeb689d173abfe75950", + "0xb487b3551c20a29e9a5abbda8c50ff594826283e443c09e3ae09b914e46060b3f9abf70434444ce1487e2a74e562616b", + "0x8f11531cfc5997dd04b997cb87ba1831aa7041d5434fe72de66304e3f165d882fac891391fbb1eb955c65319e65293b6", + "0xb195136875fd02a75676c33cb3e60504d5964f7a9e81f4c8c8fd38af62e2145c55f765b3158664566191188ac678f381", + "0xb374174b0b3eb04fa49eb4ece45173f0db5d829eac370a20a62309566e0f98b18f72f3633626893c053b7be6bfbd2366", + "0xb2a2f6b0cf652775679b2d677048f2ed8c31a3269e6cddcc7a10e3e6fee89e486b50d9d55fbe452b79c4157c0270fb77", + "0x892177c364dc59032594e7a6fd032286ffdf4fa0b9e3baeb37ec839faebfd2fd46c57b2c9bfe9977b59c93a9cc0ead1d", + "0x8ab7c0038a7dbb2ef200dbbe9acbc875829ecad4883792d5c6ce283de67ccd9aa935a9cc7b30b2bd9de7fca7bf2a9a05", + "0x83745cfc78ca709835aa6c6a233c2b86fb31e3f9f6a8becf63e501f2841c4366fb7d131b746c9d3291afda714ff05579", + "0xa723dcb67925ef007e8339dc578d2622d9bb77cfda87cca0088854a59414c02338752c56116a6c1281917842e8467c38", + "0x8a098142da0af2254c425fdbbd0d1b1a17b2bd781391ab37f181775524b8563c64ab8a1602aee2ac6c0a82ba11a8b1d1", + "0xb13bd7529a9b351c5d395c794c28bcb0a3167f1c992e8c062eef47be9be27895945231d249c73a0b6949daa295e14944", + "0xa20dcd2fc2222eaae467d9f5db861040f58bcb991a26e5663ac3aa5e1ff13d0010657c5af586cc4621757add2b905073", + "0xb818f660c3cc4e9f273c25ceeabe562c8afa8ff88529c26f2cf45ae6b2813cca5f350e3cbd56f6257c4df41722dabd25", + "0xb225d5987108b24411bc389276f12509a45e86d5ad6b6d929af5274df0be11109c0fed329669a0acafdf3b0beaa8f2ec", + "0x91fcb6d04576d3c6bae947bb7843b430e5fb0592ae49b0a65dfa5791f4eaa4bf2c7f436c8de7360f217001c2b4e5c67a", + "0x8821f7a1424ca3fdc5d4a5606ad10dfaba6094cf36669fa9f84cf7617e50425405d14980780e1e18a1ecea7913cda896", + "0x990dcb7f38f56521a70cb71bf4522649fcd46ac052c7feabb0748dfcac9f9c0f95d29e070d32af3cd0adbf869535e17b", + "0xb0fac1029fe2c1100f24e2f4bf10c7672199fce53513c7dde2e8d9b00702edf0143e0e1dc7ceae7dcc6994edc2422b6f", + "0xa514ebb1a33451b4915c05114db0b10168393613744df848b24e43e09f0bda23baefd9d731075198aace586615ac7911", + "0x8b77f7953c2e67049fdca3653b8d8cf3f799677f79b954da02bdad8cc4d6c855c1c7c16b4f6f9ba35f46426ec28b2d84", + "0x875520cfbda16ec5b1d1d00f578a910d0fc052f17870ba093e22e310bb07648d34817cc2b8811b6f52de535f7046a0d0", + "0xb8c77b4be0b430851c4ff69e91cb770db1935d848198601393810ef395efab52deb9d5c6525472bab720273d5e0e7a79", + "0xb6d4d437146671bdea62fb6545395ea3df39f1cdef21b8476b68e7a25aa7354f847740576d6c9f187bbae9941f0ae450", + "0x95c642f1bccdb62cd6a2212dcdd6ff8d49aee426ca08b7cf3a9d15249d24a9eed5533f92a70c84498c0797f8a57efa27", + "0xb617978047ed0f748c305aa7f30c2dacd0db00baa67fe0c5ce346ef0e6991dc7e05f18dcb2702467421f8390f27aa815", + "0x86411c7a00b3e8b43bf22fb061b1f54ad9bbf632cd74395a478218389c0f544668acf3dd7726532d080ca7da9a5f8608", + "0x97bf684a8849626c4710a6992f6c11f6b5406fd4dfe9e6aa502425aaafe9827e2c435aaf9a5d3d2ba3a4c0e8aec79ba4", + "0x8b178e2a125b461d3180906ffba0af3dce614c64058501fdd35243ababf892d6fcdea4834ce42c25d5569452b782a709", + "0x8ebed2c8a25c61da6a6a8cb0d8f5ea179e28869753eacc728f2c076f7aed8598cd3aa0981f120f9e7ea55b3a689ae882", + "0xa6f235b8e655ca3d634740b53d8c0a757ecc75d2b8838b7948997c1985473d01943d935f687b86cee56cd47c8e773443", + "0xa7959c465a9646908b9d8032a589e41a7dd999f2ffc54bb42f22e5f8a4d8c493a31bcc7ea2cac6c8dbcc59acace7181b", + "0x96d0532df2e12da20a57cadb6cf5f6c4ee1aa4775629358c25f1d51677a3e96d1fe3b232532324b4f02f941952d4cc68", + "0x90f493473d686b639a30d1ddc9c72eae6e983f1236e162e58e967a477c0654973ea2e1bdf4ba1a44d7247bc1befc2cab", + "0x8b2d87876d9c4085102a07ebb41c565ba69acab99ffc03efc18f20e48d3f3bbe4fc6ddab9c78fe479d9ada80504d85ba", + "0x829a0fb3200a28e09cacd6c5346000e7786116ddfd898f37dfd17bef454a8abc0fe939ed8735c00769f7f2f33cd4f906", + "0x86194ec9e88ddb7150e8b03e7a535b6e99863fc6762835601efd03615aa97aaeb413cb210e86035086ed852b39c9d019", + "0xb02efd116a7189cb317ceae392bc301ae55470f0489fa89934e182aeb8c67e280299b975786fe9a470bff46827defb9b", + "0x87d7c3903bd22b12d815506f150373f518d47dfc6e5fd74347d88b518124c9923d1e4c98defeb3a45d53d50b423e2175", + "0xa1a430406b28254a7d6348bc98e697e9bab43839aa05d53faee97546f84541ea0b559162619b2045182938f69bf61cae", + "0x99d243c226c61c6697fb3d2594f3533fa5dfd7cfc87107908cacde337d7a077fa5a9dc702d26081b065edb1227498e65", + "0x800ee5006ab6217161f42db0cfc552a81728bb4fbd7af6e4620ea099a65ef6664184af3f65a07fcec7e965529c5b49bf", + "0x91bfd307579cadc8f81009558605be3edbcb8dbba271475803484017f40130b2b216aef4f620d960193be681877d3a53", + "0x96a060459dec458d19a6f8af6e49dc6c7c58c55dd18915c5fce5e0f4b4a422fce3b9632f6059388fe760289abf70f173", + "0x9921a37f3e657222c7fda3588418a9071409711d9f1fccede7494429f02a45fbc52d79fbb64e9ccd518f60d06d0520d3", + "0x81052b0d15773cb75975ca9230ebb2579700e489c7e3f07cd9cde206fef38b8139bd4976d2b4a7840495fc645f96df03", + "0x88ac37ba66d1de5e23878c992e4d54023729e97e77351f50dc5918d738b5a73faf1dc6feec7e85784761836ba1c6f778", + "0xae1e6072c13060775f6086d1ae1f88b627ffcb810fc0e0e97deea1f3a15ef0aaa52a6dce2563e4beedadc131af2a8281", + "0x8b60a340f5e4f90badf83001b495ac9f13974c3d2054ddcb3e6b8ca99dec5cd63a263e05c282454191ab2e087d5a2911", + "0x832e2d56ba69dbf817b2b9dbd25c1538d5b8dbf5d9bc05e6be85054a423ebb66a71b157e166e0b9444ac171b34b7ccc9", + "0x8586036fc7dde1e7e3ecb61663130c4529866ae9f5f5095b9fccd24a4c70eea899aae5f10ea1ba66d1665b2d83be35b0", + "0xa77969453b5c083a207913272b5b69d4ccbd8718bdf54be8fbe11b4bd0a2168aae3ba8f9362afa69c0ffa28d7e5a2340", + "0xb7fe9568c214baad0ac5f83745611b481f744ec1c4fa78a549b180dcf79633e5ba75dc20055012a13d849eb7a9be57d3", + "0xb01cad1d2a6c51c0ce88243d1f52f95fb5ee315a905079688027511f0c4ecd0563a3a81846709d272fa5ccb9665e8043", + "0x8eae0a21adfc569aa57237654021c2bdb2c6f0f52ccc90a126682c21a1f9413c63d285f92b2b2f8649150a9284bf70b7", + "0x942acc947192b5f3cf60e92383e5d35f79e7a5904e8e9fd1c8a351676c83ad29b0afb6578d555457cf909f8f4d27adfd", + "0xa74e092f8628fba9abcabc27e2e9f3d5a9a941dfe50a2dfde2ad179aabc73afd196676925c2d98643ab8b3d02bdb66ad", + "0x896159daa2afd757cf3f9d34af248ad68bb3c62e4c9ac49919422727479cf669098f270b9e645607a7d11adad4c889b2", + "0xa428d8370813d78e7a2a24eebd36e9da2f8bb3605e5a39b5fcda939b531c35a8ebaaa642ba556250a37bddeec90326fb", + "0xa5fa04eb60a1d5ee9820e78f42f7be15e1c02757b539aead995768c6209684d6c183c71d282e0c12a4c15c03f9a89d4d", + "0x93c77d5d220e40affa7269a6915c076c9aef4db552c643ae5d560a79c955b491c6346ca4cf11cbb7fe1894e28d47b065", + "0x802e605d2de745eef6981d88e7a57ef4046a2062725e8080995374cea2b3273c27f35b7774d0dcba014710d8d6c501f2", + "0x82f7169e6ec9b3e2bd450f35ea2e66d06bcf900acf5b73139677b48e078ce2e16599103027b2326770c99c0a690f2015", + "0xb0c8581879439f9b997551233fe2de71aa03604f9cec37a7b18c5854342d9b67be468f3cac4bf6f64fe8a0066248c498", + "0xa3f626848a4db6e9fb01cac90d3362ec521e969ebd5228af694ea3671061476149f13d652942ac1e39f65591fed740f9", + "0x88a8e759b9cbe16a7c16e43f4afa2de6100d2eafa4dee75ccd653ec38c919013d0a6b35c1ee1eaee7c1985b58bcc9e92", + "0xa3d5fc7aaea072798490616552d947e95f49cf02a420314307aafb555287ec607d75589ba24b009cd68299dc6f7942fa", + "0xa809cceeb84f9bcf3c3ddafde3041e7bc3b1d14df8830ab849002176a0725e6f16f70774d8962cb0b8ac0dc43c4ac66f", + "0xb8f2e46c031cc8fa160a08c2ebdfa85345ed14771b06daa9636b0e7792b7fddbc501dfc85cc626a01104a43a7d3230c3", + "0xb5367e2a521c318b802ce16ceac80c4b8139f73ddb10ddf38433397cda70a86ea1f051cc55626a4e99d27f30f3975ff5", + "0x96d963660121c1441cd13141279cd371a6a0aa18b6a20761b18df60aa9c14e13489afd83695a0921d5232efe72045f07", + "0x80818d492fd85d666bd91aaf6257b86527fdd796773c793407df1d4a0f91d74649a6bab4d15155c36ed4c6e0a32c5636", + "0x931e22918905fd6c230d3d867ea42861f3074d320d14e1929031924c8ac209a5c552b679b24563bb12f9749b4ee983bd", + "0xa4de2c333e74ed9bfa3c0bf6a0beb90427abd9aa4221294cda74331646b58ef46ed57cccc8798ba2b9309894b17cfd69", + "0x883881554c1d88c0ed8d3b6dec3d200f6fea69a77ace3e4d6f86b41506a23724b4394ec8384075f9c75c3868ba8a8e8e", + "0xaa0539ecf6ec9bf06f24443027f8f24b6b3d8c5b2084248eecd4bcad3c9a69716e1a0d01057f09a65bff1006ac5e157a", + "0x856d74d44c943c9e809b42dc493dff20eca03cb0cf5ed45108c69b1f90d8592a53ae8100e99380a274fafad23e74cdfc", + "0x9188257446661c88da093b7c5ce998135913f63842d7c1586065377b169ee35b062d925367fb9b909ca971f1188667b1", + "0x8d3aa57cdafbe998938787479f5d590c1484c6dbe94e6c487e57a746ef5252be0eaa5976d6270de7db64b6b92e57a0f7", + "0xb8f4d6997240f9eda5aca0c43323a828d1563c491b3db2087f60ac4120a3fcd06075fb42bb19d0339ab5ee3fb7db25d2", + "0xad247ea94b8ae1e81eae4c9fd7b39e6601b53cff47b2547ff90a3cca87192eae28408082774a1fd14bf9ab459b7a4f1f", + "0x9598598070f8bdbcc49056c40971e673726cd8c1bc4baa0b5124dfb5fb750e7baa7a7df18eae2bd91955ddcb1ec67955", + "0xb874131ab1608667fa60ea29092d090859eed1812e90c609afff96d79e82c5ba546f617f4c96fc32c9bba97431c1e9af", + "0xb00750a9cdc75c2a54f0d3cc99b0fe02300754f25166f7ac85ff41ab5e9cfcca33a29be76a480f12a2d410c7cd5032e5", + "0x84b5bd1c90bb6c66755b28ba4af493ca1b0c3a4df9f436aac67d2e07289053f925cf6a149a84e74e1027dc8758150179", + "0x99caf64bd9d193ff306e8ab5da3f1bb2a190a60c3a82099b8d03d17fa810dc53d176c21379f479e828f60d25beb3ffd0", + "0xa8fd9de502f1c261d5733430e5a18d8b7892a98c9529a016fc2ee53892ae965dcd9c75850bcda4c7edb980b8d88e60ea", + "0x848c02cac636e047028a3fe8c1bf4066fb7591b96b0340f8fbd476ff01b35fa3e37d309333771a134f24800e5f3f9289", + "0xa1eab1a06dcca3439f0166441e7e7f2f5b56f5f8aa9f45e411c561f556e0fb71c514c06c26ac53b49a576caca5faac3d", + "0xaa603f970dcbe953e700e61c151182c8d32cbbb53ceef572ac93383db33a4b098b5c7b267e42d514ca66b740c0925efe", + "0xb55fd5301bd700ddb0b4f72fabe9a91ad49759506101fa802ed1677e9553595aa4d2c66f7574e78d21ce882ce0120ae7", + "0x829137bc4da7b4886d3d04d2c39cbf4b1dc40c813ac1adb425c7b9abf9142b516314cab79c68454df5d71994ce416144", + "0xb83a3a22735001f783dd48a01c4fb3598a51ff3987e842b8045c71c035b9e43645a55254ca5911a5676ef4a8af12d056", + "0x8ca8d463deb13f9eef5e533bc39efaeb0c15631282c5c0deee1673b0053a7cccd514af09801dd6c158caa159fe9351ac", + "0xa9ffb1427828f3c456b9c8cc50782de1ab0029b9233a0fd998bad0fd014d27e15c4a32d1e16ad41bff748378b5abdf49", + "0x9627e29f725ddd86456aff813976bbc4a836f4deabf5ad9f73d1a260ceb30948824df9c8841e6b3c529652202be181b3", + "0xb52c988647fe3d9276eed3c262e1044f57fbb116c64cf4f207235c205b3fda0f3d789bf90f5217401b468d85fdfda404", + "0x833bbd6e2924f5c4446cb76b881d1434a5badce9eb9b003f85d076e297ad7ef45b822069fe54d17427a348c3263fb838", + "0xa067a36352db6f82a116cb87d3db5f60b18576852409e2076cbbfc7843af78866313a4969385a40271051dd195d51116", + "0x902b99545971f9a103f99d7399acc347ac46fe156166e51deefc0e92aebf5893460c69aeeae11f5af9f49418e289ce6c", + "0x9206a0e9ce9b9880f29ef0417c96931985f5d83bb17cebdbba4ff2af81a3d37155b04649426f698aed372e4f669599e6", + "0xb54a5d7c976e45c0b1d44433595eae9d1ae9aeabfd58cd5ecb0c5804756a7b01c9a517754423b4714a3695533a3114c8", + "0x91b612131e84580ece228b81ace83da0269b53f94d3c02a1a0879ebbd81bdc252064b3d03a7e140b43a90f237d9a45a0", + "0xa6cead3b8607eaeafe37135bd6de8fbd16f806c131eb71c8d36bfbe295d45b070255e50dabf076e2c3f6b8699be71d6a", + "0x931da21e67b11ba6ce438546a24d063bcd51aebe39b4220a78d9c0aab88b2d37969b5ef3502d835507f9c8d6d006714c", + "0x8fda408caa9daf01122a2308b7b9d328f52e1e2f138a8bec30492488f4d710e5e52524a6455a3a2ae2818ec8a610b650", + "0xad8ad5c189644352d90c462731c46145410e5adf38682bb80f95495dd64d9d13782537d68690847bbb06c6be7175dbc7", + "0x87bb5cc466ade60feb0961421c3fabdc8a7e20f11df8437bfff63d3f8bd25305002a396c9d0fa4fb9a9986d4717f12c4", + "0x827cff72870ba00c29064a7d2b4973f322d6b6de7924c93d8bf8825e7a0e8478c7748f90f5c716bf83c55b2795d315d8", + "0xa225895a8e94229776ceb51b05356291f2dce748be17a60d5aeb33ef8507c368bafe5d1d6eea927f28b9d1422b661b9a", + "0x8e011323ce670ff51c964241a6b72e0e0ffbb3ff9bb2762492323fc3a4abf4718091be0945287c7329850e4f74462cde", + "0xa2c03c2e5f4e9d3ef361f68b188451994ad1b24de9f323370559c8abfcdc7bffd289d92e78a5f6b104b0a12c84dab2ef", + "0xa22b4771116ce22276fab1fec6826610707ce8a342f9f60b079c4e0259dac3cc41c96c560dfd0ada6edd2828f7c0e8d6", + "0x97c17441d0af9be83b42097aa8b7cec84a253b9a2b957214b8fa93c26d2add46144faffa7b8a55312059b10690f711f1", + "0x94bdf348849f31a2737cbae5e5848aee711067bac85c11c2e68b44c398cfafbf3493a3226cd1ddf7a916e7613fc7b6f6", + "0x838f59c6e8469a8ec6fd40b978a3607439aaebe1e50ff707eec72c0b8278af05b477bf12a384b56d03e3d4eb91e56f67", + "0xa1940f0db58185e2b3aedd2b0bc2b73b4a65c68e09b046f38e9dcd4e13c94f5406bea92635190bf315e48ec64eceef2f", + "0xb2f4e0ae44e1f1210a91d8f280f17091fa994034ba8c991583f8182a323e9b3001a712e3584fc2d64ecbf2d319d076b2", + "0x9342b89c721338d02c7854cd7466fb24d93d7313b6114ea591e6607439c8ddb911d1cf35f01898e9c557982bdff8f9b6", + "0x8583fcab15be1dd14d5a415f4b14d706c8c62f058500f1344b37730c8be6741779691f87ded3cbcf6516468b373cafb0", + "0x8fa9587c7989646571ad9032f34cedd353caee14f5be5cde1e9e0a1710f90c08faf6fa96a60e1f150f761c9c8ae7417d", + "0x8d9ff904cc08141f5a9879f5f77dc600e6edbe859082231a4d819953890199bcc5f940b730ea688332f07e5279d49e1c", + "0xb5f82b46e5ef9a2df8d144202d6e2e4f3bdae8e2048d2af5ea7deb3f722fbe6d370401954e74ff0d8cb1010ffb1f38d5", + "0xa3b5b57d435b06ed70530e060002a8fea71746ad07d969ca23f22b5e52624527595b6a6d54b4e953fb7b7596bac378f0", + "0xb90f89390df6d4b7879b915aa3c29b8d779d035033f8873bb7ac54a14ec98f0d08c0e3bf696e2ffa7b5730d736f571f8", + "0x8e81e371b92887e43d95c0dbdcc9575282b26ccebdc8cbf46587e4f2a83b61e9bc0c6d7d1f114b9d21e04fd6c180b12a", + "0x8d682947c51dffc6e0fe0a486293c9ed121f441805168236393087cf62f2a429cca60bf0e472564844347d32c6bea27e", + "0xa8341ec7dd189fa7168759240224192c58209b53fc961c18082deba217928c399bde08ceae42bffd37c1135b4d14a845", + "0xa94bb076dcc5ee5ec82fac57c5b384c690df12631882bd1b960e1eb8c04f787bc22b7bac315b9dc5a8a098f17f051a0b", + "0xab64e1c6f01b87706c88a3bd974454a438722768de7340b834ccf93ea9880c14ee7c2181432acf51f980d56de73832ee", + "0xb7b0058bb724d879e5ad7aed6230297c54cb599ef659e86bf2cc84c38225899fb388391df9b2e6fdf063171937fd8c72", + "0xae856f4fb74c27cc98b67429186e7df4feb01278cd57bfd3170af6e52e0a23b9e926bf9565a890cfb4ae8f2d590b2cd5", + "0x804b9c6702f0596d328f92fc1ed5a30a7ba17b9204524135001b569233fc4937035031d079f52fd04968f37c24013898", + "0x84274ed1af6bd6a968583995622b4d18c6a2bc703ce0d0edce45bb736529b4836343dcd11911a94a134dca7877e6cab8", + "0x88808098463f7505034c3b6328c8a08186b33f7a981c08376e429dd64b79b97753170531ed078dd265ded4ec0a1ed8d5", + "0x92823bfb23a4eb84d3759e7d717f0c8641ece0927cd2ba8c728c26bb35df2629a838002f353c8d3d75eb19520aab5f25", + "0x8db36bae4d960cdb9c51f419d7ddc81f372e56be605bc96a9d4072b829f05527c37c8f255cc6115300a2a0d2e6568d89", + "0xa8fcdbd7f3b4d7ff04149a209feb75e97149e7efceaa42d66a6b8e432590fe7bd01f1a77fa8b47108f670b612e33fee9", + "0xa9f4c53c62db7e5dbdea6918862d3c6d24b5bd8732a218edf0ba61e9d1861182323d8ecd7bef8f895b42970b492f6e40", + "0x8b95bc7f07818f4d7b409aff8da0b2c2ae136cde386f53a71565cae9fd14c73c13cc1cfd79c0f97cd77839fb738c5b9a", + "0xadbd1d11adc756b51a571ddbcbf4392415231ddad93da09acfafee03a9e4f9e1ce3826110619e5271feadfaffce3e793", + "0x95d327c8bb195cdf25fd79c98f9406a6b0316214b1630ebcce95bdaeffafa36fc1accc6882e0e5d13a8db5c0f3c0e61c", + "0x8cb2f1e2fb25558869afdacc7bb866544cfdd566cefcd048b48d458a886130bd086ecb7600a960a7f2563c61cb326510", + "0xb3aa8c4bf5b933d89cd74ca7f7176d6624d562d7d58b041328b49d7562a30b489cb606abb3c49e85baf04c28e9cd1f44", + "0x97f9053a85250c420599827297453c2cfde087065b823d9e43139e6a9cac3a2ec40a1b6e2f0726bdc870fff215462f0b", + "0x878d5dbe6b881389c2ca126ff66d87127c9aaa3f62f0d2c1ec0ea2b279ac95f8a06710dce166415db227655e2345a04d", + "0xb2c33a6b4203e3ca5247f0890e475518317ffc44cfbb1da9a1ba02114e8b752bea618050b876de5cf3b1906140a64471", + "0xa56170c8313d2b5541a795bea9934d4425b185b5c409f0484df6f44f0e4bcbf50b860ff46b7245cd99c1cfa8fc1965b7", + "0x96e2b658e2876a14147385fc423d2702a3cb76962b6b437222cf9cea39ebf4bdc03bbf434b747866d4bf72b4ceefa639", + "0x89c4a74fa2f067e7ae49c84ef782c331bcc9245db7e941804e2e99d12e987b4d25cb827778ad4c3566c4fc68018650b6", + "0xa01d30cea7d01c80ff26650020fab02e78fc3842e2398a81b44b21d58d4e9816166ff4ed2418831fa995a28ff35cb6f1", + "0xb960c80b55a8845bbf24bc3f23b0110ca701f9544ab6a5bb7929330213cb471321e55c390ceca3e24bff69bdb0d331c0", + "0x802c5b13f22be7be0e5db11eb3be0f0ea7f9182c932265060ba05fba20ea093dd2810d3b969ee3e387e60fe6ee834e8d", + "0x92478f88ef7435d15e39a97916c736abb28ea318394b88678fddbbaab3eaf31776110936abad116a8ff6ca632dd12043", + "0xa6d3da0370c303001d5ed99d1db8bce1f26b0e442f0f042e36db9674e92dcd6e80465e772f1e669f99221caee3392fe9", + "0x938f04f70a8f947d6df2f0c0e9af3cce0c06edbb3c131970dd60884fc0b0a0959c504a2a36c3ff76dfe919905671626a", + "0xa7117e55224230822e9983df2132347eb7208cb6798f291df926ab51e04b1a1f78d5568c9a8924ee6f57426134360f20", + "0xb91074c77ad93fe48dc2b10c0c5a62ca3ab7d98345b919c52d84a9dc419b59fc1b267e1c2d4b2e120016ef84bbdb0cbe", + "0xaa175c6b6edf02fe8778762c9575581c0ee6efc9dbf99c291a41444a23a056b893be6c45333d907d0bbe9fb0eef84d08", + "0xad36dcb4e2ab425aa339ae464b038d550cb11186741dcf257f1b8b80ed4f32ffabbece45e2dc1525d4c3eeed819ea04f", + "0x91cb35c1ffa9cd5aebef523edb8325078da3eb5cf9e95c675a76446fc7692aaee6f949de064ca2f3e0f082cc3fa93e20", + "0x82622f9410c143a86bc4d756b3c7b324dc295231ce865de020d61cc0868f2c150a473cea3a5b756b36771ce1032415a5", + "0xa5c29996ad3a53468ece9356a5b4ccb68971ea1c89cf39644f1da2d4a477c2ea99bf791ef902b87c225d8c53d67c4c92", + "0x92893eceed1af34fa92b23dcbab175b6a0188a27dbac9ad3317c4e39955a763cb383ab13fb1c519cde311d8a4d12e8b3", + "0x8a093cb191b94b0200e38d31955f9d240e2be1edcd6810a2396a061f17c3ddc9c4f4d56766ddff4e121be7110e03b869", + "0x93981473df0cb1f4b47c7d9b64e3123dcf1593845b401e619f5d7c70b5dbea375d1ca43fca65845fcf0a6b2e0af43791", + "0xa6beb6b0697070f9562910add88d9ba91992f8da127b27be81868b1596d1012f09ea7ed601b4a6474c921a1a1a6d866c", + "0x92026b1ee30f2ed61c9f30337c3356844217926aabdff383c19ca3c21e0bc49811ca5b308012bee4ef250cfae1615800", + "0xac0ebaea6d35f84dac4ce648af096305ba68a7a0aea0a11ab2fbe3162075444a158433c98141bc92ef3b3400d6deb46a", + "0x83046f482dee24ac3ca83373f0d1b82ac1c4beda0f229a9011a81ec659ff5fc1fb105e219975b5c744308c77a24f71e4", + "0xaa5a312c47ff7248dcb9c6ffbe5a0628ccd565c07365c4413734d415cd4fb35772622ed833862dddff520a67c509c6a5", + "0xa02fb88805c34018ac33582e19ed0a7e4616acc3dd0867e5f21914c2031c05c6dca30b8b35b57c2b137750f3878a6f8c", + "0xa60528f1f14bf0c496491d46a0fbbd6c343e4eb3f1631e92f96a3c5e5c684091aabe5801df7a67f7c6dfd1b0d35269d4", + "0xa1fd8e7fad8ca05a340c05a051bb0eb4197eed345f4104629a9e38e234b09d789cc5537024615feb4a6177d32d39e39e", + "0x8e70e36c1aa070815440e19443f1f04aae23b1b59fdbcba43b47b94a026c82c8f66c5dfe54f826f4d95ee1930cdb8008", + "0x8234c1969fa7e9079661e4ca309b71b1aaa10f4372be0b963205c23a81f5a3d52ec08ba9ff65b37f832b52d631580d61", + "0xa18cb4134127fb37c4abca328cd0047378a2e1423490af2bd3eba9ffcc99ca81a3c22404c0886f21f65c7b93c41d7981", + "0xb46fa45fe538816de776eec086e040005706cb3eca097e290abfb6864e745c879868aac8361894f3c3564373ef9ad55c", + "0xb96ca43b96c59e95439f75d1e726a35a9362f0dbd34963b156e103e080a8126a8dc3501f9fd541ff3bcf4677f5c4a86b", + "0xa8e8c87c7301613818d57387009e601a7ab5cbdc2890f63d985c30c74f9cea2d0584c116baf0d9cd5594386ee93fc661", + "0xb47e4f1b9153ef0981f813948150f283b47a7346fd9921d51fe8e4daedaef78ddeb4fd467c2ccb7cebd9816243da1c6e", + "0xa370c202a99c8441ffe96fad0f801086d4d7cc7b960f6e98cca29ceedf492afddfd0f351c9c4d29ac008bc255ec1a2a8", + "0x8f5e6ce1655d1c059b006174e3f5a55c88e1821c97f9702ad8e8455d46c2a83ae4482f2d43edda74a835686ec45a8a15", + "0xa30421e694930a3b65d397b2720d5f8e1eec2b6e2bb5a28d3f9b0a84db9aabd83850268bae64c2b10e313cccf120151b", + "0x8abe87163046f7a9b18e2a3c0b66e258facc1b31431420e0b70354b7a60ebd250a784634a76692e7d6f4330b62114945", + "0x894f033cf077d4eb312e3258d9dca414356271abce1d6094ecce6d018c5fadb1c15d8d69451574ad0701a2876db191c5", + "0xb0923d64f88ffc872654e1a294bb1af8681689c21cf08f39afe51448a68e60a9a0a74ccce9969276a932a52c07d095a3", + "0xb9ca23b5be8725fae7fa710eefd45522889c50c29c26384e00b78a962384f0aeff9d15cb5910e9565da12a577eb7e5ba", + "0xb242ccf292757197a9f470f2d80ccddc48c7f1235ba026bc68a93be2738bc968e8a200aff3e2f4807216442eb3fc50dc", + "0xadc2c3b375b308524b79a024ff87d122055440643fea6fc0a651bdb312c7cbe6a456afa9d342bc76446d77d8daf08bc2", + "0xab645955356c2ebf2f3df9da275e01daf0b44a52afc309277d6d9ad1b05484e5ae0d9d41ad485fe481e5e362826a86ae", + "0x8de96ac587a4449fcc8b7fd0a51b4b5185d9c2eb3434f94cbadd092de1e26b0f6b3f7b15a37e8424b1429121ddca0ecd", + "0x94c70ad4e9b871566f3da98170b665a09788d421818299857cde0853789fb943cbcf7d4b2c95246ea7b72edc56a8e36c", + "0xb2574be63497843340700b701d5cc8be6d23125bd62058802ee67cce1f3b5f5602b27c93fea5611f27dc695ac563f042", + "0x869ec89da7850cedd88bcb3a50a15cece233119b31b64a61bf6b2310892ce42d8b473b584b11e61db29ed24ce8033f83", + "0x8fbaa269da8e28e9adf4c1b08f109da786dbe9cba871c32eecbfb10619b7a5d65a26f9bb33e201a8ed20b3de94003fbb", + "0x8bf7a059c37242caf7f821a6314e4e4adf799e0dd86b37892a7172598892c07272acebd05b534755c57b51556b2d610f", + "0xb4e72645fca459898cdd9214892ed08b5c99f82049c0a30d72bac0b9717caa9c6cc16c3dc7aa6ea4d42dcd2a6c175df6", + "0xa39170da87a3495da55bbb9701c5461f3403447174ed6a4af75712f7ba4ac35f51a4234bc4b94da888a0959ee109c0c7", + "0xb45675b2774ea7696089dbf7a0afe6c22e85fd0e4ef3db508fbaf96c9d07f700c991789206da9309fd291be696357c5f", + "0xb52899e3e3f6341eefcbe1291db6664bf3b6e8021d32fb9c3e37b6258a35c1da927747b2ce990937d6f4c6c3e7d020d2", + "0x84e5bdb3dfe19700d79dd3fabb0159ccfa084f7288db836c855b827613ce8071067c8d7ac5cc2b4e88ed7f84b690f6e1", + "0x801477d200b6d12fc6e0a9bab1c8211193ab06e44551e037a9b4c36fc2d4f67760b9ff4eba9a3bc7b6e177e891f64ff6", + "0xb6b71a5116d3c22af26a7530f535e9b7851f25a84e562a8f17a125d55b9b3fc1bd8cfe65bdcbeeb328409521e802051c", + "0x8687e21c34d7804c12489d30680d131ce2133e2981bfa993afd8a8eeda958ebd5e6881d342d725338659882d9f21cf98", + "0xa024e97a7c4de32b6383c34431994abc533ecdbd6be9bff836ec1af022f5a86773bf345c6f33273797a61fb70a8fd5d6", + "0x83f784f095da20ce5b31f54d6cb14b32a8a12675f0029289c9cd036b7c87a8077be2d04a62618685720e6ee69c875e97", + "0xb4e9dfe7cb9d9efd3fe00d99ae5e48769d4af4bf43d4e05c0b54c9cfd8bc854de96b8d3ebf4dcc06b9dac66b7471a0de", + "0xa08b79f9d4673afcf7f38b57f484f88feb7c908f597663a2417f92c348150c2be6b5603f914eba0d9d5bdd4e5c5572c1", + "0xb0eaf919589988798cb01ba0610cd1b7fa3c08715675ece8ecd5f9ef6d5d7b2c4c8ae1ea7dfd202237171aa3e6f9de74", + "0xabff99a98baae4dd0954052503ce81827781694a5ea8c1149f96a3adde75dc2d630e138598cd2ae7fdc7a654aa17df8f", + "0x83e369b8680d8b9d995222b033b4f4f3e3b20e782113c941325c7fa9c742feef8747e4a212d9aa23285a259cc4faef8d", + "0xb16d5855dd2716613697eba36e2fae0872aaea6999e91cf6552f93f9a0b85ed4f6ff922a91b50816bd6cf8e7a4513fc9", + "0x848373db600e32e741aa1d37726bbb28956783f89ce2d781e95fb1ee1adf4359968a141678af268077eae4c25503204e", + "0x93a0dd0fdac18a31875564505b4e28f9e8bb2915faae666538597731ac56cd77f23f2456461e2f672983fb24ad91f6e0", + "0xab1ebbe49fa56524b564bc2e43784147073e6ea5d27a9540fbf2e04d0f87c645ed2fd28b3e4982cc4c0af1734ee47a6f", + "0xb3ee30b733839edab6f61f0738e3f4afaeccf700d8dc7415684f193b36d70d07acd5780cf539f12e0fbf8d4683be773a", + "0x88388f2cbdec47a6b3ae460b69eb0d2130ac14de950c22fd86de03e40d02292bb93cebe62432da39d509c1289f785fef", + "0x9370c41a54b68ff486b4cc6329c3a851716ebf1d088d77a6c56dec93a18b8a77b596cde74cc17d2adb2b2f411a2e4bbb", + "0xb9083b60dc16531f77b05a955b51a237a8f8c0173d72c352c5ca441b55abbc890b14937e457aaec4be5cbbf80cae0099", + "0xaafff8f6c6ebaad952c65054dfc7c829453ec735331bf8135e06406b7a9f740c9a200dc48bb2175516b41f77dc160121", + "0xb43d31fbbaf10526809e9e5bd8bb47a76e0fabd7852ee7744404559ab89f0f215ff518f3271a6aa972a459cab82ac558", + "0xb581ede48c6ef34e678f91dc4b89507413e00e70712e3e8c32a80eed770ec8d8b98caee9702d068aeaca6f704be57bd8", + "0x8cb0a137e68b001a5ccac61de27cac9fb78d4af7b2f5a00b8d95d33ac19cc50c69e760c5e0330a85c0ded1edce0fe6f9", + "0xb947fca07c7aa6c2bf13048275402b00b77b28f1d0ba4b589fbcede13f93b5b931c588560ab8ceba23bb8e748031b55d", + "0x81753cced5ff819901740a9a584334e355b497cb699f0be5a52cd555a4c9f149535c7bb355b54407f7f0ec27de6c2e19", + "0xb3d59273951ce97838c4853ec329782a255b5fc7c848e7992ded1be28a5ada7fa3254123afe32607b9991ec6e0659b08", + "0x86b253de246f82be1cb0cef01e87c3d022ca1829d2cc7e6a160a5afbd3ca6b94d75739b122e3bb16f8bde28a8f3223ba", + "0xb728b659fa2d8487e061a37f7d14a4c2d70cc37497a8715695d8d332cb274deee2ce23b9b5f6a7408516c02c3d526a49", + "0x81277b46d98848a45abfbe39842495659dcbb80dee985a4fc91d77d52b815487aa8bb455f411fcce4c3879c7a075a93f", + "0xb05b6f1fb4a6e654f0ee6b83e08b58b57059bb0b7c490405bc8d963c4a2d6be39c558917977e554e1e9e3169961cbf3e", + "0x88f75fa7d016fb6442551ec071cc1e2beeb3ccd213d16d744f573a82f5d70f41dd1b18af71d5f9e73d87f2f6b7dbe889", + "0x81a46434f1bbd65a661a0ff45a0295b8fd8a42a7969c5953721bc98698b64bddee3f806876d1e9983063fdd0c11f99df", + "0x8b4f6d33c510a4c9c7d623d9ae0c9aa631fcb987704726b2a4d8519372123bce3c439202f25b5b47045ec14ce39a21a8", + "0x8d5112b330fb63cf6ef3d2164b404c14ff9907d685015701399a260951912b19b8f270f869df317e9050a127763d7980", + "0xaadab394e84dfb82db15ecd2427f39b62352c3e1647c3bcd14fb24ae830ad0116f0fed87ddb63963b424a4741961386e", + "0x81ca4e5600d00a3bda24cbdea7a532a4cbbd893c10e7ff10667c15ffa8138b91667abe5466b31a3dcdd60155c48538c1", + "0xad943af1b8a5fcfcf309ed8f2f916339f254cd555c71a407a47365a139306286a05a8314e1c70e20a65fccd75d36fa12", + "0xb16597a0b437060a390467bbfab94c0bdd695ae898894f4689f939e30cc2119cc08ecb594546304adf876f4e275ebcd9", + "0xa44a4e0a6693be356065891c27eefa040a1a79475be53d54d5fdcea7e0668ff9b35f850974000ed119f6865aa6faa721", + "0xadef27d1b6e6921f4eaf69c79e2e01f5174f7033eaafdd33edcfa5119af23f3a834ffe1bdf19576581b797abd1865b34", + "0x90c1e9202f3ffe28f8e1f58e9650dc4ff4dbc158005b6f2296ec36147e524b4f2f87f8aafc39db5b006fe0c491c92f45", + "0xac817cd54288b6f7fe6338415344fc9e7b669414051631ab2f27851c052c044be06bf7235d668e194bef695923256368", + "0xab14944ef653a14456d4ebc12e3196df3f1b4707c4e50b317b5ccc8ca3a0720f0330609f0e7e71793f6ca01583f38c70", + "0xad5353f2f380837e5ffdf079350b3d42935a0517861d03af98db5ed3ea8501abd68885c8c65f5a66e944b1874826a450", + "0x8b5583863f84af8443ce8970b02e26cc5d959e47efbf8a66a54106ab165f1f76b36423aee74c7b5402fd1c4d7c1adfe6", + "0xb3b46037eed9fc30e4f8f0da8bdbdcc40a38e22e876ce9fde981883017854aba82c18eb00887d92ad847d30082fe7271", + "0x98a2b6fc90b7ad172e4368c1e54675b75c8bf2096d91c9f2b60b3397d3be3b705aed5389845dbd68f0f84438cd0f7687", + "0xb155e800852a5f90a2eac69cc4483428da1dc2c31588a13c924e60a7616ce9baeb7d4b829c772b260277cadd8ed84719", + "0xb8b92c520a1302b0cf7d993a52e1dacd7f27bda9868d59c55687d995ae676b7070af4c0792a9bc1c2635d44a4fee01bb", + "0x96dfe9bde526b8fc829eda825f55168b88e8f4e43d4d708cc3060df03437b46e12a8ac70d7788aa75760f6294d3e84d8", + "0xa3fa66c54e2fa084ced3bd838614c6c33042f492a5745d167a723c60d5e7d6020ffd1747981a23f8b68df21ad8f0fa77", + "0xb573ca10cc41fc04a642f6f62c355a4fda69b94b8e95dbb02fd1ccce4bce1191356e1fd66d372159944eb36a7071f005", + "0xacd0a1c9abddfd0ea223eda1722aaada362d34234455bd1c6be115d41e535b16f12ca428da7820a757fa4c98884a385d", + "0x96f242eee99c4db383b8754fa7987c0c159652e1866faec905a8d3f010e0a1ad05bd77b9ea8dfd653738959180f58430", + "0x9215a9b672a5d6e435e0e0a45156e0e20f75cbbdf1d14940fed3ddb63d433bef643796c7a4fff881829ebb2b2eba9460", + "0xb8ad9bfceaf08dc5a874387219ddd1170bc3a5e25ed72d321d59ae713be5ddf9fdfbd3aa7ab163be28dfa0dd14614e19", + "0xa19a1050590bc500b32c502f393e407abc3d8e683d6f6b978873aff3e3299b18b1f6b59e2b0fe237d819dbdfcfdc98ca", + "0xa6870fb11d4429686e52e1f44c8dcfc7ea24a020df9570c021578dbc1f9bdc8cf797cb3a72d7fc52805dba35d59f2cd0", + "0xa7be733b64d5c06c127bd1c87250e42bfe30ca91ed8ce51e0b6e377f454e8f6fef7f99bff650695df2fd10c375da349b", + "0xa1b97145dab30330eea2cdc8739b2446a3704b64505fcea3dd8a9b4a72edf222e98d967d6fd7f76794acfd97aa091065", + "0xb2127049907d2a3b654d1c940b740bfba3dbaf660f86ea79c2f909af7c9fe2a07a1caeb1be12370aeffaf8faa50f1582", + "0x8a207701214bb28e99b0784e9228b1c34afa701966267fe7110f6f29f5bb41eaae6cdb98844d0400787978fabd224de8", + "0x9925147a383b6f5f814520220ffdbf20b214225882c3ef49b1a1ca677709176ec82466fb9c4be2dfbe5640afb63b014a", + "0x8416ad93871623fb555b5390b80de99edaaf317350cc0c1ae9d54d59517074d40061f315cce8ba2026d9c1e6f6a1009f", + "0xa315f943deebbf0a2cdbcf3f8323e215a406e9cbfbcc3f6288714cb3a6befb1bf71b2a21ff7a2ec4731c65044c45b6b5", + "0x8213e0c2539c24efd186ffa8b6dd401ad2233bc19166a0623b26dd1e93614bbf792823f5599ac116231e2efde9885709", + "0x8e5cafd2f34a127a4a896f05e4d929eef06972a1826b3566446942198df26d62f7679b987db2b3765d9d8058b1cd85c2", + "0xb5302b399c9cdf912fd59007ad4737255552663b1e56dbe64a7b2ddd88d2093c73ea319b45db2dd49d1e03f5bef1a0ae", + "0xa0c2bcfbed4b008e1a56e5d2f2419aa59d7dd0ebd990f1c18588de702ad0fa79f445d69965fa9381e700eda13b309378", + "0x80a44eea1ffe24c26b16b8e2e70ee519258b9ad4b3e83cc4e5cca88ebc48d0160066f8b91d0581095b0de2428390c8b3", + "0x84a90cb9c7d2f799f1c4ed060387a4b793ab41c5c3eaffd3b60face9b9c3bae93cd2017283bf3de1e3dac63d0d84dd42", + "0x81d22febca276a05ba9bbc5591ee087b0491beb35b4d9f8fc0d041d642a574667ddc57660b20f5c568f7d61fdcb41bda", + "0xa3ac965ac27a28e102a439b74fbfc157e75fd57620e4c0750a466165f8aeecb2191dcf8e656f7525aa50d9c7c69b0b5c", + "0x913c17434ff0d9fc52e2ece4fec71b37d4474a18f3ea26925c1be2b250434d49759f58033ba0fce1c6862c6197930dc4", + "0xac430559c151a5e461f67b49c7786c97e1653fa8698e9759ddbdd99f5daf17fc5a012ae6330739440880728f24eba7c9", + "0xb10d8e9f8aed9361b042d1398ec74364f7c7c1cc5c7f917060572761138bdbe89bf409389ee3879f93bc8032dd67b308", + "0x937271005a4cc6a6ec134870c1b56471aa84ed4f4af1b3d5f334bc0c42762fae0c9a6a2828d3de6151a76dad7b72781c", + "0xa10e4dcf51889f69e6bd4c052f8d4036b9571ced98a3d7d779cbcb9fa5c3a82228566ea7cc1d012bf56dea0a40c5a64c", + "0xa0ed026528d9a8bb3201bc9dcd20598933e8c72fd315deea8da63d06e97392aa729d98a55a8a60fa4d5573513ba5c9fe", + "0xb723fcd04cddbd4c36feae827a03746ffef251c4f4c55a88beedaeeee194430a99f566f483668a0d88b13e7a4a37f1de", + "0x84a2cdceed44828c7c05a6a762edec0165e434e7029df617d6646aba48776e6c3b823f40689cee136536f8c93e08a629", + "0xb786264e3a237ac3a1d56c9f4e87438dfed620c867100fd38b01287f5b755c7820937403bfb86644e082094d3e410a00", + "0x92cc35b2065fca157c7bba54410f8bd85907a01c9f760aa0ddb7a82cb55811d24cb4dc6b725367a6a1c293b809a48ead", + "0xa12bbf22b117f00164a42515bc57cc9e6c43cc77fb737ee3d0c0cad94cb50cd3847d61cab469cf8ca76f7958bdcfc771", + "0x85985b00de533bde2a757eddf53be79ea39091d16af3fc92327bcd1cd59bf2bf4411a334da29ad775e8ffaf3cea7d7b8", + "0xaf9eb24185b0d330d0ea1d0b0fa78af0dcf42ced81cb0128f16cafdea687a9c5582bb6d7c5744117b271cd0b3303f0b5", + "0x8c8aaa1d85ed6327f85d579767c7a9158d209171b3efcb3e8a9d9e534c078e821b6aade255101d2c9ef6d67ba66f10be", + "0xa450518a03ffb40e1df89e0f88fd55b5b06f4872cdfb7ec55f40dc40d9424b3b289866336c195bdd54597d95569e0096", + "0x81e61cc69f93c435bd77f155e80626a9c764dd92b6c76af15c41346527948d8a6ca87d6351a0fe7987e2ee3aa66a9625", + "0xb615e0cebf4fdff4cb23a20c8389c370915ba26aa703b28efe4ab070b1603d1c5b6541684acf46b52a915f6aee447539", + "0xa7f51885c7a71885cc84ef734ecd107e8bf5f7a25131415f671d143cc1de92859e65001125323c7985799993af6c410d", + "0xabfbf7a46f32066989c32f774edcc68163f085ca81e94fe8c9fb32f8d451bbb2c20ac45cd8d97f9e618ab40186933b1a", + "0x8cf35a522b5cac1934004aa9dd236bc77198d43272888afa860cfc79b4b28dabf7a3c74098f84510897566fdd609aa45", + "0x86aa927df78f7a06a4985eb0a4f0b93529cef14f9fd2812d46abffbf25e618ead14d99c70e3c3bb2e17f3f7fabc9c264", + "0x860f1b4f4a398e9a8bb4739587cf96979cfbbe1687b7e91e5bd1198db726391b09b1a261bf12e96698818f60b5bd3537", + "0x8e7c4ee19ff115881051e8637dce1f5d6c65e865d0c757e8ce41b6d7bcd86c7070cce60649692bbf28c868c7e2e1e2f4", + "0xacf7ba01b0220419f09169ac8d16e5cc13dce08e88c90b8fdfaa33aab417f011a20b79a178d8a9f7211589d2e0affd7d", + "0xb404bde8e715aefbb9f20a353b911b79173ef3e2cf0aba98b5ae6190b90597d65043b0b4e014ad9ea6c77da2d213ea12", + "0x97e3615d1c77a402253bb55da2d1cdf82de316cefffe42b1022c94b4818d6dc4a313731db85321c537914bdf716a875c", + "0x940e950b96a4096a578c6874d747515936652b9b113a5f27f5a834a610867b05f9881e2679b0b289b8527baa0009b6dd", + "0x8de15a13ca236a3a285ce6e6826c502ae7365bbe468b6e8ac67b15b0bb49be0e996f1eec81ef69e4b7f54f8e4779a054", + "0xa12244777eacb08ecd42b5676b3a51153022ab97e9353ace0f47c6054c22de9ba60d2a60f59a36841c2a791cb1b7c288", + "0x94f7580203e39a2642ee2e7c969b9911f011d7f3a90c398e1302d26edb3df03df1d0c43baa1c6cf90dde95296d49e742", + "0x82ead33144aaecab965faf63af384565992f38fc1066e71e33d53f43ac93892e27fe78c4eaca1cccbc53364e26ff31e9", + "0xa0c129e9706d354249a7f8aa664ccd7ede89aa1445c5547410814b56d10dc086720953363ab1da8ff5f1ed5d8e575104", + "0x93b3057bf3f74edc95237781ae012cc4b1d3fd0455565ceaac7110290aa518ac32478ba4eb9851555fa87270fcc84f1f", + "0x949c2fd0b94f31f7cbf00c679bd3f6ec1a2f4056654708d39edf1a450b4e19a6e251d0bb24eb765087e698f61d3fca2c", + "0x99fd2e50e211ccb66b895eb2fc42f260f3ad5767f04c2fe238b81dae98aa6e3977443a51f4fe7b43f499caabe45699a5", + "0x84fe19626503218f327b5325bfd7c0c3d2614b47d34964aa0259d564e769c6c81502132cc1765b0b31fbe39852706927", + "0xb43287ec29d9010bec4284de58fed48dd1e129bac79f09d45153c9949131782f77b11b0c9f8ee06a39e5e9bbaa8e2c6d", + "0x908902f3ed45482df2f94415fc8e5a308057a40c8905d7cbbd58ec4848e19276577b7f7e69e5e684a8b981738e10f7ef", + "0x85cc7d9c1eae372b4f88758cd6e21604b4bc9f0794e1e74b6d9de96347f81944d01331385fae7a38e5f6096c1dc23465", + "0xaf60288c702082fc258b3dbd6952c6b75c1641a623905f491b1e72f49b9d39b33d150a336450abd3911a4c128166acdf", + "0xa7d8ac7e589558c4014369ab6f4c1f2196205b03e4278152ec0dbbd7ba54e803c3369a71d364a773aac8dbbd117e4a13", + "0x9833aed34e48c206e9328073597aee1123f5bec085339b4e6839a389a429bf3042798a31fac1464ce963204adface76b", + "0x84631a4f012bbb62133030224b57deb32dcf464cacc8ffde7775adbe68707263ab5527a1c75e597e03aa703ba658b889", + "0xa686a61f6467858a2a4c13e70ad81b1901290d3e51bbc0c6e366f9e652f575e91b11c75f640ccef8b0c6c1b05a43c9a0", + "0xb585f0ffd5144907703b41539bfad7f9f058f5985f63db911064ba6b07af8da2796b84b16db42b8d11135c3f846cd9e2", + "0xb525539516c7bb25f1d7e165f269dc8c9eedbba74df44887e178ab8fd798e2a31f39812ca922d6b64d91564f14012a64", + "0x91e480d7568fd2fae39c35b0a8d623e66a3160fee1dd4e9097255004938b11ac1cd3918dc6a1e5fbcb700c95a547e5e8", + "0x936ef55c69b842b6177de71fa48dc5442bf5132116b214302f8f242ca36a273a6bbfbfaf373777104dadbe8e7da5e970", + "0x8e950c0f6688abdff8a3b8bd77be6da6f2565c7b55711f5860ea62a3ab1d51aac31821c602bc11a45e33c69e7dde3ea4", + "0x90eed4595104a0527f8db1e028ff622ff70db4eae99cf47f6c2a0246ec7b103570a6a9a877e32e9647cc74969006743d", + "0xb756344f6c4ea05b792e416d9bd9ce9dd4bd904e7622761f28a85628506bfc9d88a25e5f04db62fad30a92fb1d8d8556", + "0xad79ba76534c1a02ac3e9b7308d390792984cd75b7e1d0e5e4ff123642d99d4ea1825643091aa8117336333c40d5bd94", + "0x832b08144887de0c0341d84f6945450af8d7a4eb32367d7703118186c1be525df9382ce61fed5f3b65a0bb3449185f7f", + "0xa322fb944e46d8e47994820890c94af423674716da810ea1da71e0a7733ad72c22114ca39a4b59c98ce4291a5684c154", + "0xb982851a65140dbea79bd3b5487e236feccee051deddcc17c2853032efca289ddb6eaf64be3dd85a73012fdbe9d2d4f3", + "0x8eed5e230e201830b44b9fadca4e156fe1a16bf840cf29da0f381ea0587b20c226de2465c67e6268973e776809af68e1", + "0x81c8f1c04490f36e41a53ee1b5185cb8adbb37c258fd6c3be8c56835bf574c37183a94d55b6554fca35d6e6dd9af0133", + "0x8c4928724107cc16d36f2976677eac0b852fc4c3c0bb2f9cd4d59cd24a113faf33b2faf405c3fcce25be51d41e42c2c4", + "0x8e4ba842636fdfc4d71f0983538ea5037d420acd26abd12efca48c252eea85544b2fa9fccdfec4e7c2a6359baffa112d", + "0xb4315b84700e26dec26f3488d308430fdff4809c10d4c24309627911cbb769ffaad0d1ecccd622dd02194eaf5ba59f91", + "0xab888308f757faef32648c1db01650dbc9aea248b09d06e6efcc996d395f48ec96f2d54a02de441d753fe8737862d991", + "0x805094cfd77e207d5c75f3cad99f41f763ec15443052cfd758c6a82ba422d831a1103a7f9b100da49c28198279c3d3dc", + "0xad857f33243e4a2cd2a773700def21fc7f94939d1a6d2c2125ecd58fc206ccafb07a2c02a1cfce19857d3654aca2c70c", + "0xa4d12d40149953daa70b89a329e918e9d93efb4e8004a9357fe76682dab9662c8507e16db83e849340f05cdb4933a373", + "0xa0dbac2ed4b5d03606524245e8a31080eb5bd3e9a0c51dad88c3b18e3e6bc5d64953a81c8e60425b80107ee6b62b1fb4", + "0x86da05355900f327164a78901f6e3db857531b33b1e855df1a67a9ba222c6b05fdb6b0ffbacaeb1ba5b45ff8979b6b68", + "0x932c9873aa3e226dd922b5a616c75153bd0390ce8f332a414b9c8cb6606c2501a37a2aa88097bc7d8e2c4261706eb38c", + "0xaccd9cdf07ccdd42033ce3b105e00bfd39e2304b1e3d66f8b1128645634452c20f759ec45adcef2fdf04408f62c4cc04", + "0xb75cfdfc1cb48918752eab17eb579820ee6e71e6667abdb64df834ffc8c1362fbbc23ca2c80dee248fe1fbb72d87dfc8", + "0x88b998c73b00638fde7d3dd650a08c5ab996dac6ac34251337fbff3fb5ae4a25dd20c1a16c987ad7ded19eca23cea891", + "0x8afef0956c942571a27f504553fb312cca9e50ce41b44e0466d0516c5abe4d8acf4594cdb03b1ccdbe3f2e6a9093b713", + "0x9042cd83c5ff261e9ebda26398caa16cac2cb840d19062fa8ae50e044c27104972948318f4c866dc4d578798272d3e49", + "0xad536719a64570a2cd1d72b6590ea1d02c8c49f259a7867be26c8191445165954bcfad50ea12688ace3fdfb0e98143bd", + "0x97c86328d63d297b6bc9718dc1ad5a05b908a750d1c455c700d84315589128ce4eea958aef2bcf0fcf4adbd8e3ce58d1", + "0x8e592cf0802e6a9541eeb654dc55055e11f3d757847285197132935ca35bbb1a9156829a39384dfa6f645ff89eb36738", + "0xac16c614998944f77590bf3913a010e13f2d3bbf6a172293baf5983506c1a2d89989fb72e598f5bba1ea10a691377c93", + "0xab8e6f5b46baa6632de3621497bcbdd584decb999fe7d8a3364843a1e0b76497600630b6a24dd30119d8bcbfca29f335", + "0xabe1d3af5279e60122d9cea8cc6581c819d7a0e20e3715da0f6da7e02d13a7653db643bd946e2fa9ba338eca81fbe140", + "0x8c33bd831ecfb18d1d0713e16beba768e9c42df62170c1f8a16764912be77f2ac5915623d1d25e8c462aa9c2f6669ca4", + "0x903692becae4a6409f7bdb127d9b11de57a5739fe24218dcbaa0092648d5332dfeef29a908ee9e43e5e0a51a4c3639bc", + "0x92591e90347ae286acd365eba32cd9ad8f20f4c9cad2dc579b195147ff290adf0d776bcb3d4b04a25d68a941fc0c781b", + "0xb64bbccf860299aec16e1f95c768a1f337c740bde612e6ba260e393edb8b04540127194761c42597abb9bcb771c576c3", + "0x9194f056ccfdfeb78a11c5347e2255d7a7ebd1251f9aebc0b58feb68d3e03a7dbbb74e3ef7309455853adfb4694bd01a", + "0xaa4f15f6d6a53ae65b7f6f91e8981d07a5919d2138679a561f7bb608dc4596e45ca06c9441d51fb678b2ad89ae7a17ae", + "0x90e3d18507beb30bde08c5001faf489a19ab545c177efb3f73fbf5605f9a0abcdc8bfbc44f832d6028e3e0a834bea98f", + "0x8f31dc0118c8c88a6e79e502d10e57652b7aba8409a5bf572ca63fed6b7cbad7f28bbc92ac2264f649792fc1d0715085", + "0xa307d1067ea4c56437b6f8913aa8fcbf4a24580fc1e3336e7f6518f0f3adb9c4733090e459a3f737414ec0048179c30a", + "0xb7cc41fdf89595cd81a821669be712cd75f3a6c7a18f95da7d7a73de4f51bb0b44771c1f7cd3cd949e6f711313308716", + "0xa9dc74e197fe60e8c0db06b18f8fe536381946edecdf31e9bd90e1ebfcad7f361544884e2fe83c23b5632912ec284faf", + "0x8b3e1e81326d611567e26ed29108f33ddb838c45bbd1355b3ae7e5d463612af64b63fff9fa8e6f2c14c8806021a5a080", + "0x92f6537bca12778866335acc1eb4c3dfc2c8e7e5cf03399743dcea46aa66cac92ac2963b0892784263ad0ebe26ffdbf6", + "0xb5cc0061f7a3e41513199c7dd91ac60d727366482a4c7328527f7bd4fc3509412f711bb722b4413b3736a219b843d15d", + "0xb3e9711d68d2c6f6e2cc27e385d5f603d9a1c9a96edeefa1ffdf390439954d19504d6aadc566b47e229ad4940ef020d2", + "0xa09d0d3f0e5dc73a4a0827b72710b514bbfce4a7fcd5141d498a5aad6c38071077f50d3f91af897d9ab677b7041dedda", + "0xb177fe260f3b86e9ac21f1bfbe2682ae5dd8c9aecebb84f37054bdab6e39094e611ce582210ceeddde66adf759dadb6d", + "0xb0ac6595eba9f5dc4b2fd21856267cfbcfb5b12aa34ec69ca32b80071c5b652e85c25a224d80443d503bf25fbbfe07e9", + "0x81f3c0e11b196bd4a2e8f07f8c037002566dc9037da81f3988add458a520c24dd1be3d43d851e28c0c6a85de4b57a542", + "0xa44308c95615f7fedb2d2127012924468c015df9f48359cc2e36ab4223870b0bfc1e9040baabefdf5266f93afaad896b", + "0x8493ec4c32d5a13b81039f1b436eb83f259945dc950e3c6c2ccf5087ec56dd2f60890ed4edf01728b6a54950e19b35c6", + "0xa1a439ec2a6a95bdac9aaa925ff337ba956c0d236ab5318354270e73ed6b73b4ae2d27b4c1686cf97b6526d04e65be81", + "0xb4659b7b53c55a4b2bbe210b53520b392f893500e18990d843b72d7379d45fb44dd1dd2184348d6fd853d6b9ecc6b7c6", + "0xafb2c68d75d00130b0e1b4f250001920213121791698ec04262db714cf7b1408d39f6cc10421f954845aad5b8250b77e", + "0xb22b843b40a97210f94043b552f348f66743055a3f274856a738e7d90a625b80e9bbb80cbbb450e1666eb56b8bd5c60f", + "0x800895ced82fe13d5fff65a93b0051c3df698bf1221b682accfdb63e3970f669ca37025750697f4e8ff2a3322ad57be4", + "0xb21f598c50d7b9f4a584d548f85e42055ef8e24991906d973749090261584c7f4f5e984b528926f7e75375dd84d51af8", + "0x849b1c68192d18274598dd6d0bf48fb5ee3b1ba25b331cff2d06f345bef3bed49760ca5690848cf33388f6a9a32cd646", + "0xaeb6fd9478b10ef456f6bbb1e6dd19b14475e65497772d12cfc097948383d3fbd191bf95f046b8bf1989954118e483d0", + "0xb1b5e0ea2835f7fc8b66e7731e392b43d16cbce04b52906b6751ab1b91978899db5fecbdabc23a19dabb253005468136", + "0x91b6b1284770cf6f7ef35bc0b872b76c7763ffcfa68f9c8cfabcb2f264a66d47598bb9293f6a40f4c3dd33c265f45176", + "0xb9ffed029846487c2cfb8a4bb61782bd8a878f3afdb73c377a0ebe63139fa070e3fcdc583eec3a53fdc5a421ff1fa877", + "0x998007249d041b0b40ff546131cfc86d0b3598dcedf9a8778a223f7ed68ba4833b97324cbb1de91292b8ff51beab44b3", + "0x8eb77ce9e0e406bf6f002870fb2fd1447646dd240df9bd485f8e0869298a1fc799d8a41b130c04370e9a9cc5c7540ca5", + "0x853db8157462c46f2af7e8f94f2ed1c9b9a7ba2896b4973296898ff3d523d6e29e0b63a5d26cecd5e490b33c87a4cecf", + "0xb1436b6f3278768f0979ee852944258f2599977d255bea6fc912ba17c5dff5bdc850cf3e1fc52be9d6d188e868670f4f", + "0xa76acbc5832019b3b35667ab027feff49f01199a80016620f5c463dfcbfb51bf276ed17b7b683158ba450660cc7973eb", + "0x94540cdb051faf3ae8b8c52662868c2dab66bd02505c4f5f8eb4d6b2e2e5fd9a610890c5dcf8fd887eee796d2b5753a8", + "0xaa35099666bceccf4eb3b65b13bba88e30a8be93693ab6761d8e5523343e8d6dd42d977e66499352fe4e9e9784a1dd0d", + "0x894471aad17be54319083c4b5e40adcfacf7c36c4aab0b671030b7ef321c53590a25eccd836efd20f32a93185fd315bb", + "0x8f52a9f705bb0dea958fcfbd52e2b6c08ad0f89a07a6b2942c1b4c37eead0d97a38a9e9aeb08d5d59b7fa2a9347f738b", + "0x9031c16b4f936c9cab55585dc5064739f696c3347ee2c0792320c9f749e760d120e396e8485ffc79d81c9f3337ad3d1c", + "0x82090a0d0d9b05459ec1c328ecd4707c333b784e3aaa0ef0072cee1eac83f9a653a75d83b9f63512a8c41200494826b4", + "0x92c3a9553001f9ea4d67236b8ad1a33275378202cc1babc03f313895458f4b2549bfbbbdd37bfb8fbff0decb6b9f820a", + "0x88651868f4da37338a22bc553388df5dd1dd0cb78c4d7d07c637d8f6faef4bed72476fdcd4304d5bedf3514011135f08", + "0x83fa0141bfebd88063f1d787719721b4c6b19ecf565b866de9d7d5d1a890e0e3d859b364bb65f8f8e688654456a40263", + "0x90a7fab753e5d56dfc0e53a6b4e6ab14508220f3a62b3f3f30570c4c9ad225e74122635826c92e8e3227ec45e551432a", + "0x8fa375b0345bf6e5e062d108f9feaec91029345ecac67ccf1264eac77b8654cbfdda1f10579f481889c0e210254eadde", + "0xb83f06116da9daebdb013b26724523f077debaf6bc618b48a7a68858a98d275f7899c4ec73a0a827219b9248dd81c8c9", + "0x8be1cada55e0c5ebb4fd460b2d209ae5326285a20c8bdd54ed9d1a87302f4063c8730bfda52d9d40e0d6fe43a0628465", + "0xa68ad6f813743ec13a811f2ef3982c82d9d9ac1f7733936aa1e122f8dc7f4a305cc221579ab8fc170c3f123a1576f9ab", + "0x8878f1128214fdbbb8a0edd85223741e021508ab6d36c50d38680f2951ee713ea056ed03f62b9461897963d50ceefe0b", + "0xacc0d43d1b0260528b7425b260a5dea445b232b37240759fc65fe26f7c9d8e51569c5722bc33e94de6492f4ba1783504", + "0xad80b1dd717b076910ee5ceabcb762e75e4d094dc83b93b65c16de1f75bc712cef223c05d5579c1561829406c07a97d9", + "0xa6fc9803f9c09d95fc326cc284f42ea5566255eb215dba8a9afb0be155ea11bcc55938b2d16f01cd2f2eda218c715efb", + "0x83ad733dbdfbaae8095a403dbf09130513f4ed4f08dcf8dd76ce83d1ea72999b7eea3a7b731da0d2bc80a83c6ee0e3e0", + "0x8748912fbd08cb34a85416b0937d9c4327e9eed20d6e30aeb024a7253f14f1e0d774f3326e54738d71aae080e28da0fe", + "0x8997e78d8acf23051428af67183ae9b2c4aa42b503745ffe33df35a35103c589987e1473ab14dcd28ee78ebcb10d8e95", + "0xa2f340502a7eb3c4a36412e6f028321372c4fa18a4743945607424e932af1271fa3e6598a162c872072529576eba6283", + "0x868ccf19b5044ab93b45c9ed3ae34fcb504fe1453d6c4a1d12c325032cf01eb90356de82080ed897e97dba13cae33a02", + "0xac8867005fe4354d67aa37b866a7e581d2f94f7bd0b9f4efb5c2d1370ec13147a60692051b02fd00ae60b512bce9b1ff", + "0x8fd01886b046819c83c12bb779e432b25ba13713f9227be702074ec3abb2bba6be37220a0a26a4bd4171b99b14e32bc4", + "0xa128981ed199f92b5959975c150a93a62fec50b61c80a3fa0634d90fc8058f76f5cbee77aae6889af12d296b30e613cd", + "0x81fe618552ff7a36c9235c6d4066cf2f930b5b38de4089e18166e4a06ca5723eadd1976d25e34b74b3ce942300b23e5b", + "0xab1223ea049e6e0fbf9b611de7fd7c15e5e9637cbd73aa0e36aea08a7503ba6804f2aa807186fdc9aa7f4f9195f72e24", + "0xb97285286981b2665f898abc13f3243b63005bef8db4cab3f658bf6167036b61af400f08db0fc3c640a9c623b760690d", + "0xae3ddff7c1f0fbb6a13dbbc667a61e863c2c7c51c2051e33cd61620142e7e30a7e0c4c1f8fbb512aa3a8640267c6ac26", + "0x99c2a89d5bef236060e51c4f952664094c20fbfca647e5d24a55c1fb8df2f3df58244fbbf3635db07b1c29ee3234fa6f", + "0xa5010764d4b9cd3b410638334d1f70c5f4843f45b4f4a9316aaea5fbb2c510a97449dd7a07b49f47334a69d37d9955d3", + "0x86706d011dcdc9e9d165d01fea1df68dd74bedaf15a39f92893c030cafe96f4498c4c1fec2d2136354341b3f440a1462", + "0x88fd57eb62bd7dc35722f3a0576c2138403a2f663a2603482e8974a895cf56ddbb02657dc6b89eb2cf5c1f9d1aff6426", + "0xb0dfd4c68e3acb6bb8a776adaa421fc5e268ed4d5964bb90a727091e5113b55b3f9c6d33cedb3ee47ff7acc5df8b1749", + "0x93b92bc942e1a636fc5c2dc1840de5faf158a113d640d5a475b48e2c56ccccaf9db0e37e90ce74c4b3f5c9ac3b2eb523", + "0xb29a16fa1ea95cbfc1873c435ad40dc8495ba6341801b72bd95d908147dcffb1b4bb426dd635f3af4c88984f56594dd8", + "0xb8f367105e1a2d554ac30200c66aeb579d3d30a8953d20fb6ebba2d876ec39c52ea5d654f1bb89b8ddf3d9d651f31cdf", + "0xb5fbc228c983d08adf8612eba5b3db3acff604439226f86aa133b02cce4ffde2f977c8dbb8b446b4375673f71634c89d", + "0xa399bea37d3056e0559f6644faa0af93063b4b545d504d7e228d3dbbc294af83d3c4cf37fe026b63899b4e7d50fd08f5", + "0x928ef411a36414b24aea26fdbed4bdb1bb6bdc2d967e2553ce54c7c4e077e76869cea590257645c9129dd55ce025295c", + "0x9684a4adeed416a9ce82ad79b55c4a3adcfbd43950bc442ed8a340381caedb70f4baaaf821e3a152f483f965d8f56162", + "0x92558a37f214d6f4cb6d72cd2f4ad24dff9d17611b9e4a41ee5c741a5d1ca9e4053b0584533ef4da206110b5dc3e2a35", + "0x973bf0724d1785cc5e85d2a8ee8c354ad4cf557217ced0b7940f6f064024c20b2bfc5b144c820b5083da4bf70690de4d", + "0xadaf1389dfa528210ca9c2657c5ff10d51f7e3b18e93a59c37211be0506c3576cb2c04ec80cd0f82605e53c5a3556620", + "0x85b58b223b09fda6f3ab674d75e780c49eb2167837243df049281e8f4fed653811138b398db9cdfe7405fdb8485602fe", + "0x849504d3db408d80745a07e850b0a804607b91a59922a5d3bc40da2748c029c029419cda38d2a4485cc0824c6b2504f0", + "0xa3f4afcb353bc2582a02be758ebf0cd18752410ca2e64231176bfa23828423e0a450a65f241a9ed8eab36cae8d9c567b", + "0xae362786cdf121206537af9590d330abbc6dc328b53cdd145dbed0e5df1364c816aae757c4c81f9d619e3698dd32bcdf", + "0x9024cfa5b0101eb02ab97866d5a3832944e5aa6888484cfba3d856576b920787b364fba5956bd7c68a305afedc958201", + "0x8a116df09fed923acefb2aecf38a4fbc4b973ee964d67f03791d70bee6356af43ffca117d4e9463ffaf0e0d5d5e5a69f", + "0x9163016175c73f1bbc912ddfe03bd4e1db19c64951c8909ee6befe71a1249d838e0db49f03670bb4c5c9b2ab0fb4fef3", + "0x8f6357318d8d16e7240a02b05ce5a4976b6079d49daa258789c6dbf4a47950ebe9de6411780fab06c7c1f35651433380", + "0x8e63cbae8be7341892dbedee3111adf0307c4ee9e375181aa53478f5ba9cdce164d6ae890e5f480119a3a51c6e989165", + "0xa9782f30674a4874d91bfba7eda63aeb5dbe66b040c768d6a925d8ee135f0655ea56276b105239cc0668fc91ddb68cd1", + "0x8d9d94b61ab84ec08665cbe0244ea41756785df019e453ef078c19380bd44c39d2958e8465c72eacf41eed5696037805", + "0xb1470e6f5d2e314474937cb5a3bc30c8bf5fc3f79014945f6ee895fe20028ffc272f9d3a7320aac93e36c96d8a5454e3", + "0xa444911bbafc71179766594f3606b6eaff041826607fd3192f62dec05cd0f01b78598609a530f6930e8440db66f76713", + "0xa9823d44e2638fca7bcc8796cc91c3eb17f46ad6db9f7f6510e093727614aa3a4f9b2c4011ef91dc1c2d224d08d8d05b", + "0xab86020972c359ab98294212558b4b14862040139876c67fc494184b5c9bcea1dbe32fe0c8dd9e60be9daa304acd599a", + "0xb7e5cb685bbdcfdb1e48259a5d68d047846c8a35c5b3f90172fb183d1df40d22eaf0edaca2761a07c29c577000ccfed0", + "0x8c88319dae4b28989817e79e6667fd891181e8d2ed91b9c6b614985bca14b12982462ec58b17be0463c24bbb79dd62a1", + "0x8c1c6867e7107fb2178157c991b9c8b0f90c8d57a51220bf3650438ccabccf62da4db8a9916491e730ff3d0c106496e3", + "0xa00a79bd58da6528b9af033087260f9f3d00519eafb4746b355204ee994e89481591b508eaa5402821083e250d38467b", + "0x8785abd7c37690f6aa870ee5c799eef72e398a7898b6767f698515be277b9c2fc1af12ea89b0620a848221343a3b5ec3", + "0x8aadae68543db65cef71d0e230a09508d72061398ef2fabec0f856aacff2125b79c70e620744aaf331faf3dfc8afb9bc", + "0x8ff0cd437fcad9630b8a2333176a55e178db4142ec841581590594d74d5b53baeac5fb903fdf7bcf83e245b95b58285e", + "0xaf274e8fad6b190be4e5dc92d2705ba6ac0d7e1ea29e958a5cdd4cb764de46a56d9eef62c999a16e7c50a50b2d9fe3a8", + "0x865e6ec7d1aa848786d6a7a4e87a24d442311f0810b01ef5a74928ab59fdfd651e48880b49680047e5b0df6b3c7c2ecc", + "0x800706baaeb35bf3bc33bdea9a8b5cb00d82df407b3b7e1b781a9359cf44fb410ed311591080181b768aae223d9246aa", + "0xa9496389d0780b309c6998374ae159f58a8d0fe9a1c24c36cebcb45b27d818e653b51a8ee1f01e30a9b2c46a548126ef", + "0xb5fccf4fc3186661939fbee2e89c2aa0e3a6ad4907bcc98c7750520540c4c183b1bbfcdf47f2f1c5e75c3a30cdf30c75", + "0xa90028e39081b736e628c2230cc1338f9210ed01309a40fdf08d39c10cced2cdf71271013bea6dba3a0444fe47963106", + "0xa0815cbb325a8fecf2e1bcc5046644be32d43a8001bd5d8cf0022e4572cd0d481b3e717002f7ab21e16da5f5d16886d6", + "0xb2024787fcda52abc4138150f15e81f4a5be442929b1651ddccbfd558029912be4d61c3c9b467605fff640edf7392494", + "0xab5aa60032304a584cc9245a33f528eae7157808dedd1ad83ebae00aadc25dbe1cd5917eb8b6b2c800df15e67bdd4c4d", + "0x866643847ef512c5119f2f6e4e3b8d3f4abb885f530bb16fcef0edb698a5b0768905e51536283925b6795a5e68b60ddc", + "0x806aa99c9a46ee11cc3ebf0db2344b7515db8c45b09a46a85f8b2082940a6f7263f3c9b12214116c88310e706f8e973a", + "0xa6eada8b9ff3cd010f3174f3d894eb8bb19efdbff4c6d88976514a5b9968b0f1827d8ac4fe510fb0ba92b64583734a1e", + "0x98480db817c3abbc8b7baedf9bf5674ec4afcfd0cd0fd670363510a426dad1bcf1b1cb3bf0f1860e54530deb99460291", + "0x81ab480187af4a3dfbc87be29eca39b342a7e8e1d1df3fc61985e0e43d8d116b8eac2f1021bde4ae4e5e3606c1b67a21", + "0x8a37df12dc997bf9b800f8fd581a614a1d5e32b843f067d63d1ca7fde2e229d24413d3a8308ec1e8389bf88154adb517", + "0xb045a55ca0bb505bd5e8fcc4cfdd5e9af1a7d5fe7a797c7ede3f0b09712b37f493d3fcf6ef0e759d7e0157db1f583c95", + "0xad502e53a50691238323642e1d8b519b3c2c2f0fd6a0dd29de231f453be730cf1adc672887d97df42af0a300f7631087", + "0x80597648f10c6d8fcd7421caf4e7f126179633078a1724817d2adc41b783723f302eabc947a7ba7767166dacf4ce8fa1", + "0xaefb56427966c81081999dffbe89f8a0c402041929cd4e83d6612866cfbb97744f4ab802578349fbecc641fa9955e81b", + "0xa340e493fb3fb604eab864d4b18a6e40ba657003f1f88787e88e48b995da3d0ab4926ce438bdc8d100a41912a47dace0", + "0xa6d777bfc0895eac541a092e14499ff8bf7156689d916a678b50a1460583b38e68158984bea113a0a8e970d8a6799a85", + "0x90ce469410f0e8cfff40472817eb445770833cdcf2895a69bc32bcf959854d41712599ceb2b0422008d7300b05e62e02", + "0x815c51be91d8516d5adc2fd61b6600957ed07cf5fdc809aa652b059bea8ed179638a19077a3f040334032f0e7900ac8b", + "0xb3ec6c0c3c007c49c6b7f7fc2ffd3d3a41cdff5ad3ac40831f53bfc0c799ffeed5f440a27acc5f64432e847cc17dd82e", + "0x823637abeab5fb19e4810b045254558d98828126e9a2d5895a34b9e4b4f49ab0a5b3ee2422f1f378995ea05df5516057", + "0xac05412bcf46c254f6548d8107a63928bba19ab6889de5d331eb68cf4d8ce206055b83af4cb7c6c23b50188391e93f84", + "0x88514163c587068178302bc56e9a8b3ad2fa62afd405db92f2478bb730101358c99c0fe40020eeed818c4e251007de9c", + "0xb1e657d0f7772795b3f5a84317b889e8ded7a08ea5beb2ab437bebf56bcb508ae7215742819ed1e4ae3969995fe3b35d", + "0xa727d4f03027fe858656ca5c51240a65924915bd8bd7ffa3cfc8314a03594738234df717e78bb55a7add61a0a4501836", + "0xb601682830fc4d48ece2bdc9f1a1d5b9a2879c40c46135f00c2c3ae1187c821412f0f0cfbc83d4e144ddd7b702ca8e78", + "0xb5cfea436aa1f29c4446979272a8637cb277f282825674ddb3acac2c280662fb119e6b2bdd52c4b8dbf2c39b1d2070d6", + "0x85c211645ff746669f60aa314093703b9045966604c6aa75aae28422621b256c0c2be835b87e87a00d3f144e8ab7b5f0", + "0x867628d25bab4cb85d448fd50fdd117be1decdd57292e194a8baa0655978fae551912851660a1d5b9de7a2afbb88ef5c", + "0xa4e79c55d1b13c959ff93ddcf1747722c6312a7941a3b49f79006b3165334bab369e5469f1bddebadb12bfaff53806d5", + "0xac61f0973e84546487c5da7991209526c380e3731925b93228d93a93bce1283a3e0807152354f5fe7f3ea44fc447f8fe", + "0xa1aa676735a73a671a4e10de2078fd2725660052aa344ca2eb4d56ee0fd04552fe9873ee14a85b09c55708443182183a", + "0x8e2f13269f0a264ef2b772d24425bef5b9aa7ea5bbfbefbcc5fd2a5efd4927641c3d2374d0548439a9f6302d7e4ba149", + "0xb0aacdaf27548d4f9de6e1ec3ad80e196761e3fb07c440909524a83880d78c93465aea13040e99de0e60340e5a5503cd", + "0xa41b25ae64f66de4726013538411d0ac10fdb974420352f2adb6ce2dcad7b762fd7982c8062a9bac85cdfcc4b577fd18", + "0xb32d87d5d551f93a16ec983fd4ef9c0efcdae4f5e242ce558e77bcde8e472a0df666875af0aeec1a7c10daebebab76ea", + "0xb8515795775856e25899e487bf4e5c2b49e04b7fbe40cb3b5c25378bcccde11971da280e8b7ba44d72b8436e2066e20f", + "0x91769a608c9a32f39ca9d14d5451e10071de2fd6b0baec9a541c8fad22da75ed4946e7f8b081f79cc2a67bd2452066a9", + "0x87b1e6dbca2b9dbc8ce67fd2f54ffe96dfcce9609210a674a4cb47dd71a8d95a5a24191d87ba4effa4a84d7db51f9ba0", + "0xa95accf3dbcbf3798bab280cabe46e3e3688c5db29944dbe8f9bd8559d70352b0cfac023852adc67c73ce203cbb00a81", + "0xa835f8ce7a8aa772c3d7cfe35971c33fc36aa3333b8fae5225787533a1e4839a36c84c0949410bb6aace6d4085588b1e", + "0x8ef7faa2cf93889e7a291713ab39b3a20875576a34a8072a133fed01046f8093ace6b858463e1e8a7f923d57e4e1bc38", + "0x969ecd85643a16d937f148e15fb56c9550aefd68a638425de5058333e8c0f94b1df338eaab1bd683190bfde68460622b", + "0x8982f4c76b782b9b47a9c5aeb135278e5c991b1558e47b79328c4fae4b30b2b20c01204ff1afb62b7797879d9dee48e2", + "0xb5098b7ba813178ced68f873c8c223e23a3283d9f1a061c95b68f37310bca4b2934a3a725fff1de1341c79bb3ba6007e", + "0x97b160787009f7b9649ed63db9387d48a669e17b2aba8656792eb4f5685bb8e6386f275476b4dfbb1b4cb0c2a69bc752", + "0x88b69369c71daad6b84fa51a0f64a6962d8c77e555b13c035ad6fa1038e7190af455b1bd61ae328b65d6a14cf3d5f0d5", + "0xaf88b87801361f0de26bd2533554ee6f4d8067e3122b54161c313c52cc9eafea00661c5c43e2d533485d1f26da4e5510", + "0x98ab18e3bbcb23ac1e34439849e56009bb765ab2f2558ebfd0a57cbe742169f114bceb930533fb911b22cb5a8fe172bc", + "0x9027507f1725d81e5ac0f0854c89ab627df3020fe928cb8745f887bf3310086c58fca1119fd5cd18a7d3561c042d58de", + "0xa676583f8a26e6f8991a0791916ce785b596ce372812f5eb7b4243ba9367ea95c797170fdac5b0c5e6b7f6519cc2b026", + "0xb91b0ab32638aef3365035a41c6068e36d2303bfee8640565e16c9a56c21703270fd45946ce663238a72c053eb3f2230", + "0xaaf4cd1ac0a30906dcd2b66b37848c6cc443da511e0b0367fd792887fdaf1500551590440e61d837dbee9d24c9801108", + "0xa06f20a02d3cd76029baad5a12592f181738378a83a95e90470fa7cc82a5ae9d2ed824a20eeb1e96e6edc0619f298688", + "0xa465d379c3481b294efc3f2f940b651c45579607cf72d143b99705eae42103a0279eb3595966453130e18935265e35d6", + "0x892a8af7816a806295278027a956663ea1297118ede0f2a7e670483b81fb14dccacc7a652e12f160e531d806ca5f2861", + "0xb480917c0e8b6e00de11b4416a20af6c48a343450a32ee43224559d30e1fecdece52cc699493e1754c0571b84f6c02c2", + "0xb3182da84c81e5a52e22cebed985b0efc3056350ec59e8646e7fd984cdb32e6ac14e76609d0ffaca204a7a3c20e9f95d", + "0xa04ea6392f3b5a176fa797ddec3214946962b84a8f729ffbd01ca65767ff6237da8147fc9dc7dd88662ad0faefdb538c", + "0x95c0d10a9ba2b0eb1fd7aa60c743b6cf333bb7f3d7adedce055d6cd35b755d326bf9102afabb1634f209d8dacfd47f1a", + "0xa1a583d28b07601541fa666767f4f45c954431f8f3cc3f96380364c5044ff9f64114160e5002fb2bbc20812b8cbd36cb", + "0xa1a0708af5034545e8fcc771f41e14dff421eed08b4606f6d051f2d7799efd00d3a59a1b9a811fa4eddf5682e63102ea", + "0xab27c7f54096483dd85c866cfb347166abe179dc5ffaca0c29cf3bfe5166864c7fa5f954c919b3ba00bdbab38e03407d", + "0xac8c82271c8ca71125b380ed6c61b326c1cfe5664ccd7f52820e11f2bea334b6f60b1cf1d31599ed94d8218aa6fbf546", + "0xa015ea84237d6aa2adb677ce1ff8a137ef48b460afaca20ae826a53d7e731320ebdd9ee836de7d812178bec010dd6799", + "0x925418cda78a56c5b15d0f2dc66f720bda2885f15ffafb02ce9c9eed7167e68c04ad6ae5aa09c8c1c2f387aa39ad6d1b", + "0x87c00bba80a965b3742deacafb269ca94ead4eb57fdb3ed28e776b1d0989e1b1dba289019cfb1a0f849e58668a4f1552", + "0x948d492db131ca194f4e6f9ae1ea6ebc46ebbed5d11f1f305d3d90d6b4995b1218b9606d114f48282a15661a8a8051ca", + "0x8179617d64306417d6865add8b7be8452f1759721f97d737ef8a3c90da6551034049af781b6686b2ea99f87d376bce64", + "0x918e3da425b7c41e195ed7b726fa26b15a64299fe12a3c22f51a2a257e847611ac6cfcc99294317523fc491e1cbe60c4", + "0xa339682a37844d15ca37f753599d0a71eedfbbf7b241f231dd93e5d349c6f7130e0d0b97e6abd2d894f8b701da37cb11", + "0x8fc284f37bee79067f473bc8b6de4258930a21c28ac54aaf00b36f5ac28230474250f3aa6a703b6057f7fb79a203c2c1", + "0xa2c474e3a52a48cd1928e755f610fefa52d557eb67974d02287dbb935c4b9aab7227a325424fed65f8f6d556d8a46812", + "0x99b88390fa856aa1b8e615a53f19c83e083f9b50705d8a15922e7c3e8216f808a4cc80744ca12506b1661d31d8d962e4", + "0xa1cbd03e4d4f58fc4d48fa165d824b77838c224765f35d976d3107d44a6cf41e13f661f0e86f87589292721f4de703fb", + "0xb3a5dde8a40e55d8d5532beaa5f734ee8e91eafad3696df92399ae10793a8a10319b6dc53495edcc9b5cfd50a389a086", + "0x996e25e1df5c2203647b9a1744bd1b1811857f742aee0801508457a3575666fcc8fc0c047c2b4341d4b507008cd674c2", + "0x93e0a66039e74e324ee6c38809b3608507c492ef752202fff0b2c0e1261ca28f1790b3af4fdb236f0ed7e963e05c1ec0", + "0xb6084e5818d2d860ac1606d3858329fbad4708f79d51a6f072dc370a21fdb1e1b207b74bc265a8547658bfb6a9569bb3", + "0xa5336126a99c0ecfc890584b2a167922a26cae652dfc96a96ab2faf0bf9842f166b39ceaf396cd3d300d0ebb2e6e0ebf", + "0xb8b6f13ce9201decaba76d4eca9b9fa2e7445f9bc7dc9f82c262f49b15a40d45d5335819b71ff2ee40465da47d015c47", + "0xb45df257b40c68b7916b768092e91c72b37d3ed2a44b09bf23102a4f33348849026cb3f9fbb484adfea149e2d2a180ff", + "0xa50d38ee017e28021229c4bb7d83dd9cdad27ab3aa38980b2423b96aa3f7dc618e3b23895b0e1379ca20299ff1919bbf", + "0x97542cf600d34e4fdc07d074e8054e950708284ed99c96c7f15496937242365c66e323b0e09c49c9c38113096640a1b6", + "0x822d198629697dcd663be9c95ff1b39419eae2463fa7e6d996b2c009d746bedc8333be241850153d16c5276749c10b20", + "0x9217bc14974766ebdfbf6b434dd84b32b04658c8d8d3c31b5ff04199795d1cfad583782fd0c7438df865b81b2f116f9c", + "0x93477879fa28a89471a2c65ef6e253f30911da44260833dd51030b7a2130a923770ebd60b9120f551ab373f7d9ed80aa", + "0x87d89ff7373f795a3a798f03e58a0f0f0e7deab8db2802863fab84a7be64ae4dcf82ece18c4ddbefccd356262c2e8176", + "0xa3ba26bd31d3cc53ceeced422eb9a63c0383cde9476b5f1902b7fe2b19e0bbf420a2172ac5c8c24f1f5c466eecc615d4", + "0xa0fe061c76c90d84bd4353e52e1ef4b0561919769dbabe1679b08ef6c98dcfb6258f122bb440993d976c0ab38854386b", + "0xb3070aa470185cb574b3af6c94b4069068b89bb9f7ea7db0a668df0b5e6aabdfe784581f13f0cf35cd4c67726f139a8c", + "0x9365e4cdf25e116cbc4a55de89d609bba0eaf0df2a078e624765509f8f5a862e5da41b81883df086a0e5005ce1576223", + "0xa9036081945e3072fa3b5f022df698a8f78e62ab1e9559c88f9c54e00bc091a547467d5e2c7cbf6bc7396acb96dd2c46", + "0x8309890959fcc2a4b3d7232f9062ee51ece20c7e631a00ec151d6b4d5dfccf14c805ce5f9aa569d74fb13ae25f9a6bbe", + "0xb1dc43f07303634157f78e213c2fae99435661cc56a24be536ccbd345ef666798b3ac53c438209b47eb62b91d6fea90a", + "0x84eb451e0a74ef14a2c2266ff01bd33d9a91163c71f89d0a9c0b8edfcfe918fc549565509cd96eed5720a438ff55f7f2", + "0x9863b85a10db32c4317b19cc9245492b9389b318cf128d9bbc7ec80a694fcbbd3c0d3189a8cad00cc9290e67e5b361ee", + "0x8a150ee474ebe48bdfcac1b29e46ac90dcded8abbe4807a165214e66f780f424be367df5ef1e94b09acf4a00cd2e614d", + "0xa6677a373130b83e30849af12475e192f817ba4f3226529a9cca8baaefb8811db376e4a044b42bf1481268c249b1a66e", + "0xb969cbf444c1297aa50d1dfa0894de4565161cb1fc59ba03af9655c5bf94775006fe8659d3445b546538a22a43be6b93", + "0x8383167e5275e0707e391645dc9dea9e8a19640ecfa23387f7f6fcaddff5cde0b4090dfad7af3c36f8d5c7705568e8d8", + "0xa353ddbc6b6837773e49bb1e33a3e00ca2fb5f7e1dba3a004b0de75f94a4e90860d082a455968851ef050ae5904452e0", + "0xadeccf320d7d2831b495479b4db4aa0e25c5f3574f65a978c112e9981b2663f59de4c2fa88974fdcabb2eedb7adab452", + "0xafa0eacc9fdbe27fb5e640ecad7ecc785df0daf00fc1325af716af61786719dd7f2d9e085a71d8dc059e54fd68a41f24", + "0xa5b803a5bbe0ca77c8b95e1e7bacfd22feae9f053270a191b4fd9bca850ef21a2d4bd9bcd50ecfb971bb458ff2354840", + "0xb023c9c95613d9692a301ef33176b655ba11769a364b787f02b42ceb72338642655ea7a3a55a3eec6e1e3b652c3a179e", + "0x8fa616aa7196fc2402f23a19e54620d4cf4cf48e1adfb7ea1f3711c69705481ddcc4c97236d47a92e974984d124589e5", + "0xa49e11e30cb81cb7617935e8a30110b8d241b67df2d603e5acc66af53702cf1e9c3ef4a9b777be49a9f0f576c65dcc30", + "0x8df70b0f19381752fe327c81cce15192389e695586050f26344f56e451df2be0b1cdf7ec0cba7ce5b911dcff2b9325ae", + "0x8fbbc21a59d5f5a14ff455ca78a9a393cab91deb61cf1c25117db2714d752e0054ed3e7e13dd36ad423815344140f443", + "0xa9a03285488668ab97836a713c6e608986c571d6a6c21e1adbd99ae4009b3dde43721a705d751f1bd4ebf1ea7511dfed", + "0xb2f32b8e19e296e8402251df67bae6066aeefd89047586d887ffa2eacdf38e83d4f9dc32e553799024c7a41818945755", + "0x942cf596b2278ad478be5c0ab6a2ad0ceafe110263cc93d15b9a3f420932104e462cf37586c374f10b1040cb83b862e0", + "0xaaa077a55f501c875ceae0a27ef2b180be9de660ef3d6b2132eb17256771ce609d9bc8aaf687f2b56ae46af34ad12b30", + "0x90ac74885be1448101cf3b957d4486e379673328a006ea42715c39916e9334ea77117ff4a60d858e2ccce9694547a14f", + "0x9256cdfc2339e89db56fd04bd9b0611be0eefc5ee30711bcece4aadf2efcc5a6dcc0cfd5f733e0e307e3a58055dff612", + "0xa4c7384e208a0863f4c056248f595473dcde70f019ddaede45b8caf0752575c241bac6e436439f380ac88eee23a858e9", + "0xa3aa67391781e0736dddc389f86b430b2fc293b7bd56bfd5a8ec01d1dd52ed940593c3ad4ce25905061936da062b0af6", + "0x80299275ec322fbb66cc7dce4482ddd846534e92121186b6906c9a5d5834346b7de75909b22b98d73120caec964e7012", + "0xaa3a6cd88e5f98a12738b6688f54478815e26778357bcc2bc9f2648db408d6076ef73cced92a0a6b8b486453c9379f18", + "0xb07c444681dc87b08a7d7c86708b82e82f8f2dbd4001986027b82cfbed17b9043e1104ade612e8e7993a00a4f8128c93", + "0xaf40e01b68d908ac2a55dca9b07bb46378c969839c6c822d298a01bc91540ea7a0c07720a098be9a3cfe9c27918e80e8", + "0xabd8947c3bbc3883c80d8c873f8e2dc9b878cbbb4fc4a753a68f5027de6d8c26aa8fbbafeb85519ac94e2db660f31f26", + "0xa234f9d1a8f0cb5d017ccca30b591c95ec416c1cb906bd3e71b13627f27960f61f41ed603ffbcf043fd79974ec3169a8", + "0x835aaf52a6af2bc7da4cf1586c1a27c72ad9de03c88922ad172dce7550d70f6f3efcc3820d38cd56ae3f7fc2f901f7a0", + "0xae75db982a45ad01f4aa7bc50d642ff188219652bb8d521d13a9877049425d57852f3c9e4d340ffec12a4d0c639e7062", + "0xb88884aa9187c33dc784a96832c86a44d24e9ffe6315544d47fc25428f11337b9ffd56eb0a03ad709d1bf86175059096", + "0x8492ca5afcc6c0187b06453f01ed45fd57eb56facbeea30c93686b9e1dab8eaabd89e0ccb24b5f35d3d19cd7a58b5338", + "0x9350623b6e1592b7ea31b1349724114512c3cce1e5459cd5bddd3d0a9b2accc64ab2bf67a71382d81190c3ab7466ba08", + "0x98e8bf9bed6ae33b7c7e0e49fc43de135bffdba12b5dcb9ff38cb2d2a5368bb570fe7ee8e7fbe68220084d1d3505d5be", + "0xab56144393f55f4c6f80c67e0ab68f445568d68b5aa0118c0c666664a43ba6307ee6508ba0bb5eb17664817bc9749af0", + "0x827d5717a41b8592cfd1b796a30d6b2c3ca2cdc92455f9f4294b051c4c97b7ad6373f692ddafda67884102e6c2a16113", + "0x8445ce2bb81598067edaa2a9e356eda42fb6dc5dd936ccf3d1ff847139e6020310d43d0fec1fe70296e8f9e41a40eb20", + "0x9405178d965ee51e8d76d29101933837a85710961bb61f743d563ef17263f3c2e161d57e133afac209cdb5c46b105e31", + "0xb209f9ed324c0daa68f79800c0a1338bbaf6d37b539871cb7570f2c235caca238a2c4407961fcb7471a103545495ef2c", + "0x92ae6437af6bbd97e729b82f5b0d8fb081ca822f340e20fae1875bdc65694cd9b8c037a5a1d49aa9cae3d33f5bad414e", + "0x9445bdb666eae03449a38e00851629e29a7415c8274e93343dc0020f439a5df0009cd3c4f5b9ce5c0f79aefa53ceac99", + "0x93fdab5f9f792eada28f75e9ac6042a2c7f3142ba416bfdb1f90aa8461dbe4af524eee6db4f421cb70c7bc204684d043", + "0xa7f4dc949af4c3163953320898104a2b17161f7be5a5615da684f881633174fb0b712d0b7584b76302e811f3fac3c12f", + "0xa8ac84da817b3066ba9789bf2a566ccf84ab0a374210b8a215a9dcf493656a3fa0ecf07c4178920245fee0e46de7c3ec", + "0x8e6a0ae1273acda3aa50d07d293d580414110a63bc3fb6330bb2ee6f824aff0d8f42b7375a1a5ba85c05bfbe9da88cb5", + "0xa5dea98852bd6f51a84fa06e331ea73a08d9d220cda437f694ad9ad02cf10657882242e20bdf21acbbaa545047da4ce5", + "0xb13f410bf4cfce0827a5dfd1d6b5d8eabc60203b26f4c88238b8000f5b3aaf03242cdeadc2973b33109751da367069e1", + "0xa334315a9d61b692ad919b616df0aa75a9f73e4ea6fc27d216f48964e7daebd84b796418580cf97d4f08d4a4b51037cd", + "0x8901ba9e963fcd2f7e08179b6d19c7a3b8193b78ca0e5cf0175916de873ca0d000cd7ac678c0473be371e0ac132f35a2", + "0xb11a445433745f6cb14c9a65314bbf78b852f7b00786501b05d66092b871111cd7bee25f702d9e550d7dd91601620abb", + "0x8c2f7b8e7b906c71f2f154cc9f053e8394509c37c07b9d4f21b4495e80484fc5fc8ab4bdc525bd6cfa9518680ba0d1a2", + "0xb9733cebe92b43b899d3d1bfbf4b71d12f40d1853b2c98e36e635fdd8a0603ab03119890a67127e6bc79afae35b0bef2", + "0xa560f6692e88510d9ba940371e1ada344caf0c36440f492a3067ba38e9b7011caac37ba096a8a4accb1c8656d3c019b3", + "0xac18624339c1487b2626eef00d66b302bdb1526b6340d6847befe2fdfb2b410be5555f82939f8707f756db0e021ed398", + "0xafd9a3b8866a7fe4f7bc13470c0169b9705fcd3073685f5a6dcff3bdbbc2be50ac6d9908f9a10c5104b0bffc2bc14dad", + "0x97f15c92fe1f10949ed9def5dd238bc1429706e5037a0e0afb71c2d0e5845e2fed95a171c393e372077a7c7059f8c0e0", + "0x9453a1d4d09c309b70968ea527007d34df9c4cfd3048e5391aac5f9b64ca0c05dde5b8c949c481cfc83ef2e57b687595", + "0xb80e4b7c379ad435c91b20b3706253b763cbc980db78f782f955d2516af44c07bbfa5888cbf3a8439dc3907320feb25a", + "0x8939f458d28fefe45320b95d75b006e98330254056d063e4a2f20f04bcb25936024efe8d436d491ed34b482f9b9ae49c", + "0xa9ead2e833f71f7e574c766440c4b3c9c3363698c7ade14499a56003a272832ee6d99440887fa43ccdf80265b9d56b97", + "0xb6547a36934f05ce7b779e68049d61351cf229ae72dc211cc96a2a471b2724782f9355fdb415ea6f0ea1eb84fe00e785", + "0x828bfb3099b7b650b29b0f21279f829391f64520a6ab916d1056f647088f1e50fac9253ef7464eceab5380035c5a59c4", + "0x8d714b9ea650be4342ff06c0256189e85c5c125adf6c7aeca3dba9b21d5e01a28b688fc2116ce285a0714a8f1425c0b8", + "0x8a82eda041b2e72a3d73d70d85a568e035fbd6dc32559b6c6cfdf6f4edcb59a6ba85b6294a721aa0a71b07714e0b99ae", + "0xaf5665ebc83d027173b14ffb0e05af0a192b719177889fadc9ac8c082fda721e9a75d9ce3f5602dbfd516600ee3b6405", + "0xa68fdddf03d77bebdb676e40d93e59bd854408793df2935d0a5600601f7691b879981a398d02658c2da39dbbf61ef96c", + "0x8c001ebc84fcf0470b837a08a7b6125126b73a2762db47bbdc38c0e7992b1c66bac7a64faa1bf1020d1c63b40adc3082", + "0x8553889b49f9491109792db0a69347880a9cf2911b4f16f59f7f424e5e6b553687d51282e8f95be6a543635247e2e2c2", + "0xa2c269d6370b541daf1f23cc6b5d2b03a5fa0c7538d53ae500ef875952fe215e74a5010329ff41461f4c58b32ad97b3d", + "0xa5dae097285392b4eba83a9fd24baa03d42d0a157a37fae4b6efc3f45be86024b1182e4a6b6eadcf5efe37704c0a1ae5", + "0x89871a77d2032387d19369933cd50a26bda643e40cfd0ce73febe717a51b39fae981406fd41e50f4a837c02a99524ef9", + "0x8a76d495e90093ec2ac22f53759dc1cf36fbb8370fb586acbd3895c56a90bbf3796bcc4fc422ca4058adf337ead1402e", + "0xad4eb7576c4954d20623c1336c63662c2a6fb46ec6ef99b7f8e946aa47488dcb136eab60b35600f98c78c16c10c99013", + "0x894c2b120cec539feb1d281baaadde1e44beafedeeec29b804473fe024e25c1db652f151c956e88d9081fb39d27e0b19", + "0x9196bd5c100878792444c573d02b380a69e1b4b30cb59a48114852085058a5fd952df4afee3ecceb5c4ede21e1ed4a1a", + "0xa996fffc910764ea87a1eedc3a3d600e6e0ff70e6a999cb435c9b713a89600fc130d1850174efe9fc18244bb7c6c5936", + "0x8591bb8826befa8bee9663230d9a864a5068589f059e37b450e8c85e15ce9a1992f0ce1ead1d9829b452997727edcf9d", + "0x9465e20bb22c41bf1fa728be8e069e25cda3f7c243381ca9973cbedad0c7b07d3dd3e85719d77cf80b1058ce60e16d68", + "0x926b5ce39b6e60b94878ffeae9ff20178656c375fb9cfe160b82318ca500eb3e2e3144608b6c3f8d6c856b8fe1e2fbcf", + "0xa1ef29cbc83c45eb28ad468d0ce5d0fdd6b9d8191ba5ffa1a781c2b232ed23db6b7b04de06ef31763a6bfe377fa2f408", + "0x9328e63a3c8acf457c9f1f28b32d90d0eeadb0f650b5d43486a61d7374757a7ada5fc1def2a1e600fa255d8b3f48036f", + "0xa9c64880fcb7654f4dd08f4c90baac95712dd6dd407e17ea60606e9a97dc8e54dd25cb72a9bf3fc61f8d0ad569fe369d", + "0xa908eb7b940c1963f73046d6b35d40e09013bfbfbeb2ccd64df441867e202b0f3b625fa32dd04987c3d7851360abdffc", + "0xb3947b5ed6d59e59e4472cdb1c3261de1b5278fb7cb9b5fca553f328b3b3e094596861ea526eca02395f7b7358155b7b", + "0x99da7f190d37bc58945f981cf484d40fcf0855cf8178e2ce8d057c7f0a9d9f77425fdbce9ef8366f44f671b20fd27d0b", + "0x913976d77d80e3657977df39571577fdf0be68ba846883705b454f8493578baa741cfaede53783e2c97cc08964395d83", + "0x8d754a61e5164a80b5090c13f3e936056812d4ae8dc5cc649e6c7f37464777249bc4ae760a9806939131f39d92cca5bf", + "0x82ffd098480828a90cb221a8c28584e15904bad477c13b2e2d6ef0b96a861ce4a309a328fe44342365349456ad7c654f", + "0x89ae3ce4b0357044579ca17be85d8361bb1ce3941f87e82077dd67e43ec0f95edd4bd3426225c90994a81a99e79490b7", + "0xa170892074016d57c9d8e5a529379d7e08d2c1158b9ac4487ac9b95266c4fd51cb18ae768a2f74840137eec05000dd5a", + "0xaafd8acd1071103c7af8828a7a08076324d41ea530df90f7d98fafb19735fc27ead91b50c2ca45851545b41d589d0f77", + "0x8623c849e61d8f1696dc9752116a26c8503fd36e2cbbc9650feffdd3a083d8cdbb3b2a4e9743a84b9b2ad91ac33083f2", + "0xac7166ddd253bb22cdbd8f15b0933c001d1e8bc295e7c38dc1d2be30220e88e2155ecd2274e79848087c05e137e64d01", + "0xa5276b216d3df3273bbfa46210b63b84cfe1e599e9e5d87c4e2e9d58666ecf1af66cb7ae65caebbe74b6806677215bd0", + "0x88792f4aa3597bb0aebadb70f52ee8e9db0f7a9d74f398908024ddda4431221a7783e060e0a93bf1f6338af3d9b18f68", + "0x8f5fafff3ecb3aad94787d1b358ab7d232ded49b15b3636b585aa54212f97dc1d6d567c180682cca895d9876cacb7833", + "0xab7cb1337290842b33e936162c781aa1093565e1a5b618d1c4d87dd866daea5cebbcc486aaa93d8b8542a27d2f8694c7", + "0x88480a6827699da98642152ebc89941d54b4791fbc66110b7632fb57a5b7d7e79943c19a4b579177c6cf901769563f2f", + "0xa725ee6d201b3a610ede3459660658ee391803f770acc639cfc402d1667721089fb24e7598f00e49e81e50d9fd8c2423", + "0x98924372da8aca0f67c8c5cad30fa5324519b014fae7849001dcd51b6286118f12b6c49061219c37714e11142b4d46de", + "0xa62c27360221b1a7c99697010dfe1fb31ceb17d3291cf2172624ebeff090cbaa3c3b01ec89fe106dace61d934711d42d", + "0x825173c3080be62cfdc50256c3f06fe190bc5f190d0eb827d0af5b99d80936e284a4155b46c0d462ee574fe31d60983d", + "0xa28980b97023f9595fadf404ed4aa36898d404fe611c32fd66b70252f01618896f5f3fda71aea5595591176aabf0c619", + "0xa50f5f9def2114f6424ff298f3b128068438f40860c2b44e9a6666f43c438f1780be73cf3de884846f1ba67f9bef0802", + "0xb1eee2d730da715543aeb87f104aff6122cb2bf11de15d2519ff082671330a746445777924521ec98568635f26988d0c", + "0x862f6994a1ff4adfd9fb021925cccf542fca4d4b0b80fb794f97e1eb2964ef355608a98eec6e07aadd4b45ee625b2a21", + "0x8ce69a18df2f9b9f6e94a456a7d94842c61dea9b00892da7cf5c08144de9be39b8c304aeca8b2e4222f87ba367e61006", + "0xb5f325b1cecd435f5346b6bc562d92f264f1a6d91be41d612df012684fdd69e86063db077bc11ea4e22c5f2a13ae7bee", + "0x85526870a911127835446cb83db8986b12d5637d59e0f139ad6501ac949a397a6c73bd2e7fba731b1bb357efe068242c", + "0x8552247d3f7778697f77389717def5a149fc20f677914048e1ed41553b039b5427badc930491c0bae663e67668038fd1", + "0xa545640ee5e51f3fe5de7050e914cfe216202056cd9d642c90e89a166566f909ee575353cb43a331fde17f1c9021414e", + "0x8b51229b53cff887d4cab573ba32ec52668d197c084414a9ee5589b285481cea0c3604a50ec133105f661321c3ca50f5", + "0x8cdc0b960522bed284d5c88b1532142863d97bbb7dc344a846dc120397570f7bd507ceb15ed97964d6a80eccfef0f28e", + "0xa40683961b0812d9d53906e795e6470addc1f30d09affebf5d4fbbd21ddfa88ce441ca5ea99c33fd121405be3f7a3757", + "0xa527875eb2b99b4185998b5d4cf97dd0d4a937724b6ad170411fc8e2ec80f6cee2050f0dd2e6fee9a2b77252d98b9e64", + "0x84f3a75f477c4bc4574f16ebc21aaa32924c41ced435703c4bf07c9119dd2b6e066e0c276ff902069887793378f779e0", + "0xa3544bc22d1d0cab2d22d44ced8f7484bfe391b36991b87010394bfd5012f75d580596ffd4f42b00886749457bb6334b", + "0xb81f6eb26934b920285acc20ceef0220dd23081ba1b26e22b365d3165ce2fbae733bbc896bd0932f63dcc84f56428c68", + "0x95e94d40a4f41090185a77bf760915a90b6a3e3ace5e53f0cb08386d438d3aa3479f0cd81081b47a9b718698817265cd", + "0xb69bd1625b3d6c17fd1f87ac6e86efa0d0d8abb69f8355a08739109831baeec03fd3cd4c765b5ff8b1e449d33d050504", + "0x8448f4e4c043519d98552c2573b76eebf2483b82d32abb3e2bfc64a538e79e4f59c6ca92adff1e78b2f9d0a91f19e619", + "0x8f11c42d6a221d1fda50887fb68b15acdb46979ab21d909ed529bcad6ae10a66228ff521a54a42aca0dad6547a528233", + "0xa3adb18d7e4a882b13a067784cf80ea96a1d90f5edc61227d1f6e4da560c627688bdf6555d33fe54cab1bca242986871", + "0xa24d333d807a48dc851932ed21cbdd7e255bad2699909234f1706ba55dea4bb6b6f8812ffc0be206755868ba8a4af3f9", + "0xa322de66c22a606e189f7734dbb7fda5d75766d5e69ec04b4e1671d4477f5bcb9ff139ccc18879980ebc3b64ab4a2c49", + "0x88f54b6b410a1edbf125db738d46ee1a507e69bc5a8f2f443eb787b9aa7dbd6e55014ec1e946aabeb3e27a788914fb04", + "0xb32ee6da1dcd8d0a7fd7c1821bb1f1fe919c8922b4c1eeed56e5b068a5a6e68457c42b192cbaef5dc6d49b17fa45bc0f", + "0x8a44402da0b3a15c97b0f15db63e460506cb8bef56c457166aea5e8881087d8202724c539ef0feb97131919a73aefca8", + "0xb967e3fead6171fa1d19fd976535d428b501baff59e118050f9901a54b12cc8e4606348454c8f0fc25bd6644e0a5532e", + "0xb7a0c9e9371c3efbbb2c6783ce2cc5f149135175f25b6d79b09c808bce74139020e77f0c616fa6dcb3d87a378532529d", + "0xa54207782ffc909cd1bb685a3aafabbc4407cda362d7b3c1b14608b6427e1696817aeb4f3f85304ac36e86d3d8caa65b", + "0x98c1da056813a7bfebc81d8db7206e3ef9b51f147d9948c088976755826cc5123c239ca5e3fe59bed18b5d0a982f3c3f", + "0xae1c86174dfafa9c9546b17b8201719aecd359f5bbeb1900475041f2d5b8a9600d54d0000c43dd061cfda390585726ff", + "0xa8ee5a8be0bd1372a35675c87bfd64221c6696dc16e2d5e0996e481fec5cdbcb222df466c24740331d60f0521285f7d3", + "0x8ddadbe3cf13af50d556ce8fc0dd77971ac83fad9985c3d089b1b02d1e3afc330628635a31707b32595626798ea22d45", + "0xa5c80254baf8a1628dc77c2445ebe21fbda0de09dd458f603e6a9851071b2b7438fe74214df293dfa242c715d4375c95", + "0xb9d83227ed2600a55cb74a7052003a317a85ca4bea50aa3e0570f4982b6fe678e464cc5156be1bd5e7bba722f95e92c5", + "0xb56085f9f3a72bea9aa3a8dc143a96dd78513fa327b4b9ba26d475c088116cab13843c2bff80996bf3b43d3e2bddb1d6", + "0x8fa9b39558c69a9757f1e7bc3f07295e4a433da3e6dd8c0282397d26f64c1ecd8eb3ba9824a7cacfb87496ebbb45d962", + "0x879c6d0cb675812ed9dee68c3479a499f088068501e2677caeae035e6f538da91a49e245f5fcce135066169649872bee", + "0x91aa9fd3fed0c2a23d1edda8a6542188aeb8abee8772818769bdee4b512d431e4625a343af5d59767c468779222cf234", + "0xa6be0bb2348c35c4143482c7ef6da9a93a5356f8545e8e9d791d6c08ed55f14d790d21ee61d3a56a2ae7f888a8fd46ca", + "0x808ee396a94e1b8755f2b13a6ffbedef9e0369e6c2e53627c9f60130c137299d0e4924d8ef367e0a7fad7f68a8c9193c", + "0xad1086028fcdac94d5f1e7629071e7e47e30ad0190ae59aaebfb7a7ef6202ab91323a503c527e3226a23d7937af41a52", + "0x9102bdaf79b907d1b25b2ec6b497e2d301c8eac305e848c6276b392f0ad734131a39cc02ed42989a53ca8da3d6839172", + "0x8c976c48a45b6bc7cd7a7acea3c2d7c5f43042863b0661d5cd8763e8b50730552187a8eecf6b3d17be89110208808e77", + "0xa2624c7e917e8297faa3af89b701953006bf02b7c95dfba00c9f3de77748bc0b13d6e15bb8d01377f4d98fb189538142", + "0xa405f1e66783cdcfe20081bce34623ec3660950222d50b7255f8b3cc5d4369aeb366e265e5224c0204911539f0fa165e", + "0x8d69bdcaa5d883b5636ac8f8842026fcc58c5e2b71b7349844a3f5d6fbecf44443ef4f768eac376f57fb763606e92c9f", + "0x82fce0643017d16ec1c3543db95fb57bfa4855cc325f186d109539fcacf8ea15539be7c4855594d4f6dc628f5ad8a7b0", + "0x8860e6ff58b3e8f9ae294ff2487f0d3ffae4cf54fd3e69931662dabc8efd5b237b26b3def3bcd4042869d5087d22afcf", + "0x88c80c442251e11c558771f0484f56dc0ed1b7340757893a49acbf96006aa73dfc3668208abea6f65375611278afb02a", + "0x8be3d18c6b4aa8e56fcd74a2aacb76f80b518a360814f71edb9ccf3d144bfd247c03f77500f728a62fca7a2e45e504c5", + "0x8b8ebf0df95c3f9b1c9b80469dc0d323784fd4a53f5c5357bb3f250a135f4619498af5700fe54ad08744576588b3dfff", + "0xa8d88abdaadd9c2a66bc8db3072032f63ed8f928d64fdb5f810a65074efc7e830d56e0e738175579f6660738b92d0c65", + "0xa0a10b5d1a525eb846b36357983c6b816b8c387d3890af62efb20f50b1cb6dd69549bbef14dab939f1213118a1ae8ec2", + "0x8aadf9b895aeb8fdc9987daa937e25d6964cbd5ec5d176f5cdf2f0c73f6f145f0f9759e7560ab740bf623a3279736c37", + "0x99aeda8a495031cc5bdf9b842a4d7647c55004576a0edc0bd9b985d60182608361ed5459a9d4b21aa8e2bd353d10a086", + "0x832c8b3bfcd6e68eee4b100d58014522de9d4cefa99498bc06c6dca83741e4572e20778e0d846884b33439f160932bca", + "0x841f56ebefc0823ab484fc445d62f914e13957e47904419e42771aa605e33ab16c44f781f6f9aa42e3a1baf377f54b42", + "0xa6e40271d419e295a182725d3a9b541ffd343f23e37549c51ecaa20d13cf0c8d282d6d15b24def5702bfee8ba10b12ac", + "0x8ac00925ac6187a4c5cde48ea2a4eaf99a607e58b2c617ee6f01df30d03fafada2f0469178dd960d9d64cbd33a0087d8", + "0xb6b80916b540f8a0fe4f23b1a06e2b830008ad138271d5ba3cd16d6619e521fe2a7623c16c41cba48950793386eea942", + "0x8412c0857b96a650e73af9d93087d4109dd092ddf82188e514f18fcac644f44d4d62550bfa63947f2d574a2e9d995bbb", + "0xb871395baa28b857e992a28ac7f6d95ec461934b120a688a387e78498eb26a15913b0228488c3e2360391c6b7260b504", + "0x926e2d25c58c679be77d0e27ec3b580645956ba6f13adcbc2ea548ee1b7925c61fcf74c582337a3b999e5427b3f752f2", + "0xa165fa43fecae9b913d5dcfc232568e3e7b8b320ce96b13800035d52844c38fd5dbf7c4d564241d860c023049de4bcbc", + "0xb4976d7572fd9cc0ee3f24888634433f725230a7a2159405946a79315bc19e2fc371448c1c9d52bf91539fd1fe39574b", + "0xa6b461eb72e07a9e859b9e16dfa5907f4ac92a5a7ca4368b518e4a508dc43f9b4be59db6849739f3ef4c44967b63b103", + "0xb976606d3089345d0bc501a43525d9dca59cf0b25b50dfc8a61c5bd30fac2467331f0638fab2dc68838aa6ee8d2b6bc9", + "0xb16ea61c855da96e180abf7647fa4d9dd6fd90adebadb4c5ed4d7cd24737e500212628fca69615d89cb40e9826e5a214", + "0x95a3e3162eb5ea27a613f8c188f2e0dcc5cbd5b68c239858b989b004d87113e6aa3209fa9fad0ee6ecef42814ba9db1a", + "0xb6a026ab56d3224220e5bce8275d023c8d39d1bdf7eec3b0923429b7d5ef18cf613a3591d364be8727bb1fa0ba11eabb", + "0x949f117e2e141e25972ee9ccdd0b7a21150de7bbf92bbd89624a0c5f5a88da7b2b172ba2e9e94e1768081f260c2a2f8d", + "0xb7c5e9e6630287d2a20a2dfb783ffe6a6ff104ff627c6e4e4342acc2f3eb6e60e9c22f465f8a8dc58c42f49840eca435", + "0x872be5a75c3b85de21447bb06ac9eb610f3a80759f516a2f99304930ddf921f34cbffc7727989cdd7181d5fc62483954", + "0xa50976ea5297d797d220932856afdd214d1248230c9dcd840469ecc28ea9f305b6d7b38339fedb0c00b5251d77af8c95", + "0x80b360f8b44914ff6f0ffbd8b5360e3cabe08639f6fe06d0c1526b1fe9fe9f18c497f1752580b30e950abd3e538ad416", + "0xa2f98f9bf7fac78c9da6bb41de267742a9d31cf5a04b2fb74f551084ec329b376f651a59e1ae919b2928286fb566e495", + "0x8b9d218a8a6c150631548e7f24bbd43f132431ae275c2b72676abbea752f554789c5ff4aac5c0eeee5529af7f2b509ef", + "0xaa21a243b07e9c7b169598bf0b102c3c280861780f83121b2ef543b780d47aaa4b1850430ee7927f33ece9847c4e0e1a", + "0x8a6f90f4ce58c8aa5d3656fe4e05acccf07a6ec188a5f3cde7bf59a8ae468e66f055ac6dfc50b6e8e98f2490d8deedc5", + "0x8e39f77ca4b5149ffe9945ceac35d068760ba338d469d57c14f626dd8c96dbe993dd7011beff727c32117298c95ee854", + "0x83bd641c76504222880183edd42267e0582642c4993fe2c7a20ce7168e4c3cbf7586e1d2d4b08c84d9b0bf2f6b8800b8", + "0xa9d332993cf0c1c55130e5cf3a478eb5e0bfb49c25c07538accc692ef03d82b458750a7b991cc0b41b813d361a5d31e3", + "0xa0fc60e6a6015df9bee04cea8f20f01d02b14b6f7aa03123ab8d65da071b2d0df5012c2a69e7290baae6ed6dd29ebe07", + "0xa2949dde2e48788ceaac7ec7243f287ffe7c3e788cdba97a4ab0772202aeef2d50382bed8bf7eff5478243f7eabe0bda", + "0xa7879373ea18572dba6cf29868ca955ffa55b8af627f29862f6487ee398b81fe3771d8721ca8e06716c5d91b9ac587cb", + "0xb3c7081e2c5306303524fbe9fe5645111a57dffd4ec25b7384da12e56376a0150ab52f9d9cc6ca7bdd950695e39b766d", + "0xa634a6a19d52dcb9f823352b36c345d2de54b75197bcd90528d27830bd6606d1a9971170de0849ed5010afa9f031d5be", + "0x88f2062f405fa181cfdb8475eaf52906587382c666ca09a9522537cfebbc7de8337be12a7fd0db6d6f2f7ab5aefab892", + "0xb1f0058c1f273191247b98783b2a6f5aa716cf799a8370627fc3456683f03a624d0523b63a154fe9243c0dfd5b37c460", + "0xae39a227cc05852437d87be6a446782c3d7fbe6282e25cf57b6b6e12b189bdc0d4a6e2c3a60b3979256b6b5baf8f1c5f", + "0x802a1af228ab0c053b940e695e7ef3338f5be7acf4e5ed01ac8498e55b492d3a9f07996b1700a84e22f0b589638909cd", + "0xa36490832f20e4b2f9e79ee358b66d413f034d6a387534b264cdeac2bca96e8b5bcbdd28d1e98c44498032a8e63d94d2", + "0x8728c9a87db2d006855cb304bba54c3c704bf8f1228ae53a8da66ca93b2dac7e980a2a74f402f22b9bc40cd726e9c438", + "0xa08f08ab0c0a1340e53b3592635e256d0025c4700559939aeb9010ed63f7047c8021b4210088f3605f5c14fb51d1c613", + "0x9670fd7e2d90f241e8e05f9f0b475aa260a5fb99aa1c9e61cd023cbad8ed1270ae912f168e1170e62a0f6d319cf45f49", + "0xa35e60f2dd04f098bf274d2999c3447730fe3e54a8aff703bc5a3c274d22f97db4104d61a37417d93d52276b27ef8f31", + "0x859df7a21bc35daec5695201bd69333dc4f0f9e4328f2b75a223e6615b22b29d63b44d338413ca97eb74f15563628cb7", + "0xb2b44ad3e93bc076548acdf2477803203108b89ecc1d0a19c3fb9814d6b342afc420c20f75e9c2188ad75fdb0d34bb2d", + "0x941173ee2c87765d10758746d103b667b1227301e1bcfecef2f38f9ab612496a9abd3050cef5537bf28cfecd2aacc449", + "0x92b0bea30ebed20ac30648efb37bac2b865daaa514316e6f5470e1de6cb84651ff77c127aa7beed4521bda5e8fc81122", + "0xaf17bf813bb238cf8bb437433f816786612209180a6c0a1d5141292dc2d2c37164ef13bfc50c718bfcc6ce26369298a2", + "0x8461fd951bdfda099318e05cc6f75698784b033f15a71bce26165f0ce421fd632d50df9eeced474838c0050b596e672c", + "0x83281aa18ae4b01e8201e1f64248cc6444c92ee846ae72adb178cef356531558597d84ff93a05abf76bfe313eb7dbe86", + "0xb62b150f73999c341daa4d2f7328d2f6ca1ef3b549e01df58182e42927537fc7971c360fe8264af724f4c0247850ef12", + "0xa7022a201f79c012f982b574c714d813064838a04f56964d1186691413757befeeaada063e7884297606e0eea1b1ed43", + "0xa42ac9e8be88e143853fd8e6a9ff21a0461801f0ac76b69cca669597f9af17ecb62cccdcdcbe7f19b62ab93d7f838406", + "0x80f1ca73b6ba3a2fbae6b79b39c0be8c39df81862d46c4990c87cbf45b87996db7859d833abc20af2fcb4faf059c436a", + "0xb355943e04132d5521d7bbe49aea26f6aa1c32f5d0853e77cc2400595325e923a82e0ff7601d1aee79f45fd8a254f6ae", + "0x87142c891d93e539b31d0b5ead9ea600b9c84db9be9369ff150a8312fe3d10513f4c5b4d483a82b42bc65c45dd9dd3bd", + "0x823c3d7f6dda98a9d8c42b3fee28d3154a95451402accadb6cf75fc45d2653c46a569be75a433094fa9e09c0d5cf1c90", + "0xb3c3497fe7356525c1336435976e79ec59c5624c2fb6185ee09ca0510d58b1e392965e25df8a74d90d464c4e8bb1422b", + "0x88c48d83e8ddc0d7eea051f3d0e21bc0d3a0bb2b6a39ece76750c1c90c382a538c9a35dc9478b8ceb8157dcccbbf187a", + "0x93da81a8939f5f58b668fefdc6f5f7eca6dc1133054de4910b651f8b4a3267af1e44d5a1c9e5964dc7ab741eb146894b", + "0x8b396e64985451ac337f16be61105106e262e381ea04660add0b032409b986e1ac64da3bc2feae788e24e9cb431d8668", + "0x9472068b6e331ea67e9b5fbf8057672da93c209d7ded51e2914dbb98dccd8c72b7079b51fd97a7190f8fc8712c431538", + "0xac47e1446cb92b0a7406f45c708567f520900dfa0070d5e91783139d1bfc946d6e242e2c7b3bf4020500b9f867139709", + "0x896053706869fb26bb6f7933b3d9c7dd6db5c6bd1269c7a0e222b73039e2327d44bda7d7ae82bf5988808b9831d78bcd", + "0xa55e397fa7a02321a9fe686654c86083ecedb5757586d7c0250ec813ca6d37151a12061d5feca4691a0fd59d2f0fdd81", + "0xae23f08ac2b370d845036518f1bddb7fea8dc59371c288a6af310486effeb61963f2eef031ca90f9bdbcf0e475b67068", + "0xb5462921597a79f66c0fec8d4c7cfd89f427692a7ce30d787e6fd6acd2377f238ec74689a0fdbe8ef3c9c9bd24b908dc", + "0xae67e8ea7c46e29e6aae6005131c29472768326819aa294aaf5a280d877de377b44959adb1348fa3e929dcbc3ae1f2c0", + "0x84962b4c66500a20c4424191bdfb619a46cda35bdb34c2d61edcb0b0494f7f61dd5bf8f743302842026b7b7d49edd4b5", + "0x846f76286dc3cc59cb15e5dabb72a54a27c78190631df832d3649b2952fa0408ecde7d4dfdae7046c728efa29879fb51", + "0x8f76c854eaee8b699547e07ad286f7dadfa6974c1328d12502bd7630ae619f6129272fdd15e2137ffef0143c42730977", + "0x8007b163d4ea4ec6d79e7a2aa19d06f388da0b3a56f3ee121441584e22a246c0e792431655632bf6e5e02cb86914eebf", + "0xac4d2cecc1f33e6fb73892980b61e62095ddff5fd6167f53ca93d507328b3c05440729a277dc3649302045b734398af1", + "0x92d2a88f2e9c9875abaff0d42624ccb6d65401de7127b5d42c25e6adccd7a664504c5861618f9031ced8aeb08b779f06", + "0xa832c1821c1b220eb003fc532af02c81196e98df058cdcc9c9748832558362915ea77526937f30a2f74f25073cb89afb", + "0xb6f947ab4cc2baec100ed8ec7739a2fd2f9504c982b39ab84a4516015ca56aea8eef5545cfc057dd44c69b42125fb718", + "0xb24afacf2e90da067e5c050d2a63878ee17aaf8fd446536f2462da4f162de87b7544e92c410d35bf2172465940c19349", + "0xb7a0aa92deac71eaab07be8fa43086e071e5580f5dbf9b624427bdd7764605d27303ae86e5165bed30229c0c11958c38", + "0xb0d1d5bfa1823392c5cf6ed927c1b9e84a09a24b284c2cd8fcb5fda8e392c7c59412d8f74eb7c48c6851dff23ae66f58", + "0xa24125ef03a92d2279fb384186ca0274373509cfec90b34a575490486098438932ee1be0334262d22d5f7d3db91efe67", + "0x83e08e5fba9e8e11c164373794f4067b9b472d54f57f4dbe3c241cf7b5b7374102de9d458018a8c51ab3aed1dddf146f", + "0x9453101b77bb915ed40990e1e1d2c08ea8ec5deb5b571b0c50d45d1c55c2e2512ec0ceca616ff0376a65678a961d344d", + "0x92a0516e9eb6ad233d6b165a8d64a062ce189b25f95d1b3264d6b58da9c8d17da2cd1f534800c43efcf2be73556cd2ff", + "0x958d0b5d7d8faf25d2816aa6a2c5770592ad448db778dd9b374085baa66c755b129822632eaabcb65ee35f0bf4b73634", + "0x90a749de8728b301ad2a6b044e8c5fd646ccd8d20220e125cba97667e0bb1d0a62f6e3143b28f3d93f69cdc6aa04122a", + "0x84bd34c8d8f74dec07595812058db24d62133c11afed5eb2a8320d3bfc28e442c7f0cfd51011b7b0bb3e5409cb7b6290", + "0xaecc250b556115d97b553ad7b2153f1d69e543e087890000eaa60f4368b736921d0342ce5563124f129096f5d5e2ca9d", + "0x977f17ac82ed1fbf422f9b95feb3047a182a27b00960296d804fd74d54bb39ad2c055e665c1240d2ad2e06a3d7501b00", + "0xaf5be9846bd4879ebe0af5e7ad253a632f05aedfe306d31fe6debe701ba5aa4e33b65efc05043bc73aadb199f94baed4", + "0x9199e12ec5f2aaaeed6db5561d2dcc1a8fe9c0854f1a069cba090d2dff5e5ba52b10c841ccbd49006a91d881f206150d", + "0x8f4a96a96ed8ceaf3beba026c89848c9ca4e6452ce23b7cf34d12f9cc532984a498e051de77745bdc17c7c44c31b7c30", + "0xaf3f2a3dbe8652c4bfca0d37fb723f0e66aab4f91b91a625114af1377ad923da8d36da83f75deb7a3219cd63135a3118", + "0xa6d46963195df8962f7aa791d104c709c38caa438ddd192f7647a884282e81f748c94cdf0bb25d38a7b0dc1b1d7bbcf7", + "0x86f3de4b22c42d3e4b24b16e6e8033e60120af341781ab70ae390cb7b5c5216f6e7945313c2e04261a51814a8cb5db92", + "0xb9f86792e3922896cfd847d8ff123ff8d69ecf34968fb3de3f54532f6cd1112b5d34eeabdca46ae64ad9f6e7e5b55edc", + "0x83edfbcbc4968381d1e91ab813b3c74ab940eaf6358c226f79182f8b21148ec130685fd91b0ea65916b0a50bccf524ea", + "0x93b61daca7a8880b7926398760f50016f2558b0bab74c21181280a1baf3414fc539911bb0b79c4288d29d3c4ad0f4417", + "0xad541aeb83a47526d38f2e47a5ce7e23a9adabe5efeae03541026881e6d5ef07da3ac1a6ed466ca924fa8e7a91fcff88", + "0xac4bba31723875025640ed6426003ed8529215a44c9ffd44f37e928feef9fc4dfa889088131c9be3da87e8f3fdf55975", + "0x88fa4d49096586bc9d29592909c38ea3def24629feacd378cc5335b70d13814d6dac415f8c699ee1bf4fe8b85eb89b38", + "0xb67d0b76cbd0d79b71f4673b96e77b6cda516b8faa1510cfe58ff38cc19000bb5d73ff8418b3dab8c1c7960cb9c81e36", + "0x98b4f8766810f0cfecf67bd59f8c58989eb66c07d3dfeee4f4bbce8fd1fce7cc4f69468372eaec7d690748543bd9691d", + "0x8445891af3c298b588dec443beacdf41536adb84c812c413a2b843fd398e484eb379075c64066b460839b5fe8f80177c", + "0xb603635c3ed6fdc013e2a091fc5164e09acf5f6a00347d87c6ebadb1f44e52ff1a5f0466b91f3f7ffc47d25753e44b75", + "0x87ec2fc928174599a9dafe7538fec7dcf72e6873b17d953ed50708afff0da37653758b52b7cafa0bf50dfcf1eafbb46c", + "0xb9dbd0e704d047a457d60efe6822dc679e79846e4cbcb11fa6c02079d65673ee19bbf0d14e8b7b200b9205f4738df7c7", + "0x9591ec7080f3f5ba11197a41f476f9ba17880f414d74f821a072ec5061eab040a2acba3d9856ff8555dfe5eaeb14ca19", + "0xb34c9d1805b5f1ce38a42b800dec4e7f3eb8c38e7d2b0a525378e048426fed150dbfe9cc61f5db82b406d1b9ff2d10bf", + "0xa36fdc649dc08f059dfa361e3969d96b4cc4a1ebf10b0cd01a7dd708430979e8d870961fef85878f8779b8e23caafb18", + "0x88dfc739a80c16c95d9d6f73c3357a92d82fa8c3c670c72bee0f1e4bac9ec338e1751eb786eda3e10f747dd7a686900f", + "0x84a535ad04f0961756c61c70001903a9adf13126983c11709430a18133c4b4040d17a33765b4a06968f5d536f4bfb5c5", + "0x8c86d695052a2d2571c5ace744f2239840ef21bb88e742f050c7fa737cd925418ecef0971333eb89daa6b3ddfede268c", + "0x8e9a700157069dc91e08ddcbdde3a9ad570272ad225844238f1015004239c542fceb0acce6d116c292a55f0d55b6175e", + "0x84d659e7f94e4c1d15526f47bc5877a4ef761c2a5f76ec8b09c3a9a30992d41b0e2e38ed0c0106a6b6c86d670c4235f3", + "0xa99253d45d7863db1d27c0ab561fb85da8c025ba578b4b165528d0f20c511a9ca9aff722f4ff7004843f618eb8fced95", + "0x89a3cacb15b84b20e95cd6135550146bbe6c47632cc6d6e14d825a0c79b1e02b66f05d57d1260cb947dc4ae5b0283882", + "0x8385b1555e794801226c44bd5e878cbe68aeac0a19315625a8e5ea0c3526b58cdd4f53f9a14a167a5e8a293b530d615a", + "0xb68c729e9df66c5cd22af4909fb3b0057b6a231c4a31cd6bf0fa0e53c5809419d15feb483de6e9408b052458e819b097", + "0x924f56eda269ec7ec2fc20c5731bf7f521546ddf573ccbe145592f1c9fee5134747eb648d9335119a8066ca50a1f7e50", + "0xb2100a26b9c3bec7ec5a53f0febbf56303f199be2f26b2d564cfee2adc65483b84192354f2865c2f4c035fa16252ae55", + "0x8f64dbed62e638563967ec1605a83216aed17eb99aa618c0543d74771ea8f60bbb850c88608d4f8584f922e30a8a0a72", + "0xb31b9e1ffe8d7260479c9413f8e680f3fe391ae8fcf44fcca3000d9b2473a40c1d32299f8f63865a57579a2d6c7e9f08", + "0xa5b1d136142eb23e322c6c07cb838a3f58ab6925472352ebd0bb47041a0d8729e1074ca223922f3a7a672ced7a1e562d", + "0x8d9470a5a15d833a447b5f108333d50f30aa7659e331c3f8080b1e928a99922edc650466a2f54f3d48afdb34bff42142", + "0x866368f5891564e5b2de37ad21ff0345c01129a14ea5667f9b64aad12d13ec034622872e414743af0bf20adb2041b497", + "0x88ef9c2ebf25fd0c04b7cfa35fbac2e4156d2f1043fa9f98998b2aa402c8f9a4f1039e782451a46840f3e0e4b3fa47d3", + "0x94ba04a4859273697e264a2d238dc5c9ff573ebc91e4796ea58eebe4080c1bf991255ab2ad8fb1e0301ce7b79cc6e69b", + "0x86b6bd0953309a086e526211bf1a99327269304aa74d8cdc994cee63c3a2d4b883e832b0635888dff2a13f1b02eb8df4", + "0x843ea6ea5f2c7a1fd50be56a5765dcce3ea61c99b77c1a729ee0cd8ec706385ac7062e603479d4c8d3527f030762d049", + "0x8d3675195a3b06f2d935d45becc59f9fa8fa440c8df80c029775e47fe9c90e20f7c8e4cc9a2542dd6bfe87536c428f0d", + "0x8978580b0c9b0aa3ab2d47e3cfd92fa891d3ddee57829ee4f9780e8e651900457d8e759d1a9b3e8f6ae366e4b57f2865", + "0x890112ec81d0f24b0dfbb4d228e418eff02ae63dc691caf59c1d103e1d194e6e2550e1bec41c0bfdb74fed454f621d0c", + "0x97da00bd4b19d1e88caff7f95b8b9a7d29bc0afe85d0c6a163b4b9ef336f0e90e2c49ce6777024bb08df908cc04ea1ca", + "0xb458268d275a5211106ccaa8333ce796ef2939b1c4517e502b6462e1f904b41184a89c3954e7c4f933d68b87427a7bfd", + "0xaac9c043ba8ba9283e8428044e6459f982413380ee7005a996dc3cc468f6a21001ecaa3b845ce2e73644c2e721940033", + "0x82145013c2155a1200246a1e8720adf8a1d1436b10d0854369d5b1b6208353e484dd16ce59280c6be84a223f2d45e5e2", + "0xb301bafa041f9b203a46beab5f16160d463aa92117c77a3dc6a9261a35645991b9bafcc186c8891ca95021bd35f7f971", + "0xa531b8d2ac3de09b92080a8d8857efa48fb6a048595279110e5104fee7db1dd7f3cfb8a9c45c0ed981cbad101082e335", + "0xa22ac1d627d08a32a8abd41504b5222047c87d558ffae4232cefdeb6a3dc2a8671a4d8ddfba2ff9068a9a3ffb0fe99b1", + "0xb8d9f0e383c35afb6d69be7ff04f31e25c74dd5751f0e51290c18814fbb49ee1486649e64355c80e93a3d9278bd21229", + "0x8165babccd13033a3614c878be749dfa1087ecbeee8e95abcfffe3aa06695711122cb94477a4d55cffd2febf0c1173de", + "0xa4c1bc84ecb9d995d1d21c2804adf25621676d60334bd359dac3a2ec5dc8de567aa2831c10147034025fb3e3afb33c4b", + "0xb77307cab8e7cb21e4038493058fb6db9e2ec91dda9d7f96f25acbc90309daf7b6d8a205682143ee35d675e9800c3b08", + "0xaaf7466083cd1f325ba860efe3faf4cebe6a5eecf52c3e8375d72043a5cfc8e6cb4b40f8e48f97266e84f0d488e8badf", + "0x9264a05a3abc2a5b4958f957f3a486a5eb3ddd10ff57aa6943c9430d0cfa01d63b72695b1ade50ac1b302d312175e702", + "0xb3f9e4c589ad28b1eceed99dc9980fac832524cfcbe4a486dfeedb4b97c080e24bdb3967e9ca63d2240e77f9addfaefd", + "0xb2c1e253a78e7179e5d67204422e0debfa09c231970b1bfb70f31a8d77c7f5059a095ca79d2e9830f12c4a8f88881516", + "0x81865a8a25913d1072cb5fd9505c73e0fde45e4c781ddd20fb0a7560d8b1cd5e1f63881c6efc05360e9204dfa6c3ce16", + "0xab71c2ea7fa7853469a2236dedb344a19a6130dc96d5fd6d87d42d3fffda172557d203b7688ce0f86acd913ce362e6cd", + "0x8aa2051bc3926c7bd63565f3782e6f77da824cb3b22bb056aa1c5bccfa274c0d9e49a91df62d0e88876e2bd7776e44b9", + "0xb94e7074167745323d1d353efe7cfb71f40a390e0232354d5dfd041ef523ac8f118fb6dcc42bf16c796e3f61258f36f8", + "0x8210fcf01267300cb1ccf650679cf6e1ee46df24ae4be5364c5ff715332746c113d680c9a8be3f17cacaeb3a7ba226ce", + "0x905ac223568eedc5acd8b54e892be05a21abbb4083c5dbec919129f9d9ffa2c4661d78d43bf5656d8d7aafa06f89d647", + "0xa6e93da7e0c998e6ce2592d1aa87d12bf44e71bec12b825139d56682cdce8f0ba6dbfe9441a9989e10578479351a3d9d", + "0xacde928a5e2df0d65de595288f2b81838155d5673013100a49b0cb0eb3d633237af1378148539e33ccd1b9a897f0fec3", + "0xa6e1a47e77f0114be6ae7acd2a51e6a9e38415cce7726373988153cdd5d4f86ef58f3309adc5681af4a159300ed4e5b5", + "0xad2b6a0d72f454054cb0c2ebc42cd59ff2da7990526bd4c9886003ba63b1302a8343628b8fe3295d3a15aa85150e0969", + "0xb0bc3aea89428d7918c2ee0cc57f159fba134dad224d0e72d21a359ca75b08fbb4373542f57a6408352033e1769f72c6", + "0xaad0497525163b572f135fad23fdd8763631f11deeaf61dea5c423f784fe1449c866040f303555920dc25e39cdb2e9b4", + "0x8ce5d8310d2e17342bf881d517c9afc484d12e1f4b4b08ad026b023d98cba410cd9a7cc8e2c3c63456652a19278b6960", + "0x8d9d57dbb24d68b6152337872bd5d422198da773174ade94b633f7c7f27670ff91969579583532ae7d8fe662c6d8a3b0", + "0x855a1c2d83becb3f02a8f9a83519d1cb112102b61d4cdd396844b5206e606b3fefdbcc5aa8751da2b256d987d74d9506", + "0x90eb7e6f938651f733cf81fcd2e7e8f611b627f8d94d4ac17ac00de6c2b841e4f80cada07f4063a13ae87b4a7736ca28", + "0x8161459a21d55e7f5f1cecfc1595c7f468406a82080bfa46d7fb1af4b5ec0cd2064c2c851949483db2aa376e9df418e6", + "0x8344ccd322b2072479f8db2ab3e46df89f536408cba0596f1e4ec6c1957ff0c73f3840990f9028ae0f21c1e9a729d7df", + "0x929be2190ddd54a5afe98c3b77591d1eae0ab2c9816dc6fe47508d9863d58f1ea029d503938c8d9e387c5e80047d6f1e", + "0x856e3d1f701688c650c258fecd78139ce68e19de5198cf1cd7bb11eba9d0f1c5af958884f58df10e3f9a08d8843f3406", + "0x8490ae5221e27a45a37ca97d99a19a8867bcc026a94f08bdccfbb4b6fa09b83c96b37ec7e0fd6ee05f4ae6141b6b64a8", + "0xb02dbd4d647a05ac248fda13708bba0d6a9cd00cae5634c1938b4c0abbb3a1e4f00f47aa416dcd00ffcdf166330bff9a", + "0x9076164bb99ca7b1a98d1e11cb2f965f5c22866658e8259445589b80e3cb3119c8710ede18f396ba902696785619079c", + "0xaacf016920936dae63778ad171386f996f65fe98e83cfcdd75e23774f189303e65cc8ad334a7a62f9230ed2c6b7f6fa4", + "0xa8031d46c7f2474789123469ef42e81c9c35eb245d38d8f4796bba406c02b57053f5ec554d45373ab437869a0b1af3f0", + "0xa4b76cd82dc1f305a0ee053e9a4212b67f5acc5e69962a8640d190a176b73fbc2b0644f896ff3927cd708d524668ed09", + "0xb00b029c74e6fdf7fb94df95ef1ccad025c452c19cddb5dccfb91efdcb8a9a1c17847cfa4486eae4f510e8a6c1f0791a", + "0x9455e5235f29a73e9f1a707a97ddb104c55b9d6a92cc9952600d49f0447d38ea073ee5cf0d13f7f55f12b4a5132f4b10", + "0xae118847542ed1084d269e8f3b503d0b6571a2c077def116ad685dcca2fca3dcb3f86e3f244284bdcd5ae7ac968d08a5", + "0x8dcb4965cd57e8b89cd71d6fc700d66caa805bfd29ab71357961527a7894e082d49145c2614b670dcb231ab9050d0663", + "0xadd6ed14f3183f4acc73feea19b22c9a330e431c674e5034924da31b69e8c02d79b570d12ef771a04215c4809e0f8a80", + "0x96ae7e110412ee87d0478fdbdbaab290eb0b6edd741bb864961845e87fd44bcbe630371060b8104d8bf17c41f2e3fca0", + "0xa20db17f384e9573ca0928af61affab6ff9dd244296b69b026d737f0c6cd28568846eca8dadf903ee0eecbb47368351d", + "0x937bfdf5feb0797863bc7c1be4dcc4f2423787952a3c77dfa3bfe7356f5dbcc4daebde976b84fc6bd97d5124fb8f85c9", + "0xa7050cc780445c124e46bba1acc0347ddcfa09a85b35a52cc5808bf412c859c0c680c0a82218f15a6daeefe73f0d0309", + "0xa9d9b93450e7630f1c018ea4e6a5ca4c19baa4b662eadfbe5c798fe798d8a3775ed1eb12bd96a458806b37ab82bdc10a", + "0xa52a4d5639e718380915daaefad7de60764d2d795443a3db7aeab5e16a1b8faa9441a4ccc6e809d8f78b0ac13eef3409", + "0x8e6f72b6664a8433b032849b03af68f9376b3c16c0bc86842c43fc7bf31e40bc9fc105952d5c5780c4afa19d7b802caa", + "0xa107ae72f037000c6ee14093de8e9f2c92aa5f89a0a20007f4126419e5cb982469c32187e51a820f94805c9fccd51365", + "0x9708218f9a984fe03abc4e699a4f3378a06530414a2e95e12ca657f031ef2e839c23fd83f96a4ba72f8203d54a1a1e82", + "0xb9129770f4c5fcac999e98c171d67e148abd145e0bf2a36848eb18783bb98dff2c5cef8b7407f2af188de1fae9571b1c", + "0x88cc9db8ff27eb583871eeeb517db83039b85404d735517c0c850bdfa99ae1b57fd24cf661ab60b4726878c17e047f37", + "0xa358c9aadc705a11722df49f90b17a2a6ba057b2e652246dc6131aaf23af66c1ca4ac0d5f11073a304f1a1b006bc0aa5", + "0xac79f25af6364a013ba9b82175ccee143309832df8f9c3f62c193660253679284624e38196733fb2af733488ab1a556e", + "0x82338e3ed162274d41a1783f44ae53329610134e6c62565353fbcc81131e88ce9f8a729d01e59e6d73695a378315111b", + "0xaa5ddcabf580fd43b6b0c3c8be45ffd26c9de8fa8d4546bb92d34f05469642b92a237d0806a1ad354f3046a4fcf14a92", + "0xb308d2c292052a8e17862c52710140ffafa0b3dbedd6a1b6334934b059fe03e49883529d6baf8b361c6e67b3fbf70100", + "0x96d870a15c833dddd8545b695139733d4a4c07d6206771a1524500c12607048731c49ec4ac26f5acc92dd9b974b2172c", + "0x8e99ee9ed51956d05faaf5038bffd48a2957917a76d9974a78df6c1ff3c5423c5d346778f55de07098b578ad623a390e", + "0xa19052d0b4b89b26172c292bbf6fd73e7486e7fd3a63c7a501bbd5cf7244e8e8ce3c1113624086b7cdf1a7693fdad8b5", + "0x958957caf99dc4bb6d3c0bc4821be10e3a816bd0ba18094603b56d9d2d1383ccc3ee8bc36d2d0aea90c8a119d4457eb4", + "0x8482589af6c3fc4aa0a07db201d8c0d750dd21ae5446ff7a2f44decf5bff50965fd6338745d179c67ea54095ecd3add4", + "0x8a088cc12cf618761eaa93da12c9158b050c86f10cd9f865b451c69e076c7e5b5a023e2f91c2e1eed2b40746ca06a643", + "0x85e81101590597d7671f606bd1d7d6220c80d3c62e9f20423e734482c94547714a6ac0307e86847cce91de46503c6a8a", + "0xb1bd39b481fc452d9abf0fcb73b48c501aaae1414c1c073499e079f719c4e034da1118da4ff5e0ce1c5a71d8af3f4279", + "0x942ae5f64ac7a5353e1deb2213f68aa39daa16bff63eb5c69fc8d9260e59178c0452227b982005f720a3c858542246c8", + "0x99fea18230e39df925f98e26ff03ab959cae7044d773de84647d105dfa75fd602b4f519c8e9d9f226ec0e0de0140e168", + "0x97b9841af4efd2bfd56b9e7cd2275bc1b4ff5606728f1f2b6e24630dbe44bc96f4f2132f7103bca6c37057fc792aeaab", + "0x94cdad044a6ab29e646ed30022c6f9a30d259f38043afcea0feceef0edc5f45297770a30718cbfec5ae7d6137f55fe08", + "0xa533a5efa74e67e429b736bb60f2ccab74d3919214351fe01f40a191e3ec321c61f54dd236f2d606c623ad556d9a8b63", + "0xb7bd0bb72cd537660e081f420545f50a6751bb4dd25fde25e8218cab2885dd81ffe3b888d608a396dfcb78d75ba03f3f", + "0xb1479e7aa34594ec8a45a97611d377206597149ece991a8cef1399738e99c3fa124a40396a356ab2ea135550a9f6a89f", + "0xb75570fc94b491aef11f70ef82aeb00b351c17d216770f9f3bd87f3b5ac90893d70f319b8e0d2450dc8e21b57e26df94", + "0xa5e3f3ab112530fe5c3b41167f7db5708e65479b765b941ce137d647adb4f03781f7821bb4de80c5dc282c6d2680a13d", + "0xb9b9c81b4cac7aca7e7c7baac2369d763dd9846c9821536d7467b1a7ec2e2a87b22637ab8bbeddb61879a64d111aa345", + "0xb1e3ee2c4dd03a60b2991d116c372de18f18fe279f712829b61c904103a2bd66202083925bc816d07884982e52a03212", + "0xa13f0593791dbbd360b4f34af42d5cc275816a8db4b82503fe7c2ff6acc22ae4bd9581a1c8c236f682d5c4c02cc274cc", + "0x86ba8238d3ed490abcc3f9ecc541305876315fb71bca8aaf87538012daab019992753bf1e10f8670e33bff0d36db0bf0", + "0xb65fbb89fafb0e2a66fe547a60246d00b98fe2cb65db4922d9cef6668de7b2f4bb6c25970f1e112df06b4d1d953d3f34", + "0xabb2d413e6f9e3c5f582e6020f879104473a829380b96a28123eb2bdd41a7a195f769b6ac70b35ba52a9fee9d6a289c3", + "0x88ec764573e501c9d69098a11ea1ad20cdc171362f76eb215129cfcca43460140741ea06cee65a1f21b708afb6f9d5b0", + "0xa7aaec27246a3337911b0201f4c5b746e45780598004dac15d9d15e5682b4c688158adffdef7179abb654f686e4c6adc", + "0xa1128589258f1fbfa33341604c3cb07f2a30c651086f90dce63ae48b4f01782e27c3829de5102f847cde140374567c58", + "0xaaf2b149c1ca9352c94cc201125452b1ed7ca7c361ed022d626899426cb2d4cc915d76c58fa58b3ad4a6284a9ae1bc45", + "0xaaf5c71b18b27cd8fe1a9028027f2293f0753d400481655c0d88b081f150d0292fb9bd3e6acabb343a6afb4afdb103b5", + "0x947c0257d1fb29ecc26c4dc5eab977ebb47d698b48f9357ce8ff2d2ed461c5725228cc354a285d2331a60d20de09ff67", + "0xb73e996fa30f581699052ed06054c474ebdf3ae662c4dc6f889e827b8b6263df67aeff7f2c7f2919df319a99bdfdceb1", + "0xb696355d3f742dd1bf5f6fbb8eee234e74653131278861bf5a76db85768f0988a73084e1ae03c2100644a1fa86a49688", + "0xb0abca296a8898ac5897f61c50402bd96b59a7932de61b6e3c073d880d39fc8e109998c9dba666b774415edddcff1997", + "0xb7abe07643a82a7cb409ee4177616e4f91ec1cf733699bf24dec90da0617fe3b52622edec6e12f54897c4b288278e4f3", + "0x8a3fae76993edbc81d7b47f049279f4dd5c408133436605d934dee0eadde187d03e6483409713db122a2a412cd631647", + "0x82eb8e48becfdf06b2d1b93bf072c35df210cf64ed6086267033ad219bf130c55ee60718f28a0e1cad7bc0a39d940260", + "0xa88f783e32944a82ea1ea4206e52c4bcf9962b4232e3c3b45bd72932ee1082527bf80864ce82497e5a8e40f2a60962d0", + "0x830cf6b1e99430ae93a3f26fbfb92c741c895b017924dcd9e418c3dc4a5b21105850a8dd2536fa052667e508b90738f2", + "0x990dce4c2c6f44bb6870328fba6aa2a26b0b8b2d57bfb24acf398b1edc0f3790665275f650884bd438d5403973469fa2", + "0xa2e5b6232d81c94bcb7fed782e2d00ff70fc86a3abddbe4332cb0544b4e109ae9639a180ae4c1f416752ed668d918420", + "0xb4cdf7c2b3753c8d96d92eb3d5fa984fef5d346a76dc5016552069e3f110356b82e9585b9c2f5313c76ffaecef3d6fd8", + "0x83b23b87f91d8d602bff3a4aa1ead39fcc04b26cf113a9da6d2bd08ba7ea827f10b69a699c16911605b0126a9132140f", + "0x8aae7a2d9daa8a2b14f9168fe82933b35587a3e9ebf0f9c37bf1f8aa015f18fb116b7fba85a25c0b5e9f4b91ba1d350b", + "0x80d1163675145cc1fab9203d5581e4cd2bed26ad49f077a7927dec88814e0bed7912e6bbe6507613b8e393d5ee3be9be", + "0x93ddeb77b6a4c62f69b11cf36646ed089dcaa491590450456a525faf5659d810323b3effa0b908000887c20ac6b12c80", + "0x9406360a2b105c44c45ba440055e40da5c41f64057e6b35a3786526869b853472e615e6beb957b62698a2e8a93608e13", + "0x93bfc435ab9183d11e9ad17dac977a5b7e518db720e79a99072ce7e1b8fcb13a738806f414df5a3caa3e0b8a6ce38625", + "0x8a12402c2509053500e8456d8b77470f1bbb9785dd7995ebbbe32fd7171406c7ce7bd89a96d0f41dbc6194e8f7442f42", + "0xaab901e35bf17e6422722c52a9da8b7062d065169bf446ef0cbf8d68167a8b92dab57320c1470fee1f4fc6100269c6e2", + "0x8cad277d9e2ba086378190d33f1116ba40071d2cb78d41012ec605c23f13009e187d094d785012b9c55038ec96324001", + "0x85511c72e2894e75075436a163418279f660c417e1d7792edce5f95f2a52024d1b5677e2e150bf4339ad064f70420c60", + "0x85549ca8dcbe49d16d4b3e2b8a30495f16c0de35711978ada1e2d88ad28e80872fca3fb02deb951b8bcb01b6555492e4", + "0x8d379ab35194fe5edf98045a088db240a643509ddc2794c9900aa6b50535476daa92fd2b0a3d3d638c2069e535cd783b", + "0xb45cfebe529556b110392cb64059f4eb4d88aaf10f1000fdd986f7f140fdd878ce529c3c69dfd2c9d06f7b1e426e38f3", + "0xac009efd11f0c4cdd07dd4283a8181420a2ba6a4155b32c2fed6b9f913d98e057d0f5f85e6af82efc19eb4e2a97a82df", + "0xb2c2cdffa82f614e9cb5769b7c33c7d555e264e604e9b6138e19bcfc49284721180b0781ecbf321d7e60259174da9c3c", + "0x95789960f848797abbe1c66ef05d01d920228ca1f698130c7b1e6ca73bfda82cee672d30a9787688620554e8886554ee", + "0x98444018fa01b7273d3370eeb01adc8db902d5a69b9afc0aa9eadfeb43c4356863f19078d3c0d74e80f06ecf5a5223f4", + "0x87d20b058050542f497c6645de59b8310f6eeec53acbc084e38b85414c3ea3016da3da690853498bde1c14de1db6f391", + "0xa5c12b3a40e54bee82a315c503c1ce431309a862458030dde02376745ec1d6b9c1dbeea481ae6883425e9dae608e444e", + "0xb9daa3bf33f0a2979785067dcece83250e7bf6deb75bb1dbbab4af9e95ddfb3d38c288cbef3f80519a8916a77a43b56c", + "0xb682ec3118f71bde6c08f06ea53378ea404f8a1c4c273dd08989f2df39d6634f6463be1d172ac0e06f0fa19ac4a62366", + "0xa4f94fd51ecf9d2065177593970854d3dce745eebb2a6d49c573cbf64a586ae949ddfa60466aaef0c0afb22bd92e0b57", + "0x86cd5609efd570c51adbc606c1c63759c5f4f025fcbefab6bc3045b6ad2423628c68f5931ff56fdda985168ce993cc24", + "0x981192e31e62e45572f933e86cdd5b1d28b1790b255c491c79bd9bb4964359b0e5f94f2ae0e00ef7fe7891b5c3904932", + "0x9898f52b57472ebc7053f7bf7ab6695ce8df6213fc7f2d6f6ea68b5baad86ec1371a29304cae1baadf15083296958d27", + "0xb676c4a8a791ae00a2405a0c88b9544878749a7235d3a5a9f53a3f822e0c5c1b147a7f3f0fc228049dc46e87aa6b6368", + "0x9976e10beff544e5c1645c81a807739eff90449df58ffdd8d1aa45dd50b4c62f9370538b9855a00dd596480f38ebe7a5", + "0xa0e91404894187ec23c16d39d647ada912a2c4febfd050a1ea433c4bfdc1568b4e97a78a89ba643aca3e2782033c3c58", + "0x91a6ea9a80476ed137eb81558ff1d55b8581663cccd41db4fc286876226b6515fd38661557419e1e46b6a3bc9cda3741", + "0xb9e8a1e23c60335a37a16f8085f80178a17d5e055d87ffe8cf63c532af923e5a5a2d76cf078164fb577996683796caa6", + "0xad8e151d87a37e8df438d0a6a7c02c3f511143efb93fde8aef334d218cb25932baf9e97c2f36c633620a024a5626af3d", + "0x978f942f210e8a482015e6fdc35a4c967c67b66e6e2a17a05cc7a0f2163aed227b775d4352b0c3cca6cbf4bd5bafaf75", + "0xb5e2e3d8b2e871c07f5899e108e133f87479959b80cb8a103fbecde00ccdbfbd997540eef33079c5cc14b1c00c009fd1", + "0x88a164b3fefd36857f429ab10002243b053f5d386466dbb9e5135ed3c72dd369a5a25e5e2aaa11f25488535e044e2f12", + "0xa66091c0db4e7cf05a089ec2b9ff74744354d0196968201f5e201699144b52bb13b4e68e12502727163e6db96e3565f2", + "0x8e65aff8e37240461b7374c20bfd1d58b73a525c28994a98f723daed9486130b3189f8efe5c5efcd7f5390cc366038da", + "0x8b37c21dd7304c3aa366959ba8c77ea8b22164a67e136808b6f8e48604297f7429a6c6ecf67b1d09b8b7ec083eacd7e0", + "0xb689b1277ad050f53da91a702516a06d7406ff33a4714ea859b3b2b69f8d0aa8f983c7e039b19c0759a3815d841fa409", + "0xb17f7a0a182ed4937f88489e4c4e6163dcf49fd2ea4d9efbba8126c743bea951cd769752acd02e921774dc8ebcfae33b", + "0x8b7fab4f90be825ac5d782a438e55c0a86be1c314a5dbc3cc6ed60760a8a94ef296391f1f6363652200cce4c188dae67", + "0xab8410c4eaa2bb43b0dd271aa2836061bc95cb600b0be331dada76ddb46711ff7a4ad8c466cc1078b9f9131f0dc9d879", + "0x9194bd7b3cc218624459d51c4d6dbc13da5d3de313448f8175650fa4cfab7cc4afcda5427b6676c3c13897dc638b401e", + "0x980f61a0f01349acd8fc9fdc88fc2c5813610c07eecb6ab14af0845a980792a60dadf13bb4437b0169ae3eff8f5984ce", + "0xb783bee24acea9c99d16434195c6940cf01fc2db135e21f16acae45a509eca3af6b9232a8aa3a86f9715c5f6a85cb1c3", + "0xa3079931c4b90966d1faa948db847741878b5828bc60325f5ebe554dcab4adcc19ee8bce645e48a8f4a9413bb3c6a093", + "0x801f61ac9318f6e033a99071a46ae06ed249394638c19720831fff850226363a4ae8486dd00967746298ee9f1d65462f", + "0xb34dbbed4f3bb91f28285c40f64ce60c691737cc2b2d2be5c7d0210611cd58341bb5bda51bb642d3ee2d80882e642a13", + "0x8750af19abfb915e63c81542b13d84526a0c809179bbcc1cd8a52b29f3aba3ae0f7cf6f4f01790bf64ef7db01d8ee887", + "0xa6ea10000eb2dd4efc242ac95bc3b3873cdd882fbeb7c9538c87e3143a263ca3a2e192b2159316a625cfb5fb0b6cdcb3", + "0xaa40ca54bc758a6c64cb932924917581062e088b3ad43976b28f2e11d8a7dea73f1fb50aeaa0e70182bb2dc07d805bb9", + "0xa4779dfd25b5ec9d75dfb54a4bb030364899a5e75c1492403acb19f2adc782c7ac4daeb66d2f5aeb74135afe9f318e3f", + "0xb4551e2805d63ca453f4f38b1921ac87ff687e1d70575ad38f3469d6f0608ef76b7b1b98ae1e6b1e7d928773aaab6e3b", + "0x99490ee722f96aad2743b08dd37bfeb75a8c59efaee4c9b694eaa05eb8a6bb23861a4480544c7617d04d23fd5e2543b4", + "0x8a7050d964d295fff98ae30d77ce730a055719313457e773fcce94c4d71a9b7cf63db67e54a8aab20fb1335b0130b5d5", + "0x903144e6bbee0a4fec17ff80fef0d2103981140c3d41776cfb184ced17f480a687dd093f6b538584327e6142812e3cd5", + "0xa5b30f7c6939bdc24a84ae784add927fec798b5a5ee3dd156c652df020728dd6d43898be364cf5ee181725fbcffc0964", + "0xb43d97ec2bc66af92d921a5c5c20a03ef2be2bc2c9b345f46d8287409fcbfd88ebc49d4509d64468222cd1d2021bf236", + "0x82dc23c7f5086c9ac6b4566359bfb830d203544b0d8332a210775670f899cd9ff48b94bfeba40040c25664ebdd5cfad8", + "0x9294cd017fea581dabb73dcc8c619904d7e022b664b0a8502c9d30f3807668af279948e7e41030ae296d492225297e95", + "0x8d6c9dc636c8e884f9a4299e5cff06d044ebc94ad783a4b71788347ea4a336d4d048b8a9ecabae789e8fcdc459723dfb", + "0x801a80bc49e882ec81b04e37407713f033f7bdac79252dfa3dc8c5bd0229fcbd4019890e402cf843b9378df08f72ab84", + "0xb4313ca32569d973900f6196363c0b280ddfa1b47c88d019e5f399b805b444a777950fc21ae198fc23ece52674b94abf", + "0x96f06056fd255fdabf78986e315e7c4fdf5495cf850536b7976baa97a994cc6a99c34609c33a0f2facba5e6f1026dce6", + "0x983ed80220a5545ffd70ef5e6ac10217d82ec9cd8f9a27ee77a5ff4074092308c0e6396fc4e9932a77ddd474e61f8b55", + "0x872a059aa630af73c4abbd076e8b333a973ffc5bdecf5dcc0600b00162184213cb19d4f601795030033beb808d5810ce", + "0xb040f318d9d3b8833da854014a44296dbd6762dd17cab13f91987256c54353b7f0800547cb645a7cc231997454209fdd", + "0xa8c4731a555308e8ce0b8325eb7a4cbf6113d07e9f41932df04480b72628d313b941c7055f1cc2ac45c7353b56e96ca9", + "0x8c24031440b77637e045a52e5ea3f488926ab0b426148975edf066c40a4581beecc1bfb18fc4cf5f9f96dc6681b4bd28", + "0xb39254b475abf342f301298feaa17a4b3051f30ea23a18acf59e003e2704ac96fe40691f1da387913bdf7aee6389f9a8", + "0xa1dbf938b604ccc6d60881cc71f38df568aa02752aa44d123514154017503f6c1c335ae43e359f1487bc8934073cd9c1", + "0x8d52aa1be9f429ece0580498d8fe9fef46d4a11f49436a82b8927f9503dacc41245907f126594c1cd30701286f8c092c", + "0xb826f396486942c0326d16f30a01b00a682c30a75553dc6ac34fd5b3e96b13c33b94738f522eebaffb59ff8c571c76e9", + "0xaa89f51cbf6e6c3e2aa2806187b69ab3361c84e89f393f3ed284fe84db46fc3944aa44f8928e3964f9c1a1ec27048f68", + "0xa254df0efa4203fb92b42a1cd81ca955922e14bf408262c8f7cb7dc703da0ca2c71556bd2d05b22ce9a90ad77309833d", + "0x93263c507e4d5f4e5df88e85b3d85c46ea729fb542a718b196333e2d9fb8a2e62dc1347cf146466a54ba12d200ef09d9", + "0x922e3c4a84246d89a07aa3e90f02e04b2cea9bebc0e68b742156f702aed31b28c6dfa7ac936ea2fc2e029adf68361f98", + "0x9a00628eeeda4ccbed3ef7834149aec4c77aac1a14bc2491ba5d1a4a2c5d29afb82ceaa5aac1c5ce1e42cdcaf53e30ba", + "0xab3a88df36d703920f6648a295a70ffa5316c96044f39ff132937bfda768937cb6a479e9ba4a4e66b377f3a9996a88c4", + "0x966b11526ab099d550ab33c6a9667e5cfdedf255da17a80a519d09acd78d2ea24ec18bd1ea7d8d63cf0a408f1c1fe0b3", + "0xb5c21b9817dc32f3df9d9988aa3560e1e840d586d01cd596bc0f850ab416b6013cbf7dbfd05ac981f26014c74bd2d2b2", + "0x9040abef5e2523e7f139c9f744a64b98fea3a57952059ffe4d5ed77fa87068203c090ef4e7f52c88fb82ea8a6fdca33e", + "0xa0dcdaeb7d3f5d30d49c004c5f478818c470187f4b0b4856812dcd1b3a86de58a99acb8ceb44c6b80c3060cf967c43a4", + "0xb5f4be9a69e4a6719ea91104820df8623b6d1073e8ee4168de10a7e49c8babea772bcbc6b0908185e98d607e49cd3609", + "0x8634020a5a78650015763c06121c606d2dd7b324aa17387910513dd6480fb797df541fc15b70d269b2794ad190595084", + "0x9504d1d0fb31ff1926c89040c04d51fd1f5cddf9d7ca3d036e7fd17e7a0f767ef33cee1d8bf7e17e2bc40949e7630417", + "0x812c72846ef6d692cf11d8f8c3de8fa78cc287303315114492667b19c702cd24d462020f1276895df26e937c38f361f8", + "0x8c97aa5e9ef2aa9a1435ef9ddfe62e850f0360864ed5fb82bf9fef4ef04d8fb4f827dc078bc911ee275e4501edd6617c", + "0xac5f7af5e23c8e429aaa6b6825129922b59d25b4608f07b65f21388a9ac3aa89096712f320afe6d56e44e1f0d51a4eb9", + "0xa8c84d9a8593a0cb5be1e450960f59878a4e6b70da54a7613dfc25911b7cc9e6d789d39401b0a0d6471ab9dcdc707976", + "0x8c9d5fd89611392c0f085ffa4fa642a181f0b9b23593deb5e10fdd1642722ca75ef34a037e88a8d03f2888fe7461f27c", + "0x8c74b05f91fb95c85e7bd41f6d9a1e41e667e68f3d19b325c1f25df1767019919edab89b92af237896cbc4e6d6dc1854", + "0xa3caecb91640821f0b2c4981b23f2069df8d2b98ce026c1538bc096b292f5f956a5d52c1c8d6a8165a1608083ba6494b", + "0x8ae8e0c36f8b79a69176ff29855df45d0fcd9e4d1dbaed8899f8fcdece676e418ec034a6c161e2a894f0c834aaecbfd1", + "0xb88d18c67dc3b1b6ed60ee437c441c1ed14ecddebccf43683605716f30058b1aa4ba05ff10cd8171ee97d8f58d70c094", + "0x94f43d84dcdfd9cd19115c7d8e9c1e856828eafbfdec93b876cf0007e317e30b2ad951dbabc186aa6ef90fdee4d91990", + "0xb44e4723f41fc1d5b0057f371e3381ae02566590b3f964b6eb07b2104f66ff78410c407235fa98d04f635694f3baca09", + "0xaddd8390173d29ca0811534d389253831fed75fed135398617836b6e70767269eacb1560b39a58f02042ca3b97fe59c4", + "0x80bdbdacc0c358c7ea52aeacdc5f9ceb6928bcf6e7dee7c17d8ae3bf7c2372aa7a0372363888968fc0921aaf4776d5d0", + "0xa486e2b6f04f403f9e609d69dfb3cfb992af56ecad1683271df3e3faa3b86638b81e73b39978fb829ee7133d72901f2d", + "0xa19472da57457e10c6a6307895393ddaec8f523760d66937fe26a025817319e234eaf69756ffdf1b84c81733424a96d7", + "0xad6a195397cbc2d75171f5e82090441eed60bd1ba42c39ef565b8b5a8281b04400678625b1dc46d617f694a7652a8e5d", + "0x8f98e721c06cec432e2221f2e1b06bb1469d916a8d88d6973acf68d1e003441d00390dafcead8ecdbf9eae4509baf5aa", + "0x91d62a0f9d13c59adfe1376ed6d057eae244d13c6b3d99be49a49e0075cf20f4085cf127774644ac93615be9ac9e5db6", + "0xaf45dec199245e2b326a0d79c4899ed44b1c0219db42602a4a6184ace0ff831a3276297af28f92e8b008ba412318e33e", + "0x8754bde54e8d2d169e6a7d6f0eae6097bc0461c395192bd00dd6f105677ea56ab384c02553ea5eeac0a65adcb0df77ee", + "0xb676afd2f5afc37a314c943d496e31b4885efcbcc2061036e370a74cfde5642bb035622d78d693bfc3136fc036c7edb4", + "0xaab6ffe6cc234397cf1822e02912bc282dfb314e92fb5a9e10d0c34ee9b5856d4b76e166bc2bb6fcdd66aabea35ec4ef", + "0xada6e62f90ee6b852ec4b72b22367acac2896f0df2c105beda27096583ddbedddc710d171330569f111c6e44a5b57ae7", + "0x802139dd15241a6de663d9b810121bdd9cf11f7f8c8ca6de63f4f8e731409e40d1fd3558b4f619ed42ee54929dff1c7e", + "0xad8e70531cec21b4e6f55be1751c2d025bd2d7d8158269b054cfe57fa29252d052ce4478ec7db6ec705789e2118d63b3", + "0xa8e4a4271769480e1b33a28c87a150ecc0b48bfe8a15ae04152197881de4ce4b03453aefe574842424edbbe4173e1a3a", + "0xb98c65726296610cef16c5b58da5491acd33bd5c5c5af4d934a9840649ef85730fbce8018dee09ded14e278009ed094a", + "0x8e213a7861223287b860f040e5caaa563daa0b681e4e09ec79ad00cc459238e70bbeaf7486bbe182fc12650700034ec5", + "0xa2879f9e1a556cf89b9b5b3bd8646a8cce6b60bcbc8095df44637f66a2da5858eee2dc9091475a8f64bb5aff849389cd", + "0x8a17cdb4077b9b0bcf28b93294ac5ae4c8bba8839fce0f1012b53187ac008f9858b02925fbfc421f1123afcdbd8b7753", + "0x86fd9c11528aa43946e4415ff64a3ca6409ee6f807368c68997b18605da65e415ccd85ad913820d450cb386593de666d", + "0x8ed55923b963c3d85a91aca11c40ff9c6c7f1e2b9bc199d1a270e5fb16aa62dec0136e97866145ae9d58a493e8b1cbbb", + "0xae32af5b5d418668ae123c639b149e5eed602404e8516da4a61db944b537a3620545e8e3d38cf10cdaea980ab2f80973", + "0x95cb8d9e9d6762d78dde0ad73869ffaca904a7d763a378b8cc11a7933d3e7d1c8aec4271a079b1b00f8887ee5b1ea21f", + "0xb5ea20b42a3ca247f00ab5328c05f0cf194973d5f7271c66c41c5055b1ffdca136be179709e0c1de209fbe07b9820bf3", + "0x98682f7cce471c92a8d6d15fee4ddf4d43dd97c3e3811d2913618ecacc6440b737717c07736ae4558c910e11ee98104e", + "0xa67da2c7cbba48e929ca4e4b9a6299fe01ef79eff8cc5cd3fdbdc0721a68130e4079f30ae151a573a7dcca8ecf2e684e", + "0xa9981c9f9dcbb3b0f6996f664fb2acd7573189f203be37b2b714662aa273551396abfb1f612ccde4e4c8127a050dbe4b", + "0x92d55eff8da600f886da9bf68e8eecf482faa4b268f3f286b3b3e5cc91b19604081498d4905b201bb4ec68e32b5591d9", + "0x963e3f1728de9d719c86d390f3eb9c3f99d1928347fab0abf10dbb37d76b59ddb64d4734c977863a6cd03ffece5ca895", + "0x93480e2de83c921056b6d8628ac37cd5ef7555ba43b0308fc13386cb0515d42c12ecd06057137aa71a7931beaf90b9ce", + "0x8feae57ff0e6a162cc81c99f45c6187d268fc0bee8c2bffc92142ef76c253d201f0e932943cf2fa312982b281ce1066b", + "0x8f8f4bd4200fb87afcd743274480220d77571928000d4197410dbb75439d368df6a06d941a6152206371d2ca9cac99e4", + "0x8ee7f11e79af4478e0a70eb424fe8078237ad99ba6d7e6bf1a8d5e44e40abd22d404bd39b718ad6fdf4c6601f2a47665", + "0xa98acfcec612b574943195b9ba95bebcc9c0b945c9f6b3e8760b2a4635909246a9d73b0b095c27b4ecb3339704e389b7", + "0xb520efd19f65e81dc285031ea3593f8c5dad793e4426beb9196ab46e45346f265fd71e50adb0da657977c60ed5724128", + "0xa3d9d0b7415280ce4dfa2429d47b2b8e37604a5157280a72cc81d541ffe44612dbb3ef7d03693fc42a569169d5842dc3", + "0x8c29e2d0b33801f6d9a9c065a76c5cad1fb0a001506b970307e21765ee97c732a4cbf1d7c1b72d95e0ad340b3b075224", + "0x839e21f292892a6eb596b9b1e9c4bd7c22a6fe71d3d04487c77840028d48392c5cbe73140a4e742338e0c8475cd0c1ad", + "0x8bea5c68e7743998619185bb662e958f1b4d3ca81019d84ac43c88911aab3abe4ee9bcc73cb95aa3ae87c0138801bde3", + "0xb8f262d21a94604049e008ce03dc857848168e1efca4522acb0ccc827ffb37f545e1947843a356563a76bc6489605b66", + "0xa7bd0842b0bb38d9943b82aa883f36f4eb8a6e8a7790d4f87faf306608f51d250a19b73984f1156cef5dd2581664614b", + "0xa993e649bd953627a88a2539dac3a12ec7f37a4c65b01425d9d34edf7ee10a71aa98f65c9e013107f824faf8aee041a9", + "0x8e07eced75c67cb4d2ec01857f6ac1408482e6b31cb2faa249e8cf99f180575587df530c7782a7539b5221121ef48aa0", + "0xb2f4578f26c05ecb9e2669ca744eb19d4f737321ac7d04fafd18beb7866e0fec9dd063953ae1f077b44b9c6f54db1279", + "0xb6b3788a6c7bcaf467d19daf6ab884d549aa866970c05a9181f544ff190d043192c84fe437a75a30b78b425461cca062", + "0xa270684903c61544b85a7041e81f65e787e1c1e23e57538fa8a69836bed0ca1673861dd29f743a1280f2f38eddd3aa83", + "0xa9c2397c4773dcad2821266dadfd2401d013d9f35de6744f2ec201f3507700adb1e6ec4f5a453be4764da8bf68543f26", + "0x83a3025ed6fd5df9d98be32a74e10a0d9728b560942d33ba028536fb148fc34ae87e92be2df3e420a8dfec08da495982", + "0x90dc70c183a90bab988b4a85b7b921c8070af0e5f220364fe11afa0722990b2c971e1e98eef62d3287fedfd9411f1df7", + "0x82d940937a6c636224d04f8e2536f93dcf20dc97a5f188875ad76c21b804aef9af10839419b61143c1f88a695959a6b4", + "0x8017f9473ce49d498d6f168137e77e62fe553e5a51e75b519cf2cbd1ab9afdafad80fd5e6fd0860e640b0d78ca8ed947", + "0x80573a0ec049fe1f7b3013b2839e145cd87e07c0e43826a29ef8c92516f9a30896c2ffcf3ed77ed22a6cf3101b1789d5", + "0x953349abd2559f9824db07cec857ad54f1a05018f3076425f8dbae37f8d92a46af2c04ab7c8ec0250449541187696e98", + "0xab7bd2c4f05ee9a9f252c4e16a20993a12c535c3809d124bae24642616521a9768d3f19eceaf8524583f47ae1f527684", + "0x9883b77ee834ee0112ca2f366d2a6fc213e0cf454e061438c2901a5ba35b7378f64da8adf6a476eb1562991ef5b4a5bc", + "0x89291811db308637356dbf7ed22cf07bfce33eb977734ee346e8c15a231b35d8b4443574f3fa97a40867b3e23b0bbfa4", + "0x93d753849d7d9588d39e38217500b123a6b628a873876612d9f98b5d611f52c89c573432d2176752b5d1cc2d94899b8b", + "0xa45add3c4844db3b7a237295fc85fddc788ac1ec395a0524d2fc90a539571a247146aea4aa10eec30a95e9617c85b98d", + "0x90f94578842db7a4de672da1e483858ece5e466c73c12f725a0fc71f42ff880c9447a33fa9096839bee817536f2591e2", + "0xb2c1b6fb031bb30460f157356562b44b4de096a0a112eab4fb3cc500aad38bc770da1fc2e73caf687a0da5e8537049c0", + "0xafb15e15fd930929c0e3c66482068a5afe0c7b7f82e216a76c5eb1113625bfa0b045a52259d472284cfbaf4796c71456", + "0xad222a9a3d907713418c151b8793d5e37634354322068f8206b9d0da1a3f53b0004193713d23ec35990639a1b6c2e075", + "0xb44a128dce97e8c4b178cdbca0a5c1b3f6e164490fac0fd68dbfe0aafa89920bb4ea420a8527e06c80dd19c2f135e3ef", + "0x8596e993ef18b8d94e9c42a90cb7060affc586b8e9b526820d25124285de5590134e2e86592e9dc4dd45ccf5d578fa60", + "0xb71bb0ad138141ed506b2253e84110d2db97cc2d24a3fd0d096b0022d9f38f87aa74e2f505074632d64e90bcc491aa30", + "0x84841eafd357309de47b92ca5ec163dec094a2e5271bc65898c31932e0160bee165e4decb23af339cfe09c83e1cc5441", + "0x8a2915ee39a6fd4a240b98533d7690ef1773ce578ed1fb05ed414ebe36f7ef289fa46f41768df57190438c356331e329", + "0x90bb337165386f1990cbd8ed2e8321ef21bc18125b015b4da0c37e5fcc446b26005379ee4fad8ce9348ceb4ab49e82e2", + "0xb707b50ea2ab05c6d183671587f25fe29eef23fe569d731459a1ac111a0b83a2cd65b88242876b34aeead3b05a15d745", + "0xae1f159f79b7996315c4f9acce7e21a6ed59d4ef76331196fc86911fda3035edd5c11d568b105175a36c948d0263b382", + "0x922bc525bace05e5dff6b5cabde5469ddd2c1c601f7131abc04ecefdd35095e6ac015b1aec3c3b25c5dee8d139baf60d", + "0xa7b060405b2740f82db64683187b1bb89e5f40c8438663c7cbc8ef2513929fe5f92625667a7f2f599a72a96b1fc8f08a", + "0xb9dfe94a08651db5efefbb813269bce80d814e3089b80c0654491e438d820bf521f8a4a4477909344ba88f7683eebb43", + "0x841817a9729465743576950b6e8eea32ebf39cca99ace86c4792f9f35926e2d6830c52854a3b2eaeb61694e6845008bd", + "0x934128034bde8fc7b93b952aa56e0ed28b36cfa04cfa1f0d5b38266dd40beedff5e0bab86e4717b0fb56c56be2eae26b", + "0xaee9d64caf28596308782cd8f3cf819506daf3378f86157ff775e618596411adf94efd0e9542787ca942066f02cbd332", + "0x85871184db314411a49575fee088c52ed5dba4e916ee001ec24d90898a0154d9790a06aa8a707ca7a8b986c0293b8d89", + "0x8d3d87edcc0187a099c97b581a598d357a41ac152303bb27c849eb78e72e15cb97cf9a0468fc36f245c3e152c76bb7dd", + "0x900475d165dec18b99eb7b5f9e9ad1d2d4f632e55fdcc4c5ecd7775fed462990e6aaafe9c669f40508f9b15f00bda31f", + "0xa25b5954edd57e7811a0d18532043d975c7b44b80f65cd630935d7b16ada05f30fe2b7be7ae8a2f54c25957faf3f1950", + "0xa089019afa3a7a15f7e7874e73b6773c0a824e6d3379b4c928e173321fb165ad979a6be004d394c28d19d410b2655d3e", + "0xb28f46797dee0c538bd3de815df641a0ef718ad3e52b2764aec380d6905b38b50ad6f60d0f68e096ca39960ba7734355", + "0xb0ac155d3d05851b04104e6b459f1a68e9e155437c92421a7c0e4dd511ef89cf71dfa3cc920769492ee283a65ebf029e", + "0x813c69a810745580d43d5b5480f0ba81000fbef0071e6b655c7346bef5ed774e9214a7816d40eb1774a5bd033767a046", + "0xb176345ca75c64f10ec33daa0dcf1f282b66a862fcd3d8d66c913f9a02db4c9d283dadc02eff13aaab94bc932a42234e", + "0x92560f67e5b995db4a489bb86ee78b4aee0800143b3535ad557a53e9e08716bd0202d9f5714722c2a5e8310046e3f5b3", + "0x8adb427bad9cc15fc6c457a96a6750dda8c46d859c5f69bf0e7ab8fc0964430b33967fd47cf0675b6ba1757f91255e6e", + "0xb120f723b80389a025b2daa891b140b3d7b8d520ae2a6a313f6e3d365a217af73292dcb249dca1f414ec05e865e3cdc7", + "0xa61a5d261a8dfe5996c42ea0a5ae703a2adcfda80e86837074d868eee16f87d38da19596c48b55dbd7a7cbec1a9b4996", + "0x99dc921eacc6bb867c5825ad4c83bc4af9dd78a18b3d0e1a60ad493e3805b8fb9b7922b577da1adb3d805edfc128d51d", + "0x85455fa165a07282aaab4a5bfb88027f47b9532e4af8195c048515f88b0db7e80f42e7a385fd4944faaa7f2a6544ad17", + "0x96dff2d1c8a879d443fe576d46bcceaf5f4551d2e8aad9c1a30883637c91090de99ad5eec228eb5febf93911502d3cbb", + "0xa87eb7f439377fb26c6bfe779701f4aea78dd7980b452a386afec62905e75217a1996c5234853432a62ef8bab21c31c3", + "0xb598278293823e9ccb638232a799211173b906444376337fdf044d0227d28fcc4c5867e6ecb3200e59ca0b139e71cac9", + "0xaa6fe147edc95027654d68140f428ec53cede3552c5f49c09d18bc6f6ae8c739a63042eb7291d14d717a4e1f0778abcb", + "0xae8ee18913d328b2fba71efe65526d3ee9c81beda53cf776baec4019ea30212010758cbb5dc85ed6620ce04b189f01f2", + "0xae9fb686777e88dffdd42805fe4114aa0da1b350d92a27ff3f8a817fb25af1fcfc9a06155affe0273bf13caad16a5351", + "0x95d372ba3a2ee38371538f34aae91b4844488e273f70c02f1992370f89fc2343eff95692d52ce9f21206abbee4959958", + "0xb15260376f0a34ca2827ff53acd7eaaef94c9acc2f244b36500423069cb1cdaa57ac8dd74adb5b53d0fd4265fcbb28ea", + "0xb0ffce6a8059537ef6affdbbc300547ef86e00109289239b0c6930456c562b4ed97f2e523963af17736dd71b46c44ac7", + "0xb5499a1277d34f9892f7579731ff53f423f2ffffa9ea43a6e929df8c525e301396249a2324818a6a03daa0e71fcd47b3", + "0x98dbfb8e97a377a25605a7665d4d53e66146204d8953afda661ae506858c5cd77ff7f21f5f10232e06dbc37378638948", + "0x84177e27e6da0e900c51f17077f5991e0e61bff00ca62c1623e627c5aea1b743f86eef6d55b13219a1947515150bade6", + "0xb50407bb5c61b057ab8935df94fd43ca04870015705b4f30ceac85c1035db0eb8293babc3d40e513b6fb6792ecbc27a9", + "0x988699a16917514e37f41ab5c24f4835ed8a2ca85d99972646fcc47c7e2a83c2816011144a8968a119657c4cda78d517", + "0x920c43fdcb738239ad542cb6504ab34498bce892311c781971d7db4dec70e288676de4d8697024b108cfa8757fa74035", + "0xaaa106329aac882e8d46b523f126a86d3cee2d888035ce65c0be4eaae3e92fd862f6ac2da458a835539cccafaba9e626", + "0x96e4c1562d14b7556f3d3e8a1b34ea4addc5a8170e1df541dc344728bcb74cd1630eb7ba4c70e9c68fd23c5c5d5a729b", + "0xa616ac5016d4e68e03074273cd3df9693ee0ce3458e8758b117a5c1bc6306dd2c7fad96b1bb37219c57ac62c78ad7a3e", + "0x8db7d9b20abfb1445babd484ae9e38ff9153ac8492230d7591e14e3fca7388a5ca6ef7d92ed445c8943cf5263e4a6ad7", + "0x88464134221aa7134878eb10928f31c8bd752ab68c27c9061c1de3f145c85731a4b76acdc7e939b399b6e497f9e6c136", + "0xa5f7c794f70b7c191c835dded21d442b6514bab5e4d19b56f630b6a2f1a84a1d69102d7a0dcca256aab5882d3f30f3ca", + "0xb96b6f98b6817b5fa6b1b1044e2411bdf08bf3ffaa9f38915d59e1d2b9bed8b3d645eee322ee611102ce308be19dbc15", + "0x92c26ade2e57257f498ac4ff0672d60b7ea26dad3eb39ed9a265162ccd205c36b882dba3689758c675f29e20836b62d9", + "0x8379a0299e75774930577071d258e89e471951642b98e5e664c148af584d80df4caa4bd370174dae258848c306f44be5", + "0xa0e53beda02bd82bf3d24bd1b65b656238128e734b6c7a65e3e45d3658d934f909c86ca4c3f2d19e0ac3c7aae58b342e", + "0x8ca5ceaeaf139188afd48f9bf034d8baf77bbf9669791c7e56ebf783394d7fcdf2a25fa4bdfcddfde649aa0dc67ccccd", + "0xa8060e6448844e9db4e9fb4da1c04bcf88fda4542def5d223f62c161490cf1408a85b7c484341929c0f9ce2a1d63e84b", + "0xaf6e1a5ecf50b754bb9eb2723096c9e9a8e82c29e9dcaa8856ab70074430534c5395534e1c0ed9ce98f4b84d4082fa67", + "0x81c8dbbef98f1b561e531683d5ae0f9b27b7f45dc6b2f6d61119ca0d559bf4ceb676d320afc5aba1811eeef7547a59d8", + "0x85b46cd64d605c7090a2faf1a2aadf22403b3692b3de1d83e38b2de0108d90ac56be35b0dca92c7a41c4b179a3567268", + "0x8dd3cc3062ddbe17fd962c2452c2968c73739608f007ad81fa1788931c0e0dda65032f344a12249d743852eb1a6d52a9", + "0x8630f1707aea9c90937b915f1f3d9d7ba6bda6d7fdef7a40877a40c1ee52471fd888f84c2b2c30b125451b2834f90d3b", + "0xb4a747e0bd4e1e0357861184dacec6714b2b7e4ee52fa227724369334cf54861d2f61724a4666dae249aa967d8e3972f", + "0xa72de682e6f9490b808d58f34a0d67f25db393c6941f9342a375de9ca560e4c5825c83797d7df6ed812b71a25e582fff", + "0x8d5ea7d5c01f1f41fffe282a334262cc4c31b5dcf31f42cc31d6c8e37c9bd2f1620a45519dab71e108fe21211c275b6c", + "0x8ccdc7e3642c2894acbf9367f3e99c85963cea46dc5473d175339a2391be57dd8815feacadec766e13645971213b9eb8", + "0x858e9b5fc8c13b651ff8eb92324bdda281db4cf39f7e7bd0472908b3e50b761fa06687f3d46f4047643029dc3e0ceeaa", + "0xae20d36c70cd754128c07cbc18dcb8d58b17d7e83416e84964b71ccff9701f63d93b2b44ec3fddc13bbe42ebdd66221e", + "0x860dbf7013da7709e24b491de198cb2fa2ffd49a392a7714ad2ab69a656ca23f6eafa90d6fdc2aa04a70f2c056af2703", + "0x8f809e5119429840cb464ed0a1428762ba5e177a16c92581679d7a63f59e510fdc651c6cc84d11e3f663834fcafeafdd", + "0x8d8a8dce82c3c8ea7d1cb771865c618d1e3da2348e5d216c4cbbd0ac541107e19b8f8c826220ca631d6f0a329215a8d6", + "0x86e3115c895ae965b819e9161511540445e887815502562930cedc040b162ecb1e8bdc1b6705f74d52bf3e927bc6b057", + "0xb9833b81a14115865ca48c9c6a3855f985228e04cbc285f59bf163dca5e966d69579ea4dba530b1e53f20bd4dccdc919", + "0xa71f5801838a6dbb162aa6f0be7beea56fadac1a4bcd8113a0a74ab14fc470a03775908c76822d64eb52a79b35530c05", + "0xa77ab73ae94b6d3378884f57eee400eff4a2969aa26e76281f577a61257347de704794761ea1465dd22a6cc6304fbc4a", + "0xacd1c5df3c487c04cf27f002e81f2348a0119349b3691012526a7b0d3bf911cdd3accbc9883112ed2ba852145e57fe68", + "0x8a28515a48832ac9eaf8a3fb3ad0829c46c944b4cb28acbcdbca1d0d4c3c623a36cda53a29291b8f2e0ea8ee056b1dee", + "0x846bafca11a7f45b674237359b2966b7bf5161916a18cf69f3ec42c855792d967d3bf3f3799b72d008766206bb7a1aa3", + "0xb24b341675b1db9a72c3405bbe4a95ccdfd18fa96f876ec946ccb5108f73e8816019998218a036b005ef9a458e75aeb3", + "0xb99c267b4a09193f3448bc8c323e91ef5b97e23aeff227033fe5f00e19bab5583f6e5fcb472ec84f12b13a54d5c0e286", + "0xa088aa478dbe45973b04ecafbcbd7ee85c9a77f594046545cdb83697a0c2b01b22b1af0b97dd75d387bb889e17f17aa7", + "0xa0c6b0cdff2d69964134a014e36c3709d9e63f6463c5cd7b01b6f0be673731b202d577539d89dd57a888326da1df95af", + "0xb4e6dc4ef11b2b41794ece70a8968e56705199d183366759568b6fa845d2cae127486e926b5b27ae9118bb21d1682c1d", + "0xa007804353f174098f02540a57e96227232444d5ae0a24232c244647148b6c049848cbd2b50d0a25af3ca9164bfff8ee", + "0x873fb034cc39c9cee553ece908fbf315f62efbc412b9afdde6a1889326b7f6f813e050b0601ba9921688e958cb75942e", + "0xb5676c90f0106c40d8683299e59d564f505ec990230cb076caef3ae33f2021e6aa5c9b27bb8fead05fc076df034c28f5", + "0xb5a67fc4c5539ad1ddf946a063110f824f7f08d2e4d30762c9d437748c96c9147a88efc22260573803ab545c18b108f2", + "0x817ff2b748a949973a91b69b0ec38efbd945aeb26a176d19f0fb76e261c7526c759e6f5516f9ed34de6eb1ac7838c9cb", + "0x99b76bda3526a5d841e059010fdb14eb2fa035a7d10463373a062a98c3c1a123e2da0848421dd7546d776438fd05e304", + "0xaa0d363270f90d56bbee7ea577b0c358532bda36d9247af6c57d000044a97ba41e35bb0db438f4c94551c6350e4e0674", + "0xacdae205d05f54b9544be96c9032350511895ccf413dbbc56d1f03053185df22a6d5b7ffcc3fbe96c3e2ce898ccfa73e", + "0xb091c220a1de18d384f50dd071dca4648ca4e708162c52a60e2cedc0188e77c54639f75bce9a468a64b2549119c07ded", + "0x878676133e5c700b1d4844564fa92a9930badb5293d882aa25ee6721a9f2cfab02088c31d62cf1342ae3edaea99a1ea0", + "0x9756d0793e6aba3b4dff48100bb49a5ec08ec733f966cb438379b91caf52fc2a5930830ec3f49aa15a02c82c1914dc7a", + "0x9722f760184d3b2d67cb2cea7fa41b1ff920a63446006bd98c6347c03d224d2d8328fa20ccd057690093d284b9a80360", + "0xb5a68489de4f253715a67f0879437bfe8f4dfc4e655ca344848980e6153b1d728acde028bb66fd626fa72eedd46ff683", + "0xa8cfc900b34835d9fd3add08044636f69614eff9ae929eac616c39bd760fd275ee89bf24b0f275dd77a66e54fd6b94e5", + "0x89967479bebf70b2893cad993bf7236a9efe4042d4408022fdbb47788fabedcec27d3bba99db778fcde41e43887e45af", + "0x889235938fcec60275c2cf0f19d73a44d03877d817b60bb26f4cbce09db0afae86d42d6847b21f07b650af9b9381fa82", + "0xb7fc321fa94557d8fbdd9fff55ab5c8788764614c1300d5ef1024290b2dbb9216bce15cb125da541f47b411a2e7e3c2d", + "0xb11b0c4dc9477176b3cda6b17858dbd8c35a933ed31364801093f310af082cb5a61700f36851e94835c5d4625bf89e32", + "0x9874e54d2939ee0600f4194f183877c30da26d7515e9e268fea8d24a675dd2945d1565d9016b62b1baab875ac892f4d2", + "0x90df3a77280d6f1fa25a986309bba9d5b89c3cf13656c933069bc78e6c314058716b62eacfa7ab4aff43518b8b815698", + "0x962b08299a287d77f28d3609f39fd31bc0069f7d478de17539e61fcc517045050644b0307c917208b300ce5d32affcca", + "0xb30eedca41afb6f083442aaa00f2e4d5dc0fda58e66aaf0f44e93d4af5c4bf8ea22afec888cacbf3fae26d88e8d344cc", + "0x847747a22fab3fe3c8cd67f3f1d54440f0b34ce7b513225dc8eb4fa789d7d9f3577631c0890a3d251e782a78418fecfa", + "0x8d1ef3cb5836e4039b34ee4e1b4820128eb1e8540e350309e4b8fea80f3ae803d1f25f4b9c115482b324adf7c8178bc7", + "0x8f8a2b0b0f24f09920b58c76f7d99ec2eb2e780b5a66f2f30a9ed267dcaea0ec63b472282076c7bf8548211376c72f6e", + "0x831ee6dc8889bbf4d345eaeb2f425959c112d2190764abbbe33bc44e1d9698af87ff5a54d01fac00cfee5878dee7c0f6", + "0xa7eb2479ac80d0ee23f2648fd46c5e819ad3a1f4752b613607ae712961b300e37f98704880ac0a75f700f87d67853c7a", + "0xaa4d1b9cec62db549833000d51e83b930db21af1d37c250fdc15d97bc98de7a5af60dbf7268c8ec9c194d5d5ccda3c1d", + "0x87396fd7e78c4bcf270369c23bc533b7fb363ca50d67262937dab40c7f15bd8448a8ba42e93cf35fb8b22af76740d5e1", + "0xa958b2a9ffccbca13c0c408f41afcfc14d3c7a4d30ea496ce786927399baaf3514ff70970ef4b2a72740105b8a304509", + "0xa5963a9dd3fe5507e3453b3b8ed4b593a4d2ced75293aee21bfed7280283348d9e08bf8244c1fce459aa2470211d41ea", + "0x8b06ddc3359827558b2bb57caf78b3e5a319504f8047735fcc8ec0becf099c0104a60d4d86773e7b841eb5b6b3c0cc03", + "0x9437e7278283f6d4d1a53d976c3c2c85c5fe9b5aec7e29d54a5423e425b4be15400ed314f72e22e7c44ee4bacf0e681c", + "0xb56067ee26a485ed532c16ec622bb09135a36c29b0451949aa36fee0b0954d4bf012e30d7e3fc56e9f153616b19349bc", + "0xa5c72f7f5d9f5b35e789830a064a59c10175093a0ce17654da7048827d0b9709b443a947346b0e5d96b5ea89b8d7c575", + "0xa8318d01182d4c9af2847a29a6b947feef5795fc12e487a30001cc1ec482b48450c77af4837edfa1aedf69f0642c7e5e", + "0x82ea421c091552d3dafa7da161420cb5601b819e861dd2ba1a788c3d1b5e8fa75cc3f2b0db125dde8742eb45b335efa2", + "0x8679fd1c7771ea3b12006d4a972f4f2892e61f108107d4586f58ee7f2533d95d89b9695d369cdace665f19c6bc3bc85e", + "0xb5ab3e8adee4c950fce4d33a0e2f85d3d886e60a6e2f4454b57bc68725f0cf246372d863167482cce1ea10a7c67c3af2", + "0xa85696927075ec188979180326c689016a0dc7a2f14ae02ea27c39ef91418cd44177d3fca5752cf6b298fd75fa012e26", + "0xa44f87b7232f102cd092f86c952a88afb635484a984da90a41a57a3d883c9469064bf105b9026024090486b6c6baa939", + "0x866ac91a437db945bbfdc11fcee583f3669fa0a78a7cecf50fbfa6ed1026d63ad6125deba8291452bf0c04f2a50e5981", + "0xb780d5a1e278fd4eef6139982e093ceafea16cb71d930768dea07c9689369ff589d0c7f47d5821d75fe93b28c5f41575", + "0xb025d0046e643506e66642c2c6a5397a8117bbfe086cee4175ff8b7120e4f1e6794e1e3f6ec11390993cca26d207ae43", + "0xa04a22b6e28c959ab265c7f48cde42bb6a00832c6beb2595b5df2879080a9424890960417d7d7ceb013d697d0ebf7267", + "0x81de9c656ac27f54d60d0252e33aff4e9e9e9c3363a50740baf15a2b9061f730a51ae1704e8c4a626153cf66d47f19b1", + "0xa15fab90599df889df11fa60c752948b68fba54005491180dafb66c5775547976d0eef33945e55d4818653e0818c6f92", + "0xb06f9be44ddb103a72fa4ebc242c8ee1975fe9bf9ef7124afeda9967ff3db644dbf31440151b824869406851a90984a2", + "0x99abdfe6806ae5efa2d11577da17bd874d847c5f810460148bc045bcf38c4fd564917eacb6ed61bb9164ed58055cd684", + "0xac53231077f83f0ae5f25e52b70bb6105d561c0ba178040c11c3df8450c508ed5df34f067fdaacf716f90b4926f36df5", + "0x99e3f509af44fc8d4ebc693d3682db45fd282971659f142c1b9c61592573a008fc00502c6af296c59c2e3e43ed31ec7a", + "0x98f2f5819670aff9a344e1c401f9faf5db83f5c0953d3244cfa760762560e1c3a3c7692bb7107ea6eaf5247ac6fd7cc8", + "0xb5b9f90391cec935db8d2b142571650fcbb6f6eb65b89c9329e84b10bfa1c656026674d70280ade4ba87eeaf9333714d", + "0xb0696b77ca8a0cdbe86cad12f358880926906fb50e14f55b1afc1e08478ae6376215cbb79bc9035de2808c7cd2b13b85", + "0xa51d746833062a65fd458a48a390631d5d59e98e2230b80d8f852cfc57d77f05eefcfd3c395ade1e86d4a39c2141365c", + "0x812d67654319f4ef3c9e4a2d4f027a4cb7768f1ea3f5fdde8d1b79187a4b874ff9a5c70f15b7efa079c2dc69d1b9b1fe", + "0x968978b653c6416bf810f6c2ffa3d1abbefbd06f66b6686e9a4fdce3f869e0ab1e43cce14dc83786596761c100ae17e1", + "0x98e1e6ab562ca7743783b802faeb0a24f1341abfb9655f106920aef08964a3c0e8083e1acda7ae28fed7cdd5478decb6", + "0xa91c0b982a0a7085a103600edf99e9d0bee4c4e7db6d9f8f376c215c7d42476218462a3765f2928e12c3dd49d688e4fd", + "0x8a43395b3124fab9e2438635bf88952e8e3084dad7ecb3a9927f9af0e0887bce4707084043671fc98ad03621e40a149e", + "0xb0b37626143d4a8c6f5693d5f1fe871525b4dd946c4239cde032b91f60a4d7a930d7ba28959737550d71c4a870a3a3be", + "0xb01c74acae1715c19df08d5f4a10e0c19d1356264eb17938d97127bf57e09ced05ba30d0fc1a9f32d6cff8b0d5f91c9a", + "0xb4c2328eb8a5a673406faed8f0aebb8540d2791646e37ce46e0e382506570ca276eb6f8e166dbbf9e0a84064873473b9", + "0x85cb9f769a185e3538e4a4beda9a008694e1bf8dfeea9dc07c5c40a9ceb1d31fcb13cacfaa52849ba1894b5027cb8c30", + "0x8742f91cddc9a115ddc73982f980f750d82d3760f2d46ee4490d5b17c6c3bb57c7d4c7b8d6311b7b41e59464c009b6a5", + "0x948ef86d17128a061e1bdd3ea7fcc7348e3ec87ec35dc20a58dd757d5d18037fe5e052bb359e27ab4c2320d9a52a6a0b", + "0xa70f6a214097c271e0d2d95e30fce72d38c30a2f186271fdff0e38e005aff5baed53739b8c4f9501aa7f529c5cb2da59", + "0x892a7574cf6704ad75b346c95ae6f2668904f1218c35b89b07a0c2dbf3c62173c348f6fd9473926eef56a37c0f635c04", + "0x837e85a41f39b4ded1420aa8fc3be46a7adb99305e0928c6d7643b7c44434b72984cea08eb68f5f803661df0db78c87d", + "0x94e495329f2aab3eeb68f347961d1006e69d990095877a4dcc376546233adf29a14bf6b16a0c39aa477e15368e87014c", + "0x851860a8fdf76a97048396553262637dade27f1f63f926997e74c7c72b14b10293eae7824e8dedffad1aead57c124f79", + "0x90481017a250972055ab1cf45ff17d2469517f10f18c9d4ef79a9bdc97a49093289bbacfefa8a1e491bbb75388b34ac0", + "0x983db15f7463df28091c691608ca9c51095530fa6b1b7b5b099c612e673d29e16787cc9ae1c64370ba6560582ce623c0", + "0xa477dab41014c778a1b78a7ce5936b7b842124509424e3bfc02cc58878c841c45f9e04ccc58b4f2ff8231488fff0b627", + "0x868ebba1c85d1f2a3bf34c0ab18721ea725378b24f6b6785637ee4019e65d4850e051c8408fe94a995cc918c7b193089", + "0x93cbf4238a37ccd4c8654f01a96af809a7d5b81b9e1eab04be2f861d9d2470996fb67367e5bf9dcd602dc11a3e4cf185", + "0x83113f4e696030cca9fdc2efc96ba179cf26887c677f76cde13820940ad6891cb106bb5b436d6b0f8867f2fd03933f7d", + "0x90c709f4e3359a6d215d03f45ad5cf8067aedd4aab03512dd62229696485a41dcd64e2acce327fda390e0352152fce13", + "0x9945cfced107a36f3cf028ba04c653360afc5013858b9a12fac48802efcbc198c9baf3a7f9b23dfdd5036e88bc7274c8", + "0x832ae60192b47fc735a8ddeaf68314b16256c90ab68099f58e43073e249c6939895c544a02fa34e40805bc6b5db33461", + "0x8b12c335818b643c1d22cbc2869606cf64e7ae54a7713617fc4dd3b2f052ebd6b920ca59ba2e9c7aa8cf71bb4f40f9e8", + "0xa2033eb7a373931c65d66989644aa0892ac3778b9a811b2f413d8bf534e282c339717979f9aa742162abb3468c195f87", + "0xaba2b4c37dea36bed6d39323e5f628ab607699c66767f9bf24ef5df1bfcad00c2664123c0d8d5bd782f1e14a06f4c769", + "0xb71963777535b4d407286d08f6f55da8f50418486392a0018ee10f9ae007a377b8b8336f33386b0eb01c45695c3ed2da", + "0x88dc87826941340913b564a4f9b74985a311371c8e7b47881235d81c081f1682bef313c2f86561a038757fb7d6a1a8dc", + "0x869e13e3fcf91396750150f9dc9307460494c1d365f57893fd06fb8acf87ac7dddc24e4320d9cad0414119013ea739b8", + "0x92194e292303d32b91ae9cecb8d6367c8799c2d928b2e2846dab1b901371a4e522fc4089aad8f4ee676f0614ff8b19d7", + "0xaa589a3e512cb4f8589bc61e826a06d9f9cb9fdfd57cf5c8a5a63841435b0548e30a424ca3d9ef52bf82cc83c6cb1134", + "0x81802e0194bc351b9a5e7a0a47911d3a0a331b280cf1936c6cf86b839d3a4ab64e800a3fe80ea6c72c3751356005a38b", + "0x88e5e9e3c802314ddd21cb86f2014948b7618502a70321c1caf72401654e361aac6990a674239afa1f46698545614c93", + "0xabac1e0f85d5c3ff6d54ed94930c81716d0ac92be49e3d393bed858833f4796c2b80bf7c943e7110de7b2d148463bfbf", + "0xb7eb416004febd574aef281745464f93ef835fd65b77d460b6ad5d5a85a24b536b4dec800cfe80ae98489e54447e8bb6", + "0xb3fd8ed1c30e7c15b0bc0baf0d9d1ecad266bafb281cd4e37c55edc76c202fb1e4ea315a91a2848f40f481793ae35058", + "0x86ef674ddf4b7d303c68bbfb53db00b925ccbf11d7d775ca09e458f4ecd868ca828103e8e7cd9d99672a193e81b83923", + "0x95ef414e9f7e93f0aaaeb63cd84eb37fc059eb8b6eced2f01b24835b043b1afb3458069c45218da790c44de7246860c9", + "0x93ec8f84c20b7752bfc84bb88c11d5f76456136377272b9ac95d46c34fce6dcfc54c0e4f45186dd8df6e2f924f7726ab", + "0x95df5f3f677c03a238a76582d7cb22ed998b9f89aecf701475467616335c18e435283764fb733fb7099810fec35932ae", + "0x8cda640695c6bc1497d19b9edc5ff4ea94c1c135d86f573d744358758f6066c1458901f9367190dcd24432ae41684cf0", + "0xb19aedf5569435ff62019d71baa5e0a970c6d95fe4758081604f16b8e6120e6b557209cdea0ccd2efec6ff9e902d6ce6", + "0xb3041f21f07d52e6bd723068df610aa894dfdde88094897593e50c5694c23025e412ef87a9d16cadd1adbb1c6e89ced4", + "0xa7f8d6ab0a7beb4f8d1cfef6960ebdaa364239eca949b535607dee5caeff8e5dfc2a9cfb880cc4466780c696cff2c3a6", + "0x99a565b4796e2b990bfcb234772d93c5ffdbe10453b5aa94662272009a606ba6ea30cc0c3c26aa22982c1e90738418a5", + "0x90c54b55ff19157c1e679d8d4f7f0687a70a27d88f123179a973c62565adfcc9347cfe31f54539038cf2f34556c86870", + "0x8612f34bcd018d742202d77d7ce26cf9bc4e0d78e50ddf75250b9944583b2c6648f992b635ea13fdaae119764e7c28d5", + "0xa04fb38e5529bf9c76ec2b5e3a1ef3c6f9effb6246c7f67301cfed707356ba1bf774f2867c77a5805933f0c8ad0ec644", + "0xb4800e7b503da0164885d253135c3b989690794d145182572181995e6fa1989f3d0324993e871bbd5f48fadd869d8a18", + "0x9981cd4f28ae7b7dadf454fb3aec29746dc2e0ca3bd371b2a57cd2135a7d93559e02132528ccd2d305b639d7ac51613d", + "0xa3ceec012dd1fbad3ef9f9f1d6fe7618e13d4d59e3f50540d2a57010d651092979c75442ec8b38a1ab678505e30b710d", + "0x8b97b8654d067fb4319a6e4ee439fb8de0f22fd9db5569ba0935a02235cb4edd40a4740836c303ec2394c59a0b96308b", + "0xb3d1bf4410fec669a269622c3ce63282c9ac864620d7b46c9dfcec52d8e79b90c4c90a69c32763136a7f2d148493524e", + "0x93174eba1e03f879e44921084aa0ee3562e48c2be49085de96ed7621c768ff52324d14c8cc81f17d7ed50c38ffb2c964", + "0xaa2194cd0fb7aec3dac9a1bd8ea08be785926ed6812538be6d3c54218ea4b563646af1f5c5f95cb914f37edfae55137d", + "0x93f2c0dd59364f6061d3da189e04d6c64389a3563b062e8f969a982cd68cc55b4f38b21546c8a67c8df466ff4f61f9c5", + "0xaa7dd497cc949c10209c7010ba4ce8a1efd3cd806a849971e3e01716ea06a62e9d5e122ad1d2b8e5a535fae0a01a7761", + "0xad402424b2a32bca775a66aa087580d7a81f0867f293f1c35580b9e87ccc5a2bab00c29a50fd0d7bd711085ae2248965", + "0x96237843d8e29ac77fc6ebf4acc12946ad11697de8e5f152fe5776f2475b790226a7d156ac48968dd68b89512dc55943", + "0xa45c25cdbb9fc327cc49a1666988af9ab4c5f79cea751437d576793a01c3eeea4c962c05c0947852fe0e4c63e1c84771", + "0x93dcf834a614a6f5484cc4ba059e733ab5dcc54253229df65ff5ad57b447353ebbc930736a4c96322e264e65736948dc", + "0xb9a94f82a82c0c5a26f2c1d5381afec3645e8ee04c947dc3b7ad59a73018db1e9965ab3642f2bbf60f32c430b074fb22", + "0x94eab29b3524ccbe0c4b928e5fa5dd8f684074b332fcf301c634d11083653ffee4f7e92ddbcb87ed038024954ad1747b", + "0xb8dca5f679931d6abef0674bad0639aefad64c2b80572d646aaab17adf5ca1ab2ebeecd5a526cadc230bec92ed933fc2", + "0x944d394958e539251b475c4304f103a09f62448b7d8a8eaef2f58e7de4f6e2e657d58d5b38e8513474115f323f6ec601", + "0x8a5ae1f13d433962d05df79d049b28e63fe72688fc3e6660aa28e0876a860c3dbc5fc889d79f5c4dec4b3a34cdf89277", + "0xafa5278724998eced338bb5932ecf1043d2be5dd93f4d231d05d2ea05b4455f2ffdc0eadcb335dcace96dd8b2b4926fb", + "0xb91153a2f4647ae82fc4ee7396d2ca23270ec7f8884ce9eead7e9376270678edd42dd3d4d6c003dfc2dde9fd88cc6e7c", + "0xadc932f1c679bf7889cb1ff4a2d2897d7973483fa283979a0ea3640c80ed106ea0934c1961dd42d74b22504be49851f2", + "0xa82e90761fae684d1415cee0649bb031bcb325ae0b28f128ab8e3650bccedd302a70de1a341ca8decfdda76f3349cad0", + "0x8ae353188b4b98835f4ef0333cccb9e29e1ac3ec11d554bc96f5880c101cb3c84b8eefe72f2287b0812735339fe66cfa", + "0xb8b41135bb1a1ffb64afbd83e2189e755f2c350e1273cf47c38ae9b8c4800d831436a69458b8ef9fa8b95a148d8ec9fd", + "0x96f75a04d8752fa93dc1eaf85ad333cff4eeec902a345576139e16de3a88eeb71b6726224349bb9844065cc454d959e9", + "0xab82b05e3923ad4c26f5727c60dc0d23063c03f5a4fd8077da66aa87042cad1bd99586d4ab35aa5e4ce6f4da6fecf3c1", + "0xa50c83db91c26ef7bf1720d8815b41bd056b49fd99710943679a162ccf46097a7a24585750ece886e38eb4fdb866fa37", + "0xa719f667914a84f62350dcc6f4f30b9ab428eac6837b70318c3ac491c1e69d48af5e1656c021818f377d911fe947c113", + "0xa148807aafddfa0a5624c7cb9e42468219e4bdb9994ec36bc19b6e6d7c4a54d3a0763d13ca80624af48bbd96d73afca5", + "0xaa012f205daf22a03e9fb13a63783dda7666f788a237232598d02a4d4becec7a699ab493f78d722ce68519262924c708", + "0x97fc15fab5952c5a2d698fd6f7ad48aff1c8aa589f7d3b14285fea5e858c471cf72f09a892e814104fa2b27eb9771e73", + "0x8da8840236812667c4c51c8fc8ab96d20dae8e2025290b9cde0147570a03384370b0fcbe20339c6aff09cca5d63e726f", + "0xb477d85359a8e423fed73409f61417a806cb89c9a401967622aba32bf85b569e82bca1b3394c79e180114a0d60b97316", + "0xb3d6ee2ed1e4c5cf8ba2c3a4f329832e41c7fdcbcda8a3fcbe8f60967fdb1717665610b7c1ac65582534d269d762aa09", + "0xa0b3b30b1b830b8331ee19f96b4a4321a6b93a3395b95d3a895682c65ec6ea64774b878b93514eaf353f2e4be28617b8", + "0xa2b88e9617f4d30ef4e686d1932ad43cd555fadcb5102e51bea19e6fca649284ccf4debb37b5cb2090ef386fa5bf5327", + "0x8a4446f7e8463ea977a68d6217a9046ad4356d6fc1c18d46c5d2ab681ea977b8faff136d65abea6bbf8936369cb33117", + "0x91e7464bc56e03f436228104939ddd50caace5a38f68817bb2991e193b57adf6835152bbf3dbcdebf0382ac9823f60c9", + "0x961a441e6cdf8106c4f45e5b47190d35644faec701c9cfc41ced40cfdd1fa83752fd56c1ac49131a47f1970a8f825904", + "0x94b7b165cc71c2ae82976b8f03c035fb70e90028992b853aa902c0467b384c7bcf01d56166bec5def4453e4d0c907e52", + "0xa5d32cffabbf547f900026b34ef46f08075b7a244565f615370d2f04edf50b094c95088a4a139ce07caf55bcd99afa07", + "0xb4e06e73660745f75ab2f34d9f6d2675b58f80f911ab6dd4c5a6ce1095f9a2b50d86f6ff9a05394190bdf96af0827920", + "0xad3fd8f83c0103b29d41319209dffca201d2b98094362da08da3fd6ff0ba96796b49d6bed525c9adb96c2954858e7f48", + "0xb0c27430695f0fd20ae31e1ec621da090094f2203e17411db9384695ffcf5c7c6badf461ba49ba70164aacebd6f278ee", + "0xb9bc6e972fc3b532fd2b1eeafc4bceb77604885f32132af6a9a842fa2440df452f49ec0cd9d86da1180e8deb0723b260", + "0x9729e22d6104b0174c136a854920f542b384d375040adcebe36acc253bdb55845eb43e34dc5a7cc27d22c417973c24d0", + "0xa8b420b36d48786c9231d454468a6e855dd7f71dcfd095efc9855ee70dbece0f06ad277f7829c5813fc30524c3e40308", + "0x8757dff5499668c93fc5d9cea0a8db61817b8ed407200d623030b5849a913d12f8371b667cfde8d8082026eda7407e8c", + "0xb859ad747ca5af661fbd03a1a282df6e84c224ecea645bc2d4ba5e35fa06cbf047387319fca0cbc76b712398c0798968", + "0x8e3173c27875f1460297af0fa736c945dc842ec3e476a973d3d5f790bf183ad3ffe96ac13868c5101d8e299890791864", + "0xa9d725e2b92c878be42b5eecc2c3081c63c7231ccc7e2dee17ca6a4caaeae22788fab1f1465fcbd7fc236613fc2bae4c", + "0x86f6c4f04a354cb2470ef91914816fd740f8d5795ce7ff981f55a2634695fde5951bbae7a4bbc4c63747040f8644170a", + "0x851773cb26f320f0c3f252d95ea7e058ffcc795dd0dc35e459aa1b6b448238909230d809e82022e64b7fca5d40b8324c", + "0x8962641e0306220d9892fe2d452caa286301a3c465185757be7bce2d9b2c9beb3040280099606cc86773e43941fd3439", + "0x8beb6e08c440b0de5fb85251d39d9e72db4e556a2dfe3dae59efd8b359d08492064cebd8d8993254b43bde8bd67d969a", + "0xa7e047894466ffe3dec4ab8d5462f2b1d8ac0df006b1d2dd26caf499ea857d93a811cf42233f9e948c9cb903beec004c", + "0x92eedd95557a91691a5e2835170390ce2401e223da43b78615a804c49566f9d31cbb7f10c8a8390c4bdcf691544fdba9", + "0xa5e5b5d8fa65824e958bbae98d146b4b332f97ed50e0bc2c58851dc2c174ab71bcbb1ae015cd2955c26b368487dd862f", + "0x853a494eafb308175629d581ed04bed71bbc3af9ca4c0dc483d03d27c993a2bbd88cea47c2085a6928d166fe6938fb77", + "0x83f06b88d29afbfbe8f61811690322ac4fdd6abb9a23612162e7a2dd6bcbb5f14cee298ebebc1a382484f7346dc51e60", + "0x8c9cf05735ea5a0e563490bdc7ed29a4426643711c651e35c8551ca6f855c8458ae8f0933a022d0bb9a952edfed411f6", + "0xb906b48d807748a26cc2a8848455a76ce502261afe31f61777b71917bdf7de2fece419db636439478c7582058f626c29", + "0x97efe1fa7c9b25d8bea79d74b6cdcf88f63f1e865f54b58512a2e60428630b0b40b8b6af1b5f71df47520507548c3cad", + "0x8ef5ca6e753818906bb3fc71405928d8e4108854ef0ef01c1009071b353bc2852e771fcb619d5fea45590e8f61003d7f", + "0x8e4d901661e2913740d70ba4d0745df5e8c9c0a260149d9362beadc7e669630ba909ff0e8a6cc85c54d6b7435d0d351e", + "0xb7c6ba3bebbd9592967954e3a480ee8df1d9f5965f04e7d78a5415b645128deae7ddaf6ed507c8877bfca91ce078e529", + "0x840bedb0ad4e25acf6cd25dee4f98fea495b2312dc5cb7a8388c5ab00b2acb9cd25da08e9fbead145a3107972b1ccd5d", + "0xa8d4578dbafdb27f3911af59962d89e75dea74db55346720357790da677312c203107d9c7911535aa563446fde7d4c47", + "0x86d3b77f231bfa09251b7fd2ce09c27ac520ec35d783e912476f9a4863f83d269eb175790d6e735da9260293d707f8ee", + "0xb34909f1cc033232652da0c34051a769dc76adb1aee00674a59dc1b860f6e610974c3b4bb69a69ccc73e01f042431242", + "0x90799854d0cf34e1d91ff8e101bc7c5007423d34d2f3bd9adea2ecac57e83f3a65a506bb93d4caea49b29f6d18149957", + "0x8ef94cde29b037e19a1ce7bf4418ad3c95cd9457412796ea385750c19a6690f13a3bb5bb6a9ee81e7a40face1e0a8bca", + "0x97053d21ae8d75972fb37f6fe516c38c32ab162fb56b9f510f954858f4e3ef6ac8c3a9557ed3f41b7b6aef05fe97f931", + "0x90a9f9f0f40991f3bddc58b92d40382147db22cce50d092d4a05aad251b46b94e71ec9f7107a180243288059fcc5ce29", + "0xa14265b1344ac2921b0f890d13bcfc432e4f648ce403e261fce4d3bb32ffee9e2794c02830346054f998e82784c77040", + "0x91928402ae121e56a3e64cd6f390127e6e92fbfb1967ec6efa4f52f3e8058f1f41a0f4fe96b5bcc11641c1139e790b2b", + "0x921c8c92b6d40da6c5a7b592acc74fc0f577d93767b9aa4a1cd302a72dbf503a1ea5b2c29fa0d0359bff3b8f252246d1", + "0x93ae0ebe0e8e133fd80cf67a499047e30ec4c4660ccec9d49098717ef57721a030f423e00c5e74af4ff4acf014a10497", + "0x82c865e21905aebfe0496af1c6ac7e342b5f446a9edb4f7da0f2fb0340abfd8e6fc545da874459d9aabe6bce0dd9bfcb", + "0xaee3961d8d2687c0f134b9c28b920bdc4021d925fbe14323c84224a9fe161248789249fb85436a5891d0bbff42c2a3e9", + "0x91aee420b98b6949482b8ff4be996b97245b4e8f583a6e085226539074f42aa89818395efd1a6699735a569bfe19d623", + "0xa48eec22c192e495b01722d0016a54acc45ff837e2a95c4294ce81d5a4e43e0053a6f0ead8a4fb3ddd35faf6607275b0", + "0xa26e15937c11faa30ffa64817f035e294cab0e839f73d29de8a244ad039be4e221eb47ea08d9a4658b0152fc3caf6110", + "0xb84450f948aa7c8682fccb9cae84d8e3558adf2d0ca5fb81eb200415291158720f8f3470542ab5b88c6873ad08e7fa9a", + "0xa8e8ec27d0608d020169a85d6ecdb40eb402f006a3b97afe32cc01987721b3a68a92ec693aeb4d357e189e05fadf699e", + "0xac87cd535ef5699312cc26f86adb71baa0be42e858bd5a2d94ac05737dac63430691e29b9a30d2559ad581a172519b2c", + "0xa4481e67b524f8cddf2046625efd3d75efee6aab87ddd2c1b22835647e918157e5e924ac760db2195c86d326f3db1615", + "0x891f29ded231486ee826840c8895cb325f7e84a5a6d2eac246cb3573612cde274720233b1978318a57ed337a046330a6", + "0x906b6e750e6178289012769807d2598925d7e51c260c14497d8af978b1695990e3352e6e809a752f376597a68083870c", + "0xb7a056898ee1e46f7f29702fb39232f678ec173eccd170303b3b0a30c8d8cf1a5321384e3513e3b03bb742c238deaa54", + "0x8f2f035fd96c3a336354c89ec9b8222803bf42e95fb2412c28d4e75eec99c1d4d402501ccae17357b757db8bdb0bfeab", + "0x81228625ffcedf977fba9cfa13f6edead3985e2651d5974789c394a69401cd7face9e20ae6694be4c0d4bab5e99c61a8", + "0x885a83eae25e61439ad809567a2ab148583402e01cfdd77b0e37ab4038935425c64b4e0886949bf06438c35e80aa13f4", + "0x8926387f48752f6933899c48e038cf14e7941ec6a58bcc0a436614b396296a17aa53e6873803dd3041dae470bd493fcb", + "0x95d0d3fa061f4d856eca78a569aa132db14cede7646f97e2aceb6da0c8ea53195d3b7a566fe5ec8c41b95ecdd89a1c6b", + "0xa3c817f4062ed6aa94064ea695d76c1825f3bf77b310fe1db28b8bedc9aaacbf1019dbd128adfd53042fb943d863a2b7", + "0xaf1208417aa584052da309169854149ede38a3ad63c76cad6e43afb6f1a7b854edf8310a0b00088c039259cedf0f859b", + "0x8b713fc3196bad35dbf364089049ada5477e540d78d76a5f0a9df98f7ba4a0e65dd0644509c149f9b07887298bf74b04", + "0x89c09c43c5b733c4a417cd9ebc0795cc3348b72778d31828a9171427779a82ef023c1a4fcfcdc919ae25056f9c826fde", + "0xa0759c850ed320c8c874435e90ace6edfb8e7b3f2a09d942b8ad8339c508044ee2ee26c70f1b626ec49a77971433b6a8", + "0xb85cbc58d4fd52286e714ac4eaaa0b2743a1de06fa03ddf8f6668ec6f1d204acccce93b10620272afb8c0b49bc4b0a43", + "0x814e0a87384e159892a8d23036985fa3f489c53bce192e107bd2d64f57b1bf5ea0acc1ef46c7a42bbc5cd0924d92b4a0", + "0xaa6821da96ad89d7881b878e141076522f104ea9a5bbdd1fce9f641898f7d6232c518a87a0f666871d7e3165c26081e4", + "0xa9041d714bfc067b5427252186fa3557bad598fc0067dc8521aa9bc1ae298f6e96113db5ac9f6bade9a85d5a950c9755", + "0xb8669340f3064692625e1bf682d34fbe69a61689e3aa6d6a3e822c781d406b0300dba9c3f7b8152a8c2513f1310d4291", + "0xa78c53316ce768a1dc5968030bf4fc885f4029b1ddb6a5d84a61c85af686c73727f62823891edfcb6ccf4545de366cff", + "0xad1d3aa29ea28292ddd438c865e2b5d93f32cdf009e6d5f5dc726de996583925727e6348bf1c28c22dec0bd86aaf867f", + "0xae1447a2062e9e28af5f38aecc60fe150cd10c2edeaf2110034aa144f6235ed7fbce432a58805d4fe1f6b12652d6e1cd", + "0xa32146634332d3303934550705353c6d4fae5fa5985105bba35041e74cd71e2aad67b45da171221f6ed80f36bf6dffa3", + "0xa232e8286184196ea77427b53d8b52c44d758ecc42d22556529db3136379b4989dec61cff610cc6cf6700a450a847a94", + "0x8a72c7255125a736da52dff5f77e44c3de29f88fc05f5ff9227c69df296930caaa11446595e6bea3bd946baac5ef957c", + "0x9688a981a9457678067f629f8efa6b522e7318b529f88d37ef56c5bf8f1c34fb9bb3a918ab73caab82bf5abb0c03518b", + "0x88286f3eabd71115fc3b17a6bf6981340a81cf7e5f96b0a1a016d4ec8c18fb486d46c70919123d0c189a6f5d6ff29a1e", + "0xb535e701b40d793c02ac0d625ca91620d3f4a512aa9741f71389e58381008b2f93d597586d06213c4e103d67d0ddf6c5", + "0x80d0c9dd941e8d8d3700cc51a434a5aaa3308cf8ebfd14128ccfd258f826b27cc3cf5c3ad7851340393abb1eeab3a157", + "0x87049225fa2380d93f18d3d90cb0697a56b373b66d7f24ab209966aed8b55a2790194d5885399db29dd5b1f189eda64f", + "0xa52df158ce8670e0290551e8878d63dd33b4759d6f50e448e63fc7fe6ea99dddb6f180be5fc0fc3918ce54c05f80b356", + "0x8b2a728b39c465fb0f60b0c486e5dc8d5845ccec03d3dd93b393cedeeb3fe1b44518359f1ed55fc770a8f74bfeb9923d", + "0x91fc05419dba718fa4a910dcf256ebea356bbea00522d8d5ec3e7ba4271a26035aac15e8d9f707969df1d655d92dac55", + "0x97c8779ae80c24c1f82d5a714762d6ee81069224e39515e41d8a71c9310dc5d1c55cc92bc5c6a4bd391ae4c321d1d4d2", + "0xb5e5aedba378c4484e3a7a4ed41b75b0844f674261c2501497de6f91f7274b5a4c1be0e055f2e0c0cab843d891169fbf", + "0x8a26212f27211b295beea500abc8e9d430a8500d3a350cc62f895d39e8b4668aa638c17633804ba353010000165637ae", + "0x864a95118e5d394e00e99efebd505df0125525c9ebe165764c453b80ad3edc730feebde3d93850745dfd88a27bb8f20b", + "0xa092e0b78290e826cc1ae56afffdd08f7c10954f549a3ea6666f3db1b6cdaeb7df53db28dd2a92446342930fe60a27ce", + "0xa1720224c0626a081b6c637b2a6d37da85d9a82241e5efef3bc15699b02a69f6304e43d8ff3144d60c16e00225d6b39e", + "0xa7b3d098cebea9cf32e19c5195608182b6afe9d4af6b9df532c047eb7a941a971279b2ae6a4b80f2f9d9313a6d788ce3", + "0xa3d2451e6788944802c5077a778d7b7299dbb9d1612676bb6baae78f39976e0fd879493cc4a4d737b8174b472a456850", + "0x930121b73da844571b1411d56760e80923a4ee09917b3e9cff4d3dcb0bc27026ff2c4e2c44e7aca7d3f8383f129c7f9b", + "0xb4b0119d163ee00a2b74bdf188a5cdcf054daaa48c483b94bbb4d09ff615afb4a91347db6363bc7535e2af9054ec2214", + "0xa5846decee706780201095a8cdd48fbf3d3a2eac8d089a818e5e22c29457494bbfb4399323b067f3d2be2197c33dbd98", + "0x96ba600df10ee7af5a9df29c0ca31dbed275d647faf9c66c7342de927ceb25b5bdd852dd7aae0228b27897f90fdd5d62", + "0xb6ac51ddc98edd9fb9f54ef84bf372a041d58dfdf0dfdbdc4b08ddc1a7ba93ddbb1413dda3c1545a3fd7386c6b85975c", + "0xb35f3efd91a0723e0d486188ea9675a3462106470455118392d7610470b623caca2fa33829721c05fbeb0fabcf570bfc", + "0x87f49e85df5f8055714a8ce7adf37f6a278e64e76ed74c60abe3edfc3611ef5b0426d4c6da45e5f3b74d30be1dc6f539", + "0x8ff8bb06902a71b1e9177a77367318b2e3e0a88f5d74d6907ca9943f4f9f1ceb5f297132c2a025259d17a67e880d1bad", + "0x85eb6de6c70fe5c53ab0ab27aa0fec439f136c979c557d317337cafa6e6c5cb3169679c9169567dec5f6c72b3c057d83", + "0xac18715ed1080771d760cb7066c6328faf65d9b30517903f8a5cad8d66d5c6381156b521107d7cd75ebb8c30e250706c", + "0xb95b9eae4703727e4ac9ddf2ae675906487bb78905a5f9cba74a4cbfd118d96b7afb6ef3ed5edf14fd963b830d71338c", + "0xa3b47b52fda16b62b11c8aa4daa56b0b669c4d5c56a3059b7d063284d8a91f6fff9ccccab23d6ceb9650483b2d353039", + "0x96a95b3f327df94c85e92f2e406f1649ac621533c256b062738f3c3ee137059a735a3e6072247acf57b1b0d8c219bd7f", + "0xb19b33cc04570be94eae8e943d5bb17bb0c96e9de4ca84f9f41b37320a1a03d397d53747dc13275fef1b356de557214f", + "0xa1faa3dcb931dd91507f3f12a17c43f6627fa2bc5c71fbdd27548e091eaaaba262477949cd51290e81196bffb954a492", + "0xb060a16079dca1d28a1fb33cbc26f368630ee042d980ce305230005d5b9ab533a7a695281ab76e9214458303932d8bbc", + "0xb303783196a858fe45d67e0520c30576da605fd69964449c20009fbd5099cf1de52a32d326d7c3b864de07440195ef40", + "0xaa550a4c20d1003d137ffd8fbdc1196d09ad53cfa0e202302093a80fa3bbc4c9aff83f34f2151785cc1ce5f30255693b", + "0xa7f8585f45566a351058e10c6f1ff4a7ba24811f1482a47202f581525615ca770da93f2f58878788b45b92cb446ef4ec", + "0x8206f63a9a5b59bd68e64a843e68fcdf706f4c13bbfcdfa9928298e5b9251006ae0bbd80c715aa3c9957d2c0148b5059", + "0xac9490abe1241319658f1c2c645cfa01296f5d4106020c7894b7ba4a65cdd52f6c5401bd3b3cf1c9863e088cd8c9a16f", + "0x85dd6d9c80a1b58c24c4d2cb7590d33d2454f381f58e820979948e5831972360cde67bbd56e1860077ef5192fcacb904", + "0x8b0285944c676fe2519cb68da0973275fa29c0718d838d363ce46651b068d29f867cf9fe579ff8da0bb8b37d202bb23c", + "0x95147275da658d43a758b203b9ca1f1c1478853e9bf77b5218593142e2bd9c0bf46d2206ab64cef99295de6e9a268edc", + "0xb8efa187fdd3e1f46c15cd596e9567690c10e253b5beaa5be8074b6ea4e6d3d06e0f2b05323453239e419ae1e7128521", + "0x8340464f52c92e31806fd3e8e65f56e27194d1f6daa4a0f0b3831e8102aba16f88bb5a621633ddb7dd0342e1d2d12343", + "0x8615d87dcab85a78dc052f05a01e751176b756b5dc9985014347454ce5752f459dd6464e1c5aff36cb6c51b783fa2692", + "0x80c6e35c0d3defbe4d3968792724a23f0b8830dd2fac58663583a49339ea20f1812cc4140e3ee867c7e716177319bbbe", + "0xa7aa63dbfc201dde8f29bb6e23d7aa5020dd35bd18a0cc93c8a10c35d695913fe25b9e8cf9b5fd1899e9657b22bc8863", + "0x97c2a4ba80c4caba2e729a603d2faa0120915e3fe64cbb065f7ff33de5f877f1ec9461cf455e88ec9e9ded9393939dba", + "0xa54bd1419f0e2d2d87757870f37c476c7e3a13502f1ada82fd7394fd29f8a00c4986473d753034d0954a2550badbac0b", + "0x8d3e2bf900d0d2b9b46e6e2f37620f0cc90526dbbcfaad4e4a37ed53f39fdd23bd3a6f21aa7e800eaec937d9710dd6e3", + "0xa88d2b1c7802b2dc216c2b6532406c091bfb12f29121b9a82c1154470e250188413ddd3e79f7e009ea987a4c45b332e5", + "0x8c552c2101dfdc3f99c2da436115452e4d364eefe029b12946f05673c5ce1cfb48d39a579625849236dc6c8e7277dd30", + "0x8415c252d52a26a6400c3189c928a98559bf24162ecf3eef1d10e439269c31d854b0b4f6ec7a2430e3f11b5d77de78d6", + "0x8b38905bad93a8d42339dbdb5e510003c51fcaf05e04f88fd7083753353bc1c4c00a5dd4a67431cd4456d0669c7040e2", + "0xb1d0ed8862250d0f0d9ef9dcf0cd16d84313d1a795dc0c08e0b150dadf9ce73d32d735e04632b289cafa69a6ee75dc89", + "0x9434e18a5fb631b10edb02057f2d1fe16000ee55ada3c26a079c9fc3943e29d6de99e52829fe7b333e962270c712e51e", + "0xb1b9f3914007e6fca8ad3e7e848a1108988cb2318da36df24767d804e95d1272943fda948451135cc1b5052a3953b081", + "0x8c02947a76d7b6c0a700a83dfb971dc105bfe996e18c521445f036310914b349ab28e57571e36ae08d13a46fb01c2f43", + "0x893472fbc225f973a0ac6a0a0130b9cfb7ab6869dff80df71a62b1f6beb4afd069bbf35b4f327165bc31dff39e4fcaa4", + "0xa7c176c0903175f3540d62f9afee994d5d9bf37081e094644b22f017e94c515afefde7bb07f638342abef7de657f8848", + "0x860186c2b1d3b1e657729bc804275fb5f5ee89eaa60848fcabd3871289665ea9f0efc8a95792d884972bcfa2de96223b", + "0x865b38aea6386d0ac8f501a7d934e23d01dc50105324e354d4c4fa3cb1d4c29c26f4566df7b1a728e10cfaa9d24552e6", + "0xb4eea5548de6969dada658df604b5d9c49002e2258352838003e0fdf7b299d81fb025807a7f37cf5b547cebd7f2c1f93", + "0x8982de11ba68d63a649a3b296d4d56c71e3c3eec016db250d733ab7c3b9a620c09c5a5d0b64fd30d3bc03037ca4b17c9", + "0x84d8b8a10d67eda4716673167c360fc9b95717cf36ef1d5bc6f2ef5b9d2624f0e76c2a704d016adf03e775ea8e28d83a", + "0x834d03ebd51aff4d777714783e750b84c16cb6627f8311bd8ff17c3b97fc4a5bba57d6c8f6d74f195d3030bcb5f07612", + "0xaaf49e0def0c4d5f2c1e9c17b51e931d2f754b19e80070954980b6c160178349f6d3c8d4808801d362e77f41a0008918", + "0x8ef4115edec841854e89f2bbd11498dac7396bca35dda554290d3db1c459ffc17be671f4a46d29fa78cbd6064cc2da20", + "0x9641dc8a64f4acd38e343a3062787c48c312f1382f7e310ccea3e95e066ab6dc980f6ed90a633236a435e68bf6b3c625", + "0x8a84cfc2cbeb18a11dd6c2a0aebb3f6fd58a33bb4b26101e826add03748595022e816afac79a4e7c20b3805252839dca", + "0x9770782d729017659844421e1639ffcda66a2044df9e19769b90292df87dcb146b20c6b9141bb2302029d84a5310665d", + "0x98c7ec9696454868ac52799d1c098c15ec4e08b34884dda186ebfe87d32840b81fd3282295df141c91137faf4cc02da8", + "0xa3f6eb921247617292162dfc8eec5b830ddc294a0fb92f5b4828a541091ffdaff34c392c1d7168259d6204405d90ec72", + "0xb185f77a468f07a54222d968a95635234e74fc942485604909308a9028ed2753b15902b9134749f381f7cd6b89cc8c3d", + "0x867608a682d53bd691dbc92eeb460d1c300b362ca49c11a280f6768ccec217f1145f9d59fe50d994f715ce89d38a74e1", + "0xafaad630ad8827cd71aade80edf3d7aeb65a344878db12fa848759e6233f6fceca563aa437e506ea9e0f1e47b126d45b", + "0xa12afbc84e3441594aecf85d089423dd3bb8bb33a1a384ddf7cc14caa72284caaa56aa179c15e3140fd56bb532491a67", + "0x98757b0b5e5837ddc156a4a01ce78f33bb1fce51e0c1254ee9b6d3942268d0feb50b93edbf6aa88f9ea7b3c0309830d8", + "0x89573f4a4ae752e9f964e42bec77d28a41840c28e4bcdf86a98a131d0b85367b885077823a6f916972de6ac110821bd2", + "0xa17f2745052de5de9c059307308fc49f56cb5230e7a41cb7e14a61c9efa742ee14c41023ce90c7f2261adc71e31045f8", + "0x914b07c53a41c0d480083f41a61c10429ea42dafea9a0db93862d2269ff69c41db8b110b4768687b88089b5e095523cf", + "0xb380cc3e0d26370976fe891d24ea4eeb1b6be8cfce01f47fd68838a27190e644fd57b049d3aa0a9589370de20e276944", + "0x906385fdfad60feec79eb1c303e750c659ceb22d9c16a95faaae093daadd53e7aa039a45d57e20951d6e1ca0dc899ef2", + "0xb5211ceee31b194dba60b616bfd91536e71b9213a3aaaf5aaf9b2f4cbdeb05191861d78b97eec58e3c81abe4f0488c04", + "0x97878e9e38c2f69d697800e7a2f132fc4babaacf471c79c26a757f771606e55fe696ece68a3163a0ffeb2f72274cf214", + "0x959431c1f54c46500c05aaa9a2bc4230531dad97ae768fa92bb85436c0ecc6374cf20fb0ef82d122db116820a943b401", + "0xb69e5a1c6798f30d33e42cb8d124f025d2c77c993c4c7107a539aacddf44d8d4d2239e802ece32e60ee4dbfdce201bdb", + "0xa8b09e5e9f802ad273b2efa02bcbc3d4a65ac68510510b9400a08d75b47b31c6f61ffdb3704abf535a3d6d9362fc6244", + "0xa41ace7f1efa930564544af9aa7d42a9f50f8ba834badcaf64b0801aaed0f1616b295284e74ca00c29a1e10c3de68996", + "0xa8f2aa0bbbc19420a7c7cec3e8d4229129b4eb08fff814d959300cd7a017ddb6548c9a6efebad567d5a6fde679a6ac6a", + "0x9683da74490a2161252d671d0bc16eb07110f7af171a1080dc4d9e4684854336a44c022efe3074eb29958ae8a1a14ace", + "0x8ef44d78d10795050c161b36afa9ab2f2f004ccf50fdeef42fe9cdc72ebb15a09389ca72a00001cd6d9b1d7b3bb766c3", + "0xadca54f3b14fb18298098970b0267301b7312afb75894deea1b2afa3e85b7a3b4efac9971ab54c5cbecba2da9f18507e", + "0xac5d4528f06fdccfc1370d5c3d03ed982fed0861a93a3f6453aa64e99360b124926d1892faaf72d89459e663721dfa99", + "0x98aa1c801bd615b8cba728fa993021e181e0ad717ba01c0290e7355694155407083eb53cb70819c4775da39d33224db7", + "0x8b3aea4c7c2bfe1020de3261ec085d79c7bf8a7903b825d2c70ebbb84af197bcc54e3653c5373a2045c3021526b63b66", + "0xa29f3de4cb3d99afff1daf7d431b38a33a9804fedc41626618928ed059df6f6fe9f298a046b594ffee951ed4d4e1400f", + "0x803fd346be540c5242667c18ee41b26bc812456ab13ff117196ed69b90ee608c8cb6554396b64066a546ec87a71ed6a9", + "0xa9c18d81ffd029c0339c72c499bb51685392253b996b6eabd8b76f05c6191ed8444a1397d63b9923743661a319517f7e", + "0xa048d5c390d08f07161faac71c5994baf152c883b205f3bb10d3501709d6516ae54d491b486303a11b751857a31f0052", + "0x9156fb4803e40e28d8d57d928481a8de4373687288da44fe88c5676a8ae013ed1fcc09d56a31140bf74e7f767253810e", + "0x98e289c725b18e0085afdfaf2acbc674dae7b0a2ecc2537a7d0b87e20eb785404ab05973a787f0495d2adb3e5565c09b", + "0x8a7237b249325bd67cdc1f9fb278710069033c304afbf270b7ea24dbc10c8eabe559a484d3edc733c77b4384932deb41", + "0x9056f2e5b02e5c2e04a69fa1323bbf1859d143761268d18e74632e43800a2a9c76fd681e924a19bc141de0e128d3e462", + "0xb9f2bf9e4e7263014296a82b9ecbb05d3f1efa4b2e675e3b38d3eace59da06a89c859256e1b77847886d6aa15f98f649", + "0x83b22949cca19030289bbf7cd2a0d8b84e1d468e78bc85271a6753241b89122627632723bc293cf904a5eb2b5dc6c3ae", + "0xa919aaf35dd0116168d2ee845122026416bec9633df113fbd913d8db5996221e234f98470d029a8ff182825b59fda20a", + "0x91726901f49d32b41afa15219073842278f60dcee223640903d871e318a1c2b541136b7b38a7b2ab7d31e4242fc29674", + "0x942b77666545bc9a858d36cfe857ab1a787c9528f4a0b87918a06bf510793264dcafd12ae6bd3ee300179dab7f40aed0", + "0x80adc1f2f9c47a96d416e44fcba41628abc0fae1f88f6a26aea4648419ab726f7fcc2187c7d5145e3d8f5a75c03937f4", + "0x8041e0f66ba9dcee01e336dd4d16ae5e4e1618512fc147cc8230003aa2940848162dc2187d4130bf550dc1f3559849d4", + "0x999e8adc51bab54386af1c5e8822986ad1b7ecaf1f8a4c2baa5bb2fe9d10710e49545c5a8bd89ed0e61a3d73a908e5ef", + "0x89272ffd39b6e9f99fafdd58bd9dc00f66f26a1d36b38a1ac6215e3546d966739eecda7fc236335479207cef95cce484", + "0xb8e0b7532af13f15dc04a0eb4ea8abd67e58f1b1c6ad2e70c0ffa04a5c18ec2018b5d7f4be2f9f86db5e0b3986f639d9", + "0xb96bd11b0f6ead4abd5fe1e4c6e995da7583b901afd01cc05e87d04663fb997997d6d39dd9fb067c62cb1b1cbb67516f", + "0x94ab08914088b973e8dbd5685decb95f3bf9e7e4700d50a05dbf5aaac9aea4be2c10c83096c02252e9238ceea1351d05", + "0xa188de419b062af21275d976494c131ba18d2b2ead8bdbfa38a777832448e64d4d9725c6a1d530ffb6513f18d5b68d9d", + "0x8f73c8c118fa25c76a4ec5611351953c491452743056a819c8c82ba4737a37d88da0b55f837e7239a5f46d2c05a1bbba", + "0x894a44769e0be1c26648b0d89c4c9f46dbdeb3a71b90c493093bee372bb9f2d3f319850fd886d51f4f58db0de5641742", + "0x87d239923b0db024a8d9b0281111d47b0761d81c50652268b074efa3ea70d793e30f874a91ce33a4acecd0cf38c01951", + "0xb1b48b75a97f9fc2dc9530dc69f6268829dd0ddd574516e7eb1b9f5c3a90058889a7bcf3d378738e6d4b02f5fbfa44db", + "0x83e3ee9526ffcb60c6e75b75550fc017912ec0daf96d0a0d5f58c1b229cce90c684ac7c3e17fb998def8e7e2e155d750", + "0xb9b7bba579e474b0abdc7775ff5f84c9f117c6ca17788cf5a5f01b2c35a14aa39036031c8d799fec2cfb371d9f7471fd", + "0x90d7faf4891fbc368a32f575dfb69f13e37161ab4f63a7139be103285a49490c2851a907f8d36e09e7d1a190dddbc6cd", + "0x968c8b9affe18fc34a4e21f0d8c5518341c566099e6b45b8721c9912bab3693c9cc343406fe90279692a1eef2a3f7311", + "0x8735baaf4704207550f77df73fb701d9a63329993a8cb355ccc0d80daf950145f37e9b4b22be2aba29898e974f9fd552", + "0x90f52b2dccf525b9191d836b205ffe966d9a94f6c5800f8f51f51f6c822619e5abdf1257ee523597858032d2e21014ec", + "0x831209f8f5257bb3eb452d3ee643d5f063299f8e4bfea91b47fc27453ac49fd0ba3cf9d493c24f2ca10d3c06d7c51cd6", + "0xa5a4db4571f69b0f60fb3e63af37c3c2f99b2add4fc0e5baf1a22de24f456e6146c8dc66a2ecaafeb71dce970083cd68", + "0xb63da69108fad437e48bd5c4fc6f7a06c4274afc904b77e3993db4575d3275fce6cffa1246de1346c10a617074b57c07", + "0xa449448d4156b6b701b1fa6e0fe334d7d5dd758432a0f91d785b4d45fb8a78e29d42631bc22aaa4ea26f8669e531fed7", + "0xaabe43de1350b6831ef03b0eef52c49ffb0ccd6189cce6f87f97c57a510ac0440806700ce2902e2e0b7a57b851405845", + "0x91015f144fe12d5d0b0808c61fa03efe0249058e1829bb18770242f5fb3811e4c8b57ff9cb43deccfc70552e4993892f", + "0x8e9c570811ce44133ce3e0a208053acb2493ef18aade57c319276ad532578a60d939ed0bde92f98b0e6a8d8aabd60111", + "0x8b21839b5dc1c9a38515c1076b45cedec245d1c185c0faac1d3d317f71f1bfebba57c2559bcdb413d9d7f0a2b07f3563", + "0x90413bbd162be1b711e9355d83769e6aac52fdfa74802d628ff009325aa174c68f5329ddd552ef93e8fdcb9b03b34af3", + "0x8b6b02e3f9dd1031ebd3df9a30432a3c86e64306062ef00a6d1243620d0cb66dc76f8d0d412eceff877ff8768c2696ce", + "0x9894b41d9fc715f8f6addace65451f41dc5ce7b983dd8cb33757b4d7259bef12f144e0077d0b662aa847d5a45f33c563", + "0xa353a9740f6188d73aa4175a6c5f97898a05ed7aae9d2a365f15b91dfa7c28b921fdef0a32d90b6fb82718b33d3ddb8d", + "0x984eab8faed87c403c9979f2d2340fb090cc26d00cb4092aeb187c3f4ee1df3f57cb8363f7764073188790b16dfc464b", + "0xa5c5ae0ba435fb7f3ddd5ad962358da326239ff236fc3b51bd22e88296236b109951cee1b98f444302badc58d1b5bfbe", + "0x880be1006b0156f2788813432f450f613d235f41aba52a6000d2ad310408ad73d86b79f6081aef1e8c51010d404ba670", + "0x937da751aae68f865c7a33fa38d718f20e2a1c65cb18c8e08f8441f0cdc77662789d2793794dd0a427cad30cd0b33f42", + "0x9496fde66c834ff86f205897db12bbf9a9bb78d9ba8b5fb539cd0a2c927cc6b4120c017b0a652750b45edbe5f650e5dd", + "0x97a6f409ffeb593e149307a14bc47befb632412d70565c5f13d6b7d032acd2e3ed0f7b6af701b387f11d69ee4a8094d7", + "0x97ed94934263dc0260f4f7513745ed3483cdddb9adb85dc33193c3a8b4d52affaf1ded23b59c34651afbffe80d40dc36", + "0xb2b26378d44f916bcf999db218b9892e06de8075f205c7dafd6d37a252185c2d1b58e2e809c717963d25627e31f068e4", + "0xb8f9fa1fb45fb19a45223f7be06c37d3a3501dd227c3e15999d1c34b605f888123026590697d0ae24d6c421df8112520", + "0x997aa71e3b2e8c780f6855e94453c682bee1356b5ce804619ef14834475511105b1e4d01470fe4e2215dc72182d9909c", + "0xac2cb2a7cf55aaf990cfada0218453853047e813d3f51f5a623d09f4714da79de6592671358a5edf938a67f905b6cb5b", + "0x8d8340d0c3081cd30d34f3ff6191e1ff6ad7994b4ebac19e5936f1157ca84e1813228b7605ee226366d6bab1e2bf62a2", + "0x9693b17669086003cb46c75fed26ea83914a54901a145e18c799a777db1df9c9ca6b2ea3ee91e7b0ab848dc89cf77f19", + "0xa6b6b2a6cd8c4922d78c8ba379373b375d66ac6ea04b830a23d5a496cf714a9439d81c865da92d52600aa4e2e43afcf1", + "0x89cb665020abc3f5e11a03c7ba5ec9d890fa9ed2630f1443a8e45a28c32786ed980b5343ffffaea60eeff5b313bc0d66", + "0xb37b989106594221bc6cf33a1a83c3e65ecdef279e90333a9e105b8139dc28384bb2277edd4b77c9e59d15e6afe074c5", + "0x98ce5aee5918d18b2326b30c1ba41669cce20bc7a1d1b585363305fbdea66055164a7ac398ca0f0e670291a3061022eb", + "0xb57f472d5f34beb4cf430d7c0f8ac5bd1c0621a284633ed36e6f7804bc2b7847f54b469c7ea163a436510d9e3b32f97e", + "0xae673a6579dbf0504c8fd0c8fc0252d2f7ae8da615a06f4d215c2f8a8f516201f24e5cc42967630c252905e5dbbd6377", + "0x97c1501835a31091a5a83f0546e01c85ee847a0ca52fb3cc0653f6a826e13d25ddc623a5dea139108f7270a1fd7043ea", + "0x9376ee667f3834f6c0da4324fdcca5c04712e0649877ee19da79a2d23be24640c38758fce562470ce2134ca34148ffe3", + "0x818af89c40379a10074cfaba6d5968ecf667f1a68a7edaa18e8977ccb34e0829f237c5634fbd079e7f22928b277f1096", + "0xb8e0af0be0a252b28df25d4a509f31878bcddf702af0e5553393c3dfd4a1f1247ad8dc2668bc8dedc9b41f6ad8e71b15", + "0x811667ffb60bc4316e44bd04573503f5b4dc44d1ec824393a699c950e5fa085b146537ddd6a08a3fede7700396a0df7d", + "0xad834cbf850b2f61ce799c4a0f8ab0c57039d4e1113933c50b0c00175171aadee84894d1376cf325bfd434c3deb44315", + "0xa8b7dfcdb40373ba4d55e751ccfb9070554434df9e359fc165284ee3dc35db6fb6055657ecf5a9e9b7b8e2e1abea4375", + "0xb56a5b9fd41c9d3f65532aa58bf71a38fcf07782e1ae0084dc537862fa02e6d66658b19d6f71c39cd5dbfac418da1837", + "0xa935af5ed224b9533b41a7e79f872f6851591da9e9d906050ccd1b2c772a1d6d010c5fc7160c4f8cd7d3aa14c3bcdc26", + "0xa81e580fc98692567b28323fc746f70c3139d989fb6aabf3529504d42d0620f05327e3385c2bd5faea010d60dd5c8bdf", + "0xa8b352054cdcde8ddb24989329a249b71498a5593a13edad1e913c795dcad3d24789abca9c7ed1d57efcc9e3156da479", + "0xb0de8a2bd7f93284b2bc700e442f52ada16a22ad8d86329591547411c23fff0333b2ab0c9edf82bf7903ebf69916eed1", + "0x843e9781b653d1a427f3534b2e86add49d308ca247546f9fcf565f9e08df921e4d969e1b8ed83f3f849e98c0f63e39be", + "0x84a4098c5dca9f73e827d44025473096101affd7193c40a0307e3215e850e753e9a08e6e74a442d57626ff26df77faac", + "0xb463eaaa2f3315b511c22a97fad353014d840a6a95fe0d457d0677e63e571407d7f5268f8775381a5e7adc3b4163eb88", + "0xad0417edaa16cfddc288eef4173aa7057ca4f81e815541ac588ef5f24b98d56fed6845deb6ae1a9740a28bb1cd8780a7", + "0x9271963b8fb2288a96e07eac13c0543ec41abdc6d978bd7c44ae08251ea49994412b542c77c8208cd71fd8e7852d4a70", + "0x8b68b6db9044d8bafc155d69e0daba95cd59d6afebb085791e999afed4f33a2479c633d31d534ff767b8cd433d591a23", + "0xa6a06a0e433e385437d9996ce823abda9848754aa9cdd25ec8701af35c9ec15df999825669bbc2e17cedb597a96e8eeb", + "0x94d414bff8b6b8597634b77a77d1060db8e1af0d0ddfb737a9bf1c66c8430e93a425510af2464bce4a7b29bc66cf325b", + "0xb6514049562af1c6fb7d0e8df6987b020f0b7a6e721f4862e36b1ba0e19af19414ede04b346be22d348b50875803d1bf", + "0xa42c7fb34f2fbee8aaccd1d86672d0acdf4e6bb083ff0456512d7e1e43be041cc0924322fcd986e6e1bce5d5ecce6f92", + "0x867cbdd169a52440ae0a75d33a28c7d00aa92b4b65aaac5e62aa53a8fc367c08ab8828cc8fa18b6e7d1f908d158e3382", + "0xa6fe0b768fff3e4a6153e59a7b7508eb2ee8165eaf5274d41ac2812bd4563c4ca2b132f0e27ea2f1c98759cc3589b61c", + "0xb3eb1dba43d10b9e17ffec8def053fc96f9883bacb49330a089a0ca5b9ab0182e8b5111ad4aa55c1ce1b6f4afa5c70a3", + "0xa1531351098bdfcda566ff4d811301c0305626c77f954a38420c490e7c684f517eb1a4e4bd2c3904a10bac889cba314a", + "0x92278d106ad2f27eacdb86bdb1faa0a07a93765bb79dcff191873c52253af83480114b2299ffe5324f9c31d0abbdbbd1", + "0x8900ba95a90c447fb6fa1f528af3d7a378aec25feb0620516b6b97e54b328fc31af42e46a8ad5e6e3029d83a6f2bbe5f", + "0x86053d481179c1ac910d5e7b9a5de82794b442f20e854583512ce1f9c3f09e71d1bf97d6700fe776debfe1527ab97a82", + "0xa32a60de492fc4340336416bccbd2591b5e414fca0aead82281212e24490acc01747537b3da783684e27aeb987245cc8", + "0x9820fe8e0338f21797143f368177e3669a1f3894b40ae9fa3b353125f7c8e85cc424dcf89878f2c7667f65db3b1e4165", + "0x934d64711b4348ac5e1395cc6a3215e5643b540f591380d254165486b0ec2a1d0d21c7d2c6310f9e0eed3d08ecf4b57c", + "0xb9fd32d589432eddcb66dc30ad78981360915854cc44b2afeb826b5d48a08e377dc91be66f5bf1e783d1a8bb320f7ccb", + "0x98c972cf01efff4fc2e485b47572e2d8dde22461d127ef401b71a111b0603203971e3cde40912643affd7341cd27e57a", + "0x8db6c1620760063edabd376f4399b6e1355462e04f5c81cdcb3989fdc00f9a466bc85ed899e886c89c149adad69edbad", + "0xad7b7fda0aa6e2aa66a27235ac5cc680aa04b85dce329fc4be84f75c9c961120a3d9e446aa44539aaac8ea203eecb4eb", + "0x8ccb01eaf41d816ce69ebd57754859e263530915e775c4e7d9dac37b2457a9099b9ae9b4c6cb09eb5ff246e3c9320c59", + "0xb895b83b5f7ca46e02697dbaa6157df6c7571864c83e504a8c77d965bc2ba97bf9353a71c56a020df64498bd40e30b21", + "0x8018c07a81c522fbc25f2cb14f2321c61b98bd8962ed8eb7d5823dbe5d1958a5ec2fb5622fd0868e991bcb6cae016ea1", + "0x95b16364e94d01b3664812264d7185032722a4afc23bdd33bc16ae87ee61816c741657c37138d9312cebfb5fcfbb3b2d", + "0x94a709209990a8b09bfb4b9581ab471aae3a29526eae861108b28edb84aab6d28f1d7a25dddd8150b70af34bee4ca2e4", + "0xae06c80839c5a13269b984ff4d8a5938c6f4d8d647b1b1daa8cf7f6145340b76a286cd615ec251a65501e6290162da50", + "0x875cbd0694eeb90d3567da9dc7f570d97b02bd9cf17bfa011efdd48f1d580608a3213bff4006603b8b4079fa66bded10", + "0xb27f88c455f025e1cd902097d6a224d76bdf9c9195adee30bef4a0b0411fff980787285896e1943a62271d0aca531446", + "0x8024880cde783cdb2b863e3dd856be92bacc5b2a1347e96e039fe34279ce528560d2df7d4d1624a4595dbafb40529697", + "0x8883d02c2a5c0e026d941c785128d4ac6f7a9de625ea735b7d6ff27a5ba10fa4d6370d450d99a855d919f40d64f86afc", + "0xa1beb985c45fdc30ac536f1c385b40b6113ef6fabc2f76d255490fe529468847a776efa674ba8fed72180f07d3f701f1", + "0xab83bd9b007561695210e3276fde72e507456ba277ad4c348a2aec7a6e9ebdc2277cb4bd0bca73bd79bd2240a1fc4456", + "0x8db27f516153812149854fd6bb1250e843a3ae1c9637df818b08bd016a769d0497ab6087fe3b2fd4080882713607bf46", + "0xb3891dde4e00d60386aeff161b4a0fbc30bb31ee7918ce5fc0b49aac3238a000ced192c9c4c08d90de3a0ba973d7cfd6", + "0x90a2049a15c02e59024a7a1cb0adea97501c60b1c7442fbbe560054c3d69264e69627ac57b7d9be01bef498bb2a60198", + "0x87df67a4bd72444b5faa4f3b067204c4927c869dd3b29ad192d859589a9b2c1d6d35ed68310081e140add254a9463092", + "0x8f80986a8dc8a0d6408ebbcb4f234e76413c11cb0d66067f9436bb232373100f20a4fded60f08dec3525315abfaa8523", + "0xb061e10beb12ba3683688a4ae3a91600d14878ef78a308d01b93e4918efc666450e3f7b0e56283468e218934231df98c", + "0x86b9e55f3783d62e381659d3e06699d788b88aab1ff99848db328a83c97d223f602201bf2127c5ecf419752fed0a224d", + "0x858d878e29925c87243e010020007f96fa33264e89c8693af12857b362aee3fac2244057e159651c476ebe1dfbd67bcb", + "0x8fd47cdef87d7a569ffce806d2c2dad100692d6c53e5f5dfc6e274f897dccadcee30fc6c6e61373961bbc1f3ecbfa698", + "0x892f2822daf3df3a759bef03168c1cb07408df62e024747a788e94d2da325f880bb9c6e136c7f6643f45b021c6ccb654", + "0x8714e37ac24f5a198f219e7c88a92172fc3db129e044e914663ac708d8101851e7c53fce79d32d0e6da74f2ccd1d30ff", + "0xae95e1dbba8b9e2c8dfbe1c202e9ccfd04fa396470035a699b902fbd86d5e6a31732a7c8cae00b9a4f6e51c8d560c7c3", + "0xb0cd058e77498e860fa20c5f8d9bd09bb249add1badf84ba8d1bd49e704b9b4bcd67a5c3d211840a2c8fefab3fea639b", + "0xb78e468d3a7da0dd481f333ae56534e2ef97587be2e259a458e25aa37952aed1cc5f835640f812d8052f5bada8f57b12", + "0x835de7965c6b26e7ad1b92eb6f0261d1f376fa12d61eb618d9b342b597c9c117a5a8f6a36269aeea88072b4641e6b5bf", + "0xb4d0eb99136b3643468c9c48a20fad62785a60fbdd3c054efac4bd1fa7979b4c9ca6c2c0b18069c0912bea2f19832790", + "0xa00c47315dc0700a850966836a95f3cebfde04dd094bde0742dee77b89a05b5ad655921f86fafd1e902938ff34d4c58d", + "0xab13fa0afaa92229a71ee91efae6d1b15f14b6eacefffb7401d41d0d6db24e24a8dbe8ee19b4680ecb69d2a0cb4e84e7", + "0xaa56c0fb18401210062dbc653df8e3732aa8921a1280e9737e99b26a0100a13a9cba8ad0317a69bba16193362ee0f030", + "0x8b410324a6406b345df0fa25f541ac20b7313fa55832752f70cf4c79f43b0bd3d5b4cdc447e6ba7bca08d0edffa8e29c", + "0x893362241ae412d9e5df46506407595c58ffbd7fb1fdaf0694c3432470599291238997abe118bf7737e56a4f5c9dc292", + "0x921618194a756be81cb49d6357cb392b32cc62d96c8ffb7e16d9659a0f226a0436bd378da7b835054dbe0de2c6372ef2", + "0x94a2904f10994928ff5367b777e1430047736fbece33442cf452018bfdeae62e84cd75cf80f8468285e347d504c94111", + "0xb4b81545b767f380bfe10e0fea9c3cc62ca8db40b43c83ffb245259378731298e3eb6c3bdc3a16932f88f5d8a86edc4d", + "0x936203c2453ff01c6fc635e4d54320d69e60047d805daae3b75633c2259108497b778f011e5a057249f11b2b888ea76c", + "0xb90bf6378d29339443c3f2008b1e2b5f0345f86e393027f14a295e583bf6e6c2b10f54b6dcc42079ff0d356c405b03bb", + "0x916913f550d327de2d8d6c7723dcef2e3869efaf95fd963d95c8980b97748c61ad8e2e629cead8577266d93fe39203bd", + "0xa033c6f3d5ecbabeb83eb363e54e5faa7ed2d7f4fb771b161762c4f003eac4e1afb236806b784baf2222cad54e2d3cd9", + "0xab289d4a5771147e6c29ff9ac2bf65d70081ea6c6af2d9b728c3c144574a31b5fd8632af57c18c389aa2cd994938bb0b", + "0x9488da2019ff13e290eeac132b491df58b5b7b23c2898ff1a67bffd7e9c9464c39bc8177a57950fd28589e3d9ff9c6c4", + "0xa5abe42b2e0891851440fb2aa6c1d8a86b571bce8b80c8e9e2692e5cb6d45a1b2f055c9fc4c74a7cd292871604129ea9", + "0x90bfef698e83c2ba4dc9304aa01edd274169a978b7154bca518daef394f55857d0d1922ebef3d91fc5ecb3b895d9e0ec", + "0x92328f1372b6406ec80786041b6d57018b8507e3881a08727aadfecfdfcfb0824394cbb1150117ac5da5d71b89e895ae", + "0x9719751c5f7a65ae2bed8aff7b4b8c34539ff011b259b7ff54f63f9d987b3fbdce5c99534ed561aadaf07bb6e939e208", + "0xa151816774aa9379fccec21cf212429a1c68cf91b055cbb9d931f461a8d5616c693331a11ac5c6fcfbd17d84ee0b44e4", + "0xa72977b1285618a45943ad00f33f37102e2885eccd2f76785254eeca495068fb1d8d49865343e9e8313c6c2c3b2024da", + "0xa6f5ad2e023a1585d90625c9f7094f0e8851c79f0eede8ec582ee8e063407cc5b8298e5fdc4c786e4fbbcecaf33e787e", + "0x82901e008febcea0c0a14ae21d985a397630e18ee6e346f4a449f23be228e8f338df567d30211a11180b94fbc5204bec", + "0xb9b57fdb8d14d1be87a25f89553b3966eb7869e0519ffdf4cc4d51f4cec90d68f7b81cdc0450e04207276e9c63ace721", + "0xa06eabcf43585a001448f3dc30411f3d5b74fd0a695c81eda9981842ba2bb0081d3f5a8360aa18b6d43ef13ea78b293d", + "0x926fe48a7e8f07559b7237beff9504476dd97b5b4d67acd01a3633358a6ba4c7abed5c87683a11209aa2ee759888e00e", + "0xa716cd3a84a963e2a5a46145b6ef4ebce705de52bf2945c374152a1e41c228a9c4eae0b6d1e222c1eea8b9c13c002177", + "0x8a9b5985df6fb32cdb06ba1591a977545444478f2fe985ed1b10de61c630f0a4693c2185d63f0dc0256b208072c43b17", + "0xa8eab26ae0ebcdf96a59fad1dc2d5e83b94abb2ea1774b607023f9d9e0fe065853b1e2242e794f989a80a47f550c0bd9", + "0x84adbf38164cd04f3d770a7f4b8eae7a5d25b4a803fb63c02b95b71b33e454319c44e07a760d22bf5f58e7e372d09a16", + "0x90f443a3ba1b9129a0bee400b5b29d42e50bb2aa56b0022bbfc3c6f8d69db40299871ec7c1b68421cc89e1af6b13a39a", + "0x81c5a94b379eb98c494a8d0067c748ba47e87a2ada0105202ed7651eb4e5111a0cd8569b06ae68d392c4fd74a37833d2", + "0x8f92324b14a1549ee0b186073a26691088e41556d33b54258fc6e0b000e9624156db4e97861a0ec22960e6c47ca8a1dd", + "0x8b021cd0fffe055068cc460aec3cc455952e2ac32be5fa060e0d1b6cf30ed15381618f801249e893b1b9f10dd82077b0", + "0xb3e9f0dcb3d6f0b138f589fa54dfb01f849890ab97016372d004aac55103f363a64bc0e606ddf75430f1534a30fc522d", + "0x8fdfe64af891db89b25daa859864d479cb7599486bd6f36e593f8f2f839f942261ffc3eed5001a93fde44cbcdc24c583", + "0xa9e4554373c5073e135874e2bacbee69c65308eb0785532fec6a37834e8d0b437b77a2f11cc63c87d7183b82cd9b6bc9", + "0xb4c47daca723ad7193ac5098cad4dcab654186ec5ea5c0fd014a3ac39726be954565a901694ba211820c011fa1c59e18", + "0x8835427e86cdceb4c11cbea331ed724e4e78af15e3bab5be54f6b926bf66b5d99bcc40dbc456d86342c9fa83a033c2d5", + "0x8ea84590a400cedba047c2661378921a42f5ca0421da58c1bcb37bc686a2aed98afab3fa5e6ba3a51029390ef3cdf4d4", + "0xb48551170fc479d69fffb00fae4fba301e92e37cae08f596db6f6489c3b7020edc074f9e8d7465b84e9dcef1b6b3aecc", + "0xa6f318b1eaab00836a330710e88bfe400395b3081485f6a212e3cba9463f6fe7864ba4f71e57a411ecdf2bcb4d189f96", + "0x848d5137a39999141a79f4bdf91150796ba36352d8525821bf3bd6e070b352792d79147341b8254dd60fa8c36e9e2618", + "0xa8526f8904b1eac4ae2a25534aa91e8031e9aac7b8f58d8f49897e920c36c0232f4a30aa6eed305deb0f7793c115b267", + "0xb8b6a727c44c37a8388383e959d195d1d0e51a657d4ba360633d219d43c5df645383e2406c25f1d418e72b862c3a6e9b", + "0x92e64adf65b42c978f36dd03ab22ba983bfbb61944efccdb45b337ceb486beda99818bf20d32a545503c4572bb0a4983", + "0x9653bb83df66260a0bd059cd4244ef7c661b089e403d26ba777d2090783ff31f963f5d3a9c125b1ad1a1d19134f3fc8d", + "0xa74e72355e71ae5eb36dc75191643500ca3e67f18833ee981010e7e7e60a68e1b01b05901eff05014b9ef29aa4829f45", + "0x8b2139a5da14524cf6acc593144db23db424b95b8c7041d8f6c7a14a6725dda1cd09c42bb3ae26a5a3650affaa742800", + "0xa60ddff4300ca44a7c7a00a1f98441ad1438e07c30275bc46551cee1b681926d2c825cc8f90399ee5f36bb9fbd07d3dd", + "0xa04e5e9958867a5acc15fdea0d88951cfebd37c657102f6ba1dcdaa5e46cf1c823ad0d98718e88e436f260b770599102", + "0x95e977abeb70d46fe8d7584204770f14c856a77680607304ce58077550152733758e7a8b98b11b378540542b1175fecd", + "0x8c9ec93ed35a25ce00d61609e92d567459a45e39922ccd1c64ab512e292787125bd4164c00af4cf89fd3cf9deddcd8bb", + "0x819819ad0338250d9c89aceda9e217df12ac54e940c77fb8420575caa3fa78930689d0377ba88f16d38179a807135dc6", + "0x8baafb379d4150ac382b14a64788d819146480d7a1dccd3deef6889686ded375900f5df069843ef14d754ad3d7540401", + "0xab827236996bb79b447714c6993af941c5ae66248df4d9a6f3650d44b853badb5c0cb67804210e07a7b9d66ca43092f6", + "0x927656c3eac8d2eb575e3daeb77f9605771170c325bee6aeade10c083d42bd8dcbf3bcc3d929ea437001c7cf9a95e2da", + "0xaf22b212d5ee44fd4197966b9690487c38a119cd6536cfb8c181f38a94610dd9e057f95774047a446504dd96dd11e326", + "0xa44bd94b9e01e3ba36340f2ac2201ecb477495d4f1fb6726a6b439302deabb5a35d237c6a6aeb7e3b0a65649f8656716", + "0xaf367aeeae3bba14fbdb05bcc1a521000dd9d37f5c34ae56fb306d3dfda201d0329a8b6e89d98e15825cb3c6bfdb1194", + "0xabcc4fbdea43e50ded9e2fb01464f4e87fb136e960141e8d39214f92794cfab5634f22cd40b18d8c0e501f2307aad23e", + "0x920786cbd674348b9853689915dfcab02cce2a4596d117962bce36aadddf4bdd143891e22f2c8015517039a64e8aede3", + "0x8cde63b9bd57cb3ef743f1f3e8250669eed739e5fbd68c500a3cc0c12f93862a69aebcdbc69dd8f476c2eb307f572a53", + "0xb967e65a5f1cd8d5d570f5e87e7e186fba51b9504f8e466392a76d8a971fb91fd9b7565bcc1647f50d7d15e48b93bc95", + "0x8d5a87b25fedf5edd57d870304bfd9081dc78c3e3e3b38b997260a92edac7feccdaf24feb51822d2edc223b70bb4ed5f", + "0xb6cd5d340a57f8ec73723c4f3ecd6601620dc8137a3e75a5d3c578bc79a9cae86b379950c644dee2ff99dad780d025c1", + "0xb6f0a8e754b7f52a85a2a2e6512cfd017f7fb0418d19bb318308951c4e242d3c65bbcb9748da9cbc91a738f9ca577332", + "0xa89dcf7d410bccec385400dd96b1cc6af89026a431d0f531aa992cbd7bc8bfd7c5f360bcb665bda1d72efa17bb982551", + "0x97788e7522427a46c4b6258d15623ef7a565712812fa80d001e1de8dc1791392702f3fa3cce5a8cd1c5755625a0ad10a", + "0xb5338fb5e137ff625b27c5148298f27ce8f493e2527c5d0facaa49f29cae34580d0d6c3c1074a2e46cd8db3f56004ea9", + "0x8962f006d7b1095dd0dd132ffe7e87e328510c95ad893cf3b2ab21c177c5cf2c27f47d8856f87e9762c547be009d25c0", + "0x87fee9ce9c26aa476e67e0791a809e0a06a8a98facf3faea730d438d3e516cdf75d645fa75c906e4e44ab9237a22c016", + "0xb75ab972e1a1214bab0b38cc3e973d44bb233acda5b4291f5e110b6fb78fdcab93dc63f01168debd898e165f615be1f7", + "0xb5a0fb52bca279d3853761a94b206acaf313df33ae6303d9b71edae90b66fc507adbc60fb11e758888736c81d5d80c0a", + "0x849b8f0005010e684701cd3a4e59e8c89e5fec59af6d2de5b6332cde03b865ea84f07f0b80ec3404380b0e148fbd2c24", + "0x96e2b0b6fe78408f9208f809f5c40398100b2dac202c8c5c33c2189560dea868270a598c419871a5a2b67783354f6014", + "0xb234b81f996142d0df2c719760bf996544820a03195a6dc0ff6a72543692f5a369bf63d1f0b477ef2fe7b3234e41f685", + "0xb85e39bcf40da1a12a535740176f4de749a93824079deb5fdaa004f3282fdefaf5275e3418c88c419bd42a3dd2ed2b3b", + "0xa27279304b89a18a4e2b443246f2368fb8b15f46a34533179b6bd2ef683f6e98e222b7a32880b39b8fac1afa90133803", + "0x8923c22cf15c9c1964213d725b337ece9ea854775a06f75f232c4859c7142a3942f418354e33066298aedfba3cb27e62", + "0xb109f714311fb9bc431ef57911e2cad6a3949455b9f23255cd7edea35be629e07f845fe53e2b12a32305ee2f4f264f27", + "0xb51e82ae5c7d48050e405897d0053e9ea4b2714d002e88f78c9a307cd50b9c6b3ee7cb86f86527be9d964b01895fab20", + "0x90db256931c7f98bcf3bffff4d496739185e7a20f329ee7bffd4e0850a37739948ec745285703967f4ca50ec370cf68b", + "0xa0485ac0445d88dafac56bfba2563b020cfc370f54c1606c89d12cfd8a4d1336d2ba50306e476155a6f5b0e0a1f2d092", + "0xa00754c3462e74bda928da855bbf90f9077db395e32f03cce9b2955546d900b72330d247b7d607b65e130f5b0d883de0", + "0x8547d56727c3ad8b5c8ce622ed9ad86fe8cd78e6e4848c9845914b5063b17330bd10b46d8d3f18f83ca09ecb28d1afb2", + "0x95b937b2a979bce0e159ac75c7d5d659be8599c92305e73e942aab414793364a3ec28c7c1c8491a5750ba84a29828d8d", + "0xb011e150f0294e45a0f4c69409999d0c2e602449dbd67ab95e8258466687cd733a0329083a31b03722f4e2580ddc95e9", + "0x924651a733ad5e5d9adadad3ea6a6babb8e455c8d5f2cb5bdc83fa422e7752592190ccedaa827b866861e73506a6968e", + "0xa4d5180122f8e31503ae027e54da50f72f5cfb910a6f7309bd882b5cd666f454672591f1f20e461e182a47d03b47052a", + "0xab19ae659c4f73ea3d21895269dbec583c7029955a36469124ebe295027010faab56c4a475973497f28e9a77c03b8fd0", + "0xae7ea1a803d0f439e91494f8f35fc1167dae23834c0c699ffe65d3da8b09f8df5a53195a99ca7b8558242279e69578fa", + "0xb9d63cf0e30f9800101b43b980bcd2f229758e74b21ad5354866b4e684791c08a184330dc316228a0d67fe0210f2bc4d", + "0x8c41629744391ddb96dcbbf9cd99b13d36e57d65962e0aeb92ebccf1c4cc769626feb3ec0363def08eceb102b3dd4ad6", + "0xb2848ff24faf9e667a8c19d050a93896e9e75b86595f7b762c7c74ccdfb9db126ae094961fee7f5d1192776c1ac1a524", + "0xaf013bc29206743ce934d5887b8d0fb3667c89bda465d2321835a3618513fba6a459dd7566268220ffce7e0c97e22b2c", + "0x8bb799e36db1132da8e8b028ea8487dd3266b4628c56dfae4ea275f3c47c78e3d7445ab8d0aaee4cbf42148b3a148175", + "0xae2b81fd47c038b5195a52ab8431f0d3cab4cf24c4237252d955aad2156adc16dda9d3270157e0bfe5a44022e5c051ef", + "0x8e0129213b1698d2ec6df132356805a8633ba79e672e586dfef664ffccca71834253ba14f296da962651fcba2c002622", + "0xa1ae30b500ae77cd9bbb803d737b4a5991cc780618ac22b5cc179efd8fe10afb8c135457f2e7b86ded485ea12eae70e5", + "0x8a39723077b7c0df6e3bf6548afa3910c214ee275951fbe5155a39473be98099626ea14d844630a6fa90292b9594665d", + "0xa628386c79b61aa7314b01d9814aeec20c2a66e3deda322a39957e7135c2e52b1da486d1b9cd61c87afb22c1d10f6462", + "0x97867f469b01249820aadd9a54e12d4fdadd4555f2d530450e1f8f6d2dae57360578e2c2c8ba41e3b5950df596537a98", + "0x97f192d0457c217affa5a24267dd16cb4c01de8fefde9df4884e1906d2f22e73382dcee6c7d910bf6430bb03f4a4f1e1", + "0x86d5b5739de8442dc74d0d8dc78e49210fe11bf8c6ff0f0faecbc47b64812d6b28c8afddf6d9c0212f1988451d6ccb1c", + "0x8ff3312ce9693cd4a9f4b8e75bd805f65b0790ee43fd9e075fe4cebc87185bdf161335049819f22530f54fed2779a5b9", + "0x8dc41d85548bee5d51941d55752a500bde3c5a8f3b362da4eec307a963968e26605048a111c9166d448b8dddf6f53892", + "0x996bdfd004b534151e309ac925fa5ee7801c9da4f6b4c43e156d1158b134535a2a3956e1255e0dd72ac2af6bddaebcaf", + "0xaead652704b788bf4983c8f725c644c327a6e9f6683215f5c826c09f82fd2e40631791f51d14e6aded91fdc018d45501", + "0x991ffab58a82b98ed8fc7b00c3faca153589fe09cebf6a137ad506387a1ca4dba475b0e4a1b9bdad829f1422facaec39", + "0x9652e6c4ae084221d6bad855ec0bc11b5f855c6efba67f644e0902ab790a98861cecc6ce047c68273c3aa7eeb2f4c7d9", + "0xb88b816507aaeea6dc92b861eabdc96988b74d7883f20a4b30ba249158acaff3c50d261742fc9ad2e9eba888a8d59065", + "0xacd028a51e16c07a10d2073b9d03070457ac5f1246365295a1359d015c460b92b4861125fabe6f114de8197045df408d", + "0x806d3cd9d02d41c49179fe7dac5b05dcfc9a205a283135d4f008d0771c58e6f963d7ad0f6798606edda718eb5c7ff3ed", + "0xb9b71f1657a6b206fc40159a941e127f252a7b324dea864ecd804f48c0ed86da9778a925fb65491204a92bc2a26fef32", + "0x80ed67bd0e74350c875abedc0e07fd42ce7cb926f0f3fb1949c6ac73f2300b5a14a5c6f6ff8aed99d5ea5029bb8e7ae6", + "0x9875f67a7a473714e4dd75ee0c763ddf88101532d9680724b3848fef69e218b04a96b90f88e0f4409aa40b9a21507ecc", + "0xb4a2bb1b421e5243e5e7576a0672dc19f9f70315a03f6411c19f76616ffbb70fc5dc0e57fd4ab85e24ea2261b7ce38ab", + "0x879723002ce43e6c75ba2246f51436efe3376242beff987d025c3c4476495af32d52a54fad5d9ec329a442b93bcff1ce", + "0xa4121efbefd9c3eb143619afa52a916f199c75024908047763b29466cdfc837c2fcc894aca63044c33c41c777e529b5b", + "0x895f637b497a9766714a3d9e3c275a1f0c9ddab105bf4c8b7e663f36cd79492022415bb4938c1a4849bda73106ace77c", + "0xb119acb8b161ce4384a924645a248a656a831af526cd337d97e08405415b9dd22060849c76b88a4785eb5e7214961759", + "0x802e712f4c0a17009c4be6c1e5ba2ca3b82adcb68793ec81f4489b7985babd8a3873d544de63d5e5de0cb4dc5048c030", + "0xab111051e4651b910c68ecfdc33f2d99e7bf4182df68cedbdbbcac219a543e04d93ecb2763fe32b40c095c7ca193c331", + "0x855c73ef6afc6bcaab4c1e6388519fd5cbb682f91995bebd558167715db454f38012291beccea8186a3fb7045c685b67", + "0xa29d02ec6d9baf84c19dfd0eb378307703bfafc0744b73335550f3cd1b647275e70215f02d1f4ab82a5df4d4e12dd938", + "0x91510a45b8a50cac982d2db8faf8318352418c3f1c59bc6bc95eab0089d5d3a3a215533c415380e50b7928b9d388ff89", + "0x8286e7a2751ca4e23ea7a15851ad96d2cadf5b47f39f43165dde40d38ddb33f63a07bc00600c22e41d68a66fd8a0fa51", + "0xa413d4e619b63799dd0f42ac57e99628d338b676d52aec2bb0d1bb39155ad9344b50cdfe1fe643ff041f1bc9e2cec833", + "0x85524e5bb43ae58784d7e0966a664717289e541c8fcaff651541718d79a718f040a70aa8daf735f6635dabfc85c00663", + "0x97f0d48a4028ff4266faf1c6997b6ad27404daa50ca4420c00b90f0b3e2d82ef8134d0a04108a74955e61e8dfeac082c", + "0x8df6145c6cc39034c2f7331d488b8a411931c8faa25d99c5432831292637fd983d4f6b1a6f55522b4a42a462d63c6845", + "0x98c2060f67a916991b391e67fcf23e5f305112807fe95bdddb8ce6c4084126557e4c5f003afb32e30bc6808b30d4b526", + "0x8964246b3c2b8f7312f0a99647c38ef41daf70d2b99b112412356e680185da6810ab8ee0855ad7409d334173bcc4438f", + "0xb56c2c416a7069c14bdb3f2e208c5a6ad5aac1cbe5b1faf99dc89c7141d0259d1c6250be9d9195500c4a41182ad2ec3d", + "0xb7864583a4cae3b1083dcdcff7f123d24a69920a57d6594d0b7219e31bf0e236682442b6499a1f6795cfeb4f5f236695", + "0xa064f94139bf1b70d476bde97099631b1284aa6b4d87f16bfc65c075e58b2f1b3c2d057605259f806e545674a1169881", + "0x80d1bc4acf14c0f487cd57c5d6157b7f38917e93cb660f1c25e474fcdcac3c3dfda50f6bcccfd6676bae25c4b6b5014e", + "0x8ad9a4976c4e3e282843518149fcf5d454240740f4b91466f6310b7216d23d70b9b47c42870293252f29f092f330967a", + "0x914197593d2d99d784c704cad7ecd3f0b9f55dce03fc928d13e1a1034566c4de754f1c2a5ade047b0956415fe40399ec", + "0x8d77f5e29c572ec3c0ca39cbae2072ba4102403265b3d8c347a00386da9c0b8688d6e3280c96037c300d57b3545f3773", + "0xabfdf79d935fd4f06a04938d6580a8cbf9735f0d498f49677f26e73d3b34b7075d525afcb4f14ef1632cb375bef7dd55", + "0xa97a8c446e3edc86efac7bda5e2e5d0158c909552a3bf86151df20ece63b8d18b608f477286fb1c7f05605ab7e6a7c2c", + "0x8618d946c7fd62486551c35486fa466bdfcdc63c941e4cff5a01fbbe566b7ea9dc763cbe73e2acae063060b619a212a9", + "0x8d03ee468070936004b06acf64b868963f721f37faa09887f8a82c155ad5c5732572a6855b531db58af03b1afe034a18", + "0x8d3247f75966ea63935ef6049f7c889c1651374adb446f49499fc9191dbcde7ea33cbc1f1e2d3d1756b6e69870404643", + "0xafc853c3a3facb4ba0267512b8242327cd88007cef3bf549184ee891b5ddc8c27267bae7700758ad5bc32753ebf55dae", + "0x80df863eaea289de5a2101f2288046fdbfaa64f2cf1d6419a0e0eb8c93e3880d3a3fdf4940f7524ea1514eef77fb514e", + "0x8434b5888c2b51d12d57da6fb7392fff29393c2e3bfee8e3f9d395e23ddc016f10ebe3e3182d9584fddbd93a6effcefc", + "0xb78cbb4c9e80e3808c8f006dc3148a59a9cace55bcbb20dd27597557f931e5df7eb3efd18d880fe63466636701a8925e", + "0xacb140e44098414ae513b6ef38480e4f6180c6d5f9d1ca40ae7fbadb8b046829f79c97fe2cc663cbccd5ccf3994180c6", + "0x936cb8dc959e1fc574f6bb31f28b756499532ebb79b2c97ff58b720d1cd50dc24b1c17d3beb853ba76cb8334106ce807", + "0xadda2116d9fab2c214ec10c0b75f7f1d75e0dd01e9c3e295a0a126af0ea2c66373d977f0aefdda2e569c0a25f4921d0e", + "0x89a5cefb80c92dcad7653b1545f11701d6312aef392986835d048f39d5bc062cabc8a9501c5439c2b922efc5f04954d0", + "0xb9acb52747ce7f759b9cdc781f54938968c7eeacb27c1a080474e59394a55ae1d5734caf22d80289d3392aab76441e89", + "0x8564f72ce60f15a4225f1a223d757ebd19300e341fd9c1fe5a8ece8776c69c601938fa2d5c21b0935bd2bb593293272b", + "0xa5567d7b277c4ebf80e09c7e200c20d6cb27acbaa118c66ef71cbccb33ee3ddce0e0f57b77277ae1db9c66ed6e2d8f30", + "0xb82e9c2d8df1cdd3b2417bf316d53e9f3cb58473c4cb5383f521ef53e0af961ef916e4f6557a6d8b4655ec01415231cd", + "0xaa816dfd2814c8a25bd2cbaf66303ee49784df471bac4b3188074ea30816f00f425234454d40d8ad8035aa925d74da36", + "0x9919f384df20faaa2d226b521cab207dd2b62420d25ebbda28c9b2ca76a2a52203b2ad7844c1a25f5c75f005c5a83149", + "0xb24a6aa35c2d0f87e36598b36224c64427cd69642b6f9c1bd478a62c70f8ee69f85028648f6603b4f04fb21355f2afb1", + "0x892e044bdb1276b455eac2204be105e1821f987c2570494b1f32aa09506caba7ed343cd09b1bc126fed5e0fda3d0eaad", + "0xaf0e01a3ad954dc048de18bc46bb1c4971db2467e839698e4dd05cd1adcb9261013fe9fd0cafb946c0b586f6aad86d4e", + "0xac152f0a9ace425378daf02510eb7923ff1ed2c0f8d1deb918e4efb63655de1ba58c96438e9aa23abdf2431dc771370d", + "0xad8c7419c097709347e2394195924e09617b47ac5c7a84aeb9deab8975f22155de0f70cf20d8a976551b14e3a2683a2b", + "0x808f14f67ae801536fb70a5898ab86e50ad35340cffd0648daed2f2c4564c9ad538034b2a179a6a8bfa27e9d93b4cbe0", + "0x80a74ab7ce4769db93cfa695a166db95f0a9c47885ff826ad5d93310f36d6b18b5351c67c858b9837b925e85a1995b63", + "0x95b88c3cdd64401c345828f4e4754b1a88b4875a14c08a668b90acd499b3b858842669ecd73a46c5d9f1de32ec1a0120", + "0x8ddbd770b7b18a5917eb43926fa05004e819f1d1ead05b915269e4a86b53e0633a90559007e59f6705a3769e2126ac56", + "0xab6db5fc220754f19948bef98844e6e38dd623565d1695e1198040c228ac4fd863c1f168cac1d036bbfb718d9d8dd036", + "0x97bef628e977c069e60c395a17740e0e1bc1828f5607ae7f30ce5a0c95f02b53af2ad062700a75212e462aa22c3c5465", + "0xb68d465e04fd17ca98501e61eccb0ce30401855e98046e0c1debba71c2153d6a7a704aa36a6f12454696e78e87181cdc", + "0xa79cfdd048f4181e005bd0fbac0a8424495474956b58ce858d2b700fb0f931c406282bd33bfa25c8991bc528d12a69c1", + "0x843f55fa0a6a0969daf2b48080738f30b269b2e7ec123a799e5b203c0b3b4b956dc95d095bc6550b0013918cdff8a225", + "0xb683cdf2823036827e5b454bfe04af9bec1850d25a7a7a44aee7696b6ff0468b7ed6885a41dde2b8f3ecc4aec880c3d2", + "0x8b500796e82acdc89778e0c0f230f744fb05f762000fee877bcf57e8fb703d212dbc2374887bdc2e7b7a273d83a85798", + "0xac35a8ee87bafecb1a87f15abc7ccf4109aab4ac91d357821e417f9b1474d196c38cc41cd13667f68d1ffab5e79a6e92", + "0xb6e517739390cfed5b395d33b14bce7cd7aaece57fe79a7eb3cbf150dc10765c3ea9fef7976a21a2243687e6eea38ef6", + "0xb53901eeee26692273365b789f2a60afc9b5f0df229c6d21b07016cf4c0e7985beec748aeca52262f68084393ab038e1", + "0xac4804f33d8ba2b4854ca3537bd8bf2dda72d4e94ff7ecaaf9bd3b7f098343d74d765471ef80072ae34f860b052cbfb1", + "0x8c6a30a93f1dde18039bbdd1ef294552bf79856e20bce863e4b8dd72d906be3ff22468ff3610e06b5a7d1745dde7ead9", + "0x88f0607fa3b7cefe20a02115572b16fc3222be86bb19e592c86c48afbe7e0dd523492b0c29a3bceb9a20f5538bc3134c", + "0xa660b801bbddad725975ddf9a8f606f76ecef831f954be224d6178c368e1c72d346f00c4a4c95c289b62d36f2af323cf", + "0xa75b9a6aea9542b698938dcd6cc2f6fe0c43e29f64b2f54aeb05d35fac73d41aa7fd750af4fa9333644aab8db90775b9", + "0x83e1b7129d963d1cd076c3baa5fe422148e939273db173e4d59d1858a7d841eacac7fe817d15ab8f8a493bf46c2045e6", + "0x9060a2e9c24de11f9c70e039b5ffe9e6d32f1ae39f3dda263610df2265d917679e689898e4a8bd84ad34613dca5e3761", + "0xb42fc8b863a2af15e04d1fe6693c09b46007c0b8298973fb4762b45b4590ad7fe0aa758918b2fe5ed1ed0359754fd955", + "0x83e6de7860fb256ecf7b47506a5e557d0fb0aefe57fb513c7dee2bd9604712d08ca26adca7ba9a54b712372a7c585a26", + "0x90586e9cbbf71475ecd3e7b5753b286804dcce61e165502a82b960099e79272de8b7494b8877b54ae838eb5d0f71af2f", + "0xb2e4b0d21208f73b7b75e08df80cde20c4578e117d37092a490af82354e2afd3a7dbab46fa2d12fcb731cdaece69c2ba", + "0xa010961239bb8809fc7fb4aa08fa30d33a130f9f417ee9ea60f587dcc5ef4e1b7abcdcbf8e848ecdcb7972ef6af46e78", + "0x8f511fd58d1e3403a5eefdc0a4ba6b8af848c7efddbf9575ee84449facde05ae9a24aa41a5725416467f6fbd11369c52", + "0xb24ebbd2d4482eb618cea1ac4fbfd9ed8c46c0988a27259300a7ce5ce1bb256aeca0357828cbbc4cf0dfafbf586040e1", + "0xb3ea29e9cca55250e9b7b9bd854edae40f0f0cc65fe478cd468795d1288cc20d7b34ced33bd1356f1f54a4291faa877d", + "0x8a8b20f222d9e65bbde33638033972e7d44c6a310b92a9d9c5273b324c4ad1a94f2a10cbce8300c34dbd9beb618c877d", + "0xb2436a9a647dc3f12c550e4ddc5b010e6f9cb3f3504742d377384b625fc38f5b71710a49fb73ffaf95b9856047c98201", + "0xa13f8b77c70621e421be94c7412454adc1937b9e09845c2853ef72cdbe500e5c1bf08e3c8b8d6b8eff4bce5b8dec9213", + "0xb25de8780c80d779e6c2e3c4e839a5a107d55b9cccc3ad7c575f9fe37ef44b35db4c1b58f6114a5f2f9ca11e1eb9c5fa", + "0x96ba6ad4358c7a645e5edb07d23836cbd35c47d9a66937d09486570e68da3c8f72a578bd2e14188d3acc17e563a652d7", + "0xa7f55989814051fda73f83b5f1a3d5385cd31dc34baf94b37c208b3eaca008ff696fd7f41e2ecffc2dd586de905bf613", + "0x882d0c7c81e58eb9560349f35c35e4498dcde7af7be8d7974b79d262304c26ab67ffa5ed287bb193d5f0ab46b4096015", + "0xa607158f0c1fd0377a8ee5e9715ac230abf97406c19b233d22f5911ebe716967cc10425546dc44e40c38bd6c2b4bca2e", + "0x87e8cde50e5d852d3f073a43d652f7186bac7354612517cfaecd4a1b942f06fef6f14546279c0dc0262e2997b835b2a4", + "0xa1c93acc6db9d5ee426fb4a0b846bb7a7b8d5915bec777a9fe6907246b0beafb8938941c8c79ed6082155f75dbc1e332", + "0xb1e4f61457b86f76cd93eafd7536f72baf239ce5a62bd5a8085a34e90576b1e118e25002d2de49b01d6e9a245ee7d3a2", + "0xa0435fe9a4bd1031ec5973a103ec9396b2ce9fd982f6d9ed780fa80ac06a6e47a0a6eb2daf52df1dc9292db622ee9fa3", + "0xb66d8e8a1717e4bfa42083b6ef4490e090a73168b2912f2111743e089027be0a4945a229ecf5d0b5eec11b23f0e11303", + "0x8eb764f26904eea4f4169be6e75beaa6a39e4eb524625a15a78befe3d8e3cc82692d9b135590c20ed460d6e4ba630ef7", + "0xb7e4aea6bb09829e53fe83e53f49a7a331a6d7bf76e0073d758577e6d6fbe63dab642b23657355cad48896ad8715119c", + "0x8f94207982373a99ffa282673f192aa98d0c4461fb77c31dc4549628bd9687a249f1b3c66b1840929341e42516c5c64a", + "0xa9c673cb247b13e17fa5e616f0399b7f5c7ad043e143e44ae68855a840870ab3d2aad737ebcf74c2cc9688d17ef3a794", + "0xb02635104dd28c02068985256975c0af783899eb996e37d021d9a35238deeea9e836760db21869be7b6c82aa687ded29", + "0xb33bc0966389710812b5f6698afa3e9c84839a1b85492ba11e6ded26695260abf66be6fb355d12d3a8524966f0f89e0f", + "0xa79c0dd09506951c33da3cbc23843fd02d641fc24c640a205e6e8150240372847312b9381fb03c5d301fe4dbee8d0da2", + "0xb74de6f3a2c502b5b658ebe8a9b7edd78afd036f5a2736aa06502863b6865d131b9e3542e72a86fa2e1d2db4927661ed", + "0x99e365def1452ff9fb4b9eccd36ff4154d128469ba5bd73e83ae457ab53977cf6fc04a5d05bdcde357ab539e34bd9fe0", + "0xb4f2bfb95abb47c67870aa6ca38ac8f3ae1b1a2bed064b1be7ff90865ea12e4930fcf66429c7ecd1183fae4a01539386", + "0xae4bde87f36b912e92398bf72e11d5389e93b2de1b277d7ed4b6fb5a9ab9f71a959ec3bcb734c11079440fe42b86fafd", + "0xb826459e568efdeeb66688482b67ef5020787275123fd3192f979b6175e3b0ed59e17cb734a0a052bf13f0afc7bd237c", + "0xa99dd735f4a7c85cb23dcc7f4835f9ab32026886909aaa95876b98029c37dc4d621726c872d3a9e50403443c958f4029", + "0x99083545034768010988bf8a9f34486c2cd9da27a1d10db3ab86eb69a1dd9c8ee723e7da4ef2aced63c1dbd53ccc52cb", + "0x8ac3209349f0142546c714ef7e9d1b094aab5469b8f080c0a37cb0362da5349e108760f272fbba770aa468e48d9a34c4", + "0xaf5f48ed74b21e3f2c1430192adb4b804dc873cd7e8f07130c556c30e7b78df0ef5a14b205368848fa9185e5a68dee0d", + "0xb8b741b65d68df89443523ba74203226f1e0d13bab073d183662d124e83e76cd318b2bfff09879c04d81b577ac895638", + "0x914abe4282d11176d4f2f08c6f15e6c2d0cde1ab4de00bbe888015c205f51929d97296a0a8d3ca5641f085a29ea89505", + "0x83ec306b2a9a6780efafe799df90b1aebdbff7d47921a136ea8a5648b9708a97231245a1082fea38e47ecafbbe000528", + "0x95d6b58d70b388dfcee4eda0c9805362ccfb60a87603add565b175b2c14ed92999dfdb0d3724ee3e5d30535f282641e9", + "0x97eeb4de607c8306e1d4e494f0d5db126d53fd04983ab5674ec5996b971899e734fa4011f2c889da21154ea1e76dbd2f", + "0x84ff21977fbd873ea06bec444d4ec9ff0e3902edc29dfa25f3bed269b3709e3116e99dc06cc3e77f53c53b736bf8fc29", + "0x8ecf483874a040a4a1c293af145094fedf203a5eb37c3e165857e108cce3e1210e0bfc0f26f4ae5e2194024929ba034d", + "0x97d9b92b2ef34609d69402167f81bce225ed3a95718a3b403f702b93e96a121a8f7f072d0ff47e8b25164e204d1576bf", + "0xab87c39cca1803b4e84b32e40ff30289e3cbbcfbe16a70f9e025643824752359be1f10c3e5398df402b6fec64d5a3537", + "0xaf84ca57e6944332884b5c84750afe0d5950015e127acec161853d55d48fd864c7da8d59cc5aba4ceceac650b813fcc0", + "0xb1d23d98edbe7089ce0a8432e0eb3b427c350fb4bb39eb2aca3c2bef68c432078cb9b4b2c4966255e00e734fa616638b", + "0x8e2b5252e0ea96d40835ebfb5693af49946509975682d68651396d6bb1463f09e75fd0afa04ccea49893b5b9c3e77e40", + "0x8db25e762f1d4a89a9a1cbc61c01698e775906bc88a921b2905735457a35df9ab84bae12e1b1b8dafadd50212f1acda1", + "0xb5f7cd163a801770a4034e2b837e00191b0ac63a2b91032ae9a99ec182d748798df48a14644935fabdbac9a43a26749a", + "0x998e7232e5906843d6272d4e04f3f00ca41a57e6dcc393c68b5b5899e6d3f23001913a24383ed00955d5ec823dbd3844", + "0xab2110a5174ae55ebb0a788f753597bd060ee8d6beafc5f7ce25046ea036dba939d67104bba91103d7838b50e36703d1", + "0xa211972a4f6a0303bec6c86f5c23c0d25ab4df0ba25876cbaad66ae010b5a00aa0c5daded85e4326261a17a563508a25", + "0xa49f53496a4041a01e07f2c2cf1e84e2ee726917bb103fd267451b9b7bb1331c0afde85a79a55409bfde27328b2a4745", + "0x934e915c67c7fc47adeabdde49f63f04644fe234672003be2aa0a2454dc8d9288f94293478936a450f2e3f249d395b5b", + "0xb6e69e9d6808ff7f60a01b7aea6781495d7a20f5b547852d3f0af727a7434209d3015a9dd04cbe3e272918e32e345508", + "0xb348d3462092b5c6fead7e515e09611438db8d69650876dd3b56226e303252bbeb9e9f3b888fb911445b0c87132a1d0e", + "0x8d6510334a905efe5a32001e167f1ba06f9bc4af7ffbf11b7f7bf3c0076b5cca373d8c47e98c1ba8755bb22632bfe0e7", + "0xa2d5200f20985dcd473d119ee97e1c0fafafa0f191185bfed9cac429cef8198d17665dac4f70342eea66e6e4a7370d58", + "0x8dd7eb6b1841b3f33425a158d33a172b79b2dc8a01378e4174e67a1a4c8f4b887f02c7c3a8f354ed9eac718155bcdf37", + "0xb16ca19388642f71afcd9f7007b490d82f83210ac1a989da9d4bf4c419de07af8c048cd301ec7e01b9d06abda7c169d5", + "0x93cb2d847d1a88de8c1c9d5b3c83efd0b7afb3682942bd2c8ab5ef35b33dc31a097a3e181daab8630d4e840b677216dc", + "0xa8b648c769e77a7b41c0c689fe2fba9bc585067e004bcb1732cb7b1618e97b317781c36c23a00680fc780b58c301a789", + "0x918c321100d57712866bdae84edf7e42df30a32853af257e0cb4da028842a43b49e775f3cecb85cd817269c728de7319", + "0xa7b0f6ce42e00c519e69b2c78fd9b75a2e7103e5892d3c1afd70c9b5b9e706180a4bf73dbb2d3eed52bfd521103ec5b3", + "0x90041994af3322b010891356afd8115340bd7fd7ba328716fbc4fe458236c8cad8c7564ae473d6091ec3a54bdab524c0", + "0xacb1ac83809573846231f9be2dc5f3e986cc36dd9574a620b1cced45bad0b11ea957ce8c6cbf964a0af916781c574f05", + "0xac54677dc002698fc4d454c7beb862ad085d0514f92576f3485a44c0cb47afb9db2c085058918a3508f9b3de0137d97c", + "0x8dea56e1bfa150e442f8484b2952b116781d08cfa3072d08657cc09b0217276efc4ab6f5fd726bfd826f6976ced8da29", + "0xa2b09e25baf01d4364b5205fa0c4dea84ef8fe03709113b034f88a0f0a502a81bf92c1d4641e2ac9f3a6f4203d3645ee", + "0xb95fe37aa351b4292691a9c2e547224c37ec2751a31ecce59810cb2ae0993da6fbe5efe0ab82f164462fa3764b6eb20f", + "0xa3498947e91a3a540e86940be664fc82f1e83ff41a0d95eb84b925e820602a41b7393c8b458bd4ebbe574a754586787a", + "0xaa2516d3620c832e5728fefdb1af0be30c871cbad4b166a7a4565af676e73bddc2f2f51acc603b3a022056daad2b330e", + "0xa9251b56467fb55f64c70729e2ec77a59d7eac79cc0b4b25ee405ac02aea46bf1cbc858bc773934a6d9bea57cb528185", + "0xae8c0a4ca7ba6bdca8764bac98df0581f00358db904e57867e6ffdf15542e55f7bad2dedac152ef88038b466ed901934", + "0xb0881e27e52cc6a57c4f3f278dffc7f63a9174b68bc867c16d8a151d9cc4d0aeb703d1074d1927faa9ffb43e10912c9a", + "0xb67138465d6654ded486d18e682f11a238d6a65d90f23d6b13eb6a1b7471efbac9ada6345dfb13e5432196d2a256829a", + "0x944c69a6f1126edd38f6eef60b8a5bd17147ab511e44e8e0a442e87244d8f35236ee0b8d3dac0631f8598f16486a5f74", + "0x995679dbe03dec775da26708cb9200dabcad983825f1ba601eb9395f9da350ca71e8af61dbff4c668fd0eebac7e4e356", + "0x89de362f02dc14de6995d43cdea3c854a0986c605ba5eb5dacf24e3a85983229bc99a2fcf50aba3df59f0fb20daffe29", + "0x84607f0e2d078df22d0866285614f5d78cf7697c94a7d1b5e02b770101ceecbfd53806b377b124a7320d9fed65000b97", + "0x93e3faab60050dac76ab44a29bcd521813e76ec8e4ae22712d77bb489bb49f98f9087acfd6a77016a09a42ddedab2d73", + "0xb7d64a7a35f21747b8e6a874be31ba770c0d13cbd41448411994e8cebb59591295a26bacbf74ee91e248a5b111aacca0", + "0x8dcad429a2b0d66b9eb8c1c3924d7a72979727db6a535526a3518bed2a9532d12aad1c5a778824ca4cb98e3e513f85f8", + "0x980882895faa347bd2fd1dda7b8ee7ed49e69843afe646f677b371eecc7a10e0f4e40bb55f28995a40080df471876816", + "0x89e8e7fb51df79971e2f7bf65783614abbb0d7f3f1b4a15d3f0d160deafa7ed1c446d9a5ae1a77160d4dd94ceed8af13", + "0x93fda8d350392e9c4d4ffe6534f7e7be53f32483d9319093e8436fbb8166a3c01085dc858373e65c7f4d014e0dc2bab7", + "0x897521a87b7ebf7152de5260c0875e3c7df1c53e734c672569219ee6f9bd196c5ecef159b6a1d3b7cd95e91b9b8803ff", + "0xb59affa408a0f7bd7930fa3b88750fd043ce672c10a3adeba95a12f23f0dda1793f761a86f7409ce1e6fd3b3b7195381", + "0xb4422ccc12f4fe99c530cda610053af9ffe635b633d52492fd81271d1f6f91b87171d572d5bd0e46ff63e221fb2fc4a5", + "0xa4542cdf3346ee0867c08d630c2aefc57442f1c05c0eba52d223bfdca5e9d0bb80775cff6ce2e28aa2730231fd7b1bb1", + "0xa7d297bb09118b914d286e5d1e87bdf13f7d174b988e38fb5427902e8e8c674072f36b19055a1070abcf357f8668f35b", + "0x9213b0ae24b7cb43ae95e25c09fead8bdbac55141694137d67eb5eab5e90a348a13d4d4d2cbc6436fc4f4f9f7334ced2", + "0x8aed71a0d116d832a372b42a0bb92a1980f3edf8189bdbaed7cde89fc0418b3ab21a04f5c6e1d3b8edf73f1f62bd6b15", + "0xa6c47d77d714c285c84c6b9458cbec5e3b191c0502dffd10ce049cf1ea27ddf868ef0cff13a2377289fa6c932b8e4f28", + "0x92f45622ec02483f2c1e07075a6695416d3768c8984856f284f40734346d56cb5b3322f20c2c9f0ef8e58ddc294a309a", + "0xaf6450d02b79ac9fc79f35655b58fd3619cd5d38c5317564b453f5f2d79d7a030bf767e399fe01b658a72fbd2cac2356", + "0xa3c01fed5240eb8a61ffa8ff4a120dbcebb53b8e19845949c77fb4f9b2c3dd52c7001df6219ad2f76c785a4ee0f64a2a", + "0xaf3136bfe8f774187bdf87555a1ac505322a956229a285d28bab1c88d4f4d12245af8dff35914a62e90e49f3dce6acb0", + "0xb20e21d28444fc96737958cd951858fda324b924b4d3d08932540fd4b87150f053db6985b96903906ce83dde0578cbb2", + "0xb7978101071268d1f485134b4dfd1e35f89b82c7d99ae91f58b6745f5e0273b7e06f3b23009033ecc3e41b2e9e85219b", + "0x9104b7d75245b784187175912cc0ad869e12f1983b98e052710fb33663224362bffd69ceed43e7d4ad7f998c0a699eb7", + "0xa7624cd71b92699ce3fde0e747976ee04ee820032ac45dd27d769edf3b3379a4b8db358e50c9d057c63b5a9b13d76bcd", + "0x9354a76f294005de8c59db10e638ae6e8c6d6b86a699d8da93143da8478d36116211c788d8285d8e01ea6647dfcaa1aa", + "0xb85935c04cae14af9848db5339ab6420122c041075ec1549314e3c9c5a610d9b794ea3617c50ca7af6b4aec8b06bc7dd", + "0xad6835a62311c84b30ce90e86c91c0f31c4a44bf0a1db65bf331b7cf530cca0488efaac009ab9ed14c1d487da9e88feb", + "0x80339f0245cc37a42bd14cd58d2a8d50c554364d3a8485d0520ea6d2c83db3597bf51a858b10c838bfc8b6bc35619638", + "0xb370420ac1a011f6d8f930511b788708ccf2fe23ca7b775b65faa5f5a15c112a4667ed6496ae452baf2204e9ce0dbf09", + "0x8ceab3dadca807a1c8de58ac5788313419c37bc89603692c7a4d96e2311b7fe9e813cc691a7e25a242828cdf98f8bbcd", + "0xac1526ebc6bd4ac92ee1b239f915e494d0279fbd065e4cab1f1b8a1663f67daa89560f6c99bbc3e63fa845520316d2e6", + "0x8240ab0bc36a29d43ec3059c7e6355ff39567e135f93b243145d3ada97fd1c970743819e0d58bd5171967daec144e7a1", + "0xa99743192a6f1967511b2d3038cc73edacb7e85f84b2926d8880d932d2fa12f5215592311a7548494b68a87ec70c93eb", + "0x8ffffc31c235997e59ab33c2f79f468399eb52b776fd7968f37a73e41949111957434f2c0a27645ab34c741eb627cd1f", + "0x8949d955309415d6d2cf6ee682ccd0427565142c1bfe43b17c38de05cd7185c48549a35b67665a0380f51aef10b62a8e", + "0x9614f727a9dac8ecd22b5b81b6e14d34f516db23a1a7d81771ddaa11f516ed04d4e78b78fda5dc9c276a55372f44c4d4", + "0xaa85d3ef157407bd8aa74032f66bc375fddaff90c612470b5ff5d93659f8c3523b2d1b6937b3cc4201c2aa339621180e", + "0x86f8fe8bf4c262dc6a04620a848e3844f5e39a2e1700c960f20ee66d4a559a90141ef4e5091d0f32acb1e915af1e0472", + "0xb3af2eb785b00588371beb3b49536b7919a3f2175d4817de5dcbf7fcc20c512852ef0f313327fd0589b10173f77b92e0", + "0x8388703c512eea59190351f3bd2cce83ff8bcb3c5aefc114cccf9e9b3f78200d8034c3ebe60448aaf6c912f0ff8f0cc4", + "0x95d0dbbbf08ec1ed3975fe7dd542be0a05156a2b3db5092825d918a849411ee536ed958201f74a5513e9743674d6658d", + "0x8d1a48802f1a2db247e633ddf61d3ef7a2c062c48dda59bf858916e04f56651a7d51e367d6535964ebf3ae6d2b21b421", + "0x971436871bfe868f25247145a55802945409b3150008535b372c949760d7949dd2fdb40d9b96ae7473bc8f6e9b83ecdb", + "0x8ca431728ac0f156763090828a7b6d860bf591e5b9dd3bb3b7f3ba0ca74191f9710ee55efd32db7d18eab5b479cee8a4", + "0x81e28f1a506e84c2b9aba1df720cb50e0b597b2c22f98acc34e710c934cc6f97dcaf33d589e845c2c1f6d8716d05ccac", + "0x8f43b11d3f00c41d16c9bc9bc0c44227c056bd77de4f1ca9a799418c5601e744f99066bef47da2d9088ae88eb259327c", + "0x8d330aa52744c08ef98cc5599eec8b9b4dd18aa01b803f1d1ca0e29b74f1aa2886ed0224390fc377af25852851fbee03", + "0xa06f5b203b67134c685039ec2bdbcc787353e2575ce73a415db24a517c0c31b59d1de89f12b97cbef0219fb6a1e90a20", + "0x9269a5f49bbb8fec1a387b5d105df88a027de615d5ca6afae20fe89b11746f8d23880db78dac238c955fc8bb3de18046", + "0xaf5074b3bc0656421c314547b45b5abd3045ca1b17f5e34ba39d8c1f7928a55d4ca5ea9c2ab59a55909b25255233e04e", + "0x8e7ee5d733c8e08f3fb7d85f0628de3de6835121672c65374905dc6d19e02fa2df14c13d5e9835dacd609a4df09abd26", + "0xa9b9aaf83d31e879dfb8e73a0708801b4dbdb5d7c8654b27d2c0f5797ebcacc8d00a82143e2060f0917c9d41f1a03de6", + "0x904872aa1c093cb00e1c8e369a3bdae6931c5b1ed705dd3bffba243dc4f42df3e7d7cf70303d513b34d2245743d765cf", + "0x8a4d6b3b1d6afe67383c66693f70b397e510be28e3d97dbc8ec543d699b6cbb0e72eb90a7f65e83cf9f7ef50fb18b128", + "0xa914de13916e6a0dc0e0fefecb3a443cca80d83276513b70c22c6e566a2d41acbd33a0e2836ee09abeffd3a4894e437e", + "0xb9c408f5f05934b0aefab301ba22f8254c5ebbf5405b6aa788f76e4b328c150b395f441e3566015a0deb3eca89afe9ff", + "0x8d32aa2c81b2a8b89f347c2e0b6567b2117ddbb778fda8a3f19004b7f5aa9dd814b9b3ad35f9223715d2447b2d12f159", + "0x8230e8b9c84cada1bf14ea6aa9ecdadd978d893cf5962fee6c7167ed21239210ea491987f2c8f2e8cfea8c140704ca28", + "0xa5d7b6285fea51c6f21d0976a7c3a97baa3d733a201bfaac0994db6c65611d91c5fc0ebc2a7724ee02b371e575573649", + "0xa54f00a9530f6930069f5e3a8b8b1d52ee1def0aad1763e3c609ec07f25410969b43d5943a94c235ed5eb207b33a402e", + "0xa8dc6e96399b81397734c61c3a8154e55a670fa25fa5854b3c66734cbb4ec0d8f6ba650ee3c71da3773ffc9e37abf8bd", + "0x8841fbfae1af4d400d49f74495f864804f043416c09c64705251d021b3ab7881f134a00b0241e61010617d04979d747d", + "0x95acea7ff4861cc969c1d8cc8775c5eae014ad6e2e0e2d0a911dd916c34ae69f53eef779cc24ff1eac18c2b478d3ba2b", + "0xa5dce74abcfb8c68031b47364bd9baf71a91db01e45514ab6216f5eb582ef8fe9b06aaa02f17be8b93392d9b19ab9c06", + "0x89e111169e4ae2f4016c07c574a3bdacd8d2f359561fbbdaa3474de9bc24ef8936784dfe6fe0e29a13cac85a3e622b61", + "0xa4c511af6bdf3892939aab651828259e4ef6ebecfdd503ecc14e61001575b313a89e209cb55a77ec19a64d29ada066ef", + "0x923c62156fbf3a44926ffb5dc71f7cef602dbe941a98c61f019a27a18a50c16b6135b6099fe04a2e1dc88a6cad989fb7", + "0xafb9191c541b61afa0ef14652e563cc5a557842ce2afea13e21507dde0ebbe6da5233af949c998c00865c79bb3d45ec8", + "0x8a1f0ad65cb2b225931f41dc53547d756111ecbf5bc57c5ee2cc1ffd61b126d0389d311ffe26cf06eaead95af09c5ca3", + "0x9040b20b5ac2e1a9d30abf7a4eea1ec2db8f3077cb2cfc8736b37222d8d3937f5d9f421167086dc5551e9f0bd2522d07", + "0xb6d888b8c6bd448dccaf99c3f690d47f802e134709ce102fb6f6fc68156943c0762be6f386338163e01eed2d1dd5f734", + "0xb94f0e27bbcda793e4a272603b3dcc739d3bf3207798df7319f8dc9d37cbd850e3724bdd30498c929debad971950223c", + "0x9769827767be9d7bacba1b687289e0794c6fe630d33c9b607da1f6a65e3f34cb8bd65327d9287c8c5f3c8b5f6d3d133e", + "0xaaac72c993aa2356c9a6a030950441de42b2d746bace29865382f0ef54835bc96958b2f00237d805ee6a69ca82117c1b", + "0xa2b1f027d80c1b0e79bfc7dd252e095b436fba23a97a1b2b16cdd39fd39a49e06a1ca9a1345c4dbb3d601ffa99f42bdc", + "0xb3fa0ad1478ca571e8aa230921f95d81aed7eca00275a51b33aadabd5cb9c530030691d1242a6ff24e2d4cfd72a47203", + "0xa43ed4368e78daad51b9bf1a685b1e1bfe05bed7340d4a00df718133f686690c99198b60031513328fc353c6825a5f2f", + "0x965e145711ecf998b01a18843cbb8db6b91ff46f668229281d4ca52236c4d40804ebc54276e9c168d2a2bfc299bcf397", + "0xae18e6efc6f54c1d9230210ac859c2f19180f31d2e37a94da2983a4264dbb58ad328ab3cbc6884ce4637c8c2390f7fc1", + "0x83a9200486d4d85f5671643b6daf3d0290b2e41520fb7ea7030e7e342d7789023da6a293a3984308b27eb55f879ad99d", + "0xb925fb6ca83479355a44abbcdf182bfac8a3c7cce6cfc7962be277ce34460eb837c561257569be3cb28023208dea80dd", + "0x9583dd991b62ae4bd5f379ccd3cec72cfae1c08137ddfbacc659a9641e7d5a82083de60005f74fc807bd2acd218d0789", + "0xae73bc32e9ff5926e1e06c07a3963080881b976c9875777f8e4cf96af91bf41bdbed4bd77e91253b8ec3c15b4a6d3977", + "0xb2a3ea90aa398717ba7d8c46743e4c487b63c5abb140555d8d20e5115df2f70d3c84a2cb9a5e0536b2d93d24f271b38d", + "0x91d119d3bf1d34cd839eb69c6de998b78482ab66bc93fa97e31fb9592f36cdfcd673f52366f8c8e8877e313b92d4a2ad", + "0xa1907e20120902cf68912cc3046f8806cabbd7673e80218814cb088e080dd93b5dccba395b13e0025f5755c183276c3a", + "0xb2e2011df72504065ec4c12cbc2137b95cfcd1355509671feb7b00dbf7f8d500476a49754cb7fb9219cb5cba7c8afe01", + "0xa48589fb7a74a3dfd782cb3503e6294a81dbb6adb412887569f9408e9079371edbd9822388e0b7ec8d3297ba270f53ef", + "0xa203909bfe196ac65ed3e6800d577b6ca5c8fe1d40f7f925a43852951e38883f2ffd250a9e16fab3ed3dc1249650247b", + "0x997ac293722a8b98f7e819f8e6c2d4c5bd1103b82d489d8b8aabeb905e95450b9b75bd61442cf68cc957212ec1c55617", + "0x9895a3de62395c33509b153b7820bd94fd2b011f0cac135fcf916482f1eda272ecc79f83a61837e99c3a3c4ab2c5c2a2", + "0x98c2ece4d49a64ec8e06407a0585081003bcef88af35210e22eab91169f8f0c044d611494b755e5bd915804b1d857747", + "0x8bc6dd083b36d076ddf0e0bb1bb87cfd059283ddabb3886f02eb7e27f1f0539b2819527b56b5c13436523c4603ac1d12", + "0x85ab8b7a696333c82dd5e179e12b2e127e67d911de609ff9a03cab95cbeedb1f364aa1f2b5e59353e4ba0d177f996151", + "0xa9478e214afa68c395aa2c7daf8ba1627feb71ad6d8bc7339734cdcdd5a42838e032736c28e6251c808d5a4875ef0d06", + "0x8c53f62cf06a35321c8af3871ee4459768d0745ebf48942b9f464206309f42fc7b2c50f196ae1e43b664f0e2e718a23a", + "0x8ba80662f6642d8866e832ec8082a4204ebc993fc304c4b794666856de0407620131a18dc053597bb40a3de0bf8aca22", + "0x8c8fac6b911785d1561a985580c03fb2ebc613ae33e486a92638aa7d4493374118d9a6d9d99121e29c68c3d67ee4e3f3", + "0x90f2c793eee07ad90157040b30558bb3b0164e8ddf856389d6742cf5bd1c712e4c6a8e5678da70a8e9e242ec7864117e", + "0x954abed8f6d58896b7f6438c9780236c1c83b02d60a29fa7361559e619e5bc9d67b3646ee39ffafe2b3019bb3357fb50", + "0xb79874f757a33085e1e751544de8fe3afbea92e0234f9c00254c2b36115a16ee46f085f22aa66e0c9177e5106f51b03b", + "0xaa148b287cf4f60c64f774282b421aae075f0eaa93a45aab4927750f47e2ef0b811d1846bbb15eeb2f293c80a7612e83", + "0xa588d8825e7b0168d45499dcff6faf0dfe1ba4f090fdc7c06d50344960c0121f10ad109b0b9d13b06ef22de5a04eef87", + "0x8f61ec93d14ebfa9c31731f9ef0fb8907505fedc79378e9a3f65c27bed4d74b41e129c97672ce5f567d897befbceec8c", + "0xa008218633f1da10efd01c155f7ed739faec902da6dc48e9f19ccbc8d32bb318d71806285cf2003de2c907bbdd4f8b22", + "0x88ad82c66f7085632d7e348d69da84200c53594553acf5432b50dd1e87f410c802dfea91be3cf804e3117ce13103f23e", + "0x8498dba17de0318af227a3f9ed86df37a5c33f9a538be9823f8dce4efc3579e8296cb3b7200cee7c5e0bfd9da23a4b69", + "0xb3c0342231dffe4c9bc7d9265597bc8cc4a82e2980ac6d1407108db5b00349dc91d5116fab51cf2802d58f05f653861d", + "0xb3f2730455f9bf5a058598bc60f47740117ba51f6a767e1134516a4e42338b513f377027acf8825da5c4d047a62984fd", + "0x816360914fbc9d8b865157bfab07aeb7b90bb5a7c5cd64847b1c3184a52266cd3f8f8f3ef99309ba2edc4622304bacc0", + "0x8fd21b2315b44a52d60b39ebc45970a47b9495f42b88217ae057bebcd3ea0e2476c0c3d13de7f72016ae12ae966a008d", + "0xb62014485bc217a0fe892ef1aef0e59604ad5a868face7a93f77a70ba3d7413443fbe7a44552a784d8eae1acb1d1c52b", + "0xa905822507e431b35f56724f6c8d2e93b0607ed7a4533073a99cce2b7c1c35367382447073a53036dfdb0d04978ccf2a", + "0x81672e39c2b31845142963351de3d9cd04c67c806fdfe77467867463dbbd8a9b0e2400ccc55016e57cbedb02d83a0544", + "0x90919c970ec668de8ec48a2a73bb75cb94f0f8380c79a7909fd8084df61ecd631476ddd474b27103c6817c8f3f260db9", + "0x8fbe37dfb04bf1d3029f8070fd988fc5e4b585e61eab6a8b66caf0ffef979d3ed6a662cd99468ce98ec802e985da5fad", + "0x950939aabb90b57a3d667f9820880eb0c4fee5c27fe211ce8ecd34663c21b5543c810b3676111d079ac98644c75ee0ae", + "0xb06201ec3c3cfdaf864a66af128effee8ec42d25f1e173c1edf9207979fa52c871757000c591d71a9b6cde40f5001a06", + "0xa79054e8febd0450c96ac7a5fd6bf419c4b17a5926f3bc23a8616f0cfbc2849d97470174cd1baa7c739b12615334b6b7", + "0x81c7391b2a1844ed26a84f054b5f03865b442b7a8d614cd44805b5705fe6a356ac182b66a3c8d415132e389efac5f6b2", + "0x825af1563d0fe53925ec9ac0df65d8211b333474e59359bf1bde8861eecd03f2ac74534d34b7e61031227c2fa7a74e1e", + "0xb60dd9bf036f1825295cd2014ef1f6d520cf729b4d6cee0b42cb871b60ae539b27c83aa3f96ee3d490ec27ce7e915115", + "0x89ca43d5b7f3622b42df7887572297a7f52d5204d85e2e1ac6e5d7aa7f8aaea5e3a07280477d910db025d17cd2e7373b", + "0xb93a2bc9b1b597f0e514fde76ce5bfb6e61eee39cbf1971ea6db38c3ecb055e7913ec8cd07fb0b0ffae3ca345883101c", + "0x8d45546bc30266b20c6c59fc4339eb633155aa58f115a8f976d13789eaae20a95b064fedead247c46665cc13ba856663", + "0xaa8eacfe00e8a4d9815de3f7619d9c420629ada6489933ca66a571bf6c044d08b391e0d9eec7d1cbebe8def1e7523f1e", + "0xb32fefc59a0d0319ccb1946b351ed70445d78d9fbb536fa710d3162b9659f10288f12d82b32ecc026d55f16cbad55441", + "0x99c7c45c34044c056b24e8f57123ba5e2c2c039e9f038a66899362840cffe021733e078866a8708504cdc35816cb335d", + "0x80def162c134540d5ec071b25ccc3eef4efe158be453af41a310b7916c49ec0ce06bb43dfee96b6d77339e11587de448", + "0xb5f2fa4f68f6a26bcb70d8eab62ad73509c08ee7aa622a14b3d16973ffff508ce6f1aff9ced77b8dcfef7319245cf2de", + "0xb4d0436019e779c789464716e1741c189e8945dab7f3072720bd9aa89882fa5b085a1755c48da21541f3cd70a41b0a71", + "0x931e798ef672e1472f4f84c727a101e70d77b3a9f0c0803a5220958d6bbeb8aeeb56c769ab472a3d6451249a13a3f56e", + "0x918c10a84de268aa8f1ba24b38fe55ff907be07b1e86b4a4adbf305c0d705c1cf5f65ce99e03e11676cedc89f1a4f331", + "0x8e55a8413b823715ccd92daee357cedd797e69a0e78b6fcdacb7318646b9903dfe05e5501f47b3c52e74055b9eb619a4", + "0x8b329bb63e6c985d7d072dff4680b3f8b1217ed20543277386bd30ec25240d9dc378837dcd5cf4fd9548658635f4c537", + "0x8c2be5386052b22986b33dbc63c5afacb6d0095495564ba4aa28fc8c880a3c78242fb083248d788ed928deb1e30a82c2", + "0x83a2b7bdfcbd25d6b059f27218e009ecb5ecc4da68ead885e00216411d8222062ca42f21c4d9cfa19c31522080af677b", + "0x9620334d2633e85646b2e2fc48dc6c3f09c64ef1706ed78a3bb6ce1f6b274a727364df71e97531dfdcb392f70f27f536", + "0xb6c84970ec04545121ec3b79376f4e45053c97e8bf2b11922cc2490a429c38735466097ecb81cc9d9692c74d2fb8abc8", + "0x8e55d707dcf265c5ae29a32c27ce66f200fddb724faa5bbf145ef42280ef645fa2f0cc3cfe2db8599b26c83b91e077df", + "0xb910b96b763966402bbebd68a32c15a225ec21e1357fa298478c5981a4310e556103fef0c73bd8903e11c4ed2c065647", + "0xa8fd933a0e9fe8c459809bd93b8ce153e2af55df94b61a1490736b19c89469954da8b72dbd072d798fc06fc3d7a3d60a", + "0x811b279c113828e114fd82c2070caa7eb089a46c8cabf865f9c77354a77ebebe0c4c6400dda0e66dd017cfc44d76851d", + "0x8ed03e91c331afb3ad6e42767e1b3e8d3a35fb831805ff1b5fd3e91878e04027ff5af1165a3ac295f1578faf2c83b581", + "0x95bf53683d64a0621bf1ca6ee17446783f6c535b7a54d6ea57723487a215759a54f886597a55dfdd560424e368ab2759", + "0xa9bea378768fb1d7ba365a16531c51fc1975f1c73caf2a0891da28509805fa84e2a8db7c6ccfbc620e9002317abf174c", + "0xb8308250891015deaf851c4e5a4cf4704d104f94064418488d7e3076d49f36240dcf6fdcf83f45fe8a1d97fb02e3db59", + "0xadcda6b63da21f4074f142f8e7f3a2274f624c733e3a4001054a1809711529c61356aa087f73aed877a58ccb41d38d12", + "0xb80e7869239ae26d1da2e6683f064d1dc93cf4a2b66e9439b3ad9b25324e969bf98014760d29e6b8de7ff152ef498d0f", + "0x8e9bf968911df3bb5e3a7655e9d8143e91ee87f14464d7ba9c86e1e31b03ab31b91eda121281b79cd974d9ed2657e33e", + "0x9007277e8335a43e6bc3c2f5f98c0ba7024a679b7156aeefe964f1a962e5ac82154ac39d1ffbad85a8f2440f3c1e354b", + "0x9422b9d670e997b7c919a429499f38e863c69c6a4d2bb28d85e36ae0895c620f68b71e39eba785e3d39a45be91507757", + "0x926094e01132938000d82dd9a571fef5ef104cd25b4015a25e3442af0329e585aaad5472f0e7a69899ba2d6f734b40aa", + "0x95552d8057f7e32c24d69e4d6c51c98403f198a20c5be8826254d19cab2f84d5758e2220cea7e38b7c8a7a23178fd564", + "0x8abcf8dcc8488bcc9ab23c51b9e7a0d91dfc7bebe88b7ed370ee68eceba643e939c5eae66a4aa5fe85120751780e351c", + "0xa91bf8198f029e6a4cf6f0cc39b629e9aeff1c77b8739e1d5c73d8c1d3fb5c8f6f23e27b435bf10b5b4ec1cf6a7249ed", + "0xb932d87ee3a4b81341511f90fe5aa36c571e8b914f25abcc33dd40ca67a3f6444fe9362c1434744e4af18d6e045c54a3", + "0xa8e960c2be9b1d805d387b3ebe2134d421a65f1fd4c1b4cccdce78f9926f139eea78e3afb449b3d6dd19b5d16ace48fe", + "0xa7e2f57cce509fe66707eaba9b4c042c1be93fd6034a9b51d1d30c45c4363eac79d54663d525c9873ab0eec0b1cc4ed3", + "0xaa162a31c2078f4b080199debf24494a8dfdfb9d8fc85b198a861b12a629c73128c55a883e4c2de3dfed6e0e1b83eeab", + "0xb5a4d075433eaf4115717a84b4dc37f843d44bba0bf820c92ecdedd5afb61be60f7708c8a151a678d9d5c0ae531bffb7", + "0xb56ab96f7a463c0079e05dc766f3a6a31cae5c5044947734ebe0a26e01367c6763cc8de6c2ee2f3b8218f05bef217474", + "0xb60792ac506b901065a8bc0180a86e028fe34b62ceae1ad640c759538ebf3a2ad9c8c927d662deed6f489ff3ff7813c4", + "0x8c8c2cdf075504d12d441a58542e1f8e4bdf92b3ee4775e836b2734c5ec1e3df919b931386417d04489a1dca806c87d2", + "0x8ed78e91e5c4a68894cefc2f7fa71f02e5e12d40f1bb74332139bc7be4d92c24e07d5ece0e82150ed474aa1337af4c18", + "0x87119c22ff8aa31150bde537d863cad661cc5159b12f084cc319224c533f0deb28526ed8568d00a1441e7d8bb4f05673", + "0x83a60ba5a9cccf22cebadf7318b706c9f29abd25db0e2fc1c802965351b53cbf316df72ee3e9b2d3ae7f3c4494cfdff1", + "0xb73b6a9fdd3e7463fbdaabc9a885b7c82201ad867d1bced1c2484300a01cbbb3f1e21afa95d4c7cbb6cb983416b63b90", + "0xb1d89ad16981ff9217708090d4017662d8838f21f3a3296cffe14590b533905fa06a20e40dd497bd291fa4dfd1bfc511", + "0x8abde560083e071a402e3c7bf31930f537f67d2a7bbc734a7480b1b760aa712ebd1cbcb65b00e11e384e980222fe14a9", + "0x89c731d8f31afea8bdc9c32527bdca257f2a840764d40f6e49403b8e75ae51017d505ea4fff91bf28b6f3a1bc65b8bbc", + "0x80e9ac8e077e86ad050ee73dfce268a69564ff1b8419e9c236d981fe7a5f0c2bc756e8603ec604b3b9e36da8fe10a49c", + "0xb4f1eea0f304898b1323c6382732e6f40e556bfc68af9ce73f6d54e92f5f23cc4f78eb3f43d578d81e7627fb40f092b3", + "0xa0e3a8d1348f8f153e08ac4839232d75d1d6e81b5de184ec4724f8213baf98d3fe739a96f6b39d79a053b628c3a09981", + "0xa6915ba0b52ffe4a381bbb8ff3791d9d3b848bf89b3bacbb2a7d2e5ae21f1353cdc304b3cb6e82416f7e604035c27d7e", + "0xb2c4c9cdfdd2fc9a340ba3ade9423344b9f429e8c7e20a8abbf26400376e312f3ae35d1c456be99dfb5c02fc8a36cbfa", + "0x9657d57ca0641825a0aa5687f3f87659d893f33aee819bafa5b1ca1db554811c1c844f971e278606e3a2f096defdc67c", + "0xa4ad24d0a557704ada24d8e27a15604bca28679e260b2c69ccc8e6cae5499866724b700605a90df7dfb35130756939b9", + "0xb18d9ea6682f73a1f99a9a4fc98c38fcda02c1a18e8c5fc080cf935a2ac877dc5223fca273dcde190b906178d0fd05bc", + "0x8ea5fefad0799c885f50ff10d94bd0af5b99b0a446cd1f367ae5ff529cc47e09f3018115f3c0ccac2fa05bb65b84945e", + "0x92450d52e6c7d13ebfcdf5674d6761bbae2fc5aabc865d35d031b588c383e0a64cf69a73dc93948632e2b98f74a5ed86", + "0xa356f171a98df4ec5a96d556eaccc6ad34b4238aafcf0e94ece27cdbb491749fc9692e78b84dfe80bdef2914079d34b5", + "0xb918703a4d3507d266414712ba8eb7ad17da07cc5f952b5c62ef130cc6ed1ae3bf01237fc8848c179725bdddd465b301", + "0xad2b0554570bfc9d97510cf59bc38e10ca54a93649c30ac9919bd0255e43bf525ab11b74f78a51ac0973cd0c5a5dcb54", + "0xa7ecaf4b631d179d32ac1632390d95196a0035e00da6c0e6e13b5c09ae44b15ae6c21538b5a31b73bc5f650ecd979b59", + "0xa37704eb4d728df2a367e59fcb6c26023136230e37f3b8a2f3ceeb1467f5cd30186fc0116f98b64a8146fd2c5903e8d9", + "0xb09373ce92314678299ae10ec1f93c702911beb4115c6b5ba6efbcab9c7afb599f59793912df70a98868bce6545a33dd", + "0xb52a878a1393094fd2b93f2d1eccabf2830ab10800ba4cc24dcc7849cd0978733263aef2fcb766a7cb575a7a99383db8", + "0x8dac097e006fda4fb9d6d7ae52adabd9448ebc8d5bd5b38ac0c4ed38ceb510763174f7adfb0b473c38e52147ccab4239", + "0x86b19c41efb949937d74a7875549ee5e997f9fdac7f7198085afda233cf74341a38d0ca3767c76cd35f875b89a35f78c", + "0x99f0d927e5ad25cd134f1c70b72631cc6b5cb4ddb86c0642b900464e33d971213a5239dddaf71f7a42f2d6d02a12dcc6", + "0x8355c38806c335d747d4e97f0083fb96585677da18b409a85175ec35dc3f74671817b34203eb18c2f729717ce083ede8", + "0xabb3603adb061a036eae0afa5f23d79c3b62442e0e3bcdeef896f88995585c1105cd3065410368456a4d36b5b0485a83", + "0x9051c5c0011784885187d04749f774b9b4f6bc594b0e4e18226de79dedc4d7aefa3529c3d2c728e180f96f3e204d578b", + "0x91888213e7d321d0bfac884edbd5cb756b280753bb5f8bc6acfc208f525757beca24bdf86fc68d3d8736ef176a960b49", + "0x91258bd7ce6e3b7516fe2f5391a368d826da299e0e99b1f82eaa44b62b110ab696adc92debab8ba098a52f38dfb3c5d8", + "0x96e3907340dffa9da3602d3b94bacff7e1bb8649edd3b9bbd06e1bc6781e78f91ababab12c0b9be7c66dfedc7001b66e", + "0x9513555688fcfb12ba63952ab36a67b36affdd71f7b843e8eb99ccbd45421698024608233efbdc905eaeb26b334b33af", + "0x9913ca9bcf11eeb408da02e4317c5ca0010fb2f4490b282ddb758001c08b438c3b35351a8cbe10b7fffc1293ccd22d4b", + "0x85dc2471860ebca88e5a2766161fdd77f926d2a34825d1134a30418f91a741759668e32fd1e37c415d07ab5824338e8a", + "0x8b128917e828a0b5eb6fa8ed72b52fae2dfaf74febee69a2e2f87e8df702f0c5bc0fb620c8d1d2a07f35a15ec9c0f5a8", + "0x964c39e7840c130b01bb481ae7bfc92682b0f124c9c383f9dbf3027f2249151925f4faf36905af476a54778d69da3f48", + "0x80671ece658cf850e522d46d25678f934ce6df043f25f8707235125765d40c2eaaf39eda6092f75039b22cb58bf2c29d", + "0xad4bb0e79fdaa340b1347a46b0f64e801c72a89770dda0a6e4bfd35f2df5146fce9934e4baecb1c2671077c771eb8089", + "0x80b3bd3adc6cf198fcd997f8867d2839a2eb28f57390352ec423b8a14cc1f2ab21c6e286505d6a21fb134dcd8d8f11cf", + "0xa26d46a6b8a75748895a1d599e7fd120d896340e79813167a400b2fe463452532a4cab419074663fe1d29fa716b76a33", + "0x82b1f3a8a1df29207d7ff020809113ab06080a7f0c631f76ad33f47cdfb6a567143144df97b4ed7f676d929195b04bba", + "0xad96633a3744648ff0a2e4491e8219c9c6ba6e655cb058c36320a8f72cd5f72c00bddf97083d07650ea9ddc005fc1ff4", + "0x91d0783788626c91662359dc3ff36a8bcc6831e3f4114f85c99910256b1d8f88a8612f53c7c417d55581dea486f38926", + "0x84edd9e87ff3d193ebb25f43474c33fe502a1e2100fd3f93fda6520f5e42214cc12e9f8045f99aa2423a0ee35e671854", + "0xb55e06a4b1fc3ff9a5520e0b7c8b5ac11b28385cce78d91ce93b82f1bd7f7afdd4195d0c13a76e80d0ed5a4f12325fa7", + "0xb0b15c7ddede2b81d9c835ecaa887650622e75d0d85f81b8bbec7ef24e9a31a9c9e3de1f382d8c76d878d1b01373f6c8", + "0xb1adb47c20f29784116b80f3670182d01b17612d5d91bd6502b0dcecdcf072541f582aafc5e7dd9a765cad52151684f4", + "0x8efd1018df9c9e9814a9c48f68c168551b999914a6719229f0c5bf0f20a288a2f5ba4a48ba966c5bffb0fbd346a4fcc6", + "0xb34ea2bd3269a4ddb2fbf2514401d2712fc46c22642f3557e3b9c7acbce9b454dcf789573ede9aa14f39605fdd03f8c4", + "0xa9e1428ce24eacfc460aec2e787c053327ba612f50d93510d58b2cb0f13291ca3d16358325ab3e86693fe686e4f526f7", + "0x91eac7361af4c66f725c153da665a3c55aca9ae73ead84ca2662cf736fe6a348a301be1954723206dda4a2120202954b", + "0xa6f02db89739c686407825fa7e84000ceedb9bd943e8a0908fef6f0d35dbc33c336072ba65e33e15ecfcd5714d01c2f0", + "0xa25666faa12e843a80365c0fef7d328a480c6e3cb7f224763c11d8cbabd0e7e91a5b647585ee905cc036afca14842bae", + "0xb4348576439cd2e48c01cb9cded7cc4a0ea364ab936dd679ddc7d58b48807e7fab070f2f1ea88595b11af4500849026a", + "0xa8c6c731e0d0464ef7e4fc1b049065eb4ce100c01e1a376365c636a0b23851022bf55805963bc15eb57434a837e81167", + "0xb0952937b154e3a4c206f96cd96c76ba37624956b0e4d43470bdd97b4af878326b589e3eaee82fc192437123096799a2", + "0x97d07ec31ecc9923192e48d37df2cf08750050fb452dcfbdb350fbc43e146bae3590c5b732b31ebfa1ce5d884ad5ad57", + "0xa69359aebbfe4cbc4d39d178150039fbf284cbc0edc68a6bd635ee3a1c76569a4a575c907fff691b2a4d82a384c2945f", + "0xb321c2c0f6b5902ee9056cce7404d858da9a573d27348c1a6bfea29b2746f2aee7abcb6192504e5a583b0caeaba117d7", + "0xa74e738aa6eb4eea58855ae6f422af22812fb388c83aacca5bd5fa4a88d4c01463174a229aea2830c348dd9ab9307854", + "0x94306a3b106bc1644346bc45c05cdc8287811d5c86cad691bde0c65d6a686eb9c0ce79ad91baa4547e5d058ae8bf7310", + "0xb64140fd77a07633e4ca8d60786452311dcdb8ce7095ba51dad8486f57c3bf4e69bced92603f71da992a48ad817ab275", + "0xaffe7f4310f1dc68e5e3cd640bedf864f51bfb46bb752063bfc18e95930021f784e509261ff9c560f53000c361b142d1", + "0xb0d2fee222c6f963ba3385547f921a48964da031d737892604f8f2677d4905dbf615046db57eae6c6dd756709ae6932a", + "0x81700c66aad7c2e51168e028b0fe086dea75d3b17d93a4dc1f47a6a0f025df0bae1c8c997901837ad859a84197e7bb00", + "0xaa4ac5fdd602f8b79cace18690e67bad557a93d00c0e295074185e8c6b4059a65495d9971685de2fc01d2171ac8b706a", + "0xa8becb3a64fdf35d65d2857898dcf8053b5057a73ab8c5bb5324af1a8015cff47efb85dc3eae7364cd5c850b7962bedf", + "0xb72ea09bd0b72f8cde3466f359ea69b194ede93dced534efba1b9ebc6f3bd53942fe2965e992e82edb6050cac4ed88dd", + "0x85bb8dd7eef023a251fb6f220af54687747f4c91983ff728163c4618ffac40ee6edc29a0aa6d455276bbe017f63757c2", + "0x85a485254a11b4c4a943d9ec509c0dd1cbfc0ff5273a00cf5c9f0babec973efb15348e5d9451b548293d778e3a2b62a5", + "0xb109f3ac809391e772b589c196b013db69a9b2b10ac3898feb70b986973731f30722b573cd0c9324158ec20416825385", + "0x8a4eb579a840d438bed008644f373ea9ba2f28470d50cf1d70af38ba0e17326c948527b1719dd1bd9ac656ebd5aedd10", + "0xa52e9d66ead5ee1e02ce6108e4ded790d8ec83164a0fa275ab1f89a32200726c8e988d66df131df9e62dd80203c13dce", + "0xb541cee9febf15d252475507e11d65c4b7819c26cf6d90352f5e8a8f5c63e254eddf22df0c35a7be5b244233e8e4ee5e", + "0x8153c297772adf4603c39349142f98cc15baeccaeae10c3230ee87d62255f6814d88d6ed208c368d2c02332426589748", + "0x970dc9782f1828474e9fab7dcdec19aa106725465a5844caed948eef5c9e48199c1b6bc1a637ed7864116927e84bc65a", + "0xa975a920624967f4ecc77ea5d9869c434caa64c330024194615a8d0640c5d4d4fb139ea11a0c73a5c6ae6dd3fbf0ab5d", + "0x811f0f9e0c12acfb4b9dca359eaef3bed18083bad96188befc036ad3143b121fff4777ca6dc70a835bbc4921bd25f5ff", + "0x82341c6ebdb97c8b72910da95c7eebccd1308b6a92999886aab552f0642882d5c7cc60931577d200efd6066530c998dd", + "0x860f7162c2f5fd1c0953c6ce75bd8c52eaa48032b914410681b8cc05e00b64130d1f96ec5a52df66a04c78a9f9f42981", + "0x8a578e674875571fe1a0459843495a5ee1d9fb6cd684b244feb9488f999a46f43363938cd0542879ea18ed14fba10a6e", + "0x8df217aba4da6781f0f5139aced472025523ed6e17e504511c04b677ca8197488e237d8bb5dff7b6b3898cd5a6393dd5", + "0xb2c9230ad35d7b471d3aee6f771517cf3145ad26200bd6fe9c7cf28120e2945fed402e212d2330a692f97bb9ac4dcf12", + "0xb78b89e29e8b782603b222cc8724eeb83b2d9d56bc02f59a3c899ab76429dc721358b07dcdaf422f59520b7e7ab4fb55", + "0x82682a5617843c4ac8d4efb4c3ce715c76c1da2c3bab1ede387db503f3489c1bfdfc07d9231d96f955df84fd225bc81b", + "0xb0f53725cc610e78b8e8a4e6823a2ffe44dd15a9a5bc8151ab7a3787ddd97e1d7f2f0e6efd2876e5f96417157143e3bf", + "0x92c5a93233085e2b244519078770c7192af62f3562113abc8902f9d72591eacf52bd15ce78653ab9170d5067606287f8", + "0xa43ef97dcd9b6ad288846bf31fccf78df72f94bc7ad768baf5bf0d5dfa27bd74ffcc6b6c6ed1d1f09e09be3afa5eaedf", + "0x817d43bd684a261fb30f709f7926cc4e1a31fd3a1a5e7e53ba4d664856827b340d7867e23d55617ab3514c8a26a7040d", + "0xa599e22d3286b32fafaaf79bd5b0c5b72f6bf266ec68948478f055391336d756b58f9afea0167b961fd94234989f0f02", + "0xb70db7d8e8356df2e2070f8d658e560081442f3f3b95e20f4bf30106835d76161101163659d5d12cc0f335fb042dc66e", + "0xb8f725b70c957aa3cd6b4bef0d9647393f7c9e0b7343e92439372f0e9aa3ceddd0cb9c30be331742b87c53f2eb030593", + "0xb2fb5e7762f26036e7e966f4454f886758804d1f4c2da17f3d13b0b67ca337f1fd89fd3cc798b07da6e05e8582c9537b", + "0xa377f944dccc300921e238ed67989872338137fe57f04cb5a913c787842e08b8a1adcfb4d2200abdc911fc1c766a7092", + "0xb82e98a606071c2a33f2ad44e7ace6d9471d5434500de8307b5d4e0083e3a5cbc67f0609ca8055f0ea0ee7501b9ed916", + "0x8e58f9a04d33a41ace4944615041662dc35057e645f63e127cf0d70f96ac307d33a62ce98f164d6eed8536c1a747dcbe", + "0xb5b11388071ffbf57ac47fc195736613b964ebb91cc8e2c17b32646f91d64ea506282b881897fca96c317364d3290de2", + "0xa40ee9b7551133856cfb3904837f9949a9558e59a418898affb78adf1500fd6ef6328fc4422161909aea2c79ad08c14b", + "0x81f9eb4ef28aacdb43e11dfc9aa92ba990be4d3c14b484fa677edad3a3fbfeaa859a7f9322b5e95818240d7326215abf", + "0x84939b2b6bc859437d1a7a8d6ec9a357c6b716c4b4cc22abc274af872655940cfc72c99f5d0283d90e05191fcdb1c232", + "0xb78a5b74a90a805410b6225fb9576d6d73752520f25cc3fd1edf8ea9f6559d3080f9acaa2246809b6a66879cd2ae446b", + "0x8d0a92baa88bf38dce5385ccf15d345b28e2e5d0a2d469e689353d80eaed8e8408933816d70ad752f226c59a0d5b5f0c", + "0xa7e15f8a8c1655b7b346c9488cff278c793505379b781b31b273b4bf09b3bdfca1c8ab2334746075d636b2e05859f215", + "0xb70daf14f2adce03c7b92d6aa181f0c507a80a37493d8dd12419d5ed5f943a98099fefb46ac827d6e4efb9b8233c99d6", + "0x8c2480814661744d116fba7355bc6b1914975e44cf0e976d50b6a20092bb1c636b7b44ed3fe8d63b5555ffc89fa759d6", + "0xa6059528a4fed36abb74ab992b22a4f9bf1d05c5de2bfe6837b9af1adfed98bc37ed7481b5a99675d432743021fcfdb3", + "0xb7e19f1b25bc159e5a769811e773c3a8ffe8be8ac77ed0b711540915e5c6e7bafdb407cf9b85c551f67fd621ce8142a5", + "0xa2f66d4f7d16ed3e7ef5fc90b42676c61a98ff18bd26ccce91de03b6a0130c1db17a6bc57be135e410a76d2255b15813", + "0xa139c916927dc3d3fb83598da9217ca64f0ae127215332e9a7ed82be923b89a801c44580d5617297175f9dafb1c4eaf3", + "0xaf08e1e1b04ec95366a12d99c80a9a9ac40ac984a575dd0230cdf4eb346a7686da55ef0a276f3356f814af31f9cbf1aa", + "0x98840aefe287369221c0721cd7c1b15b1d670c3cbbfda191cdb5434bcad757e59c30ec82b2d8c75947405888d44da435", + "0xb7c61c8d42daf2e278a12d8f6eed76090b71c82275f8b33504aba75d95103840e8acd083e97a5a5aa79897876a68940d", + "0xa0264048d2a2061d32eee4f661957ff351e78436bf49ef973c059612874ce9c91970869d011dc13a5b7c754476880a68", + "0x897199a4d8db8aa2db5d9be3d4f4312e41fa0739eb06c62e2e046c4b9be829a447e5d47227e2d96195d3b7b66eb59da6", + "0xb512a9082881f5dc90b02f8bc4f38b133348c2e933813852f6a8e7d8c270c9ce68a5524af7d1d3123e53b2d02a53d465", + "0x80b332469254a96f53c95ec79bb5a8bb1c387d40e58b73d72f84384c696ba0d3c81d6ac90be2979c364c44294e90432e", + "0xab680c2e547ea5cbf95bf813020beb461d50ee4341dea944eb48f6a8584d35682d20186e3b190b849a1ba25625a7f499", + "0x9070581993a0531d6be372d370c2e4ab2ee53f30e04a75ae61ea0fc2c320914506c4d2d4b4487c1f8fa88356fc45c895", + "0x8424303dad6b4051ab633ad27ee51783b2ead61c5a6dae1eb3ed72fc1f36e2a9b1f315504a4bd90f9664091f2f403d4c", + "0x82225611eee626556553b9316dab4043aff241a81826a33aebd9864a91e299b765ba1fb43eea2c2047e6b75b6d7fe3de", + "0x8a3fb221c616ad55c352dd5e0c09ee892022013d6965aef40d4f277a42e9fa01226fe973cb99aaf6ffe4f4f348fb54d1", + "0xb07c07679aa51713e8a7d7bc304dc15ed5664b66bd371877023f3b110b3927e09e259ef22895c4001421a69c6c013cc6", + "0x83556c76bdac0dd8db6da231b863c335be076e7299802eebc259e0818c369f933a4a4b18e2df8ca07e82f60767b462e0", + "0xa516f659b7915d2f7cd0f0f5ea2491b15f0c84dcb191e7671b28adf7cf14a56d42cfc0da94b3c269b45c535f6eeded49", + "0x80d7cc6f26066f753041b17ff1bd27f6d4b5603a43729d33d596e21a67356db84ca9710158089def425f6afaf3207f9e", + "0xb802a47f9009dbd48851209ea1e2739020e717f0ae80671d9f97a0e43de923273f66b7fcc136a064c8467372a5b02d28", + "0xac92fec1864a8a911633f377df87aab56713876316d48240fefeee49ab97f7406c22e70f4938b5912c5c4e766146b7a5", + "0x89224225b9835d04428b0a74edbff53dee2be285ddd1e5a3a8c37307c0500578155f0c4052e4bc8be04c56862fac099d", + "0xb1d3c8492fbf22ea60732745edd3b0163ba5a20d1a3315e3773f2540ee38cf308d42ec72cbb3e3dcea457d1d132c3904", + "0x8bd00e38ec30ee6c44a0e5b222f1f737c9ed2a4bb9225f1741d6334df966318c8a0fd2fbb109557fe8c9479694b8d8dc", + "0xa930ce5454efc0b247dc148aff869963fc5c240241d5590415cbd36634801a04d3873d93635911bb9c0c42ecb005cc63", + "0xb83d4f80e9e0fa47b42175df74935ba8aad2e559b80e84478ab1685bc3eb65d51b93e5738d5ca968cc055ca0c552a03c", + "0xb3ae21258f98051f13af3878b8103bc541fe6f20b1c3f8fb4689ddb8800b3c25cca9b55f0a4104bdf15dc4d5844abb8c", + "0x831ef8684c1cd446c58c59d0152aeade5cc305bca6aa296b92162615f052ba280fe289edd62fda6d9f0667c186445f52", + "0x97bf9659b14f133885916733b7d4ac7e215495953caba970fa259f7bf6b79e661090ec8d79e1c9ce8dfb17e8552f93af", + "0x84d5a89cc2332baaaf3d19627a65f4b107f8dd9228a1434b327732f59883bb54fb8ce60d6acd026ed4b0e94e545d1c33", + "0x8e66cb743f95ca5486400b0d89d02e20b98044be1e3a12983ff9fe086179e5a0ebf4dcd5098703191552e9aa660a6de5", + "0x87b4cfb35bacec805f8148786788db84eb8f4bcecdd0570ecb592c705450ce1a90b6d183d37ef58780ede3995be67497", + "0xa72a4fece5478011973afa543f6d8a8ea06a64b241cf7d8bd81fa3740ac2a4cf10e5120abcc1c1101f94da89507a40ca", + "0x89dc6001a96adcd2679916f43dd19ea00508c8d5dd6b0090eab7982fd2f3571b62f3029588a0649e73f49124525407ea", + "0x8ca75edf1259599e873530eff6151c822a4018e71a340534219ef8641cb6683215891df41d4e3c0ca2560e57a7aa913e", + "0x9282d32f868e5ee6f7fc229dda5b94b603476de30cec0a44a30edf396b52dc0ebd472b8f726d4b67d76179fecc1666a1", + "0xafa24704223707db89690bcf9761f07a093f6009ca9fc945e0a8801fc29f9f51292bf95243e466fe736088af36c55ca6", + "0xb51332508ddd9a2610edd2b0ad120272ca342e96c28baae37a2c4f07e689303a46c237712d07e446b1d67c75aa8ce32f", + "0x9219249f3799dfa4eb4770ee323f821e559e7406bb11b1f1889286221b22c8b40ccacbd9ac50ea3fa9ed754860bc24f0", + "0x993515270c128ede64fe6f06755259105d0ec74947b7eb05924a375fa5c6d14822f3d7d41dd04fa5df8aa2aa205a1dec", + "0xa83be4c2511bae430034ab15b194ac719d7b7041f9c0e321317f513a97db39e97b9ee1df92a1962f265b7a3e98cdd753", + "0x8ac7feaecd26f7b99fda3ed0b8a08bd6dd33ed5ba687c913ec0ffc64bbbefcda6f265072add4d944f2005634601ce68b", + "0xb4e3ac6b09299db9e1a469f3a0b2d8d724ee47a417a517bebc4c2ac3efc5cde086b57b9aa4efccdef2bcf8f456d973f6", + "0x9262a24a84fb7b2a84d700f98dcf3fefab8b47293778c20bfc356860cb84e0bf102bae9facd9986d92d1762e0a955836", + "0x97be2041c42bd25e5eb519279163b0857f8bef627492c27b1182f8bf0033769246be5886422cbd2409c08a2615352465", + "0xb0b87d059a00e3effa2e5e4925da913b245785f2932ac3ed364ad19a064d3561b8aa6afea22c951316074f0df179af36", + "0x891644b7b3321b06a2a40cd96c2b8b29d81cde5b48546483fdda439000982a9cbf1f6333fb6c089d39da6492cdfaefe9", + "0x8da9149b7f4783a24240b7b9c7e6df4abf8d699d3834e31ee591489bf4744141ab199c173db64397c1f9bd5f9c862ca1", + "0x8ad7f9fb2742654aa2964fd468e7645436cefd1308b064fd63fdf0d3adb4caf6cfe5426354f6cc284f208b03d6b2d918", + "0x8435e4668f7aeb027100d21e4e0b6ee22b401d21966a3736b95610de86c7e2f2c9ee5d0f901353675eee5ff458dad69e", + "0x9010895f045538bd11b47bb8996f27198c8d6cffd3220569e6b7407f68f35c47d1efdbcecbf9b5e241c3c2879a4f6936", + "0x92a9aa443b5ee7bf13b6f43f2d8d8db7f6f33fd4073a606ec5772421a55f464831419726130dd97829a7d4bfeb1ab078", + "0x843f3266560be6dcbe0258c3c7d7e332330e10630c069892954290288eda301e247f479505a8a1bf7e59c99ccafd104f", + "0x915bd1dad808f8a568725bd243f80b5476a2999d0ef60ea3ef6e754155bc4121b2b879d01570725b510c5a3f09cd83ef", + "0x97250d781815b1825be192714884630e9f564b9bd737d55b8ac79ab48d0fb3ca53bd21ead7b2fa82a05f24083f25645d", + "0x81e2d52333391ff2faab39611689a62d6ead77039e8703f4e012d53eea17a4d46f2e3342e44b6edbe73a542b461bda45", + "0x89c9f9fd5f638156b018831c1bb70c91215f4a2f5a73c84b1208bdf6ad652a55df7213336ce12bd910a0e1a726474f95", + "0x92bd02984d090ea7e2f3eb7d36d1e7b9d731b6b047e3cdd4af7cc4ee177415fea7a145205e484b366d84191f06af85c9", + "0x85a86fc61d5d916ccbb219db52953e1495230aaaca63237e9165276405f07ad9644e253ae394f1ccdd231944e7143313", + "0xa2ca5b3fbc9f3530f88c0ed7071ec3d89b272174c366eedb5d15d2b648c65d23c0faa4e92c776357e7c6883a0084d03c", + "0xad171f5badcc99c8ffc9d8b707d792046f86cd0aa478e0e2fbb32fe095f96cd134ca548d1f7713057694dc6b26465315", + "0x96bd15d57da9980870fbadc98c68db76824407dff2700c45b859bb70d98374d4a4ba99e3ed0b0c17f480fe08f16c6b8a", + "0x8300bac69ca088c3ff35749b437215e9e35a16393e9dc094f520516ba57a485def7029d30adfc72bca36eeb285c19301", + "0x8a09e20be64f346668fcc7b07fee9c0ea8094c935cbf4f3a4cdbb613d4b936c1edb9256b7c884efb72393d97c0da00e1", + "0xb1f85827ee6f041f93ab174d847a55710824fa131c9ade9561168c3962a25c617475ebc4105eba6e738961a754442bc8", + "0xa131558f92e215969f41b6a57d1e2f424149eea531723821dd4cf8c54325cbe66b002de2c8287de6b41ab4b5c35f060a", + "0x81ba492b8956f73557f361a856c6c884ebb300d828287d5699e22e0cfa75c8e77a61616551d0be5178263898c461d6f7", + "0xb2608f44d3c22fac8e13cb59e4ade8b9a98c4eb1ec0959ea400c97eb937ae3f66837e91917057148befade8389af2f6a", + "0xa6ff0323b5a18a4becb2cc6b376086b47cb2baffbfd1b0f2229ef2286fb4a34c5cd83a5faed5def7bbad519fcab8a856", + "0x857d879cb9eff22501d883071382832730704bfcc5cd5b07cdce7ab8dc41c565a1eb0e7e4befce8e0e03a4975d3f11ef", + "0xa2879a20c0360c516811c490289be7dfbf7dbd41d2f172c9239f99e3d091957e0446854f9d0f753d90384a80feb6fa56", + "0x83518624f33f19f87096a47d7b8e5f2d019b927e935a9021823fac6564c4f2328dcb172e25bb052748191e75ac682bd0", + "0x817ec79132faa4e2950665712b2c503d7fb542aa57b7b36e324f77cda79f8b77bde12314e2df65c5b5296a6bca9bb0b4", + "0xb2abf8fb7c3690816fa133d5b4aa509cd5a6e3257cfeb7513d1408b12371c4d58c44d123ac07360be0d0dd378e5bcf99", + "0xa9fe1e4fb1574c1affac5560939face1af6657f5d6abce08d32fc9d98ef03186dbb2dbb9fd1decd6d8f4e4687afecce9", + "0x89b2f41e51f33c3ca3e44b692e8a6681eb42a7f90b81c9e0a0bc538341df9e2039ee61f26d2ebe9e68df5ed1bccf8cdf", + "0x8b35aa7b1d9e2135b35a1d801f6c9f47c08a80e48603f3850b425f64e7fb9860d1adda04f92a1ba22d00dd0a26e781ca", + "0x960574978cadedbd4cd9f764bee92f94e08b7af65403de36b21bffc9424bcee845b3b028af2e9e545dd77cf1e69a6a7d", + "0x840aa0f34b5b6c39471f54d9e85f1eb946468c4fc01963a9027cd7864df01f73c2e864f1f07aeed4b1b1af72808dfa07", + "0x834464a84a11200e3c60f816044c254a7d9baed64aed45a17325cef7fd62338e0a26da78d199d30ac3411714dc813223", + "0xb4ac6fe2f5059546f4ad9a361426ead33237b6b9030b129bf0122085c85fe4ccb33cf90f5a7f23c5b708a5ac64b487f6", + "0xa12aa9035464795f2a67f3eaba478d5ebc838ed9e997c7dfa241e1ed60a94b367d3f969ccf0ef02028c35215698b309f", + "0xac8d926492ec2bb68c6d8aa9bce49085d3d266f3d5f1f924032b87c42b44e41da7c047eeb01e4618f9d0f123dcaa537d", + "0xa5142425825d813ed8ce1849d81aa40b11f1cc3daa89a9f798dd83065c74820b4da6122b3308f528b074531df66e1a5e", + "0x87ff55c9f5aae079e7bf24084dd9c6b3bc260727d942d79cbe8dc13341d98525b4ece3ed8169994b56a387642f09134a", + "0x88e680f148ef2ecdcfed33b61f9e0224790fddc9069bd6999e9bede1791e761637c0fd60b52990b6c93e6e5429e483ce", + "0x94bc20bf5aac6e9f1060d02eacd06c42aeac9a1c5635b15a83985dfb03938ddb4999a822e865635201489c7f75601b29", + "0x849221cab7599f25f0b114df092bd5e8c2430503ae959bef1543a101de0790a78245db6a145e26f40b5f9bcf533219a3", + "0x88b6f2c2e7a7954fad11009d839ce50780921f80292320868d481e38d26aecd80fa607e82219a99532d88cf33b39f562", + "0xb0d82947dc23c0b88b86c321b582c15decdb825ed909a731b42d46bc895009515a3dc646c98dbec7d71b0722df82392e", + "0xa2cfb9f7c1a76c8073363c1c3bebe5dc29fa76533caea41046c51ea9bbdc693a121b957cd96be5b6da18704d1865cff7", + "0x8f0ffab9a83355a22683a9d998d1c1089449eb308711eaad4265f05927ec6d0d1ca39217082a0b372e02234e78dbaaad", + "0xab024661e2b2937ad374c8cf2e3669f1dc55558a3a881e9ec4d461f27e0fa92e2bc88230f038bfb051cf2145ca747a07", + "0xb98d9b9ec9eefa56d38cca959ce1aee7b6d4b41a8dbbd34b3f50c0a5f97f84ed2502ded1ce8cdb5895872360d4ba6d61", + "0x851244158b3184a62d2c98d148e2b1102cf0d5500906bbc2deda95acc5e3bc4b4a3344febbb31ce05a56dfee86a74913", + "0x860d9e2cb886bd3620b5d7499d14b415532482569bd45fd76e3e8052d78a73ae4b2b41f139f9cfb136564108cd93c0f3", + "0x8305a052a0fb2bcd41f3aca075c5f7f233bd8f861451d03f3a6e6e31f7d08dd89fe1eb4dd7b238a78b12ddceaad9768c", + "0xadb703e4778c7e14fb83541ab00b5fc344108243ec6827c5d9b302ee68321aa569da1718424e6a57979ab7536d5eb43b", + "0xb1a754b87b9e21aeb86217ec5b4fadb7535344567f1bd15e88ec12a833fed68e26bfbe03b7709ce24ba6c925ea0a0e07", + "0x8c1e2f6bf820e1653f3b8213e9d959d8649196223c2aab57b7ebda094f4919f88d883bcc6a0cd0be335f26f5a2a9c962", + "0xa082deb9865fe8668e91db0e4fd7fb50fb3fdae3e7bf1217ce0aa6f286a624624cf936d762bb2b6c3fead6826694f846", + "0xa10540ca05fbcccdd0a2a66aabab3b36e9bb525794cbae68bc3dace6116f58942218e9d5e9af10d67b5f6fb6c774fdd4", + "0xb81d22c4ab0ccaf447cc5fc2ff3bd21746617e6773bf43257c0d80331be2e8437b88c9c45309ee46402b38d3d4911caf", + "0x84c7c6e924713cab3b149f641dabf63ad5abbc17c1d8ee7802a6630507aa1137f7e034ba1d12ec13f1e31efbab79bf13", + "0x8773b9d236e5fcfa8c32e471b555264692006bf9a869a3c327aed33da22dfbf5780ecea7158904d4d6ac4acfe9789388", + "0xa4c2c1bb7290eb7af2013f7dde78282148593f066b09faf42e61a3fcf81297caa5a00fdbf6b93609c8c5782a0f25341a", + "0xa7bfa6e3f273da3dcfac7cb9906bbe9fa4fc2872b184d79813ee273e6cc4d7f37f46164362707a1976f5b6a2c5d7ed1a", + "0x8b71502019e4263fcda354a0fd10aaa7da47f4abb7a0c715c7b017e9eea14f2b64009b29b467394668c7ca995adedf82", + "0xad7460fba7deccc3f9a7d204233de47ce30ffa55e1e164975cdf06480a6108720bc397b93ca8c959df77d44a1e1f05f4", + "0xa5b8df96ccb7b078a3918e74b1b10da21df982538d2c9313f5129b2797c8a6db9ff8707241ff72d3e9d5983397321736", + "0xaa6cfa6386660c01879656da6c4e72497690708bae6c5cd1d088f443cb5bbbe75561d6eec256a72b9728377eb83ef973", + "0xb9699ce7c5c878e44114ab7a598646c6c7616b8e08a9ef8ec291189ef9945c1a538d2abf1ce3b0da0f8eecb303b81b43", + "0xb8d0fd1d278f53c455de92ec4357885fc6648dc5f276930263da7dc885b4a9628a2113e28b66b1e64fd08189427c614f", + "0x84ad8d262f6ef5d93e82ff6f4af995148eedf6d8e079124daee9b99f506e2968922eac2c7d4aea741fceb7733f20b2d2", + "0xab5e30ab54641e3a44450118b8235554e0fcfffdfbe1430ceb3f7ef33325725741995fbbbb0c16f0875aef0f1e0c98ec", + "0x80e2cf8bf386ebda46045852751611f2af80eca2e910d9ec5f6e2c7376611534604ceafa639272b3d503b02bd66525a6", + "0xaaac69af8fbb87da1c1b7c1b9e59942887ae839a91f0c1d191c40fe8163d7f1dbe984e4fd33619c73e63abfa7058f1e3", + "0xa6194224ad838ab86e84dc80e9b8abb121ae6c3c7fddc476463d81f14168131e429a9757e18219b3896a667edda2c751", + "0xb68f36aa57aedc7d65752b74761e49127afa65466005a42556230dd608ecc8f5efdb2ce90bb445a8466e1fc780eea8c3", + "0x886c3fa235d6977822846b3d6eccb77f1e2cd8ba3dc04780666cf070cae208b7513dc4525d19a3fb6385cb55f5048e2a", + "0xa9801273ef850b99eb28f3dee84ba4c4017c95398730c447efe8c1146b0719f252709d3397ce60509e05da74ed0f373f", + "0xa58c2a5dd13e08ffa26a6c5e5eb18bd8f761ab64a711e928e6101512401ef2b1c41f67ba6d0823e16e89395d6b03ebb7", + "0x91318b564ec8b2d8c347ca827d4d3a060272aec585e1acd693b2bafa750565c72fec6a52c73bb3ae964fdaa479700532", + "0xa058db5d76f329c7e6873e80c7b6a088974522390ccaf171896066f0476742fd87a12fe9606c20d80920786a88d42cec", + "0x9838e07f9ed8b3fbca701be0ef32a3f90752bbe325aca4eaea5150d99eb2243332745c9e544fd1bb17e7e917202edab9", + "0x85a9ae7dd354f36e73baa5ecf8465d03f0c53b24caf510036b3e796e4764a2bc17f0373013af5b9f1b8973226eb58cd1", + "0x896a4ff4508d069a7da6ef7bed66e1080991daee8b227f3c959b4f47feaf75fd1b9e03d0917b247c2db11e105395d685", + "0xa36d9a6a037bf498dfc0e535f2034e6cd433c7b52e520469811eb2e9f04499a6ce40257d2905300df7d81f38d1bba075", + "0x97aac3c5492aca879b4c06db1834b30b8850a244d29296046a84c637d9580c8521ab4752ef814c96f255a139660d7639", + "0x8552bf592a84ab4b356d01643c90347377ebf1f2b38a8c2e55a3f34537b8c7dcbd62e6776d6c2114f2bc2d4344d1567c", + "0x84474ad163db8e590943ccd1dc50b4f444beb8275919b33f53d42cba89831e9d42ce2de52b26f4412e2a0676ce913277", + "0x900799dfaf5eafeb297c7b4f892438bf2a65ce04034d66f8e5cc3836e4eaffe782fba4f4455a0fcab49102a240d1780e", + "0x817176415e35ad4a204b9fd5771bae6cc270f6ff050996cec89efbe461b2940ae5dd3c6c7d7e31b1da5285b207efed27", + "0x965e5791c927d47569bc54ec9b4c5305788aecd87a26e402aabeaeccc03480df46f0586ca2e2a9918885cd03332af166", + "0xb96d9ada4b5a04a94807d71726bd557de94fbd44042d7dba40560eebe8658d1da49eba54499360619f3b2c38e8b5ed6a", + "0xa07b6d641a43e02e7868f30db4dd5069a2f221b4f122ce9b11eac04abadc4f25f3207f1d2d86c7935b1a3d9992ea9814", + "0x8250d4d8ccac846a4b1a9fa392d9279b5bf2283c8b95d8164c3c0d199fec8849eab85755f2a2a99d584a0407742e3200", + "0x8324cf49f56fc14162f9a9ebda1ebda0388d09d8688f1938aef7dbf9505fc119069efc552f68cc7cd9213f96fda2c6de", + "0xa98e6f1e85268dccbe3bf4e92c9f455c58dcb53de1dba3b78589adf2e50e79f8e245f956e0d098eb46f5d3746826c6dd", + "0xb103ec12f266b4153d67b54d8fc079357ee342cbe5008adc3e0689a7f788534c4601e60e939731f49e4a1e24fd589f82", + "0xb2d7681e866420413cc98eae67614d383943e3762d5742cb3c57e26157633c20880eea1209feaf68402d5d33dd699708", + "0x99fed0ae4112ec9ed74baac70d202a885aa51cb555a3886b49016744dd4017640dd5dd564998c4d842a9f38f3e004e68", + "0x95c35401314467219c8bfb1ccd1f1eae6ef4fa9e48fbea14f70d5315e67b16c46cd03554471840e4a5030b077d2a3856", + "0x8d029380e0c294400d6b8673a23aed43697cb6460fc1bcf217aca3b47cf240886644ed09521d6a05f6abf56f99722d84", + "0x8ef54d1dc0b84575d3a01ecba8a249739edfd25513714dd4d1941fbde99dbbc392f7eb9fb96690d7052609af23aa57f7", + "0xb8ad2b7af4812417aa8de8f33a26547f84bb84f39501d4b7c484cc8bb54c7e166c849b95240fbe459a4719a6e3bf1651", + "0x9858545de898721d19930d8b360cacc5ce262c8e004867a050f849f7a2f2aba968c28d51f24a9af56aaba23a9ded4349", + "0x94ea5043b70df1db63f9b66b4f9d8082776f721b559f27d37b45e0a84faf47f948d7c4532dfd854a4bac49fb2ec8e69e", + "0xa2fd88d7b15e3c2778f6c74470d0f9e1a1f979a4d58bd205361eacadab9973d585a6508e685e640b272d6f8a448eae05", + "0x88defd6bccd55db8ca84e3c8d0fc55a3456b41788f1e209d0aec19c9c70febebf3ae32cacaa1dbbf796d7ddea4b17995", + "0x88b8cde2449d5ee7de2ee2f32e845d27e171a51ef64f1d3d8a5fd7dbb9f898ea70eb7f6410cddfd7b7ae70ea8073cc2e", + "0x8e044fff6ec557824866ac76301b6d93ed19b7177aa6baa95046330f5d69b572b59200e3653cf2f2b559455e782e8960", + "0xb5446b4d6741c824885790d2d26258729dc0ba2f469c85a47d38886d933b785a4f38a951d37f3ef4bd5091c03fa3a071", + "0x956c8afa8056e9a71ab2e8be5241ddbb3a8b3cff2110cb0e7389493d9fa45e6c4b769ebef540a952db6dcd8bd55baf64", + "0x925950cae25615246e29d594ebf34fa7d52f78a9867338648158f2131e6eb4dc17e18f9db8a5fdd76d017b3a9798b3a7", + "0xa17ea4b43211ba990270c21562690b3ef154a46c3d669c4674c80bd424cdfa95d8850c8e882b8d06504f929cba3d93af", + "0xb315ec723973a138508afc387ef651fd8a8804f93975fc36c2eeb796a304eeb1508518d8703e666a74d14318253f526f", + "0xa995742d7433b3f230e622de23cb2d81cac76de54831491cc29768eb4a56da60a5cbd573e1da81fddc359b489a98f85c", + "0xadb2e89f0d15294d7118fc06d4fdbd9c51d3ecbcc23c69797e5b8197eea0d6cd1240910cf22fcab4ef1e2dc2dd99da91", + "0xb5ec9f9fcd0b5d176b643df989bb4c4c1c167112373d662fb414875662d1a93160dc0b5cdf540e8a30e5fcbe6cfbbd49", + "0xb1291b53f90aed275df8b540c74a1f9c6f582e16c5df9f5393a453a3e95624ab7552e93d6e2999784e164046e92ef219", + "0x8bc7b7b1a584a12d5ae63d0bbe4dc1b63c9df9c89bdd1095ff4b8e7c822bf8c1994c92310a3644033c7c9689f4b7d2b0", + "0xad7fc45506a10ca48f991714ecc055cea376c0cbe667f3b40ee8dad8446218835439ae59bccc474cf47b053748ceba6d", + "0xb134756828a5f5725c0b95109e09ca450e3834b127163a0aeeb544e63cc0cdcdf66f8ed98c331c7c98758f46af369a84", + "0x94535bf1636be0974b112fcec480ed8eafc529933f3065c40e417e608e43a392206cfde8bb5a87b720263446c90de663", + "0xa4df4f6efbc3701000fb072e5cbed2754b9ef5618386c51ff12f95d281d1b700fea81fc1365f4afc66a7c83bd0228fbf", + "0xb0336b3552b721087c7e2194976a9119aee13ebed9f1c3c494353707fffde52d004a712965f460062ec9443620716302", + "0x99a39d1d1ee4283b75fa8c1fa42b6a3836b734be48bdd48050f9b05e48db6354fef509623c6ec8d447d630a9b3352b77", + "0x8e3dc3583d40956f9e784e8bbd0b5e65671d2ff2a7c387b20fcb7da9b969f2d122aaf7f054d450dc611737604548c03a", + "0xb5068ec5b7bcb5d8583d51cb25345990f50d1f7b82fe535a6a6b17756355885047916f466ea3ab09eef5516bbf2dda90", + "0xa8284ec1eb1d21e693f31a6c074199ee85d8a8da2167bffab5fe240defa2773971c8437e358a18f7e58d1e2954f57f6f", + "0xaa7415639d29081acbaac3e9c6b059d68e8702db3f430b86bb6e220d476fa74841c875e9d471c8a5423c58b6fee3cb54", + "0x8afcfe6f65fa6e07c2cb3e1756c0ef2c589830be96edd50c3c248e3b17f51a4b08ba92ef7eed7991d81667ddfbf2bf7f", + "0x83b9c8dec8ca8f9b85f0e36c08c5523cfeafb15a544398e6f93b48b5fc4b15a0bd05c0f176a9c2469664acab8dffb0a8", + "0x82a128a89ea46b9debe5c903b950c0ab30cd7570b979ca911500b5c2cca5c4ee6b2c2fa414b5f28e367f4671ffce60f4", + "0xb79fd0ccd2629a361cd6f9307c02ecd4d1f07e4ee03ce4b542997e055b07a026cbc0ba05fe3da309efc58db2e401a8fe", + "0xb190751141093823b4b5324cc26c4f3258552f7893241201f2fca1ae9b1a1d4d4964a9abdde8642cf308ded61ce5ef09", + "0x935fd48b95aa6f9eada0cf9a25a573f0ffe039888b3410788c41d173747bf384c0ec40371bb4383ddcc7d9f2db3d386b", + "0xb9affe100d878491ff345636ffd874ce1f27852a92417694afce4163e6a80c78b2f28d78102fd06c3283ef273ad37642", + "0xa877670276d49ec1d16c9f1671e43ade11c0c1a1413755f6b92be9ad56bc283e4bd2ad860367c675d5b32ff567301fc4", + "0x8c660d16464878590761bd1990fd0fc30766e7e49e97b82ec24346937856f43990e45aa8ad37283cb83fa16080d4a818", + "0xae1412087da5a88f3ccc45b1483096aeb4dcf4f519ff3dbe613f63712f484bdd8b2c98a152a9db54cf1a239ae808f075", + "0xad83cead97a9c3d26a141604268f8a627a100c3db7e5eefaf55a1787ddc1dd5ffc7544e4947784cb73b90d1729003c8f", + "0x97c3140ce435512a509e6ff3150da385fdf9e0883a5dc7cb83d616ec8d0a0014e4e0fa57a4d12c7997cd84e07d49a303", + "0xa353773ff68f1615454555bf658eabdcca40a9c7bced8537ea6fa8d54764fd1f032889e910d2a2a342835513352e2d2e", + "0x89e8df0c17a36ffe08149c2ef8b27306d04cdf437135aaeba697abc65e3c8e91bcf1817919a8a826acdbbe7dce79a18a", + "0x9928c2da15ac6cb20b15859c22508cfcd452c5643cd22eb84abf5f0a1a694fdefcd8fc329c9b40babc52630743d6b65a", + "0x99d837b556f8d13108eef6c26333a183f59383b39958dd807b10590c3d37f62ade6c4a320ca2e70567e0218b0ad5807d", + "0x9272da080e4aa18720b634640b01bf1fe506c7c8a89dee8759a53e2ca5cdbbd4a4f3aca54924c46b935362cf1eca066e", + "0xb4d39752c882de1c1daf3854202c1d58c2bcf35c882006eb640fe54a97be2655281cdb91c30d1a41c698617c2cf64b01", + "0x8bf827f4a7d47e07374d338a3d8b5c2cc3183015b5a474b64b6086fcf0cdcf4852046c9e34d7917d69caa65a9f80346c", + "0x901bffc7db9c9416e06f593a76d14f6d9e5dea1c5f9557bd8c93b9e70aa4782bab3518775c2a5b285739323579f7cf0a", + "0xaf7e204388568627ca23e517bcf95112ca8afd4c6056b7f2c77c4da4b838c48791191565fd38398587761c8047d11c47", + "0xab2576b5366e6bd88b347703f9549da7947520d4e9de95d7e49966d98249406ed9270fe69347c7752dad47e42c4ea2f4", + "0xb12e3b228b761dedd99d02928105494ded6d4fea3026d73d65ebffa2e85e2cd75b6d091135d418dd95ac102c22b5ee31", + "0xa20b4a752685d5e31ee7e2353c8a1b9a5265f12bb775004d282a3ecd9deda44831bac1ac5151646428b66909b2a423f5", + "0x91a1d4bc0062a86cc6786a96fd3eb4436d8a4a187b7cbba02190d1cd6ed3c3797d9ae7d6ddc413f1c94a21f62bd04ef5", + "0x977f18da1a5df5cfdd0276f583cfba2b2a0fc6139520664e20068f8dfdde33e29d179abfd722f142448f4677aa47be6c", + "0xabc3ece90f0f7b1d80fd917de27ab0d88cca584ef959da520825e54cb5a71336b15f8b348532d08d47a6fa600527ef25", + "0x888d36a2c7cc13a1c1aa338a183a74a1f57713e76cb825f9837f43279ce4741999b76a16928147537bcc20f2e0195b0f", + "0xaf3f5dfdc2dcfe19de893f385f39f550cb1dab67c2e97f1d5fa735e5ec96d6680066803e8a0eb010dd4399f654195513", + "0xa0fb4e08ff56530a940a86c28830956eb6dec2f020f7faaea7566faf0a4fafe0cffe01480e87763ec22f201be51a6451", + "0x92343c5b107910b203c64a79c93d354f7ee5b7d1e62e56732386776e275285561cb887019cc00d3fdbe3b5d54460bec1", + "0xacfe7df83c4624188a1011ad88c1e1490d31a8a8c8016b40aebcdd7590d9c0793e80d2d7ce6a7048876621c252a06a5e", + "0xa7da001dc1e33e0e129c192d469d2bd6e5d2982eb38f3ba78bae0670690c8e70f40e8114a57bd0718c870ca5dd25b648", + "0xa903de5ff97dc83628290d781e206ef9d7c6b6d00cadc5bacffb31dc8935623ab96ade616413cb196a50f533e63641d6", + "0x8f9658d42ad14a60bbf7263f6bd516cfee6b37b91a8f53715d69f718a090ad92484061c2cef999816760a78552fae45b", + "0x8c15b72b3d5fcb9ffd377fd67d9dfbdd706593fba9629002639973db12aac987bd1db70250ded31c88e19efff612cdb8", + "0x88a2a4034decd854fb557960194ff3404e239953818a8a891bf72a0b26a8e570a65c4a630884de991ae7452b3234f31a", + "0xa09cae5c4c190537bf1dd75bd7bce56f7b799762af865bb9d1ee970f6a133c27cce0dd0f14a0e0516ceac41054e6998f", + "0x9760ebb1b40f9a97530c3b940d4ef772a225e5b63bf18283f8e302b9436c5209f6294980fd37058060e429fb7fdc3a56", + "0xadaa9400eb86d857dc591b25dbe3bc8f207b69e77b03cb5ee01f7e4b006b5c8f6ba2b51b5a45687479885708509363de", + "0x949efe6b00b3248846747a9ad4a934d6e4255994c2b540a59fbbde395fe96d69bb67908441cfadd8c8bbb561fe52da03", + "0xa19a45504b6b1dc3a0fe0e6a1384734a3dcd5a7cb8fb59eb70e49426c4fc44946547443d558e5719a04884ab3a2811ca", + "0x8934c9ee21e8d1435426fd0f64232a0670a7946ec524c054cd4f2cc8b1be9f89cc11002ca8aebae646a2050d91716b10", + "0xb1150ff8ffb34ffdcf7d603348c0aed61e5f90ee0a1b814079fc2a41325c75f2f9ee81542797ede3f947884266a772e0", + "0x86ce8cc7c1f92af68de2bca96ccb732f9b3374dad6657dfd523a95e8a931a0af2a80df74098514a06174406a40c16ba5", + "0x90faabb9ace9e13fd9584932846ab28a618f50958d2ce0d50310a50c3bc6b0da4338288e06e5fcbaa499f24a42c000d5", + "0xaf4a935c2d8df73332a16dc6da490075cf93365bd0e53e2374ef397514c30c250bcac569b6df443985cf3720a4534889", + "0xb7f948ee90f394789eb0644d9f5ad0b700c8e44e5e9ed0e49da4cc18483676d25740710b1c15a557965da635f425b62e", + "0xa917913091245beed6a997ff7043ecf60c4d655c4db0b1ef1c704fd9b0e1ea1335ce8b9f45d6e120f81805ce31555e30", + "0xa48099da8406399bfb1ba834f6f7d864111d0036969a5cb64089947a63dd9467d3857b605e9f57f5ad5f4ec915088d9b", + "0x9784c3f9be42eed354542b1446d734521f8e3f01cd9d495ae98f2e4a3a16767fe2ad909e0def5d9a6267f3fc6a172cd2", + "0x8d9afaa323847a3226ad7d7b60d87322ffcda2e4a8df89f58a076f7972d896588de685a2e155e243bcf9456b0a0d6d1f", + "0x994413faf0b843f4ec1842c706c45ea5f24351c68674a27887bc8b182eda756856e507a4e8bbfd937e2c4c581b629ee6", + "0xb3e72d9d1ddaa00c7d22f25462d6e9f2faf55e30d138dce8bb1517eb0b67132db758668aac26164fd934d732633bdea5", + "0x8e95875e338f714e9e293df104f0ad66833bbd7a49d53a4f7f5fd5b18a66a61aa0a0f65cc31d55e0c075e0d3e412cb90", + "0xb980091862b1a9f9334b428eae14bbf1cecb4849e3a5809773b0d071d609727270f6ad97f329eca896c178ce65883db9", + "0x915d7ae5ae780bdba27ba51a9788a8852a15355b569581d1f18f0d94bcdfed2c1ed5a4f58e049e9825cda11f92b2c2d4", + "0x83e581058edf9259d0b06128282327cacbb6afc939578223cbf93544599f799a8dce1fb21d52464f990a877086f42506", + "0x803612a38b6f6efb97941997e101ac1878e192456f8fbddb3359aa7f3023434ed8fa92e60ec8e7b4473b1948850e4311", + "0x864a1bf4ac046161617dde282e44ab3cc1843da01a09ca58aa00ed00eaea9351a07a9ec16d910819e7dcc28b8d2c8ada", + "0x922eb142845975d5f6f7dcfee6cac8c299b3730400e6bf82cc0bdd9888de21de9d9f1530640f702c003e1ed63b140cc7", + "0xa7db03c5be647dce1385ebc02f4825a654447fa8c4c8d4b22e635dbdd2b3ccdf219384e49a80cfb1e9e6182b6e4227ed", + "0xa167289ff0f0967bbab6479e4a8a6f508b001bbe0d16cad36ab4c105ad44f3f180e39a6694e6cd53bc300fe64dac1e8c", + "0xb7766431f6379ce62cba22ab938cdbb1b0c7903dfb43980a417e0ee96c10b86b447241e9dd4722fa716283061b847fb3", + "0x90cda18c5d66f5945c07c8c7dc453dee1370217ccb851bbea32578599aa669b4dd245dd8a9711b27c5df918eadf9746c", + "0xac690cd2af39932874385fbf73c22b5d0162f371c2d818ec8a83761e0a57d2db2fca1d757343e141e1a0348016d5fc44", + "0xabac820f170ae9daa820661f32a603ed81013c6130d1ca1659137d94835e1546c39a2be898b187108662cdcbb99d24fe", + "0xb2ea5a5950096772f2b210d9f562f1a4cfacc021c2e3801ac3a935f2120d537471307d27b13d538dcbf877a35ff79a2e", + "0xad94af4d0699cd49ba8ca3f15945bd09f3f7d20c3aa282a3113cdf89f943d7793e59468386b067e3c1d53425dfe84db4", + "0x83788367ec97cc4bbc18241cbed465b19baa76fab51759355d5618067009298c79d0a62a22e2a1e6dc63c7b90f21a4a5", + "0xa3e142d879096d90b1e0a778e726351fa71996466c39ee58a964e6b5a29855123d4a8af47e159027e8e6be0ca93d9955", + "0x860831f8d3edaabd41be5d4d79c94921625252aaec806251fb508e364e39fde8808d38b10d557e487603a1b274c9bc3a", + "0x88da39f334bd656a73c414ec17dda532059183664bbbac44eb4686c2601629ef8ff9da992c337a842e3885b684dd0032", + "0xb50addbdf7164e8303f33de5ce854d6f023d39c1c1984b214d9e5fb6f6001cd5bdda816f048a438ff3d696872672f805", + "0x999e58c4c69a912b84561cb09610e415b43832beeb95897eca8c403ef4754f4277754d492eef3673afd4362f50060fc9", + "0xb88ea0f60f8119c5a1fd9294796d387472dfad22442b29659713d1d88e7d854cb7cf5c9ef773627781188626bb2fb573", + "0xa068b3844e9dbcf74b54fd55904d56af754d8ce4c619fead7a07f9bfb9d02118db7c512ccec2489d2a84374ec1d1fb6d", + "0x871dee023768636003c799e6f6fd8d31315a4c0da7286345cd64264a016693b3485e0732be1bbd34dd5fa04dfa58a983", + "0x8021e8f508680df12e4a5a1bd49f2d7142df65158b0a7198ffa83abd16053a542fb93ffc33e5279020ba8c6a26feacf2", + "0xb5d3cd64df5bc965228b0bd4ce9e5797c409f7b64a172ba165e44a8e4b38e3d5fabc3e0b9a19afbfe427f887c40a315d", + "0xa54fdebbb594bafcefb1a03697711e0091c072e1cc24fb441fefd4e0a0518675a1d7b0966cb8294051d7ec0ac175d0cd", + "0x93922202337f72969d6d6e14a29c9c75e0420dfba712029941d1504b9f6f9761d706cbc0652cd09a1aa5d22aec766af1", + "0x9711ebf1c7c7426190d4afd5dd03b014a456bbd9d90ed101623866a280550df26a629dde400c03ee3699f7d827dc0bb9", + "0xb4d686d8bc5c1e822a50124c1cc23c6bc3a1577a3d0b8d4b70d1797418aaa763283c09e8a0d31ae6d4e6115f39e713c4", + "0xa533ea2ac683e4ba07e320501a5d82a1cfc4fa1d65451000c3043f0fdac0a765cc1125d6cc14fe69975f3b346be0fdde", + "0x94ee563134fe233a4a48cf1380df55ead2a8ec3bf58313c208659003fb615a71477e5c994dc4dcfb2a8c6f2d0cb27594", + "0x93e97d3f3f70664d0925be7aee3a358e95ae7da394220928ae48da7251e287a6dfbd3e04003a31fab771c874328ae005", + "0xb57440d34615e2e7b1f676f2a8e379e1d961209fe00a0cf6798f42b7c28dbd03172fce689305e5b83e54424bc3f4a47c", + "0x97644084c6f7b4162bc098bed781dd3af6e49e7661db510975528f1dea8154f3d87e979bcae90c3df3a7752eb0752889", + "0xa923b27b225b2a6dd5bdc2e3d295b101cac5b629a86c483577e073cea1c7d942c457d7ff66b42fcf33e26c510b180bc2", + "0x86698d3b3873ed3f8ab3269556f03ac8d53c6e2c47e5174ec5d14b3ed5c939750245441c00e2e9bb4d6f604179f255ef", + "0x87946826d3aa6c7d53435c78005509b178fdb9befc191c107aee0b48fbe4c88a54cebf1aae08c32c3df103c678bad0ca", + "0x860864896c32b5d4cb075176f4755ea87fea6b9cb541c255a83d56c0a4092f92396a3e2b357c71833979b23508865457", + "0xb78fa75d687349e28b4ddfe9e2d32bb6a3be13220b8f3ff1ded712088bd0643da9b72778bcca9e3b103b80097f48bdd0", + "0x8a188b940446598d1f0e8c6d81d3cada34c4c1ae0118ec7e0eacc70d1bced28ae34b99667d5793d9d315a414601c3b22", + "0x842ac6f7dc14191ab6dddffcbc7cb9effba42700a77584aa6a8e17a855cd444c5d138f9d61bf55f43c6ffbcc83f92bc9", + "0xb6742902c3d145a6af9738c01cf9880dd05c85f0d0ef7dbe93c06fdd6493333d218339ebc2a02be1895436a2f734a866", + "0x98bf18488483c627b7181b049d3e6f849fce1f15794de59dcde6e5a9b0d76fd484a46e48822a6a93001d3aa12f48bc6d", + "0x8769cac10bda8c53a1c19419ef073a5998f73dcf2ba1b849561615a17cbc0a49bfe3eb4ff8801dd36a22fa34b9a3a7e2", + "0xb45c084d58028fdfae792210fcd183abc4ffddeb4cf52ebf3f8a50e4c4eec2a2758f1241b0920bebcb24b757c778577c", + "0x85c1216eec8e1fbc1af9b36b93c5d073a81d5fba86a6daae38748ec1573eacc6bef209e76c87a6efbd7a3f80e11d4c3c", + "0xb8007e34bb3f927ec06a050b51e633d7eb9e9a44715d5b39712e69c36177a03cd68391090cc3293098e54f6cf65f6caf", + "0x8e85527b27c9152b1ba3fdd532a76a79064ab097570508f233e09978761dfe3012d537411b47d0e4b65265eb32cea2ae", + "0x899779f3c31a20b76068ec8d59d97a64d2249588ddfd69dcbaac6bfaee8ce0ff3c5afc4e17c934ae7cd041b760eb555d", + "0xa5dac3d8f5fbef018509612e25d179f60d2a62451c76426bf546e9666fcdc73263d34aa6fa7e2bfd4c9947bbf5095eff", + "0x896900eeef9be2b2e755128e7b1c436af6fb3984f1e66c444bc15fcf3959013b4902c381f0eab1247f878a6ebd1f4ee0", + "0x8cb17f4b0af2e9b2cbb56f46e6a5d6874ea0daf147aae77303020b4e592ddc92e0dd058def7da96258b3a68b223bf22d", + "0xa1b6d3f09a9fa7ecc021ab7c5396541895da6e9bf1f9a156c08fc6f2b815a57f18c337ccfe540b62d79e0d261facb2be", + "0xae70888811434ef93da60aeee44f113510069fd21161e5bb787295492eb8df85103794663fc9305f04adcbcf11ff0c5e", + "0xa84bbc8624100acfae080ba8cfb48fd4d0229a60b62d070bd08fade709efc6914dc232d3f7bed76a59204f9252321aad", + "0xaea47d54652abd8ca213cfc623c8e30780f37b095b59ac4795252a29c2b6bc703a5203acff8831314478b8ee8771d4d7", + "0x8dd438eb8be14935f759aa93021c2b24e1d588f7a162c42c90ec3a647b0ff857f60e24c0a8953eb7bb04e04be70f11ce", + "0x922b07b5469680a10e7532766e099896f4dc3d70c522d8add18f5f7765d4ddb840df109146607b51ceddd2189fa7b9c0", + "0x83ef6ebd0ae6c569d580093e8b0b78daa964760556272d202d343e824c38eccb424262e5b7809d3c586f9e2e9c5c5f22", + "0x97f98bd357db6e093e967fe180cf67ed09fa711580a5ad48f07cf095b2e8fabbe6319f97d1f15d62c0ec2227569d8dbf", + "0xa1953a4a22fe6c2beaf2a5e39666b0eb53018af6976e3a7aab5515550ff2efa89400605a43fb2c4ac1e51961dbd271d8", + "0xa5cbd67f4c0bc98e20aa74c09e6f5fb6f42c08e59aaa477b4b4e61434c8884bc14f17cf11faecf46dc4b6c055affbad2", + "0x87d96818f2c4f12fd7705cf4060a97bd28037c5ac0f0cc38f71189ec49361e438ce863e6617651977708094d5336d1da", + "0x85e7c2daae5fe59f8a1541c94df50402a671a17dbb8838113fa4b7aaff6114cf2bb5969410cf21e6a162857f2f7a83a8", + "0xa19575083e1731bb04bb4a49414e97aaadb36d883aa993d1f6847db50007315444814740e67e10177a14e0e074fd4c7d", + "0xa00ebfb5bcc3a6da835078189038a1e56b7dab6be74332b5ff7440e53b0f9e1eb9973effecbbf37000021fcf50c7c1ff", + "0x8969d7943abd3b1375fdfc7d6124dde82b0f7193068ed6ec83bcf908734daf3487a6a30f7b322e54a4818ae5f86d91c0", + "0xb959c8d210fa43af9b20d1fe0ea8c4921280eb4544ef6ea913309ff9d61c9327096707e84dc1662960519be8e7d080a4", + "0x9011d8ac651c42e0cb03931a9e960f58e02524c6b666047525e3b9097e9f35fb2b4b278efcce2bd5ad463c6d7fd56694", + "0x937e3b22ed0fcdbd9ea5a1b97b84bbe86b7f5b2de3866a930611112f2217f4ee7d9822c4ab1253823f77bceeae0c8e10", + "0x828997e5d121f4c305e018a0a0ba338bd6a34a7b4dc3c5ceab098ee57490311c130e2c045b9238a83908d07098d9fc32", + "0x8d114808eac0f2e1a942d80dad16756ec24f0276763cd6771acb6049472e05a9bb1d3bbd5957f092936b415d25c746b0", + "0xa063c5c26267ae12887387cbebbe51fd31bc604630b3a6e8e177e71d4f26263be89112cd12d139dd4c39f55f0e496be0", + "0xab1e1582c8d67196d10f969eeb44e6e16214f1316aa4a2a821f65ba5834326da6cba04373eabfd3b3072e79e5c9717e6", + "0xa17b1dbaa11d41457e71a9d45d032448091df7a006c1a7836557923ab1a8d7290ec92a7a02b7e2a29fcea8f8e374c096", + "0xa1ed7198da3591771c7c6802a1d547cf4fcd055ca9010756d2a89a49a3581dfe9886e02ee08c4a2f00b2688d0600509a", + "0xaf09aa60c0a185e19b3d99ffdc8c6196d8806169086c8ff577bf3801c8ab371e74165ba0f7329981e9252bfe965be617", + "0x98c04cc8bb26ffce187fa0051d068977c8f09303a08a575175072744e0a5fb61191b1769f663a426c30d405515329986", + "0xa542bf1c9c3262d488ea896f973d62923be982e572172e2461e0146190f2a531f62acd44a5e955a9f1e242b3e46d63ae", + "0xaef7b7f30efd50e4a66c87482386f39f095bff6108e68f74fd3bb92156c71c75757912b111060cdee46a6b3452eed657", + "0x8afe1e0ccd00079702f16ab364a23bbbd3da1889d07c4f8cb04fd994bf9353216360dbd364492932bfe20b8b69ae8028", + "0x9896c690999db3c08cd7b25efb1b912c3e0f976db98a3e830f086aef93222d06ce570a7b2babcd7c81d8f9955169669c", + "0xac7bcab6a281468907ef1ea8a6c1cd624159c88839131bef6aa0c22f331fc87ec6128a2c2a333fb79df549e4587e1a12", + "0x987935c08a30b099d19f96901315a2e60591baf898581c40bf5eddcda806ff24a4536e30ed1e6c0b128a83fc77b6e81d", + "0xa0a6945bbede3bb09a4a09ef27baa20619d3e15af5673b9350601bcebe952597c989870746cf75767ffb73b32c6c9c6f", + "0xb0f5590079f0a0302b08a0cc1b7a5f39cc6900c2a5cdc7baa333d8328a731b2df5dbb67e27a154d3c44ed1a795fc4adb", + "0xa7294bdeea210e528f277f3d50e89e6d79950494478998181ecb38de675020130256f2f2a075899170be964d478458b0", + "0x8ab3041b895a631869b439d5599a66facba919226ca9b39d915f19d59f9fc82393ea781377e9bd3bcc5a310e41376914", + "0x8da399b59151fd48b2579948bb82698e3c9804d70ec7d6f3cc7e82901f9f2de5ee850349a7d6f43e5e9ebd47bd78620f", + "0x80e8c32de83d1083916d768b11a982955614a345d26d85b457f2280ff6c52bb776958add7c1c8878f7d520d815b8e014", + "0x81bbec7bd99d2917d2dcd8a288722fb33ad5a4bf5416fba8609fa215fb80e0f873535349e7dc287f892aa56eb9e39c4a", + "0x9665796fe04c8519206fba58496bc84a8b9113e7ea8e152b65f7f732e88beea271dc97b1ea420dbc8257cc4b18a77463", + "0xa97e342aaaf693ddc87e02790278e4bb50117af4413cd703bdf3b7cad2d1facf31fde1303b43ab2e0265467474f97a8a", + "0x925549ebebed348886e37773b05cd8ad04906eca4536bfed951d1ee41b3d362ddc6e1a302c21ff3a2d1e70e95117922c", + "0x818fdf74d7903502101551bbf48d3c7819786b04b192d9e94362d2fcb85760d8b6f45165a5443aa5221bef400525ddb4", + "0xa9d29de7e8fd31b59f4a087168d062a478b1329cd3c81c31e56de4fb40de7a5be9a5269ef0be452c487443a0b097dd50", + "0xa85286ad573db4c9aa56221135da1e31d742e0f6ff01d6b159086d7258f78b08dad55ec8eb5c91ee9d3404b2eeb67e1e", + "0x92a79b37db5e777f9ebbebde24a95430a199e866e56597c7d0b0e7fb54c7b092c2f6cf61fb24470ddf250cf609898281", + "0x8d79f5ca67ed67d52c82949af342a9fc60fb793c47c76d84b4863c550796fcae2dd59e285897c6fb96fe31cee1efa62c", + "0x8ad2e0bda03415ab86324992bb62dfa3612d2d003765bcad1468087c27971d08bdbae5252681f0115a184f4885d444e4", + "0xa08815af979286538c31b4aa5ec805053790af1ca58a8c4341be51136d094a8a05e569d876a079033298ad355ccb7ca8", + "0xb96c2978d0165d619d08281d295e90df78bc2375d0afbc3142ebff9c2cd4b0f0aa97a9a0e3740bc4dce0ff8a9fac8252", + "0xb7752cd0e582f35ab0d0036ca9c0a9fe893a6ad325164d78d865a604a85d3d23729e0362553e8b8a3d51816beeaa30cf", + "0x99cef1fafc29e7adfe247c753c475ad4bda7a5f9558b79c86e8a65968ede67adb38dc30071925c9d66a13860027a6735", + "0xb9f6c65af178c791b6137d71980651fb09cb5b42f268999c728c6e129985a9c7d77b3dc3b50751bd29ec9ee0b3111dfc", + "0x8d73ae61fff5be883a281782698075c5650083f00399992688738856d76d159803be0059fbd9dec48f4f0432f0590bbb", + "0xa8a4a2865226de9bbf19e12c7e75318439fa6cf1cbf344d5e79a8f363439d3bc5bcf4df91b54581e7866e46db04eaf0d", + "0x894582aeff222e145f092ba15c60d3207340c38f2c6792ee2ab4d82d50fb544ae366c2985cc2b6c2f970bcc5f4b46385", + "0x956014ba2d20a056fd86cb8c7ceeab9a2c6f905dae24fc1c5278fa5b84335148ebdefec5dcde8eb9b084700724fc93d7", + "0xaf217fe2b654eff6d11a2a79fe0339a1d4cb3708b7be9f09d852158b5a44b4f9b04406d6d67c4f144fb6b69a41ae9d0f", + "0xa90752a784bc00df94d960e523f5596695d16a534fc806179e0f878fc0e82a91b25e758e91a165debd815dd1af5f1028", + "0xa697606fb32979549ad822b31df8eaaf50de4ead984439a0a33e955937d326519bb9f62c8243ad37f764655f8d32cc80", + "0xa3ad4a30922e45a3e665551e5611384f1c2d414f6fa806184b0c826af05f014dc872585e255543794ee41e43cdadd856", + "0xb29c255843a82ea74a013bac6c36a694646e61e6b9cefc4c130e2ee261e3bb5da3e0fe3ee7e6fbb009deed0530bc1c82", + "0x87e1cc7febefa829cf050aa2aea59385d1048f8617abba691f7ea9ef58eb90ad12eeb9c439af228b0e34897ba1cf1b47", + "0x994d3222f89e9c8c154362190be7167c8c2662f0cfa9d50eb4d8175b255ff0de09dc548ee312fc8226963c8c16f43e8b", + "0x8f1a980be640820f2d1e953264ca4c30330878971669852be3d5d6b41c488be1628b935388bfa2bd4de484acb0fe661d", + "0x854d90d0721579c8c88e147a4aa83553c960617b18075f8224b975562dccb30b0e02e81fa9df7070f356a0eeffc3b14f", + "0x8e156da9d4330a03e32a25a2f0b861fd3ea5c719fa4f834119baab6e5fa5236a9baaf0d44147bf0841418900037f6eac", + "0x96586fc49e53a6799242ddf617000db5a0ad20c6cb1686af2102623d64a71aaddb8e468b15fa6d100d0384e448548db4", + "0xb44d8d85c8df95d504f82d597f8c515866d4d4a326fa1b816dcc5bb0cc4ef1a52647aa5d2e84c62e194c01cae0885d21", + "0xb75c43e676a7efd199f8b32ae31f176ec667e714df355e9eecee97246f72af5bef9c5b04c11e7e90fc37bb9163f957ec", + "0xa49835ac0565a79f6a9078cf0443c5be20561a68b448289589721fded55188583f1d301925a34eea647f90a6e66c6774", + "0xb47c17ff6824a00b8f29df0adb7f06223208d062bd703b0f763c6eee4ae62d4217eef2da4f4dde33f0b469c2f2db9e42", + "0x957cf039cea6f6d41e368e2bd0cf77315938a0738f15ed9ca342f0a28658b763659ac1d1a85ecb362f13de12b77bb582", + "0x903a52f8d2439fa63f59e1e9aba864d87b0464ded63814474947112375236a6f84e8fa003cc4433c8208d80e05fbd1b0", + "0x8afd524209ff08d1eb6312b078f7afeb8e1155af649e930ab711dedda226dc2db6b0354aab9652eea7f433f90015bf7b", + "0xa95c3c9277b11bc8fe191773bf567641be57c0549913b973fb18740ff9cd7b3f7ce198fa4dc1086b2b8a446012459193", + "0x9455ce8163fce04aeff61e7808ef3aac4725e51404f0858fe5d39d7344f55dcc7871ca332aa5cb1a63a4399529e48907", + "0x809fa35b6958f94e781f2c584438b33f5ed528a6b492d08960cf22ecf63ea3aa1e2d29bc879e17296e0a6cc495439cb6", + "0xb0f50774de212dd33e5837f6b496556215c665437e657f674fc5117e5c07dadbd0d057e6ac4c42d50a8eb81edfebf315", + "0x844c65e263891d0b2fea7db6934cc4b7fb6bee2c1d0b9ab4c47f2eb3e9c5d7197dad828d38c54139123740151420280b", + "0xb13c78c9efcbb3b28eb3fe0b971380b7d5151c80948a99cd93c78b4c3ab0e86df6226a64d91e0a2ea4a1c0a46bc0404e", + "0x90300a541decad460c348b8f4257f7a29687b2362ebee8d92fd03cc0e85b285ccb0ab1cb2ff5e29c5cc5295e351017cd", + "0xac49b409ded770c6d74f6e70104c2cdc95b7b90609da0743c9923179e8e5201ead03becc0ab10d65b3d91a5be0d52371", + "0xa257b815bd8289dfdfc21af218aaba12ccfd84ebf77642cc4cf744d9b0174ca0b0d7ab2a545c2a314fd5f63c140f41ab", + "0xa34778d8446e4d74d8fe33de64b2694ef1e50bc140e252af6eff3ce7b57acf8b6577a02ba94b74a8ae32e5113cf0a29b", + "0xab9e935bcf0d8607e3d66f013d9bce7909962cb7a81174923db02dc89e485c2b1c33d6065bdc7bbbe0450b5c49fbe640", + "0x94d2c5c5c309c9eac04be4636f61bc47fd9579b47aded57cc6c736fefb8dfd8f8a5de32210f7baf2052d04c0219d3b4b", + "0xb8dda9046ae265214086355101be3460421f7cd0ed01bde9c1621da510941d42bc93cd8060fd73f374fb1b0a5f38d45e", + "0xa6674649dab5f92ab9fa811d9da1d342cf89ff6eff13ad49f4d81de45438e81a384098d3ae5ccce4c67bda5dbe246d95", + "0x8d619f7564677bacba29c346c4ef67c211f7a3a14c73433dd1a7692e16a7e2562f1d0532454af62fc04c2fd2bb1789b0", + "0xa2b93d2fd4c707f5908f624a0fc889e20164d3c61850af9125f47a1719757a6ce6375aa1910eafa4c1e8b6e20c312775", + "0xa07d5585447654d82817ef4d199984542328b238157976eb9a267f0bdb2229acc25aee510be68f65a312b68fdd9e0447", + "0x8ef55cf95e2b24d8ec88e4136399a7763bd1b73d5e90ea45e9845123e9d39a625cc336e9b67988374b8ebcbc75f2ed21", + "0xb62c1fc32e27c767c461411b02fe9aa44a86586e1427406f4ef0b346d077db91952abce79318b382ec75b7be23058cac", + "0xb252900345f5fa15a4b77fb6af6a2d04db16e878b7bd98005333f7f6e3c8e6e46cf38fc5d1b2bc399c5c2ff4af730dc6", + "0xa4ab5ac0cc15d3d17b1747c6e3133d586870eae0a0d9c8fa7fd990ebd4fbb62e9090557ca2792a6bc6271856aa3c9a05", + "0x8e706b3f2e902faee10b22742c6c33bea6f670a8937c243db96885143c1db5c979e33ab73a38359b52b8d668ccd092a9", + "0x8a6792190ee6c959d79f60c22980ca140c638d88d75660adaf9bcbe6dc4692ab5f01e0c460170f09f74d5e582e85ff1f", + "0x97ffeedfc94c98ec85ea937e064d7b290a326838e62cebd407facd1ab4f08d9c0c109d79af7cb6170fccfa6c8243c127", + "0xb79970b67c09453614ffd83a0c923c17f857c6ce3c87a356298f8351cab0def7ed83efd4f6638f48df67e07bef4ad9d8", + "0xb90f1931c7cf1822cc0a97401119910cdfd0482daf09a4d7612e4e05046295cfb4cc50d5214b31676bb1a1c9d15f9c7f", + "0x922921ad813c01fb5d12fa7fb7ed8e0b0abbf7b19affa190b36013c55b88fe3c7df0ae663c970eec7725ba37b95a7cb7", + "0xa124f33e7f28feabb4089a063a08d52b7395d24eecd06857a720439dd9414b7073bb86fbd0b04e7bfac62d3dc0fdb2f2", + "0xb252fe50bc6677c004550f240fe670974a33ffe7191ed7675da6ac36c780c2f8d02be7da5d92cbe2d0ce90147847f8b1", + "0xae5f8c9c56070f919f3df2d2284348fa4b2e39881f7bc42c9b2f5b7cb1ebeef8ecac000f37329bbe04cc1680cefc7f4e", + "0xb432a4575caf7337f11eecfcbd34a6705d0f82c216301725ceae2b3c9df20fa53d1ebef65513e305013d1e0c2df522b6", + "0xb7c016fbbc4614cdbb12db1c9ac41f9a45d5e5ce82594d568a30cd2c66c3cc9d91a2c959697b67c582a0913de661505d", + "0x8f6f3e5e0347dddc1b2a34ec0dbbbb7cafbf976f19c9c902efb5c1427d1bbd4b71abd9f3fba20dda75c35a39393c989f", + "0xb0042a1d33a1ee9fdf3fad2299b8d70c4f1862d8393b5ebe3ac2189a2c5a58bb826128cd7a39b70d524a6dd976097e26", + "0x85297c4e8ae8d9b44c3fe51aa926c77d55db766c2a9f91b659040de36e34c9a4fc6f44380f8d61704498f6fd52395a49", + "0x8c61a988b6a00fe5a277450f30bf6daa932e42a2eae844568e3babf8815e09311f3c352dae6eb2d57a98d16b7beb2d22", + "0x990be28aaecd932e7edb2a97b9be2789a3905cb88737b1c79881302585801c69a3dd5fb230808b39db1352fc06e0b4a8", + "0x82fd14bdb335aa46f022dfe0ed4d631911e6b6f5eefb10d11e9e2e02a7df55012ed8162249d10b58eb76ced5a7b06cda", + "0xac39cb058df764e161db9c39b185f09aa210bddbd66f681f1697ddbe6b305735612d5dd321d3ffbb4876771bdb321e2f", + "0x858a3f7e57ccb81387caf8e89f9b6039e9aadeab06886d8688fe6427151a59ab2e77e85ba850c67d099965426c97779a", + "0xb57fb9ea623cec432946819937c6bded0b5d03c8c67b52b44a4b67d34adfb055e6cabca67a48e4d859b4be45162c5083", + "0xb84d2990b563d6d7fe1f4c1894989db25b81745090b94b1fe2ef708ac3b2110ef93d647820b2a51fcf78e3f00fef5412", + "0x817d85b9f5e1521733d2b1fa6d4f4957ac445dc803f97fc495e20b819b14e651332f9e0573d684b854fd47824c53f0e8", + "0xb09e18e97e93a8523101af594422fb71afc5b8826002314269016fcc1b44002d91bcb7c90d923d460f0cc03bddfe9af1", + "0xb867cbede82102de7cf6cd0dae68506869576eaa66c3fc806e73585310602682fc912dc37adf5ff6f0f34a07831735b1", + "0xb1126255798368b692f2796a3470ed16e5ffdee2d8c9e0f7ee3d2e92950c3e6365c32895171c3494aff2a6d6356f7e25", + "0xb05f0a0996dec16335c770a5df3f0b08e20020c838c2caaa1d3a4a2490ede98552f5de349de2ce6e4c4a839731d80919", + "0x98c512bb91c8fa191120ddf5d63c88076581cf41e15eec3c168822f12b3dd0ce4d6df74a7e3093d3e35cad1cb3135421", + "0x84ce38fd97f7f90012c2c1e59a67bf9f465a7ccfb6f308bdd0446cc82b8a26ff7c30e5c7cc375011718cad1b31adaa9f", + "0x93139db52c9fb96dee97a0825f21e34c5d6d36838e1e42f4d12d01eacbe94426c85a811fe16ca78e89e08f1c27383d28", + "0x81454037b1e7a1765f67e4288b8742eebf6d864d9b0f508ab44fa3243168ce0ed30cb5f33dfcdb995cd2c2710ff97a6d", + "0x828deb2a26efb2ff1842f735e2cc27162360f619b6e3e27a85bedf384912d4726bb2759a3016937973092ece1bf90540", + "0x87e5a7d4e7bd301078f625d9a99b99e6e8e1207c9f8a679f8ebbbfb467bfa0b5f7ef4a4d577c7d2670efa88221153012", + "0xb9dc9d0ea48deee201e34379447bec789c8924aecd030eeb93db159af77eff230976ef60ea9f4b4a9e9e95c1f9f4284e", + "0xaa6528268d46bf0627d87d58e243d3ac34b863513c725908a2617e4c6a46ccb1d8c8334bd6dd0eea7ffebec44259dae5", + "0x8d26c9ce07293f6a32a664d31e6df9a7ace47e6c38001635918efd9872aceab62de7757b13b783d422eb67bd28ce7bbb", + "0xb0d3ca88d9829a7459b89b0dcbdb8bbb5180b00d750bd959bd110f53c2dd5d4db554b6005c4765fbe7ec5903669e5ebc", + "0xa94d1c72bf3b2dc6bfebc9dee40f6a89a516b252bd9f4fad96f156e3dbfc151a9b8a02324d764c7656d59230a18eb61f", + "0x88996e79171e30b16505638d8ecb25afd875e5f3cc3e29860937f2b5e751c66e78dc77f744a0cc454a8a655142a93ffb", + "0xaf4d94f342665fe7ecda318de6cf1bc1c40c37dd83d060fedaf827459728152b5f0e280286ff5e6a0012036f6715f53f", + "0x96beaa7a2d565ec14a4e5cb895d33624c69da56b75c8d06ac729cb6d0cb64470ed4f9b0387083cd827b1609c8cabde8c", + "0x96b773fa2fcb7377bf71a7e286f37f1f24ee42cba5b4f33903c4566e5e5bcc501ea360e3c8435749107c3de84e272d8e", + "0xa69ac6218454c3f40ad0beb48821a218fb0a4f33ebade986d2fffd9a3900d8cfa613bc71676c46cfeaa5f644d1f239a9", + "0x857f139c08fcc45370f448ce3e4915bcb30f23daa4134407fc6d78efac7d718b2cd89e9a743eec7bf2cc0eccf55eb907", + "0xadeeba36af137fd3c371a2adbefea614c3ae3a69f8755ce892d0dd7102fb60717f5245d30119c69c582804e7e56f1626", + "0xafa97ca3548b35aeda6bfed7fbb39af907ed82a09348004d5705b4bb000173270ce44eb5d181819088aa5a2f20a547a2", + "0x8423bd2d07073b0e87819b4e81997e4d3188b0a5592621a30981dc0a5a9d0578fde1638a364f015078a001afb00891c2", + "0xb92e9d4ec3966981ee574695d6e4865810b8e75313e48c1e4bc5eebae77eb28740e97ecc3e5c42040f9eb1ee4b13b0ea", + "0xb07b218321d54cecfcd2ed54a5fd588a6be8d7a5b6a66dff7facfe061222c40553e076e57cbdfa0bdb08e0a009c94ba5", + "0xa71e1ae4d6096eac9ea4c21f621c875423de7c620544e520fb6ec3cb41a78554aedd79493cbd2c2ba4f0387f902ddd2a", + "0x807cdac291246a02f60c8937532c8969e689b1cfe811f239bfdee0791e7aa0545e9686cfb9ed0c1df84748e5efa5e3da", + "0xa1faeb4504c057304d27d54fb3ec681462384a354a4f0b6c759d4fa313253a789250c6b0f44f751b0718592637438a19", + "0x996bcd3215182d49f1cd15a05e1e0a4bf57e264400bf14f7253c6611d2571de7130cce81fd28e0411e0a80e9054f4f98", + "0x89d15b38f14bcd46f4b2dcae82b0e7bf9a35e40bf57aa947e9c4a8f87a440b5cea95229708de08ca596762062c34aaa0", + "0x8d8ddcaf79374c750b8b0b3d196acb6bb921e51b4619876a29d09161ba82a42271066187211ef746f9f40a5ca17b75f7", + "0xa3dc7f70f3a6c7edc483e712770abbaa94bfa3174cfee872b2cc011b267e0ef9baa1ab49e4a6c6c30dbba0e0a1237117", + "0xaa9e958bbdcb192b19c43fc6fd34afcd754949fdada98e9f4848e8db0e23acb27d19dd073c951a8819000f2356aa22e1", + "0xa4714e45ec853eadfe5c3bee7f683b81f97857bbd7833192a48936dd1460aee68f700a21658658b74b737c4fecf90c7f", + "0xa1ecab4215c1892e4a8ff3405d710163875e5dfef8a8cb84f5cac4e317d89c7696e3f496ed1747ca6f52b304190f4ba1", + "0xb9b48943eca3686219575026d395b969e6ff8159dc5317005df090e79d26901984e40ae4b1af060ed3ff6f42e0417d76", + "0x9644b9f90a66edb0396abd8c00066886f978ebf56fc22081031fbc9ce371bf9b04aa5a4ef59e59319b3a05bb7fb88b43", + "0xb2bb14f1c055a78596488e4e2d4135a6470c1ee43961952160b8498f674a4d23040606e937c02c1fc23dbd47e9bd4633", + "0x8c61f2fce9a42b94a389c7e52d7d093fc011099d0f4914f6d6f05b631df7b88182826edf9bbb1225971a080ca5c0d15a", + "0xaa6a7b8499cc7d256043eacad18528d38bf3be970bea4c6d4cb886690280bdb373688ceba3e506471e1d9493dc76f3f4", + "0x8127703363b3b35b06762c2353d4de82b7b85bb860db1028d3640f46bdb78f2d104fa77ee3e0d9db83833d2b12a966f8", + "0xb7b01f5909f2c66ae0fab156be5d79954e3a304615e1fe55945049dd4bd95f973bb3821117eb54db7e9ed1ee9a527652", + "0x8be47ba5dfe212420649193490838670c40540e0ea24adbab18c4a66e7ac3dcf94f068dec2533b60e08c1f64e7533e54", + "0x905a6c7e24b86aa54a05c329a6b4616d335bb0b1f1e9987562eee0acf82ad302c7c44981a1dd6b24c6121ca12fb92996", + "0x86969ccfd91deed93b355a2c21319e3bb08cc652b741463bf68c626b7ba2afce3f7cc397f2fb74588c2893477c948ae2", + "0xb5a9d20eb12c331d0d300fd4b85b0ac0bb74573178a5fac8ec9dce5e95acba07fab444260355ece442a846737a2dcd1c", + "0xa13497c11df21b11fc1a63b0ffdcf7f432da4dc2c98f8d07d36da4fa68aceb57af2158088e5b05e334fe0f264aeb7a97", + "0x882e4597cc66498a45e86a2ed9ee24652da4699af00ad35f73b5e74fde6ac3cee70630962d5ddd86162d4aaf11bbc11c", + "0xb748858c2bafa4a14ce44af35195e9c52aa75e109719243bbe278095acbfd6a7ae7e084caf8dae6939039b5a4e8fd675", + "0x83a2e0524507e74f51fe976441108f8226ba1b3a33f4e16ec45c5661ce80cb1840a93d17122cb8ca9e0f80d14f69877d", + "0x846cd2946c93ee5f24243d9ebc69936b3a1a6d59f45fec6c79b1eddf15ce30a8e73ad03cf606ee66baea3d8ff115f70f", + "0x8d98d0a3a94f6efe158f8423c041b546416145c5c2254bfa157efea0d1c99fe58acc7df6424ef29f75960b18d664ea4e", + "0xa39fa47e4b79f54dbf59d0b1726f1e78bc219fcfc56ad238c84b4b610e7892ff1e65d537baf5118a32f5e2eb80d5ee0c", + "0x8c30969a4519131de5e30121c84c04f67b98c8ad109fa4710dd3149cae303d51778add3f258f0482f1c89c169824dffc", + "0xaf7f80d141ceb78b4762015de17fef49d7ff6202d292e9604deb508272ee7569f7fd5be3b2438da1dfecf0c26533ef86", + "0x97cf82f70128251944d79b8845506975405bd720e150d836205b048ff36ba8801eb74cdcc6425f28f6bc0acec0a81463", + "0x8c276c876eb88688957d1868bf3a1462375e608ff72b49870a5dac82cbf6584e00e3f36f236f732348a47502ccf9539d", + "0x964765f1a5c8a41d8025ddf56dc01b78424703d8a64a4e5539e477cb2445cb541c70127c561e717256d13f91a830ba83", + "0xa2aacd9e21b8c8efaf2319611addea1b9f41430aee42e7f2a640cc693aa395287cc8fdc2806b76b577d84fbd05378ead", + "0xab11eabbf5be4345a77323a3b75f9ee93b011fd2a9d0154e88183cafe47f82a7888666af16b40d3cb677c94bcc755ff7", + "0xa0bfe715a7af5a29b1b6148b8cbee585d2b49fa6ce59bcd173ea3bbc60d71a62f9da27ffcbbd5a6da75502112fe44d70", + "0x902e6cc38ee42245103d90b65028a471bc7a48b825599d361aa81d8c56e0fcf9fbe8d4c13802040d2cfb85b7e022eea1", + "0x8832e2b5014fdef4003bdbb87e3298fdbdbbe49673f6b66e2373f1cb2605f9c4af2cdf9bfd45d1993208681d29ee1c9d", + "0xa7d39d3fa1ec1e0c87730fa43d4900e91932d1cafb36c76b2934907becf7d15a1d84d7234591ad4c322b5a24673bba8d", + "0x836ed5f09d99624204aa3aa7ac601980fda223f3b4b96b4a8fb235c574a3545d518787c12f81bd5851987f2860d41886", + "0x94235e94445e6086f6e9331923262070a4c2ed930ec519eabb8a30133bd4fc6debb99185f4b668431fae1b485c5c81b7", + "0x9828ffe20b9405f117dac044159be2d3c6e2b50ecdd1651d6a73f7633e6e2a7ba3d783ae939973604446d3a1ef0fb20f", + "0x92f03dc365dfe9154743ca70e6dd2758f064e3286fc543cf8c50f68effdf7c554bd17b3507c6ff4127046d9bbb5522ef", + "0x91ed07df479d8eb3d31292a0e987672a7f3d45ecafe72935b7abbc3f23493605134ce573f309e226c9efe830b6868220", + "0x93bee582661e6d6cefeff29002afc2f36dd2c13dbf33f0574c35b290ddc426170a5f7f196369ad592efcd72cfb6f8fc0", + "0x89a51467d966f48fed15dea5a12dda54d0015f69e2169b5e34f44c7b5a5d4c282d6f138116a0cd06a8476980e420f8d8", + "0xb8ccebc14b6679ba2399370848864f15f63512fd6139df7359b7b93e82c1007fd85137ecb0597294b46643e1a9e7ab5e", + "0x841fa301567fc57b2cd09508ce75326684e12bfb8add671dc208f579b2500b93d5b641e9f59bba798ed4ed1259757f7d", + "0xb3cb45c15eb00b4ccb7013299f761cb8fefc17adf6db50e9ecb8abe927a3bc7f28e359e64693813e078e1dac800ad55b", + "0x96e55d3b9f445f5679e34fa5425b3e87cb221cfbdd07f8353868c7f7f4ba388ee3841cb9a1d638583bc20d03a9d071f2", + "0xa7dee9377de740270c5b57cf86699004ba8dc2766af56b388b5cb0814ec71bb99ecf43ee3d82a552733854ecc7def0fe", + "0xb129dfff23b3c1c95ddb214c4711961fcb129efe2b6557ec9e116ada909593d0d2eec2c628434493393c58c52aa86847", + "0xaed2670e201cb3e38a8be3c86735a4d76255e1e5a4c67b91df6ed262d09c8d10b0a3891da3e6ab934058cc9a7178931b", + "0xb20b8921ae52e5b3c94fa3a8b46489044174f7b897779e7763d6eb419e808d76705b7e7ba5131576f425aa81b6b0de53", + "0xa7e45bbc3ba1bc36617291ba7663806e247f1b57a89e31520c64a90cbf8d426cac2e2f381338baf78c8f92fdbbcb7026", + "0xa99e651e73a507e9e663e2364fcc193ec77e8afdc08c2bed6ad864e49b537ec31e9114ee72291a7657899f2033a849e2", + "0xaf966033636c2e9e8280d173f556fe07f8b6940bbcf6b2df7e2165c30bea66cced2596f6c17ca7c1aa0e614174953ba9", + "0xb69ca7a79e3d55ef21e0ebdc6f0c4bd17182d30cf6290cccca7d2551c91c12b966020d8e40e4ee4179488c9809c03ae4", + "0xb981cd36244e035fef043f70b1d7188d7cd045b4de0581c459fc5730e10eb7f3d5893b54cc4243849c0855e4e621167a", + "0xb20fea858a36921b35a3051ce787b73f70fdecd3fef283c15a2eb1bffb1dcba5991eee4a047ce4e87802da923fd9457b", + "0xb040e6f2e56dc1860274c263d4045837456f74b354a679f6b5ea70919835ebe5d32bf1f519e218730096c98ff396dc9d", + "0x8d2dd60e702c923a7204b530e7d6c193c6f93ca648c4f7bb38f4edbeb0aaed84184213afafb8db6aeb9197c24364276c", + "0x95dfa7348709e43d71285b28a0bfad3ca805b6ed4ae99753e9f736c79d58a35a3a50b42760ccdd03eda50f6e59494968", + "0xb8585632a13f18c139a411bb2f02df809591834d127cd1ff081e26d0abfe0e3fbb54abea26538b25a0dcb4d7e969590e", + "0xb46ba47858a29c6d523c9982660949567666daf2582b93393a4802a9e077eedbc0d49d454731696bc8e46ca50c7caa40", + "0x84b756b901b98a4404e58d70f39f6ccac877146c866732ae65e7e82727448d1550343bf7cdff1bfd4ee1ed73793db255", + "0x83e5be888eaf877a2c755897410865f64a6d1169a8ccf0336092f3932abab915e542ab75a35ffe016042340d581ee987", + "0x8cb274fc39285aed451a7def72cfbf73168ee10be02affe355a2bf87cf361a81ad284e9334cf00c5bf99a13d9f75e116", + "0x91ff6220924b94ae13f50eeac16a159232e4f16a73fbd5c22c0e185cd1998403904d36bad203baa82b85819ee4a8ac10", + "0x87f46e08e09aea2ab37b55fc300689d9b58ff3e72f1cffe023386035888f714fac4673c7c5193d3f3f3c568c640694f0", + "0x835d7d84ca7641e1b15095830114aa6072fe12260d2202456cafe2308c22651af9ffbcf6b7e56af97167dd0c4e2a4cf2", + "0x91202183f79794f114fd9e3b9bd05553c0e8985919965101a57d97ef666b028863e6cea9735af016dc1864f1542dee51", + "0x81ab2b02a9b0a490a74ae615ddd4fe560734c1bfdde6b8dd13303c1481ba0e8ab14473535a93cfe4e824a0ab29445f8c", + "0x8a32d73f4fc006551d4e2c61eec6130355ec9b8c39a65c24ec1edc00e80155ca83a8ef2455e892521a3d47634d82a987", + "0xaf70d7b8f13bc90193cc1cfb0c400c4224cf10f1887848aa93e6380f7087782fc41a159926ab53c53eb95c2383b1a849", + "0x989bf42f9d357c51774f1c7c0f7c0c46a8cb7398a74497141c32685be098e38b4230ffe833a6d880ec391a35b1a747b6", + "0x94cb6715ee95700020c630b8c19e35f231de970219bd7e6ba7ced01899197da473b6c45cacfab0d652ddaf547b4ea58c", + "0xb12e3331f1f7d7458393a785e22e9a5e1d1daea521b4e78c0ee8ca59b41ade1735a29820e18f6afb2f2c3c56fecc16b6", + "0xad4b7cf654349d136fb41fb0dd65b588199f68b462b05f5c4e5c2b468bfaa6c26329033e3c3f7873dc8ace89cf873ea5", + "0xa3279969e1ab596df0559ffc5ac7a6dc849680354e01c3f4fd34c6413a3f9f046f89c1e1be0b315d8b6dfab3d23d5c14", + "0xac74cc5562836ed89d09a9ae6a3644c936d64bdda9e77659d9982f1be29541b03ef2723236d5465e398373ea19a4ccc6", + "0x98138ebce1af531dd8b631b3e74c84f0c700355a2a9bde31e5e51bb10c8bbd766559c63f6041f4002568803fe08438e0", + "0x9006445da131349fe5714e0777a4f82a82da343612589a0c1596393e8b6894ce1cf42784f95ff67a8384ffe1f1a4ad76", + "0x88502a84a85e4ce54cfed297b5d355867cc770a8ffd0714a6f23b1ab320a9903c6e42809e034bb67dbf94c4fc0d9c790", + "0xaa8b4bf123d1a6ccaa44b86be8f980005f2a0a388a76cb111b0e85cd072ef64167fb0c097c7b23c4bca64c0260f6cce0", + "0xad49eb35dfea9feabb513a78dd1152ad7eba22fbb02a80cefc494a7037699c8df81202dfec12acc1b9e33ad680cb72d2", + "0x8694da730231b29afd5196371ddcb15b4dcc499574bdd063f4864ab80749833ea38ab8b0ca1629a367fe378e87a60a86", + "0x8eca7b488e810c479e7e32e24b8afcd837f7df183fe4f621a0336b53a9ed77603c84bdc365d8be68179a32b71a1deb7e", + "0x8875cd3e23c7e1af55af1b091025a08255743984186770bcd43f30b4a58d175cfdf1984bad97a15e08dac2da27198c3d", + "0xabdafcf58ec72997e494d4714645f40d09dcd0fbd0733e640eca44eeea67c25bb0c270299c459991f2fae59d13b4f4d5", + "0x8f040970141e61489284f3efd907705eae6ec757fe8e1d284eac123d313e9ac1e8dc14ae3f04d281e1effc49d5d2f51d", + "0xa7ff115f0d2dbf66c0e8770b3d05157b37357b9e33e9a447f0f3fa9da69ad04e371fd1e4848cfb9e8d05e3165bd969d8", + "0xa39b1a8c39d317fcc97bf6c396e6ed4a85640aeeadbf45166bd02bc3bdfb6266509159c03afd492e642384c635b824c0", + "0xa2e1b90f3dd2d0038eaa5be52127844ccf35d997143179d95ffd3749c0896398b130094d01eb1bb31ffe80ef34b42b48", + "0xa2bbe31f89b0c3c375ffaf63c8b7831860a921d5e388eb7907dbf61f2601ea40db86bb3952ecaa26a5eca4317a848ff9", + "0x87d885bb0f2ce04b40ce94d2557c15f1698dc652e938f9a2d69a73ccf4899e08eafa1a59a20cae92823795f5b94f04b9", + "0x8f7746370f8a24a2889d351f3e36b8a7d60e75e50e8f5abeea7dafc75441e95915721654e61ceac51bb6f112780d352c", + "0xa7272847526ed3d9e0d0fea1d8685b07b5b908971490bf8a46748c8b1783c629b8644feb5bac772ae615daae383d5e72", + "0x978c9aa2996d8bd6fda7e0393fa8b38747f8f99712427705c00f6e9a12c36f8d8b4cedb03fcb9867155cbddb5200e6e1", + "0xa4dec4a2354b2b32434c5bcdc380bf84580c6f9940f94dc0498a5bfe89c675a0921e66b807a3d859a6059a464cb2a9ac", + "0x99459ddecc7abce437f68722dae556d8ffaf8ed974f459e52e6d4a64f176caa4d42c2f2ec57e8a5b5f2034638e8acb0a", + "0x928c68c0c9213fe6258ab5bb0c693d97203d15da359784de7824dec143212da57d062a1fc70a79172cee31adc7aff382", + "0xaad3f318f1622ea87e12541dfd982d71629b8f1ded4c301f9f6b6af9432716ad057773c33bdaa6f15dc151b0ee4505ea", + "0x8eb8e978f149a983fd6ad01773f9aacf57bd0cc622d8a301e404184b37e610123dd081faeda571a0ab1f149a3960af10", + "0x851e7191d7b94bd422bcece5b92609fc1b1c8556229bc53e32963b2d2fd1cacd8ce5da9040b599eca6e610540f8a7987", + "0x9414157fe9d50e5a0b5a7397417681bcb3a651eec1cab63f2a88d5df68ab1fef6e4c1d7ba657cbaf241a7cb790297633", + "0xb5cb2dafdc5408959780754a58b2da55b2a9136672ebca42f34da4e329ddc89360e7218cde3efdbf784ddb390deacc57", + "0xac6b70f65503a8e94b773fda3e72615745824930114fe72b6d833484285462392617c1b2eea4a250fedbee88f503f3ba", + "0xb0829a5312f9ac6c06fddee2f835a3452fe994f6d42c9edfc390d7d5b3240ca544433b544cbbddd6516b38a6d5d7c21d", + "0x95f8e2c59905957e34d53be3d6fb85732f834e2cb9ab4c333fea2f502452a87ccd035fc9075d7c0bd8530bb0a0c96527", + "0xb93f279b7045f2d97c674495f6e69a3e352f32f43cc60300193b936c2850b2805c15457251f7e3f633f435cb2b60405c", + "0x915abf16cba1a0b655b92a8a70c03e7fb306b86f3bbfb66967ca63e64c003b59c7a5953675efa4fa0bce9bed536b6700", + "0xac2047f50a319d09df1ec44d71afdcec5ac3bd2765dc98aba347734aa780863545df9f6d71214d443e3f37edc0dae45a", + "0xad49c74ddb24c8a26b14ec08bc807313c77c5967fbb36237f55994d7511bbac8d7e7b9b8ec53eb1b3b066989f078dbd9", + "0x961483105f605e959213fe9e8a52b76dac62d7efd2319ec71fc4e92d68fbe44cd2f65d7adefb2eb64d591b91648b8085", + "0xb67fcafc97d8df2b3075bbff7b3d7471dbf1f3048f309e55d5e2c5bcbc7a73aebcb0697859be9f387cbc7ce98041e154", + "0x8da70ac16468cab6066992389cb37c79ff5e0babbe67d76878aef9408b9597a3dc2eb5de87428bc761a0d78957b0eb28", + "0xaec0ce89770d299b631f15ae12f94b1e1014ac57d38fcf037c2c7712d770d074affa06e97c60691bad8733874b6ad2ed", + "0x8b702c85fa4c915a09fc86507f44d7aeda0993b77af87780d70cc98d580c6e996b64b7c16cdb4dd4562cb0f75da36ee7", + "0xaaeb43aa472aac2253e211fd1066c3a5422ea041cef20168702d0618a1a742a44f7fb30a76677640fea1a24e7fae1996", + "0xa8820e92825d6e02b9b4ad5ebc86161d3244cddd3d244333ba1576b6ae10948145b68d9e926bf6b7a2c25dab4cf43f3e", + "0x8ffdae28a1f1d15d7ffa473628a66ee9a739073f59ba781248286b39cb8f7255f66d62337064246713cbb5017e615174", + "0xadfc5dd142b7911326d8424881d5d92006f3b17de4cce91674d6ea37f00fbb266c791ac13f6c7a0f61d04f2a952e6a04", + "0x87f98982444bf661f539bec73a10256f079a4baa88a1cea0351ae3de929e1c500485b2d1b5d933063cd7d9123d5050e4", + "0x8f217ba4dd404c5ee384f0c9a126686db001ff0344c01c82174c5e5ef89d1a241b146008c534b13a0da6c8afe7450fbb", + "0xafc85476dddaf1cbb4ba8b22186789f3818c7964f9f613e55010278800cd95422702248bdf9c73760702ef24854795ec", + "0xa59e0f6ac2ccdfbd01f002008034390c0ea78716f5e0de4e474e3558755705c9c7afb6e3c5c4370e7bbc85958a9c7a63", + "0x97c0695c58d792ec31d9b86d3b2fc1382f0855057b24d5f6a54c41f76f9e2f52882cadc89a8b2f121530e7f1393faa95", + "0x8e49112de0b2649c08a96cf737af68fa8055f1af594846a2d0534c94df6f926f200405edaa6e6ac9db7e380707a2571d", + "0x99a1bd83a7ac5f8d77ddf044c80ebfc5745b998714696d67b94d185c97e9d6db989bacac646d9def463127a8b2febc00", + "0xaba80725f9f9f7abe10760eca73ba427ca8df864a157122eb9af828a05b0199de3add02019a297750bdab5380e505c58", + "0xae18f62573275c1eb268f74c5e54e8958547f9e7d1d36a05b084eb53e5704fafe2200b8aff95cc7e9af5be2391c42b7c", + "0x908b8031d09d22b2aefeaa876a998e0a97c7a1070aad9e9c97836cc5aa6d2d5ef94230e1222074837b5e21b4e6490f01", + "0xb3132282e8b41ca6789ec5c43c1fecf3a65b8eefbc2f3d10f746a843b9ba4ce6db664678e75e424f7b11a00c1440de15", + "0xa1eb49440cc106ebc09cf198c93e8070271eb5a936d31c04858a2b311a037350100c7957d5545c9653f396aa968b91f4", + "0x81df6ad1bdd5eee4cc2f94318467b8602d15cc1be2b48b09ade12cc46ee05cbaaf77a20397e5015030b1f1db5dd9dac0", + "0x87236c68a2a93c8442d15d7f1d1dc01d1fd123439c183e1d843f4ddd2bcf638c128f66f1ef9b710e5d1f64a52726007a", + "0x84f2e7f85563bb2f61b10a712c7605d63f79af5be0dba056814fd3efebc20e9c53227c56577b72c68d185571b775eff6", + "0xa36d4ae06688ece2927aeb2c7f058a3cd2aa1de1601282d4e688e1d76ef20728b892928deda2314eba41675eba3912f1", + "0xb8326dcbcdcfce017b263c456c47692fb476c4225c95981666fff0b7d4522fc23b7f12273f0f47cf0442662124e6648f", + "0x84c66463ab277cda2cc7007d0509269e89cdd41c5e0d3773a92615f0fc5da63811186b05d7a11088048a5d4834a7e0df", + "0xb20d3571d970712ef4699b0e7034fd269c361f53e1572e2ea2676b4245e992d43b8b5931a801439a44d977a988cc360b", + "0x94dba6007e6d4998ca1eb84aa8e2a7e9f5c164b9d80df2825f2208ce5640a05aacac2e4f08918268990f43ae1ccab69a", + "0xa1c25f0b3ef9d1982153207570d9ce8d692e1b6963b509958dc4d9bcd80074bb221c46804a6d9a29e76149cc7787c282", + "0x8857748fcdab1199fc96084323a81d3bd8b5a7f0b1abc5bc3b5252a19268344e2e7d2d086c90fc9b5fa4b92feedb93a4", + "0x8b9c1d841447354b6c086549e4d1d435ab64c13933488c34bc30f0f6eb36c5c5b838b7b6bb018542247edd1ada091045", + "0x8f5b655416da0e719a204fc567e93792c301acb4374cf7bbabc6ce51dbeaaadfd75c2db0e16ce073ab8e91fd3d7ea9d4", + "0x90f2846b19be46a75c5cd0cafefcf9192e6fd80c479e8d6320c4b8d8d7d96703c9e77ff31a67afa9858e6b7bde1f7cce", + "0xa53e383947fd98aa1a55ac956214b46b20a52758461e8ba41341a23a835ebb713038bf048edb1202bbfd0b56a96bf292", + "0x9542d7debbcfb9cda6fa279c699a7b655c03b9a9b456a5d3cfc41a826c94eafa43e01155a29e39ff0bcd965f4c0c512d", + "0xa43792864ec5fc549f7afc02622454afc0e425c310c4039ba615067243ebb26a4c7ebfd19bd4d57ff412a4bb2a7958a0", + "0xb85123950e30c048465bf32365d24a5d4b21fffc6183cdbf71643a07b87463989b72dd9a6a47f134856f704909a6b38f", + "0x944ea689aec1376f855c0bc9c51378ad06ff758a2c075b95a60b535b88b36eca0be11e4edb5152e98cb2137d6e749f27", + "0xa6bef52cda22325e4c62d323e2a0e3fa91c5552fcfce951edfd52ad6f652bfdcc2341f1cd349e6b5d447924dc569bfe2", + "0xb56bff8ffe981bfcb30791836da10b87f2ccbe17ed969e7f7a650af07d27ae0223805b1264d985148208483be50578a6", + "0x8b209cac898dd580c82d854a553e2517497ad1a4cd198e1360b8b50639b380aee70ee4b87625d9b2278228ff644cd25c", + "0x877cce233fec74c7158b3c5bf108365e98238418b8a71f058f1aca44a0fd3a1021e3e9025bd11fe244d9fe0f5034ce7f", + "0xb1b871aeedb03d6f6accc99816b89f5958178738d8d8cd9717527d04363c80fdb5f6848122ae19fdbc450cfa11e753c8", + "0x858aca51b9e5b0a724e88688d5124eb24c9faf01a3d465e74d31de6da315f311143f22f60201ea09f62c92f61f09d889", + "0x8521d409615dfc8c8289e00f6aaa6297c2c4e1439b25952afd76aac641b81c70b9cef07cd58c1c0198382bddd2bd8544", + "0x88647c3e41666b88acca42505f1f5da226937e0522b538fe0cebb724e9a99730ca2522989e94a96cac94109aef675c0f", + "0xb417fdaf719caf38854e89ce52031b30ce61a632e6c3135adec9002280e022d82ab0ea4ac5ebdb21f1f0169e4c37bcda", + "0x9367a6feb5e23ea2eab8ddd5e7bdf32b4d2419fad1c71a1ed327b77362d8942dad971a1c2e6f7073885149cdf0a0c339", + "0xa71c5c08d50c57d094d6a4f02e97d3799bada92f238ffc07bd223bbe8379507b7310d20b28f5bbbf331e5e153515e491", + "0x9630a9a3bcb044b51299c4d3d3388a4ff47308dd27be3229601985478c0f6b55faa7e20815d8694f910611396a9d0d45", + "0xb0bfaf56a5aa59b48960aa7c1617e832e65c823523fb2a5cd44ba606800501cf873e8db1d0dda64065285743dc40786e" + ] +} diff --git a/crates/kzg/src/trusted_setup.rs b/crates/kzg/src/trusted_setup.rs new file mode 100644 index 0000000..3978c06 --- /dev/null +++ b/crates/kzg/src/trusted_setup.rs @@ -0,0 +1,37 @@ +use crate::{KzgSettings, TrustedSetup}; + +use once_cell::sync::Lazy; + +pub(super) static KZG_SETTINGS: Lazy = Lazy::new(|| { + // Taken from the C KZG library: https://github.com/ethereum/c-kzg-4844/blob/main/src/trusted_setup.txt + const TRUSTED_SETUP: &[u8] = include_bytes!("trusted_setup.json"); + let setup: TrustedSetup = serde_json::from_slice(TRUSTED_SETUP).unwrap(); + KzgSettings::new_from_trusted_setup(setup) +}); + +#[cfg(test)] +mod tests { + use zkevm_circuits::eip_4844::input::ELEMENTS_PER_4844_BLOCK; + + use zkevm_circuits::boojum::pairing::{ + bls12_381::{Fr, FrRepr}, + ff::{Field as _, PrimeField as _}, + }; + + const FIRST_ROOT_OF_UNITY: FrRepr = FrRepr([ + 0xe206da11a5d36306, + 0x0ad1347b378fbf96, + 0xfc3e8acfe0f8245f, + 0x564c0a11a0f704f4, + ]); + + #[test] + fn kzg_roots_of_unity_are_correct() { + let mut value = Fr::from_repr(FIRST_ROOT_OF_UNITY).unwrap(); + for _ in 0..ELEMENTS_PER_4844_BLOCK.ilog2() { + assert_ne!(value, Fr::one()); + value.mul_assign(&value.clone()); + } + assert_eq!(value, Fr::one()); + } +} diff --git a/crates/zkEVM-assembly/.github/ISSUE_TEMPLATE/bug_report.md b/crates/zkEVM-assembly/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..2d3e38a --- /dev/null +++ b/crates/zkEVM-assembly/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,39 @@ +--- +name: Bug report +about: Use this template for reporting issues +title: '' +labels: bug +assignees: '' +--- + +### 🐛 Bug Report + +#### 📝 Description + +Provide a clear and concise description of the bug. + +#### 🔄 Reproduction Steps + +Steps to reproduce the behaviour + +#### 🤔 Expected Behavior + +Describe what you expected to happen. + +#### 😯 Current Behavior + +Describe what actually happened. + +#### 🖥️ Environment + +Any relevant environment details. + +#### 📋 Additional Context + +Add any other context about the problem here. If applicable, add screenshots to help explain. + +#### 📎 Log Output + +``` +Paste any relevant log output here. +``` diff --git a/crates/zkEVM-assembly/.github/ISSUE_TEMPLATE/feature_request.md b/crates/zkEVM-assembly/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..d921e06 --- /dev/null +++ b/crates/zkEVM-assembly/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,21 @@ +--- +name: Feature request +about: Use this template for requesting features +title: '' +labels: feat +assignees: '' +--- + +### 🌟 Feature Request + +#### 📝 Description + +Provide a clear and concise description of the feature you'd like to see. + +#### 🤔 Rationale + +Explain why this feature is important and how it benefits the project. + +#### 📋 Additional Context + +Add any other context or information about the feature request here. diff --git a/crates/zkEVM-assembly/.github/pull_request_template.md b/crates/zkEVM-assembly/.github/pull_request_template.md new file mode 100644 index 0000000..8ce206c --- /dev/null +++ b/crates/zkEVM-assembly/.github/pull_request_template.md @@ -0,0 +1,20 @@ +# What ❔ + + + + + +## Why ❔ + + + + +## Checklist + + + + +- [ ] PR title corresponds to the body of PR (we generate changelog entries from PRs). +- [ ] Tests for the changes have been added / updated. +- [ ] Documentation comments have been added / updated. +- [ ] Code has been formatted via `zk fmt` and `zk lint`. diff --git a/crates/zkEVM-assembly/.github/workflows/cargo-license.yaml b/crates/zkEVM-assembly/.github/workflows/cargo-license.yaml new file mode 100644 index 0000000..189b471 --- /dev/null +++ b/crates/zkEVM-assembly/.github/workflows/cargo-license.yaml @@ -0,0 +1,8 @@ +name: Cargo license check +on: pull_request +jobs: + cargo-deny: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: EmbarkStudios/cargo-deny-action@v1 diff --git a/crates/zkEVM-assembly/.github/workflows/ci.yaml b/crates/zkEVM-assembly/.github/workflows/ci.yaml new file mode 100644 index 0000000..8b2b519 --- /dev/null +++ b/crates/zkEVM-assembly/.github/workflows/ci.yaml @@ -0,0 +1,26 @@ +name: "Rust CI" +on: + pull_request: + +jobs: + build: + name: cargo build and test + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + toolchain: nightly-2023-04-17 + - run: cargo build --verbose --all-features + - run: RUSTFLAGS="-Awarnings" cargo test --verbose --all-features + + formatting: + name: cargo fmt + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + components: rustfmt + - name: Rustfmt Check + uses: actions-rust-lang/rustfmt@v1 diff --git a/crates/zkEVM-assembly/.github/workflows/secrets_scanner.yaml b/crates/zkEVM-assembly/.github/workflows/secrets_scanner.yaml new file mode 100644 index 0000000..54054cf --- /dev/null +++ b/crates/zkEVM-assembly/.github/workflows/secrets_scanner.yaml @@ -0,0 +1,17 @@ +name: Leaked Secrets Scan +on: [pull_request] +jobs: + TruffleHog: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3 + with: + fetch-depth: 0 + - name: TruffleHog OSS + uses: trufflesecurity/trufflehog@0c66d30c1f4075cee1aada2e1ab46dabb1b0071a + with: + path: ./ + base: ${{ github.event.repository.default_branch }} + head: HEAD + extra_args: --debug --only-verified diff --git a/crates/zkEVM-assembly/.gitignore b/crates/zkEVM-assembly/.gitignore new file mode 100644 index 0000000..14fb98b --- /dev/null +++ b/crates/zkEVM-assembly/.gitignore @@ -0,0 +1,15 @@ +# Generated by Cargo +# will have compiled files and executables +/target/ + +# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries +# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html +Cargo.lock + +# These are backup files generated by rustfmt +**/*.rs.bk + +# IDE project data +/.idea/ +/.vscode/ +/syncvm-common.iml diff --git a/crates/zkEVM-assembly/CONTRIBUTING.md b/crates/zkEVM-assembly/CONTRIBUTING.md new file mode 100644 index 0000000..f129e60 --- /dev/null +++ b/crates/zkEVM-assembly/CONTRIBUTING.md @@ -0,0 +1,9 @@ +# Contribution Guidelines + +Thank you for considering helping out with the source code! We are extremely grateful for any consideration of +contributions to this repository. However, at this time, we generally do not accept external contributions. This policy +will change in the future, so please check back regularly for updates. + +For security issues, please contact us at [security@matterlabs.dev](mailto:security@matterlabs.dev). + +Thank you for your support in accelerating the mass adoption of crypto for personal sovereignty! diff --git a/crates/zkEVM-assembly/Cargo.toml b/crates/zkEVM-assembly/Cargo.toml new file mode 100644 index 0000000..3866329 --- /dev/null +++ b/crates/zkEVM-assembly/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "zkevm-assembly" +version = "0.150.0" +authors = ["hedgar2017 "] +license = "MIT OR Apache-2.0" +edition = "2021" +description = "The zkEVM common utilities" +repository = "https://github.com/matter-labs/era-zkEVM-assembly" + +[[bin]] +name = "reader" +path = "src/reader/main.rs" + +[dependencies] +log = "0.4" +env_logger = "0.9" +structopt = { version = "0.3", default-features = false } +thiserror = "1.0" +nom = "7" +hex = "0.4" +sha3 = "0.10.8" +num-bigint = "0.4" +num-traits = "0.2" +lazy_static = "1.4" +zkevm_opcode_defs = { version = "=0.150.0", path = "../zkevm_opcode_defs" } +smallvec = "1.13" diff --git a/crates/zkEVM-assembly/LICENSE-APACHE b/crates/zkEVM-assembly/LICENSE-APACHE new file mode 100644 index 0000000..d9a10c0 --- /dev/null +++ b/crates/zkEVM-assembly/LICENSE-APACHE @@ -0,0 +1,176 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/crates/zkEVM-assembly/LICENSE-MIT b/crates/zkEVM-assembly/LICENSE-MIT new file mode 100644 index 0000000..2739ea6 --- /dev/null +++ b/crates/zkEVM-assembly/LICENSE-MIT @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Matter Labs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/crates/zkEVM-assembly/README.md b/crates/zkEVM-assembly/README.md new file mode 100644 index 0000000..9e24732 --- /dev/null +++ b/crates/zkEVM-assembly/README.md @@ -0,0 +1,34 @@ +# zkEVM Assembler + +[![Logo](eraLogo.png)](https://zksync.io/) + +zkSync 2.0 is a layer 2 rollup that uses zero-knowledge proofs to scale Ethereum without compromising on security or +decentralization. Since it's EVM compatible (Solidity/Vyper), 99% of Ethereum projects can redeploy without refactoring +or re-auditing a single line of code. zkSync 2.0 also uses an LLVM-based compiler that will eventually let developers +write smart contracts in C++, Rust and other popular languages. + +This repo contains the zkEVM assembly tools. + +## License + +The zkSync 2.0 prover is distributed under the terms of either + +- Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) +- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT) + +at your option. + +## Official Links + +- [Website](https://zksync.io/) +- [GitHub](https://github.com/matter-labs) +- [Twitter](https://twitter.com/zksync) +- [Twitter for Devs](https://twitter.com/zkSyncDevs) +- [Discord](https://join.zksync.dev/) + +## Disclaimer + +zkSync Era has been through lots of testing and audits. Although it is live, it is still in alpha state and will go +through more audits and bug bounties programs. We would love to hear our community's thoughts and suggestions about it! +It is important to state that forking it now can potentially lead to missing important security updates, critical +features, and performance improvements. diff --git a/crates/zkEVM-assembly/SECURITY.md b/crates/zkEVM-assembly/SECURITY.md new file mode 100644 index 0000000..2f2871c --- /dev/null +++ b/crates/zkEVM-assembly/SECURITY.md @@ -0,0 +1,74 @@ +# Security Policy + +We truly appreciate efforts to discover and disclose security issues responsibly! + +## Vulnerabilities + +If you'd like to report a security issue in the repositories of matter-labs organization, please proceed to our +[Bug Bounty Program on Immunefi](https://era.zksync.io/docs/reference/troubleshooting/audit-bug-bounty.html#bug-bounty-program). + +## Other Security Issues + +We take an impact-first approach instead of a rules-first approach. Therefore, if you believe you found the impactful +issue but can't report it via the Bug Bounty, please email us at +[security@matterlabs.dev](mailto:security@matterlabs.dev). + +### PGP Key + +The following PGP key may be used to communicate sensitive information to developers: + +Fingerprint: `5FED B2D0 EA2C 4906 DD66 71D7 A2C5 0B40 CE3C F297` + +``` +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +=xkM3 +-----END PGP PUBLIC KEY BLOCK----- +``` diff --git a/crates/zkEVM-assembly/assemble.sh b/crates/zkEVM-assembly/assemble.sh new file mode 100755 index 0000000..956e977 --- /dev/null +++ b/crates/zkEVM-assembly/assemble.sh @@ -0,0 +1,5 @@ +#!/bin/bash -Cex + +for file in ~/src/llvm-project/llvm/test/CodeGen/SyncVM/*.ll; do + ~/opt/llvm/bin/llc "${file}" -o "examples/$(basename ${file} .ll).sasm" +done diff --git a/crates/zkEVM-assembly/deny.toml b/crates/zkEVM-assembly/deny.toml new file mode 100644 index 0000000..1ee7ccc --- /dev/null +++ b/crates/zkEVM-assembly/deny.toml @@ -0,0 +1,78 @@ +all-features = false +no-default-features = false + +[advisories] +vulnerability = "deny" +unmaintained = "warn" +yanked = "warn" +notice = "warn" +ignore = [ + #"RUSTSEC-0000-0000", +] + +[licenses] +unlicensed = "deny" +allow = [ + #"Apache-2.0 WITH LLVM-exception", + "MIT", + "Apache-2.0", + "ISC", + "Unlicense", + "MPL-2.0", + "Unicode-DFS-2016", + "CC0-1.0", + "BSD-2-Clause", + "BSD-3-Clause", +] +deny = [ + #"Nokia", +] +copyleft = "warn" +allow-osi-fsf-free = "neither" +default = "deny" +confidence-threshold = 0.8 +exceptions = [ + # Each entry is the crate and version constraint, and its specific allow + # list + #{ allow = ["Zlib"], name = "adler32", version = "*" }, +] + +unused-allowed-license = "allow" + +[licenses.private] +ignore = false +registries = [ + #"https://sekretz.com/registry +] + +[bans] +multiple-versions = "warn" +wildcards = "allow" +highlight = "all" +workspace-default-features = "allow" +external-default-features = "allow" +allow = [ + #{ name = "ansi_term", version = "=0.11.0" }, +] +# List of crates to deny +deny = [ + # Each entry the name of a crate and a version range. If version is + # not specified, all versions will be matched. + #{ name = "ansi_term", version = "=0.11.0" }, +] + +skip = [ + #{ name = "ansi_term", version = "=0.11.0" }, +] +skip-tree = [ + #{ name = "ansi_term", version = "=0.11.0", depth = 20 }, +] + +[sources] +unknown-registry = "deny" +unknown-git = "allow" +allow-registry = ["https://github.com/rust-lang/crates.io-index"] +allow-git = [] + +[sources.allow-org] +#github = ["matter-labs"] diff --git a/crates/zkEVM-assembly/eraLogo.png b/crates/zkEVM-assembly/eraLogo.png new file mode 100644 index 0000000000000000000000000000000000000000..5d9480d8f05342a06cd1ee03405137552bdbebbf GIT binary patch literal 79091 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, +} + +#[derive(Clone, Debug)] +pub enum ConstantValue { + Cell([u8; 32]), + Signed(BigInt, usize), + Unsigned(BigUint, usize), + ByteArray(Vec), +} + +impl ConstantValue { + pub fn serialize(self) -> [u8; 32] { + match self { + ConstantValue::Cell(res) => res, + _ => todo!(), + } + } + + pub fn is_empty(&self) -> bool { + match self { + ConstantValue::Cell(res) => res.iter().all(|el| *el == 0), + _ => todo!(), + } + } +} diff --git a/crates/zkEVM-assembly/src/assembly/instruction/add.rs b/crates/zkEVM-assembly/src/assembly/instruction/add.rs new file mode 100644 index 0000000..2dac5c8 --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/instruction/add.rs @@ -0,0 +1,119 @@ +//! +//! The arithmetic addition instruction. +//! + +use super::*; +use crate::assembly::operand::{FullOperand, RegisterOperand}; +use crate::error::InstructionReadError; +use std::collections::HashMap; +use std::convert::TryFrom; + +/// +/// The arithmetic addition instruction. +/// +#[derive(Debug, Clone, PartialEq)] +pub struct Add { + /// Condition for execution + pub condition: ConditionCase, + /// Whether we set flags or not + pub set_flags_option: SetFlags, + /// The first operand. + pub source_1: FullOperand, + /// The second operand. + pub source_2: RegisterOperand, + /// The destination operand. + pub destination: FullOperand, +} + +impl Add { + // Total number of arguments in canonical form + pub const NUM_ARGUMENTS: usize = 3; + + #[track_caller] + pub fn build_from_parts( + mut modifiers: HashSet<&str>, + operands: Vec<&str>, + ) -> Result { + let operands = if let Ok(operands) = parse_canonical_operands_sequence( + operands.clone(), + &[marker_full_operand(), marker_register_operand()], + &[marker_full_operand()], + ) { + operands + } else { + // try loading label + parse_canonical_operands_sequence( + operands, + &[OperandType::Label, marker_register_operand()], + &[marker_full_operand()], + )? + }; + + let src0 = operands[0].clone(); + let src1 = operands[1].clone(); + let dst0 = operands[2].clone(); + + let condition = pick_condition(&mut modifiers)?; + let set_flags_option = pick_setting_flags(&mut modifiers)?; + + if !modifiers.is_empty() { + return Err(InstructionReadError::UnknownArgument(format!( + "Add instruction contains unknown modifiers: {:?}", + modifiers + ))); + } + + let new = Self { + condition, + source_1: src0, + source_2: src1.as_register_operand(1)?, + destination: dst0, + set_flags_option, + }; + + Ok(new) + } + + #[track_caller] + pub(crate) fn link>( + &mut self, + function_labels_to_pc: &HashMap, + constant_labels_to_offset: &HashMap, + globals_to_offsets: &HashMap, + ) -> Result<(), AssemblyParseError> { + link_operand::( + &mut self.source_1, + function_labels_to_pc, + constant_labels_to_offset, + globals_to_offsets, + )?; + + link_operand::( + &mut self.destination, + function_labels_to_pc, + constant_labels_to_offset, + globals_to_offsets, + )?; + + Ok(()) + } +} + +impl> TryFrom for DecodedOpcode { + type Error = InstructionReadError; + + fn try_from(value: Add) -> Result { + let mut new = DecodedOpcode::default(); + new.variant = OpcodeVariant { + opcode: Opcode::Add(AddOpcode::Add), + ..OpcodeVariant::default() + }; + set_src0_or_dst0_full_operand(&value.source_1.as_generic_operand(0)?, &mut new, false); + set_register_operand(&value.source_2, &mut new, false); + set_src0_or_dst0_full_operand(&value.destination.as_generic_operand(2)?, &mut new, true); + new.condition = value.condition.0; + new.variant.flags[SET_FLAGS_FLAG_IDX] = value.set_flags_option.0; + + Ok(new) + } +} diff --git a/crates/zkEVM-assembly/src/assembly/instruction/bitwise.rs b/crates/zkEVM-assembly/src/assembly/instruction/bitwise.rs new file mode 100644 index 0000000..7b9d236 --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/instruction/bitwise.rs @@ -0,0 +1,137 @@ +use super::*; + +#[derive(Debug, Clone, PartialEq)] +pub struct Bitwise { + /// Condition for execution + pub condition: ConditionCase, + /// Whether we set flags or not + pub set_flags_option: SetFlags, + /// The first operand. + pub source_1: FullOperand, + /// The second operand. + pub source_2: RegisterOperand, + /// The destination register. + pub destination: FullOperand, + /// And, Or or Xor + pub op_type: BinopOpcode, +} + +impl Bitwise { + pub const ALL_CANONICAL_MODIFIERS: [&'static str; 3] = ["xor", "and", "or"]; + + #[track_caller] + pub fn build_from_parts( + mut modifiers: HashSet<&str>, + operands: Vec<&str>, + ) -> Result { + let operands = parse_canonical_operands_sequence( + operands, + &[marker_full_operand(), marker_register_operand()], + &[marker_full_operand()], + )?; + + let src0 = operands[0].clone(); + let src1 = operands[1].clone(); + let dst0 = operands[2].clone(); + + if modifiers.is_empty() { + return Err(InstructionReadError::InvalidArgument { + index: 0, + expected: "Binop opcode must contain a modifier", + found: "no modifiers".to_owned(), + }); + } + + let mut result = None; + for (idx, modifier) in Self::ALL_CANONICAL_MODIFIERS.iter().enumerate() { + if modifiers.contains(modifier) { + if result.is_some() { + return Err(InstructionReadError::UnknownArgument(format!( + "duplicate variant in modifiers: already have {:?}, got {}", + result.unwrap(), + modifier + ))); + } else { + modifiers.remove(modifier); + let variant = match idx { + 0 => BinopOpcode::Xor, + 1 => BinopOpcode::And, + 2 => BinopOpcode::Or, + _ => { + unreachable!() + } + }; + result = Some(variant); + } + } + } + + let variant = result.ok_or(InstructionReadError::UnknownArgument( + "Binop instruction contains no modifier".to_owned(), + ))?; + + let condition = pick_condition(&mut modifiers)?; + let set_flags_option = pick_setting_flags(&mut modifiers)?; + + if !modifiers.is_empty() { + return Err(InstructionReadError::UnknownArgument(format!( + "Binop instruction contains unknown modifiers: {:?}", + modifiers + ))); + } + + let new = Self { + condition, + source_1: src0, + source_2: src1.as_register_operand(1)?, + destination: dst0, + op_type: variant, + set_flags_option, + }; + + Ok(new) + } + + #[track_caller] + pub(crate) fn link>( + &mut self, + function_labels_to_pc: &HashMap, + constant_labels_to_offset: &HashMap, + globals_to_offsets: &HashMap, + ) -> Result<(), AssemblyParseError> { + link_operand::( + &mut self.source_1, + function_labels_to_pc, + constant_labels_to_offset, + globals_to_offsets, + )?; + + link_operand::( + &mut self.destination, + function_labels_to_pc, + constant_labels_to_offset, + globals_to_offsets, + )?; + + Ok(()) + } +} + +impl> TryFrom for DecodedOpcode { + type Error = InstructionReadError; + + fn try_from(value: Bitwise) -> Result { + let mut new = DecodedOpcode::default(); + new.variant = OpcodeVariant { + opcode: Opcode::Binop(value.op_type), + ..OpcodeVariant::default() + }; + set_src0_or_dst0_full_operand(&value.source_1.as_generic_operand(0)?, &mut new, false); + set_register_operand(&value.source_2, &mut new, false); + set_src0_or_dst0_full_operand(&value.destination.as_generic_operand(2)?, &mut new, true); + new.condition = value.condition.0; + new.variant.flags[SET_FLAGS_FLAG_IDX] = value.set_flags_option.0; + + Ok(new) + } +} diff --git a/crates/zkEVM-assembly/src/assembly/instruction/condition.rs b/crates/zkEVM-assembly/src/assembly/instruction/condition.rs new file mode 100644 index 0000000..c6bcfad --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/instruction/condition.rs @@ -0,0 +1,37 @@ +//! +//! Condition to apply the operation +//! + +use crate::InstructionReadError; +use zkevm_opcode_defs::Condition; + +/// +/// The control flow jump instruction flag. +/// +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct ConditionCase(pub(crate) Condition); + +impl std::default::Default for ConditionCase { + fn default() -> Self { + ConditionCase(Condition::Always) + } +} + +impl ConditionCase { + pub const ALL_CANONICAL_MODIFIERS: [&'static str; 8] = + ["gt", "lt", "eq", "ge", "le", "ne", "gtlt", "of"]; + + pub fn from_modifier(modifier: &str) -> Result { + match modifier { + m if m == Self::ALL_CANONICAL_MODIFIERS[0] => Ok(ConditionCase(Condition::Gt)), + m if m == Self::ALL_CANONICAL_MODIFIERS[1] => Ok(ConditionCase(Condition::Lt)), + m if m == Self::ALL_CANONICAL_MODIFIERS[2] => Ok(ConditionCase(Condition::Eq)), + m if m == Self::ALL_CANONICAL_MODIFIERS[3] => Ok(ConditionCase(Condition::Ge)), + m if m == Self::ALL_CANONICAL_MODIFIERS[4] => Ok(ConditionCase(Condition::Le)), + m if m == Self::ALL_CANONICAL_MODIFIERS[5] => Ok(ConditionCase(Condition::Ne)), + m if m == Self::ALL_CANONICAL_MODIFIERS[6] => Ok(ConditionCase(Condition::GtOrLt)), + m if m == Self::ALL_CANONICAL_MODIFIERS[7] => Ok(ConditionCase(Condition::Lt)), + _ => Err(InstructionReadError::UnknownArgument(modifier.to_owned())), + } + } +} diff --git a/crates/zkEVM-assembly/src/assembly/instruction/context.rs b/crates/zkEVM-assembly/src/assembly/instruction/context.rs new file mode 100644 index 0000000..cc796e2 --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/instruction/context.rs @@ -0,0 +1,173 @@ +//! +//! Read value from execution context. +//! + +use super::*; + +use crate::error::InstructionReadError; +use std::collections::HashMap; +use std::convert::TryFrom; + +/// +/// Read value from execution context. +/// +#[derive(Debug, Clone, PartialEq)] +pub struct Context { + /// Condition for execution + pub condition: ConditionCase, + /// The formal source location + pub source_location: RegisterOperand, + /// The formal destination location + pub destination_location: RegisterOperand, + /// Information to get + pub field: ContextOpcode, +} + +impl Context { + // must follow in the same sequence as variants of the opcode + pub const ALL_CANONICAL_MODIFIERS: [&'static str; 10] = [ + "this", + "caller", + "code_source", + "meta", + "ergs_left", + "sp", + "get_context_u128", + "set_context_u128", + "set_ergs_per_pubdata", + "inc_tx_num", + ]; + + #[track_caller] + pub fn build_from_parts( + mut modifiers: HashSet<&str>, + operands: Vec<&str>, + ) -> Result { + // since we are interested in register only, we parse as-is, but later on deside how to use it + + if modifiers.is_empty() { + return Err(InstructionReadError::InvalidArgument { + index: 0, + expected: "context opcode must containt a modifier", + found: "no modifiers".to_owned(), + }); + } + + let mut result = None; + for (idx, modifier) in Self::ALL_CANONICAL_MODIFIERS.iter().enumerate() { + if modifiers.contains(modifier) { + if result.is_some() { + return Err(InstructionReadError::UnknownArgument(format!( + "duplicate variant in modifiers: already have {:?}, got {}", + result.unwrap(), + modifier + ))); + } else { + modifiers.remove(modifier); + let variant = match idx { + i if i == ContextOpcode::This.variant_index() => ContextOpcode::This, + i if i == ContextOpcode::Caller.variant_index() => ContextOpcode::Caller, + i if i == ContextOpcode::CodeAddress.variant_index() => { + ContextOpcode::CodeAddress + } + i if i == ContextOpcode::Meta.variant_index() => ContextOpcode::Meta, + i if i == ContextOpcode::ErgsLeft.variant_index() => { + ContextOpcode::ErgsLeft + } + i if i == ContextOpcode::Sp.variant_index() => ContextOpcode::Sp, + i if i == ContextOpcode::GetContextU128.variant_index() => { + ContextOpcode::GetContextU128 + } + i if i == ContextOpcode::SetContextU128.variant_index() => { + ContextOpcode::SetContextU128 + } + i if i == ContextOpcode::AuxMutating0.variant_index() => { + ContextOpcode::AuxMutating0 + } + i if i == ContextOpcode::IncrementTxNumber.variant_index() => { + ContextOpcode::IncrementTxNumber + } + _ => { + unreachable!() + } + }; + result = Some(variant); + } + } + } + + let variant = result.ok_or(InstructionReadError::UnknownArgument( + "Context instruction contains no modifier".to_owned(), + ))?; + + let condition = pick_condition(&mut modifiers)?; + + if !modifiers.is_empty() { + return Err(InstructionReadError::UnknownArgument(format!( + "Context instruction contains unknown modifiers: {:?}", + modifiers + ))); + } + + let (source_location, destination_location) = match variant { + ContextOpcode::SetContextU128 | ContextOpcode::AuxMutating0 => { + let operands = + parse_canonical_operands_sequence(operands, &[], &[marker_register_operand()])?; + + let location = operands[0].clone(); + let src = location.as_register_operand(0)?; + + (src, RegisterOperand::Null) + } + ContextOpcode::IncrementTxNumber => { + let _operands = parse_canonical_operands_sequence(operands, &[], &[])?; + + (RegisterOperand::Null, RegisterOperand::Null) + } + _ => { + let operands = + parse_canonical_operands_sequence(operands, &[marker_register_operand()], &[])?; + + let location = operands[0].clone(); + let dst = location.as_register_operand(0)?; + + (RegisterOperand::Null, dst) + } + }; + + let new = Self { + condition, + source_location, + destination_location, + field: variant, + }; + + Ok(new) + } + + #[track_caller] + pub(crate) fn link>( + &mut self, + _function_labels_to_pc: &HashMap, + _constant_labels_to_offset: &HashMap, + _globals_to_offsets: &HashMap, + ) -> Result<(), AssemblyParseError> { + Ok(()) + } +} + +impl> TryFrom for DecodedOpcode { + type Error = InstructionReadError; + fn try_from(value: Context) -> Result { + let mut new = DecodedOpcode::default(); + new.variant = OpcodeVariant { + opcode: Opcode::Context(value.field), + ..OpcodeVariant::default() + }; + set_src0_or_dst0_register_operand(&value.source_location, &mut new, false); + set_src0_or_dst0_register_operand(&value.destination_location, &mut new, true); + new.condition = value.condition.0; + + Ok(new) + } +} diff --git a/crates/zkEVM-assembly/src/assembly/instruction/div.rs b/crates/zkEVM-assembly/src/assembly/instruction/div.rs new file mode 100644 index 0000000..2049f1f --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/instruction/div.rs @@ -0,0 +1,125 @@ +//! +//! The arithmetic division or remainder instruction. +//! + +use super::*; +use crate::error::InstructionReadError; +use std::collections::HashMap; +use std::convert::TryFrom; + +/// +/// The arithmetic division or remainder instruction. +/// +#[derive(Debug, Clone, PartialEq)] +pub struct Div { + /// Condition for execution + pub condition: ConditionCase, + /// Whether we set flags or not + pub set_flags_option: SetFlags, + /// The first source operand. + pub source_1: FullOperand, + /// The second source register. + pub source_2: RegisterOperand, + /// The quotient destination register. + pub quotient_destination: FullOperand, + /// The remainder destination register. + pub remainder_destination: RegisterOperand, + /// if it is set then source operands have be swapped. + pub swap_operands: bool, +} + +impl Div { + // Total number of arguments in canonical form + pub const NUM_ARGUMENTS: usize = 4; + + pub fn build_from_parts( + mut modifiers: HashSet<&str>, + operands: Vec<&str>, + ) -> Result { + let operands = parse_canonical_operands_sequence( + operands, + &[marker_full_operand(), marker_register_operand()], + &[marker_full_operand(), marker_register_operand()], + )?; + + let src0 = operands[0].clone(); + let src1 = operands[1].clone(); + let dst0 = operands[2].clone(); + let dst1 = operands[3].clone(); + + let condition = pick_condition(&mut modifiers)?; + let set_flags_option = pick_setting_flags(&mut modifiers)?; + + let mut swap_operands = false; + if modifiers.remove("s") { + swap_operands = true; + } + + if !modifiers.is_empty() { + return Err(InstructionReadError::UnknownArgument(format!( + "Div instruction contains unknown modifiers: {:?}", + modifiers + ))); + } + + let new = Self { + condition, + set_flags_option, + source_1: src0, + source_2: src1.as_register_operand(1)?, + quotient_destination: dst0, + remainder_destination: dst1.as_register_operand(3)?, + swap_operands, + }; + + Ok(new) + } + + #[track_caller] + pub(crate) fn link>( + &mut self, + function_labels_to_pc: &HashMap, + constant_labels_to_offset: &HashMap, + globals_to_offsets: &HashMap, + ) -> Result<(), AssemblyParseError> { + link_operand::( + &mut self.source_1, + function_labels_to_pc, + constant_labels_to_offset, + globals_to_offsets, + )?; + + link_operand::( + &mut self.quotient_destination, + function_labels_to_pc, + constant_labels_to_offset, + globals_to_offsets, + )?; + + Ok(()) + } +} + +impl> TryFrom

for DecodedOpcode { + type Error = InstructionReadError; + fn try_from(value: Div) -> Result { + let mut new = DecodedOpcode::default(); + new.variant = OpcodeVariant { + opcode: Opcode::Div(DivOpcode), + ..OpcodeVariant::default() + }; + set_src0_or_dst0_full_operand(&value.source_1.as_generic_operand(0)?, &mut new, false); + set_register_operand(&value.source_2, &mut new, false); + set_src0_or_dst0_full_operand( + &value.quotient_destination.as_generic_operand(2)?, + &mut new, + true, + ); + set_register_operand(&value.remainder_destination, &mut new, true); + new.condition = value.condition.0; + new.variant.flags[SET_FLAGS_FLAG_IDX] = value.set_flags_option.0; + new.variant.flags[SWAP_OPERANDS_FLAG_IDX_FOR_ARITH_OPCODES] = value.swap_operands; + + Ok(new) + } +} diff --git a/crates/zkEVM-assembly/src/assembly/instruction/far_call.rs b/crates/zkEVM-assembly/src/assembly/instruction/far_call.rs new file mode 100644 index 0000000..2c49a98 --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/instruction/far_call.rs @@ -0,0 +1,152 @@ +//! +//! The control flow jump instruction. +//! + +use super::*; + +use crate::error::InstructionReadError; +use std::convert::TryFrom; + +/// +/// The control flow jump instruction. +/// +#[derive(Debug, Clone, PartialEq)] +pub struct FarCall { + /// Condition for execution + pub condition: ConditionCase, + /// Called address parameter + pub source_for_address_to_call: RegisterOperand, + /// Ergs parameter + pub source_for_meta_args: RegisterOperand, + /// Exception handler + pub exception_handler: FullOperand, + /// Call variant + pub variant: FarCallOpcode, + /// Perform a call under static context restrictions + pub is_static: bool, + /// Perform a call to another shard + pub is_call_shard: bool, +} + +impl FarCall { + pub const ALL_CANONICAL_MODIFIERS: [&'static str; 2] = ["delegate", "mimic"]; + + // Total number of arguments in canonical form + pub const NUM_ARGUMENTS: usize = 3; + + #[track_caller] + pub fn build_from_parts( + mut modifiers: HashSet<&str>, + operands: Vec<&str>, + ) -> Result { + let operands = parse_canonical_operands_sequence( + operands, + &[ + marker_register_operand(), + marker_register_operand(), + OperandType::Label, + ], + &[], + )?; + + let src0 = operands[0].clone().as_register_operand(0)?; + let src1 = operands[1].clone().as_register_operand(1)?; + + let is_static = modifiers.remove("static"); + + let is_call_shard = modifiers.remove("shard"); + + let condition = pick_condition(&mut modifiers)?; + + let mut result = None; + for (idx, modifier) in Self::ALL_CANONICAL_MODIFIERS.iter().enumerate() { + if modifiers.contains(modifier) { + if result.is_some() { + return Err(InstructionReadError::UnknownArgument(format!( + "duplicate variant in modifiers: already have {:?}, got {}", + result.unwrap(), + modifier + ))); + } else { + modifiers.remove(modifier); + let variant = match idx { + 0 => FarCallOpcode::Delegate, + 1 => FarCallOpcode::Mimic, + _ => unreachable!(), + }; + result = Some(variant); + } + } + } + if !modifiers.is_empty() { + return Err(InstructionReadError::UnknownArgument(format!( + "{:?}", + modifiers + ))); + } + + if result.is_none() { + // our default behavior + result = Some(FarCallOpcode::Normal); + } + + let variant = result.ok_or(InstructionReadError::UnknownArgument( + "Far Call instruction contains no modifier".to_owned(), + ))?; + + let exception_handler = operands[2].clone(); + + let new = Self { + condition, + source_for_address_to_call: src0, + source_for_meta_args: src1, + exception_handler, + variant, + is_static, + is_call_shard, + }; + + Ok(new) + } + + #[track_caller] + pub(crate) fn link>( + &mut self, + function_labels_to_pc: &HashMap, + constant_labels_to_offset: &HashMap, + globals_to_offsets: &HashMap, + ) -> Result<(), AssemblyParseError> { + link_operand::( + &mut self.exception_handler, + function_labels_to_pc, + constant_labels_to_offset, + globals_to_offsets, + )?; + + Ok(()) + } +} + +impl> TryFrom for DecodedOpcode { + type Error = InstructionReadError; + fn try_from(value: FarCall) -> Result { + let mut new = DecodedOpcode::default(); + new.variant = OpcodeVariant { + opcode: Opcode::FarCall(value.variant), + ..OpcodeVariant::default() + }; + set_src0_or_dst0_register_operand(&value.source_for_address_to_call, &mut new, false); + set_register_operand(&value.source_for_meta_args, &mut new, false); + new.condition = value.condition.0; + new.variant.flags[FAR_CALL_STATIC_FLAG_IDX] = value.is_static; + new.variant.flags[FAR_CALL_SHARD_FLAG_IDX] = value.is_call_shard; + new.imm_0 = E::PcOrImm::from_u64_clipped( + value + .exception_handler + .as_generic_operand(2)? + .as_pc_offset(), + ); + + Ok(new) + } +} diff --git a/crates/zkEVM-assembly/src/assembly/instruction/invalid.rs b/crates/zkEVM-assembly/src/assembly/instruction/invalid.rs new file mode 100644 index 0000000..9ddffcc --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/instruction/invalid.rs @@ -0,0 +1,60 @@ +//! +//! The Invalid instruction +//! + +use super::*; + +/// +/// The INVALID instruction. It's puspose is some +/// form of penalty, e.g. calling page number 0, or something +/// similar +/// +#[derive(Debug, Clone, PartialEq)] +pub struct Invalid { + /// Condition for execution + pub condition: ConditionCase, +} + +impl Invalid { + #[track_caller] + pub fn build_from_parts( + mut modifiers: HashSet<&str>, + operands: Vec<&str>, + ) -> Result { + let _operands = parse_canonical_operands_sequence(operands, &[], &[])?; + + let condition = pick_condition(&mut modifiers)?; + + if !modifiers.is_empty() { + return Err(InstructionReadError::UnknownArgument(format!( + "Invalid instruction contains unknown modifiers: {:?}", + modifiers + ))); + } + + let new = Self { condition }; + + Ok(new) + } + + #[track_caller] + pub(crate) fn link>( + &mut self, + _function_labels_to_pc: &HashMap, + _constant_labels_to_offset: &HashMap, + _globals_to_offsets: &HashMap, + ) -> Result<(), AssemblyParseError> { + Ok(()) + } +} + +impl> TryFrom for DecodedOpcode { + type Error = InstructionReadError; + fn try_from(value: Invalid) -> Result { + let mut new = DecodedOpcode::default(); + new.variant = zkevm_opcode_defs::INVALID_OPCODE_VARIANT; + new.condition = value.condition.0; + + Ok(new) + } +} diff --git a/crates/zkEVM-assembly/src/assembly/instruction/jump.rs b/crates/zkEVM-assembly/src/assembly/instruction/jump.rs new file mode 100644 index 0000000..e5f61d4 --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/instruction/jump.rs @@ -0,0 +1,98 @@ +//! +//! The control flow jump instruction. +//! + +use super::*; + +use crate::error::InstructionReadError; + +use std::convert::TryFrom; + +/// +/// The control flow jump instruction. +/// +#[derive(Debug, Clone, PartialEq)] +pub struct Jump { + /// Condition for execution + pub condition: ConditionCase, + /// The `true` condition destination bytecode address. + /// We use full operand here, so we can properly link later on + pub destination_true: FullOperand, +} + +impl Jump { + // Total number of arguments in canonical form + pub const NUM_ARGUMENTS: usize = 1; + + #[track_caller] + pub fn build_from_parts( + mut modifiers: HashSet<&str>, + operands: Vec<&str>, + ) -> Result { + // for convenience we accept both + // "jump @LABEL" + // and + // "jump rX" + let operands = if let Ok(operands) = + parse_canonical_operands_sequence(operands.clone(), &[marker_full_operand()], &[]) + { + operands + } else { + parse_canonical_operands_sequence(operands, &[OperandType::Label], &[])? + }; + + let dst_true = operands[0].clone(); + + let condition = pick_condition(&mut modifiers)?; + + let new = Self { + condition, + destination_true: dst_true, + }; + + if !modifiers.is_empty() { + return Err(InstructionReadError::UnknownArgument(format!( + "Jump instruction contains unknown modifiers: {:?}", + modifiers + ))); + } + + Ok(new) + } + + #[track_caller] + pub(crate) fn link>( + &mut self, + function_labels_to_pc: &HashMap, + constant_labels_to_offset: &HashMap, + globals_to_offsets: &HashMap, + ) -> Result<(), AssemblyParseError> { + link_operand::( + &mut self.destination_true, + function_labels_to_pc, + constant_labels_to_offset, + globals_to_offsets, + )?; + + Ok(()) + } +} + +impl> TryFrom for DecodedOpcode { + type Error = InstructionReadError; + fn try_from(value: Jump) -> Result { + let mut new = DecodedOpcode::default(); + new.variant = OpcodeVariant { + opcode: Opcode::Jump(JumpOpcode), + ..OpcodeVariant::default() + }; + new.condition = value.condition.0; + set_src0_or_dst0_full_operand( + &value.destination_true.as_generic_operand(0)?, + &mut new, + false, + ); + + Ok(new) + } +} diff --git a/crates/zkEVM-assembly/src/assembly/instruction/log.rs b/crates/zkEVM-assembly/src/assembly/instruction/log.rs new file mode 100644 index 0000000..6a6adc1 --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/instruction/log.rs @@ -0,0 +1,144 @@ +//! +//! Read value from execution context. +//! + +use super::*; + +use crate::error::InstructionReadError; +use std::collections::HashMap; +use std::convert::TryFrom; + +/// +/// Read value from execution context. +/// +#[derive(Debug, Clone, PartialEq)] +pub struct Log { + /// Condition for execution + pub condition: ConditionCase, + /// Source register for key + pub key: RegisterOperand, + /// Source register for value on write + pub value_source: RegisterOperand, + /// The destination register for value on read + pub value_destination: RegisterOperand, + /// Type of log + pub log_type: LogOpcode, + /// Indicator of the initial message + pub is_initial: bool, +} + +impl Log { + pub const ALL_CANONICAL_MODIFIERS: [&'static str; 8] = [ + "sread", + "swrite", + "event", + "to_l1", + "precompile", + "decommit", + "tread", + "twrite", + ]; + + #[track_caller] + pub fn build_from_parts( + mut modifiers: HashSet<&str>, + operands: Vec<&str>, + ) -> Result { + let operands = parse_canonical_operands_sequence( + operands, + &[marker_register_operand(), marker_register_operand()], + &[marker_register_operand()], + )?; + + let is_initial = modifiers.remove("first"); + + if modifiers.is_empty() { + return Err(InstructionReadError::InvalidArgument { + index: 0, + expected: "Log opcode must contain a type modifier", + found: "no modifiers".to_owned(), + }); + } + + let condition = pick_condition(&mut modifiers)?; + + let mut result = None; + for (idx, modifier) in Self::ALL_CANONICAL_MODIFIERS.iter().enumerate() { + if modifiers.contains(modifier) { + if result.is_some() { + return Err(InstructionReadError::UnknownArgument(format!( + "Log opcode: duplicate variant in modifiers: already have {:?}, got {}", + result.unwrap(), + modifier + ))); + } else { + modifiers.remove(modifier); + let variant = match idx { + 0 => LogOpcode::StorageRead, + 1 => LogOpcode::StorageWrite, + 2 => LogOpcode::Event, + 3 => LogOpcode::ToL1Message, + 4 => LogOpcode::PrecompileCall, + 5 => LogOpcode::Decommit, + 6 => LogOpcode::TransientStorageRead, + 7 => LogOpcode::TransientStorageWrite, + _ => { + unreachable!() + } + }; + result = Some(variant); + } + } + } + + let variant = result.ok_or(InstructionReadError::UnknownArgument( + "Log instruction contains no modifier".to_owned(), + ))?; + + if !modifiers.is_empty() { + return Err(InstructionReadError::UnknownArgument(format!( + "Log instruction contains unknown modifiers: {:?}", + modifiers + ))); + } + + let new = Self { + condition, + key: operands[0].clone().as_register_operand(0)?, + value_source: operands[1].clone().as_register_operand(1)?, + value_destination: operands[2].clone().as_register_operand(2)?, + log_type: variant, + is_initial, + }; + + Ok(new) + } + + #[track_caller] + pub(crate) fn link>( + &mut self, + _function_labels_to_pc: &HashMap, + _constant_labels_to_offset: &HashMap, + _globals_to_offsets: &HashMap, + ) -> Result<(), AssemblyParseError> { + Ok(()) + } +} + +impl> TryFrom for DecodedOpcode { + type Error = InstructionReadError; + fn try_from(value: Log) -> Result { + let mut new = DecodedOpcode::default(); + new.variant = OpcodeVariant { + opcode: Opcode::Log(value.log_type), + ..OpcodeVariant::default() + }; + set_src0_or_dst0_register_operand(&value.key, &mut new, false); + set_register_operand(&value.value_source, &mut new, false); + set_src0_or_dst0_register_operand(&value.value_destination, &mut new, true); + new.condition = value.condition.0; + new.variant.flags[0] = value.is_initial; + + Ok(new) + } +} diff --git a/crates/zkEVM-assembly/src/assembly/instruction/mod.rs b/crates/zkEVM-assembly/src/assembly/instruction/mod.rs new file mode 100644 index 0000000..63c5fb2 --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/instruction/mod.rs @@ -0,0 +1,463 @@ +//! +//! The instruction. +//! + +use crate::{assembly::operand::*, AssemblyParseError}; +// use crate::assembly::*; +use crate::assembly::parse::code_element::*; +use crate::error::InstructionReadError; +use zkevm_opcode_defs::decoding::VmEncodingMode; +use zkevm_opcode_defs::*; + +use self::add::Add; +use self::bitwise::Bitwise; +use self::condition::ConditionCase; +use self::context::Context; +use self::div::Div; +use self::far_call::FarCall; +use self::invalid::Invalid; +use self::jump::Jump; +use self::log::Log; +use self::mul::Mul; +use self::near_call::NearCall; +use self::nop::Nop; +use self::ptr::Ptr; +use self::ret::Ret; +use self::set_flags::SetFlags; +use self::shift::Shift; +use self::sub::Sub; +use self::uma::UMA; + +use self::utils::*; + +use std::collections::{HashMap, HashSet}; +use zkevm_opcode_defs::decoding::AllowedPcOrImm; + +pub mod add; +pub mod bitwise; +pub mod condition; +pub mod context; +pub mod div; +pub mod far_call; +pub mod invalid; +pub mod jump; +pub mod log; +pub mod mul; +pub mod near_call; +pub mod nop; +pub mod ptr; +pub mod ret; +pub mod set_flags; +pub mod shift; +pub mod sub; +pub mod uma; +pub mod utils; + +pub(crate) const ALL_CANONICAL_OPCODES: [&str; 16] = [ + "invalid", + "nop", + "add", + "sub", + "mul", + "div", + "jump", + "ctx", + "shift", + "binop", + "ptr", + "log", + "near_call", + "far_call", + "ret", + "uma", +]; + +/// +/// The instruction. +/// +#[derive(Debug, Clone, PartialEq)] +pub enum Instruction { + /// The `invalid` instruction. + Invalid(Invalid), + /// The `noop` instruction. + Nop(Nop), + /// The arithmetic addition instruction. + Add(Add), + /// The arithmetic subtraction instruction. + Sub(Sub), + /// The arithmetic multiplication instruction. + Mul(Mul), + /// The arithmetic division or remainder instruction. + Div(Div), + /// The jump control flow instruction. + Jump(Jump), + /// Read value from execution context. + Context(Context), + /// Bitwise shift operation (shl, shr, rol, ror). + Shift(Shift), + /// Bitwise operation: AND, OR or XOR. + Bitwise(Bitwise), + /// Pointer arithmetics + Ptr(Ptr), + /// Log opcode for all external accesses + Log(Log), + /// Call to the same code page + NearCall(NearCall), + /// Call to another contract + FarCall(FarCall), + /// Return + Ret(Ret), + /// Unaligned memory access + UMA(UMA), +} + +impl Instruction { + #[track_caller] + pub fn try_from_parts( + opcode: &str, + modifiers: HashSet<&str>, + operands: Vec<&str>, + ) -> Result { + match opcode { + "invalid" => Ok(Instruction::Invalid(Invalid::build_from_parts( + modifiers, operands, + )?)), + "nop" => Ok(Instruction::Nop(Nop::build_from_parts( + modifiers, operands, + )?)), + "add" => Ok(Instruction::Add(Add::build_from_parts( + modifiers, operands, + )?)), + "sub" => Ok(Instruction::Sub(Sub::build_from_parts( + modifiers, operands, + )?)), + "mul" => Ok(Instruction::Mul(Mul::build_from_parts( + modifiers, operands, + )?)), + "div" => Ok(Instruction::Div(Div::build_from_parts( + modifiers, operands, + )?)), + "jump" => Ok(Instruction::Jump(Jump::build_from_parts( + modifiers, operands, + )?)), + "context" => Ok(Instruction::Context(Context::build_from_parts( + modifiers, operands, + )?)), + "shift" => Ok(Instruction::Shift(Shift::build_from_parts( + modifiers, operands, + )?)), + "binop" => Ok(Instruction::Bitwise(Bitwise::build_from_parts( + modifiers, operands, + )?)), + "ptr" => Ok(Instruction::Ptr(Ptr::build_from_parts( + modifiers, operands, + )?)), + "log" => Ok(Instruction::Log(Log::build_from_parts( + modifiers, operands, + )?)), + "near_call" => Ok(Instruction::NearCall(NearCall::build_from_parts( + modifiers, operands, + )?)), + "far_call" => Ok(Instruction::FarCall(FarCall::build_from_parts( + modifiers, operands, + )?)), + "ret" => Ok(Instruction::Ret(Ret::build_from_parts( + modifiers, operands, + )?)), + "uma" => Ok(Instruction::UMA(UMA::build_from_parts( + modifiers, operands, + )?)), + _ => Err(InstructionReadError::UnexpectedInstruction( + opcode.to_owned(), + )), + } + } + + pub(crate) fn link>( + &mut self, + function_labels_to_pc: &HashMap, + constant_labels_to_offset: &HashMap, + globals_to_offsets: &HashMap, + ) -> Result<(), AssemblyParseError> { + match self { + Instruction::Invalid(instr) => instr.link::( + function_labels_to_pc, + constant_labels_to_offset, + globals_to_offsets, + ), + Instruction::Nop(instr) => instr.link::( + function_labels_to_pc, + constant_labels_to_offset, + globals_to_offsets, + ), + Instruction::Add(instr) => instr.link::( + function_labels_to_pc, + constant_labels_to_offset, + globals_to_offsets, + ), + Instruction::Sub(instr) => instr.link::( + function_labels_to_pc, + constant_labels_to_offset, + globals_to_offsets, + ), + Instruction::Mul(instr) => instr.link::( + function_labels_to_pc, + constant_labels_to_offset, + globals_to_offsets, + ), + Instruction::Div(instr) => instr.link::( + function_labels_to_pc, + constant_labels_to_offset, + globals_to_offsets, + ), + Instruction::Jump(instr) => instr.link::( + function_labels_to_pc, + constant_labels_to_offset, + globals_to_offsets, + ), + Instruction::Context(instr) => instr.link::( + function_labels_to_pc, + constant_labels_to_offset, + globals_to_offsets, + ), + Instruction::Shift(instr) => instr.link::( + function_labels_to_pc, + constant_labels_to_offset, + globals_to_offsets, + ), + Instruction::Bitwise(instr) => instr.link::( + function_labels_to_pc, + constant_labels_to_offset, + globals_to_offsets, + ), + Instruction::Ptr(instr) => instr.link::( + function_labels_to_pc, + constant_labels_to_offset, + globals_to_offsets, + ), + Instruction::Log(instr) => instr.link::( + function_labels_to_pc, + constant_labels_to_offset, + globals_to_offsets, + ), + Instruction::NearCall(instr) => instr.link::( + function_labels_to_pc, + constant_labels_to_offset, + globals_to_offsets, + ), + Instruction::FarCall(instr) => instr.link::( + function_labels_to_pc, + constant_labels_to_offset, + globals_to_offsets, + ), + Instruction::Ret(instr) => instr.link::( + function_labels_to_pc, + constant_labels_to_offset, + globals_to_offsets, + ), + Instruction::UMA(instr) => instr.link::( + function_labels_to_pc, + constant_labels_to_offset, + globals_to_offsets, + ), + } + } +} + +pub(crate) fn link_operand>( + operand: &mut FullOperand, + function_labels_to_pc: &HashMap, + constant_labels_to_offset: &HashMap, + globals_to_offsets: &HashMap, +) -> Result<(), AssemblyParseError> { + match operand.clone() { + FullOperand::Constant(ConstantOperand { + label, + register, + immediate, + }) => { + if let Some(pc) = function_labels_to_pc.get(&*label).copied() { + assert_eq!( + immediate, 0, + "jumps can not have immediates in labels addressing" + ); + assert!( + register.is_void(), + "jumps can not have registers in labels addressing" + ); + if pc > (E::PcOrImm::max()).as_u64() as usize { + return Err(AssemblyParseError::CodeIsTooLong( + pc, + label, + (E::PcOrImm::max()).as_u64(), + )); + } + // assert!(pc <= Offset::MAX as usize, "pc overflow in linker"); + *operand = FullOperand::Full(GenericOperand { + r#type: ImmMemHandlerFlags::UseImm16Only, + register: RegisterOperand::Null, + immediate: pc as u64, + }); + } else if let Some(offset) = constant_labels_to_offset.get(&*label).copied() { + if offset > (E::PcOrImm::max()).as_u64() as usize { + return Err(AssemblyParseError::CodeIsTooLong( + offset, + label, + (E::PcOrImm::max()).as_u64(), + )); + } + // assert!(offset <= Offset::MAX as usize, "offset overflow in linker"); + let imm = E::PcOrImm::from_u64_clipped(immediate) + .wrapping_add(E::PcOrImm::from_u64_clipped(offset as u64)) + .as_u64(); + + *operand = FullOperand::Full(GenericOperand { + r#type: ImmMemHandlerFlags::UseCodePage, + register, + immediate: imm, + }); + } else { + return Err(AssemblyParseError::LabelNotFound(label.to_owned())); + } + } + FullOperand::GlobalVariable(GlobalVariable { + label, + register, + immediate, + }) => { + if let Some(offset) = globals_to_offsets.get(&*label).copied() { + if offset > (E::PcOrImm::max()).as_u64() as usize { + return Err(AssemblyParseError::CodeIsTooLong( + offset, + label, + (E::PcOrImm::max()).as_u64(), + )); + } + // assert!(offset <= Offset::MAX as usize, "offset overflow in linker"); + let imm = E::PcOrImm::from_u64_clipped(immediate) + .wrapping_add(E::PcOrImm::from_u64_clipped(offset as u64)) + .as_u64(); + + *operand = FullOperand::Full(GenericOperand { + r#type: ImmMemHandlerFlags::UseAbsoluteOnStack, + register, + immediate: imm, + }); + } else { + return Err(AssemblyParseError::LabelNotFound(label.to_owned())); + } + } + _ => {} + } + + Ok(()) +} + +impl> TryFrom for DecodedOpcode { + type Error = InstructionReadError; + fn try_from(value: Instruction) -> Result { + match value { + Instruction::Invalid(instr) => DecodedOpcode::try_from(instr), + Instruction::Nop(instr) => DecodedOpcode::try_from(instr), + Instruction::Add(instr) => DecodedOpcode::try_from(instr), + Instruction::Sub(instr) => DecodedOpcode::try_from(instr), + Instruction::Mul(instr) => DecodedOpcode::try_from(instr), + Instruction::Div(instr) => DecodedOpcode::try_from(instr), + Instruction::Jump(instr) => DecodedOpcode::try_from(instr), + Instruction::Context(instr) => DecodedOpcode::try_from(instr), + Instruction::Shift(instr) => DecodedOpcode::try_from(instr), + Instruction::Bitwise(instr) => DecodedOpcode::try_from(instr), + Instruction::Ptr(instr) => DecodedOpcode::try_from(instr), + Instruction::Log(instr) => DecodedOpcode::try_from(instr), + Instruction::NearCall(instr) => DecodedOpcode::try_from(instr), + Instruction::FarCall(instr) => DecodedOpcode::try_from(instr), + Instruction::Ret(instr) => DecodedOpcode::try_from(instr), + Instruction::UMA(instr) => DecodedOpcode::try_from(instr), + } + } +} + +pub fn set_src0_or_dst0_full_operand>( + operand: &GenericOperand, + into: &mut DecodedOpcode, + is_dst: bool, +) { + let GenericOperand { + r#type: imm_mem, + immediate, + register, + } = operand; + let idx = match register { + &RegisterOperand::Null => 0, + &RegisterOperand::Register(idx) => idx, + }; + if is_dst { + into.dst0_reg_idx = idx; + into.variant.dst0_operand_type = Operand::Full(*imm_mem); + into.imm_1 = E::PcOrImm::from_u64_clipped(*immediate); + } else { + into.src0_reg_idx = idx; + into.variant.src0_operand_type = Operand::Full(*imm_mem); + into.imm_0 = E::PcOrImm::from_u64_clipped(*immediate); + } +} + +pub fn set_src0_or_dst0_register_operand>( + operand: &RegisterOperand, + into: &mut DecodedOpcode, + is_dst: bool, +) { + let idx = match operand { + &RegisterOperand::Null => 0, + &RegisterOperand::Register(idx) => idx, + }; + if is_dst { + into.dst0_reg_idx = idx; + into.variant.dst0_operand_type = Operand::RegOnly; + into.imm_1 = E::PcOrImm::from_u64_clipped(0); + } else { + into.src0_reg_idx = idx; + into.variant.src0_operand_type = Operand::RegOnly; + into.imm_0 = E::PcOrImm::from_u64_clipped(0); + } +} + +pub fn set_src_non_memory_operand>( + operand: &NonMemoryOperand, + into: &mut DecodedOpcode, +) { + let idx = match &operand.register { + &RegisterOperand::Null => 0, + &RegisterOperand::Register(idx) => idx, + }; + + match operand.r#type { + RegOrImmFlags::UseRegOnly => { + into.src0_reg_idx = idx; + into.variant.src0_operand_type = Operand::RegOrImm(RegOrImmFlags::UseRegOnly); + into.imm_0 = E::PcOrImm::from_u64_clipped(0); + } + RegOrImmFlags::UseImm16Only => { + assert!(idx == 0); + into.src0_reg_idx = 0; + into.variant.src0_operand_type = Operand::RegOrImm(RegOrImmFlags::UseImm16Only); + into.imm_0 = E::PcOrImm::from_u64_clipped(operand.immediate); + } + } +} + +pub fn set_register_operand>( + operand: &RegisterOperand, + into: &mut DecodedOpcode, + is_dst: bool, +) { + let idx = match operand { + &RegisterOperand::Null => 0, + &RegisterOperand::Register(idx) => idx, + }; + if is_dst { + into.dst1_reg_idx = idx; + } else { + into.src1_reg_idx = idx; + } +} diff --git a/crates/zkEVM-assembly/src/assembly/instruction/mul.rs b/crates/zkEVM-assembly/src/assembly/instruction/mul.rs new file mode 100644 index 0000000..fe60dee --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/instruction/mul.rs @@ -0,0 +1,114 @@ +//! +//! The arithmetic multiplication instruction. +//! + +use super::*; + +use crate::error::InstructionReadError; +use std::collections::HashMap; +use std::convert::TryFrom; + +/// +/// The arithmetic multiplication instruction. +/// +#[derive(Debug, Clone, PartialEq)] +pub struct Mul { + /// Condition for execution + pub condition: ConditionCase, + /// Whether we set flags or not + pub set_flags_option: SetFlags, + /// The first operand. + pub source_1: FullOperand, + /// The second operand. + pub source_2: RegisterOperand, + /// The lowest 256 bits destination register. + pub destination_1: FullOperand, + /// The highest 256 bits destination register. + pub destination_2: RegisterOperand, +} + +impl Mul { + // Total number of arguments in canonical form + pub const NUM_ARGUMENTS: usize = 4; + + #[track_caller] + pub fn build_from_parts( + mut modifiers: HashSet<&str>, + operands: Vec<&str>, + ) -> Result { + let operands = parse_canonical_operands_sequence( + operands, + &[marker_full_operand(), marker_register_operand()], + &[marker_full_operand(), marker_register_operand()], + )?; + + let src0 = operands[0].clone(); + let src1 = operands[1].clone(); + let dst0 = operands[2].clone(); + let dst1 = operands[3].clone(); + + let condition = pick_condition(&mut modifiers)?; + let set_flags_option = pick_setting_flags(&mut modifiers)?; + + if !modifiers.is_empty() { + return Err(InstructionReadError::UnknownArgument(format!( + "Mul instruction contains unknown modifiers: {:?}", + modifiers + ))); + } + + let new = Self { + condition, + set_flags_option, + source_1: src0, + source_2: src1.as_register_operand(1)?, + destination_1: dst0, + destination_2: dst1.as_register_operand(3)?, + }; + + Ok(new) + } + + #[track_caller] + pub(crate) fn link>( + &mut self, + function_labels_to_pc: &HashMap, + constant_labels_to_offset: &HashMap, + globals_to_offsets: &HashMap, + ) -> Result<(), AssemblyParseError> { + link_operand::( + &mut self.source_1, + function_labels_to_pc, + constant_labels_to_offset, + globals_to_offsets, + )?; + + link_operand::( + &mut self.destination_1, + function_labels_to_pc, + constant_labels_to_offset, + globals_to_offsets, + )?; + + Ok(()) + } +} + +impl> TryFrom for DecodedOpcode { + type Error = InstructionReadError; + fn try_from(value: Mul) -> Result { + let mut new = DecodedOpcode::default(); + new.variant = OpcodeVariant { + opcode: Opcode::Mul(MulOpcode), + ..OpcodeVariant::default() + }; + set_src0_or_dst0_full_operand(&value.source_1.as_generic_operand(0)?, &mut new, false); + set_register_operand(&value.source_2, &mut new, false); + set_src0_or_dst0_full_operand(&value.destination_1.as_generic_operand(2)?, &mut new, true); + set_register_operand(&value.destination_2, &mut new, true); + new.condition = value.condition.0; + new.variant.flags[SET_FLAGS_FLAG_IDX] = value.set_flags_option.0; + + Ok(new) + } +} diff --git a/crates/zkEVM-assembly/src/assembly/instruction/near_call.rs b/crates/zkEVM-assembly/src/assembly/instruction/near_call.rs new file mode 100644 index 0000000..38977a0 --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/instruction/near_call.rs @@ -0,0 +1,117 @@ +//! +//! The control flow jump instruction. +//! + +use super::*; + +use crate::error::InstructionReadError; +use std::convert::TryFrom; + +/// +/// The control flow jump instruction. +/// +#[derive(Debug, Clone, PartialEq)] +pub struct NearCall { + /// Condition for execution + pub condition: ConditionCase, + /// Ergs parameter + pub source_for_passed_ergs: RegisterOperand, + /// Destination to jump-call + pub destination: FullOperand, + /// Exception handler + pub exception_handler: FullOperand, +} + +impl NearCall { + // Total number of arguments in canonical form + pub const NUM_ARGUMENTS: usize = 1; + + #[track_caller] + pub fn build_from_parts( + mut modifiers: HashSet<&str>, + operands: Vec<&str>, + ) -> Result { + let operands = parse_canonical_operands_sequence( + operands, + &[ + marker_register_operand(), + OperandType::Label, + OperandType::Label, + ], + &[], + )?; + + let src0 = operands[0].clone().as_register_operand(0)?; + let dst = operands[1].clone(); + let exception_handler = operands[2].clone(); + let condition = pick_condition(&mut modifiers)?; + if !modifiers.is_empty() { + return Err(InstructionReadError::UnknownArgument(format!( + "Near call instruction contains unknown modifiers: {:?}", + modifiers + ))); + } + + let new = Self { + condition, + source_for_passed_ergs: src0, + destination: dst, + exception_handler, + }; + + if !modifiers.is_empty() { + return Err(InstructionReadError::UnknownArgument(format!( + "{:?}", + modifiers + ))); + } + + Ok(new) + } + + #[track_caller] + pub(crate) fn link>( + &mut self, + function_labels_to_pc: &HashMap, + constant_labels_to_offset: &HashMap, + globals_to_offsets: &HashMap, + ) -> Result<(), AssemblyParseError> { + link_operand::( + &mut self.destination, + function_labels_to_pc, + constant_labels_to_offset, + globals_to_offsets, + )?; + link_operand::( + &mut self.exception_handler, + function_labels_to_pc, + constant_labels_to_offset, + globals_to_offsets, + )?; + + Ok(()) + } +} + +impl> TryFrom for DecodedOpcode { + type Error = InstructionReadError; + fn try_from(value: NearCall) -> Result { + let mut new = DecodedOpcode::default(); + new.variant = OpcodeVariant { + opcode: Opcode::NearCall(NearCallOpcode), + ..OpcodeVariant::default() + }; + set_src0_or_dst0_register_operand(&value.source_for_passed_ergs, &mut new, false); + new.condition = value.condition.0; + + let offset_for_dest = value.destination.as_generic_operand(1)?.as_pc_offset(); + let offset_for_eh = value + .exception_handler + .as_generic_operand(2)? + .as_pc_offset(); + new.imm_0 = E::PcOrImm::from_u64_clipped(offset_for_dest); + new.imm_1 = E::PcOrImm::from_u64_clipped(offset_for_eh); + + Ok(new) + } +} diff --git a/crates/zkEVM-assembly/src/assembly/instruction/nop.rs b/crates/zkEVM-assembly/src/assembly/instruction/nop.rs new file mode 100644 index 0000000..f1ad0bd --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/instruction/nop.rs @@ -0,0 +1,110 @@ +//! +//! The Nop instruction +//! + +use super::*; + +/// +/// The NOP instruction. Can also be used for stack adjustment +/// +#[derive(Debug, Clone, PartialEq)] +pub struct Nop { + /// Condition for execution + pub condition: ConditionCase, + /// The first operand. + pub source_1: GenericOperand, + /// The second operand. + pub source_2: RegisterOperand, + /// The first destination operand. + pub dest_1: GenericOperand, + /// The second descination operand. + pub dest_2: RegisterOperand, +} + +impl Nop { + // Total number of arguments in canonical form + pub const NUM_ARGUMENTS: usize = 4; + + #[track_caller] + pub fn build_from_parts( + mut modifiers: HashSet<&str>, + operands: Vec<&str>, + ) -> Result { + let operands = parse_canonical_operands_sequence( + operands, + &[marker_full_operand(), marker_register_operand()], + &[marker_full_operand(), marker_register_operand()], + )?; + + let src0 = operands[0].clone(); + let src1 = operands[1].clone(); + let dst0 = operands[2].clone(); + let dst1 = operands[3].clone(); + + let condition = pick_condition(&mut modifiers)?; + + if !modifiers.is_empty() { + return Err(InstructionReadError::UnknownArgument(format!( + "Nop instruction contains unknown modifiers: {:?}", + modifiers + ))); + } + + let new = Self { + condition, + source_1: src0.as_generic_operand(0)?, + source_2: src1.as_register_operand(1)?, + dest_1: dst0.as_generic_operand(2)?, + dest_2: dst1.as_register_operand(3)?, + }; + + if !new.source_2.is_void() || !new.dest_2.is_void() { + return Err(InstructionReadError::UnknownArgument( + "src1 and dst1 of Nop must be r0 from logical perspective".to_owned(), + )); + } + + Ok(new) + } + + #[track_caller] + pub(crate) fn link>( + &mut self, + _function_labels_to_pc: &HashMap, + _constant_labels_to_offset: &HashMap, + _globals_to_offsets: &HashMap, + ) -> Result<(), AssemblyParseError> { + // link_operand::( + // &mut self.source_1, + // function_labels_to_pc, + // constant_labels_to_offset, + // globals_to_offsets, + // )?; + + // link_operand::( + // &mut self.dest_1, + // function_labels_to_pc, + // constant_labels_to_offset, + // )?; + + Ok(()) + } +} + +impl> TryFrom for DecodedOpcode { + type Error = InstructionReadError; + fn try_from(value: Nop) -> Result { + let mut new = DecodedOpcode::default(); + new.variant = OpcodeVariant { + opcode: Opcode::Nop(NopOpcode), + ..OpcodeVariant::default() + }; + set_src0_or_dst0_full_operand(&value.source_1, &mut new, false); + set_register_operand(&value.source_2, &mut new, false); + set_src0_or_dst0_full_operand(&value.dest_1, &mut new, true); + set_register_operand(&value.dest_2, &mut new, true); + new.condition = value.condition.0; + + Ok(new) + } +} diff --git a/crates/zkEVM-assembly/src/assembly/instruction/ptr.rs b/crates/zkEVM-assembly/src/assembly/instruction/ptr.rs new file mode 100644 index 0000000..3896522 --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/instruction/ptr.rs @@ -0,0 +1,142 @@ +use super::*; + +#[derive(Debug, Clone, PartialEq)] +pub struct Ptr { + /// Condition for execution + pub condition: ConditionCase, + /// The first operand. + pub source_1: FullOperand, + /// The second operand. + pub source_2: RegisterOperand, + /// The destination register. + pub destination: FullOperand, + /// And, Or or Xor + pub op_type: PtrOpcode, + /// if it is set then source operands have to be swapped. + pub swap_operands: bool, +} + +impl Ptr { + pub const ALL_CANONICAL_MODIFIERS: [&'static str; 4] = ["add", "sub", "pack", "shrink"]; + + #[track_caller] + pub fn build_from_parts( + mut modifiers: HashSet<&str>, + operands: Vec<&str>, + ) -> Result { + let operands = parse_canonical_operands_sequence( + operands, + &[marker_full_operand(), marker_register_operand()], + &[marker_full_operand()], + )?; + + let src0 = operands[0].clone(); + let src1 = operands[1].clone(); + let dst0 = operands[2].clone(); + + if modifiers.is_empty() { + return Err(InstructionReadError::InvalidArgument { + index: 0, + expected: "ptr opcode must contain a modifier", + found: "no modifiers".to_owned(), + }); + } + + let mut swap_operands = false; + if modifiers.remove("s") { + swap_operands = true; + } + + let mut result = None; + for (idx, modifier) in Self::ALL_CANONICAL_MODIFIERS.iter().enumerate() { + if modifiers.contains(modifier) { + if result.is_some() { + return Err(InstructionReadError::UnknownArgument(format!( + "duplicate variant in modifiers: already have {:?}, got {}", + result.unwrap(), + modifier + ))); + } else { + modifiers.remove(modifier); + let variant = match idx { + 0 => PtrOpcode::Add, + 1 => PtrOpcode::Sub, + 2 => PtrOpcode::Pack, + 3 => PtrOpcode::Shrink, + _ => { + unreachable!() + } + }; + result = Some(variant); + } + } + } + + let variant = result.ok_or(InstructionReadError::UnknownArgument( + "Ptr instruction contains no modifier".to_owned(), + ))?; + + let condition = pick_condition(&mut modifiers)?; + + if !modifiers.is_empty() { + return Err(InstructionReadError::UnknownArgument(format!( + "Ptr instruction contains unknown modifiers: {:?}", + modifiers + ))); + } + + let new = Self { + condition, + source_1: src0, + source_2: src1.as_register_operand(1)?, + destination: dst0, + op_type: variant, + swap_operands, + }; + + Ok(new) + } + + #[track_caller] + pub(crate) fn link>( + &mut self, + function_labels_to_pc: &HashMap, + constant_labels_to_offset: &HashMap, + globals_to_offsets: &HashMap, + ) -> Result<(), AssemblyParseError> { + link_operand::( + &mut self.source_1, + function_labels_to_pc, + constant_labels_to_offset, + globals_to_offsets, + )?; + + link_operand::( + &mut self.destination, + function_labels_to_pc, + constant_labels_to_offset, + globals_to_offsets, + )?; + + Ok(()) + } +} + +impl> TryFrom for DecodedOpcode { + type Error = InstructionReadError; + + fn try_from(value: Ptr) -> Result { + let mut new = DecodedOpcode::default(); + new.variant = OpcodeVariant { + opcode: Opcode::Ptr(value.op_type), + ..OpcodeVariant::default() + }; + set_src0_or_dst0_full_operand(&value.source_1.as_generic_operand(0)?, &mut new, false); + set_register_operand(&value.source_2, &mut new, false); + set_src0_or_dst0_full_operand(&value.destination.as_generic_operand(2)?, &mut new, true); + new.condition = value.condition.0; + new.variant.flags[SWAP_OPERANDS_FLAG_IDX_FOR_PTR_OPCODE] = value.swap_operands; + + Ok(new) + } +} diff --git a/crates/zkEVM-assembly/src/assembly/instruction/ret.rs b/crates/zkEVM-assembly/src/assembly/instruction/ret.rs new file mode 100644 index 0000000..dadb04c --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/instruction/ret.rs @@ -0,0 +1,155 @@ +//! +//! The control flow jump instruction. +//! + +use super::*; + +use crate::error::InstructionReadError; +use std::convert::TryFrom; + +/// +/// The control flow jump instruction. +/// +#[derive(Debug, Clone, PartialEq)] +pub struct Ret { + /// Condition for execution + pub condition: ConditionCase, + /// Source register for return parameters + pub source_for_meta_args: RegisterOperand, + /// Type of return + pub variant: RetOpcode, + /// Return to specific label + pub is_to_label: bool, + /// Label to use + pub label_for_return: Option, +} + +impl Ret { + pub const ALL_CANONICAL_MODIFIERS: [&'static str; 3] = ["ok", "revert", "panic"]; + + // Total number of arguments in canonical form + pub const NUM_ARGUMENTS: usize = 1; + + #[track_caller] + pub fn build_from_parts( + mut modifiers: HashSet<&str>, + operands: Vec<&str>, + ) -> Result { + let condition = pick_condition(&mut modifiers)?; + + let mut result = None; + for (idx, modifier) in Self::ALL_CANONICAL_MODIFIERS.iter().enumerate() { + if modifiers.contains(modifier) { + if result.is_some() { + return Err(InstructionReadError::UnknownArgument(format!( + "duplicate variant in modifiers: already have {:?}, got {}", + result.unwrap(), + modifier + ))); + } else { + modifiers.remove(modifier); + let variant = match idx { + 0 => RetOpcode::Ok, + 1 => RetOpcode::Revert, + 2 => RetOpcode::Panic, + _ => unreachable!(), + }; + result = Some(variant); + } + } + } + + if result.is_none() { + // our default behavior + result = Some(RetOpcode::Ok); + } + + let is_to_label = modifiers.remove("to_label"); + + let (src0, label) = if !is_to_label { + let operands = + parse_canonical_operands_sequence(operands, &[marker_register_operand()], &[])?; + + let src0 = operands[0].clone().as_register_operand(0)?; + + (src0, None) + } else { + let operands = parse_canonical_operands_sequence( + operands, + &[marker_register_operand(), OperandType::Label], + &[], + )?; + + let src0 = operands[0].clone().as_register_operand(0)?; + let label = operands[1].clone(); + + (src0, Some(label)) + }; + + let variant = result.ok_or(InstructionReadError::UnknownArgument( + "Ret instruction contains no modifier".to_owned(), + ))?; + + let new = Self { + condition, + source_for_meta_args: src0, + variant, + is_to_label, + label_for_return: label, + }; + + Ok(new) + } + + #[track_caller] + pub(crate) fn link>( + &mut self, + function_labels_to_pc: &HashMap, + constant_labels_to_offset: &HashMap, + globals_to_offsets: &HashMap, + ) -> Result<(), AssemblyParseError> { + if !self.is_to_label { + return Ok(()); + } + + let label = self + .label_for_return + .as_mut() + .expect("if we return to label we should have a label"); + link_operand::( + label, + function_labels_to_pc, + constant_labels_to_offset, + globals_to_offsets, + )?; + + Ok(()) + } +} + +impl> TryFrom for DecodedOpcode { + type Error = InstructionReadError; + fn try_from(value: Ret) -> Result { + let mut new = DecodedOpcode::default(); + new.variant = OpcodeVariant { + opcode: Opcode::Ret(value.variant), + ..OpcodeVariant::default() + }; + set_src0_or_dst0_register_operand(&value.source_for_meta_args, &mut new, false); + new.condition = value.condition.0; + if value.is_to_label { + let offset = value + .label_for_return + .expect("if we return to label we should have a label") + .as_generic_operand(1)? + .as_pc_offset(); + new.imm_0 = E::PcOrImm::from_u64_clipped(offset); + new.variant.flags[0] = true; + } else { + assert!(value.label_for_return.is_none()); + new.variant.flags[0] = false; + } + + Ok(new) + } +} diff --git a/crates/zkEVM-assembly/src/assembly/instruction/set_flags.rs b/crates/zkEVM-assembly/src/assembly/instruction/set_flags.rs new file mode 100644 index 0000000..66676ac --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/instruction/set_flags.rs @@ -0,0 +1,22 @@ +//! +//! Condition to apply the operation +//! + +use crate::InstructionReadError; + +/// +/// The control flow jump instruction flag. +/// +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)] +pub struct SetFlags(pub bool); + +impl SetFlags { + pub const ALL_CANONICAL_MODIFIERS: [&'static str; 1] = ["set_flags"]; + + pub fn from_modifier(modifier: &str) -> Result { + match modifier { + "set_flags" => Ok(SetFlags(true)), + _ => Err(InstructionReadError::UnknownArgument(modifier.to_owned())), + } + } +} diff --git a/crates/zkEVM-assembly/src/assembly/instruction/shift.rs b/crates/zkEVM-assembly/src/assembly/instruction/shift.rs new file mode 100644 index 0000000..e3cb6f5 --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/instruction/shift.rs @@ -0,0 +1,138 @@ +use super::*; + +#[derive(Debug, Clone, PartialEq)] +pub struct Shift { + /// Condition for execution + pub condition: ConditionCase, + /// Whether we set flags or not + pub set_flags_option: SetFlags, + /// The first operand. Lowest 8 bits are treated as `shift` + pub source_1: FullOperand, + /// The second operand. The value to `shift` + pub source_2: RegisterOperand, + /// The destination register. + pub destination: FullOperand, + /// if it is set then source operands have to be swapped. + pub swap_operands: bool, + /// Type of shift + pub variant: ShiftOpcode, +} + +impl Shift { + pub const ALL_CANONICAL_MODIFIERS: [&'static str; 4] = ["shl", "shr", "rol", "ror"]; + + #[track_caller] + pub fn build_from_parts( + mut modifiers: HashSet<&str>, + operands: Vec<&str>, + ) -> Result { + let operands = parse_canonical_operands_sequence( + operands, + &[marker_full_operand(), marker_register_operand()], + &[marker_full_operand()], + )?; + + let src0 = operands[0].clone(); + let src1 = operands[1].clone(); + let dst0 = operands[2].clone(); + + let condition = pick_condition(&mut modifiers)?; + let set_flags_option = pick_setting_flags(&mut modifiers)?; + + let mut swap_operands = false; + if modifiers.remove("s") { + swap_operands = true; + } + + let mut result = None; + for (idx, modifier) in Self::ALL_CANONICAL_MODIFIERS.iter().enumerate() { + if modifiers.contains(modifier) { + if result.is_some() { + return Err(InstructionReadError::UnknownArgument(format!( + "duplicate variant in modifiers: already have {:?}, got {}", + result.unwrap(), + modifier + ))); + } else { + modifiers.remove(modifier); + let variant = match idx { + 0 => ShiftOpcode::Shl, + 1 => ShiftOpcode::Shr, + 2 => ShiftOpcode::Rol, + 3 => ShiftOpcode::Ror, + _ => { + unreachable!() + } + }; + result = Some(variant); + } + } + } + + if !modifiers.is_empty() { + return Err(InstructionReadError::UnknownArgument(format!( + "Shift instruction contains unknown modifiers: {:?}", + modifiers + ))); + } + + let variant = result.ok_or(InstructionReadError::UnknownArgument( + "Shift instruction contains no modifier".to_owned(), + ))?; + + let new = Self { + condition, + set_flags_option, + source_1: src0, + source_2: src1.as_register_operand(1)?, + destination: dst0, + swap_operands, + variant, + }; + + Ok(new) + } + + #[track_caller] + pub(crate) fn link>( + &mut self, + function_labels_to_pc: &HashMap, + constant_labels_to_offset: &HashMap, + globals_to_offsets: &HashMap, + ) -> Result<(), AssemblyParseError> { + link_operand::( + &mut self.source_1, + function_labels_to_pc, + constant_labels_to_offset, + globals_to_offsets, + )?; + + link_operand::( + &mut self.destination, + function_labels_to_pc, + constant_labels_to_offset, + globals_to_offsets, + )?; + + Ok(()) + } +} + +impl> TryFrom for DecodedOpcode { + type Error = InstructionReadError; + fn try_from(value: Shift) -> Result { + let mut new = DecodedOpcode::default(); + new.variant = OpcodeVariant { + opcode: Opcode::Shift(value.variant), + ..OpcodeVariant::default() + }; + set_src0_or_dst0_full_operand(&value.source_1.as_generic_operand(0)?, &mut new, false); + set_register_operand(&value.source_2, &mut new, false); + set_src0_or_dst0_full_operand(&value.destination.as_generic_operand(2)?, &mut new, true); + new.condition = value.condition.0; + new.variant.flags[SET_FLAGS_FLAG_IDX] = value.set_flags_option.0; + new.variant.flags[SWAP_OPERANDS_FLAG_IDX_FOR_ARITH_OPCODES] = value.swap_operands; + + Ok(new) + } +} diff --git a/crates/zkEVM-assembly/src/assembly/instruction/sub.rs b/crates/zkEVM-assembly/src/assembly/instruction/sub.rs new file mode 100644 index 0000000..c023376 --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/instruction/sub.rs @@ -0,0 +1,128 @@ +//! +//! The arithmetic subtraction instruction. +//! + +// use crate::assembly::instruction::bytecode::InstructionBytecode; +use super::*; +use crate::assembly::operand::{FullOperand, RegisterOperand}; +use crate::error::InstructionReadError; +use std::collections::{HashMap, HashSet}; +use std::convert::TryFrom; + +/// +/// The arithmetic subtraction instruction. +/// +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Sub { + /// Condition for execution + pub condition: ConditionCase, + /// Whether we set flags or not + pub set_flags_option: SetFlags, + /// The first operand. + pub source_1: FullOperand, + /// The second operand. + pub source_2: RegisterOperand, + /// The destination register. + pub destination: FullOperand, + /// if it is set then source operands have to be swapped. + pub swap_operands: bool, +} + +impl Sub { + // Total number of arguments in canonical form + pub const NUM_ARGUMENTS: usize = 3; + + #[track_caller] + pub fn build_from_parts( + mut modifiers: HashSet<&str>, + operands: Vec<&str>, + ) -> Result { + let operands = if let Ok(operands) = parse_canonical_operands_sequence( + operands.clone(), + &[marker_full_operand(), marker_register_operand()], + &[marker_full_operand()], + ) { + operands + } else { + // try loading label + parse_canonical_operands_sequence( + operands, + &[OperandType::Label, marker_register_operand()], + &[marker_full_operand()], + )? + }; + + let src0 = operands[0].clone(); + let src1 = operands[1].clone(); + let dst0 = operands[2].clone(); + + let condition = pick_condition(&mut modifiers)?; + let set_flags_option = pick_setting_flags(&mut modifiers)?; + + let mut swap_operands = false; + if modifiers.remove("s") { + swap_operands = true; + } + + if !modifiers.is_empty() { + return Err(InstructionReadError::UnknownArgument(format!( + "Sub instruction contains unknown modifiers: {:?}", + modifiers + ))); + } + + let new = Self { + condition, + set_flags_option, + source_1: src0, + source_2: src1.as_register_operand(1)?, + destination: dst0, + swap_operands, + }; + + Ok(new) + } + + #[track_caller] + pub(crate) fn link>( + &mut self, + function_labels_to_pc: &HashMap, + constant_labels_to_offset: &HashMap, + globals_to_offsets: &HashMap, + ) -> Result<(), AssemblyParseError> { + link_operand::( + &mut self.source_1, + function_labels_to_pc, + constant_labels_to_offset, + globals_to_offsets, + )?; + + link_operand::( + &mut self.destination, + function_labels_to_pc, + constant_labels_to_offset, + globals_to_offsets, + )?; + + Ok(()) + } +} + +impl> TryFrom for DecodedOpcode { + type Error = InstructionReadError; + fn try_from(value: Sub) -> Result { + let mut new = DecodedOpcode::default(); + new.variant = OpcodeVariant { + opcode: Opcode::Sub(SubOpcode::Sub), + ..OpcodeVariant::default() + }; + set_src0_or_dst0_full_operand(&value.source_1.as_generic_operand(0)?, &mut new, false); + set_register_operand(&value.source_2, &mut new, false); + set_src0_or_dst0_full_operand(&value.destination.as_generic_operand(2)?, &mut new, true); + new.condition = value.condition.0; + new.variant.flags[SET_FLAGS_FLAG_IDX] = value.set_flags_option.0; + new.variant.flags[SWAP_OPERANDS_FLAG_IDX_FOR_ARITH_OPCODES] = value.swap_operands; + + Ok(new) + } +} diff --git a/crates/zkEVM-assembly/src/assembly/instruction/uma.rs b/crates/zkEVM-assembly/src/assembly/instruction/uma.rs new file mode 100644 index 0000000..7ed70be --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/instruction/uma.rs @@ -0,0 +1,190 @@ +//! +//! Read value from execution context. +//! + +use super::*; + +use crate::error::InstructionReadError; +use std::collections::HashMap; +use std::convert::TryFrom; + +/// +/// Read value from execution context. +/// +#[derive(Debug, Clone, PartialEq)] +pub struct UMA { + /// Condition for execution + pub condition: ConditionCase, + /// Source register for key + pub src_0: NonMemoryOperand, + /// Source register for value on write + pub src_1: RegisterOperand, + /// The destination register for value on read, or incremented source on write + pub dst_0: RegisterOperand, + /// The destination register incremented source on read + pub dst_1: RegisterOperand, + /// Type of log + pub uma_type: UMAOpcode, + /// increment offset or not + pub increment_offset: bool, +} + +impl UMA { + pub const ALL_CANONICAL_MODIFIERS: [&'static str; 7] = [ + "heap_read", + "heap_write", + "aux_heap_read", + "aux_heap_write", + "fat_ptr_read", + "static_read", + "static_write", + ]; + + pub const INCREMENT_OFFSET_MODIFIER: &'static str = "inc"; + + pub const ALL_SHORTHARD_MODIFIERS: [&'static str; 7] = + ["rh", "wh", "rah", "wah", "rptr", "rs", "ws"]; + + #[track_caller] + pub fn build_from_parts( + mut modifiers: HashSet<&str>, + operands: Vec<&str>, + ) -> Result { + let operands = parse_canonical_operands_sequence( + operands, + &[marker_non_mem_operand(), marker_register_operand()], + &[marker_register_operand(), marker_register_operand()], + )?; + + if modifiers.is_empty() { + return Err(InstructionReadError::InvalidArgument { + index: 0, + expected: "UMA opcode must contain a type modifier", + found: "no modifiers".to_owned(), + }); + } + + let condition = pick_condition(&mut modifiers)?; + + let mut result = None; + for (idx, modifier) in Self::ALL_CANONICAL_MODIFIERS.iter().enumerate() { + if modifiers.contains(modifier) { + if result.is_some() { + return Err(InstructionReadError::UnknownArgument(format!( + "UMA: duplicate variant in modifiers: already have {:?}, got {}", + result.unwrap(), + modifier + ))); + } else { + modifiers.remove(modifier); + let variant = match idx { + 0 => UMAOpcode::HeapRead, + 1 => UMAOpcode::HeapWrite, + 2 => UMAOpcode::AuxHeapRead, + 3 => UMAOpcode::AuxHeapWrite, + 4 => UMAOpcode::FatPointerRead, + 5 => UMAOpcode::StaticMemoryRead, + 6 => UMAOpcode::StaticMemoryWrite, + _ => { + unreachable!() + } + }; + result = Some(variant); + } + } + } + + if result.is_none() { + for (idx, modifier) in Self::ALL_SHORTHARD_MODIFIERS.iter().enumerate() { + if modifiers.contains(modifier) { + if result.is_some() { + return Err(InstructionReadError::UnknownArgument( + format!("UMA: duplicate shorthand variant in modifiers: already have {:?}, got {}", + result.unwrap(), + modifier + ))); + } else { + modifiers.remove(modifier); + let variant = match idx { + 0 => UMAOpcode::HeapRead, + 1 => UMAOpcode::HeapWrite, + 2 => UMAOpcode::AuxHeapRead, + 3 => UMAOpcode::AuxHeapWrite, + 4 => UMAOpcode::FatPointerRead, + 5 => UMAOpcode::StaticMemoryRead, + 6 => UMAOpcode::StaticMemoryWrite, + _ => { + unreachable!() + } + }; + result = Some(variant); + } + } + } + } + + let variant = result.ok_or(InstructionReadError::UnknownArgument( + "UMA instruction contains no modifier, but should containt access type".to_owned(), + ))?; + + let increment_offset = modifiers.remove(Self::INCREMENT_OFFSET_MODIFIER); + + if !modifiers.is_empty() { + return Err(InstructionReadError::UnknownArgument(format!( + "UMA instruction contains unknown modifiers: {:?}", + modifiers + ))); + } + + let new = Self { + condition, + src_0: operands[0].clone().as_non_memory_operand(0)?, + src_1: operands[1].clone().as_register_operand(1)?, + dst_0: operands[2].clone().as_register_operand(0)?, + dst_1: operands[3].clone().as_register_operand(1)?, + uma_type: variant, + increment_offset, + }; + + Ok(new) + } + + #[track_caller] + pub(crate) fn link>( + &mut self, + _function_labels_to_pc: &HashMap, + _constant_labels_to_offset: &HashMap, + _globals_to_offsets: &HashMap, + ) -> Result<(), AssemblyParseError> { + Ok(()) + } +} + +impl> TryFrom for DecodedOpcode { + type Error = InstructionReadError; + fn try_from(value: UMA) -> Result { + let mut new = DecodedOpcode::default(); + new.variant = OpcodeVariant { + opcode: Opcode::UMA(value.uma_type), + ..OpcodeVariant::default() + }; + match new.variant.opcode.input_operands(crate::get_isa_version())[0] { + Operand::RegOrImm(_) => { + assert!(crate::get_isa_version().0 >= 1); + set_src_non_memory_operand(&value.src_0, &mut new); + } + Operand::RegOnly => { + let as_register = value.src_0.as_register_operand(0)?; + set_src0_or_dst0_register_operand(&as_register, &mut new, false); + } + _ => unreachable!(), + } + set_register_operand(&value.src_1, &mut new, false); + set_src0_or_dst0_register_operand(&value.dst_0, &mut new, true); + set_register_operand(&value.dst_1, &mut new, true); + new.condition = value.condition.0; + new.variant.flags[zkevm_opcode_defs::UMA_INCREMENT_FLAG_IDX] = value.increment_offset; + + Ok(new) + } +} diff --git a/crates/zkEVM-assembly/src/assembly/instruction/utils.rs b/crates/zkEVM-assembly/src/assembly/instruction/utils.rs new file mode 100644 index 0000000..b415bb6 --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/instruction/utils.rs @@ -0,0 +1,43 @@ +use super::*; + +pub fn pick_condition( + modifiers: &mut HashSet<&str>, +) -> Result { + let mut result = None; + for modifier in ConditionCase::ALL_CANONICAL_MODIFIERS.iter() { + if modifiers.contains(modifier) { + if result.is_some() { + return Err(InstructionReadError::UnknownArgument(format!( + "duplicate condition case in modifiers: already have {:?}, got {}", + result.unwrap(), + modifier + ))); + } else { + modifiers.remove(modifier); + result = Some(ConditionCase::from_modifier(modifier)?); + } + } + } + + Ok(result.unwrap_or_default()) +} + +pub fn pick_setting_flags(modifiers: &mut HashSet<&str>) -> Result { + let mut result = None; + for modifier in SetFlags::ALL_CANONICAL_MODIFIERS.iter() { + if modifiers.contains(modifier) { + if result.is_some() { + return Err(InstructionReadError::UnknownArgument(format!( + "duplicate condition case in set flags modifiers: already have {:?}, got {}", + result.unwrap(), + modifier + ))); + } else { + modifiers.remove(modifier); + result = Some(SetFlags::from_modifier(modifier)?); + } + } + } + + Ok(result.unwrap_or_default()) +} diff --git a/crates/zkEVM-assembly/src/assembly/linking/mod.rs b/crates/zkEVM-assembly/src/assembly/linking/mod.rs new file mode 100644 index 0000000..a4899c5 --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/linking/mod.rs @@ -0,0 +1,360 @@ +use zkevm_opcode_defs::decoding::encoding_mode_production::EncodingModeProduction; +use zkevm_opcode_defs::decoding::VmEncodingMode; + +use super::*; +use crate::assembly::constants::*; +use crate::assembly::section::*; + +pub const DEFAULT_UNWIND_LABEL: &str = "DEFAULT_UNWIND"; +const DEFAULT_UNWIND_LANDING_PAD_ASSEMBLY: &str = "ret.panic.to_label r0, @DEFAULT_UNWIND"; + +lazy_static::lazy_static! { + pub(crate) static ref DEFAULT_UNWIND_LANDING_PAD_INSTURUCTION_ASSEMBLY: Instruction = { + crate::assembly::parse::code_element::parse_code_element(DEFAULT_UNWIND_LANDING_PAD_ASSEMBLY).unwrap() + }; +} + +pub const DEFAULT_FAR_RETURN_LABEL: &str = "DEFAULT_FAR_RETURN"; +const DEFAULT_FAR_RETURN_LANDING_PAD_ASSEMBLY: &str = "ret.ok.to_label r1, @DEFAULT_FAR_RETURN"; + +lazy_static::lazy_static! { + pub(crate) static ref DEFAULT_FAR_RETURN_LANDING_PAD_INSTURUCTION_ASSEMBLY: Instruction = { + crate::assembly::parse::code_element::parse_code_element(DEFAULT_FAR_RETURN_LANDING_PAD_ASSEMBLY).unwrap() + }; +} + +pub const DEFAULT_FAR_REVERT_LABEL: &str = "DEFAULT_FAR_REVERT"; +const DEFAULT_FAR_REVERT_LANDING_PAD_ASSEMBLY: &str = "ret.revert.to_label r1, @DEFAULT_FAR_REVERT"; + +lazy_static::lazy_static! { + pub(crate) static ref DEFAULT_FAR_REVERT_LANDING_PAD_INSTURUCTION_ASSEMBLY: Instruction = { + crate::assembly::parse::code_element::parse_code_element(DEFAULT_FAR_REVERT_LANDING_PAD_ASSEMBLY).unwrap() + }; +} + +#[derive(Clone, Debug)] +pub enum AlignedRawBytecode { + Instructions(smallvec::SmallVec<[Instruction; 4]>), + Data(ConstantValue), +} + +pub fn production_linker() -> Linker<8, EncodingModeProduction> { + Linker::new() +} + +#[derive(Clone, Copy, Debug)] + +pub struct Linker = EncodingModeProduction> { + _marker: std::marker::PhantomData, +} + +impl> Linker { + pub fn new() -> Self { + Self { + _marker: std::marker::PhantomData, + } + } + + pub(crate) fn link( + &self, + sections: Vec, + mut labels: HashSet, + metadata_hash: Option<[u8; 32]>, + ) -> Result< + ( + Vec, + HashMap, + HashMap, + ), + AssemblyParseError, + > { + let mut result = vec![]; + + let mut aligned_code = vec![]; + let mut data_elements = vec![]; + let mut aligned_globals_values = vec![]; + let mut function_labels_to_pc = HashMap::new(); + let mut constant_labels_to_offset = HashMap::new(); + let mut globals_labels_to_offset = HashMap::new(); + let mut pc_to_line_mapping = HashMap::new(); + + let mut non_trivial_initializers = vec![]; + + // we need to add landing pad that touches globals, and do it BEFORE we include text section + // for easier work of pc to line mapping, and function to PC mapping + + // first we offset SP by the total length of globals + for section in sections.iter() { + match section { + ParsedSection::Globals(section) => { + for el in section.elements.iter().cloned() { + match el { + GlobalsSectionElement::Unlabeled(constant) => { + aligned_globals_values.push(constant); + } + GlobalsSectionElement::Labeled(LabeledGlobal { + label, + source_line: _, + content, + }) => { + let offset = aligned_globals_values.len(); + assert!(labels.remove(&*label)); + globals_labels_to_offset.insert(label.clone(), offset); + for (sub_idx, constant) in content.into_iter().enumerate() { + if !constant.is_empty() { + non_trivial_initializers.push(( + label.clone(), + sub_idx, + constant.clone(), + )); + } + aligned_globals_values.push(constant); + } + } + } + } + } + _ => {} + } + } + + if !aligned_globals_values.is_empty() { + use crate::assembly::parse::code_element::parse_code_element; + let asm_line = format!("nop r0, r0, stack+=[{}], r0", aligned_globals_values.len()); + let opcode = parse_code_element(&asm_line).unwrap(); + aligned_code.push(opcode); + } + + // and now we also add non-trivial initializers + + assert!(non_trivial_initializers.len() <= aligned_globals_values.len()); + + // to do so we have to add some values into data section first + for (label, in_variable_idx, constant) in non_trivial_initializers.into_iter() { + let initializing_label = format!("_INTERNAL_INIT_{}_{}", &label, in_variable_idx); + let offset = data_elements.len(); + constant_labels_to_offset.insert(initializing_label.clone(), offset); + data_elements.push(DataElement::Constant(constant)); + + // and add the corresponding instruction + use crate::assembly::parse::code_element::parse_code_element; + let asm_line = format!( + "add @{}[0], r0, stack[@{} + {}]", + initializing_label, label, in_variable_idx, + ); + let opcode = parse_code_element(&asm_line).unwrap(); + aligned_code.push(opcode); + } + + // and now we can just continue with other sections + + for section in sections.into_iter() { + // just copy + match section { + ParsedSection::Text(section) => { + for el in section.elements.into_iter() { + match el { + TextSectionElement::Unlabeled(code) => { + let CodeElement { + source_line, + instruction, + } = code; + let pc = aligned_code.len(); + aligned_code.push(instruction); + pc_to_line_mapping.insert(pc, source_line); + } + TextSectionElement::Labeled(LabeledFunction { + label, + source_line: _, + content, + }) => { + let pc = aligned_code.len(); + assert!(labels.remove(&*label)); + function_labels_to_pc.insert(label, pc); + for code in content.into_iter() { + let CodeElement { + source_line, + instruction, + } = code; + let pc = aligned_code.len(); + aligned_code.push(instruction); + pc_to_line_mapping.insert(pc, source_line); + } + } + } + } + } + ParsedSection::Data(section) => { + for el in section.elements.into_iter() { + match el { + DataSectionElement::Unlabeled(element) => { + data_elements.push(element); + } + DataSectionElement::Labeled(LabeledConstant { + label, + source_line: _, + content, + }) => { + let offset = data_elements.len(); + assert!(labels.remove(&*label)); + constant_labels_to_offset.insert(label, offset); + for element in content.into_iter() { + data_elements.push(element); + } + } + } + } + } + ParsedSection::Globals(..) => { + // for el in section.elements.into_iter() { + // match el { + // GlobalsSectionElement::Unlabeled(constant) => { + // let ConstantElement { + // source_line: _, + // content_type, + // } = constant; + // aligned_globals_values.push(content_type); + // } + // GlobalsSectionElement::Labeled(LabeledGlobal { + // label, + // source_line: _, + // content, + // }) => { + // let offset = aligned_globals_values.len(); + // assert!(labels.remove(&*label)); + // globals_labels_to_offset.insert(label, offset); + // for constant in content.into_iter() { + // aligned_globals_values.push(constant); + // } + // } + // } + // } + } + } + } + + // add all default landing pads + + let add_landing_pad = |label: &str, + landing_pad_instruction: Instruction, + function_labels_to_pc: &mut HashMap, + aligned_code: &mut Vec| { + if !function_labels_to_pc.contains_key(label) { + let pc = aligned_code.len(); + aligned_code.push(landing_pad_instruction); + function_labels_to_pc.insert(label.to_owned(), pc); + } + }; + + // default panic pad + add_landing_pad( + DEFAULT_UNWIND_LABEL, + DEFAULT_UNWIND_LANDING_PAD_INSTURUCTION_ASSEMBLY.clone(), + &mut function_labels_to_pc, + &mut aligned_code, + ); + + // default far return pad + add_landing_pad( + DEFAULT_FAR_RETURN_LABEL, + DEFAULT_FAR_RETURN_LANDING_PAD_INSTURUCTION_ASSEMBLY.clone(), + &mut function_labels_to_pc, + &mut aligned_code, + ); + + // default far revert pad + add_landing_pad( + DEFAULT_FAR_REVERT_LABEL, + DEFAULT_FAR_REVERT_LANDING_PAD_INSTURUCTION_ASSEMBLY.clone(), + &mut function_labels_to_pc, + &mut aligned_code, + ); + + let opcodes_per_word = 32 / N; + + for _ in (aligned_code.len() % opcodes_per_word)..opcodes_per_word { + aligned_code.push(PADDING_INSTRUCTION.clone()); + } + + assert_eq!(aligned_code.len() % opcodes_per_word, 0); + + let data_offset = aligned_code.len() / opcodes_per_word; + for (_, v) in constant_labels_to_offset.iter_mut() { + *v += data_offset; + } + + // actual linking + + let all_function_labels_to_pc: HashSet<_> = function_labels_to_pc.keys().cloned().collect(); + let all_constant_labels_to_offset = constant_labels_to_offset.keys().cloned().collect(); + let all_globals_labels_to_offset = globals_labels_to_offset.keys().cloned().collect(); + + for el in all_function_labels_to_pc.intersection(&all_constant_labels_to_offset) { + return Err(AssemblyParseError::DuplicateLabel(el.clone())); + } + for el in all_function_labels_to_pc.intersection(&all_globals_labels_to_offset) { + return Err(AssemblyParseError::DuplicateLabel(el.clone())); + } + for el in all_constant_labels_to_offset.intersection(&all_globals_labels_to_offset) { + return Err(AssemblyParseError::DuplicateLabel(el.clone())); + } + + for el in aligned_code.iter_mut() { + el.link::( + &function_labels_to_pc, + &constant_labels_to_offset, + &globals_labels_to_offset, + )?; + } + + let mut aligned_constants = Vec::new(); + for element in data_elements { + match element { + DataElement::Constant(value) => { + aligned_constants.push(value); + } + DataElement::LabelName(name) => { + use crate::assembly::parse::data_element::resolve_to_constant; + if let Some(value) = resolve_to_constant(&name, &function_labels_to_pc) { + aligned_constants.push(value); + } else { + return Err(AssemblyParseError::RelocationError(name)); + } + } + } + } + + // pack + let mut it = aligned_code.chunks_exact(opcodes_per_word); + for chunk in &mut it { + let as_smallvec = smallvec::SmallVec::from_iter(chunk.iter().cloned()); + let raw = AlignedRawBytecode::Instructions(as_smallvec); + result.push(raw); + } + + assert!(it.remainder().is_empty(), "invalid code padding performed"); + for el in aligned_constants { + let raw = AlignedRawBytecode::Data(el); + result.push(raw); + } + + // we need to have full code length to be odd number of words, so we add one more constant + if let Some(metadata_hash) = metadata_hash { + if result.len() % 2 == 1 { + let raw = AlignedRawBytecode::Data(ConstantValue::Cell([0u8; 32])); + result.push(raw); + } + + // insert the contract metadata hash + let raw = AlignedRawBytecode::Data(ConstantValue::Cell(metadata_hash)); + result.push(raw); + } else if result.len() % 2 != 1 { + let raw = AlignedRawBytecode::Data(ConstantValue::Cell([0u8; 32])); + result.push(raw); + } + + assert_eq!(result.len() % 2, 1); + + Ok((result, pc_to_line_mapping, function_labels_to_pc)) + } +} diff --git a/crates/zkEVM-assembly/src/assembly/mnemonic/add.rs b/crates/zkEVM-assembly/src/assembly/mnemonic/add.rs new file mode 100644 index 0000000..af7b204 --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/mnemonic/add.rs @@ -0,0 +1,8 @@ +use super::*; + +pub(crate) fn parse_add_combinator(input: &str) -> IResult<&str, String> { + let (rest, (_, args)) = parse_mnemonic(input, "add", 3)?; + let canonical = format!("add {}, {}, {}", &args[0], &args[1], &args[2]); + + Ok((rest, canonical)) +} diff --git a/crates/zkEVM-assembly/src/assembly/mnemonic/binop.rs b/crates/zkEVM-assembly/src/assembly/mnemonic/binop.rs new file mode 100644 index 0000000..f2bac1a --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/mnemonic/binop.rs @@ -0,0 +1,82 @@ +use super::*; + +// we use binop for unconditional move with two arguments src, dst +pub(crate) fn parse_mov_combinator(input: &str) -> IResult<&str, String> { + let (rest, (_, args)) = parse_mnemonic(input, "mov", 2)?; + let canonical = format!("binop.xor {}, r0, {}, r0", &args[0], &args[1]); + + Ok((rest, canonical)) +} + +pub(crate) fn parse_xor_combinator(input: &str) -> IResult<&str, String> { + let (rest, (_, modifiers, args)) = parse_mnemonic_allow_modifiers(input, "xor", 3)?; + let canonical = format!( + "binop.xor{} {}, {}, {}", + format_modifiers_into_canonical(modifiers), + &args[0], + &args[1], + &args[2] + ); + + Ok((rest, canonical)) +} + +pub(crate) fn parse_or_combinator(input: &str) -> IResult<&str, String> { + let (rest, (_, modifiers, args)) = parse_mnemonic_allow_modifiers(input, "or", 3)?; + let canonical = format!( + "binop.or{} {}, {}, {}", + format_modifiers_into_canonical(modifiers), + &args[0], + &args[1], + &args[2] + ); + + Ok((rest, canonical)) +} + +pub(crate) fn parse_and_combinator(input: &str) -> IResult<&str, String> { + let (rest, (_, modifiers, args)) = parse_mnemonic_allow_modifiers(input, "and", 3)?; + let canonical = format!( + "binop.and{} {}, {}, {}", + format_modifiers_into_canonical(modifiers), + &args[0], + &args[1], + &args[2] + ); + + Ok((rest, canonical)) +} + +pub(crate) fn parse_push_combinator(input: &str) -> IResult<&str, String> { + let (rest, (_, args)) = parse_mnemonic(input, "push", 1)?; + let canonical = format!("binop.xor {}, r0, stack+=[1], r0", &args[0]); + + Ok((rest, canonical)) +} + +pub(crate) fn parse_pop_combinator(input: &str) -> IResult<&str, String> { + let (rest, (_, args)) = parse_mnemonic(input, "pop", 1)?; + let canonical = format!("binop.xor stack-=[1], r0, {}, r0", &args[0]); + + Ok((rest, canonical)) +} + +#[cfg(test)] +mod test { + use super::*; + use crate::assembly::SimplifyNomError; + + #[test] + fn test_parse_mov() { + let example = "mov r2, r3"; + let r = parse_mov_combinator(example).simplify().unwrap(); + dbg!(r); + } + + #[test] + fn test_parse_xor() { + let example = "xor.s.set_flags r2, r3, r0"; + let r = parse_xor_combinator(example).simplify().unwrap(); + dbg!(r); + } +} diff --git a/crates/zkEVM-assembly/src/assembly/mnemonic/call.rs b/crates/zkEVM-assembly/src/assembly/mnemonic/call.rs new file mode 100644 index 0000000..1b27099 --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/mnemonic/call.rs @@ -0,0 +1,83 @@ +use super::*; + +// pub(crate) fn parse_shorthand_ret(input: &str) -> IResult<&str, String> { +// let (rest, (_, modifiers, _)) = parse_mnemonic_allow_modifiers(input, "ret", 0)?; +// // let canonical = format!("ret.ok{} r0", format_modifiers_into_canonical(modifiers)); +// let canonical = format!("ret.ok{} r1", format_modifiers_into_canonical(modifiers)); + +// Ok((rest, canonical)) +// } + +pub(crate) fn parse_shorthand_ret(input: &str) -> IResult<&str, String> { + let (rest, (_, _)) = parse_mnemonic(input, "ret", 0)?; + let canonical = "ret.ok r1".to_owned(); + + Ok((rest, canonical)) +} + +pub(crate) fn parse_shorthand_revert(input: &str) -> IResult<&str, String> { + let (rest, (_, _)) = parse_mnemonic(input, "revert", 0)?; + let canonical = "ret.revert r1".to_string(); + + Ok((rest, canonical)) +} + +pub(crate) fn parse_shorthand_panic(input: &str) -> IResult<&str, String> { + let (rest, (_, _)) = parse_mnemonic(input, "panic", 0)?; + let canonical = "ret.panic r0".to_owned(); + + Ok((rest, canonical)) +} + +pub(crate) fn parse_invoke_combinator(input: &str) -> IResult<&str, String> { + use nom::Parser; + // just pass everything after tag + let (rest, _) = nom::bytes::complete::tag("invoke").parse(input)?; + let canonical = format!("near_call {}", rest); + + Ok((rest, canonical)) +} + +// pub(crate) fn parse_standard_call_combinator(input: &str) -> IResult<&str, String> { +// use nom::Parser; +// // just pass everything after tag +// let (rest, _) = nom::bytes::complete::tag("call").parse(input)?; +// let canonical = format!("far_call.normal {}", rest); + +// Ok((rest, canonical)) +// } + +pub(crate) fn parse_shorthand_exceptionless_near_call(input: &str) -> IResult<&str, String> { + use crate::assembly::linking::DEFAULT_UNWIND_LABEL; + let (rest, (_, modifiers, args)) = parse_mnemonic_allow_modifiers(input, "call", 1)?; + let canonical = format!( + "near_call{} r0, {}, @{}", + format_modifiers_into_canonical(modifiers), + args[0], + DEFAULT_UNWIND_LABEL + ); + + Ok((rest, canonical)) +} + +pub(crate) fn parse_shorthand_delegate_call(input: &str) -> IResult<&str, String> { + use nom::Parser; + // just pass everything after tag + let (rest, _) = nom::bytes::complete::tag("delegatecall").parse(input)?; + let canonical = format!("far_call.delegate r1, {}", rest); + + Ok((rest, canonical)) +} + +pub(crate) fn parse_shorthand_near_call(input: &str) -> IResult<&str, String> { + let (rest, (_, modifiers, args)) = parse_mnemonic_allow_modifiers(input, "call", 3)?; + let canonical = format!( + "near_call{} {}, {}, {}", + format_modifiers_into_canonical(modifiers), + args[0], + args[1], + args[2] + ); + + Ok((rest, canonical)) +} diff --git a/crates/zkEVM-assembly/src/assembly/mnemonic/context.rs b/crates/zkEVM-assembly/src/assembly/mnemonic/context.rs new file mode 100644 index 0000000..f96a339 --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/mnemonic/context.rs @@ -0,0 +1,38 @@ +use super::*; + +pub(crate) fn parse_gas_left_combinator(input: &str) -> IResult<&str, String> { + let (rest, (_, modifiers, args)) = + parse_mnemonic_allow_modifiers(input, "context.gas_left", 1)?; + let canonical = format!( + "context.ergs_left{} {}", + format_modifiers_into_canonical(modifiers), + &args[0], + ); + + Ok((rest, canonical)) +} + +pub(crate) fn parse_set_gas_per_pubdatagas_left_combinator(input: &str) -> IResult<&str, String> { + let (rest, (_, modifiers, args)) = + parse_mnemonic_allow_modifiers(input, "context.set_gas_per_pubdata", 1)?; + let canonical = format!( + "context.set_ergs_per_pubdata{} {}", + format_modifiers_into_canonical(modifiers), + &args[0], + ); + + Ok((rest, canonical)) +} + +#[cfg(test)] +mod test { + use super::*; + use crate::assembly::SimplifyNomError; + + #[test] + fn test_parse_gas_left() { + let example = "context.gas_left r1"; + let r = parse_gas_left_combinator(example).simplify().unwrap(); + dbg!(r); + } +} diff --git a/crates/zkEVM-assembly/src/assembly/mnemonic/log.rs b/crates/zkEVM-assembly/src/assembly/mnemonic/log.rs new file mode 100644 index 0000000..db4ec56 --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/mnemonic/log.rs @@ -0,0 +1,94 @@ +use super::*; + +pub(crate) fn parse_sread_combinator(input: &str) -> IResult<&str, String> { + let (rest, (_, args)) = parse_mnemonic(input, "sread", 2)?; + let canonical = format!("log.sread {}, r0, {}", &args[0], &args[1]); + + Ok((rest, canonical)) +} + +pub(crate) fn parse_sload_combinator(input: &str) -> IResult<&str, String> { + let (rest, (_, args)) = parse_mnemonic(input, "sload", 2)?; + let canonical = format!("log.sread {}, r0, {}", &args[0], &args[1]); + + Ok((rest, canonical)) +} + +pub(crate) fn parse_sstore_combinator(input: &str) -> IResult<&str, String> { + let (rest, (_, args)) = parse_mnemonic(input, "sstore", 2)?; + let canonical = format!("log.swrite {}, {}, r0", &args[0], &args[1]); + + Ok((rest, canonical)) +} + +pub(crate) fn parse_event_combinator(input: &str) -> IResult<&str, String> { + let (rest, (_, modifiers, args)) = parse_mnemonic_allow_modifiers(input, "event", 2)?; + let canonical = format!( + "log.event{} {}, {}, r0", + format_modifiers_into_canonical(modifiers), + &args[0], + &args[1] + ); + + Ok((rest, canonical)) +} + +pub(crate) fn parse_to_l1_combinator(input: &str) -> IResult<&str, String> { + let (rest, (_, modifiers, args)) = parse_mnemonic_allow_modifiers(input, "to_l1", 2)?; + let canonical = format!( + "log.to_l1{} {}, {}, r0", + format_modifiers_into_canonical(modifiers), + &args[0], + &args[1] + ); + + Ok((rest, canonical)) +} + +pub(crate) fn parse_precompile_combinator(input: &str) -> IResult<&str, String> { + let (rest, (_, args)) = parse_mnemonic(input, "precompile", 3)?; + let canonical = format!("log.precompile {}, {}, {}", &args[0], &args[1], &args[2]); + + Ok((rest, canonical)) +} + +#[cfg(test)] +mod test { + use super::*; + use crate::assembly::SimplifyNomError; + + #[test] + fn test_parse_event() { + let example = "event.first r6, r5"; + let r = parse_event_combinator(example).simplify().unwrap(); + dbg!(r); + } +} + +pub(crate) fn parse_tread_combinator(input: &str) -> IResult<&str, String> { + let (rest, (_, args)) = parse_mnemonic(input, "tread", 2)?; + let canonical = format!("log.tread {}, r0, {}", &args[0], &args[1]); + + Ok((rest, canonical)) +} + +pub(crate) fn parse_tload_combinator(input: &str) -> IResult<&str, String> { + let (rest, (_, args)) = parse_mnemonic(input, "tload", 2)?; + let canonical = format!("log.tread {}, r0, {}", &args[0], &args[1]); + + Ok((rest, canonical)) +} + +pub(crate) fn parse_tstore_combinator(input: &str) -> IResult<&str, String> { + let (rest, (_, args)) = parse_mnemonic(input, "tstore", 2)?; + let canonical = format!("log.twrite {}, {}, r0", &args[0], &args[1]); + + Ok((rest, canonical)) +} + +pub(crate) fn parse_decom_combinator(input: &str) -> IResult<&str, String> { + let (rest, (_, args)) = parse_mnemonic(input, "decom", 3)?; + let canonical = format!("log.decommit {}, {}, {}", &args[0], &args[1], &args[2]); + + Ok((rest, canonical)) +} diff --git a/crates/zkEVM-assembly/src/assembly/mnemonic/mod.rs b/crates/zkEVM-assembly/src/assembly/mnemonic/mod.rs new file mode 100644 index 0000000..db9dd4c --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/mnemonic/mod.rs @@ -0,0 +1,573 @@ +//! +//! The assembly operation mnemonic. +//! + +use nom::IResult; + +use crate::error::InstructionReadError; +use std::convert::TryFrom; + +mod binop; +mod call; +mod context; +mod log; +mod nop; +mod set_flags; +mod shift; +mod uma; + +pub(crate) use self::binop::*; +pub(crate) use self::call::*; +pub(crate) use self::context::*; +pub(crate) use self::log::*; +pub(crate) use self::nop::*; +pub(crate) use self::set_flags::*; +pub(crate) use self::shift::*; +pub(crate) use self::uma::*; + +/// +/// The assembly operation mnemonic. +/// +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum Mnemonic { + /// The eponymous opcode keyword. + NoOperation, + /// The eponymous opcode keyword. + Addition, + /// The eponymous opcode keyword. + Subtraction, + /// The eponymous opcode keyword. + SubtractionSwapped, + /// The eponymous opcode keyword. + Multiplication, + /// The eponymous opcode keyword. + Division, + /// The unconditional case of `jump`. + JumpUnconditional, + /// The `eq` case of `jump`. + JumpEquals, + /// The `ne` case of `jump`. + JumpNotEquals, + /// The `ge` case of `jump`. + JumpGreaterEquals, + /// The `le` case of `jump`. + JumpLesserEquals, + /// The `gt` case of `jump`. + JumpGreater, + /// The `lt` case of `jump`. + JumpLesser, + /// The source_zero case of `jump`. + JumpSourceZero, + /// The `call` case of the function jump. + Call, + /// The `external call` case of the function jump. + CallExternal, + /// The `delegade call` case of the function jump. + CallDelegate, + /// The `static call` case of the function jump. + CallStatic, + /// The `account abstraction call` case of the function jump. + CallAA, + /// The `return` case of the function jump. + Return, + /// The `return with error` case of the function jump. + Throw, + // Panic (throw without well defined error) + Panic, + /// The push keyword + Push, + /// The pop keyword + Pop, + /// The `load` case of the contract storage opcode. + StorageLoad, + /// The `store` case of the contract storage opcode. + StorageStore, + /// Initialize Event sequence + EventInit, + /// Event sequence element + Event, + /// Initialize L1 messages sequence + L1MessageInit, + /// L1 messages sequence element + L1Message, + /// Pure non-revertable precompile call + CallPrecompilePure, + /// Revertable precompile call (marker purposes) + CallPrecompileMarker, + /// The `ctx` keyword + Context, + /// The `and` keyword (bitwise) + And, + /// The `or` keyword (bitwise) + Or, + /// The `xor` keyword (bitwise) + Xor, + /// The `shl` keyword (bitwise shift left) + Shl, + /// The `shr` keyword (bitwise shift right) + Shr, + /// The `rol` keyword (bitwise cyclical shift left) + Rol, + /// The `ror` keyword (bitwise cyclical shift right) + Ror, + /// Unconditional copy + Mov, + /// Conditinal copy + CMov, +} + +impl TryFrom<&str> for Mnemonic { + type Error = InstructionReadError; + + fn try_from(input: &str) -> Result { + Ok(match input { + "nop" => Self::NoOperation, + "add" => Self::Addition, + "sub" => Self::Subtraction, + "mul" => Self::Multiplication, + "div" => Self::Division, + "j" => Self::JumpUnconditional, + "je" => Self::JumpEquals, + "jne" => Self::JumpNotEquals, + "jge" => Self::JumpGreaterEquals, + "jle" => Self::JumpLesserEquals, + "jgt" => Self::JumpGreater, + "jlt" => Self::JumpLesser, + "jz" => Self::JumpSourceZero, + "call" => Self::Call, + "callf" => Self::CallExternal, + "callfd" => Self::CallDelegate, + "callfs" => Self::CallStatic, + "callaa" => Self::CallAA, + "ret" => Self::Return, + "throw" => Self::Throw, + "panic" => Self::Panic, + "push" => Self::Push, + "pop" => Self::Pop, + "ld" => Self::StorageLoad, + "st" => Self::StorageStore, + "evt.i" => Self::EventInit, + "evt" => Self::Event, + "msg.i" => Self::L1MessageInit, + "msg" => Self::L1Message, + "ctx" => Self::Context, + "and" => Self::And, + "or" => Self::Or, + "xor" => Self::Xor, + "shl" => Self::Shl, + "shr" => Self::Shr, + "rol" => Self::Rol, + "ror" => Self::Ror, + "mov" => Self::Mov, + "cmov" => Self::CMov, + input => return Err(InstructionReadError::UnknownMnemonic(input.to_owned())), + }) + } +} + +pub(crate) fn parse_mnemonic<'a, 'b>( + input: &'a str, + tag: &'a str, + num_args: usize, +) -> IResult<&'a str, (&'a str, Vec<&'a str>)> { + if num_args == 0 { + let mut parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + nom::character::complete::space0, + nom::bytes::complete::tag(tag), + nom::character::complete::space0, + nom::combinator::eof, + )); + + let (rest, result) = parser(input)?; + let tag = result.1; + return Ok((rest, (tag, vec![]))); + } + + // other cases + let mut parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + nom::character::complete::space0, + nom::bytes::complete::tag(tag), + nom::character::complete::space1, + nom::combinator::rest, + )); + + let (rest, result) = parser(input)?; + let tag = result.1; + match num_args { + 1 => Ok((rest, (tag, vec![result.3]))), + 2 => { + let (rest, result) = parse_ops_2(result.3)?; + + Ok((rest, (tag, result.to_vec()))) + } + 3 => { + let (rest, result) = parse_ops_3(result.3)?; + + Ok((rest, (tag, result.to_vec()))) + } + 4 => { + let (rest, result) = parse_ops_4(result.3)?; + + Ok((rest, (tag, result.to_vec()))) + } + _ => { + panic!("operation can not have more than 4 arguments") + } + } +} + +// returns a tag, string of all reconstructed modifiers and parsed parameters +pub(crate) fn parse_mnemonic_allow_modifiers<'a>( + input: &'a str, + tag: &'a str, + num_args: usize, +) -> IResult<&'a str, (&'a str, Vec<&'a str>, Vec<&'a str>)> { + if num_args == 0 { + let mut parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + nom::character::complete::space0, + nom::bytes::complete::tag(tag), + nom::multi::many0(all_from_tag_until_1_noconsume( + ".", + nom::branch::alt(( + nom::bytes::complete::tag("."), + nom::character::complete::space1, + )), + )), + nom::character::complete::space0, + nom::combinator::eof, + )); + + let (rest, result) = parser(input)?; + let tag = result.1; + let modifiers = result.2; + + return Ok((rest, (tag, modifiers, vec![]))); + } + + // other cases + let mut parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + nom::character::complete::space0, + nom::bytes::complete::tag(tag), + nom::multi::many0(all_from_tag_until_1_noconsume( + ".", + nom::branch::alt(( + nom::bytes::complete::tag("."), + nom::character::complete::space1, + )), + )), + nom::character::complete::space0, + nom::combinator::rest, + )); + + let (rest, result) = parser(input)?; + let tag = result.1; + let modifiers = result.2; + let args = result.4; + match num_args { + 1 => Ok((rest, (tag, modifiers, vec![args]))), + 2 => { + let (rest, result) = parse_ops_2(args)?; + + Ok((rest, (tag, modifiers, result.to_vec()))) + } + 3 => { + let (rest, result) = parse_ops_3(args)?; + + Ok((rest, (tag, modifiers, result.to_vec()))) + } + 4 => { + let (rest, result) = parse_ops_4(args)?; + + Ok((rest, (tag, modifiers, result.to_vec()))) + } + _ => { + panic!("operation can not have more than 4 arguments") + } + } +} + +// to transform something like `add! ...` to `add.set_flags`. returns `add` and `...` +pub(crate) fn parse_set_flags_modifier<'a, 'b>( + input: &'a str, +) -> IResult<&'a str, (&'a str, &'a str)> { + let mut parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + all_until1(nom::bytes::complete::tag("!")), + nom::combinator::rest, + )); + + let (rest, result) = parser(input)?; + let opcode = result.0; + let params = result.1; + Ok((rest, (opcode, params))) +} + +/// Consumes until find one of the terminators. Consumes terminator too. Outputs without terminator +pub fn all_until1<'a, E: nom::error::ParseError<&'a str>, F>( + mut termination: F, +) -> impl FnMut(&'a str) -> IResult<&'a str, &'a str, E> +where + F: nom::Parser<&'a str, &'a str, E>, +{ + move |input: &'a str| { + for i in 0..=input.len() { + let (f, s) = input.split_at(i); + match termination.parse(s) { + Ok((r, _)) => { + if i == 0 { + return Err(nom::Err::Error(E::from_error_kind( + r, + nom::error::ErrorKind::Many1, + ))); + } else { + return Ok((r, f)); + } + } + Err(_) => {} + } + } + + Err(nom::Err::Error(E::from_error_kind( + input, + nom::error::ErrorKind::Many1, + ))) + } +} + +/// Consumes until find one of the terminators. Consumes terminator too. Outputs with terminator +pub fn all_until1_include_terminator<'a, E: nom::error::ParseError<&'a str>, F>( + mut termination: F, +) -> impl FnMut(&'a str) -> IResult<&'a str, &'a str, E> +where + F: nom::Parser<&'a str, &'a str, E>, +{ + move |input: &'a str| { + for i in 0..=input.len() { + let (_, s) = input.split_at(i); + match termination.parse(s) { + Ok((r, terminator)) => { + if i == 0 { + return Err(nom::Err::Error(E::from_error_kind( + r, + nom::error::ErrorKind::Many1, + ))); + } else { + let terminator_len = terminator.len(); + let (f, _) = input.split_at(i + terminator_len); + return Ok((r, f)); + } + } + Err(_) => {} + } + } + + Err(nom::Err::Error(E::from_error_kind( + input, + nom::error::ErrorKind::Many1, + ))) + } +} + +/// Consumes until find one of the terminators. Consumes terminator too. Outputs without terminator +pub fn all_until_1_noconsume_inclusive<'a, E: nom::error::ParseError<&'a str>, F>( + mut termination: F, +) -> impl FnMut(&'a str) -> IResult<&'a str, &'a str, E> +where + F: nom::Parser<&'a str, &'a str, E>, +{ + move |input: &'a str| { + if input.is_empty() { + return Err(nom::Err::Error(E::from_error_kind( + input, + nom::error::ErrorKind::Eof, + ))); + } + for i in 1..=input.len() { + let (f, s) = input.split_at(i); + match termination.parse(s) { + Ok((r, _)) => { + if i == 0 { + return Err(nom::Err::Error(E::from_error_kind( + r, + nom::error::ErrorKind::Many1, + ))); + } else { + return Ok((s, f)); + } + } + Err(_) => {} + } + } + + Err(nom::Err::Error(E::from_error_kind( + input, + nom::error::ErrorKind::Many1, + ))) + } +} + +/// Outputs a substring between beginning tag and terminator. Doesn't consume terminator +pub fn all_from_tag_until_1_noconsume<'a, E: nom::error::ParseError<&'a str>, F>( + from: &'static str, + mut termination: F, +) -> impl FnMut(&'a str) -> IResult<&'a str, &'a str, E> +where + F: nom::Parser<&'a str, &'a str, E>, +{ + let mut subparser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + nom::bytes::complete::tag(from), + nom::combinator::rest, + )); + + move |input: &'a str| match subparser(input) { + Ok((_, (_, rest))) => { + let input = rest; + if input.is_empty() { + return Err(nom::Err::Error(E::from_error_kind( + input, + nom::error::ErrorKind::Eof, + ))); + } + for i in 1..=input.len() { + let (f, s) = input.split_at(i); + match termination.parse(s) { + Ok((r, _)) => { + if i == 0 { + return Err(nom::Err::Error(E::from_error_kind( + r, + nom::error::ErrorKind::Many1, + ))); + } else { + return Ok((s, f)); + } + } + Err(_) => {} + } + } + + Err(nom::Err::Error(E::from_error_kind( + input, + nom::error::ErrorKind::Many1, + ))) + } + Err(_e) => Err(nom::Err::Error(E::from_error_kind( + input, + nom::error::ErrorKind::Tag, + ))), + } +} + +/// Outputs a substring between beginning tag and terminator including tag and terminator. Doesn't consume terminator +pub fn all_from_tag_noconsume_until_1_noconsume<'a, E: nom::error::ParseError<&'a str>, F>( + from: &'static str, + mut termination: F, +) -> impl FnMut(&'a str) -> IResult<&'a str, &'a str, E> +where + F: nom::Parser<&'a str, &'a str, E>, +{ + let mut subparser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + nom::bytes::complete::tag(from), + nom::combinator::rest, + )); + + move |initial_input: &'a str| match subparser(initial_input) { + Ok((_, _)) => { + let input = initial_input; + if input.is_empty() { + return Err(nom::Err::Error(E::from_error_kind( + input, + nom::error::ErrorKind::Eof, + ))); + } + for i in 1..=input.len() { + let (_, s) = input.split_at(i); + match termination.parse(s) { + Ok((r, terminator)) => { + if i == 0 { + return Err(nom::Err::Error(E::from_error_kind( + r, + nom::error::ErrorKind::Many1, + ))); + } else { + let terminator_len = terminator.len(); + let (f, _) = input.split_at(i + terminator_len); + + return Ok((r, f)); + } + } + Err(_) => {} + } + } + + Err(nom::Err::Error(E::from_error_kind( + initial_input, + nom::error::ErrorKind::Many1, + ))) + } + Err(_e) => Err(nom::Err::Error(E::from_error_kind( + initial_input, + nom::error::ErrorKind::Tag, + ))), + } +} + +pub(crate) fn parse_ops_2(input: &str) -> IResult<&str, [&str; 2]> { + let mut parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + // 1 + nom::character::complete::space0, + all_until1(nom::bytes::complete::tag(",")), + nom::character::complete::space0, // may be cleanup space + // 2 + nom::combinator::rest, + )); + + let (rest, result) = parser(input)?; + + Ok((rest, [result.1, result.3])) +} + +pub(crate) fn parse_ops_3(input: &str) -> IResult<&str, [&str; 3]> { + let mut parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + // 1 + nom::character::complete::space0, + all_until1(nom::bytes::complete::tag(",")), + nom::character::complete::space0, + // 2 + all_until1(nom::bytes::complete::tag(",")), + nom::character::complete::space0, + // 3 + nom::combinator::rest, + )); + + let (rest, result) = parser(input)?; + + Ok((rest, [result.1, result.3, result.5])) +} + +pub(crate) fn parse_ops_4(input: &str) -> IResult<&str, [&str; 4]> { + let mut parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + // 1 + nom::character::complete::space0, + all_until1(nom::bytes::complete::tag(",")), + nom::character::complete::space0, + // 2 + all_until1(nom::bytes::complete::tag(",")), + nom::character::complete::space0, + // 3 + all_until1(nom::bytes::complete::tag(",")), + nom::character::complete::space0, + // 4 + nom::combinator::rest, + )); + + let (rest, result) = parser(input)?; + + Ok((rest, [result.1, result.3, result.5, result.7])) +} + +pub fn format_modifiers_into_canonical(modifiers: Vec<&str>) -> String { + if modifiers.is_empty() { + "".to_owned() + } else { + format!(".{}", modifiers.join(".")) + } +} diff --git a/crates/zkEVM-assembly/src/assembly/mnemonic/nop.rs b/crates/zkEVM-assembly/src/assembly/mnemonic/nop.rs new file mode 100644 index 0000000..8d2f369 --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/mnemonic/nop.rs @@ -0,0 +1,125 @@ +use super::*; + +pub(crate) fn parse_nop_combinator(input: &str) -> IResult<&str, String> { + let (rest, (_, _)) = parse_mnemonic(input, "nop", 0)?; + let canonical = "nop r0, r0, r0, r0".to_owned(); + + Ok((rest, canonical)) +} + +// pub(crate) fn parse_advance_sp_combinator(input: &str) -> IResult<&str, String> { +// let (rest, (_, args)) = parse_mnemonic(input, "advance_sp", 1)?; + +// // we should match args[0] as #(+-)decimal_integer +// let mut parser = nom::sequence::tuple(( +// nom::bytes::complete::tag("#"), +// nom::multi::many0(nom::branch::alt(( +// nom::bytes::complete::tag("-"), +// nom::bytes::complete::tag("+"), +// ))), +// nom::combinator::rest, +// )); +// use nom::Parser; +// let (_, result) = parser.parse(args[0])?; +// let sign_may_be = result.1; +// let abs = result.2; + +// let mut sp_shift_is_positive = true; + +// let sp_shift = if let Ok(sp_shift) = u64::from_str_radix(abs, 10) { +// sp_shift +// } else { +// return Err(nom::Err::Error(nom::error::Error::from_error_kind( +// abs, +// nom::error::ErrorKind::Digit, +// ))); +// }; + +// if sp_shift == 0 { +// return Err(nom::Err::Error(nom::error::Error::from_error_kind( +// abs, +// nom::error::ErrorKind::Digit, +// ))); +// } + +// if sign_may_be.len() == 1 && sign_may_be[0] == "-" { +// sp_shift_is_positive = false; +// } + +// // we also have to decide where to put it + +// let canonical = if sp_shift_is_positive { +// // our convention +// let sp_shift = sp_shift - 1; +// // can only be done with dst +// format!("nop r0, r0, stack+=[#{}], r0", sp_shift) +// } else { +// // our convention +// let sp_shift = sp_shift - 1; +// // better to use src +// format!("nop stack-=[#{}], r0, r0, r0", sp_shift) +// }; + +// Ok((rest, canonical)) +// } + +pub(crate) fn parse_decrease_sp_shorthard(input: &str) -> IResult<&str, String> { + // custom parser for `nop stack-=[reg + imm]` + // we do not validate that argument after `nop stack-=` is well formed + let mut parser = nom::sequence::tuple(( + nom::bytes::complete::tag("nop"), + nom::character::complete::space1, + nom::bytes::complete::tag("stack-="), + nom::combinator::rest, + )); + + use nom::Parser; + let (rest, result) = parser.parse(input)?; + let argument = result.3; + let canonical = format!("nop stack-={}, r0, r0, r0", argument); + + Ok((rest, canonical)) +} + +pub(crate) fn parse_increase_sp_shorthard(input: &str) -> IResult<&str, String> { + // custom parser for `nop stack-=[reg + imm]` + // we do not validate that argument after `nop stack-=` is well formed + let mut parser = nom::sequence::tuple(( + nom::bytes::complete::tag("nop"), + nom::character::complete::space1, + nom::bytes::complete::tag("stack+="), + nom::combinator::rest, + )); + + use nom::Parser; + let (rest, result) = parser.parse(input)?; + let argument = result.3; + let canonical = format!("nop r0, r0, stack+={}, r0", argument); + + Ok((rest, canonical)) +} + +// #[cfg(test)] +// mod test { +// use super::*; +// use crate::assembly::SimplifyNomError; + +// #[test] +// fn test_parse_sp_manipulation() { +// let example = "advance_sp #42"; +// let r = parse_advance_sp_combinator(example).simplify(); +// dbg!(r); + +// let example = "advance_sp #0"; +// let r = parse_advance_sp_combinator(example).simplify(); +// dbg!(r); + +// let example = "advance_sp #-100"; +// let r = parse_advance_sp_combinator(example).simplify(); +// dbg!(r); + +// let example = "advance_sp #+10"; +// let r = parse_advance_sp_combinator(example).simplify(); +// dbg!(r); +// } +// } diff --git a/crates/zkEVM-assembly/src/assembly/mnemonic/set_flags.rs b/crates/zkEVM-assembly/src/assembly/mnemonic/set_flags.rs new file mode 100644 index 0000000..45c9739 --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/mnemonic/set_flags.rs @@ -0,0 +1,28 @@ +use super::*; + +pub(crate) fn parse_set_flags_combinator(input: &str) -> IResult<&str, String> { + let (rest, (opcode, params)) = parse_set_flags_modifier(input)?; + let canonical = format!("{}.set_flags{}", &opcode, ¶ms); + + Ok((rest, canonical)) +} + +#[cfg(test)] +mod test { + use super::*; + use crate::assembly::SimplifyNomError; + + #[test] + fn test_canonicalize_set_flags() { + let example = "add! r2, r3, r4"; + let r = parse_set_flags_combinator(example).simplify().unwrap(); + dbg!(r); + } + + #[test] + fn test_canonicalize_set_flags2() { + let example = "sub.s! r2, r3, r4"; + let r = parse_set_flags_combinator(example).simplify().unwrap(); + dbg!(r); + } +} diff --git a/crates/zkEVM-assembly/src/assembly/mnemonic/shift.rs b/crates/zkEVM-assembly/src/assembly/mnemonic/shift.rs new file mode 100644 index 0000000..3fe6038 --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/mnemonic/shift.rs @@ -0,0 +1,66 @@ +use super::*; + +pub(crate) fn parse_shl_combinator(input: &str) -> IResult<&str, String> { + let (rest, (_, modifiers, args)) = parse_mnemonic_allow_modifiers(input, "shl", 3)?; + let canonical = format!( + "shift.shl{} {}, {}, {}", + format_modifiers_into_canonical(modifiers), + &args[0], + &args[1], + &args[2] + ); + + Ok((rest, canonical)) +} + +pub(crate) fn parse_shr_combinator(input: &str) -> IResult<&str, String> { + let (rest, (_, modifiers, args)) = parse_mnemonic_allow_modifiers(input, "shr", 3)?; + let canonical = format!( + "shift.shr{} {}, {}, {}", + format_modifiers_into_canonical(modifiers), + &args[0], + &args[1], + &args[2] + ); + + Ok((rest, canonical)) +} + +pub(crate) fn parse_rol_combinator(input: &str) -> IResult<&str, String> { + let (rest, (_, modifiers, args)) = parse_mnemonic_allow_modifiers(input, "rol", 3)?; + let canonical = format!( + "shift.rol{} {}, {}, {}", + format_modifiers_into_canonical(modifiers), + &args[0], + &args[1], + &args[2] + ); + + Ok((rest, canonical)) +} + +pub(crate) fn parse_ror_combinator(input: &str) -> IResult<&str, String> { + let (rest, (_, modifiers, args)) = parse_mnemonic_allow_modifiers(input, "ror", 3)?; + let canonical = format!( + "shift.ror{} {}, {}, {}", + format_modifiers_into_canonical(modifiers), + &args[0], + &args[1], + &args[2] + ); + + Ok((rest, canonical)) +} + +#[cfg(test)] +mod test { + use super::*; + use crate::assembly::SimplifyNomError; + + #[test] + fn test_parse_rol() { + let example = "shl.s.set_flags r2, r3, r4"; + let r = parse_shl_combinator(example).simplify().unwrap(); + dbg!(r); + } +} diff --git a/crates/zkEVM-assembly/src/assembly/mnemonic/sub.rs b/crates/zkEVM-assembly/src/assembly/mnemonic/sub.rs new file mode 100644 index 0000000..117188b --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/mnemonic/sub.rs @@ -0,0 +1,15 @@ +use super::*; + +pub(crate) fn parse_sub_combinator(input: &str) -> IResult<&str, String> { + let (rest, (_, args)) = parse_mnemonic(input, "sub", 3)?; + let canonical = format!("sub {}, {}, {}", &args[0], &args[1], &args[2]); + + Ok((rest, canonical)) +} + +pub(crate) fn parse_sub_swapped_combinator(input: &str) -> IResult<&str, String> { + let (rest, (_, args)) = parse_mnemonic(input, "sub.s", 3)?; + let canonical = format!("sub.s {}, {}, {}", &args[0], &args[1], &args[2]); + + Ok((rest, canonical)) +} diff --git a/crates/zkEVM-assembly/src/assembly/mnemonic/uma.rs b/crates/zkEVM-assembly/src/assembly/mnemonic/uma.rs new file mode 100644 index 0000000..5345a50 --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/mnemonic/uma.rs @@ -0,0 +1,86 @@ +use super::*; + +pub(crate) fn parse_uma_heap_read_combinator(input: &str) -> IResult<&str, String> { + let (rest, (_, args)) = parse_mnemonic(input, "ld.1", 2)?; + let canonical = format!("uma.heap_read {}, r0, {}, r0", &args[0], &args[1]); + + Ok((rest, canonical)) +} + +pub(crate) fn parse_uma_aux_heap_read_combinator(input: &str) -> IResult<&str, String> { + let (rest, (_, args)) = parse_mnemonic(input, "ld.2", 2)?; + let canonical = format!("uma.aux_heap_read {}, r0, {}, r0", &args[0], &args[1]); + + Ok((rest, canonical)) +} + +pub(crate) fn parse_uma_heap_write_combinator(input: &str) -> IResult<&str, String> { + let (rest, (_, args)) = parse_mnemonic(input, "st.1", 2)?; + let canonical = format!("uma.heap_write {}, {}, r0, r0", &args[0], &args[1]); + + Ok((rest, canonical)) +} + +pub(crate) fn parse_uma_aux_heap_write_combinator(input: &str) -> IResult<&str, String> { + let (rest, (_, args)) = parse_mnemonic(input, "st.2", 2)?; + let canonical = format!("uma.aux_heap_write {}, {}, r0, r0", &args[0], &args[1]); + + Ok((rest, canonical)) +} + +pub(crate) fn parse_uma_fat_ptr_read_combinator(input: &str) -> IResult<&str, String> { + let (rest, (_, args)) = parse_mnemonic(input, "ld", 2)?; + let canonical = format!("uma.fat_ptr_read {}, r0, {}, r0", &args[0], &args[1]); + + Ok((rest, canonical)) +} + +pub(crate) fn parse_uma_heap_read_increment_combinator(input: &str) -> IResult<&str, String> { + let (rest, (_, args)) = parse_mnemonic(input, "ld.1.inc", 3)?; + let canonical = format!( + "uma.heap_read.inc {}, r0, {}, {}", + &args[0], &args[1], &args[2] + ); + + Ok((rest, canonical)) +} + +pub(crate) fn parse_uma_aux_heap_read_increment_combinator(input: &str) -> IResult<&str, String> { + let (rest, (_, args)) = parse_mnemonic(input, "ld.2.inc", 3)?; + let canonical = format!( + "uma.aux_heap_read.inc {}, r0, {}, {}", + &args[0], &args[1], &args[2] + ); + + Ok((rest, canonical)) +} + +pub(crate) fn parse_uma_heap_write_increment_combinator(input: &str) -> IResult<&str, String> { + let (rest, (_, args)) = parse_mnemonic(input, "st.1.inc", 3)?; + let canonical = format!( + "uma.heap_write.inc {}, {}, {}, r0", + &args[0], &args[1], &args[2] + ); + + Ok((rest, canonical)) +} + +pub(crate) fn parse_uma_aux_heap_write_increment_combinator(input: &str) -> IResult<&str, String> { + let (rest, (_, args)) = parse_mnemonic(input, "st.2.inc", 3)?; + let canonical = format!( + "uma.aux_heap_write.inc {}, {}, {}, r0", + &args[0], &args[1], &args[2] + ); + + Ok((rest, canonical)) +} + +pub(crate) fn parse_uma_fat_ptr_read_increment_combinator(input: &str) -> IResult<&str, String> { + let (rest, (_, args)) = parse_mnemonic(input, "ld.inc", 3)?; + let canonical = format!( + "uma.fat_ptr_read.inc {}, r0, {}, {}", + &args[0], &args[1], &args[2] + ); + + Ok((rest, canonical)) +} diff --git a/crates/zkEVM-assembly/src/assembly/mod.rs b/crates/zkEVM-assembly/src/assembly/mod.rs new file mode 100644 index 0000000..b8d7651 --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/mod.rs @@ -0,0 +1,423 @@ +//! +//! The assembly entity. +//! + +use std::convert::TryInto; + +// pub mod bytecode; +// pub mod data_operation; +pub mod constants; +pub mod instruction; +pub mod linking; +pub mod mnemonic; +pub mod operand; +pub mod parse; +pub mod section; + +use self::instruction::Instruction; +use self::section::ParsedSection; +use crate::assembly::linking::AlignedRawBytecode; +use crate::assembly::mnemonic::all_until1; +use crate::error::{AssemblyParseError, Error}; +use crate::{get_encoding_mode, InstructionReadError, RunningVmEncodingMode}; +use std::collections::{HashMap, HashSet}; +use std::convert::TryFrom; +use std::fs; +use std::io::Read; +use std::path::PathBuf; + +use zkevm_opcode_defs::{Condition, DecodedOpcode}; + +use nom::{IResult, Parser}; +use sha3::Digest; + +use self::operand::FullOperand; + +trait SimplifyNomError { + fn simplify(self) -> Result<(I, O), I>; +} + +impl SimplifyNomError for nom::IResult { + fn simplify(self) -> Result<(I, O), I> { + match self { + Ok((rest, result)) => Ok((rest, result)), + Err(nom::Err::Error(nom::error::Error { input, code: _ })) => Err(input), + _ => { + unreachable!() + } + } + } +} + +#[track_caller] +pub(crate) fn try_parse_opcode_and_modifiers( + input: &str, +) -> Result<(&str, (&str, HashSet<&str>)), InstructionReadError> { + let mut parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + nom::character::complete::space0, + all_until1(nom::branch::alt(( + nom::combinator::eof, + nom::character::complete::line_ending, + nom::character::complete::space1, + ))), + nom::combinator::rest, + // all_until1( + // nom::branch::alt(( + // nom::combinator::eof, + // nom::character::complete::line_ending, + // )) + // ), + )); + + let (_, result) = parser + .parse(input) + .map_err(|_| InstructionReadError::UnexpectedInstruction(input.to_owned()))?; + let opcode_body = result.1; + let operands_body = result.2; + + // now try to parse the opcode body into the reference opcode and potentially some modifiers + let mut parser_with_modifiers = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + // body + all_until1(nom::branch::alt(( + nom::bytes::complete::tag("."), + nom::character::complete::space1, + ))), + // and now potentially many of modifiers except the last one + // because there is no space at the end + nom::multi::many0(all_until1(nom::branch::alt(( + nom::bytes::complete::tag("."), + nom::character::complete::space1, + )))), + nom::combinator::rest, + )); + + let mut parsers_without_modifiers = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + // may be body + nom::multi::many0(all_until1(nom::branch::alt(( + nom::bytes::complete::tag("."), + nom::character::complete::space1, + )))), + nom::combinator::rest, + )); + + let (opcode, mods) = match parser_with_modifiers + .parse(opcode_body) + .map_err(|_| InstructionReadError::UnexpectedInstruction(input.to_owned())) + { + Ok((_, result)) => { + let opcode = result.0; + + if !self::instruction::ALL_CANONICAL_OPCODES.contains(&opcode) { + return Err(InstructionReadError::UnexpectedInstruction( + input.to_owned(), + )); + } + let mut modifiers = result.1; + modifiers.push(result.2); + + let mut mods = HashSet::<&str>::with_capacity(modifiers.len()); + for m in modifiers.into_iter() { + if mods.contains(&m) { + return Err(InstructionReadError::UnexpectedInstruction( + input.to_owned(), + )); + } else { + mods.insert(m); + } + } + + (opcode, mods) + } + Err(_) => { + // try body only + let (_, result) = parsers_without_modifiers + .parse(opcode_body) + .map_err(|_| InstructionReadError::UnexpectedInstruction(input.to_owned()))?; + let garbage = result.0; + if !garbage.is_empty() { + return Err(InstructionReadError::UnexpectedInstruction( + input.to_owned(), + )); + } + let opcode = result.1; + + (opcode, HashSet::new()) + } + }; + + Ok((operands_body, (opcode, mods))) +} + +use crate::assembly::section::LabeledGlobal; +use zkevm_opcode_defs::decoding::encoding_mode_production::EncodingModeProduction; +use zkevm_opcode_defs::decoding::{EncodingModeTesting, VmEncodingMode}; + +/// +/// The assembly entity. +/// +/// +#[derive(Debug, Clone)] +pub struct Assembly { + /// The contract metadata hash. + pub metadata_hash: Option<[u8; 32]>, + /// The instructions vector. + pub bytecode: Vec, + pub pc_line_mapping: HashMap, + pub function_labels: HashMap, + + pub assembly_code: String, + pub(crate) global_variables: HashMap, + pub(crate) parsed_sections: Vec, + pub(crate) labels: HashSet, +} + +impl Assembly { + /// The instructions vector default capacity. + pub const INSTRUCTIONS_DEFAULT_CAPACITY: usize = 1024; + /// The labels hashmap default capacity. + pub const LABELS_DEFAULT_CAPACITY: usize = 64; + + pub fn compile_to_bytecode(&mut self) -> Result, InstructionReadError> { + match get_encoding_mode() { + RunningVmEncodingMode::Production => { + self.compile_to_bytecode_for_mode::<8, EncodingModeProduction>() + } + RunningVmEncodingMode::Testing => { + self.compile_to_bytecode_for_mode::<16, EncodingModeTesting>() + } + } + } + + pub fn compile_to_bytecode_for_mode>( + &mut self, + ) -> Result, InstructionReadError> { + use crate::assembly::linking::Linker; + let linker = Linker::::new(); + + if self.bytecode.is_empty() { + let (unpacked_bytecode, pc_line_mapping, function_labels) = linker + .link( + self.parsed_sections.clone(), + self.labels.clone(), + self.metadata_hash, + ) + .map_err(InstructionReadError::AssemblyParseError)?; + + self.bytecode = unpacked_bytecode; + self.pc_line_mapping = pc_line_mapping; + self.function_labels = function_labels; + } + + let mut bytecode = Vec::with_capacity(self.bytecode.len()); + let opcodes_per_word = 32 / N; + assert!(32 % N == 0, "unaligned bytecode packing"); + + let mut num_instructions = 0u64; + + for el in self.bytecode.iter().cloned() { + match el { + AlignedRawBytecode::Instructions(instructions) => { + assert_eq!(opcodes_per_word, instructions.len()); + let mut result = [0u8; 32]; + for (i, instr) in instructions.into_iter().enumerate() { + let t: DecodedOpcode = instr.try_into()?; + let serialized_bytecode = t.serialize_as_bytes(); + result[N * i..N * (i + 1)].copy_from_slice(&serialized_bytecode); + } + bytecode.push(result); + num_instructions += opcodes_per_word as u64; + } + AlignedRawBytecode::Data(data) => { + let serialized = data.serialize(); + bytecode.push(serialized); + } + } + } + + use zkevm_opcode_defs::decoding::AllowedPcOrImm; + + if num_instructions > E::PcOrImm::max().as_u64() { + return Err(InstructionReadError::TooManyOpcodes( + E::PcOrImm::max().as_u64(), + num_instructions, + )); + } + + if bytecode.len() as u64 > E::PcOrImm::max().as_u64() { + return Err(InstructionReadError::CodeIsTooLong( + E::PcOrImm::max().as_u64(), + num_instructions, + )); + } + + Ok(bytecode) + } + + pub fn instructions>( + &self, + ) -> Result, InstructionReadError> { + // dirty hack + let mut tmp = self.clone(); + let _ = tmp.compile_to_bytecode_for_mode::()?; + let mut result = Vec::with_capacity(tmp.bytecode.len() * 4); + for el in tmp.bytecode.iter() { + match el { + AlignedRawBytecode::Instructions(instructions) => { + result.extend_from_slice(&instructions[..]); + } + AlignedRawBytecode::Data(_) => {} + } + } + + Ok(result) + } + + pub fn opcodes>( + &self, + ) -> Result>, InstructionReadError> { + // dirty hack + let mut tmp = self.clone(); + let _ = tmp.compile_to_bytecode_for_mode::()?; + let mut result = Vec::with_capacity(tmp.bytecode.len() * 4); + for el in tmp.bytecode.iter().cloned() { + match el { + AlignedRawBytecode::Instructions(instructions) => { + for (_i, instr) in instructions.into_iter().enumerate() { + let t: DecodedOpcode = instr.try_into().unwrap(); + result.push(t); + } + } + AlignedRawBytecode::Data(_) => {} + } + } + + Ok(result) + } + + pub fn from_string( + input: String, + metadata_hash: Option<[u8; 32]>, + ) -> Result { + use crate::assembly::parse::*; + let newline = ['\r', '\n']; + let text = input.trim_matches(&newline[..]); + + let (a, b) = split_into_sections(text)?; + let (_, sections, labels) = parse_sections(a, b)?; + + let new = Self { + metadata_hash, + bytecode: vec![], + assembly_code: text.to_owned(), + pc_line_mapping: HashMap::new(), + function_labels: HashMap::new(), + global_variables: HashMap::new(), + parsed_sections: sections, + labels, + }; + + Ok(new) + } +} + +impl TryFrom for Assembly { + type Error = Error; + + fn try_from(path: PathBuf) -> Result { + let mut file = fs::File::open(&path).map_err(Error::FileOpening)?; + let size = fs::metadata(&path).map_err(Error::FileMetadata)?.len() as usize; + let mut text = String::with_capacity(size); + file.read_to_string(&mut text).map_err(Error::FileReading)?; + Ok(Self::try_from(text)?) + } +} + +#[derive(Debug, PartialEq)] +pub struct Wrapper { + line_number: usize, + line: T, +} + +lazy_static::lazy_static! { + pub(crate) static ref PADDING_INSTRUCTION: Instruction = { + Instruction::Invalid(crate::assembly::instruction::invalid::Invalid { + condition: crate::assembly::instruction::condition::ConditionCase( + Condition::Always + ) + }) + }; +} + +impl TryFrom for Assembly { + type Error = AssemblyParseError; + + fn try_from(input: String) -> Result { + let metadata_hash = sha3::Keccak256::digest(input.as_bytes()).into(); + Self::from_string(input, Some(metadata_hash)) + } +} + +fn trim_comments(str: &str) -> &str { + str.trim().split(';').next().unwrap_or("") +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn parse_full_assembly_line() { + let asm = "sub.s r1, r2, r3"; + + let res = try_parse_opcode_and_modifiers(asm).unwrap(); + dbg!(res); + } + + use crate::assembly::parse::test::TEST_ASSEMBLY_0; + + #[test] + fn test_simple_assembly() { + let mut assembly = Assembly::try_from(TEST_ASSEMBLY_0.to_owned()).unwrap(); + dbg!(&assembly); + let _ = assembly.compile_to_bytecode().unwrap(); + } + + const TMP: &str = r#".text + .file "Test_26" + .rodata.cst32 + .p2align 5 +CPI0_0: + .cell 16777184 +CPI0_1: + .cell 16777152 +CPI0_2: + .cell 4294967297 + .text + .globl __entry +__entry: +.func_begin0: + nop stack+=[7] + add @CPI0_0[0], r0, r1 + jump @__label + add @__label, r0, r4 + jump r4 +__label: + add 1, r0, r1 + near_call r0, @__label, @__eh + ret.ok.to_label r0, @__label +__eh: + ret.panic r0 + sub.s @__eh, r0, r1 + jump r1 + far_call r0, r0, @__eh + + .note.GNU-stack"#; + + #[test] + fn test_parse_tmp() { + let mut assembly = Assembly::try_from(TMP.to_owned()).unwrap(); + let _ = assembly.compile_to_bytecode().unwrap(); + let instructions = assembly.opcodes::<8, EncodingModeProduction>().unwrap(); + dbg!(&instructions); + } +} diff --git a/crates/zkEVM-assembly/src/assembly/operand/mod.rs b/crates/zkEVM-assembly/src/assembly/operand/mod.rs new file mode 100644 index 0000000..8916521 --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/operand/mod.rs @@ -0,0 +1,424 @@ +//! +//! The zkEVM register. +//! +//! +use nom::{ + self, + bytes::complete::{tag, take_until, take_while1, take_while_m_n}, + multi::many_m_n, + AsChar, +}; + +use nom::error::{Error, ErrorKind}; + +use std::{convert::TryFrom, num::ParseIntError}; + +use crate::error::InstructionReadError; + +use zkevm_opcode_defs::{ImmMemHandlerFlags, RegOrImmFlags}; + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum FullOperand { + /// Full including all memory modifiers + Full(GenericOperand), + /// Use value at register + Register(RegisterOperand), + /// Constant and potentially offset + Constant(ConstantOperand), + /// Global variable on the stack + GlobalVariable(GlobalVariable), +} + +/// +/// Structure representing address of the constant. +/// +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct ConstantOperand { + /// Label of the constant + pub label: String, + /// Register to use it offset computation + pub register: RegisterOperand, + /// Offset to the constant label + pub immediate: u64, +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct GlobalVariable { + /// Label of the constant + pub label: String, + /// Register to use it offset computation + pub register: RegisterOperand, + /// Offset to the constant label + pub immediate: u64, +} + +/// +/// Structure representing address in memory. +/// +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct GenericOperand { + pub r#type: ImmMemHandlerFlags, + /// Offset to apply to sp for Stack memory and memory address for other types of memory + pub immediate: u64, + /// Additional offset to apply + pub register: RegisterOperand, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub enum RegisterOperand { + /// The special null/void register. + Null, + /// The general purpose register. 1-based. + Register(u8), +} + +/// +/// Structure representing non-memory operand +/// +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] +pub struct NonMemoryOperand { + pub r#type: RegOrImmFlags, + /// Offset to apply to sp for Stack memory and memory address for other types of memory + pub immediate: u64, + /// Additional offset to apply + pub register: RegisterOperand, +} + +impl NonMemoryOperand { + pub fn as_register_operand( + self, + index: usize, + ) -> Result { + match self.r#type { + RegOrImmFlags::UseRegOnly => Ok(self.register), + RegOrImmFlags::UseImm16Only => { + Err(InstructionReadError::InvalidRegImmInPlaceOfReg { index, found: self }) + } + } + } +} + +fn is_imm(input: &str) -> (&str, bool) { + let t = tag("#")(input); + match t { + Ok((input, _)) => (input, true), + Err(nom::Err::Error(Error { + input, + code: ErrorKind::Tag, + })) => (input, false), + _ => { + unreachable!() + } + } +} + +fn is_register(input: &str) -> (&str, bool, &str) { + let mut reg_parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + nom::character::complete::space0, + tag("r"), + take_while_m_n(1, 2, |el: char| el.is_ascii_digit()), + )); + + match reg_parser(input) { + Ok((rest, result)) => { + let reg_raw = result.2; + + (rest, true, reg_raw) + } + _ => (input, false, ""), + } +} + +fn is_label(input: &str) -> (&str, bool, &str) { + let label_name_parser = + take_while1(|c: char| c.is_alphanum() || (c.is_ascii() && (c as u8) == b"_"[0])); + let mut label_parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + nom::character::complete::space0, + tag("."), + label_name_parser, + )); + + let label_name_parser = + take_while1(|c: char| c.is_alphanum() || (c.is_ascii() && (c as u8) == b"_"[0])); + let mut pseudo_label_parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + nom::character::complete::space0, + tag("."), + label_name_parser, + nom::sequence::pair(tag("["), take_until("]")), + )); + + // we need to parse .label, but not .label[] that will be handled by other cases + + match pseudo_label_parser(input) { + Ok(_) => (input, false, ""), + _ => match label_parser(input) { + Ok((rest, result)) => { + let label_raw = result.2; + + (rest, true, label_raw) + } + _ => (input, false, ""), + }, + } +} + +fn has_tag<'a>(input: &'a str, tag: &str) -> (bool, &'a str) { + match nom::bytes::complete::tag::<_, _, nom::error::Error<_>>(tag)(input) { + Ok((rest, _)) => (true, rest), + Err(nom::Err::Error(Error { + input, + code: ErrorKind::Tag, + })) => (false, input), + _ => { + unreachable!() + } + } +} + +fn try_memory_offset<'a>( + input: &'a str, +) -> Result<(&'a str, Vec<&'a str>, Vec<&'a str>, Vec<&'a str>), ()> { + let reg_parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + nom::character::complete::space0, + tag("r"), + take_while_m_n(1, 2, |el: char| el.is_ascii_digit()), + )); + + let sign_parser = nom::sequence::tuple(( + nom::character::complete::space0, + many_m_n(0, 1, nom::branch::alt((tag("+"), tag("-")))), + nom::character::complete::space0, + )); + + let mut parser = nom::sequence::tuple(( + many_m_n(0, 1, reg_parser), + nom::character::complete::space0, + sign_parser, + )); + + match parser(input) { + Ok((rest, result)) => { + let (reg_parsing, _, sign_parsing) = result; + let reg_may_be: Vec<_> = reg_parsing.into_iter().map(|el| el.2).collect(); + let sign_may_be = sign_parsing.1; + + if rest.is_empty() { + return Ok((rest, reg_may_be, sign_may_be, vec![])); + } + + // otherwise try to parse imm + match many_m_n::<_, _, nom::error::Error<_>, _>( + 0, + 1, + nom::character::complete::alphanumeric0, + )(rest) + { + Ok((rest, result)) => Ok((rest, reg_may_be, sign_may_be, result)), + Err(nom::Err::Error(Error { input, code })) => { + dbg!(input); + dbg!(code); + Err(()) + } + _ => Err(()), + } + } + _ => Err(()), + } +} + +fn try_immediate<'a>(input: &'a str) -> Result<(&'a str, u64), ParseIntError> { + let (has_prefix, input) = has_tag(input, "0x"); + if has_prefix { + match u64::from_str_radix(input, 16) { + Ok(imm) => Ok(("", imm)), + Err(e) => Err(e), + } + } else { + let (has_prefix, input) = has_tag(input, "0b"); + if has_prefix { + match u64::from_str_radix(input, 2) { + Ok(imm) => Ok(("", imm)), + Err(e) => Err(e), + } + } else { + match u64::from_str_radix(input, 10) { + Ok(imm) => Ok(("", imm)), + Err(e) => Err(e), + } + } + } +} + +impl FullOperand { + pub fn as_register_operand( + self, + index: usize, + ) -> Result { + match self { + FullOperand::Register(reg) => Ok(reg), + other => Err(InstructionReadError::InvalidOperandForRegLocation { + index, + found: other, + }), + } + } + + pub fn as_non_memory_operand( + self, + index: usize, + ) -> Result { + match self { + FullOperand::Full(operand) => Ok(operand.as_non_memory_operand()), + other => Err(InstructionReadError::InvalidOperandForRegImmLocation { + index, + found: other, + }), + } + } + + pub fn as_generic_operand(self, index: usize) -> Result { + match self { + FullOperand::Full(operand) => Ok(operand), + other => Err(InstructionReadError::InvalidOperandForGenericLocation { + index, + found: other, + }), + } + } + + pub fn as_constant_operand( + self, + index: usize, + ) -> Result { + match self { + FullOperand::Constant(operand) => Ok(operand), + other => Err(InstructionReadError::InvalidOperandForLabelLocation { + index, + found: other, + }), + } + } + + pub fn as_global_variable(self, index: usize) -> Result { + match self { + FullOperand::GlobalVariable(operand) => Ok(operand), + other => Err(InstructionReadError::InvalidOperandForLabelLocation { + index, + found: other, + }), + } + } + + pub fn as_immediate(self, index: usize) -> Result { + match self { + FullOperand::Full(GenericOperand { + r#type: ImmMemHandlerFlags::UseImm16Only, + immediate: imm, + register: RegisterOperand::Null, + }) => Ok(imm), + other => Err(InstructionReadError::InvalidArgument { + index, + expected: "label or immediate", + found: format!("{:?}", other), + }), + } + } +} + +impl GenericOperand { + pub fn as_word_offset_into_code_page(self) -> u64 { + let GenericOperand { + r#type, + immediate, + register, + } = self; + match register { + RegisterOperand::Null => {} + _ => { + panic!("Invalid linking result") + } + } + match r#type { + ImmMemHandlerFlags::UseCodePage => immediate, + _ => { + panic!("Invalid linking result") + } + } + } + + pub fn as_pc_offset(self) -> u64 { + let GenericOperand { + r#type, + immediate, + register, + } = self; + match register { + RegisterOperand::Null => {} + _ => { + panic!("Invalid linking result") + } + } + match r#type { + ImmMemHandlerFlags::UseImm16Only => immediate, + _ => { + panic!("Invalid linking result") + } + } + } + + pub fn as_non_memory_operand(self) -> NonMemoryOperand { + match self.r#type { + ImmMemHandlerFlags::UseRegOnly => { + assert!(self.immediate == 0); + NonMemoryOperand { + register: self.register, + r#type: RegOrImmFlags::UseRegOnly, + immediate: 0, + } + } + ImmMemHandlerFlags::UseImm16Only => { + match self.register { + RegisterOperand::Null => {} + _ => { + panic!("Register must be zero") + } + } + NonMemoryOperand { + register: self.register, + r#type: RegOrImmFlags::UseImm16Only, + immediate: self.immediate, + } + } + _ => { + panic!("Invalid reg/imm operand") + } + } + } +} + +impl RegisterOperand { + /// + /// Whether the register is the null (`r0`) one. + /// + pub fn is_void(&self) -> bool { + matches!(self, Self::Null) + } +} + +impl TryFrom<&str> for RegisterOperand { + type Error = InstructionReadError; + + fn try_from(input: &str) -> Result { + let index: u8 = input + .parse() + .map_err(|e| InstructionReadError::InvalidNumber(input.to_owned(), e))?; + if index == 0 { + return Ok(Self::Null); + } + if index as usize > zkevm_opcode_defs::REGISTERS_COUNT { + return Err(InstructionReadError::UnknownRegister(input.to_owned())); + } + + Ok(Self::Register(index)) + } +} diff --git a/crates/zkEVM-assembly/src/assembly/parse/addressing.rs b/crates/zkEVM-assembly/src/assembly/parse/addressing.rs new file mode 100644 index 0000000..b7ec3d9 --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/parse/addressing.rs @@ -0,0 +1,764 @@ +use super::*; + +use crate::assembly::mnemonic::all_from_tag_until_1_noconsume; +use crate::assembly::mnemonic::all_until_1_noconsume_inclusive; +use crate::assembly::operand::ConstantOperand; +use crate::assembly::operand::GenericOperand; +use crate::assembly::operand::GlobalVariable; +use crate::RegisterOperand; +use nom::error::ParseError; +use zkevm_opcode_defs::ImmMemHandlerFlags; + +pub(crate) fn parse_full_operand<'a>(input: &'a str) -> IResult<&'a str, FullOperand> { + // parse a single operand + // first try to get constant + if let Ok((_, imm)) = parse_immediate(input) { + let operand = FullOperand::Full(GenericOperand { + r#type: ImmMemHandlerFlags::UseImm16Only, + register: RegisterOperand::Null, + immediate: imm, + }); + + return Ok(("", operand)); + } + + let mut addressing = None; + let mut body = None; + let mut label = None; + + // try to decide addressing mode + let mut parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + nom::bytes::complete::tag("stack+="), + nom::combinator::rest, + )); + if let Ok((_, result)) = parser.parse(input) { + addressing = Some(ImmMemHandlerFlags::UseStackWithPushPop); + body = Some(result.1); + } + + if addressing.is_none() { + let mut parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + nom::bytes::complete::tag("stack-="), + nom::combinator::rest, + )); + if let Ok((_, result)) = parser.parse(input) { + addressing = Some(ImmMemHandlerFlags::UseStackWithPushPop); + body = Some(result.1); + } + } + + if addressing.is_none() { + let mut parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + nom::bytes::complete::tag("stack="), + nom::combinator::rest, + )); + if let Ok((_, result)) = parser.parse(input) { + addressing = Some(ImmMemHandlerFlags::UseAbsoluteOnStack); + body = Some(result.1); + } + } + + if addressing.is_none() { + let mut parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + nom::bytes::complete::tag("stack-"), + nom::combinator::rest, + )); + if let Ok((_, result)) = parser.parse(input) { + addressing = Some(ImmMemHandlerFlags::UseStackWithOffset); + body = Some(result.1); + } + } + + if addressing.is_none() { + let mut parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + nom::bytes::complete::tag("stack+"), + nom::combinator::rest, + )); + if let Ok((_, result)) = parser.parse(input) { + addressing = Some(ImmMemHandlerFlags::UseStackWithOffset); + body = Some(result.1); + } + } + if addressing.is_none() { + let mut parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + nom::bytes::complete::tag("stack"), + nom::combinator::rest, + )); + if let Ok((_, result)) = parser.parse(input) { + addressing = Some(ImmMemHandlerFlags::UseAbsoluteOnStack); + body = Some(result.1); + } + } + // labeled constant + if addressing.is_none() { + let mut parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + all_from_tag_until_1_noconsume("@", nom::bytes::complete::tag("[")), + nom::combinator::rest, + )); + if let Ok((_, result)) = parser.parse(input) { + addressing = Some(ImmMemHandlerFlags::UseCodePage); + label = Some(result.0); + body = Some(result.1); + } + } + + if let Some(addressing) = addressing { + let body = body.unwrap(); + + if let Some(label) = label { + // labeled constant + assert_eq!(addressing, ImmMemHandlerFlags::UseCodePage); + let (_, operand) = parse_relative_addressing(body, addressing)?; + match operand { + FullOperand::Full(operand) => { + let operand = FullOperand::Constant(ConstantOperand { + label: label.to_owned(), + register: operand.register, + immediate: operand.immediate, + }); + + Ok(("", operand)) + } + a => { + panic!( + "unsupported operand {:?} for addressing {:?} and code label {}", + a, addressing, label + ); + } + } + } else { + let (_, operand) = parse_relative_addressing(body, addressing)?; + + Ok(("", operand)) + } + } else { + // register or may be imm + let (_, (register, imm)) = parse_absolute_addressing_single(input)?; + + let operand = if register.is_void() { + if imm != 0 { + FullOperand::Full(GenericOperand { + r#type: ImmMemHandlerFlags::UseImm16Only, + register, + immediate: imm, + }) + } else { + FullOperand::Full(GenericOperand { + r#type: ImmMemHandlerFlags::UseRegOnly, + register, + immediate: 0, + }) + } + } else { + if imm != 0 { + return Err(nom::Err::Error(nom::error::Error::from_error_kind( + input, + nom::error::ErrorKind::Digit, + ))); + } + + FullOperand::Full(GenericOperand { + r#type: ImmMemHandlerFlags::UseRegOnly, + register, + immediate: 0, + }) + }; + + Ok(("", operand)) + } +} + +pub(crate) fn parse_relative_addressing<'a>( + input: &'a str, + addressing_mode: ImmMemHandlerFlags, +) -> IResult<&'a str, FullOperand> { + // we parse everything in brackets + + let (_, absolute_addressing) = parse_brackets_content(input)?; + + // let + // dbg!(tmp); + + // let (_, (reg, imm)) = parse_absolute_addressing_single(absolute_addressing)?; + + let (rest, tmp) = parse_arith_separated(absolute_addressing)?; + + let operand = match addressing_mode { + ImmMemHandlerFlags::UseRegOnly | ImmMemHandlerFlags::UseImm16Only => { + panic!("Trying to parse relative addressing, while addressing mode is absolute") + } + _ => { + let (_, operand) = parse_absolute_addressing_from_list(addressing_mode, tmp)?; + + operand + } // GenericOperand { + // r#type: operand, + // immediate: imm, + // register: reg, + // }, + }; + + Ok((rest, operand)) +} + +pub(crate) fn parse_absolute_addressing_from_list<'a>( + operand_type: ImmMemHandlerFlags, + mut input: Vec<(Option<&'a str>, &'a str)>, +) -> IResult<&'a str, FullOperand> { + // we try to pull out parts like + // @global_var[..], + // + rX (there can not be -rX) + // +- imm + + let mut pos_to_remove = None; + let mut register = RegisterOperand::Null; + for (idx, (sign, chunk)) in input.iter().enumerate() { + // try to get rX + let mut register_parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + all_from_tag_until_1_noconsume( + "r", + nom::branch::alt((nom::character::complete::space1, nom::combinator::eof)), + ), + nom::combinator::rest, + )); + + if let Ok((_, (register_index, _))) = register_parser.parse(chunk) { + match u64::from_str_radix(register_index, 10) { + Ok(imm) => { + if imm == 0 { + register = RegisterOperand::Null; + } else { + register = RegisterOperand::Register(imm as u8); + } + if let Some(sign) = sign { + if sign != &"+" { + return Err(nom::Err::Error(nom::error::Error::from_error_kind( + sign, + nom::error::ErrorKind::Complete, + ))); + } + } + + pos_to_remove = Some(idx); + break; + } + Err(_) => { + return Err(nom::Err::Error(nom::error::Error::from_error_kind( + chunk, + nom::error::ErrorKind::Digit, + ))); + } + } + } + } + + if let Some(pos) = pos_to_remove { + input.remove(pos); + } + + // if let Some(pos_to_remove) = pos_to_remove { + // input.remove(pos_to_remove); + // } else { + // return Err(nom::Err::Error(nom::error::Error::from_error_kind( + // "invalid argument", + // nom::error::ErrorKind::Complete, + // ))); + // } + + // try to get global variable + + let mut pos_to_remove = None; + let mut global = None; + + for (idx, (sign, chunk)) in input.iter().enumerate() { + // try to get @global_var[..] + let mut global_var_parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + all_from_tag_until_1_noconsume( + "@", + nom::branch::alt((nom::character::complete::space1, nom::combinator::eof)), + ), + nom::combinator::rest, + )); + + if let Ok((_, (global_name, _))) = global_var_parser.parse(chunk) { + if let Some(sign) = sign { + if sign != &"+" { + return Err(nom::Err::Error(nom::error::Error::from_error_kind( + sign, + nom::error::ErrorKind::Complete, + ))); + } + } + + global = Some(global_name.to_string()); + pos_to_remove = Some(idx); + break; + } + } + + if let Some(pos) = pos_to_remove { + input.remove(pos); + } + + let mut pos_to_remove = None; + let mut imm = 0u64; + for (idx, (mut _sign, chunk)) in input.iter().enumerate() { + let immediate_body = chunk; + match u64::from_str_radix(immediate_body, 10) { + Ok(parsed_imm) => { + imm = parsed_imm; + pos_to_remove = Some(idx); + break; + } + Err(_) => { + continue; + // let err: IResult<&'a str, FullOperand> = Err(nom::Err::Error(nom::error::Error::from_error_kind( + // chunk, + // nom::error::ErrorKind::Digit, + // ))); + // may_be_err = Some(err); + } + } + } + + if let Some(pos) = pos_to_remove { + input.remove(pos); + } + + if !input.is_empty() { + return Err(nom::Err::Error(nom::error::Error::from_error_kind( + "input was not consumed in full", + nom::error::ErrorKind::Complete, + ))); + } + + let full_operand = if let Some(global) = global { + let operand = GlobalVariable { + label: global, + register, + immediate: imm, + }; + + FullOperand::GlobalVariable(operand) + } else { + let operand = GenericOperand { + r#type: operand_type, + register, + immediate: imm, + }; + + FullOperand::Full(operand) + }; + + Ok(("", full_operand)) +} + +fn parse_brackets_content<'a>(input: &'a str) -> IResult<&'a str, &'a str> { + // we parse everything in brackets + + let mut parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + nom::bytes::complete::tag("["), + all_until1(nom::bytes::complete::tag("]")), + nom::combinator::rest, + )); + + let (_, result) = parser(input)?; + + Ok((result.2, result.1)) +} + +pub(crate) fn parse_absolute_addressing_single<'a>( + input: &'a str, +) -> IResult<&str, (RegisterOperand, u64)> { + // we want either rX +/- imm + + // so we want may be space | may be rX | may be space | may be + or - | may be space | may be immediate + + let mut parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + nom::character::complete::space0, + nom::combinator::rest, + )); + + let (_, (_, mut rest)) = parser(input)?; + + // try to get rX + let mut register_parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + all_from_tag_until_1_noconsume( + "r", + nom::branch::alt(( + nom::character::complete::space1, + nom::bytes::complete::tag("+"), + nom::bytes::complete::tag("-"), + nom::combinator::eof, + )), + ), + nom::combinator::rest, + )); + + let register = if let Ok((_, (register_index, tail))) = register_parser.parse(rest) { + rest = tail; + + match u64::from_str_radix(register_index, 10) { + Ok(imm) => { + if imm == 0 { + RegisterOperand::Null + } else { + RegisterOperand::Register(imm as u8) + } + } + Err(_) => { + return Err(nom::Err::Error(nom::error::Error::from_error_kind( + rest, + nom::error::ErrorKind::Digit, + ))); + } + } + } else { + RegisterOperand::Null + }; + + // try to get immediate + + // first try the combination of rX +/- imm + let mut imm_parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + nom::character::complete::space0, + nom::branch::alt(( + nom::bytes::complete::tag("+"), + nom::bytes::complete::tag("-"), + )), + nom::character::complete::space0, + nom::combinator::rest, + )); + + let immediate = if let Ok((_, (_, tag, _, tail))) = imm_parser.parse(rest) { + let immediate_body = tail; + + match u64::from_str_radix(immediate_body, 10) { + Ok(imm) => { + if tag == "-" { + // Do not rely on the assembler for it + imm + // (0 as Immediate).wrapping_sub(imm) + } else { + imm + } + } + Err(_) => { + return Err(nom::Err::Error(nom::error::Error::from_error_kind( + rest, + nom::error::ErrorKind::Digit, + ))); + } + } + } else if rest.is_empty() { + 0u64 + } else { + assert!(register == RegisterOperand::Null); + + // try immediate only + let mut imm_parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + nom::character::complete::space0, + all_until1(nom::combinator::eof), + nom::combinator::eof, + )); + + if let Ok((_, (_, body, _))) = imm_parser.parse(rest) { + let immediate_body = body; + + match u64::from_str_radix(immediate_body, 10) { + Ok(imm) => imm, + Err(_) => { + return Err(nom::Err::Error(nom::error::Error::from_error_kind( + rest, + nom::error::ErrorKind::Digit, + ))); + } + } + } else { + 0u64 + } + }; + + Ok(("", (register, immediate))) +} + +// parse a list of the form @val[t] +- rX +- imm +// into parts +pub(crate) fn parse_arith_separated<'a>( + input: &'a str, +) -> IResult<&'a str, Vec<(Option<&'a str>, &'a str)>> { + const MAX_PARTS: usize = 3; + + let mut results = vec![]; + + let mut rest = input; + + for _ in 0..MAX_PARTS { + let mut parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + nom::character::complete::space0, + nom::combinator::rest, + )); + + let (_, (_, tail)) = parser(rest)?; + rest = tail; + + let mut sign = None; + + let mut sign_parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + nom::branch::alt(( + nom::bytes::complete::tag("+"), + nom::bytes::complete::tag("-"), + )), + nom::character::complete::space0, + nom::combinator::rest, + )); + + if let Ok((_, (result, _, tail))) = sign_parser.parse(rest) { + sign = Some(result); + rest = tail; + } + + let mut chunk_parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + all_until_1_noconsume_inclusive(nom::branch::alt(( + nom::character::complete::space1, + nom::bytes::complete::tag("+"), + nom::bytes::complete::tag("-"), + nom::combinator::eof, + ))), + nom::combinator::rest, + )); + + let (_, (result, tail)) = chunk_parser.parse(rest)?; + + results.push((sign, result)); + + if tail.is_empty() { + break; + } + rest = tail; + } + + Ok(("", results)) +} + +fn parse_immediate<'a>(input: &'a str) -> IResult<&str, u64> { + let (rest, _) = nom::bytes::complete::tag::<_, _, nom::error::Error<_>>("#")(input)?; + parse_immediate_value(rest) +} + +fn parse_immediate_value<'a>(input: &'a str) -> IResult<&str, u64> { + let rest = input; + let mut hex_parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + all_from_tag_until_1_noconsume( + "0x", + nom::branch::alt((nom::character::complete::space1, nom::combinator::eof)), + ), + nom::combinator::rest, + )); + + if let Ok((_, args)) = hex_parser.parse(rest) { + let imm_body = args.0; + let rest = args.1; + match u64::from_str_radix(imm_body, 16) { + Ok(imm) => return Ok((rest, imm)), + Err(_) => { + return Err(nom::Err::Error(nom::error::Error::from_error_kind( + rest, + nom::error::ErrorKind::Digit, + ))); + } + } + } + + let mut binary_parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + all_from_tag_until_1_noconsume( + "0b", + nom::branch::alt((nom::character::complete::space1, nom::combinator::eof)), + ), + nom::combinator::rest, + )); + + if let Ok((_, args)) = binary_parser.parse(rest) { + let imm_body = args.0; + let rest = args.1; + match u64::from_str_radix(imm_body, 2) { + Ok(imm) => return Ok((rest, imm)), + Err(_) => { + return Err(nom::Err::Error(nom::error::Error::from_error_kind( + rest, + nom::error::ErrorKind::Digit, + ))); + } + } + } + + let mut decimal_parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + all_until_1_noconsume_inclusive(nom::branch::alt(( + nom::character::complete::space1, + nom::combinator::eof, + ))), + nom::combinator::rest, + )); + + if let Ok((_, args)) = decimal_parser.parse(rest) { + let imm_body = args.0; + let rest = args.1; + match u64::from_str_radix(imm_body, 10) { + Ok(imm) => return Ok((rest, imm)), + Err(_) => { + return Err(nom::Err::Error(nom::error::Error::from_error_kind( + rest, + nom::error::ErrorKind::Digit, + ))); + } + } + } + + Err(nom::Err::Error(nom::error::Error::from_error_kind( + rest, + nom::error::ErrorKind::Digit, + ))) +} + +#[cfg(test)] +mod test { + use zkevm_opcode_defs::Opcode; + + use super::*; + + #[test] + fn test_parse_into_sections() { + let _imm = parse_immediate("#42").unwrap(); + dbg!(_imm); + } + + #[test] + fn test_absolute_addressing() { + let (_, (reg, imm)) = parse_absolute_addressing_single("r15 + 12").unwrap(); + dbg!(reg); + dbg!(imm); + } + + #[test] + fn test_relative_addressing() { + let addressing_mode = ImmMemHandlerFlags::UseStackWithPushPop; + let (_, operand) = parse_relative_addressing("[r15 - 12]", addressing_mode).unwrap(); + dbg!(operand); + } + + #[test] + fn test_absolute_on_stack() { + let (_, operand) = parse_full_operand("stack[r15 - 12]").unwrap(); + dbg!(operand); + } + + #[test] + fn test_stack_and_shorthand() { + use crate::assembly::parse::code_element::parse_code_element; + + let operand = parse_code_element("and stack-[r1 + 1], r2, r1").unwrap(); + dbg!(operand); + } + + #[test] + fn test_far_call_with_modifiers() { + use crate::assembly::parse::code_element::parse_code_element; + + let operand = parse_code_element("far_call.static r2, r3, @.BB5_2").unwrap(); + dbg!(operand); + } + + #[test] + fn test_far_call_with_invalid_modifiers() { + use crate::assembly::parse::code_element::parse_code_element; + + let error = + parse_code_element("far_call.foobar r2, r3, @.BB5_2").expect_err("Should have failed"); + assert!( + matches!(error, InstructionReadError::UnknownArgument(_)), + "Expected Uknown argument error" + ); + } + + #[test] + fn test_uma_imm() { + use crate::assembly::parse::code_element::parse_code_element; + + let operand = parse_code_element("uma.heap_read 123, r0, r1, r0").unwrap(); + let _opcode: DecodedOpcode<8, EncodingModeProduction> = operand.try_into().unwrap(); + + let operand = parse_code_element("uma.heap_read r2, r0, r1, r0").unwrap(); + let _opcode: DecodedOpcode<8, EncodingModeProduction> = operand.try_into().unwrap(); + } + + #[test] + fn test_uma_store() { + use crate::assembly::parse::code_element::parse_code_element; + + let operand = parse_code_element("st.1 r5, r1").unwrap(); + dbg!(&operand); + let opcode: DecodedOpcode<8, EncodingModeProduction> = operand.try_into().unwrap(); + dbg!(&opcode); + + let operand = parse_code_element("st.1 16, r1").unwrap(); + dbg!(&operand); + let opcode: DecodedOpcode<8, EncodingModeProduction> = operand.try_into().unwrap(); + dbg!(&opcode); + + assert!( + matches!( + opcode.variant.opcode, + Opcode::UMA(zkevm_opcode_defs::UMAOpcode::HeapWrite) + ), + "wrong decode" + ); + } + + #[test] + fn test_uma_variants() { + use crate::assembly::parse::code_element::parse_code_element; + + let operand = parse_code_element("uma.static_read 123, r0, r1, r0").unwrap(); + let opcode: DecodedOpcode<8, EncodingModeProduction> = operand.try_into().unwrap(); + + assert!( + matches!( + opcode.variant.opcode, + Opcode::UMA(zkevm_opcode_defs::UMAOpcode::StaticMemoryRead) + ), + "wrong decode" + ); + + let operand = parse_code_element("uma.rs 123, r0, r1, r0").unwrap(); + let opcode: DecodedOpcode<8, EncodingModeProduction> = operand.try_into().unwrap(); + + assert!( + matches!( + opcode.variant.opcode, + Opcode::UMA(zkevm_opcode_defs::UMAOpcode::StaticMemoryRead) + ), + "wrong decode" + ); + + let operand = parse_code_element("uma.static_write r2, r0, r1, r0").unwrap(); + let opcode: DecodedOpcode<8, EncodingModeProduction> = operand.try_into().unwrap(); + assert!( + matches!( + opcode.variant.opcode, + Opcode::UMA(zkevm_opcode_defs::UMAOpcode::StaticMemoryWrite) + ), + "wrong decode" + ); + + let operand = parse_code_element("uma.ws 123, r0, r1, r0").unwrap(); + let opcode: DecodedOpcode<8, EncodingModeProduction> = operand.try_into().unwrap(); + + assert!( + matches!( + opcode.variant.opcode, + Opcode::UMA(zkevm_opcode_defs::UMAOpcode::StaticMemoryWrite) + ), + "wrong decode" + ); + } +} diff --git a/crates/zkEVM-assembly/src/assembly/parse/code_element.rs b/crates/zkEVM-assembly/src/assembly/parse/code_element.rs new file mode 100644 index 0000000..e43dca4 --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/parse/code_element.rs @@ -0,0 +1,469 @@ +use zkevm_opcode_defs::ImmMemHandlerFlags; +use zkevm_opcode_defs::RegOrImmFlags; + +use super::*; + +use crate::assembly::mnemonic::all_from_tag_until_1_noconsume; + +use crate::assembly::mnemonic::all_until_1_noconsume_inclusive; + +use crate::assembly::operand::GenericOperand; +use nom::error::ParseError; + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub(crate) enum OperandType { + Definition(zkevm_opcode_defs::Operand), + Label, +} + +pub(crate) fn marker_full_operand() -> OperandType { + OperandType::Definition(zkevm_opcode_defs::Operand::Full( + ImmMemHandlerFlags::UseRegOnly, + )) +} + +pub(crate) fn marker_register_operand() -> OperandType { + OperandType::Definition(zkevm_opcode_defs::Operand::RegOnly) +} + +pub(crate) fn marker_non_mem_operand() -> OperandType { + OperandType::Definition(zkevm_opcode_defs::Operand::RegOrImm( + RegOrImmFlags::UseRegOnly, + )) +} + +#[track_caller] +pub(crate) fn parse_opcode_and_rest<'a>(input: &'a str) -> IResult<&'a str, (&'a str, &'a str)> { + // only split opcode from any potential arguments + + let mut parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + all_until1(nom::character::complete::space1), + nom::character::complete::space0, + nom::combinator::rest, + )); + + if let Ok((_, result)) = parser(input) { + let opcode = result.0; + let arguments = result.2; + return Ok(("", (opcode, arguments))); + } + + // edge case of opcode without arguments + let mut parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + all_until1(nom::combinator::eof), + nom::combinator::rest, + )); + let (_, result) = parser(input)?; + let opcode = result.0; + let arguments = ""; + + Ok(("", (opcode, arguments))) +} + +#[track_caller] +pub(crate) fn split_arguments<'a>(input: &'a str) -> IResult<&'a str, Vec<&'a str>> { + // only split opcode from any potential arguments + + if input.is_empty() { + return Ok((input, vec![])); + } + + let mut rest = input; + let mut results = Vec::with_capacity(4); + + for i in 0..4 { + if i != 3 { + let mut parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + nom::character::complete::space0, + all_until1(nom::branch::alt(( + nom::bytes::complete::tag(","), + nom::combinator::eof, + ))), + nom::character::complete::space0, + nom::combinator::rest, + )); + + if let Ok(result) = parser.parse(rest) { + let result = result.1; + let body = result.1; + let tail = result.3; + results.push(body); + rest = tail; + } else if rest.is_empty() { + return Ok((rest, results)); + } else { + return Err(nom::Err::Error(nom::error::Error::from_error_kind( + input, + nom::error::ErrorKind::TooLarge, + ))); + } + } else { + let mut parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + nom::character::complete::space0, + all_until1(nom::combinator::eof), + )); + + if let Ok(result) = parser.parse(rest) { + let result = result.1; + let body = result.1; + results.push(body); + } else if rest.is_empty() { + return Ok((rest, results)); + } else { + return Err(nom::Err::Error(nom::error::Error::from_error_kind( + input, + nom::error::ErrorKind::TooLarge, + ))); + } + } + } + + Ok((rest, results)) +} + +#[track_caller] +fn parse_opcode_and_modifiers<'a>( + input: &'a str, +) -> Result<(&'a str, HashSet<&'a str>), InstructionReadError> { + let mut modifiers = HashSet::new(); + // now try to parse the opcode body into the reference opcode and potentially some modifiers + let mut parser_with_modifiers = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + // body + all_until_1_noconsume_inclusive(nom::bytes::complete::tag(".")), + // and now potentially many of modifiers except the last one + // because there is no space at the end + nom::multi::many0(all_from_tag_until_1_noconsume( + ".", + nom::branch::alt((nom::bytes::complete::tag("."), nom::combinator::eof)), + )), + nom::combinator::eof, + )); + + if let Ok((_, result)) = parser_with_modifiers.parse(input) { + // parse modifiers + let opcode = result.0; + let mods = result.1; + for m in mods.into_iter() { + let m = if let Some(m) = m.strip_suffix('.') { + m + } else { + assert!(!m.contains('.')); + + m + }; + + let is_fresh = modifiers.insert(m); + if !is_fresh { + return Err(InstructionReadError::DuplicateModifier(m.to_owned())); + } + } + + Ok((opcode, modifiers)) + } else { + let mut parsers_without_modifiers = + nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + // may be body + all_until1(nom::combinator::eof), + nom::combinator::eof, + )); + + let (_, result) = parsers_without_modifiers + .parse(input) + .map_err(|_| InstructionReadError::UnknownMnemonic(input.to_owned()))?; + let opcode = result.0; + + Ok((opcode, modifiers)) + } +} + +#[track_caller] +pub(crate) fn parse_code_element_inner<'a>( + input: &'a str, +) -> Result<(&'a str, HashSet<&'a str>, Vec<&'a str>), InstructionReadError> { + let (_, (body, arguments)) = parse_opcode_and_rest(input) + .map_err(|_| InstructionReadError::UnknownMnemonic(input.to_owned()))?; + let (_, arguments) = split_arguments(arguments) + .map_err(|_| InstructionReadError::UnknownMnemonic(input.to_owned()))?; + let (body, modifiers) = parse_opcode_and_modifiers(body)?; + + Ok((body, modifiers, arguments)) +} + +#[track_caller] +pub(crate) fn parse_canonical_operands_sequence<'a>( + arguments: Vec<&'a str>, + sources: &[OperandType], + destinations: &[OperandType], +) -> Result, InstructionReadError> { + if arguments.len() != sources.len() + destinations.len() { + return Err(InstructionReadError::InvalidArgumentCount { + expected: sources.len() + destinations.len(), + found: arguments.len(), + }); + } + + let mut results = Vec::with_capacity(arguments.len()); + + let mut it = arguments.into_iter(); + let mut idx = 0; + + for src in sources.iter() { + let input = it.next().unwrap(); + match src { + OperandType::Definition(def) => { + match def { + zkevm_opcode_defs::Operand::Full(_) => { + use crate::assembly::parse::addressing::parse_full_operand; + let (_, operand) = parse_full_operand(input).map_err(|_| { + InstructionReadError::InvalidGenericOperand(input.to_owned()) + })?; + results.push(operand); + } + zkevm_opcode_defs::Operand::RegOnly => { + let (_, (register, imm)) = parse_absolute_addressing_single(input) + .map_err(|_| { + InstructionReadError::InvalidAbsoluteLikeAddress(input.to_owned()) + })?; + + use crate::assembly::parse::addressing::parse_absolute_addressing_single; + if imm != 0 { + return Err(InstructionReadError::InvalidOperandImmInRegLocation( + input.to_owned(), + )); + } + + let operand = FullOperand::Register(register); + results.push(operand); + } + zkevm_opcode_defs::Operand::RegOrImm(_) => { + use crate::assembly::parse::addressing::parse_full_operand; + let (_, operand) = parse_full_operand(input).map_err(|_| { + InstructionReadError::InvalidGenericOperand(input.to_owned()) + })?; + let _as_reg_imm = operand.clone().as_non_memory_operand(idx)?; + results.push(operand); + } + } + // we parse an operand that can be reg-only, or full one + } + OperandType::Label => { + // we expect to find a label + use crate::assembly::parse::constant_operand::parse_constant_operand; + + let (_, label) = parse_constant_operand(input).map_err(|_| { + InstructionReadError::InvalidLabeledConstantOperand(input.to_owned()) + })?; + results.push(label); + } + } + + idx += 1; + } + + for dst in destinations.iter() { + let input = it.next().unwrap(); + match dst { + OperandType::Definition(def) => { + match def { + zkevm_opcode_defs::Operand::Full(_) => { + use crate::assembly::parse::addressing::parse_full_operand; + let (_, operand) = parse_full_operand(input).map_err(|_| { + InstructionReadError::InvalidGenericOperand(input.to_owned()) + })?; + match &operand { + FullOperand::Full(GenericOperand { r#type: t, .. }) => { + if !t.is_allowed_for_dst() { + dbg!(t); + return Err(InstructionReadError::InvalidArgument { + index: idx, + expected: "operand that can be destination", + found: input.to_owned(), + }); + } + } + _ => {} + } + results.push(operand); + } + zkevm_opcode_defs::Operand::RegOnly => { + let (_, (register, imm)) = parse_absolute_addressing_single(input) + .map_err(|_| { + InstructionReadError::InvalidAbsoluteLikeAddress(input.to_owned()) + })?; + + use crate::assembly::parse::addressing::parse_absolute_addressing_single; + if imm != 0 { + return Err(InstructionReadError::InvalidOperandImmInRegLocation( + input.to_owned(), + )); + } + + let operand = FullOperand::Register(register); + results.push(operand); + } + zkevm_opcode_defs::Operand::RegOrImm(_) => { + unreachable!() + } + } + // we parse an operand that can be reg-only, or full one + } + OperandType::Label => { + panic!("Label can not be in dst position"); + } + } + + idx += 1; + } + + Ok(results) +} + +use crate::assembly::mnemonic::*; +use lazy_static::lazy_static; + +lazy_static! { + pub(crate) static ref ALL_CANONICALIZATION_TRANSFORMERS: Vec IResult<&str, String> + 'static + Send + Sync>> = + vec![Box::from(parse_set_flags_combinator),]; + pub(crate) static ref ALL_MNEMONIC_TRANSFORMERS: Vec IResult<&str, String> + 'static + Send + Sync>> = { + vec![ + Box::from(parse_nop_combinator), + Box::from(parse_mov_combinator), + Box::from(parse_xor_combinator), + Box::from(parse_and_combinator), + Box::from(parse_or_combinator), + Box::from(parse_shl_combinator), + Box::from(parse_shr_combinator), + Box::from(parse_rol_combinator), + Box::from(parse_ror_combinator), + // Box::from(parse_advance_sp_combinator), + Box::from(parse_shorthand_ret), + Box::from(parse_shorthand_revert), + Box::from(parse_shorthand_panic), + Box::from(parse_invoke_combinator), + Box::from(parse_push_combinator), + Box::from(parse_pop_combinator), + Box::from(parse_sread_combinator), + Box::from(parse_sload_combinator), + Box::from(parse_sstore_combinator), + Box::from(parse_tread_combinator), + Box::from(parse_tload_combinator), + Box::from(parse_tstore_combinator), + Box::from(parse_decom_combinator), + Box::from(parse_event_combinator), + Box::from(parse_to_l1_combinator), + Box::from(parse_gas_left_combinator), + Box::from(parse_set_gas_per_pubdatagas_left_combinator), + Box::from(parse_precompile_combinator), + Box::from(parse_increase_sp_shorthard), + Box::from(parse_decrease_sp_shorthard), + Box::from(parse_shorthand_near_call), + Box::from(parse_shorthand_exceptionless_near_call), + Box::from(parse_uma_heap_read_combinator), + Box::from(parse_uma_aux_heap_read_combinator), + Box::from(parse_uma_heap_write_combinator), + Box::from(parse_uma_aux_heap_write_combinator), + Box::from(parse_uma_fat_ptr_read_combinator), + Box::from(parse_uma_heap_read_increment_combinator), + Box::from(parse_uma_aux_heap_read_increment_combinator), + Box::from(parse_uma_heap_write_increment_combinator), + Box::from(parse_uma_aux_heap_write_increment_combinator), + Box::from(parse_uma_fat_ptr_read_increment_combinator), + ] + }; +} + +#[track_caller] +pub(crate) fn parse_code_element<'a>(input: &'a str) -> Result { + // first we canonicalize + let mut canonical = input.to_owned(); + + for transformer in ALL_CANONICALIZATION_TRANSFORMERS.iter() { + if let Ok((_, transformed)) = transformer(&canonical) { + canonical = transformed; + } + } + // then apply some short mnemonics into full forms + for transformer in ALL_MNEMONIC_TRANSFORMERS.iter() { + if let Ok((_, transformed)) = transformer(&canonical) { + canonical = transformed; + break; + } + } + // now parse + let (opcode, modifiers, arguments) = parse_code_element_inner(&canonical)?; + + Instruction::try_from_parts(opcode, modifiers, arguments) +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_parse_trivial_opcode() { + let opcode = parse_code_element("nop r0, r0, r0, r0").unwrap(); + dbg!(opcode); + } + + #[test] + fn test_parse_add_opcode() { + let opcode = parse_code_element("add! stack-=[r1 + 4], r5, stack=[42]").unwrap(); + dbg!(opcode); + } + + #[test] + fn test_parse_event_shorthand() { + let opcode = parse_code_element("event.first r6, r5").unwrap(); + dbg!(opcode); + } + + #[test] + fn test_parse_imms_in_addressing() { + let opcode = parse_code_element("add 4, r0, stack=[r2 + 1]").unwrap(); + dbg!(opcode); + } + + #[test] + fn test_stack_adjustment_shorthand() { + let opcode = parse_code_element("nop stack+=[5]").unwrap(); + dbg!(opcode); + } + + #[test] + fn test_uma_and_increment() { + let opcode = parse_code_element("ld.1.inc r2, r4, r2").unwrap(); + dbg!(opcode); + } + + #[test] + fn test_parse_ptr_add_opcode() { + let opcode = parse_code_element("ptr.add stack-=[r1 + 4], r5, stack=[42]").unwrap(); + dbg!(opcode); + } + + #[test] + fn test_parse_uma_read_ptr_opcode() { + let opcode = parse_code_element("ld r1, r2").unwrap(); + dbg!(opcode); + let opcode = parse_code_element("ld.inc r1, r2, r3").unwrap(); + dbg!(opcode); + let opcode = parse_code_element("st.1.inc r1, r2, r3").unwrap(); + dbg!(opcode); + } + + #[test] + fn test_shorthand_ret_like() { + let opcode = parse_code_element("ret").unwrap(); + dbg!(opcode); + let opcode = parse_code_element("revert").unwrap(); + dbg!(opcode); + let opcode = parse_code_element("panic").unwrap(); + dbg!(opcode); + } + + #[test] + fn test_parse_global_var() { + let opcode = parse_code_element("add! stack[@var + 4], r5, stack=[42]").unwrap(); + dbg!(opcode); + } +} diff --git a/crates/zkEVM-assembly/src/assembly/parse/constant_operand.rs b/crates/zkEVM-assembly/src/assembly/parse/constant_operand.rs new file mode 100644 index 0000000..fc5efb9 --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/parse/constant_operand.rs @@ -0,0 +1,74 @@ +use zkevm_opcode_defs::ImmMemHandlerFlags; + +use super::addressing::parse_relative_addressing; +use super::*; +use crate::assembly::mnemonic::all_from_tag_until_1_noconsume; +use crate::assembly::mnemonic::all_until1_include_terminator; + +use crate::assembly::operand::ConstantOperand; + +pub(crate) fn parse_constant_operand<'a>(input: &'a str) -> IResult<&str, FullOperand> { + // we try to parse something like @label[reg + imm], + // so we first do try to take @|label|[.... and we do not consume [] + + let mut parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + nom::character::complete::space0, + all_from_tag_until_1_noconsume( + "@", + nom::branch::alt(( + nom::bytes::complete::tag("["), + nom::character::complete::space1, + nom::combinator::eof, + )), + ), + nom::combinator::rest, + )); + + let (_, result) = parser(input)?; + + let label = result.1; + let rest = result.2; + + let mut addressing_parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + all_until1_include_terminator(nom::bytes::complete::tag("]")), + nom::combinator::rest, + )); + + let operand = if let Ok((_, (addressing, _))) = addressing_parser.parse(rest) { + let mode = ImmMemHandlerFlags::UseAbsoluteOnStack; + + let (_, operand) = parse_relative_addressing(addressing, mode)?; + match operand { + FullOperand::Full(operand) => FullOperand::Constant(ConstantOperand { + label: label.to_owned(), + register: operand.register, + immediate: operand.immediate, + }), + a => { + panic!( + "unsupported operand {:?} for addressing {:?} and code label {}", + a, addressing, label + ); + } + } + } else { + FullOperand::Constant(ConstantOperand { + label: label.to_owned(), + register: RegisterOperand::Null, + immediate: 0, + }) + }; + + Ok(("", operand)) +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_parse_into_sections() { + let (_, operand) = parse_constant_operand(" @CPI0_0[0]").unwrap(); + dbg!(operand); + } +} diff --git a/crates/zkEVM-assembly/src/assembly/parse/data_element.rs b/crates/zkEVM-assembly/src/assembly/parse/data_element.rs new file mode 100644 index 0000000..3667a76 --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/parse/data_element.rs @@ -0,0 +1,204 @@ +use super::*; +use crate::assembly::constants::*; + +use nom::error::ParseError; +use num_bigint::*; +use num_traits::*; + +pub(crate) fn parse_data_element<'a>( + input: &'a str, +) -> Result, InstructionReadError> { + // we want to parse something like `.cell integer`, or `bytes ...` + + for parser in ALL_DATA_PARSERS.iter() { + if let Ok((_, result)) = parser(input) { + return Ok(result); + } + } + + Err(InstructionReadError::InvalidLabeledConstant( + input.to_owned(), + )) +} + +use lazy_static::lazy_static; + +lazy_static! { + pub(crate) static ref ALL_DATA_PARSERS: Vec IResult<&str, Vec> + 'static + Send + Sync>> = { + vec![ + Box::from(parse_cell_into_constant) + as Box IResult<&str, Vec> + 'static + Send + Sync>, + Box::from(parse_zeroes_into_constant), + Box::from(parse_label_name), + ] + }; +} + +fn parse_cell_into_constant(input: &str) -> IResult<&str, Vec> { + let (_, biguint) = parse_cell(input)?; + if let Some(serialized) = serialize_biguint(biguint) { + Ok(( + "", + vec![DataElement::Constant(ConstantValue::Cell(serialized))], + )) + } else { + Err(nom::Err::Error(nom::error::Error::from_error_kind( + input, + nom::error::ErrorKind::TooLarge, + ))) + } +} + +fn parse_zeroes_into_constant(input: &str) -> IResult<&str, Vec> { + let (_, length) = parse_zeroes(input)?; + if length % 32 != 0 { + return Err(nom::Err::Error(nom::error::Error::from_error_kind( + input, + nom::error::ErrorKind::TooLarge, + ))); + } + Ok(( + "", + vec![DataElement::Constant(ConstantValue::Cell([0u8; 32])); length / 32], + )) +} + +fn parse_label_name(input: &str) -> IResult<&str, Vec> { + let (_, label_name) = parse_name(input)?; + Ok(("", vec![DataElement::LabelName(label_name.to_string())])) +} + +fn parse_zeroes<'a>(input: &'a str) -> IResult<&str, usize> { + // we want to parse something `.cell signed_integer` + // and transform it into the unsigned 32 byte + + let mut parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + nom::character::complete::space0, + nom::bytes::complete::tag(".zero"), + nom::character::complete::space1, + all_until1(nom::branch::alt(( + nom::combinator::eof, + nom::character::complete::line_ending, + nom::character::complete::space1, + ))), + )); + + let (_, result) = parser(input)?; + + let value = result.3; + if value.is_empty() { + return Ok(("", 0)); + } + + let unsigned = usize::from_str_radix(value, 10); + if unsigned.is_err() { + return Err(nom::Err::Error(nom::error::Error::from_error_kind( + value, + nom::error::ErrorKind::Digit, + ))); + } + + Ok(("", unsigned.unwrap())) +} + +fn serialize_biguint(input: BigUint) -> Option<[u8; 32]> { + // deal with endianess and size + let mut result = [0u8; 32]; + let as_bytes = input.to_bytes_be(); + if as_bytes.len() > 32 { + return None; + } + result[(32 - as_bytes.len())..].copy_from_slice(&as_bytes); + + Some(result) +} + +fn parse_cell<'a>(input: &'a str) -> IResult<&str, BigUint> { + // we want to parse something `.cell signed_integer` + // and transform it into the unsigned 32 byte + + let mut parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + nom::character::complete::space0, + nom::bytes::complete::tag(".cell"), + nom::character::complete::space1, + all_until1(nom::branch::alt(( + nom::combinator::eof, + nom::character::complete::line_ending, + nom::character::complete::space1, + ))), + )); + + let (_, result) = parser(input)?; + + let value = result.3; + if value.is_empty() { + return Ok(("", BigUint::zero())); + } + + let mut value = value; + let mut is_negative = false; + + if let Some(v) = may_be_split_prefix(value, "-") { + value = v; + is_negative = true; + } else if let Some(v) = may_be_split_prefix(value, "+") { + value = v; + } + + let unsigned = BigUint::from_str_radix(value, 10); + if unsigned.is_err() { + return Err(nom::Err::Error(nom::error::Error::from_error_kind( + value, + nom::error::ErrorKind::Digit, + ))); + } + + let mut unsigned = unsigned.unwrap(); + if is_negative { + unsigned = (BigUint::from(1u64) << 256u32) - unsigned; + } + + Ok(("", unsigned)) +} + +fn parse_name<'a>(input: &'a str) -> IResult<&str, &str> { + let mut parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + nom::character::complete::space0, + nom::bytes::complete::tag(".cell"), + nom::character::complete::space1, + nom::bytes::complete::tag("@"), + all_until1(nom::branch::alt(( + nom::combinator::eof, + nom::character::complete::line_ending, + nom::character::complete::space1, + ))), + )); + + let (_, result) = parser(input)?; + Ok(("", result.4)) +} + +pub(crate) fn resolve_to_constant( + input: &str, + function_labels_to_pc: &HashMap, +) -> Option { + function_labels_to_pc + .get(input) + .copied() + .map(|offset| { + let biguint = BigUint::from(offset); + serialize_biguint(biguint).map(ConstantValue::Cell) + }) + .flatten() +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_parse_cell() { + let (_, value) = parse_cell(" .cell -57896044618658097711785492504343953926634992332820282019728792003956564819968").unwrap(); + dbg!(value); + } +} diff --git a/crates/zkEVM-assembly/src/assembly/parse/mod.rs b/crates/zkEVM-assembly/src/assembly/parse/mod.rs new file mode 100644 index 0000000..4a9b743 --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/parse/mod.rs @@ -0,0 +1,544 @@ +use nom::character::streaming::space0; + +use super::section::*; +use super::*; + +pub mod addressing; +pub mod code_element; +pub mod constant_operand; +pub mod data_element; + +use crate::error::SectionReadError; +use crate::RegisterOperand; + +pub(crate) fn may_be_split_prefix<'a>(input: &'a str, prefix: &str) -> Option<&'a str> { + match input.split_once(prefix) { + Some((_, rest)) => Some(rest), + _ => None, + } +} + +pub(crate) fn parse_label(input: &str) -> IResult<&str, &str> { + let mut parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + space0, + all_until1(nom::bytes::complete::tag(":")), + nom::combinator::rest, + )); + + let (rest, args) = parser.parse(input)?; + + Ok((rest, args.1)) +} + +pub(crate) fn parse_rodata_section(input: &str) -> IResult<&str, &str> { + let mut parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + space0, + nom::bytes::complete::tag(".rodata"), + nom::combinator::rest, + )); + + let (rest, args) = parser.parse(input)?; + + Ok((rest, args.1)) +} + +pub(crate) fn parse_data_section(input: &str) -> IResult<&str, &str> { + let mut parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + space0, + nom::bytes::complete::tag(".data"), + nom::combinator::rest, + )); + + let (rest, args) = parser.parse(input)?; + + Ok((rest, args.1)) +} + +pub(crate) fn parse_text_section(input: &str) -> IResult<&str, &str> { + let mut parser = nom::sequence::tuple::<_, _, nom::error::Error<_>, _>(( + space0, + nom::bytes::complete::tag(".text"), + nom::combinator::rest, + )); + + let (rest, args) = parser.parse(input)?; + + Ok((rest, args.1)) +} + +pub(crate) fn split_into_sections<'a>( + text: &'a str, +) -> Result< + ( + impl Iterator> + Clone, + Vec<(UnparsedSection, Vec>)>, + ), + AssemblyParseError, +> { + // explicitly enumerate lines + let lines_with_numbers = text.lines().enumerate().map(|(i, line)| Wrapper { + line_number: i, + line, + }); + + let mut results = Vec::with_capacity(4); + + let mut current_unparsed_section: Option<(UnparsedSection, Vec>)> = None; + + // split into sections, and trim comments + for (step, line) in lines_with_numbers.clone().enumerate() { + let without_comment = line.line.split(';').next().unwrap(); + + if parse_rodata_section(without_comment).is_ok() { + if let Some(current_section) = current_unparsed_section.take() { + results.push(current_section); + } + + current_unparsed_section = Some(( + UnparsedSection { + section_type: SectionType::Data, + start: step, + end: step + 1, + }, + Vec::with_capacity(1024), + )) + } else if parse_data_section(without_comment).is_ok() { + if let Some(current_section) = current_unparsed_section.take() { + results.push(current_section); + } + + current_unparsed_section = Some(( + UnparsedSection { + section_type: SectionType::Globals, + start: step, + end: step + 1, + }, + Vec::with_capacity(1024), + )) + } else if parse_text_section(without_comment).is_ok() { + if let Some(current_section) = current_unparsed_section.take() { + results.push(current_section); + } + + current_unparsed_section = Some(( + UnparsedSection { + section_type: SectionType::Text, + start: step, + end: step + 1, + }, + Vec::with_capacity(1024), + )) + } else { + // something else + if let Some((current_section, _)) = current_unparsed_section.as_mut() { + current_section.end += 1; + } else { + // no nothing, it's unknown region + } + } + + if let Ok((_, label)) = parse_label(without_comment) { + if let Some((current_section, labels_in_section)) = current_unparsed_section.as_mut() { + let new_label = UnparsedLabel { + section_type: current_section.section_type, + label, + start: step, + end: step + 1, + }; + + labels_in_section.push(new_label); + } + } else if let Some((_, labels_in_section)) = current_unparsed_section.as_mut() { + if let Some(current_label) = labels_in_section.last_mut() { + current_label.end += 1; + } + } + } + + if let Some(last) = current_unparsed_section.take() { + results.push(last); + }; + + // dbg!(&results); + + Ok((lines_with_numbers, results)) +} + +pub(crate) fn parse_sections<'a>( + lines_with_numbers: impl Iterator> + Clone, + sections_and_labels: Vec<(UnparsedSection, Vec>)>, +) -> Result< + ( + impl Iterator> + Clone, + Vec, + HashSet, + ), + AssemblyParseError, +> { + let mut parsed_sections = Vec::with_capacity(sections_and_labels.len()); + let mut lines_iter = lines_with_numbers.clone().enumerate(); + + let mut this_line = 0usize; + + let mut all_labels: HashSet = HashSet::new(); + let mut all_globals: HashSet = HashSet::new(); + + let mut all_data_section_errors = HashMap::new(); + let mut all_text_section_errors = HashMap::new(); + let mut all_globals_section_errors = HashMap::new(); + + for (section, labels) in sections_and_labels.into_iter() { + let mut tmp_data_section = DataSection { + elements: Vec::with_capacity(1024), + }; + + let mut tmp_text_section = TextSection { + elements: Vec::with_capacity(1024), + }; + + let mut tmp_globals_section = GlobalsSection { + elements: Vec::with_capacity(1024), + }; + + if let Some(first) = labels.first() { + assert!(first.start >= section.start); + } + let skip = section.start - this_line; + for _ in 0..skip { + lines_iter.next(); + this_line += 1; + } + + for label in labels.into_iter() { + assert_eq!(label.section_type, section.section_type); + if this_line < label.start { + 'lines: for _ in 0..(label.start - this_line) { + let (line_number, line) = lines_iter.next().unwrap(); + let line = line.line.trim_start(); + let without_comment = line.split(';').next().unwrap(); + assert_eq!(this_line, line_number); + this_line += 1; + if without_comment.is_empty() { + continue 'lines; + } + // some unlabeled data or code + match section.section_type { + SectionType::Data => { + match self::data_element::parse_data_element(without_comment) { + Ok(_constants) => { + let err = InstructionReadError::UnexpectedConstant( + without_comment.to_string(), + ); + all_data_section_errors + .insert(line_number, (without_comment.to_owned(), err)); + // let data_element = ConstantElement { + // source_line: line_number, + // content_type: constant, + // }; + // let section_element = + // DataSectionElement::Unlabeled(data_element); + // tmp_data_section.elements.push(section_element); + } + Err(e) => { + if without_comment.starts_with('.') { + // some remnant section + } else { + all_data_section_errors + .insert(line_number, (without_comment.to_owned(), e)); + } + } + } + } + SectionType::Globals => { + match self::data_element::parse_data_element(without_comment) { + Ok(_constants) => { + let err = InstructionReadError::UnexpectedConstant( + without_comment.to_string(), + ); + all_data_section_errors + .insert(line_number, (without_comment.to_owned(), err)); + + // let data_element = ConstantElement { + // source_line: line_number, + // content_type: constant, + // }; + // let section_element = + // GlobalsSectionElement::Unlabeled(data_element); + // tmp_globals_section.elements.push(section_element); + } + Err(e) => { + if without_comment.starts_with('.') { + // some remnant section + } else { + all_globals_section_errors + .insert(line_number, (without_comment.to_owned(), e)); + } + } + } + } + SectionType::Text => { + match self::code_element::parse_code_element(without_comment) { + Ok(instruction) => { + let code_element = CodeElement { + source_line: line_number, + instruction, + }; + let section_element = + TextSectionElement::Unlabeled(code_element); + tmp_text_section.elements.push(section_element); + } + Err(e) => { + if without_comment.starts_with('.') { + // some remnant section + } else { + all_text_section_errors + .insert(line_number, (without_comment.to_owned(), e)); + } + } + } + } + _ => {} + } + } + } + + if this_line == label.start { + this_line += 1; + let _ = lines_iter.next().unwrap(); + // do nothing, it's a label itself + } + + let mut labeled_data_tmp_content = Vec::with_capacity(1024); + let mut labeled_text_tmp_content = Vec::with_capacity(1024); + let mut labeled_globals_tmp_content = Vec::with_capacity(1024); + for _ in 0..(label.end - this_line) { + let (line_number, line) = lines_iter.next().unwrap(); + let line = line.line.trim_start(); + let without_comment = line.split(';').next().unwrap(); + assert_eq!(this_line, line_number); + this_line += 1; + if without_comment.is_empty() { + continue; + } + // some labeled data or code + match section.section_type { + SectionType::Data => { + match self::data_element::parse_data_element(without_comment) { + Ok(data_elements) => { + labeled_data_tmp_content.extend(data_elements); + } + Err(e) => { + if without_comment.starts_with('.') { + // some remnant section + } else { + all_data_section_errors + .insert(line_number, (without_comment.to_owned(), e)); + } + } + } + } + SectionType::Globals => { + match self::data_element::parse_data_element(without_comment) { + Ok(data_elements) => { + data_elements.iter().for_each(|element| match element { + DataElement::Constant(constant) => { + labeled_globals_tmp_content.push(constant.to_owned()); + } + DataElement::LabelName(name) => { + all_globals_section_errors.insert( + line_number, + ( + without_comment.to_owned(), + InstructionReadError::InvalidLabeledConstant( + name.to_string(), + ), + ), + ); + } + }); + } + Err(e) => { + if without_comment.starts_with('.') { + // some remnant section + } else { + all_globals_section_errors + .insert(line_number, (without_comment.to_owned(), e)); + } + } + } + } + SectionType::Text => { + match self::code_element::parse_code_element(without_comment) { + Ok(instruction) => { + let code_element = CodeElement { + source_line: line_number, + instruction, + }; + labeled_text_tmp_content.push(code_element); + } + Err(e) => { + if without_comment.starts_with('.') { + // some remnant section + } else { + all_text_section_errors + .insert(line_number, (without_comment.to_owned(), e)); + } + } + } + } + _ => {} + } + } + + match section.section_type { + SectionType::Data => { + // if !labeled_data_tmp_content.is_empty() { + { + let labeled = LabeledConstant { + label: label.label.to_owned(), + source_line: label.start, + content: labeled_data_tmp_content, + }; + let section_element = DataSectionElement::Labeled(labeled); + tmp_data_section.elements.push(section_element); + + let is_fresh = all_labels.insert(label.label.to_owned()); + if !is_fresh { + return Err(AssemblyParseError::DuplicateLabel(label.label.to_owned())); + } + } + } + SectionType::Globals => { + // if !labeled_data_tmp_content.is_empty() { + { + let labeled = LabeledGlobal { + label: label.label.to_owned(), + source_line: label.start, + content: labeled_globals_tmp_content, + }; + let section_element = GlobalsSectionElement::Labeled(labeled); + tmp_globals_section.elements.push(section_element); + + let is_fresh = all_labels.insert(label.label.to_owned()); + if !is_fresh { + return Err(AssemblyParseError::DuplicateLabel(label.label.to_owned())); + } + + let is_fresh = all_globals.insert(label.label.to_owned()); + if !is_fresh { + return Err(AssemblyParseError::DuplicateLabel(label.label.to_owned())); + } + } + } + SectionType::Text => { + // if !labeled_text_tmp_content.is_empty() { + { + let labeled = LabeledFunction { + label: label.label.to_owned(), + source_line: label.start, + content: labeled_text_tmp_content, + }; + let section_element = TextSectionElement::Labeled(labeled); + tmp_text_section.elements.push(section_element); + + let is_fresh = all_labels.insert(label.label.to_owned()); + if !is_fresh { + return Err(AssemblyParseError::DuplicateLabel(label.label.to_owned())); + } + } + } + _ => {} + } + } + + if !tmp_data_section.elements.is_empty() { + parsed_sections.push(ParsedSection::Data(tmp_data_section)); + } else if !tmp_text_section.elements.is_empty() { + parsed_sections.push(ParsedSection::Text(tmp_text_section)); + } else if !tmp_globals_section.elements.is_empty() { + parsed_sections.push(ParsedSection::Globals(tmp_globals_section)); + } + } + + // dbg!(&parsed_sections); + + if !all_text_section_errors.is_empty() { + return Err(AssemblyParseError::TextSectionInvalid( + SectionReadError::LineReadError(all_text_section_errors), + )); + } + + if !all_data_section_errors.is_empty() { + return Err(AssemblyParseError::DataSectionInvalid( + SectionReadError::LineReadError(all_data_section_errors), + )); + } + + if !all_globals_section_errors.is_empty() { + return Err(AssemblyParseError::GlobalsSectionInvalid( + SectionReadError::LineReadError(all_globals_section_errors), + )); + } + + Ok((lines_with_numbers, parsed_sections, all_labels)) +} + +#[cfg(test)] +pub(crate) mod test { + use super::*; + + pub(crate) const TEST_ASSEMBLY_0: &str = r#" + .text + .file "fib.ll" + .data + .globl val ; @val + .p2align 5 +val: + .cell 0 + .rodata.cst32 + .p2align 5 ; -- Begin function fn_fib +CPI0_0: + .cell -57896044618658097711785492504343953926634992332820282019728792003956564819968 + .text + .globl fn_fib +fn_fib: ; @fn_fib +; %bb.0: ; %fn_fib_entry + nop stack+=[6] + add r1, r0, r2 + add @CPI0_0[0], r0, r1 + add 0, r0, r4 + add.gt r1, r0, r4 + add 0, 0, r3 + add 0, r0, r5 + add.lt r1, r0, r5 + add.eq r5, r0, r4 + sub! r4, r3, r4 + jump.ne @.BB0_2 +; %bb.1: ; %fn_fib_entry.if + add 1, 0, r4 + sub! r2, r4, r4 + and r2, r1, r2 + sub! r2, r3, r3 + sub! r2, r1, r1 + add 1, 0, r1 + nop stack-=[6] + ret +.BB0_2: ; %fn_fib_entry.endif + sub.s 1, r2, r1 + call @fn_fib + add r1, r0, r3 + sub.s 2, r2, r1 + call @fn_fib + add r3, r1, r1 + nop stack-=[6] + ret + ; -- End function + .note.GNU-stack + "#; + + #[test] + fn test_parse_into_sections() { + let (a, b) = split_into_sections(TEST_ASSEMBLY_0).unwrap(); + let _ = parse_sections(a, b).unwrap(); + } +} diff --git a/crates/zkEVM-assembly/src/assembly/section/mod.rs b/crates/zkEVM-assembly/src/assembly/section/mod.rs new file mode 100644 index 0000000..9d01335 --- /dev/null +++ b/crates/zkEVM-assembly/src/assembly/section/mod.rs @@ -0,0 +1,103 @@ +use super::*; + +use crate::assembly::constants::ConstantValue; + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub(crate) enum SectionType { + Data, + Text, + Globals, + Unknown, +} + +#[derive(Clone, Copy, Debug)] +pub(crate) struct UnparsedSection { + pub(crate) section_type: SectionType, + pub(crate) start: usize, + pub(crate) end: usize, +} + +#[derive(Clone, Copy, Debug)] +pub(crate) struct UnparsedLabel<'a> { + pub(crate) section_type: SectionType, + pub(crate) label: &'a str, + pub(crate) start: usize, + pub(crate) end: usize, +} + +#[derive(Clone, Debug)] +pub(crate) enum ParsedSection { + Globals(GlobalsSection), + Data(DataSection), + Text(TextSection), +} + +#[derive(Clone, Debug)] +pub(crate) struct TextSection { + pub(crate) elements: Vec, +} + +// Text section can contain either labeled or unlabeled code + +#[derive(Clone, Debug)] +pub(crate) enum TextSectionElement { + Unlabeled(CodeElement), + Labeled(LabeledFunction), +} + +#[derive(Clone, Debug)] +pub(crate) struct LabeledFunction { + pub(crate) label: String, + pub(crate) source_line: usize, + pub(crate) content: Vec, +} + +#[derive(Clone, Debug)] +pub(crate) struct CodeElement { + pub(crate) source_line: usize, + pub(crate) instruction: Instruction, +} + +// Data section can only contraint constants +#[derive(Clone, Debug)] +pub(crate) struct DataSection { + pub(crate) elements: Vec, +} + +#[derive(Clone, Debug)] +pub(crate) enum DataSectionElement { + Unlabeled(DataElement), + Labeled(LabeledConstant), +} + +#[derive(Clone, Debug)] +pub(crate) struct LabeledConstant { + pub(crate) label: String, + pub(crate) source_line: usize, + pub(crate) content: Vec, +} + +#[derive(Clone, Debug)] +pub(crate) enum DataElement { + LabelName(String), + Constant(ConstantValue), +} + +// Globals section can only containt named globals +#[derive(Clone, Debug)] +pub(crate) struct GlobalsSection { + pub(crate) elements: Vec, +} + +#[derive(Clone, Debug)] +pub(crate) enum GlobalsSectionElement { + Unlabeled(ConstantValue), + Labeled(LabeledGlobal), +} + +#[derive(Clone, Debug)] +pub(crate) struct LabeledGlobal { + pub(crate) label: String, + pub(crate) source_line: usize, + pub(crate) content: Vec, +} diff --git a/crates/zkEVM-assembly/src/error.rs b/crates/zkEVM-assembly/src/error.rs new file mode 100644 index 0000000..43af87e --- /dev/null +++ b/crates/zkEVM-assembly/src/error.rs @@ -0,0 +1,167 @@ +//! +//! The common error. +//! + +use crate::assembly::operand::{FullOperand, NonMemoryOperand}; +use std::collections::HashMap; +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum Error { + /// The file opening error. + #[error("file opening: {0}")] + FileOpening(std::io::Error), + /// The file metadata error. + #[error("file metadata: {0}")] + FileMetadata(std::io::Error), + /// The file reading error. + #[error("file reading: {0}")] + FileReading(std::io::Error), + #[error(transparent)] + AssemblyParseError(#[from] AssemblyParseError), +} + +#[derive(Debug, Error, PartialEq)] +pub enum AssemblyParseError { + #[error("assembly code cannot be empty")] + EmptyCode, + #[error("assembly code cannot be larger than {0} instructions")] + CodeTooLarge(usize), + #[error("can not parse data section element: {0}")] + DataSectionInvalid(SectionReadError), + #[error("can not parse globals section element: {0}")] + GlobalsSectionInvalid(SectionReadError), + #[error("can not parse text section element: {0}")] + TextSectionInvalid(SectionReadError), + #[error("there is a duplicate label in a code: {0}")] + DuplicateLabel(String), + #[error("there is no label `{0}` in data section of functions")] + LabelNotFound(String), + #[error("failed to resolve relocation for label `{0}` in data section")] + RelocationError(String), + #[error("Label {1} was tried to be used for either PC or constant at offset {0} that is more than `{2}` addressable space")] + CodeIsTooLong(usize, String, u64), +} + +#[derive(Debug, Error, PartialEq)] +pub enum SectionReadError { + #[error("cannot parse lines: {0:?}")] + LineReadError(HashMap), +} + +#[derive(Debug, Error, PartialEq)] +pub enum InstructionReadError { + /// Failed to parse text assembly + #[error("assembly parse error {0}")] + AssemblyParseError(AssemblyParseError), + /// The unknown register error. + #[error("unknown register `{0}`")] + UnknownRegister(String), + /// The invalid number error. + #[error("invalid number `{0}`: {1}")] + InvalidNumber(String, std::num::ParseIntError), + /// The invalid big number error. + #[error("invalid big number `{0}`: {1}")] + InvalidBigNumber(String, num_bigint::ParseBigIntError), + /// The invalid instruction argument. + #[error("failed to parse labeled constant value `{0}`")] + InvalidLabeledConstant(String), + /// The invalid instruction argument. + #[error( + "invalid argument {0}: expected `{1}`, found `{2}`", + index, + expected, + found + )] + InvalidArgument { + /// The argument position, starts from `0`. + index: usize, + /// The expected argument description. + expected: &'static str, + /// The invalid argument representation. + found: String, + }, + #[error("failed to parse generic operand location: received `{0}`")] + InvalidGenericOperand(String), + #[error("failed to parse absolute-like `reg + imm` location: received `{0}`")] + InvalidAbsoluteLikeAddress(String), + #[error("failed to parse labeled constant operand location: received `{0}`")] + InvalidLabeledConstantOperand(String), + /// The invalid instruction argument. + #[error("found immediate `{0}` for location where register only is expected")] + InvalidOperandImmInRegLocation(String), + #[error( + "invalid operand for location that should be generic: on position `{index}`: {found:?}" + )] + InvalidOperandForGenericLocation { index: usize, found: FullOperand }, + /// The invalid instruction argument. + #[error("invalid operand for location that is reg-only: on position `{index}`: {found:?}")] + InvalidOperandForRegLocation { index: usize, found: FullOperand }, + #[error("invalid operand for location that is reg-only or imm-only: on position `{index}`: {found:?}")] + InvalidOperandForRegImmLocation { index: usize, found: FullOperand }, + #[error("invalid operand for location that is reg-only in this version: on position `{index}`: {found:?}")] + InvalidRegImmInPlaceOfReg { + index: usize, + found: NonMemoryOperand, + }, + /// The invalid instruction argument. + #[error("invalid operand for location that is label-only: on position `{index}`: {found:?}")] + InvalidOperandForLabelLocation { index: usize, found: FullOperand }, + /// The invalid number of arguments. + #[error( + "invalid number of arguments: expected `{0}`, found `{1}`", + expected, + found + )] + InvalidArgumentCount { + /// The expected number of arguments. + expected: usize, + /// The invalid actual number of arguments. + found: usize, + }, + /// The unknown argument error. + #[error("unknown argument `{0}`")] + UnknownArgument(String), + #[error( + "subtraction and negative literals are only supported in memory offsets, not in immediates" + )] + UnexpectedSubtraction, + #[error("integer overflow when computing the immediate")] + IntegerOverflow, + #[error("unknown symbol or label `{0}`")] + UnknownLabel(String), + #[error("unknown mnemonic `{0}`")] + UnknownMnemonic(String), + #[error("unexpected constant-like line {0:?} not in section")] + UnexpectedConstant(String), + #[error("unexpected line {0:?} in Text section")] + UnexpectedInstruction(String), + #[error("duplicate modifier `{0}` in the instruction")] + DuplicateModifier(String), + #[error("code is too long, can address {0} opcodes at maximum, encountered {1}")] + TooManyOpcodes(u64, u64), + #[error("code is too long, can address {0} words at maximum, encountered {1}")] + CodeIsTooLong(u64, u64), + // #[error("opcode has specific requirements for source and destination for it's variant `{0}`")] + // UnknownSourceOrDestination(String), +} + +#[derive(Debug, Error, PartialEq)] +pub enum BinaryParseError { + #[error("use_mem flag must be reset in Memory instruction")] + MemoryOpcodeInvalidFlag, + #[error("force stack flag can only be set for Stack memory type")] + UnexpectedForceStackFlag, + #[error("invalid register selector. At most one register can be selected per position.")] + InvalidRegisterSelector, + #[error("bytecode cannot be empty")] + EmptyBytecode, + #[error("bytecode length in bytes must be a multiple of {0}")] + InvalidBytecodeLength(usize), + #[error("bytecode length in bytes must be less than {0}")] + BytecodeTooLong(usize), + #[error("invalid opcode")] + InvalidOpcode, + #[error("Supported context fields indices: 0-5")] + UnknownContextField, +} diff --git a/crates/zkEVM-assembly/src/lib.rs b/crates/zkEVM-assembly/src/lib.rs new file mode 100644 index 0000000..1268b65 --- /dev/null +++ b/crates/zkEVM-assembly/src/lib.rs @@ -0,0 +1,84 @@ +//! +//! The zkEVM common library. +//! + +#![allow(dead_code)] + +#[cfg(test)] +#[rustfmt::skip] +mod tests; + +pub(crate) mod assembly; +pub(crate) mod error; + +pub use zkevm_opcode_defs; +pub use zkevm_opcode_defs::ISAVersion; + +pub use self::assembly::instruction::add::Add as AddInstruction; +pub use self::assembly::instruction::bitwise::Bitwise as BitwiseInstruction; +pub use self::assembly::instruction::context::Context as ContextInstruction; +pub use self::assembly::instruction::div::Div as DivInstruction; +pub use self::assembly::instruction::far_call::FarCall as ExternalCallInstruction; +pub use self::assembly::instruction::jump::Jump as JumpInstruction; +pub use self::assembly::instruction::mul::Mul as MulInstruction; +pub use self::assembly::instruction::near_call::NearCall as LocalCallInstruction; +pub use self::assembly::instruction::nop::Nop as NopInstruction; +pub use self::assembly::instruction::ret::Ret as ReturnInstruction; +pub use self::assembly::instruction::shift::Shift as ShiftInstruction; +pub use self::assembly::instruction::sub::Sub as SubInstruction; + +pub use self::assembly::instruction::Instruction; +pub use self::assembly::operand::FullOperand; +pub use self::assembly::operand::RegisterOperand; +pub use self::assembly::Assembly; +pub use self::error::{AssemblyParseError, BinaryParseError, InstructionReadError}; + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[repr(u64)] +pub enum RunningVmEncodingMode { + Production = 0, + Testing = 1, +} + +impl RunningVmEncodingMode { + pub const fn from_u64(value: u64) -> Self { + match value { + x if x == Self::Production as u64 => Self::Production, + x if x == Self::Testing as u64 => Self::Testing, + _ => unreachable!(), + } + } + + pub const fn as_u64(self) -> u64 { + self as u64 + } +} + +use std::sync::atomic::AtomicU64; + +pub static ENCODING_MODE: AtomicU64 = AtomicU64::new(RunningVmEncodingMode::Production as u64); + +pub fn set_encoding_mode(value: RunningVmEncodingMode) { + ENCODING_MODE.store(value.as_u64(), std::sync::atomic::Ordering::SeqCst); +} + +pub fn get_encoding_mode() -> RunningVmEncodingMode { + RunningVmEncodingMode::from_u64(ENCODING_MODE.load(std::sync::atomic::Ordering::Relaxed)) +} + +pub const DEFAULT_ISA_VERSION: ISAVersion = ISAVersion(2); + +const _: () = if DEFAULT_ISA_VERSION.0 != zkevm_opcode_defs::DEFAULT_ISA_VERSION.0 { + panic!() +} else { +}; + +pub static ISA_VERSION_U64: AtomicU64 = AtomicU64::new(DEFAULT_ISA_VERSION.0 as u64); + +pub fn set_isa_version(value: ISAVersion) { + ISA_VERSION_U64.store(value.0 as u64, std::sync::atomic::Ordering::SeqCst); +} + +pub fn get_isa_version() -> ISAVersion { + ISAVersion(ISA_VERSION_U64.load(std::sync::atomic::Ordering::Relaxed) as u8) +} diff --git a/crates/zkEVM-assembly/src/reader/arguments.rs b/crates/zkEVM-assembly/src/reader/arguments.rs new file mode 100644 index 0000000..e89fd87 --- /dev/null +++ b/crates/zkEVM-assembly/src/reader/arguments.rs @@ -0,0 +1,36 @@ +//! +//! zkEVM assembly reader arguments. +//! + +use std::path::PathBuf; +use structopt::StructOpt; + +/// +/// zkEVM assembly reader arguments. +/// +#[derive(Debug, StructOpt)] +#[structopt(name = "zkEVM assembly reader")] +pub struct Arguments { + /// Input file path. + #[structopt(parse(from_os_str))] + pub input: PathBuf, + + /// Output file, stdout if not present + #[structopt(parse(from_os_str))] + pub output: Option, +} + +impl Arguments { + /// + /// A shortcut constructor. + /// + pub fn new() -> Self { + Self::from_args() + } +} + +impl Default for Arguments { + fn default() -> Self { + Self::new() + } +} diff --git a/crates/zkEVM-assembly/src/reader/main.rs b/crates/zkEVM-assembly/src/reader/main.rs new file mode 100644 index 0000000..9555445 --- /dev/null +++ b/crates/zkEVM-assembly/src/reader/main.rs @@ -0,0 +1,46 @@ +//! +//! zkEVM assembly reader binary. +//! + +pub mod arguments; + +use zkevm_opcode_defs::decoding::EncodingModeProduction; + +use self::arguments::Arguments; +use std::{convert::TryFrom, io::Write}; + +/// +/// The application entry point. +/// +fn main() { + env_logger::init(); + + let args = Arguments::new(); + + let mut assembly = + zkevm_assembly::Assembly::try_from(args.input).expect("Assembly file reading"); + + let serialized = assembly + .compile_to_bytecode_for_mode::<8, EncodingModeProduction>() + .expect("Must compile the bytecode"); + + let mut pretty_bytecode = String::with_capacity((64 + 2) * serialized.len() + 100); + for el in serialized.into_iter() { + std::fmt::write(&mut pretty_bytecode, format_args!("{}", hex::encode(el))) + .expect("Error occurred while trying to write in String"); + } + + if let Some(path) = args.output { + let mut file = std::fs::OpenOptions::new() + .create(true) + .write(true) + .open(path) + .expect("can not open an output file"); + file.write_all(pretty_bytecode.as_bytes()) + .expect("can not write to file"); + } else { + std::io::stdout() + .write_all(pretty_bytecode.as_bytes()) + .expect("can not write to stdout"); + } +} diff --git a/crates/zkEVM-assembly/src/tests/assembly.rs b/crates/zkEVM-assembly/src/tests/assembly.rs new file mode 100644 index 0000000..4a251f4 --- /dev/null +++ b/crates/zkEVM-assembly/src/tests/assembly.rs @@ -0,0 +1,849 @@ +use crate::assembly::instruction::jump::flag::Flag; +use crate::assembly::instruction::Instruction::NoOperation; +use crate::{Assembly, AssemblyParseError, DataOperation, FullOperand, Instruction, InstructionReadError, JumpInstruction, MemoryInstruction, MemoryOperand, MemoryType, RegisterOperand, ShuffleInstruction, FunctionJumpInstruction, FunctionJumpLocation, ContextInstruction, ContextField, StorageInstruction, BitwiseInstruction, BitwiseOpType, ShiftInstruction}; +use std::convert::{TryFrom, TryInto}; +use std::collections::HashMap; +use std::iter::FromIterator; +use std::array::IntoIter; + +#[test] +fn test_noop() { + let asm_text = r#" + .text + nop + "#; + + let asm = Assembly::try_from(asm_text.to_owned()); + + assert_eq!( + asm, + Ok(Assembly { + instructions: vec![NoOperation], + labels: HashMap::new(), + pc_line_mapping: [(0, 3)] + .iter() + .cloned() + .collect(), + assembly_code: String::from(asm_text), + }) + ) +} + +#[test] +fn test_invalid_layout() { + let asm_text = r#" + .text + nop + .data + arr: + .quad 1 + .data + "#; + + let asm = Assembly::try_from(asm_text.to_owned()); + assert_eq!(asm, Err(AssemblyParseError::AssemblerLayoutError)) +} + +#[test] +fn test_memory_syntax() { + let asm_text = r#" + .text + mov 10, r2 + mov.p 10, r2 + mov.c r2, 10 + mov r1, arr+10 + mov 10(sp), r2 + mov arr(sp), r2 + mov arr(r3), r2 + mov arr+19(r4), r2 + mov arr+17(sp), r2 + mov arr+17(sp-r5), r2 + .data + unused: + .zero 1 ; 1 byte + arr: + .word 777 ; 2 bytes + "#; + let asm = Assembly::try_from(asm_text.to_owned()); + assert_eq!( + asm, + Ok(Assembly { + instructions: vec![ + // HEAP SYMBOLS + // `unused` + Instruction::Shuffle(ShuffleInstruction { + source_1: FullOperand::Immediate(0), + source_2: RegisterOperand::Null, + destination: RegisterOperand::Register(0), + load_in_low: true, + }), + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::Local, + offset: 0, + register: RegisterOperand::Null, + }, + operation: DataOperation::Write { + source: RegisterOperand::Register(0) + }, + }), + // `arr` + Instruction::Shuffle(ShuffleInstruction { + source_1: FullOperand::Immediate(777), + source_2: RegisterOperand::Null, + destination: RegisterOperand::Register(0), + load_in_low: true, + }), + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::Local, + offset: 1, + register: RegisterOperand::Null, + }, + operation: DataOperation::Write { + source: RegisterOperand::Register(0) + }, + }), + // PROGRAM CODE + // mov 10, r2 + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::Local, + offset: 10, + register: RegisterOperand::Null, + }, + operation: DataOperation::Read { + destination: RegisterOperand::Register(1) + }, + }), + // mov.p 10, r2 + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::SharedParent, + offset: 10, + register: RegisterOperand::Null, + }, + operation: DataOperation::Read { + destination: RegisterOperand::Register(1) + }, + }), + // mov.c r2, 10 + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::SharedChild, + offset: 10, + register: RegisterOperand::Null, + }, + operation: DataOperation::Write { + source: RegisterOperand::Register(1) + }, + }), + // mov r1, arr+10 + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::Local, + offset: 1 + 10, + register: RegisterOperand::Null, + }, + operation: DataOperation::Write { + source: RegisterOperand::Register(0) + }, + }), + // mov 10(sp), r2 + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::Stack { force: false }, + offset: 10, + register: RegisterOperand::Null, + }, + operation: DataOperation::Read { + destination: RegisterOperand::Register(1) + }, + }), + // mov arr(sp), r2 + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::Stack { force: false }, + offset: 1, + register: RegisterOperand::Null, + }, + operation: DataOperation::Read { + destination: RegisterOperand::Register(1) + }, + }), + // mov arr(r3), r2 + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::Local, + offset: 1, + register: RegisterOperand::Register(2), + }, + operation: DataOperation::Read { + destination: RegisterOperand::Register(1) + }, + }), + // mov arr+19(r4), r2 + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::Local, + offset: 1 + 19, + register: RegisterOperand::Register(3), + }, + operation: DataOperation::Read { + destination: RegisterOperand::Register(1) + }, + }), + // mov arr+17(sp), r2 + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::Stack { force: false }, + offset: 1 + 17, + register: RegisterOperand::Null, + }, + operation: DataOperation::Read { + destination: RegisterOperand::Register(1) + }, + }), + // mov arr+17(sp-r5), r2 + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::Stack { force: false }, + offset: 1 + 17, + register: RegisterOperand::Register(4), + }, + operation: DataOperation::Read { + destination: RegisterOperand::Register(1) + }, + }) + ], + labels: HashMap::from_iter(IntoIter::new([("unused".to_owned(), 0), ("arr".to_owned(), 1)])), + pc_line_mapping: + [(4, 3), (5, 4), (6, 5), (7, 6), (8, 7), (9, 8), (10, 9), (11, 10), (12, 11), (13, 12)] + .iter() + .cloned() + .collect(), + assembly_code: String::from(asm_text), + }) + ) +} + +#[test] +fn test_push_pop() { + let asm_text = r#" + .text + pop #10, r2 + push #3, r1 + "#; + let asm = Assembly::try_from(asm_text.to_owned()); + assert_eq!( + asm, + Ok(Assembly { + instructions: vec![ + // PROGRAM CODE + // pop #10, r2 + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::Stack { force: true }, + offset: 10, + register: RegisterOperand::Null, + }, + operation: DataOperation::Read { + destination: RegisterOperand::Register(1) + }, + }), + // push #3, r1 + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::Stack { force: true }, + offset: 3, + register: RegisterOperand::Null, + }, + operation: DataOperation::Write { + source: RegisterOperand::Register(0) + }, + }), + ], + labels: HashMap::new(), + pc_line_mapping: + [(0, 3), (1, 4)] + .iter() + .cloned() + .collect(), + assembly_code: String::from(asm_text), + }) + ) +} + +#[test] +fn test_memory_operand_syntax() { + let asm_text = r#" + .text + sfll #arr, r0, r1 + sflh #arr+5, r0, r1 + sflh arr+5, r0, r1 + sflh r4, r0, r1 + sfll arr+17(r3), r5, r1 + sfll arr-17(r3), r5, r1 + sfll -42(r1), r5, r1 + .data + unused: + .zero 1 ; 1 byte + arr: + .word 777 ; 2 bytes + "#; + let asm = Assembly::try_from(asm_text.to_owned()); + assert_eq!( + asm, + Ok(Assembly { + instructions: vec![ + // HEAP SYMBOLS + // `unused` + Instruction::Shuffle(ShuffleInstruction { + source_1: FullOperand::Immediate(0), + source_2: RegisterOperand::Null, + destination: RegisterOperand::Register(0), + load_in_low: true, + }), + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::Local, + offset: 0, + register: RegisterOperand::Null, + }, + operation: DataOperation::Write { + source: RegisterOperand::Register(0) + }, + }), + // `arr` + Instruction::Shuffle(ShuffleInstruction { + source_1: FullOperand::Immediate(777), + source_2: RegisterOperand::Null, + destination: RegisterOperand::Register(0), + load_in_low: true, + }), + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::Local, + offset: 1, + register: RegisterOperand::Null, + }, + operation: DataOperation::Write { + source: RegisterOperand::Register(0) + }, + }), + // PROGRAM CODE + // sfll #arr, r0, r1 + Instruction::Shuffle(ShuffleInstruction { + source_1: FullOperand::Immediate(1), // arr = 1 + source_2: RegisterOperand::Null, + destination: RegisterOperand::Register(0), + load_in_low: true, + }), + // sflh #arr+5, r0, r1 + Instruction::Shuffle(ShuffleInstruction { + source_1: FullOperand::Immediate(1 + 5), // arr = 1 + source_2: RegisterOperand::Null, + destination: RegisterOperand::Register(0), + load_in_low: false, + }), + // sflh arr+5, r0, r1 + Instruction::Shuffle(ShuffleInstruction { + source_1: FullOperand::Memory(MemoryOperand { + r#type: MemoryType::Local, + offset: 6, + register: RegisterOperand::Null, + }), + source_2: RegisterOperand::Null, + destination: RegisterOperand::Register(0), + load_in_low: false, + }), + // sflh r4, r0, r1 + Instruction::Shuffle(ShuffleInstruction { + source_1: FullOperand::Register(RegisterOperand::Register(3)), + source_2: RegisterOperand::Null, + destination: RegisterOperand::Register(0), + load_in_low: false, + }), + // sfll arr+17(r3), r5, r1 + Instruction::Shuffle(ShuffleInstruction { + source_1: FullOperand::Memory(MemoryOperand { + r#type: MemoryType::Local, + offset: 18, + register: RegisterOperand::Register(2), + }), + source_2: RegisterOperand::Register(4), + destination: RegisterOperand::Register(0), + load_in_low: true, + }), + // sfll arr-17(r3), r5, r1 + Instruction::Shuffle(ShuffleInstruction { + source_1: FullOperand::Memory(MemoryOperand { + r#type: MemoryType::Local, + offset: 1u16.wrapping_sub(17), + register: RegisterOperand::Register(2), + }), + source_2: RegisterOperand::Register(4), + destination: RegisterOperand::Register(0), + load_in_low: true, + }), + // sfll -42(r1), r5, r1 + Instruction::Shuffle(ShuffleInstruction { + source_1: FullOperand::Memory(MemoryOperand { + r#type: MemoryType::Local, + offset: 0u16.wrapping_sub(42), + register: RegisterOperand::Register(0), + }), + source_2: RegisterOperand::Register(4), + destination: RegisterOperand::Register(0), + load_in_low: true, + }), + ], + labels: HashMap::from_iter(IntoIter::new([("unused".to_owned(), 0), ("arr".to_owned(), 1)])), + pc_line_mapping: + [(4, 3), (5, 4), (6, 5), (7, 6), (8, 7), (9, 8), (10, 9)] + .iter() + .cloned() + .collect(), + assembly_code: String::from(asm_text), + }) + ) +} + +#[test] +fn test_label_parsing() { + let asm_text = r#" + .text + round_up_to_mul_of_32: + call round_up_to_mul_of_32 + "#; + let asm = Assembly::try_from(asm_text.to_owned()); + assert_eq!( + asm, + Ok(Assembly { + instructions: vec![ + Instruction::FunctionJump(FunctionJumpInstruction::Call { + location: FunctionJumpLocation::Local { + address: 0, + operand: FullOperand::Register(RegisterOperand::Null), + } + }) + ], + labels: HashMap::from_iter(IntoIter::new([("round_up_to_mul_of_32".to_owned(), 0)])), + pc_line_mapping: + [(0, 4)] + .iter() + .cloned() + .collect(), + assembly_code: String::from(asm_text), + }) + ) +} + +#[test] +fn test_heap_allocation_multiple_symbols() { + let asm_text = r#" + .text + j label, label + mov arr1+1(sp-r3), r2 + mov r0, arr2(r3) + sfll #arr3, r0, r1 + label: + nop + .data + arr1: ; will have heap offset 0 + .byte 255 ; 1 byte + .word 12 ; 1 + 2 = 3 bytes + .quad 8 ; 3 + 4 = 7 bytes + .zero 1 ; 7 + 1 = 8 bytes + .zero 26 ; 8 + 26 = 34 bytes in total - occupies two slots in heap + arr2: ; will have heap offset 2 + .byte 200 ; 1 byte + arr3: ; will have heap offset 3 + .zero 7 ; 7 bytes + .byte 100 ; 7 + 1 = 8 bytes + "#; + + let asm = Assembly::try_from(asm_text.to_owned()); + + let mut arr1_first_u128_bytes = vec![255u8, 12u8, 0u8, 8u8]; + arr1_first_u128_bytes.resize(16, 0); + + assert_eq!( + asm, + Ok(Assembly { + instructions: vec![ + // arr1: first 256 bits + Instruction::Shuffle(ShuffleInstruction { + source_1: FullOperand::Immediate(u128::from_le_bytes( + arr1_first_u128_bytes.try_into().unwrap() + )), + source_2: RegisterOperand::Null, + destination: RegisterOperand::Register(0), + load_in_low: true, + }), + Instruction::Shuffle(ShuffleInstruction { + source_1: FullOperand::Immediate(0), + source_2: RegisterOperand::Register(0), + destination: RegisterOperand::Register(0), + load_in_low: false, + }), + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::Local, + offset: 0, + register: RegisterOperand::Null, + }, + operation: DataOperation::Write { + source: RegisterOperand::Register(0) + }, + }), + // arr1: second 256 bits + Instruction::Shuffle(ShuffleInstruction { + source_1: FullOperand::Immediate(0), + source_2: RegisterOperand::Null, + destination: RegisterOperand::Register(0), + load_in_low: true, + }), + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::Local, + offset: 1, + register: RegisterOperand::Null, + }, + operation: DataOperation::Write { + source: RegisterOperand::Register(0) + }, + }), + // arr2 + Instruction::Shuffle(ShuffleInstruction { + source_1: FullOperand::Immediate(200u128), + source_2: RegisterOperand::Null, + destination: RegisterOperand::Register(0), + load_in_low: true, + }), + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::Local, + offset: 2, + register: RegisterOperand::Null, + }, + operation: DataOperation::Write { + source: RegisterOperand::Register(0) + }, + }), + // arr3 + Instruction::Shuffle(ShuffleInstruction { + source_1: FullOperand::Immediate(100u128 << (7 * 8)), // first 7 bytes are zero + source_2: RegisterOperand::Null, + destination: RegisterOperand::Register(0), + load_in_low: true, + }), + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::Local, + offset: 3, + register: RegisterOperand::Null, + }, + operation: DataOperation::Write { + source: RegisterOperand::Register(0) + }, + }), + // program code + Instruction::Jump(JumpInstruction { + source: FullOperand::Register(RegisterOperand::Null), + flags: vec![Flag::Unconditional], + destination_true: 13, // originally label points to `4`, but we prepend with 9 instructions + destination_false: 13, + }), + // move arr+1(sp-r3), r2 + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::Stack { force: false }, + offset: 0 + 1, // arr + 1 + register: RegisterOperand::Register(2), + }, + operation: DataOperation::Read { + destination: RegisterOperand::Register(1) + }, + }), + // mov r0, arr2(r3) + Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::Local, + offset: 2, // arr + register: RegisterOperand::Register(2), + }, + operation: DataOperation::Write { + source: RegisterOperand::Null + }, + }), + // sfll #arr3, r0, r1 + Instruction::Shuffle(ShuffleInstruction { + source_1: FullOperand::Immediate(3), //arr3 = 3 + source_2: RegisterOperand::Null, + destination: RegisterOperand::Register(0), + load_in_low: true, + }), + Instruction::NoOperation + ], + labels: HashMap::from_iter(IntoIter::new([("arr3".to_owned(), 3), ("arr2".to_owned(), 2), ("arr1".to_owned(), 0), ("label".to_owned(), 13)])), + pc_line_mapping: [(9, 3), (10, 4), (11, 5), (12, 6), (13, 8)] + .iter() + .cloned() + .collect(), + assembly_code: String::from(asm_text), + }) + ) +} + +#[test] +fn test_context_mnemonics() { + let asm_text = r#" + .text + ctx #3, r3 + "#; + + let asm = Assembly::try_from(asm_text.to_owned()); + + assert_eq!( + asm, + Ok(Assembly { + instructions: vec![ + // arr1: first 256 bits + Instruction::Context(ContextInstruction { + destination: RegisterOperand::Register(2), + field: ContextField::GasLeft, + }) + ], + labels: HashMap::new(), + pc_line_mapping: [(0, 3)] + .iter() + .cloned() + .collect(), + assembly_code: String::from(asm_text), + }) + ) +} + +#[test] +fn test_invalid_number() { + let asm_text = r#" + .text + nop + .data + arr: + .quad 1q + "#; + + let asm = Assembly::try_from(asm_text.to_owned()); + + if let Err(AssemblyParseError::LineReadError(errors)) = asm { + assert!(matches!( + errors.get(&6), + Some(InstructionReadError::InvalidNumber(_, _)) + )); + } else { + panic!("unexpected result: {:?}", asm) + } +} + +#[test] +fn test_unknown_vars() { + let asm_text = r#" + .text + nop + mov arr, r0 + label: + mov r1, arr2 + mov unk, r4 + j label, label + j unko, unko2 + .data + arr: + .quad 1 + "#; + + let asm = Assembly::try_from(asm_text.to_owned()); + + if let Err(AssemblyParseError::LineReadError(errors)) = asm { + assert_eq!(errors.len(), 3); + assert!(matches!( + errors.get(&6), + Some(InstructionReadError::UnknownLabel(_)) + )); + assert!(matches!( + errors.get(&7), + Some(InstructionReadError::UnknownLabel(_)) + )); + assert!(matches!( + errors.get(&9), + Some(InstructionReadError::UnknownLabel(_)) + )); + } else { + panic!("unexpected result: {:?}", asm) + } +} + +#[test] +fn test_events() { + let asm_text = r#" + .text + sfll #32, r0, r1 + evt.i #2, r1 + evt #777, r3 + evt #123, r0 + "#; + + let asm = Assembly::try_from(asm_text.to_owned()); + + assert_eq!(Ok( + Assembly { + instructions: vec![ + Instruction::Shuffle(ShuffleInstruction { + source_1: FullOperand::Immediate(32), + source_2: RegisterOperand::Null, + destination: RegisterOperand::Register(0), + load_in_low: true, + }), + Instruction::Storage(StorageInstruction::LogInit { + packed_lengths: FullOperand::Immediate(2), + first_topic_or_chunk: RegisterOperand::Register(0), + }), + Instruction::Storage(StorageInstruction::Log(FullOperand::Immediate(777), RegisterOperand::Register(2))), + Instruction::Storage(StorageInstruction::Log(FullOperand::Immediate(123), RegisterOperand::Null)), + ], + labels: Default::default(), + pc_line_mapping: [(0, 3), (1, 4), (2, 5), (3, 6)] + .iter() + .cloned() + .collect(), + assembly_code: String::from(asm_text), + } + ), asm) +} + +#[test] +fn test_storage() { + let asm_text = r#" + .text + sfll #366, r0, r1 + st r1, #533 + ret + "#; + + let asm = Assembly::try_from(asm_text.to_owned()); + + assert_eq!(Ok( + Assembly { + instructions: vec![ + Instruction::Shuffle(ShuffleInstruction { + source_1: FullOperand::Immediate(366), + source_2: RegisterOperand::Null, + destination: RegisterOperand::Register(0), + load_in_low: true, + }), + Instruction::Storage(StorageInstruction::Storage { + storage_key: FullOperand::Immediate(533), + operation: DataOperation::Write { source: RegisterOperand::Register(0) }, + is_external_storage_access: false, + }), + Instruction::FunctionJump(FunctionJumpInstruction::Return { error: false }) + ], + labels: Default::default(), + pc_line_mapping: [(0, 3), (1, 4), (2, 5)] + .iter() + .cloned() + .collect(), + assembly_code: String::from(asm_text), + } + ), asm) +} + +#[test] +fn test_bitwise_xor() { + let asm_text = r#" + .text + xor r1, r2, r3 + "#; + + let asm = Assembly::try_from(asm_text.to_owned()); + + assert_eq!(Ok( + Assembly { + instructions: vec![ + Instruction::Bitwise(BitwiseInstruction { + source_1: FullOperand::Register(RegisterOperand::Register(0)), + source_2: RegisterOperand::Register(1), + destination: RegisterOperand::Register(2), + op_type: BitwiseOpType::Xor, + }), + ], + labels: Default::default(), + pc_line_mapping: [(0, 3)] + .iter() + .cloned() + .collect(), + assembly_code: String::from(asm_text), + } + ), asm) +} + +#[test] +fn test_bitwise_shift() { + let asm_text = r#" + .text + shl r2, r1, r3 + "#; + + let asm = Assembly::try_from(asm_text.to_owned()); + + assert_eq!(Ok( + Assembly { + instructions: vec![ + Instruction::Shift(ShiftInstruction { + source_1: FullOperand::Register(RegisterOperand::Register(0)), + source_2: RegisterOperand::Register(1), + destination: RegisterOperand::Register(2), + is_cyclic: false, + is_right: false, + }), + ], + labels: Default::default(), + pc_line_mapping: [(0, 3)] + .iter() + .cloned() + .collect(), + assembly_code: String::from(asm_text), + } + ), asm) +} + +#[test] +fn test_bitwise_cycle_right() { + let asm_text = r#" + .text + ror r2, r1, r3 + "#; + + let asm = Assembly::try_from(asm_text.to_owned()); + + assert_eq!(Ok( + Assembly { + instructions: vec![ + Instruction::Shift(ShiftInstruction { + source_1: FullOperand::Register(RegisterOperand::Register(0)), + source_2: RegisterOperand::Register(1), + destination: RegisterOperand::Register(2), + is_cyclic: true, + is_right: true, + }), + ], + labels: Default::default(), + pc_line_mapping: [(0, 3)] + .iter() + .cloned() + .collect(), + assembly_code: String::from(asm_text), + } + ), asm) +} diff --git a/crates/zkEVM-assembly/src/tests/binary.rs b/crates/zkEVM-assembly/src/tests/binary.rs new file mode 100644 index 0000000..4a79fa9 --- /dev/null +++ b/crates/zkEVM-assembly/src/tests/binary.rs @@ -0,0 +1,830 @@ +use crate::assembly::instruction::function_jump::location::Location; +use crate::assembly::instruction::jump::flag::Flag; +use crate::assembly::operand::RegisterOperand::Register; +use crate::error::BinaryParseError; +use crate::{AddInstruction, Assembly, DataOperation, DivInstruction, FullOperand, FunctionJumpInstruction, HashAbsorbInstruction, HashOutputInstruction, Instruction, JumpInstruction, MemoryInstruction, MemoryOperand, MemoryType, MulInstruction, RegisterOperand, SetExternalAddressInstruction, ShuffleInstruction, StorageInstruction, SubInstruction, ContextInstruction, ContextField, BitwiseInstruction, BitwiseOpType, ShiftInstruction}; +use std::convert::{TryFrom, TryInto}; +use std::collections::HashMap; + +#[test] +fn test_noop() { + let input: u64 = 0b10010; + let mut bytecode = input.to_le_bytes().to_vec(); + bytecode.resize(32, 0); + let assembly = Assembly::try_from(&bytecode); + assert_eq!( + assembly, + Ok(Assembly { + instructions: vec![Instruction::NoOperation], + labels: HashMap::new(), + assembly_code: String::new(), + pc_line_mapping: HashMap::new(), + }) + ) +} + +#[test] +fn test_shuffle() { + // 0bmemf_flag_outrg2_outrg1_inreg2_inreg1_opcode + let input: u64 = 0b0000_0001_000001_100000_000000_000010_00001100; + let mut bytecode = input.to_le_bytes().to_vec(); + bytecode.resize(32, 0); + let assembly = Assembly::try_from(&bytecode); + assert_eq!( + assembly, + Ok(Assembly { + instructions: vec![Instruction::Shuffle(ShuffleInstruction { + source_1: FullOperand::Register(Register(1)), + source_2: RegisterOperand::Null, + destination: RegisterOperand::Register(5), + load_in_low: true, + })], + labels: HashMap::new(), + assembly_code: String::new(), + pc_line_mapping: HashMap::new(), + }) + ) +} + +#[test] +fn test_mul_memory() { + // 0b imm_memf_flag_outrg2_outrg1_inreg2_inreg1_opcode + let input: u128 = 0b1111_1111_0000_000000_100000_100000_000100_00000110; + let mut bytecode = input.to_le_bytes().to_vec(); + bytecode.resize(32, 0); + let assembly = Assembly::try_from(&bytecode); + assert_eq!( + assembly, + Ok(Assembly { + instructions: vec![Instruction::Mul(MulInstruction { + source_1: FullOperand::Memory(MemoryOperand { + r#type: MemoryType::Stack { force: true }, + offset: 0b1111, + register: RegisterOperand::Register(2), + }), + source_2: RegisterOperand::Register(5), + destination_1: RegisterOperand::Register(5), + destination_2: RegisterOperand::Null, + })], + labels: HashMap::new(), + assembly_code: String::new(), + pc_line_mapping: HashMap::new(), + }) + ); + + let instruction = assembly.unwrap().instructions.pop().unwrap(); + let converted_back = + u128::from_le_bytes(Vec::::from(instruction)[0..16].try_into().unwrap()); + assert_eq!(input, converted_back); +} + +#[test] +fn test_sum() { + // 0b imm_memf_flag_outrg2_outrg1_inreg2_inreg1_opcode + let input: u128 = 0b0000_0000_0000_000000_001000_000000_000000_00000010; + let mut bytecode = input.to_le_bytes().to_vec(); + bytecode.resize(32, 0); + let assembly = Assembly::try_from(&bytecode); + assert_eq!( + assembly, + Ok(Assembly { + instructions: vec![Instruction::Add(AddInstruction { + source_1: FullOperand::Immediate(0), + source_2: RegisterOperand::Null, + destination: RegisterOperand::Register(3), + })], + labels: HashMap::new(), + assembly_code: String::new(), + pc_line_mapping: HashMap::new(), + }) + ); + + let instruction = assembly.unwrap().instructions.pop().unwrap(); + let converted_back = + u128::from_le_bytes(Vec::::from(instruction)[0..16].try_into().unwrap()); + assert_eq!(input, converted_back); +} + +#[test] +fn test_mul_memory_operand() { + // 0b imm_memf_flag_outrg2_outrg1_inreg2_inreg1_opcode + let input: u128 = 0b1111_1111_0000_000000_100000_100000_000100_00000110; + let mut bytecode = input.to_le_bytes().to_vec(); + bytecode.resize(32, 0); + let assembly = Assembly::try_from(&bytecode); + assert_eq!( + assembly, + Ok(Assembly { + instructions: vec![Instruction::Mul(MulInstruction { + source_1: FullOperand::Memory(MemoryOperand { + r#type: MemoryType::Stack { force: true }, + offset: 0b1111, + register: RegisterOperand::Register(2), + }), + source_2: RegisterOperand::Register(5), + destination_1: RegisterOperand::Register(5), + destination_2: RegisterOperand::Null, + })], + labels: HashMap::new(), + assembly_code: String::new(), + pc_line_mapping: HashMap::new(), + }) + ); + + let instruction = assembly.unwrap().instructions.pop().unwrap(); + let converted_back = + u128::from_le_bytes(Vec::::from(instruction)[0..16].try_into().unwrap()); + assert_eq!(input, converted_back); +} + +#[test] +fn test_mul_memory_invalid_stack_flag() { + // 0b imm_memf_flag_outrg2_outrg1_inreg2_inreg1_opcode + let input: u64 = 0b1111_1100_0000_000000_100000_100000_000100_00000110; + let mut bytecode = input.to_le_bytes().to_vec(); + bytecode.resize(32, 0); + let assembly = Assembly::try_from(&bytecode); + assert_eq!(assembly, Err(BinaryParseError::UnexpectedForceStackFlag)); +} + +#[test] +fn test_sub_memory() { + // 0b imm_memf_flag_outrg2_outrg1_inreg2_inreg1_opcode + let input: u128 = 0b1101_0011_0001_000000_100000_100000_000100_00000100; + let mut bytecode = input.to_le_bytes().to_vec(); + bytecode.resize(32, 0); + let assembly = Assembly::try_from(&bytecode); + assert_eq!( + assembly, + Ok(Assembly { + instructions: vec![Instruction::Sub(SubInstruction { + source_1: FullOperand::Memory(MemoryOperand { + r#type: MemoryType::Local, + offset: 0b1101, + register: RegisterOperand::Register(2), + }), + source_2: RegisterOperand::Register(5), + destination: RegisterOperand::Register(5), + swap_operands: true, + })], + labels: HashMap::new(), + assembly_code: String::new(), + pc_line_mapping: HashMap::new(), + }) + ); + + let instruction = assembly.unwrap().instructions.pop().unwrap(); + let converted_back = + u128::from_le_bytes(Vec::::from(instruction)[0..16].try_into().unwrap()); + assert_eq!(input, converted_back); +} + +#[test] +fn test_div() { + // 0b imm_memf_flag_outrg2_outrg1_inreg2_inreg1_opcode + let input: u128 = 0b0000_0000_0000_001000_000100_000010_000001_00001000; + let mut bytecode = input.to_le_bytes().to_vec(); + bytecode.resize(32, 0); + let assembly = Assembly::try_from(&bytecode); + assert_eq!( + assembly, + Ok(Assembly { + instructions: vec![Instruction::Div(DivInstruction { + source_1: FullOperand::Register(RegisterOperand::Register(0)), + source_2: RegisterOperand::Register(1), + quotient_destination: RegisterOperand::Register(2), + remainder_destination: RegisterOperand::Register(3), + swap_operands: false, + })], + labels: HashMap::new(), + assembly_code: String::new(), + pc_line_mapping: HashMap::new(), + }) + ); + + let instruction = assembly.unwrap().instructions.pop().unwrap(); + let converted_back = + u128::from_le_bytes(Vec::::from(instruction)[0..16].try_into().unwrap()); + assert_eq!(input, converted_back); +} + +#[test] +fn test_memory_read() { + // 0b imm_memf_flag_outrg2_outrg1_inreg2_inreg1_opcode + let input: u128 = 0b1001_0010_0001_000000_100000_000000_000100_00001110; + let mut bytecode = input.to_le_bytes().to_vec(); + bytecode.resize(32, 0); + + let assembly = Assembly::try_from(&bytecode); + assert_eq!( + assembly, + Ok(Assembly { + instructions: vec![Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::Local, + offset: 0b1001, + register: RegisterOperand::Register(2), + }, + operation: DataOperation::Read { + destination: RegisterOperand::Register(5) + }, + })], + labels: HashMap::new(), + assembly_code: String::new(), + pc_line_mapping: HashMap::new(), + }) + ); + + let instruction = assembly.unwrap().instructions.pop().unwrap(); + let converted_back = + u128::from_le_bytes(Vec::::from(instruction)[0..16].try_into().unwrap()); + assert_eq!(input, converted_back); +} + +#[test] +fn test_memory_write() { + // 0b imm_memf_flag_outrg2_outrg1_inreg2_inreg1_opcode + let input: u128 = 0b1001_0100_0000_000000_000000_000010_000100_00001110; + let mut bytecode = input.to_le_bytes().to_vec(); + bytecode.resize(32, 0); + + let assembly = Assembly::try_from(&bytecode); + assert_eq!( + assembly, + Ok(Assembly { + instructions: vec![Instruction::Memory(MemoryInstruction { + address: MemoryOperand { + r#type: MemoryType::SharedChild, + offset: 0b1001, + register: RegisterOperand::Register(2), + }, + operation: DataOperation::Write { + source: RegisterOperand::Register(1) + }, + })], + labels: HashMap::new(), + assembly_code: String::new(), + pc_line_mapping: HashMap::new(), + }) + ); + + let instruction = assembly.unwrap().instructions.pop().unwrap(); + let converted_back = + u128::from_le_bytes(Vec::::from(instruction)[0..16].try_into().unwrap()); + assert_eq!(input, converted_back); +} + +#[test] +fn test_jump_all_flags() { + // 0b immediate_memf_flag_outrg2_outrg1_inreg2_inreg1_opcode + let input: u128 = + 0b00000000_00010110_00000010_00000000_0000_1110_000000_000000_000000_000000_00001010; + let mut bytecode = input.to_le_bytes().to_vec(); + bytecode.resize(32, 0); + + let assembly = Assembly::try_from(&bytecode); + + assert_eq!( + assembly, + Ok(Assembly { + instructions: vec![Instruction::Jump(JumpInstruction { + // note that the immediate must be ignored here. For any other instruction, this would result in FullOperand::Immediate + source: FullOperand::Register(RegisterOperand::Null), + flags: vec![Flag::LesserThan, Flag::Equals, Flag::GreaterThan], + destination_true: 0b00000010_00000000, + destination_false: 0b00000000_00010110, + })], + labels: HashMap::new(), + assembly_code: String::new(), + pc_line_mapping: HashMap::new(), + }) + ); + + let instruction = assembly.unwrap().instructions.pop().unwrap(); + let converted_back = + u128::from_le_bytes(Vec::::from(instruction)[0..16].try_into().unwrap()); + assert_eq!(input, converted_back); +} + +#[test] +fn test_jump_unconditional_memory() { + // 0b immediate_memf_flag_outrg2_outrg1_inreg2_inreg1_opcode + let input: u128 = + 0b00000000_00010110_00000010_00000000_0001_0001_000000_000000_000000_001000_00001010; + let mut bytecode = input.to_le_bytes().to_vec(); + bytecode.resize(32, 0); + + let assembly = Assembly::try_from(&bytecode); + assert_eq!( + assembly, + Ok(Assembly { + instructions: vec![Instruction::Jump(JumpInstruction { + source: FullOperand::Memory(MemoryOperand { + r#type: MemoryType::SharedParent, + offset: 0, // note that the immediate must be ignored here + register: RegisterOperand::Register(3), + }), + flags: vec![Flag::Unconditional], + destination_true: 0b00000010_00000000, + destination_false: 0b00000000_00010110, + })], + labels: HashMap::new(), + assembly_code: String::new(), + pc_line_mapping: HashMap::new(), + }) + ); + + let instruction = assembly.unwrap().instructions.pop().unwrap(); + let converted_back = + u128::from_le_bytes(Vec::::from(instruction)[0..16].try_into().unwrap()); + assert_eq!(input, converted_back); +} + +#[test] +fn test_jump_all_flags_memory() { + // 0b immediate_memf_flag_outrg2_outrg1_inreg2_inreg1_opcode + let input: u128 = + 0b00000000_00010110_00000010_00000000_0001_1111_000000_000000_000000_001000_00001010; + let mut bytecode = input.to_le_bytes().to_vec(); + bytecode.resize(32, 0); + + let assembly = Assembly::try_from(&bytecode); + + assert_eq!( + assembly, + Ok(Assembly { + instructions: vec![Instruction::Jump(JumpInstruction { + source: FullOperand::Memory(MemoryOperand { + r#type: MemoryType::SharedParent, + offset: 0, // note that the immediate must be ignored here + register: RegisterOperand::Register(3), + }), + flags: vec![ + Flag::Unconditional, + Flag::LesserThan, + Flag::Equals, + Flag::GreaterThan + ], + destination_true: 0b00000010_00000000, + destination_false: 0b00000000_00010110, + })], + labels: HashMap::new(), + assembly_code: String::new(), + pc_line_mapping: HashMap::new(), + }) + ); + + let instruction = assembly.unwrap().instructions.pop().unwrap(); + let converted_back = + u128::from_le_bytes(Vec::::from(instruction)[0..16].try_into().unwrap()); + assert_eq!(input, converted_back); +} + +#[test] +fn test_function_jump_return_error() { + // 0b imm_memf_flag_outrg2_outrg1_inreg2_inreg1_opcode + let input: u128 = 0b_000000_0000_0100_000000_000000_000000_000000_00000111; + let mut bytecode = input.to_le_bytes().to_vec(); + bytecode.resize(32, 0); + + let assembly = Assembly::try_from(&bytecode); + assert_eq!( + assembly, + Ok(Assembly { + instructions: vec![Instruction::FunctionJump(FunctionJumpInstruction::Return { + error: true, + })], + labels: HashMap::new(), + assembly_code: String::new(), + pc_line_mapping: HashMap::new(), + }) + ); + + let instruction = assembly.unwrap().instructions.pop().unwrap(); + let converted_back = + u128::from_le_bytes(Vec::::from(instruction)[0..16].try_into().unwrap()); + assert_eq!(input, converted_back); +} + +#[test] +fn test_function_jump_return_no_error() { + // 0b imm_memf_flag_outrg2_outrg1_inreg2_inreg1_opcode + let input: u128 = 0b_000000_0000_0000_000000_000000_000000_000000_00000111; + let mut bytecode = input.to_le_bytes().to_vec(); + bytecode.resize(32, 0); + + let assembly = Assembly::try_from(&bytecode); + assert_eq!( + assembly, + Ok(Assembly { + instructions: vec![Instruction::FunctionJump(FunctionJumpInstruction::Return { + error: false + })], + labels: HashMap::new(), + assembly_code: String::new(), + pc_line_mapping: HashMap::new(), + }) + ); + + let instruction = assembly.unwrap().instructions.pop().unwrap(); + let converted_back = + u128::from_le_bytes(Vec::::from(instruction)[0..16].try_into().unwrap()); + assert_eq!(input, converted_back); +} + +#[test] +fn test_function_jump_local_call() { + // 0b imm_memf_flag_outrg2_outrg1_inreg2_inreg1_opcode + let input: u128 = 0b11_00001001_00001001_0000_0011_000000_000000_000000_000001_00000111; + // `11` prefix will be ignored, becuase only the low 16 bits are used in instruction + let expected: u128 = 0b00001001_00001001_0000_0011_000000_000000_000000_000001_00000111; + let mut bytecode = input.to_le_bytes().to_vec(); + bytecode.resize(32, 0); + + let assembly = Assembly::try_from(&bytecode); + assert_eq!( + assembly, + Ok(Assembly { + instructions: vec![Instruction::FunctionJump(FunctionJumpInstruction::Call { + // note that the bits higher than 16 are ignored when computing the destination address + location: Location::Local { + address: 0b00001001_00001001, + operand: FullOperand::Register(RegisterOperand::Register(0)), + }, + })], + labels: HashMap::new(), + assembly_code: String::new(), + pc_line_mapping: HashMap::new(), + }) + ); + let instruction = assembly.unwrap().instructions.pop().unwrap(); + let converted_back = + u128::from_le_bytes(Vec::::from(instruction)[0..16].try_into().unwrap()); + assert_eq!(expected, converted_back); +} + +#[test] +fn test_function_jump_local_call_immediate() { + // 0b imm_memf_flag_outrg2_outrg1_inreg2_inreg1_opcode + let input: u128 = 0b11_00001001_00001001_0000_0011_000000_000000_000000_000000_00000111; + // `11` prefix is not ignored here, because the immediate is used as first operand. + let mut bytecode = input.to_le_bytes().to_vec(); + bytecode.resize(32, 0); + + let assembly = Assembly::try_from(&bytecode); + assert_eq!( + assembly, + Ok(Assembly { + instructions: vec![Instruction::FunctionJump(FunctionJumpInstruction::Call { + location: Location::Local { + // note that the bits higher than 16 are ignored when computing the destination address + address: 0b00001001_00001001, + // here no bits are ignored + operand: FullOperand::Immediate(0b11_00001001_00001001), + }, + })], + labels: HashMap::new(), + assembly_code: String::new(), + pc_line_mapping: HashMap::new(), + }) + ); + let instruction = assembly.unwrap().instructions.pop().unwrap(); + let converted_back = + u128::from_le_bytes(Vec::::from(instruction)[0..16].try_into().unwrap()); + assert_eq!(input, converted_back); +} + +#[test] +fn test_function_jump_external_call() { + // 0b_imm_memf_flag_outrg2_outrg1_inreg2_inreg1_opcode + let input: u128 = 0b_011_0111_0001_000000_000000_000000_000001_00000111; + let mut bytecode = input.to_le_bytes().to_vec(); + bytecode.resize(32, 0); + + let assembly = Assembly::try_from(&bytecode); + assert_eq!( + assembly, + Ok(Assembly { + instructions: vec![Instruction::FunctionJump(FunctionJumpInstruction::Call { + location: Location::External { + operand: FullOperand::Memory(MemoryOperand { + r#type: MemoryType::Stack { force: false }, + offset: 0b011, + register: RegisterOperand::Register(0), + }), + is_delegate: false + }, + })], + labels: HashMap::new(), + assembly_code: String::new(), + pc_line_mapping: HashMap::new(), + }) + ); + + let instruction = assembly.unwrap().instructions.pop().unwrap(); + let converted_back = + u128::from_le_bytes(Vec::::from(instruction)[0..16].try_into().unwrap()); + assert_eq!(input, converted_back); +} + +#[test] +fn test_storage_read() { + // 0b_memf_flag_outrg2_outrg1_inreg2_inreg1_opcode + let input: u128 = 0b_0000_0101_000000_001000_000000_000100_00000101; + let mut bytecode = input.to_le_bytes().to_vec(); + bytecode.resize(32, 0); + + let assembly = Assembly::try_from(&bytecode); + assert_eq!( + assembly, + Ok(Assembly { + instructions: vec![Instruction::Storage(StorageInstruction::Storage { + storage_key: FullOperand::Register(RegisterOperand::Register(2)), + operation: DataOperation::Read { + destination: RegisterOperand::Register(3) + }, + is_external_storage_access: true, + })], + labels: HashMap::new(), + assembly_code: String::new(), + pc_line_mapping: HashMap::new(), + }) + ); + + let instruction = assembly.unwrap().instructions.pop().unwrap(); + let converted_back = + u128::from_le_bytes(Vec::::from(instruction)[0..16].try_into().unwrap()); + assert_eq!(input, converted_back); +} + +#[test] +fn test_storage_write() { + // 0b_imm_memf_flag_outrg2_outrg1_inreg2_inreg1_opcode + let input: u128 = 0b_011_0000_0000_000000_000000_000001_000000_00000101; + let mut bytecode = input.to_le_bytes().to_vec(); + bytecode.resize(32, 0); + + let assembly = Assembly::try_from(&bytecode); + assert_eq!( + assembly, + Ok(Assembly { + instructions: vec![Instruction::Storage(StorageInstruction::Storage { + storage_key: FullOperand::Immediate(0b011), + operation: DataOperation::Write { + source: RegisterOperand::Register(0) + }, + is_external_storage_access: false, + })], + labels: HashMap::new(), + assembly_code: String::new(), + pc_line_mapping: HashMap::new(), + }) + ); + + let instruction = assembly.unwrap().instructions.pop().unwrap(); + let converted_back = + u128::from_le_bytes(Vec::::from(instruction)[0..16].try_into().unwrap()); + assert_eq!(input, converted_back); +} + +#[test] +fn test_log_init() { + // 0b_imm_memf_flag_outrg2_outrg1_inreg2_inreg1_opcode + let input: u128 = 0b_011_0000_1010_000000_000000_000010_000000_00000101; + let mut bytecode = input.to_le_bytes().to_vec(); + bytecode.resize(32, 0); + + let assembly = Assembly::try_from(&bytecode); + assert_eq!( + assembly, + Ok(Assembly { + instructions: vec![Instruction::Storage(StorageInstruction::LogInit { + packed_lengths: FullOperand::Immediate(0b011), + first_topic_or_chunk: RegisterOperand::Register(1), + })], + labels: HashMap::new(), + assembly_code: String::new(), + pc_line_mapping: HashMap::new(), + }) + ); + + let instruction = assembly.unwrap().instructions.pop().unwrap(); + let converted_back = + u128::from_le_bytes(Vec::::from(instruction)[0..16].try_into().unwrap()); + assert_eq!(input, converted_back); +} + +#[test] +fn test_log() { + // 0b_imm_memf_flag_outrg2_outrg1_inreg2_inreg1_opcode + let input: u128 = 0b_000_0000_0010_000000_000000_000000_001000_00000101; + let mut bytecode = input.to_le_bytes().to_vec(); + bytecode.resize(32, 0); + + let assembly = Assembly::try_from(&bytecode); + assert_eq!( + assembly, + Ok(Assembly { + instructions: vec![Instruction::Storage(StorageInstruction::Log( + FullOperand::Register(RegisterOperand::Register(3)), + RegisterOperand::Null, + ))], + labels: HashMap::new(), + assembly_code: String::new(), + pc_line_mapping: HashMap::new(), + }) + ); + + let instruction = assembly.unwrap().instructions.pop().unwrap(); + let converted_back = + u128::from_le_bytes(Vec::::from(instruction)[0..16].try_into().unwrap()); + assert_eq!(input, converted_back); +} + +#[test] +fn test_hash_absorb() { + // 0b_imm_memf_flag_outrg2_outrg1_inreg2_inreg1_opcode + let input: u128 = 0b_011_0000_0001_000000_000000_000000_000000_00000011; + let mut bytecode = input.to_le_bytes().to_vec(); + bytecode.resize(32, 0); + + let assembly = Assembly::try_from(&bytecode); + assert_eq!( + assembly, + Ok(Assembly { + instructions: vec![Instruction::HashAbsorb(HashAbsorbInstruction { + source: FullOperand::Immediate(0b011), + reset: true, + })], + labels: HashMap::new(), + assembly_code: String::new(), + pc_line_mapping: HashMap::new(), + }) + ); + + let instruction = assembly.unwrap().instructions.pop().unwrap(); + let converted_back = + u128::from_le_bytes(Vec::::from(instruction)[0..16].try_into().unwrap()); + assert_eq!(input, converted_back); +} + +#[test] +fn test_hash_output() { + // 0b_imm_memf_flag_outrg2_outrg1_inreg2_inreg1_opcode + let input: u128 = 0b_000_0000_0000_000000_000000_000000_000000_00001001; + let mut bytecode = input.to_le_bytes().to_vec(); + bytecode.resize(32, 0); + + let assembly = Assembly::try_from(&bytecode); + assert_eq!( + assembly, + Ok(Assembly { + instructions: vec![Instruction::HashOutput(HashOutputInstruction { + destination: RegisterOperand::Null + })], + labels: HashMap::new(), + assembly_code: String::new(), + pc_line_mapping: HashMap::new(), + }) + ); + + let instruction = assembly.unwrap().instructions.pop().unwrap(); + let converted_back = + u128::from_le_bytes(Vec::::from(instruction)[0..16].try_into().unwrap()); + assert_eq!(input, converted_back); +} + +#[test] +fn test_invalid_register_selectors() { + // 0b_imm_memf_flag_outrg2_outrg1_inreg2_inreg1_opcode + let input: u128 = 0b_000_0000_0000_011000_001000_000000_000000_00010100; + let mut bytecode = input.to_le_bytes().to_vec(); + bytecode.resize(32, 0); + + let assembly = Assembly::try_from(&bytecode); + assert_eq!(assembly, Err(BinaryParseError::InvalidRegisterSelector)); +} + +#[test] +fn test_set_external_address() { + // 0b_imm_memf_flag_outrg2_outrg1_inreg2_inreg1_opcode + let input: u128 = 0b_001_0111_0000_000000_000000_000000_000000_00010110; + let mut bytecode = input.to_le_bytes().to_vec(); + bytecode.resize(32, 0); + + let assembly = Assembly::try_from(&bytecode); + assert_eq!( + assembly, + Ok(Assembly { + instructions: vec![Instruction::SetExternalAddress( + SetExternalAddressInstruction { + source: FullOperand::Memory(MemoryOperand { + r#type: MemoryType::Stack { force: false }, + offset: 1, + register: RegisterOperand::Null, + }) + } + )], + labels: HashMap::new(), + assembly_code: String::new(), + pc_line_mapping: HashMap::new(), + }) + ); + + let instruction = assembly.unwrap().instructions.pop().unwrap(); + let converted_back = + u128::from_le_bytes(Vec::::from(instruction)[0..16].try_into().unwrap()); + assert_eq!(input, converted_back); +} + +#[test] +fn test_context() { + // 0b_imm_memf_flag_outrg2_outrg1_inreg2_inreg1_opcode + let input: u128 = 0b_101_0000_0000_000000_000010_000000_000000_00010100; + let mut bytecode = input.to_le_bytes().to_vec(); + bytecode.resize(32, 0); + + let assembly = Assembly::try_from(&bytecode); + assert_eq!( + assembly, + Ok(Assembly { + instructions: vec![Instruction::Context( + ContextInstruction { + destination: RegisterOperand::Register(1), + field: ContextField::CurrentAddress, + } + )], + labels: HashMap::new(), + assembly_code: String::new(), + pc_line_mapping: HashMap::new(), + }) + ); + + let instruction = assembly.unwrap().instructions.pop().unwrap(); + let converted_back = + u128::from_le_bytes(Vec::::from(instruction)[0..16].try_into().unwrap()); + assert_eq!(input, converted_back); +} + +#[test] +fn test_bitwise_or() { + // 0b_imm_memf_flag_outrg2_outrg1_inreg2_inreg1_opcode + let input: u128 = 0b_000_0000_0100_000000_000100_000010_000001_00011010; + let mut bytecode = input.to_le_bytes().to_vec(); + bytecode.resize(32, 0); + + let assembly = Assembly::try_from(&bytecode); + assert_eq!( + assembly, + Ok(Assembly { + instructions: vec![Instruction::Bitwise( + BitwiseInstruction { + source_1: FullOperand::Register(RegisterOperand::Register(0)), + source_2: RegisterOperand::Register(1), + destination: RegisterOperand::Register(2), + op_type: BitwiseOpType::Or, + } + )], + labels: HashMap::new(), + assembly_code: String::new(), + pc_line_mapping: HashMap::new(), + }) + ); + + let instruction = assembly.unwrap().instructions.pop().unwrap(); + let converted_back = + u128::from_le_bytes(Vec::::from(instruction)[0..16].try_into().unwrap()); + assert_eq!(input, converted_back); +} + +#[test] +fn test_bitwise_shift() { + // 0b_imm_memf_flag_outrg2_outrg1_inreg2_inreg1_opcode + let input: u128 = 0b_000_0000_0010_000000_000100_000010_000001_00011000; + let mut bytecode = input.to_le_bytes().to_vec(); + bytecode.resize(32, 0); + + let assembly = Assembly::try_from(&bytecode); + assert_eq!( + assembly, + Ok(Assembly { + instructions: vec![Instruction::Shift( + ShiftInstruction { + source_1: FullOperand::Register(RegisterOperand::Register(0)), + source_2: RegisterOperand::Register(1), + destination: RegisterOperand::Register(2), + is_cyclic: false, + is_right: true, + } + )], + labels: HashMap::new(), + assembly_code: String::new(), + pc_line_mapping: HashMap::new(), + }) + ); + + let instruction = assembly.unwrap().instructions.pop().unwrap(); + let converted_back = + u128::from_le_bytes(Vec::::from(instruction)[0..16].try_into().unwrap()); + assert_eq!(input, converted_back); +} diff --git a/crates/zkEVM-assembly/src/tests/mod.rs b/crates/zkEVM-assembly/src/tests/mod.rs new file mode 100644 index 0000000..6153c4b --- /dev/null +++ b/crates/zkEVM-assembly/src/tests/mod.rs @@ -0,0 +1,4 @@ +// mod assembly; +// mod binary; + +mod new_assembly; diff --git a/crates/zkEVM-assembly/src/tests/new_assembly.rs b/crates/zkEVM-assembly/src/tests/new_assembly.rs new file mode 100644 index 0000000..3d02a62 --- /dev/null +++ b/crates/zkEVM-assembly/src/tests/new_assembly.rs @@ -0,0 +1,33 @@ +use zkevm_opcode_defs::decoding::EncodingModeProduction; + +use crate::assembly::*; +use std::convert::TryFrom; + +#[test] +fn test_memory_syntax() { + let asm_text = r#" + .data + .globl val ; @val + .p2align 5 + val: + .zero 64 ; 64 bytes + .cell 123 + .text + .globl __entry + __entry: + .func_begin0: + st.1 r5, r1 + ret.ok r0 + .rodata + const_1: + .cell 777 ; 2 bytes + switch.table.fun_f: + .cell 0 + .cell 1 + .cell 4 + "#; + let mut asm = Assembly::try_from(asm_text.to_owned()).unwrap(); + let _bc = asm.compile_to_bytecode_for_mode::<8, EncodingModeProduction>().unwrap(); + let instructions = asm.opcodes::<8, EncodingModeProduction>(); + dbg!(&instructions); +} \ No newline at end of file diff --git a/crates/zk_evm/Cargo.toml b/crates/zk_evm/Cargo.toml index dba036d..713d6a8 100644 --- a/crates/zk_evm/Cargo.toml +++ b/crates/zk_evm/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zk_evm" -version = "0.141.0" +version = "0.150.0" edition = "2021" authors = ["The Matter Labs Team "] homepage = "https://zksync.io/" @@ -18,8 +18,7 @@ serde_json = "1.0" anyhow = "1.0" num = { version = "0.4"} static_assertions = "1" -zkevm_opcode_defs = { version = "=0.141.0", path = "../zkevm_opcode_defs" } -zk_evm_abstractions = { version = "=0.141.0", path = "../zk_evm_abstractions" } +zk_evm_abstractions = { version = "=0.150.0", path = "../zk_evm_abstractions" } lazy_static = "1.4" [dev-dependencies] diff --git a/crates/zk_evm/src/block_properties/mod.rs b/crates/zk_evm/src/block_properties/mod.rs index 6e7cf28..74f39d5 100644 --- a/crates/zk_evm/src/block_properties/mod.rs +++ b/crates/zk_evm/src/block_properties/mod.rs @@ -3,5 +3,6 @@ use super::*; #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub struct BlockProperties { pub default_aa_code_hash: U256, + pub evm_simulator_code_hash: U256, pub zkporter_is_available: bool, } diff --git a/crates/zk_evm/src/lib.rs b/crates/zk_evm/src/lib.rs index 407c583..e8e38bd 100644 --- a/crates/zk_evm/src/lib.rs +++ b/crates/zk_evm/src/lib.rs @@ -11,17 +11,16 @@ pub mod witness_trace; pub use self::utils::*; -pub use zkevm_opcode_defs::{bitflags, ethereum_types}; +pub use crate::zkevm_opcode_defs::{bitflags, ethereum_types}; use self::ethereum_types::{Address, U256}; -pub use zkevm_opcode_defs; - +pub use crate::zkevm_opcode_defs::blake2; +pub use crate::zkevm_opcode_defs::k256; +pub use crate::zkevm_opcode_defs::sha2; +pub use crate::zkevm_opcode_defs::sha3; pub use zk_evm_abstractions; -pub use zkevm_opcode_defs::blake2; -pub use zkevm_opcode_defs::k256; -pub use zkevm_opcode_defs::sha2; -pub use zkevm_opcode_defs::sha3; +pub use zk_evm_abstractions::zkevm_opcode_defs; // Re-export abstractions. pub mod abstractions { diff --git a/crates/zk_evm/src/opcodes/execution/add.rs b/crates/zk_evm/src/opcodes/execution/add.rs index 5f629be..586ea11 100644 --- a/crates/zk_evm/src/opcodes/execution/add.rs +++ b/crates/zk_evm/src/opcodes/execution/add.rs @@ -29,7 +29,7 @@ impl> DecodedOpcode { is_pointer: _, } = src1; - use zkevm_opcode_defs::SET_FLAGS_FLAG_IDX; + use crate::zkevm_opcode_defs::SET_FLAGS_FLAG_IDX; let set_flags = self.variant.flags[SET_FLAGS_FLAG_IDX]; vm_state.local_state.callstack.get_current_stack_mut().pc = new_pc; let (result, of) = src0.overflowing_add(src1); diff --git a/crates/zk_evm/src/opcodes/execution/binop.rs b/crates/zk_evm/src/opcodes/execution/binop.rs index 9a64c00..8309f1f 100644 --- a/crates/zk_evm/src/opcodes/execution/binop.rs +++ b/crates/zk_evm/src/opcodes/execution/binop.rs @@ -1,5 +1,5 @@ use super::*; -use zkevm_opcode_defs::{BinopOpcode, Opcode}; +use crate::zkevm_opcode_defs::{BinopOpcode, Opcode}; impl> DecodedOpcode { pub fn binop_opcode_apply< @@ -35,7 +35,7 @@ impl> DecodedOpcode { _ => unreachable!(), }; - use zkevm_opcode_defs::SET_FLAGS_FLAG_IDX; + use crate::zkevm_opcode_defs::SET_FLAGS_FLAG_IDX; let set_flags = self.variant.flags[SET_FLAGS_FLAG_IDX]; vm_state.local_state.callstack.get_current_stack_mut().pc = new_pc; // it is always XOR unless flags are set diff --git a/crates/zk_evm/src/opcodes/execution/context.rs b/crates/zk_evm/src/opcodes/execution/context.rs index 8e0b3cc..6098848 100644 --- a/crates/zk_evm/src/opcodes/execution/context.rs +++ b/crates/zk_evm/src/opcodes/execution/context.rs @@ -1,6 +1,6 @@ use super::*; -use zkevm_opcode_defs::{ContextOpcode, Opcode}; +use crate::zkevm_opcode_defs::{ContextOpcode, Opcode}; impl> DecodedOpcode { pub fn context_opcode_apply< @@ -19,6 +19,7 @@ impl> DecodedOpcode { src0, new_pc, dst0_mem_location, + is_kernel_mode, .. } = prestate; let PrimitiveValue { @@ -38,14 +39,14 @@ impl> DecodedOpcode { return; } - if inner_variant == ContextOpcode::SetErgsPerPubdataByte { - vm_state.local_state.current_ergs_per_pubdata_byte = src0.low_u32(); + if inner_variant == ContextOpcode::AuxMutating0 { + // does nothing for now + // vm_state.local_state.current_ergs_per_pubdata_byte = src0.low_u32(); return; } if inner_variant == ContextOpcode::IncrementTxNumber { - vm_state.local_state.tx_number_in_block = - vm_state.local_state.tx_number_in_block.wrapping_add(1); + vm_state.start_new_tx(); return; } @@ -63,10 +64,15 @@ impl> DecodedOpcode { address_to_u256(address) } ContextOpcode::Meta => { - use zkevm_opcode_defs::VmMetaParameters; + use crate::zkevm_opcode_defs::VmMetaParameters; + let aux_field_0 = if is_kernel_mode { + vm_state.local_state.pubdata_revert_counter.0 as u32 + } else { + 0u32 + }; let meta = VmMetaParameters { - ergs_per_pubdata_byte: vm_state.local_state.current_ergs_per_pubdata_byte, + aux_field_0, this_shard_id: current_context.this_shard_id, caller_shard_id: current_context.caller_shard_id, code_shard_id: current_context.code_shard_id, @@ -84,13 +90,13 @@ impl> DecodedOpcode { meta.to_u256() } - ContextOpcode::ErgsLeft => U256::from(current_context.ergs_remaining as u64), + ContextOpcode::ErgsLeft => U256::from((current_context.ergs_remaining / zkevm_opcode_defs::system_params::INTERNAL_ERGS_TO_VISIBLE_ERGS_CONVERSION_CONSTANT) as u64), ContextOpcode::Sp => U256::from(current_context.sp.as_u64()), ContextOpcode::GetContextU128 => U256::from(current_context.context_u128_value), ContextOpcode::SetContextU128 => { unreachable!() } - ContextOpcode::SetErgsPerPubdataByte => { + ContextOpcode::AuxMutating0 => { unreachable!() } ContextOpcode::IncrementTxNumber => { diff --git a/crates/zk_evm/src/opcodes/execution/div.rs b/crates/zk_evm/src/opcodes/execution/div.rs index b5e834f..24be739 100644 --- a/crates/zk_evm/src/opcodes/execution/div.rs +++ b/crates/zk_evm/src/opcodes/execution/div.rs @@ -29,7 +29,7 @@ impl> DecodedOpcode { is_pointer: _, } = src1; - use zkevm_opcode_defs::SET_FLAGS_FLAG_IDX; + use crate::zkevm_opcode_defs::SET_FLAGS_FLAG_IDX; let set_flags = self.variant.flags[SET_FLAGS_FLAG_IDX]; vm_state.local_state.callstack.get_current_stack_mut().pc = new_pc; if src1.is_zero() { diff --git a/crates/zk_evm/src/opcodes/execution/far_call.rs b/crates/zk_evm/src/opcodes/execution/far_call.rs index 7d1e040..9d55d23 100644 --- a/crates/zk_evm/src/opcodes/execution/far_call.rs +++ b/crates/zk_evm/src/opcodes/execution/far_call.rs @@ -1,14 +1,12 @@ use super::*; +use crate::zkevm_opcode_defs::definitions::far_call::*; + +use crate::zkevm_opcode_defs::INITIAL_SP_ON_FAR_CALL; use zk_evm_abstractions::aux::*; use zk_evm_abstractions::queries::LogQuery; -use zkevm_opcode_defs::definitions::far_call::*; -use zkevm_opcode_defs::system_params::DEPLOYER_SYSTEM_CONTRACT_ADDRESS; -use zkevm_opcode_defs::system_params::STORAGE_AUX_BYTE; -use zkevm_opcode_defs::FatPointerValidationException; -use zkevm_opcode_defs::{INITIAL_SP_ON_FAR_CALL, UNMAPPED_PAGE}; -use zkevm_opcode_defs::bitflags::bitflags; +use crate::zkevm_opcode_defs::bitflags::bitflags; pub const FORCED_ERGS_FOR_MSG_VALUE_SIMULATOR: bool = false; @@ -21,15 +19,12 @@ bitflags! { const MALFORMED_ABI_QUASI_POINTER = 1u64 << 4; const CALL_IN_NOW_CONSTRUCTED_SYSTEM_CONTRACT = 1u64 << 5; const NOT_ENOUGH_ERGS_FOR_EXTRA_FAR_CALL_COSTS = 1u64 << 6; + const CALL_TO_UNREACHABLE_ADDRESS = 1u64 << 7; + const INPUT_IS_POINTER_WHEN_NOT_EXPECTED = 1u64 << 8; } } -use zkevm_opcode_defs::{FarCallABI, FarCallForwardPageType, FarCallOpcode, FatPointer, Opcode}; - -// Internally FarCall uses all 7 sponges: -// - 1 for decommittment -// - 3 for storage read -// - 3 for callstack manipulation +use crate::zkevm_opcode_defs::{FarCallABI, FarCallOpcode, Opcode}; impl> DecodedOpcode { pub fn far_call_opcode_apply< @@ -76,11 +71,21 @@ impl> DecodedOpcode { let called_address = u256_to_address_unchecked(&call_destination_value); let called_address_as_u256 = call_destination_value & *U256_TO_ADDRESS_MASK; - let dst_is_kernel = CallStackEntry::::address_is_kernel(&called_address); + let dst_is_kernel = address_is_kernel(&called_address); // ergs, shard_id and calldata let mut far_call_abi = FarCallABI::from_u256(abi_src); + // convert ergs + far_call_abi.ergs_passed = if let Some(non_overflowing) = + far_call_abi.ergs_passed.checked_mul( + zkevm_opcode_defs::system_params::INTERNAL_ERGS_TO_VISIBLE_ERGS_CONVERSION_CONSTANT, + ) { + non_overflowing + } else { + u32::MAX + }; + // we ignore extra features if not in kernel far_call_abi.constructor_call = far_call_abi.constructor_call & is_kernel_mode; far_call_abi.to_system = far_call_abi.to_system & dst_is_kernel; @@ -117,10 +122,17 @@ impl> DecodedOpcode { let new_base_memory_page = vm_state.new_base_memory_page_on_call(); + let call_to_evm_simulator; + // NOTE: our far-call MUST take ergs to cover storage read, but we also have a contribution // that depends on the actual code length, so we work with it here - let (mapped_code_page, ergs_after_code_read_and_exceptions_resolution, stipend_for_callee) = { - let (code_hash, map_to_trivial) = if new_code_shard_id != 0 + let ( + mapped_code_page, + ergs_after_code_read_and_exceptions_resolution, + extra_ergs_from_caller_to_callee, + callee_stipend, + ) = { + let (code_hash, call_to_unreachable) = if new_code_shard_id != 0 && !vm_state.block_properties.zkporter_is_available { // we do NOT mask it into default AA here @@ -141,114 +153,150 @@ impl> DecodedOpcode { rollback: false, is_service: false, }; - let query = vm_state + let (query, _) = vm_state .access_storage(vm_state.local_state.monotonic_cycle_counter, partial_query); let code_hash_from_storage = query.read_value; - // mask for default AA - let mask_into_default_aa = - code_hash_from_storage.is_zero() && dst_is_kernel == false; - let code_hash = if mask_into_default_aa { - vm_state.block_properties.default_aa_code_hash - } else { - code_hash_from_storage - }; - - (code_hash, false) + (code_hash_from_storage, false) }; - let memory_page_candidate_for_code_decommittment = if map_to_trivial == true { - MemoryPage(UNMAPPED_PAGE) - } else { - CallStackEntry::::code_page_candidate_from_base(new_base_memory_page) - }; + let mut exceptions = FarCallExceptionFlags::empty(); + if call_to_unreachable == true { + exceptions.set(FarCallExceptionFlags::CALL_TO_UNREACHABLE_ADDRESS, true); + } // now we handle potential exceptions - use zkevm_opcode_defs::{ContractCodeSha256, VersionedHashGeneric}; + use crate::zkevm_opcode_defs::*; + + let bytecode_hash_is_empty = code_hash == U256::zero(); let mut buffer = [0u8; 32]; code_hash.to_big_endian(&mut buffer); - let mut exceptions = FarCallExceptionFlags::empty(); + let is_valid_as_bytecode_hash = ContractCodeSha256Format::is_valid(&buffer); + let is_valid_as_blob_hash = BlobSha256Format::is_valid(&buffer); - // now let's check if code format "makes sense" - let (code_hash, code_length_in_words) = if let Some(versioned_hash) = - VersionedHashGeneric::::try_create_from_raw(buffer) - { - // code is in proper format, let's check other markers + let mut mask_to_default_aa = false; - let layout = versioned_hash.layout_ref(); + let can_call_code_without_masking = if is_valid_as_bytecode_hash { + let is_code_at_rest = ContractCodeSha256Format::is_code_at_rest_if_valid(&buffer); + let is_constructed = ContractCodeSha256Format::is_in_construction_if_valid(&buffer); - let code_marker = layout.extra_marker; + let can_call_at_rest = !far_call_abi.constructor_call && is_code_at_rest; + let can_call_by_constructor = far_call_abi.constructor_call && is_constructed; - let code_marker_is_at_rest = code_marker == ContractCodeSha256::CODE_AT_REST_MARKER; - let code_marker_is_constructed_now = - code_marker == ContractCodeSha256::YET_CONSTRUCTED_MARKER; + let can_call_code_without_masking = can_call_at_rest || can_call_by_constructor; + if can_call_code_without_masking == true { + true + } else { + // calling mode is unknown, so it's most likely a normal + // call to contract that is still created + if dst_is_kernel == false { + mask_to_default_aa = true; + } else { + exceptions.set( + FarCallExceptionFlags::CALL_IN_NOW_CONSTRUCTED_SYSTEM_CONTRACT, + true, + ); + } - let code_marker_is_valid = code_marker_is_at_rest || code_marker_is_constructed_now; + false + } + } else { + false + }; - if code_marker_is_valid == false { - // code marker is generally invalid - exceptions.set(FarCallExceptionFlags::INVALID_CODE_HASH_FORMAT, true); + let can_call_evm_simulator = if is_valid_as_blob_hash { + let is_code_at_rest = BlobSha256Format::is_code_at_rest_if_valid(&buffer); + let is_constructed = BlobSha256Format::is_in_construction_if_valid(&buffer); + + let can_call_at_rest = !far_call_abi.constructor_call && is_code_at_rest; + let can_call_by_constructor = far_call_abi.constructor_call && is_constructed; - (U256::zero(), 0u32) + let can_call_code_without_masking = can_call_at_rest || can_call_by_constructor; + if can_call_code_without_masking == true { + true } else { - // it's valid in general, so do the constructor masking work - let code_hash_at_storage = versioned_hash - .serialize_to_stored() - .map(|arr| U256::from_big_endian(&arr)) - .expect("Failed to serialize a valid hash"); - - let can_call_at_rest = !far_call_abi.constructor_call && code_marker_is_at_rest; - let can_call_by_constructor = - far_call_abi.constructor_call && code_marker_is_constructed_now; - - let can_call_code_without_masking = can_call_at_rest || can_call_by_constructor; - if can_call_code_without_masking == true { - // true values - (code_hash_at_storage, layout.code_length_in_words as u32) + // calling mode is unknown, so it's most likely a normal + // call to contract that is still created + if dst_is_kernel == false { + mask_to_default_aa = true; } else { - // calling mode is unknown, so it's most likely a normal - // call to contract that is still created - if dst_is_kernel == false { - // still degrade to default AA - let mut buffer = [0u8; 32]; - vm_state - .block_properties - .default_aa_code_hash - .to_big_endian(&mut buffer); - let versioned_hash = - VersionedHashGeneric::::try_create_from_raw( - buffer, - ) - .expect("default AA code hash must be always valid"); - let layout = versioned_hash.layout_ref(); - let code_marker = layout.extra_marker; - assert!( - code_marker == ContractCodeSha256::CODE_AT_REST_MARKER, - "default AA marker is always in storage format" - ); - - ( - vm_state.block_properties.default_aa_code_hash, - layout.code_length_in_words as u32, - ) - } else { - // we should not decommit 0, so it's an exception - exceptions.set( - FarCallExceptionFlags::CALL_IN_NOW_CONSTRUCTED_SYSTEM_CONTRACT, - true, - ); - (U256::zero(), 0u32) - } + exceptions.set(FarCallExceptionFlags::INVALID_CODE_HASH_FORMAT, true); } + + false } } else { + false + }; + + call_to_evm_simulator = can_call_evm_simulator; + + if bytecode_hash_is_empty { + if dst_is_kernel == false { + mask_to_default_aa = true; + } else { + exceptions.set(FarCallExceptionFlags::INVALID_CODE_HASH_FORMAT, true); + } + } + + assert!( + (mask_to_default_aa as u64) + + (can_call_evm_simulator as u64) + + (can_call_code_without_masking as u64) + < 2 + ); + + let unknown_hash = mask_to_default_aa == false + && can_call_evm_simulator == false + && can_call_code_without_masking == false; + if unknown_hash { exceptions.set(FarCallExceptionFlags::INVALID_CODE_HASH_FORMAT, true); - // we still return placeholders - (U256::zero(), 0u32) + } + + // now let's check if code format "makes sense" + let (header, normalized_preimage, code_length_in_words) = { + if can_call_code_without_masking { + // masking is not needed + } else if can_call_evm_simulator { + // overwrite buffer with evm simulator bytecode hash + vm_state + .block_properties + .evm_simulator_code_hash + .to_big_endian(&mut buffer); + } else if mask_to_default_aa { + // overwrite buffer with default AA code hash + vm_state + .block_properties + .default_aa_code_hash + .to_big_endian(&mut buffer); + } else { + assert!(exceptions.is_empty() == false); + } + + if exceptions.is_empty() { + assert!( + can_call_code_without_masking + || can_call_evm_simulator + || mask_to_default_aa + ); + // true values + let length_in_words = + ContractCodeSha256Format::code_length_in_bytes32_words(&buffer); + let (header, normalized_preimage) = + ContractCodeSha256Format::normalize_for_decommitment(&buffer); + + (header, normalized_preimage, length_in_words) + } else { + ( + VersionedHashHeader::default(), + VersionedHashNormalizedPreimage::default(), + 0u16, + ) + } }; // we also use code hash as an exception hatch here @@ -259,6 +307,15 @@ impl> DecodedOpcode { true, ); } + } else { + if abi_src_is_ptr { + // there is no reasonable case to try to re-interpret pointer + // as integer here + exceptions.set( + FarCallExceptionFlags::INPUT_IS_POINTER_WHEN_NOT_EXPECTED, + true, + ); + } } // validate that fat pointer (one a future one) we formed is somewhat valid @@ -300,14 +357,12 @@ impl> DecodedOpcode { far_call_abi.memory_quasi_fat_pointer.offset = 0; } FarCallForwardPageType::UseHeap => { - let owned_page = - CallStackEntry::::heap_page_from_base(current_base_page).0; + let owned_page = heap_page_from_base(current_base_page).0; far_call_abi.memory_quasi_fat_pointer.memory_page = owned_page; } FarCallForwardPageType::UseAuxHeap => { - let owned_page = - CallStackEntry::::aux_heap_page_from_base(current_base_page).0; + let owned_page = aux_heap_page_from_base(current_base_page).0; far_call_abi.memory_quasi_fat_pointer.memory_page = owned_page; } @@ -384,81 +439,90 @@ impl> DecodedOpcode { 0 }; - let mut msg_value_stipend = if FORCED_ERGS_FOR_MSG_VALUE_SIMULATOR == false { - 0 - } else { - if called_address_as_u256 == U256::from(zkevm_opcode_defs::ADDRESS_MSG_VALUE as u64) - && far_call_abi.to_system - { - // use that doesn't know what's doing is trying to call "transfer" - - let pubdata_related = vm_state.local_state.current_ergs_per_pubdata_byte.checked_mul( - zkevm_opcode_defs::system_params::MSG_VALUE_SIMULATOR_PUBDATA_BYTES_TO_PREPAY - ).expect("must fit into u32"); - pubdata_related - .checked_add( - zkevm_opcode_defs::system_params::MSG_VALUE_SIMULATOR_ADDITIVE_COST, - ) - .expect("must not overflow") - } else { - 0 - } - }; + let (mut callee_stipend, mut extra_ergs_from_caller_to_callee) = + get_stipend_and_extra_cost(&called_address, far_call_abi.to_system); - let remaining_ergs_of_caller_frame = if remaining_ergs_after_growth >= msg_value_stipend - { - remaining_ergs_after_growth - msg_value_stipend - } else { - exceptions.set( - FarCallExceptionFlags::NOT_ENOUGH_ERGS_FOR_EXTRA_FAR_CALL_COSTS, - true, - ); - // if tried to take and failed, but should not add it later on in this case - msg_value_stipend = 0; - - 0 - }; - - // we mask instead of branching - let cost_of_decommittment = - zkevm_opcode_defs::ERGS_PER_CODE_WORD_DECOMMITTMENT * code_length_in_words; - - let mut remaining_ergs_after_decommittment = - if remaining_ergs_of_caller_frame >= cost_of_decommittment { - remaining_ergs_of_caller_frame - cost_of_decommittment + let remaining_ergs_of_caller_frame = + if remaining_ergs_after_growth >= extra_ergs_from_caller_to_callee { + remaining_ergs_after_growth - extra_ergs_from_caller_to_callee } else { - exceptions.set(FarCallExceptionFlags::NOT_ENOUGH_ERGS_TO_DECOMMIT, true); + exceptions.set( + FarCallExceptionFlags::NOT_ENOUGH_ERGS_FOR_EXTRA_FAR_CALL_COSTS, + true, + ); + // if tried to take and failed, but should not add it later on in this case + extra_ergs_from_caller_to_callee = 0; - remaining_ergs_of_caller_frame // do not burn, as it's irrelevant - we just will not perform a decommittment and call + 0 }; - let code_memory_page = if exceptions.is_empty() == false { + if can_call_evm_simulator { + assert_eq!(callee_stipend, 0); + callee_stipend = zkevm_opcode_defs::system_params::EVM_SIMULATOR_STIPEND; + } + + let (code_memory_page, remaining_ergs_after_decommittment) = if exceptions.is_empty() + == false + { vm_state.set_shorthand_panic(); - // we also do not return back cost of decommittment as it wasn't subtracted - MemoryPage(UNMAPPED_PAGE) + // we also do not return back cost of decommittment as it was subtracted + (MemoryPage(UNMAPPED_PAGE), remaining_ergs_of_caller_frame) } else { + assert!( + header.0 != [0u8; 4], + "zero header must be masked to default aa or panic", + ); + // we mask instead of branching + let default_cost_of_decommittment = + zkevm_opcode_defs::ERGS_PER_CODE_WORD_DECOMMITTMENT + * (code_length_in_words as u32); + // prepare query let timestamp_for_decommit = vm_state.timestamp_for_first_decommit_or_precompile_read(); - let processed_decommittment_query = vm_state.decommit( + let memory_page_candidate_for_code_decommittment = + code_page_candidate_from_base(new_base_memory_page); + let prepared_decommmit_query = vm_state.prepare_to_decommit( vm_state.local_state.monotonic_cycle_counter, - code_hash, + header, + normalized_preimage, memory_page_candidate_for_code_decommittment, timestamp_for_decommit, )?; + let cost_of_decommittment = if prepared_decommmit_query.is_fresh { + default_cost_of_decommittment + } else { + 0 + }; - if processed_decommittment_query.is_fresh == false { - // refund - remaining_ergs_after_decommittment += cost_of_decommittment; - } + let remaining_ergs_after_decommittment = + if remaining_ergs_of_caller_frame >= cost_of_decommittment { + remaining_ergs_of_caller_frame - cost_of_decommittment + } else { + exceptions.set(FarCallExceptionFlags::NOT_ENOUGH_ERGS_TO_DECOMMIT, true); + remaining_ergs_of_caller_frame // do not burn, as it's irrelevant - we just will not perform a decommittment and call + }; - processed_decommittment_query.memory_page + let memory_page = if exceptions.is_empty() { + vm_state.execute_decommit( + vm_state.local_state.monotonic_cycle_counter, + prepared_decommmit_query, + )?; + + prepared_decommmit_query.memory_page + } else { + vm_state.set_shorthand_panic(); + MemoryPage(UNMAPPED_PAGE) + }; + + (memory_page, remaining_ergs_after_decommittment) }; ( code_memory_page, remaining_ergs_after_decommittment, - msg_value_stipend, + extra_ergs_from_caller_to_callee, + callee_stipend, ) }; @@ -484,7 +548,11 @@ impl> DecodedOpcode { }; // can not overflow - let passed_ergs = passed_ergs.wrapping_add(stipend_for_callee); + let passed_ergs = passed_ergs.wrapping_add(extra_ergs_from_caller_to_callee); + // this one is checked + let passed_ergs = passed_ergs + .checked_add(callee_stipend) + .expect("stipends must never overflow"); // update current ergs and PC vm_state @@ -534,6 +602,20 @@ impl> DecodedOpcode { } }; + let is_static_to_set = if call_to_evm_simulator { + false + } else { + new_context_is_static + }; + + // NOTE: this one decides based on what next frame will be, and not just on the formal + // call target + let memory_stipend = if address_is_kernel(&address_for_next) { + zkevm_opcode_defs::system_params::NEW_KERNEL_FRAME_MEMORY_STIPEND + } else { + zkevm_opcode_defs::system_params::NEW_FRAME_MEMORY_STIPEND + }; + let new_stack = CallStackEntry { this_address: address_for_next, msg_sender: msg_sender_for_next, @@ -547,11 +629,13 @@ impl> DecodedOpcode { this_shard_id: new_this_shard_id, caller_shard_id, code_shard_id: new_code_shard_id, - is_static: new_context_is_static, + is_static: is_static_to_set, is_local_frame: false, context_u128_value: context_u128_for_next, - heap_bound: zkevm_opcode_defs::system_params::NEW_FRAME_MEMORY_STIPEND, - aux_heap_bound: zkevm_opcode_defs::system_params::NEW_FRAME_MEMORY_STIPEND, + heap_bound: memory_stipend, + aux_heap_bound: memory_stipend, + total_pubdata_spent: PubdataCost(0i32), + stipend: callee_stipend, }; // zero out the temporary register if it was not trivial @@ -583,6 +667,9 @@ impl> DecodedOpcode { if far_call_abi.to_system { r2_value.0[0] |= 1u64 << 1; } + if call_to_evm_simulator { + r2_value.0[0] |= (new_context_is_static as u64) << 2; + } vm_state.local_state.registers[CALL_IMPLICIT_CONSTRUCTOR_MARKER_REGISTER as usize] = PrimitiveValue { diff --git a/crates/zk_evm/src/opcodes/execution/jump.rs b/crates/zk_evm/src/opcodes/execution/jump.rs index 4c314df..7882bda 100644 --- a/crates/zk_evm/src/opcodes/execution/jump.rs +++ b/crates/zk_evm/src/opcodes/execution/jump.rs @@ -14,7 +14,10 @@ impl> DecodedOpcode { prestate: PreState, ) { let PreState { - new_pc: _, src0, .. + new_pc, + src0, + dst0_mem_location, + .. } = prestate; let PrimitiveValue { value: src0, @@ -23,5 +26,16 @@ impl> DecodedOpcode { // we use lowest 16 bits of src0 as a jump destination let dest_pc = E::PcOrImm::from_u64_clipped(src0.low_u64()); vm_state.local_state.callstack.get_current_stack_mut().pc = dest_pc; + let result = U256::from(new_pc.as_u64()); + let result = PrimitiveValue { + value: result, + is_pointer: false, + }; + vm_state.perform_dst0_update( + vm_state.local_state.monotonic_cycle_counter, + result, + dst0_mem_location, + self, + ); } } diff --git a/crates/zk_evm/src/opcodes/execution/log.rs b/crates/zk_evm/src/opcodes/execution/log.rs index d2708e2..8da8a84 100644 --- a/crates/zk_evm/src/opcodes/execution/log.rs +++ b/crates/zk_evm/src/opcodes/execution/log.rs @@ -1,9 +1,18 @@ use super::*; +use crate::zkevm_opcode_defs::{LogOpcode, Opcode, PrecompileCallABI, FIRST_MESSAGE_FLAG_IDX}; +use num::abs; +use zk_evm_abstractions::aux::PubdataCost; use zk_evm_abstractions::queries::LogQuery; -use zkevm_opcode_defs::{LogOpcode, Opcode, PrecompileCallABI, FIRST_MESSAGE_FLAG_IDX}; +use zk_evm_abstractions::zkevm_opcode_defs::system_params::{ + MAX_PUBDATA_COST_PER_QUERY, TRANSIENT_STORAGE_AUX_BYTE, +}; +use zk_evm_abstractions::zkevm_opcode_defs::{ + FatPointer, OpcodeVariantProps, PrecompileAuxData, VersionedHashHeader, + VersionedHashNormalizedPreimage, +}; -use zkevm_opcode_defs::system_params::{ +use crate::zkevm_opcode_defs::system_params::{ EVENT_AUX_BYTE, L1_MESSAGE_AUX_BYTE, PRECOMPILE_AUX_BYTE, STORAGE_AUX_BYTE, }; @@ -19,7 +28,7 @@ impl> DecodedOpcode { &self, vm_state: &mut VmState, prestate: PreState, - ) { + ) -> anyhow::Result<()> { let PreState { src0, src1, @@ -67,89 +76,61 @@ impl> DecodedOpcode { let timestamp_for_log = vm_state.timestamp_for_first_decommit_or_precompile_read(); let tx_number_in_block = vm_state.local_state.tx_number_in_block; - let ergs_on_pubdata = match inner_variant { - LogOpcode::StorageWrite => { - let key = src0; - let written_value = src1; - - let current_context = vm_state.local_state.callstack.get_current_stack(); - let address = current_context.this_address; - let shard_id = current_context.this_shard_id; - - #[allow(dropping_references)] - drop(current_context); + let mut decommit_preimage_format_is_invalid = false; + // we make formal fat pointer of length of full kernel space "free" heap size, + // and caller is responsible to truncate it if decommit is succesfull + let mut preimage_len_in_bytes = + zkevm_opcode_defs::system_params::NEW_KERNEL_FRAME_MEMORY_STIPEND; + let mut decommit_header = VersionedHashHeader::default(); + let mut decommit_preimage_normalized = VersionedHashNormalizedPreimage::default(); + let mut buffer = [0u8; 32]; - // we do not need all the values here, but we DO need the written value - // for oracle to do estimations - - let partial_query = LogQuery { - timestamp: timestamp_for_log, - tx_number_in_block: tx_number_in_block, - aux_byte: STORAGE_AUX_BYTE, - shard_id, - address, - key, - read_value: U256::zero(), - written_value, - rw_flag: true, - rollback: false, - is_service: false, - }; - - let refund = vm_state.refund_for_partial_query( - vm_state.local_state.monotonic_cycle_counter, - &partial_query, - ); - let pubdata_refund = refund.pubdata_refund(); - - let net_pubdata = if is_rollup { - let (net_cost, uf) = - (zkevm_opcode_defs::system_params::INITIAL_STORAGE_WRITE_PUBDATA_BYTES - as u32) - .overflowing_sub(pubdata_refund); - assert!(uf == false, "refund can not be more than net cost itself"); + let extra_cost = match inner_variant { + LogOpcode::PrecompileCall => { + let precompile_aux_data = PrecompileAuxData::from_u256(src1); - net_cost + precompile_aux_data.extra_ergs_cost + } + LogOpcode::Decommit => { + // extra cost is in src1 + let extra_cost = src1.low_u32(); + + // and we check format anyway + use crate::zkevm_opcode_defs::*; + src0.to_big_endian(&mut buffer); + if ContractCodeSha256Format::is_valid(&buffer) { + let (header, normalized_preimage) = + ContractCodeSha256Format::normalize_for_decommitment(&buffer); + decommit_header = header; + decommit_preimage_normalized = normalized_preimage; + } else if BlobSha256Format::is_valid(&buffer) { + let (header, normalized_preimage) = + BlobSha256Format::normalize_for_decommitment(&buffer); + decommit_header = header; + decommit_preimage_normalized = normalized_preimage; } else { - assert_eq!(pubdata_refund, 0); - - 0 + preimage_len_in_bytes = 0; + decommit_preimage_format_is_invalid = true; }; - vm_state.local_state.current_ergs_per_pubdata_byte * net_pubdata - } - LogOpcode::ToL1Message => { - vm_state.local_state.current_ergs_per_pubdata_byte - * zkevm_opcode_defs::system_params::L1_MESSAGE_PUBDATA_BYTES + extra_cost } _ => 0, }; - let extra_cost = match inner_variant { - LogOpcode::PrecompileCall => src1.low_u32(), - _ => 0, - }; - - let total_cost = extra_cost + ergs_on_pubdata; - - let (ergs_remaining, not_enough_power) = ergs_available.overflowing_sub(total_cost); + let (ergs_remaining, not_enough_power) = ergs_available.overflowing_sub(extra_cost); if not_enough_power { vm_state .local_state .callstack .get_current_stack_mut() .ergs_remaining = 0; - - vm_state.local_state.spent_pubdata_counter += - std::cmp::min(ergs_available, ergs_on_pubdata); } else { vm_state .local_state .callstack .get_current_stack_mut() .ergs_remaining = ergs_remaining; - - vm_state.local_state.spent_pubdata_counter += ergs_on_pubdata; } let current_context = vm_state.local_state.callstack.get_current_stack(); @@ -159,15 +140,23 @@ impl> DecodedOpcode { #[allow(dropping_references)] drop(current_context); - match inner_variant { - LogOpcode::StorageRead => { + let (pubdata_to_add_to_current_frame, ergs_refund) = match inner_variant { + variant @ LogOpcode::StorageRead | variant @ LogOpcode::TransientStorageRead => { assert!(not_enough_power == false); let key = src0; + let aux_byte = if variant == LogOpcode::StorageRead { + STORAGE_AUX_BYTE + } else if variant == LogOpcode::TransientStorageRead { + TRANSIENT_STORAGE_AUX_BYTE + } else { + unreachable!() + }; + let partial_query = LogQuery { timestamp: timestamp_for_log, tx_number_in_block, - aux_byte: STORAGE_AUX_BYTE, + aux_byte, shard_id, address, key, @@ -178,9 +167,22 @@ impl> DecodedOpcode { is_service: is_first_message, }; - // we do not expect refunds for reads yet - let query = vm_state + let refund = vm_state.refund_for_partial_query( + vm_state.local_state.monotonic_cycle_counter, + &partial_query, + ); + let ergs_refund = refund.refund(); + + let (query, pubdata_cost) = vm_state .access_storage(vm_state.local_state.monotonic_cycle_counter, partial_query); + + if variant == LogOpcode::TransientStorageRead { + assert_eq!(ergs_refund, 0); + } else { + assert!(ergs_refund <= LogOpcode::StorageRead.ergs_price()); + } + assert_eq!(pubdata_cost.0, 0); + let result = PrimitiveValue { value: query.read_value, is_pointer: false, @@ -191,19 +193,29 @@ impl> DecodedOpcode { dst0_mem_location, self, ); + + (pubdata_cost, ergs_refund) } - LogOpcode::StorageWrite => { + variant @ LogOpcode::StorageWrite | variant @ LogOpcode::TransientStorageWrite => { if not_enough_power { // we can return immediatelly and do not need to update regs - return; + return Ok(()); } let key = src0; let written_value = src1; + let aux_byte = if variant == LogOpcode::StorageWrite { + STORAGE_AUX_BYTE + } else if variant == LogOpcode::TransientStorageWrite { + TRANSIENT_STORAGE_AUX_BYTE + } else { + unreachable!() + }; + let partial_query = LogQuery { timestamp: timestamp_for_log, tx_number_in_block, - aux_byte: STORAGE_AUX_BYTE, + aux_byte, shard_id, address, key, @@ -214,16 +226,35 @@ impl> DecodedOpcode { is_service: is_first_message, }; - // we still do a formal query to execute write and record witness - let _query = vm_state + let refund = vm_state.refund_for_partial_query( + vm_state.local_state.monotonic_cycle_counter, + &partial_query, + ); + let ergs_refund = refund.refund(); + + let (_query, pubdata_cost) = vm_state .access_storage(vm_state.local_state.monotonic_cycle_counter, partial_query); + + if variant == LogOpcode::TransientStorageWrite { + assert_eq!(pubdata_cost.0, 0); + assert_eq!(ergs_refund, 0); + } else { + assert!(abs(pubdata_cost.0) <= MAX_PUBDATA_COST_PER_QUERY as i32); + assert!(ergs_refund <= LogOpcode::StorageWrite.ergs_price()); + } + + if is_rollup == false { + assert_eq!(pubdata_cost.0, 0); + } + + (pubdata_cost, ergs_refund) } variant @ LogOpcode::Event | variant @ LogOpcode::ToL1Message => { if not_enough_power { assert_eq!(variant, LogOpcode::ToL1Message); // we do not add anything into log and do not need to update // registers - return; + return Ok(()); } let key = src0; let written_value = src1; @@ -234,6 +265,14 @@ impl> DecodedOpcode { L1_MESSAGE_AUX_BYTE }; + let pubdata_cost = if variant == LogOpcode::Event { + PubdataCost(0i32) + } else { + // those messages are reactive and may contain pubdata from different source, so + // we do not count them here + PubdataCost(0i32) + }; + let query = LogQuery { timestamp: timestamp_for_log, tx_number_in_block, @@ -248,10 +287,11 @@ impl> DecodedOpcode { is_service: is_first_message, }; vm_state.emit_event(vm_state.local_state.monotonic_cycle_counter, query); + + (pubdata_cost, 0) } LogOpcode::PrecompileCall => { // add extra information about precompile abi in the "key" field - if not_enough_power { // we have to update register vm_state.perform_dst0_update( @@ -260,72 +300,158 @@ impl> DecodedOpcode { dst0_mem_location, &self, ); - return; - } - let mut precompile_abi = PrecompileCallABI::from_u256(src0); - // normal execution - vm_state - .local_state - .callstack - .get_current_stack_mut() - .ergs_remaining = ergs_remaining; - if precompile_abi.memory_page_to_read == 0 { - let memory_page_to_read = CallStackEntry::::heap_page_from_base( - vm_state - .local_state - .callstack - .get_current_stack() - .base_memory_page, + (PubdataCost(0), 0) + } else { + let mut precompile_abi = PrecompileCallABI::from_u256(src0); + let precompile_aux_data = PrecompileAuxData::from_u256(src1); + + // normal execution + vm_state + .local_state + .callstack + .get_current_stack_mut() + .ergs_remaining = ergs_remaining; + if precompile_abi.memory_page_to_read == 0 { + let memory_page_to_read = heap_page_from_base( + vm_state + .local_state + .callstack + .get_current_stack() + .base_memory_page, + ); + precompile_abi.memory_page_to_read = memory_page_to_read.0; + } + + if precompile_abi.memory_page_to_write == 0 { + let memory_page_to_write = heap_page_from_base( + vm_state + .local_state + .callstack + .get_current_stack() + .base_memory_page, + ); + precompile_abi.memory_page_to_write = memory_page_to_write.0; + } + + let timestamp_to_read = + vm_state.timestamp_for_first_decommit_or_precompile_read(); + debug_assert!(timestamp_to_read == timestamp_for_log); + let timestamp_to_write = + vm_state.timestamp_for_second_decommit_or_precompile_write(); + debug_assert!(timestamp_to_read.0 + 1 == timestamp_to_write.0); + + let precompile_abi_encoded = precompile_abi.to_u256(); + + let query = LogQuery { + timestamp: timestamp_for_log, + tx_number_in_block, + aux_byte: PRECOMPILE_AUX_BYTE, + shard_id, + address, + key: precompile_abi_encoded, + read_value: U256::zero(), + written_value: U256::zero(), + rw_flag: false, + rollback: false, + is_service: is_first_message, + }; + + vm_state.call_precompile(vm_state.local_state.monotonic_cycle_counter, query); + let result = PrimitiveValue { + value: U256::from(1u64), + is_pointer: false, + }; + vm_state.perform_dst0_update( + vm_state.local_state.monotonic_cycle_counter, + result, + dst0_mem_location, + &self, ); - precompile_abi.memory_page_to_read = memory_page_to_read.0; - } - if precompile_abi.memory_page_to_write == 0 { - let memory_page_to_write = CallStackEntry::::heap_page_from_base( + let extra_pubdata_cost = precompile_aux_data.extra_pubdata_cost; + assert!(extra_pubdata_cost <= i32::MAX as u32); + + (PubdataCost(extra_pubdata_cost as i32), 0) + } + } + LogOpcode::Decommit => { + // we take a preimage from src0, check it's format, normalize and add to decommit queue + let (dst_0_value, (pubdata_cost, refund)) = if decommit_preimage_format_is_invalid + || not_enough_power + { + // we have to update register anyway + (PrimitiveValue::empty(), (PubdataCost(0), 0)) + } else { + // add to decommit queue the normalized image + let timestamp_for_decommit = + vm_state.timestamp_for_first_decommit_or_precompile_read(); + let memory_page_candidate_for_decommitment = heap_page_from_base( vm_state .local_state .callstack .get_current_stack() .base_memory_page, ); - precompile_abi.memory_page_to_write = memory_page_to_write.0; - } - - let timestamp_to_read = vm_state.timestamp_for_first_decommit_or_precompile_read(); - debug_assert!(timestamp_to_read == timestamp_for_log); - let timestamp_to_write = - vm_state.timestamp_for_second_decommit_or_precompile_write(); - debug_assert!(timestamp_to_read.0 + 1 == timestamp_to_write.0); - - let precompile_abi_encoded = precompile_abi.to_u256(); - - let query = LogQuery { - timestamp: timestamp_for_log, - tx_number_in_block, - aux_byte: PRECOMPILE_AUX_BYTE, - shard_id, - address, - key: precompile_abi_encoded, - read_value: U256::zero(), - written_value: U256::zero(), - rw_flag: false, - rollback: false, - is_service: is_first_message, + assert!(decommit_preimage_normalized.0 != [0u8; 28], "original buffer {:?} lead to zero normalized preimage, but didn't trigger exception", buffer); + let prepared_decommittment_query = vm_state.prepare_to_decommit( + vm_state.local_state.monotonic_cycle_counter, + decommit_header, + decommit_preimage_normalized, + memory_page_candidate_for_decommitment, + timestamp_for_decommit, + )?; + + let refund = if prepared_decommittment_query.is_fresh == false { + extra_cost + } else { + 0 + }; + + vm_state.execute_decommit( + vm_state.local_state.monotonic_cycle_counter, + prepared_decommittment_query, + )?; + + let output_memory_page = prepared_decommittment_query.memory_page; + // form a fat pointer + let fat_pointer = FatPointer { + offset: 0, + memory_page: output_memory_page.0, + start: 0, + length: preimage_len_in_bytes as u32, + }; + + ( + PrimitiveValue { + value: fat_pointer.to_u256(), + is_pointer: true, + }, + (PubdataCost(0), refund), + ) }; - vm_state.call_precompile(vm_state.local_state.monotonic_cycle_counter, query); - let result = PrimitiveValue { - value: U256::from(1u64), - is_pointer: false, - }; + // and update register vm_state.perform_dst0_update( vm_state.local_state.monotonic_cycle_counter, - result, + dst_0_value, dst0_mem_location, &self, ); + + (pubdata_cost, refund) } - } + }; + + // apply refund + vm_state + .local_state + .callstack + .get_current_stack_mut() + .ergs_remaining += ergs_refund; + + vm_state.add_pubdata_cost(pubdata_to_add_to_current_frame); + + Ok(()) } } diff --git a/crates/zk_evm/src/opcodes/execution/mod.rs b/crates/zk_evm/src/opcodes/execution/mod.rs index 1fee64f..5c879ab 100644 --- a/crates/zk_evm/src/opcodes/execution/mod.rs +++ b/crates/zk_evm/src/opcodes/execution/mod.rs @@ -1,7 +1,7 @@ use super::*; use crate::vm_state::*; -use zkevm_opcode_defs::decoding::AllowedPcOrImm; -use zkevm_opcode_defs::decoding::VmEncodingMode; +use crate::zkevm_opcode_defs::decoding::AllowedPcOrImm; +use crate::zkevm_opcode_defs::decoding::VmEncodingMode; pub mod add; pub mod binop; diff --git a/crates/zk_evm/src/opcodes/execution/mul.rs b/crates/zk_evm/src/opcodes/execution/mul.rs index 253e8bd..e4afcb6 100644 --- a/crates/zk_evm/src/opcodes/execution/mul.rs +++ b/crates/zk_evm/src/opcodes/execution/mul.rs @@ -29,7 +29,7 @@ impl> DecodedOpcode { is_pointer: _, } = src1; - use zkevm_opcode_defs::SET_FLAGS_FLAG_IDX; + use crate::zkevm_opcode_defs::SET_FLAGS_FLAG_IDX; let set_flags = self.variant.flags[SET_FLAGS_FLAG_IDX]; vm_state.local_state.callstack.get_current_stack_mut().pc = new_pc; let tmp = src0.full_mul(src1).0; diff --git a/crates/zk_evm/src/opcodes/execution/near_call.rs b/crates/zk_evm/src/opcodes/execution/near_call.rs index 714eb3f..cc5aae4 100644 --- a/crates/zk_evm/src/opcodes/execution/near_call.rs +++ b/crates/zk_evm/src/opcodes/execution/near_call.rs @@ -1,4 +1,6 @@ -use zkevm_opcode_defs::NearCallABI; +use zk_evm_abstractions::aux::PubdataCost; + +use crate::zkevm_opcode_defs::NearCallABI; use super::*; @@ -26,7 +28,16 @@ impl> DecodedOpcode { // proceed with call let dst = self.imm_0; let exception_handler_location = self.imm_1; - let near_call_abi = NearCallABI::from_u256(src0); + let mut near_call_abi = NearCallABI::from_u256(src0); + // convert ergs + near_call_abi.ergs_passed = if let Some(non_overflowing) = + near_call_abi.ergs_passed.checked_mul( + zkevm_opcode_defs::system_params::INTERNAL_ERGS_TO_VISIBLE_ERGS_CONVERSION_CONSTANT, + ) { + non_overflowing + } else { + u32::MAX + }; // resolve passed ergs let pass_all_ergs = near_call_abi.ergs_passed == 0; @@ -61,6 +72,8 @@ impl> DecodedOpcode { new_stack.exception_handler_location = exception_handler_location; new_stack.ergs_remaining = passed_ergs; new_stack.is_local_frame = true; + new_stack.total_pubdata_spent = PubdataCost(0i32); + // we do not need to zero out stipend because it's only used on return from global frame // perform some extra steps to ensure that our rollbacks are properly written and saved // both in storage and for witness diff --git a/crates/zk_evm/src/opcodes/execution/ptr.rs b/crates/zk_evm/src/opcodes/execution/ptr.rs index 244b319..cc3234c 100644 --- a/crates/zk_evm/src/opcodes/execution/ptr.rs +++ b/crates/zk_evm/src/opcodes/execution/ptr.rs @@ -1,6 +1,6 @@ use super::*; -use zkevm_opcode_defs::{FatPointer, Opcode, PtrOpcode}; +use crate::zkevm_opcode_defs::{FatPointer, Opcode, PtrOpcode}; impl> DecodedOpcode { pub fn ptr_opcode_apply< diff --git a/crates/zk_evm/src/opcodes/execution/ret.rs b/crates/zk_evm/src/opcodes/execution/ret.rs index 76e71df..1e8dc46 100644 --- a/crates/zk_evm/src/opcodes/execution/ret.rs +++ b/crates/zk_evm/src/opcodes/execution/ret.rs @@ -1,9 +1,9 @@ use super::*; +use crate::zkevm_opcode_defs::definitions::ret::*; +use crate::zkevm_opcode_defs::FatPointerValidationException; +use crate::zkevm_opcode_defs::{FatPointer, Opcode, RetABI, RetForwardPageType, RetOpcode}; use zk_evm_abstractions::aux::Timestamp; -use zkevm_opcode_defs::definitions::ret::*; -use zkevm_opcode_defs::FatPointerValidationException; -use zkevm_opcode_defs::{FatPointer, Opcode, RetABI, RetForwardPageType, RetOpcode}; impl> DecodedOpcode { pub fn ret_opcode_apply< @@ -69,7 +69,15 @@ impl> DecodedOpcode { // - caller makes far call to some contract // - callee does return-forward @calldataptr // - caller modifies calldata corresponding heap region, that leads to modification of returndata - // we require that returndata forwarding is unidirectional + // we require that returndata forwarding is unidirectional if we are not in kernel + if current_callstack.is_kernel_mode() == false { + inner_variant = RetOpcode::Panic; + } + } + } else { + if src0_is_ptr { + // there is no reasonable case to try to re-interpret pointer + // as integer here inner_variant = RetOpcode::Panic; } } @@ -119,18 +127,14 @@ impl> DecodedOpcode { memory_quasi_fat_pointer.offset = 0; } RetForwardPageType::UseHeap => { - let owned_page = CallStackEntry::::heap_page_from_base( - current_callstack.base_memory_page, - ) - .0; + let owned_page = + heap_page_from_base(current_callstack.base_memory_page).0; memory_quasi_fat_pointer.memory_page = owned_page; } RetForwardPageType::UseAuxHeap => { - let owned_page = CallStackEntry::::aux_heap_page_from_base( - current_callstack.base_memory_page, - ) - .0; + let owned_page = + aux_heap_page_from_base(current_callstack.base_memory_page).0; memory_quasi_fat_pointer.memory_page = owned_page; } @@ -195,6 +199,7 @@ impl> DecodedOpcode { // done with exceptions, so we can pop the callstack entry let panicked = inner_variant == RetOpcode::Revert || inner_variant == RetOpcode::Panic; + // NOTE: this will also take care of the pubdata counters, same way as of rollback queues let finished_callstack = vm_state.finish_frame(vm_state.local_state.monotonic_cycle_counter, panicked); @@ -206,6 +211,7 @@ impl> DecodedOpcode { vm_state.memory.finish_global_frame( finished_callstack.base_memory_page, + finished_callstack.this_address, returndata_fat_pointer, Timestamp(vm_state.local_state.timestamp), ); @@ -234,6 +240,15 @@ impl> DecodedOpcode { // clean up context register vm_state.local_state.context_u128_register = 0u128; + + // we also must reduce remaining ergs if there as a stipend + let (ergs_remaining_without_stipend, uf) = + ergs_remaining.overflowing_sub(finished_callstack.stipend); + if uf == false { + ergs_remaining = ergs_remaining_without_stipend; + } else { + ergs_remaining = 0; + } } else { debug_assert!(fat_ptr_for_returndata.is_none()); } diff --git a/crates/zk_evm/src/opcodes/execution/shift.rs b/crates/zk_evm/src/opcodes/execution/shift.rs index b51858b..6af4489 100644 --- a/crates/zk_evm/src/opcodes/execution/shift.rs +++ b/crates/zk_evm/src/opcodes/execution/shift.rs @@ -2,7 +2,7 @@ use super::*; use std::ops::*; -use zkevm_opcode_defs::{Opcode, ShiftOpcode}; +use crate::zkevm_opcode_defs::{Opcode, ShiftOpcode}; impl> DecodedOpcode { pub fn shift_opcode_apply< @@ -38,7 +38,7 @@ impl> DecodedOpcode { _ => unreachable!(), }; - use zkevm_opcode_defs::SET_FLAGS_FLAG_IDX; + use crate::zkevm_opcode_defs::SET_FLAGS_FLAG_IDX; let set_flags = self.variant.flags[SET_FLAGS_FLAG_IDX]; vm_state.local_state.callstack.get_current_stack_mut().pc = new_pc; let shift_abs = src1.low_u64() as u8; diff --git a/crates/zk_evm/src/opcodes/execution/sub.rs b/crates/zk_evm/src/opcodes/execution/sub.rs index bf18f35..24851cd 100644 --- a/crates/zk_evm/src/opcodes/execution/sub.rs +++ b/crates/zk_evm/src/opcodes/execution/sub.rs @@ -29,7 +29,7 @@ impl> DecodedOpcode { is_pointer: _, } = src1; - use zkevm_opcode_defs::SET_FLAGS_FLAG_IDX; + use crate::zkevm_opcode_defs::SET_FLAGS_FLAG_IDX; let set_flags = self.variant.flags[SET_FLAGS_FLAG_IDX]; vm_state.local_state.callstack.get_current_stack_mut().pc = new_pc; let (result, of) = src0.overflowing_sub(src1); diff --git a/crates/zk_evm/src/opcodes/execution/uma.rs b/crates/zk_evm/src/opcodes/execution/uma.rs index f05c990..06545d8 100644 --- a/crates/zk_evm/src/opcodes/execution/uma.rs +++ b/crates/zk_evm/src/opcodes/execution/uma.rs @@ -1,12 +1,13 @@ use zk_evm_abstractions::aux::*; use zk_evm_abstractions::vm::MemoryType; +use zk_evm_abstractions::zkevm_opcode_defs::STATIC_MEMORY_PAGE; use super::*; -use zkevm_opcode_defs::{FatPointer, Opcode, UMAOpcode, UMA_INCREMENT_FLAG_IDX}; +use crate::zkevm_opcode_defs::{FatPointer, Opcode, UMAOpcode, UMA_INCREMENT_FLAG_IDX}; const U64_TOP_32_BITS_MASK: u64 = 0xffff_ffff_0000_0000; -use zkevm_opcode_defs::bitflags::bitflags; +use crate::zkevm_opcode_defs::bitflags::bitflags; bitflags! { pub struct UMAExceptionFlags: u64 { @@ -79,7 +80,7 @@ impl> DecodedOpcode { let memory_type = match inner_variant { UMAOpcode::HeapRead | UMAOpcode::HeapWrite => { - let page = CallStackEntry::::heap_page_from_base( + let page = heap_page_from_base( vm_state .local_state .callstack @@ -92,7 +93,7 @@ impl> DecodedOpcode { MemoryType::Heap } UMAOpcode::AuxHeapRead | UMAOpcode::AuxHeapWrite => { - let page = CallStackEntry::::aux_heap_page_from_base( + let page = aux_heap_page_from_base( vm_state .local_state .callstack @@ -105,6 +106,11 @@ impl> DecodedOpcode { MemoryType::AuxHeap } UMAOpcode::FatPointerRead => MemoryType::FatPointer, + UMAOpcode::StaticMemoryRead | UMAOpcode::StaticMemoryWrite => { + fat_ptr.memory_page = STATIC_MEMORY_PAGE; + + MemoryType::StaticMemory + } }; let src_offset = if is_ptr_read { @@ -187,7 +193,9 @@ impl> DecodedOpcode { diff } - UMAOpcode::FatPointerRead => { + UMAOpcode::FatPointerRead + | UMAOpcode::StaticMemoryRead + | UMAOpcode::StaticMemoryWrite => { // cost was paid somewhere, and we if try to go out of bound we will just not read 0u32 } @@ -290,7 +298,8 @@ impl> DecodedOpcode { match inner_variant { a @ UMAOpcode::HeapRead | a @ UMAOpcode::AuxHeapRead - | a @ UMAOpcode::FatPointerRead => { + | a @ UMAOpcode::FatPointerRead + | a @ UMAOpcode::StaticMemoryRead => { // if we do "skip op", then we just write formal 0 into destination, // but if "increment" failed, then we skip updates all together @@ -346,7 +355,7 @@ impl> DecodedOpcode { vm_state.set_shorthand_panic(); } } - UMAOpcode::HeapWrite | UMAOpcode::AuxHeapWrite => { + UMAOpcode::HeapWrite | UMAOpcode::AuxHeapWrite | UMAOpcode::StaticMemoryWrite => { // we need to keep highest bytes of old word and place highest bytes of src1 into lowest // cleanup lowest bytes let mut new_word_0_value = diff --git a/crates/zk_evm/src/opcodes/parsing.rs b/crates/zk_evm/src/opcodes/parsing.rs index da73244..4081554 100644 --- a/crates/zk_evm/src/opcodes/parsing.rs +++ b/crates/zk_evm/src/opcodes/parsing.rs @@ -32,8 +32,8 @@ impl> std::fmt::Debug for DecodedOpcode> DecodedOpcode { pub fn mask_into_panic(&mut self) { @@ -56,7 +56,7 @@ impl> DecodedOpcode { vm_state: &mut VmState, prestate: PreState, ) -> anyhow::Result<()> { - use zkevm_opcode_defs::Opcode; + use crate::zkevm_opcode_defs::Opcode; Ok(match self.inner.variant.opcode { Opcode::Nop(_) => self.noop_opcode_apply(vm_state, prestate), @@ -69,7 +69,7 @@ impl> DecodedOpcode { Opcode::Shift(_) => self.shift_opcode_apply(vm_state, prestate), Opcode::Binop(_) => self.binop_opcode_apply(vm_state, prestate), Opcode::Ptr(_) => self.ptr_opcode_apply(vm_state, prestate), - Opcode::Log(_) => self.log_opcode_apply(vm_state, prestate), + Opcode::Log(_) => self.log_opcode_apply(vm_state, prestate)?, Opcode::NearCall(_) => self.near_call_opcode_apply(vm_state, prestate), Opcode::FarCall(_) => self.far_call_opcode_apply(vm_state, prestate)?, Opcode::Ret(_) => self.ret_opcode_apply(vm_state, prestate), diff --git a/crates/zk_evm/src/reference_impls/decommitter.rs b/crates/zk_evm/src/reference_impls/decommitter.rs index b34998f..cda0430 100644 --- a/crates/zk_evm/src/reference_impls/decommitter.rs +++ b/crates/zk_evm/src/reference_impls/decommitter.rs @@ -1,6 +1,10 @@ use zk_evm_abstractions::aux::*; use zk_evm_abstractions::queries::*; use zk_evm_abstractions::vm::*; +use zk_evm_abstractions::zkevm_opcode_defs::BlobSha256Format; +use zk_evm_abstractions::zkevm_opcode_defs::ContractCodeSha256Format; +use zk_evm_abstractions::zkevm_opcode_defs::VersionedHashLen32; +use zk_evm_abstractions::zkevm_opcode_defs::VersionedHashNormalizedPreimage; use super::*; @@ -8,8 +12,8 @@ pub const MEMORY_CELLS_PER_PAGE: usize = (1 << 16) - 1; #[derive(Debug)] pub struct SimpleDecommitter { - known_hashes: HashMap>, - history: HashMap, + known_hashes: HashMap>, + history: HashMap, } impl SimpleDecommitter { @@ -20,81 +24,130 @@ impl SimpleDecommitter { } } + /// While this method is not used within the crate, it is relied upon by the compiler testing infrastructure. + pub fn get_preimage_by_hash( + &self, + hash: VersionedHashNormalizedPreimage, + ) -> Option<&Vec> { + self.known_hashes.get(&hash) + } + pub fn populate(&mut self, elements: Vec<(U256, Vec)>) { + let mut buffer = [0u8; 32]; for (hash, values) in elements.into_iter() { - assert!(!self.known_hashes.contains_key(&hash)); - self.known_hashes.insert(hash, values); + hash.to_big_endian(&mut buffer); + let normalized = if ContractCodeSha256Format::is_valid(&buffer) { + let (_, normalized) = ContractCodeSha256Format::normalize_for_decommitment(&buffer); + normalized + } else if BlobSha256Format::is_valid(&buffer) { + let (_, normalized) = BlobSha256Format::normalize_for_decommitment(&buffer); + normalized + } else { + panic!("Unknown versioned hash format {:?}", hash); + }; + assert!(!self.known_hashes.contains_key(&normalized)); + self.known_hashes.insert(normalized, values); } } } impl DecommittmentProcessor for SimpleDecommitter { - fn decommit_into_memory( + #[track_caller] + fn prepare_to_decommit( &mut self, - monotonic_cycle_counter: u32, + _monotonic_cycle_counter: u32, mut partial_query: DecommittmentQuery, - memory: &mut M, - ) -> anyhow::Result<(DecommittmentQuery, Option>)> { - if let Some((old_page, old_len)) = self.history.get(&partial_query.hash).copied() { + ) -> anyhow::Result { + if let Some((old_page, old_len)) = self + .history + .get(&partial_query.normalized_preimage) + .copied() + { partial_query.is_fresh = false; partial_query.memory_page = MemoryPage(old_page); partial_query.decommitted_length = old_len; - if B { - Ok((partial_query, Some(vec![]))) // empty extra data - } else { - Ok((partial_query, None)) - } + Ok(partial_query) } else { // fresh one let values = self .known_hashes - .get(&partial_query.hash) + .get(&partial_query.normalized_preimage) .cloned() .ok_or_else(|| { - anyhow::anyhow!("Code hash {:?} must be known", &partial_query.hash) + anyhow::anyhow!( + "Code hash {:?} must be known", + &partial_query.normalized_preimage + ) })?; - let page_to_use = partial_query.memory_page; - let timestamp = partial_query.timestamp; partial_query.decommitted_length = values.len() as u16; partial_query.is_fresh = true; - // write into memory - let mut tmp_q = MemoryQuery { - timestamp, - location: MemoryLocation { - memory_type: MemoryType::Code, - page: page_to_use, - index: MemoryIndex(0), - }, - value: U256::zero(), - value_is_pointer: false, - rw_flag: true, - }; - self.history.insert( - partial_query.hash, - ( - partial_query.memory_page.0, - partial_query.decommitted_length, - ), - ); - if B { - for (i, value) in values.iter().enumerate() { - tmp_q.location.index = MemoryIndex(i as u32); - tmp_q.value = *value; - memory.specialized_code_query(monotonic_cycle_counter, tmp_q); - } + Ok(partial_query) + } + } + + #[track_caller] + fn decommit_into_memory( + &mut self, + monotonic_cycle_counter: u32, + partial_query: DecommittmentQuery, + memory: &mut M, + ) -> anyhow::Result>> { + assert!(partial_query.is_fresh); + // fresh one + let values = self + .known_hashes + .get(&partial_query.normalized_preimage) + .cloned() + .ok_or_else(|| { + anyhow::anyhow!( + "Code hash {:?} must be known", + &partial_query.normalized_preimage + ) + })?; + assert_eq!(partial_query.decommitted_length, values.len() as u16); + let page_to_use = partial_query.memory_page; + let timestamp = partial_query.timestamp; + // write into memory + let mut tmp_q = MemoryQuery { + timestamp, + location: MemoryLocation { + memory_type: MemoryType::Code, + page: page_to_use, + index: MemoryIndex(0), + }, + value: U256::zero(), + value_is_pointer: false, + rw_flag: true, + }; - Ok((partial_query, Some(values))) - } else { - for (i, value) in values.into_iter().enumerate() { - tmp_q.location.index = MemoryIndex(i as u32); - tmp_q.value = value; - memory.specialized_code_query(monotonic_cycle_counter, tmp_q); - } + // update history + let existing = self.history.insert( + partial_query.normalized_preimage, + ( + partial_query.memory_page.0, + partial_query.decommitted_length, + ), + ); + assert!(existing.is_none()); - Ok((partial_query, None)) + if B { + for (i, value) in values.iter().enumerate() { + tmp_q.location.index = MemoryIndex(i as u32); + tmp_q.value = *value; + memory.specialized_code_query(monotonic_cycle_counter, tmp_q); } + + Ok(Some(values)) + } else { + for (i, value) in values.into_iter().enumerate() { + tmp_q.location.index = MemoryIndex(i as u32); + tmp_q.value = value; + memory.specialized_code_query(monotonic_cycle_counter, tmp_q); + } + + Ok(None) } } } diff --git a/crates/zk_evm/src/reference_impls/event_sink.rs b/crates/zk_evm/src/reference_impls/event_sink.rs index a0da81a..6f985f1 100644 --- a/crates/zk_evm/src/reference_impls/event_sink.rs +++ b/crates/zk_evm/src/reference_impls/event_sink.rs @@ -1,7 +1,7 @@ use super::*; +use crate::zkevm_opcode_defs::system_params::{EVENT_AUX_BYTE, L1_MESSAGE_AUX_BYTE}; use zk_evm_abstractions::{aux::Timestamp, queries::LogQuery, vm::EventSink}; -use zkevm_opcode_defs::system_params::{EVENT_AUX_BYTE, L1_MESSAGE_AUX_BYTE}; #[derive(Clone, Copy)] pub struct EventMessage { diff --git a/crates/zk_evm/src/reference_impls/memory.rs b/crates/zk_evm/src/reference_impls/memory.rs index 59eb9b0..ed46ffd 100644 --- a/crates/zk_evm/src/reference_impls/memory.rs +++ b/crates/zk_evm/src/reference_impls/memory.rs @@ -1,300 +1,215 @@ -use std::collections::hash_map::RandomState; -use std::{collections::HashSet, hash::BuildHasher}; - -use crate::vm_state::CallStackEntry; use crate::vm_state::PrimitiveValue; +use crate::zkevm_opcode_defs::{FatPointer, BOOTLOADER_CALLDATA_PAGE}; use zk_evm_abstractions::aux::{MemoryPage, Timestamp}; use zk_evm_abstractions::queries::MemoryQuery; -use zk_evm_abstractions::vm::{ - Memory, MemoryType, MAX_CODE_PAGE_SIZE_IN_WORDS, MAX_STACK_PAGE_SIZE_IN_WORDS, -}; -use zkevm_opcode_defs::{FatPointer, BOOTLOADER_CALLDATA_PAGE}; +use zk_evm_abstractions::vm::{Memory, MemoryType}; +use zk_evm_abstractions::zkevm_opcode_defs::system_params::CODE_ORACLE_ADDRESS; + +use self::vm_state::{aux_heap_page_from_base, heap_page_from_base, stack_page_from_base}; use super::*; -pub struct ReusablePool< - T: Sized, - InitFn: Fn() -> T, - OnPullFn: Fn(&mut T) -> (), - OnReturnFn: Fn(&mut T) -> (), -> { - pool: Vec, - init_fn: InitFn, - on_pull_fn: OnPullFn, - on_return_fn: OnReturnFn, -} +const PRIMITIVE_VALUE_EMPTY: PrimitiveValue = PrimitiveValue::empty(); +const PAGE_SUBDIVISION_LEN: usize = 64; -impl T, OnPullFn: Fn(&mut T) -> (), OnReturnFn: Fn(&mut T) -> ()> - ReusablePool -{ - pub fn new_with_capacity( - capacity: usize, - init_fn: InitFn, - on_pull_fn: OnPullFn, - on_return_fn: OnReturnFn, - ) -> Self { - let mut pool = Vec::with_capacity(capacity); - for _ in 0..capacity { - let el = init_fn(); - pool.push(el); - } +#[derive(Debug, Default, Clone)] +struct SparseMemoryPage { + root: Vec>>, +} - Self { - pool, - init_fn, - on_pull_fn, - on_return_fn, - } +impl SparseMemoryPage { + fn get(&self, slot: usize) -> &PrimitiveValue { + self.root + .get(slot / PAGE_SUBDIVISION_LEN) + .and_then(|inner| inner.as_ref()) + .map(|leaf| &leaf[slot % PAGE_SUBDIVISION_LEN]) + .unwrap_or(&PRIMITIVE_VALUE_EMPTY) } + fn set(&mut self, slot: usize, value: PrimitiveValue) -> PrimitiveValue { + let root_index = slot / PAGE_SUBDIVISION_LEN; + let leaf_index = slot % PAGE_SUBDIVISION_LEN; - pub fn pull(&mut self) -> T { - if let Some(mut existing) = self.pool.pop() { - (self.on_pull_fn)(&mut existing); + if self.root.len() <= root_index { + self.root.resize_with(root_index + 1, || None); + } + let node = &mut self.root[root_index]; - existing + if let Some(leaf) = node { + let old = leaf[leaf_index]; + leaf[leaf_index] = value; + old } else { - let mut new = (self.init_fn)(); - (self.on_pull_fn)(&mut new); - - new + let mut leaf = [PrimitiveValue::empty(); PAGE_SUBDIVISION_LEN]; + leaf[leaf_index] = value; + self.root[root_index] = Some(Box::new(leaf)); + PrimitiveValue::empty() } } - pub fn return_element(&mut self, mut el: T) { - (self.on_return_fn)(&mut el); - self.pool.push(el); + fn get_size(&self) -> usize { + self.root.iter().filter_map(|x| x.as_ref()).count() + * PAGE_SUBDIVISION_LEN + * std::mem::size_of::() } } -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -pub enum Indirection { - Heap(usize), - AuxHeap(usize), - ReturndataExtendedLifetime, - Empty, +impl PartialEq for SparseMemoryPage { + fn eq(&self, other: &Self) -> bool { + for slot in 0..self.root.len().max(other.root.len()) * PAGE_SUBDIVISION_LEN { + if self.get(slot) != other.get(slot) { + return false; + } + } + true + } } -// unfortunately we have to name it +#[derive(Debug, Default, Clone)] +pub struct MemoryWrapper { + memory: Vec, +} -#[derive(Debug)] -pub struct HeapPagesReusablePool { - pool: Vec>, +impl PartialEq for MemoryWrapper { + fn eq(&self, other: &Self) -> bool { + let empty_page = SparseMemoryPage::default(); + let empty_pages = std::iter::repeat(&empty_page); + self.memory + .iter() + .chain(empty_pages.clone()) + .zip(other.memory.iter().chain(empty_pages)) + .take(self.memory.len().max(other.memory.len())) + .all(|(a, b)| a == b) + } } -impl HeapPagesReusablePool { - pub fn new_with_capacity(capacity: usize) -> Self { - let mut pool = Vec::with_capacity(capacity); - for _ in 0..capacity { - let el = heap_init(); - pool.push(el); +impl MemoryWrapper { + pub fn ensure_page_exists(&mut self, page: usize) { + if self.memory.len() <= page { + // We don't need to record such events in history + // because all these vectors will be empty + self.memory.resize_with(page + 1, SparseMemoryPage::default); } - - Self { pool } } - pub fn pull(&mut self) -> Vec { - if let Some(mut existing) = self.pool.pop() { - heap_on_pull(&mut existing); - - existing + pub fn dump_page_content_as_u256_words( + &self, + page_number: u32, + range: std::ops::Range, + ) -> Vec { + if let Some(page) = self.memory.get(page_number as usize) { + let mut result = vec![]; + for i in range { + result.push(*page.get(i as usize)); + } + result } else { - let mut new = heap_init(); - heap_on_pull(&mut new); - - new + vec![PrimitiveValue::empty(); range.len()] } } - pub fn return_element(&mut self, mut el: Vec) { - heap_on_return(&mut el); - self.pool.push(el); + pub fn read_slot(&self, page: usize, slot: usize) -> &PrimitiveValue { + self.memory + .get(page) + .map(|page| page.get(slot)) + .unwrap_or(&PRIMITIVE_VALUE_EMPTY) } -} - -#[derive(Debug)] -pub struct StackPagesReusablePool { - pool: Vec>, -} -impl StackPagesReusablePool { - pub fn new_with_capacity(capacity: usize) -> Self { - let mut pool = Vec::with_capacity(capacity); - for _ in 0..capacity { - let el = stack_init(); - pool.push(el); - } - - Self { pool } + pub fn get_size(&self) -> usize { + self.memory.iter().map(|page| page.get_size()).sum() } - pub fn pull(&mut self) -> Vec { - if let Some(mut existing) = self.pool.pop() { - stack_on_pull(&mut existing); - - existing - } else { - let mut new = stack_init(); - stack_on_pull(&mut new); - - new - } + pub(crate) fn write_to_memory(&mut self, page: usize, slot: usize, value: PrimitiveValue) { + self.ensure_page_exists(page); + let page_handle = self.memory.get_mut(page).unwrap(); + page_handle.set(slot, value); } - pub fn return_element(&mut self, mut el: Vec) { - stack_on_return(&mut el); - self.pool.push(el); + fn clear_page(&mut self, page: usize) { + if let Some(page_handle) = self.memory.get_mut(page) { + *page_handle = SparseMemoryPage::default(); + } } } +/// A stack of stacks. The inner stacks are called frames. +/// +/// Does not support popping from the outer stack. Instead, the outer stack can +/// push its topmost frame's contents onto the previous frame. #[derive(Debug)] -pub struct SimpleMemory { - pub stack_pages: Vec<(u32, Vec)>, // easy to purge - pub heaps: Vec<((u32, Vec), (u32, Vec))>, // potentially easier to purge - pub code_pages: HashMap, S>, // live as long as VM is alive - // each frame can get calldata forwarded to it, - // and returndata too. We should keep in mind that - // - calldata ptr CAN be used as returndata - // - returndata ptr CAN be used for calldata - // so we should maintain something like a simple graph for it, - // based on the assumption that even though calldata originates from some HEAP - // it can end up being a returndata, so when we: - // - perform far call we are ok to just keep calldata ptr as indirection - // - but when we return we should check that our returndata ptr doesn't force us to later on - // extend a lifetime of calldataptr indirection - pub pages_with_extended_lifetime: HashMap, S>, - pub page_numbers_indirections: HashMap, - pub indirections_to_cleanup_on_return: Vec>, - - // we do not need a pool for code pages as those are extended lifetime always - pub heaps_pool: HeapPagesReusablePool, - pub stacks_pool: StackPagesReusablePool, -} - -fn heap_init() -> Vec { - vec![U256::zero(); 1 << 10] +pub struct FramedStack { + data: Vec, + frame_start_indices: Vec, } -fn stack_init() -> Vec { - vec![PrimitiveValue::empty(); MAX_STACK_PAGE_SIZE_IN_WORDS] +impl Default for FramedStack { + fn default() -> Self { + // We typically require at least the first frame to be there + // since the last user-provided frame might be reverted + Self { + data: vec![], + frame_start_indices: vec![0], + } + } } -fn heap_on_pull(_el: &mut Vec) -> () {} +impl FramedStack { + fn push_frame(&mut self) { + self.frame_start_indices.push(self.data.len()); + } -fn stack_on_pull(_el: &mut Vec) -> () {} + pub fn current_frame(&self) -> &[T] { + &self.data[*self.frame_start_indices.last().unwrap()..self.data.len()] + } -fn heap_on_return(el: &mut Vec) -> () { - el.fill(U256::zero()); -} + fn extend_frame(&mut self, items: impl IntoIterator) { + self.data.extend(items); + } -fn stack_on_return(el: &mut Vec) -> () { - assert_eq!(el.len(), MAX_STACK_PAGE_SIZE_IN_WORDS); - el.fill(PrimitiveValue::empty()); -} + fn clear_frame(&mut self) { + let start = *self.frame_start_indices.last().unwrap(); + self.data.truncate(start); + } -fn resize_to_fit(el: &mut Vec, idx: usize) { - if el.len() >= idx + 1 { - return; + fn merge_frame(&mut self) { + self.frame_start_indices.pop().unwrap(); } - el.resize(idx + 1, U256::zero()); + fn push_to_frame(&mut self, x: T) { + self.data.push(x); + } } -// as usual, if we rollback the current frame then we apply changes to storage immediately, -// otherwise we carry rollbacks to the parent's frames - -pub fn new_reference_memory_impl() -> ReusablePool< - Vec, - impl Fn() -> Vec, - impl Fn(&mut Vec) -> (), - impl Fn(&mut Vec) -> (), -> { - ReusablePool::new_with_capacity(1 << 10, heap_init, heap_on_pull, heap_on_return) +#[derive(Debug, Default)] +pub struct SimpleMemory { + memory: MemoryWrapper, + observable_pages: FramedStack, } -impl SimpleMemory { +impl SimpleMemory { pub fn new() -> Self { - let mut new = Self { - stack_pages: Vec::with_capacity(1024), // we do not need stack or heaps for root frame as it's never accessible - heaps: Vec::with_capacity(1024), - code_pages: HashMap::with_capacity_and_hasher(1 << 12, S::default()), - pages_with_extended_lifetime: HashMap::with_capacity_and_hasher(64, S::default()), - page_numbers_indirections: HashMap::with_capacity_and_hasher(64, S::default()), - indirections_to_cleanup_on_return: Vec::with_capacity(1024), - heaps_pool: HeapPagesReusablePool::new_with_capacity(1 << 12), - stacks_pool: StackPagesReusablePool::new_with_capacity(1 << 11), - }; - - // this one virtually exists always - new.code_pages - .insert(0u32, vec![U256::zero(); MAX_CODE_PAGE_SIZE_IN_WORDS]); - new.pages_with_extended_lifetime - .insert(BOOTLOADER_CALLDATA_PAGE, vec![U256::zero(); 1 << 10]); - new.page_numbers_indirections.insert(0, Indirection::Empty); // quicker lookup - new.indirections_to_cleanup_on_return - .push(HashSet::with_capacity_and_hasher(4, S::default())); - new.heaps.push(( - (0u32, vec![U256::zero(); 1 << 10]), - (0u32, vec![U256::zero(); 1 << 20]), - )); // formally, so we can access "last" - - new + Self::default() } pub fn new_without_preallocations() -> Self { - let mut new = Self { - stack_pages: Vec::with_capacity(1024), // we do not need stack or heaps for root frame as it's never accessible - heaps: Vec::with_capacity(1024), - code_pages: HashMap::with_capacity_and_hasher(1 << 12, S::default()), - pages_with_extended_lifetime: HashMap::with_capacity_and_hasher(64, S::default()), - page_numbers_indirections: HashMap::with_capacity_and_hasher(64, S::default()), - indirections_to_cleanup_on_return: Vec::with_capacity(1024), - heaps_pool: HeapPagesReusablePool::new_with_capacity(2), - stacks_pool: StackPagesReusablePool::new_with_capacity(2), - }; - - // this one virtually exists always - new.code_pages - .insert(0u32, vec![U256::zero(); MAX_CODE_PAGE_SIZE_IN_WORDS]); - new.pages_with_extended_lifetime - .insert(BOOTLOADER_CALLDATA_PAGE, vec![]); - new.page_numbers_indirections.insert(0, Indirection::Empty); // quicker lookup - new.indirections_to_cleanup_on_return - .push(HashSet::with_capacity_and_hasher(4, S::default())); - new.heaps.push(((0u32, vec![]), (0u32, vec![]))); // formally, so we can access "last" - - new + Self::default() } } -impl SimpleMemory { - // Can populate code pages only - pub fn populate_code(&mut self, elements: Vec<(u32, Vec)>) -> Vec<(u32, usize)> { - let mut results = vec![]; +impl SimpleMemory { + pub fn populate_page(&mut self, elements: Vec<(u32, Vec)>) { for (page, values) in elements.into_iter() { - assert!(!self.code_pages.contains_key(&page)); - let len = values.len(); - assert!(len <= MAX_CODE_PAGE_SIZE_IN_WORDS); - let mut values = values; - values.resize(MAX_CODE_PAGE_SIZE_IN_WORDS, U256::zero()); - self.code_pages.insert(page, values); - results.push((page, len)); + for (i, value) in values.into_iter().enumerate() { + let value = PrimitiveValue { + value, + is_pointer: false, + }; + self.memory.write_to_memory(page as usize, i, value); + } } - - results - } - - // Can never populate stack or aux heap - pub fn populate_heap(&mut self, values: Vec) { - let heaps_data = self.heaps.last_mut().unwrap(); - - heaps_data.0 .1 = values; } pub fn polulate_bootloaders_calldata(&mut self, values: Vec) { - *self - .pages_with_extended_lifetime - .get_mut(&BOOTLOADER_CALLDATA_PAGE) - .unwrap() = values; + self.populate_page(vec![(BOOTLOADER_CALLDATA_PAGE, values)]); } pub fn dump_page_content( @@ -315,83 +230,18 @@ impl SimpleMemory { pub fn dump_page_content_as_u256_words( &self, - page_number: u32, + page: u32, range: std::ops::Range, ) -> Vec { - if let Some(page) = self.code_pages.get(&page_number) { - let mut result = vec![]; - for i in range { - if let Some(word) = page.get(i as usize) { - result.push(*word); - } else { - result.push(U256::zero()); - } - } - - return result; - } else { - if let Some(content) = self.pages_with_extended_lifetime.get(&page_number) { - let mut result = vec![]; - for i in range { - if let Some(word) = content.get(i as usize) { - result.push(*word); - } else { - result.push(U256::zero()); - } - } - - return result; - } - - for (page_idx, content) in self.stack_pages.iter().rev() { - if *page_idx == page_number { - let mut result = vec![]; - for i in range { - if let Some(word) = content.get(i as usize) { - result.push(word.value); - } else { - result.push(U256::zero()); - } - } - - return result; - } else { - continue; - } - } - - for (heap_data, aux_heap_data) in self.heaps.iter().rev() { - if heap_data.0 == page_number { - let content = &heap_data.1; - let mut result = vec![]; - for i in range { - if let Some(word) = content.get(i as usize) { - result.push(*word); - } else { - result.push(U256::zero()); - } - } - - return result; - } else if aux_heap_data.0 == page_number { - let content = &aux_heap_data.1; - let mut result = vec![]; - for i in range { - if let Some(word) = content.get(i as usize) { - result.push(*word); - } else { - result.push(U256::zero()); - } - } - - return result; - } else { - continue; - } - } - } + self.memory + .dump_page_content_as_u256_words(page, range) + .into_iter() + .map(|v| v.value) + .collect() + } - vec![U256::zero(); range.len()] + pub fn read_slot(&self, page: usize, slot: usize) -> &PrimitiveValue { + self.memory.read_slot(page, slot) } pub fn dump_full_page(&self, page_number: u32) -> Vec<[u8; 32]> { @@ -406,122 +256,50 @@ impl Memory for SimpleMemory { _monotonic_cycle_counter: u32, mut query: MemoryQuery, ) -> MemoryQuery { - // we assume that all pages were pre-created, and use a hint here - let page_number = query.location.page.0; match query.location.memory_type { - MemoryType::Stack => { - if query.rw_flag { - let (idx, page) = self.stack_pages.last_mut().unwrap(); - assert_eq!(*idx, page_number); - let primitive = PrimitiveValue { - value: query.value, - is_pointer: query.value_is_pointer, - }; - assert!( - (query.location.index.0 as usize) < page.len(), - "out of bounds for stack page for query {:?}", - query - ); - page[query.location.index.0 as usize] = primitive - } else { - let (idx, page) = self.stack_pages.last().unwrap(); - assert_eq!(*idx, page_number); - assert!( - (query.location.index.0 as usize) < page.len(), - "out of bounds for stack page for query {:?}", - query - ); - let primitive = page[query.location.index.0 as usize]; - query.value = primitive.value; - query.value_is_pointer = primitive.is_pointer; - } - } - a @ MemoryType::Heap | a @ MemoryType::AuxHeap => { - assert!(query.value_is_pointer == false); - if query.rw_flag { - let ( - (current_heap_page, current_heap_content), - (current_aux_heap_page, current_aux_heap_content), - ) = self.heaps.last_mut().unwrap(); - if a == MemoryType::Heap { - debug_assert_eq!(*current_heap_page, query.location.page.0); - resize_to_fit(current_heap_content, query.location.index.0 as usize); - current_heap_content[query.location.index.0 as usize] = query.value; - } else if a == MemoryType::AuxHeap { - debug_assert_eq!(*current_aux_heap_page, query.location.page.0); - resize_to_fit(current_aux_heap_content, query.location.index.0 as usize); - current_aux_heap_content[query.location.index.0 as usize] = query.value; - } else { - unreachable!() - } - } else { - let ( - (current_heap_page, current_heap_content), - (current_aux_heap_page, current_aux_heap_content), - ) = self.heaps.last_mut().unwrap(); - if a == MemoryType::Heap { - debug_assert_eq!(*current_heap_page, query.location.page.0); - resize_to_fit(current_heap_content, query.location.index.0 as usize); - query.value = current_heap_content[query.location.index.0 as usize]; - } else if a == MemoryType::AuxHeap { - debug_assert_eq!(*current_aux_heap_page, query.location.page.0); - resize_to_fit(current_aux_heap_content, query.location.index.0 as usize); - query.value = current_aux_heap_content[query.location.index.0 as usize]; - } else { - unreachable!() - } - } + MemoryType::Stack => {} + MemoryType::Heap | MemoryType::AuxHeap => { + // The following assertion works fine even when doing a read + // from heap through pointer, since `value_is_pointer` can only be set to + // `true` during memory writes. + assert!( + !query.value_is_pointer, + "Pointers can only be stored on stack" + ); } MemoryType::FatPointer => { - assert!(query.rw_flag == false); - assert!(query.value_is_pointer == false); - let indirection = self - .page_numbers_indirections - .get(&page_number) - .expect("fat pointer only points to reachable memory"); - - // NOTE: we CAN have a situation when e.g. callee returned part of the heap that - // was NEVER written into, so it's page would NOT be resized to the index which we try - // to access (even though fat pointe IS in bounds), so we need to use .get() - match indirection { - Indirection::Heap(index) => { - let forwarded_heap_data = &self.heaps[*index]; - assert_eq!(forwarded_heap_data.0 .0, query.location.page.0); - query.value = forwarded_heap_data - .0 - .1 - .get(query.location.index.0 as usize) - .copied() - .unwrap_or(U256::zero()); - } - Indirection::AuxHeap(index) => { - let forwarded_heap_data = &self.heaps[*index]; - assert_eq!(forwarded_heap_data.1 .0, query.location.page.0); - query.value = forwarded_heap_data - .1 - .1 - .get(query.location.index.0 as usize) - .copied() - .unwrap_or(U256::zero()); - } - Indirection::ReturndataExtendedLifetime => { - let page = self - .pages_with_extended_lifetime - .get(&page_number) - .expect("indirection target must exist"); - query.value = page - .get(query.location.index.0 as usize) - .copied() - .unwrap_or(U256::zero()); - } - Indirection::Empty => { - query.value = U256::zero(); - } - } + assert!(!query.rw_flag); + assert!( + !query.value_is_pointer, + "Pointers can only be stored on stack" + ); } MemoryType::Code => { unreachable!("code should be through specialized query"); } + MemoryType::StaticMemory => { + // While `MemoryType::StaticMemory` is formally supported by `vm@1.5.0`, it is never + // used in the system contracts. + unreachable!() + } + } + + let page = query.location.page.0 as usize; + let slot = query.location.index.0 as usize; + + if query.rw_flag { + self.memory.write_to_memory( + page, + slot, + PrimitiveValue { + value: query.value, + is_pointer: query.value_is_pointer, + }, + ); + } else { + let current_value = self.read_slot(page, slot); + query.value = current_value.value; + query.value_is_pointer = current_value.is_pointer; } query @@ -530,46 +308,57 @@ impl Memory for SimpleMemory { fn specialized_code_query( &mut self, _monotonic_cycle_counter: u32, - query: MemoryQuery, + mut query: MemoryQuery, ) -> MemoryQuery { assert_eq!(query.location.memory_type, MemoryType::Code); - let page = query.location.page.0; + assert!( + !query.value_is_pointer, + "Pointers are not used for decommmits" + ); + + let page = query.location.page.0 as usize; + let slot = query.location.index.0 as usize; - let idx = query.location.index.0 as usize; - let mut query = query; if query.rw_flag { - if self.code_pages.contains_key(&page) == false { - self.code_pages - .insert(page, vec![U256::zero(); MAX_CODE_PAGE_SIZE_IN_WORDS]); - } - let page_content = self.code_pages.get_mut(&page).unwrap(); - page_content[idx] = query.value; + self.memory.write_to_memory( + page, + slot, + PrimitiveValue { + value: query.value, + is_pointer: query.value_is_pointer, + }, + ); } else { - debug_assert!(query.value_is_pointer == false); - let page_content = self.code_pages.get(&page).unwrap(); - query.value = page_content[idx]; + let current_value = self.read_slot(page, slot); + query.value = current_value.value; + query.value_is_pointer = current_value.is_pointer; } query } - fn read_code_query(&self, _monotonic_cycle_counter: u32, query: MemoryQuery) -> MemoryQuery { + fn read_code_query( + &self, + _monotonic_cycle_counter: u32, + mut query: MemoryQuery, + ) -> MemoryQuery { assert_eq!(query.location.memory_type, MemoryType::Code); - assert!(!query.rw_flag); - let page = query.location.page.0; + assert!( + !query.value_is_pointer, + "Pointers are not used for decommmits" + ); + assert!(!query.rw_flag, "Only read queries can be processed"); - let idx = query.location.index.0 as usize; - let mut query = query; + let page = query.location.page.0 as usize; + let slot = query.location.index.0 as usize; - debug_assert!(query.value_is_pointer == false); - let page_content = self.code_pages.get(&page).unwrap(); - query.value = page_content[idx]; + let current_value = self.read_slot(page, slot); + query.value = current_value.value; + query.value_is_pointer = current_value.is_pointer; query } - // Notify that we start a new global frame. `calldata_fat_pointer` can not leak in a sense - // that it's already alive somewhere fn start_global_frame( &mut self, _current_base_page: MemoryPage, @@ -577,183 +366,260 @@ impl Memory for SimpleMemory { calldata_fat_pointer: FatPointer, _timestamp: Timestamp, ) { - use zkevm_opcode_defs::decoding::EncodingModeProduction; - - // we can prepare and preallocate, and then deallocate the number of pages that we want - let stack_page = - CallStackEntry::<8, EncodingModeProduction>::stack_page_from_base(new_base_page); - let stack_page_from_pool = self.stacks_pool.pull(); - self.stack_pages.push((stack_page.0, stack_page_from_pool)); - // self.stack_pages.push((stack_page.0, vec![PrimitiveValue::empty(); MAX_STACK_PAGE_SIZE_IN_WORDS])); - - let heap_page = - CallStackEntry::<8, EncodingModeProduction>::heap_page_from_base(new_base_page); - - let aux_heap_page = - CallStackEntry::<8, EncodingModeProduction>::aux_heap_page_from_base(new_base_page); - - let current_heaps_data = self.heaps.last().unwrap(); - let current_heap_page = current_heaps_data.0 .0; - let current_aux_heap_page = current_heaps_data.1 .0; - - let idx_to_use_for_calldata_ptrs = self.heaps.len() - 1; - - let heap_page_from_pool = self.heaps_pool.pull(); - let aux_heap_page_from_pool = self.heaps_pool.pull(); - - self.heaps.push(( - (heap_page.0, heap_page_from_pool), - (aux_heap_page.0, aux_heap_page_from_pool), - )); - - // self.heaps.push( - // ( - // (heap_page.0, vec![U256::zero(); MAX_HEAP_PAGE_SIZE_IN_WORDS]), - // (aux_heap_page.0, vec![U256::zero(); MAX_HEAP_PAGE_SIZE_IN_WORDS]) - // ) - // ); - // we may want to later on cleanup indirections - self.indirections_to_cleanup_on_return - .push(HashSet::with_capacity(4)); - - if calldata_fat_pointer.memory_page == 0 { - // no need to do anything - } else if calldata_fat_pointer.memory_page == current_heap_page { - self.page_numbers_indirections.insert( - current_heap_page, - Indirection::Heap(idx_to_use_for_calldata_ptrs), - ); - // if we will return from here and returndata page will not "leak" calldata page via forwarding, then we can cleanup the indirection - self.indirections_to_cleanup_on_return - .last_mut() - .unwrap() - .insert(current_heap_page); - } else if calldata_fat_pointer.memory_page == current_aux_heap_page { - self.page_numbers_indirections.insert( - current_aux_heap_page, - Indirection::AuxHeap(idx_to_use_for_calldata_ptrs), - ); - self.indirections_to_cleanup_on_return - .last_mut() - .unwrap() - .insert(current_aux_heap_page); - } else { - // calldata is unidirectional, so we check that it's already an indirection - let existing_indirection = self - .page_numbers_indirections - .get(&calldata_fat_pointer.memory_page) - .expect("fat pointer must only point to reachable memory"); - match existing_indirection { - Indirection::Heap(..) | Indirection::AuxHeap(..) => {} - a @ _ => { - panic!("calldata forwaring using pointer {:?} should already have a heap/aux heap indirection, but has {:?}. All indirections:\n {:?}", - &calldata_fat_pointer, - a, - &self.page_numbers_indirections - ); - } - } - } + // Besides the calldata page, we also formally include the current stack + // page, heap page and aux heap page. + // The code page will be always left observable, so we don't include it here. + self.observable_pages.push_frame(); + self.observable_pages.extend_frame(vec![ + calldata_fat_pointer.memory_page, + stack_page_from_base(new_base_page).0, + heap_page_from_base(new_base_page).0, + aux_heap_page_from_base(new_base_page).0, + ]); } - // here we potentially want to do some cleanup fn finish_global_frame( &mut self, base_page: MemoryPage, + last_callstack_this: Address, returndata_fat_pointer: FatPointer, _timestamp: Timestamp, ) { - use zkevm_opcode_defs::decoding::EncodingModeProduction; + // Safe to unwrap here, since `finish_global_frame` is never called with empty stack + let current_observable_pages = self.observable_pages.current_frame(); + let returndata_page = returndata_fat_pointer.memory_page; - // stack always goes out of scope - let stack_page = - CallStackEntry::<8, EncodingModeProduction>::stack_page_from_base(base_page); + // This is code oracle and some preimage has been decommitted into its memory. + // We must keep this memory page forever for future decommits. + let is_returndata_page_static = + last_callstack_this == *CODE_ORACLE_ADDRESS && returndata_fat_pointer.length > 0; + + for &page in current_observable_pages { + // If the page's number is greater than or equal to the `base_page`, + // it means that it was created by the internal calls of this contract. + // We need to add this check as the calldata pointer is also part of the + // observable pages. + if page >= base_page.0 && page != returndata_page { + self.memory.clear_page(page as usize); + } + } - let (stack_page_number, stack_page_to_reuse) = self.stack_pages.pop().unwrap(); - assert_eq!(stack_page_number, stack_page.0); - self.stacks_pool.return_element(stack_page_to_reuse); + self.observable_pages.clear_frame(); + self.observable_pages.merge_frame(); - let returndata_page = returndata_fat_pointer.memory_page; + // If returndata page is static, we do not add it to the list of observable pages, + // effectively preventing it from being cleared in the future. + if !is_returndata_page_static { + self.observable_pages.push_to_frame(returndata_page); + } + } +} + +#[cfg(test)] +mod tests { + use zk_evm_abstractions::{ + aux::{MemoryIndex, MemoryLocation}, + zkevm_opcode_defs::{ + system_params::BOOTLOADER_FORMAL_ADDRESS, BOOTLOADER_BASE_PAGE, + NEW_MEMORY_PAGES_PER_FAR_CALL, + }, + }; + + use self::vm_state::code_page_candidate_from_base; - // we can cleanup all the heap pages that derive from base, if one of those is not in returndata - let heap_page = CallStackEntry::<8, EncodingModeProduction>::heap_page_from_base(base_page); - let aux_heap_page = - CallStackEntry::<8, EncodingModeProduction>::aux_heap_page_from_base(base_page); - - // when we finish the global frame then ALL indirections go out of scope except - // one that becomes returndata itself (if returndata is not taken from heap or aux heap) - - let ( - (current_heap_page, current_heap_content), - (current_aux_heap_page, current_aux_heap_content), - ) = self.heaps.pop().unwrap(); - assert_eq!(heap_page.0, current_heap_page); - assert_eq!(aux_heap_page.0, current_aux_heap_page); - - let mut current_frame_indirections_to_cleanup = self - .indirections_to_cleanup_on_return - .pop() - .expect("indirections must exist"); - let previous_frame_indirections_to_cleanup = self - .indirections_to_cleanup_on_return - .last_mut() - .expect("previous page indirections must exist"); - - if returndata_page == current_heap_page { - // we add indirection and move to extended lifetime - let existing = self - .pages_with_extended_lifetime - .insert(current_heap_page, current_heap_content); - assert!(existing.is_none()); - self.page_numbers_indirections - .insert(current_heap_page, Indirection::ReturndataExtendedLifetime); - previous_frame_indirections_to_cleanup.insert(current_heap_page); - - // and we can reuse another page - self.heaps_pool.return_element(current_aux_heap_content); - } else if returndata_page == current_aux_heap_page { - // we add indirection and move to extended lifetime - let existing = self - .pages_with_extended_lifetime - .insert(current_aux_heap_page, current_aux_heap_content); - assert!(existing.is_none()); - self.page_numbers_indirections.insert( - current_aux_heap_page, - Indirection::ReturndataExtendedLifetime, + use super::*; + + struct MemoryTester { + memory: SimpleMemory, + base_pages: Vec<(Address, MemoryPage)>, + base_page_counter: u32, + } + + impl MemoryTester { + /// Starts a new frame with a certain content of the code page. + /// Note, that it is the job of the decommitter to ensure that there are no two same code pages. + /// So this function does not attempt to enforce it. + fn start_frame_with_code(&mut self, address: Address, code: Vec) -> MemoryPage { + let old_base_page = self.base_pages.last().unwrap().1; + + self.base_page_counter += NEW_MEMORY_PAGES_PER_FAR_CALL; + let new_base_page = MemoryPage(self.base_page_counter); + self.base_pages.push((address, new_base_page)); + + // This tester can not pass calldata. + self.memory.start_global_frame( + old_base_page, + new_base_page, + FatPointer::empty(), + Timestamp(0), ); - previous_frame_indirections_to_cleanup.insert(current_aux_heap_page); - // and we can reuse another page - self.heaps_pool.return_element(current_heap_content); - } else { - // this means "forwarding" of some form, - // so we carry indirection forward - - // so it's not masked ret panic page - if returndata_page != 0 { - assert!(self - .page_numbers_indirections - .contains_key(&returndata_page), - "expected that indirections contain page {}. Heap page = {}, aux heap page = {}, full set = {:?}", - returndata_page, - current_heap_page, - current_aux_heap_page, - &self.page_numbers_indirections + let code_page = code_page_candidate_from_base(new_base_page); + for (i, word) in code.into_iter().enumerate() { + // Cycle counter and timestamp should not matter here + self.memory.specialized_code_query( + 0, + MemoryQuery { + timestamp: Timestamp(0), + location: MemoryLocation { + index: MemoryIndex(i as u32), + page: code_page, + memory_type: MemoryType::Code, + }, + value: word, + rw_flag: true, + value_is_pointer: false, + }, ); - current_frame_indirections_to_cleanup.remove(&returndata_page); // otherwise it'll be lost - previous_frame_indirections_to_cleanup.insert(returndata_page); } - // and we can reuse all pages - self.heaps_pool.return_element(current_heap_content); - self.heaps_pool.return_element(current_aux_heap_content); + new_base_page } - // now it's safe to cleanup all the indirections we have encountered at this page + /// Starts a new frame with a certain content of the code page. + /// Note, that it is the job of the decommitter to ensure that there are no two same code pages. + /// So this function does not attempt to enforce it. + fn finish_frame(&mut self, returndata_fat_pointer: FatPointer) { + let (last_address, last_base_page) = self.base_pages.pop().unwrap(); + + self.memory.finish_global_frame( + last_base_page, + last_address, + returndata_fat_pointer, + Timestamp(0), + ); + } + + fn read_query(&mut self, location: MemoryLocation) -> U256 { + self.memory + .execute_partial_query( + 0, + MemoryQuery { + timestamp: Timestamp(0), + location, + value: U256::zero(), + rw_flag: false, + value_is_pointer: false, + }, + ) + .value + } - for el in current_frame_indirections_to_cleanup.into_iter() { - let existing = self.page_numbers_indirections.remove(&el); - assert!(existing.is_some(), "double free in indirection"); + fn read_code_query(&mut self, location: MemoryLocation) -> U256 { + assert!(location.memory_type == MemoryType::Code); + self.memory + .specialized_code_query( + 0, + MemoryQuery { + timestamp: Timestamp(0), + location, + value: U256::zero(), + rw_flag: false, + value_is_pointer: false, + }, + ) + .value } + + fn get_heap_location(&self, index: u32) -> MemoryLocation { + MemoryLocation { + index: MemoryIndex(index), + page: heap_page_from_base(self.base_pages.last().unwrap().1), + memory_type: MemoryType::Heap, + } + } + + fn write_query(&mut self, location: MemoryLocation, value: U256) -> U256 { + self.memory + .execute_partial_query( + 0, + MemoryQuery { + timestamp: Timestamp(0), + location: location, + value, + rw_flag: true, + value_is_pointer: false, + }, + ) + .value + } + + fn new() -> Self { + let mut memory = SimpleMemory::new(); + // We always have the bootloader frame at the start + memory.start_global_frame( + MemoryPage(0), + MemoryPage(BOOTLOADER_BASE_PAGE), + FatPointer::empty(), + Timestamp(0), + ); + + Self { + memory: memory, + base_page_counter: 0, + base_pages: vec![ + (Address::zero(), MemoryPage(0)), + (*BOOTLOADER_FORMAL_ADDRESS, MemoryPage(BOOTLOADER_BASE_PAGE)), + ], + } + } + } + + #[test] + fn test_standard_read() { + let mut tester = MemoryTester::new(); + + tester.write_query(tester.get_heap_location(0), U256::from(42)); + let read_value = tester.read_query(tester.get_heap_location(0)); + + assert_eq!(read_value, U256::from(42)); + } + + #[test] + fn test_multiple_returndata_pointers() { + let mut tester = MemoryTester::new(); + + fn start_frame_and_write_to_page(tester: &mut MemoryTester, value: U256) -> MemoryLocation { + tester.start_frame_with_code(Address::zero(), vec![]); + let location = tester.get_heap_location(0); + tester.write_query(location, value); + tester.finish_frame(FatPointer { + offset: 0, + memory_page: location.page.0, + start: 0, + length: 32, + }); + + location + } + + // Here we generate 3 different returndata pointers. All of them must be accessible. + let locations = vec![ + start_frame_and_write_to_page(&mut tester, U256::from(0)), + start_frame_and_write_to_page(&mut tester, U256::from(1)), + start_frame_and_write_to_page(&mut tester, U256::from(2)), + ]; + + for (i, location) in locations.into_iter().enumerate() { + let read_value = tester.read_query(location); + assert_eq!(read_value, U256::from(i)); + } + } + + #[test] + fn test_code_page_accessibility() { + let mut tester = MemoryTester::new(); + + let base_page = tester.start_frame_with_code(Address::zero(), vec![U256::from(42)]); + tester.finish_frame(FatPointer::empty()); + + // If fat pointer is every created that points to the page, it must be still accessible + let read_value = tester.read_query(MemoryLocation { + index: MemoryIndex(0), + memory_type: MemoryType::FatPointer, + page: code_page_candidate_from_base(base_page), + }); + + assert_eq!(read_value, U256::from(42)); } } diff --git a/crates/zk_evm/src/testing/storage.rs b/crates/zk_evm/src/testing/storage.rs index d860b74..6fa286c 100644 --- a/crates/zk_evm/src/testing/storage.rs +++ b/crates/zk_evm/src/testing/storage.rs @@ -1,5 +1,7 @@ -use zk_evm_abstractions::aux::Timestamp; -use zk_evm_abstractions::vm::{RefundType, Storage}; +use crate::zkevm_opcode_defs::system_params::MAX_PUBDATA_COST_PER_QUERY; +use zk_evm_abstractions::aux::{PubdataCost, Timestamp}; +use zk_evm_abstractions::vm::{Storage, StorageAccessRefund}; +use zk_evm_abstractions::zkevm_opcode_defs::system_params::STORAGE_AUX_BYTE; use super::ApplicationData; use super::*; @@ -7,7 +9,9 @@ use super::*; #[derive(Debug, Clone)] pub struct InMemoryStorage { pub inner: [HashMap>; NUM_SHARDS], + pub inner_transient: [HashMap>; NUM_SHARDS], pub cold_warm_markers: [HashMap>; NUM_SHARDS], + pub transient_cold_warm_markers: [HashMap>; NUM_SHARDS], // not used pub frames_stack: Vec>, } @@ -18,7 +22,9 @@ impl InMemoryStorage { pub fn new() -> Self { Self { inner: [(); NUM_SHARDS].map(|_| HashMap::default()), + inner_transient: [(); NUM_SHARDS].map(|_| HashMap::default()), cold_warm_markers: [(); NUM_SHARDS].map(|_| HashMap::default()), + transient_cold_warm_markers: [(); NUM_SHARDS].map(|_| HashMap::default()), frames_stack: vec![ApplicationData::empty()], } } @@ -52,6 +58,9 @@ impl InMemoryStorage { // note that we only use "forward" part and discard the rollbacks at the end, // since if rollbacks of parents were not appended anywhere we just still keep them for el in forward.into_iter() { + if el.aux_byte != STORAGE_AUX_BYTE { + continue; + } let LogQuery { timestamp, shard_id, @@ -77,21 +86,32 @@ impl InMemoryStorage { } impl Storage for InMemoryStorage { - fn estimate_refunds_for_write( - &mut self, + #[track_caller] + fn get_access_refund( + &mut self, // to avoid any hacks inside, like prefetch _monotonic_cycle_counter: u32, _partial_query: &LogQuery, - ) -> RefundType { - RefundType::None + ) -> StorageAccessRefund { + StorageAccessRefund::Cold } + #[track_caller] fn execute_partial_query( &mut self, _monotonic_cycle_counter: u32, mut query: LogQuery, - ) -> LogQuery { - let shard_level_map = &mut self.inner[query.shard_id as usize]; - let shard_level_warm_map = &mut self.cold_warm_markers[query.shard_id as usize]; + ) -> (LogQuery, PubdataCost) { + let aux_byte = query.aux_byte; + let shard_level_map = if aux_byte == STORAGE_AUX_BYTE { + &mut self.inner[query.shard_id as usize] + } else { + &mut self.inner_transient[query.shard_id as usize] + }; + let shard_level_warm_map = if aux_byte == STORAGE_AUX_BYTE { + &mut self.cold_warm_markers[query.shard_id as usize] + } else { + &mut self.transient_cold_warm_markers[query.shard_id as usize] + }; let frame_data = self.frames_stack.last_mut().expect("frame must be started"); assert!(!query.rollback); @@ -117,7 +137,13 @@ impl Storage for InMemoryStorage { frame_data.rollbacks.push(query); query.rollback = false; - query + let pubdata_cost = if aux_byte == STORAGE_AUX_BYTE { + PubdataCost(MAX_PUBDATA_COST_PER_QUERY) + } else { + PubdataCost(0i32) + }; + + (query, pubdata_cost) } else { // read, do not append to rollback let address_level_map = shard_level_map.entry(query.address).or_default(); @@ -134,13 +160,17 @@ impl Storage for InMemoryStorage { query.read_value = current_value; frame_data.forward.push(query); - query + (query, PubdataCost(0i32)) } } + + #[track_caller] fn start_frame(&mut self, _timestamp: Timestamp) { let new = ApplicationData::empty(); self.frames_stack.push(new); } + + #[track_caller] fn finish_frame(&mut self, _timestamp: Timestamp, panicked: bool) { // if we panic then we append forward and rollbacks to the forward of parent, // otherwise we place rollbacks of child before rollbacks of the parent @@ -162,9 +192,14 @@ impl Storage for InMemoryStorage { key, read_value, written_value, + aux_byte, .. } = *query; - let shard_level_map = &mut self.inner[shard_id as usize]; + let shard_level_map = if aux_byte == STORAGE_AUX_BYTE { + &mut self.inner[shard_id as usize] + } else { + &mut self.inner_transient[shard_id as usize] + }; let address_level_map = shard_level_map .get_mut(&address) .expect("must always exist on rollback"); @@ -184,4 +219,11 @@ impl Storage for InMemoryStorage { parent_data.rollbacks.extend(rollbacks); } } + + #[track_caller] + fn start_new_tx(&mut self, _: Timestamp) { + for transient in self.inner_transient.iter_mut() { + transient.clear(); + } + } } diff --git a/crates/zk_evm/src/testing/tests/precompiles/ecrecover.rs b/crates/zk_evm/src/testing/tests/precompiles/ecrecover.rs index 0585b7d..2ba2bcb 100644 --- a/crates/zk_evm/src/testing/tests/precompiles/ecrecover.rs +++ b/crates/zk_evm/src/testing/tests/precompiles/ecrecover.rs @@ -1,104 +1,144 @@ use super::*; - -fn fill_memory(hash: [u8; 32], r: [u8; 32], s: [u8; 32], v: bool, page: u32, memory: &mut M) -> u16 { - let mut location = MemoryLocation {page: MemoryPage(page), index: MemoryIndex(0)}; +use zk_evm_abstractions::auxiliary::*; +use zk_evm_abstractions::queries::*; +use zk_evm_abstractions::vm::*; +use zkevm_opcode_defs::system_params::*; +use zkevm_opcode_defs::PrecompileCallABI; + +fn fill_memory( + hash: [u8; 32], + r: [u8; 32], + s: [u8; 32], + v: bool, + page: u32, + memory: &mut M, +) -> u16 { + let mut location = MemoryLocation { + page: MemoryPage(page), + index: MemoryIndex(0), + memory_type: MemoryType::Heap, + }; let query = MemoryQuery { timestamp: Timestamp(0u32), location, value: U256::from_big_endian(&hash), - rw_flag: true + rw_flag: true, + value_is_pointer: false, }; - let _ = memory.execute_partial_query(query); + let _ = memory.execute_partial_query(0, query); location.index.0 += 1; + let mut buffer = [0u8; 32]; + if v { + buffer[31] = 1; + } let query = MemoryQuery { timestamp: Timestamp(0u32), location, - value: U256::from_big_endian(&r), - rw_flag: true + value: U256::from_big_endian(&buffer), + rw_flag: true, + value_is_pointer: false, }; - let _ = memory.execute_partial_query(query); + let _ = memory.execute_partial_query(1, query); location.index.0 += 1; let query = MemoryQuery { timestamp: Timestamp(0u32), location, - value: U256::from_big_endian(&s), - rw_flag: true + value: U256::from_big_endian(&r), + rw_flag: true, + value_is_pointer: false, }; - let _ = memory.execute_partial_query(query); + let _ = memory.execute_partial_query(2, query); location.index.0 += 1; - let mut buffer = [0u8; 32]; - if v { - buffer[31] = 1; - } let query = MemoryQuery { timestamp: Timestamp(0u32), location, - value: U256::from_big_endian(&buffer), - rw_flag: true + value: U256::from_big_endian(&s), + rw_flag: true, + value_is_pointer: false, }; - let _ = memory.execute_partial_query(query); - + let _ = memory.execute_partial_query(3, query); 4 as u16 } -fn ecrecover_test_inner(hash: [u8; 32], r: [u8; 32], s: [u8; 32], v: bool, expect_ok: bool, expected_address: [u8; 20]) -> (Vec<[u8; 32]>, std::ops::Range) { +fn ecrecover_test_inner( + hash: [u8; 32], + r: [u8; 32], + s: [u8; 32], + v: bool, + expect_ok: bool, + expected_address: [u8; 20], +) -> (Vec<[u8; 32]>, std::ops::Range) { let mut memory = SimpleMemory::new(); let mut precompiles_processor = DefaultPrecompilesProcessor::; + let page_number = 4u32; + // create heap page + memory.populate_page(vec![ + (page_number, vec![U256::zero(); 1 << 10]), + (page_number + 1, vec![]), + ]); // fill the memory - let num_words_used = fill_memory(hash, r, s, v, 0u32, &mut memory); - - let precompile_call_params = PrecompileCallParams { - input_location: MemoryLocation {page: MemoryPage(0u32), index: MemoryIndex(0u16)}, - output_location: MemoryLocation {page: MemoryPage(0u32), index: MemoryIndex(num_words_used)}, - timestamp_for_input_read: Timestamp(1u32), - timestamp_for_output_write: Timestamp(2u32), + let num_words_used = fill_memory(hash, r, s, v, page_number, &mut memory); + + let precompile_call_params = PrecompileCallABI { + input_memory_offset: 0, + input_memory_length: num_words_used as u32, + output_memory_offset: num_words_used as u32, + output_memory_length: 2, + memory_page_to_read: page_number, + memory_page_to_write: page_number, + precompile_interpreted_data: 0, }; + let precompile_call_params_encoded = precompile_call_params.to_u256(); let address = Address::from_low_u64_be(ECRECOVER_INNER_FUNCTION_PRECOMPILE_ADDRESS as u64); let precompile_query = LogQuery { - timestamp: precompile_call_params.timestamp_for_input_read, + timestamp: Timestamp(1u32), tx_number_in_block: 0, shard_id: 0, aux_byte: PRECOMPILE_AUX_BYTE, address, - key: U256::zero(), - read_value: precompile_call_params.encode_into_log_value(), + key: precompile_call_params_encoded, + read_value: U256::zero(), written_value: U256::zero(), rw_flag: false, rollback: false, is_service: false, }; - let _ = precompiles_processor.execute_precompile(precompile_query, &mut memory); + let _ = precompiles_processor.execute_precompile(4, precompile_query, &mut memory); - let range = 0u16..(num_words_used + 2); - let content = memory.dump_page_content(0u32, range.clone()); + let range = 0u32..(num_words_used as u32 + 2); + let content = memory.dump_page_content(page_number, range.clone()); let content_len = content.len(); - let expected_output = content[content_len-1]; - let ok_or_error_marker = content[content_len-2]; + let expected_output = content[content_len - 1]; + let ok_or_error_marker = content[content_len - 2]; if expect_ok { let mut buffer = [0u8; 32]; U256::one().to_big_endian(&mut buffer); - assert!(ok_or_error_marker == buffer); + assert_eq!(ok_or_error_marker, buffer); assert_eq!(&expected_output[12..], &expected_address); } else { let mut buffer = [0u8; 32]; U256::zero().to_big_endian(&mut buffer); - assert!(ok_or_error_marker == buffer); + assert_eq!(ok_or_error_marker, buffer); assert_eq!(&expected_output[..], &[0u8; 32]); } (content, range) } -fn ecrecover_test_inner_from_raw(raw_input: &str, raw_address: &str, expect_ok: bool) -> (Vec<[u8; 32]>, std::ops::Range) { +fn ecrecover_test_inner_from_raw( + raw_input: &str, + raw_address: &str, + expect_ok: bool, +) -> (Vec<[u8; 32]>, std::ops::Range) { let input_bytes = hex::decode(raw_input).unwrap(); let hash: [u8; 32] = input_bytes[0..32].try_into().unwrap(); let v_padded: [u8; 32] = input_bytes[32..64].try_into().unwrap(); @@ -132,13 +172,69 @@ fn test_valid() { pretty_print_memory_dump(&content, range); } +#[test] +fn test_valid_2() { + let hash: [u8; 32] = + hex::decode("5ae8317d34d1e595e3fa7247db80c0af4320cce1116de187f8f7e2e099c0d8d0") + .unwrap() + .try_into() + .unwrap(); + let v = true; + let r: [u8; 32] = + hex::decode("45c0b7f8c09a9e1f1cea0c25785594427b6bf8f9f878a8af0b1abbb48e16d092") + .unwrap() + .try_into() + .unwrap(); + let s: [u8; 32] = + hex::decode("0d8becd0c220f67c51217eecfd7184ef0732481c843857e6bc7fc095c4f6b788") + .unwrap() + .try_into() + .unwrap(); + + let expected_address: [u8; 20] = hex::decode("0624bd72497747be77b2cba25140fcab61ae4fea") + .unwrap() + .try_into() + .unwrap(); + + let (content, range) = ecrecover_test_inner(hash, r, s, v, true, expected_address); + pretty_print_memory_dump(&content, range); +} + +#[test] +fn test_valid_3() { + let hash: [u8; 32] = + hex::decode("14431339128bd25f2c7f93baa611e367472048757f4ad67f6d71a5ca0da550f5") + .unwrap() + .try_into() + .unwrap(); + let v = true; + let r: [u8; 32] = + hex::decode("51e4dbbbcebade695a3f0fdf10beb8b5f83fda161e1a3105a14c41168bf3dce0") + .unwrap() + .try_into() + .unwrap(); + let s: [u8; 32] = + hex::decode("46eabf35680328e26ef4579caf8aeb2cf9ece05dbf67a4f3d1f28c7b1d0e3546") + .unwrap() + .try_into() + .unwrap(); + + let expected_address: [u8; 20] = hex::decode("7f8b3b04bf34618f4a1723fba96b5db211279a2b") + .unwrap() + .try_into() + .unwrap(); + + let (content, range) = ecrecover_test_inner(hash, r, s, v, true, expected_address); + pretty_print_memory_dump(&content, range); +} + #[test] fn test_valid_large_s() { let raw_input = "38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e000000000000000000000000000000000000000000000000000000000000001b38d18acb67d25c8bb9942764b62f18e17054f66a817bd4295423adf9ed98873e7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0"; let raw_address = hex::encode(&vec![ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 198, 174, 93, 17, 93, 119, 163, 216, 169, 239, - 54, 214, 164, 45, 35, 105, 43, 170, 127, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 198, 174, 93, 17, 93, 119, 163, 216, 169, 239, 54, + 214, 164, 45, 35, 105, 43, 170, 127, ]); let (content, range) = ecrecover_test_inner_from_raw(raw_input, &raw_address, true); pretty_print_memory_dump(&content, range); -} \ No newline at end of file +} diff --git a/crates/zk_evm/src/testing/tests/precompiles/keccak256.rs b/crates/zk_evm/src/testing/tests/precompiles/keccak256.rs index d4e62e2..777f4a8 100644 --- a/crates/zk_evm/src/testing/tests/precompiles/keccak256.rs +++ b/crates/zk_evm/src/testing/tests/precompiles/keccak256.rs @@ -1,11 +1,11 @@ use super::*; +use crate::zkevm_opcode_defs::PrecompileCallABI; use zk_evm_abstractions::auxiliary::*; use zk_evm_abstractions::queries::MemoryQuery; use zk_evm_abstractions::vm::Memory; use zk_evm_abstractions::vm::MemoryType; use zk_evm_abstractions::vm::PrecompilesProcessor; -use zkevm_opcode_defs::PrecompileCallABI; fn bytes_to_u256_words(input: Vec, unalignement: usize) -> Vec { let mut result = vec![]; @@ -80,14 +80,11 @@ fn run_keccak256_test_inner( let input_memory_page = 4u32; let output_memory_page = 4u32; - memory.heaps.push(( + memory.populate_page(vec![ (input_memory_page, vec![U256::zero(); 1 << 10]), (0, vec![U256::zero(); 0]), - )); - memory.page_numbers_indirections.insert( - input_memory_page, - reference_impls::memory::Indirection::Heap(1), - ); + ]); + let mut precompiles_processor = DefaultPrecompilesProcessor::; let mut hasher = Keccak256::default(); diff --git a/crates/zk_evm/src/testing/tests/precompiles/mod.rs b/crates/zk_evm/src/testing/tests/precompiles/mod.rs index 0706c4c..0a84e23 100644 --- a/crates/zk_evm/src/testing/tests/precompiles/mod.rs +++ b/crates/zk_evm/src/testing/tests/precompiles/mod.rs @@ -2,7 +2,7 @@ use super::*; mod keccak256; // mod sha256; -// mod ecrecover; +mod ecrecover; fn pretty_print_memory_dump(content: &Vec<[u8; 32]>, range: std::ops::Range) { println!("Memory dump:"); diff --git a/crates/zk_evm/src/tracing.rs b/crates/zk_evm/src/tracing.rs index c226874..a49e5d3 100644 --- a/crates/zk_evm/src/tracing.rs +++ b/crates/zk_evm/src/tracing.rs @@ -1,5 +1,5 @@ +use crate::zkevm_opcode_defs::decoding::{EncodingModeProduction, VmEncodingMode}; use zk_evm_abstractions::{aux::MemoryLocation, vm::Memory}; -use zkevm_opcode_defs::decoding::{EncodingModeProduction, VmEncodingMode}; use crate::{ opcodes::DecodedOpcode, diff --git a/crates/zk_evm/src/utils.rs b/crates/zk_evm/src/utils.rs index de79e02..f750ef7 100644 --- a/crates/zk_evm/src/utils.rs +++ b/crates/zk_evm/src/utils.rs @@ -1,7 +1,7 @@ use crate::tracing::*; +pub use crate::zkevm_opcode_defs::utils::*; +use crate::zkevm_opcode_defs::{decoding::VmEncodingMode, ethereum_types::U256}; use zk_evm_abstractions::vm::Memory; -pub use zkevm_opcode_defs::utils::*; -use zkevm_opcode_defs::{decoding::VmEncodingMode, ethereum_types::U256}; use lazy_static::lazy_static; diff --git a/crates/zk_evm/src/vm_state/aux_data.rs b/crates/zk_evm/src/vm_state/aux_data.rs deleted file mode 100644 index edbefd1..0000000 --- a/crates/zk_evm/src/vm_state/aux_data.rs +++ /dev/null @@ -1,7 +0,0 @@ -use super::*; - -#[derive(Debug, Clone)] -pub struct AuxDataHolder> { - pub empty_hash_port: AlgebraicHashPort, - pub hash_and_ports_round_function: R, -} \ No newline at end of file diff --git a/crates/zk_evm/src/vm_state/cycle.rs b/crates/zk_evm/src/vm_state/cycle.rs index f93339d..e7cee2d 100644 --- a/crates/zk_evm/src/vm_state/cycle.rs +++ b/crates/zk_evm/src/vm_state/cycle.rs @@ -1,9 +1,10 @@ use super::*; use crate::opcodes::parsing::*; +use crate::zkevm_opcode_defs::{ImmMemHandlerFlags, NopOpcode, Operand, RegOrImmFlags}; use tracing::*; +use zk_evm_abstractions::zkevm_opcode_defs::VersionedHashLen32; use zk_evm_abstractions::{aux::*, vm::MemoryType}; -use zkevm_opcode_defs::{ImmMemHandlerFlags, NopOpcode, Operand, RegOrImmFlags}; pub struct PreState = EncodingModeProduction> { pub src0: PrimitiveValue, @@ -16,6 +17,49 @@ pub struct PreState = EncodingModeProdu pub const OPCODES_PER_WORD_LOG_2: usize = 2; pub const OPCODES_PER_WORD: usize = 1 << OPCODES_PER_WORD_LOG_2; +fn read_and_cache_opcode< + const N: usize, + E: VmEncodingMode, + M: zk_evm_abstractions::vm::Memory, + WT: crate::witness_trace::VmWitnessTracer, +>( + local_state: &VmLocalState, + memory: &M, + witness_tracer: &mut WT, + super_pc: >::PcOrImm, + delayed_changes: &mut DelayedLocalStateChanges, +) -> U256 { + // we need to read the code word and select a proper subword + use zk_evm_abstractions::auxiliary::*; + use zk_evm_abstractions::vm::*; + + let code_page = local_state.callstack.get_current_stack().code_page; + let location = MemoryLocation { + memory_type: MemoryType::Code, + page: code_page, + index: MemoryIndex(super_pc.as_u64() as u32), + }; + let key = MemoryKey { + timestamp: local_state.timestamp_for_code_or_src_read(), + location, + }; + + assert!(delayed_changes.new_previous_code_memory_page.is_some()); + + // code read is never pending + let code_query = read_code( + memory, + witness_tracer, + local_state.monotonic_cycle_counter, + key, + ); + let u256_word = code_query.value; + delayed_changes.new_previous_code_word = Some(u256_word); + delayed_changes.new_previous_super_pc = Some(super_pc); + + u256_word +} + pub fn read_and_decode< const N: usize, E: VmEncodingMode, @@ -54,50 +98,35 @@ pub fn read_and_decode< != local_state.previous_code_memory_page; let (super_pc, sub_pc) = E::split_pc(pc); + let refresh_opcode_cache = match (code_pages_are_different, previous_super_pc == super_pc) { + (true, _) | (false, false) => true, + _ => false, + }; + // if we do not skip cycle then we read memory for a new opcode let opcode_encoding = if execution_has_ended == false && pending_exception == false { - let raw_opcode_u64 = match (code_pages_are_different, previous_super_pc == super_pc) { - (true, _) | (false, false) => { - // we need to read the code word and select a proper subword - let code_page = local_state.callstack.get_current_stack().code_page; - let location = MemoryLocation { - memory_type: MemoryType::Code, - page: code_page, - index: MemoryIndex(super_pc.as_u64() as u32), - }; - let key = MemoryKey { - timestamp: local_state.timestamp_for_code_or_src_read(), - location, - }; - - delayed_changes.new_previous_code_memory_page = Some(code_page); - - // code read is never pending - let code_query = read_code( - memory, - witness_tracer, - local_state.monotonic_cycle_counter, - key, - ); - let u256_word = code_query.value; - delayed_changes.new_previous_code_word = Some(u256_word); - delayed_changes.new_previous_super_pc = Some(super_pc); - - // our memory is a set of words in storage, and those are only re-interpreted - // as bytes in UMA. But natural storage for code is still bytes. - - // to ensure consistency with the future if we allow deployment of raw bytecode - // then for our BE machine we should consider that "first" bytes, that will be - // our integer's "highest" bytes, so to follow bytearray-like enumeration we - // have to use inverse order here - let u256_word = u256_word; - E::integer_representaiton_from_u256(u256_word, sub_pc) - } - (false, true) => { - // use a saved one - let u256_word = local_state.previous_code_word; - E::integer_representaiton_from_u256(u256_word, sub_pc) - } + let raw_opcode_u64 = if refresh_opcode_cache { + // we need to read the code word and select a proper subword + let u256_word = read_and_cache_opcode( + local_state, + memory, + witness_tracer, + super_pc, + &mut delayed_changes, + ); + // our memory is a set of words in storage, and those are only re-interpreted + // as bytes in UMA. But natural storage for code is still bytes. + + // to ensure consistency with the future if we allow deployment of raw bytecode + // then for our BE machine we should consider that "first" bytes, that will be + // our integer's "highest" bytes, so to follow bytearray-like enumeration we + // have to use inverse order here + let u256_word = u256_word; + E::integer_representaiton_from_u256(u256_word, sub_pc) + } else { + // use a saved one + let u256_word = local_state.previous_code_word; + E::integer_representaiton_from_u256(u256_word, sub_pc) }; raw_opcode_u64 @@ -105,13 +134,20 @@ pub fn read_and_decode< // there are no cases that set pending exception and // simultaneously finish the execution assert!(execution_has_ended == false); + // if we have an exception then we should still read the word for cache, even if we will have PC later on updated + if refresh_opcode_cache { + let _ = read_and_cache_opcode( + local_state, + memory, + witness_tracer, + super_pc, + &mut delayed_changes, + ); + } // so we can just remove the marker as soon as we are no longer pending delayed_changes.new_pending_exception = Some(false); - // anyway update super PC - delayed_changes.new_previous_super_pc = Some(super_pc); - E::exception_revert_encoding() } else { // we are skipping cycle for some reason, so we do nothing, @@ -191,7 +227,7 @@ pub fn read_and_decode< // resolve condition once let resolved_condition = { - use zkevm_opcode_defs::Condition; + use crate::zkevm_opcode_defs::Condition; match partially_decoded.condition { Condition::Always => true, Condition::Gt => local_state.flags.greater_than_flag, @@ -258,6 +294,29 @@ impl< &mut self, tracer: &mut DT, ) -> anyhow::Result<()> { + // for sanity - check that default AA code hash and EVM simulator code hash are well-formed + let mut buffer = [0u8; 32]; + self.block_properties + .default_aa_code_hash + .to_big_endian(&mut buffer); + assert!( + zkevm_opcode_defs::definitions::versioned_hash::ContractCodeSha256Format::is_valid( + &buffer + ), + "default AA bytecode hash is malfored: {:?}", + &buffer, + ); + self.block_properties + .evm_simulator_code_hash + .to_big_endian(&mut buffer); + assert!( + zkevm_opcode_defs::definitions::versioned_hash::ContractCodeSha256Format::is_valid( + &buffer + ), + "EVM simulator bytecode hash is malfored: {:?}", + &buffer, + ); + let (after_masking_decoded, delayed_changes, skip_cycle) = read_and_decode( &self.local_state, &mut self.memory, diff --git a/crates/zk_evm/src/vm_state/execution_stack.rs b/crates/zk_evm/src/vm_state/execution_stack.rs index cd46fa0..5d0f7ac 100644 --- a/crates/zk_evm/src/vm_state/execution_stack.rs +++ b/crates/zk_evm/src/vm_state/execution_stack.rs @@ -1,6 +1,6 @@ use super::*; -use zkevm_opcode_defs::{INITIAL_SP_ON_FAR_CALL, UNMAPPED_PAGE}; +use crate::zkevm_opcode_defs::{INITIAL_SP_ON_FAR_CALL, UNMAPPED_PAGE}; #[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] pub struct CallStackEntry = EncodingModeProduction> { @@ -21,6 +21,8 @@ pub struct CallStackEntry = EncodingMod pub context_u128_value: u128, pub heap_bound: u32, pub aux_heap_bound: u32, + pub total_pubdata_spent: PubdataCost, + pub stipend: u32, } #[derive(Debug, Clone, PartialEq)] @@ -51,10 +53,12 @@ impl> CallStackEntry { context_u128_value: 0u128, heap_bound: 0u32, aux_heap_bound: 0u32, + total_pubdata_spent: PubdataCost(0i32), + stipend: 0u32, } } pub fn is_kernel_mode(&self) -> bool { - Self::address_is_kernel(&self.this_address) + address_is_kernel(&self.this_address) } pub const fn get_address_low(&self) -> u16 { @@ -63,28 +67,22 @@ impl> CallStackEntry { address_u16 } +} - pub const fn code_page_candidate_from_base(base: MemoryPage) -> MemoryPage { - MemoryPage(base.0) - } - - pub const fn stack_page_from_base(base: MemoryPage) -> MemoryPage { - MemoryPage(base.0 + 1) - } +pub const fn code_page_candidate_from_base(base: MemoryPage) -> MemoryPage { + MemoryPage(base.0) +} - pub const fn heap_page_from_base(base: MemoryPage) -> MemoryPage { - MemoryPage(base.0 + 2) - } +pub const fn stack_page_from_base(base: MemoryPage) -> MemoryPage { + MemoryPage(base.0 + 1) +} - pub const fn aux_heap_page_from_base(base: MemoryPage) -> MemoryPage { - MemoryPage(base.0 + 3) - } +pub const fn heap_page_from_base(base: MemoryPage) -> MemoryPage { + MemoryPage(base.0 + 2) +} - pub fn address_is_kernel(address: &Address) -> bool { - // address < 2^16 - let address_bytes = address.as_fixed_bytes(); - address_bytes[0..18].iter().all(|&el| el == 0u8) - } +pub const fn aux_heap_page_from_base(base: MemoryPage) -> MemoryPage { + MemoryPage(base.0 + 3) } impl> Callstack { diff --git a/crates/zk_evm/src/vm_state/helpers.rs b/crates/zk_evm/src/vm_state/helpers.rs index f9f4b6d..4a16644 100644 --- a/crates/zk_evm/src/vm_state/helpers.rs +++ b/crates/zk_evm/src/vm_state/helpers.rs @@ -2,10 +2,14 @@ use crate::opcodes::DecodedOpcode; use super::*; -use zk_evm_abstractions::aux::{MemoryKey, MemoryLocation}; +use crate::zkevm_opcode_defs::UNMAPPED_PAGE; +use zk_evm_abstractions::aux::{MemoryKey, MemoryLocation, PubdataCost}; use zk_evm_abstractions::queries::{DecommittmentQuery, LogQuery, MemoryQuery}; -use zk_evm_abstractions::vm::RefundType; -use zkevm_opcode_defs::UNMAPPED_PAGE; +use zk_evm_abstractions::vm::StorageAccessRefund; +use zk_evm_abstractions::zkevm_opcode_defs::system_params::STORAGE_AUX_BYTE; +use zk_evm_abstractions::zkevm_opcode_defs::{ + VersionedHashHeader, VersionedHashNormalizedPreimage, +}; pub fn read_code< const N: usize, @@ -116,15 +120,20 @@ impl< query } + #[track_caller] pub fn refund_for_partial_query( &mut self, monotonic_cycle_counter: u32, partial_query: &LogQuery, - ) -> RefundType { - assert!(partial_query.rw_flag == true); + ) -> StorageAccessRefund { + if partial_query.aux_byte != STORAGE_AUX_BYTE { + // Only storage requests support refunds + return StorageAccessRefund::Cold; + } + let refund = self .storage - .estimate_refunds_for_write(monotonic_cycle_counter, partial_query); + .get_access_refund(monotonic_cycle_counter, partial_query); self.witness_tracer.record_refund_for_query( monotonic_cycle_counter, @@ -135,10 +144,15 @@ impl< refund } - pub fn access_storage(&mut self, monotonic_cycle_counter: u32, query: LogQuery) -> LogQuery { + #[track_caller] + pub fn access_storage( + &mut self, + monotonic_cycle_counter: u32, + query: LogQuery, + ) -> (LogQuery, PubdataCost) { // we do not touch pendings here and set them in the opcode only // also storage should internally rollback when ret is performed - let mut query = self + let (mut query, pubdata_cost) = self .storage .execute_partial_query(monotonic_cycle_counter, query); @@ -151,7 +165,15 @@ impl< self.witness_tracer .add_log_query(monotonic_cycle_counter, query); - query + if query.aux_byte == STORAGE_AUX_BYTE { + self.witness_tracer.record_pubdata_cost_for_query( + monotonic_cycle_counter, + query, + pubdata_cost, + ); + } + + (query, pubdata_cost) } pub fn emit_event(&mut self, monotonic_cycle_counter: u32, query: LogQuery) { @@ -161,49 +183,93 @@ impl< .add_log_query(monotonic_cycle_counter, query); } - pub fn decommit( + #[track_caller] + pub fn prepare_to_decommit( &mut self, monotonic_cycle_counter: u32, - hash: U256, + header: VersionedHashHeader, + normalized_preimage: VersionedHashNormalizedPreimage, candidate_page: MemoryPage, timestamp: Timestamp, ) -> anyhow::Result { let partial_query = DecommittmentQuery { - hash, + header, + normalized_preimage, timestamp, memory_page: candidate_page, decommitted_length: 0u16, is_fresh: false, }; - let (query, witness_for_tracer) = self.decommittment_processor.decommit_into_memory( + let query = self + .decommittment_processor + .prepare_to_decommit(monotonic_cycle_counter, partial_query)?; + + // Note, that we should never execute multiple decommitment queries using the same memory page. + // In reality it does not happen: + // - Each far call executes decommit exactly once and it always creates a new code page for it. + // - The `log.decommit` opcode is only available for system contracts and those should be written + // in a way that execute this opcode only once per execution, i.e. per one heap page. + if query.is_fresh { + assert!( + candidate_page == query.memory_page, + "Fresh accesses must use the candidate page" + ); + } else { + assert!( + candidate_page != query.memory_page, + "Non-fresh accesses must not use the candidate page" + ); + } + + self.witness_tracer + .prepare_for_decommittment(monotonic_cycle_counter, query); + + Ok(query) + } + + #[track_caller] + pub fn execute_decommit( + &mut self, + monotonic_cycle_counter: u32, + query: DecommittmentQuery, + ) -> anyhow::Result<()> { + if query.is_fresh == false { + self.witness_tracer + .execute_decommittment(monotonic_cycle_counter, query, vec![]); + + return Ok(()); + } + + let witness_for_tracer = self.decommittment_processor.decommit_into_memory( monotonic_cycle_counter, - partial_query, + query, &mut self.memory, )?; if let Some(witness_for_tracer) = witness_for_tracer { - self.witness_tracer.add_decommittment( + self.witness_tracer.execute_decommittment( monotonic_cycle_counter, query, witness_for_tracer, ); } - Ok(query) + Ok(()) } + #[track_caller] pub fn call_precompile(&mut self, monotonic_cycle_counter: u32, query: LogQuery) { - debug_assert!(self + assert!(self .local_state .callstack .get_current_stack() .is_kernel_mode()); - debug_assert_eq!( + assert_eq!( query.timestamp, self.timestamp_for_first_decommit_or_precompile_read() ); - debug_assert_eq!(query.rw_flag, false); + assert_eq!(query.rw_flag, false); // add to witness self.witness_tracer .add_log_query(monotonic_cycle_counter, query); @@ -245,6 +311,36 @@ impl< self.local_state.callstack.push_entry(context_entry); } + pub fn add_pubdata_cost(&mut self, pubdata_cost: PubdataCost) { + // Short logic descriptions: + // - when we add - we add to both global and local counters + // - when we start new frame - counter is zero + // - when frame ends with success we add to parent + // - when frame rollbacks we adjust global counter + let pubdata_already_spent = self + .local_state + .callstack + .get_current_stack() + .total_pubdata_spent + .0; + // we can neither overflow nor underflow + let (new_pubdata_already_spent, of) = pubdata_already_spent.overflowing_add(pubdata_cost.0); + assert!(of == false); + + self.local_state + .callstack + .get_current_stack_mut() + .total_pubdata_spent = PubdataCost(new_pubdata_already_spent); + + let (new_revert_counter, of) = self + .local_state + .pubdata_revert_counter + .0 + .overflowing_add(pubdata_cost.0); + assert!(of == false); + self.local_state.pubdata_revert_counter = PubdataCost(new_revert_counter); + } + pub fn finish_frame( &mut self, monotonic_cycle_counter: u32, @@ -259,10 +355,55 @@ impl< .finish_execution_context(monotonic_cycle_counter, panicked); let old_frame = self.local_state.callstack.pop_entry(); + // if we panicked then we should subtract all spent pubdata, and reduce the counter of rollbacks + let pubdata_spent_in_new_current_frame = self + .local_state + .callstack + .get_current_stack() + .total_pubdata_spent + .0; + + // if we revert the frame then all it's pubdata changes must be erased, + // otherwise - added to the parent + + // we can neither overflow nor underflow + let (new_pubdata_already_spent, of) = if panicked { + (pubdata_spent_in_new_current_frame, false) + } else { + pubdata_spent_in_new_current_frame.overflowing_add(old_frame.total_pubdata_spent.0) + }; + + assert!(of == false); + + self.local_state + .callstack + .get_current_stack_mut() + .total_pubdata_spent = PubdataCost(new_pubdata_already_spent); + + // same logic - if frame is reverted then it's spendings are "forgotten". In this case + // we need to subtract from global counter to balance it on panic, otherwise - do nothing + let (new_revert_counter, of) = if panicked { + self.local_state + .pubdata_revert_counter + .0 + .overflowing_sub(old_frame.total_pubdata_spent.0) + } else { + // do nothing + (self.local_state.pubdata_revert_counter.0, false) + }; + assert!(of == false); + assert!(new_revert_counter >= 0); // global counter can not be < 0, only local one can + self.local_state.pubdata_revert_counter = PubdataCost(new_revert_counter); old_frame } + pub fn start_new_tx(&mut self) { + self.local_state.tx_number_in_block = self.local_state.tx_number_in_block.wrapping_add(1); + self.storage + .start_new_tx(Timestamp(self.local_state.timestamp)); + } + pub fn perform_dst0_update( &mut self, monotonic_cycle_counter: u32, @@ -338,8 +479,8 @@ impl< } } -use zkevm_opcode_defs::bitflags::bitflags; -use zkevm_opcode_defs::FatPointer; +use crate::zkevm_opcode_defs::bitflags::bitflags; +use crate::zkevm_opcode_defs::FatPointer; bitflags! { #[derive(Default, Clone, Copy, Debug, PartialEq, Eq, Hash)] @@ -351,3 +492,26 @@ bitflags! { const CALLSTACK_IS_FULL = 1u64 << 4; } } + +pub fn address_is_kernel(address: &Address) -> bool { + // address < 2^16 + let address_bytes = address.as_fixed_bytes(); + address_bytes[0..18].iter().all(|&el| el == 0u8) +} + +pub fn get_stipend_and_extra_cost(address: &Address, is_system_call: bool) -> (u32, u32) { + let address_bytes = address.as_fixed_bytes(); + let is_kernel = address_bytes[0..18].iter().all(|&el| el == 0u8); + if is_kernel { + if is_system_call { + let address = u16::from_be_bytes([address_bytes[18], address_bytes[19]]); + use crate::zkevm_opcode_defs::STIPENDS_AND_EXTRA_COSTS_TABLE; + + STIPENDS_AND_EXTRA_COSTS_TABLE[address as usize] + } else { + (0, 0) + } + } else { + (0, 0) + } +} diff --git a/crates/zk_evm/src/vm_state/mem_ops.rs b/crates/zk_evm/src/vm_state/mem_ops.rs index fdb9fb6..8e48d87 100644 --- a/crates/zk_evm/src/vm_state/mem_ops.rs +++ b/crates/zk_evm/src/vm_state/mem_ops.rs @@ -2,13 +2,13 @@ use super::*; use zk_evm_abstractions::aux::{MemoryIndex, MemoryLocation}; use zk_evm_abstractions::vm::MemoryType; -use zkevm_opcode_defs::{ImmMemHandlerFlags, RegOrImmFlags}; +use crate::zkevm_opcode_defs::{ImmMemHandlerFlags, RegOrImmFlags}; pub struct MemOpsProcessor = EncodingModeProduction> { pub sp: E::PcOrImm, } -use zkevm_opcode_defs::Operand; +use crate::zkevm_opcode_defs::Operand; impl> MemOpsProcessor { pub fn compute_addresses_and_select_operands< @@ -58,9 +58,7 @@ impl> MemOpsProcessor { let new_sp = current_sp.wrapping_add(vaddr); self.sp = new_sp; - let stack_page = CallStackEntry::::stack_page_from_base( - current_context.base_memory_page, - ); + let stack_page = stack_page_from_base(current_context.base_memory_page); let location = MemoryLocation { memory_type: MemoryType::Stack, page: stack_page, @@ -73,9 +71,7 @@ impl> MemOpsProcessor { let new_sp = current_sp.wrapping_sub(vaddr); self.sp = new_sp; - let stack_page = CallStackEntry::::stack_page_from_base( - current_context.base_memory_page, - ); + let stack_page = stack_page_from_base(current_context.base_memory_page); let location = MemoryLocation { memory_type: MemoryType::Stack, page: stack_page, @@ -87,8 +83,7 @@ impl> MemOpsProcessor { } Operand::Full(ImmMemHandlerFlags::UseStackWithOffset) => { let offset = self.sp.wrapping_sub(vaddr); - let stack_page = - CallStackEntry::::stack_page_from_base(current_context.base_memory_page); + let stack_page = stack_page_from_base(current_context.base_memory_page); let location = MemoryLocation { memory_type: MemoryType::Stack, page: stack_page, @@ -109,8 +104,7 @@ impl> MemOpsProcessor { Some(location) } Operand::Full(ImmMemHandlerFlags::UseAbsoluteOnStack) => { - let stack_page = - CallStackEntry::::stack_page_from_base(current_context.base_memory_page); + let stack_page = stack_page_from_base(current_context.base_memory_page); let location = MemoryLocation { memory_type: MemoryType::Stack, page: stack_page, diff --git a/crates/zk_evm/src/vm_state/mod.rs b/crates/zk_evm/src/vm_state/mod.rs index e087b54..be2095d 100644 --- a/crates/zk_evm/src/vm_state/mod.rs +++ b/crates/zk_evm/src/vm_state/mod.rs @@ -1,12 +1,13 @@ -use zkevm_opcode_defs::decoding::encoding_mode_production::EncodingModeProduction; -use zkevm_opcode_defs::decoding::VmEncodingMode; -use zkevm_opcode_defs::ISAVersion; +use crate::zkevm_opcode_defs::decoding::encoding_mode_production::EncodingModeProduction; +use crate::zkevm_opcode_defs::decoding::VmEncodingMode; +use crate::zkevm_opcode_defs::ISAVersion; use super::*; use crate::flags::Flags; +use crate::zkevm_opcode_defs::decoding::AllowedPcOrImm; use zk_evm_abstractions::aux::MemoryPage; +use zk_evm_abstractions::aux::PubdataCost; use zk_evm_abstractions::aux::Timestamp; -use zkevm_opcode_defs::decoding::AllowedPcOrImm; pub mod cycle; pub mod execution_stack; @@ -18,7 +19,7 @@ pub use self::execution_stack::*; pub use self::helpers::*; pub use self::mem_ops::*; -pub const SUPPORTED_ISA_VERSION: ISAVersion = ISAVersion(1); +pub const SUPPORTED_ISA_VERSION: ISAVersion = ISAVersion(2); const _: () = if SUPPORTED_ISA_VERSION.0 != zkevm_opcode_defs::DEFAULT_ISA_VERSION.0 { panic!() @@ -26,7 +27,7 @@ const _: () = if SUPPORTED_ISA_VERSION.0 != zkevm_opcode_defs::DEFAULT_ISA_VERSI () }; -use zkevm_opcode_defs::{STARTING_BASE_PAGE, STARTING_TIMESTAMP}; +use crate::zkevm_opcode_defs::{STARTING_BASE_PAGE, STARTING_TIMESTAMP}; #[derive(Default, Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct PrimitiveValue { @@ -64,12 +65,13 @@ pub struct VmLocalState = EncodingModeP pub spent_pubdata_counter: u32, pub memory_page_counter: u32, pub absolute_execution_step: u32, - pub current_ergs_per_pubdata_byte: u32, + // pub current_ergs_per_pubdata_byte: u32, pub tx_number_in_block: u16, pub pending_exception: bool, pub previous_super_pc: E::PcOrImm, pub context_u128_register: u128, pub callstack: Callstack, + pub pubdata_revert_counter: PubdataCost, } impl> VmLocalState { @@ -84,12 +86,13 @@ impl> VmLocalState { spent_pubdata_counter: 0u32, memory_page_counter: STARTING_BASE_PAGE, absolute_execution_step: 0, - current_ergs_per_pubdata_byte: 0, + // current_ergs_per_pubdata_byte: 0, tx_number_in_block: 0, previous_super_pc: E::PcOrImm::from_u64_clipped(0), pending_exception: false, context_u128_register: 0u128, callstack: Callstack::empty(), + pubdata_revert_counter: PubdataCost(0i32), } } diff --git a/crates/zk_evm/src/witness_trace/mod.rs b/crates/zk_evm/src/witness_trace/mod.rs index d552394..cf66555 100644 --- a/crates/zk_evm/src/witness_trace/mod.rs +++ b/crates/zk_evm/src/witness_trace/mod.rs @@ -1,8 +1,9 @@ +use crate::zkevm_opcode_defs::decoding::VmEncodingMode; use zk_evm_abstractions::{ + aux::PubdataCost, queries::{DecommittmentQuery, LogQuery, MemoryQuery}, - vm::{PrecompileCyclesWitness, RefundType}, + vm::{PrecompileCyclesWitness, StorageAccessRefund}, }; -use zkevm_opcode_defs::decoding::VmEncodingMode; use super::*; use crate::vm_state::{CallStackEntry, VmLocalState}; @@ -23,7 +24,7 @@ pub trait VmWitnessTracer>: Clone + std::fm &mut self, monotonic_cycle_counter: u32, log_query: LogQuery, - refund: RefundType, + refund: StorageAccessRefund, ) { } @@ -31,7 +32,24 @@ pub trait VmWitnessTracer>: Clone + std::fm fn add_log_query(&mut self, monotonic_cycle_counter: u32, log_query: LogQuery) {} #[inline] - fn add_decommittment( + fn record_pubdata_cost_for_query( + &mut self, + monotonic_cycle_counter: u32, + log_query: LogQuery, + pubdata_cost: PubdataCost, + ) { + } + + #[inline] + fn prepare_for_decommittment( + &mut self, + monotonic_cycle_counter: u32, + decommittment_query: DecommittmentQuery, + ) { + } + + #[inline] + fn execute_decommittment( &mut self, monotonic_cycle_counter: u32, decommittment_query: DecommittmentQuery, diff --git a/crates/zk_evm_abstractions/Cargo.toml b/crates/zk_evm_abstractions/Cargo.toml index e49b2da..53ed059 100644 --- a/crates/zk_evm_abstractions/Cargo.toml +++ b/crates/zk_evm_abstractions/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zk_evm_abstractions" -version = "0.141.0" +version = "0.150.0" edition = "2021" authors = ["The Matter Labs Team "] homepage = "https://zksync.io/" @@ -18,7 +18,7 @@ serde = { version = "1", features = ["derive"] } static_assertions = "1" num_enum = "0.6" -zkevm_opcode_defs = { version = "=0.141.0", path = "../zkevm_opcode_defs" } +zkevm_opcode_defs = { vesion = "=0.150.0", path = "../zkevm_opcode_defs" } [dev-dependencies] diff --git a/crates/zk_evm_abstractions/src/auxiliary.rs b/crates/zk_evm_abstractions/src/auxiliary.rs index b57e8db..fff5025 100644 --- a/crates/zk_evm_abstractions/src/auxiliary.rs +++ b/crates/zk_evm_abstractions/src/auxiliary.rs @@ -161,3 +161,6 @@ impl std::cmp::Ord for MemoryKey { std::cmp::Ordering::Equal } } + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] +pub struct PubdataCost(pub i32); diff --git a/crates/zk_evm_abstractions/src/lib.rs b/crates/zk_evm_abstractions/src/lib.rs index cc300c1..973d60d 100644 --- a/crates/zk_evm_abstractions/src/lib.rs +++ b/crates/zk_evm_abstractions/src/lib.rs @@ -3,3 +3,5 @@ pub use auxiliary as aux; pub mod precompiles; pub mod queries; pub mod vm; + +pub use zkevm_opcode_defs; diff --git a/crates/zk_evm_abstractions/src/precompiles/ecrecover.rs b/crates/zk_evm_abstractions/src/precompiles/ecrecover.rs index 6088397..91c973a 100644 --- a/crates/zk_evm_abstractions/src/precompiles/ecrecover.rs +++ b/crates/zk_evm_abstractions/src/precompiles/ecrecover.rs @@ -258,10 +258,73 @@ pub fn ecrecover_inner( signature[32..].copy_from_slice(s); // we expect pre-validation, so this check always works let signature = Signature::try_from(&signature[..]).map_err(|_| ())?; - let recid = RecoveryId::try_from(rec_id).unwrap(); - VerifyingKey::recover_from_prehash(digest, &signature, recid).map_err(|_| ()) + recover_no_malleability_check(digest, signature, recid) +} + +fn recover_no_malleability_check( + digest: &[u8; 32], + signature: k256::ecdsa::Signature, + recovery_id: k256::ecdsa::RecoveryId, +) -> Result { + use k256::ecdsa::hazmat::bits2field; + use k256::elliptic_curve::bigint::CheckedAdd; + use k256::elliptic_curve::generic_array::GenericArray; + use k256::elliptic_curve::ops::Invert; + use k256::elliptic_curve::ops::LinearCombination; + use k256::elliptic_curve::ops::Reduce; + use k256::elliptic_curve::point::DecompressPoint; + use k256::elliptic_curve::Curve; + use k256::elliptic_curve::FieldBytesEncoding; + use k256::elliptic_curve::PrimeField; + use k256::AffinePoint; + use k256::ProjectivePoint; + use k256::Scalar; + + let (r, s) = signature.split_scalars(); + let z = >::reduce_bytes( + &bits2field::(digest).map_err(|_| ())?, + ); + + let mut r_bytes: GenericArray::FieldBytesSize> = r.to_repr(); + if recovery_id.is_x_reduced() { + match Option::::from( + >::decode_field_bytes(&r_bytes) + .checked_add(&k256::Secp256k1::ORDER), + ) { + Some(restored) => { + r_bytes = >::encode_field_bytes( + &restored, + ) + } + // No reduction should happen here if r was reduced + None => return Err(()), + }; + } + + #[allow(non_snake_case)] + let R = AffinePoint::decompress(&r_bytes, u8::from(recovery_id.is_y_odd()).into()); + + if R.is_none().into() { + return Err(()); + } + + #[allow(non_snake_case)] + let R = ProjectivePoint::from(R.unwrap()); + let r_inv: Scalar = *r.invert(); + let u1 = -(r_inv * z); + let u2 = r_inv * *s; + let pk = ProjectivePoint::lincomb(&ProjectivePoint::GENERATOR, &u1, &R, &u2); + let vk = VerifyingKey::from_affine(pk.into()).map_err(|_| ())?; + + // Ensure signature verifies with the recovered key + let field = bits2field::(digest).map_err(|_| ())?; + // here we actually skip a high-s check (that should never be there at the first place and should be checked by caller) + let _ = k256::ecdsa::hazmat::verify_prehashed(&vk.as_affine().into(), &field, &signature) + .map_err(|_| ())?; + + Ok(vk) } pub fn ecrecover_function( diff --git a/crates/zk_evm_abstractions/src/precompiles/mod.rs b/crates/zk_evm_abstractions/src/precompiles/mod.rs index 08a4754..54078cf 100644 --- a/crates/zk_evm_abstractions/src/precompiles/mod.rs +++ b/crates/zk_evm_abstractions/src/precompiles/mod.rs @@ -4,13 +4,14 @@ use crate::vm::*; pub mod ecrecover; pub mod keccak256; +pub mod secp256r1_verify; pub mod sha256; use num_enum::TryFromPrimitive; use std::convert::TryFrom; use zkevm_opcode_defs::system_params::{ ECRECOVER_INNER_FUNCTION_PRECOMPILE_ADDRESS, KECCAK256_ROUND_FUNCTION_PRECOMPILE_ADDRESS, - SHA256_ROUND_FUNCTION_PRECOMPILE_ADDRESS, + SECP256R1_VERIFY_PRECOMPILE_ADDRESS, SHA256_ROUND_FUNCTION_PRECOMPILE_ADDRESS, }; use zkevm_opcode_defs::PrecompileCallABI; @@ -21,6 +22,7 @@ pub enum PrecompileAddress { Ecrecover = ECRECOVER_INNER_FUNCTION_PRECOMPILE_ADDRESS, SHA256 = SHA256_ROUND_FUNCTION_PRECOMPILE_ADDRESS, Keccak256 = KECCAK256_ROUND_FUNCTION_PRECOMPILE_ADDRESS, + Secp256r1Verify = SECP256R1_VERIFY_PRECOMPILE_ADDRESS, } pub const fn precompile_abi_in_log(query: LogQuery) -> PrecompileCallABI { @@ -124,6 +126,32 @@ impl PrecompilesProcessor for DefaultPrecompilesProcessor { memory, ); + None + } + } + PrecompileAddress::Secp256r1Verify => { + if B { + let (reads, writes, round_witness) = + secp256r1_verify::secp256r1_verify_function::( + monotonic_cycle_counter, + query, + memory, + ) + .1 + .expect("must generate intermediate witness"); + + Some(( + reads, + writes, + PrecompileCyclesWitness::Secp256r1Verify(round_witness), + )) + } else { + let _ = secp256r1_verify::secp256r1_verify_function::( + monotonic_cycle_counter, + query, + memory, + ); + None } } diff --git a/crates/zk_evm_abstractions/src/precompiles/secp256r1_verify.rs b/crates/zk_evm_abstractions/src/precompiles/secp256r1_verify.rs new file mode 100644 index 0000000..5e1abb0 --- /dev/null +++ b/crates/zk_evm_abstractions/src/precompiles/secp256r1_verify.rs @@ -0,0 +1,308 @@ +use zkevm_opcode_defs::{ethereum_types::U256, p256}; + +use super::*; + +// we need hash, r, s, x, y +pub const MEMORY_READS_PER_CYCLE: usize = 5; +pub const MEMORY_WRITES_PER_CYCLE: usize = 2; + +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct Secp256r1VerifyRoundWitness { + pub new_request: LogQuery, + pub reads: [MemoryQuery; MEMORY_READS_PER_CYCLE], + pub writes: [MemoryQuery; MEMORY_WRITES_PER_CYCLE], +} + +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub struct Secp256r1VerifyPrecompile; + +impl Precompile for Secp256r1VerifyPrecompile { + type CycleWitness = Secp256r1VerifyRoundWitness; + + fn execute_precompile( + &mut self, + monotonic_cycle_counter: u32, + query: LogQuery, + memory: &mut M, + ) -> ( + usize, + Option<(Vec, Vec, Vec)>, + ) { + const NUM_ROUNDS: usize = 1; + + // read the parameters + let precompile_call_params = query; + let params = precompile_abi_in_log(precompile_call_params); + let timestamp_to_read = precompile_call_params.timestamp; + let timestamp_to_write = Timestamp(timestamp_to_read.0 + 1); // our default timestamping agreement + + let mut current_read_location = MemoryLocation { + memory_type: MemoryType::Heap, // we default for some value, here it's not that important + page: MemoryPage(params.memory_page_to_read), + index: MemoryIndex(params.input_memory_offset), + }; + + // we assume that we have + // - hash of the message + // - r + // - s + // - x + // - y + + // NOTE: we assume system contract to do pre-checks, but anyway catch cases of invalid ranges or point + // not on curve here + + let mut read_history = if B { + Vec::with_capacity(MEMORY_READS_PER_CYCLE) + } else { + vec![] + }; + let mut write_history = if B { + Vec::with_capacity(MEMORY_WRITES_PER_CYCLE) + } else { + vec![] + }; + + let mut round_witness = Secp256r1VerifyRoundWitness { + new_request: precompile_call_params, + reads: [MemoryQuery::empty(); MEMORY_READS_PER_CYCLE], + writes: [MemoryQuery::empty(); MEMORY_WRITES_PER_CYCLE], + }; + + let mut read_idx = 0; + + let hash_query = MemoryQuery { + timestamp: timestamp_to_read, + location: current_read_location, + value: U256::zero(), + value_is_pointer: false, + rw_flag: false, + }; + let hash_query = memory.execute_partial_query(monotonic_cycle_counter, hash_query); + let hash_value = hash_query.value; + if B { + round_witness.reads[read_idx] = hash_query; + read_idx += 1; + read_history.push(hash_query); + } + + current_read_location.index.0 += 1; + let r_query = MemoryQuery { + timestamp: timestamp_to_read, + location: current_read_location, + value: U256::zero(), + value_is_pointer: false, + rw_flag: false, + }; + let r_query = memory.execute_partial_query(monotonic_cycle_counter, r_query); + let r_value = r_query.value; + if B { + round_witness.reads[read_idx] = r_query; + read_idx += 1; + read_history.push(r_query); + } + + current_read_location.index.0 += 1; + let s_query = MemoryQuery { + timestamp: timestamp_to_read, + location: current_read_location, + value: U256::zero(), + value_is_pointer: false, + rw_flag: false, + }; + let s_query = memory.execute_partial_query(monotonic_cycle_counter, s_query); + let s_value = s_query.value; + if B { + round_witness.reads[read_idx] = s_query; + read_idx += 1; + read_history.push(s_query); + } + + current_read_location.index.0 += 1; + let x_query = MemoryQuery { + timestamp: timestamp_to_read, + location: current_read_location, + value: U256::zero(), + value_is_pointer: false, + rw_flag: false, + }; + let x_query = memory.execute_partial_query(monotonic_cycle_counter, x_query); + let x_value = x_query.value; + if B { + round_witness.reads[read_idx] = x_query; + read_idx += 1; + read_history.push(x_query); + } + + current_read_location.index.0 += 1; + let y_query = MemoryQuery { + timestamp: timestamp_to_read, + location: current_read_location, + value: U256::zero(), + value_is_pointer: false, + rw_flag: false, + }; + let y_query = memory.execute_partial_query(monotonic_cycle_counter, y_query); + let y_value = y_query.value; + if B { + round_witness.reads[read_idx] = y_query; + // read_idx += 1; + read_history.push(y_query); + } + + // read everything as bytes for ecrecover purposes + + let mut buffer = [0u8; 32]; + hash_value.to_big_endian(&mut buffer[..]); + let hash = buffer; + + r_value.to_big_endian(&mut buffer[..]); + let r_bytes = buffer; + + s_value.to_big_endian(&mut buffer[..]); + let s_bytes = buffer; + + x_value.to_big_endian(&mut buffer[..]); + let x_bytes = buffer; + + y_value.to_big_endian(&mut buffer[..]); + let y_bytes = buffer; + + let result = secp256r1_verify_inner(&hash, &r_bytes, &s_bytes, &x_bytes, &y_bytes); + + if let Ok(is_valid) = result { + let mut write_location = MemoryLocation { + memory_type: MemoryType::Heap, // we default for some value, here it's not that important + page: MemoryPage(params.memory_page_to_write), + index: MemoryIndex(params.output_memory_offset), + }; + + let ok_marker = U256::one(); + let ok_or_err_query = MemoryQuery { + timestamp: timestamp_to_write, + location: write_location, + value: ok_marker, + value_is_pointer: false, + rw_flag: true, + }; + let ok_or_err_query = + memory.execute_partial_query(monotonic_cycle_counter, ok_or_err_query); + + write_location.index.0 += 1; + let result = U256::from(is_valid as u64); + let result_query = MemoryQuery { + timestamp: timestamp_to_write, + location: write_location, + value: result, + value_is_pointer: false, + rw_flag: true, + }; + let result_query = memory.execute_partial_query(monotonic_cycle_counter, result_query); + + if B { + round_witness.writes[0] = ok_or_err_query; + round_witness.writes[1] = result_query; + write_history.push(ok_or_err_query); + write_history.push(result_query); + } + } else { + let mut write_location = MemoryLocation { + memory_type: MemoryType::Heap, // we default for some value, here it's not that important + page: MemoryPage(params.memory_page_to_write), + index: MemoryIndex(params.output_memory_offset), + }; + + let err_marker = U256::zero(); + let ok_or_err_query = MemoryQuery { + timestamp: timestamp_to_write, + location: write_location, + value: err_marker, + value_is_pointer: false, + rw_flag: true, + }; + let ok_or_err_query = + memory.execute_partial_query(monotonic_cycle_counter, ok_or_err_query); + + write_location.index.0 += 1; + let empty_result = U256::zero(); + let result_query = MemoryQuery { + timestamp: timestamp_to_write, + location: write_location, + value: empty_result, + value_is_pointer: false, + rw_flag: true, + }; + let result_query = memory.execute_partial_query(monotonic_cycle_counter, result_query); + + if B { + round_witness.writes[0] = ok_or_err_query; + round_witness.writes[1] = result_query; + write_history.push(ok_or_err_query); + write_history.push(result_query); + } + } + + let witness = if B { + Some((read_history, write_history, vec![round_witness])) + } else { + None + }; + + (NUM_ROUNDS, witness) + } +} + +pub fn secp256r1_verify_inner( + digest: &[u8; 32], + r: &[u8; 32], + s: &[u8; 32], + x: &[u8; 32], + y: &[u8; 32], +) -> Result { + use p256::ecdsa::signature::hazmat::PrehashVerifier; + use p256::ecdsa::{Signature, VerifyingKey}; + use p256::elliptic_curve::generic_array::GenericArray; + use p256::elliptic_curve::sec1::FromEncodedPoint; + use p256::{AffinePoint, EncodedPoint}; + + // we expect pre-validation, so this check always works + let signature = Signature::from_scalars( + GenericArray::clone_from_slice(r), + GenericArray::clone_from_slice(s), + ) + .map_err(|_| ())?; + + let encoded_pk = EncodedPoint::from_affine_coordinates( + &GenericArray::clone_from_slice(x), + &GenericArray::clone_from_slice(y), + false, + ); + + let may_be_pk_point = AffinePoint::from_encoded_point(&encoded_pk); + if bool::from(may_be_pk_point.is_none()) { + return Err(()); + } + let pk_point = may_be_pk_point.unwrap(); + + let verifier = VerifyingKey::from_affine(pk_point).map_err(|_| ())?; + + let result = verifier.verify_prehash(digest, &signature); + + Ok(result.is_ok()) +} + +pub fn secp256r1_verify_function( + monotonic_cycle_counter: u32, + precompile_call_params: LogQuery, + memory: &mut M, +) -> ( + usize, + Option<( + Vec, + Vec, + Vec, + )>, +) { + let mut processor = Secp256r1VerifyPrecompile::; + processor.execute_precompile(monotonic_cycle_counter, precompile_call_params, memory) +} diff --git a/crates/zk_evm_abstractions/src/precompiles/sha256.rs b/crates/zk_evm_abstractions/src/precompiles/sha256.rs index 8ed991d..1113935 100644 --- a/crates/zk_evm_abstractions/src/precompiles/sha256.rs +++ b/crates/zk_evm_abstractions/src/precompiles/sha256.rs @@ -188,8 +188,6 @@ struct Sha256VarCore { _block_len: u64, } -static_assertions::assert_eq_size!(Sha256, CoreWrapper); - pub fn transmute_state(reference_state: Sha256) -> Sha256InnerState { // we use a trick that size of both structures is the same, and even though we do not know a stable field layout, // we can replicate it diff --git a/crates/zk_evm_abstractions/src/queries.rs b/crates/zk_evm_abstractions/src/queries.rs index 0f03810..8c171fc 100644 --- a/crates/zk_evm_abstractions/src/queries.rs +++ b/crates/zk_evm_abstractions/src/queries.rs @@ -1,6 +1,7 @@ use zkevm_opcode_defs::{ blake2, ethereum_types::{Address, U256}, + VersionedHashHeader, VersionedHashNormalizedPreimage, }; use crate::aux::{MemoryLocation, MemoryPage, Timestamp}; @@ -69,7 +70,8 @@ impl LogQuery { #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)] pub struct DecommittmentQuery { - pub hash: U256, + pub header: VersionedHashHeader, + pub normalized_preimage: VersionedHashNormalizedPreimage, pub timestamp: Timestamp, pub memory_page: MemoryPage, pub decommitted_length: u16, diff --git a/crates/zk_evm_abstractions/src/vm.rs b/crates/zk_evm_abstractions/src/vm.rs index 7fd7ab1..d2153c8 100644 --- a/crates/zk_evm_abstractions/src/vm.rs +++ b/crates/zk_evm_abstractions/src/vm.rs @@ -1,9 +1,13 @@ -use zkevm_opcode_defs::{ethereum_types::U256, FatPointer}; +use zkevm_opcode_defs::{ + ethereum_types::{Address, U256}, + FatPointer, +}; use crate::{ - aux::{MemoryPage, Timestamp}, + aux::{MemoryPage, PubdataCost, Timestamp}, precompiles::{ - ecrecover::ECRecoverPrecompile, keccak256::Keccak256Precompile, sha256::Sha256Precompile, + ecrecover::ECRecoverPrecompile, keccak256::Keccak256Precompile, + secp256r1_verify::Secp256r1VerifyPrecompile, sha256::Sha256Precompile, }, queries::{DecommittmentQuery, LogQuery, MemoryQuery}, }; @@ -19,38 +23,32 @@ pub enum MemoryType { Heap, AuxHeap, FatPointer, + StaticMemory, } impl MemoryType { pub const fn page_size_limit(&self) -> usize { match self { MemoryType::Stack | MemoryType::Code => MEMORY_CELLS_STACK_OR_CODE_PAGE, - MemoryType::Heap | MemoryType::AuxHeap | MemoryType::FatPointer => u32::MAX as usize, + MemoryType::Heap + | MemoryType::AuxHeap + | MemoryType::FatPointer + | MemoryType::StaticMemory => u32::MAX as usize, } } } #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -pub struct RefundedAmounts { - pub pubdata_bytes: u32, - pub ergs: u32, -} - -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -pub enum RefundType { - None, - RepeatedRead(RefundedAmounts), - RepeatedWrite(RefundedAmounts), - RevertToOriginalInFrame(RefundedAmounts), +pub enum StorageAccessRefund { + Cold, + Warm { ergs: u32 }, } -impl RefundType { - pub const fn pubdata_refund(&self) -> u32 { +impl StorageAccessRefund { + pub const fn refund(&self) -> u32 { match self { - RefundType::None => 0, - RefundType::RepeatedRead(amounts) => amounts.pubdata_bytes, - RefundType::RepeatedWrite(amounts) => amounts.pubdata_bytes, - RefundType::RevertToOriginalInFrame(amounts) => amounts.pubdata_bytes, + StorageAccessRefund::Cold => 0, + StorageAccessRefund::Warm { ergs } => *ergs, } } } @@ -60,6 +58,7 @@ pub enum PrecompileCyclesWitness { Sha256(Vec< as Precompile>::CycleWitness>), Keccak256(Vec< as Precompile>::CycleWitness>), ECRecover(Vec< as Precompile>::CycleWitness>), + Secp256r1Verify(Vec< as Precompile>::CycleWitness>), } // ALL traits here are for execution and NOT for witness generation. They can depend on one another, but should @@ -72,24 +71,27 @@ pub enum PrecompileCyclesWitness { pub trait Storage: std::fmt::Debug { // We can evaluate a query cost (or more precisely - get expected refunds) // before actually executing query - fn estimate_refunds_for_write( + fn get_access_refund( &mut self, // to avoid any hacks inside, like prefetch monotonic_cycle_counter: u32, partial_query: &LogQuery, - ) -> RefundType; + ) -> StorageAccessRefund; // Perform a storage read/write access by taking an partially filled query // and returning filled query and cold/warm marker for pricing purposes - fn execute_partial_query(&mut self, monotonic_cycle_counter: u32, query: LogQuery) -> LogQuery; + fn execute_partial_query( + &mut self, + monotonic_cycle_counter: u32, + query: LogQuery, + ) -> (LogQuery, PubdataCost); // Indicate a start of execution frame for rollback purposes fn start_frame(&mut self, timestamp: Timestamp); // Indicate that execution frame went out from the scope, so we can // log the history and either rollback immediately or keep records to rollback later fn finish_frame(&mut self, timestamp: Timestamp, panicked: bool); - // N.B. We may need to extend frame markers for e.g. special bootloader execution frame - // such that we can flush all the changes of particular transaction since bootloader doesn't - // rollback further (at least now) + // And as we support transient store we need to inform that new tx has started + fn start_new_tx(&mut self, timestamp: Timestamp); } pub trait Memory: std::fmt::Debug { @@ -120,6 +122,7 @@ pub trait Memory: std::fmt::Debug { fn finish_global_frame( &mut self, _page_page: MemoryPage, + _last_callstack_this: Address, _returndata_fat_pointer: FatPointer, _timestamp: Timestamp, ) { @@ -177,12 +180,18 @@ pub trait DecommittmentProcessor: std::fmt::Debug { // already filled page if we decommit the same hash. // We also optinally return a set of memory writes that such decommitment has made (if it's a new page) // for witness generation at the end of the block + fn prepare_to_decommit( + &mut self, + monotonic_cycle_counter: u32, + partial_query: DecommittmentQuery, + ) -> anyhow::Result; + fn decommit_into_memory( &mut self, monotonic_cycle_counter: u32, partial_query: DecommittmentQuery, memory: &mut M, - ) -> anyhow::Result<(DecommittmentQuery, Option>)>; + ) -> anyhow::Result>>; } /// Abstraction over precompile implementation. Precompile is usually a closure-forming FSM, so it must output @@ -205,12 +214,3 @@ pub trait Precompile: std::fmt::Debug { Option<(Vec, Vec, Vec)>, ); } - -pub enum SpongeExecutionMarker { - MemoryQuery, - DecommittmentQuery, - StorageLogReadOnly, - StorageLogWrite, - CallstackPush, - CallstackPop, -} diff --git a/crates/zkevm_circuits/.github/workflows/ci.yaml b/crates/zkevm_circuits/.github/workflows/ci.yaml index 401d548..4a6e609 100644 --- a/crates/zkevm_circuits/.github/workflows/ci.yaml +++ b/crates/zkevm_circuits/.github/workflows/ci.yaml @@ -9,9 +9,6 @@ jobs: steps: - uses: actions/checkout@v3 - uses: actions-rust-lang/setup-rust-toolchain@v1 - with: - toolchain: nightly-2023-09-20 - rustflags: "" - run: cargo build --verbose --release - run: cargo test --verbose --release --all -- --test-threads=1 diff --git a/crates/zkevm_circuits/Cargo.toml b/crates/zkevm_circuits/Cargo.toml index c19d0db..4c28946 100644 --- a/crates/zkevm_circuits/Cargo.toml +++ b/crates/zkevm_circuits/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zkevm_circuits" -version = "0.141.1" +version = "0.150.3" edition = "2021" authors = ["The Matter Labs Team "] homepage = "https://zksync.io/" @@ -22,16 +22,14 @@ smallvec = { version = "1.13", features = [ "serde", ] } arrayvec = "0.7" -bincode = "1.3" -serde_json = "1" itertools = "0.10" rand_new = { package = "rand", version = "0.8" } hex = "0.4" seq-macro = "0.3" -zkevm_opcode_defs = { version = "=0.141.0", path = "../zkevm_opcode_defs" } -boojum = "0" -cs_derive = "0" +zkevm_opcode_defs = { version = "=0.150.0", path = "../zkevm_opcode_defs" } +cs_derive = "=0.2.2" +boojum = "=0.2.2" [features] default = [] diff --git a/crates/zkevm_circuits/rust-toolchain.toml b/crates/zkevm_circuits/rust-toolchain.toml index a671fa6..842bc49 100644 --- a/crates/zkevm_circuits/rust-toolchain.toml +++ b/crates/zkevm_circuits/rust-toolchain.toml @@ -1,2 +1,3 @@ [toolchain] -channel = "nightly-2024-05-07" +# channel = "nightly" +channel = "nightly-2024-08-01" diff --git a/crates/zkevm_circuits/src/base_structures/decommit_query/mod.rs b/crates/zkevm_circuits/src/base_structures/decommit_query/mod.rs index affabdd..4a25da2 100644 --- a/crates/zkevm_circuits/src/base_structures/decommit_query/mod.rs +++ b/crates/zkevm_circuits/src/base_structures/decommit_query/mod.rs @@ -11,13 +11,21 @@ use boojum::gadgets::traits::allocatable::CSPlaceholder; use boojum::gadgets::traits::allocatable::{CSAllocatable, CSAllocatableExt}; use boojum::gadgets::traits::castable::WitnessCastable; use boojum::gadgets::traits::encodable::CircuitVarLengthEncodable; +use boojum::gadgets::traits::encodable::WitnessVarLengthEncodable; use boojum::gadgets::traits::encodable::{CircuitEncodable, CircuitEncodableExt}; use boojum::gadgets::traits::selectable::Selectable; use boojum::gadgets::traits::witnessable::WitnessHookable; use boojum::gadgets::u32::UInt32; use boojum::{field::SmallField, gadgets::u256::UInt256}; -#[derive(Derivative, CSAllocatable, CSSelectable, WitnessHookable, CSVarLengthEncodable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + WitnessHookable, + CSVarLengthEncodable, + WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug)] pub struct DecommitQuery { pub code_hash: UInt256, diff --git a/crates/zkevm_circuits/src/base_structures/log_query/mod.rs b/crates/zkevm_circuits/src/base_structures/log_query/mod.rs index 4d42995..72b8c2d 100644 --- a/crates/zkevm_circuits/src/base_structures/log_query/mod.rs +++ b/crates/zkevm_circuits/src/base_structures/log_query/mod.rs @@ -9,7 +9,9 @@ use boojum::gadgets::traits::allocatable::CSPlaceholder; use boojum::gadgets::traits::allocatable::{CSAllocatable, CSAllocatableExt}; use boojum::gadgets::traits::castable::WitnessCastable; use boojum::gadgets::traits::encodable::CircuitEncodableExt; -use boojum::gadgets::traits::encodable::{CircuitEncodable, CircuitVarLengthEncodable}; +use boojum::gadgets::traits::encodable::{ + CircuitEncodable, CircuitVarLengthEncodable, WitnessVarLengthEncodable, +}; use boojum::gadgets::traits::selectable::Selectable; use boojum::gadgets::traits::witnessable::WitnessHookable; use boojum::gadgets::u160::{recompose_address_from_u32x5, UInt160}; @@ -18,7 +20,14 @@ use boojum::gadgets::u32::UInt32; use boojum::gadgets::u8::UInt8; use cs_derive::*; -#[derive(Derivative, CSAllocatable, CSSelectable, WitnessHookable, CSVarLengthEncodable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + WitnessHookable, + CSVarLengthEncodable, + WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug, Hash)] pub struct LogQuery { pub address: UInt160, diff --git a/crates/zkevm_circuits/src/base_structures/precompile_input_outputs/mod.rs b/crates/zkevm_circuits/src/base_structures/precompile_input_outputs/mod.rs index cc31420..b13bd20 100644 --- a/crates/zkevm_circuits/src/base_structures/precompile_input_outputs/mod.rs +++ b/crates/zkevm_circuits/src/base_structures/precompile_input_outputs/mod.rs @@ -13,11 +13,19 @@ use boojum::gadgets::traits::allocatable::CSAllocatable; use boojum::gadgets::traits::allocatable::CSPlaceholder; use boojum::gadgets::traits::auxiliary::PrettyComparison; use boojum::gadgets::traits::encodable::CircuitVarLengthEncodable; +use boojum::gadgets::traits::encodable::WitnessVarLengthEncodable; use boojum::gadgets::traits::selectable::Selectable; use boojum::gadgets::traits::witnessable::WitnessHookable; use cs_derive::*; -#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug)] #[DerivePrettyComparison("true")] pub struct PrecompileFunctionInputData { @@ -36,7 +44,14 @@ impl CSPlaceholder for PrecompileFunctionInputData { } } -#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug)] #[DerivePrettyComparison("true")] pub struct PrecompileFunctionOutputData { diff --git a/crates/zkevm_circuits/src/base_structures/register/mod.rs b/crates/zkevm_circuits/src/base_structures/register/mod.rs index 780e1c1..c7bc681 100644 --- a/crates/zkevm_circuits/src/base_structures/register/mod.rs +++ b/crates/zkevm_circuits/src/base_structures/register/mod.rs @@ -11,12 +11,20 @@ use boojum::cs::traits::cs::DstBuffer; use boojum::cs::Variable; use boojum::gadgets::traits::allocatable::{CSAllocatable, CSAllocatableExt}; use boojum::gadgets::traits::encodable::CircuitVarLengthEncodable; +use boojum::gadgets::traits::encodable::WitnessVarLengthEncodable; use boojum::gadgets::traits::selectable::Selectable; use boojum::gadgets::traits::witnessable::WitnessHookable; use cs_derive::*; -#[derive(Derivative, CSSelectable, CSAllocatable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSSelectable, + CSAllocatable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug, Hash)] pub struct VMRegister { pub is_pointer: Boolean, diff --git a/crates/zkevm_circuits/src/base_structures/vm_state/callstack.rs b/crates/zkevm_circuits/src/base_structures/vm_state/callstack.rs index 4ab9ac9..c142be4 100644 --- a/crates/zkevm_circuits/src/base_structures/vm_state/callstack.rs +++ b/crates/zkevm_circuits/src/base_structures/vm_state/callstack.rs @@ -1,7 +1,14 @@ use super::*; use boojum::serde_utils::BigArraySerde; -#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug)] #[CSSelectableBound( "where [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:" @@ -40,7 +47,9 @@ use crate::base_structures::vm_state::saved_context::ExecutionContextRecord; // execution context that keeps all explicit data about the current execution frame, // and avoid recomputing of quantities that also do not change between calls -#[derive(Derivative, CSAllocatable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, CSAllocatable, CSVarLengthEncodable, WitnessHookable, WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug)] pub struct FullExecutionContext { pub saved_context: ExecutionContextRecord, diff --git a/crates/zkevm_circuits/src/base_structures/vm_state/mod.rs b/crates/zkevm_circuits/src/base_structures/vm_state/mod.rs index 4147eb0..290f639 100644 --- a/crates/zkevm_circuits/src/base_structures/vm_state/mod.rs +++ b/crates/zkevm_circuits/src/base_structures/vm_state/mod.rs @@ -9,6 +9,7 @@ use boojum::gadgets::num::Num; use boojum::gadgets::traits::allocatable::*; use boojum::gadgets::traits::auxiliary::PrettyComparison; use boojum::gadgets::traits::encodable::CircuitVarLengthEncodable; +use boojum::gadgets::traits::encodable::WitnessVarLengthEncodable; use boojum::gadgets::traits::selectable::*; use boojum::gadgets::traits::witnessable::WitnessHookable; use boojum::gadgets::u16::UInt16; @@ -27,9 +28,11 @@ use crate::base_structures::vm_state::callstack::Callstack; pub const FULL_SPONGE_QUEUE_STATE_WIDTH: usize = 12; pub const QUEUE_STATE_WIDTH: usize = 4; -pub(crate) const REGISTERS_COUNT: usize = 15; +use zkevm_opcode_defs::REGISTERS_COUNT; -#[derive(Derivative, CSAllocatable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, CSAllocatable, CSVarLengthEncodable, WitnessHookable, WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug)] pub struct ArithmeticFlagsPort { pub overflow_or_less_than: Boolean, @@ -83,7 +86,14 @@ impl ArithmeticFlagsPort { } } -#[derive(Derivative, CSSelectable, CSAllocatable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSSelectable, + CSAllocatable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug)] #[CSSelectableBound( "where [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:" @@ -99,7 +109,8 @@ pub struct VmLocalState { pub previous_code_page: UInt32, pub previous_super_pc: UInt16, pub pending_exception: Boolean, - pub ergs_per_pubdata_byte: UInt32, + // pub ergs_per_pubdata_byte: UInt32, + pub pubdata_revert_counter: UInt32, // actually signed pub callstack: Callstack, pub memory_queue_state: [Num; FULL_SPONGE_QUEUE_STATE_WIDTH], pub memory_queue_length: UInt32, @@ -135,7 +146,7 @@ impl VmLocalState { previous_code_page: zero_u32, previous_super_pc: zero_u16, pending_exception: boolean_false, - ergs_per_pubdata_byte: zero_u32, + pubdata_revert_counter: zero_u32, callstack, memory_queue_state: [zero_num; FULL_SPONGE_QUEUE_STATE_WIDTH], memory_queue_length: zero_u32, @@ -152,11 +163,19 @@ impl CSPlaceholder for VmLocalState { } } -#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug)] pub struct GlobalContext { pub zkporter_is_available: Boolean, pub default_aa_code_hash: UInt256, + pub evm_simulator_code_hash: UInt256, } impl CSPlaceholder for GlobalContext { @@ -166,6 +185,7 @@ impl CSPlaceholder for GlobalContext { Self { zkporter_is_available: boolean_false, default_aa_code_hash: zero_u256, + evm_simulator_code_hash: zero_u256, } } } diff --git a/crates/zkevm_circuits/src/base_structures/vm_state/saved_context.rs b/crates/zkevm_circuits/src/base_structures/vm_state/saved_context.rs index f51071a..57f2216 100644 --- a/crates/zkevm_circuits/src/base_structures/vm_state/saved_context.rs +++ b/crates/zkevm_circuits/src/base_structures/vm_state/saved_context.rs @@ -4,6 +4,7 @@ use boojum::cs::Variable; use boojum::gadgets::traits::allocatable::CSAllocatableExt; use boojum::gadgets::traits::castable::WitnessCastable; use boojum::gadgets::traits::encodable::CircuitEncodable; +use boojum::gadgets::traits::encodable::WitnessVarLengthEncodable; use boojum::gadgets::traits::selectable::parallel_select_variables; use cs_derive::*; use ethereum_types::Address; @@ -31,7 +32,9 @@ use super::*; // - per-context computed rollback segment length // - per-context rollback_head -#[derive(Derivative, CSAllocatable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, CSAllocatable, CSVarLengthEncodable, WitnessHookable, WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug)] pub struct ExecutionContextRecord { pub this: UInt160, // unfortunately delegatecall mangles this field - it can not be restored from callee's caller @@ -63,6 +66,10 @@ pub struct ExecutionContextRecord { pub context_u128_value_composite: [UInt32; 4], pub is_local_call: Boolean, + + pub total_pubdata_spent: UInt32, // actually signed two-complement + + pub stipend: UInt32, } impl ExecutionContextRecord { @@ -102,11 +109,15 @@ impl ExecutionContextRecord { context_u128_value_composite: [zero_u32; 4], is_local_call: boolean_false, + + total_pubdata_spent: zero_u32, + + stipend: zero_u32, } } } -pub const EXECUTION_CONTEXT_RECORD_ENCODING_WIDTH: usize = 32; +pub const EXECUTION_CONTEXT_RECORD_ENCODING_WIDTH: usize = 40; impl CircuitEncodable for ExecutionContextRecord @@ -159,116 +170,80 @@ impl CircuitEncodable // - sp // - pc // - eh + // - pubdata counter + // - stipend counter // - reverted_queue_segment_len // - shard ids // - few boolean flags - // as usual, take u32 and add something on top + let v27 = self.code_page.get_variable(); + let v28 = self.base_page.get_variable(); + let v29 = self.heap_upper_bound.get_variable(); + let v30 = self.aux_heap_upper_bound.get_variable(); - let v27 = Num::linear_combination( - cs, - &[ - (self.code_page.get_variable(), F::ONE), - (self.pc.get_variable(), F::from_u64_unchecked(1u64 << 32)), - ( - self.this_shard_id.get_variable(), - F::from_u64_unchecked(1u64 << 48), - ), - ( - self.is_static_execution.get_variable(), - F::from_u64_unchecked(1u64 << 56), - ), - ], - ) - .get_variable(); + let v31 = self.ergs_remaining.get_variable(); + let v32 = self.total_pubdata_spent.get_variable(); + let v33 = self.stipend.get_variable(); + let v34 = self.reverted_queue_segment_len.get_variable(); - let v28 = Num::linear_combination( - cs, - &[ - (self.base_page.get_variable(), F::ONE), - (self.sp.get_variable(), F::from_u64_unchecked(1u64 << 32)), - ( - self.caller_shard_id.get_variable(), - F::from_u64_unchecked(1u64 << 48), - ), - ( - self.is_kernel_mode.get_variable(), - F::from_u64_unchecked(1u64 << 56), - ), - ], - ) - .get_variable(); + // and now we can just pack the rest into 5 variables + // - sp + // - pc + // - eh + // - shard ids + // - few boolean flags - let v29 = Num::linear_combination( + let v35 = self.sp.get_variable(); + let v36 = self.pc.get_variable(); + let v37 = self.exception_handler_loc.get_variable(); + // pack shard IDs + let v38 = Num::linear_combination( cs, &[ - (self.ergs_remaining.get_variable(), F::ONE), - ( - self.exception_handler_loc.get_variable(), - F::from_u64_unchecked(1u64 << 32), - ), + (self.this_shard_id.get_variable(), F::ONE), ( self.code_shard_id.get_variable(), - F::from_u64_unchecked(1u64 << 48), + F::from_u64_unchecked(1u64 << 8), ), ( - self.is_local_call.get_variable(), - F::from_u64_unchecked(1u64 << 56), - ), - ], - ) - .get_variable(); - - // now we have left - // - heap_upper_bound - // - aux_heap_upper_bound - // - reverted_queue_segment_len - - let reverted_queue_segment_len_decomposition = - self.reverted_queue_segment_len.decompose_into_bytes(cs); - let v30 = Num::linear_combination( - cs, - &[ - (self.heap_upper_bound.get_variable(), F::ONE), - ( - reverted_queue_segment_len_decomposition[0].get_variable(), - F::from_u64_unchecked(1u64 << 32), - ), - ( - reverted_queue_segment_len_decomposition[1].get_variable(), - F::from_u64_unchecked(1u64 << 40), + self.caller_shard_id.get_variable(), + F::from_u64_unchecked(1u64 << 16), ), ], ) .get_variable(); - let v31 = Num::linear_combination( + // pack boolean flags + let v39 = Num::linear_combination( cs, &[ - (self.aux_heap_upper_bound.get_variable(), F::ONE), + (self.is_static_execution.get_variable(), F::ONE), ( - reverted_queue_segment_len_decomposition[2].get_variable(), - F::from_u64_unchecked(1u64 << 32), + self.is_kernel_mode.get_variable(), + F::from_u64_unchecked(1u64 << 8), ), ( - reverted_queue_segment_len_decomposition[3].get_variable(), - F::from_u64_unchecked(1u64 << 40), + self.is_local_call.get_variable(), + F::from_u64_unchecked(1u64 << 16), ), ], ) .get_variable(); - [ + let encoding = [ v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, - v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, - ] + v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, + v36, v37, v38, v39, + ]; + + encoding } } // we also need allocate extended impl CSAllocatableExt for ExecutionContextRecord { - const INTERNAL_STRUCT_LEN: usize = 42; + const INTERNAL_STRUCT_LEN: usize = 44; fn create_without_value>(cs: &mut CS) -> Self { // TODO: use more optimal allocation for bytes @@ -319,6 +294,8 @@ impl CSAllocatableExt for ExecutionContextRecord { self.context_u128_value_composite[2].get_variable(), self.context_u128_value_composite[3].get_variable(), self.is_local_call.get_variable(), + self.total_pubdata_spent.get_variable(), + self.stipend.get_variable(), ] } @@ -381,6 +358,10 @@ impl CSAllocatableExt for ExecutionContextRecord { .map(|el| UInt32::from_variable_unchecked(el)), is_local_call: Boolean::from_variable_unchecked(variables[41]), + + total_pubdata_spent: UInt32::from_variable_unchecked(variables[42]), + + stipend: UInt32::from_variable_unchecked(variables[43]), } } } @@ -428,6 +409,12 @@ impl CSAllocatableExt for ExecutionContextRecord { )); dst.push(WitnessCastable::cast_into_source(witness.is_local_call)); + + dst.push(WitnessCastable::cast_into_source( + witness.total_pubdata_spent, + )); + + dst.push(WitnessCastable::cast_into_source(witness.stipend)); } fn witness_from_set_of_values(values: [F; Self::INTERNAL_STRUCT_LEN]) -> Self::Witness { @@ -473,6 +460,10 @@ impl CSAllocatableExt for ExecutionContextRecord { let is_local_call: bool = WitnessCastable::cast_from_source(values[41]); + let total_pubdata_spent = WitnessCastable::cast_from_source(values[42]); + + let stipend = WitnessCastable::cast_from_source(values[43]); + Self::Witness { this, caller, @@ -503,6 +494,10 @@ impl CSAllocatableExt for ExecutionContextRecord { context_u128_value_composite, is_local_call, + + total_pubdata_spent, + + stipend, } } } diff --git a/crates/zkevm_circuits/src/code_unpacker_sha256/input.rs b/crates/zkevm_circuits/src/code_unpacker_sha256/input.rs index 51148cd..e0e2b8c 100644 --- a/crates/zkevm_circuits/src/code_unpacker_sha256/input.rs +++ b/crates/zkevm_circuits/src/code_unpacker_sha256/input.rs @@ -7,8 +7,8 @@ use boojum::gadgets::{ boolean::Boolean, queue::*, traits::{ - allocatable::*, encodable::CircuitVarLengthEncodable, selectable::Selectable, - witnessable::WitnessHookable, + allocatable::*, encodable::CircuitVarLengthEncodable, encodable::WitnessVarLengthEncodable, + selectable::Selectable, witnessable::WitnessHookable, }, u16::UInt16, u256::UInt256, @@ -18,7 +18,14 @@ use boojum::serde_utils::BigArraySerde; use cs_derive::*; use derivative::*; -#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug)] pub struct CodeDecommittmentFSM { pub sha256_inner_state: [UInt32; 8], // 8 uint32 words of internal sha256 state @@ -26,8 +33,7 @@ pub struct CodeDecommittmentFSM { pub current_index: UInt32, pub current_page: UInt32, pub timestamp: UInt32, - pub num_rounds_left: UInt16, - pub length_in_bits: UInt32, + pub num_byte32_words_processed: UInt16, pub state_get_from_queue: Boolean, pub state_decommit: Boolean, pub finished: Boolean, @@ -46,8 +52,7 @@ impl CSPlaceholder for CodeDecommittmentFSM { current_index: zero_uint32, current_page: zero_uint32, timestamp: zero_uint32, - num_rounds_left: zero_uint16, - length_in_bits: zero_uint32, + num_byte32_words_processed: zero_uint16, state_get_from_queue: bool_false, state_decommit: bool_false, finished: bool_false, @@ -55,7 +60,14 @@ impl CSPlaceholder for CodeDecommittmentFSM { } } -#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug)] #[DerivePrettyComparison("true")] pub struct CodeDecommitterFSMInputOutput { @@ -75,7 +87,14 @@ impl CSPlaceholder for CodeDecommitterFSMInputOutput { } } -#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug)] pub struct CodeDecommitterInputData { pub memory_queue_initial_state: QueueState, @@ -94,7 +113,14 @@ impl CSPlaceholder for CodeDecommitterInputData { } } -#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug)] #[DerivePrettyComparison("true")] pub struct CodeDecommitterOutputData { diff --git a/crates/zkevm_circuits/src/code_unpacker_sha256/mod.rs b/crates/zkevm_circuits/src/code_unpacker_sha256/mod.rs index 2be44fd..8e8a95e 100644 --- a/crates/zkevm_circuits/src/code_unpacker_sha256/mod.rs +++ b/crates/zkevm_circuits/src/code_unpacker_sha256/mod.rs @@ -3,10 +3,14 @@ pub mod input; use input::*; use crate::ethereum_types::U256; +use boojum::config::*; +use boojum::cs::traits::cs::DstBuffer; +use boojum::cs::Place; +use boojum::cs::Variable; +use boojum::gadgets::traits::castable::WitnessCastable; use std::collections::VecDeque; use std::sync::{Arc, RwLock}; -use crate::base_structures::vm_state::FULL_SPONGE_QUEUE_STATE_WIDTH; use crate::base_structures::{decommit_query::*, memory_query::*}; use boojum::algebraic_props::round_function::AlgebraicRoundFunction; use boojum::cs::{gates::*, traits::cs::ConstraintSystem}; @@ -28,7 +32,217 @@ use boojum::gadgets::{ use crate::fsm_input_output::{circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH, *}; -use crate::storage_application::ConditionalWitnessAllocator; +// Similar to ConditionalWitnessAllocator, but has a logical separation of sequences, +// so if a sub-sequence ended it can also allocate a boolean to indicate it by providing boolean value +pub struct ConditionalWitnessSetAllocator> { + witness_source: Arc>>>, +} + +impl> ConditionalWitnessSetAllocator +where + [(); EL::INTERNAL_STRUCT_LEN]:, + [(); EL::INTERNAL_STRUCT_LEN + 1]:, +{ + pub fn new( + mut sequences: VecDeque>, + first_subsequence_is_continuation: bool, + ) -> Self { + if first_subsequence_is_continuation == false { + // we would need to pre-pad to avoid tracking skipping first "start new sequence" + sequences.push_front(VecDeque::new()); + } + + Self { + witness_source: Arc::new(RwLock::new(sequences)), + } + } + + pub fn new_uninterpreted(sequences: VecDeque>) -> Self { + Self { + witness_source: Arc::new(RwLock::new(sequences)), + } + } + + pub fn print_debug_info(&self) { + if let Ok(read_lock) = self.witness_source.read() { + let inner = &*read_lock; + dbg!(inner.len()); + } + } + + pub fn conditionally_allocate_with_default< + CS: ConstraintSystem, + DEF: FnOnce() -> EL::Witness + 'static + Send + Sync, + >( + &self, + cs: &mut CS, + should_allocate: Boolean, + should_start_new: Boolean, + default_values_closure: DEF, + ) -> (Boolean, EL) { + let sequence_is_empty = Boolean::allocate_without_value(cs); + let el = EL::allocate_without_value(cs); + + if ::WitnessConfig::EVALUATE_WITNESS { + let dependencies = [ + should_allocate.get_variable().into(), + should_start_new.get_variable().into(), + ]; + let witness = self.witness_source.clone(); + let value_fn = move |inputs: [F; 2]| { + let should_allocate = >::cast_from_source(inputs[0]); + let should_start_new = >::cast_from_source(inputs[1]); + + let (sequence_is_empty, witness) = if should_allocate == true { + let mut guard = witness.write().expect("not poisoned"); + if should_start_new == true { + // pop the previous sequence + let previous_sequence = guard + .pop_front() + .expect("not empty witness should have previous sequence"); + assert!( + previous_sequence.is_empty(), + "if we start new we must have previous sequence completed" + ); + } + let sequence = guard.get_mut(0).expect("not empty witness"); + if let Some(witness_element) = sequence.pop_front() { + (false, witness_element) + } else { + (true, (default_values_closure)()) + } + } else { + let witness_element = (default_values_closure)(); + + // can return anything for witness, and we decide that we return `false` + (false, witness_element) + }; + + let mut result = [F::ZERO; EL::INTERNAL_STRUCT_LEN + 1]; + result[0] = >::cast_into_source(sequence_is_empty); + let mut dst = DstBuffer::MutSlice(&mut result[1..], 0); + EL::set_internal_variables_values(witness, &mut dst); + drop(dst); + + result + }; + + let mut outputs = [Variable::placeholder(); EL::INTERNAL_STRUCT_LEN + 1]; + outputs[0] = sequence_is_empty.get_variable(); + outputs[1..].copy_from_slice(&el.flatten_as_variables()); + + let outputs = Place::from_variables(outputs); + + cs.set_values_with_dependencies(&dependencies, &outputs, value_fn); + } + + (sequence_is_empty, el) + } + + pub fn conditionally_allocate_with_default_biased< + CS: ConstraintSystem, + DEF: FnOnce() -> EL::Witness + 'static + Send + Sync, + >( + &self, + cs: &mut CS, + should_allocate: Boolean, + should_start_new: Boolean, + bias: Variable, // any variable that has to be resolved BEFORE executing witness query + default_values_closure: DEF, + ) -> (Boolean, EL) { + let sequence_is_empty = Boolean::allocate_without_value(cs); + let el = EL::allocate_without_value(cs); + + if ::WitnessConfig::EVALUATE_WITNESS { + let dependencies = [ + should_allocate.get_variable().into(), + should_start_new.get_variable().into(), + bias.into(), + ]; + let witness = self.witness_source.clone(); + let value_fn = move |inputs: [F; 3]| { + let should_allocate = >::cast_from_source(inputs[0]); + let should_start_new = >::cast_from_source(inputs[1]); + + let (sequence_is_empty, witness) = if should_allocate == true { + let mut guard = witness.write().expect("not poisoned"); + if should_start_new == true { + // pop the previous sequence + let previous_sequence = guard + .pop_front() + .expect("not empty witness should have previous sequence"); + assert!( + previous_sequence.is_empty(), + "if we start new we must have previous sequence completed" + ); + } + let sequence = guard.get_mut(0).expect("not empty witness"); + if let Some(witness_element) = sequence.pop_front() { + (false, witness_element) + } else { + (true, (default_values_closure)()) + } + } else { + let witness_element = (default_values_closure)(); + + // can return anything for witness, and we decide that we return `false` + (false, witness_element) + }; + + let mut result = [F::ZERO; EL::INTERNAL_STRUCT_LEN + 1]; + result[0] = >::cast_into_source(sequence_is_empty); + let mut dst = DstBuffer::MutSlice(&mut result[1..], 0); + EL::set_internal_variables_values(witness, &mut dst); + drop(dst); + + result + }; + + let mut outputs = [Variable::placeholder(); EL::INTERNAL_STRUCT_LEN + 1]; + outputs[0] = sequence_is_empty.get_variable(); + outputs[1..].copy_from_slice(&el.flatten_as_variables()); + + let outputs = Place::from_variables(outputs); + + cs.set_values_with_dependencies(&dependencies, &outputs, value_fn); + } + + (sequence_is_empty, el) + } + + pub fn conditionally_allocate>( + &self, + cs: &mut CS, + should_allocate: Boolean, + should_start_new: Boolean, + ) -> (Boolean, EL) + where + EL::Witness: Default, + { + self.conditionally_allocate_with_default(cs, should_allocate, should_start_new, || { + std::default::Default::default() + }) + } + + pub fn conditionally_allocate_biased>( + &self, + cs: &mut CS, + should_allocate: Boolean, + should_start_new: Boolean, + bias: Variable, // any variable that has to be resolved BEFORE executing witness query + ) -> (Boolean, EL) + where + EL::Witness: Default, + { + self.conditionally_allocate_with_default_biased( + cs, + should_allocate, + should_start_new, + bias, + || std::default::Default::default(), + ) + } +} pub fn unpack_code_into_memory_entry_point< F: SmallField, @@ -52,7 +266,21 @@ where code_words, } = witness; - let code_words: VecDeque = code_words.into_iter().flatten().collect(); + // we result on the FSM input trick here to add pre-padding + let first_sequence_is_a_continuation = closed_form_input.start_flag == false + && closed_form_input + .hidden_fsm_input + .internal_fsm + .state_get_from_queue + == false; + let code_words: VecDeque> = code_words + .into_iter() + .map(|el| VecDeque::from(el)) + .collect(); + let code_words_allocator = ConditionalWitnessSetAllocator::>::new( + code_words, + first_sequence_is_a_continuation, + ); let mut structured_input = CodeDecommitterCycleInputOutput::alloc_ignoring_outputs(cs, closed_form_input.clone()); @@ -95,10 +323,6 @@ where &structured_input.hidden_fsm_input.internal_fsm, ); - let code_words_allocator = ConditionalWitnessAllocator::> { - witness_source: Arc::new(RwLock::new(code_words)), - }; - let final_state = unpack_code_into_memory_inner( cs, &mut memory_queue, @@ -156,7 +380,7 @@ pub fn unpack_code_into_memory_inner< memory_queue: &mut MemoryQueue, unpack_requests_queue: &mut DecommitQueue, initial_state: CodeDecommittmentFSM, - code_word_witness: ConditionalWitnessAllocator>, + code_word_witness: ConditionalWitnessSetAllocator>, _round_function: &R, limit: usize, ) -> CodeDecommittmentFSM @@ -168,83 +392,41 @@ where { assert!(limit <= u32::MAX as usize); - // const POP_QUEUE_OR_WRITE_ID: u64 = 0; - // const FINALIZE_SHA256: u64 = 1; - let mut state = initial_state; - let mut half = F::ONE; - half.double(); - half = half.inverse().unwrap(); - let half_num = Num::allocated_constant(cs, half); - let words_to_bits = UInt32::allocated_constant(cs, 32 * 8); let initial_state_uint32 = boojum::gadgets::sha256::ivs_as_uint32(cs); let boolean_false = Boolean::allocated_constant(cs, false); let boolean_true = Boolean::allocated_constant(cs, true); - + let zero_u16 = UInt16::zero(cs); + let one_u16 = UInt16::allocated_constant(cs, 1u16); let zero_u32 = UInt32::zero(cs); - use zkevm_opcode_defs::VersionedHashDef; - let versioned_hash_top_16_bits = - (zkevm_opcode_defs::versioned_hash::ContractCodeSha256::VERSION_BYTE as u16) << 8; - let versioned_hash_top_16_bits = UInt16::allocated_constant(cs, versioned_hash_top_16_bits); - for _cycle in 0..limit { // we need exactly 3 sponges per cycle: - // - two memory reads when we work on the existing decommittment + // - two memory write when we work on the existing decommittment // - and may be queue pop before it let (may_be_new_request, _) = unpack_requests_queue.pop_front(cs, state.state_get_from_queue); let hash = may_be_new_request.code_hash; - - let chunks = decompose_uint32_to_uint16s(cs, &hash.inner[7]); - - let version_hash_matches = UInt16::equals(cs, &chunks[1], &versioned_hash_top_16_bits); - // if we did get a fresh request from queue we expect it with a proper version bytes - version_hash_matches.conditionally_enforce_true(cs, state.state_get_from_queue); - - let uint_16_one = UInt16::allocated_constant(cs, 1); - let length_in_words = chunks[0]; - let length_in_words = UInt16::conditionally_select( - cs, - state.state_get_from_queue, - &length_in_words, - &uint_16_one, - ); - - let length_in_rounds = unsafe { length_in_words.increment_unchecked(cs) }; - - let length_in_rounds = length_in_rounds.into_num().mul(cs, &half_num); - // length is always a multiple of 2 since we decided so - - let length_in_rounds = UInt16::from_variable_checked(cs, length_in_rounds.get_variable()); - - let length_in_bits_may_be = unsafe { - UInt32::from_variable_unchecked(length_in_words.get_variable()) - .non_widening_mul(cs, &words_to_bits) - }; + // we know that if we pop then highest 32 bits are 0 by how VM constructs a queue + let highest_word_is_zero = hash.inner[7].is_zero(cs); + // if we did get a fresh request from queue we expect it to follow our convention + highest_word_is_zero.conditionally_enforce_true(cs, state.state_get_from_queue); // turn over the endianess // we IGNORE the highest 4 bytes - let uint32_zero = UInt32::allocated_constant(cs, 0); let mut cutted_hash = hash; - cutted_hash.inner[7] = uint32_zero; + cutted_hash.inner[7] = zero_u32; - state.num_rounds_left = UInt16::conditionally_select( - cs, - state.state_get_from_queue, - &length_in_rounds, - &state.num_rounds_left, - ); - state.length_in_bits = UInt32::conditionally_select( + state.num_byte32_words_processed = UInt16::conditionally_select( cs, state.state_get_from_queue, - &length_in_bits_may_be, - &state.length_in_bits, + &zero_u16, + &state.num_byte32_words_processed, ); state.timestamp = UInt32::conditionally_select( cs, @@ -267,7 +449,7 @@ where state.current_index = UInt32::conditionally_select( cs, state.state_get_from_queue, - &uint32_zero, + &zero_u32, &state.current_index, ); state.sha256_inner_state = <[UInt32; 8]>::conditionally_select( @@ -278,34 +460,49 @@ where ); // we decommit if we either decommit or just got a new request + let start_new_sequence = state.state_get_from_queue; state.state_decommit = state.state_decommit.or(cs, state.state_get_from_queue); state.state_get_from_queue = boolean_false; - // even though it's not that useful, we will do it in a checked way for ease of witness - let may_be_num_rounds_left = unsafe { state.num_rounds_left.decrement_unchecked(cs) }; - state.num_rounds_left = UInt16::conditionally_select( + // let's just pull words from witness. We know that first word is never empty if we decommit + let (witness_0_was_empty, code_word_0) = + code_word_witness.conditionally_allocate(cs, state.state_decommit, start_new_sequence); + witness_0_was_empty.conditionally_enforce_false(cs, state.state_decommit); + let code_word_0_be_bytes = code_word_0.to_be_bytes(cs); + let new_num_byte32_words_processed = state + .num_byte32_words_processed + .add_no_overflow(cs, one_u16); + state.num_byte32_words_processed = UInt16::conditionally_select( cs, state.state_decommit, - &may_be_num_rounds_left, - &state.num_rounds_left, + &new_num_byte32_words_processed, + &state.num_byte32_words_processed, ); - let last_round = state.num_rounds_left.is_zero(cs); + // NOTE: we have to enforce a sequence of access to witness, so we always wait for code_word_0 to be resolved + let (witness_1_was_empty, code_word_1) = code_word_witness.conditionally_allocate_biased( + cs, + state.state_decommit, + boolean_false, + code_word_0.inner[0].get_variable(), + ); + let code_word_1_be_bytes = code_word_1.to_be_bytes(cs); + + // if witness_1 wasn't in a circuit witness we conclude that it's the end of hash and perform finalization + let last_round = witness_1_was_empty; let finalize = last_round.and(cs, state.state_decommit); let not_last_round = last_round.negated(cs); let process_second_word = not_last_round.and(cs, state.state_decommit); - // we either pop from the queue, or absorb-decommit, or finalize hash - let code_word_0 = code_word_witness.conditionally_allocate(cs, state.state_decommit); - let code_word_0_be_bytes = code_word_0.to_be_bytes(cs); - - // NOTE: we have to enforce a sequence of access to witness, so we always wait for code_word_0 to be resolved - let code_word_1 = code_word_witness.conditionally_allocate_biased( + let new_num_byte32_words_processed = state + .num_byte32_words_processed + .add_no_overflow(cs, one_u16); + state.num_byte32_words_processed = UInt16::conditionally_select( cs, process_second_word, - code_word_0.inner[0].get_variable(), + &new_num_byte32_words_processed, + &state.num_byte32_words_processed, ); - let code_word_1_be_bytes = code_word_1.to_be_bytes(cs); // perform two writes. It's never a "pointer" type let mem_query_0 = MemoryQuery { @@ -365,8 +562,15 @@ where // padding of single byte of 1<<7 and some zeroes after, and interpret it as BE integer sha256_padding[0] = UInt32::allocated_constant(cs, 1 << 31); - // last word is just number of bits - sha256_padding[7] = state.length_in_bits; + // last word is just number of bits. Note that we multiply u16 by 32*8 and it can not overflow u32 + let length_in_bits = unsafe { + UInt32::from_variable_unchecked( + Num::from_variable(state.num_byte32_words_processed.get_variable()) + .mul(cs, &Num::from_variable(words_to_bits.get_variable())) + .get_variable(), + ) + }; + sha256_padding[7] = length_in_bits; assert_eq!(sha256_input.len(), 16); @@ -443,25 +647,22 @@ fn decompose_uint32_to_uint16s>( #[cfg(test)] mod tests { - use std::alloc::Global; - - use crate::base_structures::decommit_query; use super::*; use crate::base_structures::vm_state::FULL_SPONGE_QUEUE_STATE_WIDTH; - use crate::ethereum_types::{Address, U256}; + use crate::ethereum_types::U256; use boojum::algebraic_props::poseidon2_parameters::Poseidon2GoldilocksExternalMatrix; - use boojum::cs::implementations::reference_cs::CSDevelopmentAssembly; + use boojum::cs::traits::gate::GatePlacementStrategy; use boojum::cs::CSGeometry; use boojum::cs::*; use boojum::field::goldilocks::GoldilocksField; - use boojum::gadgets::queue::full_state_queue::FullStateCircuitQueueWitness; + use boojum::gadgets::tables::*; use boojum::gadgets::traits::allocatable::{CSAllocatable, CSPlaceholder}; - use boojum::gadgets::u160::UInt160; + use boojum::gadgets::u256::UInt256; - use boojum::gadgets::u8::UInt8; + use boojum::implementations::poseidon2::Poseidon2Goldilocks; use boojum::worker::Worker; @@ -613,19 +814,19 @@ mod tests { cs.pad_and_shrink(); let worker = Worker::new(); - let mut owned_cs = owned_cs.into_assembly::(); + let mut owned_cs = owned_cs.into_assembly::(); owned_cs.print_gate_stats(); assert!(owned_cs.check_if_satisfied(&worker)); } fn create_witness_allocator>( _cs: &mut CS, - ) -> ConditionalWitnessAllocator> { + ) -> ConditionalWitnessSetAllocator> { let code_words_witness = get_byte_code_witness(); + let mut wit = VecDeque::new(); + wit.push_back(code_words_witness.into()); - let code_words_allocator = ConditionalWitnessAllocator::> { - witness_source: Arc::new(RwLock::new(code_words_witness.into())), - }; + let code_words_allocator = ConditionalWitnessSetAllocator::>::new(wit, false); code_words_allocator } @@ -671,10 +872,15 @@ mod tests { } fn get_code_hash_witness() -> U256 { - U256::from_dec_str( + let mut bytecode_hash = U256::from_dec_str( "452313746998214869734508634865817576060841700842481516984674100922521850987", ) - .unwrap() + .unwrap(); + // mask it + assert!(bytecode_hash.0[3] >> 56 == 0x01); + bytecode_hash.0[3] &= 0x0000_0000_ffff_ffff; + + bytecode_hash } fn get_byte_code_witness() -> [U256; 33] { diff --git a/crates/zkevm_circuits/src/demux_log_queue/input.rs b/crates/zkevm_circuits/src/demux_log_queue/input.rs index f2f324c..77f378d 100644 --- a/crates/zkevm_circuits/src/demux_log_queue/input.rs +++ b/crates/zkevm_circuits/src/demux_log_queue/input.rs @@ -1,7 +1,10 @@ +use std::collections::BTreeMap; + use crate::base_structures::{ log_query::{LogQuery, LOG_QUERY_PACKED_WIDTH}, vm_state::*, }; +use crate::demux_log_queue::DemuxOutput; use boojum::cs::{traits::cs::ConstraintSystem, Variable}; use boojum::field::SmallField; use boojum::gadgets::traits::auxiliary::PrettyComparison; @@ -9,43 +12,49 @@ use boojum::gadgets::{ boolean::Boolean, queue::*, traits::{ - allocatable::*, encodable::CircuitVarLengthEncodable, selectable::Selectable, - witnessable::WitnessHookable, + allocatable::*, encodable::CircuitVarLengthEncodable, encodable::WitnessVarLengthEncodable, + selectable::Selectable, witnessable::WitnessHookable, }, }; +use boojum::serde_utils::BigArraySerde; use cs_derive::*; use derivative::*; -pub const NUM_OUTPUT_QUEUES: usize = 6; +use super::NUM_DEMUX_OUTPUTS; -#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug)] #[DerivePrettyComparison("true")] pub struct LogDemuxerFSMInputOutput { pub initial_log_queue_state: QueueState, - pub storage_access_queue_state: QueueState, - pub events_access_queue_state: QueueState, - pub l1messages_access_queue_state: QueueState, - pub keccak256_access_queue_state: QueueState, - pub sha256_access_queue_state: QueueState, - pub ecrecover_access_queue_state: QueueState, + pub output_queue_states: [QueueState; NUM_DEMUX_OUTPUTS], } impl CSPlaceholder for LogDemuxerFSMInputOutput { fn placeholder>(cs: &mut CS) -> Self { + let placeholder_state = QueueState::::placeholder(cs); Self { - initial_log_queue_state: QueueState::::placeholder(cs), - storage_access_queue_state: QueueState::::placeholder(cs), - events_access_queue_state: QueueState::::placeholder(cs), - l1messages_access_queue_state: QueueState::::placeholder(cs), - keccak256_access_queue_state: QueueState::::placeholder(cs), - sha256_access_queue_state: QueueState::::placeholder(cs), - ecrecover_access_queue_state: QueueState::::placeholder(cs), + initial_log_queue_state: placeholder_state, + output_queue_states: [placeholder_state; NUM_DEMUX_OUTPUTS], } } } -#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug)] #[DerivePrettyComparison("true")] pub struct LogDemuxerInputData { @@ -60,41 +69,74 @@ impl CSPlaceholder for LogDemuxerInputData { } } -#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug)] #[DerivePrettyComparison("true")] pub struct LogDemuxerOutputData { - pub storage_access_queue_state: QueueState, - pub events_access_queue_state: QueueState, - pub l1messages_access_queue_state: QueueState, - pub keccak256_access_queue_state: QueueState, - pub sha256_access_queue_state: QueueState, - pub ecrecover_access_queue_state: QueueState, + pub output_queue_states: [QueueState; NUM_DEMUX_OUTPUTS], } impl CSPlaceholder for LogDemuxerOutputData { fn placeholder>(cs: &mut CS) -> Self { + let placeholder_state = QueueState::::placeholder(cs); Self { - storage_access_queue_state: QueueState::::placeholder(cs), - events_access_queue_state: QueueState::::placeholder(cs), - l1messages_access_queue_state: QueueState::::placeholder(cs), - keccak256_access_queue_state: QueueState::::placeholder(cs), - sha256_access_queue_state: QueueState::::placeholder(cs), - ecrecover_access_queue_state: QueueState::::placeholder(cs), + output_queue_states: [placeholder_state; NUM_DEMUX_OUTPUTS], } } } impl LogDemuxerOutputData { - pub fn all_output_queues_refs(&self) -> [&QueueState; NUM_OUTPUT_QUEUES] { - [ - &self.storage_access_queue_state, - &self.keccak256_access_queue_state, - &self.sha256_access_queue_state, - &self.ecrecover_access_queue_state, - &self.events_access_queue_state, - &self.l1messages_access_queue_state, - ] + pub fn all_output_queues_refs( + &self, + ) -> BTreeMap> { + let tuples = [ + ( + DemuxOutput::RollupStorage, + &self.output_queue_states[DemuxOutput::RollupStorage as usize], + ), + ( + DemuxOutput::PorterStorage, + &self.output_queue_states[DemuxOutput::PorterStorage as usize], + ), + ( + DemuxOutput::Events, + &self.output_queue_states[DemuxOutput::Events as usize], + ), + ( + DemuxOutput::L2ToL1Messages, + &self.output_queue_states[DemuxOutput::L2ToL1Messages as usize], + ), + ( + DemuxOutput::Keccak, + &self.output_queue_states[DemuxOutput::Keccak as usize], + ), + ( + DemuxOutput::Sha256, + &self.output_queue_states[DemuxOutput::Sha256 as usize], + ), + ( + DemuxOutput::ECRecover, + &self.output_queue_states[DemuxOutput::ECRecover as usize], + ), + ( + DemuxOutput::Secp256r1Verify, + &self.output_queue_states[DemuxOutput::Secp256r1Verify as usize], + ), + ( + DemuxOutput::TransientStorage, + &self.output_queue_states[DemuxOutput::TransientStorage as usize], + ), + ]; + assert_eq!(tuples.len(), NUM_DEMUX_OUTPUTS); + + BTreeMap::from_iter(tuples.into_iter()) } } diff --git a/crates/zkevm_circuits/src/demux_log_queue/mod.rs b/crates/zkevm_circuits/src/demux_log_queue/mod.rs index 81cc1b2..52a0327 100644 --- a/crates/zkevm_circuits/src/demux_log_queue/mod.rs +++ b/crates/zkevm_circuits/src/demux_log_queue/mod.rs @@ -1,3 +1,5 @@ +use std::collections::{HashMap, HashSet}; + use super::*; pub mod input; @@ -7,10 +9,11 @@ use crate::base_structures::{ vm_state::*, }; use crate::fsm_input_output::ClosedFormInputCompactForm; +use arrayvec::ArrayVec; use boojum::algebraic_props::round_function::AlgebraicRoundFunction; use boojum::cs::{gates::*, traits::cs::ConstraintSystem}; use boojum::field::SmallField; -use boojum::gadgets::queue::queue_optimizer::SpongeOptimizer; + use boojum::gadgets::traits::round_function::CircuitRoundFunction; use boojum::gadgets::u32::UInt32; use boojum::gadgets::u8::UInt8; @@ -35,6 +38,71 @@ pub type StorageLogQueue = CircuitQueue, 8, 12, 4, 4, 20, R pub type StorageLogQueueWitness = CircuitQueueWitness, QUEUE_STATE_WIDTH, LOG_QUERY_PACKED_WIDTH>; +#[repr(usize)] +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] +pub enum DemuxOutput { + RollupStorage = 0, + PorterStorage, + Events, + L2ToL1Messages, + Keccak, + Sha256, + ECRecover, + Secp256r1Verify, + TransientStorage, +} + +pub const NUM_DEMUX_OUTPUTS: usize = DemuxOutput::TransientStorage as usize + 1; + +pub const ALL_DEMUX_OUTPUTS: [DemuxOutput; NUM_DEMUX_OUTPUTS] = [ + DemuxOutput::RollupStorage, + DemuxOutput::PorterStorage, + DemuxOutput::Events, + DemuxOutput::L2ToL1Messages, + DemuxOutput::Keccak, + DemuxOutput::Sha256, + DemuxOutput::ECRecover, + DemuxOutput::Secp256r1Verify, + DemuxOutput::TransientStorage, +]; + +impl DemuxOutput { + pub fn is_implemented(&self) -> bool { + match self { + Self::PorterStorage => false, + _ => true, + } + } + + pub fn aux_byte(&self) -> u8 { + match self { + Self::RollupStorage | Self::PorterStorage => STORAGE_AUX_BYTE, + Self::Events => EVENT_AUX_BYTE, + Self::L2ToL1Messages => L1_MESSAGE_AUX_BYTE, + Self::TransientStorage => TRANSIENT_STORAGE_AUX_BYTE, + _ => PRECOMPILE_AUX_BYTE, + } + } + + pub fn precompile_address(&self) -> Option { + match self { + Self::Keccak => Some(*zkevm_opcode_defs::system_params::KECCAK256_ROUND_FUNCTION_PRECOMPILE_FORMAL_ADDRESS), + Self::Sha256 => Some(*zkevm_opcode_defs::system_params::SHA256_ROUND_FUNCTION_PRECOMPILE_FORMAL_ADDRESS), + Self::ECRecover => Some(*zkevm_opcode_defs::system_params::ECRECOVER_INNER_FUNCTION_PRECOMPILE_FORMAL_ADDRESS), + Self::Secp256r1Verify => Some(*zkevm_opcode_defs::system_params::SECP256R1_VERIFY_INNER_FUNCTION_PRECOMPILE_FORMAL_ADDRESS), + _ => None, + } + } + + pub fn shard_id(&self) -> Option { + match self { + Self::RollupStorage => Some(0u8), + Self::PorterStorage => Some(1u8), + _ => None, + } + } +} + pub fn demultiplex_storage_logs_enty_point< F: SmallField, CS: ConstraintSystem, @@ -74,43 +142,16 @@ where initial_queue.witness = Arc::new(initial_queue_witness); // for the rest it's just select between empty or from FSM - let queue_states_from_fsm = [ - &structured_input.hidden_fsm_input.storage_access_queue_state, - &structured_input.hidden_fsm_input.events_access_queue_state, - &structured_input - .hidden_fsm_input - .l1messages_access_queue_state, - &structured_input - .hidden_fsm_input - .keccak256_access_queue_state, - &structured_input.hidden_fsm_input.sha256_access_queue_state, - &structured_input - .hidden_fsm_input - .ecrecover_access_queue_state, - ]; + let queue_states_from_fsm = &structured_input.hidden_fsm_input.output_queue_states; let empty_state = QueueState::empty(cs); - let [mut storage_access_queue, mut events_access_queue, mut l1messages_access_queue, mut keccak256_access_queue, mut sha256_access_queue, mut ecrecover_access_queue] = - queue_states_from_fsm.map(|el| { - let state = QueueState::conditionally_select( - cs, - structured_input.start_flag, - &empty_state, - &el, - ); - StorageLogQueue::::from_state(cs, state) - }); + let mut queue_states = queue_states_from_fsm.map(|el| { + let state = + QueueState::conditionally_select(cs, structured_input.start_flag, &empty_state, &el); + StorageLogQueue::::from_state(cs, state) + }); - let input_queues = [ - &mut storage_access_queue, - &mut events_access_queue, - &mut l1messages_access_queue, - &mut keccak256_access_queue, - &mut sha256_access_queue, - &mut ecrecover_access_queue, - ]; - - demultiplex_storage_logs_inner(cs, &mut initial_queue, input_queues, limit); + demultiplex_storage_logs_inner(cs, &mut initial_queue, &mut queue_states, limit); use boojum::gadgets::traits::allocatable::CSPlaceholder; // form the final state @@ -121,87 +162,28 @@ where structured_input.hidden_fsm_output.initial_log_queue_state = initial_queue.into_state(); - structured_input - .hidden_fsm_output - .storage_access_queue_state = storage_access_queue.into_state(); - - structured_input.hidden_fsm_output.events_access_queue_state = events_access_queue.into_state(); - - structured_input - .hidden_fsm_output - .l1messages_access_queue_state = l1messages_access_queue.into_state(); - - structured_input - .hidden_fsm_output - .keccak256_access_queue_state = keccak256_access_queue.into_state(); - - structured_input.hidden_fsm_output.sha256_access_queue_state = sha256_access_queue.into_state(); + structured_input.hidden_fsm_output.output_queue_states = queue_states.map(|el| el.into_state()); - structured_input - .hidden_fsm_output - .ecrecover_access_queue_state = ecrecover_access_queue.into_state(); + let porter_storage_queue = + structured_input.hidden_fsm_output.output_queue_states[DemuxOutput::PorterStorage as usize]; + let porter_storage_queue_is_empty = porter_storage_queue.tail.length.is_zero(cs); + let boolean_true = Boolean::allocated_constant(cs, true); + Boolean::enforce_equal(cs, &porter_storage_queue_is_empty, &boolean_true); // copy into observable output - structured_input - .observable_output - .storage_access_queue_state = QueueState::conditionally_select( - cs, - completed, - &structured_input - .hidden_fsm_output - .storage_access_queue_state, - &structured_input - .observable_output - .storage_access_queue_state, - ); - structured_input.observable_output.events_access_queue_state = QueueState::conditionally_select( - cs, - completed, - &structured_input.hidden_fsm_output.events_access_queue_state, - &structured_input.observable_output.events_access_queue_state, - ); - structured_input - .observable_output - .l1messages_access_queue_state = QueueState::conditionally_select( - cs, - completed, - &structured_input - .hidden_fsm_output - .l1messages_access_queue_state, - &structured_input - .observable_output - .l1messages_access_queue_state, - ); - structured_input - .observable_output - .keccak256_access_queue_state = QueueState::conditionally_select( - cs, - completed, - &structured_input - .hidden_fsm_output - .keccak256_access_queue_state, - &structured_input - .observable_output - .keccak256_access_queue_state, - ); - structured_input.observable_output.sha256_access_queue_state = QueueState::conditionally_select( - cs, - completed, - &structured_input.hidden_fsm_output.sha256_access_queue_state, - &structured_input.observable_output.sha256_access_queue_state, - ); - structured_input + for (dst, src) in structured_input .observable_output - .ecrecover_access_queue_state = QueueState::conditionally_select( - cs, - completed, - &structured_input - .hidden_fsm_output - .ecrecover_access_queue_state, - &structured_input - .observable_output - .ecrecover_access_queue_state, - ); + .output_queue_states + .iter_mut() + .zip( + structured_input + .hidden_fsm_output + .output_queue_states + .iter(), + ) + { + *dst = QueueState::conditionally_select(cs, completed, src, &*dst); + } // self-check structured_input.hook_compare_witness(cs, &closed_form_input); @@ -218,19 +200,6 @@ where input_commitment } -pub const NUM_SEPARATE_QUEUES: usize = 6; - -#[repr(u64)] -pub enum LogType { - RollupStorage = 0, - Events = 1, - L1Messages = 2, - KeccakCalls = 3, - Sha256Calls = 4, - ECRecoverCalls = 5, - PorterStorage = 1024, // force unreachable -} - pub fn demultiplex_storage_logs_inner< F: SmallField, CS: ConstraintSystem, @@ -238,158 +207,110 @@ pub fn demultiplex_storage_logs_inner< >( cs: &mut CS, storage_log_queue: &mut StorageLogQueue, - output_queues: [&mut StorageLogQueue; NUM_SEPARATE_QUEUES], + output_queues: &mut [StorageLogQueue; NUM_DEMUX_OUTPUTS], limit: usize, ) where [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, { assert!(limit <= u32::MAX as usize); - let [rollup_storage_queue, events_queue, l1_messages_queue, keccak_calls_queue, sha256_calls_queue, ecdsa_calls_queue] = - output_queues; + let boolean_false = Boolean::allocated_constant(cs, false); - let keccak_precompile_address = UInt160::allocated_constant( - cs, - *zkevm_opcode_defs::system_params::KECCAK256_ROUND_FUNCTION_PRECOMPILE_FORMAL_ADDRESS, - ); - let sha256_precompile_address = UInt160::allocated_constant( - cs, - *zkevm_opcode_defs::system_params::SHA256_ROUND_FUNCTION_PRECOMPILE_FORMAL_ADDRESS, - ); - let ecrecover_precompile_address = UInt160::allocated_constant( - cs, - *zkevm_opcode_defs::system_params::ECRECOVER_INNER_FUNCTION_PRECOMPILE_FORMAL_ADDRESS, - ); + let mut all_different_aux_bytes = vec![]; + let mut add_different_addresses = vec![]; + let mut all_different_shard_ids = vec![]; + + let mut aux_byte_set = HashSet::new(); + let mut aux_different_addresses_set = HashSet::new(); + let mut aux_shard_ids_set = HashSet::new(); + + for el in ALL_DEMUX_OUTPUTS.into_iter() { + let aux_byte = el.aux_byte(); + if aux_byte_set.contains(&aux_byte) == false { + aux_byte_set.insert(aux_byte); + all_different_aux_bytes.push((aux_byte, UInt8::allocated_constant(cs, aux_byte))); + } + if let Some(address) = el.precompile_address() { + if aux_different_addresses_set.contains(&address) == false { + aux_different_addresses_set.insert(address); + add_different_addresses.push((address, UInt160::allocated_constant(cs, address))); + } + } + if let Some(shard_id) = el.shard_id() { + if aux_shard_ids_set.contains(&shard_id) == false { + aux_shard_ids_set.insert(shard_id); + all_different_shard_ids.push((shard_id, UInt8::allocated_constant(cs, shard_id))); + } + } + } - // we have 6 queues to demux into, and up to 3 sponges per any push - // use crate::base_structures::log_query::LOG_QUERY_ABSORBTION_ROUNDS; - // let mut optimizer = SpongeOptimizer::::new(LOG_QUERY_ABSORBTION_ROUNDS * limit); + let mut aux_byte_equality_map = HashMap::new(); + let mut address_equality_map = HashMap::new(); + let mut shard_id_equality_map = HashMap::new(); for _ in 0..limit { - // debug_assert!(optimizer.is_fresh()); + assert!(aux_byte_equality_map.is_empty()); + assert!(address_equality_map.is_empty()); + assert!(shard_id_equality_map.is_empty()); let queue_is_empty = storage_log_queue.is_empty(cs); let execute = queue_is_empty.negated(cs); - let popped = storage_log_queue.pop_front(cs, execute); - - let [aux_byte_for_storage, aux_byte_for_event, aux_byte_for_l1_message, aux_byte_for_precompile_call] = - [ - STORAGE_AUX_BYTE, - EVENT_AUX_BYTE, - L1_MESSAGE_AUX_BYTE, - PRECOMPILE_AUX_BYTE, - ] - .map(|byte| UInt8::allocated_constant(cs, byte)); - - let is_storage_aux_byte = UInt8::equals(cs, &aux_byte_for_storage, &popped.0.aux_byte); - let is_event_aux_byte = UInt8::equals(cs, &aux_byte_for_event, &popped.0.aux_byte); - let is_l1_message_aux_byte = - UInt8::equals(cs, &aux_byte_for_l1_message, &popped.0.aux_byte); - let is_precompile_aux_byte = - UInt8::equals(cs, &aux_byte_for_precompile_call, &popped.0.aux_byte); - - let is_keccak_address = UInt160::equals(cs, &keccak_precompile_address, &popped.0.address); - let is_sha256_address = UInt160::equals(cs, &sha256_precompile_address, &popped.0.address); - let is_ecrecover_address = - UInt160::equals(cs, &ecrecover_precompile_address, &popped.0.address); - - let is_rollup_shard = popped.0.shard_id.is_zero(cs); - let execute_rollup_storage = - Boolean::multi_and(cs, &[is_storage_aux_byte, is_rollup_shard, execute]); - let is_porter_shard = is_rollup_shard.negated(cs); - let execute_porter_storage = - Boolean::multi_and(cs, &[is_storage_aux_byte, is_porter_shard, execute]); - - let boolean_false = Boolean::allocated_constant(cs, false); - Boolean::enforce_equal(cs, &execute_porter_storage, &boolean_false); - - let execute_event = Boolean::multi_and(cs, &[is_event_aux_byte, execute]); - let execute_l1_message = Boolean::multi_and(cs, &[is_l1_message_aux_byte, execute]); - let execute_keccak_call = - Boolean::multi_and(cs, &[is_precompile_aux_byte, is_keccak_address, execute]); - let execute_sha256_call = - Boolean::multi_and(cs, &[is_precompile_aux_byte, is_sha256_address, execute]); - let execute_ecrecover_call = - Boolean::multi_and(cs, &[is_precompile_aux_byte, is_ecrecover_address, execute]); - - // rollup_storage_queue.push_encoding_with_optimizer_without_changing_witness( - // cs, - // popped.1, - // execute_rollup_storage, - // LogType::RollupStorage as usize, - // &mut optimizer - // ); - // events_queue.push_encoding_with_optimizer_without_changing_witness( - // cs, - // popped.1, - // execute_event, - // LogType::Events as usize, - // &mut optimizer - // ); - // l1_messages_queue.push_encoding_with_optimizer_without_changing_witness( - // cs, - // popped.1, - // execute_l1_message, - // LogType::L1Messages as usize, - // &mut optimizer - // ); - // keccak_calls_queue.push_encoding_with_optimizer_without_changing_witness( - // cs, - // popped.1, - // execute_keccak_call, - // LogType::KeccakCalls as usize, - // &mut optimizer - // ); - // sha256_calls_queue.push_encoding_with_optimizer_without_changing_witness( - // cs, - // popped.1, - // execute_sha256_call, - // LogType::Sha256Calls as usize, - // &mut optimizer - // ); - // ecdsa_calls_queue.push_encoding_with_optimizer_without_changing_witness( - // cs, - // popped.1, - // execute_ecrecover_call, - // LogType::ECRecoverCalls as usize, - // &mut optimizer - // ); - - let bitmask = [ - execute_rollup_storage, - execute_event, - execute_l1_message, - execute_keccak_call, - execute_sha256_call, - execute_ecrecover_call, - ]; - - push_with_optimize( - cs, - [ - rollup_storage_queue, - events_queue, - l1_messages_queue, - keccak_calls_queue, - sha256_calls_queue, - ecdsa_calls_queue, - ], - bitmask, - popped.0, - ); - - let expected_bitmask_bits = [ - is_storage_aux_byte, - is_event_aux_byte, - is_l1_message_aux_byte, - is_precompile_aux_byte, - ]; - - let is_bitmask = check_if_bitmask_and_if_empty(cs, expected_bitmask_bits); + let (popped, _) = storage_log_queue.pop_front(cs, execute); + + // precompute all comparisons + + for (constant, allocated) in all_different_aux_bytes.iter() { + let equal = UInt8::equals(cs, allocated, &popped.aux_byte); + let existing = aux_byte_equality_map.insert(*constant, equal); + assert!(existing.is_none()); + } + + for (constant, allocated) in add_different_addresses.iter() { + let equal = UInt160::equals(cs, allocated, &popped.address); + let existing = address_equality_map.insert(*constant, equal); + assert!(existing.is_none()); + } + + for (constant, allocated) in all_different_shard_ids.iter() { + let equal = UInt8::equals(cs, allocated, &popped.shard_id); + let existing = shard_id_equality_map.insert(*constant, equal); + assert!(existing.is_none()); + } + + let mut bitmasks = [boolean_false; NUM_DEMUX_OUTPUTS]; + + const MAX_FLAGS: usize = 4; + + for el in ALL_DEMUX_OUTPUTS.into_iter() { + let mut flags = ArrayVec::, MAX_FLAGS>::new(); + flags.push(execute); + + let aux_byte = el.aux_byte(); + flags.push(aux_byte_equality_map[&aux_byte]); + + if let Some(address) = el.precompile_address() { + flags.push(address_equality_map[&address]); + } + + if let Some(shard_id) = el.shard_id() { + flags.push(shard_id_equality_map[&shard_id]); + } + + bitmasks[el as usize] = Boolean::multi_and(cs, &flags[..]); + } + + push_with_optimize(cs, output_queues, bitmasks, popped); + + // if crate::config::CIRCUIT_VERSOBE { + // dbg!(bitmasks.witness_hook(cs)().unwrap()); + // } + + let is_bitmask = check_if_bitmask_or_if_empty(cs, bitmasks); is_bitmask.conditionally_enforce_true(cs, execute); - // // we enforce optimizer in this round, and it clears it up - // optimizer.enforce(cs); + aux_byte_equality_map.clear(); + address_equality_map.clear(); + shard_id_equality_map.clear(); } storage_log_queue.enforce_consistency(cs); @@ -402,29 +323,25 @@ pub fn push_with_optimize< F: SmallField, CS: ConstraintSystem, EL: CircuitEncodableExt, - const AW: usize, - const SW: usize, - const CW: usize, - const T: usize, const N: usize, - R: CircuitRoundFunction, - const NUM_QUEUE: usize, + R: CircuitRoundFunction + AlgebraicRoundFunction, + const NUM_QUEUES: usize, >( cs: &mut CS, - mut queues: [&mut CircuitQueue; NUM_QUEUE], - bitmask: [Boolean; NUM_QUEUE], - value_encoding: EL, + output_queues: &mut [StorageLogQueue; NUM_QUEUES], + bitmask: [Boolean; NUM_QUEUES], + value_for_encoding: EL, ) where [(); >::INTERNAL_STRUCT_LEN]:, { - let mut states = queues.iter().map(|x| x.into_state()); + let mut states = output_queues.iter().map(|x| x.into_state()); let mut state = states.next().unwrap(); for (bit, next_state) in bitmask.iter().skip(1).zip(states) { state = QueueState::conditionally_select(cs, *bit, &next_state, &state); } - let mut exec_queue = CircuitQueue::::from_raw_parts( + let mut exec_queue = CircuitQueue::::from_raw_parts( cs, state.head, state.tail.tail, @@ -432,18 +349,16 @@ pub fn push_with_optimize< ); let boolean_true = Boolean::allocated_constant(cs, true); + exec_queue.push(cs, value_for_encoding, boolean_true); - exec_queue.push(cs, value_encoding, boolean_true); - - for (bit, queue) in bitmask.into_iter().zip(queues.iter_mut()) { + for (bit, queue) in bitmask.into_iter().zip(output_queues.iter_mut()) { // We don't need to update head - // queue.head = <[Num; T]>::conditionally_select(cs, bit, &exec_queue.head, &queue.head); - queue.tail = <[Num; T]>::conditionally_select(cs, bit, &exec_queue.tail, &queue.tail); + queue.tail = <[Num; 4]>::conditionally_select(cs, bit, &exec_queue.tail, &queue.tail); queue.length = UInt32::conditionally_select(cs, bit, &exec_queue.length, &queue.length); } } -pub fn check_if_bitmask_and_if_empty, const N: usize>( +pub fn check_if_bitmask_or_if_empty, const N: usize>( cs: &mut CS, mask: [Boolean; N], ) -> Boolean { @@ -452,15 +367,15 @@ pub fn check_if_bitmask_and_if_empty, con let lc = Num::linear_combination(cs, &lc); let one = Num::from_variable(cs.allocate_constant(F::ONE)); - let is_boolean = Num::equals(cs, &lc, &one); + let is_one = Num::equals(cs, &lc, &one); + let is_zero = lc.is_zero(cs); + let is_boolean = Boolean::multi_or(cs, &[is_zero, is_one]); is_boolean } #[cfg(test)] mod tests { - use std::alloc::Global; - use super::*; use boojum::algebraic_props::poseidon2_parameters::Poseidon2GoldilocksExternalMatrix; use boojum::cs::traits::gate::GatePlacementStrategy; @@ -574,27 +489,14 @@ mod tests { for el in unsorted_input { storage_log_queue.push(cs, el, execute); } - let mut output_queue = StorageLogQueue::empty(cs); - let mut output_queue1 = StorageLogQueue::empty(cs); - let mut output_queue2 = StorageLogQueue::empty(cs); - let mut output_queue3 = StorageLogQueue::empty(cs); - let mut output_queue4 = StorageLogQueue::empty(cs); - let mut output_queue5 = StorageLogQueue::empty(cs); - - let output = [ - &mut output_queue, - &mut output_queue1, - &mut output_queue2, - &mut output_queue3, - &mut output_queue4, - &mut output_queue5, - ]; + + let mut output = std::array::from_fn(|_| StorageLogQueue::empty(cs)); let limit = 16; - demultiplex_storage_logs_inner(cs, &mut storage_log_queue, output, limit); + demultiplex_storage_logs_inner(cs, &mut storage_log_queue, &mut output, limit); cs.pad_and_shrink(); let worker = Worker::new(); - let mut owned_cs = owned_cs.into_assembly::(); + let mut owned_cs = owned_cs.into_assembly::(); owned_cs.print_gate_stats(); assert!(owned_cs.check_if_satisfied(&worker)); } diff --git a/crates/zkevm_circuits/src/ecrecover/baseline.rs b/crates/zkevm_circuits/src/ecrecover/baseline.rs index f688efb..c1fa5ea 100644 --- a/crates/zkevm_circuits/src/ecrecover/baseline.rs +++ b/crates/zkevm_circuits/src/ecrecover/baseline.rs @@ -1,11 +1,10 @@ use super::*; -use crate::base_structures::log_query::*; -use crate::base_structures::memory_query::*; + use crate::base_structures::precompile_input_outputs::PrecompileFunctionOutputData; use crate::demux_log_queue::StorageLogQueue; use crate::ethereum_types::U256; use crate::fsm_input_output::circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH; -use crate::fsm_input_output::*; + use arrayvec::ArrayVec; use boojum::algebraic_props::round_function::AlgebraicRoundFunction; use boojum::crypto_bigint::{Zero, U1024}; @@ -15,28 +14,26 @@ use boojum::field::SmallField; use boojum::gadgets::boolean::Boolean; use boojum::gadgets::curves::sw_projective::SWProjectivePoint; use boojum::gadgets::keccak256::keccak256; -use boojum::gadgets::non_native_field::implementations::*; + use boojum::gadgets::num::Num; use boojum::gadgets::queue::CircuitQueueWitness; use boojum::gadgets::queue::QueueState; use boojum::gadgets::traits::allocatable::{CSAllocatableExt, CSPlaceholder}; use boojum::gadgets::traits::round_function::CircuitRoundFunction; use boojum::gadgets::traits::selectable::Selectable; -use boojum::gadgets::traits::witnessable::WitnessHookable; + use boojum::gadgets::u16::UInt16; use boojum::gadgets::u160::UInt160; use boojum::gadgets::u256::UInt256; use boojum::gadgets::u32::UInt32; use boojum::gadgets::u8::UInt8; -use cs_derive::*; + use std::collections::VecDeque; use std::sync::{Arc, RwLock}; use zkevm_opcode_defs::system_params::PRECOMPILE_AUX_BYTE; pub const MEMORY_QUERIES_PER_CALL: usize = 4; -use super::input::*; - #[derive(Derivative, CSSelectable)] #[derivative(Clone, Debug)] pub struct EcrecoverPrecompileCallParams { @@ -83,7 +80,7 @@ const VALID_X_CUBED_IN_EXTERNAL_FIELD: u64 = 9; // assume that constructed field element is not zero // if this is not satisfied - set the result to be F::one -fn convert_uint256_to_field_element_masked< +pub(crate) fn convert_uint256_to_field_element_masked< F: SmallField, CS: ConstraintSystem, P: boojum::pairing::ff::PrimeField, @@ -135,7 +132,7 @@ where (selected, is_zero) } -fn convert_uint256_to_field_element< +pub(crate) fn convert_uint256_to_field_element< F: SmallField, CS: ConstraintSystem, P: boojum::pairing::ff::PrimeField, @@ -675,11 +672,9 @@ where #[cfg(test)] mod test { - use std::alloc::Global; - use boojum::field::goldilocks::GoldilocksField; use boojum::gadgets::traits::allocatable::CSAllocatable; - use boojum::pairing::ff::{Field, PrimeField, SqrtField}; + use boojum::pairing::ff::{Field, PrimeField}; use boojum::worker::Worker; use super::*; @@ -778,6 +773,7 @@ mod test { num_constant_columns: 8, max_allowed_constraint_degree: 4, }; + let max_variables = 1 << 26; let max_trace_len = 1 << 20; fn configure< @@ -847,7 +843,7 @@ mod test { let builder = new_builder::<_, F>(builder_impl); let builder = configure(builder); - let mut owned_cs = builder.build(1 << 26); + let mut owned_cs = builder.build(max_variables); // add tables let table = create_xor8_table(); @@ -927,7 +923,7 @@ mod test { cs.pad_and_shrink(); - let mut cs = owned_cs.into_assembly::(); + let mut cs = owned_cs.into_assembly::(); cs.print_gate_stats(); let worker = Worker::new(); assert!(cs.check_if_satisfied(&worker)); diff --git a/crates/zkevm_circuits/src/ecrecover/decomp_table.rs b/crates/zkevm_circuits/src/ecrecover/decomp_table.rs index 7c7ea6e..b523e31 100644 --- a/crates/zkevm_circuits/src/ecrecover/decomp_table.rs +++ b/crates/zkevm_circuits/src/ecrecover/decomp_table.rs @@ -1,9 +1,7 @@ use super::*; -use crate::ecrecover::{secp256k1::fr::Fr, Secp256Affine}; + use boojum::cs::implementations::lookup_table::LookupTable; use boojum::field::SmallField; -use boojum::pairing::ff::PrimeField; -use derivative::*; const TABLE_NAME: &'static str = "WNAFDECOMP table"; diff --git a/crates/zkevm_circuits/src/ecrecover/input.rs b/crates/zkevm_circuits/src/ecrecover/input.rs index 2581b39..089d034 100644 --- a/crates/zkevm_circuits/src/ecrecover/input.rs +++ b/crates/zkevm_circuits/src/ecrecover/input.rs @@ -7,11 +7,18 @@ use boojum::cs::Variable; use boojum::gadgets::queue::*; use boojum::gadgets::traits::allocatable::CSAllocatable; use boojum::gadgets::traits::allocatable::CSPlaceholder; -use boojum::gadgets::traits::encodable::CircuitVarLengthEncodable; - use boojum::gadgets::traits::auxiliary::PrettyComparison; +use boojum::gadgets::traits::encodable::CircuitVarLengthEncodable; +use boojum::gadgets::traits::encodable::WitnessVarLengthEncodable; -#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug)] #[DerivePrettyComparison("true")] pub struct EcrecoverCircuitFSMInputOutput { diff --git a/crates/zkevm_circuits/src/ecrecover/mod.rs b/crates/zkevm_circuits/src/ecrecover/mod.rs index 9ed10e6..6f4d7d8 100644 --- a/crates/zkevm_circuits/src/ecrecover/mod.rs +++ b/crates/zkevm_circuits/src/ecrecover/mod.rs @@ -1,37 +1,23 @@ use super::*; use crate::base_structures::log_query::*; use crate::base_structures::memory_query::*; -use crate::base_structures::precompile_input_outputs::PrecompileFunctionOutputData; -use crate::demux_log_queue::StorageLogQueue; + use crate::ethereum_types::U256; -use crate::fsm_input_output::circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH; + use crate::fsm_input_output::*; -use arrayvec::ArrayVec; -use boojum::algebraic_props::round_function::AlgebraicRoundFunction; -use boojum::crypto_bigint::{Zero, U1024}; -use boojum::cs::gates::ConstantAllocatableCS; + use boojum::cs::traits::cs::ConstraintSystem; use boojum::field::SmallField; use boojum::gadgets::boolean::Boolean; -use boojum::gadgets::curves::sw_projective::SWProjectivePoint; -use boojum::gadgets::keccak256::keccak256; + use boojum::gadgets::non_native_field::implementations::*; -use boojum::gadgets::num::Num; -use boojum::gadgets::queue::CircuitQueueWitness; + use boojum::gadgets::queue::QueueState; -use boojum::gadgets::traits::allocatable::{CSAllocatableExt, CSPlaceholder}; -use boojum::gadgets::traits::round_function::CircuitRoundFunction; + use boojum::gadgets::traits::selectable::Selectable; use boojum::gadgets::traits::witnessable::WitnessHookable; -use boojum::gadgets::u16::UInt16; -use boojum::gadgets::u160::UInt160; -use boojum::gadgets::u256::UInt256; -use boojum::gadgets::u32::UInt32; -use boojum::gadgets::u8::UInt8; + use cs_derive::*; -use std::collections::VecDeque; -use std::sync::{Arc, RwLock}; -use zkevm_opcode_defs::system_params::PRECOMPILE_AUX_BYTE; pub mod input; pub use self::input::*; @@ -40,10 +26,8 @@ pub mod secp256k1; pub const MEMORY_QUERIES_PER_CALL: usize = 4; -pub mod naf_abs_div2_table; -use naf_abs_div2_table::*; pub mod decomp_table; -use decomp_table::*; +pub mod naf_abs_div2_table; pub mod baseline; pub mod new_optimized; @@ -55,6 +39,11 @@ use self::secp256k1::fr::Fr as Secp256Fr; // some affine point use self::secp256k1::PointAffine as Secp256Affine; +const BASE_FIELD_REPR_LIMBS: usize = 17; +const SCALAR_FIELD_REPR_LIMBS: usize = 17; +const BASE_FIELD_CANONICAL_REPR_LIMBS: usize = 16; +const SCALAR_FIELD_CANONICAL_REPR_LIMBS: usize = 16; + type Secp256BaseNNFieldParams = NonNativeFieldOverU16Params; type Secp256ScalarNNFieldParams = NonNativeFieldOverU16Params; diff --git a/crates/zkevm_circuits/src/ecrecover/naf_abs_div2_table.rs b/crates/zkevm_circuits/src/ecrecover/naf_abs_div2_table.rs index 3cdd006..e120982 100644 --- a/crates/zkevm_circuits/src/ecrecover/naf_abs_div2_table.rs +++ b/crates/zkevm_circuits/src/ecrecover/naf_abs_div2_table.rs @@ -1,9 +1,7 @@ use super::*; -use crate::ecrecover::{secp256k1::fr::Fr, Secp256Affine}; + use boojum::cs::implementations::lookup_table::LookupTable; use boojum::field::SmallField; -use boojum::pairing::ff::PrimeField; -use derivative::*; const TABLE_NAME: &'static str = "NAFABSDIV2 table"; diff --git a/crates/zkevm_circuits/src/ecrecover/new_optimized.rs b/crates/zkevm_circuits/src/ecrecover/new_optimized.rs index 646d17f..39598ff 100644 --- a/crates/zkevm_circuits/src/ecrecover/new_optimized.rs +++ b/crates/zkevm_circuits/src/ecrecover/new_optimized.rs @@ -1,12 +1,11 @@ use super::*; -use crate::base_structures::log_query::*; -use crate::base_structures::memory_query::*; + use crate::base_structures::precompile_input_outputs::PrecompileFunctionOutputData; use crate::demux_log_queue::StorageLogQueue; use crate::ecrecover::secp256k1::fixed_base_mul_table::FixedBaseMulTable; use crate::ethereum_types::U256; use crate::fsm_input_output::circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH; -use crate::fsm_input_output::*; + use arrayvec::ArrayVec; use boojum::algebraic_props::round_function::AlgebraicRoundFunction; use boojum::crypto_bigint::{Zero, U1024}; @@ -14,22 +13,21 @@ use boojum::cs::gates::ConstantAllocatableCS; use boojum::cs::traits::cs::ConstraintSystem; use boojum::cs::Variable; use boojum::field::SmallField; -use boojum::gadgets::blake2s::mixing_function::merge_byte_using_table; use boojum::gadgets::boolean::Boolean; use boojum::gadgets::curves::sw_projective::SWProjectivePoint; -use boojum::gadgets::curves::zeroable_affine::ZeroableAffinePoint; + use boojum::gadgets::keccak256::keccak256; -use boojum::gadgets::non_native_field::implementations::*; + use boojum::gadgets::non_native_field::traits::NonNativeField; use boojum::gadgets::num::Num; use boojum::gadgets::queue::CircuitQueueWitness; use boojum::gadgets::queue::QueueState; -use boojum::gadgets::tables::And8Table; + use boojum::gadgets::tables::ByteSplitTable; use boojum::gadgets::traits::allocatable::{CSAllocatableExt, CSPlaceholder}; use boojum::gadgets::traits::round_function::CircuitRoundFunction; use boojum::gadgets::traits::selectable::Selectable; -use boojum::gadgets::traits::witnessable::WitnessHookable; + use boojum::gadgets::u16::UInt16; use boojum::gadgets::u160::UInt160; use boojum::gadgets::u256::UInt256; @@ -38,16 +36,12 @@ use boojum::gadgets::u512::UInt512; use boojum::gadgets::u8::UInt8; use boojum::pairing::ff::PrimeField; use boojum::pairing::GenericCurveAffine; -use boojum::pairing::{CurveAffine, GenericCurveProjective}; -use boojum::sha3::digest::typenum::private::IsGreaterPrivate; -use cs_derive::*; + use std::collections::VecDeque; -use std::str::FromStr; use std::sync::{Arc, RwLock}; use zkevm_opcode_defs::system_params::PRECOMPILE_AUX_BYTE; pub use self::input::*; -use super::input::*; pub const MEMORY_QUERIES_PER_CALL: usize = 4; pub const ALLOW_ZERO_MESSAGE: bool = true; @@ -81,7 +75,7 @@ impl EcrecoverPrecompileCallParams { const NUM_WORDS: usize = 17; const SECP_B_COEF: u64 = 7; -const EXCEPTION_FLAGS_ARR_LEN: usize = 10; +const EXCEPTION_FLAGS_ARR_LEN: usize = 9; const NUM_MEMORY_READS_PER_CYCLE: usize = 4; const X_POWERS_ARR_LEN: usize = 256; const VALID_Y_IN_EXTERNAL_FIELD: u64 = 4; @@ -106,9 +100,6 @@ const A1: &'static str = "0x3086d221a7d46bcde86c90e49284eb15"; const B1: &'static str = "0xe4437ed6010e88286f547fa90abfe4c3"; const A2: &'static str = "0x114ca50f7a8e2f3f657c1108d9d44cfd8"; -const HALF_SUBGROUP_SIZE: &'static str = - "7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0"; - const WINDOW_WIDTH: usize = 4; const NUM_MULTIPLICATION_STEPS_FOR_WIDTH_4: usize = 33; const PRECOMPUTATION_TABLE_SIZE: usize = (1 << WINDOW_WIDTH) - 1; @@ -241,90 +232,6 @@ fn convert_field_element_to_uint256< UInt256 { inner: limbs } } -fn to_wnaf>( - cs: &mut CS, - e: Secp256ScalarNNField, - neg: Boolean, - decomp_id: u32, - byte_split_id: u32, -) -> Vec> { - let mut naf = vec![]; - let mut bytes = e - .limbs - .iter() - .flat_map(|el| unsafe { UInt16::from_variable_unchecked(*el).to_le_bytes(cs) }) - .collect::>>(); - - // Loop for max amount of bits in e to ensure homogenous circuit - for i in 0..33 { - // Since each lookup consumes 2 bits of information, and we need at least 3 bits for - // figuring out the NAF number, we can do two lookups before needing to propagated the - // changes up the bytestring. - let mut naf_overflow = None; - for j in 0..2 { - let res = cs.perform_lookup::<1, 2>(decomp_id, &[bytes[0].get_variable()]); - let wnaf_and_carry_bits = unsafe { UInt32::from_variable_unchecked(res[0]) }; - let wnaf_bytes = wnaf_and_carry_bits.to_le_bytes(cs); - bytes[0] = unsafe { UInt8::from_variable_unchecked(res[1]) }; - wnaf_bytes[..2].iter().for_each(|byte| { - let byte_neg = byte.negate(cs); - let byte = Selectable::conditionally_select(cs, neg, byte, &byte_neg); - naf.push(byte); - }); - // Save carry bit. - // It only ever matters to save it on the first iteration as it is not possible - // to overflow for the second. - if j == 0 { - naf_overflow = Some(wnaf_bytes[2]); - } - } - - // Break up the first byte into a lower chunk and a (potential) carry bit. - let res = cs.perform_lookup::<1, 2>(byte_split_id, &[bytes[0].get_variable()]); - let mut low = res[0]; - let carry_bit = unsafe { UInt8::from_variable_unchecked(res[1]) }; - let mut of = Boolean::allocated_constant(cs, true); - - // Shift e and propagate carry. - // Because a GLV decomposed scalar is at most 129 bits, we only care to shift - // the lower 17 bytes of the number initially, and as we progress, more zero bytes - // will appear, lowering the amount of iterations needed to shift our number. - let num_iter = 16 - (i / 2); - bytes - .iter_mut() - .skip(1) - .take(num_iter) - .enumerate() - .for_each(|(i, b)| { - // Propagate carry - let (added_b, new_of) = b.overflowing_add(cs, &carry_bit); - *b = Selectable::conditionally_select(cs, of, &added_b, b); - of = new_of; - // If this is the first byte, we also add the NAF carry bit. - if i == 0 { - let naf_of; - (*b, naf_of) = b.overflowing_add(cs, &naf_overflow.unwrap()); - // If this overflows, we should remember to add a carry bit to the next element. - of = Selectable::conditionally_select(cs, naf_of, &naf_of, &of); - } - - // Glue bytes - let res = cs.perform_lookup::<1, 2>(byte_split_id, &[b.get_variable()]); - *b = unsafe { - UInt8::from_variable_unchecked(merge_byte_using_table::<_, _, 4>( - cs, low, res[0], - )) - }; - low = res[1]; - }); - - // Shift up by one to align. - bytes = bytes[1..].to_vec(); - } - - naf -} - fn width_4_windowed_multiplication>( cs: &mut CS, mut point: SWProjectivePoint>, @@ -419,6 +326,11 @@ fn width_4_windowed_multiplication>( (k1_out_of_range, k1, k2_out_of_range, k2) }; + // dbg!(k1.witness_hook(cs)()); + // dbg!(k2.witness_hook(cs)()); + // dbg!(k1_was_negated.witness_hook(cs)()); + // dbg!(k2_was_negated.witness_hook(cs)()); + // create precomputed table of size 1<<4 - 1 // there is no 0 * P in the table, we will handle it below let mut table = Vec::with_capacity(PRECOMPUTATION_TABLE_SIZE); @@ -581,240 +493,46 @@ fn to_width_4_window_form>( result } -#[deprecated] -fn wnaf_scalar_mul>( +pub(crate) fn fixed_base_mul< + F: SmallField, + CS: ConstraintSystem, + NNS: boojum::pairing::ff::PrimeField, + NNB: boojum::pairing::ff::PrimeField + boojum::pairing::ff::SqrtField, + NNC: boojum::pairing::GenericCurveAffine, + const N: usize, +>( cs: &mut CS, - mut point: SWProjectivePoint>, - mut scalar: Secp256ScalarNNField, - base_field_params: &Arc, - scalar_field_params: &Arc, -) -> SWProjectivePoint> { - scalar.enforce_reduced(cs); - - let pow_2_128 = UInt512::allocated_constant(cs, (U256([0, 0, 1, 0]), U256::zero())); - - let beta = Secp256Fq::from_str(BETA).unwrap(); - let mut beta = Secp256BaseNNField::allocated_constant(cs, beta, &base_field_params); - - let bigint_from_hex_str = |cs: &mut CS, s: &str| -> UInt512 { - let v = U256::from_str_radix(s, 16).unwrap(); - UInt512::allocated_constant(cs, (v, U256::zero())) - }; - - let modulus_minus_one_div_two = bigint_from_hex_str(cs, MODULUS_MINUS_ONE_DIV_TWO); - - let u256_from_hex_str = |cs: &mut CS, s: &str| -> UInt256 { - let v = U256::from_str_radix(s, 16).unwrap(); - UInt256::allocated_constant(cs, v) - }; - - let a1 = u256_from_hex_str(cs, A1); - let b1 = u256_from_hex_str(cs, B1); - let a2 = u256_from_hex_str(cs, A2); - let b2 = a1.clone(); - - let boolean_false = Boolean::allocated_constant(cs, false); - - // Scalar decomposition - let (k1_neg, k1, k2_neg, k2) = { - let k = convert_field_element_to_uint256(cs, scalar.clone()); - - // We take 8 non-zero limbs for the scalar (since it could be of any size), and 4 for B2 - // (since it fits in 128 bits). - let b2_times_k = k.widening_mul(cs, &b2, 8, 4); - // can not overflow u512 - let (b2_times_k, of) = b2_times_k.overflowing_add(cs, &modulus_minus_one_div_two); - Boolean::enforce_equal(cs, &of, &boolean_false); - let c1 = b2_times_k.to_high(); - - // We take 8 non-zero limbs for the scalar (since it could be of any size), and 4 for B1 - // (since it fits in 128 bits). - let b1_times_k = k.widening_mul(cs, &b1, 8, 4); - // can not overflow u512 - let (b1_times_k, of) = b1_times_k.overflowing_add(cs, &modulus_minus_one_div_two); - Boolean::enforce_equal(cs, &of, &boolean_false); - let c2 = b1_times_k.to_high(); - - let mut a1 = convert_uint256_to_field_element(cs, &a1, &scalar_field_params); - let mut b1 = convert_uint256_to_field_element(cs, &b1, &scalar_field_params); - let mut a2 = convert_uint256_to_field_element(cs, &a2, &scalar_field_params); - let mut b2 = a1.clone(); - let mut c1 = convert_uint256_to_field_element(cs, &c1, &scalar_field_params); - let mut c2 = convert_uint256_to_field_element(cs, &c2, &scalar_field_params); - - let mut c1_times_a1 = c1.mul(cs, &mut a1); - let mut c2_times_a2 = c2.mul(cs, &mut a2); - let mut k1 = scalar.sub(cs, &mut c1_times_a1).sub(cs, &mut c2_times_a2); - k1.normalize(cs); - let mut c2_times_b2 = c2.mul(cs, &mut b2); - let mut k2 = c1.mul(cs, &mut b1).sub(cs, &mut c2_times_b2); - k2.normalize(cs); - - let k1_u256 = convert_field_element_to_uint256(cs, k1.clone()); - let k2_u256 = convert_field_element_to_uint256(cs, k2.clone()); - let low_pow_2_128 = pow_2_128.to_low(); - let (_res, k1_neg) = k1_u256.overflowing_sub(cs, &low_pow_2_128); - let k1_negated = k1.negated(cs); - let k1 = as NonNativeField>::conditionally_select( - cs, - k1_neg, - &k1, - &k1_negated, - ); - let (_res, k2_neg) = k2_u256.overflowing_sub(cs, &low_pow_2_128); - let k2_negated = k2.negated(cs); - let k2 = as NonNativeField>::conditionally_select( - cs, - k2_neg, - &k2, - &k2_negated, - ); - - (k1_neg, k1, k2_neg, k2) - }; - - // WNAF - // The scalar multiplication window size. - use super::decomp_table::WNAF_WINDOW_SIZE; - - // The WNAF precomputation table length - const L: usize = 1 << (WNAF_WINDOW_SIZE - 1); - - let mut t1 = Vec::with_capacity(L); - // We use `convert_to_affine_or_default`, but we don't need to worry about returning 1, since - // we know that the point is not infinity. - let (mut double, _) = point - .double(cs) - .convert_to_affine_or_default(cs, Secp256Affine::one()); - t1.push(point.clone()); - // we need 1P, 3P, 5P, ... - for i in 1..L { - let next = t1[i - 1].add_mixed(cs, &mut double); - t1.push(next); - } - - // (x, y) - let t1 = t1 - .iter_mut() - .map(|el| el.convert_to_affine_or_default(cs, Secp256Affine::one()).0) - .collect::>(); - - // (x*beta, y) - let t2 = t1 - .clone() - .into_iter() - .map(|mut el| (el.0.mul(cs, &mut beta), el.1)) - .collect::>(); - - let overflow_checker = UInt8::allocated_constant(cs, 1 << 7); - let decomp_id = cs - .get_table_id_for_marker::() - .expect("table should exist"); - let byte_split_id = cs - .get_table_id_for_marker::>() - .expect("table should exist"); - - let naf_abs_div2_table_id = cs - .get_table_id_for_marker::() - .expect("table must exist"); - let naf_add = - |cs: &mut CS, - table: &[(Secp256BaseNNField, Secp256BaseNNField)], - naf: UInt8, - acc: &mut SWProjectivePoint>| { - let is_zero = naf.is_zero(cs); - let index = unsafe { - UInt8::from_variable_unchecked( - cs.perform_lookup::<1, 2>(naf_abs_div2_table_id, &[naf.get_variable()])[0], - ) - }; - // We assume that only one of the values in the table will be selected (since the index - // <= table.len()) and so we can iteratively conditionally select over all elements. - let mut sanity_checks = vec![index.is_zero(cs)]; - let mut coords = table[0].clone(); - for (i, v) in table.iter().enumerate().skip(1) { - assert!((i as u8) < u8::MAX); - let const_idx: UInt8 = UInt8::allocated_constant(cs, i as u8); - let correct_idx = UInt8::equals(cs, &index, &const_idx); - sanity_checks.push(correct_idx); - coords.0 = Selectable::conditionally_select(cs, correct_idx, &v.0, &coords.0); - coords.1 = Selectable::conditionally_select(cs, correct_idx, &v.1, &coords.1); - } - let matched = Boolean::multi_or(cs, &sanity_checks); - let boolean_true = Boolean::allocated_constant(cs, true); - Boolean::enforce_equal(cs, &matched, &boolean_true); - - let mut p_1 = - SWProjectivePoint::>::from_xy_unchecked( - cs, - coords.0.clone(), - coords.1.clone(), - ); - let (_, naf_is_positive) = naf.overflowing_sub(cs, &overflow_checker); - let p_1_neg = p_1.negated(cs); - p_1 = Selectable::conditionally_select(cs, naf_is_positive, &p_1, &p_1_neg); - let acc_added = acc.add_mixed(cs, &mut (p_1.x, p_1.y)); - *acc = Selectable::conditionally_select(cs, is_zero, &acc, &acc_added); - }; - - let naf1 = to_wnaf(cs, k1, k1_neg, decomp_id, byte_split_id); - let naf2 = to_wnaf(cs, k2, k2_neg, decomp_id, byte_split_id); - let mut acc = - SWProjectivePoint::>::zero(cs, &base_field_params); - for i in (0..129).rev() { - naf_add(cs, &t1, naf1[i], &mut acc); - naf_add(cs, &t2, naf2[i], &mut acc); - if i != 0 { - acc = acc.double(cs); - } - } - - acc -} + mut scalar: NonNativeFieldOverU16, + base_field_params: &Arc>, + scalar_canonical_limbs: usize, + base_canonical_limbs_canonical_limbs: usize, + fixed_base_table_ids: &[[u32; 8]], +) -> SWProjectivePoint> +where + [(); N + 1]:, +{ + assert!(base_canonical_limbs_canonical_limbs % 2 == 0); + assert!(scalar_canonical_limbs % 2 == 0); + assert_eq!(scalar_canonical_limbs * 2, fixed_base_table_ids.len()); + assert_eq!(base_canonical_limbs_canonical_limbs / 2, 8); -fn fixed_base_mul, F: SmallField>( - cs: &mut CS, - mut message_hash_by_r_inv: Secp256ScalarNNField, - base_field_params: &Arc, -) -> SWProjectivePoint> { - message_hash_by_r_inv.enforce_reduced(cs); - let is_zero = message_hash_by_r_inv.is_zero(cs); - let bytes = message_hash_by_r_inv + scalar.enforce_reduced(cs); + let is_zero = scalar.is_zero(cs); + let bytes = scalar .limbs .iter() - .take(16) + .take(scalar_canonical_limbs) .flat_map(|el| unsafe { UInt16::from_variable_unchecked(*el).to_le_bytes(cs) }) .collect::>>(); let zero_point = - SWProjectivePoint::>::zero(cs, base_field_params); + SWProjectivePoint::>::zero(cs, base_field_params); let mut acc = - SWProjectivePoint::>::zero(cs, base_field_params); - let mut full_table_ids = vec![]; - seq_macro::seq!(C in 0..32 { - let ids = [ - cs.get_table_id_for_marker::>() - .expect("table must exist"), - cs.get_table_id_for_marker::>() - .expect("table must exist"), - cs.get_table_id_for_marker::>() - .expect("table must exist"), - cs.get_table_id_for_marker::>() - .expect("table must exist"), - cs.get_table_id_for_marker::>() - .expect("table must exist"), - cs.get_table_id_for_marker::>() - .expect("table must exist"), - cs.get_table_id_for_marker::>() - .expect("table must exist"), - cs.get_table_id_for_marker::>() - .expect("table must exist"), - ]; - full_table_ids.push(ids); - }); + SWProjectivePoint::>::zero(cs, base_field_params); - full_table_ids - .into_iter() + fixed_base_table_ids + .iter() + .copied() .zip(bytes) .rev() .for_each(|(ids, byte)| { @@ -839,13 +557,15 @@ fn fixed_base_mul, F: SmallField>( .into_iter() .unzip(); let zero_var = cs.allocate_constant(F::ZERO); - let mut x_arr = [zero_var; 17]; - x_arr[..16].copy_from_slice(&x[..16]); - let mut y_arr = [zero_var; 17]; - y_arr[..16].copy_from_slice(&y[..16]); + let mut x_arr = [zero_var; N]; + x_arr[..base_canonical_limbs_canonical_limbs] + .copy_from_slice(&x[..base_canonical_limbs_canonical_limbs]); + let mut y_arr = [zero_var; N]; + y_arr[..base_canonical_limbs_canonical_limbs] + .copy_from_slice(&y[..base_canonical_limbs_canonical_limbs]); let x = NonNativeFieldOverU16 { limbs: x_arr, - non_zero_limbs: 16, + non_zero_limbs: base_canonical_limbs_canonical_limbs, tracker: OverflowTracker { max_moduluses: 1 }, form: RepresentationForm::Normalized, params: base_field_params.clone(), @@ -853,7 +573,7 @@ fn fixed_base_mul, F: SmallField>( }; let y = NonNativeFieldOverU16 { limbs: y_arr, - non_zero_limbs: 16, + non_zero_limbs: base_canonical_limbs_canonical_limbs, tracker: OverflowTracker { max_moduluses: 1 }, form: RepresentationForm::Normalized, params: base_field_params.clone(), @@ -924,13 +644,6 @@ fn ecrecover_precompile_inner_routine< let [y_is_odd, x_overflow, ..] = Num::::from_variable(recid.get_variable()).spread_into_bits::<_, 8>(cs); - // check convention s < N/2 - let s_upper_bound = - UInt256::allocated_constant(cs, U256::from_str_radix(HALF_SUBGROUP_SIZE, 16).unwrap()); - let (_, uf) = s.overflowing_sub(cs, &s_upper_bound); - let s_too_large = uf.negated(cs); - exception_flags.push(s_too_large); - let (r_plus_n, of) = r.overflowing_add(cs, &secp_n_u256); let mut x_as_u256 = UInt256::conditionally_select(cs, x_overflow, &r_plus_n, &r); let error = Boolean::multi_and(cs, &[x_overflow, of]); @@ -1076,16 +789,37 @@ fn ecrecover_precompile_inner_routine< &scalar_field_params, ); - // let mut s_times_x = wnaf_scalar_mul( - // cs, - // recovered_point.clone(), - // s_by_r_inv.clone(), - // &base_field_params, - // &scalar_field_params, - // ); + let mut full_table_ids = vec![]; + seq_macro::seq!(C in 0..32 { + let ids = [ + cs.get_table_id_for_marker::>() + .expect("table must exist"), + cs.get_table_id_for_marker::>() + .expect("table must exist"), + cs.get_table_id_for_marker::>() + .expect("table must exist"), + cs.get_table_id_for_marker::>() + .expect("table must exist"), + cs.get_table_id_for_marker::>() + .expect("table must exist"), + cs.get_table_id_for_marker::>() + .expect("table must exist"), + cs.get_table_id_for_marker::>() + .expect("table must exist"), + cs.get_table_id_for_marker::>() + .expect("table must exist"), + ]; + full_table_ids.push(ids); + }); - let mut hash_times_g = fixed_base_mul(cs, message_hash_by_r_inv_negated, &base_field_params); - // let mut hash_times_g = fixed_base_mul(cs, message_hash_by_r_inv, &base_field_params); + let mut hash_times_g = fixed_base_mul::( + cs, + message_hash_by_r_inv_negated, + &base_field_params, + SCALAR_FIELD_CANONICAL_REPR_LIMBS, + BASE_FIELD_CANONICAL_REPR_LIMBS, + &full_table_ids, + ); let (mut q_acc, is_infinity) = hash_times_g.convert_to_affine_or_default(cs, Secp256Affine::one()); @@ -1161,8 +895,6 @@ where let scalar_params = Arc::new(secp256k1_scalar_field_params()); let base_params = Arc::new(secp256k1_base_field_params()); - use boojum::pairing::ff::PrimeField; - let valid_x_in_external_field = Secp256BaseNNField::allocated_constant( cs, Secp256Fq::from_str(&VALID_X_CUBED_IN_EXTERNAL_FIELD.to_string()).unwrap(), @@ -1385,12 +1117,9 @@ where #[cfg(test)] mod test { - use std::alloc::Global; - use boojum::field::goldilocks::GoldilocksField; - use boojum::gadgets::non_native_field::implementations::implementation_u16::FFProxyValue; use boojum::gadgets::traits::allocatable::CSAllocatable; - use boojum::pairing::ff::{Field, PrimeField, SqrtField}; + use boojum::pairing::ff::{Field, PrimeField}; use boojum::worker::Worker; use super::*; @@ -1633,9 +1362,39 @@ mod test { let mut seed = Secp256Fr::multiplicative_generator(); seed = seed.pow([1234]); + let mut full_table_ids = vec![]; + seq_macro::seq!(C in 0..32 { + let ids = [ + cs.get_table_id_for_marker::>() + .expect("table must exist"), + cs.get_table_id_for_marker::>() + .expect("table must exist"), + cs.get_table_id_for_marker::>() + .expect("table must exist"), + cs.get_table_id_for_marker::>() + .expect("table must exist"), + cs.get_table_id_for_marker::>() + .expect("table must exist"), + cs.get_table_id_for_marker::>() + .expect("table must exist"), + cs.get_table_id_for_marker::>() + .expect("table must exist"), + cs.get_table_id_for_marker::>() + .expect("table must exist"), + ]; + full_table_ids.push(ids); + }); + for _i in 0..16 { let scalar = Secp256ScalarNNField::allocate_checked(cs, seed, &scalar_params); - let mut result = fixed_base_mul(cs, scalar, &base_params); + let mut result = fixed_base_mul::( + cs, + scalar, + &base_params, + 16, + 16, + &full_table_ids, + ); let ((result_x, result_y), _) = result.convert_to_affine_or_default(cs, Secp256Affine::one()); @@ -1685,7 +1444,6 @@ mod test { let mut result = width_4_windowed_multiplication(cs, point, scalar, &base_params, &scalar_params); - // let mut result = wnaf_scalar_mul(cs, point, scalar, &base_params, &scalar_params); let ((result_x, result_y), _) = result.convert_to_affine_or_default(cs, Secp256Affine::one()); @@ -1705,7 +1463,6 @@ mod test { } #[test] - #[ignore = "test vectors hits malleable S"] fn test_signature_for_address_verification() { let mut owned_cs = create_cs(1 << 20); let cs = &mut owned_cs; @@ -1773,7 +1530,7 @@ mod test { cs.pad_and_shrink(); - let mut cs = owned_cs.into_assembly::(); + let mut cs = owned_cs.into_assembly::(); cs.print_gate_stats(); let worker = Worker::new(); assert!(cs.check_if_satisfied(&worker)); @@ -1849,7 +1606,7 @@ mod test { cs.pad_and_shrink(); - let mut cs = owned_cs.into_assembly::(); + let mut cs = owned_cs.into_assembly::(); cs.print_gate_stats(); let worker = Worker::new(); assert!(cs.check_if_satisfied(&worker)); @@ -1925,7 +1682,7 @@ mod test { cs.pad_and_shrink(); - let mut cs = owned_cs.into_assembly::(); + let mut cs = owned_cs.into_assembly::(); cs.print_gate_stats(); let worker = Worker::new(); assert!(cs.check_if_satisfied(&worker)); @@ -2041,7 +1798,6 @@ mod test { // https://ethresear.ch/t/you-can-kinda-abuse-ecrecover-to-do-ecmul-in-secp256k1-today/2384 #[test] fn test_ecrecover_scalar_mul_trick() { - use rand::Rand; let mut owned_cs = create_cs(1 << 20); let cs = &mut owned_cs; @@ -2115,7 +1871,7 @@ mod test { cs.pad_and_shrink(); - let mut cs = owned_cs.into_assembly::(); + let mut cs = owned_cs.into_assembly::(); cs.print_gate_stats(); let worker = Worker::new(); assert!(cs.check_if_satisfied(&worker)); diff --git a/crates/zkevm_circuits/src/ecrecover/secp256k1/fixed_base_mul_table.rs b/crates/zkevm_circuits/src/ecrecover/secp256k1/fixed_base_mul_table.rs index 87aa76e..ec7428d 100644 --- a/crates/zkevm_circuits/src/ecrecover/secp256k1/fixed_base_mul_table.rs +++ b/crates/zkevm_circuits/src/ecrecover/secp256k1/fixed_base_mul_table.rs @@ -5,7 +5,7 @@ use boojum::field::SmallField; use boojum::pairing::ff::PrimeField; use derivative::*; -const TABLE_NAME: &'static str = "FIXEDBASEMUL table"; +const TABLE_NAME: &'static str = "Secp256k1 FIXEDBASEMUL table"; #[derive(Derivative)] #[derivative(Clone, Copy, Debug, PartialEq, Eq)] diff --git a/crates/zkevm_circuits/src/ecrecover/secp256k1/mod.rs b/crates/zkevm_circuits/src/ecrecover/secp256k1/mod.rs index 83e13fa..3dd9399 100644 --- a/crates/zkevm_circuits/src/ecrecover/secp256k1/mod.rs +++ b/crates/zkevm_circuits/src/ecrecover/secp256k1/mod.rs @@ -9,7 +9,6 @@ pub mod fixed_base_mul_table; pub mod fq; pub mod fr; -use fixed_base_mul_table::*; use fq::*; use fr::*; diff --git a/crates/zkevm_circuits/src/eip_4844/input.rs b/crates/zkevm_circuits/src/eip_4844/input.rs index 9b202fc..a815029 100644 --- a/crates/zkevm_circuits/src/eip_4844/input.rs +++ b/crates/zkevm_circuits/src/eip_4844/input.rs @@ -1,30 +1,26 @@ use std::collections::VecDeque; use super::*; -use crate::base_structures::vm_state::*; + use boojum::cs::{traits::cs::ConstraintSystem, Variable}; use boojum::field::SmallField; use boojum::gadgets::keccak256; use boojum::gadgets::traits::auxiliary::PrettyComparison; -use boojum::gadgets::u256::recompose_u256_as_u32x8; -use boojum::gadgets::u32::UInt32; + use boojum::gadgets::u8::UInt8; use boojum::gadgets::{ boolean::Boolean, - queue::*, traits::{ - allocatable::*, - encodable::{CircuitEncodable, CircuitEncodableExt, CircuitVarLengthEncodable}, - selectable::Selectable, - witnessable::WitnessHookable, + encodable::CircuitVarLengthEncodable, encodable::WitnessVarLengthEncodable, + selectable::Selectable, witnessable::WitnessHookable, }, }; use boojum::serde_utils::BigArraySerde; use cs_derive::*; -use derivative::*; pub const BLOB_CHUNK_SIZE: usize = 31; pub const ELEMENTS_PER_4844_BLOCK: usize = 4096; +pub const ENCODABLE_BYTES_PER_BLOB: usize = BLOB_CHUNK_SIZE * ELEMENTS_PER_4844_BLOCK; #[derive(Derivative, CSAllocatable, CSSelectable, WitnessHookable)] #[derivative(Clone, Copy, Debug)] @@ -32,7 +28,14 @@ pub struct BlobChunk { pub inner: [UInt8; BLOB_CHUNK_SIZE], } -#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitVarLengthEncodable, + WitnessHookable, +)] #[derivative(Clone, Copy, Debug)] #[DerivePrettyComparison("true")] pub struct EIP4844OutputData { diff --git a/crates/zkevm_circuits/src/eip_4844/mod.rs b/crates/zkevm_circuits/src/eip_4844/mod.rs index 929f5cc..45cf612 100644 --- a/crates/zkevm_circuits/src/eip_4844/mod.rs +++ b/crates/zkevm_circuits/src/eip_4844/mod.rs @@ -1,34 +1,27 @@ -use crate::base_structures::state_diff_record::StateDiffRecord; -use crate::demux_log_queue::StorageLogQueue; -use crate::ethereum_types::U256; use crate::fsm_input_output::circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH; -use crate::keccak256_round_function::keccak256_absorb_and_run_permutation; + use boojum::algebraic_props::round_function::AlgebraicRoundFunction; use boojum::config::*; -use boojum::crypto_bigint::{Zero, U1024}; use boojum::cs::gates::ConstantAllocatableCS; -use boojum::cs::traits::cs::{ConstraintSystem, DstBuffer}; -use boojum::cs::{Place, Variable}; +use boojum::cs::traits::cs::ConstraintSystem; + use boojum::field::SmallField; use boojum::gadgets::boolean::Boolean; use boojum::gadgets::keccak256; use boojum::gadgets::non_native_field::implementations::*; use boojum::gadgets::num::Num; -use boojum::gadgets::queue::CircuitQueue; -use boojum::gadgets::queue::CircuitQueueWitness; -use boojum::gadgets::queue::QueueState; + use boojum::gadgets::traits::allocatable::{CSAllocatable, CSAllocatableExt, CSPlaceholder}; -use boojum::gadgets::traits::castable::WitnessCastable; + use boojum::gadgets::traits::round_function::CircuitRoundFunction; -use boojum::gadgets::traits::selectable::Selectable; -use boojum::gadgets::traits::witnessable::WitnessHookable; + use boojum::gadgets::u16::UInt16; use boojum::gadgets::u256::UInt256; -use boojum::gadgets::u32::UInt32; + use boojum::gadgets::u8::UInt8; use boojum::pairing::ff::{Field, PrimeField}; -use std::mem::MaybeUninit; -use std::sync::{Arc, RwLock}; + +use std::sync::Arc; use super::*; @@ -446,7 +439,6 @@ pub fn ethereum_4844_data_into_zksync_pubdata(input: &[u8]) -> Vec { #[cfg(test)] mod tests { - use std::alloc::Global; use std::collections::VecDeque; use super::*; @@ -458,19 +450,17 @@ mod tests { use boojum::cs::CSGeometry; use boojum::cs::*; use boojum::field::goldilocks::GoldilocksField; - use boojum::field::traits::field_like::PrimeFieldLike; - use boojum::field::Field; use boojum::field::SmallField; - use boojum::gadgets::queue::CircuitQueueRawWitness; + use boojum::gadgets::tables::byte_split::ByteSplitTable; use boojum::gadgets::tables::*; use boojum::implementations::poseidon2::Poseidon2Goldilocks; use boojum::pairing::bls12_381::G1; use boojum::pairing::ff::PrimeFieldRepr; - use boojum::pairing::ff::{Field as PairingField, PrimeField, SqrtField}; + use boojum::pairing::ff::{Field as PairingField, PrimeField}; use boojum::worker::Worker; + use rand::Rand; use rand::SeedableRng; - use rand::{Rand, Rng}; type F = GoldilocksField; type P = GoldilocksField; @@ -651,7 +641,6 @@ mod tests { let evaluation_point_fr = Bls12_381Fr::from_repr(evaluation_point_repr).unwrap(); dbg!(evaluation_point_fr); - use boojum::pairing::bls12_381::FrRepr; // evaluate polynomial let mut evaluation_result = Bls12_381Fr::zero(); let mut power = Bls12_381Fr::one(); @@ -707,7 +696,7 @@ mod tests { cs.pad_and_shrink(); - let mut cs = owned_cs.into_assembly::(); + let mut cs = owned_cs.into_assembly::(); cs.print_gate_stats(); let worker = Worker::new(); assert!(cs.check_if_satisfied(&worker)); @@ -731,6 +720,7 @@ mod tests { #[test] fn test_data_roundtrip() { + use rand::Rng; let mut rng = rand::XorShiftRng::new_unseeded(); let zksync_data: Vec = (0..(31 * 4096)).map(|_| rng.gen()).collect(); let monomial_form = zksync_pubdata_into_monomial_form_poly(&zksync_data); diff --git a/crates/zkevm_circuits/src/fsm_input_output/circuit_inputs/main_vm.rs b/crates/zkevm_circuits/src/fsm_input_output/circuit_inputs/main_vm.rs index 4a2c639..b5717ba 100644 --- a/crates/zkevm_circuits/src/fsm_input_output/circuit_inputs/main_vm.rs +++ b/crates/zkevm_circuits/src/fsm_input_output/circuit_inputs/main_vm.rs @@ -4,7 +4,14 @@ use crate::base_structures::vm_state::*; use boojum::gadgets::queue::*; use boojum::serde_utils::BigArraySerde; -#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Debug)] pub struct VmInputData { pub rollback_queue_tail_for_block: [Num; QUEUE_STATE_WIDTH], @@ -27,7 +34,14 @@ impl CSPlaceholder for VmInputData { } } -#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Debug)] #[DerivePrettyComparison("true")] pub struct VmOutputData { diff --git a/crates/zkevm_circuits/src/fsm_input_output/mod.rs b/crates/zkevm_circuits/src/fsm_input_output/mod.rs index c6205f5..3fa5e1d 100644 --- a/crates/zkevm_circuits/src/fsm_input_output/mod.rs +++ b/crates/zkevm_circuits/src/fsm_input_output/mod.rs @@ -1,7 +1,9 @@ use super::*; +use boojum::gadgets::traits::allocatable::CSAllocatableExt; use boojum::gadgets::traits::auxiliary::PrettyComparison; use cs_derive::*; +use crate::boojum::cs::traits::cs::DstBuffer; use boojum::cs::gates::ConstantAllocatableCS; use boojum::cs::traits::cs::ConstraintSystem; use boojum::cs::Variable; @@ -11,6 +13,7 @@ use boojum::gadgets::num::Num; use boojum::gadgets::traits::allocatable::CSAllocatable; use boojum::gadgets::traits::allocatable::CSPlaceholder; use boojum::gadgets::traits::encodable::CircuitVarLengthEncodable; +use boojum::gadgets::traits::encodable::WitnessVarLengthEncodable; use boojum::gadgets::traits::round_function::CircuitRoundFunction; use boojum::gadgets::traits::selectable::Selectable; use boojum::gadgets::traits::witnessable::WitnessHookable; @@ -31,9 +34,24 @@ where #[derivative(Clone, Debug)] pub struct ClosedFormInput< F: SmallField, - T: Clone + std::fmt::Debug + CSAllocatable + CircuitVarLengthEncodable + WitnessHookable, - IN: Clone + std::fmt::Debug + CSAllocatable + CircuitVarLengthEncodable + WitnessHookable, - OUT: Clone + std::fmt::Debug + CSAllocatable + CircuitVarLengthEncodable + WitnessHookable, + T: Clone + + std::fmt::Debug + + CSAllocatable + + CircuitVarLengthEncodable + + WitnessVarLengthEncodable + + WitnessHookable, + IN: Clone + + std::fmt::Debug + + CSAllocatable + + CircuitVarLengthEncodable + + WitnessVarLengthEncodable + + WitnessHookable, + OUT: Clone + + std::fmt::Debug + + CSAllocatable + + CircuitVarLengthEncodable + + WitnessVarLengthEncodable + + WitnessHookable, > where >::Witness: serde::Serialize + serde::de::DeserializeOwned + Eq, >::Witness: serde::Serialize + serde::de::DeserializeOwned + Eq, @@ -53,16 +71,19 @@ impl< + std::fmt::Debug + CSAllocatable + CircuitVarLengthEncodable + + WitnessVarLengthEncodable + WitnessHookable, IN: Clone + std::fmt::Debug + CSAllocatable + CircuitVarLengthEncodable + + WitnessVarLengthEncodable + WitnessHookable, OUT: Clone + std::fmt::Debug + CSAllocatable + CircuitVarLengthEncodable + + WitnessVarLengthEncodable + WitnessHookable, > ClosedFormInput where @@ -141,16 +162,19 @@ impl< + std::fmt::Debug + CSAllocatable + CircuitVarLengthEncodable + + WitnessVarLengthEncodable + WitnessHookable, IN: Clone + std::fmt::Debug + CSAllocatable + CircuitVarLengthEncodable + + WitnessVarLengthEncodable + WitnessHookable, OUT: Clone + std::fmt::Debug + CSAllocatable + CircuitVarLengthEncodable + + WitnessVarLengthEncodable + WitnessHookable, > std::default::Default for ClosedFormInputWitness where @@ -163,7 +187,14 @@ where } } -#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Debug)] pub struct ClosedFormInputCompactForm { pub start_flag: Boolean, @@ -174,6 +205,78 @@ pub struct ClosedFormInputCompactForm { pub hidden_fsm_output_committment: [Num; CLOSED_FORM_COMMITTMENT_LENGTH], } +impl CSAllocatableExt for ClosedFormInputCompactForm { + const INTERNAL_STRUCT_LEN: usize = 1 + 1 + CLOSED_FORM_COMMITTMENT_LENGTH * 4; + + fn witness_from_set_of_values(values: [F; Self::INTERNAL_STRUCT_LEN]) -> Self::Witness { + use crate::boojum::gadgets::traits::castable::WitnessCastable; + + let start_flag = WitnessCastable::cast_from_source(values[0]); + let completion_flag = WitnessCastable::cast_from_source(values[1]); + + let observable_input_committment = [values[2], values[3], values[4], values[5]] + .map(|el| WitnessCastable::cast_from_source(el)); + let observable_output_committment = [values[6], values[7], values[8], values[9]] + .map(|el| WitnessCastable::cast_from_source(el)); + let hidden_fsm_input_committment = [values[10], values[11], values[12], values[13]] + .map(|el| WitnessCastable::cast_from_source(el)); + let hidden_fsm_output_committment = [values[14], values[15], values[16], values[17]] + .map(|el| WitnessCastable::cast_from_source(el)); + + Self::Witness { + start_flag, + completion_flag, + observable_input_committment, + observable_output_committment, + hidden_fsm_input_committment, + hidden_fsm_output_committment, + } + } + + fn flatten_as_variables(&self) -> [Variable; Self::INTERNAL_STRUCT_LEN] + where + [(); Self::INTERNAL_STRUCT_LEN]:, + { + [ + self.start_flag.get_variable(), + self.completion_flag.get_variable(), + self.observable_input_committment[0].get_variable(), + self.observable_input_committment[1].get_variable(), + self.observable_input_committment[2].get_variable(), + self.observable_input_committment[3].get_variable(), + self.observable_output_committment[0].get_variable(), + self.observable_output_committment[1].get_variable(), + self.observable_output_committment[2].get_variable(), + self.observable_output_committment[3].get_variable(), + self.hidden_fsm_input_committment[0].get_variable(), + self.hidden_fsm_input_committment[1].get_variable(), + self.hidden_fsm_input_committment[2].get_variable(), + self.hidden_fsm_input_committment[3].get_variable(), + self.hidden_fsm_output_committment[0].get_variable(), + self.hidden_fsm_output_committment[1].get_variable(), + self.hidden_fsm_output_committment[2].get_variable(), + self.hidden_fsm_output_committment[3].get_variable(), + ] + } + fn set_internal_variables_values(witness: Self::Witness, dst: &mut DstBuffer<'_, '_, F>) { + // NOTE: must be same sequence as in `flatten_as_variables` + Boolean::set_internal_variables_values(witness.start_flag, dst); + Boolean::set_internal_variables_values(witness.completion_flag, dst); + for src in witness.observable_input_committment.into_iter() { + Num::set_internal_variables_values(src, dst); + } + for src in witness.observable_output_committment.into_iter() { + Num::set_internal_variables_values(src, dst); + } + for src in witness.hidden_fsm_input_committment.into_iter() { + Num::set_internal_variables_values(src, dst); + } + for src in witness.hidden_fsm_output_committment.into_iter() { + Num::set_internal_variables_values(src, dst); + } + } +} + impl ClosedFormInputCompactForm { pub fn from_full_form< CS: ConstraintSystem, @@ -181,16 +284,19 @@ impl ClosedFormInputCompactForm { + std::fmt::Debug + CSAllocatable + CircuitVarLengthEncodable + + WitnessVarLengthEncodable + WitnessHookable, IN: Clone + std::fmt::Debug + CSAllocatable + CircuitVarLengthEncodable + + WitnessVarLengthEncodable + WitnessHookable, OUT: Clone + std::fmt::Debug + CSAllocatable + CircuitVarLengthEncodable + + WitnessVarLengthEncodable + WitnessHookable, R: CircuitRoundFunction, >( diff --git a/crates/zkevm_circuits/src/keccak256_round_function/buffer/mod.rs b/crates/zkevm_circuits/src/keccak256_round_function/buffer/mod.rs index 6747331..1c5a5f4 100644 --- a/crates/zkevm_circuits/src/keccak256_round_function/buffer/mod.rs +++ b/crates/zkevm_circuits/src/keccak256_round_function/buffer/mod.rs @@ -2,7 +2,14 @@ use super::*; use crate::boojum::gadgets::traits::auxiliary::PrettyComparison; use crate::boojum::serde_utils::BigArraySerde; -#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug)] #[DerivePrettyComparison("true")] pub struct ByteBuffer { diff --git a/crates/zkevm_circuits/src/keccak256_round_function/input.rs b/crates/zkevm_circuits/src/keccak256_round_function/input.rs index 480b518..a8cb8e8 100644 --- a/crates/zkevm_circuits/src/keccak256_round_function/input.rs +++ b/crates/zkevm_circuits/src/keccak256_round_function/input.rs @@ -10,6 +10,7 @@ use boojum::gadgets::queue::*; use boojum::gadgets::traits::allocatable::CSAllocatable; use boojum::gadgets::traits::allocatable::CSPlaceholder; use boojum::gadgets::traits::encodable::CircuitVarLengthEncodable; +use boojum::gadgets::traits::encodable::WitnessVarLengthEncodable; use boojum::cs::traits::cs::ConstraintSystem; use boojum::field::SmallField; @@ -23,7 +24,14 @@ use boojum::serde_utils::BigArraySerde; pub const MEMORY_QUERIES_PER_CYCLE: usize = 6; pub const KECCAK_PRECOMPILE_BUFFER_SIZE: usize = MEMORY_QUERIES_PER_CYCLE * 32; -#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug)] #[DerivePrettyComparison("true")] pub struct Keccak256RoundFunctionFSM { @@ -57,7 +65,14 @@ impl CSPlaceholder for Keccak256RoundFunctionFSM { } } -#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug)] #[DerivePrettyComparison("true")] pub struct Keccak256RoundFunctionFSMInputOutput { diff --git a/crates/zkevm_circuits/src/keccak256_round_function/mod.rs b/crates/zkevm_circuits/src/keccak256_round_function/mod.rs index fd524c5..e1b9337 100644 --- a/crates/zkevm_circuits/src/keccak256_round_function/mod.rs +++ b/crates/zkevm_circuits/src/keccak256_round_function/mod.rs @@ -7,7 +7,7 @@ use boojum::cs::traits::cs::ConstraintSystem; use boojum::gadgets::boolean::Boolean; use boojum::gadgets::traits::selectable::Selectable; use boojum::gadgets::traits::witnessable::WitnessHookable; -use boojum::gadgets::u16::UInt16; + use boojum::gadgets::u256::UInt256; use boojum::gadgets::u32::UInt32; use cs_derive::*; @@ -32,6 +32,7 @@ use boojum::gadgets::queue::QueueState; use boojum::gadgets::traits::allocatable::CSAllocatable; use boojum::gadgets::traits::allocatable::{CSAllocatableExt, CSPlaceholder}; use boojum::gadgets::traits::encodable::CircuitVarLengthEncodable; +use boojum::gadgets::traits::encodable::WitnessVarLengthEncodable; use boojum::gadgets::traits::round_function::CircuitRoundFunction; use boojum::gadgets::u160::UInt160; use boojum::gadgets::u8::UInt8; @@ -42,7 +43,14 @@ pub mod buffer; pub mod input; use self::input::*; -#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug)] // #[DerivePrettyComparison("true")] pub struct Keccak256PrecompileCallParams { @@ -839,8 +847,6 @@ pub(crate) fn keccak256_absorb_and_run_permutation::new(geometry, 1 << 20); - use boojum::cs::cs_builder::new_builder; let builder = new_builder::<_, F>(builder_impl); let builder = configure(builder); @@ -1087,7 +1092,7 @@ mod test { assert_eq!(buffer, reference); let _ = owned_cs.pad_and_shrink(); - let mut assembly = owned_cs.into_assembly::(); + let mut assembly = owned_cs.into_assembly::(); let worker = Worker::new(); let is_satisfied = assembly.check_if_satisfied(&worker); assert!(is_satisfied); diff --git a/crates/zkevm_circuits/src/lib.rs b/crates/zkevm_circuits/src/lib.rs index fe4420c..757211a 100644 --- a/crates/zkevm_circuits/src/lib.rs +++ b/crates/zkevm_circuits/src/lib.rs @@ -1,7 +1,7 @@ #![allow(clippy::drop_ref)] #![allow(dead_code)] #![allow(dropping_references)] -#![allow(unused_imports)] +#![allow(incomplete_features)] #![feature(generic_const_exprs)] #![feature(array_chunks)] #![feature(more_qualified_paths)] @@ -27,11 +27,13 @@ pub mod main_vm; pub mod ram_permutation; pub mod recursion; pub mod scheduler; +pub mod secp256r1_verify; pub mod sha256_round_function; pub mod sort_decommittment_requests; pub mod storage_application; pub mod storage_validity_by_grand_product; pub mod tables; +pub mod transient_storage_validity_by_grand_product; pub mod utils; use boojum::pairing::ff; diff --git a/crates/zkevm_circuits/src/linear_hasher/input.rs b/crates/zkevm_circuits/src/linear_hasher/input.rs index 9ed2817..c479618 100644 --- a/crates/zkevm_circuits/src/linear_hasher/input.rs +++ b/crates/zkevm_circuits/src/linear_hasher/input.rs @@ -4,24 +4,30 @@ use crate::base_structures::{ }; use boojum::cs::{traits::cs::ConstraintSystem, Variable}; use boojum::field::SmallField; -use boojum::gadgets::keccak256; + use boojum::gadgets::traits::auxiliary::PrettyComparison; -use boojum::gadgets::u32::UInt32; + use boojum::gadgets::u8::UInt8; use boojum::gadgets::{ boolean::Boolean, queue::*, traits::{ - allocatable::*, encodable::CircuitVarLengthEncodable, selectable::Selectable, - witnessable::WitnessHookable, + allocatable::*, encodable::CircuitVarLengthEncodable, encodable::WitnessVarLengthEncodable, + selectable::Selectable, witnessable::WitnessHookable, }, }; use boojum::serde_utils::BigArraySerde; use cs_derive::*; use derivative::*; -use std::collections::VecDeque; -#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug)] #[DerivePrettyComparison("true")] pub struct LinearHasherInputData { @@ -36,7 +42,14 @@ impl CSPlaceholder for LinearHasherInputData { } } -#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug)] #[DerivePrettyComparison("true")] pub struct LinearHasherOutputData { diff --git a/crates/zkevm_circuits/src/linear_hasher/mod.rs b/crates/zkevm_circuits/src/linear_hasher/mod.rs index 2409b3c..8f8236b 100644 --- a/crates/zkevm_circuits/src/linear_hasher/mod.rs +++ b/crates/zkevm_circuits/src/linear_hasher/mod.rs @@ -1,31 +1,29 @@ -use std::collections::VecDeque; use std::mem::MaybeUninit; use crate::base_structures::log_query::LogQuery; -use crate::base_structures::state_diff_record::StateDiffRecord; + use crate::demux_log_queue::StorageLogQueue; -use crate::ethereum_types::U256; + use crate::fsm_input_output::circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH; -use crate::keccak256_round_function::keccak256_absorb_and_run_permutation; + use boojum::algebraic_props::round_function::AlgebraicRoundFunction; -use boojum::config::*; -use boojum::cs::traits::cs::{ConstraintSystem, DstBuffer}; -use boojum::cs::{Place, Variable}; + +use boojum::cs::traits::cs::ConstraintSystem; + use boojum::field::SmallField; use boojum::gadgets::boolean::Boolean; use boojum::gadgets::keccak256; use boojum::gadgets::num::Num; use boojum::gadgets::queue::CircuitQueueWitness; -use boojum::gadgets::queue::QueueState; -use boojum::gadgets::traits::allocatable::{CSAllocatable, CSAllocatableExt, CSPlaceholder}; -use boojum::gadgets::traits::castable::WitnessCastable; + +use boojum::gadgets::traits::allocatable::{CSAllocatableExt, CSPlaceholder}; + use boojum::gadgets::traits::round_function::CircuitRoundFunction; use boojum::gadgets::traits::selectable::Selectable; use boojum::gadgets::u256::UInt256; -use boojum::gadgets::u32::UInt32; + use boojum::gadgets::u8::UInt8; -use std::sync::{Arc, RwLock}; -use zkevm_opcode_defs::system_params::STORAGE_AUX_BYTE; +use std::sync::Arc; use super::*; @@ -81,7 +79,6 @@ where let mut keccak_accumulator_state = keccak_accumulator_state.map(|el| el.map(|el| el.map(|el| el.get_variable()))); - use crate::base_structures::log_query::L2_TO_L1_MESSAGE_BYTE_LENGTH; // we do not serialize length because it's recalculatable in L1 let empty_hash = { diff --git a/crates/zkevm_circuits/src/log_sorter/input.rs b/crates/zkevm_circuits/src/log_sorter/input.rs index ee2d1de..04f7cf1 100644 --- a/crates/zkevm_circuits/src/log_sorter/input.rs +++ b/crates/zkevm_circuits/src/log_sorter/input.rs @@ -12,8 +12,8 @@ use boojum::gadgets::{ num::Num, queue::*, traits::{ - allocatable::*, encodable::CircuitVarLengthEncodable, selectable::Selectable, - witnessable::WitnessHookable, + allocatable::*, encodable::CircuitVarLengthEncodable, encodable::WitnessVarLengthEncodable, + selectable::Selectable, witnessable::WitnessHookable, }, }; use boojum::serde_utils::BigArraySerde; @@ -22,7 +22,14 @@ use derivative::*; use crate::DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS; -#[derive(Derivative, CSAllocatable, CSVarLengthEncodable, CSSelectable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSVarLengthEncodable, + CSSelectable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug)] #[DerivePrettyComparison("true")] pub struct EventsDeduplicatorFSMInputOutput { @@ -51,7 +58,14 @@ impl CSPlaceholder for EventsDeduplicatorFSMInputOutput { } } -#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug)] #[DerivePrettyComparison("true")] pub struct EventsDeduplicatorInputData { @@ -68,7 +82,14 @@ impl CSPlaceholder for EventsDeduplicatorInputData { } } -#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug)] #[DerivePrettyComparison("true")] pub struct EventsDeduplicatorOutputData { diff --git a/crates/zkevm_circuits/src/log_sorter/mod.rs b/crates/zkevm_circuits/src/log_sorter/mod.rs index be217ba..fd8fe27 100644 --- a/crates/zkevm_circuits/src/log_sorter/mod.rs +++ b/crates/zkevm_circuits/src/log_sorter/mod.rs @@ -470,11 +470,9 @@ pub fn prepacked_long_comparison>( #[cfg(test)] mod tests { - use std::alloc::Global; - use super::*; use boojum::algebraic_props::poseidon2_parameters::Poseidon2GoldilocksExternalMatrix; - use boojum::cs::implementations::reference_cs::CSDevelopmentAssembly; + use boojum::cs::traits::gate::GatePlacementStrategy; use boojum::cs::CSGeometry; use boojum::cs::*; @@ -630,7 +628,7 @@ mod tests { cs.pad_and_shrink(); let worker = Worker::new(); - let mut owned_cs = owned_cs.into_assembly::(); + let mut owned_cs = owned_cs.into_assembly::(); owned_cs.print_gate_stats(); assert!(owned_cs.check_if_satisfied(&worker)); } diff --git a/crates/zkevm_circuits/src/main_vm/cycle.rs b/crates/zkevm_circuits/src/main_vm/cycle.rs index 1e70c5b..b4c28bf 100644 --- a/crates/zkevm_circuits/src/main_vm/cycle.rs +++ b/crates/zkevm_circuits/src/main_vm/cycle.rs @@ -1,6 +1,5 @@ use arrayvec::ArrayVec; -use super::opcodes::context::apply_context; use super::pre_state::{create_prestate, PendingSponge}; use super::state_diffs::{ StateDiffsAccumulator, MAX_ADD_SUB_RELATIONS_PER_CYCLE, MAX_MUL_DIV_RELATIONS_PER_CYCLE, @@ -54,6 +53,13 @@ where dbg!(_current_state.pending_exception); dbg!(_current_state.callstack.current_context.saved_context.pc); dbg!(_current_state.flags); + dbg!( + _current_state + .callstack + .current_context + .saved_context + .ergs_remaining + ); } let (draft_next_state, common_opcode_state, opcode_carry_parts) = @@ -462,10 +468,10 @@ where ); } - // Ergs per pubdata - for (flag, value) in diffs_accumulator.new_ergs_per_pubdata.into_iter() { - new_state.ergs_per_pubdata_byte = - UInt32::conditionally_select(cs, flag, &value, &new_state.ergs_per_pubdata_byte); + // Pubdata revert counter at the global state + for (flag, value) in diffs_accumulator.new_pubdata_revert_counter.into_iter() { + new_state.pubdata_revert_counter = + UInt32::conditionally_select(cs, flag, &value, &new_state.pubdata_revert_counter); } // Tx number in block @@ -483,6 +489,49 @@ where UInt32::parallel_select(cs, flag, &value, &new_state.context_composite_u128); } + // pubdata counters + for (flag, cost) in diffs_accumulator.pubdata_cost.into_iter() { + let new_pubdata_revert_counter = + i32_add_no_overflow(cs, &new_state.pubdata_revert_counter, &cost); + let new_current_frame_pubdata_counter = i32_add_no_overflow( + cs, + &new_state + .callstack + .current_context + .saved_context + .total_pubdata_spent, + &cost, + ); + + new_state.pubdata_revert_counter = UInt32::conditionally_select( + cs, + flag, + &new_pubdata_revert_counter, + &new_state.pubdata_revert_counter, + ); + new_state + .callstack + .current_context + .saved_context + .total_pubdata_spent = UInt32::conditionally_select( + cs, + flag, + &new_current_frame_pubdata_counter, + &new_state + .callstack + .current_context + .saved_context + .total_pubdata_spent, + ); + } + + // global pubdata reverts counter can not be < 0 + { + let le_bytes = new_state.pubdata_revert_counter.to_le_bytes(cs); + let is_negative = test_if_bit_is_set(cs, &le_bytes[3], 7); + Boolean::enforce_equal(cs, &is_negative, &boolean_false); + } + // Heap limit for (flag, value) in diffs_accumulator.new_heap_bounds.drain(..) { new_state @@ -530,7 +579,7 @@ where Num::parallel_select(cs, flag, &state, &new_state.memory_queue_state); } - // decommittment due to far call + // decommittment due to far call or log.decommit for (flag, length, state) in diffs_accumulator.decommitment_queue_candidates.into_iter() { new_state.code_decommittment_queue_length = UInt32::conditionally_select( cs, @@ -786,7 +835,7 @@ where if crate::config::CIRCUIT_VERSOBE { // synchronization point let _wit = new_state.witness_hook(&*cs)().unwrap(); - // dbg!(_wit.memory_queue_state); + dbg!(_wit.registers); // dbg!(_wit.memory_queue_length); println!("End of cycle"); } diff --git a/crates/zkevm_circuits/src/main_vm/loading.rs b/crates/zkevm_circuits/src/main_vm/loading.rs index 7b4d0cb..9084e92 100644 --- a/crates/zkevm_circuits/src/main_vm/loading.rs +++ b/crates/zkevm_circuits/src/main_vm/loading.rs @@ -90,83 +90,29 @@ pub fn initial_bootloader_state< let callstack_empty_state = [zero_num; FULL_SPONGE_QUEUE_STATE_WIDTH]; let mut current_state = callstack_empty_state.map(|el| el.get_variable()); - - // absorb by replacement - let round_0_initial = [ - empty_entry_encoding[0], - empty_entry_encoding[1], - empty_entry_encoding[2], - empty_entry_encoding[3], - empty_entry_encoding[4], - empty_entry_encoding[5], - empty_entry_encoding[6], - empty_entry_encoding[7], - current_state[8], - current_state[9], - current_state[10], - current_state[11], - ]; - - let round_0_final = R::compute_round_function(cs, round_0_initial); - - current_state = round_0_final; - - let round_1_initial = [ - empty_entry_encoding[8], - empty_entry_encoding[9], - empty_entry_encoding[10], - empty_entry_encoding[11], - empty_entry_encoding[12], - empty_entry_encoding[13], - empty_entry_encoding[14], - empty_entry_encoding[15], - current_state[8], - current_state[9], - current_state[10], - current_state[11], - ]; - - let round_1_final = R::compute_round_function(cs, round_1_initial); - - current_state = round_1_final; - - let round_2_initial = [ - empty_entry_encoding[16], - empty_entry_encoding[17], - empty_entry_encoding[18], - empty_entry_encoding[19], - empty_entry_encoding[20], - empty_entry_encoding[21], - empty_entry_encoding[22], - empty_entry_encoding[23], - current_state[8], - current_state[9], - current_state[10], - current_state[11], - ]; - - let round_2_final = R::compute_round_function(cs, round_2_initial); - - current_state = round_2_final; - - let round_3_initial = [ - empty_entry_encoding[24], - empty_entry_encoding[25], - empty_entry_encoding[26], - empty_entry_encoding[27], - empty_entry_encoding[28], - empty_entry_encoding[29], - empty_entry_encoding[30], - empty_entry_encoding[31], - current_state[8], - current_state[9], - current_state[10], - current_state[11], - ]; - - let round_3_final = R::compute_round_function(cs, round_3_initial); - - current_state = round_3_final; + assert!(empty_entry_encoding.len() % 8 == 0); + + for encoding_chunk in empty_entry_encoding.array_chunks::<8>() { + // absorb by replacement + let initial_state = [ + encoding_chunk[0], + encoding_chunk[1], + encoding_chunk[2], + encoding_chunk[3], + encoding_chunk[4], + encoding_chunk[5], + encoding_chunk[6], + encoding_chunk[7], + current_state[8], + current_state[9], + current_state[10], + current_state[11], + ]; + + let final_state = R::compute_round_function(cs, initial_state); + + current_state = final_state; + } let callstack_initial_state = current_state.map(|el| Num::from_variable(el)); diff --git a/crates/zkevm_circuits/src/main_vm/opcode_bitmask.rs b/crates/zkevm_circuits/src/main_vm/opcode_bitmask.rs index f0398f3..4b30589 100644 --- a/crates/zkevm_circuits/src/main_vm/opcode_bitmask.rs +++ b/crates/zkevm_circuits/src/main_vm/opcode_bitmask.rs @@ -13,7 +13,7 @@ use zkevm_opcode_defs::{ // opcode defs only provide runtime-computeable variable, so we have to pin ISA version and assert -pub const SUPPORTED_ISA_VERSION: ISAVersion = ISAVersion(1); +pub const SUPPORTED_ISA_VERSION: ISAVersion = ISAVersion(2); const _: () = if SUPPORTED_ISA_VERSION.0 != zkevm_opcode_defs::DEFAULT_ISA_VERSION.0 { panic!() diff --git a/crates/zkevm_circuits/src/main_vm/opcodes/call_ret.rs b/crates/zkevm_circuits/src/main_vm/opcodes/call_ret.rs index 3fb6e5c..e7267a8 100644 --- a/crates/zkevm_circuits/src/main_vm/opcodes/call_ret.rs +++ b/crates/zkevm_circuits/src/main_vm/opcodes/call_ret.rs @@ -114,6 +114,7 @@ pub(crate) fn apply_calls_and_ret< specific_registers_updates: specific_registers_updates_for_ret, specific_registers_zeroing: specific_registers_zeroing_for_ret, remove_ptr_on_specific_registers: remove_ptr_on_specific_registers_for_ret, + new_pubdata_revert_counter: new_pubdata_revert_counter_for_ret, } = ret_data; let is_call_like = Boolean::multi_or(cs, &[apply_near_call, apply_far_call]); @@ -183,86 +184,32 @@ pub(crate) fn apply_calls_and_ret< use boojum::gadgets::round_function::simulate_round_function; - // absorb by replacement - let round_0_initial = [ - encoded_execution_record[0], - encoded_execution_record[1], - encoded_execution_record[2], - encoded_execution_record[3], - encoded_execution_record[4], - encoded_execution_record[5], - encoded_execution_record[6], - encoded_execution_record[7], - current_state[8], - current_state[9], - current_state[10], - current_state[11], - ]; - - let round_0_final = - simulate_round_function::<_, _, 8, 12, 4, R>(cs, round_0_initial, apply_any); - - current_state = round_0_final; - - let round_1_initial = [ - encoded_execution_record[8], - encoded_execution_record[9], - encoded_execution_record[10], - encoded_execution_record[11], - encoded_execution_record[12], - encoded_execution_record[13], - encoded_execution_record[14], - encoded_execution_record[15], - current_state[8], - current_state[9], - current_state[10], - current_state[11], - ]; - - let round_1_final = - simulate_round_function::<_, _, 8, 12, 4, R>(cs, round_1_initial, apply_any); - - current_state = round_1_final; - - let round_2_initial = [ - encoded_execution_record[16], - encoded_execution_record[17], - encoded_execution_record[18], - encoded_execution_record[19], - encoded_execution_record[20], - encoded_execution_record[21], - encoded_execution_record[22], - encoded_execution_record[23], - current_state[8], - current_state[9], - current_state[10], - current_state[11], - ]; - - let round_2_final = - simulate_round_function::<_, _, 8, 12, 4, R>(cs, round_2_initial, apply_any); - - current_state = round_2_final; - - let round_3_initial = [ - encoded_execution_record[24], - encoded_execution_record[25], - encoded_execution_record[26], - encoded_execution_record[27], - encoded_execution_record[28], - encoded_execution_record[29], - encoded_execution_record[30], - encoded_execution_record[31], - current_state[8], - current_state[9], - current_state[10], - current_state[11], - ]; - - let round_3_final = - simulate_round_function::<_, _, 8, 12, 4, R>(cs, round_3_initial, apply_any); - - current_state = round_3_final; + let mut all_states = ArrayVec::<_, 5>::new(); + assert!(encoded_execution_record.len() % 8 == 0); + for encoding_chunk in encoded_execution_record.array_chunks::<8>() { + // absorb by replacement + let round_initial = [ + encoding_chunk[0], + encoding_chunk[1], + encoding_chunk[2], + encoding_chunk[3], + encoding_chunk[4], + encoding_chunk[5], + encoding_chunk[6], + encoding_chunk[7], + current_state[8], + current_state[9], + current_state[10], + current_state[11], + ]; + + let round_final = + simulate_round_function::<_, _, 8, 12, 4, R>(cs, round_initial, apply_any); + + current_state = round_final; + + all_states.push((round_initial, round_final)); + } let potential_final_state = current_state.map(|el| Num::from_variable(el)); @@ -339,33 +286,19 @@ pub(crate) fn apply_calls_and_ret< >::new(); // first we push relations that are common, namely callstack sponge - common_relations_buffer.push(( - apply_any, - round_0_initial.map(|el| Num::from_variable(el)), - round_0_final.map(|el| Num::from_variable(el)), - )); - - common_relations_buffer.push(( - apply_any, - round_1_initial.map(|el| Num::from_variable(el)), - round_1_final.map(|el| Num::from_variable(el)), - )); - - common_relations_buffer.push(( - apply_any, - round_2_initial.map(|el| Num::from_variable(el)), - round_2_final.map(|el| Num::from_variable(el)), - )); - - common_relations_buffer.push(( - apply_any, - round_3_initial.map(|el| Num::from_variable(el)), - round_3_final.map(|el| Num::from_variable(el)), - )); + for el in all_states.into_iter() { + common_relations_buffer.push(( + apply_any, + el.0.map(|el| Num::from_variable(el)), + el.1.map(|el| Num::from_variable(el)), + )); + } // and now we append relations for far call, that are responsible for storage read and decommittment common_relations_buffer.extend(pending_sponges_for_far_call); + assert_eq!(common_relations_buffer.len(), 9); + // now just append relations to select later on // all the opcodes reset flags in full @@ -503,10 +436,18 @@ pub(crate) fn apply_calls_and_ret< .context_u128_candidates .push((reset_context_value, empty_context_value)); - debug_assert!(diffs_accumulator.decommitment_queue_candidates.is_none()); - diffs_accumulator.decommitment_queue_candidates = Some(( + diffs_accumulator.decommitment_queue_candidates.push(( apply_far_call, new_decommittment_queue_len, new_decommittment_queue_tail, )); + + let new_pubdata_revert_counter = UInt32::conditionally_select( + cs, + apply_ret, + &new_pubdata_revert_counter_for_ret, + &draft_vm_state.pubdata_revert_counter, + ); + assert!(diffs_accumulator.new_pubdata_revert_counter.is_none()); + diffs_accumulator.new_pubdata_revert_counter = Some((apply_any, new_pubdata_revert_counter)); } diff --git a/crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/far_call.rs b/crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/far_call.rs index 094a864..68af0d5 100644 --- a/crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/far_call.rs +++ b/crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/far_call.rs @@ -18,6 +18,7 @@ use crate::main_vm::opcodes::call_ret_impl::far_call::log_query::LogQueryWitness use crate::main_vm::state_diffs::MAX_SPONGES_PER_CYCLE; use crate::main_vm::witness_oracle::SynchronizedWitnessOracle; use crate::main_vm::witness_oracle::WitnessOracle; +use crate::tables::CallCostsAndStipendsTable; use arrayvec::ArrayVec; use boojum::algebraic_props::round_function::AlgebraicRoundFunction; use boojum::cs::traits::cs::DstBuffer; @@ -333,15 +334,6 @@ where // we need a completely fresh one let mut new_callstack_entry = ExecutionContextRecord::uninitialized(cs); - // apply memory stipends right away - new_callstack_entry.heap_upper_bound = UInt32::allocated_constant( - cs, - zkevm_opcode_defs::system_params::NEW_FRAME_MEMORY_STIPEND, - ); - new_callstack_entry.aux_heap_upper_bound = UInt32::allocated_constant( - cs, - zkevm_opcode_defs::system_params::NEW_FRAME_MEMORY_STIPEND, - ); // now also create target for mimic let implicit_mimic_call_reg = draft_vm_state.registers @@ -421,9 +413,39 @@ where higher_bytes_are_zeroes }; + let target_is_userspace = target_is_kernel.negated(cs); + + if crate::config::CIRCUIT_VERSOBE { + if (execute.witness_hook(&*cs))().unwrap_or(false) { + dbg!(destination_address.witness_hook(cs)().unwrap()); + dbg!(target_is_kernel.witness_hook(cs)().unwrap()); + } + } let mut far_call_abi = *far_call_abi; + // convert ergs + let conversion_constant = UInt32::allocated_constant( + cs, + zkevm_opcode_defs::system_params::INTERNAL_ERGS_TO_VISIBLE_ERGS_CONVERSION_CONSTANT, + ); + let cap = UInt32::allocated_constant(cs, u32::MAX); + far_call_abi.ergs_passed = if cs.gate_is_allowed::() { + let zero_u32 = UInt32::zero(cs); + let [(low, _), (high, _)] = UInt32::fma_with_carry( + cs, + far_call_abi.ergs_passed, + conversion_constant, + zero_u32, + zero_u32, + ); + let fits_u32 = high.is_zero(cs); + + UInt32::conditionally_select(cs, fits_u32, &low, &cap) + } else { + unimplemented!() + }; + // mask flags in ABI if not applicable far_call_abi.constructor_call = Boolean::multi_and(cs, &[far_call_abi.constructor_call, is_kernel_mode]); @@ -432,6 +454,7 @@ where if crate::config::CIRCUIT_VERSOBE { if execute.witness_hook(&*cs)().unwrap_or(false) { + dbg!(opcode_carry_parts.preliminary_ergs_left.witness_hook(&*cs)().unwrap()); dbg!(forwarding_data.witness_hook(&*cs)().unwrap()); dbg!(far_call_abi.witness_hook(&*cs)().unwrap()); } @@ -460,165 +483,266 @@ where let mut all_pending_sponges = ArrayVec::new(); - let (bytecode_hash_is_trivial, bytecode_hash, (new_forward_queue_tail, new_forward_queue_len)) = - may_be_read_code_hash( - cs, - &mut all_pending_sponges, - &destination_address, - &destination_shard, - &target_is_zkporter, - &global_context.zkporter_is_available, - &execute, - &global_context.default_aa_code_hash, - &target_is_kernel, - draft_vm_state - .callstack - .current_context - .log_queue_forward_tail, - draft_vm_state - .callstack - .current_context - .log_queue_forward_part_length, - timestamp_to_use_for_decommittment_request, - draft_vm_state.tx_number_in_block, - witness_oracle, - round_function, - ); + let ( + call_to_unreachable, + bytecode_hash_from_storage, + (new_forward_queue_tail, new_forward_queue_len), + ) = may_be_read_code_hash( + cs, + &mut all_pending_sponges, + &destination_address, + &destination_shard, + &target_is_zkporter, + &global_context.zkporter_is_available, + &execute, + draft_vm_state + .callstack + .current_context + .log_queue_forward_tail, + draft_vm_state + .callstack + .current_context + .log_queue_forward_part_length, + timestamp_to_use_for_decommittment_request, + draft_vm_state.tx_number_in_block, + witness_oracle, + round_function, + ); - // now we should do validation BEFORE decommittment + assert_eq!(all_pending_sponges.len(), 3); - let zero_u32 = UInt32::zero(cs); + // exceptions, along with `map_to_trivial` indicate whether we will or will decommit code + // into memory, or will just use UNMAPPED_PAGE + let mut exceptions = ArrayVec::, 6>::new(); + exceptions.push(call_to_unreachable); + if crate::config::CIRCUIT_VERSOBE { + if execute.witness_hook(&*cs)().unwrap() { + dbg!(call_to_unreachable.witness_hook(&*cs)().unwrap()); + } + } - let target_code_memory_page = UInt32::conditionally_select( - cs, - bytecode_hash_is_trivial, - &zero_u32, - &default_target_memory_page, - ); + // now we should do validation BEFORE decommittment + let zero_u32 = UInt32::zero(cs); + let limbs_are_zero = bytecode_hash_from_storage.inner.map(|el| el.is_zero(cs)); + let bytecode_is_empty = Boolean::multi_and(cs, &limbs_are_zero); // first we validate if code hash is indeed in the format that we expect // If we do not do "constructor call" then 2nd byte should be 0, // otherwise it's 1 - let bytecode_hash_upper_decomposition = bytecode_hash.inner[7].decompose_into_bytes(cs); + let bytecode_hash_from_storage_upper_decomposition = + bytecode_hash_from_storage.inner[7].decompose_into_bytes(cs); - let version_byte = bytecode_hash_upper_decomposition[3]; - let code_hash_version_byte = - UInt8::allocated_constant(cs, zkevm_opcode_defs::ContractCodeSha256::VERSION_BYTE); - let versioned_byte_is_valid = UInt8::equals(cs, &version_byte, &code_hash_version_byte); - let versioned_byte_is_invalid = versioned_byte_is_valid.negated(cs); + let version_byte = bytecode_hash_from_storage_upper_decomposition[3]; + let code_hash_version_byte = UInt8::allocated_constant( + cs, + zkevm_opcode_defs::ContractCodeSha256Format::VERSION_BYTE, + ); + let blob_version_byte = + UInt8::allocated_constant(cs, zkevm_opcode_defs::BlobSha256Format::VERSION_BYTE); - let marker_byte = bytecode_hash_upper_decomposition[2]; - let is_normal_call_marker = marker_byte.is_zero(cs); + assert_eq!( + zkevm_opcode_defs::ContractCodeSha256Format::CODE_AT_REST_MARKER, + zkevm_opcode_defs::BlobSha256Format::CODE_AT_REST_MARKER + ); + assert_eq!( + zkevm_opcode_defs::ContractCodeSha256Format::YET_CONSTRUCTED_MARKER, + zkevm_opcode_defs::BlobSha256Format::YET_CONSTRUCTED_MARKER + ); + + let code_at_rest_version_byte = UInt8::allocated_constant( + cs, + zkevm_opcode_defs::ContractCodeSha256Format::CODE_AT_REST_MARKER, + ); let now_in_construction_marker_byte = UInt8::allocated_constant( cs, - zkevm_opcode_defs::ContractCodeSha256::YET_CONSTRUCTED_MARKER, + zkevm_opcode_defs::ContractCodeSha256Format::YET_CONSTRUCTED_MARKER, ); + + let versioned_byte_is_native_code = UInt8::equals(cs, &version_byte, &code_hash_version_byte); + let versioned_byte_is_evm_bytecode = UInt8::equals(cs, &version_byte, &blob_version_byte); + + let marker_byte = bytecode_hash_from_storage_upper_decomposition[2]; + let is_code_at_rest_marker = UInt8::equals(cs, &marker_byte, &code_at_rest_version_byte); let is_constructor_call_marker = UInt8::equals(cs, &marker_byte, &now_in_construction_marker_byte); - let unknown_marker = - Boolean::multi_or(cs, &[is_normal_call_marker, is_constructor_call_marker]).negated(cs); - // NOTE: if bytecode hash is trivial then it's 0, so version byte is not valid! - let code_format_exception = Boolean::multi_or(cs, &[versioned_byte_is_invalid, unknown_marker]); + let abi_is_normal_call = far_call_abi.constructor_call.negated(cs); - // we do not remask right away yet + let normal_call_markers_match = + Boolean::multi_and(cs, &[abi_is_normal_call, is_code_at_rest_marker]); - let normal_call_code = far_call_abi.constructor_call.negated(cs); + let constructor_call_markers_match = Boolean::multi_and( + cs, + &[far_call_abi.constructor_call, is_constructor_call_marker], + ); - let can_call_normally = Boolean::multi_and(cs, &[is_normal_call_marker, normal_call_code]); - let can_call_constructor = Boolean::multi_and( + let markers_match = Boolean::multi_or( cs, - &[is_constructor_call_marker, far_call_abi.constructor_call], + &[normal_call_markers_match, constructor_call_markers_match], ); - let can_call_code = Boolean::multi_or(cs, &[can_call_normally, can_call_constructor]); + let markers_mismatch = markers_match.negated(cs); - let marker_byte_masked = UInt8::allocated_constant( + let can_call_native_without_masking = + Boolean::multi_and(cs, &[markers_match, versioned_byte_is_native_code]); + let can_not_call_native_without_masking = + Boolean::multi_and(cs, &[markers_mismatch, versioned_byte_is_native_code]); + let should_mask_native = Boolean::multi_and( cs, - zkevm_opcode_defs::ContractCodeSha256::CODE_AT_REST_MARKER, + &[can_not_call_native_without_masking, target_is_userspace], ); + let mask_to_default_aa = should_mask_native; + let exception_over_native_bytecode_format = + Boolean::multi_and(cs, &[can_not_call_native_without_masking, target_is_kernel]); + + // same logic for EVM simulator + let can_call_evm_simulator_without_masking = + Boolean::multi_and(cs, &[markers_match, versioned_byte_is_evm_bytecode]); - let bytecode_at_rest_top_word = UInt32::from_le_bytes( + let can_not_call_evm_simulator_without_masking = + Boolean::multi_and(cs, &[markers_mismatch, versioned_byte_is_evm_bytecode]); + let should_mask_evm_simulator = Boolean::multi_and( cs, - [ - bytecode_hash_upper_decomposition[0], - bytecode_hash_upper_decomposition[1], - marker_byte_masked, - code_hash_version_byte, + &[ + can_not_call_evm_simulator_without_masking, + target_is_userspace, ], ); + let mask_to_default_aa = + Boolean::multi_or(cs, &[mask_to_default_aa, should_mask_evm_simulator]); + let exception_over_evm_simulator_bytecode_format = Boolean::multi_and( + cs, + &[can_not_call_evm_simulator_without_masking, target_is_kernel], + ); - let mut bytecode_at_storage_format = bytecode_hash; - bytecode_at_storage_format.inner[7] = bytecode_at_rest_top_word; + // and over empty bytecode + let mask_empty_to_default_aa = + Boolean::multi_and(cs, &[bytecode_is_empty, target_is_userspace]); + let mask_to_default_aa = Boolean::multi_or(cs, &[mask_to_default_aa, mask_empty_to_default_aa]); + let exception_over_empty_bytecode = + Boolean::multi_and(cs, &[bytecode_is_empty, target_is_kernel]); + if crate::config::CIRCUIT_VERSOBE { + if execute.witness_hook(&*cs)().unwrap() { + dbg!(exception_over_native_bytecode_format.witness_hook(&*cs)().unwrap()); + dbg!(exception_over_evm_simulator_bytecode_format.witness_hook(&*cs)().unwrap()); + dbg!(exception_over_empty_bytecode.witness_hook(&*cs)().unwrap()); + } + } + let code_format_exception = Boolean::multi_or( + cs, + &[ + exception_over_native_bytecode_format, + exception_over_evm_simulator_bytecode_format, + exception_over_empty_bytecode, + ], + ); + + // our canonical decommitment hash format has upper 4 bytes zeroed out let zero_u256 = UInt256::zero(cs); - let masked_value_if_mask = UInt256::conditionally_select( + let masked_bytecode_hash = UInt256::conditionally_select( cs, - target_is_kernel, - &zero_u256, + mask_to_default_aa, &global_context.default_aa_code_hash, + &bytecode_hash_from_storage, ); - let masked_bytecode_hash = UInt256::conditionally_select( cs, - can_call_code, - &bytecode_at_storage_format, - &masked_value_if_mask, + can_call_evm_simulator_without_masking, + &global_context.evm_simulator_code_hash, + &masked_bytecode_hash, ); + let masked_bytecode_hash = + UInt256::conditionally_select(cs, code_format_exception, &zero_u256, &masked_bytecode_hash); - // at the end of the day all our exceptions will lead to memory page being 0 - - let masked_bytecode_hash_upper_decomposition = - masked_bytecode_hash.inner[7].decompose_into_bytes(cs); + // after that logic of bytecode length is uniform - let mut code_hash_length_in_words = UInt16::from_le_bytes( + // at the end of the day all our exceptions will lead to memory page being 0 + let code_len_encoding_word = masked_bytecode_hash.inner[7]; + let masked_bytecode_hash_upper_decomposition = code_len_encoding_word.to_le_bytes(cs); + let code_hash_length_in_words = UInt16::from_le_bytes( cs, [ masked_bytecode_hash_upper_decomposition[0], masked_bytecode_hash_upper_decomposition[1], ], ); - code_hash_length_in_words = code_hash_length_in_words.mask_negated(cs, code_format_exception); - - // if we call now-in-construction system contract, then we formally mask into 0 (even though it's not needed), - // and we should put an exception here - let can_not_call_code = can_call_code.negated(cs); - let call_now_in_construction_kernel = - Boolean::multi_and(cs, &[can_not_call_code, target_is_kernel]); - - // exceptions, along with `bytecode_hash_is_trivial` indicate whether we will or will decommit code - // into memory, or will just use UNMAPPED_PAGE - let mut exceptions = ArrayVec::, 5>::new(); exceptions.push(code_format_exception); - exceptions.push(call_now_in_construction_kernel); + if crate::config::CIRCUIT_VERSOBE { + if execute.witness_hook(&*cs)().unwrap() { + dbg!(code_format_exception.witness_hook(&*cs)().unwrap()); + } + } + + // normalize bytecode hash + let mut normalized_preimage = masked_bytecode_hash; + normalize_bytecode_hash_for_decommit(cs, &mut normalized_preimage); // resolve passed ergs, passed calldata page, etc let forward_fat_pointer = forwarding_data.forward_fat_pointer; + let do_not_forward_ptr = forward_fat_pointer.negated(cs); let src0_is_integer = common_opcode_state.src0_view.is_ptr.negated(cs); let fat_ptr_expected_exception = Boolean::multi_and(cs, &[forward_fat_pointer, src0_is_integer]); exceptions.push(fat_ptr_expected_exception); + if crate::config::CIRCUIT_VERSOBE { + if execute.witness_hook(&*cs)().unwrap() { + dbg!(fat_ptr_expected_exception.witness_hook(&*cs)().unwrap()); + } + } + + let non_pointer_expected_exception = Boolean::multi_and( + cs, + &[do_not_forward_ptr, common_opcode_state.src0_view.is_ptr], + ); + exceptions.push(non_pointer_expected_exception); + if crate::config::CIRCUIT_VERSOBE { + if execute.witness_hook(&*cs)().unwrap() { + dbg!(non_pointer_expected_exception.witness_hook(&*cs)().unwrap()); + } + } // add pointer validation cases exceptions.push(common_abi_parts.ptr_validation_data.generally_invalid); + if crate::config::CIRCUIT_VERSOBE { + if execute.witness_hook(&*cs)().unwrap() { + dbg!(common_abi_parts + .ptr_validation_data + .generally_invalid + .witness_hook(&*cs)() + .unwrap()); + } + } exceptions.push(common_abi_parts.ptr_validation_data.is_non_addressable); - - let do_not_forward_ptr = forward_fat_pointer.negated(cs); + if crate::config::CIRCUIT_VERSOBE { + if execute.witness_hook(&*cs)().unwrap() { + dbg!(common_abi_parts + .ptr_validation_data + .is_non_addressable + .witness_hook(&*cs)() + .unwrap()); + } + } let exceptions_collapsed = Boolean::multi_or(cs, &exceptions); - // if crate::config::CIRCUIT_VERSOBE { - // if execute.witness_hook(&*cs)().unwrap() { - // dbg!(code_format_exception.witness_hook(&*cs)().unwrap()); - // dbg!(call_now_in_construction_kernel.witness_hook(&*cs)().unwrap()); - // dbg!(fat_ptr_expected_exception.witness_hook(&*cs)().unwrap()); - // } - // } + if crate::config::CIRCUIT_VERSOBE { + if execute.witness_hook(&*cs)().unwrap() { + dbg!(exceptions_collapsed.witness_hook(&*cs)().unwrap()); + dbg!(can_call_native_without_masking.witness_hook(&*cs)().unwrap()); + dbg!(can_call_evm_simulator_without_masking.witness_hook(&*cs)().unwrap()); + dbg!(fat_ptr_expected_exception.witness_hook(&*cs)().unwrap()); + dbg!(bytecode_hash_from_storage.witness_hook(&*cs)().unwrap()); + dbg!(mask_to_default_aa.witness_hook(&*cs)().unwrap()); + dbg!(code_hash_length_in_words.witness_hook(&*cs)().unwrap()); + dbg!(normalized_preimage.witness_hook(&*cs)().unwrap()); + } + } let fat_ptr = common_abi_parts.fat_ptr; // we readjust before heap resize @@ -693,12 +817,16 @@ where let mut growth_cost = heap_growth.mask(cs, grow_heap); growth_cost = UInt32::conditionally_select(cs, grow_aux_heap, &aux_heap_growth, &growth_cost); - // if crate::config::CIRCUIT_VERSOBE { - // if execute.witness_hook(&*cs)().unwrap() { - // dbg!(opcode_carry_parts.preliminary_ergs_left.witness_hook(&*cs)().unwrap()); - // dbg!(growth_cost.witness_hook(&*cs)().unwrap()); - // } - // } + if crate::config::CIRCUIT_VERSOBE { + if execute.witness_hook(&*cs)().unwrap() { + dbg!(opcode_carry_parts.preliminary_ergs_left.witness_hook(&*cs)().unwrap()); + dbg!(grow_heap.witness_hook(&*cs)().unwrap()); + dbg!(heap_growth.witness_hook(&*cs)().unwrap()); + dbg!(grow_aux_heap.witness_hook(&*cs)().unwrap()); + dbg!(aux_heap_growth.witness_hook(&*cs)().unwrap()); + dbg!(growth_cost.witness_hook(&*cs)().unwrap()); + } + } let (ergs_left_after_growth, uf) = opcode_carry_parts .preliminary_ergs_left @@ -710,11 +838,11 @@ where let ergs_left_after_growth = ergs_left_after_growth.mask_negated(cs, uf); // if not enough - set to 0 exceptions.push(uf); - // if crate::config::CIRCUIT_VERSOBE { - // if execute.witness_hook(&*cs)().unwrap() { - // dbg!(ergs_left_after_growth.witness_hook(&*cs)().unwrap()); - // } - // } + if crate::config::CIRCUIT_VERSOBE { + if execute.witness_hook(&*cs)().unwrap() { + dbg!(ergs_left_after_growth.witness_hook(&*cs)().unwrap()); + } + } current_callstack_entry.heap_upper_bound = UInt32::conditionally_select( cs, @@ -730,43 +858,56 @@ where ¤t_callstack_entry.aux_heap_upper_bound, ); - // now any extra cost - let callee_stipend = if FORCED_ERGS_FOR_MSG_VALUE_SIMUALTOR == false { - zero_u32 - } else { - let is_msg_value_simulator_address_low = - UInt32::allocated_constant(cs, zkevm_opcode_defs::ADDRESS_MSG_VALUE as u32); - let target_low_is_msg_value_simulator = UInt32::equals( - cs, - &destination_address.inner[0], - &is_msg_value_simulator_address_low, - ); - // we know that that msg.value simulator is kernel, so we test equality of low address segment and test for kernel - let target_is_msg_value = - Boolean::multi_and(cs, &[target_is_kernel, target_low_is_msg_value_simulator]); - let is_system_abi = far_call_abi.system_call; - let require_extra = Boolean::multi_and(cs, &[target_is_msg_value, is_system_abi]); - - let additive_cost = UInt32::allocated_constant( - cs, - zkevm_opcode_defs::system_params::MSG_VALUE_SIMULATOR_ADDITIVE_COST, - ); - let max_pubdata_bytes = UInt32::allocated_constant( - cs, - zkevm_opcode_defs::system_params::MSG_VALUE_SIMULATOR_PUBDATA_BYTES_TO_PREPAY, - ); + // we have a separate table that says: + // - how much we force-take from caller and give to callee + // - how much we just give to callee out of thin air + // this is only true for system contracts, so we mask an efficient address - let pubdata_cost = - max_pubdata_bytes.non_widening_mul(cs, &draft_vm_state.ergs_per_pubdata_byte); - let cost = pubdata_cost.add_no_overflow(cs, additive_cost); + let address_low = UInt16::from_le_bytes( + cs, + [ + common_opcode_state.src1_view.u8x32_view[0], + common_opcode_state.src1_view.u8x32_view[1], + ], + ); + let address_low_masked = address_low.mask(cs, target_is_kernel); + let address_low_masked = address_low_masked.mask(cs, far_call_abi.system_call); + let table_id = cs + .get_table_id_for_marker::() + .expect("table of costs and stipends must exist"); + let (default_stipend, default_extra_cost) = + zkevm_opcode_defs::STIPENDS_AND_EXTRA_COSTS_TABLE[0]; + assert_eq!(default_extra_cost, 0); + assert_eq!(default_stipend, 0); + let [callee_stipend, extra_ergs_from_caller_to_callee] = + cs.perform_lookup::<1, 2>(table_id, &[address_low_masked.get_variable()]); + let extra_ergs_from_caller_to_callee = + unsafe { UInt32::from_variable_unchecked(extra_ergs_from_caller_to_callee) }; + let callee_stipend = unsafe { UInt32::from_variable_unchecked(callee_stipend) }; + + let evm_simulator_stipend = + UInt32::allocated_constant(cs, zkevm_opcode_defs::system_params::EVM_SIMULATOR_STIPEND); + let callee_stipend = UInt32::conditionally_select( + cs, + can_call_evm_simulator_without_masking, + &evm_simulator_stipend, + &callee_stipend, + ); - cost.mask(cs, require_extra) - }; + if crate::config::CIRCUIT_VERSOBE { + if execute.witness_hook(&*cs)().unwrap() { + dbg!(address_low.witness_hook(&*cs)().unwrap()); + dbg!(address_low_masked.witness_hook(&*cs)().unwrap()); + dbg!(ergs_left_after_growth.witness_hook(&*cs)().unwrap()); + dbg!(extra_ergs_from_caller_to_callee.witness_hook(&*cs)().unwrap()); + dbg!(callee_stipend.witness_hook(&*cs)().unwrap()); + } + } let (ergs_left_after_extra_costs, uf) = - ergs_left_after_growth.overflowing_sub(cs, callee_stipend); + ergs_left_after_growth.overflowing_sub(cs, extra_ergs_from_caller_to_callee); let ergs_left_after_extra_costs = ergs_left_after_extra_costs.mask_negated(cs, uf); // if not enough - set to 0 - let callee_stipend = callee_stipend.mask_negated(cs, uf); // also set to 0 if we were not able to take it + let extra_ergs_from_caller_to_callee = extra_ergs_from_caller_to_callee.mask_negated(cs, uf); // also set to 0 if we were not able to take it exceptions.push(uf); // now we can indeed decommit @@ -775,14 +916,16 @@ where let valid_execution = exception.negated(cs); let should_decommit = Boolean::multi_and(cs, &[execute, valid_execution]); - let target_code_memory_page = target_code_memory_page.mask(cs, should_decommit); + // We will have a logic of `add_to_decommittment_queue` set it to 0 at the very end if exceptions would happen + let target_code_memory_page = default_target_memory_page; - // if crate::config::CIRCUIT_VERSOBE { - // if execute.witness_hook(&*cs)().unwrap() { - // dbg!(exception.witness_hook(&*cs)().unwrap()); - // dbg!(ergs_left_after_extra_costs.witness_hook(&*cs)().unwrap()); - // } - // } + if crate::config::CIRCUIT_VERSOBE { + if execute.witness_hook(&*cs)().unwrap() { + dbg!(extra_ergs_from_caller_to_callee.witness_hook(&*cs)().unwrap()); + dbg!(exception.witness_hook(&*cs)().unwrap()); + dbg!(ergs_left_after_extra_costs.witness_hook(&*cs)().unwrap()); + } + } let ( not_enough_ergs_to_decommit, @@ -794,7 +937,7 @@ where &mut all_pending_sponges, &should_decommit, &ergs_left_after_extra_costs, - &masked_bytecode_hash, + &normalized_preimage, &code_hash_length_in_words, &draft_vm_state.code_decommittment_queue_state, &draft_vm_state.code_decommittment_queue_length, @@ -804,10 +947,14 @@ where round_function, ); + assert_eq!(all_pending_sponges.len(), 4); + let exception = Boolean::multi_or(cs, &[exception, not_enough_ergs_to_decommit]); if crate::config::CIRCUIT_VERSOBE { if execute.witness_hook(&*cs)().unwrap_or(false) { + dbg!(ergs_remaining_after_decommit.witness_hook(&*cs)().unwrap()); + dbg!(not_enough_ergs_to_decommit.witness_hook(&*cs)().unwrap()); dbg!(exception.witness_hook(&*cs)().unwrap()); } } @@ -847,12 +994,6 @@ where let dst_pc = UInt16::zero(cs); let eh_pc = common_opcode_state.decoded_opcode.imm0; - // if crate::config::CIRCUIT_VERSOBE { - // if execute.witness_hook(&*cs)().unwrap() { - // dbg!(ergs_remaining_after_decommit.witness_hook(&*cs)().unwrap()); - // } - // } - // now we should resolve all passed ergs. That means // that we have to read it from ABI, and then use 63/64 rule let preliminary_ergs_left = ergs_remaining_after_decommit; @@ -866,24 +1007,64 @@ where .mul(cs, &Num::from_variable(constant_63.get_variable())); let max_passable = unsafe { UInt32::from_variable_unchecked(max_passable.get_variable()) }; + if crate::config::CIRCUIT_VERSOBE { + if execute.witness_hook(&*cs)().unwrap_or(false) { + dbg!(max_passable.witness_hook(&*cs)().unwrap()); + } + } + // max passable is <= preliminary_ergs_left from computations above, so it's also safe let leftover = Num::from_variable(preliminary_ergs_left.get_variable()) .sub(cs, &Num::from_variable(max_passable.get_variable())); let leftover = unsafe { UInt32::from_variable_unchecked(leftover.get_variable()) }; let ergs_to_pass = far_call_abi.ergs_passed; + if crate::config::CIRCUIT_VERSOBE { + if execute.witness_hook(&*cs)().unwrap_or(false) { + dbg!(leftover.witness_hook(&*cs)().unwrap()); + dbg!(ergs_to_pass.witness_hook(&*cs)().unwrap()); + } + } + let (remaining_from_max_passable, uf) = max_passable.overflowing_sub(cs, ergs_to_pass); // this one can overflow IF one above underflows, but we are not interested in it's overflow value let (leftover_and_remaining_if_no_uf, _of) = leftover.overflowing_add(cs, remaining_from_max_passable); - let ergs_to_pass = UInt32::conditionally_select(cs, uf, &max_passable, &ergs_to_pass); + if crate::config::CIRCUIT_VERSOBE { + if execute.witness_hook(&*cs)().unwrap_or(false) { + dbg!(remaining_from_max_passable.witness_hook(&*cs)().unwrap()); + dbg!(leftover_and_remaining_if_no_uf.witness_hook(&*cs)().unwrap()); + } + } + let ergs_to_pass = UInt32::conditionally_select(cs, uf, &max_passable, &ergs_to_pass); let remaining_for_this_context = UInt32::conditionally_select(cs, uf, &leftover, &leftover_and_remaining_if_no_uf); + if crate::config::CIRCUIT_VERSOBE { + if execute.witness_hook(&*cs)().unwrap_or(false) { + dbg!(ergs_to_pass.witness_hook(&*cs)().unwrap()); + dbg!(remaining_for_this_context.witness_hook(&*cs)().unwrap()); + dbg!(extra_ergs_from_caller_to_callee.witness_hook(&*cs)().unwrap()); + dbg!(callee_stipend.witness_hook(&*cs)().unwrap()); + } + } + let remaining_ergs_if_pass = remaining_for_this_context; let passed_ergs_if_pass = ergs_to_pass; + // this can not overflow by construction + let passed_ergs_if_pass = unsafe { + UInt32::from_variable_unchecked( + Num::from_variable(passed_ergs_if_pass.get_variable()) + .add( + cs, + &Num::from_variable(extra_ergs_from_caller_to_callee.get_variable()), + ) + .get_variable(), + ) + }; + // but out of thin air stipend must not overflow let passed_ergs_if_pass = passed_ergs_if_pass.add_no_overflow(cs, callee_stipend); current_callstack_entry.ergs_remaining = remaining_ergs_if_pass; @@ -925,12 +1106,14 @@ where cs, &[is_static_call, current_callstack_entry.is_static_execution], ); + // if we call EVM simulator we actually reset static flag + let next_is_static_masked = next_is_static.mask_negated(cs, versioned_byte_is_evm_bytecode); // actually parts to the new one new_callstack_entry.ergs_remaining = passed_ergs_if_pass; new_callstack_entry.pc = dst_pc; new_callstack_entry.exception_handler_loc = eh_pc; - new_callstack_entry.is_static_execution = next_is_static; + new_callstack_entry.is_static_execution = next_is_static_masked; // we need to decide whether new frame is kernel or not for degelatecall let new_frame_is_kernel = Boolean::conditionally_select( @@ -941,6 +1124,26 @@ where ); new_callstack_entry.is_kernel_mode = new_frame_is_kernel; + // heap and aux heaps for kernel mode get extra + let memory_size_stipend_for_kernel = UInt32::allocated_constant( + cs, + zkevm_opcode_defs::system_params::NEW_KERNEL_FRAME_MEMORY_STIPEND, + ); + let memory_size_stipend_for_userspace = UInt32::allocated_constant( + cs, + zkevm_opcode_defs::system_params::NEW_FRAME_MEMORY_STIPEND, + ); + + let memory_stipend = UInt32::conditionally_select( + cs, + new_callstack_entry.is_kernel_mode, + &memory_size_stipend_for_kernel, + &memory_size_stipend_for_userspace, + ); + + new_callstack_entry.heap_upper_bound = memory_stipend; + new_callstack_entry.aux_heap_upper_bound = memory_stipend; + // code part new_callstack_entry.code_shard_id = destination_shard; new_callstack_entry.code_address = destination_address; @@ -1007,24 +1210,28 @@ where let new_r1 = final_fat_ptr.into_register(cs); - if crate::config::CIRCUIT_VERSOBE { - if (execute.witness_hook(&*cs))().unwrap_or(false) { - println!( - "R1 value after far call is {:?}", - new_r1.witness_hook(cs)().unwrap() - ); - } - } - - let one = Num::allocated_constant(cs, F::ONE); + // we put markers of: + // - constructor call + // - system call + // - if EVM simulator - if original code was static - let r2_low = Num::fma( + let original_call_was_static = next_is_static.mask(cs, versioned_byte_is_evm_bytecode); + let r2_low = Num::linear_combination( cs, - &Num::from_variable(far_call_abi.constructor_call.get_variable()), - &one, - &F::ONE, - &Num::from_variable(far_call_abi.system_call.get_variable()), - &F::TWO, + &[ + ( + far_call_abi.constructor_call.get_variable(), + F::from_u64_unchecked(1u64 << 0), + ), + ( + far_call_abi.system_call.get_variable(), + F::from_u64_unchecked(1u64 << 1), + ), + ( + original_call_was_static.get_variable(), + F::from_u64_unchecked(1u64 << 2), + ), + ], ); let r2_low = unsafe { UInt32::from_variable_unchecked(r2_low.get_variable()) }; @@ -1121,8 +1328,6 @@ pub fn may_be_read_code_hash< target_is_zkporter: &Boolean, zkporter_is_available: &Boolean, should_execute: &Boolean, - default_aa_code_hash: &UInt256, - target_is_kernel: &Boolean, forward_queue_tail: [Num; QUEUE_STATE_WIDTH], forward_queue_length: UInt32, timestamp_to_use_for_read_request: UInt32, @@ -1140,12 +1345,11 @@ where let target_is_porter_and_its_available = Boolean::multi_and(cs, &[*target_is_zkporter, *zkporter_is_available]); let target_is_rollup = target_is_zkporter.negated(cs); - let zkporter_is_not_available = zkporter_is_available.negated(cs); let can_read = Boolean::multi_or(cs, &[target_is_rollup, target_is_porter_and_its_available]); + let call_to_unreachable = can_read.negated(cs); + let should_read = Boolean::multi_and(cs, &[*should_execute, can_read]); - let needs_porter_mask = - Boolean::multi_and(cs, &[*target_is_zkporter, zkporter_is_not_available]); let zero_u32 = UInt32::zero(cs); let target_as_u256 = UInt256 { @@ -1225,33 +1429,39 @@ where log.read_value = read_value; log.written_value = read_value; // our convension as in LOG opcode - let code_hash_from_storage = read_value; - - let mut bytecode_hash = code_hash_from_storage; - let limbs_are_zero = bytecode_hash.inner.map(|el| el.is_zero(cs)); - let bytecode_is_empty = Boolean::multi_and(cs, &limbs_are_zero); + // we should access pubdata cost for as it's always logged on storage access + { + let oracle = witness_oracle.clone(); + // we should assemble all the dependencies here, and we will use AllocateExt here + let mut dependencies = + Vec::with_capacity( as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1); + dependencies.push(should_read.get_variable().into()); + dependencies.extend(Place::from_variables(log.flatten_as_variables())); + + // we always access witness, as even for writes we have to get a claimed read value! + let _pubdata_cost = UInt32::allocate_from_closure_and_dependencies( + cs, + move |inputs: &[F]| { + let execute = >::cast_from_source(inputs[0]); + let mut log_query = + [F::ZERO; as CSAllocatableExt>::INTERNAL_STRUCT_LEN]; + log_query.copy_from_slice(&inputs[1..]); + let log_query: LogQueryWitness = + CSAllocatableExt::witness_from_set_of_values(log_query); - let target_is_userspace = target_is_kernel.negated(cs); - let mask_for_default_aa = - Boolean::multi_and(cs, &[should_read, bytecode_is_empty, target_is_userspace]); + let mut guard = oracle.inner.write().expect("not poisoned"); + let witness = guard.get_pubdata_cost_for_query(&log_query, false, execute); + drop(guard); - // mask based on some conventions - // first - mask for default AA - bytecode_hash = UInt256::conditionally_select( - cs, - mask_for_default_aa, - &default_aa_code_hash, - &bytecode_hash, - ); + witness + }, + &dependencies, + ); + } - // - if we couldn't read porter - bytecode_hash = - UInt256::conditionally_select(cs, needs_porter_mask, &zero_u256, &bytecode_hash); + let code_hash_from_storage = read_value; - let dont_mask_to_default_aa = mask_for_default_aa.negated(cs); - let t0 = Boolean::multi_and(cs, &[bytecode_is_empty, dont_mask_to_default_aa]); - let skip_read = should_read.negated(cs); - let bytecode_hash_is_trivial = Boolean::multi_or(cs, &[t0, needs_porter_mask, skip_read]); + let bytecode_hash = code_hash_from_storage; // now process the sponges on whether we did read let (new_forward_queue_tail, new_forward_queue_length) = @@ -1273,7 +1483,7 @@ where ); ( - bytecode_hash_is_trivial, + call_to_unreachable, bytecode_hash, (new_forward_queue_tail, new_forward_queue_length), ) @@ -1456,32 +1666,9 @@ where let num_words_in_bytecode = unsafe { UInt32::from_variable_unchecked(num_words_in_bytecode.get_variable()) }; - let cost_of_decommittment = + let default_cost_of_decommittment = cost_of_decommit_per_word.non_widening_mul(cs, &num_words_in_bytecode); - let (ergs_after_decommit_may_be, uf) = - ergs_remaining.overflowing_sub(cs, cost_of_decommittment); - - let not_enough_ergs_to_decommit = uf; - let have_enough_ergs_to_decommit = uf.negated(cs); - let should_decommit = Boolean::multi_and(cs, &[*should_decommit, have_enough_ergs_to_decommit]); - - // if we do not decommit then we will eventually map into 0 page for 0 extra ergs - let ergs_remaining_after_decommit = UInt32::conditionally_select( - cs, - should_decommit, - &ergs_after_decommit_may_be, - &ergs_remaining, - ); - - if crate::config::CIRCUIT_VERSOBE { - if should_decommit.witness_hook(&*cs)().unwrap() { - dbg!(num_words_in_bytecode.witness_hook(&*cs)().unwrap()); - dbg!(ergs_after_decommit_may_be.witness_hook(&*cs)().unwrap()); - dbg!(ergs_remaining_after_decommit.witness_hook(&*cs)().unwrap()); - } - } - // decommit and return new code page and queue states let boolean_false = Boolean::allocated_constant(cs, false); @@ -1524,19 +1711,100 @@ where ); let is_first = UInt32::equals(cs, &target_memory_page, &suggested_page); + let should_charge_for_decommit = Boolean::multi_and(cs, &[*should_decommit, is_first]); decommittment_request.is_first = is_first; decommittment_request.page = suggested_page; // kind of refund if we didn't decommit - let was_decommitted_before = is_first.negated(cs); + let cost_of_decommittment = default_cost_of_decommittment.mask(cs, should_charge_for_decommit); + + if crate::config::CIRCUIT_VERSOBE { + if should_decommit.witness_hook(&*cs)().unwrap_or(false) { + dbg!(target_memory_page.witness_hook(&*cs)().unwrap()); + dbg!(suggested_page.witness_hook(&*cs)().unwrap()); + dbg!(default_cost_of_decommittment.witness_hook(&*cs)().unwrap()); + dbg!(cost_of_decommittment.witness_hook(&*cs)().unwrap()); + } + } + + let (ergs_after_decommit_may_be, uf) = + ergs_remaining.overflowing_sub(cs, cost_of_decommittment); + + let not_enough_ergs_to_decommit = uf; + let have_enough_ergs_to_decommit = uf.negated(cs); + let should_decommit = Boolean::multi_and(cs, &[*should_decommit, have_enough_ergs_to_decommit]); + + // if we do not decommit then we will eventually map into 0 page, but we didn't spend any computations + let ergs_remaining_after_decommit = UInt32::conditionally_select( + cs, + have_enough_ergs_to_decommit, + &ergs_after_decommit_may_be, + &ergs_remaining, + ); + + if crate::config::CIRCUIT_VERSOBE { + if should_decommit.witness_hook(&*cs)().unwrap() { + dbg!(ergs_remaining.witness_hook(&*cs)().unwrap()); + dbg!(num_words_in_bytecode.witness_hook(&*cs)().unwrap()); + dbg!(default_cost_of_decommittment.witness_hook(&*cs)().unwrap()); + dbg!(cost_of_decommittment.witness_hook(&*cs)().unwrap()); + dbg!(ergs_after_decommit_may_be.witness_hook(&*cs)().unwrap()); + dbg!(should_decommit.witness_hook(&*cs)().unwrap()); + dbg!(have_enough_ergs_to_decommit.witness_hook(&*cs)().unwrap()); + dbg!(ergs_remaining_after_decommit.witness_hook(&*cs)().unwrap()); + } + } - let refund = Boolean::multi_and(cs, &[should_decommit, was_decommitted_before]); + // actually modify queue + let (new_decommittment_queue_tail, new_decommittment_queue_len) = + add_to_decommittment_queue_inner( + cs, + relations_buffer, + &should_decommit, + current_decommittment_queue_tail, + current_decommittment_queue_len, + &decommittment_request, + _round_function, + ); - let ergs_remaining_after_decommit = - UInt32::conditionally_select(cs, refund, &ergs_remaining, &ergs_remaining_after_decommit); + let target_memory_page = decommittment_request.page; + let unmapped_page = UInt32::allocated_constant(cs, UNMAPPED_PAGE); + let target_memory_page = + UInt32::conditionally_select(cs, should_decommit, &target_memory_page, &unmapped_page); + ( + not_enough_ergs_to_decommit, + target_memory_page, + (new_decommittment_queue_tail, new_decommittment_queue_len), + ergs_remaining_after_decommit, + ) +} + +pub(crate) fn add_to_decommittment_queue_inner< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, +>( + cs: &mut CS, + relations_buffer: &mut ArrayVec< + ( + Boolean, + [Num; FULL_SPONGE_QUEUE_STATE_WIDTH], + [Num; FULL_SPONGE_QUEUE_STATE_WIDTH], + ), + MAX_SPONGES_PER_CYCLE, + >, + should_add: &Boolean, + current_decommittment_queue_tail: &[Num; FULL_SPONGE_QUEUE_STATE_WIDTH], + current_decommittment_queue_len: &UInt32, + decommittment_request: &DecommitQuery, + _round_function: &R, +) -> ([Num; FULL_SPONGE_QUEUE_STATE_WIDTH], UInt32) +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ use boojum::gadgets::traits::encodable::CircuitEncodable; let encoded_request = decommittment_request.encode(cs); @@ -1561,11 +1829,10 @@ where // NOTE: since we do merged call/ret, we simulate proper relations here always, // because we will do join enforcement on call/ret - let final_state = - simulate_round_function::<_, _, 8, 12, 4, R>(cs, initial_state, should_decommit); + let final_state = simulate_round_function::<_, _, 8, 12, 4, R>(cs, initial_state, *should_add); relations_buffer.push(( - should_decommit, + *should_add, initial_state.map(|el| Num::from_variable(el)), final_state.map(|el| Num::from_variable(el)), )); @@ -1574,7 +1841,7 @@ where let new_decommittment_queue_tail = Num::parallel_select( cs, - should_decommit, + *should_add, &final_state, ¤t_decommittment_queue_tail, ); @@ -1583,21 +1850,10 @@ where unsafe { current_decommittment_queue_len.increment_unchecked(cs) }; let new_decommittment_queue_len = UInt32::conditionally_select( cs, - should_decommit, + *should_add, &new_decommittment_queue_len_candidate, ¤t_decommittment_queue_len, ); - // we use `should_decommit` as a marker that we did actually execute both read and decommittment (whether fresh or not) - let target_memory_page = decommittment_request.page; - let unmapped_page = UInt32::allocated_constant(cs, UNMAPPED_PAGE); - let target_memory_page = - UInt32::conditionally_select(cs, should_decommit, &target_memory_page, &unmapped_page); - - ( - not_enough_ergs_to_decommit, - target_memory_page, - (new_decommittment_queue_tail, new_decommittment_queue_len), - ergs_remaining_after_decommit, - ) + (new_decommittment_queue_tail, new_decommittment_queue_len) } diff --git a/crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/mod.rs b/crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/mod.rs index 6f2b175..5d5eafe 100644 --- a/crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/mod.rs +++ b/crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/mod.rs @@ -8,8 +8,8 @@ pub mod near_call; pub mod ret; pub use self::far_call::*; -pub use self::near_call::*; -pub use self::ret::*; +pub(crate) use self::near_call::*; +pub(crate) use self::ret::*; #[derive(Derivative)] #[derivative(Clone, Copy, Debug)] diff --git a/crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/near_call.rs b/crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/near_call.rs index 54a57ed..230933b 100644 --- a/crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/near_call.rs +++ b/crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/near_call.rs @@ -96,11 +96,34 @@ where new_callstack_entry.reverted_queue_tail = potential_rollback_queue_segment_tail; new_callstack_entry.reverted_queue_head = potential_rollback_queue_segment_tail; new_callstack_entry.reverted_queue_segment_len = zero_u32; + new_callstack_entry.total_pubdata_spent = zero_u32; let dst_pc = common_opcode_state.decoded_opcode.imm0; let eh_pc = common_opcode_state.decoded_opcode.imm1; - let near_call_abi = NearCallABI::from_register_view(&common_opcode_state.src0_view); + let mut near_call_abi = NearCallABI::from_register_view(&common_opcode_state.src0_view); + // convert ergs + let conversion_constant = UInt32::allocated_constant( + cs, + zkevm_opcode_defs::system_params::INTERNAL_ERGS_TO_VISIBLE_ERGS_CONVERSION_CONSTANT, + ); + let cap = UInt32::allocated_constant(cs, u32::MAX); + near_call_abi.ergs_passed = if cs.gate_is_allowed::() { + let zero_u32 = UInt32::zero(cs); + let [(low, _), (high, _)] = UInt32::fma_with_carry( + cs, + near_call_abi.ergs_passed, + conversion_constant, + zero_u32, + zero_u32, + ); + let fits_u32 = high.is_zero(cs); + + UInt32::conditionally_select(cs, fits_u32, &low, &cap) + } else { + unimplemented!() + }; + let pass_all_ergs = near_call_abi.ergs_passed.is_zero(cs); let preliminary_ergs_left = opcode_carry_parts.preliminary_ergs_left; @@ -113,6 +136,14 @@ where &near_call_abi.ergs_passed, ); + if crate::config::CIRCUIT_VERSOBE { + if (execute.witness_hook(&*cs))().unwrap_or(false) { + dbg!(preliminary_ergs_left.witness_hook(cs)().unwrap()); + dbg!(near_call_abi.ergs_passed.witness_hook(cs)().unwrap()); + dbg!(pass_all_ergs.witness_hook(cs)().unwrap()); + } + } + let (remaining_for_this_context, uf) = preliminary_ergs_left.overflowing_sub(cs, ergs_to_pass); let remaining_ergs_if_pass = remaining_for_this_context; @@ -127,6 +158,13 @@ where current_callstack_entry.ergs_remaining = remaining_ergs_if_pass; + if crate::config::CIRCUIT_VERSOBE { + if (execute.witness_hook(&*cs))().unwrap_or(false) { + dbg!(remaining_ergs_if_pass.witness_hook(cs)().unwrap()); + dbg!(passed_ergs_if_pass.witness_hook(cs)().unwrap()); + } + } + let oracle = witness_oracle.clone(); let mut dependencies = Vec::with_capacity( as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 2, diff --git a/crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/ret.rs b/crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/ret.rs index f33bb2e..8e0aa6b 100644 --- a/crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/ret.rs +++ b/crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/ret.rs @@ -24,6 +24,7 @@ pub(crate) struct RetData { pub(crate) specific_registers_updates: [Option<(Boolean, VMRegister)>; REGISTERS_COUNT], pub(crate) specific_registers_zeroing: [Option>; REGISTERS_COUNT], pub(crate) remove_ptr_on_specific_registers: [Option>; REGISTERS_COUNT], + pub(crate) new_pubdata_revert_counter: UInt32, } pub(crate) fn callstack_candidate_for_ret< @@ -77,6 +78,12 @@ where .saved_context .is_local_call; + let is_kernel_frame = draft_vm_state + .callstack + .current_context + .saved_context + .is_kernel_mode; + if crate::config::CIRCUIT_VERSOBE { if execute.witness_hook(&*cs)().unwrap_or(false) { println!("Applying RET"); @@ -173,9 +180,10 @@ where // resolve some exceptions over fat pointer use and memory growth // exceptions that are specific only to return from non-local frame - let mut non_local_frame_exceptions = ArrayVec::, 4>::new(); + let mut non_local_frame_exceptions = ArrayVec::, 5>::new(); let forward_fat_pointer = forwarding_data.forward_fat_pointer; + let do_not_forward_ptr = forward_fat_pointer.negated(cs); let src0_is_integer = src0.is_pointer.negated(cs); let is_far_return = is_local_frame.negated(cs); @@ -183,8 +191,10 @@ where let fat_ptr_expected_exception = Boolean::multi_and(cs, &[forward_fat_pointer, src0_is_integer, is_far_return]); non_local_frame_exceptions.push(fat_ptr_expected_exception); - - let do_not_forward_ptr = forward_fat_pointer.negated(cs); + // symmetric otherwise + let non_pointer_expected_exception = + Boolean::multi_and(cs, &[do_not_forward_ptr, src0.is_pointer, is_far_return]); + non_local_frame_exceptions.push(non_pointer_expected_exception); // we also want unidirectional movement of returndata // check if fat_ptr.memory_page < ctx.base_page and throw if it's the case @@ -197,8 +207,10 @@ where .base_page, ); - // if we try to forward then we should be unidirectional - let non_unidirectional_forwarding = Boolean::multi_and(cs, &[forward_fat_pointer, uf]); + // if we try to forward then we should be unidirectional, unless kernel knows what it's doing + let is_usermode = is_kernel_frame.negated(cs); + let non_unidirectional_forwarding = + Boolean::multi_and(cs, &[forward_fat_pointer, uf, is_usermode]); non_local_frame_exceptions.push(non_unidirectional_forwarding); @@ -270,7 +282,6 @@ where growth_cost = UInt32::conditionally_select(cs, grow_aux_heap, &aux_heap_growth, &growth_cost); // subtract - let (ergs_left_after_growth, uf) = preliminary_ergs_left.overflowing_sub(cs, growth_cost); let mut non_local_frame_exceptions = ArrayVec::, 4>::new(); @@ -294,20 +305,33 @@ where // ----------------------------------------- + // we should subtract stipend, but only if we exit local frame + let stipend_to_subtract = current_callstack_entry + .stipend + .mask_negated(cs, is_local_frame); + let (ergs_after_stipend_subtraction, uf) = + ergs_left_after_growth.overflowing_sub(cs, stipend_to_subtract); + let ergs_after_stipend_subtraction = ergs_after_stipend_subtraction.mask_negated(cs, uf); + + // give the rest to the original caller let new_ergs_left = - ergs_left_after_growth.add_no_overflow(cs, new_callstack_entry.ergs_remaining); + ergs_after_stipend_subtraction.add_no_overflow(cs, new_callstack_entry.ergs_remaining); new_callstack_entry.ergs_remaining = new_ergs_left; + // NOTE: if we return from local frame (from near-call), then memory growth will not be triggered above, + // and so panic can not happen, and we can just propagate already existing heap bound + // to update a previous frame. If we return from the far-call then previous frame is not local, and we should + // not affect it's upper bound at all new_callstack_entry.heap_upper_bound = Selectable::conditionally_select( cs, is_local_frame, - &heap_bound, + ¤t_callstack_entry.heap_upper_bound, &new_callstack_entry.heap_upper_bound, ); new_callstack_entry.aux_heap_upper_bound = Selectable::conditionally_select( cs, is_local_frame, - &aux_heap_bound, + ¤t_callstack_entry.aux_heap_upper_bound, &new_callstack_entry.aux_heap_upper_bound, ); @@ -461,6 +485,53 @@ where erase_ptr_markers[reg_idx as usize] = Some(update_specific_registers_on_ret); } + if crate::config::CIRCUIT_VERSOBE { + if execute.witness_hook(cs)().unwrap() { + dbg!(update_specific_registers_on_ret.witness_hook(cs)().unwrap()); + dbg!(current_callstack_entry.total_pubdata_spent.witness_hook(cs)().unwrap()); + dbg!(originally_popped_context + .total_pubdata_spent + .witness_hook(cs)() + .unwrap()); + dbg!(draft_vm_state.pubdata_revert_counter.witness_hook(cs)().unwrap()); + } + } + + // update pubdata counter in parent frame. If we panic - we do not add, otherwise add + let new_callstack_pubdata_if_ok = i32_add_no_overflow( + cs, + &originally_popped_context.total_pubdata_spent, + ¤t_callstack_entry.total_pubdata_spent, + ); + let new_callstack_pubdata_if_revert = originally_popped_context.total_pubdata_spent; + new_callstack_entry.total_pubdata_spent = UInt32::conditionally_select( + cs, + perform_revert, + &new_callstack_pubdata_if_revert, + &new_callstack_pubdata_if_ok, + ); + + // update global counter. If we revert - we subtract (no underflow) + let pubdata_revert_counter_if_ok = draft_vm_state.pubdata_revert_counter; + let pubdata_revert_counter_if_revert = i32_sub_no_underflow( + cs, + &draft_vm_state.pubdata_revert_counter, + ¤t_callstack_entry.total_pubdata_spent, + ); + let new_pubdata_revert_counter = UInt32::conditionally_select( + cs, + perform_revert, + &pubdata_revert_counter_if_revert, + &pubdata_revert_counter_if_ok, + ); + + if crate::config::CIRCUIT_VERSOBE { + if execute.witness_hook(cs)().unwrap() { + dbg!(new_callstack_entry.total_pubdata_spent.witness_hook(cs)().unwrap()); + dbg!(new_pubdata_revert_counter.witness_hook(cs)().unwrap()); + } + } + let full_data = RetData { apply_ret: execute, is_panic: is_panic, @@ -473,6 +544,7 @@ where specific_registers_updates, specific_registers_zeroing: register_zero_out, remove_ptr_on_specific_registers: erase_ptr_markers, + new_pubdata_revert_counter: new_pubdata_revert_counter, }; full_data diff --git a/crates/zkevm_circuits/src/main_vm/opcodes/context.rs b/crates/zkevm_circuits/src/main_vm/opcodes/context.rs index 69b3f8e..3497aac 100644 --- a/crates/zkevm_circuits/src/main_vm/opcodes/context.rs +++ b/crates/zkevm_circuits/src/main_vm/opcodes/context.rs @@ -36,8 +36,8 @@ pub(crate) fn apply_context>( const SET_CONTEXT_U128_OPCODE: zkevm_opcode_defs::Opcode = zkevm_opcode_defs::Opcode::Context( zkevm_opcode_defs::definitions::context::ContextOpcode::SetContextU128, ); - const SET_PUBDATA_ERGS_OPCODE: zkevm_opcode_defs::Opcode = zkevm_opcode_defs::Opcode::Context( - zkevm_opcode_defs::definitions::context::ContextOpcode::SetErgsPerPubdataByte, + const AUX_MUTATING_0_OPCODE: zkevm_opcode_defs::Opcode = zkevm_opcode_defs::Opcode::Context( + zkevm_opcode_defs::definitions::context::ContextOpcode::AuxMutating0, ); const INCREMENT_TX_NUMBER_OPCODE: zkevm_opcode_defs::Opcode = zkevm_opcode_defs::Opcode::Context( @@ -81,7 +81,7 @@ pub(crate) fn apply_context>( .properties_bits .boolean_for_variant(GET_ERGS_LEFT_OPCODE) }; - let _is_retrieve_sp = { + let is_retrieve_sp = { common_opcode_state .decoded_opcode .properties_bits @@ -99,11 +99,11 @@ pub(crate) fn apply_context>( .properties_bits .boolean_for_variant(SET_CONTEXT_U128_OPCODE) }; - let is_set_pubdata_ergs = { + let _is_aux_mutating_0 = { common_opcode_state .decoded_opcode .properties_bits - .boolean_for_variant(SET_PUBDATA_ERGS_OPCODE) + .boolean_for_variant(AUX_MUTATING_0_OPCODE) }; let is_inc_tx_num = { common_opcode_state @@ -113,20 +113,14 @@ pub(crate) fn apply_context>( }; let write_to_context = Boolean::multi_and(cs, &[should_apply, is_set_context_u128]); - let set_pubdata_ergs = Boolean::multi_and(cs, &[should_apply, is_set_pubdata_ergs]); let increment_tx_counter = Boolean::multi_and(cs, &[should_apply, is_inc_tx_num]); // write in regards of dst0 register - let read_only = Boolean::multi_or( - cs, - &[is_set_context_u128, is_set_pubdata_ergs, is_inc_tx_num], - ); + let read_only = Boolean::multi_or(cs, &[is_set_context_u128, is_inc_tx_num]); let write_like = read_only.negated(cs); let write_to_dst0 = Boolean::multi_and(cs, &[should_apply, write_like]); - let potentially_new_ergs_for_pubdata = common_opcode_state.src0_view.u32x8_view[0]; - let one_u32 = UInt32::allocated_constant(cs, 1u32); let (incremented_tx_number, _of) = draft_vm_state .tx_number_in_block @@ -164,9 +158,18 @@ pub(crate) fn apply_context>( ], ); + let total_pubdata_spent_counter = draft_vm_state.pubdata_revert_counter.mask( + cs, + draft_vm_state + .callstack + .current_context + .saved_context + .is_kernel_mode, + ); + let meta_as_register = UInt256 { inner: [ - draft_vm_state.ergs_per_pubdata_byte, + total_pubdata_spent_counter, zero_u32, // reserved draft_vm_state .callstack @@ -198,15 +201,16 @@ pub(crate) fn apply_context>( ) }; - let low_u32_ergs_left = opcode_carry_parts.preliminary_ergs_left; - - let low_u32 = UInt32::conditionally_select( + let (low_u32_ergs_left, _) = opcode_carry_parts.preliminary_ergs_left.div_by_constant( cs, - is_retrieve_ergs_left, - &low_u32_ergs_left, - &low_u32_to_get_sp, + zkevm_opcode_defs::system_params::INTERNAL_ERGS_TO_VISIBLE_ERGS_CONVERSION_CONSTANT, ); + let low_u32 = UInt32::conditionally_select(cs, is_retrieve_sp, &low_u32_to_get_sp, &zero_u32); + + let low_u32 = + UInt32::conditionally_select(cs, is_retrieve_ergs_left, &low_u32_ergs_left, &low_u32); + // now we have context let mut result_128 = [low_u32, zero_u32, zero_u32, zero_u32]; @@ -301,7 +305,4 @@ pub(crate) fn apply_context>( .push((write_to_context, context_composite_to_set)); debug_assert!(diffs_accumulator.new_tx_number.is_none()); diffs_accumulator.new_tx_number = Some((increment_tx_counter, incremented_tx_number)); - debug_assert!(diffs_accumulator.new_ergs_per_pubdata.is_none()); - diffs_accumulator.new_ergs_per_pubdata = - Some((set_pubdata_ergs, potentially_new_ergs_for_pubdata)); } diff --git a/crates/zkevm_circuits/src/main_vm/opcodes/jump.rs b/crates/zkevm_circuits/src/main_vm/opcodes/jump.rs index a14751a..2bb33a2 100644 --- a/crates/zkevm_circuits/src/main_vm/opcodes/jump.rs +++ b/crates/zkevm_circuits/src/main_vm/opcodes/jump.rs @@ -1,10 +1,12 @@ use super::*; +use crate::base_structures::register::VMRegister; +use crate::boojum::gadgets::u256::UInt256; pub(crate) fn apply_jump>( cs: &mut CS, _draft_vm_state: &VmLocalState, common_opcode_state: &CommonOpcodeState, - _opcode_carry_parts: &AfterDecodingCarryParts, + opcode_carry_parts: &AfterDecodingCarryParts, diffs_accumulator: &mut StateDiffsAccumulator, ) { const JUMP_OPCODE: zkevm_opcode_defs::Opcode = @@ -32,7 +34,22 @@ pub(crate) fn apply_jump>( ], ); + // save next_pc into dst0 + let boolean_false = Boolean::allocated_constant(cs, false); + let mut saved_next_pc = UInt256::zero(cs); + saved_next_pc.inner[0] = + unsafe { UInt32::from_variable_unchecked(opcode_carry_parts.next_pc.get_variable()) }; + let dst0 = VMRegister { + is_pointer: boolean_false, + value: saved_next_pc, + }; + let can_write_into_memory = JUMP_OPCODE.can_write_dst0_into_memory(SUPPORTED_ISA_VERSION); + diffs_accumulator .new_pc_candidates .push((should_apply, jump_dst)); + + diffs_accumulator + .dst_0_values + .push((can_write_into_memory, should_apply, dst0)); } diff --git a/crates/zkevm_circuits/src/main_vm/opcodes/log.rs b/crates/zkevm_circuits/src/main_vm/opcodes/log.rs index f3aaf83..32fa9ec 100644 --- a/crates/zkevm_circuits/src/main_vm/opcodes/log.rs +++ b/crates/zkevm_circuits/src/main_vm/opcodes/log.rs @@ -1,11 +1,16 @@ use boojum::gadgets::u256::UInt256; -use crate::base_structures::{ - log_query::{self, LogQuery, LOG_QUERY_PACKED_WIDTH, ROLLBACK_PACKING_FLAG_VARIABLE_IDX}, - register::VMRegister, +use crate::{ + base_structures::{ + log_query::{self, LogQuery, LOG_QUERY_PACKED_WIDTH, ROLLBACK_PACKING_FLAG_VARIABLE_IDX}, + register::VMRegister, + }, + main_vm::opcodes::call_ret_impl::add_to_decommittment_queue_inner, + tables::{test_bit::TestBitTable, PubdataCostValidityTable}, }; use super::*; +use crate::base_structures::decommit_query::DecommitQueryWitness; use crate::main_vm::opcodes::log::log_query::LogQueryWitness; use crate::main_vm::witness_oracle::SynchronizedWitnessOracle; use crate::main_vm::witness_oracle::WitnessOracle; @@ -13,6 +18,90 @@ use boojum::algebraic_props::round_function::AlgebraicRoundFunction; use boojum::gadgets::traits::allocatable::CSAllocatableExt; use boojum::gadgets::traits::round_function::CircuitRoundFunction; +pub(crate) fn test_if_bit_is_set>( + cs: &mut CS, + byte: &UInt8, + bit: u32, +) -> Boolean { + debug_assert!(bit < 8); + let bit_idx_as_variable = UInt8::allocated_constant(cs, bit as u8); + let table_id = cs + .get_table_id_for_marker::() + .expect("table for bit tests must exist"); + let res = cs.perform_lookup::<2, 1>( + table_id, + &[byte.get_variable(), bit_idx_as_variable.get_variable()], + ); + let res = unsafe { Boolean::from_variable_unchecked(res[0]) }; + + res +} + +pub(crate) fn i32_add_no_overflow>( + cs: &mut CS, + a: &UInt32, + b: &UInt32, +) -> UInt32 { + // condition for overflow is if we add two number >0 and get one <0 (by highest bit), + // or add two <0 and get one >0 + + let a_bytes = a.to_le_bytes(cs); + let a_is_negative = test_if_bit_is_set(cs, &a_bytes[3], 7); + let b_bytes = b.to_le_bytes(cs); + let b_is_negative = test_if_bit_is_set(cs, &b_bytes[3], 7); + let (result, _of) = a.overflowing_add(cs, *b); + let result_bytes = result.to_le_bytes(cs); + let result_is_negative = test_if_bit_is_set(cs, &result_bytes[3], 7); + + let a_is_positive = a_is_negative.negated(cs); + let b_is_positive = b_is_negative.negated(cs); + let result_is_positive = result_is_negative.negated(cs); + + let of_0 = Boolean::multi_and(cs, &[a_is_positive, b_is_positive, result_is_negative]); + let of_1 = Boolean::multi_and(cs, &[a_is_negative, b_is_negative, result_is_positive]); + let of = Boolean::multi_or(cs, &[of_0, of_1]); + let boolean_false = Boolean::allocated_constant(cs, false); + Boolean::enforce_equal(cs, &of, &boolean_false); + + result +} + +pub(crate) fn i32_sub_no_underflow>( + cs: &mut CS, + a: &UInt32, + b: &UInt32, +) -> UInt32 { + // exception is when a > 0, b < 0, and result is <0, + // or if a < 0, b > 0, and result >0 + let a_bytes = a.to_le_bytes(cs); + let a_is_negative = test_if_bit_is_set(cs, &a_bytes[3], 7); + let b_bytes = b.to_le_bytes(cs); + let b_is_negative = test_if_bit_is_set(cs, &b_bytes[3], 7); + let (result, _of) = a.overflowing_sub(cs, *b); + let result_bytes = result.to_le_bytes(cs); + let result_is_negative = test_if_bit_is_set(cs, &result_bytes[3], 7); + + let a_is_positive = a_is_negative.negated(cs); + let b_is_positive = b_is_negative.negated(cs); + let result_is_positive = result_is_negative.negated(cs); + + let of_0 = Boolean::multi_and(cs, &[a_is_positive, b_is_negative, result_is_negative]); + let of_1 = Boolean::multi_and(cs, &[a_is_negative, b_is_positive, result_is_positive]); + let of = Boolean::multi_or(cs, &[of_0, of_1]); + let boolean_false = Boolean::allocated_constant(cs, false); + Boolean::enforce_equal(cs, &of, &boolean_false); + + result +} + +pub(crate) fn normalize_bytecode_hash_for_decommit>( + cs: &mut CS, + bytecode_hash: &mut UInt256, +) { + let zero_u32 = UInt32::zero(cs); + bytecode_hash.inner[7] = zero_u32; +} + pub(crate) fn apply_log< F: SmallField, CS: ConstraintSystem, @@ -28,6 +117,7 @@ pub(crate) fn apply_log< round_function: &R, ) where [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, { const STORAGE_READ_OPCODE: zkevm_opcode_defs::Opcode = zkevm_opcode_defs::Opcode::Log(LogOpcode::StorageRead); @@ -39,8 +129,14 @@ pub(crate) fn apply_log< zkevm_opcode_defs::Opcode::Log(LogOpcode::Event); const PRECOMPILE_CALL_OPCODE: zkevm_opcode_defs::Opcode = zkevm_opcode_defs::Opcode::Log(LogOpcode::PrecompileCall); - - let should_apply = common_opcode_state + const DECOMMIT_OPCODE: zkevm_opcode_defs::Opcode = + zkevm_opcode_defs::Opcode::Log(LogOpcode::Decommit); + const TRANSIENT_STORAGE_READ_OPCODE: zkevm_opcode_defs::Opcode = + zkevm_opcode_defs::Opcode::Log(LogOpcode::TransientStorageRead); + const TRANSIENT_STORAGE_WRITE_OPCODE: zkevm_opcode_defs::Opcode = + zkevm_opcode_defs::Opcode::Log(LogOpcode::TransientStorageWrite); + + let should_apply_opcode_base = common_opcode_state .decoded_opcode .properties_bits .boolean_for_opcode(STORAGE_READ_OPCODE); @@ -75,9 +171,27 @@ pub(crate) fn apply_log< .properties_bits .boolean_for_variant(PRECOMPILE_CALL_OPCODE) }; + let is_decommit = { + common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(DECOMMIT_OPCODE) + }; + let is_transient_storage_read = { + common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(TRANSIENT_STORAGE_READ_OPCODE) + }; + let is_transient_storage_write = { + common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(TRANSIENT_STORAGE_WRITE_OPCODE) + }; if crate::config::CIRCUIT_VERSOBE { - if should_apply.witness_hook(&*cs)().unwrap_or(false) { + if should_apply_opcode_base.witness_hook(&*cs)().unwrap_or(false) { println!("Applying LOG"); if is_storage_read.witness_hook(&*cs)().unwrap_or(false) { println!("SLOAD"); @@ -94,6 +208,15 @@ pub(crate) fn apply_log< if is_precompile.witness_hook(&*cs)().unwrap_or(false) { println!("PRECOMPILECALL"); } + if is_decommit.witness_hook(&*cs)().unwrap_or(false) { + println!("DECOMMIT"); + } + if is_transient_storage_read.witness_hook(&*cs)().unwrap_or(false) { + println!("TLOAD"); + } + if is_transient_storage_write.witness_hook(&*cs)().unwrap_or(false) { + println!("TSTORE"); + } } } @@ -127,37 +250,33 @@ pub(crate) fn apply_log< &key.inner[5], ); - use zkevm_opcode_defs::system_params::{ - INITIAL_STORAGE_WRITE_PUBDATA_BYTES, L1_MESSAGE_PUBDATA_BYTES, - }; - - let is_rollup = draft_vm_state - .callstack - .current_context - .saved_context - .this_shard_id - .is_zero(cs); - let write_to_rollup = Boolean::multi_and(cs, &[is_rollup, is_storage_write]); - - let emit_l1_message = is_l1_message; - - let l1_message_pubdata_bytes_constnt = - UInt32::allocated_constant(cs, L1_MESSAGE_PUBDATA_BYTES as u32); - let ergs_to_burn_for_l1_message = draft_vm_state - .ergs_per_pubdata_byte - .non_widening_mul(cs, &l1_message_pubdata_bytes_constnt); - - let ergs_to_burn_for_precompile_call = common_opcode_state.src1_view.u32x8_view[0]; - - let is_storage_access = Boolean::multi_or(cs, &[is_storage_read, is_storage_write]); - let is_nonrevertable = Boolean::multi_or(cs, &[is_storage_read, is_precompile]); - let is_revertable = is_nonrevertable.negated(cs); + let precompile_call_ergs_cost = common_opcode_state.src1_view.u32x8_view[0]; + let precompile_call_pubdata_cost = common_opcode_state.src1_view.u32x8_view[1]; + // check inplace that pubdata cost is signed, but >0 + + // check that refund is >=0 + let top_byte = common_opcode_state.src1_view.u8x32_view[7]; + let is_negative = test_if_bit_is_set(cs, &top_byte, 7); + let should_enforce = Boolean::multi_and(cs, &[is_precompile, should_apply_opcode_base]); + is_negative.conditionally_enforce_false(cs, should_enforce); + + let is_state_storage_access: Boolean = + Boolean::multi_or(cs, &[is_storage_read, is_storage_write]); + let is_io_read_like = Boolean::multi_or(cs, &[is_storage_read, is_transient_storage_read]); + let is_io_write_like = Boolean::multi_or(cs, &[is_storage_write, is_transient_storage_write]); + let is_transient_storage_access = + Boolean::multi_or(cs, &[is_transient_storage_read, is_transient_storage_write]); + let is_storage_like_access = + Boolean::multi_or(cs, &[is_state_storage_access, is_transient_storage_access]); + let is_nonrevertable_io = Boolean::multi_or(cs, &[is_io_read_like, is_precompile]); + let is_revertable_io = Boolean::multi_or(cs, &[is_io_write_like, is_event, is_l1_message]); + let is_io_like_operation = Boolean::multi_or(cs, &[is_nonrevertable_io, is_revertable_io]); let aux_byte_variable = Num::linear_combination( cs, &[ ( - is_storage_access.get_variable(), + is_state_storage_access.get_variable(), F::from_u64_unchecked(zkevm_opcode_defs::system_params::STORAGE_AUX_BYTE as u64), ), ( @@ -172,6 +291,12 @@ pub(crate) fn apply_log< is_precompile.get_variable(), F::from_u64_unchecked(zkevm_opcode_defs::system_params::PRECOMPILE_AUX_BYTE as u64), ), + ( + is_transient_storage_access.get_variable(), + F::from_u64_unchecked( + zkevm_opcode_defs::system_params::TRANSIENT_STORAGE_AUX_BYTE as u64, + ), + ), ], ) .get_variable(); @@ -198,12 +323,14 @@ pub(crate) fn apply_log< let boolean_false = Boolean::allocated_constant(cs, false); let tx_number = draft_vm_state.tx_number_in_block; + // here we perform all oracle access first, and then will use values below in particular opcodes + let mut log = LogQuery { address, key, read_value: zero_u256, written_value, - rw_flag: is_revertable, + rw_flag: is_revertable_io, aux_byte, rollback: boolean_false, is_service: is_event_init, @@ -213,14 +340,16 @@ pub(crate) fn apply_log< }; let oracle = witness_oracle.clone(); + let execute_storage_access = + Boolean::multi_and(cs, &[should_apply_opcode_base, is_state_storage_access]); // we should assemble all the dependencies here, and we will use AllocateExt here let mut dependencies = Vec::with_capacity( as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 2); dependencies.push(is_storage_write.get_variable().into()); - dependencies.push(should_apply.get_variable().into()); + dependencies.push(execute_storage_access.get_variable().into()); dependencies.extend(Place::from_variables(log.flatten_as_variables())); - let pubdata_refund = UInt32::allocate_from_closure_and_dependencies( + let io_pubdata_cost = UInt32::allocate_from_closure_and_dependencies( cs, move |inputs: &[F]| { let is_write = >::cast_from_source(inputs[0]); @@ -232,61 +361,140 @@ pub(crate) fn apply_log< CSAllocatableExt::witness_from_set_of_values(log_query); let mut guard = oracle.inner.write().expect("not poisoned"); - let witness = guard.get_refunds(&log_query, is_write, execute); + let witness = guard.get_pubdata_cost_for_query(&log_query, is_write, execute); drop(guard); witness }, &dependencies, ); + // NOTE: it's possible to have cost negative, if it's e.g. 2nd write in a sequence of 0 -> X -> 0 - let initial_storage_write_pubdata_bytes = - UInt32::allocated_constant(cs, INITIAL_STORAGE_WRITE_PUBDATA_BYTES as u32); - let net_cost = initial_storage_write_pubdata_bytes.sub_no_overflow(cs, pubdata_refund); - - let ergs_to_burn_for_rollup_storage_write = draft_vm_state - .ergs_per_pubdata_byte - .non_widening_mul(cs, &net_cost); + // we should nevertheless ensure that it's 0 if it's not rollup access, and not write in general + let io_pubdata_cost = io_pubdata_cost.mask(cs, is_storage_write); + let is_zk_rollup_access = shard_id.is_zero(cs); + let is_zk_porter_access = is_zk_rollup_access.negated(cs); + let io_pubdata_cost_is_zero = io_pubdata_cost.is_zero(cs); + io_pubdata_cost_is_zero.conditionally_enforce_true(cs, is_zk_porter_access); - let zero_u32 = UInt32::allocated_constant(cs, 0); + // check range + let table_id = cs + .get_table_id_for_marker::() + .expect("table must exist"); + let _ = cs.perform_lookup::<1, 2>(table_id, &[io_pubdata_cost.get_variable()]); - // now we know net cost - let ergs_to_burn = UInt32::conditionally_select( + let oracle = witness_oracle.clone(); + let cold_warm_access_ergs_refund = UInt32::allocate_from_closure_and_dependencies( cs, - write_to_rollup, - &ergs_to_burn_for_rollup_storage_write, - &zero_u32, + move |inputs: &[F]| { + let is_write = >::cast_from_source(inputs[0]); + let execute = >::cast_from_source(inputs[1]); + let mut log_query = + [F::ZERO; as CSAllocatableExt>::INTERNAL_STRUCT_LEN]; + log_query.copy_from_slice(&inputs[2..]); + let log_query: LogQueryWitness = + CSAllocatableExt::witness_from_set_of_values(log_query); + + let mut guard = oracle.inner.write().expect("not poisoned"); + let witness = guard.get_cold_warm_refund(&log_query, is_write, execute); + drop(guard); + + witness + }, + &dependencies, ); - let ergs_to_burn = UInt32::conditionally_select( + + // we only refund storage + let cold_warm_access_ergs_refund = + cold_warm_access_ergs_refund.mask(cs, is_state_storage_access); + + let mut max_refund = UInt32::zero(cs); + let sload_cost = UInt32::allocated_constant(cs, LogOpcode::StorageRead.ergs_price()); + let sstore_cost = UInt32::allocated_constant(cs, LogOpcode::StorageWrite.ergs_price()); + max_refund = UInt32::conditionally_select(cs, is_storage_read, &sload_cost, &max_refund); + max_refund = UInt32::conditionally_select(cs, is_storage_write, &sstore_cost, &max_refund); + + let _ = max_refund.sub_no_overflow(cs, cold_warm_access_ergs_refund); + + // and also compute cost of decommit in our standard units of 32-byte words + let versioned_hash_byte = common_opcode_state.src0_view.u8x32_view[31]; + let code_hash_version_byte = UInt8::allocated_constant( cs, - is_precompile, - &ergs_to_burn_for_precompile_call, - &ergs_to_burn, + zkevm_opcode_defs::definitions::versioned_hash::ContractCodeSha256Format::VERSION_BYTE, ); - let ergs_to_burn = UInt32::conditionally_select( + let blob_version_byte = UInt8::allocated_constant( cs, - emit_l1_message, - &ergs_to_burn_for_l1_message, - &ergs_to_burn, + zkevm_opcode_defs::definitions::versioned_hash::BlobSha256Format::VERSION_BYTE, ); + let is_code_hash_version_byte = + UInt8::equals(cs, &versioned_hash_byte, &code_hash_version_byte); + let is_blob_version_byte = UInt8::equals(cs, &versioned_hash_byte, &blob_version_byte); + let version_byte_is_valid = + Boolean::multi_or(cs, &[is_code_hash_version_byte, is_blob_version_byte]); + let unknown_version_byte = version_byte_is_valid.negated(cs); + let decommit_versioned_hash_exception = + Boolean::multi_and(cs, &[unknown_version_byte, is_decommit]); + let can_decommit = decommit_versioned_hash_exception.negated(cs); + + // but cost of decommit is determined purely by the caller + let cost_of_decommit_call = common_opcode_state.src1_view.u32x8_view[0]; + + // and check if decommit would end up a repeated one + let boolean_false = Boolean::allocated_constant(cs, false); + let boolean_true = Boolean::allocated_constant(cs, true); + let zero_u32 = UInt32::allocated_constant(cs, 0); + + // now we know net cost + let extra_cost = + UInt32::conditionally_select(cs, is_precompile, &precompile_call_ergs_cost, &zero_u32); + let extra_cost = + UInt32::conditionally_select(cs, is_decommit, &cost_of_decommit_call, &extra_cost); + + if crate::config::CIRCUIT_VERSOBE { + if (should_apply_opcode_base.witness_hook(&*cs))().unwrap_or(false) { + dbg!(extra_cost.witness_hook(cs)().unwrap()); + } + } let (ergs_remaining, uf) = opcode_carry_parts .preliminary_ergs_left - .overflowing_sub(cs, ergs_to_burn); + .overflowing_sub(cs, extra_cost); let not_enough_ergs_for_op = uf; + let have_enough_ergs = not_enough_ergs_for_op.negated(cs); // if not enough then leave only 0 let ergs_remaining = ergs_remaining.mask_negated(cs, not_enough_ergs_for_op); - let have_enough_ergs = not_enough_ergs_for_op.negated(cs); - let execute_either_in_practice = Boolean::multi_and(cs, &[should_apply, have_enough_ergs]); + // NOTE: here we will start to use other markers that will check branches being taken below. Some changes + // (namely - reduction of ergs here) will persist even if opcode does NOT perform material work + + // and we do not execute any ops in practice + let should_apply = Boolean::multi_and(cs, &[should_apply_opcode_base, have_enough_ergs]); + let should_apply_io = Boolean::multi_and(cs, &[should_apply, is_io_like_operation]); + + // we right away compute final cost of the operation here, and we will merge it into state when we do final diffs processing + let final_pubdata_cost = + UInt32::conditionally_select(cs, is_storage_write, &io_pubdata_cost, &zero_u32); + let final_pubdata_cost = UInt32::conditionally_select( + cs, + is_precompile, + &precompile_call_pubdata_cost, + &final_pubdata_cost, + ); + let final_pubdata_cost = final_pubdata_cost.mask(cs, should_apply_io); + if crate::config::CIRCUIT_VERSOBE { + dbg!(final_pubdata_cost.witness_hook(cs)().unwrap()); + } + + // NOTE: this intrinsic L1 message used L1 calldata, while our counter is for pubdata that can be propagated + // by some other way, so we do NOT add it here let oracle = witness_oracle.clone(); // we should assemble all the dependencies here, and we will use AllocateExt here let mut dependencies = Vec::with_capacity( as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 2); - dependencies.push(is_storage_access.get_variable().into()); - dependencies.push(execute_either_in_practice.get_variable().into()); + dependencies.push(is_storage_like_access.get_variable().into()); + dependencies.push(should_apply.get_variable().into()); dependencies.extend(Place::from_variables(log.flatten_as_variables())); // we always access witness, as even for writes we have to get a claimed read value! @@ -312,7 +520,8 @@ pub(crate) fn apply_log< let u256_zero = UInt256::zero(cs); - let read_value = UInt256::conditionally_select(cs, is_storage_access, &read_value, &u256_zero); + let read_value = + UInt256::conditionally_select(cs, is_storage_like_access, &read_value, &u256_zero); log.read_value = read_value.clone(); // if we read then use the same value - convension! log.written_value = @@ -324,7 +533,7 @@ pub(crate) fn apply_log< let mut packed_log_rollback = packed_log_forward; LogQuery::update_packing_for_rollback(cs, &mut packed_log_rollback); - let execute_rollback = Boolean::multi_and(cs, &[execute_either_in_practice, is_revertable]); + let execute_rollback = Boolean::multi_and(cs, &[should_apply, is_revertable_io]); let current_forward_tail = draft_vm_state .callstack @@ -361,7 +570,7 @@ pub(crate) fn apply_log< &dependencies, ); - let (new_forward_queue_tail, new_rollback_queue_head, relations) = + let (new_forward_queue_tail, new_rollback_queue_head, sponge_relations_for_io_like_ops) = construct_hash_relations_for_log_and_new_queue_states( cs, &packed_log_forward, @@ -369,7 +578,7 @@ pub(crate) fn apply_log< ¤t_forward_tail, &prev_revert_head_witness, ¤t_rollback_head, - &execute_either_in_practice, + &should_apply_io, &execute_rollback, round_function, ); @@ -381,17 +590,142 @@ pub(crate) fn apply_log< precompile_call_result.inner[0] = unsafe { UInt32::from_variable_unchecked(have_enough_ergs.get_variable()) }; + // deal with decommit + let should_decommit = Boolean::multi_and(cs, &[should_apply, is_decommit, can_decommit]); + let mut bytecode_hash = key; + normalize_bytecode_hash_for_decommit(cs, &mut bytecode_hash); + let target_memory_page = opcode_carry_parts.heap_page; + + let timestamp_to_use_for_decommittment_request = + common_opcode_state.timestamp_for_first_decommit_or_precompile_read; + + let mut decommittment_request = DecommitQuery { + code_hash: bytecode_hash, + page: target_memory_page, + is_first: boolean_false, + timestamp: timestamp_to_use_for_decommittment_request, + }; + + let oracle = witness_oracle.clone(); + // we should assemble all the dependencies here, and we will use AllocateExt here + let mut dependencies = + Vec::with_capacity( as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1); + dependencies.push(should_decommit.get_variable().into()); + dependencies.extend(Place::from_variables( + decommittment_request.flatten_as_variables(), + )); + + // we always access witness, as even for writes we have to get a claimed read value! + let suggested_page = UInt32::allocate_from_closure_and_dependencies( + cs, + move |inputs: &[F]| { + let should_decommit = >::cast_from_source(inputs[0]); + + let mut query = + [F::ZERO; as CSAllocatableExt>::INTERNAL_STRUCT_LEN]; + query.copy_from_slice(&inputs[1..]); + let query: DecommitQueryWitness = + CSAllocatableExt::witness_from_set_of_values(query); + + let mut guard = oracle.inner.write().expect("not poisoned"); + let witness = guard.get_decommittment_request_suggested_page(&query, should_decommit); + drop(guard); + + witness + }, + &dependencies, + ); + + let is_first = UInt32::equals(cs, &target_memory_page, &suggested_page); + decommittment_request.is_first = is_first; + decommittment_request.page = suggested_page; + + if crate::config::CIRCUIT_VERSOBE { + if (should_apply_opcode_base.witness_hook(&*cs))().unwrap_or(false) { + dbg!(is_first.witness_hook(cs)().unwrap()); + } + } + + // form new candidate of decommit queue + let mut sponge_relations_for_decommit = ArrayVec::< + ( + Boolean, + [Num; FULL_SPONGE_QUEUE_STATE_WIDTH], + [Num; FULL_SPONGE_QUEUE_STATE_WIDTH], + ), + MAX_SPONGES_PER_CYCLE, + >::new(); + let (new_decommit_queue_tail, new_decommit_queue_len) = add_to_decommittment_queue_inner( + cs, + &mut sponge_relations_for_decommit, + &should_decommit, + &draft_vm_state.code_decommittment_queue_state, + &draft_vm_state.code_decommittment_queue_length, + &decommittment_request, + round_function, + ); + + // we can refund a full cost if it's repeated, and only if we did decommit indeed, + // otherwise there was out of ergs above and + let decommit_refund = cost_of_decommit_call.mask_negated(cs, is_first); + let decommit_refund = decommit_refund.mask(cs, should_decommit); + + if crate::config::CIRCUIT_VERSOBE { + if (should_apply_opcode_base.witness_hook(&*cs))().unwrap_or(false) { + dbg!(decommit_refund.witness_hook(cs)().unwrap()); + } + } + + // NOTE: cold_warm_access_ergs_refund is already masked if it's not a storage access + let refund_value = UInt32::conditionally_select( + cs, + is_decommit, + &decommit_refund, + &cold_warm_access_ergs_refund, + ); + + // apply refund + let ergs_remaining = ergs_remaining.add_no_overflow(cs, refund_value); + + // assemble dst0 candidates + // one for io-like and precompile call let register_value = UInt256::conditionally_select( cs, - is_storage_read, + is_io_read_like, ®ister_value_if_storage_read, &precompile_call_result, ); - - let dst0 = VMRegister { + let dst0_for_io_ops_and_precompile_call = VMRegister { value: register_value, is_pointer: boolean_false, }; + // another one for decommit. It's a fat pointer! + let mut register_value = zero_u256; + // we have 0 offset and 0 start, and only need length and memory page + // page + register_value.inner[1] = suggested_page; + // length is set to the full "free" heap space, and caller is responsible to truncate it + let preimage_len_in_bytes = UInt32::allocated_constant( + cs, + zkevm_opcode_defs::system_params::NEW_KERNEL_FRAME_MEMORY_STIPEND, + ); + register_value.inner[3] = preimage_len_in_bytes; + + let mut dst_0_for_decommit = VMRegister { + value: register_value, + is_pointer: boolean_true, + }; + // or it's empty if decommit didn't work + dst_0_for_decommit.conditionally_erase(cs, decommit_versioned_hash_exception); + + // NOTE: if any of the ops that update DST0 fails, then we write exactly empty register (failing here is only "out of ergs") + let mut selected_dst_0_value = VMRegister::conditionally_select( + cs, + is_decommit, + &dst_0_for_decommit, + &dst0_for_io_ops_and_precompile_call, + ); + selected_dst_0_value.conditionally_erase(cs, not_enough_ergs_for_op); let old_forward_queue_length = draft_vm_state .callstack @@ -402,7 +736,7 @@ pub(crate) fn apply_log< unsafe { old_forward_queue_length.increment_unchecked(cs) }; let new_forward_queue_length = UInt32::conditionally_select( cs, - execute_either_in_practice, + should_apply_io, &new_forward_queue_length_candidate, &old_forward_queue_length, ); @@ -422,21 +756,25 @@ pub(crate) fn apply_log< &old_revert_queue_length, ); - let can_update_dst0 = Boolean::multi_or(cs, &[is_storage_read, is_precompile]); - let should_update_dst0 = Boolean::multi_and(cs, &[can_update_dst0, should_apply]); + let can_update_dst0 = Boolean::multi_or(cs, &[is_nonrevertable_io, is_decommit]); + // NOTE: here it's `should_apply_opcode_base` because write should always happen, but we have + // selected a proper value above in case if there was an exception + let should_update_dst0 = Boolean::multi_and(cs, &[can_update_dst0, should_apply_opcode_base]); if crate::config::CIRCUIT_VERSOBE { if should_apply.witness_hook(&*cs)().unwrap() { dbg!(should_update_dst0.witness_hook(&*cs)().unwrap()); - dbg!(dst0.witness_hook(&*cs)().unwrap()); + dbg!(selected_dst_0_value.witness_hook(&*cs)().unwrap()); } } let can_write_into_memory = STORAGE_READ_OPCODE.can_write_dst0_into_memory(SUPPORTED_ISA_VERSION); - diffs_accumulator - .dst_0_values - .push((can_write_into_memory, should_update_dst0, dst0)); + diffs_accumulator.dst_0_values.push(( + can_write_into_memory, + should_update_dst0, + selected_dst_0_value, + )); diffs_accumulator.log_queue_forward_candidates.push(( should_apply, @@ -452,14 +790,36 @@ pub(crate) fn apply_log< diffs_accumulator .new_ergs_left_candidates - .push((should_apply, ergs_remaining)); + .push((should_apply_opcode_base, ergs_remaining)); assert!(STORAGE_READ_OPCODE.can_have_src0_from_mem(SUPPORTED_ISA_VERSION) == false); assert!(STORAGE_READ_OPCODE.can_write_dst0_into_memory(SUPPORTED_ISA_VERSION) == false); - diffs_accumulator - .sponge_candidates_to_run - .push((false, false, should_apply, relations)); + diffs_accumulator.sponge_candidates_to_run.push(( + false, + false, + should_apply_io, + sponge_relations_for_io_like_ops, + )); + diffs_accumulator.sponge_candidates_to_run.push(( + false, + false, + should_decommit, + sponge_relations_for_decommit, + )); + + // NOTE: out of circuit implementation does NOT set pending here and instead just burns ergs, + // that is equivalent behavior + + // NOTE - we use `should_apply`` here, because values are preselected above via `should_decommit` that requires `should_apply` + diffs_accumulator.decommitment_queue_candidates.push(( + should_apply, + new_decommit_queue_len, + new_decommit_queue_tail, + )); + + assert!(diffs_accumulator.pubdata_cost.is_none()); + diffs_accumulator.pubdata_cost = Some((should_apply, final_pubdata_cost)); } use crate::base_structures::vm_state::FULL_SPONGE_QUEUE_STATE_WIDTH; diff --git a/crates/zkevm_circuits/src/main_vm/opcodes/mod.rs b/crates/zkevm_circuits/src/main_vm/opcodes/mod.rs index 48055e9..62d851d 100644 --- a/crates/zkevm_circuits/src/main_vm/opcodes/mod.rs +++ b/crates/zkevm_circuits/src/main_vm/opcodes/mod.rs @@ -3,9 +3,7 @@ use crate::base_structures::vm_state::VmLocalState; use crate::main_vm::opcode_bitmask::SUPPORTED_ISA_VERSION; use crate::main_vm::pre_state::AfterDecodingCarryParts; use crate::main_vm::pre_state::CommonOpcodeState; -use crate::main_vm::state_diffs::{ - StateDiffsAccumulator, MAX_U32_CONDITIONAL_RANGE_CHECKS_PER_CYCLE, -}; +use crate::main_vm::state_diffs::StateDiffsAccumulator; use boojum::cs::gates::U8x4FMAGate; use zkevm_opcode_defs::*; @@ -24,16 +22,15 @@ pub mod uma; pub(crate) mod call_ret_impl; pub use self::add_sub::*; -pub use self::binop::*; -pub use self::call_ret::*; -pub use self::context::*; -pub use self::jump::*; -pub use self::log::*; +pub(crate) use self::binop::*; +pub(crate) use self::call_ret::*; +pub(crate) use self::context::*; +pub(crate) use self::jump::*; +pub(crate) use self::log::*; pub use self::mul_div::*; -pub use self::nop::*; -pub use self::ptr::*; -pub use self::ptr::*; -pub use self::shifts::*; +pub(crate) use self::nop::*; +pub(crate) use self::ptr::*; +pub(crate) use self::shifts::*; pub use self::uma::*; pub struct AddSubRelation { diff --git a/crates/zkevm_circuits/src/main_vm/opcodes/uma.rs b/crates/zkevm_circuits/src/main_vm/opcodes/uma.rs index d3ee192..e5195b5 100644 --- a/crates/zkevm_circuits/src/main_vm/opcodes/uma.rs +++ b/crates/zkevm_circuits/src/main_vm/opcodes/uma.rs @@ -41,6 +41,10 @@ pub(crate) fn apply_uma< zkevm_opcode_defs::Opcode::UMA(UMAOpcode::AuxHeapWrite); const UMA_FAT_PTR_READ_OPCODE: zkevm_opcode_defs::Opcode = zkevm_opcode_defs::Opcode::UMA(UMAOpcode::FatPointerRead); + const UMA_STATIC_MEMORY_READ_OPCODE: zkevm_opcode_defs::Opcode = + zkevm_opcode_defs::Opcode::UMA(UMAOpcode::StaticMemoryRead); + const UMA_STATIC_MEMORY_WRITE_OPCODE: zkevm_opcode_defs::Opcode = + zkevm_opcode_defs::Opcode::UMA(UMAOpcode::StaticMemoryWrite); let should_apply = common_opcode_state .decoded_opcode @@ -67,6 +71,14 @@ pub(crate) fn apply_uma< .decoded_opcode .properties_bits .boolean_for_variant(UMA_FAT_PTR_READ_OPCODE); + let is_uma_static_memory_read = common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(UMA_STATIC_MEMORY_READ_OPCODE); + let is_uma_static_memory_write = common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(UMA_STATIC_MEMORY_WRITE_OPCODE); let increment_offset = common_opcode_state .decoded_opcode @@ -75,6 +87,8 @@ pub(crate) fn apply_uma< let access_heap = Boolean::multi_or(cs, &[is_uma_heap_read, is_uma_heap_write]); let access_aux_heap = Boolean::multi_or(cs, &[is_uma_aux_heap_read, is_uma_aux_heap_write]); + let access_static_page = + Boolean::multi_or(cs, &[is_uma_static_memory_read, is_uma_static_memory_write]); if crate::config::CIRCUIT_VERSOBE { if should_apply.witness_hook(&*cs)().unwrap_or(false) { @@ -94,6 +108,12 @@ pub(crate) fn apply_uma< if is_uma_fat_ptr_read.witness_hook(&*cs)().unwrap_or(false) { println!("Fat ptr read"); } + if is_uma_static_memory_read.witness_hook(&*cs)().unwrap_or(false) { + println!("Static memory read"); + } + if is_uma_static_memory_write.witness_hook(&*cs)().unwrap_or(false) { + println!("Static memory write"); + } } } @@ -215,9 +235,21 @@ pub(crate) fn apply_uma< let is_read_access = Boolean::multi_or( cs, - &[is_uma_heap_read, is_uma_aux_heap_read, is_uma_fat_ptr_read], + &[ + is_uma_heap_read, + is_uma_aux_heap_read, + is_uma_fat_ptr_read, + is_uma_static_memory_read, + ], + ); + let is_write_access = Boolean::multi_or( + cs, + &[ + is_uma_heap_write, + is_uma_aux_heap_write, + is_uma_static_memory_write, + ], ); - let is_write_access = Boolean::multi_or(cs, &[is_uma_heap_write, is_uma_aux_heap_write]); // NB: Etherium virtual machine is big endian; // we need to determine the memory cells' indexes which will be accessed @@ -247,7 +279,11 @@ pub(crate) fn apply_uma< let current_memory_queue_state = draft_vm_state.memory_queue_state; let current_memory_queue_length = draft_vm_state.memory_queue_length; + let static_memory_page_index = UInt32::allocated_constant(cs, STATIC_MEMORY_PAGE); + let mut mem_page = quasi_fat_ptr.page_candidate; + mem_page = + UInt32::conditionally_select(cs, access_static_page, &static_memory_page_index, &mem_page); mem_page = UInt32::conditionally_select(cs, access_heap, &opcode_carry_parts.heap_page, &mem_page); mem_page = UInt32::conditionally_select( @@ -1029,34 +1065,51 @@ impl QuasiFatPtrInUMA { Boolean::multi_and(cs, &[offset_is_beyond_the_slice, is_fat_ptr]); // 0 of it's heap/aux heap, otherwise use what we have + let is_heap_offset = is_fat_ptr.negated(cs); let formal_start = start.mask(cs, is_fat_ptr); // by prevalidating fat pointer we know that there is no overflow here, // so we ignore the information let (absolute_address, _of) = formal_start.overflowing_add(cs, offset); let u32_constant_32 = UInt32::allocated_constant(cs, 32); - - let (incremented_offset, is_non_addressable) = offset.overflowing_add(cs, u32_constant_32); - // check that we agree in logic with out-of-circuit comparisons debug_assert_eq!( zkevm_opcode_defs::uma::MAX_OFFSET_TO_DEREF_LOW_U32 + 32u32, u32::MAX ); + + // check that offset <= MAX_OFFSET_TO_DEREF. For that we add 32 to offset and can either trigger overflow, or compare the result + // with u32::MAX + + let (incremented_offset, offset_overflow) = offset.overflowing_add(cs, u32_constant_32); let max_offset = UInt32::allocated_constant(cs, u32::MAX); let is_non_addressable_extra = UInt32::equals(cs, &incremented_offset, &max_offset); let is_non_addressable = - Boolean::multi_or(cs, &[is_non_addressable, is_non_addressable_extra]); + Boolean::multi_or(cs, &[offset_overflow, is_non_addressable_extra]); + let is_non_addressable_heap_offset = + Boolean::multi_and(cs, &[is_non_addressable, is_heap_offset]); + + // but on overflow we would still have to panic even if it's a pointer operation + // NOTE: it's an offset as an absolute value, so if fat pointer's offset is not in slice as checked above is one statment, + // and offset overflow is another - let should_set_panic = Boolean::multi_or(cs, &[already_panicked, is_non_addressable]); + let should_set_panic = Boolean::multi_or( + cs, + &[ + already_panicked, + is_non_addressable_heap_offset, + offset_overflow, + ], + ); let skip_memory_access = Boolean::multi_or( cs, &[ already_panicked, skip_if_legitimate_fat_ptr, - is_non_addressable, + is_non_addressable_heap_offset, + offset_overflow, ], ); @@ -1071,12 +1124,16 @@ impl QuasiFatPtrInUMA { let bytes_to_cleanup_out_of_bounds = unsafe { UInt8::from_variable_unchecked(bytes_out_of_bound.get_variable()) }; + // penalize for too high offset on heap - it happens exactly if offset overflows, + // or incremented is == u32::MAX, in case we access heap + let heap_deref_out_of_bounds = is_non_addressable_heap_offset; + let new = Self { absolute_address, page_candidate: page, incremented_offset, - heap_deref_out_of_bounds: is_non_addressable, - skip_memory_access: skip_memory_access, + heap_deref_out_of_bounds, + skip_memory_access, should_set_panic, bytes_to_cleanup_out_of_bounds, }; diff --git a/crates/zkevm_circuits/src/main_vm/pre_state.rs b/crates/zkevm_circuits/src/main_vm/pre_state.rs index fb4c505..9fa2912 100644 --- a/crates/zkevm_circuits/src/main_vm/pre_state.rs +++ b/crates/zkevm_circuits/src/main_vm/pre_state.rs @@ -94,9 +94,7 @@ pub fn create_prestate< dbg!(execution_has_ended.witness_hook(&*cs)().unwrap()); } - // we should even try to perform a read only if we have something to do this cycle - let should_try_to_read_opcode = execute_cycle.mask_negated(cs, pending_exception); - + // NOTE: even if we have pending exception, we should still read and cache opcode to avoid caching problems let execute_pending_exception_at_this_cycle = pending_exception; // take down the flag @@ -113,7 +111,7 @@ pub fn create_prestate< let (super_pc, subpc_spread) = split_pc(cs, current_pc); let previous_super_pc = current_state.previous_super_pc; - let should_read_for_new_pc = should_read_memory( + let refresh_opcode_cache = should_read_memory( cs, current_state.previous_code_page, current_state @@ -125,9 +123,9 @@ pub fn create_prestate< previous_super_pc, ); - let should_read_opcode = - Boolean::multi_and(cs, &[should_try_to_read_opcode, should_read_for_new_pc]); - + // In normal execution if we do not skip cycle then we read opcode based on PC and page. + // If we have pending exception we should do it too in case if next PC hits the cache + let should_read_opcode = Boolean::multi_and(cs, &[refresh_opcode_cache, execute_cycle]); // and in addition if we did finish execution then we never care and cleanup let location = MemoryLocation { diff --git a/crates/zkevm_circuits/src/main_vm/state_diffs.rs b/crates/zkevm_circuits/src/main_vm/state_diffs.rs index 8e05eed..b72a403 100644 --- a/crates/zkevm_circuits/src/main_vm/state_diffs.rs +++ b/crates/zkevm_circuits/src/main_vm/state_diffs.rs @@ -11,11 +11,13 @@ use boojum::gadgets::num::Num; use boojum::gadgets::{boolean::Boolean, u16::UInt16, u32::UInt32}; use crate::main_vm::opcodes::{AddSubRelation, MulDivRelation}; +use zkevm_opcode_defs::REGISTERS_COUNT; -pub(crate) const MAX_SPONGES_PER_CYCLE: usize = 8; +pub(crate) const MAX_SPONGES_PER_CYCLE: usize = 9; pub(crate) const MAX_U32_CONDITIONAL_RANGE_CHECKS_PER_CYCLE: usize = 8; pub(crate) const MAX_ADD_SUB_RELATIONS_PER_CYCLE: usize = 1; -pub(crate) const MAX_MUL_DIV_RELATIONS_PER_CYCLE: usize = 3; +pub(crate) const MAX_MUL_DIV_RELATIONS_PER_CYCLE: usize = 1; +pub(crate) const MAX_DECOMMIT_QUEUE_CANDIDATES: usize = 2; #[derive(Derivative)] #[derivative(Default(bound = ""))] @@ -41,7 +43,8 @@ pub struct StateDiffsAccumulator { pub new_pc_candidates: Vec<(Boolean, UInt16)>, // other meta parameters of VM pub new_tx_number: Option<(Boolean, UInt32)>, - pub new_ergs_per_pubdata: Option<(Boolean, UInt32)>, + // pubdata revert counter for state + pub new_pubdata_revert_counter: Option<(Boolean, UInt32)>, // memory bouds pub new_heap_bounds: Vec<(Boolean, UInt32)>, pub new_aux_heap_bounds: Vec<(Boolean, UInt32)>, @@ -52,11 +55,14 @@ pub struct StateDiffsAccumulator { // memory page counter pub memory_page_counters: Option>, // decommittment queue - pub decommitment_queue_candidates: Option<( - Boolean, - UInt32, - [Num; FULL_SPONGE_QUEUE_STATE_WIDTH], - )>, + pub decommitment_queue_candidates: ArrayVec< + ( + Boolean, + UInt32, + [Num; FULL_SPONGE_QUEUE_STATE_WIDTH], + ), + MAX_DECOMMIT_QUEUE_CANDIDATES, + >, // memory queue pub memory_queue_candidates: Vec<( Boolean, @@ -96,4 +102,6 @@ pub struct StateDiffsAccumulator { Boolean, ArrayVec, MAX_MUL_DIV_RELATIONS_PER_CYCLE>, )>, + // pubdata cost of case if we do not modify callstack entry in full + pub pubdata_cost: Option<(Boolean, UInt32)>, // signed in practice } diff --git a/crates/zkevm_circuits/src/main_vm/utils.rs b/crates/zkevm_circuits/src/main_vm/utils.rs index cf04d7b..bed0714 100644 --- a/crates/zkevm_circuits/src/main_vm/utils.rs +++ b/crates/zkevm_circuits/src/main_vm/utils.rs @@ -6,7 +6,7 @@ use super::*; use crate::base_structures::memory_query::{MemoryQuery, MemoryValue}; use crate::base_structures::register::VMRegister; use boojum::algebraic_props::round_function::AlgebraicRoundFunction; -use boojum::config::*; + use boojum::cs::gates::ConstantAllocatableCS; use boojum::gadgets::traits::encodable::CircuitEncodable; use boojum::gadgets::u256::UInt256; diff --git a/crates/zkevm_circuits/src/main_vm/witness_oracle.rs b/crates/zkevm_circuits/src/main_vm/witness_oracle.rs index 386e728..39951e7 100644 --- a/crates/zkevm_circuits/src/main_vm/witness_oracle.rs +++ b/crates/zkevm_circuits/src/main_vm/witness_oracle.rs @@ -59,7 +59,18 @@ pub trait WitnessOracle: needs_witness: bool, execute: bool, ) -> U256; - fn get_refunds(&mut self, query: &LogQueryWitness, is_write: bool, execute: bool) -> u32; + fn get_cold_warm_refund( + &mut self, + query: &LogQueryWitness, + is_write: bool, + execute: bool, + ) -> u32; + fn get_pubdata_cost_for_query( + &mut self, + query: &LogQueryWitness, + is_write: bool, + execute: bool, + ) -> u32; fn push_storage_witness(&mut self, key: &LogQueryWitness, execute: bool); fn get_rollback_queue_witness(&mut self, key: &LogQueryWitness, execute: bool) -> [F; 4]; fn get_rollback_queue_tail_witness_for_call(&mut self, timestamp: u32, execute: bool) @@ -117,7 +128,20 @@ impl WitnessOracle for DummyOracle { ) -> U256 { todo!() } - fn get_refunds(&mut self, _query: &LogQueryWitness, _is_write: bool, _execute: bool) -> u32 { + fn get_cold_warm_refund( + &mut self, + _query: &LogQueryWitness, + _is_write: bool, + _execute: bool, + ) -> u32 { + todo!() + } + fn get_pubdata_cost_for_query( + &mut self, + _query: &LogQueryWitness, + _is_write: bool, + _execute: bool, + ) -> u32 { todo!() } fn push_storage_witness(&mut self, _key: &LogQueryWitness, _execute: bool) { diff --git a/crates/zkevm_circuits/src/ram_permutation/input.rs b/crates/zkevm_circuits/src/ram_permutation/input.rs index 099c413..c1d1ee1 100644 --- a/crates/zkevm_circuits/src/ram_permutation/input.rs +++ b/crates/zkevm_circuits/src/ram_permutation/input.rs @@ -12,8 +12,8 @@ use boojum::gadgets::{ queue::full_state_queue::*, queue::*, traits::{ - allocatable::*, encodable::CircuitVarLengthEncodable, selectable::Selectable, - witnessable::WitnessHookable, + allocatable::*, encodable::CircuitVarLengthEncodable, encodable::WitnessVarLengthEncodable, + selectable::Selectable, witnessable::WitnessHookable, }, u256::UInt256, u32::UInt32, @@ -22,7 +22,14 @@ use boojum::serde_utils::BigArraySerde; use cs_derive::*; use derivative::*; -#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Debug)] pub struct RamPermutationInputData { pub unsorted_queue_initial_state: QueueState, @@ -46,7 +53,14 @@ impl CSPlaceholder for RamPermutationInputData { pub const RAM_SORTING_KEY_LENGTH: usize = 3; pub const RAM_FULL_KEY_LENGTH: usize = 2; -#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug)] #[DerivePrettyComparison("true")] pub struct RamPermutationFSMInputOutput { diff --git a/crates/zkevm_circuits/src/ram_permutation/mod.rs b/crates/zkevm_circuits/src/ram_permutation/mod.rs index dc47dad..249b77d 100644 --- a/crates/zkevm_circuits/src/ram_permutation/mod.rs +++ b/crates/zkevm_circuits/src/ram_permutation/mod.rs @@ -393,24 +393,21 @@ pub(crate) fn long_equals, const N: usize #[cfg(test)] mod tests { - use std::alloc::Global; - use super::*; use boojum::algebraic_props::poseidon2_parameters::Poseidon2GoldilocksExternalMatrix; use boojum::cs::gates::*; - use boojum::cs::implementations::reference_cs::CSDevelopmentAssembly; + use boojum::cs::traits::gate::GatePlacementStrategy; use boojum::cs::CSGeometry; use boojum::cs::*; use boojum::field::goldilocks::GoldilocksField; use boojum::gadgets::tables::*; - use boojum::gadgets::traits::allocatable::CSPlaceholder; - use boojum::gadgets::u160::UInt160; + use boojum::gadgets::u256::UInt256; - use boojum::gadgets::u8::UInt8; + use boojum::implementations::poseidon2::Poseidon2Goldilocks; use boojum::worker::Worker; - use ethereum_types::{Address, U256}; + use ethereum_types::U256; type F = GoldilocksField; type P = GoldilocksField; @@ -551,7 +548,7 @@ mod tests { cs.pad_and_shrink(); let worker = Worker::new(); - let mut owned_cs = owned_cs.into_assembly::(); + let mut owned_cs = owned_cs.into_assembly::(); owned_cs.print_gate_stats(); assert!(owned_cs.check_if_satisfied(&worker)); } diff --git a/crates/zkevm_circuits/src/recursion/compression/input.rs b/crates/zkevm_circuits/src/recursion/compression/input.rs index b9cb60e..d4c324e 100644 --- a/crates/zkevm_circuits/src/recursion/compression/input.rs +++ b/crates/zkevm_circuits/src/recursion/compression/input.rs @@ -6,7 +6,6 @@ use boojum::field::SmallField; use boojum::gadgets::num::Num; use boojum::gadgets::recursion::recursive_tree_hasher::RecursiveTreeHasher; use boojum::gadgets::traits::allocatable::CSAllocatable; -use std::collections::VecDeque; #[derive(Derivative, serde::Serialize, serde::Deserialize)] #[derivative(Clone, Debug, Default(bound = ""))] diff --git a/crates/zkevm_circuits/src/recursion/compression/mod.rs b/crates/zkevm_circuits/src/recursion/compression/mod.rs index 0bd8c1b..520209f 100644 --- a/crates/zkevm_circuits/src/recursion/compression/mod.rs +++ b/crates/zkevm_circuits/src/recursion/compression/mod.rs @@ -4,9 +4,7 @@ pub mod input; pub use self::input::*; use crate::fsm_input_output::circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH; -use boojum::algebraic_props::round_function::AlgebraicRoundFunction; -use boojum::config::*; -use boojum::cs::implementations::proof::Proof; + use boojum::cs::implementations::prover::ProofConfig; use boojum::cs::implementations::verifier::VerificationKey; use boojum::cs::oracle::TreeHasher; @@ -22,7 +20,6 @@ use boojum::gadgets::recursion::circuit_pow::RecursivePoWRunner; use boojum::gadgets::recursion::recursive_transcript::*; use boojum::gadgets::recursion::recursive_tree_hasher::*; use boojum::gadgets::traits::allocatable::CSAllocatable; -use boojum::gadgets::traits::round_function::CircuitRoundFunction; // We recursively verify SINGLE proofs over FIXED VK and output it's inputs diff --git a/crates/zkevm_circuits/src/recursion/interblock/mod.rs b/crates/zkevm_circuits/src/recursion/interblock/mod.rs index d0e45e2..7db8e6a 100644 --- a/crates/zkevm_circuits/src/recursion/interblock/mod.rs +++ b/crates/zkevm_circuits/src/recursion/interblock/mod.rs @@ -6,9 +6,7 @@ pub use self::input::*; pub mod keccak_aggregator; use crate::fsm_input_output::circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH; -use boojum::algebraic_props::round_function::AlgebraicRoundFunction; -use boojum::config::*; -use boojum::cs::implementations::proof::Proof; + use boojum::cs::implementations::prover::ProofConfig; use boojum::cs::implementations::verifier::VerificationKey; use boojum::cs::oracle::TreeHasher; @@ -24,7 +22,6 @@ use boojum::gadgets::recursion::circuit_pow::RecursivePoWRunner; use boojum::gadgets::recursion::recursive_transcript::*; use boojum::gadgets::recursion::recursive_tree_hasher::*; use boojum::gadgets::traits::allocatable::CSAllocatable; -use boojum::gadgets::traits::round_function::CircuitRoundFunction; // performs recursion between "independent" units for FIXED verification key diff --git a/crates/zkevm_circuits/src/recursion/leaf_layer/input.rs b/crates/zkevm_circuits/src/recursion/leaf_layer/input.rs index 6f4153a..323f50c 100644 --- a/crates/zkevm_circuits/src/recursion/leaf_layer/input.rs +++ b/crates/zkevm_circuits/src/recursion/leaf_layer/input.rs @@ -11,8 +11,8 @@ use boojum::gadgets::traits::auxiliary::PrettyComparison; use boojum::gadgets::{ boolean::Boolean, traits::{ - allocatable::*, encodable::CircuitVarLengthEncodable, selectable::Selectable, - witnessable::WitnessHookable, + allocatable::*, encodable::CircuitVarLengthEncodable, encodable::WitnessVarLengthEncodable, + selectable::Selectable, witnessable::WitnessHookable, }, }; use cs_derive::*; @@ -20,7 +20,14 @@ use cs_derive::*; use boojum::field::FieldExtension; use boojum::serde_utils::BigArraySerde; -#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug)] #[DerivePrettyComparison("true")] pub struct RecursionLeafParameters { @@ -40,6 +47,27 @@ impl CSPlaceholder for RecursionLeafParameters { } } +impl RecursionLeafParameters { + pub fn allocated_constant>( + cs: &mut CS, + value: >::Witness, + ) -> Self { + let circuit_type = Num::allocated_constant(cs, value.circuit_type); + let basic_circuit_vk_commitment = value + .basic_circuit_vk_commitment + .map(|el| Num::allocated_constant(cs, el)); + let leaf_layer_vk_commitment = value + .leaf_layer_vk_commitment + .map(|el| Num::allocated_constant(cs, el)); + + Self { + circuit_type, + basic_circuit_vk_commitment, + leaf_layer_vk_commitment, + } + } +} + #[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] #[derivative(Clone, Copy, Debug)] #[DerivePrettyComparison("true")] diff --git a/crates/zkevm_circuits/src/recursion/leaf_layer/mod.rs b/crates/zkevm_circuits/src/recursion/leaf_layer/mod.rs index 645f2d6..4b941fe 100644 --- a/crates/zkevm_circuits/src/recursion/leaf_layer/mod.rs +++ b/crates/zkevm_circuits/src/recursion/leaf_layer/mod.rs @@ -1,6 +1,6 @@ use crate::base_structures::recursion_query::{RecursionQuery, RecursionQueue}; use crate::fsm_input_output::commit_variable_length_encodable_item; -use boojum::cs::implementations::proof::Proof; + use boojum::cs::implementations::prover::ProofConfig; use boojum::gadgets::recursion::allocated_proof::AllocatedProof; use boojum::gadgets::recursion::allocated_vk::AllocatedVerificationKey; @@ -12,9 +12,9 @@ use std::sync::Arc; use crate::fsm_input_output::circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH; use boojum::algebraic_props::round_function::AlgebraicRoundFunction; -use boojum::config::*; + use boojum::cs::traits::circuit::ErasedBuilderForRecursiveVerifier; -use boojum::cs::{gates::*, traits::cs::ConstraintSystem}; +use boojum::cs::traits::cs::ConstraintSystem; use boojum::field::SmallField; use boojum::gadgets::queue::full_state_queue::FullStateCircuitQueueWitness; use boojum::gadgets::traits::round_function::CircuitRoundFunction; @@ -135,18 +135,10 @@ where .. } = config; - // use this and deal with borrow checker - - let r = cs as *mut CS; - assert_eq!(vk_fixed_parameters.parameters, verifier_builder.geometry()); let verifier = verifier_builder.create_recursive_verifier(cs); - drop(cs); - - let cs = unsafe { &mut *r }; - for _ in 0..capacity { let proof_witness = proof_witnesses.pop_front(); diff --git a/crates/zkevm_circuits/src/recursion/mod.rs b/crates/zkevm_circuits/src/recursion/mod.rs index 7923239..e8566e9 100644 --- a/crates/zkevm_circuits/src/recursion/mod.rs +++ b/crates/zkevm_circuits/src/recursion/mod.rs @@ -4,6 +4,7 @@ pub mod compression; pub mod interblock; pub mod leaf_layer; pub mod node_layer; +pub mod recursion_tip; pub const VK_COMMITMENT_LENGTH: usize = 4; -pub const NUM_BASE_LAYER_CIRCUITS: usize = 13; +pub const NUM_BASE_LAYER_CIRCUITS: usize = 16; diff --git a/crates/zkevm_circuits/src/recursion/node_layer/mod.rs b/crates/zkevm_circuits/src/recursion/node_layer/mod.rs index 35f4454..435cb10 100644 --- a/crates/zkevm_circuits/src/recursion/node_layer/mod.rs +++ b/crates/zkevm_circuits/src/recursion/node_layer/mod.rs @@ -1,6 +1,6 @@ use crate::base_structures::recursion_query::RecursionQuery; use crate::fsm_input_output::commit_variable_length_encodable_item; -use boojum::cs::implementations::proof::Proof; + use boojum::cs::implementations::prover::ProofConfig; use crate::base_structures::recursion_query::RecursionQueue; @@ -8,17 +8,15 @@ use boojum::gadgets::recursion::allocated_proof::AllocatedProof; use boojum::gadgets::recursion::allocated_vk::AllocatedVerificationKey; use boojum::gadgets::recursion::recursive_transcript::RecursiveTranscript; use boojum::gadgets::recursion::recursive_tree_hasher::RecursiveTreeHasher; -use boojum::gadgets::traits::witnessable::WitnessHookable; use std::collections::VecDeque; use crate::fsm_input_output::circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH; use boojum::algebraic_props::round_function::AlgebraicRoundFunction; -use boojum::cs::{gates::*, traits::cs::ConstraintSystem}; +use boojum::cs::traits::cs::ConstraintSystem; use boojum::field::SmallField; use boojum::gadgets::traits::round_function::CircuitRoundFunction; use boojum::gadgets::{ - boolean::Boolean, num::Num, queue::*, traits::{allocatable::CSAllocatable, allocatable::CSAllocatableExt, selectable::Selectable}, @@ -163,18 +161,10 @@ where let mut proof_witnesses = proof_witnesses; - // use this and deal with borrow checker - - let r = cs as *mut CS; - assert_eq!(vk_fixed_parameters.parameters, verifier_builder.geometry()); let verifier = verifier_builder.create_recursive_verifier(cs); - drop(cs); - - let cs = unsafe { &mut *r }; - let subqueues = split_queue_state_into_n(cs, queue_state, node_layer_capacity, split_points); let leaf_layer_capacity = UInt32::allocated_constant(cs, leaf_layer_capacity as u32); diff --git a/crates/zkevm_circuits/src/recursion/recursion_tip/input.rs b/crates/zkevm_circuits/src/recursion/recursion_tip/input.rs new file mode 100644 index 0000000..5e5629e --- /dev/null +++ b/crates/zkevm_circuits/src/recursion/recursion_tip/input.rs @@ -0,0 +1,63 @@ +use super::*; +use boojum::cs::implementations::proof::Proof; +use boojum::cs::implementations::verifier::VerificationKey; +use boojum::cs::{traits::cs::ConstraintSystem, Variable}; +use boojum::field::SmallField; + +use boojum::gadgets::traits::auxiliary::PrettyComparison; +use boojum::gadgets::{ + boolean::Boolean, + traits::{ + allocatable::*, encodable::CircuitVarLengthEncodable, selectable::Selectable, + witnessable::WitnessHookable, + }, +}; +use cs_derive::*; + +use crate::base_structures::vm_state::*; +use boojum::gadgets::num::Num; + +use crate::recursion::leaf_layer::input::RecursionLeafParameters; +use boojum::field::FieldExtension; +use boojum::serde_utils::BigArraySerde; + +pub const RECURSION_TIP_ARITY: usize = 32; + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +#[DerivePrettyComparison("true")] +pub struct RecursionTipInput { + pub leaf_layer_parameters: [RecursionLeafParameters; NUM_BASE_LAYER_CIRCUITS], + pub node_layer_vk_commitment: [Num; VK_COMMITMENT_LENGTH], + pub branch_circuit_type_set: [Num; RECURSION_TIP_ARITY], + pub queue_set: [QueueState; RECURSION_TIP_ARITY], +} + +impl CSPlaceholder for RecursionTipInput { + fn placeholder>(cs: &mut CS) -> Self { + let zero = Num::zero(cs); + let leaf_layer_param = RecursionLeafParameters::placeholder(cs); + Self { + leaf_layer_parameters: [leaf_layer_param; NUM_BASE_LAYER_CIRCUITS], + node_layer_vk_commitment: [zero; VK_COMMITMENT_LENGTH], + branch_circuit_type_set: [zero; RECURSION_TIP_ARITY], + queue_set: [QueueState::::placeholder(cs); + RECURSION_TIP_ARITY], + } + } +} + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Debug, Default(bound = "RecursionTipInputWitness: Default"))] +#[serde( + bound = ">::Witness: serde::Serialize + serde::de::DeserializeOwned" +)] +pub struct RecursionTipInstanceWitness< + F: SmallField, + H: RecursiveTreeHasher>, + EXT: FieldExtension<2, BaseField = F>, +> { + pub input: RecursionTipInputWitness, + pub vk_witness: VerificationKey, + pub proof_witnesses: VecDeque>, +} diff --git a/crates/zkevm_circuits/src/recursion/recursion_tip/mod.rs b/crates/zkevm_circuits/src/recursion/recursion_tip/mod.rs new file mode 100644 index 0000000..acc9cc0 --- /dev/null +++ b/crates/zkevm_circuits/src/recursion/recursion_tip/mod.rs @@ -0,0 +1,184 @@ +use crate::base_structures::recursion_query::RecursionQuery; +use crate::fsm_input_output::commit_variable_length_encodable_item; + +use boojum::cs::implementations::prover::ProofConfig; + +use boojum::gadgets::recursion::allocated_proof::AllocatedProof; +use boojum::gadgets::recursion::allocated_vk::AllocatedVerificationKey; +use boojum::gadgets::recursion::recursive_transcript::RecursiveTranscript; +use boojum::gadgets::recursion::recursive_tree_hasher::RecursiveTreeHasher; + +use crate::fsm_input_output::circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH; +use boojum::algebraic_props::round_function::AlgebraicRoundFunction; +use boojum::cs::traits::cs::ConstraintSystem; +use boojum::field::SmallField; +use boojum::gadgets::traits::round_function::CircuitRoundFunction; +use boojum::gadgets::{ + num::Num, + queue::*, + traits::{allocatable::CSAllocatable, allocatable::CSAllocatableExt}, +}; +use std::collections::VecDeque; + +use super::*; + +pub mod input; + +use self::input::*; + +use boojum::cs::implementations::verifier::VerificationKeyCircuitGeometry; +use boojum::cs::oracle::TreeHasher; +use boojum::field::FieldExtension; +use boojum::gadgets::recursion::circuit_pow::RecursivePoWRunner; +use boojum::gadgets::recursion::recursive_transcript::CircuitTranscript; +use boojum::gadgets::recursion::recursive_tree_hasher::CircuitTreeHasher; + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Debug(bound = ""))] +#[serde(bound = "H::Output: serde::Serialize + serde::de::DeserializeOwned")] +pub struct RecursionTipConfig< + F: SmallField, + H: TreeHasher, + EXT: FieldExtension<2, BaseField = F>, +> { + pub proof_config: ProofConfig, + pub vk_fixed_parameters: VerificationKeyCircuitGeometry, + pub _marker: std::marker::PhantomData<(F, H, EXT)>, +} + +use boojum::cs::traits::circuit::*; + +pub fn recursion_tip_entry_point< + F: SmallField, + CS: ConstraintSystem + 'static, + R: CircuitRoundFunction + AlgebraicRoundFunction, + H: RecursiveTreeHasher>, + EXT: FieldExtension<2, BaseField = F>, + TR: RecursiveTranscript< + F, + CompatibleCap = >::Output, + CircuitReflection = CTR, + >, + CTR: CircuitTranscript< + F, + CircuitCompatibleCap = >>::CircuitOutput, + TransciptParameters = TR::TransciptParameters, + >, + POW: RecursivePoWRunner, +>( + cs: &mut CS, + witness: RecursionTipInstanceWitness, + round_function: &R, + config: RecursionTipConfig, + verifier_builder: Box>, + transcript_params: TR::TransciptParameters, +) -> [Num; INPUT_OUTPUT_COMMITMENT_LENGTH] +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + let RecursionTipInstanceWitness { + input, + vk_witness, + proof_witnesses, + } = witness; + + let input = RecursionTipInput::allocate(cs, input); + let RecursionTipInput { + node_layer_vk_commitment, + leaf_layer_parameters, + branch_circuit_type_set, + queue_set, + } = input; + + assert_eq!(config.vk_fixed_parameters, vk_witness.fixed_parameters,); + + let vk = AllocatedVerificationKey::::allocate(cs, vk_witness); + assert_eq!( + vk.setup_merkle_tree_cap.len(), + config.vk_fixed_parameters.cap_size + ); + let vk_commitment_computed: [_; VK_COMMITMENT_LENGTH] = + commit_variable_length_encodable_item(cs, &vk, round_function); + // self-check that it's indeed NODE + for (a, b) in node_layer_vk_commitment + .iter() + .zip(vk_commitment_computed.iter()) + { + Num::enforce_equal(cs, a, b); + } + // from that moment we can just use allocated key to verify below + + let RecursionTipConfig { + proof_config, + vk_fixed_parameters, + .. + } = config; + + let mut proof_witnesses = proof_witnesses; + + assert_eq!(vk_fixed_parameters.parameters, verifier_builder.geometry()); + let verifier = verifier_builder.create_recursive_verifier(cs); + + for (branch_type, initial_queue) in branch_circuit_type_set + .into_iter() + .zip(queue_set.into_iter()) + { + if crate::config::CIRCUIT_VERSOBE { + use boojum::gadgets::traits::witnessable::WitnessHookable; + dbg!(branch_type.witness_hook(cs)()); + dbg!(initial_queue.witness_hook(cs)()); + } + + let proof_witness = proof_witnesses.pop_front(); + + let proof = AllocatedProof::allocate_from_witness( + cs, + proof_witness, + &verifier, + &vk_fixed_parameters, + &proof_config, + ); + + let chunk_is_empty = initial_queue.tail.length.is_zero(cs); + let chunk_is_meaningful = chunk_is_empty.negated(cs); + + // verify the proof + let (is_valid, public_inputs) = verifier.verify::( + cs, + transcript_params.clone(), + &proof, + &vk_fixed_parameters, + &proof_config, + &vk, + ); + + is_valid.conditionally_enforce_true(cs, chunk_is_meaningful); + + use crate::recursion::node_layer::input::RecursionNodeInput; + let input = RecursionNodeInput { + branch_circuit_type: branch_type, + leaf_layer_parameters: leaf_layer_parameters, + node_layer_vk_commitment: node_layer_vk_commitment, + queue_state: initial_queue, + }; + let input_commitment: [_; INPUT_OUTPUT_COMMITMENT_LENGTH] = + commit_variable_length_encodable_item(cs, &input, round_function); + + assert_eq!(public_inputs.len(), INPUT_OUTPUT_COMMITMENT_LENGTH); + for (a, b) in input_commitment.iter().zip(public_inputs.into_iter()) { + Num::conditionally_enforce_equal(cs, chunk_is_meaningful, a, &b); + } + } + + let input_commitment: [_; INPUT_OUTPUT_COMMITMENT_LENGTH] = + commit_variable_length_encodable_item(cs, &input, round_function); + // NOTE: we usually put inputs as fixed places for all recursive circuits, even though for this type + // we do not have to do it strictly speaking + + // for el in input_commitment.iter() { + // let gate = PublicInputGate::new(el.get_variable()); + // gate.add_to_cs(cs); + // } + + input_commitment +} diff --git a/crates/zkevm_circuits/src/scheduler/auxiliary.rs b/crates/zkevm_circuits/src/scheduler/auxiliary.rs index 39ec706..9b9e1a1 100644 --- a/crates/zkevm_circuits/src/scheduler/auxiliary.rs +++ b/crates/zkevm_circuits/src/scheduler/auxiliary.rs @@ -1,3 +1,5 @@ +use std::iter::once; + use crate::fsm_input_output::circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH; use crate::fsm_input_output::commit_variable_length_encodable_item; @@ -14,7 +16,7 @@ use boojum::gadgets::traits::round_function::CircuitRoundFunction; use boojum::gadgets::{boolean::Boolean, num::Num, queue::*, traits::selectable::Selectable}; use crate::base_structures::precompile_input_outputs::*; -use crate::eip_4844::input::EIP4844OutputData; + use crate::log_sorter::input::*; use crate::storage_application::input::*; use boojum::gadgets::u8::UInt8; @@ -41,11 +43,14 @@ pub enum BaseLayerCircuitType { EventsRevertsFilter = 11, L1MessagesRevertsFilter = 12, L1MessagesHasher = 13, + TransientStorageChecker = 14, + Secp256r1Verify = 15, + EIP4844Repack = 255, } impl BaseLayerCircuitType { pub fn from_numeric_value(value: u8) -> Self { - match value { + let t: Self = match value { a if a == Self::VM as u8 => Self::VM, a if a == Self::DecommitmentsFilter as u8 => Self::DecommitmentsFilter, a if a == Self::Decommiter as u8 => Self::Decommiter, @@ -59,10 +64,20 @@ impl BaseLayerCircuitType { a if a == Self::EventsRevertsFilter as u8 => Self::EventsRevertsFilter, a if a == Self::L1MessagesRevertsFilter as u8 => Self::L1MessagesRevertsFilter, a if a == Self::L1MessagesHasher as u8 => Self::L1MessagesHasher, + a if a == Self::TransientStorageChecker as u8 => Self::TransientStorageChecker, + a if a == Self::Secp256r1Verify as u8 => Self::Secp256r1Verify, + a if a == Self::EIP4844Repack as u8 => Self::EIP4844Repack, _ => { - panic!("unknown circuit type {}", value) + panic!("unknown circuit type {}", value); } - } + }; + + t + } + + pub fn as_iter_u8() -> impl Iterator { + (BaseLayerCircuitType::VM as u8..=BaseLayerCircuitType::Secp256r1Verify as u8) + .chain(once(BaseLayerCircuitType::EIP4844Repack as u8)) } } @@ -169,6 +184,38 @@ pub(crate) fn compute_filter_circuit_commitment< (input_data_commitment, output_data_commitment) } +#[track_caller] +pub(crate) fn compute_transient_storage_checker_circuit_commitment< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, +>( + cs: &mut CS, + queue_state_before: &QueueState, + intermediate_queue_state: &QueueTailState, + round_function: &R, +) -> ( + [Num; CLOSED_FORM_COMMITTMENT_LENGTH], + [Num; CLOSED_FORM_COMMITTMENT_LENGTH], +) { + use crate::transient_storage_validity_by_grand_product::input::TransientStorageDeduplicatorInputData; + + let mut full_state = QueueState::empty(cs); + full_state.tail = *intermediate_queue_state; + let transient_input_data = TransientStorageDeduplicatorInputData { + unsorted_log_queue_state: queue_state_before.clone(), + intermediate_sorted_queue_state: full_state, + }; + let input_data_commitment = + commit_variable_length_encodable_item(cs, &transient_input_data, round_function); + + let output_data = (); + let output_data_commitment = + commit_variable_length_encodable_item(cs, &output_data, round_function); + + (input_data_commitment, output_data_commitment) +} + #[track_caller] pub(crate) fn compute_storage_applicator_circuit_commitment< F: SmallField, diff --git a/crates/zkevm_circuits/src/scheduler/block_header/mod.rs b/crates/zkevm_circuits/src/scheduler/block_header/mod.rs index 011593c..7d5af24 100644 --- a/crates/zkevm_circuits/src/scheduler/block_header/mod.rs +++ b/crates/zkevm_circuits/src/scheduler/block_header/mod.rs @@ -20,7 +20,7 @@ use boojum::serde_utils::BigArraySerde; use boojum::gadgets::keccak256; pub const NUM_SHARDS: usize = 2; -pub const MAX_4844_BLOBS_PER_BLOCK: usize = 2; +pub const MAX_4844_BLOBS_PER_BLOCK: usize = 16; // Data that represents a pure state #[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] @@ -44,6 +44,7 @@ pub struct BlockMetaParameters { pub zkporter_is_available: Boolean, pub bootloader_code_hash: UInt256, pub default_aa_code_hash: UInt256, + pub evm_simulator_code_hash: UInt256, } // This is the information that represents artifacts only meaningful for this block, that will not be used for any @@ -113,6 +114,7 @@ impl BlockMetaParameters { result.extend_from_slice(&self.bootloader_code_hash.to_be_bytes(cs)); result.extend_from_slice(&self.default_aa_code_hash.to_be_bytes(cs)); + result.extend_from_slice(&self.evm_simulator_code_hash.to_be_bytes(cs)); result } diff --git a/crates/zkevm_circuits/src/scheduler/input.rs b/crates/zkevm_circuits/src/scheduler/input.rs index 7d4f314..e9d4b9a 100644 --- a/crates/zkevm_circuits/src/scheduler/input.rs +++ b/crates/zkevm_circuits/src/scheduler/input.rs @@ -1,6 +1,5 @@ use super::*; use boojum::cs::implementations::proof::Proof; -use boojum::cs::implementations::verifier::VerificationKey; use boojum::field::SmallField; @@ -49,6 +48,7 @@ pub struct SchedulerCircuitInstanceWitness< pub keccak256_observable_output: PrecompileFunctionOutputDataWitness, pub sha256_observable_output: PrecompileFunctionOutputDataWitness, pub ecrecover_observable_output: PrecompileFunctionOutputDataWitness, + pub secp256r1_verify_observable_output: PrecompileFunctionOutputDataWitness, // RAM permutation doesn't produce anything pub storage_sorter_observable_output: StorageDeduplicatorOutputDataWitness, pub storage_application_observable_output: StorageApplicationOutputDataWitness, @@ -69,22 +69,19 @@ pub struct SchedulerCircuitInstanceWitness< pub rollup_storage_sorter_intermediate_queue_state: QueueTailStateWitness, pub events_sorter_intermediate_queue_state: QueueTailStateWitness, pub l1messages_sorter_intermediate_queue_state: QueueTailStateWitness, + pub transient_storage_sorter_intermediate_queue_state: + QueueTailStateWitness, // extra information about the previous block pub previous_block_meta_hash: [u8; 32], pub previous_block_aux_hash: [u8; 32], // eip4844 witnesses - pub eip4844_witnesses: Option<[EIP4844OutputDataWitness; MAX_4844_BLOBS_PER_BLOCK]>, - pub eip4844_proofs: VecDeque>, + pub eip4844_witnesses: [Option>; MAX_4844_BLOBS_PER_BLOCK], // proofs for every individual circuit type's aggregation subtree #[derivative(Debug = "ignore")] pub proof_witnesses: VecDeque>, - #[derivative(Debug = "ignore")] - pub node_layer_vk_witness: VerificationKey, - #[derivative(Debug = "ignore")] - pub leaf_layer_parameters: [RecursionLeafParametersWitness; NUM_BASE_LAYER_CIRCUITS], } impl>, EXT: FieldExtension<2, BaseField = F>> @@ -100,9 +97,12 @@ impl>, EXT: FieldExtension<2, Ba CodeDecommittmentsDeduplicatorOutputData::placeholder_witness(), code_decommitter_observable_output: CodeDecommitterOutputData::placeholder_witness(), log_demuxer_observable_output: LogDemuxerOutputData::placeholder_witness(), + keccak256_observable_output: PrecompileFunctionOutputData::placeholder_witness(), sha256_observable_output: PrecompileFunctionOutputData::placeholder_witness(), ecrecover_observable_output: PrecompileFunctionOutputData::placeholder_witness(), + secp256r1_verify_observable_output: PrecompileFunctionOutputData::placeholder_witness(), + storage_sorter_observable_output: StorageDeduplicatorOutputData::placeholder_witness(), storage_application_observable_output: StorageApplicationOutputData::placeholder_witness(), @@ -122,18 +122,15 @@ impl>, EXT: FieldExtension<2, Ba rollup_storage_sorter_intermediate_queue_state: QueueTailState::placeholder_witness(), events_sorter_intermediate_queue_state: QueueTailState::placeholder_witness(), l1messages_sorter_intermediate_queue_state: QueueTailState::placeholder_witness(), + transient_storage_sorter_intermediate_queue_state: QueueTailState::placeholder_witness( + ), previous_block_meta_hash: [0u8; 32], previous_block_aux_hash: [0u8; 32], - eip4844_witnesses: None, - eip4844_proofs: VecDeque::new(), + eip4844_witnesses: std::array::from_fn(|_| None), proof_witnesses: VecDeque::new(), - node_layer_vk_witness: VerificationKey::default(), - leaf_layer_parameters: std::array::from_fn(|_| { - RecursionLeafParameters::placeholder_witness() - }), } } } diff --git a/crates/zkevm_circuits/src/scheduler/mod.rs b/crates/zkevm_circuits/src/scheduler/mod.rs index 36dfb5c..5a866a0 100644 --- a/crates/zkevm_circuits/src/scheduler/mod.rs +++ b/crates/zkevm_circuits/src/scheduler/mod.rs @@ -9,9 +9,6 @@ use self::input::*; pub mod auxiliary; pub use auxiliary as aux; -use boojum::cs::implementations::proof::Proof; - -use boojum::cs::implementations::verifier::VerificationKey; use boojum::cs::traits::cs::ConstraintSystem; use boojum::field::SmallField; @@ -33,8 +30,12 @@ use crate::base_structures::memory_query::MemoryQuery; use crate::base_structures::memory_query::MemoryQueue; use crate::base_structures::recursion_query::*; +use crate::demux_log_queue::DemuxOutput; use crate::fsm_input_output::circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH; use crate::linear_hasher::input::LinearHasherOutputData; +use crate::main_vm::opcodes::normalize_bytecode_hash_for_decommit; +use crate::recursion::recursion_tip::input::RecursionTipInput; +use crate::recursion::recursion_tip::input::RECURSION_TIP_ARITY; use crate::recursion::VK_COMMITMENT_LENGTH; use crate::scheduler::auxiliary::NUM_CIRCUIT_TYPES_TO_SCHEDULE; use crate::utils::is_equal_queue_state; @@ -42,6 +43,7 @@ use boojum::gadgets::num::Num; use boojum::gadgets::recursion::recursive_tree_hasher::RecursiveTreeHasher; use crate::base_structures::precompile_input_outputs::*; +use crate::recursion::NUM_BASE_LAYER_CIRCUITS; use boojum::algebraic_props::round_function::AlgebraicRoundFunction; use boojum::cs::implementations::prover::ProofConfig; use boojum::cs::implementations::verifier::VerificationKeyCircuitGeometry; @@ -56,6 +58,7 @@ use boojum::gadgets::traits::round_function::CircuitRoundFunction; use std::collections::HashMap; use crate::base_structures::vm_state::*; +use crate::boojum::cs::implementations::verifier::VerificationKey; use crate::code_unpacker_sha256::input::*; use crate::demux_log_queue::input::*; use crate::eip_4844::input::*; @@ -64,7 +67,6 @@ use crate::fsm_input_output::*; use crate::log_sorter::input::*; use crate::ram_permutation::input::*; use crate::recursion::leaf_layer::input::*; -use crate::recursion::node_layer::input::*; use crate::scheduler::auxiliary::*; use crate::sort_decommittment_requests::input::*; use crate::storage_application::input::*; @@ -74,9 +76,10 @@ pub const SCHEDULER_TIMESTAMP: u32 = 1; pub const NUM_SCHEDULER_PUBLIC_INPUTS: usize = 4; pub const LEAF_LAYER_PARAMETERS_COMMITMENT_LENGTH: usize = 4; pub const QUEUE_FINAL_STATE_COMMITMENT_LENGTH: usize = 4; -pub const IMPLEMENT_4844_FUNCTIONALITY: bool = false; +pub const NUM_CIRCUITS_FOR_VARIABLE_SCHEDULING: usize = NUM_CIRCUIT_TYPES_TO_SCHEDULE - 1; +pub const NUM_RECURSION_TIPS_USED: usize = 1; -pub const SEQUENCE_OF_CIRCUIT_TYPES: [BaseLayerCircuitType; NUM_CIRCUIT_TYPES_TO_SCHEDULE] = [ +pub const SEQUENCE_OF_CIRCUIT_TYPES: [BaseLayerCircuitType; NUM_CIRCUITS_FOR_VARIABLE_SCHEDULING] = [ BaseLayerCircuitType::VM, BaseLayerCircuitType::DecommitmentsFilter, BaseLayerCircuitType::Decommiter, @@ -90,6 +93,8 @@ pub const SEQUENCE_OF_CIRCUIT_TYPES: [BaseLayerCircuitType; NUM_CIRCUIT_TYPES_TO BaseLayerCircuitType::EventsRevertsFilter, BaseLayerCircuitType::L1MessagesRevertsFilter, BaseLayerCircuitType::L1MessagesHasher, + BaseLayerCircuitType::TransientStorageChecker, + BaseLayerCircuitType::Secp256r1Verify, ]; #[derive(Derivative, serde::Serialize, serde::Deserialize)] @@ -98,6 +103,12 @@ pub const SEQUENCE_OF_CIRCUIT_TYPES: [BaseLayerCircuitType; NUM_CIRCUIT_TYPES_TO pub struct SchedulerConfig, EXT: FieldExtension<2, BaseField = F>> { pub proof_config: ProofConfig, pub vk_fixed_parameters: VerificationKeyCircuitGeometry, + #[derivative(Debug = "ignore")] + pub recursion_tip_vk: VerificationKey, + #[derivative(Debug = "ignore")] + pub node_layer_vk: VerificationKey, + #[derivative(Debug = "ignore")] + pub leaf_layer_parameters: [RecursionLeafParametersWitness; NUM_BASE_LAYER_CIRCUITS], pub capacity: usize, pub _marker: std::marker::PhantomData<(F, H, EXT)>, } @@ -126,22 +137,21 @@ pub fn scheduler_function< round_function: &R, config: SchedulerConfig, verifier_builder: Box>, - eip4844_proof_config: Option, - eip4844_vk_fixed_parameters: Option, - eip4844_vk: Option>, - eip4844_verifier_builder: Option>>, transcript_params: TR::TransciptParameters, ) where [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, { + assert!(NUM_RECURSION_TIPS_USED * RECURSION_TIP_ARITY >= NUM_CIRCUIT_TYPES_TO_SCHEDULE); + let prev_block_data = BlockPassthroughData::allocate(cs, witness.prev_block_data.clone()); let block_meta_parameters = BlockMetaParameters::allocate(cs, witness.block_meta_parameters.clone()); let boolean_false = Boolean::allocated_constant(cs, false); let boolean_true = Boolean::allocated_constant(cs, true); + let zero_u8 = UInt8::zero(cs); Boolean::enforce_equal( cs, @@ -158,7 +168,8 @@ pub fn scheduler_function< initial_memory_queue_state.length = bootloader_heap_memory_state.length; let mut decommittments_queue = DecommitQueue::::empty(cs); - let bootloader_code_hash = block_meta_parameters.bootloader_code_hash; + let mut bootloader_code_hash = block_meta_parameters.bootloader_code_hash; + normalize_bytecode_hash_for_decommit(cs, &mut bootloader_code_hash); let bootloader_code_page = UInt32::allocated_constant(cs, zkevm_opcode_defs::BOOTLOADER_CODE_PAGE); let scheduler_timestamp = UInt32::allocated_constant(cs, SCHEDULER_TIMESTAMP); @@ -196,6 +207,11 @@ pub fn scheduler_function< let ecrecover_observable_output = PrecompileFunctionOutputData::allocate(cs, witness.ecrecover_observable_output.clone()); + let secp256r1_verify_observable_output = PrecompileFunctionOutputData::allocate( + cs, + witness.secp256r1_verify_observable_output.clone(), + ); + let storage_sorter_observable_output = StorageDeduplicatorOutputData::allocate( cs, witness.storage_sorter_observable_output.clone(), @@ -233,15 +249,21 @@ pub fn scheduler_function< witness.l1messages_sorter_intermediate_queue_state.clone(), ); + let transient_storage_sorter_intermediate_queue_state = QueueTailState::allocate( + cs, + witness + .transient_storage_sorter_intermediate_queue_state + .clone(), + ); + // final VM storage log state for our construction let storage_log_tail = <[Num; QUEUE_STATE_WIDTH]>::allocate(cs, witness.storage_log_tail); // form the VM input - let default_aa_code_hash = block_meta_parameters.default_aa_code_hash; - let global_context = GlobalContext { zkporter_is_available: block_meta_parameters.zkporter_is_available, - default_aa_code_hash, + default_aa_code_hash: block_meta_parameters.default_aa_code_hash, + evm_simulator_code_hash: block_meta_parameters.evm_simulator_code_hash, }; // we can form all the observable inputs already as those are just functions of observable outputs @@ -304,12 +326,20 @@ pub fn scheduler_function< commit_variable_length_encodable_item(cs, &log_demuxer_observable_output, round_function); // all intermediate queues for sorters + let keccak256_access_queue_state = + log_demuxer_observable_output.output_queue_states[DemuxOutput::Keccak as usize]; + let sha256_access_queue_state = + log_demuxer_observable_output.output_queue_states[DemuxOutput::Sha256 as usize]; + let ecrecover_access_queue_state = + log_demuxer_observable_output.output_queue_states[DemuxOutput::ECRecover as usize]; + let secp256r1_verify_access_queue_state = + log_demuxer_observable_output.output_queue_states[DemuxOutput::Secp256r1Verify as usize]; // precompiles: keccak, sha256 and ecrecover let (keccak_circuit_observable_input_commitment, keccak_circuit_observable_output_commitment) = compute_precompile_commitment( cs, - &log_demuxer_observable_output.keccak256_access_queue_state, + &keccak256_access_queue_state, &code_decommitter_observable_output.memory_queue_final_state, &keccak256_observable_output.final_memory_state, round_function, @@ -317,7 +347,7 @@ pub fn scheduler_function< let (sha256_circuit_observable_input_commitment, sha256_circuit_observable_output_commitment) = compute_precompile_commitment( cs, - &log_demuxer_observable_output.sha256_access_queue_state, + &sha256_access_queue_state, &keccak256_observable_output.final_memory_state, &sha256_observable_output.final_memory_state, round_function, @@ -327,11 +357,21 @@ pub fn scheduler_function< ecrecover_circuit_observable_output_commitment, ) = compute_precompile_commitment( cs, - &log_demuxer_observable_output.ecrecover_access_queue_state, + &ecrecover_access_queue_state, &sha256_observable_output.final_memory_state, &ecrecover_observable_output.final_memory_state, round_function, ); + let ( + secp256r1_verify_circuit_observable_input_commitment, + secp256r1_verify_circuit_observable_output_commitment, + ) = compute_precompile_commitment( + cs, + &secp256r1_verify_access_queue_state, + &ecrecover_observable_output.final_memory_state, + &secp256r1_verify_observable_output.final_memory_state, + round_function, + ); // ram permutation and validation // NBL this circuit is terminal - it has no actual output @@ -341,17 +381,24 @@ pub fn scheduler_function< QueueTailState::allocate(cs, witness.ram_sorted_queue_state.clone()); let ram_validation_circuit_input = RamPermutationInputData { - unsorted_queue_initial_state: ecrecover_observable_output.final_memory_state, + unsorted_queue_initial_state: secp256r1_verify_observable_output.final_memory_state, sorted_queue_initial_state: ram_sorted_queue_state, non_deterministic_bootloader_memory_snapshot_length: bootloader_heap_memory_state.length, }; let ram_validation_circuit_input_commitment = commit_variable_length_encodable_item(cs, &ram_validation_circuit_input, round_function); + let events_access_queue_state = + log_demuxer_observable_output.output_queue_states[DemuxOutput::Events as usize]; + let l1messages_access_queue_state = + log_demuxer_observable_output.output_queue_states[DemuxOutput::L2ToL1Messages as usize]; + let transient_storage_access_queue_state = + log_demuxer_observable_output.output_queue_states[DemuxOutput::TransientStorage as usize]; + // events reverts filter and merkelization let (events_filter_input_com, events_filter_output_com) = compute_filter_circuit_commitment( cs, - &log_demuxer_observable_output.events_access_queue_state, + &events_access_queue_state, &events_sorter_intermediate_queue_state, &events_sorter_observable_output.final_queue_state, round_function, @@ -369,7 +416,7 @@ pub fn scheduler_function< let (l1_messages_filter_input_com, l1_messages_filter_output_com) = compute_filter_circuit_commitment( cs, - &log_demuxer_observable_output.l1messages_access_queue_state, + &l1messages_access_queue_state, &l1messages_sorter_intermediate_queue_state, &l1messages_sorter_observable_output.final_queue_state, round_function, @@ -383,6 +430,18 @@ pub fn scheduler_function< round_function, ); + // transient storage is independent of shards + + let (transient_storage_checker_input_com, transient_storage_checker_output_com) = + compute_transient_storage_checker_circuit_commitment( + cs, + &transient_storage_access_queue_state, + &transient_storage_sorter_intermediate_queue_state, + round_function, + ); + + // and persistent storage is processed for rollup part only + const NUM_PROCESSABLE_SHARDS: usize = 1; let zero_num = Num::zero(cs); @@ -397,7 +456,10 @@ pub fn scheduler_function< let mut storage_applicator_output_commitments = [empty_input_output_commitment; NUM_PROCESSABLE_SHARDS]; - let storage_queues_state = [log_demuxer_observable_output.storage_access_queue_state]; + let rollup_storage_access_queue_state = + log_demuxer_observable_output.output_queue_states[DemuxOutput::RollupStorage as usize]; + + let storage_queues_state = [rollup_storage_access_queue_state]; let filtered_storage_queues_state = [storage_sorter_observable_output.final_sorted_queue_state]; @@ -507,6 +569,14 @@ pub fn scheduler_function< BaseLayerCircuitType::L1MessagesHasher, l1_messages_hasher_input_com, ), + ( + BaseLayerCircuitType::TransientStorageChecker, + transient_storage_checker_input_com, + ), + ( + BaseLayerCircuitType::Secp256r1Verify, + secp256r1_verify_circuit_observable_input_commitment, + ), ] .into_iter(), ); @@ -563,17 +633,34 @@ pub fn scheduler_function< BaseLayerCircuitType::L1MessagesHasher, l1_messages_hasher_output_com, ), + ( + BaseLayerCircuitType::TransientStorageChecker, + transient_storage_checker_output_com, + ), + ( + BaseLayerCircuitType::Secp256r1Verify, + secp256r1_verify_circuit_observable_output_commitment, + ), ] .into_iter(), ); + assert_eq!( + input_commitments_as_map.len(), + NUM_CIRCUITS_FOR_VARIABLE_SCHEDULING + ); + assert_eq!( + output_commitments_as_map.len(), + NUM_CIRCUITS_FOR_VARIABLE_SCHEDULING + ); + // self-check for pair in SEQUENCE_OF_CIRCUIT_TYPES.windows(2) { assert_eq!((pair[0] as u8) + 1, pair[1] as u8); } // we can potentially skip some circuits - let mut skip_flags = [None; NUM_CIRCUIT_TYPES_TO_SCHEDULE]; + let mut skip_flags = [None; NUM_CIRCUITS_FOR_VARIABLE_SCHEDULING]; // we can skip everything except VM // and if we skip, then we should ensure some invariants over outputs! @@ -622,7 +709,7 @@ pub fn scheduler_function< .is_zero(cs); for subqueue in log_demuxer_observable_output - .all_output_queues_refs() + .output_queue_states .into_iter() { let output_queue_is_empty = subqueue.tail.length.is_zero(cs); @@ -634,11 +721,7 @@ pub fn scheduler_function< // keccak, sha256 and ecrecover must not modify memory { - let should_skip = log_demuxer_observable_output - .keccak256_access_queue_state - .tail - .length - .is_zero(cs); + let should_skip = keccak256_access_queue_state.tail.length.is_zero(cs); let input_state = code_decommitter_observable_output.memory_queue_final_state; let output_state = keccak256_observable_output.final_memory_state; @@ -649,11 +732,7 @@ pub fn scheduler_function< skip_flags[(BaseLayerCircuitType::KeccakPrecompile as u8 as usize) - 1] = Some(should_skip); } { - let should_skip = log_demuxer_observable_output - .sha256_access_queue_state - .tail - .length - .is_zero(cs); + let should_skip = sha256_access_queue_state.tail.length.is_zero(cs); let input_state = keccak256_observable_output.final_memory_state; let output_state = sha256_observable_output.final_memory_state; @@ -664,11 +743,7 @@ pub fn scheduler_function< skip_flags[(BaseLayerCircuitType::Sha256Precompile as u8 as usize) - 1] = Some(should_skip); } { - let should_skip = log_demuxer_observable_output - .ecrecover_access_queue_state - .tail - .length - .is_zero(cs); + let should_skip = ecrecover_access_queue_state.tail.length.is_zero(cs); let input_state = sha256_observable_output.final_memory_state; let output_state = ecrecover_observable_output.final_memory_state; @@ -679,6 +754,17 @@ pub fn scheduler_function< skip_flags[(BaseLayerCircuitType::EcrecoverPrecompile as u8 as usize) - 1] = Some(should_skip); } + { + let should_skip = secp256r1_verify_access_queue_state.tail.length.is_zero(cs); + + let input_state = ecrecover_observable_output.final_memory_state; + let output_state = secp256r1_verify_observable_output.final_memory_state; + + let same_state = is_equal_queue_state(cs, &input_state, &output_state); + same_state.conditionally_enforce_true(cs, should_skip); + + skip_flags[(BaseLayerCircuitType::Secp256r1Verify as u8 as usize) - 1] = Some(should_skip); + } // well, in the very unlikely case of no RAM requests (that is unreachable because VM always starts) we just skip it as is skip_flags[(BaseLayerCircuitType::RamValidation as u8 as usize) - 1] = Some( @@ -742,11 +828,7 @@ pub fn scheduler_function< } // events and l2 to l1 messages filters should produce empty output { - let should_skip = log_demuxer_observable_output - .events_access_queue_state - .tail - .length - .is_zero(cs); + let should_skip = events_access_queue_state.tail.length.is_zero(cs); let output_queue_is_empty = events_sorter_observable_output .final_queue_state @@ -759,11 +841,7 @@ pub fn scheduler_function< Some(should_skip); } { - let should_skip = log_demuxer_observable_output - .l1messages_access_queue_state - .tail - .length - .is_zero(cs); + let should_skip = l1messages_access_queue_state.tail.length.is_zero(cs); let output_queue_is_empty = l1messages_sorter_observable_output .final_queue_state @@ -775,22 +853,55 @@ pub fn scheduler_function< skip_flags[(BaseLayerCircuitType::L1MessagesRevertsFilter as u8 as usize) - 1] = Some(should_skip); } + // transient storage doesn't produce an output + { + let should_skip = transient_storage_access_queue_state.tail.length.is_zero(cs); + skip_flags[(BaseLayerCircuitType::TransientStorageChecker as u8 as usize) - 1] = + Some(should_skip); + } + // L2 to L1 linear hasher + { + let empty_hash = { + use zkevm_opcode_defs::sha3::*; - // for (idx, el) in skip_flags.iter().enumerate() { - // if let Some(el) = el { - // let circuit_type = BaseLayerCircuitType::from_numeric_value((idx+1) as u8); - // println!("Skip for {:?} = {:?}", circuit_type, el.witness_hook(cs)()); - // } - // } + let mut result = [0u8; 32]; + let digest = Keccak256::digest(&[]); + result.copy_from_slice(digest.as_slice()); - // In practice we do NOT skip it - // skip_flags[(BaseLayerCircuitType::L1MessagesHasher as u8 as usize) - 1] = Some( - // l1messages_sorter_observable_output.final_queue_state.tail.length.is_zero(cs) - // ); + result.map(|el| UInt8::allocated_constant(cs, el)) + }; + + let should_skip = l1messages_access_queue_state.tail.length.is_zero(cs); + + // if nothing to hash, we expect empty hash + for (a, b) in l1messages_linear_hasher_observable_output + .keccak256_hash + .iter() + .zip(empty_hash.iter()) + { + Num::conditionally_enforce_equal( + cs, + should_skip, + &Num::from_variable(a.get_variable()), + &Num::from_variable(b.get_variable()), + ); + } + + skip_flags[(BaseLayerCircuitType::L1MessagesHasher as u8 as usize) - 1] = Some(should_skip); + } + + if crate::config::CIRCUIT_VERSOBE { + for (idx, el) in skip_flags.iter().enumerate() { + if let Some(el) = el { + let circuit_type = BaseLayerCircuitType::from_numeric_value((idx + 1) as u8); + println!("Skip for {:?} = {:?}", circuit_type, el.witness_hook(cs)()); + } + } + } // now we just walk one by one - let mut execution_stage_bitmask = [boolean_false; NUM_CIRCUIT_TYPES_TO_SCHEDULE]; + let mut execution_stage_bitmask = [boolean_false; NUM_CIRCUITS_FOR_VARIABLE_SCHEDULING]; execution_stage_bitmask[0] = boolean_true; // VM assert_eq!( @@ -803,12 +914,12 @@ pub fn scheduler_function< let empty_recursive_queue_state_tail = QueueTailState::empty(cs); let mut recursive_queue_state_tails = - [empty_recursive_queue_state_tail; NUM_CIRCUIT_TYPES_TO_SCHEDULE]; + [empty_recursive_queue_state_tail; NUM_CIRCUITS_FOR_VARIABLE_SCHEDULING]; let mut hidden_fsm_input_to_use = [zero_num; CLOSED_FORM_COMMITTMENT_LENGTH]; for _idx in 0..config.capacity { - let mut next_mask = [boolean_false; NUM_CIRCUIT_TYPES_TO_SCHEDULE]; + let mut next_mask = [boolean_false; NUM_CIRCUITS_FOR_VARIABLE_SCHEDULING]; let closed_form_input_witness = witness .per_circuit_closed_form_inputs @@ -822,7 +933,8 @@ pub fn scheduler_function< Boolean::equals(cs, &closed_form_input.start_flag, &previous_completion_flag); start_of_next_when_previous_is_finished.conditionally_enforce_true(cs, execution_flag); - let mut computed_applicability_flags = [boolean_false; NUM_CIRCUIT_TYPES_TO_SCHEDULE]; + let mut computed_applicability_flags = + [boolean_false; NUM_CIRCUITS_FOR_VARIABLE_SCHEDULING]; let mut circuit_type_to_use = Num::zero(cs); for (idx, ((circuit_type, stage_flag), skip_flag)) in SEQUENCE_OF_CIRCUIT_TYPES @@ -848,6 +960,18 @@ pub fn scheduler_function< }; let validate_observable_input = validate; // input commitment is ALWAYS the same for all the circuits of some type + if crate::config::CIRCUIT_VERSOBE { + if validate_observable_input.witness_hook(cs)().unwrap_or(false) { + println!("Validating input for circuit type {:?}", circuit_type); + assert_eq!( + closed_form_input + .observable_input_committment + .witness_hook(cs)() + .unwrap(), + sample_circuit_commitment.witness_hook(cs)().unwrap(), + ) + } + } conditionally_enforce_circuit_commitment( cs, validate_observable_input, @@ -874,6 +998,19 @@ pub fn scheduler_function< )); // .unwrap_or([zero_num; CLOSED_FORM_COMMITTMENT_LENGTH]); + if crate::config::CIRCUIT_VERSOBE { + if validate_observable_output.witness_hook(cs)().unwrap_or(false) { + println!("Validating output for circuit type {:?}", circuit_type); + assert_eq!( + closed_form_input + .observable_output_committment + .witness_hook(cs)() + .unwrap(), + sample_circuit_commitment.witness_hook(cs)().unwrap(), + ) + } + } + conditionally_enforce_circuit_commitment( cs, validate_observable_output, @@ -889,6 +1026,11 @@ pub fn scheduler_function< let stage_just_finished = Boolean::multi_and(cs, &[should_start_next, execution_flag, *stage_flag]); + if crate::config::CIRCUIT_VERSOBE { + if stage_just_finished.witness_hook(cs)().unwrap_or(false) { + println!("Finished {:?} circuit type", circuit_type); + } + } next_mask[idx] = stage_just_finished; let circuit_type = UInt8::allocated_constant(cs, *circuit_type as u8).into_num(); @@ -962,7 +1104,7 @@ pub fn scheduler_function< previous_completion_flag = Boolean::multi_or(cs, &next_mask); // for the next stage we do shifted AND - let mut tmp = [boolean_false; NUM_CIRCUIT_TYPES_TO_SCHEDULE]; + let mut tmp = [boolean_false; NUM_CIRCUITS_FOR_VARIABLE_SCHEDULING]; // note skip(1) for (idx, start_next) in next_mask.iter().enumerate() { let finished_this_stage = *start_next; @@ -973,7 +1115,7 @@ pub fn scheduler_function< let start_as_next = tmp[idx]; let do_this_stage = Boolean::multi_or(cs, &[start_as_next, proceed_current]); execution_stage_bitmask[idx] = do_this_stage; - if idx + 1 < NUM_CIRCUIT_TYPES_TO_SCHEDULE { + if idx + 1 < NUM_CIRCUITS_FOR_VARIABLE_SCHEDULING { tmp[idx + 1] = finished_this_stage; } } @@ -988,29 +1130,88 @@ pub fn scheduler_function< // so we are done! Boolean::enforce_equal(cs, &execution_flag, &boolean_false); - // actually perform verification - let leaf_layer_parameters = witness + // NOTE: values below are allocated constant, so their values end up in + // scheduler setup -> verification key + let leaf_layer_parameters = config .leaf_layer_parameters .clone() - .map(|el| RecursionLeafParameters::allocate(cs, el)); + .map(|el| RecursionLeafParameters::allocated_constant(cs, el)); let leaf_layer_parameters_commitment: [_; LEAF_LAYER_PARAMETERS_COMMITMENT_LENGTH] = commit_variable_length_encodable_item(cs, &leaf_layer_parameters, round_function); let node_layer_vk = - AllocatedVerificationKey::::allocate(cs, witness.node_layer_vk_witness.clone()); + AllocatedVerificationKey::::allocate_constant(cs, config.node_layer_vk.clone()); let node_layer_vk_commitment: [_; VK_COMMITMENT_LENGTH] = commit_variable_length_encodable_item(cs, &node_layer_vk, round_function); + let recursion_tip_verification_key = + AllocatedVerificationKey::::allocate_constant(cs, config.recursion_tip_vk.clone()); + if crate::config::CIRCUIT_VERSOBE { dbg!(leaf_layer_parameters_commitment.witness_hook(cs)()); dbg!(node_layer_vk_commitment.witness_hook(cs)()); } - let mut proof_witnesses = witness.proof_witnesses; + // now form a queue for 4844 - // create verifier - let r = cs as *mut CS; + let mut eip4844_recursion_queue = RecursionQueue::::empty(cs); + + let (eip4844_linear_hashes, eip4844_output_commitment_hashes) = if USE_4844 { + // eip4844 circuit + let eip4844_circuit_type = Num::allocated_constant( + cs, + F::from_u64_unchecked(BaseLayerCircuitType::EIP4844Repack as u8 as u64), + ); + + let mut eip4844_linear_hashes = [[zero_u8; 32]; MAX_4844_BLOBS_PER_BLOCK]; + let mut eip4844_output_commitment_hashes = [[zero_u8; 32]; MAX_4844_BLOBS_PER_BLOCK]; + for i in 0..MAX_4844_BLOBS_PER_BLOCK { + let observable_output_data_witness = witness.eip4844_witnesses[i] + .as_ref() + .cloned() + .unwrap_or(EIP4844OutputData::placeholder_witness()); + let observable_output_data = + EIP4844OutputData::allocate(cs, observable_output_data_witness); + let zeroes = observable_output_data.linear_hash.map(|el| el.is_zero(cs)); + let skip_verification = Boolean::multi_and(cs, &zeroes); + let should_verify = skip_verification.negated(cs); + let structured_input = EIP4844InputOutput { + start_flag: boolean_true, + completion_flag: boolean_true, + observable_input: (), + observable_output: observable_output_data, + hidden_fsm_input: (), + hidden_fsm_output: (), + }; + + let closed_form_input = + ClosedFormInputCompactForm::from_full_form(cs, &structured_input, round_function); + let input_commitment = + commit_variable_length_encodable_item(cs, &closed_form_input, round_function); + // add to the queue + let recursion_query = RecursionQuery { + circuit_type: eip4844_circuit_type, + input_commitment, + }; + + let _ = eip4844_recursion_queue.push(cs, recursion_query, should_verify); + + eip4844_linear_hashes[i] = observable_output_data.linear_hash; + eip4844_output_commitment_hashes[i] = observable_output_data.output_hash; + } + + (eip4844_linear_hashes, eip4844_output_commitment_hashes) + } else { + ( + [[zero_u8; 32]; MAX_4844_BLOBS_PER_BLOCK], + [[zero_u8; 32]; MAX_4844_BLOBS_PER_BLOCK], + ) + }; + + let eip4844_recursion_queue_state = eip4844_recursion_queue.into_state().tail; + + let mut proof_witnesses = witness.proof_witnesses; assert_eq!( config.vk_fixed_parameters.parameters, @@ -1019,59 +1220,75 @@ pub fn scheduler_function< let verifier = verifier_builder.create_recursive_verifier(cs); - drop(cs); - - let cs = unsafe { &mut *r }; - - for (_idx, (circuit_type, state)) in SEQUENCE_OF_CIRCUIT_TYPES - .iter() - .zip(recursive_queue_state_tails.into_iter()) - .enumerate() { - println!("Verifying circuit type {:?}", circuit_type); - - let should_skip = state.length.is_zero(cs); - let should_verify = should_skip.negated(cs); - - let circuit_type = UInt8::allocated_constant(cs, *circuit_type as u8).into_num(); - - let mut queue_state = QueueState::empty(cs); - queue_state.tail = state; + assert_eq!( + SEQUENCE_OF_CIRCUIT_TYPES.len(), + recursive_queue_state_tails.len() + ); + let it = SEQUENCE_OF_CIRCUIT_TYPES + .into_iter() + .zip(recursive_queue_state_tails.into_iter()); + + let it = it.chain(std::iter::once(( + BaseLayerCircuitType::EIP4844Repack, + eip4844_recursion_queue_state, + ))); + + let mut it = it.enumerate(); + + for _ in 0..NUM_RECURSION_TIPS_USED { + // NOTE: even though node/leaf circuits are defined over witness-provided (input-linked) + // verification keys, here we EXPECT to have specific CONSTANT verificaion parameters + let mut recursion_tip_input = RecursionTipInput::placeholder(cs); + recursion_tip_input.leaf_layer_parameters = leaf_layer_parameters; + recursion_tip_input.node_layer_vk_commitment = node_layer_vk_commitment; + + for (circuit_type_dst, state_dst) in recursion_tip_input + .branch_circuit_type_set + .iter_mut() + .zip(recursion_tip_input.queue_set.iter_mut()) + { + if let Some((_idx, (circuit_type, state))) = it.next() { + let circuit_type = UInt8::allocated_constant(cs, circuit_type as u8).into_num(); + *circuit_type_dst = circuit_type; + let mut queue_state = QueueState::empty(cs); + queue_state.tail = state; + *state_dst = queue_state; + } + } - let input: RecursionNodeInput = RecursionNodeInput { - branch_circuit_type: circuit_type, - leaf_layer_parameters: leaf_layer_parameters, - node_layer_vk_commitment: node_layer_vk_commitment, - queue_state: queue_state, - }; + if crate::config::CIRCUIT_VERSOBE { + dbg!(recursion_tip_input.witness_hook(cs)()); + } - let expected_input_commitment: [_; INPUT_OUTPUT_COMMITMENT_LENGTH] = - commit_variable_length_encodable_item(cs, &input, round_function); + let expected_input_commitment: [_; INPUT_OUTPUT_COMMITMENT_LENGTH] = + commit_variable_length_encodable_item(cs, &recursion_tip_input, round_function); - let proof_witness = proof_witnesses.pop_front(); + let proof_witness = proof_witnesses.pop_front(); - let proof = AllocatedProof::allocate_from_witness( - cs, - proof_witness, - &verifier, - &config.vk_fixed_parameters, - &config.proof_config, - ); + let proof = AllocatedProof::allocate_from_witness( + cs, + proof_witness, + &verifier, + &config.vk_fixed_parameters, + &config.proof_config, + ); - let (is_valid, inputs) = verifier.verify::( - cs, - transcript_params.clone(), - &proof, - &config.vk_fixed_parameters, - &config.proof_config, - &node_layer_vk, - ); + let (is_valid, inputs) = verifier.verify::( + cs, + transcript_params.clone(), + &proof, + &config.vk_fixed_parameters, + &config.proof_config, + &recursion_tip_verification_key, + ); - is_valid.conditionally_enforce_true(cs, should_verify); - assert_eq!(inputs.len(), expected_input_commitment.len()); + Boolean::enforce_equal(cs, &is_valid, &boolean_true); + assert_eq!(inputs.len(), expected_input_commitment.len()); - for (a, b) in inputs.iter().zip(expected_input_commitment.iter()) { - Num::conditionally_enforce_equal(cs, should_verify, a, b); + for (a, b) in inputs.iter().zip(expected_input_commitment.iter()) { + Num::enforce_equal(cs, a, b); + } } } @@ -1098,8 +1315,6 @@ pub fn scheduler_function< dst.state_root = *root; } - let zero_u8 = UInt8::zero(cs); - let mut bootloader_heap_initial_content = [zero_u8; 32]; for (dst, src) in bootloader_heap_initial_content .array_chunks_mut::<8>() @@ -1120,85 +1335,6 @@ pub fn scheduler_function< dst.reverse(); } - let (eip4844_linear_hashes, eip4844_output_commitment_hashes) = if USE_4844 { - // eip4844 circuit - let verifier_builder = - eip4844_verifier_builder.expect("if EIP 4844 is used then builder must be provided"); - let verifier = verifier_builder.create_recursive_verifier(cs); - let proof_config = - eip4844_proof_config.expect("if EIP 4844 is used then proof config must be provided"); - let vk_fixed_parameters = eip4844_vk_fixed_parameters - .expect("if EIP 4844 is used then vk fixed parameters must be provided"); - let vk = eip4844_vk.expect("if EIP 4844 is used then VK must be provided"); - - let eip4844_vk = AllocatedVerificationKey::::allocate_constant(cs, vk); - - let mut eip4844_linear_hashes = [[zero_u8; 32]; MAX_4844_BLOBS_PER_BLOCK]; - let mut eip4844_output_commitment_hashes = [[zero_u8; 32]; MAX_4844_BLOBS_PER_BLOCK]; - for i in 0..MAX_4844_BLOBS_PER_BLOCK { - let observable_output_data_witness = witness - .eip4844_witnesses - .as_ref() - .expect("if EIP 4844 is used then witness must be provided") - .get(i) - .cloned() - .unwrap_or(EIP4844OutputData::placeholder_witness()); - let observable_output_data = - EIP4844OutputData::allocate(cs, observable_output_data_witness); - let zeroes = observable_output_data.linear_hash.map(|el| el.is_zero(cs)); - let skip_verification = Boolean::multi_and(cs, &zeroes); - let should_verify = skip_verification.negated(cs); - let structured_input = EIP4844InputOutput { - start_flag: boolean_true, - completion_flag: boolean_true, - observable_input: (), - observable_output: observable_output_data, - hidden_fsm_input: (), - hidden_fsm_output: (), - }; - - let closed_form_input = - ClosedFormInputCompactForm::from_full_form(cs, &structured_input, round_function); - let expected_input_commitment: [_; INPUT_OUTPUT_COMMITMENT_LENGTH] = - commit_variable_length_encodable_item(cs, &closed_form_input, round_function); - - let proof_witness = witness.eip4844_proofs.pop_front(); - - let proof = AllocatedProof::allocate_from_witness( - cs, - proof_witness, - &verifier, - &vk_fixed_parameters, - &proof_config, - ); - - let (is_valid, inputs) = verifier.verify::( - cs, - transcript_params.clone(), - &proof, - &vk_fixed_parameters, - &proof_config, - &eip4844_vk, - ); - is_valid.conditionally_enforce_true(cs, should_verify); - assert_eq!(inputs.len(), expected_input_commitment.len()); - - for (a, b) in inputs.iter().zip(expected_input_commitment.iter()) { - Num::conditionally_enforce_equal(cs, should_verify, a, b); - } - - eip4844_linear_hashes[i] = observable_output_data.linear_hash; - eip4844_output_commitment_hashes[i] = observable_output_data.output_hash; - } - - (eip4844_linear_hashes, eip4844_output_commitment_hashes) - } else { - ( - [[zero_u8; 32]; MAX_4844_BLOBS_PER_BLOCK], - [[zero_u8; 32]; MAX_4844_BLOBS_PER_BLOCK], - ) - }; - let aux_data = BlockAuxilaryOutput { rollup_state_diff_for_compression: storage_application_observable_output .state_diffs_keccak256_hash, @@ -1232,35 +1368,10 @@ pub fn scheduler_function< previous_block_aux_hash, ); - // form full block hash - + // form full block hash, it's just a hash of concatenation of previous and new full content hashes let mut flattened_public_input = vec![]; flattened_public_input.extend(previous_block_content_hash); flattened_public_input.extend(this_block_content_hash); - // recursion parameters - - let mut recursion_node_verification_key_hash = [zero_u8; 32]; - for (dst, src) in recursion_node_verification_key_hash - .array_chunks_mut::<8>() - .zip(node_layer_vk_commitment.iter()) - { - let le_bytes = src.constraint_bit_length_as_bytes(cs, 64); - dst.copy_from_slice(&le_bytes[..]); - dst.reverse(); - } - - let mut leaf_layer_parameters_hash = [zero_u8; 32]; - for (dst, src) in leaf_layer_parameters_hash - .array_chunks_mut::<8>() - .zip(leaf_layer_parameters_commitment.iter()) - { - let le_bytes = src.constraint_bit_length_as_bytes(cs, 64); - dst.copy_from_slice(&le_bytes[..]); - dst.reverse(); - } - - flattened_public_input.extend(recursion_node_verification_key_hash); - flattened_public_input.extend(leaf_layer_parameters_hash); let input_keccak_hash = keccak256::keccak256(cs, &flattened_public_input); let take_by = F::CAPACITY_BITS / 8; diff --git a/crates/zkevm_circuits/src/secp256r1_verify/baseline.rs b/crates/zkevm_circuits/src/secp256r1_verify/baseline.rs new file mode 100644 index 0000000..b10d660 --- /dev/null +++ b/crates/zkevm_circuits/src/secp256r1_verify/baseline.rs @@ -0,0 +1,780 @@ +use super::*; + +use crate::base_structures::precompile_input_outputs::PrecompileFunctionOutputData; +use crate::demux_log_queue::StorageLogQueue; +use crate::ethereum_types::U256; +use crate::fsm_input_output::circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH; + +use arrayvec::ArrayVec; +use boojum::algebraic_props::round_function::AlgebraicRoundFunction; +use boojum::cs::traits::cs::ConstraintSystem; +use boojum::field::SmallField; +use boojum::gadgets::boolean::Boolean; +use boojum::gadgets::curves::sw_projective::SWProjectivePoint; + +use boojum::gadgets::num::Num; +use boojum::gadgets::queue::CircuitQueueWitness; +use boojum::gadgets::queue::QueueState; +use boojum::gadgets::traits::allocatable::{CSAllocatableExt, CSPlaceholder}; +use boojum::gadgets::traits::round_function::CircuitRoundFunction; +use boojum::gadgets::traits::selectable::Selectable; + +use boojum::gadgets::u160::UInt160; +use boojum::gadgets::u256::UInt256; +use boojum::gadgets::u32::UInt32; +use boojum::gadgets::u8::UInt8; + +use std::collections::VecDeque; +use std::sync::{Arc, RwLock}; +use zkevm_opcode_defs::system_params::PRECOMPILE_AUX_BYTE; + +use crate::ecrecover::baseline::convert_uint256_to_field_element; +use crate::ecrecover::baseline::convert_uint256_to_field_element_masked; +use crate::ecrecover::new_optimized::fixed_base_mul; + +const WINDOW_WIDTH: usize = 4; +const NUM_MULTIPLICATION_STEPS_FOR_WIDTH_4: usize = 64; +const PRECOMPUTATION_TABLE_SIZE: usize = (1 << WINDOW_WIDTH) - 1; + +#[derive(Derivative, CSSelectable)] +#[derivative(Clone, Debug)] +pub struct Secp256r1VerifyPrecompileCallParams { + pub input_page: UInt32, + pub input_offset: UInt32, + pub output_page: UInt32, + pub output_offset: UInt32, +} + +impl Secp256r1VerifyPrecompileCallParams { + pub fn from_encoding>(_cs: &mut CS, encoding: UInt256) -> Self { + let input_offset = encoding.inner[0]; + let output_offset = encoding.inner[2]; + let input_page = encoding.inner[4]; + let output_page = encoding.inner[5]; + + let new = Self { + input_page, + input_offset, + output_page, + output_offset, + }; + + new + } +} + +const NUM_WORDS: usize = 17; +const EXCEPTION_FLAGS_ARR_LEN: usize = 8; + +fn secp256r1_verify_function_inner>( + cs: &mut CS, + r: &UInt256, + s: &UInt256, + message_hash: &UInt256, + x: &UInt256, + y: &UInt256, + base_field_params: &Arc, + scalar_field_params: &Arc, +) -> (Boolean, UInt256) { + use boojum::pairing::GenericCurveAffine; + let curve_a = Secp256Affine::a_coeff(); + let curve_b = Secp256Affine::b_coeff(); + + let mut curve_a_nn = + Secp256BaseNNField::::allocated_constant(cs, curve_a, &base_field_params); + let mut curve_b_nn = + Secp256BaseNNField::::allocated_constant(cs, curve_b, &base_field_params); + + let generator = Secp256Affine::one(); + let (gen_x, gen_y) = generator.into_xy_unchecked(); + let gen_x_nn = Secp256BaseNNField::allocated_constant(cs, gen_x, base_field_params); + let gen_y_nn = Secp256BaseNNField::allocated_constant(cs, gen_y, base_field_params); + + let secp_n_u256 = U256([ + scalar_field_params.modulus_u1024.as_ref().as_words()[0], + scalar_field_params.modulus_u1024.as_ref().as_words()[1], + scalar_field_params.modulus_u1024.as_ref().as_words()[2], + scalar_field_params.modulus_u1024.as_ref().as_words()[3], + ]); + let secp_n_u256 = UInt256::allocated_constant(cs, secp_n_u256); + + let secp_p_u256 = U256([ + base_field_params.modulus_u1024.as_ref().as_words()[0], + base_field_params.modulus_u1024.as_ref().as_words()[1], + base_field_params.modulus_u1024.as_ref().as_words()[2], + base_field_params.modulus_u1024.as_ref().as_words()[3], + ]); + let secp_p_u256 = UInt256::allocated_constant(cs, secp_p_u256); + + let mut exception_flags = ArrayVec::<_, EXCEPTION_FLAGS_ARR_LEN>::new(); + + // we use non-compressed point, so we: + // - check that public key is on curve (no special handling of zeroes) + // - check verification equation + + // we check ranges upfront. We only need to check = 1 + + let mut r_as_u256 = *r; + let mut s_as_u256 = *s; + let mut x_as_u256 = *x; + let mut y_as_u256 = *y; + + let (_res, is_in_range) = r_as_u256.overflowing_sub(cs, &secp_n_u256); + r_as_u256 = r_as_u256.mask(cs, is_in_range); + let r_is_not_in_range = is_in_range.negated(cs); + exception_flags.push(r_is_not_in_range); + + let (_res, is_in_range) = s_as_u256.overflowing_sub(cs, &secp_n_u256); + s_as_u256 = s_as_u256.mask(cs, is_in_range); + let s_is_not_in_range = is_in_range.negated(cs); + exception_flags.push(s_is_not_in_range); + + let (_res, is_in_range) = x_as_u256.overflowing_sub(cs, &secp_p_u256); + x_as_u256 = x_as_u256.mask(cs, is_in_range); + let x_is_not_in_range = is_in_range.negated(cs); + exception_flags.push(x_is_not_in_range); + + let (_res, is_in_range) = y_as_u256.overflowing_sub(cs, &secp_p_u256); + y_as_u256 = y_as_u256.mask(cs, is_in_range); + let y_is_not_in_range = is_in_range.negated(cs); + exception_flags.push(y_is_not_in_range); + + let mut x_fe = convert_uint256_to_field_element(cs, &x_as_u256, &base_field_params); + let mut y_fe = convert_uint256_to_field_element(cs, &y_as_u256, &base_field_params); + + let (mut r_fe, r_is_zero) = + convert_uint256_to_field_element_masked(cs, &r_as_u256, &scalar_field_params); + exception_flags.push(r_is_zero); + let (mut s_fe, s_is_zero) = + convert_uint256_to_field_element_masked(cs, &s_as_u256, &scalar_field_params); + exception_flags.push(s_is_zero); + + let mut message_hash_fe = + convert_uint256_to_field_element(cs, &message_hash, &scalar_field_params); + + // perform on-curve check + let mut lhs = y_fe.clone(); + let mut lhs = lhs.mul(cs, &mut y_fe); + lhs.normalize(cs); + + let mut rhs = x_fe.clone(); + let mut rhs = rhs.mul(cs, &mut x_fe); + let mut rhs = rhs.add(cs, &mut curve_a_nn); + let mut rhs = rhs.mul(cs, &mut x_fe); + let mut rhs = rhs.add(cs, &mut curve_b_nn); + rhs.normalize(cs); + + let is_on_curve = NonNativeFieldOverU16::equals(cs, &mut lhs, &mut rhs); + let not_on_curve = is_on_curve.negated(cs); + exception_flags.push(not_on_curve); + + // we can mask point to ensure that our arithmetic formulas work + let x_fe: NonNativeFieldOverU16 = + NonNativeFieldOverU16::conditionally_select(cs, is_on_curve, &x_fe, &gen_x_nn); + let y_fe = NonNativeFieldOverU16::conditionally_select(cs, is_on_curve, &y_fe, &gen_y_nn); + + // this always exists (0 was an exception and was masked) + let mut s_fe_inversed = s_fe.inverse_unchecked(cs); + let mut r_by_s_inv = r_fe.mul(cs, &mut s_fe_inversed); + let mut message_hash_by_s_inv = message_hash_fe.mul(cs, &mut s_fe_inversed); + + r_by_s_inv.normalize(cs); + message_hash_by_s_inv.normalize(cs); + + // now we do multiplication + // it's safe since we checked not-on-curve above + let point = SWProjectivePoint::>::from_xy_unchecked( + cs, x_fe, y_fe, + ); + let mut r_by_s_inv_mul_by_pubkey = + width_4_windowed_multiplication(cs, point, r_by_s_inv.clone(), &base_field_params); + + let mut full_table_ids = vec![]; + seq_macro::seq!(C in 0..32 { + let ids = [ + cs.get_table_id_for_marker::>() + .expect("table must exist"), + cs.get_table_id_for_marker::>() + .expect("table must exist"), + cs.get_table_id_for_marker::>() + .expect("table must exist"), + cs.get_table_id_for_marker::>() + .expect("table must exist"), + cs.get_table_id_for_marker::>() + .expect("table must exist"), + cs.get_table_id_for_marker::>() + .expect("table must exist"), + cs.get_table_id_for_marker::>() + .expect("table must exist"), + cs.get_table_id_for_marker::>() + .expect("table must exist"), + ]; + full_table_ids.push(ids); + }); + + let mut hash_times_g = fixed_base_mul::( + cs, + message_hash_by_s_inv, + &base_field_params, + SCALAR_FIELD_CANONICAL_REPR_LIMBS, + BASE_FIELD_CANONICAL_REPR_LIMBS, + &full_table_ids, + ); + + let (mut q_acc, is_infinity) = + hash_times_g.convert_to_affine_or_default(cs, Secp256Affine::one()); + let q_acc_added = r_by_s_inv_mul_by_pubkey.add_mixed(cs, &mut q_acc); + let mut q_acc = + Selectable::conditionally_select(cs, is_infinity, &r_by_s_inv_mul_by_pubkey, &q_acc_added); + + let ((mut q_x, _q_y), is_infinity) = + q_acc.convert_to_affine_or_default(cs, Secp256Affine::one()); + exception_flags.push(is_infinity); + let any_exception = Boolean::multi_or(cs, &exception_flags[..]); + + q_x.normalize(cs); + + // now compare mod n. For that we go out of limbs and back + let limbs = q_x.limbs; + let mut q_x_mod_n = NonNativeFieldOverU16 { + limbs: limbs, + non_zero_limbs: 16, + tracker: OverflowTracker { max_moduluses: 2 }, // |Fr|*2 < |Fq| + form: RepresentationForm::Normalized, + params: scalar_field_params.clone(), + _marker: std::marker::PhantomData, + }; + q_x_mod_n.normalize(cs); + + let signature_equality = NonNativeFieldOverU16::equals(cs, &mut q_x_mod_n, &mut r_fe); + let written_value_bool = signature_equality.mask_negated(cs, any_exception); + let all_ok = any_exception.negated(cs); + + let mut written_value = UInt256::zero(cs); + written_value.inner[0] = + unsafe { UInt32::from_variable_unchecked(written_value_bool.get_variable()) }; + + (all_ok, written_value) +} + +pub fn secp256r1_verify_function_entry_point< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, +>( + cs: &mut CS, + witness: Secp256r1VerifyCircuitInstanceWitness, + round_function: &R, + limit: usize, +) -> [Num; INPUT_OUTPUT_COMMITMENT_LENGTH] +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, +{ + assert!(limit <= u32::MAX as usize); + + let Secp256r1VerifyCircuitInstanceWitness { + closed_form_input, + requests_queue_witness, + memory_reads_witness, + } = witness; + + let memory_reads_witness: VecDeque<_> = memory_reads_witness.into_iter().flatten().collect(); + + let precompile_address = UInt160::allocated_constant( + cs, + *zkevm_opcode_defs::system_params::SECP256R1_VERIFY_INNER_FUNCTION_PRECOMPILE_FORMAL_ADDRESS, + ); + let aux_byte_for_precompile = UInt8::allocated_constant(cs, PRECOMPILE_AUX_BYTE); + + let scalar_params = Arc::new(secp256r1_scalar_field_params()); + let base_params = Arc::new(secp256r1_base_field_params()); + + let mut structured_input = + Secp256r1VerifyCircuitInputOutput::alloc_ignoring_outputs(cs, closed_form_input.clone()); + let start_flag = structured_input.start_flag; + + let requests_queue_state_from_input = structured_input.observable_input.initial_log_queue_state; + + // it must be trivial + requests_queue_state_from_input.enforce_trivial_head(cs); + + let requests_queue_state_from_fsm = structured_input.hidden_fsm_input.log_queue_state; + + let requests_queue_state = QueueState::conditionally_select( + cs, + start_flag, + &requests_queue_state_from_input, + &requests_queue_state_from_fsm, + ); + + let memory_queue_state_from_input = + structured_input.observable_input.initial_memory_queue_state; + + // it must be trivial + memory_queue_state_from_input.enforce_trivial_head(cs); + + let memory_queue_state_from_fsm = structured_input.hidden_fsm_input.memory_queue_state; + + let memory_queue_state = QueueState::conditionally_select( + cs, + start_flag, + &memory_queue_state_from_input, + &memory_queue_state_from_fsm, + ); + + let mut requests_queue = StorageLogQueue::::from_state(cs, requests_queue_state); + let queue_witness = CircuitQueueWitness::from_inner_witness(requests_queue_witness); + requests_queue.witness = Arc::new(queue_witness); + + let mut memory_queue = MemoryQueue::::from_state(cs, memory_queue_state); + + let one_u32 = UInt32::allocated_constant(cs, 1u32); + let zero_u256 = UInt256::zero(cs); + let boolean_false = Boolean::allocated_constant(cs, false); + let boolean_true = Boolean::allocated_constant(cs, true); + + use crate::storage_application::ConditionalWitnessAllocator; + let read_queries_allocator = ConditionalWitnessAllocator::> { + witness_source: Arc::new(RwLock::new(memory_reads_witness)), + }; + + for _cycle in 0..limit { + let is_empty = requests_queue.is_empty(cs); + let should_process = is_empty.negated(cs); + let (request, _) = requests_queue.pop_front(cs, should_process); + + let mut precompile_call_params = + Secp256r1VerifyPrecompileCallParams::from_encoding(cs, request.key); + + let timestamp_to_use_for_read = request.timestamp; + let timestamp_to_use_for_write = timestamp_to_use_for_read.add_no_overflow(cs, one_u32); + + Num::conditionally_enforce_equal( + cs, + should_process, + &Num::from_variable(request.aux_byte.get_variable()), + &Num::from_variable(aux_byte_for_precompile.get_variable()), + ); + for (a, b) in request + .address + .inner + .iter() + .zip(precompile_address.inner.iter()) + { + Num::conditionally_enforce_equal( + cs, + should_process, + &Num::from_variable(a.get_variable()), + &Num::from_variable(b.get_variable()), + ); + } + + let mut read_values = [zero_u256; MEMORY_QUERIES_PER_CALL]; + let mut bias_variable = should_process.get_variable(); + for dst in read_values.iter_mut() { + let read_query_value: UInt256 = read_queries_allocator + .conditionally_allocate_biased(cs, should_process, bias_variable); + bias_variable = read_query_value.inner[0].get_variable(); + + *dst = read_query_value; + + let read_query = MemoryQuery { + timestamp: timestamp_to_use_for_read, + memory_page: precompile_call_params.input_page, + index: precompile_call_params.input_offset, + rw_flag: boolean_false, + is_ptr: boolean_false, + value: read_query_value, + }; + + let _ = memory_queue.push(cs, read_query, should_process); + + precompile_call_params.input_offset = precompile_call_params + .input_offset + .add_no_overflow(cs, one_u32); + } + + let [message_hash_as_u256, r_as_u256, s_as_u256, x_as_u256, y_as_u256] = read_values; + + let (success, written_value) = secp256r1_verify_function_inner( + cs, + &r_as_u256, + &s_as_u256, + &message_hash_as_u256, + &x_as_u256, + &y_as_u256, + &base_params, + &scalar_params, + ); + + let success_as_u32 = unsafe { UInt32::from_variable_unchecked(success.get_variable()) }; + let mut success_as_u256 = zero_u256; + success_as_u256.inner[0] = success_as_u32; + + let success_query = MemoryQuery { + timestamp: timestamp_to_use_for_write, + memory_page: precompile_call_params.output_page, + index: precompile_call_params.output_offset, + rw_flag: boolean_true, + value: success_as_u256, + is_ptr: boolean_false, + }; + + precompile_call_params.output_offset = precompile_call_params + .output_offset + .add_no_overflow(cs, one_u32); + + let _ = memory_queue.push(cs, success_query, should_process); + + let value_query = MemoryQuery { + timestamp: timestamp_to_use_for_write, + memory_page: precompile_call_params.output_page, + index: precompile_call_params.output_offset, + rw_flag: boolean_true, + value: written_value, + is_ptr: boolean_false, + }; + + let _ = memory_queue.push(cs, value_query, should_process); + } + + requests_queue.enforce_consistency(cs); + + // form the final state + let done = requests_queue.is_empty(cs); + structured_input.completion_flag = done; + structured_input.observable_output = PrecompileFunctionOutputData::placeholder(cs); + + let final_memory_state = memory_queue.into_state(); + let final_requets_state = requests_queue.into_state(); + + structured_input.observable_output.final_memory_state = QueueState::conditionally_select( + cs, + structured_input.completion_flag, + &final_memory_state, + &structured_input.observable_output.final_memory_state, + ); + + structured_input.hidden_fsm_output.log_queue_state = final_requets_state; + structured_input.hidden_fsm_output.memory_queue_state = final_memory_state; + + // self-check + structured_input.hook_compare_witness(cs, &closed_form_input); + + use boojum::cs::gates::PublicInputGate; + + let compact_form = + ClosedFormInputCompactForm::from_full_form(cs, &structured_input, round_function); + let input_commitment = commit_variable_length_encodable_item(cs, &compact_form, round_function); + for el in input_commitment.iter() { + let gate = PublicInputGate::new(el.get_variable()); + gate.add_to_cs(cs); + } + + input_commitment +} + +fn width_4_windowed_multiplication>( + cs: &mut CS, + mut point: SWProjectivePoint>, + mut scalar: Secp256ScalarNNField, + base_field_params: &Arc, +) -> SWProjectivePoint> { + scalar.enforce_reduced(cs); + + use boojum::pairing::GenericCurveAffine; + + // create precomputed table of size 1<<4 - 1 + // there is no 0 * P in the table, we will handle it below + let mut table = Vec::with_capacity(PRECOMPUTATION_TABLE_SIZE); + let mut tmp = point.clone(); + let (mut p_affine, _) = point.convert_to_affine_or_default(cs, Secp256Affine::one()); + table.push(p_affine.clone()); + for _ in 1..PRECOMPUTATION_TABLE_SIZE { + // 2P, 3P, ... + tmp = tmp.add_mixed(cs, &mut p_affine); + let (affine, _) = tmp.convert_to_affine_or_default(cs, Secp256Affine::one()); + table.push(affine); + } + assert_eq!(table.len(), PRECOMPUTATION_TABLE_SIZE); + + // now decompose every scalar we are interested in + let msb_decomposition = to_width_4_window_form(cs, scalar); + + let mut comparison_constants = Vec::with_capacity(PRECOMPUTATION_TABLE_SIZE); + for i in 1..=PRECOMPUTATION_TABLE_SIZE { + let constant = Num::allocated_constant(cs, F::from_u64_unchecked(i as u64)); + comparison_constants.push(constant); + } + + // now we just do double and add + let mut acc = SWProjectivePoint::zero(cs, base_field_params); + assert_eq!( + msb_decomposition.len(), + NUM_MULTIPLICATION_STEPS_FOR_WIDTH_4 + ); + + for (idx, window_idx) in msb_decomposition.into_iter().enumerate() { + let ignore_part = window_idx.is_zero(cs); + + let (mut selected_part_x, mut selected_part_y) = table[0].clone(); + for i in 1..PRECOMPUTATION_TABLE_SIZE { + let should_select = Num::equals(cs, &comparison_constants[i], &window_idx); + selected_part_x = + Selectable::conditionally_select(cs, should_select, &table[i].0, &selected_part_x); + selected_part_y = + Selectable::conditionally_select(cs, should_select, &table[i].1, &selected_part_y); + } + + let tmp_acc = acc.add_mixed(cs, &mut (selected_part_x, selected_part_y)); + acc = Selectable::conditionally_select(cs, ignore_part, &acc, &tmp_acc); + + if idx != NUM_MULTIPLICATION_STEPS_FOR_WIDTH_4 - 1 { + for _ in 0..WINDOW_WIDTH { + acc = acc.double(cs); + } + } + } + + acc +} + +fn to_width_4_window_form>( + cs: &mut CS, + mut limited_width_scalar: Secp256ScalarNNField, +) -> Vec> { + limited_width_scalar.enforce_reduced(cs); + // we know that width is 128 bits, so just do BE decomposition and put into resulting array + let zero_num = Num::zero(cs); + for word in limited_width_scalar.limbs[16..].iter() { + let word = Num::from_variable(*word); + Num::enforce_equal(cs, &word, &zero_num); + } + + use boojum::gadgets::tables::ByteSplitTable; + use boojum::gadgets::u16::UInt16; + let byte_split_id = cs + .get_table_id_for_marker::>() + .expect("table should exist"); + let mut result = Vec::with_capacity(NUM_MULTIPLICATION_STEPS_FOR_WIDTH_4); + for word in limited_width_scalar.limbs[..16].iter().rev() { + let word = unsafe { UInt16::from_variable_unchecked(*word) }; + let [high, low] = word.to_be_bytes(cs); + for t in [high, low].into_iter() { + let [l, h] = cs.perform_lookup::<1, 2>(byte_split_id, &[t.get_variable()]); + let h = Num::from_variable(h); + let l = Num::from_variable(l); + result.push(h); + result.push(l); + } + } + assert_eq!(result.len(), NUM_MULTIPLICATION_STEPS_FOR_WIDTH_4); + + result +} + +#[cfg(test)] +mod test { + use boojum::field::goldilocks::GoldilocksField; + use boojum::gadgets::traits::allocatable::CSAllocatable; + use boojum::worker::Worker; + + use super::*; + + type F = GoldilocksField; + type P = GoldilocksField; + + use boojum::config::DevCSConfig; + + use boojum::cs::cs_builder::*; + use boojum::cs::cs_builder_reference::CsReferenceImplementationBuilder; + use boojum::cs::gates::*; + use boojum::cs::traits::gate::GatePlacementStrategy; + use boojum::cs::CSGeometry; + use boojum::cs::*; + use boojum::gadgets::tables::*; + + #[test] + fn test_secp256r1_verification() { + let geometry = CSGeometry { + num_columns_under_copy_permutation: 80, + num_witness_columns: 0, + num_constant_columns: 4, + max_allowed_constraint_degree: 8, + }; + + let max_variables = 1 << 26; + let max_trace_len = 1 << 20; + + fn configure< + F: SmallField, + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + let builder = builder.allow_lookup( + LookupParameters::UseSpecializedColumnsWithTableIdAsConstant { + width: 3, + num_repetitions: 16, + share_table_id: true, + }, + ); + + let builder = ConstantsAllocatorGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = BooleanConstraintGate::configure_builder( + builder, + GatePlacementStrategy::UseSpecializedColumns { + num_repetitions: 1, + share_constants: false, + }, + ); + let builder = U8x4FMAGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ZeroCheckGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + false, + ); + let builder = FmaGateInBaseFieldWithoutConstant::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<32>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<16>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<8>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = DotProductGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = SelectionGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ParallelSelectionGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = PublicInputGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ReductionGate::<_, 4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = NopGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + + builder + } + + let builder_impl = + CsReferenceImplementationBuilder::::new(geometry, max_trace_len); + let builder = new_builder::<_, F>(builder_impl); + + let builder = configure(builder); + let mut owned_cs = builder.build(max_variables); + + // add tables + let table = create_xor8_table(); + owned_cs.add_lookup_table::(table); + + seq_macro::seq!(C in 0..32 { + let table = create_secp256r1_fixed_base_mul_table::(); + owned_cs.add_lookup_table::, 3>(table); + let table = create_secp256r1_fixed_base_mul_table::(); + owned_cs.add_lookup_table::, 3>(table); + let table = create_secp256r1_fixed_base_mul_table::(); + owned_cs.add_lookup_table::, 3>(table); + let table = create_secp256r1_fixed_base_mul_table::(); + owned_cs.add_lookup_table::, 3>(table); + let table = create_secp256r1_fixed_base_mul_table::(); + owned_cs.add_lookup_table::, 3>(table); + let table = create_secp256r1_fixed_base_mul_table::(); + owned_cs.add_lookup_table::, 3>(table); + let table = create_secp256r1_fixed_base_mul_table::(); + owned_cs.add_lookup_table::, 3>(table); + let table = create_secp256r1_fixed_base_mul_table::(); + owned_cs.add_lookup_table::, 3>(table); + }); + + let table = create_byte_split_table::(); + owned_cs.add_lookup_table::, 3>(table); + + let cs = &mut owned_cs; + + let digest = + hex::decode("3fec5769b5cf4e310a7d150508e82fb8e3eda1c2c94c61492d3bd8aea99e06c9") + .unwrap(); + let pk_x = hex::decode("31a80482dadf89de6302b1988c82c29544c9c07bb910596158f6062517eb089a") + .unwrap(); + let pk_y = hex::decode("2f54c9a0f348752950094d3228d3b940258c75fe2a413cb70baa21dc2e352fc5") + .unwrap(); + let r = hex::decode("e22466e928fdccef0de49e3503d2657d00494a00e764fd437bdafa05f5922b1f") + .unwrap(); + let s = hex::decode("bbb77c6817ccf50748419477e843d5bac67e6a70e97dde5a57e0c983b777e1ad") + .unwrap(); + + let scalar_params = secp256r1_scalar_field_params(); + let base_params = secp256r1_base_field_params(); + + let digest_u256 = U256::from_big_endian(&digest); + let pk_x_u256 = U256::from_big_endian(&pk_x); + let pk_y_u256 = U256::from_big_endian(&pk_y); + let r_u256 = U256::from_big_endian(&r); + let s_u256 = U256::from_big_endian(&s); + + let pk_x = UInt256::allocate(cs, pk_x_u256); + let pk_y = UInt256::allocate(cs, pk_y_u256); + let r = UInt256::allocate(cs, r_u256); + let s = UInt256::allocate(cs, s_u256); + let digest = UInt256::allocate(cs, digest_u256); + + let scalar_params = Arc::new(scalar_params); + let base_params = Arc::new(base_params); + + let (no_error, is_valid) = secp256r1_verify_function_inner( + cs, + &r, + &s, + &digest, + &pk_x, + &pk_y, + &base_params, + &scalar_params, + ); + + assert!(no_error.witness_hook(&*cs)().unwrap() == true); + assert!(is_valid.witness_hook(&*cs)().unwrap() == U256::one()); + + dbg!(cs.next_available_row()); + + cs.pad_and_shrink(); + + let mut cs = owned_cs.into_assembly::(); + cs.print_gate_stats(); + let worker = Worker::new(); + assert!(cs.check_if_satisfied(&worker)); + } +} diff --git a/crates/zkevm_circuits/src/secp256r1_verify/fixed_base_mul_table.rs b/crates/zkevm_circuits/src/secp256r1_verify/fixed_base_mul_table.rs new file mode 100644 index 0000000..5be3f8c --- /dev/null +++ b/crates/zkevm_circuits/src/secp256r1_verify/fixed_base_mul_table.rs @@ -0,0 +1,59 @@ +use super::secp256r1::fr::Fr; +use super::*; +use boojum::cs::implementations::lookup_table::LookupTable; +use boojum::field::SmallField; +use boojum::pairing::ff::{Field, PrimeField}; +use boojum::pairing::GenericCurveAffine; +use boojum::pairing::GenericCurveProjective; + +const TABLE_NAME: &'static str = "Secp256k1 FIXEDBASEMUL table"; + +#[derive(Derivative)] +#[derivative(Clone, Copy, Debug, PartialEq, Eq)] +pub struct Secp256r1FixedBaseMulTable; + +// Allows for a radix scalar mul by storing all potential exponentiations +// of the generator with 0..255 +pub fn create_secp256r1_fixed_base_mul_table< + F: SmallField, + const U32_WORD_INDEX: usize, + const BYTE_OFFSET: usize, +>() -> LookupTable { + assert!(U32_WORD_INDEX < 8); + assert!(BYTE_OFFSET < 32); + let mut content = Vec::with_capacity(1 << 8); + // point of infinity is encoded as (0,0), and we handle it via select in the multiplication routine + content.push([F::ZERO, F::ZERO, F::ZERO]); + let mut base_power = Fr::one(); + for _ in 0..(BYTE_OFFSET * 8) { + base_power.double(); + } + let base = Secp256Affine::one(); + let base = base.mul(base_power); + let mut current = base; + let base = base.into_affine(); + let repr_word_index = U32_WORD_INDEX / 2; + let take_low = U32_WORD_INDEX % 2 == 0; + for a in 1..=u8::MAX { + let current_affine = current.into_affine(); + let (x, y) = current_affine.as_xy(); + let x_repr_word = x.into_repr().as_ref()[repr_word_index]; + let y_repr_word = y.into_repr().as_ref()[repr_word_index]; + if take_low { + content.push([ + F::from_u64_unchecked(a as u64), + F::from_u64_unchecked((x_repr_word as u32) as u64), + F::from_u64_unchecked((y_repr_word as u32) as u64), + ]); + } else { + content.push([ + F::from_u64_unchecked(a as u64), + F::from_u64_unchecked(x_repr_word >> 32), + F::from_u64_unchecked(y_repr_word >> 32), + ]); + } + current.add_assign_mixed(&base); + } + assert_eq!(content.len(), 256); + LookupTable::new_from_content(content, TABLE_NAME.to_string(), 1) +} diff --git a/crates/zkevm_circuits/src/secp256r1_verify/input.rs b/crates/zkevm_circuits/src/secp256r1_verify/input.rs new file mode 100644 index 0000000..79cfc1e --- /dev/null +++ b/crates/zkevm_circuits/src/secp256r1_verify/input.rs @@ -0,0 +1,59 @@ +use std::collections::VecDeque; + +use super::*; +use crate::base_structures::precompile_input_outputs::*; +use crate::base_structures::vm_state::*; +use boojum::cs::Variable; +use boojum::gadgets::queue::*; +use boojum::gadgets::traits::allocatable::CSAllocatable; +use boojum::gadgets::traits::allocatable::CSPlaceholder; +use boojum::gadgets::traits::encodable::CircuitVarLengthEncodable; +use boojum::gadgets::traits::encodable::WitnessVarLengthEncodable; + +use boojum::gadgets::traits::auxiliary::PrettyComparison; + +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] +#[derivative(Clone, Copy, Debug)] +#[DerivePrettyComparison("true")] +pub struct Secp256r1VerifyCircuitFSMInputOutput { + pub log_queue_state: QueueState, + pub memory_queue_state: QueueState, +} + +impl CSPlaceholder for Secp256r1VerifyCircuitFSMInputOutput { + fn placeholder>(cs: &mut CS) -> Self { + Self { + log_queue_state: QueueState::::placeholder(cs), + memory_queue_state: QueueState::::placeholder(cs), + } + } +} + +pub type Secp256r1VerifyCircuitInputOutput = ClosedFormInput< + F, + Secp256r1VerifyCircuitFSMInputOutput, + PrecompileFunctionInputData, + PrecompileFunctionOutputData, +>; +pub type Secp256r1VerifyCircuitInputOutputWitness = ClosedFormInputWitness< + F, + Secp256r1VerifyCircuitFSMInputOutput, + PrecompileFunctionInputData, + PrecompileFunctionOutputData, +>; + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Debug, Default)] +#[serde(bound = "")] +pub struct Secp256r1VerifyCircuitInstanceWitness { + pub closed_form_input: Secp256r1VerifyCircuitInputOutputWitness, + pub requests_queue_witness: CircuitQueueRawWitness, 4, LOG_QUERY_PACKED_WIDTH>, + pub memory_reads_witness: VecDeque<[U256; MEMORY_QUERIES_PER_CALL]>, +} diff --git a/crates/zkevm_circuits/src/secp256r1_verify/mod.rs b/crates/zkevm_circuits/src/secp256r1_verify/mod.rs new file mode 100644 index 0000000..c9bc5ce --- /dev/null +++ b/crates/zkevm_circuits/src/secp256r1_verify/mod.rs @@ -0,0 +1,63 @@ +use super::*; +use crate::base_structures::log_query::*; +use crate::base_structures::memory_query::*; + +use crate::ethereum_types::U256; + +use crate::fsm_input_output::*; + +use boojum::cs::traits::cs::ConstraintSystem; +use boojum::field::SmallField; +use boojum::gadgets::boolean::Boolean; + +use boojum::gadgets::non_native_field::implementations::*; + +use boojum::gadgets::queue::QueueState; + +use boojum::gadgets::traits::selectable::Selectable; +use boojum::gadgets::traits::witnessable::WitnessHookable; + +use cs_derive::*; + +pub mod input; +pub use self::input::*; + +pub mod fixed_base_mul_table; +pub mod secp256r1; + +pub use self::fixed_base_mul_table::*; + +pub const MEMORY_QUERIES_PER_CALL: usize = 5; + +pub mod baseline; + +// characteristics of the base field for secp curve +use self::secp256r1::fq::Fq as Secp256Fq; +// order of group of points for secp curve +use self::secp256r1::fr::Fr as Secp256Fr; +// some affine point +use self::secp256r1::PointAffine as Secp256Affine; + +const BASE_FIELD_REPR_LIMBS: usize = 17; +const SCALAR_FIELD_REPR_LIMBS: usize = 17; +const BASE_FIELD_CANONICAL_REPR_LIMBS: usize = 16; +const SCALAR_FIELD_CANONICAL_REPR_LIMBS: usize = 16; + +type Secp256BaseNNFieldParams = NonNativeFieldOverU16Params; +type Secp256ScalarNNFieldParams = NonNativeFieldOverU16Params; + +type Secp256BaseNNField = NonNativeFieldOverU16; +type Secp256ScalarNNField = NonNativeFieldOverU16; + +fn secp256r1_base_field_params() -> Secp256BaseNNFieldParams { + NonNativeFieldOverU16Params::create() +} + +fn secp256r1_scalar_field_params() -> Secp256ScalarNNFieldParams { + NonNativeFieldOverU16Params::create() +} + +// re-exports for integration +pub use self::baseline::{ + secp256r1_verify_function_entry_point, Secp256r1VerifyPrecompileCallParams, +}; diff --git a/crates/zkevm_circuits/src/secp256r1_verify/secp256r1/fq.rs b/crates/zkevm_circuits/src/secp256r1_verify/secp256r1/fq.rs new file mode 100644 index 0000000..79c9c04 --- /dev/null +++ b/crates/zkevm_circuits/src/secp256r1_verify/secp256r1/fq.rs @@ -0,0 +1,7 @@ +use boojum::pairing::ff::*; + +// base field, Q = 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff +#[derive(PrimeField)] +#[PrimeFieldModulus = "115792089210356248762697446949407573530086143415290314195533631308867097853951"] +#[PrimeFieldGenerator = "2"] +pub struct Fq(FqRepr); diff --git a/crates/zkevm_circuits/src/secp256r1_verify/secp256r1/fr.rs b/crates/zkevm_circuits/src/secp256r1_verify/secp256r1/fr.rs new file mode 100644 index 0000000..fb8ef3f --- /dev/null +++ b/crates/zkevm_circuits/src/secp256r1_verify/secp256r1/fr.rs @@ -0,0 +1,7 @@ +use boojum::pairing::ff::*; + +// scalar field, R = 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551 +#[derive(PrimeField)] +#[PrimeFieldModulus = "115792089210356248762697446949407573529996955224135760342422259061068512044369"] +#[PrimeFieldGenerator = "2"] +pub struct Fr(FrRepr); diff --git a/crates/zkevm_circuits/src/secp256r1_verify/secp256r1/mod.rs b/crates/zkevm_circuits/src/secp256r1_verify/secp256r1/mod.rs new file mode 100644 index 0000000..6ef8c09 --- /dev/null +++ b/crates/zkevm_circuits/src/secp256r1_verify/secp256r1/mod.rs @@ -0,0 +1,688 @@ +use boojum::pairing::ff::BitIterator; +use boojum::pairing::ff::*; +use boojum::pairing::{ + EncodingBytes, GenericCompressedEncodable, GenericCurveAffine, GenericCurveProjective, + GenericUncompressedEncodable, GroupDecodingError, +}; + +pub mod fq; +pub mod fr; + +use fq::*; +use fr::*; + +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub struct PointAffine { + pub(crate) x: Fq, + pub(crate) y: Fq, + pub(crate) infinity: bool, +} + +static NAME_STR: &'static str = "Secp256r1"; + +impl ::std::fmt::Display for PointAffine { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + if self.infinity { + write!(f, "{}(Infinity)", NAME_STR) + } else { + write!(f, "{}(x={}, y={})", NAME_STR, self.x, self.y) + } + } +} + +#[derive(Copy, Clone, Debug, Eq)] +pub struct PointProjective { + pub(crate) x: Fq, + pub(crate) y: Fq, + pub(crate) z: Fq, +} + +impl ::std::fmt::Display for PointProjective { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + write!(f, "{}", self.into_affine()) + } +} + +impl PartialEq for PointProjective { + fn eq(&self, other: &PointProjective) -> bool { + if self.is_zero() { + return other.is_zero(); + } + + if other.is_zero() { + return false; + } + + // The points (X, Y, Z) and (X', Y', Z') + // are equal when (X * Z^2) = (X' * Z'^2) + // and (Y * Z^3) = (Y' * Z'^3). + + let mut z1 = self.z; + z1.square(); + let mut z2 = other.z; + z2.square(); + + let mut tmp1 = self.x; + tmp1.mul_assign(&z2); + + let mut tmp2 = other.x; + tmp2.mul_assign(&z1); + + if tmp1 != tmp2 { + return false; + } + + z1.mul_assign(&self.z); + z2.mul_assign(&other.z); + z2.mul_assign(&self.y); + z1.mul_assign(&other.y); + + if z1 != z2 { + return false; + } + + true + } +} + +impl PointAffine { + fn mul_bits>(&self, bits: BitIterator) -> PointProjective { + let mut res = PointProjective::zero(); + for i in bits { + res.double(); + if i { + res.add_assign_mixed(self) + } + } + res + } + + /// Attempts to construct an affine point given an x-coordinate. The + /// point is not guaranteed to be in the prime order subgroup. + /// + /// If and only if `greatest` is set will the lexicographically + /// largest y-coordinate be selected. + fn get_point_from_x(_x: Fq, _greatest: bool) -> Option { + unimplemented!() + } + + fn is_on_curve(&self) -> bool { + if self.is_zero() { + true + } else { + // Check that the point is on the curve + let mut y2 = self.y; + y2.square(); + + let mut rhs = self.x; + rhs.square(); + rhs.add_assign(&Self::get_coeff_a()); + rhs.mul_assign(&self.x); + rhs.add_assign(&Self::get_coeff_b()); + + y2 == rhs + } + } +} + +impl GenericCurveAffine for PointAffine { + type Scalar = Fr; + type Base = Fq; + type Projective = PointProjective; + + fn zero() -> Self { + PointAffine { + x: Fq::zero(), + y: Fq::one(), + infinity: true, + } + } + + fn one() -> Self { + Self::get_generator() + } + + fn is_zero(&self) -> bool { + self.infinity + } + + fn mul::Repr>>(&self, by: S) -> PointProjective { + let bits = BitIterator::new(by.into()); + self.mul_bits(bits) + } + + fn negate(&mut self) { + if !self.is_zero() { + self.y.negate(); + } + } + + fn into_projective(&self) -> PointProjective { + (*self).into() + } + + #[inline(always)] + fn as_xy(&self) -> (&Self::Base, &Self::Base) { + (&self.x, &self.y) + } + + #[inline(always)] + fn into_xy_unchecked(self) -> (Self::Base, Self::Base) { + (self.x, self.y) + } + + #[inline(always)] + fn from_xy_unchecked(x: Self::Base, y: Self::Base) -> Self { + let infinity = x.is_zero() && y.is_zero(); + Self { + x: x, + y: y, + infinity, + } + } + + fn from_xy_checked(x: Self::Base, y: Self::Base) -> Result { + let infinity = x.is_zero() && y.is_zero(); + let affine = Self { + x: x, + y: y, + infinity, + }; + + if !affine.is_on_curve() { + Err(GroupDecodingError::NotOnCurve) + } else { + Ok(affine) + } + } + + fn a_coeff() -> Self::Base { + Self::get_coeff_a() + } + + fn b_coeff() -> Self::Base { + Self::get_coeff_b() + } +} + +impl GenericCurveProjective for PointProjective { + type Scalar = Fr; + type Base = Fq; + type Affine = PointAffine; + + // The point at infinity is always represented by + // Z = 0. + fn zero() -> Self { + PointProjective { + x: Fq::zero(), + y: Fq::one(), + z: Fq::zero(), + } + } + + fn one() -> Self { + PointAffine::one().into() + } + + // The point at infinity is always represented by + // Z = 0. + fn is_zero(&self) -> bool { + self.z.is_zero() + } + + fn is_normalized(&self) -> bool { + self.is_zero() || self.z == Fq::one() + } + + fn batch_normalization(v: &mut [Self]) { + // Montgomery’s Trick and Fast Implementation of Masked AES + // Genelle, Prouff and Quisquater + // Section 3.2 + + // First pass: compute [a, ab, abc, ...] + let mut prod = Vec::with_capacity(v.len()); + let mut tmp = Fq::one(); + for g in v + .iter_mut() + // Ignore normalized elements + .filter(|g| !g.is_normalized()) + { + tmp.mul_assign(&g.z); + prod.push(tmp); + } + + // Invert `tmp`. + tmp = tmp.inverse().unwrap(); // Guaranteed to be nonzero. + + // Second pass: iterate backwards to compute inverses + for (g, s) in v + .iter_mut() + // Backwards + .rev() + // Ignore normalized elements + .filter(|g| !g.is_normalized()) + // Backwards, skip last element, fill in one for last term. + .zip(prod.into_iter().rev().skip(1).chain(Some(Fq::one()))) + { + // tmp := tmp * g.z; g.z := tmp * s = 1/z + let mut newtmp = tmp; + newtmp.mul_assign(&g.z); + g.z = tmp; + g.z.mul_assign(&s); + tmp = newtmp; + } + + // Perform affine transformations + for g in v.iter_mut().filter(|g| !g.is_normalized()) { + let mut z = g.z; // 1/z + z.square(); // 1/z^2 + g.x.mul_assign(&z); // x/z^2 + z.mul_assign(&g.z); // 1/z^3 + g.y.mul_assign(&z); // y/z^3 + g.z = Fq::one(); // z = 1 + } + } + + fn double(&mut self) { + if self.is_zero() { + return; + } + + // https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-dbl-2007-bl + let mut xx = self.x; + xx.square(); + let mut yy = self.y; + yy.square(); + let mut yyyy = yy; + yyyy.square(); + let mut zz = self.z; + zz.square(); + let mut s = self.x; + s.add_assign(&yy); + s.square(); + s.sub_assign(&xx); + s.sub_assign(&yyyy); + s.double(); + + let mut m1 = zz; + m1.square(); + m1.mul_assign(&PointAffine::a_coeff()); + let mut m = xx; + m.double(); + m.add_assign(&xx); + m.add_assign(&m1); + + let mut two_s = s; + two_s.double(); + + let mut t = m; + t.square(); + t.sub_assign(&two_s); + + self.x = t; + + let mut eight_yyyy = yyyy; + eight_yyyy.double(); + eight_yyyy.double(); + eight_yyyy.double(); + + let y1 = self.y; + + self.y = s; + self.y.sub_assign(&t); + self.y.mul_assign(&m); + self.y.sub_assign(&eight_yyyy); + + self.z.add_assign(&y1); + self.z.square(); + self.z.sub_assign(&yy); + self.z.sub_assign(&zz); + } + + fn add_assign(&mut self, _other: &Self) { + unimplemented!() + } + + fn add_assign_mixed(&mut self, other: &Self::Affine) { + if other.is_zero() { + return; + } + + if self.is_zero() { + self.x = other.x; + self.y = other.y; + self.z = Fq::one(); + return; + } + + // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl + + // Z1Z1 = Z1^2 + let mut z1z1 = self.z; + z1z1.square(); + + // U2 = X2*Z1Z1 + let mut u2 = other.x; + u2.mul_assign(&z1z1); + + // S2 = Y2*Z1*Z1Z1 + let mut s2 = other.y; + s2.mul_assign(&self.z); + s2.mul_assign(&z1z1); + + if self.x == u2 && self.y == s2 { + // The two points are equal, so we double. + self.double(); + } else { + // If we're adding -a and a together, self.z becomes zero as H becomes zero. + + // H = U2-X1 + let mut h = u2; + h.sub_assign(&self.x); + + // HH = H^2 + let mut hh = h; + hh.square(); + + // I = 4*HH + let mut i = hh; + i.double(); + i.double(); + + // J = H*I + let mut j = h; + j.mul_assign(&i); + + // r = 2*(S2-Y1) + let mut r = s2; + r.sub_assign(&self.y); + r.double(); + + // V = X1*I + let mut v = self.x; + v.mul_assign(&i); + + // X3 = r^2 - J - 2*V + self.x = r; + self.x.square(); + self.x.sub_assign(&j); + self.x.sub_assign(&v); + self.x.sub_assign(&v); + + // Y3 = r*(V-X3)-2*Y1*J + j.mul_assign(&self.y); // J = 2*Y1*J + j.double(); + self.y = v; + self.y.sub_assign(&self.x); + self.y.mul_assign(&r); + self.y.sub_assign(&j); + + // Z3 = (Z1+H)^2-Z1Z1-HH + self.z.add_assign(&h); + self.z.square(); + self.z.sub_assign(&z1z1); + self.z.sub_assign(&hh); + } + } + + fn negate(&mut self) { + if !self.is_zero() { + self.y.negate() + } + } + + fn mul_assign::Repr>>(&mut self, other: S) { + let mut res = Self::zero(); + + let mut found_one = false; + + for i in BitIterator::new(other.into()) { + if found_one { + res.double(); + } else { + found_one = i; + } + + if i { + res.add_assign(self); + } + } + + *self = res; + } + + fn into_affine(&self) -> PointAffine { + (*self).into() + } + + fn recommended_wnaf_for_scalar(scalar: ::Repr) -> usize { + Self::empirical_recommended_wnaf_for_scalar(scalar) + } + + fn recommended_wnaf_for_num_scalars(num_scalars: usize) -> usize { + Self::empirical_recommended_wnaf_for_num_scalars(num_scalars) + } + + fn as_xyz(&self) -> (&Self::Base, &Self::Base, &Self::Base) { + (&self.x, &self.y, &self.z) + } + + fn into_xyz_unchecked(self) -> (Self::Base, Self::Base, Self::Base) { + (self.x, self.y, self.z) + } + + fn from_xyz_unchecked(x: Self::Base, y: Self::Base, z: Self::Base) -> Self { + Self { x, y, z } + } + + fn from_xyz_checked( + _x: Self::Base, + _y: Self::Base, + _z: Self::Base, + ) -> Result { + unimplemented!() + } +} + +// The affine point X, Y is represented in the jacobian +// coordinates with Z = 1. +impl From for PointProjective { + fn from(p: PointAffine) -> PointProjective { + if p.is_zero() { + PointProjective::zero() + } else { + PointProjective { + x: p.x, + y: p.y, + z: Fq::one(), + } + } + } +} + +// The projective point X, Y, Z is represented in the affine +// coordinates as X/Z^2, Y/Z^3. +impl From for PointAffine { + fn from(p: PointProjective) -> PointAffine { + if p.is_zero() { + PointAffine::zero() + } else if p.z == Fq::one() { + // If Z is one, the point is already normalized. + PointAffine { + x: p.x, + y: p.y, + infinity: false, + } + } else { + // Z is nonzero, so it must have an inverse in a field. + let zinv = p.z.inverse().unwrap(); + let mut zinv_powered = zinv; + zinv_powered.square(); + + // X/Z^2 + let mut x = p.x; + x.mul_assign(&zinv_powered); + + // Y/Z^3 + let mut y = p.y; + zinv_powered.mul_assign(&zinv); + y.mul_assign(&zinv_powered); + + PointAffine { + x: x, + y: y, + infinity: false, + } + } + } +} + +impl rand::Rand for PointProjective { + fn rand(rng: &mut R) -> Self { + loop { + let x = rng.gen(); + let greatest = rng.gen(); + + if let Some(p) = PointAffine::get_point_from_x(x, greatest) { + if !p.is_zero() { + if p.is_on_curve() { + return p.into_projective(); + } + } + } + } + } +} + +impl rand::Rand for PointAffine { + fn rand(rng: &mut R) -> Self { + loop { + let x = rng.gen(); + let greatest = rng.gen(); + + if let Some(p) = PointAffine::get_point_from_x(x, greatest) { + if !p.is_zero() { + if p.is_on_curve() { + return p; + } + } + } + } + } +} + +impl PointAffine { + fn get_coeff_a() -> ::Base { + crate::ff::from_hex::( + "0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc", + ) + .unwrap() + } + + fn get_coeff_b() -> ::Base { + crate::ff::from_hex::( + "0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", + ) + .unwrap() + } + + fn get_generator() -> Self { + Self { + x: crate::ff::from_hex::( + "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", + ) + .unwrap(), + y: crate::ff::from_hex::( + "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", + ) + .unwrap(), + infinity: false, + } + } +} + +impl PointProjective { + fn empirical_recommended_wnaf_for_scalar(scalar: FrRepr) -> usize { + let num_bits = scalar.num_bits() as usize; + + if num_bits >= 130 { + 4 + } else if num_bits >= 34 { + 3 + } else { + 2 + } + } + + fn empirical_recommended_wnaf_for_num_scalars(num_scalars: usize) -> usize { + const RECOMMENDATIONS: [usize; 12] = + [1, 3, 7, 20, 43, 120, 273, 563, 1630, 3128, 7933, 62569]; + + let mut ret = 4; + for r in &RECOMMENDATIONS { + if num_scalars > *r { + ret += 1; + } else { + break; + } + } + + ret + } +} + +impl GenericUncompressedEncodable<64> for PointAffine { + /// Converts this element into its uncompressed encoding, so long as it's not + /// the point at infinity. + fn into_uncompressed(&self) -> EncodingBytes { + todo!() + } + + /// Converts an uncompressed encoding into the curve point + fn from_uncompressed(_encoding: EncodingBytes) -> Result { + todo!() + } +} + +impl GenericCompressedEncodable<32> for PointAffine { + /// Converts this element into its uncompressed encoding, so long as it's not + /// the point at infinity. + fn into_compressed(&self) -> (EncodingBytes, bool) { + todo!(); + } + + /// Converts an uncompressed encoding into the curve point + fn from_compressed( + _encoding: EncodingBytes, + _parity: bool, + ) -> Result { + todo!() + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_trivial_mul() { + let mut t1 = PointAffine::one().into_projective(); + t1.double(); + + let mut tt = t1; + let mut base = PointAffine::one(); + base.negate(); + tt.add_assign_mixed(&base); + + assert_eq!(tt.into_affine(), PointAffine::one()); + + let mut t2 = PointAffine::one().into_projective(); + t2.add_assign_mixed(&PointAffine::one()); + + assert_eq!(t1.into_affine(), t2.into_affine()); + + let p = PointAffine::one(); + let result = p.mul(Fr::char()); + assert!(result.is_zero()); + } +} diff --git a/crates/zkevm_circuits/src/sha256_round_function/input.rs b/crates/zkevm_circuits/src/sha256_round_function/input.rs index b6f81c5..ac45eac 100644 --- a/crates/zkevm_circuits/src/sha256_round_function/input.rs +++ b/crates/zkevm_circuits/src/sha256_round_function/input.rs @@ -9,6 +9,7 @@ use boojum::gadgets::queue::*; use boojum::gadgets::traits::allocatable::CSAllocatable; use boojum::gadgets::traits::allocatable::CSPlaceholder; use boojum::gadgets::traits::encodable::CircuitVarLengthEncodable; +use boojum::gadgets::traits::encodable::WitnessVarLengthEncodable; use boojum::cs::traits::cs::ConstraintSystem; use boojum::field::SmallField; @@ -18,7 +19,14 @@ use boojum::gadgets::traits::selectable::Selectable; use boojum::gadgets::traits::witnessable::WitnessHookable; use boojum::serde_utils::BigArraySerde; -#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug)] #[DerivePrettyComparison("true")] pub struct Sha256RoundFunctionFSM { @@ -47,7 +55,14 @@ impl CSPlaceholder for Sha256RoundFunctionFSM { } } -#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug)] #[DerivePrettyComparison("true")] pub struct Sha256RoundFunctionFSMInputOutput { diff --git a/crates/zkevm_circuits/src/sha256_round_function/mod.rs b/crates/zkevm_circuits/src/sha256_round_function/mod.rs index 400ec6d..20437b1 100644 --- a/crates/zkevm_circuits/src/sha256_round_function/mod.rs +++ b/crates/zkevm_circuits/src/sha256_round_function/mod.rs @@ -30,6 +30,7 @@ use boojum::gadgets::sha256::{self}; use boojum::gadgets::traits::allocatable::CSAllocatable; use boojum::gadgets::traits::allocatable::{CSAllocatableExt, CSPlaceholder}; use boojum::gadgets::traits::encodable::CircuitVarLengthEncodable; +use boojum::gadgets::traits::encodable::WitnessVarLengthEncodable; use boojum::gadgets::traits::round_function::CircuitRoundFunction; use boojum::gadgets::u160::UInt160; use boojum::gadgets::u8::UInt8; @@ -38,7 +39,14 @@ use std::sync::{Arc, RwLock}; pub mod input; use self::input::*; -#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug)] // #[DerivePrettyComparison("true")] pub struct Sha256PrecompileCallParams { diff --git a/crates/zkevm_circuits/src/sort_decommittment_requests/input.rs b/crates/zkevm_circuits/src/sort_decommittment_requests/input.rs index de15754..c2d3f56 100644 --- a/crates/zkevm_circuits/src/sort_decommittment_requests/input.rs +++ b/crates/zkevm_circuits/src/sort_decommittment_requests/input.rs @@ -8,19 +8,24 @@ use boojum::gadgets::traits::auxiliary::PrettyComparison; use boojum::gadgets::u32::UInt32; use boojum::gadgets::{ boolean::Boolean, - queue::*, traits::{ - allocatable::*, encodable::CircuitVarLengthEncodable, selectable::Selectable, - witnessable::WitnessHookable, + allocatable::*, encodable::CircuitVarLengthEncodable, encodable::WitnessVarLengthEncodable, + selectable::Selectable, witnessable::WitnessHookable, }, }; use boojum::serde_utils::BigArraySerde; use cs_derive::*; -use derivative::*; pub const PACKED_KEY_LENGTH: usize = 8 + 1; -#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug)] #[DerivePrettyComparison("true")] pub struct CodeDecommittmentsDeduplicatorFSMInputOutput { @@ -56,7 +61,14 @@ impl CSPlaceholder for CodeDecommittmentsDeduplicatorFSMInputO } } -#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug)] #[DerivePrettyComparison("true")] pub struct CodeDecommittmentsDeduplicatorInputData { @@ -75,7 +87,14 @@ impl CSPlaceholder for CodeDecommittmentsDeduplicatorInputData } } -#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug)] #[DerivePrettyComparison("true")] pub struct CodeDecommittmentsDeduplicatorOutputData { diff --git a/crates/zkevm_circuits/src/sort_decommittment_requests/mod.rs b/crates/zkevm_circuits/src/sort_decommittment_requests/mod.rs index 4b9950d..fbe872c 100644 --- a/crates/zkevm_circuits/src/sort_decommittment_requests/mod.rs +++ b/crates/zkevm_circuits/src/sort_decommittment_requests/mod.rs @@ -8,7 +8,7 @@ use boojum::cs::{gates::*, traits::cs::ConstraintSystem}; use boojum::field::SmallField; use boojum::gadgets::queue::full_state_queue::FullStateCircuitQueueWitness; use boojum::gadgets::traits::round_function::CircuitRoundFunction; -use boojum::gadgets::traits::witnessable::WitnessHookable; + use boojum::gadgets::{ boolean::Boolean, num::Num, @@ -17,11 +17,9 @@ use boojum::gadgets::{ u32::UInt32, }; +use crate::base_structures::decommit_query::DecommitQuery; use crate::base_structures::decommit_query::{DecommitQueue, DECOMMIT_QUERY_PACKED_WIDTH}; use crate::base_structures::vm_state::*; -use crate::base_structures::{ - decommit_query::DecommitQuery, memory_query::MEMORY_QUERY_PACKED_WIDTH, -}; use crate::fsm_input_output::{circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH, *}; use crate::sort_decommittment_requests::input::*; use crate::storage_validity_by_grand_product::unpacked_long_comparison; @@ -398,12 +396,10 @@ fn concatenate_key>( #[cfg(test)] mod tests { - use std::alloc::Global; - use super::*; use crate::ethereum_types::U256; use boojum::algebraic_props::poseidon2_parameters::Poseidon2GoldilocksExternalMatrix; - use boojum::cs::implementations::reference_cs::CSDevelopmentAssembly; + use boojum::cs::traits::gate::GatePlacementStrategy; use boojum::cs::CSGeometry; use boojum::cs::*; @@ -529,7 +525,7 @@ mod tests { _, Poseidon2Goldilocks, FULL_SPONGE_QUEUE_STATE_WIDTH, - { MEMORY_QUERY_PACKED_WIDTH + 1 }, + { DECOMMIT_QUERY_PACKED_WIDTH + 1 }, DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS, >( cs, @@ -558,7 +554,7 @@ mod tests { cs.pad_and_shrink(); let worker = Worker::new(); - let mut owned_cs = owned_cs.into_assembly::(); + let mut owned_cs = owned_cs.into_assembly::(); owned_cs.print_gate_stats(); assert!(owned_cs.check_if_satisfied(&worker)); } diff --git a/crates/zkevm_circuits/src/storage_application/input.rs b/crates/zkevm_circuits/src/storage_application/input.rs index 5eb45bc..9d03d59 100644 --- a/crates/zkevm_circuits/src/storage_application/input.rs +++ b/crates/zkevm_circuits/src/storage_application/input.rs @@ -12,8 +12,8 @@ use boojum::gadgets::{ boolean::Boolean, queue::*, traits::{ - allocatable::*, encodable::CircuitVarLengthEncodable, selectable::Selectable, - witnessable::WitnessHookable, + allocatable::*, encodable::CircuitVarLengthEncodable, encodable::WitnessVarLengthEncodable, + selectable::Selectable, witnessable::WitnessHookable, }, }; use boojum::serde_utils::BigArraySerde; @@ -23,7 +23,14 @@ use std::collections::VecDeque; pub const STORAGE_DEPTH: usize = 256; -#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug)] #[DerivePrettyComparison("true")] pub struct StorageApplicationFSMInputOutput { @@ -50,7 +57,14 @@ impl CSPlaceholder for StorageApplicationFSMInputOutput { } } -#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug)] #[DerivePrettyComparison("true")] pub struct StorageApplicationInputData { @@ -71,7 +85,14 @@ impl CSPlaceholder for StorageApplicationInputData { } } -#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug)] #[DerivePrettyComparison("true")] pub struct StorageApplicationOutputData { diff --git a/crates/zkevm_circuits/src/storage_application/mod.rs b/crates/zkevm_circuits/src/storage_application/mod.rs index 950930f..bcce435 100644 --- a/crates/zkevm_circuits/src/storage_application/mod.rs +++ b/crates/zkevm_circuits/src/storage_application/mod.rs @@ -108,6 +108,12 @@ where } } + pub fn new(witness: VecDeque) -> Self { + Self { + witness_source: Arc::new(RwLock::new(witness)), + } + } + pub fn conditionally_allocate_with_default< CS: ConstraintSystem, DEF: FnOnce() -> EL::Witness + 'static + Send + Sync, diff --git a/crates/zkevm_circuits/src/storage_validity_by_grand_product/input.rs b/crates/zkevm_circuits/src/storage_validity_by_grand_product/input.rs index 84ee713..a029b70 100644 --- a/crates/zkevm_circuits/src/storage_validity_by_grand_product/input.rs +++ b/crates/zkevm_circuits/src/storage_validity_by_grand_product/input.rs @@ -12,7 +12,8 @@ use boojum::{ num::*, queue::*, traits::{ - allocatable::*, encodable::CircuitVarLengthEncodable, selectable::Selectable, + allocatable::*, encodable::CircuitVarLengthEncodable, + encodable::WitnessVarLengthEncodable, selectable::Selectable, witnessable::WitnessHookable, }, u160::*, @@ -25,13 +26,20 @@ use boojum::{ use cs_derive::*; use derivative::*; -pub const PACKED_KEY_LENGTH: usize = 5 + 8; +pub const STORAGE_VALIDITY_CHECK_PACKED_KEY_LENGTH: usize = 5 + 8; use super::TimestampedStorageLogRecord; // FSM -#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug)] #[DerivePrettyComparison("true")] pub struct StorageDeduplicatorFSMInputOutput { @@ -41,7 +49,7 @@ pub struct StorageDeduplicatorFSMInputOutput { pub current_intermediate_sorted_queue_state: QueueState, pub current_final_sorted_queue_state: QueueState, pub cycle_idx: UInt32, - pub previous_packed_key: [UInt32; PACKED_KEY_LENGTH], + pub previous_packed_key: [UInt32; STORAGE_VALIDITY_CHECK_PACKED_KEY_LENGTH], pub previous_key: UInt256, pub previous_address: UInt160, pub previous_timestamp: UInt32, @@ -67,7 +75,7 @@ impl CSPlaceholder for StorageDeduplicatorFSMInputOutput { QueueState::::placeholder(cs), current_final_sorted_queue_state: QueueState::::placeholder(cs), cycle_idx: zero_u32, - previous_packed_key: [zero_u32; PACKED_KEY_LENGTH], + previous_packed_key: [zero_u32; STORAGE_VALIDITY_CHECK_PACKED_KEY_LENGTH], previous_key: zero_u256, previous_address: zero_address, previous_timestamp: zero_u32, @@ -79,7 +87,14 @@ impl CSPlaceholder for StorageDeduplicatorFSMInputOutput { } } -#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Debug)] pub struct StorageDeduplicatorInputData { pub shard_id_to_process: UInt8, @@ -97,7 +112,14 @@ impl CSPlaceholder for StorageDeduplicatorInputData { } } -#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] #[derivative(Clone, Copy, Debug)] #[DerivePrettyComparison("true")] pub struct StorageDeduplicatorOutputData { diff --git a/crates/zkevm_circuits/src/storage_validity_by_grand_product/mod.rs b/crates/zkevm_circuits/src/storage_validity_by_grand_product/mod.rs index 9dee43f..39ed1b8 100644 --- a/crates/zkevm_circuits/src/storage_validity_by_grand_product/mod.rs +++ b/crates/zkevm_circuits/src/storage_validity_by_grand_product/mod.rs @@ -52,7 +52,7 @@ use crate::utils::accumulate_grand_products; // for "forward" and "rollback" items, while we do need to have them // on different timestamps -const TIMESTAMPED_STORAGE_LOG_ENCODING_LEN: usize = 20; +pub const TIMESTAMPED_STORAGE_LOG_ENCODING_LEN: usize = 20; use cs_derive::*; @@ -372,12 +372,13 @@ where let zero_u32: UInt32 = UInt32::zero(cs); // there is no code at address 0 in our case, so we can formally use it for all the purposes - let previous_packed_key = <[UInt32; PACKED_KEY_LENGTH]>::conditionally_select( - cs, - structured_input.start_flag, - &[zero_u32; PACKED_KEY_LENGTH], - &structured_input.hidden_fsm_input.previous_packed_key, - ); + let previous_packed_key = + <[UInt32; STORAGE_VALIDITY_CHECK_PACKED_KEY_LENGTH]>::conditionally_select( + cs, + structured_input.start_flag, + &[zero_u32; STORAGE_VALIDITY_CHECK_PACKED_KEY_LENGTH], + &structured_input.hidden_fsm_input.previous_packed_key, + ); let cycle_idx = UInt32::conditionally_select( cs, @@ -531,7 +532,7 @@ pub fn sort_and_deduplicate_storage_access_inner< mut cycle_idx: UInt32, fs_challenges: [[Num; TIMESTAMPED_STORAGE_LOG_ENCODING_LEN + 1]; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], - mut previous_packed_key: [UInt32; PACKED_KEY_LENGTH], + mut previous_packed_key: [UInt32; STORAGE_VALIDITY_CHECK_PACKED_KEY_LENGTH], mut previous_key: UInt256, mut previous_address: UInt160, mut previous_timestamp: UInt32, @@ -545,7 +546,7 @@ pub fn sort_and_deduplicate_storage_access_inner< [Num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], [Num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], UInt32, - [UInt32; PACKED_KEY_LENGTH], + [UInt32; STORAGE_VALIDITY_CHECK_PACKED_KEY_LENGTH], UInt256, UInt160, UInt32, @@ -899,7 +900,7 @@ where fn concatenate_key>( _cs: &mut CS, key_tuple: (UInt160, UInt256), -) -> [UInt32; PACKED_KEY_LENGTH] { +) -> [UInt32; STORAGE_VALIDITY_CHECK_PACKED_KEY_LENGTH] { // LE packing so comparison is subtraction let (address, key) = key_tuple; [ @@ -945,13 +946,9 @@ pub fn unpacked_long_comparison, const N: #[cfg(test)] mod tests { - use std::alloc::Global; - use super::*; use boojum::algebraic_props::poseidon2_parameters::Poseidon2GoldilocksExternalMatrix; - use boojum::cs::implementations::reference_cs::{ - CSDevelopmentAssembly, CSReferenceImplementation, - }; + use boojum::cs::traits::gate::GatePlacementStrategy; use boojum::cs::CSGeometry; // use boojum::cs::EmptyToolbox; @@ -965,7 +962,6 @@ mod tests { type F = GoldilocksField; type P = GoldilocksField; - use boojum::config::*; use boojum::cs::cs_builder::*; fn configure< @@ -1093,7 +1089,8 @@ mod tests { intermediate_sorted_queue.into_state().tail, &round_function, ); - let previous_packed_key = [UInt32::allocated_constant(cs, 0); PACKED_KEY_LENGTH]; + let previous_packed_key = + [UInt32::allocated_constant(cs, 0); STORAGE_VALIDITY_CHECK_PACKED_KEY_LENGTH]; let previous_key = UInt256::allocated_constant(cs, U256::default()); let previous_address = UInt160::allocated_constant(cs, Address::default()); let previous_timestamp = UInt32::allocated_constant(cs, 0); @@ -1129,7 +1126,7 @@ mod tests { cs.pad_and_shrink(); let worker = Worker::new(); - let mut owned_cs = owned_cs.into_assembly::(); + let mut owned_cs = owned_cs.into_assembly::(); owned_cs.print_gate_stats(); assert!(owned_cs.check_if_satisfied(&worker)); } diff --git a/crates/zkevm_circuits/src/storage_validity_by_grand_product/test_input.rs b/crates/zkevm_circuits/src/storage_validity_by_grand_product/test_input.rs index fba4970..19602cb 100644 --- a/crates/zkevm_circuits/src/storage_validity_by_grand_product/test_input.rs +++ b/crates/zkevm_circuits/src/storage_validity_by_grand_product/test_input.rs @@ -1,7 +1,7 @@ use super::TimestampedStorageLogRecord; use crate::base_structures::log_query::LogQuery; use crate::ethereum_types::{Address, U256}; -use boojum::cs::gates::{assert_no_placeholder_variables, assert_no_placeholders}; + use boojum::cs::traits::cs::ConstraintSystem; use boojum::field::goldilocks::GoldilocksField; use boojum::gadgets::{boolean::Boolean, u160::*, u256::*, u32::*, u8::*}; diff --git a/crates/zkevm_circuits/src/tables/call_costs_and_stipends.rs b/crates/zkevm_circuits/src/tables/call_costs_and_stipends.rs new file mode 100644 index 0000000..f8f32b5 --- /dev/null +++ b/crates/zkevm_circuits/src/tables/call_costs_and_stipends.rs @@ -0,0 +1,35 @@ +use super::*; +use boojum::cs::implementations::lookup_table::LookupTable; +use boojum::field::SmallField; +use zkevm_opcode_defs::NUM_SYSTEM_CONTRACTS; + +pub const VM_CALL_COSTS_AND_STIPENDS_TABLE_NAME: &'static str = "Call costs and stipends table"; + +#[derive(Derivative)] +#[derivative(Clone, Copy, Debug, PartialEq, Eq)] +pub struct CallCostsAndStipendsTable; + +pub fn create_call_costs_and_stipends_table() -> LookupTable { + let mut all_keys = Vec::with_capacity(NUM_SYSTEM_CONTRACTS as usize); + let num_rows = zkevm_opcode_defs::STIPENDS_AND_EXTRA_COSTS_TABLE.len(); + + for address in 0..num_rows { + let (caller_cost, stipend) = zkevm_opcode_defs::STIPENDS_AND_EXTRA_COSTS_TABLE[address]; + + let row = [ + F::from_u64(address as u64).unwrap(), + F::from_u64(caller_cost as u64).unwrap(), + F::from_u64(stipend as u64).unwrap(), + ]; + + all_keys.push(row); + } + + assert_eq!(all_keys.len(), num_rows); + + LookupTable::new_from_content( + all_keys, + VM_CALL_COSTS_AND_STIPENDS_TABLE_NAME.to_string(), + 1, + ) +} diff --git a/crates/zkevm_circuits/src/tables/mod.rs b/crates/zkevm_circuits/src/tables/mod.rs index 32989e7..149d37e 100644 --- a/crates/zkevm_circuits/src/tables/mod.rs +++ b/crates/zkevm_circuits/src/tables/mod.rs @@ -1,13 +1,19 @@ use derivative::*; pub mod bitshift; +pub mod call_costs_and_stipends; pub mod conditional; pub mod integer_to_boolean_mask; pub mod opcodes_decoding; +pub mod pubdata_cost_validity; +pub mod test_bit; pub mod uma_ptr_read_cleanup; pub use self::bitshift::*; +pub use self::call_costs_and_stipends::*; pub use self::conditional::*; pub use self::integer_to_boolean_mask::*; pub use self::opcodes_decoding::*; +pub use self::pubdata_cost_validity::*; +pub use self::test_bit::*; pub use self::uma_ptr_read_cleanup::*; diff --git a/crates/zkevm_circuits/src/tables/pubdata_cost_validity.rs b/crates/zkevm_circuits/src/tables/pubdata_cost_validity.rs new file mode 100644 index 0000000..3cce844 --- /dev/null +++ b/crates/zkevm_circuits/src/tables/pubdata_cost_validity.rs @@ -0,0 +1,34 @@ +use super::*; +use boojum::cs::implementations::lookup_table::LookupTable; +use boojum::field::SmallField; + +pub const VM_PUBDATA_COST_VALIDITY_TABLE_NAME: &'static str = "Pubdata cost validity table"; + +#[derive(Derivative)] +#[derivative(Clone, Copy, Debug, PartialEq, Eq)] +pub struct PubdataCostValidityTable; + +pub fn create_pubdata_cost_validity_table() -> LookupTable { + let range = -65i8..=65i8; + let num_rows = range.len(); + let mut all_keys = Vec::with_capacity(num_rows); + + for pubdata_cost_or_refund in range { + let cost_as_u32 = (pubdata_cost_or_refund as i32) as u32; + + let sign_bit = pubdata_cost_or_refund < 0; + let absolute_value = pubdata_cost_or_refund.abs() as u8 as u32; + + let row = [ + F::from_u64(cost_as_u32 as u64).unwrap(), + F::from_u64(sign_bit as u64).unwrap(), + F::from_u64(absolute_value as u64).unwrap(), + ]; + + all_keys.push(row); + } + + assert_eq!(all_keys.len(), num_rows); + + LookupTable::new_from_content(all_keys, VM_PUBDATA_COST_VALIDITY_TABLE_NAME.to_string(), 1) +} diff --git a/crates/zkevm_circuits/src/tables/test_bit.rs b/crates/zkevm_circuits/src/tables/test_bit.rs new file mode 100644 index 0000000..93488d4 --- /dev/null +++ b/crates/zkevm_circuits/src/tables/test_bit.rs @@ -0,0 +1,44 @@ +use super::*; +use boojum::cs::implementations::lookup_table::LookupTable; +use boojum::field::SmallField; + +pub const TEST_BIT_TABLE_NAME: &'static str = "Test bit table"; + +#[derive(Derivative)] +#[derivative(Clone, Copy, Debug, PartialEq, Eq)] +pub struct TestBitTable; + +pub fn create_test_bit_table() -> LookupTable { + // we put u8 word in the first element, and bit index (starting from 0) in the second element, + // and get 0/1 as a result + let num_rows = (1 << 8) * 8; + let mut all_keys = Vec::with_capacity(num_rows); + + for byte_value in 0..256 { + for bit_idx in 0..8 { + let key = smallvec::smallvec![ + F::from_u64_unchecked(byte_value as u64), + F::from_u64_unchecked(bit_idx as u64) + ]; + all_keys.push(key); + } + } + + LookupTable::new_from_keys_and_generation_function( + &all_keys, + TEST_BIT_TABLE_NAME.to_string(), + 2, + |keys| { + let byte = keys[0].as_u64_reduced(); + let bit_index = keys[1].as_u64_reduced(); + + let result = if byte & (1 << bit_index) == 0 { + 0u64 + } else { + 1u64 + }; + + smallvec::smallvec![F::from_u64_unchecked(result)] + }, + ) +} diff --git a/crates/zkevm_circuits/src/transient_storage_validity_by_grand_product/input.rs b/crates/zkevm_circuits/src/transient_storage_validity_by_grand_product/input.rs new file mode 100644 index 0000000..1da18ce --- /dev/null +++ b/crates/zkevm_circuits/src/transient_storage_validity_by_grand_product/input.rs @@ -0,0 +1,121 @@ +use crate::base_structures::{ + log_query::{LogQuery, LOG_QUERY_PACKED_WIDTH}, + vm_state::*, +}; +use crate::DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS; +use boojum::cs::{traits::cs::ConstraintSystem, Variable}; +use boojum::field::SmallField; +use boojum::gadgets::traits::auxiliary::PrettyComparison; +use boojum::{ + gadgets::{ + boolean::Boolean, + num::*, + queue::*, + traits::{ + allocatable::*, encodable::CircuitVarLengthEncodable, + encodable::WitnessVarLengthEncodable, selectable::Selectable, + witnessable::WitnessHookable, + }, + u256::*, + u32::*, + }, + serde_utils::BigArraySerde, +}; +use cs_derive::*; +use derivative::*; + +use super::TimestampedStorageLogRecord; + +pub const TRANSIENT_STORAGE_VALIDITY_CHECK_PACKED_KEY_LENGTH: usize = 1 + 1 + 5 + 8; + +// FSM + +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] +#[derivative(Clone, Copy, Debug)] +#[DerivePrettyComparison("true")] +pub struct TransientStorageDeduplicatorFSMInputOutput { + pub lhs_accumulator: [Num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + pub rhs_accumulator: [Num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + pub current_unsorted_queue_state: QueueState, + pub current_intermediate_sorted_queue_state: QueueState, + pub cycle_idx: UInt32, + pub previous_packed_key: [UInt32; TRANSIENT_STORAGE_VALIDITY_CHECK_PACKED_KEY_LENGTH], // it captures tx number, shard id, address and key + pub previous_timestamp: UInt32, + pub this_cell_current_value: UInt256, + pub this_cell_current_depth: UInt32, +} + +impl CSPlaceholder for TransientStorageDeduplicatorFSMInputOutput { + fn placeholder>(cs: &mut CS) -> Self { + let zero_num = Num::::zero(cs); + let zero_u32 = UInt32::zero(cs); + let zero_u256 = UInt256::zero(cs); + + Self { + lhs_accumulator: [zero_num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + rhs_accumulator: [zero_num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + current_unsorted_queue_state: QueueState::::placeholder(cs), + current_intermediate_sorted_queue_state: + QueueState::::placeholder(cs), + cycle_idx: zero_u32, + previous_packed_key: [zero_u32; TRANSIENT_STORAGE_VALIDITY_CHECK_PACKED_KEY_LENGTH], + previous_timestamp: zero_u32, + this_cell_current_value: zero_u256, + this_cell_current_depth: zero_u32, + } + } +} + +#[derive( + Derivative, + CSAllocatable, + CSSelectable, + CSVarLengthEncodable, + WitnessHookable, + WitVarLengthEncodable, +)] +#[derivative(Clone, Debug)] +pub struct TransientStorageDeduplicatorInputData { + pub unsorted_log_queue_state: QueueState, + pub intermediate_sorted_queue_state: QueueState, +} + +impl CSPlaceholder for TransientStorageDeduplicatorInputData { + fn placeholder>(cs: &mut CS) -> Self { + Self { + unsorted_log_queue_state: QueueState::::placeholder(cs), + intermediate_sorted_queue_state: QueueState::::placeholder(cs), + } + } +} + +pub type TransientStorageDeduplicatorInputOutput = crate::fsm_input_output::ClosedFormInput< + F, + TransientStorageDeduplicatorFSMInputOutput, + TransientStorageDeduplicatorInputData, + (), +>; +pub type TransientStorageDeduplicatorInputOutputWitness = + crate::fsm_input_output::ClosedFormInputWitness< + F, + TransientStorageDeduplicatorFSMInputOutput, + TransientStorageDeduplicatorInputData, + (), + >; + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Debug, Default)] +#[serde(bound = "")] +pub struct TransientStorageDeduplicatorInstanceWitness { + pub closed_form_input: TransientStorageDeduplicatorInputOutputWitness, + pub unsorted_queue_witness: CircuitQueueRawWitness, 4, LOG_QUERY_PACKED_WIDTH>, + pub intermediate_sorted_queue_witness: + CircuitQueueRawWitness, 4, LOG_QUERY_PACKED_WIDTH>, +} diff --git a/crates/zkevm_circuits/src/transient_storage_validity_by_grand_product/mod.rs b/crates/zkevm_circuits/src/transient_storage_validity_by_grand_product/mod.rs new file mode 100644 index 0000000..96a1971 --- /dev/null +++ b/crates/zkevm_circuits/src/transient_storage_validity_by_grand_product/mod.rs @@ -0,0 +1,797 @@ +use super::*; + +pub mod input; + +// #[cfg(test)] +// mod test_input; + +use crate::fsm_input_output::ClosedFormInputCompactForm; +use crate::storage_validity_by_grand_product::unpacked_long_comparison; + +use crate::base_structures::{log_query::LogQuery, vm_state::*}; +use boojum::algebraic_props::round_function::AlgebraicRoundFunction; + +use boojum::cs::{gates::*, traits::cs::ConstraintSystem}; +use boojum::field::SmallField; + +use boojum::gadgets::traits::round_function::CircuitRoundFunction; +use boojum::gadgets::{ + boolean::Boolean, + num::Num, + queue::*, + traits::{allocatable::*, selectable::Selectable}, + u160::*, + u256::*, + u32::UInt32, + u8::UInt8, +}; + +use self::input::*; +use crate::storage_validity_by_grand_product::TIMESTAMPED_STORAGE_LOG_ENCODING_LEN; +use crate::utils::accumulate_grand_products; +use crate::{ + demux_log_queue::StorageLogQueue, + fsm_input_output::{circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH, *}, +}; + +// we make a generation aware memory that store all the old and new values +// for a current storage cell. There are largely 3 possible sequences that we must be aware of +// - write_0, .. .... without rollback of the current write +// - write_0, ..., rollback_0, read_0, ... - in this case we must issue and explicit read, even though it's not the first one +// - read_0, ..., - same as above + +// We use extra structure with timestamping. Even though we DO have +// timestamp field in LogQuery, such timestamp is the SAME +// for "forward" and "rollback" items, while we do need to have them +// on different timestamps + +use crate::storage_validity_by_grand_product::TimestampedStorageLogRecord; +use std::sync::Arc; + +pub fn sort_and_deduplicate_transient_storage_access_entry_point< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, +>( + cs: &mut CS, + closed_form_input: TransientStorageDeduplicatorInstanceWitness, + round_function: &R, + limit: usize, +) -> [Num; INPUT_OUTPUT_COMMITMENT_LENGTH] +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + let structured_input_witness = closed_form_input.closed_form_input; + let unsorted_queue_witness = closed_form_input.unsorted_queue_witness; + let intermediate_sorted_queue_witness = closed_form_input.intermediate_sorted_queue_witness; + + let mut structured_input = TransientStorageDeduplicatorInputOutput::alloc_ignoring_outputs( + cs, + structured_input_witness.clone(), + ); + + let unsorted_queue_from_passthrough_state = QueueState { + head: structured_input + .observable_input + .unsorted_log_queue_state + .head, + tail: structured_input + .observable_input + .unsorted_log_queue_state + .tail, + }; + + let unsorted_queue_from_fsm_input_state = QueueState { + head: structured_input + .hidden_fsm_input + .current_unsorted_queue_state + .head, + tail: structured_input + .hidden_fsm_input + .current_unsorted_queue_state + .tail, + }; + + // passthrought must be trivial + unsorted_queue_from_passthrough_state.enforce_trivial_head(cs); + + let state = QueueState::conditionally_select( + cs, + structured_input.start_flag, + &unsorted_queue_from_passthrough_state, + &unsorted_queue_from_fsm_input_state, + ); + let mut unsorted_queue = StorageLogQueue::::from_state(cs, state); + + unsorted_queue.witness = Arc::new(CircuitQueueWitness::from_inner_witness( + unsorted_queue_witness, + )); + + // same logic from sorted + let intermediate_sorted_queue_from_passthrough = CircuitQueue::< + F, + TimestampedStorageLogRecord, + 8, + 12, + 4, + QUEUE_STATE_WIDTH, + TIMESTAMPED_STORAGE_LOG_ENCODING_LEN, + R, + >::from_raw_parts( + cs, + structured_input + .observable_input + .intermediate_sorted_queue_state + .head, + structured_input + .observable_input + .intermediate_sorted_queue_state + .tail + .tail, + structured_input + .observable_input + .intermediate_sorted_queue_state + .tail + .length, + ); + + let intermediate_sorted_queue_from_fsm_input = CircuitQueue::< + F, + TimestampedStorageLogRecord, + 8, + 12, + 4, + QUEUE_STATE_WIDTH, + TIMESTAMPED_STORAGE_LOG_ENCODING_LEN, + R, + >::from_raw_parts( + cs, + structured_input + .hidden_fsm_input + .current_intermediate_sorted_queue_state + .head, + structured_input + .hidden_fsm_input + .current_intermediate_sorted_queue_state + .tail + .tail, + structured_input + .hidden_fsm_input + .current_intermediate_sorted_queue_state + .tail + .length, + ); + + // passthrought must be trivial + intermediate_sorted_queue_from_passthrough.enforce_trivial_head(cs); + + let state = QueueState::conditionally_select( + cs, + structured_input.start_flag, + &intermediate_sorted_queue_from_passthrough.into_state(), + &intermediate_sorted_queue_from_fsm_input.into_state(), + ); + let mut intermediate_sorted_queue = CircuitQueue::< + F, + TimestampedStorageLogRecord, + 8, + 12, + 4, + QUEUE_STATE_WIDTH, + TIMESTAMPED_STORAGE_LOG_ENCODING_LEN, + R, + >::from_state(cs, state); + + intermediate_sorted_queue.witness = Arc::new(CircuitQueueWitness::from_inner_witness( + intermediate_sorted_queue_witness, + )); + + // get challenges for permutation argument + let challenges = crate::utils::produce_fs_challenges::< + F, + CS, + R, + QUEUE_STATE_WIDTH, + { TIMESTAMPED_STORAGE_LOG_ENCODING_LEN + 1 }, + DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS, + >( + cs, + structured_input + .observable_input + .unsorted_log_queue_state + .tail, + structured_input + .observable_input + .intermediate_sorted_queue_state + .tail, + round_function, + ); + + let one = Num::allocated_constant(cs, F::ONE); + let initial_lhs = + <[Num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS]>::conditionally_select( + cs, + structured_input.start_flag, + &[one; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + &structured_input.hidden_fsm_input.lhs_accumulator, + ); + + let initial_rhs = + <[Num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS]>::conditionally_select( + cs, + structured_input.start_flag, + &[one; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + &structured_input.hidden_fsm_input.rhs_accumulator, + ); + + let zero_u32: UInt32 = UInt32::zero(cs); + + // there is no code at address 0 in our case, so we can formally use it for all the purposes + let previous_packed_key = + <[UInt32; TRANSIENT_STORAGE_VALIDITY_CHECK_PACKED_KEY_LENGTH]>::conditionally_select( + cs, + structured_input.start_flag, + &[zero_u32; TRANSIENT_STORAGE_VALIDITY_CHECK_PACKED_KEY_LENGTH], + &structured_input.hidden_fsm_input.previous_packed_key, + ); + + let cycle_idx = UInt32::conditionally_select( + cs, + structured_input.start_flag, + &zero_u32, + &structured_input.hidden_fsm_input.cycle_idx, + ); + + let ( + new_lhs, + new_rhs, + cycle_idx, + previous_packed_key, + previous_timestamp, + this_cell_current_value, + this_cell_current_depth, + ) = sort_and_deduplicate_transient_storage_access_inner( + cs, + initial_lhs, + initial_rhs, + &mut unsorted_queue, + &mut intermediate_sorted_queue, + structured_input.start_flag, + cycle_idx, + challenges, + previous_packed_key, + structured_input.hidden_fsm_input.previous_timestamp, + structured_input.hidden_fsm_input.this_cell_current_value, + structured_input.hidden_fsm_input.this_cell_current_depth, + limit, + ); + + unsorted_queue.enforce_consistency(cs); + intermediate_sorted_queue.enforce_consistency(cs); + + let unsorted_is_empty = unsorted_queue.is_empty(cs); + let sorted_is_empty = intermediate_sorted_queue.is_empty(cs); + + Boolean::enforce_equal(cs, &unsorted_is_empty, &sorted_is_empty); + + let completed = unsorted_is_empty.and(cs, sorted_is_empty); + new_lhs.iter().zip(new_rhs).for_each(|(l, r)| { + Num::conditionally_enforce_equal(cs, completed, &l, &r); + }); + + // form the input/output + + structured_input.hidden_fsm_output.cycle_idx = cycle_idx; + structured_input.hidden_fsm_output.previous_packed_key = previous_packed_key; + structured_input.hidden_fsm_output.previous_timestamp = previous_timestamp; + structured_input.hidden_fsm_output.this_cell_current_value = this_cell_current_value; + structured_input.hidden_fsm_output.this_cell_current_depth = this_cell_current_depth; + + structured_input.hidden_fsm_output.lhs_accumulator = new_lhs; + structured_input.hidden_fsm_output.rhs_accumulator = new_rhs; + + structured_input + .hidden_fsm_output + .current_unsorted_queue_state = unsorted_queue.into_state(); + structured_input + .hidden_fsm_output + .current_intermediate_sorted_queue_state = intermediate_sorted_queue.into_state(); + + structured_input.completion_flag = completed; + + structured_input.hook_compare_witness(cs, &structured_input_witness); + + let compact_form = + ClosedFormInputCompactForm::from_full_form(cs, &structured_input, round_function); + + // dbg!(compact_form.create_witness()); + let input_committment = + commit_variable_length_encodable_item(cs, &compact_form, round_function); + for el in input_committment.iter() { + let gate = PublicInputGate::new(el.get_variable()); + gate.add_to_cs(cs); + } + + input_committment +} + +pub const NUM_PERMUTATION_ARG_CHALLENGES: usize = TIMESTAMPED_STORAGE_LOG_ENCODING_LEN + 1; + +pub fn sort_and_deduplicate_transient_storage_access_inner< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction, +>( + cs: &mut CS, + mut lhs: [Num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + mut rhs: [Num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + original_queue: &mut StorageLogQueue, + intermediate_sorted_queue: &mut CircuitQueue< + F, + TimestampedStorageLogRecord, + 8, + 12, + 4, + QUEUE_STATE_WIDTH, + TIMESTAMPED_STORAGE_LOG_ENCODING_LEN, + R, + >, + is_start: Boolean, + mut cycle_idx: UInt32, + fs_challenges: [[Num; TIMESTAMPED_STORAGE_LOG_ENCODING_LEN + 1]; + DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + mut previous_packed_key: [UInt32; TRANSIENT_STORAGE_VALIDITY_CHECK_PACKED_KEY_LENGTH], + mut previous_timestamp: UInt32, + mut this_cell_current_value: UInt256, + mut this_cell_current_depth: UInt32, + limit: usize, +) -> ( + [Num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + [Num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + UInt32, + [UInt32; TRANSIENT_STORAGE_VALIDITY_CHECK_PACKED_KEY_LENGTH], + UInt32, + UInt256, + UInt32, +) +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + assert!(limit <= u32::MAX as usize); + + let unsorted_queue_length = Num::from_variable(original_queue.length.get_variable()); + let intermediate_sorted_queue_length = + Num::from_variable(intermediate_sorted_queue.length.get_variable()); + + Num::enforce_equal( + cs, + &unsorted_queue_length, + &intermediate_sorted_queue_length, + ); + + // we simultaneously pop, accumulate partial product, + // and decide whether or not we should move to the next cell + + // to ensure uniqueness we place timestamps in a addition to the original values encoding access location + + for _cycle in 0..limit { + let original_timestamp = cycle_idx; + // increment it immediatelly + unsafe { + let new_cycle_idx = cycle_idx.increment_unchecked(cs); + cycle_idx = new_cycle_idx; + } + + let original_is_empty = original_queue.is_empty(cs); + let sorted_is_empty = intermediate_sorted_queue.is_empty(cs); + Boolean::enforce_equal(cs, &original_is_empty, &sorted_is_empty); + + let original_is_not_empty = original_is_empty.negated(cs); + let sorted_is_not_empty = sorted_is_empty.negated(cs); + + let should_pop = Boolean::multi_and(cs, &[original_is_not_empty, sorted_is_not_empty]); + let item_is_trivial = original_is_empty; + let item_is_non_trivial = item_is_trivial.negated(cs); + + // NOTE: we do not need to check shard_id of unsorted item because we can just check it on sorted item + let (_, original_encoding) = original_queue.pop_front(cs, should_pop); + let (sorted_item, sorted_encoding) = intermediate_sorted_queue.pop_front(cs, should_pop); + let extended_original_encoding = + TimestampedStorageLogRecord::append_timestamp_to_raw_query_encoding( + cs, + &original_encoding, + &original_timestamp, + ); + + accumulate_grand_products::< + F, + CS, + TIMESTAMPED_STORAGE_LOG_ENCODING_LEN, + { TIMESTAMPED_STORAGE_LOG_ENCODING_LEN + 1 }, + DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS, + >( + cs, + &mut lhs, + &mut rhs, + &fs_challenges, + &extended_original_encoding, + &sorted_encoding, + should_pop, + ); + + let TimestampedStorageLogRecord { record, timestamp } = sorted_item; + + // now resolve a logic about sorting itself + let packed_key = concatenate_key( + cs, + record.tx_number_in_block, + record.shard_id, + record.address, + record.key, + ); + + // ensure sorting. Check that previous key < this key + let (keys_are_equal, previous_key_is_greater) = + unpacked_long_comparison(cs, &previous_packed_key, &packed_key); + + previous_key_is_greater.conditionally_enforce_false(cs, item_is_non_trivial); + + // if keys are the same then timestamps are sorted + let (_, previous_timestamp_is_less) = previous_timestamp.overflowing_sub(cs, timestamp); + // enforce if keys are the same and not trivial + let must_enforce = keys_are_equal.and(cs, item_is_non_trivial); + previous_timestamp_is_less.conditionally_enforce_true(cs, must_enforce); + + // we follow the procedure: + // if keys are different then we finish with a previous one and update parameters + // else we just update parameters + + let not_keys_are_equal = keys_are_equal.negated(cs); + let new_non_trivial_cell = + Boolean::multi_and(cs, &[not_keys_are_equal, item_is_non_trivial]); + let read_value_is_zero = record.read_value.is_zero(cs); + + // if new cell + { + if _cycle == 0 { + // it must always be true if we start + let should_enforce = Boolean::multi_and(cs, &[is_start, should_pop]); + not_keys_are_equal.conditionally_enforce_true(cs, should_enforce); + } + + // we just discard the old one and that's it + + // enforce that we read 0 always for new cell + read_value_is_zero.conditionally_enforce_true(cs, new_non_trivial_cell); + + // and update as we switch to the new cell with extra logic + let meaningful_value = UInt256::conditionally_select( + cs, + record.rw_flag, + &record.written_value, + &record.read_value, + ); + + // update current value + this_cell_current_value = UInt256::conditionally_select( + cs, + new_non_trivial_cell, + &meaningful_value, + &this_cell_current_value, + ); + + let one = UInt32::allocated_constant(cs, 1); + let zero = UInt32::zero(cs); + let rollback_depth_for_new_cell = + UInt32::conditionally_select(cs, record.rw_flag, &one, &zero); + + this_cell_current_depth = UInt32::conditionally_select( + cs, + new_non_trivial_cell, + &rollback_depth_for_new_cell, + &this_cell_current_depth, + ); + } + + // if same cell - update + { + let not_rw_flag = record.rw_flag.negated(cs); + let non_trivial_and_same_cell = item_is_non_trivial.and(cs, keys_are_equal); + let non_trivial_read_of_same_cell = non_trivial_and_same_cell.and(cs, not_rw_flag); + let non_trivial_write_of_same_cell = non_trivial_and_same_cell.and(cs, record.rw_flag); + let not_rollback = record.rollback.negated(cs); + let write_no_rollback = non_trivial_write_of_same_cell.and(cs, not_rollback); + let write_rollback = non_trivial_write_of_same_cell.and(cs, record.rollback); + + // update rollback depth the is a result of this action + unsafe { + let incremented_depth = this_cell_current_depth.increment_unchecked(cs); + this_cell_current_depth = UInt32::conditionally_select( + cs, + write_no_rollback, + &incremented_depth, + &this_cell_current_depth, + ); + let decremented_depth = this_cell_current_depth.decrement_unchecked(cs); + this_cell_current_depth = UInt32::conditionally_select( + cs, + write_rollback, + &decremented_depth, + &this_cell_current_depth, + ); + } + + // check consistency + let read_is_equal_to_current = + UInt256::equals(cs, &this_cell_current_value, &record.read_value); + // we ALWAYS ensure read consistency on write (but not rollback) and on plain read + let check_read_consistency = + Boolean::multi_or(cs, &[non_trivial_read_of_same_cell, write_no_rollback]); + read_is_equal_to_current.conditionally_enforce_true(cs, check_read_consistency); + + // decide to update + this_cell_current_value = UInt256::conditionally_select( + cs, + write_no_rollback, + &record.written_value, + &this_cell_current_value, + ); + + this_cell_current_value = UInt256::conditionally_select( + cs, + write_rollback, + &record.read_value, + &this_cell_current_value, + ); + + let current_rollback_depth_is_zero = this_cell_current_depth.is_zero(cs); + let read_at_rollback_depth_zero_of_same_cell = + current_rollback_depth_is_zero.and(cs, non_trivial_read_of_same_cell); + + // we rolled back all the way - check if read value is 0 again + let should_enforce = Boolean::multi_and( + cs, + &[ + item_is_non_trivial, + read_at_rollback_depth_zero_of_same_cell, + ], + ); + read_value_is_zero.conditionally_enforce_true(cs, should_enforce); + } + + // always update counters + previous_timestamp = timestamp; + previous_packed_key = packed_key; + } + + // there is no post-processing or finalization + + // output our FSM values + + ( + lhs, + rhs, + cycle_idx, + previous_packed_key, + previous_timestamp, + this_cell_current_value, + this_cell_current_depth, + ) +} + +fn concatenate_key>( + _cs: &mut CS, + tx_number: UInt32, + shard_id: UInt8, + address: UInt160, + key: UInt256, +) -> [UInt32; TRANSIENT_STORAGE_VALIDITY_CHECK_PACKED_KEY_LENGTH] { + let shard_id_as_u32 = unsafe { UInt32::from_variable_unchecked(shard_id.get_variable()) }; + // LE packing so comparison is subtraction. Since every TX is independent it's just a part of key + [ + key.inner[0], + key.inner[1], + key.inner[2], + key.inner[3], + key.inner[4], + key.inner[5], + key.inner[6], + key.inner[7], + address.inner[0], + address.inner[1], + address.inner[2], + address.inner[3], + address.inner[4], + shard_id_as_u32, + tx_number, + ] +} + +// #[cfg(test)] +// mod tests { +// use super::*; +// use boojum::algebraic_props::poseidon2_parameters::Poseidon2GoldilocksExternalMatrix; + +// use boojum::cs::traits::gate::GatePlacementStrategy; +// use boojum::cs::CSGeometry; +// // use boojum::cs::EmptyToolbox; +// use boojum::cs::*; +// use boojum::field::goldilocks::GoldilocksField; +// use boojum::gadgets::tables::*; +// use boojum::implementations::poseidon2::Poseidon2Goldilocks; +// use boojum::worker::Worker; +// use ethereum_types::{Address, U256}; + +// type F = GoldilocksField; +// type P = GoldilocksField; + +// use boojum::cs::cs_builder::*; + +// fn configure< +// T: CsBuilderImpl, +// GC: GateConfigurationHolder, +// TB: StaticToolboxHolder, +// >( +// builder: CsBuilder, +// ) -> CsBuilder, impl StaticToolboxHolder> { +// let owned_cs = builder; +// let owned_cs = owned_cs.allow_lookup( +// LookupParameters::UseSpecializedColumnsWithTableIdAsConstant { +// width: 3, +// num_repetitions: 8, +// share_table_id: true, +// }, +// ); +// let owned_cs = ConstantsAllocatorGate::configure_builder( +// owned_cs, +// GatePlacementStrategy::UseGeneralPurposeColumns, +// ); +// let owned_cs = FmaGateInBaseFieldWithoutConstant::configure_builder( +// owned_cs, +// GatePlacementStrategy::UseGeneralPurposeColumns, +// ); +// let owned_cs = ReductionGate::::configure_builder( +// owned_cs, +// GatePlacementStrategy::UseGeneralPurposeColumns, +// ); +// let owned_cs = BooleanConstraintGate::configure_builder( +// owned_cs, +// GatePlacementStrategy::UseGeneralPurposeColumns, +// ); +// let owned_cs = UIntXAddGate::<32>::configure_builder( +// owned_cs, +// GatePlacementStrategy::UseGeneralPurposeColumns, +// ); +// let owned_cs = UIntXAddGate::<16>::configure_builder( +// owned_cs, +// GatePlacementStrategy::UseGeneralPurposeColumns, +// ); +// let owned_cs = SelectionGate::configure_builder( +// owned_cs, +// GatePlacementStrategy::UseGeneralPurposeColumns, +// ); +// let owned_cs = ZeroCheckGate::configure_builder( +// owned_cs, +// GatePlacementStrategy::UseGeneralPurposeColumns, +// false, +// ); +// let owned_cs = DotProductGate::<4>::configure_builder( +// owned_cs, +// GatePlacementStrategy::UseGeneralPurposeColumns, +// ); +// let owned_cs = +// MatrixMultiplicationGate::::configure_builder( +// owned_cs, +// GatePlacementStrategy::UseGeneralPurposeColumns, +// ); +// let owned_cs = +// NopGate::configure_builder(owned_cs, GatePlacementStrategy::UseGeneralPurposeColumns); + +// owned_cs +// } + +// #[test] +// fn test_storage_validity_circuit() { +// let geometry = CSGeometry { +// num_columns_under_copy_permutation: 100, +// num_witness_columns: 0, +// num_constant_columns: 8, +// max_allowed_constraint_degree: 4, +// }; + +// use boojum::config::DevCSConfig; +// use boojum::cs::cs_builder_reference::*; + +// let builder_impl = +// CsReferenceImplementationBuilder::::new(geometry, 1 << 26, 1 << 20); +// use boojum::cs::cs_builder::new_builder; +// let builder = new_builder::<_, F>(builder_impl); + +// let builder = configure(builder); +// let mut owned_cs = builder.build(()); + +// // add tables +// let table = create_xor8_table(); +// owned_cs.add_lookup_table::(table); + +// let cs = &mut owned_cs; + +// let lhs = [Num::allocated_constant(cs, F::from_nonreduced_u64(1)); +// DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS]; +// let rhs = [Num::allocated_constant(cs, F::from_nonreduced_u64(1)); +// DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS]; + +// let execute = Boolean::allocated_constant(cs, true); +// let mut original_queue = StorageLogQueue::::empty(cs); +// let unsorted_input = test_input::generate_test_input_unsorted(cs); +// for el in unsorted_input { +// original_queue.push(cs, el, execute); +// } + +// let mut intermediate_sorted_queue = CircuitQueue::empty(cs); +// let sorted_input = test_input::generate_test_input_sorted(cs); +// for el in sorted_input { +// intermediate_sorted_queue.push(cs, el, execute); +// } + +// let mut sorted_queue = StorageLogQueue::empty(cs); + +// let is_start = Boolean::allocated_constant(cs, true); +// let cycle_idx = UInt32::allocated_constant(cs, 0); +// let round_function = Poseidon2Goldilocks; +// let fs_challenges = crate::utils::produce_fs_challenges::< +// F, +// _, +// Poseidon2Goldilocks, +// QUEUE_STATE_WIDTH, +// { TIMESTAMPED_STORAGE_LOG_ENCODING_LEN + 1 }, +// DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS, +// >( +// cs, +// original_queue.into_state().tail, +// intermediate_sorted_queue.into_state().tail, +// &round_function, +// ); +// let previous_packed_key = [UInt32::allocated_constant(cs, 0); PACKED_KEY_LENGTH]; +// let previous_key = UInt256::allocated_constant(cs, U256::default()); +// let previous_address = UInt160::allocated_constant(cs, Address::default()); +// let previous_timestamp = UInt32::allocated_constant(cs, 0); +// let this_cell_has_explicit_read_and_rollback_depth_zero = +// Boolean::allocated_constant(cs, false); +// let this_cell_base_value = UInt256::allocated_constant(cs, U256::default()); +// let this_cell_current_value = UInt256::allocated_constant(cs, U256::default()); +// let this_cell_current_depth = UInt32::allocated_constant(cs, 0); +// let shard_id_to_process = UInt8::allocated_constant(cs, 0); +// let limit = 16; + +// sort_and_deduplicate_storage_access_inner( +// cs, +// lhs, +// rhs, +// &mut original_queue, +// &mut intermediate_sorted_queue, +// &mut sorted_queue, +// is_start, +// cycle_idx, +// fs_challenges, +// previous_packed_key, +// previous_key, +// previous_address, +// previous_timestamp, +// this_cell_has_explicit_read_and_rollback_depth_zero, +// this_cell_base_value, +// this_cell_current_value, +// this_cell_current_depth, +// shard_id_to_process, +// limit, +// ); + +// cs.pad_and_shrink(); +// let worker = Worker::new(); +// let mut owned_cs = owned_cs.into_assembly(); +// owned_cs.print_gate_stats(); +// assert!(owned_cs.check_if_satisfied(&worker)); +// } +// } diff --git a/crates/zkevm_opcode_defs/Cargo.toml b/crates/zkevm_opcode_defs/Cargo.toml index ae50bb5..5a04ad4 100644 --- a/crates/zkevm_opcode_defs/Cargo.toml +++ b/crates/zkevm_opcode_defs/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zkevm_opcode_defs" -version = "0.141.0" +version = "0.150.0" edition = "2021" authors = ["The Matter Labs Team "] homepage = "https://zksync.io/" @@ -26,3 +26,5 @@ sha2 = "=0.10.8" sha3 = "=0.10.8" blake2 = "0.10.*" k256 = { version = "0.13.*", features = ["arithmetic", "ecdsa"] } +p256 = { version = "0.13.*", features = ["arithmetic", "ecdsa"] } +serde = { version = "1", features = ["derive"] } diff --git a/crates/zkevm_opcode_defs/src/circuit_prices.rs b/crates/zkevm_opcode_defs/src/circuit_prices.rs index 03330ff..869173b 100644 --- a/crates/zkevm_opcode_defs/src/circuit_prices.rs +++ b/crates/zkevm_opcode_defs/src/circuit_prices.rs @@ -8,6 +8,7 @@ pub const STORAGE_APPLICATION_COST_IN_ERGS: u32 = 678; pub const CODE_DECOMMITTER_SORTER_COST_IN_ERGS: u32 = 1; pub const LOG_DEMUXER_COST_IN_ERGS: u32 = 1; pub const STORAGE_SORTER_COST_IN_ERGS: u32 = 2; +pub const TRANSIENT_STORE_CHECKER_COST_IN_ERGS: u32 = 2; pub const EVENTS_OR_L1_MESSAGES_SORTER_COST_IN_ERGS: u32 = 1; pub const INITIAL_WRITES_PUBDATA_HASHER_COST_IN_ERGS: u32 = 18; pub const REPEATED_WRITES_PUBDATA_HASHER_COST_IN_ERGS: u32 = 11; diff --git a/crates/zkevm_opcode_defs/src/definitions/abi/meta.rs b/crates/zkevm_opcode_defs/src/definitions/abi/meta.rs index 35505ae..2b2c2b4 100644 --- a/crates/zkevm_opcode_defs/src/definitions/abi/meta.rs +++ b/crates/zkevm_opcode_defs/src/definitions/abi/meta.rs @@ -2,7 +2,7 @@ use super::*; #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct VmMetaParameters { - pub ergs_per_pubdata_byte: u32, + pub aux_field_0: u32, pub heap_size: u32, pub aux_heap_size: u32, pub this_shard_id: u8, @@ -13,7 +13,7 @@ pub struct VmMetaParameters { impl VmMetaParameters { pub const fn to_u256(self) -> U256 { let mut result = U256::zero(); - result.0[0] = self.ergs_per_pubdata_byte as u64; + result.0[0] = self.aux_field_0 as u64; result.0[1] = (self.heap_size as u64) | ((self.aux_heap_size as u64) << 32); let tmp = (self.this_shard_id as u64) diff --git a/crates/zkevm_opcode_defs/src/definitions/abi/precompile_call.rs b/crates/zkevm_opcode_defs/src/definitions/abi/precompile_call.rs index b20f24a..d82ccfd 100644 --- a/crates/zkevm_opcode_defs/src/definitions/abi/precompile_call.rs +++ b/crates/zkevm_opcode_defs/src/definitions/abi/precompile_call.rs @@ -47,3 +47,29 @@ impl PrecompileCallABI { result } } + +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct PrecompileAuxData { + pub extra_ergs_cost: u32, + pub extra_pubdata_cost: u32, +} + +impl PrecompileAuxData { + pub const fn from_u256(raw_value: U256) -> Self { + let raw = raw_value.0; + let extra_ergs_cost = raw[0] as u32; + let extra_pubdata_cost = (raw[0] >> 32) as u32; + + Self { + extra_ergs_cost, + extra_pubdata_cost, + } + } + + pub const fn to_u256(self) -> U256 { + let mut result = U256::zero(); + result.0[0] = (self.extra_ergs_cost as u64) | ((self.extra_pubdata_cost as u64) << 32); + + result + } +} diff --git a/crates/zkevm_opcode_defs/src/definitions/add.rs b/crates/zkevm_opcode_defs/src/definitions/add.rs index e33f734..8519665 100644 --- a/crates/zkevm_opcode_defs/src/definitions/add.rs +++ b/crates/zkevm_opcode_defs/src/definitions/add.rs @@ -47,6 +47,9 @@ impl OpcodeProps for AddOpcode { ISAVersion(1) => { full_variants_product(0..=Self::max_variant_idx_for_version(version), 1, 2) } + ISAVersion(2) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 1, 2) + } _ => unimplemented!(), } } diff --git a/crates/zkevm_opcode_defs/src/definitions/binop.rs b/crates/zkevm_opcode_defs/src/definitions/binop.rs index 9ff6879..ff01749 100644 --- a/crates/zkevm_opcode_defs/src/definitions/binop.rs +++ b/crates/zkevm_opcode_defs/src/definitions/binop.rs @@ -51,6 +51,9 @@ impl OpcodeProps for BinopOpcode { ISAVersion(1) => { full_variants_product(0..=Self::max_variant_idx_for_version(version), 1, 2) } + ISAVersion(2) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 1, 2) + } _ => unimplemented!(), } } diff --git a/crates/zkevm_opcode_defs/src/definitions/context.rs b/crates/zkevm_opcode_defs/src/definitions/context.rs index 897b31b..88e2efd 100644 --- a/crates/zkevm_opcode_defs/src/definitions/context.rs +++ b/crates/zkevm_opcode_defs/src/definitions/context.rs @@ -11,7 +11,7 @@ pub enum ContextOpcode { Sp, GetContextU128, SetContextU128, - SetErgsPerPubdataByte, + AuxMutating0, IncrementTxNumber, } @@ -26,7 +26,7 @@ impl OpcodeVariantProps for ContextOpcode { ContextOpcode::Sp, ContextOpcode::GetContextU128, ContextOpcode::SetContextU128, - ContextOpcode::SetErgsPerPubdataByte, + ContextOpcode::AuxMutating0, ContextOpcode::IncrementTxNumber, ] } @@ -59,8 +59,8 @@ impl OpcodeVariantProps for ContextOpcode { i if i == ContextOpcode::SetContextU128.variant_index() => { Some(ContextOpcode::SetContextU128) } - i if i == ContextOpcode::SetErgsPerPubdataByte.variant_index() => { - Some(ContextOpcode::SetErgsPerPubdataByte) + i if i == ContextOpcode::AuxMutating0.variant_index() => { + Some(ContextOpcode::AuxMutating0) } i if i == ContextOpcode::IncrementTxNumber.variant_index() => { Some(ContextOpcode::IncrementTxNumber) @@ -86,6 +86,9 @@ impl OpcodeProps for ContextOpcode { ISAVersion(1) => { full_variants_product(0..=Self::max_variant_idx_for_version(version), 0, 0) } + ISAVersion(2) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 0, 0) + } _ => unimplemented!(), } } @@ -94,7 +97,7 @@ impl OpcodeProps for ContextOpcode { } fn input_operands(&self, _version: ISAVersion) -> Vec { match self { - ContextOpcode::SetContextU128 | ContextOpcode::SetErgsPerPubdataByte => { + ContextOpcode::SetContextU128 | ContextOpcode::AuxMutating0 => { vec![Operand::RegOnly] } _ => vec![], @@ -103,7 +106,7 @@ impl OpcodeProps for ContextOpcode { fn output_operands(&self, _version: ISAVersion) -> Vec { match self { ContextOpcode::SetContextU128 - | ContextOpcode::SetErgsPerPubdataByte + | ContextOpcode::AuxMutating0 | ContextOpcode::IncrementTxNumber => vec![], _ => vec![Operand::RegOnly], } @@ -111,7 +114,7 @@ impl OpcodeProps for ContextOpcode { fn requires_kernel_mode(&self) -> bool { match self { ContextOpcode::SetContextU128 - | ContextOpcode::SetErgsPerPubdataByte + | ContextOpcode::AuxMutating0 | ContextOpcode::IncrementTxNumber => true, _ => false, } @@ -119,7 +122,7 @@ impl OpcodeProps for ContextOpcode { fn can_be_used_in_static_context(&self) -> bool { match self { ContextOpcode::SetContextU128 - | ContextOpcode::SetErgsPerPubdataByte + | ContextOpcode::AuxMutating0 | ContextOpcode::IncrementTxNumber => false, _ => true, } diff --git a/crates/zkevm_opcode_defs/src/definitions/div.rs b/crates/zkevm_opcode_defs/src/definitions/div.rs index 4f7435d..d4da970 100644 --- a/crates/zkevm_opcode_defs/src/definitions/div.rs +++ b/crates/zkevm_opcode_defs/src/definitions/div.rs @@ -44,6 +44,9 @@ impl OpcodeProps for DivOpcode { ISAVersion(1) => { full_variants_product(0..=Self::max_variant_idx_for_version(version), 2, 2) } + ISAVersion(2) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 2, 2) + } _ => unimplemented!(), } } diff --git a/crates/zkevm_opcode_defs/src/definitions/far_call.rs b/crates/zkevm_opcode_defs/src/definitions/far_call.rs index 49151eb..98474b3 100644 --- a/crates/zkevm_opcode_defs/src/definitions/far_call.rs +++ b/crates/zkevm_opcode_defs/src/definitions/far_call.rs @@ -1,5 +1,5 @@ use crate::circuit_prices::{ - CODE_DECOMMITMENT_SORTER_COST_IN_ERGS, RAM_PERMUTATION_COST_IN_ERGS, + CODE_DECOMMITMENT_SORTER_COST_IN_ERGS, LOG_DEMUXER_COST_IN_ERGS, RAM_PERMUTATION_COST_IN_ERGS, STORAGE_SORTER_COST_IN_ERGS, VM_CYCLE_COST_IN_ERGS, }; @@ -60,6 +60,7 @@ impl OpcodeVariantProps for FarCallOpcode { + CALL_LIKE_ERGS_COST + STORAGE_SORTER_COST_IN_ERGS + CODE_DECOMMITMENT_SORTER_COST_IN_ERGS + + LOG_DEMUXER_COST_IN_ERGS } } @@ -75,6 +76,9 @@ impl OpcodeProps for FarCallOpcode { ISAVersion(1) => { full_variants_product(0..=Self::max_variant_idx_for_version(version), 2, 1) } + ISAVersion(2) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 2, 1) + } _ => unimplemented!(), } } diff --git a/crates/zkevm_opcode_defs/src/definitions/invalid_opcode.rs b/crates/zkevm_opcode_defs/src/definitions/invalid_opcode.rs index 4f3dada..ccf50ff 100644 --- a/crates/zkevm_opcode_defs/src/definitions/invalid_opcode.rs +++ b/crates/zkevm_opcode_defs/src/definitions/invalid_opcode.rs @@ -44,6 +44,9 @@ impl OpcodeProps for InvalidOpcode { ISAVersion(1) => { full_variants_product(0..=Self::max_variant_idx_for_version(version), 0, 0) } + ISAVersion(2) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 0, 0) + } _ => unimplemented!(), } } diff --git a/crates/zkevm_opcode_defs/src/definitions/jump.rs b/crates/zkevm_opcode_defs/src/definitions/jump.rs index 28b3ec9..b86522a 100644 --- a/crates/zkevm_opcode_defs/src/definitions/jump.rs +++ b/crates/zkevm_opcode_defs/src/definitions/jump.rs @@ -44,6 +44,9 @@ impl OpcodeProps for JumpOpcode { ISAVersion(1) => { full_variants_product(0..=Self::max_variant_idx_for_version(version), 0, 1) } + ISAVersion(2) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 0, 1) + } _ => unimplemented!(), } } @@ -54,7 +57,7 @@ impl OpcodeProps for JumpOpcode { vec![Operand::Full(ImmMemHandlerFlags::UseRegOnly)] } fn output_operands(&self, _version: ISAVersion) -> Vec { - vec![] + vec![Operand::RegOnly] } fn requires_kernel_mode(&self) -> bool { false diff --git a/crates/zkevm_opcode_defs/src/definitions/log.rs b/crates/zkevm_opcode_defs/src/definitions/log.rs index 5e7fcc2..44ac4c9 100644 --- a/crates/zkevm_opcode_defs/src/definitions/log.rs +++ b/crates/zkevm_opcode_defs/src/definitions/log.rs @@ -1,10 +1,14 @@ use crate::{ circuit_prices::{ - EVENTS_OR_L1_MESSAGES_SORTER_COST_IN_ERGS, L1_MESSAGE_MIN_COST_IN_ERGS, - LOG_DEMUXER_COST_IN_ERGS, RAM_PERMUTATION_COST_IN_ERGS, STORAGE_SORTER_COST_IN_ERGS, - VM_CYCLE_COST_IN_ERGS, + EVENTS_OR_L1_MESSAGES_SORTER_COST_IN_ERGS, LOG_DEMUXER_COST_IN_ERGS, + RAM_PERMUTATION_COST_IN_ERGS, STORAGE_SORTER_COST_IN_ERGS, VM_CYCLE_COST_IN_ERGS, }, - system_params::MIN_STORAGE_WRITE_COST, + system_params::{STORAGE_ACCESS_COLD_READ_COST, STORAGE_ACCESS_COLD_WRITE_COST}, +}; + +use self::{ + circuit_prices::{CODE_DECOMMITMENT_SORTER_COST_IN_ERGS, TRANSIENT_STORE_CHECKER_COST_IN_ERGS}, + system_params::{STORAGE_ACCESS_WARM_READ_COST, STORAGE_ACCESS_WARM_WRITE_COST}, }; use super::*; @@ -19,6 +23,9 @@ pub enum LogOpcode { ToL1Message, Event, PrecompileCall, + Decommit, + TransientStorageRead, + TransientStorageWrite, } impl OpcodeVariantProps for LogOpcode { @@ -29,63 +36,98 @@ impl OpcodeVariantProps for LogOpcode { LogOpcode::ToL1Message, LogOpcode::Event, LogOpcode::PrecompileCall, + LogOpcode::Decommit, + LogOpcode::TransientStorageRead, + LogOpcode::TransientStorageWrite, ] } - fn max_variant_idx_for_version(_version: ISAVersion) -> usize { - LogOpcode::PrecompileCall.variant_index() + fn max_variant_idx_for_version(version: ISAVersion) -> usize { + match version { + ISAVersion(0) | ISAVersion(1) => LogOpcode::PrecompileCall.variant_index(), + ISAVersion(2) => LogOpcode::TransientStorageWrite.variant_index(), + _ => unreachable!(), + } } fn minimal_version(&self) -> ISAVersion { - ALL_ISA_VERSIONS[0] + match self { + LogOpcode::StorageRead + | LogOpcode::StorageWrite + | LogOpcode::ToL1Message + | LogOpcode::Event + | LogOpcode::PrecompileCall => ISAVersion(0), + LogOpcode::Decommit + | LogOpcode::TransientStorageRead + | LogOpcode::TransientStorageWrite => ISAVersion(2), + } } fn variant_index(&self) -> usize { (*self as u8) as usize } - fn from_variant_index_for_version(index: usize, _version: &ISAVersion) -> Option { - match index { - i if i == LogOpcode::StorageRead.variant_index() => Some(LogOpcode::StorageRead), - i if i == LogOpcode::StorageWrite.variant_index() => Some(LogOpcode::StorageWrite), - i if i == LogOpcode::ToL1Message.variant_index() => Some(LogOpcode::ToL1Message), - i if i == LogOpcode::Event.variant_index() => Some(LogOpcode::Event), - i if i == LogOpcode::PrecompileCall.variant_index() => Some(LogOpcode::PrecompileCall), - _ => None, + fn from_variant_index_for_version(index: usize, version: &ISAVersion) -> Option { + match version { + ISAVersion(0) | ISAVersion(1) => match index { + i if i == LogOpcode::StorageRead.variant_index() => Some(LogOpcode::StorageRead), + i if i == LogOpcode::StorageWrite.variant_index() => Some(LogOpcode::StorageWrite), + i if i == LogOpcode::ToL1Message.variant_index() => Some(LogOpcode::ToL1Message), + i if i == LogOpcode::Event.variant_index() => Some(LogOpcode::Event), + i if i == LogOpcode::PrecompileCall.variant_index() => { + Some(LogOpcode::PrecompileCall) + } + _ => None, + }, + ISAVersion(2) => match index { + i if i == LogOpcode::StorageRead.variant_index() => Some(LogOpcode::StorageRead), + i if i == LogOpcode::StorageWrite.variant_index() => Some(LogOpcode::StorageWrite), + i if i == LogOpcode::ToL1Message.variant_index() => Some(LogOpcode::ToL1Message), + i if i == LogOpcode::Event.variant_index() => Some(LogOpcode::Event), + i if i == LogOpcode::PrecompileCall.variant_index() => { + Some(LogOpcode::PrecompileCall) + } + i if i == LogOpcode::Decommit.variant_index() => Some(LogOpcode::Decommit), + i if i == LogOpcode::TransientStorageRead.variant_index() => { + Some(LogOpcode::TransientStorageRead) + } + i if i == LogOpcode::TransientStorageWrite.variant_index() => { + Some(LogOpcode::TransientStorageWrite) + } + _ => None, + }, + _ => unreachable!(), } } fn ergs_price(&self) -> u32 { match self { LogOpcode::StorageRead => { - STORAGE_READ_IO_PRICE - + VM_CYCLE_COST_IN_ERGS + VM_CYCLE_COST_IN_ERGS + RAM_PERMUTATION_COST_IN_ERGS + LOG_DEMUXER_COST_IN_ERGS + STORAGE_SORTER_COST_IN_ERGS + + STORAGE_ACCESS_COLD_READ_COST } // If the write was not initial, the user will be refunded LogOpcode::StorageWrite => { - let intrinsic = STORAGE_WRITE_IO_PRICE - + 2 * VM_CYCLE_COST_IN_ERGS + VM_CYCLE_COST_IN_ERGS + RAM_PERMUTATION_COST_IN_ERGS + 2 * LOG_DEMUXER_COST_IN_ERGS - + 2 * STORAGE_SORTER_COST_IN_ERGS; - - std::cmp::max(intrinsic, MIN_STORAGE_WRITE_COST) + + 2 * STORAGE_SORTER_COST_IN_ERGS + + STORAGE_ACCESS_COLD_WRITE_COST } // Note, that the `L1_MESSAGE_MIN_COST_IN_ERGS` is only needed for DDoS protection LogOpcode::ToL1Message => { - let intrinsic_cost = L1_MESSAGE_IO_PRICE - + 2 * VM_CYCLE_COST_IN_ERGS + L1_MESSAGE_IO_PRICE + + VM_CYCLE_COST_IN_ERGS + RAM_PERMUTATION_COST_IN_ERGS + 2 * LOG_DEMUXER_COST_IN_ERGS - + 2 * EVENTS_OR_L1_MESSAGES_SORTER_COST_IN_ERGS; - std::cmp::max(intrinsic_cost, L1_MESSAGE_MIN_COST_IN_ERGS) + + 2 * EVENTS_OR_L1_MESSAGES_SORTER_COST_IN_ERGS } LogOpcode::Event => { EVENT_IO_PRICE - + 2 * VM_CYCLE_COST_IN_ERGS + + VM_CYCLE_COST_IN_ERGS + RAM_PERMUTATION_COST_IN_ERGS + 2 * LOG_DEMUXER_COST_IN_ERGS + 2 * EVENTS_OR_L1_MESSAGES_SORTER_COST_IN_ERGS @@ -93,6 +135,29 @@ impl OpcodeVariantProps for LogOpcode { LogOpcode::PrecompileCall => { VM_CYCLE_COST_IN_ERGS + RAM_PERMUTATION_COST_IN_ERGS + LOG_DEMUXER_COST_IN_ERGS } + LogOpcode::Decommit => { + VM_CYCLE_COST_IN_ERGS + + RAM_PERMUTATION_COST_IN_ERGS + + CODE_DECOMMITMENT_SORTER_COST_IN_ERGS + } + LogOpcode::TransientStorageRead => { + VM_CYCLE_COST_IN_ERGS + + RAM_PERMUTATION_COST_IN_ERGS + + LOG_DEMUXER_COST_IN_ERGS + + TRANSIENT_STORE_CHECKER_COST_IN_ERGS + // The pricing for transient operations is the same as for the warm storage ones, due + // to the need of handling reverts. + + STORAGE_ACCESS_WARM_READ_COST + } + LogOpcode::TransientStorageWrite => { + VM_CYCLE_COST_IN_ERGS + + RAM_PERMUTATION_COST_IN_ERGS + + 2 * LOG_DEMUXER_COST_IN_ERGS + + 2 * TRANSIENT_STORE_CHECKER_COST_IN_ERGS + // The pricing for transient operations is the same as for the warm storage ones, due + // to the need of handling reverts. + + STORAGE_ACCESS_WARM_WRITE_COST + } } } } @@ -137,39 +202,110 @@ impl OpcodeProps for LogOpcode { }, ] } + ISAVersion(2) => { + vec![ + // Storage read + OpcodeVariantData { + variant_idx: LogOpcode::StorageRead.variant_index(), + num_non_exclusive_flags: 0, + num_used_immediates: 0, + }, + // Storage write + OpcodeVariantData { + variant_idx: LogOpcode::StorageWrite.variant_index(), + num_non_exclusive_flags: 0, + num_used_immediates: 0, + }, + // L1 message + OpcodeVariantData { + variant_idx: LogOpcode::ToL1Message.variant_index(), + num_non_exclusive_flags: 1, // can be "initial" + num_used_immediates: 0, + }, + // Event + OpcodeVariantData { + variant_idx: LogOpcode::Event.variant_index(), + num_non_exclusive_flags: 1, // can be initial + num_used_immediates: 0, + }, + // Precompile calls + OpcodeVariantData { + variant_idx: LogOpcode::PrecompileCall.variant_index(), + num_non_exclusive_flags: 0, + num_used_immediates: 0, + }, + // Decommit request + OpcodeVariantData { + variant_idx: LogOpcode::Decommit.variant_index(), + num_non_exclusive_flags: 0, + num_used_immediates: 0, + }, + // Transient read + OpcodeVariantData { + variant_idx: LogOpcode::TransientStorageRead.variant_index(), + num_non_exclusive_flags: 0, + num_used_immediates: 0, + }, + // Transient write + OpcodeVariantData { + variant_idx: LogOpcode::TransientStorageWrite.variant_index(), + num_non_exclusive_flags: 0, + num_used_immediates: 0, + }, + ] + } + _ => unimplemented!(), } } - fn max_variant_idx(&self, _version: ISAVersion) -> usize { - LogOpcode::PrecompileCall.variant_index() + + fn max_variant_idx(&self, version: ISAVersion) -> usize { + match version { + ISAVersion(0) | ISAVersion(1) => LogOpcode::PrecompileCall.variant_index(), + ISAVersion(2) => LogOpcode::TransientStorageWrite.variant_index(), + _ => unreachable!(), + } } + fn input_operands(&self, _version: ISAVersion) -> Vec { match self { LogOpcode::StorageWrite | LogOpcode::Event | LogOpcode::ToL1Message - | LogOpcode::PrecompileCall => { + | LogOpcode::PrecompileCall + | LogOpcode::Decommit + | LogOpcode::TransientStorageWrite => { vec![Operand::RegOnly, Operand::RegOnly] } - LogOpcode::StorageRead => vec![Operand::RegOnly], + LogOpcode::StorageRead | Self::TransientStorageRead => vec![Operand::RegOnly], } } fn output_operands(&self, _version: ISAVersion) -> Vec { match self { - LogOpcode::StorageWrite | LogOpcode::Event | LogOpcode::ToL1Message => vec![], - LogOpcode::StorageRead => vec![Operand::RegOnly], + LogOpcode::StorageWrite + | LogOpcode::Event + | LogOpcode::ToL1Message + | LogOpcode::TransientStorageWrite => vec![], + LogOpcode::StorageRead | LogOpcode::TransientStorageRead => vec![Operand::RegOnly], LogOpcode::PrecompileCall => vec![Operand::RegOnly], + LogOpcode::Decommit => vec![Operand::RegOnly], } } fn requires_kernel_mode(&self) -> bool { match self { - LogOpcode::Event | LogOpcode::ToL1Message | LogOpcode::PrecompileCall => true, + LogOpcode::Event + | LogOpcode::ToL1Message + | LogOpcode::PrecompileCall + | LogOpcode::Decommit => true, _ => false, } } fn can_be_used_in_static_context(&self) -> bool { match self { - LogOpcode::StorageWrite | LogOpcode::Event | LogOpcode::ToL1Message => false, + LogOpcode::StorageWrite + | LogOpcode::Event + | LogOpcode::ToL1Message + | LogOpcode::TransientStorageWrite => false, _ => true, } } diff --git a/crates/zkevm_opcode_defs/src/definitions/mod.rs b/crates/zkevm_opcode_defs/src/definitions/mod.rs index bcb8041..18b6a66 100644 --- a/crates/zkevm_opcode_defs/src/definitions/mod.rs +++ b/crates/zkevm_opcode_defs/src/definitions/mod.rs @@ -371,7 +371,7 @@ pub fn synthesize_opcode_decoding_tables_legacy( } } } - (&[Operand::Full(_)], &[]) => { + (&[Operand::Full(_)], &[]) | (&[Operand::Full(_)], &[Operand::RegOnly]) => { // we need to encode all combinations of input and output being reg/stack/code/imm // but we only have a case of inputs for variant_data in all_variants_added_in_this_version.into_iter() { @@ -566,7 +566,7 @@ fn all_variants_in_version(version: ISAVersion) -> Vec { } } } - (&[Operand::Full(_)], &[]) => { + (&[Operand::Full(_)], &[]) | (&[Operand::Full(_)], &[Operand::RegOnly]) => { // we need to encode all combinations of input and output being reg/stack/code/imm // but we only have a case of inputs let variant_idx = variant_data.variant_idx; @@ -1007,8 +1007,10 @@ mod test { fn calculator() { let mut v0 = all_variants_in_version(ISAVersion(0)); dbg!(v0.len()); - let v1 = all_variants_in_version(ISAVersion(1)); + let mut v1 = all_variants_in_version(ISAVersion(1)); dbg!(v1.len()); + let v2 = all_variants_in_version(ISAVersion(2)); + dbg!(v2.len()); // check that our ordering doesn't change for legacy tables let legacy_v0 = synthesize_opcode_decoding_tables_legacy(11, ISAVersion(0)); @@ -1018,7 +1020,7 @@ mod test { let num_non_trivial_v0 = compute_encoding_density(ISAVersion(0)); assert_eq!(&legacy_v0[..], &new_v0[..]); - let difference = find_new_opcodes(&mut v0, &v1); + let _difference_v0_v1 = find_new_opcodes(&mut v0, &v1); let new_v1 = synthesize_opcode_decoding_tables(11, ISAVersion(1)); let num_non_trivial_v1 = compute_encoding_density(ISAVersion(1)); @@ -1036,6 +1038,24 @@ mod test { assert!(new_v0[idx].is_explicit_panic()); } - dbg!(&difference); + let difference_v1_v2 = find_new_opcodes(&mut v1, &v2); + + let new_v2 = synthesize_opcode_decoding_tables(11, ISAVersion(2)); + let num_non_trivial_v2 = compute_encoding_density(ISAVersion(2)); + + for (a, b) in new_v1[..num_non_trivial_v1] + .iter() + .zip(new_v2[..num_non_trivial_v1].iter()) + { + assert!(semantically_equal(a, b)); + } + + assert!(num_non_trivial_v2 >= num_non_trivial_v1); + + for idx in num_non_trivial_v1..num_non_trivial_v2 { + assert!(new_v1[idx].is_explicit_panic()); + } + + dbg!(&difference_v1_v2); } } diff --git a/crates/zkevm_opcode_defs/src/definitions/mul.rs b/crates/zkevm_opcode_defs/src/definitions/mul.rs index c237d00..d78fd45 100644 --- a/crates/zkevm_opcode_defs/src/definitions/mul.rs +++ b/crates/zkevm_opcode_defs/src/definitions/mul.rs @@ -44,6 +44,9 @@ impl OpcodeProps for MulOpcode { ISAVersion(1) => { full_variants_product(0..=Self::max_variant_idx_for_version(version), 1, 2) } + ISAVersion(2) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 1, 2) + } _ => unimplemented!(), } } diff --git a/crates/zkevm_opcode_defs/src/definitions/near_call.rs b/crates/zkevm_opcode_defs/src/definitions/near_call.rs index a9f7d30..9c32d32 100644 --- a/crates/zkevm_opcode_defs/src/definitions/near_call.rs +++ b/crates/zkevm_opcode_defs/src/definitions/near_call.rs @@ -44,6 +44,9 @@ impl OpcodeProps for NearCallOpcode { ISAVersion(1) => { full_variants_product(0..=Self::max_variant_idx_for_version(version), 0, 2) } + ISAVersion(2) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 0, 2) + } _ => unimplemented!(), } } diff --git a/crates/zkevm_opcode_defs/src/definitions/noop.rs b/crates/zkevm_opcode_defs/src/definitions/noop.rs index 67ea83e..9ba224f 100644 --- a/crates/zkevm_opcode_defs/src/definitions/noop.rs +++ b/crates/zkevm_opcode_defs/src/definitions/noop.rs @@ -44,6 +44,9 @@ impl OpcodeProps for NopOpcode { ISAVersion(1) => { full_variants_product(0..=Self::max_variant_idx_for_version(version), 0, 2) } + ISAVersion(2) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 0, 2) + } _ => unimplemented!(), } } diff --git a/crates/zkevm_opcode_defs/src/definitions/opcode_trait.rs b/crates/zkevm_opcode_defs/src/definitions/opcode_trait.rs index c4b010e..bc7ba86 100644 --- a/crates/zkevm_opcode_defs/src/definitions/opcode_trait.rs +++ b/crates/zkevm_opcode_defs/src/definitions/opcode_trait.rs @@ -36,8 +36,9 @@ impl ISAVersion { } } -pub const NUM_ISA_VERSIONS: usize = 2; -pub const ALL_ISA_VERSIONS: [ISAVersion; NUM_ISA_VERSIONS] = [ISAVersion(0), ISAVersion(1)]; +pub const NUM_ISA_VERSIONS: usize = 3; +pub const ALL_ISA_VERSIONS: [ISAVersion; NUM_ISA_VERSIONS] = + [ISAVersion(0), ISAVersion(1), ISAVersion(2)]; #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct OpcodeVariantData { diff --git a/crates/zkevm_opcode_defs/src/definitions/ptr.rs b/crates/zkevm_opcode_defs/src/definitions/ptr.rs index 841cf4c..1e095e2 100644 --- a/crates/zkevm_opcode_defs/src/definitions/ptr.rs +++ b/crates/zkevm_opcode_defs/src/definitions/ptr.rs @@ -61,6 +61,9 @@ impl OpcodeProps for PtrOpcode { ISAVersion(1) => { full_variants_product(0..=Self::max_variant_idx_for_version(version), 1, 2) } + ISAVersion(2) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 1, 2) + } _ => unimplemented!(), } } diff --git a/crates/zkevm_opcode_defs/src/definitions/ret.rs b/crates/zkevm_opcode_defs/src/definitions/ret.rs index ed506fc..dfa133d 100644 --- a/crates/zkevm_opcode_defs/src/definitions/ret.rs +++ b/crates/zkevm_opcode_defs/src/definitions/ret.rs @@ -58,6 +58,9 @@ impl OpcodeProps for RetOpcode { ISAVersion(1) => { full_variants_product(0..=Self::max_variant_idx_for_version(version), 1, 1) } + ISAVersion(2) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 1, 1) + } _ => unimplemented!(), } } diff --git a/crates/zkevm_opcode_defs/src/definitions/shift.rs b/crates/zkevm_opcode_defs/src/definitions/shift.rs index d41fda9..ea3fe8d 100644 --- a/crates/zkevm_opcode_defs/src/definitions/shift.rs +++ b/crates/zkevm_opcode_defs/src/definitions/shift.rs @@ -58,6 +58,9 @@ impl OpcodeProps for ShiftOpcode { ISAVersion(1) => { full_variants_product(0..=Self::max_variant_idx_for_version(version), 2, 2) } + ISAVersion(2) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 2, 2) + } _ => unimplemented!(), } } diff --git a/crates/zkevm_opcode_defs/src/definitions/sub.rs b/crates/zkevm_opcode_defs/src/definitions/sub.rs index 255a593..de2d67e 100644 --- a/crates/zkevm_opcode_defs/src/definitions/sub.rs +++ b/crates/zkevm_opcode_defs/src/definitions/sub.rs @@ -47,6 +47,9 @@ impl OpcodeProps for SubOpcode { ISAVersion(1) => { full_variants_product(0..=Self::max_variant_idx_for_version(version), 2, 2) } + ISAVersion(2) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 2, 2) + } _ => unimplemented!(), } } diff --git a/crates/zkevm_opcode_defs/src/definitions/uma.rs b/crates/zkevm_opcode_defs/src/definitions/uma.rs index 9b805cb..b90b1a5 100644 --- a/crates/zkevm_opcode_defs/src/definitions/uma.rs +++ b/crates/zkevm_opcode_defs/src/definitions/uma.rs @@ -18,6 +18,8 @@ pub enum UMAOpcode { AuxHeapRead, AuxHeapWrite, FatPointerRead, + StaticMemoryRead, + StaticMemoryWrite, } pub const UMA_INCREMENT_FLAG_IDX: usize = 0; @@ -30,6 +32,8 @@ impl OpcodeVariantProps for UMAOpcode { UMAOpcode::AuxHeapRead, UMAOpcode::AuxHeapWrite, UMAOpcode::FatPointerRead, + UMAOpcode::StaticMemoryRead, + UMAOpcode::StaticMemoryWrite, ] } @@ -37,12 +41,14 @@ impl OpcodeVariantProps for UMAOpcode { match version { ISAVersion(0) => UMAOpcode::FatPointerRead.variant_index(), ISAVersion(1) => UMAOpcode::FatPointerRead.variant_index(), + ISAVersion(2) => UMAOpcode::StaticMemoryWrite.variant_index(), _ => unimplemented!(), } } fn minimal_version(&self) -> ISAVersion { match self { + UMAOpcode::StaticMemoryRead | UMAOpcode::StaticMemoryWrite => ALL_ISA_VERSIONS[2], _ => ALL_ISA_VERSIONS[0], } } @@ -51,26 +57,43 @@ impl OpcodeVariantProps for UMAOpcode { (*self as u8) as usize } - fn from_variant_index_for_version(index: usize, _version: &ISAVersion) -> Option { + fn from_variant_index_for_version(index: usize, version: &ISAVersion) -> Option { match index { i if i == UMAOpcode::HeapRead.variant_index() => Some(UMAOpcode::HeapRead), i if i == UMAOpcode::HeapWrite.variant_index() => Some(UMAOpcode::HeapWrite), i if i == UMAOpcode::AuxHeapRead.variant_index() => Some(UMAOpcode::AuxHeapRead), i if i == UMAOpcode::AuxHeapWrite.variant_index() => Some(UMAOpcode::AuxHeapWrite), i if i == UMAOpcode::FatPointerRead.variant_index() => Some(UMAOpcode::FatPointerRead), + i if i == UMAOpcode::StaticMemoryRead.variant_index() => { + if version >= &ALL_ISA_VERSIONS[2] { + Some(UMAOpcode::StaticMemoryRead) + } else { + None + } + } + i if i == UMAOpcode::StaticMemoryWrite.variant_index() => { + if version >= &ALL_ISA_VERSIONS[2] { + Some(UMAOpcode::StaticMemoryWrite) + } else { + None + } + } _ => None, } } fn ergs_price(&self) -> u32 { match self { - UMAOpcode::AuxHeapWrite | UMAOpcode::HeapWrite => { + UMAOpcode::AuxHeapWrite | UMAOpcode::HeapWrite | UMAOpcode::StaticMemoryWrite => { // 5 RAM permutations, because: 1 to read opcode + 2 reads + 2 writes. // 2 reads and 2 writes are needed because unaligned access is implemented with // aligned queries 2 * VM_CYCLE_COST_IN_ERGS + 5 * RAM_PERMUTATION_COST_IN_ERGS } - UMAOpcode::HeapRead | UMAOpcode::AuxHeapRead | UMAOpcode::FatPointerRead => { + UMAOpcode::HeapRead + | UMAOpcode::AuxHeapRead + | UMAOpcode::FatPointerRead + | UMAOpcode::StaticMemoryRead => { // 5 RAM permutations, because: 1 to read opcode + 2 reads. // 2 reads are needed because unaligned access is implemented with aligned queries VM_CYCLE_COST_IN_ERGS + 3 * RAM_PERMUTATION_COST_IN_ERGS @@ -91,6 +114,9 @@ impl OpcodeProps for UMAOpcode { ISAVersion(1) => { full_variants_product(0..=Self::max_variant_idx_for_version(version), 1, 0) } + ISAVersion(2) => { + full_variants_product(0..=Self::max_variant_idx_for_version(version), 1, 0) + } _ => unimplemented!(), } } @@ -98,6 +124,7 @@ impl OpcodeProps for UMAOpcode { match version { ISAVersion(0) => UMAOpcode::FatPointerRead.variant_index(), ISAVersion(1) => UMAOpcode::FatPointerRead.variant_index(), + ISAVersion(2) => UMAOpcode::StaticMemoryWrite.variant_index(), _ => unimplemented!(), } } @@ -109,14 +136,16 @@ impl OpcodeProps for UMAOpcode { } _ => vec![Operand::RegOnly], }, - ISAVersion(1) => { + ISAVersion(1) | ISAVersion(2) => { // we allow imm on the inputs for heap access for offsets match self { - UMAOpcode::HeapWrite | UMAOpcode::AuxHeapWrite => vec![ + UMAOpcode::HeapWrite + | UMAOpcode::AuxHeapWrite + | UMAOpcode::StaticMemoryWrite => vec![ Operand::RegOrImm(RegOrImmFlags::UseRegOnly), Operand::RegOnly, ], - UMAOpcode::HeapRead | UMAOpcode::AuxHeapRead => { + UMAOpcode::HeapRead | UMAOpcode::AuxHeapRead | UMAOpcode::StaticMemoryRead => { vec![Operand::RegOrImm(RegOrImmFlags::UseRegOnly)] } UMAOpcode::FatPointerRead => { @@ -129,12 +158,17 @@ impl OpcodeProps for UMAOpcode { } fn output_operands(&self, _version: ISAVersion) -> Vec { match self { - UMAOpcode::HeapWrite | UMAOpcode::AuxHeapWrite => vec![Operand::RegOnly], + UMAOpcode::HeapWrite | UMAOpcode::AuxHeapWrite | UMAOpcode::StaticMemoryWrite => { + vec![Operand::RegOnly] + } _ => vec![Operand::RegOnly, Operand::RegOnly], } } fn requires_kernel_mode(&self) -> bool { - false + match self { + UMAOpcode::StaticMemoryRead | UMAOpcode::StaticMemoryWrite => true, + _ => false, + } } fn can_be_used_in_static_context(&self) -> bool { true diff --git a/crates/zkevm_opcode_defs/src/definitions/versioned_hash/mod.rs b/crates/zkevm_opcode_defs/src/definitions/versioned_hash/mod.rs index e718826..8f45d43 100644 --- a/crates/zkevm_opcode_defs/src/definitions/versioned_hash/mod.rs +++ b/crates/zkevm_opcode_defs/src/definitions/versioned_hash/mod.rs @@ -1,3 +1,126 @@ +// We assume that all preimages are [u8; 32] and we just want to peek into them and get +// few main points +pub trait VersionedHashLen32: + Send + Sync + Sized + Clone + Copy + PartialEq + Eq + std::hash::Hash +{ + const VERSION_BYTE: u8; + fn is_valid(src: &[u8; VERSIONED_HASH_SIZE]) -> bool; + fn normalize_for_decommitment( + src: &[u8; VERSIONED_HASH_SIZE], + ) -> (VersionedHashHeader, VersionedHashNormalizedPreimage) { + let mut header = VersionedHashHeader::default(); + header.0.copy_from_slice(&src[0..4]); + let mut normalized_body = VersionedHashNormalizedPreimage::default(); + normalized_body.0.copy_from_slice(&src[4..]); + + (header, normalized_body) + } +} + +pub const VERSIONED_HASH_SIZE: usize = 32; +pub const VERSIONED_HASH_HEADER_SIZE: usize = 4; +pub const VERSIONED_HASH_NORMALIZED_PREIMAGE_SIZE: usize = 28; + +#[derive( + Clone, Copy, Debug, PartialEq, Eq, Default, Hash, serde::Serialize, serde::Deserialize, +)] +pub struct VersionedHashHeader(pub [u8; VERSIONED_HASH_HEADER_SIZE]); + +#[derive( + Clone, Copy, Debug, PartialEq, Eq, Default, Hash, serde::Serialize, serde::Deserialize, +)] +pub struct VersionedHashNormalizedPreimage(pub [u8; VERSIONED_HASH_NORMALIZED_PREIMAGE_SIZE]); + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub struct ContractCodeSha256Format; + +impl ContractCodeSha256Format { + pub const CODE_AT_REST_MARKER: u8 = 0; + pub const YET_CONSTRUCTED_MARKER: u8 = 1; + + pub fn code_length_in_bytes32_words(src: &[u8; VERSIONED_HASH_SIZE]) -> u16 { + u16::from_be_bytes([src[2], src[3]]) + } + + pub fn is_code_at_rest_if_valid(src: &[u8; VERSIONED_HASH_SIZE]) -> bool { + src[1] == Self::CODE_AT_REST_MARKER + } + + pub fn is_in_construction_if_valid(src: &[u8; VERSIONED_HASH_SIZE]) -> bool { + src[1] == Self::YET_CONSTRUCTED_MARKER + } +} + +impl VersionedHashLen32 for ContractCodeSha256Format { + const VERSION_BYTE: u8 = 0x01; + + fn is_valid(src: &[u8; VERSIONED_HASH_SIZE]) -> bool { + src[0] == Self::VERSION_BYTE + && (src[1] == Self::CODE_AT_REST_MARKER || src[1] == Self::YET_CONSTRUCTED_MARKER) + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub struct BlobSha256Format; + +impl BlobSha256Format { + pub const CODE_AT_REST_MARKER: u8 = 0; + pub const YET_CONSTRUCTED_MARKER: u8 = 1; + + pub fn preimage_length_in_bytes(src: &[u8; 32]) -> u16 { + u16::from_be_bytes([src[2], src[3]]) + } + + pub fn get_len_in_bytes32_words(src: &[u8; 32]) -> u16 { + let preimage_length_in_bytes = Self::preimage_length_in_bytes(src); + + let (mut len_in_words, rem) = + (preimage_length_in_bytes / 32, preimage_length_in_bytes % 32); + if rem != 0 { + len_in_words += 1; + } + if len_in_words & 1 != 1 { + len_in_words += 1; + } + + len_in_words + } + + pub fn normalize_and_get_len_in_bytes32_words( + src: &[u8; 32], + ) -> (VersionedHashNormalizedPreimage, u16) { + let preimage_length_in_bytes = Self::preimage_length_in_bytes(src); + + let (mut len_in_words, rem) = + (preimage_length_in_bytes / 32, preimage_length_in_bytes % 32); + if rem != 0 { + len_in_words += 1; + } + if len_in_words & 1 != 1 { + len_in_words += 1; + } + + (Self::normalize_for_decommitment(src).1, len_in_words) + } + + pub fn is_code_at_rest_if_valid(src: &[u8; VERSIONED_HASH_SIZE]) -> bool { + src[1] == Self::CODE_AT_REST_MARKER + } + + pub fn is_in_construction_if_valid(src: &[u8; VERSIONED_HASH_SIZE]) -> bool { + src[1] == Self::YET_CONSTRUCTED_MARKER + } +} + +impl VersionedHashLen32 for BlobSha256Format { + const VERSION_BYTE: u8 = 0x02; + + fn is_valid(src: &[u8; 32]) -> bool { + src[0] == Self::VERSION_BYTE + && (src[1] == Self::CODE_AT_REST_MARKER || src[1] == Self::YET_CONSTRUCTED_MARKER) + } +} + pub trait VersionedHashDef: Send + Sync + Sized + Clone + Copy + PartialEq + Eq + std::hash::Hash { @@ -46,6 +169,10 @@ impl VersionedHashGeneric { }, } } + + pub fn can_call(&self) -> bool { + self.data.extra_marker == ContractCodeSha256::CODE_AT_REST_MARKER + } } #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] @@ -101,3 +228,90 @@ impl VersionedHashDef for ContractCodeSha256 { }) } } + +impl VersionedHashGeneric { + pub fn from_digest_and_preimage_length(digest: [u8; 32], preimage_len: u16) -> Self { + let mut truncated_digest = [0u8; 28]; + truncated_digest.copy_from_slice(&digest[4..]); + + Self { + data: BlobSha256Storage { + preimage_length_in_bytes: preimage_len, + extra_marker: 0u8, + partial_hash: truncated_digest, + }, + } + } + + pub fn normalize_as_decommittable(&self) -> ([u8; 32], u16) { + let mut result = [0u8; 32]; + result[0] = ContractCodeSha256::VERSION_BYTE; + + let (mut len_in_words, rem) = ( + self.data.preimage_length_in_bytes / 32, + self.data.preimage_length_in_bytes % 32, + ); + if rem != 0 { + len_in_words += 1; + } + if len_in_words & 1 != 1 { + len_in_words += 1; + } + + let len_be = len_in_words.to_be_bytes(); + result[2] = len_be[0]; + result[3] = len_be[1]; + result[4..].copy_from_slice(&self.data.partial_hash); + + (result, len_in_words) + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub struct BlobSha256; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub struct BlobSha256Storage { + pub preimage_length_in_bytes: u16, + pub extra_marker: u8, + pub partial_hash: [u8; 28], +} + +impl VersionedHashDef for BlobSha256 { + const VERSION_BYTE: u8 = 0x02; + type StorageLayout = BlobSha256Storage; + fn serialize(storage: Self::StorageLayout) -> Option<[u8; 32]> { + let mut result = [0u8; 32]; + result[0] = Self::VERSION_BYTE; + result[1] = storage.extra_marker; + result[2..4].copy_from_slice(&storage.preimage_length_in_bytes.to_be_bytes()); + result[4..].copy_from_slice(&storage.partial_hash); + + Some(result) + } + fn serialize_to_stored(storage: Self::StorageLayout) -> Option<[u8; 32]> { + let mut result = [0u8; 32]; + result[0] = Self::VERSION_BYTE; + result[1] = 0; + result[2..4].copy_from_slice(&storage.preimage_length_in_bytes.to_be_bytes()); + result[4..].copy_from_slice(&storage.partial_hash); + + Some(result) + } + fn try_deserialize(input: [u8; 32]) -> Option { + if input[0] != Self::VERSION_BYTE { + return None; + } + + let extra_marker = input[1]; + + let preimage_length_in_bytes = u16::from_be_bytes([input[2], input[3]]); + let partial_hash: [u8; 28] = input[4..32].try_into().unwrap(); + + Some(Self::StorageLayout { + preimage_length_in_bytes, + extra_marker, + partial_hash, + }) + } +} diff --git a/crates/zkevm_opcode_defs/src/lib.rs b/crates/zkevm_opcode_defs/src/lib.rs index b09ce8a..9b2eab3 100644 --- a/crates/zkevm_opcode_defs/src/lib.rs +++ b/crates/zkevm_opcode_defs/src/lib.rs @@ -20,6 +20,7 @@ pub use bitflags; pub use blake2; pub use ethereum_types; pub use k256; +pub use p256; pub use sha2; pub use sha3; @@ -27,14 +28,7 @@ pub use self::definitions::*; pub use self::imm_mem_modifiers::*; pub use self::opcode::*; pub use self::utils::*; - -pub use self::system_params::{ - ADDRESS_ACCOUNT_CODE_STORAGE, ADDRESS_BOOTLOADER, ADDRESS_CONTRACT_DEPLOYER, ADDRESS_ECRECOVER, - ADDRESS_ETH_TOKEN, ADDRESS_EVENT_WRITER, ADDRESS_FORCE_DEPLOYER, ADDRESS_IDENTITY, - ADDRESS_IMMUTABLE_SIMULATOR, ADDRESS_KECCAK256, ADDRESS_KNOWN_CODES_STORAGE, - ADDRESS_L1_MESSENGER, ADDRESS_MSG_VALUE, ADDRESS_NONCE_HOLDER, ADDRESS_RIPEMD160, - ADDRESS_SHA256, ADDRESS_SYSTEM_CONTEXT, ADDRESS_UNRESTRICTED_SPACE, -}; +pub use self::system_params::*; use lazy_static::lazy_static; @@ -74,7 +68,7 @@ const WIDTH_MULTIPLE: usize = 16; pub const INITIAL_SP_ON_FAR_CALL: u64 = 0; pub const UNMAPPED_PAGE: u32 = 0; - +pub const STATIC_MEMORY_PAGE: u32 = 1; pub const BOOTLOADER_BASE_PAGE: u32 = 8; pub const BOOTLOADER_CODE_PAGE: u32 = BOOTLOADER_BASE_PAGE; pub const BOOTLOADER_CALLDATA_PAGE: u32 = BOOTLOADER_BASE_PAGE - 1; // some convention @@ -122,7 +116,9 @@ pub fn total_opcode_description_and_aux_bits_for_version(version: ISAVersion) -> total_description_bits_rounded_for_version(version) + TOTAL_AUX_BITS } -pub const DEFAULT_ISA_VERSION: ISAVersion = ISAVersion(1); +pub const DEFAULT_ISA_VERSION: ISAVersion = ISAVersion(2); + +pub const NUM_SYSTEM_CONTRACTS: usize = 1 << 16; lazy_static! { pub static ref OPCODES_TABLE: [OpcodeVariant; 1 << OPCODES_TABLE_WIDTH] = { @@ -225,6 +221,14 @@ lazy_static! { result.try_into().unwrap() }; + + pub static ref STIPENDS_AND_EXTRA_COSTS_TABLE: Box<[(u32, u32); NUM_SYSTEM_CONTRACTS]> = { + let mut default_table = Box::new([(0u32, 0u32); NUM_SYSTEM_CONTRACTS]); + use crate::system_params::MSG_VALUE_SIMULATOR_ADDITIVE_COST; + default_table[ADDRESS_MSG_VALUE as usize] = (0u32, MSG_VALUE_SIMULATOR_ADDITIVE_COST); + + default_table + }; } pub const INVALID_OPCODE_ERGS: u32 = u32::MAX; // will burn everything at once diff --git a/crates/zkevm_opcode_defs/src/system_params.rs b/crates/zkevm_opcode_defs/src/system_params.rs index 00dd00e..6319b93 100644 --- a/crates/zkevm_opcode_defs/src/system_params.rs +++ b/crates/zkevm_opcode_defs/src/system_params.rs @@ -1,10 +1,15 @@ -use crate::{circuit_prices::STORAGE_WRITE_HASHER_MIN_COST_IN_ERGS, CALL_LIKE_ERGS_COST}; +use crate::{ + circuit_prices::STORAGE_WRITE_HASHER_MIN_COST_IN_ERGS, CALL_LIKE_ERGS_COST, + ERGS_PER_CODE_WORD_DECOMMITTMENT, +}; use ethereum_types::Address; pub const MAX_TX_ERGS_LIMIT: u32 = 80_000_000; pub const VM_INITIAL_FRAME_ERGS: u32 = u32::MAX; +pub const EVM_SIMULATOR_STIPEND: u32 = 1u32 << 30; + /// How much a single circuit should cost in terms of ergs. pub const ERGS_PER_CIRCUIT: u32 = 80000; @@ -22,7 +27,9 @@ const SYSTEM_CONTRACTS_OFFSET_ADDRESS: u16 = 1 << 15; pub const KECCAK256_ROUND_FUNCTION_PRECOMPILE_ADDRESS: u16 = SYSTEM_CONTRACTS_OFFSET_ADDRESS + 0x10; pub const SHA256_ROUND_FUNCTION_PRECOMPILE_ADDRESS: u16 = 0x02; // as in Ethereum pub const ECRECOVER_INNER_FUNCTION_PRECOMPILE_ADDRESS: u16 = 0x01; // as in Ethereum +pub const SECP256R1_VERIFY_PRECOMPILE_ADDRESS: u16 = 0x100; // As in RIP7212: https://github.com/ethereum/RIPs/blob/master/RIPS/rip-7212.md +pub const MAX_PUBDATA_COST_PER_QUERY: i32 = 65; pub const INITIAL_STORAGE_WRITE_PUBDATA_BYTES: usize = 64; pub const REPEATED_STORAGE_WRITE_PUBDATA_BYTES: usize = 40; pub const L1_MESSAGE_PUBDATA_BYTES: u32 = 1 + 1 + 2 + 20 + 32 + 32; @@ -36,8 +43,7 @@ pub const STORAGE_AUX_BYTE: u8 = 0; pub const EVENT_AUX_BYTE: u8 = 1; pub const L1_MESSAGE_AUX_BYTE: u8 = 2; pub const PRECOMPILE_AUX_BYTE: u8 = 3; - -pub const NUM_SPONGES: usize = 4; +pub const TRANSIENT_STORAGE_AUX_BYTE: u8 = 4; use lazy_static::lazy_static; @@ -51,6 +57,12 @@ pub const ADDRESS_ECRECOVER: u16 = 0x0001; pub const ADDRESS_SHA256: u16 = 0x0002; pub const ADDRESS_RIPEMD160: u16 = 0x0003; pub const ADDRESS_IDENTITY: u16 = 0x0004; +pub const ADDRESS_MODEXP: u16 = 0x0005; +pub const ADDRESS_ECADD: u16 = 0x0006; +pub const ADDRESS_ECMUL: u16 = 0x0007; +pub const ADDRESS_ECPAIRING: u16 = 0x0008; +pub const ADDRESS_BLAKE2F: u16 = 0x0009; +pub const ADDRESS_POINT_EVALUATION: u16 = 0x000A; pub const ADDRESS_BOOTLOADER: u16 = 0x8001; pub const ADDRESS_ACCOUNT_CODE_STORAGE: u16 = 0x8002; @@ -66,21 +78,30 @@ pub const ADDRESS_SYSTEM_CONTEXT: u16 = 0x800B; pub const ADDRESS_BOOTLOADER_UTILITIES: u16 = 0x800C; pub const ADDRESS_EVENT_WRITER: u16 = 0x800D; pub const ADDRESS_KECCAK256: u16 = 0x8010; +pub const ADDRESS_CODE_ORACLE: u16 = 0x8011; pub const BOOTLOADER_MAX_MEMORY: u32 = u32::MAX; -pub const NEW_FRAME_MEMORY_STIPEND: u32 = 1u32 << 10; // 1 KB for new frames is "free" - -pub const MSG_VALUE_SIMULATOR_PUBDATA_BYTES_TO_PREPAY: u32 = 32 + 32 + 32 + 32; - -/// 128k * 4 / 32 -- the maximal realistic smart contract size. NOTE this constant should be updated once a new -/// packing method is introduced or more than 128k of data is allowed to be sent on L1. -pub const DECOMMITMENT_MSG_VALUE_SIMULATOR_OVERHEAD: u32 = 64000; +// 4 KB for new frames is "free" +pub const NEW_FRAME_MEMORY_STIPEND: u32 = 1u32 << 12; +// 2 MB for kernel frames, where we can be sure about the behavior. +// Note, that this number should high enough to allow any bytecode for `decommit` opcode. +pub const NEW_KERNEL_FRAME_MEMORY_STIPEND: u32 = 1u32 << 21; + +pub const INTERNAL_ERGS_TO_VISIBLE_ERGS_CONVERSION_CONSTANT: u32 = 1; + +/// `MsgValueSimulator` will automatically support decommitments to bytecodes of size up to 100k. +/// It will mean that if 0 gas was provided for the call, only `callee`s of size up to 100k could be called. +/// We supporting a larger value would lead to larger overhead for callers that do not provide 0 gas. +pub const MAX_AUTOMATICALLY_SUPPORTED_MSG_VALUE_BYTECODE: u32 = 100_000; +const _: () = assert!(MAX_AUTOMATICALLY_SUPPORTED_MSG_VALUE_BYTECODE % 32 == 0); +pub const DECOMMITMENT_MSG_VALUE_SIMULATOR_OVERHEAD: u32 = + ERGS_PER_CODE_WORD_DECOMMITTMENT * MAX_AUTOMATICALLY_SUPPORTED_MSG_VALUE_BYTECODE / 32; + +/// The amount of gas that is always retrived from the `caller` and passed to the `MsgValueSimulator` whenever it is called. +/// This value should be enough to cover the execution of the `MsgValueSimulator` itself and the decommitment of the callee's bytecode + pass at least 2300 gas. +/// This invariant is not easy to enforce within this crate, so `MsgValueSimulator` is expected to be well tested in the `era-contracts` repo. pub const MSG_VALUE_SIMULATOR_ADDITIVE_COST: u32 = - 11500 + DECOMMITMENT_MSG_VALUE_SIMULATOR_OVERHEAD; - -/// The minimum amount of ergs that should be spent by the user while using the MsgValueSimulator (even if -/// the user spends less funds, only the parent frame will receivet the refund) -pub const MSG_VALUE_SIMULATOR_MIN_USED_ERGS: u32 = 8000 + DECOMMITMENT_MSG_VALUE_SIMULATOR_OVERHEAD; + 14500 + DECOMMITMENT_MSG_VALUE_SIMULATOR_OVERHEAD; // std::cmp::max is not yet stabilized as const fn yet const fn max(a: u32, b: u32) -> u32 { @@ -92,12 +113,8 @@ const fn max(a: u32, b: u32) -> u32 { } /// The minimum price in ergs that a storage write should cost in order to protect Ethereum's `.transfer / .send` function against reentrancy. -/// The first part of the expression is the stipend given by the MsgValueSimulator to the callee frame. The second part of the expression -/// is the 2300 constant used for 0-value `transfer/send` calls + 1 to make sure that within the call it is not possible to store anything. -pub const MIN_STORAGE_WRITE_PRICE_FOR_REENTRANCY_PROTECTION: u32 = max( - MSG_VALUE_SIMULATOR_ADDITIVE_COST - MSG_VALUE_SIMULATOR_MIN_USED_ERGS + 1, - 2300 + 1, -); +/// It is a 2300 constant used for 0-value `transfer/send` calls + 1 to make sure that within the call it is not possible to store anything. +pub const MIN_STORAGE_WRITE_PRICE_FOR_REENTRANCY_PROTECTION: u32 = 2300 + 1; /// The minimal price in ergs the storage could cost to protect against reentrancy + take into account the usage of the single instance circuits. pub const MIN_STORAGE_WRITE_COST: u32 = max( @@ -105,6 +122,16 @@ pub const MIN_STORAGE_WRITE_COST: u32 = max( STORAGE_WRITE_HASHER_MIN_COST_IN_ERGS, ); +pub const STORAGE_ACCESS_COLD_READ_COST: u32 = 2000; +pub const STORAGE_ACCESS_COLD_WRITE_COST: u32 = max(MIN_STORAGE_WRITE_COST, 5500); + +pub const STORAGE_ACCESS_WARM_READ_COST: u32 = 30; +pub const STORAGE_ACCESS_WARM_WRITE_COST: u32 = 60; + +/// We currently ensure that that cost of each byte of pubdata computation-wise should be equal to at least 80 ergs. +/// This is needed to ensure that a call with bounded amount of gas could not published too much pubdata. +const _: () = assert!(STORAGE_ACCESS_COLD_WRITE_COST / (MAX_PUBDATA_COST_PER_QUERY as u32) >= 80); + lazy_static! { pub static ref BOOTLOADER_FORMAL_ADDRESS: Address = Address::from_low_u64_be(BOOTLOADER_FORMAL_ADDRESS_LOW as u64); @@ -114,10 +141,14 @@ lazy_static! { Address::from_low_u64_be(SYSTEM_CONTRACTS_OFFSET_ADDRESS as u64 + 0x03); pub static ref KNOWN_CODE_FACTORY_SYSTEM_CONTRACT_ADDRESS: Address = Address::from_low_u64_be(SYSTEM_CONTRACTS_OFFSET_ADDRESS as u64 + 0x04); + pub static ref CODE_ORACLE_ADDRESS: Address = + Address::from_low_u64_be(SYSTEM_CONTRACTS_OFFSET_ADDRESS as u64 + 0x12); pub static ref KECCAK256_ROUND_FUNCTION_PRECOMPILE_FORMAL_ADDRESS: Address = Address::from_low_u64_be(KECCAK256_ROUND_FUNCTION_PRECOMPILE_ADDRESS as u64); pub static ref SHA256_ROUND_FUNCTION_PRECOMPILE_FORMAL_ADDRESS: Address = Address::from_low_u64_be(SHA256_ROUND_FUNCTION_PRECOMPILE_ADDRESS as u64); pub static ref ECRECOVER_INNER_FUNCTION_PRECOMPILE_FORMAL_ADDRESS: Address = Address::from_low_u64_be(ECRECOVER_INNER_FUNCTION_PRECOMPILE_ADDRESS as u64); + pub static ref SECP256R1_VERIFY_INNER_FUNCTION_PRECOMPILE_FORMAL_ADDRESS: Address = + Address::from_low_u64_be(SECP256R1_VERIFY_PRECOMPILE_ADDRESS as u64); } diff --git a/crates/zkevm_test_harness/.github/ISSUE_TEMPLATE/bug_report.md b/crates/zkevm_test_harness/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..2d3e38a --- /dev/null +++ b/crates/zkevm_test_harness/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,39 @@ +--- +name: Bug report +about: Use this template for reporting issues +title: '' +labels: bug +assignees: '' +--- + +### 🐛 Bug Report + +#### 📝 Description + +Provide a clear and concise description of the bug. + +#### 🔄 Reproduction Steps + +Steps to reproduce the behaviour + +#### 🤔 Expected Behavior + +Describe what you expected to happen. + +#### 😯 Current Behavior + +Describe what actually happened. + +#### 🖥️ Environment + +Any relevant environment details. + +#### 📋 Additional Context + +Add any other context about the problem here. If applicable, add screenshots to help explain. + +#### 📎 Log Output + +``` +Paste any relevant log output here. +``` diff --git a/crates/zkevm_test_harness/.github/ISSUE_TEMPLATE/feature_request.md b/crates/zkevm_test_harness/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..d921e06 --- /dev/null +++ b/crates/zkevm_test_harness/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,21 @@ +--- +name: Feature request +about: Use this template for requesting features +title: '' +labels: feat +assignees: '' +--- + +### 🌟 Feature Request + +#### 📝 Description + +Provide a clear and concise description of the feature you'd like to see. + +#### 🤔 Rationale + +Explain why this feature is important and how it benefits the project. + +#### 📋 Additional Context + +Add any other context or information about the feature request here. diff --git a/crates/zkevm_test_harness/.github/pull_request_template.md b/crates/zkevm_test_harness/.github/pull_request_template.md new file mode 100644 index 0000000..8ce206c --- /dev/null +++ b/crates/zkevm_test_harness/.github/pull_request_template.md @@ -0,0 +1,20 @@ +# What ❔ + + + + + +## Why ❔ + + + + +## Checklist + + + + +- [ ] PR title corresponds to the body of PR (we generate changelog entries from PRs). +- [ ] Tests for the changes have been added / updated. +- [ ] Documentation comments have been added / updated. +- [ ] Code has been formatted via `zk fmt` and `zk lint`. diff --git a/crates/zkevm_test_harness/.github/workflows/.github/workflows/geometry-config-generator.yml b/crates/zkevm_test_harness/.github/workflows/.github/workflows/geometry-config-generator.yml new file mode 100644 index 0000000..0aca8fe --- /dev/null +++ b/crates/zkevm_test_harness/.github/workflows/.github/workflows/geometry-config-generator.yml @@ -0,0 +1,80 @@ +name: Geometry config generator + +permissions: + contents: write + pull-requests: write + +on: + workflow_dispatch: + inputs: + target_branch: + description: "Target branch to generate geometry config against" + type: string + required: true + default: "v1.4.0" + push: + branches: + - add-geometry-config-generator-workflow + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + estimate-circuit-limit: + runs-on: [ ubuntu-latest ] + strategy: + matrix: + key: [ 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 ] + steps: + - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3 + - name: Setup Rust + run: | + curl https://sh.rustup.rs -sSf | bash -s -- -y + source "$HOME/.cargo/env" + sudo apt update && sudo apt install clang openssl libssl-dev gcc g++ pkg-config build-essential libclang-dev -y + - name: Estimate circuit limit + run: | + source "$HOME/.cargo/env" + cargo run --release --bin circuit_limit_estimator -- --numeric-circuit ${{ matrix.key }} + - uses: actions/upload-artifact@83fd05a356d7e2593de66fc9913b3002723633cb # v3 + with: + path: ./circuit_limit_${{ matrix.key }}.txt + + create-pr: + runs-on: [ ubuntu-latest ] + needs: [ "estimate-circuit-limit" ] + steps: + - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3 + - uses: actions/download-artifact@9782bd6a9848b53b110e712e20e42d89988822b7 # v3 + with: + path: ./ + - name: Rename downloaded path + run: | + mv artifact/* ./ + - name: Setup Rust + run: | + curl https://sh.rustup.rs -sSf | bash -s -- -y + source "$HOME/.cargo/env" + sudo apt update && sudo apt install clang openssl libssl-dev gcc g++ pkg-config build-essential libclang-dev -y + - name: Generate commitment + run: | + source "$HOME/.cargo/env" + cargo run --release --bin geometry_config_generator -- --code-decommitter $(cat circuit_limit_5.txt) --code-decommitter-sorter $(cat circuit_limit_4.txt) --ecrecover $(cat circuit_limit_9.txt) --events-or-l1-messages-sorter $(cat circuit_limit_15.txt) --initial-writes $(cat circuit_limit_13.txt) --keccak256 $(cat circuit_limit_7.txt) --log-demuxer $(cat circuit_limit_6.txt) --ram-permutation $(cat circuit_limit_10.txt) --repeated-writes $(cat circuit_limit_14.txt) --sha256 $(cat circuit_limit_8.txt) --storage-application $(cat circuit_limit_12.txt) --storage-sorter $(cat circuit_limit_11.txt) --vm-snapshot $(cat circuit_limit_3.txt) --l1-messages-merklizer $(cat circuit_limit_18.txt) --l1-messages-pudata-hasher $(cat circuit_limit_17.txt) + rm -rf circuit_limit_* + - name: Create Pull Request + id: cpr + uses: peter-evans/create-pull-request@d7db273d6c7206ba99224e659c982ae34a1025e3 # v4 + with: + base: ${{ github.event.inputs.target_branch }} + commit-message: update generated geometry config + committer: zksync-admin-bot2 + author: zksync-admin-bot2 + signoff: false + branch: update-geometry-config + branch-suffix: short-commit-hash + delete-branch: true + title: Update geometry config from branch ${{ github.event.inputs.target_branch }} + body: | + Update generated geometry config from branch ${{ github.event.inputs.target_branch }} + draft: false diff --git a/crates/zkevm_test_harness/.github/workflows/cargo-license.yaml b/crates/zkevm_test_harness/.github/workflows/cargo-license.yaml new file mode 100644 index 0000000..189b471 --- /dev/null +++ b/crates/zkevm_test_harness/.github/workflows/cargo-license.yaml @@ -0,0 +1,8 @@ +name: Cargo license check +on: pull_request +jobs: + cargo-deny: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: EmbarkStudios/cargo-deny-action@v1 diff --git a/crates/zkevm_test_harness/.github/workflows/ci.yaml b/crates/zkevm_test_harness/.github/workflows/ci.yaml new file mode 100644 index 0000000..5a5d15e --- /dev/null +++ b/crates/zkevm_test_harness/.github/workflows/ci.yaml @@ -0,0 +1,68 @@ +name: "Rust CI" +on: + pull_request: + +jobs: + build: + name: cargo build + runs-on: [ubuntu-22.04-github-hosted-32core] + steps: + - uses: actions/checkout@v3 + - uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + rustflags: "" + - name: Setup rust + run: | + rustup set profile minimal + rustup toolchain install nightly-2023-08-23 + rustup default nightly-2023-08-23 + cargo install cargo-nextest + - name: Compile main + run: cargo build --verbose + - name: Compile encodings + run: cargo build --manifest-path circuit_encodings/Cargo.toml --verbose + - name: compile api + run: cargo build --manifest-path circuit_sequencer_api/Cargo.toml --verbose + - name: compile definitions + run: cargo build --manifest-path circuit_definitions/Cargo.toml --verbose + - name: Compile kzg + run: cargo build --manifest-path kzg/Cargo.toml --verbose + + + + test: + name: cargo test + runs-on: [ubuntu-22.04-github-hosted-32core] + needs: build + steps: + - uses: actions/checkout@v3 + - uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + rustflags: "" + - name: Setup rust + run: | + rustup set profile minimal + rustup toolchain install nightly-2023-08-23 + rustup default nightly-2023-08-23 + cargo install cargo-nextest + - name: Main test + run: cargo nextest run --release --test-threads 2 + - name: Encodings test + run: cargo nextest run --release --manifest-path circuit_encodings/Cargo.toml + - name: Api tests + run: cargo nextest run --release --manifest-path circuit_sequencer_api/Cargo.toml + - name: Definitions test + run: cargo nextest run --release --manifest-path circuit_definitions/Cargo.toml + - name: Kzg tests + run: cargo nextest run --release --manifest-path kzg/Cargo.toml + + formatting: + name: cargo fmt + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + components: rustfmt + - name: Rustfmt Check + uses: actions-rust-lang/rustfmt@v1 diff --git a/crates/zkevm_test_harness/.github/workflows/secrets_scanner.yaml b/crates/zkevm_test_harness/.github/workflows/secrets_scanner.yaml new file mode 100644 index 0000000..54054cf --- /dev/null +++ b/crates/zkevm_test_harness/.github/workflows/secrets_scanner.yaml @@ -0,0 +1,17 @@ +name: Leaked Secrets Scan +on: [pull_request] +jobs: + TruffleHog: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # v3 + with: + fetch-depth: 0 + - name: TruffleHog OSS + uses: trufflesecurity/trufflehog@0c66d30c1f4075cee1aada2e1ab46dabb1b0071a + with: + path: ./ + base: ${{ github.event.repository.default_branch }} + head: HEAD + extra_args: --debug --only-verified diff --git a/crates/zkevm_test_harness/.gitignore b/crates/zkevm_test_harness/.gitignore new file mode 100644 index 0000000..0cd54f4 --- /dev/null +++ b/crates/zkevm_test_harness/.gitignore @@ -0,0 +1,10 @@ +/target +Cargo.lock +setup_2^26.key +.idea +.DS_Store + +# don't include the results of the testing (as they are 100M) +test_proofs/base_layer +test_proofs/recursion_layer + diff --git a/crates/zkevm_test_harness/CONTRIBUTING.md b/crates/zkevm_test_harness/CONTRIBUTING.md new file mode 100644 index 0000000..31a36aa --- /dev/null +++ b/crates/zkevm_test_harness/CONTRIBUTING.md @@ -0,0 +1,10 @@ +# Contribution Guidelines + +Thank you for considering helping out with the source code! We are extremely grateful for any consideration of +contributions to this repository. However, at this time, we generally do not accept external contributions. This policy +will change in the future, so please check back regularly for updates. + +For security issues, please contact us at [security@matterlabs.dev](mailto:security@matterlabs.dev). + +Thank you for your support in accelerating the mass adoption of crypto for personal sovereignty! + diff --git a/crates/zkevm_test_harness/Cargo.toml b/crates/zkevm_test_harness/Cargo.toml new file mode 100644 index 0000000..9d467d4 --- /dev/null +++ b/crates/zkevm_test_harness/Cargo.toml @@ -0,0 +1,65 @@ +[package] +name = "zkevm_test_harness" +version = "0.150.2" +edition = "2021" +authors = ["Alex Vlasov ", "Konstantin Panarin "] +homepage = "https://zksync.io/" +repository = "https://github.com/matter-labs/era-zkevm_test_harness/" +license = "MIT OR Apache-2.0" +keywords = ["blockchain", "zksync"] +categories = ["cryptography"] +description = "ZKsync Era proving utilities" + +resolver = "2" + +# [[bin]] +# name = "circuit_limit_estimator" +# path = "src/circuit_limit_estimator/main.rs" + +# [[bin]] +# name = "circuit_synthesis_performance_test" +# path = "src/circuit_synthesis_performance_test/main.rs" + +[[bin]] +name = "geometry_config_generator" +path = "src/geometry_config_generator/main.rs" + +[dependencies] +circuit_definitions = { version = "=0.150.2", path = "../circuit_definitions"} +circuit_sequencer_api = { version = "=0.150.2", path = "../circuit_sequencer_api"} +kzg = { package = "zksync_kzg", version = "=0.150.2", path = "../kzg"} + +zkevm-assembly = { version = "=0.150.0", path = "../zkEVM-assembly" } + +rand = "0.4" +rayon = "1.10" +derivative = "2.2" +hex = "0.4" +serde = {version = "1", features = ["derive"]} +serde_json = "1.0" +crossbeam = "0.8" +tracing = { version= "0.1.26" } +bincode = "1.3" +test-log = "0.2" +env_logger = "0.9" +smallvec = "1.13" +structopt = "0.3.26" +codegen = "0.2.0" +regex = { version = "1.10.6", features = ["pattern"] } + +[dev-dependencies] +rand = "0.4" +indicatif = "0.16" + +[profile.release] +debug = false +lto = false + +[profile.bench] +debug = false + +[features] +verbose_circuits = ["circuit_definitions/verbose_circuits", "circuit_sequencer_api/verbose_circuits"] +log_tracing = ["circuit_definitions/log_tracing"] + +default = ["log_tracing"] diff --git a/crates/zkevm_test_harness/LICENSE-APACHE b/crates/zkevm_test_harness/LICENSE-APACHE new file mode 100644 index 0000000..66a27ec --- /dev/null +++ b/crates/zkevm_test_harness/LICENSE-APACHE @@ -0,0 +1,177 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + diff --git a/crates/zkevm_test_harness/LICENSE-MIT b/crates/zkevm_test_harness/LICENSE-MIT new file mode 100644 index 0000000..6035caf --- /dev/null +++ b/crates/zkevm_test_harness/LICENSE-MIT @@ -0,0 +1,22 @@ +MIT License + +Copyright (c) 2023 Matter Labs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/crates/zkevm_test_harness/README.md b/crates/zkevm_test_harness/README.md new file mode 100644 index 0000000..17464db --- /dev/null +++ b/crates/zkevm_test_harness/README.md @@ -0,0 +1,67 @@ +# zkSync Era: A ZK Rollup For Scaling Ethereum + +[![Logo](eraLogo.png)](https://zksync.io/) + +zkSync Era is a layer 2 rollup that uses zero-knowledge proofs to scale Ethereum without compromising on security or +decentralization. Since it's EVM compatible (Solidity/Vyper), 99% of Ethereum projects can redeploy without refactoring +or re-auditing a single line of code. zkSync Era also uses an LLVM-based compiler that will eventually let developers +write smart contracts in C++, Rust and other popular languages. + +# How to use + +This repo contains a mixture of witness generation harness (that runs block's code and produces circuit-specific witness parts) and basic examples of full block proof workflow execution, that is: +- create a necessary number of circuits of each unique basic type (so called scheduling) +- aggreagte proofs over them +- run the final state "scheduler" circuit that verifies logical validity of scheduling (feeding outputs to inputs) and attest that aggregation is a result of recursive verification of the scheduled sequence + +It's easy to run + +Get some modern Rust version (at least that supports Rust 2021 and const generics, but usually latest nightly is also a good option) and run + +``` +cargo test basic_test --release -- --nocapture +``` + +It may be a little verbose, but it's a full end to end test that: +- sets up basic environment - empty state tree with added "system" level contracts +- creates some dummy information about previous state of the chain (only state root is necessary) +- runs a contract from [https://github.com/vladbochok/test-contract](https://github.com/vladbochok/test-contract) as from address 0x8001 that is a contract call without a calldata and particular meaning, but touches the most interesting parts of the system: external calls, reverts, precompiles, storage access, events, L2 to L1 messages +- produces witness +- makes as many circuits as needed given some (arbitrary) set of capacity parameters of the form "principal operations per circuit of type T" +- generated verification keys for both basic circuits, recursive aggregation circuits, and "scheduler" +- makes proofs of every stage - basic circuits -> aggregation (leafs and nodes) -> scheduler +- each proof is verified against the corresponding verification key on creation + +One can see a lot of `.json` files in the `setup` and `test_proofs` folders. Those are all the intermediate proofs, and if proof exists then example script will skip it's recomputation (whether it's a proof or verification key). So to run the full workflow one can remove all of those, or some of those. + +### Running regeneration of setup files +Will regenerate setup parameters (geometry, verification keys, finalization hints and padding proofs) +```shell +cargo run --release --bin geometry_config_generator +cargo test --release test_run_create_base_layer_vks_and_proofs +cargo test --release test_run_create_recursion_layer_vks_and_proofs +``` + +## License + +zkSync Era is distributed under the terms of either + +- Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or ) +- MIT license ([LICENSE-MIT](LICENSE-MIT) or ) + +at your option. + +## Official Links + +- [Website](https://zksync.io/) +- [GitHub](https://github.com/matter-labs) +- [Twitter](https://twitter.com/zksync) +- [Twitter for Devs](https://twitter.com/zkSyncDevs) +- [Discord](https://join.zksync.dev) + +## Disclaimer + +zkSync Era has been through lots of testing and audits. Although it is live, it is still in alpha state and will go +through more audits and bug bounties programs. We would love to hear our community's thoughts and suggestions about it! +It is important to state that forking it now can potentially lead to missing important security updates, critical +features, and performance improvements. diff --git a/crates/zkevm_test_harness/SECURITY.md b/crates/zkevm_test_harness/SECURITY.md new file mode 100644 index 0000000..2f2871c --- /dev/null +++ b/crates/zkevm_test_harness/SECURITY.md @@ -0,0 +1,74 @@ +# Security Policy + +We truly appreciate efforts to discover and disclose security issues responsibly! + +## Vulnerabilities + +If you'd like to report a security issue in the repositories of matter-labs organization, please proceed to our +[Bug Bounty Program on Immunefi](https://era.zksync.io/docs/reference/troubleshooting/audit-bug-bounty.html#bug-bounty-program). + +## Other Security Issues + +We take an impact-first approach instead of a rules-first approach. Therefore, if you believe you found the impactful +issue but can't report it via the Bug Bounty, please email us at +[security@matterlabs.dev](mailto:security@matterlabs.dev). + +### PGP Key + +The following PGP key may be used to communicate sensitive information to developers: + +Fingerprint: `5FED B2D0 EA2C 4906 DD66 71D7 A2C5 0B40 CE3C F297` + +``` +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +=xkM3 +-----END PGP PUBLIC KEY BLOCK----- +``` diff --git a/crates/zkevm_test_harness/config.json b/crates/zkevm_test_harness/config.json new file mode 100644 index 0000000..e212d00 --- /dev/null +++ b/crates/zkevm_test_harness/config.json @@ -0,0 +1,14 @@ +{ + "cycles_per_vm_snapshot": 5713, + "cycles_per_log_demuxer": 58750, + "cycles_per_storage_sorter": 44687, + "cycles_per_events_or_l1_messages_sorter": 31287, + "cycles_per_ram_permutation": 136714, + "cycles_code_decommitter_sorter": 117500, + "cycles_per_code_decommitter": 2845, + "cycles_per_storage_application": 33, + "cycles_per_keccak256_circuit": 672, + "cycles_per_sha256_circuit": 2206, + "cycles_per_ecrecover_circuit": 2, + "limit_for_l1_messages_pudata_hasher": 774 +} \ No newline at end of file diff --git a/crates/zkevm_test_harness/deny.toml b/crates/zkevm_test_harness/deny.toml new file mode 100644 index 0000000..6977d43 --- /dev/null +++ b/crates/zkevm_test_harness/deny.toml @@ -0,0 +1,79 @@ +all-features = false +no-default-features = false + +[advisories] +vulnerability = "deny" +unmaintained = "warn" +yanked = "warn" +notice = "warn" +ignore = [ + #"RUSTSEC-0000-0000", +] + +[licenses] +unlicensed = "deny" +allow = [ + #"Apache-2.0 WITH LLVM-exception", + "MIT", + "Apache-2.0", + "ISC", + "Unlicense", + "MPL-2.0", + "Unicode-DFS-2016", + "CC0-1.0", + "BSD-2-Clause", + "BSD-3-Clause", + "Zlib", +] +deny = [ + #"Nokia", +] +copyleft = "warn" +allow-osi-fsf-free = "neither" +default = "deny" +confidence-threshold = 0.8 +exceptions = [ + # Each entry is the crate and version constraint, and its specific allow + # list + #{ allow = ["Zlib"], name = "adler32", version = "*" }, +] + +unused-allowed-license = "allow" + +[licenses.private] +ignore = false +registries = [ + #"https://sekretz.com/registry +] + +[bans] +multiple-versions = "warn" +wildcards = "allow" +highlight = "all" +workspace-default-features = "allow" +external-default-features = "allow" +allow = [ + #{ name = "ansi_term", version = "=0.11.0" }, +] +# List of crates to deny +deny = [ + # Each entry the name of a crate and a version range. If version is + # not specified, all versions will be matched. + #{ name = "ansi_term", version = "=0.11.0" }, +] + +skip = [ + #{ name = "ansi_term", version = "=0.11.0" }, +] +skip-tree = [ + #{ name = "ansi_term", version = "=0.11.0", depth = 20 }, +] + +[sources] +unknown-registry = "deny" +unknown-git = "allow" +allow-registry = ["https://github.com/rust-lang/crates.io-index"] +allow-git = [] + +[sources.allow-org] +#github = ["matter-labs"] diff --git a/crates/zkevm_test_harness/eraLogo.png b/crates/zkevm_test_harness/eraLogo.png new file mode 100644 index 0000000000000000000000000000000000000000..5d9480d8f05342a06cd1ee03405137552bdbebbf GIT binary patch literal 79091 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, + F: Fn(usize) -> SF::Config, +>( + geometry: CSGeometry, + max_trace_len_log_2: usize, + start_hint: Option, + config_fn: F, +) -> usize +where + SF: Send + 'static, + SF::Config: Send + 'static, +{ + println!( + "Will try to estimate capacity for {}", + std::any::type_name::() + ); + let start_size = start_hint.unwrap_or(1024); + + // kind-of binary search + + let mut size: usize = 1; + let mut next_size = start_size; + + loop { + // we just try to make one + println!( + "Trying size {} for circuit {}", + next_size, + std::any::type_name::() + ); + + if size == next_size { + break; + } + + let config = (config_fn)(next_size); + + let join_result = std::thread::spawn(move || { + use crate::boojum::config::SetupCSConfig; + use crate::boojum::cs::cs_builder::new_builder; + use crate::boojum::cs::cs_builder_reference::CsReferenceImplementationBuilder; + + type P = GoldilocksField; + + let builder_impl = + CsReferenceImplementationBuilder::::new( + geometry, + 1 << max_trace_len_log_2, + ); + let builder = new_builder::<_, GoldilocksField>(builder_impl); + + let witness = SF::Witness::default(); + let round_function = ZkSyncDefaultRoundFunction::default(); + let config = config; + + let builder = SF::configure_builder(builder); + let mut cs = builder.build(1); // formal resolver + SF::add_tables(&mut cs); + let _ = SF::synthesize_into_cs_inner(&mut cs, witness, &round_function, config); + let (max_trace_len, _) = cs.pad_and_shrink(); + let cs = cs.into_assembly::(); + + cs.print_gate_stats(); + + max_trace_len + }) + .join(); + + match join_result { + Ok(max_trace_len) => { + println!("Size {} requires {} rows", next_size, max_trace_len); + if max_trace_len <= (1 << (max_trace_len_log_2 - 1)) { + size = next_size; + next_size *= 2; + } else { + if (next_size - size) < 1 { + break; + } + + if size + 1 == next_size { + // small step + size = next_size; + next_size += 1; + continue; + } + + if ((next_size - size) as f64) / (size as f64) < 0.03 { + size = next_size; + break; + } + + let mut next_size_binsearch = (next_size - size) / 2 + next_size; + if next_size_binsearch == next_size { + next_size_binsearch += 1; + } + size = next_size; + next_size = next_size_binsearch; + } + } + Err(_e) => { + if next_size == start_size { + panic!("Initial search point is too large"); + } + if next_size == size + 1 { + break; + } + // println!("Error in synthesis occured"); + let next_size_binsearch = (next_size - size) / 2 + size; + if next_size_binsearch == size { + break; + } + next_size = next_size_binsearch; + } + } + } + + println!( + "{} has capacity of {} cycles", + std::any::type_name::(), + size + ); + + size +} + +pub fn main_vm_capacity() -> usize { + type SF = VmMainInstanceSynthesisFunction; + + compute_size_inner::(SF::geometry(), 20, Some(5000), |x: usize| x) +} + +pub fn code_decommittments_sorter_capacity() -> usize { + type SF = CodeDecommittmentsSorterSynthesisFunction; + + compute_size_inner::(SF::geometry(), 20, Some(40000), |x: usize| x) +} + +pub fn code_decommitter_capacity() -> usize { + type SF = CodeDecommitterInstanceSynthesisFunction; + + compute_size_inner::(SF::geometry(), 20, Some(2048), |x: usize| x) +} + +pub fn log_demuxer_capacity() -> usize { + type SF = LogDemuxInstanceSynthesisFunction; + + compute_size_inner::(SF::geometry(), 20, Some(20000), |x: usize| x) +} + +pub fn keccak256_rf_capacity() -> usize { + type SF = Keccak256RoundFunctionInstanceSynthesisFunction; + + compute_size_inner::(SF::geometry(), 20, Some(100), |x: usize| x) +} + +pub fn sha256_rf_capacity() -> usize { + type SF = Sha256RoundFunctionInstanceSynthesisFunction; + + compute_size_inner::(SF::geometry(), 20, Some(2048), |x: usize| x) +} + +pub fn ecrecover_capacity() -> usize { + type SF = ECRecoverFunctionInstanceSynthesisFunction; + + compute_size_inner::(SF::geometry(), 20, Some(2), |x: usize| x) +} + +pub fn ram_permutation_capacity() -> usize { + type SF = RAMPermutationInstanceSynthesisFunction; + + compute_size_inner::(SF::geometry(), 20, Some(70000), |x: usize| x) +} + +pub fn event_sorter_capacity() -> usize { + type SF = EventsAndL1MessagesSortAndDedupInstanceSynthesisFunction; + + compute_size_inner::(SF::geometry(), 20, Some(20000), |x: usize| x) +} + +pub fn storage_sorter_capacity() -> usize { + type SF = StorageSortAndDedupInstanceSynthesisFunction; + + compute_size_inner::(SF::geometry(), 20, Some(22000), |x: usize| x) +} + +pub fn storage_application_capacity() -> usize { + type SF = StorageApplicationInstanceSynthesisFunction; + + compute_size_inner::(SF::geometry(), 20, Some(32), |x: usize| x) +} + +pub fn l1_messages_hasher_capacity() -> usize { + type SF = LinearHasherInstanceSynthesisFunction; + + compute_size_inner::(SF::geometry(), 20, Some(512), |x: usize| x) +} + +pub fn transient_storage_sorter_capacity() -> usize { + type SF = TransientStorageSortAndDedupInstanceSynthesisFunction; + + compute_size_inner::(SF::geometry(), 20, Some(22000), |x: usize| x) +} + +pub fn secp256r1_verify_capacity() -> usize { + type SF = Secp256r1VerifyFunctionInstanceSynthesisFunction; + + compute_size_inner::(SF::geometry(), 20, Some(2), |x: usize| x) +} + +#[cfg(test)] +mod test { + use super::*; + + #[ignore = "too slow"] + #[test_log::test] + fn test_size_estimation() { + println!("Size of main_vm_capacity: {}", main_vm_capacity()); + println!( + "Size of code_decommittments_sorter_capacity: {}", + code_decommittments_sorter_capacity() + ); + println!( + "Size of code_decommitter_capacity: {}", + code_decommitter_capacity() + ); + println!("Size of log_demuxer_capacity: {}", log_demuxer_capacity()); + println!("Size of keccak256_rf_capacity: {}", keccak256_rf_capacity()); + println!("Size of sha256_rf_capacity: {}", sha256_rf_capacity()); + println!("Size of ecrecover_capacity: {}", ecrecover_capacity()); + println!( + "Size of ram_permutation_capacity: {}", + ram_permutation_capacity() + ); + println!("Size of event_sorter_capacity: {}", event_sorter_capacity()); + println!( + "Size of storage_sorter_capacity: {}", + storage_sorter_capacity() + ); + println!( + "Size of storage_application_capacity: {}", + storage_application_capacity() + ); + println!( + "Size of l1_messages_hasher_capacity: {}", + l1_messages_hasher_capacity() + ); + println!( + "Size of transient_storage_sorter_capacity: {}", + transient_storage_sorter_capacity() + ); + println!( + "Size of secp256r1_verify_capacity: {}", + secp256r1_verify_capacity() + ); + } +} diff --git a/crates/zkevm_test_harness/src/circuit_limit_estimator/main.rs b/crates/zkevm_test_harness/src/circuit_limit_estimator/main.rs new file mode 100644 index 0000000..37e5f2e --- /dev/null +++ b/crates/zkevm_test_harness/src/circuit_limit_estimator/main.rs @@ -0,0 +1,31 @@ +use std::fs::File; +use std::io::Write; + +use structopt::StructOpt; +use zkevm_test_harness::circuit_limit_estimator::get_circuit_capacity; + +#[derive(Debug, StructOpt)] +#[structopt( +name = "Estimate limit for individual circuit", +about = "Tool for estimating individual circuit limit" +)] +struct Opt { + /// Numeric circuit type valid value from [3-17]. + #[structopt(long)] + numeric_circuit: u8, +} + +fn save_circuit_limit(limit: usize, filepath: String) { + let mut f = File::create(filepath) + .expect("Unable to create file"); + f.write_all(limit.to_string().as_bytes()) + .expect("Unable to write data"); +} + +fn main() { + let opt = Opt::from_args(); + println!("Estimating circuit limit for circuit {}", opt.numeric_circuit); + let circuit_limit = get_circuit_capacity(opt.numeric_circuit); + save_circuit_limit(circuit_limit, format!("circuit_limit_{}.txt", opt.numeric_circuit)); + println!("Estimated circuit limit is {} for circuit {}", circuit_limit, opt.numeric_circuit); +} diff --git a/crates/zkevm_test_harness/src/circuit_limit_estimator/mod.rs b/crates/zkevm_test_harness/src/circuit_limit_estimator/mod.rs new file mode 100644 index 0000000..0fbdc0b --- /dev/null +++ b/crates/zkevm_test_harness/src/circuit_limit_estimator/mod.rs @@ -0,0 +1,200 @@ +use std::panic; + +use crate::abstract_zksync_circuit::{ZkSyncUniformCircuitInstance, ZkSyncUniformSynthesisFunction}; +use crate::abstract_zksync_circuit::concrete_circuits::{CodeDecommitterInstanceSynthesisFunction, CodeDecommittmentsSorterSynthesisFunction, ECRecoverFunctionInstanceSynthesisFunction, EventsAndL1MessagesSortAndDedupInstanceSynthesisFunction, Keccak256RoundFunctionInstanceSynthesisFunction, L1MessagesRehasherInstanceSynthesisFunction, LogDemuxInstanceSynthesisFunction, MessagesMerklizerInstanceSynthesisFunction, RAMPermutationInstanceSynthesisFunction, Sha256RoundFunctionInstanceSynthesisFunction, StorageApplicationInstanceSynthesisFunction, StorageInitialWritesRehasherInstanceSynthesisFunction, StorageRepeatedWritesRehasherInstanceSynthesisFunction, StorageSortAndDedupInstanceSynthesisFunction, VmMainInstanceSynthesisFunction}; +use crate::bellman::bn256::Bn256; +use crate::bellman::plonk::better_better_cs::cs::{PlonkCsWidth4WithNextStepAndCustomGatesParams, SetupAssembly}; +use crate::bellman::plonk::better_better_cs::cs::Circuit; +use crate::sync_vm::franklin_crypto::bellman::plonk::better_better_cs::gates::selector_optimized_with_d_next::SelectorOptimizedWidth4MainGateWithDNext; +use crate::sync_vm::rescue_poseidon::RescueParams; +use crate::sync_vm::testing::create_test_artifacts_with_optimized_gate; +use crate::sync_vm::traits::GenericHasher; +use crate::witness::oracle::VmWitnessOracle; +use crate::witness::postprocessing::{L1_MESSAGES_MERKLIZER_OUTPUT_LINEAR_HASH, USE_BLAKE2S_EXTRA_TABLES}; + +fn ensure_cycle_within_2_26_limit(cycles: usize, gates: usize, additive: usize) -> usize { + let two_power_26: usize = 1 << 26; + if (cycles * gates + additive) < two_power_26 { + println!("cycles*gates+additive : {}", cycles * gates + additive); + return cycles; + } + println!("two_power_26 - additive / gates: {}", (two_power_26 - additive) / gates); + (two_power_26 - additive) / gates +} + +fn compute_inner< + SF: ZkSyncUniformSynthesisFunction, 2, 3>>, + F: Fn(usize) -> SF::Config +>( + config_fn: F, + optional_circuit_limit_generation_mode_fn: Option usize>, +) -> usize { + let max = 1 << 26; + + let typical_sizes = vec![16, 32]; + let mut gates = vec![]; + + for size in typical_sizes.iter().cloned() { + let (_, round_function, _) = create_test_artifacts_with_optimized_gate(); + + let mut setup_assembly = SetupAssembly::< + _, + PlonkCsWidth4WithNextStepAndCustomGatesParams, + SelectorOptimizedWidth4MainGateWithDNext + >::new(); + + let config = config_fn(size); + + let circuit = ZkSyncUniformCircuitInstance::<_, SF>::new( + None, + config, + round_function.clone(), + None, + ); + + circuit.synthesize(&mut setup_assembly).unwrap(); + + let n = setup_assembly.n(); + gates.push(n); + } + + // linear approximation + + let mut per_round_gates = (gates[1] - gates[0]) / (typical_sizes[1] - typical_sizes[0]); + + if (gates[1] - gates[0]) % (typical_sizes[1] - typical_sizes[0]) != 0 { + println!("non-linear!"); + per_round_gates += 1; + } + + println!("Single cycle takes {} gates", per_round_gates); + + let additive = gates[1] - per_round_gates * typical_sizes[1]; + + println!("O(1) costs = {}", additive); + + let mut cycles = (max - additive) / per_round_gates; + cycles = ensure_cycle_within_2_26_limit(cycles, per_round_gates + 2, additive); + match optional_circuit_limit_generation_mode_fn { + None => {} + Some(circuit_limit_generation_mode_fn) => { + cycles = circuit_limit_generation_mode_fn(cycles); + } + } + println!("Can fit {} cycles for circuit type {}", cycles, SF::description()); + + let (_, round_function, _) = create_test_artifacts_with_optimized_gate(); + + let mut setup_assembly = SetupAssembly::< + _, + PlonkCsWidth4WithNextStepAndCustomGatesParams, + SelectorOptimizedWidth4MainGateWithDNext + >::new(); + + let config = config_fn(cycles); + + let circuit = ZkSyncUniformCircuitInstance::<_, SF>::new( + None, + config, + round_function.clone(), + None, + ); + + println!("Synthesising largest size"); + circuit.synthesize(&mut setup_assembly).unwrap(); + println!("Finaizing largest size"); + setup_assembly.finalize(); + cycles +} + +pub fn get_circuit_capacity(circuit_type: u8) -> usize { + match circuit_type { + 3 => compute_inner::>, _>( + |x: usize| { + x + }, None, + ), + 4 => compute_inner::( + |x: usize| { + x + }, + None, + ), + 5 => compute_inner::( + |x: usize| { + x + }, + None, + ), + 6 => compute_inner::( + |x: usize| { + x + }, + None, + ), + 7 => compute_inner::( + |x: usize| { + x + }, + None, + ), + 8 => compute_inner::( + |x: usize| { + x + }, + None, + ), + 9 => compute_inner::( + |x: usize| { + x + }, + None, + ), + 10 => compute_inner::( + |x: usize| { + x + }, + None, + ), + 11 => compute_inner::( + |x: usize| { + x + }, + None, + ), + 12 => compute_inner::( + |x: usize| { + (x, USE_BLAKE2S_EXTRA_TABLES) + }, + None, + ), + 13 => compute_inner::( + |x: usize| { + x + }, + None, + ), + 14 => compute_inner::( + |x: usize| { + x + }, + None, + ), + 15 | 16 => compute_inner::( + |x: usize| { + x + }, + None, + ), + // L1MessagesRehasherInstanceSynthesisFunction + 17 | 18 => compute_inner::( + |x: usize| { + (x, L1_MESSAGES_MERKLIZER_OUTPUT_LINEAR_HASH) + }, + // Round down cycles to power of 2 as L1 message merklizer circuit expects it to be power of 2 + // https://github.com/matter-labs/sync_vm/blob/b538a6105bbc0586ad437484f7f76b2c3e329c46/src/glue/merkleize_l1_messages/merkleize.rs#L298-L301 + Some(|cycles: usize| { 2usize.pow((cycles as f64).log2().floor() as u32) }), + ), + _ => panic!("Unknown circuit type for which the limit can be computed {}", circuit_type) + } +} diff --git a/crates/zkevm_test_harness/src/circuit_synthesis_performance_test/main.rs b/crates/zkevm_test_harness/src/circuit_synthesis_performance_test/main.rs new file mode 100644 index 0000000..8ea951f --- /dev/null +++ b/crates/zkevm_test_harness/src/circuit_synthesis_performance_test/main.rs @@ -0,0 +1,49 @@ +use std::collections::HashMap; +use std::iter::Iterator; +use std::time::Instant; + +use structopt::StructOpt; + +use zkevm_test_harness::circuit_limit_estimator::get_circuit_capacity; + +#[derive(Debug, StructOpt)] +#[structopt( +name = "Performance for individual circuit synthesis", +about = "Tool for performance circuit limit" +)] +struct Opt { + /// Numeric circuit type valid value from [3-17]. + #[structopt(long)] + numeric_circuit: u8, +} + +fn get_circuit_to_synthesis_upper_bound_in_seconds(circuit_type: u8) -> u64 { + let map: HashMap = [ + (3, 5 * 60), // 5 min + (4, 5 * 60), // 5 min + (5, 5 * 60), // 5 min + (6, 5 * 60), // 5 min + (7, 5 * 60), // 5 min + (8, 5 * 60), // 5 min + (9, 5 * 60), // 8 min + (9, 5 * 60), // 8 min + (10, 5 * 60), // 5 min + (11, 5 * 60), // 5 min + (12, 5 * 60), // 6 min + (13, 5 * 60), // 5 min + (14, 5 * 60), // 5 min + (15, 5 * 60), // 5 min + (16, 5 * 60), // 5 min + (17, 5 * 60), // 5 min + ].iter().cloned().collect(); + map[&circuit_type] +} + +fn main() { + let opt = Opt::from_args(); + println!("Starting performance test for circuit {}", opt.numeric_circuit); + let start_time = Instant::now(); + get_circuit_capacity(opt.numeric_circuit); + println!("Finished for circuit {}, took: {} seconds", opt.numeric_circuit, start_time.elapsed().as_secs()); + assert_eq!(true, start_time.elapsed().as_secs() <= get_circuit_to_synthesis_upper_bound_in_seconds(opt.numeric_circuit)); +} diff --git a/crates/zkevm_test_harness/src/compute_setups.rs b/crates/zkevm_test_harness/src/compute_setups.rs new file mode 100644 index 0000000..6cfeea4 --- /dev/null +++ b/crates/zkevm_test_harness/src/compute_setups.rs @@ -0,0 +1,725 @@ +//! Functions to compute setup and verification keys for different circuit types. + +use std::sync::Arc; + +use crate::zkevm_circuits::recursion::leaf_layer::input::RecursionLeafParametersWitness; +use crate::zkevm_circuits::recursion::NUM_BASE_LAYER_CIRCUITS; +use circuit_definitions::boojum::gadgets::traits::allocatable::CSAllocatable; +use circuit_definitions::{ + circuit_definitions::{ + base_layer::{ + ZkSyncBaseLayerCircuit, ZkSyncBaseLayerFinalizationHint, ZkSyncBaseLayerVerificationKey, + }, + ZkSyncUniformCircuitInstance, + }, + recursion_layer_proof_config, + zkevm_circuits::eip_4844::input::ELEMENTS_PER_4844_BLOCK, + zkevm_circuits::scheduler::aux::BaseLayerCircuitType, + RECURSION_LAYER_CAP_SIZE, RECURSION_LAYER_FRI_LDE_FACTOR, +}; + +use crossbeam::atomic::AtomicCell; +use rayon::iter::{IntoParallelIterator, ParallelIterator}; +use rayon::ThreadPoolBuilder; + +use self::toolset::GeometryConfig; + +use super::*; +use crate::boojum::{ + algebraic_props::{round_function::AbsorptionModeOverwrite, sponge::GoldilocksPoseidon2Sponge}, + cs::{ + implementations::{ + hints::{DenseVariablesCopyHint, DenseWitnessCopyHint}, + polynomial_storage::{SetupBaseStorage, SetupStorage}, + setup::FinalizationHintsForProver, + verifier::VerificationKey, + }, + oracle::merkle_tree::MerkleTreeWithCap, + }, + worker::Worker, +}; + +use crate::data_source::SetupDataSource; +use crate::zkevm_circuits::base_structures::vm_state::FULL_SPONGE_QUEUE_STATE_WIDTH; + +use circuit_definitions::circuit_definitions::recursion_layer::leaf_layer::*; +use circuit_definitions::circuit_definitions::recursion_layer::*; +use circuit_definitions::{BASE_LAYER_CAP_SIZE, BASE_LAYER_FRI_LDE_FACTOR}; +use std::collections::VecDeque; + +use crate::prover_utils::*; + +/// Returns all types of basic circuits, with empty witnesses. +/// Can be used for things like verification key generation. +fn get_all_basic_circuits(geometry: &GeometryConfig) -> Vec { + vec![ + ZkSyncBaseLayerCircuit::MainVM(ZkSyncUniformCircuitInstance { + witness: AtomicCell::new(None), + config: Arc::new(geometry.cycles_per_vm_snapshot as usize), + round_function: Arc::new(Poseidon2Goldilocks), + expected_public_input: None, + }), + ZkSyncBaseLayerCircuit::CodeDecommittmentsSorter(ZkSyncUniformCircuitInstance { + witness: AtomicCell::new(None), + config: Arc::new(geometry.cycles_code_decommitter_sorter as usize), + round_function: Arc::new(Poseidon2Goldilocks), + expected_public_input: None, + }), + ZkSyncBaseLayerCircuit::CodeDecommitter(ZkSyncUniformCircuitInstance { + witness: AtomicCell::new(None), + + config: Arc::new(geometry.cycles_per_code_decommitter as usize), + round_function: Arc::new(Poseidon2Goldilocks), + expected_public_input: None, + }), + ZkSyncBaseLayerCircuit::LogDemuxer(ZkSyncUniformCircuitInstance { + witness: AtomicCell::new(None), + config: Arc::new(geometry.cycles_per_log_demuxer as usize), + round_function: Arc::new(Poseidon2Goldilocks), + expected_public_input: None, + }), + ZkSyncBaseLayerCircuit::KeccakRoundFunction(ZkSyncUniformCircuitInstance { + witness: AtomicCell::new(None), + config: Arc::new(geometry.cycles_per_keccak256_circuit as usize), + round_function: Arc::new(Poseidon2Goldilocks), + expected_public_input: None, + }), + ZkSyncBaseLayerCircuit::Sha256RoundFunction(ZkSyncUniformCircuitInstance { + witness: AtomicCell::new(None), + config: Arc::new(geometry.cycles_per_sha256_circuit as usize), + round_function: Arc::new(Poseidon2Goldilocks), + expected_public_input: None, + }), + ZkSyncBaseLayerCircuit::ECRecover(ZkSyncUniformCircuitInstance { + witness: AtomicCell::new(None), + config: Arc::new(geometry.cycles_per_ecrecover_circuit as usize), + round_function: Arc::new(Poseidon2Goldilocks), + expected_public_input: None, + }), + ZkSyncBaseLayerCircuit::RAMPermutation(ZkSyncUniformCircuitInstance { + witness: AtomicCell::new(None), + config: Arc::new(geometry.cycles_per_ram_permutation as usize), + round_function: Arc::new(Poseidon2Goldilocks), + expected_public_input: None, + }), + ZkSyncBaseLayerCircuit::StorageSorter(ZkSyncUniformCircuitInstance { + witness: AtomicCell::new(None), + config: Arc::new(geometry.cycles_per_storage_sorter as usize), + round_function: Arc::new(Poseidon2Goldilocks), + expected_public_input: None, + }), + ZkSyncBaseLayerCircuit::StorageApplication(ZkSyncUniformCircuitInstance { + witness: AtomicCell::new(None), + config: Arc::new(geometry.cycles_per_storage_application as usize), + round_function: Arc::new(Poseidon2Goldilocks), + expected_public_input: None, + }), + ZkSyncBaseLayerCircuit::EventsSorter(ZkSyncUniformCircuitInstance { + witness: AtomicCell::new(None), + config: Arc::new(geometry.cycles_per_events_or_l1_messages_sorter as usize), + round_function: Arc::new(Poseidon2Goldilocks), + expected_public_input: None, + }), + ZkSyncBaseLayerCircuit::L1MessagesSorter(ZkSyncUniformCircuitInstance { + witness: AtomicCell::new(None), + config: Arc::new(geometry.cycles_per_events_or_l1_messages_sorter as usize), + round_function: Arc::new(Poseidon2Goldilocks), + expected_public_input: None, + }), + ZkSyncBaseLayerCircuit::L1MessagesHasher(ZkSyncUniformCircuitInstance { + witness: AtomicCell::new(None), + config: Arc::new(geometry.limit_for_l1_messages_pudata_hasher as usize), + round_function: Arc::new(Poseidon2Goldilocks), + expected_public_input: None, + }), + ZkSyncBaseLayerCircuit::TransientStorageSorter(ZkSyncUniformCircuitInstance { + witness: AtomicCell::new(None), + config: Arc::new(geometry.cycles_per_transient_storage_sorter as usize), + round_function: Arc::new(Poseidon2Goldilocks), + expected_public_input: None, + }), + ZkSyncBaseLayerCircuit::Secp256r1Verify(ZkSyncUniformCircuitInstance { + witness: AtomicCell::new(None), + config: Arc::new(geometry.cycles_per_secp256r1_verify_circuit as usize), + round_function: Arc::new(Poseidon2Goldilocks), + expected_public_input: None, + }), + ZkSyncBaseLayerCircuit::EIP4844Repack(ZkSyncUniformCircuitInstance { + witness: AtomicCell::new(None), + config: Arc::new(ELEMENTS_PER_4844_BLOCK as usize), + round_function: Arc::new(Poseidon2Goldilocks), + expected_public_input: None, + }), + ] +} + +/// Returns all the recursive circuits (including leaves, nodes and scheduler). +/// Source must contain the verification keys for basic layer, leaf and node. +fn get_all_recursive_circuits( + source: &mut dyn SetupDataSource, +) -> crate::data_source::SourceResult> { + let mut result = get_leaf_circuits(source)?; + + result.push(get_node_circuit(source)?); + result.push(get_recursion_tip_circuit(source)?); + result.push(get_scheduler_circuit(source)?); + return Ok(result); +} + +/// Returns all the leaf circuits. +fn get_leaf_circuits( + source: &mut dyn SetupDataSource, +) -> crate::data_source::SourceResult> { + let mut result = vec![]; + + for base_circuit_type in ((BaseLayerCircuitType::VM as u8) + ..=(BaseLayerCircuitType::Secp256r1Verify as u8)) + .chain(std::iter::once(BaseLayerCircuitType::EIP4844Repack as u8)) + { + let _recursive_circuit_type = base_circuit_type_into_recursive_leaf_circuit_type( + BaseLayerCircuitType::from_numeric_value(base_circuit_type), + ); + + use crate::zkevm_circuits::recursion::leaf_layer::input::*; + let input = RecursionLeafInput::placeholder_witness(); + let vk = source.get_base_layer_vk(base_circuit_type)?; + + use crate::boojum::gadgets::queue::full_state_queue::FullStateCircuitQueueRawWitness; + let witness = RecursionLeafInstanceWitness { + input, + vk_witness: vk.clone().into_inner(), + queue_witness: FullStateCircuitQueueRawWitness { + elements: VecDeque::new(), + }, + proof_witnesses: VecDeque::new(), + }; + + use crate::zkevm_circuits::recursion::leaf_layer::LeafLayerRecursionConfig; + let config = LeafLayerRecursionConfig { + proof_config: recursion_layer_proof_config(), + vk_fixed_parameters: vk.into_inner().fixed_parameters, + capacity: RECURSION_ARITY, + _marker: std::marker::PhantomData, + }; + + let circuit = ZkSyncLeafLayerRecursiveCircuit { + base_layer_circuit_type: BaseLayerCircuitType::from_numeric_value(base_circuit_type), + witness: witness, + config: config, + transcript_params: (), + _marker: std::marker::PhantomData, + }; + + let circuit = ZkSyncRecursiveLayerCircuit::leaf_circuit_from_base_type( + BaseLayerCircuitType::from_numeric_value(base_circuit_type), + circuit, + ); + result.push(circuit); + } + return Ok(result); +} + +/// Returns the node circuit. +fn get_node_circuit( + source: &mut dyn SetupDataSource, +) -> crate::data_source::SourceResult { + use crate::zkevm_circuits::recursion::node_layer::input::*; + let input = RecursionNodeInput::placeholder_witness(); + let vk = source + .get_recursion_layer_vk(ZkSyncRecursionLayerStorageType::LeafLayerCircuitForMainVM as u8)?; + + // the only thing to setup here is to have proper number of split points + use crate::boojum::gadgets::queue::QueueTailState; + let split_points = vec![ + QueueTailState::::placeholder_witness(); + RECURSION_ARITY - 1 + ]; + let witness = RecursionNodeInstanceWitness { + input, + vk_witness: vk.clone().into_inner(), + split_points: split_points.into(), + proof_witnesses: VecDeque::new(), + }; + + use crate::zkevm_circuits::recursion::node_layer::NodeLayerRecursionConfig; + use circuit_definitions::circuit_definitions::recursion_layer::node_layer::ZkSyncNodeLayerRecursiveCircuit; + let config = NodeLayerRecursionConfig { + proof_config: recursion_layer_proof_config(), + vk_fixed_parameters: vk.into_inner().fixed_parameters, + leaf_layer_capacity: RECURSION_ARITY, + node_layer_capacity: RECURSION_ARITY, + _marker: std::marker::PhantomData, + }; + let circuit = ZkSyncNodeLayerRecursiveCircuit { + witness, + config, + transcript_params: (), + _marker: std::marker::PhantomData, + }; + + Ok(ZkSyncRecursiveLayerCircuit::NodeLayerCircuit(circuit)) +} + +/// Returns the recursion tip circuit +fn get_recursion_tip_circuit( + source: &mut dyn SetupDataSource, +) -> crate::data_source::SourceResult { + use crate::zkevm_circuits::recursion::recursion_tip::input::*; + let input = RecursionTipInput::placeholder_witness(); + let vk = source.get_recursion_layer_node_vk()?.into_inner(); + + let witness = RecursionTipInstanceWitness { + input, + vk_witness: vk.clone(), + proof_witnesses: VecDeque::new(), + }; + + use crate::zkevm_circuits::recursion::recursion_tip::*; + use circuit_definitions::circuit_definitions::recursion_layer::recursion_tip::*; + + let config = RecursionTipConfig { + proof_config: recursion_layer_proof_config(), + vk_fixed_parameters: vk.fixed_parameters, + _marker: std::marker::PhantomData, + }; + + let circuit = RecursionTipCircuit { + witness, + config, + transcript_params: (), + _marker: std::marker::PhantomData, + }; + + Ok(ZkSyncRecursiveLayerCircuit::RecursionTipCircuit(circuit)) +} + +/// Returns the scheduler circuit. +/// Source must contain the leafs, node and tip verification keys. +fn get_scheduler_circuit( + source: &mut dyn SetupDataSource, +) -> crate::data_source::SourceResult { + use crate::zkevm_circuits::scheduler::SchedulerConfig; + use circuit_definitions::circuit_definitions::recursion_layer::scheduler::SchedulerCircuit; + + println!("Computing leaf params"); + let leaf_layer_params = compute_leaf_params(source)?; + println!("Obtaining node VK"); + let node_vk = source.get_recursion_layer_node_vk()?.into_inner(); + println!("Obtaining recursion tip VK"); + let recursion_tip_vk = source.get_recursion_tip_vk()?.into_inner(); + + let leaf_layer_params: [RecursionLeafParametersWitness; + NUM_BASE_LAYER_CIRCUITS] = leaf_layer_params + .into_iter() + .map(|el| el.1) + .collect::>() + .try_into() + .unwrap(); + + let config = SchedulerConfig { + proof_config: recursion_layer_proof_config(), + leaf_layer_parameters: leaf_layer_params, + node_layer_vk: node_vk, + recursion_tip_vk: recursion_tip_vk.clone(), + vk_fixed_parameters: recursion_tip_vk.fixed_parameters.clone(), + capacity: SCHEDULER_CAPACITY, + _marker: std::marker::PhantomData, + }; + + use crate::zkevm_circuits::scheduler::input::SchedulerCircuitInstanceWitness; + let scheduler_witness = SchedulerCircuitInstanceWitness::placeholder(); + + let scheduler_circuit = SchedulerCircuit { + witness: scheduler_witness, + config, + transcript_params: (), + _marker: std::marker::PhantomData, + }; + + Ok(ZkSyncRecursiveLayerCircuit::SchedulerCircuit( + scheduler_circuit, + )) +} + +/// Contains all the information that prover needs to setup and verify the given circuit. +pub struct CircuitSetupData { + pub setup_base: SetupBaseStorage, + pub setup: SetupStorage, + pub vk: VerificationKey>, + pub setup_tree: + MerkleTreeWithCap>, + pub vars_hint: DenseVariablesCopyHint, + pub wits_hint: DenseWitnessCopyHint, + pub finalization_hint: FinalizationHintsForProver, +} + +/// Generate verification, and setup keys for a given circuit type from a base layer. +/// If generating the setup data for recursion layers, the 'source' must have verification keys for basic circuits, leaf and node. +pub fn generate_circuit_setup_data( + is_base_layer: bool, + circuit_type: u8, + source: &mut dyn SetupDataSource, +) -> crate::data_source::SourceResult { + let geometry = crate::geometry_config::get_geometry_config(); + let worker = Worker::new(); + + let (setup_base, setup, vk, setup_tree, vars_hint, wits_hint, finalization_hint) = + if is_base_layer { + let circuit = get_all_basic_circuits(&geometry) + .iter() + .find(|circuit| circuit.numeric_circuit_type() == circuit_type) + .expect(&format!( + "Could not find circuit matching {:?}", + circuit_type + )) + .clone(); + + create_base_layer_setup_data( + circuit, + &worker, + BASE_LAYER_FRI_LDE_FACTOR, + BASE_LAYER_CAP_SIZE, + ) + } else { + let circuit = get_all_recursive_circuits(source)? + .iter() + .find(|circuit| circuit.numeric_circuit_type() == circuit_type) + .expect(&format!( + "Could not find circuit matching {:?}", + circuit_type + )) + .clone(); + + create_recursive_layer_setup_data( + circuit, + &worker, + BASE_LAYER_FRI_LDE_FACTOR, + BASE_LAYER_CAP_SIZE, + ) + }; + + Ok(CircuitSetupData { + setup_base, + setup, + vk, + setup_tree, + vars_hint, + wits_hint, + finalization_hint, + }) +} + +/// For backwards compatibility (as zksync-era uses this method). +/// For new cases please use generate_base_layer_vks directly. +pub fn generate_base_layer_vks_and_proofs( + source: &mut dyn SetupDataSource, +) -> crate::data_source::SourceResult<()> { + generate_base_layer_vks(source, None, || {}) +} + +/// Returns number of basic verification keys. +pub fn basic_vk_count() -> usize { + BaseLayerCircuitType::as_iter_u8().count() +} + +/// Generate Verification keys for all base layer circuits. +/// num_threads control how many VKs are generated in parallel - each one takes around 30GB of RAM. +/// if not specified, will run them sequencially. +/// CB callback will be called on each finished VK (to track progress). +pub fn generate_base_layer_vks( + source: &mut dyn SetupDataSource, + num_threads: Option, + cb: CB, +) -> crate::data_source::SourceResult<()> { + let geometry = crate::geometry_config::get_geometry_config(); + let worker = Worker::new(); + + let num_threads = num_threads.unwrap_or(1); + + let pool = ThreadPoolBuilder::new() + .num_threads(num_threads) + .build() + .unwrap(); + + let r: Vec<_> = pool.install(|| { + get_all_basic_circuits(&geometry) + .into_par_iter() + .map(|circuit| { + let result = generate_vk_and_finalization_hint(circuit, &worker); + cb(); + result + }) + .collect() + }); + + for (vk, hint) in r.into_iter() { + source.set_base_layer_finalization_hint(hint)?; + source.set_base_layer_vk(vk)?; + } + + Ok(()) +} + +fn generate_vk_and_finalization_hint( + circuit: ZkSyncBaseLayerCircuit, + worker: &Worker, +) -> ( + ZkSyncBaseLayerVerificationKey, + ZkSyncBaseLayerFinalizationHint, +) { + let circuit_type = circuit.numeric_circuit_type(); + + let (_, _, vk, _, _, _, finalization_hint) = create_base_layer_setup_data( + circuit, + &worker, + BASE_LAYER_FRI_LDE_FACTOR, + BASE_LAYER_CAP_SIZE, + ); + + let typed_vk = ZkSyncBaseLayerVerificationKey::from_inner(circuit_type, vk.clone()); + let typed_finalization_hint = + ZkSyncBaseLayerFinalizationHint::from_inner(circuit_type, finalization_hint.clone()); + (typed_vk, typed_finalization_hint) +} + +/// For backwards compatibility (as zksync-era uses this method). +/// For new cases please use generate_recursive_layer_vks directly. +pub fn generate_recursive_layer_vks_and_proofs( + source: &mut dyn SetupDataSource, +) -> crate::data_source::SourceResult<()> { + generate_recursive_layer_vks(source, None, || {}) +} + +fn generate_vk_and_finalization_hint_for_recursion( + circuit: ZkSyncRecursiveLayerCircuit, + worker: &Worker, +) -> ( + ZkSyncRecursionLayerVerificationKey, + ZkSyncRecursionLayerFinalizationHint, +) { + println!( + "Computing leaf layer VK for type {:?}", + circuit.numeric_circuit_type() + ); + + let numeric_circuit_type = circuit.numeric_circuit_type(); + let (_setup_base, _setup, vk, _setup_tree, _vars_hint, _wits_hint, finalization_hint) = + create_recursive_layer_setup_data( + circuit, + &worker, + RECURSION_LAYER_FRI_LDE_FACTOR, + RECURSION_LAYER_CAP_SIZE, + ); + + let typed_vk = + ZkSyncRecursionLayerVerificationKey::from_inner(numeric_circuit_type, vk.clone()); + + let typed_finalization_hint = ZkSyncRecursionLayerFinalizationHint::from_inner( + numeric_circuit_type, + finalization_hint.clone(), + ); + (typed_vk, typed_finalization_hint) +} + +/// Returns number of recursive layer verification keys. +pub fn recursive_layer_vk_count() -> usize { + // Leafs (one per base layer) + node + recursion + scheduler + basic_vk_count() + 3 +} + +/// num_threads control how many VKs are generated in parallel - each one takes around 25GB of RAM. +/// if not specified, will run them sequencially. +pub fn generate_recursive_layer_vks( + source: &mut dyn SetupDataSource, + num_threads: Option, + cb: CB, +) -> crate::data_source::SourceResult<()> { + // here we rely ONLY on VKs and proofs from the setup, so we keep the geometries and circuits + // via padding proofs + let worker = Worker::new(); + let num_threads = num_threads.unwrap_or(1); + + println!("Computing leaf vks"); + + let pool = ThreadPoolBuilder::new() + .num_threads(num_threads) + .build() + .unwrap(); + + let leaf_circuits = get_leaf_circuits(source)?; + + let r: Vec<_> = pool.install(|| { + leaf_circuits + .into_par_iter() + .map(|circuit| { + let result = generate_vk_and_finalization_hint_for_recursion(circuit, &worker); + cb(); + result + }) + .collect() + }); + + for (vk, hint) in r.into_iter() { + source.set_recursion_layer_finalization_hint(hint)?; + source.set_recursion_layer_vk(vk)?; + } + + println!("Computing node vk"); + + { + let circuit = get_node_circuit(source)?; + + let (_setup_base, _setup, vk, _setup_tree, _vars_hint, _wits_hint, finalization_hint) = + create_recursive_layer_setup_data( + circuit, + &worker, + RECURSION_LAYER_FRI_LDE_FACTOR, + RECURSION_LAYER_CAP_SIZE, + ); + + let typed_finalization_hint = + ZkSyncRecursionLayerFinalizationHint::NodeLayerCircuit(finalization_hint.clone()); + source.set_recursion_layer_node_finalization_hint(typed_finalization_hint)?; + let typed_vk = ZkSyncRecursionLayerVerificationKey::NodeLayerCircuit(vk.clone()); + source.set_recursion_layer_node_vk(typed_vk)?; + } + cb(); + + println!("Computing recursion tip vk"); + generate_recursion_tip_vk(source)?; + cb(); + + println!("Computing scheduler vk"); + generate_scheduler_vk(source)?; + cb(); + + Ok(()) +} + +pub fn generate_recursion_tip_vk( + source: &mut dyn SetupDataSource, +) -> crate::data_source::SourceResult<()> { + let worker = Worker::new(); + let recursion_tip_circuit = get_recursion_tip_circuit(source)?; + + let (_setup_base, _setup, vk, _setup_tree, _vars_hint, _wits_hint, finalization_hint) = + create_recursive_layer_setup_data( + recursion_tip_circuit, + &worker, + RECURSION_LAYER_FRI_LDE_FACTOR, + RECURSION_LAYER_CAP_SIZE, + ); + + source.set_recursion_tip_vk(ZkSyncRecursionLayerVerificationKey::RecursionTipCircuit( + vk.clone(), + ))?; + source.set_recursion_tip_finalization_hint( + ZkSyncRecursionLayerFinalizationHint::RecursionTipCircuit(finalization_hint.clone()), + )?; + Ok(()) +} + +pub fn generate_scheduler_vk( + source: &mut dyn SetupDataSource, +) -> crate::data_source::SourceResult<()> { + let worker = Worker::new(); + let scheduler_circuit = get_scheduler_circuit(source)?; + + let (_setup_base, _setup, vk, _setup_tree, _vars_hint, _wits_hint, finalization_hint) = + create_recursive_layer_setup_data( + scheduler_circuit, + &worker, + RECURSION_LAYER_FRI_LDE_FACTOR, + RECURSION_LAYER_CAP_SIZE, + ); + + source.set_recursion_layer_vk(ZkSyncRecursionLayerVerificationKey::SchedulerCircuit( + vk.clone(), + ))?; + source.set_recursion_layer_finalization_hint( + ZkSyncRecursionLayerFinalizationHint::SchedulerCircuit(finalization_hint.clone()), + )?; + + Ok(()) +} + +pub fn compute_leaf_params( + source: &mut dyn SetupDataSource, +) -> crate::data_source::SourceResult)>> { + use crate::witness::recursive_aggregation::compute_leaf_params; + let mut leaf_vk_commits = vec![]; + + for circuit_type in ((BaseLayerCircuitType::VM as u8) + ..=(BaseLayerCircuitType::Secp256r1Verify as u8)) + .chain(std::iter::once(BaseLayerCircuitType::EIP4844Repack as u8)) + { + let recursive_circuit_type = base_circuit_type_into_recursive_leaf_circuit_type( + BaseLayerCircuitType::from_numeric_value(circuit_type), + ); + let base_vk = source.get_base_layer_vk(circuit_type)?; + let leaf_vk = source.get_recursion_layer_vk(recursive_circuit_type as u8)?; + let params = compute_leaf_params(circuit_type, base_vk, leaf_vk); + leaf_vk_commits.push((circuit_type, params)); + } + + Ok(leaf_vk_commits) +} + +#[cfg(test)] +mod test { + use std::sync::Mutex; + + use indicatif::{ProgressBar, ProgressStyle}; + + use self::data_source::local_file_data_source::LocalFileDataSource; + + use super::*; + + #[ignore = "too slow"] + #[test] + fn test_run_create_base_layer_vks_and_proofs() { + let mut source = LocalFileDataSource::default(); + source.create_folders_for_storing_data(); + let count = basic_vk_count(); + let progress_bar = ProgressBar::new(count as u64); + progress_bar.set_style(ProgressStyle::default_bar() + .template("{spinner:.green} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {pos:>7}/{len:7} ({eta})") + .progress_chars("#>-")); + + let pb = Arc::new(Mutex::new(progress_bar)); + + generate_base_layer_vks(&mut source, None, || { + pb.lock().unwrap().inc(1); + }) + .expect("must compute setup"); + pb.lock().unwrap().finish_with_message("done"); + } + + #[ignore = "too slow"] + #[test] + fn test_run_create_recursion_layer_vks_and_proofs() { + let mut source = LocalFileDataSource::default(); + source.create_folders_for_storing_data(); + generate_recursive_layer_vks(&mut source, None, || {}).expect("must compute setup"); + } + + #[ignore = "too slow"] + #[test] + fn test_generate_recursion_tip() { + let mut src = LocalFileDataSource::default(); + src.create_folders_for_storing_data(); + let source = &mut src; + + generate_recursion_tip_vk(source).unwrap(); + } + + #[ignore = "too slow"] + #[test] + fn test_generate_scheduler() { + let mut src = LocalFileDataSource::default(); + src.create_folders_for_storing_data(); + let source = &mut src; + + generate_scheduler_vk(source).unwrap(); + } +} diff --git a/crates/zkevm_test_harness/src/data_source/in_memory_data_source.rs b/crates/zkevm_test_harness/src/data_source/in_memory_data_source.rs new file mode 100644 index 0000000..4e59a3d --- /dev/null +++ b/crates/zkevm_test_harness/src/data_source/in_memory_data_source.rs @@ -0,0 +1,507 @@ +use super::{BlockDataSource, SetupDataSource, SourceResult}; +use circuit_definitions::boojum::cs::implementations::setup::FinalizationHintsForProver; +use circuit_definitions::circuit_definitions::aux_layer::{ + EIP4844VerificationKey, ZkSyncCompressionForWrapperFinalizationHint, + ZkSyncCompressionForWrapperProof, ZkSyncCompressionForWrapperVerificationKey, + ZkSyncCompressionLayerFinalizationHint, ZkSyncCompressionLayerProof, + ZkSyncCompressionLayerVerificationKey, ZkSyncSnarkWrapperProof, ZkSyncSnarkWrapperSetup, + ZkSyncSnarkWrapperVK, +}; +use circuit_definitions::circuit_definitions::base_layer::{ + ZkSyncBaseLayerFinalizationHint, ZkSyncBaseLayerProof, ZkSyncBaseLayerVerificationKey, +}; +use circuit_definitions::circuit_definitions::recursion_layer::{ + ZkSyncRecursionLayerFinalizationHint, ZkSyncRecursionLayerProof, + ZkSyncRecursionLayerVerificationKey, +}; +use std::collections::HashMap; +use std::io::{Error, ErrorKind}; + +pub struct InMemoryDataSource { + ///data structures required for holding [`SetupDataSource`] result + base_layer_vk: HashMap, + base_layer_finalization_hint: HashMap, + recursion_layer_vk: HashMap, + recursion_layer_node_vk: Option, + recursion_tip_vk: Option, + recursion_layer_finalization_hint: HashMap, + recursion_layer_node_finalization_hint: Option, + recursion_tip_finalization_hint: Option, + compression_vk: HashMap, + compression_hint: HashMap, + compression_for_wrapper_vk: HashMap, + compression_for_wrapper_hint: HashMap, + wrapper_setup: HashMap, + wrapper_vk: HashMap, + + ///data structures required for holding [`BlockDataSource`] result + base_layer_proofs: HashMap<(u8, usize), ZkSyncBaseLayerProof>, + leaf_layer_proofs: HashMap<(u8, usize), ZkSyncRecursionLayerProof>, + node_layer_proofs: HashMap<(u8, usize, usize), ZkSyncRecursionLayerProof>, + recursion_tip_proof: Option, + scheduler_proof: Option, + compression_proof: HashMap, + compression_for_wrapper_proof: HashMap, + wrapper_proof: HashMap, +} + +impl InMemoryDataSource { + pub fn new() -> Self { + InMemoryDataSource { + base_layer_vk: HashMap::new(), + base_layer_finalization_hint: HashMap::new(), + recursion_layer_vk: HashMap::new(), + recursion_layer_node_vk: None, + recursion_tip_vk: None, + recursion_layer_finalization_hint: HashMap::new(), + recursion_layer_node_finalization_hint: None, + recursion_tip_finalization_hint: None, + compression_vk: HashMap::new(), + compression_hint: HashMap::new(), + compression_for_wrapper_vk: HashMap::new(), + compression_for_wrapper_hint: HashMap::new(), + wrapper_setup: HashMap::new(), + wrapper_vk: HashMap::new(), + base_layer_proofs: HashMap::new(), + leaf_layer_proofs: HashMap::new(), + node_layer_proofs: HashMap::new(), + scheduler_proof: None, + recursion_tip_proof: None, + compression_proof: HashMap::new(), + compression_for_wrapper_proof: HashMap::new(), + wrapper_proof: HashMap::new(), + } + } +} + +impl SetupDataSource for InMemoryDataSource { + fn get_base_layer_vk(&self, circuit_type: u8) -> SourceResult { + self.base_layer_vk + .get(&circuit_type) + .cloned() + .ok_or(Box::new(Error::new( + ErrorKind::Other, + format!("no data for circuit type {}", circuit_type), + ))) + } + + fn get_base_layer_finalization_hint( + &self, + circuit_type: u8, + ) -> SourceResult { + self.base_layer_finalization_hint + .get(&circuit_type) + .cloned() + .ok_or(Box::new(Error::new( + ErrorKind::Other, + format!("no data for circuit type {}", circuit_type), + ))) + } + + fn get_recursion_layer_vk( + &self, + circuit_type: u8, + ) -> SourceResult { + self.recursion_layer_vk + .get(&circuit_type) + .cloned() + .ok_or(Box::new(Error::new( + ErrorKind::Other, + format!("no data for circuit type {}", circuit_type), + ))) + } + + fn get_recursion_layer_node_vk(&self) -> SourceResult { + self.recursion_layer_node_vk + .clone() + .ok_or(Box::new(Error::new( + ErrorKind::Other, + format!("no data for recursion layer node vk"), + ))) + } + + fn get_recursion_layer_finalization_hint( + &self, + circuit_type: u8, + ) -> SourceResult { + self.recursion_layer_finalization_hint + .get(&circuit_type) + .cloned() + .ok_or(Box::new(Error::new( + ErrorKind::Other, + format!("no data for circuit type {}", circuit_type), + ))) + } + + fn get_recursion_layer_node_finalization_hint( + &self, + ) -> SourceResult { + self.recursion_layer_node_finalization_hint + .clone() + .ok_or(Box::new(Error::new( + ErrorKind::Other, + format!("no data for recursion layer node vk"), + ))) + } + + fn get_compression_vk( + &self, + circuit_type: u8, + ) -> SourceResult { + self.compression_vk + .get(&circuit_type) + .cloned() + .ok_or(Box::new(Error::new( + ErrorKind::Other, + format!("no data for circuit type {}", circuit_type), + ))) + } + + fn get_compression_hint( + &self, + circuit_type: u8, + ) -> SourceResult { + self.compression_hint + .get(&circuit_type) + .cloned() + .ok_or(Box::new(Error::new( + ErrorKind::Other, + format!("no data for circuit type {}", circuit_type), + ))) + } + + fn get_compression_for_wrapper_vk( + &self, + circuit_type: u8, + ) -> SourceResult { + self.compression_for_wrapper_vk + .get(&circuit_type) + .cloned() + .ok_or(Box::new(Error::new( + ErrorKind::Other, + format!("no data for circuit type {}", circuit_type), + ))) + } + + fn get_compression_for_wrapper_hint( + &self, + circuit_type: u8, + ) -> SourceResult { + self.compression_for_wrapper_hint + .get(&circuit_type) + .cloned() + .ok_or(Box::new(Error::new( + ErrorKind::Other, + format!("no data for circuit type {}", circuit_type), + ))) + } + + fn get_wrapper_setup(&self, circuit_type: u8) -> SourceResult { + self.wrapper_setup + .get(&circuit_type) + .cloned() + .ok_or(Box::new(Error::new( + ErrorKind::Other, + format!("no data for circuit type {}", circuit_type), + ))) + } + + fn get_wrapper_vk(&self, circuit_type: u8) -> SourceResult { + self.wrapper_vk + .get(&circuit_type) + .cloned() + .ok_or(Box::new(Error::new( + ErrorKind::Other, + format!("no data for circuit type {}", circuit_type), + ))) + } + + fn set_base_layer_vk(&mut self, vk: ZkSyncBaseLayerVerificationKey) -> SourceResult<()> { + self.base_layer_vk.insert(vk.numeric_circuit_type(), vk); + Ok(()) + } + + fn set_base_layer_finalization_hint( + &mut self, + hint: ZkSyncBaseLayerFinalizationHint, + ) -> SourceResult<()> { + self.base_layer_finalization_hint + .insert(hint.numeric_circuit_type(), hint); + Ok(()) + } + + fn set_recursion_layer_vk( + &mut self, + vk: ZkSyncRecursionLayerVerificationKey, + ) -> SourceResult<()> { + self.recursion_layer_vk + .insert(vk.numeric_circuit_type(), vk); + Ok(()) + } + + fn set_recursion_layer_node_vk( + &mut self, + vk: ZkSyncRecursionLayerVerificationKey, + ) -> SourceResult<()> { + self.recursion_layer_node_vk = Some(vk); + Ok(()) + } + + fn set_recursion_layer_finalization_hint( + &mut self, + hint: ZkSyncRecursionLayerFinalizationHint, + ) -> SourceResult<()> { + self.recursion_layer_finalization_hint + .insert(hint.numeric_circuit_type(), hint); + Ok(()) + } + + fn set_recursion_layer_node_finalization_hint( + &mut self, + hint: ZkSyncRecursionLayerFinalizationHint, + ) -> SourceResult<()> { + self.recursion_layer_node_finalization_hint = Some(hint); + Ok(()) + } + + fn set_compression_vk( + &mut self, + vk: ZkSyncCompressionLayerVerificationKey, + ) -> SourceResult<()> { + self.compression_vk.insert(vk.numeric_circuit_type(), vk); + Ok(()) + } + + fn set_compression_hint( + &mut self, + hint: ZkSyncCompressionLayerFinalizationHint, + ) -> SourceResult<()> { + self.compression_hint + .insert(hint.numeric_circuit_type(), hint); + Ok(()) + } + + fn set_compression_for_wrapper_vk( + &mut self, + vk: ZkSyncCompressionForWrapperVerificationKey, + ) -> SourceResult<()> { + self.compression_for_wrapper_vk + .insert(vk.numeric_circuit_type(), vk); + Ok(()) + } + + fn set_compression_for_wrapper_hint( + &mut self, + hint: ZkSyncCompressionForWrapperFinalizationHint, + ) -> SourceResult<()> { + self.compression_for_wrapper_hint + .insert(hint.numeric_circuit_type(), hint); + Ok(()) + } + + fn set_wrapper_setup(&mut self, setup: ZkSyncSnarkWrapperSetup) -> SourceResult<()> { + self.wrapper_setup + .insert(setup.numeric_circuit_type(), setup); + Ok(()) + } + + fn set_wrapper_vk(&mut self, vk: ZkSyncSnarkWrapperVK) -> SourceResult<()> { + self.wrapper_vk.insert(vk.numeric_circuit_type(), vk); + Ok(()) + } + + fn get_recursion_tip_vk(&self) -> SourceResult { + self.recursion_tip_vk.clone().ok_or(Box::new(Error::new( + ErrorKind::Other, + format!("no data for recursion tip vk"), + ))) + } + fn get_recursion_tip_finalization_hint( + &self, + ) -> SourceResult { + self.recursion_tip_finalization_hint + .clone() + .ok_or(Box::new(Error::new( + ErrorKind::Other, + format!("no data for recursion tip finalization hint"), + ))) + } + fn set_recursion_tip_vk( + &mut self, + vk: ZkSyncRecursionLayerVerificationKey, + ) -> SourceResult<()> { + self.recursion_tip_vk = Some(vk); + Ok(()) + } + fn set_recursion_tip_finalization_hint( + &mut self, + hint: ZkSyncRecursionLayerFinalizationHint, + ) -> SourceResult<()> { + self.recursion_tip_finalization_hint = Some(hint); + Ok(()) + } +} + +impl BlockDataSource for InMemoryDataSource { + fn get_base_layer_proof( + &self, + circuit_type: u8, + index: usize, + ) -> SourceResult { + self.base_layer_proofs + .get(&(circuit_type, index)) + .cloned() + .ok_or(Box::new(Error::new( + ErrorKind::Other, + format!( + "no base layer proof for circuit type {} index {}", + circuit_type, index + ), + ))) + } + + fn get_leaf_layer_proof( + &self, + circuit_type: u8, + index: usize, + ) -> SourceResult { + self.leaf_layer_proofs + .get(&(circuit_type, index)) + .cloned() + .ok_or(Box::new(Error::new( + ErrorKind::Other, + format!( + "no leaf layer proof for circuit type {} index {}", + circuit_type, index + ), + ))) + } + + fn get_node_layer_proof( + &self, + circuit_type: u8, + step: usize, + index: usize, + ) -> SourceResult { + self.node_layer_proofs + .get(&(circuit_type, step, index)) + .cloned() + .ok_or(Box::new(Error::new( + ErrorKind::Other, + format!( + "no node layer proof for circuit type {} index {} step {}", + circuit_type, index, step + ), + ))) + } + + fn get_scheduler_proof(&self) -> SourceResult { + self.scheduler_proof.clone().ok_or(Box::new(Error::new( + ErrorKind::Other, + format!("no scheduler proof"), + ))) + } + + fn get_compression_proof(&self, circuit_type: u8) -> SourceResult { + self.compression_proof + .get(&circuit_type) + .cloned() + .ok_or(Box::new(Error::new( + ErrorKind::Other, + format!("no data for circuit type {}", circuit_type), + ))) + } + + fn get_compression_for_wrapper_proof( + &self, + circuit_type: u8, + ) -> SourceResult { + self.compression_for_wrapper_proof + .get(&circuit_type) + .cloned() + .ok_or(Box::new(Error::new( + ErrorKind::Other, + format!("no data for circuit type {}", circuit_type), + ))) + } + + fn get_wrapper_proof(&self, circuit_type: u8) -> SourceResult { + self.wrapper_proof + .get(&circuit_type) + .cloned() + .ok_or(Box::new(Error::new( + ErrorKind::Other, + format!("no data for circuit type {}", circuit_type), + ))) + } + + fn set_base_layer_proof( + &mut self, + index: usize, + proof: ZkSyncBaseLayerProof, + ) -> SourceResult<()> { + let circuit_type = proof.numeric_circuit_type(); + self.base_layer_proofs.insert((circuit_type, index), proof); + Ok(()) + } + + fn set_leaf_layer_proof( + &mut self, + index: usize, + proof: ZkSyncRecursionLayerProof, + ) -> SourceResult<()> { + let circuit_type = proof.numeric_circuit_type(); + self.leaf_layer_proofs.insert((circuit_type, index), proof); + Ok(()) + } + + fn set_node_layer_proof( + &mut self, + circuit_type: u8, + step: usize, + index: usize, + proof: ZkSyncRecursionLayerProof, + ) -> SourceResult<()> { + self.node_layer_proofs + .insert((circuit_type, step, index), proof); + Ok(()) + } + + fn set_scheduler_proof(&mut self, proof: ZkSyncRecursionLayerProof) -> SourceResult<()> { + self.scheduler_proof = Some(proof); + Ok(()) + } + + fn set_compression_proof(&mut self, proof: ZkSyncCompressionLayerProof) -> SourceResult<()> { + self.compression_proof + .insert(proof.numeric_circuit_type(), proof); + Ok(()) + } + + fn set_compression_for_wrapper_proof( + &mut self, + proof: ZkSyncCompressionForWrapperProof, + ) -> SourceResult<()> { + self.compression_for_wrapper_proof + .insert(proof.numeric_circuit_type(), proof); + Ok(()) + } + + fn set_wrapper_proof(&mut self, proof: ZkSyncSnarkWrapperProof) -> SourceResult<()> { + self.wrapper_proof + .insert(proof.numeric_circuit_type(), proof); + Ok(()) + } + + fn set_recursive_tip_proof(&mut self, proof: ZkSyncRecursionLayerProof) -> SourceResult<()> { + self.recursion_tip_proof = Some(proof); + Ok(()) + } + + fn get_recursive_tip_proof(&self) -> SourceResult { + self.recursion_tip_proof.clone().ok_or(Box::new(Error::new( + ErrorKind::Other, + format!("no recursion tip proof"), + ))) + } +} diff --git a/crates/zkevm_test_harness/src/data_source/local_file_data_source.rs b/crates/zkevm_test_harness/src/data_source/local_file_data_source.rs new file mode 100644 index 0000000..1a77071 --- /dev/null +++ b/crates/zkevm_test_harness/src/data_source/local_file_data_source.rs @@ -0,0 +1,482 @@ +use super::{BlockDataSource, SetupDataSource, SourceResult}; +use circuit_definitions::boojum::cs::implementations::setup::FinalizationHintsForProver; +use circuit_definitions::circuit_definitions::aux_layer::{ + EIP4844VerificationKey, ZkSyncCompressionForWrapperFinalizationHint, + ZkSyncCompressionForWrapperProof, ZkSyncCompressionForWrapperVerificationKey, + ZkSyncCompressionLayerFinalizationHint, ZkSyncCompressionLayerProof, + ZkSyncCompressionLayerVerificationKey, ZkSyncSnarkWrapperProof, ZkSyncSnarkWrapperSetup, + ZkSyncSnarkWrapperVK, +}; +use circuit_definitions::circuit_definitions::base_layer::{ + ZkSyncBaseLayerFinalizationHint, ZkSyncBaseLayerProof, ZkSyncBaseLayerVerificationKey, +}; +use circuit_definitions::circuit_definitions::recursion_layer::{ + ZkSyncRecursionLayerFinalizationHint, ZkSyncRecursionLayerProof, + ZkSyncRecursionLayerVerificationKey, +}; +use serde::{Deserialize, Serialize}; + +use crate::snark_wrapper::franklin_crypto::bellman::plonk::better_better_cs::proof::Proof as SnarkProof; +use crate::snark_wrapper::franklin_crypto::bellman::plonk::better_better_cs::setup::Setup as SnarkSetup; +use crate::snark_wrapper::franklin_crypto::bellman::plonk::better_better_cs::setup::VerificationKey as SnarkVK; + +use derivative::*; +use std::sync::Arc; +use std::{error::Error, fs::File}; + +#[derive(Derivative)] +#[derivative(Clone, Debug)] +pub struct LocalFileDataSource { + pub setup_data_location: String, + pub block_data_location: String, +} + +impl Default for LocalFileDataSource { + fn default() -> Self { + Self { + setup_data_location: "./setup".to_string(), + block_data_location: "./test_proofs".to_string(), + } + } +} + +impl LocalFileDataSource { + fn get_proof Deserialize<'de>>(&self, file_name: String) -> SourceResult { + let file = File::open(format!("{}/{}.json", self.block_data_location, file_name)) + .map_err(|el| Box::new(el) as Box)?; + let result = serde_json::from_reader(file).map_err(|el| Box::new(el) as Box)?; + + Ok(result) + } + + fn set_proof(&self, file_name: String, proof: T) -> SourceResult<()> { + let file = File::create(format!("{}/{}.json", self.block_data_location, file_name)) + .map_err(|el| Box::new(el) as Box)?; + serde_json::to_writer(file, &proof).map_err(|el| Box::new(el) as Box)?; + Ok(()) + } + + fn get_setup_data Deserialize<'de>>(&self, file_name: String) -> SourceResult { + let file = File::open(format!("{}/{}.json", self.setup_data_location, file_name)) + .map_err(|el| Box::new(el) as Box)?; + let result = serde_json::from_reader(file).map_err(|el| Box::new(el) as Box)?; + + Ok(result) + } + + fn set_setup_data(&self, file_name: String, data: T) -> SourceResult<()> { + LocalFileDataSource::write_pretty( + format!("{}/{}.json", self.setup_data_location, file_name), + data, + ) + } + + /// creates folders if missing + pub fn create_folders_for_storing_data(&self) { + let subfolders = ["/base_layer", "/recursion_layer", "/aux_layer"]; + + for subfolder in subfolders.iter() { + let dir_location = format!("{}{}", self.setup_data_location, subfolder); + if std::fs::read_dir(&dir_location).is_err() { + std::fs::create_dir_all(dir_location).unwrap(); + } + + let dir_location = format!("{}{}", self.block_data_location, subfolder); + if std::fs::read_dir(&dir_location).is_err() { + std::fs::create_dir_all(dir_location).unwrap(); + } + } + } + pub fn write_pretty(filepath: String, proof: T) -> SourceResult<()> { + std::fs::write(&filepath, serde_json::to_string_pretty(&proof).unwrap()) + .map_err(|el| Box::new(el) as Box)?; + Ok(()) + } +} + +impl SetupDataSource for LocalFileDataSource { + fn get_base_layer_vk(&self, circuit_type: u8) -> SourceResult { + self.get_setup_data(format!("base_layer/vk_{}", circuit_type)) + } + fn get_base_layer_finalization_hint( + &self, + circuit_type: u8, + ) -> SourceResult { + self.get_setup_data(format!("base_layer/finalization_hint_{}", circuit_type)) + } + fn get_recursion_layer_vk( + &self, + circuit_type: u8, + ) -> SourceResult { + self.get_setup_data(format!("recursion_layer/vk_{}", circuit_type)) + } + fn get_recursion_layer_node_vk(&self) -> SourceResult { + self.get_setup_data("recursion_layer/vk_node".to_string()) + } + fn get_recursion_layer_finalization_hint( + &self, + circuit_type: u8, + ) -> SourceResult { + self.get_setup_data(format!( + "recursion_layer/finalization_hint_{}", + circuit_type + )) + } + fn get_recursion_layer_node_finalization_hint( + &self, + ) -> SourceResult { + self.get_setup_data("recursion_layer/finalization_hint_node".to_string()) + } + + fn get_compression_vk( + &self, + circuit_type: u8, + ) -> SourceResult { + self.get_setup_data(format!("aux_layer/compression_vk_{}", circuit_type)) + } + fn get_compression_hint( + &self, + circuit_type: u8, + ) -> SourceResult { + self.get_setup_data(format!("aux_layer/compression_hint_{}", circuit_type)) + } + fn get_compression_for_wrapper_vk( + &self, + circuit_type: u8, + ) -> SourceResult { + self.get_setup_data(format!( + "aux_layer/compression_for_wrapper_vk_{}", + circuit_type + )) + } + fn get_compression_for_wrapper_hint( + &self, + circuit_type: u8, + ) -> SourceResult { + self.get_setup_data(format!( + "aux_layer/compression_for_wrapper_hint_{}", + circuit_type + )) + } + fn get_wrapper_setup(&self, circuit_type: u8) -> SourceResult { + println!("Read wrapper setup from file. Can take a while."); + let start = std::time::Instant::now(); + + let mut file = File::open(format!( + "{}/aux_layer/wrapper_setup_{}.setup", + self.setup_data_location, circuit_type + )) + .map_err(|el| Box::new(el) as Box)?; + + let result = + Arc::new(SnarkSetup::read(&mut file).map_err(|el| Box::new(el) as Box)?); + + let result = ZkSyncSnarkWrapperSetup::from_inner(circuit_type, result); + + println!("Wrapper setup read from file. Took {:?}", start.elapsed()); + + Ok(result) + } + fn get_wrapper_vk(&self, circuit_type: u8) -> SourceResult { + let mut file = File::open(format!( + "{}/aux_layer/wrapper_vk_{}.key", + self.setup_data_location, circuit_type + )) + .map_err(|el| Box::new(el) as Box)?; + + let result = ZkSyncSnarkWrapperVK::from_inner( + circuit_type, + SnarkVK::read(&mut file).map_err(|el| Box::new(el) as Box)?, + ); + + Ok(result) + } + + fn set_base_layer_vk(&mut self, vk: ZkSyncBaseLayerVerificationKey) -> SourceResult<()> { + let circuit_type = vk.numeric_circuit_type(); + self.set_setup_data(format!("base_layer/vk_{}", circuit_type), vk) + } + + fn set_base_layer_finalization_hint( + &mut self, + hint: ZkSyncBaseLayerFinalizationHint, + ) -> SourceResult<()> { + let circuit_type = hint.numeric_circuit_type(); + self.set_setup_data( + format!("base_layer/finalization_hint_{}", circuit_type), + hint, + ) + } + fn set_recursion_layer_vk( + &mut self, + vk: ZkSyncRecursionLayerVerificationKey, + ) -> SourceResult<()> { + let circuit_type = vk.numeric_circuit_type(); + self.set_setup_data(format!("recursion_layer/vk_{}", circuit_type), vk) + } + fn set_recursion_layer_node_vk( + &mut self, + vk: ZkSyncRecursionLayerVerificationKey, + ) -> SourceResult<()> { + self.set_setup_data("recursion_layer/vk_node".to_string(), vk) + } + + fn set_recursion_layer_finalization_hint( + &mut self, + hint: ZkSyncRecursionLayerFinalizationHint, + ) -> SourceResult<()> { + let circuit_type = hint.numeric_circuit_type(); + self.set_setup_data( + format!("recursion_layer/finalization_hint_{}", circuit_type), + hint, + ) + } + fn set_recursion_layer_node_finalization_hint( + &mut self, + hint: ZkSyncRecursionLayerFinalizationHint, + ) -> SourceResult<()> { + self.set_setup_data("recursion_layer/finalization_hint_node".to_string(), hint) + } + fn set_compression_vk( + &mut self, + vk: ZkSyncCompressionLayerVerificationKey, + ) -> SourceResult<()> { + let circuit_type = vk.numeric_circuit_type(); + self.set_setup_data(format!("aux_layer/compression_vk_{}", circuit_type), vk) + } + fn set_compression_hint( + &mut self, + hint: ZkSyncCompressionLayerFinalizationHint, + ) -> SourceResult<()> { + let circuit_type = hint.numeric_circuit_type(); + self.set_setup_data(format!("aux_layer/compression_hint_{}", circuit_type), hint) + } + fn set_compression_for_wrapper_vk( + &mut self, + vk: ZkSyncCompressionForWrapperVerificationKey, + ) -> SourceResult<()> { + let circuit_type = vk.numeric_circuit_type(); + self.set_setup_data( + format!("aux_layer/compression_for_wrapper_vk_{}", circuit_type), + vk, + ) + } + fn set_compression_for_wrapper_hint( + &mut self, + hint: ZkSyncCompressionForWrapperFinalizationHint, + ) -> SourceResult<()> { + let circuit_type = hint.numeric_circuit_type(); + self.set_setup_data( + format!("aux_layer/compression_for_wrapper_hint_{}", circuit_type), + hint, + ) + } + fn set_wrapper_setup(&mut self, setup: ZkSyncSnarkWrapperSetup) -> SourceResult<()> { + println!("Writing wrapper setup to file. Can take a while."); + let start = std::time::Instant::now(); + + let circuit_type = setup.numeric_circuit_type(); + let mut file = File::create(format!( + "{}/aux_layer/wrapper_setup_{}.setup", + self.setup_data_location, circuit_type + )) + .map_err(|el| Box::new(el) as Box)?; + + setup + .into_inner() + .write(&mut file) + .map_err(|el| Box::new(el) as Box)?; + + println!("Wrapper setup written to file. Took {:?}", start.elapsed()); + + Ok(()) + } + fn set_wrapper_vk(&mut self, vk: ZkSyncSnarkWrapperVK) -> SourceResult<()> { + let circuit_type = vk.numeric_circuit_type(); + let mut file = File::create(format!( + "{}/aux_layer/wrapper_vk_{}.key", + self.setup_data_location, circuit_type + )) + .map_err(|el| Box::new(el) as Box)?; + + vk.into_inner() + .write(&mut file) + .map_err(|el| Box::new(el) as Box)?; + + Ok(()) + } + + fn get_recursion_tip_vk(&self) -> SourceResult { + self.get_setup_data("recursion_layer/vk_recursion_tip".to_string()) + } + fn get_recursion_tip_finalization_hint( + &self, + ) -> SourceResult { + self.get_setup_data("recursion_layer/finalization_hint_recursion_tip".to_string()) + } + fn set_recursion_tip_vk( + &mut self, + vk: ZkSyncRecursionLayerVerificationKey, + ) -> SourceResult<()> { + self.set_setup_data("recursion_layer/vk_recursion_tip".to_string(), vk) + } + fn set_recursion_tip_finalization_hint( + &mut self, + hint: ZkSyncRecursionLayerFinalizationHint, + ) -> SourceResult<()> { + self.set_setup_data( + "recursion_layer/finalization_hint_recursion_tip".to_string(), + hint, + ) + } +} + +impl BlockDataSource for LocalFileDataSource { + fn get_base_layer_proof( + &self, + circuit_type: u8, + index: usize, + ) -> SourceResult { + self.get_proof(format!( + "base_layer/basic_circuit_proof_{}_{}", + circuit_type, index + )) + } + + fn get_leaf_layer_proof( + &self, + circuit_type: u8, + index: usize, + ) -> SourceResult { + self.get_proof(format!( + "recursion_layer/leaf_layer_proof_{}_{}", + circuit_type, index + )) + } + fn get_node_layer_proof( + &self, + circuit_type: u8, + step: usize, + index: usize, + ) -> SourceResult { + self.get_proof(format!( + "recursion_layer/node_layer_proof_{}_{}_{}", + circuit_type, step, index + )) + } + + fn get_scheduler_proof(&self) -> SourceResult { + self.get_proof("recursion_layer/scheduler_proof".to_string()) + } + fn get_compression_proof(&self, circuit_type: u8) -> SourceResult { + self.get_proof(format!("aux_layer/compression_proof_{}", circuit_type)) + } + + fn get_compression_for_wrapper_proof( + &self, + circuit_type: u8, + ) -> SourceResult { + self.get_proof(format!( + "aux_layer/compression_for_wrapper_proof_{}", + circuit_type + )) + } + fn get_wrapper_proof(&self, circuit_type: u8) -> SourceResult { + let mut file = File::open(format!( + "{}/aux_layer/wrapper_proof_{}.proof", + self.block_data_location, circuit_type + )) + .map_err(|el| Box::new(el) as Box)?; + + let result = ZkSyncSnarkWrapperProof::from_inner( + circuit_type, + SnarkProof::read(&mut file).map_err(|el| Box::new(el) as Box)?, + ); + + Ok(result) + } + + fn set_base_layer_proof( + &mut self, + index: usize, + proof: ZkSyncBaseLayerProof, + ) -> SourceResult<()> { + let circuit_type = proof.numeric_circuit_type(); + self.set_proof( + format!("base_layer/basic_circuit_proof_{}_{}", circuit_type, index), + proof, + ) + } + + fn set_leaf_layer_proof( + &mut self, + index: usize, + proof: ZkSyncRecursionLayerProof, + ) -> SourceResult<()> { + let circuit_type = proof.numeric_circuit_type(); + self.set_proof( + format!( + "recursion_layer/leaf_layer_proof_{}_{}", + circuit_type, index + ), + proof, + ) + } + fn set_node_layer_proof( + &mut self, + circuit_type: u8, + step: usize, + index: usize, + proof: ZkSyncRecursionLayerProof, + ) -> SourceResult<()> { + self.set_proof( + format!( + "recursion_layer/node_layer_proof_{}_{}_{}", + circuit_type, step, index + ), + proof, + ) + } + fn set_scheduler_proof(&mut self, proof: ZkSyncRecursionLayerProof) -> SourceResult<()> { + self.set_proof("recursion_layer/scheduler_proof".to_string(), proof) + } + fn set_compression_proof(&mut self, proof: ZkSyncCompressionLayerProof) -> SourceResult<()> { + let circuit_type = proof.numeric_circuit_type(); + self.set_proof( + format!("aux_layer/compression_proof_{}", circuit_type), + proof, + ) + } + fn set_compression_for_wrapper_proof( + &mut self, + proof: ZkSyncCompressionForWrapperProof, + ) -> SourceResult<()> { + let circuit_type = proof.numeric_circuit_type(); + self.set_proof( + format!("aux_layer/compression_for_wrapper_proof_{}", circuit_type), + proof, + ) + } + fn set_wrapper_proof(&mut self, proof: ZkSyncSnarkWrapperProof) -> SourceResult<()> { + let circuit_type = proof.numeric_circuit_type(); + let mut file = File::create(format!( + "{}/aux_layer/wrapper_proof_{}.proof", + self.block_data_location, circuit_type + )) + .map_err(|el| Box::new(el) as Box)?; + + proof + .into_inner() + .write(&mut file) + .map_err(|el| Box::new(el) as Box)?; + + Ok(()) + } + fn set_recursive_tip_proof(&mut self, proof: ZkSyncRecursionLayerProof) -> SourceResult<()> { + self.set_proof("recursion_layer/recursive_tip_proof".to_string(), proof) + } + + fn get_recursive_tip_proof(&self) -> SourceResult { + self.get_proof("recursion_layer/recursive_tip_proof".to_string()) + } +} diff --git a/crates/zkevm_test_harness/src/data_source/mod.rs b/crates/zkevm_test_harness/src/data_source/mod.rs new file mode 100644 index 0000000..6b48dce --- /dev/null +++ b/crates/zkevm_test_harness/src/data_source/mod.rs @@ -0,0 +1,154 @@ +use std::error::Error; + +use circuit_definitions::boojum::cs::implementations::setup::FinalizationHintsForProver; +use circuit_definitions::circuit_definitions::aux_layer::*; +use circuit_definitions::circuit_definitions::base_layer::*; +use circuit_definitions::circuit_definitions::recursion_layer::*; + +pub type SourceResult = Result>; +pub mod in_memory_data_source; +pub mod local_file_data_source; + +// Object save trait to just get things for SYSTEM +pub trait SetupDataSource { + fn get_base_layer_vk(&self, circuit_type: u8) -> SourceResult; + fn get_base_layer_finalization_hint( + &self, + circuit_type: u8, + ) -> SourceResult; + fn get_recursion_layer_vk( + &self, + circuit_type: u8, + ) -> SourceResult; + fn get_recursion_layer_node_vk(&self) -> SourceResult; + fn get_recursion_tip_vk(&self) -> SourceResult; + fn get_recursion_layer_finalization_hint( + &self, + circuit_type: u8, + ) -> SourceResult; + fn get_recursion_layer_node_finalization_hint( + &self, + ) -> SourceResult; + fn get_recursion_tip_finalization_hint( + &self, + ) -> SourceResult; + + fn get_compression_vk( + &self, + circuit_type: u8, + ) -> SourceResult; + fn get_compression_hint( + &self, + circuit_type: u8, + ) -> SourceResult; + fn get_compression_for_wrapper_vk( + &self, + circuit_type: u8, + ) -> SourceResult; + fn get_compression_for_wrapper_hint( + &self, + circuit_type: u8, + ) -> SourceResult; + fn get_wrapper_setup(&self, circuit_type: u8) -> SourceResult; + fn get_wrapper_vk(&self, circuit_type: u8) -> SourceResult; + + fn set_base_layer_vk(&mut self, vk: ZkSyncBaseLayerVerificationKey) -> SourceResult<()>; + fn set_base_layer_finalization_hint( + &mut self, + hint: ZkSyncBaseLayerFinalizationHint, + ) -> SourceResult<()>; + fn set_recursion_layer_vk( + &mut self, + vk: ZkSyncRecursionLayerVerificationKey, + ) -> SourceResult<()>; + fn set_recursion_layer_node_vk( + &mut self, + vk: ZkSyncRecursionLayerVerificationKey, + ) -> SourceResult<()>; + fn set_recursion_tip_vk(&mut self, vk: ZkSyncRecursionLayerVerificationKey) + -> SourceResult<()>; + fn set_recursion_layer_finalization_hint( + &mut self, + hint: ZkSyncRecursionLayerFinalizationHint, + ) -> SourceResult<()>; + fn set_recursion_layer_node_finalization_hint( + &mut self, + hint: ZkSyncRecursionLayerFinalizationHint, + ) -> SourceResult<()>; + fn set_recursion_tip_finalization_hint( + &mut self, + hint: ZkSyncRecursionLayerFinalizationHint, + ) -> SourceResult<()>; + + fn set_compression_vk(&mut self, vk: ZkSyncCompressionLayerVerificationKey) + -> SourceResult<()>; + fn set_compression_hint( + &mut self, + hint: ZkSyncCompressionLayerFinalizationHint, + ) -> SourceResult<()>; + fn set_compression_for_wrapper_vk( + &mut self, + vk: ZkSyncCompressionForWrapperVerificationKey, + ) -> SourceResult<()>; + fn set_compression_for_wrapper_hint( + &mut self, + hint: ZkSyncCompressionForWrapperFinalizationHint, + ) -> SourceResult<()>; + fn set_wrapper_setup(&mut self, setup: ZkSyncSnarkWrapperSetup) -> SourceResult<()>; + fn set_wrapper_vk(&mut self, vk: ZkSyncSnarkWrapperVK) -> SourceResult<()>; +} + +// Object save trait to just get things for BLOCK +pub trait BlockDataSource { + fn get_base_layer_proof( + &self, + circuit_type: u8, + index: usize, + ) -> SourceResult; + fn get_leaf_layer_proof( + &self, + circuit_type: u8, + index: usize, + ) -> SourceResult; + fn get_node_layer_proof( + &self, + circuit_type: u8, + step: usize, + index: usize, + ) -> SourceResult; + fn get_scheduler_proof(&self) -> SourceResult; + fn get_compression_proof(&self, circuit_type: u8) -> SourceResult; + fn get_compression_for_wrapper_proof( + &self, + circuit_type: u8, + ) -> SourceResult; + fn get_wrapper_proof(&self, circuit_type: u8) -> SourceResult; + + fn set_base_layer_proof( + &mut self, + index: usize, + proof: ZkSyncBaseLayerProof, + ) -> SourceResult<()>; + fn set_leaf_layer_proof( + &mut self, + index: usize, + proof: ZkSyncRecursionLayerProof, + ) -> SourceResult<()>; + fn set_node_layer_proof( + &mut self, + circuit_type: u8, + step: usize, + index: usize, + proof: ZkSyncRecursionLayerProof, + ) -> SourceResult<()>; + fn set_scheduler_proof(&mut self, proof: ZkSyncRecursionLayerProof) -> SourceResult<()>; + fn set_compression_proof(&mut self, proof: ZkSyncCompressionLayerProof) -> SourceResult<()>; + fn set_compression_for_wrapper_proof( + &mut self, + proof: ZkSyncCompressionForWrapperProof, + ) -> SourceResult<()>; + fn set_wrapper_proof(&mut self, proof: ZkSyncSnarkWrapperProof) -> SourceResult<()>; + + fn set_recursive_tip_proof(&mut self, proof: ZkSyncRecursionLayerProof) -> SourceResult<()>; + fn get_recursive_tip_proof(&self) -> SourceResult; +} diff --git a/crates/zkevm_test_harness/src/debug.rs b/crates/zkevm_test_harness/src/debug.rs new file mode 100644 index 0000000..a969546 --- /dev/null +++ b/crates/zkevm_test_harness/src/debug.rs @@ -0,0 +1,167 @@ +//! +//! The methods in this file allows you to debug failing circuits from production. +//! Just pass the necessary contents of .bin file into the debug_basic or debug_recursive. +use crate::ethereum_types::U256; +use crate::{ + proof_wrapper_utils::{wrap_proof, WrapperConfig}, + prover_utils::verify_recursion_layer_proof_for_type, + tests::{base_test_circuit, test_recursive_circuit}, +}; +use circuit_definitions::boojum::cs::implementations::pow::NoPow; +use circuit_definitions::circuit_definitions::{ + base_layer::{ZkSyncBaseLayerCircuit, ZkSyncBaseLayerProof}, + recursion_layer::{ + ZkSyncRecursionLayerProof, ZkSyncRecursionLayerStorageType, + ZkSyncRecursionLayerVerificationKey, ZkSyncRecursiveLayerCircuit, + }, +}; +use std::io::Read; + +#[derive(serde::Serialize, serde::Deserialize)] +pub enum CircuitWrapper { + Base(ZkSyncBaseLayerCircuit), + Recursive(ZkSyncRecursiveLayerCircuit), +} + +pub fn debug_circuit(buffer: &[u8]) { + let circuit: CircuitWrapper = bincode::deserialize(&buffer).unwrap(); + match circuit { + CircuitWrapper::Base(basic_circuit) => debug_basic_circuit(basic_circuit), + CircuitWrapper::Recursive(recursive_circuit) => debug_recursive_circuit(recursive_circuit), + } +} + +fn debug_basic_circuit(circuit: ZkSyncBaseLayerCircuit) { + let mut circuit = circuit.clone(); + match &mut circuit { + ZkSyncBaseLayerCircuit::MainVM(inner) => { + let witness = inner.clone_witness().unwrap(); + dbg!( + witness + .closed_form_input + .hidden_fsm_input + .context_composite_u128 + ); + dbg!( + witness + .closed_form_input + .hidden_fsm_output + .context_composite_u128 + ); + } + ZkSyncBaseLayerCircuit::CodeDecommittmentsSorter(inner) => { + let witness = inner.clone_witness().unwrap(); + let _current_config = (*inner.config).clone(); + dbg!(_current_config); + inner.config = std::sync::Arc::new(117500); + dbg!(&*inner.config); + + assert_eq!(witness.closed_form_input.start_flag, true); + assert_eq!(witness.closed_form_input.completion_flag, true); + + let initial_items = witness.initial_queue_witness.elements; + let sorted_items = witness.sorted_queue_witness.elements; + dbg!(initial_items.len()); + dbg!(sorted_items.len()); + + let mut tmp: Vec<_> = initial_items.clone().into(); + tmp.sort_by(|a, b| match a.0.code_hash.cmp(&b.0.code_hash) { + std::cmp::Ordering::Equal => a.0.timestamp.cmp(&b.0.timestamp), + a @ _ => a, + }); + + let other: Vec<_> = sorted_items.clone().into(); + + for (idx, (a, b)) in tmp.into_iter().zip(other.into_iter()).enumerate() { + assert_eq!(a.0, b.0, "failed at index {}", idx); + } + + // self-check that we had a proper oracle + let mut tmp: Option<(U256, u32, u32)> = None; + for (query, _) in sorted_items.iter() { + if let Some((hash, page, timestamp)) = tmp.as_mut() { + if *hash == query.code_hash { + assert_eq!(*page, query.page); + assert!(query.timestamp > *timestamp); + } else { + assert!(query.code_hash >= *hash); + *hash = query.code_hash; + *page = query.page; + *timestamp = query.timestamp; + } + } else { + tmp = Some((query.code_hash, query.page, query.timestamp)); + } + } + } + ZkSyncBaseLayerCircuit::KeccakRoundFunction(inner) => { + let witness = inner.clone_witness().unwrap(); + let requests: Vec<_> = witness + .requests_queue_witness + .elements + .iter() + .map(|el| el.0.clone()) + .collect(); + dbg!(requests); + } + _ => {} + } + + base_test_circuit(circuit); +} + +fn debug_recursive_circuit(circuit: ZkSyncRecursiveLayerCircuit) { + match &circuit { + ZkSyncRecursiveLayerCircuit::SchedulerCircuit(_) => { + // dbg!(&inner.witness.leaf_layer_parameters); + // for el in inner.witness.proof_witnesses.iter() { + // let vk = inner.witness.node_layer_vk_witness.clone(); + // // let vk = ZkSyncRecursionLayerVerificationKey::from_inner(ZkSyncRecursionLayerStorageType::NodeLayerCircuit as u8, vk); + // // let proof = ZkSyncRecursionLayerProof::from_inner(ZkSyncRecursionLayerStorageType::NodeLayerCircuit as u8, el.clone()); + // let valid = verify_recursion_layer_proof_for_type::( + // ZkSyncRecursionLayerStorageType::NodeLayerCircuit, + // el, + // &vk, + // ); + // assert!(valid); + // } + panic!("Scheduler circuit not supported yet"); + } + ZkSyncRecursiveLayerCircuit::NodeLayerCircuit(inner) => { + let vk = inner.witness.vk_witness.clone(); + for el in inner.witness.proof_witnesses.iter() { + // let vk = ZkSyncRecursionLayerVerificationKey::from_inner(ZkSyncRecursionLayerStorageType::NodeLayerCircuit as u8, vk); + // let proof = ZkSyncRecursionLayerProof::from_inner(ZkSyncRecursionLayerStorageType::NodeLayerCircuit as u8, el.clone()); + let valid = verify_recursion_layer_proof_for_type::( + ZkSyncRecursionLayerStorageType::NodeLayerCircuit, + el, + &vk, + ); + assert!(valid); + } + } + ZkSyncRecursiveLayerCircuit::RecursionTipCircuit(inner) => { + let vk = inner.witness.vk_witness.clone(); + println!( + "Got {:?} proofs to verify", + inner.witness.proof_witnesses.len() + ); + for (i, el) in inner.witness.proof_witnesses.iter().enumerate() { + println!("Proof {:?} Starting verification", i); + let valid = verify_recursion_layer_proof_for_type::( + ZkSyncRecursionLayerStorageType::NodeLayerCircuit, + el, + &vk, + ); + assert!(valid); + println!("Proof {:?} OK", i); + } + } + + _ => { + panic!("Other recursion circuit types not supported yet"); + } + } + + test_recursive_circuit(circuit); +} diff --git a/crates/zkevm_test_harness/src/entry_point.rs b/crates/zkevm_test_harness/src/entry_point.rs new file mode 100644 index 0000000..f1ed20b --- /dev/null +++ b/crates/zkevm_test_harness/src/entry_point.rs @@ -0,0 +1,53 @@ +use crate::zk_evm::aux_structures::*; +use crate::zk_evm::ethereum_types::*; +use crate::zk_evm::vm_state::CallStackEntry; +use crate::zk_evm::zkevm_opcode_defs::system_params::INITIAL_FRAME_FORMAL_EH_LOCATION; +use crate::zk_evm::zkevm_opcode_defs::*; + +use super::*; + +// Define initial contexts to work with + +pub fn initial_out_of_circuit_context( + initial_pc: u16, + initial_ergs: u32, + this_address: Address, + msg_sender: Address, + code_address: Address, +) -> CallStackEntry { + CallStackEntry { + this_address, + msg_sender, + code_address, + base_memory_page: MemoryPage(zk_evm::zkevm_opcode_defs::BOOTLOADER_BASE_PAGE), + code_page: MemoryPage(zk_evm::zkevm_opcode_defs::BOOTLOADER_CODE_PAGE), + sp: INITIAL_SP_ON_FAR_CALL as u16, + pc: initial_pc, + exception_handler_location: INITIAL_FRAME_FORMAL_EH_LOCATION, + ergs_remaining: initial_ergs, + this_shard_id: 0, + caller_shard_id: 0, + code_shard_id: 0, + is_static: false, + is_local_frame: false, + context_u128_value: 0, + heap_bound: u32::MAX, // so bootloader doesn't pay for resizes + aux_heap_bound: u32::MAX, // so bootloader doesn't pay for resizes + total_pubdata_spent: PubdataCost(0i32), + stipend: 0, + } +} + +use crate::zk_evm::block_properties::BlockProperties; + +pub fn create_out_of_circuit_global_context( + zkporter_is_available: bool, + default_aa_code_hash: U256, + evm_simulator_code_hash: U256, +) -> BlockProperties { + BlockProperties { + default_aa_code_hash, + zkporter_is_available, + evm_simulator_code_hash, + } +} diff --git a/crates/zkevm_test_harness/src/external_calls.rs b/crates/zkevm_test_harness/src/external_calls.rs new file mode 100644 index 0000000..a0e2aa5 --- /dev/null +++ b/crates/zkevm_test_harness/src/external_calls.rs @@ -0,0 +1,86 @@ +use crate::blake2::Blake2s256; +use crate::ethereum_types::{Address, U256}; +use crate::run_vms::{run_vms, RunVMsResult, RunVmError}; +pub use crate::run_vms::SCHEDULER_TIMESTAMP; +use crate::snark_wrapper::boojum::field::goldilocks::GoldilocksExt2; +use crate::snark_wrapper::boojum::gadgets::recursion::recursive_tree_hasher::CircuitGoldilocksPoseidon2Sponge; +use crate::toolset::GeometryConfig; +use crate::witness::oracle::WitnessGenerationArtifact; +use crate::witness::tree::BinarySparseStorageTree; +use crate::witness::tree::ZkSyncStorageLeaf; +use crate::zk_evm::abstractions::Storage; +use crate::zk_evm::GenericNoopTracer; +use crate::zkevm_circuits::scheduler::block_header::BlockAuxilaryOutputWitness; +use crate::zkevm_circuits::scheduler::{ + block_header::MAX_4844_BLOBS_PER_BLOCK, input::SchedulerCircuitInstanceWitness, +}; +use circuit_definitions::boojum::field::Field; +use circuit_definitions::circuit_definitions::base_layer::ZkSyncBaseLayerCircuit; +use circuit_definitions::encodings::recursion_request::RecursionQueueSimulator; +use circuit_definitions::snark_wrapper::franklin_crypto::plonk::circuit::verifier_circuit::affine_point_wrapper::aux_data; +use circuit_definitions::zkevm_circuits::fsm_input_output::ClosedFormInputCompactFormWitness; +use circuit_definitions::Field as MainField; + +/// Executes a given set of instructions, and returns things necessary to do the proving: +/// - all circuits as a callback +/// - circuit recursion queues and associated inputs as a callback +/// - partial witness for the scheduler circuit (later we have to add proof witnesses for the nodes) +/// - witness with AUX data (with information that might be useful during verification to generate the public input) +/// +/// This function will setup the environment and will run out-of-circuit and then in-circuit. +/// GenericNoopTracer will be used as out-of-circuit tracer +pub fn run( + caller: Address, // for real block must be zero + entry_point_address: Address, // for real block must be the bootloader + entry_point_code: Vec<[u8; 32]>, // for read block must be a bootloader code + initial_heap_content: Vec, // bootloader starts with non-deterministic heap + zk_porter_is_available: bool, + default_aa_code_hash: U256, + evm_simulator_code_hash: U256, + used_bytecodes: std::collections::HashMap>, // auxilary information to avoid passing a full set of all used codes + ram_verification_queries: Vec<(u32, U256)>, // we may need to check that after the bootloader's memory is filled + cycle_limit: usize, + geometry: GeometryConfig, + storage: S, + tree: impl BinarySparseStorageTree<256, 32, 32, 8, 32, Blake2s256, ZkSyncStorageLeaf>, + trusted_setup_path: &str, + eip_4844_repack_inputs: [Option>; MAX_4844_BLOBS_PER_BLOCK], + artifacts_callback: CB, +) -> ( + SchedulerCircuitInstanceWitness, + BlockAuxilaryOutputWitness, +) { + let mut out_of_circuit_tracer = GenericNoopTracer::<_>::new(); + match run_vms( + caller, + entry_point_address, + entry_point_code, + initial_heap_content, + zk_porter_is_available, + default_aa_code_hash, + evm_simulator_code_hash, + used_bytecodes, + ram_verification_queries, + cycle_limit, + geometry, + storage, + tree, + trusted_setup_path, + eip_4844_repack_inputs, + artifacts_callback, + &mut out_of_circuit_tracer, + ) { + Ok((scheduler_circuit_witness, aux_data)) => (scheduler_circuit_witness, aux_data), + Err(err) => { + let error_text = match err { + RunVmError::InvalidInput(msg) => { + format!("Invalid input error: {msg}") + } + RunVmError::OutOfCircuitExecutionError(msg) => { + format!("Out-of-circuit execution error: {msg}") + } + }; + panic!("{error_text}"); + } + } +} diff --git a/crates/zkevm_test_harness/src/geometry_config_generator/main.rs b/crates/zkevm_test_harness/src/geometry_config_generator/main.rs new file mode 100644 index 0000000..6ce0e5e --- /dev/null +++ b/crates/zkevm_test_harness/src/geometry_config_generator/main.rs @@ -0,0 +1,156 @@ +use std::fs::File; +use std::io::Write; + +use codegen::Scope; +use rayon::prelude::*; + +use zkevm_test_harness::capacity_estimator::{ + code_decommitter_capacity, code_decommittments_sorter_capacity, ecrecover_capacity, + event_sorter_capacity, keccak256_rf_capacity, l1_messages_hasher_capacity, + log_demuxer_capacity, main_vm_capacity, ram_permutation_capacity, secp256r1_verify_capacity, + sha256_rf_capacity, storage_application_capacity, storage_sorter_capacity, + transient_storage_sorter_capacity, +}; +use zkevm_test_harness::toolset::GeometryConfig; + +fn save_geometry_config_file(geometry_config: String, filepath: &str) { + let file_content = + "// This file is auto-generated, do not edit it manually\n\n".to_owned() + &geometry_config; + let mut f = File::create(filepath).expect("Unable to create file"); + f.write_all(file_content.as_bytes()) + .expect("Unable to write data"); +} + +fn all_runners() -> Vec usize + Send>> { + vec![ + Box::new(main_vm_capacity), + Box::new(code_decommittments_sorter_capacity), + Box::new(code_decommitter_capacity), + Box::new(log_demuxer_capacity), + Box::new(keccak256_rf_capacity), + Box::new(sha256_rf_capacity), + Box::new(ecrecover_capacity), + Box::new(ram_permutation_capacity), + Box::new(event_sorter_capacity), + Box::new(storage_sorter_capacity), + Box::new(storage_application_capacity), + Box::new(l1_messages_hasher_capacity), + Box::new(transient_storage_sorter_capacity), + Box::new(secp256r1_verify_capacity), + ] +} + +pub fn compute_config() -> GeometryConfig { + let runners: Vec<_> = all_runners().into_iter().map(|el| (el, 0u32)).collect(); + let mut sizes = runners; + sizes.reverse(); + sizes.par_iter_mut().panic_fuse().for_each(|(func, size)| { + *size = (func)() as u32; + }); + + let mut sizes: Vec<_> = sizes.into_iter().map(|el| el.1).collect(); + + let cycles_per_vm_snapshot = sizes.pop().unwrap(); + let cycles_code_decommitter_sorter = sizes.pop().unwrap(); + let cycles_per_code_decommitter = sizes.pop().unwrap(); + let cycles_per_log_demuxer = sizes.pop().unwrap(); + let cycles_per_keccak256_circuit = sizes.pop().unwrap(); + let cycles_per_sha256_circuit = sizes.pop().unwrap(); + let cycles_per_ecrecover_circuit = sizes.pop().unwrap(); + let cycles_per_ram_permutation = sizes.pop().unwrap(); + let cycles_per_events_or_l1_messages_sorter = sizes.pop().unwrap(); + let cycles_per_storage_sorter = sizes.pop().unwrap(); + let cycles_per_storage_application = sizes.pop().unwrap(); + let limit_for_l1_messages_pudata_hasher = sizes.pop().unwrap(); + let cycles_per_transient_storage_sorter = sizes.pop().unwrap(); + let cycles_per_secp256r1_verify_circuit = sizes.pop().unwrap(); + + assert!(sizes.is_empty()); + + let config = GeometryConfig { + cycles_per_vm_snapshot, + cycles_code_decommitter_sorter, + cycles_per_log_demuxer, + cycles_per_storage_sorter, + cycles_per_events_or_l1_messages_sorter, + cycles_per_ram_permutation, + cycles_per_code_decommitter, + cycles_per_storage_application, + cycles_per_keccak256_circuit, + cycles_per_sha256_circuit, + cycles_per_ecrecover_circuit, + cycles_per_secp256r1_verify_circuit, + cycles_per_transient_storage_sorter, + limit_for_l1_messages_pudata_hasher, + }; + config +} + +fn main() { + let computed_config = compute_config(); + let mut scope = Scope::new(); + scope.import("crate::toolset", "GeometryConfig"); + let function = scope.new_fn("get_geometry_config"); + function.vis("pub const"); + function.ret("GeometryConfig"); + function.line("GeometryConfig {"); + function.line(format!( + " cycles_per_vm_snapshot: {},", + computed_config.cycles_per_vm_snapshot + )); + function.line(format!( + " cycles_code_decommitter_sorter: {},", + computed_config.cycles_code_decommitter_sorter + )); + function.line(format!( + " cycles_per_log_demuxer: {},", + computed_config.cycles_per_log_demuxer + )); + function.line(format!( + " cycles_per_storage_sorter: {},", + computed_config.cycles_per_storage_sorter + )); + function.line(format!( + " cycles_per_events_or_l1_messages_sorter: {},", + computed_config.cycles_per_events_or_l1_messages_sorter + )); + function.line(format!( + " cycles_per_ram_permutation: {},", + computed_config.cycles_per_ram_permutation + )); + function.line(format!( + " cycles_per_code_decommitter: {},", + computed_config.cycles_per_code_decommitter + )); + function.line(format!( + " cycles_per_storage_application: {},", + computed_config.cycles_per_storage_application + )); + function.line(format!( + " cycles_per_keccak256_circuit: {},", + computed_config.cycles_per_keccak256_circuit + )); + function.line(format!( + " cycles_per_sha256_circuit: {},", + computed_config.cycles_per_sha256_circuit + )); + function.line(format!( + " cycles_per_ecrecover_circuit: {},", + computed_config.cycles_per_ecrecover_circuit + )); + function.line(format!( + " limit_for_l1_messages_pudata_hasher: {},", + computed_config.limit_for_l1_messages_pudata_hasher + )); + function.line(format!( + " cycles_per_transient_storage_sorter: {},", + computed_config.cycles_per_transient_storage_sorter + )); + function.line(format!( + " cycles_per_secp256r1_verify_circuit: {},", + computed_config.cycles_per_secp256r1_verify_circuit + )); + function.line("}"); + println!("Generated config:\n {}", scope.to_string()); + save_geometry_config_file(scope.to_string(), "src/geometry_config/mod.rs"); +} diff --git a/crates/zkevm_test_harness/src/helper/artifact_utils.rs b/crates/zkevm_test_harness/src/helper/artifact_utils.rs new file mode 100644 index 0000000..561565d --- /dev/null +++ b/crates/zkevm_test_harness/src/helper/artifact_utils.rs @@ -0,0 +1,89 @@ +use crate::zk_evm::aux_structures::LogQuery; +use crate::zk_evm::ethereum_types::Address; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; + +use crate::blake2::Blake2s256; +use crate::ethereum_types::{H160, U256}; +use crate::witness::tree::{BinarySparseStorageTree, ZkSyncStorageLeaf}; +use crate::zk_evm::bytecode_to_code_hash; +use crate::zk_evm::testing::storage::InMemoryStorage; + +pub const ACCOUNT_CODE_STORAGE_ADDRESS: Address = H160([ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x02, +]); + +pub const KNOWN_CODE_HASHES_ADDRESS: Address = H160([ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x04, +]); + +pub fn save_predeployed_contracts( + storage: &mut InMemoryStorage, + tree: &mut impl BinarySparseStorageTree<256, 32, 32, 8, 32, Blake2s256, ZkSyncStorageLeaf>, + contracts: &HashMap>, +) { + let mut sorted_contracts = vec![]; + let mut keys: Vec<_> = contracts.keys().cloned().collect(); + keys.sort(); + for el in keys.into_iter() { + let v = contracts[&el].clone(); + + sorted_contracts.push((el, v)); + } + + let storage_logs: Vec<(u8, Address, U256, U256)> = sorted_contracts + .clone() + .into_iter() + .map(|(address, bytecode)| { + let hash = bytecode_to_code_hash(&bytecode).unwrap(); + + println!( + "Have address {:?} with code hash {:x}", + address, + U256::from(hash) + ); + + vec![ + ( + 0, + ACCOUNT_CODE_STORAGE_ADDRESS, + U256::from_big_endian(address.as_bytes()), + U256::from(hash), + ), + ( + 0, + KNOWN_CODE_HASHES_ADDRESS, + U256::from(hash), + U256::from(1u64), + ), + ] + }) + .flatten() + .collect(); + + storage.populate(storage_logs.clone()); + + for (shard_id, address, key, value) in storage_logs.into_iter() { + assert!(shard_id == 0); + let index = LogQuery::derive_final_address_for_params(&address, &key); + + use crate::witness::tree::EnumeratedBinaryLeaf; + let mut leaf = ZkSyncStorageLeaf::empty(); + let mut buffer = [0u8; 32]; + value.to_big_endian(&mut buffer); + leaf.set_value(&buffer); + + tree.insert_leaf(&index, leaf); + } +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct TestArtifact { + pub entry_point_address: Address, + pub entry_point_code: Vec<[u8; 32]>, + pub default_account_code: Vec<[u8; 32]>, + pub evm_simulator_code: Vec<[u8; 32]>, + pub predeployed_contracts: HashMap>, +} diff --git a/crates/zkevm_test_harness/src/helper/mod.rs b/crates/zkevm_test_harness/src/helper/mod.rs new file mode 100644 index 0000000..266b24e --- /dev/null +++ b/crates/zkevm_test_harness/src/helper/mod.rs @@ -0,0 +1,2 @@ +pub mod artifact_utils; +pub mod serialize_utils; diff --git a/crates/zkevm_test_harness/src/helper/serialize_utils.rs b/crates/zkevm_test_harness/src/helper/serialize_utils.rs new file mode 100644 index 0000000..22128f8 --- /dev/null +++ b/crates/zkevm_test_harness/src/helper/serialize_utils.rs @@ -0,0 +1,55 @@ +use crate::zk_evm::ethereum_types::Address; +use serde::{de, Deserialize}; +use std::{collections::HashMap, str::FromStr}; + +pub fn hex_string_to_bytecode<'de, D>(deserialized_string: &str) -> Result, D::Error> +where + D: serde::Deserializer<'de>, +{ + let result = if let Some(deserialized_string) = deserialized_string.strip_prefix("0x") { + hex::decode(&deserialized_string).map_err(de::Error::custom) + } else { + Err(de::Error::custom( + format!("string value missing prefix 0x",), + )) + }? + .chunks(32) + .map(|chunk| { + let mut res = [0u8; 32]; + res.copy_from_slice(chunk); + + res + }) + .collect(); + + Ok(result) +} + +pub fn deserialize_bytecode<'de, D>(deserializer: D) -> Result, D::Error> +where + D: serde::Deserializer<'de>, +{ + let deserialized_string = String::deserialize(deserializer)?; + + hex_string_to_bytecode::(&deserialized_string) +} + +pub fn deserialize_bytecodes_with_addresses<'de, D>( + deserializer: D, +) -> Result>, D::Error> +where + D: serde::Deserializer<'de>, +{ + let deserialized_strings: HashMap = HashMap::deserialize(deserializer)?; + let result: Result>, _> = deserialized_strings + .iter() + .map(|(key, value)| { + Ok(( + Address::from_str(key).unwrap(), + hex_string_to_bytecode::(value)?, + )) + }) + .collect(); + + result +} diff --git a/crates/zkevm_test_harness/src/lib.rs b/crates/zkevm_test_harness/src/lib.rs new file mode 100644 index 0000000..234c8ab --- /dev/null +++ b/crates/zkevm_test_harness/src/lib.rs @@ -0,0 +1,60 @@ +#![recursion_limit = "32"] +#![allow(dropping_references)] +#![feature(allocator_api)] +#![feature(array_chunks)] +#![feature(stmt_expr_attributes)] +#![feature(generic_const_exprs)] +#![feature(iter_array_chunks)] +#![feature(iter_next_chunk)] +#![feature(associated_type_defaults)] +#![feature(bigint_helper_methods)] +#![allow(unused_imports)] +#![allow(clippy::drop_ref)] + +use crate::boojum::field::goldilocks::GoldilocksField; +use crate::boojum::implementations::poseidon2::Poseidon2Goldilocks; + +pub use circuit_definitions::boojum; +pub use circuit_definitions::snark_wrapper; +pub use circuit_definitions::zk_evm; +pub use circuit_definitions::zkevm_circuits; +pub use rescue_poseidon::franklin_crypto; +pub use snark_wrapper::rescue_poseidon; + +pub use crate::zk_evm::blake2; +pub use crate::zk_evm::sha2; +pub use crate::zk_evm::sha3; + +pub mod data_source; +pub mod entry_point; +pub use circuit_sequencer_api::geometry_config; +pub use kzg; +pub mod prover_utils; +pub mod snark_wrapper_test; +pub mod utils; +pub mod witness; + +// Debugging tools (for example for failed proofs). +pub mod debug; + +pub use crate::zk_evm::ethereum_types; + +use self::utils::*; + +pub mod capacity_estimator; +pub mod external_calls; +pub mod toolset; +// pub mod circuit_limit_estimator; + +pub use circuit_sequencer_api::INITIAL_MONOTONIC_CYCLE_COUNTER; + +// #[cfg(test)] +pub mod helper; +pub(crate) mod tests; + +pub mod compute_setups; +pub mod proof_wrapper_utils; + +pub use tests::complex_tests::utils::empty_node_proof; + +mod run_vms; diff --git a/crates/zkevm_test_harness/src/proof_wrapper_utils/README.md b/crates/zkevm_test_harness/src/proof_wrapper_utils/README.md new file mode 100644 index 0000000..ba617f2 --- /dev/null +++ b/crates/zkevm_test_harness/src/proof_wrapper_utils/README.md @@ -0,0 +1,19 @@ +# Proof wrapping + +This directory is responsible for wrapping the final FRI proof into a SNARK. + +The main entry point is the `wrap_proof` method in mod.rs, that accepts the scheduler circuit proof. + +This method is handling both compression and wrapping. + +## Testing +End-to-end tests for proof compression are in proof_compression_tests.rs + +By default, they test multiple levels of compression based on the files located in testdata/proof_compression. + +If you need to update the files, please re-run the test with `UPDATE_TESTDATA` environment variable set: + + +``` +UPDATE_TESTDATA=true RUST_BACKTRACE=1 cargo test --release perform_step_4_compression -- --nocapture +``` \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/proof_wrapper_utils/compression.rs b/crates/zkevm_test_harness/src/proof_wrapper_utils/compression.rs new file mode 100644 index 0000000..54070ea --- /dev/null +++ b/crates/zkevm_test_harness/src/proof_wrapper_utils/compression.rs @@ -0,0 +1,143 @@ +use super::*; + +pub(crate) fn compute_compression_vks_and_write( + source: &mut DS, + config: WrapperConfig, + worker: &Worker, +) { + for circuit_type in config.get_compression_types() { + let vk = get_vk_for_previous_circuit(source, circuit_type).expect(&format!( + "VK of previous circuit should be present. Current circuit type: {}", + circuit_type + )); + + let compression_circuit = + ZkSyncCompressionLayerCircuit::from_witness_and_vk(None, vk, circuit_type); + let proof_config = compression_circuit.proof_config_for_compression_step(); + + let (_, _, vk, _, _, _, finalization_hint) = create_compression_layer_setup_data( + compression_circuit, + &worker, + proof_config.fri_lde_factor, + proof_config.merkle_tree_cap_size, + ); + + source + .set_compression_vk(ZkSyncCompressionLayerStorage::from_inner( + circuit_type, + vk.clone(), + )) + .unwrap(); + source + .set_compression_hint(ZkSyncCompressionLayerStorage::from_inner( + circuit_type, + finalization_hint.clone(), + )) + .unwrap(); + } +} + +pub(crate) fn compute_compression_circuits( + source: &mut DS, + config: WrapperConfig, + worker: &Worker, +) { + for circuit_type in config.get_compression_types() { + if source.get_compression_proof(circuit_type).is_err() + || source.get_compression_vk(circuit_type).is_err() + || source.get_compression_hint(circuit_type).is_err() + { + let proof = get_proof_for_previous_circuit(source, circuit_type).expect(&format!( + "Proof of previous circuit should be present. Current circuit type: {}", + circuit_type + )); + let vk = get_vk_for_previous_circuit(source, circuit_type).expect(&format!( + "VK of previous circuit should be present. Current circuit type: {}", + circuit_type + )); + + let compression_circuit = + ZkSyncCompressionLayerCircuit::from_witness_and_vk(Some(proof), vk, circuit_type); + + let (vk, finalization_hint, proof) = + compute_compression_circuit_inner(compression_circuit, &worker); + + source + .set_compression_vk(ZkSyncCompressionLayerStorage::from_inner( + circuit_type, + vk.clone(), + )) + .unwrap(); + source + .set_compression_hint(ZkSyncCompressionLayerStorage::from_inner( + circuit_type, + finalization_hint.clone(), + )) + .unwrap(); + source + .set_compression_proof(ZkSyncCompressionLayerStorage::from_inner( + circuit_type, + proof, + )) + .unwrap(); + } + } +} + +fn compute_compression_circuit_inner( + circuit: ZkSyncCompressionLayerCircuit, + worker: &Worker, +) -> ( + ZkSyncCompressionVerificationKey, + FinalizationHintsForProver, + ZkSyncCompressionProof, +) { + let start = std::time::Instant::now(); + + let circuit_type = circuit.numeric_circuit_type(); + + test_compression_circuit(circuit.clone()); + println!( + "Input circuit for compression {} is satisfied", + circuit_type + ); + + let proof_config = circuit.proof_config_for_compression_step(); + + let setup_circuit = circuit.clone_without_witness(); + let (setup_base, setup, vk, setup_tree, vars_hint, wits_hint, finalization_hint) = + create_compression_layer_setup_data( + setup_circuit.clone(), + &worker, + proof_config.fri_lde_factor, + proof_config.merkle_tree_cap_size, + ); + + // prove + println!("Proving compression level {} !", circuit_type); + + let proof = prove_compression_layer_circuit::( + circuit, + &worker, + proof_config, + &setup_base, + &setup, + &setup_tree, + &vk, + &vars_hint, + &wits_hint, + &finalization_hint, + ); + + let is_valid = verify_compression_layer_proof::(&setup_circuit, &proof, &vk); + + assert!(is_valid); + + println!( + "Compression {} is done, taken {:?}", + circuit_type, + start.elapsed() + ); + + (vk, finalization_hint, proof) +} diff --git a/crates/zkevm_test_harness/src/proof_wrapper_utils/compression_for_wrapper.rs b/crates/zkevm_test_harness/src/proof_wrapper_utils/compression_for_wrapper.rs new file mode 100644 index 0000000..4dc5b7a --- /dev/null +++ b/crates/zkevm_test_harness/src/proof_wrapper_utils/compression_for_wrapper.rs @@ -0,0 +1,153 @@ +use super::*; + +pub(crate) fn compute_compression_for_wrapper_vk_and_write< + DS: SetupDataSource + BlockDataSource, +>( + config: WrapperConfig, + source: &mut DS, + worker: &Worker, +) { + let compression_for_wrapper_type = config.get_compression_for_wrapper_type(); + let vk = get_vk_for_previous_circuit(source, compression_for_wrapper_type).unwrap(); + + let circuit = ZkSyncCompressionForWrapperCircuit::from_witness_and_vk( + None, + vk, + compression_for_wrapper_type, + ); + + let proof_config = circuit.proof_config_for_compression_step(); + + let (_, _, vk, _, _, _, finalization_hint) = create_compression_for_wrapper_setup_data( + circuit, + &worker, + proof_config.fri_lde_factor, + proof_config.merkle_tree_cap_size, + ); + + source + .set_compression_for_wrapper_vk(ZkSyncCompressionLayerStorage::from_inner( + compression_for_wrapper_type, + vk.clone(), + )) + .unwrap(); + source + .set_compression_for_wrapper_hint(ZkSyncCompressionLayerStorage::from_inner( + compression_for_wrapper_type, + finalization_hint.clone(), + )) + .unwrap(); +} + +pub(crate) fn compute_compression_for_wrapper_circuit( + source: &mut DS, + config: WrapperConfig, + worker: &Worker, +) { + let circuit_type = config.get_compression_for_wrapper_type(); + + if source.get_compression_for_wrapper_vk(circuit_type).is_err() + || source + .get_compression_for_wrapper_hint(circuit_type) + .is_err() + || source + .get_compression_for_wrapper_proof(circuit_type) + .is_err() + { + let proof = get_proof_for_previous_circuit(source, circuit_type).expect(&format!( + "Proof of previous circuit should be present. Current circuit type: {}", + circuit_type + )); + let vk = get_vk_for_previous_circuit(source, circuit_type).expect(&format!( + "VK of previous circuit should be present. Current circuit type: {}", + circuit_type + )); + + let compression_circuit = + ZkSyncCompressionForWrapperCircuit::from_witness_and_vk(Some(proof), vk, circuit_type); + + let (vk, finalization_hint, proof) = + compute_compression_for_wrapper_circuit_inner(compression_circuit, worker); + + // we did it above + source + .set_compression_for_wrapper_vk(ZkSyncCompressionLayerStorage::from_inner( + circuit_type, + vk.clone(), + )) + .unwrap(); + source + .set_compression_for_wrapper_hint(ZkSyncCompressionLayerStorage::from_inner( + circuit_type, + finalization_hint.clone(), + )) + .unwrap(); + source + .set_compression_for_wrapper_proof(ZkSyncCompressionLayerStorage::from_inner( + circuit_type, + proof, + )) + .unwrap(); + } +} + +fn compute_compression_for_wrapper_circuit_inner( + circuit: ZkSyncCompressionForWrapperCircuit, + worker: &Worker, +) -> ( + ZkSyncCompressionVerificationKeyForWrapper, + FinalizationHintsForProver, + ZkSyncCompressionProofForWrapper, +) { + let start = std::time::Instant::now(); + + let circuit_type = circuit.numeric_circuit_type(); + + test_compression_for_wrapper_circuit(circuit.clone()); + println!("Input Circuit for compression wrapper is satisfied"); + + let proof_config = circuit.proof_config_for_compression_step(); + + let setup_circuit = circuit.clone_without_witness(); + let (setup_base, setup, vk, setup_tree, vars_hint, wits_hint, finalization_hint) = + create_compression_for_wrapper_setup_data( + setup_circuit.clone(), + &worker, + proof_config.fri_lde_factor, + proof_config.merkle_tree_cap_size, + ); + + // prove + println!("Proving compression wrapper circuit."); + let now = std::time::Instant::now(); + + let proof = prove_compression_for_wrapper_circuit::( + circuit, + &worker, + proof_config, + &setup_base, + &setup, + &setup_tree, + &vk, + &vars_hint, + &wits_hint, + &finalization_hint, + ); + + println!( + "Proving compression wrapper is DONE, taken {:?}", + now.elapsed() + ); + + let is_valid = verify_compression_for_wrapper_proof::(&setup_circuit, &proof, &vk); + + assert!(is_valid); + + println!( + "Compression for wrapper {} is done, taken {:?}", + circuit_type, + start.elapsed() + ); + + (vk, finalization_hint, proof) +} diff --git a/crates/zkevm_test_harness/src/proof_wrapper_utils/mod.rs b/crates/zkevm_test_harness/src/proof_wrapper_utils/mod.rs new file mode 100644 index 0000000..9859898 --- /dev/null +++ b/crates/zkevm_test_harness/src/proof_wrapper_utils/mod.rs @@ -0,0 +1,184 @@ +use circuit_definitions::boojum::cs::implementations::pow::NoPow; +use circuit_definitions::boojum::cs::implementations::setup::FinalizationHintsForProver; +use circuit_definitions::boojum::field::goldilocks::GoldilocksField; +use circuit_definitions::boojum::field::{PrimeField as BoojumPrimeField, U64Representable}; +use circuit_definitions::circuit_definitions::aux_layer::{ZkSyncCompressionForWrapperCircuit, ZkSyncCompressionLayerCircuit, ZkSyncCompressionLayerStorage, ZkSyncCompressionProof, ZkSyncCompressionProofForWrapper, ZkSyncCompressionVerificationKey, ZkSyncCompressionVerificationKeyForWrapper, ZkSyncSnarkWrapperCircuit, ZkSyncSnarkWrapperProof, ZkSyncSnarkWrapperVK, ZkSyncSnarkWrapperSetup}; +use circuit_definitions::circuit_definitions::aux_layer::wrapper::ZkSyncCompressionWrapper; +use circuit_definitions::circuit_definitions::recursion_layer::{ZkSyncRecursionLayerProof, ZkSyncRecursionLayerStorageType, ZkSyncRecursionLayerVerificationKey}; +use circuit_definitions::zkevm_circuits::scheduler::NUM_SCHEDULER_PUBLIC_INPUTS; +use crate::snark_wrapper::franklin_crypto::bellman::kate_commitment::{Crs, CrsForMonomialForm}; +use crate::snark_wrapper::franklin_crypto::bellman::plonk::better_better_cs::cs::{Circuit, PlonkCsWidth4WithNextStepAndCustomGatesParams, TrivialAssembly, SetupAssembly, ProvingAssembly}; +use crate::snark_wrapper::franklin_crypto::bellman::plonk::better_better_cs::gates::selector_optimized_with_d_next::SelectorOptimizedWidth4MainGateWithDNext; +use crate::snark_wrapper::franklin_crypto::bellman::plonk::better_better_cs::proof::Proof as SnarkProof; +use crate::snark_wrapper::franklin_crypto::bellman::plonk::better_better_cs::setup::Setup as SnarkSetup; +use crate::snark_wrapper::franklin_crypto::bellman::plonk::better_better_cs::setup::VerificationKey as SnarkVK; +use crate::snark_wrapper::franklin_crypto::bellman::plonk::commitments::transcript::keccak_transcript::RollingKeccakTranscript; +use crate::snark_wrapper::franklin_crypto::bellman::worker::Worker as BellmanWorker; +use crate::snark_wrapper::implementations::poseidon2::CircuitPoseidon2Sponge; +use crate::snark_wrapper::implementations::poseidon2::transcript::CircuitPoseidon2Transcript; +use crate::snark_wrapper::verifier::WrapperCircuit; +use crate::franklin_crypto::bellman::pairing::bn256::{Bn256, Fr}; +use crate::franklin_crypto::bellman::{Field, PrimeField, PrimeFieldRepr}; +use circuit_definitions::circuit_definitions::aux_layer::*; +use crate::boojum::worker::Worker; + +pub type TreeHasherForWrapper = CircuitPoseidon2Sponge; +pub type TranscriptForWrapper = CircuitPoseidon2Transcript; + +pub const DEFAULT_WRAPPER_CONFIG: WrapperConfig = WrapperConfig { + compression_layers: 1, +}; + +use crate::data_source::in_memory_data_source::InMemoryDataSource; +use crate::data_source::{BlockDataSource, SetupDataSource, SourceResult}; +use crate::prover_utils::{ + create_compression_for_wrapper_setup_data, create_compression_layer_setup_data, + prove_compression_for_wrapper_circuit, prove_compression_layer_circuit, + verify_compression_for_wrapper_proof, verify_compression_layer_proof, + verify_recursion_layer_proof_for_type, +}; +use crate::tests::{test_compression_circuit, test_compression_for_wrapper_circuit}; + +use std::sync::Arc; + +#[cfg(test)] +mod proof_compression_test; + +mod compression; +mod compression_for_wrapper; +mod utils; +mod wrapper; + +pub use compression::*; +pub use compression_for_wrapper::*; +pub use utils::*; +pub use wrapper::*; + +/// Wrapper config is needed to specify how many compression layers should be done +/// So after we compute a scheduler proof we can compute a couple of compression proofs +/// The last one should be using Bn256 Poseidon2 hash for FRI +/// And then we can compute wrapper proof +/// +/// Example: Scheduler -> CompressionMode1 -> CompressionMode2 -> +/// -> CompressionMode3ForWrapper -> Wrapper +#[derive(Debug, Clone, Copy)] +pub struct WrapperConfig { + compression_layers: u8, +} + +impl WrapperConfig { + // For now we only support 1-5 compression layers + pub const MAX_COMPRESSION_LAYERS: u8 = 5; + + pub fn new(compression_layers: u8) -> Self { + assert!( + compression_layers > 0 && compression_layers <= Self::MAX_COMPRESSION_LAYERS, + "compression should be between 1 and 5" + ); + + Self { compression_layers } + } + + pub fn get_compression_types(&self) -> Vec { + (1..self.compression_layers).collect() + } + + pub fn get_compression_for_wrapper_type(&self) -> u8 { + self.compression_layers + } + + pub fn get_wrapper_type(&self) -> u8 { + self.compression_layers + } +} + +/// Computes wrapper proof and vk from scheduler proof and vk +/// We store all proofs and vks in the RAM +pub fn wrap_proof( + proof: ZkSyncRecursionLayerProof, + vk: ZkSyncRecursionLayerVerificationKey, + config: WrapperConfig, +) -> (ZkSyncSnarkWrapperProof, ZkSyncSnarkWrapperVK) { + // Check trusted setup exitance early, so that we fail quickly if it is not present. + check_trusted_setup_file_existace(); + let worker = Worker::new(); + let bellman_worker = BellmanWorker::new(); + + // Check circuit type correctness. + // We only support wrapping of the scheduler circuit. + assert_eq!( + vk.numeric_circuit_type(), + ZkSyncRecursionLayerStorageType::SchedulerCircuit as u8 + ); + assert_eq!( + proof.numeric_circuit_type(), + ZkSyncRecursionLayerStorageType::SchedulerCircuit as u8 + ); + + let valid = verify_recursion_layer_proof_for_type::( + ZkSyncRecursionLayerStorageType::SchedulerCircuit, + &proof.clone().into_inner(), + &vk.clone().into_inner(), + ); + assert!(valid, "Provided scheduler proof is not valid."); + + // Initialize RAM storage and upload scheduler proof and vk + let mut source = InMemoryDataSource::new(); + source + .set_scheduler_proof(proof) + .expect("Failed to set scheduler proof"); + source + .set_recursion_layer_vk(vk) + .expect("Failed to set scheduler vk"); + + // 1. All but one layers of compression with Goldilocks Poseidon2 hash + println!("Computing a sequence of compressing circuits"); + compute_compression_circuits(&mut source, config, &worker); + println!("Done computing a sequence of compressing circuits"); + // 2. Final compression with Bn256 Poseidon2 hash + println!("Computing a Boojum circuit using Bn256 Poseidon2 hash"); + compute_compression_for_wrapper_circuit(&mut source, config, &worker); + println!("Done computing a Boojum circuit using Bn256 Poseidon2 hash"); + // 3. Wrapper + println!("Computing a Bellman circuit over Bn256"); + compute_wrapper_proof_and_vk(&mut source, config, &bellman_worker); + println!("Done computing a Bellman circuit over Bn256"); + + // Get and return wrapper proof and vk + let wrapper_type = config.get_wrapper_type(); + ( + source.get_wrapper_proof(wrapper_type).unwrap(), + source.get_wrapper_vk(wrapper_type).unwrap(), + ) +} + +/// Computes wrapper vk from scheduler vk +/// We store all vks in the RAM +pub fn get_wrapper_setup_and_vk_from_scheduler_vk( + vk: ZkSyncRecursionLayerVerificationKey, + config: WrapperConfig, +) -> (ZkSyncSnarkWrapperSetup, ZkSyncSnarkWrapperVK) { + // Check trusted setup file for later + check_trusted_setup_file_existace(); + let worker = Worker::new(); + + // Check circuit type correctness + assert_eq!( + vk.numeric_circuit_type(), + ZkSyncRecursionLayerStorageType::SchedulerCircuit as u8 + ); + + // Initialize RAM storage and upload scheduler proof and vk + let mut source = InMemoryDataSource::new(); + source.set_recursion_layer_vk(vk).unwrap(); + + // 1. All but one layers of compression with Goldilocks Poseidon2 hash + compute_compression_vks_and_write(&mut source, config, &worker); + // 2. Final compression with Bn256 Poseidon2 hash + compute_compression_for_wrapper_vk_and_write(config, &mut source, &worker); + + // 3. Wrapper + let wrapper_type = config.get_wrapper_type(); + let wrapper_vk = source.get_compression_for_wrapper_vk(wrapper_type).unwrap(); + get_wrapper_setup_and_vk_from_compression_vk(wrapper_vk, config) +} diff --git a/crates/zkevm_test_harness/src/proof_wrapper_utils/proof_compression_test.rs b/crates/zkevm_test_harness/src/proof_wrapper_utils/proof_compression_test.rs new file mode 100644 index 0000000..e224add --- /dev/null +++ b/crates/zkevm_test_harness/src/proof_wrapper_utils/proof_compression_test.rs @@ -0,0 +1,398 @@ +#[cfg(test)] +mod test { + use std::alloc::Global; + + use crate::boojum::field::goldilocks::GoldilocksField; + use circuit_definitions::boojum::cs::implementations::pow::NoPow; + use circuit_definitions::boojum::cs::implementations::proof::Proof; + use circuit_definitions::boojum::cs::implementations::verifier::VerificationKey; + use circuit_definitions::circuit_definitions::aux_layer::{ + compression_modes::*, ZkSyncCompressionForWrapperProof, + ZkSyncCompressionForWrapperVerificationKey, ZkSyncCompressionLayerProof, + ZkSyncCompressionLayerStorage, ZkSyncCompressionLayerStorageType, + ZkSyncCompressionLayerVerificationKey, + }; + use circuit_definitions::{ + circuit_definitions::recursion_layer::ZkSyncRecursionLayerStorageType, + recursion_layer_proof_config, + }; + use serde::Serialize; + + use crate::boojum::algebraic_props::round_function::AbsorptionModeOverwrite; + use crate::boojum::algebraic_props::sponge::GoldilocksPoseidon2Sponge; + use crate::boojum::cs::implementations::transcript::GoldilocksPoisedon2Transcript; + use crate::boojum::field::goldilocks::GoldilocksExt2; + + use crate::boojum::config::DevCSConfig; + use crate::boojum::cs::cs_builder::new_builder; + use crate::boojum::cs::cs_builder_reference::CsReferenceImplementationBuilder; + use crate::boojum::cs::oracle::TreeHasher; + use crate::boojum::worker::Worker; + use crate::data_source::{ + local_file_data_source::LocalFileDataSource, BlockDataSource, SetupDataSource, + }; + use crate::zkevm_circuits::recursion::compression::CompressionRecursionConfig; + use circuit_definitions::circuit_definitions::aux_layer::compression::*; + use circuit_definitions::circuit_definitions::recursion_layer::verifier_builder::*; + + type F = GoldilocksField; + type P = GoldilocksField; + type TR = GoldilocksPoisedon2Transcript; + type EXT = GoldilocksExt2; + type H = GoldilocksPoseidon2Sponge; + + fn prove( + circuit: CompressionLayerCircuit, + ) -> ( + Proof::ThisLayerHasher, GoldilocksExt2>, + VerificationKey::ThisLayerHasher>, + ) + where + >::Output: + serde::Serialize + serde::de::DeserializeOwned, + { + let worker = Worker::new(); + + let geometry = circuit.geometry(); + let (max_trace_len, num_vars) = circuit.size_hint(); + let proof_config = CF::proof_config_for_compression_step(); + let transcript_params = CF::this_layer_transcript_parameters(); + + let builder_impl = CsReferenceImplementationBuilder::::new( + geometry, + max_trace_len.unwrap(), + ); + let builder = new_builder::<_, GoldilocksField>(builder_impl); + let builder = circuit.configure_builder_proxy(builder); + let mut cs_owned = builder.build(num_vars.unwrap()); + circuit.synthesize_into_cs(&mut cs_owned); + + cs_owned.pad_and_shrink(); + let mut assembly = cs_owned.into_assembly::(); + assembly.print_gate_stats(); + + assert!(assembly.check_if_satisfied(&worker)); + + let (proof, vk) = assembly + .prove_one_shot::( + &worker, + proof_config, + transcript_params, + ); + + (proof, vk) + } + + /// Saves the vk & proof (if UPDATE_TESTDATA is present in environment) - or verifies that proofs didn't change. + fn save_or_diff_compression( + mut source: LocalFileDataSource, + proof: ZkSyncCompressionLayerProof, + vk: ZkSyncCompressionLayerVerificationKey, + ) { + if std::env::var("UPDATE_TESTDATA").is_ok() { + source.set_compression_proof(proof).unwrap(); + source.set_compression_vk(vk).unwrap(); + } else { + let existing_proof = source + .get_compression_proof(proof.numeric_circuit_type()) + .unwrap(); + let existing_vk = source + .get_compression_vk(vk.numeric_circuit_type()) + .unwrap(); + + assert!( + bincode::serialize(&proof).unwrap() == bincode::serialize(&existing_proof).unwrap(), + "Proofs differ. Run with UPDATE_TESTDATA env variable to see the details." + ); + assert!( + bincode::serialize(&vk).unwrap() == bincode::serialize(&existing_vk).unwrap(), + "VK differ. Run with UPDATE_TESTDATA env variable to see the details." + ); + } + } + + fn save_or_diff_compression_wrapper( + mut source: LocalFileDataSource, + proof: ZkSyncCompressionForWrapperProof, + vk: ZkSyncCompressionForWrapperVerificationKey, + ) { + if std::env::var("UPDATE_TESTDATA").is_ok() { + source.set_compression_for_wrapper_proof(proof).unwrap(); + source.set_compression_for_wrapper_vk(vk).unwrap(); + } else { + let existing_proof = source + .get_compression_for_wrapper_proof(proof.numeric_circuit_type()) + .unwrap(); + let existing_vk = source + .get_compression_for_wrapper_vk(vk.numeric_circuit_type()) + .unwrap(); + + assert!( + bincode::serialize(&proof).unwrap() == bincode::serialize(&existing_proof).unwrap(), + "Proofs differ. Run with UPDATE_TESTDATA env variable to see the details." + ); + assert!( + bincode::serialize(&vk).unwrap() == bincode::serialize(&existing_vk).unwrap(), + "VK differ. Run with UPDATE_TESTDATA env variable to see the details." + ); + } + } + + #[test] + fn perform_step_1_compression() { + let source = LocalFileDataSource { + setup_data_location: "src/proof_wrapper_utils/testdata/proof_compression".to_string(), + block_data_location: "src/proof_wrapper_utils/testdata/proof_compression".to_string(), + }; + source.create_folders_for_storing_data(); + let proof = source.get_scheduler_proof().unwrap(); + let vk = source + .get_recursion_layer_vk(ZkSyncRecursionLayerStorageType::SchedulerCircuit as u8) + .unwrap(); + + let verifier_builder = dyn_verifier_builder_for_recursive_circuit_type( + ZkSyncRecursionLayerStorageType::SchedulerCircuit, + ); + let verifier = verifier_builder.create_verifier(); + let is_valid = verifier.verify::( + (), + &vk.clone().into_inner(), + &proof.clone().into_inner(), + ); + assert!(is_valid); + + // make a compression circuit + let circuit = CompressionMode1Circuit { + witness: Some(proof.clone().into_inner()), + config: CompressionRecursionConfig { + proof_config: recursion_layer_proof_config(), + verification_key: vk.into_inner(), + _marker: std::marker::PhantomData, + }, + transcript_params: (), + _marker: std::marker::PhantomData, + }; + + let (proof, vk) = prove(circuit); + save_or_diff_compression( + source, + ZkSyncCompressionLayerStorage::from_inner( + ZkSyncCompressionLayerStorageType::CompressionMode1Circuit as u8, + proof, + ), + ZkSyncCompressionLayerStorage::from_inner( + ZkSyncCompressionLayerStorageType::CompressionMode1Circuit as u8, + vk, + ), + ); + } + + #[test] + fn perform_step_2_compression() { + let source = LocalFileDataSource { + setup_data_location: "src/proof_wrapper_utils/testdata/proof_compression".to_string(), + block_data_location: "src/proof_wrapper_utils/testdata/proof_compression".to_string(), + }; + + let proof = source + .get_compression_proof(ZkSyncCompressionLayerStorageType::CompressionMode1Circuit as u8) + .unwrap() + .into_inner(); + + let vk = source + .get_compression_vk(ZkSyncCompressionLayerStorageType::CompressionMode1Circuit as u8) + .unwrap() + .into_inner(); + + let verifier_builder = CompressionMode1CircuitBuilder::dyn_verifier_builder(); + let verifier = verifier_builder.create_verifier(); + let is_valid = verifier.verify::< + ::ThisLayerHasher, + ::ThisLayerTranscript, + ::ThisLayerPoW, + >((), &vk, &proof.clone()); + assert!(is_valid); + + // make a compression circuit + let circuit = CompressionMode2Circuit { + witness: Some(proof.clone()), + config: CompressionRecursionConfig { + proof_config: CompressionMode1::proof_config_for_compression_step(), + verification_key: vk, + _marker: std::marker::PhantomData, + }, + transcript_params: (), + _marker: std::marker::PhantomData, + }; + + let (proof, vk) = prove(circuit); + save_or_diff_compression( + source, + ZkSyncCompressionLayerStorage::from_inner( + ZkSyncCompressionLayerStorageType::CompressionMode2Circuit as u8, + proof, + ), + ZkSyncCompressionLayerStorage::from_inner( + ZkSyncCompressionLayerStorageType::CompressionMode2Circuit as u8, + vk, + ), + ); + } + + #[test] + fn perform_step_2_compression_for_wrapper() { + let source = LocalFileDataSource { + setup_data_location: "src/proof_wrapper_utils/testdata/proof_compression".to_string(), + block_data_location: "src/proof_wrapper_utils/testdata/proof_compression".to_string(), + }; + + let proof = source + .get_compression_proof(ZkSyncCompressionLayerStorageType::CompressionMode1Circuit as u8) + .unwrap() + .into_inner(); + + let vk = source + .get_compression_vk(ZkSyncCompressionLayerStorageType::CompressionMode1Circuit as u8) + .unwrap() + .into_inner(); + + let verifier_builder = CompressionMode1CircuitBuilder::dyn_verifier_builder(); + let verifier = verifier_builder.create_verifier(); + let is_valid = verifier.verify::< + ::ThisLayerHasher, + ::ThisLayerTranscript, + ::ThisLayerPoW, + >((), &vk, &proof.clone()); + assert!(is_valid); + + // make a compression circuit + let circuit = CompressionMode2ForWrapperCircuit { + witness: Some(proof.clone()), + config: CompressionRecursionConfig { + proof_config: CompressionMode1::proof_config_for_compression_step(), + verification_key: vk, + _marker: std::marker::PhantomData, + }, + transcript_params: (), + _marker: std::marker::PhantomData, + }; + let (proof, vk) = prove(circuit); + save_or_diff_compression_wrapper( + source, + ZkSyncCompressionLayerStorage::from_inner( + ZkSyncCompressionLayerStorageType::CompressionMode2Circuit as u8, + proof, + ), + ZkSyncCompressionLayerStorage::from_inner( + ZkSyncCompressionLayerStorageType::CompressionMode2Circuit as u8, + vk, + ), + ); + } + + #[test] + fn perform_step_3_compression() { + let source = LocalFileDataSource { + setup_data_location: "src/proof_wrapper_utils/testdata/proof_compression".to_string(), + block_data_location: "src/proof_wrapper_utils/testdata/proof_compression".to_string(), + }; + + let proof = source + .get_compression_proof(ZkSyncCompressionLayerStorageType::CompressionMode2Circuit as u8) + .unwrap() + .into_inner(); + + let vk = source + .get_compression_vk(ZkSyncCompressionLayerStorageType::CompressionMode2Circuit as u8) + .unwrap() + .into_inner(); + + let verifier_builder = CompressionMode2CircuitBuilder::dyn_verifier_builder(); + let verifier = verifier_builder.create_verifier(); + let is_valid = verifier.verify::< + ::ThisLayerHasher, + ::ThisLayerTranscript, + ::ThisLayerPoW, + >((), &vk, &proof.clone()); + assert!(is_valid); + + // make a compression circuit + let circuit = CompressionMode3Circuit { + witness: Some(proof.clone()), + config: CompressionRecursionConfig { + proof_config: CompressionMode2::proof_config_for_compression_step(), + verification_key: vk, + _marker: std::marker::PhantomData, + }, + transcript_params: (), + _marker: std::marker::PhantomData, + }; + + let (proof, vk) = prove(circuit); + save_or_diff_compression( + source, + ZkSyncCompressionLayerStorage::from_inner( + ZkSyncCompressionLayerStorageType::CompressionMode3Circuit as u8, + proof, + ), + ZkSyncCompressionLayerStorage::from_inner( + ZkSyncCompressionLayerStorageType::CompressionMode3Circuit as u8, + vk, + ), + ); + } + + // Note - this a large test. + #[ignore = "Test too large (too much RAM) for CI"] + #[test] + fn perform_step_4_compression() { + let source = LocalFileDataSource { + setup_data_location: "src/proof_wrapper_utils/testdata/proof_compression".to_string(), + block_data_location: "src/proof_wrapper_utils/testdata/proof_compression".to_string(), + }; + + let proof = source + .get_compression_proof(ZkSyncCompressionLayerStorageType::CompressionMode3Circuit as u8) + .unwrap() + .into_inner(); + + let vk = source + .get_compression_vk(ZkSyncCompressionLayerStorageType::CompressionMode3Circuit as u8) + .unwrap() + .into_inner(); + + let verifier_builder = CompressionMode3CircuitBuilder::dyn_verifier_builder(); + let verifier = verifier_builder.create_verifier(); + let is_valid = verifier.verify::< + ::ThisLayerHasher, + ::ThisLayerTranscript, + ::ThisLayerPoW, + >((), &vk, &proof.clone()); + assert!(is_valid); + + // make a compression circuit + let circuit = CompressionMode4Circuit { + witness: Some(proof.clone()), + config: CompressionRecursionConfig { + proof_config: CompressionMode3::proof_config_for_compression_step(), + verification_key: vk, + _marker: std::marker::PhantomData, + }, + transcript_params: (), + _marker: std::marker::PhantomData, + }; + + let (proof, vk) = prove(circuit); + save_or_diff_compression( + source, + ZkSyncCompressionLayerStorage::from_inner( + ZkSyncCompressionLayerStorageType::CompressionMode4Circuit as u8, + proof, + ), + ZkSyncCompressionLayerStorage::from_inner( + ZkSyncCompressionLayerStorageType::CompressionMode4Circuit as u8, + vk, + ), + ); + } +} diff --git a/crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_for_wrapper_proof_2.json b/crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_for_wrapper_proof_2.json new file mode 100644 index 0000000..193abcf --- /dev/null +++ b/crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_for_wrapper_proof_2.json @@ -0,0 +1 @@ +{"CompressionMode2Circuit":{"proof_config":{"fri_lde_factor":512,"merkle_tree_cap_size":16,"fri_folding_schedule":null,"security_level":80,"pow_bits":0},"public_inputs":[1961802424684827,44478075017541700,68433799240021256,10969447465159162],"witness_oracle_cap":[[5936792345932124505,17357561102651133416,17564433200710638038,3339893668046740377],[12751637666737176862,9794001769102033621,2926888803123961451,2255742217288078923],[14424068896481350537,1663744739457665080,15411678023980512377,2656399497952167630],[14593942856615725619,12403785068245623768,14543930526979508339,3247198537710313514],[14555124325380201455,12831916618503092409,18119306365361476768,1081509151164909476],[2184001487798491667,13398850378810632004,12162804217246642316,88205035743977771],[2985241303989036080,5639329015091076845,16098527543150746653,777843601435943179],[4382218438320880860,18209648393626607190,5961037480977021298,551916823422748952],[4914907307695915796,9935272882836807915,5222261978140834407,2708224665524920749],[18331614967843979531,10091823908238697419,14097900961670118556,2570526166585944838],[1375154610859174841,891073102800727438,18175591411548691764,1353318082637276602],[3125794744516893533,6111180613707178082,18403690168139902178,1552259542423584847],[15972895612330448567,10988237003176468622,15738717022470293871,2641761834706679529],[2900330342774089206,6764519923737989075,12985549017113278181,2699211400666336179],[4573373042259436899,14550606132651717840,5605520911037883491,1982548793003804189],[7515089412043452258,17218044359313968057,6898929749885892912,251926063904403341]],"stage_2_oracle_cap":[[2513118163168853659,1991120480211341364,12888987064538012832,2102486537360075904],[11395476368523927196,8949711336020786996,4543601068957102614,422747192664807651],[10862841590103581363,10016119126112067069,12948805821223370669,2528730380787563597],[5655246695778525965,8701184376563036362,11832837250501297431,3148155469003568018],[12934034366924058371,1419808922808253172,709874405236178294,555890908161866042],[17430613849710583222,1159589317534502073,12196833275422805538,854430939596104915],[11018672654507992562,8151654866357164288,7272319385794335881,819280309374660814],[8519201335098566108,339482902089515277,8697729807284457011,3202980038934918722],[11343367142597232364,3704297495360562780,17608652890894432421,1103904059029523897],[17090041640588492457,2292742355661447968,13959166391164385519,388487796888092964],[15486395615100656617,8639197020899887488,11615270350145036748,1127313427352015514],[16704118833023246727,13700585725095879982,10341056701244503472,3374634723253486645],[13806702114569569354,10290844943567145696,11861348926852882546,536376211856374649],[7290089407482349880,15911151845444007071,15894857787310121084,2411412079037748664],[1483174921095085248,10815325244880591770,7807982318609703163,330633845056061738],[14070994087605651385,12385960634652802769,10210020086641602104,543029215449804634]],"quotient_oracle_cap":[[12182934561540273974,9264789689311563655,5488771210058381009,1318920234824938821],[9570468362716131749,14004515567231449438,1438329474974451548,1847102070195812813],[13351202872675899608,12058332421629795384,4712864496063908086,3307120276520662163],[7032001631089381522,7153455358517711735,14507583906711243259,1565038859220709805],[8610224893487075364,4510139625263849671,10058171132873388290,1972565709911976169],[1841745127223683874,1355010492425789033,15527378804668628649,28789842198507642],[530196451289063162,13736885380665346721,13663256310193742596,3321804700671479667],[4369215630412309798,17543119972787129228,4607361476212863185,1555050149351494539],[7275890833413927365,9969439472266750926,9742222479857000579,948873356967151932],[7705137278791077112,5195498375975369438,7889358941732403490,185381053283784079],[9598015426274437319,8017576320676342662,17954984577158876630,2036603574813162429],[2924921907314141027,11215044284966749330,5108510234545470367,3075655474650666780],[17594475396460849769,15983375278119777780,14607578184892807834,2833947807367850554],[5258629320193981750,9517969237210092828,4984345363012222940,80803743759158318],[15905299965678486855,6080765002020222596,3416334384841787351,1871528359723999640],[10059236345154595797,7658752867184243764,7978366240439898303,2076721622722775796]],"final_fri_monomials":[[12661359263559419170],[5177762590278875202]],"values_at_z":[{"coeffs":[13647245762944148502,4103054803952010384],"_marker":null},{"coeffs":[11930412561874305136,8015878717716787423],"_marker":null},{"coeffs":[18226785023685550211,8692688565391533406],"_marker":null},{"coeffs":[16421980803458613581,10923533265503055688],"_marker":null},{"coeffs":[16765114282391261743,106529664006200941],"_marker":null},{"coeffs":[13628508245804437691,7385111349488434310],"_marker":null},{"coeffs":[7198293305569977639,8427622913370142493],"_marker":null},{"coeffs":[12331913885736731454,6751097194038615669],"_marker":null},{"coeffs":[9448412073982653211,15878943509935981211],"_marker":null},{"coeffs":[4837873787087973839,17359866221670475724],"_marker":null},{"coeffs":[17163967765941804676,11792905229168859234],"_marker":null},{"coeffs":[9137659575263365045,10681053224754075797],"_marker":null},{"coeffs":[13507768618808803517,4112383862526955943],"_marker":null},{"coeffs":[9603963996468727726,1394829641289850711],"_marker":null},{"coeffs":[3764910317586646653,14539212649899845198],"_marker":null},{"coeffs":[4316535877355020146,1090781564320688],"_marker":null},{"coeffs":[5196802278171399725,6577194232613769549],"_marker":null},{"coeffs":[13564802580484640638,193938619301189047],"_marker":null},{"coeffs":[13765738151000688695,14835112548989544559],"_marker":null},{"coeffs":[1948067476212569514,17926462622213245021],"_marker":null},{"coeffs":[12805923058130627093,8755976649924626326],"_marker":null},{"coeffs":[17374892944797818954,8163575068479667565],"_marker":null},{"coeffs":[684338956788830067,1693490416718641916],"_marker":null},{"coeffs":[6095466186787271152,13864639027013399243],"_marker":null},{"coeffs":[16052013988859472067,12578920405883182973],"_marker":null},{"coeffs":[4793608785108322495,7404418159044121173],"_marker":null},{"coeffs":[15553746211968219330,7332966405248495292],"_marker":null},{"coeffs":[786181746230891122,7363242227512299565],"_marker":null},{"coeffs":[1906589710811109587,203401383426778937],"_marker":null},{"coeffs":[5399547770366946955,33227110440519684],"_marker":null},{"coeffs":[5754581145008376403,13244903043595587787],"_marker":null},{"coeffs":[17118882655242179621,10960791614465889808],"_marker":null},{"coeffs":[5507976524157584396,17474041896164715159],"_marker":null},{"coeffs":[14756604241732100156,9331955600114434286],"_marker":null},{"coeffs":[10401622766597252974,4427554862670225424],"_marker":null},{"coeffs":[13298089388762150351,5301987941295041402],"_marker":null},{"coeffs":[14163187047529944025,1789981258764643940],"_marker":null},{"coeffs":[3867458578147663607,17300720628618365590],"_marker":null},{"coeffs":[11695813988709158019,11346307245317484870],"_marker":null},{"coeffs":[347558107058492314,15665556404399950143],"_marker":null},{"coeffs":[9185834000254813940,6653372440074757641],"_marker":null},{"coeffs":[12891147033137465309,10561980727692231326],"_marker":null},{"coeffs":[6516058904737013289,7412146998416201270],"_marker":null},{"coeffs":[4403266478674467075,6270072928239743133],"_marker":null},{"coeffs":[3052653026711682211,3065625725642559127],"_marker":null},{"coeffs":[5227486589011918072,17586997672995289714],"_marker":null},{"coeffs":[12896790325689534624,7060416019117342171],"_marker":null},{"coeffs":[16358239341701143587,13330327093107331315],"_marker":null},{"coeffs":[18347910213601681167,13000130427205386666],"_marker":null},{"coeffs":[17980832347452758719,10679301607989039611],"_marker":null},{"coeffs":[1364346757599911043,5929846798115389484],"_marker":null},{"coeffs":[1745856616671781704,7954491821385196842],"_marker":null},{"coeffs":[2766598932516954128,16960503843748741222],"_marker":null},{"coeffs":[12964808238950113634,10724902130266695752],"_marker":null},{"coeffs":[3992660343163192112,12055905775316947935],"_marker":null},{"coeffs":[10265316388736348504,5737790892079046015],"_marker":null},{"coeffs":[9480668371285906144,11382154428063402698],"_marker":null},{"coeffs":[1366007289150940253,17704887439727714607],"_marker":null},{"coeffs":[4319477926489104461,11485035401196731264],"_marker":null},{"coeffs":[3523578814783060959,9252242849123230894],"_marker":null},{"coeffs":[3728053742412207030,1436897637107569398],"_marker":null},{"coeffs":[7622630425292098650,14888932459962007465],"_marker":null},{"coeffs":[8919614945407768155,13126450876127592898],"_marker":null},{"coeffs":[1070536417304712237,9669617685910571647],"_marker":null},{"coeffs":[337764782417361639,2467188567744383247],"_marker":null},{"coeffs":[10848887736028878410,6930043868921984103],"_marker":null},{"coeffs":[8281100712502663127,9918155507906236321],"_marker":null},{"coeffs":[16018155407426042285,13929621683836343516],"_marker":null},{"coeffs":[6208003190969913512,9652833044526144507],"_marker":null},{"coeffs":[1914652675409577175,1198314272440570825],"_marker":null},{"coeffs":[6809972263245550824,7620257793887932243],"_marker":null},{"coeffs":[5281565189148648233,2083968140836251823],"_marker":null},{"coeffs":[4952447184559202854,4362745911296248879],"_marker":null},{"coeffs":[3843353806769253578,14430280134836884622],"_marker":null},{"coeffs":[1790659067415481800,11355005918518510642],"_marker":null},{"coeffs":[15885053636744672190,14752090813650610939],"_marker":null},{"coeffs":[8665375815081721872,10611601047158342488],"_marker":null},{"coeffs":[9968052298721801109,3698293353947917204],"_marker":null},{"coeffs":[9943686649695635308,3386809737456839267],"_marker":null},{"coeffs":[7488130375360387517,8436095589162253680],"_marker":null},{"coeffs":[8294754193809877475,7907656679775684516],"_marker":null},{"coeffs":[1035170829398229601,7656140630713693169],"_marker":null},{"coeffs":[2701461251454932267,17516908701561370873],"_marker":null},{"coeffs":[12173744655365876696,17538729021276136348],"_marker":null},{"coeffs":[18394458583792086275,13154842834549528022],"_marker":null},{"coeffs":[6556139067280011990,1991328420719883540],"_marker":null},{"coeffs":[13175069992827999160,6799993951220466898],"_marker":null},{"coeffs":[16746276900922597212,14753197413199730519],"_marker":null},{"coeffs":[3632791118833766902,13991950170744810874],"_marker":null},{"coeffs":[11234345239752613813,12686775817417211345],"_marker":null},{"coeffs":[1598343338691280536,15425411511021961135],"_marker":null},{"coeffs":[14857707815471172995,3512374200656660368],"_marker":null},{"coeffs":[9178080878174634918,17719409273008080919],"_marker":null},{"coeffs":[11143707992545150121,17979128477352841701],"_marker":null},{"coeffs":[1835937217149870719,8539968363373743948],"_marker":null},{"coeffs":[5145880019573172594,4156766468148939645],"_marker":null},{"coeffs":[9391441304279421891,2590614024223819430],"_marker":null},{"coeffs":[9320907615958860625,8435644334027290531],"_marker":null},{"coeffs":[14818942389346852337,806043210165934256],"_marker":null},{"coeffs":[971698417783432995,464138150243781637],"_marker":null},{"coeffs":[16302598437814746280,2298505947934778966],"_marker":null},{"coeffs":[2775992958391399204,17526328544257562815],"_marker":null},{"coeffs":[9714037426311110987,1407744622592748814],"_marker":null},{"coeffs":[15509175360248107173,6159363218374158413],"_marker":null},{"coeffs":[16414726060050495202,5681770995421741089],"_marker":null},{"coeffs":[2891839949987944643,14577327000337192798],"_marker":null},{"coeffs":[11614572926738115360,5522495396790733912],"_marker":null},{"coeffs":[15549470061157948012,6744867707145123086],"_marker":null},{"coeffs":[17128184166244945972,12100219378750056711],"_marker":null},{"coeffs":[11992752542141840490,17032922492325151785],"_marker":null},{"coeffs":[11754289242875898950,6114552846167603682],"_marker":null},{"coeffs":[13747546185837957470,8874171456312313104],"_marker":null},{"coeffs":[14962114923801594610,9152574866030097409],"_marker":null},{"coeffs":[10473557240527634374,7552757163242509566],"_marker":null},{"coeffs":[18025128677440825029,17380863966277737314],"_marker":null},{"coeffs":[1799199668843480034,16589545490400829454],"_marker":null},{"coeffs":[12103643778522738088,4066417422767265911],"_marker":null},{"coeffs":[5588233639322982099,7072428987792119209],"_marker":null},{"coeffs":[9094572829198793896,7856652110703500992],"_marker":null},{"coeffs":[8900128911213610632,5426274775154809927],"_marker":null},{"coeffs":[13313555159157771574,4870678470306378893],"_marker":null},{"coeffs":[14956542534319574803,12244011405811266715],"_marker":null},{"coeffs":[15518202862949216816,2554668047340712246],"_marker":null},{"coeffs":[17653361088497634190,5385067939183819827],"_marker":null},{"coeffs":[2085116333101708106,9982031994136950857],"_marker":null},{"coeffs":[15455285459188480589,443611967542591175],"_marker":null},{"coeffs":[9734654971500452383,4214336198653655480],"_marker":null},{"coeffs":[14210923441603981658,7376277407652888665],"_marker":null},{"coeffs":[4742675839977452910,7836135030286298408],"_marker":null},{"coeffs":[13915247656390131182,7507961946028991348],"_marker":null},{"coeffs":[11884099799319557675,18395829846955099573],"_marker":null},{"coeffs":[10411878963255197647,13100178011866844021],"_marker":null},{"coeffs":[18215287006749309329,10405713965571507646],"_marker":null},{"coeffs":[866623648876873178,3964292327079651159],"_marker":null},{"coeffs":[12187987043301540670,13708473218451684126],"_marker":null},{"coeffs":[8559569362779037728,13366976676720880493],"_marker":null},{"coeffs":[17001735210818244709,8575794719050260896],"_marker":null},{"coeffs":[18336566518087603997,4255882403374368339],"_marker":null},{"coeffs":[56665080862604338,11032591472706806345],"_marker":null},{"coeffs":[18150771859720995090,17120531525581707638],"_marker":null},{"coeffs":[1740743211888990225,17116942672805906344],"_marker":null},{"coeffs":[8632221157093933771,2402158804917263539],"_marker":null},{"coeffs":[9581489724109893074,635543196458020459],"_marker":null},{"coeffs":[14538006008888414673,15867379067230977357],"_marker":null},{"coeffs":[1573987165939769996,1065287200740761426],"_marker":null},{"coeffs":[9204542825537968017,7673687180720538272],"_marker":null},{"coeffs":[16680117044335165955,2655910832122976643],"_marker":null},{"coeffs":[14442259223794323623,8260765674922223828],"_marker":null},{"coeffs":[15760725259235968676,4555973624064870934],"_marker":null},{"coeffs":[5909077336854754352,6430157701774717019],"_marker":null},{"coeffs":[8143388467974012784,8579140910508689764],"_marker":null},{"coeffs":[12749469951366413774,3402709634520190570],"_marker":null},{"coeffs":[11937217763675188801,10444835383110457336],"_marker":null},{"coeffs":[17986636891212681634,10338075594213066815],"_marker":null},{"coeffs":[14642812254568536629,10803891764055128793],"_marker":null},{"coeffs":[286748109491815707,1572616952116727094],"_marker":null},{"coeffs":[3435483447812279981,13749570402555274543],"_marker":null},{"coeffs":[10227779161739005260,17155358935407956502],"_marker":null},{"coeffs":[6398190723438948970,12141314335891179837],"_marker":null},{"coeffs":[9476703765018392273,6587848292167327936],"_marker":null},{"coeffs":[17726820152362502713,17969675030675756472],"_marker":null},{"coeffs":[1549103662702116898,1845516366070080064],"_marker":null},{"coeffs":[11734114471920824129,14270098984618014970],"_marker":null},{"coeffs":[1363553334564880012,8455200146704608560],"_marker":null},{"coeffs":[6879880807975765176,6346779297474201939],"_marker":null},{"coeffs":[11329921641759450998,4989424773156590413],"_marker":null},{"coeffs":[13708647627577237899,12895391612065553452],"_marker":null},{"coeffs":[396973641228076901,346030544479456433],"_marker":null},{"coeffs":[7325537278019703612,11008156740940218190],"_marker":null},{"coeffs":[3118367166330655864,9394598160517259992],"_marker":null},{"coeffs":[12072196583341478733,7507774280656722663],"_marker":null},{"coeffs":[9353557147257090643,13531312378741053528],"_marker":null},{"coeffs":[13374713614315517689,2754536013189726103],"_marker":null},{"coeffs":[16060954878024429754,2421521252919997109],"_marker":null},{"coeffs":[8866325105480087650,859455714026181428],"_marker":null},{"coeffs":[11265474169187767959,11485936994895386447],"_marker":null},{"coeffs":[3195281610381814107,10107942162115000673],"_marker":null},{"coeffs":[9136073172619503260,15273587842790932086],"_marker":null},{"coeffs":[10492314346940782728,4794729761371837524],"_marker":null},{"coeffs":[17880899330884937480,16314121443658596545],"_marker":null},{"coeffs":[14716607505035136254,14128342920595074752],"_marker":null},{"coeffs":[16526649628263599326,8468638849573746659],"_marker":null},{"coeffs":[3627377869194311157,13677731592802039567],"_marker":null},{"coeffs":[11401870300832233258,10323522161674179340],"_marker":null},{"coeffs":[4858667098577268974,228799045321475979],"_marker":null},{"coeffs":[3252186931004924901,5686364797954500455],"_marker":null},{"coeffs":[5783464305397707962,8633452289878048402],"_marker":null},{"coeffs":[11702840783883767101,9522574079118602553],"_marker":null},{"coeffs":[7638887866221235274,2650297595570598817],"_marker":null},{"coeffs":[15046026346121186404,5615539803916037445],"_marker":null},{"coeffs":[12702324932006920874,9929012661564934912],"_marker":null},{"coeffs":[1013827141985574571,16690489513208709329],"_marker":null},{"coeffs":[1570625572725225849,1218602977456642621],"_marker":null},{"coeffs":[5308929537035829828,8953463743415242099],"_marker":null},{"coeffs":[14041242079230018364,11156704695597682270],"_marker":null},{"coeffs":[15107646097154030351,1328737745906183138],"_marker":null},{"coeffs":[13675919088963433015,88954231170833423],"_marker":null},{"coeffs":[10017364935402444127,15668837189799715231],"_marker":null},{"coeffs":[15051538157985048969,5568072016829567960],"_marker":null},{"coeffs":[9861760730224062983,18134410525779808205],"_marker":null},{"coeffs":[13952787639855400842,13705769101285976725],"_marker":null},{"coeffs":[5443551132303688664,17046184298099690401],"_marker":null},{"coeffs":[13044685529490201710,1563026507931601931],"_marker":null},{"coeffs":[4221519332129301909,597776207951918702],"_marker":null},{"coeffs":[9336677689534193612,7566525924323620527],"_marker":null},{"coeffs":[12187575953488779195,12964027866247517664],"_marker":null},{"coeffs":[11858342759856023834,15919648340877285523],"_marker":null},{"coeffs":[17114747229597665293,9021072696217283712],"_marker":null},{"coeffs":[15484641862480093590,7623884684239326159],"_marker":null}],"values_at_z_omega":[{"coeffs":[13876800558718408085,1177638553394772467],"_marker":null}],"values_at_0":[],"fri_base_oracle_cap":[[13023623373724153733,7693509439392478135,13459181111721331271,205826789750120743],[12588558584125590561,17136285365406706033,3947184904817723073,1478776267502488769],[5609388281881485294,14984776301126157281,3873195771675661226,2465680143960632055],[8379768019844187595,1750475652084081134,14870971529928009579,876141120437101899],[18308493330869519743,1934618174225772488,11680965090811973539,2792183601480738157],[3610663400075411705,2958494330299832199,4761231087970019731,567595469091410869],[6780497525129308229,6963336448084608656,14132166347360400897,3121253855545144299],[8535201649794136222,975402783590640319,15851995822942276601,3130273628564481478],[11103804770008250274,10781190523213552267,10111045827160137969,1827623889825669766],[8692391763582252239,12720662440145799079,8225491728765170342,360583144308457740],[14059750202134948219,8584444375684363533,843703733878046928,365887021698036542],[8019842621987750324,9092911918898649637,14996808834785808617,2000310218558683248],[383076901109906794,15419610976090284378,16844278846429524047,3024570346294111563],[3753409728791415580,3430621438869691336,11769287212103886714,3128450741191491048],[14997413969199992418,370847694802137469,9641638975847122300,3234753350255711011],[323644742219754591,12479223170287588192,2418633843161802364,1347629437337976612]],"fri_intermediate_oracles_caps":[[[11486364326807733373,16095157552656495097,17464701652943151831,2562487265497119246],[11204363567411028572,15976955603031251306,9268800754637413654,3417414033123970150],[17941706954622322273,6188436392209885419,2303219737153731351,346486616521172086],[17687008308588421963,7599428868338626839,9184840350375458341,3456307968804298409],[18323692795448908958,9218913927005796551,5116016308467991694,3128483343193418411],[14934744357461331231,7412922782117470751,17695113294719451478,2494238017518509914],[11308957531284836884,9117763546257017105,10775153728185870940,3328060650938873553],[11036133787297289206,13990733150043053017,10289900399392318176,2643139813079132160],[14454328726414709542,5203120582037640344,13422905520581943575,182539210274487125],[7473407880993514812,2317065431687605638,2737059895770416633,351294087889270265],[6212154032330702745,846305481631609469,13779765024975206018,2610425492493723301],[9112277065599779054,13566446172753361747,9454796519012132388,1718211326882934461],[7502884008463707144,43804071784643460,16780119621083468648,2307387607651438741],[12486957575238200128,4091880660936223424,7348345789286187665,1855207674196543648],[17359313793749862347,16770436434687072385,9320750868253963447,3059362393701821307],[6351998920756783360,5441233037288967772,11118916024691701521,1985592002315763662]],[[9329345353030418747,9613751818152991687,5740459293431781368,2510902272484387925],[17493637964022768523,2297010957411528814,3957763747370895759,1044072093188960773],[15474481883911752272,3238035192213870369,5866981793459659919,3287059697720243334],[8694040972342276898,2103469039493981623,17344392423031648266,1054480605522446009],[6918325235926783162,9944947605024732813,15547526258188011955,2504315350139700982],[4395517819764573018,12253981372373668867,11859371769546107544,1118872901000413130],[14749394393591683626,11000776225275551216,12352048417261118683,2413812224734013655],[11050032273225174055,13986054800092804596,5334913990079262833,797230507115758735],[3437068771071019120,7125429960674097728,13970838174199127077,1594527757558662873],[3522192113441495880,11875534008185039579,13854558165633852586,3268554358457925484],[6951619082002175966,2611703146885436631,12053603710559185158,2041499244282838862],[5413510787899658975,14893966931477594357,1508446887557034970,113401929670407267],[16207398756725444465,6726936759799918440,1343687730684621195,1814847291911428394],[13197308643833608108,17564494121984813375,10038198752378403687,2428612336461633889],[10120923348224388074,15025815469601946345,10835323168968101482,399982811704667652],[1659267680213375593,10396058047879649156,784598023214678837,982154395378732439]],[[7204673127894606493,18111253129455967275,15768064423827158936,2151066241068398300],[2493706633160293481,7496364476440515002,14314327334707867987,586503383870550464],[17228787832852928833,14811308362674473973,1080468271411638305,1890998594690737667],[18415463491286983883,8652816853494898285,10503106058786540253,2930828444891273706],[8410740365188585598,7261512797513690389,1572282204739046698,696861089558301844],[7524127991590511486,15708527139942146643,14247048324177208978,256976317350823045],[15793404645007015842,4882657144692089336,7767751484218913819,730650101331320802],[9023466307480099415,10492856126206033455,11661852907360399935,2278374568985021005],[16518194351118663666,16769301337256409855,18441535296016815417,3091954676228668552],[1173446635672677647,1076412534734056862,1066140619518354898,3440043667112880759],[5932921460246438052,13456641061912001903,3703108990640093949,2585169981003779297],[8288627708237748673,10627277503631409847,2442308291053881017,2011807516206831830],[3428625100914457622,1558017222161263208,5127118104769598692,353346865357714030],[8585093154048942493,5682708602516563986,5893899424651272866,3309206844156814155],[16016036992630391722,9277751847483112382,1122219181213390816,2684723254928430328],[9177109416506346544,14973827763952432144,13863455640833510788,1514622780638393156]],[[2249746580193432381,446741816178796635,9244269322448197809,378288937436145734],[6878543685982669424,15476118142976122833,15513498085494959489,581320572052945494],[17500211490922446511,15575121288141712216,15833017644734789838,3400318110086079545],[5086057097713328796,9077778167796364525,16045569426136481237,1088150184245572902],[17115718820809306131,5390087364885354824,4372979022061885936,942250674086630674],[1583826760590994528,10469724892358443159,12123575146946205579,136828447741905393],[7792186397722947917,2569111264071890767,15648747416504397097,570701918856511553],[6763381264701624783,12011606252205530900,17525980326202554180,189788864327327506],[6610634358427297886,14681438980785209829,3532106138962462328,3009168500678043785],[14501119918514732153,13470884032601415031,12093075169880414955,269703144021632159],[13298496552172011012,548151459505710010,3933610945185324113,1282022143211955637],[17141155171544585200,5222545885799413452,15000221735200813736,3066787421574162328],[14156881376263775355,18283405779125856358,4657116298036510019,1877780756815956856],[7673028598079112663,3217811023225732537,12197086333816535301,1934883232959682642],[13801750160278341187,10672750568853656456,14782192141457341140,2658380147337102132],[10616120643990999987,13302557011150308540,13313082708006119605,2749621339755916516]]],"queries_per_fri_repetition":[{"witness_query":{"leaf_elements":[899914983435868632,4324416016229926050,3130470153621160894,12187148268093247544,1008863571683540614,13186103442861970478,7116738113579016875,8909157433811413624,9589984497076307540,13013362828696315981,11799644215480573636,1434846234635306097,14139336883765214851,6169903256197265804,13946700032626127112,17706430286875196590,16581875645927834588,15131593265423801352,17120402533015017926,2193995528738251777,10586593397909833596,12399157713149326780,1511867953358956018,6594339683942705535,17230384948261952091,5551539854068977286,17331289525021086596,11200990715953059435,3704779611417543596,9435625306102854690,13980116448466596621,1769824873242402943,14328924422283960582,4275883359523112286,14535187137816236083,3270162802253064921,5843339761832984981,10476394347796901235,17065454378109299299,834471189725782147,761560641633541261,8211807353517290226,2719127950431414086,16044426514054044090,4783928319252955505,7235812842529604347,4196813337424561478,14809358709167834133,195240226440134223,14448921141386980701,7264863727303446632,18321515171447949844,15904140619715278860,8052687994724648793,12468449570019084897,4169336782611553699,4037744882908253586,7124756640012307151,3913185318080321760,2339316405487081192,997918306274098996,11741089354296197585,11349036219465970380,10094982146488216805,12196865143858541968,9322242664886837155,4269017524354363561,1333472640806347777,11196226127420217827,6414813148394671211,10488413416789536810,12875922848186121014,10299232277403329751,16000367368553571446,11992451086705604862,18117925075640343058,6980561741514558156,10802752096670377257,9837759500604428989,503176992665043840,17736567660105592244,11792931206853723367,7336968639661080750,1010070031399234775,14211446442421877718,11528853805731296715,9924113939469006898,3678914418840107369,8365772576451636927,6199300844149725128,13440921863177051026,13414735597489802071,6218013685174707887,3423500236175278301,5218243802600090415,7325926914198956814,18054207701361706434,16241152618365074097,7931348569449161075,10589610731776139686,2292115652024423195,13590323688516711461,16443271834965552290,6584637865166188903,6082542854648138355,13156963053033030198,12150450220888475522,6065678691944470746,1620326088999608525,11841958495651745031,15369600216887393255,12531769419049203776,16834381665405310383,3039998213549122017,14005644193477359816,4642192937776959362,15901276618171251341,6284457787590979516,3155991964393894248,18356269051369681775,18222978633343976643,14941767633675184168,8990846816288006295,4712215205406638521,13943766396882668309,13817198530271685720,12034632150699331478,2582971941146595769,8015260724539907930,8137378070949289880],"proof":[[3723108495749462013,6223712438461837414,7316824193004188356,264816204710082964],[8132419902747653996,1291552291498873909,17113134139269549192,500260125181101237],[4996833992252267890,6811638253147589421,13800272130484199467,3252359889677400755],[4036249599095862706,8273739805275232839,3947425284340664890,2346236949751031194],[3650893853879720212,10637226932583619785,8215015625849958918,350866173175548275],[10031588944344927621,10065200320718057695,10269317838725069374,2342179519256802051],[6525193798093697350,5008645742806762826,3572863993539910869,2372840677841148514],[115550465453013541,5296249476437719422,18364260646109319016,2534372448147688134],[1391302865623650600,6216631127928647715,4322724448429932980,1444632980289262955],[12481086529942885582,12999426790605124523,7629574237971053025,294140012720583758],[16791063995820302446,11163899394212530930,5537946181374747374,3128223647105067126],[12077261473985402378,18022626211033392480,2993913389837211213,499344359282920999],[5031044430547663261,1299053134475445146,8163237773171456407,129532836358193060],[8798410607816030893,10891622556520590922,10535449718619973729,1322233074084924906],[15329884928799873475,16472374461324125692,1392594329297628083,1833140326290871434],[12823045712750277374,4011328068431504106,10580873178989757274,2067068807960070220],[11372356074004619123,8979239930795921765,6858143565084972102,1493033884808793730],[989433841769163069,14335179097040001030,9929046314937314029,2978543101046467536]]},"stage_2_query":{"leaf_elements":[2405702928819733404,12343454158554465449,11257027816306714622,16055722750975129628,2731794173650569364,1764396317465875377,1726436572234406052,12014145006860241937,17364572710575836072,7113682738348966832,3867767410856982154,17449049479822149374,4418887289737684580,3864943764838237741],"proof":[[14235519909215927499,11217854581470416781,11308916716005280896,2020716049839889625],[7419488157579877865,8694474906163778537,10161074584534794591,2789305518601422447],[15961488152735397435,2200477174495118570,15173968334812309231,2341188366255009365],[4061330449782105956,7673865239968995763,18053796172667035540,3012455304018771478],[17917578433708079441,16754406029625235081,18289010322266956868,745779004405237183],[18036836790608898765,4817115195691294264,3939803710507162640,133812633955566277],[16477174960234736953,13417649270505497744,14242900736848827957,1724667821739762654],[8638639328817618164,4007068790741309419,11638333916966702473,382236329215114190],[16615111279355389028,2515169009804704182,16656942830090911927,1520249619507659044],[13232860977699525221,4077540944514587507,8849368439650815984,80093871010432766],[11047137584878795452,4669611788870877969,5918293813455818974,3389416719767952398],[1159752385694923923,16178700143288020583,14380642947089698532,2059850703182828329],[4044486619125434823,9869834746797033690,8518832828941822602,2760464378583000156],[13397711789186439097,10556210389850169737,8196639535209852467,461959216539637632],[8172091854087463142,87556173865818742,7512973656168452972,2347018541013283760],[2190711358494871970,17135961168341992686,7632812991365825424,2530215222133509203],[15927796505684151770,9339995840736143091,8148991842318488329,601070727692109341],[17279111870602452287,13010077418041939716,4371225226704469416,209600038806311546]]},"quotient_query":{"leaf_elements":[12906364547446202643,17328147453778570477,10700109161337267647,3771626221960470603,2000300261153795728,17113670363828490361,14500143951666499742,6665691793777109940,12293095849786640672,11605935593004489474,3959561606140173069,5268395264508547102,14782402050685276126,16279321202383201391,12731565979052844330,5974536434948072585],"proof":[[12300630514849642790,15646357843398229059,790722609773956659,1912839541868825830],[10894727555050746308,16504638124202206926,10624438434290398139,1164632603595733783],[6697462567082929006,4647960429900686774,11204058952034770303,2335135955193921317],[17576212319962626060,16419090517204577808,8053369654257019555,3173166148182212157],[6960649016500650845,16108383608103334472,12119086774504378309,1839063176726233091],[291039184134726164,1440951865031158328,7101600365442873861,1706659432407387368],[6736081685149634970,11475476055278769086,9580504361773643791,2232246324701657667],[12296329286728824646,1464290244424868976,9613778213336915814,1359364433057981330],[4001352884145673161,7947638455173333174,17142058831691518949,565134267462400027],[12311460290162852066,11753748748118953950,12036866922309418616,179937032271419131],[6271688759909677410,9791708128437829570,12344124160689006694,3042317786066473704],[9454271256801426228,14127565286312397600,17882181185886944296,2408553369579259020],[3436269848223541722,11258313138013582933,8815374242684035742,1003776494790463463],[14402992996671161203,15734969528973377361,4757616291831256329,1736306729375016878],[3226930297028277914,17476374006132729340,3833533085195298081,3179329707714162381],[8239969311481432235,10624794770744465887,17439148672709567249,1967452668681759953],[16953174764074285488,8293868959180075621,7419040469213982168,1620318860168447639],[12244226702255038504,15008018255574260658,5689720189948098345,1812832190245522882]]},"setup_query":{"leaf_elements":[16793189425106717477,13202496519864806960,8902500434889598518,9684430133898560833,2704162808325686545,7320560786471462039,1584255476895765793,2239782290697852175,13080360584840483562,132453185445252426,2757728486139316714,15166598742972313458,12305178564133120306,15203678689008177223,18205745037187957333,12583416359285336220,13029506695338428162,17021984835165633672,5808908293542243733,14885457903799187669,9476391351438180956,10194596362390680118,15092526102882381894,13525183043151258814,17591767029212407321,12148482075037633415,16929029947446956207,8760869300457865843,17984064432578480497,692150385371321355,13398681718119961617,1050916774788205222,8250529582382086461,657414868481451214,3833679026423517723,17053354576218385918,13733802925039771056,12374698524561438915,4414414012805116892,16259487003097164402,7860339882632448760,9981620269607429579,9238284415837538994,11961472844185718929,9291758366091039575,12664378470430682982,5968672317808503526,8118535936536981645,15705313037263853796,18122695333015902441,4567451861750120526,10183255538461441763,1806696205143048550,4213089090307960858,6474396175682564602,12858647891675068002,15887345570553536230,15797259246186895373,3582919760620572883,5113896398626001718,12557802690293578082,6317363118344962071,3403455836060080550,3291525350686818804],"proof":[[6511381088418581028,10181452254840037502,13518944431089140742,140020652211343059],[3421360685327443731,12710745987916026800,9147228337660058359,1640289293723285288],[14816939206310650352,2535967513943402323,12737182503030582110,409328335080722939],[10087221965311442466,2603469691255525310,4528978444238752784,2716069990042487057],[11723861955182712997,14565560404168348627,15359545982062037236,1885770595200932544],[9089122700203874821,16973763254896162884,7014061055013271014,2775678115881567737],[13643699734887271428,3938578855092303877,7980140459033402539,343675382562828310],[12602527072085578398,18207988018778519238,2470423853644765642,1130881756016981284],[12168980616428573288,7454076955277516775,9232143661911883300,2291894492490467937],[2844273618277253041,924687477762010055,14318238693701362054,2248503361203231896],[3221885482770621769,5475511799406109652,7254878612806139065,2993691054115797953],[8206550273005158819,13828328362613803205,8791991688682179564,1207065688689358832],[3250301089676617085,7390665083493593029,2747952056228259511,169227801709597257],[11431610851546456389,12983822120964913880,3042938472418119467,147071575687070613],[15781458352553874212,3718838346580184050,8085906051256465229,1936328708631338850],[8271282677098411625,3693380110229530010,9473108083691544480,1073445369855574366],[12407570044707489488,5623381013034851040,10808438575722940215,1894503728907843645],[13299906095878087531,16363564844023027150,3400944305194918877,2057102871656357347]]},"fri_queries":[{"leaf_elements":[17110189538504038889,17241814339130296323,4962960938177335929,15912245554711725593,14915885873447308619,6617004465259901588,6393678971895140603,5167464920141752988,17436885942385898206,9461544175791704540,11697379825797874712,11256476423376095135,364455444823583107,1537128353707691119,4117093758630570318,15201609561486968830],"proof":[[14970817408003067964,2447780733713374143,9043340417732134046,502727318610919513],[18067881991523184057,2366780650260896101,15856479093431564938,654623400753976038],[17758112887923925362,7618320804232031103,6370285889019503792,3256657513653207433],[10325665898460264095,10131486212319149004,1078162138796191445,141532598344741981],[11337980448737183390,13928508726229540137,3300631340177814441,2814554014897194021],[10957705542511363160,3200230248905788045,14308592246161059330,2989928281926176798],[16779803757258913745,7807217315165387809,18373361290105523251,2018023121227332929],[1317573487220885212,162615643642721896,11345344888364325279,978186895475436881],[11384588451801999893,16151551682282027417,3879034212174663537,739381237407387540],[2534906898500073399,10400652482332096945,12686381208964560117,1295531153851589249],[13303076532841143512,16512878031113900914,3381036531325118824,2381434698200859373],[17844094776113378979,4925847946324089763,12161259193835631578,3402428306118006350],[2283146657362365483,8121148431355924480,558135801169442134,2442461595064095644],[18398418801757627579,9501004910664571266,7433555711340352439,2449617453513447343],[5693977732585476407,8414944157290462911,291526847321400867,1244593632775098667]]},{"leaf_elements":[13706795293719350647,5079996085002075749,4615942763674904420,16612683425619707776,4417844246572356121,7113126103394405013,12971987517158856859,1967340618951634044,9430939839460423422,12153242812446740001,13035122346167164914,10836918587828882000,17868022543911277833,7098490760104510011,16888342964407715604,7663022553915935661],"proof":[[6398679020594376674,10972968612867776664,11050970339032455156,3450438715011075650],[13731302590263634926,10084526821753004198,3360616360278868045,2513036884517197182],[923100600411860518,18339643365406514378,11436443561135138656,1464766199944185541],[9472303733815260102,3765529943376205098,2501424304898385909,2556593824848518653],[5228996908051296564,2263132628186885295,16646952988282645679,1110257794974176154],[5836557916316083542,14410434728615055681,7542315356539583396,1227246245591104690],[11030362691208845873,3138085327766416554,6334471199997427486,3061456441128863564],[9217037873964953900,15156354848778355150,3502724336888684030,55553380027780687],[14377834179210287119,9271036873435215328,2225032357146102524,2066086643111374999],[7105875976664240656,16025358526812434085,8669208253807755657,1839656841108635647],[9603776628859469884,5223380418084759280,4899691706670976834,3479641934920143264],[10364017626340947012,6809392119703823929,9069963008465418804,769546029320850518]]},{"leaf_elements":[17795430363336561464,10944891183075030521,16866781717908519827,10907922224435658435,5593498645620239940,8246661032161833176,18039873925648649693,10609913750385006603,15525435352036804717,8311558240462777459,14560299619021726837,9437467547351578330,6727205396418119559,16628960801824974634,11312294754282211693,1111871119159717853],"proof":[[17084465230742130827,14219462317990789414,14180697933824109349,2814834630364331997],[15451372302087256312,14812173476133172576,1868171937656464253,450097273499733694],[14052665673751594306,3293685293612804479,8391634458717016953,1229748626358502342],[13708700547021272186,16128559149532067226,10021664689351788345,39658853211473342],[828583216580690283,18256168657764167876,16763507952025931946,3352067378263808804],[9021995972972375670,4707618464170079789,7950147812590281500,3224103268303228995],[11696265162352955585,1055971155793199333,4685252548578561561,2187027655908909406],[2118989629964169519,4743630427810789810,9790018432235073845,1135639086213579308],[2434603535117955225,2103567568034425303,1718207908551784167,1175873577257172521]]},{"leaf_elements":[1563772685160328455,16856855111087884999,11448004278278759305,13565379201306276916,5532593663051984634,12771560126874265771,79583350073941436,11887709434711629866,9687723760329140429,16395976747561860341,1286154024673264586,7773744097478047742,5214408824021382857,17571654324285541048,17200022339809085840,12951169413477690392],"proof":[[14167545555247932296,9813445711716421839,16271059108845342306,2490043463565402177],[2642366997379126533,8312832747134973278,8969507859361018979,1790724016874605183],[9375049123868192851,2208780571595194153,4143818569412309422,632963318940658131],[11265755619462373962,4999889030904082794,16373712310835811106,1627058526899584446],[1494520282465259490,2834295861883769989,3638806300196023220,584734417312885004],[10155146308496114366,12410182043098754603,12192514972202862915,761976526236156928]]},{"leaf_elements":[16876292267499973898,5062548109038399513,5597258746708251370,13513602105197009024],"proof":[[874207514402430088,15033900945362295271,11059184623030878032,1648703518297408681],[12133163901222640475,8445678376592668441,10369957471204131310,1520618962171356823],[2181936401322473687,8977218228987764089,14607011929076344993,1703336138242869608],[2829221251905420508,15873457498737647638,3350230507590025372,2111222301339951914],[14443823814060425356,1717773491133911424,3005785806139853539,812229573463448888]]}]},{"witness_query":{"leaf_elements":[16703974479740067349,1635869186866235780,6276734091156501838,9222372613349277394,9204631950431043265,15989220598225671198,6754661298288153746,8220693194687900577,11766356519971254550,18238423485705119235,10717485715792015449,4429760954538937165,527794492554869677,7216947210172738154,18262832348895012838,15817194784464373600,12607668989902702454,15695637361769889673,16000498348073077351,1518148018279045552,13834996307375080862,5622052891812676678,1756379691163907730,4078956804432501210,10371068948349133756,5340462794164287753,1359784902396197124,18242265487473494478,8894067870058247343,1217888035741310774,2793162425694205877,4820751860688738710,15481280790674981736,979504550005037683,6195480416744686148,8418149947381722775,18310656002805476028,7034203272812323121,4206396736049360546,12754539017240647105,17669310246176159194,15479962217845780145,8378796212708883642,17441603161492607835,9536810983512298862,14875410747966759796,6718740121223146830,12549129446088050777,16541044550579203386,16723245110989999852,15155821835174112618,9279397776664261861,10564892212165695645,12944102288292343668,6489551304306580824,2982925627560630202,15533578910425955861,15994997230176681265,5142307181329204902,9045161829780652471,322807771270908914,553595482326270086,10722110353515334712,14195658695963687671,11951551724153422120,8244786331220174207,1834286065484615272,18418385884017789006,11111093449133776813,639979181772178571,7543498690617965072,17585019061389169943,9965099974870080531,15462466356189840237,11725337201325434098,5469439256817946733,14006971579019282443,16964637511891235017,5852990923347305112,2267211917350154241,12572154902320304642,16761261754525655107,4005304649775767111,16926576122601503707,12751080326925713699,10695467184981328188,2692645333792336989,8983128102883799875,1321329505177627507,8834728396162411418,17927935235420592966,17184112804470494614,18446556788750638020,14700094059292406374,1131380395855431009,15678896925865998355,7190193555609419754,8310463502283469548,13146148571405976115,4873338776032279252,9604767586716313699,9243191583601105069,14308558248283138386,14908839462411972880,17314868522443447829,4673733396882973811,4694476339531062416,11801396196310465924,11659747333455104702,15461757206146025821,4441658793917013563,8152302769492792018,10544407081694763927,13709987830109057826,14200950070424548242,4736117438129589514,12004880568049726622,13093488560870496399,12038941578890965419,11016659275308768071,5470564453227224036,3384035827795394957,7415422512495214789,8570788856629915606,5197565461211850503,14821328345124290549,4079797271136722870,16226000056350596144,13477552919618993017,1852584963944555557],"proof":[[15271760905893974242,14164300265466722499,5577492061333504297,3414330851248560804],[5258415382617793674,5568702784590010458,16601595128457351868,1732768694989384256],[11877521006731101333,10568650194190737575,6539627285570359160,2003765649458874616],[4428107268375073992,11206519957806780520,3498004816603338803,648502922503552657],[3623495617061178172,4925916611082397880,4377182833571816988,2466317522896878740],[8132309527995869847,12969356572619117370,1610086091128440608,1817692219766586636],[18136592388533941104,12427770555116617722,16098489780316849077,1597442137169248591],[16936147308653948874,7611590845600265974,1824181557431510612,2281073430869378791],[3927374328535846802,12583300594422088520,17641183660112923210,405907480152166585],[3846707904339818993,2925316025346126345,14490585400316472789,960719996844242752],[4397118029435045056,5550217793855281073,6489745746221833590,3371621210982494772],[17288481640868400746,10544433101776445401,225774922062125042,1557983862311235041],[5996189760574519049,16403616484061631662,2259715071338566407,3008070066635283428],[2319796612575072780,7005490170007050725,1129414528841554050,212701082136087118],[9066496566060298641,8805840790132247509,7116181866336025806,1557627393763697916],[2528719353349464898,7272399241467387829,4558496317012483302,584876762466211415],[16247627453183540468,13137392007134447487,13658695391484639261,1193285423212774331],[10240525352586518794,11325402873459669401,1058782688087872803,205557680263850512]]},"stage_2_query":{"leaf_elements":[13290970571671999865,17160583653522605783,10664131458228346509,16122548319275512551,11243587526936903875,11602823786843257217,11729846559099212798,1405685909767728972,17265969718837297041,10148220381496563817,1498518486710023724,14111710837982055504,5213453687362235275,7553842311703620530],"proof":[[9014757638578275354,7630215752583473518,5305483080165884895,842357217276883967],[7525318983676297666,5139681317533148241,9760349253044309851,3310529301297762259],[12170893512488615989,17109854567609615992,15209770360495880981,2211166590870817412],[13395437623134302662,8005119682200661764,17912524388904794016,2731329168807692784],[9753336321653488140,13641262136151347050,575431054174541983,812175695396309730],[15542419350573436643,3534674004012420856,76565832035909543,1131712487938232871],[18416828826630484685,2428358942526312548,18429070911398860418,2843447539803270411],[7773769905399562457,6771642238851299031,7044686455963482477,3201365343167738669],[2224108118740790734,18307566245810580213,7859206250035717441,3279129737065218696],[9382928395619632074,9671475279052683947,7095167101833479577,2031971617135453737],[1441351789811761683,7307782498106854117,14441003674997192643,72559869167863936],[5583706880559017309,13851663419855645804,10367636666635535167,2380519630918464052],[376307581067380282,17960647614590083575,11034179551032826124,2430121706144966444],[5061938271231721272,18228408956946276853,8549512566841632192,570492234670851806],[8250037896337518883,7636065083194203419,16796273283791279598,1753030189316519962],[850263549942647633,14294334235474678229,12052640605230009867,1387035992412020533],[15363944774279323079,5837005389606460833,2953061783706576616,3436317778445511584],[7167683529990973994,2271513836541330223,6698703540998776319,748447258192877349]]},"quotient_query":{"leaf_elements":[10204673676572508859,8693003320713763541,16086971453580186961,4414824144486540417,15863707056402825394,9073251502465380596,11251449704908608689,14137180313096848414,7740534408743338337,7650794397473907394,14929587514736561396,15254034852571402816,2545224963190666868,8542346307126655696,206606574324473060,16779124124873894946],"proof":[[624933493822663804,3674727937646482010,6704747909465059683,2068698166532665038],[16764488662819712931,15481512835287390457,5386900161713358014,2854016865070299097],[16988887695661802751,14468590225537295131,1411152557364248047,1565352356666273989],[636555780168574660,1689708447367560354,12966387899371405932,2898953569459735933],[558399687789741983,12831247859394785179,6677052355195775325,131097287786265017],[12423817052954036994,2952674534305016190,12391421627405317766,3458583816333459398],[12094987055165716641,18248863107954240570,18014636566860252535,3231009296518462802],[9288052561662938177,715293399380933586,8945923694850061271,2917513703467449280],[14729502072730990203,5869454251255949752,4438567459649717200,1623737924805114015],[15922240060762210814,14890654202554763339,15614038097977949991,3143275133100395092],[11838016057158736827,4725445505818991994,2893270741311899203,995717504601917910],[1424492571933337221,4651883872741864385,13563486749368338371,1299304970821503844],[17870566285858322585,2996477065965169558,8634053911619298032,1634313359620927663],[12612574662189505666,12889748649328163629,14419136827796532314,446698973948124794],[814896009675287445,14995804486623652888,2128687356226779943,155830024460242488],[9040122510685489061,7442332898512918387,13678148027733600058,2208092231987845524],[9103224899225238923,9974489177004077920,11742171837227275679,446075411975990464],[5671748666302684609,11698668745407825611,13468755366211043800,1880173120109713712]]},"setup_query":{"leaf_elements":[597696716465147771,12821253172751579624,12419495865298839671,2759698587258075427,15197835817779484807,17690514254731513917,11022758113232289247,8540409814381900932,12100337442709159346,8698962018583607631,8614200122961428806,9461255122869515721,3407865683337442286,14243137415740064933,316620324771959888,3648469101389714327,13711806056136850210,3292718509760655384,11293865107932434615,15181214909844030504,6258931321571130427,4888669985848625067,12108559939449111442,2644867585381345343,6866193381866310145,4965420326204899365,7086792060852049681,9690921739413296735,11754680495450981909,14381055584330606846,18302863686293031687,17526519267431410700,3043294314303136810,5880250962583798704,1634396273567857349,15059574058211365774,10346687454482676123,12074330877983742723,363529867170696813,6525065024914044387,14264470564381573063,13584979675448933747,5319213273681640128,15316272860395332544,12510529957314966834,7091507394230903243,8460206649459044665,16477198005860149229,1608431519371150395,5312589527009649430,7611706300749272603,3014262613178790707,4497312415440380104,10287880845256279872,17518593513604988462,13738455873573522256,8107488383464854611,14899827256292535494,15456041603203393496,5018150058952006494,10696145285047744854,2412131781161056991,7148495362234539581,13069537799341529065],"proof":[[10974062361709819573,17625901310122932720,6568432340198519445,2441790998992598603],[15597008921967012406,6569939247438320941,4330351743551882116,1035982665089518005],[16953485532660844242,5589380525529872726,11427213743137289744,1601858721713621149],[4445675918673424806,16521423167361423062,10329720909732585162,2735711993021181671],[8360879646607652797,6881525642979175636,17958193765797399816,2488401047215705264],[16575269054897425231,5846891289849504669,15197556663397251592,3351885949250981954],[7624228730683586741,18364163275308000178,7790780373332886260,46184208844363023],[18334117549143345326,11202339850921210575,12601370964039783320,3274835523991460781],[15317367920350854792,9916296066520399157,89540064924342353,1258624088634753274],[9885526321179791237,11514034561230226482,8367927728193164114,2403267571151817311],[8067459413201711065,4691857119952206471,14253066405638924807,2493007184116050209],[8779325176245780783,515452296024413290,17173496845410807277,266175717854738514],[14447308368251643366,9054691765008809118,13553483137028551031,1430267379592315260],[3076298100108113173,979974752943448628,13405159514878904058,1190951567654485408],[2600665150601219802,650850731290759044,9237881672224240527,915833749229265254],[2058418400986912051,15134877593505221403,7876818753888933212,1847250736522473612],[17536538563574072834,354011757250483634,2624345558365306906,1068027511616383226],[15672270940081627505,7573503123057646305,14384843344569842791,2025936064508250612]]},"fri_queries":[{"leaf_elements":[915849720338925245,15934092279707091256,3197250504553620637,8610220263005737075,12140969627790305287,15466297474313866211,17209619122975095025,14604159974602298389,2542323400863179401,16645749821317563614,3294346388681806287,15654185891779284880,3503697029208795171,11680417716236764719,1740891124826489350,5735500418642190083],"proof":[[7220532612822027672,7233153352136578662,14245794751993589737,3382261135308309896],[14948894422413586008,3998803478504821321,4885414248635738778,3399889636341277011],[4531467639973662683,16733965801697107875,17101860072361108847,3469716516544694866],[9972477101696843074,16534404891569657448,3667976167098257501,1033749817713546521],[14960869193816471430,5295550362810890787,12591220735884662245,136034256250660047],[502810603070237293,17777664658441685610,4418526096691955307,2446526515911934511],[1887491397798384581,9381721257086952675,9307030356855521618,455300002305520253],[1656488398796944997,13049275843281869293,1134077404516605057,3196513365527670747],[10273675980446357039,2887901329439906648,7536762722833525573,283526879865736814],[2667150772329738518,3727340750675527948,9719802332005538727,3181807557816660984],[2984354197017491545,14167755853604499965,18239658153141985520,2805956903672517847],[5667340426236087046,2970096027916187390,4904360774348832902,784924044471281087],[10023878409971561680,475933963802386226,4114604048336397988,3231285199995628528],[12436924489554133324,8523492784897953208,10180291969811971616,1875414929035116770],[9172473753416479839,3316194371886680158,4327080940966489314,1673713460412263255]]},{"leaf_elements":[7541373019128486220,12909384544330357345,15840393635173680975,5328839702009761977,18393541904835391216,1600031112632397289,441457997737519187,15073635646013936320,14760713686156109664,10048632206931578803,4136879527691607995,10821212446623780553,16582494786965328151,8333053536102501325,15907666812834114072,15954264209673991254],"proof":[[15108044010026437927,7564386583721298882,2891594153517438374,1581709330202037681],[9386787670294337065,11821580823206106875,15413802749774305669,886812638690753095],[13480417613603441789,3690438392754943379,1727375543069452857,278660718477331469],[6575993475807411810,4434880637544670745,13902382266813175712,1943382630533752249],[14260449927215676762,12373214885387338840,7575527792099151291,1168997468332650942],[8395967060668316309,1536817683356225378,1710170982017699926,1182993163587896056],[2368899852850351251,3822602043581890412,396487972124873938,153698477794030252],[9559134497954191233,8391465546023612811,17155832853008368587,2877967017168056366],[13738544447416596728,13993508442432237976,18313700043378409721,2218706393387408993],[3730860211194517399,2939532771253237105,4762292626623316839,793363411221453591],[748128323531015431,10536106919591615975,17705640298103441989,1917998245613927893],[11815184881121871301,15415507152146555159,14364261891870678323,3188953855129974081]]},{"leaf_elements":[6680404052990433912,779440032082954844,2561231027634222512,7081994989509893021,16257874198284148619,11003345710839552386,12091591360131522376,4403168390011211146,12444864538626693663,7818121482834393323,5300274273892765367,12260926559827051266,179858196741329596,1603777257025053284,14928879115667566104,7907366315013374983],"proof":[[4911870130775775654,3331361285737044406,15900129512333723123,2706960825537979063],[17421241371891263914,2039250469290165720,6302760087019831308,2584201802117947067],[4277493032754231157,15128865539987324005,1188571080047963093,320375985575186128],[5641234708943631584,3440118593216938529,52450403531757592,84487448942571874],[11343429231168081299,8822862995626520277,3772424381459334864,925148109003735488],[17986557406418710435,18045119194710479394,6963931120184709077,622771686606052791],[14216071680906059511,15527440487844201870,8705060278800880862,270744103729663785],[1573146691258357199,2052983808041650196,1854247537829226382,3132714600774361190],[11178407915810956884,5881593695605190447,17287590022781341400,2597036478775900165]]},{"leaf_elements":[9453797484080908374,17659168783107061680,6247138973695620792,1127736363386413059,16652304690662505342,17321403243015634038,13966185825121786359,14024679498596231309,9716822557438103421,9005559495362922407,15764310321844965148,8320327187242758500,3356002811869453055,8626924322859251442,1512363130107146636,11603939532993204781],"proof":[[11712987723259212916,9512567433504497410,2663706408878039785,567079642796121705],[17241049285942698894,5288920900291855718,5551832030766583000,1595010270536825849],[8426427658785874113,11455530917094220679,9737251984846621129,271800383069581160],[14993656376802544631,14562598338907586769,5280641999700593364,74490357692193239],[159198280217795631,13358659809945517634,7367005512653223143,1200018892576446965],[15341132699456790898,9547885010454600,18238341771632132702,2392176907570232751]]},{"leaf_elements":[5730937816112028249,16207902560426345162,558859287972276372,105257494518399701],"proof":[[12962072428707312186,5625171142934563717,3995582229357081244,3085954379776511308],[6015997959726690456,7808105654307044286,14040355778740138490,2947007811492499353],[6913814170515646827,13243815081851278765,1225667034801624088,2864955225549939088],[13327468809373539994,14232630350472470835,6966180072701400500,1533636727300672886],[5719303027115079821,13630852719477139654,13459201700510403056,258874632104756456]]}]},{"witness_query":{"leaf_elements":[5198406540658817791,5529187068525951339,17914403158017075364,16243955349551232635,7086118169531340015,9836455564928767044,289706309455152877,14000707130526215512,15990155540076173978,3482801145021349553,6293564961226468040,12365618844983879474,14847191037827697278,14450748964246511559,15955570827972398081,9902048695286407741,2171725006464628348,1424992754488276554,9875231877888703216,16155115035996948937,7221876685898213413,6602407029377401741,16922597680001662548,7464898659103657714,15847171750764183276,3450072525766705170,12290329485228429584,8645886277875442161,7459429259369406606,14481503439815453745,13991932072602861585,14724579791072331781,13837497400578056435,6038213155657931545,3825534131942220144,8960715648359110615,4971646405993322933,13826698548874228803,14893608486246759416,14363296272800761942,3872613474386071992,17407406088176399168,9214582334882500575,15898149448795655024,10203932096505247696,8159300689134302248,2617232236912559708,7300182298439346023,15107772684379780049,11179434538672005934,3026498209936334315,117117587134960643,2999824530050157046,8402917612425141197,11437696678056287886,11051338859556586990,16262567431654719990,3269917480898356866,4561397603168616367,9809983607286284388,1689330850768073987,11608208728242909707,4366021022753224611,5723721341562580078,1640276308853535921,7801986178079815582,16584963331149888770,13740298368726544354,4388971223409951571,3695926045951368200,3886341104200178404,5309686113883521227,18151251239614632756,6417074588983792613,3564017103287181935,503567823887271257,17606672151952849360,832007971312212597,7258219284226200079,6454763112782247189,16374390459288370313,3551090941505835886,2582700942384543310,17080149592595329364,4841747951358520640,5678098047961510323,2147934113741338424,1486463747350897458,15596363215666583450,2238559572314137541,17298441659248123367,1198272878632646657,7014900164231977680,4992848256012321371,14333545972940075122,6621337891385469759,13038270738781949460,17894932001722521609,17203693134614944420,7363535507286815164,2585958724371508674,16396290340565327823,8002526029252106594,13016995423287085407,9168531760560533226,5301363279901120881,16666355568771321178,11758475950377186746,5679008309433747313,10992373384816005799,1737375360926191609,17620161657381692545,16513352274746404915,17954109047747183979,1130505579998517370,6402668564976809294,11957609124997625124,12256398976858211524,2765418862891143089,17364430169863021139,1874316303770295356,5306486440286667849,945506226543122443,1493630329108716423,1465008093400378979,17898308556171482905,9013739290021582649,11267532560137399584,8610116430805268347,10059475519502560599],"proof":[[2668265762790979812,12432323480206789719,17459826637001498244,3166604798605603044],[2538684913630392292,4033105377760787683,17594502656075646363,2044259632034452112],[983592312674955080,11711723603688245247,18145615070667854175,943804420192269939],[11288788061984640876,14594111670465372365,3466519187572046305,1397824997474558890],[18216829502705781229,16747141176467142114,13124328975816546027,1308331574399726201],[14601164967769514915,14437059738407764530,8725774378845605239,3347660111602760228],[6652759114208000432,3999540072306382096,13274703031561016871,1926037727618394302],[17206047468003866093,14372639354885888605,1449211459751609337,1404196291416211924],[7839582658513848297,14518152288349305834,4848448305790181172,2094484995379010759],[16108252903539814958,7402434988493929530,15670127191013346378,971629182704244485],[5706767856464542838,4794388284047824005,7991470770482940472,33702658707207934],[11163291798425501615,16969636719901556727,9062596009690783800,920317825738951387],[16841816054493660432,15583766880124594973,2775214425226465709,3433352971755127366],[244264683231159178,9902594577682797166,4474699091563211512,1318993988122557341],[14662227676433267389,10087823478159861066,13730539315438247710,853587636925919781],[9565325302010396786,4380066350991510753,10888194658343778410,3014170042729397615],[10565496035079316801,8575501729770763055,13946294697813105551,2892007915535684980],[6421454581074168455,11921480295421595591,8249025721742792107,61528479984627704]]},"stage_2_query":{"leaf_elements":[15994087452794445434,539412693377822244,3270083829819045185,10751198793872029236,3370311965077369368,520710190202951088,928839341271994427,5567114730390563487,14403395461894937068,8853850720820124615,6137525942785153955,3073746942679717649,9495722711898857280,13333392626193538647],"proof":[[1053357838514961254,15237130995930656676,3240008327031122880,1138744134224975221],[7832507467234659931,15551524764138373524,4487406152363703751,2700106756964587592],[15445985757712226389,1952492844392868540,11435206567034576727,1992046307444495462],[286777762073538479,16289891371105439452,18315617219432069675,1011866457325933489],[4950044340437154174,13405236191836306048,4046120341078947413,1773862933351253967],[15454130443661345195,6543359599308875007,5375797061252151914,2101705279135886326],[2549844377168336023,4508325654131523070,3353061598161503602,882199767979724641],[17804733202798210014,17537118342304390018,7896004866529914881,1184931891086062722],[10681528710004237441,6920333140528215959,8106964832658654720,2427031390779320847],[807217454390773506,5600886614893014593,14229899793414715659,2829554191748886512],[4612232696286359667,14709625604159543156,7198312809780484692,1811481561524102962],[5803640154521887207,1284916073032742206,15279728663211200633,2251234617669334625],[7476143365057796697,4931823748028437903,13571092474075088694,2419586195174242313],[5503070780831929491,9418067852261933396,10506285257703554701,2933592233774971531],[53621883744553660,16071217078058990631,12249194371468553375,413341545418575950],[14233778915335862384,10263288518969414929,17856307166236157548,827016228061309137],[13992459479737221144,5311202838405905584,8073976050857791213,126957140756323140],[318868390328225936,5866746710873500561,16481947920376445154,2250087834649825503]]},"quotient_query":{"leaf_elements":[7589705017080660888,11430822562355283479,11558083425897125014,18365233609539644500,94522810055773820,1571103328563161274,4595690568326733189,7643357711285377929,6214759354586869860,10101086815567517667,16377054237321039126,3244329769439668275,14198062455346334956,9052660265830499962,2641426493950724258,1304715384850361676],"proof":[[977507743418577652,7557940429053858108,296268414153505424,3114195677303061156],[4086739288476133970,7158343483553554819,3483031168187657294,2269949894988542902],[8611780721893140511,6965818037202196228,680967972310425734,1312621722788490064],[9106620704729393329,5423112687216768621,709520192843069386,2160290739015367141],[7217948785435916465,600941449549138725,12094427987478624107,3320289150188128235],[17148695347746453996,16020603438965666238,8412448795527309396,1992909264048224722],[1815583788893054123,14647750486747553301,18037348016485126004,36788345593382857],[11314071427098670799,16715265488323327700,14933057061707513425,1819498454528382829],[12926461353685239276,7569301910898486933,7781880942957682059,2545181891960223602],[11314848322187789504,7225965819649829838,8166765088978564168,2916664060202396122],[2349288307075789215,9196179229099840997,4752490649578306242,1358035531615103879],[15829537614694530050,10508782321785402592,18045127490622655697,1134912169124293351],[3178422884717788761,15616605926642838748,16602779351349095170,3200423957924199791],[15439212215845142175,10164223753723327433,18371840979435314028,1276887479021794618],[1903349012372778225,16685764793282351213,5919748466655726604,840023082258064184],[17645992461619294283,407383627909896066,15739965254727692009,410433758271096112],[5570345564769933312,1256792263590189528,12022647123817244315,799152248790834349],[7932148378530671580,808128519509682583,5452591913359579277,2925062541846668390]]},"setup_query":{"leaf_elements":[2054382892713051413,4435296734545684558,6829210930335801085,5798242626936790945,12435014733864790310,8291237647409784354,811420187671153805,13433242364236053805,5285923166271635072,12698134783777930036,3768666578797481816,9980385910236337176,882965686441111136,11905971028315965751,5749647101807849059,15655813674735148617,16048973718985549545,4600798112163641043,16535596111275690728,12877280708012165811,3383762391678988095,6377816193554827918,14712521588337712014,4550941977574291625,1226969818389895854,5977709270258275349,17560954490751558977,3749219057596360714,14804231001701773204,7440586002361889466,12738674796173617374,6341369357751055794,14511264446439543437,17482072999804011318,7130580587075805932,4426944554096015113,10805975720065358796,16979584277435285923,13617192334153313869,807316960876902576,10174483989756590026,6280245317501846118,10712714801583627762,3896887876235241967,3220835433522981009,11569503264011776993,17151433930271136902,2134968662723916187,2871493173186610139,11229538544065361741,13638687278918723479,16175965036771980262,18383595381889246560,12827972393307586068,1186902653012426879,2876762781431482054,1928309081139367788,9639646169900030036,10405283465271421189,9959462195677408104,12692445387476510332,14428529160069731891,11744757662048617155,13736697740996301142],"proof":[[2137862097520064142,7690720468538874816,11631028309226150385,837020007742367727],[1654097744161294012,14949917928066289678,6727357610970744936,912446113107500315],[9672424539797893282,2638130538462626171,17398404199225729784,2641911504650310102],[7298009843414947098,23716946208511869,11222354614787103296,257095748868593527],[8842186221220629839,12700344220737720095,2238068385126323499,455296569137988135],[9285442639100937341,6621079033147518430,868325313816133201,2786932646301800422],[9386594064268793212,6830878905694619649,14254782298421969090,2070430777595317928],[5701849593449759709,16183369220829869990,7860929120231297601,516934231569017926],[6352372520313546919,1303702834503625255,17384578254775228499,1811154610714628622],[10481101306786104500,7870410385373326803,2108009671976786694,3053955899545057960],[10156103588617892878,16874063333773816563,511028777186500751,3274221758810501193],[6265836130890609984,10047230165858274681,12939173074484241903,1003828785004239740],[15668696484865775272,8148884658673185576,7503506455704885478,3003748819438413142],[16433730100788184355,7706165594267880869,16337833188806238419,20103497232964687],[8875069626768698434,5605522928337430837,15320052273727682916,3020652869922196326],[1143353800810527975,1517938605154575900,3135863019846347259,379903661167218565],[3115600838120004758,17422806961695087548,14037330203242619549,1690212595902438394],[12339378471994385306,13999618414356881935,12906666137594807146,1655264730636798042]]},"fri_queries":[{"leaf_elements":[5688148497325818253,17850514183323806806,13364277004129644404,12587430040251213485,12910338713734963925,18434636563175448077,18309168760210555684,10303749216518173673,6244585812702809898,16260118030918710597,11216187426096203855,4038582925425856323,15552104278900596708,2262169948593974893,6991219202865332106,701108972607784758],"proof":[[17494008852742201660,7777046752090048591,8587726724416442243,1565910066201161865],[6696828134124547723,7862916193633784283,12517916216510393243,312382416023089131],[5340348102664830793,12006502284588181620,3798846934649494391,837522231238334815],[13185479169131990549,15392328256229872659,17133738320074008406,2617744988608278586],[8935803934807846330,5844285817415698087,14313382162562963009,605855299919860535],[13292246158757996880,1273524687026366309,14936356874723071342,1002228749796275745],[4509044541500128827,5219758505516349786,5554063443053011964,2766774449442748186],[17058202085508364192,17317869103158858194,14388593842597533264,3280237345608460136],[9586800221588811095,5887872963067126663,11313454449048816911,3191647719169235057],[13353850902704299905,14678687736976493581,6063484990651179423,2607811314822670117],[1250803576117427580,13681602402415650893,4884082129559647196,99986984223684023],[15234597662139271966,6259111139894791744,1527852472710201519,1828490293496756998],[12659646113560772610,10495117034224460402,3734949232163176481,1224048284862526861],[1241312676234417688,3469722311008533333,1696949515917473812,481111832708622064],[10193722875060153060,8057701653584840486,5291441780548931415,720829168023970517]]},{"leaf_elements":[11543167940607712788,9849598702565763288,3441068092212642721,9352366571085854646,11413428196141489583,1359598273198359218,8347314174510449992,14549104562858941957,16570530609873058453,6659686321424787840,6486389641717034293,5065981390100399322,13520588343188994975,15818461156296991597,16692814379888108366,11778936570088614120],"proof":[[7917057000120087415,13517122795999451096,2978784352856031180,360984010730734022],[541001194341489455,10208777829362545865,11840823529577620867,2316110003863410998],[1823946965901403576,4938159622617593348,14662106028162422362,176853332349576705],[4047720818552054037,12938616883760892014,92854306523966949,2418132369242723344],[5791138629596521419,6404805836844066228,2775675520534691495,2922916932600308148],[1020632021705064735,11508944090920924690,11018002480575876148,638853242194195611],[2305600509693105826,17112956702376346918,15943653398791457104,3270794622916385146],[4531580615939322490,7702087314680025197,13057020132068744672,2008226796540334646],[4347737603308471143,123475592265042649,2507093821552931442,78031529469984387],[9210477071316601434,7039443895827864675,18101810483752127963,1672290787789612690],[3991332579939367335,6518618261677254703,14056025875621812659,1613798754750015491],[3138843453427804487,10067876227812557370,16294205220018003068,663159325142263806]]},{"leaf_elements":[948034218717031621,9738504222402024818,15629495249871489251,13459163191356597882,12139591723965992964,5148448896488645161,950375701380268004,10481193256618949950,8296343876300878001,14446144050871452842,15549943759868296281,6737334680249504887,1504002832417452113,12055907769520493987,4840780088045488971,5498008864558742623],"proof":[[6811740772369662690,3928118691360823928,14142278546942936343,2679359395748657209],[14976635849033394584,12693028113700143756,8556900731424660789,2479071586075854732],[16293603354274511102,14004339573843063077,2293401563603111927,3250682197505904880],[1054040410815461346,17798541936852499163,5754773474005767640,3152347789034294909],[2896461193761368620,5123661882372057222,7792521968665162894,2361168494016331914],[8663935098199978849,13835238348967392798,4470330971677440678,2148533397952053865],[8129023979953305198,1167984171595873352,2234940979903883988,39135176196207491],[1794580305948458188,11185681064944065576,13198401992273427,837017050345062388],[10191479060830714890,5876998926148981656,4687258378611793306,1334424931671029321]]},{"leaf_elements":[1302779286526441982,9861996584068511511,5194180020453527033,1781828945311004990,3422078908394773970,9261759363653010420,12598487088152973496,18389936683978786009,10108770665990700855,4739242305654823461,2478043581108139755,593529639804476749,16495823482470698255,932804033946368471,1451905010369700247,859557082717159875],"proof":[[16588085588932381956,16744109376040930255,17957911821412092463,1023524645445732320],[5301302968971618848,8634115784320844693,10454639550919907693,1265205143903885878],[6974886790993551670,7690197373519663050,7930603470702864315,251367905003694073],[9777082697553074979,11490364362835791261,5563566627492349505,1942668372098188476],[1403898427350771732,18228146078995171596,5922495458194846637,2347219429823012201],[18153576148286557083,14640067003341976383,10069407996092249333,1463178912408274447]]},{"leaf_elements":[1343473011181599834,2148623295942189256,18393363552495683767,717497299409576627],"proof":[[16026800034025279006,1194109106632403618,7921542045564248240,1024326950638156692],[15941933539944102060,2160270490326863831,12647024975027428740,1411636157812324243],[12744419495274178689,5906428658533240638,13924717635013361658,865370367338473700],[353760822651704527,12104545132180141466,7398019946229802330,2208996632836641894],[3673477206452052080,4502936699897612635,10664607323974131317,686724019868779651]]}]},{"witness_query":{"leaf_elements":[15264195027700865049,17411722771691801095,18332465760459636874,16372347739107711813,3316444803383210944,11933238464690485017,7630267349596817591,13527827362601910608,7774948128765801433,8873699384175139493,9379744326690202095,4216841978655900513,9639800702315882980,11008322933407932065,12457634655716627753,17881724414925035205,4406401543970673885,18136803093894730412,3125996248759909689,1354793104989574658,16625128729735420186,6365562616623936089,15404620859965783351,2029961019494870954,7347930436591971104,6536539122117514697,17158409101130766990,17833677362965657608,14180659384691395398,11233550920951109880,7389784577003947192,9461135094100559612,6889563792967372329,10620348924313574048,11260180634371162509,7186637199786655036,8183370803784191844,1276826495350305832,12490290146244504266,7416936912164172150,9567399451646608898,9019173647544532060,7513092273902005860,14562041188897752207,3712710027163781829,3059378343862133068,17907337836871833991,1797531066021648288,8452206006698290454,908445490502218492,1183054735166620295,9812912267047827997,16165085651666483627,1267684799510875312,14738379380323445290,14856703714344996700,13623028241912288198,8294049880635224400,844915260437215798,18400641145203220205,6925819632646541189,7185564750466179401,9589745509243308567,11441635152689003430,7686981426574033499,968070891393390569,10180337181722285498,12133843552184437255,15850728374588490712,11152550481881399039,14650566854922707924,7738108877060423024,2537405289081369908,3726853469657355745,16907305533506533530,14361517034540691655,15109818405067630592,8357688199977572666,16071245247781409061,14729280069661600667,2074338213142989935,6572895326107540863,10777534155047975126,4024422357043916733,6326613923508769587,4054450380667088620,9998144084799278041,2060919631312121853,5389872904884383897,15881282215909440126,4748941490435408731,11102560418464784741,13924866240590803084,1844065190232609005,15762578933462431992,11186897305227547569,17694950921689589496,5644142632290245344,5971340126921239231,8219805660114174404,10406527205161592433,14476617080238961934,17897383406612408812,9433557510660990471,9949040808669481463,8801620997568323534,7610455108639656514,5118376431274030389,7197729269642356490,11183066155725291920,14742526292490417873,6175389096891223934,4533744927809719294,6270512859024088994,11474055141096737914,15632042604294152378,5777583464285673476,3667280757409572623,405017570861001890,8606482913602253712,8041645936249415519,2755735717089008547,8821290602755901062,2684083027432947293,6887282638357619907,15132990489477824041,11335413681015886271,268065473802372304,13206162893013240693,3424835056023155918],"proof":[[12659069402942114596,2241719808180272863,4652573147044025490,1972079118205322281],[4233457212652529458,8754389554766734826,12941174712215076735,575614450420562881],[11652071319827077932,10538669807022404228,12524068846676075041,2376116730151711886],[10933390148629294295,10845788637903799785,18046021149769702214,648585452748729237],[12391807971878196134,6387059302079900877,3429216611193099212,2006491652667633005],[5925330915275338083,9248598802909269591,14739557336436363627,1236897689630771420],[13342860528013446817,271953231402007818,16749067219432905432,2950195287144981342],[8983265729822105307,8450436361272586618,10162389242478996777,2045800339585875739],[15798851299890398357,14752648323147941029,10592568612826614621,1031705827308204046],[9889885725882900055,10923388084776848944,14249511090075016334,3084354693631752326],[12096733672131514747,1834692536501123487,17641654578777108976,1771707163897572961],[3517445051362519562,16557746231833977230,7202384885385397928,1237462838644787593],[12061552858743397432,290202522057394999,8595422394194221127,731781620910415521],[15462762030847683677,16608870848840747060,10267397435805044048,778481188934513691],[417849683570094318,18287094634337486637,5713169179383418667,2020804355764788244],[17470382594321666956,17468275722758095024,16227708838307628316,25804090821279447],[3041623770239361669,9490991598386068740,16101108767212442451,3265692143145646535],[18277843149013547355,14809091392936512429,9355621142330848862,809260657301462975]]},"stage_2_query":{"leaf_elements":[18351725027735021793,60240977442725851,12614642423807299838,8858406516528424041,18135105176083505454,5737020093641863395,2970936668662397248,1899164818834497874,4157062811155306135,8075900595526748090,16291751722338791888,966269399894733790,8582447046147546377,9354884754092090580],"proof":[[6823914463931384539,17317346227027019345,517035871932656086,1357373189104500425],[13000260648261411052,13381053177938274660,10673446179559480367,2634256663767665384],[17178035525029750209,4995110114590502243,17888566418194761598,693541871757669466],[229031110334764030,11675650625262892897,10727783745014767089,1809732732354500989],[16486013903888623628,5067007559690583905,10266969295820108744,3231321682697551874],[6338507791977952278,15296165471968794808,5029988948622691395,737197953853482457],[2396260415702555027,13639414598571907570,12722895518581266502,1303523139565569490],[14846171554917114046,6707747795127093704,11037259102203071138,544418512086727484],[1029977721491557096,17357588113768746418,13780514302163509380,1906882275163220571],[14318641466730091019,14853659377744139427,166507727602152695,2882085731070676899],[6594783773534397357,2011024094335359386,8876651522108238749,2900240039902466119],[4634963555033109185,3705999202466596374,11337945121211321993,3070884824867363910],[15527895627372366979,9193879115538058043,8784334238892900687,2972693025526711419],[1836187112615886622,4928320808418075236,2572700825958068377,2833516995727519417],[6441369834981090680,1133906278942289194,1300335143308351724,3060172807060205200],[10919711537687047433,13764668345406395919,1087852456812173000,2811002337465908757],[15722468050024336349,9809391555685642102,10842667440351032812,3043578366828334918],[17532781819212732907,17831925215289041278,7997286019200983105,2641279771507897779]]},"quotient_query":{"leaf_elements":[789974419446629138,5171684804480762836,8550351931420051030,11870379524220813359,483126403139996357,17937529840184309530,18162577757129667176,1732324297305832311,3360982631416043239,10857448058121660935,9800252068060437547,17482524212638461778,986822832653978083,13527117430279922538,17802998032301953230,15726139656298215320],"proof":[[453373798656794190,8480144436868401457,4367855302050013905,2453569615415359656],[3418265098578047311,12472402179896672162,8127010584169234862,856573555104385085],[10245766186897595011,10145147333442444740,246967035201426258,1721825350883761380],[4997821238399488896,17938770219997947332,4725292745929889454,2815689530488548999],[4863384968294306251,7838798001121298480,14555524649675110553,369888584458289918],[4511598694592568942,2203777911063661329,11850706962491864791,428867075677102951],[7148823700389933725,6861145867444306693,6232748986611359372,2898887486615804275],[129485923889969264,10148737778258444146,18195312587154870154,3083592600451842685],[11396161174863263854,16196488291671510593,15958368825069989430,676222014149025997],[5738944151029127178,7556813693139191074,6216363811233578458,987689627758625867],[17258520894265549659,9372819079698775017,4605752537634746235,665462191974576731],[17273852188733842031,15414714126025724069,5937144248212095543,1119282850012391080],[2381423404961356996,12222310243693180185,13746720454320445409,1621146981691604016],[3095980969477464882,6507055443745816352,6027505728769493991,3364151805980133210],[11984938244403546256,12133260831080492630,801941294356778227,561400253630078759],[10968348770004681383,12950044653531662906,11356898358089912440,567974757515163231],[17110565403311052654,1268786710735689959,5264257422090835948,2472960016547084931],[1048583078666817295,8464968244547201137,6049268805589188523,350591550118182394]]},"setup_query":{"leaf_elements":[7229664855569746115,3396941415321664212,13251369444860273063,180296991836074548,7232910398828705848,9336645097298840066,12489628767629527450,3840062800572486263,14062106361756173435,11721035839455134284,14632067524203036976,8371039882538903131,6662203684995837683,10737551417935377138,5242110691143228843,16018571560456824656,10994598587136291345,5868097842956920623,3300949887756219873,4386701811231914979,5755635269553979524,5352731644217782921,15642896003160704482,324228346578432379,10214099864055468755,4734922187657158064,13380921768436195019,2452616533999861015,16757633383686979459,14412886251761627471,14859482804509709876,12465904887552522382,12884011100625541046,12462413749069702784,15530995525281829589,8212956388046575103,12544205592771040782,3632479050591932024,1484362695505321886,5691881827445267810,9402804619399722559,14961231974524729205,5750352149729035097,13255110011199483951,10745202059841519799,9161318283319921967,16514911615793764307,3532407024622575095,5747125619903553867,5551300965667879561,11583862640186781995,13411798359168389026,1124582131513623234,10426978668861303288,5335743961326263894,13595392292811854855,11034622721439984038,9176663321031913242,9238059234366302873,13686291883411320447,17582743721057973835,3200794667599759205,10125166559197058463,17785216292559443974],"proof":[[4019086524139694372,7510307634728623179,6032571557290082004,1495834041710397033],[13474697798288953925,6361222955187824640,10831759676762348928,2791080412926896537],[13270784047460150086,1514318512541024133,15735680778315174921,2744332700819122450],[4738764858436388780,6930980971136370178,6748766369581383870,2844036306424389793],[18357716685349069918,9596178517141423485,12497523232810086865,1258885374328307441],[2569470627610671635,16806836178966557559,7273009402899220316,379826337533943841],[12554514901911573068,12601585813052644882,15361706094527339149,250164389715421662],[3257050187629664655,6005997106495956889,14313968132910112102,914519351096467730],[8326076291097725177,12159696019202793990,1929847846032416662,3087847781507101987],[13867795878791544145,2590891235040938790,2400242218595520711,2084356489702941140],[8821902952239460636,1556612095897087982,13916615937380917325,2025982428364978085],[14836989037077830629,13311971590813936029,18070936923407391867,2825493166241976627],[15902444196424033817,2976766288805764506,7554443996183525392,530514006340773282],[13773252690177634140,14142246582212388371,4585669868389823140,1785820698067927577],[6282538886361430873,18105557860448041199,4943514710248805689,1947877510218092655],[2657613675415368463,14795508036869113635,1297761630665648857,3393070002130862420],[10182117167083697258,11239087945138943836,14214271882577843790,3426401618090640852],[10205521618026419140,13727578631647841720,12765876539523016858,1749189693691382285]]},"fri_queries":[{"leaf_elements":[15748055499696420905,11480702569797006777,1456105534937348282,9152428428285786703,11320103645511387767,7783772598098529211,6112585247482347658,17393755283578564537,2846075858022921471,380263156688253188,6475206361125621528,16343362507513809953,6196507934332172677,11859600075052157400,12412983450343778241,14681403787669048375],"proof":[[9561753885221546078,8361201636131953775,17406445710378833811,916196147785284538],[2547899181791825326,16767889159730412787,10306055579826408833,3343165575254761225],[11958862113900654521,9487577672205560779,1641087654705913692,2514617519318647273],[350930041172086235,18022785785512626733,443619437642051369,2223950076195732959],[4920007239951540096,1658483890158012086,3553386246882501233,1011559902674959258],[5918279066094726280,10373105846003207633,14812037020207042217,305813189506188726],[11886893024583016916,9571144561542480825,6037073957520765305,1831896797126239779],[3256513460818448222,15925684047067648278,3824628107607749376,2743585344757599771],[16595009966699383697,14174605045951804272,7708433155112384529,2539750799431521270],[7035744722428977038,3412793805092287342,12036784002525740535,582699547700181273],[13945829251741197692,15471760294066584410,8446962931390426955,1888593531303938172],[7039857095118296080,16248501768304790390,12934172251838497031,3154422432795401135],[16297877494579211600,16818390641717090181,9095240682564312517,3103010674994346786],[10137816334095415360,14412896466076556556,9484928667860420439,2145775503897167170],[3909027551869580616,16451289421824023179,6871831572022992351,2062921579877598264]]},{"leaf_elements":[8846146209462465862,16095067335822835198,9755980512190364607,2222946321030365823,11023098485060925880,12062929285174522803,8595251994218065554,9947124441490906879,15871887520916328221,11316828809810194411,8079554703612741120,4763438066414320368,7105730323461100290,6133352724197488869,5848423551641215788,8192210528606737325],"proof":[[2376807949173058464,11563794612545994011,8824774779719272468,2222244501813790292],[17040781833040767733,17120791249085312700,12160944530555777991,2262629051739030256],[11368371639685303768,599727414031289976,12631704788243724580,2527120917808709710],[4187823581050725151,9017764724199726506,10544135004564744764,642932440558932612],[4332186116610144304,4311816453812398331,3951880028978597291,1627965864431543734],[11368494431888523368,6722872598272305269,16283044692121663903,907425094920394095],[3217504633688282858,13705392519705481218,9954678948161096390,1700688667131706556],[5570576658621306618,14871394379617042748,11532736354880286772,408761154466322533],[4258274613166033567,4769858407321703239,4121981711343760043,1481903061640626305],[3311966544673968231,10550739631810267422,9144101156034976539,827098086485794130],[6462477162830526455,4417107764681972576,3572092280387770722,2339233396474479388],[17257895725527976808,8785426568597893200,3138410151362096150,2087021156881475193]]},{"leaf_elements":[11571021068022847634,17154965986084449545,5339278478280683143,3409658793215488634,11767796032479886561,16113078304142229686,17312965679681518720,3782077595152366909,4743797398564354281,7986744248934065647,5685333539000314303,690818323170090523,7520557983001954288,6258771208108093648,14611701370141487102,9988954060465842642],"proof":[[9598377299113823693,17478770433789649138,11796881266673801267,494572985114947454],[12546996736458293793,13321889147540637334,18366965078935454344,1560034083696627215],[16273606822490254081,9788467812540907186,8078687917263555975,3020139748634771298],[16523877091752748077,2742619808145925676,10864587918870209386,3068740381780789786],[13406438846975570799,18268926997114454016,4004204812383007748,2969852194586691268],[2102536071589644878,7961157944922010425,4754899557537289601,3152852414606265311],[17903338243064815474,9869420360101887373,17297228956712826827,1276804556216832829],[15810049741988506993,373473160880589312,7392855423637248045,3426171994075541120],[4769013646190856373,13408788504856505828,9526807178983253050,2120796503420640317]]},{"leaf_elements":[1382685390186044965,4098691841289284448,10327213671753541185,4006801968786897971,4692653898562720516,6311289298835662486,8846720808607035242,8469412618924367911,1716495913777177301,17949595083353048356,6551356123024637760,17591158478961585885,18420459693227727732,684186660008827560,8456586168115149921,992415968534138118],"proof":[[17747444692724101024,16800872739926913066,5505908763361722746,893199708332313533],[2470989530533064062,13397697311480546283,7732618918112322016,337105598463173553],[9785724853037251269,13792260910600230576,1070157635194218823,2057050496209767706],[13042993270386535122,8358457265906593972,7370714285191245591,1945516835192632532],[10504824041787275030,7050134477050390530,14547332349177982851,545593301483999747],[16431377848522246494,7384648657348867317,8151445098351503581,635437872326501392]]},{"leaf_elements":[9410680236209210982,12528160140329162429,13128750748268823444,5982110103636436950],"proof":[[8790902610676572317,2045239567499880503,9467998942045972296,1619461839866021893],[5080861109626473571,4086822526198266025,9308078583879659887,1387911158763904097],[16339601442872204018,12382399071273258293,8926553520311543513,1795195075786347969],[13227650902232864326,9665384271506823306,5322259365266114918,553589874761412281],[4913106965313302990,17942911988888008395,7840008451284248817,1780516591546490535]]}]},{"witness_query":{"leaf_elements":[1240461012959860013,3443991914245061696,677917324168379307,13527152922608388341,13340118985216901300,10681013997276104456,14901657602670613468,5672775602551917182,11937095525521256948,12888810033747758025,18182759436767723115,9662247539206685126,13534644803065015704,14339704106894980229,7806665400867058096,15244992840508770913,8073600549732031792,408462217968997144,5466216608729525067,1771198840576241144,17161976333890994428,13916864359061951925,6909731351691162764,2731060930461991171,92512083052286484,1302894147995813052,16527505756074169592,9355955797915413607,1705638364179080038,7564035594110160789,214399201408168630,2661304735149796409,6019617696510990359,10343310559083354605,13186095242950594951,4137875991192795021,15304683222358333030,6882493384936560134,1022487826386797608,3407231400930415304,9667219267901580819,9686178648065859984,1799775218819496850,6797364376918793075,5603728436991035802,10549139773922873567,16278089233449190597,14766284390024060197,553847689626881152,12305230863921497349,6037220110613129722,12329499905592633602,15508552332705500135,5146504563559047381,15126890973441594180,18394150566490334957,15990989381434734864,13908474419324933625,5674877686296183251,13858146570139576727,9143513710315423397,11408669947048071179,10343412495885063465,4512669604950760805,15131008697913148432,14238196514041202651,13771147774026461189,737424465257109510,12789920660681264255,640527808262338603,4543736022302420053,7076744580871759975,13022596597799903744,9533305878806225751,8655784022171641614,5203051862414935404,14354589304590614904,10634832687709962235,13600074513457661761,3987823996025382677,3156336550713095969,5508363382996128033,15639332220458133724,10994679531528107370,8334187432047329297,18104834811882610913,17454108175760773083,3458119702037601695,4284677846207733074,16476551370565527533,6653275564687135771,3752169834239908434,1835973247631776503,17198092340957570299,11559019287450875377,13820699062959444801,8400187995820442476,11248564904618685660,7884436225440608241,12670258680404719623,11197129033377293678,13760010603116695346,3673315187811778551,8400749421597637418,9023497815196806189,7304254519915784457,15662833067402005511,12646539394377417610,14307599174026303059,13849764521785678133,2772347260822364681,5065292282519801414,5350274701281650915,7143782754220365543,11758043085258299447,7046179177457695463,12172347814369078017,8627775487554339060,7400062673828506997,3975953392814984201,16298742016186883519,5888190201503565299,3103885172894298912,11176271982424533359,6349723357628495225,12081807716090878530,10088563883627060415,178175866629492276,8479586684101665608,8338765530664067221],"proof":[[13151734455670968712,4848106069568894175,17377421175483914380,1831834638393142683],[13765350372119549567,12615465233053753194,7547205554860405522,291365261674263888],[12067049781194469112,6486744899707112364,5045790475868963425,2269987085139139642],[6121159257969525384,10520124078757519523,7371912695206135215,2681035224260656393],[3710809890780911112,1446366425323799744,13615368823921498738,865847158553761296],[8246417627115212147,8568500411658019186,14823918742000908001,783668124482150887],[7485526814054033621,363754402850340478,13845724732313227371,389350351775970768],[14786365016778994016,7764304452582432744,12713288302899936727,2458484385441968305],[17122007857740811391,4645593186764903687,10736704327564171248,2456510273675481195],[9082822894782278224,12535487412018091200,15293198817000991569,563396287880242928],[9690009535531924764,13818739462004200774,4900356676302860256,837937054663476341],[17541765465042902595,16383308106172142687,9209516027182904251,1892205237150171213],[13914344036193505596,8370373135046552866,10727797652753461884,2018733489645398460],[15112313259818890023,2611199464069890147,14760360776698425231,532006389613047411],[110995276987627834,6904847926360899490,16086253147905755866,2352226082529667946],[4922580221609179407,9786110868949352521,17400722085657849173,2559524062791015839],[9621459891212802427,14246044861244598206,181098648177324320,1964997777367736681],[6203625007813228202,4647331877431346587,2483510041518548781,2219636767859339725]]},"stage_2_query":{"leaf_elements":[1151095754403174999,8534962918895648598,16761745048816883062,6592440814315876748,18026606927409289126,4255499393007841132,6531546954367152823,16996363818732633026,538868106158354952,2173071440009308270,7787713121009957041,10630955772653512578,2581857435361998695,8350222060928578609],"proof":[[11342723603710438944,11568676274035091045,15986273503175450375,1351314609408445579],[7294642697598117042,13185376223981036587,12171967089674626519,2543709553508791105],[3485627229375213263,16805484275507533719,11199015312928335103,2934082003047154692],[6551825674820367884,15150139737534102599,3980760851347649698,2856385150703355567],[9009677541943151046,12972127460843673238,15527542920524371807,3424788142033963691],[5445325647669643015,13809721481146078692,5346461438573015858,282598899275376937],[2651193533780614878,7754528879177970079,2386266013083289679,3303008372374486383],[12307418555447742237,10744286932723129408,9929148554563427511,2627942310361805836],[6771722408614187390,3151762689254320506,17379252295217448419,1929499183218950824],[6330370397218272244,7828280583320891501,8627610289992579998,765602317993948855],[3406500609864833581,17162399637087844692,4242391920326821828,1746587894633595242],[13387284361235893909,1130220071658170247,3493798618054791962,658096155094240844],[5946254893707799884,13115642929481536600,3689235382000045672,1039495772273386333],[295320769203724486,17157988264077876634,17844836354735369715,2529110706551965726],[11379041403345428591,7693424218283120411,15112541842817159682,2612975598005629166],[5479976111471155901,9473208448549149019,17604283711083282279,491456573291435308],[6138342633835300778,15576651104999955477,10603104946026547962,2984328225871505454],[14233162489566872102,12284998496674254926,14269259877273341510,1074819831927582406]]},"quotient_query":{"leaf_elements":[15665914222045182614,17424209010875283115,13582275188884850465,18300712948718796270,14137186021070057818,12492106744984687436,8376610467527804253,1631789487578716544,14268108117984026231,254979643297651633,10517685242050802536,7804199085032936714,11932201539202930847,11208387011779012620,1432350569220148727,11514554053870907447],"proof":[[6740525195872662429,860693216704533075,15304910825662381603,284674758099294543],[7293171975574836264,14656124472228798802,6681887152103993403,2884175359908160327],[1568844426317396879,12483250202760879027,16650320810977918280,311797938000044393],[3217869823359592669,13618868917871766294,16708952828171161985,1634876206679776172],[11202682742555286218,14815814754532249487,15722162769509139532,2701878270635541443],[15944090583039809786,5650055900178403180,18402471211796443026,2913885270787184326],[13428550661853982495,6208372022000495459,17483426478394842912,2485017340404830344],[1204803202332835115,9206418131328817098,8592981150812930709,1338378576342241751],[6656279385571522326,1979126654569538571,11993681394349859836,2547928420381828532],[3239500338135437641,9374095047215748747,10592178002729481209,2779229585505360414],[13779361659562739106,1148367770515332845,404760176392902921,2214407572028004731],[5382154086340242370,2229710541732941969,7276982356939719553,2876935792585246005],[16783188345076600028,14246984856101453664,15808307544304638705,1983981033742030997],[7871624603444416730,380286058782604312,452467871789107764,2535350337174220019],[18135220649616176178,3025266452246951674,11162714117940625810,131288886156590573],[5031116513332169526,2412035192548109385,7810242362958191301,1695018573269366315],[16987495525008493545,17540280952016323734,17694649372640027244,1769387588339876426],[14457605553819322269,6037604204805506213,18060175469066365735,2331474714530997802]]},"setup_query":{"leaf_elements":[15426541253886520932,5548077407856308406,18205565394042554799,17325714105008732448,15864441121812578303,9819050561169163017,12397811036888947774,737661821036013967,5984016295571573415,5238151441345698069,1655714491770751403,16664549206772064990,16994451574082673926,3149319778999187911,5947418259944999330,5752328594736514157,11980118037131942118,1462486699549149450,17298384524859917185,18331934241458677701,12237737697916381334,16403341531933638814,17457192072195979664,15346623687609136316,17062860809229728810,18085769945102082644,1072950754149903180,10053451395236903059,16149555362665158493,11793363768184072781,2407942374243472757,18337504131894527359,17859180252248936462,6954662163797323626,7665307767199850237,9230520076925608468,3747650038686018472,16145386830130957750,145177162410453587,6412702168775348139,10473665553353973391,16816172585782758330,4568633509793579462,3317921015463533175,2101938167283375319,15743061915753769176,14737883542381117579,15905424501583668043,3680984544693343885,13077213189468949893,6732492329666367228,16023068828165960530,4756268391738107885,4612345194388733043,11918448896280288624,1420829608175108628,14503640889509698951,13458533187135169277,5064369963392364824,4234214013950555119,2116750828984632530,8847717307046811964,1570137967447596335,17765037204847232202],"proof":[[13375166632179024328,8354563224974115659,3273359691556072938,2232596315099791329],[3398009193131956273,6931705696601565887,12586250460219667546,3371272597065681376],[14481065656081286498,1015418754463658973,12147117052678969012,279172619728107520],[2179927451870448901,79250495015778454,226640683007019081,181738473119470565],[15772500154298255562,9528447488743564239,11066332672064711338,1194859710270331077],[13191090611281525874,15579185296840902559,12813345281907516812,1504493966323145189],[14055086091366873932,5230584937007200304,1854203208309534329,2348296448399822938],[12764239334881363410,12715023163398431030,5433288181954143296,486147459970023395],[1475775919673082832,5889491910497781820,12486974432384470483,325400432615002163],[8401559291620569721,17974999362203199539,8184218940847738178,1930749978990652172],[5205903262179493276,10713494551069720249,10747402014534485622,1586132212457793812],[6059950103874771460,13497901589930455340,16480026304091533937,3479413883252208995],[7480652033530288799,15190035345152515391,3821367929660886657,1611939969429355169],[2204673548887801700,4682747794380489691,16642107804114109745,226200663015537959],[15669734412105801245,10499657269452008775,9055908947484509805,2915927043179069863],[17304264364367395603,1331974985737223877,1656181910144040342,3328671290069282012],[18038303815280059110,3980780450534888397,922200225759201059,182629147268891448],[9595345913093692807,10809604427596475797,16931119990738015435,842210882908938522]]},"fri_queries":[{"leaf_elements":[8183885366867423860,5952012431991020424,14015217299260328506,14990683546017235643,14691216466038685932,8189079031983410707,17396504593596390905,18100331049019821556,8585127925892566814,660162544771647237,14719940791200244767,16708085686355611995,11764785314414660002,9414636594696879817,11250351431936114189,2118407140670947898],"proof":[[7139485690283187077,2567522716340147845,1649718641334544756,3147108625111493821],[5393272948878467778,8854598969413165223,17419482005200855093,1274849705353097561],[15823738776020470004,9660212601527302520,5122359943206411358,1461086666569062929],[11517007496121187546,15039686228318213558,6336261528442600417,1401850553839228805],[49260635556248581,12745974732546420053,2024789319001687671,3318515791627867237],[6668545504800596186,9596108546035435616,1834889112347311441,2594562682200349173],[11633931153734171689,10531483880926617192,2586983379017070185,2982553475030841119],[8300416343640078470,9197947959631260625,9395478410296117718,1543511379591811991],[51069108434378911,2858832428903401366,8528881971247755798,1067735817493530257],[7874811507061494781,16905465650775098124,12320773751412114426,2661804070279266591],[14153000763947706530,5643324089301117957,5878042416029269580,665822854311070818],[11744360042206407153,9114483337402054729,13509990553546541487,886460352588628152],[2268161179875263525,8406676677814337791,11686580585018494899,371714362535691050],[14324527800066162409,12464730200029420912,11815892595289798233,2079311065820971643],[15650324515562733748,6392329434116202259,9428903809532342805,1317692484054466098]]},{"leaf_elements":[10927194946504489856,13705497996596707,10348219231479268646,16933248047555585745,8983967101913514393,13443036070033651314,621516398076585326,14642455662579538385,16306457841345698185,1458886039062678817,10396834997504282536,16099149592834985491,12289264652041807685,7218997886888908389,1279071314309826546,5742613490658691430],"proof":[[5264011594923741619,11439814959950867579,17386328869644600233,1886093011074557430],[1237780619344600149,5792545566083489023,10658300228100470350,2011980526743672723],[14581415672397860890,12045036841255685378,4710122328807822435,2765696863207906578],[12060320882090966836,4455085510917287267,15874116326447169077,2789250076931976060],[17816232417151820701,13612671379530073792,12057888134925848989,723551818152181449],[2530563908801900354,4473147337914482729,16592061034503485006,2564205844123374090],[17347301746923135767,3257896834599456274,1259049068542084771,2090418935606936953],[3992555350030333987,13708467872866727101,3606200865126210044,3183949401896977362],[14527899313429214432,4808167019492529429,17019144238856950465,2424093979284638687],[7224080732452751736,5339181207764051156,4151245183796594214,2790177991997859329],[5977680522738684693,11711534554713163476,2835692713440371561,584528448918085615],[13045349715691377444,3013070322268048680,15925549541035591334,236947855457869275]]},{"leaf_elements":[12960515026451962512,11467988347772461651,8591131776939545134,12112117629125884135,9299346936855154380,18156516621229343840,3652899915191475471,8286176989083589648,13036958086128697693,16028101813602174515,230041710556223462,14671919999430713571,11245905096947123064,8831796024466227804,1891853874065459005,15284123781986735897],"proof":[[5131769759006039966,1311716183937882973,1616821201848633274,634535833697889958],[15200850696722560991,9915571213685230899,914295655606003676,1127675681292347895],[10441921240822808665,10914173378796643533,3415361212798916816,595871313596337534],[14074691356687987209,7116047639753269206,12626410903043292839,1564294018804355907],[11245470335090197047,10008692655464711365,4294326205410640798,2093680113988290045],[7255615517297196522,7617420043842373064,6066714339941395093,3450990413728196334],[8577182322035082613,10912040523989408862,14579468512326490578,242451568031983128],[10414747858782735543,7349157183702430106,12140656916439136734,51966059799202161],[4519553264401158503,18121637157677644561,8553608889965709204,1341859082359673734]]},{"leaf_elements":[14892315213956727447,10820400519922877652,6300173756616280619,15499636175509180139,453385258365918398,15052658553961939929,5123744129653419141,9979724188026843146,7891570697483426586,2667642302071692638,9922359432240188051,18364931190959477901,15539750752003199539,2000593307411191258,10418059846202040134,11329177309249295396],"proof":[[6975761936420838965,15906471765034738771,486409349664705036,1360933731775972340],[4988451662267688041,10796356167032969160,11467462257822596757,2196693437477407280],[11322174973153227061,11655870964542634959,5838915871582706912,986537307601249311],[707716881052996732,15646632161659857653,4745433843371957971,2257777175091103998],[15641417022334312675,16573842776178159005,14536775622154533563,1241601052329201400],[15370587291698764709,8843860872397163748,12941950735259182052,3187690161793959251]]},{"leaf_elements":[17022185655917337845,4916654720621035566,8595953094812165323,10514907757093095071],"proof":[[9282136640369549177,11183068777850376786,16676141439477520883,2839922821449113719],[3545498774300766774,11890409446453886230,5572644691218732342,920488609282711454],[10280065153062008895,18065314942021227455,16958915027434911136,649209603223609353],[11373940827425288983,16279876737182693747,5482361491893353713,677937929076876904],[17184643784617070162,5980745144652238732,15621801712456388722,3440166424394655153]]}]},{"witness_query":{"leaf_elements":[9213954805413172855,15324601133656287712,8646361814485591672,10936933612126726315,14853026574662145908,4888416698655319667,5497843674669647551,17983756289202280277,13509097299187457672,8127993810692982140,15699865326948929006,9314723524159588116,7572687495705708784,12391419895633318743,10442545575252123113,1036602366159303164,4375462337091857818,11875876464557672117,16286517399601062711,14805650544703369296,17972063491705970891,17270264338380985694,13856931769783570551,11867644309135529158,15772659995668653839,17547808578508584788,16732213256640822059,3409976791055092344,18132116303342704045,5787902790846995005,11024590307760882722,14994513353400219866,14321875214938790516,10004673202184994968,2476114109738329410,11118129313310136799,9068532800772817476,14708070553893752787,9631512328092166336,7432445375307633198,9152496808707502376,13183974894880590081,1810477253008224155,4252144304961518357,12729200200622696346,5993049841956280213,15703362738501806016,3463224327671802165,14351823125454405676,6526442941062080350,7330001705652058539,9380890235159717167,16251867450518880239,12891720504602908843,5550101633299935034,853304069355634291,16459105293006846447,10784669304443578099,620798012975257403,5205692438832291176,10184541486996956767,15097808521862631666,392913777003291317,8511148724660873614,16620709507000074473,13855938256112052687,9578633289986317835,14216063128337078165,14793566962150398708,1781686201201185958,10826336719259017397,12098219974664944321,9560440473598841308,14869718476938148344,2272038735214091195,18270619287152336551,15917221867827832418,412778730984547489,2072059526152774559,10409537366786780361,12258858910928410641,4464049182145980240,18338523952740518656,16506357482897634645,15679193019784915602,7088277324440743254,9147547000341479819,5084946648014448174,10779286755826963788,18416276060216058819,18263759364453926554,6030389448779360380,4376555945000237692,13538873472160940072,13248352974458512503,15869240927336583047,5099450909444237319,10018626652688158292,3278719376964114773,1388239968685046204,5517684762648308788,14617429482327123295,12749089719267931247,22911496079629603,161114156168834224,5687849924946251501,3925593185333184785,10574396789276525542,57325714745040843,2789714896753329187,3512386798705071269,10624879267534596250,6360306395921222800,13583215575748422828,2365199662214965853,12324439031812047002,5298518056807753371,2989390906966304903,14768994124275658514,14282888640928778130,8997101456784442947,5772434829491631291,13350299732432081178,4920025602504004810,15555399451499443199,16873461413267771172,16496126783915592052,11536781884743735836,18228510413469805994,11419581476177866306],"proof":[[16882304210373957891,11713214325249457459,7601260929808600999,1075087692321550013],[16358222441496620962,14561694591839656870,2712764055897708089,3091570039504692798],[16594038077516785926,5633637993356265840,6399597669278908154,1862688667470694850],[3521065815363032003,16219794374829324240,150298335687717430,3408163425272644455],[13959979994895869195,9282343763699472831,1373406195129582907,3297299789281837305],[13657882543619846496,1044297932213270582,1015952453671106086,2363051804972269350],[16855906310262172614,9346447271136461169,17141735037442596204,1302066354146016192],[16183535634614430316,13146052557657851149,1483344044023337449,3128864521511455989],[12970889044388892888,2275563148473789616,15287081055451130414,3066410522343007203],[14991871332855325198,14319799702099007991,16465638503164299462,2489962403652491837],[6350214934769045390,1597323614276387119,7329907033910016290,3107303716922214417],[17165327217902698856,13436360985474948206,13730566274938916521,3349792022331409817],[10349514900613188127,10490717562083436261,5618037649418411482,1141171569978484320],[16570285931499647634,8213183625394632323,4243970601100079083,1918489098682134786],[13288324108451235707,3599991524033528698,218677296866413617,138571841650054773],[9979780177053412913,10626092936634742234,8936489590242666503,1684560858131169482],[2835464234335179670,7640858689103246030,14239546580147084071,1326464547232221908],[15335481241739237039,2825571021651209473,10407989400057476785,1104159424619562462]]},"stage_2_query":{"leaf_elements":[5816296859019251988,7350350078960040217,2711614390724866492,12238515116508291878,4780637762783172537,10610464761543258010,639863671126771845,12166171335758696231,16378040813561657088,10393766685907890230,2220742144601818918,12764376606696254241,15513989993317670687,14806488465341131988],"proof":[[8840414983377710671,13351214353199116277,4076483827785078678,1510322158556529531],[3097034235707541672,15924547501809552084,13161879913859652552,341692191342892752],[8677257654621692977,3401175164138362606,8573876037234094200,2672234035152102917],[6664672703879016874,16618461998639336548,1825899911446041318,2061265167703064659],[9258543145531734024,58536519603967895,12860239837090937347,2559737687969018353],[18303526342407636013,11797118132054506743,7052640664129158798,2276425548973732858],[9335967423264118582,12781038995268615647,14356711674604584504,1394993150987654409],[8619322973263077804,17748930297626711817,1779859385798781766,592564144464240122],[4775869649565750229,6905394930585732862,12356779682929390703,286920564002812110],[14527585292020421482,11275487124215104559,13188642527861005820,2235439064682512311],[13736684405285893044,15419770884516865765,7716521825641041801,2074976825611758837],[9612789793392671987,6616827635027376332,2127629553694336941,1559601468761794840],[6607132231007271692,17733185848365335809,16847105233429227432,471360974169912167],[7608183321397478899,2786292979249255112,7397116476950241956,1924269381868917465],[17353545887665449291,1259111685744731556,2585618332841160330,929029362707760322],[454801693554104041,12407297761648162227,3932151663358131907,1942077836249906930],[11899823440923315146,8849615674863295126,4665141740228251428,1247633095688830091],[4322568098889145445,161610071230252417,1659351114233594499,495571118860981034]]},"quotient_query":{"leaf_elements":[7827494968831125550,1712425007503302456,4543531008297259746,14938901557880228367,17986073211848450669,16546230579875568867,14206508812703866621,5347249559730803669,4679086341740198935,12187621623148093002,8333065819478732064,15848353303222711301,3852925401040761569,7645751177775189552,2092671832768697169,16559210811049699817],"proof":[[12843229817195490129,8740260793787763565,16649650855969186016,73470036175842891],[8336178391657404928,10758948898895636391,9238293727271464086,2079683572008363110],[468382205225566504,8690269289299656996,761185116535999751,1322794029770340750],[13373556540566582067,1516667091075350192,3049521985064090523,510813955702452248],[5068839737436222172,2930676968693553329,17024921673685139756,101186926844491157],[16357785899793011295,66684922852506344,3291247322026318072,275771258984472318],[6885497682237734490,751041750638867062,1918736273515057408,924429051305654973],[17715282304160477953,3824135844789225606,3772003465448080882,2515386284811943713],[16270807840876339463,2596900228032842637,2618060601521327563,2445799576837318449],[16286707228467891091,4794114311154549230,8995071382761062864,2304139722005768003],[12848352552066219011,17764412458194266463,12061516516989626337,633829154106474266],[8863136371980185016,9418424348790948371,17041284727213225978,1996927015154242361],[5437156966452718993,15562647683143028211,7961882838007990492,149389960116958410],[10159494752144582329,15700183185051830738,9698475073495533514,1712103150580801901],[505961122474755273,2422594983408103076,10993024719413296471,1537553591582824959],[15549542526079574195,4409339384387116837,757979292613344682,1080608818017115252],[7826959409693515629,4864428186895501743,14184573732096387234,492920181947279474],[9319219046066803377,7737802907639788308,3306656416137039741,2764832271785672935]]},"setup_query":{"leaf_elements":[4818453827087862736,10034512761770268459,18239794392871091708,14178387151545491238,15793928029894590520,747869266199081261,9071329459331869065,8100117237703771566,929113468170843564,8231513164219188449,11666934168739997546,11328256926852512610,13919627981468359630,6298260994809282559,7596746885423332667,17300521427114929228,15651332399599472269,2642739681741664232,17577289144251905775,1858258846057750142,7786727217837443078,8420773337884222309,7023542228534844114,14747830895879920888,18318037010575710076,13079348516985732192,15904847606378105884,8484055677412005404,4826522770398952872,13423811851459301701,4962124789817165066,17058725947003900805,14235835816652552668,377476433837236996,7878806773522637817,9360753215537378422,13221979290565662405,14798925350252539897,14276008399663303285,14819215623915406521,1290926537383130245,7266312411954282402,10331744959694843700,6201659300237044681,6786347372534424195,12005104534037227261,14350668680230274814,8818978282673817496,15626239625957355580,3049085424109921122,14387297454563620253,15557857349327055505,18092414306397007842,8785912526775460355,6684211851148540531,9658769364722950032,2918127519747729736,1986620827142401503,13564569059403421600,15105589525594016137,10096454114878394309,1615581211919125431,13555217893814108588,9166100709691212480],"proof":[[15715549345740551720,4791252480300846953,13603393049648892635,2423157234807435774],[15814450338072832144,8284053494718341660,10963147393281301426,3468620407298197441],[16374575426854175010,1459751821105756028,5752273307534503339,1059154428482251655],[12063706398691131243,6056511287905428100,12915632422264395133,2571700559020014910],[3437127946407120702,5496454353724899419,7511580161715157978,102902569272804842],[14980884899868549911,4142908288963390515,13599712543971855248,1239505822537913143],[8448591134425079449,3362201906595704424,9421707111246858378,2350275956873990506],[11196925031507188979,12006718835136606868,2835798656930324286,1666074593648911941],[2440614651677889118,7320702697517404554,16172632176196036797,2889826473392295389],[10059662449541287166,10702031627079310568,14999527910147798116,636988468433834306],[2643520929757389257,13181802349951520280,9461972640504657212,495661980132730075],[12288690435060661819,17364874209425535766,4272113023219145384,729746453693530100],[17233921317301565729,5338464571212339723,2386659291474477131,1522189218945171265],[1000271064378416280,16846255101905265082,5218530665569082822,2090318689988960182],[4205653625186037360,14052043566444640688,238928972272019646,824890216434403019],[2167500509288017222,7091677342342883478,11173723261835213237,276213663524965184],[15523513640132389808,7536391281839378459,2998899503036420375,567173801298179701],[11603769123308223469,13092681222680774106,2241248637488496322,2282898326918459999]]},"fri_queries":[{"leaf_elements":[508384764387027698,14175304784121249785,17623672327494767770,7497479608952697353,9802609137728973378,2332827085848934189,4456919596818940416,5969840920292278662,10989752252917038458,11202769590870731296,6906236538310012354,9852072474487749197,18126615800006592218,5768890686491125590,16775106150642725190,12617618166279053194],"proof":[[10258477357182182244,13506506118832558540,1448417018388265716,2287496799835505028],[15014359712759556205,5453706925204250971,1689263884632669439,1338484052062271581],[16415738389924890790,11152489889697996289,6311336348425387726,195047108431819013],[2008331291696370617,11361137207340239060,2273936953966680900,1983279484155605897],[16900453617186090605,7160912873631005459,16698926939323718447,2415211362070933342],[12174444076042885272,16694667678023622114,6498824280208826692,1770536401139512031],[9490921268048461277,15139203041069673076,10360839376143311894,1576317720590991485],[10133612408776120239,12780821230811002592,4388142847287878137,162436188147030010],[779515619330787767,7952406774395521038,17179581208144365961,3012246868693284399],[12976324273461290119,4309708243392572410,6026453958888440246,2934284054965192698],[768886713866268254,12042436252803830589,17942618239455397005,3308051788357832462],[12337126599003973339,28335589207764344,8391769428947797964,2510385518118350055],[765849832395540336,18185407187650950269,6556969557317732828,2175172641686785346],[10144694819945146988,6672032025327512589,9808010789177894603,1140670695713555780],[2541481095354967025,10002189925744583957,8488775209798173553,144329181555578731]]},{"leaf_elements":[2180242257194665957,7554236221093687919,4828449131309469825,17340297783819311011,929361194334993928,6925258938060925499,14798605319330346080,17450036294352514358,13563623827907994327,8097319327701242538,6266783571911752315,6703134463469207509,6144727921097713985,2694590232400821678,8036977267485588830,6256447267654374481],"proof":[[10338882787699783216,15808740648112377260,16428285293058663481,3308895891792533707],[12122670294316875698,18078782584619114241,3963157113015653588,2453776814231267652],[8361685843099735587,8899622590774743968,6536467402538087290,3205065523218553244],[17577978673048342465,4379500596162710520,17635237521306934663,786334782348367536],[1820150020215336354,16920037725111527532,15292322115239078875,2761529943711937162],[5615488547451273678,3103365771254457334,960769272065089384,2990393097709259579],[15463452375245320303,2868757375099844395,1566928967235457920,2932135062524629021],[12835222577275519341,1602555835718707481,9307417803357758780,2839649711918368896],[16157043204780417199,2116003154603499493,10005758546657188787,221408137048648873],[13371122611552635071,6238882705247713721,17874182841035285392,789601210227370384],[17186626576383100641,9426217686197944408,1953226205575109977,3250843721598583440],[5662214149381615525,16945386033993399979,17326581715328261317,3141413778038586151]]},{"leaf_elements":[6158909772551919839,16261199118637194979,15211633371992162315,11793111934942020717,9150111622876042462,15160843209416670137,6959803866904838514,15142381281208852146,4609453225769498538,16655137624825058773,13087945499022759939,1683376196426798266,13027859662180976995,16316672200796689412,3089129399204215751,16378217899440084725],"proof":[[11037566191284787280,5011372973807771854,6520280988448206006,3211205260629271870],[120435761847618268,12971696043957335099,6073884422148806984,622706763054148036],[17120579765664888445,15969218739612462511,7493355218992037222,3267553937872541715],[15017368327596266915,4207449810392450060,15941821830713124625,158962169988656880],[9532219443110867939,11139654627867696787,8432904442806308119,3288624074382113068],[4250862873784506249,11190929978882871116,14677878586954755199,243735557325261370],[17250142724237995586,11210962206309718164,13006548900961046361,1725689744306236732],[15071984663225442597,2858284941848278028,12186928039176580259,1563624885882413892],[160244967788095631,1615417562416916695,10710668815107271213,1087502143039719231]]},{"leaf_elements":[14045508658081081119,18426253076124305334,6511752942794764242,6674221591426241619,18402665590652454633,12178027090839268496,17495478575832518086,4661224722837665537,10623323857114861604,6257495943520832408,5626835191580863578,12753121714882461658,13020493591569115595,2468489633023648148,8870065573998705966,8306923247211011707],"proof":[[4295086693497811289,16139717035113238757,2149765617334976466,2273299205633480073],[12195146576389221000,1087139487014254697,6465143710172339231,2209937431115677297],[637604248093885768,14144826757752805950,2095580537551510459,825207600283324254],[14491851817398619229,16344004543191149276,356904981892106288,550461571055757892],[1270974324026540938,4596611097145880187,6334645405178071087,3044789703636785210],[7052934682127493573,7469568532986638135,5123795985333269222,3407842648042572447]]},{"leaf_elements":[16557794750219843443,5381045626318529968,4640083617797456335,14470777234107804059],"proof":[[14545184941529475548,6731321421435023061,12324998794513088836,1394558721857141254],[13372959033763291428,1899212459701562085,4787136402950773465,1218543238954675844],[16045080713191701019,10037779362282809613,14614174366005064967,2306182145157793959],[516590647916477486,1195810288688218895,6477251735176601615,2023145603653571194],[3458861517535428480,12761963947732783251,18131325508830808739,1943585634345296754]]}]},{"witness_query":{"leaf_elements":[8077287939796025749,11691491045296931190,11149335592323049275,1919553188750480960,16222679834752309388,1538910072500947377,6265553202647972557,11363523510586439858,15980611336997343780,587087853388511186,13835806191708317123,1141143339590526419,6124712347358356508,555520394062485615,8807834502186114540,10355898634020228099,3709831619906518034,16395749992707933306,6934116790783703583,13688891782298548927,17413263718772582811,9876695644645308774,4623118802914348048,18087388374918805820,14469338818726473737,17329575742254874386,2448434156668757449,14155536351936907292,6280020200292471501,8553336570762080152,17686302201607086441,12069092583008009598,8658455376317354882,10568726632031486657,6938798859791027655,16831897502060519140,4440698675744431213,5833978341302038045,14495550174896045879,17048180192068025961,12422814543039116599,12849820272738327826,2272887827686631035,15789918364659031047,1862736163686718222,2317977990135041509,1167360724057211197,12013873107995334810,10083316122754609659,3364654149256853883,4623927936023179847,11961260649818613469,1973502603633942106,16987533122319684808,6906545934446020567,15987988837842239253,12547479374591414097,5201832961294383309,7808706921046892103,174614223019288221,8112250997332638140,17028498200331531788,17992023649322535175,14371862644053933955,3003095518114936066,6381351975458679591,4662538965205680648,909448385541789454,5352554182927440638,16446833254225866231,8137630940843652848,7440045382080675910,1701686344494582462,7943171707765998874,12608097356366017830,15828910605356090163,12786177593437700223,5445654003664635113,16509741932381571120,14266827524224094202,2842675721494523762,1575928738348271543,12379143141814216440,7159690990598238284,16764760864654421175,17131768193907176273,7103102209021054053,3056120680815907423,18422359112028935004,16925241363559827949,5302544321314943946,5721390750537136445,3654189733147788381,17046729054767141873,2602233629173236660,9350340919824031726,10467688313045897216,1169240167566872440,12301791718242383772,5573234907143628885,7453607812992866393,12027215107470753476,11266498104846558349,9889487490350876556,9226600077933156424,13342204494475761198,8558839147479125894,11746748012077468589,6895395542567596815,17015988067129680328,6654703206775252415,15731421358171430171,15956413492878193828,7175540257383266187,1434244667198046994,7810766522036749660,17217150705465439747,13223655417045231661,15633712370176539441,17215173102726260016,4273266114405764533,10594715470211927806,12042755021881361637,675470072827925684,17848221106376061632,3592753900798580756,6404825564317068781,15729132616570638883,3553682489357002315,12486592175955758124],"proof":[[16017607397370690775,14175947244806619522,14005561207094742644,1928878595931560211],[17582725622019134954,3643483993963535241,1443984003342346031,2740068734448616495],[18440768106739581679,6835153643208065324,714272044703377443,2160787019004240796],[12847350161063447383,7207319379533343064,16971521544824702143,857769483627622047],[13457286369201076232,3662701075681151655,15469465251232946560,1087885558326402531],[8576579745870688306,18310448201129806540,331893327784485381,2890959535983187372],[4420639567443725706,17331400981996566159,765171216756822264,1322595227004766582],[7008690799721286189,6967585151158296876,12320750789234069111,3007198139986536629],[1458485569532679212,11028129106890789675,67411073120475803,1118346388875666577],[2785391687736037583,3016876627518452476,6153654971719468017,3029771202908022694],[8358026341707652497,2310920691185968131,532353127131395107,685064386482140819],[16566386223316427804,6954767977266719502,11834655548387491920,1486095908902259386],[1091448493125264756,8211017863830065932,4882802339191110377,1460845491635131648],[16921739472239467079,1602506089576224542,15212861301689140954,276720577705015118],[12277269693075711411,10123107526185953950,16045179107562419740,3285456383402439865],[17276327826309205693,6622649245744392951,198838715129322118,2021128430558695296],[18145156410346209684,4010073336707978849,1924457385425049288,694784276879166813],[7555343381780200285,7222080530487105359,4149192478263414659,2087134207257506123]]},"stage_2_query":{"leaf_elements":[12918856712936590609,16365423892759626917,4341760101911514473,7677713422390476317,7046787020043449295,2832340137005642817,16020843560922602322,15161791821336084134,15055060455930533511,4782525634379543317,15587906521509392255,730801731898896702,752449134219832399,1590938740220148729],"proof":[[11635269460206047110,8075265233872400358,2129752157964655115,3174119860414724932],[1289920893555211296,11252036587394535756,9273862743197299940,1337206515799505457],[2589957189910489588,3615562885550084514,12916082893934489083,1531987871049546560],[2193636858927130713,17229074920028536690,10975770876249099383,3165945127117770503],[5012495645152450426,5380196522079963391,16445200330955722732,1602534631420852245],[14954621044798412337,5645281813493543247,17128106105274400681,1777572232591359014],[15418725933961311177,17688067307960063068,584590495443301211,756582903194422992],[17100169032811231476,7424751970302623947,6718633957579257000,672580559110955635],[5441128369612902483,3598280304005095126,1056844080995811098,1912585559332168612],[8579863666739324185,13956928846734283934,17978556693669460401,2955730931693231610],[6078927350002801508,4131691644363417540,15191495450662750288,1766189959770272695],[3406843087726899382,5510770028682272734,5929312954453889116,599187987752291529],[16396919452730935356,17040332360788416827,4511194970260973903,3011380701941504400],[4869501257214379893,10069470203079345558,8192737206992125747,1328942028099834751],[14004775076640737134,16405860784886565580,13611647961154559005,914657335449437982],[10948117499453596763,17193642117776934247,7412064918550009175,1054181397094229425],[6817592767926923523,13606885855071621058,5257040927009635798,133687452795438449],[10657617963869325543,6363794218619939837,2056964279663867420,912544397321124190]]},"quotient_query":{"leaf_elements":[3966486081663220045,13133148226724326590,13200208587130112557,4749806289427395302,7577393170971963434,1529742946087233736,1538414774231557817,17505492844630239388,3854967359813243404,5017923496595137394,11208403157887178024,6447360623987897748,5594553810661572631,9568989091266335341,13340371096019311397,7497754778564363375],"proof":[[5748113139276671493,119289633062705764,13939851849579902781,3352988333925806571],[1921095596856872669,11988600452804911524,12283940166682325792,3311871723128993175],[512786500792456966,657947505901766403,2112304956031613562,991225310764335457],[10330735888031549702,1053641884612939740,18432476665621668798,2665898028172724942],[5211958756578378388,12615032607452325990,7326780687426729882,1296033462526849734],[18360059315894046072,17871463684109973150,7754731403750491013,1904769116524671371],[6897209779911995864,9958957390637517669,2267605418652260893,1946181208778557129],[7534719304655069060,12247966208445128576,9076514791087190900,2060922052492120838],[4968868603014237066,16533801179184020084,5298331921983115655,1531795863156950403],[13083671272642270208,12405853032350974213,15428743458800249285,653066255959645321],[11446722228582079389,10910833486914656283,1762021186735939546,340457076467474605],[282613453035514519,10028766319315199000,9255914738313707701,124319804299551831],[13887323479144111264,7220787334413544067,11771778064742425924,3030509854040288412],[18079984792646154002,6987661351365831684,1365428838180545043,1237663910990127620],[8834946699931256770,17930296563709169638,13715214054395488975,1464781080912163542],[10830038955985670022,2913369465331198475,5469165964983774055,3047910495489321071],[12531036841669743981,5206617712042914217,5543290058962336438,2598235310524617221],[6697503828005158963,4335318550068953724,11264087962333758347,1342513686441881497]]},"setup_query":{"leaf_elements":[4222402182085277098,9885319183200264959,11319334741132100704,17513742231080859159,8434815011156262747,2960532042701452527,14844046688635134534,18328388826024547695,6496283740654646237,770628581028926595,5235414557641497652,7725047329686818079,17998241471962905047,3576735288030992901,11824408668232521630,7842647839481423929,8741470342935597889,14549580974367066469,2939237945940274652,13072824755558936193,1010656517706824273,162203500024046772,14580954045741754084,1399561859975914176,14973676241539675334,14375960715701262289,12286287084432080876,12672964797074510175,9455285085067030087,10264033077189848327,3897167384451112763,2004463336603294282,11847290877641743939,14578649362068506327,1147638215304660055,8169157169955148896,13605481146012348641,7185651301788819802,13348829065289724934,5755951087339860650,17512380484122156314,7489413181616608807,6184755086214415698,13935051053285924082,6576799660712635914,15505014563596817498,16305423707869949342,4285245184097132382,2804213818041597879,9147461794919496666,16463558904679112473,17550002403637016521,7377228527592886450,14585077982767473048,13395077321356376905,13096220503538983594,6748906967986240687,17177428548726497838,16608082326473232114,11995996245289489546,15617496698046941119,4330915831971945918,8158506378791428215,17592245371222665727],"proof":[[3850464562742972212,13432393700375361467,3307239653013884692,1387285547132239081],[9757223824775027081,1866037676651449641,16836718135788085232,691338820251568662],[13109313202978128434,9058766929187876131,15540555075089140600,452196370328651591],[7564823724204472490,12682359243206244184,2966710541857133735,1307958358314599824],[7284172313654728708,12210106038322508183,17479820058498364445,2785415892914486248],[17436434844799911321,9869400356694884989,14519123137552087382,95553588009542727],[5046926702157756591,17859681993527328089,2024606466105660792,2794420926480055614],[10423607633174905746,5985321222097780655,16942181234772649222,2214648425526619417],[16922287945826940939,15870027624188108269,105018211583698318,1501312843761252060],[306459765942410502,6825802986375078451,7987515136125242872,3175878072870145836],[13449175281684049954,15344416003795618387,8890714706534690325,2389517749973460172],[12433882291719692660,15875036090147282110,11710837499010351094,2662795163131530223],[10522809122010151398,9363360153444473319,7872039569683765967,3007007126811410971],[1996665985005863826,13212144296352549324,10276560107788634286,2418080602058287426],[9501211666595037674,12893818581416000695,13329984382214739488,2834756034324269377],[7209727885835139726,7554397849097272310,14452557455043775395,26505425351382499],[16971969976901157167,1534836047535051086,4478151140287452062,1285813978217339663],[10615174389090850807,3952411222890345652,12751567640464541672,1567202650818891729]]},"fri_queries":[{"leaf_elements":[8149486887507326430,5227321933602518336,10765998052085561637,230953808454252391,8576893428344191729,17551918863745562086,12606605424071478045,17165026700193919625,18326756406500697196,17725303203453412616,1601748743734625197,17760381022735056465,11347454028616499869,11961602869203157293,8327768453946985917,11541824683338900074],"proof":[[10782873474545573700,21226546891695701,13073338124551514992,1496266654983455046],[8022025418772577980,8699342201080746869,905665637501006584,3353572825548022491],[16154819125251954899,10610677134130122406,4302473302165717959,290090943903059804],[6078565221123827866,8460592064632028916,3078830713323712459,727007256796817508],[12931870062445137353,14189535617303519203,14454156658087574533,3084405111233729044],[17028000126779597526,5383981495755433717,8060372681572950017,856680957055793751],[651735615282486605,5625031862593745194,14750843722678193109,2431644750688781798],[14690938950486623893,1874702621836480532,9931892435186726217,2640569253423910059],[1839541853118530193,17374698443936338113,6145052757933712718,1302487857355329746],[3204445842338229586,6383907853212635212,12405628917857408986,306760663529086789],[2278889919116112665,12799254699939731195,15726112566672414769,1951498926712601808],[7028098590949746749,6886590560031024281,9914331681087662134,1898280501105857000],[8386092223718495825,11766070727337569053,16856415457191058715,2572897829967559553],[13913986881887727756,13045470872211730755,841762152990262081,2078743796367517383],[10775305224345001933,11572126848983301959,9687398839139571417,1948432115551708416]]},{"leaf_elements":[12414311033871631242,8301234608768946747,7523857045508012772,7546708113127540773,1204081274016044195,946454815425662096,8342228339218108191,6015867171082400981,14127844335133614344,6711336344135967392,2316917368850947240,9035829734707156088,18384078933971500557,6036273275806907969,7864637186211997164,5356938653494847471],"proof":[[13821072172874372527,12821303618767694283,9795302386720867975,2871809166831461579],[11885391882212789193,10761140819723120311,3525345294657090683,1776036952438236434],[1746575484587085008,1593525529061065458,5039993196988759304,186245749668889427],[4173988369543620888,13251229531122084955,5863310613609514003,920311931722549236],[14713208303540427443,2115505181766536938,3638049008126189530,747912219135103154],[342833107466437833,6115807943263297798,6031159926386593362,2408569488335466499],[5375718225847361880,3063120096227900996,15533093192814202009,2849588484841295345],[17863980620669607942,10262750106536118622,15316847521898948304,1622652272465938423],[7342537872220900365,14677520409585663993,7943561852907278625,3278185834007466316],[15710092701610245381,18348229294850784933,4543996205218240847,914561041517863116],[18406221117067344193,16566744332386408173,15261521134524134617,1032304335220294523],[7293919579905722180,3041810186025698226,883672649821965827,739721740827960340]]},{"leaf_elements":[12361361795486741311,6872117542752248952,7913470923225392366,6304361283130906767,2110304200817389579,1212289637369899742,4706190716343426715,11436069359671395574,16154888370588775424,3991652066073287065,4235945673560800093,15840260912535452720,17010830141814657661,3034092817111508069,15061739421270081785,9623770571845016031],"proof":[[3598631318230554037,13866099796731142287,14313882559409695916,461282864224355289],[16946184414618533048,14446542257903700161,1946175244796748758,2355392118006304418],[7270273740683883176,5891923776112570399,13873010705400615963,2269367103187922155],[15970966276402602718,13047079376346798540,3202522288129963492,1802371206653190424],[14187695113547707537,1142090908646645515,150383646288106607,1596829087608796154],[16506504518207516741,1179880218115853910,2961577289466768070,1095401658467595942],[16695697832737451674,5343092724580521378,11410717676155230564,1264158619855165917],[9348216199235002039,11720672214215654293,14015468307844482147,2857318515698138453],[6751756944236222367,17440817873358183086,9064364982137601371,2708451860092029174]]},{"leaf_elements":[18084253634605721729,8654397885491434817,223414140370542845,11615025157271394681,3831571654217253158,3520798472159737463,3087374698266769049,4047131116111598481,8140505412984669787,10435631352198655674,16165201384788881002,3919581910962945130,4715480076284191396,11851313412426671796,895645928838445196,17370814250535703517],"proof":[[10956245742383843249,16386911394469718142,2409056597893745341,2317836889211441437],[9014856085505113296,5529016349206758956,18305416867024204311,3186661511079561073],[13395998095724680734,17584496013146268579,14651107127066456122,2977502928252662628],[7159536990757253087,10904384865557494336,14942811686447092315,3130741030135414591],[8175294652039099566,13404018473413354936,4086902164242785503,985134816495386422],[14026492541169347435,14477905587688421303,14195254501512933225,2288041550899015223]]},{"leaf_elements":[13072000811531649326,8866839565006724085,3608360253602743866,15502500598302516528],"proof":[[3366209606167480204,16454720454829987891,12770516611175953337,1765343273335321460],[11459291772035387489,7397975415261021042,1613501827541558017,256696747045588063],[12587231392659778486,9789301860220757719,1664343977052005450,669834057422773060],[16718046695076638421,4828946584469141751,15305938188181302197,2386101549763988771],[13312340979554262989,10888740160641725472,550599547070284854,1972009457029137197]]}]},{"witness_query":{"leaf_elements":[5410267193526245712,13594945885759638917,3216548862879909725,3473465285184708164,2348571990684672528,5071423308398301732,16538436915538943735,9140469125087775630,6410235788694477439,10282334410622246394,7860251024423655811,6852522944162395869,15251788309785433989,15273690798951432618,13299790000526332248,2474349315455925409,7425194988538486694,3224682400530095716,16047214269891163776,12513586936990533762,12986127866647590377,18384750830380454861,11312351461853748152,14406784765512382314,1993406401512448498,15848736433294931723,16184588986863225587,17470110487717014735,14530615578498046328,4656477981746666344,15278746967394582554,965808842975780380,2917835615967207427,7068736481311494445,12529037179307380308,5522864231244087473,17500963538188010698,2036535803163538674,3535853334729337176,17413457764208850150,3772857743351350706,15289471228112143957,13428015432903049718,11986323504850695324,5476065093239540216,7974243204641869523,16194225681565516472,18021478982120819453,1605046105916860118,7039455851072389983,8847405131187800838,15774303811519324391,18059155743216292566,10810129277322790048,501151173651930809,3124438492716454845,15742486745624742167,16082719421656653910,7454261139065592601,12856545041648792021,6799041781937362800,954513144280550798,18298578570486405967,13785466392892250668,3537937599076162694,5986982637290478388,12156907016980716526,15432166516810594170,6324778685894410111,11118775077404338863,18282700657723143153,16221595761663008685,2047365498485828622,10441803598845792427,15467487392913229978,2110073097169041573,13373075540178361641,16993291961773215600,13572267179394985440,5478901911667283688,13565008468815217167,11852601593949066560,7737518772597518472,16137221620349235804,7553964493326560478,13045962031758412113,9802554348562260686,10839403762147295429,9891582532088030750,10844438057363581735,12270961235338685736,2992919707092421663,9695702673125789481,12840176139113527689,13753467326454452650,14226165447685104928,11865977943735066720,17944166779918286836,13878220980685901789,9590015045227788626,4514171763295914505,16191300052333781509,4953057000991239688,13375314905009265926,8987568807368074389,10801522491608371626,6453682192449705251,2179031757425598759,2218320897880344971,11838368152868610720,508498440901529642,4078281871362703535,7336908728264801081,16848058052332546787,17138597504790601197,1058945827662180866,15376774126999737952,9939435928447401355,13681380566058712837,14933416668922284655,14138470595753920205,2727251274103821853,18174445681933035826,6767254187064889136,3882631559434656430,6195010481173063573,9674439650992325769,14474681713913752580,11993736776718033740,4201932284799691089],"proof":[[17999993766390303902,5260176751522145958,3618357322118005871,2717730624374232931],[7532390779511142169,473357933026231899,11221660055745909286,873501503324375471],[2090205014260072828,5135180345330242244,16607197752244218217,2946204512269136891],[6821500660792765283,10317681318712839429,6951393353912966000,1119394101648218923],[14774601842414698864,2165648747118090189,6198738590578180386,3451830583112903055],[11777017293268227021,11271388156858153883,18305503458867823041,2310480467637285367],[1481203636682171414,2163553880892462469,12340897862494822184,1903973470927101491],[13911618225968217899,17813904697459025518,7596834788480750743,1271394230189865605],[3810496500157615192,1551041020526126609,2007189084809571284,975630210934797969],[1626586731124009833,2617891555574038854,855334275361259580,1159009119845384857],[9933685395579948801,9754794744979727341,13640177058945940190,3478271640468647776],[1658904221572945163,5547741934663679681,12176987502858276249,1016518536616009424],[5890087007084655389,11518726011728787559,5293537412542162876,2259629176201974603],[12926822421676535139,17714021194524965824,3926229568285959891,693035497991924671],[17787261546270747727,8260369348300109526,15369286840537156109,87419069013873396],[2258327222982263132,3399000348560281197,8147954427616003048,3338616278902806170],[15452153235492408652,11107381567660417528,6446362686939865634,2001752685707497572],[6093614570478946208,18121236698669216702,5237770875669588425,1468000590712101238]]},"stage_2_query":{"leaf_elements":[8428622033357718345,11247789393874987343,1812838810319550845,14165016863107742057,4934935364004467223,1444835244357811059,13088467517322843088,11301822623169130141,18199590691698795070,14494514633833913815,482377788978183058,3696201160820266624,4968233543965187432,15151584819084542614],"proof":[[11975501689848883832,12645840008075984899,7537795558570586007,1573935875645154630],[10554219101044741212,5402846812575718398,17135095318287907622,1159025794198958789],[7400411877957861555,15401502695799034012,9261179423539281051,1704568265551006758],[4317623135743702393,14242721739681326804,3137375459132314376,2618546509060287286],[2829321998875797064,1180904018166742344,13678225270087428281,710321165103351470],[7323357467711418964,11819265140574694696,15180540553046097593,91376353703952495],[16578980923259680806,3306473201952289045,1557924674644456775,241857265367519270],[3186093054867682120,5976456812516925240,5417866011291743624,1946272954815419516],[8687892171795003722,4308997933148793225,9704384543179143614,238355339464018825],[7980637203076134299,17206859406088748965,10682144975157990480,3189894646113504359],[11173060146598695367,6837998944994798529,525823053914720016,1544213159024658618],[3851562303330677228,10342773910192664444,13058676704294955962,2830264765467214097],[11205509763658451752,5083326431232249714,17978719259814526929,704851669260740138],[12472694197124153991,7167598996594964847,3409853019722797809,3102540991881319837],[15115880465180748554,8072526006295534257,12011321764567018181,2265993567560404356],[3390756080172707968,16137317664081293645,2381341761145055272,393174065724692724],[11262544031343913585,1247183418450672399,16651826430471021187,815432003715758309],[4680661078407068827,7063284898563483665,14919630655373191766,944225218621027487]]},"quotient_query":{"leaf_elements":[5849993795977002364,16843459498342731908,10613532700816065162,8087937920562276588,16752590275775591109,12542722454563488478,1341516834269642612,9514631025581869367,4478306389903327314,15141241386108575987,16003038467535500646,7165217899383002405,16587499898172384464,9297102330836332525,9676322732869442940,16626990351391673066],"proof":[[1113974113395351331,17971301502265990045,17585138953350928778,3470538035512675785],[6002775812616504110,17009197927012760732,9051841533673932414,691187291285411554],[872538945978382454,10868522354124930912,8946198141742125665,1663179529318292322],[1625279852205378723,17901465582794678904,1517879421373373448,1878184769499481949],[16260430836259938402,6117625266810695870,428271149208092649,1399863306177917960],[13180046175505164828,17384953148837904958,7450008118361683933,3352342033899575084],[16387584469226084364,11616405739533043121,9984511328688605629,3069514198320142288],[1556602963816557470,6563458531716534089,14329454214122111261,1689692559584092890],[14299476591834090589,16621806024354563080,15248199910026318979,2806603708075261730],[14434165399661846254,5143182720363005890,3037441346627530596,1907594091764861209],[5645632146526867750,1380025397636774770,3385759004090087851,1023111620041683246],[8379828151278939436,8433755181640961512,6130265549364068560,3106712877789118099],[15938172127488119382,17479625529537558544,17926224159385510434,495705058424913947],[5647857062307148417,9315208856532935630,6539749027868730756,3093810135451592472],[11155359173860648902,1835391928955026809,17690537989037072998,3088866717645343934],[14796513722749866898,6053603413708815983,8758461069342044581,3271167975462172908],[17753368777005928722,17280380530705180827,11785351911004981354,2259170545485546306],[17421224639589785233,5875696394063518255,15672456706514154963,248459372882512423]]},"setup_query":{"leaf_elements":[5218811379905387636,16283286070668683875,7364311119988023829,7877357045487996245,4178197603412823864,15078250656360449892,7810675893067337538,11012443487147504548,18415060990231224217,11182284490502794880,6980902021336067638,15577825971582631376,11749648515881988484,1159717329698825779,18105598200383082190,11881440897389919842,16651809663693402471,1355331736555135457,11411622692869698469,1127418836645292037,8283980231544162309,9989679324261658027,2504289580639743535,11738347674206086942,12929687190532224994,1150473251150356108,3016768097642128772,9437671612935904363,15294628662300361696,17759512913255592791,9315704997922770602,17020270005121292481,17418064175242335978,2505362445349779400,8566284632927741037,6491847057265654640,12371707952434471381,890395748582498338,11486303866165522355,558189562850838482,17945676757169131789,15145628286736966373,14266403592351044381,15595835195845302225,15297476872780909257,5096390061949543890,3203505682449927589,11698185046309406214,3066217214340125673,7944975453926665710,1320285631667107653,17231028014770579812,17337098939591779709,3102936775463526228,1116043507684001783,11720714017674135100,12581911244769203032,13371000396383330663,1218140911234371482,5016934260664059940,2837668648871891466,14699307659746649642,9425450982371718647,9448068393563928633],"proof":[[12821630853230403035,7966250132921646703,8045684145337156175,2509092707639899413],[13165157203670377584,13415933120046093107,9399298091061507528,1839715540244035490],[5391041869097724861,16547388367048926382,13009019893064736557,2993497558816472511],[12688254850233571398,10668584644780050151,498861205563665738,708343114399687875],[4295778907407860,262616395142312238,690765659487899593,635040933032892262],[2135851968539040754,3100978924798479472,9683070110491377413,175928744416137854],[4272779903009086997,16105730691668591174,15316520090044577972,1797570862546486804],[18275453454055134482,14054462218390077847,256374584057717415,960902977017103971],[9004879469470906581,14269154833213501501,1076627654417042612,1899569213290330919],[14224284793093366604,8616645311871923604,5102735489204418301,2074029379439731368],[13857688923247923821,15270312197344989409,17773005370338474339,1470833376663288417],[13265436270068205264,12882528110097987798,10468599918177726655,2655633409177488946],[11042384131952232514,8282744298336460548,6744601854124225697,134917241127285526],[16130897545771905775,18045592693864675756,4557085260143766941,697181750840182954],[17598411203511064320,2941896982156262264,9784211347543317900,289594829462914730],[5709200842404989350,5698689149818646759,11040344212952787902,903410401961731660],[716473001982184107,9603470024582712513,13111335008639139665,1903169351946485038],[16813186002723420737,7382880016425709098,7372398686650400372,2188188764110999617]]},"fri_queries":[{"leaf_elements":[6931753636551346132,9214671700331944370,8524718382708008494,11550979095051722712,12021156116116846304,16328340110550154720,7749920545285898458,16081308620628590570,9143893635028020262,8567781565105601271,3721166667430811249,16689583751537494580,2121162849561847382,9445685334811806907,17046971593482624516,16981013662372601316],"proof":[[5283554203132946604,17903373764559041526,10083927438824403849,3359108989750194733],[1657601793562955077,8938002818186085062,12855734136608103492,2157332396037574091],[12554126947119837049,12836724712819931934,2985898419588485180,2844098739082468390],[17379447127197591596,18286914663427157013,18329313150095814169,248109185772295327],[7742040750201424671,2308807690049220682,17942738861595053840,286091756181082643],[18340087094186699703,5222643869705270414,4240956733805087753,2524276157642681542],[12430549168921183924,6464910023596876146,17321238248370696098,1234737090026962001],[10771049600553208726,10182052342616895243,17010107878508905456,365456863364605032],[9532819502550155376,14951515576615712208,9550883863041469525,10482357148573184],[4181908704679758296,13997915739986091509,8629926241835340550,776000776133666262],[13777669882188159241,4536533617475200444,340128402910274028,1567512317260761221],[5217235706714323661,5714237762358106998,2874549935088914501,153662080229315242],[1448757911260743559,5390159166684242746,13939267925683310044,1732437009636778556],[14557881233013023878,7932846547650909598,3821175766359245010,2417481241515717959],[14670527213519236072,2433943556158074390,7730595993356917757,341805440570042456]]},{"leaf_elements":[15017935275926022519,15881561455225510120,17171044390082696760,9763968369344852199,890315555698056950,14575022054932796934,13761094119113148610,15206210676835800302,5721707128165112152,13458946248549925777,4659999017943163833,960856771796652183,5577273368644480654,5277297923539972713,4425779098459979341,6596185183299502245],"proof":[[17705326769040630173,14638291510674368126,2386961651378475883,1946650309578932877],[8602801463937584824,6067236523959424242,3118849164939107526,2688699828709745663],[17405670360838519479,3606084021584556263,9934276916550566287,13535608401133741],[17307461429749878906,15222292770514414331,18177967046203664507,3313978283851858118],[25736442492474806,13227421485174194263,9128139285074483392,509557738632575990],[7290734794953521231,4684983050178438269,7907716747429551880,1414498811860611858],[4627836049981683810,12854964975664665924,10540858361048166153,2010123349302308064],[5587188199636443006,17336890428595404008,1960191955755941236,2975362128527748230],[17119926551346509166,6678673926521166474,8081702804512185167,370085933192364357],[16340796183639961507,12982457411965034425,15114291173349013150,3047003817816592063],[17101524032669131746,2336819652277306540,13019357351420016304,1241714923476394091],[14857646424410374765,11326202776732471553,12691034493755458568,333083807316228280]]},{"leaf_elements":[9532953962369494467,555250322971352277,16576100654963032947,5957402606737314100,3609433548223062957,1558864868113341911,13888961842268230270,11012525934233140365,17118214205111974562,6230078466934907883,5882005494835981976,2937111612739039111,13435959430047936148,15488864184673059740,74043327833681014,14249010398249627160],"proof":[[10708970259436670677,1616452354516376263,5385654099780020658,2702478900693449079],[9111473222114856702,17973014606973407079,16892898535394936687,2667472485485279386],[15907388814917363573,1700159816361680624,11976642761074863763,2265577522238747825],[11118115361495730780,10340679977688574449,9608516308168504534,931527896461831888],[13584406574205537034,14885218207593580039,7081576714266736539,280925742213832309],[16903320974230998971,17409170791760236707,9867311251434580464,2824225381380466098],[8602523865619932301,12085020053404635430,10721267560898579495,613040236193801737],[2819456000592129099,4603020711434741188,12955081293991707655,730256938250425678],[12620876767755405978,3709346092908067134,323513677033980590,2622981867869345148]]},{"leaf_elements":[8779583074706614310,17675881794893960525,5902740827877819901,14632610141662760042,9521763058256460364,6965181036572502175,14633442247010780285,1633145515210986440,12333334758403298002,2895994788921857053,5569178616028297082,12346773451858641660,13893877924204168289,7130166058759841851,5286646048442355080,1572630263524489372],"proof":[[7746416141801789439,11830337548006760227,18118377122018565072,2880214364473230784],[15806810887796136867,15678694722677374781,4957295817048435424,3257349780367923386],[1597948018450221495,5575967079161314719,6761573610466284308,3337502639220620569],[6524871763516398077,1956002892908620623,4742589373386301300,242603267604269802],[3526166870301665083,2345739460011994772,13182473932678774556,2964193387372664731],[3379437042358322665,7687960308397961500,1574254794887636549,366652975620896967]]},{"leaf_elements":[17759282035790659556,4179558340747713855,10063085424943978712,9047775426961281682],"proof":[[15665430535914174426,701194694872829391,17793651544943900334,1370388154028233315],[12601638860456567106,11847145808546575562,10373883322563244814,621720130885742181],[2902391295503475405,2825788872310872832,5192825494381367886,782174593250373033],[9350976033936583301,1738269895382108163,10534984347236768717,2527040919344974012],[625783396740847302,937322205885791169,11162810913048955870,1892113840964451585]]}]},{"witness_query":{"leaf_elements":[1570732389496294102,4979900035167695524,14435462763301563813,15456090886032928347,18401066771979552126,16760998793458592478,9980911187262047533,5783366701347014065,5638380142659877177,9201269189095552508,10213609013372209056,11886613082287320783,14308984786892377873,8660500531626691273,526559790535062905,14753494362857618650,4999895166286557258,2829385747751240822,10336112185994336193,2881675694180501094,12909306445183776211,13912265492220784292,8569188982969067878,4161692951287876159,12298596928644043806,14696803912350437304,11139379061447667268,17236155828149592686,16475844588070569911,1856831803317091932,17457231462857031417,8997042648463358793,11418048511664719791,7547214090112128176,1904653295054582729,15523460587035137230,15162701659400578702,11574475274183313298,11361013980087756006,14048889339300325465,12674793656125437682,5795019690578973095,2695214404571136162,5931479305438036057,18250837127640712937,15835268762419508609,11554566630371069205,14394218185824733849,16218134783146921817,8726674198392214539,9870720940958619611,2051106900111160962,7026553920712303607,10431187110545779718,17910942855087670135,13408699296980411288,8515893960516616076,8071209093243304615,5350650561133113458,15028569834093387565,6501283937564790812,1327039875435743331,213755887419678344,9497366706963374737,5453788569507015235,2905783329532425739,9698977147604603751,11289321850387171824,13643377133066030662,2750497510161203562,15486228491049805273,3402255769834578032,9337612617529701105,11643189069296866535,13032681679195729411,9111782470759268725,10065766775259274452,6449554547416042737,13291188750926251081,18183320824586811821,4750292944812314490,5409163576034796872,4296637639037545508,12154591684952619878,8878233633214589062,12152945812521095606,3602517106508292284,6197927120239305410,8965477514008520301,6096151563356727673,2149625629169818373,17823818783013138590,5994358017482714110,2601717051811209926,3164489573855005487,11338409748903513626,6593759276751834275,2847032603785155173,10752465255184970809,5683072802653105501,15526081865854173024,8844801604093818061,14320965383079621122,11590680257476443642,9531938773105226843,17080075675691426335,4980929584818830361,14347308828284302030,3406124614419070530,5504479981177540083,16019601021939256331,2908481443243544361,13195064713637668911,2817372952407509886,17652234201526696711,5411840570553536891,10912626517194683013,12524333850887426322,11123865129203060846,15684961542675926933,4829671927106846206,7925153366400731205,14145381150933131068,8246403137245167289,12038252706268265508,9696733304246942948,6472165678706609226,5421064476074486231,12583218525011468537,13450839716179423703],"proof":[[15347191007852286036,7106420074630565003,4879805523874560338,1680764953350563883],[13193719505644961132,3854272880128176802,6680354915413153473,941864587650010517],[14792699690702183258,13217875359975621612,11276624752056579424,885715490258389144],[16393396785697434902,9021623765134425138,11885744486675764356,1998154737881658278],[15640810707829611386,2012172499560312543,6633231193575686903,752084955511073178],[7307722240309109664,725776419469413777,831463342286850106,2021116106083790120],[13849097290196641604,6175761588715398083,4469817396888374119,258569293844548851],[13227602470893131167,9391353411296484420,14172997068998417477,2748610527613442931],[9981118573492128054,2638604177476019503,16092210269103739079,1640054492405864538],[1811099741394837305,8868333052912894942,4995322761196985655,617861982939764951],[8779682374782347872,14956695115886111365,17135371480583882707,1547546315334118150],[4700349733701699309,13633371085382006531,2962726823054233425,1806680044981189896],[9021672705539750366,16919860405426402856,7706041721495199407,2179540670306471520],[7690597583236610033,11610763765602658956,3066513634965940831,1173172371746303009],[11201924350079228408,1097536569618870247,7077759591031483054,1275798062105887854],[11714639523712311903,1574442002887369892,60168144917125579,293013356837747621],[9942420627945889044,8550764353647682635,17007440350277091138,1971101352170115038],[17885627015336238567,2512472131386994783,5535244870829101097,2608022734657406515]]},"stage_2_query":{"leaf_elements":[954702953027606841,2513246808297813144,17260198006674166101,3416927866270062637,16952766611690971663,13564014469672297584,17525144718368152876,6283677146451090744,10144208676955355028,5014879251793017061,10764480850717454709,4521730731226904015,4106399840762706823,5558631972534650470],"proof":[[10157438206549183591,8924571207145580923,14472865311604465045,708024509539733387],[5891650332592542423,16445956683206424271,4561929124538764176,2358096225635111867],[10639488774572714761,17660669409647505325,16807552184105382852,3252910051589708841],[1780540402171857815,2284277782393981550,18242639959388222070,2778639781061691595],[7116493317796272923,11884154906116487302,986793830578004408,1391970953461885824],[17571533666333620584,12327762307799062812,12848885378252656948,1242450757624719411],[16374409268958297982,15482533346441924453,10593684664183869699,1340924098114089957],[5766882491754598103,7509573445762216410,1309328540856389913,220023393924425762],[16800822332497207964,5824157548823781986,14728387087617192374,2627841279920105943],[17577385195800816805,16295502678426969368,811057613774416351,1414460310284873356],[13683444586247461177,14422326762148338572,16812752037853777160,288648374035018137],[2316697102916775889,16993096808441128003,7970376423036841388,332961764471324205],[12983598424435040955,5031168166910562972,13747521738308443808,2232212580467844920],[10999625260080134360,603444621222476038,8236547149802299131,1693952550997331194],[6533715014534535938,2286859199953712944,2458084162190309771,1849072793948775205],[14755804151183863947,7511420043634888188,10601191418775468070,1654978611885840752],[16764092186543569935,7443902080621598633,14043901883533411737,34718451080191937],[5610227141405240554,10423533713752218724,18391548912049176337,108546057523119049]]},"quotient_query":{"leaf_elements":[2653346787049850351,16659831566947575054,930380478897221787,9206590451147945419,8773637584577608099,14275545895718411605,2491740083788839420,8544153346915554781,391491282816022486,12991898157050979565,14550589281113176999,2605005957745212704,15526051420100216967,2802870876604700490,7645701066566869431,12082391402570733060],"proof":[[13397302073615824918,4783570171789942079,6999684033587503944,3151211512041997534],[11490956802077231531,16983241552623952584,12090765897803071445,3093702114306961696],[15866855987930965924,13958932392923978087,5340520966778777681,423781134748836891],[5323387482962601054,3777542215290163806,8477679211188080060,162554672588131731],[13888670965628986227,587117960217166644,13853756026141221660,267436488271507109],[6403393375782006417,6693662517489683477,14146507902595261609,901323681639675561],[2142021072798796022,8657421044698891578,10600471251210665718,1110794360008265086],[14290688995096714347,9346951158786962880,530407915747481187,3476439757846057902],[8197918941066054627,12702272238858102622,13035209661873852576,2422798607290512874],[5005403466193065850,896938109072120828,12022310273519310917,1382349040501130443],[7956376755894257094,12637525787399251188,2314041426306151681,678061397843937022],[11313294136906284500,12275069351498892928,16416392904767191896,2154915637960907283],[16589001947110265975,17574938179034714174,18035180562409429455,2146954170889664660],[11500107167689625364,8164541099941188445,10406367904247701809,891830877267916662],[6355595910187515046,6931047150754531361,12644193854054753991,1946379085419443478],[2323115937795228854,5345505742716203732,1804816219143609624,3171074634241079826],[12653182313652106121,16338091785858681069,11047656551097786178,1676272897413300037],[5740235183620706597,15764442809149654899,13466321763323994757,2341492709970342168]]},"setup_query":{"leaf_elements":[2124899252818257584,18303627037207604917,16385178953600650483,1624389784176062743,873689800495869734,9609638228735081152,2069555796142539866,6523211679841364587,5845097940835636046,13728874775773637936,276529265672797280,14508270017961806271,6316789783181844194,8527841530057225749,17549496694191492354,4814965753683751772,14803461882486149272,17553037668970655029,5141844607772363647,1731943588066004422,15819236757570406327,13139754513359015320,2236633924157756329,6118392300374946754,18350283114569908664,7631151378859701928,13346656300424080954,18388655122499910543,13631263296011239179,1748878631121120965,13492490041165190204,12236329057067684673,15597259627345496935,3956976962667481720,1281068721760726063,5674192671759334054,17807852125185604086,2968760385403792589,3864424766568551422,8938707512887991253,3907213519058842068,13224883652574462554,10686694181824371576,2818993597731216685,384829236541258198,1933001966562626094,8095903082449654620,2171795186405586004,12821077572598631331,11810841082763841631,6882825399567807201,6145741595164606041,17418541464199931274,1856749472492370035,4391414250885455741,11538890302970685424,3128802784101194670,7182338568498031610,17685317934827048811,13429846776089094182,1535610029497511223,17051532551617974751,10830786225580185731,15786718033198113656],"proof":[[18422885859635626653,3620523821428656994,16995202388808846998,585665260935856192],[10611938987786073696,10461313080336283107,15199588903057586741,350416580301822273],[7522932325619261929,10808584672402233864,18257866847590122889,3346999839449922884],[7349323784859821781,542304080968739096,18415293303638652914,717854674682952840],[2331162080108893997,8898973108268265797,1807915044907560769,525669417067353491],[12403377318867559062,16448998080357788072,7216890144467953227,150155199410362458],[2762801134739537678,4506477521280119661,16254131095912222792,277728882447063813],[3964825031506735468,17692359869597932109,12802041013620211292,209217804010916761],[3840251949945990444,9781695455782822504,8422793742741730160,2416359212919125955],[4917743072298943066,10164372079288558273,1537319449410142027,398606100707755319],[5624503507657429325,11331432784413490675,14323959563044686559,1380880868734066414],[17914514149810411192,16231530537465668876,7156813348143062250,95716221250122205],[14554456231392194976,1575072046894285742,9366048094220852638,2496881755704816487],[14570782592689404600,1568391697928093646,8264492775934993209,1297638731370952105],[4415797696064034702,10175628936706700415,639472968078770627,126507066712405241],[3499489590098033675,2072863774632566785,1176331588521643867,589596942374299434],[6166717553852431051,17880363082735159730,7180658827206451510,2081141360498862186],[1223256068282353153,2022424107244141259,9758377146235760321,887975082211068185]]},"fri_queries":[{"leaf_elements":[14685829762024748412,8383167567730891196,11050791145651069436,17787675698341366942,6990454220864244161,13252547181281029341,13001238434641744107,17675885430410428260,14682854561990865800,15076260878124105394,9773684236450801769,2028330413233474942,3324375075803998955,13702984926274360733,9033695857575007139,3088722179240691845],"proof":[[5427837950251406870,9077575466919944494,7777319030616227179,452269833059738572],[7726999078612729454,17892646593436674370,14410736060655421533,606086898686793981],[2009287163633666146,5575191776904799627,11053264260453118274,2486389338626770477],[9795888325497013313,4150023533845815943,16368310715536389101,2235174366272126405],[8634895025717485225,12157457479439543452,5577919309761927544,1877312820753900056],[3738214336821206678,13283063257759322033,1155142400322963776,932942431609039361],[6905201752007248715,15808637573093019229,7886866722747544022,2876666774261284487],[2055934701481413489,1005328571561063774,9758299596630267766,2497809578746777172],[13520468564857576630,9571197776814459875,16439385825958840294,873446948247748524],[1744780616254758383,4222310847420307085,8833046764658851214,2992045645111691590],[7303475258600813846,6697090731691451490,13981335452255562598,975816443806013],[18048712417283769979,13252261094500174418,18094452574565201247,468441255668166255],[1569936160144755148,4422511479750343786,15285559213159201494,3005400366064396504],[5998251354500684442,5311253576630791492,5299333027927324545,207582787414007467],[14768061687967409960,2585282958711345964,10711664444678803449,2975844561410365943]]},{"leaf_elements":[5500635976008830256,7563810605456189284,10696186458953829541,18310403932752135228,14293223361979889187,15208123548691512731,5889433874596422980,7999730653182957132,14459792626436761158,6302400136620069250,12604078746720275400,9931363464945730731,5796929282428082493,287776147722474408,3222239624338814889,10764477742280307999],"proof":[[9285549764840500249,6907412010256195692,9235328925598004290,2014779221496219420],[5903956294424886828,15142176695981091598,3954289906801760890,2920468915026814898],[17789562849267814805,7085186765821607445,2994662482380004655,2866073791977952479],[16839168214895684953,7094384231624883975,4729674121024034429,712163924974575377],[11792009741778546406,16040591862829856710,5359842131698933055,2183320033560359007],[1654178659481803956,2175915482867602905,9612326356799802254,381573096249635963],[7353733080464093144,13733564388945352952,7566709183631636172,2492239816775862743],[12649148135277567,6609318286495012953,17857990991428458272,2071535796474232716],[17828775651254186243,8654252132391401394,12557872590116286447,2845748641830130328],[11035227247797731382,11278198446946380495,8248799679298027179,747924884454501356],[1498147249435873824,4827649167585458314,190235596877464681,1516366004241589550],[9322997592103904003,17670620383809772815,5312434220215701886,1505383475406206694]]},{"leaf_elements":[13065822615528008031,241972586284083183,17321273891003902372,15925712721265627602,17070426843872866275,8512579651275360864,12571168717462552130,9518087921140897491,14566268391560258663,5641836219048489361,10231828229753279979,17034239403720944093,15009960160010203485,2448061487428981756,12849552017897896857,1045051530506040572],"proof":[[6358856718529130759,12229328439772800080,17320769379202602064,2762551156564020100],[15047231527741067025,4015807258844726807,1507068657527716164,2322273377321191261],[14120236159007873256,4257007754439241999,2891448587158496959,1139432811822077411],[2800595872723549517,17528004246997773535,5123990487960372864,2022905321068771607],[7609315789931428842,14822827666814077637,13332033104380144940,524310113144971640],[1621622366884329407,9772752826681558487,14583002506200006303,1707602675397599477],[4671427983352607950,3584824270162420304,11505198706178416068,293007279388821699],[9269712428078286834,11396652529731701665,9309235595593654844,1346923262052410523],[13659481334673242790,9036309192701656900,11049642103975709055,2431291629518934451]]},{"leaf_elements":[7510542065935843554,1446968986292179204,11264720370632743368,15765941728131422522,11510578157664439128,16598594553434462140,64399223110505492,12000752793473527723,5604835224907860161,7769136206452950903,4727377418559202373,3480535628736108174,7794500283466494600,15715889629229327530,16547448350941593707,11986478420971374180],"proof":[[6856763594021003974,3229619874926282048,304870486296071706,989745832317216123],[18439384910820831211,10483998115246483253,4738042279184391937,3441574309772298249],[15235920998406286287,4563891927527255066,10785024455724488134,649632637298105652],[8612521286229996671,12748247789276753818,5462965523799033762,2628242346718445972],[2619817990904366696,4939518059746535870,13381939917831570245,1085783005720305645],[17245888943714473827,14221654547285706402,9127587227942606797,2583097537932832398]]},{"leaf_elements":[6345318474102515159,15593521902435858252,4476337869928704917,14634522981976555477],"proof":[[6746708774784818103,16890378742842527275,11318277754574859979,2045256667247581565],[10868621363361047182,15060690260281196371,4618337523865834983,3068335424178531105],[12819310054222195535,8565142856658128447,18344924902259701964,2301154371367899262],[1811405109269232041,8802548593739232090,6698357440020237418,122612848765833737],[9303120185549006534,5961908874881171171,8436025736608217306,2038348638567412814]]}]}],"pow_challenge":0,"_marker":null}} \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_for_wrapper_vk_2.json b/crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_for_wrapper_vk_2.json new file mode 100644 index 0000000..052ab06 --- /dev/null +++ b/crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_for_wrapper_vk_2.json @@ -0,0 +1,275 @@ +{ + "CompressionMode2Circuit": { + "fixed_parameters": { + "parameters": { + "num_columns_under_copy_permutation": 56, + "num_witness_columns": 74, + "num_constant_columns": 4, + "max_allowed_constraint_degree": 8 + }, + "lookup_parameters": "NoLookup", + "domain_size": 8192, + "total_tables_len": 0, + "public_inputs_locations": [ + [ + 0, + 6733 + ], + [ + 1, + 6733 + ], + [ + 2, + 6733 + ], + [ + 3, + 6733 + ] + ], + "extra_constant_polys_for_selectors": 4, + "table_ids_column_idxes": [], + "quotient_degree": 8, + "selectors_placement": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 2, + "num_constants": 0, + "degree": 7, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "Fork": { + "left": { + "Fork": { + "left": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 5, + "num_constants": 4, + "degree": 3, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "Fork": { + "left": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 1, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 6, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + } + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 3, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 7, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + } + } + } + } + } + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 10, + "num_constants": 4, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 8, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 9, + "num_constants": 0, + "degree": 0, + "needs_selector": true, + "is_lookup": false + } + } + } + } + } + } + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 4, + "num_constants": 2, + "degree": 3, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 0, + "num_constants": 4, + "degree": 1, + "needs_selector": true, + "is_lookup": false + } + } + } + } + } + } + } + }, + "fri_lde_factor": 512, + "cap_size": 16 + }, + "setup_merkle_tree_cap": [ + [ + 12175478387078638833, + 7308586870388786996, + 2771357516189562600, + 426105426559705681 + ], + [ + 646454430908379480, + 16136930146484975547, + 2820216991103395100, + 1851907610131498421 + ], + [ + 15915317273721894284, + 4266436685482321567, + 10872023196446288527, + 2795741699518103877 + ], + [ + 16280731022591313948, + 16466498794949893659, + 1024804231968971078, + 124121496041777831 + ], + [ + 336160601229262991, + 7767022879789084652, + 2429465810037076433, + 842374653055138514 + ], + [ + 6938313425266995322, + 17892101090755049084, + 7721953429544737621, + 1521544672748712365 + ], + [ + 17087898757423921596, + 3466147975306127947, + 14809222578242380613, + 2688175195316654954 + ], + [ + 12870168139726708168, + 13703145443293945506, + 2105360195427729565, + 2016200793116368536 + ], + [ + 17458434289472512142, + 11620128720986408272, + 417506129367646550, + 2969817863755989004 + ], + [ + 17636810599142414881, + 227980588344096719, + 16017570565322366624, + 3385093816004115444 + ], + [ + 8001528968322620546, + 7960569183770806336, + 12534687593246880307, + 2258924191687294668 + ], + [ + 16552505063694497246, + 3994065988507155063, + 17416937630830374680, + 3299150511130934863 + ], + [ + 16990426683033724509, + 12440603123858713267, + 12728445236442824300, + 3217604671400787546 + ], + [ + 17811224236789113606, + 5770854258777502946, + 16830903759507586918, + 2647302237685371189 + ], + [ + 2138587037618817238, + 18125199892941375671, + 1936850360942423800, + 952628393937474217 + ], + [ + 18271801641463509612, + 8155446048478322096, + 5847415895986948732, + 414677985798648336 + ] + ] + } +} \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_proof_1.json b/crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_proof_1.json new file mode 100644 index 0000000..0f66096 --- /dev/null +++ b/crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_proof_1.json @@ -0,0 +1 @@ +{"CompressionMode1Circuit":{"proof_config":{"fri_lde_factor":32,"merkle_tree_cap_size":16,"fri_folding_schedule":null,"security_level":80,"pow_bits":0},"public_inputs":[1961802424684827,44478075017541700,68433799240021256,10969447465159162],"witness_oracle_cap":[[8748444263706850093,6772282615508453856,5877688812331106083,16849613428907260733],[11355094708818819365,4177802108798988599,3740223817572677378,9851627785056721572],[14207256199308952422,8022236360328791803,15018072240713976292,14233694614457198791],[17290641172969891772,16450439528257808231,17640578664130000920,3133818527897931552],[14986656802592825567,11086724563810950540,15004360092987327930,16064733584853773049],[7182779751046788673,17474934292027617888,5342187302923509670,14385191340459848448],[17042076790322358447,2813446972648802436,10951492846821387665,203177712817394946],[18386673402112989917,12952948879361156034,12973260318824427665,4982620120226768342],[16241051352089787146,17822403837169620596,15497894652644561098,12337490424598319421],[8734360823733396346,7505610898221271257,5126054716127983910,17484207678449245315],[10452221929738690180,12229129600446715084,3525424883229279723,14740236317147343830],[9333032682929675502,14941861695729547292,10133414917777302538,9214318542958755349],[10341576936425259106,10079755747170201801,17957615883273718052,15371324535825699508],[524755341251462051,12294225036877788130,9737378048377493634,14926161971525195362],[9162300512087380626,11450926540675904957,3847649258203203374,5175139022884510982],[15424544346358302848,8792962811052100672,15483705219420732411,9264017748236942652]],"stage_2_oracle_cap":[[3602359705323945651,6741190625982322216,13855267753321271838,246070968140943913],[14357009546734052429,3110088449977386864,12380090971260135450,2682952698369198125],[17674242065974296691,6344192589428514016,10399003121304836214,13704106788197169936],[14144019605320547096,4696906892716933711,139395351005761830,10194385877414112479],[17255000196270358860,11247906440719513422,11081547245768083376,1998414900437486922],[6323379707832790281,315470319673509776,10821666115071898164,16690501723720069979],[5330405262037294537,5542633046475975156,7866380865157921897,4321508812123505895],[17792602374780957685,18055794815465426541,10938106212879740247,2901673293330937627],[16989016694265726042,8305143065436348509,15017230485240096529,17590547100633769631],[16379376925565281046,10587922620351939897,2130263432138367521,4436180986828218958],[17272374832105032219,8493570569889084055,1274127125838332862,14135924548928116722],[4378474476165324009,14612487083037030168,7722215553342050322,4489114157998287107],[10965569913327928722,15930116573399908376,10983962257222069708,5081428172485688372],[13013361759868957749,1644654441064372502,7100184611903635753,17470049239571644922],[199925399481955412,11796348391629164118,13621478375043232556,3194202822003999213],[3989629651225552600,1118887593300182898,9425889101842093106,12555393011537499935]],"quotient_oracle_cap":[[17365626348903356310,1532139238165119497,18047517518453428712,7887866235522045221],[7341378003847773674,16516128550773888722,1808965959560651021,9325684624445417593],[17159849433079937014,13508562211496784695,15186978312090290545,10839985898603868072],[4323383789292929387,6602864436228215947,1924157905291328084,9537223197853287011],[6192546132260088193,13703287484761321099,7951671601714100837,9110959205799485600],[8364225766628464219,12826084394655713919,11366752663267814987,10785148998247056307],[8125976373666125075,1723686735004986577,10133069958985950962,17384141027909752832],[8099088529743307539,6794950972178464122,7256047857179376071,16457211885917279331],[14302083281991007519,12305088301994018508,5302534490224408281,9975125034482947626],[7667733179680240284,2432139685187053455,10322450013344592492,17019988454331888903],[2055408289087684091,7436674423971928445,1961893060399117987,2521559303844663980],[17656565198086239001,1765235995682016704,9595683724451879610,1022248752709804586],[9948089667919047601,2737081569925354411,6442197739304774928,17635150191842862593],[16497409620799429196,12928652920635075195,15177990952766625838,754495995252774034],[4211670951326452460,3017672271700547193,8039468954874975116,17620923305962042214],[1177978624592927323,14426639079278831157,3706645192964309795,2890044152588799859]],"final_fri_monomials":[[13751739232523224374],[13728078306509052741]],"values_at_z":[{"coeffs":[9201489131773771813,12694309159197377414],"_marker":null},{"coeffs":[16930211613092877246,7505264714443629576],"_marker":null},{"coeffs":[14795861757369079221,15537639090092107569],"_marker":null},{"coeffs":[6607906376879082062,8297027857706822275],"_marker":null},{"coeffs":[654005552839202522,332709276111278694],"_marker":null},{"coeffs":[2653172674850154710,10786577115909126205],"_marker":null},{"coeffs":[92711720234706720,12686757044640591005],"_marker":null},{"coeffs":[2770486440314556543,5000021795688168679],"_marker":null},{"coeffs":[12224699460325382080,1744732993711379523],"_marker":null},{"coeffs":[13684620115987719372,2568632909963503125],"_marker":null},{"coeffs":[954162485734687015,12140414992168457502],"_marker":null},{"coeffs":[16344078119648843926,14024249713752340817],"_marker":null},{"coeffs":[4796357330266742491,17630899382202212611],"_marker":null},{"coeffs":[1958569950482541465,7493409992109530711],"_marker":null},{"coeffs":[5227927162095969761,438943437479670571],"_marker":null},{"coeffs":[6881744873874732604,10033422413919816217],"_marker":null},{"coeffs":[8539591936115806369,18146559068284724833],"_marker":null},{"coeffs":[3571530846127700329,13585694780785891645],"_marker":null},{"coeffs":[6709206398556661370,9931034872721245932],"_marker":null},{"coeffs":[6542928688643168303,817677223374060548],"_marker":null},{"coeffs":[13577611696102681492,17362539777034924267],"_marker":null},{"coeffs":[12743909000513085301,7000506037832027127],"_marker":null},{"coeffs":[10398508713020005290,10119327873903564650],"_marker":null},{"coeffs":[15378472418260660784,18320485786859911639],"_marker":null},{"coeffs":[4442237925020781797,11913639164982267521],"_marker":null},{"coeffs":[12016512964983833661,7835356057144208175],"_marker":null},{"coeffs":[12310341372242584362,11094386562897366655],"_marker":null},{"coeffs":[6504980451386737292,3685281344759065367],"_marker":null},{"coeffs":[15225323192983761564,13889060171015035925],"_marker":null},{"coeffs":[850209687712464586,220986492683367666],"_marker":null},{"coeffs":[15769908365697706201,1442397358883634781],"_marker":null},{"coeffs":[13742459772378343858,167379478002780746],"_marker":null},{"coeffs":[2534845263356610786,16573272250502644710],"_marker":null},{"coeffs":[4019569359838582754,15960465341362726861],"_marker":null},{"coeffs":[12242189869997410442,15300088829850158347],"_marker":null},{"coeffs":[9067721609653748160,17179395868402741574],"_marker":null},{"coeffs":[11592411006912503600,16927887774713879500],"_marker":null},{"coeffs":[4283972239058628663,13781807083242339875],"_marker":null},{"coeffs":[13399682724876335711,4132369053166793272],"_marker":null},{"coeffs":[10469729227583331216,17180241103668711470],"_marker":null},{"coeffs":[9261664242654641458,5129240504708527494],"_marker":null},{"coeffs":[17760519598344659085,17772592765245952545],"_marker":null},{"coeffs":[6827724896321847382,16717124007059298200],"_marker":null},{"coeffs":[12636860453950199066,14888045503527099041],"_marker":null},{"coeffs":[8349428464660549430,1801789047788046119],"_marker":null},{"coeffs":[11876938598915507463,9619595792262747523],"_marker":null},{"coeffs":[11448399124353902252,15294595012046854840],"_marker":null},{"coeffs":[6005137149243962749,11237388588972828481],"_marker":null},{"coeffs":[5428321845137551138,11582700428829876675],"_marker":null},{"coeffs":[2656032233515266275,14951329459673986856],"_marker":null},{"coeffs":[9048488895273346445,7599626249441663644],"_marker":null},{"coeffs":[15060173690306372513,1372001344117452720],"_marker":null},{"coeffs":[12847234838433235361,7505649082153425412],"_marker":null},{"coeffs":[16825785723450767068,13096914467362719338],"_marker":null},{"coeffs":[2234716863618787308,12198412293841129057],"_marker":null},{"coeffs":[4938801230235681254,3703500363359659708],"_marker":null},{"coeffs":[16746608426638012482,16295663905775715812],"_marker":null},{"coeffs":[4957956192323646009,10034626168195944327],"_marker":null},{"coeffs":[6893013109147552668,14565641016866210581],"_marker":null},{"coeffs":[7366998445733232543,17885906506920274344],"_marker":null},{"coeffs":[11017281110568494904,3649467160150157573],"_marker":null},{"coeffs":[3880796632132582101,14540119070661868185],"_marker":null},{"coeffs":[11567584505368789489,9658423618530956729],"_marker":null},{"coeffs":[1459156096714139330,269063461064393906],"_marker":null},{"coeffs":[5925774825069440822,3989541236451677779],"_marker":null},{"coeffs":[1335992478661768124,3555321800162494998],"_marker":null},{"coeffs":[14533129251716091109,149151193079332569],"_marker":null},{"coeffs":[9755337914505281505,17944314535000160515],"_marker":null},{"coeffs":[4488656929654363030,15739833370736136928],"_marker":null},{"coeffs":[11123561309502806674,6899948523399511166],"_marker":null},{"coeffs":[17702152818975340236,1447790012543291956],"_marker":null},{"coeffs":[13798862591965067652,7743354779080204584],"_marker":null},{"coeffs":[12685523418074689403,15125347222738008623],"_marker":null},{"coeffs":[14294663113785629350,8630772533859046848],"_marker":null},{"coeffs":[1545077190364862249,10974813633807499272],"_marker":null},{"coeffs":[2225081972086017152,8719905988392843261],"_marker":null},{"coeffs":[11158948842477847997,9731958601366117899],"_marker":null},{"coeffs":[17933112660887187783,17533844299889441889],"_marker":null},{"coeffs":[7599438041468500301,4665473741326485489],"_marker":null},{"coeffs":[2177180006872081333,16220913295950710267],"_marker":null},{"coeffs":[4079265133507922711,56996481805133254],"_marker":null},{"coeffs":[4522832505841555533,6836018242222143595],"_marker":null},{"coeffs":[18080454686433711956,13203099556421105780],"_marker":null},{"coeffs":[1290703352711426960,14016147904649337995],"_marker":null},{"coeffs":[6447841182095089742,18020516735376411260],"_marker":null},{"coeffs":[796664417712034001,11079743722994855785],"_marker":null},{"coeffs":[16312459164549675032,10758767768094032376],"_marker":null},{"coeffs":[10790809128827881760,3160484450073400238],"_marker":null},{"coeffs":[4739543727175493061,4167963972281454525],"_marker":null},{"coeffs":[17678093779875286895,6908237399947607062],"_marker":null},{"coeffs":[15843708835284449101,2106421702812199046],"_marker":null},{"coeffs":[14701923812046951655,13877333302322384845],"_marker":null},{"coeffs":[16435497171996756146,4450908307067007209],"_marker":null},{"coeffs":[396265886624642764,5802767682778901523],"_marker":null},{"coeffs":[1324993745956248745,3121146821272673705],"_marker":null},{"coeffs":[14598268953396138992,429452606746226879],"_marker":null},{"coeffs":[9273408915558459980,6226696635153093846],"_marker":null},{"coeffs":[7477577354770486908,4254254966804803361],"_marker":null},{"coeffs":[6488545612967059726,5797503836610863091],"_marker":null},{"coeffs":[8657019205903052135,10222123373700583095],"_marker":null},{"coeffs":[7655442528728621075,599632067106030009],"_marker":null},{"coeffs":[8356994929034684673,4311651570130821336],"_marker":null},{"coeffs":[1784471481219837268,519785556557843714],"_marker":null},{"coeffs":[14026275677930027035,7139945483377409957],"_marker":null},{"coeffs":[13230892121211150802,2771915219451624567],"_marker":null},{"coeffs":[13486601517640865213,7971935152021221593],"_marker":null},{"coeffs":[7808285707938838930,13752163053722695368],"_marker":null},{"coeffs":[14783536494927464071,1672791362231704638],"_marker":null},{"coeffs":[8288482511761024340,2930224366446981682],"_marker":null},{"coeffs":[15402686822722592829,10547165515789771772],"_marker":null},{"coeffs":[8650461761399357807,4322413438983802204],"_marker":null},{"coeffs":[13985636219877314467,13452873179330264831],"_marker":null},{"coeffs":[17127304369605886002,13642618079290613310],"_marker":null},{"coeffs":[17578631316473528895,16757154872827138294],"_marker":null},{"coeffs":[16286351065149748309,4661749590104561080],"_marker":null},{"coeffs":[12741927218616848094,11775833230986348276],"_marker":null},{"coeffs":[7547704210069192103,15648401686492757152],"_marker":null},{"coeffs":[9037330354006199509,10330437239322976137],"_marker":null},{"coeffs":[4061038276670972446,13883309620460442380],"_marker":null},{"coeffs":[17934837445515364998,13771259230009602311],"_marker":null},{"coeffs":[6202316910568871250,4100673709912137967],"_marker":null},{"coeffs":[12114602418121604611,17701930037079211451],"_marker":null},{"coeffs":[16693300563371307213,10563947504251938526],"_marker":null},{"coeffs":[14662355124893650288,7153239680240225429],"_marker":null},{"coeffs":[9770341160270078029,8314089951243024446],"_marker":null},{"coeffs":[7035059282945287742,5761811745139972168],"_marker":null},{"coeffs":[17268093320497052020,18037608622067213420],"_marker":null},{"coeffs":[10463527810952222539,16979130846415673769],"_marker":null},{"coeffs":[4377125292333629036,16051944929971350145],"_marker":null},{"coeffs":[3571126363884746831,1875310223137166083],"_marker":null},{"coeffs":[13536011052132659094,11738607951340558319],"_marker":null},{"coeffs":[9276824239192753607,8967071762336690712],"_marker":null},{"coeffs":[8188684384046445601,8447752293112347953],"_marker":null},{"coeffs":[3164469890563421894,3568244827292573229],"_marker":null},{"coeffs":[16057680568524448111,16448764931219494274],"_marker":null},{"coeffs":[14692183612512989497,8828655331871930254],"_marker":null},{"coeffs":[4663133344079901186,1127773908303464674],"_marker":null},{"coeffs":[10412338205085109814,5224485093089113348],"_marker":null},{"coeffs":[8746687037063462686,2177274065365697439],"_marker":null},{"coeffs":[2085779732963861624,545169057880513680],"_marker":null},{"coeffs":[884828671336950825,3847606070201026584],"_marker":null},{"coeffs":[16053770867041996269,11168423209695105001],"_marker":null},{"coeffs":[6980193682815761666,8457324834896641580],"_marker":null},{"coeffs":[8467543136251103968,9925384363242973083],"_marker":null},{"coeffs":[2510001493321692603,13493064491021938839],"_marker":null},{"coeffs":[9621361273781053264,5019118588535294593],"_marker":null},{"coeffs":[4895883929736643363,12971154419198056727],"_marker":null},{"coeffs":[10593550744363593433,2053379475956543820],"_marker":null},{"coeffs":[6692415336616724586,1694977625669794463],"_marker":null},{"coeffs":[11337371351084041355,18256674430322642789],"_marker":null},{"coeffs":[8497865309165837222,1124465700187168404],"_marker":null},{"coeffs":[13929998560815916580,16137630144929247750],"_marker":null},{"coeffs":[7983644213276770595,11092596197761175546],"_marker":null},{"coeffs":[2086901145715377409,17745961745582768213],"_marker":null},{"coeffs":[2280390135035582578,12404836821647433404],"_marker":null},{"coeffs":[8059672680411668715,1196056622458729896],"_marker":null},{"coeffs":[13684713305385742496,11744561785242682640],"_marker":null},{"coeffs":[6185782787123572511,7184447107276237509],"_marker":null},{"coeffs":[16176191890798624357,16970924461896972067],"_marker":null},{"coeffs":[11259961431269107213,7554611487568927447],"_marker":null},{"coeffs":[91644675826892454,12577562090083218091],"_marker":null},{"coeffs":[16740611534963663873,17075322186347759902],"_marker":null},{"coeffs":[1665642267120313834,18139295100163290686],"_marker":null},{"coeffs":[5759202515785005512,7850490508469135977],"_marker":null},{"coeffs":[14187736444490557049,11291592250784414470],"_marker":null},{"coeffs":[15042115641582152230,8387881536187724014],"_marker":null},{"coeffs":[4920165866098467982,6020612025574153073],"_marker":null},{"coeffs":[6427346924093740964,1015497332176576564],"_marker":null},{"coeffs":[11309560693235399509,695000315142637135],"_marker":null},{"coeffs":[4500686210033372261,10174794351251603838],"_marker":null},{"coeffs":[6018448931756503148,17255688276209168723],"_marker":null},{"coeffs":[17825197371330929896,15124475395647065246],"_marker":null},{"coeffs":[8320177310853246397,5418697163563418370],"_marker":null},{"coeffs":[948409370930847187,16553664806927925692],"_marker":null},{"coeffs":[13848527028041318686,2602078741578448420],"_marker":null},{"coeffs":[4437726924666471925,3604668553131018188],"_marker":null},{"coeffs":[13989318281874066773,5254286838982412391],"_marker":null},{"coeffs":[16293029945131560408,4010357170186875556],"_marker":null},{"coeffs":[1357078337105382768,5474529367227764794],"_marker":null},{"coeffs":[12558973559701349568,1011207134899431599],"_marker":null},{"coeffs":[7493498549384375536,16074889631991012170],"_marker":null},{"coeffs":[11412391799754251022,9066110063883609271],"_marker":null},{"coeffs":[8752394014994916296,3217775857066600426],"_marker":null},{"coeffs":[17304459628325105761,5057096308538686171],"_marker":null},{"coeffs":[2287297983394666604,10355585340572182760],"_marker":null},{"coeffs":[5464045510463053460,17223169469320223481],"_marker":null},{"coeffs":[8883523784942577130,11761351040973483305],"_marker":null},{"coeffs":[3571607597271228890,4201712233048900309],"_marker":null},{"coeffs":[18418975195381928952,16795659434913707022],"_marker":null},{"coeffs":[13533320954238176032,257558027602410522],"_marker":null},{"coeffs":[7235706916942109056,18272531851527613585],"_marker":null},{"coeffs":[219610747357886883,12873155429344633554],"_marker":null},{"coeffs":[16494262536550676613,15532494590373115027],"_marker":null},{"coeffs":[12824910799739598266,2346612601526487987],"_marker":null},{"coeffs":[5740263443649228309,3866086217237331479],"_marker":null},{"coeffs":[7370480751063567560,1684929967951235483],"_marker":null},{"coeffs":[3182251625653888510,2639962360734861523],"_marker":null},{"coeffs":[5295594400531476267,7101336770606308556],"_marker":null},{"coeffs":[558210686209755502,16868190025526308369],"_marker":null},{"coeffs":[6342387602634092519,10594515317903122654],"_marker":null},{"coeffs":[11818144807535727887,3550858814678142755],"_marker":null},{"coeffs":[7975840229692565426,17312170367663559536],"_marker":null},{"coeffs":[14287141017969295867,5539737266347763430],"_marker":null},{"coeffs":[4009955389563257326,14107846213003118424],"_marker":null},{"coeffs":[11406314962484308429,224832049856562583],"_marker":null},{"coeffs":[3390514969638935578,3063248053835422554],"_marker":null},{"coeffs":[16683375906862087795,13243268212361934529],"_marker":null}],"values_at_z_omega":[{"coeffs":[14733784799576470821,5895105650148502102],"_marker":null}],"values_at_0":[],"fri_base_oracle_cap":[[16370820341779072970,4699864580641084060,9418722434544246799,9137969630333811635],[6326216057969738154,8699855173986743355,12554821412972285145,5242796703275116078],[16859222519492553351,10114235217034383040,7444926766627455640,4359619529230536698],[12271041752430032307,13957210257871516707,8612904092949124726,7592063062102406838],[995992131906159709,15337166689604122566,1027661412603596428,17186257716654156974],[18188081364770746745,6173995843217267557,9574869374653447810,7442640012381221986],[8386358488409193119,10652974860211893773,10491715416734462351,9844322080304119517],[8779432800630965178,14167722777231143321,10059018360113010861,1752821422166007027],[18273289795212828710,18175087802620862260,7686603697003041803,2038868755099793400],[3659621361212458040,1322910745480031272,16041505030492665805,12025947472228229921],[13737378981726608038,3797102524809980800,8177042930496541232,15437950383183962182],[3120079106487567181,13864239862703687550,14292256738079704824,15952272154061625942],[16112265863287256799,11564759352427173198,15667983551560359905,1435203250069965264],[1796798107742409433,12380597469868440992,16001319468078090515,8623956379347982278],[9233586929073841942,11582998506024362170,957758918167022325,2195273887254603331],[15334776021690397661,3011614101263141020,17975903413333648424,11678904926573379765]],"fri_intermediate_oracles_caps":[[[12673492105124612761,5118403623790313064,15366374277761753990,8111008799008530426],[13919776601239218359,12928798436795157459,11490457565036652180,5983460632257926103],[1814353358251547223,4410457355377201064,13528443748597837730,14258207240432887878],[2209419497926135056,12945856425133972693,17070277290552382884,16310884572935881332],[17252084152536997004,14649467395937609210,13547957224968930172,2967447610653176910],[10160982873637166409,16586661125327563263,9101166858436035872,15522071045566314099],[17920207777981046708,12548611479164867852,17830849936492328684,3463451960499505038],[10018931851524018716,4132748382716887407,7766891927955641053,1560105494882346982],[8666935678466864509,4478046295963649973,7882258654258572661,7804672442221577439],[4320775504997456317,3046259318701962104,14629946818643470863,18262538421177198963],[17264263743263943580,1833037317953357532,18307397681305260870,4629066259539430561],[18011065381744807947,6903743070156755179,9503476016902218937,15860148712948290096],[9586715352041398570,5041619324696171202,6142221064180527068,907640765260095251],[16320595600975478128,12619810027558134712,230294878976708088,13581404801694898009],[14557692985997986331,7903186497534373430,5064076657455351038,10948605216632570234],[5538852984668765240,9684985346032396568,9021834072428100561,17832503630194048652]],[[4424037779701888637,13683109259849482456,15379101337745512831,9320813106648353425],[627581261790758606,13534393841564262495,16386990498212711044,14618920485509932467],[12731718365014673863,4958069517237909056,16855524656139834831,5315944378181576668],[17807566263457145210,12465144276016547855,15225667644687205291,270658831950545274],[14985314698490971563,9604713447937193101,7143372780575495246,954878159614280235],[5204939444978553879,11279542978166778357,16173760503225394339,10329204065538515992],[15973289871468431133,15427643743428415274,14165516453517694440,1999148142730636089],[2714366761954495887,152094712803166856,12694258322803799585,4195244384442852862],[14133144187985330975,1689385819721822533,14844971730926650715,15614036244781252023],[11895003963242822637,2987511550020132075,17600164674617259987,11508011302907423648],[4674232428805865523,2770357072873547326,4382549158084754201,61501218574296592],[14261624628472717232,8907450055227139823,2068687889108204926,12672828953454399148],[14720871077323655012,6624369590686611519,8824530585867194907,12309093562821241918],[11710182820865379458,15937280929704517518,1919975643927719128,434423192706882565],[6971096447305792112,12161941429374251074,10470072107952631572,5170547466724389850],[14047145216146641505,17003312382936519655,7844197892938886650,1089346060833831989]],[[11932472207976053037,748689339034817260,13014825706780072383,5988111596141873118],[1356065497542656362,6646113278353417818,2582904667550116751,7375424492090583178],[6860783189451152288,11609390826454006860,1084918865299946153,13066957208159548954],[15124957365273956299,9575033634362278263,3604575503821003239,16100177121788925290],[17928830161851735518,14725933435328660497,10380956835409428515,4229784771099644418],[4829695212914188081,11705344478338702451,9145699071560678402,3928318546325590834],[4329582913738621913,5949189426956384833,10950976566698728494,6470710773978375061],[260169792893029105,14296036352431486080,10275230127280893207,17793789403270430101],[7699549129335872503,354976008013374440,887424905562418326,1848603885541996603],[9584822584480310267,4036823555559740634,1814173823306716304,16747237403897736577],[15317927844555506473,18267238748006788599,5292822222922056526,11887980855096525075],[13892188225561380239,17676080806954621998,10877592665952794931,15159414933858275630],[12067005057255548234,6643409720969150453,1924699014455550944,3993783938265092013],[6190991418932479234,14700621524927371849,17480483029148128540,10285494343382438086],[14424892901913618857,4759943183754355133,7837861226654098196,10735587063866841462],[5420502452791442025,1120487548166103348,406653430331757066,8208004390585500088]],[[3733479543711628827,5738612160510921622,9570387095914113136,10561711528863235420],[6860444356985501991,1855280026453973162,767075149919262340,7745765659521064230],[837509246865531084,4252252351125688314,1517896522101540604,1120354510061113487],[3904857045193607327,13984098158374017194,13426686690605298755,11330185511069884387],[1233684168340619330,9339866308089178104,1568981389707878714,5280259004859550494],[16521332654491508022,3945535605117974383,11106923870650485145,1132286496041427962],[374216492920500301,5182221604643431900,10599747191258551410,12876680114626769107],[13408929864320278869,11644458086302529529,15876568982920176294,12091845163046490748],[14982385279028419394,6340561020202059521,14673076265710409947,3732230112631866776],[3455310605425551930,10251291650180274558,12473228570571248442,7602252954098645682],[6032571251534845175,12501372497610375476,8156030796078190967,9875267309985767988],[5992022522464357153,13339685819719412789,17981081983533047879,13705608723844314204],[1282659250862017519,4567151302726914072,5296882130087499714,18002571842307254581],[17373170659457103859,17233930872303407052,16298376947870212739,7277970069188616359],[1220406430316799760,13380029853856022957,6212537407913828729,16881229388853593938],[6731160231232858722,15657731213189652818,12712515482950882548,3131746211648424874]],[[258270208090895262,902306266582303631,9949706723062551276,2185034287247178578],[16694202464400933265,12456172783888107412,6469519424740628993,6009903938691721052],[101066457247132009,13681602346701529468,9385583201558398031,628701798670327019],[13237594324093989243,9180627403806122429,15334734153869613176,11775570941909326949],[12029773474880070551,14319174725180937759,13160424119625743381,9743830429829968210],[8328613250509992056,18328544395034331391,15827817177636637797,8069074992829197482],[3454354908320873266,7659242061126764324,5366452705832001003,11913732833688405855],[861590028665527745,17532281111188414166,11712158291180246318,17173125712909267487],[6712350817811915167,2869793375180799790,10705889418404485067,1346927403549013737],[11351434707507170355,9028988181094766962,7053502660499206499,3948074630766340723],[5294108231283637336,2276157528025838159,11445040361204312227,5901051274090462401],[8046054452893760687,122015790637368891,643074040038317024,2038088955713580034],[8438349134532537170,13638410849600614377,15455476075948951473,6884127566644286410],[893205034610834475,15763441350736075535,16304512881132914348,1471509795556249568],[1942047597279546654,14908460076547823478,11030348558269582930,7155649486578249544],[13741168163435538656,3463866971449862459,16171171526458254264,4134531988116433331]]],"queries_per_fri_repetition":[{"witness_query":{"leaf_elements":[1278685679824729929,16124356913015902722,14162880898456711820,5778027578488081305,17269991030275847525,4406267706713264743,3488388260340902624,5599844353787803401,9914662410529847640,15578172387233874692,13714915345486888900,17674300391921449163,16603359211042057913,7083865444983926909,14167523305734045731,464715903802108184,5375128462767201252,5361573756871327847,11515396662905914183,7123838928569190368,11498053956275798516,2463408092703451330,14579064151936776489,6647630476882508608,8306796534191476215,3431236611816157228,6726162494485126184,2185257508482597756,12508478253197153298,4356120624612069362,12348832083445013641,516714241665619311,12940299859046041125,17541677561222187245,8863885740466896173,15076950418580328933,6345889921549110372,8341046754995021560,11511932651475505674,11799440269324723699,12388593471878915537,16730785898535026441,15383092634846317341,17971309863945544047,10629412055766028451,15348169083920141984,14146293133665902008,3486711561531641640,13900753496367957408,10353436154759511220,8290298503978579891,3552831764209930676,7611741461463890854,5129456726192404585,15681000818894259620,8204245048974165051,12518983028158247858,3366200150216525043,3650238190760494236,15593987636046865318,8960092122404913072,16901868389512481505,832995683739035850,839229975420685983,15696379103996831952,15841251694116838189,11320172030083149951,13926730136573502812,13967126320886493520,14067921396527454305,15769587193332343338,17286288503366822967,5620554341306656756,8490999097127618670,13349435965982402519,8870060249487175190,2821568469106546916,13692305979627647535,3713693831741116716,5663693241810672768,14862167363839184669,15483855339142464877,7606273474080210873,560435787693024043,14647675625157522048,4456308576655494437,16649736102723875362,5109646936481996794,1203118187355534223,16218961977565258427,5071363731950101576,745440822273693314,11398758242126495049,4209520623434437630,4886278376567273753,1045496463602947591,18316634952382394723,16366475478642873180,17709469668385818687,4082544990456103897,15928784174003824650,18084338165982231847,16352725989040145917,1492356898874618422,13674365763762542893,269938799546296820,1075577912873024226,2427386351374760595,9271499416864216176,7341309102304896352,9283049393423348121,5994977476231641825,10821358926238821052,6944665621760367627,15792372858103148349,5440495785516049056,12652645556837269203,9098919331834736433,5699966309915154254,4127411831763478082,754874798611121683,14448986662447939225,16326745249580746078,3970405077391264692,7375600141606602200,5210919318279947302,17446292806297691274,7634246972011920057,5901911897120167940,6966626281813263951,10539673541731951792],"proof":[[13372784254324697255,16580101804061173490,17189699496745331677,15469784499877737167],[4355066194296463326,11641840287018491425,672037964646134094,14398022469998455212],[12207284165489548740,4370939509746431556,4102702878736207311,8901794424397847044],[11827182824014145469,2335041656006680867,509672357841742490,5783392392479683036],[12985133096275033997,17045409687294393058,18353445394048032742,10244878310051383320],[3128699161680687844,10346337001727126832,12125494430042447889,7404498544351532556],[8206649143993028212,5338038200000764429,17348327762897379964,9652181576518905278],[9349476232460346015,8252835808058206387,3738133196177254155,16737013462368467606],[10862641728767976634,8328298421879235110,11308149931403367707,17499952131760155099],[9726144373196147918,1919742032440987390,14936022544948778520,15545589572183859567],[2424775634194052759,12855739591175360301,1346859547127452571,6732212918306216241],[16287460266841240538,12893972165006988392,12840368772479367107,10447201963824461523],[17718850284774686906,4249656049772419824,4091689849009064264,11228913485567390937],[26383720488409915,6286653902231473342,16109405247741335594,7369878586996651201],[9115411030585823489,9555310357211750813,18039608106183901226,15710933429724555307],[6299603089096614599,16885224374279002587,14064821871726195842,6369956055272979144],[11943032969864740135,7959850750732092702,15133996037216302215,3119839773681966583]]},"stage_2_query":{"leaf_elements":[15727828039515421985,9020976442136615003,7963556856570938440,2613745944252973021,3949290681094868962,9763144291671749700,15155005820655534344,4840881750063231975,16954736493560157934,17355300273311715330,10538858385097367122,8997964665384693719,7517653382865538605,13133668269706348050],"proof":[[8449281610283350586,8982813438689080505,1584524385777816737,16788224611485936095],[5263495194141945458,18180321617554800425,8603599733643268390,14133298879945033547],[11265009297504134118,12954741899120673896,6930018280870347644,430356421560266113],[6581615540711320095,11137751229606257064,16985731957382440993,1098799505521009098],[10065843612789005603,9775343295779437389,15574553525885736887,11174438031037020907],[3131298265123831871,11522290101128823735,5498992869662870847,7496839388541381205],[5711406358624732861,5529488773820577742,11918820618259088683,4355002508186376313],[13957724994094907371,10935395673617244347,2668955504386840936,14241362385490416721],[3171642051195908725,5488965338022892646,16729923659977752977,16154078174673669827],[16982733913602530880,15485117019154320846,495566480878280157,7621586637164137686],[13452096505939129389,16875463928712400107,5104365957997438474,17913767307248733157],[4171097399394295319,5821655537486512607,4068903105182178425,2460924103650160173],[12982811616273592289,11055253830141214631,4542631357761102979,17561125483362145136],[6342835905360678139,15741540146555753559,7510849581588099424,6718170541085634680],[10031671765655168971,13960152245906876238,16853124155040401442,11558519141392660611],[13298588335802645486,4924544341158094085,17451038673661495150,3651204588760381244],[6125975348076251787,718390605961733643,18167962812902370622,1668373908691130837]]},"quotient_query":{"leaf_elements":[10756216117014238795,12376033280964069502,8454806942238185615,6861096582568250601,13726366247451554578,15522987078353319693,11442909683637944238,17771832182716625103,2790755894613733226,16862759004281397048,5789069680172921429,14005811647534864678,9168928481218059582,14528400552689594723,6912959201244536714,4743045574158112258],"proof":[[7599640265960165942,6883249084330308046,9565364614944489467,1727383289207885250],[6521151945010131529,2476023293117929949,11801789698384306986,12296865522148574629],[14177120556320855356,5294292310972629071,4381213485598251083,4969993043870205544],[5243334751307554603,17024682977062200161,1329762624835786536,12296415690404431724],[10207472609687373194,2990837617457819154,8700598756704626250,16514477689926830104],[9448996437655341196,13605932112340131470,6110452549454444136,2414938488706558964],[16333699728547275866,3549078591138077690,17463775104643994463,18040487740038082029],[12411665885294150949,606796216207027992,17879607642306069661,4987515212946375889],[10623087170302232154,13779029374258149997,16137326705145296216,1633056789429363936],[6821158416977897581,13318986240843024198,4013504356272197963,17388163331226553588],[3164769954805463797,4567663632454315200,11017556612753741300,1122916368987505315],[8860729517993686321,8648456058386234446,9438111377052360500,6373768756015582123],[17045700973910273264,2032516433383947737,18022490646627262620,16789726899438252892],[10304719125027839851,12494053218170981945,732674850577376989,11049079734699660264],[494026304212832512,10301657485607283122,5121852040973331971,15280944006967039579],[9966602029149213214,1395151123679792381,7965095519201603486,7928475408203646111],[6305957632545496956,15786689006480693990,9348596821402279479,12430289352088415914]]},"setup_query":{"leaf_elements":[3316375850288632489,5011404337721835211,3200595220758017922,16138671610091091437,15415010376523558910,17286274729710541391,6187278012764833886,12699355602461425814,922543554186578826,9008817914995507708,938846829424268316,7345470814267217486,1943540676268305888,14371831219771755686,14578078542793869416,9273481141012366416,8872722852138553999,17578622749479772108,18283870942994615508,2655293483696834583,7572083758215123125,12044861024161703635,15296450014742889428,7620166363506576806,193383382105192160,15822662514516266286,16519041240988923501,7142915000458635202,14128989507226077604,8438556266581352112,6443185132382255431,11379742586472579170,10152551174632975507,8751609311657308645,12799264461428094133,2333991354561703000,10361298396426381545,17546950023625059490,4629112138625772215,5672836642045977116,17794658548955508006,8517185275792623339,16592507128100945484,9357586825449993440,8087031760639775466,5530789137995307176,16940334049071769768,5960718334249085738,12488903230680447054,5027631476044688624,13718255030570655738,14843337900051974259,13141236498243417632,2810161244985906816,458473263706853517,9100057261581566927,2012059930707317363,11244717060797955688,3709310009066405322,13442855555549493267,7643011487002828414],"proof":[[15591769515329668633,16816955918319457966,9898408584406481748,11961932098009147569],[6600264802573993033,10543852697331483767,12117837091834223470,16141938814676462701],[13194501030637724287,7573983405953511151,5771245518063024850,10515607794444615556],[14118411610841277821,13318426052291915907,12849153473379801159,11201144833056958612],[4506633324886349507,9891203358790428171,14501352891251996028,3946284011783295873],[15235656901267999094,8701882078559639297,12682835174552307113,8081136603750186662],[13232722666035654860,9901705112174671452,18196037620375421179,12929551362711267043],[7147734317670572516,2029529407475599825,8980644752985395091,15615746441977125976],[11167621406660120595,632925421475897208,9804618500771252844,9394071531809429360],[15903056497442582673,2542593386538008585,13470019147600381112,10577176543788818048],[11720814366626513746,14111261662669996491,3506097812342661685,18103233011048817980],[12127111796891818810,14308112776040296008,11720956507520698977,177704286981044491],[12748578721485386008,13813217256281840295,10914924509623599040,9772037411451710633],[6802688659511763244,7084607964206481230,8901577105313220515,3851489117103087110],[12246267538514113931,11528526589564272577,4357495462754649023,7201797501540593900],[7997193999307008820,11507332120643533390,4730161531846058454,3109611857761041503],[13514547956240234087,3380099716568992686,2060147130956422462,584955250598177231]]},"fri_queries":[{"leaf_elements":[11432896343722928722,8332293388026701428,14656803625544170192,4635432710163465364,16607263316765393193,16182895523463615285,13252088419609341767,18384417614990349412,804473613565921753,6716025572019770915,7215136159182371482,9878927814232476066,17567484877267919101,17480249589785039914,13637586277354121451,13300568295516441630],"proof":[[9299390424720690387,1139629346750630593,15404574150615509409,3102672150174110052],[4273350363345151915,7411653981228590044,12113646123733258106,7472675280847623611],[14467423401509025416,11225460104633742549,6806540929143666200,6960238062819424691],[6327232850590462450,10295206069820437008,6456975246299883899,6549513837028868728],[10488205774818525425,10565338921716585537,15102875546241295114,2104198570738060107],[4769104009847756795,2984570152458446620,15333742023829659360,1340145056444530660],[5035567390724832627,14515057130108577799,1257389647252727192,16517420174351366477],[6697710366244686348,3385618678022613804,7286056677364270126,2924519056204254679],[2027818161962052482,17507935198669616843,3289769899278087699,15110301469744103623],[5040777407628357168,15626804069306563907,6986821875627408778,4201541488165020446],[10286207529603600591,278024245552255890,5860876253233900225,11019576964052504484],[9467155807103739019,8294161443023797320,421798144502393239,14722151301561668612],[8746858824506741077,2291530368104285501,5931751732960776389,16293416420266682995],[15814433419485104056,1400756577291299233,12283248573486033313,5741139201462895664]]},{"leaf_elements":[6873745807717695243,11706049100062055771,15834914924517798378,6928281538542101857,3783382270676849734,4656864515687392413,2654357773675817423,16125331565981983002,1244746302066549146,17250718705994875825,6117415569212366203,2056652085075864834,7312501353080303556,499765264190901943,5211618531303508450,4591275086157552360],"proof":[[3195114360407650749,14205163602122984822,13767371365984823848,4289491339087347359],[16987988274408684697,7719738798291173183,1556604026508135599,81168504252025540],[1220294516017410662,17238055721753020883,4360204657201927554,3141654517169192941],[15125417568838917126,11335673921035034091,7577079621076109671,16070360068561297358],[12681029379844394284,4450594743261669097,15979914588714560273,10891769806879977344],[5198679114935930416,10001293868568796423,299436675783575240,2301011367816003233],[4805528679788687168,11882466596715777401,5559920295887605092,8584080743472044445],[5682449091028199091,867169125452532450,15175055588956947144,1213103926524422202],[2398858320507751212,184123809700784043,13178865882505178693,3851536557327210921],[3838902483026018560,7932221457684181858,13433828715684803300,3541986681315980214],[10544880173400393548,4413620492410911296,4389446069917864721,5889614876766614786]]},{"leaf_elements":[15088905083744694109,10248920673368976870,14274237668536331630,17912062064657119958,4654200548859833319,7951305691649189867,4681777460422707155,18330869925947114859,4828484279036918244,1581383795935484015,7544688042351317514,9241060864173122450,7270469056650141715,9168997529833414544,11976680816478028051,10445164105229580035],"proof":[[16808027070995938013,5923297351566491198,17511385874639505946,10058177328662223664],[6580781923984623727,17549857502730153158,1874779675110831896,4937467586625200741],[10568980332796030631,16077755588258226823,1471065071131941856,6435653157072068733],[10282648991188913518,16322780133132607330,10026236659251510966,15404302698734690223],[17944940781817484791,4087374420157065857,1628311523981419290,8831626423488255500],[15206428366585989036,4489099060382111995,12875176748043962831,15615572455681692442],[13205377942479436883,12029391051777767925,7103076770396749864,552657583238933976],[16631630429982415286,8679943977895137090,10100203201248511933,10365464695193725395]]},{"leaf_elements":[7110278917885502954,3838525861459053360,17885216655456475643,12203784864632625138,15672447038124146541,10667336232691496532,1437999583077046395,11658783516880749920,9700279257684463695,13024321341828431553,3586812253539625529,17044804274376653217,16872358009734449332,16709355359063702681,18119856251154552797,16229898902991870538],"proof":[[2361029571572455031,11545064752883563697,2328496015660277813,10305169571269411598],[18376853681252357638,863003083756727970,17186437038439172396,1399728322487586407],[13235876419116211189,12300115121663233194,6682726612903085264,15821499805727520852],[3242288807542686388,9026251970799052653,8236476831258112163,4028630696365931822],[12984173567287017121,17467429106527560216,12662914317885471387,5828856567217956128]]},{"leaf_elements":[15202150764797062993,15786181052905217237,12748874049699590986,1903621702415280935,4939408550848882895,12787098356702983307,11699632241234573225,95539465993985956,12767052104745464443,8619390591802930261,9399706688675374001,6338027382062821110,1046201738720626964,13856301340253912171,9102228130734331605,921461332835551084],"proof":[[15470727910277273188,3849030510198036565,7194796162985154763,11084332455497805787],[17093440793069753537,16513802885514608026,17543188115145949188,17171117668842399924]]},{"leaf_elements":[12597644431430244040,11372706906312571978,13913858757512220008,2566233284407244613],"proof":[[16611364857998161051,8506600833192962777,3117931063065445539,8529191711644863332]]}]},{"witness_query":{"leaf_elements":[13863216732603852220,14864203675111461136,11218700557989340696,15819009667177429916,13225921082022692557,1491829080043717143,13216525840826370894,17321047529035091649,6396311922970974431,1054971637432719493,16336122843350509591,1405218164803607843,3605752009670347372,5150123282703811517,14911006555615693325,4507389009133553889,4209960727993003551,9928212547820177379,1592767628775621975,11032912122916742523,18062491894507993670,5805492230137693683,8598313843833705447,12784921253069682881,17697238980022843114,18136889798831047479,14880592392618188757,18288564162853966767,7053972458715939788,1721421073792398682,9395770939175060217,16271043174180808944,16155542810687538344,5594389302594932307,12302948788852722043,2452972695344185236,5950189149689772047,3061242702516192427,18399366286376427352,8761365824177263407,11047808782723876249,7377794367133228277,1068061586687611250,13359696351598003359,15671337690237140283,6750394689700611256,16637826618266829701,13203925809931777183,11764311188266408862,2941960318239796188,5256908912432823981,18094155222909930204,7224820821509457455,6555568760023415877,15586996180219715044,6249927474320176388,8909957619516791720,18221155070370840457,680066324431598289,6832755710040844833,1170044547262450999,8200469397630226795,9798730397121719795,13181159374917190636,17437472803700473441,16202905149076838239,6526018484447851022,18189578964358875242,7316196788426827498,1449391529514557294,6693509990186973692,11289447994045608901,7828542591383664440,14389190699651452884,7215450046415156909,15616415531198914570,12951425976466818288,9712229530215403615,17518075526633307587,11589099792690022232,14421631214940104005,6945874990969168,6161883511813304962,11030072150862431473,12187518111311933142,876338671100783572,11673363244420791300,5536154055899727013,5662388001227953674,5769614432834033901,11639064831205902886,15094493957475718044,10395879142289557272,10100431044031982658,10126213235418749057,17677438912260269033,16278780269847582238,5356031851335818758,11665640804448661359,10673993935381636633,16313031137380958525,4790808455788734630,9200892122431822452,8098551287609827716,2484015194510372891,12328903887680912819,11977034863266054919,9503980466648045878,17527284849698795819,8583354919315688758,13699876208142188259,7477249574973078786,618609763421994627,17522549038080609897,16448040512117367076,592214965358222750,417969482156341152,12091453876028162968,8105205400976497152,4281293561604403512,7430022169740295263,8017527283348199830,14080443791330709112,12571174913757496871,6355699536612229846,3974986080045398622,15328603178626015423,11577326758241339099,4850126471075416205,12805765613097954140,4234994706502003931],"proof":[[9800183892364089676,4187543567046050530,12565944886816179281,15975437586592318905],[14377380636943114521,3117615818204545355,9905412884754676321,2511190851468969836],[9772989010714784541,17507036686403699677,14329167518621674151,13691124183454964908],[7171401156814966132,14503532388056171776,2519535190558977483,7928068698000269541],[2265972672293221983,298590783835982460,1378453610614782241,4251294388863846570],[17548244349499542998,1413506001965720930,7194026145828740861,6826872882194998300],[3722659743388999009,5365810784618049619,788213060422320844,3136456594592539786],[3054449817139740945,16288939146216815810,16379271662304300250,11361636045893231473],[713473228923603610,2878569031758292883,7378940793671682307,5248976282179139334],[4543603537924008531,11986226494930185661,15339722330804738978,1128732176527327193],[5703745090438068546,417239261998866926,6693705514945373060,15125199541404772655],[2640516317709379572,17971373541526685394,17946349389348556824,7200717875234265512],[3655421653329771299,12589817449305390265,9491632020201351726,3971845238749761924],[13881449545889092743,15693350642773289927,6530612449236174033,14152326617206080703],[14634704070137678251,12131854469869876432,8918386126357594887,8001901551460989996],[8072639082176612258,17568341920853918402,11369923643445694058,398426348360184980],[16223097477568228514,15107169622771903152,4353888938053007471,4109866272590480353]]},"stage_2_query":{"leaf_elements":[1101596422003664649,2042590507464790340,5737513209970438327,3412528212083191293,5376436026978214861,15775046569554570714,3703629681652173096,16683929163128554026,17692218454152166061,6567853220529890011,3434516206967277836,14525746687142267214,5092060661848014026,14080108446082472760],"proof":[[672058824640047410,10013633043450234874,16313991138312789572,11302019274919767927],[10688064850875582667,11650338190795072756,14702531640307929113,813865730357656305],[6945205798246095388,1457822172805167662,4142589293110455106,1289798962389527182],[1544889252259907816,14381006989089566988,3847497872209772562,11532650018924505963],[13700823826835187651,18441609535924781033,15604541114389038217,16857573230603287440],[17661565432210882401,9205905759501017799,6456998885471595299,167329009033952287],[11809552366045119711,3907595077652744279,13777440451423415422,819247321354468295],[227687772317146308,11225653321323552136,2432304594209458182,4843990742881797911],[4334407763901726170,313450018968628179,9631385124702328626,6809582893710680296],[16127661337314139205,948686671024522264,17406035419323670745,17133545086933127440],[10460225642310499353,14245452209608628276,5703587806876771784,3409737953336303343],[17913138208261535198,18319501538947306597,12431079821693391353,6332484923029314356],[5069633424450178769,5277722028380646396,17011660884286439744,5496654038015642334],[12104778285662878306,10126898182615894411,12412775693906809939,2068916940728423974],[2819742885865406755,1583896963160693404,2446170842504686953,18324416590345092453],[1703898148018402254,9494127036287711159,11254466315374574750,16117938292587610966],[5871806667717910386,8335411056946152827,1215122802519829202,4329801010722079060]]},"quotient_query":{"leaf_elements":[2593843085646849126,2792839278610528768,9352445825997110554,3250764609871211737,2820156167160878120,5675044702890922496,2563123710561714338,885310145851980121,11037356793879513966,15507036247002121044,1799709176138754860,1165414718604268136,15963213167857869476,6274663457646043480,18239266226291880276,8619943678493333056],"proof":[[17720466871439362144,2458515192513276798,16252744226031379544,8840429114588640250],[12638320649067985700,5158436369181751208,9925753420409868388,229518942069140559],[17463695701820640162,13208413955456543004,9811759221468992436,14974770763195281437],[15702820216277380690,16130799804790324226,8571988784374269642,14148311597174927438],[10806520955738592277,17275179655495752430,4890100645502017455,7295562643404042001],[1817665527350473807,8082428686748015251,17222008611704240140,15464100542924227335],[286685467918201719,16070971931958369730,14769807217955505313,16040034007071994810],[10084491093867532751,12901126280613345122,13957607191678431864,14280529931778101725],[13291290577475237405,7410344956509857284,2954327021205917530,949580143379744168],[114204532072782901,9587722439437539421,15332637821319549079,9992265386407606135],[10652159618069080483,13953569301666254258,2726630786556948403,4429371806807665563],[13374914474761282226,7690118699982478129,2172231581194808218,5509437284277277030],[10181167500688060905,478937781412569022,13079295438882978874,8022582687019299818],[9095972428020078186,15448966360592514428,12407434884290282363,16342689086374947387],[2929653343038760813,12245303964162878784,13208672705124469466,9446434637924904507],[13861447659773691260,13424256322251709663,7929184059624946494,16187815052216722753],[5377886853321531037,5068418336764625527,3831105231537902742,8019854688524569751]]},"setup_query":{"leaf_elements":[1121306952100759668,11755114023683596235,17399361770228679689,5994888464378624767,7083723490608390551,14518416355168250979,5103034317666902996,18406315460416570406,10546420865279035180,16176569673005287302,5275426908322710586,9458884349874775976,8726541568752087088,7956425330086411013,3911663252998491381,1957150801663026181,6819209176460874114,6943786546743879483,17938021530062736821,6757612792712826031,6747410744109771181,1997171365807842161,7745121324030300298,3372544925243551063,2907303826157735167,2800305595087367618,9529062682515534597,5330125139147059820,6885597587848346483,1349980573193072127,10012377141019413133,17976294380535948356,3789513011208000293,6889059543353720570,13389661057461032986,1587152570363060464,8575498588149482603,15781933738680322442,11937829559717936251,6276086644475947007,8141418121664288937,10942295267529423638,8980446677793636792,9818316259351941060,17293158831095526893,508911577279589225,1996615743706473711,298169374671484831,10281701774186338084,5329390829290809315,15010659874626709070,11531490668864431761,11000299198096744531,2993496085235616377,15775242930622202316,6873914224819963056,17954726662024998812,16036180776650096048,7560130901319836856,16901392316696499071,4825767781772059603],"proof":[[1710494217685349682,16115053697168712316,15729362533055534151,11384732420881941663],[13723007289430876132,5884288394853482600,14202389798538793867,9867140805559032222],[10404888169907442332,18068506046598821668,9269998498934563923,10229948246834258083],[13322363031135800882,17725079626357694620,3526164871261571982,13609909241927936004],[18288787048182507476,13204767528675150864,15973139979868797631,14161295996023363123],[11297093021584567949,8914280221052215741,9517647278964060605,1993362145500819805],[6286994808262296159,7118889824535004380,6305401147376406344,5977435396205881612],[7234513141369318481,5366126465474943452,10388578782766315324,6947303682465713948],[8432886339171630167,8619842077730617772,10640801589582051183,17644464375965493363],[13519469834230032509,17489675108687903198,1102914854735690790,3831874402737523247],[273208670030703020,4105915758371579920,5495085511593423939,10013478185971835945],[1136528578569628522,8454685282037697325,12863082708762771379,15750078740438865070],[12968144510764785768,2466742160990063397,6140571771443410718,8146024797402483451],[2754294466366465613,5613375135143932498,14944114938047741544,12361459023793748210],[9256468719778933924,2368966330726718713,10210858981833914790,10109361431070547794],[15406844241651940972,12596028732776037699,13279897417670693523,8282250005542349188],[12060882516990353271,18062336232280845659,15112757981319442566,14295771334065133069]]},"fri_queries":[{"leaf_elements":[17223157976077222513,13315822823953717532,14023274167570305557,7631877167764747009,11516511299014479070,8860084285676562379,17017495740448088801,750893412014516885,8900489752593720514,14510172049701140233,10488565920354267780,12174423218334541745,14783725970737867054,11125061238725940157,8187424734628853068,15588140766051873323],"proof":[[3087431058279236490,10543873684449213453,8925141333287878477,7430794835716885345],[7221631570091980575,15997314816014754829,14744903260809614988,10270287456619744380],[1108662723650930793,10881487439221394195,9665503915898471574,11319160883190809431],[23118705106577957,7110799594031968018,582518384840882669,4454272366076035686],[11319762925943573970,12492543533543570299,12718470055078917103,8290308011298761520],[12339073342178242824,10098149601530843692,11546614284274616302,8660423519496507171],[5570961807208531935,12098675640374453883,4502296212301280314,9554448850681564465],[11244738101114097453,17721000149977599424,12732239018239884392,10642877531247601941],[13283658786288391654,6660343312467351506,15398051672278095829,512755725792344358],[8525723990636845703,1711455875096753924,16867621058934316654,15926720262557503969],[4158146789488407883,12736767911040145711,9297059049247838639,3491154577222520886],[12595565812059763788,6871323598003274490,12594013759087887397,4511209178933887633],[5502308638161325911,14610767682874674969,12889767220023112011,3460393891669828034],[15451562443760431236,14499082353945845691,11386736860540678516,16349633736424413311]]},{"leaf_elements":[16988565257119726510,7293497420649322254,3917763459274469467,3886374563566006006,13517603658291797504,14722208415122608626,11064503402306665418,16052508558331476734,17268958553124613399,12311325446904713425,11808672986852537437,14105705234809203319,10071356437898434079,7887365363008233796,5687008686719607623,5454962324454579776],"proof":[[3344631222483821572,3992571801931566704,13930416079370549246,2086299731613871826],[8979588298990295487,13432017660555905320,16630860592655736640,14104241493587373208],[6950690756585655919,10604022529708074645,5870068944298965783,2620049551616052135],[14785930953857210650,4695871531835058507,15941540463980949508,8388177527658091775],[7585963382798304681,10512998162151162889,10138719558247542351,6033191194530879426],[11401644446627805854,15433283856351154481,6435303129568691527,14222870549466951981],[4891203427414256478,8805216531457069807,11302272016616486148,1490356039503379217],[11646789076273071497,733924268478560107,5485696874934262169,17625139997562741512],[1579161448987160411,2995298868455887002,777292269404709788,2746532065741894532],[8701182556602948792,10190209272649107554,12773055772007403052,15827164044187913899],[12379756798398335368,12781876495701630078,16204068137559689675,11665895975816789516]]},{"leaf_elements":[14847069386818459846,5790470091585145938,6267736358178118446,7905942683646748793,14696946855391544694,5279673981367839147,17188673637077499775,9435083887423416155,11968511803127240574,7588080956306199892,13027195011154565853,6160903937307138100,4138680464077949743,6557508813051462768,685006609934187971,162770660049716023],"proof":[[10958596383807905867,15111633996003170723,7618574639682845479,5851994450990928028],[332542740365301170,11824845036214652016,8020462279304318866,3382398796079635734],[4682579319759886299,13213174653205715219,9490476255932972691,5544526447689419251],[5884114914547025482,14093456391563470429,11846785503819716933,3355896885410742623],[17091672887975264161,5363278835506593015,17188588289404827706,11199463184737878943],[12341099318253616588,10689332131464562214,10800673175285039787,11146281990317595037],[17394859831473018027,5560182041147289365,13998219351180941063,207352775630490989],[13026042088435669931,2011134095450519707,18027490226845733262,6580835643178696687]]},{"leaf_elements":[10066203706638680805,7685608654379547799,5241687444382875707,18166469631063484005,9105209589651616131,3805755914269105234,13771943247867994993,12326707722488885399,11342906078389335986,8977467403331807150,517918789343721851,17847611471834796282,16491443102187664014,6195029847525655541,1732839853231770791,13428914083589788207],"proof":[[466733193579587382,17158191518018796538,13516606317787881257,10665642970511630131],[4444354679599101539,8688257191504780545,13368164002669027782,5276873474248272185],[9171478075162462807,15368199982888558254,544001458971836841,10328288046608249019],[5387705283387024320,14010842412917880888,15217387128433771878,1952493684305680795],[13576853914633880738,14940004865464326471,227561502295571098,2257488146281360122]]},{"leaf_elements":[12508043303203380276,12071050613693196252,4917597267451337379,8522911289558321819,2665447352550593313,16023902596123739171,18433609178457387192,2455331157312895435,5254461340929434323,11228242911215720123,17405573373020844744,12923639064435141324,9684857397667125894,5115559970155831904,8273413097234149885,9013236197037723706],"proof":[[803145975923768761,11259312858953462285,3753807215133909016,14483887510753031536],[8859434493783711083,3189336826114292609,14174841169115998680,18345781695200256815]]},{"leaf_elements":[14367577272868085553,9602774064874730465,14713880134720850873,1766211907198613748],"proof":[[303259409192285017,11030654848140337703,1531364211497220714,11843859341669102662]]}]},{"witness_query":{"leaf_elements":[12383978411135975132,14141620332841441307,2955695295525635497,11783405077041482014,13662883120360411094,17366435200173532654,2284934060235205300,9074653099979448175,6954200538465932398,16018405600591061280,6318682601536543857,14184876558231279148,17490824601828145875,6411435058408627236,15212278192586887424,7146919141342388049,7923299140316826943,7194432485153111921,924459082897254992,14926160665699785742,5020537793824432703,7518786727033576731,6759109932838033163,8149095465196673855,10874255543058827591,6487552097377182404,837428407695426152,12063611615293991784,5474909666309102400,5014744142316568760,5162670814294227949,14396226460512906349,9353446376992433956,14826649039975098195,5106065637332307550,16734398052715946181,15772939640332912224,17199285709778404231,18233497105184260458,14833183574375860425,11008628717294776340,8943620322000963896,15797844608255747439,1258982437013137318,5759343953098813899,11973628034369018440,2565582743655880013,13077332507322127577,10097136446136272131,5763205752366403822,9465466045363683645,15018704295146838492,17148973822572029635,16621795884418726308,1906439436041309307,6023753466413715454,2859879907390765878,8588872566717176146,3936981980620685201,13929052838477412758,16709786133363640164,13260665990122387835,16188976380943696865,17958897755518736540,16945202076512925951,9750177130254869093,18367555703031168202,16360959012251641903,6444291895110285817,16091294955783663102,1609429669682927569,3092860975664091010,6482775993623245740,14919894913459901532,13047111835924127825,6367146691192524851,7004649122214427386,5552607284329838739,13542081272697924762,2373028752642029825,16433104421399617864,18366005920261502392,748089057383968657,7288191592050437666,5499009494444712394,16842135574597675206,5009089328205666901,14278410079430213229,3420148092705177555,6057428404434972312,4902140828736404579,9821263461887533426,9018081953552664372,9858952783871094544,16045696311047007649,5327360992151349786,18170660824623556058,8839479559002299652,13264264628117205809,2146822784900684724,3382717987713213315,10346205191512658792,9338609028210954956,7438931287725056561,1139953711918632753,5534201386528337247,8943557888753525935,15106105775300282346,4742293616855275329,18417655866096135958,13428496266036638898,3202333013817309921,239109848405337351,2150364162335861550,1286074883773545116,2234100664573006281,17093182106470907543,2322792645641024472,10865071419221077187,4503097896545986675,14121731587485394842,12763630227143269439,9152283887065217257,8369179829517691249,790704814256311319,18171558706248249338,2430000334522734146,3372169697698751560,1158003824497692611,1031384317487684937,8758873899544772562],"proof":[[15013824659952477902,16263088972983282783,10123681149279726535,18424472854692981688],[9303980859972248633,17064429513731860636,3936177022133524530,15863956460274949501],[10576804903570886006,13767248322812869587,10904125119731989809,8804764354737630439],[14045442360695971857,2407575112167693812,7965967363740169523,7855853109408103798],[11133199269778734307,9526374590466118072,9050705125041593799,17920290274926397373],[10568075276627644498,13900348913009511007,15709633420378965097,8187914557061311932],[10403895241404669969,6586733660415206394,12238537161988524030,5573023580946687626],[5265604441456874315,12725624856638927893,2284577565700008334,13782369504596031966],[13346131288887032140,3443131328352076638,8098814960772663218,2992424626316706446],[13657493790766419000,5055061409334658685,11625199169351462403,15300088707803730095],[13653480550551504740,11574259585265335860,4257711881367019357,6561249803519416963],[10991357843533134213,15373717243110842556,7913758544220740726,14335881089226506910],[15814683711845364445,7750672521429580953,1133637901528559286,13708453402243189424],[1530756857355829779,10817191729181821037,8352966416033682707,4862290856092546523],[3195725028447413883,9790415710780760078,58847711843650079,4186091914898709988],[15315626147334945403,18242524699322662909,14276867673315777968,7132690860137372401],[17865166144098905747,7390016598904853841,10107979291902490955,9436749795966031130]]},"stage_2_query":{"leaf_elements":[3757298771224921196,7426626335245134098,2359338932991327626,13593905142343406223,9618336366158745196,5098106606127353328,3484263278044000722,16473578829437366670,199870216194129863,8950682740813276469,63622333531994495,7483178594788755234,9180837025128318042,6045511187000249029],"proof":[[8136567699984553477,10435401551344333264,16624765582117104977,4390430867530369564],[12643274838484303149,353143072097178406,17544447127028217439,11064694695749987387],[4168700484941523819,17176010541168348810,10296504412463043411,13884110188662847356],[1534626295047156362,1468285154137776397,10370403565037244190,1803770458668816739],[17584151918474739564,17779411770428279472,1912843252117453124,17214553450278634744],[18292066061994458972,5752563244917946893,3558081369368425088,15822771340150314129],[16145155654292983087,7845548412497309519,1582458622650491397,3057559727727137623],[475855408101320444,6463344743061462239,4222765598115173341,7085398610296870713],[10225601481682843229,11191413972029991147,14281607252913334191,17372421818915684268],[14576449831967806847,9281990994699831052,9038230367713510193,692340226297139584],[7074818395816454488,369783263382993224,1951701450914655428,17721204672540239808],[3800045161280083811,17456090548118921012,1145375356885620325,1467325731041722735],[2429845617424977490,13647582021517795635,10161502489710215107,244233176116970060],[13324867634311004008,4123957901618755694,8102016649123452070,6499951319704507033],[17849577325522944793,8535331683234475067,1648842093157807098,15625873283244864762],[6009905890130933657,2373660380508197677,12786660623893110077,12907311798045809157],[5992823250717574237,6566103437837786488,15299331955259601897,7680830569138827481]]},"quotient_query":{"leaf_elements":[7732622118420288508,9003140001616851529,15759084616609392704,11009012949605089136,12881020878688131855,2233274802965599046,5130837318085945889,11838263991762160908,15417991859557881044,17963297562623350998,17448583672908850592,11283626272943136415,6769661418854832771,7744424744095334003,9329574313581583677,5632502648128669550],"proof":[[5912189173449714201,16863660785148906097,4773184870302728354,17012058747689368540],[4852148852072597448,5124898432263793342,14459702466055474511,3484726414214198879],[13388953651743464896,7328043897980355006,16213726561198322948,17011670595668090831],[17232315935772984467,12457639560122479022,14715161616561379853,7182456259280617325],[13025480372038785318,16093644235308579688,5939428045990151130,409007974362473835],[17757217839579149356,12574049631097729964,14319747605313991667,12979381570244483071],[17389217552679041024,8607254800064448779,2001753974387641044,53882759644279135],[13976506269242372791,14339352098797079296,8452960350714515021,16865161950644732134],[17218949606593859435,2488361257138851137,16518069103810352767,13235662771904884428],[1660301031067113115,17839710274091927811,14547369470021406058,12275602042041923023],[67657804733437098,10218694244110108108,9489427832683625400,7107712296159610108],[6063923013256952480,17604699894651257526,3184345822996173895,16288044389997279597],[8247963873034667811,8798560067156155377,15350979594131357402,6314041475803082788],[6473383257579668257,18296731061775407682,785287926121707163,14969266247380146042],[2440890310593990632,13702443488101009483,1642115163364334895,12033149251682921325],[5241491156640478250,6113407242334473897,1595188198348252177,17687859277881291494],[4342779165889968941,6482951464513037436,13462260865303116355,5710193447373149973]]},"setup_query":{"leaf_elements":[14493501835100439375,469665006850038586,11633562755878929246,6874393923693460506,16290830847753166072,18298606689924075288,4074778132818283649,15487186121669565737,16930538022284484012,12714667303739778025,13001173064436891102,14143859221899258787,10604261270429178797,9304715508428068747,10056052306884143366,6023836977833167241,8889359122788444831,11405538984936842794,8563252727492760326,1363367432319369994,2963591654721222817,14595078328668932558,16693507940944367915,8359696798011749227,441480208100634649,11590760864365729503,9741055226481103044,17019462364060736095,1028082870753691223,1536918831227697371,18349045556906098820,2949388480717268066,15965745981043602952,193539516941657243,8457274771935489165,2805684911486708137,6678306183128217745,9787452823414896923,2517811577319183969,1925840477985577204,4059495608834600284,16096188029420628927,10859623869441114144,1081893077737335083,18159317514643848573,10323181993551985648,8354015951246355543,15907184955978572882,16263243195036631806,3134900180731217923,13550259911724213255,4482796798367469720,10558507721318620407,14329135450621990649,10628305085000045721,3983033868890666139,14962064207556956348,9666357647072395134,15587486729264951201,1101658991812248458,6101212761932997668],"proof":[[17988776579084983659,16541764979077583977,14098909998973116,9512742529018801623],[4087813339805174340,8663541814833728326,7663627301342301182,15157744812455814319],[8947233218152553279,12553756645800762720,17383754266815682905,14789552013622462921],[15738590600826907626,17180316365247031262,12100856200352677839,4855932422588935354],[8166245480092981605,733090162232233263,11633712461329390708,2749661448352986107],[11543945563046969257,12817480227712571328,8326668686774055675,15186977438285577712],[4488535977556224584,8344485253243788591,9977435438720209752,5214617520608270157],[7832880704159731347,330070793561499879,14872903497225382591,5457768558851511857],[4694294113494380789,15255897590698369266,1485371844308964638,9378231084762729161],[11335195615286372723,37568934379793002,17037157724994650034,7915786120733980919],[12034824155580787930,8215703584874043978,7390922685566069803,913296965203545487],[10564829484782142206,12116453484827470947,585220046196984138,15261903748362404656],[13929835176564933619,11767093283831950198,9933872111473807253,1688908864831346283],[6996276057554255160,10713295263328481279,8399795769261046445,6261188627959216447],[2434683239255506323,6165565183029533897,14859278037701289543,5851152211686720108],[2395306436722752831,10185097690296105192,17500200131402924133,2932773295728481789],[17466908762098371552,8363535842381194231,13094963899949745846,4618844041241187208]]},"fri_queries":[{"leaf_elements":[4562024854206185740,9554996087692211810,18431306140796065757,7715127535133536428,9337734179347364273,15522455208438690043,5718181916835578927,4673320601501950370,6449441223156487678,6918109138397474341,10387507494349631277,5093238772488407517,16824707280782410892,714928028824049460,13820918088093408250,6268998184445646942],"proof":[[11213646157581100823,10442147180544304086,5207345561623224519,7219317144806206870],[1463287662990559239,8471512448107239216,13330843252214224509,12984381196807333480],[1557744223205454636,11616156300728021066,17655546957524888902,7855395120863889103],[4557742922492540248,6221027135345437898,3141156218713382828,9781413100083861135],[11971771123593070088,18047917594658360948,2677152293897183809,8588960762035564110],[10111423571713567410,15203889560501376237,12416567482726350999,15391647654211793813],[16694040493791663892,18059168727152032677,2837284499158482119,1749893778255460893],[8849409002357372366,11855931742087755250,14726221818124696031,16958367570235898947],[9168316059136093985,4060980665754817676,8728967637296458346,13648869368748278332],[4975535631689270499,4792971566346852230,17218919521968877253,1247211214667661950],[15350842957851957517,11388579344607069638,15269323125657126466,18004314808433265135],[17296488231566278942,5414210617786149007,8444836326326038810,18438646507089327814],[3155282313289701307,2079256713782685100,415586920237425704,8665585792236417856],[170141225394435602,17262710002343083717,17402703200700202917,1120006288220426873]]},{"leaf_elements":[11307428846616679708,13083421204399335487,4939588679973711333,851891969349192640,6526404211622333832,9889775082885154881,969693520241246191,2090093886976740168,4407133171916592533,9671408619438436490,5013995133246461305,1839849209387751261,6361236441851327022,6029415930464728794,13332123404948910971,10955854435935268736],"proof":[[5526321193642561824,710730693837247792,12322020761370034350,9419279055019481335],[15977265364105413420,2101925794745754493,12417115883224475251,16316010320334760736],[9503141383822020939,4311643398028580655,7211473932839275091,7334977971443698265],[9950614625863170582,13535772121054325249,12883859050009942867,8897784048313606383],[16349177988974606036,1192121998997769926,237925759087361965,8612684647046277681],[7622390169264868203,9214820127731114187,8539283180913918694,12543786224290804811],[15772664426872645060,3565314769211666566,7076540480295283613,16523480053081553659],[4570885339429790956,387880730417596111,12341088459857043908,14008146459868392151],[4181542733544650395,13636448898080225407,12475169714877111075,10645279390492686412],[693965329252742554,16449575740939220107,15399225596520391030,1669864357672483939],[5199094120865169560,17463526085841947172,3185458664173315361,10083001392030090965]]},{"leaf_elements":[18174242412224480861,17472751023372592040,6972597647892309810,10177464545971286015,11359181072916136118,5531774024276371696,12419250094609660195,6646495832743894982,1346333351300481350,7656779692487813465,14025613819378828410,11540178890663031709,752811199024815373,3931555456526144569,16888575181465309818,3975511680721705402],"proof":[[15917040247893481911,14553357949351803378,10012031977159443686,17486697344113247435],[17895739219009673513,17884919168031103858,9082960147657660123,9311775767240881897],[3323649376436129603,7343387939078456778,5397522000734069440,15506113130421230633],[3936816134391696646,15250151613824628479,5744922741086337070,305448728684828444],[12248830404082088334,11503649573107710639,2037793287277798909,10390929779576392798],[13505860172763799703,1715081617567359119,9827690646418726809,18313943252521763003],[1609189558051937423,11308985685505938629,13302836710246669146,2882525120256854806],[4374567577159966410,17125851462093643157,6121986273982530193,10111634658541985454]]},{"leaf_elements":[5185443137984635290,298015502775474725,2367414585972077160,15278835795241626441,13577465116997624432,10469754261645585445,15469183717260840043,1336533838505753972,6237849417012505874,2564029139207083243,6912625510179854418,5187514119646536559,6667357183424186093,5461520211276511625,16521511285844728568,4498276289474242467],"proof":[[16715740609242603909,11472725327220782849,16657562680687787798,3930872102512162648],[12472188699824342075,18264570084010083225,9823171612416269593,11308253750235314431],[3419202394589390085,2866188242382666071,9936444150518640755,382711416259522893],[11928411680048580500,4762063976722926382,2824872982311524827,16815131402363802710],[11592770056521429672,16191424820244574051,17530068385739319132,1206134198485462619]]},{"leaf_elements":[3300250305250749040,4436628421181352487,14755950260598254312,6855331856632198767,6961176707265247413,7809467641002532974,12537721873115918955,13307452604079373914,2877106935352807193,6037790657193286201,10530444072344727318,6645079980048218947,6072315830198853148,6475874352387416233,9139330217433178316,12963513562113426093],"proof":[[1010931422580187053,14540789589166799608,509754243052097714,1169249460998492933],[17077067914152246809,5968092716277181305,1224229199107816319,17580625464655193577]]},{"leaf_elements":[10494411487431777395,13475939850311038623,368963683293906755,16111128358625557866],"proof":[[15375026947276182328,15281698798523912774,1594422934667731334,423440563697154486]]}]},{"witness_query":{"leaf_elements":[15977033910063766911,17610571673250710014,4346778586738735432,1034642595651501377,9640593308824069786,5010067161820645819,14880405017893695190,5666200073720274511,6406929135702355033,17729835349892881877,16838638768021063996,754123424776384986,1369201553220181571,2941667099006505261,14043657849438050545,14783124364800978653,11894652504621601758,10779982736352076618,3325656536723116955,4592575996849801249,8843326567842594215,3707504871498185982,13496112067387346339,10725421562956472049,3723002192294414599,6741151010580217128,1844992913573067501,11984085018818795054,2009457201589746578,9857992588854859350,7074659269478531863,562011748199016980,16620301315947946808,14559083458902166355,18093474154188141774,9751644319996848281,13605827250396369938,2826654858070478914,6097157537917412777,7595481956158133217,5089117101618067849,18352112274931411658,4280641581973906293,14067962535598753048,5216396263799201385,8320631442499297356,12568573804378520492,11318505543952062826,8648983587903684810,14955917732702102840,9838943633341215365,18379531868398973574,16852278442973970633,10546068816140490872,17939589697107845629,6676537218526120886,3868762346930631673,4143829998937690726,15863041935794988223,449071599939731562,17721102398886974162,1032279486883124956,12966683504665969630,9969850575747858257,3912324472843850853,8367993237485595631,7701123926188699085,13947538050908761843,1746097884591022420,2153509250000846695,5820173900965957502,5760699358441895700,16097394628025771742,13369433253022917495,14960471590841670809,13733168306533720512,623234401756067675,11201182616631985955,4280927044028660183,9503476326050017263,3988299266264587169,12578134676241354000,12709448833255582429,7147718220485252420,8486866161345022909,17577868650347445263,739171156374118868,29273322363360495,16645689119508990219,5943982374704617419,11726105950891902180,7947726225021525561,12935641413390734045,16837167464443934738,16754727243075488974,719373092268894388,15156483564073446015,18011019928939841021,17456178447162163057,2569391859512284261,17921539421239973227,8754075450673529439,4497034066603564879,12541150359335069633,1573682527878941728,14224563820322842325,17848966806943837885,11546832195571047054,3038724394276236560,4979969820999545423,15603259426699968598,5537338160080784695,8763926711707982503,15627089173143605580,805623281464449353,5435484561699765702,1131986245932504356,15290892441248328470,8450315201235352744,4448258208287045528,8563645307046116892,10757042863973498399,302334491745419708,1351003914035637714,7012235959674322840,9065667847556579516,7091702926663062216,14056693459844216557,8994259885568042766,10329985572560922802,447642380631032150],"proof":[[13430270731590702755,13913881016786591896,11751903742821859445,12431825783867547227],[12718584203968446440,378528744054847576,5781893677340313393,2873718100961063103],[11744592381560380213,4909173289350629080,837209408106734841,5437849288900805260],[3099302760133928612,12151699152429078387,16134861700924089754,16372926215508320692],[6267037148876840149,17028675920758473943,1534199905741773704,13234299154213443192],[11394919440318317530,5686731032019717669,16305353898540432978,13293302949044820069],[619585132822296145,6378435501094724516,1051719966393445748,9157724803449761151],[14068809159436564263,17932838101385084512,6140756499420225931,11310814158221870993],[2570157691404095185,5295366151696750978,18367198797886767500,14136694673361402531],[5543599649247873083,14838841652179184432,5761383219523817780,5677258822093270737],[7101020382623787776,17485156762218383240,18180886613520264009,6066656868880462210],[12751357724909550499,808132940903040074,16415075415579190349,3477606844593793745],[3552958295468519712,16985051103021815610,260945709356854719,10530937815463224881],[7663994947227555456,11489030873449665142,9935159063567454297,5007192378381799024],[6547530937349251102,13347848973016222795,755057075677278029,18334260760829946372],[5137008909247573843,5491678739555322598,10712024963839968982,10594542023043301072],[5780903278015675520,17047651052402954586,11942609028261001136,17993021700732801640]]},"stage_2_query":{"leaf_elements":[3236041891340725793,8581294281260615231,7959887476179509201,4964111114279926505,10840992700820628660,6017452919379590215,17447314386818592399,4991279921162690469,13354618712723229015,5928599873115105480,15914461363716889755,15749478523571697933,12557936391645918002,11867384995355190833],"proof":[[12327964149962508097,7284104524940459937,6116501888059375633,15808911573315158526],[16202999001613700504,6663332474607754947,14070475043957952499,10019308336470709487],[17133609020479092249,2256637681732188699,17177112877902984010,7320166727838375957],[8792438356200438509,14203903402910082314,8457779368002936940,12653239191729701961],[5727534800748636031,9795190408307444316,12765663415943627038,5029207517540128781],[16106960020994780952,15305002192962098419,18388375873041644811,7636784402497224674],[11564628693761384587,7966372412888175947,13030058149343852157,16491749242732622892],[1656444468555184337,322670026803370970,2107777165336909872,7870574529540863258],[7318914717551491055,8917534875072671628,10746433177564283999,18060510063013873037],[7826603282495168596,17757867103941126644,14586199114065555532,11442264294593812751],[9104263119924663075,6808292795190853416,11519375334728905155,625073156667430880],[3135899105498863554,17650757171333295748,6380138685098350461,10066204681612507295],[10633255859233455332,16765339141426665004,4165301333987517719,6268466692418468034],[11776248807548440447,7024292781585496338,18017364943352739015,17866704525243289637],[7928630884867147627,3021875154943204323,13017782439411418391,7220870467363742499],[267567802678909657,2898353110227635391,5704022019229704396,11702755541008140804],[9821710105240352479,4279517482634659402,13704767358895585969,2774967519268577047]]},"quotient_query":{"leaf_elements":[1354701302445414286,5790725851387187921,15442162284600052511,10141030275712967160,2579984789966075928,9486711544579271277,2356411730694778773,15065753189481363344,746621146848442684,16585994084105427010,2530878626343596414,13413863650905749437,9341765362939445478,1124890661304579161,17425081977329210589,8867509170181279774],"proof":[[15543909096322501330,7751323547993807639,1434033027970393063,4020143791564203832],[9584512705003370597,9289415981478785423,3443282094875660750,2883780635441171331],[7214452829564315201,7858415051844882806,13560728935801343545,14955529618659875677],[4303484581061229909,293983971404754401,3837086025277020722,9059910241549115555],[11666215950758366878,16283907339131841159,8602770098321045946,11760916847455443013],[7252215629612975210,5516235372810275051,13484365532935592979,7580180975905895922],[874459046053125361,10384554340432056333,946175329451011910,5868084742465831348],[7435749001349792991,11516562222028890028,15671414699733901754,7593550909858268745],[14456026458967119533,9450089815354368742,3712403200169750047,14511370869952814044],[9617516294321239722,17919880223785189236,11145658309096598326,5432422436341172911],[8918275378268352405,7943782665594341650,1764818314736400051,14728571819489061629],[810845339098516878,7234014236135754601,10359734893170720434,13846245895254088718],[8700386207393718360,6319685943766892392,15077106119049524683,17488958623158963642],[6743251946450448825,10433597312497775401,4242714338028027892,17287840274271567853],[10741033526163427837,13855432143284632891,1938363642190252247,1665092855656422678],[8124161782716708731,9221667353246849534,8034047284345420097,10963488266225246847],[3901568850990174475,16948880853950364387,898672871153283304,12137241444218984600]]},"setup_query":{"leaf_elements":[6534588423889505350,5704131343458899083,7779696133784478489,3333448532380813248,9402381858749168547,14826141483228519313,15057989623503638168,5876266201138299780,10232603996496396878,7443422542746989567,3861381035372915045,8058572006337868585,3793925173507710163,4242940504852867977,8735185677790857886,16723805856280426572,6643547065242393413,2709509103611326176,2023632042303439287,14611441953440035324,5220421678706133796,6373785248976798717,12189956507909350549,3867502791472995325,9351277924622267225,11329247454842320502,8245046296128070669,13287207976006174568,15511815558197600462,13432349919606165482,18352375437926876431,13675586326227652254,1467382527925803230,6473555043606743565,10705514949304576144,2924114266088667217,577122214240961562,16795161242907630273,2114594728973454844,18275490283990973739,9520559271829418387,7834076967754015370,9421420375961571694,10591770342968893235,443355674065665509,8400551292670521779,10489110543416650536,14008766269741852563,11538987403693019075,15200755095740766670,10329459641822385987,15136659408508820448,10849631228704883669,14763520114751766424,10489557312397602877,9854787794211299629,1356499550682840802,9081346752563410644,9360197044129524932,17786752169135176113,10359499249507884603],"proof":[[3686853617372377992,16041067421462210514,6375419394119706665,12760637212545387915],[4101263535823426612,763725732291739503,17643751650203599741,17270667090602561427],[2226173229470810226,10262971498610662625,787184027087809486,5534289736851217712],[12202414120485496341,16413402345677947447,5243446202265822199,13945919089077148449],[3396413695189228454,8249449881373997540,16716452121816937244,11979091275052659459],[10293930158387064446,4967923313021885651,2640050331601392912,15431725404064939580],[13159267028809622495,6421715619013444552,3003204703660878022,8570101048245542820],[518424487058041026,3494250592475475777,15005389692815027863,2647238985981288655],[236556817868693033,6546745157187419874,15691973836942625040,5262293360078279508],[11014073092041788302,9455307130169351038,591907821744703017,7687985859722765464],[9469119956659638276,8445812470232954407,14637979213332661944,10196904286132455823],[13069940666883257250,6006326025047220319,803029819904388520,7776774230345557359],[18392372541559985579,8416640616596789256,6923921180573009178,10360922933073544411],[4230109945252521858,15926505056709734778,14059791724351339471,1174615987391456604],[1371026364080532241,16774247710175122284,13594938526221534741,10049863576485880239],[8645460761936294553,2596643575582700729,12253196488297932077,6801439249303104782],[3651073611918533907,15798734934902616878,1616672673493228833,15298427545319406372]]},"fri_queries":[{"leaf_elements":[1376982696697797760,17174673750518471144,3420128789341643184,9835978822898658218,3985430388500541928,12455030247283666500,9276977624945066571,2103478554748125000,12265665231686391889,12945624788093011450,1623961274307843298,3382422217471511613,8852428426336518534,4235347906217062681,17778253202177287973,2734282495795463867],"proof":[[15038513105057307041,12038956342587369334,6924566692630572131,7928376877103380715],[12962012633405870880,15476564747162569946,2218900079069303930,17151694929870689905],[4815354657166980331,6909081025056970497,2297260128926247340,13554562284564475330],[9532880117516040969,18015901632455301816,7573340225782685469,9132676328712934957],[10873058052298965550,1335163339488629397,15309078821058233539,3241749184225109087],[12111216575742363886,9239085613522569249,654468408651252880,916743307046552853],[12254351689972266120,8030653957596391942,1958483757379518036,16778024678763895618],[10088700425526250939,16612638956620219718,10420546505562376504,15513211978423904836],[6809320763760295151,16778640624739419243,4837181724266195081,8735806646252643027],[2020825087540607224,14664442401262683920,5239319157411340496,8891502630544702097],[3274172595639909051,10024668999460491430,5446411398882597978,7008969517587446715],[7123014656215236820,5780918386823782470,13158535959526125970,4250923143104606742],[16143217563511954298,12460461016006714392,5048205664306167815,7199179622793046273],[15141646993592924744,18318589562432473142,14826518153774990406,13336047225910522861]]},{"leaf_elements":[14561338578057920846,2153925397867025351,4494457261385596948,1971261094758099250,8829599020570212640,14854905261446102329,16795452318582814973,11479470170010414868,3477232277778043249,12768651289729804253,7836304797862071064,12203620788987379434,3776990063981348842,3228298856868349782,1723147790667007197,13737619489138109357],"proof":[[9010596604284726555,13150804528519364508,12486652214619924044,15583399967620534621],[9997607467713825428,8120409051926193318,6050399765339780220,15634884904959920654],[17349847396857374151,9654513842382508038,6863030938901134678,12150575994080228870],[17117625062376160304,15607764142106973448,8626130946153559773,9022968318660558635],[11760361221443454547,4504787193636359701,3932433511277287836,15559031335877930792],[7002957790796748473,10294412766506988517,8839743171603094421,13373676315130627190],[6216256709523150518,10295682974738186792,717717253252550544,4652676154582582484],[14471489980992121712,5378686580276179189,5169415796839417621,16451544843620423932],[18257075578666263394,14338288314784368334,2465361707852793933,623360075579699239],[8377563358391425715,12391944246418071305,15243388599149129631,10232558016508081192],[11349772500409747002,3366669206451581272,8864662506650285501,8812011237371875873]]},{"leaf_elements":[1282653694174019476,11830200572800413787,7790217502795308415,7447160170784084932,3080805605871081286,3497378400666227246,3227333144428675315,16520118475873825123,14452842812386618589,14257481495812955580,7574955765604763198,1059550544603540258,1024913318477319930,6651992039119502579,445899966924309464,13157695539170178054],"proof":[[9139103710350921228,4522666472120565556,13332297818011265659,6108416066912044050],[875770284895542891,8314175308461122992,39148355442815218,12611881647571219951],[17157969690229152870,871687961035229474,1392612037551924129,2073179711693014330],[1628511454174107917,5971894397325927959,2555823103677387645,16668069055715777951],[5375155032605092462,16904292919481486176,17236020097790282618,4598089711906153269],[304945883805239849,17427998458143488654,2106501579356704880,2121445978530088925],[17575013460988716215,7549009817869098747,11419827090275248767,6639213259602142354],[11197245588527443982,15745526000003865227,3490794832014231404,18359932471148049175]]},{"leaf_elements":[10450683396586985239,11576558981812480777,15661373064070909176,128006710311614006,11812364914089819887,18391418802796133014,3405461768810915070,17906589991365549423,14186685265895179758,826207914351129916,8322920308174935763,2350171823194754629,6505549093040448825,9795109333800684027,595024519665062221,16287634415879029987],"proof":[[14250548659790273516,4795204468250209812,11213089338717083886,9120283384359553532],[14752944708747191888,15693937280720728938,11243076546771230149,5376954664911923368],[12331359160764049155,1475629026097333530,3896276233560635643,5987152647455137038],[7130004473046552518,14258741773593552419,8989707879056938128,7121524956104583132],[10945294448648566989,13821939225563904776,10530290785404158150,1320710991026337381]]},{"leaf_elements":[1074662060945156405,10621057686042909045,6813720275036818929,8304621859181714652,11624811695506665140,15461322572353960896,10142396076549159224,2186034861058563142,10324011250514407888,5021252864369045080,8545469348112318854,7998814467330267789,10055119331893895483,11316892023055203401,14941786351359279716,6000340179845071572],"proof":[[1967337978586121576,4731993401279183116,5310786791659970432,12215043265417586543],[16674372902509347714,11611872601324962899,3312282548524003582,17404813053523781834]]},{"leaf_elements":[15345224946206544614,8625126391536271404,4695382966192564506,11784709075726900115],"proof":[[268335760101084646,17808592281501734448,11906254015832598598,11418599162854101892]]}]},{"witness_query":{"leaf_elements":[8812050358264285525,15635071658102778258,10786801805902812267,13035078782529249406,1911589171234464257,9059796698739782046,11156921340843154754,4526135742498908668,8452915740540389199,8644398771949178572,553037090741969396,10859535638956512105,18190610988541095949,13349200643088876454,7958352223642118982,8710147297131354951,6324593758979357792,6936149747519642860,1935245609708959590,7092960993663728974,16785365787506798854,7321071725939422360,8289821646024917747,14651122456848477958,5066066976282515294,7515250356075098416,12683443073754484631,12990094523696441393,13919947386592445642,2219210351049766131,10306268376655926314,9720464596202888951,2195212882409732709,5140452518728748437,12912715378562005692,2280166742782697629,1026730422604389326,8848629567630236067,15240336373165781710,12342028131511296314,15071394809630674958,12341605065820356837,2018565884341743442,17449725693324653508,3283944786714558028,1092764946096525578,10441048933427175559,12800911081533847783,7329695755377111564,6942962527788829396,10416931921246235981,2565271352315277112,17168326314448023016,15112472201380104540,3049290972813448272,3998712156616037750,803697380022699034,11788069739248934069,447925626302836857,8046875225272543517,2482043033881757040,9587046926979982941,15968072584214281351,10189413403741527912,2663598718348852505,3608868643661175931,16631658015915424182,3177601357336750140,14564004560564826854,13428926914539868342,10352523647852067057,4202521372538311132,11949847320211397301,8387729369414471535,15705967348309729040,13279476511900591994,7373801490566503876,17489183127267258573,6332208974185534067,4635876715547896400,9328514398376818286,4355601847153513897,13288410646225809734,13265382223419772369,4166258954936855950,17561432301130413306,12531500535156172768,8127453383620927999,12281326300652164637,8791388392430018321,10482694251478170436,10766638626242095786,5635855025120296297,1580116686365720236,10418473286964793094,766052860639004068,16572037703416875502,7458947394273181881,14694333901252165834,10822891496209806131,3846990233027550937,4802866881893198358,10332852568266666561,8471666321164180117,3230552395363678808,4226412121673180319,11142346177380686411,13420024812552438024,14234573986238134226,5445987318100407730,4313141651697640722,17932039256890268815,12989241096022809495,14051840492187333549,12977585198514848814,6748261533305474906,11833738165352775297,3410403408902537964,11735475654066687221,3665054478977309433,18126928774147421679,9969401420593530827,6628050907472606295,15092656256556470603,3445695104650478982,2454537220619804133,2486593712444735428,2059785149760349513,14615595101607981589,3372682318640622184,2532061499169041072],"proof":[[8241184957267896673,9095072376422089396,31221723820099618,2914609298087521645],[16921852099692809691,4848507376881980771,11741838511313899306,16454892750719042352],[9108315483673545515,5818595905284364216,15487127582546133395,15582539756141723664],[3195641875209441706,858197920095011767,2830234330651685975,10628154137367771576],[17205842647248838406,17970899687281437615,4945672683617052603,8769244415520649964],[14076473110893758860,6528355344772604941,3669145912322129340,17466483797207576683],[17788976500958004016,12590048549779023117,17321134330088016762,12194749771711932832],[12434664732869820474,7132913317802193511,1162100315532670971,10895428127116726347],[5222204795150944588,3802429037138250357,9823463627273500057,11191383339766477009],[461897506495692129,10695651912772733771,8795654969431144584,13674029450745023888],[9982120569328483115,15186194627317096268,239416282193110746,15391760694330444212],[15720974010370191316,11223680491215220192,12397308119627389672,16436736128063661288],[8692475032111143369,13000806301403712076,9687729016272505184,10216694632822623755],[17369087026695905940,2282212673265061605,1118548304777193570,6954710172276262795],[4900587688206718297,10231252816769128530,8567455879507348250,9829074523241777914],[13800899791786948994,1183333435184379289,17950372410664387618,5565142864205071605],[3393871209601250222,703884795262674403,5617473330063218609,4166382418844188663]]},"stage_2_query":{"leaf_elements":[10349709738357056155,10084808916884620232,11570497723178610643,16489822900198024696,5860323407672622776,9952227698250741828,8071680273443282093,16790707643871385412,5966316595422488483,7784804994040506084,924178234200918437,16076282123730872364,8231576679198380184,14612575341327708118],"proof":[[4572466067644663666,10629901200036037661,7107490575361886475,10632235962694327291],[17276913737791976888,150021983494561737,17946006451825128133,15330059345838128993],[4277566442715563681,18388940105666284928,9353123940175646778,3822055683227646970],[3117536245337187717,8453273947672558505,5512943913163452112,4404446512352205291],[4745820365667383832,12628235241761926541,4411340657896925663,5929534578977842491],[6466161736268438395,4419902326557247775,15681621662774269507,6229559350501012713],[10082217135629872723,15403321371201506988,14406488974559141824,17458146501907682621],[2260841319485486507,10932226112655322703,376236986631235903,2951369342053638291],[15864852393942063403,8995761427432813025,16156146251820980250,6217782721460142606],[3130751655990561734,17045893795342866225,16021828987862568518,9889763854177817810],[3684860919706656152,685839786111810676,3787562626850865619,11417252361198138452],[627126925414234354,13364332302956749379,13886102653928287620,512693954951310175],[14602081994659420521,1052770005959049803,14907808187117499179,8263538065053233421],[13192153476846747681,3782050004812218088,8347441243844239683,7357573018300817869],[14070496676054058214,7273478636224730245,3565976135672878442,4148403636530026736],[11349201894860166589,10418290087207365743,10724316435702442016,1613603781219327118],[2376589215282065375,15866912507816706072,8741136943557390550,3471792826795121590]]},"quotient_query":{"leaf_elements":[9458614576478915835,10900794930858561484,2349907823610674544,3466187403511303287,15042164028386974318,14389439793223644271,17028949345813853159,8063877765626434967,710860654372634459,8303952182745793462,8272335466791611312,46703043656118227,1773935858409850563,16405745509888199203,4205360038204652140,7440143451154232610],"proof":[[6824999187704367440,2929136300759137392,12038634735800754221,4776946473216252149],[10446134525015812465,6213944091172921104,595399689903770206,15105747145145751842],[8733176292951934015,12669498080086163022,2615796286829815887,4411652153929733560],[15275523671367381293,7737909416525827795,11201223216227198653,18319001001777782772],[7024320428115667948,15572669516257215094,2868843502367349912,15433767180152966754],[648405463065554232,1266944067764607647,12520216068530132350,2002159453116715325],[1879917572846413457,11809157903376973037,13830489701557139511,3170363824641335291],[17057790848524575821,8711366481705528751,217925065198877759,8962473138830912905],[7516759395442454151,18098477660355971618,12506427976571890021,17450281874974542313],[15728038362302016115,8888299101537716818,8032989088235488182,3119305773673943828],[567270716953729139,7408745832438984599,8745966670697751814,1921252930186371915],[3202273046983014802,2150013647384427929,14107261418265295224,8142328139490310471],[11214990433593427425,9225303768681324785,5175083799498198960,1265433426013082396],[2101710739244467232,8978302879598038214,1368358489654925626,16930967362565449596],[10920993177302999616,15890028055034911147,719896489404155256,10165001987556653741],[7702373905826084876,3779368126887063776,4187193899147183797,385307142625548285],[13873983527620793734,5538246857807205789,16428272114622577962,7585704904145452900]]},"setup_query":{"leaf_elements":[17217852440059726607,13973367609246894256,12968784344779383844,5541895685141680678,6511352525060625191,12440203945545283835,17147312841347032093,14751322357414083607,12783148167920115932,16355532756533312114,9218513843887366823,182799196415494254,7257100284186313001,11781571397103878020,4678507536801787106,4712304693055572809,8769059880541038820,17211252963437525440,15177979425591978901,12517584883810423534,10809963043367929077,10634516257291992998,1381591114518442818,11838750657688756411,3505969276319095605,11542291246786049668,16977065493252815910,15694961883166864403,2461925300551917545,16087636745575649278,13185290341829069794,14460316499563096750,15121895230855262593,17138140854430214684,17372171759453369166,7262494679832481399,6749534159980067971,1219666220021118598,2377847971675924865,9486417927716968663,3912466093355182121,14322982914016580734,1548928275882368580,10107567488439473304,12169022114800961683,5967318842999016348,4536043141446550421,14903261329000110496,2729721162380225181,5743444374372182953,12368078714249579020,10680471942410111902,8870240704181400417,4567861473661317259,4600066838547960684,11906544302001412045,8241802167128608746,11135604413496598218,17133014797975401516,2920030632359764760,13127936848308669614],"proof":[[14922877746326431173,12569499868118121143,6252672048921270375,17759957951612370953],[2579019472231592517,5018739380396691298,10561089639635615940,2736044513399828194],[5094632723303958264,11457111052919576203,1739689103698760047,9679076807825049968],[419612506493036686,7556971399151429653,17685576023841929801,15352419801258726323],[13158947380560177155,18020317084227255251,14239388213117778349,4166909645864738178],[7409740783332962361,10601030529402443525,4778165175584306501,17723496030489935016],[2694677523202802078,5869701245050262971,12029895225688666527,2716631688012426723],[2684129531151212791,15249068506564538754,2184326847172559133,6217264200090462294],[4613749799210999663,14817717200395149240,15711906544319938956,5898149696871236121],[9428322831833183367,16116760485149551232,477937450009348931,15688798818017899608],[11053454238746379990,11600271589741882601,2396099546779319512,393758444632242031],[655691033320015835,16412069212811139057,5835197896167596067,14339071164406108255],[10627531089833481215,9254131416287074594,5613434488447835240,11629061763971620224],[11870154135573034837,1574308178116234128,5096332214877679812,15729712510518587812],[13530515322648684842,17777205920972641278,10798484095630807357,18234302213199024675],[1417980075933143238,17220649434937122116,6856092148304195601,6828658372095855296],[10567984478803164623,18091897840363936695,12573130155263119716,15666570801739383580]]},"fri_queries":[{"leaf_elements":[10199793993865694189,7508049704310032640,4174243609621770266,8900896413826001349,10163788114380746460,268325589422053402,13907521003874614648,13136337780251886969,13848145800061493021,17060164009535735376,2611668138460131753,3261723022737411351,7219229319256793626,11754261503002954967,9841990387889343066,3963180311125172191],"proof":[[607961840073500000,7897400316389885055,14703404598429981737,5408284035534024021],[15602111045145784194,8654056763570326518,17483250608523773981,12094966549862766406],[16850534895135815659,8101105885992709231,16973090727289435146,3120062696669534091],[16316166873925811397,18429850746656601355,5936354709031608269,7931155190717230800],[527277047262793962,16055691605897882695,6231716612145936842,4084415216700932543],[15234740193552010674,14935313303291550210,4351042934174215237,14600209966785815826],[5494253874868449658,9483321694311616425,6188193376440774749,16075760176601742473],[13501665943706423017,389905195003820380,9671983979614076432,4588463314580048795],[15012195581544690527,11382562283139593654,7237080744910605021,994613940361061648],[11038568727903171953,11081975897747162128,1488611262680254190,2868428986770882205],[14891559444684416102,7365785223193341603,6942060519975560111,9146119863624935043],[5425442438461353039,15929286459683500585,13565460685772726763,6546243097041444674],[2832576672971152501,3379218287516176698,10635671997862126689,3952401530073630782],[13760676854779378331,12586103901516069338,11837711225087432254,11243314579595420294]]},{"leaf_elements":[15852768176691150813,108967611785337209,3076166724705205142,4733178029327157019,15896528029030121241,9567815622183967952,11724365303060386467,7419466972278384591,16358274882141468798,2595940332751145804,2358756253894784559,462027774389646943,11765330564006388300,11777994271777347607,260024962241121585,12659754005803422409],"proof":[[6833786018870260059,7306451922609086351,15462370667372721276,17380264830280696801],[7756128907063906597,16979138277159213469,453325936152067558,17289915727010297638],[13055707277172523759,6043677011328691703,13860535313191688128,11651174823775735833],[4738081667175388188,110221569929536614,2030756998689315269,2258991097522229829],[12087649653047906805,7891537672677661385,10773940214731914960,5106518960746768604],[3763894166170700096,5834077350092411200,4089277706706399948,2166422370999902590],[7745051195916351455,10129051112293494559,7078372447464650008,13254276022543750122],[3076840992565678040,17163036640262359373,7471762485683160745,4822306373762225355],[5175257624663398980,4539286225251211377,10941147869261002418,13314369086779785581],[12087264947137892738,12689087948258299724,17318301511932808606,3098135342556233594],[12854372577048767948,12893725682416060566,9553528197170383843,16743604674518758559]]},{"leaf_elements":[5617741078600771369,4058930967925095803,17112428953063766730,13546023315377469685,1302417963946446421,11803855357986030806,12833117864390372172,17762525538652024362,10749086791708907945,7822139514837733164,12609252694234292558,2852251854928180808,184695858153019548,15801258012353181858,6801479451719943766,11610452694740878883],"proof":[[17621518457418499959,7054956147233897494,5881448311482405391,7656501433198916271],[1113170364988230541,9307245614379808575,4567969792216819111,5724223056558446374],[1260267360157203527,4620249471626319141,16278761561874311301,2288590777424929263],[17995215095597576023,13083879879621777589,461564270346471403,1303885522823911837],[9957621271111097284,6155915636442714436,8264241726652371839,18437604705727887177],[7363073909481985449,3675549985562018383,17451585943632861336,2575911250911410670],[4447284316994042079,8257006850954281651,15557837868395411088,8259950209718937077],[11304602737041440013,17087162656942784989,6482489079846908548,9342824352433447354]]},{"leaf_elements":[15856598713492064632,13260229803866065501,10194356289746345768,10463674996779494786,5965972151683009740,2994616491044079029,9535285059793165136,982502133207016476,13858199677007980328,6035778492888450767,15914512936378010742,5321584308353181382,9808219273078331303,15411245663110294478,6918086049792401810,17528292114523121110],"proof":[[3480949151625278207,951091492201610216,12465312563744297645,9539372492621919176],[6911616199934215236,11032312448715094838,6493499652420954081,452487011568388570],[16317551149453830040,14685964934087046081,10928105415248821599,2892889681396738147],[17803484793277888087,5831958870643149590,12028396324057597898,16125611327991568626],[512053513863061598,2002380255743949479,9190584305322589713,14156749039100967704]]},{"leaf_elements":[15594754714644724177,7034980007528329327,12757709916267302126,4281393678233531101,4937848372780748433,9300679720985447739,4290072722051965124,9046323667082053556,5892411612232638064,1676074571555259132,1246360140965797348,12062615642085843283,15942348569860199954,1244987182438668288,13689167975444961302,16021208181444307300],"proof":[[3531223462616494339,1721779358192805038,12040767781267643105,12461900958415241326],[17826718640729923265,6529578062451925741,7217009274646659038,1084074285071589791]]},{"leaf_elements":[8809988403807970318,15160362933934845700,11776238319247965586,4703853722671499035],"proof":[[12235680278416154865,16467979665684915512,9417111133874346442,5572305809501364044]]}]},{"witness_query":{"leaf_elements":[5594597565164404494,2028109770772169027,17121879032178525680,12267108979369392001,1665166854769140174,294907996804166500,7395573129020611876,7850325028797235173,11719646505473753137,4492133238051626347,14433353938807656244,12670879776978176149,10162433324810626858,1210615759810459876,12428818149973223107,10966440412000331752,17864175269368420134,11604821481476738916,4347996811179597431,5449502122099219004,1818820681531628235,9207524896780352768,12088296307733290071,12861115013708400367,4236369748737091839,13781805304895022444,11220263667133385540,6904615985917791745,13605038785818471966,10766801565641209633,4605059679673589677,15272052623025521424,17343298002151205299,9814650282502442509,11144527402968173029,11587849360832031161,15183636257133605083,14346237279222803225,7509292944475429623,13721880645930949537,9083245365339432301,5975038463516782043,16460546795142109473,13621301436234125301,7895878918297611046,15958453921329281522,2631721927076446981,18414191346337966963,2858174797546152664,568998694099857705,14608568993944510854,10708920218930794018,5416256890749047577,9086828378374504485,11358788218869695224,819160220040972195,6288275666733751020,12012860278694642183,11560126817407015415,17176270105240017314,17891095661698335412,8054594843601355462,4278231225236168659,15759576671924185415,1946052395106656567,6644796224211582895,3165328303015354519,12083728214045590541,15472561070868241939,15631824657213136996,3182610452684704510,11097630609635032739,216990516080244528,13694050720756266627,8516149914031476571,11885385847819237246,4808131002559116704,13974598144857676106,17256444894381458505,3448480901239707232,12550400765801499894,17172462383031287394,9562263368526877098,7488208321482156379,16991523594669848603,838229583662890902,10706110285195401644,1275747270868964223,1134206286181223125,6413382024438943330,6522855534191378740,16026063913314103355,7857786140142419683,4940165613565542310,6628913789466296482,9203051456713688397,6043152499779324187,9840874556052510151,1911858406315134925,12962244597381569285,10167530950749676091,15094510288092439569,7321622198773984031,14731468626012659897,15490970151743687142,2799113992357556015,9335552230687124934,8500544805641018705,571740353852845359,1033986181462504754,14191786876930824671,15923230315536096776,5387082587515497156,6613274176603608681,1201671658234559111,15563550394405922668,3595626156127427166,7984523268596532912,11437234444840205785,17347436656260505207,8778398170747818543,13310855728263996010,8282550314839020560,12000126695953932412,7518142875229620781,16193639292653080806,5659197821299524427,16418933976855822172,17870367207483393791,16645222179714622360,17707730770883772825],"proof":[[703170307586221970,15569116062649835229,12274704946191730321,12481343220563402604],[887368650187884168,16074778659407839893,16785150448460927200,4512304912201365816],[8505515690242598733,16741970026458325301,2969811276210739475,1077953387010877615],[9987536072813503303,11830800699523385028,13874927758732372618,2997587956651948925],[716473476798939163,15050356858422339380,5539647074671828096,6487545354866455982],[17104251881499910962,1288611253263437931,4017865118453574551,8197463788201559813],[10033214609344360620,7184328059015095412,4926286471113856003,9426510784345684995],[8614686368808858002,1795779988557724426,4123639359471300984,10631374739701206379],[16827646883737648138,16294486359750541600,4328451151597825359,1769542088023181432],[1528174284573297153,15870603159338744719,17753303992797760315,5399281265772906387],[7742237071753657598,13242443218990741957,9738174813719208437,4711427759404479489],[17821167298174289610,8301791013693276860,12369581494249169540,6802973645123060327],[11408492779251847670,15510947570580467229,18220867933090159503,7544743324372818854],[15398682568664973736,4676152151038649593,2032919694847286748,12608862949635255271],[8464748133805986085,3173541812581670380,8489080384197873701,15866591111998128126],[879347377745451181,8108356877829843793,3165329137865426209,16785548039980130513],[1515531368785806118,12574507258131797238,4478339747602551492,2855719036921307901]]},"stage_2_query":{"leaf_elements":[18247276515368088591,7137756738142567540,8670990352365529313,13491704340779251049,4726538211334480973,9081684591215680557,12229018930557292775,7853311525599335978,10980515055039667757,9531472656945295952,9768271163133979534,3345951414238019829,13056666246299823747,301246638837787646],"proof":[[14403755251169729620,1268914011941112087,16170190928615696609,14351869909750447351],[10301410577295869899,3100889787266571295,15325484196359983443,17050109249630653861],[18022595735313706793,13483501599818378555,11812246417492539683,12089277934622656592],[8986887278859121220,16452332550388690425,9837659692404782189,17579390945899598263],[10652240378445137577,1781072978782389044,1913330324806964372,8400505110454158825],[622672722143777072,11465128737066128759,5648181413798261406,4004089509947912012],[7666984954086100326,12427645416305635770,7951215380673300870,13677617527159817970],[3188449628145032346,8863612055226237368,17015199467518505065,6122482364516726198],[830824202710259891,12163977761444007504,4658088461729584648,5038834099575061780],[3373158842678999594,1359866332965927826,4613349850851541230,8909459868559328310],[13100420775858751657,16597981136255035615,7896154885321677742,2288657033350913804],[398545519809298278,2232613696456437407,10369971261898373943,964934683770506135],[3021149205116494487,727245208162824031,5857918413511104842,3976048914904759768],[5345052956320597674,13646157234632970182,14301344252945457338,12133306750143478541],[311493835118533743,14749283691191176543,15531887074084589450,17664988005144458255],[1851671143595539559,7235392623517278448,15726574631115586338,4196541625833244120],[12958835977485274012,11470768286575198063,1429224968854664410,427573231515910381]]},"quotient_query":{"leaf_elements":[2263817774148805886,1283562747938328109,7855580825475235600,6541706478116307188,12057581684044389467,6661104193494393859,8744012326608945038,13822681942397873562,5213322278694250331,7099558368718023275,14345734266052275583,2517842711578104446,12257880859747084301,16874613533135581234,13291451636646640566,18249782837439726923],"proof":[[1538221612790526824,10290797496667540071,4555875851735325398,16753924705173843199],[6836893423246548496,1517305633074842945,393896070923351382,355492641382164757],[3601374938260752095,3900926734845389122,2091851777715041514,18336781858720233796],[16739509731449277681,13888379393347321926,10304606253479425646,12506644744559860338],[17728599798809944982,14058377049608212668,12281195167347374982,10110927862313872822],[15994715947229826178,15890980832556750559,18326627575980322643,908954496217618611],[3704971099788585426,1195286003698107261,12749286747965493401,12086249104734987946],[9498380322016370724,8994809693600782048,14476514466968581253,12609885109282775340],[4759088223155126783,5328528864793377158,11666820719014218244,1982535929377839859],[11063470947065782141,4446305855682513865,2495457548129388372,5264591522740528750],[4028285032808389437,15203056584526606534,14199047692532685018,2267127747321974636],[17591244510616421979,17473650720994503785,4960477643494006328,10317721157840298879],[8624435458488571383,7138215340682806730,11445941502843820459,12795018817148199295],[15988648638055839073,17404656239809368354,15520624794929361726,11729437325303891248],[14512667982264547609,17249106523672480273,7387264275734061044,1509258668126980827],[7303829015949650780,18196318235894723679,17048752027077948182,10633652492272188363],[4958372076536817658,4811778736283187152,5226019662864543818,17518725354318748021]]},"setup_query":{"leaf_elements":[13445984678198752548,16905635545073401672,2393955294325760656,701666780447855997,3124832802419581183,7675241965712962210,14330055959239736906,4526354386299751489,477056498980962255,319359809692269197,9773591261492979741,6980293214818122069,12267767485798471960,14186841730372821310,9229419185563379618,14178238961631285818,11292197230600353663,18236959585873167607,12761909590431559123,13432379923023957804,5892256219402094117,6332814786831572726,56426086387781695,4017848214276257500,7187398015668928398,4693278919298329703,18239413796896968816,5767207285257552678,8563147377733817463,1537366085660611822,11971757557268221292,16248203240734846477,13410055786261941922,4610848918425939789,12323168422337235606,14701716855727737380,64074395097120154,610717774017779481,6680972716889149703,545287855395589610,12430115411131528391,17631732924383644926,17897909868768082336,352080754772159868,14879954020829597241,7220786586842034405,14993068885075179601,6940388660017844535,6988588173223299544,15777367983782254460,14818425584212714188,17616300394888296546,2041803177164598599,17682742584915873012,16996579214069109097,1333402853520692978,2112011576274835579,14092587883881595927,16404707990368236736,10961980652058262572,7434024676766729522],"proof":[[4344042628481312686,12070503381583649646,11496321263857409866,9364568543124619038],[11357298319784956721,5550184305604217997,6268854538471386608,3268239103113220868],[9953180943625605289,1058372703919404600,15337017505222868115,2280310613712270959],[9272988230668068640,1692880309994430651,911318452235524241,6736647157291458480],[10000537292372977883,17955926298227716312,1436091286464493269,12509650569435493343],[6899748743166019707,3751552451467355203,4333387334502709885,15028554994092351016],[11946698327432936014,17790083659997730490,5764287140493013796,7119702923535534279],[13812620956233378626,6188460873024042776,6670208523477098675,4423395164544115239],[15164172189869135416,13364919544328000751,3797835927158382381,7164417544861662587],[8696966072867701352,13758856309513001143,9211879538778144608,13049996526129924833],[14635002924096478790,2714389122824908302,15611995249557717068,3097733788508036375],[2374424152777114931,8021809601963739161,10303054226405051434,7380709992932050878],[8497984019826155330,2761786194745749357,3399943724703589135,221317149895688166],[2450447687540724237,11418632784568667529,9748833907289493006,9849166311984525002],[1630423200721957586,9358327701048956192,7161953039769585305,13792761587248978356],[14480083425005881320,15642499719937864686,15162956839395616858,16726147093968455939],[11784839653342799892,16093042341241302371,10172015339558518927,12140084199236421839]]},"fri_queries":[{"leaf_elements":[10411227192250944715,13814927350432367197,16740645363735529137,14960495650197080582,16636559867343762014,10689515244057302912,15159534024712664725,12676908671913581482,1337181131274001989,14232772227617067312,16136002701521203201,13968433298122747063,14465539805173494794,17070850991450354911,17658881118049485906,9610759122307729548],"proof":[[14360082987891920793,9376929907646166465,6637347922704752391,5083859051975332950],[6889251867827447259,9079128005325610985,16114439153162964642,8323992500908686537],[17599749376154927221,14347869181185172118,17317427739507800701,8368636216158643132],[114832774181859718,13396971357978666009,2258897108615735311,13838369642341492500],[17156556816548442050,7835930483065387715,9089231849046534925,13137187580298938120],[13313116613930394707,12304652187100434487,12720992078146125057,4484675204882859860],[2151987226246908022,13925841545867928476,12141304231932104958,4840671758389621153],[13443429504340891705,13715248817909555396,12154503038946224355,12384480074117581856],[5984533101153618335,13702221584615611861,10802405702248296620,4624382415722761156],[15281689833688504360,2940498552417335884,13746711403319717994,5555380792704060257],[298209625668970265,6468046828080866273,7087340942697704299,1570021467385182753],[5483079788121675716,13243286440633360609,7418842601164268981,8299164770325595245],[5803653550653876504,15022931865386960980,11700535091039125963,742342098076444190],[17423735773845684644,10781364305585028910,4741937113953705357,9996559428481107602]]},{"leaf_elements":[7713823237757848143,16054289716908721877,17900315625079672330,707471658724468609,17688280539533350794,4996519588649860722,4118796895683382895,6477813002751009901,11747465361056628443,217253068520422704,4190731134278522832,9340598101556696010,11890876129098795686,5494590458126378870,602508988470455267,10386259569177894439],"proof":[[12339178637382179205,14497988573624617606,10100095949741783233,10109837262045844457],[1400062346009924623,12957463219048896723,16694273226714061127,3318942638199096378],[5840678400202248568,8454934505359405922,3414599359655303649,1055450678950583333],[6409217201221874605,4976511717894877260,5636203120202758971,17341279975649256003],[8980791602668205966,5089567392253822744,12764694049292885680,6970739167812267861],[17273792046297506573,3774319267361242903,12111169130817083014,3145703080085957775],[9242835155225653457,11751716753502394575,15181803502765456888,974014609534877848],[241229100982891441,5409723811466727089,15847431942766013202,11270137376623575979],[13902835318658583626,15156244426759827456,17805600169018191045,17590416833830737144],[7264185616771470661,13017878513337843949,17232745165449300226,17237609481025865140],[1896496896329280738,17060017233009461565,8636397705282574411,15875586524508575570]]},{"leaf_elements":[17032964075680530971,12445207156302040104,1102446397145353167,8697255913987021452,12420248387319325346,14775739887168735340,17607318666923332083,8596457394940334663,16333590700496999892,15222650586303589889,1054569287982207739,2780358469472022738,5660043021042600302,11362327778613995726,13557330457956520867,6787715049279547310],"proof":[[17183490461314350196,3526406261768705717,18314284101071465063,8927878464927354793],[10794155772295589170,1576719972271651409,1423007837863087222,17989743463575139011],[15129141879385869069,9076079238088842120,10870089518513373348,10219768604659763957],[6801260820622171984,8201948165244642355,11502027028713040459,5816883991336862675],[5987084182539927923,15375727458168384505,13752707901453500280,11546218765926255325],[2999507100778466129,7874213215006918144,10357081701728210934,16917803560327032990],[8042909117308245532,6557716414995228853,14166119175197219124,848913286620910990],[3131048149049991469,1970056947160111397,16865612428973941074,8441701721341228021]]},{"leaf_elements":[17211225197450597592,10670505244816815117,9400742376092481383,2233611834217736259,12353982089677408866,12481154590696362798,12474257491352158949,9212223527058393290,4715613895644212299,15253473814906568248,2783688037980602805,11383702462841480299,12049907953901728156,5290198099873187416,14633599483057182139,18440050774606372532],"proof":[[6800776481720428811,15526557153001992561,16775562335188601983,17446771963593425381],[2316964387775876513,14606451346115823956,6589656299255467716,3073545257305514242],[17655263478721012687,12671121464173153106,15347220307032463331,5338490924516788407],[13852577120630895262,1880994351232029344,12915120794444027384,6676184784189409198],[16910557630128917127,16100829597702530750,13180827958792118020,14523710155883951802]]},{"leaf_elements":[6158477130126806979,4261416063082602357,11256589118767286774,18261925294652512804,4370554118133581425,16012970566643040109,5104371069793038699,15818356540991775905,995427122234004085,7251926233713299338,11238675935544657073,989165157908038575,10311043537048741403,13652996557489549334,921303485677266788,5511153641742028921],"proof":[[10232198646979596551,4200019506293856082,6742733555046443537,711471976672106095],[13052362528957556876,17233313225687805254,7649592855461115455,15853957615174524693]]},{"leaf_elements":[16459857234331969778,7510494103410846240,17618706697640144332,17308129413693904610],"proof":[[1991287736843650671,2777827374600143465,15658827494031667277,8816693819394133828]]}]},{"witness_query":{"leaf_elements":[558283320709331576,3309768656721394978,12179892643036624491,17732814800253650596,8454974503658373429,12257293680913746456,17350871301140129904,14723309156038597879,11355508300500066782,8323304793612235842,10520818758454314132,9295547364181948731,9374930466273948470,14819949610229546276,4612853270843964799,15465503592069283034,7138249514158801503,8652577486497315753,16100437192859610918,11503371892610936655,17454115071946331415,318748009421614555,9628470551600887760,4957524493839642675,15823520460169909324,17668519756370229485,17469288517053514653,12239141187723551071,12007784442753399300,926613870961917350,11139636445828288474,4273265946718227450,8410497288871827784,1115268758511804333,14281589667941894749,2768051975979699463,13500577071387712283,8409742979743809344,7732090213602011819,6997691696128885789,16911989254745273869,11564517575004330005,15064351782002134837,1674723813519646017,8528820309683615103,10125096944336481322,7774037552214436074,18137670393024143415,10624008799675743316,7178316803343992378,15937400004854262493,6124984692804168732,18406759297008093316,12708201650202706723,15444745156150015380,700588065498072394,2912057449300419566,4255759708547993074,9508063050379548403,9743236222896790854,15213003119596260592,1779482358648151120,6894845843965176101,3251316549589260021,13602406890205792880,6163916654371819571,15399776093353345059,12388666186226547821,7754006549094563418,14640278894742302513,13991014184004250549,6091933624898379178,4843483958924636201,7735297600415935980,7436482701527698530,15022910276543728590,16741729425925506490,4997230271120651879,7304330006909564439,60407918503564198,15383445064994983396,8757854260508506424,17503252052666649882,16594713326508237795,8332352551883529877,2010799887285847596,8131134341489501601,14174132009697523013,9086931856043623571,17083979507388854078,4824785244589645113,8090001302990157484,16313685428209619853,6952149360859773065,5277816474547670946,8067356125471065152,18238891399577561733,6846117503168459676,18419101360902876564,9544306144890771996,16950730052982051173,10334071496293700290,14067290922664058660,12633675363147170346,5050374704147605289,11664021742482586435,10210934379118488420,4639794673796358127,15658228242410912048,6625846303078853597,6448017820927138760,15792060073046743253,1661789344179269887,7851479916193428790,14779992905539677808,12336142952385513249,14302694605908765225,7605099161176340262,12870509944657480602,13636267022390560716,5957608594604179698,6111647755322571509,721616491706903062,9867706136866315055,2967414698968925761,16727289892179553297,9594652161764416727,18394920162715364475,12332724639997453578,17970001251277361663,5968134694529515447],"proof":[[18017731294645174232,10562147168126769521,14716816916226039250,6491338992026335014],[6325352149689496952,6389412835504231053,8752444815184797330,2742729007728036436],[10850323131074892041,15439891309168834686,17585672214254417364,11572460873936183581],[14225150088494771017,16192203100809818250,16574434306163845996,10795436503440549499],[10206386807571039369,9134891090520530494,6853019111389262541,529622068218623226],[10516094970026983092,1139396130409035467,10654744991077180571,1091192188282915073],[12043016902593601826,16135671515059895832,12718072810976055994,11096001969441654267],[13637860610938880820,13980891621676961929,7448317077741576994,10603587770480063952],[3830761087908856393,6644038581387879029,5631708997505350886,8946400898186080238],[6188521596702884501,7620839502875725506,9909680861166737556,5321086993637145973],[13720561694459289574,10437582576293562163,10393219952653486184,5343727439905770436],[3067667722066505648,7076417921105813292,15304319363383134908,13148703451650722047],[3834921506787009265,7003796861403075634,18405183306692262836,13346076697670714648],[9445848919268158601,18041282051959700338,10478092424191022164,3045507064185522693],[5596848992299019380,6720598110190826469,15265466511197144388,4051625334336743747],[3464193732310876390,1928857259286490489,9063741777299508086,1791793890237091125],[3942523976666198938,13291394958920426438,566874857732920564,10882708277828489182]]},"stage_2_query":{"leaf_elements":[10686461674026895997,2940594110848965523,15266196705876125638,9127397860913735539,17448696767725943375,3603269335141930114,3242489064875513789,780854402167289154,16745647276730010510,16878174693544648792,26714252127619035,17409889030230647724,15150799045324051161,3804104830692100690],"proof":[[6457009692186092669,10979173896380517556,5774842855380062592,16243614451017775436],[15220140095285925064,13635177982620212171,12305862713040992551,5890713029266119107],[3326029639675094927,15433648211905089979,16064479660945507056,18358519483018933688],[9188504455916463842,5662053211371335960,6143464593512916136,15417080822675928341],[2000486219963912753,11556917380117479431,919641490235834319,7982344562967876087],[2701068666180061828,3290801890568862572,18296280514388299553,14021211327608421045],[17981110166546150528,14824583651148004015,968688292325171276,9226844245264598076],[14843621123286121005,14463980632270601526,12867183921286435686,15184459647795940077],[5893702092141454813,4508114024306138567,3289545893683973535,490935841570040708],[5867837836803206959,8380191427881688805,13835610604648847873,13957934544452227659],[15851217560679796574,7813807251224565786,10878387713577521180,3383810832051009181],[16381259481482315298,6773328405908235858,4901384793476525233,6578822259705929698],[6392879721440195432,2855246642637606680,17833658666926072338,8214334024503476403],[12889162761126781829,1310956540345725392,17792377594026609158,3892431255966156949],[3852660434784039864,15683603138794094952,3789832319253917143,4443988515009619617],[3249812918745523242,16703535042615177192,13644125087194464866,12612091742313138684],[14399815260597414518,13226723793920981694,8384738828565054317,14222265326803929986]]},"quotient_query":{"leaf_elements":[5461842050587663024,919668250943323693,11199188691978620581,1253331894770346710,15219240564797795248,13854020579029682620,14492967913254565285,3536056455816844393,10446886717281533338,6116793778863889434,2468445604449953553,277607581240141859,5324759425446145709,7588184543014439152,822150707018580966,3664863956246164589],"proof":[[7541127902270697289,17302833684286761808,5194489780512154774,1429545047269355351],[6193175497942293701,6242161722090948664,7386296726482694704,14839917208996884279],[7933454630967182969,3216474849353431363,15636149765345723069,12287122954009818937],[8920660911811500333,14589801210853073522,16397585864122532366,10744637442044554467],[14102958837063849401,13736871468166995783,9328931243179535982,2180580604953274020],[4995168462244576976,2760965182053865983,10854367946128721788,16842504900229529257],[2902320018753739182,1516186639956170714,16353348931269351940,248149391473266152],[17468909794654322940,1032945007712301910,5223512334036233408,17821621849141005365],[877878167528179962,3453717700111480035,10999424369841413902,3025335586616534734],[5669892322068543217,8460703532594279112,4099710112052284152,6820362911669810744],[18077709373837416219,6463610337079561075,15051273244201518226,12968585236595864932],[5142253793536190088,15607903666522418734,9454898109916705059,9629565491829123890],[8879733724315446144,7867735496548705723,2018865747835537917,7567850883985773689],[15193403258948895218,4615111547861757705,12478426347697179431,15420277401788125240],[1943260810119674783,14974960987795274097,9901464148264458140,12428164039213278272],[18115898199283878517,11957413541732163411,17182197055580208319,2743465526883226936],[11869766860304978197,5632731256340496329,11092129394290368152,13561830409124997230]]},"setup_query":{"leaf_elements":[3202667602770774485,870282699875162248,9381740334849267779,16472673490986056525,1707660656757236727,7383425980108363976,13726092304402804688,18155499099337106683,9234019772078859837,7674505461575622804,605175873070408330,64256345768444798,7774068034695217432,5340824410580432775,11194137505439645280,14533037699634361535,6183008143890926767,13664731549347111559,10470006656536731024,3398027112945222313,1727396871595621475,4760865767474389926,15125060571627716154,16064145218143966433,10750491839541209185,2042956783613006709,7819385879293765663,18342919639545963518,1657986392271687231,18096503679082608878,5822301199028112304,5607799872058249968,9438340027398001359,10285548004077869125,9258367539952965775,8052420577367208434,14083944749366321021,10881747536112561030,15848982308412489937,7629932404874740005,16292046248657771902,16234781316486795611,15166118152153647615,3182654011650154175,1967910379211155768,9994228303342128942,16265328850407098331,5447764492863827779,16456594723724410185,6515147335941456498,14759170406002721248,6133405230618705441,87059832774033617,6308399370007189232,3227911518807812099,2782201577414985593,651122141974402473,135719323901069528,14428247741806249133,3008652184050483945,424700126364724657],"proof":[[3461255707628049746,87975223582411718,15026185985148364423,11288040057710748743],[6663903505132260829,17818792125941112131,2330337347985044408,11123674439958708379],[876718018719509106,15109543050343243253,3061488466747522255,7835725335110509186],[1683559519177354228,12559897609531445135,18280563422322497056,3599238907927424941],[12210160587682228392,6847240098326374858,17694256656469602358,4208589497682801146],[13775420698458837507,11241595926498529506,14947051414042697939,14390544491948513534],[11872003915768753240,17557876268702576574,12615893759733050498,6473512700493841417],[8975968421610076359,10483757491795030395,12349780691602180075,1038104904637677668],[15247548829223019375,18261459715517696532,11919040193131549991,4085266865144826664],[1858860219013723044,16888317182224655210,213043180357819224,619004830277574643],[14285441373867625443,17131790092335631441,2211663461193376977,687794374904093616],[13646054826614424735,5671839437327235599,5084791786196898511,7807526321012439093],[14040572441306508343,5350655568521915454,12492448959078827202,2145916859323750679],[8751215698567475605,9179740260669195336,6051832888812835827,9363702720980344403],[1623231229060051561,7018944666942858978,1020371431678794831,9059560798639284614],[12406973806187839388,11131912207763281661,15043864307190857353,14301987458125796205],[10442513145732489562,3087011686077301239,3586866941972424375,11269799207874704610]]},"fri_queries":[{"leaf_elements":[12756548008008515137,3445687201844551957,5378669156339248706,5142883155070308287,10479153892776920015,14650557622481034100,11834681053463703373,5829781052777339830,1406490147877328740,14837146372189768797,7568269930266959513,17015829452940021340,2930197756059055908,13622389317095859181,9473854970530551675,11913241409480314200],"proof":[[12340972716155056214,8220329326712578086,17911403186314229675,5891127226796656005],[977233308091003267,1759741234275741279,15479673289118918692,17510937730928400753],[7979309365478185362,17340679207266283720,9383571240846956225,6093391543011922466],[6691300186298082918,8593499303174439315,14142649135804748073,16853196326676700182],[386628738556665932,8347588191017066638,4769628860860991999,845136666881525260],[17209090537608174977,13468565260929470521,1007430219461484452,10169912110595848865],[2007151342687255025,16175291563762160434,370724633164273761,12308708460310094732],[16527435835379722043,58073535898940583,13740633055024341754,7299061945032291573],[17946033574197736813,12190834997117284704,2652645967319107426,9108650068280435191],[17007885105215459820,15604509351912582477,10050391345576506686,18440146029097026375],[13350604473039569750,16309443316179494529,15848530835873567035,2327983899433517123],[12943188864155781997,16991497434559276134,3795113457699371766,8580471142384635628],[13841838802058043823,1434599492448253578,8667371724338120823,4219684573489645965],[12106152019686822556,11116581897165494889,6833560166593138529,10567548675515000298]]},{"leaf_elements":[4875600428655325967,11147995130939726844,11480325473851006911,10306576877910075975,3169611796235116497,1306287291004464862,17547122542916749695,504837738114926501,9895356243443575229,10175781980357884979,3960094571329186096,11292603611546321927,17577461823773576918,1569068652689738069,8460711567191270498,4416707692529003238],"proof":[[1616132522261461380,4535135319407238303,8753686436956626369,4433928847972317149],[5919568480082888104,13365225700807526334,419920481140937088,8754612503498109009],[5352841972218568754,3299301193709015937,13378488600620116307,11202457300283129172],[7966911397214890065,6233207436113365494,157277711562872577,9070753835022672140],[7840942612240782709,13844299467315111025,6997135913696194082,11033817691352759621],[12219729401436502561,10640328199889761402,5483758122688041034,1281715457792038247],[11462808525628426569,13155366360542697743,7688946170550281399,5142979768785481485],[15013661217239217818,14306496990211452237,8432694642766615855,10705176117091213682],[3398899105769812087,1350697535144288308,4279845617647701445,8181771522659534586],[32749693312285115,8653665072879707838,3109139387283662892,12578756071688281238],[12910427101055863920,7165108278491432904,17369818687029612694,17545733887073658377]]},{"leaf_elements":[15159741424016203954,9747830302555225481,7994485695219493870,5380430486599947538,1092765290863329255,7591476064242560800,6677780705469824,1814997923884764025,5302534509487377511,7862825164886712201,10859107455868184143,1211958369274328122,15849166370361383549,7982321617623125767,17167374738136584923,8949757249976022554],"proof":[[9425998268220701753,7853537568404133466,16709523981374784686,14657285076786663602],[6905640223723837087,18101284631154353901,809349702660429979,1590350260460040138],[15730703604508747992,2960145563664147381,10315818643865735008,8679931073617400703],[16389124147068032186,14754544536473429998,4283446036760187486,14925131010197320372],[6705163738144453865,861814138987321145,15181876630229042117,3218705933984077994],[15213695891537695126,15470160174951779239,17592430183886500278,12260913880454237830],[15938354304025568959,7671470041495145016,13848100170362921877,859960753523824487],[2449852488706507627,17273581230310163537,4184276826551998489,872693459153727047]]},{"leaf_elements":[13830223649062148713,5657140776033080977,5502771625747762058,8164611915566879262,16669039216596934372,14335850112460840465,14430764368696223253,14016109921322393010,11487163065577348552,14606892395191920134,12274530650529545030,18416276380651789766,11926728721557698655,1357553965829838105,11229591697413810469,4510702172632325432],"proof":[[15246628522928941748,11892271063089236529,9210167337291470233,14191508332641581960],[16007703739389381900,9966166217335324009,7135874728809128127,7431615927746726465],[5887378755044142354,119543580796327487,9211550566509887016,2314123886476621870],[4319336480678551305,2320980951274577721,15346455002289794426,18205792983752900303],[2336765532983792032,4679903953870096367,12614027254750951398,5281053139684471222]]},{"leaf_elements":[15416692140361536028,13980477615593230586,7036288953224824708,17960302319907952492,7488007983602754068,11570099532161231554,5745126091438125890,5095511741364403636,5076481152067044133,12900334653223609383,7295446033150383973,14086558454513278422,1074982066452436924,13478328596284324083,8146344620011464983,4004632833775505299],"proof":[[11918937497913422057,7396628654229298974,16524658081743319159,12008402254097590601],[12837809978461060891,7938450809206341757,1281850120845547861,8719045238256605111]]},{"leaf_elements":[17434263629900827529,6536087707841988489,4024980068851268940,12455111973068195681],"proof":[[15792960275528092745,596035238998372857,3580376097667487158,6894328176394571706]]}]},{"witness_query":{"leaf_elements":[6237328780831173247,12975683411074389881,6797641936964885850,12084575058020880616,1423321498793456539,5174381586924837017,18152676353806901130,4025624573511690451,10077959669480011522,2290146011131306157,3696748693263906136,13209222187684991947,7506134918289789217,11592589989967258070,13472578732932683556,12506315337973816650,12573028912237279387,12351914163825807464,12162215824754206547,7091885668836169102,16094489620904353888,3638987262720539065,8737047267501038884,10952877953985706016,10759632508227353792,10116998219705509071,12722591277736980542,316938902003958892,2586303744219561163,4163064931878062997,7088373260291460633,15573818925583313472,617866168715935648,8210344190734004985,11769063257931684568,4943488410705744255,12028425479115233978,5765667717386377434,10236973704753189207,18240406900579954056,10784056516081675668,17575658750041129275,11921293076578786711,16673768040681183763,11861468704764544795,9986372901421085945,17254601598178873870,4522241824298619535,13891161204029026260,8574309824275713668,16659783897338742958,12062014549729557810,11588298521101674215,17312475576088980419,10264441439680698417,15327016050807888930,8682835543396152908,4937450390715407307,3904425339153961634,15086761088494312991,7497913521377359836,15570967900412756134,8712172651564607999,4525724088321446637,7761450027949987311,11006006440395296397,10578630822517954104,12786717693594272219,229260383748880844,2413304925054929075,10243517853012239336,3747746065082594237,5228606686950269418,4214127731820317743,2013860893749083045,17857684916605281195,14121866137764845696,2564867087140282601,17403957020837494959,5115636022893461754,4336649276640269239,4146439784936822359,9827141363203096364,10975683715574637487,6995713346525370446,7886290899400650546,1353380003057152110,4219050510205842793,14821418074499207604,17601844394290718834,8390994097946089620,8469010876519459172,13089195867574573965,12392751477990757092,13516454233814989618,3997934812393034563,14805527793209875583,4461591312496454202,12783553135522729291,12229247329147455089,1345832651311483313,12897658647779443192,7527061014283408366,661745386227703169,3668317322345467695,8339294637192614815,7544132786220956947,13069485130285818979,16224862946713026685,17437032423287605977,979793983870077934,4818363903191097160,2005872994978076011,9506708376598477457,14625242696897177521,17512616095632491153,15934267531569173283,15650666565289067644,16826513227041176925,14379538197827185026,4751103160700106011,3562593875367930175,6424221516313606252,6626170864725584584,7726034258332319516,16929951911031939951,1948830653082776381,9963766195895715366,3495254097726475981,14676690523657590029,774314136563111932],"proof":[[9356458789440644736,8893465580746767449,2152601957870007106,14077090198147798394],[8040707284051011173,10995340488414727933,18286013542767163973,6309728426671001632],[9249498936017788094,17256479391015181387,10364614766242159553,468660122248850599],[15368049280397437902,14492668725701504178,11822411075178628695,6729527305535046227],[8767985171069820601,16450659043171104088,8620571955088607888,7866276372728067471],[6928797023873038509,13226218394046690147,11102341322340960747,12769360752956802664],[15404680945040306405,4656859123221189856,7742694213854688433,12421230272713256411],[12744093412234126000,14607386467006152952,1751840447599056530,11673984647356545171],[7540253737971843496,5861595601803183735,16374276424514330822,12952533724893270461],[9714102337202304507,6847406131799790883,4825519105603708592,9150933969036817739],[10383044437351111671,18410828192840623067,16123208799433280853,2773323709101057037],[3740798998044185313,946768207063815525,7861085070087520043,11598382710336759293],[1548779429380981742,12113871792256574000,384061768869250469,7001362574855678941],[10349152223799559519,14879636191345914859,11926562006421970764,4646927335624622173],[11257753459099628554,5880094778881315897,1868560576580607412,16645910301278561540],[2942052796838314317,6257816360227137506,18195367374523064612,15538261544801090737],[15295161104420988,17938364994123593739,8985416604031407303,1606132511160417243]]},"stage_2_query":{"leaf_elements":[7682864517315489539,10310485354425383776,17210669778659051133,15296426860080258314,11156753866771627157,17316932602537145186,2377037401585360552,1646397635461026301,889418039732320299,12220183309270223696,5414468888723560620,17806636654521242476,15486306212520389249,5917854548204937708],"proof":[[1314536923345396839,11685691358115134883,3702723626299276598,18020097868532677644],[9394352675577442573,10193108057704680973,15880703444450132671,4792228417974993344],[11394048017384992218,8155279308586156766,13370170578283814121,5220805131514697582],[7906541067307669666,981790002619695508,16165765626715971552,11991363513730434200],[14419516458392797242,16257561087478157337,12764642287662442938,2069450495216039766],[17829402955464524958,14467004981158091378,4162095839858657524,15909721957659921901],[14936640717757639579,18145957874519622989,2513528685515710220,12136062540403123327],[2116027452418032356,15420489699769006585,8432408184572554097,15173056305099472345],[14662809756877691443,17449129863674893879,14889448459462547591,3329580006937743702],[8482620399079215248,4999878791230457132,4238676840456063636,16629664038067974942],[14348452055094515055,11945415199334977924,9084749524961076607,18322777731059367204],[11370379569600496082,9365487708529864181,5816994365870434190,10196258096555262420],[9045693128659533992,7685944290087017087,8226904095664968023,16716150241032089274],[6241806792016722378,13391845311767127953,14849773034207014523,12680630194568522479],[1668061312442925073,11909580667910065475,2539819898741397824,4964030245645306789],[1114130513216689362,4674911322402981587,11473754712734681222,2217764154632063992],[8371627387491774703,16494694681229176306,13610663165211813966,7496639466667253107]]},"quotient_query":{"leaf_elements":[11572778656657273943,2532398647459132196,18192892725619915963,1388785806481279328,693870107395573451,3780770164335512681,14031858106698945165,169280800422275170,12456133731496981553,995431979777190540,17190278480879131881,4410533924124972062,6964951733752442874,8328808325980139552,7789703939722634821,2567191918183144042],"proof":[[8924622651907995566,8032545994915722675,4449655042023592694,7660291358195829204],[11599405642944694973,13930904396483644452,4014033122624328164,299236513695251662],[1413470380527655676,10342361618800664654,4974268402390503159,17063881526499248239],[8768879354970401971,2718199750230192715,8970070071597137159,1494258941289253723],[15518082051447566339,9003170449313201898,3729529487581089272,5943834144956946697],[10659430484816602675,13246725887465367639,11585185427384240008,5285101909383878805],[17306664424003998658,18061064391448278562,16176062983622796406,17451193481868276977],[7413634117999157136,4763788589162362552,5486790714771723915,12487661588071529532],[3554998332752887214,5036255284918281472,8863441691448103090,9946092763114362118],[2182742789353625402,357246033967020986,5692699824388684083,11760142888556232429],[510059499480421218,16768851943854615906,2454043598708320024,8054331103982180713],[5255690083110285123,7691448152338367926,107368380715660975,4427506049036794600],[73143747383182146,15168085125424188412,2242778651201911374,7961988146055736099],[11453293226743389601,17434315561654222693,12906202945192332516,4780924640891712859],[16686863144467863441,5831845721997019198,16131418743802946003,4612270101246390145],[2454497894454286786,7356074563511004826,1002817073770042942,16236028388469816400],[5245813457831815284,9443137342874716850,11166982830265576811,11123808540248760442]]},"setup_query":{"leaf_elements":[5002165543529370875,4310732412195687981,13176730726646069046,5431194936152798305,5783240294262272328,2408111477826680501,15585609274279325641,11620296905936387392,1572984091584095180,12896850790921712818,8755442836740794625,15800083958511241479,18372131960959748988,4333003047045464458,7884053989148138741,2509311890137773924,3255067996930911286,3183298497096157467,654008248698901951,2388869661913256394,588270321389389133,18336601468905449604,7715647259149606217,3615574796174993233,6350199396285344174,15966819181232706880,12849271627925174016,468441918121101648,18122966860855213637,16011917187907387833,4534723389576297705,2583379148159651941,8251186271098209281,1274935991416981810,10590347075171122774,3152532708052558710,16590041217883622109,1532878177088768567,7517959191518674320,6059585881397802369,13071276602472748578,12577345736064269415,14166478564411532982,11810441635596637965,3198225512099514490,7104985186191819973,7710740694160985720,10974876308776185426,11060881003056402885,10990008142954178516,2298313478906665159,2609235217543067277,13018195697220313571,3062944244426171787,2311126812338533929,18100152022851653796,2103052729480166559,13652420712401016712,1548656976511708923,13349121946672504275,17708759954941495327],"proof":[[16238592539361773261,15611626152646427934,15007834124884900215,16625396212350620289],[1247668292841638709,18375042503489861525,1726376366880042845,17711972216790634043],[4958841036707240344,12345642133443744350,2085319820253669311,2613846207832608527],[8542303059826889113,12701299821985620764,5737835457454410156,2584889849716910878],[15605551328103439813,8980753209310246978,5211623351640565933,17505755612269596362],[9992865747294580598,16512071698573843387,17943201850702533188,14670174696872959346],[4462863504135053435,17468560368356643154,15692622919210797847,17514955280449676115],[3857181700185080686,2016698977360757339,1987937283024124101,8246511930669650293],[9555982565097939644,15364418402945705824,14379087862687495210,18236983227764099874],[3060063558328963547,10881750665474448973,10223856100761599228,12330572325418881084],[18139272710769469925,16810493051589278313,11492583065436440853,1724799734880116975],[13961448587515746825,7109732406782843367,9904965253474762161,7808095543218561085],[10684126805087759082,16914290274296546390,1629714946319017584,6447752136567410396],[14488708194733311326,13657773637320442843,7847784172466739589,16384114067715361650],[3139423236104351465,3260844849575232415,8414065816897041083,2904317146059360956],[14072742919855166440,18139907950664524020,7637422478612173019,16528262209851407403],[5854712857385676145,3499886231386273490,15046823250291359011,15931408819460312547]]},"fri_queries":[{"leaf_elements":[11047906898151511534,17672798588418734133,623955124560226415,17558857697800800258,14454488349971424693,4354001543521385802,2938659399385035507,2868519604710262315,3592623111858244417,8280039082394429075,8470043055697064545,11284274533903544449,2274650374311813346,2790909849951940048,6886309407087108484,681036325954742102],"proof":[[16920647878214609560,341049136224704954,4322795807141129247,9847524587613597960],[16520232667918736683,12094788276571705067,15200306573098875231,17173270341680463937],[11102458517438156404,2006947636614363288,1333850811618291409,5267558926007585901],[1279421246598828937,15081514550407102605,2298981625571315657,12530768788717606773],[4547283893313969949,8370036506189283032,3665507253274255791,17965001608726908287],[10556580738057075647,10951201124753166212,4483299188470580831,10526663989355682784],[2750252009517306964,12366500337273044239,18411929820883135688,2017399686115568522],[14372827251255077823,1068125917188377934,507335756139001087,14578873355090833000],[12933148741888530373,10730250266587807100,1242074640013595879,4958401219343055866],[14625966295213936190,14243784263874259923,1374665300270206999,9574151869452471727],[4018531189800440873,7407035383730608944,13828022859658450636,7758736247926522744],[12722608317380318525,6210530408924071508,14758202548531219537,13703313347489284085],[12854998652508639133,16340326036873861324,10051905703298000617,16251566537744388765],[15627559939898052776,1635631378463612897,18125194970116636895,4545529434669902876]]},{"leaf_elements":[17882472420177200186,15512585222388429759,1313161606290181714,9676466739184098520,3007969446533313838,2065915822897812336,4582553650927725890,14252184499534782268,3412999760667271474,8818394829752289282,2786100907609027616,10804895533250257408,17109589826644175713,7263181695872538936,15299295669440987591,11528906675203832251],"proof":[[5042340914192678758,13430063582883435231,7369946487772006051,17684013939620465181],[3890944499360562598,4361216001869474159,12100130763943677224,210727904825022121],[7866033203632857180,15544887778586597106,758603255001159823,2394794183360178804],[1752803999681511560,1398388772487162041,4895079686338941769,14338592563260775196],[14962857173610303436,9793972235689550636,2692421939422450110,2330311979938939487],[4440420663441832342,12160568549292576248,2845636615102139689,10850989223896152467],[6311286435676543652,11394874621160295503,5106306621822460882,4442311572989098744],[3544849068297969212,1615123061929779256,8398442747312164352,5690562466399194827],[4976727874251774955,17630469882718083991,15736553993143772011,2474471562205105312],[10761746833620631175,7442424478276786154,4125893156910955871,2972297572972663113],[15686906172524153271,17664910767386129714,17403540000200297614,12452874820109152372]]},{"leaf_elements":[10132138481213183112,16414233427611483400,12664767847615697395,8964008725618464393,7136648657696830993,10740335469426642451,13802986157157499924,17911140126283888667,7982418281243516752,2059753935760323813,8473459341952376459,7978693159511024903,9758727984777289270,537496770059491681,9023956266012366189,16324880051619900506],"proof":[[12045552390972931503,14985416080700908351,3429717422341528164,11392215818890956023],[1649883603280559658,13229408099229370168,13096691461299731413,14225773935131536028],[14251160773327355311,2694941932508466135,2772354004468029830,2605810766839249966],[13730300156211772005,10463951095717384535,10853240056721103451,16399780042219334835],[18352161521609261463,17532404331756845024,5489728041374019403,5242931245275706756],[6680549630337487205,1895729354003842795,10112809542408608771,15019007375863900521],[11440879374969031372,6915133710765686340,1915368071249806053,886695474846582639],[5523907785475248652,3166246084361746153,2159702641699610276,3498260783230170876]]},{"leaf_elements":[4363447196646771126,525978973583724473,1796258762060497869,1934090655843173575,5539293236849065276,2583294221936809481,10944457047773654254,4619100168786678690,15004090587114645811,9933257813467005467,2595267788694350272,10538317537656106235,10698666008575905744,14208507859592708922,16069499420161342920,4909108920552141829],"proof":[[6935823776991069002,2485812047719441304,7086282231791660915,1397863647767107127],[6104618664508159181,15230365454561974201,11688301879625631765,15871780904838701536],[9963753011084196238,8585498000439443883,7250676064983155572,2276118228269659978],[11306657369024263918,12352610859681133630,17299727235116685971,5253608401671406381],[16440547194406030067,9955826339499974621,2503879737901415361,5839109538524220096]]},{"leaf_elements":[2528378738999900097,6358073797909638753,10469147047163600889,2287172435524234355,977657469530365097,7344513821522498302,15656099275370747797,7636291150115073941,6514261132974863427,1506043436585391432,9148472639083753811,4562609251533617387,4761643013981821248,1556178646669380461,10739886059076825760,17785551603509748857],"proof":[[2231205557360459084,3296636129005050851,5429869489359525330,18001376866137716437],[13058248677568172091,4479823077234043161,11121505541274771803,3693203079723191738]]},{"leaf_elements":[3678995532376285998,1844611735951945699,16399226379140177394,80865662779287227],"proof":[[5422537062485511263,2091001410740989427,11412251066733544696,4170914066569497080]]}]},{"witness_query":{"leaf_elements":[4412797744865870250,16685678594347377722,6363890497074688670,252233628894905068,10158431210422812023,15076313183103739170,2897616762447338546,4929308173567585224,17861328018434825333,13625271949366063621,4611463860478648026,15305666254100807337,6001578266631875500,16933715633742780895,6554834828630323688,15601447026927588575,17607380284144069520,18186062758934524146,5312899847518375381,801101759870489894,11704965495569914603,14524340127406127696,10887119428563251845,9953004233044271004,2603085495963473572,3293818091685470469,12482684757822826027,3075043077577448240,15067003361157706445,10577409376523381669,12004468374127303984,2184429095392433697,8337979851166146312,5434098483915908120,1331976277277836133,10592722493106381195,5756345428172004865,3347366507669378766,8526972694584416272,5666922209981269996,1550084950932545795,5813061362234363099,7387255603409246641,2408765823143030739,9165654280808599326,11282755607316276886,8540441402420688217,14726687218667236964,4921529974384342697,1042715387436107982,9726727040022367176,17633685529191246476,3134859128534952793,8317834313269738577,14877587686994968581,14775456668033321497,15886581700737952894,9199228249110811170,5690223856578290842,17294847023558967205,1104336062392704663,7829961109206263619,11621268544950271310,12614903970816557061,16729211764272169366,17921828509052781651,7988334228351481463,13860276535576468041,18325890810981707271,11602941282633184716,17363687137173033488,16826727659628703818,17371534653574558229,12790787199855942566,11667330329274492185,200263164040587443,2769369858800115343,4599029475776455558,6118578343641742405,9065020000655704440,17050326960339355365,17795314267264196144,15512888965631827650,9124158580974807653,11285737298234261191,1621893342886017609,4778495956013444232,13095332526283012033,9584495747042130593,5392649128454416757,17497201624563041379,4218864910407721657,12496035661851310264,11729458637046224253,17514949790544156544,10437913726008622219,8478124245943138615,15972646255042227476,11207797796914639756,5979141522290866414,8519613508313372803,9436163848419791458,10781242116880359975,10872290335962480910,13027153100657128930,9069457999642831202,17854160866310533203,18095566308651692901,13819304944128910301,12985789110968318003,2509309799857447338,12746496631430487216,2345762657434452955,13904484453087724328,9129870739989853625,12829832644565105033,6508894697807792590,7058626811539726835,7541444671409794953,5683508759057746021,6805655860146604925,7738491972299896796,14431199176117642272,16755751003445861765,12037548787284034644,17783857319940365249,11725802393545600429,11681342590983873717,17648387837076166006,12273806975648703480,4090912949883508094],"proof":[[12262099321766611281,10685633735790960237,17084429482916430811,5693991407468119975],[16702361572263871814,15702274973170961295,17190966194888114262,9461735618726980349],[18258251170641876022,7705712155295051887,5813608624169304411,4355199991522729838],[7193025890350835548,12517711094469077400,9786780599182431266,15644891047022268225],[54593387192503237,6601457826834798178,4334345929062132968,9990762989917947234],[10564379675984188912,11346965245275888479,10895890648540588491,5286552333865144944],[566147815460567607,1029613104095189935,848796524939500768,1196398601817480445],[3808155657394637984,2430012366463268985,10633876566464719661,6967668686921609867],[17584568115791130981,11332082696305051356,9805155238629339485,17526558290935902994],[7086231464305696966,15532241063796306446,7880050301145741450,3981974702729966065],[11746820281130694092,8415889500046293894,14434862944825391212,3510383256699242738],[5928614522956488974,13612083189046855343,14826719307349584883,11514066890934041124],[10934165168381760996,15222057404755995168,6767043813973942585,10077588282301563864],[6378266947830741747,13180205479700662698,7429716045624389724,13156378656236804104],[13394703149996491537,12853665841341050333,9023226813503778137,8800371600795086709],[879347377745451181,8108356877829843793,3165329137865426209,16785548039980130513],[1515531368785806118,12574507258131797238,4478339747602551492,2855719036921307901]]},"stage_2_query":{"leaf_elements":[14943248824214571180,11256634852874234387,13934547678383980719,9867973262499120948,11479049185114437754,18224060250550623583,16757936907561640836,5272219426645856887,3466731518685593773,6916118910703366337,856803405038575640,12778324172909131154,2910739245563872863,3358167117310514833],"proof":[[780362265336974065,2148424923373951500,18200884731701796245,2335787426511231668],[10334932129061001033,10565581209598935612,11896804000285650494,5774961649921844775],[2931137328839257828,8318227872657813965,11714887679165205155,8908079804824608406],[5768821666897322744,6712312004716530984,2775507947912954917,11732015512900345682],[174543322306244493,892193894177584235,8514144289756134894,2807462761313231106],[13139197545746907908,4234628479992777159,8339245169134313030,2033067047202211603],[3942165024353067077,13579403019663860651,17629780339744326268,15458218124957923909],[2198279875317347987,17442409478645526113,6783686873149454215,18054163412734460468],[10124048602929242207,3284911271827601866,8443571476029589946,16763921346232902624],[14496448773623860196,13176634370904429437,11042777519143103303,12141415467072153459],[11968506388293468531,3448420278979205531,5512014809803521806,17197734103626183443],[1125833519746864271,13301867501173341720,12632396406957898816,10910491693832548477],[6556832673403202262,2077914279544797964,11681193504758044112,1631628187470869650],[8744350414019888516,6121494885787062802,14787714206036982207,3932700717556007140],[11045510105229525685,13715329067313070064,2334091295889433730,11956847446373181191],[1851671143595539559,7235392623517278448,15726574631115586338,4196541625833244120],[12958835977485274012,11470768286575198063,1429224968854664410,427573231515910381]]},"quotient_query":{"leaf_elements":[15103556118868780072,17047916803141222107,14711835067770499521,15406908377009113314,13910986715928705621,2589704774787640274,11258673163854099217,10520527994073289605,15527840354705906347,3952389696550573449,7978125918879870452,10447190233482654185,376361434907888496,10606065508371114811,3859253373988489893,14215920760796655059],"proof":[[10326445796613226937,16041114097847099335,17645046136087400086,14019715705997186357],[18117594160964999458,1609180093203304592,404678064253740866,9911926451824349744],[2999747226767540789,3828573122150446850,1614319991774896459,617684173189604372],[17146776781941315149,11870918281693516912,4300143076578501318,12677551316734300216],[17636903014829044091,12224276844739108407,17662649760345202673,17307116655657128386],[7687936836732339542,11907082534983039844,15659859223545591274,11125829005708496691],[14338743752199937067,7857465221284348618,8772282975894568519,7906916327850269476],[12857874476044781657,3780901714921359455,35308255619851420,13564618807031566789],[2261690998572757480,341367692198509992,3706119454473722484,8410259187871165119],[15874345662826067667,3002884038092443732,10075811150065144279,15445137327697355511],[9507927347348251682,2886457268346753600,10498723333455436100,15711131067295770402],[2485376937356426860,7284771628557308233,16510434943746490714,4626818157885739938],[413941655176587696,5046123555640750727,5966466452769922698,9442750170115047487],[2635212370806043804,3325709944140162785,18437200068194341902,14838015793734183755],[13045807424338792356,2150671311015446784,8763392805987891642,875503887516615053],[7303829015949650780,18196318235894723679,17048752027077948182,10633652492272188363],[4958372076536817658,4811778736283187152,5226019662864543818,17518725354318748021]]},"setup_query":{"leaf_elements":[3075532617250848563,9515559893970039875,8570648513556474306,11676901579083839137,67659552659137057,17145266626805471826,7496144939664978859,8510046836298602428,6174406977907466137,11200615673494091684,8365004427499081417,5660075804549271383,18206106386962957843,10957163966302946534,1698641757349246692,14141691386996520574,15449143960052073361,16012342307547220669,10846930133035536168,6931240176154467664,15623800276072445635,14380776854779587613,18242691218905338615,4613781120191772332,3166248460962639371,17806514166516199441,3565820006512657479,5522147581406786267,5806074603600458010,12097432360119010690,8490723764454662542,239491181026703941,6546627956088201296,12612226538705148718,8167470947716863335,7551313260002070903,7803845090184555713,4280791366340175857,9934754362572077933,14662764469696809409,13073611476974886001,16250741189395211516,154936819213684350,17722821388395233862,2824018474151929267,17816282354343940951,8070607481282429186,3883166900057848679,4047440932735996439,10361095044852097168,10103981729772689298,15605146278743462295,4461317642153151126,7020442985314700024,10840940621878685739,12617624549427378482,4792738511894790736,1854771010649572847,7326446761549965945,8592427306383737475,13393774974213756823],"proof":[[9865677252568258229,16694417712254161289,2662950788450856065,969564863938521882],[5605745105150247150,959485091147543751,13608858913332817831,9245022332375807267],[1551124081526679075,5192621131029808220,2205502869387361203,14503883395118891760],[3309865690636347632,10752519300798020433,4520180055548995492,3621004449920918576],[5131587621738387826,5839285009804942389,10535497507165190387,14578796689247328113],[1140961329553447727,16264877138815463270,16916799128617070834,4804928142375668220],[9623586608784369047,8661991960564236810,155305402569219449,13810760629445774388],[8148981688466300737,12773872774832264463,4429433194403086047,6127445641173012506],[4861850866465125330,17408681338976265320,6359004412878954117,1089072845151487668],[11763077224905083219,3322515809295428458,1564307070844391021,12073852421918499639],[4662140597435860188,15986665056496223744,9985855568757142241,12097153713695866508],[17521811303846492994,16621950291891350266,2622482133144921313,13414297295761877452],[16912933258567436450,3758214915684726255,18012057037786878865,18071635308439893777],[2108133720727396308,3685303571652004133,14338192848557198175,10233418226734415033],[15085667825534603748,15434035755120892216,14201312498016621375,17038643387687308032],[14480083425005881320,15642499719937864686,15162956839395616858,16726147093968455939],[11784839653342799892,16093042341241302371,10172015339558518927,12140084199236421839]]},"fri_queries":[{"leaf_elements":[11135026167511937436,17971231252655870308,6228835090359963203,18440140246603462627,12138029740192616421,12759086763519625599,16956176303314763176,8339643578826611524,5758832495388100755,5755043349387018635,11018674273510524438,1371732084413180172,5287007235201932679,14082357462993658301,13258470541738494664,15022510446206548951],"proof":[[9795310326901532696,10760034543527742172,16734173774951359022,15529394157946284666],[16833655732893820938,10045262991042617282,5135669248243316242,756226717170705078],[10272605715505347338,9860800844301536156,14574335207493088521,12707107128448048838],[14795179301414090184,10606508657167616506,2768627989880859823,10007215473266487132],[15487173601688786412,15781900933906490279,3867160470976473527,17829508064193501741],[5049600895368942282,7521471905959094189,8688398757433840240,6132196641546993372],[4633619910476039186,11359423085719333532,15773630378486047573,6966451705955297607],[13590183258077094875,14273014111514999038,7044021647176602841,11184713686403445771],[5375982340800948618,8702530451711713138,2289551863468469250,5123747103382713816],[3275350821740479190,13702178273105589070,6291003288309315941,6435912613963987977],[10456113779046880503,8323712290696071988,7236330916809911127,14012565474644981350],[17945852202316169084,15847946808099579723,8230132436156343337,12189456287612213280],[5803653550653876504,15022931865386960980,11700535091039125963,742342098076444190],[17423735773845684644,10781364305585028910,4741937113953705357,9996559428481107602]]},{"leaf_elements":[16520899336962804484,4750765728294680146,3148528493326625669,13106900999317207953,7108537628153326771,5528292899358895023,5563898957601013666,5847302121541573016,10814061431632105905,13064319941381732444,4403076911396921972,14151331862552777327,904597702933868593,7080006121030237283,15060283628684622572,12790925311794173311],"proof":[[15682990543937670946,13870166087554483208,2223860758645405579,16104247658130779233],[17216626006872029380,17233643303322238258,69377166682559534,7136698881039822453],[12483697907111369825,2391566145738969664,13533806029745836288,13307309724213787891],[9061639181495755289,1934910430172240290,7140802056243668577,5627746794460534581],[6023788026385382252,17481492684191201471,12783719588020002600,3577848824588983778],[2751345557017326278,1392380286003541967,9100633940184559230,10565642893423842113],[7254877452727598585,1225040452648309086,18347317052890553591,5343337892879968258],[571079598233752445,2230363532493558990,7026885405737843570,10325451741356244773],[2090295512876420775,11216648464304849305,5112406734526972595,11052331487730356245],[7264185616771470661,13017878513337843949,17232745165449300226,17237609481025865140],[1896496896329280738,17060017233009461565,8636397705282574411,15875586524508575570]]},{"leaf_elements":[589074202627316683,12030621036812427470,153622687334796028,8565095760075978405,1602832330265419801,11066473933151443026,15510982805445047450,6040651646318567138,16522687911355551824,783835475287298141,6756484681329381701,15781813900753511591,5518306738564264436,7891433722684424216,13547459450376844590,13985885715101404958],"proof":[[12485997600987380912,927369535420181431,17251285338990599614,8335087507604118520],[11070349315496319717,4404170673857297566,14189598829417265881,3363267226415156296],[15299769228360931033,7073227145774514514,13766267668682984108,1797877891122066311],[18426672198491024766,3782313959355432271,5691261347774787456,18162778282570532987],[3217343884531109605,13918652566641920019,7830520510178380770,8376201745776231870],[6997815011984525197,13517646183108555141,10014612734578881246,9710446354603752472],[8042909117308245532,6557716414995228853,14166119175197219124,848913286620910990],[3131048149049991469,1970056947160111397,16865612428973941074,8441701721341228021]]},{"leaf_elements":[79936092339598266,11299331460352630178,16005287320911500993,5625663647551721885,5389506591689653330,10881283555327795309,9255363275957780926,10061101213588988058,6371114636247883791,8397160027991270706,13274705465359109935,4605251895745683589,11309403118103768135,9070119674841993521,3443899823495784519,383357064511327220],"proof":[[4466360159322774263,2618883420686795977,8628830415037553122,9557541481147135181],[178921182851521493,14567190161076936832,18092997502708740982,18130012727364786360],[5976968409239852,5832099307584497743,18207591008093864179,13455248300184993930],[13852577120630895262,1880994351232029344,12915120794444027384,6676184784189409198],[16910557630128917127,16100829597702530750,13180827958792118020,14523710155883951802]]},{"leaf_elements":[6158477130126806979,4261416063082602357,11256589118767286774,18261925294652512804,4370554118133581425,16012970566643040109,5104371069793038699,15818356540991775905,995427122234004085,7251926233713299338,11238675935544657073,989165157908038575,10311043537048741403,13652996557489549334,921303485677266788,5511153641742028921],"proof":[[10232198646979596551,4200019506293856082,6742733555046443537,711471976672106095],[13052362528957556876,17233313225687805254,7649592855461115455,15853957615174524693]]},{"leaf_elements":[16459857234331969778,7510494103410846240,17618706697640144332,17308129413693904610],"proof":[[1991287736843650671,2777827374600143465,15658827494031667277,8816693819394133828]]}]},{"witness_query":{"leaf_elements":[2956998395229022527,10231318929730770677,4753044723779657288,5635639001893522629,13895667819867842179,10451068055654670701,5620337885671439689,6779402683194527446,11784267423853588037,13293909455974451761,37253841259322323,4954630434437280656,14313084155864784425,3551075652285562914,1691694677140982875,574569666712567241,12210316110623139849,12043153571650462737,3545378466428090023,5745195721032948150,7990675317411764647,12289076344907680436,11154342577181335488,5675284592767093815,11801485864677800937,10617706378072892013,14423622456796588921,5908021084608323055,4630308627598084681,9023699059782517877,1641960942683052520,12148364194688412252,12394511228684842488,15228797070956021970,17714817218372492719,15712740411451435134,8767108299274538825,14217924071640995337,3256439808090981169,3543484491216414193,11145179136701376759,6505687685174907980,14295238708015094514,2350893785940864780,12729846357274963441,7586486093235345093,16846197707315508268,7284318625368362446,14398709354966917977,3750602317958339413,1641043003973444049,12029002113148893764,15592826383917284127,1586921483357368973,801947546186553996,1556410793138031550,14243200038994194414,415911946421779787,16688023109645233211,15051478334298738870,1367190739701337739,4257266745398026570,4824256241918762530,12760473687257337957,2256276592033231258,6684857968717819300,14252290377649167930,8265987379681005944,7786383842127566040,3822855729126449746,12003755173164521245,10590758330354850178,16611529212156464140,13610218639497275308,12811808185428221025,11447186585360199792,11801208863363202971,17563961383295326462,13015107375308298662,11447338335575541908,3216793952776935865,13786950940215866442,13477735491092001609,1051253283921086936,14343863576064430850,10483252326426319127,15347026535042252076,9609561434013760853,9237484446293085689,14759050366940330409,1793630542271303522,12282982482338774315,15701667174253210895,6007547555482042728,10983612595434848631,15977492513532458882,9634352901258558522,8601669930063023782,6895556618662753656,18043568914455100146,8182689591615138204,17742565902135567410,11378944787943066244,17457455376851025604,9402801426504333555,5645262076373125760,3190149689741355685,5510836756278904370,3796962587283568950,16452789924492484734,17004353905897926225,3304784920947511325,6229761596467464321,752759964211430437,15194887147673295250,10166738569720341,5413999830009955679,11868628057215442438,6444120925502337724,16708596097791437486,3131842298156343536,11966734188791126267,14520734564758436463,3215735322596043513,16892400260720926093,5330075828445043484,3910510287207083620,17072604511671596531,8145323103244675639,10336582436199533799,7803635836752805836],"proof":[[16389772472073350653,11094270409050057848,12756342732253867054,6297747729788030473],[16947213971911642378,1633857296126368461,349853557943832442,2700698271765207422],[3168597114975097138,12812543815434523079,1008967220413887235,10800270870572707731],[5602973746224405924,1160564721068950657,10477187316764499653,1513995751084053233],[3808560200795885051,5706381862442708514,1275460689230746742,8303723592319809243],[3672399577927252723,179625241395890102,14226539661852653922,5889873865073819981],[3651153320973524921,4541163464577457991,3070741599579132366,5556263150560094064],[15077940584597449232,16029425936537658136,13256461012750522091,1734853864977580936],[6214928497424200864,11893232492847786727,7321142474418900724,11062302419370475286],[16176180811826292348,16503057250395407634,5767913746713554256,12276200976881655023],[11001391274018609745,5340285484630899932,210420871212443908,4535946786476831437],[1647032366637837700,3783622266507323413,13264563513098562036,9197276069788131704],[11212760801762611573,2952906592445160711,3901451728812213589,8146116705309297110],[18194142413689581915,18330254325303234018,12802789438854576176,7077521839799998227],[5388061908046059821,3146978283395918792,4879384126871168978,3802707933475506126],[15539754539194209666,9276762011744316601,14882732954451527653,14100725202975764985],[3947150370992107115,2642413062787284775,13554968791794382387,5523232288997905844]]},"stage_2_query":{"leaf_elements":[9461219316900415717,11400792333932376223,1228689245713896437,8733039005397990072,10611220588958268055,4704094939520782220,8894684001450590286,8709118145877750511,6813752412677897257,12751313847939138495,8009943339511146875,2799015133586405816,13098548110585741096,3145834626091885313],"proof":[[4711015981722472486,7178957835262703285,705819066596851641,10006136983615860061],[1414697293490993820,4549386393470541622,5807795956681318964,14945698391058088045],[12853312523095858342,6397127911500331479,1211842312504455387,12991632987886986010],[7517874060432784044,6226582717591890465,2796986064678142484,11513137603113562409],[100559421881120391,17270898549707362190,9054641176162355689,2562003858089794082],[18306630402670761218,16951697472169794675,10267013938989308777,13795189657315744299],[10368696490571956264,13969899719518367873,13260824932366025693,17780495978845994354],[4230229560955530173,13475970716104627596,5064664052906030622,15629419365088279109],[3149074741811023708,4531336778551384038,8778415841841093978,4763756605998088411],[909831424579401011,4632911171326545226,622702361615941721,4866464160670700809],[3926347815127127483,18026622995257367147,4383594557349857730,6233257855315790668],[1190199724560769631,16353374502325130885,3783823509762968574,3898524765657264796],[12579294118738360350,13223652225889823656,14837194992375310655,10707053283546020976],[8367340452037510457,15983808650160083050,6967325477499078622,16536467383251226465],[16239191710829840470,9401899516970758094,4851175238098287319,11837751741264584749],[2985386359184956191,5056769847407984584,14153618186021087864,7844910207730996592],[9378017061101208729,18251487971075368117,3400045795226039197,8181793834576338372]]},"quotient_query":{"leaf_elements":[14665916909562219975,10639878004466474857,14103974411908548040,5150320117298135924,4521116254707112510,14475613741472779683,7056791431488690816,8558968637406850863,10386963551904632271,3615616945595597208,4780816895159520931,11118770507912695830,18329851343531297142,2630038939211162651,8024721703702527032,10534665440563210717],"proof":[[11456247873593764586,16945201204918503935,3823774663798376127,152151843833609722],[7345612022461171049,2923795618047141249,2528518843147700564,5278168128566289481],[13833800579206558805,1538789801843125698,3057078859366717536,3168616169961215249],[12052827856750087368,9092597568084963137,16807344689383829960,14434862551193671501],[5383767957886142899,6170800054219002152,6338854034562483406,18119399825093923266],[12806090740443032690,12321826828249049513,3247792028101338211,9866718993835894241],[13755186709733107913,12365091468364503186,2407977241096679201,8315828526204368657],[17255926147290762080,10981773761409785630,1992505667628613816,5711442270547159952],[11247773141650874126,14908188621170963152,3280500632733181705,10709421317818180287],[13613089514177760649,8547866278532523458,17806901518860082947,17385516176028466508],[4507249562331662473,138798061939379735,6953253265954858425,3624464819667513057],[8477571570013523390,9055819967373860787,9867683547582039180,15556902558898678231],[12595044263013396560,9657606359972756047,4099337831949456761,2419588494400641246],[14524424646783872079,18423835313250613182,11467398270253631298,6458413743065189914],[6213043884128278844,13053194112360109095,2493724622772038125,5614733943094833694],[5947098821156715836,10876790318140524999,3089486450795172731,10473730025295929945],[9242056365290430366,3482276153476402650,16977389074201201372,3031759846676800604]]},"setup_query":{"leaf_elements":[15518281597683540616,18364996374176779706,4801164375667400664,12411974338578597787,3344527880630447753,16717456995987585858,8367496683840640865,6198948512823166354,5394843104492174089,11350413562306607493,6660236684567218861,12164636420255175406,14569009209058517073,8572429179028363151,14804288852867653200,8690534787090213235,8319085274560702051,15557946023375322987,14652081265865433946,12668098855974548325,14447143102592012093,16136532399398449622,17947489488987311048,7676411480043998310,941655386477075121,4107747221482065351,658647877100418051,11937284001348553588,10010279907993995704,9049472212463794257,1585002802903936811,16641729832756819118,8291660066041851977,10660068948885578136,4761357996318925792,546858836511880571,7634543816848562736,13692202163620629392,17622409334323823199,11744372046155267796,13085579600695935300,12425395847966147883,4826266435754122126,8725027068650479801,18013084730598996692,10072418348443669342,17458488658300523384,1469648787256107946,9184873851123654422,18136972873768785246,1602156068418651803,478505054794854685,10711644585220176866,8855700631236847116,2839130020507989578,5295243889381557542,16825429108631392482,15164179361066685094,9491991771945936737,7195779035553756102,2680076892817530832],"proof":[[4151924815600930310,18169059942670107865,14330824998330372608,17756850197858065264],[9027136800252349222,9971913165192305946,5635594007320367306,14159146984920814395],[12255135006339711076,3835539648699279254,255063942277157212,14445141723442847060],[560775279776755165,15735202606649726054,578553996381169786,15065000009311318612],[16768971401411054387,9132261096901582678,547607575012359952,9212269970056684367],[7887375453673082769,2132183418849352035,10539089771498978939,3063961047217969732],[12149697576991591415,1512256491693939277,7043828981771971744,13452219652276630214],[5545556837416514547,372375627754651526,11357246011888995227,3915339416058695982],[2385584406344040033,7115052224170563237,6279442122309649590,2491555732339735807],[14571647067933271487,8903243846866237555,17077930877708248099,5889972723221751226],[13202834132791510687,6992853212310837134,13887470001018937443,16084948861402587411],[3845794925858425707,9479541431153166488,11932830507117716465,16574199952166085646],[7819074527462744132,14178534925491927509,11966930470734966064,15430163361097774460],[5076554389794638216,7821430103920695943,4416877150305843082,4392841648861365899],[7469743266015633850,2067962481008192497,3347828706322622457,2976723315721367608],[16143856358961404152,5996519384631355076,12438297312417073347,18193110341742101052],[1852062084740715227,16843597978682988060,6699072745485299007,8416947847240757112]]},"fri_queries":[{"leaf_elements":[4769018898516808508,4482221263873896206,4251886280579101433,16682932134952098808,10193117329686004025,11564122159087224674,3106178450571049418,11830391092722623167,11477047002843963048,12951963708545619050,5038004770788810419,17152009395553344238,1190034042520796854,10436845761293059754,14566967830522538668,11892528633697992988],"proof":[[7169653343275541909,14405527216849248065,10081578546513208215,7889588367117996053],[12865457128229888424,2585056982636312622,9092957907869713368,9425930783160466026],[9415421569876964667,6043672717666103885,260520448301094562,10442973335112621295],[16711683917370079883,13266349291186040955,2778308600853963877,11231673225425971725],[845609405874987604,10302517259122129228,6723719920661676652,1891704705792580752],[10387877856156249025,1742513863964997932,2120058809340813377,10283088878119536960],[18388560544788517194,7020988735998510987,17327661019192743466,8374401051356735317],[3314175995260987190,8055333396583891679,1406638855161608820,13555773330640543891],[4965992574095303582,3734517603431448533,5519383863248016672,8343917001893075222],[14540911907822332220,6105396940109464718,10580594894355909081,10154405023844876588],[17682203613631615257,14284685014853016592,6795271907475657286,11046428053100383787],[10034112964725602337,27853665609825447,4942857936893633585,4770554674015042574],[8953011301512014736,8375500996675222153,4768605147644974355,16070527159099931740],[13610355021872374443,16390214494125455206,17171096382768899921,5724327341222183434]]},{"leaf_elements":[15711656623704926536,6298462876916375917,8013499984951865053,8103480912144406845,13419655317638246845,11055050198745351055,17066357493726831804,11321584051984753537,12253717339500351318,2108125147143827945,14678086947307826951,18297038162978449161,4106426819199847255,6968504482891758163,2538643307413562572,7023209535698301892],"proof":[[12980839833676411334,5376009332828086562,15705961510923265778,15823078573105378793],[16920556900241900184,17496594660962667889,8283423188709666778,11783551090743371132],[8449394236411772016,18362542714573071988,5765358029975663031,13946182186996768212],[5171963557359679200,1776431237719388032,7292055646066973395,15315260826650974181],[17008051169874992866,3464846689659507777,11513617203839975919,5243109671493126575],[1920715559739913621,16871183492793129643,513562807344856073,10469987713992639168],[750799961986648852,12799627982897962041,8369728878098497335,13985498971450584848],[4014273806920276216,6827284004700397092,2449283537052733534,7356822878799261996],[3750690821630095719,7218855742402272836,17393589467352025170,13543007914879083406],[17205145939362666723,6171423704458157768,1694383433885278761,11669304394345633035],[10682418301306056926,4397095648977732114,9129476804090528356,2486042903507615444]]},{"leaf_elements":[8590503004693146183,17193946357290144679,10261263735071275062,15906676042560529358,14872219655141773356,8825062352996802565,406765982423961714,16773479141293986119,2421027163289747304,7672878678134081033,15295164200280051793,17975981845613027052,6520269682338859201,10078590075751744064,12955972024499457622,1359298127698221682],"proof":[[13585522641784523163,7574133689563858349,1372654767457077982,13145148209163366662],[11645095026458586536,7482728654566562804,17978699551883595814,5408927829896874337],[18069124694057672954,11637056283077256430,16010387481272536285,10736413005415957531],[5291964850054295247,16703204215232945935,7388062633203162727,17067064932129789424],[16639057666218922901,15598307940838095585,8898742259005793875,6154785543080990632],[16239826994047346042,1031332937696833367,15396656537886886967,224164903378387373],[3999310531777917570,5117558220654725406,986622121901616122,2573288341139828342],[7710590443953181903,1665559339107437526,9135446049558838395,6925893777471136724]]},{"leaf_elements":[15351808055654677228,14843448324813300884,807433483335404908,438606949128437762,5762114721224727918,14691466815672029687,2326118871872992829,3936813105278443335,17590242554236914085,15837430758599198331,6895617490020695142,16631052313848994577,15046012228768851882,11879820856220130304,11331237666932127384,8506993833071034081],"proof":[[5625331405280959098,5859718581039070663,15612639009132275883,9301501949396337155],[6346958305029095291,12991741314567184222,9271483572187164407,14829543465836263151],[2664484646257981248,1205866365976585800,14520591337384607444,4331621172801866224],[6279864777603778371,678680687311988811,8476427838502957990,7317682539494958522],[8510949190905270369,3022555498354495143,6630447393776538375,726806246032755332]]},{"leaf_elements":[8381419747460808363,9682041478917048918,8832335651285071452,4782262302348399797,5171799143027226650,3487333851355975518,14477241757594679357,10319321765666552315,2296846853020724686,13834755393422759648,3080949388900232604,7998512944699353244,16130268322013171367,5288754545080995367,17765990141192492990,3393741802002408949],"proof":[[3294434734851612531,13573913025773284713,9751967141864464097,1851544732546932952],[3773284951162968959,8445645153432188141,2209936326836181177,7580283031811594398]]},{"leaf_elements":[1190867689108365167,4332739579219866530,9664569906437014725,6815522135482449896],"proof":[[16986050412455206964,13618228087451635190,875700400828703808,5583175232334739525]]}]},{"witness_query":{"leaf_elements":[12851296883658267466,8929704681007379934,5738964749619215808,9641506479095523029,11596550728899499484,18294027298131468778,14611226785691706604,5462335142258314821,11480951782245976376,7614709171410312272,2623138279023268630,12268574932278175572,1036158180406130769,16847161701198021868,16526773286882798671,16334138053793295656,12539728820324136627,12940922275598455394,9551297293764586669,15370247178189291072,9986282635110711369,4691954711917220273,13442016363129730320,13213098158908853662,3335556011206480855,3064357067849421826,10715714914000741508,16535155377585852587,4384076932740404240,3477692266312430079,11033542444349565865,8920978217780357511,15311690917058557716,9836378365850988040,1914663894817343700,14246134168949868673,6887096226808778878,15632555452741124613,4830628424064995297,9124482389571851932,3038445548130088281,4476529320100411309,6374929798103911404,7382060808365710412,13682595111159129623,6556684821760697174,4990530951083188651,17799936630730558556,1527898575901057652,2133531460839479504,3369635584689499811,9191854355833364358,13345141501230433742,6121098080472549298,5934807862887380103,16153924453977089570,9352997574932752184,5843249377682808680,228395281024405500,9490550018557585665,9572857959607659449,1615828636936437708,16161384775373927154,8822673230039878243,1530714232462707230,3484551417996835964,11022315336936508142,14942679423677809946,17590270573119265656,16904938911450266872,8503239614297662223,1998915214385387660,3355205390886647040,12290838383547831278,75203825209176302,10666573893567683997,4286162784907972827,9882475467453999000,15160685700831462481,16300569305940000425,376019840030338496,5615678679837233394,12705311015927684346,15754798899441421700,13014757673122509019,34774205166653217,7683336161447252325,14306469756416903981,7504788939140390932,18409391655044525605,9998944173701737691,4924696189259079268,18436780766574173369,13625354690683121549,6608711850108552246,13831816855542303751,9535955298601764817,10585146286283160192,4732541416192889386,12172856129394082282,7219290533006205046,17999920344674240666,12241250949689923045,7421402380599596177,16301672895396399446,16931611696149064862,18355891524591516398,38725606845307528,17089704792935655647,9634743989394957713,9193898576324605138,5464521776434209634,11647567311441663226,2829551402535305478,2069678435047855459,18008171821035265430,2914602476565372865,8266413770477987235,1677391727351410421,14190212204607803878,17538400874042776237,3523151531105356204,5641014602275837677,17977430526077377946,3863362117815518043,15966178235855535439,1906861940468384244,13243419011671469182,6832088402757136581,12626379045358659413,13064543594245766056],"proof":[[18320851892025770066,15624018562749151549,7032937871847868585,6356178614422466076],[10596362916477954022,12007985943364149509,11768055831438758991,12856871781654946870],[15301082417260499187,14444286832310591182,9418783099562756785,2081576718397487785],[2425983555595523882,5104554719691491882,18149334828060924323,2358948236800340657],[8568692784857472081,15840522502261012910,15658697959358157449,14270798484218717029],[9801150079277578706,14732312660449339335,1564059668696658576,14978558874434745422],[6601560582624552446,11983616532980810149,289892004152378204,7594909920609375971],[6965636125645419190,2778356538389006830,10655247509967451302,9139491377015087046],[4051440603516694040,13553484936829100056,12939783527008947442,17676292583769983362],[11139433061769088517,14828605413876648109,9202623190563570133,3416585263715356924],[15168805477467274190,15920264793884784438,1222424162419407527,6745342130129571918],[6674736043433846282,5975817012350009184,17773698205142715092,12646681022206383968],[15339485139944235608,10101686132442171309,5336335525840703713,11564996742804813408],[16872774952102326479,1605234470883616103,15019779377452810803,13251421680097680769],[3207936292782500580,14524095576492307290,12112779008836613447,14090375721564865806],[13800899791786948994,1183333435184379289,17950372410664387618,5565142864205071605],[3393871209601250222,703884795262674403,5617473330063218609,4166382418844188663]]},"stage_2_query":{"leaf_elements":[8881024175932977885,3354529185447279793,1073300128206864784,8412372939065459607,11599022414459143425,6739945944837176358,17543880920654631570,17780878720366894284,11399934404292443991,11717296523439066620,11328278416257440780,18080117381877938123,17425138209153928003,6517839374425952612],"proof":[[13783196547957351858,7391026153951477546,12789642117877947723,2100116367131149833],[15737703163600276537,3935459454578437466,4665114849251737896,13486556717200996303],[3148866494973291741,8363144475108141001,5444980172390213268,17768956616916812421],[15234215892549388307,4031061680770956293,9787081811766095558,9513201348896150432],[14790446595067590830,17867894694884676255,2166298781380177052,8704212206938889000],[11013337077360896176,2516955346556939267,3915785165480577171,8887537587404001642],[13272869376526217743,16794513374515586737,13125222663357013519,17126555558879111218],[5108499390431435612,16998610632086504350,15699655211095392813,7909657794421221229],[12392557321600585115,12419615425199723015,12894521476611842606,16970315304214815711],[16188320209067320159,8190299277527556062,13850287829586689473,15553946173618149879],[12546432276919694358,2357478255033453542,12830814308079731500,13740562427336744865],[16338486037596698991,198774247946523074,2224023184936431982,16881316619952056736],[10293518846745904965,16092554777487810885,8091219546424865498,12810330837610619411],[16273025630741195945,6529439620375360111,7191485266102663172,809863974912768552],[7345005012688684630,13635021408069857899,1316586708031674244,392138077556035690],[11349201894860166589,10418290087207365743,10724316435702442016,1613603781219327118],[2376589215282065375,15866912507816706072,8741136943557390550,3471792826795121590]]},"quotient_query":{"leaf_elements":[16264321396616559379,8238732301602453399,3171211725250368567,7541561434367513846,9241455998998124874,208576385648310543,9133622560136538378,15025750624808093044,4424192247087773335,12638789052271141453,205854584652118187,4652666158903759459,13961579852964959179,7166223383067126243,4953220371516903738,1301690731034832213],"proof":[[16164990220677310240,9965111041484184517,4280592132098649349,13405431262374880506],[11022372731898188390,5133259730612733964,3025053970798967408,11216891939351297394],[1711084888319524855,571734425462241645,10082191796897396914,619073537557358455],[11964795366529228873,12427900410177559996,14170848510877399391,10616366726304591522],[1167391612575777871,5338052017361238833,950837598163531218,6351373686524781138],[16188702022223881975,2889956830497710655,5427962835606924896,6997025036128891745],[16411561230670415008,12180855910536652458,1615882618280754896,347441019857728536],[8214561915373901697,4885616992680079292,12872503867375647218,1776138163759235580],[16532498890105721251,11299998644167171759,17127511079982773901,4765941055891841611],[10326864763584339588,6972240180410243396,7393588537867894250,1371992394016437876],[5335030811746690025,5880164470237524203,6893116922853282541,2394287571635764126],[2257681304891588690,7741450944039511066,8510075505757491912,13343166505020160251],[14505682615963184312,5569217647881198130,9516374235162874847,9923856660067538981],[6881383326157155299,14929366581304853289,12976167222388921937,926582427975535276],[16542160548706441824,14396230370598365407,9791905095404214316,5902013376074363185],[7702373905826084876,3779368126887063776,4187193899147183797,385307142625548285],[13873983527620793734,5538246857807205789,16428272114622577962,7585704904145452900]]},"setup_query":{"leaf_elements":[16147951239508623530,3025533856246518790,17698958128296276568,11639858290778431128,16660965050693770277,8656480249798579540,1339667800499088242,14661545887410251219,5437705304346298245,7047906945138768352,6089226192607539237,6623988705797559246,8442935005237955077,13268486551196434326,9494093213438537330,11383657578514888461,10176015678117318380,5967852214433237341,12075905691644782077,13337995532664048650,14977571561084962912,11658320154346514481,4444693348950192124,13413741111899019524,15855285567319820500,5009965616940765352,12747516141767125990,8177679075522441688,17859389404581901991,15114425154046989370,4744504116635020800,10681210729162970005,9858050301879222134,392445790893771770,7794551289681648632,759862946258778879,13123179492620869909,3806427902180540771,1696144869559111144,14409906172737797962,5855522582275258820,18369684922814460414,376373567745345742,7310225089467614503,17531040102895079235,12911128914174631424,18081937937359744134,9067906146331353030,9152940749680677159,12646662476008045095,5374702755876426446,10671427089233560752,10491196570716344762,16726229457028730542,12507811089449751583,3815680208937121479,340508140340489205,7966798667593919632,15645012064558984967,17001696235903417557,10908613567176829703],"proof":[[7194547282319629939,18354160496344510332,17549404929046272075,8949257715483224761],[5786375667578901898,7853969889845866980,10673894316751218611,5261347661576804965],[12514746213143595062,5662406025534329517,5295760050858846323,15290458987037855302],[13706767332988676518,7668131691284010951,7301964255043163320,8720456154737689759],[6194610385416890630,4939400442142257326,8149786562091092048,10344537256812415490],[9839466636142201637,16871885320368544960,14637999693974091790,3570565428190298326],[6647449154599368047,8187671812514108497,4793201859583554327,8485257167666320215],[14677926806910009700,7841491893358815919,17612775773542381950,2648418462242572956],[13586365633324972890,6783959991411484782,16695249737148991960,18259198823902358162],[8198030502945116374,6442769325353291418,7980986635647759896,244228211209412572],[12654782974092189330,13399309117689645006,8913414324404636894,10215697723234409265],[8391290394083979646,8915816596594726448,7628485871921936984,3508947551097761425],[3595734022533319206,7053999561568682458,9760284423808183464,14216858043983216659],[12326150991307837424,1613322825058498618,6964835554835925034,8049640677716323834],[6194187945286456484,13897753358880986879,2876953670385445733,201068455362189695],[1417980075933143238,17220649434937122116,6856092148304195601,6828658372095855296],[10567984478803164623,18091897840363936695,12573130155263119716,15666570801739383580]]},"fri_queries":[{"leaf_elements":[5617034926149595384,7087223065972222381,18009783125132868755,10913011204531940818,17705573965579279994,4331911611423019964,14773504230749490812,8336044097340604535,403388916370173762,3090464610946644942,5002265510663796741,5501498013181551125,3227866662204245320,5485775427229198298,970622467155323233,6949944043700589421],"proof":[[11711086419618239202,16679194337355453268,12197075917921650710,4430679355868365355],[18205567852704393081,2568533224611992073,11400944838426097302,11137578560681730872],[16451342695660079415,8677972483308222245,17607892230413694099,6389233872787730805],[12358259264024225419,16946975647117727564,16157214399489719559,10269151401274201412],[14495843410516753212,9251152755650291722,8409797681774863775,10024602365498828217],[9095582138128850671,6177554861552467377,7190644279738544233,9858592692303673317],[13902833625740556156,2895127872600924856,14981947808935810323,11012316748074565614],[7739672881780948555,1768289580574028755,2158269964435323142,6210395770427511474],[15100413857882945105,12038294540964181451,1659085239346612354,10350205330143505069],[3946816342614070870,2415708399480847232,6165448668511310058,7222885125110806533],[16461623451901392224,13261710711263420188,17383203563842255475,11850864874319740563],[12802439702873445462,13429483344192824741,14908002083799769397,5092927762909933213],[2832576672971152501,3379218287516176698,10635671997862126689,3952401530073630782],[13760676854779378331,12586103901516069338,11837711225087432254,11243314579595420294]]},{"leaf_elements":[9742087897807810455,15823620011491045395,5002243566219075087,14452093572667213518,14655371019111091475,13457045844972389430,16437089680414521799,4865797400135789274,9169111769367795151,3015845440739430867,6438387682839442363,6208756565290875,17770863496494444045,8207519712780301432,965488083538932128,4367664367151143062],"proof":[[10729131527750079667,12946516889435068020,16734633184420515966,7673127399957981817],[5507877713082419348,14299430855884786310,2684621534912333433,12001802930060401533],[1487507579016967408,8068509388657658698,5482694930947267864,12016468589223718007],[17335234853662559181,13202437965626460775,14634391165333020418,7420286469176778998],[9019347643420491350,10076224162517139278,4980993911836261851,5476638428430062747],[17838462815217366358,15689696021806175248,2100724790929602675,3022018889346140054],[12873012608855098486,12900244570531380493,3430483320464930461,7812072877409345541],[3917712821623582913,8370330792625898781,9016922381555850981,15177100559520464602],[10565620564880637757,2188574762446380140,18257022642385169999,1660255536701533548],[12087264947137892738,12689087948258299724,17318301511932808606,3098135342556233594],[12854372577048767948,12893725682416060566,9553528197170383843,16743604674518758559]]},{"leaf_elements":[16239549288638473194,8317838823109402543,467301483445360331,15977376856376203557,5568631416736142245,15192645572329042597,11579900818130469001,10172131782242013131,5954505372730883287,13955556413526383293,4674146980355587277,6949462193863473977,11146488949989214102,3125219750780641676,16318013258492785760,712379495779976794],"proof":[[11807905465220123210,14035757576980918151,11042191255787682271,16814625706850122319],[17156518183234834763,1027691135599622965,8761885799256327426,17861542904814150196],[14649012083032704803,12743454369527896594,13201200858129951326,18122769314738227111],[4594278524718729619,2217958956233306202,17405634397183910576,1886702583443992113],[12921210154433622783,17287529461763051039,4571541343702322974,9479770263395957910],[4962072288155652261,2340235569750498040,8612181413540318753,5288589879503886904],[4447284316994042079,8257006850954281651,15557837868395411088,8259950209718937077],[11304602737041440013,17087162656942784989,6482489079846908548,9342824352433447354]]},{"leaf_elements":[13614388039401255990,9158755496875827617,2798899414993439809,17749886421291606302,14990636254111250081,15745058698314129293,15149854849436835442,16306667175595833939,16185729844738094024,14380208512876996329,4172797125111111090,14194317400676546302,235357342780232668,13798299266721959604,572400747514755924,11755554156789071904],"proof":[[10603080952186289483,4999392895573658310,3468299844760856939,10065341999675791782],[6291852882792192012,1233444397142928010,2164636068028834129,7992511955178995414],[932000878301653328,5663234810714108720,12916960545376059402,17274575844218797858],[17803484793277888087,5831958870643149590,12028396324057597898,16125611327991568626],[512053513863061598,2002380255743949479,9190584305322589713,14156749039100967704]]},{"leaf_elements":[15594754714644724177,7034980007528329327,12757709916267302126,4281393678233531101,4937848372780748433,9300679720985447739,4290072722051965124,9046323667082053556,5892411612232638064,1676074571555259132,1246360140965797348,12062615642085843283,15942348569860199954,1244987182438668288,13689167975444961302,16021208181444307300],"proof":[[3531223462616494339,1721779358192805038,12040767781267643105,12461900958415241326],[17826718640729923265,6529578062451925741,7217009274646659038,1084074285071589791]]},{"leaf_elements":[8809988403807970318,15160362933934845700,11776238319247965586,4703853722671499035],"proof":[[12235680278416154865,16467979665684915512,9417111133874346442,5572305809501364044]]}]},{"witness_query":{"leaf_elements":[9514673579016984253,10294650858493318409,11538265721684082521,3563530009900438892,12986737508903938707,18158337324377165185,17482202047556215075,772132954491081987,13970644058379328343,16215563543445576391,3088326772432040077,14834973119533464202,15651789006084271437,12879469346753333594,3906232992165719457,4389008884483494891,1971098237559849297,870870700620914414,671421729201930855,3702485269592321891,6891144489650244095,1686374217353302030,9548154978724600367,1912662748407305767,9001022854423155762,7236082464820126056,5071257906262284650,17285694489933339044,11459179960268877522,5518486054789923199,14103867767638543699,16730719995755110564,18174699743258089042,14014338098077945279,1863340457373410181,2139174919711562557,7894966005100118537,18231849923058658957,261848910176432664,8337323195873415550,14772123173378209911,2992025858164318575,14167436172063580246,13834350095826848395,8487369701221969480,8794284708440907299,10558205412860924477,1100037763139130584,2130086685884141616,1156539910383020451,15968825838317562095,17640615494969869486,15714324645060590657,10782705099678911105,7622741396167107929,10457125632743311247,9251110619356307932,6031364309687638515,1950839848532984961,13575506428445479875,317293377860780638,16046900495028497003,12304080672112451102,4870137897487542852,14309239856892420544,8771096701620925538,10540120802143486671,11828197542474287365,10985803326314347527,8223012919520671347,8582350354079156842,15699200911872263597,11167255575400397284,3253145975771423045,9518468884395871585,9594905664269224647,11542400793211632694,9597755987898513308,16351437454031545474,4842066465492965033,14069942519761041831,11691651550005960958,3803197387880828462,13021887546515571318,14504726230154803901,5108631075279058331,10335689292311107897,5901186858530824890,17734732385501303308,14762397092956254352,3572805424735880518,7826632103176632450,6678588410885145524,2461002180495831431,2544650768966606457,12506915104289748088,10409861547577228253,13183765799830821454,14179620048428478201,6565091528618391796,15785906421750021260,13474443933358250828,13919441283402446164,12958390453170060642,14447706273574618200,5924094531571515663,1554845985550921473,16232403927296231785,3303648176485774108,9863482671584273578,3503369856305260178,9320481006202618369,2922602114384248402,5455043375203233466,5759846171366235853,2980478273790974241,4751250160143655866,1048471609753952171,6160579101042943830,18137615424687022101,3546013214047358802,16088842772130154544,3555890949145768140,10333692374544730420,3387582640128008114,14492255969335258283,16954774485780964411,16368315570257242767,18258528901948405690,12039975185541067195,2768193440262472647],"proof":[[8577985333487916841,5907013150773016762,10837714644157301824,8806899898114554663],[7047311481430827904,16502786481174085018,2154003869630472163,7745398055980073023],[18276278437162469576,5891423522421982736,62008925753786275,14971813865689734745],[9304458385420883665,5551168759978088815,17856926444669024044,3094750454783937532],[2574087262063767316,658383718115253168,380520398029771923,16523723243472061447],[1054458626412609853,6920403181039135087,5270464556027562155,11989798970735190184],[832046340747260815,12593348786542984358,5975254673363579209,16475142894286362810],[17818801289377925033,12168529493407159783,15059691328062680576,8490265143592656419],[8069107543178179007,6167725840996854928,11943727317506279069,7761097204736770600],[12575342100709156074,9683839004037204548,7161740925781628156,2538668807533312143],[6596724046241611022,1952892804936541560,14994419699815644883,9124891581026248607],[8579462635744470608,15432301668317748163,3030367369930326821,18028298789683650901],[18428786374374114052,9646477318981110817,13931191073154733865,11331434872285306758],[4467753345533526350,16207251854017636100,834149089514951027,263421307772246734],[14232458703075821975,12766306955497689842,1713331459581368353,17806804703697862832],[9345926899335508586,5715321272162009648,14753380950316931054,8959900411445936960],[13255727909023806858,9413315306704877800,8591396154521213104,2625714645163393602]]},"stage_2_query":{"leaf_elements":[5304768209121876567,17574497031659285596,2590870061693826625,2477020696412798571,8733541210261794734,14500358987389886214,14317473695919754749,15105802091391173221,8351189643054748026,8773440285964405047,2359316368180865004,8496028351034515208,15374249900349241800,15722509418206477115],"proof":[[4819504087410412891,14078618973397933510,9275561350596867516,8672699725340364724],[912705948526786308,16604390197040066531,16422358197001233407,11662878276617386237],[4139442590249144084,16594471390240197327,749202106897568980,7384768186917225836],[10123424946256826241,8833101325633883640,8309111861146520032,15693918552200527091],[8675151600995037130,13182516809117404279,7875589440898455713,1673627104073702704],[16686084935056502647,16616235143409531041,5193737983562018965,17152536523972579281],[16906522687491279873,5230896441409315588,3101053258420937624,11029491711690931308],[3987921153043701153,9661807078317964301,6292935612732847075,13388726934258959596],[3637525603521656729,3883162201521024295,13964327622738133246,442825683634699555],[14207522863146478194,5982491356910935388,16786188323597743722,9118815928836374571],[10390458073511478369,3750849907091030196,10599813575623517836,12012420621200833563],[17705129698560993844,17818311854747839391,8141735435054470194,6259958955676248176],[15058326309793319611,1081374279921234254,8917164901355117430,17990374782442390543],[7289989069958224817,6975516276550638916,5967398911153848390,12085595303613703152],[7932971968029234306,4558048546367670673,14177323275601916228,9800643410316077977],[12354075948538854767,456520140636138971,13930787413699122222,16819792904776391214],[6100607465638496307,12865708154674808231,7666936066939960365,10727797711719580254]]},"quotient_query":{"leaf_elements":[11373080483110739184,14769516890892982533,4594113856204496251,17347182979724869501,1759439050883972102,17993597233098793361,8711130533588017441,16482725827124677536,17489425968476918078,7625451015938273955,9023839489210242417,5327035895962784725,17033030900789241885,12138551944986521302,17388386281566096316,9702941611282140794],"proof":[[12181706335580324016,2540347201242294981,16850666667136609881,9540166653598725784],[10354334802549546321,17307370594099333310,13328094525567921427,3002132075958258188],[4751546517679403452,5518958091660862498,7071978251657012895,9833274550561833944],[2323198609628932703,4734682567390230072,726077728668778787,13401429748118691274],[12167443283380824560,10824057282522827475,13605280168840570133,11374941536292037723],[17469052985022445842,17680251926066559943,3979968222788901112,6514696293104273147],[13595100271065269113,15070347829847480498,8989014519997693661,18348867832797224127],[15421974267965801841,10788190201966724687,15598987370795631563,17116975781979429853],[18109232763321944119,5674140341039189492,10548214354730218699,8501642238311748117],[3110199569986835751,6447902179877337050,11631304833226888478,12482354875054815464],[13767348442191763745,15422437463210529734,13885340065130124202,3709717755609905902],[3983568113335106891,4103966587554684344,6525916847381173727,12429795426896492272],[3698459047863175402,978288214809905875,6524828662412345406,15947878229181503321],[7092829333368964198,17880816439812481244,8455522912738379278,17886351429306730471],[13651328090811473567,18154273967731351046,11418076732452874920,16117577304234792886],[11868340625958688647,18019212651492142112,9694925985172501274,4928766326579826723],[14536972128999250177,6667143565379068080,11148832979425214395,332911980230554219]]},"setup_query":{"leaf_elements":[1239307787169856749,4555827207661407079,10921884114350289540,10468196397896390826,15711930231579261369,7354467723927799287,8942155924881746560,7750884004185418465,2042310581240086181,7855659643004993846,10248999398304632224,2970953481296997855,4202702485960485261,4105432285530532958,6489957354655097304,6971986625346978412,9293606555207925151,11091340316757581372,10940322982482236459,12256596971103526554,9540176644251581795,16015153851752782183,1057695455752730539,3745723772686831874,14490862761966126933,15328781042504901013,3698361540510612931,12496636942033796906,7148885567881209034,7670032586242000986,10744079262156156457,17546863316027356391,17025326174457008429,18316945411714185269,1658953253854269821,1683817563276606024,10994570693015257413,4609407333078456231,16338311019078713810,2279305181824297283,3415172813292994423,17211503586885459375,5998402530332535372,11551533712437503886,6335743793059004818,6548925022220007029,990896839807028851,7824673744747913992,18023287424075467969,612566894785931034,15539110698532816831,1533146557009032110,2885493591047972968,16465080457777833968,6794385646814314625,6836653370136327793,13010410951030167039,8000955125164096237,10397686666883061516,15979734399089438558,5957990590007372986],"proof":[[10934684021944141209,9092494572722550319,16166910756816374825,3088158487140059922],[5870284947907098238,11746682618873753119,14741806933039045610,954309508489992668],[5163031134728331958,9804539209654306540,15362067908355077411,3604567056469574764],[9580731595363433071,3257531832200902671,6985509274290806062,12698442488918902567],[6894521832908764269,11035397902343697400,7131122650412194311,13860693874816724256],[4267474982169087265,13686415514352377915,18096392049090319978,12379427026228203998],[136511421631868381,2495235012699393393,15457108964355440121,5034661047438877254],[7971482402919324782,5681857675006720744,3582405350056628454,11002341287134607146],[9350951803620371154,11747531653386060848,9149260659826932471,4442110422023422182],[12775107032428965529,15988954715281510074,11495179158465786720,15075755049885873373],[11240056747678300163,16697232102083681473,14085136303149355337,2286360830013704496],[15430263637962055229,14685943083299370697,17141222362656472791,8498997911561514575],[263424532737608942,10042391538175834915,14039609838509138753,3704501999636741451],[10505172070594591263,1552142136512031840,3918960209610434049,16214205027961992063],[3943939803439131542,6521571361625140281,13781785586346302940,7690846761572294953],[3157985308958941197,7576400177295577894,8613758861343242940,5485616649925545153],[16583575629050195378,11918539237340408988,17266148333552418545,2318334120421549131]]},"fri_queries":[{"leaf_elements":[13751365196866011439,1103969098454582786,1697088631115327449,13683949540282480364,12806715482816669466,15814750678636607217,7117169089825457794,11628994983039506132,1903756271598540725,18058040322154212507,5135931238013323740,14151332098704732063,10998174636986235940,2671665662227722250,7885931231361066434,1950741633515555758],"proof":[[12402835855687207622,9082120600252192073,8792734560962605019,4635692861679843348],[9245753454673813495,2717751020066965945,16283080089088289443,14220128088992926012],[14042775760740408481,227283793207706809,16741923486211746767,11862755030247207514],[4323047878915467676,5004827648670233480,995861336753757137,289412818577813501],[18033807417939017698,65934805217002100,11459826072053753018,10971805356361894957],[2795932270825563605,1403934765190489663,12944862176394438532,10049652922443575508],[11860829029005674151,16718966954094316417,12018525124380594635,12061881175390729187],[2897955867484815188,14041410675741747844,1232564054263775652,11001347682361331027],[11085673567823450328,8192325147499134573,12185049775110477671,3225953283368133507],[4228926871217950684,8002207028834140978,7469206471541097222,15099712112908773331],[1845824524950025511,6614956586795481624,9621375879193361486,12423770016728672738],[5553332684171534683,10601372839128215365,7627612710450916619,272727969173267057],[601144344064999803,9388378308023134623,16607194334953765916,1300416795846521324],[16908454296595297924,13718690926177122060,15594844971309743355,1889588241462229191]]},{"leaf_elements":[12171514689929087570,3480953057446128975,4787801734896192403,2377431603439058562,12655649043708949063,7094501842830751462,18095710507585191874,4513012107438800212,13182589159641267899,394560517518480101,6236593988411377737,11326972799607912332,18073401242376080183,1849637325484271340,6169287448691250310,6487155835590353894],"proof":[[1656920000529512662,14431899649770505168,14351815934869027973,7457794053717644335],[5259526555494887738,13336756174885607438,6952150626762856651,18399131966968669244],[15501776816906303600,6035988013660365228,1736204898141947181,13475093338247236797],[6358850513384479904,2965500147589327205,661796959501249240,811392113452460339],[3580736950992204798,14769917859877891072,11124731469166896563,3266399075726045033],[17425800817679763676,13606132610563538067,15058169731878312491,12922429185176556345],[3940384241581994591,4136175441060426450,868133241495212975,18377998940612401408],[6970874931281214588,1150159719393284867,8548443867176763099,3291037408593342697],[12441066887156850436,4305638407175688728,8333766255960169738,16271297769202687552],[17883168812284973871,8046575643913793968,11447616859048523923,11643259451614129924],[6101564178588544594,12025324819710531617,9145989573612374006,11082714772692650549]]},{"leaf_elements":[18071627774380389253,10853706207567956545,7843593829428242154,8081189856925237583,6125976821400858173,12380741273671679345,6840319214622359127,5647594875910376187,9554120745448493504,18411870768972832525,9437703419160602409,10023652167744224585,12897354940939652217,7110577140444160204,5040519553599995921,8052645870339491015],"proof":[[3081223970383706341,15134869016564491827,17434513244595464520,5019003736131220198],[14175413043486257831,16747918794862483542,10504975515556082814,12103779216914995909],[6950536305052692501,7173513249870639904,12137922951359261564,5937122036445756100],[4808595496533429586,10550288118792634261,13474826332453935095,14369795534616367198],[4418688213115736275,68610714129923815,11186925765241623680,4230023218146827242],[16339117811665250064,1831147802477964957,7151421854794889082,17811736875229566130],[11999127526443723594,15460213949247430206,1888474429123097976,17595405601142015086],[13062779735471498388,2666710622980737108,17005839063337516540,1038029484197260533]]},{"leaf_elements":[2617874787026216936,2488967522925601277,2222260674624119102,7401612678515702587,10393183270366280891,15453017982134169752,9568575251922696952,15690825722327624746,3545901026392232449,16229747619568988919,12918063757230183784,10261951145083584356,5339012894695494731,17944196780154577586,2798259520805872007,3186499306874864928],"proof":[[12272311016410496932,7088387763411157999,13214419420267757366,14992950329749525636],[12346341785198937124,6452575801890894220,15782373663858419776,18305920816986526953],[13110269037369647232,12933068522583263217,17101163007442933271,16242626025475386033],[41841670697983867,2910968819039187125,2651532467719605998,293301418865271518],[17241421336591542366,4752306758757300741,12596814237935603341,1094297754487151721]]},{"leaf_elements":[5947231207324214246,927924776839276860,127373974683668475,10657805463538097642,977272119028456856,12272136088839003304,5592989310274946848,12958589530374114261,10647280714183221445,10174049013701791572,4732067753978528596,1992203527241651566,10730463731643414872,12317868401435801779,5774959914679335406,2943037448673291990],"proof":[[12770033584247028504,12834506541173125253,3889025783020205878,18071213343783589709],[930657607580029845,9415123429837400419,916733607769265567,7200549481156444974]]},{"leaf_elements":[14289688333807745351,9680663003935070667,11652551806734550691,4827540235184913930],"proof":[[5240023807566851728,1888324444563251120,5407198403062163597,6292866438329913828]]}]},{"witness_query":{"leaf_elements":[13891142811403648165,5627472381352500857,14150333818153670187,8106555017163629876,16655541369048356585,4171996321854479463,14688257020010209575,13021420414476714681,9090360933481884559,7361116177954148915,4679423833033243265,9290210685701899861,15379289824303316830,8794390562712700637,11724504117769073035,5940988124272025366,17413444286854981755,10902620826010717967,10729029223250428184,14361106434990755683,13833288879361967763,9127142104317065234,17378774550998244253,8016498455384399932,14943036381644881117,9798787127344079337,10248808929593697738,10915602442327421446,3574194551472602785,4449350919115432485,6764985043643748052,2005449257510908415,17760389020755530173,6762180904624099861,3812435922238863425,2958149790758486241,6901803691215067433,3952413074935009410,1198938527035102718,4580449092194596431,12618761283497230263,6735842241735428168,6785063268862150755,6064634429150520896,17396065267199743145,5641457970242107860,18110495153973413961,16438067965441011405,1871490836772226339,7032043849947981323,5138214063401260275,246462598868306181,13671737085587904666,13289285813321237410,5777017119588858186,9255791908874093329,10279154010578184492,141998803546352255,13876680741234640733,8156234815963745810,8637574420989760625,13047284905123529146,697804167840511078,15904674718810663444,18345012559743361084,12286097478150299079,1608472761971002017,6184972547901734104,11033124776947789782,5744880967809471904,4955835190152049148,18205685166399310197,16766857312244623669,18264353554124677143,3720160704860662682,10640136474772766656,6066569906181654388,8643271996213485927,7640031720720752244,5726889489374077608,12932782546563195048,6330772812853877470,3731398222932636734,7597057731677010945,164432979150034055,10961848405232752088,6508743093251102391,13989863311059179930,5859499977014018778,5734653304278527403,12521979684144754671,15540269024511764310,5274584537739208339,4128831126539709609,12039010846965359585,15740400028629284250,17189573942284819807,17656572016045312007,12332252441312607336,16765183935280829957,18090800134111886581,12424984455475447006,14552663153441137214,5359467044063134696,15824066735879040256,1416405464839540848,5816095642053039426,7133135804695652084,13415377615110751089,14635718036460542425,6839144159979046791,13444607042495965718,4281354826904922182,15772072412720910161,3201246150508991250,10601265435824663701,14433771844487027198,15449795499358412526,6425640999701095991,10574303462610760826,16641343744164010062,3591501761256127901,13011450135386432448,17710945156160561088,7113002754875628648,8061738022442840780,2205188227952834022,16718903528165773286,2499636299568888472,9493681020248072493,1944532759489263029],"proof":[[2371034189396442970,3474397899175687280,16180012454697027326,566933996429359827],[17161918774795219970,15146889380193839755,6612813710156882418,9340442434859124889],[980138991608020609,773405830913344199,15384669014219719748,6433728494514773217],[2987872908818141977,3695460470511986947,8617383769242683922,8405063253389604125],[17106238841224391763,742640468387448893,15269478586826298754,12971916551180311107],[14875643328300658709,2205678944944132359,11092181350810410961,7563012846851041745],[6414567060173891154,15451769358849230941,10030428480406503513,4622437500059525956],[13813425748783298653,7952654920585577851,11739426967172707211,3712414517506511430],[12851581235684914224,573308473288852627,2766323486375545659,18057827543021038158],[12751054157718278148,12992347322957883498,334859559236911615,13019458091444633130],[16659409764024153393,17641152548443592425,10803271124388681685,9382039948148851079],[1856024375609929103,13929077232349592546,17198008025044765002,7151771383133726430],[755148913383636505,8853220253541320002,11301200987805007477,7983271158518182864],[3508518172268451508,9363996916802862673,46115867177118099,10487992413958736194],[12170382144320295219,15316582273223235522,15114258973011271760,13802403247793345518],[3578577681730767450,9368690041651878747,8495338200155419042,14503253077421831434],[14360254976046920197,13783054700758641950,3309149013408006006,16355152192614615655]]},"stage_2_query":{"leaf_elements":[8189162610646094973,1647053895735833133,17184420239042505118,1953256216039858167,14345200543589847473,17458509622149544443,8679248949495318325,8113882235395011185,13162203850734330672,3174441375554668703,1771015947883508688,5613138439504268057,5071176739558259146,3749987355665873783],"proof":[[9603187022107881378,5444143032231019794,13913742056754119957,7878062091417308262],[2123224290946940867,3148591237575365951,4173251177447790995,14804653010399127203],[3181496276541530608,11506557697807827047,12462930636886235039,15145530044032054333],[14873609634821919790,308439432115349182,4577930936942324739,13915815590615143358],[14189500441990512072,3514523847637663757,1165007498742868572,6942214256432560363],[6855101660146637510,6649450956675004648,8905137077550859652,541638800980893228],[6416614034457999959,1376202771208352115,645016772454636239,8563114641952166916],[958295572404900147,13247272800525019831,2373453924528744250,17289809183897882686],[8960999726885999045,13402519384300977071,4937203183774998119,6289975814954964600],[3054479472643922805,16301108479488066959,9240958853520826958,1534608375576898926],[7605478829844357883,545116827078330644,1931126022625284845,4857758040076531297],[3724765794145463866,3423680882641764281,1331557735584816180,3413722762311800221],[1112617726077964113,1432298953749638163,12292877844574619880,9434320607175730574],[2452514203319781315,9106741696525742360,12275052977719759274,5588259364734025883],[5770632536492503622,12459324890447761475,16182603478842755542,12057744867413335075],[7958101777751158077,8726227828211946912,5553939564125435842,11511246841708928629],[11864390066030281953,5359018194481938259,1771580212061568733,1445833475109721071]]},"quotient_query":{"leaf_elements":[14291760601055962211,91175724547660150,14192584736524571945,16993291927837631945,6486419113207714464,15203116060864480394,16193856106455392466,11128615414948933218,17273906129877437635,5157312956960649805,880906298396817581,758634963328902476,93337294486463869,7226437100376524698,8292109740939799688,18401724329819892475],"proof":[[14164289294812628336,3168411876524345864,12347273934857954854,17430024478265483746],[318942377141676903,14142644660905605820,1136064311872492388,1554516215295118175],[17045373570181010771,8298580344261440886,13611884407411264465,17743041711293223209],[1113178497832089943,4188724043211006899,9457204288322588965,17113732757219943891],[3901852942115692213,7142230327932524272,924583201547025843,12841095660266687257],[318909328062429448,7207626832081483525,5285749420814601359,11320946642446015424],[2243046396640789933,2480362049868132067,801222350555147387,3694025768887340163],[17945121188856035380,17668907750750649873,1960532301007637707,9568601010553867589],[13206640423014774228,15962419971684899048,15917796574235443904,6110429821885257966],[11223786017162050960,9566590773721922364,12302757997786863109,11712789320170350912],[94754957738324060,15567935482722662372,13752384032949343336,8793723896142270666],[7240002987759811105,1993867464653032700,13403588628851136403,15682239284672376883],[751862768679400154,7778670220596373462,10874151373435875174,4241983915251727120],[11718716569603925805,13210139683568195532,6335776117199783569,4851228550621889684],[8749878877722433889,14674387953619938387,12520714061342649950,14022913669441296749],[7309285207040950022,5286909053054710376,9871809912584387952,9779050189155054069],[5394371064630256703,171910951916185763,14377293751567218100,16749361516179576291]]},"setup_query":{"leaf_elements":[5162472683418608628,6315041640548984959,18266393399943574055,9510937305074806360,11133360595335350192,5227425196705878425,3961886745332143560,3599537255004622580,15132158283320408248,6497144314819493574,10065619045201430992,17772806843474456714,9335709528299935893,13773766887888770258,12012304483664536420,8695458382394225614,7247068804237973003,13808742653340764688,9310213294900985389,13267485018811679294,9924057834022080260,3977276108628006772,9978623801447083159,12509863997703281693,12103877108532647278,11853022769084707881,2540777504409972000,4579123657586171792,6894511633883152066,5741530155877583729,14695630940644591223,1689801137708297763,8355896658161447096,5121661424206515786,987017230022729104,3778645494355588865,12626612930565272951,11029254627589399358,6891255159673169165,3322959764695618133,14872902777156385595,18128629471126759527,7632791223907438013,15453790368653871915,14360915802710531213,8944117128300035107,4761307459743821846,8196698327845831919,14135418898505155919,1828087877995389620,14275511079340949294,18187728252620662586,13220654975900714824,14999177185283355604,17908244456947101776,17219544428547871237,2064219067570397607,1176377771156701945,7895776027850479648,3235150547106136191,7854393535973680528],"proof":[[8868989435319915061,9065302952941826362,406981807803496196,16637038353918526342],[4940237644379428431,16326645086036575079,8095081768336509444,13593938520239246031],[15100498458204537049,13633902627088148912,11928508867149898164,15869573325628732881],[7671507467144603618,5327816835703420077,9467565734077797681,4844019112025418756],[4509639751765336907,6965125528239717984,555830922454458863,13934359949635425457],[3628793880306316330,800809612724905352,18090914376248197651,10586008836324076944],[2587565120278222198,7798430577235423010,12599374558308819902,3114879246901880769],[2920758036466257078,4639217816822593175,4436147169228455373,8430418878802922283],[17823994823662287457,9306364267811051557,12554328331156088747,13191528220707750218],[13300763582468770528,11566886814399742253,7382338327181795393,16831155577940362848],[17080894646389501025,18392003666259016068,15707417621517092910,1425009132936369829],[9983168384944057310,12219294049560489718,2007259597799798877,4571421041353678525],[4889330355768010267,14652382920773313485,8937246768236720463,65634883270174303],[3425680085323760328,15108941645938481812,7974967502562354630,8296142830533568822],[9984115875480147999,1786344342108324714,1525444747856584751,12382626575244589260],[17767161948896404239,12128630444799226275,12889546133131274520,5560682659236718347],[3422028529044609166,11361892151387542196,5942325074154982037,3638617755446140525]]},"fri_queries":[{"leaf_elements":[10105186669025642744,11671174270624105870,14482816717500870366,6492260887867691502,2935246013924955837,16958664572054604583,16212151645587941975,10241056283433281917,16628924048875965158,617921043216511687,14243420804185126416,10613518540240411296,305217464659430826,1219025236292592522,9384638037453750505,15980285289513350451],"proof":[[7222202795410264323,10450682578356339826,13205489602224018884,2976833738046674183],[26584685725643437,586864733504028887,1572029643658666395,7577063304543687576],[7030486062406195039,8053411060663855369,15211483703892420671,65428216088036311],[1893581048511712750,11153492872415783328,8986107831228291300,17262638605850974276],[1550657011032407227,1700263352781169630,16557302784066023114,17579175412269003369],[3485577420626911666,11863734976231880609,4688378910859091342,1275179675559804591],[7168256596773697420,4137130678713109072,9249028552999846322,8072430526556483986],[7997110267594362605,8399520838715880724,9549155876920808541,16042394324529029457],[5801774395184435041,13920066733905480725,11692744522080957852,11563604240842942920],[8086488418836261434,141806546385551955,3565766562215288935,10821088455421753565],[7930419978737029760,7360211545914640996,5711046685779695661,7595878794711614974],[12808075231415843888,8115143120178509227,4706806155413227089,12095478606376694431],[3824951571980252343,13829372700510553261,3781543313594758519,15558384282967267079],[7840903004772847643,14024754441693974173,14247775127813146867,9526944857615598140]]},{"leaf_elements":[5712662966691347248,9720031833804241877,3689010506016208816,3388527135081156228,15248421968633185138,15629764154204784378,14471684753396973167,16449378551625602065,8688396076444608166,10137041902154774967,11433693218794660144,8043088278052456243,9307481306350016959,3233422765676152870,10486209293873256806,16663033907927066392],"proof":[[5173396410381180361,15558301662710166333,18054815085702406701,12924725825287303008],[17988589554531100405,8848453214653888187,18231866516499747215,14883506191565528212],[5543047923221669062,2335583932967115592,13192020060268061200,11194992540733091103],[9006500671076667463,3012226957917689292,12677219743685499502,40259894110332946],[15642306057572964550,11940186341679069291,1004027799924956352,472891185616914982],[4051193410772123446,2379335320456487029,9430396841142564483,8943080628356136963],[14954487530822492995,8519076730810036247,14618539550929273145,2846834744168930140],[8020482278533762051,5178511779506690111,3470285723209065394,18430069020414636433],[6136970361045632262,18219423925160450585,10750646977061759973,17818704382485679865],[9672708972991563690,16082715580302132280,5634558163615158323,9846845885766824582],[6338019957554687017,3774989019719914295,11012721884966440916,6175155909534017473]]},{"leaf_elements":[12208277025028107485,16969680838786207136,5185249594882537305,3790389259268236849,15150809812458723844,4921684969318485704,11328015653650425299,7937974441241815051,8924794641493465448,9468724356319976680,1173750046442604951,16027302654288605154,442847869349046241,8837318272907887883,9034275376114693407,17803384854867917233],"proof":[[9363375082284131398,3430680797333049910,1322100963002889380,1968971046218267623],[16406861539546725293,12074727065512790844,7300847797996960434,16589664456091706700],[16534807532287321975,1025353824837425766,16001877163843386812,15751114314489102424],[1181978501306684540,4210483851852727866,3110071400968157040,5677501514500643317],[14736561742026518272,16702255136417294196,16561165092407415003,8156264276644679478],[3824521549270918812,65916904110827401,17446941446647981378,1971026545301408778],[5689552255545572250,13642051312036694673,474208301744006748,1297421447072192074],[14852921497236026580,6056308775356446436,5081192679916074967,11837940092280243137]]},{"leaf_elements":[13064116131893879811,16309244435229316054,11629802870235552737,2360181946958123592,16298025172470566925,4994334429637449663,3842686722945763442,16923575914431387090,18048637633733766860,8620164870009486341,2294091535146140986,759379218009766357,14128206925732726030,17595941162459605635,9092181824652767842,7118872078173835554],"proof":[[3797200574238884745,17348208332315088726,9532591169645403342,13291441571587887120],[14839032562963523903,17046133048863152150,5296042544302468387,4328598669284153132],[584241377793112636,10097503375860427864,8314501640312962481,1117967874373294243],[12845460761330499996,8139816836023143817,14831815352913686601,16460213017710724933],[4837081316476379574,17344319629916935599,17155719427621590057,7011703269203098561]]},{"leaf_elements":[14968711391439378229,963467806984571479,14306583974025167081,7104347584547286118,4368706363564135359,17056563709916845601,16652339121395383918,2196603890549495152,10183933648264432715,10572024460979223786,1855955409608765061,18187605291697367590,14163378767570664432,7276619975408381486,2831341808196257785,10140426061521276320],"proof":[[9760356211018575664,18349980715526773400,15447942603786629030,12629763578751092262],[2884197219044505094,11055616854069026720,834821751078496710,11214729858909078267]]},{"leaf_elements":[12282975869370992702,11687375468371823316,12508039798195106691,3972052243724357930],"proof":[[5831649766774482216,16719406146370762377,4952797128536035654,17633464091822439029]]}]},{"witness_query":{"leaf_elements":[12251012839438618916,11044629409676839829,6418856724406691628,11311102823519039807,6057277046554756483,17105882295635964220,10722870933810150962,9627492398268535201,9896349950475003686,15979229615403238816,11152685612313044689,2906745809302147431,7306279299230260819,17053043389278024527,1851190712250075926,4148799167240252979,11179778144134380359,4845000991711840863,16572816590505217259,11987943603872782561,4351472126098312902,8578350907119587700,12945137474145801711,4802212141416257011,17223754177689895225,16557057803767273000,7323088995978844577,17612805178024858375,11332952910823642094,16211502309674624172,16687515000697952253,5894967058351514582,11387876700644006025,5739259686963603830,1597160346193270777,8330195674958360246,11418064203664017950,3889925301276141110,12469683759339994693,6350834369438080896,6662362515819412403,6743983704715642459,16053738263967315301,10447095222670293754,14115598737377320618,758975424044311337,15881982310883886908,12568028868477477746,7061999844516635319,5304485004495105448,213911691584777047,14397548851121201574,8905597702144355215,10342727188001138670,12226420954385909088,16328115046360974904,12907785833933881456,5069279097747433089,6932960064430516275,7193234303202930077,13482244453493321343,11027502591834216139,16690681025923027748,902995866036852177,11349147429417293160,1108416102576113084,14131238402540284350,16904095257394464002,3009925398396027364,9043661968976792966,2463978938691571192,7707359967921547022,6192662291019210238,7425928276057449292,16608172460134973606,1569970127312169276,4709552725718873506,1308255638859489733,6570219053842993993,9731388377351800974,3208613341572288244,6274521479297103102,310417517373137282,9054773340976042946,16640397482414982133,2282022178718596183,2552388775046022166,13020404005519338051,9320165234944929289,9305964790166530238,11893027689558430050,18328289211162424073,6080756594717397411,6202275574760426000,17217732399578898259,4979372713240375665,8550398571636041984,8702834574157032475,6667507201449733876,8565988078020747375,6971208110242684478,6134195620001718769,14900441617678273424,7424430060365171538,6389052720907750371,16596042215464088622,4118390310089081624,9824073385036861534,13472849382138894175,8695534619746044680,8637095290992403383,1246642238438221546,12721003077965804967,312531799981785547,10978304613794485885,10377770480002649452,11613682376119251821,6249936177833321585,2625368763657041212,15949931990887669861,14567310628682385753,3649082438112321378,16058841558492925414,9718434400760334326,13827564514386633356,13959306026050280655,12387041685011740022,4109016225108369716,5874086694176185407,13213027257675091143,1418347432078646322],"proof":[[7822050696114148706,7930386108879514356,17436576340128397431,3664593833370509063],[4819491672085797015,5733881997934141458,3992339394897359717,18394540103266342919],[12616240223617503648,1135969591677202605,8564346621626873026,3229772474404970150],[10290268926212259096,10048888601115422473,8723933825187637388,6690556001694313822],[4912182547407557016,6851187343554288654,11702560244325690698,12182396723480327655],[4126017058843524282,11155599233573397898,14760282773651829532,17213139857016456950],[4513731612882595271,16061585830580508113,754086979295719646,1903182683633232558],[8523171354319260981,12113841993535433063,3092160557685435844,4090320652055002747],[3126648800374272547,4672260196590882917,13829750621579343748,5933574510346950321],[6068539133416163146,14704422386119072935,14770837603538866315,4295901907072708296],[5537763076384161164,15737050783708977797,17317465364597099286,8682747283713306874],[4335219382401610773,13026586312787943357,16008242398759439470,5729530011495977581],[11284562356109191067,15870309599588521545,10876914295339334526,14953576296704870079],[5828544394612571751,5012957214315438013,5038203003983522890,11580339159109027150],[8022815932793991745,12524449088216984083,7590565692081572831,12239851964462117016],[6465130926526020201,12275118955649157026,2316020815235034411,5261159220131389862],[59665264292061762,10434171546492780701,2465697546388061308,15079588132574491021]]},"stage_2_query":{"leaf_elements":[18203934961532593432,14082381334046642312,8028717421258071693,14191134513469171778,17929552839611499922,18440515731243729921,5888866458412715662,13723152039009848970,11325080746938075532,17265410228067888323,12955891397133215175,16611626206072061867,15458563599014091034,10540704535607699282],"proof":[[2605419983304253973,9873358628113265108,14157016044872675512,8819146615760239185],[9684043527731515544,16122564134061411565,18408983971049825731,1337747083031333487],[11578291725599201606,8340735724746300228,2924793634839236352,9208801038425206317],[9412751315500830592,11086734871591684798,3940108449737499826,5531803521079523477],[7309766093332099069,15245773827544722503,15698057782028833188,7554182189254013924],[8796374378714319005,12987127207007706933,553365344575571400,2647646248668597849],[7072941216623728732,12872441060412667117,9492806429797981972,16291740991375576571],[15363983118125144412,4798671296791617479,14554228972475279664,8701157198671434017],[16136344023266511274,206588854380212463,5146444967335498678,218006071249382675],[11096666194346123115,3021405080035166409,2943935324433985068,5568776384604679274],[9038216326089542534,4202747875842069146,11020706702124174238,8639874000262083214],[6529516322595928443,4176614971577358046,13462994639439126128,18157427747045577737],[8967638861285259722,8388066331564082848,14915333614941559544,16378966129775105860],[18412450839767944441,9589472408694470224,394149566196545248,8994486590075727229],[2830911968501051073,13871975484399408505,7238323093793879692,15609881873003308481],[16299785444941056938,2306532815250644529,10763462678764195188,5764349433605221429],[14256310723838750342,2800151069131913519,16987067277141538976,14612400261991695567]]},"quotient_query":{"leaf_elements":[10678945866376008891,2171033567419960256,15866732628167198821,3861491190898866097,17629770572409902120,2893753809833362251,9982989310976009750,5357793392079030268,2844055245631960491,3359676349566182733,9100005042938376643,15435134009865221508,18017639871428163039,10092545971816349823,8684748190072335332,6434575538586180134],"proof":[[7867978843649402870,13920808921854800231,725222291664962871,4591000876447502651],[10489922243355982597,2428530608091618449,17890110230617417205,6229592871807865685],[15157622909403432456,7335926574924364609,17886092613860002157,10203662474823638599],[10936266520247784503,16153558500478661821,15142595735230034026,16795952583593261731],[9497041433623622294,5329135204154662111,3347700800326124290,3150270735907447534],[6966932421521764056,6504580855730754782,14859200400784627384,5880188851055263798],[9355677756644869200,301199182718439298,5883401478798693023,6736983724217493167],[5308811186062646523,1443681024702304722,10113361888468466099,10022410327220125979],[11401055236892261553,11104512519041794305,3230131376830683002,15383342795339036822],[9058487323819639893,17238443933344018128,6300437992810944714,17454921557139338333],[17930710664666393046,5950955407318855543,1847744452742231822,8883798066777235507],[16753647684285088009,4774980043310377982,4238867101242267237,3232684756492336255],[8648520569516976302,15715576330842954414,13187695886526757302,664366760378705148],[18141253037702087348,7882263372097871491,3310789905287726401,9330220346411617531],[5035658251459834143,18413681849241003744,6783323213722165114,6630674755097126151],[9627594401287154996,66842368668842994,9311993464867505197,11472829473039691407],[2844704157790904070,5548445532181214379,16485542245719371347,4771224454353680271]]},"setup_query":{"leaf_elements":[11671499633365681709,3725107717170509792,16660038658431548654,4894927179962948760,1265598911601150716,16341779597226243404,1443055789079527354,1966419683431303286,13227302043579450680,13276542419460281205,6031039782822545681,758560227026651893,11687371366813515036,7559889988489037178,16823086662763997309,14689046343324776626,6578627024017954001,18046424280541471620,2362527767452009830,5930095033006880252,9565731346062661621,14392340185971678616,8151519748295426387,361363958454600491,1564434521794960553,18246960228825692968,6181410864135289124,3601810499958999266,17433593950193347998,9734766493383733373,11541824427360771114,15763904185359489197,1518786638048215195,2500135133070349099,14706552086593160617,6351705058446144280,6014159881724770108,7912533895378858620,6722537323227626662,1896432829949204667,1569762087785670478,4937798513552761143,12930239106476630449,8484237596689113790,13695407125578447530,3147990162038658209,4564739119048300467,3445562783066371718,18291794549629914392,3415570352723374607,2495991168609038794,13499696712537877428,11224807834992651041,8620772578767697441,17580043499424464469,6815696233940107669,1114904911192094112,3030693984001613020,10865312691199112918,17600234796545055823,6427209485421513398],"proof":[[14967040974236554052,6992809853354235635,6538101493342499991,5468013553132312254],[15839186147972640048,559984404834371448,17992040397426742827,5912298380275542225],[5563357025956010205,2320930768014733584,16450584054084116748,3129788623309520557],[8037838818073754314,6041284085465371547,12671963294064626253,8745414624128627746],[12035818600907279620,2579996990050076614,1880991578878201017,6457413381444713820],[636206460450240657,876300318444331957,1421435030258935184,12832331822362295203],[4024622817677908436,8148824379021154661,13825799010640257614,13900844032792942610],[7109136587197754538,7910475493808266647,13842064683555824018,18167362462169764751],[3327008895954415406,5440564327996461636,13084089297909527580,15031075582138470580],[3776242994069692756,4347324236105355660,8402806328811314812,3383468889399442179],[13834875340769752498,6446522421324956431,17671186069923792489,7836868049614997026],[16127476054127325217,14822298764644598166,6932315002618166514,10370500696401368940],[1403938532958985636,15991451644012378651,4106075340201410934,6596428342866769561],[10523729008145388832,1140205076533410775,3529126245296042189,15184144461647907011],[14064028140249803374,15987562047908615583,3646910543357030118,6935993379709279143],[16332680959861951630,1880936476400605025,9315773365800687881,6540647196803212629],[13946498371540021611,1863300965338470286,4282947032581402,6800393994095340878]]},"fri_queries":[{"leaf_elements":[33773546434765389,12292771204843608642,8032174296677993926,2485137931153024825,5762579817006320270,8556573766284280358,11530045171917176507,12319409732827391057,17624259120954772320,13146194144495650825,13392105519255084066,5634059064100702171,10871400225478092128,6215479744298372387,10214384049127852388,6565000491288534075],"proof":[[3935190710307941851,17520379915450448391,15779474553507208024,11385220231590085806],[15324243557180757233,14181104626277341420,9219152907582387742,14254796374575805766],[1633304157227166279,16792822943574335012,5350627343737316658,15418741336457556960],[18243511268011893992,863566805342028010,7507791992579692045,7173528495822286037],[12070110301613925839,18322354062229877855,13458578782109710511,10084378178614874979],[16023108637451741065,13640289962630445842,7862253792896510441,4995879968615243531],[5276295306696265283,16632903716883282347,2365061478135935289,4476827931535038009],[2151295854236874501,10905550027076052410,9955340288478706244,5715997466479437405],[14383994481828847968,2418272388468168001,8878200241227094753,17164101133610385694],[6920047540257853871,9391474076014687826,15678771851532222420,7035262043669104548],[9824436170207524358,5504644129815359571,1263184003042548053,16270381165210091228],[9719116704334903489,1399850082479250002,14158886724586014729,4657279767999128929],[6333778296118921197,2547260159915842042,16621574571116674122,1902638454125312930],[4175377845256475459,12067527558563709156,5489896183979920856,15310067138133132503]]},{"leaf_elements":[17832896394554982679,18127022317623036864,3529716456187410521,4833832078069294859,14324051196309795860,6566298811712209741,14273473800226918520,10406813872476922192,7253603269649702691,5354689745389247143,15141887254229557956,15836973959757476471,17457459247805023312,12545688562884275627,5840146829190219631,11114507608970070011],"proof":[[9802993361567341166,16592432335546803824,5163176560978546585,14932176970620479732],[7458430879363673290,10251746037239699944,18442402956165889395,884422979598510501],[1042211435782615687,7198489503905021479,4503796328198256957,5032297218447176024],[10706750161571585627,9092116013742100808,10371211058100285706,5279357605798170953],[133647835952194747,4536942889650053876,7986885330827173869,3238357123345780679],[12611748265042781375,4454612280555262505,6987389691948032691,10352733220586310156],[9978655604402338096,12114075947840922309,9084392815952234659,3844942950790591206],[4729753143604186405,8652585575919726494,12093347193603116476,13795137554566266754],[17098064852631272475,13499041307833535154,6474843969747260007,15383522702147279929],[13796238161845381314,1689854490384974091,10922380055958145910,4030635777416377980],[487553425888725415,14524123842849536983,16167997028897651914,8606268240078866823]]},{"leaf_elements":[15119431603941928031,4513873217425651697,17013432777211349944,13862423212160521622,12651426788718997691,611691419304280174,7840123987857144372,6445998063892516885,6762839604169866043,14681667708087854783,11608427883926749502,12230331486615412137,14586833044239713380,7445862343613509246,6288973230902263180,6548883141210513209],"proof":[[7048281710101229233,4449588816087583837,12439588078136525771,9674776173355343071],[6129796754692558911,16213426455148920975,7107288296861606814,3780960449043334209],[9180490516641905044,14974906688297709903,7017328867821644962,17119661731878900697],[8099180456425736713,14977860924590883450,13223896703245787278,9546847880424156454],[9802236181136467400,8774019744235841579,14237959028754804850,4080226098996849128],[10815735703945678213,4198505797776305949,256517067184002193,1315787259904397652],[8468287407270384933,9393044823893171390,10220697177982084814,5950616712974928206],[15631013919708760344,13957102086129007903,15042593718768734335,2165418342494390694]]},{"leaf_elements":[15877720521438536628,8896968847511538636,10158510662088864851,17644053994475481035,12233254136045657919,15107742885530410353,9923711327723978878,5827229341601671047,9689414573666623902,11534269060431292718,1479647191811472472,17913558288682071811,12467355180447623715,5406057440296005521,9258291678579798459,14696723538016582474],"proof":[[16675832405357011733,5704831852617209592,4356074541518226513,7534142977610524162],[15667305405053353673,4212855471269341608,11619988169841610682,15853206916592862023],[18290320442281976189,15190205038671547159,6839659964067676981,14457227779093654252],[18086233553284556549,14429244895173850159,7898404879322263698,4840744845856856368],[16364331121954969187,4601959089981859452,7140914072102350626,14457067407800960821]]},{"leaf_elements":[8745308740042238805,16647571482788522826,4599130602344952848,14730457484867141101,17462797894018968701,8947050244195085478,15854559767511441534,14101750176731596693,874227424088994859,6037371780961200255,12252339675926315433,10055296358249208924,1301543401768375393,2344955058781105364,614467669777940229,9209759284115613961],"proof":[[1545753496571960937,6421088366302616762,6596032508088440103,9787897082650712309],[647353304559108532,9275611980771284708,14730994453731046787,12330307950258318096]]},{"leaf_elements":[17864432177839986878,6105919159902829140,10412865070070699466,6067226971848765155],"proof":[[4315079671113271930,15110831729224522313,10275338276838809753,9399697754263435268]]}]},{"witness_query":{"leaf_elements":[264816544011889880,9100206721462844817,16371182814510505828,11029891574075681112,114839173021102421,12926636090927564382,4113572455483060699,12770947233764427989,5471980450030209636,3042065778784855043,3231675420785993373,10238539570131525581,6102383132985187762,14207291537771591946,6902628691634053348,4712799545147774635,9593677457859452128,12957027159655912452,14673350886818675031,339086891626313122,7346776085013100711,252814852427038788,18297411229050931427,2096766505345929021,16502374146837984464,7195943870146164456,3341955210888774929,419661678542255962,5354961225686496836,12631098947250926581,13696452074539555673,13181030329224775435,11793727240124648389,2154926797114768058,1972185245360006897,2629977036841428673,8732607497521820397,16724930960938007610,11577387611887373062,8114605280188006257,1828136030294006152,18344348674183380935,16037461336176112971,8177884294904035649,16456823088532174530,5108169279923228648,7027604890689666452,10136944016725449383,13469708982749599648,7290533932404086958,17310811993672070278,585723470370405429,3269950303014733540,15904586778807491516,1261456168388921667,10104220497263946502,11420235251485001997,17638795180339136482,2889821056850147515,3087010361894240115,9138858340833785361,7938460486396315312,6635425569107821533,3805322558342516699,10053682577362594127,2372917694545455457,14685565214710122691,4636548032166168514,3762176447105314421,11640453484474652154,1126228298337772775,8056517311286273896,17013309749553481006,8356589757719639672,3526581373421968751,16884675847418131579,4140134816356268814,8109296126895275452,4100975683645024927,4048179621440526252,8960237653829223202,14273556668432430856,9393521617025868309,7653652290129668927,18049089682508356894,7839560841225589065,1353815406680802214,14361635277692182804,8729667158894607595,14663318243796473526,7894992374297737443,10116604163868612740,11503649948038582030,14501309640519564635,14613955804222481245,9738700651836013286,1773192617765880001,14044509693456414535,5906748761830274313,2490155803110702467,3597436337368156160,4875085068956771250,7663515299904245883,5166713500573483792,12034906363923345066,15292781636921044518,9798748509320588812,9497504102100041671,4798537533647892735,16566156398103293650,13531655492486968269,16704817337878975962,5945869046910413177,1627411616278803809,568341237088167381,320640716308520881,5820383818439577965,12383681291458315453,18279521763355914554,4667643228410627778,16484505634593434453,13806839941987437303,4226171953641129753,2253642325405769835,1210534585745778350,16084417729408389074,13739893394980278965,10597832878689077847,8681005279204652314,14903886369831276106,2431971655536136599],"proof":[[6035637926535746335,6172153563047897215,7286731465909536385,12694587054009167412],[12393104077307150135,11074597688791469270,4384283427173798544,14567332532551781641],[16385024312737298774,2061992425270593996,8222830743859723864,920489110178723243],[17498293418187330621,16884159538757587058,3432118210164913319,1109930605414412628],[1787933341103026509,7816458760190846192,14700871526752165873,9058830588318453963],[16760975491488485680,5457346698472274215,7738393219525783041,5092886449068807077],[13346692020969767332,16808397458556126727,8123847735035527532,12882439303404054812],[14290706439209463006,1011016247045115990,3656424116322492510,10429170912755534863],[4771610727590541148,3166428846208584605,13518313042573071991,2062208179222155797],[2944036502151777040,8717292275038319089,2651582198107748862,10723841854283402431],[4950344527290371137,17617485727701485237,8895218079566548165,3027074247450627943],[6990853650742262376,12505606562534551957,15386941327102302623,7482330062451144110],[15913099373171370675,7020052131760399862,1900495190492066544,2097410656712802911],[17042999266950702996,6282524089963252582,3218752529120439130,16507876374629260253],[4589748493696206751,16814564824157115378,535275882445080352,15383369079621341387],[4949700806444390849,8704934912964472905,8339976728649815012,2720838299478022937],[1711941643846476557,1041760448514689162,4586553947365039558,5936552928679352201]]},"stage_2_query":{"leaf_elements":[9838017781584805749,4415699383860842887,11167778547026216085,6802997581383366197,16612010954724373409,17135185333603296873,16457355591375822488,10910564275620831217,4285989769415264,18334866793914130511,10122652734772725488,8966595244832788148,11808464198943386508,9844094685150366771],"proof":[[6428977631091561822,1804579360059083332,13704792552953265392,9538062648490749081],[8341593415373569666,17725399937674583455,17650998340409379704,2631498318011337525],[2178799867260443020,4660680451042208074,12627953541253948062,6186480325744528771],[17880934737832253318,14007759605220355431,10111823313334776085,15364487985908205552],[4915471114590160456,11819798560419687458,9928904178836666497,5031448790581982823],[17455157374857379832,14359171957736859805,13733453114634349477,1857490311734080937],[1982273739862120251,711955519094923557,13496330044561502918,7014833229996483701],[3862968795997134019,9408510120229359086,10943409348386625008,4053053428855701721],[7832270994808308652,11147970213373570245,3970450850120777311,16999159271917454946],[6996561284574802657,12768613396895082892,14557299584375194994,14141521342000878395],[6738705276296609739,10937001763871678963,420626775437188125,1817775337170815870],[12246429044071313752,13844521934794928422,16775635639134112331,2723144417236244979],[13658292311152468501,6799851925039314277,11021595635673255214,280847070612438756],[1904334406245937973,893731082258539505,6082639590655470629,45379334875388114],[6105270714402722971,1168222777729640756,1300928146037279261,9276814491033684084],[15457416554847790076,13873584533424750966,2918620755871963935,8988379069555456562],[17541018358015783929,6049016812875881820,4451295632130130985,10253218944408934589]]},"quotient_query":{"leaf_elements":[2233822958755246015,4182676788328394032,9728336832123277323,13510587195335206279,2912117503495125967,2068034756587133740,1911390444027595621,16297483492426001278,8263602476620633841,4635209342471495641,9426313949729885549,12798253122005018207,17720786977969879498,13249991157322034078,17092288564698459976,11195085327501662689],"proof":[[4843240167648415389,17801739438246248048,12037882108184044651,5360843480957686651],[3554345733145364775,17241593073353974741,14531870519952374420,14401258718656416281],[10350158445189826665,6651630160098788101,818998412376586593,7865050845053832455],[15330933726954766479,1885324687447333283,1031965778130548220,2404578809090808308],[11430381181049626697,13127856638351786174,17594215801245151830,15533953036721544334],[1716636433328826831,4350068362216993356,7855632129756045579,4000933413379280562],[3422378753076908797,10247841364426973557,2082074688360263843,2633067522044999766],[8504005523309596942,10534591356766750134,7776159276500845471,8957646949149689532],[3712151616948391786,75664457811018685,1526261906919506371,11031272299523707723],[381204930050755481,650913144234020497,8140955379413493356,1802220249778075849],[3920978558623232066,7204733221235416667,6684475150634935186,4470006324497921746],[15778876352730073441,15088227052390070690,12803862039174692301,12799224219793098441],[8942870634773248141,17478731132897322607,2181156460285689550,14993500231512888890],[12333115368796398646,16429292609990593706,3340578921806343729,9355659293938878594],[14099646069836590401,13648496333253251535,3352704064307303725,10287816646704449120],[14002509234694310936,724921960230320463,17938253895251108301,10997647339320879183],[9055823150918635942,16926810451933254088,5004020845142725221,4727923442808968645]]},"setup_query":{"leaf_elements":[8044958075310299967,10580296664329979879,747890707234895537,1375864015050862298,6629859287237248060,9059282028528802423,14056229986428623435,13144042306806718497,2292362937370685634,15729283150782104195,17338170898704390558,6287846123692775799,12243310779804456599,71428985507509563,12317042288505679468,9116167228111336921,12797863430281385151,12975368175834217389,562195914971770056,8908399821352265281,9816923313528218,1284704691593444784,5917365942523319263,15982929124138854722,17470340843243068064,12824833413767576042,9453930770717312704,460336658191536217,11713940065478282452,7310496257094645139,6827738343502916124,10450948242597890530,18032351171936870092,9133148266569096762,10794814818454815387,13877374717231988082,17700478951305946275,10143829761648522748,9330493834175345458,2887052621721935233,10630683735471890470,9618564739592166075,10980386287627271878,17924251000852780851,6748787420292820286,18071871443066833552,9554217789774702428,8840143972049371370,10957483895290814561,7831502418074131908,4741733234918082795,1541797581525837859,11344539045065017971,10473518465047392594,8568334389730520010,8766661346802321621,5964520263878710032,14641590044976268133,4326677379070878815,3239326944739840374,10413740070801069092],"proof":[[12880705920786098027,3179082652699537848,15993699684463829574,16299979726576027017],[5814619301427580621,9290217550377884824,17344788660192476898,1783600336504320941],[10298608515946507144,17307169603652056381,1645071885380042211,11964206625039838030],[4704409169439550326,1410739185564280995,12475519689333320951,6081334857954270417],[8636711978829569208,12698570042533840191,10239607636074506674,8620099325056854266],[12514578416515981548,11065346893203199616,3187562613520962358,7606940976931404209],[3496484063196257125,7290706528166339958,1005785820408684113,12670369994525526488],[17140464401604753181,11893028395617178933,2184662570118153583,1108742033565981887],[17750998940163333647,5396667742692444718,3693495928293247334,15777543598515572859],[593646632120802513,17327840722825740133,17563106826900971930,715438210608533042],[7978647667652789007,16230163781425016519,10879707748395236458,14699689837293590094],[10840982275988936754,14276268872073092765,16917837944062957582,10781868210577877410],[9431969477944237568,8073907072132900864,9388094453595871831,14573719491060564198],[14554527197249850456,7431170783991757037,6275932016830709461,9498116716046111847],[9267239203457059955,11218154518017790184,6232818837601094850,5706420075511243372],[14239157432314135533,15407674253766045992,5148191476053964333,6535913709950150630],[8060760968921501049,10563236797127934631,8960714643447367970,12389288049029494486]]},"fri_queries":[{"leaf_elements":[8655074616439010858,2186657802996359169,13394086172239246325,1065356538556356137,17787517904701409843,11054813861659371694,6147939571883761778,16019432344869570698,17154087583648086814,5178564593318587364,14740905208207824858,36545356342791136,9734523450424327927,9007706611747460272,7108360339290492369,18414989503208169662],"proof":[[5574491839820511161,10296653469252632123,13568633853854289788,9335835796133978253],[18274173334985916168,3904696736146964011,14776807837772540892,6571232747385458158],[9368916226153475275,17024966037054203019,12257632358044003355,11819042785495277517],[13977843515136090941,862726786431385528,16285404922749074274,13565836089751437302],[5399935330306844807,16729251490171233525,10735546795051355952,5997598129643592311],[5282022098833804907,18142816209959710567,11925781867254152413,13735706037474771539],[16915118287488916756,393545809077031061,7447432336594228497,11133689075850284815],[3745558946118215144,9023219223958924191,11267278548491947691,10799601512138975979],[9921993296432402642,16900654211713122324,18136308301651504672,12448163247842100525],[191713231511112878,917850584898395158,8026489478985469742,2154952973891747382],[5218961703821562136,830479574242369732,17941941898450855056,867899601523319888],[1475668377853706843,969596433378917426,11144161947033835648,1847891091792448241],[16088326129774234362,15649736898903869947,1443659414693406637,15006734175569920155],[8356855562427882806,138344385291786005,16876570439300941520,4831345395553603879]]},{"leaf_elements":[14483706181720620016,16283573117715677456,8494355173222718178,5880345256807681545,6551946600116623611,1060083239854345099,4346074840486508316,13678412632812647061,5241034375726804589,8011607688860593172,12390346211891510830,16431718600848805056,192360243598382575,1515631714465833445,16383561059868250988,405610177769459115],"proof":[[11289362006151511260,8491203343256017083,16426030412229923138,6351514465691245360],[11002372497852670013,10907248085244038576,18169317329286539093,9355192146420358535],[5381038048444805310,9938336662076801883,12641413579518418257,4838240635045272809],[14052001924339792709,3834492252554457576,16006752941517234594,1850607395231997943],[15075012894932935711,9401758738781020475,7883689514583227254,16877116112809279558],[15278728221997103027,14689333793046898251,13722731938625115272,3839854455059261274],[5441289573818186912,12855557174736134291,7480407440768719496,14557104332609271662],[2697729986803590871,5813040095547394959,9431730556776993059,3091617465760803216],[6698162838138232955,13255859318127883411,12886297981850784588,11315131756911150421],[3806010108964875273,9357343883778009011,14004075924030608070,12690108586308987041],[14536870359165088002,17151764549751829843,16174167682344499409,11319008214500805859]]},{"leaf_elements":[3701568040601211376,3133677234250238958,12557554810073614977,9281456023174686935,8131457634286970809,6289475017423026610,14482462815874798434,13480410674127784680,2002129288956239494,6084339177528905523,13249054043888770947,1182677732077379273,9098713932059683916,15977999261458656691,11159350453524267547,9727374634791973646],"proof":[[11969844369416937552,9315680707405206030,12084507972688358816,2473959685097642087],[11768487276149521708,10720541697856567846,13150221110708906724,14223689341145678681],[5845032321667964686,1786358027488424049,10039231850374745626,11980041387792687650],[13416097823631344002,15432253527507162625,5474187534602212640,11574860018926359101],[16291639668187459851,2574277301673243836,18335426579220443386,13133274848655689822],[10550824145807897548,13518980738349067015,5507624635251792495,7900518729013567319],[12675143277461708990,683920180895292047,10477362709097852495,7558372325472664510],[9612889404704441076,474889125021751686,1632638294239325987,2870759428578716259]]},{"leaf_elements":[14466105515605582173,940089211792601717,5273609729332526720,10522428382759242662,16470070648826939525,4913271038761830478,5345506269811447310,15853761187326495643,2909229431759242195,17082514885526327307,15387041983527257540,3168272490294737700,11066357461770470693,11335097462207727770,13724224405312172974,1440387021179960623],"proof":[[10597414453253567430,5992035461447251224,4277798817579661723,16879586768900224170],[820450294491909284,18004357020573757856,2440052887833168599,2191878494409786901],[17830846520901813613,6923211624728434747,14097882562757601940,3224547397028964959],[2481009009742184063,863093541631214110,4843141797297275074,17425943470581643279],[12671540720029004630,12338151589398362581,14632163077521151509,3332264839482766995]]},{"leaf_elements":[5347266332826093710,4236094711122481699,8098390496034471047,16573467980372391555,13332122596475120896,12850372371147869964,938895770035109779,12301395439244452602,11655881474552661151,3371003686809443089,5948168872933625816,5280470589847829466,12920319624524399210,2659144012711702156,4593220309244825205,16650568881285257649],"proof":[[10771430535566485967,10574580803217407207,12178888218844898847,14833344554163081591],[839918630665455134,6523414215569306167,6617368742222728231,5611367591847462067]]},{"leaf_elements":[4659846952855530673,863760315472701024,12397128288475891533,4082963753443573088],"proof":[[10408766427617841417,1230126644601694707,3183158647387215805,12448713826252515463]]}]},{"witness_query":{"leaf_elements":[8384801764497341198,10794001195353085317,448512729980262084,4360866730939276186,17407668206505374286,10377857082308311038,13260991594216508345,13899994735876600489,227765560360737421,10148343031784850287,16717898977456110020,3558343918704710327,1259120703535424397,15530131677332258495,7292528772670014482,5371559716224881985,9478764541745872182,8054681345093633871,5143757306631794051,2926223505410710117,17544999289621142460,12213792565090366836,2838629485568540323,4960122383265187319,14157608910094787109,4894965991853122317,7202262490049963044,4415430987738989262,905861300203840182,1825918496453240670,6764023849704587926,7556648165925844330,1968010564289577621,10060987372251722550,730056064667694912,17783051313637788143,10812318171641383517,15705307313521753801,8284707753933424415,12298344988412551112,17302615538883732355,16622621921048643888,5631069127738644438,12284641322038969395,13044740749937941196,9451065286648541869,11884586322532776032,247578772398124216,11764894152647602810,636943839911546659,15507643489187964754,2751701296457016699,7470450259383920158,14673891854600483094,6015036602362148538,7015686711837529175,5620047780643013263,13869034121969281442,5815788286380195074,16195776216565104173,7293189613585440022,3873947604919297784,5113449519337803226,4038192852753674624,10727391436058104790,16685135759921850862,13214516073269032347,6470773379074719344,6780096761918239437,13941696562483557935,8460980856917745996,2024835190060493690,16543589283337213963,13884406124630892768,14525534703588701741,16365457506154336572,10181923082767076659,4210768272880878048,3108196972071316831,2558865147496028698,10402333775744598447,16877776559322138951,7143265490170587980,14596782711354153822,8660321410425591145,2928389201640799261,5100356430176953342,2672274487079637357,411914403864564222,16796995568592652114,3335847034466498535,16076924521985205329,14817708295739146630,2829112264345225539,8454526410849146510,9044852684306997894,15084683062966412550,413435262923793184,14483261876424695020,4038819228008542282,10021111505128537139,1205815130731350844,12755552788840788270,12627534523471293965,14102020894473592074,12032521015544927901,12961244535596196498,2811946505222468157,8575618363143690073,1336227885889030581,1931221340467078220,10366128013842156222,17820076385203262199,18011713526101818346,13025319465397392827,8216926015382921357,16332988736875060159,5116164492752664499,5582399183712604429,13679977658934775512,2558205579054344962,2120255736569348343,8205032347835860947,14514494861618812513,4471705299322046746,14281696300004573230,9396545587415145469,2744303385227998017,15720085892008775319,13311623282476235484,17567140195106707582],"proof":[[18210587531518954561,7205119008643903188,10853430960352585968,2971395159923228053],[18117367485622880306,7117592974677903874,15371020934016739612,3698944831769585850],[7051631972221981469,17437796635715067527,7333111428317840338,4104508493206575042],[479995006454870761,17076392729157840742,3805273294077380919,8109883893806479543],[9356198387551013591,15020965403562167009,14782248007415463317,1416094102403706137],[4365096809856009694,9148664966192278401,12207667627342845791,18138403408851866025],[9023716564808489834,8821278913167552259,10557253990238096480,10463298177621056627],[3651497396383267730,6449436443756052544,4820159526887999544,15215554912345678814],[9407085208613641440,16144353257016742036,9913261480228420485,4865766604750266373],[10663484413701448358,9179544827237471028,13834714697518869853,8181432388414501040],[3062335506992280765,17017424252481096036,11585881453005981943,11658061430482070029],[7031558066198410054,5234860666534105366,7149752238952026845,11167207004593094777],[12996314203957314477,15498665918878495500,1837583084139060926,10320173481031021400],[8673506319216449126,16700471671284043399,10392575248067838934,12020152954529410793],[14727933238956341900,12722662394712252356,4605980276357282974,12616697264822919376],[696408965331914977,13977026082772156537,11235415268786469489,4205455148090181854],[1282132622456469787,9709099448380659234,5444835061337466334,10255491277385210692]]},"stage_2_query":{"leaf_elements":[10427390241697233462,4258258874838819228,10852660381623093378,16785490106649502746,3934969781898939699,8747378368418489119,2541825588010810599,18064000341645956150,10143149000304913489,11192561996975480957,10973401010775171284,14821336978349244168,7045974770278252675,11275831313530243689],"proof":[[9128097609203826456,4211496485964461332,15979406181427249181,997416671699063319],[6197585065347538974,6974404743267869672,1271596190695438628,9168207274823386402],[2015145003772955145,6482270133831430741,4472170835812278248,5453322867584281964],[9572862499494347635,18235076724504502500,17277651162911653108,11119695146717278994],[11736081892653896710,8432383503533468101,7439873703675259619,7815660019760711816],[10586472797777610427,1734570950470818878,17897936434999752795,7445004402661859911],[3746907771784577851,16602135118920510128,5985528547992439095,9772960653142067145],[7109165006633846236,6069415743871523320,5099136136013078254,3983952476924989699],[16254448015046046742,18334540682863813941,5312660013657058478,1532035107026195081],[8348484708343025002,8548033442666855165,2099575954456627874,7184906420275997891],[5675625391081963558,2293350911061060380,6791783385974878862,13262120129346398652],[5574554942020443272,1859425376500550406,2981843126164042933,2219134856584821206],[16866297965516291511,5660174945509195318,14608293629600083099,17416242454625119167],[15116234172307713785,14040419183787241997,12863678700842805015,6196357924962233903],[17529316026566977056,9166821958035461154,12135349448531937552,16806754547632003726],[1698808707324330327,5847818661641387231,9472890324145089590,3613360168378376977],[7790759431085138978,8106971551489689186,7257640493376193444,2475480204482631006]]},"quotient_query":{"leaf_elements":[6557243936844455546,17826292208588862102,8975010305642109462,14654202193941856413,15954405498732742448,1420778448230189972,2996294627045896706,5358119426041308655,10859803929575271095,8895669636208531729,15967905622951597617,12170924834093968982,8891292471988628217,5628919596703288682,9933725859861708436,5226394289421416617],"proof":[[9408320756021233863,12187561661654910372,7259792568417355549,15101031666081586369],[10913452014945522883,69158016811086815,18252216109334826752,6025611059821234743],[12904148973560247508,15563358013844193069,17145427882651456735,8966261746909632767],[1488014194237234538,9624241653766368548,5882617555163334820,4176879649886685831],[1392206173454504392,5954248832869947805,4114312700623811926,13698958634837995828],[5795165592007488350,3222119343801773534,3672191590756668493,4122215266809284888],[3348499183883723769,13894125183306728425,15541053656715623748,10535615377594156485],[2404179880480078686,10575367412533267958,7053972673059462116,9017714639796233921],[3453872184211718128,4552095137581054440,8999000348700204679,2356510608679825327],[7123180601817801408,4929058934225845024,4840603819842022998,2396872916262200338],[11599073433270528198,1234545008226336982,16727485424233435175,13846623129084830918],[2075441969576883278,9795694697280836268,2274306481925533721,1818329458338020982],[6102638653996997667,898141345390984292,8317820903427886765,428570291656221233],[1058160158335767146,17259972905600511807,7191090071961160900,18398435220200486089],[7098120677950352759,15212103506984180287,11012105690101328665,11422666757738965170],[10734683921290861711,9150637424559282283,2828575708492932966,2149105249050668584],[1449473256369105157,2354823088964465587,13988405084653819660,308731744374779041]]},"setup_query":{"leaf_elements":[978139711170888140,1706879706248620014,14025785694899734920,2367019330959417036,177985200912932830,18313056032767380670,12523274538541226269,12543609500272898246,6854661188234804203,4204586228229212065,15795468019167567026,10453137543668203204,9251129673222091760,5683608091465662635,18443602841000038641,2197816646873152471,15662556316683620212,2401412682152285548,17562112360638340872,2217417417296522431,9950668397300496035,10007824868618754978,1196310144942594354,6281982084984146984,3424124425705142865,11638837872436654719,10534731409814157691,15122150441527219521,874949316520289775,11062600410677677439,142014017441818976,10157498874407731096,15478931767214781232,15011324010650349099,3003263316016744996,13319237973710668098,4806707816451415981,9866015858199227992,7515372689227622212,14194001803667182646,18108875125412549564,5305802812318132075,8796308132265601774,17424520908020830376,1676914880972314372,4726053588752658653,941008241535802832,16488301132255138813,8631863039627681558,3992539378404926709,4480905479434300478,3633202155250317603,5836611642706582092,8289905324021670095,18025571739065861055,281712592317234841,1267795923131537723,13964897514776655993,2139574278372053410,11236087261744002121,9449523508689553397],"proof":[[12301651859336063766,5331751678839221901,7511407632068298875,6474755791334972502],[6689877725842466499,17505300924460668278,5243822525539315813,12492036218656339712],[16756772060118838784,1258610842636541047,6472272235783586534,11537826078125983798],[814603092857382467,15929794449287257986,16972282210073880803,13870030617720578948],[5231198576931633531,8390735061800905999,13564141709228372055,1290475980180277726],[13916865893746371846,4519035374431222969,17863463057261306321,696758641974854704],[17332241449215992538,12903171007178133700,881519303572730161,15275959819081264355],[13048724535454314225,13300933537458006761,18215089804542239993,1724120689752547735],[9578988885380326141,13665016436326263808,5469276179675554416,5525736049610104696],[15192291315203482951,15480484478654057639,1375631637723865156,10093418110283853470],[17462957942351179830,7046289419341955747,8113654564708720676,16406633746585129545],[8028523803518559874,18362668893893626804,15894515948502686518,4703316162623525123],[9277169097759519984,1103612719792957505,8038046668844470510,3849925696133430555],[1908145413019100195,6834188628268340751,14586634120324601207,6470268937398651708],[13582403330164801950,10188641938165481000,780801498363314869,3777003167219053696],[9477650935488749990,5079710287473414229,5139930877597881649,9856188670879794965],[9445621398762571278,5025046327845726104,7607526250521561281,14517337902743528763]]},"fri_queries":[{"leaf_elements":[3440710054793497771,15061923462248478219,17579201474561672649,695134821155665278,11046454695449798900,4869151124295812919,8037245453843148256,2476814654200509704,12288367692094208479,2391605349565783320,12272995021617222633,17689862379871687558,4209817617218183545,3853262267991220837,18327241172624958161,18293338428200351164],"proof":[[2970599929787595341,9749454918782857913,14378420265615166467,17382140915197812705],[12534858219688993176,12383018246737545604,2755139718741890941,17684047900059134023],[13110655303382452612,16493287242994039478,2394353655671766519,8233496050991730950],[7494447452314697542,10125673536533089242,5173511743615235693,4151387413010322593],[12425635176134634111,8683489869621680675,8505318375267855119,11161475007596881502],[11234403644746806977,1610617619670112794,14813936635876911145,7003099464764772370],[15362742487784020061,1556487357600417148,18017985084829937652,3570998553999624532],[7004151923235491914,7328011489792112955,11629422411642556697,11003612489013106795],[18229229353939987806,15333887234245651356,536925762032210775,16553677858329152638],[16275032449388612515,15727038253339656875,9151061161716579081,182100023581109214],[4176973180810146726,5255954355746890396,10865477648351956558,15244468063150953824],[2375653170442290454,10010712657090427583,17776679797695163995,4980809327772239915],[8205059632732571207,11154874804443859656,17022282735444558506,14367426077202064812],[7180529967807406566,14303522395242893858,11744209102482955977,10726082762573625571]]},{"leaf_elements":[5670300096227766269,17742671418686141408,1703652140310664946,16204085858514452207,5884446365820344698,12374409988288751139,12766558197118242095,16023627656259082154,16395337769195564868,9112702270124570773,11015322508288942545,1576999828155329759,12039436508082589285,13761873152675661595,178863017340972866,8517224629951590470],"proof":[[9833042743145673771,3599848602043978146,15449349037213756518,9831882632946005982],[8209982482595751916,6976921943527812322,5746419162202593481,14872159908267244571],[14848700103576181451,3890585449496797865,3399393254931905756,3252459928547070536],[12114676743173209961,11370968133473434848,18194292325487699211,1799868734804149214],[15303194824070226941,11648805653347788753,11524097081915460261,18005080265854652504],[2402754254959170500,12752607943511998597,16229857375781831369,5391831997357123389],[14062887277325298101,3317748542985632648,2816024185652462339,5375507087679577141],[5700059805230525424,3632742430852901203,2933208602228935698,17395625118774721765],[2991731331917754421,9919737379208997575,10207071810267846174,14141971434870575182],[8982814809119766094,18032312568348695727,10307574702836553820,1425655282181408869],[9818896638509815363,14111342752126742640,16940083938541347143,12847595792075619010]]},{"leaf_elements":[3951938924400030133,3553548856419097954,5896230958252988122,10449181694322346552,3384707500258847563,7898537560916793381,10693868756606087849,7752736804951584365,7021500059618136026,7097899987691993346,17318377093007051541,14013184764349675323,11390938065524686941,17699323353987511722,5280858815856889513,7434492280226380561],"proof":[[2737437715775380230,3156190872556271908,217499908056714753,17469096184153907236],[8928776583975112842,5127338097682667109,4926823684739208328,3725231513210771064],[4451232018979181343,16685353690206557006,13883049659849417784,13051099457520955786],[13985036246196444655,12389971698801031120,1411288838006533494,3284605336079623983],[14572518989865658893,9500135421548362920,17655763646441237026,13108116248614199584],[4692957140458110504,1349298255845576837,12026183214469745061,801800237129975472],[5012786430292282638,714082964405093402,14568518633476701140,5706240536019094089],[15933965855264394922,11826399197660217720,5748944088944779553,1862508836070034890]]},{"leaf_elements":[4829840708230027087,10408969433310128430,11120281612081229171,1036950003424040424,8650318887902593225,15810586974011363033,3529517524563309581,17514592156910065284,18273554468254120578,17802584090168223611,5559600378463585674,13850619627849124321,9340829911433160006,4959437885287055029,12960318169238734659,5527666900206544002],"proof":[[9219616098467312503,17000999182943416124,3462933681735584731,4458590846333982194],[16380018785202324365,6184890772490246096,15671792548229535249,14732225600952914443],[17018789493416300989,7123235580021435216,12336508637303869389,10809476289094733750],[11542013111996879407,7279280741304923276,3310953196681459778,9372892092313336097],[16231679038151481732,7487911523695974729,7349812909464763124,13691117954442939248]]},{"leaf_elements":[6075202337747508673,1457853674626052171,831084320303098120,7572852475013512707,10665584143103099826,9481015519106511353,6328999218646712907,3933195283722148616,17233549791840103760,2222929612442174093,1480451420886437534,18157728212598502261,12981575932508498308,9697566083140857504,3183156656693979225,3562330014757965319],"proof":[[16802695290568767686,17690413701437491163,39758637509110663,1747029711034766523],[5568732675741408816,13417053568945025512,3262099126965768035,18413728694769490279]]},{"leaf_elements":[12070317668262492689,11900033669480323329,1977232529639075650,14502859512280388971],"proof":[[13972093823449137722,17870273312762684946,16976529753745423853,169765467049487406]]}]}],"pow_challenge":0,"_marker":null}} \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_proof_2.json b/crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_proof_2.json new file mode 100644 index 0000000..ae288f5 --- /dev/null +++ b/crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_proof_2.json @@ -0,0 +1 @@ +{"CompressionMode2Circuit":{"proof_config":{"fri_lde_factor":512,"merkle_tree_cap_size":16,"fri_folding_schedule":null,"security_level":80,"pow_bits":0},"public_inputs":[1961802424684827,44478075017541700,68433799240021256,10969447465159162],"witness_oracle_cap":[[15529583968858444523,17424967751495661158,6624134852057433715,10065450245543181332],[8114018778419602897,5999551459588652422,16012906803173273570,14420154581581872054],[12187433742970960512,10605329950320396434,15249954437947376005,14244673392348257535],[6679890526667466320,1978354068745171812,7666447769103671005,16277121298020778879],[13703327261655682079,12497192582270452156,14675967591656100198,16548528238038999709],[6922290054020779195,12852190282281452240,14541174696500061452,18191922499656897639],[13789997923162837434,7957408283524922000,17770659093151973753,8558000142652328783],[3676355762409775010,12173106962641294780,10832010680197353518,1330253516373482240],[13939264744737979696,15608599773719896270,16973317313421292944,15466720614565335438],[10293570851009024759,10915722598326336995,7719640875710332486,7899774663088164728],[15823939306929080437,6054539759622698957,15594070472741659789,9708752143656971169],[9918200868900954949,10373525614259208889,5843567131923468874,9136733461767158943],[3644015912291053632,5819346073748299627,9175056829165704929,11670497842321712419],[16114437925665495841,17616559374454105722,947306738161354887,18003826818499849137],[18177620371181429079,1384850778492105658,17124934997681591188,6634237479098017076],[10187597119396897127,12923675424786343324,5720697096793190728,3728774308949511514]],"stage_2_oracle_cap":[[14283746602962321255,9596445980578667326,2544441457331541189,13687190582698257491],[6709463332824006796,9492452573120150580,7664285959545527740,18103058633165128830],[14986202559230271372,2557595903064284179,1557196248727158170,16614700332472174202],[627302361718848030,14703386169961653405,5325796394333370865,14549943950170908585],[10370712199317627888,11122856295430642218,1583214099536429549,3084484885342258453],[8825932973219105630,3855074831151318888,7682925656220182690,4533785297190803868],[3916890410091546448,15738346023318391856,3281184712038404099,10315562520795795666],[66515930936250308,17181042025343985234,13247665941650860352,11666912503984342255],[4225804107141556079,4600631174386239920,3520437601540044352,15060230265296685676],[9514238757744338066,2596649376300586572,13178459605605970478,7088619455253119791],[5739485318105089545,10176638046266611259,18203692821584622399,11413363727154364250],[7462942112327554373,7822318376366574718,5800059877541267725,11103886153741624878],[16028025369459157619,17430242214562646744,1365438258177790628,14737142547667407289],[1164150903794987660,3626641233477222744,2707538715991648961,8867442487411238275],[4738089647211267060,1587060044552087367,17293416601635167554,13443066679411801104],[3843726693901200247,15736595395229871836,9348441280906668952,13287892829448732313]],"quotient_oracle_cap":[[8742554652989650741,6266796107981927978,7516086001818180796,16132701794771999930],[6607765468165125455,7349659269969407347,15166014319101771302,10388108052842854738],[17842031314090485006,16035703203917341553,17293027173465025096,13963708128725087146],[15159849084190207779,16756200457153815551,13628289171244769120,15894494746741354440],[16445269032828003428,829692280057330253,4919773084283074244,7482010797550301012],[14263890466184640978,91609345904474947,12839126177055222166,1290235305000557241],[18315275028724361762,16582690079136350280,7144089468886716590,16769492050051594402],[329467292234129350,2647719219679848480,16589745969818334815,8705326210063787677],[9794839915519510905,1754577164468972202,16110155406324192490,16156472773474038148],[12429769858117940646,13151716400777736,11122839987853085942,9692283555624113369],[8784216582853407194,17421764007200320168,5889863509167178380,35139793327975540],[13090864985165144685,13049165821246011084,16739852583451043779,3350041489648872187],[15797544464399027407,10599985291891166936,10264024891490536537,18408821829797731236],[7484256944136956326,12375065183923532473,9533031976517479998,11452622393643095737],[5989976116935777083,17614678427130090970,18425950890048029908,6199763365019862564],[558959887173825285,4011455190280975577,9124501178193164639,6691637056170216714]],"final_fri_monomials":[[9041342022690728778],[7828027812833487763]],"values_at_z":[{"coeffs":[5645420367605261158,16316144161543505015],"_marker":null},{"coeffs":[12569973273320858591,2657405864495836852],"_marker":null},{"coeffs":[1803212003151938315,934541490027315090],"_marker":null},{"coeffs":[12970042191865268243,15852170217221049853],"_marker":null},{"coeffs":[15624658640778194653,13640024289622846709],"_marker":null},{"coeffs":[9340825989659686880,11780074162617040226],"_marker":null},{"coeffs":[17399017387006091335,17606059577198086317],"_marker":null},{"coeffs":[4411046809839592223,10272657133035023053],"_marker":null},{"coeffs":[11862376883325135820,1421890687691372214],"_marker":null},{"coeffs":[16899775397354635429,14759171800429842615],"_marker":null},{"coeffs":[3319018390884684182,17386474517922358041],"_marker":null},{"coeffs":[10214277489946004597,11997067506060161301],"_marker":null},{"coeffs":[9654547291711198980,4670286662273114225],"_marker":null},{"coeffs":[1094623499778980744,14988607364053981253],"_marker":null},{"coeffs":[17484698607263559702,16038378385539124162],"_marker":null},{"coeffs":[4668357517208931232,4512880973968123330],"_marker":null},{"coeffs":[12296553423649185055,15102368638853829441],"_marker":null},{"coeffs":[13042193241344732195,12975590258859462679],"_marker":null},{"coeffs":[11200260957885565706,1576318943583184423],"_marker":null},{"coeffs":[4427487229287018758,6164856432542375065],"_marker":null},{"coeffs":[2483490787263048238,3859600468941203626],"_marker":null},{"coeffs":[15350654080231003281,6421812558370749383],"_marker":null},{"coeffs":[9036321533572525842,13291622236939208975],"_marker":null},{"coeffs":[10362865778296805043,11531914468475722625],"_marker":null},{"coeffs":[13312108469285424262,11009060684717303961],"_marker":null},{"coeffs":[12190490009123860260,1504307913748690800],"_marker":null},{"coeffs":[16975214975501583968,7047894510372584310],"_marker":null},{"coeffs":[8265694111811535288,17483346609725472616],"_marker":null},{"coeffs":[551265163384137180,13530707918179841668],"_marker":null},{"coeffs":[12318859811922896266,7463232493321153456],"_marker":null},{"coeffs":[4380865366158460445,8948937847707679502],"_marker":null},{"coeffs":[11591227515215221268,15923249813543383192],"_marker":null},{"coeffs":[6872614848090178032,5073595684682194337],"_marker":null},{"coeffs":[7627866083968105121,4162415390748306914],"_marker":null},{"coeffs":[10058287058539039983,16492081454150566977],"_marker":null},{"coeffs":[1239530415836810164,5195787331213065055],"_marker":null},{"coeffs":[4948977950605069046,1181254314044717069],"_marker":null},{"coeffs":[3950455076191512967,6006261072892967079],"_marker":null},{"coeffs":[13469816502403805882,15017065980527373362],"_marker":null},{"coeffs":[17261075353806671372,15646806349489477719],"_marker":null},{"coeffs":[7593174395221998610,12447480708215396034],"_marker":null},{"coeffs":[2054826750607571386,15152529224541546109],"_marker":null},{"coeffs":[12568035949707199962,7799526145138418277],"_marker":null},{"coeffs":[9235657306731956504,6662281599717497453],"_marker":null},{"coeffs":[5892040897168064214,2464545539874954830],"_marker":null},{"coeffs":[2110491232291112266,14349698615148865607],"_marker":null},{"coeffs":[11975023891738278323,14339133043106601475],"_marker":null},{"coeffs":[11508953371382635624,7073883766190908287],"_marker":null},{"coeffs":[12520365811149102396,11250688342505417983],"_marker":null},{"coeffs":[16919460886522684857,6966129483122447608],"_marker":null},{"coeffs":[7503428702818990144,11368811352819955071],"_marker":null},{"coeffs":[11459137072545899450,12562789838966775412],"_marker":null},{"coeffs":[13892110104290608670,11324696922309551499],"_marker":null},{"coeffs":[18251353388388148069,5808947008289974495],"_marker":null},{"coeffs":[12921293520894453551,9287706940782878783],"_marker":null},{"coeffs":[1008592879384539655,16638283721547269066],"_marker":null},{"coeffs":[9995374943979639578,13382413708057856393],"_marker":null},{"coeffs":[17974470785735285079,4128976556013061184],"_marker":null},{"coeffs":[15654389263554112879,2339867577175630847],"_marker":null},{"coeffs":[3750547943603874754,2513758455213842308],"_marker":null},{"coeffs":[16752208765680280987,7564189745134711204],"_marker":null},{"coeffs":[14692443727917796311,6264781688334143264],"_marker":null},{"coeffs":[2069157614255175025,5375619609073014462],"_marker":null},{"coeffs":[5885956743413713000,1859002984727999069],"_marker":null},{"coeffs":[4304814921592721412,6295442760536423901],"_marker":null},{"coeffs":[10548805553546409233,16251330325734935812],"_marker":null},{"coeffs":[1611811808665895284,11110536847900874854],"_marker":null},{"coeffs":[15660017624877930527,12149478102417959153],"_marker":null},{"coeffs":[13147813546842722843,13215317525546861938],"_marker":null},{"coeffs":[9132998845215239087,17225636425296760059],"_marker":null},{"coeffs":[6529015054586353081,6048687269488896949],"_marker":null},{"coeffs":[5586876143712314687,12107212911608732951],"_marker":null},{"coeffs":[10447902787735327009,5016791254658575812],"_marker":null},{"coeffs":[13215153502281918471,4051009232253973671],"_marker":null},{"coeffs":[11485045227596643954,14272880588267237849],"_marker":null},{"coeffs":[15530034060738028004,12330564117223012598],"_marker":null},{"coeffs":[2600899017191503388,7008141280029260843],"_marker":null},{"coeffs":[2983227594578077915,14249814229920296696],"_marker":null},{"coeffs":[5285348138424539534,6292376915171394938],"_marker":null},{"coeffs":[16292329248307587542,15661657027817878262],"_marker":null},{"coeffs":[8717630547715039594,3281440723841578825],"_marker":null},{"coeffs":[4168300164629962338,70920237756140301],"_marker":null},{"coeffs":[10771586818368516197,723442269395325545],"_marker":null},{"coeffs":[9447460074800769058,17613276932711178339],"_marker":null},{"coeffs":[6769326681271574488,12371774031930174622],"_marker":null},{"coeffs":[1944965190723016132,15745156577002960714],"_marker":null},{"coeffs":[6953389382615129650,7285649525519791805],"_marker":null},{"coeffs":[14102943292360268262,3198224151259622583],"_marker":null},{"coeffs":[10226526399309576708,6249152496030728599],"_marker":null},{"coeffs":[3146972484891598530,670820544154942661],"_marker":null},{"coeffs":[6647386786165272771,612902913429732587],"_marker":null},{"coeffs":[18363512774264364009,10134185757944452394],"_marker":null},{"coeffs":[10527408718123129043,14370971390151933713],"_marker":null},{"coeffs":[5941066257553313341,5982432630535272663],"_marker":null},{"coeffs":[2718723393411064674,9009653691650638569],"_marker":null},{"coeffs":[13994619304417624457,12083649327984117817],"_marker":null},{"coeffs":[11580298943990934083,17835673560241220930],"_marker":null},{"coeffs":[9712593374426010915,2850944378207135559],"_marker":null},{"coeffs":[17885284775937601078,8289357853220825410],"_marker":null},{"coeffs":[3543271300235827947,9193856667282109293],"_marker":null},{"coeffs":[10619652418137099860,3755228373604167867],"_marker":null},{"coeffs":[5457141099087718062,1171955530689335456],"_marker":null},{"coeffs":[11247626556230758028,11543642251142417811],"_marker":null},{"coeffs":[5256009287673885443,5903214498139367112],"_marker":null},{"coeffs":[3012467208655414755,7837970652131465951],"_marker":null},{"coeffs":[2835267292903154193,5596449615178020888],"_marker":null},{"coeffs":[17562982055426263232,10123815993259966653],"_marker":null},{"coeffs":[9118459464744742075,10537761578821134153],"_marker":null},{"coeffs":[4360695867954250150,11849627522545641731],"_marker":null},{"coeffs":[15011431950030039788,912888561833530392],"_marker":null},{"coeffs":[11434302198510760032,5642880187198497316],"_marker":null},{"coeffs":[7043878415057173882,2534296850731202285],"_marker":null},{"coeffs":[10123378829377278307,1907516258317659652],"_marker":null},{"coeffs":[7802895068733218060,10964317238471468470],"_marker":null},{"coeffs":[12176402487400144722,10891728793956586197],"_marker":null},{"coeffs":[15285683635649337391,17954495617401409339],"_marker":null},{"coeffs":[579406046669115928,17073667455787257777],"_marker":null},{"coeffs":[17305382996503345959,8978030330911925336],"_marker":null},{"coeffs":[1731010218284965111,17352299934442896951],"_marker":null},{"coeffs":[290465057188962123,4649532918964535775],"_marker":null},{"coeffs":[3968325750355919260,14318523921882015622],"_marker":null},{"coeffs":[14949666676779813804,14633310912322481907],"_marker":null},{"coeffs":[17515912939125560043,18221263989267773507],"_marker":null},{"coeffs":[8472852688853159832,5761151649224128522],"_marker":null},{"coeffs":[4463417740769154276,1618289695394600171],"_marker":null},{"coeffs":[7856244175170210753,7462087721227494604],"_marker":null},{"coeffs":[9113617535749701116,17015902725937751610],"_marker":null},{"coeffs":[17036198239806319655,8664336821349497541],"_marker":null},{"coeffs":[16114458695304427738,2476870113115755398],"_marker":null},{"coeffs":[5362194834510314650,11906545663338971202],"_marker":null},{"coeffs":[8105192920804207672,10523257265205048445],"_marker":null},{"coeffs":[16929860522052740064,12223923448649627079],"_marker":null},{"coeffs":[8503910700554684118,12787903327882774041],"_marker":null},{"coeffs":[479560021680993788,4918415207203975293],"_marker":null},{"coeffs":[18396630985249457664,7271509778705780846],"_marker":null},{"coeffs":[11739256144193266735,8009683467961795618],"_marker":null},{"coeffs":[12273195002602023908,9045706334275853450],"_marker":null},{"coeffs":[14373571599938736054,3327197276490994688],"_marker":null},{"coeffs":[3167828123949610306,581507223145810102],"_marker":null},{"coeffs":[8044229110984467274,2496426795660834450],"_marker":null},{"coeffs":[17482155914859945876,15779162063741051485],"_marker":null},{"coeffs":[14268870119257899298,16434758005645534759],"_marker":null},{"coeffs":[4296348093021846953,15892859569809081350],"_marker":null},{"coeffs":[16448287275620179129,11450919392533244831],"_marker":null},{"coeffs":[14368605255836032497,14445761347695870224],"_marker":null},{"coeffs":[4307912973593923298,12591869654547366502],"_marker":null},{"coeffs":[10519854798856548468,15684810627456674339],"_marker":null},{"coeffs":[9031149212542421941,523299920660464162],"_marker":null},{"coeffs":[7382098757361873833,3009487093194151979],"_marker":null},{"coeffs":[233194960267742996,10074499674317396345],"_marker":null},{"coeffs":[14984786088474278533,5203728424867006378],"_marker":null},{"coeffs":[5540750960712849182,10377200132813586873],"_marker":null},{"coeffs":[3048098485109218957,14815697224334165560],"_marker":null},{"coeffs":[5072946657032182414,11213092669854124260],"_marker":null},{"coeffs":[13907547269652182500,8593930160037396509],"_marker":null},{"coeffs":[6499863225887868241,1456813463520099490],"_marker":null},{"coeffs":[13299047123994473934,18390994297929085358],"_marker":null},{"coeffs":[7275533544736806483,14045903532754068861],"_marker":null},{"coeffs":[5652482254864599203,2590029245130089064],"_marker":null},{"coeffs":[9007379515846345788,5422785181795057939],"_marker":null},{"coeffs":[13055206976214970247,6013164935075391435],"_marker":null},{"coeffs":[7286063099152012962,223226655740929345],"_marker":null},{"coeffs":[8640183680706835797,12188409355476194307],"_marker":null},{"coeffs":[16429057479421608677,16911208708967712200],"_marker":null},{"coeffs":[16614470018357638657,5050499766489172978],"_marker":null},{"coeffs":[516799059835308830,17635010830893673303],"_marker":null},{"coeffs":[18089713082426342149,2213800118065123802],"_marker":null},{"coeffs":[8842661843313864352,4042885675924933314],"_marker":null},{"coeffs":[7559516727290358190,12699556024052827026],"_marker":null},{"coeffs":[3002952355812199208,6777662488705349874],"_marker":null},{"coeffs":[1170396779396933241,8218214880410108909],"_marker":null},{"coeffs":[6576582142050303611,508845937959371300],"_marker":null},{"coeffs":[2678247615045487158,5119097843430384045],"_marker":null},{"coeffs":[11702036536679340418,5038555482901717715],"_marker":null},{"coeffs":[11679133249345275276,14042861841542378407],"_marker":null},{"coeffs":[2541634139080610329,17555650344671927955],"_marker":null},{"coeffs":[3339403641085192782,3850678776066924339],"_marker":null},{"coeffs":[13263561053463573995,12877421018871500726],"_marker":null},{"coeffs":[1431854919155355945,4069170605438592082],"_marker":null},{"coeffs":[4607651227295614389,3317073306650096474],"_marker":null},{"coeffs":[14725415163779925718,9483158970463010587],"_marker":null},{"coeffs":[6464403902953244134,13862789939297911315],"_marker":null},{"coeffs":[12362504900554598663,11421040763100184145],"_marker":null},{"coeffs":[1478940254330952410,11579107531214055192],"_marker":null},{"coeffs":[17328935753625816452,12846238489538912764],"_marker":null},{"coeffs":[55102416813999261,611964826088314310],"_marker":null},{"coeffs":[11139547548511712343,15126997979986754740],"_marker":null},{"coeffs":[3759056792646902573,9377525079219953489],"_marker":null},{"coeffs":[935795810520801744,3184747128766783500],"_marker":null},{"coeffs":[9532090733342201187,11064643333317482553],"_marker":null},{"coeffs":[8031391047252815223,8000875018136296285],"_marker":null},{"coeffs":[15315803036354193383,2108518182900287066],"_marker":null},{"coeffs":[17684790338412113465,17901228093227332872],"_marker":null},{"coeffs":[4288895406139791501,10209003074377842865],"_marker":null},{"coeffs":[291993461700343849,3031877234882923964],"_marker":null},{"coeffs":[3594732160061625663,12394527147548231496],"_marker":null},{"coeffs":[17645853871202457960,5803879017298994280],"_marker":null},{"coeffs":[3124003861265018641,1450939052787048446],"_marker":null},{"coeffs":[5582334305714893341,12178421997562724356],"_marker":null},{"coeffs":[9364334175595143100,17086347063002970185],"_marker":null},{"coeffs":[1503369161947962670,2107045899510159876],"_marker":null},{"coeffs":[3661258074261533208,2151997318921721029],"_marker":null},{"coeffs":[7533110907473081155,9571551578518649967],"_marker":null},{"coeffs":[1465460897397788658,17854382567105442476],"_marker":null},{"coeffs":[6893738705887980011,8706377328438548999],"_marker":null},{"coeffs":[14381140341058499205,1422375210884815658],"_marker":null},{"coeffs":[13165763183236701867,13859528945070338871],"_marker":null},{"coeffs":[9982959052689348250,5007986484945068669],"_marker":null},{"coeffs":[2215944358604080631,18311739136020478751],"_marker":null}],"values_at_z_omega":[{"coeffs":[10541114392339934442,14952481003485051752],"_marker":null}],"values_at_0":[],"fri_base_oracle_cap":[[16293829421290417928,6480733642873798968,2720064835245473987,5984018222264797794],[15625224169399418676,3910260727383492094,14041531422414135032,16061230762719902122],[18038265717349387436,17591355462368361141,16073841630641562334,13596073253612676379],[5270818716868153706,1010008691844288332,2881235245584087146,16920476172766621946],[12944584001733016137,2048697080318573610,722638443467274478,995558081479926166],[1616998087286289725,10082687592744651115,11811823287817162272,7080554586625749974],[14449546932292252831,14410043765503086224,18175134705701924541,4931526602281491343],[6816278660289589871,6873065522012627658,9584342761502979947,16448613966362290148],[15011861466651806276,16347623533505104881,6882431751970080413,14142285841549869523],[13871642900874618094,17713709936223628245,7661368691936853051,3463823588630390092],[8336275055670660303,16184536948031658782,7801617598578713156,16580059869200187572],[1936126474664567157,5214377127325020055,14735718466317548767,14732316353896421101],[10052588442783826625,10293053825874169523,3466980960467426834,16623650330501453796],[418159986626357782,6914700556238353618,9580884633934598273,2913744417262084437],[2380142699676445740,1774458046503773700,11906724331507065411,6269507920650384339],[13604760960798564035,1215184511896029588,708789222945307448,15483216283150874838]],"fri_intermediate_oracles_caps":[[[16556243533664338723,13089883775252505668,6639726196042574825,2531442206943348754],[5402483862591957506,17335678614211753953,2263473182287713013,4869752363955929815],[17750914237904503735,11862564922556685204,12706915686850136390,5998711101177180618],[16233136998226359877,12547539499679567607,10068663282810318101,9049385626075631536],[3725622493340722168,11199094947344456174,3434465360085542809,7481949578805011270],[14208128559643416438,7511938442466500517,16575915166379479293,5625097886102013193],[16872504666422312504,16076484027581433692,3567454185700963403,11893473531379767332],[13405798713253058349,8943386621935468473,2742333341975809350,16498326773694972550],[12302276199895522628,172485849563731956,2448899214230031772,2206576578741033181],[2952664626998812333,16790727516843050273,17903523360136836364,12242534468760997703],[11389476445109515476,1383614770345254292,9251247428502586177,4927389423474566285],[16890831308075705029,1593001697106845405,6413130388383406986,15514180260987303527],[14118780576477265991,14268280721484224127,18441931836828723953,11886230544306843330],[4803069519834525098,16122240126265733797,9102527664925409141,16727875156140281158],[2072357137931607590,10513681240813237758,2841759093561962579,3074568251581860304],[9779729675494069399,9056702697771263651,16875439469095497480,2638110549925671923]],[[1482126033031846230,3550756890096831321,421122679679750171,11191613845701389807],[2089137889221624381,6842317656962709081,9755376574977429895,3553776985918147306],[17499946863906334050,14863552234262915521,2903833864320825370,312176477166922715],[17372735726265258626,17395909216821956714,938581446934331906,3292327168494474326],[7888972882355488462,16843394264973973734,17611624998601929589,10990455610987460922],[2973184103586090123,1215646621277209284,3031237514906506605,12694311099677672036],[14422317021848068957,10819477454885064157,12678309212328383483,13342812832186982126],[16339996918480458692,9533108277067940276,3837115466334780415,7445890223018545238],[13641274094184207082,8837791107765242005,14399245921349236473,8228400729271183304],[10833914612536450530,11553314062585108740,7331985891926140940,2402326241632613911],[14018138793618942548,17028138164816614951,7356046491598278355,16225181695772631806],[2897124746427560392,1128101003960488153,13906876868143284070,17383349370356605378],[18359820098468631800,7735927065101884647,15457564326469279603,17942742431399382847],[308399979475913911,10504264283678831053,15319039535799158335,17927366421251443585],[13435081686975420624,9590328887657505999,415607738755800538,14824699297089178241],[12563953541898214137,14236895692388482929,9853990681446103542,15749538488935720307]],[[5283435580307660471,17167511810815790677,1821458196500642103,18133844026470470695],[13454652207985595802,13643431526707340558,9918617860167442583,14057633675680205166],[7533203798083427413,16393888921939704194,12497979979178702921,18346867698867051846],[17485513229845184269,8164479490267548111,3149092393894340361,15434056147476898141],[1887564187786500596,14159179355098388371,4298600534322831702,12259976034654721189],[1950910912780411207,1887934386324482196,13969240347860936829,11450162549973602064],[14228966684192898917,4490739024435583399,15387966533768536486,10585373556090430243],[5280949158129928598,6104006978076583253,3887716550775405296,13468568683888136416],[4720175286917823182,3335271149713123268,2257772520061396563,15391623797532894648],[550161564289478429,17608038170290567291,10376948587706260175,4814154719630764389],[248811070975369114,10210960412153076316,2025781579780654748,9808525523991086690],[4294110559611042337,14866609597278595303,12317728385741027126,4109940312838200334],[10037021665688682547,567368235040807939,12944895101248865903,1716459588137101290],[15112826388858429573,5977303025565565510,8130074884293979412,9465164936223290015],[1252978179958598955,8603670888266577088,5690871479871530679,765743036082284006],[13682566438284462444,11399127505614862582,16073153528772470586,15898820425860122357]],[[11403673940186045491,3356397370030755205,733457924420412893,2671424847782010367],[10674316072094533080,60033374848231249,15211634017981798195,6821739552365803431],[15483813321200534797,2702322212980742686,13469367946684931648,11648570915849471134],[17820994366707795672,13049652057531279647,11606634944656404203,960192386544696044],[15019565245824176820,14077727819395260913,10758182297563817913,786457918364627844],[17387938195818140267,13169252224149262375,18423017395310993508,13231306107931744230],[3051185857807063038,17516821650948348323,1482918357076166733,1435433860775062093],[15788317365606663704,7765871580335505574,2350071992989598831,9991654973119522087],[5918257773730567710,8606820715859479692,12880229567178203789,17188289744561801463],[3995757481444943722,10926228220725189947,16567655791381595786,4624806344531244038],[4696390000095888367,13598745989720078654,12794345706006728066,15776106833198881541],[152637478220102616,697454880860503351,17536014469521884815,11327578739059178525],[13050670014621172255,6486898317743015295,12669041671841541302,9361589608337197321],[13134346769093778880,18391190003556879832,6822943203592206637,8349250890270153229],[807646698697969835,4737687492964588417,6578554204069736045,7027987414024561485],[4255479924216194806,4279166963102351850,3717275284339110518,14673607385555971099]]],"queries_per_fri_repetition":[{"witness_query":{"leaf_elements":[6855614948472796259,1776029619168076817,6520607607646327500,32665343949505966,1276126129485809256,1894131050827317227,8758458270959762204,9521511470354970770,11550331208351398481,48710087320056411,11731247710041564841,11407135169779135388,11377100384901807657,10353429220770113078,9491270113702578626,8152328657822005318,15799570034905431496,10161567338589244476,4260606144079685143,12449215977286485659,7322281013131069472,10071029577389222191,1835190841934259186,11594645382014362842,18240783187668008616,14417185752310212746,17511354247149844948,1228247442770070719,1921436416410494699,10124227285122100838,5027605780139194547,3266647381302607733,2618426193092442371,7728257899655163028,14148456411240807792,14590915175053018026,14071093949999165784,17784437830185229029,15906298736218209147,17315831757792482139,12173899623996527419,4376271210548991608,1437905790295221972,15112168289129586404,7725919465293349768,4771193825637395762,5682009572241334912,18321190378604053698,16896745612521186248,18193558781784980134,6692758229711730024,10515294303089161395,602787502390122899,3387117313927853728,12578078988995444976,13695394546091324015,7279733826154808290,5992284380338782518,12995023867591444379,14919108736391445510,7550149021343264347,7603519224144766851,11470501154294571626,4565967070497886624,1349881691013645698,12767399768211697841,5798373400289406040,2595806817775430323,7492994309472601955,2599288515532208510,376063437257865907,1569909738284991566,4437112889346432042,11194609227465969404,6452112929387559126,468095519646524823,12839440842273264363,12154533363534676901,4275032829784624494,15205388412497741375,3195309931126585518,16074193659140921320,9539263242305817892,1108101590910139580,15937694572472134099,16114559278232345338,3290044165702313147,4379932938167107084,6346943506697468518,18017443376470244992,8363834902829872184,12816146715181035250,14288851041290778142,1441206339233226488,9134073223767258190,2081738048335787366,5910676001016968129,6817418313110604753,13032785226390032943,15985932289503527518,9504773703227788159,2436203762543436291,12193986916754190487,11829012846890605073,6791504532940179204,2660716680059615762,13369931590708267048,2606317588787516971,6678243770729579834,5235779420015242165,11194886741266661071,14638963229923441194,16147077120050303974,14972100448852228087,8574881182779400439,965653775213618940,14736465129486436206,18115232484168279098,3144672035850648721,4185994761043788963,2167217863551775332,17438292723035225504,10773531776919494668,16585235634761292880,12871230130106998820,4974244181604571401,14052451298983333717,7742518943104333134,17808454174845831647,14758457213585499786],"proof":[[14349907049519540073,17077285882077540333,1742694822978720863,5961886323183760875],[10872954282921482890,7556162185055990717,4622106368915955093,2690415788683470339],[6933334083856917585,10954624272217915608,14970174839580979885,17390884771006335859],[1801148489354613117,3519255117824818066,7397951377993221416,11305370475580879404],[9341913699560245986,8122573265828810675,4653329385683984726,10334463351890394277],[7645152811321299779,11417641212188102695,5563500905995690281,3074412202751421827],[16105021486228186353,4436800493961435592,5733174212671529137,10693420976664796430],[15536389264606299864,957628568616585384,2107238043879453479,3924379449749830274],[11979985415742754463,14281104152471536105,11493431242678459506,1130873336719747831],[12760213466931225299,13733282697689916326,16410376976031341719,2488213868353222305],[17705526293184323647,160896743643535778,17226618117676748284,1606197778333249269],[7514532335665917252,7145008113425956576,4132817052678647425,15875729633294010063],[10108840295815264524,10138765151409400151,1471299391448867710,9035710434707061959],[1569536486997776467,3524317700676378587,12015850281881387565,11912062458334684210],[4511681668197187950,3254677061705611219,12433601496835420635,1546228494597293989],[16636234734522759499,8005634423241415270,2358270828743096311,2931298150634639008],[14860422273076035053,4442487297886050120,4107415192329045666,4695207835516566045],[6572491212768576938,137897960636717636,10521351724316120960,14139744951647666720]]},"stage_2_query":{"leaf_elements":[16616467114296683502,8502672979959046627,12330178335237507405,6573349442940789201,178823925415552732,11778970405586283453,10249217268974797875,16845497385811342787,15171400340919332310,2572492299664357449,1745893748489930331,8282386164756926010,9276454383453919956,6090846242572267046],"proof":[[2085744817549475000,1484320001908125267,16782291135836727279,10658701050655782504],[3260951341736069145,9597256596989605113,15928260589416626344,10769391023054720953],[13986381448044573160,4782899082417967830,1987460133295520000,12613108191239511693],[8095864926162677218,949318915130485401,17541412767774848522,3636478778728405188],[482912535708536210,9273972758212117364,1032694066458637692,17941469585265023822],[17251490761899197903,16231474897292551074,9604729402163584047,5443673525980387626],[16451567374953447898,4492973096856142161,5850699374190958413,714739276429734557],[319656420560324286,18385058751451304738,14126425093598225999,2250421175267040588],[1312009351268294034,8841023220593267924,11635554453999812593,18233003612437816162],[5748756462822943841,11189269414033563225,16486272950196320647,171798105536984487],[4584074327701578938,5690900588928966006,2785920003606374963,13678938310780486009],[12230463469443700833,10559579258077637410,13762894870705250264,5757678899342616452],[18388875802022299363,10302379754093654824,3593863746088195739,14267065079590576001],[17208330141558250089,5567584500128578953,13029832258142717156,14185411498283447246],[1208409400205493610,4249619924050828015,8219340708301563609,16510542055890594363],[12270545066119395710,12924986898520275235,8169018874334596604,3328669548753658818],[11950108087200330379,15943355498410365029,9109714097787490936,10846832310384032055],[5471743823811849253,6540015935649497693,2283573760867703507,11142925402175779307]]},"quotient_query":{"leaf_elements":[8234580784554881741,7770478761604337234,14336126081517030236,11972019287411210298,15925896356955112632,5426076549099567937,7055890312425398913,9786554106721749265,13494929955232768635,11645938684005812873,12214159457101258216,15643803162884650439,10677549355760299795,12199581795442242557,2902317165279748039,8765783615728420147],"proof":[[16793925686623983966,10285331800138756743,3064250123754244980,3747203910432792516],[13976806240241782240,11445562905598202263,2702031389229054349,13054225133550690276],[16109847005342999787,16236836377158660170,473484512261440050,8513157985134521310],[13896895517511718640,14295194852872119372,7284323075789150199,10555073564312540549],[394918583972957359,10748765956963775320,13692782392498511559,13397874139023675761],[13198407702032497921,11882882516528890462,595247716717889333,4286578011044322732],[4421018160664329933,143420981705053934,16750817562052019647,3545573461995659442],[8376277725905874743,9252571747657224673,2836885502364780162,14235531416768422663],[3518351039897830427,11145078783063100758,10246086770647408222,8229394925895986859],[11421253800066122701,2141338050421036219,12294393049212272006,16413004383214235975],[5901409860279741493,18421265628818960080,18081211084676562481,5955144950215357787],[1840433650981817290,6429567132038274300,11556093368959064005,13715749771229756607],[15174612001241894594,14205229839903354107,6485789488615718137,10768719194235472336],[9103631358572111646,11920375344310856495,12024048426827835849,10789237497502513957],[3196003351755861170,10991440665872746462,475902488697174912,15674444804545863247],[9624221634929588745,5433075186533412406,1281839225096206906,14677440097087927497],[10850650229475561126,11592194541391643092,4162862761782034596,10482732923829073926],[10826344330511786354,5332764646915660931,3292010532699891612,10539987730221327605]]},"setup_query":{"leaf_elements":[10955266915795647154,13158706400690899773,17610134529069541733,5523624208871761015,6881037103837581935,1061553281432901881,2744798954685070895,5070706888552701843,1991494169558568410,8539129638006694792,9231210826636203681,8785186669083850821,13153270091629844249,13538133610577551888,13542401688884905702,14291035221232288180,2142277920079020769,12585462378277391181,6363920329466034965,8607519776254630864,903596261554256752,9604471972630850360,10859504633153903561,15806623048241882419,3800805735327718144,252414209520124357,10892067761009957381,10230051338284147830,896248210492094034,4451577639788533930,1697217924489644275,11833036467777612889,11074084638670485242,2898375512642760329,4204425988361990550,3133269268311843258,8260781017876926518,4218074408111027062,9936213491587892198,995490766351983112,11985567353272859782,13577770060401910091,10070187772091358823,8760183736361326655,8865145200471782883,15986193513940673868,4692279860012670060,6814568036747030347,6932175195136021265,4854627174369812314,3524752778685105635,9206582751154389494,17197088704625750458,18099908131599787981,21961255866310645,2098481179910047188,17465226089456864701,7441090374841745122,2747523761488928378,3595063115386095662,9517827242716313294,16793230705614923576,14735029135349972185,13982618057301828219],"proof":[[2805726864356591313,16725740482970571776,13246119786594671449,10138962801291274673],[11870107709065141150,8864364754670901842,9488764725988859762,12004761049131537043],[11063317628003352883,10580460176981844396,4633059868038755484,11941914519622494118],[10161870513348777230,3164727960745907427,8997005347393857735,11594693195692061038],[2675204054486877276,15282860880232971044,10219645450291195853,10881910465325296537],[4005366118433799360,16251797522921602550,7370801699093683303,5684424234634015548],[7914512519523536291,9739195912692481314,16334636992635257902,13085085137276376602],[7327130293427323561,15710732495110929674,11690611780324071801,8816890648630225125],[7112809758727143993,2930949874010083742,11783953384559376984,9098457668442193518],[2009358531823072094,1906435078558915020,14408287292005914490,12113845572304352081],[6990128599585313641,6344487957976877000,17511810920905514165,18361071483736854753],[18402218735622341419,8928983550758556326,5093757429248591523,17688937126990273627],[11965322800413214117,9235937611227133850,13691688968828559652,14073725582957393743],[13880333381746595161,13052423666565415457,14806041837099038661,14928481878385350145],[15713018853036559822,10760732038913024439,9924406601968931541,5048002562093424266],[8323608329915151510,10217439390384931287,8287844020242751215,9207711581487170531],[12665965224183815847,12852225587838471334,3441036154967094422,10935063228166505858],[13511381266976691921,9204072167241091301,339207757332023896,12754055892169127042]]},"fri_queries":[{"leaf_elements":[13547479799530829069,18124298704133234244,16749863586271086400,14785698088992616709,7680024269673265174,6624442824397564523,11890007083060086200,6726479935440810981,17208225373170284728,9200267962155532074,13865973785434698405,4525950069827137537,4612911495995565780,8756032798400696760,15187970571140089419,3115451483368648493],"proof":[[205522699037735730,827516813822254468,8335902365789234834,13867830954089413744],[15006514108527721048,11248146975040939958,15222307356268247673,5912250289609350532],[16178441540869888471,7172688865634215642,14820089208926012152,2763473336178594122],[3018796776848682115,6380829036593817642,10865392716187191945,2701273853483410225],[13258038988950998461,9029808577288852274,8626554229271808490,7270404442852955913],[11774793166222175221,7881583133197994458,628986148071305663,11475076322439829990],[5389842141652717074,17737539037836501384,3879807755824231081,16819083409491895375],[3333842297618109935,10941797175664434035,5517856262345870920,9102535423145661089],[5930926927766411747,1392516371614691421,6812582913294508091,4668291838590622461],[16666515586262932757,2786037736300601325,11793559908331451648,9625861777182032238],[13159716949358687985,601822572797389010,5671688105883383228,9964506869810385678],[3941564793114074467,16150707069422372795,3800914832400365035,8997709615652276985],[7660994922858066898,11175244286478001333,6864035964196567459,16645014612527987028],[4123087973811596462,60091459026376897,276322692142586638,8378649212419280320],[7545942003694895962,4430901567266856434,18008190376195831755,14457898847592396527]]},{"leaf_elements":[7136890303949353332,8366814180326480184,15132629542514482371,11002373640250826844,5749382537150372378,17187336947380780416,5964642700252954346,7875296901456044015,7247096052571879942,7666433118954243996,18344038097515588554,15389515301099313430,5675683599536950743,10127312100516862906,2538287168892859296,16131469235861912853],"proof":[[12673822804211046266,6654329950198940164,11550704351969379253,5783374863027584626],[10609273308296461422,5288991292730339044,2517589260397992233,4463796519718869692],[5448853939163301612,13502661164725104282,16301580029739670148,9093945148828707864],[746072059359106277,5876078637144034146,9044623604030511057,9033667415460696730],[4005167237207533795,5698068916868133556,10795754763014173656,18286495356399859928],[8422024995079538677,464820902469902431,5242745589607459360,4083811454637459378],[7448290166074612597,1148205138467259318,13710619697799022396,2464108126237759502],[5362641997326876300,12478017365294135463,18228715352690517771,14760258507763525136],[6843783758216406382,10101638085782995141,3531190186348610791,5579682995273466440],[3234690204607741087,7009754920092708554,13624782608586556458,6585776756697264431],[10304894767559387404,12670628770277471109,6628231763760372128,9264407436434391959],[1476082179997634999,4973310619918354050,15585530083552013026,7246114375327049413]]},{"leaf_elements":[8109619023014168863,15662824524870336967,860305233051526432,10165734192562573584,6237392016825824773,459100085217556301,3911643143430500580,3818551717520272447,16821853687718017002,2378704306972350046,4282319017978921905,14081309977651636716,13376465657842889310,10313496721454463716,13796737838431777426,9569012511572459056],"proof":[[11491768923123103236,99165302486085427,3170976239314344587,4784926194534479531],[14986947700872817347,17984341923804650930,7717937522350110227,14943957985882303782],[3611915383372317623,17692417314988333930,8388612349676826364,13891910131200516561],[9123336209561988220,848210245391412300,1295814224667966859,6067786712896101768],[3352867983604929289,6988965228139667492,2448185487625446914,2382030514953763346],[875231355153513363,374979190745305118,432249615296598996,3218378566124288359],[6817201104978592735,12795241883936007059,2262453518747453554,15517440984737593132],[15656840055282203870,9154266329915119856,12107195518915425772,16885195688754229952],[10208304403933904922,14465763810456685406,17659371736893445385,2521515806800186067]]},{"leaf_elements":[18213801575016839613,17309395621885976330,6624520477635841658,14159324467405578289,13104685734095901076,18335231810036095157,4857925666769035344,3430707230264316976,16504164778749717004,9594207663172182043,8069427809770631739,16552134461079981394,7944877386006621271,16436157360936308939,2588226490509739075,16128420943334097364],"proof":[[13455554283893629454,12352922620726764556,16277541946177301877,8322661487994955148],[18055089658677946456,4014379099749604253,1898143717956780374,12962865634865089033],[7868848093532648606,16669180455255531980,15488411038363284307,15110289464558430962],[12911414839942193020,17810605807185140352,11570342427468746729,8961949651640930003],[6663084025768576561,6371918601386671201,9894455364042152670,13149698628837040266],[3935484210871915129,6085499747822073997,13696068127854900170,16071953757664270289]]},{"leaf_elements":[12403188902893079824,4357198051962227659,17039830303816683861,12700841727666450325],"proof":[[14129469851234172007,15297294734680640909,13903785342374515690,10186116085735259808],[534005724367584665,16109373489849711674,7242017527024264419,17238331527371265009],[7046197724970029053,3073105137449928333,7146437533624004042,10894489292898565772],[10372735260732223591,4194280906584580781,5121283148969848664,12886586096620936158],[6195082165675208403,3296113561374908808,16304923259978842349,7184461966159293560]]}]},{"witness_query":{"leaf_elements":[10948217389093497702,6759902100633180394,6326821877358840932,8088994657681140913,16222171571060062709,5876535827972854519,13289073311281533324,1834655292558353185,206529263343747335,1005674123754652795,13159277711060271462,10401851020808173505,8726789290314399359,13483342475482304442,1134110038052673869,8883810110086715824,1378454424676528818,10069059024878583278,7658736508983858502,13874556644969426208,12173297861288929999,8469081628592992419,15449232222660562200,8189904006839170133,12076666680163972227,4374425399732849106,7705715286807893511,14240897732672554968,17267065644797851583,12922503666903323585,15612968993174031352,6348315563729300547,9187843916723430460,15757996425294582698,6173140715035088754,15634797620431974370,17171315948752612177,1100784634334547343,2123631725034902734,15732663699516143050,2718742587150455006,5125853823841191169,1585676204507792549,15235980247929936971,14951968241578066248,7502647756354599086,5666403984850917620,8787852143737833427,9082212306714291845,15121817625946237412,12569894580953147431,2565142403741196566,8804629345474273104,15498827713559958066,12595750261622379235,8486635191342740963,10538287312871959484,16216665855758946905,8179337381998996037,3422341372776298227,12817069913902859781,5830026780634410448,4802345874142574757,15234365928654047367,2033517732005912896,15241955352018039169,4518894553604666716,12675937033297340340,9071913469913361527,13421138520800803286,13974729557863583002,15668124204466085907,7649968454863927471,18315325868255120758,17634108682830982106,3163349714496607085,16520712107917558344,17611445599769809528,5781681335660659526,8004033629874576571,17658858507169780556,8817508500481160414,14169724524343610414,7904511816124167525,3926214450809058140,2091768012382326949,6689596107641634088,14225633125472127173,10542197494373853593,18079280842911951854,8654363407010972579,6732128552731931324,3613915080131400137,14215403978492416397,6810444127499240298,4815870031455898214,9099450339153508632,8318961982062251266,5270302257721802903,4220836174806002675,9611258553925554511,222504159652847628,522689138260522427,13011769289672631268,2993474519140713973,735832791986881153,16649036419163986478,6362120505893182240,4110652287242257601,12474162244529338931,4078376392148664117,7440433303963934063,9035360003888977632,16970214894964400906,16066597219618498427,7436021500249334954,2543624811840960219,6223518943558791543,14123627434408089498,5333525643879492050,11703185602283647247,3857788763554906976,10349588300226781197,10675802122688910586,12626884214741458995,9748652298455981684,9088859111425670212,15371074127932498943,4394008026989596215,13113537303466204869],"proof":[[13191599496257388029,18132942763492634076,12453226499195144989,9914923783623020442],[937991674093964465,15834532553960646194,15681922617052211947,6995102072552198111],[7419750306645338937,9102850145901334942,18294081118737298200,3564699008911437936],[17641616128645093976,6052228748454811287,5370237903607419744,2870061906080927875],[1097849782671700486,1804549561906652168,597190851919350854,380033039736250835],[13835986158028635336,12124329866982350709,11971706637727297890,6374642281053707582],[7263786763881644863,1361439142826597270,3833358355746300214,2251056592505256852],[73929032159497507,15154704966803984271,11832321847075540447,16017206523399326370],[14852129495746631468,7328671197575292934,1671052870333690877,12823058961291851926],[4171408252052652274,7481773614323870972,10279659955387963109,3157873375124419996],[11033419322849548092,1748617670032716241,15800732490873271068,5166144782242051539],[10307987376814098412,13840635630749745335,4146525657426601869,982170735460454479],[11771817929391114894,10159638523820790292,18343739869864712715,7503654525428545807],[11260418872327080711,7635157453257751925,11322832476404613241,13607739392572698776],[3934040217913727076,4653621048970217352,7194170727964502530,5687986391011065981],[15390012280223453741,17206030237099937604,3158527342772415824,4899503389472616907],[10237803776938456003,3155060787996455540,15805150084414564273,7603582789654176425],[13105183402301530099,8396744471784795126,5588323680871131548,6569925587759847427]]},"stage_2_query":{"leaf_elements":[9833148294007410556,3695240436881774183,4847273816232691799,14601908966019780751,4108232479015755362,5611175324878392583,14744063638266493716,3746485506643302805,576604940078780068,11804051194339483121,6947454780028648159,9628535364512732210,12918209934499473297,1327309399945180404],"proof":[[1976574983075881896,14836144308329896828,12765616065883707707,774356662762908000],[16415953074878729999,14886654693980028185,18211527361951425284,9097121404875995162],[13611057472202476426,12217293809368280594,10388224883410343617,1664494114173921193],[16948018165513321684,17269528529033032221,17532118429780213943,5240707521046592229],[18222840585915563225,2595236469392285999,14102339608629254374,17819932001085830791],[14379307429445471225,4950446978916281057,933592674624687633,7294207039534936712],[6441098121747908217,13040267706222783738,7872135246705904085,10965676771916512420],[7278490288029952819,16209107909544251880,7743999093122174408,11987279656533328637],[16990670945095281606,7406002592772358589,12685501575312940608,15789451480350587933],[7434398742710529316,8233841746634859866,13585988962288296894,7294403798013615250],[6188650927335683639,12278654250693871624,1075611297422077197,18137820507785686746],[15324954202298928940,8019243703154254100,18197454552211765779,9959097281382738316],[8444999469623942670,4171556841846280548,183324724361386323,13380934054563910190],[3290721042223475882,6042693665243398871,17218482741526655292,345504324883069705],[13533986422779230438,17091513204605762727,13112626428780535800,1866636867839296960],[8818898498204347039,18344793709788354707,1843824729665686090,4172663474554313132],[11052849106833223034,857258110695828137,13738627395017462558,10711500666073585110],[5547417495676185461,5068518114375938675,16286565849983914506,7128111235683497953]]},"quotient_query":{"leaf_elements":[9345890956188082913,11713036865579709028,12063720142112256441,16125684983901543616,16254802150319446237,15059143807061306764,17281540036046274777,17467514746284827832,5223106992596335765,7307871632361442760,10587450193048214988,17586110891846614114,617764064366517149,13271235394784270383,6768408715859545771,9078896768240577506],"proof":[[15467553907625400057,17017106407890190198,4228072068158270741,4806773366789050992],[17573900750562763090,1816743723255663655,10070540420151643077,1686469742846888036],[8172744146252989681,15043876497510283069,8885124318401019797,9215517152884508520],[4850848978115485473,13251642052719643957,16487465043298910744,12017291194824728803],[10122417791485600110,7631010729545199108,10257280484325905214,14513847617399491948],[1839242120214635354,2185872947852934773,9335598481171254283,14380329301252644472],[9212351095470786714,12436474850058933803,11739032755420235384,9159318420416053520],[5494949999263399783,10661751295311546485,7274816122008668192,3112822158291152829],[4368641712451374902,13292894760264526878,4390381702619603783,6384090836577772556],[13762177267745254882,7384431226749418103,16578269319583623474,2089337259346219206],[893871944476465529,11332002592578626214,9129366507512095088,4351718059590728980],[4564994966713100226,7370913553730578035,17394176009617645532,17035865455799524812],[1532190630782171159,7523649572429775235,8534869337691619593,18250085836460792423],[9067547667453845375,11160464122539134058,3494858704808830886,9839945143926730177],[6781685175040479797,4031131244131025759,2305804125959942321,10738952540311938099],[12246720532933297129,1135463657427836826,17550433449144143946,15578483884280116646],[14572847491737966129,10061236076266083911,17774687168709206976,10488571489277745247],[2165233475601013609,11354151705151233047,16696491571678498475,11559262300971943987]]},"setup_query":{"leaf_elements":[4748408572354876199,9094640024829931811,7131260295146485896,5955251866347053098,17202989987266797769,18209383962230781587,1122917488882747007,4408931017146575670,7700884748418711438,2961512988878207648,9086677262391159608,2371412471385484772,137323570786469598,5618355476407818576,12058272376730403451,18434269582397235603,14029703075108414630,16448068041878094620,16721530213452940709,12498626303054787582,17975375193975149048,7190156194447557540,17792255534656771869,10316911878915218240,8701800992696853149,7397626548735673842,5605981267667279219,16681757472635983301,2964594611113802920,7280103268768391635,11673982764538153112,9942808076642920443,2722935882287867458,9701421886217232469,8938123532008950558,1305930387762592568,9196033749576624124,8539807465054986364,317807669384065070,12969861106268449060,8603249669054383103,7946211137473963714,18367478567685634693,10612199999103104782,16178988368408960301,1090788578573332994,1720488890166389888,12819218219451781948,15274423340323881416,14042229590174973408,4850905243750098202,14903158012304452453,16460169815091019352,1617428521010542731,7413103733540469532,16500317198119242655,7368963593118575651,13453098423718559690,153589244346098746,10934089043016558483,7562632187711351917,7128329798387311048,1346747889500969972,12273235396312238075],"proof":[[6117809334187692874,10617879623142946260,17737328453902294451,8064935723183974538],[15928667676419406753,14660342124239897725,13472047734762979130,9528528152618623621],[5475345108496361256,6521070649433439013,6550748839329719155,4198165081749736047],[7932853803990079683,5965714636977857152,9032411870992042538,1518065022194621159],[15200760812260498242,1986419910378463730,6142695722992615965,12358311044910821009],[1524383428332321450,6390354856613833018,1038136416789427483,7492621893379116218],[12600402506068133423,8830563706885474796,662168758704068378,16816633441834755836],[6362548610965609236,632069899672237697,339931309873680386,14222564107142245529],[626171647687937568,16867849639999724709,8838714031399952826,8476160360368884543],[15338217598630775268,9634124566582780842,6939422640455393797,8457302182644683365],[11043591443538048140,2746094683662281493,8401597121967909842,6271636420189775542],[1782347771088691471,5437935348270784574,13813586204698470967,6793940799114908451],[4332654482498281533,14002561183520191652,14028083275110862096,9629044974223165063],[3427803980847631205,14636917882373379984,16471294305770136007,13962678226646071587],[1563396169511111494,3215877027453665719,18188702568024487497,7022593662365152151],[14367274937219978102,7106156626145048547,702989453627617249,3819124772645344784],[1900104538896250495,18220170488363978896,4742691525445405266,2249975310138289157],[5207881449636840982,17714534431214766577,11309683036448824717,807645417412994980]]},"fri_queries":[{"leaf_elements":[2473576032246382085,14571515869612424074,12460697505985588452,5587218652422295357,4277393583728237301,11500824416900939591,13188673342447380992,7719933756135751206,10831410973843334129,11270809897528846835,6372969733802243833,8567767541987299005,5699951533803511876,5109653561388800122,4539799477230605737,5551251178693907895],"proof":[[4681949812275303247,11998415227161671155,17816966937923716181,16790574153316480421],[11062484353830487963,1879696942239371352,14782793770311939788,15579271012360574253],[6206194981426397799,12282623805489552686,806044125097310040,5974976869348459728],[16407760917251329341,2426271935923039707,9562946437835150727,12087364244612748428],[10422798892619402115,5281517640773360979,5839835089915878348,2568225778841343521],[17524568515476023320,6198443312084147673,358869092506515943,3993376971767444278],[8240880516856914762,5620911148851025197,227303596758742245,7913570346127293236],[10302444143535698119,9513935529398030971,17053569476277727208,9092166760864554504],[12105903434809521673,6872027910956978997,6401628872060908375,15732226425927406997],[5807455167669190611,4992557527633621860,10422518820556166880,6405435764260739108],[11541016324028597002,17224420793283711972,3040457013853580209,2363039149882668325],[7124638818796913839,16629779373941763106,10846115375050919222,5940447725683007923],[567652839161128105,3173657597208681317,6870924584839215304,2313353974445526019],[910664472847687552,13752664669381403666,9708262782604061079,10753781015857331808],[10738804589373340699,15258254929028292796,17593746788419198167,17266169472202845000]]},{"leaf_elements":[7330359444718733177,6059207977308169122,8651517171375256753,5842021507041919773,18083592745802599410,249793149178983274,4319555775760677348,15981347302337656793,14567611336160108844,7871542084578549329,11900693476553167776,11484201066203348946,8415751321602836881,7537782131004480884,12950681886968344536,14256352240860300973],"proof":[[15867137689178460034,11092443536408903630,8952187602368218323,8035184548135360371],[3952817992931501303,10269199808509873618,13312702862784485637,5582068635588566931],[2259148746212848978,11669523027268160560,421220129820984507,9774723782050818737],[1778716400350961516,3532847008269983133,9448339678661732004,10868356088516645752],[13549442199742607554,15063188774733625159,8437333554699101052,7564246319758350246],[2848523846907010944,15756663113299616520,7440565625978864841,6150190294243719632],[10644091154826821991,14791307369177242196,9242846816406373346,10159528646627999253],[14316875274404429969,5427869749718646686,9647876910722343148,6476659413692351297],[9403335761381887256,8043486049124760792,6910442838222941680,4047208577945456377],[2924373707400716138,11567826282854407106,16137715100391626737,16406804845081346964],[10033408742992061832,7933332472075107782,17121501065002254362,7600898281841973859],[1419227034100694798,10469214133848674192,15473182115035622104,14052688118198590804]]},{"leaf_elements":[6228851449701100260,6299379197247387901,7036092373328266509,12832482919280506631,4442625387660797700,4874722771450323773,8097605554543303947,13892427647950759793,5708324306271547124,2268187261373738938,11615475455426692944,2432368103855309231,2048782113223835071,3893585079243647183,15828913321157431256,3527851709815738061],"proof":[[364093385423375576,14423171622737413682,8277981468915893244,3130035262182090812],[11954097954103428929,13289715623270523121,7982864525229925436,11963659339526581992],[9118521666761058624,17431495521432519228,12483621692422468958,15342410816007242506],[14189177767279638221,11697808538796621773,16624731683734680114,2943380523699959833],[1537015054038301700,9042036785436935904,5519128212544191191,4867253104668252470],[13099951622508666636,17608670163500132971,789688772706089891,1009448115431666155],[7801145774179491396,389329116813976032,5194951759966885428,7910588994996187439],[8995739209553060154,1370917579041627093,16346102083940289806,15688523016422267541],[3506279471744931397,11242738875474011353,2713616342412345620,5301654783798251712]]},{"leaf_elements":[3408073566797281035,4722203628863001374,15211621030302722100,17630659979415711134,14717894448029533138,17414066856120671394,5046863076537134270,17659626938818764522,4680637747269273948,2252750116233661559,1079879486367454731,11347124719318070929,7183232004143327575,6810789245864113437,5071438947495795467,1668648014190777516],"proof":[[10634913869348579441,7853019902808107929,12115091222173443577,2725631587612917905],[695283224603580126,3640317877022709339,14541389953624262507,18375056754251999376],[15123221386994950142,5316955471910924659,3210549192217733193,11154171958406912116],[14592720091221195157,11639324169960672075,7302237728287390698,12663057719281685997],[4989185621466157825,11455989121068457440,6076360540024797076,12244472668557348672],[12913094571626216325,15615848081723021827,17812233298096691496,5004676353765437592]]},{"leaf_elements":[5670779521113944598,11089607433741362885,12338219183159638944,17402452848323495242],"proof":[[9243860788576187847,7995673309406961138,12129992260712109470,1049638853727176092],[6415591808928206148,16708176588363309965,7095645660243828202,1153917648651038379],[3182298384929636330,3908979797464485797,9073991605201374959,2407308650513241390],[11140678322470237048,13462661405468034174,6235451994032611597,13502238937475638801],[12666719805450886465,4176671472922122183,4417725997429561084,13915186659392281078]]}]},{"witness_query":{"leaf_elements":[8012260195011728778,1025285204382792399,1240443735737263510,14912765966051586819,3208732394651251575,6400706927211314101,8813781591710388780,14284663233116090624,16936129630337689441,1493772420475293047,571237272394754100,2588236371281611278,12143209112666159747,5068059569770840551,4367119866145451290,7813073138021832490,1731126296871550963,5962658639938467164,10049708410146604909,15779403695541229454,17807804013902032919,12021428726897275829,11338285214800362086,3811311975823117425,3167194631583434646,15428778002039113753,5825783158394325719,12871237725119437144,17520407908473470222,16664821656234269684,9412505439519633691,4239372618456242408,12148472406915259280,13236670416922012419,4047285337636168794,6044716970401509255,16592482291909242902,4166177795003055398,5899491954939556729,16669068841591171279,10307650137848104346,966240240566534331,1484101176566441738,9928185058542949817,13742164951978892953,8017731138877248101,2836347122975561735,11442616584052908541,18335885498074059538,5720700762463930833,14465399641807183310,17757483106473961318,3926471816324555062,6191128787640628646,949488697669204309,2424386212858915267,1349409208344065299,14340029101634103628,15788339384782485085,14279599842853544771,15242739599540909888,9507676106158735736,13890059830527570103,9593965731469318094,5250804324055330033,15805083821915797430,18371074313762650070,4845017798262334115,5083172288248446247,11705702401936369956,15469601536165667125,6567464331379702416,2193175504116002951,5311562059726051294,11985860433936758759,1655472182244682244,10480215155229724467,10090552420965784201,15420700165696372577,2634492750058486684,14515304340197057952,2088910536955301948,7021227070284556204,6826442826721961083,7126621016588067116,12154404776955587125,8627701331552157783,11122453290144255248,17604805693172831330,9446971577034343977,1886457120765161983,15413912347274649958,7886371456734606956,5831692314883359593,13605954329514714248,17332129792957497275,16382355808332440208,5222279262996578641,17243792399413467220,9086617486814000504,5453948871251121325,16495736903812005475,10988138237700483454,10664575824617908628,12619137562366273643,124694178278070699,15651931067216621971,9023809818292453279,6102063829556524894,11218642891715125307,9015829515524553475,13371553447456861913,2474109270106754312,11972814166864990864,4355331529423543103,17625170793909902964,10224457538942888385,2537692970358187079,10569533935289598453,13350192167581402044,3216024552014138456,12097177985675081747,17575037445678018225,7033246811233627462,1003045436610952742,16435142513741929631,17824121162179751100,10602148982946656467,18192006785055303730,6430324159806411460],"proof":[[2248063245088464693,7155907751202423148,2720983349804921806,9801359910248783432],[11486094967641701424,14432404759422825030,9918823365359247852,9029851116879662380],[11503310579526822682,6337646450913792644,9344609386851871620,2318050471625228875],[7343013883960616492,10721412274470935957,5653788487883003709,10396080250476781329],[15000520289818746099,8195136205642181282,2519127915662151032,14368180910101640701],[9828320010394313511,17683007543636341706,8183984118208423400,3823212388028648427],[4553093490614951407,10479394326842310063,1502768156478453015,8011200395204264610],[12963882065154593754,3912575282145928266,3260535402171459759,11917717983727535890],[12004898944531514984,11838520732291383459,6354805917564023259,645505569970178787],[1030534223810324620,1903528854059945656,9579246645058730813,9346109841854914981],[5349151866968759380,15934328579385450448,10703425463262847711,10442100143155299097],[9692048879660109679,4584286539640867396,13442906594496978190,1697861689170914030],[3779599600982393801,17670852536101768258,7019690384701589554,3991132831362832016],[10289960702423778165,10099155762097928379,12343634958414348564,4678645793284707957],[4869257307773493109,919092882863208231,13557591648183317544,13367624940597055643],[18033592551266239757,18027772609979988597,10469180589616611812,7902938836370763023],[9254340677438738051,18069077629550840831,1904129316663908497,18334894845219338582],[16626787859327828113,10591678590060674568,5153363900127467617,11845450721433301458]]},"stage_2_query":{"leaf_elements":[7311584152696056018,849193666992694172,14137243843638442477,13076767394113047158,5809619226468807417,349049577733841033,6912051206499527110,9873306949486665471,5145657476635247481,8656390389290476230,10090418574376573516,16181069278619837922,17377483601442307941,12803575265775538490],"proof":[[5457371281614712937,8261475399361275997,16563071669192197446,13542003165664446023],[7534432673487307152,1873155107776561131,6359801308345350914,16962187416598064715],[13524515473585868370,6763623979860425703,17244043505575901629,7616147427388949316],[12621696638621200849,9569940946241281028,3319183166767093347,115985903882355421],[14755678189086488232,3091949941939155604,4728752496495523716,6823824570144068415],[4931269810215090369,17202328529584877012,2790883548766323149,4388775333499521537],[16296972782403515608,8505259282585953508,17703385185375398089,11569979683384112607],[13126608260536781845,17160286841903262466,12773379108187225309,14506211848818014726],[10616800275529108533,6000800728191267691,14009891462390550140,1091758245974201063],[12436543036059575146,17989901077055577473,13549098665388491711,16143331032241614872],[7058771327062734282,2440942544918241680,8982903546653111963,12087675386882490566],[16803410247089787553,16415620769085498379,9910299723094158811,15719428795701568156],[14749768082433325374,11426027368209568020,10879400393129774173,16615955975590907326],[8186096213088157444,13874573100559437605,15191652056967849123,10607461390927598522],[1838211583011254920,11486174194411655827,10335489909691796848,12404380303512938190],[3039490568186573488,9326189058806427655,17844054803060681381,14518559237251135930],[14617052641357379793,6845019211715381432,14318462590570319022,8534846660721715164],[5511312150096494805,419333769699462590,1114666534855983284,12281977652822565677]]},"quotient_query":{"leaf_elements":[5706580359140084217,17383726579648523658,10001637660426619449,13652026756631960093,15480460964287360141,908442508462684646,13258290192679864362,7525406502650560365,14279729126252136380,4086572445302503197,6369158194939091919,7937909258300905947,8664121589898114159,7485782951423173231,10024214843321432546,1701643292989764173],"proof":[[14538651296645274931,16039184293097172084,17815173334306126880,4041978198750830642],[2580008067313579693,6339590474903893451,6995327158388061502,15596157618039194826],[13161469575383128918,11754988006934544416,16197511676588096032,9843075452836176265],[5262486553065344721,4389519022639996311,14125324262808289918,9852745743378941414],[4080465249863113776,11823702571691896760,17670199145438024247,4347187742684333225],[997426516081447541,3795323071102082469,8350793193089724701,17843704215791206179],[5349025600482343007,17537361158124770600,12176733523464227982,4383045789830009034],[3741118162984965555,7261489914031667745,396399861540240339,5361872907566161670],[15871058574488196935,10622960992713674428,3931611574202467359,7843900325278072645],[2533903188196415495,6118868395082753046,2973057716004467152,1724042765236021643],[10380058726006107408,18054431761566187532,15668081539121275182,5615570054159965627],[10019806935014822049,10516443267238354037,4297376376419665086,2036122116334248769],[11565258571685564368,13950009724560418997,8978160316034591124,6313569542675868116],[12044516204212546786,9253979312900593125,9508077040696163634,8375962727681697342],[6847402289918457791,11766542765145068816,7274550599141968319,6917610912326460099],[7395014308380599390,1003696116977907753,736270394544804296,4727087591563774039],[7371016273869150428,16115620560192911884,9831964714465300895,12201066446372879926],[4293389376513706323,7340530374360499354,4765310210140450451,6170562504757807224]]},"setup_query":{"leaf_elements":[8880803468704890285,6120232374803372221,5653612124585205065,5406285249976865597,17252799347029531561,15686869064252719602,8781703170308130569,10930901866132493865,16109156103280733583,14733280752085216282,12428465489173096988,14040595057438400793,726249711009709328,9199077495518047816,10919077950666953828,12283277571893324947,9334105928960093989,4031221694019683561,17401040476629040536,16106671942076084052,6873558554960116155,18294205784738776734,8587676099233868333,8820445078854097878,11767589273539288368,209497671652498027,14486138811182513817,18256495313180121354,10884451265902489046,16243410785959043723,6885505151057248598,17467361520292251898,9800565289214340866,5114299408813260879,7080793773976602495,10775686608260109635,14863616301175281962,463067537210919286,10284552181007682688,10337504559872464478,18262282165013114255,11633429224101756940,2433625736328945159,2319372801151926346,2457430618382553983,7688497261856959778,14309893621456120094,7155592827584750447,14883253703707748287,2383087472864390874,9549967187169845540,5095104297932941318,16091673384277724010,10272274768657392440,14070369650601098933,545106912156593931,2266984349370825469,18349323733291274175,9898731640170120,8857942397263831232,15991752247442155256,5529523059204627475,14108225836908608502,9580141773937836356],"proof":[[4650864164692725945,17931896299586639940,1951585966905028312,13874463660236629863],[15820508024577868024,10115950275408526299,8612745168199311076,17212777270422738126],[13544929712060750707,16099899193437685241,10784199314138259959,7966729008243824727],[15123898475939523879,8112419295824925534,13522740138797159701,465619954920305991],[9956145522042673787,15619593612939147345,7139996630004960915,13109978916347496579],[15743416586269805525,16735667340299069966,7599758942812884459,2553664071711197731],[2829337431820609092,9658435043623740897,12043428381232939668,9422334241750263392],[14991345550122423780,4419658388364542400,10501635019248785913,12451451269155470954],[11367252056700997123,6975080449412969922,18358685013364680391,1861633188343625648],[7945489877399894941,18317205388517686373,7651631054069792257,9334519080514500259],[11986893743044494115,9886507686356113335,13701547790874502139,5788330439871097545],[11384246540665137098,18114554957263464721,14451498127907329046,15293584352561613397],[8188788732679107219,259934984722530092,5529145063207635334,2295148167020522436],[17596559179146511890,15745864153704160209,533564729334657506,5485732298220383884],[11968794819482208883,17312250708886680237,5584827653472768603,14691880390309490439],[6205830079291376251,15959050989215705938,5698218322746034778,9754271032733135243],[17800221154943223260,4605887485663436525,2867377451422893191,5110867604661478927],[10366387643926998930,18342697872151585877,3467584844104043212,11554409319084066172]]},"fri_queries":[{"leaf_elements":[3294184555235936835,9270128996766456001,2648110465336156895,7458340584796854762,7120468421583075274,14368565589404352974,5820015828205766267,3783718453877843591,3667968155994856440,11131988447992984489,1619748556972284451,3143552583972380553,1712597454778213169,2414355069459005275,3980900829784709387,17315622953808699441],"proof":[[3396862335714893037,8333241703546021149,2825144917164950802,9233574581205589957],[5188563648493892163,11013494926573788134,941680045155051587,12969731702790505950],[11490650087717143552,14079481406672127989,8471843881614473732,2142977949233305975],[14257446610032495802,17987792735488285813,2050657245020619322,13214479356862776325],[16970935390453818395,5050132066222801230,1986745803075066572,14339596998975319621],[4837171209313288833,8550339953175364542,16909564862487285635,49546873889762218],[16949725896776009497,1608252825984944080,7229865169977793073,16186530592196875276],[14682717832693206602,15826389492331359180,11957422137256744699,6884129350744143451],[3656436778718689643,8394694471992002128,15418401520583678522,16911595413580666004],[11331287221535761725,18020301483916903595,7543881753508355105,17216536108340185123],[3570821552376678643,9323578836432208100,2597052939183219240,1065087492147545867],[17054475124904444058,15332172956671080434,11440130387971024702,12318433612412015248],[9280476743046361621,13826773205829907213,13701515632791410470,17549281025637087383],[14881539164621744318,1425188519528882725,4367256595344195276,8009445177790881690],[9793228082528259425,5592873272686314588,4875784681209589849,14785171053012274966]]},{"leaf_elements":[3832857330791408909,12052181768951242181,11690124767887042319,6777969953102694340,1087444313282700411,15333541393478750859,2172454664939966884,6999791705102465714,18127996831733950081,17968758387610668749,8453194963496317844,8388127157242296963,4991553123424176326,1222669626284629058,17338627343044174266,6118181860651978476],"proof":[[18006317449974818380,10693041917029341384,6477464625148349729,16890492359433933742],[8446002360211555652,8839136026367634454,1853193228915896484,16305464078561596814],[15435956177279106640,5172396175491981456,15173919211543610750,7992526297607495810],[14369223907100997569,932766310811439878,10543842855600249593,7772735334401323337],[7300490295333998012,15395963499047316058,15522182875390740399,14196149315816706795],[1911178878180915916,13108161897677716519,11422423599244650576,18238827851043945492],[1998593747462522383,13065966869467127333,3534639645087564367,1566726946309038499],[3039647654892576311,5249551648450955160,16413261940654376832,184989638771639407],[4867548826735474264,10119763299164812997,4697583737534991457,3404585328995787352],[10044294214408095154,6278751489741787191,629922485623532438,369597611651840802],[11341967103655077710,9880801347006761564,13230190997400175308,16234841912272476208],[2805754139447898449,9032506466856427920,15814012214845267994,8449971360592548494]]},{"leaf_elements":[4880502338080409517,13547981876049090467,11430050966425598411,11810216015075928932,760374208733886335,17340276762031209543,6190977437052228248,17949817769552238808,2286281779919119308,11545095683133403208,15957380280805951013,16333841718024705344,16773304150786157883,12407909948433035026,7206580791128966924,5864125030275446448],"proof":[[13026700588344311352,17361131592659329526,12395742030723691987,15971108577341078584],[5219117153143784386,10490146170904068883,10957925869756058827,14183738539576099488],[6725794809826380548,17229817302822801854,3979427014330855435,15645785516113036826],[8507420912520906496,15282880232660234048,8671487268052997423,5912876853100304332],[13025786120907848870,13782596120677445359,5126363573952106056,2691627401538389241],[8775284726664092996,17133905887725845311,17270945045589164748,2368027478825141251],[2084455494101278095,16513897573429844420,9639961150896883366,1248594232664972207],[8198106426394540094,12446966026410613237,12419701871482256416,15557080145464949698],[3036063358292700207,10367173521337962358,12291434036422842687,7215014166551082706]]},{"leaf_elements":[3227355362984450269,17553086811528993081,12127011499410330288,531720015420096886,2749188088857008007,184410665135162052,6233497743993179837,6895511157023694369,4584156999311725735,5711209140270438550,14436842389976176798,16371917398610831045,15834291444791982719,6307453238963466910,9699073814876568726,2523099548161149141],"proof":[[5395925841426304290,18377323963807864911,7077912696310443078,16109952201147030327],[15186411597414447316,463571536129061955,14172498552665993230,11395936789514215976],[8832285959368860046,17886678264121113864,11316946605282615973,3217084414753832112],[10461044557814560809,8291706387804442906,4772782064301842758,4980774312595840828],[10049941778828180186,11097678714057078551,11374362777186741746,1167449716550005452],[7910784131205845609,13653454751201827830,8738235116344462180,2122685963808046229]]},{"leaf_elements":[16208438161285500776,551948793569806707,9625711940924694395,1668216021143855470],"proof":[[1785248853172594941,17745073277565183632,9991100266726418587,14776408067330328470],[7577799696030649437,6117940517615764713,15147686031867979345,9771982988714261635],[16562776856071358698,17540723132252125119,15064613769536954659,7055742616078694263],[5964966024583300582,17238036245291871088,11546007143884546140,12358971573439911351],[10324860997149404898,14709921536372867418,10662809617754346078,13590046540121176114]]}]},{"witness_query":{"leaf_elements":[4375665596889441390,11554762127382953206,6157359453919607104,11039520788833377476,12485872455905919202,3240469184184522277,12016437956119225755,3396232050540920642,5933459204639609824,18265822539769200888,9658383055914536945,17752278008516462340,8951642105403483100,6115202124975001780,1648873393435473631,1672903555819120438,1301581802009449781,14479610843828301567,5371975036026629597,208163978206250393,10609072375043274710,2062127602572614244,10181763641185136606,14148311897412646124,3422507665584054478,6574007092945343763,10657493639715852853,7533978098918211703,8711903369924411948,5607272588668792292,10431374353988226034,5667715730339833397,4270211939999425009,6299927716421139294,6000378426482669928,5858072958540116846,12592980556078857944,15070374766889368038,563637712823612885,1607698383875805611,13217054223599557423,14012440964473695707,14312520336247805591,6755231262597769124,15699695039737886526,8690542023235768401,10393188156184419441,5609855220369305122,18281571851445528570,843143147002180243,8896443891714537720,6018033016920165211,10551335017073142044,14945294766274861583,5214930232744203308,11396591157878647307,1182843165571780593,15555337988695398264,1415873170692139466,2287927847152635920,13883988260520627189,3727212321143377835,14872918685202346814,5565187177653841222,8498727784357523277,17588324892113706420,12289859633976919703,11945106985039901517,10835527820160263370,11293305252059108847,8317865339009201592,13815454665119164677,16252750271615385082,11279150369215555140,7433506851648173264,18196449484818309891,4646059305039425193,9508251391714948040,17466788432941622338,11002826885658244379,1640711045196963562,14647202693326269092,8310995036795381151,14441522146076805013,6995328523653677293,4662021139831184627,10941154084714373866,16105531535362107973,3550842166362026628,7076906807165928289,16550378398503860249,8443563001667872556,10111444322108266721,18019670466001514749,17089418168151980525,6102680589813538302,1308922349830607574,16597569658865519432,18010849293738735024,9998111790710074424,10685419166425142081,3005817664460191988,17457429339042283090,3229829326157997934,12399455263332965394,3927412487295397781,10447012957384394716,4423715383607145265,15266729778574630734,4975606559438551388,1553340926772556836,9170072791225852678,3301182183349589227,15983583483891912194,451403607387418252,12260325364279113149,3245388174389735249,16618248092246940169,2846929778764897204,8677787464069245555,9340635301206882047,10970223988707246346,14891837594665975415,4385832259254479705,15427978912507540590,12939691229761524330,13674743436613016498,17550414831182544051,15612460740363460419,4443099841753981226],"proof":[[3042666889351690566,1720621798262361739,13900037233732485691,12381139652520885024],[4141730970958320342,17537946985765962662,17196196445718231774,13493530858212144546],[1682172163094270589,11368988608684383058,11389463412400889298,8868780492648779218],[18232270139736212129,5013136284037593495,10309622826996538295,12772088679316752432],[3494386948258310042,14607147831426660942,16691665978591032298,2180974554344405990],[17831477557446664734,16770855216319627258,6437307534178935490,9159962080669499426],[14334949362918788224,13705862620805908917,10920410034104547866,4903941060213338205],[2316999820389512589,4305853695228735819,3723018922728972936,17890483222176445670],[6578262403937685038,16265453495378864326,11849156398954345772,11574413922254076761],[12301288044144469536,3106678351263005561,13281444970458840,7892602520297786132],[1327800782150021309,18050470989109258881,1806176149862043376,10751494968082262774],[6331284101798729815,13086632162046393224,7943534547541865289,833025576209666082],[1813336577580058424,14276280838789184612,7085658650768927103,943902165374232522],[13076584036140376505,17266415732529081270,256479280824679936,15638706663837188307],[17662276184362482715,11883769768740905218,15072680637960318842,7450325453152542826],[12074712573928370215,4700517437467879698,5163370175078370589,6387152929180842438],[13574806515437767400,17914331986883162246,11215872391501883692,15395570887147499293],[7298924030527576787,6106874661418284688,5813830148649555790,675934481008424145]]},"stage_2_query":{"leaf_elements":[11027187450444789898,12794175687361089577,15879308523401989261,6338583034266676307,8585744946981429963,13602947267683484557,2971077960920400420,15148202136837140006,13745973026743531299,16522605518704906113,8266510921532585578,18012717437773499586,1534361386589952200,1353983398366246592],"proof":[[9853800455719611252,17294267826258080592,8046513263539204017,13564046666566445708],[10364500621455282572,13473032483085360299,4952174144954244076,13205611777916233678],[16624289738441714449,10863967362898320334,2599819756671470580,3522491815333386580],[16193828595111324934,2961387996541387556,13576635758202539552,5351889120180206668],[8925117054830300247,13834984062624484333,9997798202596602800,16019420267721143631],[3393506844126617957,10609314544254813679,17141751159238931962,8228658838180470111],[6062963258976227812,1561292995334807974,17723307040061739717,10167314784186315824],[3885607086864015074,11865228053581887451,10776327398893917458,12085249414221664090],[15323824876007368842,13676207560709887367,5570410984675101849,4394390274397070430],[5343495028232186818,3342125879151684852,18041226514695569317,15247592500773521501],[4625480549723126673,10837952302575009124,3525902174949612107,13208352008569269780],[6261459760242147251,12562138176023162046,13541492129004200223,15426693184542163962],[17303768441166073594,6944311825914368194,10497462300117580972,7193629123568710374],[1132935773416861214,16986623112698016041,5137008761029044327,2710370502864203472],[17631734561721470362,18293590908738564902,13313612401577701000,11421214518409001731],[9545365802917579288,17514445992752587967,14767541788179516255,12761584776494435855],[7609193551382950930,2569006051003626180,15919541557998069229,1544060254021467953],[15496941387688411795,4272853557216362711,7640826143497123888,2288489950311330717]]},"quotient_query":{"leaf_elements":[11825113525499642918,15634915015044959948,17276683461061695192,12606691938573384967,7631962873826098248,5414621231371847106,16013148375534213710,9503600106722450899,17668857172919175739,15155323813290021875,6635925162012227986,7959958250392086136,5363420151813751956,1121270791312364545,8485059825680632745,18052986970429859923],"proof":[[8405511935672603716,4468711317979017421,12326426472068186333,16187683250102719327],[14729698719063883637,6583705578237048317,12779538249046117706,3427057303228621432],[9396090937683630830,17630509085116212120,1746782877551261631,836698930054236623],[4818709396568576096,3154235973942434405,13125547971827335873,5127372556615449370],[3096101661335170094,6097667188875223835,95435104552290563,6657996291862750736],[12462079026880735585,11773780768383207700,4714814411853320279,12489854779554596527],[572013286458835827,7904861927143377072,14097890521661302037,7600257112504842524],[5835874953718011985,12193720481667556491,7826256925934622808,5944761612171367085],[6749102969411190772,6622893336415386195,10360932201825462617,4749543981063429315],[2087693412356978926,21301938499275945,4072851923220171721,7973485611886048128],[10822397728301359085,2321587287868547158,13341579204937340676,15402963083323668306],[11364544729473593898,16754206492150667344,2397112715222546715,7691604839232093275],[16167197240393436896,4822554183134619934,16139977801511026797,11896475108142968855],[7211788618044114871,3689398606174509354,4579487540981017582,3296836340899631937],[12829689956331449441,17145011230666020018,9626981876625744131,7592577524384884663],[6940856409910668240,7900270079400015779,5997851180518031106,5666338912012481268],[9705371587450206010,2123154254438976216,9928637200414543062,16350012477358718111],[4570870155188138792,15266948639487955211,14637576315345253282,9238144834233778605]]},"setup_query":{"leaf_elements":[15576389439751760015,2882342080098224085,11469309473959793296,4840638078089220823,7445059717526850732,15720905937434459537,10551003752178242564,12150378696859516901,1402196341179989918,1260860614115422424,8263942807887272383,18129089688472218106,53789116485732110,1200332094520854731,18412265584710442448,1222512963046746370,16145771935602628619,7873308526860470296,7145026879139711097,10999372975126612251,17054332810488274619,8323472045456054535,17732471091674096608,1769219134035114805,11625665910332598657,17813470026770544979,5447923242082999973,18397535947640918320,14615608494934338404,11970738912391375804,15417391860505917416,1666063900036864616,8369679403116559993,14616853370661587092,7599247226441140097,2334701591242913863,1919994795156854592,11356074843420231267,13338869506558395635,17900537941057774228,6094207344398873003,1567445540581374622,9774429502358921161,3736160299677259423,12772033366193332990,9384181774840844746,17121843779273027265,17322742228259563929,17289863428579541692,17642551648314553981,15725589908854319668,14736632645876048621,3350854119180313334,5727348287804564057,4362401029537799760,15110072484619709162,13483207989577207773,10875932898291905906,10561632471740979844,2884953699801216153,10063369042664990541,11455887951846735211,6600600516068818104,14823634818900011691],"proof":[[15552127562809286832,3622683065439613961,4312328909369301101,17097651246504490142],[5706049206343312664,7452311478275512137,6423847532111374137,1665919348874141921],[12657269927665149666,1461422431646369674,13489882422956098218,14040036658705228642],[17179088101745388885,13189515940110643508,15135185793960471805,9337908380890512051],[15396507565248695004,4773029769620558377,17413868370329981966,8452573019817733439],[2136535960320293702,12168091613841211531,10884218731391033175,12776708455388636303],[4794891631086655705,240607342506829234,11752062289251769119,13464623935041496850],[11321370429689912488,4142101525778742046,13131403687259496143,172080949973706760],[436271931320505590,8222901879429033452,3073924394386280622,8620098343241135960],[6222025025342792168,10035521630819407146,3352659269374554236,14523213673472260345],[5299402577285375555,604458695604341650,6634597085503800093,4136234626766445473],[7722798362011545122,10998473542079788828,5640308642979440866,17591953713332948138],[11956953076767829915,2741381996582817650,15682396530002826716,2770956937464362072],[15626280346793980145,3607956209756714776,5909861949617019198,1408548501614087752],[3932785409917311031,9864495239252725036,12712504657257102499,15403737948149976881],[10756496632368304936,12581063537945536162,18141499731136995053,6817337762693653903],[14928724143875132233,13963510086886257579,10949355447829410579,12750413111252461643],[18372132326669368170,1821446464922599669,6272008540613239354,6046582007206807696]]},"fri_queries":[{"leaf_elements":[9128392423363968352,11735802642575197025,5652474149266739140,7756115465091892732,4938972435376153608,16408092695437644389,2630391803776352213,11493413365895804041,1363088061600942239,2238450442070067811,9967887222092889862,5039013780324076787,13511608273442734405,10408940502978961904,2636125715360218639,11037623310175805001],"proof":[[8990799024498446892,14420201280991158322,18346161347245919150,2874110221198077796],[15481290238357307936,13072592270458889797,5524529114665286268,12745432442572818100],[18122722270228290563,7925501709297739724,16155900823582895180,11253800803788383502],[15175698211588611302,18261140402078029481,11812002764497173037,13374427967085723460],[3171867995239824928,8011844305534927572,14841904488973875771,1455974049787413720],[10519612371110616402,7855016975852474774,12928226048749125859,9234589615072033855],[4253511163825704316,12104813938391297977,16942340891153970947,5863390316935812894],[12023698599592550894,14333018036286894051,1921820707239109595,7363622715783763704],[5743887321348058503,10424330542994345510,15440720230972728803,4943153651299549253],[6870369308165146799,12327819092323096408,18292236376294303053,18044758550823635591],[14393313970053995015,1199030987003025744,15384584277703251724,1451509799111018800],[9421638787282802906,1368064295201121985,400754667019636376,11121381935964926433],[13664717352342623510,2387250668273319092,5515677044204498265,312869450073572313],[13271906502160655825,5314341450834137720,13131847898650060124,7063848175693357806],[17798916429192716227,594417564005495930,2619044529242577522,9012608649392508762]]},{"leaf_elements":[2066466641350007883,9978293115578412067,1523606786247668171,17547198678960616544,8475120831228614432,7119763852500240459,7025914516089478757,931895634548000464,12256641012499485036,12620553741503969819,2699600832343612869,7904927092870152165,14752842162697860518,2284617250152612273,13275805926264186313,365414566196752909],"proof":[[16682054758895562204,3593035860294461466,7905868389055324893,16950656469847083422],[1717930479462734738,13581943032027130960,17532698438954264944,1869289492483834434],[5982885207734508015,718665535125181386,4210384496637114681,6208239841406802693],[17837093734592295224,7070461585357299252,13212828059134295435,7287250103981378177],[2668846539803396819,17851695933364310249,14152797253723627593,8795633747763741388],[9938325592559113229,4712220407571173597,13608983608744405645,15109556406757451588],[17806545631578300700,1721928759327372881,17065033680764725612,3275475772175012063],[13467599033445556099,6803833174472978710,14306922561778975728,12638055296226993859],[10394049359583580054,12537689883855919338,18446234363438696332,8572791545650786677],[17023645006744338786,13816167205987260660,6908261491337925208,3573288690238876085],[9150326813068017040,307189171178543928,6487288896492346182,5364664623477868750],[4646419624459045094,774525811534538311,6184314457750389328,4273638829652696859]]},{"leaf_elements":[14544633195841255685,12800989127260853884,3036245711539517919,348204918722447923,4345693417198346292,16143950380043712090,1642580909238702122,16511492239142814124,11712995534919539150,17090617316859353214,12808921683322168828,8210426449066100263,8619847271867659904,15735654392178492978,585425379894403661,18139027955167004188],"proof":[[3860443961732381152,8805353644970076830,994191964353379297,9288124856640697470],[1538193197268853239,4697880702898358545,16050855787862770149,6533629829916079040],[11757607397351267764,14777162722894842770,8990262397408652336,9009015549706098959],[4032640173393352328,3109349991677264334,3950141660290868228,14028803735575281323],[4428524142545408309,8202836136187789572,9738678847465779735,9912389897068844023],[3097550963200591020,11679511546560227088,8901823073455493932,6402604425094741745],[13151449068968045211,722941269581350421,152157409976266098,18178666624826903353],[4665950020414071561,15310299763886049475,16798619265046406989,13302809884219250546],[11782310287091909659,12806554866206448438,14849420250672972749,7530860185090193985]]},{"leaf_elements":[17400064220112898747,5872006110087432124,7454462887905751181,10867482060870750953,12783374301392908143,11384667143063504657,13988895381089112835,17899640347577488200,10211981899720578870,5866228298603450470,1903545815956582632,2546460314940343319,5907964014062273969,2663661553118584452,3972730522631472902,844472705441810015],"proof":[[9628298395279839779,8605917723275039355,149499791925510614,8672747526417619638],[12391451373949445444,5244916677568838709,13561037887240582918,50145454389461844],[14105664656194133489,5474232335706429794,9357753121768811883,9615550462966106495],[16186029216367431254,5362062126845735779,7413079663078766018,18014380826357249026],[2091873898711444810,8437889310604871595,14097408631596783073,3816447128249102095],[5567381475413961407,7979575653722955626,7420594698496685559,7415674171997100410]]},{"leaf_elements":[3276086154740118909,13484300800115188574,12451028418103025357,17289643613380108829],"proof":[[3777318073386875155,13356518787560105954,12696931034725633742,3837009864980330424],[11946123083890349192,8985768374439309938,17550301514191448140,13108978974592377487],[13480083309602677054,6739985060959716454,5523104130753217058,6937159436429156801],[2519035850991120803,3265274169354817993,11948632908044941855,631688698788305971],[7709833662016218895,13649926181068180800,16280435888060145222,5076252058493378442]]}]},{"witness_query":{"leaf_elements":[8940666990113190976,16506825171286587639,14586637015297328078,4470619031792706768,9847029828615726570,11339555312991977461,17502348429891395650,14449562603790178665,8030103628903415714,15900878862473064549,9069839437916160492,14872088499804280499,2474053812582408486,15730621247483566895,2797611520269316460,3138253168482954506,2767122577808090375,9410193478198470549,1631772138286299183,18383045354708632724,10888960569646686303,11026153259667797974,17254274835647088122,4779842723118282405,108157348122948946,2422556183286690402,12848810211138719783,947069760323978691,12047116715089581631,14985646255251179843,16626117019416224313,15101779233691174185,13350005222903858606,10568581065167625893,12073032436077789048,10804803377233782987,3854403312478399164,2224317839854375056,10189821641154918442,13340686937521676182,4994395515749012660,2929526577641045969,6623817303972169581,6387861764736541728,13329572808051527154,5059373639116739661,16284093303979498687,11034949353487572451,16980951864104968694,15174828850574499650,9968058778913837888,12012537072102058367,2902135447017303849,14240035712108292711,401371551564761392,8400405245394247512,3896393872172060378,9738982612421102465,2302999775819267724,1526928206770438474,8188719020417205689,8555119822423783397,1989798076416763419,12441176935511632600,13625735050855547903,8458403168388574456,12904391799146203294,6375559290806502009,11407300485932378561,1815232914633689165,16218061819798787978,3366694531778184997,9767567846684868656,284491361434277067,907355296779443485,16291004433338478136,2224235212885136572,6343735136621325577,5411697350867851356,11177498621257996407,16186093652117654605,8466834839511040399,10426520651236974603,4338379783632997405,14806810183159790215,3848792756440819774,17566079945070285259,11784749607784724468,687035150807765064,4709476122461940782,6323404302705234332,17749327479140395521,4936871705883685114,3357056764546722342,13297977336134565828,4456048048425586078,6134724941004645940,12778159869357364571,4836413452026512032,3599683031814887208,5049281136728001325,4456686292650782177,2870530845734130636,12271867734316454765,10186017759787577470,15591437511868318961,2034888524088882570,2504996325128725137,8950790992819577787,3640439124800329824,6530890285010883299,14198932611213535774,11068858843610462914,1304775306662172035,743033004320734110,6212070024299309804,2893329285741862267,6407289317306414661,4925560061229536265,5962337828415079536,10449505798027567383,17748963484608747923,14035937722429001893,13265209610378738289,14630138459551693672,2089760763799888502,16111389574165579558,18420491086549800494,5601504101168039167,6290799887677313823],"proof":[[13570934114528166672,6165520444359943384,17322078750049628190,11509472457531944924],[5297364779386402948,8377101180570342435,14810324391655036069,7220315902481828547],[9237065083094485129,6951491283166893731,17076150910313456512,7011296677427092512],[7899713927526171176,15109396477068735934,9418228302055023546,4443039302155067567],[6793584213872261245,6352890527681367399,6616608384676748824,10905512970626200259],[26647973904868582,16489552997841065432,651194100797213075,1539380297226306037],[10213751896517789475,517863100887434286,5571605823649057212,9432807160457539760],[1681464897553126413,11611906813974014677,10371707882280190120,967118071901543175],[16779620918868784990,11241684752706368896,16237634703792151458,13977037107372228161],[5699955279866449412,18241784727620018329,7945605788070870037,9348738243672046736],[15195985470212920474,16281662041306761224,2216294370417630265,15701553861893833247],[11699785557941690579,10926891102068330109,16825377296894744294,7507071525097718526],[16333382486254923894,15582570864007842673,10710968877575410316,5444289772287858659],[7870638363941498722,16098276544709852438,5758925342347148828,5114038691850471304],[6142635022287696861,8049011173836651618,2792913922172386457,12319172310131302820],[3649263350228941199,6173249667718559680,12196228172609062831,7828225908594660229],[1329518824687954791,3954999000691791906,6326506370773435321,3192504100935246199],[17795281634043991196,15269729003924764429,2540497320938438876,2573226922376803593]]},"stage_2_query":{"leaf_elements":[6874149202100455228,1491608494235247218,16431941867776377506,3168431538611736456,3483097337544996362,42974063753149435,11214535280810363918,8220131255632417040,8031449689472154442,18033952505965613291,8467630477751674344,6272902654293125546,11076256262351379478,63569199653830514],"proof":[[2390884097448863959,12075257738062435687,4406459752927536562,7272047050213529554],[10631595353549351323,16110892118483625395,805411952573469675,18219724438713074078],[5985353496762747763,1639065352744517203,10681351542445603294,6440141670467349763],[13862031655394700883,5541485555457625602,15316747998716825447,5331667137533524206],[17271362683688614116,17247179804294733029,12987278675839869453,6244817203864592403],[12030651788585749472,3594277920936771714,8994930745794076738,13204232197616964445],[14313599443720252335,15520134160602244002,7045973344893064113,325629480117361481],[14864063082072696056,11449342916932072386,11422298939160525834,3982737589741373181],[1363986919099065568,11829538143304066346,10395636749559850017,14932793693580083561],[14539420658923838153,18133333251722801394,6872015722369971584,2815339021580649499],[564735383306833524,14606373434160893600,12954312609145266967,5694794770586546619],[3807613550707834479,9234000871112893310,14950729070983771764,12289614986176706360],[8922715872651019575,8782097430872905422,15992016655181714697,5802174126932870622],[146914447380503525,12076060809277362006,14407256752508490876,6310252506210898763],[18124593132144827327,10147896607080004572,2187620985782780956,1836108581699091117],[8923139134213421058,10721993411494170705,10034976733989990582,15554100409434487857],[15875572327684435918,235330459698251084,13894808740860311416,13162095065778626437],[17200834457584013945,11821951001578261504,4162204268438662929,6888092700734675328]]},"quotient_query":{"leaf_elements":[127730359685814717,8051999850603203700,13268083283092626249,5762389992373061294,8247810084873212003,4845990214405007533,1548537219287142099,16505302867179122963,109770716089523575,12440682836319844089,12625879688532596774,14630800849631684498,17534230605731004409,479779175824152086,17189194038094597144,12353705029437272331],"proof":[[10529764986995761930,9910312223443607623,204437398814615821,13079116026955732860],[3142826676169951855,16808598891994485633,8840452929462110488,6900323582950853633],[3569431242037115306,9068539750507299947,13349525813965343062,3133308391873175128],[7387942412136098794,14968744161545919237,10121644744135693325,5583200242016059738],[10379731540395699750,2826056239182932530,3077285250333752417,8713423301448544218],[7737532348690323784,12260443017391534067,13915178906975064783,10114018150499006753],[11419944005381891534,15762510334083979316,5451052339574555845,3845612969689451924],[2119884713242847276,12653851307169221478,9744790812973293255,2833594899457299196],[563997555603260040,6284327216444870556,11416698785924058895,1241020335640799997],[4668623285896194488,3232583604343605807,17520171448454393852,10778792719712372177],[17481266789061855680,12448663814704341421,7880535446978982337,2675169388987051079],[3628814354699504728,2508337035357580470,11890790458133423680,14961754604990104248],[16449101238366196641,13352711448598240015,14794024418586353318,7162674812363977775],[14103621029238288797,18402777668282595356,12660463395023531331,7228677817671136418],[7811944668060403372,2660675510489777708,12578516193093877610,10780576226694705446],[6215202543180857707,16973998978993956065,745744673242377599,12734676896153057995],[9007680813805623693,7896069277529689315,3739544913406994177,9921164113096813017],[5440438953945002424,2231881066814987546,692206463748314650,15379013337233262328]]},"setup_query":{"leaf_elements":[406831160110286228,685268478108703403,3918716245714817020,2115607761629464872,160840988883224043,15182616721089356304,2418060072364118933,14382098802118282640,11038562496053109588,8420177449097106557,6781132890614590249,2178650923574886017,2175474483147479878,9038618853142906638,6035224946833575323,16770149394840959388,8814763850411471670,14302148963887357266,4609826273773138188,13570136521860155661,6738421842667095397,2281540064917418681,2703832950445901988,9365042274249669564,16252065324220590026,2150184844898381562,18183252924462985717,18222482356044295658,13476906159581120502,10360241700935244275,10119094820304511296,458884744011933716,13546970010775392346,13913617406499716437,2280863981798799212,1893211081810347268,1088451813080301377,13961128383191710588,6553687376262060723,3752793440018206229,15546520299997925221,4383461365725307615,7500312446809425810,6382738071069724736,16161366162818215513,2076908409223223555,14606968784776050278,17463518165283528889,15151305075027588475,984753552152308773,16110275529143631368,6496735589248631944,5488154579859908286,10516277975948828417,5641622860269190412,10687526427547090507,1275518086865437321,18168252933275554191,7672998889347009959,14719273507232569315,1803612263623895378,12931911958502967128,4562870979267228429,10160871756484494534],"proof":[[9915970689992057282,8896533554405986847,8768557573269860609,18193088852007140869],[16831257799793060058,13997764032299486769,4134569160888835348,6691064674546399146],[3347162974578960201,17693499903992688150,3597103967904808800,10640585634228631484],[4057830076192494901,10890461338475722501,17134255139396374358,9658017799708707336],[16053883618615328650,14894210156477924077,7421407100516069376,5787838430709645601],[10164751710946231209,7987844030864942512,18440647968532203374,8003898128176885938],[2369971408773180007,8849464092120030479,2598847931379928530,5709870500227343968],[538017774615091974,5132621802716251038,14970110146659412411,6703984123633770869],[1885145655943536643,15122274347610547538,15247868280334628887,5991150535076456977],[12510811184984388833,2925597555117649371,15541770376028917248,14980934247277345469],[2824615326310008680,15528338700596127284,9382301484268817691,3938949011833492319],[12228148972003110687,2825998788063742172,7322926748934357317,17006279527404760373],[2153644911312319596,18045612793958821474,9705281272025779128,6431021282604648478],[8954885183364445546,13698948805373754175,13146865001772593342,8386899562718697850],[6628271677204298981,14220698642396017099,17966992086107351899,11544947986761904176],[739659851589833139,11791919722310581989,11486711477638622289,16831585938822218784],[15845019084015378539,17939526086513879269,16210251671969754644,11521650850905724115],[3822971771416016637,9204552801728509602,13260254553574402576,1206550035001210253]]},"fri_queries":[{"leaf_elements":[12926415928609195703,17025551313553321683,14902583168486286972,1537298809176931495,8802061368630172088,2062370831382353195,15988737693850524930,13033650984815491879,11158607557693660245,2276021631319456728,12339340957826965610,4323168652749753826,2592859342275488765,12145008086658294927,4123091980256719971,8445848713100622578],"proof":[[3688121329073618830,17641140424428635176,17075306636381123193,10728966854453486720],[17301015896767248165,17685814276051629884,14999683111572289594,7133382595564126785],[15423590292710964737,8628559452118876619,13308972506232011687,6399484840486731752],[12466109401927633110,3826533899900850511,15416366109760190298,1636399736101267131],[12702823519869643747,8465782914757999708,17260773145152908301,12767051152289316475],[9866015419047775235,4573030188453150663,11171095105975572896,9065597981599889739],[5801747105150507631,13975804672229630100,5779792420020710585,587953534573826357],[2238729901435060811,4243574456115604236,4338753161348472068,12719095564377751938],[8092218483857681001,1962613022102872470,1752636935430696215,13001922872984727331],[9547259003520572555,6437562014119650595,13828158786966840407,17124828597271786981],[9858772388525347551,11283444075993378754,9787229035901075205,449283266227538063],[7412227522965097055,7935203789920154426,1048816500939817711,12893394803190701833],[2526106355537996810,10534034824890166709,15566394322650143129,12200855569543938686],[16315503897758828702,1945072876342465957,6207466470877707890,11773430256961012144],[6362304469411611939,6506419859571639845,3684411728997958545,211024196620056567]]},{"leaf_elements":[10361886217967536616,13231357781813057411,13345131932665317854,18028296090794022197,481428048663649970,5564925927514631151,512134644343660306,8447469069993153477,8076457031212584523,14403147234586560296,16749835841623609291,10255086964279640855,9953725484457688273,4828018408112602483,10574876886867914341,3207303942521918160],"proof":[[13629403277568504067,9420611541728264857,9843807967246876397,16139795472054709723],[2214953628303413905,6370413994738228808,10949437711890373027,6418276322123903645],[3453297001610625350,13690177505764052908,5708479221710160103,11707588578490304836],[9643498920515929433,8801498454529856794,6001570996105672360,16868126348550422904],[3066830535889013640,18101453448064192752,13055412286608302311,581227636261108250],[4525268274661597619,10820713631377080813,3556857160732261312,11974052939950663411],[4905974615636285909,519730835359030211,12769442634018630209,2384680036266259944],[13047613753821162702,5276546102832317099,6426020725493177520,13720694903618763403],[14262410940175118575,2459216339695548199,850589658204409792,320263178985009048],[7388882453198577401,1326270329458715879,3869852824755267686,3163877200671221093],[10806619253293116302,13493847112885055813,15511987452743631874,4263860110137492143],[7296237506145134462,8701479948320702311,4544951175523408335,11534237744538341892]]},{"leaf_elements":[10812714551834224484,16670124736949108108,620659353691692320,8664491020860622092,5981429453245256659,17175488564285626784,15983234738399603569,5722198338988281157,5560680473343382488,6587670061663233440,3617723810851446552,17431599140465576188,14401906154644722154,6760240381427037246,13274084488647969833,1335437364860850425],"proof":[[16912006824213507734,693281425722478733,6647644982968505585,4702434485670151753],[4856467633584870317,699217466720494685,9945598782248888882,11112642260681622301],[9416140417075368309,4103426587257630055,5970607129826452667,5861649189426396589],[2981128037294585819,13233250615575769314,8900043217899291784,13290239650108876214],[14589946334518524425,14953393278382315692,11382417093397570410,7885161074238470794],[6973085939794073526,11692085563245935926,139708685448953493,2555323609793975193],[4416022267653299715,14835206986554017325,16995672501719159623,9430963325241555184],[11407113255097503436,5429013039852262707,3218467705278926294,3047994329080145438],[16257421673486828698,16484283103984009744,15836348559680538426,8566569692841037672]]},{"leaf_elements":[13466490137323408856,4317268988755412809,8556439885118690781,10025606051366772705,12959948189411251850,6293991410640080735,13695863564751682877,12345925405611943703,12521303233519884240,715806404503417200,12819045222209012198,15107978870934260814,10864868899548723066,7366481283364913444,6915505994724601499,10484544343370192098],"proof":[[16498391269115815553,3602275005256026959,14931071328659193612,17913755806205532009],[4026538430862016067,8539231635541840752,12625291025008604959,13883267992307829366],[15094535214405069286,13350382681684601930,15142546558489943413,964796960498835022],[5786627875144801427,10005548115374354550,6540672025996377804,11201830985939150420],[16170657962881741674,11160627547673133555,5874202989985510818,7708302584513613450],[14584044233910139747,18280063650689373002,17245810350330507444,5725994523160115742]]},{"leaf_elements":[11003189856471263297,5757197098384044186,6268298845938929044,5025629116129620821],"proof":[[11512493177117081208,14772783737051945053,15910435686680873891,12723856974712055962],[2608982139505623880,18398247298506884336,17574922522970818591,3426932777109838908],[18207861506331385930,6403559669784389310,14422890114624003427,14427551463285648649],[766629565387529983,18248180901886529055,17076533938478383959,3487557072612498505],[16225730070172836283,5723109316517074685,16600753429997216216,18030200166561212274]]}]},{"witness_query":{"leaf_elements":[8110481273300912237,5224018884839027388,11039917660030609282,10166868145492511619,2317161587468758699,14307783043889276284,16050679607931312365,15838590729026740146,3236942189516773959,6350386018979806693,16195643665284481705,15428634698174057995,961125045493141566,1004448871379625953,16536131675937470741,10231305841817814223,10351178351279270831,15004701067945923812,4270668752593115278,9363477947945812686,3025124601740958642,14330740490896727723,2976868844138446902,18045382320559221970,1262101204540456534,181345995560146674,16301804688503591850,17051449037141217857,17063358311564420205,11403200355969074721,8694279703385751923,16158100735916394118,13696519074325360069,1796345874014910816,3554456575952971478,8533145686222365225,5727526477521531442,8043359483639982901,9732815628784182341,6814197079550501779,123088354479219386,7354248749717392893,11286939125833643178,17559836555199191763,8946297784056286466,15670716081619293002,15814913386841315792,7544334671872150407,5730210802013919244,14428400939026710186,6215822509237825757,14459172043580537433,8126963839080246866,17838003988516705826,7029678406910636796,15906448138304843582,5854584270733473064,18061474262979065544,11281114134893397417,15032151278289458805,15237696023803812222,9244150101943008623,1513287282364771572,7720980428434658536,6283782548958193032,16713667849169818889,13816661486036265383,4024420188313675892,10601314945255471370,11860342429194695470,8650955296774080693,5271509211470007470,8283655071703012421,1875440248395154691,10823369437373447273,8647362500529167966,358506181398542063,2069943516670319702,16456594066918433988,1463584615061868881,5529445969129658263,12234875861858641139,4563994447332695033,4597302503244006595,8012770409263229709,11135939940796304655,11985776326539689864,8360788068376076210,17504767064164760463,9847148625499255844,11529900949504108996,8791239012924093051,3568128752700611849,7375258675194985439,13120109264414101903,10837942402805571510,8709846843495691525,16516598894067624114,11193335108615084398,3790628200174506371,12787163532043724924,5611425082142317936,5007373276918178896,9538979206845279982,707056554920151188,10434197799584319491,12015589943885405200,555763714082531738,4897364013459857918,8899192061093297522,4219053797999087130,5053869622007152757,16359194072285114598,9792200634213020576,2844632361224525027,11872262854045375944,12911424234845101862,11015197592171791332,1287139930423175694,1579275801761549252,7519864659419511946,10722297171506803415,18215034156119484219,14469467099507842560,9392512519369064660,13527871460692906944,4122870061182072398,15058688899083389875,15910672439015798842,5904610229077100471],"proof":[[14706767697287675337,10877286906369392530,4326834029292355752,17099180239476626042],[15176953862143144018,3320755545043898358,5590808165007927758,4818847163283040750],[3499233829967867625,4506583543417892918,7559534966865307442,17433493382700737169],[15012475365687550542,6761090751939021597,6315661834169746036,17483298622685949646],[4004426006445088822,9973029168980834419,8811337119793281489,1171467922146265431],[3695107768902313329,13674233516529465468,9860254563222240005,11641989533504056401],[8111211216513159378,2793027867142978410,1360889524593149171,16766172219535793766],[15847714978379775763,16538435314682336659,2903463440681042221,5784771936471537452],[870139507543638072,5626999656923411079,1621375453072016118,15176987936243449640],[15293397237827230434,12105807842515777845,8457396847677277633,13966546274400004413],[9382536428724068578,6724895480805058890,16883928022405784298,11345613771657769301],[11958488418500337128,198882017783411904,10655682923130011830,5638844152245093918],[17088176602014420593,7972098902490796468,15017331731246503345,13352618900330258032],[14619107995074607556,3854136027154000145,17115657654721593147,1473747650677451830],[8632102841038899385,15247977915398909445,4365187920210233344,10346940781884556052],[5576407094189439012,8204560050192287825,10888087733940057966,309312368663457418],[16740305887439843122,13265977755236700319,11109568187143504780,18433550665827047161],[8784762519931215302,18233999836680074686,2041846333654033434,16354164961400374147]]},"stage_2_query":{"leaf_elements":[13522177238465198622,2517733998670781781,17714548672415908893,1797280001115312687,2735232415329631675,15135123671993976260,588861534022635425,5324033018190579174,13281712126846347734,4528640083230863616,13355603528064035263,5457838365944986235,5582836454977859827,16175289056486929376],"proof":[[16589812444265042884,2081038066638943021,8617085888186397954,7550413574899388004],[10818035164666010462,14905911536684970056,2303867450724156161,6164526870111025892],[7425724871570617807,13437511985049238651,7305774502434399147,5548959687121109509],[9092727388237284833,18328676980293148730,18078101776197105148,4484392336205805946],[3011024447269075414,10464521266824503587,335623243224706984,675577186600096995],[6124043363097967918,271690459011299902,4636597124466936557,15340566642997345854],[9395536509386104208,11458192127171384354,7558948720085058247,3401904034460517960],[2599527819565346015,6181321128120434802,17268921706355988301,12378406594048263968],[8491989071852400378,1881353327632721645,7808333456803765506,2714807615914470611],[14692348942545013323,8911145785405044043,12105929791292918188,16884197921453555812],[6327927896317662814,5839633805799925822,14084025705032169778,5396113627447757208],[13089398210751566891,10131654928703496875,13691995308575137776,12857139294456967418],[5800284859334664348,9851283457627628620,2702403356251090415,10518846518306377405],[12890277943477543674,16667149668247591226,12134433571736703150,8670271969503820726],[9190397214345508420,16637697978256159092,9360480902062362529,14057503061089734448],[10992753290417773404,451952828266695799,17549664810727603410,17912166634290792394],[10840542863736845851,375737064401670662,16575509997654568081,9696481087660932450],[15113536297744850672,16608702742885920303,7103599089017710311,7581445386622075820]]},"quotient_query":{"leaf_elements":[13135214691801069779,10750375069607175975,6519334063632350869,16616392701271319902,1269499335986553013,15905153981840835974,10750600314899803429,6895662214725567528,557696784578213316,13416016424368249870,11645042506847673420,4579414666589363141,398011002906088939,18349066482375452541,8400736549255975697,5678256680127677208],"proof":[[16785365227718509023,17506513263087095503,2626109268167910169,234705353526529015],[4033133144179368483,5163328436634631317,16062131034011279218,12071628815008394442],[15442591699080572667,8955211449918941224,17317295472165332829,18197970975241181821],[7430655148188591438,13012095381787565033,4569441382586726528,12693425718984604293],[10257234461932585162,10909907177908930189,16841566588088659337,8107269781482435739],[18135893483628757610,16414326462653666901,16564774011234078471,10797350069472583797],[18172740374660694739,3073503847722840461,16456376222634953293,16575842147842545946],[11742342168199787586,16234496150993081236,1889354774597570704,17640074138575931151],[1703035373977328464,9597047937120531210,11926216554873020654,9955073075138866621],[10438864098605158994,3318380847578433746,15909694951694729580,560230625529100652],[979654658182601568,13008550399076956553,5102327547424435086,12923619650013989052],[9900420690254819760,15319007252611526219,10048442056754170321,5699867913972528591],[11986289005450541122,4266289508713663881,13566356699923187752,15105141414317591847],[11580029201188746865,6035568623773395355,17146349268893225566,11578270465648985250],[5561555643554952246,2090194190043948914,1581799985700937399,5778471835478866799],[17473107658566218753,13178466050404083176,11750553236452836116,3958057964571838396],[998193579161938501,16335014590443429457,6346439938520927683,15288563828177720062],[6820728431639780018,2074044014348586926,2515720846208058916,5772129624804234629]]},"setup_query":{"leaf_elements":[1956624092912918062,15026586575369013310,14872950934216165158,8998414705060603578,18141860569463598526,8690239946916241519,13838810280607370577,8367638582534315964,13949453238171950686,5329446119293771726,12646505448357931076,921029676262117842,4653145221133751963,14535023744643674136,1053596644532137430,13568613222321864581,2804435722284421390,17339328139098793340,1165511994041655424,1119052642092661331,8333407651243408766,3165679339902859288,13418127721568659915,16348992693539997511,1189323862140176841,5488481553918436653,18385946364029187864,6960085254645889295,18034866312294942843,12230670295609195959,1541883642993219474,13116871538737042650,4737639725144321550,3483047876642068272,5953018547439777764,18011565933445275432,3633581431516086559,3303710439261840587,13566307651134321666,6953048842462824992,8597079557523684469,5574773955540984978,1390995108916471762,10160046255627760913,1759517035268595209,14279973685495882579,5777169788952244743,1326001353732181624,16862222181958752915,806306744490552179,3741773757130665688,10014453816688558308,15974244968622910835,8379778436346189411,1294403018502691826,16867759450590704350,11387178392483836151,9847262804228852991,17414887092539803089,16422046232777019160,3164827270190948644,4380049103440404865,11966478694326743475,3665990875329344774],"proof":[[2523066501702363289,17026055939740818767,6704188064669145190,4506686954242043076],[8025595349943279730,8689503976773686798,233182534539422156,15174299104035530775],[4976957567974398288,3172744768197864219,777168654782993196,14718770142704197901],[18280527119999613174,10369353217392410622,15360958912657415857,7708924392650371713],[3928216726047986546,6683113898313699978,8631580401895184128,14855510410872405140],[5059658825694874476,17304346558412425031,3290867584368539112,4149992932191394949],[3559444738442102386,1785039968795637361,351716863241110366,16101810659373860151],[4931197932135850568,15366974125487642370,14642414099654717157,592161387126130205],[11446450425403795284,919050974803805322,5976169447152784726,18087215417805383271],[11779508287572116147,7111020881673076554,18228217047731083708,8544755209993780989],[15394974173918977647,11869596992916861432,11582562367514569468,2506655276635187749],[18264337122439337759,11981723703975640861,10621798210084242290,14769855925478795799],[13986804054486946344,5284005187109673995,2130344345114008673,15848076299561700798],[12932234539762401902,18361877099413026239,11674659770469601068,2343742718028463766],[1458223372158638472,9107691769015133830,13085351839469757779,13172811764693715616],[12178514813625035175,9635238187758599259,14110368411182283887,6499310634839283652],[12180952862142560143,5282037893822842464,10507208815138226776,17108467059249648245],[4145914382796653192,12014587028456366923,6540199116704152406,1274764619439205933]]},"fri_queries":[{"leaf_elements":[1953230078289372331,5171792634942270676,11109028901307082227,17556865274834619242,7902159424196863883,2822556884313296606,1207557801733859524,4314349668642541290,9155507958386561383,11958207658934293924,15392212312489881964,16652550262637740745,10609239737999158308,535521226740754545,3476813416310238618,17668801612773706788],"proof":[[14414675168843234943,11888706097661435858,13127813764575862078,15918375517013501797],[17706557993035943873,554389467073437122,8338842304552844055,7532424182043590996],[17789670873557637263,11755210733179121031,17671990380577341011,3695490961383553699],[8163156903100416142,12343330834999892082,15498110408014227095,13893283518563778632],[17001255446109436256,16788643307157092204,5086071336639110641,17344134846294363457],[1202864203118832855,12235324531172597851,9596247218313419382,16184208446489234290],[7849192807169243395,2564449682649662240,1525510724604503811,13365892469506567388],[10861575142685329316,8040440240758969009,8033609061043692110,8951620632850910383],[13395200456635447278,5639593419705253708,15657293143555771507,6045742662952840502],[7586570583767629706,14629523793492154375,6582496017776864739,384094198223808457],[512238199720117394,4481418713816060644,5937248917018873144,7657418841493756849],[13357571921471594957,7642612722849893725,14988160267058987879,17431203880502347235],[6632930774759415811,5621757386319481299,6775266539188729752,12400548365750910030],[12430058658243936768,16966241782890877666,15478727135934843962,14776728745597830121],[6884011987551252956,18233674825997198359,2070513317287236832,8697155528178237627]]},{"leaf_elements":[17561653959676637001,18151083940396774883,8681710227482167230,5434232983440852319,10760282217427521935,16985266807680469998,8446245402338514528,13835191210285385561,18101782387004842992,16155487538643942961,11517212873236000352,7419643867239972321,11741311477563417372,14273048883626562667,17484622400147478916,724960302182321076],"proof":[[871017008324788189,11326626266047864719,10117262199863657898,13764985697352214518],[13689324720309205776,8074730120934156050,5417312361446281321,17292147945572730141],[17087104365313111694,8927491916862515635,2657196485946189579,14770792732823363881],[531352305454150426,9374368663329582760,7634810654594031274,17235604723966881737],[2460605521396182240,3900120226651575504,458709619945196890,175827304720556464],[6845734549054222283,15643944417819119222,8016549100466845881,2856839849269857952],[1250002013138528168,7667989046249362925,15996271127672285576,16354697503696248148],[7732408756464466937,2540836766351654468,16019738119308819737,5601640060443471259],[13349429578699769387,4782089833635126376,3706330864605313081,3057002270925038947],[16767561117756565522,6282471361420619105,6592089668398540830,6685980485573422183],[8136290935252006486,5437147918258946211,4304916234099539707,12680983015199436356],[12934553554404635553,1694727996262456099,6132698027291951984,14034620547620124357]]},{"leaf_elements":[4328289647597711704,5894445027341901096,7284300727267118018,5279458703513809597,5424283298008509963,3655767431790055260,16114147767975503455,4518776597237868496,14067476070442391821,12204051996765079661,16338803668300640008,16941536622692331268,10440047186165936343,11300734756020148464,17540716333603830949,14866404242961336218],"proof":[[10882978454027919993,1379456198474137328,11461644391108896434,12188626527790864747],[8436599896452428011,7812523825395014371,16772118161435696121,4847039960441377830],[11072483698973901825,301403874146388900,15404722235267545378,17310629087498160386],[4892507505219207186,16170414274497224089,4596495623567387500,8060010127393158455],[3353318766790973213,2700301872926772593,15385057888271019038,8105045208488432705],[4209036415194123886,13076110428010827747,1637826279574249810,15564706452356459891],[9510392189320256289,16277537528940234367,10605580679299293443,800602390706220665],[7429277007009652632,16650819679119369993,13192083409875660653,4237220161484120318],[12536720764333123526,4157391328647313449,13509861644930327639,14906795197868486607]]},{"leaf_elements":[3140325238246511928,16530688064694983662,2192174312710126446,8644821146199565815,16292679955766655335,3848622522637909283,9797073387249056993,17335873215386664253,3649600115671419599,790587465637884663,14217585255919248529,1950349306819955565,6629379939658897903,1886365137335845228,17733341997340447786,6398652067676866124],"proof":[[6189569060709046032,18415781057781996541,817641326704960519,4724812748101586256],[5195958049230578006,3897284912984026718,15291847105113559855,14251509782630425498],[10033906517588844955,16689023968686136789,11311124323658573834,5072190535539331335],[17203256074041102401,17762925567495678888,14731378491200707408,8411397959030162602],[8843034718604560541,15889675017663928065,12580059191995085045,15945664994133347333],[12572623962063413046,15845580721608737896,16343501089308957965,1753499524481277909]]},{"leaf_elements":[11092290000861769423,5668096953993538060,708386446642749646,10585541515425800219],"proof":[[380033579960147703,4726588164961969487,15116596828786891031,4860541666748474870],[17852289623986738594,7577553406576736177,1749332274415078419,15156249563231032155],[12075665233615945453,7124360507996357680,4989955274449417154,687261261336728774],[4501218828545981059,11644435393831505739,749119719904835179,14188287748449821531],[5705572951660019142,12219633875643945360,10025377711570361705,11812670574449984272]]}]},{"witness_query":{"leaf_elements":[12182885896321909818,3507208940704516763,10235434282636381072,11177349261286380730,12394575514808404238,15080364797005662382,14238234534145790366,3164282950954609754,13837192374953040687,507325690626967594,6994386106856949565,10123892145129449935,685615624408578626,3363590853818434135,15529270929856528136,11072749411508250819,17989496957569369783,12399002522617980489,6151567050194925850,3577201430869365003,11634081622063003035,9725634276979283792,5575085477807999056,16197647308047911654,5169811295246218061,2307835814532359605,16735786579552102024,12744344127195499917,4886268261796495964,11886620841436731642,17326045359273410375,17710256352764850882,14835197142863936030,12606163719767429854,17412090514208388865,15548839962057314103,12538872639639257538,2217661867830284540,14947048393752666820,3684789510199525313,4187913114158299217,6441911006304457383,10391820934432504063,18015047923405558072,2680310898492202412,587655996413257291,7523633163279254174,16241236671263758697,12543078838330655819,3672801330138007893,2510086797376254101,8852394314739123664,3994496622538121120,3660801508925236180,13733311091067699328,16476870162609619252,8796240135102828152,8957593523580896025,11956287562961676487,5890396763078767345,1279601838774468813,17618629472666247027,14893670845276707794,653171729179572823,3705603243313048820,6825463587292235077,16275986249608346630,3997926412126344981,6775759107097997637,7127156917655662382,7552412035335780847,18339867781563983640,16023697038288409739,3119005701310172006,3779943865275867184,6461268287665721398,10200593205925712252,10805146314019948772,9213981187425472712,6738448122305278635,39808373865368962,13316294601857044341,13802356212066363706,3976553098863703940,13881494729688588805,2566970306241472773,14266842966338267020,5323578741603550170,6855566741748691027,5509119126870673447,7726219673068092693,16584830643144403780,1431797587088989443,4374180199016407458,1603477494837268738,501096445799392175,17537348943629421312,8296378131497983074,12604003809782256201,11162132343960892947,10647275147094773575,16625387993539383098,14501800477382719013,6032226181012511051,11054765776821357877,9473069600647995686,16094640123063437020,1271105200471015332,13128614037892922578,12316880947088039125,2117517120983922499,6910747806513324812,8295742185336542589,17395407499482511598,4863544661221493217,11941367048652752599,1902379215718336363,1678721744256026414,3686099521702336886,3739848634448101187,12903332178796284005,11429233625290617711,15690621845172781470,6789799445015717595,10425510227076388708,17746534264584533713,14088877264269572821,12140165142999042189,13259238635024888489,15279056441941487879],"proof":[[1850879548770952168,12388173732070123194,14967790354538925125,8276611214965883194],[1769467576904136655,17387804854368370131,15013863647034209286,5680807334219034187],[7759020566428049782,17488992694863611393,10681049745777425352,17024615636238487993],[3443256702426214909,4274787496924201365,3321050785829418296,11290666887558500147],[3518261127387154086,5888956529133035576,12784894474920238413,3998726791108100686],[16988955399323368704,15094421441155819017,1262710133320945353,16365207846278803037],[2363405309228441332,2468143323770527312,17825479231929219435,1221089992830457526],[2516315894740015524,523776774340377703,4300471098471446502,5262874956223961728],[38600089324838281,9361559007833680007,13462901458971781064,18263598021262352478],[14847505326011512818,14319663394502639605,9458061589122202596,6757419998424870680],[8972892388028122700,9266430895362291068,6289387892805692234,4813434528426449678],[5283221445605572292,17384645432533736012,16581063669649479121,2499505292625024474],[17863584477338047697,9272880857024134708,3540483565117287752,9248278537444757444],[7301726628118514305,4991687092348274746,8809374789628697967,14994387186162004945],[16958194320707068617,12295333910822859469,9438434485533864677,9995203497511211533],[12533842072541078817,14149989489615155311,4524151888154020264,2908476788955008333],[11433670679255533720,7963357677951539773,1944119200614818607,13942020613158351370],[18148579322751285942,2760971705168147210,13294291097572878670,9879705615898637752]]},"stage_2_query":{"leaf_elements":[3433225445564622241,11034662856634832261,17920989950275485461,8249655825398795218,561087738127927215,2560623308034380095,9441094039022245518,12990931651901947120,10863856926531082767,7370600924371691720,18170512120543718829,16397481910290838324,453497805216548176,2246798133851087803],"proof":[[1143395376695717027,11382172841124689089,6283417340214777611,333258513451472276],[11354978833507877644,13960218618193344219,12734412656185690603,6421130942227592802],[11064445252135107622,9586668187125906429,468049679399296322,11683854830347315840],[15685572814396486002,8769891177939186622,6521606009880458982,17935332165498803309],[13987511762199573825,17540855478435356512,9892914802070880519,3149551199861391238],[4504210948350160350,12221431521442395077,16040738837400644883,1139335456425933964],[4134490024006498934,13208153111557135523,16375124873212032886,2518412846768044636],[5939475377436521448,10362804054685292438,41977783731708123,3353325941438577454],[11713843392926432275,13615411421338455951,13884783741632097967,742993280240230437],[2331486370144671601,4849910616518928707,2732204541625737701,816470918535774284],[8017672213049894202,14504949295056720041,12040661311210361627,9116066812294720978],[990303663806955390,3839314100761705226,5681979746554608937,643863227054590400],[16613941848239840791,17312465084371520445,3486121053927684613,2324040969636097353],[12321263975751841768,7431492435711546025,10050972333873400442,12779435451485801047],[7639790845603715843,15522164951928729299,18408756475369833392,16127720018696857171],[14260869251714884210,9752361344019189438,18305024942933068415,10526484220545019826],[15146805793772089880,16322925665677924406,16953902491014636913,9404079293725288108],[2094594733942671059,2971060272499666145,14155513582135381643,17304967974205278701]]},"quotient_query":{"leaf_elements":[14340201904936777188,2957525622332011381,9341772456488174294,7959620322130667901,1626030165465266000,7560891000698594239,17235087618904337831,12415091141669057101,14192111790606309687,12282747047440919634,990182399948196131,8156392595035326157,194859989931654011,16899592472646753175,7022387069334861083,1136104270147301146],"proof":[[11469202841498010682,2104132406441321785,11986699843435390821,11611749950535791506],[4064800092398657919,3333086917664132246,9564758332552939501,7346474575013839572],[11469085378862906968,7445966204131684370,13651282579399122086,4288090701943769372],[1499092912934206043,10344742024613222041,4544885282235041010,3827835617444984317],[18127434714035507237,15456792007160817934,1846721123743546494,16288851285357736837],[665706532572863907,16202263015062587174,17260543502172345706,15112054614121552084],[8332850585825551275,4569861366214712719,2312119326380860969,13795734144704567494],[14190527003453376189,17110592817762589164,11339113845998177262,8853372592546185323],[3456663650617909308,8943492096884099960,3630455834782710841,2665468813279237933],[16660757428627477558,8999955960543040164,2852399797325031625,1612353780260994754],[8240890491753610985,2201556096984419101,5206623421879709072,6660789640000184789],[14081553251271268726,16650376787017722060,12494527125221951694,5399916485534104077],[8399535866916712325,1543303580633389103,4107293064102370062,5945580929431183701],[1579064656742956953,13109354943222838900,2079189472584356620,3762926147064456903],[6926486400652347257,8095496385811043694,762473537252053014,1988375982655573580],[15469209153137790193,2855479624068830231,4432913839951458332,16786706000571028383],[11511164569288634801,16546327632164680715,3202960371414180831,14531077463378965825],[14029862780072879746,3967743542796005858,10810878151428366301,10474236622789535871]]},"setup_query":{"leaf_elements":[15698575344836806342,11531124607447831249,12948527188035363467,7740776351469743695,4227649498893881921,4553030277144340596,17185424838877937425,6171666039021474170,12973856809882724184,10150274772889752106,16394596339016263127,4153770846043752057,14715241111739701869,15934299295802330857,3145710592965832125,17122354052051246064,4791164252236135783,10250245416454579573,7921275245872093216,1550596663403045744,5117024800223481605,9726447525120639471,9014270967418227604,14146936855504123361,385302905785884878,15407079836827035451,7301456070897840046,15536761701211430274,17235805009303682944,2377347425301684907,3640684785834356297,5134551738241735608,3954789047365866084,9964610050610529530,11446747429306299310,18352021349044196309,14107778562816663438,14554412844091675848,15787786336527450484,7328628860162030553,6984983402840682665,15613253239767753138,3754160995964050566,3125833404757365444,9890327493403398241,4843173860389359077,14820946860158204144,16461739584352094638,13456685047793706951,2653416450811712762,9671547953051125219,8585643841575331230,13705001150037110815,2533408583731810963,10883079186593350867,17558509416882620008,14914502408723912627,15380209489689150510,9806444599375859598,4867818627827682167,9223896810112255902,1544175467275967145,9391650942737344503,14397558081765831750],"proof":[[5048185551604972470,7916058617989859047,8160683894382467689,5551274320667758927],[3533697769947108582,8061107087598653562,17082903180441736012,12727617709814714903],[17821462338549229911,2403658449058147589,2978051589414591300,14127826004209461917],[16145310649108161207,8804919785246011295,15168517306279085424,2712637781840157385],[17873430265431490875,10902510940390946208,691130990267480809,7299887453500374959],[4953985724109503825,15744742531114119696,15198885688575184181,8980795370046373766],[12320336802323667211,12964803574029502808,3872209250094103206,14344860671164115400],[11247660391081634414,8935245742755173070,6137656315528103439,18125416628475080918],[5908204354919946996,17123442255552932508,4188403582086613533,3046548886200582497],[17980899748080916640,14046185796535228473,13665933452956135602,8441123640994408668],[15117315069885879661,11788225944529966687,9316625958326379123,16398338708857120425],[13610434483216135226,18231286351641145045,9214330743191004407,12818092364945006601],[16542447701426378542,3552094859122915228,2309406918111589629,10062973779737635377],[8978363452212273310,10916526267898890939,7180935532554447468,13718744908970663902],[2545906024769486673,3160068412260218204,13424487328114446845,8755084768535746511],[16616664914539959077,11701845906332679798,18075662059221735200,5976961494570672384],[303151734142868783,17443555257742714016,4941929058541131605,6568509831070840770],[8146166445247676947,5003742890534910868,10880065721913004527,12272502221928496556]]},"fri_queries":[{"leaf_elements":[13669850670960116400,15764930136093714509,1936918415177234302,195440442412355631,12586879791170915316,7630053224979953401,6569048503993527521,17295359371642858946,10718346175723209385,9732349900944010459,6742765089150371287,6553334257205271816,3720182751879935074,9675817098776665650,13862678857429549645,15097415635755990092],"proof":[[12272807890373403589,18274299214145788287,8633693748390170265,14207632843017824027],[14113727278076503696,1407647906972616058,5318766120816830284,14333391014615222594],[15469893663933021824,1996413980073380879,15895397774292547545,4436799542122178965],[8678674147375783756,10471304899095385694,10944251062211507414,12798549149157510640],[9211743100025255078,14653426219313885802,9903760752040268221,18123856868038967951],[14358377061937713350,14068441441548365862,724409018344527327,11230312490990507800],[2282596498301285389,12912871286075502340,5799510403733429075,800226977346580544],[1065238409913059598,11986907867233770598,12268198775153490505,12788195713452941962],[628718851762339457,2110524661240791700,11652738747024200811,1034720070471309286],[1473470337254688922,10633392688827611779,1978000310748250937,7469996971214090183],[6929271703412262478,17083981008849244225,11552292702763319696,8008022347870799135],[12474952588321809401,15277434161960022884,2961270221701789775,5396366762490419334],[1712338767318921025,11973068346225177597,7238299471459099580,7411857482589404708],[7975111456203553570,14691284198472368066,3175257879397026895,12386005674013307715],[7851127219568855673,4897799264749986595,4161035734706600389,15163469338156203768]]},{"leaf_elements":[2769253276443694239,13636219032168309561,12847524555670900365,679705282294151933,17153573818604376396,6248890044465291968,5696201047957174302,401423443565277275,9853227409757117351,13071294199325301453,12968879642904569737,12609200414528801318,10402447055908571393,3290661508846701728,6210678608984778053,3015235819792506179],"proof":[[11152566025252152735,5584167524558468243,6500307741357672654,5267097230693686469],[9426791092629376746,15333423166628586349,14388716028166450736,14005852374960727058],[14685279510194258909,2427002146507603599,1659383531328616474,11352922430539638395],[17449310646272591985,10037996714759027361,11491115313726850783,5601944729995190544],[9558387466726252538,2142686268024471335,1087932800463348915,4974563013170926344],[392830568384875225,8162957298162478126,11049906494520053901,12961874386250454789],[10341777028335315098,15655281094571283073,17231771623526441118,18108882828743412975],[5071704714811796889,14357615625507800407,11660585463958144095,15172148347380976153],[4416966920444401107,7744568358701316232,12096222691637512052,14277781247458994586],[6396327982279356799,2891423833056824657,5111709699419151787,10102522779573210095],[8143262444532230895,7495306247748602158,669100069922290866,17673855300873396875],[9676679518670558510,14149200179561189291,15359256914066339331,1823793103247548063]]},{"leaf_elements":[11918079783579457207,9570477887425668914,3981398914501566877,4469191879349088437,2940845652474815301,16417605926249164235,14464153190826660728,5914877409965142823,14004365948436919448,8715045387622724910,4646600589452168590,10020465152599097303,11908276304136257951,11553146075237367871,959148501085191259,1019199665968180411],"proof":[[2386091658903270195,17656932258626253666,1969717439983002493,5317984926112459892],[3448944943832079867,233389780261258669,4133362634484878518,2580492148100832651],[11231328088781291145,9205443867812276699,10011696327548557743,16531924316168750458],[5580644911000263668,10954608610816388314,1523324641920743651,14094884273147443839],[15987743935746261829,9315088225840431014,3344604947414942785,17912038951450396925],[4206741134038211648,336680832161227390,6659200807932635187,8574598193373643963],[14035641328258667036,2024729299095661402,977836086617373348,7773967668765456221],[14773857388732030853,4668920016152239622,1756976963577847511,3321514926730343664],[5859496306036824315,14053766140669507549,2639673853492966030,458232257419117440]]},{"leaf_elements":[13973663324515295328,1441763505550663602,2303147821569620529,6784906534215137305,11780259948651209277,18148983468175961220,3796696323727581649,11621787699561111024,10611297926695758455,8937507086836779875,15118442246763876908,17320615996862319876,13889600026459781433,3210987256948712723,12679047854489362781,7558171757349715775],"proof":[[13706938831439252538,15231196582123521439,3431327482962223344,14082690493687669528],[4596006809025447806,2965823247809113315,16840869720612340552,10501704867651420507],[7034775186851864744,1746953294687494425,16424953666425174056,1349554758977654536],[4570164754581486217,9525700260667234458,15711144398460964924,12339026212729837434],[8895483901048535549,8028717381344342165,5666609367441934287,7481418581941481162],[12953891626000419152,14579679374984057076,13507784827263271763,151774044829430123]]},{"leaf_elements":[5364145791890090046,11396241162965217437,10476540682398060519,817387279670489346],"proof":[[10133176421825556150,18007918706240405420,16839265080474694577,11979852979286746984],[17177250062142895345,5867489652418039264,7676875661748302915,2819729357755850533],[5543531730665456065,8983340610692003231,3856752992759827750,188425101700388548],[4447063484444050969,11002729428572803879,13653974321451095178,10346918093187674371],[3778754788991250824,17763967478844533828,5824622786010168732,2760357468662770618]]}]},{"witness_query":{"leaf_elements":[12520111076296609495,9451898402101449050,17626854595712701258,6197659176718882968,14847369275753281614,3379617207573844344,11726541198896408343,11042965726270581133,5575129006173532705,10348728048842240155,7870325756556646214,16848948502376591536,10113840169934167542,6834078740359263478,2769348835309819176,6683241670953290214,6828187826381531322,5712148036674167255,15573188564721049028,6042886945500913395,6017226001333174827,2721111636929839581,4539313970479527996,519620797110423712,1358047343650955498,3066704065301485646,10604020302009201826,9807827323761901591,1591744976989103552,18430814949642214565,1936980158217980966,1557841592512123412,16677379619456868618,3138959661564370064,16700186996558250453,18341246535758431353,2917261866122045034,14923091922296848161,12804298335117711994,1546920923352031300,12882523712583481353,17670713869285820634,8840725103555626714,9399485644343608157,4784318732122945431,16998624362496682706,7386723254165791520,12385145164170772838,8889208673306114346,18248402126206402482,12209211972687505705,2394714655981526405,1017776136161792332,4916075232420367838,11855922506638163122,13787674314247233224,15941458034801085650,17971617592653358026,7058904764964001108,10101908458239015080,10005858614421634426,3063126973403935830,7150055465434552089,3879338337032936241,12052539890059120511,10790125422983043509,14391586733355445906,14313676279528146503,6946680678123802285,2247344633301804115,14924909108708691382,15627297330930197589,8177892258001837181,244087305825527474,10215594969251732427,2455726410445946305,8287582408348727253,18319071883415823243,12934782974662072664,3583496562137415031,12677277039243252299,17081956085742421859,12016151774708605103,7302027869395564323,5094437173896947109,11639110564652926536,3348423508296093296,689510524699150384,16921471114710722565,8152550134499951205,13107007632880717119,6443991765989285344,13894942312113057602,11935415609310738265,4403089682816065388,3639801992787679131,14912500437662452301,1097164348666754493,13788111455419024084,11940069291023093503,5882932679105251255,11361592474440517645,9651512064736417450,7707901456596714838,3253137873309778851,9381749601470100992,7531146981318136660,6067459490114227282,10032095008900395393,9604420726397731448,2809327097937672016,10586077105984644765,6741183327691160706,7857005962647152822,13318844150795317094,6175150459128276971,10883153516751532899,14208620172862037254,11642794176487798641,23275407791280990,17288673888040296214,17547591393453550919,12375031058688294896,14002079535598264319,10726596007814059639,1036569887691685552,218213997268788227,500926365056770826,537329779354825413,6301065515972051521],"proof":[[8654358984122878223,9364265837178003303,18277001853345039631,16027500384760766184],[11632802200727453129,3816402674236213718,7938388145836668772,6433423310577848432],[12181681730186365820,10587860112270426747,5906578680752364180,2626339373518052366],[9386912510106473537,17296625327331236980,13055511358242526720,1451464536455545756],[870654410947466693,12152064826815891380,12502731331439378512,16664443892918009566],[10070576176065523766,6111164259953266291,9621829244617028830,10705769314706995476],[15855396009035765226,751145537186405066,14360164074162875962,6261433437190683189],[11842398376320833323,3898951606305367663,17801742729829193703,15327123060499890834],[1064613818980924079,10845544728007260659,18278385126562266366,1764310263395142187],[12120729619195353540,1364700119548734922,4428999562289859102,7822213313685520703],[15791831736776183331,4208143942442677389,13360374549076344679,3858230976300793255],[7075204460980271566,15082930813484268741,3022578159025724635,11823539420727212534],[13137557467532270746,11103376363018724495,6851209939010215593,9662102881595862280],[14511383408751896573,14354903187691760455,1314367314794894971,17766699547582566592],[16411660436445011508,14131920107516422330,12986911466165706619,12255109997130336013],[4009209267425344380,13401724588566118842,1665462238786822081,3226671904676026651],[17033145164065543785,16985524166061847210,14264170221022251987,3677754271835177104],[4321157937452814567,7731506513669465267,3663256000856470146,10541675974451685032]]},"stage_2_query":{"leaf_elements":[6880877856631344537,7927453361005701095,216684095318290149,56758699695717827,16637422518666925366,13611526027338164611,15456184982735128092,6296708199064435666,17879906549355918457,11222076758012238127,17277102235695947721,4164015067869876337,939857057306126109,17736079995767602578],"proof":[[15594381194378289137,18186762243173667870,17099414284672956807,3228597338678338268],[2600451726412472248,1422655478334051565,16719288923625916917,15814254088597702572],[17489609036647966514,10462257974449172286,2045657414418868626,16227793495432115942],[13423530449110912462,12686661293166685294,4698678320310262831,2124259516314091395],[16150106444140843938,12776696459237307715,14459829067587848171,5796766363216047651],[16645312732445959925,17281096165705972291,11657992736949785718,15712053355959083565],[17991578340975775439,6228939830880403355,8996372274144535600,12395762788622222697],[5168624108719803786,18285901437143328297,5725520932214905081,10091179536710616606],[15671049451070138874,1284783326164037381,4459324054461882803,11769751367814726855],[16435636505007117403,2312381635135788424,12968920238385759986,4778452719999840829],[2064701509076346841,5947427953162209326,5315834432780424714,8949573108476972303],[2350986960701728353,16332690677537258823,2639901820081444250,8698603788891424003],[10784680439110773465,12179497424311613248,4351443472709869608,16738707194077794475],[12461756292411976475,4923019727117125835,17806871992935789025,9114022642266114223],[793199994230877210,14769660399263657366,5465429689286388209,16949787759717526423],[13957769767427980198,15573022948248891376,9779853925836275222,5821857486510841917],[10849337697945872177,16612195616424072351,370516194166239354,7786330597640370373],[7539505677637449719,6025541960785004510,9195215168130357252,11338226592154399597]]},"quotient_query":{"leaf_elements":[10883881496376763788,14069613114360776087,10729337888607419112,14909322329127214133,13154790157442297773,16032727024109424286,13419451339703991182,4829330310528805576,15435212877052344060,13979852272056760274,9934902482602571616,4745831572367832412,1287807616320224420,4563787112048456703,10961778173536788792,4285455835756544232],"proof":[[13452284987133563049,14522452918049983291,7772032620980195432,6397155379078986899],[13090803058150586781,13165515745567265355,14794851126436833066,13141052289704674061],[7585288339849949902,10083200352878869101,18095755902030799644,10121855937253144075],[13994763253540845496,2712817708890190241,12794338095634648697,2410588684566493567],[8396691552680407106,8015849278344870865,8339321057916516064,5038937975018401208],[6564453137838874333,3777635460530878194,13035144744699553091,3052334596925665143],[12683564868591940385,61818901388166826,9187850363782400605,14753046402658063235],[7839714304568457635,7001521690693934955,1757113725431960068,1621471955205034701],[1380776124218378430,10871038038569013995,13299573925639678142,2688999345692354531],[12209375111486059342,9721592832585527067,4219921083853162239,15783541329176915492],[7771465185064080221,1636064257387946826,3149726736306332863,15011674929428971486],[10402682206757726109,12857932644537465676,9763852294716717837,4314079741032886043],[18409842720793056946,12973480436096615709,17897240382023623713,14027096374043189448],[12602329583222543119,816989419126569730,7819438403328256392,2912865045109004145],[10747001704439455694,1227270164812384040,15870738276589118821,9567130894328232742],[4718970257806206599,16722247253301647348,1670029797676309561,9407268535420985892],[18405849297692561034,17958012992901766217,14772706814862661765,11259820943491985096],[9079718446025061513,1292368641255159576,7250326286537613076,9645619482992454196]]},"setup_query":{"leaf_elements":[13093973093280034988,15637454203245530644,16976746394907713838,7562784194236828816,469427035263889091,1580795222373861101,1242391924111450599,9124121171320165507,952523827200179174,10534792721149580236,3476463021138861316,196394097721238019,4938988560588488564,11629858008534798785,15392465615606774595,15957521686289454903,16035707017436392869,5654379929353271458,8844342160866037616,12240603124275647964,6573763398067100578,12587269214665947800,14404182613135119197,15883160745461484081,14234378407730918394,15012426902572610245,17483761200401178573,1431460591037879984,7791550624798452623,12961015508415866206,8412974923767923547,2136209052269940031,5818636549121655088,789747310375398666,12956374052735842536,14387953664761852648,10184336900631705177,10260207154442963048,4748981551915623792,5259437337623399840,1182157325918604919,3479217509385488460,1612480303929595155,863762135256328530,448602695555246799,1795646165073292283,9728275096631535401,17328346073052930563,2633067867452704812,6441738718862524161,3429294130411719523,10064345763096881682,10991936641276197678,2920112795890524439,15242248762081437301,14501127832556758192,17930256218725685155,5672125881617959350,11547945468658934248,3684174312827665181,10202177437469709866,8246390982556325358,7426490755484291678,1482307229102687161],"proof":[[6747050077718434696,16606253581003802347,10076104981921907498,9301167011809520236],[2608914242312787575,4850595667625844402,18078788033200688559,4098705983836738845],[1729614411652571559,13173205965155649171,10191490637942363723,13596853210879219326],[7936951560457815548,11213172650436034921,17082631297025821438,7469124336839702764],[17260815234379218066,7936947687660251466,8482792056221774842,13613723613667147369],[12673220567869521020,8398104133371005483,3851421027273503675,13969416001780471868],[12312400347421351619,803454312886568771,11526416693892364706,8813446745900210049],[12109051276826891357,15440989642135796189,415941916636253844,4839933819631529724],[3430896885160849506,14966710724898846845,5996178204001763874,8991294208352837347],[3596183838492060396,13718844963145187431,9155718891371855256,2639902943441156469],[15545179223695652466,2420650510787075701,8319066579734864517,7104153418603362355],[2249256821585476715,5488000419859416951,10710788061286454006,11978918148843671455],[203051532335863925,10416370390278561201,1313755030771824315,13245187111732183287],[15996566707136236285,18369427430016836721,14040470343180741087,15031297199896140120],[9279583332189253022,17283596015535563194,3823884466027972362,11080613768177372182],[16723217047692693580,16058831188216141488,3684022573474557444,12105493860548841828],[2379651368045778339,3153358118598965966,6892765585785902663,6294952143405254237],[14560993849689671787,16671308470200432460,8498636477232585927,5234538969987680415]]},"fri_queries":[{"leaf_elements":[13418967423105548002,17212095191472893196,5713526621762434480,3603342988786481073,16113583756391698988,17396599637007589902,5478918046595353501,6264110217789668315,7573426670181110821,17856239148404806196,8298936956149576705,16846823239164374976,1153638653388909856,17429394503520924280,2621987214202372787,16255049717831315519],"proof":[[17785152432440149690,16880956775624590994,14246645323702514488,7446091683115607853],[2187404795600730295,16301667361990360560,18134820676415128001,13014515103981382161],[11134696365005312201,357411661585812520,11352651111979587379,1964084695549309001],[8494413106358652032,3118838669831709025,12672915859843491950,3027745879024865420],[13686007718148169758,15293478035276835566,14803261296444797050,16701498615368630855],[5133263630326352815,5720027314436785725,14918569219836120642,6741639368623181223],[15613771044702174316,10741569544170367553,9691459606261459672,10655165874537174144],[851856666861121341,7926373084446027561,17224137819702936083,12573467885922248906],[17484097910639093035,4782994598218208660,3676196692146362352,7185229590708272197],[2532645331699760322,4850200452766845499,5410500926982266966,15231490412301207914],[7980688880355959991,17535235101780238541,5023005928545639077,1904685303067979153],[17884664744798632521,9252803860231316053,17249805077759677401,13394723891550008408],[14865407224511192008,4968976407299885114,13156330591105169068,16185918644041387234],[18270518138414302645,10352798127348583527,6790254438677473823,17991067837535095301],[9119482119369203881,875018305366015816,9152526766393477122,13342214401793080493]]},{"leaf_elements":[13848846449379770315,6305750301533022816,15307953979639087416,9850770747074835632,8565840076635260471,15722902922140786053,8345601775902435929,9218714338231865787,17420723587313657415,14443501508372001730,13158358228090785372,1441907445118219256,11741174176659170022,9054524637715353266,915673154862269327,18149534851927014421],"proof":[[15541230696200353631,9140261890061148809,6505445204144354114,8428243800692326159],[13018992025097463199,9719512938542420792,6931723299410521893,11099913170161038639],[3388599523728455877,8162721340807160028,13457963586108205675,1396670643790035699],[7502094724464808621,2358415820075149880,7768051664161259528,10324941368605455670],[5241343685789800079,591079212005718474,5448213958017108102,1047956531363861407],[11348145870129569336,10540067677760002313,162168604966452148,8713666141637192333],[15635659717346199395,9391015150581933240,17816770664921862591,2301317022275248565],[16755759268727380661,1166991847047217525,5171319255668687554,10372980662876722413],[3269274127923068950,5149526649118233271,7887135568034425234,11900800791872161166],[4687143599772625581,15526309536182046880,2763483208584892711,12534697390576748238],[12529376578927044297,8706939344463382602,8995959676003444553,16887045281749523631],[18299795209616354035,5785305265085024558,11941961956200844562,8540303024267733809]]},{"leaf_elements":[11369804735855419660,16618908497793120105,1988259313556500741,13328604136081673969,11944470831289235580,4316242484655472812,10741551539504159920,18157532449380249885,7297222426073909868,8882696139052136408,3470111525472466553,16365618850907414475,3892736479898749390,14892729640298091786,17129770066631289139,16295737374161198512],"proof":[[8408309618377102952,8422470507356105137,13350441544318564909,2878829373076097583],[12931807240343101991,14717609473004536622,16774567217018057960,8504337099393500259],[4342530316816596951,8202506814404720673,15337214138103868843,12489105017546238305],[16186601546779018150,11809691432925814647,5417761315531166389,4399361805068649627],[12279299390905824936,14605104901492217120,4640104220027961076,9010506255365221216],[2465887746252714575,3116346774064300081,7290636894028724890,9518628096404381114],[1848643335484374047,18240015267767952278,12083939257407609841,755381560981015469],[5213373745945178957,9943796192812173107,685893229113495337,10809034435891545869],[11286922043889471039,9238763553173827433,9660201833576050128,1119993761782987112]]},{"leaf_elements":[12607872654450671479,17424916658509127350,2495142723752146228,6305067598713318301,13715433063693487132,11312553245111182190,2157771575391403574,3203210954348345487,15445457646702913910,15327226215457524843,10797050061224945688,3974563464651671141,12579921653443025007,7298508939496860555,16792039193638045026,9229373473385204974],"proof":[[17109880080110296924,11285307829509178802,1767853841711488697,18059892887286323739],[115627071105314318,6587245990257968483,10817554418187887035,6086524250303973531],[2027535766456975611,2984665654829578470,15844007400502654608,15821204744363406046],[5751855308647890575,17927004986368460951,11428765766974989132,10596492315337975655],[1311096980168886658,15693917604309077783,3518152202410043889,8358643840616534692],[3116570042224531386,4776994613350753721,10281947676972560020,2367345947044145660]]},{"leaf_elements":[6255583391562642141,10504803563292665342,2813758026231765665,8480169935836784200],"proof":[[16025294759590140256,2099325213339797073,14034682248464321627,17853172558723754562],[10724872203897269643,7415310779276875730,17430273535994730070,7428252531780530470],[9891556985550198540,12812726469206689147,6883803578601372927,16417787537901956474],[11349921802473282482,16899149785402571716,12755714122743906663,17068548560611093382],[7694225130733373594,15908811539442583939,8409570603706991182,10106254446583243495]]}]},{"witness_query":{"leaf_elements":[5525340169520289802,13717944340543923248,12870349162075032146,5429719645595482880,9377056018167775539,12914085475584730052,3305725346824076349,2757978175922135366,3017059185756003070,14342368847241355267,6366383731353568945,499538949386428431,14361677678136389899,15543977654037241243,6346176194339348815,3009464644570767337,9236675812938364345,16660275150621177917,16987922095996659900,11879607092917450705,4735088119420846908,426876720757631276,5181882205010668104,1603984353505290070,12452398191727822026,2239415220884779273,1770861102746097153,7957450925881118605,5468799260746209322,11744506325737037688,7017763443551871646,13500251231542099478,482320279806214255,3439416813717051774,8118100368144648595,10572096212322270933,14134869322527942663,7074847474037125906,14765112472786637351,11337543777731467777,16636441025442267790,17603835262701947629,8216735690369871823,16783570365376236397,4210702652611829801,10275016232464211176,10036560604296015104,3229043709853473157,6400050534758231909,13815412879494584490,6642396331162625573,8767547151641194811,13307557282184115036,12244014663458004603,2377074469764451811,12097227679434657156,17467042634714811375,7172006940309217587,15751956657887949816,3700830720548258806,18038759193217982337,6676802449878764155,563467119153841892,4090873389078701924,2580671547901452690,2076871973663274170,11931472368368845750,10391872075286608560,1384014634142976346,10217303373538751555,10907535720655202618,11996050218764900777,16279531882846091133,6127350424606509085,8090129612575750242,10500571496019295987,9847040788825773860,11901791152210040393,9416453398520707244,4471779674880480092,17110577418585516715,6558588853571790726,16225493125390894728,10101794290278127447,4697416861912964767,17005843944062472611,7824971569900101510,12455732183375354008,15596327192337489045,10382935832647079270,17807919091036053731,3442527620630148473,2497340138805325062,4025568272533654069,12961997189994734687,2051203731486747071,4300886632287779769,15534271857363370620,11585954488414521328,11608989251735778820,7223309409653824827,18061510782215646029,12854367143717397694,2009361168892380832,8860151979120799121,17185555931430200287,10809640149390082586,5648372526247084032,5493714058878091964,6355944121094241839,9361427022132584151,5609863431789574034,7135641263648538927,16802398839079964279,9823267655005031544,13909179144768597347,17805618377676030320,9025577860232858483,8580073044778854800,15597822955405748324,8964847540955712328,13478049576056741470,884563727425524261,17228081891218573384,7503869694410875973,17698637305766536560,11287715173543378048,16610187466344714862,12985891145761121402,7683875357124898252],"proof":[[10304165600530527200,10572338688591745323,766878317188865039,13486937997093684922],[7606832821626084739,11646012653702083119,7526128090228697700,15112043286147021490],[8700635279718998856,13428346630412720958,5247353010299623483,10924450456974947125],[13644666052102230768,7829622604047758336,3567601124589041784,4104095485658455094],[7740659801671641955,2613964193441152648,8266226240286854433,16336856594606540244],[523271024516780611,17243710055981468831,9113134846121570132,15703311907197013238],[46052554515936412,16910341156164780463,9627674260869872137,12824531658981057883],[329236302411592453,11755445087912291370,8841154078996158320,17026820385973810921],[14878112546129989109,1354725948939492301,1370767188071918302,5550123441539277435],[18231593830652979938,6468053014191679519,8704269923248659363,1634536524770902604],[7081651528024771402,9133457948546931146,17543797278192746283,6575994486797729425],[17986210519033172683,10083070753845791314,4426391906244806705,10300223500327486821],[15239619985107223215,13517193998026966610,2557857955387745560,17262244072840237990],[12150663143170549972,9864607509488913235,2406510949557007250,18079959223259238077],[2442119260735479993,707631471450350500,3951216910662791725,10534461440555733952],[7346957277391146149,866048574419150765,17410796138976206386,9386921468638350277],[15838467848908824410,14875238523086735926,3257297323333584755,18095943985312906126],[6572491212768576938,137897960636717636,10521351724316120960,14139744951647666720]]},"stage_2_query":{"leaf_elements":[14976219280904091510,14965633052542554182,8128016976963063250,17090194594535101486,11396918536908840144,13189158203439736883,254544631184377312,2380735118716352038,8461382021428201173,9037424243173845949,8344071546669936526,10894466513947162645,12975986835805044437,815173829120024366],"proof":[[5344933117607184077,15249734638535545279,14548409128051277757,7652426423104245216],[14917809998993565430,5939608189044204949,9028141921790701839,1433628319179540804],[8423252097791095849,10922203385884186664,12614484941522724509,1079682504656614288],[4894363803987910574,17234895268054740795,5961253878863188745,672751660161727426],[1937074526918497334,6567389187387186363,5383619080248563232,1136205004925380555],[12229557357611064325,769983473285496497,7595665703731128083,5980964406685202032],[6876465260103903900,16765528539910586589,18336360368440590885,6370172719050810542],[4546051102167141600,5373530379056771694,4263331294084017079,10076692191821049967],[11628585071234968790,5950601936657181905,114726339343476578,6134334027143430169],[15440832467151555356,5479273855463993197,6617114201746396057,14633963974186621307],[8348010997789928264,3714343585763534842,5736928882501950332,16902124051074050377],[3914627237842066996,12267515581478055507,15402054932069527745,6408323307624289664],[7855167677598373369,2142188081707728460,6327518364192911017,3573775425728144385],[9822362843558230730,15058772864136074260,4494706712189923786,6922721037503262682],[15632236608052268635,9093255704663190905,13364791509029059700,16423361262046057891],[10229358543517269427,16193566026183384413,11311607980065102320,17621110224851630107],[5869921309556577715,9339185068615337392,8800710872398262048,6282664368056103267],[5471743823811849253,6540015935649497693,2283573760867703507,11142925402175779307]]},"quotient_query":{"leaf_elements":[11040680067169719323,17564844997755245678,14514690882005111192,4483118347211581032,17024994559054631767,9571738578196281785,5612985322282877347,16336955672880181497,10817737020460820364,364394106928166447,5318066738806657438,4071915765069898654,7247479246810860463,7269369694357609085,16756915835735038047,14040866168167914930],"proof":[[17611366899827455115,4129610797054318452,9083170355140096162,3574982213872897772],[4038361511253678887,11425592977140695600,17047864627422635076,649224381988495374],[3151543170123442829,43415538799924540,4103086418941021287,17570660220233975560],[6913233667612821039,513980274273002202,1151368040798554811,2672281754274183257],[16053687257789042551,15485423230597104808,2105686907121880928,1104753758145850982],[1244891542072668297,374776923964130765,5156996815486054689,8044196101045614739],[6892380391280244797,17790111248753265219,4477324959935659932,13625849117220453593],[14913200403675152841,16420383808252006557,4372820795309976661,5504063898234541903],[954512696768972019,15165198277584608910,3653764181340989036,4811537302590184690],[10187893663332375081,16025402607193403156,17379086927407359878,11474199296979898324],[14581811691225952841,12367546038564084878,4510122370359754547,2130604912026050425],[12759260492029526225,10813503682447925760,911742128688742608,9403556201650262210],[4928201998237630615,12423829971316965793,8391896244594166289,1596520396656659531],[13487031459295947599,722207019614685929,4973631693733087716,11134452499098448957],[5938566187808703992,15891881479836128491,15612814849596171115,18403343529525591847],[2318902930113479058,1243341709191820942,5435910896198801360,5512228300575826839],[2431131357391274341,12268613246918333298,12320730895980528629,7461349556249580242],[10826344330511786354,5332764646915660931,3292010532699891612,10539987730221327605]]},"setup_query":{"leaf_elements":[1054024053603319750,2617395972906752160,197379866724343030,4616502960940879852,1643991677829869890,2783214038615812389,7367604718983315887,7646406201109248839,6707780065217858273,1035212949173664872,5907957916752583076,17927377605576506955,6454828237704435896,9633146681838639601,15554417367515760497,8052703926792949014,15668458810100990280,17550320015991080125,3344331879692166171,16419914349729399376,14693553409037475773,17176496062143200681,14621293792226282128,16860215303641477364,6678794246313886009,12188769171807906680,13917193223042158268,7129935149882378114,12379770378215728176,6812208460298063405,13074254698186702173,17456164731143312880,10202036211543343056,1242896732676455979,12306275944916889097,1980838629786226688,11730526504729668493,17793177016731657642,14412818266232126497,3505309159622809790,10470061299534593338,167169037476354642,5686609229392183646,502450082996895188,12854130711045136421,7776597577294860216,10184198421564390718,13433052350708315924,7240744588049037195,2445273400102824198,13916256627383926573,7443781640707043074,9094779836142626991,11649721945628797446,16200228425341680131,229479824138385701,12026304316993957602,18422347886606782399,5052756993463355503,16036519401883291062,18060637402653785884,10000293111475535415,8994080474965938479,6920902911726653932],"proof":[[1073166653091725361,12572268128942891141,11473681302598831798,66605677386040866],[17987538764391580188,5039383438559871350,10542119875772330173,7697891998392785214],[12038686132034403908,16221617612109075769,14800265682393301319,3590367957226605730],[12894644477402698371,3866553342543854956,12724540967708237382,18106987710787452749],[12094555408056179954,15486020120110200308,13780018594837625998,17167969982601639564],[7517196204075965259,16105075927487766026,8483826554021275727,6564764128411848297],[15128789479537159359,9837294747701327789,8802574169673247692,6492852811904253280],[4353087121954401060,114502361192997676,3802193014025135340,7239027749512390741],[332864283074662186,4697345279920118343,12840162695996386233,4662772222529091098],[2314796323274393469,12990884423023088206,13315326447411822875,10690747354688312499],[3770004358179730259,4004628832479349472,1167919516113718603,8663863562236252594],[11195772720160550131,14181000726986860555,10053255583332531921,6799746254881049796],[7129931188928540057,8800898852823266022,5419592470522684177,13541550303627901240],[13061006656516950005,903372566144978903,8327130445469963055,6156609836770167028],[3335205294908407113,13364072588304262467,15381297070076395089,14770868299799417494],[18250177956055794712,7658397678139273373,4374745740112763778,6946914389470709248],[6819763408055541008,11765148831660617075,18051570944864039866,2861928988314562104],[13511381266976691921,9204072167241091301,339207757332023896,12754055892169127042]]},"fri_queries":[{"leaf_elements":[7246674715257934842,11460878035132385193,2284330786618373309,18213888820596662553,9247567077292436621,16095314723252575331,10923586079791294122,16851262273666500268,7650533855843417286,702357168523535568,2485298170192358018,160115963744059638,14453449384189738964,11486609130740869485,1830978901246565481,15967034833928723867],"proof":[[15225084150985196228,9214497751922411089,15838119938596920137,2277609327862981816],[837939167302518830,4426425740925152989,13074254381754698483,10293877444019806485],[11040940549578748408,5812386485910778984,2630778391662911025,16367240178728899787],[5657547992392833135,10921112933765458790,4028148965456123755,16799849701105635430],[5510025556392076551,6500653341041176957,645331161134556333,1034497717560707248],[18043411146556089479,318949029802388601,3515662798785011021,12597852335613980],[8051796317182057780,5503522181189635005,9611488717894870380,16812430646612138119],[10065394572120559975,5019136222485604195,8987226429351842880,7387976702804866329],[16159400338881498992,10664151608502495450,7901267523350027900,17570614743704954561],[5107053210586775711,17287907062373683554,14357227159191181585,8935975670759240766],[13117259431950850634,16249763254708065066,4161554328007031371,13810007365223282584],[14001825071001746894,13749424692534672826,4610053078018678434,13256456141923219814],[10377188900711704163,1963487382597196011,18007656014685190672,13222595465088113623],[518037237748469646,8464465888538270010,2672997553360631705,14735009888172809189],[7545942003694895962,4430901567266856434,18008190376195831755,14457898847592396527]]},{"leaf_elements":[1946874215825162009,9275318291622953291,5898921190937749160,7982459213866272040,9625662957398160690,8141013983178197785,12042763715367226918,13707467106551360096,13753525959965936303,255307588243820798,11729283387408084245,15312103465973115550,10562352809617872946,15093692641692087525,17263486481143890981,12143567453820041933],"proof":[[10647371826275411923,7467514293938863018,16518999768389178984,11147418775334772925],[17174921571803373116,2087420678330896864,17296352798283507838,16408543617055434078],[3514371526948892948,13888509442455492378,9696921592434301020,15275166582713484850],[184941994254309101,15769750953343543502,9459529700379071983,4716687079685031677],[11819050437689732923,388334058283990690,7473546011739131060,11835151450471352106],[12856131558560620622,10415566829662203756,11887455741387033523,25214574774767881],[3171628126779204251,17044073838885727413,2183342525528429327,3993839232257814416],[4195747733709784598,2326772876317556195,3559317343959319698,16600127041433218902],[7179665857147103096,14891166619982925747,11378422288771439705,3010269020139204073],[12518693291181474123,16324756575396701251,10278587244966618604,14172435832571177953],[5955768343138615107,5526856581958276412,9473829436335066317,9376882554089853521],[1476082179997634999,4973310619918354050,15585530083552013026,7246114375327049413]]},{"leaf_elements":[5330641656621853699,8711732863125538823,3447929774869712766,7168574408118096988,6797722428365811277,4567139453540762228,7124957519482582969,15388176571640449380,16673959318674154730,11841722474351239383,5748838800645976687,10692182436459427430,11031282618862358018,1724848736519926820,8859876651335631974,10110748524619036439],"proof":[[18136774783176714672,3281413396486877473,3037892234996068051,9299649188447232435],[6389505632732016256,703900770940356843,27506637295504877,14043493804289372884],[410439850443923477,10722844089717522057,7148212315214287112,1095975523312701205],[11707913829259726964,384931307016213355,697536652987809403,9565495768812115202],[1989208768483957577,11343648864072423751,2722548807025088174,3296203684406301326],[2651321282195997867,7507816525201665086,2840421606862190804,1590583044410136081],[10283355561544098303,4731597653445311075,16290542868495815823,6717108767632654456],[8791099107346208823,4584416702334346216,5183012522400628418,15734320795851729363],[10208304403933904922,14465763810456685406,17659371736893445385,2521515806800186067]]},{"leaf_elements":[2186421424602105816,6450246289647562627,11972379055334450769,9813970224766982991,879362449000127671,16896852614972749775,10108767207921819214,3337955330394570211,6822733019802979393,15827437646235361313,12989577208095706031,17789041301402022171,14554488340567834510,16384314450703798208,4220430685136636311,340762826558588821],"proof":[[6268116134796542711,4010065226199649889,10078255254467470058,8673234310322547378],[6382783948479903036,9406026191488378978,7591765175653861528,13602691365137215649],[12253780897952537791,18232620503150080534,13260412999447618141,17893638821250803040],[17567525765662997033,18104909051651200262,116845577605416002,17575331003484804244],[12520963196317715250,12034179766624480193,874724416978697220,9510735478429761646],[3935484210871915129,6085499747822073997,13696068127854900170,16071953757664270289]]},{"leaf_elements":[13849200735265606592,2911186219589700891,8079342903966152931,3214585058102396934],"proof":[[6646333828370510291,12790334713601427454,9588662109326697740,16720823300183019225],[12779445884533560653,2343216436280778759,3619172083211263972,174257551434159748],[4469036213792095104,13148882059967935549,5958811219522023613,4055260207392587346],[4265262798329431481,5363171640436041830,10324534340023204103,15488647740906044989],[6195082165675208403,3296113561374908808,16304923259978842349,7184461966159293560]]}]}],"pow_challenge":0,"_marker":null}} \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_proof_3.json b/crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_proof_3.json new file mode 100644 index 0000000..52c8705 --- /dev/null +++ b/crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_proof_3.json @@ -0,0 +1 @@ +{"CompressionMode3Circuit":{"proof_config":{"fri_lde_factor":1024,"merkle_tree_cap_size":16,"fri_folding_schedule":null,"security_level":80,"pow_bits":0},"public_inputs":[1961802424684827,44478075017541700,68433799240021256,10969447465159162],"witness_oracle_cap":[[12055323888936785949,8925141072488969043,8517748933146167,10619647413238491136],[4752550732523370721,2172293896411005027,8771173985154707698,1707274044526905507],[14166662071573286059,3226257817502040590,10103648779663134280,14877398228887781687],[12081182684597771927,16163451325610214099,8997089674927262091,13106537637972543462],[2748514063954722702,12179648782000491345,14090846012120196559,13977348834950131145],[12820649030096062499,16249595047161742751,1650462115574186781,14590737570209463874],[10673376775381439556,11183671114905506514,3983327380923467014,6029538833066971066],[5044990778226736798,7351414561216318590,4306268577549311586,15294188262862894820],[16830814754971942954,16415497296093943212,11407215381897682806,3922549750534806974],[13183714747191390726,3197190502234878679,2421279128170782081,8771246220286075956],[9852634317492955520,17329465939960336883,16143080540615273224,47664137932467348],[15417601071549110808,3522137722303516641,10924910234659671756,2675013225896886932],[6677815924722241429,13047366815065775455,1829388675863057024,5871005199389633090],[14699785317281247239,11480307656616916718,3295435611919325783,3101134820014103294],[17735875900235896501,6495696023797089355,10023270393570070300,3950946623163496713],[8701979621160167324,11514893901409466588,17223235234907192292,16243855973377333136]],"stage_2_oracle_cap":[[3815884216919426084,5551665547907765167,13989076466180446003,3063727649625422824],[12507016016051610552,9346781294048201295,6312152680644953397,14490197124604554329],[16369117938634173871,18405970148557288717,3638925296650398116,1237992972876156743],[12347323213492920768,665665933224594266,7004939778495477872,8212401294256751010],[16969320961089901105,13112542524920180038,1052121488105109576,1782394159649385895],[12749384910174352984,14315377020470550313,8252536608616100617,5167029918875568519],[9407152521515531066,11459880003030391872,3288832994507811178,11056884472148426354],[16989385108794456656,7913910007712515816,14132775077426011660,830687231236796096],[85867150628166762,9804617839969305645,7394666572455217517,9796165708430176183],[5583170277919135991,14889918577295875176,11813611911636842259,13889934737885803072],[10737101943207826014,16346122036036415236,8624451143641013104,5373689891232403178],[6101701716253925996,7332060231224456340,1877522504073751247,17478084542270283307],[7168025052528145409,6722326536734673741,14195320942031695147,13645638999523145657],[15945399202608118806,9652728370911336405,9040709369805130200,1333236514742944042],[8819436836814844051,14098334801363244470,6970020312001201445,10134967432211087486],[10910034154644480672,15805276799556927476,16879506225819766607,8727945133467102761]],"quotient_oracle_cap":[[7074259075159004689,13613780955430494855,15282777131689971469,2576075763848133044],[8601610168193126937,12845694664420384998,2475985721010970426,1765665756120802038],[5603875406611913845,12248390406876110053,9463212293863363667,1014913930189603403],[11541907345659319356,364056772594990202,16534634295291403823,5093635993922826315],[9228872662515542553,18071476347337160899,16092129869056669424,910799602377406538],[3653851253652940003,14739662579771344727,10746107129137942116,15311992762351170212],[5353934843778394984,4049503219260589679,14060871957087520786,4617649985774570325],[11186802715162605405,3998548954542090634,6796328792473944314,7504685783359905333],[9976926024723823699,4137140791515298439,13749717212856717307,1113988424369819553],[3906946126707296561,5254907035583203455,6582264959638041819,8327968249111016832],[10858332652678238310,11287648956110237075,16410359780850107830,6699194961792569119],[1759904820731068539,9132150118722130539,8114170989883567216,2958563962259651729],[14165692166868075550,17198204640153997501,15209333639782382012,18411513543155698381],[15088005614892313525,4899721596301663397,5770185011714021278,14996748948101305208],[7539141050401103213,1141208486950374529,10764147020553702406,6679711165512212386],[12547764767368669395,1864850594641004365,2574043737027291034,216699615810870731]],"final_fri_monomials":[[5597756513543857309],[4442696327276334004]],"values_at_z":[{"coeffs":[2255279565488157578,17160156824553230460],"_marker":null},{"coeffs":[2148093839001304925,17222438167411216989],"_marker":null},{"coeffs":[3154973740397109766,11264928886802628430],"_marker":null},{"coeffs":[360979005802180133,499180039304749418],"_marker":null},{"coeffs":[4689993417456680389,4986532210698117235],"_marker":null},{"coeffs":[4354447152696171222,11784250721490813113],"_marker":null},{"coeffs":[5841543181077406631,4518223864285185852],"_marker":null},{"coeffs":[15330842789582063966,16178878226600342460],"_marker":null},{"coeffs":[9760555479924098680,879839217603379723],"_marker":null},{"coeffs":[295251258478788065,17486015100370102260],"_marker":null},{"coeffs":[3164962038105510218,7552898047350078285],"_marker":null},{"coeffs":[15840254556790466759,16413291019565723972],"_marker":null},{"coeffs":[10440245820350745699,5124717076074625773],"_marker":null},{"coeffs":[12778197682476528670,18189617754427342203],"_marker":null},{"coeffs":[7619081774755363992,13606879689105326798],"_marker":null},{"coeffs":[1454297331349103902,2544064225673355094],"_marker":null},{"coeffs":[8344009471969597491,3689522163926246896],"_marker":null},{"coeffs":[597797421020413888,3558428790686379859],"_marker":null},{"coeffs":[17603762269998415026,4087017613133203900],"_marker":null},{"coeffs":[8768709944670404004,11678143906326141478],"_marker":null},{"coeffs":[15028550748493312322,14127069309923152560],"_marker":null},{"coeffs":[14310428246606977375,178744889638613035],"_marker":null},{"coeffs":[13691319922154292636,4248124476587587458],"_marker":null},{"coeffs":[16639473316077058861,11829429492306688613],"_marker":null},{"coeffs":[17756876009960887184,8750610948770752685],"_marker":null},{"coeffs":[14611542256820446920,6276210100071320335],"_marker":null},{"coeffs":[3298795344150058971,1620852226282864060],"_marker":null},{"coeffs":[12396815889426685536,1761820332670164857],"_marker":null},{"coeffs":[6820701808827696120,8985511301266887625],"_marker":null},{"coeffs":[16605134639328916683,17580918937218502518],"_marker":null},{"coeffs":[13904633084812759532,8663226186936539483],"_marker":null},{"coeffs":[9226195689889843008,12403812508292506763],"_marker":null},{"coeffs":[14385869586293566616,12102736795536240606],"_marker":null},{"coeffs":[17438886138571932130,8506728145990778841],"_marker":null},{"coeffs":[15419878873590566470,9825706748934010926],"_marker":null},{"coeffs":[7868843837011580863,8878984203365449744],"_marker":null},{"coeffs":[3923387034397755366,10825223467503347420],"_marker":null},{"coeffs":[9525900896814435140,10880054342310654681],"_marker":null},{"coeffs":[1320830505821594884,5031738507702668822],"_marker":null},{"coeffs":[14348655714064392259,15521436527877519590],"_marker":null},{"coeffs":[9896776537738463322,3574059449809479833],"_marker":null},{"coeffs":[1139291681210973916,11986769475154890277],"_marker":null},{"coeffs":[4193238182225473514,13788243528674404020],"_marker":null},{"coeffs":[15843598273454325062,6561663160639362099],"_marker":null},{"coeffs":[10277003639975802432,3525843103986504191],"_marker":null},{"coeffs":[11728825414256233470,4051862126836472982],"_marker":null},{"coeffs":[1596331986046399371,5965036889276199688],"_marker":null},{"coeffs":[13874416515613849533,179199087222269239],"_marker":null},{"coeffs":[1837948426098899692,12801742547434481124],"_marker":null},{"coeffs":[9780712625437596585,3931736668229554854],"_marker":null},{"coeffs":[10035969517482380147,12235467085876013920],"_marker":null},{"coeffs":[16645808173317813714,14102511937201419249],"_marker":null},{"coeffs":[8530808846222386667,15292501938147734556],"_marker":null},{"coeffs":[3748778249477553238,2722231668410586040],"_marker":null},{"coeffs":[12530892896424782003,16352627701979051850],"_marker":null},{"coeffs":[16258667513747651674,3530857589613247298],"_marker":null},{"coeffs":[17309506305439205088,12868593359582568820],"_marker":null},{"coeffs":[14787458083536446842,10216554123489242730],"_marker":null},{"coeffs":[14228212715813826703,1198026748726441062],"_marker":null},{"coeffs":[18127077615070953180,2683549651327227335],"_marker":null},{"coeffs":[16881218994821855484,7340532505593023276],"_marker":null},{"coeffs":[354442871774004890,3669325994681545141],"_marker":null},{"coeffs":[11403877357549828829,10368280831863639470],"_marker":null},{"coeffs":[17669717799389090263,5343838939781737502],"_marker":null},{"coeffs":[8237116308123298845,13244185723325739336],"_marker":null},{"coeffs":[2479081626712778638,2511519318042245379],"_marker":null},{"coeffs":[6807463675335392380,12896637149738481776],"_marker":null},{"coeffs":[14829986473646850207,17076522634257161497],"_marker":null},{"coeffs":[34355778780043843,12459405877270077141],"_marker":null},{"coeffs":[11760757941323743090,9206397059566462661],"_marker":null},{"coeffs":[14411314250073452177,17717229209689488046],"_marker":null},{"coeffs":[9742021175913756980,8460344404257031556],"_marker":null},{"coeffs":[4563857127817922020,12462737539225026039],"_marker":null},{"coeffs":[10002312195017471404,2889758129030683080],"_marker":null},{"coeffs":[11415448882463351951,11619049693007948768],"_marker":null},{"coeffs":[17518666680768021232,7214815903438709285],"_marker":null},{"coeffs":[1032446261717356657,9156469659485736183],"_marker":null},{"coeffs":[4774845687523144817,2793207423900666150],"_marker":null},{"coeffs":[8360621045193327181,6598937365233937350],"_marker":null},{"coeffs":[10039595253604463116,17093009314869545005],"_marker":null},{"coeffs":[15917848180399906643,5181569068947837744],"_marker":null},{"coeffs":[2352953194543311125,13697910073638964028],"_marker":null},{"coeffs":[12762928380819839022,11816127064051464754],"_marker":null},{"coeffs":[1266251713245268157,1062561168404880878],"_marker":null},{"coeffs":[2106737167971311342,1489702785067625662],"_marker":null},{"coeffs":[14881685930439266158,13006970994391233213],"_marker":null},{"coeffs":[16186347476206742012,18408333322447592199],"_marker":null},{"coeffs":[3021077420103372603,9882805514576359901],"_marker":null},{"coeffs":[15616965661800351074,4984761249667355026],"_marker":null},{"coeffs":[882385451620077681,17423368543750058148],"_marker":null},{"coeffs":[9447062687134665700,7385117549410896632],"_marker":null},{"coeffs":[6615324453566025437,8707845870815290582],"_marker":null},{"coeffs":[6384558596965894675,13900948443118622757],"_marker":null},{"coeffs":[5489819824361592689,8656993254623606347],"_marker":null},{"coeffs":[5054214343930492414,6453627588035246011],"_marker":null},{"coeffs":[5245025843728543667,3400844577946811086],"_marker":null},{"coeffs":[4254514098262285979,12959763209140843132],"_marker":null},{"coeffs":[10279276472046892511,8245432894316226372],"_marker":null},{"coeffs":[15756840521588580156,15678731943266615747],"_marker":null},{"coeffs":[11378657069215329462,17778950717192185113],"_marker":null},{"coeffs":[3264948578528682350,2591361033227563559],"_marker":null},{"coeffs":[211374088030095880,1535932694000728027],"_marker":null},{"coeffs":[210175105095151421,9560997090584978794],"_marker":null},{"coeffs":[2992848926399411120,2394443325846556275],"_marker":null},{"coeffs":[494115769545165202,4312017676598157055],"_marker":null},{"coeffs":[13542502494726868178,15586688029091043921],"_marker":null},{"coeffs":[8042746208653966106,6882631918135090446],"_marker":null},{"coeffs":[1822848332718561224,5588872652113203252],"_marker":null},{"coeffs":[13487308348924465492,13817483916226203404],"_marker":null},{"coeffs":[12447199272111883333,3144730536680866477],"_marker":null},{"coeffs":[17983119159898050268,7510498673887578518],"_marker":null},{"coeffs":[15846737727878644339,15312634003992500297],"_marker":null},{"coeffs":[10725242101862932788,15455724617751300780],"_marker":null},{"coeffs":[11962747126162498524,4467899624434483956],"_marker":null},{"coeffs":[18211388590840464221,17672217361818549286],"_marker":null},{"coeffs":[5261474754539120404,17948280826484736646],"_marker":null},{"coeffs":[16361874745819236690,18078858989562897264],"_marker":null},{"coeffs":[13687071184763956080,6868159875171225884],"_marker":null},{"coeffs":[5283653986960247842,17402864129446251065],"_marker":null},{"coeffs":[5593596208019056913,17443166201144230128],"_marker":null},{"coeffs":[16653651342276388192,18441306978053664307],"_marker":null},{"coeffs":[7731453197127626835,6945847085249157136],"_marker":null},{"coeffs":[13142846324137919781,11550884813795773242],"_marker":null},{"coeffs":[5443931919474713825,13462629826547623249],"_marker":null},{"coeffs":[4312369611306132534,12767370730797433315],"_marker":null},{"coeffs":[3388468908719965747,15134879374146217335],"_marker":null},{"coeffs":[4761873636953519444,8569069980089959441],"_marker":null},{"coeffs":[8808026260643468875,7207213070146676696],"_marker":null},{"coeffs":[6776416057401160771,13250097142885983012],"_marker":null},{"coeffs":[11051905382575514795,2930097178049150849],"_marker":null},{"coeffs":[15244681057807691348,12534570533263142605],"_marker":null},{"coeffs":[15433652732438832939,10055070834365158551],"_marker":null},{"coeffs":[2823795586922428862,14261339058285848830],"_marker":null},{"coeffs":[17842340461332196150,17381609293820511544],"_marker":null},{"coeffs":[15278132891459845682,1278141674563844718],"_marker":null},{"coeffs":[13167285830350868143,7037667575663848288],"_marker":null},{"coeffs":[3062727378576733173,5266378835164496336],"_marker":null},{"coeffs":[2887538339969913627,14649599734550778553],"_marker":null},{"coeffs":[6782601277507876427,4477222143156101800],"_marker":null},{"coeffs":[5642278496329170611,5322718073229394691],"_marker":null},{"coeffs":[16680945389504483527,11683299623114542039],"_marker":null},{"coeffs":[17523366852843219774,14078248554792147451],"_marker":null},{"coeffs":[1827996710579094189,17637592797554070167],"_marker":null},{"coeffs":[9688018137776070647,10388577656924687388],"_marker":null},{"coeffs":[4561291080340492947,14777035469100864163],"_marker":null},{"coeffs":[12686840887398946148,13992524461989447982],"_marker":null},{"coeffs":[7552839257516360910,5321276917414075220],"_marker":null},{"coeffs":[18003809665505699865,4870161802244806887],"_marker":null},{"coeffs":[2687045639205768621,8528775779723264225],"_marker":null},{"coeffs":[1718564608086311897,16534062467340030813],"_marker":null},{"coeffs":[1922606818895294706,7296395113620096788],"_marker":null},{"coeffs":[7080515797293232674,3657758760072482892],"_marker":null},{"coeffs":[7850981169350918172,17898766848830397373],"_marker":null},{"coeffs":[11599636621482625047,4547473767937214880],"_marker":null},{"coeffs":[18308113347178017550,4156533963748697273],"_marker":null},{"coeffs":[3996521042449903723,10596458951185604657],"_marker":null},{"coeffs":[11348414022817803672,8736464425720846926],"_marker":null},{"coeffs":[15341293017365041882,8304508163121222077],"_marker":null},{"coeffs":[3789416469421027192,6857493520281070432],"_marker":null},{"coeffs":[11417898365276179946,6925560626949940986],"_marker":null},{"coeffs":[6476837665197116585,11825771986645588918],"_marker":null},{"coeffs":[9258878048081488367,11073111005520579988],"_marker":null},{"coeffs":[9227858176781152662,3032269296470542439],"_marker":null},{"coeffs":[13224286613128718593,9266582752349578782],"_marker":null},{"coeffs":[8482374640603459397,14946877623379043451],"_marker":null},{"coeffs":[18078579308386580115,13861812875313729682],"_marker":null},{"coeffs":[6210756888421478203,10772273356527427285],"_marker":null},{"coeffs":[897100858954921320,15808448472073475990],"_marker":null},{"coeffs":[13624275889311018958,14669821095419359476],"_marker":null},{"coeffs":[3604246402531841596,15245529189203448497],"_marker":null},{"coeffs":[7417113425021198545,8632128189730735499],"_marker":null},{"coeffs":[11306289075286145778,12231514937060340923],"_marker":null},{"coeffs":[3434857836515650722,2911178661569405805],"_marker":null},{"coeffs":[2672389837234242382,9451201576544832258],"_marker":null},{"coeffs":[1767496233631922162,4490328478519003554],"_marker":null},{"coeffs":[11809994116971140395,14524874819010965796],"_marker":null},{"coeffs":[195811578446395124,14727921649304017206],"_marker":null},{"coeffs":[7097238621710552730,15788648094910038384],"_marker":null},{"coeffs":[11076125803660049932,12956411822654088350],"_marker":null},{"coeffs":[12534565049905993281,13087225096538957391],"_marker":null},{"coeffs":[7294064126491329960,18321865639940766325],"_marker":null},{"coeffs":[8523988141198623415,15456135993503743606],"_marker":null},{"coeffs":[14213487287864974290,884619257740836327],"_marker":null},{"coeffs":[16144913300317219645,14259748025641860508],"_marker":null},{"coeffs":[11235531875433904948,9479953777307676323],"_marker":null},{"coeffs":[1566108428721433947,4400779007194722460],"_marker":null},{"coeffs":[6435303315247393400,17423874528700800348],"_marker":null},{"coeffs":[11573215819688225052,7279654578262591643],"_marker":null},{"coeffs":[15431496599481413057,17950645536236015382],"_marker":null},{"coeffs":[4200218940449243309,9239926842511687475],"_marker":null},{"coeffs":[2808735863565926743,18123659698036956752],"_marker":null},{"coeffs":[2888990719739792590,3829246360937633039],"_marker":null},{"coeffs":[10446089532825654617,15393147207027418343],"_marker":null},{"coeffs":[3895548869456979925,11586679164040968700],"_marker":null},{"coeffs":[4817307501968952054,17808296062614932013],"_marker":null},{"coeffs":[2836438348978104541,13515451114587941285],"_marker":null},{"coeffs":[17823211751380941386,256729780974455124],"_marker":null},{"coeffs":[4453599260958219186,11831467413727770629],"_marker":null},{"coeffs":[15414175284099752034,10757075804124615555],"_marker":null},{"coeffs":[9412632316648703010,16359394676096138582],"_marker":null},{"coeffs":[8211946803197003198,16566176324470826177],"_marker":null},{"coeffs":[5906398840144695672,6850611044566097063],"_marker":null},{"coeffs":[3210198957834762317,13419620657663495052],"_marker":null},{"coeffs":[16769130353081236706,13169764296554191432],"_marker":null},{"coeffs":[3641027927963064531,16845777667483292985],"_marker":null},{"coeffs":[1532841227875648720,10461714733732126913],"_marker":null},{"coeffs":[6728515713532073430,15891105777798480244],"_marker":null},{"coeffs":[8279628419380603187,10677638630327851046],"_marker":null},{"coeffs":[16139942503110197177,16685986218528526063],"_marker":null},{"coeffs":[7758954390389481122,2057497060298460837],"_marker":null},{"coeffs":[7545662670813863071,993274782268141748],"_marker":null},{"coeffs":[12034940445089024837,14370339606120499993],"_marker":null},{"coeffs":[9731470338987352322,14069857557624372295],"_marker":null},{"coeffs":[2139236420100770232,13327443702353968700],"_marker":null},{"coeffs":[15868847981696639528,15140008996153637069],"_marker":null},{"coeffs":[11302692289848740507,16474709524007342998],"_marker":null},{"coeffs":[6669587275630218541,11157340947872062322],"_marker":null},{"coeffs":[14402120653415625169,13853622657740594880],"_marker":null},{"coeffs":[11628957024432486447,552283563588957817],"_marker":null},{"coeffs":[12126867579988757578,13112126303834879073],"_marker":null},{"coeffs":[9171248977509391000,9994197552219353202],"_marker":null},{"coeffs":[8495682802405167951,13260497780582854182],"_marker":null},{"coeffs":[15179316064691968262,16805165424789652007],"_marker":null}],"values_at_z_omega":[{"coeffs":[849559988323313509,15311377625005448921],"_marker":null}],"values_at_0":[],"fri_base_oracle_cap":[[18037766314841742175,16837403793633526285,3933242938824237083,6594884538426848802],[16404170892310186753,3734107186250264005,5225449858527852730,14128141498808104463],[16580308348679027333,14900746323804196821,10160495810032596415,5383115825539138536],[1676932257807790840,8136544804593013611,9904167287024507910,21224136618992733],[17855202415899775276,5425908915046970797,13143487867378589370,3185199587933743865],[6726097289839644742,3829585317723294326,16396978046688086666,2976101802890085467],[3636681529690395314,16513542953983971498,443664551135021395,7293107149819850284],[401774420061835973,18414171058943101257,9002059112898233194,1424074648670828719],[719298709511998758,12111373920530538094,16262691628723686063,18166249837175968467],[7419425633706354561,4164432526510935026,3592366658989321283,14991490494181350197],[12112255198226312685,10070828027405353219,10180361326621841460,17747642793858338271],[1309276720936016377,15148646097289002370,8231590116047758098,1756236643210797210],[10979666801278128192,14925185316992266418,520189756763396625,2780738192340658044],[11920936812481983113,4595987010024081083,4055457826732058343,7749707663570487878],[16358920207788707845,12618937435569116953,14802583002467896375,13645156229645869543],[2293411823001204908,3247614174380411820,3137291055524192134,11398259806065367524]],"fri_intermediate_oracles_caps":[[[15297133977116681079,5264741235380085687,9600037262974225166,12906412835907785252],[14505441773859444963,9286715477894152257,8641862851491957203,4219884394177287422],[9793588384506107950,5898597723824669051,707455326491897797,18271250489439515347],[991942791337905274,4290108262283367040,3492910887201281781,11437310866262373179],[2936483236198973922,7826208133818556716,6650576972210210290,10355729386274179665],[1086448522654140603,16343401734946975024,8757989935744047320,9799156887308981420],[18211628960018294903,1051432061178954132,4575114188852558988,3449827172651496856],[2069103607141046606,13531003751349835658,10921489291847367712,12658691921660459124],[5802261884827271440,14284651020450180352,6127474227122189632,7002744325987576428],[1042543233268276560,1731238017678847128,15329321129060304723,11261127017062864311],[18221595055853221347,12408681864170528373,9780272385089144952,14161548835654873309],[145610052238851541,244797012322567904,14915459011660781400,414982351855905566],[1144925621997951993,15273739299640958880,4155655258539454571,16081214963535822808],[7080321816674391695,5669966336788910023,12385573045411997784,3351773449271870525],[7253770902624010118,6095457630545518314,7430582230635453612,15812760944057789216],[6676888714228425589,2430310541639587989,7649806538733665090,14777878472491905057]],[[18062945576957428821,4092393582988833931,12288292644477425129,8711275296511531725],[2898469276672294049,3915799996359493824,3495674165130774567,2649585211831513236],[6785999588541087151,3652266523625756985,17253902437534351841,2623465533309005199],[5907763416051672226,15496904561760893993,3771202295640827700,1864229529186986407],[6210176488080251093,12152505197942599265,1068181701339784864,14137667645038506396],[7534126408266801773,1375396599124136701,16301909797025294167,13442026145526168559],[12881708261673053758,3020154915209393047,16504211513294644832,12681124779762618960],[12865121247838164597,11810599792883952601,1852090919550268189,16513024091458088565],[1838234518157338360,2841358607833018160,13840672020828569478,7917547786810133485],[12568477323851078011,14750712839016663132,9908296394463569892,10647118357391655192],[13769539942177967083,1014373883079911599,14688717879461299929,15123983109007624634],[515752622933333702,14276629476056381688,17439012096805597236,9284662778407534344],[6453854553931152041,15950064422877012646,6759701934576034418,12843810428749558594],[14115077051404704083,8601343024028999178,3959029151772904398,11922912370680606153],[12331988137795633343,660477231010645367,5059188442201453691,16472380026410137171],[6411693889241902406,3735354708705487124,12590235504614751755,645499687210961150]],[[10520272951378319657,14211014634468194832,1373930421713443597,4268524228269898189],[5965505717169228897,8213226257664331077,4478275986832669524,17201180872365396644],[9226884646403405386,10600135983347029520,13208144465375772747,2853228364563709500],[14130102535142301502,16929620841585669259,9219420259509968705,17665225108764636688],[15470147306501002111,10077701258551270918,7798367394971073320,15218327177841257943],[12611913509337751829,14229644255038502874,16704044545941286892,11979877897950216562],[3142963958357109370,10400849048066198603,15755155534288604506,8218722621342846525],[1343978851537278763,16060957114874755395,1398776359369973927,9855755789831040494],[7955412348408373134,5252266216738241220,8452573847729821334,8731137696349796409],[8577012418158146644,1519103383619381670,13685910994954422959,4297127191219378568],[12643526761275895156,1256875473650510188,15759537262871821351,7638619297579832520],[16986069679005498063,12023215783472554664,4724702346023631009,18120352557941040448],[9133725644610369506,5826189170999465103,8407196305142261827,15962045386649120844],[7977299442012849110,7461871847746276539,16070221331224059802,6667464815109545958],[14609585550394881181,5971478804465111698,9131051387972033285,14163269233433182293],[69710145065465985,17525341008177180725,6348971638552660502,10528126660683588429]]],"queries_per_fri_repetition":[{"witness_query":{"leaf_elements":[1663596935519139824,10973338504805859036,9019054595113998654,12621232012581835409,8950182694013911791,17116561981129376272,15736688310662732145,12405027986146583601,14811613610131102430,16941003802087455715,18239880623109985238,18094799630173775340,8829961701601993405,6260964449859621834,8551392385977194105,10064459943865132244,2962214300208087863,4833744369203085901,7293644962957371450,12768848647949259087,15304195807563456149,11360453390038816705,414644300111790440,2692140903029627853,8707194678429278476,6228846475089976490,16999877816635304606,8148370371337563988,15017557697460009017,15760154154252160297,6507141879148249590,13227807604190618179,635665361587588396,6028047418142476235,10983525536549259716,10733606951080493607,11153609899722259933,1111838267797726124,10502628834228203762,10610131801350131174,12396359727013660320,14093640486494179232,4093930709665987905,5703111551030759459,946433808290525595,16657746246129804732,6511656332101174134,4840978463489671991,16078991235613390198,11101127550644080579,2394252039565414040,16720989611978248532,486535407608489292,16110086747362957869,10342433370517998011,495316904243745790,3269772498157973392,4539804619292806023,10974347392894352119,6693140184069223860,6197739998614127122,5668914396494374107,957262212715900848,18091748434071393576,7841708826564004469,9120146454304930920,16740104237687074150,14210277641183380797,8434110624149523851,4819731777571375707,17827817799982925248,2338285366095474414,3050829441459932465,11468854024910914462,17684133981300615332,9502822264054194324,1073869547344023426,9783644548867374421,16941281837748420263,11558387716413069706,10014539532671349646,16364133102963521449,10812623179029232994,9506795769620472991,16912658755399435754,17256899866848006929,14957641375120448529,12205324406045474677,11760416197692742120,411332280516899954,8152928846293942467,5466650570482794027,4736509150488717055,15166564274342270858,12087978270947241342,1774363941718963080,1049152256214335510,9643477165133638330,14526655932350272901,2561861289818567718,12362483447105830559,6193243646155872108,10190228081173325922,3100307939624686339,539501971558317508,1423308963191404079,10829953679298796717,9093057570139331806,2118608071897633978,5195807739427490139,13458545030095989480,13732948716214303488,7228268898095931794,6622242955279653335,4547572395873065999,17399901606238603145,7925311951691107285,2657205170020418722,13748769094527932225,7629850925438477570,9856822489173922800,8234947621141696968,17385492725784628708,14420060637561072254,11752870370163984033,3309627266217838810,17836795557413022543,3592393574682649596,7745172435243621726,1416320760574964909],"proof":[[15137756884730443966,12408816729326718203,2136646895088303734,5970561594900993738],[18377294343652764248,10423132680065328624,17656314340749033567,11104302278272374101],[13428893615067343744,1554507286948142241,17036272686650392259,16092098637206791866],[11070523448541583571,15675162663133835949,12564698097947229946,14818061890654725850],[16236326683691114559,6955155557092273479,5825343396637488714,8198894082940448607],[38808936434785515,11365708849876604215,17883417951542441963,16838165097590076614],[13474735392467975737,2670001389226329584,2730593160514064576,17696365982527634344],[6393833672473698644,7227278099536696718,2126415846417460545,18147737637687249447],[7601003874052040105,10559662341298853416,2019587538880199586,16357627693270866244],[15259217994042437726,4785697030798770451,15314104295024775391,2171472341893627682],[8672024166947877766,1734858206083733028,1930513571646426149,12348556434843283247],[6163764896283702417,7966785843461764150,16127451722861739056,16442900134579176303],[16253906793243772629,11839883687895322454,3484583364847295336,15309384830608646673],[15345795324143086228,3136447453497623870,15703321837201318524,12805242863420923769],[13558494071172387459,2814199735065397363,10291448787017792713,14382963344311970400],[14831383226595884605,17074194208441125300,16436983537693195598,9342079513622645313],[7325553852022195721,11557081777466539126,12297083230043688966,13040681872513583546],[16000792915491631923,17148416164197935686,255216172133186196,3263293029400120095]]},"stage_2_query":{"leaf_elements":[9666481309982271091,12051126905008471574,11577875569564708356,15430388925435994362,12628294145655419795,3541169861319772296,1550829298966654262,13728837446334791674,11926551761064248714,4723240463740355468,7377470809844185350,2886904097029994272,8526940990692378836,443225271361812148,12053458090283927535,5099625517289508523,524662607180110180,2622359950884422531],"proof":[[17101668475718061869,8306675266629240932,17202723043491403286,15778944264757974059],[12936798685427157993,4380237462843929995,3875824102811683390,15710593410815434625],[6033943380067111219,15642268869034892872,15716873843141991875,275042604406774215],[7445294018393318013,10638876997894771287,1204670246325725867,15590728197248445439],[14519525970025908647,4194769559719580161,430039246753534197,9339932289600578373],[850480652648158419,15199130976219577902,3973058197381399041,12988957464156473093],[14904758758768497428,12884744842696934001,6685070108004619488,11110580991317306943],[11646797563368172586,13271649393194823961,14541593597338527150,14841842758129705637],[1897435920027289949,10974926276828220199,3301857362033459865,1039023045414156384],[14574700139530640695,5809256704017645537,3824828012086984451,18358557401603399059],[2869731939790910013,3999612137366643616,8907774836671416908,17544365400063051446],[1821221931932750151,7249736372026478291,11656730041491694088,16896768187762434629],[14005562070910521600,9313930838058617387,12207229298853810101,2564133658990824512],[7735048738338158653,2700567523186607184,15722298311010906755,14062563360986339505],[13469105930635518647,17954460526336428382,12763883402782695470,954560209145890809],[10109059936027153009,4160079021200532750,16440716538157081618,1609452719181493111],[3426387263747438051,16490117925089820756,5678337875440141603,95982675255037776],[13215945619658995689,12733923498228439579,7381658026017304721,7304220846445513817]]},"quotient_query":{"leaf_elements":[4992570905201168491,14684936133036727301,7780147227660379417,15569519286214350335,2706381667305719021,12779199481741580953,6824760919337343360,14450473889579701364,15498366528344281091,8052855729840343749,18321700022025889704,13129452287435150117,11210559830613909819,4326125373693717459,18399477896509874777,5058644123104075782],"proof":[[14285452356943411462,1694972428851530835,4945461485509004132,7139987193418707039],[8988948857333932766,13124582668592857868,15544309504545552771,8456110792991410781],[13393880343446994232,3675390515021307146,4486008818787636,7998197974842403161],[16872678195759357260,11079653104318220872,8500915181327491584,16107799727796984657],[12597927539952063970,5145315065885389115,5934327593339028215,17181925463763614749],[15736520617566394922,148471382464996751,7355649531321574234,7743925616082082704],[1505227699337797359,16902080653945525643,9424564691671897889,7913251409540561033],[4601280979955374887,15385920455492806219,17418299846203509388,11819684490397771535],[10455689812143912662,1472974583256517113,11436367666530106546,3344393257727976095],[4567179982711867233,7894864700133679537,14395624855128671651,8384674672896303016],[7954258319752310032,16852360857412073217,2206483281006412156,2856981809957147000],[12535812134829708076,6468096635513456187,12270169983819017739,10699157024488086974],[16568479485469410901,605077144051243302,8109339020797687108,16056476420810264137],[7637954666691713122,5814779470497888811,4002833628297568986,3669874534667192163],[14720881945805933114,2257443512412313158,5829036336048002595,14939569739648688167],[9806448703615476692,16117607797247599609,16639590750018772315,7497715421055893119],[9734821043215905567,2298765885060623539,2363652911132784064,17229212732587161398],[10408441719539954717,13011800597907004526,14171568953217407226,2001335238582904093]]},"setup_query":{"leaf_elements":[18066265914262677978,8465870777549006336,11007359029997200271,11448047527196869874,10190520283359969870,16082008150552699346,14370651941339150532,13490328733826541267,2754905730217912003,10755467509023859167,14143429301997058881,12843542453208494834,4297577489430581932,10029965966419279305,2147952099463449246,12740254252777061255,7015643639128563513,15798332542496274775,4081675353256077096,9018151729199067113,15481662030929109906,16773297863688479918,5367457498923414949,7033613966693708929,16699663931423093466,17998923510196009306,10645967317164070096,11171947965935705393,6181195373183193440,11736213791081329712,13829719309061617564,1707137578362604579,2390706342246861887,935683169636627470,16186395491284513822,9721841408489134710,8416675341893254237,5523636343708313985,7802122607429239730,3747997871706446336,5574504150224562086,16748003674611652066,14890219655337758147,10689613167708106749,16515946774542455991,12548314247916474385,7605437821524246698,12853572910037184282,15703548089176828202,2151641639259871752,12442836080286300959,16536175221507168243,6714977256948001428,18037373519576558542,2900619176043281433,6464065686420727076,2365376980938874244,1974845226922970813,14427341359143264939,7812153787652764555,13833825160458756448,5799188642163885644,838545769706409591,18015280254316738220,11906821110550395672,13998543635331488535,596721590537786082,10693767338865339628,11123371289466958938,12815490579269465377,5976655817474096400,7518358154769851990,13307816883030860410,13652086816423787404,5905715022227383387,17034792337429081871],"proof":[[8978895774541820899,1318147608835733558,516027726025731493,11971574631039265187],[1566394163278787802,902612586359876357,8073194209854178668,6236806161589932978],[5182821186548638299,5730621140823530769,16152749004765741347,434070389716873476],[9128306630515326289,18048530334576987695,15844520752065233806,11758405838554053743],[14479676510191572290,5359106814123387959,1963983102840190640,14298333230346886523],[6369080092791380521,13288321892157766006,10074982994717058193,3294445639200841291],[7260434977635056575,12354459432569490170,13388284576304863179,6421817300397080880],[1798716230836080581,6942864342759104867,1683873204898678291,2010523352438363737],[15721588136394225871,1825343027487026696,13487750241386227766,742703170284390129],[13062488983077989217,442722348273231279,10609287062968555747,13179417874101938276],[5156875369555418439,6482037859475720476,14489411936126502061,6646077636421465624],[10872627035431470950,4770351153749393055,300686457896298474,3606745842893758147],[14043426921107412001,13035117081317680776,2705414202625205836,17477608240800514110],[5372816318137058245,11468313637908496493,10895374080410561172,15056899781328040379],[6934161552888382697,17838282533123295611,17518515387088521511,1829418374080507708],[5115759697894093758,719364548534175885,5036383665754954988,3852895828090997022],[4210053070281770351,5152741504942943913,15945630524947556513,7677777836534314364],[13964512678520146398,3973544663388919938,186760477672923819,13825355360666167950]]},"fri_queries":[{"leaf_elements":[171455361455907237,15792281337675041711,11939218528188626092,10325005044092586593,10727790077663802681,7551405780770385589,11687209222983715081,14545689917327261975,3951945738312844408,3543662132200587231,17398436911096177903,8497150821964564753,3134669006912782915,582133955523847967,6831483668368960755,1389949814574353831],"proof":[[2702403480650669878,16939908881883877062,16717378601541703861,12299124121728640684],[14196185567129029243,855184594664060440,11652687647391914377,2593960174694613995],[11348194781526150942,522930566971734656,5998477171442986815,9395931063725009861],[10797664241126363497,12560825816663906322,2662558147492231920,16210690310044861406],[18031211856706335197,5311195909791687918,7122317853286294680,2185869760777285276],[13847749332107726698,12482411312537267569,2130757642672626114,6464205410967140445],[17488694750919956483,7040528083211459990,12232307585400791074,17925778977578926988],[17899745813737566176,13484774369621994431,2789813616727115552,4791901403030784624],[8721031800714956596,10057588120957680777,7945064323853080365,11615814072514157991],[3538171647770355808,15312495631820856211,1298379766011541883,8343143677892218702],[8667975401000545131,13865835481594892842,2249269202744355986,3382082750726749424],[5096448279421048255,8325895126152476418,18304088716996215693,12555893006213600162],[1817118849353387859,1591371013446557104,13687858345174582066,17746130342325168535],[6092347916727510682,5059372794859274149,8579337667193015840,4537769142471612467],[15998842700408272004,16140036983046065200,7408680032082393515,16326881239131036253]]},{"leaf_elements":[11204139861381761860,15501062135972878540,14140608394779069778,7010813586751636949,6262663708414219522,6785409703290594467,13388684616109054953,14146468279184018449,13632294540266780328,10819910390908552375,2634020259411856809,11306034701312937338,3649653319798786551,12917527322501157534,13068228372135230546,18076589114139408727],"proof":[[5889623489224337733,4039120338267986924,12815316825551360514,1245348153991511455],[14410433714338696255,7692986755670327683,1109283313980419943,13626183027596891529],[10159484918492685078,12702517378031096309,9287866267707641326,1511434357473765242],[16490773478570608175,622295333760889805,11986662312286052616,1583012028332174678],[17328688474827712469,916374601291993185,12079794005027870725,1892920241581726242],[13211742147571229564,15508315883886194274,5352267393399667615,5677038522116692554],[5557170379646279266,10411392776453596879,18103178280386018615,9014403917800465746],[8108154048716845993,17372634871278028253,3500529177410996148,9932996295491922404],[5348991498670835167,4216082389994285121,18341916044458565905,1819550603534758304],[5883550875012504202,11574299126755811541,15815812657893748266,8027697677235196187],[4354217781363813355,14607611923355119931,8110146052192118145,15828356775710447212],[6794995996057262805,13792243618903563842,10909130538480736396,14886680849939553311]]},{"leaf_elements":[14584417080033470610,16153698930170760229,5444247951822849545,17922389496667682417,17686701342476353605,8923284807771197505,9446328361050547094,14310081918332671538,15499577980851754298,10701392547840128379,15305208244135988593,5959913081366621922,15223680910198147472,7111321767123033561,4225698891728662734,8318818449204214389],"proof":[[17884762281315997221,13079733243904360026,11731852406116210415,8887326794623156490],[5189156802234603068,101792006261637536,17955968868054055042,11958854509969484373],[5214611857153110902,1135702812047233896,12751370948983530148,11263551915331288419],[4510079986240078027,12853236388917459613,7418950974395931474,15535813330599930681],[9941872558204393939,2160593201205205974,5018377885392261674,6081264559962484541],[8449696753217707758,13039892759673129010,8417940999018782710,11970172021375037886],[13719555257638219357,541727046414935681,17828340160700652818,8322198594370522943],[3960034083935288799,9671106614604515016,18080150179927275966,8182285695726902112],[11641811818129840643,9033655661638385978,5054579237060948022,1422767373936033471]]},{"leaf_elements":[18402561255697633530,3123190193400429530,6042854677793165709,3186496325548576732,11662036951497003692,10306484163209459101,2031981746298825881,10483919268511093558,15685649059936778866,14970296078362861648,3004523931364785091,7449198262131805835,15834592216105825051,14398766097606760989,77740404641756795,7260898877366032037],"proof":[[15294675277615002153,18439766221888057594,12760192117085325474,1027869274025393496],[13470229047584225846,5257704526251104003,10260782182593730351,1442416305343296088],[9805062406516187178,1103060514527521082,14805115566821996365,6953514296595020888],[7079475693179728360,5132339742554708033,8655585415989750732,15916123847493200846],[5347526123486097368,5487832405853602959,4935653453315848322,3533138337626681196],[7453354418341110603,14824132733225774960,16932858133388935648,1906057204418661506]]}]},{"witness_query":{"leaf_elements":[10396554479022288117,9589713157482476953,17266699819558941749,14234547948393857364,5368798990219454405,11275714377809325177,8159598125016419168,3969531995217885723,2853812323630758436,11325895416430999545,4009843059926119277,4173257794336049080,1435051660148748012,15396334589734857344,5568007150142310944,1272987178595146869,7485054886870832072,2087358954371513711,18421037716212303047,2795199123926858969,10419308605402421742,7809864295414874134,5136861717527621214,10892277496827019768,7498837703772236947,13994037621206094700,15937563913237238526,11445630882780674947,6329375857333800489,9571092776402631432,5655569562486863854,6150329253436426479,5175230333587813437,6655632439610256650,981849611900418636,294942164326017961,10961105626580137359,15803282121614955209,15202029649391506646,6037791393606207067,32019779775588203,6462343439081368571,17131750786062039788,946141013598145787,3928151711833839859,5253946222793235194,1763424480828452561,13308375976290294658,14318000039198098038,10276942252413161857,1910099880450673934,12574432520168138659,5279464102027217165,14544176901268252033,8051472989340218169,9970430990935912569,8940753191788675852,17452066665365328089,3904544958409086400,10419331741734136322,1775366898115153193,3943806578849729429,4114056982751233452,17769990166929811613,1289958570739656855,13176208808031103769,1784171769452617934,8681037806674164149,12841482894347195484,8463146311258811729,18440244768750878660,5540612789578367452,3686309328747978293,8789403355532627378,1374614476056089215,13326901396884682910,9153298569344124223,3409881266959314893,8714988060926636873,15890646982784583840,14604960103041173201,5894392164226982144,12572832128111167519,16804390188095520126,2664713672712793972,13839379728479075958,1454256459448106021,9886559033816281477,1452635410245008665,5147414609659316956,67719431339642806,15472463429879653009,18268686493639733297,16265902321195949144,7848032364288651507,4828568260911419649,107613299009005949,12704230901791681952,2300546081879852549,12265610354657032933,15119934255993041463,6334826975843441549,7641166980964826966,14977309125681356460,13016959209431901086,2064848276869996254,11771304259364398767,2829145498832458361,7889718984473808561,2646346596622499566,1291603945669527922,12551635267394553747,13647398245108500632,2693828768555152016,1329636330432399044,4526636458026737144,3756487168636629819,10873842817766928661,504031075754421993,6590014798800544710,11621545965989597620,17662038999113522515,16435354239629958203,15034845130111922940,4742169544023941091,9921678673670196340,7480162079121471111,15129821112099855753,4017859533152184465,918221912670340495],"proof":[[8036106213953208420,7357580003850811726,16493064839026330517,17217812112014615914],[6588401983244739873,6956136482923648165,4118586819067754626,15273006620532842048],[15829565245659127914,11358208484884127566,1647368832490966401,9218150152654503063],[9632416308685679119,16489821193858779715,12736049920475379890,8485414797325133805],[18184957594837150637,3170054887370536371,12824257964117339268,18369099648283124426],[13950513164047408602,2122061232287262939,7633049333490770880,5478041822256568560],[17430328918778485999,5833478408910877850,5459732776007928553,5648555453445708665],[16223070016976842583,12135577135540841092,4519946607876145072,11902344331911108999],[9063115769543770402,9096234461560061470,8480074277560455961,10233892807113794335],[1141264243816894016,12938166812512486297,16446712098502561281,894055854132399793],[12369343544314027323,3241207835676907335,11172594711662198010,16395864672970772220],[5951501521684926377,2888043530043650749,17856010929199678797,2501700789648958357],[8851916378140468399,2861959487209132280,15927196457782344362,3500729069793143799],[14942949293784510276,4683240531136701909,1274808005608621958,11257889774318390919],[3068203250224839294,14824693375947280807,5971505843347611238,1557304839090809484],[13332782806494387675,15602137019018449947,2031841375298228683,10976405011559988619],[12995499090774366648,14016455058023703220,2881375641441082480,16725664723406415789],[10124925005125015680,11122935805642487523,13455660655047775160,14103456364518762468]]},"stage_2_query":{"leaf_elements":[12901761566316989078,6917593061526105755,3103330424679807939,16119539972322132939,8517482977995439208,17244245741769573649,13898181042485364532,4966016353777844031,17225337965845700029,1903159229223695065,17105619861630252670,11183270779645789755,1882904723424985455,522455775868809929,2397126090393308269,8181065206578884045,12850124479201026456,15764480793814080565],"proof":[[12834830532621226229,9404289832754066766,7273203769390572350,11854309654014491617],[9397478975966180344,1649381679842790981,14882767245291811217,15031103657631702934],[15555706336092227684,5924176970430648271,16615227531561215825,3545131497278885663],[3576752752402260201,14925958145616619165,11796690724022725004,6918035958936191399],[12104276819727688712,13182637570256917738,14971872205010709948,7480904759012776697],[5550150702850714825,14811251446990612498,4331097252836515159,631427042073641397],[14516535752339508255,3962981941993336577,12276361423278429821,9096532436231810243],[6125100646663439797,500523766361502319,14954421647143401798,16902793400649288141],[3444370623742897961,14350326428150479197,17721880200233559054,12775161476833595463],[1667167022555461556,1869981011713332961,4995763666376453682,17554647932755032370],[11208711964646931665,8309702002453988251,12862929849476110103,13676443281920279863],[15812182787930807879,17055513752698081470,1407577292595124988,982829838616215648],[8063640558084968435,5914607631491290006,17186251885144219933,14459978972863140205],[6413828938068991338,15380232910103292765,15450838110260422971,10429563011607752987],[12782615170699768003,220292913860285492,11855409164525847925,11500062960731339581],[11612233238748477440,10449936868161924926,1547180629286057795,4364984447903588093],[7188918970133133532,2167557014627783556,6165659796439168916,10967734353770629438],[4898899064779566847,15318691255286174386,3409456466114033659,7396910881001794806]]},"quotient_query":{"leaf_elements":[13218551082611811795,3499534924854360098,3583834459495023025,16532717960317242738,5102443800170039684,7944014122141118210,16593081385276360191,17237708390418201587,11758522238792720561,413225721776294978,11727705646702136333,2172012733962135396,13588251057397498295,1615115689681595074,5727048327511951406,10483940190601221326],"proof":[[2218494712428031706,9933104920209910189,16373164046317811280,12316405712252470311],[17537389326270083340,12241845482756533948,14117207331744232856,14121098278983631805],[4098255871349899074,14990408130328475150,11802960953479924152,7860129555290525146],[10604548655139696691,12280475966126449648,2792398402102047252,11254272683513045855],[13392458893020056017,800891290775214403,14679633905745294360,3705012639105542041],[7012765980134250884,5584962045246033921,16979477491259275113,12290870220284801072],[7938664791076995075,8564949873316000230,8047356678320382281,9730484104744624551],[15066570804394363882,357688979436968787,9315654699377037903,15359752490021294580],[14613754535572990386,18299842496136425677,5391332185996314995,18202338083445074257],[3993922979229110156,6576966014585160631,12586307283104400783,6323191931060815189],[2575618490354117462,17936432983246218206,15649694491636845211,8306361590777077351],[9565068301715952109,8114019432233751783,6067217873826329510,16657181897840331150],[11804280911574331159,5490859478910565430,4141636183227319343,4901810484533342558],[5713900313173328421,14902795354384178778,13603963420310252203,12578181906953406729],[18126594381627953955,10436841020589340257,13972018463134667731,12845501995780509001],[10375017986306125185,3440515941780511376,9413600796355355777,361051453369021485],[11059209759738362919,10355253662709028589,4835313493373174340,11282406209898157601],[16399043668560858007,8250714820413585852,12227481143822277886,5353859692419650920]]},"setup_query":{"leaf_elements":[10961639019399963488,6975022547049124008,5716945654824553362,14835809331217931478,907066707547471904,13420763875031341300,3771119526849921454,17172413432371455881,14539949539079017047,11198234918937777271,16782257391797754754,5305900629511777750,18337017363213261934,17171702712544704552,8415226157681309489,3477395411988525765,1620487249465332182,4348099002385209851,17256867859007691332,17307358853595644238,15911065634712507936,14794890604757200080,3331234576259512994,646347332246117759,14558148313688196713,18221587171373891304,14135647028068897548,13098805359207504370,5999677162496933967,2133304178866392783,10471880679462710376,15744168317667498915,4398495381000868794,3629517014998041107,9232213170004779688,615202840104729837,14726278673093761020,10332393247273288757,6156720239646995406,14892190771922893469,1917671628048610699,3921961313574827262,9576437145918153415,18042055865301588412,10850184838434267698,3764238534271258018,16055943708846545341,5255316438060127008,5976508209528899034,3579022800535661997,5407504336513295263,3523147441503283818,17707153559193330206,16150954043018825791,5078470286250147533,14141637263999546237,18065375251582830648,15035361484207075099,551268092842398698,8308624989307832136,7264842668334577954,5662129952660568750,8274099449362436981,15814441360306419367,1682316782646521910,8544303290317680464,17853397765153988892,15621550355596981002,15831090143506142902,9051809932979061549,16356190976606123168,9381828316962457549,7733521896342432212,4102694123442647830,13127148453721650255,3423527794491637094],"proof":[[5243577435097590216,4032379746377312345,8789286933010505302,1761946426495801927],[803341463129283727,10077583085374350499,5512188405552689589,6531247990902618887],[13948971883495492070,8772345211629182884,18097067371359021181,3261582828783003175],[10197684192909297357,1300435596616028573,15690742765500526513,11078361718783771766],[9764395209962821593,16272079676633027597,11971772797164247289,12188015709768643437],[11850062408187083980,10979760976503685850,1701891100244130288,12761728259351201054],[6621558115945305336,12304780659737340105,18022710174646679289,14673723055977453093],[8287377368301831023,7679332266640983642,17555819698755748449,9814410650995570826],[11556441640902123819,7467266544725816630,331826532535327641,17152456502124149831],[12104436318891096945,5441999773256074996,11848206748956762447,9240934606751603681],[16366525068549035709,17024334556520635707,4922906946206253479,11224419896315718534],[1613614277365334735,11978732918779913047,3896974168394880757,11751838931660419105],[1104680759417059754,15174334361792240891,17605403536671522308,6472126157544343357],[3683477019702328320,10705666636060659453,16545453780919992566,3450620043039154989],[6656517949148815452,3355918125423549953,15365193591051581326,9845823833744868835],[2490183894175459549,18006267448997371923,1828293048388680509,5460807593921920998],[16687486600624494865,5185374507715611913,16997796223029014057,17311254140899066724],[7233177384642440760,8702758636784930292,2442646867126237243,18207673233785727800]]},"fri_queries":[{"leaf_elements":[5299796651925284138,1014935792594172783,15552646407379839846,9464810190970152266,13861271094930049447,11535218647733155005,2786734100138715249,16104202870335918127,1520901684856370721,15204081069357935294,11673517815357113141,13934240285911195107,13425721594855006970,15106092048245017835,5247227347560611905,14475684020630977508],"proof":[[1713928537488852048,6676769566690963944,7678070052303500250,5530618509468412455],[14700105749867080841,2793520372074425683,6347066346668123691,15877244700041321147],[2179941380751009965,7747794108864592140,11546734454104833003,7213119449631617833],[12288704857241584345,7818058263699840579,14026867860918841999,6747761586084562825],[3210420901210220473,4356583727158804436,16702358148024370453,18285444235749056747],[5135989522884621896,6500434799238671110,13767340827184581057,14100279249964119307],[7792937483303394957,7789429926720397595,15201151787228842607,16275200451544885558],[1010662970018945105,9896673216380819689,7558916772642044785,1559104746439736197],[11405730199096144969,15208053091268081299,8781118716996197578,10517714680253088834],[10035894224466951815,15827274184136474899,14425100152519452691,18002585388020399997],[15433328004408047667,1957848861245422539,13197174211169299031,1430057487661662825],[1839754434674092556,12190111705454978763,15767956695639391129,13257780858857754941],[4346719920529719564,8231631092013636274,6901919960761593091,5918908614655647493],[17258018552004497248,8650928477807174768,9642157280207138346,17160470489212579670],[11768530266419203548,6938183619437297035,7384281187276928772,4695625769018474281]]},{"leaf_elements":[16462610817397579238,15875931066289300581,11295449795540065689,8140604951727921214,16959717012144988485,9754568777692451373,6344308017977592645,5997372919948682461,13396477919704078856,4280751984951767925,15654994330154101488,9070234283014404973,8737702017641637084,15243676640576474870,13670901576083176529,14094523141332750600],"proof":[[8742150854061323076,11538287460076657103,1736866544624692514,17921303864171772743],[12565272801873371506,16093658509150203421,32910020278729854,3352718863462441],[3332556294333647875,18315854881758576587,259150708826913810,17212483849456215952],[2956459741346332497,12853742496651918048,14168662620207386737,8835503386430479785],[11199413117372237244,18111821962289067354,438567650430122737,8902988572615475270],[4484161172874312805,17840289368540484353,527510043901953078,1504685049571477194],[13945326936720190386,11419387938631256037,14610385376168500119,12703078446605315659],[9828021061902667122,15830438273729442188,7251469543405822355,8216306277385727984],[4284364077951953076,17172487122502008250,15852524665048807466,4136803718686509044],[5378582693725365534,6309899256331398147,5515744345927170718,18204857614941134233],[15320395827934743051,6595944853499492541,234464085033623289,15704499509070949686],[8368337798740396307,7167741164786226558,9294856539680846148,5674787406686266608]]},{"leaf_elements":[5212233689509195402,4810708409371700337,9706761811169454833,6949649417655872671,7234605476317904984,14432700860025507136,4324014161886499316,15934630921244959128,6362964580385248307,15447104168656714748,8095251051021276421,14826547348003486789,8224446605766846014,11158162593769908791,17151716587518936457,308474137507922561],"proof":[[11880065368356894506,2121135892163763059,15190219322415527567,1042701093155547047],[5836496960770049539,4422848621158195459,3061121488358586887,18345964619114005309],[75371862808453528,11086671171441774460,7126301929375048350,14607244371475846772],[15753314554241717099,18281285338033360369,10443220590933543957,4310157980584544183],[10312853055362212810,12426423832509901703,6379709235960137506,15546646651941992340],[17764390904151115171,4081880067830243516,7711932630204842117,175780812187383147],[13373884085157562649,1446573272219481642,3612214074416382185,10911546190281032796],[897421617835003524,5288965680480873386,13467945254661006861,16731079312358120696],[16952947719119987566,14591144256981681036,962631639710674582,6678872756952341893]]},{"leaf_elements":[15666292606107090618,5881397549384258399,1423384831108537984,6581134961972360225,15613643203674643233,167846947789902134,16323550390365030557,3582274091554364583,3026064783096308806,57640555585464297,603259864280864911,11649673447914437145,12426300855544416667,3845416284199544126,9761780300038868358,418040698027533360],"proof":[[17794974008438970128,17353475986528573203,17950735649439039408,3836655537203644043],[13475050792888193812,2572308673150108459,18329921452301073675,8295717887417394121],[11757914679415963932,1128135298120361679,7563109487320265757,3212130378704176857],[71152666814476814,12894023519236526337,4574041009793962585,9788893866570468308],[8542476237606591922,11555495637902370121,2764086153383420717,843924793128411452],[12679918622514369144,10547403892597610820,14940856916106438555,2589841497450645719]]}]},{"witness_query":{"leaf_elements":[6206234378471805732,15433801781663783295,16888897317043921805,18138913256821720193,11401155446091725524,7181358292850848449,15753669872225246125,10362445983649938213,13231598700911263589,4502033351336003437,1611078664426785290,10694407532792372454,9129683210095279108,8760810584598221745,11796949656798288151,17469274846455186067,17416711954122682784,15062534522875734597,17802720732602338219,880518995932803210,8907274927611298373,3935816613096708916,17482876826837189037,11158908919028205406,3735350602237572171,8258572173862209028,13002515525129526363,18111145035894738791,7413966421548098197,6185891180220360150,11098309718588643034,8027194391043435949,169267889766378182,14597361262853052238,1129604530081160997,15323499366166771462,14207311761948595757,17391604377532317902,5025925554005310474,14561112368456951634,9280144429943544542,15344178134291238767,6613205986113152697,5439927533109176940,4126705845445801561,13229045312095802014,2290310530770026742,3484302367454982670,10902355771045058136,18227013645277440691,2829694169843509625,12576777897176262475,16106267875650061920,1899617534452718329,9874579431585864612,16333145438312190159,18254466930735090461,7682330099021049159,12539583501955642492,12696243189155606410,9193156579066408715,16696230373475305277,12046395696736713892,5082788570451334826,8357255853216038331,7662308205224828905,2565017804769653720,7737872188292640622,14692152112337876526,11445869071414332839,10669798594462104426,8537952450761798023,11441116853003217906,12074083370056353956,14059307867876425876,10625759271176749192,2806796246036094555,9836842678659782243,530281127168848236,10142851832357210888,16333550923216519438,16535075158965796,1867032079530940467,10058225920430118903,5715960285748266865,5153474240408279210,13981766767596063699,6990571557220394953,7434725906467484045,3285293787371229805,601140447637375431,16590511337004242233,14179648953765969801,13049036298802774396,12162509636824142274,11535843693696065283,10150421838980900925,8275781740583340212,10629791850347168865,4276627955175495107,15621876339894625797,13073054393591629478,4442882758410775293,6121255324368726932,16373441096352023061,3774759819615195881,3378394478941773851,5324964884543898066,8902390177484440944,16095080815318388472,18390954295785013285,16361158621399108724,17611675080224785484,6069760552398611018,12293822219882275762,12208040872631095689,1636885073337337509,16491541985730008218,10317549453774074781,9789438510018197976,5893625541101570094,17240048899934379587,6286618621070906781,4850284561477785471,13661125150499186214,15586552883295418909,13498536988887646515,4527636059755455999,5161718081698147105,2913225214172848494],"proof":[[16117219004969319980,13855531608760710611,17655352292895039939,569859720273487171],[17891841596866018370,5715660856016670361,172086113823853930,4059903306256484514],[5586990450214032049,14071192475513909376,11653964715630310888,8084494532849513676],[4570706511715559697,11760189519487557258,745818840140165830,9479473472670523015],[16652307008989948412,4946739141523066460,17995636174594854315,6455802793329848753],[14147323111427778504,8893803044577424470,8598509225525864074,10552060915323071631],[18348240613025750947,16587210526886654046,14273032288187117598,11261161047216711216],[10173831886520933473,15177551177904775568,17113813219273392550,15875775534629144387],[6950076238506040292,4915567213720438008,2171064851378597184,4851814885335358196],[1696255352132440372,4217491055353952329,15633099143007571227,4921193507892563252],[4937310034568513284,2029873804404151407,15563555131585309450,17852687066039887629],[3172895014371058123,1907713362784649885,5494016891548984407,15733315515228548368],[9748950684503469244,17247846094569216806,5325045719108470797,16556437054042563579],[16952327501142572174,13418183665268204473,17048629774702092501,13951140440961776178],[8068322890024605336,11438406130778967442,1829197596050645930,10508824440247626042],[4598827232552504278,18300460416190793862,8655333824469437202,16624106833247352973],[7118832770553629286,5640161716204296916,6364840825189593002,13922682755946615069],[16268086523709051900,14988041527450775806,16248933219287021442,15731140141516467751]]},"stage_2_query":{"leaf_elements":[14960899832858990272,9157573973181278569,13721393834349281130,13448143797710260917,10976158066099618481,3177703860831901421,6406039523878072396,9550372582474024687,14243081346784764014,7333299813045665481,12834829960437164933,4422720760176254259,5251794158617506418,13062783484289063881,17358278759725132397,2687846353667149612,7846918519264360502,6823398671812427443],"proof":[[3370203754357161059,13348601344384081589,15386097410494946088,2894002651150741736],[12841416400521769922,4057871597216676876,1812001812600347775,14504397939819987935],[14907416409357595263,11452442214426051358,3554780377577440318,11745655003227381631],[9472176905632063935,6921263329222775070,2181015271025505685,7867717711203537324],[5574033523231134187,6543245714276568685,16633651213639022358,7710799190309044939],[136124189419185227,13138513029725175805,4998573334392203088,13043917608270617375],[9413774164276944889,7057318317077410376,13223452473904662189,3749938712896051773],[1644771322284571817,8547409097912646671,1579436528199615153,14531785640510973279],[10530014067887031696,1417732969506395155,13628069901380327361,10446701557601380463],[14949190418805529429,8933276765844272361,17856856051286934233,12708489736616882400],[11143544562939468817,5782030562361718283,10458212967795643327,4479687958007414524],[5948546033733149804,9965677192638812099,17811582757720292669,18428165802679661226],[13254492833714890709,15285025788248031119,159097692071003464,5298247818045293947],[15486113260548138369,14004440484638506519,6953273848419023248,7988275006377427980],[8220280443437280683,10601312055488256985,15294011452883220755,11757268704692756721],[18235437134917560032,3497780223205512189,689106479686557743,17396557446755504258],[495252962370835777,8088216664097321334,12158413295856942907,11750534238822813997],[15980840883917575426,10526314133402964098,85400734784810231,7125417555254487406]]},"quotient_query":{"leaf_elements":[4609449190727908652,3651009448590109303,14628061699710209062,17000448753325905251,4286305284416218864,12194361134740541276,10170175934189832093,3985481288637056793,14266746591457819479,15411409742880764710,15022753123620218132,7312696297364118723,7797291365850551724,6269378103943104430,4220515670334330734,17833442824719065484],"proof":[[17676426007363749076,8654707424469501026,7370245720742215963,11131213980712761582],[9564245398709737354,7805486089754034787,12682775635167996104,3409160629763303546],[5264190098260231047,6703307588168964761,7259873273338988957,7425296859044471928],[7094252248506935617,14459482802709687435,5385500358804534542,13957672625475309985],[4206445112768628544,17060240792749063141,7942780005835987318,4878107298932332394],[18110483923295712958,6466615959208113533,10734932915751764171,5865807491878701186],[6998404555539353345,1892480347905845858,11017729337399806078,5987928638886177991],[2912277355023994616,15778673046354374660,1858232628027843934,13768856422664603151],[17740194948185194646,15406826720712421970,16748035081641279880,17278302152755757356],[2955166447693767120,3441693457960367503,4260511247418516214,16807584250358084386],[7095903040193357367,7630175890809587380,15315580838526623074,8551096047623578212],[12709723967100800448,7638631425558809717,14386635528909894666,15556678849256953276],[16674077437938837115,13143486227470633478,93388850097432410,5122477728210708017],[8361162933497966294,5782659015641115072,7886500096570456902,9703923695081551795],[14866762839132624009,6934100783241438020,5319364892268370872,12856790632839684631],[3508077886644395912,3640944023496253428,18108136108956448007,9858002116463077571],[453442081571323694,1388509008213955195,12818018025376087044,3275203387654303195],[15377347274707290709,1130227866230159522,14040377008962221224,17632194773399975558]]},"setup_query":{"leaf_elements":[9765681910338976010,8166194830973733314,14807077914960873151,5985816788314583604,514991485055970786,12104565654850301562,6722049628228161008,1522572263487543375,5981139741688783554,8796350655696209150,5990209400061378670,12710271346483411958,13936896387892606069,11007257640156441270,13366827075842603920,1007711336739709726,13687740977314568922,4119880586273878540,1644510182922797791,9570499619247011006,10161913301600447759,5938926297254149421,8209124253954973145,10629647556548665968,5618687835083047831,5890205489874343952,1417456574505343204,3228031058633219692,8820210907095222472,17459746918557007624,15435386684756217649,16739770289499226359,18188584043198300386,1882536493037015968,1866797309758922015,12383233736973555821,9573016818156372057,8082787431526342028,7124638829854093412,16684107980830045477,16608226610500871671,15754027693761908809,5897688862632981241,8892181947530598351,1854822488809628950,15661770319713215245,3990148224012339183,418791918145979481,3052461424030882209,15138983337466260612,13051152719968351121,13720315744334724742,7921070970273792671,11430195628402714992,18001708631624002006,7181952156340520633,15919209278882438591,14002814160215673530,3507922886145568864,18428329524658747351,14503383833987874072,10152620223953545266,7761611354219544627,994588192500090122,11329562170398105795,8827617868520170642,2836458072182714466,2020604864938917834,17509030964272402197,4707030861440417944,2028237428503894226,6735857781516324694,10884292937807352565,17775822245175848620,7136433732504658479,12902403603923287859],"proof":[[4890878910724674421,13131380450101908139,12843152657331345120,11487109798504243000],[10542892590344220459,11818713112706227551,2124455117128197609,3008849258476447859],[2268377932445161338,13190505748622513194,7467577022847042574,14716884404439984402],[1396614426443624676,3501561308918876952,16313229427108853435,9188323797501343719],[16837493636160666933,7024215730668654920,10515470766594781168,11075522299874602436],[11153349668665823162,3474585762568960576,9312248774293755134,793334804659911092],[3043074496917235847,16861769806403670735,16680602005859253051,13684435018953636907],[8664609688899108806,7062927738091791120,5456073921522632171,13137807024427821228],[2563765813344744037,14959767756758904862,7734593970453851855,8808409549826281754],[4690825040725334133,11517189018215878498,11544459400592552548,15367472716544222101],[10097537463470120737,18263240760557628375,13567092760290756727,1033161421457195513],[9089142569897555342,10101294717817867689,3465536114562197779,6706721817930085044],[707991514570529040,10474083356570636454,7301604672473744324,3577709675764276386],[18190228289891452758,4759103263527098508,4205332343789053713,5482857681488161998],[17943158731010462814,1598146793323457592,12540508904754189766,8400182013178008913],[17368029736338379470,3818141302415494797,11239802788312865736,8204200308861329030],[14858841901480047288,4984330715889141062,14222585853337180613,11094469037517813143],[7897047629797490527,4498172521387933671,10174337977549945703,12955271064836760817]]},"fri_queries":[{"leaf_elements":[16762816245935052420,14637760852069504067,16699553597088501853,11140422813496953319,3051093122920423898,18324934565973535997,7853024367640332667,7612490111756995286,12255662864663643289,2813302244490749122,7685577804451896258,1857665281003685224,14135005310668912843,8566459709089703600,12161945568802561893,919109124356964285],"proof":[[10163188776841987282,11938592391030823795,797962729599232613,17162043127984028288],[4497226321713755777,5129285037083629000,12272545652137189222,12448570482568708698],[8967889793023736637,8867133222971193153,11078188334617717371,14932699171343390058],[8053279020965394568,5096461857282880046,11743637398541479036,16550340520292711538],[547053423606788780,14742884865111511393,10151603453445872177,12977915955159064822],[14136064685642249442,11177677579347992516,3570530793334944129,18333652341021460003],[1906783954073833785,2204496791565788320,18301619254753695715,15744606414768572929],[1773791972288763256,10947863133621868678,7376918110097453443,15041434404430644808],[4550827648055870967,16387334476854812726,16422384561485436171,8647763733356826545],[14906721855280207969,8365933185192173256,15392198067823127018,10568886482782790136],[12201142909990201722,14664660240225252980,10262042076613486303,13587119919510135184],[14125031773548769841,5955531352920569042,1073109376276924144,9640482637040090153],[10863923315661930738,13465369546200675084,16513672506897072297,7834927513578321770],[8166841103185804752,14249155014731241291,496207802782211468,13934760340660616263],[15187539760476402746,7957300121418205660,11135115954439583374,8745301280390937242]]},{"leaf_elements":[14561928080602687424,16403212965225634750,127153658593591063,17629949598844944095,6479972942191277070,17587942930676048367,10201549842658587689,15381454997045211132,2503011514069550966,14157851079138621099,9877790094966905473,5066112120080359564,3821266107758485887,6895466204853183535,1296756971817785234,8375990278619907731],"proof":[[13975178885535436279,13177627496008401588,16505251348641966377,13110348060199860207],[17502808356214362633,7177003798273914638,2613451125669066172,11926758009828169023],[17978519258542900830,2251074211953330377,16782392270184594943,13205829214444414307],[9936310693798029016,2088152070376248294,8565806788208638041,10684248282426037939],[15759302541189223093,17135826497876295192,1639974565028927743,5110654138200287006],[16075068656878309161,17861032396624254782,4336918334619004883,12848826650720048815],[8591908166990511658,7733436813520085567,14606017919625012159,10248710935056456389],[6071036590368446060,7311302301269357672,17289245497281676462,1239076150266793717],[3339686534806023490,10137736233931399281,8238198392757053286,14894137371100378754],[2539913146248323519,9097804544773601144,6725750596322874345,18073226430205197400],[8559046796634960210,8467821704429424932,7363853845100584428,12473354613826396444],[7888167809845526590,7606917115924155387,8594512517807828747,5763452085129076314]]},{"leaf_elements":[1329386706310798033,18035195609436780533,7306441514519662990,6470288612755149184,14015799501076769481,2483791884912720620,3151483221769562773,3998381573324249357,10582501627965576896,950407354683642734,4756036390284179568,6786479957524506591,15241863083520372677,14285864421738751968,6364476449572516073,16604585788269136861],"proof":[[10217007923154116504,9502911177532913987,4770422875045349604,1595532179956934302],[12304179784434342908,10586932208266401878,15929177458292096029,10548596214653341096],[17161174518245461505,9503291711054408503,14550577320704081140,1370727858898733207],[4731906798899719136,1604745064784061046,2839772003211637534,14807314747715621773],[13218688220079243682,697800059715709525,7350133179278394244,12833590556714526713],[2238380000743458950,2729154195492267510,4546719781280613123,6583333934205501380],[16756326422274108880,6074355258565927953,16874283722628566429,4685959916179101858],[17596302832835382444,8021547176614663957,9876684146787529186,3104154432583930006],[17981065144928463011,7101609389141760645,9162104586171921059,9947706710159871540]]},{"leaf_elements":[6320906021088730571,8389457943231080351,5404706190353158490,6023782195378241363,14212902475417980300,7263571535749949966,4300553647813224469,13323644572923822223,16738607371925473830,3079744217165161941,16096407263490613660,15976655223496887089,2081607034496890087,13325470289659796180,15224710739695236924,14605206857001130922],"proof":[[1859599412384861550,15758315355998777390,16245829911570759469,10135462364549667324],[8218501014511024741,11926175358062324299,14505957733217504775,12916395732007227656],[14217618695993711574,8088348684349914514,1919408270760029895,12839877589879801280],[11903444633619112777,4931611145665014825,7649651876253428122,18393257468904092621],[12968940854106168517,14337304090312876376,12121515736862482239,10675513575988725926],[6301648820502627997,6595754601443884870,15706819966584523141,1901012347648786389]]}]},{"witness_query":{"leaf_elements":[12156219740527390090,14292493080162162950,15696031888092375235,10349979815813292807,8234541016641479173,8015028344167632391,13319046883586188821,6078401700358663490,10973755586099041879,6427886169631132766,3453105774825252380,12433753823122121526,16471020055159412394,6300135402381460079,6545140229810638657,2329052354946504284,16217245469762413011,15528291926857527535,9398969296839388601,14041561035623561382,1453108927611802038,15660828756628516441,18360393449625398167,16817717246549900498,13247366036655843504,7689828448803819444,12152022050332282319,3539287675077814646,3602913691851244993,15393876347179772293,2986851583637922225,6791066148616439422,13158136154665173888,8639290180009878894,6755133878352164702,16972793280334634134,16490202995629824309,12540062195580355079,7081025977437929594,15161443970872493483,12251107576553983542,5464752947314718951,15195924745309472503,2377426739951218971,17458444884536522651,17295109061862543053,8930514645056255210,2888574041495710853,3074152248240131511,14297358758371899323,15068946290442418297,17546344296981476940,740777627500754351,9263377772655801593,487010077142614268,1010897603829589982,15482984696979979079,868020281778544536,6707439975691108447,14870323409903883660,3889933093496899332,4913797343998667306,9139616081199680766,11598229972986833970,15979886834614949343,9504620036702726390,11089384191008276956,227153457386340343,14474771179761445493,10255209594600592158,14890110366454009644,10997882784292266768,12223195060360243822,12157816446327139895,6673092919288018981,16175306107229592905,15905785159281183790,17418648214679774485,4791262228893728965,3996373616355812958,600885279734370018,18303324284142099959,9334469026650142847,17409170682060687625,14788741391769393102,4642781628219490649,3063581227184360013,11266634918272176785,17862810289539229873,12151922199609921848,9301202377016918040,1435749917228804473,10763324194921396603,9235335044816639172,11834429709617791897,10669951543553868471,5809662588966075286,9964911986560962274,9054183645658140814,14687910780504377239,2132731427067716764,8539806564770879403,6230191047457076757,2533704138027340026,7243255125306094519,11476335235637667037,13614265205282810296,16513114851823662550,5644716253521507639,17955684866877253984,17136985116361151289,18413201375796271011,11096252618504342848,14044759148701997759,8047088312898599870,57549210894142820,3071819359531273894,78039331348820999,9230622772185819054,2612669368018532973,3450107198003526358,3960698611255060763,16381553165195097342,11244339183857882606,12336463291332155307,18252998550445308760,5406621027803439177,5951297965751468415,15682327038725345817,7539301025987076512],"proof":[[5519812547061731412,3526805692485178679,15475595978817393204,15991859583080705543],[478029813859789142,9997882490918384567,5473611345262551196,4345284212152361297],[4157811517412143984,15910152924591515585,5902069047934481305,1518848171317903344],[14329336863793175367,16958690667238872493,17025906049624934851,18204259350007177874],[5917254480344323009,12685043547586387664,3927430186705029033,5645767705574526605],[12881705279298737969,8417862627950890353,13148006623245969056,1166221947827011821],[3600999470147946625,4301808376841530494,1222393482804503255,2878644291739482555],[7946575834410130452,10054145876564068383,4710492216597143996,13492095575624126557],[7208053946278322918,16654079909837416088,13260561654589018950,5914885462140537904],[10760894134901455873,15086273453695321861,18036938258059971562,8818378857069223439],[10212783539182416396,4354670665493075314,15543092135146433283,15959895760761627282],[6737400241090125299,9681013048920237026,11792192973603809855,13234630124891516142],[10153586295799538359,8518873241920368276,17614026823520296811,16737227107928888367],[13857447686632135178,8246725314554680619,4056028515279277421,14498189104015069741],[4697447871530407751,10482067277952155504,12348751360735070571,2058379697102550756],[1037272205341422870,8148648928482866394,15731940336288409146,14840245787390119653],[5292630935056036516,7057262959808174041,11885039295914258570,5642311501362689236],[5383852389528933874,7336933548097249520,2977352851054193478,1823395369702592296]]},"stage_2_query":{"leaf_elements":[7387395124875572160,13768152735167253171,1572180395377643263,3855430475624956561,5323407863118337854,17182109842774499602,5253303870777190682,15841005673999025924,7641572181076546534,10577396199886405619,13772725891378895946,10036323241522025271,288261867905545470,7593532110425650326,11414144627248534179,12439843653518203072,18403068100881438476,9765248620205226210],"proof":[[3008980123376586944,16240542681484000391,525850603587473871,14379865250641326350],[15212793556368047868,14645141409464108922,15482940151495579791,13948996234460248787],[4681608868313962005,4798925707928201279,9136624734776190596,6976254376072421884],[2495785291555538090,12516659279126223510,11983959625747125492,13052415644052393079],[5830175780523285343,9249455847543432484,15686573518232333053,10889355861522380426],[2944948352425720019,327115002908315264,12515429036115929458,12672842826522056639],[13611222694732460430,6488397083440556451,11540779249506621123,17272503139138103403],[3267578853633664282,7831525405749277285,13117581391592133672,5372187847042340052],[16169683367253336835,5556965202308186023,3187321440336797372,8773267889832222880],[14855301004991910527,1848078738287671098,11469271900678205743,16437231317278374533],[5039040661223008437,11934689115838060604,14323387951832466238,3045498653277006106],[17556104673189771299,9998894461001489836,34105510906218657,14791838882917598996],[5409935393127042910,6618074939329055592,13030106559958957703,488057677561083206],[7533209435492205913,15153551860020247413,3237076377533568370,6751848776256191914],[15816758424573635042,8653688549176993777,8500942458133867469,9569334271438114251],[2229712252043765452,10735452825580538097,7123506184274151001,651702053081473409],[2384716746081912787,10110315804184294219,8871921430362313932,5095402456500696573],[2915563122395417828,9832480337282349187,17313050442977431322,10721060620698443911]]},"quotient_query":{"leaf_elements":[679300570061611794,5543526293155517825,11352039547715788788,1075602022561775786,497622441024502449,9758800932649119966,10759163181075738301,9024396749043061815,878113809877835105,4397399748436790522,10793858694375302070,7530904385892824369,13496306031015229932,14680118939508289500,14537259049754854605,11605668914559216116],"proof":[[9169451133160794394,249272043254983625,6688140539616085991,1717780508908583779],[7547905313187296986,15295333809689066724,6884055585794576957,1942544328115026766],[10698538323689723071,15545239071141330741,11842183383061618585,5582745267370036794],[5086652726510006392,8774474069910092527,12212201462316667537,3648822264351486856],[9045453518959507893,13222846519216666884,15568047090750691464,16396227194528338265],[8972278954574495901,6434265953662605956,6225280618844825324,6616271001042707273],[10420795177024162744,13664847630708025049,2748870260778009161,1247032745936872144],[4341416305183199030,3511006945892306321,6426513266173091587,15013347020329480060],[2258411558349429614,17025466282151915739,5985172816160199624,13047460814459380947],[15793511267272432898,16805678635851880144,13444274115957073375,2304430637085672898],[5388574882117111408,14181164910418652506,11217350178823635994,11413706635140666143],[18419375734642082221,6717280100751441279,8039637466940601279,16419535787038872385],[17653828759484354011,14029232424213469108,2145824856810062900,8817213399964133908],[16437420289250640920,6805554466885008254,9154939752888224467,18308121918174593926],[3946454590847606283,2493303273523843591,17180724140542931073,14984644637824487560],[14730815067367347663,8501818032011648560,14479918824679725232,1494798844341062018],[3982281265809990760,15764310989584131523,493536431500004445,17597874209937435280],[14158926044515602916,9503451543914547636,16932346425984841710,10261144329593810720]]},"setup_query":{"leaf_elements":[15629654079398929243,9187293263281106678,15693407072357813639,13008156415941521412,14555757412133524942,14630699769626965761,9441137691366636479,13143955241853626658,10205237919020009085,7159080941769117624,8906718727468047881,13757681995068891955,4233466521045387642,2849757256490482279,666170911781264380,16637662616961575400,14943715325493459541,16003198754073165953,11348042986428240856,3482282243888613632,3293927988859014979,4037859359184859742,18150625156489258767,1438562562729681154,7147826275618271078,8003303494812977229,13250615904723727850,11351509312835925614,2700127232405086135,1901428979779906700,14874009645780540575,13263202941332919870,17001128706663598084,398899464042831844,15023523439568356446,3792644375919958672,6249919168561863749,17600506886221140489,1786724428201942916,1641447123234421577,9605839446173097174,5912761202195951195,14690131157095977494,12441211541988986143,18042906057517190842,16181692799813756836,14475898648089167476,12401326940405676953,14545726590853214715,17405161965143171003,9023830584357345479,8745686151429132748,7372151687665679526,13693067600797985103,13759247846625396240,10405587792657356658,10918681019695428967,6610339750665571405,8328000421127982130,8763831461783145187,10821652887485313499,593455500794277465,9750061402019547561,15136201836100418090,7230567491365136746,2182232128619729245,16944287810348076853,10041402093019215375,3805894488771583397,9404938592470347389,15754109172297308825,7786742653174111788,4785935387056769553,14926295334023038381,10688341657203429087,2141297176509945813],"proof":[[11897082284175341686,9946741561288868155,13887767586602648342,244669593402063196],[3270903973155937675,425409343510834047,10557295640751466280,16668241390420313652],[10175077671472058170,5921036115664836451,6523129705819297708,9354704158845879759],[14015124825395531722,8212155162078418705,10220351535936600515,4925498564113497901],[5022076929417114227,4649811921079964351,4722193864567322357,14758941306325101018],[2440421807474532284,16737388949965344657,12909605659127722060,16370128245002069975],[9906052253297164339,474495420995464625,4856241416949517876,15164282163389031202],[17125772087823883810,9502237717938534561,10586247967097238632,18191004841635664216],[17140596675974087209,14752682810501388749,12341658465756722680,4996442396570429213],[11775937216193838193,6662930398303159823,2048617804951724378,16325544615568534258],[8578761973644604246,3669533383911183995,4358804492476070512,2081999166844960107],[10726952366005378137,80788211344332797,2451752104613342695,8075647303350987496],[6967388433997095667,177525245400443360,17291021667316083463,9445819014049269898],[3925683349647431428,5760088177117427750,4489643835922903822,11774158739597179450],[4134288624965558654,14640481604726773930,5923891161051250851,12215558036775638535],[3613955094445706103,16894559804600718188,6351894750829214423,3248940645743349346],[15813073083681539142,1919749836305862311,14725910180112943539,7162950403381646548],[2666128136895300911,10094025976117415706,613548520225083731,15812128138221447878]]},"fri_queries":[{"leaf_elements":[10392225141612389007,13033353924787646275,7198741472073027031,13311439228505811965,18306047505752363667,5536881062970191590,15899884785122738028,10363831756428121409,2736898504166364574,6487982821985526423,10563688494532914142,6552758482153160549,8033977234753821011,274618428200946025,17651164186113926732,9110419085838381349],"proof":[[9611037317288026792,567458909468128800,2813145181017292322,10205941668323154915],[6170490577786477643,3227957396687029765,9568470946423686470,13388498281237322193],[6842281701765486476,7998510803003452001,12841622411065728491,4475036103953713850],[7580730836560449793,11259633052450251417,12497942632529653912,16993896237259449095],[13400107304149373767,14598268521484976714,7264079343183958133,5095264514784065703],[14390826577433214795,16272535700876188466,2130262400562364503,13998884718927561424],[11293638196251176875,10213745338946867926,385786686992568164,18283992570489345960],[5271603806748234792,2673137949022079044,6315230956951099470,13807912116369199260],[3556289031922993023,10851565580762438644,8108481594406610992,15598466145483742931],[9239640547984089553,9472540157890467481,6080160467043880449,6342551098067013879],[15599297691246462667,12546705695136039169,2933425076554887103,985513631115697511],[12557369339451961598,16424242178215166944,14854950857853949087,18443727789731302451],[15582559471939128142,14198381767522853803,16058262810680066228,14933116444040693666],[4120143778835238945,14587847913270285339,16480940402746778887,11500913341756582581],[18243610942061872488,5977556241233368391,2381932756674597376,13278303353469871128]]},{"leaf_elements":[17976868126084445179,6472118077937474672,15498079056820157573,17286386494385169276,8524368758276314024,10716755419855302176,12884568113498347705,4173316659745355996,5456815805476052653,1833643635978358954,14094233390184952633,16774405209853097710,492179441726559853,16183572087849145538,11059141020905044772,2737036549915571509],"proof":[[11303248455682069079,349597607746087926,1503571944162324282,15002567411916920267],[2001240583053065928,8148387463254055598,3345751314208839151,3641463090623145539],[3062513672176640496,12346565382199303820,5809663906165823901,10096938515917663639],[11227575449330962322,1423624221592159949,6051155007969410170,1955942762866952512],[3202283157337579392,5059054072107522708,12184245800684719198,10595408783207213258],[491466615508599411,2916887833000757483,17999646279820411493,7901480449185997610],[34511261517192228,11177138062798616217,9983809959813667230,16532002607899625790],[16663692890081207554,8662869089823256644,1758474121121539896,3221389569558340304],[8996464479924048222,14255008759688035661,8992623802287560345,14067948879193161106],[17605184757553768609,10093142647963590119,8073530031727943665,6129205645178143901],[1420378984724003361,5436723286197421233,1867127502194551771,13513299655949880853],[7098964738231942440,7965305854641880287,11762818591498264941,10728245422134808124]]},{"leaf_elements":[1273119570505423309,8629170566777005101,18382520073795589110,1236987740646507606,13960510989276031341,11322320036949891102,10499480472791522718,16367935570620805570,2610649604578060969,9205966413199368696,11431895532551911287,18048771900915269025,15625661013876649221,10166691351212124177,17295946724264083911,12194747201052883323],"proof":[[11959642094180709721,4686365476259726733,5294724762195191703,13807854527011745282],[8321815786682341659,9085083231865989891,17929964081265195333,4110115394234046819],[15391744178659190860,8930076092133917332,18377537283205623888,16326639701022039033],[6247157952533791197,15333692698249003700,4524043163213600570,10233476905016192621],[8135306725966984114,8993710665764885403,14432796215345019047,9229305189476886082],[4299372646816328233,170696847589610212,13400679645085977212,6044798795978065945],[9216570744816450098,15005284284451039974,2189008967809670538,10273604417446315349],[7478494998970705656,7007028466755151198,14486930490347048059,5171037451178997382],[1444049014554147479,16815242806765425740,9415344690619219759,16154013189755811650]]},{"leaf_elements":[13764283969887438179,13099687241180002467,10051623300673274127,4179682821538699385,10194799834042922717,8399871668388255780,9476097091953396105,14520222723706783294,16989945863993152186,5266940563216869913,6146476807944908110,8596554436031864958,11587373731320389315,881638929997832919,2412014634243329397,8353975891353675193],"proof":[[13641014950649158748,3448041412396202801,3367462304368275343,2933214714276755714],[15421130395707418930,5578633181950632790,10697383897376053045,14952521497698458371],[7127254561533091966,379793276106192819,3978568147518773586,5917539973650157406],[17389485801548752826,14864432984381908990,17429493365715823740,8782744535196222330],[1624322729522103696,2751926524365227308,6207030929056416438,14955715013082252183],[8512266482115860099,15546750407423970138,5424652095822915445,17299420601417888846]]}]},{"witness_query":{"leaf_elements":[8997221107625485039,4604379378171749501,17981440546892870773,4408964563507559513,14895460797062747698,14653089320925680993,5782789611139117799,18218405407271273777,5626952104344163706,3248356402033762776,3964537392094893424,1889720761311253595,12410973898201733548,13996427910907443714,17985284974978527676,7728330361976788687,4210077462925260638,3175928395770576255,7733741745790496460,958264085456435260,4637219494562149517,15121048749222685055,17594242844495225260,12132306140154422843,11489699049812295398,12031117726816503178,3660396125392376590,15243864233471842707,12042961008250554127,12718763930599625310,9727839115117258702,4462421809534106125,15604830606632676615,5173599081586680851,2279967740093829837,3213658431628499534,17792186817309405677,206134724538812288,5457126946826775742,476359462561207197,11155327579999860552,7350721670641726050,18224600731414818925,13781509795109252881,7906901113258305656,9306374286551583460,3319897257528823642,1376643335196547764,5596976437113962060,14983925476084872510,1523125047548375437,16245608768435566268,1222474519351081787,17954439859735275816,13715866174815049936,13190793593638929224,4355114086152698504,2270477800197921944,822146665345525548,16692027741923353958,799121624417497566,17103500339757238717,14070647276043042737,12468971765612477571,8676175097838177558,9576737453738091881,1600028988199093196,13359505949662104545,9428252947300890929,6171677393428399700,8101801859553302138,15754097411036482088,11113912994213181501,18255496160373564799,17774430988675201357,18149556862849141424,10830089285321105830,6992652116634870589,4871790391286250135,11682902283107232868,5060887585903835468,3913753850469687709,28772257355724497,1934314599538122720,1616848754726042694,1314104049709646717,7914171331683796513,8691026117877460476,4874757424110127749,10127647697104031688,13724697737142555613,12149327718858166299,12098914635281437902,5981170540051882666,6194080022967734956,18084257652781113887,3297919918562879536,14901656208309745464,5643090160060840966,16103058152762283035,8288491950876324589,3223663074715188458,4764677505984249273,12758239732718703999,6158873630475845771,6459151320424925222,17090591031246846397,16655771371459072678,15819387490855330582,16279406212964895068,14048024368734660389,17014449562111953912,8010474448529217514,7802256362120557139,9871856943239952084,13442297713221896185,3235254651490054522,6363098491635427996,9887721036776792002,2450206166466771466,2103212321095075185,16179373023004383395,1424483575299234835,12857874178530090929,5484190340397483110,10580420522784606802,9580104815660799150,1643187276803009013,9353409373360453356,6226882501530658689],"proof":[[9544207905771897602,12693364543399622470,9024665076565280896,10781020777150501015],[13432589628191519223,9826489645409148450,8132579969266706177,4166069610387961348],[8470835627869449333,4398224618233534770,17204100534026932108,6747388812919335174],[6757823504675187668,7368183308028225900,17538208571627589683,17982839252365961137],[7015917115023979018,15026669915942601781,9219575407688793249,5484381234422289586],[920905122617562025,6770274973500801390,16393996569219779169,2094701461663136803],[5806750528444252744,4869300529758468918,13720751434948647314,3568989988336118066],[12640090870068657516,5852158248774746840,2518880201967290420,3878299098217343331],[5753798849529383376,17554487416508298712,5708250613892360191,17397467012865068459],[10469093843981786685,4380067363640466237,4405562695232548731,7429167962000886307],[6478621766957545664,3794169900588498616,10080006751250453726,1325286964009886876],[269866393036651411,15953019578831480384,667234262959222886,16037751487935195373],[13672003998270698442,15211815419249315172,10235305282813728493,11262363692297936597],[6343235743738820377,3737277811156437584,4318978321403145205,8359101591779482369],[5734606586086461866,5283065877254190427,8530673759420305119,2520051663245228344],[13029024780917804609,8858054344043897781,14960337730498733320,17324617070040952574],[6053656364264988506,4846457680509250821,12707172833950381729,4222327628984904869],[2162049736183788496,16672409335967003138,2669924932333973143,6777530277826547333]]},"stage_2_query":{"leaf_elements":[1879853463296251628,7783358773774174464,10143032226905695371,17073325927620315142,16001042663737217860,4192528174749980044,947051204778093958,3322033704157619251,14530155570421067792,5643090728408817415,15192406759039491787,8864965320544548357,14168708343037017063,17836011431455676068,8547986538805396110,12495880290121091461,8000644845931045650,12517869020536991419],"proof":[[9492231731746452899,8136119924709436046,9641736837960208713,9665017841434646367],[5462406626532123876,17124833098632158718,15758134245870520134,9824897204283704090],[4446887827073007801,1262176918472390280,10885888972647346022,9180058666151539054],[11593793068379122081,8168083062261554657,10501449435850661444,3737818354946115338],[5664042765847333701,16499217702393331168,6227021400616373990,4411290249650664277],[12727217677035836370,11993411986064272721,9798018855684948685,17382933314172251493],[8815209176640122585,3342057956186798390,13507178892273308492,16375536889838456323],[6863847015243474006,12117557393051350518,5289697117848359019,10694856629065402154],[14415730774660797652,15741299744184417506,17190404097978770498,13285496288434264722],[11930062614531514560,1634882068947410316,3338472228682034405,17191860147424052777],[18255207335381171020,5103397061238093079,17091344817248705955,5624548943487952488],[15955925837022209410,13893732850977126396,11945316293606575564,8131289161753364599],[6973243299940549410,11985639501194622836,5039458968710835912,2386024491981238643],[16973079613186774104,11740696066586835935,5806872823529243773,4363053130312897362],[11185606161669942681,14505212939511982572,17570073523935500759,13781944697345096372],[8559711516817552438,14406177037246052220,13536337997022377418,9768372451068442327],[4788103586408647805,7091459077285864894,3501802730472823090,18191657498707621451],[9359148312680168169,3283054090511536203,8698881017692029383,14841092957800663386]]},"quotient_query":{"leaf_elements":[15790155805214647666,10988848186460072385,6517600567770330836,15760167558262033102,9920855071056556169,14870424407713210251,8294116688699938434,5354133571719860860,4597588969835766876,13476935278719209425,10862343255184378570,16825438202096253510,11403312494856189574,5147590255425098213,13824832739455366045,10537448868974006190],"proof":[[5417249610703628434,17511755862789004678,18153940701533298539,10764334014961419830],[3224352867368134853,13456417456515169857,3780581309546259544,17568475968371736581],[7272671610626710841,1357565317638738317,319901790780373626,14004179582779622177],[13486805844990983498,12342921550943864912,17054857206399634396,556151451917117008],[1185600548165144111,16786640425034053539,10086758116384407015,3000642137607921188],[13471274218431006530,16343527429153717437,3415702426520412767,16880556851257132664],[4776595000595554703,14606738078645070711,381635943268762573,8534693305878433885],[6423679223268010099,306457103559484872,6435036782316860523,17483382726816371786],[13892805435492565304,3958795270993059148,6292483690164574543,5742562083926987638],[6080401947407776593,18038699289010125017,14024743681438198509,1580509683532657092],[16788654429490179053,14085317499209461335,13465549315663144177,4912411981265374108],[16050568800017971743,11343383543391977485,1707712784713219999,2112708284100181779],[3432840878427852472,1518816905757357519,11289014197397321392,11345888623363468541],[4270183630656346732,16090007268351150129,23976212392810930,16611087008269271443],[6980936367227442432,15672308816238618208,10849712534229025303,1963971262235347272],[15827286773260403397,10123566519448512368,15735981200742629073,18025005703062464991],[3698584522434317184,716018236038350150,7575109566059492046,12807843346642471735],[4335525026145511277,9779309019813044212,275964694616761875,8043532188563706675]]},"setup_query":{"leaf_elements":[14811452902014838815,15379985421369101211,12318748638740341962,10264801919820141386,9142283742243336076,14849156795154948135,9614806822819263977,11780931438626487163,8496923199207771465,17490982817265474473,3585564875872936572,18116039108469389369,9365310066290693712,4881232805335962589,7421377684545602961,5112706959685836141,8481079855271003847,11645221345286214601,14324631891570127170,16628579022812256265,9586473346301006126,6275487469325227040,12709352606702428256,649830315924810281,14057864657812572812,2212731142857547268,6989596485772498874,7778831689907091349,3989988449853475550,18185341797252862966,7893904807812898045,7581595470291201021,14004861095197850779,10526661257976815828,3916292413359847343,5544888100636928497,1628745037314694907,15951271312397788153,619165125712222102,13910726651033006361,13111682810108127458,14796776596729974299,16478714172279864292,17893052745199730426,1291602255972282801,6271804603394491608,9827693482791381728,17542861634693630616,10272941743990824839,8115116327077169899,18222815511381323503,6364434881613744749,13706230336908911438,11146938649363910259,14494395961608653971,6009862095323736589,8444988398219629988,3224642774924469758,17969095548654033062,3488840995203307365,6337246516278304518,17508519531244976787,16683540268649401905,684743696115052595,5748865987514543330,14638886469242353452,9212290100958771460,8318810723156584350,2459632389428399528,3380720946734375391,11514901535337517767,4542852712689148806,13835293928619343649,7824856009160564468,1604115926875096084,16505697394048263367],"proof":[[18002213256105960277,13217816924032193827,7142728681479405640,11802724519753684794],[16296364658405175393,16429171924448553783,13149288143744994623,422176199091718575],[11915716473282461184,9805207056018586937,9752543599052289763,1224820844790678628],[11101780763424756136,2638388722777193626,12579197265287721759,4759585116011707241],[15808953780241062991,2650920870612589960,5128716062930154502,16988242625801805479],[6853114825474310041,9153490616100446723,17214083812025221636,14369576974079741965],[3123152413624376064,3551429894411891892,17104270893806025759,7003248163875173662],[7452841256932705267,18104550983376561831,4929930174946254132,17597355248820486924],[7928222211116476925,1346542316450448531,7449245849026032578,8109058686663942503],[9953874565095283847,15203612443131666298,2621952925093852188,8947703670710390750],[11879376102217277372,5843927953090788000,5936068561732918967,3086217542563038849],[8427076842701749792,6625777459452193551,632041996574661122,16720028333987534649],[11260573924551935716,14583752017115235958,5613211017763359217,15590799088209349641],[1310756302575860530,10022622693274546865,13342606282710281622,14596041600844772351],[7111143592555070027,15994459161356347551,2867738366609079443,16018723307672233401],[4258983142602858729,15462638314439509700,14975711112391255091,14057738003512569290],[10363323786716428252,1405887743681365448,1117467435672324148,304234346392141292],[14554215690654893326,12274538368117510090,1099712874894858174,1994026747996274054]]},"fri_queries":[{"leaf_elements":[4354643593499758547,13649392363535335395,4386855604506796193,4403580870183811000,11774726968821745671,1488374786414925087,12534118149357447921,2271975529468050331,11263480111459596894,8921217640742247720,9064676558708499151,15631657087149216721,15895694745219688051,4191414465493645894,3932030649384908356,5032908057355609282],"proof":[[17058946316810457878,12534210843412215395,3421408105959294414,3103378680399073236],[943702283738341905,7535807635335546862,589781325341344042,4470748294945990783],[7687233320032885491,18063001176472107045,8723489964750825470,2560124962035300849],[1112062261258805692,15578732837023618957,15956203724157950307,6424116528344656800],[4326039089332670188,17419416834335561898,10369350777739312879,9567231019090036105],[6612298674448847393,5394755468896856491,2940447722617400061,2672056922962018968],[12741117104067353503,1777788392936325346,16328720123812059777,8662718099051573444],[8147816145757614250,18165672256911363831,4115823892101422698,11968308288792806620],[7909143303531634218,2377777530045974523,1950202705378367061,9995230453526743101],[6812738399722861819,10559671857026791274,7964736839541155839,9522135446861554943],[12447560299046005628,14332827283593605948,8270632438638125913,4749552207127725915],[5112545911228197688,8671010353958699285,14484162317129684817,13785323136044288031],[9046745818964387859,3462978863378758621,13186058940808842962,1212087769618857412],[16239924516794706805,10786797742240425161,2002727674368151768,3593877885974378725],[18368530197592604994,4933783359463203121,1953582573169270714,16291876187939661748]]},{"leaf_elements":[10714093294945983543,5540521144456118347,4980954864575201043,10426771120284639781,6505096961410217256,15449494653370915191,2934238862166099583,9617479879712372638,10333444649268738411,17401177248526369724,14193166196995881004,11630457457598298108,16230765306983147281,10732814861571784312,13859004680944780850,5881110329081902031],"proof":[[15832065227309468441,10949044344570580133,5065765619185134654,17437537334311250492],[15197393814003309365,15298698196315206727,13362074386747259502,4479439888878539227],[4850126591849782574,7967766956623837003,4815498549091619466,7233334677188161470],[1316136819260381615,2270107771483421803,11731565336348740026,7005023854662504877],[4430682462238299188,2458111334773459719,11520299720797405870,8664025526934841120],[10395770912531971605,14610938955873368325,18041400036579421970,1968965035148786405],[17979623152458212312,6655371168952909219,10577270154621359826,3176208391003976239],[12584231131043881051,15028754677666760535,10859271914721805754,2929025816464751825],[9724369218982576323,16032309296116206275,12268461402613978764,8857181933812268367],[3373894347321505796,6136188681375477139,17030193878966054826,16687592045050482037],[5823602747886773100,14423234530254812635,10391662186643694855,7247640837180568193],[396318617310740375,2322436258782184613,16704983524898725488,3612477000936399396]]},{"leaf_elements":[10348463356509184643,33873791868286873,12877601820851746294,4019399978599851776,683328754220985545,14809012323302372210,17432054556220394804,14800647053598236904,13122376236070926818,10350283240407317066,17311018544376088408,18190753304410190286,9633422035334666659,483303978839072754,7936766833660740194,6747854120229971312],"proof":[[15949677125123257850,11418588661234791026,13725068281726349458,12184114325475660375],[7667232866569910160,2957254791339757715,12683280490256316945,18280810093066882185],[5053759462702032184,10475646015060023264,4991068928578052110,4287773661669350319],[9805297994288538259,15421104415440836115,11544231424746120897,7136718478589969295],[16073993785898098216,2995673400813542405,9203313727988619860,9582591450847869155],[4076221801374922946,14599643177651982323,14977672329366559411,18220791494527714251],[17944365041088350123,6790609736254147901,8501556004224505016,10945016703375135495],[830627872698735777,9687843926929708258,13358184161361454076,18260911331492149284],[37931547955308754,17597763790818610940,3082892579103768412,17551490439760693930]]},{"leaf_elements":[4179759964807590451,17158230940450581469,17029950356238449434,13025931707732738579,5973082919736154368,7140155410257980676,17984127121589410450,1195030230557866627,3336161115621362341,17030145629053084174,8890735869672551981,3478653964942696635,6525645721866290582,14032896215361820411,2777104911666339912,4163577429917875955],"proof":[[4311692780793424881,3930793207181584829,5992539673756807252,7988110727092410054],[4105569453012538118,12791067346576881871,4169631341543680661,8052756734631157221],[7235814161893725357,12920273737547876719,5500549828487630784,11263283376212971094],[12116288623801272376,11915218681507686427,15809009643711565393,8515191937108782838],[12296181460375770221,15147869952952055531,14100847072885228836,12042179703270345201],[7366306617314369220,15996341719703361080,13577419605788541523,18148484388828322055]]}]},{"witness_query":{"leaf_elements":[3020205059411777932,17347685375747257444,16986311708436842203,7558964910618383873,6017754825381038894,1699669967453055076,5199175140589382394,18056682186220941184,5646857769692233543,4589897348626796950,15017604442393299138,16722878857256673759,13201029169554734546,14837060127787556176,12323089413646639457,805490407479443707,12607692597229886130,572332307759975729,13084363810859414075,16704876754909726004,12049919039769139955,10371235337984898925,7524030633524247405,6112547982243085059,15184450354219301346,12255357215042939052,11149221539268727218,2123785700956418377,8566353132767317866,13685526065060859697,6431916660541486363,6593063513706109594,18176777334739499376,971249046134685681,10961067172938681930,3743027647178199182,16414298793395844765,389003815902386029,3489195993936276085,8204322723207834909,6357598471101739447,12507390271474359628,17798262286782524060,2423009304096802044,13799134564472324976,14362220330985701591,3569574227333567268,6651140141373799514,7415085813989993861,264698693235693858,1082318239917179449,6307410620901446367,14725178908308436830,2034732249213270450,14473465553606635718,4179572844021957336,1115806601485555222,541875528135632006,12405619051344905599,16378336779711524430,3617772290049134708,8843759682063454144,8774784174069491453,3938208431495676909,17112756626222468540,1471994797597424689,13064923602511168501,650379609891374791,16822098614551083315,17734477174296767229,17064885119825283972,11524054058786259907,11957547853087109226,5321829545100360392,11697318137055751036,5792032664803261634,16612944691747063397,2574757245688218973,1507527906652572605,9464333316591977499,15919587715970692047,2866314748716408510,657264481143306300,9867939321792471072,15709641695774511279,374194677684837155,3111170925403156182,17116555032901626813,7286141723052618532,63611304518682768,12054493191410886337,1546081896480388522,10771625632492034619,6611837189836476810,1644850641497110852,3339866882884862999,10206908017187089261,1277742995133456072,14577280220241232358,12821480845310742607,14670458335707414862,17729080616777568860,1450389576454403591,15083399269196498128,2236257906047318273,11831464556963952851,9122608081685041271,13466403115720463397,1110679272440555049,7191114187825223680,17578539075334217667,12603733597570323700,9061450655621203140,18249632058686546625,4467622065119664483,8591380131068581586,13012365095612834647,5635637266565058964,16852939904545515033,9757104975365391605,3503522969331049913,281227748687095219,6956621976202949284,15085612769195295526,8949279423567412613,16037739582219577960,6165221822466747337,6535496794178309778,16186058491390790521,5850708488052616244],"proof":[[12015463193894481110,18423522048623227675,12193148262721418898,1206141237005887748],[3511718657260697200,3622560635183041888,4758104716388249888,17844694987977364936],[16426123145033759818,7056426861069340323,17221814155535850882,3298216581155489886],[74481937471444864,12448452839947567536,16568140219338881740,17960691750810206083],[15760077356969131812,8985210540640710815,11022202994521169198,5501648943199260858],[5048698852390706318,11018491619999779049,15879117983330825277,9241629295019716722],[2035529352656440577,10438514000879597019,4422582214658145117,15510674319869978397],[16115251743767238064,4182031564995473972,9330851346284517300,15092633294128059571],[17185102681622434965,17759900981419681664,6904154494840016505,6389775456156828730],[361438301142262181,12163165744935998083,3393647527904344308,2073397391561229594],[2755220860001222194,13733427314359313105,14385648122468256717,6644853120897729782],[16386224572285973727,6227906151082480877,16081650153223621896,9076778039725517924],[4795841619539370985,5180250580881706204,14420659209469064168,17414302759700285541],[4710583432279118084,7640645517494365017,3679078713091495820,1856808987704108801],[4074359491087279697,4436320067051922172,16922239320859738057,17648408805703043480],[6204077631166342008,18097317975608234880,14004155830323433813,15207111276085771244],[11288912811563943891,12031180271448373630,13279513074385745385,3969789780235877208],[14959946405597873701,1376215581984121396,6299231533537098964,10579534812057679918]]},"stage_2_query":{"leaf_elements":[4917820842363468540,11711703142233615482,16013797965143527862,8699554190347711425,7463409259918341492,1770556149437025104,7673857795367767851,5813511567101819932,4902238924862724020,14764830450837320968,417300038491519003,17132588279954156496,13843905382185490564,7700181653089787284,4089185565803343083,11459605600555300632,13818167576064199723,3989877059748465204],"proof":[[11796517403894521994,15282915862321426649,6375869963382650680,5710491019522502368],[17022927401404179138,10980804839934014692,10839981922142549152,17428934564255121754],[13446114265957660033,2755642015350288313,7153551847067133734,670217970087348247],[9810247555995186286,12688180496563454137,898485869587677302,16672167067817071821],[9773783620781717343,4970928146479202827,11930577322305685829,7981419112979786208],[10891772711742895984,14308179095446460585,18137264327422572931,99313702020487475],[9861322817620769416,6956043022011773810,9285648502332495032,5014435147831563545],[13013172928152664138,7915236574152177154,11544399732786399006,4933420748712355703],[8185210103777170519,6468007579181673551,6600707173121633186,931231736864108512],[16974942332991912497,14271957175887006655,12912983473412496423,14308995495169679230],[15838410772612913667,11276236779987449281,4298540244689740246,3083299945760726388],[10067641754906007884,4490717409124403444,17230470926497826294,1493801397205050142],[9206260676384005869,18050672617375076669,6262687565623298433,15123013351479642471],[7249605414883077135,14887379565093129192,4747226524013478201,17511340258206707280],[16527792148476734428,15947268782089288184,2775848424646366694,10847270884725157131],[7229302786702269603,9886136816474874308,13327400916171167097,9112309352171337615],[17912618618530434956,13794873435566321007,11159992594481609632,10836674151214918567],[13522695531207039924,613638799054233107,7080910587238990459,14950006677377623880]]},"quotient_query":{"leaf_elements":[10412261125285926101,8622479083958681244,9849217441737347765,1805356127405639217,4958960421018390716,14642283178559988518,6552477521176569771,16272219674748189658,5237463712502731641,15479613444263139306,1122471069726417076,2678687261694026989,7117082597538472473,6426322926047549641,828864788806250556,10258940782079452650],"proof":[[4797808987315466665,13025040838148853364,13426383015089605244,7866710540022619180],[10554344793514931518,5342823295566534501,4260088879208188896,11768673257981707831],[2482938989939836935,11024673977420290545,7642659756522257557,4940448149038491631],[15108199286332217920,4789625395064961734,955541978120062617,4926776292379563870],[17305924847571769757,5377409514853441703,3165514019221141821,12971035310979194352],[17660133443431792653,415077746937685082,11186674233050906134,14806806372883990582],[9873553718008013681,18388831353286968070,12571506584902577353,16412422258376887259],[252942374848322983,12731165543422653305,7155641105046137782,14665641360040563547],[5189408395439591472,15922022953044748488,11521210593954998314,9772532238397209088],[11503620216660588924,9858348530730127956,10872173941062001554,13889358275686119915],[467807578322613406,3846203280653962888,2919047085888419563,7590839881062502456],[4466915976323035176,11529540911307013671,1538407693164300956,4701596356137095945],[3191827715939626880,16847187952042508175,9577331480725620396,14974967652116688861],[5181489523298791613,14915838972309493832,2565756363312318357,140409431774491743],[9214215336717439492,4064258648776035542,10313934483094689861,5308949786041793174],[16632412118613651926,11462816643110001875,8929937911166955703,2574161567384901305],[1084154059402630515,14632892368922686710,14895417831295307710,12801793058272683341],[6810824304247157919,3554945223271348989,11380697936671302732,12373031758778783152]]},"setup_query":{"leaf_elements":[8806523231113787036,11236040369419066029,12057793898297686314,7867418865057281485,83714288543253793,1833918245516741922,428688829105965217,4705427473477033984,9102811920762328888,3479372506959280268,5188823269036805366,747017475004609610,15737310866291094897,8756906629902028592,18261926379620469210,7887154484612907071,7004514534135397621,13419986459392574215,17018486611021126594,13446898749009423541,9002157752686938194,3878550692793125127,17072000475012881130,9838675851218256380,11654187282882994520,12762272461910016535,17302285401840619001,15391206898634820697,1384522083842045235,16358148660843683124,6294660424395463067,18035029891766923567,17146215120652941548,7401408482679163514,5760487203082317745,10976316063950083897,15209932609397868617,12420885639139751662,14743820324231306386,14818422792064951652,13254735068222017282,9341746219777800223,1923036506336516174,6084673210825120195,835114724482716785,1563164556710681241,9357123637963037382,5748254277351531844,9323364772729150445,8359653158149333328,12174002697561026947,9203830264167631819,3615302220937228126,13731945148917327331,1295383467167103478,14277216699888614176,15604357614979759327,12729092088942615809,4849008892413514207,9013326330239772278,11845327663541436562,1098432670840059269,13555920218434187206,8554129951959920825,11886899180447425585,5146361434165248068,10651977904776289252,9950872658913981694,15851381303526402077,1400419039140393898,5196540812635163168,10848141951432309385,4794853764320132339,5179617236951451077,5431924222573743104,17064917016125165229],"proof":[[3559384024471546878,15943894306162553240,316310324381072350,9057438666470184897],[16856713240012163083,6719679235767981100,983120265046058233,10435352359277735843],[10113284697256352701,17170409357444293256,15825007598821011046,7628102477230458875],[15554711348514440139,16616331391815445630,162412466259715485,16090784969870696673],[6022503687968606643,11681085201212759918,6011701006541704727,2151934641259689041],[13661205371987683167,1595490049091991472,8613163208182476427,5157466019029530187],[8627116699433167143,17944942751088714820,16254600866080068206,13534223082076421141],[10936402167012153173,10578068993769110825,17756157508619414942,12053736377231374274],[17127721096718058326,3561422211689640550,10393163213587726911,353100507890202071],[15724332133224160757,13912462357263297667,3914918873065948433,6241497500308383235],[2992918901642255673,9636091388639077967,10546457140626336316,14681930902216791036],[13372123874761503971,14038562447967832172,11405497543755943025,872718192060834787],[17148949387951133967,10961739129586212479,6846493103896309957,2100622701638157377],[15681596263203596834,13308441788029142166,17029794867352934717,17262192233492343157],[472316247797619072,4827924335095709251,4127630883794419027,13918577383190612340],[17375243783519229401,5228725048356919739,10884614995122474811,1353703575014926986],[7304269548724013610,12746655423087423072,8793103898598125888,9618394908750043565],[14247099103803672643,13012509232738739119,8735651762249409991,1486101644139975517]]},"fri_queries":[{"leaf_elements":[16051530753176033486,5252541871324041482,11220780380291890127,13153702389268987298,790769252840642832,2310413777171946819,3766223217943022024,16247786821016811359,260045096462550630,16816627570904238712,3489961184439449990,4881753420286604264,1062612652806436396,14470406468069319561,6867521689829894164,7951272250992754357],"proof":[[7050535307029038159,16623616936868531960,8708569759854310291,8607326236391778796],[198736651253912032,18437378434081733519,17552803118003822769,6469281361926886448],[59210733432879806,2650539969246556207,4890029747643168614,9703897176644157536],[9233033836975812469,7508947922489941042,13685693154425486255,10278679527055959240],[3177009708038520894,1109879909211851164,7210295051672655507,8956835038102579585],[4032510715059204890,339608027974403492,17848662909709708090,2827982483286762925],[4205653830568571462,15413692885555651563,11153838496814558820,2326177922137898319],[9137023408582839580,18211703981405535263,13926261005543948940,17702180176020573743],[14670723970894885134,3723382637091044623,14196669978302737605,6485205430632401609],[3424375822314831940,11371719424423369632,5505782415640379648,5887848793910013799],[16971744047664775274,2907541170849761206,3174662253352024170,8789026136219063244],[5908162933863507923,4681714770388734231,4794461063149937355,6366808746966078023],[16388365513571100779,7014897625288394568,13987161528677688730,4737747497833664149],[13448605175719409529,12216856030455372834,9842351648860951097,5117324984378131290],[7474233541876675874,14607106581736682685,18125377006778553197,2310195700152262874]]},{"leaf_elements":[13567440218061362628,17675645697531198196,10618395738465342249,9958722993833911444,9394455506352280927,12824276072564913111,11775704579931294981,9185484799790990326,2496806245715887201,12916621553739121663,14551257221200906835,6155548515816430649,11503253944706545945,10044175371160257032,10979509593742330850,10853034834166595872],"proof":[[18385322486396900163,4156779765642526663,11393555397159377481,10958906761514448082],[1289387962465035128,18198706151386454674,1804805345559237243,8439138283947562680],[11165530886360706912,440089849308730320,11644200040327512887,4603123813177503382],[5463927368843673930,17085112413063458744,7890458595296041778,9031766705710836275],[7732359281560713050,3937907355670300732,12653169529551583073,6300198542146424681],[8572565797253873956,9167563083429745587,12285286185757964281,5335268763211239658],[10164403316008103587,8004390656887449031,14988553528398851385,808547345545928173],[14909076495265429431,11834791619561505575,2245186526216238877,16816127980096730666],[18195022779453768504,17782827779093594530,7422523225036645596,3919550182601343087],[18401933107781183902,15161656455386026939,3589373964002901010,5532282061687160845],[11197746374058932020,4009858598091038090,7044862869042612144,15514495161705838611],[554878789859416185,15659318091927986215,16674725656945392206,15208291420161342092]]},{"leaf_elements":[14184207725141146791,14794013203570084594,5467380864793661713,13853528887466452123,13562190335942517382,14568774537885856969,16173319068029687181,192405681419767271,1801449494831288475,12912339228918167470,8422301279551336204,13910556914467177208,10038401062683820346,13874765333180378006,13350965619235985586,1324407149919823539],"proof":[[9142495818548734189,3258644523234531089,7098501695569199740,7389380860173996074],[16131109886181911602,16220430183038634696,15249187719698721198,12705756143729283146],[14335109489465028541,1118316728264673233,5723686786018229731,10130071577248959430],[1824680470459079488,14874085695835649398,16001956149450143727,53872779608609571],[7982059622928253460,15045268238514133444,4215608942763097005,13689027434668662253],[8083934948925422201,3640226242219236153,1291851946869898463,5674643334209437419],[7318660855625495747,12185163049515315249,12384237818251225142,13041873193398943564],[14749460892310277075,596624635095461068,12863356917924297929,14163975756762738016],[11832462927017853363,11063620557583904494,13690411385901640056,4408732182589750361]]},{"leaf_elements":[9233685009221198465,13606844110956502111,16728875121559514596,14475807225572258712,15867245322149181932,12895223719822683787,15441587722560072174,3883744488943944598,12496250391604770862,15789956909854639110,372800712273619897,4267697600951989865,11573341821370543419,5379597786048991617,17151022366241337554,11650997339170713988],"proof":[[4699109714417808268,7648462325594832676,4071890420866572421,11384352987993521792],[6101377806943626289,2386309241385576841,10842804949557343241,5036926514256003473],[17913346890050313952,15459423009333736663,11804041220295720380,11174307943756573032],[15604511384817655524,10970580428557715462,11491439920380968775,12499069079939742164],[2643022386348347870,4018499154020741466,13244822538717619433,5120940167773919068],[5333324029988799954,2694790899811649700,17893771400965260860,17976542471478320206]]}]},{"witness_query":{"leaf_elements":[13013471163611472755,7297907098329031008,15025277815074881348,13363252539302312076,11931426169864365062,2696204358775197594,4236744911396505044,7309022510681864709,5327453229656354451,3288572979867845871,18060417327848076003,3524385904762134305,3019959193890011651,8211242415752803421,9135237737998442075,6423250392018613657,15147787261763478640,16021057508041652089,15398355051051176679,5089996433556597228,6283018644371032351,5675619135831377730,12919350266442831186,2165663767900513172,17551310026379547689,15051743320977573445,718219774171092521,4981923308927807095,414643207006352123,5721810800985817276,11492634023987184163,5272685899278057361,17301655911393766131,10619416022388626612,1660042511966562680,17697951390249690698,2509378211429173206,12269186667490359725,13250957548756516398,9423506619558673741,17070444048604882876,7290018320487730800,16203629421646593997,4223722562189100548,17006993053508974928,16238869679869412703,15942249623778941525,17856625308382551145,3192722477153149081,4919821627172893093,5461413458023239044,13546406391889284068,18279720572543419524,6137981808135607303,10815941517608124660,51333556050426173,13206375122768791003,6137466807942528975,17216870079869340656,9868553413063082184,5765729245148729002,18194991420877393886,13409589333100506646,11788009985807718662,6047645430210672797,10710932534972940211,3705107728882033697,6721518386461584889,14555413418164253451,5911514108836309045,17047903787385036379,16473757916756877553,584045134253237205,16951864761608732213,16640165466203498475,13866275170839958473,4217215038029493557,1615585720478456531,16036286536192942544,8307963782139649235,9950385059636693152,14794086642513973231,9109333900510976081,8320419790668207902,7140848763274989516,2747989706811147848,10346549450618838652,28185700039317326,13510860869832736460,17837520317447817995,4995444614742772275,15460733802119000788,5110961309913215350,4728779601709868779,9524076382799945385,3717605792832936497,4905035501694970850,6513410521238053687,16416278931924239559,1511115079735905964,570116599954911694,5229474829538793118,8234209228809477944,5163543227835903875,8924273656894960722,3563582516590583366,16409394614568268330,2560764765467927780,18258075919558822988,1648926751299034108,12012766158715555268,7898675282574812619,6150837914795728224,12674964522081501768,11836871056089144669,8627305583768080336,7016635424389954346,9742193395452307175,14755880561378327556,677481637622066421,15143434718680350379,16791665167770585625,11429308504403241880,3861607576563116108,16686363313556689733,5076960924708154785,16129737653278733864,11605093924223139289,3913778049850060786,13078503448139208034],"proof":[[5753659914495812908,17448760629228668254,2172730215064715911,17911272446977643156],[4499191572388468738,16289176256062672592,8613667136390090392,369752421845663313],[4121382777496207730,18106672744989633602,12356468103606225966,9349836281485667971],[13527209481952258430,1720415639564041293,6113268199129283785,17039779813619281165],[17867983707960336335,6739550091072250210,6685854680770345406,14916872924868264129],[16313708234725978682,7420559255050286485,13979606337621118833,11308650911606720522],[2278645217244676271,10399851225681436923,12415189932125702656,1770474722532037768],[838110234479692656,7991497855107288929,10375700822650564517,11152637238606948820],[5984367625507153345,7475108316587190157,18411732370828613636,9622608683348738665],[17037692346985998934,32662907282761980,17177209194448444203,4908830376069118496],[7861222663545829143,1633134793178654131,14624851776714835140,12671267066043140699],[7624800624084944235,13440576733728410763,6872740738030615296,17242297670662042853],[1124861042206584464,3904960445149541987,12393329612628811546,13651776823661078720],[11558092810370016633,16813170435755261092,4812757011349445716,18186431664566852731],[2376386849335580768,6132727213382254319,4667493337832170655,9296460040315095526],[7888470256292747067,6599640217534003967,5338662350262028853,4754878697295939121],[14650977515411816023,2090457776796058030,10427296248988243563,15583213969728941708],[2758139587602645424,2293555986678431825,11301754673649453656,5565532941970136358]]},"stage_2_query":{"leaf_elements":[9639306352711669817,1314442065282315703,4571685277453045449,10193135560836852405,13623382868221841177,1623786127760151237,8787817746735198504,10511436874317094347,4490020995055504154,8786951763138821977,3257935634500141723,15704417877290486270,6319993744723481957,6295019835824696087,4529633600387420737,6773598770953453297,3663280564194063366,8084816176492740974],"proof":[[4390374748832271562,1803961262117062171,5412040915828329689,16821048415144500146],[11719529825332365123,11949340972629031397,3854898533509798091,2400230866157927228],[13024033572186858735,8737048194893511714,16782107499281270895,14105688077438691748],[4301694773724228026,12030135749128278376,15192876022435746724,13010300831725254220],[15492784031471810050,11665486365422895736,1516782572238700451,18195101423046992595],[9399611175647213177,12118000403953250511,314755780550362837,1808796069957825275],[2575036865915937508,16194341594663463544,5990523396128672696,12945651906454291284],[10802024240161252739,12588614486501296144,9417309678501138483,9845499782820956029],[3043660767872418954,3155529078291741398,7397669948585845353,9326868713745612174],[2611568857168486865,3012481582493574813,1669667478582492389,13154577151256105089],[14293299062878571917,11887280395078518162,15248021149982765529,8642405459593072884],[16318653001775873873,3323325319907433251,11226554276408486821,1767995352624676256],[3312213346531953583,11957176008323160381,11876707658938361758,2811561712696322972],[6394657720568622251,2418949913930218569,16657674484077292057,16097796914609529580],[16189844897904454340,8296583484202428279,10635549505714904322,16625167454705635043],[311581270960878107,5231330151721029357,2008033630115410929,535714425214597479],[17304425259690088964,1159045370593172008,6445043999311515287,17579336169383721087],[11938223405665464948,13228230044497449720,643946266212768974,3388349090712489639]]},"quotient_query":{"leaf_elements":[12567494310764466278,12882380170760209004,15878244581587580330,5819404160313599545,11514346419106635550,14101665331628548269,10965096184936327734,13085716112686053426,10972747550520616214,3603404576546572774,11336581839438731247,7851536983027137846,6104906363057821539,6429938086222438799,7876259700618222243,850812009949963167],"proof":[[1795913806909642463,11991040035584016329,777899080279024648,18172083849579196739],[615375373005715749,2888757607584929427,11453796786078522123,17907611435042278382],[16261800240805296248,7451318538491300696,462936274574974664,1507976624728791954],[1757953260309831635,13822185932573402092,6618967449608937308,13530534359265609560],[17478214074337535734,5470878245784494078,15205370038965324936,15205932523117147628],[18247950661121987692,16260096946807016241,14117111540451322703,10860987643201439825],[3672018101579080224,7787478567320045044,14970979478425707709,6969802620331704985],[8951196346041915728,17300434944526516289,12060922010891432460,5875757313004982865],[16985873777772359458,4166169385119648216,7350680776129715988,4584850414533704422],[1603439517302919012,8163991654716137579,15565279899667927205,14048845396034901737],[9937699877202394364,11004161460446515044,3236707781089344924,13737561259837134959],[10217011035251893072,2055706161616928329,4416593123701662692,10637536114409988027],[5311356214685660424,13246469578693545195,7560799309836199576,6060064478377141879],[14619994780957003177,5138269805036477328,18238327724714433188,5333959937396404592],[10512848162319354318,8774700028138930676,2772902136047680376,16294462610610783410],[18330489460865271711,14353664898369024458,9635381350583345042,9371165045585528272],[13070392167831527834,10094241941744683331,11673563903879428178,6080330351846360274],[5781445036116328463,5757420366556988234,8397910456447116490,8071426218545120181]]},"setup_query":{"leaf_elements":[16773141148068726957,17051687672255134742,14965553604812976226,5368416722348592180,1270861651441734327,17635679124084962754,4427777864023007423,9272884272006595132,2280418842572562977,16902680033534241989,3322866286922992510,8964725659528207303,9091759074120417628,7405559768857016770,337215139061204243,9372184180917430336,3603320712826907501,4854662681808156193,5096738557920787139,2088734205766377645,5716250129346197012,3811583830957972943,12269018662317376766,18191604643970766769,3648184895412692459,16783631464801277346,8698332214822006104,6875510359257181409,2823935716440872835,17508688568267389677,7416759140546920314,13292641593815716607,12977659818281382944,10243656939792179029,5976420914165730519,5237486567365541508,16800628676829147093,15404315724050260244,9542395993801693061,2928744741423558070,15362019229474641382,15230952162284209824,647152346580243955,16345995411019972678,11396875435316052303,8299621518916040118,7036656440551441313,16001818718766971922,18275735272252171960,13612991499627935731,10833351903970089701,11454971240798445435,10252761763729687945,6223551165587802446,13349150270144278116,8707543638498125003,80118985198572548,18048942125091295081,2263841443023832799,10507911280729682676,9250477951968800562,11659972009127798524,3974071336895804259,10204053453613846528,7211758566843548001,12467623985817069917,18291070609487604130,5031054205142330541,16609395043984237286,4932047082136308173,6878121758033176768,1763857073595713835,11647731167710262960,3711065422982360963,5121583503680635295,3734158863920638664],"proof":[[1400437296234473250,14758259360418269716,18218906605030065020,17028171055495901019],[495103045826137876,15388288813860846625,3911544343586872824,8304658097532709797],[3703162016901717809,9299724983219175949,5832699144039881037,542372244453017915],[10493902084082580150,1221769647256870954,15928161143737908167,16438843928574798488],[15328066530822715521,573545978070243010,4467842709275129872,5579364753590918839],[759170477906268562,13500191290620176090,7389576206043382641,4500276199209131658],[14070534264673476395,9799426975373906035,7780416253624245323,15191123697309223367],[5841805075594503729,16309732199708433852,12188650701923108225,3400787291618524269],[2532934033661602202,13541142361853923265,455763781567965740,16352741528394104732],[16738738301879760305,866745036288781128,1325435115329756571,14052210590616993096],[14077614042729135084,7130759922991919651,18019303405838254932,1476889445783437316],[10323243642882908124,1874227485032253507,13175584419427287496,5777651685015440466],[14706734193472423446,11694152048862543851,3872689004665223094,7673578606801367780],[7848642753267079874,16587713777202006706,4444854608819707044,17095266433869034018],[14876335102081389238,13540174582631341762,6088545862730696417,11722463239334926134],[4946775938494609309,459151724655656839,11416496798684731649,5708155952764575935],[13129670145223024538,12145431040307113844,17222985759728199887,15252058405089269196],[1431198421189927396,6674175134525323288,10898474567615895769,11958199217546211168]]},"fri_queries":[{"leaf_elements":[12314542356182334168,133928133975095612,6300141457502167367,17490361636027819063,2870130312163251344,6094383717898880809,4522717601222024052,584820528991122682,7509185469235527934,2881070031334372224,8108028983529091045,5349865816228357940,7718425859414035465,5907470842278113501,4925189202410551122,9532482840335712392],"proof":[[11738315924274356472,15477990134706880145,8527731261319889286,18313165010451019223],[10379340495970452983,18303642068271952583,18112760888374266034,13763581940140522459],[6747159988420486057,16890602060950309403,8358137224363779442,17851176268646461601],[2923247465739730183,13594371357309164262,18085181660422750392,122685872968450985],[13028176960917232777,7465644549542267983,1321976129911095577,5922128464576465586],[1064714850348850023,3040117808223526954,17480637550669425969,11804179171578434706],[12840370364813619085,12789116526146886297,14438214600665265285,16896730184433703781],[15147046022762313007,13311212578688137121,17664127429698552608,17307562591794902100],[502326661884022506,13383491367718963575,3560383381414367564,3338537392011486585],[12390948349603386542,15238877943704395716,1314964312565508682,9842403336952148367],[17817363779570781139,10859981470031727856,14346729232170195799,3312907427118555614],[4393642452408594412,6526333949442335410,5172589260827013287,1713031709447609722],[16507009972924376276,6059322311592832730,11095997842428007925,6146377922529249333],[5452076772842441828,8036966763532314421,803087679717726812,10579437438419740374],[15557398852062684822,6548014869322420913,3113604831664601166,4041744305562473045]]},{"leaf_elements":[104802111469170695,2241185957723912137,7710728037187053464,3992290191039948699,3846341971559725203,16713806440599212055,6319849417230763461,17267510674082371724,1235051959223694304,11036574488001412901,18102183875828908731,17443534338086220131,16000165191127750605,3929989749752111634,12980110183874951060,2978268006536632392],"proof":[[3394661697169858037,8738205737269027220,14612418952271126479,16433610014436606592],[9678030363717950051,10641656321779847749,10455687519007219923,7809217267961686562],[12836778160583718715,10316107626792119676,12833029472962963002,7153277556447509054],[2734311193602965090,17664649867875149296,7820132551470328871,10295101775778470922],[10925767178072789547,3717970177806268653,17520977262864199612,16163338104878436854],[16901899213979872695,18412052972873732304,6782971777156537572,8127647227215508831],[172745955055641375,9914345934451788296,17319088457881551524,9864964384806056536],[7192772502359264856,18336145389279612174,4792986309984962136,13245717629662559071],[10061921399265387575,12955235500671558307,4285668793793478970,1863827296827477191],[7599167941269595,8577522314305095398,8051969387489324547,2338950045253078651],[1380067395269895695,4198345556766357652,13931150467550910759,3998399715859125645],[6456558775173819697,5828490496837528228,15671242697197278568,12383068128869222915]]},{"leaf_elements":[6821010701390391053,2605722101526372272,4813180574736567023,14883856553697495370,6607223012388257803,16874959548185548265,13490046934232154421,13309575443397404181,9625093335127730678,7296600805850167357,14949712999695289799,5265515288659213078,11165367700478023310,11655651270578673312,13252961008950956441,14745610942088515250],"proof":[[16984432544068949191,5536046218690503642,328623885937195515,6455008716515957067],[251806545803924072,2442111465385053270,9571397215032950322,12679781285235939822],[16875173938450832919,7913321968774382905,7676827500236477774,1836418400054824496],[15626646939415436469,264568712572573211,648609226283938896,16742178384924085620],[6096345491263951672,7085819867466631547,18218399108349000013,3198823225467769848],[2628085194776189983,14511736779192779741,2029443253641045063,14737366704869483591],[233499240999264520,5049946533971304431,17659696158698519733,12735947237247652813],[2020859747221397988,5518068539127012029,17741274816432267514,12950981618980458034],[3827773605099555438,486046821624541978,2075122105041677700,15806462050960729910]]},{"leaf_elements":[8099785852716831156,16851569962102379173,17259275519308870916,11430484583369976200,8392973678002649667,11472552336551336305,15536745891187074193,13089624897546238765,6683939159105714718,17892442225966181220,7805630624838260765,15636975308977622875,5650539735335386976,11069953132602952371,13523644557518152669,418540183172334718],"proof":[[317822119893433757,3451579240413182986,7603411582848715799,11715255090528113308],[15314623604847833082,12239261946974351096,4830231413210781494,8938439823970153831],[13735210118616008432,6825574220297275240,1946547777807001977,3978649295566576702],[4360221881669224420,3877092380325525659,8899343498160289729,6180094418864871559],[17780899506296536912,16453561989873269082,4320737651380181721,4319455935117791474],[12436201465006516924,545875347413466535,3997291242032620764,15485544272390934834]]}]},{"witness_query":{"leaf_elements":[17320454643328983301,13861336690780567370,17837655535913534286,1561455696786464522,12533755869325211528,4017722506675606107,17466792026585181254,14789181522250547326,9271415512158381375,991640394789849221,12799240346192062227,3799244960408682635,1750223448467673747,6254385630038523694,5832144038472669481,18135078671107782417,260639516284665971,852453942831334720,15556447608831599465,16725098089238272242,17227357806875671984,93342023576378676,15701739595741078257,14637937019091450416,4511365872072148797,12360819368561927110,12630303817484864917,16221664558633029561,14063183965483848110,13180442137566086090,18228052649807332928,10258110745661928600,12853029671633188042,15937093003688689330,8691941513495576454,11480078560657106019,1529257038723192812,14639284081292163649,15188956687140206081,14009578603523236104,468954575472049860,8187838377513705849,5634621286421823984,14319057710252919342,12556735544507542765,634844869645680404,494960841365668255,6400909453828735757,9483132306943029615,16602016517077728539,1681353568708333919,5144872378506263267,11446496349447581504,11834989746848141102,4396606827706543019,228524524608978621,17237966440099914465,6907623007158086479,10222260737130424446,10533480133931299392,795527628033881038,3028934916531050933,5230379789726855967,12798145299354475574,3809165916791015689,12660783735878393907,12145962621187934955,16755128623727033559,16111339731493959649,3673142341853962130,9287819394398462184,9965232619091403666,485032434492495513,17189607410600279237,3287069463383821897,17547033896798954958,13449051592841566521,8395070516086547147,11210982961417390768,11409029997437673100,7789640733669163356,5802980647486986982,1382313422910269872,240512996389614906,17658012499009216232,16160540975387026732,12856770697624718801,17300456368190802628,15401577411961293475,5127676008204915580,14138155392461772485,1728270278242809345,17376715975760571916,10479102173358996583,12764101475572868681,12402075848473038675,5667053731001540245,6475202212348793736,1922513811835841656,11140260255417633531,4191503596753658826,1924415598976134244,9358237680461990565,18119682402803615337,5537767118264796163,15012965881610822730,3837901786975082134,1270643050461677805,16162968010258127972,2212520265115767707,6757234251918764570,2711278510145686933,4695299369698465110,15517390700014125198,11613677491992844927,18270554489310531930,8344961542373430284,5619896332242272659,17142611129528543324,3375038095909808013,762201244932708287,17798511581711406686,7639277336524571555,10698111804729925745,1302514450352388421,8581703465685319032,13736517660403743234,16119308131941478122,12756762505785308341,12696407213117580359],"proof":[[3282812781751337612,229780095046047264,14875665232229197923,5489835977949857416],[13526968534075888021,13135531736396834836,15363246514407489513,9789818288699054601],[7994390180242698753,12742959062528014196,76004806407194768,429980616186837839],[4369154257377153376,6875881549293830413,10019659073777323302,760558266964164875],[6497792470121528727,9887644448032331430,7729588410946969304,7605333048725979698],[7664547660097142275,15394375917228228307,12016046662211332023,17189468322728267551],[10019237024399334164,5619934420299657393,11765718532791551234,17291110305978948805],[1658827284234932499,12519835610817172753,4786505552574775822,16953639567072834640],[16600957197683926148,13954970062431482467,16077791260356169841,18060468580252003146],[9329180266776290537,18100259331547476565,13963449474567008107,218041099051277048],[6090228534715868106,17059048841868049036,7129880458534176305,6376706505240920965],[16665247971998010033,4136734022213701044,7152256074324274209,10747368362048981762],[9710012904472749688,5111993575359543548,5812810474902594588,4578194310438582590],[6889895220743993534,5255687563664244522,4355326003655929484,3182314036206592887],[15416518763563709598,6211513352162954609,923699046671432323,4333668287368526651],[9416316000248639488,8311292101319174307,11435471310281558673,17075593739982622846],[2092526011162038893,3855491975789888950,406339943874420439,16855111669052602822],[11592266003504323462,2583524682704957291,7795152182967040428,16714398500457915144]]},"stage_2_query":{"leaf_elements":[289327294097250343,13602332684701427315,15054693080126760079,16806642263831850284,11485251030974838793,10767922142552076355,3332965769735543032,11724921384915579251,2746472642286685336,2948137503714318355,6652339466598552643,5074231685355569988,11567638068469713454,16613401728783437335,12793118057968651262,2029776073469428226,1524177303962677392,1249127102430149972],"proof":[[14926439126934628209,12554431871709637220,11038748844113654667,3939144968376049464],[6401357716881535799,12563251384534165138,16538363053516786305,3393205020608308709],[1845799279247798398,12374094675171018979,9371369669368939191,6569522611610045739],[8353148491779071697,9542907799262700910,4723820577504486290,1823909036022257951],[8529650882904167407,1230292437431203753,17278641617158585314,12822645077224102793],[4317699240681272569,11161036643338467967,4696573670573182397,613165385283679622],[1907042546333216588,3695670265839263657,10034521064042561929,8675957359864827822],[9957082188964906585,968893766645730020,12861570115230779690,15135563244662654975],[3228158128705658029,16978725440891219545,16230024415685610322,5088353634176602763],[7080768742145026080,13564716646500669047,16772841728045447092,4545977914501114792],[1503912102729232126,16694467867955683616,4681170344170032761,8227306989199179090],[12376187269582727877,14533480283617557330,2926967701425405939,8064429514373790713],[9072342400434273937,1713789323529748095,15026708042440168190,10737397935256192423],[9689268141359083745,10325346995209934450,6578533393587668044,1690906192880250789],[13080982314570791275,12569314944888303244,8176203971197630406,6590737906364500799],[7389413821569227201,8624698638366827428,12122295335316098164,10913717383088591448],[13322748610404962329,3478739994622599138,7346438980512817390,7611978967539997047],[1078181616551117385,8157365238135106062,1047242060179425887,15489146996743726209]]},"quotient_query":{"leaf_elements":[12967434845907922269,4314907124891041321,13236354437760321536,15168110152243411912,253951441492423058,7595200937724707158,13865649585653000565,6987750956462574977,12524963534764130436,15197504415983051592,7098923454528559410,2274492557662334231,5203857269654044935,5820137542609388667,1702178102616151085,12601909081391156328],"proof":[[14796975137857654851,7449517970766225138,7313222728091173297,5180257291088829675],[15292907978108634016,6646848383213817174,13658209272967664943,9947021261735228215],[1361821885797329011,6242001931287338128,8573278363293936980,18314031979277184208],[11680492107575878691,2721221580242300027,16401092851641940155,9474895650604087919],[12846472350692236743,884867147725954088,12312848204590507181,10386441279749886294],[3236750871950120562,1626567962390839858,12775493835116692484,3208853206836543088],[12633803273155498774,4856773801264853081,76400548915056116,1536444010576836684],[18366277152095657258,1566566155946726929,11432515142303435447,4335665143271302711],[6363350961323034803,17822659930854356410,5556771061753319344,15537466047889885469],[9893678356860560884,9129586238629295495,1459473447274470201,13582081049937969801],[13021614397205398593,17558607088731820574,15013914884752411716,15861469125389946544],[10998897983834398223,3151559114070881655,153939431653858321,10809925308765251706],[1249630278205346623,1769555991105569840,12708676701668838039,11268826412609983085],[18180068319694705854,17229197253619489004,8572751661269257568,16873330514157127700],[448125002636070877,2773014736983681262,9528267107008303947,8088748813998884349],[5086601171958008045,12458382555145793337,15732311498198271149,13211441807795166470],[18432205470332590902,12575124689041144794,7109818802931481560,9183703985273843642],[12619424513469669861,10617971963302503172,14705061647082468890,3109341683512538805]]},"setup_query":{"leaf_elements":[12686462412268785620,11560500129036067135,13535763968317173695,2731513620254407976,533970591176380754,11839911186097656514,6660253816065246549,8252331549668720219,5457534027162191475,4539495176255760517,4179038952962558032,13812764296401209553,5627148859980394761,3746671518616555140,16151952607457234657,5216970002562632719,1448269529010478048,6774049944080960001,4480437952312009470,18123959510261762094,18390080864996614962,9124666057791249192,18268258125908814632,7443020189024690761,11341950983890133295,5215752329363217207,16650660418456438091,14270418089608001052,15784474852971408734,13858196426218351751,5832002266895872629,3014364908015218146,4173576278275134713,1730231010126783622,11602515462436475261,892909254332885246,2784471581681249308,4535454136100323655,12962914762000556143,16412740866386411239,14654204742449330344,9035882410044673727,15638441103318259976,14106674520756899528,16683809559068358656,15216639399692024951,14163391146099066024,15871882741739380128,961867905758357954,6123402990323320579,15344736168749244092,374161474632845686,8396900304604933532,8854588139004146574,9734692103118495430,16635340472261218350,2653056100644692807,9806811496177935053,858763155509486937,2561440331963190274,11588219765723556568,15574227843957094617,15300082978247974715,16980899325186149518,269494032683211226,2535325914980401465,17042041149285685206,751352749942607277,16848797761965449857,13344174538931783058,875112367585587397,8570530478942981640,4602510036592206906,14854905526670003109,2263241401980673941,2001898248650831617],"proof":[[9415424320296778752,13998820299972638796,15520382878919413545,7024675049024211004],[4800836744511112197,16677165485461219820,15207240276527914766,13152587247062240296],[4886945690798591123,17213995885864146429,3870923085261051490,9847115232121167110],[6563694516325492738,346129027750036452,11919268525999678308,8738059947981376841],[8985895084557168004,5530776180349251488,9951052079443465870,12974680900123988562],[15083834105066726652,7754087022591276300,17498722147117156107,643666950502256769],[4664617936618921647,7143322125674459059,15159212754316063887,12991713625653367752],[3398504761266261613,17744606635603349439,13921905214195070024,17966280036197518466],[7310978004818135474,5218706167198694674,4674565403763597192,1077561907829705641],[16915941218297031093,17475012459231310162,3968583049552562060,13029338710142566631],[18293490412941091110,1390725997304330202,12056089113103175600,15986892535186296546],[12897138754493246752,5986146021103955114,5142672878721902279,1329930864593815403],[7494207587585518310,13784957192560712146,3260782343692121754,15362338366645051469],[2499945971927566218,1023015734325763537,4949670029506815677,15592594261713392394],[9659591934681047488,10660880672364701145,9511680031694915675,2451763933688571800],[163154039032120740,14616872330049232269,12264439720212691203,16709239031643798644],[10954312931933556185,17917826701976164966,929786890876172507,5623892717193872906],[10811791851027182253,15700278300460815390,8936044427716652456,2000021736665231139]]},"fri_queries":[{"leaf_elements":[4238153484265144581,5952803367135491536,8721096952924144493,6450445751443428184,10120357968946116050,13166492529084998098,16251615872152288699,2854963582186662193,2852640480900412354,14857888061104697451,15951521400046747226,14352206151770377689,6572265529233027681,16552380759926556500,5210320022425421811,17418979880192352315],"proof":[[2625721338071829980,17000785936714786677,17123318880464396731,1345139481690536350],[11806183335863835050,12262409247383766127,6288604879290832975,15633222124655207681],[14429972657105384185,16909017596021897852,1607772399617342064,17992912315102652953],[9730315290189107081,10581168430217809826,13495595811617118337,10956633966041162999],[16779278305349699459,6301684526099148834,10458638657932591262,11414917255864874426],[7820837049124149329,17368233957149387945,7357934711649777164,13260354951490802082],[7846909832825916400,9024048171443133428,4653322834345993848,7450069678495255666],[11084482868195555801,15639478159347439577,13392716648881750507,16912804398543031598],[17290372951037062932,14328031703730139999,3505644994525315839,8972624169609266734],[10505461477390413682,17864356689049285818,8943968664559911750,4829877714084975978],[9266186789895687291,13886049167469851142,12112576281627396138,3997055931557962146],[8854318553980595682,8770241306333582741,17048911290318018600,18150941203231852054],[16603767999767930079,4594664206557027650,14970989720294810605,5886747984618185414],[8030061943330190751,4107675586318216492,5501925428194728661,18387262650807369513],[2667981761732455473,6256365962792016275,14983328543872329548,387158731141170567]]},{"leaf_elements":[320650407635359703,1659942582424158167,5307281951222227418,16840456611580568876,2138167400898526215,11716446332551950295,16989732807660599671,18395321726751471467,5386276362720927016,13261595581607271165,3154563197459530987,4664275286857834337,16864225433427227676,10069121554558973962,4426391638755667101,827059599655303735],"proof":[[15232055205874486972,11402014827697960407,15853130278252113841,16571528629593988411],[11103253570359802087,4161153996695243906,925616848180094515,18444836103242695023],[1778931418032796023,5409403785948581006,15093610224730145652,11115055143238615013],[4043014038410109478,11170022418252752300,15050185011333732645,11433639973749731169],[8156019176819970226,9120744078623541305,12262203462446913007,15220545648228589422],[3594902426330507288,7915508381858444706,9052479023059126696,7502293601578543761],[15907602092360696132,1186703118667832196,14875862251924066942,6334764430334413326],[5270665316918969406,7962355486987523321,15269960975506003347,11671879372663078602],[3808885049262375829,10756509134653348496,3738191641508333158,9781512556395352322],[13567375974673585763,13710829749964634636,16546180100443863530,16515392349220305481],[14192466152768164886,15476647203785900731,11529873850925404452,12879758649161871039],[11891583495256891883,7411330268184349854,12260568546965337305,12562237245585858198]]},{"leaf_elements":[14820746073524789771,13911511384722138516,13794944701163046783,10058292983890551805,7806745622321331316,17552081277656178636,7394091710531143413,3694320059667334412,5635760737782554203,12603719430882883029,6160158710813415910,1685178966080339345,11944458718386556532,15579006882435429908,11141506965487897995,17553564949427081700],"proof":[[5282332476952016748,13260457640417854403,4620146001103301992,9203125274233405275],[5872623676246052546,12548236142131196480,15869925580462556603,10362436355864381937],[12428899172934055816,5536986227752149711,5910505465932334327,8873172948087944180],[9151509115678924456,10079527457960333930,11921152957752234111,10972091086860747010],[6196957591961708509,13415596251451261740,13097258912699907288,8039331108458720750],[12370656307104620944,16766853510556703280,6963279264188274435,6944155578438449275],[8875467647244903144,10357364247864684635,9711400013997108962,11013005460662157422],[501878487700198971,13943717994252837586,8489807884587848837,10967128411555602974],[1726119584306404953,376027092172092408,10328309563468502561,8904568018818210655]]},{"leaf_elements":[5200124287553758598,2342564162276334013,2839412238632998081,1975239538283571354,2016099160732596371,17651558437532124146,9882439039884253066,4885343647645967783,2293992149159643371,3346570749560272194,9447027549790534964,8668123606336156520,1946767536417260831,1060600399685084954,5971582839314066727,9053511958424418109],"proof":[[8780832574109503821,8956148958436431580,11979287414635868067,3091711277221540060],[6870791739347004326,9228340520797177399,5288850404488489274,15125616817993998863],[17424913616742808360,10609715514922547848,1677274998290008818,9882622596806999309],[10039002722181843955,17670999088907307054,11365917948587070542,14719270096815896697],[2699471664512790096,9026914074407769663,11851207158025668519,1618663802579837325],[12944765237308164913,3508922314624476777,584361125437343553,9948346116839394642]]}]}],"pow_challenge":0,"_marker":null}} \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_proof_4.json b/crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_proof_4.json new file mode 100644 index 0000000..0a8acfd --- /dev/null +++ b/crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_proof_4.json @@ -0,0 +1 @@ +{"CompressionMode4Circuit":{"proof_config":{"fri_lde_factor":2048,"merkle_tree_cap_size":256,"fri_folding_schedule":null,"security_level":80,"pow_bits":0},"public_inputs":[1961802424684827,44478075017541700,68433799240021256,10969447465159162],"witness_oracle_cap":[[4472019388491310447,18153573944721187951,10698216301195161638,16432796343913576692],[15020308245688675887,12760570394606078569,13877995979173949130,17744940953979927850],[8331896271970245093,8146389346079502339,10797286697790154849,2651888074876663354],[10953862414260572853,12671766551468886395,6079585094061265825,17449134195012135470],[693445178118843853,11051126222429657965,10744476784101739718,14458028109243953484],[9993417483167552819,14430443018369138912,9708597216940615017,566979848293436706],[11869482091457483915,9282776358606120881,6843306749828532589,11887297336521887534],[14460379220394788052,18112570060453277634,11749015091649943353,15036075678487137466],[17828774588688455458,4181380992469556047,1304043108683723227,18209703361863386545],[7538558616611831249,15752712643461504178,15413463067272303110,3909455337929462891],[3423765228053858476,9641363446545085122,16110743349415602352,5641097209511415805],[7826312712441957770,4618508965442946461,9117074738749597250,8363342370154956211],[1883542022583601291,16052045558361121985,2792745739943443969,6882546382161431814],[3337845950344359295,11949555535109256072,18283620140950989802,598867998095840217],[12289564660380451613,1095972799358028366,13858115885879913051,8131332686894288923],[11544999690840303795,15237010924491138876,3844569686499581688,6890752080301285028],[48237151932569422,17098749371805584668,18353270559826953297,16372300471801361300],[5944308618327781617,10871960570231761560,375142419155545350,16366202542828771914],[3074276592894274561,5422513105066139325,7555301940528677791,15445286813098331668],[15628167592561763993,11431950502613040374,6505593991444963153,4376453734541252381],[5929366142835870550,17202903239022245378,14841745203688325352,2508904479542776257],[2253234729920852988,8855821467432554266,10478031617728978407,3189004720321934512],[14714479282023838236,217421928806263080,7399706489308739227,383275687679586654],[620968818025243141,6428289012791248990,10056997116889970389,15212120928889322624],[1702931209870313168,13123924497238548317,8262709440234631759,2198699077382115948],[3594008776793699570,5303602236536837411,1138130511606472255,17518365813540995456],[18064406367590780629,6516412694137912585,1238357979722024061,9346444394431623166],[11334201968956334401,4828404896729504953,9949063657046433715,11097797150678261903],[4418595285351211105,7121117879347899974,10487176527540469408,14351114877139443792],[17804324610119543846,3933430837846559403,11052303539225623235,11280081510279233318],[15867138572309996043,16970255066311976550,1206266470207281260,2218586063488884076],[15451127088816077468,5743524873533041197,15467015083992615549,14232872966837416297],[9928352708803156630,827151713584489605,14002097233488480122,5184073521112985924],[3234602498282274326,5684050793009938506,11870921418456830482,17217736693668383808],[11339010069406717671,11599057023313139561,9158348948112405678,3336230402480289811],[17326608903311777481,6620043631115121898,11612726747060614034,9479680997402199564],[1922253552767135626,11698488614751343222,17737597246360118825,1369688162359261807],[13550868340174045761,6213031242529240748,14916878735293406102,4587099181221470897],[13264565010831209433,9219086609613061918,17385879627974565401,2496328958703158670],[4196695733492447626,3956403556760417936,13518377521316807975,12222164003919489327],[14967371096789122169,9089319013807466280,13420634700393318852,18130473711860350712],[1072875441431140048,507765723772227961,5994815329630160797,990270031728118472],[15840522821989099492,3284754496392805165,7999143801028715387,16305091456951055195],[9101616265550560405,2530141446532760930,7937713940903601500,6214399130693374792],[12122815196838798926,1188811858018388752,15179209272046807227,18280234700100518312],[3663027090254366269,14763395782288896285,4802723399607041588,4407358820916887123],[12071642470736726131,6581984312140701617,13998354102171982361,4870284073792812999],[11668029671559269642,950125687648686286,894297269630910924,10460126016716406650],[12406046835128871667,13074874865028151328,10857247180597885068,8189098128071986933],[7519066205910366434,9626269759645077980,2785095384113497943,1429047233350014136],[5980088735574778799,2467056992605788658,8612681604089136119,10717157419132421099],[2338744332664959086,7790889043211569249,13047618231124910179,12305988640106722310],[2612558704295533201,1586017532071048174,15057737954616525357,4023033211753634374],[10350514187707082212,9321861204929218524,14927584713328173825,14989871321644035099],[11292327558564745473,15250169057651165781,14800506587338102091,15602044068267072144],[2529712650561358894,2681676946665746126,16741441348627598985,5756824220900835939],[17994275455651547390,952789636803893481,8742898192051107083,1581001023910218908],[6816945712585050831,14784617456549345782,10158948369814901425,10812772071846145723],[5310783954166663753,1726244938822156125,14498553074649352487,17938797608722629439],[99579189658210515,10478840116059792354,6098427208561478778,13735659247743331325],[13379846005131152641,2033794785015921232,1729259096911899445,18054601193993051923],[8886372666123456608,10591980381609387988,7125763388515432885,10337442092142877906],[9805854620306097843,10542955132318746089,4110687946855191221,7410572029523088182],[10933206106328702947,376526661527929862,7555203791165302305,9317517315109110414],[16177573151087610454,9011551624754512015,3324184926244399978,1634590937658358079],[9827933257996323981,17125551279777488047,18260847951055192978,16719661840697057842],[6174776474889238907,6801967162387759847,11518090727586488563,9762670639321237828],[3793889508794081219,8317949467659230220,7101304514746094070,8211658542519542437],[11733271479108281388,18223077454328406255,5823774287738081795,9010498717679427293],[17443206279491400270,471131638721137197,15530948195130304650,2294322304096131085],[4987697071937578058,6296034441499190469,7677343981097443161,9135664658362777196],[4600400107749412456,8673979466810200134,1384371216824608454,4898049395814422786],[1516561958331034881,13723648630854949085,37951249076471651,16730545972836986283],[2736702970632145341,10804330981974787886,10769678439533073061,6283103617132746365],[7565312845926231055,15386027981863192491,3249299198104508554,15052414467477210146],[16464684936985043857,4807853239931006100,12473510634756193710,17372447452383355581],[4758485787179694380,3992443763044964243,6296251505691988535,14757984713493105427],[4558821422486433617,9914171474185760762,18087285600669385073,16239131769013036528],[17332905764571119583,2062545424818726246,15860987574243368393,7287923131358058283],[12380095629452029203,13255410490979606821,16223966932955981672,1999012944998879686],[10805976749126111901,15418852034009766848,2714273959616481573,6112606324428044987],[18414969432197483035,17313965127343468665,2353810151507364694,10087556258147111442],[16695246533404704051,8269313637683394083,4898136908496165008,10697446160103613035],[6814450568564893010,6880824246021157694,14739413334686859076,34687354570101046],[282133356499054107,15744862553005006004,10444518632849597390,18261722766183841660],[2358350037594360368,11589932226053907995,10783636275385512533,5543871382088312258],[6289035234537965539,11254069616765325353,4886324736414302621,16531379774050147597],[10601167847574323692,6433264460672382712,8067503418449302315,18426902828028383715],[7492804798593337484,2498022828964070313,10035777328778989195,15727824965389302778],[11503386891651162872,5937927359467567872,1138930558057805282,14353691664231747064],[1917740714099222400,4161194899406412746,15896541419140716806,8670631092152904621],[11146022093858421441,14411236664661663292,3003531287163965930,2868685551711563204],[16287770093606087496,13615342935634958253,2370415163314203512,6106103809586653308],[6805211367216766822,14376677901601214936,2151400906249263354,5681765567548883974],[18149349889344399464,8735417485331079261,6131502005520303046,3128179124415328075],[15415841365126438656,13956262109588570608,4384563246022302446,6340528252987464870],[1876705134691903906,582831716612945679,2258973115912625754,9141638890067568711],[9386513732565357445,3784300550038308072,5436527000969705761,2902485952855858100],[13652276488794974951,11224500475719531023,18443866954067895748,14592215345665233825],[9581856896098627857,10753244607722541162,7999211683986361609,841767720276220658],[6593509568727926190,16427998815190426105,14806005175143337559,13849595581184620576],[64883163062632534,6900097578743288428,12163540344694832828,8850194408582805075],[15154457659054664303,16979200362853939714,17167951379957769329,5481251852506526589],[10256873300828736916,15253577084501136526,13832240943467531439,16988161270563618254],[12288142426761063387,6957879148811320397,2347260049865005782,6274674801690191798],[17848179421499600204,10919064759425607864,2223553994059998049,10301361258066544860],[10091563711897077297,7958665338811372608,16435374783578031166,8016777721517383727],[13066853325302605490,4216226665864769097,13157994440444969587,17484396857463043215],[2765799368401250331,11435104286927251616,14707329763832470411,15825158735573251389],[17489892798873151106,6331619859825252027,7821536009825979794,16234506080782249135],[18207670671604701820,9277970049942732201,11027952110047808031,303109501108041172],[8426282153712328180,2752246007435911339,8802850958100954779,17970475785378183595],[11427997495737864059,5165010583833624636,16448517400429164404,10582414627776692150],[3573787742650446532,14957131881516729003,16183336075131257800,6252404338103122404],[16709747071520331004,15940347464998755767,10877057994487093628,966672456250929728],[15576890666538692210,17778909875922833700,5241513949429367510,9085742199047257252],[7105086263703131684,5417113408393181183,8048169319940862880,6486341269664981201],[6407226857944105170,4884779009025666626,18237579303794898048,8184879390491686273],[5057986177526656889,18129186090898991430,255945136714519156,18220735000875951858],[4382638632156886661,18057953476609002392,14313665079225364383,16294137548790823704],[3140859625664545816,1042007390185790781,4810185171514714385,14999703391431572647],[2560334637888016077,17491776977261092995,11046157379590061974,7506706869013414456],[5069676621902221279,18117883584640157685,14020413989844843301,9966332537601121227],[17067406257797251935,3725870554349367518,11019464244327463117,14098910153029325165],[1046824233118999233,8445997929478662118,9856482875404477920,9089358512087088875],[9744591010521122218,498322843056468024,11378339479115810075,11074841977038818144],[3881146174139398931,10655170931905240927,8656140090249545410,13347695177363899349],[7193916341646239495,4502388714863751929,9836033970517255619,6539551172676859127],[4629615060900685356,4496945535980615150,4492486401602124684,6259592790636074783],[4731844392435532505,1122624741851692344,4088981558964816716,14602466547337886811],[1530978627241030153,8078194867135219818,15903056668970147923,5381939565304974286],[11730593175705641406,15831203113045081122,1374738939811245227,13354559073796664052],[17683972979219495204,1715314099950375500,5120425077257218735,5782409508804661033],[9988437612218937354,16453759966378618957,9520696705516073377,3030482483556626409],[526708567014822463,14892487596948824794,6370111977813254604,13244892540301170506],[14327896413043835447,3901390039447087973,16842662336052506550,17501836254603774779],[4741457516230603451,3726378462236268861,7509421950438239494,3828701111508991989],[14278276902023253513,11198462220057259000,16542531213461733606,12491479077441575305],[9751621843412872799,3710735992132086043,8113891135177056688,543739481199894623],[10546221784716527935,7703035342425046453,14765450311983662181,8043149220074370148],[17851693492999658663,17498003406439043102,9713280767002841839,1722669024739860546],[11885143111622459031,3495707275888112894,4063698524014895960,13295373205050928262],[17043897620060362339,13248076671498915811,10948524538112417882,322810178412943239],[1702293622502494214,13867423537948792576,9209246831257044523,3833524472133253743],[6807590402728799517,16639311511534499632,2339149002586955766,5406827857358081136],[16920305443045331371,3538892860074352957,1937157536129663001,2258983501521374838],[15773130063584320050,13560398821296382072,1779673693202636808,18221764003032055525],[16193908484915115731,14089665637775600279,2378022678067461421,5976104202846142203],[15164327455692603248,1339598164593956492,6485007557536815627,145733438785931390],[1413797674627110734,17016663902369876641,13020310115490314797,3700541252889665111],[8823110890878776232,7713195976873016122,8936565307398815450,5514606653991820760],[13857013880788378472,1253927853811790524,10202952295627731242,650899191899836544],[12007497525432300526,17382396044893217999,3338822463075790983,6964012126321884942],[416689452740673812,3273973933752931771,17742396778927864769,18341258932568870331],[13722556514844386625,11840132460923102132,13799941802814034904,12366337115005638959],[2570625619910940587,5343148473062882240,15446868341754532796,8247647432515175932],[15476783426321560862,6853972193468624266,10319046771808668958,8483572040822919777],[5376493218692014616,1904286032801451184,13121384210374135606,12730325133869664418],[9138061297877368899,11547410494914503440,8765750178180971063,12455401552222116219],[5093276747065253849,6375744210375604972,16831974740290349251,12671120278553605324],[2167976361233665047,3208037081341296512,1095748486957540168,409004727520945822],[5213861066478141769,7465766826621438212,15049336050285674345,13778870714284595198],[12024132439168885171,2184847039656915260,340390145306001920,1892668599093742635],[3004997707182782151,11415711639816236421,2393440011584270052,9558639055224433603],[13575217114707426440,9326917140813248689,7595184731001733245,15411133137634851081],[5315598099791809842,4978984673221414303,13080664867423080828,14005346135057779113],[12231713165245189466,8026822878014633910,14963474123180343682,5861311335631895972],[2462771185114383625,8725777922969085838,1481535021022843244,4198890405438818375],[15472371623426855175,6677915200913859848,5149492594303473968,15656791168923901110],[8088272410077639886,12919614091880967925,17885990882348119660,9615346346330786763],[9017528216233410752,13698129007545685707,3789516013187295901,11013398823936031948],[15837186805851570459,5506521701158253107,4754983602754419381,1148268392035303348],[18279461363721668989,2818952704537951737,10129449222214517293,7248691630771756080],[16823463750904292604,1316194625980355709,15221197410385257634,1542756409923636737],[12312666680353365280,16155465464625906388,15264291000852632431,9415482125487794131],[867400654089913827,9795020405253992456,10618265818657114498,8103115307502853659],[11082324796411286033,4508143538212528610,14087960055786066797,9259484570252939497],[14760352409237737200,14605992448882692793,5514188148087694572,10827323439823683458],[3849963471037581929,11408373828046961016,17100919233371104373,9783607174168201225],[3793932807140350279,5764389390110931133,2128996569533773442,15321037657741472069],[5848828739021474805,8477391686364315758,8225621849646418235,6543076783038898805],[10901369216856992040,14944691657142794391,14174573810983515292,3984876366138799684],[7689021042911755494,7666385245296113405,13683232292677757824,16373669811911959842],[10338326897940822066,9560440042377182719,12331725394004635846,9064433871258174426],[2097401902879682089,17749465646023798821,15000712070635667574,10224432469605717043],[5827381462728576427,5036496919990615832,5639766624948247733,15113451011539967317],[98996833200372167,5826209608059674032,11488471731395478421,17215985732498752886],[16026473890550945070,5677507444504234338,7920746732618672732,1570624956353258347],[1146474061520104597,791856307053355039,7146372312058861098,13505453786816634372],[10927871827278361123,3471728107850749634,10256156628742923188,6243981700742672851],[12496467839959524103,11012305120979622906,4434956002306678743,16328797013592478158],[15328722494776436835,520900864132078489,15256223054890034098,6369043096347657398],[11272316531655944293,17341340841669043299,3195621616222574506,7096337587016812993],[8179494554273551227,5372977433556772473,17313609493355425035,14302646311842542317],[3067629867822807519,9828724370422845783,16158825882148625930,14778859787839171721],[5875956984469557197,10298262094141820774,15976845157436035557,4508154928178125394],[13168997778605558705,16709788657962739815,4402097625157685838,13275631694464503192],[5982252205290079224,15697460493173274282,7579296099246634152,10588046726162375247],[4023203554682198219,1242777655077420352,7880342097166760891,6694323553067809754],[3045714331871290893,14352659852464543850,8705319457565565050,5803649763518203757],[9292091692983665956,8518771180028091886,5763884263523776450,12141597671028825587],[13771148366802990834,312765787308070640,3534525089254153882,2840581221356934856],[16567224469755753645,3183735545563384931,14093368970924541421,2289679070223769916],[964665764437042244,2605922977271914439,13428042867876893769,3066815199142014533],[10069641494520211111,980869762529623643,8214564173811879661,10405324153979043829],[17984497193099990739,14909276304656715669,17784944512205276718,14360512262951823224],[15328929557223628098,6094165005980070641,7216789193728241752,11547449786614267314],[14924668972078555304,15389999971260155497,501223781305271898,16132587686932028239],[832442807667976056,3123514840464752895,15528617931915146421,9183152257573026156],[11262912021285552317,2358165040135690476,13306590427598581496,13819561832784345869],[13282846309007168871,9352229237134699683,9422287043539274660,15222429275458355564],[4147796876470362010,12132431848890629802,17446032180671904538,4111296905905906377],[4671179884149087828,11644753503053124052,5350404647214596771,780944760517175766],[3826925516641759924,4934172330359104831,11865664171366346100,16628991636821246509],[18414891783849102189,2660971573057165377,8806606012023116669,15294457113930052357],[3420760106407768723,13059492913847102933,15142964290646592641,12925397021162519955],[10662706654856027310,11191919512295615226,1938335731114900962,1091742707232012102],[16033648992069264535,5502746015697959465,2064377045723992542,1272766898733685278],[10883456502071225732,6837041302180260544,1131114000262737091,14188422076027429041],[1623257123699614991,148902517323723618,2895632314892318805,7609790635476472344],[1579460809339798817,17710663118069014932,16064990454967086615,12882904029048649192],[12527541362496190150,5480244699033872751,15175536632292636475,6913424560890811919],[8417955313112369093,17020633028653237496,7286901709963551644,13317457972078610736],[8684303864973975949,9947018139844610522,5879491710294395894,12010070773431096598],[7981279087334345855,13867765813342338099,6133172664484343467,142037978343257495],[17707388803468331369,7157054626705149491,6753593078581495520,15765207786298477904],[14265289814537665949,15395501435008814492,2149143315364580052,7851895717872724903],[7900828485786401083,870002970148257116,14064330872023402090,11495944564617160520],[12829284713698265506,4824464339421299435,2492171185901661781,7435296519235267580],[14519685366038699046,2390734301951416450,1228782358266005775,2809591077457459294],[8908791605957002096,16661479998439304102,818401167656929881,7460631523851461506],[15952933667027874111,7677027025103083681,4284010337664241254,7827372220154166798],[3901604957131589766,15757835367393071183,15594644900271642320,15046556263705388416],[2416545901079647085,10455700072498929889,8516727235632923090,921715400862259500],[15065016120134355818,14388616784124549094,13589533981826368286,17873199051464281945],[8755333657007307259,11468634904534706092,11013464259933398033,6593099238540576378],[11648590580201239074,3177941724669170007,12923712992754639258,17602688298585336367],[11960959707231093468,12017726563450848672,7699639361546679749,4160192757013467503],[12372848421847147321,6826941510891838301,11610058411919907465,13625328045779226192],[17775267293866610018,257802642312247874,14602458900260832219,8791019422387930112],[14031273563742558099,276409419270298317,625557338298365232,1782554224535514459],[4415391164971289660,4318489638013183316,6387858470056261987,1012747589978903035],[17681517851164862486,8921531422426480929,15894996370343257870,4541755935107049858],[17852191833292540999,13108505923395896806,10837258967367611580,14840715097017603528],[12284533092167234274,15813465595443053948,7880850148541163216,2253933687897605237],[16337189124992751040,10435685251331337077,12730882185533855398,1497668274527713158],[14798971500653305844,2015625707041949719,17928240967609077533,11617871629360795047],[1207313987523895580,16988770417643891181,17137031530587604900,15960191055888402419],[2283538079705350072,2048673239158531306,3211472665596477768,13888626289222408203],[8165052185685709119,7277337911736924335,13346819398658804034,4589508497082886812],[5122434651125742873,9248908522425716178,11417311240993351053,9333637090795283912],[4110726473878434008,15393620348926942026,13041997569082394658,9934653110085609739],[17006780616663466295,5046219293072086594,12952710537623787399,17143663600155137224],[11840065725393149462,7878878034028023003,11891735908156872258,12525735783090732355],[1681077344371680878,14503761528307111765,9919203444004514228,14275912006136110255],[6292753206650509524,8056334206420359363,907693511443426759,5547259667013584149]],"stage_2_oracle_cap":[[5320608947036975654,17483483957667406684,10972991109152339543,5558262198207596388],[3051219394832155941,9585308864677333811,11947227443989680448,3688079298941196629],[17376813588437516685,11910176784866766261,11819407065764523450,18029856088051846665],[1939502417298948673,18263681482273703557,15564261836626669318,3531628196831235424],[295616787032970308,10622340171348251689,4024946863241879726,12645495009302945061],[14315909613525299691,9713563003673765713,3173471546014094818,14966475114669243264],[13894797879401267795,15742781786930411919,6294205176193581889,3083866393054638368],[17602967558274342822,4728988941081790374,462843097607205310,14113080994594005365],[5438085682288291547,12675835021413481077,9302986503737895196,18315344237040689008],[4287590272215188902,7262418554862092000,9767483363203182590,8715960382105530225],[18203788349642726848,17022862834557166134,13835204490909448107,15845315359372993103],[17897655854184700118,17013040108370123495,17551231048650833399,4096722989713578046],[11807918810049705758,12169892613333119103,8140114849449708807,17408072688915790892],[11936623754354137714,12572291295552955939,6226583957299041699,3624414971716311430],[15867607119857776920,17651650766092411605,8769287500483203533,2231353401003910640],[4267087870180920015,8332466070425106736,10456930030464325010,16387641828742834226],[3187685833445415570,602695833888224307,18110872674942699997,6206592888390439839],[12022250955588632247,16698667572167730521,17948046334892806643,533014066487134212],[11541787483269253658,16566022942990978557,15903408627714310188,3900141801344850467],[1529012431525452798,15957760945347107859,13989186924029102133,10887202302221379073],[16718394442923546127,16727119910291042484,6119550216201527618,12681024694115000999],[16788673996259378405,17186267745763292480,6975499312361279865,5374809647443335259],[7143052444489104263,9404746894898836920,3206807550248333929,14138651016391957333],[12484609923551097001,4739284594294334254,17703515826422846236,601300462989152948],[1410272527646053650,3560312367175732573,2706692042059202598,64162970642320688],[4913191044018212484,11871581476995970152,16972670385462866818,6547774677775839339],[5942837949319432862,764749292287934091,9205038465705622872,15875662666380490742],[17929762242230131839,9519733470384022454,12506302214913767600,2122583011731707266],[15827583074507696659,4835212364623579570,5341061469082970077,12403472838878271922],[15490645443250209420,17377134614155237160,9663481869636426357,14826592238031143893],[16810206937351185554,12523290622655066697,10831018908902425516,13232090101450215532],[542321861301665898,5963663199455138132,431325414560367298,10315306544938508527],[10451189922766618253,10605780457635983393,8730109217847493702,9241469333274764356],[5343712937813399588,3235255277662139587,12181133531918685363,1233347746696062217],[18331769507302775956,3522127639733368833,13758947054977383201,5740721485704145266],[9086954466218801465,16204483892944999118,6461337513872819929,13774297001192174346],[11458592202687469607,14997502110502936991,14052975283670004229,13718595521541580271],[14509131597150373242,7091293047120044968,16516733005981423976,15012938848267148273],[11316329907897729810,17333331681622246367,8180128677842609157,11229337186627960530],[5351549163682761015,367321120844225923,2606422555348198137,8011405544883510209],[2879588553601664481,14972630249600612401,15907893355947019916,13520243506515046032],[12764827396577140479,4092010772417503878,14516023527961586215,1632980554487248883],[10411117199558200568,17414129836509216756,11289496339538555924,14231602005315211944],[11653608949200318873,17614741969597048171,4507043113665720321,608838881099148817],[11246073285169182134,3955511546212761378,6916855994034707708,14430850262344430084],[2655416632817773311,7764657267535760108,10883152122090908330,950208248550394013],[16691053884637585019,18339819311168920491,15457773010990121274,1385561341670272406],[8073143317694397934,6952543206798366825,11448365159694976151,9085497054853822953],[14974598618264673550,16383410590059098578,2049319352438112396,277613557733301006],[13750955245578481007,14124959132217518501,17980468160537944311,13271863537999033037],[9858301649562142026,8108281695710149504,1518236572115038107,4640697519609420437],[8847412933922479443,10165452219007599594,1801358984005895376,477966451838574723],[6092340267090365076,11408858129442649631,3266026766345896481,9904290848342873086],[10006304872690852226,7934212058180022424,14138466360408853602,5283366900235243445],[10249549930891509398,1379437274154303539,16856976920776740747,13785843695438065078],[18147352777821833153,14210316838353951504,835750937012764656,375684109091605148],[12522131635851925253,17008913497324432513,1839009171614989578,11251580626462966358],[2962320668548987179,8071279418712183247,16758262381889345981,3253087383397405088],[806126522831970961,18010432164642736368,11016788192730294062,11230192478787538759],[10027750237257016423,16781040485683253073,16426076975964478862,10062824113561264000],[9468460122975173766,11375642061876641122,3553482727333771340,1022498747691870166],[13660376551622635211,9999857266236624848,11557270636542407481,1073205247784568179],[15520894540827695930,9076510292014460668,11418419212303304488,5078918904239106779],[18068547861826676129,9270457383016339909,10916539894971090239,14853180928222828901],[12095142814747512211,4313288242357475455,2653794058517260182,11219310519006111259],[13604187149932438795,11302942760838869880,2244189615517258389,9886945506262049286],[4080341511001828704,2246911238838272191,15062522832468057450,6827736969377468612],[17178604114714419001,11051141155969331113,6510486050992651447,16171098461996723124],[17419395192453458942,10769780682641616770,8322149009819373121,17916885203238825426],[15838898085225266788,9901877658222563075,12198663975772974872,4811629494948304],[18405901032683838036,11682101390245160985,8353172545872672806,16970801071075086979],[8663541893299173703,6451773882153681671,9140755421503992302,5928674532568500664],[4269012108228088601,12357603389388692491,15893977894452964435,11807406637884612550],[2426467692057201507,6701572292003244590,17595558207665332077,6338363452448348967],[11571986959176425784,5420764630195977958,14560368383585602647,9687396162278421432],[16579916884940561720,1986454765902343538,203071101165653663,2273955310568694117],[2797273056777931026,7472635349178114096,1329171290223032094,2254240817798453824],[9040509271088416116,811015338026445097,7905645055114721552,10671510480279305850],[1260055456026557685,12287626987061926914,8973028271082450210,9159544893690599118],[6175476235312048317,16288832128574461908,3032465174394238472,12483562529638696607],[7095600978643673974,17258555041611356238,10856385222769606402,3564044884765828519],[14656748228338267892,7605450391618562183,18028483141074413690,3312608085788731930],[10409456999519154403,2992258868969773805,4263181538453933118,16036222988390817319],[1181194957916323145,189878555306215589,9985583018915365667,1457452020039901064],[18287267601210090267,2435982202573395265,7276462844098109043,13091210692483968543],[10739433397821825570,31109383493860431,203685819979584098,11640213804625658297],[14194755311105241995,8277534497421999309,10473170190607370368,12282223597342501383],[18417758563330328818,4219174830468050555,13067840651308324739,5626530060813858456],[13639221111541628692,6874095543875555014,15518925024151213717,5949739882612393690],[701923089477459928,14917515113253697471,15323476922750232654,3248107683621124265],[8831252200334922881,15867788854277203914,16088172193514025190,15190387530118332800],[3791911574788280040,18393084269067475405,5450654463877472433,26341916486071886],[13693061021864473057,14748117131998379391,12921587740918106858,17904532239270356228],[13430074106589659441,9196722093188877780,608496789955894502,11390227574307560716],[16213861963735475516,17193797168176725563,14435591177988883998,3536939444076103554],[4283714996038996371,7175802054703405102,7804669880937504910,7841274437170962339],[9238837348134459512,3839698419367742573,9861991357781772320,12370780294622587903],[16079397645693761788,18437592346211725952,12426044545909994729,18092768672648984576],[13391159583817948939,11453159270344880303,1430559886351650094,1026790019016884950],[15158430401063471580,9051549706857217144,858837178257545166,17216001832727448216],[17823677456292222711,11068218125266934779,13497604197429140860,7230192694604271123],[13936509468470022512,17016577398265757043,120244958140944894,5617886862633644182],[12180861843560192219,17475435917310134762,12360112556564812003,12625785877686661719],[9941572084840537425,7396668760680740288,5825966095324552981,3391442985944458727],[13964972364480849859,3272389166416140520,3367266844047215345,15572855671405150323],[13609350236835252301,11225305566290998111,4873290006513774004,13769394685162705186],[2902867806763878828,5859380804292019826,11754761473338599925,11346212347372960660],[8836947942611372056,7106116477485704690,9539701951953882853,1932073842232449083],[13695988209247571704,415757337554372399,7786147019968400574,8984909458569136639],[11813427876628141278,9276694772128150411,13909929043652720830,18198244730321590035],[11186843304554910064,8192940746761164138,9925076122497800246,12925086074038987203],[14055099356221888156,6869215662496281806,8422090607940196126,14000109783956162223],[7276131424043920167,9929111858792444844,14579130771536116226,14190854205233812065],[9977696976824775406,10536267105320127726,14613116590766625056,14003836094120389553],[11823434405889156003,12696153286593630632,17589016071803660151,8962162485954440928],[44620006692139094,15049928882082072613,4915495044349698616,8760039528319908773],[14213016564967336177,12732482168790126298,8410213749340306406,13600539046331125812],[13861273815517131241,3603352141062179104,4295155082014964017,17513440667434996682],[8186995881873716211,17098678002201940861,432580744297975517,9394584216583833792],[5884101371790592662,12158409543612373173,6935280755168584941,8510032034488938016],[14919214722463366678,6177700918871225951,15958092256901058641,14911016843565680474],[3554714873683134343,3406894641117742994,17592899061837602082,6559469632661534775],[18414636690245693382,11028231604928907551,3440366302608810524,8357489410616771769],[211883500835768925,17698052553592619957,10369923487219853271,1776921218590008723],[2207885440994870950,3502440502915787549,17080375945014472359,14945212814275670218],[15789500815896989433,7634324830398245563,15059750025439441225,7258842983506127949],[11772132406905150993,6285179236956967661,11753723740246850696,8289726825359220839],[16894235903917046814,12921754904076505949,409981983691332201,12815408802377406451],[17595854428136115048,4683467687677447431,2907506093848926956,4084567843087142299],[6243863814363503510,5909764219141269886,14140223859787594703,4609881414146799744],[1236695090805525506,1660413945128467828,3847956893488756658,10866315985440678437],[4499375048216415520,6588808745340859002,12513720119002896476,6310683974659695629],[10525051788580202257,7410553477886897460,17948735162305613011,13542552301447832311],[2560566849450480083,16154750000133849268,1683581488834621045,596973259722428139],[8056854663032719123,10837948727746901277,11339554579070592646,339204538259837173],[532669349395999841,4037053140705326061,1741296449636507578,12160334590459517557],[8225728772576055928,17774592506681163451,15734163788570099855,14375496304346099665],[17335045480114428806,10346279049522558223,1705063511262804051,9116078337790053304],[14405719076140269561,12512419428388066306,13173648995931420961,12451969618879550575],[1472651091942801852,14043102490305214084,1282949502144742761,624412958378735782],[1241841257003407,9636862769047952836,9761937830261263784,2184753998248495465],[18397847285218202273,13343662680260186182,8134142866872664581,2838280309914561262],[5748007696396100817,12770898989930750320,1129536429952794325,10108709219214129619],[2511283393484665401,7952874299369272292,12945928121565619556,11625467643233292166],[11880800093874652300,13520747451375976072,16549942906429640491,3580910920166360411],[12077689161927751388,8401373413813927132,11466536725211521137,14204786506250490193],[17535854112208005799,2632110725043732882,6118468512343864310,8628713097810073930],[3378849804078629122,11226624503494760303,11979285643043627148,7557210200137328968],[2576423305536234175,3205453559966178759,14915957529897324075,4694352457190993092],[14786657353421776924,15768058516543050010,805035856222629932,16963089722161219161],[16322842059830636249,9994102103512609186,2114491762183952235,16937947312325137053],[7024899759145399610,8508714489871947361,5806636452212425433,5502684448377618942],[10053685548010863427,2540812313720429647,2072076996472085561,10613068411450225106],[16601367461385169743,14379357954483109652,8936571242845731273,11417091464658480668],[7494197855102638911,11475318580529448643,1497822792211108561,12530971082544254494],[8005414801182745048,11682211984452158744,1972383803805283977,16954315795338478257],[17238229555472054648,15834005980189530702,703975254525243989,14604702516999608667],[11702192190123348130,1072388912787974738,16783869081945847428,6073139465203250106],[16119690893271274172,13035449122725309771,4777638038882849353,12420002767254487438],[8155780857715436309,10190016122541344727,2780973101895904459,4110104605538285913],[6387129428535103476,1355747003329320502,100949710803339461,13408630693686143915],[15790398840212485406,12332402013468774190,9392517977789483091,11612304708528574967],[11681311759671228922,2998141842356225134,275744121777272430,7487185518035378177],[6163141839450572037,13168623933706655121,7939060408695429745,4209359673630878063],[10783588030737519524,350789299095767084,3830831252737601220,13274655076067331212],[11649711834267073655,9969089706079547063,4027124129250118963,6460540284881563946],[10384008305925571772,11423234004704880648,11540829678421567503,18246280683852121974],[12866797349151358103,1253420570577178806,528215982449102205,17790600207951208883],[4063439033013065842,6838419701345802522,8614393233963024629,12652256495944982247],[9067603807347488832,5420398845248049120,3555895310699887042,8036330885352539642],[9428368825565544930,18102418850639597653,9235809798242116081,14719566874682782315],[18054300664158025901,1022092593340675746,12012261690833918176,16200488557711923212],[6074878263974022109,8706608063444305036,10652960576769136057,13422251914538210342],[499868524021458659,7569203562858651641,15781076396932615974,17098954414447912430],[15626956179622394867,6850472860388881386,1141702529112635543,2147277885006845138],[7590539551651232590,128271031339573721,17398553226901826083,11371299945056673092],[1360878657979660586,15517288979939790371,3372053977911290721,51498752123285083],[6066532893719576398,10598509787353540102,17497136845967997603,3178268829138924391],[11812208279597193600,16903611805076423611,14309988115302116129,4959095673614531892],[14475301624216810948,18376528021375217835,1947563988882419675,7474963274022000399],[6570360872512111598,3533059347984893682,16922630291419165810,12114595845579284454],[114923320007271245,11291142157534564882,12095599976487734549,15064406523243230071],[7010186476385047239,18330215885581375472,6438578249109469098,16669434546024336923],[6789586092672544055,11648876465204032204,15305747691908192758,14432705705190854213],[2435738794695098921,10939563104982923867,15169245921228945644,16638406570097202759],[2016485145116043927,3838474453571895805,715435310882393624,9029131164929123320],[12620630030683410635,10829503170474629664,14763026256805859621,16614356552717297832],[2678868048327447523,10058441574883274178,5658929577051091365,18367192544395631844],[3227154013883564990,654412087566480370,12205312472648210091,14558185023758212910],[3107207462134211536,2144590233793864687,2800728647282131242,17652609872296453859],[9253835064809183944,4695401004666800953,9934108147164339780,10700939683876839225],[5111971327298277289,11809643410501204302,3566635580216915788,822045320601105158],[10451153942616498701,3437040518679761861,12587771105182641014,3075228766826530990],[2141368484882263492,7888660397755114067,2350472462246882350,2993088526486198699],[1173131973978986098,8588020524282761196,3610523687162808150,4199759711917939521],[12511073834832436953,5873432121227854836,11375378657655072114,7115249660074987284],[1545083126504368546,11250896566370129010,17047296157646312530,3617692583242037568],[13161617905044243605,12106194867721976842,12219805113366384359,2622083007349554010],[10160864422911665757,13151539539418853388,12883044962194902486,1118522498802201522],[7046622230827692216,16071745343943096987,12250802192439250659,8375447123512013645],[15149978111995169600,1132782066745060493,10484434404271888527,9071368154800931053],[3141168806235297281,1502813865499624242,6760167070740371060,10178017845880279699],[5262065448730721250,13854409740303605594,10790487786881768643,3747039136431389945],[8745958531968259364,18399948570762223574,1079666256537180809,4829243304616582775],[15246939835616920069,3659828300191062076,15084652116090220497,90534803978760882],[10985789146381608741,12006668014985437115,6407540567122629064,15867821306442114722],[9920427551110865259,12262494605607085276,6775741966922247463,1756389837832716687],[8280491582712427543,8041371731070716074,6607581090123457406,7864041135959655286],[14431592760407245701,566518325491223894,12157883181222575875,16020595814273606597],[16289982046793402874,11490162874910791729,15204645038586783352,8012292946833605488],[7501887984500566444,11892130721384800052,15495655011347317126,18378348065357286449],[12629045533450341045,15407261887505765305,11298786866964993911,5683273750355445533],[4407296771227928815,16462911524805663734,12480875869881912469,8896532557649508673],[15371761444893123414,4672577461564702703,790779138032505440,13597656537520261783],[9611073977564972047,580617457008631567,2169246411553296830,15375684607858925382],[16001137054267303964,13777449385158112654,16250220056483981969,17629990768925372309],[3813479475502945970,10098418135086610391,9058735039938746558,2685086801231062435],[5465511719093931313,9106536030045538841,6512364257754599983,5415202236108921736],[14896846094949931929,14209525819304009198,14341596546161544471,1462671589073892862],[11292886775852998218,11420449441613567781,10657404360374547469,2292274653978462911],[3575704943958076074,404426126363838547,589406591175732823,6326693847453790603],[4662668004266238999,4101203356805601652,7699979798652747458,3958182506230700185],[13236642165327399929,8343171828700674972,7273223599999425298,1667556232785502764],[17160360083759116760,3145260250505013044,14142688271558990755,15653098552071995064],[9384908205462114011,4807676373769415238,14658356258986422744,11588428238247610827],[13472201702622341844,1167752654865794699,17893134075534147908,14395436892988322529],[2191920821836780643,13120179914429975573,8477075456964164819,2547999001956966639],[15641302355222017329,14611787109429460695,3493233289885197568,4865695016136959687],[9676178723094446759,9485448066669192974,12836786940546621893,9904769334813745472],[3406023801503605197,8934140234415212411,10583119981357530190,15337602955387666829],[5294276421652159291,7554440290294676052,4898656284319726366,109913104597437402],[2357084124907696378,9820023058295594886,15694987513241660562,10769789902918634129],[10500460078274519741,5609475114880930859,11667862606202119910,7197859085033224953],[2642586045743280893,10390838802036954780,11411975194521992925,12946594473582149821],[1236546105598732648,14101638538076164997,6016329922804245913,9805670586652475590],[9165551330470936629,8424217360713143702,7667294902973589316,18391929867036911085],[2801023492603568550,9513929868793959837,190333986711936009,11794950661322406013],[17487264417908843147,2834249255537674119,782455141972505052,10397237048898878478],[6206773458631183417,14837136530669476385,11239283496612158584,15975856136810816355],[14256412548309873109,5916956481374135088,17787327513544662605,9515319724498299313],[3390462626657992865,13700467662678243932,16544697873828501733,7318294222063529053],[9150357406012268541,11406258206311634731,3834735754588970369,10558768566495550369],[2417515212861248879,12987536309812560191,4255484228700126206,14923803813448180877],[2044921792479758421,16915197811938140319,11883378486018370179,17266599340513457936],[1405204249981904746,472519535702041958,14506234176389267577,12916926400516790113],[4545229956339892076,77988615689357476,3456012495818944522,18047868552842232984],[13227534984738179313,17075157671600934692,3897093845071919198,12910714815226424620],[5676741020668923487,16290198639369896615,4146987813334839160,1479536526600459332],[201732618024401037,501064504516761828,8323579894366562611,9922711096574998880],[15569631042540743602,6450059317288412178,300860033993496225,1845515287498851980],[9203989535044827974,4488064232098800695,3296257491565690506,6656791321873356309],[17449828457397270421,11906793233877758092,13072295004683320704,5846084652737869911],[1995846617614532097,16497945220183350846,6279599451923210731,10205611104316094445],[4873978849714144745,15391350505097521507,553575086735508149,2843561669576986313],[8310887969129418642,4518720939615484668,17065990002212515903,4852652599276836657],[11244978626187338484,16778597274316739211,5757674503247366409,6618613206475735970]],"quotient_oracle_cap":[[3736722025022537877,12934911964479872561,996429820487150313,13121168883665403125],[9830375606125108851,971024480888887951,17991487589022446494,8426488172096362147],[1389987501797716984,1163544507963866802,18008993992412451500,6470818593653974291],[14439605222604163533,10283857657995475617,4654848886653538691,13049271794547352052],[13260640707915176642,14639607805208755231,5782813998496120394,4582671666412484494],[8679462207467793819,2492831767360282403,8097424372613114649,17657042361476187900],[16261156126950590249,10858379130316032985,4358276537509939159,13609841232894117114],[17545695425386457714,2358640276559921774,13427867104048983417,15737293387182581687],[16330327126824962839,13910074150869441423,3041305296075260643,5079855402184527893],[8665788863430000589,3582266699363035463,17805226431797977567,4017113831378860038],[4620078126709527736,17529052898357600454,15198283916457096135,8514275889486354451],[11760352518288815918,3147658584873552032,1393869521256042867,1666820727460538103],[18019829356487194364,10481032025084397535,1940919497823579484,15233017938174723044],[4798065575003573884,16365833065988268810,14875179063250149043,3390158023524361293],[3492709578406479239,11520978299700485933,15545639384517446835,15360470199126861525],[7353869338772406831,16911594924480317852,17433538707472175894,18224438746570818506],[8768866980599561755,16768765410400456686,12440212295357243164,5247425472634341369],[9332614397306387433,11320169169097340203,10756179910855169284,5567158869641572886],[1675708663646661184,10831962632119650349,15853266011484430688,16695738933952270725],[15241744548261154486,10327844283857191575,9681909483442447928,1929442754528554758],[17657055757676606331,14138150755961956867,17065700159343424428,180539391458082677],[1654147326294294775,18036816031100353422,8032784070943021403,9785019953544960599],[4084928828807027824,10128772309222759823,11112977335999207752,9691457633451476507],[1706273404326941852,12328380503251308873,12966680664084093167,7116888378504359501],[5781947171835647524,10908415590308737275,16275718294881837096,14210997827642343804],[10991380996943053690,13391804365268622179,15786847701556353387,5986047762041514151],[4632287020722065250,15150304479800564509,7830523100890432595,12091110079278604670],[3131711993363760861,6375318111392136403,14159946508201753849,8105810001748322437],[5221450507448537199,1117872077494490189,7849107374235275000,12579196241565868252],[14099517798616939643,3147334747949549164,3773271435835442644,8207170216197090717],[13137801374891192067,16155351270988214067,13696739774646774834,2594989645166555692],[1137960109838047232,16656980509293501532,14696675412191594848,935549081398165307],[5047388000803779559,7313755237823913134,5501489909141842399,4108575557041977909],[8363043149112529405,2611718223070768746,11832447227194018475,15608600432421348687],[11884116160424690113,1855528135962156770,4063121800136811702,9166769539482128816],[15208862917016008196,3198456974509255077,14411400692018893589,16061125321339079483],[8289724917204351286,10905111933910853187,6490397619395677178,9025860725998222047],[8305759487142188749,659586702298615712,16966088542744830527,13086855130477800195],[17051540604500622743,7379434473725266783,13646955694865886346,15659708261768947292],[16290230320756931567,14748505639061796364,3124441403870748690,16453948456689193862],[16104791156729714178,13266588933925756232,16766602978871609670,3685925255795682996],[13052940025103323836,2045836787895964974,3943517329161529241,16341259523843792886],[961218473789307821,1196230487510237962,15759722836288088671,11210768688186552730],[13231627835011187845,5242419916172368470,3051855208369555442,7429540370487896024],[9655464366948914097,7528917162711332047,120563878140828260,4611494623374672508],[1998895544217978584,13464698989454981032,5922098430183043731,8353356269140597473],[8624262467420989808,2419769907680396313,3425444240685011296,896296576601513499],[15402395194922073107,2637727944547041558,6518326509388131239,8421950094638815266],[17271167848928156777,320673613369222162,8871976114399497749,11908189664682276193],[9262986436292513720,11025270554314569585,898910369029059012,16110112488148744247],[3647458433428327256,3030312293047507228,18078734217519000950,13160802973420350180],[2503163467265281855,16751116192020870521,11700235152814201721,4033054903236741029],[14662730247941426454,38269407094780005,5763794228898625666,9418173623757095220],[3840149068192575763,158913347197124033,9845539299517314298,2493475641833641077],[18235877037015154339,14918990213103818003,3337430692241996365,1201219738973591804],[9699689291139366533,11887231951112165192,16418642602407270981,16172545603643626968],[3553845474635059818,4699465470557980047,6588680085918645625,11812631934606350697],[15655905723438689602,18180367896371528024,8824193427700840884,5775697851076210799],[15764382945685362803,4773763873219157452,4645956083664080167,15753392641426053562],[2874215389080936822,1495258246474867521,6825852625961433758,13544008719386901465],[11119324000456576769,16686170792373846050,13690052070426646263,17773599037007606337],[12923126576207304817,14353908180071275935,5138401090013066515,5396916563024366466],[7187385123384824866,12619841542149470071,13554749101285030626,15897544319379255191],[1395312366855794285,4005452114383786637,17972913530801156834,11290567157808870341],[6192079285044450131,12070388036555330890,12587413060028724573,12138729578955403395],[6076559862594376694,7868190884337581535,5173962241122021829,856843414093454521],[8624593739925456872,17447269783857158508,1354856309765080288,14644141742312756021],[17373083161760614021,2146165977362419625,3923116094128190671,14379676178813945314],[5985668776095224622,6104903695104607546,14580426088601943017,1047154432442117362],[2835098841911208317,4667017625659812269,10185379783901882021,12196068860994690102],[6761995850017776618,13755753706067791893,10603905478247425779,12940660924838210619],[9603167230602417186,1451457750566686453,11908530601410188332,17236680192437249978],[1118180560943940380,6235736052666772226,1553781019982060824,10604037513975899215],[2905972697526020718,5051219733758406253,11777167206020385322,4119753141952368351],[8089785179371581220,3108885530940596765,9870984508237012894,13059397352220219543],[7207341972092754619,13003319895716905675,1974485341643268741,14276608871429492840],[5885437089704516093,14884271100928654242,6687799872380854332,8853475469309001528],[3735773409344948175,14503568659032902764,17619916154232416410,13552223895003348920],[17337762153732479196,4711796049369008585,5351761600205748326,3997157313771264540],[15432766229552202102,792357309030336743,17160419458840563886,11039566360706192467],[3579732313439497738,1589928698510126479,709329388481245172,10253049484953385012],[5513600124729434163,17533757432229767051,6221156184671571097,15101462231925333835],[12437383935694584934,12560980701066270532,1133352223744935019,14521630136958075381],[15245797217236282551,1207994904611827276,4546665709936071818,15248361074869083370],[1559590430537574729,15425444959076060624,4385497839790432674,4612914020324605974],[857214367333433118,18249865764240616774,17758307470128706134,14141584197999602020],[13863830822058865657,4527138837323551127,14302367043461550041,9265257921574299750],[4377236912514935579,6420371732546208310,10382396633514210431,10778291664137069327],[14804595792093266151,6573242918876930424,9655122578280575736,7695272834344899864],[13163824576711700841,15211872728959269330,6756163742944466200,4230651630893629588],[3482270778984899803,11222514923967040134,13119096581304049044,15454836208259420459],[2029228827691104255,1426103569522431747,11917459215979059911,3599033768556180384],[13224577967727518791,15127368484697982707,10381764944779121939,8202602640823551562],[14587870355608916789,16048950954398497262,1488755645377666143,4122548005828320198],[4380556498502547246,13494958196923845701,11345161496257622037,790039334364373782],[15470713003223929019,4327281390649817794,3608899704425739285,5837720179600982790],[14585768032675400569,11846364507069211687,1457468887573127067,2355074850315085945],[9709908727276169785,9326345212366966126,14678967395464855676,5172961599254576110],[13327410098348877098,5318015385697951330,15970959569625638242,14429037299964367716],[15440224551997234679,11406682911457169548,17057058502808128768,8807540820631659087],[1925066028030413807,2892913200815148739,13658329635873781257,4010352545901786625],[1730822205593165457,9652403070387847755,3785946669109274913,4155108650135217065],[14596236187609841842,391639187814799298,12938072467149435898,14646419993127220509],[2964434143242224118,15467933742620215425,13545209660632157932,4078699583807259634],[11391140678618136533,544327896234023176,9755632212285772477,16711505041250804325],[13802792819174055251,10786212194194819038,4382247210292751141,2798877645233516978],[4580297038554524889,3815435034669583152,15521355268650084510,12824645205323917421],[515619186194642067,3575333277070389323,14294071480078451963,13504317350930543813],[5172888881522296636,4264966565399039668,17094009501001123119,4084605470618400532],[12486639645869148982,11226400039406842378,6807272330250638640,15300239355924665389],[15491889435675331499,17320506389648966806,10022241815966880129,11799841542373920346],[6986237317090477119,16153336254203158077,1125506361469126588,3905382905854230324],[12152360737149893358,17567040619903353771,17634904337165247979,7819704192162028790],[6410986817022950133,9612579601872207185,16406036946454782257,15643349556949236385],[9380268784480887454,14263987619202968409,316384330305058049,9927909366892526008],[15960950162305444294,16260107722795417885,7251159597526618370,3386668051619604634],[2685086160385000724,1054883131722972651,15468389208216367797,10077024557032370052],[6044208682099207820,11012514276906054082,17494510264547696109,614141649118961587],[16538658137790949516,8348686611762814091,2481098433033281251,9295064598288426052],[9143729193988868148,15186128831136055273,1112697184987450864,7783255835496852155],[16426168066239401482,3212733007334204248,15889657344694352901,11115510643736269210],[16025078944964211365,1030373662452715415,11004811174189903555,17120886596714917047],[3786711446024857036,7297184739763364429,10999462503702229261,6809005557959086096],[8105598586330572253,2913432112707281090,5325911804716389905,3982774778234045509],[14094588781936945941,11266923040471500655,9935616933305653948,8479144245810984870],[8164921106744723018,15668716041160535303,3568699341872814564,7321836770950237909],[2916601816223813772,17380871666541550799,5551829508305535531,5274232495050540220],[4136137317933173951,11525872250979588554,1215756959419260508,2333027708273369241],[18120001129338554417,4346980285419282446,8558602296556553555,5886154786921042959],[12450606646018920937,16024370437425507704,6451847606432152698,10183867680500150203],[3808369446788604812,17822820790888773483,16950905501349926945,12602487920753657688],[6659070095169177810,16122006683318534569,9895647682407529025,8271744429537873865],[4742611347052472706,10434900702435404158,2548468690596235688,5932392507143653436],[8191834157410299382,5523885940964616801,52952201020400272,14544988474174485710],[13951275993209920408,14387090979763167843,10860057179616957529,17757281304096778494],[7692266793677303814,16759196727722105561,1846973441619874357,6260467804033858784],[15367069369174360032,7576241145559637576,13055117037362804362,2067985116098045777],[1781279877497178328,3396321021982905120,6601492505263112102,12539392566437150217],[11990108168904344359,12701905535806943093,2487423596098521653,16476493734991250241],[10103919733897098613,9021560468949097572,5536275182190847198,14511585488547762331],[6523577007175312096,7519926789115157061,8616720191270432035,7675480239356033418],[8092916087732531830,3320612076201447310,10940205199502696657,17456516737681358980],[9127314997793510409,6846037981662234125,11916473410585988293,8237517562811535417],[10928412549682007847,17638510795478340262,14849062067758357066,11584580247753903454],[2686484673971453797,2022449228869286730,3661319744670089889,13126813182952992097],[15816106507713949864,11214929060086634700,7979961699542744001,15681750884572337271],[16752731880133669731,10970464316975523352,6837059314816216081,11965749390684476848],[9137642089011578761,4197605643311727929,6886945323997855907,4995640571839054735],[15941873613177744566,16699046093133217981,4891446887981688809,12541810073632657011],[17749145595897161456,15260831824855518121,14036461322185088497,10060663915087630031],[9168321478405869818,7303430166222681463,12405573041519251539,10043241471046820917],[7192447094304302909,16006494795526240833,4529860241572024481,13046907696637500840],[14196121230810191559,3769797708717637257,9434883072611586413,6942588430840174266],[7788114284786315339,11205589043361507673,10549833548646878885,12322816149680516466],[17464687043711395365,1456970934923253048,18126063650414912306,13230631231686191080],[8890037646255102273,3689070970708263216,10931062353076237754,767919208994732077],[13566968551349559278,5016148609272619003,6706102689109394204,13515111410108214550],[16860120922575580215,13723842186973691585,8386833692836272382,1108132701629778451],[185096007363423729,464141456800990604,5540831563073287269,5175593666589870144],[7467898594583199757,12084394641005619029,1403491368854193631,7424184425354808195],[1426319171297715716,4637355519807158013,14018060132862306148,6884541368966988856],[12246761498590896013,5859937159514516484,14384942423244013800,2293122175993088128],[5455118634268166266,13537362246785647214,10354235479283581214,8777566898566245119],[6353299093604755332,2137593613596537230,10469703119256559325,17489738252038629539],[14314012749937149911,15038380243261064208,14120089569416803733,6029734189618641096],[11709008940234206309,14953601350682261066,16734157247907012424,16447160551180724158],[6278757568358151339,6244292263017062498,14728607985549980662,8590395935242403170],[14619345785059704560,189514230617816952,17735720147225390763,6640215249344002776],[2437132327910697190,8123803410299572920,13841354948866673087,13646219663790320384],[7458108812646562225,12748462568831563614,10411356630913013329,4122636372472693740],[4959951110711925418,11748958547978551470,3504716399312531645,5185964324448081600],[8654673480316499895,15890231664419715273,2158604985632384221,13230368881852736492],[1246466996007656131,6914491860370997909,6275210895716403622,9681885395659193371],[1031946119542464079,2764812790455206657,12018095249010814596,13283124557282913115],[15463136995725791030,13757873954682754017,16222405303448884947,2317256702245219765],[10394240105662509360,4061801178944436800,1622703530223160038,17464261648975884222],[479883370907097078,996698891781587103,5301051689915959614,17625839963290343079],[1411938717036428310,13910829014456067354,13939043805025369263,9930547941882779022],[6852527509580949999,5348458348762004646,6158826327352224168,14079191861161062078],[3602312908377140117,11643805610798240971,837051121213081217,18438412166174561309],[9092972176323901929,15675220778766340381,5637494941423795776,12894268472027514577],[17991173638172183950,14041384140265585190,15536254633845718047,7892800678833998272],[12235457381525415879,339706221756635372,14314610774455407202,9184878852234655269],[3569891338302811141,17417758060883818759,7206538045716695075,10110362026435152958],[1851498047300450117,10791732966420417434,17657950831501791368,2647678496814060751],[607609089249744053,945854693292981488,15859391915139331078,7925304460209889725],[14088402373221097960,17837617462900365794,403108696117163466,4597215449503578891],[17694485455283294156,13176104216562053959,16368366950368783251,10968869246539409767],[13246462907240178244,7455543378728200621,15968743809899450435,6444690536814435090],[5495869444576751760,17821804151917570151,8850382951030872582,5699460667910117554],[10121515676215873304,5236333172103671805,13400906028716105672,13568247804693989306],[11592923381014859697,8418954156746538494,4016409493519455091,15547891006751409969],[2733858504697261594,3126599306614637326,9478408391883919950,3944269692330185556],[1271016868050779865,5894662082031300178,16901052811400458991,691872881602170251],[10931652245881487216,10677470787492764690,15740454192965436075,18008151809434863300],[12088237899892979460,13373755216323579086,3766644041562882154,3871413273075339109],[13837800856206677848,7766613626961269754,12007810170324882988,1321270756157416484],[15635007998569467099,1914865896634424118,15257550618412114338,16609274888153197589],[7960597338680167803,7833152618184196597,5237472444087881502,9325722051716246540],[17244937706480615120,7173612485265039748,9375368543842501873,8959190810115676604],[3097693416852955936,1715839259094287309,14169411689538346310,6806701941989776588],[8869482718271604936,16389861594854975568,347999531075794923,9570376102107650790],[5005703512180695676,12808869487433144895,11273785902963094719,767478747888597508],[5297470643565510685,3446447413589693926,5999072973213580591,39048864970238596],[12907972290598381585,17893955592842859058,15865682867647896453,36777517130595534],[1333267432654322489,11097122200317274442,8190263672643129997,2281956624216031232],[15110422609131563309,16932032284175125174,17817318579183016561,6647848728657835687],[16717413711533660022,13273134733443576043,11947685619141468798,6478969650026490647],[1858379895041616092,16082563456427774102,14325343933820304163,2079914519524969506],[12623847219581367047,16307313883604302015,4488398709383209839,1306778729972151321],[6635186812740527047,15862336063157734683,14849647780188487602,2542323213291184480],[14166967276578397167,3747826100943396098,445066230140170402,7596751138239721500],[17341362361394681860,8523065494676578546,16345152424073226888,4529515907305702322],[11274544989197961741,3520772190646380960,11363739017537420657,16025648354328192468],[17557416157961897446,5525142709510444760,6870046023975941571,5338468534462007892],[18303589481930061455,15659019643973402904,4045373590563204311,3413487221763422459],[98344416841357525,3115806691959193407,1286229315698617355,4803078471905136476],[17106333924925816903,12105656483726534222,12775291444792218889,11348562625255658134],[5322221531539470535,4961694652351962090,16266023035625171359,16619399350360383343],[15508063727001286884,12120814810431803174,9140840607200103581,16971063066759376484],[17964026757122237629,6105505716687726672,804438465630108527,6415386521987151374],[565901563919585168,1086289071884377406,1250013387981255020,3864383618852740794],[7324084086134742463,8434241839434565426,2782313864684258215,9602968881149516111],[16775628155181325254,17254231070739054265,12432231402987251923,5055447561857078166],[407726753409267498,7126215197287278598,17543365005401206322,5599812591619809474],[17924431257444733841,7899854349129863828,9478632733135459865,4186683518641518625],[14493347366675694331,5066323555503271922,9320158140650127987,15554874207151872543],[3165405305946816729,604447708975052019,16582715750959360783,16047315530932843937],[9447562660533996790,18227744001787607741,3647236818795855950,16522796029485538344],[4900379413814399740,9375660866906252205,10519488770692112804,9598776513054988309],[16621723946342078616,9924961246720695196,4469890204150310710,5936549067950378277],[764418541398727892,5464722454347052855,10048044838150510424,17320169338479746224],[1325494231037222185,674442160117307944,17556161988034317011,9400038615091874432],[1569901295643999048,15337866560135771021,7887362213088438282,10319299228977491468],[2027841567995963623,7062366242861801969,8743092905567495529,16626981502749997503],[16670449154038829001,4582679516110372976,13130149820425588215,8449365107191017488],[2325755932200145433,3770784623267926175,16556882460539067048,3784289682506852197],[12022318213107629949,14540568981998625004,10969407379725193135,8569799951587205318],[7788138525279366892,1969306602182356251,17694839794687872894,3876669092078385224],[13924215169462252055,15630672210105616820,12065027912926209453,7611322791607279945],[18044538825821860830,11579120840337718231,12475238645827209066,5582325757823970078],[17157021405146099941,10508764408937312926,4169277952565325289,428792794484949825],[3311780726430610320,13649233169105517432,5043407324546488868,12679168847398484200],[17729622501256801531,5958298522457675937,8419433472375105867,2599938564563540317],[6756744478423063991,11076165023684508176,914708774673361528,5734738594437852941],[5735290319292137174,8123110950944544297,11714143870052535164,11203872170199129278],[11787187266261641841,9669608159108609529,6882966872376212334,16640860330780657889],[2986783081892406395,6441396659575548390,13764460519536972613,2042575999737032617],[13436861449539811010,1428176260574603823,17551934831218922944,284616755834443760],[10093752369204146180,14961436183757694032,11486584818946241968,7140008795179103142],[11689847984606605317,3486709742337826322,16014558998661280151,10545367927238176244],[8940893106866334975,11715988917112846112,14869789261664845563,5485702393943431417],[15629427540301667726,5414584298226757031,14081435006690109813,12582214732351105525],[17126724428491319003,17557610912966797420,5419167855382050074,16458778781358892022],[3831228800084418056,17222673770600620578,13860647096307069016,5723855914532343872],[8932264308557018941,2480739016845788314,12370876682334633757,452898620728911954]],"final_fri_monomials":[[8880505689986208888],[2342134586575857408]],"values_at_z":[{"coeffs":[12490281089913070405,9245684800185146861],"_marker":null},{"coeffs":[6550153076920629332,10522906751129430986],"_marker":null},{"coeffs":[11460806635052852083,520759617770767214],"_marker":null},{"coeffs":[16286922586645847807,18371565684480290433],"_marker":null},{"coeffs":[10214222255203992122,6671754061119611282],"_marker":null},{"coeffs":[14892763138049153707,13268062896416872711],"_marker":null},{"coeffs":[9571911383040113104,14676112064290591960],"_marker":null},{"coeffs":[16751173239064905221,5686812848729100899],"_marker":null},{"coeffs":[2427461434658985712,5646454044902389],"_marker":null},{"coeffs":[15337133279873409511,6375463598388792372],"_marker":null},{"coeffs":[17659895395046993097,14441785085370768585],"_marker":null},{"coeffs":[8382855187852169378,1647326365033063439],"_marker":null},{"coeffs":[6630339611904190074,1582291802249574042],"_marker":null},{"coeffs":[13963954884515428039,14566741089011030027],"_marker":null},{"coeffs":[795339690458627098,14066363582349159923],"_marker":null},{"coeffs":[1783078337671663754,17291258695554112641],"_marker":null},{"coeffs":[16010487427301878882,13874037540984403429],"_marker":null},{"coeffs":[5026599248314785019,16153692064828723763],"_marker":null},{"coeffs":[11772677258833111862,189461062283599872],"_marker":null},{"coeffs":[13102820714477301893,18247377162040599128],"_marker":null},{"coeffs":[10234669203452794636,4957316657063942973],"_marker":null},{"coeffs":[3959796991288361685,12361742194225044815],"_marker":null},{"coeffs":[6769917102738618001,6453398337356950259],"_marker":null},{"coeffs":[6599112476839313333,15775957076843881842],"_marker":null},{"coeffs":[13027087204824526808,9596440011351330337],"_marker":null},{"coeffs":[3765569472505678929,3476769888553529801],"_marker":null},{"coeffs":[18115002844813413689,12360361245713272992],"_marker":null},{"coeffs":[419556037314934287,642672377219729977],"_marker":null},{"coeffs":[8502429044562060595,12017451013522530974],"_marker":null},{"coeffs":[1535344333561919733,17466293646066774248],"_marker":null},{"coeffs":[15690939630346927400,8035427248879958594],"_marker":null},{"coeffs":[12474610810520701978,9467147415934986803],"_marker":null},{"coeffs":[17486431960417612897,6842670093360125523],"_marker":null},{"coeffs":[16197895004055163085,13234901787347939941],"_marker":null},{"coeffs":[14834013516508282427,13010427601840845854],"_marker":null},{"coeffs":[9394460200109356735,10294691613535375034],"_marker":null},{"coeffs":[17058335033024538571,10973143443611534312],"_marker":null},{"coeffs":[11735603248316127627,7348691942525469868],"_marker":null},{"coeffs":[761804087382789626,3874835785835133374],"_marker":null},{"coeffs":[598546823303611061,5680308656634435378],"_marker":null},{"coeffs":[2214386443497240293,12393164600002654452],"_marker":null},{"coeffs":[14857393422006369004,15159032009863076571],"_marker":null},{"coeffs":[5866340815128041961,70436109195574423],"_marker":null},{"coeffs":[1568394449611787657,1257669974575652280],"_marker":null},{"coeffs":[340128211203336236,8464474548000346045],"_marker":null},{"coeffs":[11920801399419180064,10093092718694224081],"_marker":null},{"coeffs":[10070109467203031071,9367059958616030653],"_marker":null},{"coeffs":[11944000817198998391,11479647654440079778],"_marker":null},{"coeffs":[4970649116424847361,4330808423753018643],"_marker":null},{"coeffs":[15424570690463228943,16898741365707269282],"_marker":null},{"coeffs":[1974153298215863821,2091751084742137446],"_marker":null},{"coeffs":[2140320726827568978,13540607441812331669],"_marker":null},{"coeffs":[2172084610096161627,13880782115479051715],"_marker":null},{"coeffs":[15699883940921211867,4275192546526014467],"_marker":null},{"coeffs":[5427173077335792306,1706517917264424048],"_marker":null},{"coeffs":[13636640373125607533,10397355311224679553],"_marker":null},{"coeffs":[12534014883544646271,15972272310480205908],"_marker":null},{"coeffs":[11746851636307547833,9544577073681190308],"_marker":null},{"coeffs":[17905135347353355788,837560038451754434],"_marker":null},{"coeffs":[13447088269872769153,14385557434902207734],"_marker":null},{"coeffs":[8287392507434634082,7716585805329669696],"_marker":null},{"coeffs":[8255469121504861481,1428113561245581939],"_marker":null},{"coeffs":[9191309074741797654,6021645906615126818],"_marker":null},{"coeffs":[7765694146100911230,17125769988681098576],"_marker":null},{"coeffs":[6911351874485661845,10919031611877993438],"_marker":null},{"coeffs":[17797646681043526921,15595501199613864129],"_marker":null},{"coeffs":[11915705092693810005,17707110941397929873],"_marker":null},{"coeffs":[3997749696445684358,14782444283355836359],"_marker":null},{"coeffs":[4331339363245154228,3190346586911140271],"_marker":null},{"coeffs":[12896337159273023967,8289424647269940211],"_marker":null},{"coeffs":[7311611831345525638,16928183315507680441],"_marker":null},{"coeffs":[871510485668019492,17664804803899001980],"_marker":null},{"coeffs":[800608171891297300,5726671523409769950],"_marker":null},{"coeffs":[13122179982462364733,12642213879693319122],"_marker":null},{"coeffs":[1104576442492496188,4561065035250638960],"_marker":null},{"coeffs":[11239974497362676142,9737917870901669283],"_marker":null},{"coeffs":[12243581916657629753,16539334597646646762],"_marker":null},{"coeffs":[9509259068994538691,1582314396772522171],"_marker":null},{"coeffs":[2946844198212440264,18419625524894113289],"_marker":null},{"coeffs":[1634632522141023393,8711176908430914040],"_marker":null},{"coeffs":[15992818612211707455,5842121999054660282],"_marker":null},{"coeffs":[16457816084581013039,8011900872879027834],"_marker":null},{"coeffs":[14842461863599544826,4785746226785759819],"_marker":null},{"coeffs":[3093769945396624477,2898379715899644408],"_marker":null},{"coeffs":[1662692166555028818,3752857810182316051],"_marker":null},{"coeffs":[5097583292480012027,14657281930440983142],"_marker":null},{"coeffs":[9434110315529590391,9030764826509200699],"_marker":null},{"coeffs":[7540616331138908566,16165857022649735724],"_marker":null},{"coeffs":[14024060955907979264,11527288695918687493],"_marker":null},{"coeffs":[10329688069105810751,4028146496364836054],"_marker":null},{"coeffs":[18270381535507136213,9844783726311515167],"_marker":null},{"coeffs":[15045369681135450588,5894750075432884697],"_marker":null},{"coeffs":[6659834607158044800,3164076560256468732],"_marker":null},{"coeffs":[4564003493594533748,15476630418973631039],"_marker":null},{"coeffs":[1290867815208599092,18413459337688082212],"_marker":null},{"coeffs":[11091216131546461010,16314849632067876573],"_marker":null},{"coeffs":[15581684817424578296,3808130979755515405],"_marker":null},{"coeffs":[6486580271955048252,16249369868398982673],"_marker":null},{"coeffs":[3877085875292377428,1870541011521473675],"_marker":null},{"coeffs":[1366807651538660933,16191848536847613909],"_marker":null},{"coeffs":[2978491584205637016,16448682253142973813],"_marker":null},{"coeffs":[7753899463891723697,4607042004405737110],"_marker":null},{"coeffs":[16146331405859922444,3751894391940994248],"_marker":null},{"coeffs":[15567123044039469590,15968259442860484431],"_marker":null},{"coeffs":[5401454540038695275,16009361583411356387],"_marker":null},{"coeffs":[17328162096615361834,5920407471021122040],"_marker":null},{"coeffs":[3730427661720444514,11318103515677788990],"_marker":null},{"coeffs":[7290458404852983011,2035199794808456752],"_marker":null},{"coeffs":[15455749328536008230,11357726430834886174],"_marker":null},{"coeffs":[5909676870641958248,13436460748809108726],"_marker":null},{"coeffs":[2210147682235120840,7002654109501666881],"_marker":null},{"coeffs":[5250372044417647105,2543095827925637600],"_marker":null},{"coeffs":[8876320294833107733,17237656856964168986],"_marker":null},{"coeffs":[11761388574356023526,11989369217207950244],"_marker":null},{"coeffs":[15676391976245657496,5998298182275503640],"_marker":null},{"coeffs":[12302635628591129123,8111688590601415856],"_marker":null},{"coeffs":[15443776609371123714,11996024191727916471],"_marker":null},{"coeffs":[17987818931557888138,9360184245999677150],"_marker":null}],"values_at_z_omega":[{"coeffs":[15188461332093271306,9077311381750250491],"_marker":null}],"values_at_0":[],"fri_base_oracle_cap":[[6612994378649296076,8926656274876728416,10080102265698055064,12184110029778225665],[16268620707278136850,3456633076952342663,13389170252534904251,10859005494847865323],[5790213929125366496,15965785924971060748,1408134609992732611,15500862630341538240],[4299890976716074815,5862693223986285446,13785441643936629840,9075784771571456637],[10009884018698951688,520417851793734699,12352207975247878607,7626517289678581423],[5882080542558869205,5626214915929003638,5804173734713021152,2958039614324238800],[12429206195744672309,7621351617935143434,11811352000139133511,12024802554658032022],[7279949630054685609,4183271645016934897,11053569919186209840,18314955058092914469],[1089361398790724212,6507322966911893031,17581316911642460981,3201006243537394568],[2681245124601826805,14600687775787819963,2033201562267820912,15932418459777270879],[11818435334367091589,13322285849086496713,15052895316584168428,3527241083991730860],[8326918426448469388,6115331443837930725,2833858018122142532,14282439029293558016],[546606336620961345,11538015024684405022,9160583967717149218,2954199192372039951],[17684046326601941098,16333963875622522133,1318062120901305529,1832999774962067284],[13367269858725529295,15339536098328545289,13283154170951874375,4176322169464549937],[15368854911809466034,13959180963563000593,16026990499841672140,17726740678852001073],[10370528123613746777,12684803541651438959,10775458450925747530,13199788633770314988],[7623982614437897555,3568490025972619338,6781736118285539472,2042604797511659601],[7203903584510307879,12653326608898617492,13041029220746976768,15140223421622603626],[4497521368540902457,12344920399037882018,9300933017728755336,5597573495557972246],[13683451457295946013,11069505517779595602,9668321932152697313,7671733311365557486],[16785960386601705568,5627251678570739529,17996335209122307038,6970759203494799696],[18176977939229491805,6552693665487419553,14469576340549167478,18035170877237762964],[6969528122542372200,13677660727533102600,15071365167706024222,6789096752222782752],[13919426866550741056,12521290422513582859,18266757471934792135,13159894094793409524],[12005783325336926306,3592669371574874881,3349176266632930752,14823400308616326595],[5384543374699813709,11096737473936538485,15115966645462855360,14774119548142098871],[2829393070060747906,9113523342422200389,13939719598851009768,9207188748441614233],[12081752002788238986,10638906159869151729,17884876997415951518,17578122788175669835],[15971931935461202720,14855506930687621827,7884939454045762953,1636694543032488296],[781427891839158931,4562681082196918307,2983810945962887265,11485605349962006638],[8573195520974127555,11325029313767782101,16452839209728080520,5833430534050704135],[10374455646655043719,7625402346315885732,5301473677093040668,2665543874796228370],[5928037696748373989,40956367354432566,7056954285753617950,13565843813648081506],[3073538646226003828,15669734506122556221,1383170011173376754,15244845354112894014],[6766415747006021394,12060623811653659029,10821901496505767474,10589667573427139935],[18243441852118689092,17971896782095575064,11933437351236905544,7202898177605055607],[12023259846125763271,615682920961139200,5851954854231678028,4610206047005124104],[14727917766795964853,17097321944427410122,11575688147998101847,17330934814810004882],[15019351508093443307,15827074630612643911,3393958786858540969,711681357293713601],[3785042874969114685,14516631062787768903,10046618564996098881,17029344668451499743],[11370325367617385350,12683298564598522207,11838696143634125567,1006178536361723228],[11767109921209325561,7247204436292556319,17488089888304895506,7138736602736992559],[18010188536779391701,5791498219056550098,11848812802841422613,10227064547528782986],[1328177856874700910,12685081543224436072,2012937072071817790,6493098516672268812],[5195024857678707142,9580206140594899080,8806996752719988490,718222861467189392],[4945306694215349711,1897418884518140513,9845686162011456280,12325649088706468689],[240601719358965579,7297841042088415297,17974496996321421571,7340488213758234451],[17499234175857129791,17478706553192236386,2605927970564620706,14498593624472318565],[9762090679618598977,9411841480962681152,11694048841088406341,8859438453581220922],[7000212170476241800,17455154747929318888,5934385929920882081,16145605518037074792],[14111954096158914872,17288014227791648808,3102383568858572034,4284934626412386139],[16634116015590102333,8264929127586548464,10127348669063078026,14260813421998826216],[10257887118034891033,17172192565123913628,13112865620809646085,13174714710278401734],[7354965782536152661,12756519620878861500,13288528945084349804,12725759653603272565],[12018633884996884165,9558470806696257493,1283312842901948331,6247028064607769172],[4380925218776014764,7711650701918886727,12154128268334252308,3890964047486726975],[4119825577098269301,1035858555942523717,1157023771702677676,123672844979052781],[8497785301049213990,7429545831987784984,7242353441966583022,17437599321639024829],[7194000602418086419,11435324998688291030,7769655883283785470,2834004805071433508],[11905526299565373810,3543837306077556714,15513807470595398776,2157272356478397416],[4489138228910303926,3644125418003471778,15631916826102674057,18344110103089190969],[15903222194452998727,15522027916965156931,6890049209930217337,17699481910261675045],[14959432641213379970,17629923756116881538,1567720727107498357,17117509134967443888],[16256819983503270318,14622380528757443153,5923068287632019388,3775262546310810540],[5664345773499635020,11675482633078713826,13481766969749488433,9007272144270094565],[9238118717872107298,3468428904531540942,8865254675630227304,16909592267764288037],[16157837990760295855,13677616887233735610,17157631610260451662,13244361951548258984],[14032805852028984455,3307295414458110371,13228501143062184607,5337342014546740998],[12030247535612233649,4763677495903018295,12141313333261276361,768236387722225664],[2694581022867541857,7433686093732219632,13432648985102435276,6444070845483988754],[6750146673588557576,13962017860167729892,7820412005257092527,13490902413315812590],[9950886964352604240,7814962729976493167,8003639063580492067,17714302631291687233],[11075430134642480087,10816165924724538356,11879181004849391806,11100998428907432464],[18012146849863379606,16730088295588092224,5020554712124305014,17931703056353474235],[15136388113258341810,2996384677220677701,493476638770789343,15639300548691332583],[13177486473301491680,12446825272954838957,12364795231451698039,9545820680428407419],[6364643831329302698,10798090305331035725,17223904043836660822,2159519058501078327],[8878343343827712361,9641265838747999952,17156420995888139470,17878597847998698211],[1690644341425257881,7339353380541586182,18024554663967927753,15037503465222299889],[15826969705235370788,16043079639571400831,981076550008384027,10642113174678229995],[12296654206412913793,887174281031909062,9679710866698572863,10331380371464018020],[4796156147061795952,18155229312507707593,16869525111507462689,977617216010384793],[14125181944148941918,10502352054326677894,7963415842573534951,7599640267379891254],[16614456917753060894,4741341757210446929,16260712009121288070,4971697299191165273],[13052020578365624443,2918207805378333118,12199341550053977833,12765223255142766104],[6556771586860818059,15513659649073695171,161036881583773139,3615328743097148492],[4063005580905674706,12550323331110894466,2891339616472186044,18327793389820564966],[6357068140003990665,10441436016975437466,2088268247382700601,6947175679650457956],[75390702850456610,997967389163284839,15579349749757676456,11237841261126241135],[10754349559213471777,17632711339710046202,5417717305118042633,14622740853141852329],[5791901577294257949,13250959013629361489,6063155543381643751,13545685291449834575],[4384554777851244986,13523370498156812467,4515291657566355309,4825368841815484370],[3335437899319974341,480471012168294632,7092012912071077730,1017933091300173477],[9410090553534135036,14411232164277962797,9432477575390452184,8378245523043275236],[4166751474690230084,15766735664521444720,107566888895020926,6302072822419545580],[9134998206341458967,4735858517215456163,15558504292500427626,16760744990636022551],[12250328448300660656,9234400624300007336,17690880013620996247,13459492321281788556],[4974601412988246563,7701928507323323755,12090372331444445460,15188744437787120473],[12905120201943323817,1995105636951235174,10039761439528508777,13463146656213717502],[1884918269097018558,939911484112621510,298985590944070222,5812695030401690167],[7344900651473240286,8188728207702743010,332171721709229319,12268390126470281743],[17691321439317225058,4540393722869118049,6660693348557999661,10550286877138554411],[5043568726248213851,11717583788447495281,7228724101506272030,12660965989827009740],[3573928383417403226,12084915701096254766,15534664304458730758,8686885219151988562],[14965742269836508727,7168323740495019680,9845313006343512058,11402855653457762725],[374117532460060052,3132122033593530382,11093748372651072968,14356163264804309590],[12536590165080445289,4949155102336977823,10798128417928009248,8290021757486491634],[16430503152831977247,2625351048101512593,15222574676335265565,14108083876006083370],[9342757826712741938,9341043422066995757,10913242306036505438,6475108591689293900],[4546392909661031597,6188488396892176282,14046806725538330170,8436313579664445147],[15597369935685130234,11458261462957275626,12276111922112941996,1590933749639921512],[18019206250543196624,5001521217325049787,1660528192667950429,17412444581533916073],[3865594909867764966,17535863132457190260,10759392141073116366,15556485514825420337],[7649980424895081871,9423257639315942957,2175025737557931723,140716342048250385],[13079065699548144953,2935304186137677620,4835317828294422689,7801451673268170347],[3375735799501091704,2142073575625892143,3634020006548454924,12589883410093052122],[6340312574503402056,13036071078255670094,1505380457368568362,1806819059469498667],[14137359958476371224,16454005472549393248,12259836425125981436,17750172816073767309],[339082510358798382,145927481127552294,15688832985270985186,17472948734198658149],[386527701565566936,15054917159738338345,8353017098379540782,1143169631032809304],[531948748058925407,14836894491548211678,16118431535030052636,5721095319141448756],[436597867334634434,5009323963643807229,8911368773846053113,10007641636295100416],[11091485294812737796,238009345031784692,4058129652812776739,13904329939263405850],[14711940782886030205,11006984611177426781,6922359476150440695,3750897059142524469],[11660235693729351394,14620306049032580529,13282064173141788572,7784128234359553436],[8886181915746150080,3404446050694517106,12430769802296257576,2451433648437981064],[8159854051659886248,14160601482465164848,6648069691405692972,17794658712650692801],[7935101413340741669,1658245614645876387,14432744741178794749,2781391193456892432],[12262882493282266359,3985459865524296357,17146597385023895039,15722572181048078739],[927930165980485435,4046303144575213025,581224858109709595,10454715704840474757],[6282901484839875166,2007273532318252335,14580496491008161100,14797654331612131815],[9831897166658630768,5855702692354653835,9072969915730820128,1576956117885419298],[361928269372530966,17849306924413783285,14556485010107311820,10582794506843488801],[8499114808678170340,11966158344276535042,14357142114114703954,59172660229281796],[1341476455782149116,12897080808664071317,5970290426945473874,2320861409309546225],[17217049985722347736,8454723514282674338,2956600801536174491,5273000579371459003],[16253382946471057355,14246802776772442613,13059045929713207479,13877059678827672848],[15342038991078517448,610158639107237069,1844733859935568289,5304397843438422175],[15780044012224546262,8797214159878947092,6176345227307265417,17415165275504574238],[9797237703036999090,15346929858010454808,11733938483290385461,14800014340992754069],[10750614181223215117,18421807428772462854,10750222236742149268,16853003295141420848],[1042558300421888032,4268308817487691036,17932755557316295786,8841475010973815618],[15799992035615852707,6792350802005713194,5757124412355361108,2852469739897525044],[5111689709194118320,6930545356708925651,1142999789158877129,1073673125568896775],[15128956355985084743,9263510347073399622,4872294651419665363,5003447794394273537],[9873991533538893681,859992902062709398,9678722694347271357,13046090007692337648],[12042659716723690061,8122171536645794762,1622813743653466615,1440467824063119950],[1764039982251302971,2308897702200360534,3210621606524616145,1253338105120205122],[11259772920548383760,3683710336679866439,13844761052452965867,16578287448338378451],[2984652246085435358,1189643929594450506,15192243259064150687,18237036511136213527],[6560672062796304354,5926206102732127576,5904019510541514738,245903221377707083],[4372140362230184931,2984862139378613876,17941896047141186839,16716650932111462002],[13293545851565069623,2493228789138522892,12845167522365064591,1287200763532075107],[15569283984159490453,16276188825986838348,17466772839672276298,16847389594544163817],[9055278028405731648,13596068137226693436,8007427236353085047,8801395100553901451],[3777680301795879168,10763626257710937284,15391482338752465140,17303681878704946368],[948651492001501276,453221774705992973,13857565264840426832,12001963962746749341],[9865123693989975015,2362300362480347261,7446894746829768158,2047750377780892074],[7040917233419227524,11126672540178407077,8709284561681173448,1177139865849120204],[14984479036813561193,4211171240563731288,7316495573665226501,12419787418356921711],[2487738067202622507,4823755582921759064,690442250977288425,12470124187741276070],[5423882165720760013,6791130609464456912,1700325832493335302,5587864757075212033],[10347715244497950155,10553798466898722549,11540579864263186918,1260036580907594519],[15312293786657032024,16617099792244848285,17927415593801711201,855574028008236061],[6741898816987287593,1887337043144064063,10881181588512170640,8435061322545390218],[9310658284044905532,683806839344089377,8074458214153755852,7561289782220628279],[16201609097212870129,15640393130156787723,10096558762787555702,12712795915633432850],[13310711432266404828,16733538778067493195,11535359160704630819,16613009748628284252],[14831356624135105710,5650633082261266315,14818721449781703600,7789226682658727632],[889141357354829856,4750638503403028346,8903248244462926777,7427807063782944991],[2884625624450880404,1871620601439356620,1411674874414028274,4568028199301328556],[16261400182924420238,15990171570111680285,5616187438217888756,409611336226226827],[12274262854271502161,15619176792137618414,13484063157820200295,12201091551405377355],[11034270883136980850,7661771482559248974,15884621212765486302,18329472636940868891],[10849882042097292321,4515105714395407692,16774341547475881867,11952488230494185395],[17832897908857986629,5403771752315297623,17601585826235627819,17201497866998035908],[3029263254257620654,5526636873144382328,5816536449210728326,8772070313309780539],[3680441819621320139,10912549779044927124,5463171022150345102,3945294434879650086],[1067465051278721057,17164316279342356243,9670964258284612713,2132386782921568095],[14819750605143754002,4327999514411283013,14509579350189431305,4266984760322150713],[749470208355505184,15010747783496872404,144862439779751218,7123159139157946255],[10756831628059932238,2215004465259209196,9590541242145232669,923251697463949899],[6227096986989550586,12916607613436458331,16030639740917870810,810030876574470188],[16659259832654480511,13038798534994992525,8349366646343525793,8162085038967639586],[3930720595706835754,8227295043810907014,4830947350129133011,11744750335402192450],[4484954941833720241,17519467702194215652,14064490567679669104,7613997454583544443],[18130324904448895652,9636192717533670643,733763772908992697,8467944682458231002],[9805949002086689406,3550423639474395359,16684481021895021814,5500524125263013271],[5019957920593285874,12146845132467069420,10933354451311827657,12525678172237563464],[2407821076584319390,8381940716305542372,3942737254449571024,4076036557679584517],[8871859680448134852,14243812414526608366,486505708369030920,17185743972848441358],[14000240891112418607,18089491079214131639,9147493614063991950,16036012803976237907],[12001645602794363994,8855391016431144266,12890514359409797761,3456528581324672889],[2816277306958738756,10885916911749820586,5934320233292716463,10632901350628098310],[4008531721173676429,2377406587251568074,5601626043056855729,10236331349176938071],[16546472117391851877,13630311165020122847,12739895412640603150,7500975530883317271],[16072898270524721887,9770990951072434609,16435817098901921380,7074209106160063338],[1302622090171452876,13849362081425896003,5681528319584822,6047409578472675795],[13042494159192008067,7867603063723105480,4574482528744772407,11170421220459392569],[14907214213565496608,15697773682724453937,3266192901136339036,3067189278141012373],[2290781093905057646,9924296866049927879,12582735078312910619,10011296337975459773],[9613254984898433685,4488277594429050448,14428506297741893461,13540720112644521615],[15801126308909960972,13842619871471037071,9425646906077482092,13921226517368892602],[10672043641420749562,7861341733744373169,15312919659259100668,18106294607741036816],[9263671080541019169,5574866679205971035,16847374675677061691,960908375831939032],[10401681554140018663,16093805562434970832,5625668070743291512,11597306176941906261],[7854188694289865267,6940486633302274675,15890954157329505483,10036643372591747612],[6148445841774064381,9473624922947935532,13300646515594014766,5421803970276985578],[12763923563846319919,4276321229328820121,8316560831740305054,14995497054219226957],[16086324992033796976,370175433897281367,6090685650049392235,17190365845319001765],[17514973765271215044,13860824230604855922,18347959024163244644,565179418123320550],[10701371440872883066,11136959772087906644,11624169217161764324,12966790099675793292],[11569322302961147957,12449757410165280022,2296015071471094921,11502964388676225040],[2948734952748276167,17165142892038146514,7751931405824511441,8018103676360547958],[3487455036144737236,15218668303206651605,12374363439431650935,4980902782252233703],[18098918699091721366,1295859107331363446,788571627711404835,13173947574731896244],[16560079523974068515,8881496284086233560,15986984703356533007,10585303911972674986],[2075006664167240340,4929215031375467077,6414484980697174222,4439861629353486081],[7031085817887454808,17575169927042638020,9593539310680647616,3332194170191640680],[17839781302708841077,7683856077417972183,3630927024691210559,300501015585400919],[12756727679112997732,9704402730333297241,9241476789961546256,15834340339809544274],[16333742341650731257,3627451950249299197,6468394046169197896,15333016740768534088],[3025953494232713704,3211043844129634954,3002864432641331166,167300566517206748],[15631704914489888976,1152262908956516680,8066757846294346602,9100884516805931798],[11678414734166961387,12258067884843318817,15664455445408099466,1784406985095053764],[14024531025426060201,8899851904998395218,3415459265361333000,2010269421590530981],[14476170957378184840,15839846904852951734,9938190714350237149,13803191554349164037],[10415180676365973215,15578810132664814708,3337509157624100214,10198259527189534452],[8557916047184303193,2916337068616826719,16606408773169916429,7205949024099825716],[4307775287746298794,6213634138572500221,12769689540891683830,15457695115866398271],[2599527618794568364,13719790540785908846,9223633827770757377,16655900594816121190],[3284847296327611369,17717337710255039492,7721026939503908049,16648360428520142010],[1644676688329363601,17935137624989994413,9231445860902683564,8763656460959690367],[13877055763066561885,1698690842496157846,1138924093199739777,2880340877823180455],[10545488450178945277,12054963064037522870,17379280871719725863,18373772082778406740],[2056010855971419137,8989043917473585402,3580886168476220545,7898346795252277257],[6850252688218057165,11059902220582554740,6814222449924012057,9056061564899370159],[17798070534046263616,12436229876592890903,16055991649042583074,16768057723653507577],[11011432843168236608,4514527452856404020,8346706370112748261,3731660415100814402],[12505934781616721101,10454586428005263432,7876768814150459927,5301878097882276253],[8148193311747564779,16376134544749545778,1858829551785370426,7401105641464454739],[4576037322974146135,4963042968673579178,4490351504767682126,5321357708350928903],[16118420649474731556,16150538011118281708,4190380459918923223,7969988812248387200],[3775000711949505376,4243090868473021910,16088782634673996685,9418339131975586022],[14597065758315421731,10003228238011161029,3752617058907576872,17305918127706145726],[440634044056130705,229964870057207443,8025281056803963148,2656419907832268646],[10278921471209962440,12609081382042444929,8326341037213289739,4293179897799254007],[910784703568890213,4748523705491634731,3925662800086116892,931656148567593709],[17047644226041712181,10973744418373053250,8868861319229887204,13866509547619318334],[1231725400251128415,1803245832793617220,13169633153898409422,462980060956781867],[4217576328866560896,10658458803189765987,11794431928867368467,8318582761683586117],[13857503617837704734,5520018887160895962,14887843405608668492,12282039040728326442],[2303525575276710077,9088584035231375380,8035056420342817768,16786281003751858226],[1033860516745210335,1108059920002102200,944330623242207803,7799422703129318964],[2898411053555511136,12238269080636105949,6565545487079669552,6538632354975439246]],"fri_intermediate_oracles_caps":[[[7668027407808045380,529917014723040131,3384042145835419627,6735535628660688430],[15383001111815517136,4511289264592468202,14029051542900597658,10537973346840830029],[559907952792217018,14786062645843532449,8339325553638936543,12257637917463298413],[13287657483375795379,221483540166189091,16516814435447476342,14748565305795567820],[8816990358638303175,14409476958369952755,5556637273641530671,12635056753146129780],[13123013672585740057,726286736621348792,6360557913635247284,1764747464189657840],[12845750359851391300,1941013911947412644,8765063579315282809,1683608937942745217],[14521047495095979407,7539394833148091764,15806323046225071179,983354481401601474],[14823320032775040065,16672981640798388568,8828577709473403616,8316515969839219550],[2133992365047865815,17518628752195472545,10590552955967709856,16002875515941966639],[5908992570005277871,12683362847312391894,14595800402437781987,17760284448853221153],[13433899883981142059,6024290853526189618,2724225552334544373,12261951828575754268],[3240982019695137793,273576218823334012,9209265685230766971,6018639796397204714],[843526588344575944,6873554082560934906,8272399078115956599,9976182998978680806],[9899197646298885975,2976876504140891079,8035730839252910522,12392031936134469004],[1467090830217194693,5829867847510746324,11921305150620599460,16646481360797224617],[15466344896880037551,7753840695331225036,14662991466402066876,8716036245177920758],[1374684384792584450,13598160674550885139,15012219580264792554,16368040525775871556],[13654757488057401564,17606593259830958949,14654533781233398560,2939312929548703108],[4724607381137163701,14729628091834003902,4243447712714127901,14462945532715381368],[4487873669697820264,4879930093130637567,5190064570526551616,15450319947649855130],[4309864800597817253,8763764072907293119,5029194872968754568,11527293355461441587],[3693397744545265203,14299044624535192980,6519079824542192429,12331342970374544028],[14400867601285391483,17160742888587892109,16853667466725777642,15227759082708551531],[16485208348722067312,353668373586605690,2194695995671839357,9502070094641869242],[11523877790984114741,3473669222536466951,5255722810251905671,8923484841087799105],[17788525893647571254,17233731227551381361,13310822809943420374,9586903939448713784],[8104132459498179286,5989064389034745817,14813649580800035576,14077316379721181320],[6658603986839427733,11117146144701532172,10046015195537279939,13959078944812858544],[12285767319304645232,4948388640345707768,5116958857154110827,11828457706820634010],[15464614638620246721,5892563422453222832,10739909974779442377,13432226001310514010],[3295249539285457215,2730370680888178030,14776626595465539356,13249160069984005945],[7503230337125036283,14012464714993345042,16145370644378169954,14289692973100386778],[12083197200413456202,4314680565919733884,18102690091600367042,2279039233356959367],[10270129984408252141,8114845744439702841,10157681733874912974,15991242918970583940],[9482165973599388624,7425336169252307414,13134889970968113291,16692144587978697156],[1181615529531714806,11523838471803593954,4818361726458439891,17250058029335882123],[13864179216672285418,4546907229594365269,1817274662172112474,4851952585661619532],[1907967933941108045,6580461947240188081,5302747472390664362,9480125932868136775],[5021760760225610172,4482469348551001643,10251994361309857727,17285986317753291923],[8581282806971544610,9220037693655614921,5077298923998087612,3952137842421658177],[15981115193302058075,14872015425818396016,11141578099566900449,13459683753466337022],[1433494796961303996,16895676367356183852,14141206692369914446,2653787210990581466],[11992602382521419583,6877343574118014603,4001880976922937527,14399856404468932293],[3036560474982164657,6209289570921535670,1314338946255663394,11028175230231254516],[3320002352524033070,1645659083296564830,12992200485613628578,5118039961177876042],[8818763451160538168,2492682664437395972,14492466647672179895,2550488126429132204],[17304517609225877878,16839614034450206890,15228883204068711080,3084852324681754998],[335242254193993968,7062490193917159559,9055811687371563489,12090566992161160314],[2110072515857460843,1572101779081716873,5539894931922660159,16156518909069986709],[4472216966390058301,13294967256652985730,8266745638865106626,17489803446609011036],[988289849256476450,8843571079682335891,2029878067377414219,9686750572662608029],[15581161200164034495,1495556217651516171,13632730580915505191,2465843979225564519],[12662780781185689310,5844774397415971366,18431002517068544575,2431776387608163225],[16872953490229786341,10950770919735368626,2379818434599925469,2971207641378193019],[13023229362243578672,1435314278676557979,7211776139701241645,4118138791805076831],[4909905397705930953,5170514759474803062,9898570970283383403,18245876116491918471],[14793094297164461649,11724341416649713614,12288708611928003120,2077114131651938070],[5233200345466073002,7664413326814714149,16864293285614756740,16266968522760238727],[12424133032401716782,10840303901510337717,11796951373867787230,5156404108768769778],[18210681489575546610,2143082437283332227,11388973731705242491,2833816033083200344],[10913715559393115108,14692996960830468774,13366138254856194895,16294057929509523167],[1851094828323926661,7627681831925283957,12498143103944130011,10169223281373754478],[4044480964100130800,15329475900230346180,7409574806354206576,8102796050954244258],[1496806919011693079,17692000424513594503,14932844600923001058,9984358767075156178],[2502620566398999996,1692005132179347905,15476938605918795926,2283754770237475149],[15127680821855880724,14208652918121619698,5381377150562187655,2692467636869083407],[1406410934485932011,8837714927690163633,12607607304645841951,3330162464684280907],[10520758205485816679,15700273332402156524,7639819801074348312,17011644299153824948],[9559915521034261984,11463681661040005152,13826612753710625031,8381776265675213576],[8110121819437788004,14375865222733974044,1912819319918240618,15339075400015656985],[17115640612389741564,1315668345430367405,4047073437116314561,15991155521328572519],[590664014602324494,3313566850509925860,4020454826038787940,7920085315499728772],[16298952934243686008,12888138805248806294,13514100857174298544,4130891039401032938],[7978948223835854606,11620761058426344309,10961114026586590871,876203364276552245],[16719504302803689095,13957907884768765083,5798496004270173872,15445351447257219514],[727547904316298089,18236394935595772623,5975362579133815818,11451305567790019925],[12371787360475764120,14469845104624230091,5153881996543680091,6317049862410546137],[16451489508490637042,6469832412818662729,2116469265900804003,6539767457677949485],[13361282695146500290,8148815471641468882,3885586419325578769,9165908864735537610],[4192440315987973004,13007626494626676343,471427001599322203,1413325893563988194],[10775031704155750303,3189163828131955861,5333437695742673629,1781296790870969684],[12079123830388554784,13171562753034102913,4259749975166726336,16801799450253874097],[18067772574084590687,13778462235234978605,14865260164177535943,1972967658877167239],[10693659384329397481,12740020107967253028,1383894778046590952,15760619415012478746],[6286263515592105259,15377286577881026544,5456858631868958433,17712234121661995456],[14182431157973947294,10690525456836157434,16135903713439020803,3703546536324285429],[15353497229327721671,5770607597905045048,13983875926830370968,14741192005971437448],[6352482730652869231,9847799439347423620,1912217677801023246,16593101766873861471],[10798356376165476237,13440499353679565687,4047666849029925127,18222505292497243117],[13691708080615389449,11974450535935432902,9600057897974544506,9053675620408037139],[7470613361564639018,8122948057109826257,3921712311127307040,7138408259818296927],[17238129746458960340,12700316851756799941,12963948720754076204,9082878203656882944],[12816981637622364028,7164454220821481510,9462829226572062058,11647715339887974380],[17346287626570385729,13829386813465830569,4088461370974004643,8907586328909960447],[16312798513799263270,14843367546490999454,17778732554440397487,13766462071512105519],[11290201684426785578,14845412392164459401,3473139794403608745,5222077718808473847],[4276257676952610162,1323438246277738352,1008888121258019557,17105812813467358045],[6246852854647294708,3490850577567349986,1148716030316577044,4070772599876834841],[10818056915153843673,10299641289119926270,11449655495521363794,16712253592244035736],[12417517265335334229,2308485877009688912,5545863729552139065,9509121016930764182],[16512819594701597631,14862952525421464719,12883807220572397321,3904796379505717720],[190709458848853370,7288276808496055888,6486847909901485050,59019439070516162],[11414900868308829000,17280350769132986482,3370037118079853578,14685247640727318461],[10583221730009626538,12586000100900286243,13959756488074033825,13533065009991156768],[13607655997902114607,4554649330470345907,1210066101104777880,13636605859606631018],[3801533473464818694,16593899625649927333,10568550384422889276,8784511390672799329],[2330341475937774619,16079132806733922728,4509477857557890596,13704352982622262199],[15669711364908483236,7959300145609809903,5849628998397679433,4294456712307367906],[2920835323501205117,10113620870676180642,3741338471797560836,16011157128949026176],[4391926320339956880,17936517622231077765,7658876633909736108,5461382813306479826],[8300624132165822164,12019652327795081940,7022804465090885518,7874197876204072491],[6609927245370876823,8284121982512237528,1886414454205245550,12791342734989570617],[5738321873269099511,8961855696284339163,15849143387977488619,16035156096036287642],[9562666201997752113,11428596302732921303,12041155007705843985,14278034227855065676],[4994882570393267361,6669513093403397357,9307184361844532221,946465645893168675],[12290543777326229085,16560506062301101303,4721004783629861874,11890327749569121761],[983005662365620804,3114183821318360546,11512107192180191327,12131684047264564233],[7209239128162298578,5601136533762731028,8541969883088175281,18058885678400941433],[16959423500366713021,17780538591354068638,13187770665323099848,8210771153596878170],[7639932145719356323,13223654605827924148,16512038389972469269,15633720036541217513],[4869851285618421705,12759816923779100223,16427315763132234769,12866285116421497574],[10720691027226687056,18446093977339567016,11094000224198155829,9428690920008104586],[7984013983976366146,17532865904331053472,2293850359232485975,18430985100558271661],[2304820609212528425,6850118993993097796,11650455399866544711,16750445238908571009],[8990962251644094576,10276130678571697901,15203672358802590988,4127416689644456229],[1609297068493783512,9495185852102318874,14959406365920899717,1089614125641836867],[6311297798672124809,3781292294275007471,4965999594888179202,9619200086917721579],[6029590895787884740,706667291145836518,3721983720794185992,11869593992149803904],[17867285105378544973,13864524257504142196,11236640952623618011,17276885232101602830],[7818330298349783381,16572169384376605983,10190134183721269770,8045602600647177415],[6483511329997841238,14176703863893977464,14296908659849128821,3282332539881021077],[7078863752381957744,12831709455730431991,3364760155498758156,11127943859025238232],[10427878337289958771,16725026446558767984,13928346329369481622,13229021766777370464],[10719722496164697125,8721619828156052800,13369283075563519033,648470720621686343],[8413154057417375239,12225283296428719919,11242603475837518891,11814671374149181863],[11412985208208199287,12605902480891890972,1325938842934257680,3920343923679784689],[2985269770415337248,1455613411132874658,1405032563381432173,7919560003636609045],[4910296469754826278,8547648334070783337,16360166120123741760,15324899919996014318],[18310722362123745703,12876922988927022966,12348985512210706468,13494866155882318978],[6671251976482253678,17429408335054314913,4113068291545221331,13888110870045686416],[1644898800939850386,17968181166210949391,2487739680464123136,11479976326649679692],[1740259521308655638,17279194686303951535,9418999015175424494,12153093721727883774],[10588810378598463151,8475623170419120699,2135959283776720089,14326041137669348246],[11460826678806011127,1844046496122890930,14495328969178018987,12668620122319729697],[17212336635108554869,16051545353676563529,13363973538841820801,5303090432365702922],[13082929452760299287,18168476899027445812,6005231722153603663,9437591729247777200],[13313966597169188852,13965166997703890250,7832605074224056936,1720046769876943954],[2937502470561797505,9534879879220863283,507524880492883316,16206228062205630237],[2733266278292645174,5828455974109321681,11381868436702627086,4169741700069609151],[4449437750862283639,492599487207678355,13203129342433960623,2930028925758107475],[6427963374485919361,4709192609198417922,11352498359474231164,2587726017111947887],[8710904427107854492,1034885670745285630,14314637494211718135,8674232509453286650],[4479285020455233960,9927947427936681463,12158978868880580095,8690960819453472668],[15818843333944818381,12640169295314068418,6863969446344123048,625911061827386926],[13988629087611914373,9538385576539616176,8724131378314910078,4909023931649544699],[1343590434586496824,16478185408501114306,15726286171533713039,11499842157349437339],[14598390051385655269,7673820996319748746,12037610249451563203,7938786120648592920],[2388310404442775448,17358264523556017561,1402065367084878532,4943655137697606290],[8403270125591092976,14017648629706357604,422020114779084368,9629670331226193533],[14688159899053630944,116375365871746005,1655903292106341380,11063389742152812172],[12701886571262937204,12374215058138651921,16330373095307290764,10380628381102217508],[14041800235278179480,12648500407072165814,1949307264759324439,11083731001478873538],[9176637653299177646,17217244781061753915,12285810882529024671,9181306193847579045],[11871357438082918700,10177316225252792576,3236557838902885305,3419189745496157977],[1021387586676383196,2410689529848463628,8556836941356015124,652477632412766027],[1856667416722013785,1801841454459159900,1244163168617608810,16912188361242084352],[15959417996249964992,17173758050148573405,11617669594540655105,15984727789739482100],[13508773708942222102,14700829534114400054,16084379683785770892,13397728951852564166],[15303319752568398105,12343480894849978248,1942995471611750465,2503904911013180843],[8045347903006791661,17639342835888568819,1338191672971663487,13429407231101889667],[14427509461713959572,2764498757144048826,14577781258568888992,15105730767119914742],[14064409358495947711,5421782293657813376,13678935669888116823,2793961297272177342],[6351279761305790424,18226875027753308592,11199368462600657929,4960168068746048871],[7056309988392860226,15532284126706394959,1627098917471990896,985304275381632839],[11973971191103765818,9862909033131451780,11271770642057722387,8999702179792802494],[1556464013902340457,12802961246553787128,3938393424139551657,6945795044637582846],[16506373144047442629,8054971371802664843,8196128603677394101,3795229468662105999],[3490998261459839764,12616111411183897451,7185873549865972306,17289549596249431970],[3452393633514131360,13877046293427787502,3766271050601636734,9355774991073080897],[6499000764002621002,13559253063164429205,13491066760197680403,4883876027118537085],[17799759426555144987,14383831613206047898,5200814754375678449,4541846377626513523],[16770932962401758312,9518596636922944734,6059091714440336334,9243523053463376286],[12348839986938348471,13600856493519038766,10452953785493393777,1027646733266207419],[16154441168863401091,8282909308688928722,7818561537093730235,727530235203422336],[7282522950866724596,9692781134625455387,12080784723050460652,5154489251004251104],[16644507483536756080,16892467805287719619,11557737023213210686,10266848504927442271],[17596633187424159724,6822801694057036950,13239544292525633805,2337176060176373554],[17452896508701278453,16933150506303381198,14373669406182267507,7575435603466942204],[6145814073132653293,14713534480060476075,14122610685536605313,1680426109340190433],[13631273473445162938,3196827460276624505,1731029338115986521,14621679096469060983],[6199694327735310073,12694882108205091591,13629665222548488587,6586706416033683421],[3151000961266389015,15134615494333052685,12252479099982229686,15911645982937061440],[13919219452277627224,1721101583793483117,5007984352489070656,5880842398486590697],[1810670034762965628,4306193648379573683,3756866700963330787,10275993285905321797],[4762245579874346002,5950578400849151657,16544184427252815238,15017782629678942497],[15238508627043527118,2466631928639899597,18228826088850209829,1903905920307178536],[18308496563210512824,9381143334029854432,2730021249585012713,6796736065746574964],[377758574582967096,7731303216277945184,1635535668833966819,9784155718734620027],[9856977896718347249,10197562078039421138,9280632959840777414,8632177539752934761],[14928874496714738634,15169702298212585789,11002729825369456913,1030906218793621158],[6066609051091434090,2228562140717133407,15782402680641487278,15380021360980319419],[7924672647605449344,17060435177460778833,13891086038023528428,4396350132798590239],[4945434422650857764,11210747558787592947,17691090942695612212,304006422196226497],[403404132656212148,16987693752748708089,13907572098920966651,4570638771243345660],[918976162766357368,16940809108399177430,7867978866046646306,15714665118280371460],[10135517816232340584,7159820777321468467,9116386529991225061,16733256466927480444],[7631667606598373632,6428525119709430327,2765344029757395877,936035367388329406],[10608436807688522582,1954121865071677597,2337386807396830417,9406510900630663133],[12670888163175330002,16868819333638820613,9176803870568099284,6716446162712974873],[17990951822849171774,8252789866533662053,18238513517688620817,2422885932963733958],[1970167451668811451,13674889579119773153,10933904174956559390,17445506735459416998],[12528522200204445858,384298507022553297,235783265945332798,17714543960007356697],[5129609003201770994,5618641358626808257,16134380058387785871,13154359258400840190],[3702596040697956612,3698238991152219972,17840828001388067481,11193506128848022230],[531138228378778963,2654405090983365862,14968452271262025294,2413137556892315112],[4327664335187837589,5459483876521938950,17718458133107018778,261853210304117092],[11304268298041802566,1065367301777972078,9798640262836170603,18085597206739860504],[6627548585360752381,3902940581092409913,10528312962426993728,14343048378561708995],[3900859003725139026,17398946380162458041,4165903452246761594,3818213079207748187],[3806478400567806600,11841756914240675082,16250149197702320811,7613011868762393215],[9262295278488302056,11580296003931926472,15180577053953380270,11283590149061970694],[8570854474291679494,1350749037262877296,11092000726275757429,18066162806989192507],[3234723973664264667,13893336762171543899,8137736169214442238,11894704919071416719],[9671041622073141136,16564261361785906503,2884163700764724837,10017465865572046307],[13939192206566785447,5187502177819036234,3411047021634601702,8610028076416738022],[12774747660790215727,14794760899414413867,10488729727572342013,17935364747505162621],[10618239473534276003,11861208121611576824,4557001216978161241,6262971562631515584],[2533801050261555256,10629793447124302278,7274134125576134931,6160169090129674132],[2601223002252666739,4840802602393233097,10110952137508288243,16786052050430635182],[6249016384041424130,767643271527111093,16778289971813669025,4756225927822550491],[16234377320610458525,4030811659149058399,3248508930901120148,9568761467151661303],[8693315028286253317,3542208699546613923,14703314530515387801,11087995626657650812],[870117122723013692,14435103248869453909,2849418830155103049,2532503089356160094],[1294125435473857569,1725354455776521809,14901556136328851921,14268838623054078342],[5386306026500576345,2834986354003393901,1673812715964878057,6629739658995432309],[12322698948915344374,8580419600923933201,8041836284660541092,402845569144562995],[11987331080048478933,7625059928858997105,2237939349411000759,2851970159115638625],[9342344226902424218,16841854433421388731,2982901338841563801,2143472377430746966],[13963616234245523469,14014644272819819297,2333401346681602245,6687756529948638405],[4536646184138846494,7494587562822981069,4914673367020691635,8090660657538304492],[13011596538178981015,11636462332782132369,13591413760290696493,273300938413504781],[18430199110648087938,8179812409365868500,14884975708631544446,1310156783880986497],[8709870076505698921,3768210361461969130,5485995117914669865,16098172702655717536],[2359461084697908440,12654517552192257961,11215914205644835819,11202881071454943996],[7508698487045458419,2012175467589326809,15473360027960656375,16352836434692178013],[7096144614356152668,16847502831037731118,14112851616398288945,531057115381019701],[12821131738912918488,3635184544258390255,10972738692022900679,2201025726917802039],[15300498918311803782,10053961385230956613,17454042707822276713,9786551125316382626],[11026419551585973169,14489930739205364047,8057461858439111391,306704080118246951],[5135296995129541500,11480625619076534093,9822270024808522907,12819914037017852812],[3156455332639541615,16828025396006176290,631159413653461941,1777522356618110964],[13882849814880818849,17657934530621277779,6659893656717856519,8497010262934754336],[13401847752399390741,2399440614195874583,15252909030124413209,11820989239847419525],[13822533199452816802,15115950515660901616,10728989248117150028,18432722312164595348],[10021388450157106656,3828582563385177519,17920615057304814223,10148540415446554513]],[[5915305944369416697,18276630693452542271,1701096517270601350,1312801855572028310],[3415850708770655900,1269484657338901677,10309377890292323701,7534984443561838277],[8311556856146396406,9958258230868342526,8368754413731569928,12478163783594367678],[4935838930508036085,992490485862701461,10209261096329395507,14974845320353205197],[10964229466460880491,9531775660667271723,9687233692929002696,16536467210674771802],[2126452380973357233,14669698128884766088,13380692147081420534,2094182062964803762],[1086824141563469806,1950935995901814175,16820983844058592341,13568082078075419657],[2743536223160473088,5231549291957038923,15067640845119217606,5446088692416018110],[1620778680871093354,9911060322606956995,6931884204808848270,17435704358923741261],[233132998462524341,5655857297811143391,1122189071386437994,7021047584944900409],[1411696289385404925,14714742792123997193,5837352159741341797,1726728701538095596],[16677143820064980082,3430518204308011840,1319417176008054899,12443662738117360328],[13245890634444260331,253451287428253769,16059420447107656199,13395837976372111096],[8124373745580888834,16070071210948394072,14466139110943500750,4355486728564471077],[18298721011490787151,8887937701860792234,6137010374919511867,7356615076439935295],[18376739213924931802,950362384635847950,1361905718581137535,11217149755388023111],[2115035466136209241,2312749316611975848,16280663601450165796,10469884456507123721],[13664458806273412571,12625467059678425461,4880868865613017536,14757066393890164155],[17350807920322327342,9575330462442099689,1542364133872403633,10901216201954346220],[4580356931872946814,13299555369045079445,13907409485538199819,12531853903282781133],[2787685462764713809,1392826624907151222,17843510280264748160,5825395007128999846],[13961749825949884806,10104992517101360140,12298167838983932767,6764274168368718618],[2532636748001558960,5361274815622473411,16941377034116990497,1455954539358520650],[8515213079683515467,15092246262822652174,7246069081346502123,9976724619075971823],[6918678453064956380,1385550986447247636,18377829647342651819,18221395522946340864],[4567947797066193473,18132628978089024081,12391707722893295365,17210144856483682915],[5453857159260183454,4860071120044593514,8322498240675284440,9300879749469523821],[14707731315617101127,9705675566512905786,7997396171434118502,17856358837817639771],[9892821525764263895,2084637270472512876,17974356834746248767,5197336281622101748],[6623684347850741208,10388309312247596719,6035863393740867577,10673804173755674161],[453925886042231497,8949869786038918995,8391089974804780330,310193739083829603],[14504762175850182409,17686530889664019671,16046443681269330812,570761480952057479],[9106920963227074521,15035196181026694387,1321583526384606554,3522817642316233210],[8391215401696012090,5164695970674463707,16496745891461521932,905591663055764148],[7811093805010404311,16907224237520880956,541308789319911597,4798911663098882662],[9285925199216344919,9275816228088136461,11711325596273605878,17154946063125104797],[4152660973065622294,1229632743701093100,4869033399548759228,12471076701785243803],[8283170907858598130,8484338687179444415,2778325753999438651,10712390882188342489],[830513030504162507,124206361944381633,1212840648527077737,12647808726805480230],[9812325001523915741,834043136595052829,426064348286206158,8312263393819526163],[1241196350962305811,5489938976960579575,1419582360220163183,17734092056459140822],[13869123110579049985,5189525928634445859,2060405861394949110,17719357777497481897],[10195934936857644301,13013857625441291463,13870455087825977471,9023494953141837728],[3330036049858807970,13708775781675509333,6644099601608844484,13952476524283918775],[15129508562642674028,6749477845157857809,14895300691353360522,10551929139437284841],[8298611906536772441,17694827107478975401,6190560559026762541,18359625396824829541],[9070092480542871804,4598756436376413147,6685752965489072600,15482847322393922641],[17718186863424082258,17654468156216676473,10547168463297820019,4625515743934405164],[11144777659950536706,5508524777916161581,12735082644895269681,12220262104133009539],[9689575712751311419,15394342271592848775,7859990618919095149,4721461782486819884],[18426216838795314152,18291374227816660994,11973118173535117105,9174069360307137500],[9471380980158618096,11575445922932906784,11596647457572048624,3890577121947747737],[6521107130630196851,6365974018581749807,14867988535608209300,18061437752239758775],[15948127086455012099,13198908263429156333,13914556211975848824,10915218917710108395],[2642782836995618295,2997835801835054505,14430849411112535452,11027985324430436559],[11134950791191976844,11331178849522578771,8408128103052874349,12539351988333742834],[7476857507302209900,4754876508943798010,15466793643829209720,16272574912815958924],[5385373330755534028,8673645633808236708,15581064140622791862,12699449112785966426],[8420541352197421180,15907352966563732400,1769381043859464591,3030071579863664777],[8522603648058210744,13541447455568806069,4185999930222330950,10667515816072640445],[564462150930546269,17077259295542310973,4389520398734367537,2731741667035191922],[15155194682954602523,10486804314733845964,1951795405668974281,7055415889330473425],[2541151559524641620,17861482983959512689,3766535442864892234,3936629008275134003],[1895520185481457710,702322711425926174,4664228463411406143,16572108365349818491],[18068308167759627521,302326686545137750,6763338314311537692,12947955221550730026],[4154813176744531628,7335204656951419800,8598872425482526188,8242224988934546667],[18342185997283954249,6247936043919902545,4396422211580691733,8611559910455223060],[15127289558995786797,4545249164861811852,992821142145291084,17094001510417388253],[8695750810434934973,4471146304910479418,12030941123594737731,1977728123395489641],[8662916173115696586,5208024291865975260,7241377229004625190,8741442456855586290],[9704353314199555137,9143611009557416231,1274512408221633392,5095694418004889220],[13482801047036037646,2647233433314485892,3734828216092391242,9135388465158145037],[2637468419439752879,7180632076749619018,17122740292878749104,17064701624377348251],[10846494748089254707,9995009962396687136,16861275248091519005,17133672285961538393],[5568254453006893228,8660228166473470517,1660454285385957900,1640128774986171940],[13028480530212968815,4223300696446352720,12764789313452206123,8137184428559813828],[10000406883713344747,13326769557697087827,3672915816088088132,2997399834196750632],[17231586493786618740,10911989579868675875,18267505338875762458,7605388502589610951],[6911275722829293300,15025337181804739738,5493961222051009464,5641085822543868075],[13428899009390279612,4397262979527255163,16303694663381134362,11775273810026098584],[4532831996107132108,17775197566047214681,14684060977284378737,3931608044990997552],[18247178742629236091,3210659583182600955,13616629484986058202,11077044335814474445],[421072071011728749,7744730063450090475,16669285883580266686,1012036862280478095],[7718783556862932586,1901107407870742761,13351560921480670610,16444730126340447146],[10224729840359700384,8289443265212613549,9420395059301793536,16545574267982056186],[8258039795354805870,1219147417301345324,14486391875473611871,18335865222306432077],[13956414035743450920,17613907412361089606,16547730735046599218,9077618192337942192],[3431720788833709783,6527810755272606956,6721534584483728720,10997893933408162520],[1077079040639820949,7381117061812291808,4665995104221486429,14839899524365315503],[6890059593442012957,311737863187510306,17141472944021026286,2647720196679679764],[3644960847452780936,5928161398455903604,10843589433568024693,8685379571135880955],[16687960650369633195,14766277329822864623,2563382566180974104,3350709312929471597],[14056311483296802489,12423043614144852774,10519923222146826560,18015733623347069795],[17560235662165293249,11404972870045700900,14289280975790640149,17599537414070069212],[14826415944286893650,85796291677044978,16150733143634469753,12796420227739181329],[2159598677126340798,13595779322384506182,10934566989035648171,13715503731075757506],[11883477165016268507,6747841542590143424,8306849711312212484,9464089626161665634],[2384144949846855536,17329874524800521333,2097843579946225861,6615396624697111522],[6467883265906645164,4600646689493912584,12950654337205874355,13037312849371197225],[13538379534111740493,12325590639772187304,5598581487755400854,6197139263868247608],[10485680959223411009,11015351392299930733,8169979461885168201,13195932831458999483],[10780018078629002719,2822285427557480103,2289316276767543125,15685430222585676911],[13631356457473746072,15641703193288481560,7644419791936637319,11247078062136794210],[49778580926580876,16032635045676385583,9238888924766621130,10838946772593331782],[3028956794791953899,16014216049568595861,5376512625327221498,14470041199025993710],[16934748730991287010,3705643599162423068,8245613379973040219,8958492329108764443],[10203596883815114688,6636920577863746136,18362807513500448255,4929048210547208763],[17672705864563474208,4300897971590208249,4473399892312437394,4539641909655025876],[17920774634912354830,10823423314502464280,16645337999610883591,11039133609188641195],[18264570311802220669,1482041010438084745,9887930094890038785,9748899012171143566],[1649932511476267246,11943125838400912521,5194912540645264692,16314529813144138092],[8070178493880928950,6368207118376672216,11240408721846400890,10342075569761114930],[12129480650088148809,7063554945463672181,15950903920009627541,1815831452702865929],[7125056490699222492,517682396540219999,17328511046201365639,2412554148967508921],[14763305306052801287,2531660560190287618,4648568225165487337,9141722420909139922],[14328316863367761236,8254166429715427185,15840650175712954869,17638358939493566522],[1926429871017945788,14724962526001175549,17983570930557040027,12951601914183542480],[15656219921442943122,12433528079797810187,1378576165334803487,14889720450888433839],[15670092513801770428,12312785910350980473,14909183669392063774,12251407270741760832],[18393633158495645153,12751294092789466707,1225374180466947027,7683941119334083932],[10690285785965805959,2869574294239661565,17600518917732634360,9512009895521350194],[13681392690413274415,10892473140477657376,16498836817934534066,6874878426845132213],[8812972393663433870,7968512232309810566,8423847833518164511,16300782748524144984],[1931861987684284684,7073400499761391341,10412497287123175655,996120135772563805],[10103899606509777193,16654000867744215217,5647932026363209702,15241571581705136943],[2383438890614277350,12421197573751932735,11661513326071126185,14000958952430435649],[172762072846584095,4653578842052577282,13641973914957955663,14563432965744972104],[3501202700876640785,17624029849132767065,3309859439031045010,17166415683678728040],[7528399776603265708,11193695698028420832,15535119643024432503,13847442363477679407],[12101944055045955724,12672505601092061386,13321282467698555045,12789744844291247895],[576633997630663597,16208815359857877433,8829428635993246052,13036446398783788144],[13578343812705323022,15151743252830729339,1232480918023822375,11878160231203383317],[11749500638961956419,7187829314017816777,16910213105658213315,17075893448852901760],[15124359042723386398,12260839427887741502,6182239922607498644,4451109564784991339],[138981859444841926,17262824589790295346,1444129453968623745,12187580931630973747],[3388433087907668177,1431209362711812777,12857933063123535011,10271912634301583809],[17592612681783919752,5971990967879936005,5324534798546279753,10574905004513218186],[15599790828359354641,9846635795159245778,15458288035476569379,8030978218579466115],[2740046347848517257,5279347379531068949,12505583612174949230,14355125305554659953],[1744896960163522498,17923058798609424007,11855970201245486075,5943068134717468157],[12983459597136577769,243165746680033273,16992326658669765685,3867427059848886986],[5926077598218429736,10076000865888639971,11231900870359248109,10741470433697803009],[9601159719331669343,8924930746742892946,12018736321768543720,2163668684500507494],[11104355873457026832,6659580960221972140,216114651203552842,15375408473074549899],[727476122688189595,3894841598697741450,17271577835461860587,8021722737248538602],[8053671702986290100,16719742050241551710,14851103449539402146,11328866238456474648],[5071822034220160091,1394472372189886464,37199548350942205,10018173422255374982],[11519143222952664506,7830789010370722872,5053642801990635531,1437075771421775489],[8740995760611787427,6002282967324407144,11462460097200165795,3946591021777132749],[4992770637390836702,17006842102814500010,3634802853023250297,16210914775731520095],[7269668133145379664,8009172944959739140,9603522585085081082,1781542403326283441],[5095744243165258440,14913390027160436291,13207522392384822168,4263727360105021316],[6197198010569255421,1890323288503225558,18163800505052331525,799330919187701814],[14918613006436551045,3502368230630696711,5700235576287249509,5879585653617039325],[16426905611375667144,17887567554075418914,4735454219638995826,3246551257048452204],[12074848960863421430,15427974630685883813,7187739737030568673,14332886113464857930],[12133159150108324058,2263677706323168452,9214200306353637706,5315149851961116199],[13937758228038158016,12926008827888041347,17487856924319916849,8723943508704296706],[3428429811862094627,15141977799139417153,8774663129318871407,2027390810317586986],[783283720637407676,18032330760082035768,11922761722955888521,7020017097586750205],[17221383973738380117,14396582878536198278,14313648438016311567,10473082501486736659],[7027765368151045381,1177745824365004773,17593753730056274294,14473682997388218942],[17513931729491770084,448127486459518750,3076259520421474462,16546864127636155506],[14841452985155387444,15813528967699588801,4138102438078129047,14461511548432681339],[6701806089536578958,12210952019257532424,6711251254891663194,7556006098602501884],[3701923006827901464,16929504416603081058,10877674550768745372,15527449954626793898],[4638860257033625692,9500551951536848616,754701361869949013,16483036693717260718],[12922724948924092426,10655418549033576756,17030233269928742702,13146940542975373301],[8186033029546183384,340261747452893387,16736194971429426436,14465136814510330691],[6120545218636343798,16215381802180217304,11910977148799971091,8710266315308283653],[6397044033021918634,17626347509911197775,11209305142352890014,15101602669403220078],[11531958166672673827,1129400686551809603,6262736247770507857,17254822990735960595],[10495739373162793346,6914427935700839412,16094759576930182815,16851184807720422878],[15938159741797317829,1730341897292803026,13219750109779960549,14352314842481870792],[16982902147276257505,16272871941539305456,12861619820815019734,10543205480614702186],[8941599455625081030,2826284837373719378,2404647301635767590,9778025221220019289],[17302623522116420978,636038302549710185,6958820017141103304,2965967334270235833],[3686376914574222411,5026772229483738107,2576179775267407650,18212780217878767643],[12463739904754622706,7077138022938822839,15316658304478472720,7916557685746558562],[12233807672671795989,8447437440755536921,15472532076533438674,15751066471762080831],[17461573968048920297,12373938739934793961,1203270050460268722,5716734652403175508],[1231538797825614583,17998492129256744099,15970911288907935530,8060208959018644483],[15316903699204464452,6898551167968700749,263213715166589110,7820119855516887274],[9548904464413672113,9754052659463432963,14149388767541135927,12913059966641623669],[13681301260444047964,1594669430669812780,8400558386583103209,11460249255323477651],[9293985891095416079,15356478727791159535,14663267109918156850,6566053974965795514],[5546427953378216276,8610665058841978494,2896275116638989930,17049758969388654487],[8797536811938715484,5267304849746513916,3883839833452384643,8730181149088232671],[6805644122994338816,3523526471905734122,8714028509347564731,5523945397558450040],[2916905763593071362,8446518688578705856,1289437214730834540,3756043166609338623],[7964357974679280795,7291882619794327608,16864365065205216776,2692995224863204788],[12049521104568270674,6676070863267517251,18157591466466387676,17581281938136356402],[6894217812372527753,8305958211424506396,5432928940852863662,395776769703830418],[670410631431420728,10345829811219566546,7146065399729264177,5249980540547319475],[1285784605413037540,3867674171688379681,6923508687369931464,11109144712825460137],[1507777715710166013,14041092269004806564,1338161942591235694,1291981979241415361],[8364650328870642817,9289763415574960577,8557829998054711178,13102878534867517375],[10899272516553673402,3767278144418138011,5879091283569126431,10252551035024436599],[11549740031072745830,1159900527487046947,4586610383688215166,7863127647686276080],[16905052827307382592,1977763459163950925,16655247483294561292,4419620672544740447],[15070972922612921785,6392437884931358308,14867390650472701108,13434885456473026012],[9967744553928883175,5630773214653075341,643451584126217062,7145490162131944790],[13188682131438652855,15047885489097449186,17735969414996437618,2670224411432490578],[16428066651647758163,5424973471494406998,623957722705976191,7277637761171545502],[766783785043623124,3905199221192639674,8388017321462692730,3723838276275213818],[8605261126658902840,11390456689739545969,6516194990766931689,13137396607920097267],[16373872501461385588,14476750465470133796,12915863479101634919,17325517388983178436],[9493716755893944987,15361954319271422349,4611819966892937350,2784903996220136259],[12612404674288044028,15710373915725233838,8157265163075076143,7527423112088997651],[8428102459624094054,12587510402177146457,17179474762931626432,2307060302759164932],[14944790258605012562,15026521446129723331,3944832290566284364,1630444141310330612],[256565179529896010,1446549575831244795,13777148316560465300,6141296036536945766],[7822462728626064730,9960145237326610988,5407230395348485033,9727860499311772080],[961314978980772349,13460431995051841777,10861832979683290224,7794572859010106514],[2221069274615894635,18080463375919534900,10113283348942333203,16404463966016979474],[5589566272770798316,17084113627771078456,9011590836075854328,14684383306780962909],[10693996658621331655,17841922960869810759,12535900195523926233,14723856105498557609],[16689447016653775280,5376920853989844878,9439973050659489762,17611491253349378484],[16636773860151243405,7500950376100715887,15062749465936784014,5729017295811061064],[11561574750912409517,9486244539954170414,1476211870830217304,11183876226935033045],[13277759749651170355,1512365006706794504,1924453381023358392,4313066171803599987],[8591656065279703110,9721342668880970421,8779145322090663456,15204651170693845448],[2898358573986723399,11272182974717010484,17415569431228752844,8734810779880605709],[7959918491292053307,14036579977658792042,6755536714987427321,13818455659535185350],[5849985912957295916,17095693680230115853,5053749610953801727,8774268789023366215],[15919535327638352746,16041312682154723243,8359781037100764664,9165812101998353329],[3146440655148556393,1297176270738835133,813055762104446170,3789435908119648267],[14752100025143973437,8911688189762893191,17790449818029634211,11657741121554254471],[3045885789957108625,14368493506437185899,17400048748208523890,9170490298149165826],[1109507211607588503,14185364453307810267,6938296682452177638,9958940287930042283],[5372034321154520329,15827723811164349176,99550188699184116,9655295463220885163],[1088562915171265382,10567224301072875290,18033886111769103142,855480475776196873],[4130262798511494135,13829878942223199564,12739361821242843950,5426404205664542465],[12750097566884300152,7194629203778156831,3938911527262006713,14396826891939878650],[12075900322441541905,8341031708559058419,13201480668038710751,3698312336815102655],[10016343317478892567,9931700908975636628,17786646722107638908,4935151890906052136],[15836838641372618604,9136122685504394551,16865631525359495238,10026314585940727638],[4296338327275624138,1407719520965764001,1264670652931405750,10409498607947075302],[17215147751307125635,14301959700770371159,13029738694163834047,15088070691601050343],[4636985011668597538,17303089853072993522,15368167805771471129,15151924185776691528],[18417249687176106570,7076456352521278075,13455452204131423628,2826411610645151921],[17528023975552944353,1393164345779525523,562301050064019926,1605514605867665402],[15196454097296118497,1380360393182918659,13401163269499754758,5849368297071279455],[418785455582830731,7959337961581470862,5743006534051271567,14679537638830881371],[16647450684730490093,3648425716648684177,17641923347786066969,15487748265275988436],[2404663313544246186,1994040109335802526,16569274241345001337,3054115075255661373],[13262459723181331131,6488427987149843800,15417179579620242307,13386878024145631784],[11253934371992647536,5163645282229986550,4331453294222567201,3650519123057085584],[6206772500074097371,15229360110183651172,12634944864451863190,10787599126049111820],[14088370739729258141,853715902677842171,2098600541050587569,17573453339731618543],[5620915096972569246,6609930260208395846,13752781782953616321,9709183423647707575],[7656228217239000855,14223417087872788581,10707451144514063964,8807159601913484780],[135026860330873366,9465794979946870034,2244198926673076364,14764626312445175872],[13291455448550728583,10373016110753180486,2303383429688697747,6326087781409495939],[7719036079675086500,6518419268996121705,13178289359928053444,4180388362507697258],[1039414214300722553,2718133072206777065,8046762641085874795,10592794370203383354]],[[6806326578495734960,5505456778670535915,13712549283639085312,11122054459933452690],[4241913633992889856,14658339445972280536,8836811078273483139,13264852953774922995],[15692248088639213166,1904301962864974530,15846436627291218876,9044532405761338837],[5948087400635206630,2333349117914479403,7939045656645253061,15007483019001196835],[18137554850430090669,8908465903051743693,17043942187977089291,1093289579434330648],[2606202919971013235,10119219496814883379,10469775540100006763,2443225078157029823],[5495187211729966127,5528147534818792480,4437009827700771034,274962277063555795],[6943494766688792790,6970105835232166567,2501070245099750013,4057887014388714324],[4375055505435796559,10722870534491010827,15308399914492808613,11533515075452687742],[13995687804343893714,13831824713206378488,14472408866192711218,5915058347791219253],[3607403350204288531,7504336866322574770,1332801287641516197,9410257607210965434],[14083231649334986696,12952060050882638585,11680395326488573247,12706858201332497480],[12827274500583999049,4527885457604058477,17742357215532980125,4992131692635652493],[15077095626562692989,13562457780048135541,29884411143343911,10757293503759336783],[12078543097493621219,3139336723004163643,5058165749144664915,13565091551975359962],[6830338821396623822,4391221893066574656,12704559576285779116,6451039525512631417],[69022236563619760,14235999323251728003,5855866654084846712,8048171911123019351],[1819681122569746204,6315402641761977605,327127184215068792,7655039439266585599],[6863329512343592364,9190825015325865826,10871540787021082607,8548898018396613820],[12903695941959137977,10473742744013791145,2257786119773093040,15334142686073642041],[9692309191868742117,14125521487491994632,111246184690851587,14080577133781505803],[7584902440480585328,12804075818956672618,14987686754908709263,14438198368578866983],[15545444874461171356,9988259135076899042,2853965048993340265,3265759993888404632],[2015094396419386961,12963110414152417394,6066304325266021978,566063847492665090],[7318024347297814796,12511508723350398015,6940559901227304267,9510067533475477054],[8625760594236608027,16564579080675612243,12200727495794116292,14571472264171087916],[14887392651299046361,16129338546224128608,498035657227649834,9844463890736277576],[9444894384981825381,17348555091472323884,17821760729168571409,6693355897158343837],[7192680002266861365,10814379508307159030,9454834740789064756,16248881418021922300],[13216152737591740634,15005019685816060950,12008564750368485012,1199954434694874112],[1105069693358628731,3437057368428389850,8892925830656846019,3047598268014848566],[6749302335421933089,3554391088527636218,7035308199477612095,13241066013495923540],[12787038853487615928,8251842039609792543,15214179847517821294,17105554605684603647],[15932760292627192593,5749045853055794153,12785687137720069196,9467060059350676084],[13221354051752950256,792765652055167620,12176840602224301310,13080521002775345637],[1766465132214854031,15343937384916698919,8627169322167638942,11850840994158019968],[4855029345220309175,14459839142778350501,12224364082796677748,7281311699341083588],[11168649607508352006,9014129253764013871,4202751936820762151,17191199485814724998],[10640301427563690478,4727442535102393358,4748689549654178106,218629273188586080],[3290140268919208927,8218599350805092264,2926242522121347445,12070558867290763452],[7478023637457515496,12962695111088169846,3868528236125912048,1945386965979357323],[11987983412166471813,7855832992611525303,13448887200147067056,14666229950226688027],[8696592712834011598,11646424832545070311,1059407028516434471,17178250453816762881],[1499973313450611569,8937901034716014643,13653145376778268385,17116759648636404720],[3477612760355103601,6812234237375202429,2319598886905846382,8139649660046066062],[8258229504153629495,7394261512850168029,13970762891257793020,2114088053030083102],[325230366946975261,14713468034780340619,14030335760878684029,8777029513641933202],[2433988608413380764,97193121867337688,13631983825714040746,16304096163926180972],[13555849041925952709,17083660190033693111,12998683710414585576,7430260793721160710],[5089466705857988794,5963472070819337784,11755065820836968754,8514821374890427747],[11312909871005803682,11418501114972165871,8913843113813337848,12960786834661316118],[10674222297810905567,10677521713690607496,9757820413506671485,6187590105458961657],[10031319222379977139,6334148485898574085,2849317389472302914,17462921209357484548],[8852733224243671837,16053013417859960746,3097108943501558107,8085374877548757318],[2917992767782697279,7864750896073630442,11671036241944657865,10374026794277447912],[14259242737825024856,16074543673775549422,17985246225058277388,12323622991124008546],[5981851421687651764,4113527782321099880,15126786689684891912,8030410360864566271],[8661268839683809634,3144000232627523604,7232388702347755970,14635772271689050902],[1673439818386726606,9261530081830644697,9253595084473149595,16948050130479396470],[3233033288686885728,15679754865202025747,13837897433674230646,1168025556918891814],[3055883474453273607,6463577077545445934,18287826817866815829,2941109592666313162],[13250158745389125457,12356263201034424058,2592454340515398466,8255994775404073996],[16965643115456725565,5229377565249656466,13192577956723417628,9605562992592119692],[11135894954687866966,9961535280611007204,4208466951064239108,9231143554030395850],[88564385930669550,15115758269151909568,568884247166541089,13621235312743421872],[8623556853705582936,17178861363562358251,6807302746108992736,3286345545623933755],[10801377846932539381,4040224529787050291,4799989942635307919,58790162444040521],[15262288290500402015,5222050924486932199,10577840679854694651,12250596841381912633],[10578870980478424717,9776348868028567210,10134127840124602575,4187984279095656006],[1343834495944051970,137388671681924948,13235562785792397560,9103215895274729164],[16011062393244816226,15536619810103547757,7934401688310028959,7425760162056583236],[3154676538555825831,656135180619747341,15444426982067174096,12153567958235038212],[18116776523036533126,14211209787021425975,3981898928501752046,5305974851987348440],[12497074991965540051,5273584590571158960,17617247515325582919,5269911660307821613],[11725214247777343177,14550825712612855498,6775726751635072786,16277414012337499883],[3736254491786377424,10499710484569921851,5450069274199342076,17076926657784601304],[11806155400184641254,6056622716925083718,6511483789617259914,10669433297616349973],[9311466327032716654,5701421756774805862,811952369774680476,12279243302260975117],[9077137201652966880,9262104695969960922,9259788449444346626,233577768283487071],[8131932877029846662,6779492209382738722,14207776414452278043,11651606723378736413],[17031567067374058523,12704922867176862668,6708627687043179824,14254040360372647498],[10180567458148465164,9730858348009198387,9896389929316706153,18414723619348866732],[14468329563491862472,11557255962089779819,12907223931356174332,1370032336399727815],[3952714431437606105,4948065335048934461,11801331854606021772,15834421341614403169],[13116426277924215831,9062810284982502535,8791873818191873075,14709020335100527926],[6546278885899480379,3501752903408318986,17405249806195269460,7809653390079839436],[9274723334828955938,15393073565290410156,16661126490172337121,12190243287913058724],[10309749911915420935,12386520249484302765,16585482780202057470,4561544751615283],[9521503248586930092,7823824365615267062,13049522111680863488,5840244345347149358],[14474471206557428376,15427520225516063087,7267266433994119507,13821297822658535663],[14774432139383481848,7793295537436996393,5696333368095710799,14532880268878410972],[7443780914679018873,9043846330405947493,8605110807928265131,18123821040345686337],[16391860168461506448,5402480943922169348,13659216871057966260,16563895238244246056],[4030457629487974489,1367584093066369487,1682719954386741981,6465950765564866211],[18319115904395797259,18297550177049376539,17187037952966176320,7535759341912412738],[13327235099465905059,5868243404204851722,6281624906810072949,5939899173563262821],[13904167856625039907,17452116867258722334,14849167618034283032,2205442321479789675],[6200428084306089168,5075391359285119331,9690736152626556225,105955840583789082],[14423054037223085773,12872063113589482695,3288281632994975796,9266585617519080782],[16869514953008579807,17801008581635578883,1257853971667440051,7679125697522794787],[7976596425482979401,9310564541350701161,1612320144684972352,16963843914814114763],[5376607908942735184,9408756369770198725,3328225659698384129,16083004352269000801],[9828616590964409430,6788824378291554833,13582844775279011786,10156166478494580177],[14234575783453679471,18030314399198593024,6745865780272700841,12533314353545336839],[9024238956757915554,8312305147024854460,7749383024251514989,7634136014866935134],[10888550264319254651,17989095051656205074,6531295581948624731,6227209839928699092],[4942468683542789043,7553936667919802425,7674151679136697115,1222172371430564275],[16507498207149928998,10294530430607709808,7271757895479804532,8434285562900849957],[9446257479302234996,6615753909978032381,947857103451686150,1993428197419167030],[8844363126954062584,18233082117309602880,11846748384566201908,11808830720904434145],[13762810607496291572,11582551577159272341,15583857445031714643,17016600071073100823],[11954735694949590525,6453625986613570009,4836500846060053860,5073404001557009253],[5311539906581250989,13316467049083221889,16732775006541236096,17831719379310016573],[11648214217776724577,3496488278865517054,5872432985812654268,3776626080238356739],[18340962092833317009,15070414418399266412,3860149230978648066,4507382825496810831],[7856637813361994277,13725441085231632361,15124285810875705546,5422046213342592966],[12387252323169415405,9883267575255958237,16989510957879892589,1651645591497080217],[3374641429585759861,3982889616430830590,17025637687825499115,18211654590353856058],[14976111331042807933,9797893321327591786,8094608980443499273,8184413284818894385],[13454582028750388344,6058559726138318346,14531116404226492467,5803893834395629349],[832557406661130963,13080274407346971842,6465863786120196366,13480619089433109659],[13457658279679295664,18397637285172429552,15875430073780331921,10124103401074421660],[13991907522980530866,6687270182777423337,7338766790852870525,3539969886598876870],[316646107175536258,6786521039240614425,15677934958912014221,15115980377068300420],[13602830029465877389,16749328079120447640,8637082446305022157,13791879721851630774],[2920445862292204180,13519328543005150466,10629204151141036806,13541115072996261268],[7545658298085978415,6676977072131811848,13061167118326498260,13833529400249278787],[14537428963585907581,4331413756897030383,12243121950144354540,11015129414203008710],[11686415377247263720,16008370414391459911,1515399817855006447,18349510593097166886],[822541264144313509,16889705914160936778,5627482178472307371,17354107518451057118],[5772980475954357531,12179201465900429584,6086516637336358497,14115004635760049747],[17352746629940284084,13382268908412479998,1322135987358607743,16842542614076040676],[2685066678369697745,9726638002007918690,16379261005873215559,6794330870647472246],[7590062395253572177,9524239074097977336,15626683101371440183,4925634112810580793],[13158122129277770457,2034468050043523638,2346726189029571618,14609415532946838637],[7825083359763347951,507021815479426619,15522508599435035046,2132590886874066139],[1413583325142160991,13901907067450886841,17641543961550626903,944002567846753038],[13944185182422934057,5586973255599448010,18263969307635138588,4272130294475005569],[1822040824299690052,5050621264561591047,7107934031076267379,1491609773354948652],[4136356072770536216,1702481626200488517,12141268593391580769,5133441959262021731],[1062257175297566710,18050898663048538498,12431788741332514095,9048501540760232333],[1348813804463118353,753780073932634627,5350968716061780193,16895908633483716397],[2187972979936070665,9608141684753719596,15555397397650867062,17415640162865901170],[11433100593579862268,2631165375856386114,1237832768559138853,14683924071259156143],[3991547245087279419,5099196900866806502,12366960365163691037,17549627791813255755],[13026244313208608104,12057806694623032303,6002794403768461125,13704889485699389232],[8391633260441146067,14601945587598437381,10245688780341427550,12031738423020283589],[2844551622873799639,2465642446941206321,9325278173212164636,1340107347841405055],[18434146142159535430,8417390907404486038,200451709852538190,5988739000668341348],[3903918036810096832,14336907947761067771,16210560950727743037,15553969966415101281],[18379787052222767036,10137453323675801411,14365425135813785153,8904355416381774478],[10226381936313425749,6224142325528149210,823856347269838874,13050371187158810233],[17133511389917792738,16622523475615612838,3944145284208081519,5593378393088597493],[18416467332796932082,4585571889994104078,8356319013098194187,4238142267248716297],[8719134652961930059,9005233375732349194,5609683871468810919,13331322877123348349],[2919949608331875600,8360374286033943452,6552655451389052873,1121993680587746417],[12819507489530030884,6191011617854500613,3013663263322220008,8265419009136034119],[1867603929946181413,16181073025415381363,16295586205437304778,17743310168841637602],[7436768139677578007,17126550056056911985,8975292796987181706,17740692215288858091],[5231526253352236690,4494743451154988893,9452094835074245952,13438816244287247576],[8687677934907394390,5716611336759432319,7587763498432882809,7864722798472985563],[10301398889517271581,16026870499599363136,12718212128615493977,16966144358182702766],[1316543616439029172,11461570405658751174,84907565709457330,2247309715750242725],[2180743850476575729,4064248140621125730,7793751080540459020,1847534559218777799],[5152540347879977421,17837557513719266763,176038516211227569,13620835796587956508],[16651886392930092745,13112413938661772264,14832843017174268038,6920036582534107843],[10819750360792461358,10164101585244468853,9948978562985566840,12242405534618718367],[9933103385977336804,13219419958448487413,2173802191883892375,12432527054596948108],[4604908740968271247,18170203310832128658,2817323948733774578,15892401819474925042],[16639326826073873987,3123736189463260647,896529445140869326,18081437036430421533],[13020895414720026461,9610130068147068252,2752829994020248471,6373254773010401650],[14766874916249894136,6955932837985499295,4974616145916011090,3111155907944996188],[3534582970975690750,15734889834924250530,13800823039417215402,4230242143288898771],[11493859174955521824,1837749094197973328,5738870679987015543,1323408730863954590],[12819731870632973243,3688352668595139113,7969717062517138310,9105754481958631251],[2609215116909688474,9645893696413258345,7485649605203385746,2603806052966204528],[4608214964370037978,16499424066079919084,3908156897181679205,16755911965778228992],[8539938923121515703,12245666472352467332,17975487898761507112,17783720395041362893],[11100961214819757287,12396622764593083567,5126242098703447321,2770431800587595334],[15989491051041169505,6111956609599968054,9138036675364623425,4802597925263055313],[17140922097658809611,3334015975861384570,8980610050948099397,11811515019891239579],[14508112523835278261,1186518499624714156,13510134305875060640,1758761111056939900],[14109393031300761747,11492580510721027558,8486493121024850445,4644067513294157653],[14262484144657214905,17831081166967863750,15463907313469809572,10287409143657586299],[2115218760475395293,16461933198356433318,8142110273826470387,14630046313758397597],[17373311998286278966,14511294039858611187,2156186278942873472,6814822438867919963],[13590685478525033955,16834777785233431327,7523755295648730735,16738323417385172446],[5825015975173577680,6912189924626894486,16876448422420425488,6694564322146809995],[421859552113284115,2825829026600940429,13633791831143473889,6201320724115773082],[11324188880071793942,5317856090906348197,9632971152496464080,10035116983272462581],[10502958450189641761,5991737037120994245,18028929860755912636,7047338806076226011],[3330244051597943567,1692604074911775408,9014579596665977112,16310788414816753656],[14298061677369762827,7582443386296214907,17547643597357242322,1524516438799065267],[2427840780186408318,14427681624080840931,9171085031461145493,14196486285981484644],[6089494363697518125,18084956054113122498,15442136618664723480,7221756361885115760],[7172519962365881659,4603139159277204980,984264347400641021,4992316675967852575],[12895357483466723198,15133445768546379275,2369842793599459184,2223267745044854718],[5225132671195124920,1794115907065064257,7973894120206361829,6614024419149854127],[1699614826067485654,9342030354971638022,10940102464710900857,6675354599336957294],[12868824489739543163,10931305273610568114,5153660802612659441,6753435206372975394],[542427978396948026,2138537827080839929,1419527911591852836,7427055445034657779],[5780117463762142847,6190223371384081540,14379950693166665095,4228206176851408929],[13741391861699408723,8920130030106478105,5974623929131984413,1811749054754702538],[15581403847426594892,13049001041207261640,7726114091156797735,10555287536187808389],[2427567237766175731,2204094180756242172,17278180247417387456,7024524625694239820],[9850142688769771878,6021201540504131676,18285846601168001716,15977217366727551482],[6164002022375135291,16232132761287155970,6623695479338670444,20570552448915703],[3748559094378505691,9695881548743136523,10574678902645151196,17426721953759056586],[11331923154043607176,14790231988975418615,17117834169783749507,16660634370971587372],[4396054544382991634,4819203986824264722,3560203563100109070,7742857014270844713],[13509405243356358290,5324862926876203051,4347871918048712384,10588217177859737563],[10015675368560862211,7694334535629515150,5479553131654560696,15169869316495320942],[8423092302455769571,17963549586036040067,9703827180796622997,8213803278713976375],[13506490115137666735,13952551888686174608,5236207987620801127,6385227293151977335],[1871855526612928256,6548186261618784464,9529703963859504483,2996563857891690254],[10322699305063279580,207938068517060539,11659844909644618048,11547912419151321517],[13091569100736162937,5731081958691522624,6374310868277474313,6918917178684821694],[3045394587714884505,7819828704588345738,10978646304769398178,14951309769009060999],[7274878190206607127,18367582752768119338,15619696353024625926,9150444482411501181],[13453739010573893772,5471103891901050490,5832352041384180063,676347093369978304],[3253206018475759042,3905730052139169480,3221012183140180578,17976548070817138073],[6435384678211187327,10505803315212836151,16338016949818495212,2719606627200432964],[4016321757938348161,1440891357542261843,15918549497728151542,2615266849607944659],[13414175117433750918,1773920013341240464,10940992828058815255,3507158897667581392],[2028468113542456634,6813094492342307112,10817825259671514506,14067033832436088725],[10492493621107361059,1364860561535367681,6503394236138658327,9648010026380085075],[8760751471916645186,5921747823697101253,1922524073759691130,7389915101239487618],[13053914584353799378,18045924002132996680,2352307892786489207,3078779753990520964],[138644722987929355,7109997124705223644,32727968800460337,12519562007703698971],[10508950153666159594,13432556508622643093,5220174383836607532,5430262519694333284],[5075702240129531169,15774064673178924044,6323264979781793466,12795642705696741245],[4347979323184775642,5986081721179923660,17249069218065205118,13731012026822057370],[5259881017088831932,12235949903180421171,7019089709617836975,16770579538771284775],[15020703652098797695,1978119660732198948,17710944916626453451,905041025617490276],[9479485243294443741,3256490749739850954,578153151366022310,826074025517325333],[9593879025456361026,16087028875354387779,6318468746162032817,14593017177839223045],[7147502463523804434,14174878000855751642,1023373288911405636,5427695691552751092],[7106284879733963375,12940904360173054094,12302450354067133576,16882591424116502194],[12142718270993170741,1394316445838061930,245807488079678404,13994108875648505661],[7894593665582839661,4098599265311775259,5588519121207517797,1716977565163080654],[13854316522047062866,17863557304586374575,8608376535121201094,11128394008034326102],[13454029322632045724,3554578425648061624,15468400847446215558,1961464215394435322],[577501315167483343,9660279099405229074,10683851897696581823,8302933434048017484],[17535185650062045206,7967572344372024256,4867335991995723636,2326135909264893884],[3977057768625026752,1219491263323289348,2599710534760294802,3380851860366515886],[2243032956542863789,6123424178231259597,12733431707536579464,7972499795951506489],[14766009700535034829,14959277285853318485,7125457148975624263,4041087889933895235],[4319423379745352497,5411185528785618531,7566236917508220608,9499633417065761757],[5298521668312349526,8685265143213814391,4699272409703749332,10650991848246415250],[12159544137621844982,7610197529598645837,7765879233413549600,4057023083498514784],[8666425476839210787,7288447163185727553,10845166937711379059,7034950587482644717],[10386204140821996055,14620864452157357365,16166258463916249316,11035023105242151698],[2814209775979712135,14821056898068647968,3207689774894956009,739098592913863039],[8022289732233277779,12631072253126307743,9128071955382028381,17053887692253506892],[4475891258009769720,14180140044032526516,12990290831606813581,14581156012787672399],[13499969032774034804,4559646086900499907,6301034188986228688,6076578452111375394]],[[10236299856310096410,13757510229242469316,13153401954839010416,8467892565941739577],[7245769784588931622,4751800534855176261,9956573316752569862,4959214752050712009],[9829846714320856447,5965255000333329400,4783505031063907838,7040302217388498854],[15288298620869229598,4910560181702232914,3293310920347922250,5645533628087269765],[10618844133222287904,12531711762021513284,3185205303362272064,11399968719302874892],[12861589438231945849,10221862664829007229,12172799499181757931,11955087352854210801],[6508593927725169058,11714431977960814357,4233161959138147765,10471882417119654658],[15543775156491131258,10980406483918578747,13548822795217577457,3681974913427234647],[17133811042835673767,14765936768785890160,14452744133767909939,18279540375420575818],[4034491176994754162,3476844910135753155,9252201013730915971,15034621063743291674],[18173326217143544388,5331392798164591975,15904573754384540483,2325380270990815559],[9694724364468159930,14670357155278017757,17675427091585330375,5513397076446376510],[11251592044809717341,11865351482963985038,4630834818101685811,860258553285688746],[12318103287535248497,2457227702058758521,8089251155567798049,14195135405369715807],[2401361578767616245,16092644131585261139,14008289046507288616,2058459514155730174],[11797126323416489577,16322425737704989183,7983980944376863924,3441071741945909437],[8601833050774490437,9549568261486118506,1558653333298244573,2980689776621336166],[12470078673470500651,10481258056440239266,3822050524603600716,886102691466443250],[15252648020499462152,17181854465764167687,3474123880602636193,5405107146357612966],[16394154590765434346,496099302050360161,3487344836993962889,6798680280714291333],[697422770306494790,16316089632096161728,2945895962275600064,17157322965115816291],[12149168813633735354,5750266772989999512,13737459048673987905,17630157660352707767],[11071797024628048893,6213703420020891469,4668487338372930620,11538176343060656971],[8300997444315985599,8820658529521763953,2241917300049663191,16781299481324114148],[94120622450119847,8543358045783235830,15818799265989810377,12341745329021742493],[12503568081365995946,6875598046154403082,2107739683854195703,1551368886413036861],[14735878667977163460,1725110518823735195,2309199184626326682,17384859615076745069],[17375507226319181209,2220580352476568111,12440761740443019215,12853894091863084832],[13372790481158671589,9873424022281508672,4061469287787823977,3947848420473459620],[13841007773194754490,16606079310381277978,6988765221880067032,10394365789400727646],[2815863163339452710,10246073326802722072,8118914957473243444,9975497237579809424],[904966329707618576,7849637727061223719,16537200934904014198,1882871971252621911],[11213107647514762386,7391955169161982653,9714715295293422469,2249075555956233686],[1733329004261240615,10192451309995132082,3279774337061759434,17230223379509913584],[5298676693740846071,16742154450654925745,15974146077201962388,4731209681694908747],[15643154523690339246,10618164530027338800,11032918584372585207,15670811307495608375],[3829114729202091197,13948149587735482824,4621057842131604885,10975992320613731912],[9084946586904961452,8524200597357509682,8945107667631140545,17437135409882341657],[8159181421040824847,10652540126303806814,13439747261034574212,7665483637370775404],[16166889481331314693,13933506455633851056,1986615304718371653,3132354210030425719],[16391260352280725492,16132615012056955553,11239003077775760905,3457368147087947847],[55598939129525598,3382684488969204083,17699051545703656218,8815683997763312863],[9485023137480321878,16582224394069375705,18052001891922579672,9523282027210032093],[3051986379781079466,8006132885494521472,7724113580328067799,6932347493536697619],[12358347441296763295,1002400966905498834,1057771218374301424,12193542202549245532],[13768301298377566718,7806999670984101610,10803035055588364166,10024703180145367591],[18420054866449643308,14903723232986107360,17444598364251392671,17889175801963387456],[16018992866398832833,37177830001677468,14571572409824480430,9906337455750242806],[15196866509848626350,1334759292978896704,9907544659851008350,15161630313626392059],[2356097710778439580,1872576180785124317,7653910168862615145,5285346680835710939],[1003243770815752608,7405127793299978782,5350873854523642502,508278262991587456],[12139646635007668075,11446342932332103925,659783431316902411,6064977023966105453],[15151281753827705930,13202003789900437833,1048010791698813118,8178261443161169616],[1354863223099765480,7049083580148842364,15295302592122459877,3139424155703506113],[10287469617425566464,6091215537677554145,1205616271393796928,1771450541713810617],[7312386321504247865,1525533513106033066,1771082977732563833,12720645444777852039],[11760080221204664922,13620451085550204924,14381774295447511789,14935863617532872218],[9302503376028050813,14794545548036739793,6086156077032467127,1757067753881322059],[6478981029226936610,17271934427841220518,11384200494795750406,12927266751806352891],[7934693320478911130,8482325296604282204,2389734899019143927,11329750878127658393],[10510091898017245808,11306091052403084514,13289989041464899379,8850835925326356398],[4473732975672219999,12395717320167756550,9202666902484515283,1803865320599125445],[8705076383573234370,2000015876047095165,12641475672484862335,10876300392465133396],[13329540238198061508,17614364529215411748,15807322679928846392,17865143122487523033],[15498759171058876414,6913902613808449241,7901534486905102583,3378517760492059013],[8258120911617813406,18065599031349560661,3196251161295014022,14798020292780462105],[13343832282807543851,11136999464834995654,1819348819430711733,6772458988497313412],[14968626304257725312,7474691086204316089,5064122746471301913,9896487952757008623],[1011331776491653921,6800415477343095069,12687596886646861721,4159900233167897585],[16582517215816996939,11852297336332925395,13955391754769614010,15916411727728752645],[5818947744326633483,15977457839130032826,17960937373621503083,15127505907131068165],[14088534230481642604,7270165373402777706,7822247442899437229,1893729732587555565],[9521666684289593612,5854481331068896593,2716657475023553796,17944628971598610815],[3472799965817618716,16347436432887572548,16541794831631081848,351217538251997552],[17670200986029361267,1712785036737049886,11027865961382844878,11269898132564314769],[15421654757800019504,10843099333904596548,17269844488119203321,3438903424654573964],[3319133335724365533,1739756896688219717,17075242202564044988,9596025064990936717],[17780205154829534178,6612363049325356895,4284859928504277286,10813334633623258336],[4404118775544041685,11450467042060392877,4095096416569165071,14690195018256548743],[9483238513395806053,15758603516160473822,15443479225662869123,6460807447153886011],[12468326570966400984,5611969975079931753,620217865859065435,1835567175794706417],[8208115832316135420,5894031656555891479,16554479385428681764,7255048026213470709],[15761857468070879418,7994253704726477996,2044313098843565313,18233650269911306227],[9422739715179689739,6379728236681375795,3495657413252828261,13646950376471254079],[9290094798274413132,15602653167891511212,3001807574123993176,12254829638350939683],[4859796965824171484,7272953371081627949,15612870704750305448,14896115529629820877],[17998655974594769769,13065354223560726639,287459449311781657,16572632507012264635],[454210549887860943,15778385493969864884,8365150289748109147,10562360788670062346],[6576936999746624951,4574417875466609444,2700060000926917937,6239375966959209832],[4972177779967936020,16249333005211165413,17016850444398986948,10098313342913829139],[11794434927001092984,1318777730954872143,12078386679646300786,6001263700142566691],[9524552046462056135,9967314029993035221,6929400727131934620,12582377769889017505],[5493420498608724755,456713283009845876,14429004878939623407,7753634382659405546],[9048970948983572747,3173584556818155379,8180346714902502476,13678746546138146035],[6989803629881199656,6882469808924036224,5252009675138065085,10362725584196780991],[8505119124822982075,16944572278156647513,7114655403336238844,1925227454977855126],[16733533706141932087,16331255768230017853,5768015000187016451,9860031089389287333],[11880569407062639453,13645598435945338695,1515382116898423243,2794137124788757501],[15182678045319851454,13620897765119203057,4931674628236790587,1072161120020477229],[2382914845724632170,3876042562697156197,9275566667539802114,221210716389500518],[1538692935132731934,149301629655521331,16546563640394296223,8420373188812833117],[3878101346905384950,8962308828132010264,1865308200087321071,10562053773214877426],[9581852634422340138,3927981149130452540,11040929075849361673,13009106714563094436],[12504614537065918435,2121334948128396995,7951123356369732557,11635760228100434096],[3908317598172282626,3308881224624802016,10703439793720562616,9070964645185962490],[17505105606931072503,7666698186452924932,18056152864528142948,2521470273270427499],[13895491130752346436,4013767523703958921,16472558938889629376,4307058230477809678],[10992939369249441166,8683670885480942868,17255349025388431040,3099765732104904818],[6078204059155096159,10100361130148628164,11192117289235669472,15597104683216201222],[2082110256668037090,4732839769391378929,1458217617940529349,12418490755731651859],[12282552977957132590,7035836527583343471,3549402063186275669,3506958726345838335],[4857665062109513208,14608735009046797790,16055907509424740399,5021397111119996955],[12410378746683709703,14734600579381666012,9059036735747091277,7553011093315234138],[7213250418827730078,17613542626594340178,15886653326604112549,13514998354064961697],[5293545459564884584,10607261734149471441,17308175442057157200,16380802717869800768],[6016078365452677442,7799792211180406053,2764732371013952573,7502657487227777588],[6273659644297839820,8956806679273974184,8944498110930206162,5260319461850581739],[4636716911860545098,689935192566932621,17752774702832791110,12770115172695249957],[8907667692021312612,1615976735864350180,381213630108860211,9287437210795679044],[5225400484843816178,600772053619460514,10547682637746958278,17774730969038787722],[7757987205342517147,12482180404456961816,17564867668388285370,9668065569554153749],[60052652555276193,16844709204146764484,11092346145688520233,5055281796833559350],[8801113841651640054,6384915010817278295,11001197274974244092,5274134990949801268],[15010104248627940538,10934301525817778784,6126744840481285526,6038404260236147137],[12438301491399174213,12454083667044793080,10390235501283258664,12872772247201004984],[3784243449072034777,16172453972296753247,7039459999276151950,5913716844734991690],[1198620879169761049,3013795866280327861,11350976736807784939,4505328606016239539],[7701268079408511020,15977861796551631750,10655691160915184344,11186593392075136435],[451006711312039502,14061121016699279201,6606407701443222939,5818608274534651165],[10913275766302324299,4708115327849158880,15103620681292421987,14518320752545673837],[2185129917271485162,11656451775488617864,7682146144033326529,13504420575915082898],[18165039282716578315,17620767570118576135,8180563531233075482,7500945337342224334],[5208372749321272223,542971750235534009,15941320416581575667,7525510520996896969],[10184351493289925026,11571850665578146484,18079772168280162027,8434310227924961653],[6540370454142098016,7990925732520687320,1267994901662882307,4163963855318898014],[6348333381359619611,11409444053433971291,8866215205525078923,7955998223113948589],[10760577402913719162,7439743413515329002,13567327074721828975,4174021925437701431],[10806885822529535326,5978462332191653030,8187291282639652128,3884844500390418246],[15801996932133734435,14134503820351682940,17900235866777907491,952673144927416260],[3197765506719048572,894222964610799517,4755204552737720477,16459623755210954668],[8124234381866897281,16438142867605077159,6453873801699652975,13007810726982121674],[2318876495091942155,10389254732334347264,14519556095938414263,5836957146244359555],[18213701001203527537,13575136969269383198,14059427934303536070,503512688652147150],[8803833588828027532,3262131138800695172,372932628413368295,12788673818042617216],[18162571287074823136,15707838474850460408,8925826156699250948,515117553832618470],[8789241075520158041,8103535441185534920,15468665623176482759,13768187664596197427],[5147644474536455237,1606832441668993213,16623256622368106761,12088022986462701717],[4950554206230961803,8871086543689580464,7384080107477727256,1433443229341548817],[13465902909560076741,16138367176616748011,14336688634769438758,4458158957254552862],[5862185405261740987,1589016651973739823,1347622926856209510,12503699549518197113],[12128204405535342514,16613591849247797765,678111312748075928,5313998457163684286],[3375569370287352295,14886638577950801630,16759606336662940508,15988585130934089203],[578862738950274650,7919872696997823782,10162315719363998172,8565400830115043546],[1196977403408096330,1497399658581807204,1283940148608564345,2058020827890494503],[9935480430936150228,5630720125271386938,5585607895726812438,2625900685824167275],[9810562540661502319,17860176665284024150,16586545325756230878,15436331032580653846],[10376983577415655458,9645228624751998068,4242986505261590654,16576243758121928853],[539325814451117749,8823779467637775688,16348333381805034900,6919405240301177731],[1652014862488430328,6089702010499933254,18144913219765010368,6852016662170204808],[1038980863193718372,13329883527983539856,16308032417431487849,5991510573396959434],[9780455455005743007,9785488634846276436,13662528915692000700,9898523562393686336],[8968907784156378374,17881854168906589160,5964534907897585756,12328105581162601449],[12711282790029521108,13688339528443494513,12495843224858708655,4133858138103952782],[12516827171880078444,10528945364761887480,18292655354076296295,231702470194729142],[9011822781340486655,15464619946049233926,12468899832257448397,6110967513836221463],[575825547642631992,14501486562359986127,9049079925253602162,5393613878802105434],[4815037050291832981,5767233964633305812,13541437126475946011,7998662340909982700],[17722684161288527098,5227515059943355703,7833480524056816576,5661793309034375419],[9925675752664568613,15655509394252794586,11427320628402629666,1632426474276195610],[18013261024456881200,12410272222425387988,8820656826244616312,10510243413423249736],[1614377023801138741,9685546617895555253,4559494978903389537,4186419770543516813],[17154850880070158859,7685686609110971599,6409708735867516652,15873594857904157051],[5496044468473835334,15018052981495272275,16150224525704921265,14865663422370598396],[9158134122996441431,5471478110671568272,8072612442575057272,12580111836415154265],[5901136192672236225,15220558167518777042,10951323231997849560,12868948292405166355],[2316604948383137529,17150768365418739875,3431082309595725197,10589077150575584697],[2063779130734727235,9717197293897620395,14087787020014318916,12264291357071818831],[15872733503048147293,5116536275730584701,6540459444591741826,8127671680119636466],[3962783868116698291,18000828433154362969,17804881771144919822,10730067267688990096],[467032526604872612,17063786877598535412,6958979064206932025,13040245717851269639],[14992810682725439354,6771478975821687992,7493930199400654520,7630511052374444249],[2990450728193150703,16457649343239500482,16728466186836611304,13280448659587828556],[9159072801540977250,8447917201941696158,17829410475296359576,17271815414506154314],[11850313377149399592,1994270184216033892,5461603827307980457,1526285294824623945],[1754804194062792619,1915027023589817657,7035384838233830622,4615931073078982252],[17096980554472022310,5634220098072675591,16611641247160882419,7496743559151983052],[12994632154497952659,10087535994782413148,4063475883154094369,10136735604095522990],[5482879060413636096,9217891981158875425,7460874244937873766,16337685748355464920],[8010127158915126312,6882055396682282099,18068349674873117139,15964296677155183384],[16258895496189403716,4671567062943603429,15054623319100826517,6237365435127809042],[577167168698897301,14157451918656938010,2515974286416385309,12895390535003696331],[14183132207496896438,7638399113152093232,3210008062927661240,1557231888091421725],[13702058726812573872,13140742807593165047,7157380716686861384,9350976131606692933],[2620054177551614235,15286312254564367499,13619004359851884357,7834017371660318613],[3682135741713125904,9140590605262767938,11715786834979858724,8304592807690257757],[833775849838489673,8166136586847896737,761033633442994738,6318296541220163510],[12453899695496220871,13146280026081945274,8457997252172768911,6083875677857490369],[8817634253469108611,9474416122130056671,4037938064191915497,8801909319778504854],[6755264777401490590,12562908855826632504,9067050779685860622,12985896165554029845],[5958228811062956543,15901622167785542311,16691396591205695052,15706404921319985454],[7736637174193992264,8188823918171318454,11655688167087817361,11281562062142935258],[7117774602515445403,2123744547372115593,6384201176462635640,12605775364566431743],[7304025336655186122,1219129204060732684,14051942999660349540,12165405417184741927],[9827963106808469162,9126547547526853925,5464253750760031223,622707145826751834],[18206637148122551802,11391717369900737695,8846701331060046708,4881489482935984614],[1351243216411223862,12476048759916840180,2087304245433895406,18081099647586969693],[11509936393465618210,16523913008224420867,4517140565432028332,4781808226938474819],[584841328864398109,410150332556090971,1041635412435455581,3404945434433605954],[13780703827976318028,18254054750446557121,1775808574470679316,6998436976258858776],[11083463481792348694,10529969790449493025,7484937725157262655,11669760549652765524],[1976716520335678076,13298103452750453267,18387515550655159761,11150197572882466909],[15097656650616655287,9829434122893734992,11482486785646631143,4616451947158764592],[14754794161357194596,14985956708712071816,8084629688684924993,9484634706722410976],[18376046251164995910,6796649211716893676,4332809576138586026,8918565009434422891],[9867132226174594770,16357317497702426847,369166628888978262,529070287299874591],[12660541318224957503,7751159216644795606,12737766235309304671,13973223422125736324],[10393625924273575931,7107898864719086211,8703491633385097869,10146576407275770672],[563855077970338840,14450570883803005940,14213886649593254824,6734075724508810411],[5809822225360158902,10963782140469056350,9288269973698761504,13552768444382740517],[11453863743335832531,921943423969155330,13359219457504986680,444683779496223984],[12142190093078399131,3159395431584780884,11560783270505048394,874915596265973937],[11702759784215974157,11417096476558689710,5620303257548507558,16385826417251041479],[1895177400740515490,18269290800715750890,646334184603692658,7241745076270145065],[11498244934422127359,13326318511210719210,14398896559499561680,10059364645588205654],[11456365958660323371,12272934637645965095,11892234283296094420,18184370973522447275],[7929646407028259905,7703758429379216424,17549793236161962190,5445705265836368175],[17079046367940052552,12106544965666565661,8598669950381557769,14342229949029202612],[16257569728418219926,15724257536426073173,7589349524450623182,14233773932858164344],[9782111522081721209,7392951447190835880,3954030470119013147,16622371805559000972],[12339424085675251225,8482931137599669833,159502083654270541,12392437605687628462],[4759004560566612888,16923431878380208410,5783815296268106051,13735617212286484153],[13865986027240832648,5443755452633151766,17755972353643029395,11985194102166923800],[2773774041364344885,11745023088896443527,4728852358706256934,17459610194720120567],[16638510978520119457,9141065080124883560,9580804420739687289,9297592000743867953],[2440723882463895696,15097425965553186005,17317573626338974115,14441851236190906602],[16694704262716856689,7406130799330912118,17123722919444195479,8978436420220610801],[1143355586868964435,11735248383935781206,248175057965396051,3101285600829372097],[15580585561837704940,307365155042426709,2981067968515877150,14019120858088354674],[5813616240584340305,5085830763531867868,17744603054546918078,7134664144039352916],[1868072892650356124,11296496901848921861,2083158914090441455,3694021316921030822],[14564407973620484306,17573630705503743368,5444464415630424702,7374196373201448511],[16474140724257680583,8125172583675152575,13900711374593222287,7647632509191402645],[12803047783756091253,1884849963223529960,16063171531961415402,12933284957204713559],[17537259900556114390,980068614706220873,3824106782012882586,12597149321008463532],[15916834179920728129,712718756311537320,15253787490563814082,11335476671122676441],[11074727501895053295,140486244145447095,10474515306451448529,2996818848886253121],[6475965285856435926,17360344387108696515,17108105825810998685,3801085072172808509],[5149716575947418232,8631639079913180748,8424625470242174239,4761854094956690611],[12628861748150808478,12724957498944478117,42585547972844218,2556075467587737482],[12386184856090841036,4551578519594757133,3047878103990322674,8576143724841367095],[9042023176945296776,17640300589964397868,10980746869908578860,10728592020526068405],[3957484376937247431,7447785236455528266,9464164615969437512,3531681528490828416],[11602642417998126450,669309806170723654,1574904701806286472,12219125113815148453],[15313041078153714968,9694748228277844699,10677412749904519886,6832227726731857134],[6536064004728810240,1859722290982291827,1148982352528375171,486330548294635865],[5471229144872800830,3446933544261759455,12367108703873955725,12765422932303241565]]],"queries_per_fri_repetition":[{"witness_query":{"leaf_elements":[10956800437136520009,4016615169219485476,15163054448147996767,17617410510801141276,9725304596854650837,14294026300672155640,16677961064159179164,9741314083931142977,9593377771718583504,12145026932833308702,11445678825825460167,5501011893262234832,11569060981376095023,394715657658652570,13340968455987149561,16014619545651688110,17261136730935187765,1847084653938112278,1330094808967830940,601849952621757182,15211287945553074495,14295863685603398580,6055626057251821018,3586519582232292981,15893683022650982598,12761739434817658501,7617744436487353441,13908623501634690848,13920519707619166796,16464238078776225274,15381992288243169532,8225339449993189334,16647818716741499407,7396074486504376307,7185558461889724757,5619077806244885786,15502880693583944545,11762406346021583548,1958775939623391200,6589928347099785942,14152427192842149969,2782610151667969082,12856846520899421134,17562834152932650864,14051182542899797375,492291640210071464,6828504764484269245,14120045560110589805],"proof":[[6752198598302721738,18135535665197562464,11665727934817540418,10418183108506324207],[6664651325925887949,2237857598587136244,17661931346376051197,8556434779107395440],[7109684067112242819,11119321242402258143,14368212425898880271,670255123356233199],[602255887360160225,6668813586954066892,1364064819256940426,406499742673116534],[14015759502140894574,722299230449236255,5215229481939155576,5015049398204191013],[9592020898935071122,16501130315065745633,13541017050739847806,12983077203843462092],[4692704175155885170,13444048746926792229,7161808143868802145,3421538119569561591],[3822390485681600475,14740666102683197896,14250711937950006327,17660862114656092214],[39624536530379720,11945749580271682821,8560236261423700303,1023723782677616415],[7553116626246622824,1539886974812115930,17884666948276720069,4253140937911367891],[268272971467593583,9471037156078649991,6473506419207491997,4253500741137287920],[3504719809720692357,50642879002120538,17940460602199364505,13135850952009658231],[11573513630489351156,17170993316887061828,5895684437016821003,6349206584915327285],[1483416130757766283,14406686442493625047,10871489070061370751,11731826231337439296],[1654051821616667915,17439241697756315745,5505357364838264272,16117825770839750817],[10823650876946644246,14123358526180651626,13305075459043518760,5128704132138141538],[6462776555116701088,15525655674137881980,16035695303909529133,3948951991356416634],[14990919738889548463,14601740873702660733,13722172064873565400,3934003297879459981]]},"stage_2_query":{"leaf_elements":[7603259717012041039,12123293673026701864,1667005537718418766,13343530043035377265,16229641884609625169,1932968440243245993,13220116114734612290,17826238664997103806,4918460280333880060,17332739566416568761,18221729651891163429,500779102778008397],"proof":[[3011654352462997955,16229394930440659539,13029509436080763989,14188961144884496749],[5064313489624394552,322166560832189844,7678515604615646447,11021343071213988146],[11497475395667228526,16808679731451392136,9748637776041195301,14295235022678103908],[1681263660817512176,18145192287706504464,2309806167131806465,13547628044997168760],[11798613290939739172,2227874161422226735,13794767106417616890,1139412758850237351],[7135114494722794429,5706292950919743406,2492375032174863136,11209639703998571959],[18188111135884216281,2069282334881689534,4904430435795810154,6349122198060547041],[2873644077227311601,18121301782683189577,18118572952088623595,1999378401803769464],[6077569456623341767,9977001155158867285,10051744122329839408,14730361592469583219],[7544137646102123743,11616065224293658978,17855192433617860491,6340630559990970204],[15141860457852162460,8816177837343408581,3061136499444796469,11859784379445625684],[13668418439263742599,8662058029908527072,1057804678038980049,16488817350698769973],[15638299625033875194,3814095488023938057,1922043348406428681,11197220294942478839],[10711134340362421941,13604211889058222199,17838771499077609550,8251898642726060577],[12475955198329395919,10001381503229577868,12590774277433676403,14922101304595201442],[10522022782259724777,9454967700664331446,3396246373497327837,17451906204885034306],[8145778046421210210,2860455049165508753,3652094236100342479,4359517581192865843],[8495424016178591919,11266169991088301994,6108036218129798286,345177820090576678]]},"quotient_query":{"leaf_elements":[12084566971512201384,7860859350989600261,12527777742674476980,3903195513031120232,8325999696264639289,15043908439805837554,5917671595759586674,7843569669052498307,17625264137639867848,7456398751980847009,14150859870624192675,7762945704535646618,6114895061828379880,16473531464155878256,13647427790328282416,4664855897942481120],"proof":[[10847998976989147508,9039369010984328727,1895562156986259103,18359334837225607857],[2474713194995833905,16118414070107225571,4689636717349813204,2830071943194319487],[15907085356321827442,2987969193376748086,7056127764430268933,9897027133384865287],[14585559999379978333,14937026876029356109,6297035073757219940,7312309963703427411],[121569599285314667,11741064244216680600,6323101785595423958,3427315613656921041],[15628308458776891057,9287122454973665499,5575644180511222197,447812530298680966],[8433465889120886894,8062084547449177436,6112274788660258981,2090292853242864663],[204111098192462333,18210558811104104408,16081006446550714511,13877637471383950491],[14525049013488046534,14256671876004403371,9026402718127125930,17912442912702240904],[2976611905279062844,9168680984733395753,2250929589380577571,584569615194996318],[3209527490547835131,16328503702206047555,7120072841536051046,5161385254297275520],[10846804808501181849,10532933718013279417,6948993183311001345,11299382490190631889],[7149485757493958015,6639434196865076520,3990273658085675602,14701670835452387595],[5427900185970993722,2607331659258523570,11139518153141102781,14052025599593841386],[12082592285822588971,3691923349472861698,4296015991990112855,10816844534159430874],[475801532255172402,15972410542742519833,10089020905445811881,10067396461365728403],[5910345162413418259,12232518876790913063,13365584625018105565,9885214747097619525],[5753530755884239749,10301276785797990545,15122746014394191484,15288087917740272066]]},"setup_query":{"leaf_elements":[5167773860701632351,16799459002711026403,13144958895158404066,7608322636610089497,2964796677455828154,16223875306926334592,2290474821700415294,16445138435791013416,11481333739781656832,11214040520641880670,5254231738744940828,9920241602847125692,14623592295993183096,8522424736779561371,17495356348033788559,4089902007598981390,3903806883936063016,9202930421350567526,226227625405995722,14662959717060462349,12732557059715164654,11407559169164924365,1611304880401186340,11159276719552357002,4369939100746221585,1891149228321660883,1889548770734121528,17295542978772757505,6829516312949641022,4448456258813782291,2288199181760070136,6368746249292920494,7242164780063520149,11910621236118741282,16641847143877622456,13283316769796599238,12519721741449361622,6813793799771939753,2589668609372103339,6847276864161508773,6607834497873155292,1475817985783917426,3677386812292396002,7731856059117986087,67984273707321623,8800458118804840630,9792148097605396790,10819135578548885632,16461009661237784036,3016872228772886421,11417716543398955732,14371724428574178393,18114010293895970474,9598223373817830693,18368124365890100580,1927573342093954860],"proof":[[15835077135351308243,11596654115457880479,17484505089420713615,14454965697559834847],[15225724947710031413,12124730666859711316,15376996803598997648,18225738669767819100],[14875490427819459960,705676055831290613,385016262356136169,18374562300998908561],[475609576539562006,13223191181609232775,13383762486183248231,15726704757247486241],[14041756676272210982,15265500500185159791,2661194100335710598,16977625858341076079],[12867317001011028958,4104563723347521167,4002302389538402967,4847296974190095679],[175726625704092957,7011655318382801438,13729047547862529654,9954912715103442923],[1393797796045365978,16786560581213087883,16936798114723990793,10740158009789748189],[5245998499145533566,6129819344314707243,834704392547834999,11366176155606380348],[18308921611341872003,13362166912818254959,8589141465032189939,16150953005620764240],[12033143939336043659,5310602129043427714,14942309998634516203,12188059626390291447],[17138475174445671304,17678143628754689116,9803707619482819894,15789236644395972719],[764715431429594446,7302367790783674316,2749070974330519806,11900632355230874114],[14994905820216668761,7339204997145222944,11130141542893439656,7518025684917294576],[4140514054788374341,9655354547735555294,15727253409382266927,1341716938191969257],[12497626645023322875,13070716943817591966,15158164119016479348,3614398766338980442],[2438603752298635964,11205646292568014989,12752681860005496696,12221108489094263080],[11345468380973371761,7421741894124467201,808905749840165619,8573459891664669074]]},"fri_queries":[{"leaf_elements":[10830835142727724664,9870617282858182297,16318309062627991658,2947408352078524016,10322691943733153473,7304225240930064549,7756186041276282289,18044133570381736018,3967282307528019518,213320980697008215,15713749757271681928,3842539261955431298,8503503472524552230,16743936063302261518,5615267500458359060,395089234647510997],"proof":[[16726311183114718689,4048545961084655601,2256468410790884645,13801860187633923414],[16980421087507522942,17349795161317435429,15445877543823258112,15948074026932260060],[9459683688817684846,11377685454017887675,10532485565927091643,9029798836921948333],[13304549544293907317,6545510141086034861,11173564932823819311,16720468763330986668],[17547219019093332398,11486129952647725686,4579539679824609307,11704706409392197410],[6633796596627187002,9786352562952076860,18326248697376310093,6626181767743309125],[10194905853813956595,12779484431934771767,2516876404446116516,18217237280482493495],[5937092067092674849,439622637037166737,18136498911262384407,5382893474313178057],[14440928789532173014,9861465527449664656,12720342157407240885,465952959215450145],[8914167239552695253,2777961869393026146,1139388367520719451,11420159662598014088],[6711079983815089121,4377008470714437941,14814301446859224708,1978546897758607876],[5839995143295263705,13825482331557712172,1516190637648167283,18387013452233045929],[16403675971057122708,4455447918697936304,5514480254360146136,7021695618158070389],[14140435843006168847,15329888973767052688,5818979985613114090,16561510480700860558],[8093712790465185343,17045227089599083698,15528437385689217059,5890612564995452626]]},{"leaf_elements":[11909553791926573797,10991007988650307489,6485395890866120096,3364915706766085854,17915755304793717081,10433462074023995244,4738342825332570419,7660726134023559168,15835645071405951253,16313458992744733119,8728835137882695029,16896274382002712200,14652652285072362803,15131968156340642309,2372655499682433397,6279385607207365795],"proof":[[6118571161676320470,3070243821486991535,1604976886712301641,1992554001850219086],[9915915575891514970,4082429987509841289,13320205547211205501,12694817102492725486],[17364951414809583770,17021127589971993276,1657194198495689403,5729634241167229925],[13101857180483970391,10695807797542328,12660907448439435968,13927460365501964870],[16203053691490772089,3629154720638105366,17154796209189671667,5793377300845529250],[3524330487136395072,6713355573582658253,11408790426930457050,10118510387697317527],[7664942808752755819,5493308443071215412,7856660143199904100,16392934850962001341],[6958906366489989608,4712718252802886899,12343510576158809399,1481239806858494956],[1064268482317296268,16547594008276712390,13918276799080788380,5734373578637523411],[4730728288128186260,12116638896270410980,11830121059995710732,7060281177905349971],[1266063486089732393,701208963041608599,13246466517302653944,12418697292459632918],[7319711677730849506,1387767038450331314,1885207669250705092,12863040643398367572]]},{"leaf_elements":[11540197650384365893,14618223475792295612,14103637825617551810,4970746290136264951,4056269676992286349,14585777954262973227,338839666667997233,5885215035990123268,13262986599954728035,5710845623896018109,15937461427674184999,6914785152329069140,18329247386435427252,12771321253590574742,10915142771365857137,4535403085148719924],"proof":[[10154542463487841043,7090624508145942507,17704535025991344399,10606122419375593012],[10593703974708658899,9764791582235115257,1530475387372220331,5160236531410074088],[10579227375362797451,12474214048608595504,1765000964623013207,15013580320158775982],[2442307227249023204,2836728381200298083,8259430767169545028,3938381552100089957],[1819926925915943791,12461779958558420431,14719102666324835407,5901907463783219572],[9844078596601769455,16280830712084230598,13548283527964823674,10622052189623831942],[4589909149485098895,10663983530872754366,8129327665054458706,10370950505635386797],[11313273649811164633,16795520285038283093,2008212290046167029,7188039683490257589],[16983257398042636872,17040768422560532395,2829569793533002550,12795052714528843256]]},{"leaf_elements":[4260072097349268987,12550015503456985085,333063349669018006,279082344198923686,17477761111927682331,12729077034354041187,4202365492939077489,13971600523391343671,6243965989012774545,15757643417890648915,15746640127370753003,9143758436225674660,4355006321329040479,9901301979913902526,9861494133048102201,11709816127480062270],"proof":[[12239906512462889896,17726329283505917701,6007481971109566216,13653007316093463334],[6434787970675838137,4085557441351039695,1770609499456209960,4723059853976355240],[7667108744881587346,12341998262918987456,17523237867795766491,16720129895947754590],[4578173271220324555,12680482371809381019,13924589684350848069,10314713171933887038],[339949651165849554,15848658899700214053,967027941358994397,5823317764943347458],[2375791723762674426,12526714993249209225,4162105068072480563,1468095445293474981]]},{"leaf_elements":[15112162619941646893,1821608103102665887,9423567991201246675,5422374098098412233,13334298690222395694,7116547114913100608,17137421614190653768,12989013485403452416,9761808820645783346,6024408880881676111,1286632428709118795,11120686510661713569,3053490952784339558,7755768872266450395,7896322959599836102,6359510456520689594],"proof":[[3314636004366877644,12115243789179599972,9448110075142183071,11904601798279540413],[16164155964825489710,1323051902070541057,14099145996819442888,46035974993910835],[15174913838320714374,10422755460197685352,17655716354103931706,9958437427906184582]]}]},{"witness_query":{"leaf_elements":[15967835278053744437,10454697323189921834,10036658148853063712,7028912399877353353,6900578822835900890,3320350164133415287,4015245738898608559,8337442236982519256,15676379157678392436,4088258143736731142,10699095180316047670,6944256328224357176,1773666027449051824,4808799053077558754,11833723864546879812,2268761393041935267,6321948342485030683,744124760552048115,4257098826522874740,14548931442223834184,10055575842751351813,11513057901772736101,14560012075439434410,14288138238210523113,14265488981760872257,14849715740187940960,454101117217004292,17950166924658557470,6674054974898526151,721653984118711021,9145742272425945653,8182133362055061724,8029613606079002308,8855564663496892714,16379957118342675382,11479772528274052320,4861985899340909517,14116526599836212065,1169086171119516529,10304592562196335863,12544243373756176200,12085406489764493794,10488355180327792279,9295328368792552389,15771152638741580307,12558459102495819434,7614561797659939982,11364505772821808218],"proof":[[11539242677266793006,6556515491993668786,13299674511153530285,87661795968007572],[12516893523085981785,17204719503431465480,640793511138149883,15477640652633912523],[1588698632615772432,4535881944819787562,15259912170411867012,11604548063571279042],[11096052732081582375,8809327358026436654,10215778765924193430,2827939671546317860],[10951663354350185002,17499084301786331980,3534549234327708883,12313836179889267721],[16912434601128852743,3970567448010179845,15767836616883905235,4209911374309854652],[14623030446376925000,892452816995349059,65788969698374495,16280184592839583706],[7778786774757891604,17046937642805676521,15961157119835896093,598481401621309869],[18370183641620262158,11516359540090645163,6110122993533317047,4697400380419445391],[13339807194399808547,6289625207198704283,14399427664579559444,10219746222683161912],[14002764699212838793,6890431275792177096,14930506911017161626,4620928623380287755],[16241087653688700464,7402111262830771088,11823322453208753011,3639392905214648153],[18332052504764140603,14888112186762889923,14475023457944753154,18188229318778061536],[630095096416404986,1640194221911874452,2804777895797792727,4959917175519887554],[6615580111910291235,17158400532750869005,14075980412418991402,7943969945613903724],[6843275915625378396,13313527648558062771,11151963286780950051,13010957389791283076],[13347331925152956122,10669739809125196321,5406170901560160450,15851937992199374695],[18109232669379617623,6867835609585041411,2236241402565573204,7623388891220169725]]},"stage_2_query":{"leaf_elements":[12595550057895565210,7810464401506695136,791380760507219675,7563313183919826994,8057930786197876082,13902063878136843173,14024684158242612803,10766270897198950628,970484795005958316,16984444167334114091,7741051669025968531,5640820664055043135],"proof":[[1104960732466657125,6021426340037919342,100599339215100383,8199446651269888833],[6017396420017428566,14799832054093674779,6238089402138444327,568779504221990596],[9993716312118232955,891008455163854591,11901220301693006295,883197428824791547],[4509004056169182180,2903256655189192816,4643701603888178834,15704162086636470911],[10087795959434705789,16636402789255873846,13241296579105455903,1535849807001832116],[591138067853733016,7663846859323631465,4361090355551267254,3913404965469261043],[14035975585187670871,16711016855043331305,8432235822545157315,15001695085259942807],[14411556671803374669,892342768110879763,13475922777427087521,14266417885638235660],[3079792849924801609,14586605448759181290,2029734180667032692,1161249566788146863],[10331043757249172204,4360045983469540929,13215374347657373138,15426646538232705313],[7392476435304511252,6762408383179517544,17943796654162151600,5100280530230315836],[2803740233413215151,14389611682609692030,15492540174615668894,10835995437567797693],[11966659202548077697,11744768501646622896,1820391665236482247,3358038748010637873],[3776044893172961934,16312887028810929461,2800841021573097243,18337022652285174071],[10093642683742685655,12300017734414551674,6297570289714101121,14526958119650727446],[718527569481666854,2262066059440449357,6590419177095530527,16457316267934394959],[15304160878879410975,13860052467648623821,5085012987390101737,4197191864544600615],[5650561839148309540,3486150289610249585,3876015128443138941,12410659014865685022]]},"quotient_query":{"leaf_elements":[16195479072416565305,1225519993691914477,17678252556029299641,532009306548680485,4567214740614094126,7400354208610974648,8321607578702357936,9341621274854102798,13625440397820666584,8841224488418376797,4839252138517289906,15268739144866648774,17078206386705906060,14666224114796791599,15849465601656362874,16355472560909562247],"proof":[[16834545949238703100,5986493354972818232,641733028859338788,8275747071263379652],[17840726327235552011,10476497776627079982,17767713471221815807,4866098393574194878],[16598821115198872526,211522958675582777,8982531886327425010,2402088878954140942],[3001574993095851757,10317342606944164546,14990610586079038878,10759630050156553521],[5871275950398773946,801534293337423053,18200955267204830775,1890197523871470467],[15047027988378604416,9718825003022101598,4183314247438405887,16845958322320286355],[7748435801680618467,11549671194900501498,6348013736179749444,1206639745130054379],[4127793055382057078,5351065199870922801,2478964955367515663,15772832819955502975],[15220991465270305599,11257419143729951214,2528937042881646649,13486446986735005723],[5178562465621927615,8971354030173288347,1738561817871520269,17792652600648689178],[3562531498781494510,4572396242299976438,12448790459962555856,15124932265190624089],[3698187506754841886,2517468841190313000,11171510970634991283,40772294532446378],[8836541230121065314,15552207285739904021,14757814269843148076,16668554567281511554],[8151366074046698707,6579170121224404695,514284324345437830,12203921798472837200],[11265053960788701397,9662034351725539284,6910477665434675016,10289920329461081495],[11270158975308841813,3798427953389968762,15332752617957559166,15183727771167407389],[4211902339597750480,2955161730889049897,4529576896211024578,13213786482739774268],[13384900533731680055,9783421784220101310,4338791429773181805,8092902424943860467]]},"setup_query":{"leaf_elements":[16001198719081409354,14526767114220296612,8533021513914602259,3752707352439534371,11010815821002621222,527747824206135030,894547485940008609,716156984159108992,7359589136447699560,9039687224637334680,7684145731657233876,13455448539228821551,12472248562766328852,8936566297722175071,13056396978269937255,3726681386289146952,4819268069004063159,16569542232509213694,9404550027771767701,12545421344176353147,5048743356733595547,2742424145407883687,17547392428259137214,13198721765017447777,9404377134557682526,8806497685414413298,6277360404633344553,17231894288860826174,5686643160703523288,14526260497985460008,7862228044391187907,11014794128013868726,16336749385116995175,6768308099546926383,4457831226140585491,11167166824392523895,10880216071593260265,16808318861298276507,3413182077772138123,16595811942969280951,2869260745410524661,4821202593979385946,13478011081821406405,11295158055830269,4267735843823864920,17920252525711650172,7440283336591268825,10127470026587830375,4782050166129856464,6891398141581616060,17399717225949740285,1537003579430638102,16861354439222666741,12847181656191717924,14026539948241408048,16698376110199594973],"proof":[[5430877387750837126,10297123470200709987,3206281613472431805,3704590413765808212],[2805244988406758111,633122292542946055,4698738336433892733,8273268969862147373],[13251802663975505351,1830876113697533338,1204420198181801052,5134895538020170269],[8679167488560218511,12642670313668250438,2192816643549293436,9558453558639499896],[12145472829767483613,10647283226103212942,1953502185108762016,17708378228132268082],[13633895800916630719,11257858324491906016,3121691593816751847,15728378889437437621],[15358279753111177510,8282267005797762924,7581895658275924320,14669523002372359281],[8262604187822338987,11527342035909122535,8550165894918848524,12067067563005324895],[1632367458000107213,10214364986997475483,3372699590516695304,11045660917052117917],[13342230358248033203,3602959566143612306,12716162017680655676,9599401329472901339],[13326240869470327843,9265323623761994078,11756129544512507011,5810702947514103245],[268395671618085653,12049592238822716168,16218157307856613073,13346725646531946564],[17681300962365659422,1163879470333307969,9566467508139754827,2498262622360685460],[15860574550605817228,6499082533304249041,4215094596835690132,15888809117193388749],[51548983047002313,2004334856904447945,421544944620297938,3156104850689426389],[17858135262989172222,10905517750170358618,797982560556308064,3219525012864023578],[1476877574533481013,11118137000535492692,3731065391418363315,6636810023102627796],[17936505694674837271,4659365505051781136,12404658051927984982,2863478064185444151]]},"fri_queries":[{"leaf_elements":[12151409033255495226,17960220693730717744,9462720124189469098,12887527693105914946,17460225521002596473,11623746453639747929,7035982510616379046,11515029762825957811,9732531173244227461,9043950592256151978,9519533561349106295,17259168530701213548,10978316574081472582,9639227486933148747,7242894359402751856,7393330195769007929],"proof":[[11703682302830432265,5027632575561422566,17918130830465466584,11289947946677559258],[3694044709217341413,6272703149152816236,10803214606121502161,15567632334753626071],[16590177831087342805,18155280540672312549,16532602977723424631,17843836444802918997],[10836232928406243328,6711504940820657979,3978467505061814691,13054993439198670776],[4405826884971785652,2169202464420086521,1346816621313760746,3810933539041418941],[3316105712810237931,3588444819417295706,100519366084687191,6022306128423544899],[4594553166523153025,10167187605452219144,1202665512102586699,5435057317928775749],[4348855587617370043,7498053577572540410,7909799331223875141,553568326732889910],[13552691897892563987,18096144281730013063,16100392367401402165,3741920675210086185],[10556204474307166175,15935707966448357227,18169502694736297513,14220272718661361795],[17745729967313493115,11662380538298618792,14100997794089376563,16272899388151066809],[7463736761267188537,9754887641601216338,8092856445979436555,16491881630466829747],[13100087524715551017,1501710972858205191,9699173327769304093,13586132912091159888],[5082013639675312114,8728135337306802089,7204467043113139660,15643198352985445577],[4984840019775373806,16088190193166921639,13843793028378279698,1588298860964711884]]},{"leaf_elements":[11251650428956227374,17648258676313120764,1175723080978758359,458740429364345062,17277834534543899016,69035217316127326,17986650696282816728,3143263694478795529,13709678411802718949,6915052284351480750,8616048599808372007,12702559797432176425,6861135157350779370,14523181338111459457,16397889842819787366,16687499192181563475],"proof":[[9768038190479097860,12793983158490121179,4233454531548458431,3747334538732985921],[10357475414234680292,12025128058593245918,15317714733002172611,1543470177850933238],[8608847923255972600,7959709642526109400,17019621730582152304,12739332211002179650],[3840340905673976541,17583158884877122641,6498936729050988664,373795813272073964],[2593828055546587031,17244562092436575625,5966603033086343083,14455182799248268474],[8693290120816367885,11874045509463375122,8526557457226211997,8614262064166063373],[16581326877597808746,7741874115043504194,14060333386761339753,2034911274960614034],[7191505720709442762,7073740042856404520,15917486424744152999,13327677089760528694],[9723687399208067336,13096617237697917497,15518671637997264092,4717378280406111291],[10440980096124791271,8382896075114279391,9366855092691175525,5665408609237465073],[7170806720191803061,7250966952983792109,17485718711037404279,18440890126078346866],[13210922695454159135,6718951634940607322,2894901244045485440,4193003599784294405]]},{"leaf_elements":[2496528132115510224,12963161535843834051,16316652058779413341,5172036899627998999,5481139020895370507,12719648764474833160,4801691884592889351,12153231048593200948,13243538997070142927,229944353625264178,10172696167690264256,4005423632529533482,11813753736325457816,1244266476477070860,9572828658193202205,9888619315377075387],"proof":[[15989823914975603550,16121425107629213524,16732466620121333110,517417271677174517],[13489251417302665240,3776065376004788013,12225050689725998106,12088949839991972633],[4622219837447531840,10152568444948454672,14548018156755743840,15844535159192341561],[7610961140545860834,6650691293049797000,17766103882919226307,9626869366584980573],[10330852986372635780,10647424955145617254,4418376218490648719,10145889670520521921],[10011628959893960283,15952983148755930352,1628097494678866771,2792277436601637150],[15897552894923256539,17414721686884849046,16902837433430910732,17266197268824927374],[5393753846590522227,5988347433312672129,12194413076264532622,11168682569100242703],[10462644778503062072,1229702582469057956,1740695829088218508,742897875073805121]]},{"leaf_elements":[9563308067659678294,4471667158078175629,17552029227031677671,4984161093586131758,986733876564796608,11480704959825092155,4466646775310085770,15389565388046900546,7447214393531388470,4365782925339223953,1938372999227680117,10800465740204847810,5537437679781815737,12346278884892089588,10276524396295856384,9495222541437156327],"proof":[[18020515500881839652,1879703345682406658,14703302773946234756,11704632002107730423],[2388806336960096067,13642690798335584684,14806102878001991839,10611348437647975218],[1336447918447300851,13639829802388581436,2757183197927394495,6653850152435733411],[8278339560225251177,13535405539944207190,16905887046506815298,2100839618114683547],[3705038938519847765,15145352121284603279,6486758713065883823,8582727148488567977],[2764927834860645125,2047884152667695667,1921935921002025309,12233840421794849043]]},{"leaf_elements":[9029888334596367933,12627540101409768809,1163935808364218192,610555884297579401,7541938272466216672,4151508835568572637,6182599448792652718,4155538892749029170,1415459652719137439,7754507656608168569,10581055075449936052,13938576973318112780,11582861330497706663,14281623714075166946,6251534935641729675,5899754613174233667],"proof":[[12499249098764867954,1225768354024237263,16405186140799415303,15890008300373316588],[5727749215104468131,13188301279243213170,7973121534544209714,17380763036696378897],[9501018778930372649,13016239042805969467,7696863394450436864,16524656881775366706]]}]},{"witness_query":{"leaf_elements":[8634811076587758202,16579920399610089772,2033243648042209252,17109004241827948838,1822324464992241080,5073353889102923172,1481149823476489840,9177352004588365692,12136394607866448513,8264757335955706101,13879605061548856902,2147902404890625187,18271827269926758266,18173758709089300890,18419245530023841402,3117214015706280559,1273065218469608858,4411759981026363914,558793847975597636,8411913179862014577,11461880509887638532,10052720763538507750,6949729069228628554,1411413844724389852,2076947077749063217,17902049755601395814,10759765700902462603,341535044628778169,15975969455260167464,17550136024901528810,6953363507611525142,11698694831718965842,486250566554765188,18238704875880009060,4387444040799701651,5941236371621423565,13591613737176965844,2066054583672839786,13161297901945759281,9427976576560929206,13550724938933497130,3575163627151383241,1466116126093548170,3189946705802623798,10352000949272765529,14773680371543768318,10529981749875983081,10018360093321231562],"proof":[[4117704827551397661,3702657138583975409,13632946326452886234,7274542748827708239],[6478097132793368774,365265137953295612,17926461739380188897,8533648966606662130],[9459500442197678978,4592929140784610234,5512969260236695559,7641500505083008684],[4682801524623777750,7962768337540905517,17649607160457666481,4741059668302813979],[2273893203622254872,11694988656875846018,116367477818209548,15618404791826619965],[6061872496699357908,13656340014784590919,13996376196361813309,6650101192903283590],[2203925907098105599,4385414000953272325,3991266074564409214,2524070300436135675],[1095325783830089416,8648122626448798590,703625376315433686,11757338006331265281],[12070861453287906345,1168136159794592842,18056684338635820559,4423345128738743832],[7666376573449600700,13365578957942785640,11028795446571879849,13878625267928851482],[16406028288129273188,6914917522091147291,16357057125997877010,6542093058786898899],[16484580533894640830,11501548917705272397,12318025456900697898,10463760609356757503],[4580859414075167419,1226474063426075489,14642193658229886712,1485922935042343961],[482011111768370434,11631962503761198487,157480373765151760,4697234089835100840],[9656625922667479143,2274477342647752862,3793445500724698597,17254639437928754124],[7726451962176198682,3202378625734963905,13400995181991914323,5933506519626544857],[7941939570354632604,8595347632357049226,10052807007763277026,500304887586655202],[2464246202951998093,16320436350803439802,14148714951167053518,1244135353102357331]]},"stage_2_query":{"leaf_elements":[9385666812482366504,2209856218780392180,2432313940493377772,677322050438714480,5574667769064537624,6001069571878973167,13915278207900327234,14099605973064899457,7569161447116293955,12844356214312877386,6332272550380927371,16329723132499126141],"proof":[[15184595222642943413,5293465471830990416,6049365382617656686,3404418602373733994],[9853582568734222682,9567957462899406731,37265307725710217,14450937632293204955],[1081131639240401274,10091576287075597242,1650619982793828761,2770920980956301395],[14619578107914855327,18379314354225365940,11456844206484415096,10047894613623144711],[8795696933393229805,4815619205321984604,14233018238836397605,1531873179223875061],[9576293918027202663,15426295285901662233,1903216119063124958,5200678331779802344],[2742121488163748849,12679501100189093082,7265896115377158450,2445643641056931154],[15710314452699410767,11038697838736571257,5044176799017758431,1866732170834750719],[9776704696670529580,3074204648812428873,5451096492553966325,10278540564165361523],[1404963340546286341,17785232906543108637,5331437364819889069,15309937635378830487],[902812031205950515,8120544583475005085,14444367236119920797,9762004656890201089],[16371334138045525231,9156628612977952232,6976220716410404167,18095012412082874181],[17999810193816241781,8606210428449108525,8725694775294861025,15231427128187266005],[11087914431552093128,1203662535421044653,13871762300395674318,3493199115852903998],[2650834406189454997,9338330484243595813,12424413855245954599,8085962915609708118],[9969033085749422066,5032893016901771784,170146924837136436,5328927770969202993],[575041749007092807,17645118823332348747,8959611526780115788,13052189939926102367],[10069806769161292064,14736479902806298280,15632465526452189061,1062956211714423789]]},"quotient_query":{"leaf_elements":[4276488767508447250,3164239807723378479,5449181530331313478,2416688844330179189,611190360989858695,15086522864892784804,16079357388526807508,10727404249265349767,18026088421387600092,10539399184070940281,18418489953440361809,3501323170367276997,3320507605197559519,863319113034575494,12469136865032106836,5616925482790544245],"proof":[[18003071835930788860,9748797777276524451,14687702930989648649,3122126207637721243],[8140905621503540686,18079980440975358747,663289222654347079,6360690132532069913],[285603377712057446,5115550601358033828,18005453084762703553,14508547375218136692],[17356060429648695324,17396791985756269427,2044585611559547749,11666913074116190899],[186156582908732252,15326531364860405624,9249472674601507479,12556641839754744947],[11798570709356239151,14695819366069504560,7762547419040733937,11446747604149589945],[592029453225349097,5161197811186137514,15538273582711352316,18078957174386651432],[2429279281787840667,15879684852691878654,14715078545028403672,4449279864464963446],[665552813631844426,12606455720354685144,2112398819519658967,10521802527190264265],[16670219025871726107,7108294818362690335,4800325131458742105,18165857117062174649],[2223902954134989541,7781453015328583907,1733524826818209858,4099507808227667526],[13466870103863794410,18077455222819438543,5610306576338063497,8519541049603923128],[6224320213617279874,16253874086948310536,14323234014639449335,7470421725739840648],[11067208588903151312,10871602260111525289,2819929366341065988,12378018255367799652],[848494116397201336,16939179290420074322,16827597660898420209,17921086159625514163],[9220269276920582242,4547464629282360090,6211114886028154084,11763024291382108651],[12307271177441322859,9645066696328535006,234496707641402070,8922426556022768190],[16261937434417653484,2189639994618001401,9649039522118463883,9235773647135624039]]},"setup_query":{"leaf_elements":[2665798556057128085,16660839754086875489,5274853084888208579,16109328884542902296,6940796781010908648,4476659295810394346,11700063421664696483,14467267147344588742,17909364519517495400,12804561955666146096,7427959031662856009,10327048376981983409,8961723021069510122,10474195324806167538,15662674012216574410,9733594071149178242,86116558696926829,5452889696322747422,18410260823126101584,15242625603985387320,12205214629357832237,14358966954122577735,17214905079924947144,17868647979749407131,11010814607181855186,16373047402100387895,6216511093064047777,2283506317295384610,14335058710959698380,14796558183392679062,13761426290939363369,7961710401625385252,13833461891517278751,1630702839693598190,9529617390453359040,7103515770875263802,11105735311738065527,10126196807625870431,811594299332261469,9096890324262340119,7742410184624792571,2377278210616465748,6866821793103200767,7774121739147086823,15225428140063870208,13457944929702637554,16617594072073418956,13758554481520992123,2486432923830802493,11206072011208295364,4261265777154611208,17166308408195034860,14710531667055116705,14823275273523671137,7892792012845174928,2829796595829572478],"proof":[[15853027061812789036,10629929705101796559,9318523979563308473,11115627315600177644],[3671386009891773474,10772551275348307333,11062744705045921557,5811435056660361373],[9736095544550471485,2013215978991898611,4604359300088312008,11080298052376901646],[2988373857581775152,4079418132266376558,2533069632298673395,17388707132919582013],[11428365823334431457,6756566234867587530,9910611717017688740,5010460130577405042],[6980239215106605605,11094659770945920513,9646653122554605013,2589162174630230331],[2826814786620639051,9705877453628786582,1883828513022487534,16607373879937894679],[130278572935658626,16002866180290670831,1829289824925940797,5899735228754637588],[4696902218008583816,17789283462120579814,14688031168692684622,2087864586385307086],[13075088453390450543,13120288583903644234,3939239065468640529,10660980810750449226],[8027058453537229006,7167461212288970567,5310953794042252983,4967034347722501154],[10174974686899861854,11702076024126524248,14878812074624470133,67349144960880095],[6513191736258912530,17917360650761218827,6124461713246501911,7700473032188574775],[12090183795902535963,18415248260092853089,9850894777126684109,14157739529658966789],[5876045124532621678,14156214436779380900,8256563053012264277,14875579613471291118],[1440888199944162296,8393161381874518359,13320793373946143608,16140650426331363273],[18330938892052230028,5098075365864232469,11334515158336507652,8134234352970698403],[5957761909735300335,10117592133814483596,18179494026309114299,12388280816421006330]]},"fri_queries":[{"leaf_elements":[13006828921540548303,14901578929480959321,13844071493862460952,5072437700091040584,2613156477201170613,10265413262775792153,15674231102043513330,1358000446654012936,11189951252295436428,11345165286258233344,17383529654230158319,2184526564571642682,1038099921529978594,9137203645600444975,15825227974443684947,6870701330190134860],"proof":[[17004028580111348440,1598080134744620373,13565049676351344994,14517974316992030166],[16370478270468625014,1770824194493090495,16494781416738547554,10084962357445925026],[9288462925134016048,10843885987756233766,2567858106202777738,7928745928209503407],[2313979355611291253,13165398522693338448,5863542211091891852,11479953474461477475],[12561685824330856597,6752680114486996343,13222930122004126589,13162803346519058918],[17486552292648451369,2031777331003575660,4275467475386331747,18285015824080313581],[4893529479190203383,12635566792220584883,1208750013216735138,18396027523691787668],[13695812876577963260,11144513405471395326,3939317232981794083,14801352821599359551],[6921702495794826556,6406215235445699442,17650737530563875289,5501743519168916982],[8562394836114734418,10025568148048378570,17333097012250121305,13437246514591319305],[16677844764624991609,41931773778144268,146240483996075578,8800948971483348545],[12161402670926969453,15619018195285204732,344404148797604613,10328560962482464696],[3473205204776573811,17819927364282633916,14758159048423373254,975922367820594075],[12161698822702584363,13914412849192247895,10054967588638925465,14138315973513190322],[7617375712889098230,6681806153672525183,15337880034269639559,11076075858490711344]]},{"leaf_elements":[18413865033556445094,12619394680183511963,13740805757261564388,15583221428290616435,6960369398872899307,18060584944483188240,4258722534529479275,4688497401542949720,1772156966492742431,17962600125563278494,5822006317759586047,6571856638661973445,15494436200139567537,5068698471019486551,4902338556057023395,12227318426352948729],"proof":[[12742473001203026327,16379120576773347474,6267672905364497286,9317819892706797468],[13928671564236518472,8792703937175847781,12467622316616043980,15498376309514910745],[13651309204497753536,361215213758231930,9151701998359027920,16667432155542121035],[2774814693746123948,9871821710983195870,5975094508009062578,360211034420175490],[16065367154896594427,14680327237176426238,8837472548575562994,12672750217378316028],[7549631596147558552,1047145638236471284,10453299067826263022,5323997096978381736],[16715109660307805371,13874160934437378469,11581121194511340640,12557413770906354978],[4698086274917940569,17665707991078296017,2413469803136873775,857565109921909431],[17982774795668115769,17805094284999907703,10726450622059979487,7638269068399837148],[10091420813782134228,5699820668188035043,11120913653385740074,2175716069148502847],[785250791689672801,1923617514503043105,16837044779616236794,1296741735062422618],[8323736684747684161,2890660765227512365,2331317271400761512,14263778183598358107]]},{"leaf_elements":[12016143496530478028,18387808696342158267,17680402603948064029,14191415176673178193,3883035847885242793,6422585915185826063,5642907411924840506,13923032454843371440,15395180675042388663,14103590709062152842,15198543672353963397,14951313843378050918,17207316153212651430,4658808439266961863,12660122373211868274,10120027250759505912],"proof":[[16102195818366448553,8968078628925433955,2925886235466819337,11731447951661507370],[1469583221424417278,132289335120922120,6507940990386474461,4507802308640586253],[9512771782191510896,11961740457462442996,3222955628957994963,15550773134863224323],[5509086382696770106,18348018423979683116,11347177751330144615,6969874891960333161],[1584084411467231031,15284508064811800881,11454720643171455283,8921194171582905948],[11153739899694455144,14017631583544390111,1493875667236116722,17999589219179518518],[81977464372105745,14048918827963494567,3111436925902137370,3718177572129767542],[10175889001556598622,5287064584413401674,16476887491666342858,13070017445035861873],[11149187746470938670,4552198826769374390,15215208557384414793,3733134391926221001]]},{"leaf_elements":[9896248299866239474,7478069327973880081,10454657275763849778,5033419030222118869,7695953364353537117,8856668633158791798,1040177522792346871,17130203797263435559,1935970924365135867,6606083907380274509,18358500626112605054,10082057636364639130,13698561374185246885,17409697646332040092,15068969558649360518,2028705288758001813],"proof":[[678022393803952510,12162321542836709486,5109997139846687357,3448734213064064937],[14639054407907788498,17050432909733414926,17563638527234030123,6069967389252101401],[12350660240421821100,18138782875536249306,1112531147877833928,2974976260479271985],[248187204983777672,12036383706445364726,4959232231656575435,10828947616053822921],[8347471604095435719,8709250509565258698,13792462017887936041,5943450673904347216],[9644981150280406257,5943509916532883154,11413269015121257702,1850055931756944761]]},{"leaf_elements":[11551412811622229578,14923726126698943571,6921697307002565677,12845457267838765321,14334573343032131825,15144420329391769527,3430720203336628604,3204986328150540071,14835942135310005521,589085240000005014,1166784536381735625,768651649236983034,6998156712118741107,5017050429141589897,8084888887258422036,15798070292622125236],"proof":[[15634361151346486313,10839094876148034836,13661517486429054428,2123765142389542762],[9437066826358676930,8845751016304032040,2868166381643469215,15670132594446257610],[15810428595864435087,7443171673770482495,6932558748299491238,13070342389058397423]]}]},{"witness_query":{"leaf_elements":[4536556804308356070,12716151759791540963,5471020449778711365,17370626006274304586,9130247496824576114,5833649878279660254,12505048890494954761,324513838842816951,14229047081214851723,636333088414142994,16053633096824318793,4362801565389579721,3204818870816501568,11748359667315851337,10162422463354625382,16374330832643332846,4127665663899863232,8534431846074794768,15558388849807072637,17021897538707964153,15938171047947282893,11526990834572158599,2763291877708946276,6232211068400065767,3919673098842900867,5243871665325371328,18177406969326807733,4879264474141776927,8790642799626023219,17707517573193177748,11161363778441317706,13305840777359535902,153120424276205687,18208061620652804954,9665795896025914309,4964725396376867704,13422815716312442413,8898385632699538884,9759156367284444143,4721008312838312700,1641192921503946287,8436332440123486226,2638800840220808090,3067246289202556284,18186510539348174016,2639719323239051721,8840774480309853660,5931343063968483688],"proof":[[10035493964550873318,12580777285114962440,6188051341986095227,3431437102724435149],[1222580972706049373,6190161779145770942,5219717540424847005,17600061151445273190],[17148066884250056565,892572719894771997,13827836121599999139,17748332543734898888],[1886652262877859136,598234347614333091,12877437370083587722,12582675490324984326],[989695467921303751,5941084456925578244,5524613756992050858,2447613701049779362],[783647908319858907,17869716291324997320,3128358478844224495,17048926517745394819],[1337182109643637740,17459399199056841805,5605880602706864924,9836833691920614059],[6793995375396338716,13424088595643474829,3463801334471404354,13683757196937252872],[6603921030326503755,18393307097857815759,1987310577196060933,14222736726410922008],[5957921756598941036,1483251843612476507,5793572169817894396,12137318458632275351],[17582354033990895378,18174509237950688064,13883979936119326594,3379821451981726051],[14259318171288303143,7290689618387801851,15642597109304940162,13112249811150503755],[12529738434021538335,4049968435538850656,226104252338606841,14579258711727876724],[3773622353438375540,14620370010018151693,3546369131143353677,14234429243349545168],[17599549564820350855,10116674463111742362,4437651493614250188,15273810512304513115],[11907522569610805623,6807682670822717277,6880348422578219884,12990826054671242010],[15006950160523244503,3468573632011119560,14921069072437130580,16384948877369948440],[5897749806982583834,10314725414396866485,11865202969079395036,14905390954674704188]]},"stage_2_query":{"leaf_elements":[2354347144104989434,8126063963959338131,15076123637981928599,7009844137105560393,14708613058014497420,4669649010265677780,13710188726397550457,11325285443703490706,1409662930933868829,1347952282504916245,10261393343603009217,10882665203215015154],"proof":[[3277294408957734115,17081477068817754727,8628570156013644774,16457642110336290096],[12746869510046769856,16787485655015473181,7797991391448684988,12349881812163970460],[11961512745631509289,12515148224738130383,15162907510915508638,7154674109693383934],[2864708296486777013,6190167800097509270,926787310088745893,4432317795148366734],[3166432554598539464,3557861408298487310,1808228866814758041,12133190246366374113],[9946791102287877593,3033884906800420256,5011923904660848034,18092288386637543769],[13357238224506754483,17316337095564651667,15403105872276338312,7754301788253241567],[16923002560907709778,5910703277690382420,933614282857304554,12590074387560126159],[7153242406919572362,17436710375955101671,7172243394100345000,17441857913134940830],[12206798433473037648,13524608009123611879,6252646328291814864,9334914517681280323],[5392125248221661394,17198857252851003832,14421111840021161773,930904520796470050],[13578367453157761673,15560771102659514189,1399014178049243225,14535808044078310887],[12231112819993379239,697575009222700797,1020086864473304108,855898704166998390],[11312628122940352070,3436828919101764515,6559096999573769532,11622715327684969732],[18048571085558599808,13332753610819984634,16825104661841129530,1185553772283830345],[3552355702508617549,8322431354314789284,11953534591114868281,16727338939363775367],[15688001309547901694,2024213108748267462,13268224971873873114,1905669622551170100],[12985131911950059187,1155338876188420060,4608887800025487820,15166839703034738585]]},"quotient_query":{"leaf_elements":[5118334886961271365,14426091436317454712,4239117472488315635,8425052471161042500,7997863586762262666,3761618089627345171,16112310346844887172,9223548403048125188,6845473044486090423,8124512563942957972,3489287293771871607,2780965768373143442,18269211399156328689,4755187133519059324,13996064803793168516,2224213200166158165],"proof":[[12556133865853781489,3196746965210239576,12273142680757678063,18352555054689089657],[12247722947621240451,17216397972569968683,575573525304495693,14207125542574292389],[17121329060563548374,228689458951996301,8768291034820935402,12921477252189151042],[1675325921867503208,4855595988845921873,1050781107961232336,5642354746634793802],[6418456828802635194,10421365139969455538,10595448436897656825,5968997026404455329],[5470585157396641756,1777146489431948548,11656739063388175413,13940626418915926797],[12267890494219865364,9415846313365377520,13816155916939264154,11018291629479152067],[5904059731653683476,17614669256578917697,11977682651836030674,3415916947893728575],[8980654351902417475,23481197064839844,9964064166159130099,13994592996688732457],[15252373956901226663,76032215086032822,10976019329194842815,12340569889769578306],[10088532271328158033,1389546515235310437,5923502557520540652,1541046534585213826],[14124912544608707026,2233255539667790628,448580471770184905,5452696719291788977],[5095250415046234433,18076856144273113731,5254270864960475997,15296372600796240519],[406520538314844792,5431123609675134545,12557459192926161628,11490164185465843258],[7701174372323504152,2843334454885597785,3616857908368492008,4366470094996683328],[14659513499784332575,12956754071847531480,13703652225087639969,12408242326070073059],[2891585186713014053,9071327090743784557,11179029845883176084,2766364400893613198],[17325450815500747411,11590909759454885162,4097507074981283210,14533654691466118864]]},"setup_query":{"leaf_elements":[11878307375879401887,9176864417896560545,1410345274509053497,15871683115339182197,10328405364096474136,8150139308056392044,11256661479367791984,6047668888864644348,7100130636449637106,17355303483263853813,18445630337973675895,11287157931993149844,7062326726912148731,7858917091492506049,1318396797838559713,4793248356418403693,18394615338806623122,4881692480582331748,11429584234136663171,7967764499978955752,13095747395062569014,2321985638684651603,13531572651572359306,6882495653233726519,11831280691129187053,4197974801941508716,6201811566301335247,6745840192969859217,17480601779587636157,3998874749866652299,2682332777344585672,16080573249021193687,9405567876928474283,9112048287191416502,16045194585062925937,15343149059258534899,12266009864472247101,8806759688021395868,8072132901626281817,4416670350483476228,712217527387881133,6535904160755167320,16458205751115224426,17577468835095116667,9271323892425571052,14402399584607770944,10077603735768880274,14258363937454735751,13999819851237207838,5912879201657315122,12349213819119290168,9967438187611936792,8579173064144413348,4890234265719901755,1169103157422455011,7759135875859334302],"proof":[[10718702392711681282,13296364248300632126,2593934747371460361,15398915046310052651],[18352670093660031154,16636756036998104445,6804625581088495224,15242321001521511289],[7054848824635862469,2727068643241188424,928725683215804569,14390334685567996553],[13703828679058514991,17930855439589635060,3233698262456861523,9600820374165512300],[18391632411808824399,17055002356207422548,6104173773862175987,2531292635055566677],[4666685544934297198,15182996603559386989,12421664275731463572,17442233908496134034],[17851717334761727179,17299461784400238671,7582396489125911995,4360909558543750161],[112440243279436927,6541693002866806503,15910029563044909718,17988995903354941609],[7681136168621906490,8305456111777091519,2099648499955364031,11534852657331166447],[11999829633854429295,16575210052092376512,7529530515352070799,16401275149353970950],[304300487317614806,13680094672261781925,1510586334517864561,14984482162902704826],[15632396894636494036,4693064094562862286,12005784425642471159,6442314750360271198],[727393792913001387,10012343486906850187,9416850693018188823,6243560037728951873],[10227102631356759482,7573604735380959401,15269780426631883131,17557082062516151677],[14336216480306266902,8100994091302540993,7498311695801211541,10560283267231093182],[10398607200511925058,374030194764602857,5217664171869066685,2214317754326895021],[2586713763788356659,9372196107419184825,1152399742240310659,15858773836768559459],[18254166451247968339,1794453949493242585,8497062858369271935,6057385485853944539]]},"fri_queries":[{"leaf_elements":[11119175292815392790,16165516779631339814,10207971714142485660,2330787777564604922,542936828960971510,12021210577344956934,707507076822666699,9031904155830926336,17370050448968642006,1042867329240291045,3484217328026967216,18165007412352876756,11119520321053106347,5105699387368974164,11717208716574543442,8470855288373661334],"proof":[[4383692568009668520,7223186801938535809,16987936855428012028,3854385031567675299],[2398585311595738594,6740933261082802500,17686341856597542828,2339073107595460237],[944466390176188813,5034115882281782045,2722134328766809166,7357233924765935403],[4530103312321634974,12401068428474431021,18070618731983416416,272856889171734719],[9284196888681394049,13542950038867876182,10475612795683240270,11595049577832557900],[4599222523817771688,15932427402348324732,5361960677601601907,10626921026248207069],[7278641664578034305,16693833814208725657,13423127908499821153,2909482502081678128],[17487030198679255186,5633477060513742742,4280990840332995147,10430016977365427638],[2556068944534076309,11308253684415134749,7246493994196798418,16341437705918504],[150642699054389564,18420916364060675210,11652286970607486168,155843944515809551],[8262817666486758189,11358981598530955465,16223900672292870016,2433445772089244274],[17830070773589929029,11140127425129922259,8705076486541420174,2221317339395529799],[3485125362116049663,4608955143279395451,12837086727200912608,14218766541179555801],[13179010933799875061,12022696389848061207,14073063073134900881,4478968908571616369],[12227158577389289076,10185882799953290325,10261748284489240579,15999983291387042473]]},{"leaf_elements":[3456494995172371894,3618551273191804593,12640798863670091755,1292323403329719474,16622630433430091536,5063975278153714161,11114133501874307100,15661746096287373832,2559616360251504903,6811956405347130121,11422266802673473001,4035789731798386285,3746654370369354641,4931489236834417588,13071822220974526220,9084672373378668312],"proof":[[10051435935607852339,14056027495730445397,4232556243565616445,5385567934021573512],[5731782701525002172,1106183765683259007,2415258513821122801,2792496575146337412],[5347240804561055159,3643462086117145285,14925679737348600796,14720681786949083699],[15847492297850408155,9166363878892512920,10316311254090206872,10672647884428603601],[7384815595177036074,16991864813730455740,6975778745333242406,8267702737890989608],[5280754610513826936,11173617368144464763,2651781290611368159,17250144775792075852],[10972517597619665527,15060764640981933945,15124299497054233547,9890428876677798630],[4922836529057450959,13908784704287504502,11197182325937168302,11423192374451559616],[6824995249612999896,11413715888026016617,8041584254422097552,12871528405789699083],[3909808077080990281,8825140913284879230,13249766563777123128,3989027770125819192],[17320329432499064354,6719711302240804983,18041930035609556244,5621535108761543831],[5377646647394322361,11916139752071888634,16149040000597833861,14851557207287325779]]},{"leaf_elements":[14438761971375102860,289547733664198002,14498388006326170771,13891775909916688495,15176868607826830272,6383782336189121973,6558436426965095204,2024513086791362437,4236428438836021392,7219107496684529073,9467301874036218440,5322542972324048459,17359876858377489012,17184289561223051870,8418353212572571016,8818128331577344016],"proof":[[16623668065589095929,14932413467335094133,3796322589857691364,16025676825007262047],[13777097905206884065,16935948391509709067,4582311350383631900,11146927247652332203],[14336531133698120713,3560879525133542963,8195601362334588546,10026462863037690209],[4662421421037137261,9546230771965092544,10227826032475275718,6540690282727185748],[15712657008336282415,16338516989149812903,945265021735520365,3285898007475491593],[1840853643620076939,5517960019011079582,10359210288237969199,5667716102474620078],[2054051717372766325,6562699198470454827,13884787152138107524,1118608883148558653],[3886736687132322980,17911262845753981544,16842223507874744089,3892558238967106365],[14656599488744274310,4168127601807206993,9713079140872538548,9945035105577394485]]},{"leaf_elements":[15544214740068071540,9672954342860968943,10551512999592523443,12761485675686877127,17766337869066062625,12273264302308520666,8662018945205617368,1307263405175493720,9033115156726771865,3150612785397019770,4552716129212413071,17056374068122008042,1342657702428354145,17109518342082949238,1462521434556499744,7479355165563631819],"proof":[[14264830192778773434,10570218495155136519,17952483152661623791,15822711726939295952],[9306681503120951184,7859542694654553784,14856992702739001643,6761197198705384289],[2536956674977922976,671326230842906907,873310413372353492,816054020778507722],[6247260403554673652,8020451127003585815,15191541124731099747,14568457644454539268],[15840809011595513887,829958488519205859,17890011505727121197,13048838062950973839],[13311162244657824692,13669787908611767580,17816716218121587445,2828452054126729030]]},{"leaf_elements":[12052506752311115422,5886553573807480236,8927240706599485824,5721370672517263231,6010717409681420203,9214173540955357827,1355534262974618804,14742152728812248306,9825449166844587747,4516951348342405733,10376525418273854211,17733738515348307936,5595438839542283227,14767840525220795587,5631168133937536758,3258262003974420592],"proof":[[285337353343873249,18382069765401610801,5785973162420716692,12730098775060211819],[7746077278772750341,4354522642623714010,5457122309694725330,15067297235787723752],[11377161089913425078,18385047155652701767,4382218256228304509,10217687015705109713]]}]},{"witness_query":{"leaf_elements":[13926935563564483797,5373935012735871240,3900620216051081589,743607841855796740,1860280884883447849,3692411005290483126,15659187548893374949,6942923863830223342,11229191649105084697,15673986187450206310,14642126515629358619,15750800942617067861,13650286919952135063,11755591194403687959,2348673869497223069,14590623061949372862,1578868250686401628,13724953603817494129,14736681813651785031,11003287020992309966,9896450373431880315,13242045466762168219,4701382154131988553,7543208681858067104,3455724941417141779,18028677017565795472,4260311083684181593,14140918677144402713,6788407911483425284,15421515315425729928,8703524869574660585,3860652997918542556,5764004023588467930,17535411507726244436,16837897649920798321,13333001094999158993,3069191217837967237,16605403868302522258,6375399865029267537,1214166319479714361,175597267906293017,4282097456185447210,4077307835724469573,16729927449167327821,5803272136322527402,13005410779973764542,137621414381797933,9389092413736309026],"proof":[[10683850457966308972,11846424243530468541,5848125412670125846,10238181862887796188],[3655480617903551598,16656310068864181135,4512186542388326702,17450918906308856904],[5541246110476886122,5806134080048377549,17929148007251305309,662416198830845945],[5962129634527697007,13443430871638607356,11150185335497749696,13096352164137049454],[16763324358770256924,16194007945492550665,3908269794304401199,14314587886455555088],[11292132297374797880,11890454561744922771,6026108153495724346,12061427930438932026],[5797212564554251239,923471049691891215,3209668349858014862,1238516298091889729],[16858761241091716348,9934439369097750842,6710102634338967897,2742594674477306133],[16260461156821125437,7364025651546011478,9832149353411211838,3451641003990832150],[8872413557241920942,9461971531558947582,1838353886307989359,1549072992571812353],[13539521158153957724,17289892434035545116,332446794139735869,2995273229619847156],[16020512992279260631,14835516694555289930,15855784192242202474,7322141116934237544],[892933321324312017,6118300545284684422,14593340877851474330,2600379683127848697],[12198861131137522956,2104899060848719245,7084034672194738751,14970878261830078939],[15421045355702280205,18231928722329686929,6368006640833307308,13218083366154352394],[18271229098266134351,3587942088431921881,13075567405197797835,12946421799556755495],[9067476618292642109,10799100144426915385,14565664021346233992,14333920318903798955],[1646524666495475491,8020138051508343041,8974648728133537666,3688542325656783176]]},"stage_2_query":{"leaf_elements":[1671493630699943754,7681645731067074347,13071548786598536291,1523298416232796801,2506640940722846976,7778374962803940238,3815411810165529291,10817198789310373385,13755005527745221288,9644080932242792268,6582207614143876135,8575402875935463082],"proof":[[17645808201306809808,12695756348454797167,17704511102167715505,932833359227398308],[5879403119358108644,18252721826635191660,11266210935037692588,12131053678566370841],[9919014979627603545,3405140009808064375,4804192417990614574,6705497514260458425],[5567074614471718403,12640190914896388891,11036144886125169538,2713473770058133651],[986549461586684978,14940476167026117366,16213435940955101597,5689271644649218739],[9880678517691620578,8157181597554141077,3857300831419333932,17512312966413606632],[14195883713721263418,10948805394700521323,12975617376815660392,9694505832335725102],[4593498784964542492,14296732353435977247,2713151535599190643,13011811937393827198],[7832941413619195593,8212566010248516747,3009809607618194431,17658345589612860382],[5315448053997260104,13141071692159823084,18306924955891423103,6600365648762191103],[16474736165034051173,16574308567165940083,10692450112241346347,14850303054719850330],[13200082587793177448,8969906865006689677,16143074288868983361,16187660783182230992],[17813207101440661525,3525390344419648359,5811349961303641895,18394536031327358066],[13550437117365677252,13250003578153874546,18042661546247276117,15635181481409907208],[9019141011517183326,17662513259156566379,4926409131395286982,1336294024725276591],[7819142368343342379,10386728685339378957,17890624587244039817,7933421307525449388],[2415861464659884336,2696156689116147392,18323798015193053226,4768176898685709653],[12023342856576794422,14535113737892747747,9729872312180588442,3139791498641226112]]},"quotient_query":{"leaf_elements":[2726206298548982537,3691253299020702687,3391809165765396235,5891113910752430617,3372748346087355884,12935933745373991551,12865189340743060186,4807170460616223292,4817281674988262429,3942478172565912707,6060034317839891596,7364930981836562527,14825824785112212137,3544018245619863304,9871440953620499638,7000975937576297833],"proof":[[13135386442697041778,957688805810527874,702219215424633301,461236214048538466],[5521596148949579954,7281783705610197565,6067785102965467395,10251687480784443470],[16071322543793001571,3193189509534636757,149446451725705423,15471976441785288635],[17874272638478567617,17317887338740656011,7124756267122784876,12695324070712153914],[6797300457208402912,12642592473774784972,17070709004515489599,4759396679373654922],[14326193618411584568,2736507622760064202,6381606421902448523,6375678469303191114],[3059336716725132714,4737556629290171551,14757127109201459475,7744639932217192625],[5962471760882484733,12128940596797722839,7443023834508919731,10742684142371421298],[15158599917330877380,4875687884651637676,3377661441382096775,16569978267529996633],[13819381326716099241,16732836985428812183,4848029973541594405,2002808896030135527],[10675149620280946150,12702700532831707384,9593077558940648563,4284667580502351058],[9430933168325331092,2623445094441626672,16593132712293940350,1877532038944269415],[9097350015372866530,11922438636308085829,17720499981883606059,15814918648894672101],[10998314789114333711,11440044775901880346,1525119665381098215,14005903330231764314],[14712869026285022996,9314659006728818186,2209356459689812365,356724681195792062],[6357169738217502560,4715159276189700199,14501937582970196504,9046898551744072014],[6339182857617580453,8075011638497901887,4896442419066825598,632143169067830673],[17109958286714466245,13722791211622227996,13373102504707803699,13285752994313092092]]},"setup_query":{"leaf_elements":[10689170704766938693,4094531548201563990,13824593099089028645,5056191222095092073,14553914045540869599,13468875424464520248,12979937117917569862,18328433360647907271,5196689494224762023,3108871869924627961,7951640132814753566,12798218685708303302,16504997595992255573,12188591970232163236,13854289670427402755,8503642908705373351,15746022850199671616,6273521786563074444,5694326521439737378,7444491323368835629,6493184580271726321,15134377335848935207,16805799324756901911,855096835641588833,4072520224976360471,11349464813453645087,478850525602226016,7985031168569760,3505264747549198024,11784341227139533083,17319829241779756734,176869009962611031,7044644089836936322,6507828710804520467,8150335567131037403,16885363274764379810,14079369376755393491,16395632692654830159,15986785933304308939,5074253368354551764,15402421901216697885,1207481210436766822,14552854602762280344,12723886332708429118,3423016980639524649,892093179933520359,9637576742242962447,4604106393992747660,9923571645536477656,271298469970778683,5294510866229741862,17722566311185984679,7924009781990728387,5173871921192037964,8024834220266061263,15426462526354502125],"proof":[[4812710523739131800,13374353284972184894,12676378302481496129,278048402939403953],[16203787859440183107,10036113137560286482,17740286279321448898,1367314929764374162],[10260361786658948942,8425437087124662416,16020478933869253629,8553327875556559719],[13863016700343192579,5109631543750291643,8145000311865301716,16360893693388832949],[9438757950667564265,16547054832281733251,2676455116633902619,8423409484949631695],[5676195282711199786,11233258467931088470,2503853973202033267,6250324449140729018],[1566098070749193277,8145532959556812749,6202276279763228464,13544918847991346655],[13795489053091907535,2864490482325445156,13741782139230656921,10303609643864522281],[17980114363839652855,8792762050945455070,4198880701617542477,7823891977233309059],[9459397076662391433,10547491097603004397,9035757897418181843,9215884494292535692],[4164823712779858484,8136110243378180991,270466576449955454,11729512156527432071],[16667103176876723261,9700446990003979615,12734041971473562357,8338747978050552770],[18191709471490317936,17151561249409890510,9140482251707911672,13062285184425764599],[11309999088492131804,14378631160452733141,14847029961933376920,1664671147094754654],[17985888716444292662,3532372883684233485,10138266979639246342,12832969844968135281],[18205638425359614078,11774002470399747454,2766728874837671207,2630278501548173055],[16238243922776738324,10665337892383987745,17524827861748349041,16857516070664027038],[12692357727194591615,5353613950870032841,10203792086904415464,5139528623909913120]]},"fri_queries":[{"leaf_elements":[1843749629189777051,921657257690704880,2090055057608569120,1575858072531798866,10248829196560011129,7105941807870201586,18261539916029199257,4996996925412382681,16529559222156413912,8586345742444368596,4675158574597213687,13881329997193363175,981959562565147831,733708948996881246,81676789082369983,13530200201674014398],"proof":[[11259143818136373433,8582048964346058016,18032485106663846024,2618048930412512642],[10365952588949124918,7684173176236202295,14656694582541157938,11546314212992771630],[18370023341366215791,3995109575705793976,2341190511579764176,14460622358685683689],[17790433931531799803,8111882454166201337,7588535631466291773,17099899278209072353],[4320110980025533361,17888907938299607775,3536615965305931549,2484507938172175492],[3876581630786836395,1845882204098599156,13880302918761788362,4954138266553874477],[3267609188807997523,16045454014995108844,7065844415646828168,15810313695439668602],[12701888439747679366,3009021691836637000,11495046460749933417,13823025962518737408],[14831312471761325517,4697687137000154786,9369507846217851677,487944602814540430],[18330620008457108057,15628777486087393699,18337158108636611552,5946963764096750479],[6969255789156527460,10921543193753479891,5327706829712641763,4434383365434762456],[2899777652203978259,921222798519668558,4610693737532963886,7533771047976523477],[753961183247378306,13476604892676930625,14544927519386100895,5646593050853059163],[12414823606277499623,17255019343950278548,8789593622353882671,8587321136759744243],[14343240783094236371,12966841993630724059,7878063284316940778,11250424963267954580]]},{"leaf_elements":[8725239555705074577,9568616962733295261,7120446966936862231,10293665287199714234,2230813042928039896,3154201151842012493,10302377141540826952,17356545955731616958,15472278732237543131,6031284329799204676,11884895349858722415,18296282167234542562,1421280671944473864,17175830711091596400,15676596544905052931,2362299724978283267],"proof":[[12850584520597151677,1084165021395505087,3279348954919750357,2714393551040673730],[4859438247756743343,16616862773031928944,6359415475815591051,14112437292510032552],[2939929171960158116,14307136999974385544,6642428028056213237,8757378872064255090],[15359092048238206659,5755463029126304155,16235706746450710212,9163570498413769195],[3404192721481733102,50642835024786607,7845363374613611103,17375833101187673195],[8876908724363786702,2968092539460207572,11212382375765839254,533663710714085529],[2103319480391544899,8912699619065778262,10655155916362002055,4900342133496960301],[3342084417717556877,2343370139488382495,4793735235995516803,12618992205538365788],[17484008200728027957,5344682035228440621,14273393122608756688,6299664607015732939],[17039448733689967954,16105715573634482867,5328781584888293765,16710901380957039589],[4343760591618657892,16517048950817318432,9631575068191334318,1986151440285805677],[14721744498311932396,18241106321802497691,6507673460924745042,12695200323700323583]]},{"leaf_elements":[5665074757746542475,5164653523286826823,16552569760607059129,5052462645191897577,7634021715524626242,17712605981656461,9383796400989844419,15494032856379893016,16661685048725598692,11050918869650308785,4770996642997222610,16473457607332446575,13211898577008082798,10884923058301844412,15652886414601279691,12640949024598374009],"proof":[[18159367606295668885,4340313230942220117,6840083975468371475,11894971471726945212],[8324763158363005921,7445761997448772068,7389063527177372959,10633954614541271385],[11714527905270422936,4745355278985339897,10762395057918054900,11765627359375505084],[11338495838300945346,11250994536215679073,6757873056226475709,11688844438922212614],[9285939886486037378,10696710795643547460,319332811607602940,18006805257365631789],[7093522443731453859,14808130939953071800,3751679826383942328,4515843654284334315],[15918409470712377935,4879071753039470167,7221840382487486807,11505785225614801526],[2943969783934469265,16449556031425281515,2558325876318778218,6120781669164424265],[15126464091894446204,15479533560193337969,16105035973856763647,3832276416687814665]]},{"leaf_elements":[10653799846789774244,1099671754096451545,16667626017493528876,6258994128058158663,703299090066447573,3372127236319201323,13284028809467992157,15496733178049671363,7364495844866965130,9423530397602051108,3848114103117982543,7703348963067631579,8414872741909416139,4315347654990191269,16841465818907261647,5410756244563538305],"proof":[[16001375848851026991,18047962140053260487,10324245352570996610,535800450555941441],[6891136896613145449,6912288168225327402,8529126194825595558,3601446012277757411],[14856688254666552540,8007866583712281982,8870659888200846989,6697639051820858727],[8693276295147590921,12832367135324966245,10033626437073106635,408457070450255060],[3117410560214978198,16583078714360472116,171942990284829018,11117731662601454608],[2819436595351019720,6715909117824973728,12833004638196695358,1978913384888663959]]},{"leaf_elements":[1308282812850292892,15697661098077856624,7336571784070649321,3592351631739482615,5458782069837724787,11222732979586155994,2547003692195138826,16746863579301688794,3009677181381394159,16114199703591483886,4858718560737125661,8847631647995533349,9830731104831137440,17210258221407373055,4884714541805979909,6949442989734164332],"proof":[[14423063941754173839,16236655549644720840,2680632801458780641,6447921739338479599],[7940829192716321344,13379178410605547085,2202550851534697978,6856217643319365135],[13063893268370887402,4907308492440454872,3444494088425747489,14450247675947101483]]}]},{"witness_query":{"leaf_elements":[17345268644705997932,16930110324127956240,17513759745728186316,11274159868076168148,13497496016918284776,14552936435241274038,4527921444056773578,5836621224774062229,12137139215341181879,2139247601176310295,6947547337952675500,6335832284736284472,6929255463561976465,8300087818711908182,14630174904023930642,16015941361095644440,5595315550159011158,6486311346512028617,9941194499617700036,7409275717239692986,7504523941095713881,8052284142826800815,4436263235874949111,774042669934017153,4681881056644604830,3620923961127847657,20319117917906231,6238622074581893557,17396635326247015822,15538722969173882043,4805246236954961474,17745554659236883060,1280985748819889404,11716668487929957782,1828572647904573956,7762384545215064099,668218666453274716,4814680558122638003,6933852391947798057,5737822481798887590,16461841348106548381,16516220649252792815,8132580035561231953,13470061274208221523,4273715270756499926,4651612849575781088,11666330984063967463,3544823578472299720],"proof":[[12515632331086718986,14382816232258658353,2425629870394352095,11619121170293056111],[17234444745123143653,14379373322626692774,2764782474164104442,14814314673877997550],[6137704150147160321,5869275050268146768,1089215869822912047,12863414104093970124],[13721305648780478946,10206772657843737696,12150009360677902405,1885171319673991232],[1301772727558108687,4001737174155453871,8126264697369666938,12831714003422458804],[2698169444538621788,16911417557594760243,17070005205966323061,16348774775706632219],[18070820629334909251,14309425862004855336,10269928603642233638,9634626101435106389],[17361641480854887740,14038083424142866892,11613021885041464124,2075169014559952243],[8275016949581193696,10601681226418760413,15063264323012812240,5009718270360435887],[891465648812506237,12253767026719457129,585166336203021284,10910471744501155765],[14047191674735858469,4310735788208276626,15862647313927914405,1010619250856554600],[7354251631831698487,11989827277918501087,13073237340455218240,14846353103701287917],[5537713410006879616,10458629998848688781,137827085563086039,3238242747500581408],[6139000931238754627,5886788328456085923,9053540229256411301,2260002265238199169],[10464297481142830919,2164290413275056788,10630249194612948041,2927130012214911923],[5917298219307954374,11472610110005508887,8410013834934329717,6834166139332431897],[2217381685426059630,5306315413282638935,4516987451382010930,15460027922526446118],[13509581940766983146,16469061479523163396,8494254033872891688,7410481698960870223]]},"stage_2_query":{"leaf_elements":[17109906616549071640,3933674444895155119,547111448845273676,4359801041852166203,7715674712267762770,16930578306268993574,6073600692619863223,17369273429795179571,9508502951708277590,17449970407685139016,7411735741948109865,9635208781326720917],"proof":[[14711015214864328445,14335800646607588838,6140443185183065344,6013292047980579241],[17688980888559441325,1605718863994007759,15636075955792886154,13918945160404843209],[16770361124634486836,12539435660064157986,17294379878323351218,3786428509765085588],[9558441519132947021,8003291844854399318,460179322145717005,4596315033070790384],[14512679432245238557,5802322056544445897,8826809677804054165,10551656989935973978],[11498040980150921083,8534302873653161645,9940576443794487997,1832869193514302330],[2324172394623858411,5659358331017903416,18032541757315588009,12018342644007360011],[916101087035220570,17833887819834493266,453742888105876323,17716422750270833711],[14109549366157567110,14965926648806529148,7528878696193150989,9729323394811380598],[10800832795647053320,16346646359066884912,7764980433133728536,3582645127583355240],[18129798452825518530,12333796758695947899,2271003011383442906,2262568863729999851],[9579876229689106174,14473734910649773527,11058403108214603472,17590133922486505944],[13483212994166558821,9619490416961211249,7487465914449471500,2433432872616097726],[11291340362743623681,13081747335942115734,2481094984041734767,18146857779829253523],[14036032384236550218,14070625045414699690,1751268403512862623,4766253338303387375],[11055314263324923305,11170802602724700630,6408990527393940685,7681021706002435321],[16614372205187675403,2790028100577844088,15346256193037896549,598945216570785028],[9391531263624388038,13730644107859653358,8514042525742764970,15001558276327325305]]},"quotient_query":{"leaf_elements":[14448637647276451582,6407503677831188010,4480823434342371863,2949143853124372869,11650955696941969728,974648863862085148,7220255344255011691,16214630350994382807,4493026095812037299,16353230886471264927,2868383792976154666,4264437434972682824,5103916711251107582,6819189563612830892,3200419626611242741,17685680013563095130],"proof":[[8498388345894737736,10965091511126566882,18218854180477309058,15235173490028424916],[7046017453970087331,2404660627463496825,17776535294012558720,8235486618728273890],[15756718809338049589,11613086349474941147,1968908297101432992,17717127240557421806],[15426995986742014613,7957858750795183307,5467720485416976996,8628076090068460137],[11097654433100144744,14440532660890154257,14162416768732053778,2458437028049742338],[862429675183474265,18112012595983449897,9677706503234092207,15016366231874075625],[12209684186611419873,2788229736247143795,3225123626538255312,3509539557094808770],[11496573075612262819,524106572026079727,9097439046396054510,9484511710785829193],[15216466197559677724,8266864374946270800,6876276232369731398,12450493492449063303],[5500503760126029320,6544483968643148972,8783707148127617092,5556512805502150080],[14826018149855964119,2204176963005901081,182202602774440953,14339609210200655082],[2530910185624635215,5083254703708309327,9874109260975154831,11299327224143706107],[4774507269039243143,13007102699690124053,16166033873742892257,14024402933152632106],[14118637823341155586,2747501272928465736,18138874616015369009,8168084501905183719],[11706518985947258414,532549418258958805,10907607322462163892,15302828549070722231],[11340741507127699639,5790936188393049612,11815129518374684750,16365851740193942830],[13645857246080626918,1593966545496058388,6138608713472258776,15319755324748981109],[2799163134414344231,18205618057121846507,5598986257648441868,11793149271911637226]]},"setup_query":{"leaf_elements":[3908047166357706748,8199761074510552855,7552957260327510726,11552905872544140169,11798311020823531719,13795723315041315744,761117823609087380,12680530680612152739,10448393063756362652,7400006070025523558,4651237817231315152,1089826668632184705,2881372270377152300,9828943928425415823,7522951458200686644,6284398033162135500,14286684121850539040,11511251381931206640,96786282853319374,16632932849374074164,552019256795754007,16904163113751943667,13711314484668298336,10344927348134712821,937617906695906293,11828690173773078676,7712261854062844523,3807224789216058383,14542374161845673483,1630716143171009860,379414425937994701,17703742094878730583,4025498244813248572,1648128269002746436,1586123811043008009,13632416042075295331,1979525679268389485,11654369245530452253,8750185966705789602,13068058165528934664,1230484142895289161,15721079902979312186,17946158649169368115,13657010734099500344,18134746234482998969,15296497335160404018,15276836418431272829,10993769804485914877,15229643774958601142,11297174113977268176,11533342874100824174,9172034140248700183,8423823289094743564,9097979493457098537,1401303001227320985,7513788942396778274],"proof":[[12283900627107382643,5382918168483913884,7632440654319494167,6981477665335617834],[17058740470661338733,14928661923317639139,7607722816977753189,11793140445884807234],[7297379987609281256,5531286619193620738,9054571566721024187,4648748064703148517],[17593468813879459647,15149798450536310838,13620913334091920486,8419571664043822709],[16386252780742484515,10786771774903641903,6034624245180204105,8063618830230344100],[921361675921174139,11222011389834184638,11465986677221609551,17652658407461506511],[16568251767720490851,3920467012727364345,8566791691826598725,7704608854490785138],[2425947350517959555,7383588295984997441,8929800593566020916,17468949900682994825],[705556686336606911,3270827679095286922,5837796517078954589,12507387107916729236],[16841628778794590952,9497482716941338845,10858196481254806301,15081812848177704748],[12791019824929651339,14099251027523382653,1326968167667482813,14080137578950343484],[11830078415501993877,15838473723323017945,4787381492849386908,14189747006923649273],[7221907043916228357,7804139379609293824,8953369965559436702,484936834834190793],[9384553824256022002,16084378506885265447,12113238668007163975,9518014374204967877],[9642686661069491705,10480717864252276137,10527197538739471790,14964791325590381952],[7041084738254529827,4651717414442082703,10233485876445985825,571829471340327211],[3947434609566887494,1314374293409533365,12459105590072671994,5103939276420888004],[8833308348027662881,16517179675173875256,14863395599578902998,12030876739440667579]]},"fri_queries":[{"leaf_elements":[5246873339553425181,11748787433697587812,12723053125148834067,13500527403312695099,12239789536375914711,16123861262830826845,4599341920041170112,6990253349769570483,18342165737548716352,3183795892648658811,15913208491330798971,1204767406151754276,10134493949081102510,13565013145429254905,14066502347326955708,11426296101634859107],"proof":[[12283623173833189412,6692242022845810864,12236994357940142264,8051682744572486912],[11054789547565862571,901216962275615465,1477941802673705862,11873197685713568638],[16520017867943862455,11349037942953562098,2782108364001446944,4120344733256334906],[4638433669420088825,13480995692822555111,12231509495048433200,2589488349587049229],[7151425474516189433,2922705325651802917,4728630405606864993,7550116147140426771],[225624665655024547,6721804156291681755,6938619546795214967,10868582473540235690],[17511284305918058285,14760236905419309918,14561173216659836065,13853622698204763580],[1989262005183049181,16880560912936988162,6486861445026303873,2587470273510073828],[16527442448468997763,15568645038409496578,6180938488839967731,9931569806900967558],[9309269808990673083,4826666798904269424,17354143506120886075,8702121478936450316],[12413540128655065384,7981612484602209159,6437182942323214905,4611704191412120191],[1569834787828260802,3118483244988576981,5715785056726637769,1202856020259956916],[15355335228385370694,12390491963665631576,6955507965940558791,305993477421908299],[13324544584088485100,3098639767495193430,17664328652435742898,18270888621985601843],[9245107685030849213,11028601889881562353,12331961901391993684,5705136287449633417]]},{"leaf_elements":[8739690853438058249,11166365083184630711,7667688137032091328,4112895251331474680,5727643725803949287,4649174142534792653,5461585479328133842,15452103934238232756,4947858268782585442,4499109209725153304,192151130922741419,8877376683879588915,11238118592764119951,4958165134788594447,14444632092739291908,17620782860718283483],"proof":[[4185513714746634940,2700857194944584028,9935058364794848906,7535588018108982852],[3909805895089522995,7521826461487617021,10694223149069089768,8660145518323614403],[15005960409012288513,995000663818318615,3951749510195882441,6810501684020427164],[7726263027990576977,16427591160159300157,7164620262300215307,12581825762564937686],[9047425787836960204,11121334505723237034,9802284593374271158,906104083766257211],[12401698800139217964,6354004357669528370,3896616766862612026,14090983552340002984],[3971334095883070839,4225569669171121347,12243826415234764180,9786199827801142021],[15692276089383476493,7124483115569315453,5535417223645292164,6947978755021489946],[517640396006198728,13346437094122588676,5363051517133141369,3210346948012916419],[18300544202247725371,12937817812064110462,4218161286360567227,12237693196329693675],[11411871130029409553,3864153559374549046,3653776562692507308,3286312724220608210],[7988866267726296320,14226557170125573222,9324188540007280796,9967983085257835857]]},{"leaf_elements":[6079628511376406693,17544808396526456166,13085958624408075173,6475987868031019176,10558404621445840862,13644149367285072605,2601498831933346900,8702017272234706127,5047805705649914327,5395869782144262586,5199869283841363074,3595518044069977423,7343941679048381793,299103167442438605,12970639263505626418,14016093686248023551],"proof":[[6300916597324603019,5023685928932214634,3478043871382356848,4447085507843110922],[16710092362704600913,1613291599497366901,1966724151285925719,8529582251166429905],[13614283283557076207,7451716058800664724,7914780289505129520,13444864293792313168],[2544470151840395165,6093079035005845496,16401538758258626103,11422617424349239224],[10081878855200958879,5710309849166710643,18239885111054886724,15190452569780210493],[3697199725391455839,17645228386856978037,9122168047320067308,10733696195226575701],[2294960153887003600,8741228592670157942,9317111884344929776,262814172555078703],[15980627939449115081,15132912307725954109,16581666644922526635,3921735992306860071],[15734314615854058336,15700167148645689599,10188826244248607564,7536323257978719024]]},{"leaf_elements":[11621529942777315195,3124069862712016606,1453861285400755550,6871992019712441415,13662923261740054703,2468147217820068869,3355287935987354997,12979077700986886174,1492042602283159480,1387168241926960567,9742595594902849256,7782885956621204425,12967345954991004739,7022588313352712780,769308511295127786,5300890956813129251],"proof":[[971596868186438554,18000887958954946349,3946287696302483342,1036037445958753811],[9833582026439728972,16627266614414155319,13805684639342587774,10085323145156283205],[17508114836651278106,17498598804593985998,15888784989559768998,15678830529420844520],[7086396843784602190,13321032120155818876,17326251432749347619,13185269460572244127],[6582689762784588400,6476147800425542616,1575075879923887726,13997710000696305883],[15448003216238380467,14723095147410078775,15237205668534450828,15382590376812770243]]},{"leaf_elements":[18076676151314767212,15912301737468923201,13788230214883064881,11304803616021802662,1824486867322810599,13771958491779032334,3584099937668699381,4094436700614473904,13933377392568689942,3246168070785520388,7850612152127152850,8743691117733975742,16700671708081799135,8829177565392980018,14994396313896315683,15854023700312342354],"proof":[[27445526706288272,10482620797685950391,11285538286242225850,4927579576522311160],[182978867677319881,18231124276819766572,4495570200999870229,13639272824537972274],[8194562633994890846,14933604375765338643,12777549858813397645,11261463020358737833]]}]},{"witness_query":{"leaf_elements":[2090854675427051191,6225276690990566923,4255098818761935202,3351203109322925141,1917678084828195993,9487740958719872849,3632914461610558408,15321286038760122840,14934711966242825979,7735967282302112310,17502690578531605798,18150520628528901402,6790475555956012736,4037778811535716467,12906220477219608836,8601625917451032012,13444930355633557495,12101175409301084630,12902522114369682943,2834342446101360184,7932645385044891336,6739036246099480375,3441364073591856138,11148942837303082125,7145765445211203436,18205941985613986815,341016261131275857,8649089458457459476,15061755501277745797,16390342730639982265,4810218695385234324,12580409063277320341,15089628090493112446,6277497087434271702,9673014217839763923,13544978003423923725,7956149449631068257,15179967947866515516,1020485532085766695,12890234855914567025,3514687325720405253,2224707020319467480,15099598242436360739,12561448437627869055,16081675447775613240,212263102351781868,8078742176526696514,1728700472171379847],"proof":[[13172893579157927822,640417273401439628,10090034558222208189,7398443369409754863],[9915876059454254558,4679902004445680221,1497055876588466881,16246962914984194458],[3370475417781199406,5686616393508868844,11214464341394248797,12875927646877215799],[17385828887496969259,14675991867398903734,5841068944784195122,336545142890222808],[14530844274772129965,9260192472900121338,10050604685691415421,9932824165612761591],[15724792627696842585,8567270847925214104,865118316253284675,11317381500027524217],[17287160244718202024,4529434883194980410,10382267547192705828,16419977225871669750],[12674818377772576334,4362214000739134842,13255388485313776684,4549331950527180291],[5796721647378430705,16929160165579792717,674921163529377979,7691461944181821541],[12903758017318908315,17047043581995119557,5973241979921385620,12255945258615481684],[12525187858058515516,2355792908025017992,9590428551141628462,15951890910039984215],[12725771603402941758,2935162768182721405,2517379923274184311,18114784019542012743],[1453464506042780785,13601788474513857427,16747344481057191874,3259979190776541254],[1840959254014580288,1365322510891118600,4464541726944144785,5804658933903731834],[18097890338991036584,11068316821767001107,868544974471068181,16226289768412610757],[11233636795876897190,864934519146470591,7884933087676049493,1714484794283440206],[9460666903428481551,86535353367692350,18427729838772223069,7680358008986207430],[3891012648020747849,14843786826185715946,2093661453328639973,2821918487938754064]]},"stage_2_query":{"leaf_elements":[15687503437518149138,5020757605428335273,14480291398335794892,14977040596411197064,10902431006587647992,5725319502353715491,16976516608890375349,11589163451173591942,2820783648808444487,5046460610770561676,4901474578943661363,14154831139949691699],"proof":[[16253945368832814242,6658261640430691224,10582595148365698116,2988573935129575580],[13575730679780612412,6282151974188711797,14965741619834330965,12406584035497845182],[149156106837709629,10277611912566522389,7631732949727891528,15090970409334011785],[9368026796150233905,1947316430687910158,13180620269088517410,6539541862753527413],[5683341336545975978,12489253196707191655,7167042270274997661,11350174897925647676],[1678182374176039664,2324800465640325409,4266326345081416405,3649316048016246474],[8604274202793135310,11815648813402827027,14142750278058645204,13585131985894983608],[3910838251412506872,6527751551552611602,14156835895609500358,16422144302189594348],[11645708406806229024,7462758174197861283,2691083788943168281,1963980080563028344],[11021046164480387650,15313165035317149372,764352444325028339,12988833194680368763],[17738993839665544568,17362054437353906049,18347037137899574926,17422730781686285134],[17161522496534437013,5556333905219204308,12029371797967230882,15529838295355370595],[4682797199590784262,181512442036985665,11799708204325636327,9541181110402516108],[16952076163143232556,14412709376035023341,10641199246893546445,8691756125480825672],[16872381280722505942,14012695071349714850,3997851585971637492,3414598024789252303],[17815089589909372820,8412525930002422575,14574420618998270193,3115670764665595947],[7903839456265079682,4527813511733106221,17772096184753347112,16748133004463629576],[4469434525131405271,6022183154168507437,2168860562419193934,2231389944886550172]]},"quotient_query":{"leaf_elements":[2344962500627743480,16673874593042537790,13936673928389454379,6131082052149784125,16534857067736427339,15482261907082142623,12487952416122134759,9224134668630749776,14419050485090672952,10339679030081459659,7341406248816142809,8502971067521875664,78334710514680680,9918450319910359656,5104156116042693507,8649430721786457522],"proof":[[17494873376229201315,3451964364909028485,14555602056051293839,18099858462383935866],[6838894030818119164,5644733129833172498,16310709093145026017,6552282020262300949],[7572219973298318651,15776611505756708519,17418538032322879927,294628560530310515],[3318032505435589394,16275155205997464639,283864547975235121,2342002228746397368],[2228028201599294240,1311405036200275373,9972443204555776481,14854753904765451334],[11862941021765584548,7608455346416695924,3605422566501081712,9751158117921295946],[7316952441495872406,14725493554086532280,9879556109028624405,2152972038363214378],[4035909300022803307,6390834759753931376,14310815738290843869,11055693333172012667],[11374148797233670989,3111260630673706540,2633023678223007184,15427386040888961620],[931563401894898163,1925508915660047703,8822810469498537989,7311979323527984303],[14277310176231531956,11233068432122453157,4647354617894176788,16805031987932138951],[2694625977000269567,14494318881942374389,6857820879049795913,4159490465951257682],[1443130967122349467,7376344016696803176,3971728271139323479,7581196438094532846],[17467175718300504756,7522434030477442461,10542649857852524017,14244930421232074697],[2172866356249987921,10574129851924918425,8210634239005129349,1073381345953995042],[13537365139075742054,1048570844316830770,7664252700768662395,12927502780854904691],[7089311533526475501,8039142261043594468,8662661121847442724,17407891573418068016],[8859274335870636747,5838186496339753321,15036660465237779948,9780603874582360799]]},"setup_query":{"leaf_elements":[3957841638239250868,3884241561980166014,6693933099164396240,5343867492423369797,7138428548436678308,15449016790629623811,4055733692586389355,7345193862574751999,13451302308981973421,15234387709659718406,9026570547622495349,8025615428169052707,137893742274813017,2796652839899820742,9489900455752839553,1034995311317944585,6129431453166981225,5823637280677155615,6546141251592298874,1046738163529076747,5582969102084456114,12493044477737465337,8021954900946322139,9879518493039701527,3148522739233147140,13815089700190070878,23127562235105097,5848098689101062083,8969270530170078488,9278993206677921086,4803373779066915585,2158426071426859769,3129531234867653283,14363285839781565268,7939594703099517029,4135232180058646363,8055672125661349356,7733253860964438806,9444548410377549674,5106524299942905255,16487343123498860822,17178957138271931055,9992789545403013384,8280672232761393722,1465532526440814291,6992414679399583160,17322166646502192344,3988714542444578204,16121375787701347614,941781829381637882,6406379207637218669,3528489134648677135,8488922924765014691,11371542655530926030,1364281641491866345,9546186310391967645],"proof":[[9095089225028430518,4989039752470900050,13868037907665954174,13285728480865220931],[3370226143107786238,1694108129309243262,17242311103023762876,15265791110341487668],[16425677654218829196,17961477768876824542,8190793896470145788,6153868331664911849],[12508164882818536385,3833082807129218894,18374420646259492900,13354497925169323427],[14746422895788678393,6213133798269504755,7590892834766205223,9560729627276365663],[16173229692926202191,13619363129825255765,6588608191091573359,3275550167852502745],[15188206174748607099,657305903302759761,10708436683708522119,2466803090139050720],[6554223857369475763,9941648778218824521,10559000999072602416,13806916991664889866],[15977416448201608560,13167537495096282267,7390558981404023358,4655700050921915134],[1798713020282287677,6543169209040337647,16334323567791498874,6846607566774847915],[10145253564025124913,7407495213741717007,9069973597473558636,16945339003527729942],[15994889900767544692,7840821026656949813,5060015838820485340,4235231333627929482],[1822774469245581784,725745850806523146,2542743941164428072,8290573800283103653],[1098144407407315902,211404037569883854,12011235394249238380,17619359635299506917],[4842724575415858406,2296211935592015761,3174375922544283901,13422332236307167377],[4726887321263617382,10747414911219687453,9477013538821104135,14650535195383225969],[5566469597458037467,15122854441705660695,1416157050904271894,1153189190891402810],[15921429755520043953,14077808127348431856,12685850570264828289,15894453504141304101]]},"fri_queries":[{"leaf_elements":[16489776801678917139,16921691394326063138,16242847336214009209,7188104157446808989,14018263760965935901,14062294739426931714,5114910038777661677,3434240118610823218,4865183772740063208,7633307384005414405,3717175383896732224,5037154528389386726,1102108966703478128,4869332058920392471,2921657829412109273,13605772066776182211],"proof":[[8377338227270933916,15462379923698409170,6600002777726566654,262377901101169944],[574266636658828214,1361832248234109215,3381873942404543405,16045874957911461148],[15650087730768381070,10227414168229717639,16440178932460494830,16012451143847133003],[15545790582047432295,9676467403264045745,5216438437482478742,7916170881347529858],[8290524552158851346,10335919978936195389,11029519516945506529,11028921176385339298],[11349905367890438546,12896721948328312303,1728459293074726593,2618864519018000213],[11759693220001266496,6774936074840696705,7126807888599926660,4888383008677339101],[7475427797336651807,4567338776376222899,4984386074125131616,11492264221115455804],[15656805445832739949,8971466014778189619,11230599592231548317,1945486966560972310],[9720478665448214872,10794264683832430126,14983561284071079485,2517487147483656607],[15985209463025418245,5827998720719475003,10606650102093194104,61085120924316538],[4485247967244033269,6822235411878596424,785704986288429276,9171971674909144924],[16273707858010364824,80469829008564224,15393118771580170713,489040701018901400],[7953000689301911346,6258713516143713042,6898461784325404224,13609115517100241224],[14443048083015833058,6384672627369985545,13146867765229679381,3146343307661537218]]},{"leaf_elements":[9796986316012466713,7604388504166861083,12920317854070781156,16446428568853014408,16706255739631486311,15807783847820520900,4536658893953742048,3129462529976875902,14455757161061195644,6227305820800369014,15289563418597227134,18077108778131237339,11741368375210274395,186089172605102658,3305981706712595960,4079507563850153321],"proof":[[7107932698518234473,17962000588312643060,6295372866142514649,5496377961221286987],[7003040275054800013,16785013178403187582,7656838069920252071,5737217991627937640],[3590725355962805195,15396535778173462818,15468783267573794879,239986442366281852],[10296651765498403187,3864581295773158958,7839651140828271262,17888639860235701120],[14021587089576266460,13869841320103267255,17307412804508025565,1724378561518842614],[13349138092305028407,9291588607506433307,2764697551198843281,1977122206541536021],[9118262914408630143,6247057878070561283,502270482344966465,15678663846232894950],[1309591185843432666,17016399144471037978,18046822536597875068,3858006290279297948],[11343588209568895617,11293245552019441187,15720019831438728433,2127160732514629148],[7383183561198363457,1493033301563225525,10958215933209936012,3596645532398551518],[12100961906675001362,5054179548881736162,3777036530832678969,8742220057881496494],[11435670363388757256,9570195244268405681,506249738894622783,14155869619869225805]]},{"leaf_elements":[13358666622789562078,4023809316088829932,3702144711655623602,8787200307611088023,10977414184662212982,12729614085447257374,5681117999951299276,7764872937715023132,8379824332334633890,16348243353831074445,485746915399405076,5558282731195232520,972752346667011127,5577353676264470945,2187176030076608756,16312295163542247496],"proof":[[1941202073694125504,9678805842481320070,18213133660812536691,9874753573546582724],[7222494421578104995,13961294621602083484,16900982875331961031,13949287703829192021],[16162701914878065735,1913918267411232465,6278505082834155998,1119149084577726032],[2445970225611191025,13732668393339032266,8486571184808625273,6153240953677780312],[3475837993269560469,12104454426579144101,16427776348732829136,13747768614295684539],[3505963527705725013,7348973592273090950,9906977105475310092,4693556561557321390],[11999566455065382787,1296095742843632791,12764317180385994929,3581151439062059621],[3492375228405084804,569941052903432749,1161175657787765750,6281507140233991444],[12054166190586800963,7945374787333011277,8517657448236644247,2661694593065817282]]},{"leaf_elements":[9016271071935539117,12535308149770950698,808725810378252973,14669144131520040886,3361298275295477220,9003676561751502237,10370769951193048599,8786777588582681766,14289551676679131661,5038556096800004189,10654286377172040886,13428369716203463945,4825497880399897278,5669360018886736579,11728613165396056514,7220087697179401294],"proof":[[5803651433669117430,15985652011347251913,16155754200009530945,5381583852905325476],[14104802515260415302,18177789070475563694,5706724384248838185,2256696622442067390],[11776522383547520655,5421531380405390545,17424348498680597715,16876892383755711915],[17593699242702054355,12382140083043009758,9016885103284363261,8032752462621391740],[2121102402267791912,17902052308053286535,18345025307564081769,587210778456748502],[14710713927116519418,4916836987224732428,15959760584199579095,5891726997841575662]]},{"leaf_elements":[9949990676024829044,13462240670374897806,229748857083397959,5053718599292030143,11823780255499477468,4281691542277403049,9811899055896597935,9297179991210356449,15956832325026572702,18220078047369337561,15431136898364591752,5383275574957967258,3662204722660259139,5636452360883760004,8610139818506069375,17251998273130218321],"proof":[[2941695560672546627,9776519158166271732,11179522009869498250,4438190937731823380],[4938043138020474916,8701651922197586508,4046327333616030961,766412461751498615],[4520246198191780881,2664929267784600441,15915567444828812118,8340693260019474216]]}]},{"witness_query":{"leaf_elements":[1814819817144347714,9988568664646025370,15259459665554236112,6732527143896249083,646144244020044589,6541156325101793940,13143862054873318922,4109882344921517508,10921813090743988187,15682818890204959173,16911736840850136976,9511520944093507580,9619267826171592706,15560023348593742904,17341320395029642257,9841218148720053896,11340143937728216970,12558048206369599822,17911229146117666536,17653151139500988904,3214034716878880872,10666580319758942273,7332487465350356569,15584283751917982434,9458634283926522446,13320410730566173629,14721755100572680883,5863531280396389398,1780059029334291652,9717001806107899277,12632888413590110625,4801110544122545315,7921749562066343628,5446288867601292863,12516407032896453787,3958166872782571462,11762062868817798246,6137885056242007378,10776888728653217463,10034785250670372211,17856844123152092394,12696148948458656223,7902239985740939217,16492729773431657272,1533706117906275696,15470161212891147850,3116649157246942118,8079128028140024945],"proof":[[1614715191445205099,5249642774697419006,3095295903852806365,15790601502832271220],[16880783761208238623,6756079974564905773,6668186676071935744,321366575809952711],[9913455626834058625,4985041554611220654,5403510346086257952,13257767821719318140],[6168607346459062367,17342917209518670035,1447616697701592216,805173390265941724],[10975296582032573035,17242622832100020628,2203632234191278509,12228265784123297597],[8052122320090284584,3678531418913876879,10222047285620909459,13566451373704056406],[3474468349810079127,10857836532344313333,15269296670724347786,13223412182593502974],[3235249118470996534,4941372999764346278,15129781213659262530,3247607349966727656],[2137092619131607986,17945582520363875702,14575404338004490678,9047592668869650017],[6991086414160553191,8884710195423829188,10374674568735949530,15386345961061122287],[10350232800820536969,15750422625785469057,1195259149203930839,6231550584713736310],[1761541849135142805,15697222977095241127,10941950268144097137,2513196640181045310],[11733605599610554746,17287007572908866996,13784583960862684190,4615092086413540134],[5348832802245307386,5988499411056899991,6187273120397146946,11430664782439298719],[10059090542900356666,3742994688844652701,16451675531373488017,3044120730124304026],[6685153829703860974,1600323967598809248,5284149249619364303,3779214564552036442],[13071370502002007379,10684731432244351154,18350122479141913873,10507746080081961618],[3907900705668083963,14922510500786564345,12862763145340389366,17397272743405774534]]},"stage_2_query":{"leaf_elements":[1165694496930516277,14786884863434140718,6090399839024339606,14231105015422506222,7111703889533897966,2176152447586862806,4436698562961155915,10794110789728229068,4996256808119509535,11191153408163759815,15345492545397889771,15173896758583147384],"proof":[[2381219654036154858,5133910743923501807,9701522725898705922,11075662426996550553],[8339497128426062206,548484253395315961,7766797449534325388,5179224232287553468],[8079129574587720254,1328880758984691592,3014918621348905040,4370743004049339185],[12051789048640573363,7548498909745390439,17896172089615969053,12478591181475382215],[18147567802159341091,15241904388046924372,4333222645733929675,5688461156770837031],[8079480318250530384,17472541082177943557,13479464961504946736,8501790126333814931],[10194092435047626462,15625950648623055225,9979289602221273432,8235793582172547444],[6437811863250472017,2912548523491343607,15294563275579760466,8764688441975196403],[15458269067512511641,1704421778377128741,13393673987361687810,14844410387102824908],[1473012057348019809,697398787664297743,10074662543120324231,10539082992430868944],[6091833045693205432,3437615908735092586,6903601278649699578,17166413183766699634],[8209059108027746860,12497054031679086992,15772126377929492639,14073173211283312065],[15840478012144018735,16519071808368267349,4834208117105429843,14457444374674183424],[18431487536129152012,14156774805624195418,16095478488927364156,8942173732735823071],[18141553717850237623,6984990732556809396,12748987456441355660,5659860855332537488],[6487357007227361938,9511482271504024520,7838919282788327047,15290363951455370866],[17243084855826773545,5337061957383076079,402873644980936689,13697425446891540818],[9035997490969685956,12706141683081848156,5934077683350838557,1551392805899216779]]},"quotient_query":{"leaf_elements":[15395438503591389841,2539151852248394354,2445748535109466266,2742226759385025366,5372434650896890145,15460268168250866957,11912135052236200426,13463610578872881385,7103893495614831946,2540030746165447804,9618250084321545107,4626463570152227995,17492219146902778551,5775315564587767991,5797532608156373162,8641989420238422130],"proof":[[6793024283738310570,805990117970352625,5749694216452464395,344650829134596286],[942429217704241374,4237589230255186349,3930081560701127126,14138327514212479229],[9374793479550368451,6087773034324914512,2612488845123589091,12316993997809110292],[14860707567529362140,11524088980627304965,2272074625034441729,17411185767645898619],[13424177119820982277,12877361751108574499,9469261258302893173,9649742193334288128],[13796566517813512912,1233672105208022347,7741898184175881456,15730534044324111378],[1654671686857286972,10862235261252971277,9725679751714201845,9464496522050756849],[11002253575301632918,5647076749345680406,3737202683460414525,5196409321078368738],[6951249177321328118,11637894816970513893,14573442374922893450,12068017059279510106],[11171158474410679818,3861664774665599781,5618124456379999503,16738965722224067679],[1686395851343611560,11814458177470983328,18294764128835067597,540694226999558742],[6919349864076547288,17805246552986945470,13913354807964686146,978819381619677345],[6998703874229492213,15807816979557292091,16327084649033551479,8493215292290895754],[2532268528915978204,507096350040160134,1228785067903539532,13977419211588922907],[349821702915555503,8816689550808085719,6085343628247472482,15784842990921121500],[3324668339700517151,14883542523041088074,14113727449747458180,703418891231629383],[13564771666885069775,3627018710879460847,1911762058170727279,4385708589224906415],[5352838722884438161,15337039329465422330,7453342268093539590,6648772637400646807]]},"setup_query":{"leaf_elements":[10964325391372953971,6187057123018883609,11445282342615073497,3776885826346708518,17412459354478358346,13828028083041272645,9225761754093353477,1311004263206037098,1639273119434384844,6893993586354479106,3002732799483304263,12121886942934476045,15226441087214908635,6919463045394326335,2425932794452115359,3317829453396909096,8442521848300685804,15236372970105651250,8770021835729264701,16490679823273784604,16190620304136944171,2999639694117421995,9551134269851015420,4375589166033930534,8092946649505286266,15716060668425946685,16241430843433571807,7006636253337032381,15463700499703051091,1261308026483155567,16517599460912947888,11740017019824547121,11153710237142101800,4916280075218919464,15223722549712096263,15077880947028395811,665280978492261963,13395412132963484852,10284709904372208147,1706772397926144988,2842370750144857927,8784506708971014697,12666593504873017730,376041698482799542,34786211900824218,16050644591963623218,8294901638001480163,6957992657677162812,12871611413146411296,6452833462157691907,18232430944652120468,17149763856740879602,13573266993204674521,18088873455401662344,4231074291228652125,16345638195423180345],"proof":[[12929390910368670936,11951776053484061204,13871259564605182036,7836841177754431329],[1297833443821053286,7662362110796751494,10314412762581098508,7063258076611503715],[6484525486963244199,4844830815653566165,12067409268821272417,2557699586152862957],[16826262721755976904,14043162563258386967,11280943357752171394,14317040625615649830],[17915913080222596267,5469774918710762779,9171335961166843346,6971799322502558792],[13963213400885421150,12663301134825364179,14823281134914864397,9197872971974098867],[6456781512926520139,2585531758591696639,1097528636050446343,15687594424060652925],[6017882063269810917,185926091726865805,13736326823063496010,12089366555810342025],[11308011066295669099,10046653139560642765,17373717937631123243,10068424593362159119],[5297155051489010174,13707126194372154608,9641459447911778648,4615768393010449520],[14788577030978986362,1183930781724652405,9939361335801723571,1927735124797822566],[2698918488182113557,1239586434498471956,5154077917544219945,7519372249305651190],[6532123980625538478,6072808081441509414,16600642028185811068,11552473954200883673],[3363332992633598545,14357641563998029992,5747348784955835944,1321461549573573411],[4773386489950572700,694821680471184952,3767568188378187199,14754400245056609944],[15818834484391979876,15185006683700745223,6449991504461507752,7253121887745974924],[2807719876218840764,12548264829409420705,8564382560464953787,17226596535090502554],[1535706127255721600,5575187156618135904,8817516877202214930,3875265006754882320]]},"fri_queries":[{"leaf_elements":[2590806072180500716,1551616959522555906,9996001489230516004,13457220343373878874,735593934695575907,9246104974887483035,17329331291541760735,10137984607297209708,12304573420092478562,12788458609506328243,8178939551155872856,17204235859457392860,12448709921449304982,15322136973741202869,13046872294918986767,12923459083422010953],"proof":[[16827744748215524008,9288739213088432825,958843305087589196,11161227154062038742],[8307663822802556633,10536769094542443052,10954632924160894049,132009340187528471],[6441505577777737032,17555172397077446408,13866462472413751261,5561791786908313968],[3180130942745768953,17490866646215464439,16291890136390611620,10418455732090360139],[15782699576694643828,16684191727196759474,7427881068570935765,9639053474420131404],[5551704052867876889,16773182996687876751,4834319472047264765,10386257058972650341],[7750715514730541266,8079220868572803795,17381229519817685362,10404529388128671801],[17998985572560614408,7166624615972679073,3056429650858886812,2033813949991548669],[14403851683332512406,5680074812900285691,3814009584184184946,12582111520454683215],[5783224214798720134,16229133305255176433,15143308945798117742,2626360784382159953],[6944004763819849585,3222276658918991953,8188909871996005010,9497001919411018886],[12135865672768823999,769915918047400005,170686355599414746,10795568251384527355],[3642522542495722228,11412761343119759645,12026454502606617685,16897697392571550552],[6680698149471727150,14202425043352883511,10965568155806343344,16469096993815572203],[14362060684039001345,10325925697371992843,18137267579644677844,16990629886161853631]]},{"leaf_elements":[1278144858013733130,1473090498376760669,8912791734219449943,18203000897625824089,3607442337348951498,16790760778432650284,4651002458359396750,15506786501203703245,17474572525757545132,8713737080290339153,2643201042783648982,9348531986343390930,5605076905912888137,715998769879494372,5084217667507936958,11119576963900817351],"proof":[[4378118298916704437,4016954261708631837,1116494482850199786,5440045603370013504],[9165124085393378647,136427163419930806,8562339365764181825,5382761563357579336],[6836048010684996728,15207766821637690387,18352279937606977571,4076451825091602459],[7984314840598285710,5067114761006719600,2243939596020057989,9421981579207091042],[10391358555059175726,1743348791363407674,18349379755501289476,6799637878097655487],[4462661839925085792,4366750979057927391,15560936418607432477,17776682794827630688],[16599784546180375492,2997964824464952616,9658292744304849314,6744201544290674957],[18048309604424403251,4418766823798313130,1861899435248198095,14176056661857974361],[8257634993023410053,5446845424048968776,14501588404314119805,2825149100271252443],[13118848490437023770,5770242959246377756,1124254211519928796,5196188490272911197],[11879520396025637374,12194182315750197025,15875646826313452059,13283217322112206368],[10625958637139347406,6362085959161359679,9216241890618710385,17870217730633779657]]},{"leaf_elements":[15028176269683052716,4200381311674229835,2663971774072469194,2291100805045698259,7781680059953587104,11877805745661605688,1079054857454804466,1409259387350599538,11215994709060192923,6223541996462541429,6069105279950434194,4315862010111364370,4971906246715227539,16865700212249897586,6019783311818678264,15652683465410641497],"proof":[[1258605529200061248,9347740508215224198,9399208494698291386,9678680652506642554],[5366947374498848255,4999632573817829314,14100933280139598086,15589074550734209390],[18257761082994875651,1939753153309878119,3444489780478110614,7934422287257335254],[14956085175764977597,17801406473748621144,14534748255256954122,14421726661486610948],[2010182102093058629,2771888932058409414,2222140979118017040,5838188919496045668],[7811897843564996820,14354708742032621804,12931559449648736244,17756443919739155801],[15857661028449345188,17421664484801676123,17359187766520323914,2904937251417302448],[13607930513635884161,17442145543102231438,17945220114611014092,3499353238167423973],[7813723060696040439,1291112458644889275,14635193487089125269,11041219478614796203]]},{"leaf_elements":[13415437018198592072,9210504279702636167,7321007166942219264,11899389312812080481,7086568408028768567,4219562918805449988,6025333658820348825,13148621069072519416,1653818775258533115,9201661485829121104,10527966501408970278,1817245086396759630,1633270020306817848,12247017006365043395,1008502988501155862,3287608649265399748],"proof":[[14898357234250418604,9044670807511817270,14527333445897927566,6915499495795678073],[9872669838541567639,14979843571311718427,15023006684261939196,612571587741677902],[14807339948216897456,9526775310207906821,4718627745113996205,9026850367002631569],[1874307055475690472,10926552935464798788,16209922670205489144,1434820357434614645],[16326855226596551624,6286510272670693212,6998886249969664334,8505431540656170604],[10574812525453894877,5880593242216872551,9568528464138403942,5793901869354254986]]},{"leaf_elements":[6123559405512106630,8955322710880138079,3662312013334252545,16565089662648576302,5810330713543799825,6140350861912579247,10716957726923232102,5936326552904305123,1181726269509467753,13376985201790475121,8214406859310653984,11319814374840426437,17210776364115216763,7126920003640986360,418958041769927864,12855786836507037509],"proof":[[2588557775832839476,7756674447286202,5268659083210045440,2943526744465537565],[12461782947718060184,13418278835410767929,722377642466162959,1596080864842222827],[15857347618795526205,11485512013945494063,15271999501599471210,16510912266378221486]]}]}],"pow_challenge":0,"_marker":null}} \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_vk_1.json b/crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_vk_1.json new file mode 100644 index 0000000..f85a371 --- /dev/null +++ b/crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_vk_1.json @@ -0,0 +1,262 @@ +{ + "CompressionMode1Circuit": { + "fixed_parameters": { + "parameters": { + "num_columns_under_copy_permutation": 52, + "num_witness_columns": 78, + "num_constant_columns": 4, + "max_allowed_constraint_degree": 8 + }, + "lookup_parameters": "NoLookup", + "domain_size": 65536, + "total_tables_len": 0, + "public_inputs_locations": [ + [ + 0, + 43116 + ], + [ + 1, + 43116 + ], + [ + 2, + 43116 + ], + [ + 3, + 43116 + ] + ], + "extra_constant_polys_for_selectors": 4, + "table_ids_column_idxes": [], + "quotient_degree": 8, + "selectors_placement": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 1, + "num_constants": 0, + "degree": 7, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "Fork": { + "left": { + "Fork": { + "left": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 4, + "num_constants": 4, + "degree": 3, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "Fork": { + "left": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 2, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 6, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + } + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 5, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 7, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + } + } + } + } + } + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 9, + "num_constants": 4, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 0, + "num_constants": 4, + "degree": 1, + "needs_selector": true, + "is_lookup": false + } + } + } + } + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 3, + "num_constants": 2, + "degree": 3, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 8, + "num_constants": 0, + "degree": 0, + "needs_selector": true, + "is_lookup": false + } + } + } + } + } + } + } + }, + "fri_lde_factor": 32, + "cap_size": 16 + }, + "setup_merkle_tree_cap": [ + [ + 13748092900677045295, + 3304937540712751392, + 17770014597022564786, + 8941553450891961516 + ], + [ + 16012382533100988059, + 13296747545665609293, + 13183006057148756019, + 14791960656774580406 + ], + [ + 13551593519766611768, + 16680728936190350388, + 12845305479227498665, + 15319706439229567608 + ], + [ + 15692210238147262631, + 8155754670667424858, + 18000000734474662330, + 17873985308936114266 + ], + [ + 8773299533272066415, + 618056006972512639, + 10812793409117747974, + 9699218397379972504 + ], + [ + 12100347971467866361, + 16498988728852997378, + 17168519803346613181, + 9550597251397146084 + ], + [ + 13708504650457046317, + 4556629385630317976, + 10890552695084643027, + 751973090722244119 + ], + [ + 2618200053994912586, + 5553359594045410479, + 8665774343709586092, + 5371601150438989999 + ], + [ + 8256937042925751396, + 12005382499131151909, + 16402127292673103641, + 3909594889774570223 + ], + [ + 7734138424224996735, + 14802907940393582464, + 10356284901312497963, + 7485357477811032014 + ], + [ + 105143795154493361, + 11885134707777836196, + 15392171034915508665, + 6082794126562486690 + ], + [ + 5003354491540383701, + 13683784187211301653, + 17984027875057263661, + 8038915685404055933 + ], + [ + 1036948013802763413, + 12728876074671929870, + 15367249685469192318, + 5247518745296759079 + ], + [ + 5526453449892376516, + 13133365049153482902, + 4460841556559949045, + 7358105471963817384 + ], + [ + 2112371792704066037, + 11183910920576082728, + 12800985758824309810, + 4727801367543225692 + ], + [ + 558519072415405473, + 17785546603565868082, + 14234221687085123626, + 508567827146650600 + ] + ] + } +} \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_vk_2.json b/crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_vk_2.json new file mode 100644 index 0000000..ac8d670 --- /dev/null +++ b/crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_vk_2.json @@ -0,0 +1,275 @@ +{ + "CompressionMode2Circuit": { + "fixed_parameters": { + "parameters": { + "num_columns_under_copy_permutation": 56, + "num_witness_columns": 74, + "num_constant_columns": 4, + "max_allowed_constraint_degree": 8 + }, + "lookup_parameters": "NoLookup", + "domain_size": 8192, + "total_tables_len": 0, + "public_inputs_locations": [ + [ + 0, + 6733 + ], + [ + 1, + 6733 + ], + [ + 2, + 6733 + ], + [ + 3, + 6733 + ] + ], + "extra_constant_polys_for_selectors": 4, + "table_ids_column_idxes": [], + "quotient_degree": 8, + "selectors_placement": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 2, + "num_constants": 0, + "degree": 7, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "Fork": { + "left": { + "Fork": { + "left": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 5, + "num_constants": 4, + "degree": 3, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "Fork": { + "left": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 1, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 6, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + } + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 3, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 7, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + } + } + } + } + } + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 10, + "num_constants": 4, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 8, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 9, + "num_constants": 0, + "degree": 0, + "needs_selector": true, + "is_lookup": false + } + } + } + } + } + } + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 4, + "num_constants": 2, + "degree": 3, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 0, + "num_constants": 4, + "degree": 1, + "needs_selector": true, + "is_lookup": false + } + } + } + } + } + } + } + }, + "fri_lde_factor": 512, + "cap_size": 16 + }, + "setup_merkle_tree_cap": [ + [ + 15542520360241997572, + 14194235504285137085, + 1816122538887256221, + 17663666902630103113 + ], + [ + 7119975388622383653, + 9319293034541771156, + 13970994676105013016, + 11008693825949590952 + ], + [ + 9869864942797268555, + 10071689139836437277, + 12598187184309650881, + 16955378773636846033 + ], + [ + 5770053548528607393, + 7266263007533304628, + 3900930112807349457, + 2402852371789653948 + ], + [ + 8627404190091264469, + 3909729121499264467, + 6835003366980085274, + 11742130192353516180 + ], + [ + 617721345777820139, + 3303509876327864452, + 11233810784426854458, + 14020562168899154098 + ], + [ + 15474902381218856188, + 9018602835220007728, + 4890329696264190295, + 10328377924767712378 + ], + [ + 1700820264998509220, + 7456658218462470885, + 6964195618569300729, + 16952483304769268017 + ], + [ + 16974341591093295554, + 12579329345978574383, + 5203428524465555363, + 6533513253290217010 + ], + [ + 13567582902689225641, + 6612546165625421167, + 1994184532494906004, + 15899030985349465173 + ], + [ + 3054644811656046386, + 10814140721783212413, + 12868982504928899774, + 11622979673493351581 + ], + [ + 11346042677121321508, + 11741901329133268374, + 13218412032858988588, + 4276916475834613120 + ], + [ + 227491112545332560, + 10948955472095241299, + 17789870312199899600, + 9785914168643463422 + ], + [ + 13716447631954177033, + 16934607649575335463, + 7060987241700849693, + 5583515768733729861 + ], + [ + 10743187047878044733, + 8276211677128783137, + 9306467505230024600, + 4246779791859817893 + ], + [ + 8510441393103109776, + 10795535044370891136, + 1933666971703730962, + 300378100816969630 + ] + ] + } +} \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_vk_3.json b/crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_vk_3.json new file mode 100644 index 0000000..65372bf --- /dev/null +++ b/crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_vk_3.json @@ -0,0 +1,275 @@ +{ + "CompressionMode3Circuit": { + "fixed_parameters": { + "parameters": { + "num_columns_under_copy_permutation": 68, + "num_witness_columns": 62, + "num_constant_columns": 4, + "max_allowed_constraint_degree": 8 + }, + "lookup_parameters": "NoLookup", + "domain_size": 4096, + "total_tables_len": 0, + "public_inputs_locations": [ + [ + 0, + 3921 + ], + [ + 1, + 3921 + ], + [ + 2, + 3921 + ], + [ + 3, + 3921 + ] + ], + "extra_constant_polys_for_selectors": 4, + "table_ids_column_idxes": [], + "quotient_degree": 8, + "selectors_placement": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 2, + "num_constants": 0, + "degree": 7, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "Fork": { + "left": { + "Fork": { + "left": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 5, + "num_constants": 4, + "degree": 3, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "Fork": { + "left": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 1, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 6, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + } + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 3, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 7, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + } + } + } + } + } + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 10, + "num_constants": 4, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 8, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 9, + "num_constants": 0, + "degree": 0, + "needs_selector": true, + "is_lookup": false + } + } + } + } + } + } + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 4, + "num_constants": 2, + "degree": 3, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 0, + "num_constants": 4, + "degree": 1, + "needs_selector": true, + "is_lookup": false + } + } + } + } + } + } + } + }, + "fri_lde_factor": 1024, + "cap_size": 16 + }, + "setup_merkle_tree_cap": [ + [ + 2303085045719213964, + 10359109466320448011, + 1505324500580255903, + 17237201041830174250 + ], + [ + 9106275786289379831, + 17518899748608409500, + 10006184568128201798, + 11256426736830669723 + ], + [ + 3359923124209044999, + 4585190269263512770, + 18165397816897694593, + 14906903257334732591 + ], + [ + 3245631184074956146, + 16119541634689042545, + 12304697032643499500, + 12946804318320172675 + ], + [ + 1758408664891180962, + 3288581841041917184, + 11720531990301953000, + 16341272918688254563 + ], + [ + 7704152322574770862, + 12186071412601763159, + 16782181569480350833, + 2356958967923436148 + ], + [ + 17671049276227598999, + 2518189125908896765, + 16619905459525208762, + 17812753285205728285 + ], + [ + 11251048513404253950, + 9350114763525857011, + 12829221041838533851, + 14026263498091546754 + ], + [ + 7357340712234584953, + 9846069350821844848, + 10854001497410494013, + 14347292043697828778 + ], + [ + 9471338781749903485, + 11960743223353403856, + 8799922156469032111, + 11517515837174065401 + ], + [ + 3892635938603472650, + 7163170625131474424, + 6379414432299756925, + 7362925813399880968 + ], + [ + 17912522346430578324, + 9643590363665191090, + 8366544752186699179, + 7200443900726523823 + ], + [ + 11948992936236935733, + 1727246336559082254, + 13950225072945655860, + 6105949390216036959 + ], + [ + 937450383527088392, + 10274527579548208837, + 18061600944125534086, + 17612384215539416718 + ], + [ + 1557537847065862802, + 14624474479106484260, + 17783029463771022153, + 11268483073065398803 + ], + [ + 14887016863832753543, + 4807647668380474215, + 16372757023820898339, + 17321092213662583635 + ] + ] + } +} \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_vk_4.json b/crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_vk_4.json new file mode 100644 index 0000000..93539bd --- /dev/null +++ b/crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/aux_layer/compression_vk_4.json @@ -0,0 +1,1741 @@ +{ + "CompressionMode4Circuit": { + "fixed_parameters": { + "parameters": { + "num_columns_under_copy_permutation": 48, + "num_witness_columns": 0, + "num_constant_columns": 4, + "max_allowed_constraint_degree": 8 + }, + "lookup_parameters": "NoLookup", + "domain_size": 32768, + "total_tables_len": 0, + "public_inputs_locations": [ + [ + 0, + 31025 + ], + [ + 1, + 31025 + ], + [ + 2, + 31025 + ], + [ + 3, + 31025 + ] + ], + "extra_constant_polys_for_selectors": 4, + "table_ids_column_idxes": [], + "quotient_degree": 8, + "selectors_placement": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 4, + "num_constants": 1, + "degree": 7, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "Fork": { + "left": { + "Fork": { + "left": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 7, + "num_constants": 4, + "degree": 3, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "Fork": { + "left": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 1, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 8, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + } + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 5, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 9, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + } + } + } + } + } + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 12, + "num_constants": 4, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "Fork": { + "left": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 10, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 3, + "num_constants": 0, + "degree": 1, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 11, + "num_constants": 0, + "degree": 0, + "needs_selector": true, + "is_lookup": false + } + } + } + } + } + }, + "right": { + "GateOnly": { + "gate_idx": 2, + "num_constants": 0, + "degree": 1, + "needs_selector": true, + "is_lookup": false + } + } + } + } + } + } + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 6, + "num_constants": 2, + "degree": 3, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 0, + "num_constants": 4, + "degree": 1, + "needs_selector": true, + "is_lookup": false + } + } + } + } + } + } + } + }, + "fri_lde_factor": 2048, + "cap_size": 256 + }, + "setup_merkle_tree_cap": [ + [ + 6661088035983077081, + 4779071769782445041, + 14878742466038470773, + 11856126940898714991 + ], + [ + 2089693999536240910, + 1916595073662785087, + 9146083583648130615, + 346844827117978263 + ], + [ + 7636917145318031662, + 4766717491236752422, + 6269632827516285472, + 40631533926337499 + ], + [ + 16981866899864792322, + 17573972650801784009, + 13126964870708738300, + 7264636164046613385 + ], + [ + 7666656852501666855, + 14490771513393374109, + 11623790893444245049, + 15650780431092765210 + ], + [ + 15527533253500077915, + 8531345626009274803, + 16063526070205710655, + 10097607635666350279 + ], + [ + 11367775254149583869, + 15749187367376381645, + 1196761583363411191, + 3030606203837774680 + ], + [ + 7489699068837895328, + 3971693631554778270, + 1259851816306224734, + 6711500817731864338 + ], + [ + 9412933099895446650, + 16202460964405802634, + 18045248319097312352, + 4724039411904285100 + ], + [ + 1302764759988213047, + 3011356040529787485, + 3997724694707369692, + 61889389014605315 + ], + [ + 10190310051667539674, + 4979982907133498111, + 13483159953260757819, + 14860066230859692223 + ], + [ + 18237894871367876288, + 14231753685285067978, + 18183463348777426441, + 11511488405061954809 + ], + [ + 13331248803403027177, + 3082228949639260555, + 3252276565158896186, + 184153720824478610 + ], + [ + 6863075327100289851, + 7522496371738739906, + 12137910313724857273, + 17111848870056424418 + ], + [ + 5254711401318665523, + 13382572366028911539, + 3165813361617021706, + 3072083978007151450 + ], + [ + 16976909255343070759, + 9558442768804927733, + 3668642074439036360, + 2171662038976355709 + ], + [ + 17500121582614113428, + 14497062791488027319, + 14945549651955895521, + 7862532750917067311 + ], + [ + 7865311582300365806, + 12123941452240167989, + 8751378880523810290, + 17536564007594614047 + ], + [ + 5482660744352171555, + 9901386844961060334, + 5212812281852622822, + 16303855614597814626 + ], + [ + 7608936298866675318, + 5303795391672936381, + 13238431382124758738, + 4700444176757711273 + ], + [ + 12856674572475441341, + 11044475327032685501, + 6195368892774454682, + 3104665861652751325 + ], + [ + 13237062942423138373, + 16950161131054702039, + 18330781814765007187, + 9762875822135440963 + ], + [ + 13331031141769970159, + 16386913990945864964, + 14750231074493142257, + 1895412176447157314 + ], + [ + 6748773479148163160, + 18356039693803988679, + 7403982618631957849, + 4369759304108998504 + ], + [ + 10170039605944985286, + 13111349010120400383, + 5452029975875464695, + 2817992403823457483 + ], + [ + 2945643583775382083, + 3106254006031200801, + 12441177236659379497, + 17367870022111163551 + ], + [ + 3986387267141138671, + 12173324426937025284, + 14233271068483058786, + 3969962386787584440 + ], + [ + 1130114965325949186, + 287454577318321793, + 13820711396518349005, + 12625169185969065817 + ], + [ + 16527202005244727671, + 5213901106950264033, + 3603006237911433854, + 7502547826401099576 + ], + [ + 17258962051529538487, + 11108567353272856562, + 10633209977383018305, + 10278372760127874647 + ], + [ + 13280058899972332486, + 13515743097095059459, + 1479844689264582662, + 4820428283671746143 + ], + [ + 11303053291110365125, + 11164095934984936005, + 7006196861625735145, + 5589213605365154539 + ], + [ + 182165641277037239, + 217334094945715215, + 2500470811661456676, + 1538949841935875313 + ], + [ + 11718028501596149538, + 16710232786075799062, + 13244334552902308407, + 250759206246700214 + ], + [ + 3154547230019906468, + 5651993888995748384, + 8784863853196356519, + 5356207127989436381 + ], + [ + 2851769594752723187, + 1627682906419525576, + 4616162992431330423, + 5417915672266112364 + ], + [ + 448018375062548000, + 5152492298290729518, + 1960638229166950903, + 12821103447993695561 + ], + [ + 1783508151801145176, + 9783566362321377251, + 16130967550671669819, + 6305051109891035372 + ], + [ + 12763821128316300852, + 16513250943491029781, + 14929897104604849305, + 10651055241175498928 + ], + [ + 6962357575817414659, + 13184329273014767068, + 8058223319083312020, + 12487635122919572790 + ], + [ + 5186523998638248465, + 8164100303693663975, + 8893894875346487518, + 6118720741732562188 + ], + [ + 12005251565914948295, + 3302211779000703303, + 8121475233217219332, + 13382111677228404809 + ], + [ + 7277011709825124180, + 3905429796824226452, + 16353948222275942034, + 2229134948666182703 + ], + [ + 17916011784004336223, + 1083223882458057181, + 6538431539839615960, + 12568421027023101060 + ], + [ + 16254334167080029384, + 15178671819044524673, + 4134354325778013951, + 8855571007240229107 + ], + [ + 13813502197972581060, + 8599735351961088146, + 9523150624440050929, + 13939401161558224120 + ], + [ + 6649316827421448092, + 11259811252065962588, + 18427386402166940253, + 1552624789555448893 + ], + [ + 5705925251891185810, + 17499554815485473784, + 7848278436702742942, + 3812430589139850106 + ], + [ + 3682039137440155404, + 15236837510314943045, + 13923579520532987978, + 5140353407739637386 + ], + [ + 5372196795727018043, + 1664266050526165932, + 9690560527651493545, + 13500887804166655350 + ], + [ + 15907737876055965319, + 8915585303679410982, + 16433621235993310860, + 11983961815006824407 + ], + [ + 18352782110327475773, + 7699828934865298408, + 5888023589787827849, + 14321615216783269673 + ], + [ + 10593232520135892276, + 4932344782717006853, + 13829902511675094192, + 7583902003471527528 + ], + [ + 5008298816286042314, + 16113423152983976114, + 6015149661386973552, + 16539183306984599514 + ], + [ + 15010483224291801746, + 9011780937376255710, + 10010676028520590781, + 8399640504834755143 + ], + [ + 10045960669953125011, + 6552953852228107377, + 9819525414193039175, + 14659633308470709193 + ], + [ + 8345218647661054640, + 9701935043174500919, + 3917217309434511278, + 5434996050798337303 + ], + [ + 5953896885302893122, + 11931292674898705091, + 10196753012578918465, + 2043524162504738125 + ], + [ + 5679547830781426372, + 17201949482892518127, + 6024803188379212594, + 17406889325828634911 + ], + [ + 8384460544137235270, + 15628048783482805, + 15399534684155658781, + 4206057848679904743 + ], + [ + 16793454613594221976, + 2643555416032389114, + 15938756381766599574, + 12426186158218055448 + ], + [ + 12479526538631257951, + 10351476301056754940, + 6071736399686208588, + 9154238597539688688 + ], + [ + 3902936043078450930, + 5839967288628214385, + 11331070567878822719, + 11964971775676453429 + ], + [ + 2714819063806916384, + 3530765711056811050, + 12310576862004415054, + 3190259747629200793 + ], + [ + 14313855511578936190, + 11987560066285802815, + 13431824607339250726, + 8323762503528742045 + ], + [ + 17631259292455752322, + 4083444272640990703, + 2729395215676168286, + 5139152594167179488 + ], + [ + 10484543285845518570, + 15139464189636145612, + 6743933365716848873, + 12337293750687814822 + ], + [ + 17850012580036659214, + 7657508067563248244, + 7772254010886831132, + 3032252403978600945 + ], + [ + 9163867593650533394, + 15962792498883015501, + 12516780810181113888, + 5717790209861404179 + ], + [ + 17866721860521313191, + 11434127521408096376, + 4781115983604228012, + 14643874429841326276 + ], + [ + 3339347210816622894, + 6171598006043714938, + 16533306653492206752, + 14634529927452226671 + ], + [ + 15024533473716105899, + 6374486960661834824, + 4384198806722960774, + 801776976666073324 + ], + [ + 3921748565396873777, + 1669058323437228032, + 15687177345565957359, + 12781551666055478828 + ], + [ + 18322924385541407973, + 6195064743022338937, + 8121649049773069527, + 13676858937363725666 + ], + [ + 13507914081378686411, + 6900398006911419267, + 13764685107231640511, + 5093947607231195671 + ], + [ + 10027066534835023539, + 7816102433700391118, + 1447106822505925335, + 17342685342643041756 + ], + [ + 16614341996552593700, + 10386048144926657103, + 16475113042384058511, + 6695682260248346505 + ], + [ + 4922285967792745247, + 3162695127354640438, + 18046699099400491941, + 11588825880330685249 + ], + [ + 14507861798528156405, + 8123110172312122160, + 6480714258852193674, + 14964554674686488013 + ], + [ + 3380304098215289333, + 5268565951082933404, + 3866788585106370788, + 6700836439528892278 + ], + [ + 8592580752339094146, + 10112772711521342918, + 15679284239891690967, + 8360638871313213757 + ], + [ + 16081956622907827465, + 8054933962935344643, + 9889893673786244422, + 17527132777965298015 + ], + [ + 15069990180304119167, + 9134021024111774067, + 56951029833065303, + 16163461191206250905 + ], + [ + 13130401034584002731, + 9832753437298789560, + 16723928696599708718, + 13054679277787365067 + ], + [ + 1380971957608365019, + 16708597074613152634, + 15837868327431246887, + 10630960386456142182 + ], + [ + 2991905675844956101, + 14972119660453677842, + 11178104265093495221, + 17439562788438655788 + ], + [ + 18112440562064996417, + 1486205175648317954, + 7944594712575336997, + 2159370588553136279 + ], + [ + 7300869746360323630, + 3807450634524591565, + 6130550778399734526, + 7321456514349777996 + ], + [ + 15698694083854861245, + 10385913391962068494, + 10692240103594062019, + 4143492931095635261 + ], + [ + 3659365952458273800, + 7731837116277062118, + 7178548680450714212, + 12882889866210050716 + ], + [ + 7906824979850143535, + 3813976272171304721, + 15503136250289447978, + 16768318058447844681 + ], + [ + 184982615094063201, + 16842485881080581664, + 11207091084589206344, + 8083706224031808574 + ], + [ + 4961650270592021641, + 5924165413665717214, + 18411966147841315542, + 12810132532886417754 + ], + [ + 11979475549383183233, + 12587121705538223989, + 9303636125703923880, + 14282941262572335536 + ], + [ + 16764182265543790240, + 4312294069730069565, + 10427409725049754976, + 11939609767118409558 + ], + [ + 16635080382884558963, + 4691526645475218126, + 3003646692791700628, + 3971052806962196861 + ], + [ + 3032811397725598058, + 9228943088070295526, + 17073387781211740223, + 11761928551820707729 + ], + [ + 12922995253897638252, + 13680438378506297669, + 4933966182486100383, + 14242891564194875707 + ], + [ + 3904466848682000557, + 6859388284008915897, + 9051076183455942199, + 15048104390672335130 + ], + [ + 11555628047554291201, + 2270169395077194149, + 9918321260566861416, + 6063821562294244243 + ], + [ + 4761820368422238397, + 2177446048350732042, + 958435507161836179, + 9030413030993388477 + ], + [ + 16428805835772169491, + 4150913395384653831, + 2992097858400877054, + 5276010644222180766 + ], + [ + 116309604989779771, + 18308897409673059560, + 4951577239630686620, + 7025975288840812174 + ], + [ + 6744647499989670897, + 15641976030088723126, + 5261558548902925824, + 14824700523221526006 + ], + [ + 12437761984664383151, + 14215007728038555696, + 402728279824874946, + 3127901637386690987 + ], + [ + 3942733024258949626, + 11681436768987648993, + 15029488185422020251, + 5459255400391694801 + ], + [ + 2584896396867214329, + 5166959654511029052, + 16414371474357440306, + 6767824229668362897 + ], + [ + 10926020494032840624, + 15105704961289405586, + 11535858859542172708, + 3773342432191839787 + ], + [ + 13844907264078348913, + 5714111719503083816, + 15187431414487538238, + 14583432737512906928 + ], + [ + 17948750975931336672, + 14755358584720551182, + 8151034320178323289, + 12712744407841163269 + ], + [ + 8109712749996838347, + 8618515713857551314, + 2060521934032109154, + 17509613903567645811 + ], + [ + 17335424908207204726, + 1842586460640180798, + 13419021583504707865, + 140676449234539182 + ], + [ + 9059850527957172419, + 9826517500072350607, + 8484476566733034983, + 4937484134132043951 + ], + [ + 17075234239375275026, + 151091203690980333, + 13838472936981038136, + 87538733859422003 + ], + [ + 1508041636071736745, + 743430603741903246, + 17533809650178753026, + 1485560287784381952 + ], + [ + 18362588404944360534, + 14902096413298146866, + 11295770646204264239, + 1015301356210954272 + ], + [ + 10199439488293180253, + 2364563455388825268, + 3998540681335505314, + 14208234994295721025 + ], + [ + 10098973995803552114, + 6419295088780860487, + 9166012564202115548, + 3962928360406170346 + ], + [ + 17903075279940998932, + 12782294818055564541, + 6367592695439617274, + 17966213175268216385 + ], + [ + 8829073841312765698, + 4265312650624099407, + 8082284629818530082, + 17162733676260432047 + ], + [ + 11887440124922179258, + 15454429838331979960, + 737156850724650130, + 5204979596136681169 + ], + [ + 3457833408166531180, + 17283068535245570562, + 2746622786107423066, + 2602717639127154717 + ], + [ + 11070100104320229536, + 6683638611883083687, + 13166570375299729850, + 10010310725909904537 + ], + [ + 13224933915592907129, + 9268507843873907183, + 14316169554524861684, + 3337754905960089640 + ], + [ + 15854381477534717290, + 6674129811300873317, + 14192808203928468421, + 5651746545869791171 + ], + [ + 483598332369754907, + 11467851499515701802, + 9231704363079874103, + 3166150044254538085 + ], + [ + 6541862768830587994, + 2974976051653030841, + 17116085913583764834, + 2797870286641245429 + ], + [ + 9464737552786481642, + 2365138741393777823, + 16638846861626525080, + 798463813320334434 + ], + [ + 9964277801040402854, + 8209764201170295743, + 530245579937456802, + 16864498465624065585 + ], + [ + 7756708721595676945, + 18296340996451234980, + 6357856134443409769, + 13307299449011773674 + ], + [ + 9862334694992530693, + 907713131744336602, + 11520723897477829462, + 12431189645588650652 + ], + [ + 13457590051988181527, + 14454488873068719245, + 4126720379380466981, + 3339414406818534721 + ], + [ + 14327880192123007756, + 4158386514406235375, + 7802064990472326135, + 12470510172099162819 + ], + [ + 13685783324328748364, + 2707991278883454649, + 9315332694826677115, + 16007489613988639519 + ], + [ + 9937009483000563113, + 14517976863979221971, + 5676551989203928375, + 11043313397154392680 + ], + [ + 9885491388174250284, + 7302701562227311593, + 11152350707258705730, + 11034265052900739761 + ], + [ + 17826015157851191416, + 7243371482241033590, + 5854522017655973628, + 1762698904663839463 + ], + [ + 8724684019294626623, + 14567202278397959497, + 7751164585242708340, + 2297825959941156240 + ], + [ + 3003122781521764787, + 17376156166973732483, + 17842527454564994899, + 7999550240932530672 + ], + [ + 3696274591942441978, + 16523939119161923726, + 7368929485549825786, + 6245874292326924464 + ], + [ + 15442488201932425286, + 12372528603263463535, + 2398124344651602005, + 916449987978614209 + ], + [ + 12848915405352193342, + 13830041404622965444, + 10643943267275022010, + 14704584498800592378 + ], + [ + 14107050554954521789, + 11336336080374035050, + 12805815845515331690, + 14692987401243197171 + ], + [ + 4255353961304675365, + 3847842909363515928, + 6635790454216676939, + 12318945627744599934 + ], + [ + 4712051643616223038, + 12136307941794433948, + 180126245665447228, + 4472897004057242439 + ], + [ + 8468680552288201737, + 6929629561954561251, + 13440030446847273098, + 9827948673091057206 + ], + [ + 14253723911333691533, + 17487651160064583630, + 4695710223294203574, + 7800676490974099104 + ], + [ + 8814018554568868114, + 15355062800841399519, + 6506141170710045471, + 1479516190083807189 + ], + [ + 5897973770742905936, + 15080800613069469400, + 4634085023827156536, + 14097723330360140085 + ], + [ + 1978239849096328367, + 16761479859331216688, + 475715228792815867, + 782624200487472036 + ], + [ + 5160479858034253217, + 3996895915776535396, + 17819076545507779436, + 10310316036920549452 + ], + [ + 18052325734557512729, + 6994739616934853120, + 12769310994509501773, + 10128024839943693413 + ], + [ + 944788984473525885, + 7977294141450180016, + 12090589799470685712, + 5959253867469491589 + ], + [ + 13914204225528482691, + 17757082915624065491, + 8381390704811882003, + 17213729551912788407 + ], + [ + 1044817203878915697, + 8027765981713212702, + 15839999549977413573, + 8101590670670086355 + ], + [ + 6605511150964516497, + 15034414851722338239, + 1955131577749304926, + 11720788313574826257 + ], + [ + 2642177241172471636, + 252426781939887763, + 15664489700034816353, + 1429017833218242343 + ], + [ + 16665445518622160639, + 8948644044231816633, + 16965349515741958408, + 18118288889311614306 + ], + [ + 10421894364284754919, + 17565084229771192378, + 10593850584693107534, + 8430431654963682073 + ], + [ + 7593950814222687725, + 16466821766403143648, + 11500792495407244617, + 14485952249525894053 + ], + [ + 11550118833679917978, + 12812905230083094569, + 3511929543291847908, + 15048319182266783134 + ], + [ + 1751649565039173928, + 14286735672255077282, + 12007107129781953186, + 10827328711362917992 + ], + [ + 17656064863506766464, + 1405148113532221560, + 4870311434392668725, + 14998183274403357198 + ], + [ + 4577686065727953886, + 14277577235835676394, + 751056234879128119, + 7549941536932313096 + ], + [ + 1322321317083149405, + 12548819549401440834, + 14268859093230168562, + 6529192220648780905 + ], + [ + 8367458802757277936, + 15838049591599068145, + 9825238058061491928, + 15548744372658937077 + ], + [ + 3163541468526194010, + 11939567680036074096, + 12689583347307674704, + 10000253782400148335 + ], + [ + 17352207122846103404, + 7553719261455929482, + 15332516677868745716, + 14114536656620325832 + ], + [ + 6507953225395371914, + 12452830182805696192, + 13234786280362108307, + 14265729041883832126 + ], + [ + 6143086333016050895, + 992788521784801468, + 5262440138094333538, + 18347347087030176688 + ], + [ + 9237187409083294193, + 586729767804794161, + 9331611255708184157, + 6013949944059446939 + ], + [ + 10390895282905324775, + 2759409020725357260, + 7974121716016946156, + 5828932063913974827 + ], + [ + 6806724186457892673, + 8270074742091601226, + 6844563714968067565, + 14533876013650992223 + ], + [ + 17981338158146823916, + 2934425229045676645, + 5805298340135767495, + 18095523765988837569 + ], + [ + 3524215691167532316, + 16220954869007450580, + 1979400389857032967, + 11708426950194495142 + ], + [ + 5105667331760983131, + 4379545736784952195, + 2024545271228731707, + 631620383687055 + ], + [ + 17507030423806385341, + 17670241027355440730, + 15541568295144509727, + 14697785193678797731 + ], + [ + 1755292827197992510, + 14744657901269199725, + 13848819604283869308, + 3663285010133269824 + ], + [ + 11916535179430966187, + 13947374919471482779, + 1659302754666761372, + 2190858779697159038 + ], + [ + 16760320977779704391, + 14223488170199975977, + 14387934639647870614, + 9474585386079666517 + ], + [ + 8166618695901200106, + 12519070635137625184, + 15453129469562476040, + 4738367673598114401 + ], + [ + 6175485261537949777, + 16478499667876790212, + 10125905921359793948, + 18406870719315205828 + ], + [ + 10334076687307689742, + 2261823256154188396, + 9887712041083404277, + 2685752150468443786 + ], + [ + 5827858307832680108, + 17307477162642117309, + 1822899557725014588, + 15520082800827401435 + ], + [ + 5484204086852887449, + 3099161126555390674, + 11148796993326955564, + 5018820169775862990 + ], + [ + 817971063831885672, + 3123594883093429558, + 15061576397097474252, + 17810140747204321129 + ], + [ + 16491375258704007958, + 1559843032579989313, + 5827889363393792834, + 9572746157115019558 + ], + [ + 18020320853327053392, + 9288273606334203972, + 13678129169524175818, + 154064227873770900 + ], + [ + 14896197086154328782, + 9080157856754744360, + 9772251463643306653, + 382192208444524380 + ], + [ + 154975660848179748, + 11456386886355964989, + 8855376259011175128, + 3515771804098899828 + ], + [ + 14011391936130697733, + 18335941125580591371, + 12463637291311485580, + 13324586146449118697 + ], + [ + 15131993779456318774, + 10791750152291657408, + 11899353550676904557, + 11595780770196243082 + ], + [ + 2111829721833550914, + 3606045405586647488, + 13871449123252388382, + 13323562132134428837 + ], + [ + 7937091467134015192, + 9698606773628199127, + 12632668457048463154, + 10687451357969318167 + ], + [ + 13898975737873037397, + 1295116331136205939, + 4929572996204127746, + 15622377566631723905 + ], + [ + 4718099668369618130, + 8589476145210207608, + 11653827138699831424, + 3288474533809560522 + ], + [ + 8293933241927408248, + 6686922849072154042, + 10610129659292578321, + 5276845732881358879 + ], + [ + 5042499544248786378, + 17679221294420487599, + 12835593401829867491, + 530055997386620161 + ], + [ + 6806219120787073420, + 16620937451053657064, + 8107798583421809054, + 12107960753431244872 + ], + [ + 18080854377107445156, + 9494953279734785928, + 15325893752593942241, + 17882227543195336767 + ], + [ + 15022595764257350533, + 11762329905229703189, + 10641547888672493945, + 17898269790565999870 + ], + [ + 12892451109917780167, + 13951184863016742, + 8992670774313521058, + 3563384819404216497 + ], + [ + 8237243945577158081, + 5747699809108735008, + 15173664564416075866, + 9461901208954527603 + ], + [ + 6913351909025592229, + 7887561366395271442, + 9746718901481130758, + 12551746975351529938 + ], + [ + 13988674515655776552, + 7558832118810092019, + 10815958260955393991, + 4861104111294677828 + ], + [ + 5215133247084141047, + 9910962516166245751, + 3329340789099844406, + 9854811867405360235 + ], + [ + 9369820724319242420, + 10921844405257001331, + 921027087300332621, + 18163731954657721977 + ], + [ + 17048892671580514631, + 2184418719038868781, + 16297297552191226871, + 16309565419845725293 + ], + [ + 12004652760313852388, + 527090214140303821, + 1556461581194401124, + 12577196274003592926 + ], + [ + 16608444124786343435, + 14551959088886448414, + 15088404183427080545, + 16481669656318193080 + ], + [ + 6388433196197487949, + 1388478747295139723, + 2851940523808948958, + 9356337776023610237 + ], + [ + 4087627132377467384, + 446885467759213647, + 7674704511317860933, + 9226641483212593544 + ], + [ + 7626855552963247220, + 13283565816647612539, + 7243830952723747095, + 6656510959238906030 + ], + [ + 14711312112856527688, + 10861161885236318398, + 18356250230689286316, + 4453105754561274621 + ], + [ + 6395870237086787620, + 5730123626838045604, + 4854353143608348351, + 12395703405986668968 + ], + [ + 13348462171879433138, + 15718911450786755814, + 3054316978121118213, + 8807587610897705900 + ], + [ + 935636849453653978, + 8367823294215195132, + 16643135178566511858, + 14508823921109669735 + ], + [ + 13201343182161448982, + 8234981656652184199, + 17268938270016299636, + 13365283797600830994 + ], + [ + 13732460821270851161, + 52506069455652279, + 6763463900368989383, + 4707455424753458748 + ], + [ + 8354840134196897389, + 4588020902671181258, + 10219596050133754739, + 5494992686880995232 + ], + [ + 16111845426598538079, + 17455341512695448842, + 7399964876732266846, + 3152564317867434435 + ], + [ + 4897599086809288165, + 5481183529376419729, + 12027048962821246305, + 6162584631683445538 + ], + [ + 12396803850838104315, + 8836112149858865911, + 3242116506340504341, + 15068652394034429357 + ], + [ + 8013939138553607516, + 1761389560726858788, + 1055199877030494384, + 5707006469897487990 + ], + [ + 2008341515427177258, + 3129733552980805133, + 16620145015240691135, + 12493327354103576169 + ], + [ + 208608279858699389, + 4596553048958500781, + 3885743631762886384, + 14678765207815259873 + ], + [ + 2098873185023799686, + 14683108419070193285, + 15846773735508003391, + 3050393459408841721 + ], + [ + 13362422795947485879, + 1422598976548809200, + 7447263356384633081, + 5214049347734545182 + ], + [ + 9915350531213924971, + 7196413266034187702, + 9178399950963215404, + 15535268105953650912 + ], + [ + 1224760426050193982, + 2474712430640611307, + 13485122978168505078, + 7683376068017090018 + ], + [ + 15012414572701814303, + 8567676532388386691, + 6610113032980473712, + 6931709307294492828 + ], + [ + 14567066446442503467, + 10400087250888954026, + 2600100395465154074, + 736485002631289834 + ], + [ + 760605329034304275, + 11658445268335605341, + 7167428190025504886, + 17906710187572951029 + ], + [ + 18346725458037751594, + 13209295160261750450, + 17702810915054722286, + 8562536947052750480 + ], + [ + 7360826607476011504, + 1447403713108104343, + 17921426312095991630, + 1213235099715690814 + ], + [ + 17290727846669565774, + 15406633488564891899, + 15179582496330773362, + 2049231034756410392 + ], + [ + 16868111184706665549, + 12512231023381142128, + 3031263602217211274, + 8715728797133425859 + ], + [ + 3583337172309766215, + 13557822866512727426, + 11820334656183908658, + 5363481710163205994 + ], + [ + 4040019911702545328, + 5103802201376994001, + 9963711425261170886, + 10536750756641802903 + ], + [ + 17904672727465135360, + 905344053716873220, + 16943468264594440445, + 8118109047030631868 + ], + [ + 14435731337048950179, + 10671801053517607513, + 1611523078091398828, + 5605433201210521776 + ], + [ + 5508016895193416836, + 9030335658243061431, + 15369833667390020276, + 12095904499853948960 + ], + [ + 18157561083077989309, + 10107750265606796372, + 4057675934615359531, + 1174424602265081118 + ], + [ + 5968638488818854680, + 1774928788223396202, + 8064568983517831681, + 2926309006812717935 + ], + [ + 9891127685956804487, + 1327498048639717782, + 4649949243043958130, + 6959875260427150374 + ], + [ + 7624256089428340049, + 12220165774665495582, + 17042673966310293814, + 18140311512336499576 + ], + [ + 13506611765680483074, + 827413620609919538, + 13701521165618023290, + 15882789625109238489 + ], + [ + 7151827133837169019, + 15592972959373546408, + 5797042625908654384, + 13556582377954480827 + ], + [ + 2577617000952929120, + 2546408520057218348, + 15362285547679399462, + 1925329616281458705 + ], + [ + 4035613530602751478, + 4815824802702684252, + 5947499812200422052, + 8307261097356254197 + ], + [ + 8409685494101467008, + 9087734950608419040, + 5065780300168124075, + 9933784968823031399 + ], + [ + 4145252066077182391, + 14495005153700459579, + 16384125995443252338, + 6009999323326716706 + ], + [ + 17754449171803634770, + 1848135718995058381, + 13545143645885641511, + 17579097657796665798 + ], + [ + 3004862488726834604, + 11291325036935494839, + 2740063487482033250, + 16347585191004582263 + ], + [ + 7517575525876322474, + 18076717933713601934, + 10841009248457817225, + 16991193842649283870 + ], + [ + 17597599913364962860, + 8304567729997988279, + 12395941274784035911, + 4133021281394020083 + ] + ] + } +} \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/recursion_layer/scheduler_proof.json b/crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/recursion_layer/scheduler_proof.json new file mode 100644 index 0000000..6710800 --- /dev/null +++ b/crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/recursion_layer/scheduler_proof.json @@ -0,0 +1 @@ +{"SchedulerCircuit":{"proof_config":{"fri_lde_factor":2,"merkle_tree_cap_size":16,"fri_folding_schedule":null,"security_level":100,"pow_bits":0},"public_inputs":[1961802424684827,44478075017541700,68433799240021256,10969447465159162],"witness_oracle_cap":[[3936774789042826465,18163964105456700886,919935410760335525,10955818595940331111],[15235889955170513760,11531297647681132535,2331930137019442001,13006761290277270613],[7277900302693487304,7661597161339540273,6357574785708027996,15865888488676582759],[13545136441087506598,3221743787047509545,188796548885687245,8976961847942998004],[9061648476651802348,7825518007650061461,8351576740564724764,9018945834793318096],[13206145713063013606,5483743810003731297,4327806714054397558,3708215061896342077],[12842346615942824748,18122092034329069550,2497241054730218789,16632514126127762697],[5435402064482897574,8679892100228109472,4472732843660498470,13328544083022601746],[6553279751969482252,8262860622613048638,3530246786769998060,859284678410375061],[16047566397098125565,3007113504899180423,12437050280547394848,2084495641299303274],[14935968874707909348,2295292176082830570,5100949214530293302,15151327531202219516],[6896332314317691704,17473746081354007997,17982184390898690888,14988751656629082540],[12387216106344129189,15241834663614004269,14904653997431750997,9548434405508697263],[3891018237794364182,6448999136201184934,5394081793886067923,18056863280143055276],[5928900468067357021,7807585162554809202,6342449936183215652,569217952772677429],[10600524579914530145,2445891550872390124,6899102900972134199,9024021135730888528]],"stage_2_oracle_cap":[[15556793643596897085,18093476028581475592,12019325712070615599,18237563743698779779],[5087649936410492325,17874401704795520106,13832056335121582127,10146512081244352227],[3457635026073464648,4282657053786163448,5755278988772207990,3142992197969991311],[5154899204244631659,11344033280710764411,208369218147940293,8519139549860374669],[4729536227908329676,2116784960409635665,15677170034064002265,18395964296458651018],[18120677177182352342,13188659706130001544,9248747626870342035,1360389155353177146],[8234399878376689134,750726205986815749,5783084401521578720,1630717045501531380],[13557370978610104794,3806509989362809589,7231918332865778092,14312221465923994201],[2645952990705020924,3356888385392686170,8447630465108903853,8490470241055996217],[2786578172970122690,12130887123545446497,728452860675047171,14574506587897923280],[13195551065099936623,6929528638394253566,17204771244895089158,14369779510937601116],[2842542636609084004,15587204628510239930,13276228578011405324,1265976923685561610],[8924398449957901130,14641400639941535235,2034136276116534117,3192156626938835950],[14547908407872563280,7867867615682492052,6136518335472031382,15262958332877101501],[5696032875030779016,17616661801745486238,12958992128622954597,1387871989754553411],[6061503559430297630,15936947788985579924,10446919849869787070,6586927857526245402]],"quotient_oracle_cap":[[11982400487976881934,11582382209016340730,16642644844187065987,11106469208498209081],[12106246273667556953,3406653896978343255,10616596887360416387,10005808230614823014],[13544142370668584249,9750097148162314838,422501040916320632,16537031580772414853],[9882765242096761638,17903826819244927455,548049240500317375,16492995616441872077],[17614971197987650525,13167492243946706333,11320689641308106947,2977660822263462994],[4106273856926796781,1105544184709414466,17848202651118970473,13073590376913696699],[15667991839947650985,7603683017951912602,13969698328538712364,7048624210986456192],[3510276087693345735,14636775881781448631,1121394970362538302,4340206314400607707],[16211399793900558670,17826322914636011976,7414908528034465276,2412101635491535615],[9201855876008061972,17499571778328551054,983651448892040516,4242454005413176315],[11171869139116938231,7925838664453840988,13233544629325254829,16921142417477519086],[6738738672006290728,13381136373609816439,5400020805099000028,82496007265064633],[13339404266737279186,4452542641240529368,18356927190930259321,13208578725892734465],[943071004068865140,17025171255606610216,9279138684609852262,15116670334591021187],[13054488710873960943,9669189123184294380,9671473956422480016,6765514936560127014],[7680185506724290802,2134617717801426524,18233658536171657474,11924605591280309647]],"final_fri_monomials":[[13855183530694186903,16181933741086911746,10008898886765012497,8123224062270405606,18241981562585403744,9383071563581843191,15453177997029954812,4364970461208066464],[12024188023878262970,15753505697036154725,17291086562224098978,15463177947096137261,7548593978800006261,7922846527518017233,5127787458303311769,11678966441521641526]],"values_at_z":[{"coeffs":[18194572502006662084,4697713181164581155],"_marker":null},{"coeffs":[17273655616054159061,18231665939568198839],"_marker":null},{"coeffs":[7931385543451067720,4442583633014848038],"_marker":null},{"coeffs":[449007282600217762,8617435626022452806],"_marker":null},{"coeffs":[4158799646141663269,14455435691754576585],"_marker":null},{"coeffs":[4050594436634527305,17113262397014555108],"_marker":null},{"coeffs":[6664240471158553163,10268860241582046642],"_marker":null},{"coeffs":[5978826126179339182,12548630896003807535],"_marker":null},{"coeffs":[17988555777937275172,745454658335485522],"_marker":null},{"coeffs":[16491040423889895762,5138976901402420224],"_marker":null},{"coeffs":[13764804027771978882,17830639616697616377],"_marker":null},{"coeffs":[11688690567695584039,13944368359473822050],"_marker":null},{"coeffs":[7557163469540847221,17821771340865187165],"_marker":null},{"coeffs":[3492097360270353077,13377337339503260101],"_marker":null},{"coeffs":[3727554979297786517,4620500517198127855],"_marker":null},{"coeffs":[1438224193789859377,8756529593956570416],"_marker":null},{"coeffs":[4969546626937845705,10867366853817853104],"_marker":null},{"coeffs":[6921246687801462020,6674803949201070512],"_marker":null},{"coeffs":[17894504025083199347,5353427723513661502],"_marker":null},{"coeffs":[7426914046936236165,4503914353923868372],"_marker":null},{"coeffs":[816780486822016510,4016406489741267470],"_marker":null},{"coeffs":[17449865079892529070,4439678170811639529],"_marker":null},{"coeffs":[7323077840812973155,6639936145700646932],"_marker":null},{"coeffs":[4604421824158784712,2205372795066569388],"_marker":null},{"coeffs":[6456457116170190864,11948686891689809881],"_marker":null},{"coeffs":[8692107600446879413,1489197549909741680],"_marker":null},{"coeffs":[5902446087623588395,5445474776714581547],"_marker":null},{"coeffs":[16057307761759667369,17069538820942301524],"_marker":null},{"coeffs":[1517693885082109292,2137672665135556498],"_marker":null},{"coeffs":[10676159354643780964,4463136379288412623],"_marker":null},{"coeffs":[3174266658106146818,1858665672981839078],"_marker":null},{"coeffs":[18030390445099944676,6253327879951182857],"_marker":null},{"coeffs":[5054517278417371268,7575059502227905933],"_marker":null},{"coeffs":[15342407126006051441,11110004714662473960],"_marker":null},{"coeffs":[14132450500127040695,13795318989209167698],"_marker":null},{"coeffs":[1446227842706880143,16677200395235145053],"_marker":null},{"coeffs":[8886581299267890475,4999006242404224071],"_marker":null},{"coeffs":[5634183216832617408,5881165029425241065],"_marker":null},{"coeffs":[14456045405861578930,1167103697033010239],"_marker":null},{"coeffs":[5423691795492347351,201243156573765911],"_marker":null},{"coeffs":[7556061064977858602,18175304886520992330],"_marker":null},{"coeffs":[3722078162574650250,12859892117430345869],"_marker":null},{"coeffs":[13362030077143704140,3410887973858254118],"_marker":null},{"coeffs":[3574432435976397540,17231796483428064176],"_marker":null},{"coeffs":[17762130663935363754,12858224605334818306],"_marker":null},{"coeffs":[1306264236486434854,10920750530263383168],"_marker":null},{"coeffs":[10790539523554432842,13346385683425573535],"_marker":null},{"coeffs":[1991650931862414513,17126299863091291748],"_marker":null},{"coeffs":[18400132621875682989,7942584274856899998],"_marker":null},{"coeffs":[50941531472284657,10425668499193681490],"_marker":null},{"coeffs":[5498271720829901456,8626461846640597167],"_marker":null},{"coeffs":[17501655625004682079,14283285108929211437],"_marker":null},{"coeffs":[7047348278282524989,9787040276915476285],"_marker":null},{"coeffs":[2761689937204152880,11110128601627401678],"_marker":null},{"coeffs":[10331868144878226698,4418703643744063954],"_marker":null},{"coeffs":[12545397205141785022,9359233960807442201],"_marker":null},{"coeffs":[7117978357210685926,8521506959339720148],"_marker":null},{"coeffs":[11334917751595984469,4004700865683059608],"_marker":null},{"coeffs":[8251520344359773740,7850323043788579383],"_marker":null},{"coeffs":[8911088508928514398,4224727547591726399],"_marker":null},{"coeffs":[10821824000250598639,7088759910924389818],"_marker":null},{"coeffs":[17332669095302772842,7071710368577184436],"_marker":null},{"coeffs":[9963905291642542765,9609341385764248394],"_marker":null},{"coeffs":[2760080977235346618,14525249053274842310],"_marker":null},{"coeffs":[12240461586799332629,4781909320436122576],"_marker":null},{"coeffs":[14442078351367398823,4235616952341575097],"_marker":null},{"coeffs":[27689839103299453,11111881953487884745],"_marker":null},{"coeffs":[18125582376073109006,1358802277353690099],"_marker":null},{"coeffs":[1999819998099163479,9935384450558022334],"_marker":null},{"coeffs":[9604314130040656248,11090150136451483505],"_marker":null},{"coeffs":[3988036829684301358,12160542002830096751],"_marker":null},{"coeffs":[16545883795896644809,4240730417323412011],"_marker":null},{"coeffs":[16248086652261461575,7610695289444717137],"_marker":null},{"coeffs":[9589895495256018487,4099202662600745726],"_marker":null},{"coeffs":[8123298796552268746,15493984769481632365],"_marker":null},{"coeffs":[2193548013695226612,8062492220879511806],"_marker":null},{"coeffs":[1504108015832207781,17837510988554833577],"_marker":null},{"coeffs":[16950807700658610277,14485975606066076028],"_marker":null},{"coeffs":[13256644180699772849,7823427704205354918],"_marker":null},{"coeffs":[15908207861313575559,12715288344063914814],"_marker":null},{"coeffs":[11929966199967993608,12427635255045780802],"_marker":null},{"coeffs":[13348833298114298322,11926874616774131507],"_marker":null},{"coeffs":[10875171737567225811,2464803214752190543],"_marker":null},{"coeffs":[2296175817474433655,7156087642175335343],"_marker":null},{"coeffs":[2756188629266080357,18207323925524069249],"_marker":null},{"coeffs":[1338663299862180104,2914591721254306238],"_marker":null},{"coeffs":[2917203039297618574,2700766702293575646],"_marker":null},{"coeffs":[16499163797707251885,14329011707613394281],"_marker":null},{"coeffs":[14626934304551518438,2073376864941204727],"_marker":null},{"coeffs":[6153258341449354587,11842607103047892056],"_marker":null},{"coeffs":[3060707855218968478,2470403765138986780],"_marker":null},{"coeffs":[3208131683951983535,4741299167666470248],"_marker":null},{"coeffs":[3318640912297134312,17362958841709107984],"_marker":null},{"coeffs":[407910056259027480,4811034889541302424],"_marker":null},{"coeffs":[17239953166238939204,10096399887644435027],"_marker":null},{"coeffs":[13844705438215810020,8259974066993637935],"_marker":null},{"coeffs":[2587392471793239581,10842645623854484871],"_marker":null},{"coeffs":[7704334598847956615,16455953869527622500],"_marker":null},{"coeffs":[6916690541428096173,10703359815566205481],"_marker":null},{"coeffs":[11205822204376025871,12294765708320983616],"_marker":null},{"coeffs":[5321348645753838036,4213533397527382803],"_marker":null},{"coeffs":[14376982335033044002,8875502362381900674],"_marker":null},{"coeffs":[10687818864418036039,14780628422225725400],"_marker":null},{"coeffs":[18327763888820227516,18334744594833360481],"_marker":null},{"coeffs":[5860993469046345046,14030148083340916361],"_marker":null},{"coeffs":[13987034174964699365,11178461096456435196],"_marker":null},{"coeffs":[12205332827238929451,31561349804689097],"_marker":null},{"coeffs":[973544409978430457,1732364240251190048],"_marker":null},{"coeffs":[8898874229317610202,12891785049902010512],"_marker":null},{"coeffs":[7819634541535974997,6578777593977500810],"_marker":null},{"coeffs":[5450335857479012434,11575050668835003483],"_marker":null},{"coeffs":[9363364326400790454,16123440589022542696],"_marker":null},{"coeffs":[358945245277113226,10199924193646955239],"_marker":null},{"coeffs":[15670418045115549523,15970967750709737945],"_marker":null},{"coeffs":[9346056165719129530,375293040897003902],"_marker":null},{"coeffs":[12599001811147269673,17838749624152647711],"_marker":null},{"coeffs":[6448440711384239453,16913421810445418179],"_marker":null},{"coeffs":[5753096033445119318,10374098014264839343],"_marker":null},{"coeffs":[6439315868070621910,8680215216906826470],"_marker":null},{"coeffs":[7030698638267946345,17269074106855555038],"_marker":null},{"coeffs":[2318130419142131685,1027684520688777961],"_marker":null},{"coeffs":[14868827795729628216,351075766328018544],"_marker":null},{"coeffs":[12013652816726088667,14563113841792885218],"_marker":null},{"coeffs":[13523586224469468310,6095907626504832926],"_marker":null},{"coeffs":[11454947636300117539,9399463467705443919],"_marker":null},{"coeffs":[83670557526251805,7551553265089216107],"_marker":null},{"coeffs":[10036964585099857540,10377435279103513294],"_marker":null},{"coeffs":[12849295211412166304,339242307147903951],"_marker":null},{"coeffs":[12241392872891351781,11859714754144612205],"_marker":null},{"coeffs":[2333903656232104906,9921740327191405990],"_marker":null},{"coeffs":[18045025735153771481,11949295753787804184],"_marker":null},{"coeffs":[881303790162039983,510557809586979024],"_marker":null},{"coeffs":[7739113175944339420,160778323894199703],"_marker":null},{"coeffs":[6575363856894751536,2040396741528171225],"_marker":null},{"coeffs":[205303373731351257,10108084080370239225],"_marker":null},{"coeffs":[16016581476914040142,8398284972520608995],"_marker":null},{"coeffs":[12858607521288375313,13968975305836931450],"_marker":null},{"coeffs":[13990400373927842350,14298164975381366306],"_marker":null},{"coeffs":[3617924236977134926,1808939832202779374],"_marker":null},{"coeffs":[1220646976456464440,12536817571850644199],"_marker":null},{"coeffs":[16840308767937484470,12038062537936375258],"_marker":null},{"coeffs":[1730708789208144050,15892633090079044629],"_marker":null},{"coeffs":[12064539946692647067,6453158740722468684],"_marker":null},{"coeffs":[1727963635788275718,4243773245132762504],"_marker":null},{"coeffs":[4760112522352930537,17569843585150723307],"_marker":null},{"coeffs":[8140879726642348061,17007451324025702209],"_marker":null},{"coeffs":[9821281075913264719,5060369990565837504],"_marker":null},{"coeffs":[1174687202429955650,17006126989886955859],"_marker":null},{"coeffs":[314985963463105634,4552264968555549434],"_marker":null},{"coeffs":[11336715955563454128,6820655033506221642],"_marker":null},{"coeffs":[11426261009514423785,9227684770543280230],"_marker":null},{"coeffs":[8708354828331456039,8503517039146318463],"_marker":null},{"coeffs":[756814402039131805,14689876537558618576],"_marker":null},{"coeffs":[6873919841618904502,2380248844220851957],"_marker":null},{"coeffs":[530581395227007548,381395802140758550],"_marker":null},{"coeffs":[2390594399596625528,3702555036492412311],"_marker":null},{"coeffs":[17846439590243688274,11815545791245284148],"_marker":null},{"coeffs":[14354243241147473612,16587711292878088412],"_marker":null},{"coeffs":[294185085689016489,1136000123418264768],"_marker":null},{"coeffs":[1986319142487451938,2832233580169004431],"_marker":null},{"coeffs":[14453469701816805693,574704726731182268],"_marker":null},{"coeffs":[13123819068597987212,6209909220167240818],"_marker":null},{"coeffs":[10085350327523848316,4218885055254728828],"_marker":null},{"coeffs":[3096347863818756393,180167898235615665],"_marker":null},{"coeffs":[7873984329587423595,2093286845409139517],"_marker":null},{"coeffs":[11049728143075352844,12364342926338643641],"_marker":null},{"coeffs":[9245868944530471769,17712083612323041371],"_marker":null},{"coeffs":[8056869394556812340,16762610620055953882],"_marker":null},{"coeffs":[10229241158272566560,13171064342467313850],"_marker":null},{"coeffs":[12029664543355227400,15577384996011189075],"_marker":null},{"coeffs":[11643330002960449041,6002624944366828169],"_marker":null},{"coeffs":[2401335179002240788,329630765236890725],"_marker":null},{"coeffs":[7154297917643831527,9982056586211342903],"_marker":null},{"coeffs":[7179918546866617549,710324560130200819],"_marker":null},{"coeffs":[10077409954594702159,148511537982125356],"_marker":null},{"coeffs":[8774664309676732931,2324841627411402571],"_marker":null},{"coeffs":[4511028724561318845,6160273597433521696],"_marker":null},{"coeffs":[4451251681573224490,4716387798783038397],"_marker":null},{"coeffs":[8351481846095241862,799467833631795607],"_marker":null},{"coeffs":[17453526914261301479,1769835751108096741],"_marker":null},{"coeffs":[15454911689539414097,2221917451808258626],"_marker":null},{"coeffs":[5527195818544043810,12399520475377093241],"_marker":null},{"coeffs":[8078015305894818893,5341966270360838760],"_marker":null},{"coeffs":[6729404833684879913,16296811316239727565],"_marker":null},{"coeffs":[10730598018764291496,2547127563636045905],"_marker":null},{"coeffs":[18322528777410846794,3201177795339012610],"_marker":null},{"coeffs":[18200844447481833025,1091006032006540043],"_marker":null},{"coeffs":[4921735243810477404,277961949854148619],"_marker":null},{"coeffs":[17654986272233913162,3643607450198771864],"_marker":null},{"coeffs":[3240986059024326815,15142107232094171558],"_marker":null},{"coeffs":[10646052287789123658,4905810327891380261],"_marker":null},{"coeffs":[18230610105720940804,5989859347077815459],"_marker":null},{"coeffs":[3838227891003015752,10232269317531439232],"_marker":null},{"coeffs":[2352906572415218760,14936031074704434738],"_marker":null},{"coeffs":[15171659923554450250,5929969993661447456],"_marker":null},{"coeffs":[13943307732791613005,5384062325079809655],"_marker":null},{"coeffs":[13152979273893505698,1806035460029631347],"_marker":null},{"coeffs":[53433664489878950,5437350260743547212],"_marker":null},{"coeffs":[15545238200499102246,11134722660613367119],"_marker":null},{"coeffs":[1205303313725447705,15431705294278685460],"_marker":null},{"coeffs":[6021933686055782603,1869005992075516003],"_marker":null},{"coeffs":[18311993318834253972,5939362577386194976],"_marker":null},{"coeffs":[11653911867771838786,1693383595182936052],"_marker":null},{"coeffs":[11312979505306510603,13981793865551040835],"_marker":null},{"coeffs":[9380674408920968493,8059717304913113650],"_marker":null},{"coeffs":[10440978420475675864,13716412008799174480],"_marker":null},{"coeffs":[2789772549461911585,11674044013318839896],"_marker":null},{"coeffs":[12116251728348549118,9637053119003505586],"_marker":null},{"coeffs":[15099699541441007575,13194437778218581054],"_marker":null},{"coeffs":[906528461816815045,7190999273578518453],"_marker":null},{"coeffs":[6057704999804896894,8916831875111282378],"_marker":null},{"coeffs":[10765965758799265376,5931671468955790376],"_marker":null},{"coeffs":[6141941770145628715,11926212677075344926],"_marker":null},{"coeffs":[17042320414071702403,10875586661718479981],"_marker":null},{"coeffs":[705606840944353207,1755659664106034233],"_marker":null},{"coeffs":[14104827295787640263,16225708228147322869],"_marker":null},{"coeffs":[4171085825257894931,8966883249011021011],"_marker":null},{"coeffs":[15767937104962239581,5019561555029072869],"_marker":null},{"coeffs":[6540503497834198115,10066440569391955844],"_marker":null},{"coeffs":[13989507644617577064,18233627126805686834],"_marker":null},{"coeffs":[2435729014696134847,14344810235022185846],"_marker":null},{"coeffs":[3467226268096623110,18303204313902415261],"_marker":null},{"coeffs":[5346933029009847550,12682188675534369507],"_marker":null},{"coeffs":[7447096582460219226,16551369901040010390],"_marker":null},{"coeffs":[15859792003628545115,5592549196261932898],"_marker":null},{"coeffs":[969944793830169150,8298783270846096856],"_marker":null},{"coeffs":[12937468885157799463,3837877185417429748],"_marker":null},{"coeffs":[16745720288509764092,12538588236124281459],"_marker":null},{"coeffs":[14303177882091460022,12620363906311461929],"_marker":null},{"coeffs":[4576432246112711480,6807595260044821323],"_marker":null},{"coeffs":[18408421198659195417,9290763232154228327],"_marker":null},{"coeffs":[6849157001817107432,9924274513088769044],"_marker":null},{"coeffs":[6121724510823206762,17276693388807798864],"_marker":null},{"coeffs":[14803944757990239961,6256798008372123238],"_marker":null},{"coeffs":[11598073476171594828,1408484445491792946],"_marker":null},{"coeffs":[7725516590146258551,14384166770820935712],"_marker":null},{"coeffs":[9250500222570461453,5699487578056174384],"_marker":null},{"coeffs":[4733686729303903907,2794713501318820369],"_marker":null},{"coeffs":[1389741528559884599,7700031877796019457],"_marker":null},{"coeffs":[3059670038994323248,3609385194613371062],"_marker":null},{"coeffs":[17818989937285774002,13602100339792814484],"_marker":null},{"coeffs":[11277694566074019078,10221679385799488126],"_marker":null},{"coeffs":[4397168751866712234,11318841393918263161],"_marker":null},{"coeffs":[17807316661154646698,1964115888000631856],"_marker":null},{"coeffs":[15110658476496739542,7764497643817259345],"_marker":null},{"coeffs":[750542464643192157,12963421362428426096],"_marker":null},{"coeffs":[11046183640256209805,6558509509032512048],"_marker":null},{"coeffs":[15443673475250950736,11108240257144472665],"_marker":null},{"coeffs":[14854393486048375542,14339086470098159101],"_marker":null},{"coeffs":[4744463891910461630,5938294695393822739],"_marker":null},{"coeffs":[6041224751546272306,12929111678247811097],"_marker":null},{"coeffs":[16113095206452845556,17425145623183354506],"_marker":null},{"coeffs":[15958088118804307843,5329703218686102743],"_marker":null},{"coeffs":[18342756225269980907,1511082021068831673],"_marker":null},{"coeffs":[5502841591893584340,4606782406769828477],"_marker":null},{"coeffs":[1742442332661836478,10127365080591216122],"_marker":null},{"coeffs":[6691640619498734084,14765218701048691234],"_marker":null},{"coeffs":[12683108801561582173,16705298627670602457],"_marker":null},{"coeffs":[4451330640736108442,14932003808377710452],"_marker":null},{"coeffs":[10034450937675779366,1422779896633053043],"_marker":null},{"coeffs":[13654791157919314904,1024790006711374085],"_marker":null},{"coeffs":[11495008171632172549,12733391810229799256],"_marker":null},{"coeffs":[4060490515561101192,2844758740489781318],"_marker":null},{"coeffs":[7058925190373302605,7728409423097560076],"_marker":null},{"coeffs":[9255703696426070915,8402397285945892119],"_marker":null},{"coeffs":[14795747919499206759,13044596570864498955],"_marker":null},{"coeffs":[6919362025912550037,8439054972278484330],"_marker":null},{"coeffs":[6661850535523836668,5536371988356957649],"_marker":null},{"coeffs":[10879223486976969504,17793941879178005850],"_marker":null},{"coeffs":[2513142742399233844,14566409174973304704],"_marker":null},{"coeffs":[5585465804430449226,3099888521837558840],"_marker":null},{"coeffs":[2197739444685109349,17204399579902487122],"_marker":null},{"coeffs":[12208578465926831221,15022096252391074188],"_marker":null},{"coeffs":[4562826102376594064,18195196051497622811],"_marker":null},{"coeffs":[15153088328768514560,15799980727135815141],"_marker":null},{"coeffs":[10186733529255116004,8697567123154909301],"_marker":null},{"coeffs":[15012199288682859007,1827389231343900544],"_marker":null},{"coeffs":[18283746265929935361,14159057497636368813],"_marker":null},{"coeffs":[6789034287161671866,15139572284513208899],"_marker":null},{"coeffs":[6023957506722143786,4690657305919231706],"_marker":null},{"coeffs":[18203022890411145552,13725044886028473879],"_marker":null},{"coeffs":[929415730786820290,5511310996408420632],"_marker":null},{"coeffs":[2401177600439201948,3715473427629835628],"_marker":null},{"coeffs":[11417701628370378006,8872046163863626819],"_marker":null},{"coeffs":[2185801828568054729,6689711772681112351],"_marker":null},{"coeffs":[17453423192416732289,16938423988908724701],"_marker":null},{"coeffs":[6749076698435045686,13956258874443346640],"_marker":null},{"coeffs":[3618508032804177142,9688698697526752236],"_marker":null},{"coeffs":[5185050135802595623,9324419158220764564],"_marker":null},{"coeffs":[17872081416986761540,16744730224901552460],"_marker":null},{"coeffs":[15726642016712730493,6626968930857499787],"_marker":null},{"coeffs":[14604930782918395535,280138748746120953],"_marker":null},{"coeffs":[4614406699594487125,1180110560220202329],"_marker":null},{"coeffs":[10673496862543401007,13242061235653794086],"_marker":null},{"coeffs":[17835776297516358498,15830642264671403833],"_marker":null},{"coeffs":[16398803515978859200,8958271119651983232],"_marker":null},{"coeffs":[12840331214848505932,8456303090840374788],"_marker":null},{"coeffs":[12390865057108318367,10726916790509802624],"_marker":null},{"coeffs":[5529754197803250594,2658263080633465714],"_marker":null},{"coeffs":[12223504106262674511,3272885026583903160],"_marker":null},{"coeffs":[1016540385260959027,9177761186950455822],"_marker":null},{"coeffs":[7608784930045625165,7190766046776414001],"_marker":null},{"coeffs":[347670534616001129,8647954569953217095],"_marker":null},{"coeffs":[17637420408620489996,6940901839240905048],"_marker":null},{"coeffs":[11468008773302102769,3077988640039496923],"_marker":null},{"coeffs":[7686558199192043488,6212515438553725873],"_marker":null},{"coeffs":[7808598251408553709,514194333367732166],"_marker":null},{"coeffs":[12921839468819706950,901030670258588143],"_marker":null},{"coeffs":[6152589145595879131,16156753130666617835],"_marker":null},{"coeffs":[8172690981704212960,3647568127144829742],"_marker":null},{"coeffs":[14423064843405587277,12938694653874227510],"_marker":null},{"coeffs":[4474895664830070868,14267547204466174046],"_marker":null},{"coeffs":[1132613905668245057,11157252360494327065],"_marker":null},{"coeffs":[17541945986182639097,10123094415153215561],"_marker":null},{"coeffs":[17733998402735102628,11008064407966717586],"_marker":null},{"coeffs":[14186890500937867402,15700862525668721302],"_marker":null},{"coeffs":[14261842540927849989,15993517520448010176],"_marker":null},{"coeffs":[13703541677406874565,5916416452193363836],"_marker":null},{"coeffs":[7839464059179537010,4234710814566821262],"_marker":null},{"coeffs":[11363825416400964720,11155438880225367269],"_marker":null},{"coeffs":[13176240441590436978,3211715579022297358],"_marker":null},{"coeffs":[70704519164316772,5093560098069423942],"_marker":null},{"coeffs":[12588606775127128112,18245667787270644777],"_marker":null},{"coeffs":[17026065692949293221,13583529202452169149],"_marker":null},{"coeffs":[15488031469297611033,14043331951896743517],"_marker":null},{"coeffs":[4154635860766436586,14735227583703305811],"_marker":null},{"coeffs":[10986331507973437401,7355072700468326890],"_marker":null},{"coeffs":[2744130283850644666,13924368750764294285],"_marker":null},{"coeffs":[16707672484077482456,11707590908631917293],"_marker":null},{"coeffs":[7556816771941724780,5010805656889875870],"_marker":null},{"coeffs":[16076717691155352678,5181722909069226690],"_marker":null}],"values_at_z_omega":[{"coeffs":[1128505831080153765,2101249611858827122],"_marker":null}],"values_at_0":[{"coeffs":[1607182597868775507,7608001658327261962],"_marker":null},{"coeffs":[18093081592911701763,7084227096818481118],"_marker":null},{"coeffs":[2809701288855797604,12526071846540823103],"_marker":null},{"coeffs":[5482497188792347615,5084669764629488759],"_marker":null},{"coeffs":[9545718599014038168,13856226296901470621],"_marker":null}],"fri_base_oracle_cap":[[3681115382525003401,6793608500606324630,8330825774599068639,697450270388349971],[14383109467311535089,17372459298126870242,8011456196447649161,8474256198524309493],[15399280269322176438,9073859656436238472,11367965726957988424,10640675857861041480],[8133474778942228563,17916745751462665487,16492212727121400926,12525020327737215845],[10072895350570536808,14813648357799499610,11422763853023682369,5259655740956894418],[6363853072653492291,9967173534803974299,2859936865652630245,7537272927326346936],[6657958415209346040,12549227987541235582,14850012154990556255,3613474599759770949],[8830199211465812417,13500451849184041637,17816845888912214723,17477584348007419050],[2524687211448378144,5691136425580371088,14252965498628089881,15323089632378445861],[2729754646891094869,830625752115870939,4534580926320842199,7858619347130294321],[4227509660075286261,17266172950841950717,10854113312691741225,15131951769196412459],[16191439865516112137,8864249112879825382,18416009431528227849,1211724049062677599],[5888163116368129329,7428881765914517866,2944648787422887644,7392162084760218458],[3755285793447955295,7761454055884494536,206364456859474406,9670775018923937622],[6898785204208438904,9524925879890686225,1654744822708112348,7167574893996944205],[1190019633110560127,4165257078291376485,4374762886624763702,10688750015952095683]],"fri_intermediate_oracles_caps":[[[10394283850254350115,9504121907308959154,12654513247747756566,10055153189474871753],[4362048115188192130,13140119397768896678,828979726062053173,9090803788491849203],[4169739436126464215,7074557713444887926,10721635440615117147,9405900581809561121],[5579403050011899291,1299543566922603090,9184440365645769946,5271950477660530559],[6089788294377899590,7573094608652041310,18167630281844117978,1853375047562269702],[17053538452964804474,267957416322312065,15769501068870798620,25184541718378914],[7363929585431428947,10678533816119422361,16345215583229557147,894970796318424567],[5764127927461435611,10666534617353402870,4311149561787273320,816773705652219815],[16273633467834904849,7203338045978986839,10154105711287807362,17753560755600343091],[9828450312326374996,2179967565289181959,8566031821672904818,18224241622933101335],[11703911171008623231,2766350676565107412,3582476052188485966,5712018543880071733],[368499484424380860,3695619555158016809,19160702374642985,5940832624694642619],[6440246789392770407,14126464336043040879,17775983184544421744,11877564831742004161],[11750568199825277095,10602714528648447966,16294827829627427599,13308246021347419248],[7032804267344844906,15116901890849825501,13994084684494189498,3249060553972671238],[4276936683359856508,7299576205891517050,2553694845636614153,12420704479231982805]],[[10567749218574871476,2156855179120986170,7051260887056469344,12652242631594413875],[11927827660038741099,15636183479170195580,12614549417978764661,14101114609811754511],[1676013108055504243,4467104225632740607,10368719734069774705,14936786937174740140],[11291587160494653743,9013551181170206790,16254731366490274565,17000024323997703359],[17818532586737496756,16491139787262130337,15010027679577810744,14969541215238008896],[4069870508387384775,5190382705959689433,16105560029875467962,17819714983805140609],[1006155065199579047,14886947043316666850,1380531892245751705,4747638839905561209],[6303624226934566127,5232303242366517309,13708635826111416479,4212076018383661385],[7531082386068280100,9233015572210570671,1863184998837548184,14768973579939306191],[400416832932398428,10712046782807734325,8868126925837574793,14454677291487117173],[941611899961239575,11866332619606672082,5238235852132538535,11299704330758682442],[2543164487550901986,1145270000228215994,9564201709943731620,16973570461749607241],[11319634844018173568,14719552810895020173,18277582875185166958,16240939202242976008],[9721362325398953704,17109972783139155998,12993975836831281221,12316481977975436273],[15226492745985796966,6724998962510302326,11663388814673580283,2133876448719915163],[14705528888443977354,9625105360014637117,280360866248061507,9519025947468827192]],[[11026418826103840035,2962323099874503260,6184379705838116050,158341231634384694],[13972504039763872718,1328282063825528158,2720336588394126956,9071345610088612985],[7085680747612377988,3385485007250149254,1060119948259087939,11020699218077982260],[3264414997076634938,14398760786485177372,4060951667912214742,16095512708195018056],[5221464548096132308,42751927111766616,4208549691488842810,725733933289703679],[18326037027069099640,13362097830426219432,15098729197100505151,12582710628469537905],[17040494721454099127,15825287344195380471,18003923212893545868,1405586227711247755],[8736355125560431545,15110457450577285484,15387901244251912043,15747180179007611093],[5942500630077369783,15734247359405236676,18165986244458895171,8240754760764196187],[6509512335935850160,4440639771879126826,17104882107223611188,5575296247416200251],[14773379394335223221,12138665513810508794,16994244945244665067,7003856848251556724],[15107685360611655439,9716950224856798762,4044839680299062586,10781483071608334325],[2348641638120458559,9046717131780680388,13366875265096833719,3960147458670011489],[12404298876080930158,2683827149614215874,3244502126241782542,11520890867998263050],[18022922299191089400,14989982805825884445,9361524406753729769,7159931272536079980],[3248032031939551890,1046950266317698075,13812775633609973861,15910691196971986443]],[[7147677653541871712,16095109455835329248,6307041975592765159,16922514548430323442],[16157480710951766496,5541463137948348200,17573012188614204937,9723333485442218184],[5857335901113289328,15979757434891314561,9644669044109013957,17055474714328797208],[1712864585378100623,2226516168698730182,12970027878407773132,426660533698652710],[7874905241589944676,6507119217802388116,15213925837511947715,7225846944909181130],[1547894495146960536,2092711984130029144,3609327012530491890,16626688725585547904],[17143718173319838705,12422865705628658128,15085422615248191285,15791771801126003070],[10035533741744417741,12585228768506552422,10230733188659701992,8448473679615723749],[15801354857255232757,17746599919135947242,8090152031801209725,18149674186623149580],[5579852198370502534,13171502381005820438,6812067293250627602,7357258806879329360],[12623719472767643,2484127987382780963,936785536821436818,5099864454385699147],[7232132998621794226,3009902002591223546,3650247416969810085,13722795956768362323],[17315454299931160779,9213899352460870030,9212967608808048540,15233691752684879326],[10445108790679412796,3146588704411628887,8588595575782872759,14502154330509723220],[3351326879113516243,14090136623095279077,13512226329876435488,1349383972108026920],[10094052097043347686,4098335702561223480,9940556209990006987,1727122683324151384]],[[11002097723956886080,12857720168389935367,5212177958356795240,8773815310793718069],[3502511857980334845,15288554695748713200,10668068585257832854,1009499477760405459],[15244692773230777293,11008677386758404361,12043608285196949335,16027202902317818055],[16488796469850022324,13395853889596715429,11362016446410974714,6277695744424500228],[7341551474522121738,16875680480575914052,10992689530756131398,11993341215574861545],[4363575929941063622,8874639422324520547,8503722369026331359,17531866741939274822],[15320996573444332340,7546722629954028301,493621671695658473,14519040692605670820],[1646238656030157011,15009987809097315092,11075189328072415455,16151638075534045059],[18048230622422541944,10199401967347241514,5927604259108097648,3525747972807902531],[17869674032929886501,12459259008667099409,2113203525365727985,1676961629928408342],[6994820635871029794,6961324354589404855,12270442922517538793,13990703611892244454],[931408683122620519,7796924617286403397,4223578974117119579,13458741658183501719],[16086437160747982750,14593364527314092648,9321571150822792512,6770008407856625052],[2606052454215229785,12977437921313755555,17452350942027988510,8106534116997996940],[2263411913809894579,16111945727182109462,1477894489972185540,776336543232774265],[16576158053754429308,10088560142855912728,2239707749419247267,8846175747019913330]]],"queries_per_fri_repetition":[{"witness_query":{"leaf_elements":[16780364289265768270,305524875074754954,1464238289814963684,14561233499730635548,2061704545807382094,11052121273598919510,166107207116104644,6548085656568933476,12966316283990926934,4961767312948832911,9054212730119294062,18257189206516964669,1038619760781241707,5838704807003449667,12040067955421982802,5199824314857311574,12968013767409932680,12869990462121256776,4017960247510784119,3047146175396460820,12614720556358558816,8161935614686752733,656422827410691041,16176479081851295968,15345659696170902976,1597462160628698007,11596777925250533033,10519314096206758081,13444204415199008507,8816925345122690867,3035243187488797711,14237091333775409280,15979755665935768325,675563189141895178,16989806560475452468,5081204143166218751,14855711825676633025,1440924082387769960,6573064184262372635,12478904906535458506,7069869966930213924,9958252454413659684,10369749724203976283,7668452378274032441,11971354870057861487,8526927839538853876,8199897281992810046,8724667901307467192,13235740185258248652,13369984337489049917,1566553057746394272,5708607401571010104,3933624021687187258,8353189904530028225,18032210540011573106,13157216445534777645,7469894189075227931,12936514182981931830,3561067771219572148,18360703939481009720,16183004668833901907,10251599995080693316,2331307047118972145,7098175046841015094,16192972337593239943,10039189977246336603,11998183595547839163,6857141391286015786,1195892920975253523,14737011885621819705,11194747438689353757,15975799810235837387,14214433742095654800,9692610185906178687,4507173278775520632,8845289145859174758,12846081698615729989,7882556592744084806,8608192333925144359,12246670810928044596,16639342918275729317,5913470601753433801,16121378929201092789,13481879090816053670,10782250458570906341,8150082337268372715,8661202330786319112,1840989352938893908,15553585532659592912,3921550040929403885,14629258996731857401,17944265410915880166,16658182289732551247,13479870241804442962,12799804714054727454,8511547641329208590,12350032718733412617,3367941708568081969,928193418687910201,2275243819671139008,8829090719705950717,7811784586486697329,8037441072549802351,14506391350222529883,12945191634174382034,2929816102140332528,4169360343195679188,8425886812178961066,17937901248117973536,5817191723869428621,7767500821674093548,12232030004638935818,17234344374909216201,12062969228594350378,11023675793666481646,8705328402500550048,771299775907629498,1963933726700273776,8441602898702096736,11009688138930196001,14691746557755132008,4227837811740581541,1968964571684660981,7640383105225334974,6336186662961490906,14090138599896526445,2111335129433801663,953159152785254205,6032808130553224697,6477343995134898784,8668017419881089,696949638935595700,1508466276613657431,15629647340084935214,7248371212060179254,10862617536140471517,6081650260751891228,14994916674388232828,6355181038156868709,2604458046998512422,12042699585894150975,2875826020929167802,8079169740000464967,7762524942404579537],"proof":[[13248333790297502325,5969592327827025777,17752396917072260615,11477158963266457654],[13924133050713422828,2829050010022432337,16725481167198066163,11571638005303641459],[6409283107776957799,4185565079304555972,14918744158681501757,10839693640158764416],[13456507492171619790,18294814984212618992,3830200532628740365,272930413367926918],[1716267843476793053,14816284844784069087,6740301928504414179,12949079976500023149],[14271521137417052901,7089915568817764478,1476401595257213695,8889440976686549574],[4471021635377399927,15387977511463894770,880672881393011920,8911064231350702729],[3742143553269638475,12029463220424637997,6322152074910631153,17969722896567452145],[16909476764145410467,13174980592313722119,14396104342629842637,18194161111784392606],[17120001924744798724,13680504143607699593,699485783671600790,17891465173137011069],[8468407019883959546,11069323726288541966,13028007038399299962,10801032703597947759],[12839895813934701630,8441239573441764829,16232485199036103314,2333002778403914398],[6061131359999716358,12699424688912378439,15916491132651080959,1557934297839384327],[16196551002024478015,7673288438504631828,8647767620552127639,13716428296088478628],[8656114365214242897,2026613752555735250,11746444510852321615,1310166986361981072],[7049343954157092833,14391493793205640963,7395172756984581331,5113072916745052878],[14710339626193100422,5166397287786674443,12877026722859487242,10407735240586944831]]},"stage_2_query":{"leaf_elements":[10502861270841911075,508599799216690258,9390121684624252872,7919476102990988926,16325173610717582322,378972656040356106,11512789251521421049,152978865814246882,10593059968968319519,15532240864409423500,17314466547387972864,5000268159510106770,16598044694723923258,626768305503172789,12696142278494780893,7859828399542380714,13758029333236122025,9472592459674597234,16864253407757391103,11702379993837745498,5672445485306258897,6827047126793976920,1288228544784184862,11402113448659764894,13240128218716990582,4193510154979132820,14316740965513197989,16540029010478500846,16475733123650077339,6910393715039294340,15508468464640004748,11945446863111128023,9304109603271460190,6087147961729232605,14680203705398882216,1463447289747409541,12976920289335856379,7461779139492076870,7872949627945976509,11352540130804691166,9447381527973204408,5629525396429689616,13529492361508463301,1349481860157443032,4213390322971765098,1352846279469081295],"proof":[[16450599681904478045,4709917431516542271,758327500189214602,12172624990190531330],[4163143264401771689,15190200660051597606,1109333027218427673,5758755437594197311],[5465295072143838408,1153368479492486195,2478386341332275169,9327781661038541348],[754026795381770744,4404146807612077173,13345450295624418054,3309421320119379801],[1001048152569743360,8495176371651998049,11041575058269849842,13123334453985556723],[8772366281178591371,3308130415130226605,3596090290371416547,745076205979007019],[16159269077964916784,16357424046363897236,1685091299877960375,13840239626008348902],[13049396781268332144,18385467185793770403,14003635259477100085,14807436289331633772],[9119857971481606536,12690951927687071114,14678865182458187037,7193519734454190894],[9776822107765071350,9246426424483176922,9169509404839729688,4284349315501192544],[6784785182888546842,14781399337974647178,4657161167500840232,2058260959799605429],[6894730570005539246,3977044052482844539,8458432162401505209,18248521049641740773],[269885146538173221,10294497963915879623,12117249534374337589,3331528788004333393],[9794122329828468316,11615974254754166780,16867786550442077127,4584026516448637928],[3279897117021941917,10243015713882380433,7774611088600453506,3965896168529592963],[9069739529505737466,793676914951333750,14464203160743970347,10684389483843064330],[1135997963394111510,13275752990064275231,6348311180324878415,7982923292041772706]]},"quotient_query":{"leaf_elements":[10436002120659059928,11006164367871672417,17263840781879968885,11144358836388307730,16142052909370515947,6341736783514193454,10661326899322679329,12135465152430166827,12278805728554914236,14697358071233109052,7583053432597384161,8483676209819029583,14147626935875439825,9612641965270508002,15821390454301311947,6314029420593735192],"proof":[[3823547577547562798,10774853425636744642,3902332734519040318,4369649352149665098],[3376016618505472436,12978613007155985693,11970839718725023143,15733133822193663320],[13702211989812254306,10925632174908727109,17344658765174800647,15792487801020846459],[2313828613887708338,6205156919478144729,5967451599458505696,16807597975798941156],[14661087880934887295,11015772037102887621,6505989459328662261,3765110641505686111],[1138531133517635248,9953963119432637775,8539899412997647921,13070534054635300750],[2540409363063314374,13201745247313799784,7805683731410172306,16360775097182631553],[2685279242126586660,3560699854674149000,17088843874287468695,13877554295205503873],[10606638695521652705,3953654589200421993,12618256893565729569,9472996829325619464],[17842574054957772510,13046744521227907130,12264466200223463879,12874157980630016745],[5081648144698302316,11264404868965218640,8248419946383882573,1104983169856915351],[8200670377200257007,2139327851038209972,14302487489975260884,3241595794171488079],[1700249301982663130,5487222179490299,11167555952461912762,13316158072955004000],[15290488279160795485,8551668492266178251,849529415722273839,14484376397558487849],[15399655746354707545,4603123658320543225,6138016519870730333,7155963258212196888],[4359957004431156532,8965941034467977781,1773912866110419813,4664342605257984095],[12530437638825942509,9467813558315705039,1660881245341910574,6918973135087974952]]},"setup_query":{"leaf_elements":[4529309466515726865,9794010687301567241,15368067352969337406,6310665327696448614,12394777664573715172,15049768520168639687,11072557744664416158,3335144775670448862,15695742911438558797,17271027418851151629,6399379501765627846,5779326100733540199,17265812675226427617,10223552969550513752,8090277651955467928,17162189385263823088,17169308143769911867,7073929079044498458,6088257012812091249,11285282945038625590,8442862436817475920,5161517135517569952,6039888881696201136,178952968945402785,17869234552217517754,12546365434045659409,12089979361137530424,8998437804074203374,2212387134975082616,8988460746951508845,13617233599728457144,5879309607372274513,12353389926992733741,5740585115036206835,203526521447491682,12868006218059833802,18231862245083368586,8657052551103918102,11857070412249451943,4660511592080714988,1860837991657052293,541231836687362953,9145108728209020905,3362147189815162780,107007336345561022,8213397383834833629,8643764020720637580,8420862768217323654,11789374424753788906,1493432498075672380,3931828970727920025,12714633727572771562,5950824494187897805,15211123193362724615,6172503337131744619,7382970173835558229,401249828332581166,3564649421676554439,1861949474538957739,12957502751066020502,5193046001988674106,6790343319718204142,13214509583347026303,6691053389794542494,14786999152082737329,8560674843884508601,4883530145976024193,9620348563180305440,16193920634466003787,15787025780595719472,10198288164676870305,65857895331108005,602207449054821490,15016401776599562615,13251231927391055170,6343676951534997438,426226969380934375,17766976589196334,5397088486024581143,17533950776249721427,14600438423088005510,16993188193765365561,13063690900381970843,6861821887541013656,7055831107815794810,14030495817910271949,2074198271515189283,5917472229707264122,2209464928087108209,3943883287739260397,13475740682976451440,13654563658819239327,2004811397600935151,12593164789138687097,6389668870751697650,10501090934357819556,14740507024088466694,14113761934301551798,6886307810259882956,10231536916323328551,4809759589143987584,3457951449678216739,5475996308169030312,18000333728887728437,627295571558487440,5375693799667612763,16107516387651637480,7216698176249900066,18390071148063656406,8423579284000924241,7352463795931265811,8239443117260721102,1901574705966419977,7331828374662971987,11261903999205953758,7088872916254117654,16114063706151727005,3178298961170954782,2081512870071000328,16126173911888256766,8908233568589715961,151183949886260014,5509245586780528873,7792265658136785592,3191304542559638342,12936054282245893247,1151981785535710716,507643904023068694,17832341963395765678,8446447447870426785,8111043110282176245,12649440302675127602,10282129615284997494,298532772623907962,18059634965038173082,10072502850425274912,4550507129110839615,9231944605656546563,14203424559241987840,10727256100518626481,15822074660770215421,15834543760571268180,17331146668465069057,12103131224887146475,15951184333705533187,16287195946781948501,1844495946277321689,13117115686167569101,16573763330749869833,15097689928865810970,17256664512286572383,8013332682522720565,17023107869472804228,10893746323256742168,14135435443951808011,10303779369471333949],"proof":[[6124879384833815117,7835323913131203177,11988671253348624570,574338019856093541],[15094198677438273926,9717714000643242610,5345396281000593004,14581205174822955064],[1890749046323786701,8821195211387007663,6094349698053486669,16635224295824232513],[8772438496081182054,12042259976704777313,15405665322766259370,9981453199209023454],[14286833510359726206,7425844620722074424,17132561256804715993,8434882536202351049],[4603200884766257124,6807866151460076550,10381605166964097368,5109823321459057129],[2417575407648415523,15164364067108701711,12553888460602087409,9343680982859718677],[18424417982307205105,15478118982864099812,16735182174280291622,5831966659833851773],[1374607753273104340,17867158438879409707,8000063305783515813,10135695772057608453],[8574409788691144861,184272308020483515,1976488984583437880,12290945354805628599],[4589640724535420890,7964742307629490095,10233359623945669824,14102796549267621349],[7925748070487292214,1586439642743239030,16511854835787800148,3438990699897960944],[5659481453106058123,2427945940424173741,1181410798006836175,18005274976167694701],[11160423493432677305,9456166199718811518,7142221301919660781,17344400581567319618],[7433896140923527024,2202919805167777348,995682786262345260,4650991904692400848],[7472052915157579580,6454707544650764846,13241508517962884643,7658945900870394285],[11786672773418549703,2339467107386851422,12140533047963330746,7373381974425188538]]},"fri_queries":[{"leaf_elements":[14085087057522964865,4202469780656408833,13978361119076288568,5093452923422561879,13851141080597882336,6430543645994397964,16721219003374028621,7991966782915801029,292983505376609013,11481048983025383190,12997970418580241866,18239460849679665964,12474171915438818548,2827069484614628949,5352228032524437543,1067882354418332629],"proof":[[5262947658986407002,14856294186050763434,16226208846482942893,16497223842061342921],[15528417388592138676,10882014012577229929,12560124677600489014,18393809417735032996],[15645467263753436430,7676531696884797726,6811223522562805700,10909046641208187001],[3880497403118931840,10271662563900278069,11655361806884024835,4884967253671160123],[14418235817748776652,2955548772914527409,691996341327161943,15629403109805057255],[14651779675616582918,11172710129093706016,6526387658408581993,14144380244479890932],[566115862070500575,5073772082134567634,4024092254495034465,5567306673908885652],[5654311972727435884,12953769545911107098,1225776535057735525,4057116025268053698],[1648081196068781205,16291124343029144398,98489237287471196,1116099414585102685],[18323446992132432489,4728275766562740159,14589094978523231165,3062080650923062953],[13891128054499851535,17475100656938073344,2496499344324880623,2643467361105064032],[2570903842201634756,2815180613750793309,17915806315847283131,7559249678223093886],[8565450714688367775,13371411646079149581,7669076451911119034,5609613507105328615],[2065112813907786203,6898755846797313237,17320045911186699311,10677055216998779661]]},{"leaf_elements":[11356213859624584302,5684202625687427277,4957997449591695394,13102306736827696352,12554336444714616307,6174656452962754562,13258642170226475592,7215272576222459153,5989597498258589905,10545965035782715197,11749379494045210995,5375819492834123419,12879648988425702620,12484357461958809993,9951375946958069456,16524577864056991740],"proof":[[7171042383276344755,4351421395569237705,1717006161550303659,13945691239798852988],[3498780438854768058,15042345984138659998,11504517918764271467,14822337965132965541],[1834776998022080269,6070150664696846915,13355074775351742226,17280987113569973617],[6245236900916642992,8690114468003503056,5576029822625347768,2999961787901879937],[7828927761349917282,9754490211937220868,2086556024562165126,1739135775235928621],[14034152352365782114,652910976034132084,11348346518580433605,17675537308764332725],[1093880937445319958,8984306283653256047,16327497833756206967,2590527419034959313],[9733608175882666488,5489501355331763774,8927934403352772406,2736090202289005850],[18122974946076478425,12435953803150465335,5650098485695833626,7295604576442046531],[7872375859433308862,12547335083355183725,2049786543156448692,9084700728308976857],[6068200341678021668,17238405178273883915,16254243979175388415,6326469122072930844]]},{"leaf_elements":[17203325566718241867,12392657092612318097,8433552402984246335,6799410683087574650,2256404064899666196,4832435131744830198,8772914855343154930,1589130112380688626,14043202156699246539,13617233855062488269,11851842375097362155,13720164261550428620,2323846088336232884,13934862476079455915,5152288764991940941,13800770209781096252],"proof":[[3773209559122452771,7553148704306693786,727817617234973532,16636006536300681214],[4063252464079962202,2639625993356102251,10527368897495359545,1713237109554322430],[10992914870487931448,17781315954295093964,13789456874620456049,17412184007346780248],[12789469121769975114,13467418002409423722,17439917261769017768,10262868624052854773],[11562246006303192512,14703138511331679963,5689417565345382787,13021043594748125904],[13870329784909238581,7462340476925786125,4280724661028926061,12799137110713553459],[4425897915657748671,812478123278601336,14446386344517017273,2479368791048095681],[6284005312668722525,13175024327537991261,5546811104920909949,2703000136490581107]]},{"leaf_elements":[10931668978387920311,14459386142248735949,15760715611928924380,9508810772046854317,6702351064574639199,3553813091253586437,14038163186323184813,11496837976539564214,12285652622781157438,12574094331963251607,3252358902620167629,13613888653964902754,6097985415571166090,12203296929207700417,18357592689871852003,2864590052098745989],"proof":[[1574338207489362210,8489329743836165134,2203775184916054105,106041864122542862],[2881542360498075064,17386986147483548145,3749745903066613385,11565828843696124053],[2603844429399662471,8473451585878134884,13416626538418064197,7340279460857765664],[15183664090613473060,1501067564438234346,2135154504861079625,2969398395681691923],[17991506096714915795,4636722536725601757,13865614444769694335,8815772354958363399]]},{"leaf_elements":[10912580827303826969,13112124498184870572,5166031771435844608,4246959628546674791,8337537940124154336,2808515550656452715,896327017507608806,14965286150849039867,12366897045461968021,11139471698543338371,14093486012080335828,4141646308185794490,9103831047924060398,3762366279174691358,11512998418801433510,1220189138193510249],"proof":[[10958797391945941300,8725990360423169908,5482578788976588944,8844326393553402907],[10835623355140351544,2411159751067968680,17855867681805886030,86569936236411870]]},{"leaf_elements":[13912788208633012260,16592364955197622110,12930883254427910878,5599575569218380943,5682660096836901399,4069773254031359724,17686759155637027087,11829746095036037227],"proof":[]}]},{"witness_query":{"leaf_elements":[5551651271885236923,6715601750011582916,12081267305773477679,2562771713345895313,14384581924361821693,12194874875178515440,10710312246543894259,15178241467459226921,4895121564516910462,10181080480700966081,4735836262441987439,15723923847174450938,3894982870842005935,15995156523598305223,15736269339994215356,930942541550511137,11097655354272527125,3609327034417554042,11674631346061857364,13847065979240798978,7577151636420478804,17187516305339808783,11166632709342576765,3899773689583580910,6320393788228601207,1856081352276692360,11146192705403094199,5604072056163957690,11375311318320695786,2268150804033845588,17903620677320908023,7107042617324403632,12742515076529702535,701301910634954706,9584610193436957517,10079889814403377386,9909817075725284540,16308951058048101998,11838861372193790024,15772070546426966556,11397240940470985763,4132697113770724826,4873134361784693566,9757407390033834124,1278904492287592897,2073162392407969482,13947064403847589975,10017183900597674626,8675712257021407316,1967604062773833745,11979704408523445002,14374030965992975600,18034881483881452315,3096045182880656234,12937222603059714998,10191474812088189293,15452988418189365288,1813868263725841007,4796808740425692805,7755462978432576707,11231437094447148984,16561548979736556092,9125572629565445613,17109699530218241017,17225116139858394072,154920014484121723,16018177264499636931,2776360214745335448,1889624489066526316,13184237589429630164,15123175488412433193,10626860065818155217,6165426024201288232,17848840307455508281,6647632276006500291,10815125782605995671,5254411199747983980,16928986815392419110,1746502668886134208,15293214819702623491,17021984190444133647,14776176130084699493,1175684206184685591,7047585079424632107,10286741587903725630,13391490191834399412,12237570498226649167,17308291787155955457,9143671315313622458,400130913582767668,7313919214048867298,9075996301841082266,17464399027501679838,8977244101912424012,15454688673913891385,2283849373387192370,12690544374578272389,14852817484428997820,3692719142686237048,15108486568451674393,17085186868158977052,1762400592547574694,7377318042731278516,11108423890525859660,6720993377052426317,17053369206114301881,4870457106974466552,16862506086723695458,832077880288006531,385329571558918387,18353925060269358287,12716107866888136379,14317861200803304245,5791779813662567447,4251625800774316938,4620002397712544858,5411410829194635807,4504239748893786658,2398147410782786274,6155490524155384959,287696895398129894,5127379705586564173,13646019494439040625,16624301361380178435,17631983949833020196,16323694555606603846,14457002550500973798,11420638462631234621,11214344408322132096,17290579508010056034,4741868123616930757,8243360903606582943,9334001043370843642,4458041322321582601,11764424113524627215,7940198202869594902,17746390980568040561,16530341088210072018,17939418179442808882,333304467998242995,425899977080093486,652511594663517824,4094023650618464896,10559482214914050754],"proof":[[12395145990858626153,11210014480306528142,3026661888942912447,16849263544812323681],[857026954694758484,15786586045610003214,5106745817511206317,14627932330870918658],[14986731108578118679,3994324132504989199,13943741809436559270,5610528583775168630],[13319948570088728238,5283933356952155203,15439598506752221143,1965760375031295397],[8173578230636947450,4660027580500549223,17409326832288780939,892802147442806590],[3537711544473306458,12707051039082342263,15448631553899156894,11980137527475338785],[777672912226835270,9227894531868700933,6409232628833354996,11693524247215709024],[11673326420737608218,398652487484061276,18311436953875577371,8214079578673485240],[11863712671220082150,5915762610648337733,6356143003601750314,7555796739136343436],[10677998737747463681,15872511490105445338,9022783538685779828,10655315028420405517],[11173054070438807970,3030175670535865964,17692348940106512761,16509283265782160378],[9467710854281775228,7336528769195004528,1950827883983767742,10083655994560297643],[3838753818275197996,189064812372433601,6751751491049115548,6352382887092289600],[2140620345695808662,17355368533352956164,3457190195744214967,14814315369125319841],[11951827357206309229,13097214819727585193,2036367471187991867,12943832126383923209],[9980410839683514472,7322550027951755367,3541525573975756140,14982918748775531105],[446318376307115417,3375364935197782891,1913390476604132002,14742194311215528796]]},"stage_2_query":{"leaf_elements":[5802675130378740966,12090967007061142604,17486983213438982731,9184503976195448005,18392281463265114950,1287315254226153192,9704457470459997679,12170882744807048638,15061741860215034285,8770894313176049405,7644068962644877616,10737076415937162768,13230225786716227589,12739175625236113704,11650898863371284726,14244678625336130197,17635643737664811902,13776589985791607124,10232978361178759112,12932965709049077638,18329818434925268256,9882206434119219621,8985117335040545438,16333303390010016470,7088697842056910834,12967619468952851426,9103430179532972724,10911731131619038521,3116457509791353177,9506655117024496039,1969233048544050352,6983590381416276751,8155948995342620359,12021481251198459866,18217183561744762271,1427173765813006651,18396451460077732578,14658133546676202680,5687999141832092599,11619477008813285450,18028292474296859525,12450164526060280835,5820926658638036912,15574728508424112149,8938963407583176171,6240764810550872308],"proof":[[11834005844121118858,655028672178469554,8710125209379253756,16796091799997242615],[16291171430787061555,10004453790139557898,2663960691056147840,3756517029891218397],[8564205170174751677,7618186241464975901,15599745658053523986,10380344715609041974],[335195846380594600,13621394966827268877,13821188500412733298,11863817448334473917],[3904255477425562806,3135945264732484851,2286046144989217450,4059748666068342625],[4142610889637787491,4573906060787914620,2724013836900456552,8574638849852291343],[5485189832506805025,9328199153028110696,10956544676041954922,5548527775282263205],[9626872552064315434,3764972851264971958,11878281286392842650,17753567015000915061],[9859022198534845792,11641999042433679692,14101405471218450207,9807317088208658844],[7798979403798072647,12683506188780493814,15094578871526859188,989457745075443382],[14508383984662961829,10568339229887192911,13483232286373873177,11460006599117732359],[4563101885001116837,17528333220092244608,14112757367157532418,814034618517842701],[11874573185120475510,8891806505317929699,9243203651744718165,9710881829965455372],[4473087033341194905,6577066188905207355,12643674693770159128,5530704844735218405],[10914958427844876499,12282454562936516529,7096338018838841972,13961594818376461985],[15746818743837445237,2985640451447576772,6733483411823019191,6575594278664829228],[1283005982263822647,5576217357074790266,4838152385037052151,3671493702847934836]]},"quotient_query":{"leaf_elements":[13422145220471422727,2107805303091838252,3840657565515179862,14384445389024761528,4983126655559978452,4308867198810084261,580344155878154421,16371713356643193454,2930288002125125392,15062873252200761196,6922932837593388259,1591255181308980007,2212130844285634984,3211189815002065269,11522088509904919598,1400940849015255872],"proof":[[5100830543781535448,11483435461904007874,11874407913019664376,9689825335684197340],[9009938859646713338,2031324932206644193,5693521397862082938,10924635609972762254],[13146883499656940849,17894685582453670335,17886579718714645391,6936753181773391293],[8846979404446552154,2119474573569787158,1750732259770261994,8165806577719884724],[7950273629801209723,5723022020907615883,15216061639721674376,2114256301418071902],[5863081001262384319,6745399957612211131,5927823867886367363,14699297386768521581],[18403689117191582932,12819010558649004574,15439510289350010310,17160015597287092855],[7570895104985728881,1999145409836225014,2265715582617541941,651086318570784245],[3843905545256146889,2356481600231971200,5673667422976554234,7817120166571738532],[8671240781371739004,1072451430624759992,5281344568173259315,5478440224187619167],[6809407661216187517,710828800895251379,7332354822508453191,7989543847452326407],[1848548248523181356,7337212549115773025,17190141329868061756,15928605347500523968],[1281141348970139804,3973661263912025359,16665281268818327291,4744059826086617055],[8151549188992794708,14291217109933088059,5162015206749826315,16072450646956129237],[14717752442514341439,13981289008847674605,13603209049062031231,4295238302453043424],[3689109562764849626,366021334287970053,14460318300993859375,15450980280223614390],[2756204060012982104,11181890352814265502,17993618182006171151,16194213402389489504]]},"setup_query":{"leaf_elements":[359628116770493807,16591592601983725945,16756438208894223146,5504743747370802900,6777018986423456407,16663189269248559446,8365563728258533407,4052335552939128488,3320434883591821811,7320116609663319628,3127564224375518768,5020799038282555757,5073565861037249735,9351979561485204593,17053707626916052940,10074435420478167755,2385154124951584733,2149604049878782162,15415956988671989093,11787767114153679772,2354904633167069175,12810519440667032950,17302871974899354576,1735049684409406995,16320333256492052909,13552706010578497948,1800740898877662106,7202980067709612317,17959486549349729820,9617961138225431020,13344721522874508790,18358065465889297887,4000367558585749870,9898941769115967260,17184922045700253143,2423484089308895556,4975221249208958419,18216980642496412638,4909797544968323050,14501282092924036985,17677707884888816482,8041568916130854600,546069802610744133,14495856862155898928,373356123276937366,8028045366983933912,6525204280952508136,9552077598350161787,8738237131791850718,10808960988116192203,13719900136000739024,8706245176407240780,18377352322386349570,3386042216421184207,7915421122978565694,6724476476776084462,9613357632333101536,4643259187499417100,15663858119390276467,5508515424581602585,5800782930571024085,17299200758706557416,10520978544345920398,7077613508833390567,5135127007713981610,17995056369050576521,7596380302528066014,6388680385893496603,11101699429919679032,8308565238466071889,3786572747471704969,5836325545816613427,3517528361696271937,2518356074298646879,12027565444817413794,15230939157069849139,853626834967772100,14403289836041940959,10030847524833921478,8478324896988144660,18124910674615647798,14260713729470666798,5415159757889441042,2379535786508141872,13105596968011984014,12109900251658293653,7124411604464923569,14755649681483632716,17132701504491795931,9333082434265540813,3994764130996326338,4420303825336435858,17537802113692018936,4873661571683042018,4469869772197901012,6631768580181886767,5813938098233133980,2162371623973126803,4519408664946573764,1066022582341298950,9025918451915002318,15406543889439602035,629733841047615959,8416752893213118209,18357148628862622798,8271480099584628448,12822390893470477745,590390861371069058,9506067279278586332,13007068658353249129,1250015389540169632,7300879624613905009,11945332590237300843,12679441825378759500,2154335538059550397,18289219638935734955,8368973709201846505,3656440738357357810,16189472051791472091,17376767206728937336,2611217633362548423,3535334245485825313,18130218047956242887,10310359458028562758,7167478329864225446,1234527821924414887,16788714631253818506,13954172305767488100,6378609815070589032,10565132447663819080,9170040887152179387,14596584837707357827,7444878493983963325,2773136679684082799,2796372817791105293,14859816773550853175,470362957018462583,16401407448300139276,9881923715530490235,797908251133983643,13753185624579411586,7284109984903477950,11466185568042943135,12952074900761440461,13467780736742260925,15203297459670166346,4299183638256317781,15065069232989637426,5185014667444771543,133780256942437709,17929901366414902513,13688451048441969441,6972728695658693090,11734810701808308905,1062579026430838612,2022197086478079432],"proof":[[17369520799359488901,15946437884108466875,11300029348362334643,1883875158783695541],[8205520693939456693,15638325713099421165,18096242965016258113,6482659755253244864],[10756511619687999330,1197924830446869465,9687192741745156468,9055934265529586679],[14197070643004137890,3778454153338577700,14523720299839484811,15839491949563289455],[1172729193101775063,14225903168690415950,4069075874286476034,5037310380229830442],[970393559245028234,9291091968729929500,5251859848376665585,6582550218078505379],[17823042953260333165,1604676414294010782,17829187943120434804,5338693038246118140],[9756230662314544924,7543529507424661931,14132278491745759168,792351864533839914],[16610965087081723339,16394780888365520674,2133289121307622971,8854826245749063503],[11573912671995700580,7740262485832039620,14145689671892364957,7433731526718092638],[15453959596011598887,2761584310954475574,7396484958800857614,6269106449594033063],[1189756990033392471,11532214100558565432,11479848664292327592,16042493941868163748],[13561520046415926964,5191234622223782317,346126807967777470,15247111468523930660],[18116677117884776531,18190039508294493617,10170924942196989904,8600647547038082942],[4948683317486886608,7487393901776645461,6837397248267998270,11397513462846164754],[15572169563599132323,12343102909949677132,4166028430645002977,10454462429890612665],[119942016992425815,7641812824221345957,717302696007773285,8607632033190912232]]},"fri_queries":[{"leaf_elements":[1105577043493589606,11612929391539843319,14662476614387048374,8553585843011810745,3613444576125765047,8663828472087925119,17398455258828037867,14471718986643629894,13019820576832002970,164137295245354302,5271708664599665446,13300223234671238982,2612373374678151524,1989495684861105958,2081308528903141012,15369748913012371036],"proof":[[14683706350447848115,3730575540785134214,7587748576566987888,12637117200533342218],[11229144425092610634,10897432754221964752,10746988964291603730,586664009273844012],[7653831083072080428,399934367593974285,13612360337391019070,4516280461861679004],[499131211923076482,11535453713445136958,18426407708833981781,6581866135232268768],[2655459873066420394,9990389799991488658,18138747162584340892,12671839202050951234],[9436736447567808468,10078912412197055512,13662254587182212327,5539069711972163228],[7509562066633861865,13803219356474295070,6727206628539159366,8028207126742351323],[12997562814244102926,2876394267276877115,8314379716662995580,3761485453685589799],[12277397894661307842,4291919801018007183,10563669048233174993,15456305895485077351],[15763687618680049582,16702443174187800006,8103153856687608059,8008799878661428481],[12689699574537352100,16869873833182078432,827686016031246424,4612442477576389535],[7348396166919247276,16263404970388382454,2142379876581275148,2942414570241630678],[7027844335128081170,10129972155212038019,16401628726279509279,16456211717365178169],[9497522330654010607,10428746838159854411,17282797116643625741,9370446250429457167]]},{"leaf_elements":[12526555094614984978,4860048489752653583,13325658711611084277,3893584620390009238,17296393254298128194,14819094750450887550,7235277985344231844,13633731864211759490,1210555089572709972,13110668486061726375,4277653859205314012,2498455807886747517,9521750255471687527,1032178709340904764,15378830978586451277,583435835761773846],"proof":[[5094658276598443568,12111154815069583133,8958099625914277296,6333929329222379943],[7643158503653364182,7957249731444750311,14884870543627931760,1154094085364721006],[11854910462845526809,3086571116721739670,9593956478946506480,360025872447431358],[4907628743649666279,3172174115613701575,8324718861920170841,8866508638223006534],[11712351860952746617,6000517707696465353,6458537834547806796,12225359367939944889],[5365917128700362530,880197644457594037,13717023684950298597,24355427645426939],[6475988291275091565,2759609085784789852,378548600990571050,11314411342419046261],[13390545111612319389,1205746715804681740,16615507862939638980,5308728382904331482],[7585271640700190864,18291211731480065701,9035414603451998978,870184051879949350],[7259483814939175432,9308379871861495517,9174850034895773180,11667434776828581520],[843411343929838404,8361740330644747194,2332379768699751226,10226462084284657766]]},{"leaf_elements":[4618794660615883416,9313157876774914647,1111704759553604444,8340902690681469187,3014072353295198194,17283675337507834837,12227278924532348936,10050227664628366875,9283682596794853876,14754229435130016100,3149898668755580520,8379821272007221867,1932908800208347227,2747246730953267260,6860456038997535694,16312401245886773995],"proof":[[5373499395545191830,3481043356634564438,2114296793218184836,6653273841849526475],[14915723356401285238,16583073876564518226,7840016811543133284,10382802229919186717],[18143381531024638910,808043248536269719,958770420042928226,9016278189328834089],[15695510957342278557,17823791350685881784,6203970712076474714,10893230762195395712],[16567448744096545537,3732207049566888348,10242330901349945915,15858518909867275710],[2490798402822011519,6029075995711532609,10209603759146943077,3041891424170958311],[5626976220079211998,8278137800848799186,11465004431706415804,7425384378577539552],[9196460362043655518,11124783458111663969,6628625323182741542,8138792676882935518]]},{"leaf_elements":[14481704833980340178,17666584716008845727,9006556362424447690,5910625655703466385,12018543939728306180,4287305711793925693,12852079917614358250,15524459745094602771,10337404720180223904,2196912735314285344,16796529531597612664,15022421287791409900,18339101524181828232,16957072650681514784,8131540312183057368,16896817154965831656],"proof":[[7377616827040124551,5718187279352145734,3459076394803313970,9334456961166234594],[13861428052915354879,6958595065401372938,17861956757320225247,2422553483355887586],[1757108959004317661,12150813522724279935,11278123630790057196,9521192206715480589],[1083676519607914320,4441070181462611819,7752158295056961851,4667463103369543388],[4195745188892480400,1278917477926341115,858660738527305749,12026569133742582051]]},{"leaf_elements":[3042246220767584763,5961267606790053738,3559887806305008337,12317224916301103859,8124994906015625402,10898482425804395082,11052780135917769558,16398846206887122599,14733290436189784745,1767138289286919366,3896055115106055191,17020053650901645609,17018099229898616363,12843003703710192669,3954991896419468685,13020405056681120945],"proof":[[14146218265997383420,8880798799092325101,15074502922591213158,18215518835096624766],[16070927894096146171,7499309042979267285,15222708687563261277,7377423658769375210]]},{"leaf_elements":[8872244034292046542,14961388654118324654,5802056968775514489,18302383666416428067,3933647026650259001,8825851261617385151,8616213839298888053,10450361630528634353],"proof":[]}]},{"witness_query":{"leaf_elements":[10694625122705032845,15435413703750298837,7372444570973932860,8517665981250858357,8912704784060101293,2810889259740544325,15929673635313412766,18299792806637275918,11536093143683935144,10697758522907600089,10231289685377482209,2216109655994591281,2207065624727596658,9960972196154419884,9743494985437481948,9744896179651746133,587724538179745369,18020890614950585807,11121993639979407443,5936374647193580205,3154028560876367060,9111325906483191139,7689515620050534269,11907955401434442649,16118744649284999807,3938880096155099346,6403798534063177197,1336883895639674569,8183959022264199351,13303745087741305733,4867181207153074665,6585225000347256884,6321935575435129292,1041708062066106818,12324725027058752090,18370713231090238778,16790990897380742186,2862922774175986601,8945572965295920083,12058593943025509435,4130071172208189283,4034858138046988958,14201973435630890864,10582240943611992664,5322214767580381419,4269009768296585606,17847454592298459617,2493699058718283972,18131402252471228360,12371913924721463432,11644984768618754220,16545999464556936391,13960281537064949773,4319627111037395934,9210074071893198489,11033132914802922051,16132997106001876892,15053330837641843910,7803813702732506898,2853315362321185366,3930710048093914342,8499464665869578659,3239028345590372347,10093071971067958820,7451625173452314986,2698192895204345717,12801825776196001307,1957553700975051357,4393973048231094356,14823986081752336609,11895039844667842609,14553917808033024658,15027475920403989847,10486441218677469930,4614821848431516586,12648751304254349062,13881865848073029498,18425602132193681059,13422927765965260588,1624534948874206083,11673511167290740247,8837394108723461258,14164247343655706491,17751182771648020770,6165194770015256265,13968405115041298130,8563791114626739014,10084104280445846210,4818062030442644434,1610085658285868245,6878271338422369931,9083023584308288275,6302241884391286959,17257315781497077932,5707615900365157335,1210099866142846556,13611416309959982876,3654652473474693563,4428487151486718018,8658543157154975840,11719551174271371043,18350456206565286549,5533365460422837935,3088088496582057034,17955599310420473958,18084597081160570542,11320658712588642082,13063601729050628045,4492746259902668264,5926142105121327914,6230566002583699274,1131908521127032383,17781141668002841039,7585810690817431643,13720224470724568129,10685717347349270372,2055485996116359357,9173030734917085372,13403578816051805714,17269855553667994217,9624563326277051020,8306238529893809127,14941976413427954277,1421156921618712433,2024000119613881885,4758319101596359032,7108490116571583295,8547975510781561423,10528812492182577940,12477436127450640855,15162308122845885958,5205407449806345952,14754867866736636083,6997659110990768045,7726176509022636179,11915796884217467915,9145889317818061045,10169187416521796129,15312844151624091934,19557920741135428,17448347386333002360,4095988482902273258,6560643870831005978,17916213064994547818],"proof":[[12609338481264193455,9974813846228956018,7218765010501726565,8435890417003555858],[2305100597056113876,3300497752358364620,16012030237259213110,13227701137072425937],[7609750712411903250,16536721640838929815,6695750253033389057,14413671226337611359],[656846122628584609,9786912350041265412,10313096103903574771,5722397376438794105],[8181369437035364304,1890619607573885319,4026145985276282834,9481684325935585540],[1294704517521453507,5307860966274315797,3582323833701670292,1506438934482184773],[10308863999539332391,306495479804603553,11086696735361579966,11450769132966476026],[3034328544037129868,4897500228829969841,14298033702154056473,528699980960630115],[7451686343906818028,14628384781142011053,5237947737754801046,16713662471898068964],[8295587085838450196,17156717130402234347,8108461731675118252,5259445256430468300],[12946582053718774118,10047293831298234613,3443920817643449233,6693964823679067634],[2586822092791735521,8834843648638878691,16902428114822456623,16535089762678414318],[4376164078395418988,5990515358942966867,8406377959014730272,3619687164250494066],[12291427333951220753,14143593920280156488,15816754562106609876,1828761874663885724],[6452364739903858865,1756178861780720340,7926722116732525430,2851538808533012304],[1229954617622350783,223341353737700159,11262718422115008133,16234643667456558298],[1860896835063429843,1652403080417522212,2261129679748469386,13254769866375557538]]},"stage_2_query":{"leaf_elements":[3460818551185147179,15429212797904138234,8547510522737768667,15713389720577091347,14183018708459955846,2674389034601163890,13014450497986515937,8327475244767023390,6611744722858596892,8327708900237541619,13712886267152948159,7537298544300203521,12289846744139342679,9090622550717539070,2850400734857146123,6223674801436361391,15458323860753181803,3035299202156505177,18270972888827788151,15218879257713028456,9379321925378450104,2854199471191062100,14219790565940353998,6013404121560218929,12688931193475387014,2450129483470928123,7061780047399147170,10851869575761420619,15103889739993929539,13900096599267170337,10272535901126522718,2386411408459397651,14282216144890257614,4616052888959168769,7512276202771236515,12301931760644569892,13026108749308767723,5131243460219230299,5827048325367231225,11116897314871779332,11328415084084029377,18361267251824492466,12773681162413594476,879100963861265394,5199506801061699477,10256685064247010467],"proof":[[14085052969002287082,11745746034406350760,3987383005271330283,17113298843088839268],[14571056676666535992,10482020830347323338,18011730693766726607,2531466338849788695],[12981045739245500670,2242388451221536111,15746144232984672296,18287459583402925364],[14529960423385629037,3287534748007561183,3553485220235663726,17579364622452608014],[3605274216926229436,1032521663022069539,3338639776158894061,2897240722460650775],[4099015987544663898,2085213824310480103,7441527292664862345,13218879904731800919],[16679808304051667874,7850435775162956987,10377159519222025590,12612211913675504212],[10263951015730826628,18328771835943652847,13585693522855210411,4307719597259422518],[12777038703685031634,14810648860573847051,4176786337714177213,15553392336433387610],[3545913033294946656,17498652071076852108,1702566927969453615,5454044590594590346],[10648009575814557959,13269355119420481152,6058772493277228059,13983418825103853374],[11182768880860851773,14127774695619698391,8347615224907305762,8270073379070214736],[8426466410608150778,745747923357301377,11954381780307927930,6677200244160644191],[314169300351684242,8227625848223002629,13666910025555776397,5223523005468514801],[16090402115538643782,4207347920785816611,14668941264017576505,6701810227507000135],[12309096360736618859,13017107242388306051,449911114904540476,15134185721515875032],[1323240375839521967,18311725375579224908,3996149533677948373,10325837003394018898]]},"quotient_query":{"leaf_elements":[6197355149834466296,9206759218471795561,7243940878294598025,5850010291520419532,14347636948197174461,2492763786819868993,16749365668470798648,12676469328792009605,4148680357342237772,9463110034577390801,14333821764808641315,16217874661296116776,7371075458474100374,1568332142138466250,6785306007002550954,15377896445221052981],"proof":[[9641466338861914275,16577194337540198713,9703740879536151554,13243407208600896735],[16285020552069068263,10675102736766228699,15294851602010851889,11663423638732102118],[12530880940700110272,8948017060459100059,17010843396506037786,6327658833239139899],[13873160819600188911,13208425836385603359,2394797001834818381,16819929674505526055],[5607098254872089071,4073641159189434941,9882531233268677584,12152821803534110340],[16241032051782340487,8013760186895575878,15116198930499093702,10249364165085578422],[15497597097406952718,10277489143059398966,12912176065849968134,3620195118917476535],[13743450276538682451,5241934087062453280,10172721463375134770,9306801297182212754],[13155456171455411595,16326056743415797769,12726874260946645017,2639028899231270841],[9983825045639153908,3904515009195146724,18314699852939925182,13941694919213918725],[999639527341713227,13023768036665658252,3345288925396679733,17990554643273504926],[15603371281896209830,766988257463729002,2412420855784703420,3445680650199292205],[7075878706272401038,1596977482973950183,6427374398851879389,15822643134884245256],[14204105559722484300,9319682427839569745,14555878797713897792,12278407871291153964],[5770469810202323991,6828195142667963930,17440251667282253740,10635560271304255736],[7045919137679011009,14546525874582766876,15773874747941613327,4625677362883565456],[16275865454186967714,8029517013225501122,10889177156594922072,17199111512595852426]]},"setup_query":{"leaf_elements":[207452225969660600,5427687554199673420,16974415458298310148,2321388089835735348,17251686159133616176,2835529468827087261,17541917584469889113,8337882568417187864,2740920026503967050,13078461199842815012,18076756389712816679,9430392830965440994,7180869876927006193,10688888878833399827,14351148731266512815,3656963533335661210,8650854101795229014,1155407685987030617,7459687382893498862,13746131390450791533,7621977856855615671,6287588719928636091,346165465455207539,17977396192289078446,5891250674975621112,4710741623073457749,2266687278761584314,8120251902225328111,517990435610727688,11565619163785882724,7374141332911248017,11799150355082690830,5038718261084625738,13563543984705829617,15385036359698900417,5806684556005280668,13055582732322417102,12205549490402212165,17775286911253738576,10478924701335967125,10406228055246068933,16815982589595692142,6498689898583763447,5573493322020555708,6482693862957396808,5924182925294936642,15288977984306740337,4859145473829047393,17539438996175284165,16394292886916084353,8379753729356686037,11450195321035035381,3563254266388133964,13872527154289193972,4795438740566117265,1591045316093881164,10200705396079427592,9805041810352134709,279518322068522730,7620011545208515540,10530569684108880802,14174268017805453127,14150010316823354215,7991950925954609661,13626640222449265342,2792915090367818210,10580535948400232470,6776510194760397702,8144377934408643620,6484016309906362430,7775588210660033162,4576681396634025786,15562757177894594609,10324523742239646910,9804979955782837967,10047320519218198200,11610985483246028429,9250125395321626035,18134013128490232823,11090572914983289908,4540659468710367193,10974077110297220627,14200147755565873361,2708863492167215369,11110723609472220506,7445610472410647734,1160136543602953628,9901082350128727386,17640982104574670073,2908980592613849514,8789032001051807101,10276970597385626662,6057264549932843071,3239977516578630915,15447947291519857031,6949897606091415070,17424675066030968911,8560087482087815873,9763067173101178688,10805141328215523226,4875010657204730662,4865356992994800705,2997688462864571389,4833119746894682267,1688831171075551709,10316637864726863889,8601286688308830588,16963175708173620163,9170551727387579119,15559669220051002053,16107458619746090673,8356079023011313191,4992178665690269592,16667388608073726889,14482150154590201474,1489054463577594294,12948129243298466859,8994328747069165691,1662549767459522230,3919075189326158058,4922915592376239303,2899366871319420802,10015502867271149399,2208034021376009220,3637353023786278905,3059535540544671423,5778061339780490479,4680930180178507364,9335879325457945243,14508203591383478382,16240515286557585857,380540675771569814,9927113424995361903,18011085999867991964,37803122282089827,13059480212557956980,3681561345607237076,12908136812941552239,13934543860038110141,2827863866961765965,13663338232558347958,10254433406142816277,14504779601230504114,7820297715019580430,15378108486607772937,9327452582546745259,10685911647189116478,2037259574396750157,12398486983915717160,18091347470927089679,4035052558470263325,541905903361624031,3832026849602519472,5135418454554292535,18058559912049455659,17821821591755449198],"proof":[[16599681312869163686,2364113127210880610,10847052016590438500,16486935961498468389],[10476215678756227827,12768657057873588159,198220105711689175,8765063269059520476],[1874280439904684653,85190859113837363,6570116853641116572,1260125504084655194],[2111290790428878767,12231746653631789321,6141869720868953738,3827672502407345180],[14518390964851257253,7256986107413792991,9030473851024035241,8780402508882594234],[14638240060798989498,11040192724330913033,7833209131129155233,16797554768603621288],[2501930212603375069,3428523314444396832,2929190563252044338,17395198894371005033],[18442475635479263344,3416601661191730746,11079383150540617227,2801629414777914760],[5060816311470970591,6412210348569892614,2839959648520338227,17974218858731409711],[14976450825122221750,3087476118390323911,1934372378819178179,8614741180176154783],[15315075426922767802,15816270822731043267,6733241463626122329,12666164223106525346],[9052239811630029981,10721503710718990725,14118483746718468864,10812281038364548972],[11580692838152896122,4903381390695306531,15329290656176988946,6355696142788751927],[6834502183052887470,7438138502159430532,15340062845401937389,15750854749909169435],[6039978864776414256,16684320486211577709,9026253400374827822,8420414771758402186],[15030528263251317749,4242853461917807478,5327545180277659756,5783458376097386022],[5614327065933285653,3328995280875371920,12239808749654718222,7079628069834605315]]},"fri_queries":[{"leaf_elements":[3340459941986265228,14073431188426675943,2845703833222409150,4671146688509134465,16005394536616278236,17400827345182140565,17325443004549057411,9056009749096924906,503527155149659128,3334204974510718106,3821684304225216244,3538748779794164365,17155464829547966780,18374333619996356220,6720248265485452231,15120322926237567102],"proof":[[9081593118397701767,16496110839730498176,6497415019729400879,16155403618761414],[13667763554198486565,8529792139305498021,1567376060786232385,16583891430115472574],[14514537994758563942,15243636003445631788,3392309036877027959,8526932501475002799],[15019736244918019079,6235629854849498610,7529565829295508899,12186726123555883246],[6356354109727231100,4604121027889403380,5445433216933850479,558288587032584847],[12697392542146786039,16828091090380181902,13472405762341426359,14884283346976007594],[6115503946789276427,2902654312931309232,4219473949848323733,14705378403020468047],[13010891718071351350,2522051920581390091,3364098964978172923,15637005309221906595],[2456463779169345830,2918227297008157812,15795082626652232615,12123166330063290137],[15840722814380013373,4721402378692427449,2355497241945891542,13528513670126263529],[8560492275278044878,10568289441027128613,17328443065205705181,3655807956516547900],[13404339266993435877,4332252777298865405,9856724266266546070,16899282398391150462],[289622834953926945,4739514746218542285,15198284630534844698,308868212001277128],[17617671789936036600,4392943681491727174,15270466481397815535,18102028030276323478]]},{"leaf_elements":[10010358067937179681,1282231318181759473,15685348745638010727,11445566581934429399,13390474112534953003,9740052464809855065,14825958858629447559,638214084395051585,17153610890844809109,6068190737486602006,11987198405828402516,13599093130472517776,8261363970749835214,16574725236688538676,17595478899087508453,3995988901176123949],"proof":[[14200433060080486369,5870162261154090569,1487505522808073676,11564522400650974273],[17178409533455611156,10907855624866261932,2990016981359299717,9927272940259330486],[14885729817246231654,7905542084983945578,15056716002784152394,6116369111660789430],[15989334698098545984,17032450511061275968,9023248599642081433,17014851419886439740],[4805887409021734973,17147535220288918525,14461836862428812370,1205028800819661793],[10222200582095220024,4111634849148733193,4788592816092927572,6530361211003854506],[1770134628451972689,16515921188012379855,8576541939753560900,17144953472761302663],[7230282998573795132,9629761181122219322,14599007984800761429,18301831816549182067],[9094650438710549659,16451800673743269156,1843716998759769020,9588207743298467001],[11958482329582428009,15538471351557630709,3219528826303116237,3257572718844663530],[5204416224914363540,7631047996102225273,12862164145984685228,13063266225627597449]]},{"leaf_elements":[18180772154783583493,8991960612663594502,5519230096222529045,15638238486037190512,5427070446545949445,1334045270086811526,16397645578709574382,8741839906053942900,4065476544971731928,7563595231667516350,3831325623379634514,6344635531813275547,11416332813008298808,17771446698509752238,11852160703555339382,4166653817794241787],"proof":[[1231711392857488211,12436222791525703923,5176399873770269717,5757489814706007691],[1843084450744426070,8982516176527639456,11986921503028268187,4483714831884928096],[15436513086412369434,4695888362172436307,16251143772144968316,5876725163727239834],[7001684638848180204,1131195543195432189,11403073717585311287,2454804883197649861],[14794427526234257921,18170261130764571634,17203990904921793779,9358364752463364018],[2904150075492521755,16233861083227583404,6394005426060411307,8278398605433684976],[7923242251352242268,153381576576218413,283295221810991411,5920986221870284012],[1770868264315023480,7812579801998129002,524698746031729832,10714744940176785641]]},{"leaf_elements":[8144812684358138151,18355042793331376444,16189404143445113330,1773423536310652832,17444031050051202459,9211016860704544920,6683409492677438159,16910794019930177036,11372493655992497328,3191204758528919027,14521273895053216897,12950668261594398734,13991504443848689357,11245406554501780918,3569607905271423114,4131810234173212773],"proof":[[17985086537833748285,11514455672323888839,16773416478208502891,1853972609592565344],[7362704330970818462,11352252513910447505,4936396231872657782,2195413567298870485],[9625151127912515707,646542862591532542,8987038982982839040,6251042702593306980],[9311433136140116046,16167901788318774094,11855969264015946040,17556600557244386052],[2352908338701448330,7592253344295024086,1427121771405932881,4783686535469269471]]},{"leaf_elements":[18244009124896738654,15821622001502255422,4526262099698427938,1137283563577044944,7399610442190683406,12795036314234496782,7643474175706283426,628413751515727991,11347339693989407834,15219169595640251979,941127248225816522,5008726223019531335,18424363597062449628,3398189034668579268,2494450716533549696,8977557539522968157],"proof":[[11593867865185666648,1242943260614570549,11365500542001986185,1045360922057259851],[5266687653515500013,4022039819281218887,498832073896150918,3983130288007996505]]},{"leaf_elements":[11907939937929050222,12199976274714464765,3239066403731203959,17951336118807113373,16307121117972480027,16234899209723555345,8364706858358154655,7274458572308793086],"proof":[]}]},{"witness_query":{"leaf_elements":[15122892984068357855,7510950921576269262,11490152320055381972,10911837218955071411,974673941454690463,7528074822007537961,7332284674077549129,13942862170175337582,8680440237508707986,15775713007685362597,7838538861694838486,929758039751441826,17209622511075758647,12121169118462216122,10113105270917072742,3087322670301712244,14460443952263662809,4135909587229251653,7272807451009699569,7876882957252242055,15986884722720574691,7457088755585624738,1158984085027416310,10707367320635545063,7779692648201028540,6763568377585312974,13612606062908746312,5963705218069173093,5829160725969189536,177118459988503244,5689706389692060203,11354886051413891434,14088584147729531713,5899384637674368170,7122219434545600062,12060944834277547714,5164548036286138696,10167374764259782129,10973830542349314788,903851259072477347,11674628160948366209,18061813485642488728,10494213505006415858,6519414311783829346,11638950200356218874,16168782650190660758,1032551089137246130,7128869429882584271,1993795330834169974,2542894319930130296,17077000920747046045,10630679878987003655,14963247298741362900,9371862043589660456,557361121995652960,8941644900645449164,10524075744861037319,15787231153563151257,2417162545551210485,8275042411493333833,1281426247752430409,16342148376054019024,3427073406253794324,4972616120759935907,16011033211829516988,1978308583546807177,15493018862709790895,2865269745216957113,4144770286314951750,4438465829307770574,16093107235802752263,6702461885055926039,16002212734791937716,13415370114521077224,3321512926406460950,2216332853752937309,6578641624344199108,2187264303832309007,158831670779849475,10123555830777939903,6780748734014651859,7591366637246357433,17605953238271723652,947417440760936666,17342969228904109349,12991154546537180259,1698085537720366812,18316701171064739217,10708177921588848566,12466298078617083951,12236324432482723077,17272060610727382329,13215216370629145655,11489657041800222097,17972036386027000349,16695887774477638707,17222293937841677506,13280688687419017361,6799331344177755581,4703858771946701574,11258494465316751432,14342037133161967148,2469210561620433837,14077669337691303463,7723840842853610557,5217399615779940343,3366502072856244742,4475855794726159267,3799872367224758009,18397244397945923716,10054600058053161296,9861391546429797766,15423289843078594947,7950638428664728391,4981816893788482923,5081177020151602225,8330411936448784797,69109503015658984,5413337029732638306,6480289613897858323,4286518278043745317,18029685450005701192,8680088328514204589,11963993105840698822,17271307040975854299,2282903232968702168,13702616434143016401,6690740890477995474,1777043313764961169,8779646140978413083,15617110854152565688,17889475942625659378,14246575943276407530,4257179393936748154,5760578621291666493,12348443832493305137,7565610365871499701,5529767313420855535,8531107671886341882,8540113302478412465,4834992602477560319,1504416129890168652,2719340695106558069,5190157411473187432],"proof":[[14465073304364328497,7978222339947231195,11239900156420624310,8598768461481862475],[14048059998262499901,4044558588907840186,14392049900950688873,7389221374349754301],[9809054666855933843,10858987221369508374,2076790923388725599,7145598635099978746],[6287647607882402220,12123650146257949031,2534954205092329967,6461601232422427355],[9796334231081505326,3139063803965033235,7316169012275903358,11409118429940962511],[6320255940967729458,15655894032973672079,6149059052457559372,4111353425201433709],[11041523610138613020,8293438516247256284,3590892366986605347,17265751315487885741],[14734159478252488465,18021405272252380457,10924415770882177039,442543648397291001],[7073244238839035610,14182906448073212184,11506163468295602941,5014431398032762794],[15613017847738336909,414883985311504695,11427429647445571536,1314335602681637193],[2349694023644640962,5241666680456819629,8098620003210322637,17422674576466282573],[18138182055877533161,4873652570819175864,15051858825549555513,7863436806602409535],[1424020814594550497,17817986876243262875,1794934357715930108,6721263199355939871],[7830512112922339996,17727495682694563546,16997787868208962838,17482795724031522200],[17294425535442445052,12480806441169586766,5818890119747378961,1432714490823942251],[1294507834402425353,16204177922238609611,4229704699458681784,15747956095913126584],[14867216664302836752,12562456856035097602,7756423531439073568,3128883302367687612]]},"stage_2_query":{"leaf_elements":[4053743753485921624,2381236633852193614,15766490026972031408,10520333316381775405,7161695139586837193,13678280942563359968,13273492665040396792,13354138914271268692,1598536275024978836,2925894874577707334,3950935297159080027,4681102222664263111,5013701981451080252,12107640854533420100,1221669248542679358,15415013115953019647,11647044240309119946,3260589575758022567,13243859029978979518,13312245355413731727,11852196808767004683,5793054154631582161,3360691647522303046,14926289631471109048,10421513439677607185,17070233657526421614,509981602949693556,1457912377803260638,5370275914283600722,7748111034049301258,17146242990296690766,14076988607919414005,14031094153075193818,3671939402801620976,17724284031143431089,2755895631099428939,10275387804429069988,17847293404848635758,910094466535988056,9710226407793863031,15544592811082684706,14556676947430256713,1695117862007908003,2746216009504370868,1619818341602686650,2632892574379307882],"proof":[[9431319553125403639,336986956161372220,17717093489774744165,12275488747428032268],[6722743187109930480,5112114118812400705,2998466371628037359,1041176959864859673],[8026702607285164836,2780262061811463331,14677190727377578521,10285177096170240691],[18185499798227496064,15257000360649866286,8116819800001848926,2173870696213507595],[4694180555826430982,10009154364801352088,8301965567082384187,16079692480300506056],[3821336532107938881,15016725059584367673,7311564596829914047,18380530576954989422],[13302814737985994341,13446694595423574505,15682549049718646376,14267656117841754937],[12152541663144240241,1890698013532407577,15288253192027141013,14783617248337434129],[13743657925829501654,13829169205199958179,5370016213759219344,5633339876935965207],[10520354001080860133,3964867749611612205,13086101343155287754,16231544489032314657],[17714624634191750524,11720765697458406863,13372342399022451408,10116292449986316229],[13438245925550131334,2423506919373996039,10548376732852628975,14640865689409659259],[17749443221138498240,1233477747636841226,650570969541830478,13292940951627419591],[14181648138000452695,4439891763590443290,14353584496728962296,3511803597912328171],[6169289834773681393,57618648066870099,11698174259869823384,9712874366755944831],[7184898419626512862,1264414065077409862,13227383278426655158,16425363301641612764],[14260353508351826515,15997840699848638873,5926302242716405762,16396812349572820247]]},"quotient_query":{"leaf_elements":[6769833709440493090,12613998709478918802,14952744440399082734,17534974351564347633,8915715592815219804,2149931959025215205,17823790269636617522,5424792298850819046,4583758976522269701,2215159383561467652,7172763316978626430,9081996609905853180,10072722933608918637,16336740415692635236,2585031597077995349,17521947272871636255],"proof":[[5954517313207737470,11968858482346536792,9672319153286545849,18275293027153200059],[16974186401015713028,3223734242350640263,11020722366966261497,11305005735079691553],[1572663471651808543,17431642742276667740,6590477942573763251,7277112892475302850],[13130637218214409919,17117051512301565187,6542709379073662101,3666233646267801973],[13803841783164339932,16353611657861475777,8826755556094602093,17425174616263186837],[4638955537976798666,14943953164744699069,4346451230570895388,17863208259354877392],[4873338341301561149,5980407633702229921,2720895753422119816,2997300397487401061],[3487585926357177604,7587009856764851413,14647250316850358355,16078535613549977979],[11360741839510752949,14341730542851564614,15147654031634875567,17270053843960314577],[10699456838957545282,5082479000794145227,10826012737916280380,17703320076741989184],[10371088718489807510,12578434676580808443,9134089739783784944,11504958059915684451],[258166858981189128,852812390117576887,10764146268224916942,5445946175865010004],[17056975834481798907,8615041943826679830,4212310171119813609,1012216295167726999],[10977195814046321701,9643417974694517755,14467879213488440260,17415146885645400300],[14891135157739581636,9864004910349528741,6715503218577009184,10049679523254750449],[11412373697305413293,607638771155614381,2963920969718945259,16115524288733371694],[6428516624234788705,9287937350807014828,2717092354687218549,16008904268343540721]]},"setup_query":{"leaf_elements":[16640513195230017339,11285457126243527687,5674072914507120185,17477557922719082915,12985690046720706437,6082924529768941384,16064440694109791131,7545588424424062696,14399291090718227008,7650316187872357480,4324967754257550771,15656527044640715758,1743600696142941458,4596218528598592183,17574856555673951046,13632297707585323196,9375150984247542787,12016523019686335226,17251968076465109908,738870045695724579,7033132086142911013,8738319881858341280,11990158454625969278,4000751781542374796,8585456324366395809,57620952351863823,12713619648156690703,16722550714490305993,588018621421866000,12101879083349726442,16515313774460625116,3467762348828555720,15944429264054749316,4884917622310647921,4857719054261324915,10530706108646454737,15800590225676044491,1814050434710337755,6841071965731568696,16105169312081783475,11519195590520911206,11700995156749402943,9225460213413741381,1704046563627445779,5989204081839799378,17928667712308586015,6938456779890667388,14566833600895386518,10459778565474207044,7139305115025517016,17720856659263704775,15664291067326745812,13565107220161902424,739355725658550624,5138361025543083675,16032832247750046688,13202961543333119709,5559341072872051298,5923788499641673684,2442302312407514914,3912079400559828162,12091537840358140438,7773737765943353546,7018424503995214828,6952214623714614347,11600496659652947232,451672079244503844,4722163485561646363,12356999828194171505,9761023367480525727,16146407962638494715,14221089572046944357,14930782327221930805,16977010906719911942,15006484267247000965,18243964115326375110,2993572918622700443,16804902553268200878,4069675700285649264,14622313268515050513,10348008578453437130,10830845262425975490,18212175288186151463,8458483077818970551,13797477930689149747,9982153289399690173,334563297253108330,9458802084987046438,6745796295358010584,4994766349236596046,6222515157751349709,4031555799238680100,7310683033400608870,14902278886684964362,17603225412447612578,8752319508586082048,6853813295444477485,9403373232694198513,13087421914668427188,10072315439878007332,17759851977281521560,6079467025721897181,6812086798588713960,13392177618023221672,12601706416388147991,9011057291507663463,16463298962401220357,18115934202524332966,7715138819256539630,4156492399296201718,5725979394040064413,16478108048221062331,14163128121755783930,9902950835359395449,12026732261472394287,6836761134107695323,12739751324374507276,9443125305610479007,18407444936133454651,15531851783778393936,8754506708505636360,18440982533783651510,12914458885464767513,4812686143194566124,17187776078286226935,14781204392054470351,10752968449447119557,7964304141299031712,4368538675183677544,17075736515550325144,4755020391952301972,9630383588092450921,59586803363357891,14725363611221620037,5538542051581618911,13587451838754991040,18366714978573338547,10679794871763764043,15955473280481820219,3188880207254158914,12274379024485161081,15748853286151500982,6969155038524670545,16715077966727190722,9289912251707154059,16326668869464283280,13399151945769352441,15088275302945712218,18170016315994319059,4727493681830683453,12380515443281161190,11048962722241543727,6307239218866982458,1562246733522825938,10473223199033834330,8767276233970022262],"proof":[[13034702605422735484,2006233769560509466,8028804706497454403,15837404314827461058],[11777970871698440928,3892794353289884470,18422322265284940953,17231822916682722956],[10622634454438825728,17971284448810091319,2813139538476121760,13215747321921151917],[14302272764588579154,6795596447488117582,6652756347568536475,5095774963308833347],[7950240734947098164,5458566311508612913,18275107015716807830,17133981115862797103],[986640527639200128,5641897788425134707,6835867128903000452,14445710731855328932],[2643663589069169235,5140851145148377024,17224083681748925758,9328760446716830819],[826541210396743588,6644752354727185662,151028887856699280,9932692475093042408],[5226571090336864308,5140435549948968133,13124246266018283426,5246409763759724604],[5357005256645936918,18311275656189004918,7804196485458664027,11669828268056227658],[9442792791995970460,11334355822359853327,5560289076345397633,4857635885374417219],[1688244309124362418,15113653829726799067,14140667396822404598,8916232447129459940],[2066528436386449733,12160276398846378411,4948617892182681374,5691506553827246876],[17918069008151461641,16668506026658527897,825158808144946833,6390989135336452622],[7592977187780002359,11573891513110662584,16391823540749713140,17115529487235681621],[6865682747942295237,2640699354757576495,5356019421211970945,16171192827922680647],[232796533062090112,4701081437590138433,1090891335699248712,16484287474631432090]]},"fri_queries":[{"leaf_elements":[4210844239250590283,9124211111145283561,4946950579834767950,9781207514396785897,17023693994491900030,11447845727043128263,7283389587069438763,6319173412469944662,2745879066915484697,8826777616053343336,7356174451768639903,15011468706188427173,10002590963169989194,8293511183199398798,418471899559025033,8393190543679106357],"proof":[[770323920895871969,8095671115587418329,15723269227088635423,4907747906933410387],[5356260498759291814,2736609725893620290,9210568227462452729,16949680882636365694],[13175577703251099221,892993144636797489,17629844203729932045,15546459579852587870],[16816948764878765934,17544114378407072739,15934129296963419105,2067064280452829669],[13435201466035149727,10465873173187068506,10135722943018491404,16637900350022899989],[13423121648241078066,5922330152752277798,9100623561788307491,5530433435503955466],[12824591641926724122,12938199467176859444,12838230994150874485,970043067053336563],[13631979299970994546,16780671701236385030,2467570095074115558,7143093259535148429],[541526577297823291,5801192584360884840,15427571937645011471,6557488543484443382],[10045299271514711650,15081590911429675606,11624199795153134771,5174650653241416636],[8721007244176784277,3935998281826298343,11968000340873915575,5347802191942240058],[15841615307890707508,11741981027275873340,16422338017098754052,16245466416320235471],[17273285503999603591,10177253992953865211,8217584755969497320,15867568127220932956],[6169857227742315395,13357582364418817607,5697734732019327995,15965541982362316595]]},{"leaf_elements":[8873777170073823632,2409780757542445688,13403644611196443351,2688887611683520431,11793102957949324487,6445262184943608360,12626933532155811427,7155677384261962870,18211765330651528645,18320204475303328284,16909606142756687458,10502601767799887563,6985579702184972522,12838168080790798200,11694275132746443882,5922616524384997815],"proof":[[9903126374388188698,57736917760915518,3387220410569093317,16170033576620701620],[15721465539353745677,11483181734082765026,12878813011889192180,182710030285777569],[5017171321991500602,251401975233120169,1130681961326035238,16951128270338554135],[18190648603693008923,3395590677151915630,629498144025149463,2392248034765922529],[10292178002799904566,5916749941733537269,1724194352762339947,1362467599549150031],[8682245260074500668,2766996181663455872,374233244521899571,9091211715744293684],[16625921449508988952,2013005936336481083,9525854676795868759,10194386175808620021],[10049357660013305908,14736092565346051943,9292284334483204352,10056355569601737584],[10667134333040399908,7948974503532787875,3628902065844466516,16344184403121613474],[10927911743046252519,6833170664210277590,3692697648548970700,17144118840444395726],[13767557634651448597,14275372649907910762,13782730872602003299,5632469238773170118]]},{"leaf_elements":[16536207293096642319,7719702466604677106,2981534493068704356,12547924012794661979,10047452675912452512,3502091530888782294,16840779853470722694,11336077694738665436,952456594688716420,10942019191453766809,10989092767484257007,1736670110567440761,10660591538491497349,8811906361630234185,5758871087185208693,10941178034727985095],"proof":[[12483102579689525531,2854819513386793810,11032498651970060978,1090318677121503059],[10880194393260848752,2413487857367911848,6694566962354018687,6871409646376273702],[9853657417915281539,4496046438724277043,16382168231817875509,16473721940994526799],[2108233851444949126,4592177370753992029,7869609306362371028,12684260506222867789],[8958005049019199917,16809146236365067097,5867518805517639168,341859456494365325],[9358858203977005388,15373214033532230192,11993490951110065123,17224053347372938781],[9116490056091927865,13726436516645210939,3431243528066806060,6303056289232439508],[8453612859827862692,15597950537987769407,14607321109355321458,12321877943907868015]]},{"leaf_elements":[760539641790273295,1126337535605753347,13365162706089468761,13932399342038820538,13995911888457789415,6315534762851300407,477734570562242591,9507832482130338598,350381960661119276,15775714281211401761,16219633958831711721,11207594959205380948,4236842591151879149,5987150912493275411,7786648885084621529,2792718767833046863],"proof":[[7611547625775133059,2678969031648796713,6610071549768901935,10145628511501425195],[2175181166789080791,11436883777371966934,2629741338880206547,8244386934902679654],[11785958964047837968,12807196129256974409,6332965548205027132,15885719329683082130],[4289192467471052181,18369002550090439562,11219815209708029570,3336049208401170456],[9732057508331218338,17742413443053399360,1687316217664623535,7873157723082167597]]},{"leaf_elements":[7259499866529922001,13225902794735727321,8151805155221039719,5815697995361498519,15969969849287416935,14361666091342391082,9015431517793438017,17120277160163954276,6908518412257082109,11977506784033897926,15749807957236746608,14703936824606871060,10387693752753013939,3493248226677078651,10750858826860075918,16559169727365355807],"proof":[[8258925625237069139,8750564929345660371,15077161300129307211,11233840805661625877],[6156120735936047017,6378596361573101966,12234030277201030515,15524298584112405956]]},{"leaf_elements":[11907939937929050222,12199976274714464765,3239066403731203959,17951336118807113373,16307121117972480027,16234899209723555345,8364706858358154655,7274458572308793086],"proof":[]}]},{"witness_query":{"leaf_elements":[11893250198572234067,5785101739703517835,4015198927707950357,2108970431023797308,14191120113820292350,10429244381509694170,4317009947746826818,2906550989979104529,4675183871029290820,226207623094057509,1158900504431004921,14905761383042006259,556827569786341845,9991360889732198176,464179663547852229,3342773092484661292,4010632933961989422,4891302575717401509,16781921649454190120,13606362102255728305,1995958780913376567,4865453954326406852,8944661914417433262,5324340290735358806,15905427644256615967,4489806424484292847,12361532518802169145,2056723549775254408,14100053654019507036,13663796791833887338,3869514963627883638,13943037908893669113,7358386830091233042,8165610445393246645,9036599996034260882,10845199060711372949,13270578509066554040,8449930962715542842,9127450776779161781,5180181547818364628,14358149618965858942,10432562564502939531,5445338297111803843,4768942700971508061,4964609909231911632,8425361084163421340,12903655806748345466,867095205705933786,13621748557773238664,5102941713145724624,15424057056512487643,104956713586108635,4645737982000393586,15513877246480887089,17933172326102163330,12767583672029624037,16301964239854642266,8075800325663484176,13569446596663525245,2494424724370712011,17877571804501391074,6442237855541551960,6264069292526265392,10119928246937621057,7063855390882498906,13856428273889608508,756206633992486942,17386743866965776671,11937466783620632183,7119715175081976667,5966259920251231418,14129752605115317677,2480947763708879504,15646786594849357132,7621607303416409446,271189518730002056,4028555879435394568,6488787984453975102,17771615382948836803,12133047460771904744,12314950076252329792,12231732738282548490,18102583468580878885,3966436964721453910,2088793428795761982,16087397256852390634,6846944257162791489,9298297386878178509,18273344376616624375,3640568690274784166,11150395732823568514,7228061161213405643,17559382259507922274,10248729701130637245,17616139387603114635,474388124136003252,14879465596320998814,12326951668677242780,4860285205426824993,10409417338184904557,73188558144696745,14443932527565211413,14750878275428017770,6159945358357225767,13176905469965411371,2289355110525518182,10517301315307152260,17083405847601247711,4431826205385652303,16334257678297239061,14455654800035107019,6859058624316233092,12041579456631041053,13035794259444182926,9238733878134943964,12978091712038610303,13901695407048472348,11516000049193309893,2130216310860652536,15292751591867133772,7381613955458539896,9424055385870380823,8766102055370683493,6806125133212915472,4081956732881058655,10188193027915782083,317511773813589494,14598422816498429092,10330405631822278954,2814515076276943245,12910795116301531904,1238155850826604190,6095490981144673502,16132350069284114568,11374947964045665805,12793709906029576327,7111602596121569448,3214795099659495574,17781236229620787569,14636977889975354369,11160338198229938152,15168486792141783039,7594860908004660279,1351839359005280728],"proof":[[3402891115924955789,11344196951516526886,15957250680863663714,10757294324687639379],[9736092380250951769,1371788839035255816,9440290478288243223,746677788623290804],[4399998551203010499,15080044517383459366,2329671213717066250,7812201010557604263],[18239232302131278350,3481504465614848512,14527661745362020385,13705456071317341898],[3336499520759975478,3868986672646970858,1960999535220664469,345483220219329372],[7907135840561271275,14041959844965997642,12605819179542444225,3710791459800083043],[7986099791944617161,3835942654862924017,10794025393391685153,8884427389868334846],[13452805955544669499,10226780619500117289,15187083243421818618,14378763982014926063],[11173259050850729441,9519069607876478102,8806148522700352466,12081832732130920832],[1952196908910676091,12198849385270008181,17493624442322379793,7502212761325848618],[1165318859463771245,6985094744998870761,15851825766461307572,1556507897172227927],[5722605052077214467,1402508686477654933,5121837574828788143,14602552014520298266],[16711192004937073893,7812945539203058736,12235824629598624857,18222678834960857436],[14642826941721830992,12199323220814497001,7619709942261643440,1324529611099754234],[499601021688771915,490594726026214526,2436752795675718753,8091982212759487229],[11527782358675222967,7329642938926174414,14341101577487875752,14986603775519913343],[4131246993864415573,13941769014960634211,14244756967470440488,13400230066119539514]]},"stage_2_query":{"leaf_elements":[5889207834607629610,17253844067669163545,6267421529277563974,16511285875546776565,2621381465339340949,8445091068291565590,2415099853503348714,676098470209744954,12222062718917551527,16264234842942389678,15762214691878533476,5813563418597072985,17448815841198786432,14540595227262182,4616323249499092573,11254665320059291642,12215791829031463310,13744046394915969396,11738538654151043553,1612555728011255126,8425238309459196997,6871523359071508578,10749572154469327179,991990387632538520,4030183527816632057,9756881199172712939,1323873887203794993,14655945847954479038,17317237654639299315,5743413091971121024,3283144203212621017,9925506708288304163,10397851753149027044,6570493042884954808,175941118844342799,5008083848687450803,4510275275820928675,12693973848816621079,14734293077416459922,2942404194435233884,14563077194574379430,4615327048630921295,17414811780697680510,9242866920989739275,4805576462009924986,55253309953707811],"proof":[[17961935250301535779,4794312555646882811,5602007999641536367,1473013228668077514],[11933284138949640424,1002504842265919468,4015382115489245748,13369077557280901691],[11572266897886491693,2973507932418022825,10401936541623446560,14671508962395492803],[15986802375571615051,3350296781589152061,13179170963856513528,7054370599055959498],[11502620159579868886,1652672557037968904,1194454867672380957,18255280321431396123],[7347396495178030893,391790261161852497,3955106403224211353,8005896512009458722],[4173812544920369646,305372774225111491,3455959050478804104,10423292243250207216],[1663954229137335566,16142706423350347511,7559852483651432244,8215205440174092272],[11310038561318089417,9140249375688954875,3701202354232582770,3544280707292751116],[8021560052786597944,17628467597804717099,10999757291428136655,1634809082668370098],[7056048301336219885,9045366418906464016,17687901798320164686,1064085512966815875],[15113343032582553054,16239746883584949394,101363299843937069,11886461571387363845],[16598715099807633831,791292817591699767,12928270581987876032,11432526976877124495],[15457821812336345357,7746547016285884839,1290081010883453512,8948561470809249257],[16223035612808764380,11332721853906273158,16464367561192575616,10150487068375660440],[10693398880102404674,15442008528330274585,5658332399759345394,10702521366286461221],[12940350048878081686,18318030771015011443,16734511954444878893,8710777237650930866]]},"quotient_query":{"leaf_elements":[6731878554435173989,4496136357299490944,17458265350131095605,13871628729112439337,351592397443627972,274275330576301962,17382950942563231480,16086322220286333590,1420863862177507535,17552714348463150583,15760822328626606666,6613640771631620836,4119961839923448453,1635704386792082257,4392751408190125652,7139427469283878208],"proof":[[8258607900550846145,8973999315688884078,9843969051960811567,5580050636061022574],[17157818413776605767,4604356084118639430,13477697211222971224,1121676267577597306],[11364006951069303713,12642082387966589626,14973241035265026712,5262143795315819311],[14047898633423023790,10220665512171216521,9008876609040743189,3512812502893549140],[15436103688890430002,15128229378405288586,4678352344068476343,17118358043370239022],[2254948396379238393,11415806549222242508,5756760575677282436,8349440830915382061],[16088043486650329191,9482072911033157701,12876201423186583569,8962628468012705712],[13776540228891054106,11689472690162071861,2753375366421836077,9775407830093078524],[14059818507566178367,15573778203447861356,1505717364437100978,7755145916037893928],[15206501023358108939,11676170462556923292,13306797135641258165,11755676978917224500],[3489708648531000249,9640786737564471829,11264407950795618625,422105174339763620],[12183323203964318038,4850685647594497813,9733326394203155138,1073242966308461998],[18185391110668183143,18215760411189788847,6673327027046071524,12923235176070648566],[13740077252299184982,15068673551029823094,11228632027412380143,15734194994631345399],[11529839688148445478,9904672654954967038,1533087469050591783,3940373389184848924],[1920978485513619324,11039587626305768913,8541043003930432246,9136120106669000367],[4907767893259991028,8054542250148444320,2777251878088069259,14509779907815603908]]},"setup_query":{"leaf_elements":[13154496149533867838,8789273921160555331,18163211508269329848,2352577425549236855,18383893595420327340,15409244299452257302,7503224256242843155,12335563929502559883,5832888429728381130,18032828301672343313,4666171284530065118,13575390247271572254,17254804498720794213,10095047446545134463,7431684563084767333,6850739220980250650,1448089003926699729,10578810569873074030,9291350771098525650,14463164263530851486,18244835787644887623,8178808837574861599,15970288227266593349,1043072834285471193,17098184571757625710,6360564042364925526,1007605418959716615,13168300975710299867,15243966875139432255,2639781423504306572,6043633866862433819,4647303773949956857,18425068334807662732,15552413189426782990,186246518661206235,10768500419621370514,8602536485068998495,15923753683291560609,11266132712719618007,14257638348561998406,2281516734694687921,14293726560392887208,14209299289771417168,1826363785880633864,15324729305497091212,462780565639478109,9971678981572352587,13440964491992001360,4778426728986963307,10837247687734449259,11999384493206388746,7189260258190690303,17921042607637528146,9315205729400004594,7553307781799772291,10492747430270168153,6631190879608729748,8411522393520472154,11929899953670084077,15950045663574599293,3185634473365518780,10813060056565417965,12200142977752702754,2715527813486415507,11920902157465459322,9703101610042232086,1197061845316676752,8739291450473699968,9201221287492015341,16751772982319248810,8382426144516112942,7740251399378319929,7492235523240108570,8428148840945286834,13845002426931827465,17838925810522718543,12418019319439379485,16231473370349719757,17338977023419563675,17579279433426270013,8524988406293038270,9164454113551434388,15128736409147434195,2072097452795732165,7633081574561919272,5543853636355294364,1891090580358877861,1107120456006935464,13031514469636414276,8949690664884251946,3495262342565366291,1811502834964108565,11510791243842285810,17463890593845949398,11464252643641520057,6436713351421936085,6513105382385631745,6453574919676079207,10502094771236942564,4162701823688096025,16262114676589665562,7355447846864151742,14764878469643367317,15713592245270123614,12852606821880043246,13950255032844483087,62913614173122084,17369440642601613915,6575982277420186786,3670839847447253005,14984287356723530110,8420048840869204021,16231012384910582912,3367175332221009544,6403338550475256985,8552581112601833369,5094498216328055032,16045755416957639797,1835304442397426073,14949083663923007527,12256620408443694442,7361128252830121437,1797997474849432743,3378661662127321730,12119299680945867587,11185399716474313846,5547554586819823723,8918727827838975390,15112300820687134253,15282427621922342878,14852360687577870354,1833180214407496886,2000182174034887523,6112880339651631322,9733058632672724883,1674490501659967259,16388322531708521260,1356397278114660316,1130171837584463416,7692232073999214708,12019171232661249419,11920937873719204830,712240096131268313,5918648216506767022,6053043583169244318,8715006285088863675,14101666340162436131,5336261339236633320,7444612686760838882,10864198715039250711,1793205194021718257,8218194828429968611,14028822107282323118,8478533783624109121,9400050542368483358,180668868990494882],"proof":[[3707273834542366324,5179313108341667105,11847887078731645714,3707690688705478958],[10963950777364833496,15882361319421542701,14269403187402652739,10841079128836604749],[10551150413187861279,13403056558447091764,9174078712388692504,8911077517591673108],[16463334315451705268,14674281642296900249,3608812956735325957,6704969819836857560],[12955041497318552338,10192450310704695847,9057931357860363831,6371294575204847288],[12968798862557414799,6325728488860904366,8873903762271705037,11073006849159236753],[14104088556951229086,14473967610291007523,2033511205539602718,2506651904179321678],[13741449141673946992,2995771552055268866,16740215403745739516,3378836250532427598],[16584366991905194993,14628940017612940025,594903598368071114,2083037429494567551],[4305578458677048751,14533789797521258286,1234004640724352841,1462535572873037688],[7795241134433420140,11467278233165750258,3858557674280080496,4092996903260448654],[7585529823896270845,18228836614042091693,9954237527725191825,7422874656894769320],[17209551076106149000,623414069502809208,15701950207712034025,5427103313699549425],[14934602439866889910,1958290372258237956,7349388584616373206,1722421424693135390],[9553734045390339084,13739943575955771714,16836990449829495936,10396004934391702266],[12126118751853742528,10995391132364676709,13052548977393997118,9094159610493951972],[6870603959408415557,5624116706049520422,7652133964888741811,10524187432264972050]]},"fri_queries":[{"leaf_elements":[5760231109563908334,13702064761108654796,4661774965521864614,7926059427387866308,12809363381427795022,866403360086534105,17846342601054036436,17265237390396996410,7520738204961300958,8418902881647612621,14922010315153765456,2848919269508807067,4787725437660543415,4403681581162635564,1868426816594900613,10484720799735755025],"proof":[[7832188966127560190,9956305930785212389,7279921119308528986,17748716497701977952],[4050411908424968650,7704847096686713754,3706235032453252441,7461086667642627610],[7822694663736094653,5660977941508372758,8273046792749717407,12862863433818734319],[5059168900341929153,15446088851739315477,18006804919810940784,4317154866318924113],[7942952175040555251,9640343279675001913,13278191171989592156,1623919698694071399],[14916464974354886968,10366349722978586001,8865504605590332569,12336139015487151014],[1055289934182052711,8253659845652031153,804324953468978849,8212304389831342410],[2476928579687095754,5702446073521369740,767260213853844344,15528865867446637818],[11436870506429275946,8386741594910304633,15360261478904122168,14414877918275019262],[6850739216739437522,1991981573598440838,224862685657895013,17236561622899199432],[12866980302777582486,290096082835060991,18431716523446414284,7160222833120432566],[15497876071108069164,7267249099480991535,14195085342664102842,3863787869330240822],[14227907531368981851,3299918352090377063,9079540946813844040,14067106316619862699],[17797284224233237864,12190792518859977071,10373917212654131311,7623241933351057876]]},{"leaf_elements":[15924530976599742063,13889325702322259892,17676011486669339358,4908047095090184238,18121485560265410448,12019499573271481585,7510602681124718965,2547159127689377594,2447286223930677501,4752119586343973326,15636158188228801377,11024870056058945640,785167860122888747,18307327201613797706,12700202133511443192,11717633050631166152],"proof":[[18196288361062063228,5752911518966713855,14621936756784847166,12052473789707555138],[2218454221379220519,4355814853410184246,3614317226546627463,6669920714709137986],[7334442527033716158,16731283023819414410,8368353561131925080,9310578568072657971],[10358652672574568877,6670569855887462452,12102823887168177994,3017464307373518189],[3197627771980483253,920528886410400452,13880485193795243812,3897580673902700816],[8345512444577212068,6098522352649345269,596424398928242759,3868528311768516651],[13433093794480466141,15097901308960559572,721038654390063402,15836375296366803101],[6543494407947251108,2320088005411466123,17304701090263275607,11443022229421587014],[8831854704239338220,9745829563333514899,14537234298913550395,990052432487534416],[2083731320593879527,11321298316090969006,14658969833713519578,11366407245708934581],[8161171072864732734,10440603802106643560,6180756988961224215,6889831446143809249]]},{"leaf_elements":[17596025499048688476,9387691998060732407,4618342790803516346,9537759412629463719,5187782982879600127,4069694526678241563,14155754953450752154,7555769062859175433,11157776416710950939,8723499654409847685,14312564551560084308,12499537026350142563,12467311732235477025,9666633958420785027,16260523126302187092,6447771560580243649],"proof":[[15542202680568186753,17382691140805889484,7655244446553268194,17119148172815410701],[1862971966606188195,528957509355029775,15084422260919817686,8077777616888298547],[3359274198079067177,13140964842994642042,6546345887133304531,6746102316970304041],[15776500364805525040,12494315058410096906,3547183112152248770,8204912220626784856],[16780545202679094870,4421446789133509357,6458186716248289919,10143174203777788009],[10025392773632267332,18240246690218643046,6220026842322683119,13482069706163222707],[5944087289303131341,1366526878480810646,13928333602637998699,15146785386909763270],[6720534697580595973,13474766828711122676,2473097082919214989,18068252403595198348]]},{"leaf_elements":[12898014418559939118,9154919369982118954,9481807210717182305,10234985040534927397,3609481773949654083,8148875968297585551,18009249938179049669,13253422983311474586,2823994841341609093,11319935741460911811,17658344989180559323,6672331962362140102,4506237893309668810,4335217073371288306,3924676789128789710,2227341659097296973],"proof":[[10101894524495599140,11978961337931191753,14058927862508671707,17508774854439258995],[6750790458204797338,4171680792352138157,7888727325318655949,13840400938334682386],[13009134129400542353,8929842038923907829,2772279457740204155,2164536622126645809],[12847039190984953006,13174639818116613790,11504371774753153665,9076017712480606856],[7745958475259728694,2873250920535013732,94873201471673482,1565932192576522106]]},{"leaf_elements":[14593400273275102508,6309906633185327112,11951149523269201712,3153226618731590137,15587889054422217223,6392110987823427023,3621125936573809567,14576880692054719856,17099860724011204251,6185746063294943650,4190495433158066683,1382854502718839598,11821090327081663632,6488081574875153781,12460988453342024029,5740494408679326104],"proof":[[15293729950173134341,12922832714615665733,859236950517306116,15306405013353736461],[17656621556331237756,3884539910827412734,5169394874961648628,18423172052389089955]]},{"leaf_elements":[3103352029016043777,11936003578925779291,2481494059698405049,16760758113560209882,17943014902864064829,11760753107849584284,16263520714716793081,17159242401050750845],"proof":[]}]},{"witness_query":{"leaf_elements":[7930616101540743829,9223312520259777141,710091247073395588,2152543779645643841,2092954643453571784,11438496447748981546,10727947316939645370,14976147991405320764,16961746702216800271,4569519330299980253,13061717442314902407,8352933090785125176,9293176716924165300,3215560375108482721,8159321009385079448,5025544304948720367,15408877256480143191,12468667323701412874,12568047080308044324,4320096609766343890,15153578769249541434,18229091021888980832,16927652359499529615,10850727345626330721,983339741559265459,14912003248844183613,9639027451751935800,234832105315222299,6589375901438498242,10794532798083243165,12208686864139392757,18064541202259828262,14019765180466142044,15916318644696001165,18376471661171998791,9059390736587306215,12979595570938634592,12268449720889275276,6177376451375268774,2647928242749651827,16417796131982086267,2705976521491036078,9700897080356386309,12208920060319677439,392058301192716900,10517360914111530017,1937683653054158898,7337478221755632176,7680499912555734588,232564168428840473,4749910811908922636,10902080931227478042,13477520861104666952,14189215538809736215,13575549450868672779,10325810933686600139,14779985185073431674,665038251773645875,9302715472941235884,2700441407437741431,2583442882462987430,3258550410614540583,4334434043017472374,2031077309807323764,2565943369077852200,14519006114276615224,16521231082950742747,11156957949721005428,2452257650774383225,2022729938365481836,17433261381558899342,10700182740731768454,10018273260415884382,10697666063127798355,12699077005666843571,12172592676818000504,12723321198857631115,1749108400922078632,922604098110113961,17195770192158273739,5429370142109915946,3104516165889744441,12011245048166462676,16350862953082581954,13401975968193974418,11880649511578843381,7709126812997136715,4999630937173413794,14252547569269507549,1422452363007758152,3130559451720182531,1947082294926349259,14956966772393347133,690165729379910999,7244093060429535648,12584538408157132306,12145216826233797323,14733802262244722045,2464001917379082917,9297388809686203407,15752939811458002211,9178455250499590236,8801526133166659705,14311910593424222584,10649225536477459400,1673067066337417453,18130772541896397610,11969589649285003643,13359665137835595505,5459325103721942699,17682201048569651417,14526529609120871560,3886589898055965605,11450298945922382356,8091412483487271893,1165498071695662799,17603765367645166063,17799126030435891259,6079150730850729112,6810034505152825969,3303252364096801320,14121085909592450689,12074127817174118729,5326946235416294590,6248750108800601084,12356674257936382109,16227739445349873287,11536361989365113128,1491626881973561433,9108779219352706976,31676218094778276,1303162659417150579,10742723795265298370,5778206451697281454,3130265209553100966,12400850576078458454,11774041523092938424,6294018818543657896,12416547963358046320,2019549904604374900,703847657708739284,10224128459180614475,9555590049630467243,16414130994708669618],"proof":[[2892596290467159406,12520866176522939939,13719625392789107183,6994863727610059213],[14125943479125485182,2636237808670142351,17079127567791416471,17270659138257843458],[6740593035361391934,7910544064774065759,3904225151236968716,18301108710157012821],[9472477087326679891,17902961366595490458,10989532849819120545,12225824305160498699],[4538959232208174881,17840236251624072485,15874179583050862097,4534283711508592801],[13954029185097653764,4205058632621138201,3868781393006917922,12600067193300221764],[18341771140896449799,9168526124615472186,11118154734819083584,6875381721578740258],[11736854594138929532,7873489466877156946,7242743676481097842,1375994785494885535],[5956948300705750374,3081763318907810952,10870089466664125491,16284655059884892424],[12508714879062745701,6099603145793178432,6176515678393937893,2965226072116964347],[15511559630513840089,14662775433735450929,509326263825519991,5275461499438086590],[4187873216825295838,6840401271112010497,2434917120551206795,9371782843263770384],[15268286115055794426,14687187385108451624,10632685841990932037,12129445391553118714],[16900230956759612222,7176600490213115612,13914824140669497207,12338584587347730461],[10602015471343550610,6084302869172335650,1290306762301672338,10817757383992130855],[7391550419632455370,7353138198053081472,9917740801777026060,1807177363596301680],[11492603375086044906,12889659685821786976,12763639147647709194,7612402080902807848]]},"stage_2_query":{"leaf_elements":[15322057316004093522,13213734140720638924,14124214503367027230,880972362022610422,1951223422335724369,14367966642552566484,9530613212258572878,1985790720346113015,11671186117220576627,3650128468249181025,487519096182206561,11362236624029718609,3362979252173422340,3374207115610662801,17283185344828246414,12879986824099414884,15611121658992855614,15423450868472955778,12517242269685866387,2016051433893960033,17744745984523573573,11102997924063350022,2419009546664019425,5711393642752506973,6413705589322268310,5684623279723592665,3679681208514528905,2359935213012697643,17833536444006174501,16946986904410804285,3419978368810569335,10062284093072907511,6754690904482285463,17559306696724778910,17524511215899940327,10147993160317664280,1987118279753688865,7629630753072490330,14640623595851917773,2284121386170259869,7304877262558501185,6211188562897587834,352799833447295458,17017552473944255742,2176163825827046433,9783931545813548108],"proof":[[7740808959566646278,11778916382108391281,6683684118641189195,1187582491234788997],[3113932607761823154,17282379728756438509,852897803196100721,7485247909393327179],[17538469279894665156,14365311366388215456,440110391161307783,135883139210826717],[5292035189567317323,9457907438226705630,15433329213961247804,10742010818438557074],[4698191404464067114,16169337377999775282,7859232356334070747,17150168137639542595],[7416244617255128426,1411954023211543292,493369727700538134,1333714206152665409],[17050537566351945915,1339028982050240942,5224816631232438966,10831884241577120735],[15355034083599936127,7857133400016228177,6856741745745612007,5534303106786775504],[13764471718794081444,275953937808716763,11363054791869104677,4717018529184242909],[1896820215448068360,16868358269615957042,15426004904291379866,6203334551845184480],[6009218826232862613,3002780378478236827,10237793189523718823,1168031636027172540],[12073186317069953217,3946890421642452292,5349626207519316719,8909626713873362335],[7320274992419430623,14666709721074094508,16647396810144049648,2305348954980574220],[17767530925966193945,16411543863662846878,161029346752351968,10194182343909444945],[2133027120705430788,14506741655754183559,9124372184781519392,1752743557619826488],[18044837318049931847,5089109922213256631,9007865455302168374,13965561091953725102],[7201919828557878623,18075308308153530416,7707424879695993339,17576654716129844431]]},"quotient_query":{"leaf_elements":[990212078010406342,11124771370884602620,14119790868167826196,16438222243210769766,13366036726048914873,921521077832204792,15326175655163737112,6862749068436912253,10167049139444800830,3013702839912956618,5087429420704938478,13862521328863252155,6362842687770888923,11159592284098864153,3067980714034695230,2365163426273521432],"proof":[[13895235688868003603,10153173228417618191,8414837407249776839,18024108096393671706],[17171462956092579166,18387659002691020565,16316573066954179889,6367643245465214798],[11417091259844529191,4733268485296131063,8012606866504997903,2251363805346894860],[9933322886141827307,1790732949850290062,6615242236693557017,17699358163848985264],[8588345430947011689,6228136127774445477,7670509685837239530,2633350046360645545],[16747121731598598949,8818582923006994144,6081917461583383782,2996090062913695434],[5719631662689022236,8601662308306498663,7571646163805144955,10577240302055495696],[10272204288372499515,12463088239881826806,6831159297974380068,4789836081691028134],[18075442534977135524,17572925731400149192,17158347753674135719,9524215638465221379],[10353796050536837731,12528063209469630188,10461140965682040012,16449589073285285465],[15485415305811514837,14591516959989130126,2444696212878345712,10846458488038830956],[18328086458885986287,7497727108193640088,11635472635665128612,1421254341006526999],[14965517095291489927,340996506717860728,9368858019972282201,14072263057984563707],[7817684020060174645,6156777127877393109,15695779772190500353,5862598155376665479],[759233831893777170,8235708692773765564,16742311210165759403,4436441635642969119],[13839080274321237697,17650602992588617925,8321763831059034086,15504702092238890626],[15219974090202041036,10355475081129221990,14003088272047570913,13426480185855385482]]},"setup_query":{"leaf_elements":[13009879723325871569,16044599275533678481,13579462197288919012,7798323601454886352,9083603921914129380,18178512601932286947,17444054248575531263,14456513108823298586,14564124561665620279,10599595569697252118,6622643024561042402,16962341224196436767,5728433684639110634,4448879116187138742,10644894400044020449,14776155972649342932,3232101048688956816,8010308330052252444,9995282777416487048,15490406155683460654,8659394047402980284,8126921245140284805,1651518753858441950,1528209247406952875,15986158788044567606,14839921643399062568,5086647228169354119,16396194100344448222,8274577817696500834,4841439321302422117,9491443781996862195,16958864850449104757,5767336714601208730,8967946490748620837,9476159570248295175,14974871299169787992,16754923716414869681,18156943824808935745,1666601565905927667,10560780275843797044,9115020661234629845,9928350986028052951,16018014720566145363,7369174287756097647,15889447649555177327,7331808733043344536,1510203098814942638,8541348179677984014,8388904885687786914,331465053966431386,7319945465453024249,6668975845166807225,10337189543002377140,12519132140775793997,2574951801265082388,4304891072630011482,7204076435122196364,16548416345248147522,17648954003975842466,17126959108255814538,15234623406037000211,6260944515246804947,5305559917132561737,2666376641442311184,9151261659728289,18061862596785149275,17485789037534932989,14584439686982380545,1952040721342351716,13695141834652746170,6518460382023848207,16114688445799917275,15610323489088249396,5678417382228839944,2747679138389354170,1894134543441639225,15826041965136331149,10675659901526873966,11439539943335543869,15355083460995241765,16649735916766204831,7220898650136616529,2576272077685972798,9815861845722780463,1804241231776628023,11588601327548511948,12100973130014571419,5962187452864560866,2605820870010365264,5764041273416759592,15186312737590120754,12840567067184762504,10095652130572538328,16646477315779804542,2342301797169220366,4100162399720073712,13172395727994547783,15920330482148160939,2164324443257180958,4442463020841701991,3967303884107440493,17652213017018808507,1763372432433551794,13920736691997967226,4594100614615356544,8530107072073900783,12268118401408547733,15034256259034396611,12929417251298125009,9080336605140528590,9548468817022779112,17735936653718260394,7308906052676095711,8062526208182277955,14400530641549934563,439959373966637287,10591254373942283971,14426310011895603862,6923331379338111981,2803686674506719985,16641892549035047569,1371351547127205191,14035841439066817057,10568958030277647753,12423747828529239677,3393132688078581957,9710460671514451423,9557240216086383464,2033192323968967811,10910422075025890162,14275349281874155318,4416048740506916609,13730974789858150242,7143766814924397349,746221342747176220,10841243043054194696,15323247233022861262,2879536224768148367,10522136640671117815,3123520256116890965,13792624782163556111,1776698837984117009,2174180465809465820,11366938661119848385,3469889760973791099,6867936882393648342,13883204625440670894,11215078290211778421,5330318472518001959,10485117672591718219,14669036920824675470,17915007178759089534,16261363563433427879,2268753978508902643,5793885896399256408,4276859648785693340],"proof":[[5024415002358186470,909893420068003879,921669527565478072,17261440472516528937],[15032833032619235120,10644562843472313913,4171718764657650321,11092040688169862998],[13531177034655235880,12679854887946499666,13294785320046186252,15690274955920688454],[16293638462416289165,2093290327053665024,1373355929784958067,2728654463022956406],[16860551435085825158,4222149000902974532,7842679207956742399,1971180283662448775],[7942550670197968033,9225479098693615844,13078540411885467658,4892293223531765196],[15491070578931546115,7021274704971540439,17920427217533679,11691393079352427939],[6946832244083729562,5364720182781736113,17482747189102775589,1351194439647919300],[11367927233215264044,5676794820177524643,886242623870793723,13614241235704232723],[14197179428496132714,14112824390939740949,1917555189137789976,15276543710339816760],[7473996941064514676,15900784747454095044,10838712902147398872,2962970408259408558],[2124071340790488675,154159772258631131,17687051170884178444,13609561372142606064],[1020588385142275441,138233410930072390,4187250242901048563,977924030203814505],[6161825263029359505,13512654302688300848,3076893680976865242,4295665533541021337],[11570307290418140112,10389774488072818142,16061712009456319471,7140988892878726635],[8020002558570059266,10443012702653700049,15932751534643521742,3352117544250770153],[2825337570834942701,1347676540585739012,3552235004407085711,1060583059816643653]]},"fri_queries":[{"leaf_elements":[9116460559533694436,3106848882483286183,7012354375750697009,14120563948876044697,102788763336284131,7183324492711154958,1384592092169034783,5839938510551384887,10254913208133432609,17048431947075750578,16586610654029661044,18314222991277044728,1797362004849914598,18420473933931017631,18264460792534950031,9331372602167212722],"proof":[[7923388872555481321,12288449244544342654,13335730753250841119,5090083583790022617],[1466199673216186755,9057225071223159411,13520279220615718011,4992091159935115949],[13624870050856803645,1612228520396454548,16175426590422315338,10493793647912700013],[15768049777291030041,2327375189015374383,14755444206752445909,11231538830645379725],[2345856844310463134,10678785130095534489,7153646974209283284,10114350730101426013],[11448780489226787080,13619013152326439704,41185389369675780,13419955163276547399],[10734034041414158184,10736561517636719531,8348318325504490545,2136978749639138839],[10406123683089882639,5112193198210999991,2657529905907384449,13901123329819784791],[11516083232758746639,18057888024139651297,4936452804791716995,13908197136394829855],[11677363472818189500,3743262489581652619,13343776045232012872,1618409628813752797],[3789962974584683224,9805516986810223924,6039744300552885457,1873514459932174824],[3101034485835155774,9008610919676958850,5506629699482922900,13953160616803763940],[223063546102166964,15631043792493354186,3230671428063390541,16759072897370886309],[2955499177815998310,17670437591182936880,562230480527952728,6479201791096082069]]},{"leaf_elements":[10677266547699193934,739942183661680692,13384994058881956265,2179596004297339886,6552317813023796561,1439008406247475514,14519421907360789844,13464734767522491217,13597352490118562011,1438585434364836596,18372520660386100036,4635832632079186225,11259595469860746603,12375975962131985924,15628623557029601203,7430510942733143308],"proof":[[2127241699527092676,2291072250377231184,12195325440107342590,10667016717275468460],[16072299252025291959,12640778888902176364,9100843642377673299,2450982843103332629],[16174249697237901600,14675122157062645094,13941390937219811779,18421767176443726328],[11291894085724414585,17705023993420613944,2540841506502887422,17489577659949561377],[14124953944708394145,6463927901883889624,15941472366403877974,14824877341147545386],[14566920894614929196,405020744593754884,12087745003206595443,14238258955108894078],[17919737324327995792,12994518835008273573,11861767582421950678,1989822030346597196],[3098065873383619325,1597412334929280171,1559592990521507187,1402354560787376891],[14352052994240922434,1780601316358723329,15158330433986266199,5611203824004231807],[13525927782408492486,15324579232051531586,1908597401165410403,9076820131835419544],[2065914019466681039,9751093087361631796,1041788443461241707,15886007464689788957]]},{"leaf_elements":[3975604128939234080,7915757910505532258,11746075490125658320,13431113184926442537,5884449241751480374,13473289930426725061,6975769634824683517,7633493325215312226,2967674974622006153,2575884981390041506,14366124305552629494,5888171815250086829,1439274360674237775,15605936222412308891,12517059951635182151,15587745712288792531],"proof":[[10319411111919485433,8633434486479492323,17880319609843456041,5173393420974238131],[14948100385339506805,6614932026037150806,4548580376055050125,17404680868809852786],[4493800348898731145,6246341325463920170,3975526444748709335,11392681859855131512],[565001809702815898,1737688196292437304,12241379921057305320,234098047193773562],[4604384999503681539,11514471071656757231,9159019364615406677,10783863121430794935],[11170806514163640602,9378973055871972731,11492657452785534440,9108871221285915549],[13281647056082207744,5119194867032265412,7535781743097623298,13356440861002492933],[9337493231350890712,6135849217265235357,3602169715072990934,2155286987634949783]]},{"leaf_elements":[12859374292061476147,12776368430061125923,688624790490431112,5319347397710481858,16393395172676229641,14141816488408794719,6674778474614157755,8765433985553748722,3035109819316977288,8670476235366926209,11173485611225205399,17358391418418839274,2451977603447525997,3303319172423232043,2985471737525390061,12674629808718160291],"proof":[[3650461446977161059,795607216873970353,230235806157593554,17519892848611002138],[13879941321968998069,6600024168795805691,9477636617860937916,7309042680121499222],[8865777626584308169,6243537805477078796,15093948731464397260,17973672634519515505],[7484183575447401065,14619243701218643616,9046357397872697234,3068807957990664061],[17767512737782668149,7056691306617396764,16344617099772662451,8528842919536213672]]},{"leaf_elements":[7821591009655390636,3270048445753351674,5416180886831661512,9306614966387360365,14719092910014157483,16904641073930451927,13626591185643028219,4848426334388246820,2506065836376076023,6343631956425256970,8907145888105387325,7782962303070277203,9692232272406511788,12762666845963411138,157102105057210546,2297883503611522610],"proof":[[8878511060119773169,13866025087849137697,2619305261921130573,3372285334303707700],[2707402844557173430,4658636768790482534,5298647501566847874,2652057082738657760]]},{"leaf_elements":[2090332255920191090,15383793183514205018,16796842030129987924,5156234286113161623,11959741824313716934,16079524884866373675,9779476225871497989,15653106700864869981],"proof":[]}]},{"witness_query":{"leaf_elements":[7845885630394580824,7768073837179099604,14730707682793357589,18277778271036268894,9837256592172764048,5042296708940319749,10158012714461268750,7570142711879203048,17506349069362392420,8546050619520261922,16512413899400773504,10099016122368673338,18003815213425557599,13689176377313934937,2772724180773899731,10997773803382666973,16153404158274165958,12177554933100809500,11349880992707182155,1352580954323597467,16380816836706688925,2113846766618726506,6919404498085023830,16789948361888497750,11905424137509736680,5399441875689103476,6956546376931927772,7785650836461957803,14939585003395507852,4977728700591599613,6768299943642388678,15225032242416876194,13974823701622290739,9196293338741705809,8432425056284019179,5084432428451249333,10644928090981536189,16533440497345966244,8957688840500052289,9711598014500683884,11441873161209945442,16289206212245735817,2267622518488030179,12552824895095334626,17564568836357510014,18173223572550251673,10182915557525487607,7913650604767506630,1107546017883067358,11374505328881120515,551742429769533844,15181380562526855461,4344608171981383602,7604108816400956838,17474843479094220527,1796089165519089599,13564844099303320112,18370817706416327598,14675046714819607117,16752596120929482478,10789943691214650516,14297424387112930259,14931756849316422568,8747527249773313933,16828133810678218702,5149010058252048946,267747776276150394,10638201231493562991,4143514416210002917,17478575802668304410,1455416054620468377,18282508661660342665,3354846493166656659,7134226793835103417,10507798206241923333,7515005493246346547,4042582035647254071,11886846654592722036,2161033992510902849,4851782739722547948,11382041719603317906,7992167261573939299,17115136169000708584,4425012738187572599,872206563288333144,14962680917661376337,3294052577353121009,9032636741743759833,2355198497974757972,16095343268507785396,5625848563832952103,4047372564695339809,5849525996568643817,9979560574101648937,2645261933687494284,14962053147396827977,13489968647999036988,15814490560952791514,6307728376754803964,1114012545810785707,176647830071721101,1605784538864097253,15185731803651914750,8170919211926615147,2300932610884902534,2464340524843451773,4753191297562627259,642229700629953996,14957553887469793104,8456622659044297910,18269475153595792108,4615007957032876136,4776602200972780609,15613591265331699514,9972269496333018673,16626631785452940832,4902487124649037034,17721996077589255457,2486124511888712534,2228531202983985571,6419427372724066798,12316337019150834969,7761669296996990274,7405360007027261132,9075345131902220059,12107055770314338087,4873104070639596055,11962384546005556884,1259995479501870226,14484805467156694905,14452201104992155632,6574535629662319382,337111148248183049,804402618892825573,9998926500861773308,2987214447365621012,192642499728577814,8855453232213927874,5941221714126324471,16834704451595267986,11823160684320478871,3883225254491656917,10716897726083838365,7229949201633373167],"proof":[[15361524483497020674,6675839139378732120,16701092480726746516,11420120896599315211],[7424995402684008213,230414715775817478,8026982619572736671,8464087247122414341],[4179606167322334181,10321546065172069197,6135531553412903791,15559584754985378083],[11691983551339512348,9681060716420366618,16346136164268491346,16888937277621988388],[3988198412292325015,7997304298778231330,15771266445610422592,505399183569307706],[5742476250820800716,16725417399516945210,1630959442253205700,12192654577207956867],[17310227218735883230,171899355602816925,12757388390038174645,2178052146838346503],[15546580220871594041,2167156393996911248,1374724205052141687,13027200465435793610],[5749539722165467332,18229636618984492653,1482680583618129036,4907749844064666917],[15221524251245110824,17153627012683128555,12172225931699985059,6194203538556981694],[10773285194590158207,7528305635359921801,2268914147738385670,2569064649490635747],[3864072091890358851,9112308106415920208,14459527049342670425,16844050217853210644],[4776809437031227312,12361537423957791547,17365210682310616251,4425897406842466138],[9166419298048219651,6098825850018440549,4992567851977020809,4820309080942114300],[3401213546233727545,4160889313185188485,3444574503188552940,9739772980445261360],[17636075311908780014,17353848808359985749,12075875312595441458,13651145607292130396],[1360073737404009268,6704211837639141409,13662088324981550234,3380234095738789957]]},"stage_2_query":{"leaf_elements":[13854472704251218236,17072633752065019912,15259109517576054593,13745142896680470412,16728270172600316557,15793342979248882574,16339599691098500593,16542302695556090362,5520194287163465953,4799230252543343290,116847509596502148,5698814811870471512,17492271603053556077,13956847807401768355,14950456981997318534,16800543194462076768,7818866457277572553,3878816778767171408,14145173030231948604,4347926524691742875,3775984074044963360,6794274505447422482,3835615073673839246,1382668086132317891,8390601056606051025,11361038710067392100,10741856981263011865,10064310693649891239,6166209826464692964,5220670730819088991,2910704380236976493,8045947229170119075,4018427908382077596,7714904922792498817,2854252789196139767,15806953478200643638,14562560033438060485,17705682801331500522,10197865959666902347,6280902675159878900,5785856410839303324,16253781048702994971,9577917852236900314,5025643280830043005,12444170345373846035,2040280857420069326],"proof":[[5056383959857316759,15337922055218375552,1435766324517823417,5199857761840987181],[18359474258077835932,1185887630264234180,2046354500127513536,890566570520890524],[10102201163656505015,1164007684508428061,13540205644411870988,11199321988055070243],[17909803212610691555,5194215088301662864,12977101989253496582,8767023253355121965],[528328275677265097,13091073566856156454,6201708785237004851,16857692544375004055],[7173660928443321465,4814448325329267868,4273806342274165164,1320840610629249784],[15316539203648239254,3999937035610047665,17604695453323046377,10106920377918736663],[1589115907756670723,7072029881940331367,1311035839377279394,17880935845998850210],[8452362300916975937,12377670716835959303,495357611982997700,1531183342449984026],[14870829378885283025,12802541070425195423,3299785780742404989,15124533933961327394],[16515462334826933695,3053699484651402991,9598052595021891857,13964382394576208582],[17002845470899108276,10777593941279011463,17159389748703450571,6516721498981632898],[506490815777758938,10806236859159782176,13521123226270339043,2705967500197432243],[14478786296495354433,1593368337750324921,14721811760686597686,2785137016932844149],[6005332309773229662,15757169263984814236,2719457185003340351,1696502891371203748],[15501394167900749995,11197586135871419193,935706737801708135,1241914365515805231],[9361241096660372388,7871199822756612728,13057621005758402560,12934406087966475422]]},"quotient_query":{"leaf_elements":[8403830972661952581,9876559395103108901,9404247186078146842,14964569927377305899,14122175733714825543,2368510274452263144,18210615101743763449,2649709420588898420,13114444965562372372,6903195050473337821,9409926599497518817,10793182675460680167,3487683345461219693,14343884618295472517,16959162579179353476,6591689855630323683],"proof":[[12100390650758452557,14789614627448291486,5780163413132634331,3549800612428425166],[5598756607018791011,13476161105048636436,11719178931825993133,6577606960390037194],[5372007809698289542,11945357924639360059,7998770925763715218,16805345609448262943],[12157432051148051779,2572193935584651255,15060629640544146876,17255154438471570407],[12023054667027404486,7698908214581292685,16686701605362930169,14287339964916829059],[14179613163196390325,18090315012662706676,1205632101113575645,7017956672292828911],[8220854087925707624,6705976119014484681,10831801592568153239,13262505134984426819],[99918274044480371,15257101098236770867,15883099135006550874,13347854156115746360],[18338614049211864035,4177686575577757119,7451866073609888022,1501650156659693176],[11612636024304047492,18376585473072876445,8812297875701700472,6574864219148855792],[8025728524427413829,17729186962216780783,1159863826810334741,7577811395603418076],[16317583886577197829,3518985772032667565,12454037677150104841,793685216760180067],[10854834364636226779,12364009610863395263,12846043800639853015,7523025454382812117],[17925027325090588288,11749209872015043307,11190556055959466303,9984170006697929829],[15135291086388792592,16576068135324548800,4881722155945816270,9411245027368093085],[13250766141660135960,11386093487756629881,9978779752784877204,3582753556722114631],[15725155024730071472,2846784656528433399,1476956847549245851,3176915357345878490]]},"setup_query":{"leaf_elements":[16251937209302208222,378239627362263065,9438719550920217888,891931745010523525,14558099274968136012,17718361549549004881,12423314710827267718,9799253934913954761,6984511809451851653,2941351439652900469,13022133739853568715,7043098123552524479,5720826729302454130,5512538140175071709,3255854912228560605,10359560032308801532,8446862508662964821,5315179166178889039,16136740394183278569,8470511517424487051,6988473101727395691,8340616146798682831,5148195504058678981,2764895998640129926,13541699509355454311,1140097742982284091,9768126336530850049,15502160021882020571,6848823308806406632,9117654408162175097,9207503976299287988,4534089545898122439,2334586541631912856,14232381991678917723,15557936154334568791,14464979428669269586,12118259423092888666,18185214532337074438,2635763543778663720,1623478662046337495,14559557733264724251,10783065304364771729,2370567572113059326,3509011248143771826,16658036557169156487,17214178093453118816,17850888736200539973,14048005830088078767,16402902974993204375,11163415308559139183,16774543420889642485,7358705222192414917,15313812505784817406,5864654440018318191,12874222430897084070,2237808936272853874,15802683757799619288,9622878726424638397,11209498561639277112,14248366099752375192,4469748826621962920,3891516674096382480,10464328881413468996,10443136130512556840,756301724463307226,826363028608966399,8375976252135328754,15539570798226722112,5019047864607581667,10869951626439154338,15064347086807920134,6339481740861038643,8352653578902949834,16948924538571014523,2707824754865365567,17371245228901542255,9819257237630672199,6743269585911263348,17856980360270156824,17990310837496558167,17096790065662947129,588481854255157769,12751521734575863675,8420503165051487329,8943729115238504472,13432802104023985284,14585119045522762719,15921227973079131990,1697763310100453623,1391996543828010099,186519279115544424,16743037625678624020,7913165630801206776,1770008686767982691,4619493539185043157,9995897436526898612,9602603676182474037,18052064330964841873,17098464097929341919,10625679372009225646,1698497137157272420,6460329989687872,15505865872885222250,15037113904898035959,15459143915680600407,481893792257934513,16421851530862804240,4205100430096852146,11132988176675723259,6484360910100378965,619633804803146302,13518195360948352850,9120253073198635395,5090506024594386312,6940013274547065359,10877551875434623755,6129181315480211019,17530139332330723670,8463576238985295836,7458731409059766795,14163011771980193280,11981160456220452977,7997111697575961938,4370588115683523116,10994648451065471549,3962729892955655985,16227123796482294051,17450212893672383009,11618575054612477559,14085811264593180960,8717343297070700037,5269648006533020086,13198996486226853125,8854882186686059593,986456523364288119,15742936653367865135,13868308848252798021,3297973390189423599,7837322891653732160,15325839334331891009,15524199263016257148,3758259811320493587,7459938972985046666,14592471767419732093,11800506609010737204,11924649430012210546,8622935744380961603,15121348238720978427,545534219965232419,13003592417183314932,16529221771571245791,1718629669103129392,7025159143810754757,17437501156074539648,1864126303203454893,17590503628083862256],"proof":[[14249522124593333376,531766748843259789,7588589713154230555,10933291570460317560],[7980236305048710208,18296630770067098276,17338909021586954431,17899498285702883325],[8322989237863442827,12221862141705131441,2594351999261897474,5190748959895495848],[3619912097242973161,14992006301368882651,2995195724532971055,2728857060451200392],[14158198802596830867,9785237797610155586,1751310802237671122,1345679419430050995],[15172289847866510893,4718605483514614186,8169644567100523385,8827217930377233410],[16378585870677030536,16575248486711098357,5158829001570000830,12598857914440391373],[1686880007226358472,9559376020464014296,536440419804123047,11021972983182402303],[15503283849991998538,3495585297494308850,3216651608197426653,11472317677450520969],[7144622740808541164,12211531053386737470,7936001747968685632,1917146350301337793],[16434662186165173794,18058601312320863390,3142230060964741807,2258181956449754555],[11749290061808371745,10120174080769322071,11718227953333325438,15599049044084451675],[9023721264928321098,9285382275877308320,8583268341435753578,7271823108679453990],[17425589027563816766,3107364238401198731,7799852125172671940,6716969503699841485],[6030633041335087284,17706683855528030775,9824200195094009319,2733486558048934832],[352131923286179634,7794124398289854836,5479446117613665341,14090023505397123381],[7584630324897337125,5855445357232526401,15406563887835073472,17749225028109240870]]},"fri_queries":[{"leaf_elements":[10796359180977635737,9858643944432272068,6733471125403491217,12986223626973460075,11185944212565084734,4564782789377984409,50797949628203780,6032267621403502239,3120566657564464998,8005982267708860458,11066732737438774958,18185551036150137315,7509486814119227158,17806807995718827728,17209722743961431157,15739332538937313728],"proof":[[3305902942122888577,10745277177062656180,3858294841057749670,8557566714388619299],[1428583791494570081,10710078874187770050,9709039023524908931,8742889086717159088],[18305550697209460523,15798722880674402063,11282599824705838852,253750413144665243],[1025236752438909133,3714739448756477604,8894750505574746010,3521214087492875025],[9169430582987906165,14483433800604446558,9018108848247605262,10362944823618495154],[10770640301702015629,13242630920854739022,7290489955980540127,7674947628533578776],[4859178571175134046,10214449096419038067,3429652706310110085,7154870328029453577],[12031658962367958841,14877594782056884448,4797642873956922370,741490961460987762],[9978157921055943115,9002163108794010153,1304716255813771321,10369851115265018447],[7349148555787273237,12977120797826074842,12297811765533460566,14288645660267330482],[10641766499515912183,12823917552826661159,7765877936110526339,6019313251441790754],[15767380546039469353,8342564351532261737,983077915371187554,12353250988297461735],[6658853470708666258,14288061462074838470,16021201117273385315,13823279494601147756],[885017883695360673,13435321449249769282,5466777689613489543,15313896769676842091]]},{"leaf_elements":[5944223163665543261,1557239238971276328,6996211351311485770,11645694840213648808,5414755989268490581,17992292567718159527,7306340982628142597,6571517305073922086,8411694641477581328,12331604404701091417,5901998313817157103,18413773495200147448,16196338424281105674,11735513150700270079,16755205787371237276,7572593946254647855],"proof":[[295130068118993808,17042844149942859704,272855324265379326,7349170370963432222],[15952290160909756306,3921137767199629925,2542845235813878535,5035659324439997884],[6040835867681410316,3943935819284273997,14987051073131220212,2807004743352753090],[188288162985081597,11830579196298115812,3445851477596750997,7268275659755682612],[8717874988328863326,16068052481215975934,15651488701619352997,12032996127162335496],[7349924179863793212,2624948323798911067,4027759143320932411,16529945699695231183],[16044106583922947155,487070012125292188,5689924879676636769,8935611338668556040],[13560735142244988476,13462580319708590358,1250967796203700925,1407291648887672277],[17027911532715879223,14803249834572817034,5646057547018057837,2014488055503808674],[11020032155216820905,14239460558716090538,2553107458770358029,1954654636233882204],[2991006853592388490,8934783177013465999,9854609272269142038,8184295943294888051]]},{"leaf_elements":[11833711137901470921,12239889681139333965,307930416734480795,17276423258713085450,10368179363371578827,9291876051987621240,17046665614138909422,10441936744199522825,14338737830563541834,1298826942529347691,6325383219750802670,3115573216509380998,3460906155255255441,9989186447411701982,15153541345424173584,12546209508303086488],"proof":[[2855912366157007803,9269462901939730779,15348096559237298080,9977007556401926924],[3121381073504422373,8684511121964723819,6574284901740374658,8172408902391337615],[16785506844317958847,10956169583486949832,11665939894592012124,10931056996847836072],[17363057725776438353,8133846188884406778,9211206727457027426,1018502785488194195],[1419230330200022199,13217645708403726423,1398068072628989077,11055683395879136324],[8300291083138878412,5069198424524338217,17136951357450084520,3601331646298722144],[9993083837760948409,5970939434941899773,3978708845555665730,17755052416559584430],[12483543229731015254,6228922028592210696,6804550060647530973,7609776898298193025]]},{"leaf_elements":[7604482432269005335,2892807378488593864,7703619740830660642,11872074851912890910,8556394872753693618,4563962176945168889,5605017774977908076,7043675180062907611,17366447190486205824,17304931068548483602,3629214935737719382,11650350580422597352,14856671099063834924,14516525055753952172,14250009990574327390,14338647460377364083],"proof":[[12296526630145916000,17085146549059441118,8473816181468997158,15618820036623074858],[13883354112000236271,4594672208351509256,266843386294230961,9284341453671925718],[12544621958116887805,15976446210261604567,18444223475325847570,14527295136129465393],[5113091748394536210,1209714313524782154,747485470438991072,17485143069284963853],[7378436202281888958,11263343018560466750,12515193662408163156,17578933933619023765]]},{"leaf_elements":[11156938043986047455,8058800495604043138,16105805660982524567,2267992820469558720,12663960685322860493,10046903392075626890,5534413413444273804,3415369278833693594,17539053464684713302,17119473303060456797,1193395596228754704,7397800834845770752,8467912030867365571,838702488467335514,13889134140680315451,11793796394214456165],"proof":[[8918299459814526725,16890029929897481883,6563368210199774689,1850949772037457808],[1130374547257051060,8284282418257759999,7393623318517703239,16641200946473051398]]},{"leaf_elements":[10934508164646927795,12314719184668898168,7161347650890243018,5323539938734047040,427222851664169786,16835810319965862076,8726096516971579929,1018351776603887044],"proof":[]}]},{"witness_query":{"leaf_elements":[8480819682206722452,10615112934535635827,12538035934298147008,14760143223603003701,7329784266504825749,5841383273450811728,13239250033211974942,9029743232298469893,10642120734139854772,12042124430992419102,8182745314178330716,13518335317034516066,562569315615999666,3966514929292630496,11648520592001888095,16537810228381247435,16016571929428360257,13262762308077463534,8051074789780089343,9661240048049531487,15786495913013713639,16969017913113714054,5634377489281082025,11582633357958009716,15850034044527444761,18390336425497364118,12768395945120969428,3884872727634326533,155045427072230903,17474592564239355855,13856026232325505540,11349025721569148735,5633654333571360945,14418387014702248813,7273709858469610169,15662068581594481200,8534415467785721295,531651131374892034,9957416676809177367,17446010965891862203,5705914225630407024,11425727899686860793,18122528568893231317,8464548862577117385,6540763114726464376,4212636471239574869,5517114279467149631,7403806988331001026,17603111512982728112,4005353718202384855,15058010681997397415,16829198203316180247,16827151794014897469,9209495074448105381,9001799552717308134,8004709026682011887,6247685067717310779,1202717055265088524,15883297242516133051,12582621705854002427,16527018592665867368,296406536169996339,15478980315998979190,6425617036574443798,17684562740683009849,16377139951875731247,11958580966801347672,8547251343560762510,16905275121947871001,9973119884371352680,9777798886632592340,13267347366690586356,10839285476525230796,13884974693250686741,17654701388509760411,4758819762426904922,15062932454082622651,12801120952343965378,17264251344688925217,8149874525112620557,10447143248825856828,3703383311736622618,3783484093124629288,787156222296097971,10666325461316907607,4269299743789305569,13122857393652079657,1840884110369118662,15954884834637676630,10112095710001744827,9508494131306809821,7154405698152740632,17592152219326009452,11945373822425874543,12075219179597570372,9346781118025299969,2238554273211631014,16012206564399580119,15080246439517527630,3798048391746578370,15795074826162849647,4531791684417652517,7121458781158923754,5634991947820368976,163548549699022577,1728279596345494557,7163482213471985023,15499439078602029937,6105380563502565553,16735083941989492797,3907419115740195916,10451946719130865491,8064612391014144907,7902871728626114702,7403119649631712026,11899401347963429408,1276229557627112330,14934747562544772313,7044033858201366623,14986478779288188029,616825142455560451,5274276213318242829,15669766594901121716,2879405282612810461,2697938806803102799,7389443808347097810,12234159642450706471,17000089532252309443,2817460633214214733,8866297206370722614,13005516812691310927,17630307229943180871,724229346188852412,6611169501196679680,4031736291575567692,7550495811518797922,5893022207404552538,9246950925694151279,9661672202751892900,2486301321733865379,15895675325601088091,1598405518593084441,10037836569682379762,3395288802082306766],"proof":[[4757082294070938807,12852425808546409990,3835164960441561806,8573319778946418017],[13213887968424833069,12678567030444234501,2368464174328130586,6655393334340480775],[5121604351570174578,2108557203636334154,6972354583817888812,10472685071279458686],[11925300071954394634,16198823840276550371,3507528840194458339,12652742635570741955],[4046232735302507937,8531863679388476503,12292427879085522242,16974384260477268097],[15997540352798970076,4473657848961488087,17749342491957394673,10380503554552961504],[16343462447142827518,14454330580847982401,3176595324049643410,7457741784456664271],[4561809723562372916,15777758273243083270,17019278029479077100,6659317786277883665],[18331423145183307278,9475497818195424932,15544320778298818821,8233557593039278411],[14891468184687135844,16392997658177660492,3304226416618389667,12427095753378691612],[12872771991824995029,6011988035346969662,14286740819764023930,16700746025112548015],[15171303313191393781,9071329802924592925,6450894278484343519,15901142958164980251],[6799079562413563919,6588093604999840512,2632032734151614682,12121536778891643488],[5397538174645193509,10720678615688955789,5580493749301621678,10523329701871811657],[8337512444325559916,15353041959783095985,5374726833674977643,12226767965844386202],[6886474179884240681,16439154287299582691,3231970666283801380,18384200476527100205],[11350054266242620580,6717146233067051964,6161093412962147136,8935657310830520738]]},"stage_2_query":{"leaf_elements":[17301139703217043031,505871705896602493,16044443889400167540,13600019807464728717,6524084724008610545,13075223287133621099,13875173431041133630,13827349713659674036,1993678642650210166,4711610505662155409,11463712122985724708,10015829608607588459,327195869151125541,452113257240695124,5450048369694714549,7590298657951067463,780633144140600270,8724834095432701131,17876781176320415013,18180597015972406928,9975788510066849133,7733401783129571053,8064644465659302703,15536589107404536867,6589307239288118563,12088833124447135192,15253164107302522472,3112707143615758899,510130477088020886,8515921703655134712,15459590207231210061,12245217576783650918,17049376963584033795,17136356023522624539,5248240112009286023,11628606817497264685,2535065721343248325,5263886880891703194,151311605821858216,7521989241631261708,1650812569474813668,13758923002825179922,18353263748028216958,5207806316012729570,6296637658219327825,7159692132286494555],"proof":[[6666171384317862429,4542896191099892794,4215344983645887162,7469150317212033481],[356259253971063283,375919276265914269,16617756570376992463,2722426887016960319],[7978594794958183306,8824680792390485193,3129176160865856774,17787128560578273006],[2157489774674774951,15656755852345899949,790385862309724063,16269245556063416163],[12157224167263723253,5047452886212054350,4095698794453400021,10434143278294035305],[8362472027911110266,15993237207394917780,1353985808489086974,2827643849974599264],[1166099789370669265,187053541798835406,12799708082979400300,987614774602222979],[12539945871067387481,12962186718354527957,17421228221976708952,4245865878936186329],[12619136610599646414,7133685428517893165,6376504977127831656,15123177344248387445],[4504088665469973304,10977506791310707335,17846671226456582465,5564761060282665332],[12934795417883656142,6984012855777190062,6079112013773939469,110962493924684242],[14338294793121058703,3959493051303416663,10105395198742532390,16914842922859228931],[9722560156975968074,2256849307929562774,7431431572431207413,5494512386155819618],[12838337067860178155,329522066073283259,16241766823376500807,15189322809125831821],[5256443803669001268,13448958975426653055,7507030085589334741,1152891743208947109],[14369636617272839613,769082626518957918,14723074919799844209,12575814143068115752],[1518475277183878351,13495330011763321220,9115621685652662343,6489546065185696418]]},"quotient_query":{"leaf_elements":[8855493596483286297,11624031064042730876,10842974408437719110,13674096031214257273,15697986985500158324,9731064800744637441,6159927460931644420,16808924627991775380,10361026618914548363,8468392117262125786,3887116159010191370,18417260731663252610,10494423314376571797,721588426361016467,4326578679612067679,14618636000553264310],"proof":[[9931896696346574533,11046133898814195382,11075344027693874719,6741844828895767409],[13714323241675710190,11780174119714539944,16278698934474909175,7271654852278714784],[18117821925805257043,1218305471901409940,2699459038206202742,5362798289622860103],[1987226057595762873,17526854819736443107,15507896642966969991,14383658382217455247],[4071430607633124655,324003531821143149,4038453675064662738,8087396352527494002],[13556236341438331699,17490713503451842626,10051332856937142547,15274169145553459290],[3479418816452085112,10249427190803078548,12712338840432012640,4963320628857122041],[16183537152792981160,3284107230146148351,1615403230085765195,14448098328580168193],[15399436616556389895,14549875233694813477,11913068413561962009,14128041175666910382],[3219131045798448369,1225849746520020922,7774980599134995860,3404562411226366180],[8245176370589579781,2885305264021692476,2621340264847238648,16848987386237962879],[5338021276276328033,15082753950722303516,10703219368608183159,15168981408988309894],[7440879878091244409,15592008232742334607,3264916716339074480,7827089877587479692],[13518194017683127665,15072651715449510838,9111643449760229270,2109599084303879930],[10428040842367392537,16465969009175630925,7863916910079697730,16996908341790814922],[13736514939100016281,3315623275810354233,12231384894636952323,6708607002201009244],[17820760276996863375,10216686837309516532,8030491108914819360,6003298734879692044]]},"setup_query":{"leaf_elements":[3334715977967624802,12006980462096382451,17570624975906141195,8263077830528644276,14002641937094137812,17218070857024465235,9107838225842175206,14364155018363078086,7829646532794143778,5927945473276016810,7707403668591615320,16363093571012995684,4493001345561740101,6218755724934999196,4770110630536375624,11324186704482466368,6008533861976162864,758685491216503973,4407253511495765385,2387546420745967162,8268494958687372358,16078405508501469411,11999152827896721836,5249822588361702549,8414147750031882669,12351285612327224805,2247215587194411955,17091399045312116208,15084495420609437439,14813592754517361535,6935637736290260361,14511493507850114182,17662341087257594642,15996307156493752928,4722511831890410589,1684779510319463351,14511636869412744024,18018191630241130228,6408077155686857553,15404708690968839426,17498277189217702190,4043062911563981889,17516206228490120644,5511043866799715132,17216426771152074846,3724145015692780200,16631318966578889685,15786506546681114624,4786175547120472522,11166833640378444372,2260413002686528827,13777550096559336270,14023531016292192254,1460265536343963422,14027659485915497211,11088810367268949213,3836103554174535187,7190920587389354303,2712603348400179073,17330572010799684873,18324311388963720731,13771967593342209827,9966467805602715238,12914447096542518079,2675957223769059589,15051575629052493984,8315064038952383716,4443169910915449758,10232955415234442712,11871316565880673619,16385159684165368591,2086937900409727766,1296120612247272317,13616598990904181819,12090180253146173085,1115081848753863894,8623836567136855916,3461166191828061313,4069276235771637332,2259449693944007982,4920887419460660823,7890520063894300162,15024659575594049809,14439075457340187635,965626652005642566,3407520427145641241,964728991271647735,12811511005082296033,9824133785731078197,3773608038754670139,14603232869063889967,7125572364098171214,14997670440470273675,1600369544852305046,12929306228138688251,16621132960880389161,12432244551599452294,13593806038447461497,13475240562942374966,14231838161648423683,14761953966720279610,6393229509987522582,451715586875019417,17823238281861288912,3552115599101356739,16423515725556508698,9429468626068588562,17121316825310087732,9905858181243794943,7395994509099062561,16265258391052355892,2918055861973967337,8674694113174194005,12454715655991985050,1699302427861320879,2202917595660081015,6287178451265738743,1535966219750768245,14785726329731283761,16782933836607351843,15062849992965868403,10501814381665265896,17235713975143292435,6637338084265118852,5243857837597827991,250580052772587322,12404563159697765097,6142969511907072982,4670894782765724898,2937455564712000877,6747937377870706053,14684319163134803442,11903785123188738901,1642241567720896598,16949242280489351065,17667868346842831035,10346548620616578226,10788345038548257998,10772846685795179945,7220389081674863772,6602364741883044818,3697536181596720417,10768668248264570094,16944477926281758209,4071280949546926534,5746714823726498048,8494389646421868486,5763171714879993011,9111439313201348103,12900356853470713364,10965675979504409245,3131374329319033664,3970464225011509101,8768200507770095369,3226050920399712473,18236575259060727484],"proof":[[12618249868881901744,200209639272566718,13615528868130816039,13229557151061603662],[8663535281099139256,3742050627420672106,15313424849624753616,13770764717230864836],[3334043973639459284,17379679082151629447,17485072746799726727,16442943285168364389],[2733498165344061593,9920881753623228548,3294195080138521865,1633144269503650898],[17032112996801859089,8443937775813755860,16847796635441312150,14243692931485502284],[15963805942428857276,11550116888387407517,9567320986110264501,9589055595979312076],[10200643072301740994,5879510018087970545,5103313014195252094,12152968263575887635],[12107446901324882768,6455680481318966304,5178550131299849191,9767936332069142341],[2383725222614161351,14298855351527325738,17812868865150776695,13686293710336109655],[12964999977969406883,1535712426729942845,12055121638748758435,16754167568717424205],[7703255907227285391,186654820099441019,17028908026502135861,10784096219786532516],[12628999338211552924,16938679866849804424,7957243986387501473,2334836789092387816],[7980707986730542005,15557543746835383388,4025323552345169895,8508165560698606874],[15961001749735456500,6042059772166293429,17883666959316085830,1936478181780949082],[18053424720841051506,9148641213694294870,7075363838696663695,9143703784175648683],[3145883714555167239,17832422268898223862,6552749558330443087,9698474823968867607],[7045693185093702392,3053864862465226362,5174513965978999888,10652156676010014419]]},"fri_queries":[{"leaf_elements":[10950973997236123322,6859939675952843433,13439294460716469649,13775032240360237725,10343067216925782338,2314644450214510823,15473976851977998693,7564723117198167712,16172436801356834890,18024685379006812316,5430251962915791695,3888118394165094118,9017269015841594274,18176009832098747095,3598427744101910751,10615341210141101668],"proof":[[2120681544187201876,4140794940394623619,10339375740673972789,907303022618496548],[14433957641808729558,8044340435746013322,14521109169231443414,2035065783973360244],[18261799861924210673,10052953567653229634,10424674245547428568,13121699430017119118],[461616036951850183,13809024120887333989,11055465846380636835,15636689360548330942],[14703185664852731165,1209592933099971880,16265111412003561260,10388021614773678115],[15423165630107916204,10703107482333875617,14312250866748157573,10788494240919761264],[7802691299459920068,3865043883679668582,12414632391947281971,12671898121823061681],[9159476441460717800,7865188336330885001,9896907930361801493,14464614480349417052],[14406849732378402971,10184590847322048921,5040180672907282433,5140193810172480555],[13290624086714069895,12083787436718516308,11231382447609229563,8132118006850420227],[7947721978253249630,4521281100783527384,12206111059567620273,5873093808199945075],[7309720215328375820,12329669731281918080,1410491834258943851,14587637122709731491],[11876864916534247624,3232893979257049513,14343044879082195171,11381620463788937400],[9436036085613120994,9138757752906074281,4592184338475319271,16269358300088240680]]},{"leaf_elements":[5622070546725065077,12432863628804838181,14468239792122248353,718760688892604140,7574145544698067658,14232618846066897954,2849886106050580883,10559514329184229787,1376576008557567611,14583557530912611636,8216031807746364642,4184603570558250644,8069634424523305324,4483645438470255671,10922086782157407164,13447673989436813980],"proof":[[15978562590476797639,7095620146085578938,13554602303055528518,12373492059817095610],[15957803102853626576,8347567418238571487,16995007172305183271,13826213377839382415],[3803598100255829074,17253134350869981549,13288544787667066248,2893576879835092760],[17260824829783342108,13127055840962429077,3231798509901227267,12295671734024100754],[7573594489291044284,12769645301802811552,5431741687434120449,9301796064295427132],[16031832240264664474,8507188368979554001,3750134573089315609,11157369738704974418],[361657809759235546,8301802262006155968,4808812517670476782,8559769344205148754],[11373428292058565395,3980075896323271363,3990281413283421192,15933648218263092636],[12099230686588021966,5281747004695262512,3342377341555875231,2643715988207776513],[8220481566339736506,7498183421885082286,7606818933761342483,16141904381016776472],[6686906591241727369,8571182967814379765,7115603858759199184,421617287814022009]]},{"leaf_elements":[4383935554916125110,1663733341407111453,12664989562187151394,11307318290931316971,12745039837861531993,15674569941841984921,6467882983739954804,4831132442668159814,16242946433444719846,1487585336373968226,4318306326194361910,8345548315140891115,16623014268749951824,4599870250153792188,17481347085429846822,6296662384144317182],"proof":[[12183272156025000002,4728676783568277612,7165300420519030376,4117378737181755076],[1578111659909994949,4436573067502472875,10342119504488955975,16386001719914409698],[13438238860674249729,3681896371791473823,12275801822144187258,15426068261014402922],[7118183525291395224,12865163023332169307,14946120668079580280,5289602577577520143],[5032320209090192684,5187309367924635455,13241640513412042250,7812535527603890001],[15458132878350889148,6272849715387149938,17924223948003132055,5016147066471697864],[38682419825441823,17553343309747362569,9492539936289441473,1650379455894437815],[10938821742966244955,11911901241379388386,4981322656000654465,14178069308102147458]]},{"leaf_elements":[8000553695644171153,3198635298458943263,10440310018570378010,7315337664890314595,12312765973047958903,10587025253602301982,12205524662453824599,7877403182119594533,9924416745492877065,7477659409362514845,15372345304720494530,15932028209293258754,15655568302642507867,14666413945158452598,12360991376765050199,8229761346301287164],"proof":[[16910530206047945241,13220929993480764296,450997063648252800,3924965022272937062],[3512991498726909888,8178335608480357535,3604902357132307535,17286680097983953861],[4109411763014704468,7994734149771435574,9928989822312539426,2061695384689465400],[13923787027285610981,15089224792719600542,7312593884310293523,12701083874317425026],[4311061275323904949,10237307365185888852,4759762726841936497,3629984639313244848]]},{"leaf_elements":[5494219646948061248,60941172992861221,3794231780177374971,14751156091696014383,3601195889719204024,16132136038516730500,12596719155879498332,6403373356144463835,4588690453605796221,13748673634258272997,10908317003063146367,17313990191255107693,11592305040250120054,9487541516301033515,14914001104823944053,13328040857347487776],"proof":[[7752496577628023162,10825079036943753849,14579586548937585926,14596506304271959267],[16608373254442398158,15558480294849148664,3666031975490616406,10425732788875687238]]},{"leaf_elements":[5913797713474501816,14390836815188810001,2598086964460305874,4219281277613110736,4341490336555859025,6837138495876505826,5182460282140934405,12936941785162437742],"proof":[]}]},{"witness_query":{"leaf_elements":[9175229721369342670,14556416345895917546,15776602310476574862,17004431067839643390,17804769784812472915,15466635812433385646,13332503253236573399,815719776635414984,18002490541552562018,6494237655171075793,4058508362417234936,15940772771301484231,11919717370549928962,2304853108544688364,16344771234133648585,780295136722031655,15981528394640215,17359731457903512722,15774292071114834724,17867786073492002691,9746566257322005388,2240954211083416665,15114245561625939207,3666706870361149577,16459070271457324527,369564382305348085,10524064246629191724,15723448892278812043,16661395709502880548,12254679609398910024,17251597506789224946,15824059106480715434,18314104274472645651,7306106868244981644,4611364971632586975,6615607656647504287,7632971673732290856,8233287450824431562,1814956885896712660,9595238683542861053,6026867840080817993,15709705794225924681,17770770308756974116,13739154134952015564,13792358253933258466,17444861132093612155,13864900407794759618,1859930935447959443,12614086949309353976,571834018139191008,16810668278283897686,14606268437729787916,5750897891057832868,3694791802199136641,7926368855238146983,17931680340564738896,12078990716381460877,3980381037728309633,9146887504071735396,7163899706409033244,16571066298563143855,8937027674522933810,9028324287015521468,10230632898526778315,15460692554370609733,15078325955239637725,17776335270996374386,17291478645010372591,3227590654372068638,13564402562731395075,14781800073344717702,11517932467029118566,15457789487304806271,4594811440097669994,12385932112113211261,1262157407773219107,12731197984877739957,8846756127229744881,18072028870694246311,12461105401091101093,7613001284604608973,12162044242765026365,5756736146013297526,12701762862489258621,3748198184472458205,6127699166804908853,249311702631086181,7933374112063561081,8804839519251356674,6146756017941817536,10380323739383876106,573944364765556367,11658815976961031679,14889290667731382172,3088560999356457069,4949139001158775594,6418498434981652762,16310109548371082055,8570718013096930837,16689785198545781425,1784800824316403807,14487462596510507077,2377488894507161344,5290270961679338701,5213170578234824566,1316095705193767128,9204666531424206489,3853967261360345473,5524356807841387529,16877076171714789422,10839142735667263101,11246023304551175636,12382857288384998403,1632411327418103767,8912722770952647157,3080218457844462910,8493515811885093815,6227079835170331556,10626089504395459155,17597087036647437716,12394667046320584343,10524263717038143018,16813855767448034822,8507033343980842435,3643899687590883251,13886782383228551438,5538220992291724115,15385600085747894439,12881052869843068727,12315915509438528020,7463463783413802671,16362126764265486789,14054184744380402950,7770012095696415022,16948680710406332338,11994174327642954433,1539929435976675891,3685628092168109996,16661052514715918081,15659163646858703090,17946138161865851190,13247559865590457203,16770799190355150680,8882145613186123449],"proof":[[3887088285206785884,2342175601188582420,11063357819289675787,3233725060981514169],[15442722679173308528,14097095927096060058,14614023845676364713,11756258351559584190],[138808660128243729,11681578263355438777,17456368508777627627,17384720423611905547],[3183491583805818973,4419696313226248687,14158656566868930797,13671569740393889516],[16844071712099972194,1304738715859385492,1254097516544211698,250645686931178060],[12062016801739269519,11647448753015942074,294289527087296047,15920414482002680526],[4513317779208336967,5516037702502374892,17869240224644943545,6915859737436221322],[12056102076884707466,4586426271621037372,6586116959793700012,12183946408781312679],[1993993098999742923,10602442429301705627,11785613830471168301,6358450955229237221],[7851393450788931644,9323495706947327634,17063638472084144022,5078550185795902549],[4962162923310164497,3174706509682901040,4027282773965939710,9326629544975137120],[13985208319562232851,11913476123805035634,10504054886489818062,3039295652749704799],[3469409802898129641,2695440945051042043,10000904707872526999,970658856091020625],[7902393667093898271,4833136371247894768,10474348895659038021,4444607386201407542],[14397906994854452485,6532824353014555471,7420495305022695178,10858353788495443857],[4660153396613228210,7319074183465722094,11910719470206088219,12234748405667649771],[7668237077592825004,5957116417149945187,16233895935611871800,17838538969050014477]]},"stage_2_query":{"leaf_elements":[12377035813994475035,16217336508727565035,4035573989169859908,13907114200504425911,5772934164430862621,6696164036055587629,4421576425829991658,7346543090142612626,14660500525895702956,10691650566301806971,13944277782043378528,257190961605544800,10880263564519157296,10324349921079796763,13170395503762734125,4634608914221054117,4454480203437334692,7271189811885203288,7166912914144184550,5101050305888368162,6491822301940944561,4453415936414113469,5726382962879070766,5567818577651319677,831151654492180732,1742229241506640981,7361382940649887841,13849558461345230382,6048291083182140227,2059464915537721929,7321012153792536918,2841637677480599481,17064996746668957683,6422138545490927448,15983280359028069911,18151810652693839395,10347322812100770610,12195026453525748676,16087724176912656083,2851034717922090152,173241964734616682,17308717749038622498,17025695933606053061,15875291143788351625,10490463771930217296,11616420260794510072],"proof":[[9337791495341943865,11945837928926962827,1890603480272999766,13636667975444457989],[357335864578189389,10359939254181489936,17609489308413585186,15957703761351982190],[6311211832204886222,6494715699598296964,4699487164043347145,10130418049483422745],[2391020292701595988,11733984394786237809,16878570234969079258,13431592158677856529],[14943611483617401361,1511194913711389935,848351740551299466,4261369626015137416],[13872580350863807601,557788723726536825,10499206017978962492,14309532785458932274],[6056825608341184476,16846022003516286704,14867184647502073645,7470666407007197219],[17711115164581756839,13124203637807481691,678836604344116437,2699368423170622050],[2733773566238367111,1630729238839568914,11320875154500499518,2133321273074753814],[13373596228124801485,2741524384639034655,15530142408639732769,17523947635355251639],[16379461970316932517,8346300011865679691,15526306999831840968,1219056241544142145],[422032310522096343,17764256325171952747,1343900494143177252,1411601000969106818],[8750655387126512363,2789634624507212017,3006804262963241075,5089062537132663595],[10658398929757563147,9596748355288192456,11628783535000573437,13479155823806997259],[3779849034355683495,14682002260904541504,2275567964363587687,1486182608332353504],[10362281280639356971,7426813909066805825,9183188488298461024,16457279526025997478],[4282750637154906697,11193865276873436640,16027026646227156219,7229065506905931669]]},"quotient_query":{"leaf_elements":[10133947242697899376,5618041296731168052,8184267036057924496,1329373948451198839,13420599756962744621,7181055557165570352,18011106275237986841,3194826798018600401,6636284985061369303,1043655762232343261,900891829313708189,12825735055343282978,10108798932153598986,16957721326393585333,8750485171357743764,2634120426158388294],"proof":[[7136425557354866800,1592080191014891148,3433169038794587720,3143242076889934757],[14024150465742983360,7806923365787832633,16412284671899753972,7629007764546607901],[2127880434220722881,15206999199134794420,5964792191951976216,8582960139860504008],[8906281215197824981,13690417222161590818,18330801563534354474,15402548243709594554],[14292762527643080787,16952949705960786929,12163807291212453650,6529880948449188814],[6538094253204172996,6093237393804814975,18332697967655483222,13303186375890633311],[510384670474816835,15435699274439676384,16478282304374684581,11634570153265223088],[11654392271403698411,3860532185716285069,1032795003638822577,3418267062450268821],[5308395629623331066,5373660829131467088,4838209456166967750,4503311199098685741],[9533929793803493132,11425373096313624559,5529389916667267501,12299467993627012325],[11351804336548945262,2533116249450434606,15860283961908234920,870495630071802792],[13545077737337848500,1023203185595784356,702902063494269999,11129817419240138822],[16578267152268512764,9298583282276268562,8188124149742385712,15327922513954875386],[3570346718576940941,4293682967258834771,12273037915015228712,7718265517949749311],[6946880758056695993,5780820478954686530,5356789551841359222,14887115630187059829],[17144836120125926459,15201353506706726057,8965384436568764932,3461521867335494087],[412161255135997019,7426697135882287011,15407766786379248748,4603043754552020108]]},"setup_query":{"leaf_elements":[12230444392335833661,3975254704811814505,13931735295668816276,6969100794731699112,15036796997848864943,6336198787327288933,2584567319603241827,11394045759431689087,5147432496220548110,14222212668638042318,14122482284859241178,10268450838801245532,763138072164900044,9631598770306015028,3997930974536842773,9137110088889283947,2175209227727574741,1871631370878653210,6482302803419078252,10582162711808894284,6159976732053462182,2781132800624335196,16748447106330675258,10118016585112074459,18006713260804641824,11723683806655209948,17146168696827659455,10092617628819347784,15157396725781504955,8327082264120718579,14970360881803642790,14509054213532270816,2418952974581009575,6481521710306736185,7616147627171395019,9762276916389694948,6193804194618497576,11234363773479217300,14110350744210805435,7443551366845919667,16730123351798492673,13102474237838839976,3927431321069549219,7666974784492652400,2261655416115036545,7967258147749383071,6887378982476123184,14772822825998094641,5971954331251309355,16521308176810482122,9631041841468498097,8080818125742326248,13776066168427919167,3871988320751564747,17147151774867609728,14417919775063922082,10625247607656421732,9595232108964859394,9172470488486415207,8014129785049369720,11516677879216321288,8774142248230640775,4036449818074298715,5681304951728972189,3806423372961325282,2044213159144343330,3301168850081308002,4269709791995580965,5467793461698594194,17299233713674035086,9410953306136205964,11342206461380041914,397008122848633538,2541778979585214925,13356052908225605207,9490179864869339036,4206237803610225696,11868252747798100438,1454916753305210715,10833787391027725230,12328206128476481567,15942462043034715523,11755872703467974477,9284230097560345992,15894680840096010931,2610129757077039978,12673559837781650400,16138574539939851133,11400671680896128298,12074903575144395957,6076580229538263606,1209723937918459468,4858669773716551118,11856711024791951779,10298851483927736835,763449605988488871,1849642007999132278,8506756722192437644,12940804999491447822,8910245496823441093,3051132332252841003,4149196789795511878,4440456044984584330,4427432090443770681,12624125530673601869,1101244014980273046,9333239521296934635,1106061812405191718,8314339947251919082,7114960845734514161,11201582728414183766,1694079431399722871,6021999565629282752,9044800710538930359,10172830538944193396,17152127853039213701,3563919356874966870,4561860002236276137,3321669506912268020,3154141046440513946,7472885834568245706,1544256756695780898,14262825689022487950,17153700649255150841,17906569774053974501,15419065074841498675,970213168355126087,7482200198574038795,15952753438702730951,7911887648811343574,8014118525923583706,12285236651094342193,11559355878174586650,5400800679736965174,11677168003531508351,7211120386394661865,7226633291770691859,6209773490149139992,15156587551805244238,5952581615011859663,987665863950917672,10736324322313869073,2174733920253884864,12413392502699434565,5469002813931108091,13619262124623264553,10758578938586967985,15847399296251091576,1529601683202681796,12798597679629082884,16643243918522113938,7313819191810648537,5699369098973404696,14330495204759948287,4076219122418538101,5213977776363383778],"proof":[[1708334075002356805,6531150340160907246,8184885579464985732,7226023209741559470],[17969059401347219666,7271641354180999224,6722644719270815984,4037918068682819136],[11058772996270013103,8388984038393841309,18192890209429844753,2294486139620487904],[5810631905419529155,2440321124008697888,9478688732073550917,12668244310071275400],[17337785623425592053,4514202475141972846,5460402034420924789,1862232661935178952],[5441011190428633019,9586988756663408933,1908652090090546647,16601010604093680357],[15784727280180052526,9157894377597940749,4361912315503156512,17610641795271794827],[8359452914229600448,11898006668724356384,9839896691748074220,9352056016115714227],[17344452252246970724,1355944598990043022,6717938826374354488,2871155360957426593],[5754711383256016199,14362538069058913065,9914550462559436794,15181456175449030843],[907509722779349691,14045383582830625631,16132283705166133964,2565799880480400752],[7736540935478360381,16837024484305507114,11991366911897851391,8089669538723927726],[14749644357872721765,8064600038945654113,12951766067877451520,15213663543803009260],[3726327351080150178,16240499232255735375,6201453908500538187,7190469445668997624],[1154262797978083460,13463081485896199657,11724072421055926470,8851204769706107495],[7148597397650241926,1704733478978426128,1137154492670237907,9481674803390495620],[11103322097618702733,2127780295349214531,9279168850811705515,12312144320251496219]]},"fri_queries":[{"leaf_elements":[2174760469328605039,18189490082139310326,14758439406456406838,619754786042305019,6887471268344740186,12542378014017130406,17527265384591879624,14492892033646585673,5926735463372240913,9815364625946847454,12077329698403451974,4940756570609161529,399999108390600716,18243110337495430911,2548510488713401163,12511992388732542056],"proof":[[6009385342726325077,4340517505213857624,2758413290148043901,6811758641304772467],[1815093978981744250,2614891901646321092,13137106220917993019,8307879409584543092],[7834256594129586221,15251048075745071716,4299288599145413086,15277051458564902400],[6616886603378751292,16822145995823843882,7183465002692506261,12263766506863965682],[1086733625206508713,4219197496748520726,5263135258401258210,11103259693120758768],[1542657951748569491,11296996698957460184,8210144603587955103,604994326504062322],[4561493772836793531,8692483725071711125,12660746930263831607,7764841297983401022],[1316278949323216304,3718116124449527070,17694740078296574297,10562505112619726052],[11675075602334331693,10866083357407324462,13874520867268832273,14632748993985639950],[12283833766033661592,10771340371407365904,12139653394469853196,17266862348736297196],[11587540009946507539,16667675587724880212,6003142045929256055,16175211996397894900],[14977687043746970452,14684043269474543097,16482191445973155273,14240106991907443251],[9716404334617796419,15150862758478461036,10116738246206876770,16159310944564628093],[9921314296445597352,12607643182737737336,924539792316356819,5516451865609828541]]},{"leaf_elements":[5601612149383128652,15484859632470497210,11901607754984771316,14632047148669991841,10219281831559577341,7055578710311635192,8849162299638234143,13536228228083926333,3176078216633383127,13883317530257248900,2030564479436527291,8702394895617665882,1477153476339935858,8862851181316894690,15978593713273735337,11061076665868397060],"proof":[[16572940109726702884,11231597395377421862,9621177317538506159,15755540581716399627],[13908877859487658192,3705215936712626404,6305400342670893843,12980198344451039659],[4158826544291075617,12335480242387528038,6081066229870082950,4614249895229860379],[14765005839771775094,16886631661260249183,281915442809504053,16176891650699535870],[614200497686389879,5739054440931911795,8056625264405178428,10912533683674421730],[14744275089800677972,5745653830150982930,452946266488884976,12161009158579668106],[16320568016833267747,12045919340430624396,17157142182525124554,5315857660150245843],[6978202536854948096,12970296368269635524,9952586971638828697,8281096616574876025],[4541387980591177452,2564083454536883133,12572909133365858410,2190891235877495506],[3419930858868890386,8376773629383943160,18099467646165415649,106843137514098629],[1035045995526660610,13644572249133237998,11620012939398060486,7212075288884837126]]},{"leaf_elements":[5166897607573044596,12299062838129928053,3967878670649890349,10235412709440622093,8212442734029475194,1218776151280123309,15280838874580073113,11983250192487666015,7218724746950909956,13708132664174250211,5395185154475539648,6779437534861757735,16729781836716026860,14214630403588386311,13573508473231846294,8096721176545396945],"proof":[[708085501095957962,3280424226318933082,7699388957090470192,11661804754501470124],[14196659224849785403,14153632301513404295,5049287514024988177,10614401513903353698],[9497320520529004806,1616205190456102258,12317996820881531293,9764966073218471594],[5049329228032474103,3848423750120361752,4553140003660888146,3515235299675442595],[14459638480676571932,16223705341491234006,5614683784987231016,17752133748420020205],[7056643233617901829,17855519057653068261,15322857214366104056,426423954809932807],[10687968705601249996,18083595299393111625,15633247368662652480,1216968033895479174],[12226308802717355526,10631940034649103891,18308154700960691799,11171411898695195914]]},{"leaf_elements":[14001861864869079757,1927691761982461363,10024400185356505851,3699748113090993511,8843033967629692378,16114790552511681908,18425920749570380944,16034140821113926621,7500880626366654815,11946281007234963176,14176493813804569905,13071062397230145597,2011125716542965531,6243402907543742461,9248371163423411467,15921060725074689506],"proof":[[1465145704520905834,18124766104582527301,9186513878598620882,9686907391137434207],[3673356504180688115,5874563162129001122,2755258412546785942,14136178181667913093],[9722042701419339515,1884462433232370078,2745391453288793838,13790024515677466031],[11440096460337808210,4507072505727704764,358471103796110339,1530173096672055472],[8537000182364138753,9846641187754615169,5492652896324277680,353362856001838847]]},{"leaf_elements":[17422870121820784949,9279649763883458558,10392649704438649206,4275716394208445319,14923458923996159321,13441693995813286063,5538784996620329588,2291025495255618999,8987325732237904852,4674522562884064771,5646039796703103303,16954647411338512743,6043644490882419722,13918267068453747259,13542531026347326988,14851488079789523248],"proof":[[10485259444215048698,10568962927375070722,9662708587694725555,9951838211578437977],[7146818340987684729,13421072458407422161,12178806875058478953,82408401134322510]]},{"leaf_elements":[12636509829310569228,1221361967083405863,5202005031054329410,3979567876410885304,1779072914486373873,17530329254161706299,17673969969636411403,1918506755882003],"proof":[]}]},{"witness_query":{"leaf_elements":[16874061286505603243,10272082133576034470,6200782385092353070,5494068393107492714,16614054642155109463,17233589978136815993,12945614804574146523,12373501400631844249,16913172620366933634,12774805982969287218,17530903475065440843,13078333778622294592,11810861235313221576,4517235990119281712,13042919305817659275,12599473661982972627,16450511687752985261,15851174905048059416,4205596400136021210,18314221750743806488,5662957064632740323,16483969305199353580,14871048144327595077,16684218940024290204,3149745713823407927,2270490603371391842,15192546430494801169,10646846185185111450,17871510577933681553,5088133707713787248,2455452869227492077,5249128743436985667,3993477735771297635,3265619625481957525,4761913390313813801,1369095875705662697,4209536133383186237,5621548649194874400,15749638122222973084,8795079284832956903,17943009203639005533,13808145533172948266,3124335575821458320,11792480195065631612,6555720519812383923,8429194545393900836,9408599725503272312,11278585120628116301,7991163442155388757,16841560674422212884,14710638921552569551,11595786651054493192,13258234709529542468,7041447328521203648,12618962064343036375,9969170096791525196,11830530372003136750,10308864738860294771,4640266768030145781,18163058411484293050,2285690099220754347,16428381714274549509,3128121958368196951,12654192979454586855,5714174647591718946,1122917573770612823,2053099740281180142,6233354702039841976,8791942340958520440,11380066746848038462,15685698945055917076,5533750006475609709,14728054333047748766,17854260479556953537,16394049187785616978,18415390776733823213,3617393939582818186,3454614869828276091,13116866365807309080,16562604813536417877,11421207987847756692,2925460129411451115,11526400601266211950,4612668904139782731,3192560557079799287,7641727216038535386,1011878295395249395,1875519326059888270,1195517229823730662,4781519417609419645,8565454645352089131,8618875597217169448,2103323310370996434,4046038967005504044,2384601378353269940,11668762881290233729,5817692413922173198,6140656912011047470,2914840138431832042,1014522844387610625,13050150957414290735,13739791269241875820,12267625520205953146,11024773816092687683,12518091004145832005,249334367686705121,9262982066185880497,17143392472360360418,1091033109985527177,3411580254883935031,5311830602998954701,1986212024459468242,11619338126681396391,2265007366416382815,10563915010210471860,12621025355027531046,2573873142046488368,10576043038543425710,2772193786371485304,685788248200073143,10256961202580919415,175455971288097790,15696602342807422934,5204805821919888041,16870006406962244810,3864161177916186678,1686119537153337565,17032185633079103393,15748795218712969190,16074916003361328681,11132831598439571030,2227497390310287078,7995999247060330468,3511667461934591232,17658268138893043830,8034394436080723128,10512033942367301946,18234809421248292410,5683885653738191243,10090574566171447080,4704498173663045553,13404328479004032992,12249331559152267248,7176631861932707734],"proof":[[12859384958855641802,7087681108075792825,12699104326359119469,5193552079460240209],[10272410417401540512,367190903557458835,2705725995392236765,3044694452260393442],[10951007080066720130,5608352673700688614,14231067673828548357,4658946136434227071],[747578640976314221,17181456429896815935,3780021730757867111,5891433114621623611],[3056942339285530237,330511901791620816,17458478158944790046,5737601339493487245],[11004535163200453148,3630018955936964715,6974799507003678965,1823582542843017200],[12593411182213862452,6731225554140655394,1249142065938691486,4408012443237556253],[11109406963260863625,13069050464444065934,8409923502264634376,18284958538947270114],[8501480408366865102,17483101076006864717,10806707235903498606,9166255619742647526],[1086837020282832051,12584034645140353984,315628504957200796,16518424140370615459],[7035037551780417777,2989100804830266373,2019598911332130186,11976795958875916470],[6336866026099930212,8094281895363781730,1148133135399641239,15044269753949926549],[1197031834290166284,10186825499288556944,16777455698147595529,18341260541305313659],[3561948715413377835,3267971675029251735,9660996358473957169,13987640129675628032],[81404935495920623,10367925456407724300,850417853471508642,6534213597303926418],[7334411300082770951,12086926226931838807,5367919214856517770,16956018325863472135],[4359419555939631070,5227685469558326376,4299489759422445987,2820912454895713138]]},"stage_2_query":{"leaf_elements":[7367053170139982222,17215153353729514039,507819695748372175,17499270682594939173,9901770651534060730,3833400509890353019,11962899394195967880,9342635137493762112,17256285117517872887,6066576908629442658,13497687669046913949,14730622768740766002,1049988062877956005,16918625791701927067,8299517372764448628,11327869169683852697,17594892863811605632,15986054497691964634,11271932197012851214,2263722211730256964,1206306907116226037,11154834304409843364,12224969207599759742,6673651859848416796,17867091175005834719,11814990547183058833,8930670236055397138,2569311662759907843,6681102889518398485,15345135937216827279,14769612543336805210,8572451788240522539,3692204812301856163,13210551740450995327,13018858192241882218,14849922511803588864,13760629682201991416,12971739547171792014,15135866398897403326,7547966372652616332,17397328178857367123,7523727169489210158,11719863037448749381,9290041244117063007,6000172999337592299,17513758846075292147],"proof":[[6939509592074380063,11223957484193523789,8733867139661990822,18399264917418393736],[11006038372272207100,18260524067059564247,15336645667329997895,241356680938047847],[1444293587956812506,12489550100504221187,9064971130496306044,16809487253294941132],[8259526408397447903,5492677554209994529,3965811299316125768,14850232663405613048],[6071416155677376979,11717710622367077009,17573029548677711589,14231886523876108538],[11636833332671222286,18085444868555612251,17641299733493573362,14168353554268877201],[14849025084588528628,16821279277094077275,8308550628985733582,10234319045868184131],[9839816326364312537,9298588110485026896,10594906971235314600,12945006584000739494],[4846310888582033572,15209808775537594451,815796086902571859,4995894460103191521],[14350652228805562691,6138315936605940160,3552738797026444080,515438387552717290],[4129808635210604916,4103851672718831415,9727770493729931214,9869684238817078549],[13825814927071071053,15822358523605907232,9833941502730494281,14531689206429004583],[1313700066651202991,2109859993998329954,16937637041411454006,16528548110983641529],[5923724478671214364,3073193792800089748,18296917939765124582,11537342783483581731],[16365142889030041025,12082376397396192091,17047384251832579857,615906979646366573],[4921770710594290304,9185323291812345458,2514968554878497274,14426577779788055045],[5540963335732028914,5019122691898865913,9979259034692188216,9805535735755270370]]},"quotient_query":{"leaf_elements":[16762688128138224817,16401866455970118404,4217608738805207307,15921047798444129636,6976687556016672589,2088717142003513458,8183837004411197823,4678966019023948270,2786084284218562001,15260939624445120910,11530606315782185544,9187963934936862335,14345389570258330679,8258216006376525631,1902189909027075726,3743838837488953671],"proof":[[15315426633341470965,14728098560053020463,2833998949422743770,9129332275695145859],[5035751136431501635,5351274915497951057,4210323728994516441,7305185181290668004],[4149387661634855125,4447539944746021483,207721357446756370,11887512896782109407],[97075422934889465,16756600023699842824,5274085350743670402,8639357457445537635],[14920985942150521165,17668810316781022443,9346570819779559995,12128694818053166770],[11531555748804927753,5160925653693555525,15966261388395846141,4092052672939795323],[18282539103216103974,11498103177680560050,12624137679119172347,15760299708332681676],[10027223471078618190,13803093374741849269,25809744624216253,14769716411531640497],[16409514979469624430,275560712174001914,15094353099603685209,17861043203795668114],[7821165628921208699,6997134983282180874,12075224747167956464,8318455956078502606],[17471135305809995772,6627210981639578868,13346980021127749866,13749598657537111698],[15143453971804138659,2438852698148516618,15035521472565277820,16126826832034397853],[13454273562086787859,9323916900362931470,8607649538168749377,7557690322487559084],[16031248598813108983,2008520673466714035,4279745924199372859,7000800584107661872],[4003442918998192539,16477696447018788789,16902533597044133140,2075027214351388046],[14204652051409107575,17986534491637893818,7889389594308946328,17309631168896672534],[2791882030703869011,8386224077544136348,6613824618578734525,4331060394536153385]]},"setup_query":{"leaf_elements":[8077990544821179731,12684318345424129648,5303660896726646637,284384950836658390,16541363906390467334,6014109916357685729,7002954042473742218,362194430581027286,12966723045059085120,17573220989078040057,6991077478394715502,16206190577030956307,8773932096297623603,13912564889961969235,17990489314031937481,11579623318468130555,746946564866235411,17541250555496672523,16493490312270317941,13488274794865054592,14466401970355715614,14269921266657175978,15213178591519057492,6594584559007501108,7758312387923464422,350887587762765462,4593067640046669305,4921748199947784645,11784607096001317887,3638801820757084175,779820292919883764,11472813776154301410,9765069463398335169,14325072226595949207,17253649161123623365,5961485410481526100,10242041974622095230,3770719170465246452,3989096882039692723,5821788944805317943,765605708466407730,3984474984798505670,17962766657712758695,9198961983132095870,620836770217785688,7495443346358648005,1413840888147286559,8986329745311001559,14726687859225084976,668508627208998257,9781173002641676471,16661694410913372510,3416291477464020912,7683395753857326961,14123653957238304359,8789742138054837393,14580513724818948171,1647594558947373439,3658710218686190480,11166881900032607693,1635529414974156031,298542382634416617,6058385155419643368,3970577058567270241,9702165805953165603,11780093462885528588,2243886694171598198,17510362180941732443,2538101076629193891,15002578877707914461,4288096277888440259,17624780559579456388,5925565872695621947,16121653884965829358,16499635582430323147,10138102319807227858,7553962086532004096,11966806704544458332,14426664971378704593,5278893272686228875,11505297585320761670,9222952314992071530,15827220369224989814,11462760467672135353,14063417272511410406,10261140880968873300,16925793598245564450,17799033852268742862,5770594455265141347,12175651567945434928,11369238758728898631,6263143388214696900,10367171766911917449,8849690945027217232,891580566995899589,6521633571331593397,12425667580553197677,4249599502093219865,3424246873479022730,7475165478827555240,8786062891764377284,4922369917173888662,2187821771682134420,1129566773269171104,14875659729843931557,14775060109438881023,1275716081158720789,12185996793465305757,11530046817949825943,11515780104154096774,7843889144134253219,16815222697739871563,11715130456148551701,7013541208285875468,15447457393053111117,4116148266361286142,9368591622308640402,1148398822843614982,4170623865595818599,1824227499334467932,11474183860239504932,654369919109991750,13285182076401075810,10964594904590057382,13972687821819275350,5844363027676859453,10512454836332332213,13548107920462390818,15883653600196157915,12599634712807458953,15169888645565650236,2666833237612538991,8662000867328833779,3394715066203038261,7887125568868296562,13917071090742739538,13973079907406831328,11074715187446195602,7671179451857674268,4878162718599726502,9862055522675098390,1137453756833263506,7015493569156291438,16818091848739424077,13155085367086141340,3554379779435306694,5823895599739832132,2910228781147808608,1612524559799289876,5003834592029926822,3981824609313925294,13762019222191955480,7981022160394826989,13044757247202612644,8855361728938165988,16612509475264656594],"proof":[[2814979246162927849,2517026894100185793,3596651575960791172,3227823048025951323],[1354879224805135840,4876247978970041159,9254637054861269541,15145503651946270564],[12159130904817337644,16217667201740010397,5562116493275231752,10881335141005936634],[7728039412217204755,12290190169001654391,13513782353873684388,11478284657677204680],[4051771853312443531,9165050241624740266,9162535607886378402,18075650366322919967],[11186729528621682777,12639026670976879209,8059549928920376021,5548064169461114203],[34647678816213084,8680361077268804451,5808199197807283534,16565024330257918016],[7954584597751927975,8486970757759271694,4733438170663981553,17439795961064876589],[323332478423432055,11688933668250602866,814600740329941228,11167386131674419004],[14525111078498210491,6365900360606431416,8649938882169449812,15535939636807952699],[9227628680742595856,4399744027092579491,13265486878160199738,6201839493469699444],[1241500961333162087,12486649780663222833,5527112847677693429,11949262594627162601],[17460579002343122814,16453975255360772113,13397989421392265131,3530035359873643077],[12579251781670942083,13630482492929848577,15955014942159736979,17964129573174326436],[3811213772093117339,9739305535759354372,190734193439019620,9502995338827106154],[6630741113735957717,15813057875700594096,10523487808615131770,1357208547331637938],[11952496666317946850,14106701870998791494,4928685340694513193,5844896803328937675]]},"fri_queries":[{"leaf_elements":[14348713986167605638,8365868954958637111,16795790421784348366,5513745139308162044,15024269186461764752,7571046029629781637,16015188285894362975,9090492609265592121,3180814598217747417,3594255601572405980,12532106894957862834,18017282357517715008,2885929700537410931,8084191854768963004,16326411443417288757,9610817531220737523],"proof":[[9749059715267376915,10363205371985898683,5141755951136277616,5263661367047500362],[566171516968542178,1602052750443437046,5008106086659047018,9968170250805953700],[5694890678450116568,10718648408659841101,8716750623688723031,3778922161120958234],[12191607725825868192,9350982171144705969,17793422690930266830,9816975983961254311],[10331480275416727979,15144469308452578883,5554317371902137666,13307731869933397806],[11050982524218502776,16992671989360335077,14995088535902203138,5241576090669303304],[3149778986409583911,10335353028939432709,7974191965655861730,7055725982323256077],[1231737998868578125,7138568208618311364,12445401723151409674,4557825784128658142],[13337197793053439905,6811655268776226404,4045097681397873650,6320460263056916549],[4987383692535036886,2833584223244858334,6652397756633172938,5990037562572349883],[580307337231157396,13958219004691388512,14204384074305022710,6550259343726482574],[8438016631710116992,9552952154333545290,1685815325400124734,7239509801701855884],[13853149763104721902,9914822014717403361,15444810409845271004,16801999471088187671],[6264189890197500469,2505798765283131806,18134415645551471218,12796488203245217184]]},{"leaf_elements":[10625046415886724722,14715590795074843399,10238271929274455322,6975773394472515224,16668679983805263046,15399247010759658627,1873096911750161753,1556348266832207142,4792942036336933330,349367742882184724,13639753892061372635,16228548673397025031,4467692821650680673,13372072678759475354,18359506318795769926,7626776384310954578],"proof":[[13748457664748106353,9692081390518573139,3496472878477961032,3130838241082660429],[13081520711085087988,12495977920156042013,5443267612617276726,13207722577701963621],[8363281379597455967,3188464872696029367,18377081744373938538,128399088137786743],[8729681804965686636,5999169002342127344,1295626465162297683,13212170482420909345],[10980814346525325697,14785666548714746776,5361370705092190154,903159689757549532],[10724663272791309312,2376414260835912900,9459940316984398124,4078982173665359970],[2496308067692543663,75946357227805193,14704281518931455974,3327975928860550421],[9722563942442034609,13165804769973617802,17577227169646499061,1874168166542254607],[9512218379231635928,13876874543639425572,8088230262087341199,13149035866498979068],[9439390162424317968,2299459755921043334,1792805760344932658,140132355022027715],[9542339140070878958,9433221299340662562,11624070632307255800,10202168923944062537]]},{"leaf_elements":[7209251906390865028,2917058473480366512,8177190180843871064,1871787882084078513,6000434960775404896,15000798394137924259,17217429302782328573,10693795812842396738,7476276725502170245,8132431155826654892,12524908093601827966,2999490215769424700,947693572158027150,426834863251677728,4885965323797986189,10395548316940564423],"proof":[[11887377157057466148,16986918237279901420,12229044808578601280,13360291770892802687],[17515409985373934583,1963877652704202995,11067303154210231371,10140183618020782897],[14536902835627534267,14534330449685509986,11379588192470414265,3416510144645866528],[12455975401578344708,1044171767172369369,5047684006743960012,16147554160908924001],[8352852948381643288,4246665217750920550,17297841651271144411,7061789798132153796],[303726680414620903,9986080263345663337,11531443281479644608,7617939624086117313],[1698147613861660988,15058150017661331147,1237679489493475304,8687194445027036436],[18173370157583508499,2709233486588566022,11030139920035397110,13654676242878744133]]},{"leaf_elements":[605188161146445630,10803074315484425436,9661432141638565376,7595746432637834854,614340761475201383,16349497613974241655,16984067551240243863,5357626289332020316,7825330570436660464,10358776805873685983,5789209486002928937,3569829953933799847,13489531966474048290,10927053847877291538,6399078487850979789,5714241362176100238],"proof":[[6470846707988544840,7339833405866984325,12821238701690704941,5256189934234840163],[4106332590172770750,13451436797104216390,17210812377702112116,14670464380484022816],[17604057367588432336,8413093555034859388,10024525268100557153,8056361219915054400],[12987097896163666884,1767370316000027302,4435634339343404117,909909342269393211],[15467640581700449935,3683179857735655608,4626913535802417700,14117286974173883330]]},{"leaf_elements":[3447895095703013693,4553481086833399206,4847734805967749192,14366568436030222650,17725151908213255208,6850926251305201876,12374450564197018080,5797126602522335331,11035407726228850755,3965237046580468058,12204933946874184704,7351819631263025846,1065617850432847151,17721919357762073321,3976690589481041656,13513722101894862596],"proof":[[4931980653673886728,15305696826609055110,6540482734836369803,16518953493492405559],[15129585986487152700,17576030168367934235,5498017594008677138,10324092941631561055]]},{"leaf_elements":[10666499788113613538,12946354179588810142,2978942579100575765,17219500348011935376,18432379563349423049,17978726315520234670,91014601379555257,582079298344061305],"proof":[]}]},{"witness_query":{"leaf_elements":[1299900833655442082,16534282534656912761,13303089065834213075,15935229642261980653,14690060834965420374,7023166750599786711,3001832019556662364,5398924727482822722,14674460347231871373,17918130694531966597,2570464589198902981,14025287273480414302,11376078082372245494,14216506954183149813,15929804920654390763,3727404387835994047,269640816864668403,13919967415708507944,11259326675815144487,7046623847066023071,14375783070293241578,10794787271578055277,10280098002218142024,11556530523986108350,10709879276474738383,10745968824989726642,3551402180906408664,4001740988475943043,6722442263170547172,8696888066311712828,4787124590489273728,13303176098939035281,3145450745268961185,9908473598111374686,16867013011240352201,8043803838893093271,2913559070907824708,4034368953324938628,2051410174073372323,3961069232286060067,6744494598554553621,9064883266308676623,12334861533642728026,6103115543150309700,11245429159907820160,12446250791824675717,12832654376955524468,2362777682195980048,12424500926614828327,2907231879812017068,9377243784785011261,9528420240472245580,547053774484558221,8416987076740608589,1611320585278181409,8053053790238354148,8084176531819102948,17911479401085107653,1362671426590758026,17385298809983866756,1310100929390857378,5462328923768537183,3758066679016677859,17427100762600673638,11107531513042170844,10637343283606695092,33410873240642214,16366979740964678268,12431922036359341358,16071686115645969055,1093979751011207175,15657562032300089948,7639918012161304666,2908435066429493525,2980697143205726885,14511233754843419126,12482004452130204535,6429555582864422029,7969499002210720658,7563528419175384202,10592308679114180339,1265257596002501629,9613065912349943702,16797753546676027709,9421459105399707152,10134028372732589261,3366822633796481223,4883484046337739712,7009526605736385677,6495879768780888992,12037252295148894891,17321581102488008361,2502588444782280310,8867689902644597036,11079294429618075655,3168665605675715931,10229574964460934703,8505848493010111025,15497731879239805845,3083573287744593720,3652482286093591604,9534598938032078653,6913111738387886453,15177468105984627785,12364665639942888462,50965276924563906,16507544150754342104,14181615129754984170,11444756707052213991,11858799064004122949,16186685712257036070,4059967987252056818,2248059737610238461,13048670270352626851,16825807463645566508,4655973972732105710,3766726963169439950,5353310542914006413,17646024790765752654,9826133095055614009,10926772736994535002,5177809059611974922,18038304240191967470,359896759582538810,7403891221600489143,7730246320120243173,2307099015845381208,3604710744368551524,14271061898293732905,18289235491877511984,5559111788610927735,1629907845829488834,4084367334752338213,14471180249610746055,5118328728453603899,8735437108676057474,17139397215671410209,5727197447109123580,3072224931878455760,12299605551842632392,7909203855144927287,2219687073411434668,15155513793150379021,6007668463869193140],"proof":[[12131885223937146033,15701052497310537747,17706717205610287875,12625607562472312307],[16536275172391242145,9671627066265526796,3370674710202031412,15216471862357236599],[8452441450783901588,10994519405936366555,2983068395229518227,14912094397032460419],[12273005756059868936,16830931068066769653,7110084439347273071,9921852822444812378],[17176638532805779517,2855742090938477007,15097783289524119237,17254221462949594159],[1849952524091472206,4584460424734647419,3031631104083829164,17156218958341639818],[891958871267708137,14810211566548658036,1733710129843850967,14137463976861018740],[17234718830261822255,14424394209536878749,15712489188787356303,4423931537191780134],[14149931715699366208,14960312715809950315,16930250887576731678,23225632518481616],[5486436746056288150,8952811098767157048,12077875691461760799,4954044541614904437],[15876145424356178311,18153557216555010091,13747277691349151718,5819205121692148918],[6756330181379847541,11478805794574340050,11839326402240619183,8672910382146977594],[17185962594211008015,2402365526803167921,15324228922694707564,7577813803322683125],[16416313127879497767,11283712842195255990,7891409969594794740,14888188863113442943],[398231122643392427,1077515630903111632,8171464226775056111,3773838388961395314],[7049343954157092833,14391493793205640963,7395172756984581331,5113072916745052878],[14710339626193100422,5166397287786674443,12877026722859487242,10407735240586944831]]},"stage_2_query":{"leaf_elements":[2808236202245270772,15542498171572483795,10760134725789222581,5452288617718447690,16328863891380249244,13948940107152388133,16852809845594819879,10941771195958551495,11992480396086445170,3595844118089950525,15863637281684340314,3353659496921408587,7916529212370434547,16594063446615479511,9823589665915197817,17677374068027501040,5390382206132550864,8084813131286574489,17777687096736022682,13064772843697004661,13022029169760482461,2727571873077423133,13170367833170536193,13669594996797371511,6480460571385390368,121355206125605325,15553114346665884497,15175593152882573892,1872630534245498861,5705166950372833731,9686947780261090669,7173241944151666968,17731910487720036096,10480914192701091730,10666911626674539016,12377688591238989495,14003418281669717623,1776005651227164276,3413102648604932399,16261497734111816024,14110311832017485196,10771834901300823663,16333961409007726075,15871512985735007288,10229582492725828456,12735786878000859567],"proof":[[12037408553834405480,17003316210141249066,11699003711527794653,4076358690830765613],[3891306060982317931,16218061952654420015,15131074135691634742,1544763516331775569],[14445512321699533505,14121268729648110109,9707027567578473670,6001100673071743268],[404417261343480409,17987706089783548306,3235089466444935923,4682368447416309398],[5073397013923242711,7658457046220705894,13871249145123010345,11210129706813831778],[2796745531856950318,4087697182434816687,9111205302913843282,3340850073951273427],[7129586788369168961,9955927409989195132,10921720733489505603,16996143983002898235],[2958492640519213537,10002013377548073296,17726866054079802339,8201639738720142716],[10883433208452401206,10213822365258967341,2696327117586672812,14673866061024183442],[11979631742546411587,9927180337246101132,1540327035476127809,4481519182440257490],[16973044186761945706,8061110601173109545,11299963775141115200,532253136470371932],[8711545899366666194,15334658399060735073,8515831949898450620,17756485371181294574],[3340387271794327875,1251197004046925087,7893104991024589904,14249515019403817999],[12148236292999639054,7590710492859760345,1980637592013849352,3723113238523705697],[9088403170230633298,4772161975431710649,11728304519422826717,9718595746418649269],[9069739529505737466,793676914951333750,14464203160743970347,10684389483843064330],[1135997963394111510,13275752990064275231,6348311180324878415,7982923292041772706]]},"quotient_query":{"leaf_elements":[12223361006511290157,8127177002781513702,2558605725747579610,565761621635589700,4993218721531211699,11321373766981457677,15636442009359346776,14172645749817099193,9029060184183340728,5873564549981296269,14135291619588911917,5852975501638245088,6020457266119976539,4789341447482318918,7089736494805401164,7027135716796874997],"proof":[[1795846838804903587,9446575823824616497,17321497193213867748,9906469970031466593],[16758973990550151629,14267306611355077272,14117552613934437883,1470131094430071584],[12620262615281757047,17347220035869359017,17362898134200372985,14410473339028743385],[15028254705295167407,5895873430031514904,11346261745191690002,5074514468848246871],[1502817588660647358,76401557036533426,2848457507933134672,107934404634521624],[10240135473138888574,412733398963693951,4945753076528579274,7223676635157668819],[4838515906217866512,3542184455833763229,11767891501191648444,11616670390868369883],[13953520218923981656,13814006447345864232,6215357473043167214,1285587148439382876],[6178458132853627409,6811619439523233749,4864956693533873889,10737090054406682570],[2774104247563382471,16906780444070092392,17630831595818248688,4535887684320480477],[16220452998105796568,17754879855587613613,17528263876795686243,16749752059711009852],[17958527212874828412,1072619381323763120,11646510865249930415,13796094632028797008],[16722321007475928859,1043102131177689182,7161804069560873222,17963586484528766453],[16720737551778299070,6117863868663704696,7095011387297801312,1982089210033508086],[4185821918032747897,15735348166646380793,5064113847745346115,8556318307176491458],[4359957004431156532,8965941034467977781,1773912866110419813,4664342605257984095],[12530437638825942509,9467813558315705039,1660881245341910574,6918973135087974952]]},"setup_query":{"leaf_elements":[6820346159580647467,9943358750887076227,560020448687632785,13124953571852587452,14643237423255670710,3094570159844907731,6444183563640177788,1182559612943712478,12649343070414805922,6032923549061737054,3653144309887487180,2235627378702489770,2707726059942763531,13023586544451704415,16749920120872522903,15038749454748519566,6411326814874162507,2692368240911633992,2743711499220491795,9124495122927008309,13290964723939309262,8902267862232370027,8574428681128302561,5433024474584961412,2854051948182975969,12660312142311849424,15067254458448740664,16864413464092938764,10553665553340073555,16919956658492013972,828755948013666742,1022278851002331654,8192106751153807532,9530372038061134668,8809173159658660848,7806472046837677368,14104184026141624810,17025723548419498522,5259331777379416015,2273307949560119841,18125686413621026602,5623528614912872997,14090996363367624937,11587973961417416109,15398835691739200200,3456057465996335520,12294979176188155941,12308007260379259767,10903236813532774857,1126092385318507202,10348940687707535254,8904819894654024078,3245857146390641292,11874866774915718329,7233052735569235392,15090487285350327463,13038984614137774997,6262201556057079963,14628813583236164509,12531948853399861462,8228236543439071392,17527745885505477926,11871584125281899465,16407445516263656655,15131230240213143507,8269468220923729453,13741836900997152071,10670674495875806420,5238903155893601833,7811238882083290808,1148444400670666553,15979838783493320415,2748523685496742264,18016071802060435188,15813424497553683665,14101672928566342473,10442865185957752019,17334201094582270979,14508873105264145738,8865084241585149702,10387294475380116135,11718599705193701514,11912656563682936231,7529729096437139270,4478493049550075315,18367778435630945182,4397321693017377316,11564160995950703009,14861331802310760989,11929998347150687176,8541831624788420381,9977365443736495652,18283685367097424104,4867045788914812415,12015875918044415300,10476471770106544593,2012195165638166167,11549191817873407377,12378559146176100361,3055316942002449831,17260798150984245593,12360939240827930633,5102454699593378301,8335249943004127392,15958554065527423537,4286842764414327912,8545183733687801139,11194952175763669627,6434682406659881354,3809675216856202975,13369071809456453353,4461948840179400650,16596869271678741099,11395995342938078055,16183055491365908263,11503432114275780439,17717611462358600971,12593056673876493017,14576541893893975717,6907042957085695254,12134843231668750787,2866966943718154679,2157762751090824782,16021876802392986294,14372892943359488749,6995719180140913006,8539085403686390526,1385508442636506161,14900702292772086130,10862753672833083003,2152509248984629618,3927628279622795876,405166075449651760,17564451839200151540,6259125399231258653,1162991300352620128,15641399832658324136,14102501453270295806,745464227138240971,4800825852359896640,16425269983461391575,17374627855007886710,14791214395460022730,8332235133939542792,6999195868576940327,6593025055605645113,11940864577670079317,14841250215346511102,16456477649814937803,11055099360873654284,15042101588264739257,10555039113687037236,15527795436468180199,10286727538780495866,16441808429682104455,4467485554603028168],"proof":[[4552586996635344625,1350060879091178447,17611390861832911684,7447383978822986036],[12454563482646821914,13227308604652478831,10172981932670982843,13032774234159019829],[8304183396265717156,12595478408464745748,14142132821899406713,4948674538564940283],[17861840208544551069,16043061253327899730,6477962659778493193,13264209501416285606],[11765648590326591259,14109335066050260762,17433226700379867352,2997157125864558687],[17805811527132113598,3515516063038729062,1823241428076427504,16184867669619261575],[16641673645025528806,14954970349254551558,12971276689734886717,711232109767163228],[1441386996689548087,16748847530300248373,8872613477442661881,1926544683764664992],[14064858160942617339,11905193820428859266,285369982308307420,16669491697512478176],[1484983022004807380,5319412438760637358,9060626086755242031,2454640994237318964],[1337781529365980350,10484124136929726257,1543780921280102046,50556742023442763],[4061098796669560835,13456051667886658375,16957637435543012787,11527897986709180315],[9608637320385740969,10915303661682670672,2701252551658560612,17867607730859245127],[16166008489637773246,1279799760342066913,11042046517293120016,13606881585610663231],[9994972003397564105,2959648603750529511,14163024019547965359,2585123501789816162],[7472052915157579580,6454707544650764846,13241508517962884643,7658945900870394285],[11786672773418549703,2339467107386851422,12140533047963330746,7373381974425188538]]},"fri_queries":[{"leaf_elements":[3383783302081861548,13729929214912562931,3842614442359459257,7157320757740131464,9413507951184962149,8066300961756644596,9999500919667821703,10307799126917852372,13882676822060294201,15494749234867023389,14424009885687953794,1928293441767088111,487660293150389206,15271167317151365964,5806301753416820887,4505854765937449271],"proof":[[6584802797336863341,9475581370103592727,4480935256822828893,14611397351528688125],[12431467091617944153,2647563634101847050,14337512326756794440,1540236102447355033],[4031624656459519282,10017845566004776335,415048576933033055,17006630954095847300],[4587999183689255681,6994498290318358312,3126548946217460588,13063870945585851158],[830696268150475951,13778327115887714401,7430335637453184190,16901873981566635801],[2210744840533097595,9020425112447292322,8504663446606812519,269419387288446536],[16413579793260989041,11973347965930021673,5301288100816323783,3649874350991251467],[8045466030713467810,795295165079563048,3465747590080960401,16906783570269314102],[7541615486353675789,12376930855921130436,8377246465546319973,6215508440806797622],[6943372219014379414,17888779167727329974,15882535811530209400,725877029105326639],[4491773661715036764,14171176404481372813,661677434233046938,5497373734903659592],[15540064237382094286,3313093377055220107,7825057548834223934,5345285968476203704],[8565450714688367775,13371411646079149581,7669076451911119034,5609613507105328615],[2065112813907786203,6898755846797313237,17320045911186699311,10677055216998779661]]},{"leaf_elements":[18222627103851116215,12582093518246278990,668103003018230646,9271971321321968615,11303236669594416509,2873676597940485371,16079260218848372622,5992571059018554629,8384514948125922782,7212799649877033125,3154012958364714009,12933885299756497827,13662876640672442086,1349768786390132738,6638062989701419600,6824868164464672250],"proof":[[2127271596297241041,17520571290239292654,9931053625896617648,7672222799784957455],[1289273010888030611,13172730639669234753,15366998071835220134,14623755906208152594],[14147356642789220203,6822718366114152128,523911869201311288,7207547758734362152],[5945072598581054870,1646214387893749780,2152675685170464135,15354242394105481576],[8276431584075193951,16252561652127045666,8780718880853231407,17815251129446269541],[15154245202904767755,1944902250697221244,4122572895987361890,4258270032169053003],[7982844263994279391,12768365078082598579,14400731034484975417,6048179088496250966],[4012238349150723203,15475834714837565938,13798406662550217730,6671721927003531189],[542848223190788416,1506785852940021233,3207114844624851525,9598216552803946550],[7872375859433308862,12547335083355183725,2049786543156448692,9084700728308976857],[6068200341678021668,17238405178273883915,16254243979175388415,6326469122072930844]]},{"leaf_elements":[12406242582969173078,4958067123754446039,15820413704016274061,11766396150987340879,14851311347731636466,17711714075067839721,8254920757250963002,7641711980828570001,9021321000026366263,15927281383180992821,14196426594261850963,8999807718767023529,3393457500472264308,11545810752106949409,17585212629562378387,1280453815587053299],"proof":[[1935597304830414358,7174973596548825064,10239602625464672742,6272463128354052871],[6834695334937902953,17599083713401347195,2382877619754580691,2566645068185979375],[6517499353509548759,9573692284012163548,15610231278268098026,671143825955081069],[15629263944427010770,9249669331561847631,7897450308111318990,4038386292089453526],[1029864909632161683,229958764587629181,2852611746439144198,17317535500545670382],[14752200600324885730,15916928362011918693,17708939923110433162,3063340899749603662],[4425897915657748671,812478123278601336,14446386344517017273,2479368791048095681],[6284005312668722525,13175024327537991261,5546811104920909949,2703000136490581107]]},{"leaf_elements":[14435557163062443704,6994600743254273699,1211576302331739856,17614519201122480244,11619332603223995802,15609029844440924736,11729469717751699447,4378104875673563545,12362743141386379715,15864858577743340157,13908312719251321655,10421414566698649693,10074992441682560162,8986855505977257627,5022110441644760876,1455085143007144896],"proof":[[3703846153268668725,7628466044361679691,5037624562018264705,10053316249922015686],[734501117818705858,5836905463483849422,5571639830852080378,13195914388199850733],[9996949731472101347,15815289785699759353,16091488387712227042,7938774201082856478],[15183664090613473060,1501067564438234346,2135154504861079625,2969398395681691923],[17991506096714915795,4636722536725601757,13865614444769694335,8815772354958363399]]},{"leaf_elements":[10912580827303826969,13112124498184870572,5166031771435844608,4246959628546674791,8337537940124154336,2808515550656452715,896327017507608806,14965286150849039867,12366897045461968021,11139471698543338371,14093486012080335828,4141646308185794490,9103831047924060398,3762366279174691358,11512998418801433510,1220189138193510249],"proof":[[10958797391945941300,8725990360423169908,5482578788976588944,8844326393553402907],[10835623355140351544,2411159751067968680,17855867681805886030,86569936236411870]]},{"leaf_elements":[13912788208633012260,16592364955197622110,12930883254427910878,5599575569218380943,5682660096836901399,4069773254031359724,17686759155637027087,11829746095036037227],"proof":[]}]},{"witness_query":{"leaf_elements":[8716272129438998123,222127148525883421,17114494034152717864,9218823581117062438,3977190781011241011,9404766036058554558,15709349522462057498,11652767639577391887,10819227119638968213,2232408310257367732,8609832227700027218,6234808629719899249,18424943763598445519,10712718499893229040,12130450256705628324,17916375751963976454,5102576815109023260,10632061733855973182,8854868396843276458,3706311254076946174,5692710616135981662,16694078826067779591,11901168425341645363,1809237567524691103,17813370495406917951,14681776456010520299,11252839494396915725,9247521780220655617,11957493515954406085,11850064174023602680,6310028606577260973,5540427259581217668,16813387161984784988,1462387963797812467,17386072776620085803,1736320876800387912,10560030535686586706,8103169290343262382,18296202799621223875,13266065826298179020,2948474076651800305,4099900212874260514,16239593955497601277,10763269075775090456,9319440244050044422,14252101199331220293,13985591823042114079,1194463425476525498,14304746147467828628,17468685988458419562,8608249165892136657,12710485158877899710,11463788217725099683,4937683894565300187,854124128537431662,9273270961097957189,4797760773554760054,12172840887201779008,16548132749922674754,12924793761521881153,941072199863152039,18275350973525172051,2385628481868093435,13933976689153895743,4341162982676226637,6088334613343201883,13255214266805241238,7755992253884187877,12913016611193442249,17263390811297951607,15070217652657223472,14684515350008708423,8241116482754008097,4072688024003098893,1717418892493710940,390935129154817173,14438736750002233806,17022296582470411667,15362953999421014597,15452518129850372631,14676492612596877082,15615765465628869144,15755830920987641395,4667004431920880299,10070546577762949787,10644280455517186822,11616252090177041158,718437964044695733,8710543564137400949,9712419603484818483,6663217491625521164,4232040455936183041,9951528401540031630,13149229583573007096,16586176787448744761,12964278570440333186,11928748946383589114,3143785895657279835,8569326205493567785,17169127937672748716,13306696460297576883,17589516988876387322,3240831283762414275,15445934027075094331,17161687163706025134,14740878342664893264,5223713586698518472,1179275054982799079,15239223723208945795,182575358686338420,11251319015780487620,2296806562544277870,11825396687615116150,11925593621341893741,657987984065334882,5498797002782923308,15258188037502158120,15702470360161771819,14997851052239653746,1156890359453660458,10069200547759599193,14191171659990456964,18328578785113835450,16511812914905734113,2036439541220037964,16743222175967691853,9076273129918103912,2923626448347777910,7695586584271045507,17843098550436945144,12464646675993971906,6229919621905872765,8085432152675208132,1581623509720944188,10326880851165185598,8934053573256220053,4438724626484084999,15837346950934616530,1001711791007895890,14341983204918196581,11393294879843974924,2341524666267582917,9785723668861500421,2637004803665489826],"proof":[[10421824382255657705,17211996529695306713,10900261053678836888,1134631831378595855],[9659365361233493968,1333087528548507874,7757876827636571934,7402398659020940721],[10388347553003713497,10968933504864162073,13883345818470269586,10296423976006640501],[8262367096179335005,7371506477496567803,3605446642951990142,6792435768570616600],[5693767159575927199,13938172576183856862,9298142994016418923,16229435494347168409],[6719930033401120484,9363497416323549821,3574010408228951443,10142185143234599711],[2632863681563167113,1901883410789253958,18231528459680572100,14918551063237686178],[8719011254890162869,401033913002491509,2652414095676281253,9380822724125082025],[4886358723986618307,3741208868359975047,2033096986024650495,16534428634268081045],[14923308829524265115,6598226018664196543,10686988746436482661,12771599396176537424],[288781005000790505,7224638337994503693,16141435012842013833,9892504054686022132],[10160136958036438696,11877763774817745010,3877510526109719407,2914196045400845357],[8374365300405837357,10551573914858174083,18071514280664511983,16123773871316434765],[17367293562867017125,3092601236135650562,11570291466895718510,13713774572115258068],[17399315722107599347,9975763854577449947,18206249874266513158,8851869651638131737],[13956091290665605269,7893671946068161603,17280842991379820366,14844174942388040798],[446318376307115417,3375364935197782891,1913390476604132002,14742194311215528796]]},"stage_2_query":{"leaf_elements":[17906508015082925373,10876559706272468973,2146220099966438855,13095269441903010840,16024320372289755267,15017402237134493162,12825853895432833697,5810246080312321732,16712105253621902034,3475213355685183269,2812173550442030951,10855754855292619292,9869666762113126169,1740300762193556393,15724164978551894862,18300612314355185279,6234434664861397625,16823993879908799501,936380587171518224,17840257185943994957,10507271161940977181,12985331283976669728,5030932499909712083,4312852607339042334,8655305900057145560,6572076405511184098,11311740446322523108,4454085358802969165,9288526541904707957,18422163667247684826,4400504477771711155,13807268864983935965,10883832841836422236,16961124657392735057,144065983372530023,6213644776197109540,4228857738852398338,5698399051085035068,12063133478326137736,5380505129291643682,7542115086350956812,4386926521872114503,6367058698713489300,2836557647241701268,448872329320991888,12310302765474048016],"proof":[[17568219625362633478,11728164309925000190,8376405669633149190,14695589083549771808],[1784254238737131010,13495998780057786402,8075752771102496829,14150326866163372950],[418356374157814022,13514409243781999472,11369349418804916755,8053427935617613961],[2857557477058929542,4895539378194896248,125245471397584880,5004679074738738195],[5495033719775422649,15836882504558094233,4517655303059964426,13480801662497005129],[9188283650940478939,15739354407994658895,5527428091969308391,13797205604828281427],[6242115857210123431,3779017796221100486,17804705615562746915,8701270859059534957],[3380751412652596166,6176208828747584686,18298395480994433858,17016308051743163419],[5191331173368835590,4467297635198392055,10955321641010852037,12202939285336397053],[14942010683607684591,5709779915222542068,4246564665486582167,9614956274603036454],[17432831633668995857,10700399429851256309,16966517425565569601,5069056014061593594],[17825287584856073844,4273755008926608392,1412716099871537490,3196375579810396653],[11764817158922253009,7449702647565203284,1566412070216088183,9443058507340471738],[5040721577805836341,16120858907255230316,6546530672844669212,14281200100578908824],[7213591029217635396,11273666069304860178,2440722841686736503,6840017750781558337],[15351827245894792358,9295638853386574934,1602616796632692872,13047387633705632052],[1283005982263822647,5576217357074790266,4838152385037052151,3671493702847934836]]},"quotient_query":{"leaf_elements":[14252996674651264897,7857351296055251032,9893170606851022694,6224585896457434173,6940198454167919883,13396569223944514603,3902224345276593668,18209871048704239452,2685777864846072183,3408963006809365429,11798257667443362403,16290476946127070034,10575495193150031163,17212619692815898844,6427381931556648314,17142969345893031840],"proof":[[15229332915974564232,6092094984272004011,5672644574705484958,17644377652838385665],[10144040022478450202,17381682784541816659,6157635211189307679,17721113682427323759],[12054289810240004898,17306385689154522885,14340824290081497507,7253595405900831369],[11005579520780480320,15603142254943749544,13403483463639254085,8542305492330441939],[8184865109140775934,1621225149759869282,9540454023601080841,8526081741354051048],[6871899432014051222,16970469286070688822,12517743037759004112,4845705380961490140],[11112738929480732804,1858901918249087590,887577695360009332,9718753421061987932],[14391088475388963406,12519089017787807958,4383038453977679948,10583871372052998826],[11041783803688838736,13474702454034088602,16246690684905756953,11320529799780081449],[1686189720857934730,1697518639458641140,3563218117818385904,14918242306560038294],[6839303081821617480,9664659608305123166,14087311472771791930,1688978083710608740],[12600316593271040772,3323539439726661377,467223598681198029,17015159682493563232],[6474196104749237174,10165527601921739800,12639463630510069382,8267685666853913209],[16200073760722965325,15962215393777014518,16958839329421645766,3369907618720960769],[2517254183832167733,18189810458877796117,7350733677052505173,17241227777780402038],[12383435537749213360,7913388594304678688,7500054166861163716,17121339375120288845],[2756204060012982104,11181890352814265502,17993618182006171151,16194213402389489504]]},"setup_query":{"leaf_elements":[4365104042169800659,1993007036323920919,9374590231907554995,15992138389290847029,15034222026672861220,13861644576931502087,17925225718010882734,9705706014865087578,13809941967466179072,5849803823156030425,9979732973191712277,8679031290381623999,7759907345362118595,12427851767130823212,18136246736366149558,4616911120919736967,15831745955303344978,11799454473212855179,9334341656254236091,4506052034665566853,6986817559454467928,13049500254027993561,6727530934367114134,12471394497933741981,1247077174354642704,8449020273196051608,3622055076695875613,16930746186693353912,12715715867824369996,1263624346192116847,6919744758016554713,16014132475645835059,12899200155100033662,14765752114732057436,667457503983913355,6883624067643227123,3222667405631200712,8901968982713868671,17423527790771959166,13011464194217877115,1595333356905070883,8060434653301972709,4986098015679325970,11516729644477933263,8537276546003282668,14688555214321533457,14164269623179473855,4709690399869735367,14863941234048438793,9164468900525275109,16160208878132381323,11288113784264489450,8736260103348247190,9158673172311824359,16588958508778633168,18033602306636992608,2506858913379622861,3646951460213197655,14960854975633366141,1366968914035544961,17462726253831954180,2823330455281576721,14836591206838736480,14521383499562110734,14258383936562888198,1928216661121553913,6350886674591620880,7677129022164515888,11327149995298768970,1013920344323027374,10164433943868802773,1136493686817126180,11349286916181570667,17280807494365346896,8632478574009023554,5385799305488413810,9115764974235071905,16263784051857098401,5642582887896267772,16796711076170047984,1623854142098962590,243566084175098974,9906863046731516269,12698883559900912594,12391776595355419601,554187553273882904,2075828745911325585,13954735026832473683,15409561152160475560,901091186838301845,4250051732120072380,1635946339476576447,13481507330804347101,11812038128152736380,12251378798348083576,6718767885585417874,12824748789051859570,12042951489509296596,17268786193310846529,17135103982585761448,17116391767380009176,17999399524036062080,10706271905727127818,7824219340382710859,10989745470732095442,13247451016778541231,14071084024993126542,14518356519368471191,2863043055808151668,2801850397198667719,17992818137951375094,14679045832731762537,450974834793939552,325308970134326412,7948807663777067662,4731869811589336647,3433867895387837238,7433087050902132179,15310722114249998874,2248775368011150858,7087000595139812387,8625022472766735162,8854643771321240941,13834753911876387457,1064228142099632098,15581392436899210817,2186726818574712176,17085680082968994729,13040855496804088863,6757792945961341864,11235688231859242364,7360817404638597529,10056689101330586745,2722666872813447987,4909655591541267753,9173669877839299305,16463117185155136353,11955168843116852962,12153210713524341210,2192477094750137887,10306431850354728206,18075275606979419806,7568804125505148880,17840850045859811228,12226551794447236770,7445879565814742742,13370079743199030686,13605509643920473913,14227757384585419688,6372814306074647624,18110706329166818508,5724769993582937849,4942785372494785816,15210423883823259040,2406905871961488599,13236396639430065429],"proof":[[8628699970335630937,12057339947259080035,4360414756208634316,6112586897945366714],[3606591422399427920,7648221919665914796,8134572448734769586,17144954690654512253],[17934717611688308382,5116007819268965822,17829929991989713559,7945672661408669416],[10451656993073728105,15543878364954003324,10344400742554414255,11645123846804794754],[22255079701403950,3644419718663758530,14158782771582665093,9028034030395273824],[13719689005419630735,12279157821090361594,17281038874855103677,7634842209407882488],[11507023073829803322,16991622797263674934,14359090630125074168,13306743620374523482],[5560542243753149746,4005705664255318069,5418182793997979435,8765260755105091746],[8750349749786164931,8289399357411517499,2249428293793647248,17305855499204383352],[3209839071633386616,12459486527337845299,6130025984819612907,4611746635629019942],[1326712463123770192,2657506376564805537,932977720893747911,3301955383052199992],[16901359152831116770,11226826337478754885,251038167657661383,6752787724429628580],[3350773157717329164,12022597435133773239,5691769807784669046,17257917305919793467],[16707328741705353550,731422941741359932,2432686559325386527,17052628443024089097],[11464192866181959546,16507321561919748636,12292824181903010950,4854829283203017429],[6552520117544810486,16587019088306324507,6380014223602582641,16116898179121020620],[119942016992425815,7641812824221345957,717302696007773285,8607632033190912232]]},"fri_queries":[{"leaf_elements":[3625780493420217255,17712682570337138699,15264579221517497056,13693810659370329462,8043783434695994217,18411011609401987348,18120786803835266509,6214295449799710567,5894289017899431120,6844119441687364042,12595483090696997077,11971821384471464206,18390723536131591538,3491038961309343154,14681564730978830364,12161984997024330804],"proof":[[4835138082246459278,16864614651192447235,12659869697028987957,119337277003214621],[16629417461886935135,17807177699769289033,4806881517177064303,4549795685160532935],[7184361729509777252,11837172560448762981,12648384707030280205,126132660991321210],[14552530658915175435,7908863643643828622,8861730975483208053,10627600788847821013],[15458227626897594204,14752685895987021862,17481896212538327390,1653545363412980826],[9555057751797485555,6965815567318518093,3747640425677622005,1532879869564763048],[8521987686061529803,12443440827225637629,11856075167023404563,399289817693841731],[11081777508375927426,9245848844717630415,6361270235773738403,1763478607662648523],[8208525081693527570,7209638879998541068,8502201484427532978,8023145940833968926],[15172664915338928251,9798915803737375946,7236911325661990875,9839665148430634618],[7222115725566232631,136858731730653350,11038398348244435847,13115199515840052271],[10964313202421950351,5630947744251068434,7004972551600042285,10845042182834146527],[9828755776288769143,13986765444697018228,17216114589747554748,11737062743669164398],[9497522330654010607,10428746838159854411,17282797116643625741,9370446250429457167]]},{"leaf_elements":[13595222477033770853,17917994074456992087,18316871696377367680,1654776950807592831,14441694227309034452,7715425270554359242,6816792626426083844,16991952385470670554,9873501373953167864,14489133414899564864,7231707204288638176,15030703663827537434,11290591496933237105,3079178508188284028,521349498435038147,13798500630518457661],"proof":[[2392887512636968847,239072986935581580,6253311539044729503,4500600813172385159],[14430488975319340516,17015798075381867150,8664277062884255926,17907602008721818485],[9912238124466159069,17612927286257148241,9396585766745175612,5263518249436788647],[3513984234467478907,7807480918307393768,18443448686772012026,3002254441688755046],[6596447968478347401,1294774585353457390,1361139769730008226,17695235318984425645],[3226597551574739141,11958474520158689073,17023100311164932152,11299428744959037972],[13693283836743130811,6723249867745792795,14639812148110221668,13831459334179517037],[80394451719204121,13936241259286648926,13121099544819924140,12329515285660958746],[14572539141946693120,932423997073474659,2314406510198147272,6370293398431955989],[10995142404837032615,18037828248629944783,3621605584051744,18272512998774485959],[843411343929838404,8361740330644747194,2332379768699751226,10226462084284657766]]},{"leaf_elements":[7678373577315816423,16800491264201170736,1726122848183693620,15837484871501775133,12932709503260659207,920195185144677776,3879197368721162173,10237082055573201212,14835428164824631007,373399025836747724,10983910548372958083,3389455427864732109,7187533670366000477,17432823734457736368,8884561846278720724,1817939310752976683],"proof":[[5569317468988989559,12541523191335031342,8337402758767480929,10426980321225193062],[6974611607966881927,3071993099785980770,4911995567644835757,4902460052844019421],[894902656477323542,12423939253487941684,5617103257582091736,13966949843373872827],[1850974449679782650,4235316550785036319,13790982684521235625,5725094798496139925],[9091470843413851119,2917399568321618438,10550203724206784423,2588538136512788507],[5667355671482229712,4260810179119353854,3301767374709718245,14970505800725926762],[6093544420987595980,9570713105163657521,16834300732272845917,4954962326226044419],[9196460362043655518,11124783458111663969,6628625323182741542,8138792676882935518]]},{"leaf_elements":[16292162615209207305,16835619475717110694,1289091089237978076,1327029158436568477,975291339599568622,9370852025120418714,16232883525137297608,12513620144035650937,9407590984672547179,11609310993594515105,14596166302137742373,7675670749763698584,18406666204269418437,11513658480226802168,8361097222069523064,14332971526594340274],"proof":[[15396001077236102504,14899826665366635754,2266550403224879412,15329597798426536510],[10162859011904421319,2092288711722697557,1394274355613322164,119339020920692],[1886952331324614014,18408455444181824419,16919638281214785380,18298698280380929486],[6748302237752748816,11050683019842041066,10744285173980642168,2830567593414132163],[4195745188892480400,1278917477926341115,858660738527305749,12026569133742582051]]},{"leaf_elements":[17243346552149652517,10882619986357177751,8096803201503556482,5222497194179763350,1473082545781564758,18086100824368415238,12291573177398886098,1525169808899722843,10361841926233051838,11515798859454192158,13069490598638279614,13771904632740530077,6153907696260295489,6369593925792411855,5785431625204876738,15730679172607800300],"proof":[[16997450673583468054,2529071262208839696,7011471064570615138,7786772006240297790],[16070927894096146171,7499309042979267285,15222708687563261277,7377423658769375210]]},{"leaf_elements":[8872244034292046542,14961388654118324654,5802056968775514489,18302383666416428067,3933647026650259001,8825851261617385151,8616213839298888053,10450361630528634353],"proof":[]}]},{"witness_query":{"leaf_elements":[1224409903972569940,17377377160837563742,16760327933774999753,8112163778574136739,8180295493384330302,16236820275215865614,2613284552582894685,6498911036305057016,2326597926278260142,9594684681144050451,6308920449526070084,5456713552345818392,8417182592417757672,18428026641604168645,1357343481717284772,12082970337537809544,16488139105938439954,2723249423412261729,11634019300705009653,10370515177846967062,13659261088460339896,17232712438935670574,17479513410168798638,11060731409243780258,9655115254172534851,8874248355636129392,13292499246201707033,18021449529547114563,4149505376580457564,12859871929883190786,16499284142023046619,9391820275329417880,16483345069061947488,3744992481705849914,9473736494699087142,16474965663588411375,866592806069033860,7667983532788417137,4006860792214798538,17628306037885355875,16727514950390293565,15996761531224044500,16834484636992102804,16684106008058655731,7635466464087843509,13251135425313017179,4892651532326615221,15114460827477897743,3649044422023658515,7293880449318455195,17948455577164531740,7973932827820545234,11644089824759210733,2068952604131857636,7446102051341927410,13968757197052735498,3934261601808120676,3615333187112151486,4086470079888233226,15576105309005925601,596913958127907521,13525918374750963441,3680787774156694288,14472380268575813666,16914751505843678662,6115253464011764555,5745051214736705333,12784004918591485326,8735070994662830016,8198671771407746400,7011825265417413005,2104228658566880334,2089840614090704199,8201372473302921635,6417261857948313330,16030582539335916713,9159298491528884965,9492027743260131753,14466906819354463657,4079336617416291633,15529836074409621917,18314237194770924630,17710473803947519290,7222712966240275806,10935580180517907351,14968353124052163617,14953713049746112008,17626798284517860717,4688853083137052094,3220789938929398079,10787015497719564136,4712429919641874528,9912678989874630617,9710086485340326513,15627777176584857778,342667368762741238,6917597576147528062,14246348237872788385,16651454378564498121,5991066815053227032,10996426409415822476,5218098600118787999,4757712343992203104,7450074266268454072,351094697202193864,7573251281183079840,4471097279950110578,15085293588311347955,11674425491379999727,10309971892304660553,429407916343487132,4241757845439603896,12197928311651144145,2761145681895921414,11438004212923073271,5460802375768884228,11571645624611520780,7904181364713818814,9956472012857067112,6853134167622454250,10800007650530024712,5952833009987801745,1086540133444709978,14102036159150528740,7209493807552747715,10938441539600405641,17977105762423319374,9515297333168574847,1646325392396666730,2780184805744967577,88103264949947723,11887751601348072835,9541566100360324457,14184629513222646031,5464837311307839523,995270962676118797,7961062182779095184,6667846815144296207,3814644864463901208,16660986626534560490,15791372732871745918,2791857361362152899,6062225003837303802,18136798791884860736],"proof":[[6358273205048736582,4658479312466272763,11958480964246927836,6660329845125894945],[165208822950731504,9202589146969099520,13983373795898431900,13355151058286720394],[1663434029076802067,10458144489966634625,5678041555360625462,7606733836478337387],[13006838271156131878,9576001617062062557,13199851508259602353,14472113166729088113],[1126069374169541082,16893612815839831172,14151291347151765825,4804614777638868860],[11429831510109800084,5245178833168850676,6087476222256260459,14250187654225539195],[14785063575461031393,3636542289379401703,5764808483781307622,2182611085893013405],[8632186099842815825,7861904478703018233,14576026997129494667,12371500274594644244],[8569604911574057355,14762663342397931729,5945739489719493713,7159826339198506064],[124736748783533094,6364361054498929755,8836978446062944988,10921175636585566278],[8096369905483340796,10442660117926971290,11841457729533856991,13948215284561488533],[14094771868958844616,12214563978599791864,4888199035627539119,7094511200835426253],[17124929130464657477,9516011940117939922,17946051123625799586,18157838683132959487],[1594051163830500238,17523638210689330760,12284723098073292246,13983219656239907052],[13527906551350567895,1126177864609261121,1649458512220056811,10809155286649142894],[13239482398054249942,2673767639284143452,2322923916887495121,8336621435945842114],[8962983601327175991,9655400076779378322,9372067540546984264,18437205832166210823]]},"stage_2_query":{"leaf_elements":[18030815054913893217,8609473525860127628,13427643245010056634,14247570477975235800,2317384364853753580,4800527878284392453,4803810638925119281,7371481442182028079,13115662108965104579,13560518122129703257,8564938887370834612,7187074152212572486,17996364816793190733,6254940946032881173,17595823624593608939,11772826920594536875,2726464278771016501,8377751353736382955,14951296721467907153,13759869599146089960,6675199288759513590,2443188246834395537,504410712635553294,11196613580826827958,7695749573830066833,10148828948201027289,740807667609978998,16566479424191009279,12522091794525849339,170663627873890543,338935290872573610,4459053194775542350,10984340356701704476,13764825689597518881,2942929942190235286,12224087333903053456,7377448977288540778,2587517349512310603,14263759242597035416,4784006836669745258,791284889299234442,17802596133113796779,16341764824151679594,3405415853223360248,566178452074077110,9554738035033605456],"proof":[[2404123511592279393,13390167269085963572,4915825923315262130,8169672621093751060],[7668866820010684084,7662312332463903105,3312929575305037352,10287281674944021985],[11641116025227205263,12595164469780940356,7296925152293306473,4897330522313372996],[1460271408784089655,10998517034873343403,8724380111241270071,16445604676337879528],[1270653585604656451,18415046350462814902,17704077404283714618,7932067262047161677],[4214118201692956227,7201879617330782540,10833638949737518824,5476698931838340170],[15343855416713382007,13201068277843607076,614272467216562742,9196713284493803105],[17422606585327400820,7788026797044277118,3218983150845945223,17070939320057583373],[4086530483162906898,6420768509238985804,18403048766628791702,2965506187642645404],[13704718438568972838,7510549591826117485,2081550398931678511,18104661517618119535],[10535068776475145405,278677235637880212,4862031285867276239,2437128759330622920],[15831581368767379326,1674408771027303451,4313336066363997112,10578818593628124556],[11109485596876845399,8647488264486140724,6942393461438655014,1793049596697505205],[16703285575515796849,12572017633317823565,16401483186522193134,7831511133643106889],[17422640282436261546,13720468865539618857,13239742126861041485,3078081734527238389],[7868377146465893942,12855249661258455866,14376170410156481376,12632632809800891006],[1911347836580775672,3246100548763748938,467751161131197312,9129819829973384756]]},"quotient_query":{"leaf_elements":[3056081568077490911,15011961223621815744,1738767977272590368,17705893065155400349,18270468729051809695,1802452635183294363,8358488908716327365,1182575944966198639,1347716874772854212,4460384366254854046,5190764048204790057,747980628953676024,16324807705886478108,687707558325071825,10398668120368189189,3069278122480343284],"proof":[[7494671257898328238,10057314882283720269,9162255325304724177,15427269677646732626],[13894049710821644197,16776349425298027835,9463282469281953752,17712957098745450400],[832275750334059349,14626185691750075529,3365429740948117927,6262853638065789314],[4496539009639363633,5309807230661372122,13918680922379974339,4275396425724999604],[3262820356888632745,12190063674080454174,13008133419345640854,17127688627737389605],[12423938688211112074,2079582808669957239,12113748412240810185,8792259035193371105],[2033503764400999048,11258253927817182423,624888505922168629,13705127903732005740],[5862084882958831171,11340329734685099183,5324403669303128987,2835703148100837973],[8888771438342433082,741809814057321372,1706933430359836229,6771124948157316504],[14242546058994011159,9564375928635845519,2455184335857789986,680536745810386219],[9746436452262153484,15823201359262983597,14956898580236153111,11207548290335960538],[12958098468402343420,6933184091925744023,8845333443637483646,17527644141836458098],[8110700353843182208,8690330832796236293,7214217509345715756,5795189575818148507],[16825014094291839836,9783686295585385431,5202643751276855842,7655227671267544479],[3314316981268349542,16577539173163137912,625950167720324996,3259838266077124945],[3750321380710082681,5816539556762857119,376379246827409819,6573078953659508109],[822135299882928769,6832536832869235243,17165440014740463881,14363198558232023699]]},"setup_query":{"leaf_elements":[1387445438541278530,2613151847515239375,8725389098274786683,16684314847167038331,17723138805467736325,1002466695113516018,4076704060498534362,1065875739710379447,333742180188956649,2393914235514966882,15719526423268202261,13568134256355731269,14824442893665231447,16551729072741201374,8800937243885892330,7257614674790112227,4748852261164474692,16473471210444829915,8946079075052197069,16914987608817129345,4157228295293798342,16503523761510881840,10506747519396505922,5370833822459687108,3760557999099040914,17029831135653889466,10681520648658054547,2320474936345708923,8983394426438740151,10178527906382422218,11167501115809518504,131557157334518328,8340161991561255138,9139793459172086227,12542084872378182830,13131021675546898380,4703252522976758602,16185958333669582715,3230778438113896164,12973359461719093819,15474947074728576461,6436023184110856486,8625372026215387731,14957771087249423905,10961694099400959823,11560665291909200565,10787179540070934335,4358766265127703898,7748059265551591701,12960241623660780962,1188886394012770895,11742314807929212889,1445147562328477082,2673959531884911894,13372433835423164362,1377367800147225750,16672389332261354419,16007354469798889581,12754845415456050744,10488502719585259763,18400085662641524137,15423296310768477894,12798203368994353817,15296498566047893014,7554027186729105186,13238692757462564904,9100347732494757838,8875765563736247099,5532336387747008304,11356678081093843091,8686504254611651806,2741801501480894544,2316524853522231152,6914854563710445845,5577523138992965775,13536352192175040918,2539539108594275007,12293462487741280554,5887563199172884862,7223980451673983020,5244553762963864915,1135016941626911688,9725124606717008810,17051165473260104230,11294414677431220969,145057487789695346,6826288540935323303,7905209082150303239,1604873354598399472,10130338042723549407,10132615509533806585,2578713201875748833,6561374215783650006,17913033937963268795,2758949981095703962,16042240641712868951,9642102608469957444,17062924746788859786,3752172309633708074,8286801181477705592,2964760173200013717,3539538392487542578,10448212737662460995,16191340620763283937,1543549492158209218,12627186842637208443,3422516054440931223,4506381867948047623,17280337123027777723,5246778680279418354,10514910129773414869,2132360631156014530,7134464014842762830,1620160842504744074,9138081187685673540,13608192158347724581,2304359992910509773,13323140987506358908,9288321985935481485,6501251613844501407,4087098427244598550,9310343582678911773,4064618279351599205,15775232204154308104,11255656637430942843,4080537721450124462,3596041801642544511,15799632712920286893,3908900961826144932,1384840004417295079,1480311390977756366,18295581791293108676,16668731476718646539,8770827486395191234,5557526785339502682,5773042510362311484,4853683507408075487,13152493314050163014,1614586391624388866,10143216002206215796,13082674679749641778,9802476311667366257,16003537468980143576,15580007680816699469,175210636880092067,4362482018867088571,12975582431395930439,9037284111830726910,7536781231972894912,4399606388797518923,7345131750285718764,7907614242405703168,17545513353399747650,17577113265477031356,1441584785049579073,9861587414468062590],"proof":[[1436431638609407784,3525872675823038679,7909248211304197635,1885083999763104694],[15182191176447863636,4886265408579557500,1512157355669883132,12082160924906652301],[1825694071304428232,9281504294380876505,8943968408958827914,18093419455830328232],[15851498015314471430,13670700460380243770,2660855079847961056,11542202793651350537],[1349717629272657256,14998416344760638611,5548332174989430316,6027357807693379484],[1458888071124161775,4276351344558897252,12163112062853429128,13101155551054473449],[2354319526336157512,14210263393011736828,17884998230746979629,9757132490133298136],[15974017545211507568,13905755897750542914,11527898040993621520,9660913194721199102],[11002534305900815868,3703785721521683427,5585615792815288613,9956607412164179507],[2011301846376887799,12909048399887254005,7663363340223278717,7255908158406524647],[4732459036334824215,3450871023410370891,14859312240776924240,9319774814201705771],[13844084487873207259,9723852857124399077,16392299915793327092,2063134252735939083],[1033706124290298271,8502954231883376322,5012764104216949190,9786319677036434812],[2404247375372075204,2120440060139808894,12051667679640559669,7310212323420561499],[17140123694555410042,16357209920365251751,11173316720750410846,3038972666247689388],[7763034114238797210,2612653954970864313,9874548532761189295,11950095805038490746],[8150671396367591155,4374957965196029991,10091316552250686626,14304794448001423245]]},"fri_queries":[{"leaf_elements":[8316847959089276351,8803693942384876142,7687595748559168467,8313447879187169531,16646383831879070450,3648824113005009927,10143371252091321592,3727304513117423425,1118773516990456767,2823366452847175397,14426154101866200609,2026264212054210987,3460900940747461025,16276416895092476914,7817886312651939279,7530887031977085937],"proof":[[15509776459722644142,8994806162603621284,4729155692688232601,14174237882897901932],[5218275550790260222,2074099418426074934,10545688162395099125,8474377724703572866],[1627778920992459311,7809782408405241505,13853742413451491262,12411673747818046038],[8870842340338862283,12527941586981965998,10745017772577961313,923503575726283486],[9837058449643617700,101739096651345251,3265726707377866463,11152781459621357340],[8271756088186647230,6075041172243784196,2859339962068045586,8953095893618847839],[7532345866077485849,13356237493730964436,7299655309055797778,14842315765203522947],[9016782271954432517,3063195637077687465,1423318263047361934,3537267880527172143],[6356822541416120156,8869544013443792376,2335282149731171416,1907306626041671035],[1723446283962674458,17148206143011472937,5065913325777958341,16648825284461989208],[3451433220562635366,3014539303180941117,11598683235056267116,13730833298046402864],[12879541903736667132,11824926927769541120,14012119210494154312,13069707240719046365],[2036743038621850211,5423246773758321676,8041016251608296685,17855908391359447905],[9886176930643768256,3509706781999382685,16706751567586875992,15900181631248865387]]},{"leaf_elements":[7036578644313315811,14040107442571824001,5296598749976811452,17998871326689214535,7751876804473882190,14123341786463765255,16453516277956015157,3545473373363403415,17649883380931131205,7174923468325796474,17583086998528898749,1394029398133996606,3615848365681286292,14467747127261688865,8686543137406422742,11850581104701744140],"proof":[[6648857287533095052,1912047286252883511,6244469381066702973,3930257914413236940],[12860783589864873043,9290387619549991764,15699434266901019122,956451958168492127],[865108500696020017,17988294796582093282,3319791641615356169,11146921032582330751],[11799589957634237510,17004970370746833731,4269127647963065223,1178876932055379340],[8087942222923816731,16176672857326729545,3632978374554417187,16125493273359495830],[4905816055335891635,7464716050714045368,961972272235282131,3319831451390419986],[14040957616231186569,4557300819233338939,15164814507718953619,4185736056056340480],[9247003558324354267,7934798486739581793,16407023349428788637,6234830621519586135],[84907776483638961,1394753659584127488,2413987940492755642,6447560994237404355],[7449431501732386882,11031208553786558036,13638679846530505981,12224306339616136851],[10540896754816519323,1746180075358321372,9865956469169334927,4589766901983917581]]},{"leaf_elements":[16048402588299812677,4261592622523875705,13680278892081425090,6575669027177313130,11016523872353579706,12102611439755988303,16283565540315479817,4153737725094996136,8307227889594948393,613949411164088285,8053024856129360298,17225565263043379593,17826238957738452400,5557493045307248623,13604201708401399290,3081991453750809466],"proof":[[8823918433355388403,13935667300555859004,11326364000287313386,9690244272479606147],[16680983392391500434,9390985935278596425,15943852473361552162,2143744341104562265],[40151325064460516,7746243115093422140,391456986431878963,1546653761561520422],[4214153805305784800,4280675457163396639,13606849627479963779,17216495103194382529],[6068317863409527416,5408319203364323378,13898624514707194219,1244917661769372809],[18088448249367477155,18138139662602334719,15579270348978006452,7576075133395427403],[14450638296737090204,1943028934310837098,14316870729705224232,15060349458129626311],[11336173358147927605,3544125422924662561,6152060134110928826,10783791288329227367]]},{"leaf_elements":[1687490175499694107,9519783883618922087,1638528759001847082,11128310435449141079,2891539213075789647,8397702254064235389,4496431697974938882,12416666220337427568,13866157681001180413,231936066823931329,898436866589932492,12002220889754384904,12927592622095117966,14964356837046261063,12461420715814895958,16492164222662289673],"proof":[[7684233784396667602,11372621947045010753,14063627832034048174,179690396867285023],[12097363615913209093,11216576144109292013,8512880816767717475,13785928941070154184],[17063526522483783390,9051040406103768446,7625788946035310826,16199235844778692722],[8431282242568030943,10132639644794228227,14548814393084832958,11257210547446171232],[16976949461203448459,8268644666328080056,14706620297076897348,10709889567794796744]]},{"leaf_elements":[9306828645540789088,14829391157001254424,9378227111629524164,11716745019895415222,1848398401099685924,11084788197227462359,7893267969825095172,3640734689388496039,13110229117454893753,13024444064704880195,8942605042497989081,18096099345285820199,6836986349229157748,11440143176033232175,6539666487464362440,6381810964383519537],"proof":[[17328635329280208295,6571238372153749382,14827737472456699520,16135031428133869750],[14983243035340635343,13554744403256603391,9231851320950367445,18031029812144592016]]},{"leaf_elements":[1275295786118718478,7488170357634863325,4283449960128273261,10193008459420986025,4238185187837649128,6318479223569512088,16394860438500661164,4148361282767282169],"proof":[]}]},{"witness_query":{"leaf_elements":[10182617437622560730,18197339266653350832,14188381255344622803,6458480697947850512,11735460472443303675,2929630618201902916,3950517090313449986,1653437194450716289,16365970547593904956,16805717451763974827,4251494774492100078,5933536973889907380,13778335440540849504,3516953822069512424,12940632907806789155,15669279525022925904,10178829725887341681,12675915133634587075,1723951745959381941,15798972582499980242,5298452248258619451,135308147935277692,4676847727982329945,5137596360300637775,13041588954491082062,17926827967667152704,14289668613983584529,13178789349236323682,1120000820718106545,256018351368222833,13157188819611164043,3963525503738013536,2406800887254795459,8705667334821303072,6139519425522042807,3370257275584620382,2071961895264757684,2610222245855881225,3116624995583797212,14870213390478710962,3215408263507671839,14855821159672686465,4329397238837776755,4841200438972491170,9628353289995690983,17164269373605218270,9892663259408066190,9751815021304826337,7075786733952002329,6773125692877490768,3966853856091564874,11636484425280269216,3750724629611887657,15522489832656239935,7399791022079551312,14799845100314515476,5325315743334441977,4074842842026193829,2284232493859140842,9274263473034859123,14757056629146840333,5698334570861862233,2019787821203809124,16693852287502851460,183789091907811102,9828739242233944783,9343229046177419253,6372929227050821828,6118229252288242080,3518778778528100711,13653956523349349590,3304987424352157373,6904703024137301148,2645917155946775207,7698474896194647379,7880828804763626894,15140436283877195564,18075613855624146113,17302076704050512732,18433528352602239630,11214751602369758920,1169699070811301000,16584098788965559929,12779290944275273442,6731935086316625920,9685843112265236944,3329758635279102704,13141978664085809120,7468037441245194934,16907699578238001215,17188482306513292981,15286660820665763813,17004867502841938878,12273015159734648095,5372315475762019476,7285736556528756431,17810098346271066592,4499392649070596732,3753230334156057076,12580422172357191695,7660330580259496777,12820996401936621004,5060244605026651946,10766307318539124852,654745669357614796,6742668612660195171,1040154836360353710,6090692266042225427,14274168318087538638,926819305890029010,13308837355108909749,7125107244129991826,1962559438345213690,15944370621055929070,8247364114425981226,9264455715555739312,13164097950260047894,5069866735859370705,2267883632307357792,14357508706196666514,15357130827397963973,7538937526993989398,7129603767060389087,7430122313937696757,12548743290208107792,4639177419701674700,5662911604952091937,15436457894877855591,418705171771537749,2444391271666610806,7352410055109299308,17734145405009076321,12285897173086768508,10582440444715001430,5066187863507192558,17429795319376872533,17205099230463059377,15360330229004274652,15994928556231172449,9253160195868517398,15231368237137542632,14590473427625021288,12135972171880454304,12591253178889427346],"proof":[[4271886662738563623,5331640592747355077,12298235127574817331,17405803712251235687],[13900569256040209742,5425369972540708328,14157461096301620106,1892480675674815903],[9121876642254238800,1910218652753522050,8155024743598137555,6568516529293220228],[6565808536203936725,7295151228128019782,7987166904800857021,8328497303224210536],[11310896938313721959,12067826143311252326,13683659684235628757,14785083712369067316],[16041495143218332853,16961777586329038897,680057967705411842,10928229057143755056],[18148067060828554617,12461592226812458012,7876086608091283807,3119411963135544728],[1004709898268761596,14524460209572083674,9838539330940904972,7346999840775233716],[18363915400446737114,751058279961267185,12597730027024136279,10534361389429313033],[2149570350838569620,12502948830846038177,16517061833041990915,457739288198080827],[16522976523388455706,9320884575423409636,16472051977308250652,14463379031320236397],[7809441201026223575,9517006082670216099,17542594309689298187,12997417013649810096],[779702173475713928,10268414702834552320,16439780457929098689,8359123390627922411],[812964626811219364,13492657107426116310,4292823667651574528,5634146459382591900],[8994450480713180978,12808670063373988272,3312245676680118161,5681115170205008632],[4956536191860962690,9740002573886859770,7965922547144827009,9881948363159305843],[12698140864963633855,419357374229537337,9620795343936707768,5865575737066574990]]},"stage_2_query":{"leaf_elements":[10952458167337739726,16920353805327176104,11174223233898994667,482549348078029412,2416411326561768291,18134486912406149828,12874737618333753733,15602365193057032798,10348014008124366803,16680441471691820055,11538710444857482251,270573549001808534,2630486170911120764,8280832231805378440,2518737476441111592,11128652385809489240,7178453991717051441,15329072057858361883,5599471136252514472,17459069527180169691,12688622802506025122,11577743955952402187,15998739490123653578,13227378134839265310,6124613513535933249,16398372953958364134,5525765547093668654,3217326309526403582,9183512060842505776,10261577928268283763,1606474930116511090,8777242273860172733,8622582351895781748,18077757937977678430,16585424565093239868,17527588914385694576,14930557635334207941,14769727280817615679,12063072206003195779,8531486519823893051,11441316642388660293,4579094136423888238,8827790089218147147,18388784858672296350,12732731356282656363,9397069098391102106],"proof":[[9254182410206247240,11885665007592478324,17417961564740593660,4155995457446331898],[12947984311213870826,1389067240770162344,1656607686248614442,16191389927532697715],[17382339743707332385,1571956341538475134,15535557079900995216,8448074905733879862],[15356990198413395938,517673791791561801,9850971914706421327,7872427438333405923],[16943113928839371883,7617443080131727481,2704683784196047957,18003890324061186769],[14065078045385750448,8669659910990984552,17751007242856684234,5564939628498821769],[626784949157728692,10675577831101877755,3779257874014828460,1575999697669980356],[17661729363508475325,7469460753306120377,5177554721339606760,11347344125701309267],[10343983660602771371,13536282979314237106,12701118799692541089,7791699800907730750],[16477182210083722725,8892733930461590927,13156488715002109512,8407507012883969122],[15078046221870275907,3116579132215497072,17828269142451092963,4763352679493361143],[4332054618437965433,7026984501649204094,10842341431423243009,1106894383822093954],[5713936751142558819,5161664529312251768,2240205573894992255,1875343010946585333],[1110164411740831112,6097014061654298498,10340966577274791763,18239753433822917824],[4178988488198794634,3945639405656170453,3338672611256894684,8947185355948714227],[4368029160520258810,7161438462072646830,16152631782368806991,12236771943529764097],[13885167953277892178,8555964237507770117,4719750036722080927,12815453938056583397]]},"quotient_query":{"leaf_elements":[2693514172801143415,5489844473286803566,15648688658939832587,4497722008255458852,12514229842309077399,9066885729196981493,2501993743453631429,15847259924336013080,4494533598697523622,3423761794973072762,17750211602154587742,11132371426598453563,14401121293464361896,8243948792615695241,11783925508442310726,17408968798182230133],"proof":[[3502308672341654356,7077533917853816938,1335588009717671166,6550519116739138844],[13377136096867512486,10446320110044369226,14944887501885746809,395094960482369324],[4744970574737436179,15273962756884204681,2271977163757760040,14968049354617256044],[4576008176556493086,8123348099802046719,15813223467865123383,16770214674866344380],[886363220117416586,12733640844771596945,14493399244132959807,9291080518063949580],[12985183469449683930,5689253911135688181,9368544580219792816,2501338443079918102],[15699363634590772117,11831292956486887520,15174478365390250161,2076886511122158065],[15926180076434945701,4432920580565546224,18073929171083366280,682680440486780780],[18226665369232128696,9373045522113653141,4712029892910914048,2457921362639727028],[18396811892481142703,3073070838357053616,10513323721855802007,8890584307702278320],[14531729078084452826,12842865583239215954,17298708677440659200,18417264278904153243],[17448576628133481919,3766735263109209166,3190530365807627063,8411346186621326174],[11978295391448876517,17894190311088104425,2291115261024459808,8309367512024619695],[14533937050223034876,5134986175978935309,15991182943304623963,14741398786087685133],[1587885473651027469,435689603289496298,1198639496131916799,12121841847572499378],[14507401648781074682,5481093608352663045,1665047443890160083,13045093494271559918],[642646296282338947,11452596773553033960,8795257061196785695,10386969935657262527]]},"setup_query":{"leaf_elements":[15371054108474774242,13983965088887597244,17725918979111900665,9282743822936585384,14029538461785362175,6255684561287247474,8293162723709961447,384155001588339404,16704833747569665438,8813128245569894138,8967384578402160004,14252835690014980394,8773779913245905939,4502428687597836516,4024297080182189105,10045979050584862489,8894643528659264929,1321971198212404658,1912957695879384241,14086238348667619533,3074329267501375618,4824375934896633240,605916985946224029,9274254544744533863,7663752166065965512,3729060881167330622,17595914768514389806,12945384029743536236,13734468041998451972,8856824255540683499,6922457089954285248,2010304407542265410,10896607696605628456,7247044871869835741,8684880735870122597,607244961152789130,13530264168349662378,4329432366932821829,8590823558841176621,16518772917877014361,16258344253003493371,8340744171414494956,7764769855286937335,15562816211810174321,15410443483781098195,4920293545390122773,2032704465834744554,1832456382948305047,17961562817235177373,16424934170769112531,15019247068837488341,1086720995029983259,11510816606438664938,17988760193175600996,15046133538871053658,9083888018211633195,7834110858123128899,3767890952986136055,10909510580316788628,9668781154456285491,12789731418162045231,13029190974376493383,1141171685538006668,1882682210930771114,4045874266015558835,15096384049477483190,16698101060652895316,12050767577608330687,5584098968270028142,1889426250779982384,12726544863171255115,9188816184270692443,16954652990237033433,4077537235515344097,11692549616988955093,2434959989178323766,4556153074742674993,2219677888913678953,6586950135917314297,177902131272376776,15705511404685663060,6397026541159483622,341360997739097122,15009591926175497712,511525972019527993,8792721957948449969,8654442238899677445,3295196918363151512,9833103416217240530,463526404419784563,1139587157892861154,10612076312764691770,17258887140178757565,4027264736321638784,9905584206536193710,17364451118576042157,7535055633202545853,708600138174539970,661714505434798938,11990840689877643383,11386828682471789299,1309058461879613343,4815838329151863281,13737191535016085819,7082007793418107341,5944464226415230579,2351203768180622151,4241186893471019811,7656097247183170883,12334411364002832115,7606247376723847109,6567319310428603253,13346908922369690899,9645034767865208418,17119850495905895304,2406519454491388440,821238018501401425,4038442219732337612,428433836894904905,2431806939421398928,15707340138008798475,17138860080963821827,1262986100871760640,9987448049717301301,12000024687232992824,13746668332670049264,4034761756815219087,13751928318653336711,10594627981615267188,6212354680475484704,13364743279152544810,6538225586070958508,13678937933441920977,533357877150216286,7997357929163648330,18161311320517130434,1441289549340998040,4773760473609799709,9947271834536734254,6994864376932383941,18005950481803864419,12046263688229364361,7954185483983319870,15274731503788519051,4712558546612278055,14112119668357366170,18052890152640051103,15160457272784074964,12064122894750138465,7343440518298353771,2795018602136928632,8336999158263119753,15488991327156619068,11077324305883527576,3958916997402405069,12200085973647429877],"proof":[[3542199819049730847,4580690983592580085,18077420516965096730,4101198205999571227],[15326322940604930228,15350014250024181444,15030963485553198465,11856490808669540830],[18248452127333275439,630701840418670227,6605069701073888520,7664192199023719955],[8093411941139497252,9003024892167336551,13548358877056560480,3866798194075702964],[17493297611182977788,10998837602984723117,16307322127448674587,434031929433134176],[6963392696269145302,10515943439037044961,16184104954107112643,12229935653600250386],[14299800619455069448,1911209329454255711,3571698357489011972,13422960306656972553],[14974174788817080539,8249718181987318865,6382706615279324372,9455057889974302028],[7183580873790936363,15602444420826032824,2774781638711057458,4295290860203620812],[10766647058119717481,11797168447105201046,7952034335469432341,6307347063532980261],[8850577335538475332,13844998842550736497,4190400706833668111,8048638807077158685],[16754974107426926930,18047822104571790053,8857020570872766698,15125698848784482376],[10578944867171266649,10039895329584372671,2771805351510669792,10111817157161415549],[10870069940900057628,5218874568561289813,10508388403405146622,15040261969436673074],[17361770725807522427,14729458579348163080,10228599255241899186,4409021679407842319],[4461952551025463037,3023088726574070982,17982674338935786519,9685827106554591550],[786433969103539048,8122187790720253298,17324655261546370362,16556773082047786574]]},"fri_queries":[{"leaf_elements":[17368830858768732973,7265553788281509198,9207546342108660277,17315874740916282360,5369102270480312491,6518788829015679290,3424481173809743147,6522201349266451423,5742401435308207883,469068601388090685,11443651365169205858,9518909079022325458,9186668376796234260,5344568911533761748,1659570882818507621,7124938341744458808],"proof":[[15778690645230331307,11396630868353665526,9221962865254914658,16089047693544988407],[12845730212847625417,8972144212728633642,15929509274149096546,8412977350824229204],[5855905046685222353,5763460185739345778,9357180307289535923,15817761081740780716],[3338311073317048388,9485585045012822542,2314903825496292189,5909516940612805085],[7940514943044788210,13150985205242227176,11240126625241713075,11955924246899516668],[2404200894713915946,11561659419502714545,15512516505563521634,8277487971202156345],[15568363017696523440,6861739486585189470,2790692471597275310,11096355136063698351],[1438568789672858043,9381077307126731506,1841530742161470193,4253390503890974467],[15009981434981445454,7526587824740764804,16886804120577747185,13571769409343653060],[10397616549542754282,4658245454129694433,13550387863645909106,15157127141428840903],[5796702095385337064,5929727471834422664,14987364184734223060,12680636211064123178],[15065778828105432257,10013615733743590390,13304884605210688153,7218938378334712230],[633006299616784563,11139233886430462112,14538861665720934038,17078736384713939743],[950518108147387034,14461496559104778806,13917507090447352020,6484097189552047977]]},{"leaf_elements":[17162730830699668797,956460849688465665,8806236636535379987,11536225459161963636,2091104414552330925,11564509011440779029,14832452980901280311,17621370721479742046,2246993541319862827,5417848839996953108,428160532377031109,10749023138226825113,9767516690349181729,11152121896099237521,6328209340971761634,10675325923073087292],"proof":[[11449503069302933978,10808124147616806265,6078711468754613221,11135932052324658855],[6707860716007823826,414730456385944334,11654615768890739840,12064245588997457021],[1223478592527258218,8660498098277358529,1574603094176870743,5791637441862090324],[4895584282910133623,16056366445031422011,3093320871234493156,14071444753489604567],[6097556710344212802,10501168456134653549,15462609527426900417,7213677357911340890],[2234685539686188970,1665538510364274571,14223649326459231114,4589229071474060478],[4357927833858828146,860108016601072008,11977906996352393633,13910209213106316447],[3823167905000593996,3194907685507499972,2356535569810701762,7159725989631623802],[10222771338731633041,17361017823122605221,2714690534464596000,8911117393961323959],[11727157629316029541,1250806423073151966,891800793544898678,3305784069475612933],[15418802502015684347,3748451402095185069,4925493761703378520,17844205222826790497]]},{"leaf_elements":[11567683458886036451,1597283992820790889,2463181429253551621,10799071716901397289,15169912424644872129,9611320004045589445,4746255087604989682,17184294765678500093,2485836897953053665,3254830123001649458,16912848291020007697,673457783856504658,7868569308096024785,10764972113212156849,4124608890816253394,752546200863919447],"proof":[[13716014969991794645,9247776130298763978,13580075455739344240,1077004111098491101],[3266092384688199826,15877784068316748370,16394463390144686061,262184052284935992],[12407038142244075545,11649280445622811941,4214923072429868503,17248309233300783000],[16292805959215884557,6654700504076876774,7293837888008988575,2100624510177338552],[15848063422878047621,9277802629097193765,11862907028495847627,729298618029698035],[3977738057721108586,3070379765737344393,8174808616426452332,9119824238271489461],[3309760038805872449,3631375083889281026,16237336208109412891,4696666898883299182],[3212075062214438924,357583838110179765,1255898485944832398,18404599682258834503]]},{"leaf_elements":[10216675240639862713,269849901696522388,16494438958069438958,4545063749225696748,13778744576486926198,12699564477560996075,18308454314714130487,5652899461663756610,7764275779490772545,16100576254953554641,11230807292924754692,4923775983990519278,1087561690060562802,15402585458484697379,10119843917602734617,14566460307300826562],"proof":[[1341071131959760797,9226088062341522242,15436177155727890332,12094800177096082154],[16773331195215763653,10401524539972891714,12812701435394831260,11763617065129856659],[14222300175489054809,2267038271584479440,17141794906431139061,8444591244767840963],[5044779916256531052,2331765407222297206,13413041339537916887,6356322448670778330],[16725837145914548581,1125423394101345531,17017529173301036278,3401633365302970415]]},{"leaf_elements":[8077129660493228735,4858281455775931419,9738227539308241978,8050169102116844847,958630553091151607,4272321284588196009,14067102189345055928,11594738691112592425,17695426800051813913,1734969492251892270,6619316802958639459,17588832284713609068,10653512817480937953,1880283887890030755,6288995053754109063,17657381800227068251],"proof":[[7234137796739021793,11668650209537815079,16507941039562116065,5221555160632642940],[15514906446679858530,10979498789109703592,12967136000864485334,17159923573772454695]]},{"leaf_elements":[5913797713474501816,14390836815188810001,2598086964460305874,4219281277613110736,4341490336555859025,6837138495876505826,5182460282140934405,12936941785162437742],"proof":[]}]},{"witness_query":{"leaf_elements":[13757405091953738287,6016393682577714188,2176353661393723467,13218424230147083815,5875570653197318632,6296032986977037445,17832732086766185491,11272514250179807063,11534037334677623230,7827334570736469753,2976685039735270273,8690722342992321968,15516185373925475915,5262226399593148722,1019221660799202725,13299465670658315524,6929618088595335382,11437877738950705224,10008523867302307257,17239436488880932969,2098250725033734057,623288463860394937,13671584486038613302,5985628620919957080,11189886401332358345,12287964905315636866,2667600468279402767,17216258209385217708,16190323100006213738,9225461517791744588,10600358221337791242,2053180120297776318,11158542579150753533,3118584265954477362,16491487143380712016,15699402036171124164,7527145075015289442,12429606244478590569,9485134777624395520,17349031364060151378,15271473441844468530,15779723457112839209,10825030127448500039,3626505313621684568,2589183434602679266,7110102461240835318,5769435668201672437,17513154623302154450,7298641876021857153,17204360313378954746,9553124031628825818,18289106186621488113,8272226551109534889,8725996451627374574,2239899806464511088,3266593052069555722,4473434145519150171,7216769317587917154,7182820340813105659,3263766284289775475,3473583146769888515,16712853937890962679,18362607904706781445,5186504124007300260,1858115161969744490,12931680095543150998,2766312688937924618,2995373193731648621,1215086316006082546,12584883508178097638,2407369469841519399,6081504272053647804,3593471554808681239,4127516085389219384,4540145284536288287,6563008758247532997,4642814879797729148,671415815342146503,18106973395298166607,5619051809354134873,7559235232679119559,1093575909291239082,7798818814865358252,1870550414825914520,79731803071489264,1440390565203518381,1991576360383177336,4093541826591157312,4425150027587072546,15551227822419836888,4553409421869234749,2773023648320325298,838723794023896904,3448233565389420677,7501664713089641907,347128222645045826,15691874931166710236,2579967898131755914,12435300389449218588,17168172469963805713,17158179047327583682,9754296719547261297,8189069570060623,12887330950720518964,7375986125309362826,16857562875425143187,8932407764791272109,7743123012701516394,1832863032633725530,18399490914228988293,10733990110285463934,17312852062080550916,370807377079610282,10773600467535008552,4998969305507269396,205041557540037966,17964936995586614963,4893914354704899662,7902610931712593515,8434091028833953446,15961531441005747049,3992119761594060719,13718871683346517682,13643377943691107365,9767874679882071810,5410980566760459749,6900329752879008823,1352781738547723490,16339915860918575283,40640258855216560,5614298355563804708,17162345415397964128,2865102526469258740,3098464384328852992,13658414329813364403,10242033105510630878,4008312728885648789,17801525516963034737,9590925087188103682,5219463602404918287,15276706626475252114,10730429987959626670,17379606235309331588,13313063510776642500],"proof":[[8060782631841532650,1020561268196857428,16581816359450371879,10811505401856259279],[5636518599879469022,13746249171006055171,7952834733192265775,6947805478579159975],[10024002982447160291,16407840065521446955,12217103127437148764,13295360003567287629],[7310165149605025193,1190674182272522088,5286352928949490358,8770654047697932443],[17628996684900731118,5786804025692865774,1578597949882173753,3289665449934475725],[8293579440624446336,1815872842344435804,10782228292906961780,4873086033325899607],[4920443072178109535,12166339752785263406,2765886158311820276,14389634261895736381],[15748356119724444701,16496895720319696903,3088986984171500884,14315276150374356539],[237261159631309426,18163293419273505379,10955358815064548662,10205300065829386259],[3377634474164411777,13884586911625635671,8676415733247373358,14487726535829868017],[4465793107056927296,4772541034961375933,10418499922402064767,16379385802160077328],[9233245185978613117,3276489465248264693,16116845147925257429,14097161724551501536],[11144285152993250353,18073836749956503598,9405328957962321525,8017932497937870422],[17488420493232688917,8103912751855791885,9793824320435016301,2118999956310837980],[13796122261690762301,10360539622368174272,8482336745964205956,14128367477301736790],[12501434380289524413,15834598559144601317,10778040236433503731,16209251581256996478],[11492603375086044906,12889659685821786976,12763639147647709194,7612402080902807848]]},"stage_2_query":{"leaf_elements":[11713415158316510926,6327022698198597005,5588337157636914882,4851465273262935674,9773240736522272750,9261937230129421267,12442893198500992603,4525784545755602390,17614252631741728919,16071416045620222648,2376061193870717767,1344565231700780621,411945454208659338,16376132342945030306,18423854002322359388,6079102759511676975,3629680723136400684,799509021681439414,10061317072558006374,16367395161236200386,3004865566083185003,4193867311951686971,15811086355904980615,438712970255291219,898373823038928663,17203224869861457907,2019359712051846511,8584392277590564049,10477046630518786459,8159426854357861299,13025192819722151994,11003082329221282811,7062199428539274104,16390408893664365662,10285701245493543596,6251800387040447971,8560091471823848351,10786688425970558581,7047662779988359134,2739057635384318413,1051573892658406388,4274743544181306357,8664033200288765186,10058457374313784009,1901327379620819510,11628189209782757468],"proof":[[18365085965459775275,10845413286812608616,9685310897326265290,13448572807396178474],[12512427174464272811,14491862205554701723,9183721172759629060,275627199628737334],[3362936869557979356,15838764322670868225,2418540211606120698,13191281018196837522],[15446967506540884713,10715671102360214878,17268282247047494911,10143971279292451845],[17972495608955698000,742144179800279050,2695317084917928886,17406640836804649627],[14686944060762620969,16343159175256250080,6731677370317786389,17192229734357405770],[12543150714678160264,5961376198118246833,2925261932233738282,4759049946660114567],[8661414622483653696,2974940742523603228,5762833456535980311,2515409010909764637],[8272725843287820839,4551246682763554698,17404647594761459778,14096395841817274263],[481769891327765211,9549598208179676103,7465231059460409272,14593022118879741482],[13705342951457024315,17366170459099833185,10878718311866627784,17328516329169245204],[11483719647642157854,8161927728953395235,13791815194561439522,8301783100482271411],[7573680678515573928,17525864616530753441,13203133056176856922,797262845250637711],[14771740795079720353,4414166733749286675,11142385885751381098,1633307354359267217],[5100631897362844009,7165837283169339954,7281050093574407805,13493931811596315282],[829065432957179500,6000891358471194846,2286365648976107359,13267591513881651515],[7201919828557878623,18075308308153530416,7707424879695993339,17576654716129844431]]},"quotient_query":{"leaf_elements":[6370415832592260516,4428143811578277715,14311477560644769338,14177757287674544954,17961784852878299623,11158711305427465296,10835280327789735584,13770552378735561148,12065946727807100239,8807212875558417834,9422592213038749564,8707576049780048790,12442718373502198770,16877199190226969621,7803778265593463247,17115389718694229496],"proof":[[2329655391880163308,4142321241590139843,13603579136898957772,12350250078995592964],[1929706513687461412,15909463017829879599,17432358343538384291,17399805577406989696],[3457933720646615039,3190577602814923486,8120012853850540155,2290652192785369808],[11416351218882695984,2341847392437405152,4082102247198896863,10925477991486753974],[12801150077606904490,12269498543547495868,11425859233335232731,16069060494264427378],[8655124012146829680,5648205588601425683,11989029971016369365,11049139870093944037],[6809065265627712754,5861078850524216205,13807039466579155036,18247420766430532933],[6688935271700292001,17562375486367822535,13507118119003332688,6974599610001655366],[16128332340157125627,10217977662210444847,6827770130312019184,14703418167537599091],[7681317279450208150,11899018441431924648,17388952393558932576,14303527872757711486],[7433137857638037641,9209526100047537076,1551986912363946912,16987387486891940480],[5960451973099149930,8021141276045637742,13225550297792509961,8302722016122243055],[14419597452126409405,17069960884966323696,3268793124054715915,2149251380605701930],[15200758721523334734,15407134382049853773,5678127118331526982,7766224087075264651],[8704591735502926050,9784958346272239438,1684885808446795441,13207138455500432691],[895434351308107697,10579659998531182317,4539328167759638957,4918587761299476539],[15219974090202041036,10355475081129221990,14003088272047570913,13426480185855385482]]},"setup_query":{"leaf_elements":[9823219890383783886,946488553512052697,5417569868916339988,6152891786061844622,17975830737352926550,15731967086945980521,18140875083415390570,6875752834167299567,8352717381846763631,13640996643070933211,17847630264595323726,11683305366159343180,9167264988176901571,7029611546880984463,16444031787712608463,13413802681506853915,6928222216346476681,1723801519649640716,7173806994032268800,15816310080141089944,6718242520957188161,18030544843900322150,3887590736049143643,17556987275256942262,10543951600483140475,11510840533873934025,7205825304655883148,3258373924928619236,3232568479485926459,5811444836730483998,11209103346541815246,3040998336497975969,4811839849334368057,2531998376069941566,14976253649397696880,6605841769112765687,12149234502579371109,16858761629223043341,13027482360034090672,8077722112053482170,11180261469806691798,15107407068809401964,5184542473933840278,5438436592920228061,8238748507525353816,11685665795087499433,15841134478420993243,50676900960257967,3891202662426817964,4293979942052109017,14113631158844273178,2499614252624944269,9412480974859400578,18021206891379607096,10212253249325383009,8194129441334472687,3121720288257139696,4987444636773225774,11417398608149724138,3415124327417477174,7491269274922467054,5007177902610447268,15564683842242590514,14383975692214770709,4604852303092647235,13159206757542868632,11108292863960984546,5865935627819357491,9961351288630714815,12658068865595892861,9680738824954643724,14699129787730047291,7150454091353396353,477080672804911890,6460647947591081850,11693864195734643738,14360468426579743243,3174024553314493449,12292871961263369186,6319169794928287969,3685399878116285306,17166333807111602630,6235606326474080794,8882678975128976649,17434015825094432554,197105009636393431,6035429994513658732,13694393410431236952,3977214141660381131,16843809660610791503,2642030648201899330,16012634848491120841,1994760847148364703,7913350268391933222,4712797367039615507,18114525196427111972,4652332912464934999,13313051697744337212,8202346906646198,12114380237761021911,13513000737535975077,9170850577007522136,13639196726011275856,9931290080909872793,3186581485772212240,7040898303913106871,6619424461701573065,1046031106362030492,6223008194269117398,3715060940110745466,17663556931676264993,5630783219458903881,11136800822216121943,13489786757906025440,15329213928569273959,10674747129057953624,18233150051917658882,1142170858773733886,12449030868528384290,15011224821961876486,17931134271816238671,4175147189869175764,14411734014346313639,14574223729791523723,14867405626938386383,16796968347583303636,16223933706034690868,9832534137566769402,6100867708482356049,12111826409770627039,7045030943809704004,6926110512035917835,14518175037384788379,5093753281404053166,17084201877995865584,13575652175706641784,6243583523722115727,18139473120354616955,2715005234654569465,7243943936410894705,3274833527326891548,13149587143543277173,14581731941936913962,9791981239276394457,4854945055115486475,10670298628806410123,16639043747399178936,1936741642728062103,2412275799284722849,8141397556517652033,2857183871127917645,3223282185192346864,12758141931392841587,3427575539149761671,2812605697300525374,5746044822059559229],"proof":[[9543233977402851096,2207430898836399221,10661430779539941702,12149047690405170544],[14469154754617262410,16937665681208732426,9272483972699844846,8876335820202410882],[86198997334302203,10985270990771157954,2505666450220239525,5737445984179679217],[13322276935506084933,16443603846732887599,9530975227596282789,3174852748197962987],[14385762773099427268,3583852325799765044,12248403338038556635,11166921637055959481],[17938066593566652039,3827339447502591597,117026882878161295,16533537222864110038],[653993488131224296,16010279689532981413,401124075296450364,4062512819823938735],[17195002832880276433,10535360459928009584,10804399627931997881,8142376900442668911],[1068127249658617964,16124488112643879181,12274545444334794645,16217443317660640465],[592165372370340357,8081785104833576084,3171079107262575462,5851791157105531506],[15091659095387222393,14151357596202485313,13325349480338917192,5022099884446925340],[13955869699772395735,15991184255712495966,18082116009506743880,15019740153526644835],[8909650144759738951,11556081018348487584,9062528644984870019,5563521494227200412],[8809754800750914017,6209862063306683682,4812283614052165904,10161312941711397991],[7686807009685169100,9081579634793303474,11714924497422732827,14788151134378114931],[1832359183755906372,478848257101307051,17709123270266000116,8454173216194720377],[2825337570834942701,1347676540585739012,3552235004407085711,1060583059816643653]]},"fri_queries":[{"leaf_elements":[4971841849253627632,12072343664742220369,9563275430145725160,6878220622359072752,16085513481718479291,10700128385667591711,10836583368740049810,9640440804222465723,9817556952670494180,14771603871117696594,5708808558727541783,1225217866036628318,11738706188755330522,5703184739662263341,12885754213251669718,996737468849835625],"proof":[[17350735653258250583,10613675843578222254,15509334490472614319,2684752527326418783],[13047300028447277199,6191630841379208449,4928032934866102112,14275310094634830390],[11568699538610409706,7419578923485439698,5173593392503226180,16583648893922539130],[2378571358142622733,8030901513464881555,6624160137969424944,578340014278576956],[11677156782414284386,8566885204375123539,1988690074470345905,6227652657051426863],[15332170106768399232,1927872761942655646,16994403890387959000,1606553852577347383],[10239101250798877534,11131858242446533766,5055883797703529617,3464751438740084694],[2786802185112749551,9844648149554097884,15963368190333938740,4453913284927000327],[9924063444299696549,15584472061742353363,15964983299238521847,2495300189514007838],[15757080690025053615,17229654920614794210,5087985887802744831,17776415287912611562],[2041828871546546364,49993403752893910,17501280813891950730,1209680051909790255],[18233982695736586982,8519861737571468355,3626711855618245048,14765850127569784158],[2075575888495109935,14826032821986342854,13043476262639831219,5503614509639437556],[2955499177815998310,17670437591182936880,562230480527952728,6479201791096082069]]},{"leaf_elements":[17864777408078917840,12578906029930760220,1514363100360161445,15537270123191226313,5557565005033197360,3376221319999938171,20075097262411113,2939880511653310080,16141500054360120844,4785789051922859892,11791041754829116878,16329774305048741228,12220367326402734985,623166761331606123,3305222473261117200,8611008425599002745],"proof":[[11404397598537043757,18205335120037133677,9964321294133945849,4538889510078457017],[2065752936797644203,15261404600844902708,5763748402905846085,13863693212809231529],[7137106913787963637,9527427346934536850,7492580203590287064,16756120906374599898],[1329417476458354694,15831678636532470475,8181348223284098686,4797302166242780342],[2573000650488466437,6899116585234290689,14159365068988669244,5775188670194538250],[11234430156877730147,3323304005909872869,11468122812737312041,3747946739489102684],[4501086812940072622,10782210726117866832,8499226025882534467,9833717397164380530],[1782571512839701044,3497903930172748738,14956583414166916183,3141816006788988629],[4806326902669731481,95510899124497139,16343121197592428193,8043675224446774393],[4886186777146325567,18021849030663188427,16962870464187756074,8000864275442546488],[2065914019466681039,9751093087361631796,1041788443461241707,15886007464689788957]]},{"leaf_elements":[9687508909370545780,10677425565821313596,13147840045054562248,17046765879531569000,12561234991881242458,7114065416998148142,14336605374470646378,16909209598861031435,16372096147710793232,8971523534493252162,2476846754368275151,4641505196751269450,10533370890072785360,8658739072580506832,5666720838936617475,5550565855924423965],"proof":[[1479905612052175753,9378895720534981899,226190050438586090,13510135922842325095],[3910182174272093263,5386600989119777513,10182690900925891351,11728961224697173766],[3050807177299085903,5758175349854386613,11767293092863878682,14019239371793669041],[3211731403685326699,4949298755853041137,10262101855131352504,14682535249419937553],[5606572872107754846,13982311558427284076,5209431434733863772,3918851608076376810],[17792126217390042449,14848445439189206305,9825098216946612703,10315349321126240435],[12925576717230592371,14128923248834914992,4251405656937247208,8454846902498067334],[9337493231350890712,6135849217265235357,3602169715072990934,2155286987634949783]]},{"leaf_elements":[2133817071720834260,5368632698872852213,7523170898478326457,11318600444065722970,15511082145360558531,13531019219050501096,15670968824108104959,11901823816326065432,8242399044635633624,55893444912625550,7798104128721066616,16870399301875225133,5492177662256651374,11812440938339978652,22393783965550763,10608785161483347143],"proof":[[8986419926864677131,2412265238629804387,14747609387121800318,2109435488178434301],[15652199198108751043,13624884210600504684,13576799305979165783,6106651707700517357],[17077626971942232048,14330358548413414894,13422962166619146138,6449272927229729334],[16686500822935332902,9436103090645439744,9674689513333575711,4084637182715845406],[17767512737782668149,7056691306617396764,16344617099772662451,8528842919536213672]]},{"leaf_elements":[16536059362089900462,11268140529269111989,9460098320762629874,9830945258861761270,6288656409479024023,13924384278244023541,15169509868311569220,15654511477145531389,14028228291525785178,15085293467702255741,879070397201127375,11011827327796012696,4134146360567690974,14125562988571942952,2015371210282404664,1741297488956726505],"proof":[[1105159788271115204,3777640860133329440,11458073058188089014,4971944028264465656],[2707402844557173430,4658636768790482534,5298647501566847874,2652057082738657760]]},{"leaf_elements":[2090332255920191090,15383793183514205018,16796842030129987924,5156234286113161623,11959741824313716934,16079524884866373675,9779476225871497989,15653106700864869981],"proof":[]}]},{"witness_query":{"leaf_elements":[10323930651284281396,14537786548998273133,13568627521507962017,7967795123370083806,8248196193981665382,6551332430580621858,7610432138037065766,3584249598268177836,13416235706500881455,6948975327725277873,18071288875475677070,17992921870686931045,2470005314808858608,5497887643885045148,14558923488506564826,2402241830819662962,9273259688620992365,1952417827874015431,5781677139223623247,1543002805965994136,14763905511634981821,6179572249519978418,2900730167273669237,15039104944046686832,11640802435774031012,16138974613964228704,10285530414697499720,5795097341930478326,13643612001004152556,1871344498830549408,12811561343266254361,7668176286448313165,4188403950007702059,11307697379456908168,706072622591532734,14314256563816524770,6749310077855365680,3497650001096740603,12592961939095098531,10418460548354330204,14131963957146234802,7066102089342937825,10550912918457286066,8121555173533541323,106284187385534011,17038269829344996667,16637978282117402260,7067733605092147476,13655610540372401184,8260773517934686423,3288763606791652714,4030544546303629814,11443980563429295671,7682479251892194502,6757351346264618910,11908006535162827504,10783056403967940550,11202140578604246590,11704854384393869683,12184774092413098913,16968110135841889770,13504418634719433298,2512454135588403652,5339255737963425740,15037513256622707032,13030187712557292742,3095969240877957307,6979051370956616549,18333836553694073175,16243846830398064580,13224514168726861424,723874896501687589,4444244078727282056,3246136033176357167,27731749592088030,10912908228957489154,6180513186525873084,326609154921557266,13313039515818965116,1075115387170753642,9701957452890855395,14911050214371888429,6592690552202003732,719453095236041109,16396783942076509007,5723983314422955788,4549445810540352877,6732594903795196821,2250868624779976382,2066455939495457762,5070338705592120915,16694341212712005664,5819192078915253398,18067452224410569255,2801668379906442224,692349126492750244,10041081784253899451,17183876030122404492,17114052583527461668,9647433710711891891,4576611233909532306,7967855471954359622,11048278743067840709,8810387185882991839,3107069060155789151,2833050969157275573,12493156471605223640,7239653176681324726,6973180315082202494,2101400068042089987,6760002995768071587,9307295573727550732,7924400677068132402,16209763967676448829,17877381677076017935,3465255419048241021,1997056847909433914,16451101024372083744,1705388111431251178,16013573458447854822,17760852592608244077,1615613999333274061,17486169272131953878,6989565989186643183,18431362897608207725,11711691609150063332,4755761894112724124,17038339320207027692,13001035757519696425,2678681277388154812,13236659023643893306,4162351546148704210,13391352040481714497,8370600362190062395,9009596297509698931,11138714524827416313,846482265428899913,2875772498187623121,7202029425280040967,2127035257617460728,6625554905136982032,7688693624867480536,861648732742260743,695851471725937403],"proof":[[2958138957693395549,4034382948401945708,9413653712214946956,13494105305952720399],[5152259756045975367,9280701924905447686,6350885132573466445,7266698575693861517],[9419383589591187565,14395223071448558389,3001982500316263389,3831462880983149088],[12906440383649179475,8688981115130253343,12492671351657713379,12121270082089051197],[8758301419786974519,3918235348119602276,16401478883664258697,2667298855610823523],[15066207734054813839,9437812469423851151,14904593004544304011,18189850022526888528],[7225680207702391357,5151944535307786316,1249978649454166980,14818694036314105330],[8070941178578088666,17210663568795797587,17434923977060081679,395767171590067833],[16533290176245754608,7087753940467034301,12199786307385761485,8928667522716117473],[2878136742274240074,444251272005946521,17111856794210354297,10297457619634600059],[13490945755449086021,11611213214885527736,7993743719347843823,9451118529045301325],[14975041563661553528,1779896053612991011,18344904608243287786,9276379260094141005],[17378978982005721834,3989061682745186789,475998697031185862,8761070052484012133],[10377268849219178535,6283149019122802107,15767833922963367462,16252538588132110945],[390054767728482021,3178553506404538979,16471365595016750963,12722632490880425324],[1088713196523712798,4106352671711940184,12949254492880499859,709736761924260540],[4131246993864415573,13941769014960634211,14244756967470440488,13400230066119539514]]},"stage_2_query":{"leaf_elements":[12548977122244969082,14567139720121901743,9913602812758854583,15344602924312897970,8083705253468027713,3876334660241328031,15424464664730737335,13173490392449896664,5417821098595125642,11622922792097547730,8732902439468214816,3946134372970985595,6450768986974204082,15817248311596058328,5559417851087288695,12787991003833073824,13106602117615793106,13351305709410607485,13778280776225581860,600395705515450249,15558944282339438159,1341364239095743808,1993337933197545069,1351748504398403151,16110533122205625047,3991649210675667815,10831039554458234715,6809108928120894840,4611511559406165535,5926174268649752079,4149322472582368911,11946528637114189,11480309112777621681,8313100840252286870,13564653446016356279,12259889752098325298,2426768440521513495,18345517551262648167,10504421536352160252,2077601566540952898,256460412721351146,3456479445550059354,8765840145257240320,17649791596237574892,16174976294462725637,5022457866695324341],"proof":[[12362871970535229388,6625402969357778252,8758434628587349117,9479565655519654762],[1536585376043519850,14020043458962052706,18021236372748805041,4808099576231853075],[2180414514892405628,17670492056296612350,3853298789279107295,178070432315204042],[13548042332251927131,3148006310368470938,8325067431968984548,14296314869351843083],[14630253832219676153,5153279654681018152,3288641712501508072,10570287996023119863],[8903751453288913526,7677579349691678172,4665636689309833615,1444733457655889968],[14252139981797948608,14100259025721253859,5655987354547369989,11082186465460832813],[7164989844476889038,7486884342747897966,16683950233956893995,8282951424002286054],[17635534296582994842,7280017302796690308,10742942142766712930,14184878436458660011],[17686666871604944030,18193430769956564862,1338736292833598009,9975642807858070523],[2899386080852391275,7994982328784296439,16227849476878890923,17803412922028521888],[91050213629431083,4529233202727277240,6623803238481213287,206288695588980418],[6316650619401167705,17682057280559785427,799629626360958291,348701045153943800],[5419969964322697877,16075411435224447166,12143675337285554169,7546637766413598143],[14861271776944027655,3530685975893493237,11823050274724820575,3599583553040106491],[11177371579661376970,15443685942562331261,13327478431993353618,788544704267509153],[12940350048878081686,18318030771015011443,16734511954444878893,8710777237650930866]]},"quotient_query":{"leaf_elements":[4215790299971453527,8292858278145872555,1557373521324433057,8205455937973937974,15735934267207917317,13404466478568168864,13045118321343959432,11856866023752959449,6267825658086581921,9478657219705363270,4781091874985961246,15848917864620808899,12349261889964873472,14239277230823784406,12125044648446921592,6528216817085837962],"proof":[[15505540117385812328,17476564782078721367,17525126353297383226,421889556751813488],[3155598371432826418,1492570051370212295,2067406860178258365,11419601387473453342],[15587129547641710600,3401913109975602627,7195458934242966833,7645787639896367153],[2381082250846655958,16962682344597832782,2707742131950583468,5006058012516297644],[15675391130776685395,15828980876632315378,11527402325559665417,13299174114694476139],[8177474765397278593,4499993115774064997,13631454021459468962,17300793465232011614],[17585482435207829673,7066609677631266204,11536104105308018432,6328712349083663463],[11167802512179681502,1003332951492374074,1061010638356854926,2568866222804376649],[6101693744076301692,45818475051693275,18189565988190440933,13761638486276167251],[13424183617521365606,5749252847053710176,8247327080353277151,1484468486752285867],[14821947792321831516,16858672516985180013,5619309318413684930,13080775835052637363],[15368715387654844175,10299442138068944320,16994481819012223994,9724094365187669179],[9708566651702414159,17881491010318896456,7434554562114054121,16818824944475071974],[3976510312342119290,12590807029254512542,13113254493792018650,12232233395266175125],[6471125751045445133,17605062945319898144,6668223292464788117,9326179089221659344],[11738280845692456013,13470361909083677798,11310297966262001218,10989414759253677420],[4907767893259991028,8054542250148444320,2777251878088069259,14509779907815603908]]},"setup_query":{"leaf_elements":[16561901750319799101,14438722315883317250,16885773128660888181,16830603632233137285,4614273365835567072,10108901636515693032,10079218154683289639,10618114500492505027,4723534477536115303,6645548824478162576,12964899791804850507,8968695628444304153,4947591849924397129,14681410683452990995,8323130022625000190,470496215028947032,10168865909964140121,6153202359003484786,216050273886939787,7211779075259027796,11650882359532488588,9004767721104951988,12216737035457498333,6320686019651165059,15932815619389373886,16933302718901248915,13396883487704560954,3510067400741798057,11198830546546783167,15722361991222366307,12586796013229907875,3167217510573562884,5258850869111699860,14863781744705336833,6097235987048729602,1955541202570749657,4730272067445894503,7620244181287010269,14916646534149767219,2241023489980573743,1128815498225488896,11049295090859586246,2614941320126362867,12383498334973620691,8477034759675928689,14562767645417757029,5297813793029767274,16953486653434107019,12608398542271176509,3862491080666087271,14385739342335704952,8655186328832250980,2809360058157203845,1094484843434068525,16932679012053801561,7629522889729727554,2631822848016734308,7967176261386718609,5834844825086455929,2783572184460862120,844179544951867743,12495407819847761977,17788225801190316787,15602640714377447999,7660750023847831378,640622665112957451,1227662104178236288,6786052745002487086,13273454127750396574,2690418740239145446,18073695549992203046,6189667295714878930,11265043404852050696,16152406499162293070,7303541226227847695,6222444040464938553,10230288742106362914,17608304262786931578,11597805053843582288,16951294686757378937,6530601889687158264,325532868321877215,495625948802769301,14396293378139156358,9219726894706680885,10640177698360499882,17428087469941641377,10773045978575952589,11732506728787188668,13222895790015018490,12652936897752267054,7472890208000545155,10110394364629572321,9589168155410005304,963776128688210308,4960706618170422861,11398127355725412851,16842914134207335399,6748099190585754147,7697985719358941251,15912372644283728752,16583934349629096792,10490857171566515046,12198218861212655464,17456486220494881346,17283094408316489000,14746383723927384675,2436099844405129085,6238227558500940925,16991401740187703819,7976749524711452189,17189172756460967949,3660347002208409652,188005141631545605,10367780753256706511,4810310788771607031,5912333676475049267,2961250383149634159,18402307468314781702,15864231675352195516,17034812456712266817,2909667869477116671,10873708410410371266,6679055516241278701,10941655661784148424,2532386252766841049,14663816946551947401,12733180595512877314,4085661968947990133,3439494289148672735,5166278826504223439,9539300788134256409,13808913658683159293,497073020750158217,2087142766177655546,13360971578920526732,11412276425399373734,3816115699870726659,2551238275901197758,10292438353677504741,13832666467167059264,1604136234756320100,8970427339878953451,16004943103959726095,7469134356747372125,11364879378729315411,1276855179037173370,1497906945897405169,6414129647769283381,7579034925493059787,9168496078197440301,2752706475179539388,11015448768990029608,14000849923010658265,4829804412080506497,8762625438191194071],"proof":[[11326350927650366905,7664479027272444589,12662125184693955062,5289784612470444581],[2614031955568804720,4872039126063736358,10263501768724965227,9664333118194884396],[15962455681968829726,2031533800419918469,10125524454354562493,10734170095412852205],[15857827881324423948,4200524322556711884,3322772772278057474,7696121726765805567],[5644411560873045366,46383374196642476,4281276895946074130,10060859586573997372],[16490839286193962337,7016074173522503580,4969329354766450083,9294391343485994321],[14251653322531082703,18106351513188909060,11755825732476002394,5521080262549366697],[3006246184083306036,12923735128667358587,6009481014870022074,10529906421984847433],[4498846820103016667,3215681259561496827,2905805041158298784,226156617973702743],[4055540923709834972,17143476899290188190,11985045993292046132,10050611724614234627],[680405051359319966,16165432750039798905,8861877192782006155,11995863752161335315],[8592848779478201967,9144134752581774041,7456797460965065037,16351559790660945519],[11493488036288831806,12529003886597130668,17646025576812806461,5351813331449150458],[2492596783302826314,16714333512000969864,13249129474461301786,3577478552361868048],[14305792105545863207,6192754762712833423,4672185026013962968,13662212095374334783],[14148266119838845243,9213971169885570210,11876504924492948303,17827164428586835007],[6870603959408415557,5624116706049520422,7652133964888741811,10524187432264972050]]},"fri_queries":[{"leaf_elements":[11379735317476619897,18099529111840469682,13361236057650025614,7765277618530547775,8013106867061768689,11830847250079726042,12133210627517171639,13867094587313505579,12615038747161178763,5665534876511381906,17198238262950589921,10432459529473689308,4950393239436718913,12510198736107261962,385428915474866197,18029384116170541674],"proof":[[15886245419522862127,5243083865337134564,7104087688324089130,4897602318380351932],[628267840375818924,9589542993500269959,13764717214138401801,16877421299016374044],[10440727100950120674,14233995503047757145,8636506369164593723,12420676568153120851],[17555381033875554975,17344889900333223689,7977598543147948704,13509189721051988460],[11097659497023955461,251408916356168448,3460119564819179901,4813800441717595716],[1725382484919093160,14246762636278475448,4367831673459094976,10239600633916928886],[10951181468023270850,80355974438357732,16779833458637962306,9930654333209730925],[4050812120642340858,9093576240543801408,318576606033088427,408911435887126833],[11971084360708856217,1710086295234004276,9874629164349606586,18332473368999446496],[3834641770401181066,10953543126352785882,17402299591104030824,7599834750987266379],[9660239605151032719,471663181711003322,854558578649553629,15127084159968512463],[7636320013389772558,4174477033717715047,11893591161147178801,5895721639590491187],[1938764688089121501,13373907275709387593,14774259897771044993,14976022568275049060],[17797284224233237864,12190792518859977071,10373917212654131311,7623241933351057876]]},{"leaf_elements":[12555520185252718525,163379821740592672,7800204444248277991,3372416920904113000,11544400466748731629,3769668887790412890,18349883819277312320,2252827564733055134,11464401468788500882,7836883128272220815,14643145248630729381,11674393650910099954,9508093460131806715,7441234899249532690,8100219827043653403,9399751138836832812],"proof":[[13458699678534438768,2684557171458181237,231106295167909353,6354218570654159819],[10694104300444015612,1731303022347660876,16870413576080608808,1236545697788918419],[13767290635355878739,5829354966080429978,1025701884364535836,9653201279211076632],[11370286585798639283,6716065270105460676,12522049637951415073,14877070388972275332],[14644229995272842385,9665390553236671627,16884058688293748812,17612152525017696001],[3754063689332237994,8349834479735110624,13781557275293269233,16221824061515939731],[5402179976899940377,17484829448287807895,4586154046027867943,13475422243703970381],[13377228374642020582,2530623959047499801,16444141573829765019,12456891616004680208],[16906423020611547213,3584670311213892073,2573114324583425593,8339089016560294674],[8061577346435452110,17650354644707453151,11922245048828574317,10793930734906615046],[8161171072864732734,10440603802106643560,6180756988961224215,6889831446143809249]]},{"leaf_elements":[6158652079745965293,18428762301089258448,675712904432150117,355726720935448960,2244488839189086645,12724109188055919870,13418883765060867874,14089394846392398591,4025433765680008052,15629609150645266256,12433894142006658250,287074542445697721,4315460984519364877,9823251307225797064,4296613202039966900,15979880259082413965],"proof":[[10394694113721588434,3373573274879758996,2932529134728992283,2160541412375629644],[8169267599372619410,14152995638645649577,18106051704680454195,227336033197724427],[3121893841800416057,2518262632112229255,6984293743484167525,2854859552905644029],[9886841504729920684,16646054915053540268,3893267370551610369,1400763562630800315],[3455230555162943149,9040799732424166978,988937931298342021,13191886052017278499],[16797031873335384288,13660174552545171177,14407548593192313954,11907433931637969276],[14902444465082129622,8528938398362357914,8935076139948631106,11557470680509185356],[6720534697580595973,13474766828711122676,2473097082919214989,18068252403595198348]]},{"leaf_elements":[7639900336684674053,7971880799616905834,10573988181358550581,10614710723656874702,18345718252373046555,7073095264966646920,15993094534177779004,10998568231202588106,1700478864485766480,3183081272735836318,5492297210240046966,9446934939850249443,10627932426581805234,17954466205804411525,6682850694832895613,8748618163345592329],"proof":[[5061947819949746315,5205526273644311120,16454351405371466786,12903929558551901275],[16862614568860013114,6266398500883891198,17506416566675842588,12642751054754509455],[15832995800328868421,3106052253951732778,9980697058940262759,14118543079866706281],[14693201314004073283,10470236196002365949,8450305842439727349,11635396348164023828],[7745958475259728694,2873250920535013732,94873201471673482,1565932192576522106]]},{"leaf_elements":[13966723753100009171,11759868888991535077,12315879254388428501,599834740171811313,6104656930027499858,5787245737769192166,8049629852570101843,11355002810246629560,4215440197962298072,11661020364620719807,12156015093228303048,915220606642817676,6944909196506577934,2124652442115460136,4379482078261594662,2249293679505961867],"proof":[[2271441942650369803,15961933320732874494,1029771272337896378,7796262979946111341],[17656621556331237756,3884539910827412734,5169394874961648628,18423172052389089955]]},{"leaf_elements":[3103352029016043777,11936003578925779291,2481494059698405049,16760758113560209882,17943014902864064829,11760753107849584284,16263520714716793081,17159242401050750845],"proof":[]}]},{"witness_query":{"leaf_elements":[12359425454604625447,16002368361365502652,3540399622764649367,9882685161944803398,17928213048313556883,1210932645186709801,10458331601294012966,3058126574056880221,1238542055243466456,978410324280966789,8514773959297775984,16565864821028579292,4541055414627415708,11076660329507986482,12875227641515412226,13780926265681133454,2966859572354038800,14134491003782198842,2984647118845662026,6831844839826172079,6452835088680954659,2969058771836382395,1713718985246045753,2671719356122880085,118618860730864608,13251705724840888151,1308616355486571699,3838189546294863244,1907938957258593102,2467553502100512515,9890324271689436304,7061001943632096071,5016358111951888377,5021506795973500603,239470940360408576,17985993114209003488,9734595225456331586,7758867929179719008,10598435863026360813,12978518119437518732,18114844797472596379,10228233441942307030,13298555035215751472,17059602375595026255,2118246257313649997,2854158156715929739,17047319258860527608,17761864697037623017,7683599986364687814,7282389529750860111,10834530014928700801,17295627486908182928,328900905129808911,471885620519832288,6101256579407537909,5132054473319130817,4969196173236722015,18368233278990100663,11456910706476096254,14110143303128574900,13504043557845038560,2175420172307342971,5533438599695028730,4515674505988636189,12267344851037683564,5549310295182315039,18384325150857425693,10626850378606408013,10413983103487990034,4032835389622242227,11814363926035182379,16197474704021625072,1839228322443010822,11083745357716873785,11908372696094072480,774741956808103750,8888992019022937991,17467723048664924222,703523776683427973,9612274697209764257,18110289664631862893,12670494172329901787,16341212284337829246,5728522720841525646,7136238168501813830,12565213374408501741,6096288222523265459,15771412202691027024,9575766157679130370,9721863083227269457,7775094490499931038,16945718928140971433,1897198348076527471,9183609703319128502,526066158801195925,12125616648343843028,5030124539093882696,11364929577559081053,13145613891973049332,9703229790380842309,5360737697258746719,11510818763861861003,7124742409251241305,1597289069433412714,3460783819325807648,3935758099010251527,11728573606727883263,15313196947333530583,5410693247522727528,5592649413793411063,8311745161727332729,7092388973161132735,5235330117178665387,14166151156306990504,5461894896248937450,5876152215134297050,8229834604126297680,7273264073807149200,2881791156836158083,9981518466948190638,14530757891031007076,10906117298322819336,15104345031470370624,13037352517258949298,12071071397155617803,11053345897642655466,5743303950268232503,5475300978394419853,18057764496330275650,625565685747739806,536708666670101052,10226531683397696390,10803518965110848862,6445037456910481136,11070760288872029073,18063494787116704581,16144785426609452095,15161963140531650294,10366602687513291142,14024026741791698889,2429169695538603454,16837608413342259518,8266975350601540386,12086368245489296223],"proof":[[11757746021494690999,13836484555536752274,14604652788766901323,18421794843064199059],[15029034127436921421,173888217826606728,9153909553993109335,16371468612006097151],[15742145659578802951,9789146157820766405,4596353114703584376,9807102152429057294],[9688735184550029628,11779821926866148433,10706780128758592507,6060734097329894232],[12632708937351583821,11673369278552359244,14500677044277106220,9486641504314704934],[935120929032159792,6636784295889014162,1084980658109007669,12491612156995256967],[5437352448382361592,5965676504720361580,9082039426056496566,2723139982998148980],[14925781859750213703,5151364416914899484,5214263351710854375,15880912627822477914],[9456271157567617884,8259108641470253386,14443808475094965277,7270719919826928317],[6372534729296671746,13901754256003123555,14567160917254427857,2326501243684009324],[14474269665934145303,4295145589154478269,62693417622813673,18424464356182307421],[3900077880510438806,8978749825787126117,6310334047280268308,17428938823651990343],[1217429575480450846,3610543298912214252,10795541128802089328,4914506781381754411],[2900792717822450496,478929863053921967,9248159437056505755,4993771996452701003],[16739067688556130049,11095817199092295687,15273075958739258080,16832208103774325746],[17394839474954665308,10714620509385696929,1516931889067598655,3613694577534817218],[17749797669654443142,4009991232882674734,605325695833004585,6573277157088601865]]},"stage_2_query":{"leaf_elements":[8038399061025611147,373256371561603837,458986544619635658,1467638370184871137,10477663150451899753,16287190964954065605,6422508079048416585,5209101886271520171,14135587118195630475,7500038237596859620,8648041610343966618,9339364030030096295,5290926460340661132,1538665986959193880,13694050297815828262,7453112490673754260,11542245330201454276,7619258525761992312,1587013313291214752,725919371010159438,7809746840866746428,18120571224735753675,6413123883393564766,13413548388566325409,13676459981187787444,15047897572808572493,15571882892232075605,8723223705972143482,11961562548991810863,8017564811057199524,18406520619624725346,11949498458590668069,5484408432945514784,10277695944039128587,1676045383105722725,368497465229592893,4875394211038185743,3468354886918596976,5763254942948546344,16011098465166572765,3923838570177586896,14654492672234184463,8117399310877693437,16013010221745920330,12644228493520326535,6112750196732879598],"proof":[[17288258915004323614,10351767930374353874,9060995506209766196,12172427885852959371],[14090869246760065986,10460143103800857710,16253440450750457227,3478560870662657396],[9784083769699192411,4919937359130673524,18444360947620466508,711095403962746038],[9110574586405571042,5812443462294278728,10466974809105482823,7137885093127138658],[10462987985200105852,14433696256494516077,6076264235737357133,14831743743938416239],[13428887732111650514,18002051986601320321,14268805110405742105,15379808233126424701],[11729037670708698578,14702832037524303582,1929560965596496625,1701300081089575337],[11529537276839508182,15344564198915130997,14860570853326819608,18378591161579726586],[16291434715777134399,15478557155847392367,5683698547138655431,14909796201986194063],[9023593186171775674,13349925112522368774,5741256337776094837,7637285858543101227],[9082512140865703870,1652206415545274240,13308630545856797765,2522207993956272343],[6208291678213276040,10491903721152364542,742887194878109710,16882805916337382062],[12971848567197884827,15779625414375686786,1141229268635382134,6191913258338589448],[15054987604978413118,17981969902801841793,3098107877927561736,641986042882354855],[10497225429249921596,2576218401865570247,10947209680571104012,8349875474015396567],[13812450547504630275,9307724372608250421,12795344249259945845,12762437889312024893],[2715413528194906888,9925031826019529185,245639860247107963,3124596961874203968]]},"quotient_query":{"leaf_elements":[15419470071585607342,13570535296256074974,14637013515929032048,13571490068018244966,12008645286891678503,9656460172048368543,1762738760034524433,5650154646175742615,18263954753702845245,832831907693559710,18388290641994223246,12371474083646412467,13967212815289107131,14503269220681045381,126916556700464429,16532082153881555312],"proof":[[8396998119602911240,6416949406067392562,5172369114185180774,6078830695894865185],[15439995729386443133,7820431072466060926,13334044626315355616,12523863153803567391],[17361664047655877758,3115264698725589765,7290684462763638253,2526813686293262366],[10646610689700087589,9249026834866872825,4740184125327971274,5853679926372686964],[8247325796256069520,1623896238033680346,9290572682142804076,8363850121121893532],[8619303892129252131,2296047907141441759,10310421282862625889,6409188359790301069],[8638121076403282927,6379154010462763318,15552214056599072887,5622588980199282675],[7562761346362242817,10149298237700207569,6740219810096420803,7472636852690058506],[2830824253180986387,9483414132070020839,3500360560672830260,11119656688054441329],[8797876068073684389,965277356101291973,15834539882206271721,10463867782580015445],[9165530235678201931,17525242057604168501,3711134384890001565,7465725787473077090],[9566553944014568754,187210011643032143,7015379761900798770,13177636528877170967],[8832249561136072331,14114433880828750443,3331902777748452670,17615998846901779189],[17999746678063181540,13242919210196820873,2364297772902690847,736479592187731052],[17367427281961181698,2239565629594721306,14034408301351545408,16384576246356159388],[6726144109819370796,4969950042246196166,2037085210041389708,1456417560739645009],[12614190965028526896,1433231526985104969,7403404578079225471,7543970622185024684]]},"setup_query":{"leaf_elements":[18304999710690750388,3734587998778323141,13573596382151370660,9459563434195592934,12712354195820587344,6755783002709666332,10021832713837834483,2430909002038545250,11869064200634951365,4023192463795716526,1281597228404262305,6458665817380010035,3035988208275391690,3932888700663493871,13974128854614331685,15964151092368672374,3462173573166716064,7174153325012883258,17266485361869705643,11781434346904117927,17584892619444642066,8956751017207438124,6105035659903216729,9468289817523426990,12777491441289308228,11778453476293566706,9560374517785988950,15430505648240403046,17057465416089293110,12857936846210932940,12994026183339743965,3170131159123235541,9846397540814248655,13229530931358534501,12831235166766395900,7381598231629974395,453889275037817500,8242210380444188358,58527137781897330,10569678903477292976,1527417799287998398,16547370928980224220,15973379934517728525,14284636895299105905,12828789650050057532,16857915021824651152,16151585179136756138,14686577915922917711,16284573191998853643,15238920288559098367,18171419802142132934,16780269785561417172,7533333748724745416,10229456853267570385,16716183743683790434,17604867590294080998,10541021924092077448,2982528145583922882,6474351936852256841,947772143746585339,7457493190099155851,919436012655764717,16645986632104815567,8307435264830332161,7801356710895577040,17345706021935767411,7731893102698166149,6173202637223113005,10342506271979711024,15711156689487432025,8219206146006385423,15659501484727162911,4770976110211573200,2901002092505002511,7025407703071914365,11035243892386383577,4841135335680185277,3477921279671135235,5625978913647349472,2515083879710595706,3873858562402510686,17515153468761461997,3103801608832996005,11512772484981637751,17217697219468090189,13376647121164976458,3250643138807867268,1369816109887974395,16842531225423015790,14742150604061977146,13448998836809118644,11626462306714951681,16274029822053363497,9617506203953702759,8931085581579785600,16693483503343078754,7287056687745942872,3845593693155881245,8865420469954341683,9021710481087837051,6061526674438312073,17310034180770670094,4040108771579448096,7455398340007875990,14697758802663971952,14473249826448538401,9654160929354110767,17516958953003081971,11872711240945037972,12932241999166152314,12835294230005431269,14241576948591214745,17240794547693247140,15056869495404225311,1273739171590965482,8191230849609619733,8622786552106138796,8338945505551052681,17220109174536735444,9241990980061701084,4082673393168830532,13660313917869312312,17098121186707722818,12715588867472473942,3494082336234352592,10609872683634743264,2681931536021501409,17696963683367141608,983387305441671948,6053517670575695600,8607598809176580928,5846411479056070602,13157273522322700310,14827615084175936028,4205725696997930965,3997756773200679467,7789867572165317444,12623413741403628163,1880904497861573530,1808680009342879385,7368063506656132835,8550197062673088620,13086269892736147569,4219739174950146397,5465192134910997430,6178640053125509233,892014922607284113,5684407110320898341,15840201456672350458,1478262939701747537,15130301126994203430,14817851011985121625,6971875814165536122,17973377505877991319,12092633863669913620,9042686869396116180],"proof":[[16928923680696586321,10558604021243891050,13937124534139978822,8927302365248742111],[14930506504369007321,11820002754784269924,4710927287339985563,11394823540193477166],[755203837541438180,4116038783195474139,6682940219777748721,11920237419941089223],[14291123470095493554,5502137217417236892,9385631307063095549,10074800328913101021],[4763985008786730665,4502058902221402957,2860069582476946005,13349021445719658918],[15761150038808502576,1156596886807425864,1773607318697730779,1545341539361126785],[6820510817006766759,15134521887900327989,2563256821460461064,2804953628329254338],[7777105359319207673,4088620183555159592,9600665028742356969,3116911952145098695],[10844431499670211640,249023787123693011,12090936459079686357,811120720366902881],[16411025185907575925,12446950392410779927,16882133212974458673,3740496485543550178],[669107950368496862,16515962405022549230,998007194650585335,5517647154844404842],[17265948688419200034,13882740352862163194,8356003766101485735,850951825052559781],[11611314896281750236,8576553259584336360,1381781439376470812,11390387510499824354],[2756795663564782257,6395886215972992808,11683895449447607366,1052302355051333770],[5527488034326329228,7448694919277925646,14850821080927416216,972464198182861346],[5903578999765761747,1806049501837537744,9027834739298587119,9284380516486803063],[6589670078010939968,16725824113563304687,8885655980294268245,4567844467747420596]]},"fri_queries":[{"leaf_elements":[1630589259219029078,12084938398105057384,3652701242382415819,4318172078424524884,17822443654355258783,16033372287529755578,5639553503655575041,10363261966286085635,34031129182113670,13759767817518477503,12006749927621641903,11700351325956047673,3027174057024998570,7737926667060086258,1405694063160972391,15795429882869169670],"proof":[[8003334646419125297,3178752824037097673,2062811630899986854,3081638211060625155],[17328520223252733614,13701278274834785127,17292074702040440228,15600043183485871678],[7735913132381226817,14077213248013108172,1361117443993981865,3608579268931775960],[6115853036157024079,12613872855463605231,5276757389878035212,15510943625877730887],[12501232674787156203,5523335492226518469,9794611981722381279,12452611452383522459],[1707264164047082456,6666703294758624672,16381248361641241553,298558056203455998],[11730432543182733286,14677049968025630942,7875114466292568130,12752996971309280780],[17775086003785532371,10252507577025128605,2445908364091411950,17173391037102076824],[1093820942124463278,4755488735420313207,4552322819750470947,16554744978264853947],[12724635701756431625,6731208753444714153,14648612841747352284,16051539788122889618],[12291708416401439564,6267548064509262490,14188115589118761824,1988230515199039130],[3094519036914810785,12790147006134864885,12626282078366951472,16637955004191373099],[6811733995792320521,1416990469745232924,9941472239977387974,876399526878718509],[2021873893557404952,15786744563948742915,13683315706066140808,9697021181175829557]]},{"leaf_elements":[6919069380880063569,3444400933149242271,11230180880334617014,4192992242616611500,559871341113171070,12574747479059559762,17878325495918058609,12357600856274342535,15785716986473964210,13669716231561257459,2150240229073704133,5532478204572094122,9932041084904732523,7466340685156895220,7259548636709046004,15145364929683426708],"proof":[[10924187366083932991,3056330599979638701,16276951622194531254,1311244163660260497],[16188223590394164497,16220840936127303914,11599012429436510330,11798655574704103020],[15044994429163937970,3503208435993427238,14796928757081841532,5484554356065625389],[910025124307485207,13551138022703813206,13829919520309009874,6536698306801929389],[12293647792975545128,8823503067140662769,163820137940894032,40043562107651984],[3481825497092363502,14750795649998162957,10262236484848267555,3549360211277464185],[1989437509325644661,3072963952218820121,13159161915434415025,6231288241671598834],[4413103866758194723,3104365422654098030,7201511017947215379,11998015572605935433],[6686562930058896422,15673889531974415754,16147810889988694411,209998909411336678],[1273395600654573564,6710747287474069912,11594440748705663131,11716519810845889897],[1834334951414258443,1616263108559885528,2565690566078155455,11602153308567131946]]},{"leaf_elements":[4116028202579501681,11588712205917697728,2187555827697848705,3434001069254332116,2282791686463514656,15023494614088216073,18364379022415159974,14248768813362130701,12330630773871409537,2815222762264607530,5187170010467498739,2764323277126765394,17621247014222151912,2396771349545474896,12876828054872256050,13228638340496668146],"proof":[[12134400947088105470,10302792032962171617,7342048624810302270,14648243345064003556],[7162084579792535544,12859193770020093490,13293809201734769298,18251998533074103113],[4481791434103236155,10861256513681491314,11145087405659977345,17809831696264389512],[4785538436542433343,4564650141118508275,14396524650352909400,13592651606642494066],[13165672376370582566,1456228222210114146,10333265514049469617,4844860376040556988],[5416384067444848482,14248871228087525711,4163118716817867386,5105282655952987396],[5229250102254960410,10780058762046438978,2901524364594559908,5011195387016196499],[3346736718718744883,13933060122817757739,10193934182905661484,13653016100923550432]]},{"leaf_elements":[15972753279437751874,11269152963581025127,10251699688036381994,18267696390254464393,998572944047316248,7105875735614803603,14631918289393821939,5474003058379242274,13809125153199403539,8003871971538054932,17400460781734846472,14065229145416905847,8585934282593360951,16930521958496357790,1088343263725177810,18299619926838226146],"proof":[[6173614143570767082,8051361580924141903,6608206519048226029,3686061535866592021],[6328861783803074774,4309690532007332884,13947912242391467598,13638826446664222253],[2828634632886397145,16556356002749211901,18208299515803008312,14982666881889047608],[12720079535709794969,8786801493458161507,13566418957692675886,7184746272558140198],[4358907288188110431,7712808693960648347,4185965397487066865,12918764144379557939]]},{"leaf_elements":[2460176121868212821,3299878601553739717,11674788052425307070,4504385869058416944,5074222255066100632,2917072263982601126,6752096797512073671,14639283367289970484,7157792815370175154,2906126235265470156,62029639156094130,15286573977971795870,3203402905485982877,12476409603463855525,13907571977627932833,1929682928589291455],"proof":[[3925260190984129482,4900208549381549830,1574346737430393795,13443301126700407139],[10681033929559715168,10548561920915882694,13557244669854761596,12042341239689273021]]},{"leaf_elements":[16371276844632437187,5763442631456442294,9612659274689155166,12661874354129793348,4727490084259142759,16024340444489255688,11060965350812909448,11778191179252601154],"proof":[]}]},{"witness_query":{"leaf_elements":[1749318795988841676,3434108826850885030,14094993767821572941,17132982112503795598,7113742811852701055,3575216041370805944,10707252103789925308,10824602262600589501,11352073275648873794,1877806319063038294,2939923265756619330,10185536961983695173,14430685944034818784,16817948527770221196,11835418853109479314,2529874682290084554,4980582075993063231,17962201543986164852,16513725683612265655,1800235296836524015,15732165123129275859,6266793539117899318,676018250377483829,4301395524847552913,16239535240869404128,5371178259656966412,11838972997475956615,17534878836233918224,17540464753664561003,5893350040979952237,12526104641934259202,9152674341846314484,10751303318089908244,6439813962655403566,2061034195542092544,5919104828320211961,17232228299158425871,5640596943315572637,11503194624951826523,547217568834753124,12365830824677759126,5421892014229995608,2789436151699957496,7459529496254192899,9109427326215812056,16730978514182817298,12877881463060065320,17125911781244166863,14065873054574912327,11671639384514894206,16899944062068658555,4927636955464900312,9204995351151684737,11368266498645286969,9782004744016186139,11778652703078469603,7792205131702946912,16322985584629741674,3405214566138492074,8514800951317569642,10401741303731143473,12987751681582386410,4058129050780125348,11312997560951889333,4095322454925534257,11772516581240578746,10554152165750284630,15574618542413215765,5219404840690264122,328929181904266424,1654084683778757229,13651450032810819770,14646265567820594981,2389902586178186243,17911673053792403602,3609743450794660277,5788553172553237769,2111403311401179716,9841710960397389581,9717074524759414602,7777679339387816401,301153449698621098,1730028477818859747,7262298517122450426,14441850693500248929,11309707929144432242,7293408634988102298,17187042115076508331,327453139190367994,8808105932693772442,8262337411862692772,192100563083485393,5318090536433393448,2451514225439677522,12069276680752297965,16272245833597496614,14284277291560784393,9810794468562363254,3471194766681222837,9829855119612890901,12380991970722004579,3883116324010698141,258553893424007845,12886367852844029812,18427437424114460852,17294505318226708120,11909296036575018811,6144925647248597995,10717000985050989862,13099350447406112001,9977760194605077235,17651613606029431530,18217359801445785930,4732959536870972081,7462481402018789530,6887782154587495722,15588276401043519238,491547355002251522,17703271326607744621,5032864999432992056,4256063919227696618,15937027356895987659,212047736567034825,2450436347289900828,9700457573235931286,8394915816424614278,4317137216179784086,8541604804240753066,14617546569548011526,15909168534220761201,5650135906688714546,13751309742226917310,9019216048229581655,2982893368741436057,6049854177065719109,6414557848627350023,5369318071111352063,13567227776597009702,13925229467139887688,11323053421162836315,17183235602480719993,7781925638609203309,15372837272562020922,2033817023337233366],"proof":[[2579195506720895627,5311911538263103591,7570731893321313954,15824123928876590023],[17681845796022350033,6064052257065568549,16006707981347501668,16561861649666917306],[11188344960254484244,5704206095717042527,6895166358373253086,16796740686109282745],[2679606107477198658,10350326239853949102,9476131519721485164,12930632378361763574],[4391185735448136923,13789812693278584717,9537606984873701400,7307437657790078704],[11957505274997572687,17691634819609469254,8589452472827014935,16495591055463216319],[6320282510492765591,8894482293292889900,2955868647673206339,14152850691709433794],[14987831999329384486,17561554627709501329,4900988622876924589,6193490079746635788],[4283254848452830723,8743807154568724585,3137819758750418114,11431116363484159816],[2478435269417687178,18395916837501278869,10931462338868884765,17526694693635030832],[5396896562751798518,8692335704085729328,15239125985544459600,8525011363881557417],[6776044844103454766,15631626757629346946,13183803587061627081,13320430894187256583],[11141511310493366335,3830210817480843750,16274384912074237224,11363777781457834939],[3567840596515679497,14154398217189760667,1266307445584227033,12154380241475704068],[5119174449410094368,6783218321954872037,4610628366495594084,16453898965506231093],[1684920909900349610,12438085064269544741,3746918374882824878,1200255243420519331],[15531624426577644058,13865094955186564174,8472382933617714768,9186383827036465161]]},"stage_2_query":{"leaf_elements":[11678538044165159923,2345858666570180028,5091199370996868060,9579307047534999342,18040439504057420201,5146519650861696989,2123484218828147555,14282906999876738933,10691443452599628951,14896747964783861136,16499596165344050760,11601558829066025009,9742081502262562799,8199644181235721124,7563775700601777513,9051253200139713533,10179249080598321057,6458034961196400444,12813653438704769948,4842698274241905361,7721322250667657189,17211026030951125672,14976551202696989794,9896946929770718586,1863791996439932995,4196225910482814131,18196346198628442902,17859466760917570771,2307037838824771736,7310636906537372071,7135712104025994860,15027766657564961647,9381695443347563124,14288430536347788290,5813216343894006548,5929997836430993260,6236461481705992164,16052895331420057276,13287749349501158781,12807364173239265457,1134697008386797633,15376663838691882698,6603727732785497890,17462873805393615051,14873066888448382698,2480042426183772155],"proof":[[909198546949433509,8449917003572818013,18043302838486179776,16078003648121555296],[9291259844167385294,1225175758887774153,543597108703393281,391829510480845011],[16521522828127323074,3270292928332569837,10558384754322006277,1113217440855168635],[5318475379631651339,8388968391927145846,1791494312359018986,11198353043053963757],[8283131133906156637,916569843153523402,17369183720417501324,7218311031508991580],[10464853923443259814,9360760650048493003,11587612151444519329,14168474980545152949],[66033719152905063,17316773485886737443,8875425499082061039,3678361235796161342],[11950526395947031029,12689729147056833517,2121596867176252897,4156159261946104891],[18057445886304362064,3536923852209802119,6124163268176866903,14054805865792996641],[8644216397838331913,2799314349413297779,13271624908335900969,16782951734207821792],[4099643135313609726,3791420719620345529,17554290911250490222,16155380827684579095],[3839616447011636404,7850225352517742483,15295362217688081094,8579536672465173494],[12102639373458668134,10834284024048987946,3521167560439110878,9398074210613979713],[16055267870968852393,8571493333304870983,10607320839730538540,13888867225816484288],[17871983624317112170,16269053627596628347,993923179409623349,12165717632428696271],[3733678106888686941,1708510073092627917,4801889306091087792,13847471618380368151],[11139769588175042309,3395418516901826134,16872320672903789189,13422806634613587681]]},"quotient_query":{"leaf_elements":[7442295976154806626,2611559690238283157,15767435566019963296,16393273458771612803,2824852322976387428,1405096071556304415,11121757392865454410,15247246450676757444,17420817875274155138,1955256647557459500,15775113275369659885,11921056586326617030,2508324852330895728,17037507626470942344,17732910664773550151,3253221223245199035],"proof":[[2733858955328553836,9663772279836799123,14373527307343788224,13068884264550747278],[16640102723972090236,8629222802515549042,820464771349492495,11033070438130548772],[17864157609402969043,5301058889404884409,12696589116806686668,3617571948699222944],[4710710720020715314,211927017688658123,9966515095946014048,2390717453012598523],[10699890072885435552,15207903039973387124,16817239755919195074,10859959461059295569],[803530583675183863,9709784447987438307,5272802248147930507,11105668425674740298],[2158219984475808494,5708400423944562304,16892609821293652757,12146134353977112855],[15842279274628474776,9746804084251158708,14587895059172385011,18292373192745126016],[7215367028266234943,2858980349478123893,1891154820928095574,1481001959961462662],[12910953735986037129,11752546765509417516,12263386713705549697,15141220445143689509],[6760387833683121107,8767817133085380411,7489849095465591912,6500805872691332096],[18437732969222123466,3923308142178583400,9279413409430363723,5850870632073376836],[10867414851140185130,1710838504847067966,16664568367416733766,11992457478236749285],[10174318550913132433,16607144356831541556,14324355393694181536,7198849015674088636],[13023304084802678313,3563077805662794313,6410947702588542990,1664223585000777012],[17485242766052239519,5516948418714018096,4195336187223058700,8635621805112940107],[11697277180110068323,12262495074403684463,10030620939404639532,17419393265831488427]]},"setup_query":{"leaf_elements":[262979957959103587,3495102630621471409,15017459562610749101,1134735020772234196,3948091541664158907,8382771399939534003,17216580162766727073,3585935785754060252,12141878811308275003,5801296906451162253,2583681310833961348,474499025134941359,14317950283555953732,15760882538509587255,9213467702568552551,12638341475209263244,15712997782014988066,6937939247602161652,3503543980054282466,998543551697444421,16726881908203301724,6964094977424616188,15696774275477965459,7897992569602835760,5096977959672397734,17101337331227044749,16878635044933916369,1292739571906043230,12696523711299937007,14556897402442972572,9150146653317500120,10294397982517392783,16706753425108098479,15370773292530205725,15747122427845849617,15000824811102969842,12390696747237580733,5849714177034179159,6332434176398240616,13184231159667866177,10550212310596886349,16650580667619010252,9370423124634501325,720863137412326239,15039835562215382719,18188576464110175048,13123042167089318712,14368186807179962013,12173715127555982793,9883898731197471953,14341375029323791911,15204803084604488858,4242921966268820022,6371933121312145460,10921179586948798721,717098839333704213,535205657430193590,9774947933632880304,13128668777397403716,1294834224949395530,12863536373728678377,1997477102529963313,1091878592622382847,8466023673967007523,6754763381016362688,6904709411727343542,467728301885849254,9273806830375438271,10916356065450439465,16128693515187191214,13205368369933575399,1959514589822009579,5982007082372921666,16208117056750106197,14902500869003690197,6206915878153631931,125443569726474253,7128163006561082420,3880842340988025175,708721677505644072,4485780164125362960,8521047576415504690,17581066512235521815,15466685120203469543,9608741917371621181,7290040848505333655,12811324859943254358,6884375705545376427,10839365875328867265,1483680948219755438,1536268831947446864,17015384288098442899,12930218942573242055,13550590379869750307,2075954056759812405,15091338705557598761,4208158251773861831,9299572249437564898,1489756939661626038,1275569331014261089,3371810916386214949,14098784890400296539,11421111962472185762,6619202287709948537,10866446869980040300,1106110902051431240,9444187116604233543,14327990278382791360,15528773275583136773,3305669876310455230,1408131840985450730,18056273432914727234,17481944309443323245,9519003158909461909,9788186493509796906,2721555679297838652,16433356758449875341,4527193393066820624,5412863056425727137,2824052781300333138,11904003687618898716,8163187788110493241,12404224655340568886,12733736870673557593,5183244552132545288,3350460579143404906,8715244670303762349,8780721440931199446,6851746278098333974,3074144016971341127,9337725170466259966,17575404148363926165,18012135304623423146,4700546680260004030,18344438043339526480,7265535491661038607,7509890139448626222,2151040508666256777,14848212127278155299,3458729592654912230,5017303278189832259,13632389315598449595,3495175933791503818,5737103872366446258,3657772704177146405,25429637227194004,7715293357822672619,533475919643243992,836740659210752958,2762416881954498421,91044173859279020,1286470352533135403,11986325662835312313,16394462835419266862,3654402870918733741,17542906040804215554],"proof":[[16670071227293001717,13129775592747645576,103216723752661022,948174458447532179],[6879404078080512182,5855469849404353641,4377661688302172887,4915960022491768799],[1443895163436359296,14689649011585752689,9131225792669103174,1775096659498442431],[10320851614022692380,9905901181614825101,4931510566624006116,16696697440174763993],[6024112295157812126,12851539785990086437,14063730896757458539,12233195505863291002],[17772757151247564759,17302817293349424812,17037262822270261883,13694457851152522738],[11916139557398746776,11314057172287459141,12666342191813665002,5807020906432494712],[11758931031978536372,14755550165446002992,12392887370332649747,2447565675108999775],[3625630277356893309,15340406873679774722,11657481985751661077,15239569516651482797],[16929734233014800111,17197202609141219465,12595313292440982537,11426955115739056593],[15886463827304826179,7220282384180998282,6973808016722649787,6762338958666559502],[4401802417558772962,14931149220414768921,4565680047149648006,18147726580225106989],[15717954292870499329,6287638434487305895,11379533899319949829,10246204865777408554],[9641432755381057012,13710693230394772589,7075312143364457696,6106142160030116169],[16085267451659014449,4823209204138401522,9255160922321727673,3196976051578252247],[3290374437558219455,17397892016632924015,4048917788441125437,6821011670244156541],[9581065928976518234,12135839458439982826,14501700026775568689,10922824617600197260]]},"fri_queries":[{"leaf_elements":[11823549636914374824,7491918146859758208,16586686821032742726,6335448259645586899,13682908825689574565,14927815284812733318,17847868222345953780,17605042595828081264,1282269193458687042,360733996371095073,15608853765114838332,5170780356299489356,6638201561258471503,9362667883747212925,1146459316010308006,11179357932475134895],"proof":[[6120745438394676558,15286084969326123896,2531553536122631017,6504491012709296519],[18432822676399468531,3799029724421128868,1228574658775761869,9141484091213397498],[10462866647949395186,7623500626041999419,3737596161517734166,5004299047020198132],[10221224696986500168,4769386906079579789,15351868226281089220,15193640771339123815],[2912633909092159380,11227349494680560986,12630325714769103585,17766434765917509913],[3820280244684884433,5098538554623895977,3798030362954167198,16166619103084302354],[20505969256607549,14345194654818398085,7478562914271281381,4456372680225367662],[1058192488959307291,442258605243109644,417567929372882711,2812985100781756789],[17901005449316066800,3916298886772499087,5990115463130760755,10723965859671892440],[16806381865210843838,9092955818752202110,2911797601831220502,14690358821897235138],[2245125512340086359,16972619172433485995,3455411412489625627,11022105947425305391],[17190715702881363864,6242136082075915178,5509776317099152141,1704067556957931118],[1321225676741995457,5002192773840269981,597926072037421651,1398311611851514421],[4013925711984337952,12808912816756715575,14647408150579817702,3065942723487455518]]},{"leaf_elements":[4049262100729908538,3935187033472283642,5270309812691334498,4985042609266238179,11485404248435047994,16208180689415797072,5061343719064057886,11339983471328064681,17570766754019945870,9765583020769641917,3644245923912316679,1498692281611324352,8686987745785374983,7971158437637761576,10679113320755741105,10481051798282384659],"proof":[[15631749076995484054,3553344456710459735,7421742273451806258,2042237254334282882],[2036779782527618093,13966084134609100666,11611358221339867553,9470399496876169293],[273829643933085619,12369558785999497464,17105047452352641663,17046675806256196517],[11422243370110772353,15451709318769779449,13167705769636769278,5864357901425057484],[16386189538804939050,5568015731773590328,17495247082745089341,12818633800557195025],[4228540543171723398,6267895280513407734,7566266445069576633,5965085936562258700],[15384140401201187858,2290899659911563813,2790238286641680948,6903254416010805522],[15606195605232295032,18398787106605052446,1335962986641479329,14794344881606774501],[9236683570534641674,5758675971195837455,16453425213803828715,14621584154216632583],[11237239552454366304,269214822760849939,15087353558995165612,15231969366643715357],[14386605697277095907,14780595627292032292,7787645265485481351,7681369631244592202]]},{"leaf_elements":[10681142856361768051,5763285544686688462,17922303100046549727,13881942863777165438,12460879276341506344,1428608784717542683,2533355449293258940,5504956128223564946,7634610772929124081,1291634977521649222,4138854525563578135,12289668900454509424,4594636287617050670,6020103689035891098,5610214380930163860,14087015141566213430],"proof":[[17776019136065870981,5398190741894563978,4343059535548423031,14858779632667459242],[16997701041579960607,12251135537605387906,14309507853960829631,15871393605144112772],[1658336005400072540,686911293274819801,12272911460376228948,9605227899656208570],[2145560629009403040,4387298020567774143,12631827655699649152,4264092131370498273],[10479074113489202071,15514844944939912218,8182623112382663194,7190423080471543698],[4528726745225685619,13057702528082512816,6742949411533993632,7349351254843873366],[38662865275608526,7842382810436525841,17126549131666992464,9456346611551948765],[2140196684590980130,4475900447607608036,10467238145322070967,6718390191579177126]]},{"leaf_elements":[9217331805652071815,13472445035917082407,12117132401498877140,1443965376263528600,1018053184655541835,7663392143732792868,71987206304764962,14917030049619046622,18286580461855709290,6332851288741980492,12529988947115912557,2703863996459798464,8630123906935104539,11283861952759073616,16049403345728633977,1559890544902435664],"proof":[[4566766409589095702,3338762789259481378,4990223560647947045,7317801719070235738],[15273202447917016939,900559778016401503,10564689258989046636,14989533643861499661],[7596819699823802138,3472590654914928900,3931543685228251426,18225811891099867316],[12831115212201283630,2021654149849164915,4866697979591898407,3963523862788363052],[4058304179733633736,18279683539181582970,17086072377035853914,1947585076045058930]]},{"leaf_elements":[17154985130103437025,11970188327225638528,10683314450985514809,12432856952525938526,3681463913109433617,1370543623621528820,18064695252079559213,14056191522051667869,12830714955889098383,5936734090336409171,11462448122055380279,14028662054105935114,9650789450882255604,14842665215275134854,16742160424854962953,15201628892638301449],"proof":[[2624410923785354201,12886709050758138890,5165919856831719521,8193115987328637285],[1459326226627952671,7768976976853534276,5200236173962639007,3670101928990175113]]},{"leaf_elements":[3103352029016043777,11936003578925779291,2481494059698405049,16760758113560209882,17943014902864064829,11760753107849584284,16263520714716793081,17159242401050750845],"proof":[]}]},{"witness_query":{"leaf_elements":[4976556937493371238,12114183631165513594,6813212175068321698,12167038440995032224,7151824239713395762,12261730120390381214,2277234390140910193,12086276246537985616,15257718023695275834,8210564926387274478,7553184535579775723,15521923999476438946,18446617318172250360,5541334748339322,13719411725311699880,825709873778342789,1891135289088453258,7037410164755139920,4360568367912081360,12687163877732912476,6586293134285964267,10561218972590018781,3674389086904858505,13441147645244909678,4498709546587617586,9618104503741600815,5625278441347855884,10770268589681882217,10647042308855670773,8540583441568821392,11606203072703070050,15492936736886538927,1539559675575158145,5475251966280942030,2162229174088150014,7380772316040782784,18070594277427253902,7655968956945688065,4824066386741247251,17612753094993759222,18388024621285488788,9270431846315116443,288427385417903224,8303604504864843631,7914374596429231852,6955594701944585114,16142722441273906021,1021667121691016837,10917579518330410189,1249761016418301237,15596809027867119485,15616379705875587905,1308296595786383309,6848511677705716612,4020315021628665536,15415245143602889801,12765391664066160313,6405287858999843740,16384937610168369105,13890752806104199399,3001070452479754545,568047742934586687,12527120048736824793,15051103145130918612,1650012493640066472,15125854585596544482,1647815074542466566,2450109504448256960,7841266406183250122,11421627218271559965,7733574779773174338,10297325389725429111,3963718444081661162,1492787454280834950,5967988168104659169,14224903364672263541,644877392867481349,12040064882455644181,18164282315021475682,12434676369864052257,8372344618475703798,7872463288302316237,8976446906676606427,16901786294691075647,3245113529236735396,10643640538036417767,12722888166754576683,15527839681667630259,8870801995961072018,8828085503667317334,16100947021811080153,1234769583092410734,703893291197190186,5258538488746408011,10059514758585860861,9012514347140854194,3546320870693714887,16788041232285557610,4682756210379324616,11471664490912290225,15020572402030207469,3048848571032914903,17568347756019676583,4010475495152380047,3632280932779572965,10766882984150354636,16030192640771872599,5399778178600686403,14496297302758826961,7269673313374806765,8301346208553709179,8385167253312556851,1891921238647057238,14219133931074622702,1328961772460974196,13705358890023761217,7111976781149525741,10795865446083387350,15293738585394131969,6217174681140328970,1683532743487295704,13615120495477724995,9664701812979863794,14375620013527021005,8249169696191687655,8513815563458785954,548882107065139655,16321925561210129613,5798250224599969140,2660698187043561308,2881017624266331128,4727319193951539775,7231798801686286208,3544795018202640681,10967626632414780267,16557736747562328371,5811651881625534264,16664375561960030113,13242051416416789503,2069945154222165477,1597193668165094151,5087852369768496949,3879020673669795716,12527958430791255941],"proof":[[6605659311877359180,14208369922195498722,16849899023418545039,10746043347685659535],[17976116701718351503,14287745815278227290,5909240153476304135,6665451198413518866],[5778194618185715917,7700021989873921867,11896821541175764151,10281647474237608303],[10236113181353114468,7314878701849631977,3904548610580116009,15952068858308698508],[16377454649546373410,12792310656974673925,12909012126617630966,13998757693682171622],[273341803226888938,6821401111955340283,13124811801826206557,1309067476858626318],[5366295793844697554,1221108787799288285,9965020871520482729,7933860037173986225],[18205919342664383340,5152849144482591067,3575001440626190127,13556638856178511910],[3088286831222101726,1695332158772760206,14549133311198302121,8466086058128373732],[15432864718461562399,7671107565622757729,10608697285386221867,483778859424999958],[49490975772863970,7025211784654013273,17946964629515897798,3430093016326819864],[14762180202834536912,16861492880545838559,457727454240931255,2297269705763971544],[2822339873732093868,8392808902048373525,10867033706154981544,15723169382541379038],[12362550512280214339,7301222296323467027,946909366182026066,14917149844365441035],[14764954617591504419,591994197062546129,4764821114693595378,2081082897634909172],[4660153396613228210,7319074183465722094,11910719470206088219,12234748405667649771],[7668237077592825004,5957116417149945187,16233895935611871800,17838538969050014477]]},"stage_2_query":{"leaf_elements":[16661906858535471482,18172484631773766071,12796640656093347942,13826617359339403087,4680392955321755878,15048140127122422390,8988248740402615240,297062803642051159,2461266859911622191,13589126034644221904,5503682054897347828,13685438933700998929,13426208894078418566,9973254822729962177,11398906185658426680,13615392992469429630,14229377356492144769,13137464322506202168,17046461167241431570,7228798934097809702,51799125308578068,2204264695524261818,16886099520073168189,7977005654279822988,9774183888282580781,11133408986773537479,14842162105136035578,15523148762034009469,16189813057034957226,9208000964815967268,16531108748813985105,16401109809702600365,14220085527427569859,10045207864101355627,15302957650348268552,4185687578411519750,9947458197200984438,8128221986911235973,64768105419450982,18019890260479769420,16887354792569464002,10719311051402358611,15351349484733343792,12067874273404376018,2200175574482848303,5088836613895092489],"proof":[[1692462150606569176,17697940623759809186,930553933769945892,4591245958753425498],[17071844127110835801,85309955765888460,15432822525845888991,6971004331675468951],[12005351461532896265,9995812137250205018,2789833522076923653,285136346361933062],[10970318091881789102,15711304186889077795,9244642901573683248,16398043431089231455],[7668371925875212660,12572825749572010963,1449442043678950235,14035609684539301953],[9400811981673687542,4792559138937744926,9659150620695921499,17363661715666504297],[2506669510315616426,16266381573640585768,14731197489106056390,13805530396440124432],[5330913905130589616,11908613105952236103,12479315272015234348,16390933366033186452],[16050288595665845792,8234114243171346582,3241648021084951625,17868608719407306296],[15365832921078595695,10242651527586021307,4457453476063335572,712289796071107578],[7082541767012059585,14107851165960800024,6419848842642590040,4566565230834940648],[14839576655594034027,6805886498303008281,9294070035447284069,2004115888946327298],[17614027846182425171,8821876891961750926,7260375258529498575,16099171483721881519],[15215503179028663333,615205142234189804,9395469026505961067,2526177543320111085],[8155062647038186858,13824706416672988014,2032929102959790223,16353717565863963140],[10362281280639356971,7426813909066805825,9183188488298461024,16457279526025997478],[4282750637154906697,11193865276873436640,16027026646227156219,7229065506905931669]]},"quotient_query":{"leaf_elements":[2593848975341962166,10168615631215969353,18024165063880839034,13549089761017637835,14440438248602169829,4717802653712389878,1856014579488777855,3404460662611559984,1070378736524189523,4125880724822507920,8891870918056606210,6234784808529538773,11361973231750980068,5453592678214634381,10588877471546152838,17795016631169218604],"proof":[[3521288585368323873,7248135039720682337,17362552060310142403,16118580381877278166],[10060759831950911879,1294656597319512743,8513202657098728932,5905826055184551902],[13191038651481474857,981959420219214589,6921261700402012311,8026425666373710484],[11074811342425170217,3201049830819116638,4485933474121502040,15760321084551788582],[4956135035390200341,8363345861314849919,6221774086886040755,1635676675501616104],[18186232570199145295,11067315186831819923,13261072278646802515,11830813052848333790],[15464959362607168806,18161204376853066652,7199827658332697012,9701816272452402612],[9858411769832161611,16596681307218593142,8730182868967453820,11682776672355856947],[14241437126511162159,13700345183272832145,3496318751314045136,13384606901037949774],[3596823829002037155,12593397371494681669,13913163179234170909,3541473134967205556],[5146969499340589384,324888038142904934,6165947098113709222,13707588492781895914],[11435396882073044366,17266078102818576025,7659918825946255592,17867222030380319246],[7903079704963845862,10571315490025203062,17522067644624491379,3809380910134193098],[1735825259002246803,5285745385255683211,16905735802687296776,6832045500081751702],[5300964561718551913,3688436530938695422,3672013875141401262,398755123019428852],[17144836120125926459,15201353506706726057,8965384436568764932,3461521867335494087],[412161255135997019,7426697135882287011,15407766786379248748,4603043754552020108]]},"setup_query":{"leaf_elements":[15680702558515855821,17020575508448798241,1110562860355351798,13265501237785293033,14092672433841230085,6499755170842699654,9375574064881789320,15060927935362749556,3200581311235213830,18362021132817609032,1936033247488402848,4310899639624348467,17234949170773349677,2548222238662965227,10240952473263292329,10178612632858324028,16059816273178518653,13577944174459613337,292662828864070019,13446664924428137726,16303168106486965773,6348940021684502574,12327994326511788372,2715315563602893056,6669920386013504233,15827631183806055621,8870184055248840618,13962486619596937087,17543304018893945568,12775935279039956924,16935084477606274172,13564576252238732470,11603656867570792156,17595744596808851401,9674234143678305773,7007523978528640284,14919176677630619817,15880063030721300495,4465312625057678333,5595843954669632583,10493175535264972377,15907001213286216713,13983009690120099592,18298961961069340698,13614800921197116672,1851892780528424429,15764862567381627164,4580257004605517343,15649965174845484547,3627141384439290772,2026524826928550860,1712728297417816451,8735011198182498864,15054610294252268505,14922272037961407649,8686770915977931245,6359395678552188402,295935300278850244,14380627851075931571,6890987678309617435,8328385127469148955,17129729798034982715,2853814441319233267,1075724146635653597,3944472195968537364,17429966706241946637,11119550085635393300,13719182689002923164,18081979280373348477,4153980787859224027,3873533966850002910,8482808908992269282,4952032371089867188,6132881430404357008,4910981567961545977,3318748389430442380,5559323350492101578,8379771268692957173,12847321302334591852,17279166994132934643,7503121315220689758,6743916186018447557,5641554425810417078,18125067822416627119,16687672259082230468,16155897785677846216,8203200013450168421,16988003382800675850,5377412620183592883,7773593155951077886,2194746542124799421,6283729502335455306,5608821808768367891,16936520227387554586,2327901213110989348,15353808416036193576,13628287423116452838,13511851595541115910,2677616553784728423,1177702893316096438,5859923733354526002,11836925795866572415,4705977564921150130,5472318091823158308,3848111291427754206,3843598653172014334,6256298095907097087,14486588536730649350,2609283318383431778,3156468995379794568,13613396950033855296,15083800136079950641,5777031307040785553,11937509383557884798,12104557582114186221,8418797730343102965,12347249660215046130,10881394814266894908,1623943894799182789,2847928694621625693,6839596417758899275,7343683323665331616,16081630307525790288,10961380489522058964,395644660958241394,8567785375254677726,10381631321622270760,4065101349523916929,14387295493699491956,17775645589024228720,7836293530334261204,13817827999019281200,11251489761653100707,15015474474345639621,11878262313783872216,2052448665260594129,1607487031494613879,7332111050942937315,17010783831876133310,6505002807569230630,311824991737238443,7197486288117084014,14994864015902568130,8061895624964137486,5599472117546264857,11907943176146411201,14841877275605023433,5031604138315432722,495685660101802297,9098100376968610275,73950952485688457,14510289323738793864,18267803318523449367,8094060651040291465,205267203358620754,12380599031752723555],"proof":[[802143828466313978,7324268641544728913,15793175035385712746,479852931839315000],[9473476425859564918,11468587874948738238,2623185703510971832,5198001625716536339],[8397883533542889397,14429853645139007110,12674757165318631508,3926462043500955769],[2089814718503106787,15400993974368723570,3816612620369836333,16465993455435171117],[14402120803119335256,7161997771161322755,627364215879266862,15019877419734932556],[15367693987884357781,9080170816785334084,13916183097506907437,14440614526320921885],[7001550409869520938,11473572809184013610,15590663950607056791,5934101668823998336],[16968394606331619163,15140162283447039859,8421841930089386618,6352100499609801141],[13816431605036463109,14910971038632784429,11534237477446024431,7661146641358040251],[9043331771567807481,16785554775080633952,10538942573422210600,11705811471477535428],[334541798408488131,1559533073422527041,6383227019679402809,3042320390437670422],[4589953317554325797,9909590559049532675,124198194741420960,12048647652657025031],[2086327863442687126,16649138097498246218,10260535607242132782,5104170916603274525],[17383828041651844833,2281693514439338593,10750892937003260468,15997750768080342934],[8879598469516946668,16416350209891696449,16637641980725237203,9684281082136478126],[7148597397650241926,1704733478978426128,1137154492670237907,9481674803390495620],[11103322097618702733,2127780295349214531,9279168850811705515,12312144320251496219]]},"fri_queries":[{"leaf_elements":[5007293853367888162,14931442032314220403,12453950756920262959,13152868861081826718,3761715019056928155,14573324686300636526,5399036253540036658,8734297364157609943,8293442744596402304,5678442684031031712,7351218900585514576,16769511114673097729,5717414024800734274,17902693539461844087,16699374846383795073,12398327176759545152],"proof":[[15058591670110847776,5022121037401441860,1300262439657964975,10966376400633764614],[772172942231002555,11579835860532823227,5816952061166698060,12212188848489787028],[10435599818724701941,14757004323525954553,1957709702689396944,9918080037093528329],[347023484815811255,1195950811600709943,15994747727999311435,17327453754802938381],[15404366384554046150,2489206864256158427,3329712341785253886,6075850703188412388],[6227270140422061221,18352351308761454341,10952403939479396264,11687532091759624473],[3511173506425622884,5507440692106288986,17384446010668912515,11905487269231296860],[1767351786158927932,13698155673592941518,4673546609143763935,15814947473380749729],[12927394104445135515,3101600064365353315,15504949443753904303,11874433696588952720],[9026155342685264471,11290520056333961924,14563692815874377336,12295145713590624305],[12673859192211394501,16771163903931146451,17690026192092667518,10422078678471562424],[7862377849054715433,14071879779472163367,7776909037993620490,7385994024884082094],[9716404334617796419,15150862758478461036,10116738246206876770,16159310944564628093],[9921314296445597352,12607643182737737336,924539792316356819,5516451865609828541]]},{"leaf_elements":[15868105094538412378,14333262671297101888,3685031584285313494,7393214865637220909,1386215278989721510,3847470187375163834,2019472383311847748,8743764681192654650,1523744741445440941,176016891254472901,1089730728474159967,2185364620479528477,16772789012163479367,11529803589663679856,14108423885930870328,13638449522630026036],"proof":[[18240801834644305866,16779318807742384722,4936132222645492926,17807578393421896766],[3311817396467792514,12991995826129886297,13282401513738907712,8688944363644328755],[15977842492548577475,10877940895530512957,7317672795289655678,12448941579341043150],[8454823788552506931,9481819869595642833,14085526183377663502,15706148161543220924],[6099666052257629870,13238011311407584119,4019516865173180527,12214631265345260140],[7059536166213387695,2119729031178436486,1015600677882371849,12733956396112472794],[13124621918398238031,14269397488431515309,9637075759243217281,1374692847079806106],[14380219811590412422,9850558203365847216,8103723932688736129,8558059708465338399],[13229281141534379196,7452617037223227285,7165584774954677330,11435236973695414597],[3419930858868890386,8376773629383943160,18099467646165415649,106843137514098629],[1035045995526660610,13644572249133237998,11620012939398060486,7212075288884837126]]},{"leaf_elements":[16138061115659449528,14376086909319363220,18226909344887391639,8034017787638277681,17534404338754477305,12092620957434788027,4503792096201724600,7212606255258841269,2911178129059473078,11895098696280298784,10524363032180376016,13913324450189060270,8159280239564722641,15887394323437412911,7595756227448553985,4142461163057118725],"proof":[[3896789791477639099,9612652590056761187,18178117667325243307,3048588340246530641],[4296243293865597473,4081930369799925010,4332945036412278916,1212786958610276727],[13400023227753589855,14199934427211525773,8099576547073857341,5202607207856989407],[18044574462078730935,7820425394316889645,11190855850097649249,3871374339757775025],[17440655271801898477,16788427887561402250,4703255539404539829,13109024628181737046],[15546076668546903780,2487767760765576264,9680070786425229558,4857489791950133344],[10687968705601249996,18083595299393111625,15633247368662652480,1216968033895479174],[12226308802717355526,10631940034649103891,18308154700960691799,11171411898695195914]]},{"leaf_elements":[18207050576054863925,3154941660543458647,5268717156954502128,9427722507446504274,9662944282244051109,3574384285127468250,3857009401822053031,669713249134480193,6319163699964819570,15827065830409691418,11556745883782074773,10457956556481883268,10172483704248151091,15846527610302064405,3741414667054275728,10857047333627110949],"proof":[[6156925175526582550,2080008407224307417,15479512628423699819,10957467831492747861],[12191078918878418998,13841524061515945460,14381708293353206820,14522642575501060555],[16610717167823960674,3486907729776690083,8106730628631496224,4361396367403325232],[11440096460337808210,4507072505727704764,358471103796110339,1530173096672055472],[8537000182364138753,9846641187754615169,5492652896324277680,353362856001838847]]},{"leaf_elements":[17422870121820784949,9279649763883458558,10392649704438649206,4275716394208445319,14923458923996159321,13441693995813286063,5538784996620329588,2291025495255618999,8987325732237904852,4674522562884064771,5646039796703103303,16954647411338512743,6043644490882419722,13918267068453747259,13542531026347326988,14851488079789523248],"proof":[[10485259444215048698,10568962927375070722,9662708587694725555,9951838211578437977],[7146818340987684729,13421072458407422161,12178806875058478953,82408401134322510]]},{"leaf_elements":[12636509829310569228,1221361967083405863,5202005031054329410,3979567876410885304,1779072914486373873,17530329254161706299,17673969969636411403,1918506755882003],"proof":[]}]},{"witness_query":{"leaf_elements":[13023088579440639709,3807800565592095489,3590531593212475093,2278065811520248939,6351895187498756978,15045506169403623452,14054825110851902728,11279879056831100728,8830288277700441621,12808043242438216176,15705823698780229000,17648821350342478193,13102498711844679943,16470628432382618847,18262305990928222226,697441205951610309,12193566014282252715,13140364857984172676,10949627380139370303,13901930106402094998,14312958679801438895,9710364550845368997,972724021619706310,13952784363808874722,3920233776612318823,17026764958470149992,2532728550167584500,11504248926395648726,4012044920100997475,12721884740253665801,14793850265621593540,3883693403291722168,10347987688137726384,4333231648479005981,6216667338429303008,11800148392081875036,16647049147596926967,17160951021060098685,13059029396806862200,5242051853293123064,3083894782240618192,1559584063729205086,4274855123148967802,2395521109447180510,9543252489130061619,14139142951817054863,13140321584554323798,4992817751044210281,2424594184367415616,6855173222091009140,17876064074925051570,13321290053561761214,1683887447384381037,10239721472861290611,6813427068522006354,11056067271843500287,11266034653056746805,18108862191759361710,6097636338355661402,2166331491257209488,12579843567684035636,9382295269854138918,12422389456877526632,8798018017739362383,18211536887738277808,5223742625778611246,4343194185632445691,2964885402289836885,15057590817927243349,16298548570823887432,9635332942165212418,10653265733001357564,45077252551576467,14781575327680457946,13686929098002362410,8632123815238482350,10526995669541894853,8997028575819857534,16344081162387844125,2707661502455933587,12595723322855164563,46412196554415730,4086696388072978562,12574001786199295502,14765931160475250630,5382108561915734873,2110729959802047095,1769937458044095816,15976818782445640364,16738026064492676056,8950189621798408154,5061463746131851135,18157556171162153049,7425806394023764465,9687487371971100403,5934778253695906092,10109111586881931837,17573067677843330974,5261716367515013185,575986188632457589,15644173079355322902,13252290140623478266,14626021960284901982,629679203104157731,2400005508753082084,2633211036695645474,17252128542741176034,745953642735516955,6838699316606820457,1524102223061960061,16850124888798927000,8465672644342515736,6851721641493311520,4248086897067387790,655367844692192159,10683073168933281790,11579277501632469356,5421563951815613335,7111999465733194281,2612264439890865565,11425137797295560525,8409401569740457726,5341934383935090695,7843143029970028504,5836969157696844797,5204054946130972774,6867594029129573523,10160761845848740768,10025625236974484241,6911118927677308758,172681763292338588,1503792518309164206,10993982811619853542,1754363643744816467,16191544045880505163,15823749595527422892,2919209051692539318,5143628285725916913,15588022386229366161,3161346832602341235,4040124884923690887,1012589016935498211,7078334196392205173,15124753136292965384],"proof":[[5901125408231620405,16306090689150787661,5524473054295627333,13641742834215579446],[3741665172451633551,11809459064259697705,18446246848196412304,5329067398011253250],[4482012118831452226,15135942315602635098,8900340675931698523,14676960467467709347],[14015430736843525820,1129842938419380232,7177576338223518578,16936521024492227804],[5508875437925727691,14004032770062775836,8992936728806302605,14290867511328399805],[10007054066385080655,7130737954217520631,9327259453675869119,6442176656851740546],[1244162163003591499,14476539596918778373,7234595912968884344,4861426653151426080],[11202971547301479517,8004996655023835710,8661885874531407055,771132373248708419],[5989578609843522104,12450515281751560527,10181834519882383788,17348206954969371467],[4484024719086295768,8922676464030482236,8743410621178279891,12702636013968411081],[17098280738606634921,15805836445396948818,13406557431349508696,404775272043951829],[17241979544984472270,4000514890736835937,720483814971296269,15648859663151666383],[14231971693888806074,3178334269010414284,1905018232115151135,17501115730252415726],[6719938547731947364,18381038806707769686,9999457766139969944,2332752895053699904],[13324208203217116714,17575570912700312000,1368410889916671713,14872706654074001604],[12907659714789773031,15362240958630089440,12818816904679508188,12812504910080655697],[14130200971923311735,6651683995243888503,15203163966109424273,9102607848739181089]]},"stage_2_query":{"leaf_elements":[16826031314423443848,6703353202935673536,17656798776097726920,14299905913932214549,6394019348955010828,15196724622028014195,7862580982935197072,6691312272140783466,6929868111621659309,2417925136619696995,6814808281034726039,17861839706663040399,2918468348644716906,225909065815398158,7280265067126960436,6344687685811184448,506189421056408951,3180797957351533840,3895667081628428238,6943021338303649407,12301333995768166886,5940619981195322808,4930306844420949277,694370245607846604,10184048653556237807,8565775908851317398,14059509867991540276,7110563122024248966,4408598054524705258,13888028534314862947,8078430167087288144,6556802587606175467,13860209833627310791,10205609105672492811,14903539642946535633,14757605814948470172,7976899076416409291,8821104543562719376,10379633551316497532,6283826143912290817,13282393005103969452,17255233739722115165,1421754897178006187,7820736361373042352,7665366676352646871,8250213230568276952],"proof":[[12165094690442710041,10794625091404569732,5918382621740309639,15536737974648662021],[12371399085736664244,16467712604663933022,12746624843035957337,3294921121615057033],[16848909188315503133,2523660179090354611,16550147755165230880,11017080345405343001],[11041325514386560908,16754348287230766237,14353171897361563185,6066934790282571823],[2571630625579284486,10388837774790316093,12497430363555718252,13385148643381551977],[16561655497606731796,1772253914247238612,6448106568388785573,3953971196463058693],[2679878158705231040,9489162546746561626,12711068124792208470,14427992411761165018],[12844878032559251558,16339769322675171290,10369479772627505743,11454704744830880088],[15485092015105020873,8467096861731133330,9685677901592179838,5135794716193471321],[1281608480445612401,13706740498582074462,5513937402272194910,5714887144918829247],[5862880760612225259,2238536704257300786,12103387814988140449,4011097737588277128],[3140022894041879985,16858762390962933773,367944229642092234,9964114929589952097],[9111438864505530703,16673330205854817355,18333040860204802052,1835341715495503047],[11328279007104600745,12217042107246640729,4759898674199107607,10781563880912094035],[10771258428247759912,6207304462114917612,41870003621969154,2858391199729644005],[1148290655613984112,15214728297738620607,10734551957386112850,7308553254202282142],[9682735025945753680,4317430438439789134,15965635585394694008,12418312636246604455]]},"quotient_query":{"leaf_elements":[9069903222768718022,8381733068056243127,8005629915967180981,6783883988119148851,2370406607938829705,17499815323084562590,5187058910203242930,5957950004811915076,14310963442287637337,13299004904892710426,2060254204860246206,8212348461645894272,6727573979343815533,1374712277945407548,1063537862488964616,12890513029123705062],"proof":[[18334689979053713723,5146651640753845966,5600997540742049143,2556129307990283272],[16947370403998789148,15696624532040334989,14928882313681623808,13057714810941493134],[9550258150197368477,13666166403165625044,10980338373657375240,18225870725701426766],[10634182526238413437,6704883294416464986,3751665465724418820,7420180680865404008],[7030591355081178060,12427111624105420599,8405120614362049138,5310931046999577547],[2967542510196659287,697843555061910969,9476137549893432807,9637811612747123182],[14946768091057631896,12890892465136901110,8833582152005027088,7590462216987804714],[4216989429988276686,5191420450845548282,16491432968616171046,2495228970126039009],[1388298953994724482,2129260873041007686,11820702000791865343,7923247520485354254],[6502047924803134411,439753675911636202,15789112991264494755,8057242081313706489],[17247432945867571446,10980170428562087221,12534609253093781427,8349715860017557546],[8487470116870715745,16676343875993368863,3232253314108105616,3999273500233893751],[6028724837435952919,2526456606767285576,6698403157988391497,10394355208793092229],[5484318687480365949,10984581825172238155,18201300519452814751,9283239254149470742],[15226034049601027732,4232716227345460870,13820715803405629182,10107406719247474810],[13387716190969228312,15527222198495219636,16020392206691203500,1285302555135810936],[14933014507590879893,9131645674222512813,3502417436312829601,618204606450531218]]},"setup_query":{"leaf_elements":[13768617751897926684,15391981727048071500,13679733515354520120,15998696605281641086,5813765855167798812,3721752694141599441,13844462123552742020,11094606962749389620,12536652060358326864,3466150636572504357,13818096215342834465,4408765749664937989,1685170104459506325,18404960564625220312,5954883624812921829,9214523429546339460,18095469078522717892,9305158401179497305,7134711854242409794,9032584708503659934,12417548429852480772,1679505245085352098,9847238259842536444,15364544469853522835,300644542778348115,17387201228323865955,4434440808943244161,11011192441091585617,1020564269850748249,5952413617690929625,3548944368180225593,17943705356319115694,495275504390909328,11288714499371806638,209516267864515553,3754868955881378354,13167183140447140775,7129159622906768326,9932547163974409518,15910942783962883439,9211508986687812680,14809275460423741232,5400264000553284474,8144908232162147433,7228571966706272825,14786627670144000616,13855086366700109674,16980372812806760262,13117176470588746438,6188417699895559759,12707929519957509177,4710120174217201585,15227161713748470586,9942696912529033998,14099228423077620155,15330665654240443288,12919655839371812915,15098770951816321077,16108441144058789220,520322320743199505,1760682131854688740,6515516654988742014,1478511230066030078,6449054698981247509,2279964346151661219,3215323063000185367,3446564298806583682,12838055955256998457,298003807924161407,6951277520916149844,1204020926639871344,18402435209339701124,6754345168134172506,11746177091663642364,150127002395810054,8790832497953275087,2260931413777369920,13499750827428946875,14209657292256178626,13727319184584459381,14235147240893149172,16137542596528991105,17426953558225186392,14747336277634660602,17215666736124778605,10017676960924372355,10954704968506315631,2759986323325290359,5599246851662232072,2741962426080464994,14150117573764839839,15914210839460830353,15467803891973881364,5818374311884714181,9854818988667108943,17524397007063839886,9381344127534939255,4452342281155769457,7659332806305810314,12460867038241254390,17475339811378867907,16482085002352122365,15807640632820145805,9917838431602093921,815256893673418953,12505082946509572211,17521767612967372521,13080153611947247210,3283634962756572229,17050338136314254651,4317649021073443989,617149015644765437,9009360838635136373,5593162308383428220,394618209272950574,11868514986357261562,13634182576281023292,12485932701744356975,12301262610524293344,3413576512003195194,8213286075262497101,363068796785182124,1345734533663555131,1628126660470373171,11507320664881211615,17659451035717804429,12516968364308140896,13866273677274938835,9275703392339530844,13626984005519395849,13265520024683768949,6756686392200256788,122634982637428005,2429156434754884823,10993215496821646230,2212441593952495510,13404141379154496255,9536475585193582637,12994210846699012362,14706559517733924559,2807464852588665814,4570529943647710130,15071576497862073437,16450124169994226133,814282172978714650,12449068219278895077,2535780313590528142,13793443646049499219,12252761856807685007,10698595148101163572,10447470575225936322,10485734308935841916,12669622466936392361,11358991495499768848,9264086829431797512,1828528361855369541],"proof":[[3956880986999280162,10789677061518564783,13387321232278606283,10894884222472004683],[12852182833709816536,7711486524554992151,6062689369477809231,12869661696912604019],[1834825467837628486,17211388615172665129,11839283393202156273,533332670822806058],[1452819378308558285,17784323185664432763,4607047611426925373,8345551648536700586],[1878791861101608670,8298613326494429482,17418039263907874958,7310503383201070033],[1050151842833301550,7201993914193583821,8844396985438475550,17692307489463947061],[18291721368638545695,17682898150744210483,13575409480983867619,15567612458787907143],[13993344915466858477,3837401104133918064,2528728733684125872,9679155885568115141],[4042583233381254444,10583874863851637935,6066692153214105045,1224572695598206518],[12419827802340866864,16286630653897489989,9248838865677640677,1488480930094462197],[8591237619977196607,8221633275605989206,5810769623651771928,10610438085801659962],[2428893474710275211,14833898644111600483,13001118106190510513,16809545684606292721],[436135230278422103,9318290871166546678,3680160148013266144,6714168942052935945],[7688686850712054612,12275239759410233671,11656101604890917057,471471945726519657],[9882813573913538428,10567048512103007113,14406417502411768368,6283531677579847767],[354094429307260434,8631341349596660270,6275513169725859541,17902804164686293460],[12788968215640770969,15395814659856495736,16441176413352232392,4988221887709223088]]},"fri_queries":[{"leaf_elements":[9161336549823394922,14243102839022177751,8968312488912074133,10518868997260561603,5543425354297383353,3305482690898319192,16622903823697457814,12480515977575842195,11952411224566855511,17890810924264063654,5593310264116181859,12796843040788095817,9021147023108861294,9742881863792113756,13052162551907301432,6786805733632580174],"proof":[[8153175370673687140,13228833735352531837,12058790191559150474,4821184121847693445],[460676726676572007,8676814449924706473,10292215631610302365,14831499937208977694],[15658848105476051279,16030285693377812486,11402268542596835219,18018731287627821506],[13401654253974772022,6238595717954794862,2217967241316338847,11293642369791063981],[7136919229899726433,11078076005340433518,12997759298475399459,4761970593487774677],[16707069477824856172,15504094004225191537,2047042707239972661,1018174048998878790],[16874658984581298993,2186437023257725849,9146505058437008998,7662113090266054188],[10326692057728999800,3527143108734292009,10517329002646492516,587039973556326303],[6162681307090372595,7909253937150046247,8482436027059016071,826762826092016141],[11070413660396565069,10249224033520832202,7574640369826110529,12903078884616403695],[10831147512579311657,3416365476993995939,4425484562730112694,5193093170837109638],[11287539737203131545,1080266398505953295,13248499173483336275,7548406248563806954],[6892457904690702673,11053070338194049502,9118753051417605884,6811676892061353505],[10975219819314666334,17698203983996991845,13996749007200269419,6421099739404742832]]},{"leaf_elements":[4312082877480869650,11272752484920959925,3240189159346454466,10717619756978871884,3757986327190018532,3506733865213624258,11804973814923726957,7174077296625596920,13407442588638707478,5588898750975241633,15028799511830905510,5764225165690271071,8433129529031680722,11671897823400774830,13108342322073435558,9433214035405583215],"proof":[[4661990587975993281,3378040375285290149,9465124560482232246,2315013861669522497],[6863228204894399327,15931476681237366483,10069786016018480210,1863094191476829842],[1584418960782736726,1469951648866116183,13586714496079909130,14458120300996132546],[15042068178030537325,188794003920575686,7396956640642698829,10820329292134803499],[17331215967548387317,7082695580443467128,16391677003262442439,2563479932340228451],[15188098217012483172,8186179090897269036,4644309110942918116,3203864127295322330],[8597666528823076369,14255330587757135333,9561761644956205214,5019237868937426769],[16533338278147047987,1027862687292354108,10373268933886359000,13262916987950355145],[15089602268567792366,17446269560628948695,18400999305136167304,18297731037809356332],[16065098293988506958,17524484150581651032,12972308983006261214,9495520717303859545],[6273137302147058655,16842727192735160116,17462047879407581663,3191456252220169878]]},{"leaf_elements":[4333429328354784394,680717972756858044,15367680478050117168,16310229718706035353,6021949985972324891,14913661585424279698,15415018207765463410,9726157046335452325,11621424488271563244,16318553612640002570,8997066453462721393,3485973479586467295,15441224597467645299,9281458719929057411,6226238789325652685,16969333396652682674],"proof":[[16101520446952207272,3489532482465327125,10347631153570249833,8453606937971759047],[1260534894206126387,9986761009805000306,17102548777201808882,4702892201953709394],[5552496888438225595,9681336734533321216,7585755970298198875,17096602246297459205],[9158983793329334597,17392288848955820310,5365227417688229721,998614609770752324],[4708423966147189339,6747560560363374581,1821640084446434294,11035894709795901505],[17230314050538594810,12261750609913441656,10691464593425113412,12805290156619890011],[9558721438959252966,7010417456835893796,2352170829879877676,2585899056629068380],[1458000923231966225,1743471728030505060,4692414711521089629,5142152751128367777]]},{"leaf_elements":[7691516913479140966,13856929822773790195,14875717737565790987,6418661987421330399,3280633077764394828,6740778596506181632,7414300664392678350,12634015338394628328,12657180914595384746,18237694686291043058,10806622129452335826,16815815136793850452,3226536848824278186,1133835079294934838,11164981794408053336,14611936916900707046],"proof":[[9610995583407218908,15511171818664429449,14003788909599898170,17726637212041528996],[11919947930445360014,11365665768941126722,863555499268606089,14420711537615254599],[13933564729259867901,13673352833041258566,8141320562084913430,5851380881315910250],[2195353225858735177,842536826032844030,16902275581778039547,11433057312073869980],[17460711705121116281,2182629749969665049,6271637777622513950,4232391251747557089]]},{"leaf_elements":[6936612079237842431,11743946443719028437,9298429153859121378,8553746452911923458,15772399614609647697,13466933403782328514,4970065767760877503,12310176572236117984,18097148361448356988,3858190117976054514,1702846687994709171,8723154666174990922,9415645219421558558,14391607058993615383,12332737418437117675,155213600342501210],"proof":[[1920022738755588950,6707752958205562427,11872404460933202966,6641833803093917258],[2639676831002333666,3798708971946924358,6256517588071388176,16700697641207873264]]},{"leaf_elements":[9390894857537177134,6775050549137632293,10212697533785944089,8397297093669755354,1622143564591104592,10285492781803425441,11612578074530589,9279746851921347959],"proof":[]}]},{"witness_query":{"leaf_elements":[15085207407647500040,4380601752308568587,10472570356392620699,7418775287370714949,11872849146529500808,13710462322479263438,11178588245192870700,10678402199549173681,17664458858436303481,5993673789062905386,17705368079986947402,780707603988213710,14413688839308219122,16335876881613499886,1883703480712001774,13131463116197944557,12230660531417432147,458685004436909246,2882768010680534277,3403871659049346800,3852566082297175533,4462471109931717067,8807533443484370182,12684468055494285427,13498780535877083310,13361962851696693120,11808360888562731445,12687835436861773807,11992215923195704082,17095104670134149782,7300751903637444609,5305542560753038263,1914675922511773062,3035236168544212851,628142978805935785,5541967384819391186,10185747744698618479,7231525279612954670,8099785689391498270,9319563294663672957,10443436498505644341,18425311978360855048,3965382412126134251,16714103593406614,9232747443432996898,217934536228825000,8990609067153698318,13906450550838377922,3070539571340827158,2771629292401264933,5237905361792504859,9742761901772081808,11572464220773635240,17590008868083232383,5749429834678220513,18177206566807597787,12612168795534877775,17433494442466051195,2195952417881517142,11986046489337319429,5036486000532148604,13273217277693833084,1970430797730865770,17665393191292474152,387011492655258596,16775172026465065677,793138798382288190,1341444895203955652,7381317052595637648,2596102794963045295,881817528380899403,15892086081633817830,16446357547664896323,5329000430082544084,17602275178530723054,10320304154302733788,10870951953314632461,9741659706095361822,5268371514666035636,4967692472345160467,940686352302634144,7507833028621450422,13904073282436720332,1707840141329551406,974131030005961794,11008547705590788974,2233572115602505617,6766041978689937734,4128433207613624,16998192872186128741,7339365361987747260,4814946012318634675,16027360853946647057,4553333813562194584,13387387491372914581,3711355241828409903,2655457384669207803,8242546565120779379,15649347654845071894,6883366247103314307,6632979005500255305,12352954579018869711,11173926015631111147,13141189232993168090,2889015903556762321,14621317263117712426,14651018626798576249,5350443605733965915,6504691360876722710,276249020529973404,1809667213594946571,4373124395611296101,17099210012916207474,478216121823112658,10291309648113675352,6486050508782621859,2443140049570827079,9480588548019761274,3908627578310640323,10719600665264137750,10248163656172482277,17531214670462919062,9760406380405715938,15550185741219342499,183109792310950496,3446025559864465179,3887032102296272051,14349186436705487623,5676983815756800176,10127083774648802686,11271123192422851204,7491027778353522558,4518046537338600623,17908916595402394374,1760540488495681028,11249346922848221348,17834808857932661144,42018410926475946,3665025691361897869,13151914786774268986,5594423201689732558,13995140532067496086,10636415074712132069,15276239734633588013],"proof":[[5866639376344002373,9170420856802725732,4310459670559183428,3309471276452748435],[16475083629047097502,7776780987255972008,10378517026500760107,10511622436715757272],[10337634366436171506,3882158598158947565,1190296392961476065,11178055540187644258],[14645103565890577625,4374755054013309601,12181590602671003718,16419545239973131341],[10784778155166239191,4968302309274525823,16227834294947181922,11033606711689837131],[3415773743332903403,12092663525329254706,8345703045199378562,13291234176549557190],[13299370366936224448,8520027386572595123,5191440816458130036,13729939707193896600],[14464042931891183953,952795581667956628,2092306058219530061,17747281509931701603],[1989847058633734617,13273050119966616431,11973439631486616534,16569451267788800829],[4779234021933660138,12776997158089047090,4893476066655563647,17936480656634173016],[3803778277234176413,7906509517302739173,4123210831148554405,18170959703207156681],[6764005446532770390,11765277871888038854,17441583506537569954,15495860530515005671],[8123551473254673208,5425083114766553835,12088983127878163803,3094836122646002480],[131037618696783944,11021894446617608942,3108813091764721732,13813396667052584451],[17224486936319432768,4012808329941046084,5808896982819658008,14316595921143908806],[15346668047248116441,2526726310755198274,3435646062692882897,12890230126974746074],[14592655159823375692,4886438218661956004,11773371646111906104,1577097193499964970]]},"stage_2_query":{"leaf_elements":[4092131156079890022,13154797958503726098,18317607811661675835,6098860545723965870,5030719607274821933,8067789990512531856,4213288257950321454,14074067188109460444,9173422211920937300,14067398622664150840,808407057295157762,5305583642283166808,1410043661077482673,11497015454346968785,2798709063053821464,8412249247576228108,8856770277944210329,16541567499914328424,2144263638179622561,7662457405736142563,5455407812096802279,4167367193785308459,14252508998073288622,10714292019428296658,3735280186941939572,6689707977880254736,5152858571981522611,12764672292585868501,6866233387517586163,9115545031338434192,9567411760536838061,12013301224667212424,4059194780652937555,4970812192016178395,1674331494729085811,15545194480575736814,11458425431219401811,3296111242963588980,14848912064810514004,821097033502623177,6998073355106676076,3745178175289667184,17675434420803109255,4791996264123891866,9179021833010083999,14129925557310586369],"proof":[[2110573253613382423,16672377412518871854,17488165995620792691,11595597304620636466],[7673427747385278756,3075359397846955747,16488982433311277623,8383299394053689106],[1472406698784762013,1055412917529190934,16763635851669469658,15644306009269444169],[12572025559432576660,1744816708949456647,4785980817548775855,3746833404755336747],[13652698530721906451,7560836501431109054,6744307188574652183,7020024588979499143],[10824301353149737579,6296483243904730662,10905316244055418878,7931031561341459684],[11445729263801600570,10134444706549484353,566857400116538081,15058765244809160978],[171232719841311425,4413695266420858280,5923373265977368168,13244602711946379479],[3035844212192150250,214535267984635448,5675546492033295998,14040517288455643304],[6457659121988116424,16324483982034110419,5424972990785802285,6415487829682690901],[148024633569417289,16600236100125251508,10296555674099957661,16537395641576181429],[2422150732794084432,913094016544534649,8285658787311399886,16177522044698677465],[12484523196125591449,12459953192581911465,9818012892282422080,18021509728021390670],[16890889665043432234,7686910210175725266,11506475150862188983,12099479540476397906],[16527242421544523961,2343682257090696879,4181098400110605841,12345797978788165037],[4551867285975537203,12482358037606313884,5878331143723473561,16657304009053288735],[6300385583840829135,3508707821927913265,5255373578022653255,11410137574386606844]]},"quotient_query":{"leaf_elements":[298266399495574122,7071760214915735093,3493382482146023364,9974348307015744433,3351303241742129579,14691422311191441001,3489344911143722602,4229823331203292808,8202362726343752513,6899765238629647716,13091934354284325844,16395516374020037415,13236610180102420343,16642499868116202601,6722539089519837999,17179392216696497905],"proof":[[6239979902282062515,1512326984220106557,12939233249988861687,17325106190203342689],[6869486042873887811,17223613518556304186,15051166969331663529,14273859051897596742],[6015942387475192690,13262089342239877407,12962710281537824301,13083413787853696845],[4815406905972931681,13586428268455718698,9944144492812594128,13140682879895221810],[12011837690569606746,6262675997759022468,2798910756154181423,8483500031511028491],[828876467873606384,7514624192758581698,16589065625724495307,5841594162043918054],[15904082621850588899,179366748666425059,4796077886475933686,13564839662489302927],[11609805698694758903,12695462681188273604,3189548650179429679,5137003151647791661],[2832050401746249941,14389690713762453746,15798234829792248277,2605326323544303133],[1492107896177187973,15507078448693894731,518327893612224316,10727222960939848651],[1827344038185885734,831605963950831868,4662069634967272699,8288470625934617973],[17317524821614843654,12761306509626477694,6836002544073427792,11474286298217843791],[14073880016817932153,14793232730616315308,6362888659043339308,3166195267964152617],[6378490680025243283,6872392033632720727,6938417612271335851,992334858182449518],[18237710150287508201,6434957956891426046,17484963899709329462,12666809802027787663],[12737530948504826777,16198149493584598394,13562122960665280839,12900254218326374689],[3678234868369141147,5283638782478520511,821763301433200291,12666613813678185860]]},"setup_query":{"leaf_elements":[16720716287308571277,17135728006836273588,8745390872302420089,3281050185494628846,16123320113120984762,1842032349365930089,11165821206209399384,3504155889994805086,3956843242896234675,10457904477074854288,2014889616140973222,1314652050561401041,918120677488911748,13523824711147485033,4785105389819767468,3331007787908103793,12535816013799955517,11243724869118520518,17937155443238924019,8168408040954492107,5906023993296049091,1551744773770362179,10002699126258531154,15405671212487132110,11467986147618920589,7252464641601482336,14080476468537695726,14542850599294690927,10920376024502509810,17594674825633456279,8126384042178850685,3529865933566985186,3793610109850926094,3196474262915399392,11124343342840314306,17264530320746989438,6393237204372090083,16187408329959188193,12701828931821375325,4077557086646766661,13101584726126458284,5175862925104170222,1684071563192236090,10609920157388782079,565634697788516137,11813702868308585331,13754510806973421022,6663056195487464100,4073748556935305250,17736977253103599757,3914219977770774314,9824635292005985293,15989103490671909009,17196722510168736329,8574845896988206402,4137556951987491178,14936579176901935176,1779433519720289934,8940568721927006549,7180667046487607372,5538135415794730619,9159344790378386942,7128238777965456005,725322271309519760,4592105856767747127,158973485879253382,6794260601425650840,6907857103458497213,5510845060248621404,3106469841036632467,15787107730037778965,6562538212225904280,847057003014201414,1661595871247455508,16659588377676270039,3160375988766571565,5809464749496691185,14484414392032570692,6180115587056367133,5272704407071260657,10252370744641470049,2267455072013308968,8300788769055474006,8533295453980190063,2992764547642251826,2532844099837140648,247835476644843717,11115120488319182917,13248715783188327399,11784430924838101909,11124307490951637969,5880306381799522740,4151018342785683230,3864045794702659663,8051315942345031811,9816485794274112015,13670652728067081490,15706713512665024863,16507522552937839260,14878436511792655264,3186390394138537628,17684926399876462908,1024553428363730738,4991183928189559260,12028471548913932670,83802013747979177,7794932455505315200,11941721222366227575,2948061364022655350,11273247872609728547,5989480219521278384,3303956482493095695,18276980637280917795,13959704809482354448,15553296520618569352,12789217445414608617,6638430692443385129,15956949289397263827,2193891070583677167,4275040726519216703,10095954586073142171,4310254056756415088,11434283989553828446,15099218680906521194,509011594952472592,8228171486449368213,9185611041671128030,16065078598966210666,7535389161302033542,6375672328322791239,11257901487515828344,11173187236459724831,13191503699527184247,5549266926228605103,8165383346301093371,5285590478793777842,14620767856810644460,5385218232366288336,15741204368282280393,18378397959037262331,6167867476376542833,4866421862315179279,15165853845357391400,1021890118500091226,12129638465914160091,3523084163457717174,4442501797939848832,15091769735263140206,1255428092413119153,17771726842417887020,13495803012842139911,13074537041113955174,15587025918879204763,15286610895778088998,8124073999008022176,2146961925322013086],"proof":[[14690022931376096566,17618489961541181438,6166783611474002418,17924746332789543490],[10689035076976734549,3106487381046420171,3805152203679037020,6741807937465218269],[17585717150436645584,12956975296534370169,11843387561666504579,7317774752856595622],[18262981354435926532,7480881826537551558,7766949260299748288,14587301876756790208],[13256653792023068822,8478881925951331753,7346187055148642119,17568889782577335467],[2171874744720365091,10193239910809737508,13337158065352333765,1708977385165848099],[15947555714583800370,8276311018782022685,1973889071599983703,1177116391690298957],[16974100647235180161,1183465250371902442,2736594411377513299,5656628606971178600],[16531394196989776980,6819536609413995742,5339963719734535811,1747967486275752552],[11036852298242601582,2642706938393281741,16949733209507553818,1609349345455626610],[16305626422984715078,11980802012561213963,13687249673548884944,12635597673405174592],[6192219721768320464,7637698733324000669,6901137480393713624,4008954105008300873],[573952451920485372,9424344434617535765,8562958777352571455,2983994628332385710],[196890332408581882,14483141499775954983,423474683191115903,6089172241593578589],[7315760703789728030,11098854478372754895,13853021607216137132,10213664874690697833],[1604331307223421191,13365993051588967226,8588985829317977614,3926111662093512656],[16354204956433885405,13679537276615897443,10956784370045293126,16160403238752695896]]},"fri_queries":[{"leaf_elements":[5757908217034536631,6407602436737497925,6813866755137612567,12070798723167188911,12139911351027365887,7880629540373021553,1689847044899406520,18056481654795135653,9850530429802517830,5599907553913724403,4081658762133422027,6607075640939223960,17051212653978442216,16701277894734587744,4332295101671218866,1866119293561534021],"proof":[[5991800668567636879,8028474577402301206,480432266205123900,6061296582428452495],[9722233426632506795,9258496670627786709,13331401022464051849,10205996670814196667],[3043565260504935589,711156637096503769,5119078264043720794,16737924528144850561],[3651134945015298545,3049728565187818611,17415317930300175733,1593595284027451497],[5545602506751970182,563393985244477761,3109778513118548021,11952434025490064982],[713489533757859661,1931326472593847395,12806298869437942991,8377273220312991535],[10782349601864150009,10711209423170087909,344271995078526745,14523694598459002787],[12880981404789403436,11065363141582447051,14367344779527154176,11374062235937392884],[5827071486067933425,9696883917613335463,50375762861635936,4927889542893602490],[3158748878540477853,2266748749199796576,1833153328908152032,16754364805679134883],[9999677086902422802,17711742339398222979,9606511752655746359,630251274131874064],[10793168821751184675,3276469622324403314,16975527531414042145,6168806466598292865],[16653975507766997525,5852361545422212783,4542679570729558458,6286968683788957014],[15841979698184688428,6766978167612976972,6988718529989188967,10317852718069604352]]},{"leaf_elements":[7560890320642799379,5282491535510400862,5607419881757671556,1056743511002487776,13031209178573055524,13046043282924824917,13209311551281339614,1188442632347682598,9904025963783583475,14935993784223313591,2125211627340640943,16048763317095153094,14811981190952270013,11533826076405441980,5807279657099577315,6813772626130102817],"proof":[[7544932755275595730,5934191363654471611,9115884986291044975,13705524697526574711],[9698361762622310002,17622515387405717669,17110445326963116414,9599761679150973913],[7199636412532922258,15411917663533212417,11212207975886899653,8646787544048090609],[171098317466231307,10568916696664986223,6666041837828837543,16235631627246663863],[14867872829633844197,11037763818514447309,4275213342081089538,11873068471049025973],[8047112873860042147,1050274196654381787,1785050719211015375,3117149026248434752],[6159448405895532093,11863354318478506795,12391274065309171505,18405737093660854816],[12219700182612444541,13950584779394766981,17930322635740990935,14779241096246822714],[3601417170926426764,10960416971598528667,4116057248854126,2729170038546637113],[15738158813134786993,3418264850276457326,10335140839884698714,2264973671078968161],[4620940820684181288,6218150265279905101,4394142517619279316,11376274407012839491]]},{"leaf_elements":[8187273316370381845,6274636056443065833,12880439808365422365,16006400694974114053,18320056354674113226,4231567453523860710,6303136900102456349,15651750716034976206,3609883868891689070,6939073280779749956,18202073006041505179,12285632918287518412,17473888345555238545,8477548977359695720,14621658602724473670,11652135781618788287],"proof":[[16664279303840169104,14827129264735349084,10155027218531957775,10729581600924687095],[9526844208305113431,15819402841593836477,9834515500620354232,17974545984378533175],[11070050278560580053,15148099944886559247,5869533189247176102,13857555819166731287],[17776768916682634229,2224689893349522310,11058527296202641201,16327117437585152092],[10163523725857345082,16911721419559452583,1167766712083652524,15821284496188217206],[65980789906675408,13227748254987345579,4087138736314592439,10840232629741442268],[18157687998917215258,16763460318887211847,934215623952467888,16511182297630279563],[13141057789689340553,2448709708255569924,10951846470074346402,15630920576161203827]]},{"leaf_elements":[14552837601400842674,8730714980944737494,5143599796707751273,10636423116031114322,7987224282911666773,275606989635124112,6604149741215321740,11518504909737533812,5223143569610877967,11462945895754909507,4424158563648772850,2129988949422037248,11002984258986389372,10319137814347061994,15920264736719785322,16560780324001621620],"proof":[[7070694536920731315,6974829325859641846,4575431838830410010,15339981279063857093],[1206535875783586554,87698552582489949,16366783604413041387,139321902172391713],[13584073186140220454,2815326856160201506,13520802899477509320,11367850166795314918],[18105499576403946718,4385796141796696880,14788005547233371370,11971365134580477349],[18094368428717041921,10947070686492808250,14391504912823517373,16135841269932707575]]},{"leaf_elements":[10436843727865497361,17846276555127019869,5922784516808728109,6563996082027773457,584050490551381099,15548329999239472536,7506827572629213845,9991002189841428580,5484499667580979130,8499433419154611987,17438216066036198705,4590668035734578888,884955262166708534,7181494639364029331,10730017351734604780,8530100638143981646],"proof":[[6389906513795140626,18102858087891980784,3468257514373005665,7876526185786639359],[3419541161667130895,17696456370165664112,6168864541569884414,1311020060133671248]]},{"leaf_elements":[13912788208633012260,16592364955197622110,12930883254427910878,5599575569218380943,5682660096836901399,4069773254031359724,17686759155637027087,11829746095036037227],"proof":[]}]},{"witness_query":{"leaf_elements":[17684262130117103088,16542227305789435264,18021666854068017471,11456039304340045350,8746522205596036559,1527169078941544335,6822297549991722004,10614959717856116668,11843345016184969645,14649226374553417793,11552540434659972042,14781829733177463233,1310496211872762048,12843899339171962163,14982291583808420901,15539644461416091348,9681528576289036026,9782141692671327259,6863525273893585529,1631452012657559101,17545476772776429973,7309512421000227619,3282272016241600910,8108682326664961326,17225286116194100318,16288945737292765392,7695701788974663233,14354951727573121766,567531718976666481,17737610211657028847,17127916610519149901,17358964820833184143,683188627810201560,2818189779557229202,2684652479768688854,14158121546540925922,10144688191860178408,10560575920897104565,10554005966259065508,1668270441635495259,8946112106747448736,9731078546900768817,474322352853603049,13677128007052096172,9326709639309097206,7789006378491595855,12333657807481847670,10596899647153145871,11384834601222435490,1974897155082186199,17595944094231365385,13666631509484652021,17608142009443470893,3609778315865816086,4369698425454055982,10112121219278954349,2938211151611149936,6461567902671937721,4540280276731689604,16747654607523658381,12509638119726481999,365255752406277195,10803051863752953355,1226671899362806946,14086465758366307589,12336499108140831974,17237500970490938677,9007296649084526939,17638279012269402114,2818392118990006174,4956105423987851757,3437704693758755583,12554029713110469169,6494406728447621562,475144521298781899,2522542931622308884,17562635136552108477,10830146552118884679,14189659558798207176,4552030351617431334,13970930579703843974,13125757358370396101,4833336050156133862,2175136472226379043,18283755012210491130,10824489451921706541,5013273887748494894,17456786240383475382,701733280100626535,6652582154154402388,12322490184306491536,480840220595285119,367602302886320994,6743263461362525225,14838005744896102494,10843347309772000206,2572620913069238361,8553234189030606652,704741363235514584,10222943372507080962,15849962709026950,16921849460711363199,6212652430830760157,18261957703088324334,4622647107261873954,2828260939543752999,14573075022835709945,3122756046558616573,2370501652506186121,2289813335059757929,14395631768793599062,8684919577425106327,16439120241046442845,6802861693420218262,12796828057143251395,8093119284383016867,7001288103163786742,5734071396275143815,1374245052192611207,6674836007954558840,11890875535019780872,8627994164420243832,6216421820119132312,382851274416758323,8356103986684133702,18275149654659538719,492394687151272577,279342544041348298,8145974770979003401,2753505601524872175,16234131711609301298,16071413711827428370,665012838706845912,8594069562688417582,3634985988271547042,3264890563143230239,5112077888093194856,13084396250740366400,7706747107636770399,4833091837826484614,4026983266260665999,7188529623890140623,4900214576958334769,9889058536987312226],"proof":[[1328899702048603818,17892777711457724833,7617875479105476438,9099692041609381799],[15021896916347092490,11660124127235887015,15231647452161449640,15399173920741927633],[8633060803682555727,4848819516643243779,1505957576944449605,17096067209294047372],[17086487862261773746,12642251446562385784,10362999384360633835,14622099900505514519],[3745440716495459679,15669083105797399923,6821491735506616056,9668681402619847600],[14546844710321264407,5389899681519140020,8766099737332664787,700440187345955628],[7769610338483570724,2395565294431188112,1821858334462526716,7868899132682918522],[2756063873840854207,11011367202555815850,1477927247616758491,13898741320447436786],[14448325218850454673,15030480988812106112,3140589063515774662,10762754656544138327],[11643809531008330226,12076642625730782376,16096028718123446302,16338721701605133690],[2494113429697438831,16930860662488084273,17747150596892428388,1004797512128309103],[7363280989626235516,12750383094928786700,5251726344800305384,17777393699067124528],[1632347621257281874,18223892393158898140,1220051784573033425,2994410525195176434],[3267788898445257600,3572457938085949913,2474745628933508158,7090800016342009163],[8900158205464371207,7087611967484414154,500149392547462152,6631168637209843780],[1283360576568911999,9024752693137239367,11803197830612791194,14692967384855259076],[8193979718528806600,8375224386207577318,1516291403550624483,7080112769819207072]]},"stage_2_query":{"leaf_elements":[16598966640953331797,10615180930977784221,14793035595011464896,16553064311714665399,13587944442919707126,18103155887478350942,6039867512271360316,3757361172772416365,13404464057110111757,664138187520374366,4600889549488514075,14428421473099830563,11143568195014180525,12244144829003067960,10853260910661681544,2577942036302026021,4777409709083251971,8461941303894978938,5104481909879684149,10481648750909555526,17205903193676262523,10898004792348101624,15895210701594828448,14353207017684172759,9293624831884131210,11272316963475491009,7039761893602156689,10809261166735195740,4305579444173477213,9436118542443266974,10335127590914234124,17940407321263368055,15037980090731791778,4374615709303980904,8925048902820976379,16187542270754182428,9248955647802050278,10434523663530145090,7648192611709388367,12340977279876908614,275882233025521596,6871623541601656397,10210927386775590061,13590610230045438336,6617151385002246105,5277551285331012830],"proof":[[2004604058450501544,4462965290753841102,6573011797338834834,9854327717557842983],[1475371924663430519,17593703792192393244,9848770361643783374,11679592908210715040],[12671112571536828743,5077082553822588103,5976981404407008623,5069346694657730874],[18083085416795807727,15736510416371226503,5545007853453185826,12927753195803424392],[10603717840294611268,1929898127130279102,2744854410520277068,8685049899503291704],[4837034330034639114,7904491663809605606,3026219253796571775,7255816862665503456],[7472356260793147788,15873407602924229132,12054642318762126968,3147003037538359151],[13372013542279467801,13726347090573543212,6516475721393507578,1266667477426934527],[1785136638880124598,15029313345421909708,5857716994128948395,9404940870534047644],[6305621726285737973,7314221249085949138,16395650085586932508,13876436900543288971],[5629083324903663842,16745667633607369442,12666694182480083820,9598973508808041075],[3878456402072733940,3112305882596825159,5995575137188680805,1789645276346293271],[6220058379399917915,10716679217544849769,106533355776823446,15262706620186873578],[8296033896508869004,16887117958116281563,15637231510650632538,9352721149762684440],[6557665963283322451,350110529628495976,8452763338186057316,16119657677614989426],[6735894668517342114,2254395315240689940,15407949256100964303,4355345966601743125],[2156372198160320375,10758004586682519094,11754802890427400344,1564423923851060793]]},"quotient_query":{"leaf_elements":[484006850684924804,10126934401361990952,8121706223077943267,13890147087484752618,1164481024420871563,16716836516007634498,2611066822681674629,9071627779626229980,6023588400939756759,6812755645624361926,8875362898872092603,125246100067948442,624986963117419913,2788267840772113426,5437856218929217333,8288299439349394405],"proof":[[16354531791421093428,17006594417696324715,8841472189140915498,4795625404294834687],[12479204100136377999,9724512508097540639,10847930383476531309,8674680531701239525],[8099767000315593870,15418390906744332035,12499932781188024101,7121607268898741071],[6243800867869779574,16924481606006636121,14660845101922894426,17038644583480757730],[9828336346475115421,17505896690218868525,591132264769446399,272745099455880697],[163805498087484338,5566184685022673476,621741804742930424,7998559966278350938],[8224193481139457693,17951796216859189045,2652661095268777986,448705601755720738],[13712557007069265858,1490511997757845320,11993283123787435617,15581353784731774218],[16062799463758904941,17037849284403512206,1728129360707837599,6915568769128678039],[13576201408754072953,10611292049776123923,8013967321957008713,8195692572834643447],[1214659298180173374,4992766162249061103,2406845464776354921,479415037799379505],[15736536041120680604,18403057682011811929,11893885688080143720,15991878608746580476],[9276483481347019859,18404371161050680688,13939443580621462002,13269301492240544920],[11298587206569397891,10721075503959382136,9106751758249278992,8568865665548150866],[12783539803041952739,13323927941613774881,5130371623472432486,3951196972192392486],[8088998488997634110,13089346029432649081,8293343074735624269,7646789556839383591],[6781824673145116271,11884988964241063795,2786037544787052384,18285016945696491669]]},"setup_query":{"leaf_elements":[11359573369769400212,12159139628371702149,3183411653219151810,4391977441170515346,12698513070208219782,7028778929278603769,8217336492232980240,7323044357366156547,9072513160568574600,4883517539106775672,7406779653253330391,9556918624018301316,16844125873098635747,7527637551422565389,17585064303690330963,1188077727734950842,5543414866803609833,17049604924475623212,428810667831524280,14772360029795933707,13387659636613328492,5521326412192748525,17497625888644359042,14189216881358722840,3693498001032453157,1215667307926844108,11983948083986668173,8728890416112510007,845975178092469533,541586454443084794,5733853370956361954,907955891651192461,9050062997864439752,3101184573782935881,14144173618387162142,7553692565742427123,8962359019819975912,17310377129357569364,4325822727768303506,3557219763681755163,2437466429601768798,15265343964333234528,12280399626071090170,10777227391149519155,3102189034775465673,431111946756317272,8901427977168741599,6431191554564547744,3432843929768189005,1870720499583139507,6549174984365939392,6577322592809004201,7325497740289989094,5798746771125714962,13832255228943207105,13431279495052579287,16053042942616843518,15532417326145026830,13427691927967152357,10176309071865470749,13428982406588752165,7603596572446538407,16307099428094968986,4343305060628469466,6490293966287420289,15510781248014394652,3803906464255858822,3659031001988591088,3815239176865661775,1123465629019511259,17046918932645765546,7322575961306913556,17177827742382272556,9719607219926431378,2416322863920573315,1087426308595845752,14121770316734302577,15680981366658858819,5201526744893936624,4246180015329652483,3910972246568000317,9741339217360823775,13659754698616198290,6909699777303305654,15212791427682309490,16010659787999604378,4403714734577679471,5963044096268571529,14639976958747278991,8816960347233735158,16669650505043254012,6616052718105746769,11530273168334382315,9620944300850231143,5012762787256595484,14511356146353887255,16617625463292796945,6178565413587548049,13973346096150193654,14639151826302360016,2750303838600391371,13060868850329239510,199717192614692651,10198359942168007179,6774545104250963640,6895008348527931908,1363376741233537764,7394918127788607305,12670748207260207119,2213626958325570670,8513701033040358356,16817579514403136736,9792250926060996168,16235060109941536412,12205593651433539514,9105757645232119675,16326587429590028247,4335198169962676859,8087769360525521715,11225650837249944358,5416572451774018222,6435245008147764893,438522792793493565,5008439492986404904,3772712641960725043,10066106498425457880,2323803548643588946,5651411041500180146,13233476968387153275,171049207255586971,15617333275622012322,5887941390795161090,8149458693136677366,983511255170963086,13312263931352601832,14126051375617571210,2187561814256487163,565852365784238822,17791157509018065370,9942046257070862639,17310887102326230095,14334252287383932727,8154389175256074371,17132858871339068478,10000202633539290396,6038015345444958517,16320039089887695530,15771386584185120381,4007081486330994361,16810712858446889986,15244395105740327664,7094535815982440953,15942095494504627955,15121642361725276437,6352628011356689111,14371920966817443082],"proof":[[16185095927537124677,16355338737715706342,7624722699249452589,11461452951242129860],[2749778898030783340,4724501822224063342,14360757901595157537,9769556489270025684],[13041612969352940933,2023220814410755175,17380572429062318239,3421491960375636253],[3186493540729528422,4046425984591854498,5138129120255781807,16438921934590082305],[8793575117623782189,13190668997837979641,3789494685335194324,14865747238229248209],[15262661656288361235,13310355153225807918,13235023432813978428,3822670367773564409],[16035899087025324471,6225634377418343603,4202756417766934923,5848172058907155108],[8673145813155857769,17561083858021746444,14680404870589394107,12433472127037527489],[17108635728074574213,6820282375461673956,14064370702204450746,16749215970889120868],[10161819952345951446,16975374965039572498,4389797578614618528,14934789387346925252],[4378890214990725275,18399763936690536244,14756811755409579985,14569515797423491803],[17992166064273438013,4586897593204042288,16414635682896665505,11291390792803949603],[691552562833073652,12957791172788388973,576634594773181886,2346912220049927667],[12594269998139015092,10841496220172396051,18073044509528242310,16122212572737929123],[15142349855116345949,280730183298362707,14529934662846043094,13771582299387956187],[1118519530963883209,10848321333738772205,5330177198722116980,7353880659786792866],[6927789725927369932,16315812677162299352,8615590175857271490,8798523207874952519]]},"fri_queries":[{"leaf_elements":[10073062183392410763,12411929472260289586,4492216343822664863,3740703449368874523,12178173778155198535,3011376177264746457,3939687263373295039,6965678158151404467,10097731732417804941,9529757290916979219,7305052054075409724,6630006226182652710,3138825460605340168,2135758494841957727,17347897728037212662,12605269278243971226],"proof":[[15075829532733155875,8454694958534567155,2451349035140556714,16215017352666145575],[2858450689209449741,599834321296568044,15249119904007348559,8857772095177379326],[3411215295062687318,10648912928633359084,4695308706347088289,7952926904700350264],[4782060996134829362,6504148299253353416,5180654869211978276,10857927573832609399],[2199369625635545965,4311748751665997129,13060863995040948772,12026069132794767130],[15967386082294884229,3696386237199869796,17886664294547091554,10673096836060166028],[4579117367823475679,10680273911303287769,12718572184087922903,17645379946165081706],[15573658479076274161,17262464774113324309,10803765859425266380,7389989258786596829],[12902049863438123889,16759074024258703605,383492332539736671,4684562677949976024],[18143433252059123096,12806436505345711306,5946923105866647003,2931171953103045433],[2140251274554779736,5687717197685406411,7287301503586583745,1134094300569049975],[17784077093144787720,11162273194833986061,11651746052824811064,6350164312171946776],[4823775090622523102,17377176146413885058,14886167961571781759,10386264933094300949],[14128138712872929702,1370874517542577445,17278172058011345670,7215150699576622869]]},{"leaf_elements":[2447768983596714003,6516419794110995637,4561747190292922844,10076853039165984963,9839636473017456514,9334725714640572291,15156000524903301218,8356424778076658472,10779834821615862633,16788264327415062769,17573074334912817972,14619623197756241449,15861266021460722267,2542121905447866060,15719617581469735484,3142117629167998922],"proof":[[6780466765561504764,12616794643534639113,6000244133911328590,7758216157423518014],[13233713715941010132,3707280624879009649,5557096945557119646,10995351853275175969],[7356361454971091867,101392925724113135,55778939718705633,16599717441113286686],[3902417389714432937,10641601009105883713,13678287246622666842,4748186423466694596],[17305735542279758617,17080602016516391415,13286256727452217350,5222935271165169348],[4557433770098866784,6545704170161282421,16989743738733732461,1155189611072362105],[16397272137290321845,11685594350306096833,14529879433126746865,1292697945788992050],[5186942931567099826,4599975666203028179,6566077281447765971,5800723070628123965],[14594112611091397759,5814674367178345660,773199285690431314,6742922965481819112],[4504277996475953278,5048606525951268932,6329136227013387494,2728520336002152165],[12455615997980745569,6899641713496781723,3754459214410385641,5180782410589882794]]},{"leaf_elements":[941182622134846593,13930856813393093996,12112757357795021199,6643968143573891486,15424260680675758180,8805751189467587780,12388316652922833442,399744757453170951,5725678776905681912,9256273803674338931,8532562026014181981,11493505275209532263,1303166542726072604,17326342884481885411,1809032005816218110,12404361235548455502],"proof":[[4961364155084696276,10909449487691458631,13203117553411167617,12398759336561491004],[13715663980165708133,4362761105440599708,14467539751616030470,10301707683235358261],[7615102269834253018,14296076238644628473,13586364955246395383,9384835216521845390],[6228501792705678438,18013028791402913162,11674240931639286426,15018593203680623884],[14770106134700607638,16126515452155942636,7559838243912548530,10796864360500609036],[18405569483185494313,13859603584169062633,5289141811568643747,4668021453467978139],[4360551918683084081,5932106819593999164,3453896156327546243,13720849880176096220],[653609557330627868,14023145008717793735,9829013459427154980,4354604016037302551]]},{"leaf_elements":[9975774928750495014,4719283506549127304,16149990249301509513,16488764384425549188,6485092266366657349,4276057663906675853,5825468105080446609,17676041632193435718,13041953904745706637,4646372329781747858,10246269581005127406,15074921782449616936,9202989682189300369,12992045744008285405,11591184637110260338,7542931485034124799],"proof":[[8495827516866632274,17509404941724863037,9917999480240734271,6543745592243985901],[9269842283107391727,4679263153227430748,10603297093024940395,9501781533108837898],[13849401993678120605,91451868416688005,9989412207310737655,16669986068946590457],[14217058136595866010,6147447817722482822,17513986941361204491,12360345635939740895],[9177491066822616147,5431401594819627928,1355274528698398268,6660308507820893921]]},{"leaf_elements":[9546429611733237515,1140136910027212754,14343156404839747194,703485673038560043,8941717885765512809,6005222077910030650,10120684140967795619,15074687717830685338,1277873869438304195,5877538223715750234,12170856735981246404,10120348378771498645,13471658678519707183,17206871714988631181,16417718761255008528,7814049447191432369],"proof":[[8363529080180658138,6254582814694413754,9462479987058175578,1198865157323622910],[6872717206768702692,11989125647797140964,2137644504125081380,9069676152651109583]]},{"leaf_elements":[10632746266096061438,6757646590349987949,13549814758625843258,704655662152719460,11622797146708305149,15759578015746123756,4397608871267503275,12640380755777952922],"proof":[]}]},{"witness_query":{"leaf_elements":[10757269130004546132,3495180886104443038,12750504796826493397,660319683696931349,8315676331414153520,1489598406377287154,314617015231060333,12247535784525473587,16011863826766342297,16403899916766486919,1110050677295482909,5957452990309928591,2953640134874526325,16494171024072897016,9621144018578099630,5803343900820719946,1544771753107404019,6071751859479867010,17919132765614996207,9438328607163625693,16139518459603417277,14568506472883864927,13507294073911239797,17434901130761014646,1104685042524798870,11537240777075853163,10153033015505215717,5667636439757178750,12406777481015175113,16209795234095345703,9229046361677727836,16132836008041424155,10940920355712637964,17863505785709276147,1153875167007791546,15605179259798938548,6607762630660233857,4257139658685082199,14450130835872198673,14956019965038989238,6563443008001339683,1008014692487699235,6911407555104629536,14476324339031091922,15484745991307000260,16219231472684317342,13013429059744149811,9250992068827169955,2222530391168930001,12809936512095335213,10498289321815858806,16096085797794184899,4955848212530686503,17236762590544690034,6589239234432828572,5363803243046451298,6584511907308464148,7537387715280740071,8003630267525841075,16077861578604818731,5822900613865307191,191615281183313954,1772655937887102993,8819207798325151449,323353866639444739,11439897703251906351,14410920239137026629,12198385907186437531,12840566851137316102,1843516137951016809,2467748049454659194,8551655622980430648,16114853725686424423,6159761803312286527,9249713547226559107,11887368560951410032,5570948198451276425,16914337237901840656,5475633660286039986,15852154399952515282,14763302438621156014,15455890102099795173,13400169589903079423,908603215909010409,3836638695370811516,6811124009880247361,10044554376631158922,16605793056118548317,11314322571341299795,806788644370035560,12377997511985692898,13050462327251331773,5216802975042347894,16901294723338585992,15042536336488310926,5805594238418107045,13868479268165628118,6221383121734822263,17058162230883913912,1516170980393762154,16323652461596240999,146754845206995711,6535702901271477855,8345832367126224332,4409358566023308433,12583818005541801118,3543816071674666106,45249709650098711,12959475440389380775,17497297344216340977,12538578757657357593,14015339149283971147,18209329169384117231,10122977226594919829,15402034328693599002,9111375345600725311,2098802684114748998,14069027892303253134,11870340688547563313,7497188042440885201,5395005683462057762,12691257745520832994,8770239483618853832,12102813302983440618,15759534129010848903,49611453826345225,15037013274494271737,14414099939345223326,9008036919570904621,14914228918713910382,16777392794988536838,4770769706170001979,10169265798181509829,13521395107254366849,2791402227402507043,16218004301164687840,16264182563106597891,1908148164169276310,2895380000561553300,10991512120355135471,1583553571402385141,2633233718293389004,14876975455016034556,15362459420667416879],"proof":[[14999221864411662719,10664930449366724757,2602912556773404726,18228725569266197894],[5799345694254282174,5808389509257155706,17749086026372961067,4723841542314963929],[4703581952485726952,13602015945466077667,2713134455930206701,12221766438679275362],[7968354983385554956,2373446149750934080,4157874456821262800,15082410292904692972],[17667323542309618111,1185915387550174724,14898480294454714021,13412262793956146415],[14420176471498519005,12743383191540189792,2275900006617437984,13728002729250749110],[16417808327672676399,17938621802770727732,17445703927338531166,9164334116731940585],[12750812033947335669,4135885198876351679,3969555131292562236,2923882800602149669],[16980868075088600976,14575972529675563957,1119096344863168029,10466058168907672526],[16278915661082630575,15952133571289753339,2175789902171878223,2929647528938047819],[12882347889805717806,3603874652463984001,2472421686229172680,16073863695421147453],[4750759670569021707,13401798973687167960,13782682746231315772,11485337122965775887],[12817576498564940692,1866695360454547471,14769828063138173325,9864571079789513014],[365853687983279010,12982723795007105120,4158164774758393705,6283238807100895841],[5224331917109680441,6598835313364140741,5627357161473253854,10409932730424475483],[1485233880896638379,12071662103515543055,2139412878003956338,12505221719775911968],[1360073737404009268,6704211837639141409,13662088324981550234,3380234095738789957]]},"stage_2_query":{"leaf_elements":[1803394224327684500,15084535019548988301,5904457480712452594,12574022690483673490,8819907897138042213,5870178489702254487,10046522453191424414,18013732482519234710,204277706669572690,2103056126154051432,2535938452317963981,8726245725694501998,770128752312245307,2437281420018172342,11497345210563045191,11080822120250166230,4497920328384881574,823336841297949196,11929092421884171089,18316342770276075608,7442296619448938303,17948969656198627970,8378430222020298376,10894118774655877671,1557488933061771235,1449790809208188588,6607303079470953637,11385138142401034283,6918535189207716514,14514482557184862700,11538326327004346692,4964388835526528343,12844323363926864232,1452617526761870258,7374395984863573786,10891955318338556295,10494611837656566617,373555562053407853,10948002602966188679,9670515386091683147,16589142522115862124,4185409322830656934,8566930057648394718,1138317268325824747,16146318432451985304,7329155664661327549],"proof":[[6602804196366326290,6259950532309859233,10941501451220058824,9643727301258529555],[6972649199321794212,12022109260194129862,365272593125467897,10834500823963565735],[9374492685136585845,10003496875529322613,812862229534551908,6521021556559226726],[13340985944145253007,15986989871483976733,12548327205407879442,4636267747913641669],[4489443650353057249,15638157019019717428,18257325625877275782,2858465881636211220],[8482199253628237057,13310422007124902498,9087193271237516139,9446681152251285757],[11557857790345261869,18323489695716956683,14057033427910119394,5063697753501620744],[13139537806805500760,15210612229575534764,15987557517112821262,4788077905995180178],[11760825918495251227,4826961061300322099,10811025611849205325,18336729570719245776],[11293537490979173640,1739227976944095038,14246480046875970632,11876524415538914654],[16842727559792585022,17912883644155300141,8921064126944894744,16703967519842154616],[6056151858121898803,11047111564976668536,13517084501996701353,18239371702540954809],[15011692302861657930,15080247585004111797,2562611607130292584,15388758212090818179],[17684428011770412940,13926910399479652257,9921951111939917461,15607398847386075208],[15305483213261681942,3870622862172377250,12772033365770669216,7358212229418854563],[8319008327255715913,16607857083414074991,17654496975262618756,15647971105491672436],[9361241096660372388,7871199822756612728,13057621005758402560,12934406087966475422]]},"quotient_query":{"leaf_elements":[17295990937273280222,10719604926654496969,4333401180306998669,5687605136461253704,12019136681231694306,8389941741646259367,2606724579094933843,12578243941231596416,17405330376544163001,16759708050982324523,16398177891254370673,417029850594009638,3840640430379325262,2522849948279197504,17914372248258627909,8729238531600879839],"proof":[[7304458072592020896,314344254349387092,10575112597961137868,11769343411569803200],[1136980561555470908,11125041832436370885,3290015213944581223,305976795596839816],[17876946574059209233,16243353269950845138,8345249383119716982,3950992209084735927],[7130426593906854021,1013809204368467628,13096292362921655416,3839016194888691498],[14866045079153121929,12051468678634063121,14918163592075974861,6376217255544794750],[2989849942651704953,10131554894480543410,13458055120059077330,11004106652828080561],[1666210971920824319,481392076456467101,1326783318177472538,17669643124945706841],[407792218737839627,15319408493336116979,5276315692552025467,13907564195912126272],[10457145944957824395,15156308170397704488,6163867540480356405,7051161798429484696],[15536343862104023059,13184582017829096711,7965819538522103779,17441093142498134759],[11505874437967394236,14847072995508307341,6807427683415705869,18323185635184471114],[10178660466298684939,18233324667686828688,4245179158409674981,13765241056490529352],[6828958930081040986,14840791760062723710,456607985866232076,6934378731152011589],[11907433163258754287,4102402208178005313,11373680436316053231,1160586008651705573],[13434498397880401649,1377437689243008671,6414084363350325787,8876393564240908015],[16270142854963809435,17117357370502291560,4036575513188496805,7297495482732776731],[15725155024730071472,2846784656528433399,1476956847549245851,3176915357345878490]]},"setup_query":{"leaf_elements":[16035484486989423424,11472682631881065962,2971529270097846946,5582403574469967598,6476789461286181796,7289385389935237809,11125338647115631939,12453576702957486064,17333403487862724768,9291322976280635125,805631770896183732,2250751969868491459,7794517047217906836,15190915026596555437,2233265453711549664,5080401088955699031,756028844848533378,8532167854923580330,15252497399866335279,6315958703761805142,9826232281108271300,6159162671264593014,2355905544541695943,18172923467809085356,16898774263366764549,15123180313933219789,8782717520948110674,12851244445976893484,12435220072391067637,9567269370121569615,11952976342996721439,12013977069128845829,15772841473854898290,10218934450908054118,14939127982409911257,17822909402573014616,14728947413649578175,2065877093431530565,989732628494778242,10441945997669926989,11134090573384875939,978797198218504675,3222639851653462018,3840536764933584476,11416995346682304635,8083822070763678049,18000009201283189325,4427095265126464666,17011510901180893660,3669345816845057492,10067056307298919573,9943822119455865040,12796630358657264756,12041987081712116715,8615835113810305797,1925511073540033611,1090541996991578306,14677402368123510169,15313889319267805742,8800061921600541571,8378971768610776229,3107875227796537494,12814559804158926208,11792670507700907628,14360227619255789295,4022083132149960276,4220715807676432863,17641595169878530652,11902074246435934789,2058904703863831228,15433397505286721156,9669179786817923573,9434525260890339850,13620930337000864775,11972041588231147383,3760893540254835157,13037315692107778345,2218635603718341399,13805396925969635057,11220291023188928441,16935876384948351500,3821762258096987823,9241008180810020212,14212071184443898361,9733065006953860475,17314916819710372837,6715847650305909301,5371040844298917521,2276492475920966546,1852935045233193348,12595894265256663049,588641014709693809,7631232904185413469,1118103294856748902,2588069038287031295,17767356381494538093,6808086929966453360,849164127808537200,9472875023364014989,11761246940650691466,3697957091962716581,3969043565174014396,6050620245191782776,13240360509597701773,13955126085873875310,381493701914230110,10324409155763169651,12864644785095630669,3646651115226479915,8200510369832934930,2871166207207046264,18392288353363442969,17675452979341064041,4579323680280790542,4982692053994444160,10550141938052101133,6398703454551949568,11341232977723729453,14436469345669357991,12340724934051494817,8404990045741497192,4923004160578056389,16898817078070263183,9231298690167639114,7014507198311211498,15371243853675010913,14904249323113773972,5008943100166747172,4564287110533972203,13308294553504716504,4114225739421692774,13532618765819042671,8950311170529508860,13934645940682861237,3336240232525040353,10570521147701726320,9081663094393590731,8165712166209907484,3890205104672196476,1035071682553673621,17959624348480620490,557754349385063420,8454337985432798523,17390086778200375207,1078716859793913097,3154240162717813679,13607091902737008625,7316418929562939541,8108264828489206815,1104676582403505008,10324329227832867307,13405909019032516375,2356441934931418275,4004808755399835505,1941519848059861737,17659235551517366250],"proof":[[9245233223076390037,3654272495372974051,18367018719461653587,5866847158480223510],[6104345780239175167,16705994682416786583,6192539877363429772,16592357794814644640],[2525747306786995024,9019944013359720177,9267627514773438108,17567366185456327474],[10540465669727486610,9938766557145326838,2976924634976101757,12676839923442484549],[14015012501563891731,18372973532449630958,5946451529368505052,7737178120253996108],[3650897950692600469,12594237196587175577,5861232093381836374,9254770697884622562],[10692388561574052285,327989064581676092,16776399676893822762,14486751496821542031],[7188254819099001846,8162326545743500932,10226299897631405009,10206539825603475025],[7444770567503565940,15366517473527523690,11672270867900483889,12079548434163775946],[7584897811170107221,16919463037851418668,18237346117321601535,9051939440077175538],[12080130488601041888,3422889378815620889,8261922234636287065,7427815474624059522],[8098313169899227621,10717748233088575207,5450375859618305743,6676447749701880938],[2916993484026457950,6583976772020465971,16852688558880855548,12588061038153119212],[14590444149286529261,12613365926211339319,15071631742151426368,17200315270947518517],[13153488764905338662,17294234018794914879,383266437505029734,10715325043533038166],[15832722289687690706,5355226235880548863,4170637444115930380,14904023068600351306],[7584630324897337125,5855445357232526401,15406563887835073472,17749225028109240870]]},"fri_queries":[{"leaf_elements":[5756557035700489601,16813640706632690334,12062286710084176819,6566372037838734581,11327847025420600399,16325109014125125691,68043957647973017,5520149161037878457,10344278313347979825,17878200208581829983,4238799295588244271,10341749067734463277,7785396146719954911,10958536291489576293,3109434686323948821,18412804825026017944],"proof":[[13066444314524497742,9614412419958239398,13923823978832367516,7976726584990838723],[2414492106631904914,10517951889970210059,15799720177255349469,15127196732156959983],[9178808467441980033,15253893294926261621,13256837682791515332,14212850993839018128],[6061475496247310415,14595632967810559824,9708268996976110978,15966432638189030172],[10667090454137666489,8263705368988164390,7444104724569926096,12974103718708161693],[7087491377340629456,5071417352588151343,1118273897863635472,5576595910242559450],[9537891333651537067,8099719967803546001,16898713790330905624,5622533431681332164],[5963645550910124950,14844238613106475272,14608401964230763006,4117922771603717461],[1651538258495103316,7447592822541939892,11010092787010361147,760300486743634707],[3965991598093447603,10683840766763117205,11275259230154665039,5829906487355709148],[14634351391148075774,4173936561396501268,7974056935802094082,9214873540013714245],[3424565659697107575,2212386926341110099,2945411392726584410,1986064473197972921],[12022107492789539694,14827703569735874720,11010683985336556729,2708594108380546783],[885017883695360673,13435321449249769282,5466777689613489543,15313896769676842091]]},{"leaf_elements":[926381982388727154,41453370065126512,17508571594585139906,3165345171680399639,6516497146361413669,7483374232710560413,14955326435533363286,4688311764130534737,616914358795232384,4527127661350492347,10336443750358024111,10645785457656285605,17775421093295137941,6700339724303728822,5772787981485868732,14855058022949770968],"proof":[[17914746405507363432,15613531384609812871,498857817681204335,16383769622642825920],[3548255660244575127,5147560297869454712,15170472826823113587,5556670241546618815],[4857429497508536888,8096956139814957469,12521714598603879014,8597845995814511443],[17741959204483814473,2095397767060309652,10346615222718510988,1958821301044663752],[17333360673944996533,10118620544280683498,6503192349750406786,1368859525780939875],[9925227497825081279,5019475142516831393,6329414653588764122,18046798178248238300],[6291580503925751859,14219855627521945191,2598982771713925021,7794731877184715469],[17436251114921806417,16535798766211800611,4851878849710974566,4277226705572747051],[6403746061435475432,15913864629493149740,3308487274169460013,11203944096163982866],[13500830884699680927,15306338317233456995,3299836681659625374,18226561178672362281],[2991006853592388490,8934783177013465999,9854609272269142038,8184295943294888051]]},{"leaf_elements":[810531419221665574,5850993748037238379,15672299468821623691,16488612111126214173,4422619556336728753,12193320352924084985,10910973009136610765,17646734499625668982,12326426266412545454,4150838786537622321,13207896195145559942,15908780351413200240,774239639226688456,12298710179328776032,8412754132650425669,13309445014655124309],"proof":[[9181151504686169362,15478496457299172042,9933642204058033460,5716894297642230496],[12096965623433928351,7700848943391686243,2574920917953342370,4604980706043410739],[7143484819799262622,6271961918321437095,4491852909779887470,11227920404916705429],[16436273173799198432,14488596143786945820,1893337975122508643,16628209297467130580],[526920546931521716,8212976993424576662,4218974118067087499,3073881240728208286],[9653031288271274176,7368529689121526004,14430692323790644160,8836060061319362932],[1806088966856210746,14248697546475838012,8730757304671791597,1502249710639534215],[12483543229731015254,6228922028592210696,6804550060647530973,7609776898298193025]]},{"leaf_elements":[16220555948562470282,16294092828564379295,7454752263197886872,11760545156373845810,13682514345110781278,2182756736131513620,14986653900015969526,4618887156097244636,8981297501724218652,6588889935404339318,2519622556567680192,13352227269741458591,15444258869272420391,14222534219808279662,5683718844753269840,14359860386355514792],"proof":[[12144930190416831919,14988997305901146768,7208392182777998702,11618126824868607831],[12837418204452230580,5880114232396079693,17219826641796858692,7119944924535700114],[18262645052720567710,18348730857695951440,14721440193968122228,5552481305078184410],[120353459084075878,11977129796923774441,3691473483747185222,4915274756070214257],[7378436202281888958,11263343018560466750,12515193662408163156,17578933933619023765]]},{"leaf_elements":[9189383041842988590,6965146586893804418,4220618660081283782,9999429366986671194,4630406983623020347,13765611947963961084,6123428965095967777,15132008706310555292,12812442353949431520,500786186807618677,1689459190315911207,16785331210584185479,10900878928231131599,10840504036657509228,4695360181196839233,10671523540088974323],"proof":[[8007485682100854625,16814109845768904116,1453178838105146259,14110354663391078558],[1130374547257051060,8284282418257759999,7393623318517703239,16641200946473051398]]},{"leaf_elements":[10934508164646927795,12314719184668898168,7161347650890243018,5323539938734047040,427222851664169786,16835810319965862076,8726096516971579929,1018351776603887044],"proof":[]}]},{"witness_query":{"leaf_elements":[4760136491612493631,16304885371743301073,6882129190885298913,15677725983249092916,17833153039503378570,16947481074704681843,12725840746594038219,4765420721993532574,2392020058823950407,10553142314366619183,8283841159432052799,6563011408520584091,1963129835045629498,2289848706487507189,11941170826367532344,15213368885523182058,14377301648310141311,14113147763059792131,17671432700216610121,13412306099248883048,4436078411763010485,17116550229908958639,3974220259180862376,15096803764976334467,5677997405296712253,2836996880844817697,18132615385577389549,10162455902150158057,16711812137050705833,13778561362913637939,10661227240979244209,6319579505511702856,13450379839255451672,9482443397585182181,3259310671206270775,1611590649505864958,1432418337530643635,2878892142980570341,3069382324087769499,4662310509803552433,653989388254183782,3573975272645996902,2896846537050172756,1003691615105703121,8545584345241464518,14851151094912854700,12150809439761303822,12250038751524373038,1274219753021545522,357440366703375221,14755619697001832713,2882672567330553829,13579024659322589908,7232441557903081830,9326785791483481526,13754807892692827892,7505988285807181837,9221447027153111077,8329548793521570279,16894901732962880164,11392571716098117976,15400743851817471511,4263688801540201027,8670944808058716271,14726499361080242202,12919801136749639135,16124330282737442418,6477487215341050582,7114072873377078635,10526982154127322303,16348928329297799381,18348826658809913389,12771071676021573754,12965162680559862281,17799763551197321234,15542515108890081351,5836050686034020597,14320331198743741682,11233394240538306497,2125942984042729248,17670424103229791279,17496787504985498839,7991104498345766266,7177666784680170121,13309196777879989895,16397669012396472387,8252342784009479634,15459053093666151089,17265742836616637656,14534304298967623406,15177179899751300535,8597885406965908882,13787392268119331119,16645008053314608183,17280098421236074375,17578134285139155521,12049788701839498238,7395869669427612936,9609832415485739323,8748595298323903781,17265526053806049967,5502261778645774753,1971684790995895273,14677394693842646047,7220048818874407066,9244480192134701856,16423789804766591235,9806053955867429431,1096496816325237287,18027118957459339239,11359003440597645354,4621116486216660877,9007609805577518131,17913863190779036837,14419185055234844556,8226883238517049912,5574136693236920950,5027256449244976301,14288146235635689818,16456836026873221774,9207592552207377575,2480623781579325242,10069153209977914103,7570378348564654194,7850796845011383658,2203179927011349498,8854715564222358739,15149095506929903041,4772987146680401514,16659513296870682106,17573012346887609695,15940170435228669423,7912620613958513679,1830160846844054434,2828056269105806240,8850314688036131527,1622406400570726105,11859068571787820306,397372493446258040,6129999801360668863,17310016123252011545,11372696749695081596,8532950954455381307,14980056993387070606],"proof":[[15503535352265543690,4253370818126932153,6465922541860332134,2758594268723075488],[12473463804712544739,4517073476724875576,12012153686997829832,1056472590359718732],[15774045156574709950,5072689099449979862,17102709787600345939,13885246313652819762],[3905119059622763665,9234135743010064246,13240549370100416665,4090757733933131349],[12289827277023253539,6248641059181811303,8636289743049131311,9405333619182026710],[3770642106392716265,526922295221690666,14608428993823007471,1440000920831273821],[11992998149303764667,12344722859842550144,5964368104997658834,512317089326546233],[16384845403164003629,15717243711719692434,589042325960573526,10868296236518996722],[16497483723764653488,11811566452593333412,15217689370718794101,10983080579615872228],[153098936007841043,15862027362323526889,9292817124468324972,16710090379652980716],[17228736967070302762,10561509433989689361,9591316468347157963,10698813626661374101],[17472047536818678858,1344876654511023527,17860842532847015735,9183516961837833584],[7525243320061281877,13826608638586470119,3749129313346792611,8207852766719486036],[7923221809918158538,5027613339088919296,15093047807294118623,1975261536333644148],[11469943012277631832,16723999048429742909,2373543112651190741,15074360677859439541],[10239312564110271300,5006577322178539158,5122910654177033938,3835418971351753017],[7496285285731941015,8499315508080853662,473345457475729204,11805382148206819207]]},"stage_2_query":{"leaf_elements":[16319651756257651148,5084015677728442055,8979863753290486544,4309864842918615676,16953955082861422648,8374097501760461114,9565679569773010946,14012176235520630331,12978750768652220115,10901881911048741440,16991007045519325699,5672577376212769323,4262149372217783578,10462244945228231918,2046145087122650053,15700488339546336007,16021169328700787773,61953493895126502,11716614259227749413,12293834644918285255,16958196720845415402,5929144625903514406,9529466909212033069,10396615858586603271,8967786481844367050,2195339840683007780,3396473061074456426,1940344439155137709,8851672926285463034,5503198795481077328,13059887447631037120,17467620601972703030,11491720423394653513,9064638948633207118,17162334896831168763,6999662914263036884,16339032955187069525,11668556916672216482,12470015717967360660,12067762066933579664,1838762602134294276,6178079620176099322,8014490496418526682,5351253197477454234,2301876440685306653,18014183111056305805],"proof":[[3221501250758821084,12871892180764968009,4411517801622904352,1836655005866533876],[14225511334334977846,5809881952598424539,3760875933417955941,3974411264408715928],[7876081751389644131,14691193895003588392,13183704759685703872,14236922312584326943],[15829137366834083057,13855080608547164391,10248206123363871972,17575517812297834130],[537795225979855594,5940610180331396957,1788281354143619966,9055499426008944549],[8290905716987910989,6012312846383830040,3447301545181403764,9176705341791335611],[5659091342576189050,8265287680711319916,15942471625693667091,11546659823926977043],[12079047257412704702,11512312377818706859,17613656400483275109,15556149643030034452],[6982609520444245774,1065948016400275871,7767671946772525661,18079725867423590059],[16925401490609754383,13650642332637444770,6252278338445971124,9829017927044149148],[579321546487598037,7580324382520625374,11277011879561101407,17690606408480581708],[3765248323388502961,290750417702312549,1118005079942392149,2495918198537570531],[939388618569968988,16091121074714260607,18144536644734325679,10302196690855386400],[5925531594919112483,12305873123856525460,16944791986843253506,9160072333459521097],[10179322942606117143,16871653649416982806,5509339765541654229,2877781003933131463],[787955184542241652,1113699728185648878,4417897363943848764,15122575123948571050],[5142946944478076970,986898338813114171,7166217363221429812,161025064090010519]]},"quotient_query":{"leaf_elements":[957263884752552867,10881991269649176410,8935405435337949265,1842011611913365177,8469830101891246481,16849567540122758095,14965252783579533464,5445552218971169992,3352341259849793996,18267047362606895684,11107875190432907123,2862475121036070191,16140190136799575430,15755025250142492721,7228071857877615060,17159284742150903931],"proof":[[10384191463410542645,4347779267448547488,13887496795049592874,816657444986446777],[12214467638636917240,16319836675350486610,11911706986860654848,3234915117597795383],[17749084956189419400,4537446563736875687,17260211307232505061,3771689301420996504],[3205863012478989924,9772067913728610979,13742286996256866427,1000950628443704862],[7887876365145382901,17925214898940765158,6525427055433134942,11806213072191898561],[16172371657958751649,12470793795777844249,14909563182484887912,16260489483503286242],[6651459635485919404,14602325616091547656,4328603394994967323,12459773194555684676],[14967595043509685898,15250370822399277016,3543422274785833515,15326913447974737854],[1000076372064386685,16354173212321182963,6476965199357938356,12513147208581457869],[9380178966148315848,14504136434356295989,11247572116601413335,2823798776366445845],[3934579016590876419,18213296400657071323,16970703978767993470,16268085428422011039],[720099010937968487,7091567405588529586,14857635740402692934,14250470352914378874],[15809719442529308270,2397388100779206956,77051782775097719,9037981853409510766],[10110412281714631362,8190281734593159063,9701707388126825807,14891908751928323029],[643327386753116569,10929773337222646462,7356375542011339020,13341097194635487341],[13843971056907492895,74463908173249504,2393726805756181154,3274170467717181424],[2446409545039768405,7227926324246186594,854384392011511427,8044654895162765687]]},"setup_query":{"leaf_elements":[14742803069384409424,4497105183168894573,9773282449517922127,6328271426814620813,4082756080367448568,12164976557592537774,13287429045206675010,1544328207075558588,12986828037273158472,15438476079947731299,4080044762908519320,16055261973646757013,9479720757631497187,6631247562102792049,6418950030529242679,230134885575227681,13307031524894817796,12400632280431655487,6542283211682120632,8675194572075809086,9559277535879215523,15884800506419352659,121350224561834788,797789800874370333,6660202190050028231,5047698600084534936,13426420214850136749,7940516013753665671,15456486791951878676,41112806048410176,12291592418911240303,13901716583359889911,11252255481847529682,5474528712245997652,10233997551909234787,3050124253878819409,15938570473196228526,17015683490336704116,4318494176669782902,7618442070837670079,9265374898763451758,12485657703553890305,8620265131799378996,11489380194981583175,294616437506595202,17156290015526277476,8836818247174555377,15014732006830890986,5849320812704649365,17730942087435634568,4690963285917170496,4613943551845565703,749669181680453416,7953301171586437453,16626617023450731683,9955140313082922345,3824945764588175212,3788314723232793666,16425104361812823974,4380269350324261644,6093865446089351397,5770695719201927572,17741446066688390071,14027916254143186189,4279765848361339822,14966309018570966529,11259985508631438444,1626904181312757788,18296353460738694410,841076184953919387,8137630374242888398,2960442504380179724,5083312064976265989,4229509174969367127,15939611276807922048,1697491096447516336,9163831578576708129,5438390001954116932,9296594211362918219,17949564397300954944,7827885265711445509,8582219591950368877,5036459642748384700,17571139592248799869,1613472188570276384,11413366022815269818,17362764179754104172,3931935224383041530,18109271052329815778,4720612190809755394,10148508510439147564,11126857189871802199,12178312013612687189,6866475787632903013,9879930195349956158,7555573814182223349,4141266604208485391,5889883995592211488,17169192474859018657,8720781306962513089,211064032457014361,10979527070693925770,10750411283330250145,451406691597561765,12910232522094542361,892755149992604156,18391278403949464009,12513212875323763286,2055871469270751800,11510094555324410535,11955468571997486988,10571685838113093751,11560122443612236379,16982248485626338027,6172906045906198577,11820044398573622922,9747824322873168683,6432831239481315557,4816994961808394704,13175502128055230141,11282943665270441248,13776381108831252739,7835630282775685207,5224748820578245330,8963868881624011173,7864627799880712674,6768013007329917437,1784255276767186259,6759753438800848785,598830365400929525,9594118208494089947,12338446808736212722,3057846802339067696,13696219402636474196,8149814999985782146,10919413466085918817,60198208112624999,1876503111197335543,13704139720983472321,9859359008859572851,13023472578754183410,6087253374949802400,17252183836356752943,12900196830637719934,741587851935218753,15436317263629402321,13022101130313973615,17826134394813516662,9777546018047269568,148651595386079263,4597179224720966298,7722766820793012887,10850118613498069650,14308136693517333238,2181958300205974240,11011881984455916525],"proof":[[10400140080894828288,2882181655726177095,9709265516823096946,15979273228503127514],[8673354795223362406,6406219718607312387,7711763095549036174,5525734691718114534],[7822773142863405430,15768634806023955624,7763664002939875026,12194262740024156859],[11565129008008514212,12954254619623661450,1292194053234595339,11803012530055712204],[15246771800293295187,2032112908843448624,6463512818898504952,818682844032796659],[11691192734362374030,15784845493050653667,4733557934209815662,10953508474008190441],[4802963642195828997,15932787281244317933,4743047380045923704,2076168621705234890],[7809321807833692466,7372977725637655741,10259004668560122297,6439987474084295869],[3453570873027254767,4224081550744127449,15416059957528503213,16644207662901243424],[12937297272406726698,17064820829785353072,7997170735591083368,7481902121430369419],[9665489719385574500,12451839980430547209,10511485358575598933,13163660167914988882],[9047037130943684937,6820342626896962894,15464060018860845807,6613272998211038396],[3515598021931473495,17521540497093898270,1553179078458265499,6438315347607291348],[4311914763039103961,7990690375711187088,2254123536644435410,5310915487737962325],[14791496817323544784,16408593701234453082,4928690700350634989,14659042241023121821],[9389581839137957039,316013109439099625,14677708382208496575,6198689805279676784],[605714035794641895,17662932137553231899,11267508260417819854,16646936890915875827]]},"fri_queries":[{"leaf_elements":[5313541969971115560,8445332755630355849,1397846211846438485,9170699369412886137,14630705590621245859,13704355882496457259,424812196933347236,4955803428836285885,15021057493324949478,11027724236282554744,18013540449489126235,2866694241555818083,5253528574808232839,12286563902609137386,7466041651155221592,17949700646937917769],"proof":[[11027048057283458576,2709681357009697984,8438808977205074057,4207011808813285937],[11270136936577278613,17865487797976122299,7459775218288883438,1674678101625024231],[13073450669452134827,14328910528005150565,5105015244257093720,13908246660597690897],[18062902934389522243,7247316675407887441,2875478932411283974,11358312043478213266],[16849728966878187890,642681030421524709,1898682844121349645,13059798036443868354],[12694460460865604377,13425992925164932469,12846266083097751224,15681005358646537203],[12101847139728027806,3592379916373324859,2408782832905143790,5675383379861864141],[4136731684677205321,4341281378894622007,16060614755508414680,7945904299310286052],[9727559480964328550,13385513937331480211,13023412394742125635,3306554971914814219],[16552117193378358532,12189334593374987286,4890853578361792939,11060933084238232153],[6233600481514705360,1274123991741068728,8483625632510823541,2501305799943399135],[7196463998602787960,14033130521596057132,12023421012704558494,2102870762200769078],[18142908917818622101,7494272579818419620,12558431376592652348,12182618765900537677],[12622435136088813530,14088618649142867045,17064798125148309400,9557743827860148380]]},{"leaf_elements":[18062575282519576298,11287540604506697797,8929571511369809226,10114982611347929526,15482003315458360148,4841180569207710598,7405502381985657984,14569208867868987608,9889300723259052259,1711412221102067583,4198644965452007431,7410716831328178508,12625192434031832489,3613344590607731683,4087701032528459116,7329592319407416438],"proof":[[2018878829501550743,8306600292304487114,2878192385098015078,12746611489997950819],[14878463232400708472,10236310672590794223,8038394618762357323,13153721540254080460],[2624441773339775662,1342293917406616645,1402211556836438021,2869139267370014142],[3531438981298098808,6160533290832662914,5095917375129161018,3468915539263953442],[1723740490018981361,14017153202551411445,10129504606186982120,17874110475173138726],[13694777677650677883,8688013390684437223,1797102254546066627,11324582789568171168],[415536829525432736,13552021112115089819,14406587546759490613,2523288714029725528],[13452299479977735866,10581301199882267816,6730611127778495415,2535135362464952050],[9809845507939689650,17432421651109088307,16731020926444142069,9563095142223187209],[14295434801479632874,16995200288116348859,776903632202100390,15575553808252629596],[10451027598658794289,1409017892025884115,1441116716198485217,8515659924305447215]]},{"leaf_elements":[3765464068474903347,7327879064361808169,5003387828242042753,17957287282723349754,1206182983139986092,18319929594859664700,4120202596868738702,10900961827940716848,14942613494347739244,4660217120680378227,2558492852661832576,17357378129435074627,13762845721065805100,1376374315419855414,6666625008995754610,10221256566837527877],"proof":[[12659154213526107651,9045291864096833605,17047718324866067972,11729887048439669966],[12511975531574691750,11484422905783273961,10484919206343351702,3231811946747475650],[16832139247545662926,3694216456422607802,14137916234017427836,1727071913835204871],[9402191906557068467,454116000874241241,2212339527256683105,14985020313135515270],[17467031817723577378,15403021336542266260,14146239697649768024,15136928754679644218],[10336831635806293042,2078847213647208562,9284350543390437649,17107828558094331416],[5536165752182131798,9929382143180799801,18423748697702302070,2756294044769054717],[11283839272348111020,6063065441510746998,683150689620058394,17700376312019760627]]},{"leaf_elements":[16922289349674252345,5859850949438424315,522484321690228927,3778469060664035368,3375842966706970006,1673602216071406235,5816019010297436979,8017151706290769319,12426381615482558322,8634531499199158818,1836447295823381235,13473269436192878658,6353499252042256732,2505301001294090429,12477835846487610977,18363401514615463963],"proof":[[217763377874256535,15795018723336245774,737199001134476388,745941886999487252],[15383381396159645885,7752235738048760150,17274471909757344646,11356367793881471175],[4025077178005605917,3361352522723538719,1088985924547272065,11621089344095768281],[153614523888197626,3831270908457420952,17468571913123373758,12003599467361797195],[3577803525313655451,1801329653411590312,11522787841478459221,16021617102567237239]]},{"leaf_elements":[2355092831518217399,13291208007397555096,16112562303614477948,6283778926193439922,8015297497572453768,6144906371828301093,10795234163397836453,15317047556002133258,11803210352662175508,13964960512557523158,14371730922491567815,8615468377972021231,5245619743684049418,5589714974433316690,2225411792490568876,7951315786847606418],"proof":[[6659689063559870066,342080100962376558,2937060353910455897,13102301432676217499],[8172119166490220643,1715341192280120671,9751970656955179684,3510476705473611346]]},{"leaf_elements":[1275295786118718478,7488170357634863325,4283449960128273261,10193008459420986025,4238185187837649128,6318479223569512088,16394860438500661164,4148361282767282169],"proof":[]}]},{"witness_query":{"leaf_elements":[1404528507424894243,13800650418060011602,14338620816682850551,6535085508759222326,9564240746456979008,9634159366437185520,5619204740314867177,6199923767254869347,10406465292331361016,16136738169088886646,7748977806347846119,9495902707144950173,15812100850453421815,7152470722125286572,17365881093368342738,17650383860832750616,15825982819044634863,3430540928078585694,4841378214449015268,16169702507248357248,762637667366569453,15146630560820584502,1654621062167271550,4135328849289410589,16626003993977785772,9102176742358767082,16404881218044477377,12295768700108884970,1423059565677682881,17485828951473923903,7256918649504124160,7232963297753467287,7325105420704435442,12247027596271637772,17548615909075483691,11611116977643013068,659418635420033583,16500982877735028601,7387483287730051575,12644439919692795802,13667272439588885595,9532006661619719964,12696554787365531118,672842368473380931,1084459868722611809,8739938263850646402,13663635403498283807,6733450752434260430,1176029465402832606,10989149059064810440,16972968073020398525,1220772640492798469,18394355339306484292,3263182605810375135,16183595734356545086,1943437760839204224,170120782491510592,14754841121905422565,70649212631716224,9982366234380943829,12722644392982582415,6721290054802829288,16451884351812315390,5202286356130698807,8697738925687922871,8563862487391082341,10065587014276420452,8771516718338215449,16615111719549365864,736842439961175325,11091109416089409190,13652141174567181942,6803967924120252747,864272454092155266,8605449820736339481,5148011080256000580,17653636078893426848,15401587407725021567,13978218335507491684,673686291475605629,17190701768021501731,11142212509817165049,11035114479510198575,10667338088885081091,12295432037664341380,9250275386444872475,5827218470403037459,10186820060548968697,12267336778642530317,5836223202826435153,16608695403550209289,3088244448812100167,17966217070706471281,13701768808761225760,2744863693370658831,570094812703098130,11637975481614294431,1841244825839450057,4599713768359721237,8787089730759985532,7296439635860575025,14646404001744799316,10907722128313682207,392861031029149146,9963097178856026392,14831442340018213034,858748375808231353,14578527497211962616,15299187136943704015,16035308714561244505,2146432666609204474,2350373253368057095,979942485197671075,3344648579642872221,8909691629688673974,8431359447353961995,1665319832836252214,12450801133161000074,17901485040290510456,16554618584431691688,9498431448119458179,14643829909952990702,387125549194604037,12264891334158146467,2544553723109333888,10773489637063061503,16846829176414833384,2479621863009651793,6744321614030440549,9360002682350910257,11859001614588433705,2538562801446495263,303841614166998622,1060396547000069512,13613785628078090215,16076699318570639092,921318941837577181,10164953116492505664,10550712991461734397,11750037325895191961,10840156931851386978,1020159442520769468,18054957474380334784,323215730874470160],"proof":[[12589737940483506544,18191397204225253629,6104248347066526071,1225902635463474837],[9389464201394505536,3880233120554771372,9898985157679403001,17728213486181367277],[5936408566496686069,14510797803973763105,688012412294931073,13870843797639006280],[2003510998961720297,4399031637701467197,3873096801881832924,15102398358862839010],[11662793077843277359,7696631034723454479,16586921243829597999,6063224944375115023],[2084581598569680937,17653864558712884545,13009566568505214536,9508888362635072078],[1628162987181576949,14095437191879839354,3899720580292107845,11236551189549850268],[7997039097630217535,11125885002195570679,9596750675048383565,35073321862472872],[571419225470546086,13023736385016700633,3881373823060713699,13329294300915026329],[11185230863240381393,11332552985347273617,4807096402518148694,13486112656989369913],[467609032431826260,16985610442764652178,2834556030765036763,7019788054754825817],[11215690567293568636,4526374418924880497,16319706086936334636,13724905513944639179],[17583364658320495809,11554958836555221327,13678729763413148204,4780064544962786998],[5859630537328849310,12179870857357982148,11351994778912388142,7771804348704701505],[17224486936319432768,4012808329941046084,5808896982819658008,14316595921143908806],[15346668047248116441,2526726310755198274,3435646062692882897,12890230126974746074],[14592655159823375692,4886438218661956004,11773371646111906104,1577097193499964970]]},"stage_2_query":{"leaf_elements":[14408521551801714318,12464916605306431063,31077588660535696,4550326144101867493,18073733635605376296,14287745164423891028,1522000058563456893,17809936744337773451,16312522058167232054,5302643031250511052,7090518258500646252,13651515635475165426,1767705315499498235,15246107617510477492,10827314427608989014,3050802171749722644,13202427591532188217,5523656589742842590,5923644387611380213,6158995283260444596,7163701737411428070,2908341524531037381,17968862376240309024,10784996119223075045,12731719840171063846,7960035996704353375,8700859054545163527,14141407887883342869,6536734796049622015,7338995246139237798,16104008342944586273,14167779637819984197,7345933699579734117,8634922541702174258,3786215040600242723,14451254770866251505,2985551126689909948,3490634042574048649,14224781300876875163,11587176116835899764,841194503162472777,6985479137253517213,3582104833243901702,14245125230099418112,5291898067430821313,5385692763517233027],"proof":[[7756104619935197709,17825785550933844502,269901901218253074,5363539028145481275],[16748258405941649094,5845115808585830749,9585937120774758259,5300979675502405401],[3130496505553809917,3872843056558696797,9271952497037783463,7253678204805123592],[4911667511489020311,1711804762510182064,2000392104434601313,8350107039227446964],[13383242265193322218,1629737229365040880,13789771342261694303,3953073210348501471],[5930829379667571913,10150167190346239975,15956253934520931916,1675692009508950036],[6904613541203410189,16081847483088124538,17606614352531980043,3741717734616948175],[10633048538031764986,10436741577201243727,16158832416099217330,3362767975952996587],[6956125186249098465,17248430040656246152,5504208922608158839,7066371421902627626],[17712670101023719453,10236037595860105296,17599347926090984458,3506417131687671045],[4904585544387660812,11331433642225450528,4333848833228017653,602531695572115616],[3502049557287436448,1370338310247984763,3428852397805816608,9680714871911660055],[15233306705563525039,9149661147158560468,3004555243456290899,6541988596352514461],[15142784827152798947,280846781490759747,10284128906134275077,17127943654973131352],[16527242421544523961,2343682257090696879,4181098400110605841,12345797978788165037],[4551867285975537203,12482358037606313884,5878331143723473561,16657304009053288735],[6300385583840829135,3508707821927913265,5255373578022653255,11410137574386606844]]},"quotient_query":{"leaf_elements":[4220222372001300546,15579740560338596091,17871347932934325513,6793373818204495213,6102339308485492849,1349483959864932494,511075013252249837,13010131624417561923,13156556288734988858,2532933319794119464,13016295211953828999,2767781300943557947,4481317627640903654,14470023374017714529,2368098277564653462,13879915558860549156],"proof":[[6986775824667538024,7669237093472735719,5123334765378160744,17799215031308459846],[7411285560450193736,11303821670798272741,9861199145696584122,17306792830586176591],[16660494845459708538,5754648052526799178,101537083685612167,7932617387216986969],[3459733176749511485,16427224450962620576,8791164451692562229,16622571119092526369],[12126580273531151350,8231233579043583348,18440612663350136600,6007592400168641742],[11427693814448388181,11961057298052493352,13349605566777092621,12384845809234934054],[18337796977459511052,14217715503730384314,2173179657544666435,1374764629286030800],[15295067584236933117,6806132621971695340,10018126019166994251,10260860396192287788],[4993936736534214712,4784441806346298813,13209775631402537410,3497204190067535845],[11489557651359316556,3157632915003161015,10800368490436934424,16659572423867830676],[15540723757818735548,12031799354050391179,4168312864690854162,7246998121152127316],[12818274463233575405,15365970202025533854,10264866263992320023,11060986949844664494],[1577873638926120167,6729023868819585444,6052711460845204459,4496408368573082395],[9663427871853241770,15957342441767790132,17785628620996656916,3565723913574196873],[18237710150287508201,6434957956891426046,17484963899709329462,12666809802027787663],[12737530948504826777,16198149493584598394,13562122960665280839,12900254218326374689],[3678234868369141147,5283638782478520511,821763301433200291,12666613813678185860]]},"setup_query":{"leaf_elements":[13547471556699506567,619850885920153124,17653378468576260738,2112717652479045630,17927807255013385764,1451119136080307993,12087957212864846071,4244788130926871528,8855019152405251274,17956229752616037261,13438196444213294308,7416256188852037412,8158227453155458708,16939595031163631634,3502805411442482123,11562159003514936060,10333369154013031701,4236701892780482088,576660649044219133,15772626757436583268,11025533003155430839,7352297169103710993,1455079315050854411,14240656862045499858,8666576314030082034,10535450840056630716,4462949030766224964,2422108371831485684,6054995243585802812,711498659320879641,7399407104798597026,1514088766451967235,8044031343496777148,7111423650494581477,3509681557283169405,2978372303148324588,16534966766188235027,6409405743194692526,1912112620937572525,9397293191543973943,11938520000242875864,15125889663389872472,4796742733476070669,14465262806866212378,7838306874843982838,4076965244799919804,9782168509184625791,10358167268949399038,16134846566433336001,11544979743717318817,12533580396104655762,14556349943468488209,10259873792348074786,3460170591059005361,12849648785718114839,795665609358437758,11121025230704211975,16960785442761031879,17710076596649641947,5076859294837323153,8767290854152949924,4008780962711002621,17896576974773167780,14875974803335291894,12645858557636781620,5000917640129060487,7788594018026584446,4757035693698679200,10166226507552095732,14416579203643327086,16917957163591450744,4585134802676650429,3719335375112022589,770620467567200677,13151760450634064971,17931509153450652875,5770657192890010926,4728854458135716448,5653541559599471418,6827307960104754232,9645715313180259381,14244971240318332037,16457410698874654142,3388091496589163982,1658993410156801657,14077280061586074535,6611468094157353988,17055523802120495534,3026039115476581859,10722901675895326853,9442667421091313020,12692036994255037453,8928865943918673608,7933063116603852535,9314460589276907313,7152514593696891381,18097873920384913008,104808006955170552,6024139259124765074,16980203880737489084,4665894206767332252,13591010111988247914,215734108949830061,415876210961138105,8952023198021090537,7183209495128392992,16223406339758152298,12142953301792813396,17007482608324410208,4904967454546256352,3262330711121870858,4488886006560483229,12455846121102296885,1698376720752850851,6856987144432419522,7798373263748747982,16243779642026107883,12471060243833847110,18017256526064995576,8807182137465739207,7033108879346680271,6091738900495679474,15196900064555712348,6615095431753780861,6628853983982014588,9696455406298709646,5093732962760894641,1974079268870449163,13499681062039716356,7200452588843137210,5601291769895490056,18334995462751276587,3328643886648745485,12700249363608035643,5894135509227830130,16624341609077446396,17964121622462818271,4243631552347051219,13714149767514969804,11142584043505157305,16160719445776828425,4118045239506693459,1030492318141203764,16412713969785825827,11525271354954907203,10199099725183217520,7355741955745567951,7888975564387681766,3552458508003530142,2767468384091865894,6879455438335355030,14278930328532306667,13249189929514228082,16686166670627243891,1231438199352595833,7577085905097918681],"proof":[[7260071195495667769,7656157597488723953,9356666225228806332,11034283520520437192],[14423568805187773335,3114315208429164307,10598445338650598258,12570234283911220800],[9001682567357417231,7819357342498908215,10547422521679522325,9208487783677185050],[12163085686918798325,4187625148887533522,7266726545213758063,8431166915201995],[6150387597554043582,11243233867216681454,9728917811769562696,10324556747995356317],[2871108675383420737,9085938532728715399,16541148597189504615,15289760822127289621],[9386380661485403029,13011634132234316598,6746216056613991719,5844486637534720659],[5640023528986187816,830688238191035161,1167337845437552174,17623301627866634011],[4107084672044127966,11352203209061940315,14405989709968663292,4593965282204810487],[12199692685973360515,16019128926598536824,3331682263936099830,7691088761454493122],[10832784506282778005,10079690747110743654,1179206862373701737,15046866254778736393],[8340386789298353841,2625202509465899107,5115259763439133154,1845397437162838585],[18445561099746961076,17074728644324214451,6174573330478746591,8936597969426919290],[7141680592569670851,4292770997412106254,14870137729722332231,9246559039106688033],[7315760703789728030,11098854478372754895,13853021607216137132,10213664874690697833],[1604331307223421191,13365993051588967226,8588985829317977614,3926111662093512656],[16354204956433885405,13679537276615897443,10956784370045293126,16160403238752695896]]},"fri_queries":[{"leaf_elements":[9623524323572993657,25558880642562281,658002140754013965,10346682673706072106,4625505646488883128,7546143293008450236,11373814324986553175,12414837057312057781,18285919370672267160,13587956227446947582,10158974572594306955,4559175444866919954,17839896231164526503,6802972597768559206,15938344109121172386,1115343093548146651],"proof":[[13188594347062674541,4440777122877131956,14064156176081600394,13439495636825871459],[8112728159513764267,10059456883638704421,424706175670829189,13502155477639187670],[10683296798358127652,11663981672651477979,6831451330674182349,11331862649811014730],[6611271950925138199,6089563617172336238,14229405795804946331,4427116118877150077],[2494928323554127144,8261483419941704569,9869825001341282922,16324114136087564552],[6943780804981829040,15766711798200787852,16463461316863370745,1218179723930410654],[578015492533071805,12934346036377740848,15083204038339439262,8990182344214826942],[11091739947064850929,5115069787112506444,14505095741042836674,6101429812081801280],[11959823859926567097,16817290488534626082,13084508713903042050,15062687948128750583],[5044176288203587582,11540177007998131464,17775480255618760564,18155515730420726329],[15494872468154473237,12701095984694621023,449469773876686931,5969728520165138629],[10793168821751184675,3276469622324403314,16975527531414042145,6168806466598292865],[16653975507766997525,5852361545422212783,4542679570729558458,6286968683788957014],[15841979698184688428,6766978167612976972,6988718529989188967,10317852718069604352]]},{"leaf_elements":[14139606035776788788,15935703074019653620,1178493699904840419,5986377067347385908,15306099448752351397,9977310104582709785,1588888055952691949,4248701961932599764,15583256679978507231,17934657331491697497,15128375595950071804,4275532687179044951,6974732524968267664,2644828386470753559,9497990805544177638,2114988751060729090],"proof":[[11683788524165481235,3006510710908924339,8609682827524014159,7548365873956265932],[4718616562268097881,9903099106460274902,12195653112686883321,14154493557576242761],[15608325291820569752,16923975397127027493,8287040063472047298,7695544922611621631],[2105207139578644749,15948554170764791367,6756651764508542311,2866319225937426604],[16278293677155038739,5853429325213991311,1698752306518341970,3079841516771761383],[12441426895479306285,7940093953431436142,8383626898814090188,1689385620396612026],[10884109562408568720,7130462523659678305,13825774239652666032,15484378367163052136],[4551806843147067715,6807916825335826092,6366435830389672071,12905530471968754307],[3601417170926426764,10960416971598528667,4116057248854126,2729170038546637113],[15738158813134786993,3418264850276457326,10335140839884698714,2264973671078968161],[4620940820684181288,6218150265279905101,4394142517619279316,11376274407012839491]]},{"leaf_elements":[13722391192602715523,386840651808450732,1493729999099269792,312545090814408934,3386216706495368677,2872969564890282966,782083517070098488,5041857538980077802,512193734770716420,2695594855991318439,17073002205649032437,15217028773293166964,5359251358622106871,6783296705325126360,12385179793007088249,12186696140898125178],"proof":[[1431197191242771627,9817271263585285793,10178331625613081832,13909998036629342147],[12228454707032722978,13475518251952240775,4583984518717350747,11332422850404092980],[11762190239899609731,11247484759398494603,11413265932625651029,5047998117278041764],[3901151538869752067,16231256505939414357,7996629450226258023,4040134339539710726],[8228566862601996342,14177459401727221873,1718100261631303634,13119874860072289520],[65980789906675408,13227748254987345579,4087138736314592439,10840232629741442268],[18157687998917215258,16763460318887211847,934215623952467888,16511182297630279563],[13141057789689340553,2448709708255569924,10951846470074346402,15630920576161203827]]},{"leaf_elements":[3509714768259719497,11894664950919283461,12785145228320148245,16693105258030004808,9021510108358440081,16004221595363169713,9484265303582478447,13007148202657754114,9215480595503823721,5841662028843855226,2037476634677493170,4389897679482279111,16385109474744877691,13221811197849375534,823172116554068360,8202461867800745082],"proof":[[12771977910336883831,5995719090664390741,12724516012575500716,12523971605316148742],[17848796575654657697,2854481216177269724,5400972372091096495,15064695430402812073],[13584073186140220454,2815326856160201506,13520802899477509320,11367850166795314918],[18105499576403946718,4385796141796696880,14788005547233371370,11971365134580477349],[18094368428717041921,10947070686492808250,14391504912823517373,16135841269932707575]]},{"leaf_elements":[10436843727865497361,17846276555127019869,5922784516808728109,6563996082027773457,584050490551381099,15548329999239472536,7506827572629213845,9991002189841428580,5484499667580979130,8499433419154611987,17438216066036198705,4590668035734578888,884955262166708534,7181494639364029331,10730017351734604780,8530100638143981646],"proof":[[6389906513795140626,18102858087891980784,3468257514373005665,7876526185786639359],[3419541161667130895,17696456370165664112,6168864541569884414,1311020060133671248]]},{"leaf_elements":[13912788208633012260,16592364955197622110,12930883254427910878,5599575569218380943,5682660096836901399,4069773254031359724,17686759155637027087,11829746095036037227],"proof":[]}]},{"witness_query":{"leaf_elements":[4803647011949500620,691791730143823003,1634500133554289420,16098813910279900520,4837848063448624838,12569917437292304298,14284204465734111515,5346901729478452592,6809807669418882296,2034935585558326916,868530096169227670,13777743849576603134,1102072907122680969,13251459238189291945,18079530138433766502,7823706903241062561,14567142911116986351,15567062244958923426,16427460763465119306,7952089601481019199,16730373701927709483,7196256023161722186,2520741269572042021,2080171564239702328,2744931719001762351,14777556374708301908,15056071971558621454,1395688703219656828,12804282432382645370,308482468807020983,16821873688241754243,7773020617452529665,6092275783949899427,7775399409513185097,1760832734607484207,13053333620730048222,17794436382819789843,16670438832351783980,2115620885172743480,2016114153579840161,2402551130248294275,7949259737957650907,3421710443224573725,16664007105593511670,12105062859211966296,9291494224036177873,14786763589755295916,9048181613894757618,1056828240821492218,18350944714861693881,7333219789735987540,184487980620779179,10052943494611659613,12659727379711280910,12719368911210966228,18236128463138721633,2442130222049896868,4348196380920327441,2372449183527493993,15526012598160270925,9657208323384213227,10191239700187972935,12890742416169820915,7643982024096300355,1819641993583183234,3917274590146627108,3406755293193989696,4743975418546583435,4059986831505411259,17510656019247197812,10510321496211946110,13137571391827811919,15891948710104585341,6359176758485825148,11377740106128576700,12939897723766624239,16293804348116092714,2826304653228987269,13064699179768626040,5422209087428490907,10112053779754694378,4587464310418364954,1492204367821248291,11935810356161973567,12606535610972693441,13430478396389033471,2531821258107124871,9253207212031669259,9473386461074791899,13731537332716082038,8940264333788680428,17502858224776507987,9256254786711331690,7757612742657286185,6324549811506910815,2609417092190281131,1498935983437404506,2676974099922331385,3677667796512179899,9656325493882038584,15669213131627088178,18205952304161585294,18220254516892288695,9853489212701786084,17759097173023295486,650759036283774147,4127142482897839508,6751487451649320969,13691948284908890155,242586249829093999,12200481091576103715,1954876049819010355,9923405541887391419,5176271035429348667,2772158756433798316,15489573265261938204,14369802185480311512,2661400633128344920,12210858346806015485,14478593233880043020,942358564057686210,15715277952610460971,18345197920488982412,12966114430373164123,15682110411550015917,13041926269749202235,15906159729667008910,9122947496727363926,11790165211337534181,1998652089841649954,16616541646561282543,10208897704585301156,6000252134033183519,3293808401010897672,11354214972630336539,17035120416195112864,17364840084985637962,3990026705552414268,7700379917527357059,11373431266421020346,10636956221285743552,7414207402669023736,9856069265845554203,3066395662235043700],"proof":[[6538953911749267185,14388598474922528252,10905639920261565755,14647618713288582741],[18422471133992308005,4642418258668221780,9495740750886769469,10075923606448966488],[8310725693478009207,11150586474410935706,5462053728861849057,7795270579834069087],[4282673184557785908,12029723731037968675,13807391754744339030,14944802810133009910],[17401371182389340306,12181940125469075116,12954792973912349903,13134139147943987125],[10101321509764375511,15684984292229332008,4490516326097517876,13215218240808584819],[4234102159976954647,5748273136158256202,10814832876268050269,47645744170338946],[11578439783910802423,5945845434207172717,11906933361339401925,5962851591682635207],[13017359594849872324,7480330705049888859,11411311866107789519,575831172759653363],[10455068595971553395,17113384533333133426,8047494210691362616,11894551162923129533],[3178887028876214646,1456911932209357006,12598909924653254443,2508115375660080166],[13696164753692743516,15506641344796823596,7192627745387370899,2933186146245808447],[8575807326895657767,9720491204549049323,4135870576857577880,17232981068547378222],[2318822228975747329,2273142748091734239,3844965548090906821,12180710911005079440],[9204037462967564318,8038527579365052976,4450330239474090047,1635669627502728862],[9258696388259646266,17598517151173297928,4711376074229708222,5650504760284536662],[8962983601327175991,9655400076779378322,9372067540546984264,18437205832166210823]]},"stage_2_query":{"leaf_elements":[13479099899257029596,4046056887103244325,6555858386165215561,7738494138319527745,14386128981457937626,15003320311215066404,10803873016811423255,8391521817300302072,18041838263586568207,2473349374428007927,13514145464407876806,6520954737010155154,6650161063071875421,9227278454789159408,16720003817054459647,1758517554356111989,7525191599987313652,6593146492982776483,17275554567942497560,6124393614945897396,159915311060226791,6504857118745718238,10298213328909565879,11888408157551841605,18399438947551392951,10264191309689237037,9018891930685356245,10050772111428691502,750849266865527331,5504298697756112602,11603500897111109461,5759829013195628876,6293764160864751517,9041867249830607908,1727409147658915508,8711490718231108450,9901547096591735154,13804995345609461318,12618793824503914244,14152511725733612280,6821919406588561324,13590274135125980370,3276208077445646592,15548851659597274924,10890654491469514982,3258195655321664186],"proof":[[4635842289207183534,14720716531640550877,10262314988321401921,12315556221054956309],[1270343378116289005,8500319757477380592,17480838738814761105,16017273212819469873],[1998962842767970876,14644531125278728727,10340850351628558958,13078628129386594704],[3446673103769332891,6433004678297808840,2643852632241059495,3466062317747561048],[4256854956860278334,13911183223523784997,6010053350543556928,10228827913730321494],[5577700025637304742,9781340875914589658,3626789001192955602,10271200792134673414],[9019730607609273391,4929747826230064794,8529621921609439221,7146522049135752969],[12204844149333959397,10479759696859596949,17680189291421821038,16405745522456756473],[4665778934048737328,17987862356863795631,4873348103707167591,16884874052748674997],[11804729414709877006,7822903759199723207,13642845361207691272,15343381756799847549],[9709134600385575798,10324272617845418781,13123527020465075889,6307516879228535386],[10173368029182259974,17488056856077348800,18159629772444175906,14686611522348841874],[17785631112701427756,10136984792924879794,17233861951366118460,2552014563559379696],[15106508066000398903,14314485421508365116,8142409013111107033,8480357597860591181],[17366608725132155367,15325142881924560155,16666722095506486987,17519096490909345296],[6333286269642657053,17140459283162829619,12326919124775573624,2052845357278183538],[1911347836580775672,3246100548763748938,467751161131197312,9129819829973384756]]},"quotient_query":{"leaf_elements":[13262182777414201697,10461648903211843666,7274834646928163981,2164621861600000967,12560036747856261692,7683790031385710632,12119199773211787519,12577385494137876075,7299204262437853245,7911023785431217811,11098345832167338564,14735054878125910599,7388016590246777885,17817336319459787055,2502145737525623276,14065158707023544035],"proof":[[15192305557794787758,1923061653482014270,16068679497549215035,11612102530844653509],[8749692525451688764,10598741418189870073,4160876081169180132,12840854051623151226],[1017158864990433444,660814439173385902,1364968423745291729,7408034079331761652],[9244227252324029276,605042665827619513,14112144668283018487,15612036653374050589],[10072361441870851503,12551244938877122043,12927430540677789576,10301585527888431362],[1179159522913603317,15345805729530759679,11141637159596445105,16596306109361338328],[12098778347615213325,4566664342041702288,3337036944493671172,10998501501651290065],[14007988441581593464,6079118920177757450,3422395055051858922,16211267762757451702],[2240317375222684980,18152990878692957625,10949126508532658323,11184448689341898629],[1629147586031219504,18173292120691619920,15592870204343124537,12565425261976793008],[12563493692575672251,7633464953962929441,2271629368799182720,5744942685730882968],[17177984530241884815,2606431704153039248,1112346566999682999,15466343436004086575],[7421238926635097844,17280845837719718315,6642076691086146350,5666969607462327564],[2066999811479382460,12416145717101021936,5227762792960303269,12394156157752959397],[11874183217706943114,11600580190747408654,3711762230651781200,11280937970417300898],[11730836521037516166,1828634444375258535,2019516141894869084,16751645220763745696],[822135299882928769,6832536832869235243,17165440014740463881,14363198558232023699]]},"setup_query":{"leaf_elements":[3100590789174593691,1940486076134704170,3798289700650515706,12038221370199179399,17376996416532966824,2475603044322163570,5031329058705583064,13323229281542424547,13770693696960844488,3293236467869930854,17395818370512682456,4495891068038929783,12883485185826518217,12967738009120881953,12599121291418742758,7583259259535740376,16516139184529623344,4333537923811338579,9874340111975486584,17447572294652586838,9994743913410521121,12703860029447179541,10238283526381233698,8955109678819182585,2745066024304945455,404488333218703903,10425233615658161471,1658047728024203832,13327934027562063009,9735471596254564899,16427936915645964140,6327124461489327523,1250290969618746992,6006735430261581720,11658357055673583561,10746915916888618139,16929854481417587998,13774193881460248516,8874235180945540024,9603718068754178485,4174667975400069844,5380756125022568455,13684820767810462257,16104027715857026180,14688187374020084303,17581938878639021755,14921309736821964026,2597210547874492074,15390462038929761427,13969193182154947191,6304304240950597507,7470475335978672349,1941551035734060063,4332627280841255774,4638485903754448688,696413674885078275,8238629920183392333,12770863212900542716,5980880425495660201,11130258241750561022,14341510661305188320,6860083664936561769,18140388947106934112,9808806363266863604,12278697485501893805,10368155833404017986,3568756638192638931,8102374898482700577,917923723376830122,6103280732593353151,10811009242486416786,3637449379413697685,16891566221399078226,12787271503154108688,15708424171080857201,10966729682171841841,18230700925105283326,9209324602884950870,15078476720386163706,1214513935719091346,2096393173338891338,984584116069098908,14746859909163279834,7205261260432274949,11531401000060253480,9101448890714951833,13300550611992715964,102972037463385856,16600180331230490507,2091479248943313964,9779719225076386914,13170793056254357117,12072700128208867530,16350064726227103439,10806749613700356566,16416053833246983009,7607835673159382825,1490945829111535013,12617659208775539895,17389532362893730007,16959834281196794664,1561214100363196639,16773244142793017654,9471531352935303917,6653769074060045197,17988581766584023503,6530562391563885133,1925244210703325855,16722904506611659228,15673701353999536991,16673965563499194962,12807564361366932503,13338720890541059107,7202795092797061236,758873842424065513,15825857437042286209,8037178447160802302,4361740244810571351,15368479159044906022,8245091884061261867,10012106766503812385,3786037041968434416,9779116110385721946,9254878432976992929,11534024612813883529,11443541703848922124,8219864745888449465,2564450114830385495,9121995300981001278,2112603903518907546,17804202186224820873,14051449248928142991,17493021256438408547,6894588783139536992,17671165155686310663,415834961128368652,5405192316501291121,2006577814640715570,2150033207086456697,17316500624361605298,6440842958232509810,5216287137885518052,7154521615400019511,10716976977968093698,5602046453251834878,15364974507015475119,11281215674929286634,1506412049389844646,10317058710813025725,16902541507120193869,12075851903767410721,4989459605758453974,8418041851862658532,71945996156945413,8582583856786954620,18167124127156005119],"proof":[[2459359083221210505,17353947100169120376,3566933268205879355,4977440224148126308],[1235953519532567972,6337311304841264962,17253097186310671615,13946651501340419773],[8374858609099474598,1787196355894877900,1641207054630999571,2398706063976840323],[12485896694633395824,7653876874297758345,12071545959423465761,5791551993917518104],[12303127679955856114,2922214515226851023,12756573047169093660,5306038140954215469],[16136029623197164320,1445549907264870634,11533115860757404577,2260465138333274488],[5618109630794072140,7318386227694457192,17998650151817427837,10856871856178034051],[3762794016333583151,2460078857046118664,4521749761706195334,14652814181901489404],[13860302769600266211,258386427630206161,13733731921379812187,7328237391356680117],[6418501344169527369,17053918896358193910,18084274322469793840,12944473220771499954],[10925375397525836762,4143863081816660490,15803349689231706805,6819517881123735768],[5021948571532632674,5138410543566839110,3513728436393230418,10068384662754270413],[1744403055364271525,14376346059452867172,8748920632086407659,4649104412835008734],[1496968347166446236,14380306695868389427,1752214416985856080,5357967017880880025],[8746012872396559438,15764223071154154246,1393213182096559454,8177006848233926031],[16737497394283627010,11649289685888163732,10908735700891821988,9254629283264086320],[8150671396367591155,4374957965196029991,10091316552250686626,14304794448001423245]]},"fri_queries":[{"leaf_elements":[14690286533309824066,4392834980470928649,1948070495022405697,9538798296257119660,15925734318774575157,6698618042627737162,13820464404134017665,2208756277052889601,45639319669088226,15764155699909085278,16405521253128681161,132139933640154412,5485873162929028420,8310863099922883028,3667116285542958411,13168769492532594656],"proof":[[15963225750829236682,1331122163073811160,11983926961939069231,9676414185327719976],[4885127957370105069,12134035384829916227,7731856555789690131,6361650306356202592],[13063828540734419633,15412833614697790150,663859172494057911,10553108879069005388],[14953914767711907913,2971335265042667536,3851356302465182426,15967039693680305808],[13851091134634061460,13416907990986945122,853744538103434722,18052234773377663592],[15512341332662443044,18124913168868492997,12840446005825190288,7972240644724680887],[2237867839008765060,5461313857952092711,8179524534554426434,15592930140264073819],[16273745541596636669,8898349746361963720,14390384537496908502,6656655682605312330],[831208807491562782,894696672499095010,6761469209843233148,12530269328400269004],[7780257276354199765,14863893546999052797,8909948923625164823,13608462401740193639],[15008254530204230242,12612796999669740261,8099054603982248882,14252427171261954268],[1065543738983190616,3025580391014251373,7559706968987851272,5828378497983666873],[339703385633183973,7670437397318837846,18048821532852590125,8406083420087351532],[9886176930643768256,3509706781999382685,16706751567586875992,15900181631248865387]]},{"leaf_elements":[6000385888505261906,11655730482157564506,7145609288244860412,3627979940925989486,14973790670758912787,5822599803144756053,1304433293044108793,11824287751778146080,15258240113596334453,13462118938468094138,10433570382226534757,6540237887155941119,5117149513036456159,10039131986650544828,10927619802623122763,10590138724828820567],"proof":[[15377967203902955339,6264180553240932285,17614971924071451013,4315185154949417647],[15189940679442874908,13049361174674763155,3157347263126098079,11609609546446019214],[6684709318793464418,16802381774220689665,13797382329569050590,10355788582191393134],[7240448317784789345,18319094842796225918,15956589414722034230,6907923439224027503],[6106749491216019608,382315747424446597,14683955069156926318,14612903063101495352],[7026950916300076316,16498593080219672878,13095680281306298518,3285366313624888603],[7306130188753140971,17070736554541940932,3072594811394592729,10653793656684231288],[7446015495796832761,6628502511719921117,2284401361054965159,8311119693255963970],[6507510698819873106,13097833953320972306,14774377699131941844,13442424979054711608],[12841953666056688777,5361563003631872390,14660902111531508412,9774313833785861662],[10540896754816519323,1746180075358321372,9865956469169334927,4589766901983917581]]},{"leaf_elements":[879372967470598780,4587278670957884392,7240780667591818119,4427829034779236796,1350242719057135816,12770678039887316500,2953277807982187145,1935464269678424121,965148944804840494,15395605914235819414,11204529104338357025,4568713960289324359,2317111467923324336,16162399861355384859,16963535381409954135,5987968777910532161],"proof":[[5315584395816997361,8832392160716320030,12219789663785819749,3236510851401031720],[15365253849779270968,14863628634679853769,9718398009561463990,16010338853250275168],[2987470024740801791,13772766139241697278,3835604489988852884,12708082156524253277],[17934779517264200976,11656763767688750531,5910603783964827338,12433992134522626299],[6023038685461556368,7768993094954539618,6609840278800073718,12082553288388970689],[5951297308731515340,17324232485096321510,4763110575899498615,12299764094155403358],[6064294541870818696,13668918464227909034,1418615694861108410,14140178517947142363],[11336173358147927605,3544125422924662561,6152060134110928826,10783791288329227367]]},{"leaf_elements":[6879911430554881667,5457908162295423931,15028296474674323396,4046210442783393741,9961928499662956440,667458987502983091,16632556689878053945,2071748348740193844,117625768684145565,5084714589989713060,7994625769760391652,3856302107534390337,6031078983020444766,11044030727978740107,14212558157748823125,5335476334763261373],"proof":[[577186888705896668,10017713326479616255,2717235974596937709,3990806927718036807],[7408186873918973961,9277611139554582032,4280019211308123297,7832620401924566206],[1731963949716636922,4896835533387008970,1774743277627791549,15923742504826336732],[5214742837520213826,17181281553215454143,16067227234442976705,12411500705198646514],[16976949461203448459,8268644666328080056,14706620297076897348,10709889567794796744]]},{"leaf_elements":[10594062497747178768,6384452250181563199,15120224220169110739,14257094230388822829,12275186352644083754,13115723322657344614,14792667758968283071,16646530487404452813,12684016013882922324,14181686528498407957,6147051580776037258,12391221252508774151,4652914516088146984,17172279302994484655,4065624863213034231,9390611246858647274],"proof":[[5193648225052607111,2473523997048599759,9699913891496939882,4155138417900049372],[14983243035340635343,13554744403256603391,9231851320950367445,18031029812144592016]]},{"leaf_elements":[1275295786118718478,7488170357634863325,4283449960128273261,10193008459420986025,4238185187837649128,6318479223569512088,16394860438500661164,4148361282767282169],"proof":[]}]},{"witness_query":{"leaf_elements":[8194972504357378991,2045237300670560876,7129630010456554220,1377593890388815376,13225778808178532367,11203090405015499681,514822190418039408,13503170631563890530,9800096139606890686,1958224813922834254,12611494360860201223,3889819358321985201,15044431767365317245,13799562364090914095,13452274794799845237,1878060871584475457,5419814399641046446,15763096374741388738,15943746084275667597,6343642739073810419,16945173049551583315,13512096877457951954,6271567737701049820,10974360090629752120,14814034465456636618,1620977865042894304,3771424068372182044,7101097136579718623,7620461470146372382,4978060001966706602,17625243470415715431,5603016460788461805,785862682295557826,9412761301985214350,8856250700732039071,11646555763698894626,12940141305325339861,4727061854155401581,8287651225067210777,5209624984567717696,5432252829628164909,13892016128673926191,2322688557915906234,8135375165825634602,9987655766604076570,11533499137902330653,12831116752708993207,6681948945082901884,8489858584949933211,8141413200821678888,8750811174797515640,6897185263028919807,14141715253214665548,3758204851286687318,17268695340613238378,16141734664068714091,15514723925452173332,958323257183482244,17204461123889169343,3377988950525523583,7721488333592545610,15513488903205844490,5528843307449102730,7832476735790670520,9223836206204979028,3964513784716545928,4346858980131952864,10659823328534087877,4614920912855123817,5619798071699695471,16778544803142246746,9986039924634184489,15435896749961287321,9867765515409210633,2646237541377163774,1274403971209463825,4836262835899681654,15791967150729579373,16692902580161624774,6403032464242222427,3530622864387014908,16967801172912092232,11571512750368872425,13735956630128755313,5025729677791928800,8972650703853854397,5025950947643827983,1668120286843650571,998837832703410259,3687772684554996094,3073914980332114064,7812180322683672904,8890124137783924051,12468190230936719994,14690663306153931561,14488587766450269680,16855981256150296652,11495880526491029004,16897614341143920652,3360907056923274878,15782030448779269386,12839886904588633786,9489129236524148214,5793524945148801020,1996414395882155323,6640517663572879599,11849055487651754219,17855913729632592392,8433716643400513036,15737790622240218061,13840316447393299135,17838776138506149616,15638171844325628597,1966134965036321655,3623381751078212035,11675754187677394775,5371747870289694738,13296085804981842525,8811523786341558057,15269172399174235847,17089154999049628958,2281009696060234146,6888288411379234684,6780757931728525456,11060020187631823206,1633527738182455049,14789309303186006872,2954844641412185954,9197395045802324982,8678366841698891103,8836898988746361387,3442279594902119006,4421429985638179974,9534239634470442257,17841893591721959801,7000704930367165896,8989246594559084333,12803414095678623794,9461521806225741660,10762830979940991991,13253807578071490236,6843455768079726505,6860981005698002646,15628789464284617698],"proof":[[8317086360917411808,2692816929110599484,6547811338275287031,15579052770898565546],[14479725561573966672,16509514604379943532,12388823110037265344,14892759641705895895],[12777270926663633480,3745967114083263032,7369537423982234950,6313778325047502101],[16056798090215192472,11485936578113959632,7878539198497606833,6959656821417275445],[8548119317976611418,2473538572383946938,11771729781439894398,14493400468900970994],[9216392463846435310,14344822003022377624,11977067963917138950,14968260952915424950],[7181574653043583895,2669646094365652459,2238358074953244237,1208731822164226435],[13149355373319488793,11314837939061453791,17048720494859953735,13510761891958378190],[15572474864816567016,8269607513662509781,18154163004222139552,9099201358225653276],[9849931496962847291,6589575973865425789,11249339439147708737,10853293198168454502],[4366998182970850724,13591029813087103237,4499651039756257090,17395481652555551231],[3857470388238666760,14271942188086022130,8193717118959246144,9218120010045292570],[95410201355513485,8691682845645918703,12963990057706305641,13619932282563402379],[7216492805563057394,1315772107979272011,10481488627740949131,12919072823573616467],[16776836378192897354,8081579203419053292,1861350322693408931,4963880248467234301],[6967107814280536626,1470405342389546328,18406806842200599376,6300959978026716109],[667075809834928833,5991294366952926453,3234520755801828472,11803630721642567180]]},"stage_2_query":{"leaf_elements":[17792953309611371949,8529469211027476615,13779897755286899618,14552790019526950601,3022327612333386608,14690650543985662018,10574712103616040911,10444202355837811638,13230512848691252490,549029959940608887,7569355866746267825,9673549270776873181,8539359218643249257,2415449459849288163,3347252753662576979,1653922992280165261,2091098928723277791,12955764054288061812,1245658824693081180,16966710371949605082,15015531803766785462,18020222866874728328,11447474065443474884,11977521560880215226,11632206789745370737,3896782871561484014,17775364109430986444,9479178850357886736,13931059542326232183,12183856551661892958,16881291722738948084,15471315207078828548,175726850914136859,15323466753087008667,1002111040145730310,2387348610299965829,9886697885770287173,11924645256827148577,10626506543067510135,10467776632057814865,3273728074626789469,1275451858157072844,4093148858673367243,16191495701172398663,8250496879573477839,11154227857109011904],"proof":[[11206312407499006789,6843363400168239577,13226016925264004768,2342735200397373999],[12989306505234907988,2394729025434473659,577683183727856930,15317170239043400651],[6652243536959489753,11783581607794188971,16736529422767034919,9779257963485817360],[9619529600996474059,8473912773490502514,10067308234736667820,10250468474747181476],[9391837564725197658,15860417367177942038,7302938384231198379,14560788988715646068],[7876543884059301946,1775554753855437754,17185110053073270130,13506910242094115622],[12879066931717905486,8780107706790950251,3402611575488306777,13290562965234144871],[8450637607386076971,11550924942756532553,407151687356852403,4993511319676765128],[1268332719865236505,18022223567187016077,12266283000235346005,3126437285763487842],[10348818394692099457,17129661121999697692,6505485368840985824,1146210912591304761],[13680543571040770878,17886200019774447609,3469276473208191459,18359915382471304409],[8385303179066362501,5128159046977564180,17493517885449474974,5044623490345142405],[10658329254284502081,9433780030694349197,6289946939753725062,734451694770851359],[3414980974293201902,7385705770824065625,7625111505331701988,8221874447471112104],[4544529970902379502,12287014608705466831,404836482841693505,6795087536151590929],[5630121831473639108,9467743323625796507,4438877485921688530,7614349880189021916],[9207694402130270883,11419654200426216451,1427563265836939032,8959631267510654977]]},"quotient_query":{"leaf_elements":[9562965224943381602,17264633978783025524,5014881448637866343,16540926728734694340,10098683178647773562,1266067546087362370,14339335590841625196,6632163668859830259,5417520335390453797,3345125525813305549,17998520468584461558,5475862012103679636,16756981737770902199,6668509590360783609,12019618772950725710,9331809015615617344],"proof":[[2846697846100776195,6164501265612540934,1676953079824761581,319539283609389461],[2190766702276215860,371937368901173236,473053149079226804,12346805702478021405],[16248420961647681921,4685598682950926738,10683135015959648418,13368382064054696543],[9574242386788428181,492595658765896607,11115593935192862669,4440185513078933434],[3201550421838038305,9387624028703384814,4851753832451541594,1136037604309717203],[11284904108139533798,753901182078758469,16096652676323342843,522851186256229358],[12799993675497401722,3267417849299133388,4132962126689185500,10044546911551006364],[15172233545755455265,9109773299489190794,6133934439794189741,16092430842164889452],[8006211607604706466,14147947750209919968,15698895252039690690,5200578438098057126],[15652966477189497691,12773122707310055966,7883451322247544414,12764847110081134136],[2507708533022135451,15086456770280597366,11343385649105239638,16125665347147692113],[16059949198058171535,17622496749044692685,15496729348445347910,553537126935354694],[9226025101375535829,14598696553166404990,905469211989616031,13170501862101422445],[4372121375743087175,8921066313376680294,7592936087215086641,9086647131530879994],[5954824331264250053,18438323559916732476,9230887163731788263,2685208380882236244],[10236538253372358577,339371913126775392,15497139557378331791,15213659135913174927],[15302778404576921720,11814066077929029710,10522112645627058746,2170028931474566010]]},"setup_query":{"leaf_elements":[15378864440440159460,1207981962791396434,4552022014971656430,6725043168239332726,7370922046296163371,10698413596771366334,15902084477419648777,15463465091165646633,12762939870040436456,14655868279190557051,12616215451494452844,13553854250507424134,16169609602036725623,14268507600211552274,2503321126744461143,14051270318017298890,10416637136011001538,16936460435552834339,6680571580800555297,4279321981379501975,7754729871233050417,2642253486244207666,8840898631634624373,1717309777344255064,6487526293209164930,3447416229313034664,18040924876068564652,2039689831930627906,390876411159790194,12100103478315784628,9052325942521673100,9044983973504789326,17540866824316947132,2832286217020245390,16079508903372701627,15828608704168877671,3305429949747539980,1645221133907201241,7607355041890274178,1525921393457709823,11076190827219090084,7152746365508403712,4731529237761645135,16225660406091000015,15754675773338706475,4342957012618073118,12465928369879376777,12989700877726588253,6131717092573158837,3723287461018585637,737884156798258200,3758598967811541311,4716098858439086759,1107567746750297575,13588137968982123230,4964415882188251166,2552241724308568052,4606427055677147336,14639262906777109658,12252609894843556649,2765479638342973400,8486273421827236094,16063377896703306565,14672307184753794046,11761386031353711161,12349631418286486083,6526184620196298219,9667248036498540359,2185396585360178496,15720339309145075697,11777990834727761630,2962766008921762939,5343865615759792420,4374970992223034705,2672790900033744624,5746021388554539451,14160748764309763662,9416059171273938870,15492493400719332289,5963185294820651049,17976620534591707118,13747156437970543748,5051653490389200794,12395745310165960278,147949468002576727,10954625889433205746,12268575043480716113,2745915607239926828,11909372941463082276,17293570124854112387,14777538664203137052,6298938674171654778,493126913949224130,16215626366055215805,1562385533541661630,10196113909540285460,8583301678235749853,6581113892971118786,5892235312603815772,2243974549641083758,10823180166300218758,15453160162034812317,9045298271282861012,13645584153957669773,10188705833834944452,5622704160873593406,16976545526455065799,8252922615096732260,9328498540290989126,13770871544214426811,2431704131902178805,11176164880139919726,11356718323968963491,153918530980378236,6967770882157300842,12310075885260039354,2438274709698544954,18260775159713251287,7998989539576245331,2842378717164503491,10709426133170905419,12357149443349321781,6556340161230975003,10884829156311901014,646987482824804391,190125615067880660,984210109595924866,14654765552386923577,2230013347207989129,920127036950751757,14364320968225043668,8741799375309171620,6710816997397333173,9471044678547694509,15972243020076105004,2120263856180120917,6192421998859904214,14359208864954372857,17376505826000526859,9702231835062908513,2411531412438056744,1533209171630643166,10380822412819716952,9096319333588789474,1038557680453366983,12990589663278775343,13074905895186884849,2867015952312574533,16451457890998822942,5283759031214869985,6320228806275981272,15123163683573921801,14774849215635201134,2262528716290247041,15094581814841974546,11157895811101888264],"proof":[[12553222039925461463,17399399478710333891,5038351384233637047,9548139479217372065],[15714750684470835288,18262572607465423785,17099890060218813909,756562155454562351],[11377824465426682752,2125632624401331462,2511466222026048284,6942073071717247325],[18079613276772642903,15167676741292438361,5734261918641104372,7799372868225786435],[12681623775441653184,15864244029522569153,11703872851355426862,13252078684591253048],[11740162868096152519,5919430508981951872,13637530822544646283,1417906270738370101],[2400700723344812334,10278700576901107344,544208603049029197,3472187507209262130],[2311241293364318095,9897611474591106766,1870962991680185640,5227897869280189318],[3849949801029312375,4857747448966078483,13385292594114904048,1905643287411198925],[7837403549015566497,14980455427086347968,18292920054115500610,9011460318277505918],[8677979894893617439,13097273444507265191,7948435178189131305,13983761057063280067],[8188796140544412628,4021551701385678371,13095532756154933724,16045978047673140749],[2075235351824713080,17680036973842022737,4974213996228185280,17990512100330561416],[11208063540790893522,6201165443809891421,10653507730811734984,10278657591870573116],[14139683782483572341,9412805522021111127,4945021700300637191,2565211475890956526],[903050695532034449,1054817570978865232,17945811280864581322,17195504959655138034],[7120720126365939453,9301679779098522440,14567674671977422259,5737163305740258263]]},"fri_queries":[{"leaf_elements":[9557688218409733828,14731007167154246054,10671044827947338810,10671875545233988276,6764558458397500798,7006375641389833434,9966410477390427451,16984732637357928982,13137105575394593050,14020367973196711765,16334592123831350548,12015375857411107687,1438334855920997077,11236081133434866046,6401882687155469490,8133226658522802301],"proof":[[11394352667028938585,7760386469465335418,3421380457913148432,13241485814485610896],[10787174105887539097,7685700637930320833,5593616638548712054,5167847317857379167],[511245192533063296,18000848036717924179,15825416216531054628,16333035365187807783],[15753746925486243036,14500499665447640556,11843536844329788718,4285997385287893599],[6153728857179248790,16993516547814797323,3224637910803870346,4384214137678679450],[1630428840278223281,4948988425736682566,18130132129176571978,3118703582598919091],[18127350089949907448,8561323974547358824,10715822176937291065,11498157258568332816],[10346839779748722472,15881385284103383572,9195403736454344283,10602757079424858192],[14197391178186781943,3451465922994346077,6683241078150689339,7364536172349938510],[13868157727576580106,6742972347382321997,13982194751142014915,11262597369267916330],[10936616530660841783,2412953989065009442,3261163823025819558,9637359944943293767],[2911345195471242910,14044946355338048237,2469247940380538531,13713418546767455768],[8697145523376735944,12323198033727035094,12122390477786416236,4964968718143400942],[3402040197144832143,16624859650092102648,9771646739874512713,9644679865246592281]]},{"leaf_elements":[3276281469159713844,4283756599589146554,8445318276928308965,2609096807184553852,14232045654815721077,2921293596669033384,6022205262878592526,10308439799026609715,6422489457114425795,13247827635800467481,2944137852578860116,13417600711733582182,11974101491704611407,16484506395602868385,14276088355109954606,17564254250254203779],"proof":[[3150262627880671787,14849299159886671802,1196344989238046367,7922913546107236509],[9426538305572839868,15927104825553331523,5449682718689179761,18302886054527833648],[6071497599562709674,669519566946132622,16985417455979054876,6249320932933362872],[1377341251680624482,13422441922497013804,604206524285819158,14999049108851701446],[1852712898182025951,4211505937000388229,5596945801499908635,13651123460244706604],[7283057823169151755,3880837593645249827,1239118988454003992,246267012440709313],[8109551355497277997,17382486038947611355,505754520325642705,14905622487371616663],[7219155190683079156,13278727009194175752,12013619582869303659,4005578830118635892],[13592761786045836074,16438260464804926172,17041681858720181764,10262031240117685990],[12846770010313021474,17887961240957826125,8592255928138321485,346584178346993725],[18351435286393245396,2865657294868377891,12507805816395302687,10169105071705863335]]},{"leaf_elements":[9489986932045307664,608059101105889639,2414012079847546529,10840600183167439305,14039165008215128372,13483197549947709976,6954745056321193288,9602120421210419362,13580931837489587417,15498453918745562780,4150060078587255765,13500164223488863031,9156696389192772334,11887069882769328017,4358974428463051447,13906451855488485325],"proof":[[10000353329488027815,832190043950799954,13784479930953205040,4175837197203506735],[12461159463214577985,14249454989674054296,4655917732410036798,17753804940955939364],[7905703589494561533,237278714225422241,9270048018852749697,4018755179668573005],[1737458951476542712,14339050105958772878,16927593938134666136,17519387355342941659],[3914045133788226403,14759233291208149664,10846885218648675623,9049077646562807712],[9114014921319346376,6301475647408146346,4598658578464543408,12256320417673836948],[7096964106589829956,1843995992751235698,8612477056013154565,17527362827534856819],[3007305652148126886,3973547783666200093,3625693024435444758,6853635343299758316]]},{"leaf_elements":[2376214632098711870,6043043529270339359,13230781990314799858,12100398948828759617,2537672920111745623,12188197094714700058,2389581011593502546,11479574444508209413,12291971132741133579,2663902487090936477,16216239018062984366,4534158853154787237,16931603405091114194,15543454542565957984,8504072233596907403,6186139377223078577],"proof":[[464461059976463107,14688253662596123247,9482390865688809559,5099200209823027370],[17913756765364410128,8295259903309808998,3303300363829194121,2891846219086976449],[598959727765354097,7439756908094140783,1624876239118251380,8949848834915472685],[17404052605182948704,2046680756537763799,13773774237465136681,14799408032600173066],[9511959561061228326,12142498241637411804,13247686500668664919,9845123999379242829]]},{"leaf_elements":[2724040922911492793,5087103980458597262,11299591881328374180,2673049836433349821,14905235852038124018,6545437964311646289,14368780626907374199,13404306886548389772,4381156114158810945,15706572840247697232,13913053587621277295,4567537599877316798,16719643124784460691,14674271351025365586,2243864061417714005,10198005462100586264],"proof":[[17014255528778501771,3434765702674004882,9364355926509270905,4578477942722818694],[4012994884363358194,13188108686276194801,17251058977930729867,1715204375964092596]]},{"leaf_elements":[8059053765769322751,13417580637374693909,2911351709503266961,17513728947462283680,18357528550657626748,6795100929311303227,3237676158979040141,13444877005340907045],"proof":[]}]},{"witness_query":{"leaf_elements":[11185017973793996806,8060040951048928995,11749882044693081539,6574018024382036072,1093547855723659260,6782088214715260682,13069798981774462644,5574007687976773517,15925742676921637715,10459938292289902987,5636711867263575788,1828053159185231541,7809312017770802447,13113783971718287789,6306397574335451299,9890704837794277317,10388460231815997619,6019501827966292405,6752709702416001210,2135336832558789807,5862984259319156054,11855379873673637375,4558697879818875141,395210331144490277,3993103637487793477,2526266078413790488,12720816990936787774,16968257217028702492,14639475162254202438,7076835168248048506,5082946337002270455,17988709327394111293,6024557898930993701,18006567449366811363,2137582338327734461,13865568341523809779,9598510265263866141,2311488421516927764,3998837037419873886,4792319565287380781,11682597378314342349,9014818671565429611,8428882584054245260,17540628972522864315,3897787330025615878,17832751244812191773,5671575146420401965,9618637121803885531,10839360643840883315,16761964711292892436,15289104322378427123,12795853274217607078,15977822447060373072,14813530519747524673,161323360929286595,12409383416156985686,12225822024773839173,10761557779283412237,6929984724279282502,16924219084185851086,7637972952681459850,5112312185827717761,16755750497035033918,17408231952388382627,242648234772336383,15677429399855020852,7532637823280299104,11393090874997087011,3201646453805062345,14691776952084902961,18287172272268070939,9215726767786854222,18321483032098762111,9071271700410538643,9466308555738144471,16842214963110849780,460807535909798048,2926230148577107038,18404324096285443138,4661383049252286555,2765755610890902312,9489964792281177712,8423660358169170638,15606518275374176010,1225381892351040972,8976236852948460653,3183022082547825029,2719710111847100994,17896256227662853305,16594894643982432905,5703212652455531169,6015119162771139197,1868509371340579490,15661846977774491417,7933672782690381818,14283329033623226652,13680152054129773140,4739294480709852756,17432067278148354176,10286419146063780161,14941534116791571855,4021853723789512077,17583441608230739678,13957534878313077320,5841387587911706368,8287630410177062347,12947543235628046959,5664400155568032409,4777864920639474075,8969874658213534452,6624333684593343320,4413938046862853336,811585987896200451,423461522404036499,14678375478109027953,13551836859028139950,2236274229053686538,15483593788629110559,3843621952388043026,6718187060858422486,15457898946173496145,12692025396207299665,18022166594844655831,7214077792912152432,702730309012717284,16890987422688786183,12359139702238968209,18008729084902007087,1576487444411454460,958076549982275837,12276710941493610235,15627402017472330438,15815280685523057367,17134707660306959748,18298935344903917684,6245563247995858899,6067101192554052175,4576151484727406144,15579490312678046130,8030821235621798037,5598529499922499921,16050900971385493638,13004799695407031794,5181627710929871357],"proof":[[15403577749391356522,15949187606680123745,4034368745902300803,7535639501663291483],[942537277084217775,952134022200269352,11980187066022385911,14980546761545174304],[12797861475724416704,5345950766994966969,648884158260500205,4074845412109950238],[9967994903841324122,14778326534596119024,11296889122089622300,1028658472642700330],[1943575018974564707,62655664229294417,12889104168263585205,17790831328167037418],[9153914835970962875,7628860024768614090,17703354334179208623,1826399276191226662],[9881845085837129394,4956020465337462431,9311258563130057224,10008701542245149910],[2100553897880321816,6954867483496603940,17604047852920589744,14767096522696618658],[14517736098394010007,4864296627190770474,1828161395509896628,6049987180260098542],[10349676288247521392,1578100883560585940,13758548991946268714,16518670117150385323],[14638100579519028708,4884565205669505655,1974041893837543991,2512659066688640634],[4019547399537004279,15001134370731846398,6396438392437630427,14578931476189380781],[1635215649725777350,3047985408172623283,17893650606700089930,11294761984954965792],[1780144148491350298,2155095951104267255,4033351031373621124,522336819624927246],[17133277740034451421,3925619382089884750,14865395413370471787,14287208841406747511],[6823154124807899260,7966338225703430134,14719678606785559608,2396330595089434142],[4209660706171061763,15569665661657088303,9863745563231888711,4660762711415287022]]},"stage_2_query":{"leaf_elements":[5477630488123492006,9899173703071163412,11858979609972472934,4755512224943076548,516752597665573667,16300126281604962927,16278451226274780302,15918782521497675486,1093902183854471538,270886592142017333,11992631601307681693,13866904256523144939,4866681941288703109,5575925846565868906,16967749107100481305,14879892900740639298,18084862690568326673,12291168328901943894,7939926069148261771,9666438962860280982,1505555958791486403,17829203113701030327,14344231600469906029,3383514551136562279,1371813190880971431,13324040931729620280,14167542591429564191,16058799230778465449,3351683956021916320,16172804770119933703,15756289454132592038,5907459997202801546,8292605753542932529,15858012911749053660,15229528341787684035,7302393991156759168,8919057600751142004,2114247592709672184,5565429460119032030,1353143618641828496,6533161575223305940,8284145342051919856,7899790231993713187,15609261401937845060,2138299062945925871,5642322260050331739],"proof":[[12961129306972110638,1870563093024912527,12401827464331813542,8508429092235227325],[15742819402367559457,15952780688302127127,817350975828787474,17489061657875457325],[809774365796945842,7853820034922223252,10951186212166017448,15616727618936551279],[9937761020964523848,16162846656057072755,1501782993103872387,14171812392004939420],[4217038346947207451,4756805764158856064,8912734231303719920,1436020799185693598],[10956757131794070516,15566231548914241027,14586567378264397206,644339492141906326],[8927337816292145896,10956321463969513856,3844409915114622340,3649868550783589718],[13273108310499074629,12010967744566774639,3151112507943289577,12365620775374865091],[7720460361723542894,3383908358668297006,10657970337371258173,6946304926649450610],[15265737062244826663,4911145947732074386,10768032280460633089,4107175478155019062],[12201554683294739705,3732133655835936770,15839382541068531236,882977882769114199],[438080098031960364,9477152070332013120,3999799191286155281,832782569866730838],[9783347773362544723,8552562234287775331,13008976758801532678,17368643777235491022],[7543076544285358191,8013294620812278051,11971703971471594293,1449228209859823576],[8718175688711115968,7807439757818773932,7964907846796814770,16209388904561797611],[7162058758784531182,14467555510605993018,15067973510751214330,5027069747263159001],[9665480788566780535,15441174219972231479,18344208163066031937,3462579523809054127]]},"quotient_query":{"leaf_elements":[5953484658985098740,11464704298595719679,15935159433537352385,14650166768389169615,904206499094436833,5717730051503423768,8405572281742188393,8911388891589370947,11727921779223114202,15835491721535226635,14192933831764095083,4223214035243577963,4263219662666105024,2121189344512013926,4434709550835357545,15012758519810416996],"proof":[[8632492872470951608,17691764167466122365,760992744865647814,17335664389135264129],[8767015210841908032,11813648635497791007,707324584318882332,12598215502035214781],[13534575332499038871,940847322982671519,10620179388236812918,11136093796123322976],[17626650243254190163,1036567796234007695,3244429801119405005,1928572885272401491],[15400753240913871357,1529722915805029251,6082957932451105926,4945335056922238066],[9897936718297261979,8623479401535406794,5735755060393869683,2106273730929127045],[365482481607448134,5649682975025190643,5071117145334660968,8245750032321390480],[11409334823253785642,2205150434750933237,7202335658788276667,15972386994413096899],[6950703711797643578,5752308330787215919,15927698827918351440,3215084111624826328],[11674580437379961966,2808932842724390349,4110128002825545026,9284635453456945342],[941942678417774533,10233010078688049502,1029992437991197924,5851962643385211944],[14454992195862216412,14472427308687560013,16633213229329020359,5567660935318703425],[5407811668282942097,8376796500896318046,15353392147500007331,18204653504900721726],[4153406512893777453,12225179825409211392,10226311643125535309,13042450745290116618],[16551884140075363596,4698565463580719340,762919422797111181,4303123538301021669],[12895396197185972449,11126740586049677724,3419648526910130387,4052341779871279080],[7272481940847367093,12648501695579666994,5565709819533877885,8039129685255867198]]},"setup_query":{"leaf_elements":[15773434346402008045,9861449120825493733,14087928112698538333,8402804825840668118,130134880909006869,8380380273752820353,5692082636317386635,15183074866240179086,3857724363088199214,11565167892533648971,14373687411153924075,2667765096503211570,17433158770981693689,5278865232212545548,17552526197824095983,3094353777730668543,4857037556386099094,4992025088991759294,5076834409375244672,3755601824134375875,5605642948495962657,8790129583104044517,15813976973780444406,11898031961365092986,4314845971641596045,944232203002221392,16093087557287201248,1032782151756560176,12684087410716749025,6229639055987772706,13248045352184538756,13915744369379642505,7908328521590275492,18266202066244376300,3206022994763438825,2169250479354986397,16153908246238391395,8809455981468346424,18066202001457285400,12504299497783599847,8872065910161922523,14978400765768941753,413456809563547579,5613828924637920918,14864123592735565026,10307094153135053899,8464621913588628371,14634281122139039793,11768991786131949179,14694384449920660500,15301912837188702615,16755104168876283669,14350939677793546641,12286625278520039865,1161290703612254398,3743345595350448689,10456539958336373578,16820130672960161670,14860414211885971810,3094671921982095755,17942662707576509559,5709176311945195513,18209341592897981717,16409443232659003390,1371636737426295208,5846452543116931426,6436685472100602664,14546683969722793248,13177000351117504281,4908578607659702167,4809461667101613150,3943233908057716762,1147677830031065791,7515380911905947580,12814180334091187692,12842503350192298072,4690596891689260899,11711033863248910052,4661063549970498270,12495767874397252310,94491870178409743,9725861716071412276,15362310880034046961,3287322679248139815,13727822354359732300,7465741066176370403,14557712394528638856,14799078591743167729,16894553324906131677,10674516424771601711,8194051218708139713,2380080173539849457,4719818904163036571,10243167793697307948,9272042900306287902,17337548686944004151,14530513514169739094,9509260304870147952,6846427377875938021,3723559296305992363,8984282349432114982,9092913181169297904,9715740677735908008,15671621624528035275,13423380455635064128,15441934457236862429,12103322951585734481,17163623102510349045,6827725685822477260,4453863643001795891,11623308008836497796,13392430400791818813,10675371617390788812,804721942081772851,3235144629896634174,2385314913571639197,17201396805572592857,5197686241698344210,14235210160858880203,14610495898180047650,2673248300466183186,10133716404218879912,11361132295586604484,1163965939637611623,1706683293280543682,4063416352947026409,5204400601299110800,16585355808848522011,4882010906276445774,17083059434140329429,13778472435671389367,2948791073963402757,17059670850065704278,6482565326984813642,10915013789868115448,12003719444419387795,10212635532928166544,18030946145658042392,9712634264983978135,2055558933376226644,14075354845448973341,16803668429097059988,6969143749327218766,13322019927689743615,10754776669816560750,17327076669704577330,5770521931474696755,15600836530788910029,16958550722889082417,4981336258924967024,17698535998560530567,7444912420650678049,8373615241067391223,7050681069290963885,10818126854614711972,153363167220001453],"proof":[[15612151569421444395,3684237441595699885,3509909098952999194,10964046224712139155],[1540856527397843581,8208847501482500162,5779247833305237131,7808145591125373758],[2521904537289558499,85015908318052705,9455967826463731514,12017599474342349377],[12897244682932564696,16126789454054935362,13242734633038993186,4774881350949797755],[3186390219490140901,3500066957482991265,15780076121395337676,4655631623630152327],[12469053403750152849,7398355472956110611,4499881924670395732,11359811629104633542],[14259778850438579860,12330311613160516977,5222937988545375579,6927149612543308009],[8785055530289565641,9439160243620594230,5922675942685146250,270531329650243001],[5403488812541577442,8139270260197520143,9581002495438824281,12464731594581708817],[16187576741841227167,17297250756362857805,2690182567181478031,1864245621617006392],[7966048010386919774,5769871877511424968,5456629052417100616,6531461651706899468],[8844420940244844776,3325829131948261852,8848250132126645743,14851416073321417294],[7252228647771670219,7798224828866918166,2201485509031167992,17455477050432712529],[12630167592258518666,3587984956356781952,5908326276628294855,17521058886384427440],[7859021983496320513,5119598823418330715,3034491142180765991,17739015609171948451],[428113797058758715,13603508601850025584,10691442901423439437,17871764610276256917],[7509741136347436482,3376409090404699080,7106851404074101484,15631598259633138714]]},"fri_queries":[{"leaf_elements":[16133049258367656909,18303707990667160619,11434955286742429076,2615645702352872577,106077820468974646,2632002178282542695,9521235588639457625,2809938965426905932,4082015091360008218,12576919092368301670,7154836885624401830,1436736868841898832,6154610154087349848,16052498013409327275,17203360162328607732,2686530647230954394],"proof":[[16654406426071374690,9796051580639085913,4087610454981501610,15673930082305311580],[8457907423999212221,8751668357262903407,16291332775785942215,4364732894402016103],[11947038584184709789,8850167766268362458,8629848205517275087,14818258784016753542],[6939729525497097289,3150385570623320533,17390916593931905468,7686440016667645631],[14975702163610693346,11898030113002748719,9125367588434091648,2081878310244810647],[15360116978110106595,3904101495835502847,5801306896435519540,5997715003753092310],[2743632535219285837,4149893357777468658,18378061595438554856,383320113275278055],[17969863479598645264,11845929193290119756,5158412977193577955,11040913088261754191],[12475195904159415806,11278487367751601172,10589540015796415825,5883099887437942726],[11239642940219078050,7847572549178337715,16384063364470071640,7977333570233144242],[3513989283508986989,16700777469177327540,6418351002442034590,18182490472036937660],[3736524528917762705,17587195345688884363,2756669824450137931,17514543130280997302],[14115097976854659465,15136337476635248132,617789316714937483,14741986668452770457],[8305776603362009226,1749975925679637043,12013609855588987408,14181483331819815011]]},{"leaf_elements":[12927124592350374795,4648716535486783429,2182005124946145758,4977517001698346327,7829573689447906849,5572161856506036488,16866346247237906545,7732761579093241763,8940417462000492406,12036304968924705291,1701565515301448158,4371119978271563180,304280106262198843,2825396682722193234,536373254469581717,9013115964590953150],"proof":[[16094837916757435527,4373790435146792207,12756947891103436345,2829949186350740215],[5324298140309357594,13476051514178185878,11652645443883168189,10043770492657452206],[12447336424496248244,13066376740774185150,9785056315709231975,7168846950770017615],[17284857691119129246,7694386608014034728,16884854885427872227,138818107291726934],[10397609872995281762,6026666752306642970,614432548068333902,15713869225083743155],[17273765820148971378,11812209888980764221,12703360037766626774,8709599299235130191],[11518557386163868322,14745812680384726598,9049350435920439502,10718805541578260510],[13025650076108690125,14050158445874355065,17029027386571491611,15325955075156745778],[5797989367219509013,3503535824447403083,10850198249495850355,5353779394641423407],[7043298236281489658,5602865514217982209,10327341924659808751,14784042079067273139],[9089877299035286039,13211086284025128974,7103523635707635640,6143338230424736938]]},{"leaf_elements":[5968545869466464539,6283882317773040070,1925109968049784094,15580182408325443929,3099129040479836314,10277807868387088007,16026755503768697038,4342947763623626742,7987436877375064301,4512168500060005731,5335551411086571289,565321236900339681,10191737399599798615,10940292282392206752,9975819192568450070,11484810826324381787],"proof":[[17762210969753801902,11134377691083800948,431652372273566891,8834041201407746119],[4667149840866822187,13805399514824191785,14590330202904194648,2416296960677973416],[12200195273723307307,6201716979269049079,16658208021316772107,6666293202424989830],[2971326464913475551,4044126430705846315,4715740231372960894,14685491078375443843],[17697705330146735474,3258350989583179394,16225192587086444221,11216496792994199594],[10073800714633074503,17308358430428381832,6877390616743430192,7621136530696839583],[11252694563654801628,10472470631434382152,7554028300558442778,12245882522027797483],[1523028420938813456,8383364562886835624,128497755588736195,17828178017860490490]]},{"leaf_elements":[5105490324300240177,10494148814424067639,778397786818358919,243861842502025842,9717566201152336322,15348007242213891029,13340816727471880048,15138353207556062182,15252357949407298565,16665934200855651114,6006756485782777287,8305011758366315984,12178177457356086557,5676041158718256195,10982687090191921305,12230817782772608621],"proof":[[9908655707797871798,12464802506987596063,229578599679129156,13851644824609953797],[8406952543579793450,5733823715510069003,1719774694614205250,10652056424884763291],[9974695694623180362,1449946445126947115,15881675649240304536,14215588421949939444],[2442968217613959615,10116005101438868226,14441291019434002343,8737391483828600256],[6261215226436674216,15743080239327813690,1842525900557292747,17693706794580574465]]},{"leaf_elements":[4055331174193476774,12532707642948001435,12022388871363304741,15867611124762664086,10963337660646232085,12351399747807263981,13060729164749376717,9887290939388018134,6851889979818403137,14974206683912561298,7041517762395965468,3706114119568658296,3645262288933893539,12210277724026313443,4460587325738147426,9164151194468956853],"proof":[[17344826569041680859,17915507149662931101,17844090822775430663,4162774940712551771],[13176973524804019933,16965119035393196808,5769199517311706096,9495579311777928719]]},{"leaf_elements":[16371276844632437187,5763442631456442294,9612659274689155166,12661874354129793348,4727490084259142759,16024340444489255688,11060965350812909448,11778191179252601154],"proof":[]}]},{"witness_query":{"leaf_elements":[2922953134679865212,17874289661780140263,4047473165919357301,16985926186506045271,11243623030758277211,6169259344187180473,17699755929299442704,8934428532219992307,9597927082060135232,4392481630739932212,8169308788542028413,14275881514920630990,17557668361609442625,11157545846410280270,13087308264551830733,4513625458684607100,7277820783460194532,8443889627769685424,3594577235854117102,349437646304967750,290862283463487252,12892635703941292684,3104776555936195021,10769967265506725375,7652752605827076481,8596960102285712098,4267007964929213392,3787208111292530379,2416269921296010675,14676259043581812971,10919282181296277510,16807821762262912615,16696482276976228857,11658573257157195595,7478108598016188797,4965281019738780194,18159628544768435044,14048169978659612905,10554276884351561295,5730368421774648667,11272302288325900450,4089088074349082670,7462401298562590710,13800017474639219659,12068960750912039070,8753544990946587144,7912186804650844008,7616534231541189991,16635436825849006966,6703114358482078704,12289418080553098599,9801563374228064952,2886065567086806586,9555504037249285570,10872444166477884801,14514010457292344993,765846184260187793,4735380143533014321,7283378910341789014,11759929106504991890,17403058689992493170,15082575013347453818,8040401452280302955,9383051026739437515,11793838820776864738,50182940073338942,9605440350407228848,9839614891724439585,1127770271527838726,16892024271918181791,9844327950860682646,7789495806001264627,13763082699138725107,16452382557271144075,9657963769302778255,12372007763449651209,8157421211071623218,5672703568101962149,13497324099198932495,10484177644430474293,13396144558991167608,13917675451060646511,1406570970357400568,10123557530172248746,3358562001227302593,11216611328358720907,11145479068853557762,12351524159987200320,6890013634867613459,11940555642356779133,5304347983363333497,9948831622670483893,6426118851597070382,9619574175453202834,18229927101418610543,12422659410326478770,824374497516616247,11575345950671155057,3640832212335777638,9124279411294560987,6279580204201200540,12383645848751729537,15057354880355378404,9014350385362145447,5088861610914177525,1540750298421186080,3432382235233350060,14740067310518433732,9490608023147473740,7956480203242682085,3353193365589359328,2825974501630985426,16721976105507985633,18244823150923993850,2474671676105919112,7408511907428415095,12795269268142856430,3091043331333528597,7484637617157558785,2179052361357654747,11153410874980607785,16682242666215207821,17350042839776395641,9321418278485767729,11189715891718573704,14882708308069874352,8356274443611251334,15831242031270934326,17562470712327682262,15436750652704902107,405311071603571736,12639051335170287541,3319230924121467325,17004446541008689290,630810403296696416,2631190470051589873,3767701821860702193,7442103001505513636,10806250193436985471,13561090826851762685,11866343768231422514,18072063333122900423,3836145349795812470,2679219265646096781],"proof":[[3096653598686996983,4169819521918026373,1958957335269816405,18067715181357202228],[1002566059086195513,4780254296041487785,8314084260785773859,12342319058196117148],[10655909226363826961,5120386159657882272,12526446443033027573,2200037097122784749],[7035237379917636036,11182658469974129401,13835246737208265404,9200507690243453432],[3337439397690768707,4981598835659318834,15735236337882542937,18390140370516453703],[3343096995012223095,15711209143924864349,6996344017813564955,17111039252151958701],[7754470528328947280,6616933061543513526,14469857058527665458,17623210116553907151],[9934398203340410500,10951722384851211398,1445515587182294436,4189992515759214385],[1142814534528817475,2301844629941542908,9128503162367153105,18098299153099908418],[16035773690079203111,15685721692249896022,14852848849537817733,4036019877857639020],[4565700936663473124,18187172194502557655,361926045976846968,6420632277882961566],[15787932172391084630,9793382307399952207,708355592540645265,16108070523718439924],[1544573074269951265,9799083706879142291,16906397716553538221,12741873027211226133],[387082535477455768,15219990329182189210,8189866092614685733,657763993357938607],[2659060738251997370,10050763742789921527,15978518701777175000,2443309892177426546],[17909269620353864015,13261051985899087948,12998451932328951153,17865522459203578745],[1953798436690953238,2147321071292191388,14284794412897050288,10182010349254562119]]},"stage_2_query":{"leaf_elements":[12353174672845611418,11285957679993125648,6207366296990552833,7876394489317295162,5396042598127634794,16551084347272369690,15589130667364481668,16641259201652104837,4287394226390358825,11246304500515569696,1302475995866797916,15566057928374426558,3537861961511013299,7987662455377259942,8986605794614867233,14825907792157968045,7752898147234718512,104462407589743213,7220851001860114682,13617585141589470534,2227994350951422310,13397161966323766404,8064762078145273892,2856336076209594607,5826372799035229449,4024788123277376059,17071426767051701314,14125569393074032910,13862340450376210112,7812172965508789433,4215379278701598155,7269434023296904591,5372885511609725410,9016092870777499133,11219756024973388227,11286466460224239658,13990526160807293999,10746634917586626749,8030583196448304606,12378853013379623995,891576693447635491,1387378357533808453,12763354073184995760,7939473070387397818,15541513807293792389,15753242301353559646],"proof":[[3822694154890651699,12025026938819336685,16037055096712159189,1352770518424843320],[4406622924328887052,13164767277639651030,6679193019821361173,2407018745541945232],[6518453006865184236,18342598925808568356,4982143431558806262,16359247530384223254],[2186070857430067213,1894835344277541609,13271660590291513959,1281815868437375030],[13347445304827355297,10753371804864506051,15176896899895593845,7309241364007025427],[2531961482260998436,5378291746985498233,1121880660379154786,4202571636291736124],[5449896257142585549,11341359419395279339,7492497828848227266,9828750428399760785],[12248937465331213585,1647656863053239691,16897890539158027089,10982495781333410867],[14554369712263499457,14898155461496937269,17889866756211779232,12194724800525538839],[16486392755219076153,8454508168274517061,12769267457421930199,10187138379334761618],[15020907430130989283,1451098434292514751,5528191236962995761,1071839483968804957],[18220674645662314213,2729533954651069677,3184996663941708132,17325535761504657536],[14570900212193913327,2415219944327468090,13952157789915959637,10013415167850621888],[12453958666781901646,518069078693803201,11042666845185610846,15684560293444675271],[4101627083011103107,1002209927757219336,12102686251851698166,10425869972513256031],[10285956182066410551,13835665182111703010,11561955299191310775,12519120612921197446],[4885762215220938472,8498695306163120439,15353549138751841550,724186417904133468]]},"quotient_query":{"leaf_elements":[5802629851651220226,15089803933685457442,5076223254900879511,14486050613818961422,239830983613994221,9222289468648720698,7377917189030366079,12995246684290946202,4837079074737961644,12371299510355375542,8430574337262088016,18377649045248525300,10825319958322494538,5042516741038909662,449957291649699183,6951166095327584138],"proof":[[701756252697616125,12127207885382459996,9509658865498202269,12195472214880088764],[14848459641949541920,15509878126906906027,16493407715364492313,3473617116345203681],[5901811161906914001,17482587963284454754,13625304073392517183,1683182360927441863],[3313487252016875313,16476546194262540868,15279487208989827027,3767422517770517406],[14294413362383264227,5208824067275092627,3362609115427806335,13643548963642927150],[17158467083652257896,16482217662007326262,17399753965984946899,6979017119772298790],[14022069948569685236,17146474367583524526,5976049831276462329,452275337392428488],[9421059293199861186,897248071845178406,7710989069580055213,17412127276549931963],[13064595896285000946,15259569182147886938,15442920800233448010,4044620118092585178],[7602209511258397777,15907382605494908989,4412964085187676298,7525870812169258530],[14814127448583206825,17869514254311975965,12724058278311597386,12973730470958110658],[12148486954346348653,15616269138839225973,563608520513572169,11712066934075268213],[268632461372357711,6930206956885814883,14545807755298573493,1711051471491030832],[10362373941166329374,957101686819675710,7370553725610798807,14393050365497470490],[15055356226280532834,7476384548771162125,11942948857821119622,12096315940752998014],[12409159067935956919,59240917520353899,1749013461618880112,8027725687825175896],[16596895484028765537,5749472348574443297,15124699585505040979,10983306082536664468]]},"setup_query":{"leaf_elements":[16823924434274507957,16208854688460211852,15231348169207871279,18002474037797662069,1147696919181838452,10255422990032858480,14974229271333666258,7601258963462227206,11224528418367812848,8124228217485230260,13910733155146587257,13089779659539802343,996877436296736384,1208788828550088886,2962680138085354581,1758476321745367799,1551352525919123909,17477527118102015848,16858166941678730723,15388132561079975887,7268429069951870157,15986523143750017584,15067201914401099598,7311917994588684441,14019878186538694702,8583661514226033209,11028330397373390088,9858726223985623381,17947171747885477589,11355046952592626650,2704998495952935358,6504955299629021520,1731001219212264848,17381782234100994473,4644438885562413617,14821496172715457970,6300074508338815293,16824051172852817412,4997902714607812363,7492877767760473763,11147880809118973742,4856645068109206353,8800780049667726895,375314941049813830,16577553255312612322,4013445326122160831,7752679979080293684,6987480840009445985,12909575125156130188,6760371627573344215,12537214669233578872,7536291133775841,16447481590431908427,3356096151470848441,14405716578793014934,7562874214537669824,4878233766991442225,17407562464964009504,15646332463435704532,807601104305109438,3821913809446837661,3248541986718958506,10365557298714987087,5933853960242721227,345079313676653984,14655191772907946238,5827434375972862793,1548392923374689194,15014675202887260908,12273520522507299346,16265526061527184250,11256429594169306482,16623154661075182201,7226818865839714626,10255176444219093084,17470153561989352372,8859019119824390866,8253975596848024301,6068437492356076529,10975129002074408091,5800837268953398472,12316201158914229537,1927348692496139360,3462925765698085518,3165295099597221603,1551103443091708254,14967876885148806640,18280945228623386020,1276218340929520877,3662617014079404318,2122043220374192505,7383476493725822192,2451798114825792976,3089928177590408696,1733010815625699625,11948349752128272428,13180896196226678939,17767680906216961834,12317322816786368857,2141411315912335467,13808678893841859298,433648613928884876,1431948547937695505,11872573596453418817,3829896364228702939,7397921845067155946,6326635103726141630,2203183975270220028,1866027793905728778,16137212968486880681,2592778853783020249,1301295832984469793,3962575846783549566,17221546012694158632,2418420055333130454,14153587705835717308,738790091934458468,14146309863414030489,17349164412770943619,10342404157048203827,15858198247047278872,12753034553569589167,10065787534738181121,10390526776515336214,5594876937013159533,2594526806209500122,9329101776776530985,9404606227386472284,15314465140971043658,7001451251999530429,4969372014671506475,8633357580488484660,7323018262548916997,18043762483823148937,6667130984467521697,1536411518576051879,15197688743639745043,17381655987138163908,12351085991054888749,5732224316881985896,17447923435572244957,16640351091255743218,18292683521789303082,1832695739975291179,6303485317869408377,2303250082070724291,12778771532745324775,14751736695066520508,8818820916381841957,4796195358327230199,7541151162404319258,5439099864553605295,15497400564123471203,5724609020646723156,11041216596461558043,8786655040026272603],"proof":[[14039462944157605319,3542974148131630546,9424360235345303865,8602989385696218473],[16241773351057808467,15366157945339804150,17624204367337212442,9968674349753291604],[2973996133689894287,8443721660841032250,3076218072299941150,11245108166165961497],[721343201213312133,12223393713090755545,3452665357603227729,8739360062886772044],[16674547018272414687,17684763514026823486,3386577355345996024,8464300368312953682],[3505571574851395746,4230316405204343045,7548091810675386940,8488024685567641865],[1286594013351239627,14706152211092640921,16885999557934262341,6576290596766395582],[13158772820435424179,16339477123290645386,381586081826292908,17132215496563364329],[3778733344290142958,7646514279602573691,11820913303219158828,15059601825629346940],[11973613450208779630,18384369601451497719,12663015793904464727,18135138803207917940],[10720829329168616958,13862622407957064839,8578260168329752502,7753890484310990957],[12292531228898729407,16167177525828371085,1610205309578497128,18131665444927841809],[6875843505072068697,4686030584373393107,9092777592050209585,13770079760392189670],[4445263015164094605,4754708159751809073,14538278862994279810,8214460809820812198],[16447370809158012384,14738976981363294710,416631091641927228,17508451770057489382],[17608365128988463923,7344841169915027559,738053527282489032,11888854221056382987],[14058783525262674831,1223734685381543111,3472322076695179989,12739283938439908737]]},"fri_queries":[{"leaf_elements":[2180075908367445965,10287874881972431460,4999868037456443964,14343702116014484367,15119959927076398340,15381063694678140782,6729871106799455622,12344801657624020167,14328781646275896023,955924865873733025,15505741465630926156,17257491055988410652,18291665152952224059,16018303282507194722,17945898163021321881,10666962939627737965],"proof":[[1341435234826635307,14291185253516771399,11966958237681393962,11326490360873037274],[10150388646541266581,1339050985848771924,3974988119924419468,5753216027627029291],[4337750917727689463,9520376931755589801,9742078396896661687,643184399665954097],[11540921765156288346,17131110965898864499,10099289876172802309,13542381595111531461],[15353711844242893613,4894405045695886182,1144406796505640480,2171544486652366168],[1682007259862208879,18177750694104471996,7989404494869989379,6424313318632940180],[2419333705326292638,3971125488564393789,11657037666803056110,6000653201937358651],[16858991759747319270,4037932432676825166,3543096646493758357,17628772193393633307],[17954137606016947969,15134749063485258462,7656451374461827584,5663743796940161236],[4906875329516501696,2582294891860490300,13136191308008720243,11804013079775089034],[15540809639294792187,8329290651236055191,3705098786913735978,17507390932939780437],[1037063230749843485,14664610469762288220,17304294991658895028,10494434248729882993],[12279769678883907016,8497946479353562168,15751976405119165447,16636282989174434406],[10351333275933153941,12142588681261912147,4012798614446165582,10948289742999808665]]},{"leaf_elements":[2385836143770459656,15574797709052094746,17144272080404540361,17564072201883435403,2158091430902279775,2681781542909707583,7722762189322214187,10894973974387318047,4936404605677601289,5868229416652308812,9588830708576755257,4396865953742741435,4593164519292665528,7546013112787071958,1641691929643226106,11267146049994951140],"proof":[[9835573948080753488,1935699118376115779,1754856053183818723,396812198844402676],[9208806679992541695,5677171275969107310,17634177548325023675,5677648385976742610],[4860469475942308923,18020370291527521927,11353261657761057526,12465464925314213970],[10463185329631656230,1308939476228600093,7231649905527479619,10619770188197067664],[2942474306255039028,15719262043004853407,10134582347286807425,3136170524968751909],[3988703845610203363,15097566402912487431,5818766441409271436,18342874257540710525],[13301033930225342939,13706110074545639747,10672148150614987795,2609545950081648850],[2983233124103102530,5840279662687789958,322475114996106207,1094829979637443674],[10171554260426052666,17513683272883220251,3909061854062562472,8975664412270468325],[11765031133761408434,1890238479774320673,15049995794057208018,9377104703358117550],[5276127892358659024,16578295356712318542,15127043412970318387,12736306873740238832]]},{"leaf_elements":[3042349617183071308,7581962110933650057,16691285183933961334,1296096022345382715,4355462689923225181,11891204076958281826,15117336067048129188,3671429386898501688,1105679364020090611,1849460459919658569,12147558567429150342,8172970196934367507,16823823693485152828,8361912399536934860,4108065553463274950,9408922320784878358],"proof":[[16969482414021088254,3591267541363109410,7502504582517946879,316322759359922071],[7006506297658447575,9462063128642283912,11800775412622072783,1426987997656746931],[18261031765504952940,6507765479950450195,9923335374965829605,17182336021563084907],[2950901635000540216,15958576969986369467,7771060212765933456,14367697009738411694],[8027693898794803229,11407587272687742422,16208825819013648119,3954335334644720784],[17137930119694703079,10081311911709198807,106421761515695099,10253346757598364684],[1605732864984470241,2382887846547701586,14481892491004143879,17381238418829164551],[14020349378869571117,12637582428669394796,15734502401402495762,5695164799417959082]]},{"leaf_elements":[8913476656325959453,14738371123175135331,13770557212095506733,17056573170433981593,11385359942521242430,1334720810057370869,9819137629235744209,6780138040763124373,11837185706826701350,12491874793402017403,16739346789068203116,8007954596565043966,14721200868495834413,8408593037124393753,10592320884138060380,10930449814766239021],"proof":[[7594061882585319707,1680113879679946468,2559803279060302721,1948011341026884651],[18183525484049389870,17681643040810419801,5562644573772579148,4907263401623391988],[6707901680082425635,3958893131483557037,6585393682241306830,12080313545823720070],[9263048480467429659,14365565138492214422,16900514500570431002,14473788162135639088],[18349052270228711893,11686217883027640403,17714450851383567286,10630403265852227136]]},{"leaf_elements":[2302575516032627620,12362913799151499027,9464051798642536856,9178830711071251321,12134273011626767564,17331216040310034439,3969818381943252656,5354494638362983741,12690067225270824732,8944692166906473485,7953330183398708362,5795526181714019468,18009750608913694842,15786646204324923488,12300168099572503114,15145646509267238501],"proof":[[3102152717900055225,819124904820690444,3198436900212415383,8938898675656456924],[1572026914896846847,15703434778445970145,18039674663595608947,12269104932850371711]]},{"leaf_elements":[8872244034292046542,14961388654118324654,5802056968775514489,18302383666416428067,3933647026650259001,8825851261617385151,8616213839298888053,10450361630528634353],"proof":[]}]},{"witness_query":{"leaf_elements":[10294005649222149197,10036559499506560678,4845637912418182302,18013003200067881688,1193667033174587391,8441648974495988564,16497622347188398962,10942158780031706121,4672380304918022323,184849387885866925,16864401209951981321,3852537579528942322,17516744424455237492,16125803242177775872,7153023986412867874,14494892051798905484,11151158879324791493,4755361884209827218,4870784878191302145,9419746670495062739,7036621589779791663,3154805497140656570,1458683056978959934,15373904630166724360,17753925088337185863,880933711257179078,13609843877888270535,9091945857603788416,9546716162982292664,16556048724985852469,3888326578008387283,13750170207371616158,2965629691430150541,3970546111919574789,1252172024706532998,7692428140708518195,15824554766823049096,11813272461800756355,4236789176053333621,17689073913351340248,1081683562467543573,1730644500649274930,2814873612192281261,10429953353668164443,367676085791742696,8824934631707668729,7802420629652467669,17759711319873638380,6217764303347955056,3950025612893850984,8916262718615568517,15703218472332043756,14175799856339947405,10391923656274608579,16158429958440716707,4895372633200312093,15031116948133118820,1931161501597042012,12249217656587169041,1588909742259870520,7920043975814507497,12511407809039935170,1160387505759110777,9944499564030766701,15218618070471017534,8116390195227080653,12546779338355615773,10522312606031772266,15769826756133045867,3386717797996356302,4875124171614444319,11064949309407307289,12729149953047601312,12083761324946545335,1267014622276588598,5866552678385663722,4922327485785383804,8908837784456858439,12083308813580089853,12351909534673970604,8247738721849864879,11309081967051601231,17127676390570430664,9488737221356716319,17295208645399935090,14805935985091026289,3305280699076245657,14405615916186961064,4427173851637883185,10251778538771716729,17467800909991221955,8033755121326408286,14548896114968189229,8458512919618672861,4113504660625315914,18305232415019368889,5557385651070678796,11717157748379835023,16987722671895408533,17191951085554901889,11568951567534948008,694754301285643747,7522468862468894944,2999915232752620476,13489932991332879148,16785810723834372804,7811989891800794730,9074642803912790678,6740382301769192623,16909777622840369933,13015962626796174877,2445374132936342728,17418094119162093473,7025245241024841119,8592007549103207249,2413097527163180617,15034714621538767362,3163725471899533833,17894744219196955910,7439393005742233093,6659104729762650864,10330607395843651797,13116862100456599083,15358891673717499801,5608867025690787485,2446726355361118713,6918177485989148273,16295975701028774639,16223315037796085110,6944775811460316511,12768261434805365547,8748373008552361669,8757893387355817400,14989434987489238593,3524570245410599655,66449270418126073,15285847183126454582,15906857764949961807,1604199990424459835,17114605760136409159,16580242021296825837,17212918914156670800,1864561755598730029,8661992693236870648],"proof":[[7249270413781469360,14152257321912423303,9141164909734045077,15901276746543113553],[16445558936624670970,17265570344849500076,7253059058823116083,10706284831326841415],[11503254145682131299,9756947102258782008,17708320029196554142,1419511510258471176],[16966734654732169426,1467381064585020364,15316958723173817095,10236266664128936770],[16238293950239352803,15262863208983381855,6918624850729241512,17324649936783984889],[8177235025155461633,1267027022298237716,5636646409962765769,14993915737879658643],[3350582546556373166,13458119485219611177,4538329226808076677,6891780113378086646],[2308204865092327890,7782978804273264571,14733817933445547932,18063056494025487434],[11930262233598209042,6833283388275689707,12974619967844778658,6022291578213729815],[109763817594101144,17670464859453717228,17270063541626198636,18330455323867299164],[16483100284620719173,18394898689513076344,10433976508365002722,8542163275331149343],[3908486765786496804,9367322298142574459,13529428349669306199,7036823539189801638],[4155115560439273670,5654870456091389431,18131489647563232812,4870512136151167483],[8221328558169986601,16610654125577060450,1485212902192423767,2345553805450360358],[2639955422394070578,11201601250680092989,11440853508996275731,3544830074669802384],[3391289171207654785,7007665983984736827,9356879587048400840,10018796648970944431],[11350054266242620580,6717146233067051964,6161093412962147136,8935657310830520738]]},"stage_2_query":{"leaf_elements":[1134998765182640872,16993607037777911279,13758493007612465273,11711013409259037264,15756029477291267360,12019081194845820941,31103534643871069,6165397770103904681,11768652849357009017,12977416894997652825,10699800065845143529,7212267375522137243,15626521125794976846,11557261469287770958,16190997452174578361,17720141885506411849,12170271363983253371,16188942071715588493,17871257283055682579,14780132849022956075,2888140354838204149,7415663946393820216,1867400153763224771,17397464739838563409,10685064202619780497,9373593718778251695,1535393889938247173,7273198256390527739,17918681604416378364,7794046357210785912,11497067616717295630,2573993103829797004,10233511800514918812,4754642160945993551,16782897861743340780,5368024628446323155,12880060853081168607,9614601752868413730,14298832676415792114,13933749638774245016,3684111455534592888,10200728382037916282,9462872355289672187,12828917965946368480,5022411999234088066,7519852009997782953],"proof":[[15286261180486119871,14126558383696199073,13526295228327670940,3822714875986345467],[6596384630089948473,15526593149362848556,8751574991889310663,4721096898020303191],[16088912949169418259,10928107736596766904,9901084251260400271,15251164509718064927],[1837436026443223214,15238367412126485177,10474600888467359245,6433552436827302966],[6618496462688086820,9147564483317814655,6094547853511719122,14072068563099130783],[9597443827550767664,11970686518743227564,565762611220499482,2721343713192535376],[7860902764114826341,10895288222631302884,11199038196519453798,14722548681332646473],[12033006042779462115,12525300957753751297,17181159932122474979,15874613294013222943],[5065876464682855059,13433391025958158622,12513606975200729466,10398353477241152048],[17386045818278315901,10420776241275688684,17570780591965537448,16466681823828855979],[13658992858827142812,14141436294712910033,893930090050102152,9311269916064765984],[16317451810988325425,839907514741802713,12216075183798050416,16109671264551375444],[4137509117768554813,13922468688562642960,10413001910308165688,8924580853117992308],[17867954098988399896,9881444673465440188,13914245011776506778,473691740343728306],[7476762211093303103,5737540960285596194,17878123700507615849,16125822279325347210],[4943245725504803452,7749286684652546332,6358730901480003500,483879996875154315],[1518475277183878351,13495330011763321220,9115621685652662343,6489546065185696418]]},"quotient_query":{"leaf_elements":[1868317088134449153,6145867709949331151,6722228545173318484,1517238326908456270,13112944719027418681,537163511907415814,16553256231099510411,6827100785344316283,18112793307443030708,7180389525662493889,2792462386904526089,15550646228647166819,2890956824734716149,16638167523600930581,8186985518160748,9459681906683815635],"proof":[[2353004486403746559,10550004186639076892,3562394551679492882,13995366069095307875],[1460267677742008345,4216681503394711460,16309263395147145492,15092494961435388763],[6509593854046511332,1124031068736785502,3001796607575600847,4384323967504077436],[2423212317180992599,12532449655713062009,8759457476668120256,16298624938383219642],[6420046939213857609,15947323517087694750,3393080765237936455,13264033997722775778],[4374522573850358801,3263007204263180116,16211387894394203448,252088164534290447],[10276851648779468616,11800479674124567640,17326640192792415046,6403786653245234600],[9740478895263955274,18223156895062851461,11962065957574534119,2279138929116172266],[3429358480401041613,3066261560468787906,13390337115274487256,11698895245155941007],[16888955057121357461,7177071453794923855,2614825764296080688,7171004673526130358],[14641646416514639142,11296411892021224228,14203270915164958483,6242904643878078918],[3155198642851837889,17451346539667905276,13597894914929114195,13231746919808577249],[16603755552439163952,10680472855939845688,16056511927702361935,7141150396992695815],[10348165239024939523,12999705605052124075,5714692171882386556,12601516162777923041],[8540557713285390933,6086199522220609886,9501927642394002334,13905785419865019939],[8915191846098668258,5309933113264003199,2219438225219196291,7186243803698191533],[17820760276996863375,10216686837309516532,8030491108914819360,6003298734879692044]]},"setup_query":{"leaf_elements":[8074946992380136653,7879734554483367996,4716366879022803845,15716187014118021994,6341176533675881547,7661881006952079692,17964934874519919732,17036624247074528587,12404339781521330556,5244213172465726062,4572780511047182330,787652038446570925,16477629760378840670,6449192157596026155,4176741870185470553,9569389902889820146,13330487442100690854,15531152947739563726,11658984019682986831,5128708517660030054,6246392123115690196,8496489135792010221,16818610500489735894,14395963449175508746,13019606457205201292,11627232966408825069,15117811003726242613,594524368381904593,4483512470103610960,16116233699041096430,4828816817074979468,12014260868997668616,3332013602753052918,5812753312065825794,8297420816413155847,17293627015966140247,9421105173472625148,2309044110367664723,8960281255879965120,4497928414427387171,17464354592868101406,10824259374963820172,13227661078569030811,3094137234611070209,8230688600145691630,2237923160326306033,10287508138193679721,16455679361379238885,15878169426842749032,9367805174122008410,17436221525096643540,3442580283750769013,162432641325787154,10187296087635978464,10290760205078743168,12952160060800763255,2292630224998537275,11289309786656540456,8064265952698819816,11459226584019397100,8093110021206743494,11152672440137547154,16413280643872411317,14178132635988436035,6352146822295931993,16842849423398154676,13994166397591966290,17290462253755722211,11737622058661345400,14089916948484590534,16811347537722911121,9862863224913310998,5783991171079473066,13340600944680577878,3445700596242932256,15838364584002112912,16977946764524031782,17719614582929541772,14191705758230984000,11960804713664025300,17585346426321554825,3476750703348583527,15858890900158486105,4631519090040187249,11957540845414231052,14791691249024889761,18079897513684642187,5274944557325401187,7554180550343683628,5601532297857905881,6518268752001203705,788330985676909390,8634161392672641086,4421426852496875340,5173152399191318650,12802614059407108755,722280829116524705,15140747964489434127,1948285950811443654,836666922763681242,4778337112874811597,15018821541420834724,6916563369560599465,10090440980221373497,4865281263679962047,13287618432251100088,13836693330620451353,10846341030615325797,7714061256264899248,122016110013745493,9110293724454277034,17897103442833208590,13462825022209493962,251523571513573022,10609146521599591484,7271656067846545857,4179896019669081232,8977934917012172581,18171619637193434732,9686147263427248123,16972657210498635128,635522523589620716,16046505691582976935,10889318409175634547,11227451265751149814,4747619446685875031,2112852088127456820,27281563541048378,10375468278817916155,518092495338261878,3938841420295910050,12589442402636964545,10125789815246489752,982241870342340265,4180129048579037005,13458376491612968819,1564201547429039750,5171679430277241860,15325291784143489126,9212882524944261600,4959783896659958045,12446847807250210519,4583611739538390413,2491920632516821278,3667839063339275133,6985425956058807046,11696150075539755027,13937530825638893133,7676135948380597057,4568649721684096959,7640152068594532644,252481920781038067,1120076559810708952,2496316756752515859,17747849543854972259,5602046862748029883],"proof":[[18196932451271470304,1850444640928787007,567015606581573178,8085866505444734967],[2552221548941641169,5188076732356047101,11037413321239453517,7408729801979142808],[8926414593849483288,7307942402931015986,6499448451814489929,16123167260800876597],[15451262085902934794,8815006469370620120,15999011077399553801,12343305790294016488],[9815055592685357533,17965158366302078656,10742567064720317368,5301980046838027308],[2039665445322085449,2096305827556600158,7099497380251307094,7964456872800637263],[11770840424706992013,13749264251043297730,6666369980270202664,1065923850855887198],[7545322894974843076,14120772809001168872,14621460051733163793,4635973571872394326],[5502261185473787412,2962987513496027616,5283058653329283494,9863034057897434146],[1226017701338927225,5507559573109963418,11715097561504388828,7312337841437462328],[4151001657292058805,2533257980141529725,15192909173090544474,13614446216417922387],[11073168374873525070,17465718407346697337,504314981401457952,3207057252876404637],[5968451406070511384,3591822090975587891,3101160138326107513,12361259496649825784],[18045182790099735214,3770542404706423202,11126835680846241140,15715028483250340836],[18246863808497192236,15142165921958121144,10390131574496553492,17270659068093766525],[7796515679998349785,5123543288797896245,11553103988766187479,14507515685403024856],[7045693185093702392,3053864862465226362,5174513965978999888,10652156676010014419]]},"fri_queries":[{"leaf_elements":[1622543463152835594,15046262710494316045,1465746842274403665,10281924680711813387,5728841438266503386,16886422219281774851,13454386508632087935,4773106799949662876,1495477146403998468,7052262674539234747,9264210190523904411,15805526514842148916,127924317794708579,8680118484644722776,13433159527310875851,14889200646896223117],"proof":[[16311464567532329303,12805577313199708910,6068892001118166226,5792905909629468517],[2859006055226385264,17210508685296125359,1127632665663818514,9881073441611078399],[11723733532812800776,6562518466888083841,5611264469853924992,321376776972172138],[11641009566376470377,14782081445617231965,6781840894560675382,12956659913050238722],[8641094106612816976,17538862179396080246,2629549744894427211,14095474254876410159],[17732823150219948297,16750683532038738078,9558799459212969693,6282625952597911759],[17683787490873875685,12405838966794616014,1263729763414600784,17506901149682362066],[4234034304826148367,216612998622796285,4307166663738348735,6273163630030220878],[13494352741873273669,12601864576618532381,11696105450869346476,16112666262347112164],[5963116213327711080,11632316261593838512,17542490275591447127,11835571781428071486],[16051259549720187335,3133990361134809714,7870136515239675743,4126829021652328786],[7488152037397181305,997521943828760139,12430572523988852608,2123035239648044964],[6659999624970365490,17685202818826730706,7705766716795780606,16140453052080968691],[9436036085613120994,9138757752906074281,4592184338475319271,16269358300088240680]]},{"leaf_elements":[13708446805670868453,8549276863835913603,1077730576725692256,6908783994367467026,11640922326273107493,2398457478147867304,4483666965277621006,6851970063881596630,8184043728180813629,3113500665680202922,13078694147691632873,3892402631466689870,2709661881439896276,364329293890787519,16994919143014094678,12338072157827335241],"proof":[[8548827381803742880,8746223244213190116,6648801608714679671,7821815153086679775],[5574877079005925646,662750694741278691,3492775154052537554,391788633786613701],[8596185199564020139,3768156331414821625,3306332658826274942,3557446022728108912],[11632190616733803039,3359413862270163210,250572843701236273,15610234328513336836],[17275049547733605766,10120045098336935103,10134574792734421096,12569095953941137719],[4354900649551973518,16320705984342195477,4151730008017895342,15372264365929598570],[18135914484894219643,5393214467892712395,4155862772364693425,4454619051912334093],[9131212323177418929,549825162998641801,7572441864633006071,8972334607092565267],[12912413511899311214,14682800640838365863,5922059127001621996,11517522791839355167],[13862450819966349640,13666989926741556477,1200439045958580394,5385097922366630532],[6686906591241727369,8571182967814379765,7115603858759199184,421617287814022009]]},{"leaf_elements":[4392998121875130234,12251723329196615227,719108642686391073,1804114690716836038,9527373711778274473,13126339873778231119,13449089515569454386,5348685006903627606,8335030557366934669,14714367826708650984,7788258014650854388,17632044134118782566,17372540227315536751,2637285283622824625,13541634593054484956,3297673464855062643],"proof":[[8642248913901675545,17816964221281666962,18156777786968205084,13786505765749332443],[13531770663079333589,3480482177547742147,14101154374265471273,9938637064938932043],[9256273013776633705,3254714216936733180,9403199317715699744,13260801925817654626],[2640193240216865076,5890875738206682843,8876407324300517959,16706930649345759586],[656746753510775955,9933829652703227943,1783196628667332504,7959784942550951697],[8947088644574956097,5352039159656206718,1065226683196032953,7216372087986462260],[13197868626576359201,2519400326732045958,12706414350278011942,10273987809803297391],[10938821742966244955,11911901241379388386,4981322656000654465,14178069308102147458]]},{"leaf_elements":[11534161330679575152,11061309845671809837,12309357427055816348,13276902138690643975,17483367427251997082,14211768242480367032,915495057914024050,10203101571902346549,12574089591560611770,17279462147428947959,11485220859563627919,6238763772827645991,7319440827084135660,11023048239745365164,16628637417567004270,17848837918740433478],"proof":[[5915811178180831004,16636180709835690845,18195562273242437159,14952296403814547309],[141058749580080953,10686609797938573655,14088720383988588416,10640087408277865003],[4774652301612594444,16285257677053967822,5713379746024083672,11216460440582608593],[12899065370321243854,13089473193201560632,3912869706064356263,3623976971484144796],[4311061275323904949,10237307365185888852,4759762726841936497,3629984639313244848]]},{"leaf_elements":[3971032656754509901,6242750001806783074,3289573577841311507,4723759412385717455,7990472227479536062,9551913444504527051,12528470007834886650,4804148057129529564,14347300067173596985,9306064789259756998,10028113922713404304,10599925518470309170,12535887185957872091,11801314760616791995,13344624036610194433,16282015287088952945],"proof":[[14908317330813799564,1801576219256327645,8393819521130354036,655486226575859750],[16608373254442398158,15558480294849148664,3666031975490616406,10425732788875687238]]},{"leaf_elements":[5913797713474501816,14390836815188810001,2598086964460305874,4219281277613110736,4341490336555859025,6837138495876505826,5182460282140934405,12936941785162437742],"proof":[]}]},{"witness_query":{"leaf_elements":[4759929970435852699,7816433702993537232,15990180153621803734,7220078045812344419,5103669919469299017,13698556234172809228,17474466833937946540,16259876334921382456,7928143727193099371,344349871404265906,17822435615746987243,10457286682375913797,17010741275397011154,16965931322084648125,274970741544441662,6816725200611099420,2057386593576087479,6431808763649835496,7716161365578046432,2550138150815481358,16192898896452766226,17722202245027223636,12463927069890165943,13042349674965173791,13247258608885184639,18093999020829728712,8872785503880722934,2871753560500899933,8541865434632832385,12895473821330724642,6931514943849121643,15952457076512568846,9908679092506454181,6763246219155629722,17306562264885897339,9332070621109426987,15351648426445313948,16731454003982047595,6216452427668965111,9375771757830520411,14580313698974072672,7434822615953322567,3598241567809690748,15545526406549006014,10448331027343439880,11350142903655938117,1283336818251593034,13662274895713899295,8398451552217953636,16318184175740926680,11417828608263612513,4926474091896800450,2627624430122687728,2151823116046853730,11235347116223891368,8861025723261272620,17921466151559773715,11678719942631989976,6964778886524637732,6137696901122495978,15257268021730299320,7314220577582085863,3801407733972859165,8584315534829602577,3465279979898272279,1638974993488292496,11163715131912916185,8500228495425696420,8933244614124645737,10240977921875113637,9404631173998750092,1138534592566205388,8033426789263804924,12581965332433858469,3265943947379012642,1792878316070214374,812026413662190281,4574247570758170459,4734785253306508204,31302678318473146,6475088784093724154,7933300335003961210,16800216016975962644,12696172357692736931,15737447738498526383,10228133076848570822,1318218577669318159,4873204949339137706,16485751270863410008,11703225749158368332,12415434629464864539,13058444662175813110,1117574464637898774,14046633652244526505,17864940657616708416,17696773789190452895,10889099559664928456,3437665097947126609,13781955175495734188,17828863864663446780,7017111271138024186,3299569393316556819,1004376847752816797,14148442890690119538,11329774595422643319,13801207132906078575,14456894651869701374,16036368533818201289,14332147462014841238,3265782251532770517,2153325596656407394,10627995046414125763,18283808418595789420,6788562549182275835,7981413342297492982,13292833938181225003,2801203222728622621,15819142104708122349,6199742873630810799,13816265455138929497,9692478451945187006,14438463013949782375,5495740600532005016,4520162901751630179,6038620834765468664,5845764972059259358,7114935564903944698,1008771283318778758,72505335735120609,223536681589029048,1799799304592708080,1269929979322781275,5020048633678455856,12192852870860418049,11309563921318269653,4139706521520204057,9958290086883608138,745782781845310354,9807169046395713892,8570731033094978730,7552584966510905131,3272701873413210584,17271948250027179105,1546117086376185055],"proof":[[15520075085689401918,12409292496879793144,13184753512125553298,4740441971178524153],[242334415611720976,9955763908179461841,1149551639740026079,6529586630594092212],[809051919643818116,10079784402846280039,13285664914426539508,10492406958408741114],[10879979202678642634,14434384853037248507,10199145426871908140,5103771834711204537],[18252394816304449835,5253269121012901692,17342279979721494596,12738257281758379603],[8753085884991760825,10176360181056863597,12175385277545022337,17230524042300693873],[10916420897103334107,18058587847623895574,9849224841949448129,2841959587517204880],[8055953971623439213,13123250646358595671,3853983624988841312,17085941828396986524],[17828889337229994873,8590613851601355218,17908130896376663871,8507637685689587634],[4284575987103619359,15549913880830884427,18240923923714955518,5811515891004352606],[3683016477964053951,4310210344295974189,1180167309713633929,17806031904985635134],[15241258278909405380,16274434167414772267,6751298663345959808,10908284607511318168],[12093315285112006086,10476634771155172036,8307066978694045235,9173748072805746424],[18000948409007906549,8833517514565230721,14391754555435027835,8860553732894574003],[2639955422394070578,11201601250680092989,11440853508996275731,3544830074669802384],[3391289171207654785,7007665983984736827,9356879587048400840,10018796648970944431],[11350054266242620580,6717146233067051964,6161093412962147136,8935657310830520738]]},"stage_2_query":{"leaf_elements":[14586040126495755563,15125367992244213671,2256213125796630836,11062115734113805830,6460434643640512368,7974436568834134221,10300337592445974007,14872067164730164009,16147879117498243035,15828666183139262377,2732325805737762012,18319214693317554485,11112705611235942519,14546137334579746187,17512371851609961141,18386310350240558240,2220352719906839520,6013174133304941851,7351747963390519387,11598599769783449144,3861009463351027542,4833490587111493315,7846625442855844828,15575095770648667339,17588993267046104943,13995070273704416103,14030132716898850069,17663165879859213632,848180437373594943,3790368038310378745,8778441609376861279,16021169814078555004,18288843399796614851,11389044355887340667,3136652525030743051,15662202382708091023,8059272661638845886,15441684089725463232,3971898308046928183,1256714957131860746,4765901333917098013,6384281081859478294,13318362942970729044,11989299765840656878,7602647680364647264,10209126770176860714],"proof":[[10407258927379145572,8581154557355148090,7436454829255025809,3745323751129766409],[18193317389261332152,2949625132317836886,5062514346747804129,10456553780361452881],[9547084732993460811,3728869559031305000,16043830649877655665,18346160668494644779],[14055377087631512520,263589256982702368,18106178604069431741,10604439775857657512],[6095564125608819304,9062894190126098059,10961431556153649949,3814207447522799928],[7414103017387861070,13123557999024365993,10354053656945061084,15051941962690612997],[5117624578760458170,5332164618151234787,5432159921748334016,12494438772030566176],[9158939949836845045,4304640497684537772,1348619843062575752,12383539536885653041],[3624430173171448269,3229501978654277199,6593409932857818558,13842798175002976256],[14994140425987567505,12977553507435181435,1425995790031416756,6988157703918645233],[3156970818549156649,4790629361152322692,7917814662521912706,6350292715100555155],[15102126984430356094,16264537378056591150,777014748359695574,14607779603418095742],[10407964006258997971,17817979648868911113,12258698343717031027,10687366239653437338],[9613405514778591797,3694753183304479690,3917740692980782215,8441568679556592317],[7476762211093303103,5737540960285596194,17878123700507615849,16125822279325347210],[4943245725504803452,7749286684652546332,6358730901480003500,483879996875154315],[1518475277183878351,13495330011763321220,9115621685652662343,6489546065185696418]]},"quotient_query":{"leaf_elements":[9592099413802250452,6548529359854437497,17991592462941615472,17776615265614196363,9397307185155085025,11296475895963955408,3391077714243060380,15608300478633979219,2985370329135468537,10284607629496230089,17287616522100972178,15876342883447006667,15153212531849549192,17528709635197221248,12543289664859675452,9232893529670698960],"proof":[[5599086994235541201,17874113487683787148,6237171463404830446,1178936540167235384],[15237396377524700570,4794417536893252712,15781187217523868679,6283341426974655528],[5810708923738102210,2888454800508207660,17231161199254763127,1786588273856547397],[6720117695900960949,7979304556730315503,12374943159630955251,9740678548214564730],[12607524316889028995,1953964499483890203,10176510411414763245,12291885837747328013],[9295189867820405761,11104461179342217046,15076360545194346382,13556521180326992765],[4414761014132724349,8457930781318620074,7384379896251560731,4953564149405912080],[2088470375458307561,11945577344904598114,13827215661996047860,11762877712645772848],[10517628823586407342,6028714229809711060,99558290302013583,8586689667990712345],[9306388384066800648,7846918710928726599,11233594559047182382,9457625044341342142],[9944148099770066279,18123982804938895348,12894099380039233019,15712628355901693748],[1700561278400099747,16694835531854243199,15820104387619413119,11146050792498943994],[740716257265585480,9681161751883418808,16700428358678969339,11882389915685153230],[4563263475065680301,979205808633505126,12436284577488184263,11610300608401270028],[8540557713285390933,6086199522220609886,9501927642394002334,13905785419865019939],[8915191846098668258,5309933113264003199,2219438225219196291,7186243803698191533],[17820760276996863375,10216686837309516532,8030491108914819360,6003298734879692044]]},"setup_query":{"leaf_elements":[4858324435639144799,7602956775941983597,3083690362876506997,2729192987762912920,14782529829498760439,1353776309017381707,15382210020099013074,8307141055837053299,18313394394920414624,9294797497136516837,8810436383604644007,7594222142044023125,12765804555336233539,10671866342188329579,9692340333910194685,2710942961834941653,4821162234355633768,8514362863972946681,8870575438245441028,10340669949877415046,5621003504508999273,9623952846248422550,3420090400468149144,10243271585531293522,11418026053310474385,18106226538370048057,3653636986056234193,7033498215504727646,6183784469201187355,1857915903679466913,3143577730192330136,7630122719821771866,12985862959184513240,10444242579336889382,868456051721557793,12550596108538155947,17004767313826218261,6423267662088226543,2165828483686218680,12395748300961428404,17839425628060407897,9198415988227900235,9284666223805752213,2768434756999223364,10839392310444706452,4614638112715357639,12235243752878670040,13258369351630054561,11923545402107149552,18025509411709423272,12905692264373243975,4567236456197518341,7617863128423154988,2063224063299419338,13785889910085336121,2597298241377560635,3660004258481894128,8284119416645420478,4596273077448505131,8546141809406050830,14066878448868364284,12553440787190479442,4853066471054014268,14627804482780155455,13719874223627044709,9292820935422881771,6076653866542010157,7619859227981393308,17442568396737563807,148701697693302518,8666973525132054619,7908566513301100182,2559526009308650497,10777932053700162928,3843089396057591680,14088238894451364806,14483463777848818555,1035111143446651353,3045606613119791200,5821850523400511608,14128700133594592385,10093283368444994702,1241391209269684679,5548970546500041304,6090283996549355745,1603244868985746838,3293706201099719823,10406237731780136357,14833865234200132858,4950170781044346197,8688315814874416565,15446306542306125419,4540059064463442278,16980189011164355522,8109229547650943657,13741803330893278878,5862761869245549041,7475144152194213156,3883535978005517434,15450930331943403142,5727849804864240326,17312427787420076666,13289927441413998690,2114030304478368955,3568118339090040803,16793248435476249438,11291759220893168196,9667426841026528932,617743771965714096,828782420946831844,7816720912870680138,8335548688500691656,1046815447882819095,15703280800477399681,12795140111708251620,9928225115131369836,3079366383847759020,5880901779487987187,952192927679802409,6510553287923365930,17175217744829725858,8791899870280094288,3475490672876566755,13411158656400559128,9950819911843308680,17735534296047814627,4976264370056330576,14234985255300222987,4565781591804952533,10949120019201099254,426079700602264769,9285810766006113055,18010766042698677944,11803883289626213476,16266607093138882952,13943641290442188177,6327329301027862267,8456255184002553256,10945243296980567608,8984136079956036717,17738270760706880480,18236994121772125995,6643254061490512478,18200105416604739764,2449712416075796548,12610180494959985303,3018692339069188189,17720916810582422847,15723469817261509136,1806634366820900200,5565905165974941031,4892822150582365767,15804224790894308181,17076522987074619159,3206865254265444815,14303251827399986696],"proof":[[5769285177496985330,11762397714063721426,6344519699728705905,7372525017785049200],[12349390211661322588,12504176556791013446,15109524136027347296,15582688222943510404],[16319021374870448305,15218979914273665900,9365878820258172686,4637486540916383710],[4276309624996582687,9588784980342876446,4571091056857431046,11769570583789684616],[16942286020789792497,9455842526702690994,13280509414252033132,9066272472077029212],[3200094305098740617,16434869837781187967,1857495532218442730,9139050189025895620],[8153866131643648824,783266003669821460,9214670924011268458,6366760611943004602],[9916529018373342633,14138619368213386525,12692257664007780106,10200779378545266914],[16986781960718240716,8003625511777670667,10585297599323732603,11950323493347383061],[5836848850876993005,14476159390028482168,9200847450155760406,11649993482508593366],[9381502535677657069,17315790123110058829,2266200475024438863,402848100440053517],[10698965964702540,5501577315708229945,17691016867303973293,5726286701419024069],[11526160160745627193,5057042717044686921,5447307204992631854,15748531968815944146],[11150624710615206773,6778799920913823543,16140672780942960564,10799370683246693191],[18246863808497192236,15142165921958121144,10390131574496553492,17270659068093766525],[7796515679998349785,5123543288797896245,11553103988766187479,14507515685403024856],[7045693185093702392,3053864862465226362,5174513965978999888,10652156676010014419]]},"fri_queries":[{"leaf_elements":[12013824167458500897,9849638611095724066,9006387141117417011,17975360758803531837,6413405337353098940,15712405689472901385,9403757201775557058,6095114045327550285,14942510954701272434,12049648667883994118,5178893896674474567,16863605297182801690,1339230755449840383,12091709525981823831,17629419282088704057,14426130411424317802],"proof":[[11573488438010497084,18015863565704760961,7983757224176137421,8450045394582905360],[9167953847276285694,8206961099159239016,6007967086731728014,3496903152550622488],[14318741785156673440,10349588035349334111,4822235566435910675,10435122718560325051],[17045817219533133174,9019249117611048545,13923250848041664158,17672834201922910248],[11496254513367070081,13772139592907282758,7821188963327373142,1569711244020260959],[10498393811085531585,10230246852785827774,2893278550759021813,17185328185691113992],[9391574212187790790,13602858924783067711,458795616132013528,1130436551865547653],[12736927280863462496,7363173209980072313,15180860103644356563,3778879227849599318],[4270273894700095812,16177306445482346057,14450859907913718757,5675780381679248941],[9560896843625793846,13892450171196169051,3822332434007983446,2696632903467042472],[1426992259416306753,6199565141633176196,2679403195458678690,7053136536528459347],[7488152037397181305,997521943828760139,12430572523988852608,2123035239648044964],[6659999624970365490,17685202818826730706,7705766716795780606,16140453052080968691],[9436036085613120994,9138757752906074281,4592184338475319271,16269358300088240680]]},{"leaf_elements":[17954529421136125171,5865420243864366257,16615681402054141024,15477655412357818426,2543597300118152542,12217377165310989337,9190885142136436981,12940194113913511302,1248536069978118999,1374267026951159306,966228827600867457,16661843587057607278,1855350844555511248,6081527169902935305,15660931130365436402,6665975809527015709],"proof":[[13679858841471679882,6318917710102809143,6985964207489578708,16952468974306663674],[14171022411252658897,12948073076946476038,6575645554990051687,4915440799336795151],[3281276057854747114,4427968454693422535,7917910468507915337,11002163020610658865],[9181288734421480787,2385568654735696814,1442113717230691816,13009099310545664958],[9160301524159832453,8409291634741118962,12952994135751938296,13920350920997585380],[11750403048603124166,14426536528880872186,215813502957946563,6865221461338056725],[14244733098258973053,159661718081143428,17001308604584248028,15351127424655910469],[318104591254431595,3954611580509335173,2253306523533625062,17588478458704664418],[12912413511899311214,14682800640838365863,5922059127001621996,11517522791839355167],[13862450819966349640,13666989926741556477,1200439045958580394,5385097922366630532],[6686906591241727369,8571182967814379765,7115603858759199184,421617287814022009]]},{"leaf_elements":[6330431759986553042,675545766544396395,7252297348484605151,168473892647290467,9577106873711307451,3825396951563790430,2130329224645534615,15257922954786496743,12901108691744942300,4249269491918181116,16158564040768706517,12605005151096640522,1659633404626472634,8321602726005494691,672762087030766775,9327629896975927203],"proof":[[4722842596479010454,16218587977259400842,16310335716193349535,10860845017265798574],[13595555875770136204,13879182095885374494,10566026110186661697,12164037296857765668],[1886905390756978995,7544363121983907386,12061416593246596664,15693484473519443876],[1805566594016870720,2370925264591426986,11894625418707719699,2986998379612196878],[9734809784998758809,1098495921770213826,2590651938985354104,15154802902299059862],[8947088644574956097,5352039159656206718,1065226683196032953,7216372087986462260],[13197868626576359201,2519400326732045958,12706414350278011942,10273987809803297391],[10938821742966244955,11911901241379388386,4981322656000654465,14178069308102147458]]},{"leaf_elements":[15826557273097623560,2511284853733965556,15890780784251083124,5382776080277894726,5262631526243983447,10111432126974990649,336318732227536609,12683588595358762314,14414556921220575830,13640202598608300549,11022206250393815841,13905760965412180331,7796872603123239464,10144624773199514711,6156142327878075307,4770632126079561104],"proof":[[12499814706645278683,3846483181220423261,14672374202349844944,16188877997244134243],[14936450713587877447,2089584399828576461,7468970841458073115,16250034524329847089],[4774652301612594444,16285257677053967822,5713379746024083672,11216460440582608593],[12899065370321243854,13089473193201560632,3912869706064356263,3623976971484144796],[4311061275323904949,10237307365185888852,4759762726841936497,3629984639313244848]]},{"leaf_elements":[3971032656754509901,6242750001806783074,3289573577841311507,4723759412385717455,7990472227479536062,9551913444504527051,12528470007834886650,4804148057129529564,14347300067173596985,9306064789259756998,10028113922713404304,10599925518470309170,12535887185957872091,11801314760616791995,13344624036610194433,16282015287088952945],"proof":[[14908317330813799564,1801576219256327645,8393819521130354036,655486226575859750],[16608373254442398158,15558480294849148664,3666031975490616406,10425732788875687238]]},{"leaf_elements":[5913797713474501816,14390836815188810001,2598086964460305874,4219281277613110736,4341490336555859025,6837138495876505826,5182460282140934405,12936941785162437742],"proof":[]}]},{"witness_query":{"leaf_elements":[8696691245549559706,5866690562055335892,15657228231605252017,6455818851210755846,7603128213628329635,15363789967199579097,2379103724102774902,3273501395249665219,4629217502836013866,12529154394979761809,5866750721200976088,18229183931314974471,9709698589148212951,7049380299665795401,14729067622996913178,11677505208179754218,3813716728356050991,11217624893992869264,15963623277272667604,7479213274383413158,16793025609765693415,12537329147604231172,14451467829308260260,9353676384759052439,16236881050386757188,3057226149056769999,10882941575478008028,18219853433613153133,8411947423915998524,1838593313624645203,5262007446505116916,11701408832897922910,457978913818041527,6528072539129911337,15351750811886633219,3423663778715654436,2844962468682348343,3536603244896717815,8671651481337710272,2457734349345832155,3677830499506783800,13881227937717775836,581636482116743499,12477302604238130554,16937475608938775900,7658161949010024915,17920685657315086760,15701747839516480232,11906240327368739645,4556989914372694479,17368221114392349866,11267707179343593958,11803793443900394410,7783718734072184260,10910880035881756176,12018164399217594260,4563869425254591518,9519922255508082451,13217303392345732424,334680879517922674,12599740246089882780,7274418211812458617,16848458154761730916,10329652520575876836,11925623249680300958,6469182393862057715,17195773485173417735,5586937613763597365,4884431141967811581,11175196813421375193,3009475424093340809,12843993455010079001,15851675663021409713,14077961819575197519,8633467940509291794,193003244973705152,11126225814247533841,16905820479220919004,11394040689229803950,17060833560527602065,2323850321899806331,5353093494637129386,79385410132387738,6659327725677246154,11117258921507499022,11979435795707928824,15329535242750583129,3099449052917567139,7490430463476800349,16750205354163069638,3781663580298131962,1524798646223694654,17123584424376994317,5103085943063959960,14960957593157540131,6209705084776157790,6653118054547453105,4820862617544175622,2539873014621214018,8171336155610694109,12143516158112569535,10778697081773790047,15731406352824750092,5646530386830183092,12455010282625041164,8629614492416349594,82828620854117531,10045247392823062862,9776091360675597694,1105468570415976134,14105614246982475182,16834664716796901798,4237021932313402136,9629076119697424160,13899733916739084067,1481930107445751464,1300696921101260369,16888804101177661889,8617538980100503869,12460285261269435917,1992974765796855382,4860318322365974397,8548410410575895267,471666053417379873,3569970247958738485,17753697896733555613,5283682664479165575,1195826012143996741,10331546903058613156,227677595322551841,16502074551433088070,4432798117539654614,7023721502141414065,17918545099302154425,4473110024421280180,5831589359260036131,421081404127100608,2735004897951563009,4814882683542214814,9269229195204318616,13337836339505294062,3798383732155702608,9878778919951329058,16473358196183305833],"proof":[[12342486770419137084,1631015165817288148,9928402689341752671,8219889557915798509],[10629961988345943998,16977877937173222225,293775633062333061,12209742362077148172],[14791612653918707892,8746075213570808377,16613306337092196692,6384979718630250155],[6423364149072164451,1298595011968252994,9505220127747877848,17801636998694225506],[14302945415314793117,16830706961047804533,10665466522592941544,964283041810478961],[74544045990194854,13432135266336899580,13071663797349041531,12524483575084308842],[14845748367238661368,15593475311651295972,3152872565553379298,12691530498527287203],[10407517155154221276,12577924359205410220,15407640114949638584,6123798867170238289],[14946898212163754290,6237540371845523338,13618873899619392195,16295397803857886620],[8158425601835672491,1581883378555491509,13697143321740770058,3805416171563551784],[11606606816282712594,18287989175525366120,10553435066721721136,9420564883895101286],[7190027755808256420,15565146529871799653,8786151803863023171,15503123039439353459],[16360533639188647224,749226709780230896,15606280823414741585,12932371748950980211],[8598602791587020261,12423842397669257281,3572948672455696522,14179030010103987073],[8656114365214242897,2026613752555735250,11746444510852321615,1310166986361981072],[7049343954157092833,14391493793205640963,7395172756984581331,5113072916745052878],[14710339626193100422,5166397287786674443,12877026722859487242,10407735240586944831]]},"stage_2_query":{"leaf_elements":[1532642155648604357,2288721697550173906,3850071930054416952,7573101284899122697,5818339311646744735,14816095324620314130,7205867088719291500,829725970234498321,1799478240195602552,860211030024090712,15748441523440974142,7696253666585577558,11511310075998670445,9520287093523405068,17643035212786025932,10100737084033498700,15122436435755986988,12696906094368855254,17724427089138274181,18045059335616005644,7344916314949375992,7399296536840652557,17569979553606120703,755823192878471539,8074281233215020269,8640989267513244565,18165726672643243320,8058714863075569611,18313382011212388250,6328511724852736251,10036135207467178505,5973963465253267565,6311289273852702278,13539186707377444549,7402802243556539879,10837035226709450891,10292099560305701219,7307913509962175009,8424977126871055288,690678088512012272,1331090519069651664,17442352607418436535,8840622590026480537,4518057894715088993,12601298657943826975,2654387493142693715],"proof":[[8437757179569826577,14185529001785147397,7069024806735044362,13159429341963039380],[2550791508509506497,17529256265291368123,8378234007964755738,443330591258925196],[12385490059081061250,7606922907838098888,7204653369909493368,15653316920817587932],[10814833871924284422,14632008343145371262,10990993842807274617,12723371719929356351],[6807292382449157534,15492559322407859976,16147776194135491401,11482346108593937068],[2895655913171516272,9011837703585879227,680061258966478294,16155096052645546885],[11197533736267133202,13298868306069067863,17316384913635800564,10433109314288956966],[3881913210798203125,17694756430269496120,62475762403721793,1045850817237061995],[18376382856855014442,3933414316000680140,8751795752461440310,7604916535547961360],[12825509063002856854,343637900739805939,4357555177284042708,6638718736095227987],[10945127941432012776,9501420705833565640,13885622538560527207,10332728548081269463],[11612561252247278651,5475120356697472247,5878163152404606534,9097778005796004205],[9057808241460103730,18269745027010622405,2180966046901875328,7152554968429286788],[6772332951357254289,13774378700322702633,11678401804134476226,5011324067189204964],[3279897117021941917,10243015713882380433,7774611088600453506,3965896168529592963],[9069739529505737466,793676914951333750,14464203160743970347,10684389483843064330],[1135997963394111510,13275752990064275231,6348311180324878415,7982923292041772706]]},"quotient_query":{"leaf_elements":[5043288992424111894,2665035204431000974,9158551189461290250,5652206348420962946,328641493723079652,3601277743167612286,845186458280921443,8123340575052439557,18426510752046056233,4381886596718468964,10440563825480229283,9840356452170054118,4239932070101757913,17594476020961978602,4939517453815536598,15605634058893955622],"proof":[[2087740928015931355,17175254472767665013,8229333762414521945,6898084589820215214],[17110982411375499989,2164859132128241866,7099947014682790200,13543566744079719300],[3533800901070079946,8467420424468711961,4557008043952071165,18176943016807050435],[7783149831871231933,16889776054863574772,14393550204720886772,3751281730458756481],[17995114585954980563,9691824603279535539,4470561105800548387,8968951139979062197],[16607888319666079792,14212643602759256105,4168998416726244046,15591780383866801734],[7184586224192717061,7506576587636772262,14614864167223981622,16113847358277441003],[12481022870339504619,16167877664429104422,12828294617314724504,2673919995734896602],[5341896057610391989,1741709388836041073,7775781278165006999,1668896678907061095],[17340119254076181931,17741703881237088196,12754116462056990294,11071154383700536793],[9248756521720027264,15167061580101403981,223756496505796074,13541223068155267984],[4633577532038014226,666057752645205797,3630577130732074328,7867135249637948638],[4809235633936970173,13496269573704325558,9693473106357396871,16245205934268688415],[2228287880592725725,6354108257833819074,9307310573855347575,9364347711115264187],[15399655746354707545,4603123658320543225,6138016519870730333,7155963258212196888],[4359957004431156532,8965941034467977781,1773912866110419813,4664342605257984095],[12530437638825942509,9467813558315705039,1660881245341910574,6918973135087974952]]},"setup_query":{"leaf_elements":[4089045743514784095,2932445723087391634,8980295484456590588,357493310110691332,5807575148587202503,6299236055870112839,8123531998459928030,2841093706842745645,9596387730316110012,4014565370448459376,1593619777736730178,13417623287274971396,16387083927053795188,15698331879490223293,4872228139190911707,17340652950159562191,11404633711629072553,7271706049067470851,8878707155875402820,14686367564729290530,9645891844466601541,16774831292399870860,3982232826557589860,8042975419547928724,15674037484202926961,11944192140284360012,5811833315041078502,9753178299224478752,11609779934258634739,17514072546169274115,12991636841993629466,14010510493330059128,3045456610626239115,5885388148669612941,17890358915883353700,9331045100343236682,8277887932624800618,14801893713130042509,9356068811114518837,4244217614778464436,6304157291634091515,18403234709928879583,17415652776041337730,1991159685529254801,16669752860089914499,10355551422628798514,12991373312708742368,2280449552090617119,15711915033137233972,1276524459408163744,1704421089175394198,4784337590444386776,3909575478187100500,8212403111475851731,13663556109004915152,2478576678831063158,3207688718977108363,7552943496567763672,15007007836283459492,5587693394466027435,16395753578765873857,2457630009757929083,5888113166370646774,6123468466854611363,243693243981952954,4361728177096170972,348413720180781494,14074842077825593073,13531245237879539847,6581815575496336651,7204847077626103998,16464813806367855777,14543684004817028357,8383342741855385601,5253114100197605750,12204568074786042668,7450835126700458592,8902672142362944203,16111716765982615024,17150850924346694003,17173539188891558921,13592307998186428162,2448998680597671674,7873690534765336651,9331996426483262655,2680708116664841507,18013653974503126989,9373043199391136723,44139189393108907,13212005753325040647,13421050187467500198,3841794585081713095,5882515895813638824,6724218880616409654,18354936846803514395,10751487391110391292,12343313666282782015,6006522920592407566,3981805866855190127,5985004579202757211,15919258180381573010,11106543680712013855,5981849904409553796,8291848808050208091,17972479335873927918,12873163686793450200,15473204770101430423,14078107052156485003,1497902465772310886,13789406880698272932,11105772409413079475,13930098321894209595,17583811002566576437,3213366847229662016,12169463105808793466,14389583617616671627,10409492088533811905,9668798968170321098,6563803038062287111,3259584596980161527,12287043803095911708,4878963583614263414,7516572154971241965,7499570510210116783,11536817505203391469,10532512558650186652,9805877286016296591,12073563314590847011,2378712123886776559,11926448626313416782,1945359929208265037,4425602563484061836,12511672532334606904,15187746388665729649,10987235784051446311,9211101765277546937,16826773676281565889,13402525426374753974,8010035675575208390,12939615832357795631,16458413798746772020,580719738663675995,12325897246251900822,14973054659616386169,1782960491328066243,16893844158275767152,9599676550404522177,3027344454053597974,17123480908022416490,5645014612260634562,8798650073127635321,1137915529813368694,17922196918106970750,8738950174037878075,15297829617794751173,14284257802290976003],"proof":[[9807135864280955558,13652449751538193072,11537695725440491650,11380379142975159295],[6213497445013091497,4321473418040455807,6923982341684014919,11093143544957804622],[9402101344103765096,12554784179184550405,12647018580602818894,6410091510613932923],[2920640207465437560,11206702431315430575,17348840316441842508,15835711750706771902],[4655050871115851879,14425379728912868247,13676164934754247914,695557180039128912],[1391264613639790042,8396759892601400511,6858971987112246548,15109179361449391020],[8879666108014361830,5667542830426910595,3212678110752381929,10333585428494109502],[18291063331283100189,783864536425272742,10988391485654856842,5875238249617463308],[7020580265169116027,5624590473226437296,12112893059476099055,10683428548204211922],[16245953559915808273,10941217231804898394,1808005987623171964,12600613819015516403],[3025271721853071318,9680087710049489904,7650023800240188319,5837597909922921965],[16850597189180959271,14068611268921562773,726448345856172484,8293007379547392523],[10571717381929595579,2670225427925834335,16622354145591084804,6260740393398022554],[17227620838070879349,2873798938091299271,2541816402164827295,10023619831373938197],[7433896140923527024,2202919805167777348,995682786262345260,4650991904692400848],[7472052915157579580,6454707544650764846,13241508517962884643,7658945900870394285],[11786672773418549703,2339467107386851422,12140533047963330746,7373381974425188538]]},"fri_queries":[{"leaf_elements":[4243601146373322851,3830829002460207071,2717357513797364856,14475350041097688696,8887236834916391442,12690080379102395529,13778218627907840073,15565402081991765421,1502310606190486300,2812023665867412381,3732181208842120316,17387077821886748218,13804941010516719783,6649018346525025309,14075308079525367315,17602440394009427107],"proof":[[13875958961623512300,8776869951204674310,18429174176016591921,4971271582724611204],[11764628880820780448,17033854698982783360,17659702848030457323,14546293829579516198],[11187257051447348807,4648856904157895926,10435619907730565031,6065191521830608060],[9915966512622929838,6087267775983317174,17741251946593891526,9674618924462442913],[16617533383445888146,6564996526958376209,15308233261996725480,11863401660054504851],[399520317681619915,13089355882400706863,4278225005809181717,98304557701585066],[5070383114891487373,9049127361016305337,7025742456232212386,300266384060601342],[3168082756341807705,5261286391724297652,13588319189695719296,17545741018013767995],[16123618540301024912,3781534737041363168,6947962937615073386,14721172309193953879],[1840348451294108124,1238267715473179432,2618657970793781351,9984813603812421633],[9365515902094200456,2951939712759294661,7006928308939997545,17157690633060941542],[2570903842201634756,2815180613750793309,17915806315847283131,7559249678223093886],[8565450714688367775,13371411646079149581,7669076451911119034,5609613507105328615],[2065112813907786203,6898755846797313237,17320045911186699311,10677055216998779661]]},{"leaf_elements":[10803130592937811967,15094332980259249805,10893595344466078882,14960410219961500930,16268899480846322904,16345225024049183216,4305845943521084610,1107076836724780222,4571061011710687430,8127816934358174751,1649842723966393066,15767690071607204804,16628401736511244770,6329733248612355335,10088071330344310603,475055538232996137],"proof":[[12003438644277575323,1838158119675986920,2800487295179925436,12956798974982145070],[17219089456837766195,6019900286465484115,7946404538979788961,3016526111841547856],[8336776192408303967,12826757538917807042,4714005180950183876,3603138706647335998],[3550896033335178789,11241864893918789790,3775189500466423784,17944633578049682095],[9827929749874793733,11277609542916427287,8053746336727433890,2051448980460406441],[4495396727424813324,6532825821045436063,15978992465212883161,17916906164180368117],[18407066263289774402,15239047476739708386,7772934842699620444,9136834540275269976],[3786107029932858321,16458231901912159396,15457602999257304735,5424677581569994463],[18122974946076478425,12435953803150465335,5650098485695833626,7295604576442046531],[7872375859433308862,12547335083355183725,2049786543156448692,9084700728308976857],[6068200341678021668,17238405178273883915,16254243979175388415,6326469122072930844]]},{"leaf_elements":[17483679165044131333,2325471453232477877,13401582951807987207,78099769057506884,2862068744555362696,15940031393951093357,14919026412960644899,8526140852827008801,17724905817643680849,11752987035399633898,4222722633562561897,16728281051233417529,5520862743511504573,8546525277247072136,13680795137066023399,15835887809520091887],"proof":[[1509201189670433097,4449319464189850657,4215110403787770387,16506656042740341854],[2104658848923171935,14587255320544026190,4586974360415144251,15656317671219903761],[11409875511370095379,633406327811586600,5149712778247790059,11034721298572928945],[1550082661254426850,3231999268326022123,18366417477926807097,1466176914950862645],[13015287250962012261,8568427362953534394,7096992791547182610,1756180818365304399],[13870329784909238581,7462340476925786125,4280724661028926061,12799137110713553459],[4425897915657748671,812478123278601336,14446386344517017273,2479368791048095681],[6284005312668722525,13175024327537991261,5546811104920909949,2703000136490581107]]},{"leaf_elements":[9989888028108047850,3743674821984604287,15074079641009789130,6537727238948442817,17159842295649020544,6295503768772607124,1330876484336985269,997382752530088678,812414970511499434,18304469303254014412,11792371387382066076,16842555558541061996,13748149352301210039,14277814209449245707,2404346787317500316,4954769676911477468],"proof":[[11305452553490786917,4625093913942607091,11882148624404344342,8287115154931221821],[15883652414000449561,1056407615675534662,5706230649050103751,9725587249963417843],[2603844429399662471,8473451585878134884,13416626538418064197,7340279460857765664],[15183664090613473060,1501067564438234346,2135154504861079625,2969398395681691923],[17991506096714915795,4636722536725601757,13865614444769694335,8815772354958363399]]},{"leaf_elements":[10912580827303826969,13112124498184870572,5166031771435844608,4246959628546674791,8337537940124154336,2808515550656452715,896327017507608806,14965286150849039867,12366897045461968021,11139471698543338371,14093486012080335828,4141646308185794490,9103831047924060398,3762366279174691358,11512998418801433510,1220189138193510249],"proof":[[10958797391945941300,8725990360423169908,5482578788976588944,8844326393553402907],[10835623355140351544,2411159751067968680,17855867681805886030,86569936236411870]]},{"leaf_elements":[13912788208633012260,16592364955197622110,12930883254427910878,5599575569218380943,5682660096836901399,4069773254031359724,17686759155637027087,11829746095036037227],"proof":[]}]},{"witness_query":{"leaf_elements":[10446167279515629251,14449732437642728016,14248604806467372754,13687787644348525743,14221284774482673791,7180771846271149541,2362660443036478899,8205197449284723476,8030350576972719245,1097640457713000911,6142289957681409626,2496106162912512210,2408740881404849013,14953755659628124808,5104872804009293118,17022790623326586026,12396515202652022409,761253873374250594,9183420565965779858,6734075428875408794,2203410734959075972,15279843616941035525,11236128719891827060,9775263769089671749,4475986931770871871,12316745745473409644,11262364196129349686,4157798711012520339,17968157977943644208,12872645792455417689,389026385706874451,3410148251865452707,13673784623890512791,13559995852528011795,14556464697753843358,4781835017382839919,2254381014938573950,1192987764390442144,904532067450878785,1149691102159296215,5807024600374276604,5805265242814263912,4284195977038099241,2382957142717349063,16828195406899882563,17281231314172724855,2123698660125665700,6797993373761098359,5739094906831828532,13989984000513890381,7689957802424686954,10989812582281564712,1860173758933535969,5489542320205208707,17213865492586811704,50061546174702009,11549473337084089564,11980220052499962354,17744439604184931380,1547008702771188527,2485297127234238904,5313055508539595159,8652305935937653220,1260758097566026768,17738012981760561734,3988033284083579971,5721301899451787902,5256163051994705672,14174597083423181570,2419246951145103568,18162507574053089312,3839966049222383411,6274620994307759866,11953250128939045946,1362389984833445493,11292021225483882420,5470731681600853985,6197396205018706685,3864306592750780234,3565121419430494476,4902807292253064384,8211159622103054032,9316613015974647954,9211143604808027929,12336551978253514520,12177121554658676615,8222243465481038875,16503268610241462836,14022543785316074806,109694541003040297,2588462449088179535,1844233718295128395,9940392009262379612,3406302744558369229,12807249845210435533,3042682118525775398,7695551837093625226,13236631705425331744,5282728558293204676,11180343779504592232,15591112746098025486,3802384126173032033,16740134380045741770,7519039012814891341,11105531945039337328,7957245198046298853,11852837208509704305,12889672017236807277,15510193699814739783,14522586431141343872,1091106844521439628,9954638265984427362,10187385291893284909,17360191424730651340,4711041224246851098,4095168102685215641,2069911778311368554,10669707201563601727,2586646790125687440,9149792049934768049,2166564635629354641,13555020300464074384,15896887571371627139,14504273437785633037,17765611241685211348,14961638050292283414,10228583598391770931,8958979894951606548,16051241037315908533,4433590968421336456,4438090496343447686,14765667899221880840,5857901634836950441,13776862815734791877,8514423990943812566,6497858989822351521,3047110890903920706,13162361638936613058,1345353762920987759,17701703035716096344,1816972445726528924,4982396797808363168,11864143949781964347,16781398332995430322],"proof":[[10432996626285475712,1527672587056369955,8957032208260936096,666230663653130732],[10086396883123233596,9804668609602344130,9581337785681482111,16232912698296462381],[6382308052896839166,15916043449406158577,14367761713293428346,8140839154908495147],[18302350489964018284,16053936001292516330,13497320530724315802,1392785806577001023],[7505683824171261211,2520123096169461535,671977603715053344,5311439881215665708],[12694689878454350516,12258686516357619799,14803941221625777452,6690414774349093730],[17169386002617009810,12324783532477838101,15724805043245246533,11922854956957093971],[11306515473976588332,5115236383575556179,2268996464655090603,17194637374536427359],[8078154935229492817,795047631633675205,2328916703109242373,9902076855491677012],[6312068705354685551,3997883010540287608,6560792965923595449,2031891873158857837],[18006689101744528676,8329243243710905418,11638065446143258891,14023483120341609844],[7402741233768183914,6971795663984522780,15069319740220455013,3730742036611295057],[17622557529912734934,2908984426827205456,17908602554974275135,15738333805256879082],[387082535477455768,15219990329182189210,8189866092614685733,657763993357938607],[2659060738251997370,10050763742789921527,15978518701777175000,2443309892177426546],[17909269620353864015,13261051985899087948,12998451932328951153,17865522459203578745],[1953798436690953238,2147321071292191388,14284794412897050288,10182010349254562119]]},"stage_2_query":{"leaf_elements":[13738299124592808348,9472782436565464098,4290672969502629854,5001122679174324913,5045989829018159093,3504248274379355312,6503099334765032260,14658274840239828873,17417367443482312751,6142920584549996728,14548555652366196739,2121047975952350367,15881583490891516007,1106161054796513211,16844255615700717525,6779728200307854732,6551873437508929946,5591160501161783893,12456208199111370654,8724599024404388327,1644171009815764324,8280157203319015690,6019036046547630683,12165943739428166480,13890484536320282273,1824379810349256218,3832528556390790809,12690977394856466410,12562064331745919848,9284610867404553148,11039077122582559204,17147974914386689472,245503536805633342,4979908863724434926,14526064745343040653,6433137230046533308,12442285522090735038,17451478916953487766,9137816486104736449,18173628627427283268,13484985026560199125,3678031908298336211,14305023327043171945,3915342437662930270,5627894692638049615,2528757479206187753],"proof":[[5468149370623612092,12020792464537225917,12078393097511324750,1867181958842766931],[6791383059739574004,7650347247560937759,13469110642076157972,6042691906299633147],[17043789131231264463,150986812793846346,10926395007124327590,17384036359831175721],[4408218028540577034,4603517602597762990,5356266993099157156,3266483483657948235],[2976904834645068709,17654618830399572959,7928882190340500717,9647729734127016317],[13663846254557198467,1037340445537188514,5332724610300523524,5846058368514495141],[15644741874655356787,413722981902570669,9050007502144775012,6959189461641997926],[14857987525797097341,824573342708082028,9474720940350085127,10771570770381992325],[15079207905060699347,1913402059744589240,2421039362661939442,1735164152179693208],[5096982877096578277,2458646387814896674,8791615111361888913,15091742175908493529],[16550562360012285835,13117252294862300706,8061572743258264816,16863839355251945553],[16185470630304097515,6087458070873321246,9415535811068587462,6742650472740170207],[261829513952342855,9119211523706477490,12658975873174897672,9838818978667267802],[12453958666781901646,518069078693803201,11042666845185610846,15684560293444675271],[4101627083011103107,1002209927757219336,12102686251851698166,10425869972513256031],[10285956182066410551,13835665182111703010,11561955299191310775,12519120612921197446],[4885762215220938472,8498695306163120439,15353549138751841550,724186417904133468]]},"quotient_query":{"leaf_elements":[16443140395579778958,1810016522050373324,3397451088625305509,17314510010835612177,2757287560372400628,6972183652371986137,4981565254026310797,14722455308831076727,8493538492149757821,9451845380780991340,11115415248907098024,9983563800517029889,500743810286740538,15637401321063979386,3922129385491531869,14980032854056101596],"proof":[[6620755122901887697,6821111124852233321,15793757605193150701,11094906409118751520],[16042630401218277239,10156208303791243864,5791187575188964124,10744424188015160388],[8770600462387218330,10491775665253847039,11130236236419531511,313456647759608761],[3254860158235479665,14331837391686799886,15869194965939374528,857891636692578077],[4708904990096122510,2649441602882994376,9808374741027055289,13478470800901615363],[101397834618282535,5413924656463281590,7121755201328340398,15512660593623840648],[17965165847827893054,12189169584829716799,14982117313509871847,4939152115538724068],[1547908848991736447,1943509404657722324,49960989527694806,16013272471098957153],[4296635438914189487,7460425502268559794,3326164160426619302,13337776928861262442],[13210196706144279136,12451153073854424429,11783842751722961034,3209502100068053351],[3868819063593818643,10475504449119153886,2304486185728606535,7159353408471384332],[11910385593311740962,72794721421056071,13607824620235212513,17724070168821565038],[17223660700783530056,6479044969658901987,11644949331835757329,1614367459413074499],[10362373941166329374,957101686819675710,7370553725610798807,14393050365497470490],[15055356226280532834,7476384548771162125,11942948857821119622,12096315940752998014],[12409159067935956919,59240917520353899,1749013461618880112,8027725687825175896],[16596895484028765537,5749472348574443297,15124699585505040979,10983306082536664468]]},"setup_query":{"leaf_elements":[14989948086172640451,11612799578469563345,3163939133523908507,7756636504542608127,6320364036850896357,11008101251287768887,6825817819422392239,9887574197035407693,4205566306771377930,8547251728681480167,14099946104112820210,4017541055889563393,7052441610885526183,7533208961620486728,7863953500985728676,13225153834037969393,3931768763267091319,3276017555627458018,1837695690962884575,2531239576579797945,4263607657262491483,2433554870692796333,7307759320785541910,5168356946994162873,12583447970478621994,17552101346522786341,14203171209229934148,9480487111096083356,14745716533517616116,12237221877537857896,17088155278649586723,11777560876250441420,3239233884869959045,8854335610796658849,2640433424857207840,7660631536801176398,2093611544323791110,14742021034631871077,14585892491440294665,17402440956509480076,14679160795951738051,7504487515159306487,17009719015631014208,16823167402209018247,3802135055651067260,7999913095263306310,6198829458511724178,16680095377158317918,17039229254905435388,4051434364600020071,12015292878171297639,15453885981203771978,14205644758031465173,8407133893261705494,4158194057257858240,17149924063837146965,517455439296883085,4490721594974591213,17576487693263048462,616682273206849004,7659618050265887419,3830348717521823198,9299327245511267287,3190759748531244312,11431624742087358659,4901340401183742552,11028064397701977602,940717974116051025,16096089929331640332,12979949362270485258,12154187076417267886,13032213823927499307,12495406162596278523,11614532997245587273,6539205869094866995,5016275157140167041,14684227571727854771,4339901153663265894,2317647729777648954,1577593370680097306,3258967737695732928,10094435047467856980,6438497982826098450,1447509127016595225,14520435171435054723,13129707324497486028,16953451080933868160,8518029247885212266,9338958795150503252,1265640674304360622,3498618161539078113,286424421124665008,2579444161705147526,4721452338866417089,14271318891188533832,15339996132615737646,92663580298417563,17922422821002586094,10398249921340440096,9596143806533167321,128545669050211431,5122552550372286585,14485545562848932690,4884171692350735435,2210937169551004649,4198214426894828486,14897085723725219055,16630212203900506414,12959562148494175660,2536429408293803434,16209995578154922015,16533447752236186197,18341688352687232624,2944686316632585029,17694153162131123716,12775118539520803686,6210725101973929268,1931960041515652038,9850961745277001203,14260455697315728846,6952180931214983523,8737500193064645806,8229732639973079552,4133007920403765174,13196045585326216984,14145111019884911214,5062483569522353237,16121640136078152900,2040386990471433246,2558012148346864668,14639902124605920978,5988773082519470071,7043170928119679846,10863022581712437207,3337829295381812850,1990146524150271305,18109009066602760778,8157728666436466995,18207818521045441614,574640613609536469,747601196859816467,8472009912480462144,11104811635511156749,15024891553897959022,8466494442200906117,8469536768972610622,18090112389575125849,10256464938300313016,2484346212748509722,1354582020065045668,16140460512493044395,17025758447876361999,1045280789104803209,16041709494554317406,9591606157797374673,14602425244718957765],"proof":[[260019168294923518,2684360830529079020,6292463119977789793,13855538506345947628],[14000121148233308943,11880893068645005839,11459109904668692197,6586557071137787206],[2280888180462507779,15457943048526985337,3359441410970073296,7187377427772307339],[9278106893858998468,7780294485908392226,1002866955698677475,4725482727694955233],[13490417797063075549,9003500686233017714,9798786150695453712,17922130812797678057],[6435420677904576753,14674415358422760933,4345965283091827153,11886846369433480005],[13691748221692370589,2938915896787616653,10063896611039401093,13633618461445679138],[194527760981376812,7333844285567579576,3393413100346240727,7529687095650992839],[12762892974590429342,8795851833072719701,6513769366476236864,12276673736240178370],[2857010126244904671,2987093737427066863,9976884854724550129,9156437345846413348],[12313911021835268645,8106183104851195789,3615585453621099741,694763132423590303],[12825180431805693878,1119447864115738680,16942238789450008973,4122133472466295624],[5412536562944888518,10580219236909540527,6205135571780895692,10861808574070796814],[4445263015164094605,4754708159751809073,14538278862994279810,8214460809820812198],[16447370809158012384,14738976981363294710,416631091641927228,17508451770057489382],[17608365128988463923,7344841169915027559,738053527282489032,11888854221056382987],[14058783525262674831,1223734685381543111,3472322076695179989,12739283938439908737]]},"fri_queries":[{"leaf_elements":[1872549093538136187,4763105132529160107,3092708788577785764,1571879300434788643,2994821749287530142,15817715942663259352,14100407232240057376,14504784007533954799,5560472240436597439,3536925783962983997,17052115136564636744,6956095908857206558,6366208056405363240,4731686657642085666,8035501921188988505,6541490903274085736],"proof":[[306115500531392122,13088687537099283490,15022485903733673917,17673804156925690775],[1816345659914111990,11100015931562435301,9151313163202168620,4778710562453322036],[12561959081466799282,17414780172721200606,13685190802292402410,17335017022936050248],[8870225472924654223,13391058952184752305,6634833772532970777,7978622909315097706],[12738639682290123707,1517428545724765137,6653098499484212056,16210882793969195400],[18218482323480129868,13946755884592081478,9012259724788562902,9618444538872406097],[12634318118924555097,3048852526834228586,6219284926327969310,5160936125727366884],[1041275239065059487,3888326097588775749,7165188235439636663,454134115550190498],[13177969971381785475,7449275696400719078,11339128367827733189,493035240257502926],[14730864901257092186,11050924202040037444,6658431980074158426,2675045185361264437],[15540809639294792187,8329290651236055191,3705098786913735978,17507390932939780437],[1037063230749843485,14664610469762288220,17304294991658895028,10494434248729882993],[12279769678883907016,8497946479353562168,15751976405119165447,16636282989174434406],[10351333275933153941,12142588681261912147,4012798614446165582,10948289742999808665]]},{"leaf_elements":[16188955827888108412,1397731986037398992,15341272611477544895,2895226959193109458,10041339177795646205,9183210132826508032,3311545643651512577,9592122824801600278,18116610315533012153,16173663262519066450,12419949302726117043,12098485181303607781,9475147606475815805,3258791715836186404,14669517023677048429,142780129817111228],"proof":[[4522784053270736027,14554022289191162651,14238364836234276604,7829978938120691825],[10791065873303488382,10797604041236851126,2420814214003608931,16857160187047253907],[9486344066507225077,8738642158941964556,1711876230170711739,5824091263363555902],[10271538115212524451,6606374887557794657,10175545348896724421,2647801385491708788],[5500477804026497555,8743423189171655289,16350746681504347484,250227645335837703],[18091661296397383255,10625831964865777688,7336190720352509492,4357903637155948260],[3229265099885911678,16788786086191487527,7398015609278793529,16146238071267359756],[2983233124103102530,5840279662687789958,322475114996106207,1094829979637443674],[10171554260426052666,17513683272883220251,3909061854062562472,8975664412270468325],[11765031133761408434,1890238479774320673,15049995794057208018,9377104703358117550],[5276127892358659024,16578295356712318542,15127043412970318387,12736306873740238832]]},{"leaf_elements":[15877214291688049401,8309987028941799676,13473200382749017596,10539524240977654794,1403946247068730724,13404856413531995430,2503239267644524867,13323681721895630215,11606380367144124893,14971514468790908619,10456926290231499757,14743656838611626076,1375665448106896452,13978798286449738897,14608849695411656686,2480220676157093064],"proof":[[12276645765815691883,18204940051780708359,16263519449138642326,15833675476262063315],[16704299802540816515,4449059293805660187,1463595805487825665,1921534531490374434],[5130640658353348968,3874732026686930725,1446540627482051993,2861329340810892379],[6896403959795474429,13048838547494353837,17233747848252399712,14888614573393614307],[8027693898794803229,11407587272687742422,16208825819013648119,3954335334644720784],[17137930119694703079,10081311911709198807,106421761515695099,10253346757598364684],[1605732864984470241,2382887846547701586,14481892491004143879,17381238418829164551],[14020349378869571117,12637582428669394796,15734502401402495762,5695164799417959082]]},{"leaf_elements":[15502980420302219469,16848128703906174501,12301843658960966672,10981387575983436021,17250520507791646112,3469022804211294332,7205619179773820552,6874512166521778410,1079156210650247256,13362789923162505695,5920275900579714500,8155278983031522435,8512593472594262878,11198926109610612871,7483582570507247511,8294373665403049835],"proof":[[891727278255493483,6731492757971987745,12744390371129243495,1104419600614457912],[18183525484049389870,17681643040810419801,5562644573772579148,4907263401623391988],[6707901680082425635,3958893131483557037,6585393682241306830,12080313545823720070],[9263048480467429659,14365565138492214422,16900514500570431002,14473788162135639088],[18349052270228711893,11686217883027640403,17714450851383567286,10630403265852227136]]},{"leaf_elements":[2302575516032627620,12362913799151499027,9464051798642536856,9178830711071251321,12134273011626767564,17331216040310034439,3969818381943252656,5354494638362983741,12690067225270824732,8944692166906473485,7953330183398708362,5795526181714019468,18009750608913694842,15786646204324923488,12300168099572503114,15145646509267238501],"proof":[[3102152717900055225,819124904820690444,3198436900212415383,8938898675656456924],[1572026914896846847,15703434778445970145,18039674663595608947,12269104932850371711]]},{"leaf_elements":[8872244034292046542,14961388654118324654,5802056968775514489,18302383666416428067,3933647026650259001,8825851261617385151,8616213839298888053,10450361630528634353],"proof":[]}]},{"witness_query":{"leaf_elements":[13533534435000974031,3227142848451792193,14352320411435472892,13534751668784876517,2595236111648602842,8573665626584998967,18381999010126652165,6281013538582034491,13739968888510749998,15358369887614863671,9891036680372707685,3730962131886192467,12067088261894806650,4551939490348026670,9693764465058177925,17220003734056794595,2989333549714115436,11193461621224214249,2416208452527634723,11909705950713540010,15724193007591976162,3827153445180991148,6911457520845037983,1091842283711663717,3298821750596192892,14616860189510689985,10424713009163556201,16013215634761381045,2101375452796063274,849973618992133334,734713515235900278,10188202374355469738,4310604709349578848,17152138576468827979,13527776614062466010,16650877330686597636,7592372093915009409,1408941753115772664,13037056075916938141,10401918821856347812,14212573516114215779,2783192990858795587,18262100345339904134,5879611282211728422,8805988589364863618,3567569670424217780,4346362435743585664,2970225130947304830,8688724870025462585,13017684141809159369,3664725259766972301,14065566448523262792,4147760015104917028,3510294824978504943,12177059123442073063,2967661443045953634,7223562421158995240,17722209450769414490,16500785847318073637,5072912866341383002,8827998960761606709,4470435309497763205,17539926738194947627,3042383032949107293,3421486862373450686,14802555364236328341,6306664435372533215,15653412104769975984,145891096719615362,198524523258050213,797961648144025886,14269271098560838591,17037118932957251283,4850550204437581519,4492702666155855321,6602104528026182022,9561755598882014902,10245119958576873616,18129760645319918324,2948542142466575497,13524829418763859469,12298932583857095323,16106135831800384370,5559294322603998131,14878117595452398297,15854758593228899623,11810823303837320123,12937538641546919835,1977879767589340362,16712590627585536487,13174481215301657395,1583538668679277708,3064872351549383844,14011568625249806214,14018516525348868973,147872675903291574,17861987765472327696,10058000894844169420,18065792886552874502,11766805070436283128,3684123494643705699,863594055493684165,16795653790478869492,11858086292545729718,10751659443537808049,1645376131842453449,6040363349376013504,10035702347178164044,702715329579644996,15858054044576272590,14557453496760684561,2920913452309616412,17535072304886049366,17228930907697424868,2624181296861581274,14699952584250017690,1327982811127805223,4559216047553395623,14749835950990481162,6837019016339092111,13252001395186513006,14734673944371248797,8534027464893273421,3078251970242916627,3613567372426212176,10901660293342191436,10396961982376609940,5142379737705011384,16966210512575498669,14862824658318006033,14192491216910150748,1838265662527909498,1491235046709780826,17421300525992041939,7517600723741991223,15553352568821786405,9654217583669345707,10449477312811662291,2757111132276361444,13156390824073919159,17620405694317267412,12217120991086719446,17427069107300509548,15137038576448958787],"proof":[[8805701981913850391,4439955391466914937,537696646875133618,1275061250452596269],[4332456258663059919,16694789847249519003,17612113908923176240,1390055205204014803],[2245919972976887861,1491343902186479001,3954881556592882206,17214322028614243709],[10867862331938793807,15904423958963919491,1999542139487046235,16099641001808226904],[12191078297095889605,3778379388789697582,16686739800836426959,14111590116224429370],[5931967770014704998,3335149419490829633,7359351306407592454,14003455916575040975],[17477377181093346188,1665273313505445242,2340701627845203600,7375877734167782958],[18426307295142568008,3768872808824527056,517476732810582713,10388935863005442310],[6889916254560648591,15767946805585333307,3734868309116830872,9785273419651391080],[11560432098481781905,2285885531278400026,12268719622604272915,17532927559556864648],[15281800362319544710,18416721828674332628,10433493846825466924,16125590467198197264],[7091616414922362685,3901003081015735426,16225463365749741542,11387253839470060096],[12679304201027531717,13730273341485283239,2483231439167376531,9930969564062066808],[9821063893691812807,17867299546791096919,15147926109497737143,8279330505416890037],[398231122643392427,1077515630903111632,8171464226775056111,3773838388961395314],[7049343954157092833,14391493793205640963,7395172756984581331,5113072916745052878],[14710339626193100422,5166397287786674443,12877026722859487242,10407735240586944831]]},"stage_2_query":{"leaf_elements":[4281817837284695498,15721989378225493981,3048377332170285395,189536640701489187,8284721163728200906,2847642457488718359,1963154732918458327,8377139473220308121,5375179259806761082,17273022363163218440,7397636813882349106,8721842075926897975,4405201244975515467,9123064029891335230,10302783691702198753,1051870710000325824,1937623350808516347,12914046847779961900,18145210763907049196,14743263813557313579,14394041895636247858,11537862838976331773,5576813246250639852,16985546562684082821,10015239419183306676,16139612527488746681,9123211011415615515,11744573447238708825,14923704338196549384,18055800538104249151,5791972274624506010,11386569922452341275,7856762567516460183,17501229502814319620,10635168827959602803,236317294363641668,9648044463520263649,2397579769183415123,7788640938295808551,13424437292142459235,6050312419202571118,559263935257937925,11803355073248201344,9960229599581327235,4999028613964371751,10053079257017059798],"proof":[[13150953194148511289,8900002026774537043,5965652986530956634,10565186525602923766],[6556435420157043095,10550185927684695779,12217995625546476021,13825911074676521706],[11023027070899840022,17304719801189508429,1784384737091602347,17378391643430643966],[10453255537987401963,16550442591559223290,8092305463564154286,5991428974578302317],[10975295094008729614,6269308926664815622,14383292641431111423,540262752640211877],[12941875682862763747,8655018921398799068,3621272655488359319,11979186140288953251],[9248125779171642196,5833728334505090319,3356329024329404954,6312604294733881255],[7048256292916461700,1077410107024950262,9436083982863502368,755319340560292139],[10524003854213458131,2365437019767644024,16426681494540807272,28073408180792391],[13271851086785952323,9556209098305985283,6348752673081033621,17350380175007765156],[15255107399507195780,18162719259506474797,15065757524291086752,3749268503368360412],[16513672158230403702,17789999730821440472,7128013338197370135,9091632982412055698],[14784801419441869608,11717185138125587115,9415216955529335536,456808045198592454],[10594387513554379214,4350224895646392145,17603716797440728377,260942563225835968],[9088403170230633298,4772161975431710649,11728304519422826717,9718595746418649269],[9069739529505737466,793676914951333750,14464203160743970347,10684389483843064330],[1135997963394111510,13275752990064275231,6348311180324878415,7982923292041772706]]},"quotient_query":{"leaf_elements":[17122541610586915462,10092838620467649048,17186614723942161202,10062174521195248520,12540932818166550981,10950294638458978221,8758252568416800504,348237344849571000,9088675784294098516,1326442929425457380,4016758006641567390,9260482463926081602,15975629548003433103,12811206672117300594,13135530913050523450,5422429835317267630],"proof":[[5431189809953773895,8553164106441176590,11201959247701006308,15813261398445563763],[4367969764788269605,5404611839427057944,18029691907017991859,8229710564070353317],[15300553321413822207,2980150196495275818,8794833729916328614,10305690529259077595],[10732822430448262007,6907635420009048163,16531838404634688782,9983866207531849132],[1707777239866554786,8445160559694729997,8478432410052459415,10139940316331925598],[12782758377682565597,3860919253348478494,9644083844839201335,15671945825750713269],[9460008983251596241,16540805105575003757,10143394954192819283,2469584665258533891],[12951817136550995042,8164901510491572349,7265971065226967480,16758186926970044836],[14874712941141884113,14865868993408521180,6975434189710710702,593314991796848601],[3699145777626637907,7954971480756749100,6746252379825894388,13810117269332242174],[6950413255882787533,16992851897578799153,14574338474149619179,10495304921430521259],[7024694400045007415,10701696243834289720,4543603867269384046,14294243493571612159],[6819290057784874421,18357763692579527899,17346031821284485101,15557680002529467501],[3299437787128475374,5521575304056904078,6682366749448821903,9445789465027678444],[4185821918032747897,15735348166646380793,5064113847745346115,8556318307176491458],[4359957004431156532,8965941034467977781,1773912866110419813,4664342605257984095],[12530437638825942509,9467813558315705039,1660881245341910574,6918973135087974952]]},"setup_query":{"leaf_elements":[116633925991568750,14902568962399334255,15266966978465250759,4762690966631189723,2468223540623086765,10306757587224502903,7435578735987932881,6776271967787704866,9118679625307756568,12266167335262665018,16737953013449615271,17637151471209331576,14641187449293912780,10673844365852792758,12011377232005033785,16398705197867108243,11290603092171934588,1412158291231764975,18330965037388232338,9873891568497833967,12363217482941263632,18373538688943526239,5715120037500681104,17888566418592451205,1925561860482602248,2458391032451880381,13179608669162897255,6046912928718780379,1927035887267983649,13116774717237083047,9814507432111824440,16879872622893533119,2179081258697718584,1041361969474263186,13138113646643823761,4331225014999331956,13609649933475766371,13163029078408182174,11414026925816645810,17677302810060025202,8468901881473177336,6593334523831129306,3574246957701006227,8836496130938264876,9232598976854942076,3269239478563601439,8937694793718960835,6425402713655300867,11208673762052690773,8029472064326517509,5812571832841911457,1632271648134995651,6719872989556393613,6559311585181720907,7004445600630744625,15162144200596657731,6761034273203470629,8990742461956548624,10107960235083987824,2894935723080102593,13497425360494563372,3937457220355961284,17640226851684525001,206154366730882063,14456631789445337443,8005484415538416915,10652823810492058339,9467812544154303818,4164878156186545816,178767167131740007,3619188382942098579,3291023450172046938,7917618174179563740,5083893998520193696,474908324322085841,15047552398101737877,11393497560709878311,2726009610033202819,12689752881229735650,10764748995444863347,6929421955712642324,18210942249152869605,18221995749973611327,12895757642411159264,15987864839059803976,1951812145099616942,16860006073988505197,18428310847497731688,10427875415442893896,3493542223498212781,16747699887235473821,7874886583893221781,13160789821681547119,15891326302252075465,17933119711616721309,8240985764691281448,3920202124783178096,9615613502669167142,11105180901160833470,4314688171865359945,5782950717372326309,10521308185834664774,1471964325023326787,15604046728250013509,8297865702359676354,3208111878443242116,9151243467998397331,9824301783787268360,18351362343900252348,9633321658218581662,16827972061080661763,11161002329672113794,12525384536373759870,9250522313472965231,3768885154534072295,5696735221790993532,13775270650077189699,15426720211828272030,7529138205522419686,11956136747918219235,6666488690271618287,5197778204335827321,6945455819528640292,11707562952213623340,14175912736898956331,12991341307311006430,7353296009177750054,11606162068916992691,18415615738450009599,10462922873603838385,11411307398243221295,2471971830194048161,11049910621450590138,10544777618089251121,1599774186165146777,12681758657142817162,12674794068710406586,1562220502938404252,9384068570787505560,5496377289990260536,12789133765439732504,8667678925035779204,194958974532935351,4152917902223737752,10454724958002582730,10245427772483818226,4568138820560027550,7698008278095806845,13189302212307388581,6143090809004786235,12201214490084642581,10070993142519331460,17067754710717783420,12990755617246362844,15341085522930248368,17978082871006709193],"proof":[[10164712021930807477,987203319164495981,8638286633194122665,2020602378625116454],[7038858739161052357,2467639736362220330,5617403179780317509,13034000541238366077],[6818945303909279616,10820007200002190128,15031089039313169554,10926128752794673750],[10847810948409199009,3913306218922352428,8441078874640927384,9926651670986376303],[6999169694115972946,2434205672749204323,15024214485723918983,3099547997225862419],[2547739072889990687,10207756357875476319,362186137227204028,7468465202665414227],[10187430311414788582,8630690879676637658,8781852616509186564,10037731489051776886],[2238466098109195924,9880134581824209956,15108668437842438744,11623834717646063480],[8017382615092810299,1849930717737315030,16682051178535380996,17013359395525735838],[5010662686528373900,12000353272546423010,83794566745662554,13257614091186640503],[6774104887649984953,4388033570845993580,15926423093244210602,5113729167854195893],[4003117454446502828,17452303700165961781,9927626823266148123,16355189743651136802],[11109759175395958550,7832833031311344161,14045762093986741143,11695626156842161335],[9093562831273535603,2587057607836498295,5480189707892825472,3786143531376925963],[9994972003397564105,2959648603750529511,14163024019547965359,2585123501789816162],[7472052915157579580,6454707544650764846,13241508517962884643,7658945900870394285],[11786672773418549703,2339467107386851422,12140533047963330746,7373381974425188538]]},"fri_queries":[{"leaf_elements":[11570661414220231392,5932801261902260947,6295009589588456551,15809129161385705465,6546463052877453699,14490976106721607962,13635027671416237626,3921319219167619961,5876082773942475152,14309069954352372326,9827819208316186300,18181930957064493762,8086661377887974573,11161511682012194371,7694506372809693350,3133214613486441858],"proof":[[17426260096376532919,12696835692269126813,2926071030284181015,1263454352065765773],[1507954837423155986,3561559501381329747,5155463083275073301,3557595644570431105],[2181054457783604674,6748038295491111671,12039113716624171333,14384455448520315440],[4052669693305137781,16576070737663425916,3803020364042026946,11764712892834805863],[14812154973048190492,16041750059058879734,18185079266828903028,8179395072502391193],[3716268554224561097,10249271634928953641,12689126857800978023,17150012636516567646],[3464092933870213097,14494346570138465483,5405305214647392177,7684351255804115052],[4702804010320782748,13000106155704863538,13694331787611143089,7012838787664088364],[3555422371870421648,16353547731906810487,8896309148967838872,6066998508867038159],[12386434201227503532,5111546104892655589,18015591095436412682,11758037429555457247],[7026628706574204154,8919751692345696278,3516460627174503182,16787235276359554974],[15540064237382094286,3313093377055220107,7825057548834223934,5345285968476203704],[8565450714688367775,13371411646079149581,7669076451911119034,5609613507105328615],[2065112813907786203,6898755846797313237,17320045911186699311,10677055216998779661]]},{"leaf_elements":[5851872526907221225,14099300415191218094,2534518731313389562,16576889151813633137,11289690897304070033,3799694535592491747,3769057588816750826,9005389096059920908,2517137881130967427,10296717167068253288,17757212559972504191,11094404137989219419,8010380515897774739,6874607774052366710,18106248185778328025,15999633049560161618],"proof":[[3086104553525289465,16111483078249153642,145182611184679274,11801434721589723983],[9376129040784787952,13797453329705396268,7405307484940122968,13264561625667633724],[3344660968510880450,4926586452999765377,2281690658500949821,6691616523638235888],[6151072457538798493,18280461614013241783,15501721947866746236,5525533145572492174],[17703637705245173658,12070479443818623789,14560334472170663288,2468662088936936846],[8125247284906516151,3051461559929218410,9708316220864194624,10379422222980464256],[13871953534014038572,9254481939564081048,6585507045363376427,7743721745704705982],[7748181275488517347,15588691868138427401,12955900058761573169,2086163879032377032],[542848223190788416,1506785852940021233,3207114844624851525,9598216552803946550],[7872375859433308862,12547335083355183725,2049786543156448692,9084700728308976857],[6068200341678021668,17238405178273883915,16254243979175388415,6326469122072930844]]},{"leaf_elements":[3405033999312509014,131452528372592980,11871979390334496520,15645070602867174225,15735740696554280300,7614015845476789633,2964887520173414133,4169344292744866189,7669107433370264846,6128399978983037602,8532954363556820507,5260004297899133647,15635601410225486949,2248953135067742279,17412046257302740293,15424439075911052817],"proof":[[7877273732029832023,2292343854353119091,13431651325746258764,3111558538421593677],[15212818533987003390,9248968553252561072,11701043395617785651,9446099372117406582],[11846346963405646276,14383615503064487262,6405231366628093438,10580590801934436462],[9429985987472221325,11886231688107872400,2972432058378879307,4695087658858871099],[5924911388547422523,9477022946345212380,6424585157177982351,15058787922047507506],[14752200600324885730,15916928362011918693,17708939923110433162,3063340899749603662],[4425897915657748671,812478123278601336,14446386344517017273,2479368791048095681],[6284005312668722525,13175024327537991261,5546811104920909949,2703000136490581107]]},{"leaf_elements":[6048033502206899776,14005792067325579602,6726992890913653430,7022997116735611848,12876206646904542534,9599104624179867393,10441911274374841466,6781869356582871617,470118762421562141,11653146312230123078,2643594022535091533,823305918950675108,7827467906761545752,9299859364453134575,15561558840286312597,12319391425973398358],"proof":[[14304656299895672068,1943249345902423103,16038305288053890770,2365503321341759214],[12093333448342574734,17918173762267755471,5414736232073848662,12097266919869310091],[9996949731472101347,15815289785699759353,16091488387712227042,7938774201082856478],[15183664090613473060,1501067564438234346,2135154504861079625,2969398395681691923],[17991506096714915795,4636722536725601757,13865614444769694335,8815772354958363399]]},{"leaf_elements":[10912580827303826969,13112124498184870572,5166031771435844608,4246959628546674791,8337537940124154336,2808515550656452715,896327017507608806,14965286150849039867,12366897045461968021,11139471698543338371,14093486012080335828,4141646308185794490,9103831047924060398,3762366279174691358,11512998418801433510,1220189138193510249],"proof":[[10958797391945941300,8725990360423169908,5482578788976588944,8844326393553402907],[10835623355140351544,2411159751067968680,17855867681805886030,86569936236411870]]},{"leaf_elements":[13912788208633012260,16592364955197622110,12930883254427910878,5599575569218380943,5682660096836901399,4069773254031359724,17686759155637027087,11829746095036037227],"proof":[]}]},{"witness_query":{"leaf_elements":[2134444859502472138,6670108791411595866,15206260062045422724,12208103774532084987,16967758441344914623,5753792293204998350,12352376803405243333,18396473736980318907,8950222603878225175,2319028535605001320,8256732945644386797,10307273221441262980,16237417586737952414,11755424371789155152,8674942025458457231,1497210988498141731,13567090946413124749,7801286259772624137,6635202201518432522,2337195839880715804,9521810955908111142,1430823890484852440,12704540762916748097,17575504525284845666,16851770038294453783,6621952470918826405,13152120213040730435,9448913976222030421,8258952641099308525,3101859061815093274,7196170925309258205,4633453885037290799,12710151521957848443,3772449914931046067,6441212251524509979,634997823334634839,12025903139827889351,18150619025988876308,12774523042721038580,7381932896379074688,11067873762847476611,11062221971080733944,14384486051152306213,5370028453248586698,7701367800576949937,4631577822926950963,6392487528213074580,15561773138231733402,10592850454857499838,13151516806329825319,420516523592634920,8149095062044239950,9505273267956277644,17274962571576398216,4107043442676041267,15708263105830584894,5226001937550131294,15608036106465445325,18015879830457816004,16870827368593711535,5066773920979666847,17251802940193899864,15541212494402096727,3120357820195751211,8929438359772732387,3099022258526539068,5659374830929021204,6319049979350278771,10760893002278891922,356522842432630616,16563587579638972463,11674709776111158826,6672980578908993331,3887958332603894260,4286732862475373207,3383812184775262649,4520120506063755167,12310650577098002798,14057956759582495568,2482018392831272892,10387086686200103797,2411178006404171630,12771997618679088112,11279096957090301979,3959717862550502448,2037507849327696758,12639665690909095444,5757056561950260249,18282200573558666277,13664339046268133025,14668804954199549706,18436630278221459355,11031627574742599963,10155384439877073874,16849162788250787225,16138963149934624358,13429639484203366923,16546656236212976702,9638981431759885489,7778577175863218390,13738072927702826978,15721742230899855702,18428474231693341626,12858783217717441724,14682017705372112620,12786964064001643560,8306084965632114502,13582274773306568584,15918028816827226272,10269478649703858145,4637279318214394455,12345982820831695813,3038095398463038844,14818816980920205780,15577852727820409858,4949636201349970219,1715535059781074555,15061856814312767355,942263041487526714,15731193857766392167,3861520795257886786,10632881911748382691,12913901046038575086,11262721114368268146,9224060330032688334,15327904143151723832,9066498065923757461,5524672073545380178,2288419197158160056,10291473558387256707,2927058630144140999,1219481238157240593,9595058890631090487,24622185494466620,5408267805573740769,2915330463362124195,11200937725531226638,1571896872190336401,6352035718957805361,3309222014905470400,9435107244993748954,16788752433248687130,1798758479438997343,17479935867805372194],"proof":[[15110577258407681691,12211916112974710467,12220921944970607940,1705690506742329775],[1014916033684588638,3080428179195028279,11129871696929971788,1101554636120440323],[14094839005437795098,17843695761365770316,7877256666969566105,1210034719444752597],[17875579090336720688,9791046801984011125,10303925243448286989,12947556332031162883],[3203102519169685715,5074290431733405266,17125021098777258200,5427829091214914468],[11502118470458811416,14839684825126505841,1390183247086074623,15521707964002225450],[8713283788058952760,11887698921506935090,7503069206174713226,5243121859070531732],[8217888007301135093,11347623635915004788,16383661367414787381,2103940379841638729],[11543693211399385375,3589155663672010235,1479720197498932613,1714937042513815641],[3857089368621128874,1502612445932475716,14570817730075365616,6605329817085416330],[6570470283501436905,4885148533876849126,1033183461292415319,11179319713702250873],[858024287804209077,12307045606320144875,9643738736102327125,12655412492729886452],[15931410212488574696,15127675710469511987,3887787282226139036,12617929948786624150],[16581688132622249688,2106959062612208607,3103180904925767904,871012131143251167],[7501650907493420589,18115417497264427321,6912235817025796297,10801574402201529497],[15235335116559186392,15892416953483269590,4257562188192374003,5435506066485901152],[13917355053280016149,8948925822613976562,2644449230881192143,17693607858324556593]]},"stage_2_query":{"leaf_elements":[5674209788770634315,6185592373672099313,17532483512613350204,10425250035933211686,7699787288265268222,1202828179343211402,8621057686394234400,15394251123112769220,8748177813153566582,4407672035857674230,345749543097093773,5967878494725820215,14390111244992810095,15084023813642446832,571084776341678173,8079057715707413961,746170316666224005,3806636875274265490,10303979474948737023,10042887683055801045,7268936171761605675,9429672345735393364,7961016408993669175,4345202605870483731,11937821089331156040,11603391144378579051,15656121095582648799,12689088092107423772,8609710671632647760,18382367681654456904,2539577629142026218,15455608923574402466,17486801255491159603,9146286649780593747,8378774761266398370,8148578459688537191,4479953135620849718,5162769105053200027,10913623008925970311,3320687523914629915,15838512295005082637,9593091613192332431,10182528407409000895,5210653198687894018,3333592683682497892,11519382636537324386],"proof":[[8809278293705770278,17787688357112389268,13769131809303024350,5598049589698884146],[7902683775256257676,18227279498156943707,9565239033831839015,6056556983884475798],[8971913122942042778,12624196163289865017,5930816776071504424,5652093980713522603],[7655785930423862090,4989267077850503478,1866358002331883867,18075809516775039582],[9180993194474217252,12304520932811239548,3450797689660322795,15195755513939118219],[14104455228874124129,2499264051749257588,10069075955642213212,17900459449857927795],[11602564922038267116,1839730631896322247,7752005847515510016,12699862893157990787],[17211637475574096785,9061079352583999627,12212813816183694726,8275219523818242109],[11138099119220581991,9963400842770458187,16855210287125468209,4073769119609446088],[3756096060635956936,9083320614911524060,335462961293685449,15040295050249858888],[2744125941949285885,2723980327496368757,17144809115771340191,4712314342039948606],[348061908126060896,6750843956589519282,14978925111532830491,385729221342216911],[4864789656258109071,16661654223534543821,6698834674326948745,2060648789422573818],[16546993396727780035,11251147440725635523,15284460638958776668,1346012661203881008],[12418543669626934534,6928769811354846007,15413148634109126874,4257007887127773615],[222111210970722296,3825106050610300442,7352119793866497368,9694702305784944945],[16102002282897089743,18295213055960652280,16731926237739983378,4021316012502111925]]},"quotient_query":{"leaf_elements":[4848529070651316882,18061840806984035754,2917380675077645936,7926830868224644422,15128884965462390493,16162649566734243886,9899988947430792676,9298896340975684790,6379619967504267776,16148204960645569964,4177296906610450683,9465009170096359128,15522358221743753683,13491105784773061487,16951471789967525801,86898207256706049],"proof":[[7576310050768683971,3938207923926192285,10814694785980995171,5393443231414131909],[9915750978973439514,17876691042304507373,6865075483820005963,9407709415558356820],[13974334129243433894,5846977572395818841,16838317642044788351,13971090040484495517],[14443822337571395969,12083286834004788664,97907312764405597,5350052393383491762],[1027209313080626672,15802545503343808537,5935360367909461688,13967333706633848137],[4130472106919200956,5758575637990644164,18250837080031144506,17333138320554237580],[17953009495747643447,16837658115456687574,13937647301698362943,175929168660056111],[1043935399664218133,17662883901231412872,10675651752189362918,2909470084007833342],[5316588564654577599,1442795217822773286,13135881503614885616,1586380747972287476],[3228727005570916249,2935578256683073310,13579314132486745441,9189794472819832179],[3844763138080386600,15759139563299696139,3977831835081667495,2621949811882043542],[8924845757171338087,6816420596618144954,4045926783254197391,6736849012315737113],[6778377696499023832,10726858212754658653,1241902643183519811,12815285484342736560],[7173606864975952245,9102691760628005646,11976520701771294450,7219685583344697845],[13591750814405290134,15452824294704799313,1530802652222121807,16753775283653918996],[16741468966194098236,15350463128901316943,2177702121472861379,2771647075729034050],[6281296206957475465,7421984504665194969,8595830836685202410,9223965952567029697]]},"setup_query":{"leaf_elements":[7688938444218392766,3412909951965536907,14542040626123721605,18288341413865370869,2727168666633239540,2688259898582473787,5792724676178020862,2776831066826764073,13617597476525636807,4274598404873781192,1076059535180958929,11107236149632141453,15407626504862933336,1158965291596937482,151420506394134678,1852040145661353812,12681086549574029233,8599152600248234495,2305220727960829737,18039790174168863204,407169452504763799,11859946831361969799,1159849435438939626,3331719561069445,16422487604591411418,9801849007875796337,13310309663435205902,18167419153506666691,8892960551001090168,9453190433585007793,17706716007939165252,8998121626712314925,1273651350850566016,9001549972452800541,17847208510320646733,17699929128286235029,15987816404266117743,10367889579513202004,15412335363656391639,14128761969895068680,11089037402058641312,11067362598196293299,13563270453009926086,15579213006991303144,11102388957490738257,4662733869675126438,8539321128510749666,17783534940467226758,7573416710054774291,10381488998613707459,4757599643097751566,8904398130892263810,5972823625211153523,14505601464355544584,11739163186887705203,14242300935862198969,5636975611589397906,13514589303970410130,12847742773189838828,12280464623842899556,2808596339724633179,18063431945149518848,4456115868567250355,3920402078103696805,13703699793049450436,945410081583129683,1584659684052563513,11541216213241316302,13430138212390278677,1013817473734463959,71726736013653947,2506883887858782148,5965310303497941877,3383952225636722542,5544846129338588168,11090367594600367332,11649636965607782821,7827426960399282423,5768786810214425369,3503077673526431070,15384304369396669434,5568844477043031414,6401630779154671934,11682634689895774867,9036729067902774278,776183396240720662,11808548617507090826,2360298997794917136,8254479811886986245,17496264101529645104,15529634927124871503,3781092371170994324,13509269450882197150,16520156420716581091,15382903334722863601,11363809337662181276,13728179198492937001,8190259486738768592,14109280595144548500,8063798949146817975,12053627581096794187,2881830378925550255,6494658012627285845,4304974671706310171,930782398273461083,12017778668911020039,15675905683709066666,8472552555224036054,6447257744245382306,8906059294350086820,13839679943107489988,6164169562392381424,15400303277860237645,10850872337569824040,11660382473895356820,9954982814976129667,7702396513259560971,896323316106989814,16603185147193586446,17183029806739168070,8052763339771626967,18045906166511724081,6053854062013590536,743360406368852705,16455696120196996022,2903736848942487857,1192158805625755422,1386278065113071760,11439882369038816520,2641301799042849013,5045742185996773582,8220590250208217744,5894963440982627990,11122446425656137943,16803386451394161330,6452907006706752261,18218057522493299494,15345424616763276442,1491973970772925663,10462654739113112220,5808822878920750093,6432507021640280018,13111110048674004278,11458578300159106910,6423849256585366993,3142608304528629112,4124914253015581120,8019239619705963027,11907809464170319073,12388508302950788566,10499605706008940608,12866453228921929531,4597467741854925604,1343483988658131271,1656276438229220887,6862201595893828060],"proof":[[16923561742945741906,6473622858403972761,903359395068397783,4110294640300856123],[955310345835070155,5533257134131089801,8898394379112476065,3760816368699966840],[14486820360310715009,17868746056921385023,7110396462675542034,12497410057783318788],[15703196658206225749,15667237984746332811,15846897712478876600,1033949191115063925],[15703345810116123165,5865017996987473267,15215863102968769881,6520395233666711295],[7901827736562436022,15939555903149480402,16406721966689727156,8426354581318040035],[9445979587587391776,1224498325808061811,8489062381629485793,14262850810070926749],[17353680034464311362,14157536125217326025,1722481832520611064,812457769599511381],[2783303864842570806,2267691155360811909,17438249380137402122,509239600045615808],[688308687451884597,13018054554107449840,7622122834049267421,3351631791266509662],[6969743566048075796,12126782065044410649,17016526439220274093,8857693226769656618],[11740432385041614709,8338893340481586995,2052603227948223673,4397794650563348062],[17372430544314550407,10712140928334287661,3774456714956416547,16897771288086538358],[6354614941920409275,8026318157405845965,3801290116467027226,17418615910153574109],[12313797741473773335,8370279694053568924,2668095330885991714,16247303786991462407],[18020275633595426801,14284626255368306249,16056288697478984106,15264414679822005263],[16329307129806985023,9953934407507996651,17796105896734973357,9595248702518778663]]},"fri_queries":[{"leaf_elements":[154692025759342918,7315431288268725466,12736498538669458124,5255135800342316940,17806955111826133290,17984538334800243207,11740274177618075011,4556191033862600618,15068422415062923406,8666370212021866550,16336164730534826132,7939435333324024542,17445762955659332406,16216368177080213771,385803616766777375,12930132277396344926],"proof":[[8886679825141196323,1827990543563140949,8988219985019820969,4209426788691564571],[218812473950503182,62406545582945259,4060246171399720126,15434981595592266857],[790879003101967441,2647172809961615991,11644769707947989210,14270878867956745638],[10024618629061983560,856386829849574002,10505643623676317609,16247770096149150603],[12222747125129443422,7415676419208578096,1890358772322755813,10961757635943762687],[3258162827831832326,7365381760245222314,10944059239231559422,13131075265897620765],[10104126497332625635,10548152279389193701,5463903766714915077,16172085485951145102],[17498600236502451647,11295405769695664284,15033145481551360042,12407846066201694795],[6952132180318511636,1403920837835743714,15304650304655987386,9246293400976783522],[16573912942597683655,17160150096627479532,5383257575759464016,5948748814396215930],[12608270661351791133,16285583260893928652,8383506067597272514,6920371796431182049],[12061299832243980857,2262651034190947857,8512034167279367103,15445060271564431603],[6328309673005062957,5218411992668026111,9409018391366369194,3797432641586375540],[4465615647496587512,8285173340571531709,822663484090032335,13279897163627865773]]},{"leaf_elements":[6130175930225374370,179067243117581369,11941298377256447569,17777545983819129977,2428893108907455093,2176009633343220117,7396038615179817188,1384617314384424680,8868835301578395407,12845002541497549941,4309177712613611188,9034710103213857210,8965474275009914557,11850655987517118840,9280360618111836673,5756499183019684318],"proof":[[10852586059759849889,17986570543584965438,16345961169513244061,434862460087438388],[10395770619257399316,3517418114736872801,6666946678412546231,6932562201216593871],[12412271550306281206,14418130917547040508,14630822470947844025,14857535759954574443],[12639854922494351863,3423481250311191515,14053800558749669214,7983178440537925310],[18277894259413475318,4735646765669340549,17210428131614615166,14682587397563587332],[3334390465913750506,4415189569661362040,702814500582697197,6397544709952400932],[6925379922787705348,14122998392323472629,6228071951390082667,15059365692486104158],[6410922865528675024,16765725870225013578,11350519013521847290,16055080845858102790],[7552597030581678544,14047686555188753387,15008656695288837116,268626988935643942],[12672013934825332136,16877324709889442104,5170910431268595671,17126302502851201712],[3377987416368381751,12702386094819947235,11394188911260865769,10895080491670436673]]},{"leaf_elements":[8931177359998042868,10938702218174626380,18059022662822944141,13107969312108634046,1754716596006371347,13512195925634559347,1441213711812221784,6093276014235900093,2726953251249539954,10212624642377048828,12653857715639149426,1538703665985987547,13555455845807277667,174180459424779334,14870715337939518540,17286719406845529544],"proof":[[11572445752314907981,12229515914861346986,14356568717976909367,5509867600688465585],[1880173598216916055,7654754552237632782,14863856727707240803,14838841452444173058],[6865436724941400305,13617697531748748359,3271995568428027868,7389783123950501014],[10622964265765756848,1494792660982188735,9422618380908117722,5843367955203199298],[1858716062974385003,10597021745171535033,7012420771360508968,4805418730972281628],[6958836402676814456,15085331330946992892,17317683594540289837,13876642830987183325],[5459106626098609109,17153598788501938112,7327139023360808886,5992005874010244496],[9032826725719266629,227858595913098862,8937616530513623233,13597688038816946759]]},{"leaf_elements":[10461546856644875091,13472687131413872705,7530958574901110105,14669665545692886898,12649141023127050581,15304129342512009292,9569163979857680135,3383860142323540092,9960549684924497463,12230791802232001933,5050100132938316642,9716245316925172916,766770471472786140,14481852943068317741,6243621643189626645,13692376961089817128],"proof":[[1880287177588670678,12647163855316230204,4526918525112284913,16434269487513737761],[9891103500573815583,4523188741704837931,231679708189248774,804462343280461388],[4933515625237573044,18136985165549167844,7391218887651494860,8388044862421051871],[7244971540000740526,6946560814218976240,13178592776491907096,1127335393888409824],[6499859092204384521,1570252448210781983,4297295299120074783,11214492741968423331]]},{"leaf_elements":[6286420817581793361,4891637005521315639,13243072748595109385,11749052924181860372,17210303019355704229,4258488926435668566,4292489405267004336,2251998060159949115,3530005094630038559,3360146570564187265,10760944650519202096,7038583320611695001,1172457921306657294,11408269057328436050,9058433179278183378,15228689396594028901],"proof":[[7413905529533012020,16387128209063711862,7660761031597372183,13314059306427600863],[8522820198600300673,13877549476641228323,10358658571474361490,17789923675703019552]]},{"leaf_elements":[8059053765769322751,13417580637374693909,2911351709503266961,17513728947462283680,18357528550657626748,6795100929311303227,3237676158979040141,13444877005340907045],"proof":[]}]},{"witness_query":{"leaf_elements":[593872187149036775,12367550318992735430,5885009993748340797,16723871453435874638,9153332502519452538,11507135533595870471,17328324748471351660,13905366847042328585,5448948741199642250,14281485510362073650,12757215899738221913,14759412798526647785,13877818650209333558,3228898646734939094,8189075360297753867,18133671597525497528,17084468746793063875,1179781720377806151,4613658133109877634,8786662018326487998,2601013879360490212,5173059977538904835,17883857689319593306,7726212272478670931,7062014780358250120,5954188955911198750,14876964441065728708,13468799579755984058,4050845047350814728,9156637389062980841,11907315064179949256,16900384962567085719,7509518164772401254,9654711051298632059,2842215973107029036,7006616804245194443,13963755662505507813,17858403073382927115,16038795801406940566,15924863593008273472,3398984119482605384,15750222530521790147,2895023670154465160,17714176527779215659,9081817668899396181,13160769340086755309,17065041021278488616,1459243283592912343,16057151016260438259,9252721109427438744,11829468833807810569,13841127442280806728,10793794876989296388,1440761377632184978,14324149227283582258,10996341892901131689,3835361768890318841,11846247734064493798,16650498820064902410,5967391772284717276,17545692820197994839,6325677504259505239,15645515907032818365,6940047177851383212,1121823552977984462,9259582151914525235,15924338823107033196,11304590447236652181,17640668336536167890,9715180146900157397,11521533584144060927,15522703470067209371,18248703857242328384,14845048453228671687,1830494283462664007,17910738934612087388,18330000101901827876,13676941497478572468,13001435286007218149,6763384218998595812,4984108954617934675,3515762948829167262,2556428399550611269,6200843630367234955,16977645727901210306,7220356056974405171,6973305597838667677,12239069167557965987,10860511035695851963,18136368308242166354,16438984265639949936,1852653402313130267,10348198556815886594,3078271704044980747,14569561093603579239,3683258939758430360,4673637715380704793,13757161404267743563,1219038724838939626,3322124262687780665,16620047804315143275,13045396840249988880,10754732649773001558,4262433497337638285,16584299620073016805,5069445434413239709,5202041227487116855,14109256685778181261,16117007457780895196,8086056980352784624,14187704365732061394,3420003286276537416,14914861263426281017,15439944791733255593,3148816155758013097,17444771017992668046,4791604329520850338,10236740954541436853,11954471285401163383,12510704252046761575,9731705571789329962,5221595095723714721,14435877582681383399,2160129620514425876,10830090427776615843,5537403218884548126,10386961289195553360,13861215526365374811,4616088083447022041,9215090356524826229,10913521144929997141,11989701442772869623,10495904645108395325,2335104668896345950,11978505313847908565,16834998775967046474,5675482024710984284,12594371101434965090,2558667911519891052,16115180994318795435,3324100167036135470,6010511314140624118,12073788293551477564,10932949965343699026],"proof":[[8026600393894384723,5551881410920894652,15822037739215546407,9610830501887140773],[235917858090326518,2532276423948139815,2837833695810233052,11543020109465235716],[17747572582666823966,10414695203464079052,18164066463723762269,3006035198262908070],[10096776334583383304,15920306420097132038,8233600733245501593,15393802573195689693],[15626895218306168754,3185244832697833837,16086783269157282923,10533751970576027711],[949078636833958203,2954214523724639892,11069187518222187736,10434387060018764796],[3325008965870600127,6776566857884494215,3768856284510976955,8000476427493162945],[12638065247840891531,2862021618389377273,17410859400346371611,10897901465329413410],[14143181261509922769,15842470698120590414,7596357318348715531,16243848082575561219],[301543732443137371,10377669664103222827,17788691512015054816,1572088726741423940],[1590750351192049554,6152740329749518870,7243543055955068199,1146141135378932826],[1405332901856990725,9834683368575251969,3101095179029954773,16099169942725225525],[12759555050239305223,2049983811007430236,6256625091037737711,13870808364038057296],[18388329577735791342,1430392883690865413,10018099715881943372,17134357446701187204],[11447950177152928470,14973270498751062956,13335276167614490038,17157951216689431118],[1684920909900349610,12438085064269544741,3746918374882824878,1200255243420519331],[15531624426577644058,13865094955186564174,8472382933617714768,9186383827036465161]]},"stage_2_query":{"leaf_elements":[17408343858850597455,2044905957924193387,2571471496078451083,12903496830530162838,6347283836288595001,15130017697178061371,4738135130909572278,3937722705981045997,9840328087837455844,8991069994164127752,5174979734815296687,9703067861908879417,2359829241133208964,10522264236295572762,16213671490485380700,10328125300415430798,16550118263506677405,8290658860841383974,8333947091361752852,14643683031112844633,6343293547197893283,7586811884851965442,11100790182137531674,650099213330125963,3230086277726015319,3042190750366946172,11897089261202154605,16899235525721448842,11696983448788033768,15190132117957563708,6659891138235347067,8261424409800742683,14266927463847836311,8763050993184753830,18188868463012752391,7914478201683787650,5841888189246774935,15992567203782003123,4385659160189862049,5463772078008726176,17037535260490393731,15124299035080041917,1868282431320832257,13250824872873461174,9045923166603337759,595597000984666772],"proof":[[9174699019406675861,6759317867471799913,10300175214705179963,14210883085109763427],[12551934332099380383,9992241459152465952,15765526706159169666,4884079858345334854],[12825015181795931595,15255197290673264622,2135271122430706660,8339102917357626273],[17888237396038162529,5179790338663305451,1353539642166007732,1456733990320798400],[15394029374649314767,9878088480520204146,7294944775328887933,11021551650796432833],[15729612302602254744,3296758776451528037,1478194791995001691,2839159760848550755],[12898124723043386061,6033614145821146061,12726443571288220907,4570364328286218835],[12588036305801886829,6086922958789861250,15244286605003123683,7816392841057667962],[6465658348208159726,103401474033979942,5760046333399171122,17763190025468868490],[6644743322301692155,15475955959094141926,2686860787337992758,505500918850745049],[4302249113943576817,12811105029808499190,824398197788949955,4561771366207971260],[14202106410919872633,18000815605829223572,16510881673122835289,11854329550665043794],[2115274839823951340,3782478013762022551,2283399851178384408,16421762535317426284],[16628480523609636855,4237207823763680007,5900281251119400478,9607018077110259268],[4301359209673334540,10005856867749004066,8694665432079740832,7539561465113842113],[3733678106888686941,1708510073092627917,4801889306091087792,13847471618380368151],[11139769588175042309,3395418516901826134,16872320672903789189,13422806634613587681]]},"quotient_query":{"leaf_elements":[12653116416015317883,17930448377144768063,17068272080489784507,15095781628174477949,5342769474528535249,7268748974504001163,10125179538138120954,13852502494552903673,15086635910226474210,11399402428055224024,3877197898152446101,1697977802643216890,9427555667206969247,8984208695558761389,7378877079307019642,4735538239737015317],"proof":[[11240845251201084553,12318031939258254149,4560583314621157016,17994032725987632118],[1086876950298758453,9154073468312669329,17952026971054106930,3564124242313656699],[13502359463172584764,13895554635576691085,17000573083936383393,2399749849178905634],[12792687902806617803,3648288779806730621,16765303080080907728,15143410096622513843],[15065485707150301229,18232925026855907791,1969598070643852787,17855959387886122719],[3039329822801297992,5370501593753776776,15246223070912716429,9039950251049513423],[16084877981004246972,11886435505061793548,16614679052539589987,8164108408932714217],[13596040459628910262,6857152495695284005,16268929264305805786,7400119862459893206],[5588850011806221021,777297007925040224,8808068754519020965,14868855226440307075],[12375179109201474150,4552644699845085410,4508106618232156440,16556572277560747324],[10638786462405255728,9543461730908150384,4683189627811268116,3306870920457030134],[12505416086716476505,8846851059399801678,13150055137755342455,8983839234259410994],[3332735058062746230,16043426747124295646,12117854124741109940,12582087773879347998],[10214200183296205275,5148271185226217373,2165548149610081745,12668694662401733725],[2669912265353019975,3863530204996131399,18027659083432176280,5995683832767527638],[17485242766052239519,5516948418714018096,4195336187223058700,8635621805112940107],[11697277180110068323,12262495074403684463,10030620939404639532,17419393265831488427]]},"setup_query":{"leaf_elements":[15294139869116892380,10401179317242664298,16125541915325190689,2905207699382841034,12453758438796099062,11061959760955820138,396175126925304626,7796882126896473170,3842721998743146445,3346969197628619263,14816812440190187306,14749173783501608714,12777795310038464228,12152200013345635378,15688370442849280110,7235993680511166521,1538058779880563456,15267270007153580462,4379322778020487086,10551465742033768774,9412352381965355494,3317885883674332671,13227428312726559850,17341450826699691713,15522743688175878173,10805618551322156466,7566944485917983899,9907100739960859559,9571417887255913481,14536964191077121426,3206073358888750244,5630064032031548504,12694017479544403819,7288243741662572157,12991164564313574193,12253747643578178886,1062254061218260749,1405476520834354215,7702819635977041037,6327702771075080325,18386043349240337839,17538894661375297369,18120021920351091081,18350447856099888240,11327739068906780716,15645506240054703284,17403518833348343760,7788619375679975211,5632246815148014954,17876542488483843809,10919130783788917157,1062717789232524960,369163482441669210,14211177614695007281,3076530793153727572,2093256875043738266,6328255877898934272,303272689678257822,3037303281273125448,4464245887460708097,582397112680503544,9522740053898681162,7378600586631764823,6445518913774624016,1245889108260962608,12060424701135440043,5435231183506482077,11317214266006997412,4769109903716968138,14553236040676102296,1002623626092263001,18023185254436047090,2517647733911112585,3289120584717324010,15257118734318507487,11239915521669329791,8824275391303869653,16015334600861294385,15353284114863339939,695122245997416095,4532565071731090445,5486494802628187970,8598966832421189805,14269519121479269087,11838404171477360224,18207449636247747790,601356157081231801,6970378696313191882,16758396416658535610,1569756063325169608,10665132812605203140,13099866107448195915,10914302803420223363,11523533573193016786,9668019436051399347,10882526090586348419,3026759108832251003,10597596681007034620,18191871239826179983,8242708449051286647,12452481623236640172,18130303302308818781,16706798608661071290,15070973071807933355,9500517032080602301,1552966475016270110,10236388066119316937,3646164484465769918,1798389567445208178,1086929138681749711,15522978992595481854,1901923323725484015,13519735276239648366,12829438242791793223,15222523333021148391,7272655063819628342,16470903293108724554,16628907233569872889,17927498957023307418,10093742819379570826,14647686265648361893,4882439238642506777,887953160955887737,14477777749241223056,11149736533604701400,13442655143372620307,10849249444535600734,5222109165024475576,7973299690917577588,8357160925968793574,11534235114975825621,4615408818924681779,8545263924780550250,11275845643399246764,11044319728227805015,7693188598427785791,17331935878177939766,13208829310169924473,1662510197062581106,14516123935469578300,579469499856240157,9936341357098929068,4699996729378808492,762830583692323955,549156671714634068,9384339448849113964,4798988573987541826,17288099539629695899,11557117877959230021,14990210834716762601,5830594356353384781,18348613283222136183,16999370758704968127,7072704856058457253,15029436129058280962,14943425295434665004],"proof":[[1787971853327175854,12276995092429634097,14380036026003377542,12288573769846970462],[15177641931219909149,7529911663093642189,11774461091009913396,1766103593504462862],[13342513217386092115,16584017224480975304,12290337656796700097,18130800948828255449],[1953314174882356364,18025903375148641296,12404982157073030654,16870435178481436364],[10096922349585084125,852097115584391583,17709634105667353732,10156348140772376452],[14417845836239759574,17392924162382299493,9403276638474555784,15634317610551673433],[12732523035844703595,13770347179804484245,3559880571922789949,17352771161481384772],[16249578757831624998,5480965191794664299,14498367649147671393,10709900381094640421],[5232957170848909006,3099229967957536318,6655292645831135393,14779567946213591732],[7092652049954889137,11955918025355178059,14388231591473149843,12436901531289436807],[10271605616909264633,18277684122284783960,7486081077205061209,13483054077591551223],[15540506318213734976,10851598247419373907,11614395140922770511,4590863153809649941],[6133606756760261993,4465459644845099075,6919242678194270317,13022008625888078357],[6705254846034163061,16118057282497002874,13875661086817984605,17067927050039625104],[16728405997915879866,17762095587707393375,16931561793509719617,15757934168474030627],[3290374437558219455,17397892016632924015,4048917788441125437,6821011670244156541],[9581065928976518234,12135839458439982826,14501700026775568689,10922824617600197260]]},"fri_queries":[{"leaf_elements":[13529795071309076536,6765643600344360537,6258054771592083123,3642473504315672793,9627062888440838061,7329843005591542629,13782143222282051824,12963068552947912096,16131943408257683047,11332371534232316210,15048304435629976520,12473382996914023599,15843142709236525840,15634417269153652013,6023255189890857275,4937574300883196837],"proof":[[12843251350441506273,5485962410875476196,2606117800987771517,5344184218076011459],[10210091835048384668,3621262999544567264,2197850942466438657,18042910888374610403],[836230086872497205,7062195834406539271,11224436735891604750,6500188361525860996],[17842293665506536181,3077808612802441059,13197639093306975182,13011608548537525128],[17023867302068221407,4753095733122862587,5465557033496712182,4782638669030715008],[8040195449647740679,7718020961111723497,4887107472769385490,17047448394319179895],[10025997719262944055,10519074339642533181,2487010632575058258,6896219936759426614],[3615232291812147275,8756628908390896514,9382864531959589998,6090278801032602537],[7159035448788058779,4590702824420079685,1850652386294905670,12289584945576375245],[5557778283551841643,13562318496697278024,2920956787001758576,6050205570703387246],[6865137402639942138,10132958510298726043,8362587700731162950,9437619715091219005],[13144802666077172600,8713503867130301936,12725946645926178852,10677606066406196697],[1321225676741995457,5002192773840269981,597926072037421651,1398311611851514421],[4013925711984337952,12808912816756715575,14647408150579817702,3065942723487455518]]},{"leaf_elements":[5830594162929529830,5827010081873395902,12416026934331114496,199788371911375923,18106968015601365655,10881835997922416592,17507907975118210595,6912638946489300388,13150109915138237631,7559265635998856431,282528101787152663,16587223739902129335,13990015080977070021,5308709688707900679,11927369353491279989,14896222061536625148],"proof":[[12317701519187278944,3534750392387185231,904055518007364177,6808995528299258238],[13773465028528334424,6035690212352372292,1987039255236635207,6594629096700387060],[4473066518680461842,2779958964019468098,10752616433105345909,11209225500038095630],[11278675482926037692,4862801761651322132,2584008391241252147,9457326057178449136],[5376828681812511162,967827832356972245,1553111324486918433,17510509011570549706],[9298723302270625201,1068050563080280843,10682278565282722220,17286212038124113029],[15219763678931680726,4049162645531315164,7855323585089621391,5588728008404600246],[13892570783708715752,8166100593277795189,10542869256025326719,814489202776181189],[3725957878871744880,8467549658717021588,9485565277327412942,11732577308346568693],[11237239552454366304,269214822760849939,15087353558995165612,15231969366643715357],[14386605697277095907,14780595627292032292,7787645265485481351,7681369631244592202]]},{"leaf_elements":[10431269287258467456,8144289895957369115,10956463250855943284,14891973362004391382,2531251134484109229,10319804458714147391,2245816034960233192,1032848184102479876,16789714003549956134,8424745529756512623,16305348581893636880,14368898726555031011,13558969070929346486,11622843748650950054,8196755043099906411,13513366407807316655],"proof":[[14958479239873107674,18116699398276321738,13763995643578676653,15237799641759900581],[13481062931433204135,2859435570868059397,10405490337084013823,15577525515671373292],[7612805709682505966,11783293333580416962,8471049559392933035,14895264618168092235],[14950149132071708477,10302888040738411381,17512848185945691491,14584934551865074053],[14105426905243818768,12962083984765051395,13352070851338143377,7696973591685846738],[10745761438051268672,3976269627218244991,10409555577972490176,17709988815991202267],[38662865275608526,7842382810436525841,17126549131666992464,9456346611551948765],[2140196684590980130,4475900447607608036,10467238145322070967,6718390191579177126]]},{"leaf_elements":[4195573817296666189,17737935684483690938,13793191301127291050,8707127553883387283,16850744356137981293,17237939055784162326,7655794177292415826,6216621892184530708,5629535999119262863,6582693307105263349,1843213423219156016,4806986215564460784,15357299360896160635,14141993522340751651,15865192075798466317,12093671722769618858],"proof":[[4904629051730339263,10959227757674552421,13154557080527151464,1409317529726660029],[3922598369513984406,5751164380265567356,14671308890674308051,17634000476481581182],[3659180666187326936,8967273846408859879,14735407810289036837,11829192976105676096],[12831115212201283630,2021654149849164915,4866697979591898407,3963523862788363052],[4058304179733633736,18279683539181582970,17086072377035853914,1947585076045058930]]},{"leaf_elements":[17154985130103437025,11970188327225638528,10683314450985514809,12432856952525938526,3681463913109433617,1370543623621528820,18064695252079559213,14056191522051667869,12830714955889098383,5936734090336409171,11462448122055380279,14028662054105935114,9650789450882255604,14842665215275134854,16742160424854962953,15201628892638301449],"proof":[[2624410923785354201,12886709050758138890,5165919856831719521,8193115987328637285],[1459326226627952671,7768976976853534276,5200236173962639007,3670101928990175113]]},{"leaf_elements":[3103352029016043777,11936003578925779291,2481494059698405049,16760758113560209882,17943014902864064829,11760753107849584284,16263520714716793081,17159242401050750845],"proof":[]}]},{"witness_query":{"leaf_elements":[18401134820076822734,9110379376206373400,11697472477463386302,10197628045807242061,6840408524040716144,3226338572111057725,12093021340622451142,105652815756978530,12196185997075966348,4781995429137825908,2361693646753740670,17235787748603133924,3860824961371938469,12011125350357629380,2604800676775716455,10360534811580741292,4879706986090190417,7637944129294674179,12165400725501699761,9322556083386948052,12629722575203859572,8023015499293734564,1258660666396981369,3904052260704928379,15544240030233868704,7470827331924017505,15059489149709841106,4338982607524673470,11507526365669762986,12604133592236894713,5553399873780495962,2022268478847544910,14102047604123042878,12054937914888613863,4954664839259504237,2973814239490388014,11532995175821663446,3451704535846558002,17263674843206125342,14353648344562794887,16044172364974589726,8018249516295122727,9915086708421628949,3588385761161912970,3925338500527835893,13058126646056991962,15243186136638767116,1762715967619301376,16462914330289578375,16606654094328372011,1782238217019196636,4504838308236469943,10802055735591337550,7396280837412203230,16687955328249520343,10512893327284141449,9827359154055822829,16214423401097559711,6179868597451165491,12747366344638042287,10464933340163452364,6690796778946543427,8482377301887998319,18193203236903926308,14862791681250149808,9974890414807801131,16443970405517824005,14282674093146292879,8917016174608064700,10003886197598033038,15401215632391637316,1426765359169227105,16580355370302251937,1857404726954535860,16872907545019378754,2643442173241520918,4297169593439894620,1345519156909888789,611289464318781343,2299259184749165116,13979377557300391294,6853458319140663970,9351531087852190220,1673560422137383908,3409710522842331791,17206060767767584733,15380550001172576566,1810102662350076702,6368518589195819336,4043242035802062366,16923915482183031227,12588325230663265756,4041632304272290513,560897755235087228,7685411749720502538,7195420035945077565,7520700179148317375,9298054296783059107,13379340173902235289,8627288400486392989,16593692130611573555,18140615750925716063,11859512800806738876,2737008204656516011,2538814647221091247,12048046659571522626,8874984671955391299,14068501159460747510,4266131370719025867,3514089290935007330,1128526466270690724,5695816057515115213,10582364420193838006,9121356815611924874,13178856084631603856,5813247291486693722,5405197896217867671,13469791142954578853,1754893818232113387,11501498621665626192,9955795817883238434,6983818831031926799,5836919173882867920,5726412729731091297,795885046398227894,8405953700815437463,4453683152840108515,13627995197443923788,12971376252040558983,16808788601417576567,17164609569670129746,10613671477300022363,13226790906669703708,17948750675010828830,9796909910674818490,1191838345707177777,523986186792661321,509534790572040581,7403335520748317835,17884022143716225399,6367504278161987125,10915864403396577131,826847069956715444,9733076080172171508],"proof":[[9968412702575397657,5883014110591807469,16836868699683069511,11547298892738445071],[1945313267645247169,18348811765325946146,4637303682390730908,4389837671954691011],[9657386875802457980,12382066538807047154,6343829690801645872,17726327821331972320],[6794782900665517040,9153656414627900055,2886616322220751583,808638755078950386],[2702985167899588805,4099696072296882073,7255790041806084034,12939951485674766872],[10018598589376620348,11830858946544167290,3568978059804930999,3722820146623727584],[9361941233956825829,11159887545875799760,18400692792388685667,11387665114271122260],[8116549712249718240,6223216221953838688,16036044740703847678,15532684269359504858],[1715538535598952220,4363225868940681271,8955720711350282456,11393469999359239997],[5600242078216784487,11340600650677296762,18412179257216228579,4435526859238097799],[12231111045662029154,11384916702135239878,2815729147923709152,7507262529385287019],[5024713259430421978,17624402391484150655,2872159465026048543,16278565126598097532],[11192557884134429346,13936271776851846129,16935828077821843303,6441598658011974182],[12756153472076262821,11823419683496555401,9377948782734553012,17307180851149203689],[8694984196385831170,10377557517300121577,1303216994812448465,1093394040747371251],[15346668047248116441,2526726310755198274,3435646062692882897,12890230126974746074],[14592655159823375692,4886438218661956004,11773371646111906104,1577097193499964970]]},"stage_2_query":{"leaf_elements":[4913390189255112072,11906719377627763385,5016452078608595224,772401314571294270,17624804993931602855,14436411433531478420,14053596488717367807,4619688376301884370,16966502450917531600,6474095227465890322,1864841281232219167,7304698522311482610,1255349404901110430,12337658200736315534,10390021082984418802,11789349225348682187,9210627065518310890,14777838727559539020,12944873235259903253,11340134496663692706,17477394689783409874,6374026652065329854,11122135246269838513,15382130767277604205,9818837208944911012,12585260360615528969,14896244394279573327,18079488660540128619,16175427111589804183,11177491456766387265,6109473762926633794,17054050943332892568,13163820996168042795,15805569051316766861,12436291627545698598,10071120666586583430,4111936973834513455,13747976173148642978,5972038855983729424,9284296627819123977,14774351036061745652,3815220924081750833,12061029624342437694,6531109912608181473,12447878621862730015,1501725859123118121],"proof":[[3253903643987159858,7748679996005671285,14135002317092777047,15272428954999061755],[8294926099681362104,5969551984572587849,12435680071357622962,14802600807360782394],[10581556802336945507,15248101242160544476,11756835975143688422,11724639579474916852],[7556643415332466792,11200874586576295218,476974369761072073,241101279522353768],[6959101536154231606,5841934403790942705,393880486676251889,9788302694706255559],[12179205124608279979,17485973209174995430,10130336773152987429,3700131525561709769],[11144299176389351843,12666264206834561439,5939668085073032619,10470140944059590938],[18310405401087208957,2376861020243826701,13403717487416893991,2297944526363755783],[13844953579082364267,6267105912957148542,15909925264049249650,11849111740782354383],[15682551325283373207,18392289825094676973,6668518452601156006,3352018524715633401],[9881981802917007677,3055497360692546638,11399129621173754538,1425031942910209025],[2937934092847909875,9870286298857269994,8037618805225513195,15150070590330387620],[17351831067031926850,13073705821167718358,878325901321159050,1147235378273085650],[13311727995642040165,17116652294159426363,11443022982720948295,8125816725703023611],[10545993604532934878,10528420384796372810,7261146220497387840,3242804158690056784],[4551867285975537203,12482358037606313884,5878331143723473561,16657304009053288735],[6300385583840829135,3508707821927913265,5255373578022653255,11410137574386606844]]},"quotient_query":{"leaf_elements":[10890606818938443341,7135482974345632063,9765020295755531248,4874123183952453981,16616729942950493938,5777649041252981167,1860361218870890401,7054422507612930324,10587243145850138346,2688465237133609927,17924599676426018179,2492111986715095091,18042937196690363255,18096683737568012962,4531481554250437489,18249781310044645373],"proof":[[15707332480768900073,6766576005876432988,6746568427492754412,17643859862704794488],[3495892268156212232,13271323560629816971,15413712595732632523,12268504472146533601],[2256335701232825910,8936712635109131437,2651454583051616604,10575381120409334887],[3636537255384064310,17920576194211473501,626117411491274765,16678102759577584692],[15814243692649480949,13324391665638993378,2792290670907452297,2158612381247221035],[5925109198453168329,13187018832138423861,1543888761403806378,9758320360485937303],[3945801630200941373,2106710607635834446,12288558666279157215,8930107392038663896],[15392449119173363026,11796556377440275856,6281541665597273862,4320476325619252296],[7349445518709487194,1629865653661606556,7900752687719772564,7618176602309589314],[18257990386911203914,235600482489805393,16812463358965304663,1896123796043368429],[14212006014612612515,6147982211096895682,14981725891424581690,4719790340792710991],[11170315500581837265,750433487624510252,10064542044632422118,17462826755905964212],[2445268512523980988,4848025345664641189,3616820369626697447,6582411498978013429],[11417965489048702553,6887990736505551970,771904684706104089,7738600763714262413],[11300409796497706097,9731925357132144884,1094570406514492297,14706170954544622210],[12737530948504826777,16198149493584598394,13562122960665280839,12900254218326374689],[3678234868369141147,5283638782478520511,821763301433200291,12666613813678185860]]},"setup_query":{"leaf_elements":[15498157236894514188,13934374670127125674,16362247537694483847,1922766354402782860,16951469036844942072,15544675532290823345,17555410878226900686,9040162836033591443,3456295084814188463,9755795030737804971,10234799431819197897,5065669188049388000,17361886239535333237,237366801181317176,7960800867389604486,403732002754058842,12835623670203643207,2775478259616646625,7483694479604794599,17302044669346563292,13267470653992611381,13762496853100794449,18025808150334906282,18109110781944985190,11845580873719097048,14338819701039921891,2043002256488704277,11561333691044746413,18150840261148740640,4496274006314538843,8891061293731048376,6271560412902872058,10365003296882483826,13780032064571256708,6947132055021164272,15121454461827514464,17528708741557899623,10376589871113101337,12828413989862597286,5382491454730479751,14595688574325168308,17389324598636951254,2106709128971211912,15071442293446653201,8298706978943443732,17958727500865183626,10415038718536296845,18024612758419647582,5529748481259110734,695323059982057159,2655520558259150300,7812017149517624754,7977410806592097315,15794769621243586189,14920164674479810375,15223647889108049193,16580494393596553470,119785490947293139,16335484906178795083,6340511471262750745,9899052982210672446,13621315657889373945,10162010918999397127,4092109999327856471,12525055597978111536,7120917924342296048,10014793588641370661,14309115875160458099,14131787131312812133,928283494829497758,10346296170552744474,3455867416826716092,15401472699348221529,13689545985704680547,2813937962787235008,14166409850457209196,2164080801513397583,13536042987269402101,3445398299090563324,15993840773937116725,10021790100390959194,5687354589811036143,13612281886617870047,15199205581227321056,17851687831789011028,455396248705712076,10643410514904104555,16282230382902350289,17892086590957462241,8402980006344756565,6457147447640364358,5353410784982671043,2460675314805012809,4321338621490303047,14149245086525041451,13780132778470688885,8987540188049916831,8172842538990722443,16859626133585235554,9988436630458006502,17933101400464481179,14930321013615463904,267007945069554542,13717383955740578509,15133666252687207149,5555184717296473807,13589350717539670575,18242608587105232461,18042969009336950635,7005803677919624579,4105603063524608431,11914031008556941230,16174695773449021910,3918272932293436807,3458459665995723060,6987311571711616947,3189498803852210671,3675432767925549974,8252182433771491632,17693643240914280535,16480607932303778004,6829082686875224238,13017837879064736320,9213924934648301817,945934998233911579,8299446348262737196,12185791341714506818,9517938460337037185,3352228220948891330,188694809160804794,17832621198384272919,8447912467218505011,9667444725431903377,101772051767501421,9663818754888980242,5373310798406955500,2016123664256617790,2854807562730743142,3269066517470478700,3218425270697881517,1107858057614522952,3286901959281115739,15307337185031703301,9237471623707958852,5970583951852149374,11443363267203666894,878623147413775877,1274554094308186899,11707768084391033735,6523380074938120491,4216253434533397184,16887322186623721270,6700345687585723302,12460084032665629724,6109050558048906063,15176684575593627908],"proof":[[3868378095321105696,9043968063100575726,16549722640986633551,12475859570192995581],[7738567897112913760,15019181239372290409,12508057315818751226,17135215402645292951],[5306430349097173581,17130030902937611832,3860337635211906641,13074834947458281741],[172783701436883546,11921592690439944671,13818830292885713086,8237372864301437124],[9777084963383000249,12993318412147024403,257926049591051803,2901173633187933887],[17012316092379866518,16119384615748914516,3468072567675327740,17268259706795575601],[7573837156064617260,2504072509349535718,810678340820850061,2224267347621989597],[16666173622428971462,9912007353464066539,13985935438569063042,3738366137913083370],[16627126424220340120,942893190014769573,2981969680792077645,9130880525931840519],[8382637148851873755,7313608678588429351,16744048306288712849,3548776729492576549],[17504504454813859223,17767695384126884995,11036810928912031735,3041259830776204272],[4231654440390345589,6800215409424521004,15045880740912670672,11301960403887521448],[12684293717741082472,9052391683385497328,12355018871795983614,8040185737804032060],[10846596146374530680,6439652907334445380,17694756985870183299,418786656865738685],[1306832656619515287,9764804451951828868,6479109755049317156,1962897658694048219],[1604331307223421191,13365993051588967226,8588985829317977614,3926111662093512656],[16354204956433885405,13679537276615897443,10956784370045293126,16160403238752695896]]},"fri_queries":[{"leaf_elements":[3988568659155071176,16956806419169858774,11949501300427196554,17746804005535177438,10029742176291860600,515651375338369850,5076048574420247150,14589951564300420944,2950898667175033324,7670409308766304611,10432325800794462164,6661373947122391160,17417200926830977250,12425786555547370442,9541619671471142251,12762595804154274177],"proof":[[11950018972893533271,9377685728231082859,15861868180570406018,7685694825487031946],[9382440390934336467,14125739464149435199,4095143152299366791,17930028188991511748],[11771084153347947142,17506015583178607754,5553258455854004362,6263404357580826259],[13356942575821733736,13424525674794913275,10167167586383028310,1776201183087906451],[8701361422161693782,10534765688164805887,3066155827817600800,15885087301335998681],[4311901385263750631,983899965232421263,5212902449978552817,15419993910733329851],[7079996695946026492,12711503073672805453,7610618017668897917,12162047762397190130],[13738394969250201983,12652999758056440828,17992546538778516102,17584522223320323237],[8648572113549561877,18343907913611092310,15764421320788264439,7000644906742992355],[16226722186025184926,17693783690898548251,5696597435566175827,9002755841729060102],[14907223291319924982,12861382532814708885,14845924582340091506,1045781553147400066],[10464480329745872290,18095765198530670135,15973523973771035502,14445717066983072635],[16653975507766997525,5852361545422212783,4542679570729558458,6286968683788957014],[15841979698184688428,6766978167612976972,6988718529989188967,10317852718069604352]]},{"leaf_elements":[4898910022115882937,5672510687813081303,1554295498553830202,9408106835167781158,15055493705954940,12720319657856399545,5818083812026107065,14101715129433047296,571521709392439875,16276152387880231206,5071606160513826871,7026938131766797649,12295973726836946714,6887691287775887477,142740201375040646,13250417813823441907],"proof":[[16002734143087305077,5280592256552285474,8110697396802458784,9169137603202829210],[16239115770858992464,1620498711273308270,7663250588320689126,2478432708763248055],[459642852797447688,975050685280739648,17142524312146023686,743835067902103282],[6464997001266865498,3192866811668877693,12292971543598243922,1052848309530574924],[8497188978666246224,8225241685193747779,7734183827281769632,18310941159145208099],[8233010824725037091,4659723978016845856,17545993156894075576,9293412418112843976],[9261932072719496463,1732880658612232297,1757057380923141906,5729594146579091951],[9855187397619384484,11965590780756612056,17878326641116136075,14115206121431344812],[3328040420158164936,11165030521055605488,16709879237159342819,10050784542656473286],[15738158813134786993,3418264850276457326,10335140839884698714,2264973671078968161],[4620940820684181288,6218150265279905101,4394142517619279316,11376274407012839491]]},{"leaf_elements":[17856093272773263156,6666293502656200244,15316556418197778328,15647828412817705008,8499492775737597948,345122030299123632,5248687571727390241,5086846299742130114,8874620331823394319,12243564386421101311,13134112459239411744,6124098555743645720,15519853952107868826,12663584388571404474,10814894808899861526,64174898353879182],"proof":[[3319674840685320364,17786227832873194961,1985593292846950589,8594432391778108225],[12568806182256102987,12021560655966905698,15738136593199358890,13727593858695622847],[15995726168270021045,823703212786249384,15393384563547781935,13040273891636269303],[5821954786998141726,17395087391869507378,932575361593848572,7011666957116936189],[18136518950016492913,3446196409981501224,3305478383428301974,11228373037873852684],[176306145803066522,5103082738707997207,2246879073538169788,11813999213871271566],[18157687998917215258,16763460318887211847,934215623952467888,16511182297630279563],[13141057789689340553,2448709708255569924,10951846470074346402,15630920576161203827]]},{"leaf_elements":[18008750123803443756,16783646190608621850,1218716906253685443,17527763562736679576,17009704451381297904,15514828105146821904,11591824136999617349,10141133867558695741,10040478892319366775,10356395597819727055,10302721792901033057,4949277830327608350,443817731075712960,9260510812446255709,10332033129550315450,1190371033251799840],"proof":[[6095056834816468848,1235033246879491277,4658499611331575862,16791861771849062753],[9056137171644731333,15839044044753202734,10383072268509844182,17074048888521335562],[11702396021756725980,6341214669014431916,15614636811617511183,3329397537271826463],[18105499576403946718,4385796141796696880,14788005547233371370,11971365134580477349],[18094368428717041921,10947070686492808250,14391504912823517373,16135841269932707575]]},{"leaf_elements":[10436843727865497361,17846276555127019869,5922784516808728109,6563996082027773457,584050490551381099,15548329999239472536,7506827572629213845,9991002189841428580,5484499667580979130,8499433419154611987,17438216066036198705,4590668035734578888,884955262166708534,7181494639364029331,10730017351734604780,8530100638143981646],"proof":[[6389906513795140626,18102858087891980784,3468257514373005665,7876526185786639359],[3419541161667130895,17696456370165664112,6168864541569884414,1311020060133671248]]},{"leaf_elements":[13912788208633012260,16592364955197622110,12930883254427910878,5599575569218380943,5682660096836901399,4069773254031359724,17686759155637027087,11829746095036037227],"proof":[]}]},{"witness_query":{"leaf_elements":[12699524091904310791,13371077489086581553,15571902805119902124,4729551749420121057,12797128642088875768,4915289896495294391,11566804036522157223,3925376926333049076,2318927937988448371,4316370709903873354,8306524157359298244,13209850345768582525,10983748423495383384,974210447623178774,912291516741433358,11675186251400884522,9941153581185158945,4086519137540558995,4494633564628855225,4571860515470435320,15193194319800013324,5453081767903221018,8830190527586043831,3779361159429412390,14746943346412389127,8037401436094046116,5174806440798920912,14614938706706043510,14264592811716546413,11838316029485230134,6778291653906372883,9026466912104851143,4530619721069815134,17310970912372056698,15598956111842665269,6950415323950912504,10850185660771011117,2858536850805341680,7212101549659539805,8998810454478019419,11861800514076493141,10048955882376106527,16790768740273897163,7901745827101904054,3599355506251946914,5301683649404516308,6926337546827970946,3774164539684117528,4739236874559587659,3823348244760828448,7741991695709492113,12188103322559272408,12813323349140421476,17357484494821503980,16387763701731135119,1527023543355994769,3200179222995019206,2570321521363744018,16457830406831243691,7112524005668766516,11138669179043163324,5242542061381602080,128180350022829101,23751341834707377,14457132974732527976,16961464997674664124,5991583958993018316,15327223110051247699,17070456826541794618,2250972431521077522,15830485007126164831,8041601503039083741,5321696882164500134,13119408863694566312,3462114243212272947,493967105376846359,14032984981970670153,11875055960040100174,7971998132538482227,10504333444936434986,9537842210583157328,1309234375789151164,15016618285147195348,11095243918634100560,2652386722851419422,11562736014461397584,2730675018569773486,5407722545359264945,7364015053821677423,11242179370381628346,15839842843925349017,14351317819143694932,592220914163316611,16225972481040423942,6481384630941563790,18380964858102352082,2042173535249063051,12769243835800692281,13872716339708748420,4344214203958254928,16938196560591819806,11197066991974585166,2536621685950989061,8589608866343229561,10276895810825253490,1859990641748207271,4707298300334502172,14422894081642699994,8478331470669683390,2310226015921702950,1690677537325362724,8975025143918580050,16317941952239595989,7727128566460631732,6559934354975339782,2375764279019662894,17969847421653604082,3569253037275838304,4778320097010517851,13598878300909797547,9497011210419997221,8359350987714853141,7038462200568288944,8524566371919108373,18020408630195232023,9772285953227686501,114281052396312468,1903491468211674300,13709054486158027650,2993177884789025796,8513969463842561859,10553599175497866000,17067160766202817273,12687992240415921862,1742609192415530646,11434741627743039784,8864661838062993657,6501604182056131030,1428308062104029558,16723883670837910790,3532650253037349303,2480658166467283673,6354229179357001184,8519900257245687254],"proof":[[15754403857367683503,18188395300233571973,16984799857373812585,6703183594098090867],[9474123465133976391,3449415689222811682,11981771163416467355,5319720111324541755],[4559735317813604135,18296245969274562718,9911150852329617689,9498296862317836119],[8651421921157139988,6632273420160620814,7836858379534546561,5161011781853630745],[12021677041982030619,11339602116025820123,12013624223654343695,1786750090054125472],[900484633086621543,15477912540916633699,3667929050525127411,13980907270382762731],[17541923551763081720,14982825897910753165,8791351717758623091,10961552040154192655],[12718313318604500604,5232395872580193856,16293294932826599361,9429650172943811865],[8933476559046788580,9539742645558839083,9981930882423051148,10882674363935600035],[4814840210460475537,12524715014257163665,8546344859643658818,12555647150177809857],[381983660464003304,15411539628835229526,15921394755822583216,2386323915248343005],[10002317819687458600,11548562785607404541,15999696637753274342,17503162726698054387],[781372574832077812,3730711553257873429,14972349999715421339,11451116050409889695],[16754149089531427002,14089001606731837094,10884986179963517005,12454502391661716663],[16507217071594272165,10194656818235019375,3488859089409517252,12719712166686569973],[3391289171207654785,7007665983984736827,9356879587048400840,10018796648970944431],[11350054266242620580,6717146233067051964,6161093412962147136,8935657310830520738]]},"stage_2_query":{"leaf_elements":[15087270492868156324,16489178456470768756,6164966926736007539,3728582220942804241,7252937749664027018,10332686575522783893,6528631687468148068,17237316944936221503,616731667555529572,6077648606669516372,1698214127262057132,6984777692241142379,18445011902958567092,18337935705156681734,7871670540612137824,12480653806267368403,4536236384849346716,5540848158226643043,14663865218231852489,1248620427916412782,9757065175549430371,15824805285781415012,17174272568292890170,15081751212217959120,1698515461030864846,7273457524952458701,1945190630777503307,1456594811443659471,6106542068705224999,8738313814517832987,11159549108466794763,12904905568114138556,17533268010155187494,5335392553164447085,6773394325284551961,12945836475660960260,8538087466117381774,4325003252496873138,1189174571766717604,16335664188741937183,9249319975154352223,18211936401516758203,6642677021622890954,3298482171915106260,12287527410134497243,7626116947710862174],"proof":[[3783780157415419861,5530576875472224634,11419976404487923058,6094654251913386387],[13503492174622639223,17749876166046988964,1869158007615020473,16501447519354666882],[4502447287807826536,12297254583811370253,18236160916997860537,15592407669539310336],[3238630641904122517,3174562796860451411,15341413789761825690,7468895240942261357],[10812691715837173881,2440458916703465933,16646764875989203991,7239887683565117486],[13677276495299151754,12521095475065763062,2586808171813013323,4833253269827688610],[8836748893224380814,2068730187538919470,14996975683042884625,3335640221343144864],[208031828344737227,5154254555484858264,10962004869423559250,5160667553183064009],[10109360198291779411,4512157136519000690,6874986619084103539,12640788605340535983],[936755669298658328,15468779757310113345,16307889517498020454,7485096237995303869],[12120684753398577908,9348607868545196019,13319033659656188699,3162076764866961085],[4831706704181099731,11061671939382677295,2851173670518511140,877314521738276390],[900600265940601252,478996835831403913,9669291492977540984,10487139398800334861],[4467642133954898850,4194053689910931447,4874685684134337064,10290112283831898044],[14773516512846327928,2889649663034364314,15692776384075391741,18205723204277914668],[4943245725504803452,7749286684652546332,6358730901480003500,483879996875154315],[1518475277183878351,13495330011763321220,9115621685652662343,6489546065185696418]]},"quotient_query":{"leaf_elements":[10724728947242766872,13892526342406150914,16410819503006078498,8420139728307478216,6386273141101095970,6381596717214591979,3371282200262518484,11235444946809396227,12419047542354151367,18042726855922302730,10123715451251731574,1365076093348739412,14927801595366281603,15298558957895202925,18236364200143606183,258018195292600268],"proof":[[3438675446766256860,15218169738801289713,18004408110474287082,15875266844535323889],[16734929603837446032,10468280695017821008,6594980183064600703,1725439809325823576],[8819443624479084408,872287777718493514,14100649864620449222,5994569354740986041],[14928293399919844768,11642491126273502754,715616793309742864,2853632467967955873],[4125281315424235138,2652352012268859097,15523853638935392651,12845364098593643171],[12733153377614810876,14779185551155741990,12388586837993883224,14852330400672279366],[8802704809926006656,15314479341521483008,7486019957954702579,11250087010706643325],[13048292544365680632,2395377178407588235,17061963153625292187,12878158156895957961],[17159472822960425283,11167618328441509128,2253019290458289444,10828578826049591343],[17438480336475990757,6009623869052982412,8175454134395832770,4368449970895968661],[12012653825272138423,5972272868522944459,1130926947851213597,11778119047034784138],[1654982989308596068,13870207614272736986,10020649500598820283,2577397061164484838],[13324165319509821918,8823223144197779339,17324543684258485385,7345261977940408796],[1273209209254474592,16141576755767287387,12257302815321807289,6068507953146735541],[10297085452533648695,2208075917392849005,12849142399305260624,5302076502625518767],[8915191846098668258,5309933113264003199,2219438225219196291,7186243803698191533],[17820760276996863375,10216686837309516532,8030491108914819360,6003298734879692044]]},"setup_query":{"leaf_elements":[1510105571418654807,7535048492856113066,3792915734559667730,7945729389135956953,3940010293080312514,3514712292325867172,1743371328355730023,2859403727499634484,17607954356045604430,10209343687728665341,4345951455783167871,15868758859162580897,9990165221051284069,11818206025318357892,11860936283084326072,11931498616872142453,1204323781574868708,12648054328087116641,3992520090311282703,5473839897971821599,5569787326749458847,11226482955560330274,3916165584446192286,12481186551309034262,15356135404174220436,10607435516940943848,13277078518639554894,13783815361489018251,6525310953172117781,5672638810518552385,6692077948249585545,17517892973298741770,11814185052577793022,6571047008495878604,1265553470662435455,4437439103364096010,14705985438210618630,45720979426730153,10173557100740647607,5139312511392667395,7364887167041744292,16881706598563698388,10968271831308058614,11729856700766192797,16756010616796430721,18135706929229341420,13575598890532130300,4177414094812142277,11211703206040474831,15392433325856755456,649451392546135419,14651587039801624090,16866458975511188158,4811364848829255801,2994966237169457974,15755588829775515693,1841876642637274369,2718758325140447125,3371522036487132156,14222328770494237787,17147053937418419955,12952135519637518698,1796457112531548182,18375327238922455542,16809676220221874178,15768387356136384527,8713492403717060536,14306634518978224566,9937595131469893976,5243853241266299804,14686147965020853230,17917012194568496579,10094556395822637738,14962988419850433849,17928349437044928402,15114163143901488064,14038730721229178598,14264981109422320324,14844963192079592096,17539581107175931073,15452354101253409164,568289059441315072,14210335614939686473,8592418345773146294,1410098829094230180,4807580037609637936,11748697653608261381,5844292729600031800,8823779512632980740,11895999020614681929,18080478456935244895,2864818692450532417,14500498400520807875,17431763321533861449,8864302924387383822,10859077023345844759,12678529492720754131,8457515110839994889,16464863144234192877,13617239484253138897,2786802995483781708,12810333536005239296,806480266189159556,14895378121409666800,408830284924491430,8821011609773951305,16350378691323542987,8784317315051228679,7452030957574219597,5625642237405298247,4199559316751251284,121145051116147517,2308967483363669191,16903099297821715569,10990122898038969119,9314453863807415216,14011137072214041780,10172510326567609689,8885983933359113526,11735527850910865930,17250089135261036249,17404903773485948845,4939020387491445352,13121494375528140485,12946017484544480291,2637182644705980824,12256152295989506694,13387794159870382904,7062692089494328835,4375417216288113959,11207778904640342702,5889598339135799861,1611722373824746713,10862360055547084560,2679805265811830637,3433297743514253634,4397560870463831924,4273992567726692251,18315371860547284529,6036844439026097737,321655370667010472,12633783146467040258,15705523319356350627,14582771465918964636,7252984807438199021,4773419876616607481,2538109137595557995,17422311588191798461,15062430087663436618,11848535697679437093,15805768749390396826,18113017943553277568,9415491691966069871,14475258276502024593,5206931173322374424,5131563354934155300],"proof":[[1638222702322386552,10341761368997209626,14333143245437320980,11095283194445105646],[1160816546366736347,6093766650657378549,1754789870479339759,3723804434035701138],[16388660513945172954,14907357677041015131,18256386561538314400,7582124771260874254],[7281101301733142198,5008920433279436734,15884072218060447386,4450802335704997110],[1569998912817536681,17578485762917024200,13596971836526885285,10211854516354577781],[9731342892975199861,2848654415893337347,761881066608121201,977883001179802666],[2674342097510272579,2353936799492730626,713347520744255417,17552215113310024610],[8016893963097059241,15983514709694511750,6288916579530976359,8655350984076672105],[5032271980453576608,6219308925519199998,14894518163368571080,11251771469695092840],[803361626476888729,11369234774653680457,6244094081508966986,1695654482570350890],[6296919273045449443,17694594013136930913,17882786246867947303,8773285429773155379],[6704872125151676427,10615909462583774744,7067227877604296578,16109545983486355546],[17229990480391786796,14729959152433050452,2731215919017669660,12124378399249905539],[7953741330474265438,5816387360816007091,10219789029615847103,17614945457700422884],[8634647052197067085,5452168941454508840,15206297923240795444,10625474669655995214],[7796515679998349785,5123543288797896245,11553103988766187479,14507515685403024856],[7045693185093702392,3053864862465226362,5174513965978999888,10652156676010014419]]},"fri_queries":[{"leaf_elements":[5961152304659715817,11283860446369803002,1892617206465751357,6056163932822482423,8155864271653440732,1548175235573984321,89419288750526704,9214309261818442575,3471008296828120928,15970655594492001155,13764485720247289119,12487970481879983865,13231307413940660051,10605271904243876540,7103432662026881201,3833365054930530590],"proof":[[14683793989610165665,14955821981510134682,14238608530085184332,2325751265833916992],[12033459439331038482,16440346034393497757,2559505676828809886,17745416319951955995],[11844879893671715893,2938692249255909161,57848171016342855,283713230045373421],[12303796113532805672,16960690245299385837,18271122701017310353,15536446979922799299],[15021045561847903292,6010141540471562003,1324517274926400527,14097913456779079670],[13402269154484379657,1432570376170339804,130924609137490864,2043817785066553433],[5348001209027729332,1113784356000531153,9465711980927770072,12878997124025413804],[6359960859615697722,14864109163416094691,17493674254109936745,4308063270284716977],[9179242451211900855,14561895083000389916,591870224609056235,12552983103189619445],[10332418474043564326,15945403197873886423,8959213917920734700,9966563177937755654],[5883534480009069253,1132284957031466825,3590022012279631746,4148509106754312244],[16130183825830947435,15622473851134116019,10231381786920474496,14207972866442292049],[6659999624970365490,17685202818826730706,7705766716795780606,16140453052080968691],[9436036085613120994,9138757752906074281,4592184338475319271,16269358300088240680]]},{"leaf_elements":[9943301491638842654,1493033754697413303,9266738268230412542,1321922421329190837,1293622279903021669,2068747199139268016,16580341740392044757,16636151156710746742,16843020348582990339,3304312382516915979,13958158472667330170,1521462605361923275,830028371817881752,9606280020719058669,13402451153737328966,7364475767039937157],"proof":[[11254798808171626434,5727585220873234029,5530766771215850350,14736885305786931322],[16147810472976024981,14203445603711071651,10288294997696495127,11451189185230619180],[1632436627690343095,10381908742186441669,8803923653569649262,676965121218949743],[10486089220531892718,1118721727359551277,9927700546752037302,6911057568013854717],[1824978121375430640,8481138318117156427,6300920770407974189,12967474329601335064],[18144287388144836203,12214603376508016598,551924883994799867,18095653804657842146],[13804465536541266953,9489462591902257279,7849739543337020653,3548222824079103552],[9016159678505688315,7987583201724812921,4007496531881884159,16763930134072161695],[17948500233224788653,94998544526757072,5372853650925536485,9857320565256716284],[13862450819966349640,13666989926741556477,1200439045958580394,5385097922366630532],[6686906591241727369,8571182967814379765,7115603858759199184,421617287814022009]]},{"leaf_elements":[4896084194136821314,17023694233920656932,4431764308381980835,5104866057845236267,11436765747587518153,13987550442760110227,2863794880933775569,3074936290250168921,8352006113052920405,7880257384690428065,12797856207712395298,16919856505043683650,1982494893703658204,2195443158252052084,12646141762824166523,11056450813798861188],"proof":[[10498257574750349233,6448294369651864266,2634863626973517779,10811774630950706972],[11158567005433699418,18010154744310115498,191130312826752321,333097180374607930],[17783250704252765191,565663449248650401,11382286419430429473,18185837961734459896],[9399601972793765395,10616961135290261099,7109725411928059750,12031884725380545716],[13649148451842795922,201553521235069277,3849993480449119973,5654817631152458788],[1718882164546037795,3831009138973677010,12978757200539084050,2306162237553595008],[13197868626576359201,2519400326732045958,12706414350278011942,10273987809803297391],[10938821742966244955,11911901241379388386,4981322656000654465,14178069308102147458]]},{"leaf_elements":[12403571585921212188,6677863233501072009,7640914711364188563,12463479944725493610,13403043190840119516,8195380812503788494,17362646461815783299,13014430094298303903,8870836722500188490,8688463420774998605,3827048439736864084,1832685937859828093,4909380195098523557,6195326874998186116,363063010330389277,14139651891481369784],"proof":[[14453681728730911910,9301894345830621005,8412898388401078959,1538276461920554088],[16674271373925052438,12501304788514196700,7522384592509565344,14741754452149139606],[3856438656793485018,7624084937544873622,7929591281619326817,1233535409900586681],[12899065370321243854,13089473193201560632,3912869706064356263,3623976971484144796],[4311061275323904949,10237307365185888852,4759762726841936497,3629984639313244848]]},{"leaf_elements":[3971032656754509901,6242750001806783074,3289573577841311507,4723759412385717455,7990472227479536062,9551913444504527051,12528470007834886650,4804148057129529564,14347300067173596985,9306064789259756998,10028113922713404304,10599925518470309170,12535887185957872091,11801314760616791995,13344624036610194433,16282015287088952945],"proof":[[14908317330813799564,1801576219256327645,8393819521130354036,655486226575859750],[16608373254442398158,15558480294849148664,3666031975490616406,10425732788875687238]]},{"leaf_elements":[5913797713474501816,14390836815188810001,2598086964460305874,4219281277613110736,4341490336555859025,6837138495876505826,5182460282140934405,12936941785162437742],"proof":[]}]},{"witness_query":{"leaf_elements":[2090413078893645756,11613083996527504045,17160911813381776690,12640839766997102759,2222879438049086881,11693130538543389702,376082357171441981,11137005666074298081,1125798795484669029,2886514552678921586,17460705636021242932,14525178640688723947,9124093387784172787,2297316725092503801,13449437279845336048,2221914238642155250,13836386393537269748,13136835175028661787,806052828060948309,11094158081787917501,4305622281080635227,8978510270980403371,16930526559722331223,1907424648231041115,16239440057640142404,15805981118499936201,5079120306503325537,8993132708253618451,6023607486207201014,18085552046349880538,7343193493078818656,4180319200070203556,10340922825380795861,18176502366269239311,14387111888145411161,17361970848090782847,6821549117048831877,17672003445481432561,7776438660302484982,8562343517284567292,4289190126543234194,2690203100337874829,15546350717107725856,15149108368242594054,16138059188329973650,3198365857939502251,3852720810818957341,2881361132122382058,17363488827437804889,8295494484854294403,10673441771236111079,17654604864242800039,11114421785543224261,13237270623489844991,5073422113653663688,15671285619211405866,14697173217450348095,17587715614425108587,8273417006269592053,10167413209660376305,1579015145125788834,9632464831567367031,17285565048737397937,8198899416697132180,6025372899725042498,9468485725243246353,6349679604454116828,12363143679875297982,10278544519487731566,9674035880856251549,6289445719404712896,970148721408911278,9841363745285921743,3991823912346754292,5793639831553912833,17310831127103007654,5928865564348515169,6536364060525990,5948295398514712762,16128483330666721072,17475994651628388973,13319864233239636522,12977010039905143627,17158195760933760984,11158442611112283506,4638615110393369833,18170578188299983891,6964312700286344018,11052183839928447512,7711861677296046489,14519304509177424153,17030247936546496936,10768686510340768061,14844209508251048054,16928880966370214029,14888438957564121867,10505428355013235416,1472048588566574431,801427627563032400,7455033426215838400,12000748348019902047,1494517523697781129,8529525591007741594,7817047062133289470,16388193025733904823,18282482374315988847,2820499864864229953,14530007612332998041,17511372442305397042,5321184288256319107,16307817192748292958,1476397905511670174,15218209880038576431,7098222910482316036,13606411904663761994,4473372984384415228,3407100432425011585,7122924951243828401,2424628608075015489,10055774239243168720,8883815400932478152,10435788825780426521,5932617304816425033,16857175386709971529,5215573231965644430,6127483079877884630,141753356354317222,4348484201280534730,15875392338786768121,13659461257245224676,5854326901262015367,3107505864406788468,316793396591046674,13173019645366800281,3651808374621365031,14000290827257683075,10157289253642280668,13388268659954094222,8056587200511935586,7224135995758773231,4284494256390914993,4228404528772282147,12276162263238628705,5846428803838064578],"proof":[[2852207158550295827,9117497149949858672,14224450267835363174,3423558484262019887],[4876142175740958592,11210972207140225360,2131342818469910772,14091374810684255914],[7414471833673656626,8609318728867779836,13207565372309665945,4956869759257958052],[5135434197371329778,13144356320840353920,16619988795478392363,12797627927888107509],[16805157946674416529,1770225724358126836,14487818478413426840,2825759498666814193],[14570913934400318111,12857748074807347823,14653865219763800192,8368615487088230734],[15867362760952278255,6640123265466607231,1291616443363643224,3337238230955327021],[17794028347241948984,2762846527843673944,15240168015691393918,17939598545716803697],[1323385664971004003,14916877755626751029,8682932850639122204,17086943382850424364],[9917865308057532576,17076919263391421559,10809388123791902656,2528381815176920043],[3657229957504014841,8835700669172394424,15623580548057718921,16458780486859249680],[7831116415213874024,2876320441035658860,17152600356189016146,18066112489104076278],[11296458751694020316,11493466421479399699,9760827000593440274,14066995544366965963],[5229330436031763403,4934249764988974366,7864138570360332358,7187995720325724870],[3066409994391931675,17931054695955975068,14409118067836507221,8073427200857987684],[3842324479603033363,4753883796722324137,996743413852659708,7080313112542370590],[5215536602320635037,14251933243871324531,11901504793503171564,4410319055582773978]]},"stage_2_query":{"leaf_elements":[1875200294890834550,15954043938772076377,3728497299973654595,8259856496810123904,5515102872659603827,14224688806648316819,372574508198384924,12024102717557136700,7685008258177518948,11386446845619553659,11517290177810540663,6633429863040851580,15662324812420504478,11565829080594022619,13272323091365821165,11602620537204448997,5696150713359118917,9178091980384485214,6870595618695709451,12861990192009935307,4583350922817841849,8549218076478667604,14421135902315927400,1838548651470717043,14448121224524305430,17193186279453493908,6978061296924286050,6442757592436662542,5725128677176197863,11928448004292682488,460309727100674920,4100787884951156885,12606343203533431219,5487292111284480800,8632763020270769009,2025989198875338917,1593437696200905543,2579159686244060315,13923258291477077710,9339656390641478117,14443615228585085176,6683382602210790591,10365603994582893782,10655147236328920347,13570890361352646736,10233161866479625999],"proof":[[7339382127178573513,2529241464299602752,5393569563602493635,16615491772485214682],[6064503494395255347,15174577506417407508,12978436632121612703,14163544908312007279],[16240582096331396072,16204250539943410236,15571427828120969524,14014019092111562156],[2764669992664472704,14010779995897662125,5523549405553008281,8299939006904403152],[6695767664273341659,4090781593888244461,11742747363592516557,15825835670057724786],[9546370105201014361,7063498809781434192,16423101540099356947,9470105468767037488],[2740925256394654012,16729602404168156257,5465761232373076103,395213132273944119],[2268905842367327286,8395598290480322686,15582343850077856311,8516876468114858603],[9242909846315392262,5824373471565565565,1274251135764175824,15137885412215054319],[4398040912192192878,759623514440591386,14033511175586123426,10968436424747740773],[15941315751701427412,14548110460487630303,13957221631063466222,6231005220831576148],[8924150257932930917,3810471452757002807,7036511046108376420,4167552980590323433],[9015460786686211851,16392138729493331856,8677867785881388615,16048000152987642973],[6090058692781856397,2288935420156891787,16862230000526207459,9665037698479697800],[10253418077415502460,510522615733517269,10984778422433217658,8467631808147575013],[15066487968136584680,10748893798959565870,17849425289372712802,7091762293707477544],[15709091770705664402,10049110614717720455,3752215127558376869,542242508725039489]]},"quotient_query":{"leaf_elements":[12117451893655701537,15179248339610905909,17050860267311354996,10963417484761714750,13356703155638297107,11549742487263547966,300664908053239220,14079334298552649621,2222803272654534779,15048805701451361766,18400389126363786135,14219466413907419756,13536364651431167703,12014291144440979871,15866724010101577771,9627290623221551206],"proof":[[6861236185777669396,1760652938661901124,6417705368107410908,3315023876530112842],[182201055793736109,16320214099869785826,3793813520750843540,9386514577677854466],[10880350566252936394,13197010845818560253,10816789448897742548,16728590329208910937],[6059534184025054236,14010755393403632860,4410587966547577863,1059847299465221015],[12694201413766229465,3485551046276882746,13961195064703508060,8368544070555269235],[7272292975524364939,8893213678997199578,7660267926164493019,8385163300126358329],[1730622214249196143,8101441413679958625,9269943262066149268,704760375784781279],[12282650971177730674,64391368412464734,4168892935303872728,12235812639587445357],[5625454989589396561,13187819672783568477,12606880569424504217,16725389416560516815],[9268132611449961613,15400458402473418387,1005300156387651342,7202647044932982684],[8166527308085343058,13039713371699116359,3583621283738161016,11325729833867563605],[10869353452517841064,11045241158209625901,16659568644297335042,8828810499056837343],[4301130624030385416,4521469506247942699,8454425981161815705,6946616335142168997],[16767430783345696130,16516468350160824067,11851903174222244591,3185020659794543821],[6640216247820107371,12195020463030337182,105899641608409333,16156266672647552676],[12263676989284392594,8510713884196198992,12470107030909895174,12012457562114486062],[18400306852838558706,238886437693955427,400059893464688571,13855449120686775870]]},"setup_query":{"leaf_elements":[11774355978047819587,16928711523439068114,4164564011783205828,17394043753125593305,6313650481190437615,4962833657123244784,12780944239393657245,4031928402381151145,9504146285249061313,18382753589161853672,9900189191250871552,16577406584003070039,3827581185153548062,7887890010194649458,13710217551160806334,8027747345082210373,10759494934540077551,9518179831336682504,6710852464820435988,11907595233377481172,2729928216185141190,12553941020947457011,12506223748244966234,5676270943406228188,1506524417954226390,1956676127488396616,15519288464447671820,9379181502249655402,13717280690176827993,7616358737022404740,2954572530792413009,14418183589668255316,16918818717699200253,10538429458508284190,12126553239567461120,7631347516750516983,15109011215496797605,3395512194130571900,692708399096155125,2461584727744425635,7209413482382910202,10634581134078595305,12331836494372481729,9728869020078523652,12190562239473193407,11195274798940591114,15127953540261533341,3583314189279918370,15885220911180325153,11465414538185510465,10174644009550196354,2933907842327367626,1820523458078313898,1740912020384794853,7175389393494384815,3068192075285336286,9763441949384119378,10016158737310442995,3761043354156293935,8808836813042111091,13519821098036677658,16187464531255981162,16175873123318513285,3088976066023712564,12734823136283276207,7491916773558370690,3654789525205306560,15419297614884179428,10017501605192911521,3349638713228900716,13931500015541882569,13565234520134502222,13766123075259184110,14373351460427267803,3156584694368288762,4665644807242616983,3313684120714759006,2828612679375447156,16763730041795024016,2962048163932260764,17553099738586530682,11761575279897436154,3780522874514319565,4430426174796414692,10602432254740362824,7753864996882429110,5661477296222090828,14982151424386028660,495402045907073315,10270473846860430163,4736746521174552160,2801895607356450644,6736494485271386103,6216614689429370529,1249882784234910107,5855364231379319882,5554622428752422440,16020534030154119475,16571644803439310230,9030646734246621357,5606473906099684537,3237538768434746881,1250540448528740482,4957251858928153154,15064932467337670541,14681245296487071279,2757345683095372277,13362353854416836277,11272256891288514811,16259590123444194011,8549335692033952345,17462570135633925273,885231810701159541,6905026004491225787,6644478356922478491,16478495310574737854,11165909864199903083,17506655524477001468,5927593654279231398,6956685255340543298,4993293733081769444,1832069436704789792,8651185081571030329,9157614101587658507,3501896256575692580,18110478557528565492,10825092304624492906,12719846694250287774,8577297938562978171,13313466462581089006,11860350799954301810,12189351470407730342,18038128132794253982,13665476504966701612,8484010946601894504,6146053251454837855,927294344381992825,2580867080880397800,12262740979342693336,8999113635626515363,15936831292387528118,6375313671900821109,17559170567494583575,16708058378697269894,13876514492536895842,2330230227766342130,7392212327359023584,9308648266561645908,12659364857766591925,6757103686430389943,14371759730931728684,18042159951599278784,14935936057428580832,377554718105340201,1574498669629646431,15583445341786555699],"proof":[[2652050290077058009,18571846798934339,8959252307658040150,15508598496084637962],[6330906939282812704,1154096298337196857,3771601933357438973,9311044017224638141],[12433865740148024329,4078394777899555819,11831873417654145436,11185861765527103871],[12811122643685219352,292142044984816105,14110229530307499193,13929693102026430332],[8675632245797565145,13742470350125491609,765114864167397140,18251494720491361055],[2953700191069590709,9308569043216040924,18047312515450013581,15022709685319734069],[14959330876536660158,12384786173753958029,3276827526854716504,13108810860844418863],[16504190978027936434,3556193280933078619,8838076169862179606,6401754552963899150],[17306048586582354395,1724720219637152180,3921770462768275656,17249325082892064382],[12116931929318857220,3192785612809933802,16370358183331985287,11374281702223698412],[11140786564524088587,15491017642008227264,15744286584167204204,17576619676153706166],[16007841606520546330,2636730016692818070,8598779032045129666,11942563353472693638],[496103414081637524,795102016472730103,14779919354932299422,8013649130978120053],[16793965731495516574,1550215886543636012,9995868868474314954,6302961282075634269],[15977193871017265340,7074927534431925933,10280375710052340886,6851979077984539004],[8082532824431749284,3843126820375714518,9921638987202456600,4700374442741404830],[7984657953714852832,15734075477941574236,12214476408838324436,16357190233096441477]]},"fri_queries":[{"leaf_elements":[5137410730086717005,16137170332984896964,425110327212942121,13299675088899852215,14826829864582816763,6557714414281702922,16084718714766557311,6379631785855795770,10472258842856108705,15716469655724219010,8793184437240631589,6247691438634338569,8511092546338297910,11487482111829143419,15918426528151973071,990861236618244833],"proof":[[17639991890925110459,11997105264216437134,5853831287815671063,1836838637272482890],[6764722636264127286,1130612437308788353,7615428931168194849,8779661098860306413],[16535904796454357536,9215187508349630316,10620084500665042422,7330303051054367653],[3776606529937635126,9094097325690294872,12292702014977356938,7495088546040918622],[838606518088390969,11399782766052848797,10356477875950413737,14731240477395835787],[2346177882881890404,10597824212571798916,11083345340379831532,10847817921770807767],[7089677865317774554,5091904518219318412,10211351756872238636,4218193141443800670],[11749057185989856605,17122538809963237672,7213134789666553323,18035219374661772235],[15323778306793626766,7324087607348069302,3456897818432517463,12095961398116521295],[8952580890436322894,5768100307403236215,3203839832751105406,9835799208143188332],[8865225499950872263,6403393481847298634,15591632753240980944,16179591510887418279],[1427628853032500544,17873585991291573604,6487117564694564778,16950231015599290553],[212621411862146511,8903151658637067423,18251638345583523812,12207401644271428315],[870959045068062007,13190212933665272848,4148349890064256493,5894738798348384315]]},{"leaf_elements":[17751926757044305641,776738718796316311,7039015974590687977,4121361061487800987,4486083834473941404,5508448836536245020,11854915810032707388,2377113660752231585,4352456859120615483,6774666387637571722,17847240334608207327,17109399068739429283,9014932399820470643,9942524633921502182,4844570343565308290,7048609777187330056],"proof":[[13956582297414717635,4426033235305818678,3697703096446439914,10270240571060564159],[3137827139346101042,10172562416084072149,18063566739148954586,428370383763064777],[1501376085441229907,6569414685554683505,5544361236270212447,10071397660169651603],[10680367346470325742,8411866923419544533,13203545375640248540,1711139557347945688],[6678961545078646371,11589713276476648882,3178753114839549135,12309467094820727390],[15665917539596046957,4123970638590310199,386406892954866085,15418614199423852569],[11915890185282712406,8218579765636764517,13574194942640249470,16023145300849214013],[11299155147564582328,13982070608473495999,13108669296848053651,12068729268879694688],[8675336644938332162,12776268104812848307,7241131060343632576,586889771863734648],[2487148934501296196,3983692171113856117,7941658709054989526,7308480547553899285],[1918395912208850369,15595168596087110741,7847666842944273172,13450074119918273287]]},{"leaf_elements":[9028014661062771543,3837810251327606845,13034579735619129313,11916810977826484831,4032805764975537405,7502211831100390699,6690834281888326880,10942603042685265314,9906985042385085703,9657751731317366306,7466287241066891244,8339155265854552425,12550770483674641445,985319241453631886,10349324774275355753,10972478186549721229],"proof":[[13429176248453907201,15442067842747587143,231298654947866491,4867134926643657313],[16713018970499511161,15084783431002716110,249015635391034749,17564586762782110118],[7255694305747082563,10316121995370790363,14154884407235508112,16798010560835473775],[5750933865318390032,15339418273514673034,13234299211102127716,2030836079956668782],[1751938786139310609,15717846900891317022,6790404132347081908,5826439197753965678],[5959570890659043898,4545656654320257697,357324409198966268,12855665872828152111],[15721991068237019347,4547321401710826365,3508635116086454310,9455975844866674381],[1902792532381728571,8661050412531662077,13331374864731157815,14587068449346603177]]},{"leaf_elements":[8997101697916148321,15069690318494902170,8191041401106613592,7428504562607903926,3170075881868298077,9644722087474551770,5538556450856198189,16808238786918234966,14875995408490020867,13851386391870096339,9147369505081701838,17760782623093583109,10948163422283333049,12960930082484781095,3672873968008513851,2320922191987191942],"proof":[[10323885799434391331,12332110799665968419,4516470404583418056,4318445875518840876],[16464829746627495844,18012875463509795397,8588206179357292897,14358970623277843012],[1680741443765471065,3223380830214410898,4604283891098503971,8862800834554039786],[843276462998301450,17812695627880111594,4064030155738183492,7685901774517416374],[1131135611643424584,14374117323723228443,5408462005651363443,4195584784838765836]]},{"leaf_elements":[8831762582281426707,8849679125304178455,1163634422775562171,1214511418988627632,245761212292741986,855271111985650865,821644234077548527,8219783424990092525,13673513761143997212,9144940770014330210,492584385794290158,1704642129888627330,9671690423847147211,3137862290104727289,10330794113950435655,9406112070867154275],"proof":[[5621136431675156442,16038549556823953128,7179633459019492285,5092742752241552913],[12639043879551777198,3116432281338880680,16966569225874343934,15833611935762388359]]},{"leaf_elements":[9390894857537177134,6775050549137632293,10212697533785944089,8397297093669755354,1622143564591104592,10285492781803425441,11612578074530589,9279746851921347959],"proof":[]}]},{"witness_query":{"leaf_elements":[2178494155449434976,6803386607962018224,2117095920870304336,9387277922908079246,9314464074546068473,4699458960477269906,821318793872098373,3285017556890216754,3243586207462331348,6149926068394627872,17521733025059016446,15107230626993984192,12966249583819517638,14631213934994632070,1997241620835553411,6198754757328398278,7178618327636421739,1795321044384507113,17632107018148076520,13747732529781814577,8985102949178709617,12075060962381424458,15323012281985682780,16804332049928668103,10733966753884757626,17776283308202067922,2710630993274680596,9731887760864846948,12655001671905095856,15736541523108473576,4886153429540273770,9014382887088152443,5506526804970719524,8595230035347882187,14990420862480502043,9801397888768053170,7535836857055773846,12160754848025681929,9158446250653850222,16618236260499883331,13586851243153826992,4730463133070245870,17917754530137959016,12722549645669778205,343939527934865546,7960361906555996360,9736053199642751865,5915420382222409658,16735047873820210465,16864090889208585109,5042630028422572839,820070037558037111,4153454984241845982,1042209246299330449,16224402082111982424,4282779683877938846,12811855957472827060,13111060028603444228,17315867058904806508,2658078305592374217,16500838106967630844,3733044470604514385,4309960700691072919,16803428423331443522,3389039029174361787,3661107309299449784,10491094730767442727,16113240917870710333,3951404512507636758,15501654292363870011,4557744503670374274,2322433930733017934,8130058736685125739,11888700044197570580,3651386651919136385,17550460623367884959,3819195175913619149,6374615702542457378,8080385552745484730,8774810616289585945,8135789438405166047,5198160377926959677,13489879570762560531,169769395458888538,12397006409480379942,8864687782076976349,14586378174065934642,15021898609469337097,6766430431103622696,9063850078778835382,2958943733885006672,15936393176017488821,17922093795095764395,33659521041482524,13032733944835270292,11112699787211555133,6587301270679999198,5650550901727514681,11382712680489733474,8927311704965705887,7817874875351335336,10388087033839612895,10724374990978412290,18236110386476076566,17504223651097736857,4183001787622968714,11047790270209832011,2743620107554303290,6019324162913283548,8992012810936881737,4080168199339938008,18063091516056481237,5787565529096975748,8070970685755388945,15537018635171690022,11693158662461682917,13193578465789501769,516031200655443785,2529109787051959926,17757063260233047054,3984106137449334466,17790225909513962711,11948605321890209854,10914206537593793638,7016803932721374196,2657054135414276137,15395843659954180641,14902131764292782829,4579230518488174491,4501159111048292897,4606124826055983519,11163077849240900276,3143949793506847174,9957530266602031504,6691179797422604950,3294814865096399779,12407109797651097446,15103130252751654927,4202808784275079656,3241575612888992731,11556405326657176011,3889539861931158611,8141560542808600839,2113411624012864206],"proof":[[6148967587533658010,7636867651556976050,15975572468718642337,14898366162745379850],[6660039128115516779,15850483964979119647,11871177725006440997,7523361768581419619],[9414014741387440951,8829595242649999077,13851011919579500397,1991916496709283142],[1287538348497496044,919097777470366495,1617836061584147390,9598093295393706600],[3881018332693421159,8579565856310567763,17917525122961572871,3720696661903458928],[8210618784500195170,11252721283686594113,15170721197455645865,2316459309092159243],[810410604207925753,14120998025273860214,18267885868178681298,11529439184379248127],[5679303319292841087,6542953058823552962,17134590290294060217,16630228526872864391],[13246952732036589212,14457253857655624080,2867396999015201087,15596181212692722552],[6191602738119718054,8120833170780930010,10513400052039546127,12709815808401704359],[13269102046459908763,5637071282115588475,12453962811242155455,16027546919662080611],[12079616040613043530,17894573241146901018,13312057225550005345,16277577561316021191],[5018820587613158999,6683736591582469172,16019021153306355446,4557888596331306112],[3070479922688378791,5898853514227902247,1553389394708399163,2292551964272991436],[13149582394289039999,3863105559096309962,12176340138820409540,9485705149510076414],[12263107530976983621,14946409716744128635,14252860576361415969,578891639014760147],[13917355053280016149,8948925822613976562,2644449230881192143,17693607858324556593]]},"stage_2_query":{"leaf_elements":[5696979355546913419,4981606878468877003,14033561759318777394,4322120737416576189,8978281327142105345,8188936541526776252,7710795198919413572,10324269246426231922,15294641229822370270,13622027870986702615,17511115733930050556,6904450361498134097,12671218499958828604,10886571320061156016,13501725090006327120,5859180389350414451,8378340955049638488,8855961847173973113,10667295197621676321,6021137764533393243,5418017376791222427,6000705121872918887,11139185594493483630,2708866603617159780,4727814143819388334,13422868201596499649,10620255251895003666,6580962132780451094,10299847516904291837,16869145063046542452,1296486589599522448,960828337385533732,8721260186469777588,7947239686212071805,1961371433163609530,15501003076236396144,1290734136988823141,10411982258278792224,6563974895344119682,1431014372248200718,1082979588705142424,10615155454677742734,354048533812474980,3672981157678089882,3563943917365971486,13477784032607916435],"proof":[[7096366958808817345,11649548937129320635,6356539576899986433,7617315063210313225],[7217059713098687068,17661607358573624600,11347880708579789052,3350709692538490291],[10949526114451130504,15531592574115096199,1187897184661474005,8715767217961072209],[4157443170670134918,12333676112465561382,6929311838975309891,1041562490694306551],[7724095595934874180,5071532263252051368,11118116133857445988,12991583884634253506],[3492605348184521139,15239498518278474018,11382438675413505237,8495450279705165875],[11591495397775599772,3783328457192877482,13042563449010849440,2943938031642557972],[9132643881729071309,10803734963283769348,10121673339901204916,706615389062837630],[6912716745700246466,6157329356752818161,2760226722519238739,2098690090855379256],[17319088781878749264,10002655556991657668,8651977425950426183,18127613806354184024],[14529779221586720592,16932731158029869461,593127285390845979,14179883051010994584],[6992508459286284748,3617513725277814819,4275883928810637644,14515755080350868156],[8608947074524862565,16926085813344465806,3359752279836658211,5661166842745592379],[17525818542839585548,5302400811698484843,5272013957691095156,13653503190808810569],[5627742164201297610,9777558814962783590,14277263566687477581,15783309951922458709],[15098974582678771594,17169642870996584685,2216656668362150997,2378405125656634772],[16102002282897089743,18295213055960652280,16731926237739983378,4021316012502111925]]},"quotient_query":{"leaf_elements":[11961972381683054691,12929706447959133630,7495961996997332826,5602288145625920175,3189800592384152249,12847027787716511469,8318400691775716680,3874101700695563934,4295235380637487167,16617153521119692129,7825002226078462796,4824949492943919192,4428568448376155375,10892133963544427680,2244188811586906183,12375949645187122566],"proof":[[16758999955920131450,18243887870125331816,10047062718572192859,11954334633647395475],[16043823646549615879,11590076037191934822,17422719740730995355,5739429523495629817],[1017990547860271350,17229726407511947853,13557087540474708655,648258038613647973],[5978746359346561344,5300549178147606115,12713488123303463267,15772900245332367916],[7615865184850941457,124600945393445100,15489458783156385614,11424662959624232577],[14625843449205374945,9299578488548971806,17560245152116501291,1178394352365745479],[17296938915421250774,4696558748519628306,11670502061639225648,15527801344977338798],[9218934726272778172,14326677666509663512,3992930124063607078,778705236438309597],[15302595007409627263,9315189085499811665,10938942248577447997,2505185537982646005],[16773425893933388394,10877278935251116062,11396135947278085592,1047284255431730330],[4281174683604439924,10022424172061343004,6061437264273247052,15765805552792312734],[4259249798668692436,12663333989078968804,13122604882820868197,12115785171116327618],[15832156236080096490,17551689624874536188,18371792370362233383,18021361105855795669],[3609652466728573695,15585811638873034393,6159071651713361184,15783367642039856367],[11860180965464790304,3412872902928969330,11693808609481521852,10358402473659912079],[6206099150163201512,15100852278251011038,12758768420780090649,2156096104618429715],[6281296206957475465,7421984504665194969,8595830836685202410,9223965952567029697]]},"setup_query":{"leaf_elements":[6750234296713004605,8017546906205572016,2439940443718707994,10666421060360856358,12029054177071035718,3496797317917216311,1111253595821878925,17190062256973796801,13333323474527510108,829712661596954117,13593067737937869889,10888458568480743274,4923650909879915880,14640719101787270843,2201967135860646126,6951368396002893544,12685273223433614702,12052409696191079994,6119679098699660881,165119470494855530,12675184344598700256,9308754073726966290,16300034047416529843,17698645298476448966,5630749568864866506,2352201013965609163,17793561719314609225,9539287112947698327,8017698374644639024,2287375419824269644,8773188991251233137,2527924013266834186,4117238787076906882,4280778256510656610,7357388464725349995,13988710887118260070,2987726005311005928,7999205593945020951,3265537135898600654,4271527202417028208,14650748211394259748,1193999639950384917,14597580900491052582,14103636149912183337,6260432549225656838,7043575651718813212,7010878445356133014,16277810367077905305,15598831988826330323,11920338668183872606,1481952452813223942,9602472429187703358,15575316773528021722,7902552639311336,15985799902351057266,13321651160408184605,17431695379086812163,12791312056589676312,14997299254427578328,3923576873268199843,15435804189187771043,16341140501114719319,806572606161977676,12877514078403804643,1385671452138266388,18296208994727976180,4274481184109437459,12302644542525557625,5980494691996304002,1782671926873037577,1157808344247025234,8070406274060022049,3005573991641194245,13363728801967672677,15673949814933446031,3714751645145660380,5104897435050599370,17590957681029059716,17190202811138493957,17101285297101526135,6635242381283446916,17701611177389762391,3284935718543090547,7480151663537988110,5045164108222734108,680621720689083461,11988803491567222165,4959360427643415248,15218484111505432820,1955133474303044282,8981976417774665462,8640378975185216616,3324960359539293440,2740963960123209199,2732993909593760189,7845071354847675822,4507591882824488690,9301707380586711937,11901541927926498466,11172500997080880177,3966766066597759207,17385180086707915077,11088939032200407408,5784364259092343444,12931675607613044712,12234050293389865972,9800832057955953166,6497569028671826248,1669357876774219626,15875330068641194105,3416652978441205032,16491373878233311771,15331560951872867548,15120117925686583711,7566399053331864988,11659764331172634419,7333398233939461198,6720060128324422265,10635591551372124305,4666534506620800554,14034109152063128864,10208991380240438822,10995058422117908943,7482940391651818083,2818970083944471260,5207759223598565137,3248472050559853352,10323667523855861962,11317739493254726803,5480531198107658364,5077729064857655781,10692405479959048494,15761428869784236600,18036119324725400128,8577857226107845895,9880974170334995306,5870455452527438235,17072943876087326420,10917629182701242317,3534407485979160042,6883352514295192910,9783370229501413988,1051416361065199721,4394192557550950328,14640739784360655345,17401952841419601584,4167923971778818,10963525954716141848,16729519644604863093,10316870231864640574,13622203400160527116,17518339057740627659,10629517013950772031,11863725445422776341,4576053187932374449,7219522425726548322],"proof":[[14577784023607039378,11503531850890721935,948740698282896657,10433699886368721693],[6015849532374280394,18324966145529779829,15307469904275225693,4776723075699812127],[6522691698109873142,4396297600273207178,2439210524360811640,8105382987108135145],[11619751396116964523,17037221415693411411,318478340450289033,14396562161010494498],[10670089100552375145,5525720056318152362,6345692976442510380,9235872353993093130],[10431951749216321024,16791387316735818663,149412338063226941,2159694385655606184],[12653373069927339886,9497526281171420961,12054578260912127549,1159342179274527759],[5224988730224844909,2443843495052269545,547098562632531247,16881418966510751440],[6963929805115044103,10725168966859015966,3583528161736958554,15764482361872924342],[3181456199858018393,3879879308224027328,4590435597069141992,11836017870842386587],[12481888291954968879,4995833246643708509,6560705201804737612,16621165903225943409],[8893579584429080498,12041397730791621652,5743790087175014709,5347086928263931729],[5700574815171277821,14657945424408012918,9087432996728727302,3353886182744744878],[16052126685533710577,5903441962964655418,10705078810819990233,3070560060256633146],[9884168840848525181,12746459065676605993,14625749261719954007,2494185389594399956],[16468624810732279052,7607762181012516041,13301591688908842866,14513626317199103315],[16329307129806985023,9953934407507996651,17796105896734973357,9595248702518778663]]},"fri_queries":[{"leaf_elements":[5457872830845024315,6555213562007920204,11749787383470680348,9275223528443620724,15298134610738879913,9488259533263976471,6622945165401322320,14057182001216866559,17531885044759816310,7392899660253612623,11697650921755157402,12562571683447600706,16520961895835947000,14662088212266970798,9460957975401962417,12875845101898685832],"proof":[[11661674340407346333,14353302907110474009,14473377949357586795,11023581915617393520],[16826319570774406042,1425692596801324093,934992563410162659,7578311242024148446],[6362330186566582815,9134765238430506796,8857264375814301827,14892497199474393901],[12514221633730904524,6464256285713310180,9077840758818385018,10867831208517908980],[1989911626454766182,15680795366545074311,6414985751666611971,13488559647036848848],[12467037003041016962,463383958592390170,8306824626360253667,11976878063738315681],[12318140843909827778,15031887451904690684,12537410090654102307,1388842782121144571],[17179268442336956268,4063500558446235110,8678532961878530614,12595298442295216326],[1928740683844872920,8426568699959684715,7971374647184164741,10603687284741086538],[18126585053169863608,1584339541089197998,9609437056136847192,10258022426446596521],[17023372076183962668,71303628889462357,14295253508283646956,9730050538184122555],[11379332909651840568,16212189402113394255,1898030179623757668,12011109569732791995],[6465615274603114717,14071549083825852095,7045378021159046136,16922538754275474264],[4465615647496587512,8285173340571531709,822663484090032335,13279897163627865773]]},{"leaf_elements":[17926348236588898006,9270042739356661147,12883489071354965855,7354482192560944140,6249573743032088279,2462949763641395092,9400738369316770422,12335772603844006267,18239022991531374139,3236078303668072127,15163179461479474493,3338144145091455612,2494833536935448261,3999331561945664682,3486646129741146434,5481092633805127352],"proof":[[9763525650858869693,2233332230765108126,5996827962017844001,1633638246626498738],[15723806051002588041,15549127506424116689,2609128818724708360,7936439361544254761],[15798970969672251019,16703506770936168776,15943655696875423920,13136112984021791333],[14151198340511505615,1879771297191791823,3896621659142131992,4858599968216805416],[11485458549301202526,6064743869219638404,625705404355790697,15452129113226969261],[7011036312082662269,18394015711142397025,13675919754593456650,9251832345603527616],[2060038622810660265,16801289964532211020,15870915571195704522,3390868782571285116],[13535951566851625729,12224478070386680441,8680076108770385720,14989658080330675006],[5997748667029226252,5253831833092478352,5748949807750658983,1519970775224885184],[7862559798017551018,9033343532301844761,2885558212208918642,16873691328531701810],[3377987416368381751,12702386094819947235,11394188911260865769,10895080491670436673]]},{"leaf_elements":[4764731762441436141,11418758723987134674,11636466917766590533,12502949875203616485,16132930944586905826,6766101849172353131,16907478887386153174,2132790874054882357,10353663338913587046,9227244684901063988,11806841105132110612,9648538629580766627,1667333605865745811,13176329365892041590,15124286849166783862,13036129210321457531],"proof":[[9718564310280893577,8416826475867750977,12615033354605422939,17655316296581566850],[13111900225158071650,6899655365114177897,5768693662083571256,2396499222673807257],[8997733503086936649,4895971479001304148,10438229011748622493,9329256563138183537],[192900492887725323,11919095949673521874,14332347983619260457,5627408142099241824],[16371414114471586517,14015077460436728594,9789581692918465641,3012581160236618272],[4892817541283120341,13407570818461787565,194931254415774815,16862819318150998117],[15897745627646410123,4138927095958316503,16777395258972555039,17546639614974312439],[9032826725719266629,227858595913098862,8937616530513623233,13597688038816946759]]},{"leaf_elements":[2941852643317810409,18029793201272015237,15623585455499074228,5121218849951319482,7575135413390539855,4025469449541869473,17942644942427899896,8444666687220437310,3400167632827038155,5420265810929880774,18089684239363449202,16145063376677296069,7379734940849470882,11288702490424834563,3882865634805273631,17533094366407349756],"proof":[[8642827111054646612,14304661405988051990,6144335735664025211,17643704206497929052],[10903124825505571723,6339296836887755928,4937863499982827128,2962197255801421016],[8992983647160762927,922159778811406903,10867278974160493168,14864961114681734125],[11675671693818182133,1902706738904279231,17289973263092114011,7742664280850999043],[6499859092204384521,1570252448210781983,4297295299120074783,11214492741968423331]]},{"leaf_elements":[11829855331155965599,4830546353375774059,6299146983170541748,8501732138942588807,3527757281224878907,4933478568204213464,4555578098407807716,5302499633095859973,16798395881058879975,11279462491894822504,4487845517109864027,15000180622038315298,11612261100968573448,10559637258036816725,8074471440320161870,5417869784998170984],"proof":[[3185008591465807942,13474916269366926992,6311046616943205964,4403111204538895131],[8522820198600300673,13877549476641228323,10358658571474361490,17789923675703019552]]},{"leaf_elements":[8059053765769322751,13417580637374693909,2911351709503266961,17513728947462283680,18357528550657626748,6795100929311303227,3237676158979040141,13444877005340907045],"proof":[]}]},{"witness_query":{"leaf_elements":[923242777242072834,18186754465264066341,11777766764580104126,7653968460153851231,11196577370120581497,12853425749418344358,17897437796178329759,8457896380227105312,10242283856534788022,4911769316866741420,17150688142830798623,15448740330060375953,12992950014493390763,3769884738022812269,446620806908261065,175458445647740112,15775896196823276683,1014869461896226847,2357944199573215109,9645663134323558109,207070490422532690,1132613961213249931,14882104736133459112,9431377007001706918,8126696898580734964,11676440787218487147,18248377581094846599,4223839220222257328,2565177600748704054,1135994580883554127,6716251061002572382,11904951881953546906,15976139576719417781,57755834908304801,8732867841333405770,15902714479893392007,14108305509606621139,1455958671625471995,14675642857277790053,10026206895025547796,14363238759817801022,706089577873616664,7673510753285774697,9975497373652692763,5989559720147381693,13264942054145734936,13898158343639176507,6021909974047928629,5537157379931359649,8910931112190084218,6374249092584964490,8185603507703323056,639556518716916740,18365798376743955379,12862765760610099490,10101741179263348221,3741173179553544742,11729828879264724210,14033982332734245493,13740617461731350638,3633735325525340384,14030942693576099829,4697718049807901576,11450525854032293139,7569698932113958902,9591186050454241577,10370142532783137126,16312990662056033250,5436834314145558516,12877581068587943637,3945592229369183979,3755326416327283188,14694261451849757277,5133515094859834551,11897689259257607543,4872973554348082153,9207045100234679277,3039183238608474926,334254906465080707,13569509489216313848,9339924821384582156,15270649318906750479,2664187221812617091,13245901864959128078,6368586424755642717,17192355761105438595,12378760614492549583,10404122951380106106,16107111805070296886,3117422931884963809,2368503671322296447,1822137936988533173,12241717734028902778,9678890256695295184,233644074410046571,8963156323536336419,16344317047168598146,3815622490313939218,10288133858482741852,1057154223511787940,15880471868195657633,8766773656810278319,4899245755888889390,13603488804288175483,6858990952019742426,14859336230940155615,12199501320908527755,17906460038491884539,12645283883546353051,5416888085852344553,2823401459248696463,1337405486381971277,5816693796978140720,179706147335437883,16874708973288958242,8492664718495250582,11887298568242476662,5904251659949797271,16740072057697407031,12411587087683120714,9313645532354946200,2830424894176578074,10820422820580906177,13302667608693523520,7285755782679469928,3426197903495547037,12207815558654303878,12609985046019358832,1833189658379704022,10532737585218703399,9207611620651717268,6022970597483091333,17453672601594304843,5414620028538532325,17647285964393678789,16111066439776711181,15885643595856798880,1993339522415728560,17166131828236718704,13298027930725153359,14242633806993650868,3891697172614890070,9419669106471500919,3605200996395339690],"proof":[[11665132675693982919,249366000993910422,18230056584854070483,7203602562383121620],[14089286161260527175,11619638207692551512,6189592586325983895,8803718998767165441],[1147531272617135112,17254469201834167333,16923420715830458966,12575810259212880311],[2899125297419140912,16355825897093917522,4046997970797867641,12321572355328859217],[8113083720642045354,9067140071130990156,3906550595279834405,11129131522686255593],[10181616875811291993,12333454807730062162,2224528631155650997,14973686979806817814],[5646623722173176731,15128897715489789920,17524289665939577506,3319624027677856222],[11594224366246142970,11409411903290900778,5540120154775145344,3635425702599229303],[16018668442467850023,18250124825964815187,9591020167574270446,9449337632115797720],[13141668965819703668,16330599109657260095,14952378441336884565,4595741185620731125],[11530259804677267297,8077726747389201546,916492104744665538,8333162757177526023],[4655620556732784825,1834473746358748481,14165175147670727934,10360388554103947003],[5838416433762917169,2000145789879621565,8380711604097384492,99700056980069350],[13826330566503663160,17954316354866035668,4232931959119268505,1336387530934305784],[18031733399207821004,10412379805499463891,422010323843746668,7161932904258828034],[4956536191860962690,9740002573886859770,7965922547144827009,9881948363159305843],[12698140864963633855,419357374229537337,9620795343936707768,5865575737066574990]]},"stage_2_query":{"leaf_elements":[629469528036849741,1919250640889888982,5130526876003203336,11756691092817156750,1199696091183367471,10784980256220946341,269695534391140415,12450058662304655263,14550705003602188353,1998679454051857649,8242462319971356505,15628431970062902923,12415644600051667444,15820819760972279545,12570626007494851181,8640717038390384775,1729376572435553593,27162309198074921,5034687986872792889,17434971297356648679,10142589907423637516,8307047016096745456,6138553506108831891,9094458919839636783,1524614075512160807,13584206202377186116,12525257990159121070,9692174054432726742,9042171184549707224,5293619470499081486,7962538503158183272,17877998090806792302,3967319100449479846,2836322388164417749,8892784616802305004,9260988313549927595,14384590915687885938,12305188224565605594,13284147435836814756,12104317646889258770,16292057136274097455,11459276806685134577,8617724473574279528,4749336740957657252,6781691040170402160,1437090030977848528],"proof":[[17709530566690636602,1545919525284722639,16736070038955571168,13298088218326773308],[5936582908542393658,2843373369992453087,2176972637943258280,15497287996747429954],[18169334273564587427,12706331673495246756,17844219654974666685,5908789361720064966],[6983149489126720124,18082015042833728930,1930831428389390435,14602818322804283753],[16363058014177877658,13389552697831319467,12119205633796419481,6875696815173258085],[14406664539874748104,18335070184780271182,8876466591830949766,9420906865940805712],[11732121709029944323,16722402703598075190,7791383960283403081,897057716785488488],[16384013764143329176,7647729008365846053,2688803876615191313,8186206282928932442],[8175975555378788717,16885613712536975994,16554133668241764531,13217136597653746091],[16839795422509904942,17708631698583892899,2199834981767436794,7738399472855639099],[14935362125382035725,3139796666795175588,14704186199323763370,10736019915793927581],[14363076588494702288,3189859081137265879,567535915570772543,5299887733606224642],[14593763601571066822,16294564131873891001,11133822127468341558,9412389108827025781],[9261480102398729995,268054833379598669,5050269017603250095,7352617167510709528],[2354388938045228600,10591708672482087136,17234027940642076022,7131257646767318350],[4368029160520258810,7161438462072646830,16152631782368806991,12236771943529764097],[13885167953277892178,8555964237507770117,4719750036722080927,12815453938056583397]]},"quotient_query":{"leaf_elements":[5928926640604503285,13605990755437883243,14621201503462190042,14431085529668465166,6063963725989515307,9529317752252399778,5674782192875781899,12519279951539925822,14072549214264774103,104126620284826186,8439668955894486792,14490888543678429658,8511985043948518230,954625013005744244,17798772099031233342,9159518720848352182],"proof":[[4033722323801515435,15149732219514192945,254638259861331115,3054172270258456770],[414198514938344324,12820008772986747169,10948215344720828865,507512052570303343],[9895298580251138582,17250814958710688192,3968289033133462325,136781683653549557],[1737193739090065741,18355924666780825981,10003257589553449709,9507443734226883740],[17483094907524865754,867128158965975858,10339245794108204386,5074738414644392680],[608050101578534593,15715452484009410702,15901296362163671805,11711042789309293288],[220000675201237430,5228801631269947519,14907220747440751464,14402457931819333777],[1032337809902040365,7659452558219430100,535972893049799893,3712802075677296799],[12025215333269550235,11610903727888404009,15621589918013129518,6415222570413122718],[1841575371056575537,14880458178425905264,17828238154914020061,12256412946173236070],[14207366725443480648,15188245587215479589,10756409362178272221,5621409307707312228],[1669619545185066663,9123053572525571650,2597588012122955268,3234502918837319325],[7409160065521413905,12614553470090105200,2202640213126387558,4111466291727946953],[8095669491435877599,16860185108866740719,9380014318320979741,824742350028082358],[895680244825613597,12535612324434027543,12292214964834360559,265521962583921457],[14507401648781074682,5481093608352663045,1665047443890160083,13045093494271559918],[642646296282338947,11452596773553033960,8795257061196785695,10386969935657262527]]},"setup_query":{"leaf_elements":[9335702559744988660,9687228287742135937,688866664082697486,4684449141526127110,4601986032624789990,748112265897605747,10650650823396736572,13725063126248847774,6810290438112873996,14825808038048598511,429263540114555937,12678063100806862445,1226239878539818516,10530186522870774394,11213910286271261671,14711193355121225896,1698705157838145486,12394584543208520637,14299110219289604298,433703589389625978,17659012671307966169,999018522948554725,9539137624534854151,8429696000633949908,6414396197893351605,11346996692622335224,1313955168729327986,17622421236154555430,12614146151215493303,2195922386344709981,8009639799520084759,3096218874512126013,4722052113363293965,9608987605352401610,17151668465762403509,7138829320598065710,9526708773083712898,13187477021389604198,8176485049608270718,15992210006578865274,1650904621926004612,10425631003215620809,12528778141377965830,15338304242264012230,3909597892863124783,4358370595325071405,4239930603793739391,2632006705666826518,662463314655449821,17221470659572736639,14667588786215615396,17525016196955884359,4422531059987080314,5665474384261301927,10399479809400045059,4316118560234355198,12347079403677800494,10585615041883598396,1980431875611774063,11580223294158096983,4743545761197949189,15551482592512735527,15071360757853940398,94465678130300220,7735800647320913470,563235163357940027,4395755301115199661,929061892157564548,12898971736510480070,13468025283031994736,9306170205484063107,14919914393427315288,7230543341156850483,8753363924258762563,11152323928510354195,8457335303023505037,10317051312002364742,7802406184089238630,4228735269717516661,15938351746367351237,16306908544168702532,15424751099035601366,13374177903391761637,13292275630348695961,17186666398337317299,4705991151423392501,9741863346005821082,7494058112276429358,16577003642775729943,18380642224135534410,14182949150755788064,2605703363785258896,10372321319957790614,17323083055690217480,8222946888182984258,9822128020655943629,2227035013212395729,5944565113069024371,12886050295404243579,4978681415970213115,4304750041619800686,7003264480432062151,12437246451464242382,13186684211984767911,15596198678989393983,4536873963010127807,14335967891344308023,215131140494958223,4428396453521711492,4318886099930413286,656304746890891925,12108190622134901985,9173391801248278518,12985305205131158825,1025951296399473277,14085697785774741564,11579690183945505229,10917294111711177166,1388657338273245681,14570923977722697195,2293807508174670296,15072081256632451345,4601956567107462701,479208166546651884,10915314368313989494,8748406825936977263,3064752864739060788,8115428733776927148,10249857597213999326,15220620073846722211,6657775323229435904,5108332648224485034,14748067283915977960,12381161459330993958,7063694029001724714,172010882568973327,1175610617215170051,8352415757365096278,14331083756026222872,11902575596066454525,13218095534479457082,11700597813875342051,17082225241363772511,17270567131700882485,14671661306452172732,14808243405555822416,17688414926251895722,17421831810704875046,8519397606353958113,14749553387854987105,4534200481181115323,464940290335135314,4624255538741708698,10257488762784241517,8373595324286884501,9560295305466210716],"proof":[[8657633999470771775,10600639896607593469,13272234087476955091,7179094306050627415],[8270944715166453468,2501261729569803801,12538628685722442023,5906350475383223431],[13692049496501365028,11748119359597526657,10295090001913304828,3008745831429720996],[13558137931017669218,16864736365236829444,17091038905279388486,7019551129669360969],[12525161004129042776,14944869564579073374,5481586747429400282,5492633090818776759],[18336310235586929984,16166447166268445866,2372053238326082613,877823564871698707],[7356123184099588419,14033270941544604624,18168874064406341401,8923349996769399038],[6539672917431305316,17269752826383528304,3380943971467033860,12360492866920927161],[14143542867474499344,5924534499213458743,3659998962400927853,14544390358807644330],[6540764888423528577,5841117875776599228,14688398453097733038,8472690484015136655],[8207470431308756183,17388203909660756826,16587006990407528250,7035616994539840738],[14887253675925463314,3344234969550757029,10709244911736127799,12405648050232488104],[10120045364453527192,13358673169313156947,8755302218762175966,1764689348016947802],[3352697175083948905,9250655243035394423,4191796040864674555,16123623831863722432],[18064541082863809829,15872008460305419277,8588056278847533005,6950004221199042362],[4461952551025463037,3023088726574070982,17982674338935786519,9685827106554591550],[786433969103539048,8122187790720253298,17324655261546370362,16556773082047786574]]},"fri_queries":[{"leaf_elements":[5748197947297182738,18413822789044316686,227854843867719676,2389009037793262445,4309909085306651100,13745621515049561418,12100439793775938624,10776254143970784663,7359071171322281333,14419268655690369593,2813629385727693857,10312259688892981715,724028362732723835,11551186795500682488,1523687085965586533,5260779811209286190],"proof":[[14984116133091158960,8268578115381202069,17684103777369392866,2670453634963101257],[2629130279323107358,2762056885352303820,2389169003642167450,4328521515062330758],[16742280255025924542,17167684997755912485,7409371381574780132,11685260699406619900],[17188884446700381598,630612485196567514,16417643120773694165,15248723433089783586],[12441641930153748747,15267384116541718951,7067188019955453562,3101716639936],[9663372091620055159,2252740729167782550,7809305053087576465,3319501312477686731],[16455696974242751344,4659892274654111158,7171679446993029598,18043189119936775945],[11541786235280045197,16193849841657478631,16097155789913537510,7148304494918798999],[10323245518565354748,14652200480477928682,7043266351969330761,16611285915438829715],[6956224171706153506,8969795122387657788,166670448996536963,1342197626199386034],[15966199927465979067,8527666965871274785,16023585324592680108,10518718853905135451],[3745876628175163865,3756960508763281976,203824404837271864,11390953224647298057],[633006299616784563,11139233886430462112,14538861665720934038,17078736384713939743],[950518108147387034,14461496559104778806,13917507090447352020,6484097189552047977]]},{"leaf_elements":[7600759467762954267,726190465542653804,1165276785568230246,86390641148680856,7024367613896000618,10592301789336439421,10554092609891171910,15100064437717890253,10813435858762766341,14586841684185486552,12261048851581630162,1911160903966667957,17438262103169348792,5384479211725698754,14245528618976197816,17781678218781137074],"proof":[[15782775482445914000,14808105337732394377,1262036900007738231,17786970850791004439],[8871178816608670255,16915641660023357704,5215203234954712112,13676744619471429264],[8015333283552471440,13820171786124798877,12875789504587653579,14738940146935812388],[253623993956411682,2886879917753192789,6627860561954653340,15983706682091918687],[8819639350682079831,4208224893634328358,10936850932290737787,7759145232134270410],[2046304923896359999,4667148973551768499,14749883437869469140,8492850846076548025],[14164821122714060383,2637679632712638017,15983735242419252952,14438993407019143150],[1840052571332972499,10751182823263430600,16774191077343426191,15297337149317586454],[13118213535434356573,17000520463528956436,7324718712935840724,3748701430809538626],[11727157629316029541,1250806423073151966,891800793544898678,3305784069475612933],[15418802502015684347,3748451402095185069,4925493761703378520,17844205222826790497]]},{"leaf_elements":[8618753437017166208,9902711168653849785,5167863246239711175,13172280104502369012,17908249057241744110,5499038356417339779,8802742959175164615,750092249771591878,4956001282081402217,10506444068657529181,3729149513608936756,4343190449395675684,8280183691711692399,7672608131616360581,16721920022517099243,16495656655238982474],"proof":[[9788021056244131898,8003281489201952841,16988638773511280847,7985676838826075628],[1119479528803146847,18158844118935735397,2832271913880424099,16983700749542114585],[13293516467545269583,5985142123277820490,15167963478173014677,10399933957771745694],[1709689125924260974,9285994502207404546,6659810448861680842,16622984740912240169],[633549936851608190,14280973325313512206,13669646986927399745,6976294110258517848],[727247544399857399,11206817533063356232,8958672615128246055,1486376110366752437],[3309760038805872449,3631375083889281026,16237336208109412891,4696666898883299182],[3212075062214438924,357583838110179765,1255898485944832398,18404599682258834503]]},{"leaf_elements":[4694248105743968230,16479592979122757101,6995529293129170232,18013751749177474761,2518387109025432728,11087057171034726079,9732389920662795570,6363333545393030043,16663154110890999112,16109971046893259403,9818968753209276547,15777049412086717858,15793788183465388499,6890271747429288362,201028384699365372,1939076077544277317],"proof":[[11945913660338363359,12397234939180282285,17265019184278388236,16401006483071904644],[6650306810058327249,8754662947417517490,16148136509143999165,6922883671423112688],[9338266497367297772,17909711551570829906,1184528856542146875,11900208157843974364],[5044779916256531052,2331765407222297206,13413041339537916887,6356322448670778330],[16725837145914548581,1125423394101345531,17017529173301036278,3401633365302970415]]},{"leaf_elements":[8077129660493228735,4858281455775931419,9738227539308241978,8050169102116844847,958630553091151607,4272321284588196009,14067102189345055928,11594738691112592425,17695426800051813913,1734969492251892270,6619316802958639459,17588832284713609068,10653512817480937953,1880283887890030755,6288995053754109063,17657381800227068251],"proof":[[7234137796739021793,11668650209537815079,16507941039562116065,5221555160632642940],[15514906446679858530,10979498789109703592,12967136000864485334,17159923573772454695]]},{"leaf_elements":[5913797713474501816,14390836815188810001,2598086964460305874,4219281277613110736,4341490336555859025,6837138495876505826,5182460282140934405,12936941785162437742],"proof":[]}]},{"witness_query":{"leaf_elements":[2187445627217550046,11141624725450670686,5346485338520239116,10927795500256491507,17479094032888187741,13902302588136989492,16856255376046552874,8438062531118581024,17843383236513542786,18198206525372319144,2346637603039162992,14552555836832916254,6473569791221363006,15776390730542735061,11242862177174363396,135430380188740638,8269735131636381556,2937037749675983610,5258193830890865982,1984235981900527462,2343777996160329655,7051727625387710868,18222015209195223069,3117091888295666335,11228023973020067634,17621143370025656731,1557961957987926894,1354228926909787509,3235718276186167354,11757650068347011703,7822558166833606346,3826619906666589346,10776779348691458284,10083296376244656673,2954654634944469778,9488316568246420664,6258781248769084454,113384637162473935,8099275202621832670,15101372089013950676,8585720343301062904,2659510628780642220,12676053929333129906,15794280076426982696,5881842197957396219,15559618793995074672,13211928389404231710,9669069297683592275,14421234846855446571,8604790560131649947,9567722070272252366,3332203658978181709,15346966984032197692,4301471692118419597,17459405918030035726,16946382475595880537,17128226324569681146,16156504853365557531,2032471298250685682,18256313917160330123,13233218048641749579,14812967582263143389,14410739271103129210,12272853854104454776,9674704784381396248,12052013054169130106,8722061534587567781,5150796960712145080,285824763591518146,3937024734878397852,4372429158902197755,13606629358153237927,13854488469765428952,16123804246861584843,6410306492666086148,7251798785562514930,15102610177681032473,12735377632173392635,7849075231538605188,6670854418913654671,871714318637337592,11639661043395619248,16824228146806415043,2184989905086573740,16390869874998917436,3849212389565178645,16897694362068034578,8125143983268670243,16224911765966445253,12977730606340796419,16377405249040155899,861042226506205941,17926033601696546409,16394028169204137415,9771522733031780807,1553196188029673361,11644672895168159595,5167230831990449128,7456941545232541850,14548167991660124414,6610869513113172043,6997714430297486712,6123357527952591132,510795952201017303,9598044880272098461,12616235374392139944,7010444997531052001,12082278862768718256,11392058977970873440,13270087559216521142,17118182001786773909,11334020069449145462,8026235711295843605,9944154576680665886,493742286944493980,16388586165030314268,13727956954839624403,15890398509431278649,4376321627844012043,18425831851255171210,1158905444882315740,3244181400164483347,3504798547713923468,17403332071212268483,3684074551798890218,15515924677648727432,14187182731551440912,2595965953426095577,10565560061619987024,18327759214186450309,17014082832808531394,5756119275767239599,17542480111703986521,7544895769136692996,678258593756030719,16873445165242976165,11890518778811923647,6952568677651657777,8410281331131150437,10074767494974215780,6646882494548642927,17196956109690353856,6893423846658545359,4997234228839885416],"proof":[[18102787992296444800,18067250209836734921,17064611448815787253,13676467388816749291],[12005326396684257322,7888796390831156042,794228133814239144,2126554367435404413],[13918276700377748050,1593594687174888917,4623344331952165005,9160641566992754671],[5432288711625568160,16280427171285835919,11116987893432858967,8634873922081703817],[8034655804875935548,6472258782740304960,3434409463855590867,10090626692137693342],[16913484323133621741,15308427647674404112,3782205579336841594,12545210867269026267],[51158428506709596,14714433365240449329,287508671108652009,9873146370499429184],[10537932881173584932,16221209150812275399,3702512971048837513,16654432195917287828],[3165106287411878333,6985766557625348578,6720503639939951879,4899911615736044942],[1753567836989793232,7261926287301334102,16127061192694952938,223208935864146374],[1378802962966282360,15227951267078116698,1745266076927696152,13330732739507689619],[13862327355748295987,8961300494536233398,495028445604325402,8594144651062539135],[3095310531169987483,14252582378466689317,12859948703902364889,5243938803927191503],[5532952643396446933,15115593821167834197,5639254269697157159,14423923320488902469],[15544351026640428253,16664542032675314289,3793469854707451638,2061914490897817468],[5151659993604751115,645557760056141545,4654911061998168919,4128363658395254435],[8193979718528806600,8375224386207577318,1516291403550624483,7080112769819207072]]},"stage_2_query":{"leaf_elements":[15806498221678802692,450511978431366504,4788001624038957515,6558413410066764706,5423347344877834738,3959589724592064426,14626884593008668323,16290888553987297259,3827327090635220616,13921201464838001433,9208356686940260437,8829676374882974136,14627294729564365206,12733487052192715396,7527415423622245571,6716701602181808255,12701849040405993793,3594540791492346259,11209864319251040869,14969243694976202843,8313395523073758556,5025207715855683979,5263243277129165092,2837181170477895157,16276992834670303091,3778615816648633662,5718468592813133742,13103535363923531845,9380623660822934519,13838575329070983498,10069570720705604072,15613607724645631837,12752689317317510430,2706211248082359133,5213924060586376238,14004586573216282936,415964466618533472,11869392452272025569,10978298117117075030,11027865552581142139,18264881796374953427,14643271288357863987,14681002401122559001,6474525799749849768,7004566822883052284,3227503934808770512],"proof":[[3756871404012133050,17196784600976815180,16119622010425950677,10270704421634729117],[17449029691844891760,13052626377761289858,7873394366296350529,16213524283136264636],[5248372103085765396,10421036245147754410,7736434704873499720,9384679602520452465],[10517352926037349685,16289407989199976936,14711369096691195000,7467146660714259449],[2633763119502476237,4045333654689761374,9369179322808040092,7620548725308764360],[4753129216484653749,1111464516528509981,14782767328313127805,10519454703891596266],[10116090359984364835,18254915105913819801,8213033203386522362,7683074134922062833],[848097307279538155,9078846241850469077,8968751523548632470,7424400240663072239],[11430501409928233382,17923220183631601878,10235396694454962641,2287453981053941194],[8442386647222639772,2379975048068595654,13434416096016956166,10969140149729793591],[14312825099870096101,2696678077652712786,10381157892411789711,13805656747367188920],[13497778939679774706,10433837432438928217,11355162754300207380,17650463938461850746],[9596024493739806441,14729834049401309639,8674300309348117701,3695098945644645122],[2240300403073741808,3573087946674017339,1747560860203940084,18139251089162316523],[14389400424703654529,5728229013465273740,1620393258125587939,4898587107104186394],[8160668943952387841,15113233575098833141,17900040174636689252,14690530551601386128],[2156372198160320375,10758004586682519094,11754802890427400344,1564423923851060793]]},"quotient_query":{"leaf_elements":[10214563216159049387,7319032293035794074,15270944541668900277,2636730892963340863,3323298490575829891,11316605214396016918,7526720223836943028,187156325293376890,9161470007661159057,15021050845051282419,7937638877480144457,16649378140308471172,90793322083707048,9296800049215297033,6935757668677697710,15397109847070722369],"proof":[[4112222849446277505,7382368443022511551,9232078447963751041,5444894505621362105],[7874782945875706185,1698755667385544143,15955325175265045940,2425211014738020327],[11658489678958048077,14036825934218976073,7384735348349521130,5732873804721274651],[11729045530081722777,14505603921032760642,10110059993398388873,755463991391548623],[13681372706526446022,17573561373262951872,13204157045441545972,15830416892530523536],[11997938382838657739,3610023831909204420,10917008745543326212,17927916731536486166],[13931596976311366378,7029130826776948221,13144692038615018174,1991403722391910167],[12692689827573176707,13177368612041949269,3831716163204842667,7523556986497347856],[1389193685862276165,7196287301975767082,10131439935012354018,14280345430933375558],[1958419220160598409,9682916114467722339,7226564716741263772,14348422585951384218],[8065098512672823083,16952196117075082816,13170471853572311640,7452099418036193373],[1591218004786438884,270987115967709796,17759778341267599937,7351377277269956621],[16218688527646397728,15274207880157958938,5359337482383702315,5059080077160211470],[16855521754175123871,13844465178348561343,11015280952239979845,2237986598648896851],[7249478780677482838,11962943810305152810,16203087488686938907,11175210214515286520],[23346753238032871,11726231107646689909,18446617914928111271,6867169717337366453],[6781824673145116271,11884988964241063795,2786037544787052384,18285016945696491669]]},"setup_query":{"leaf_elements":[16559292023548496393,626380530257851083,14236612091808420302,15653002504416399044,7189689575017200836,11071206233414077352,17431923021143793719,6840311891248757836,4851641223307670210,17656730829382472574,18305479221265366720,1792803738625356045,12616937304212373670,13707456452091585650,14880361201409709085,4362813664167431217,3631854360164077481,13977998147293551255,9697811620863006424,11732421410405909546,5397088662871578242,9835288974223515611,4342379278505858246,918059442567160048,15956276403538143386,16586085767721883119,701594361080518126,17728832745083584784,14250268583992185809,5063281668264825091,17206625377190586362,7034000724815605513,3540714300144941876,384008886034164325,4354352447408406506,14383446915084288363,7830587317905776,1362938219274663422,10111762902580225105,4738947692767750052,15709732887208847076,14701429727427887255,8414086823189909986,5191840313993905288,17481859631610205440,6098376036385985089,5213832929965839789,8214454219669910727,1996445922966837101,18434690278805910448,13942892854534866928,6240532312731167831,1177320791564416156,10526446798424559229,9986426183369265631,11126256885795627392,16884542338527709409,11701715425168097029,5106048676846161221,16434522033563544420,12566724376208567641,1872259657013700774,5350737003484855127,16250532592001216293,11240559850837123899,3480430557102327997,16542034451944612644,7050523151487272293,3579025148324104192,16837857445050657745,8046813935957244618,15173344770143092648,2360632859382519528,15592495886247292688,15712419847980953594,4505942116546191949,4085981196183055325,8770947730300028754,10296711207916923148,6788172187849063844,4886928825880951098,1492713051253483383,9250129278032724659,2457883806365970598,10856046385561936070,10450082754240130356,14921281871330983883,1131836077321630136,330783921329551530,5303606820935383006,11471975870032994408,11428609471355316876,9553437918448861409,14604621491364987872,11043609662779302370,13308027326042375281,10000726575597862093,10476569688298623472,10681546627954382790,15516807179508174017,2471604923803736096,2236051471814870959,18106888446865553672,13619352683435730803,14134385997765496918,1209918292462210955,348670373502153085,13836580795784622615,3925141624547697475,7227426843728801235,1450948011934409102,9793942024058607749,18170656111245736775,1098844998485896954,1225501739082661446,14345882681634207463,1065479110013629019,6518600124207706625,13169478964048918261,18082532167691301354,9536560092165937271,7697369315955778338,11478661613290256202,4871184557960747088,2106637543401138540,7751227035831334948,8287752896850448429,13076229022509265782,14232264074323884135,4961330625639391270,11048432888523536828,4951982586125028663,12722411293842507229,6244442782008766289,3700958816495103369,10241182616219048563,4534110757135350982,11194062534908490554,4546191530123717668,8461459970957773094,8654641303099891686,12478656445576431150,1863092021131611031,12834492566397727537,4650750885655947373,12181899178997406741,14608422472277543356,9863880364023520576,4115892764787241963,4069581555401890769,15192043328709621275,2646260294431093747,3987110196012231760,16116052091563801298,10838694711729522430,12614897075970578641],"proof":[[5603075477364511194,11149143033663871913,7243786867366752743,15230164554391291715],[10982965970860086804,16107823402714480715,15942003646542418840,16372349078135958740],[11783132262608198665,13481330533508868854,9412287014507044279,7411462813507624715],[3144261995293250041,8022380758722844796,11720018761927753439,8114223955759196819],[746176751104596333,13676458243019550629,3996592666314964005,13574679228256852159],[7561840272509994441,14523962027920318916,12654714522169605985,12830687469429452804],[7314904302062454662,4049377261329540102,1563463624248770642,17232079072282737320],[4157099262366391630,16611254661123715129,9629406473685617274,1921043659715906],[4550389495868832205,7594909407130479576,3335224276037349241,13541124495475975465],[11235471448080075515,3280492222586703515,9515621796911346745,18181932432706717193],[8970280984479700939,3880495282417521359,17515347674602823763,3086918731540698264],[17717167806555130964,10961764412624849704,11663645332001355850,16927275906987432137],[53602245233248394,1711546221371918423,17550328485082660529,15666190942382677804],[1003141733649992894,9539287109793419589,4658599763642001075,5980130582232820097],[11536297571503551137,6988476425824431457,10733993600214099676,15165029585949695467],[6693758018881043178,17163178482231601620,18394111945980300726,8057694723322035056],[6927789725927369932,16315812677162299352,8615590175857271490,8798523207874952519]]},"fri_queries":[{"leaf_elements":[761033229668487588,5819047019037257838,516869693986407784,7496486200773497493,9951965428718367560,15336870762977312834,7702212795628549510,248171114622605551,5576413120611698886,14734453468037412120,9612632291724390068,11899905841518091299,2760521796709697678,14079577319588609298,3230741219630724778,16359227250171844510],"proof":[[18443852530485379124,3523642728707504374,5987534038396859438,10670182037732284637],[6231186417361700227,5262281969076266006,8444481680881094026,4896163738751696549],[8064547926874907689,11070143901397529290,13468681595366840869,1197623684733432763],[2304556388319554323,4057404944250855369,9952397459592636277,5545948137683104638],[5338222695583785590,951076756731279423,5014635465627223618,1705616429656477678],[7870809085938833157,15233770592930173692,4276578356435284893,11168404914322085808],[10431117158911590215,2671335283198862367,15898297803263238063,13540141153225359122],[3842025673896904133,9628584310952611239,4961013740634569509,8521982845484688762],[10416193975009395699,2721798047788486982,3814225359005027339,9060088919144243543],[13185620429688186139,15668442923880998067,1463559732172615715,2176346358904310569],[8157105332537618779,4950728495401761568,11774349360587143175,5916534605188581827],[18212893585142838476,9783772644328034385,15316994782106476312,16710059087839086961],[15977936783553298065,7883991643266293292,6140878641507662900,3647299902647897688],[14128138712872929702,1370874517542577445,17278172058011345670,7215150699576622869]]},{"leaf_elements":[8544768788927969813,12663450652899282076,336534569825769887,9652193700582312944,1528454805375033683,13640919014837762606,15964981603401154362,14893083756964839613,8627039834864845367,8611271781746994447,6891769484626894110,16811849267303504076,14600120895539412291,17102380335686433521,3363302526680540261,2802571568574941776],"proof":[[1409595249430419738,18274510994400590601,1626450915438833376,2546070822225819737],[15840364487690736171,2476084825560554990,6322374777686267977,8743074193450063647],[10797481711576956712,15621665191889121943,773205803400661854,9607999293135320118],[5360210078109579334,7520315500174433150,245866908730945374,13659759923331813058],[13304855807188030308,14499862540665034205,7123032833363744334,4631001811816739153],[9639725702494842068,3043821596634213042,15833737919595372537,17371611237227074991],[13507877685082294032,9599928342525723481,4953344209219648615,15904215237451203646],[1990844980646651911,11609327103413383168,6375818532603393810,1586527757257550501],[12493369875508989842,4025515444913769318,6994036029812473475,2364720931976867574],[18331591439139592594,3424784786448365084,3142444139132171757,4272927789110192094],[12455615997980745569,6899641713496781723,3754459214410385641,5180782410589882794]]},{"leaf_elements":[646142038413045525,962404453877184726,7266875592215476168,8666665026071422563,15165504274024193108,4250842030352456956,171143973665558448,15062289399687935225,6737916418175684872,5875453225307927053,13055062249787396221,16236670097899876477,1408538582687870944,6569509544359131153,9021435801402804033,5336486611927808990],"proof":[[16009151595510501399,7369165909476078398,13614474114917040547,2141122137062434982],[9267201103209075045,12210166960071774986,10978022191551569372,14106106858580819548],[14203582466879790448,9600426333746527963,16347569111425773751,7803261431270672330],[7090215950819165839,1718322555648777863,15607358997600238430,14187544475212456511],[3353637974388874635,7811532738950344826,13544203854161378556,152491397084776938],[4106268852492397033,189587160016102801,2799038724498290629,15143849028774563269],[2651109751430335033,11439206719483041059,16110394345713369638,10184638098901079706],[653609557330627868,14023145008717793735,9829013459427154980,4354604016037302551]]},{"leaf_elements":[5988149563717735068,10129107082301516676,7845327467558718460,4397913916305290901,10711025144146452365,17477238232825545418,17391574583945768728,4352772736690808064,16056439212024610479,16932185373649929120,3591695287406720998,6156103632758778142,9563088248796676335,8311169350694442227,13008706704424577584,8445328827297140982],"proof":[[10428684209189502097,18393245596798885122,8858871421500338386,7130446161967547828],[6825746998886106819,575278192205346037,13201989319296857797,16380780625021427391],[7967361218271946802,2459424386439785929,13914933594261909152,15978298734219702444],[7624181206374835069,16639945051842694695,1627165198208021593,17909495709380549978],[9177491066822616147,5431401594819627928,1355274528698398268,6660308507820893921]]},{"leaf_elements":[14886676399737703560,13931663038602304496,5280470600619763712,1602784438155796746,6479264596726780000,9993197544143353723,6492683510011167601,17140074783765260898,2942983150467580832,9921602828685932366,10671825697004583395,186956216834001891,2326717636085023591,10627251099606495890,5711740284682674751,14130161378460007906],"proof":[[17970726031724212930,18098966392717033744,18329467923396995518,15033918897766573074],[6872717206768702692,11989125647797140964,2137644504125081380,9069676152651109583]]},{"leaf_elements":[10632746266096061438,6757646590349987949,13549814758625843258,704655662152719460,11622797146708305149,15759578015746123756,4397608871267503275,12640380755777952922],"proof":[]}]},{"witness_query":{"leaf_elements":[18393114174695231243,923692761285441356,1199353442486837829,2081521804718309200,9327194683880794442,18347655558072506812,15324165280485757348,16807630066001722735,145971660384558559,13199522062931934389,3479538064309148345,16973426270813467894,14025368693265863282,16255141090929537150,4682711526745062608,13586916961694505142,8648661781694029627,9358866276250312523,997573511660916227,12391460253927499568,11059212370136432988,15591212591622490246,6646940514600535227,15095769391931416787,3603604864377794393,10606915233171259698,16315325268609017300,7930901700524460184,13396761665950640078,4535174001348641021,17793704361479764918,4311170690249426307,12751341943755497185,5245253132346224219,12193872336675475760,4205200972178664439,460299956554797882,8492957551526765159,8156729567854959244,18335249365489311625,16095932298697093713,8661461736405465978,5772808580855298362,9350750850654528735,5712048313307167432,11646964466456875933,10117289444998192621,15531735736855325556,17629208185118912580,12420305742739054806,5166223815211847443,12483178806250014535,1774616854159384922,1800351211574430997,1394379825816181372,16177163233606194400,7365635599320561314,12654414881745344375,8141022402449784165,10620974305975725546,13852643951384887964,3980740257291459569,2909595533006208519,2303498067469767080,8194148975566604763,4154058171555004174,5061348624382188243,4711500206076584343,2105066015449033958,12742654859900479501,12725410837118453582,9329184451375480039,9794034657180018733,3033090453663890732,1170179541844872824,8478142269118023168,8791720676309774598,15993188143675072848,8581812596104186009,6182437159000658254,643929200369827514,1958471923731921193,2504103928795389792,13290048129388623379,18205519159821363672,4384716179442933284,5793882600451297968,7331069278706772652,5074576325720144411,14852545984831003213,8221465321898066223,10064441663339795355,1960192941296074314,10059221018252626319,10634393264446876203,962685992881875932,8172711093953970437,11683450473138217172,10829933010807799170,17136846614977017061,6427823392097360059,8920047688319527251,9084368069170833752,12478868902163781321,10008458944842335990,16955350129488736319,8417766860629374596,14903649934063774312,16020884999958759069,11929139203839226816,8164286943747766747,10966771234722563961,7345754681030884170,12022171187212876355,12494727741742112401,3957361114505706058,11876341226698559463,4978827291956344286,9616382890854941341,10610154538657006512,11926576810945590298,1930766894319224959,11216862818497078126,11998863334380101842,15555346980593709161,6535115634001007801,13298169116903718224,300483483197486419,16639198663831323111,13181322603984462466,14901429913589442806,9182554146353784300,16473084398166389140,1327367769241944705,10595148532694997471,4905791254834478381,14948029417757689971,1276564535778136527,17343951697404101594,7234138637639240879,15790590548735273564,995340934586824242,3480855003119561731,5678771817763599013],"proof":[[1905622313059632371,10430965332472044216,2085522462712207625,2095213078364404818],[10284755316417068552,7382041355763137235,3827203489539622390,5185212249948644450],[14404830452815536629,13539644628159959803,11695714716803946384,10534115806409246754],[13981992382461963876,16947161169662449550,252544115956605205,17535940023497708759],[5124563391304408791,9853215554224204577,985186528874873988,13709050329182146156],[7108479470964299102,17034129417518468944,9269541825447293749,17162233234273977366],[2302514743107299769,15240357231376311904,1309482296578585714,12223579504653041287],[14040798928754748515,1287063704141585386,16615331070582055741,17748278549475829137],[11493948247201593386,7264880948542308075,7775686322422193682,12455796811455610838],[13817198806270243317,8433564414707442631,3044455311206627140,8532632425163670701],[13180575415309808358,3894249156065441455,15010923770791822762,12985760518043936574],[4626779910144343339,9698937344130403250,3442996622861768559,956593083654251658],[11140175665227094444,13629156972520623282,1455704004035922971,789815538715411048],[2599110953492299543,16445433041266899079,15310725646533348689,3752669276386948495],[3190744768793536238,5187551680543924474,12462003973924477240,14938803969108644071],[15009272789597223464,1793747896466623244,4154965185377302103,1318697924097471620],[14710339626193100422,5166397287786674443,12877026722859487242,10407735240586944831]]},"stage_2_query":{"leaf_elements":[10296338320737295194,8118255884523148659,17147716940825153614,13403157187537312914,8681721982626745578,7117549145357255263,3063547213354054270,13274831685797846966,15473558298352118539,17004057659118383044,953193497629250965,9068969023578116543,10643042611971584201,3230169116763823129,13875952377186356188,17357266599051272411,17474423513560146901,5045538408744984678,13950998013247388869,13691140720173929043,4575536792179924297,4226427884089890913,12987641174865209498,7550052825216369812,12072168533837431051,11950402133001192491,6756729356723086893,621653702645103342,3820891804954122719,2904401397723160163,7015915152619871656,7194228830423643879,4406451235387020568,14682516798551649042,18325913249718061451,14094692068459934827,14385285437988216847,5783243085631009864,15243707465336705586,16710317950629146141,9779262089434348359,2416272860413501544,12446033357903027315,3424465653817695598,16347703655494828915,7248958025895311541],"proof":[[9018121735868829529,10709116411340640792,18144250769803355451,10615554216013376362],[5882041654425543595,10587036870578802187,13253749810992502445,16973415919202441432],[11309343261972578504,13579492016200834223,2928271044880487415,2111698670444653906],[14057889428443613810,1285416188117199673,5435887573140071177,1722624632219645938],[904374806673610487,15742558316582578299,11632661673273913073,14336095668692266651],[6829371956400475357,15097893269252701612,17962401498926680968,1270027646845832983],[14915644848886084542,13528870040031882145,17413129710308942556,17159688183538075668],[5869135392878403939,14912832311407118193,1017754708587709610,1529955454650733920],[10169889227458514062,11396039967620281842,1170409026867444321,4320090164152139222],[11121137750290511763,15833256957313706243,337446250360152042,8486635404070851245],[1683904461514100720,10826453685657069995,16394370420186619550,17130347574353831469],[12187824432519143257,17822567161871902104,5886278759673521716,6591192483950609101],[18103835666855579592,8394583156348763902,3215267438534170014,10771623404777911190],[9960593405479888625,8113027595493202359,10427956466321531438,16865727042739732471],[7973967139164471259,7242352344671373559,1700715075142582428,18301175903709491195],[11511868158734641022,13379677230417986929,13834832617723560419,8351544216255033565],[1135997963394111510,13275752990064275231,6348311180324878415,7982923292041772706]]},"quotient_query":{"leaf_elements":[17842531366904862938,3066837529666912393,277378036777115666,18391915433634801276,7142027584667753544,12290082156690123246,13698060198314381058,181022532908560358,6839896265574335776,5863118797823042904,3077177332011323111,7073217002289618774,17332713731511871986,2567829718925010036,17981586416171854937,15785318383780700465],"proof":[[3905731914295762603,1703928819407926508,1408653216465869912,16595928320992777848],[4808428134110241222,578998096538185012,4858564744902997881,9890223566756328485],[8044815956086618571,10208149967773333245,7098734371089593621,15573973623922223368],[12329837534305312223,10289425827285609598,8621693216325538948,5849253527359201128],[7214295545048581940,6912125792979954290,4347801457121571814,9761490401854797378],[7856871468615846143,15175185533841781984,17098573653676137424,12847171824267318568],[3932195901628098878,8392207897203321427,4176554159104387753,13333238128294594496],[8269014362451974543,10478653715261205896,16095051890183733652,589149010850619520],[8629981051605188616,14308994780090858172,9925394781719034236,3984548743947540955],[11261364647001817960,4647707155639003708,82616879809101832,6197862103539726047],[18280223944681522034,442406276797769847,1297509089243516641,7898277128836861993],[13605830753119403593,10272830646938494080,3768687836703215065,1823951007678366293],[15818210036490540771,3873839984626544722,1208620065514682989,6534029958283739922],[1715641539140575462,14007700721554265090,3203330286389002312,9042769257566901468],[6108497889351340802,5398986692742181177,13895256427289640102,466566345596639332],[743715637329255100,10066940987687814209,220670241976254492,3608508566499664047],[12530437638825942509,9467813558315705039,1660881245341910574,6918973135087974952]]},"setup_query":{"leaf_elements":[5166119146133672599,8289969664507888974,12534536815716352420,11594089787092856308,7423981703882260007,14474128176474348564,15068624945583964549,12438811633954729070,14946203652815468801,12446584883333687844,9861606685018168883,9177765463543554018,18185909790897052956,12286616847424882353,6529574576097414470,1261233864648122379,13071588675033073564,3735202147873403933,14861867246159055444,18287197773592864438,15017163092971468505,9375307944094564841,87470820639148871,1188391480207621259,11262497414457683333,14390606582628641057,14228971707467383963,10432513204260344063,14128246490320282161,12491052033154853421,10910251663533035055,6378910831788813269,1570017953161993330,1867971211647438017,16090887015033176952,2932507156890486800,16745259278775002679,15564574850884640459,13263559278693862213,1949114131079010854,13975241752172682179,326155682982216923,4555975231831581676,6036354234874359090,7124157121746830848,8411733132687084095,1354807745773881556,11508153894528284869,18414475885548625460,12078953000012706330,16656369042308150674,14010382311914998501,3441562911474678258,10594565738401768011,1130691326890672784,11430820739622638952,14202448048757733284,8958230452781245775,6363664184333016343,13395049535259109674,16765345651383479561,13841188669502253091,4531623053585530330,12695395521589089652,18202418160772581033,16537888373277921855,87650918094514363,11308258167649155319,1303405774824211657,3128530310778708826,17876205718272444946,11109624486471500822,3122101086783826878,2214641123689105355,8820102342641193857,15498783136533870734,10181876842671002405,9561996030036072855,15147262269389354812,2070473912680807884,11786221194494547249,6860343976573162268,9926535246832169915,9991517292951573557,14968745842141459011,14659618308197165340,3418338821884786080,10280639086329778109,16743082101022203931,9411007509096058358,16412738694327183588,7628499579321511324,817901103805520788,805090081081553279,6188814267922951036,12310743128014777080,17918058579960993457,14131047642861438816,4420452461284571618,8207363063321624646,1172004706421657392,6062632868961575879,10508217090025988478,13364472520738166283,9561849448830040973,1019859493830142764,6365105860259648037,699970082941331783,435112167150505399,15672188348835346049,9711163175564112882,1082293243121574546,2103180811434513157,4491926882231572479,11086316024924292116,7599970837738092735,5452086004840432809,10573869876253848478,5655700105647197117,8714083986373781563,2271518093161991012,11187450673651342603,5937224625129943201,15547280597884341999,7156438004749386782,15085283472230870314,15559037301784862484,6136279196858662335,13609197240577623617,7220307194060663027,1774513490917890309,13352862109889795715,14938536860072072557,13583834756744688014,13297360496016390853,4632018961095644499,16521706826655512831,5558361699078750935,15091770599632801197,6344070519573214911,9262260655954293844,11402099197458844,8122488196219690289,7535491826364509154,17114086673040387089,14240468296206615494,2163332970824957704,15902807365985967887,10806773659135230207,9661909664543723632,7771128416102405008,5271759594455193989,16609552498208139070,3580701632874983018,10601663743396851965,8751042429119329290],"proof":[[4575324482380854712,1194580636532923474,6706509204934071685,5410112772416225039],[2287665451398315334,10959147873087936479,15367883563702261264,13677475076759561763],[18345507973682759295,4350032935755434149,11106482726831358277,6726891703927499222],[4322934879183337127,2465073977764213783,4913266793514459701,15293444475101035723],[3038065487462104997,5358996728653355532,171501526953825974,5338551530359324159],[2653157319542583506,11581993073634423943,77542853542088061,12316883987441468899],[1697337022459028494,9209448917559516848,3094666540974852489,15646626750024694552],[11617264296521893765,9131532117695180832,8260779821707101150,11998098942479754552],[9040275238682642785,14394011869568800078,14888516443969050954,1855411306155360631],[13017035449289506222,1572972920673589751,1057815529645724831,6147598563051023156],[14224543654155460945,14731564876152217188,16366948004530072482,3314694528679955655],[13506846981653211784,9726560081027970539,2498281730565413567,658225364951590765],[980835584230921852,148835529061801740,15686018232727829828,5087176876351774885],[8767721595337212539,16278729301795318642,1461021613127318371,11383014273284099454],[12905882776999238470,10574484417424369917,15012986911913400699,4685670864673593800],[1155622468097280682,5323416548298108832,8022893987892584074,11953756625309878271],[11786672773418549703,2339467107386851422,12140533047963330746,7373381974425188538]]},"fri_queries":[{"leaf_elements":[4910725119096092813,14271788069888211159,16663456642490305721,121164108599677364,8186014406555272648,1192752209698619683,15168900590020322236,8251671721759248546,6124411450478966334,796220898712877574,1480462058054153689,3620363855781964776,16087190627507075706,4857961134565448192,14239603459036068340,4054228400447605882],"proof":[[8480726366521369045,9709366248184775198,1652574936400414472,14960736936402413896],[13362594024305080620,16150340236164404193,6184143539167087398,1321025251253052516],[9361448551653879484,1780240807595584410,13217648919291357648,5305694070279222915],[1046521521419487605,16714986829571431187,9794667897005330640,12505669406496756407],[1458927186121294509,10438579922919282596,13067182002903167099,1008088435436756137],[15860253873425177214,6428724936931389940,18112130241974689488,14773083941138275710],[15370824723190406874,8459338629237266265,16138796837953216147,17578298414914733112],[2362407080558775715,15293870165392898804,9840008119198566225,6858309699267301259],[17905232536085135756,14523991317510140686,18103499824242537153,18175907867237639952],[17482551630676725888,6860419367274710731,12647313350925461503,11045950389642874913],[13358613261555114715,10411274019882998102,4461738657058286723,4991096931689027227],[15267790849070639342,6466212133871265129,4581505514599380446,10610508530949688217],[9910303583025534766,1414356923107848953,13001764951355095740,3311228748280393472],[2065112813907786203,6898755846797313237,17320045911186699311,10677055216998779661]]},{"leaf_elements":[819560340094883517,15625921308402870464,17290824021189317334,11259119723820164213,16705758274236702801,11981161140190082654,11785274494583277138,18417187253937272252,779678456319483401,2995067812335704612,11755251460307782783,5295857814815975486,18120933264883767257,8349022338496789249,14376031797074791765,3730895539536725451],"proof":[[4750929973213897274,5428233762458186657,10305446683362267189,6882108185876543308],[9211075893690261667,18373327137286202638,6271159398719668093,3848607124247722367],[2217083485369737648,1838677217490870319,15741375644168778661,15957700649355950139],[2827806959276756461,10222950473115209792,5681658749785265824,6150481134844712859],[6148176129495143345,8690396302772415778,9981280209203646458,2356653661140762223],[16373645715608567167,6705591111741220056,14878806484828317120,2373924419377395242],[960957800208868041,7925598567382229540,10161168106136753895,400823979631954644],[9733887757658192713,6768675164008008308,17201532427793889158,13093464504717849431],[12309313557163945685,13438460833138649064,1362127772746089769,6791297938156535339],[15586760640357510652,17199437880074354068,8452752432785340667,2190745931362611588],[6068200341678021668,17238405178273883915,16254243979175388415,6326469122072930844]]},{"leaf_elements":[12990701718064396205,9125273541512958946,5312854553349010798,16913391832353501736,7697084894203355706,5217510093265450042,10948579825756594224,14742965314771584901,8851805531066417085,17854574191172564757,2135340757848680198,14075817739262577741,10092143246392092373,11764046291472901137,16388741182769166932,17676631991864001358],"proof":[[1724279091421490634,14375303229738382485,229430311685066168,627078832307716961],[15990108351986265431,14199231478796433618,10715916661769450051,2921614007049954189],[17530258872685519779,1397971060595243633,7764569963517986340,2148278909536159856],[10254766985847880634,3535007550311437625,6500057094020377968,2367492442890125911],[4037202797787696282,1693057410348181795,5551088463183606843,8211320577655265337],[15240139933297949284,1462587790837629184,17966711357235993021,3407100832053152973],[383955214807640705,16818216626337424042,13232217085098681904,241005896151116121],[6284005312668722525,13175024327537991261,5546811104920909949,2703000136490581107]]},{"leaf_elements":[8336314448630638967,12501907102837562160,7426866939920300960,6731436815826883563,2682441800241751469,15578326231554591730,11831314687136323102,604896766367345365,17511101279346859112,11106880812283781505,954139587609810958,4591215041420580062,5875580583845308100,8658526377715167511,8792429836804270322,6724208841689475303],"proof":[[18270658805018744257,18037512519851044521,12097089816301657566,8906949678530437644],[6517220859100365477,11012649566548009520,1344252813115912406,1669752903032142566],[5564564252235922998,12681884071870719668,17256616812607015190,2076042361274142078],[700619608235653952,12943330703004030898,2480455716292619428,8323977305965432970],[17991506096714915795,4636722536725601757,13865614444769694335,8815772354958363399]]},{"leaf_elements":[10709399384505901433,8410325356231090929,15561720818054825268,14595136295749910987,3096112296966750560,3421660690568712333,3091144484682138335,18310247230512460785,9482461499428884128,589864126313932898,16665152423982453751,5925405038121600556,17725199030289479468,1096803743263879443,146129809745760679,5540267174767141550],"proof":[[17994419247383461759,8679941398660402734,3461954500207538403,10904733956278157357],[10835623355140351544,2411159751067968680,17855867681805886030,86569936236411870]]},{"leaf_elements":[13912788208633012260,16592364955197622110,12930883254427910878,5599575569218380943,5682660096836901399,4069773254031359724,17686759155637027087,11829746095036037227],"proof":[]}]},{"witness_query":{"leaf_elements":[12813148654010451483,286362382674337914,2814474863990018101,15347220285916967026,15883466270792828269,16551587943686274141,10342735151317968681,2267903398204999665,769930879777694564,5650423620746018493,7275659284151474732,11924398606799627882,16582269259231633091,16412451228026775148,7459518721674661490,4212893267526190282,14646915982440028646,11554978841740143364,10806346919184079422,9451905244116457139,3187007398506063694,238819287354439440,2565329882104299096,14996729050856364178,7850863029288344138,16798294019325482822,2655107421426029354,7298035208829467973,12911969005447348920,4891385032024718711,17720120323157773348,16961438092602204652,17646768572121820355,6668298346835199475,17075355817712972976,5764304259691367679,4768699818523421866,11091659195503080736,9393230280490219989,18017671269641776793,15269653553031888289,12250169323808832767,3242144544204372456,3776825586298741964,1752738832384914962,8030046001489331310,16582011057218507401,11788386535325462497,6443787445720403766,18334487859857822041,15199532292009992870,13883727120978263644,4497262362557304294,8310996496270279589,17152734317419010577,13408011386333597240,11793597509828940037,5362063965221831853,507748552543614885,15104219723821792972,6175307098142114606,10648647576286298864,17550164598519644041,3181833813358131362,11478964020769797190,9340507646314364910,6542020370780818820,209606456076515033,3079358670429091322,2203829758702480190,9980016276799956839,17726425668915838759,11843765732215010802,10213354953589992441,11153721382809457970,14336928462748305728,1962175685077121736,5296629453810155906,1090531147821642338,16063187007846262632,12568943344642028888,2413007035478274726,15560077215780587393,180222632350853077,3243619574583324298,788431486190384205,11433091029311692857,1911134950939113873,10165284603397263199,16468989938639357164,12534335137081421011,13706948400336571483,8908563926818729606,4631160796812928503,16853824859970201941,9539228363881054568,13660195446505913860,2978433519235104199,16709772508310938752,3492684497018784746,5288773485181206679,15046175452997271958,11604815662304484806,9684599373016496613,9175889693910283109,8099755443919742799,4093853848991584190,1394950735630085481,6396054377023118239,4995596378250927680,4639870983831052075,2900761642238015734,11318756666725520217,13741905569300787573,17622179639328220499,9346895212256408533,3165420591211232497,12301673465562659462,16581261412449515615,4469719632823465578,15802209254840744988,7192518615138702617,5393064178886240477,9765290204727813976,8951287840786835894,578114797291654302,14797266192997323909,5136785092184873651,775096644556970084,12175824106185944882,6912289140026517834,12664944893615757971,16113842196606976163,8330676713330334778,10164144711953180776,4824890593336652292,3550500502474367306,1349664085934440291,4340795199920555901,16101049140664942230,16519177825784408869,9374783367636958624,2794997282443712669,8262882958084605091],"proof":[[14966400817746611434,522622981339705416,14442404850488942811,9540029049725077787],[7724661192158990617,12753035754759512897,12906387351356575254,10281485566375912457],[14657546089267453985,12554833070700907482,12506624547187240734,15763341737589754149],[3778690876372723226,15320983376398240520,9890780911053895013,8512294935615378177],[2811331510013791599,6347664315968048394,9435613188735737117,12616161553966138373],[18421739366840900552,2563772942457183823,3328979479724394666,1941233965143337810],[1456795938916541448,5595991386411753324,17775907174223775848,6044367597672782533],[6151761865228269062,6931854719912652430,17040839864686505108,9669027511945635022],[4657439081778797571,17049609391750947971,12837271303497083744,5327392206585303019],[10765791006783448984,86574817623661470,9515010530852948539,12453408229001572336],[13172372243874722897,1129613057516897112,11355148437370212500,11794997384313570599],[13983668825928715342,13935786314907982796,12041344031718939949,17140650127710913640],[16951585816998125180,15629203953376818711,18016519220657293729,13530536533506452721],[71800669901457375,5534913327462865305,11403778414113451477,4475648615806325985],[14382599008489442030,7515019674278969732,1219720309068316843,3690953608682207385],[12501434380289524413,15834598559144601317,10778040236433503731,16209251581256996478],[11492603375086044906,12889659685821786976,12763639147647709194,7612402080902807848]]},"stage_2_query":{"leaf_elements":[4027828974084283102,7898330349995578782,6073599769449612998,13628373632806894826,849138620009235289,13372604764015144658,7223819527172472703,789763175857474801,15360700370828054461,17864972447757406728,18278372010426653903,4631924031687343459,14549295575915347038,10589938467941883148,1284568490455369087,16291471742056659025,1252317146055295410,4336394619676178054,4804322007558465354,11460009079918802589,12167800982591293759,3428040170074933940,2972679271150378654,12473704341977454753,6851984894787257891,6879983726754316753,7526099601126910282,16818301308867392153,14309487205969381977,14228322485543492208,14328681026050230979,9083525725739008140,2037102785639016885,6548383285882217689,2718178253781125253,17982004445107552569,1991213244271384384,1802351239391840848,16932935846559202190,11159259522396508647,17271141161771702161,2546750902292464347,13341408611119995942,7004100479428861450,16144905378655410447,13045658273679186353],"proof":[[13888096840552075036,5000143572242103164,2397354732118989722,15586498441171256766],[12449058145334902725,8517135336402602478,5098917691863568548,4965462675526180547],[17116393910976445799,4927741911230108377,10859570596298907286,13428220702534358038],[13883207079541976553,903830730594871049,261869409007882214,12672539424800882646],[13897325614405175300,1224077933613921547,511550541909757877,7560891563821932295],[8316362694539649480,11973005756594465833,18214591474873112098,6176198665066403718],[15170758767939122579,5180813021515901336,14356101945681634783,13422201295915123042],[10715947891599192244,14158218417759494825,17415850841145772440,531201420010260866],[10589625268657000049,4370084523576028989,6613744136663175408,925560995334677508],[16189633368016307561,10036191918439785991,15344791975982131198,674009074753553470],[2989770829179832708,1646084659435357961,6921509041611206983,2589410767710354888],[13882396818042726023,3200228976925340405,6956728661487355935,4722578331516436060],[9948118979767857600,10640902076967682226,16929649351519955770,15744297710545703191],[4906138932829079932,15874327502585336943,12820590262298752536,4892376643216155891],[8851468390249716854,12136634283717416728,17954055740264603461,3858769662819327071],[829065432957179500,6000891358471194846,2286365648976107359,13267591513881651515],[7201919828557878623,18075308308153530416,7707424879695993339,17576654716129844431]]},"quotient_query":{"leaf_elements":[11268114008724919644,4537550648826425036,125506571456509531,1749741358032370726,3887456348495441682,15838809918455948053,790419789924501237,12748599616954513731,12572198125673505018,4571962153598621247,4308868402198109126,17786582845172548583,13778715487882241725,8295654249036351918,17993568457231870150,8032507139565747229],"proof":[[15177246904430310071,3161240175559792749,8937328445847727795,12135675160751138397],[15810426891015994494,8363120693578271242,7575433885322260084,18426524413269569047],[1251941343555600121,10635279458562469570,17991112683604864872,10425323945451857816],[14732068291583492649,12387951046741162498,569742832475451048,7151054334028785745],[12257078060747365069,9392146808447985274,11688196883246178414,422787198725278146],[10945021106819152337,6577248268347165945,6298471285731995664,12493160296408903627],[5513798756250765585,16845264744196431094,9074576651121953324,12365394283923753888],[6499074688293981174,8362938740537624967,16398533862811607967,14312942705167371480],[967576571288156335,15494864051376728499,11770015838500451424,8417560864450801195],[16471243184074167840,17749177624857098826,12803153324748142995,7231780396380970971],[16307987297871575797,7013804047130485930,16517406602617004214,861387695881314036],[4887600425860233983,4810583565542878368,8523232069461057210,8916620184139489102],[8276857097286186211,8724891900512661627,14512923604556337414,14992541670848199727],[10301769106401968726,5359009653098251425,9924963337891577465,11320539965018442372],[5067128947483746008,11479597664347576069,4940501934805440191,2703228334358431978],[895434351308107697,10579659998531182317,4539328167759638957,4918587761299476539],[15219974090202041036,10355475081129221990,14003088272047570913,13426480185855385482]]},"setup_query":{"leaf_elements":[3736591297062829976,4281936876848742692,8144871370790337493,15300273396949728762,14499731422938764958,2325351277293277303,10444653829810009457,5495954186239408346,13781216302470724380,3670520099078593439,17077126937261972592,14548380340827263778,10959474884494090446,2900659133351259927,15633079676677040396,4692972249641088061,8157594703693237237,3394337948538682076,732067778279945136,4884147369361871914,6901230462799054990,16756439765180612931,8013094948675886234,5555917495103346102,1104507352496372500,3597377104774951840,1380693034360585491,16643331613273533270,15405577114854357174,12477979228327232958,15287972778670671222,7586461377113715055,10754254355048826342,9538017922694430801,13620109363633157796,15257024652807781745,12743909129886337021,16242398665930480215,8770544444853760372,281507374083253964,6931925435542828576,1468447756529051884,849472194526381872,15525627820544894795,14720461456714435594,8636238233913724026,8952268289957815339,6487712398057660873,18042303730250737480,415450383772800660,3565836587885044589,12557724925337401189,8272398216720777539,17527899568330381971,6948712528757228023,103356439861086367,17670971246772749330,2099477711056749431,11432782502076066349,15729751751596047498,17089956173186394246,16619243656468289662,7126927608494386710,13674641056571985747,1335191844594577318,15996464993543049901,12567584328727720594,6906218007256184336,8785523861706714056,16352096930041210889,18213633419101122218,14575299000324908115,1549775012046061585,1916150639677484107,11367459048698198747,15305838458068530556,14133759933894657211,17425876469586709539,9295506751769551754,8616130815716032347,16992546667185987712,15797146449240350439,15087017792574200180,4303420175451177820,7165302130623462625,11988155180856182537,12320297281181908808,8058033222593351199,16330344512928975215,8880046787900345447,13955320573771134889,12862664163712571535,9768705599509398773,18280203079187687325,3183593459359957822,11482986556157036190,6382403817356481206,17215863525615618094,11424891569314981105,4027564385237373863,9861651668311967789,14812328691325005419,14751342636872195422,8928886976627418263,17726422368437289746,8363124244859645145,14870763835934169956,14576608998112311327,12783714464472296967,521451490011214504,2613866298319191978,11442560548342770330,4118457578455972943,17953189357536517849,13077816101523010106,18436675944124956613,10749498159261142381,2473461159616636003,5256555833052705622,1877529768725843196,15597158540629348436,4325335036441994934,11513185106680639376,13415695372098742969,370221227398055947,333202018452768327,1941815801471056296,705573288038175943,14030066677666051171,6499001181644092654,1179585473261667934,17061857088571895542,1821858364427169335,5961218848680450614,984628445314971264,13348004665207756153,15758217345001282668,7867849603341544085,713924720999605294,2995357411946693617,11392583007811034376,7453652194287512880,10492081110082010265,4102925682987009611,15761879788231935550,7833255255009766452,9194865119161572985,1290495980515413579,15186248314970019252,8173527751820947792,4418843450766017766,13808722795168769018,4421044245243616059,14419957343923195659,16836660478570861422,16352595235945241371],"proof":[[12328877622657366097,2895134587554494197,11734101109925447125,6766772120611988956],[7527947936113627057,12475379296000377172,619161972206176645,10152875392267429803],[2102028400030354276,17869991174546513083,12760871897471826965,11037364219549209368],[7015809302911331743,14236189361733283458,1621518090846836727,15347698389478755722],[6411509318429428393,7199739104786390898,7282817259681940352,6148020393362625409],[3412918786936463780,6312045812515333369,13975146876923945595,1631023504226020828],[15996156703750359764,5650339779559835859,6339614451019589228,9565462521861649505],[8550378461754474669,6835006665043205454,10839113237898355061,9876579643652053670],[10312639247018273018,3718772840101265581,14775817064583405334,8212477289586090721],[15451585878285211514,3548875162566892908,15839671865025490325,13936378635436548977],[995948163709942319,3968315863282934871,16315259346331707279,17731298937643701072],[16087068376127199237,7420060422356269621,3680324285971123301,6606455036569627971],[9745546646373378817,5367222369237133798,6914163643288206864,8073375872156046076],[14323173664950735639,10426244635860938392,13556860138247746886,17603233129383346610],[9787470766648099616,8741233848632978724,50331670771518888,13249547556916395400],[1832359183755906372,478848257101307051,17709123270266000116,8454173216194720377],[2825337570834942701,1347676540585739012,3552235004407085711,1060583059816643653]]},"fri_queries":[{"leaf_elements":[2486146003312649007,16065777049364233005,4548550864983065710,15960192959880115119,17934035518907873167,11200728162820731197,12277440370406389582,16597246336516524139,12057592572420452066,18137850675930292435,15294719580423340287,9814321238887767329,18158188010085565184,14832167720476846001,12311298360618321860,16140395593980539910],"proof":[[14582729445713308081,18023741762541975356,386397994544646427,9182371754655962005],[6718233191628876395,16692781029735771025,8127327481567676335,4733009950560619984],[10684133144235428755,5406701155788670661,6039193800397219254,8645180525734403219],[8839224242901402396,12198678532843592683,12409681663040669624,15851288959496618336],[18058153137208317622,7641673226760462352,13378420764312772369,10551321979674320275],[16412580056847256547,11022317890684845660,7721765449628121300,3987759522175339328],[3051182153693577021,1732307882216162727,16277797269838791656,14451637378821457089],[4927087176097958284,14676121035438425320,429018682838821929,6109061947728494107],[6475683838559256320,4646873118759917891,7665123206959070975,18177576424988508615],[8067574413427000556,5295111217854638739,11705189734098995829,8231269141572965021],[18245988174458935630,15567189106049843416,889752884828743410,8409103115457668320],[6735586844435078875,8579791375066474498,3024573940078134147,15145341117179858328],[2075575888495109935,14826032821986342854,13043476262639831219,5503614509639437556],[2955499177815998310,17670437591182936880,562230480527952728,6479201791096082069]]},{"leaf_elements":[6734032287685746377,14473485091687688618,10872195780801730226,15572051715826708398,576091370516636243,8357216203973379982,14311018323570207336,16479840348095448068,17535714030702757431,5760574979995960674,15436715195276849849,4032519758932045461,18348908858437928077,10020181362417083565,16674878677857798729,14655114091297957107],"proof":[[4069831677312874892,6482516435714953170,16586822947269934655,15721034354352775552],[4922780155343536105,8642755299033790044,1571318000833994797,1624790841562057473],[10051083263176755805,5351019087678802379,11814153480413127248,1972508194101150178],[754320728196881270,12376738312103376815,17124265818734598844,6191174066945636360],[14599250031767630157,14695644951419667136,18189143601202596274,1234104787205992033],[14813365796526422309,7250457600457929862,13262961221750996207,9264267911700020561],[17146624261382801680,16032520511998629900,17892468416436541213,13542473916159872849],[6734279193109334099,4344115223091470528,17414970147092835765,4685037215386961640],[15435384154565875491,7443260919263928210,18263625449695726932,15477863560200891661],[4886186777146325567,18021849030663188427,16962870464187756074,8000864275442546488],[2065914019466681039,9751093087361631796,1041788443461241707,15886007464689788957]]},{"leaf_elements":[16603298125161912807,6759672311870037409,5457574899040436589,8534537698231920841,18069524889524268463,11806801145941009659,9576401536554104849,740364091443514553,15145000987745723815,6580096938962744824,6768775984321950750,13686234144488043150,2035474610263264970,290053883045591772,9311689290662745385,10883663535595228069],"proof":[[6985546507407598251,1618506176917176432,137911702894673129,15347804783899645584],[1697232978980356036,16088500411255818981,14067157882851521985,17697326221892938312],[6513251074757084718,12235263390256429002,9039027465488757987,2544524107738441295],[6704910906495305797,5537552802321342434,17050478959747462307,15781532375090222567],[11274019841409549940,6865990949925828773,9384892456996439998,12219286995936386530],[13657930101507524724,16306701525501077277,4500520271016090240,9622824569097031121],[12925576717230592371,14128923248834914992,4251405656937247208,8454846902498067334],[9337493231350890712,6135849217265235357,3602169715072990934,2155286987634949783]]},{"leaf_elements":[8028746647513535337,12141820831578513697,6802215169372740339,14070081398248574407,12961434475110896314,814470655965836887,10122756849315571022,17210605020379394410,708039466677040570,2954628787604657876,15668021445009815475,11083213823098611104,13993542854576954285,9967641015376945817,9404322345931232778,5909559720809862234],"proof":[[9530461554081235654,9291215933040912620,15848386459056055301,10779360220052116316],[965682175435047918,8771198937868337508,6892195808801095766,11497608787345202308],[16995459805685517926,7865545328262611099,13201704181062898966,4196451855870247240],[16686500822935332902,9436103090645439744,9674689513333575711,4084637182715845406],[17767512737782668149,7056691306617396764,16344617099772662451,8528842919536213672]]},{"leaf_elements":[16536059362089900462,11268140529269111989,9460098320762629874,9830945258861761270,6288656409479024023,13924384278244023541,15169509868311569220,15654511477145531389,14028228291525785178,15085293467702255741,879070397201127375,11011827327796012696,4134146360567690974,14125562988571942952,2015371210282404664,1741297488956726505],"proof":[[1105159788271115204,3777640860133329440,11458073058188089014,4971944028264465656],[2707402844557173430,4658636768790482534,5298647501566847874,2652057082738657760]]},{"leaf_elements":[2090332255920191090,15383793183514205018,16796842030129987924,5156234286113161623,11959741824313716934,16079524884866373675,9779476225871497989,15653106700864869981],"proof":[]}]},{"witness_query":{"leaf_elements":[5701027775835229690,14408424390980045707,10345653370780720303,14141109631018195830,5406421070884189767,16650702027314746751,16886371612454746152,2169472890029026303,9667980372648489010,2525650397181053304,5993914430762999841,13669844566783201812,10292119680990672980,15544604423926101096,17022003378736764345,2065099279147023248,12631417972500811090,10232548116623183566,6394920562237892748,11570124224712960012,8712707046728210841,9332931670987444236,358737233921395592,16541115062047482171,261173422133864097,12674290430197102220,12437552012496175376,9061740139561639732,17283321802442800665,12455574268877584349,5432262964935971127,9109684113877931689,2623285610648769496,1481932584340761239,4402861193189682725,1790273435796291583,6516480957123904325,17681376205716090704,5396943611683971602,7782651644254178286,2479327532092500234,621640576531350328,17543773890920588088,11808231609669414435,10400010707517595232,2650653963466824312,11130611987338698076,2158786688639833966,10725194942973698685,6782603746123439783,7568142012372382110,16012782676449569757,14091170245359222454,9596993547028642852,2482228786571299589,16056953821600209900,17561622839941633305,13583320876692909296,1002743738107559759,12386290371835319333,6528989313742578659,10463203906990885589,10052576520617176262,16340081338944284199,8334747236526481222,12416049180246664602,14826464935477462531,18059989372841323982,7590906081388144351,16430608690141897702,14506313965418719152,8445480902144572850,3774061037830375126,4606079003254754927,18241909628056200000,3379490940140739580,1876077776629334592,8909608730147217178,8062222502926057514,9353514553102248398,13264027093318685223,14431166838976144831,15320642180529966502,3011479659864927433,5272254839035153977,17936491101658955977,16129453849971646149,13595304592271689158,4129016299576503108,8277189618044333564,12859890281351576491,8280457811486406556,2255105207428257061,7528201850769507695,13781327574833334189,5312859528634259951,7683208772710258569,5068813280266287608,17850362619293584885,1984635275983889686,1269125870457754205,7569804292144923403,9420276854395231506,18303256849802634032,16916485026814808975,80324780232305606,13314392244366415283,17574584797887169725,2786518755543283087,13085778008301931537,11149982993742042552,5586165675731639605,8900167759017278405,14429515953021738626,7710946784537960685,1281139966728396372,12918482801783801567,5270110798366595576,1820925619899144144,4077734485383589683,8069770591600337203,565162839350481740,13914441808043882211,2487795340046912137,1440513477544067938,8765089600539174720,15742041029897950138,10299879471044430117,15269723907100809749,10881354740479746441,17888848845715960248,6822168493321460275,12412179517869062781,3783210607004452281,3360826043883505671,12364345447657388679,9472384549231013802,4743244932384973481,8953693499899770778,13465707235859092760,258746651907082467,8957567521143784827,2526912280751511497,15592910896271256514],"proof":[[16635561623986359317,16810573457491033807,15112454361565839359,13441447626271452809],[15287191383631815991,16031901522365473236,2243271391712343489,276060373669139675],[14575999880898553589,3074450788337737103,8611962481726309104,13936215769960916033],[10880223763895225092,4203695811061650489,9543371579956138566,9728140838550465246],[3248299381264706208,16604267686165188135,5326830954133837614,11380445121414550168],[15820146039006279729,1013489044290374476,13158472446574530536,18270787799407658434],[2979387768635390766,7555690384164659023,16702861375575338874,8886364793869643883],[12645626599560490521,15704109337778624480,17331733601401645051,6329807864760358802],[9198428506652240634,371053527165631570,16821860758995183586,11643355068310718372],[16038450919731027343,5512738451434460611,12495305845606709370,6116095651579637379],[9678270577650157416,15728830839091800134,1677408464584527725,10500453446307933872],[2063889294138215411,1492988686938961331,4568898611042585480,18037375878962675462],[2333155183653402953,8034043509697465599,783162182192269370,15555589359920530557],[346450128217157807,18312650961011146505,5676191016913004795,10473261726870479704],[16257320324116150610,6945341700375420554,9402323925439320188,8543682351195565127],[8786901246570694531,15598711582937709331,4992846818896369210,8099614993110636723],[419767960013473002,17109390475800629470,8639988902087429244,4890066993498588476]]},"stage_2_query":{"leaf_elements":[16592977814339544410,622203610544476913,6222687811443152966,6545566725056879112,4842998335155748888,18409583785866887850,3826374139979961976,11236291254113150042,16358053707163397614,14645010563882649742,3366224661109667698,15565438347134891390,13252817377781433205,5064307283466981612,13897646792542746511,7584516454421011938,12407134651670610501,5740145818766297730,8736272050479597993,6749581766696348875,328618403885805392,10006676943791280378,3429559224638887781,3954076755680067453,2493002644753109127,6508231439971676868,1614307287265472115,6411677986299960479,15728012516856112412,11602191057214306675,10770981208056290392,10104695812929174770,16686294010778295814,7180044933223382650,5998397856181777546,10492772936127146889,15492936130049050270,14905936949477404410,5175007109771591923,12619933563885713327,4051306297303325396,8656732691020085887,3795107352614286640,6595156584892527983,11677507308656930388,1714789857034938382],"proof":[[2522553063054589242,4875468286934703651,18375157976594288397,8423174867126896515],[13941910632297081968,9367062315820829013,14045709188025450243,15945843651592340374],[9825551481945649261,10965939596507332340,11827124440848407743,9137095429784364542],[2852073712087334806,18929690662376024,17463312768426663043,8060615894215045573],[14062515530685992066,3142144634166794439,12873171305594854781,49769894564852058],[2277295098843854762,13596238769666433357,4414471272612042077,951771498731733726],[4773898680729862945,7686950490654554483,2785467126673722962,14429568572217612873],[12733763384040675632,1180726448224209134,13615524540784469608,2055916683439923916],[2531438823776937806,17688939234587726152,6645875667748926967,14500282142306531405],[4144218846148935379,10696513751727779056,13134189570435645784,11696941637609632743],[18094243669243594751,2915945880793146132,9013530616516926673,11486199422933943395],[13807357595590829381,18342321748227219697,13048295947629073336,1913378358635855474],[12160588534330472642,3633651050337716510,17774181356204551580,16683626658786939425],[11478389967580257838,2831408474834176652,4243162703411174044,2095497841098650498],[8264982490678058401,10649239398597653012,11069664977127002234,17658997670510276545],[12465951976243032693,4386310198827030044,7866660897260785622,1350223188699163989],[10158124209984741994,16226656038178008969,3741652179974482416,6264112555369881348]]},"quotient_query":{"leaf_elements":[14318641269443899364,2891433980685653704,14679405261843666589,5604203151132610663,7189698520042572257,3420172317463396968,16889663664113259186,9577522149099298725,4519040390196966174,812159724612245640,12988763257623525817,5913810002243503671,7037859832215241383,12786053734367097124,1710374518670520705,6866798760966258086],"proof":[[4248938678300772281,6931651470838000493,12569531800165965537,186319524620586901],[16067788383247661022,16250416270002919072,4942592343269780055,10234447263591642680],[15410695960420720917,11199616245855816401,8832990030863798088,6431224010396136322],[12466038786459630679,17238443444265350017,3609394320212718962,9182833574521269972],[7071591731804322927,7665453884076730458,4780010946908858337,17650396105330411954],[12428512260523021093,10342832741565288332,14908989199118229645,5949487833641185472],[5932818623968321085,17723463411280087738,609782268033075502,6570899035277933523],[15229056258245728956,18039641358100415155,15552692092854491435,1978098352909262951],[13034118961656947605,14390432583099821858,3324366837717264118,4546710450754484827],[6849693293367674396,6763487187741090904,2556220886617990847,18038988575870111682],[7749364276044312926,17763059968620705538,5459509206077238939,9106697668857289419],[3742714668796062982,8262191599289446085,2336048687299940887,4666334493163969321],[3659414326365237019,1719804269259574123,15507619285435657266,14621285006798059654],[17655479697151266798,8762197659732873633,14328679798349629044,12034751739786016464],[975387548431011769,10318386252705852828,3234715058801663915,1854655107545641237],[4159297563346906859,16490019495456799181,9748690350163725367,15624755122646525026],[16409500404073121066,8990193684458285948,13212415193707522779,16227876625108158804]]},"setup_query":{"leaf_elements":[906319040847531116,1331691596948756660,9905115247744599867,17884198009012548072,16257704813119336722,6921602112054005304,2823148882866022912,4654864693332480845,804383396386921970,10976225974519748346,6045227248644880845,4590157470591145742,2993388014958624259,15518158250604413529,16336272459507245593,7405861529143311052,4471456713495683198,17419473971933150928,5392886596310766119,18386343354350851297,13284615513740032044,17343177128751472112,4329484019587813737,2643434080802029937,11546710998740725094,9135939076399463992,11344153254615745466,6005430840870950508,15972191436047067580,17444956499955993724,13232609336740364502,3875785065691309416,11540847655946598399,6378666423784100108,2962503350076821759,4071548700971943853,5272575762106103766,85501398845034967,15117163481375957422,4079090882197461180,4187483461477582130,14667293529823413589,14371495120778006669,4712407877391297140,12143025747677741256,16614238686493854688,3035334014224317521,4961297189863725977,7458661980504079221,5892833292136638502,16729547202262978507,5715470397681921919,17503181380080361545,7500146135145569361,13392534581957711652,369157063189027172,10915999005242851008,12251775419834312101,12667028924624627161,58923417133194378,6280800985558112363,3943483640335318009,4540054197548837455,11975988875317500902,6439688880178300495,8435362901660224777,15368704538864552930,15116350086781189387,4063004806131542777,777112228397319390,1598840126383510670,7383238416649065931,11464304999362634274,2726086177305720399,5040505641182631671,11341546209153222574,1517088284633726965,10636102048004974418,16942304218780780981,1665869166120195198,4980112981669788724,10652303192534165802,7796088417338565685,8166995779667778369,7822956073266455498,13992863813802341607,13235412828173237235,6375570965637891269,18328843243732640687,4252282630064172365,8727462575687158807,14597845487980778396,2867821618289813302,7693984073956432012,1138396336733141884,2028260493028215583,4035306970535353224,6309080831459719806,7959848335578949806,3783693105924857043,3194403872643846297,286350757776205246,14376173926831652532,15956940440080359432,12014990833270155041,18406802581978272841,2004349016447104193,10964638451603142519,12349749992203509362,9209756217386218322,1640845855517332966,9946343893191303292,11825500206596589421,12013743864587406956,3536518732398746731,8735274862594616030,5660939232066539346,15460148593279544542,2085834858238544959,16308929526539636379,14642977684768427798,15215897129328426093,8473469093606480533,7129391353208443039,1250064512095746411,5001983499762846191,1187303095477010071,10264475578919478902,2889465390246492933,9506549468589722803,12922119737340633184,13657620912666737592,172092792919301708,15881203538685445668,4709667677688473488,3959444137026593575,10760631830099498653,17710168731241625022,12271323494726264935,15315424070210271785,13386911375094488712,1506964112617503313,6496755419273120301,5695681801182763317,7424225363095147704,6837335822255839822,1668757413090508421,11302448544791479240,3486990979168196666,8096052062659990752,5353862614132859030,2459944753312771969,16651491925085310360,11590069542231186516,15211528688326473929,6507516131417228348],"proof":[[17228115977368048539,11689893239047783080,16514394570036106076,16130476728650897573],[12294501590794004228,474730935400845265,10079036390213586285,7764795275858685845],[10627688053441810324,7412256972144462841,17954201443133038577,6348484322843101803],[20504418816996368,14856778080339667939,5963695319452591380,13876610040956457263],[14116236516613709149,14223582924676300292,5543640925876332903,16663194513318512539],[7268895623523458052,9496985724417337166,17143205921154350709,16944356730999788339],[13695610229410067879,992411891089597344,9108470385578842177,15025153367755605993],[6702281043064842775,1468710224760891708,14412883418147062566,15915520704868050699],[7308407070721549707,3400015526229507223,18014411154430966155,3868076394811163385],[4679276104725650521,14484586606428107822,6517659338793748747,12015436203808425502],[11105285452776061029,4653405558605714899,7400541271622979595,2579598042634822478],[1879115522764207194,247458287265014905,14556651715530580241,4011246398482196765],[11309417269451381678,6359970192836739449,1592430952845860144,11116994983750301309],[15623215950663286638,3285071836597830671,6752977376428239686,13504384612690036751],[3313420749761857630,10815538770176282206,6799215186058998891,16369143375419228790],[9281632986786761885,9146411332782682248,16978034826954748835,15095079311044548212],[15592707957572156924,650278155476359726,14530324207485211744,6911883192800032837]]},"fri_queries":[{"leaf_elements":[15362238765668874435,3614164348729079425,12664400644744295982,2690279252154177650,4523850046475713313,17411992874295901457,6083950797981703749,15563953055290813876,4487416646525891437,9844606846766076792,14915873932531195372,3697692392796464698,1631377045473183900,9404765487804713192,148125214160102127,1963509014766435283],"proof":[[10545099433854878134,39282639442224017,15149851012466017240,11517862097035724828],[7460351140512726331,15661854024423295215,2799337419834738438,11128368189467649331],[4981652146023875337,11018646514006721057,9174132996209954630,3654515605173487605],[13351363859927122031,10284098819846854506,16916915020970364980,8066440630085397453],[14682924423853570286,18370692118088950261,2764024950509807514,9065847104456171710],[16500731582306055878,15568702509241952091,15082252020689501481,5254549928193408683],[4697661727279616674,439324335959661639,8875942399478130631,6352082221541730235],[7433803972093963682,13655010321684726028,11799112896266672514,465708770384409374],[16619407359205778520,6815744010186380608,1602045332001484516,2894114638316039862],[11871565977200887506,9839453382185236639,14977430288433133193,17795921268692573350],[13433259505915811474,9540827336517940360,6951470684300042480,7270021791058598931],[16341408397365963002,8355189924531542444,3938657569500803190,7937296726528771550],[751437110598892241,10250513168281559344,9449015892331475448,3695676248170991360],[13073144155723704124,9967600106886379736,17430651840016265214,9638113403856335645]]},{"leaf_elements":[17697509193425045066,8637078335873147246,12954542995635764334,1060386870893277142,15367344922846200384,4712759188815338416,9973886597462021819,18316806801369775941,7987790732297800034,16865079208870252304,9019438374311007358,13707949445860743367,9319393384062080823,8224723974863302994,9091583599936249963,8656456898138752216],"proof":[[1522569163362647714,528083925910713594,9071443839497685018,5822011720546211721],[7087620628842892793,4717058012415558021,1101444320046062445,13883364065803423511],[11189996557452297006,1439721598660375026,11895555033205349530,3405041638940787875],[8320633816810524406,5908424350092941188,3560981123084395694,15333518164189661241],[17956338131323462558,16168686131940357023,6220891046422973342,11704509120570544116],[13314054291393584132,14506035216106416211,10833038775625479775,27514243533220818],[5753307581863078016,10836410666121731526,3456811966862831651,17093629634376766287],[15546935828421184006,9217383358111772203,10332902575936136227,3394945055847536619],[3540304782728062053,18378170606166961981,14046722917662923075,1420350128684460909],[6838244010446104895,4210511214853097525,15652804428844226486,13364425758308560358],[414118011033434084,55175342163203851,6612543516590770018,6162635671036924521]]},{"leaf_elements":[1680166965361460149,10562098599646930481,8774387410736919096,13524474244326407978,8059748694287304407,7867660182568144405,4226425895833223960,6413731372555909556,1176044011255216205,16614578616551561975,7710372006462748654,8840681925049448370,5480348619861005019,17166303722259307948,8176230106826547407,9826833546867032701],"proof":[[4751072081222150641,17075229519734952281,11133885388421975221,17469091665603798730],[4210411070990590163,382009718357199424,9466892355192498646,13104838485434552119],[6554296613227730474,1121926494321648460,15198929888146384345,7504361556861759349],[1978213362116640644,14545098282943558196,12046389235153553705,4331795010097366923],[13672776707272202195,4700110416946042590,4909123780094952509,13399657929601222774],[16400908008645167385,17219140611380958412,6079839179971730777,13443216915251620075],[9827209818991742304,8414356134665304351,1568179924609051206,15887867708208892151],[8831914298880442245,17268507593120261021,8594445948554606595,1841851711924634588]]},{"leaf_elements":[16161993872444478012,11184022081401585948,3509446684942524584,15984891284835174092,11476661922686550579,3983972953876615972,8991541927159823273,2215555241110468685,9508085899269274005,10078038540803556493,6901858499377046823,8715787454957035615,1414719084204100214,6523188840251110829,9729956011918017928,5845268993403473388],"proof":[[2799066957734800632,16697058231968234860,13996808180426014507,5995415462783660271],[18221713749766800534,703510884258364628,12967568559557578091,11027150713891313314],[5879907340149548386,13482749565689473714,2891077398356963569,12288028326071493389],[7566029449597263450,1585818245123818314,14950399805749525489,10676342021628199572],[8762109792849395656,12963698369367311152,6281722454582194491,16065535612160339395]]},{"leaf_elements":[1368433193200465423,7559188519008331957,12200309038622117678,1680972348981197271,10109489235199448728,14746558705666906565,9471497026517910175,9299641528514457316,7664753552747284379,7475502513743313747,3509074674700169965,7191244398734099253,2272245910812540040,16716689907106662668,12654053991144248194,6370045626110361431],"proof":[[15750381050633495752,12000827714559599052,17420350435679288486,3465178301020881246],[399398933852474206,11814484348914375054,15104623172458716957,4037298757566163615]]},{"leaf_elements":[9963697324120512130,6935802622808596880,17106977806795412206,5253618945110997920,6891196272247429548,9013941163798537644,13032579693020402188,7112978098992766075],"proof":[]}]},{"witness_query":{"leaf_elements":[17892694817061118872,1370335042250329426,4502597079617268436,16647523562541167355,14015331532883838036,2663256259620816458,8741047149980522821,12253499274102653916,4944861484810642261,17795299554901222910,10472586489472418632,16455508425740935514,1111653527156302210,2802347222974512474,17259658750455603995,5670704125212173332,15765863907364493610,11494223270204170057,15913870590894900262,10382475856371458889,14497299296030938478,11621113400835048522,11858107685233414027,16977010404264164582,4638080170566331239,10699128128466676564,763433548701812057,8370461341896886623,6679724878167180428,16460425938485012188,14555151640450206531,14677138493119403247,795642247996764383,3148121589757354679,2002904657797371565,8888310859813714137,5977748574875393076,11683293395096610674,16038874974167664907,9839115518174111760,11913297648470271504,3389026068977537926,17651557169964368,6805269251908110671,9003539478240534925,3581474783999821720,9176034512892975483,17723370771814714353,4991741802072898843,11295878126277598784,5223050549690269681,15678001336036811741,14185148622767875891,6592476494366806070,16915117363802013567,6102900546110916081,7697874784114828537,13645874202870778523,12098560301255071240,8407675458521858749,12482629502889648580,4083178264631499005,15114993292215459844,13476816987941944236,11638333346782474489,15500970077167512596,4493886179335747365,7732773379968196157,12401719366468614780,5698668106861148860,6127676329227788247,1707316974882031356,12120704287665883936,10987492908171749554,9652618014951336771,4119471271190807143,183859516788272260,6862480096854244308,3795416376441484843,12047474603545668520,5004564366395223248,6105037928263501698,2387924452600686454,4379635533609288312,3689888917391636278,3105594913847920323,15981301120551387387,16441923270347239661,8979196846414310216,13912842991495004112,8110325328405584243,9125114731462323731,5178284116756441341,15402170586860926873,6816482289690652202,15577263981099225532,884553957090960790,6899049610111439636,18006139319749192157,9384360280950725003,18392627039532933945,15884913444858836809,2410913957406458193,10628906607718144348,4917977235867732781,3204775316951617905,7858776465141044926,8298983800383173403,16535609012224442451,4102700199492067285,6460340728219690817,1980658248186413202,15460763654082422264,8342685007533229921,4366985444154219113,8997341470257569248,18325821868530491041,11363115825373060649,17757558610224182928,17543644570160705433,2505879184331539794,1436391090896477926,530780569787401002,8145800725482269379,6673044580029813470,8681423049682880460,17991017696219905633,11370171567513607260,2581533954761822182,1693109499272582888,14005958224414378676,5439213722576169205,7967591333102327483,2443318098894024193,13073591566585080966,12850507906603246214,10902387913444888258,16088258412081301953,12704193876472471957,2580535654092473329,8900238533254918838,15452674884101567429,16063839595170606285,2484062873291099264],"proof":[[13095927275840693247,4197192942141714476,9170466710486361906,10756221699517747426],[10977247139668559970,7231486562401882562,5993797283376037978,10492445819568600441],[7510561093103357552,12089927010485121772,17710394228956792427,2483199313133344947],[5957260868396743910,2620590829747343214,12026516289455763875,10804330328726366459],[16210218859745441524,11558059400823681554,12223562563289576586,15603463843224198751],[16692296691466928662,17519830488201572689,7328062712338071308,15546293791798551162],[10470436538350690508,3165198525115655751,17662530167093009003,12715510121728235580],[15000036407488378516,14162782486000967501,14321869858079415161,6912799549974852796],[14370576323407920201,11648674663152186436,7861962115783661090,14906854470476708269],[3055159771627756509,7423907359972785232,17763278359031822726,16010512505292432189],[2073544383339075013,10962629460034155087,2003744448914565466,15829998286851886968],[7905447263067846642,16541355926281004317,4423717476616405561,7218111409117190904],[5260869553947245354,6381219641700010805,5210497284546609096,18232444564067320820],[10723461629677534465,2707478892567098636,17146862661252984738,538353174211345679],[13086947009885873524,17926292704719088978,12827324314654321258,14763767682480287493],[5151659993604751115,645557760056141545,4654911061998168919,4128363658395254435],[8193979718528806600,8375224386207577318,1516291403550624483,7080112769819207072]]},"stage_2_query":{"leaf_elements":[4418939864950299151,15870199754321973870,17280112766749221899,16129822049414267362,18287488365478737349,940129414973006896,239887366913061425,12607761835643801186,2854660116550502630,2742963943813612855,6927322101389359179,13073926335357976208,831657984929941490,11972285224384262669,155471255218749750,1789113769063345470,9553741408668472799,1469368521187362951,4264178756740282469,13907613111970080606,17594250016751732126,4895854147879725917,11653561764148530681,6447114913191588903,11953638749518854723,15351189715226159939,757204112097088100,11567434941855333331,11060475477499718323,11541763323517794568,17304773334779473779,16113136090118565525,10115381605859602822,912121525666647784,12628218706389640649,12405683461685377276,17727276389950854549,12466158458966446135,16963527687392409160,7958788214717802653,11382329320694319739,8968643464409323853,13980236847595666359,10366544170615006460,4186657653729487808,16067308335386006851],"proof":[[13370495102815646114,10484912527027727241,7925325845814754950,3838831308746066647],[17345208623776901354,9785739536792837921,15200133094702701237,16466309971487655794],[12910784845664851831,12255048684155792399,12374362262594712779,6075224023765714134],[476588724913426518,11181414814655653031,17754504293866595011,6902356814059460142],[18001964662969018935,5847602634028081103,3988714882352546170,12998959420136703918],[13349414861283000747,17756750396941118281,13275023399528013390,9402697775048569587],[5097461941988680119,4816758317608151424,17794166362580233933,758562871595853509],[3586285147788445590,7660921414996268285,4327428007021464575,6178055200904072493],[11086703187436095540,17111326946432323286,16105850561184068172,15921282485891170235],[9067236200664588094,18117230827253197661,11317441842176651381,7349408663179390309],[14242944749518929933,2113811178039807443,2425465251053237555,2699035512783494550],[6571973547819546992,14572578828059123611,13163579577854308956,10693413033680650806],[12472658175404418421,9887202534977708487,3140379427600941253,11571696428203195607],[10510517492760757224,12536191123707509437,242151622595859350,3826666131681329809],[488968743326476238,14812932797373492422,14402863114624617654,10789556844124299629],[8160668943952387841,15113233575098833141,17900040174636689252,14690530551601386128],[2156372198160320375,10758004586682519094,11754802890427400344,1564423923851060793]]},"quotient_query":{"leaf_elements":[1358965441035074920,6632384075697924535,4945250462009970565,8226287510077012894,9481254600906141208,17509317434833856692,1534902964027986288,8721543620055131317,7679578263888883851,3022674973064412663,10801446527231749374,8614123238119808531,13635943270773897750,3603124747560030350,2329241633733740940,18069450237962306201],"proof":[[15838411592409018719,6375027602648798928,8496589026797407978,4174075829035039918],[8375651407128636272,16633148432880113735,13818856153911342636,6548277676443623061],[9804792931117302106,3705116545917095888,12413498857879733881,11509916924691128979],[6357352972441599600,11472095308496660248,11495644714196387880,9877345169131962345],[12096328348144040345,4332337889426153834,5769783720649212285,17455910829306991026],[6300451992249777358,18376002614879376471,17590572190764562356,9824839728451507032],[17501509864742192522,4378455506780969856,18195831911431776759,15113109840746696108],[9583562158696846177,7108441572694556572,1430923444599926214,4698252882060691284],[16519125482853238370,9164255981707751018,3778539253621677211,16572328285355796056],[15952462497523246350,3033325853494313809,7837900043931425282,6756680526603109051],[17160661363496506058,10555125219203128294,8361133953550914134,4927553574246820638],[16080436425450512842,11758441174574319594,2303516922098306012,6849428486294376223],[8383094170790430789,10148453346836349658,8608033417800387591,18329769210831359949],[11157520959810888983,13021921678734834208,16803041583872903266,3545847210636191147],[11550424608649018644,1590118885783884738,9443887553204569475,15792118458268034909],[23346753238032871,11726231107646689909,18446617914928111271,6867169717337366453],[6781824673145116271,11884988964241063795,2786037544787052384,18285016945696491669]]},"setup_query":{"leaf_elements":[15573835540411998879,3596856711235498152,3065491755240667183,8967375445101358073,4201105430382045046,9034958061123943395,1685036302977272839,4357424840163248170,6856011715342804281,313921305102654712,3434466278139455367,3977065664892025103,14508328352632500486,14787524515110914253,8097154944684050799,9420623312503774770,12343243653694636730,11765501901866752062,3708041425929117129,195233840066356228,2044556989113706753,1776855350493478034,6753694403217726181,4425737189894343067,4563332673353623038,16510483681001814686,17950129909985715936,2185810857462903548,8813316073338822564,14411059428487184759,3258967005439736449,16960582308383492258,7763789918470596158,11005439680046393721,13027153549556597376,8489943351408041253,13911425666799347069,2905214082871463874,6854921281620939089,8060563814512190181,8222203004814304527,3312665062114817517,13829995068504135858,6436580068924365184,13980918881197706950,3362095919747483487,12783796052709701963,15570997704347005545,13814828027318833572,11307698319070124621,4072150667371686893,3379158146097347638,11361581073628769099,16928962549529404269,10633158109403008655,14829058206735964746,12627047426178933028,8631545680882093734,3145707925921813061,9343621739696046788,12416494597793668136,7143918792731917932,6119287542875772979,11396477168788595296,16826528515676814688,5481301068213597617,649352737576938857,4280007978744449612,9427062071738261232,5221043207445844370,7128411413082991789,2664691174348943414,1394454755550084128,1569101599178849741,1862257601788628053,14999825133976721728,7950938803530158635,12855241614202209271,8094641059302311753,7071655498830496136,4452424532041515369,5635617753632453974,271195997419130093,11515191380652870330,1092873571132385802,7901675017378644002,16918393693204092555,1823839575344990340,18017274278112071725,9482638589488971525,12056796963956383795,14701160828716276103,14359784306622999140,13941411833527936023,1673123703955663280,13314041386301573466,6841907469517035419,16757802220240773211,15942852390612458058,17915738252858193316,9626391506955942970,9644668022456813982,89925269035082150,5738614434245018443,9316663293844532923,16701647351726235990,6511957880732442719,6166337990474388185,4696590093193709751,12460787112778103422,12476387629756968654,1776685412832093604,4453902662661831697,13253756002731408028,15464058736354343015,13476101162052304042,15451303037420171034,12273768041971569626,4390192576992518900,943382469205150336,12436429650092300688,13188935451436970765,3621551110488642971,15396270478786037949,6779530618268061952,12571159561075400473,11250237787405633929,4439750064740860777,6027117997542334981,14231254197266067266,2704022834288576165,15822954766389484818,12312076446750994630,15012796779231243402,12050807709725360501,6250489552385344596,18212790125625359934,3438375464057958087,18397590508217587981,3106104055215409263,17270355106552648349,5175564089477506076,11894164229083985550,7249171338117271326,3117805812890649838,7484123995020076274,3099214604535986464,12758617300475548934,775473537622229038,15906437148003627809,15518159227169121612,5392059261599126861,12362942854709738570,13088063594109396719,9750298466265371004,16836187963632895086],"proof":[[13753892336261721854,2712372125996272035,6501653464480257983,133418054798932803],[15583942869729446614,5840541161080277769,6199671128465210810,858850738518223423],[8771272793689172559,16925704347953125739,3037923748771025491,8305796819267710501],[1363901915259821419,6378566851092316509,9076557040860026501,16363824919849031218],[15622415536758409147,15092123912278710405,12910002882835946153,5403810913929019715],[10842692268442241350,8202845448087496193,12264293248496955473,14966205973010788698],[11715329714551487968,14448093606645077752,14635970865751431816,9930864531442172441],[15601590541449590397,14287734991571185993,13966825407595568198,16606292578184985786],[8368174009076833352,32482806192896016,8477615165638214222,10218209127144526247],[14035770613618371534,6353129489296730518,16134283269342973351,16024936317101387769],[11269963128846982375,4715386455203789881,4051089050764883436,364445396535991515],[8992421915706719293,16936191075438020871,14873173844900778242,3725126895419306524],[4352275396634492549,8813930853334736923,11110191420959509430,12231294539735592045],[1356355948750740799,17329733832843121182,1609162208105269623,2268575359445558510],[4776672151118591306,4514280833189832321,6878515843535875591,938127985507253224],[6693758018881043178,17163178482231601620,18394111945980300726,8057694723322035056],[6927789725927369932,16315812677162299352,8615590175857271490,8798523207874952519]]},"fri_queries":[{"leaf_elements":[17852487200833999305,5589875297359166356,12180891208411482851,16529653530155807111,13545006036473987872,14789925530030375799,8834405645845645053,675857984408047247,7437838566345076149,3287348661884719636,1450660725921674653,4124252065818643632,3367680227759566432,13900166298103482617,15749674614328298162,12710861882359399935],"proof":[[8202257145266894556,7505540926761273392,3118183001135170094,13199838613867815640],[9747199143332759217,472987836682957674,2784244406889575983,7044415120599676085],[8131005039663818225,7521220542086545783,1734020710509856667,14645489492815197831],[4042291425160270447,8193032565772090481,13886522388661840417,9757824032693321371],[16908757432115226555,2458570083160506751,11715229047455900813,2231427790323870300],[9052337483363028084,7940480311204697432,9896541322635282592,2196085927227018092],[43926613556887774,18285833138117985114,6421112247397234210,6267062354623720505],[14749085092387346049,16919350200641464215,13527979245533234,14941858462628450093],[2200906473415045705,2498891598868980648,1024166772492848389,8713650887907625795],[3494569933354291482,7004085660404996600,7686840113602080227,7671776463589696964],[7362733012786738344,2014695607905659720,7771107444878276915,8606287712527476410],[18050982265310127424,7708517498881429692,4760118211787106962,3355182030634371245],[15977936783553298065,7883991643266293292,6140878641507662900,3647299902647897688],[14128138712872929702,1370874517542577445,17278172058011345670,7215150699576622869]]},{"leaf_elements":[13993667684953757158,11842731070296534835,16149713694133021018,3392572206364304744,12215778530578866101,887269868242919025,7168837529168485093,6975350625951351792,18050905620029758823,9420953153544142498,1567004700505656726,10927832786541721839,11457365497478341075,17367429126635606594,8066268236317614432,17062801700713732018],"proof":[[12481635132193582302,5690284625742881331,8157031716825181178,12777370422238630127],[13697303596443054643,2562408818919641431,3526665997179143284,2000029266661199455],[12591611319825511266,12233010562468424254,11340306304056552801,10643592967931348973],[5082751811894416893,14206701576472797478,14847593766181788697,14081012755281338888],[5354916559983383693,6424153965718006700,17735163002310110198,9556365869848721131],[6641966064908367300,2321414413526740525,3835361534804160658,7367465655671376299],[2710950641560609347,1608127399303888647,7963449247972988268,11420049298441656245],[9609384321624286180,2336425830037847753,5121191435122818334,6998257404604369530],[738101403740892801,4503448456760245851,8844044300277765656,14187259714936380700],[18331591439139592594,3424784786448365084,3142444139132171757,4272927789110192094],[12455615997980745569,6899641713496781723,3754459214410385641,5180782410589882794]]},{"leaf_elements":[13004601806926329592,8881463338789703975,7064501211573463797,5807075698453480429,15207061712798990574,219509986787808177,5590289349157099208,9150284545904208120,2291307685993505021,9104302290163630471,13360817470805425633,3668910503280467727,3602385213999315959,4372910983516431940,16018890043354711550,16284727053294684610],"proof":[[12647117015298224803,13999537301784052045,1776654782077903117,8075763688500163625],[14714536575836137950,14157171651510424997,6490764891724557339,17279250256803166277],[10544173217148788226,2684502205568712584,16112856573910424683,4852940413400959296],[4303925332357092810,688761885107423328,17411684983448372972,9487030466465457908],[3742725092040559630,1153189769272435729,10879975115285537905,3801459887383939988],[12842127656784450503,15192024583366589417,8881156604976923797,2732579949968367180],[2651109751430335033,11439206719483041059,16110394345713369638,10184638098901079706],[653609557330627868,14023145008717793735,9829013459427154980,4354604016037302551]]},{"leaf_elements":[649498758726510427,15540549177150122379,1487307102419287982,11838285861112275668,10890574446284558403,7700947441327062604,3658383618598211848,2346327751113505383,16764162968555729343,7483359226078984376,9258015727734682970,1118738353476780106,2347347133404105626,16518102390397221781,8931245830892559297,2857660823754334511],"proof":[[12123469586555620682,8340021900924544223,15564759775291908209,15768307453336880845],[12107942443969859802,75046549874008154,456040071774737818,8366683538935622943],[13759604345151266542,8066485996518942575,3755573335511960786,1649424906162623451],[7624181206374835069,16639945051842694695,1627165198208021593,17909495709380549978],[9177491066822616147,5431401594819627928,1355274528698398268,6660308507820893921]]},{"leaf_elements":[14886676399737703560,13931663038602304496,5280470600619763712,1602784438155796746,6479264596726780000,9993197544143353723,6492683510011167601,17140074783765260898,2942983150467580832,9921602828685932366,10671825697004583395,186956216834001891,2326717636085023591,10627251099606495890,5711740284682674751,14130161378460007906],"proof":[[17970726031724212930,18098966392717033744,18329467923396995518,15033918897766573074],[6872717206768702692,11989125647797140964,2137644504125081380,9069676152651109583]]},{"leaf_elements":[10632746266096061438,6757646590349987949,13549814758625843258,704655662152719460,11622797146708305149,15759578015746123756,4397608871267503275,12640380755777952922],"proof":[]}]},{"witness_query":{"leaf_elements":[12164610024672211758,16242608056103555924,14406070342920981607,2813978090705024525,15748064166898333610,11446647487861619718,8434357110465742065,12307669162567647067,17281186644552887632,952787931594561455,2791305184233892579,11121566039409128400,2961665694762483500,7303451384164833007,16578538331466624073,5873165133729351023,2970304597122382297,2756885830945445874,2686230683352829020,9052932459261720659,3472797429994740906,15953382347630115454,275343298788457502,15887889087241965566,7056034675836339622,16188335650397362266,17470320193314863100,11267592919464783633,1372728176151953771,10402522450018631726,8125409839142357958,1798438906519360925,15989077924277136217,10537956540828397228,4408753134685155565,3475537814151366553,2282822308407497416,18159917714280172809,17938117758241668375,15907059212021389145,9097931841864992750,5266790670763593670,2233002628811225931,11856382369769322841,75777601138448192,12336296673267261381,17000764152107572674,13036913522344652202,13745405724432071571,13788627291921610369,13370679733062438332,8630345240257843502,8982258386703145202,9942861255569686673,15419809441993598382,8318896389651928562,18271897770167635912,4335160857105936859,109020245696259296,16670514276705426869,15005608901530294494,6475229574832306575,16167082541959116915,5439300125475968635,7779568360286941674,14120842008947995870,5697259156328511946,3873984477766159528,4864188483411002784,3292580445883030413,9017481781067137856,3179198193914430702,11688630328840718285,7159735376812935704,18182176458249402280,682447833591063362,8955473855852343535,8803756128350861977,13424673911652437078,18424621028598981117,11927790123214929488,11640156215697140847,14703075482459748704,17340398264303337184,16884804044309078070,4606074035863489484,12134408582831835579,8434056718298670387,3157578405582990188,6429207264475071627,9429213399981734500,4231689643076708459,8896660006400508887,16849913324905616605,2014627950903065417,12290895129875644103,17286197442204351411,17237037067875721607,8512083577082714972,11634021372276346120,8334809503474061217,2400747770248175137,17360945782045009268,9218477530660149206,812264332297722817,14260881400873896238,13263617475239227798,5460535833187834511,11053365822675513591,12405321708928850840,17877008742698955064,4698327348298393569,456179044948837234,5651014377602854801,15537280868629712219,16606380622332794117,15921274261743700117,4346360344731441769,15438689772566997531,5090934551160694768,16429460651197816777,3569542662122410766,12602218956221704338,5832805067697884667,6290396088675609309,3318741938114508954,7943201924394916701,11188499066102892327,5957608730553112978,4003771354482335203,3704123183921588770,10883717243712541613,12536817832168936683,3848992078910293931,3879554333771526420,17320885586361277380,3038492414748172207,18154003982219640437,15116173597950000587,748171150764052424,10813115004481206602,18139828790082557434,15473083637260587318,1248470042594779024],"proof":[[7598430997833767579,16018124942109035850,9306737007295510674,4114877681418951664],[10257274607629947039,242725179290250794,14342883463892230697,15075665635843829511],[10435233487419928858,12462330921958089236,997875320441383836,6168378145421537489],[6130902536251185184,14251023718664913105,16223893198280739316,9514319258846266763],[15385178605940389457,9970399108324708417,17782864907548423382,15376102747721102072],[11891935398330206371,14082510792334630632,15813539305122775212,2742341497360779396],[4383659446534755367,16711689716970024921,4107473911191485475,12073108394233813112],[611644264842055422,14410176731361026497,11597650217200505143,5002776233992012396],[3537108929522289726,9934980690895353313,6748823574407520076,12529991839472166548],[7209919630193015589,10318395873651248303,11813247704742886260,15052385077124054904],[4835897990747860763,17290656627253286919,16262785299513022561,6332980968441266667],[18172156444393309721,15896378592748144051,3696834223788200157,8625488002083402475],[2611377287171183142,13677342263391146941,9767954302004838820,14338547879408215496],[4650559885172216210,11983157492070580481,3710825244520903168,15022832953847901205],[12612569859151467167,16743852037426301505,10489684354590848624,17242193648790315077],[9980410839683514472,7322550027951755367,3541525573975756140,14982918748775531105],[446318376307115417,3375364935197782891,1913390476604132002,14742194311215528796]]},"stage_2_query":{"leaf_elements":[7050952590550132036,8565017934290104393,11552933937263518340,5786850701266031346,307170594095543096,10313489207326190659,5395371378037476366,10022203497887430975,16029252209832132924,11948135388778289074,12087287775614760060,11086263721958599046,4364745924746717803,740436739047116533,7201705062777766310,5939476654675964283,1008006214953591683,703172791041432760,18146783160225293281,11074381797843152835,4200740880517333094,14268713355820711489,12169713858814947320,2702975439334246005,629185943689817596,8131240510397097443,6772456989712828639,9207347488844154321,3799099041196442828,7793776409523199626,4453098941017660637,15803420145916822374,15198116319411148064,1003611467455162481,13980131765539660422,6328167914808097183,7286015703092770555,13556354095306312506,17678907164403621212,15896113075287999504,7862760348064180421,13704858227607034113,3722220173463400265,17836432313867381342,5778330172045386269,17157657235393990114],"proof":[[16395145395527850473,2261402961896698433,3165165063442990444,17450048209413293375],[1138229457798738017,8622704394108770254,712967472934420377,11175173989057536597],[18319308474308586737,620663683886075331,9288629232775443786,16282494960417011769],[12843851912050107644,13779405982796983759,1182850638840787123,687818800689706022],[6215802199250348920,805572628085282795,2292817569768456563,4241831209086811025],[11737301681964244556,17673331330600732144,16176621221937672141,9599565802164521158],[17115406326482332667,4411668924701804687,3058793334128755476,2933336292088554161],[5821059947080711552,2729137384286482471,59011417563112093,7526777819867318489],[8862518020988355874,12119412329341608849,10191117789870118485,3288543107877109943],[4169300434467239094,108136967827489567,861433570959076351,17412069821724880298],[536663938927454206,5631330411087707212,3039106072332066422,9863756458447629208],[1220569996345341805,12114069947795991227,14944530255562505326,5257077439135548008],[18282828610818295973,1020858778126652003,18188879603659300256,552177250451103028],[691704461430465126,4706200438102593815,3377065410717072494,10075474551196223368],[6189930972438388531,5746758631072541824,15577435025865873559,4101436592301095303],[15746818743837445237,2985640451447576772,6733483411823019191,6575594278664829228],[1283005982263822647,5576217357074790266,4838152385037052151,3671493702847934836]]},"quotient_query":{"leaf_elements":[9820053131085739141,9021921889786735235,8863373608195935617,15221824746525873741,11650151732793882743,7154290863867838725,3834586684468467102,5670929154934063445,10351704169296003301,10727472910107738359,7331929301329346249,5455208950001635529,5285488404095037038,15933321870114640818,5526847764505061283,13341161380262670532],"proof":[[8532043129795561310,364720883221909573,833729533865703719,11012765179917067856],[6758191433821057498,14154394897776878089,8304264821766135772,9410734045483101290],[17185875023431932027,2077733777857889308,15923063138706830814,9943703648901081265],[14401178650902988305,9919321829806661549,381716731501346909,4609587054115544380],[14438826360575944217,6090369412732957113,10304499225461916323,14194869746548892341],[12720170791624391886,13150189901839897756,9617728962289124889,3818805839292242852],[4172050019841020284,17634438872578160578,1875813926794710883,14884325274902102423],[15168476470798192191,12880496268277826090,11711373207708500065,12184888888518633783],[10827657961702270610,4060156853481891398,709197599284040201,9194019244808457760],[2572739730848949916,17718554806792166330,9766880319556239059,8626863715454166889],[16937894938492192179,5207465037338912170,9720661220296289831,9086180713976048059],[8912984722109782694,13701824900456791803,10544899423459210183,5879055246084109445],[449641449976196831,6245409251799487372,12622430805369423724,652500299630652092],[1938633762349147574,9207546808316592652,12023040233869334606,16741886636648919080],[4625552990378348106,16488607089553743419,8263795991443168781,17361855714883836451],[3689109562764849626,366021334287970053,14460318300993859375,15450980280223614390],[2756204060012982104,11181890352814265502,17993618182006171151,16194213402389489504]]},"setup_query":{"leaf_elements":[13583647949637281465,16685839785049037895,9314436290089677004,4532248271551724709,4243738481417283664,12275604272643828235,5720442640373566303,12341756460494319856,166975748058741846,9627216321581106099,5106127418844075674,5469825868549453512,14120262727238843179,11001634334646258287,8496713357887745949,12483907072017581518,16801271478959971560,15674334081495690292,16272221463428948389,3053113141797911494,7608872969509705028,7678220677277560945,2580243219729217185,3431932874967773106,8827044431224638485,12206080940720945862,15852799880315887112,3979206802632261224,2619256986896159118,10463387065838203852,2318752664745892051,12033519635704680512,13924484768594456110,6316693866288051801,17024869040148813520,1832146689621219723,13826659518721305306,14874948977570098059,12647583431644330950,9503801104645130817,16951846646480255931,15535168749791525779,8385298758580816369,12678758354711641276,11820687367152964539,11411762997335567430,9863898326139808139,11236457859012668839,1091484640975201438,8050266904166046520,10961751299164724312,1673929795745968902,13205187813274479196,3079895971092434642,7389330156088296874,13635121421990926416,14819228297392907731,15304836085946707260,15566859430455538626,13647288875557466024,5156727229838495598,15099823455157451354,694924848895422661,6447984948128911749,6789103881644941473,7538917150959620044,14953252195574163090,14514205788578898081,17536341707154177813,12561078203116831251,1095534664133862498,12965635850757891019,7895479962898861389,8926286297505980228,8818296108522284505,5031616888177793669,2591239194541972393,2887860636197931942,12503594784132712087,6902182245392648105,8352245085427328498,12144038865601829182,2432256631532784953,5935329133072043621,7475541408900947999,3866145891801930088,15662571544651822822,8625587467333468533,15486678225659272057,10042951774095225011,8493247176400416514,13853398443393058597,6513604526324264096,14483293508867398584,8048454607130131583,3557009750790021822,965119726274873605,13325200454392692507,15140783730080269372,17197404255218162804,3101456633913924334,3189566672378240628,5180008550736360590,18423502914087494974,1086732983408900140,12645552026354838079,13989906747005242466,12664731288295328986,10740544341587772385,4058436516320581266,13089960052360818278,5446247310932235577,265905107179529663,5803619289678484306,10229831730898111962,4988219578836419584,16345995429222790855,4932949517615198475,2208152665125109091,11751062545691429739,10431062920551357184,16225661538617491762,4130512484145373782,5034760365818117176,1343337336265098690,16347482317798210896,6469904482109091646,263414165383619689,2172080066703925882,7119338009676956170,17808026540710590241,2754037537647439227,9824594236392169117,12526180464310463302,16176600061335408185,18345154785206064830,3170138412577459980,1399758695095069618,8728095534997252684,7282092533809457895,11054822673558395732,9936356285684767414,3916273721514417143,1517348895776124952,18392597251573505633,9157260226400588839,13528895217275120180,15672650892569687337,13210098023789908730,17909628247192779864,17074075514674389435,11433419454659808398,14244263720890095164,7924666868004477560,11424901493392562420,6462771806421931357],"proof":[[16564852585895703598,9004134612617880493,8537120434977519230,3738928095639531427],[5624771172452588426,13265279922645205175,6386553757236994101,55017554548513667],[14985794989461732808,5151254065102300881,13215142775498754145,9702355730234978114],[15315353731546754764,13662611871633389346,7720982517748116432,7774834474639460474],[8655426945453565913,2601034064207168487,6159651282142504775,5712115223895090504],[15081624991428196440,4740984983286318104,8496485991032908681,3559698234568843606],[14500340048753187167,8397847742793296282,4909133925158187836,14341061840419797075],[7013553923271850860,4158564231201892487,10640267482356267339,11541221496450729833],[13779090374832601874,4114889495404690750,7240487320038488425,4798030551490549119],[8128575929847900314,5461535405316096987,2682384657138285087,17315727872170056503],[7915214810052833750,5176174178476745294,7104847586001842597,17418612063740382505],[14917115283084001147,15090419649830426127,4846353243417452926,9488850157305102954],[7389710083241111354,3446554316544986638,6310990866659825669,5489815470507790961],[8944196554726228434,16973329988402161402,2725189964210468493,12902171507816298035],[3208089261995762393,9999545448444607063,12539177820629239661,9733301447206781313],[15572169563599132323,12343102909949677132,4166028430645002977,10454462429890612665],[119942016992425815,7641812824221345957,717302696007773285,8607632033190912232]]},"fri_queries":[{"leaf_elements":[3635204749449559230,10516325559144556777,265118824993663226,7751599278191169127,14454551935484629945,14318573271187566918,1830663786919466064,13572460132356291818,16759194789835416674,4201852442101651364,14546926336693814065,13574342665154592437,18010024100096359536,12704860678945236144,7832402838617580218,17598910302950576742],"proof":[[16099660609923859260,4149192722010540920,13489094003057867598,12284455922587121617],[11045567590903286474,9600185078273734243,8931582225876448081,2909341262526551699],[613990669450586863,1084134422944692116,2016751633540783508,13401916952623091225],[1369605509074490790,17381798184996494003,4161069694521898415,4557931803566686712],[11822979058324858900,3846271743089554134,209504620534472045,9052994712576001974],[12434500048964326172,3029207007861044125,1845527092646116851,14217892181804205667],[3889530019298757143,8188502443047143867,1262148354325094052,11131753552016339322],[17663807865177203742,14133679427074522964,2033537183639914530,15420941695291375200],[553016424302688834,10175944386047518358,1041222110816259713,14940339297636328624],[9797815570232889773,7153150863532208426,7483128651067913960,112533066714722617],[12626586014110842517,2191665691737176368,2101794862654565997,4423073684738706584],[11627377915665385810,17121838236677565878,9367085610916447784,104591532124116225],[7027844335128081170,10129972155212038019,16401628726279509279,16456211717365178169],[9497522330654010607,10428746838159854411,17282797116643625741,9370446250429457167]]},{"leaf_elements":[5608401408116434231,16719268204967207354,11792548613768107858,14641755922138969761,6134378811144906363,12304939791900008378,10641259255739901973,4083783951149853579,12960123802655557894,12006439544536034451,7912916030794187771,16421498651662782509,1872923662202951293,3313684494570956717,12053801816098829623,1839082923818786163],"proof":[[7638404198374946775,6707332736497021618,6794647617097008173,11861562237496951755],[5922971974865206545,14935490893009503288,5306134421091294033,13621922425999740035],[8569078736507587143,33505960463315172,10469120983409712307,870243273777802483],[7213181041875552111,14155612293633580908,5756511950832842790,11919228876270094569],[7603749951732925904,4522231617422270845,17883215944400156058,8883725952647372353],[8673596076609169774,8755838405716326040,6772747748514337872,14704395724892279534],[985148488206250607,14505183180777833262,7637175203411097435,5022451673179622797],[725333028211199516,794012936860718921,12495969151594436680,6006187624007003155],[3550366116560404314,11392075634275133989,738502756335242506,12067731576962190331],[7259483814939175432,9308379871861495517,9174850034895773180,11667434776828581520],[843411343929838404,8361740330644747194,2332379768699751226,10226462084284657766]]},{"leaf_elements":[4256304547088982830,16382929048200227138,1116401497754131423,15624839840108943539,11329797082815386888,11667205323541554684,8844497141771789745,15987167513214015024,13891685016387733686,5556311996061259057,3050756279359894993,16272938927886296479,16200279544232544275,17296306107244450923,1511116778132889062,3809034285095790225],"proof":[[10931134755331692222,78792219460670846,12084875901403902621,6043685058743634114],[17645889253555483276,4356954279597499129,5407124615922027984,9250190753666767786],[9715929869955805421,4033450729923759903,10971977983451390411,13313235923591077858],[1057472324657786137,11617927413330684451,11995569073425654411,9590323149763147243],[11710125471011702313,2620560946096845979,848353929005706603,4114733125876298155],[13624437219125101837,2397563059911228825,4492932418678902018,11617592844068830077],[5626976220079211998,8278137800848799186,11465004431706415804,7425384378577539552],[9196460362043655518,11124783458111663969,6628625323182741542,8138792676882935518]]},{"leaf_elements":[8525725900262897101,6461333427803051237,936741220065741297,4673610274693904808,12277000755031712383,11609274134620501799,2207498702285373056,3290393562553982882,17696761163873810431,15943886914210078405,17860054229807814834,15876958863961078873,4322337295657013251,6575874175133897580,17590953486573504558,11170652802766269413],"proof":[[574533917907854760,12904246416210192928,5143546498648761084,10123968643064051273],[8097057391905055970,17337197427136777256,12564851177375301968,17655282917769570551],[1032258115052514634,12039694208811852756,3221006918827940206,5234265606746411937],[1083676519607914320,4441070181462611819,7752158295056961851,4667463103369543388],[4195745188892480400,1278917477926341115,858660738527305749,12026569133742582051]]},{"leaf_elements":[3042246220767584763,5961267606790053738,3559887806305008337,12317224916301103859,8124994906015625402,10898482425804395082,11052780135917769558,16398846206887122599,14733290436189784745,1767138289286919366,3896055115106055191,17020053650901645609,17018099229898616363,12843003703710192669,3954991896419468685,13020405056681120945],"proof":[[14146218265997383420,8880798799092325101,15074502922591213158,18215518835096624766],[16070927894096146171,7499309042979267285,15222708687563261277,7377423658769375210]]},{"leaf_elements":[8872244034292046542,14961388654118324654,5802056968775514489,18302383666416428067,3933647026650259001,8825851261617385151,8616213839298888053,10450361630528634353],"proof":[]}]},{"witness_query":{"leaf_elements":[3091979262135866635,3273841223961115136,7985461468536181888,5346626881479581770,8857352639086234628,5989738406055402545,538444674857676512,2232513657905544095,18385192191650261505,8643661560617254889,4966911498760563022,15784412761423927426,4626934104534698695,9188157477030016559,12087298862476843214,16806314706090251675,9471713352127970551,4866300838408019142,6282124630363783151,124853529500125798,8772154784204535639,8265824129405333472,8945623286648715192,13873544875149785315,17825370970302728405,18252278039499493772,8012180940746536994,16968158541191021057,7548230523782924766,17852997473765313201,7228973488743137503,1739584833973544188,13547141755646491542,8397048883406431097,6240364884790055620,9244791886910227462,2309921873401791274,9356908004765406256,16529437894646886944,2449796726820195057,8510652852572287760,12297320128045523626,151519380070805897,3240440528559922412,9853052166072686249,7542114369872001132,15040045138707491005,10865673130236967096,2106334979973484272,8252709603895701788,10176388524290712068,4152446405150853948,6907745538145387093,10281634175010384883,11717129626958408790,7879418306258539375,3732432937324306581,6537784000414486451,1437771517994676873,5344006646167069457,15003132974783088256,3674886579817127516,3117907845080922650,18328448342653870017,16365668503660243572,6998767042302554692,2919576045680420231,16348704944516739290,14033530088551494039,1465198461223100928,6900444041345293350,2216883491801339568,14370206267901825093,10944584196028383213,17457888981049691321,16806028880914322502,9736856588863130185,9473787030883035071,11719141826529868522,17800636428012832940,13424926254957517228,1784074057341187383,7491543120990507289,2170245404591982173,15347804681535094268,7551399088638774257,10117580955055057168,10578612409674565375,16222701778750488905,15259777076593968854,4393648440022616449,1891403180973731238,3843426759709689342,2395389540635114173,6130581531407147586,1542512047489931362,9640836828499619028,14028153400910255028,1922017433573056422,9780626505293515231,10736637101243966334,7136331666814699477,11008677588977600989,13468361706704228631,6086326891383632613,4646215122497509555,2074053878803118647,10566716808691657615,370496491567159332,11839500515541228068,13184401348087547607,5083661216219236639,1569242282571014481,18359302387093636515,116098203550261256,479337243438225518,2142738208082681528,14218768764125696437,11643145357491765216,16266640114355745474,724083000199469841,14427792172726300224,16067877813350700682,10793704613155039834,16405821672263985571,4115685337637896987,11128111666359099453,11562936056821318560,230996596570526780,18183214092874724964,4377522652028181886,5513952043010859942,13987580708041054118,12996193105249499064,17548325628252293137,12390141938747126420,4982313853182532469,4855657045491620451,7322446371621289381,2050361129195539857,18037150463027714437,2163161520539230332,106269652101566006,5459845204006739092],"proof":[[3496503826702623664,2420199232619607100,13009343229686556192,1605347978027610300],[9120163071825497995,13675691125636968525,7013774174492410475,14430337144879570066],[6255204450991764726,17081431603252465590,1779352035844298166,17419100545585194181],[10072465843581862725,11791592936956115646,4517982765213553818,6430922406982274139],[3132095829424825155,9810493217332653516,14176107701167953257,5545150454899618416],[6865983631899113059,13116765164665432134,9734400785261316258,4885447946917717542],[11696077852725513799,5435499967334221953,13342452011528019470,5788405802370955535],[7993499368948990464,7591754747294393673,1838256831937114354,15406466882351382457],[7845017802433877176,12648546702728518730,3707332632798976997,11353850801548767165],[4610174410915458509,2015165475964077981,3347744955950921881,3822987149618401596],[1913101323592237345,5058273718466906516,1071169382824145010,11579664871894131300],[11509188508046416041,12190910602013852510,8946636582466635693,15604480375883398821],[4025757355439724405,13747402291477017871,3996573137873570374,9147355996823194471],[869562166817833727,6750439612033308469,13915621429654110358,16069848433767030447],[17399315722107599347,9975763854577449947,18206249874266513158,8851869651638131737],[13956091290665605269,7893671946068161603,17280842991379820366,14844174942388040798],[446318376307115417,3375364935197782891,1913390476604132002,14742194311215528796]]},"stage_2_query":{"leaf_elements":[8552043124761352190,2790624856390707345,16858040802411392615,8065763318311974484,17510847686364366281,15114125788540835411,15268141039290950966,14466375859437412150,7748751210730171694,11549441462933943114,16390616873818693460,16730345811599328681,4532660542245224368,17353221524050358851,8805751746765304866,13356503650384643473,1582996346574963205,7888425552573495240,13244375381928826617,10172360894700541231,5441821477110245815,9684460502534320765,2094976772100549708,15701871031429744358,7547573605654589138,12978850945481362729,8277604961842014019,10199260437836532139,89486728332301986,14139774138225119450,7324633875017424621,575197774767103731,12747721646012715642,274351837131036854,4819625542660055625,15701815319848448636,8830835379565618491,3224693797422384951,10835317612948395650,16863874135527755312,13370433730007609544,9747973654426649757,13423257845690122248,17636983661167599410,4990091810340133573,6696923664003903655],"proof":[[18374877951452917706,10528268382747953343,1263223263999562289,6515610715346400517],[3459925021750086296,2202514411851989185,13212298235315054215,9437526422859260958],[13278304550854591671,6559839672629205613,12753864373686013551,8262442784616971081],[3470817367425946247,7057028652311679379,4317760527126833672,16160489200403462364],[4243018926665645339,8105049127007701517,8744041348824766820,8927346948719211004],[5790568126869195837,3658093770275100816,1509959738456026912,17159910820871876423],[13352596678437014971,1097888139398171357,2019828696448154689,6152271655958623055],[7113781394800434243,4177351634640349707,7030485393974396748,1185548510816966385],[18072764360086137031,17466318004876689601,17325052868282812719,6450372916063597235],[11196208260559735504,11527360075399135092,7360764322700692052,10982174229617439916],[1243436888465546839,3667631861784425449,11726445538421550246,15461375043005854096],[18163993795592802952,17166514012596044891,8959322030441529795,8492061668355458294],[4307660732657649945,6765817332594842572,13197984160118179054,3326654834308082253],[14052966467386858443,11425255595548855161,14934395077750463412,17479362390152699594],[7213591029217635396,11273666069304860178,2440722841686736503,6840017750781558337],[15351827245894792358,9295638853386574934,1602616796632692872,13047387633705632052],[1283005982263822647,5576217357074790266,4838152385037052151,3671493702847934836]]},"quotient_query":{"leaf_elements":[5125914538217400176,2772076806575105221,3146480064312869283,11276695331758702983,808790812179702656,15695530208833147304,10556526997286985918,5098891990107849127,14992253188796421457,13902626818027771005,11601773200327521770,9239083163370968489,17167260423355006624,6896002479368002639,7786895573292180351,5777656119256630467],"proof":[[5717349713389659442,2527791375976317231,6409177362171893773,6453322238487394491],[12495522301148038399,8605548337579167258,16525906962383622562,1366859686280504314],[3520848534674393447,17300309967523499050,15500661053895165430,11736027789227272149],[15803725200429226142,237631102589853725,11682203038265196597,4645184759486367215],[5662789332157792176,15216651301516222571,14791040419576482677,13551034494913180650],[5512737881090852146,5377019543481224171,1038617421617923826,17290388552823187230],[12015888505673314518,8917355414122225707,7553708700178891356,17170646554537209693],[7313530338515521147,5851234617023097352,756192468012927457,13690334790483663754],[9256237772121375539,2522998724279543104,14376095671244410387,9541573320949978659],[16097580131828216271,7541382559141236649,7793545187590712813,6478182582872837942],[18030293552096371409,13752183217976609748,11915668164936230497,16191968035563287900],[6247176042947338782,14239727792459607867,11049360652129530097,11931775113461360600],[10819316577141290103,6843441099183219396,5853597317373809233,9832034496262312119],[5537033682917984415,8273816598235921735,1177787098648190802,2536047258685688281],[2517254183832167733,18189810458877796117,7350733677052505173,17241227777780402038],[12383435537749213360,7913388594304678688,7500054166861163716,17121339375120288845],[2756204060012982104,11181890352814265502,17993618182006171151,16194213402389489504]]},"setup_query":{"leaf_elements":[8590585111276373479,7791973510814868278,7970364817288956257,5007619000947676759,13593977856484054809,8979694250710913856,1348716504567547429,16747588710832702718,3107848445537451408,10504661926339939113,17243732770268119683,7615745348067870892,12149118371065813382,30347508859093347,3412163481339324219,15322290583380402642,8253978482223676601,3492587910060954694,16787820695755842102,10231662795279753781,11467676126779951136,8414692750646314453,12167016656677334734,16025247598857127413,10490866512429256838,5266004128530419981,16394974368078327651,6440619056706437358,8040341298364258312,7766620908854665520,14260231063293263529,10824572818801929373,952226682761966952,2054199243676249354,16471143355932502706,4039185315093780439,16550744096435615292,4653410283541818567,10508722792270635597,14261075484991289342,11598986799850990493,4108634894739247903,12250466225623565432,14615650065294699776,17244903462261576845,9574498519013079736,8894141225696572723,3166275562779738196,12338397857281708647,3853969952877581683,15723276023367955202,6101737415746792967,4818522927575676494,15077788341794502517,5296337049846671835,11762978692370477621,4739830500228929023,9743877199630835432,13854927388237269280,2003959799798921053,17198425256377100137,15227751550059012320,16887835737419756807,2104146020565663611,7112416088504319844,3165253637136003467,2207218728240551739,9352306502795023529,18283417430154975653,3544420776091201083,12628085712910068431,480171669092923578,16870031441304546630,11114364995136332185,17835718294844598615,3903301082420944603,8708438897707944475,193010599860962234,1209394846059666276,17021900997641246692,5514678932065050545,14772679589665134627,8124089137723530398,9724867586097766417,8908509073211890527,5982280122338101540,17230600429155807268,5349435117950097477,16712092939046414054,13801210276469849218,13685996945364446201,17631028492914390102,7618253326353034509,292554325128396541,13310388951464208027,13973085158838603532,9301889714302233720,6256718021594854481,17782732395294160865,8579849655435684917,4111348545551455729,16715402217554072298,7317849263255665093,13719995713021361042,2372740644641178585,5139415037884328891,8044447172512638272,4726991570596553589,13936509705244483662,5285976836935792058,12608279278859740765,18016616967146873174,13288370124778782681,2744894564327755863,4895181377062046266,8529893823859139750,11376682838352981323,12390605023865856386,13718590467589867182,10303332434433400809,12434884663758770839,12234271180914296848,17646262793549897970,13550329487105927824,5961998391267747694,14227959413457892681,9145115301015060280,8337052667092574069,2670244466031246547,4533191826916638661,4097552397892426060,3951704645361952364,14903634586878561987,17103097780256529935,16762987353603406490,3127356056885608495,14795337942358695494,6585975240172448277,4208081374748856005,14801877567796478670,13913941962389200750,17236466974871333297,17700101953346480339,16769442031404827503,14390330578889785116,8969107450209223015,13338113219987654940,12309395504504931268,9479896976212683188,16578891451066912260,9903328041973629837,267352097996306434,3303030668402035865,13103985772933284667,18281364288343054516,10722521951522725834],"proof":[[14763016289483169401,157807006534538902,1280625762880254264,11960487697575370718],[8126445872811458203,10913467479801000342,12077957613437868587,15376418874454870273],[4680775279595682292,1677852986438068058,17919200571891823594,2637290458751554832],[9718454768256335814,553113099623651083,10969679165004447541,9083980576828757235],[7018663720060871396,15613144694536914230,4375901565042568490,3739805410694680116],[4811680282263476661,17660138130704873713,11370872871425415625,7785658000961539530],[2734849420848251377,3423016475672229600,10467386786312938868,17963839623605285736],[17347606313495372911,14483040141676157460,5716179632223585651,7253091841711541363],[14582070829014604151,17087509334072415732,2159404586013566760,13940643311184013929],[4615477857889133501,8416548353612181477,9763499370942980747,4246881964448335065],[1569085253730479228,98383670877028012,10481740367061774920,4902774050563411374],[2270601142933425586,10681683474140746303,15322446199198903535,855111582598901309],[8758601278320187839,10296960103795363457,9487334711844398569,4234670866842769119],[12707349254868250716,17192249626583540578,10297575062334643323,15274346379212809897],[11464192866181959546,16507321561919748636,12292824181903010950,4854829283203017429],[6552520117544810486,16587019088306324507,6380014223602582641,16116898179121020620],[119942016992425815,7641812824221345957,717302696007773285,8607632033190912232]]},"fri_queries":[{"leaf_elements":[2501389703791020420,14076127406864312740,1907203803656740503,18417569933779581294,5307071757172389000,16792569209757225975,8425058781132636112,8935219781159022744,870169705132167275,14817529512675801625,1207598623959368007,12496277630306267738,16977560372670598169,15304156407472793778,15126951314823818347,6156686147383490674],"proof":[[5467020337982169040,12575727486594351821,10758059868907110736,8845759579980259842],[3361531473586986106,4266764824713194431,3078369075173917828,3622546856673542054],[8967000011692871519,421439325008958901,5749667739905340597,4177504862970069546],[13493831006024332602,14924643343659126151,9491469051074569832,1884012097336344861],[16052486862294699617,1018249572757610014,1251771855399697691,13223121735954794426],[1970112541166091887,13910080562776108388,4271020767196365470,16564717787441853991],[5919707362404021583,4778763654081669090,15434909872610220964,1549935363368794180],[11695821799622209583,14963213551118593922,11254310837194100099,14611605090287114034],[9798739609677358899,1688101294256404406,16659611538438518503,14621611415398200811],[6378154751488147265,6935679216710446720,1455650981657100462,3177392118924407237],[17339955107256989097,1641019884911129666,841565240646883791,8922187284743974510],[10964313202421950351,5630947744251068434,7004972551600042285,10845042182834146527],[9828755776288769143,13986765444697018228,17216114589747554748,11737062743669164398],[9497522330654010607,10428746838159854411,17282797116643625741,9370446250429457167]]},{"leaf_elements":[6909132602220545781,16025639445929434744,10670877211598019257,13218705543539676529,15069036727183160,18342049521514945235,2556843597612419567,15657246572878725399,752084387827082274,3943621358299242083,17448052524450286721,4958813483959291401,18050596924089162304,3721603350394429173,174726983828314477,5519326662724511607],"proof":[[3628437659268155317,9234790331501395240,15616557718995280554,894647647288565442],[16213508039440870908,6025478509094000505,11293521442641383846,11956746888381366113],[15423360537356829323,12952557277990979208,15135559779450174668,14350204945721708193],[13102539876383318194,3190187871754798297,15636749853468746387,14799555736928782506],[16858394715021036194,7698593437561600718,10364584037157452271,1949457824421896291],[11311483403606437502,5094223803897947019,8066035407960072352,240499035953790595],[2941298264257650280,7954571707791613800,4068465367903289321,13075510753736505592],[14776554399792262843,137313972572654050,730836889369817572,10798294068820836149],[14572539141946693120,932423997073474659,2314406510198147272,6370293398431955989],[10995142404837032615,18037828248629944783,3621605584051744,18272512998774485959],[843411343929838404,8361740330644747194,2332379768699751226,10226462084284657766]]},{"leaf_elements":[6781937271617835454,3647677777660892361,11916035911590991876,6045350796018646298,2381243516354686422,4260077418757146678,2116836847776412010,4451768091634157798,18000594661244211976,2031164647154758861,10402646766542123227,14683908707376355941,108783359024292701,7251900003247662471,17769003622680185567,3511137865852884297],"proof":[[932718096812556454,16124989598806479954,1659010449606365574,5273955272793580403],[16038451708285473813,11972394156994911848,12024180544690141471,4495019219495865631],[9144300160242302157,9817475197421886963,1649025768564131266,16762885089350270689],[1209329309426784537,13297354449869796811,3774242972303149134,214104359704716573],[599767199512435036,1967984730182154248,11785011876590664411,4327671152219501889],[5667355671482229712,4260810179119353854,3301767374709718245,14970505800725926762],[6093544420987595980,9570713105163657521,16834300732272845917,4954962326226044419],[9196460362043655518,11124783458111663969,6628625323182741542,8138792676882935518]]},{"leaf_elements":[11633979649053666357,5329602135335445160,7867014123007230997,4068640104641616822,15647071449072303294,312665193208512714,6401152846296842452,16081367488664135353,16144238538932366858,6039606643070643307,8860647262740341320,15648203561033316403,7888507451127590299,17826703912552442720,11063989165958760757,3168410052316999061],"proof":[[2853289806887407499,887599467277488544,18184897185330789330,74166536668972619],[13906769319968368818,9787540702194157681,13558457436249390342,12843237014538744532],[1886952331324614014,18408455444181824419,16919638281214785380,18298698280380929486],[6748302237752748816,11050683019842041066,10744285173980642168,2830567593414132163],[4195745188892480400,1278917477926341115,858660738527305749,12026569133742582051]]},{"leaf_elements":[17243346552149652517,10882619986357177751,8096803201503556482,5222497194179763350,1473082545781564758,18086100824368415238,12291573177398886098,1525169808899722843,10361841926233051838,11515798859454192158,13069490598638279614,13771904632740530077,6153907696260295489,6369593925792411855,5785431625204876738,15730679172607800300],"proof":[[16997450673583468054,2529071262208839696,7011471064570615138,7786772006240297790],[16070927894096146171,7499309042979267285,15222708687563261277,7377423658769375210]]},{"leaf_elements":[8872244034292046542,14961388654118324654,5802056968775514489,18302383666416428067,3933647026650259001,8825851261617385151,8616213839298888053,10450361630528634353],"proof":[]}]},{"witness_query":{"leaf_elements":[89967872651870317,6908105101105829251,6901778784496738489,15914150729128863066,8665997217562753022,14362811782785675162,98329578968520360,868385362162262736,8767918815977794862,4544991389653057396,11770922256312632226,14937996368277260833,6369579775689241651,12128092874167783814,17194662216584927041,13401380147380446774,3453590094805127608,12776401241758449424,14867011116572523867,16025717302684258990,10507989718094469894,4230354899975811890,2230536359159856630,17165922194066547931,5012595509038441526,1265303782380157959,11663763010390177530,3201388951662067093,12235992744634635780,17169160053835602068,5480232556809232684,9266514494556129312,6262384704224773919,2486041215965749667,12918755811467075186,2044638199784882753,12322188359178276253,2639501128724732698,6525106192711440397,15247377130252939884,1408683122394610523,7012824974011938699,9675155717499268988,12966366190532657559,1296630481638720460,12343792298358717400,3255189049228324426,10057669553036890752,8907556987840360553,16933705225807265749,4979517696004717546,13926080598281688065,1651867259190476087,659830118839282728,7706180378415665107,13254381452555805836,8464150340320291794,5650323504468903788,8255289279451961439,2867912378589191208,7874901334811505831,3008403536079962742,5920001735654152932,6758896303196080170,5534709084150923792,9298648741985558219,7661914207631037531,7071473064786375230,10111789867367268703,8896244780702976806,4787799495878439017,8704460399541887932,11185628198689351708,4182226048320443978,11876039265329901115,3012536163727095222,12140897083151062223,14945902255428318726,17348426885044156778,1761945087803763644,12025378111802469546,6943683578144009537,3651853808293022358,18419804278854902322,16427541577918445841,593025554125078249,6956136001656151569,2796742799296004368,16483445755869449464,896900707124157027,4449335576844811920,1214802328001127397,14035087662196654601,3281640746061919516,2158038410552273732,3756271075871327,2747783705205769682,1364554755200616298,14730437433072526993,12122784186404092365,7887161763225731929,7638665603351598466,13765059609600744305,2990118209746596490,10939876838425634329,17628863977025287857,16150628791602077004,16947386073714742622,5359742694513807768,18206257413762669955,15650909733862854562,4470032797125237348,3228201081312261140,6993809199254163707,8426590365636289426,16737945203662598657,18024831605293793966,11510715434316751948,13386266083252725654,12347262837714610493,4426038386261839665,3110965136256554379,14740345778495012383,421745367510468307,16648436046603763876,2630166075346636658,10755729011347173546,12076781255031204408,17793023928562047782,2541833505451244234,4518603774940694860,11632985558088386536,13347051759852424894,11072710660895919604,3053876651248558981,13326881672132371588,14335119940166888575,8383317255343257084,14674806122636531847,16509607089443245391,7225330687265004236,1790781543744254826,11902286818610945937,13533720849307948766],"proof":[[4257287115014237644,6003578369897391909,16255798210955597457,3728066823788996212],[4357668104660622194,16498072388737038771,10560851623327045569,4926658614369659017],[11529789067818722603,11600481986331301162,6718333285515879485,11725471837143121354],[15499371089774718259,11459804818401346562,14268397404867944205,7845430151143451854],[9310015964216110917,5830364953410778108,8194819585438523466,5777872503993747539],[18238633539992683003,476666384747428854,6005566768965343132,16534177370993111451],[11704634559408875859,885551969651876972,17874576854578828995,5312362383589183932],[17405931382780810328,10104905975901398427,15158790577977166703,10880772732455457894],[2263797313009348988,9655336063054334049,13890522919881688369,7907961999315327915],[7858688894863052559,12142642974996255468,1692554974927177378,1117546793892434648],[5699052398132611432,11427785832354560639,3283494660483653988,4103543214154779006],[12483589416193753630,13723723024991474018,12437136247710929839,10667524215229059040],[17650216392051993700,12827114849884510763,7881834984698370269,14104999393216020719],[16049153506296600433,7776151352044540480,12111368638492284519,13567202420710379867],[8222120764870362964,16058169862729838915,4977243498242341653,8290090640492166098],[10239312564110271300,5006577322178539158,5122910654177033938,3835418971351753017],[7496285285731941015,8499315508080853662,473345457475729204,11805382148206819207]]},"stage_2_query":{"leaf_elements":[15224291387661071477,6716108716236771606,17848860281886141489,12065985980540105953,1957499214125528271,1173306498399399999,7869571080655567181,8886889289725386898,14682689671120884672,8655762491302841455,8755745081223880710,1095318100200177686,9867911259164539755,6178745210912237355,8877308236947610663,16596640042488777970,2559433156815115368,1959553638423462563,18332252073265139544,2187984043204258999,10720030035144693918,18228624130856509926,13857846377725350198,7988630845750370799,10995497801391736296,967548787487921301,5565162461788513910,9781022545406247705,1898599716469903193,4034979205361803959,12059537084568445652,17199986578760974086,11828642849912377005,17040892673803422822,18098170211775094237,10258857416037708082,2169325292608462438,11628443030592068916,8013284243963921206,2786521400456972611,11660970023943930658,7375116644605942078,949118126536254922,3391259645174669760,17133621185175276187,14396723012675299942],"proof":[[1640020132309910230,12611653420004338895,16799548593732395502,16680043351358159324],[14467933545417891881,6139920013027329857,7990736654694685233,11717579893659933314],[12270492050438894583,2854584464933405816,6833741245649297715,13226588923410018731],[16466282509145223199,12587084822837387705,10515988150211316227,4462809075839092175],[148521902441228139,15063275322313997494,4609186119910597655,13363633279414376974],[16080500161876418302,12921284021339905391,17122182753872519217,12011019685258961728],[18018921188992577717,2996281020284192418,12468150383157507544,10927068768359756147],[8925755456467926084,11665514865126071812,14738373136990335732,4233166312730223617],[9209086553941323732,4816217870200641149,12910274754843805588,12365176413305547559],[10404630644743583436,1482955822924987305,9582584806607160461,16872719685335950748],[12835680616693192964,13184854327565537119,17299526998781068360,16016758264827232356],[6021955669525589004,5627090340704992595,2178564171827173690,6171085441088612473],[10632515397094462259,2233824380913669089,6855630046946104889,13526276395083489520],[11856625878131776960,1888718121735279606,10568654305931759204,14602455233680541649],[4081308807093744791,15560394160628889983,3250319938231782029,1622536602611616920],[787955184542241652,1113699728185648878,4417897363943848764,15122575123948571050],[5142946944478076970,986898338813114171,7166217363221429812,161025064090010519]]},"quotient_query":{"leaf_elements":[6997013435089088118,8718671303377955803,295613951774416296,6919511541277616131,11600201704186180034,16562721489806523910,9907555462466334136,1374714025745127997,6468994726945244991,8349270109784148097,4983404324196757674,16176011392236032654,13228171483324651194,18409437890090775404,1930838443922330532,4067455541078245906],"proof":[[7613164625379625608,7578251992311885882,11044423308075939527,2774113352994404558],[14037206845861697797,3278226895666926073,8505721749270303968,6796375359248241674],[1954488930329258922,7055116099970114560,10171973675632729837,1101781232570181811],[9896330421171537598,7474435380975524078,3312050241752139866,7041756878512855217],[17693760258683443421,9192709740573530956,9668455363203848162,7717324178479163102],[1951810538268473849,12224354903700937310,6241058955924526594,8913564922016455137],[18119599912292108238,12072984789442239676,2955366179069557293,2860424554401308544],[15327192928314468960,12127538318379770728,16451410042466607869,2256623355759878049],[882224348634931532,4689526703743431343,14849420150864924471,9558349468561595201],[9518572456317406002,7816623425087143714,4945563432805447762,7848481852494655140],[8765559183201390241,10350966286088063547,10805150789961228793,1725641481352375137],[9123285671484097084,8646151273998085934,17052337656149810425,7285728936795240454],[4135773072829928633,12304344392302721859,12645407801716400599,7088154180756309820],[363871782527219260,300846838944945514,414401148494718737,5141649963397797505],[1163061193029542706,52449656932076410,16026505180788713609,8209664368477613287],[13843971056907492895,74463908173249504,2393726805756181154,3274170467717181424],[2446409545039768405,7227926324246186594,854384392011511427,8044654895162765687]]},"setup_query":{"leaf_elements":[10325231653067299043,2241686367464243925,16839567938708233278,5749313009753819946,14512407786283629340,17511194874968398533,693122855652431567,8181585812720492423,2176461328998630566,753525249064039269,6629441216191414850,6714706681033006244,1742849979103746434,7056144721480150831,7617713102024683949,13700739924347183402,16525608879936830055,4272314952616004526,14115266306964782972,4944459007371772848,15005261707970935247,6692771845616743816,5800360209554873490,12269953480282064858,9149472509052267949,16696070589761988795,5896447066683442847,18432973499558451262,13961525821855281219,14315206881999175394,5708980572563139396,13483425357657811218,14552743523394626569,9229711561154372818,137717831393417031,13010554146599390878,14205018366273439646,4732668795759879595,7821416605822965285,11352313292881796406,13027292996140558844,13051326850180248977,9433426936537891534,579053142155727711,17995235825135741648,15057620627401183945,12167827944216867789,31617084440023907,14426864150731987628,15219628170434787567,4183582323583215449,13892642299256358387,6641971017987251872,18256420402091468758,10422601794615593841,2456912082771592530,16169826080092143014,700735844066884027,12981487513061543302,18042071878642564533,10755810631731383424,16565216147283813165,16929721264898398745,1890127929111376925,9603915446092789392,5528816950073571975,904594903642785631,762704812725578588,15875647741869581750,14409001809421023943,6488464925932242472,18419788072091123042,11970509315203523742,147286955934262304,779777213289943614,6904043176858143741,16981068719752344833,4211747222277643975,7924513136299598973,15412163285217340103,6065200888997691057,10286973725443354081,17895670205348169852,12282880774968028580,13785777062395892070,2301101969991333283,12755182222245837834,6626957481110404839,3878435498678534556,18332541033037917484,10689530151013517943,18285279196177838742,4125320274813794912,9962256067997850456,12308589972024828601,14334212042594071892,3236465352778159876,8975126936208253374,14471514773521092904,12012555428584577504,14038459059311463989,8457175982104476994,9856135434467412298,4725101324694139382,8766079666721628992,3936825609290397376,3420021879434932819,11408822352408732213,13836955752386465713,4746478212131432438,384424718783742896,8284663218611193227,1366604677057908889,6668179784808883193,65040993750650213,15561516153219689824,1149015450244144173,4281523092618165885,3159584026437114392,12162455452504100311,8304316403956274755,8654139868146744403,321675063503220351,16510277773828249481,4667927546054079651,7344689982211075551,601246307428623631,17926355493943681543,12209963397088022884,1757873439780260621,1904736400364914429,2308622347775085319,7039139081865362667,3364278427807555486,12869598636408364667,411567298521736177,13954487570110201386,11359925700789273925,15262427801334958891,15002994855545759533,10401351058945660679,13017213471459970947,366156653671109827,8477558145293806573,14993371602763381153,7805168277209471707,5466635489702977559,13088580875357492858,6571964506205155030,7677152280166930864,6692374282670624087,427639224135231013,15488307593874652884,15747551172297546847,8118228939117368380,2970946088092989632],"proof":[[10283198215423559473,12405558758984912018,8992566322511299621,7347108776276176468],[2439562314150686760,10970517888355400652,7978450621156982660,16272663539390772060],[12359298150770251955,5718638515279174460,3522726304314908633,289952596158186619],[15715040986961507779,13126242574355498101,894949062857028293,2337243053836265012],[10276390938897680267,6349035752098119563,11841092221388175590,10035007557667493240],[13394233424456938145,4050179376490601808,11031839107752045944,1692055441682533179],[10454750719922391213,2804279728069348383,13512646720380759037,10594422746378918191],[14640168089854227507,13633008173916330715,4891271519553558178,8292677760852243777],[14380675338270988624,3558026316242273914,11726083312140997394,14180070397032802197],[2408120843020910857,8669610764523684779,3150589790021397626,14103784177086608270],[16684136845158710216,9370427378525147954,16590428752581236347,10521800959427581743],[8884247200289175276,14772313642549821518,9491057776887557516,4842723335625046708],[12179998991635418173,5200527309209417750,233902841363271931,7230939229685944353],[8244923571387786950,11872924754686007359,13549434129534389200,12327021718980365425],[13624135745317289321,10381180933273806530,1461712731872936679,1690784280890558612],[9389581839137957039,316013109439099625,14677708382208496575,6198689805279676784],[605714035794641895,17662932137553231899,11267508260417819854,16646936890915875827]]},"fri_queries":[{"leaf_elements":[639721065025299636,2289374591837945607,10224254355675464531,754505920256997176,7140441484803330682,14136461814804328717,17888263090067399441,135750744877762161,429909162293936260,14182349270904862944,17823943100350455476,7558778260937486885,6892831378846101086,7059692113987808269,383101886122146675,5220325588027997456],"proof":[[594320654804899467,2820425734856841530,13486490650672149257,6400406174245131190],[2031949627237475100,6515927791608400961,8691846718861444339,17625470133457501982],[13524314373654737290,13379488015061371020,17800965186529341781,14334415721052575230],[2680836191317829816,10524532347098044387,11809137417717307028,7542563387212256572],[12823239140901970932,4805198018104998393,14046399761115627111,2915088912426148993],[16982899892044002791,12602389452256773642,13939060003321385569,5668385373975367467],[15352770933163267961,1941705568571221202,16164093414820208710,17113533546613975447],[15652081602649850473,6744204288674005080,10295599114002258948,17659284184523372330],[15340800968835413330,16404029619764677774,7406199465233134860,17296028792609697259],[17489020721573326563,15694585169205415830,10805853398038720495,10208793472509955405],[517212572502878288,16756443154376072998,3516578759819367722,8981675593121409695],[12513480571307438591,2389368690298059883,13311416206934553406,12668389354147763287],[18142908917818622101,7494272579818419620,12558431376592652348,12182618765900537677],[12622435136088813530,14088618649142867045,17064798125148309400,9557743827860148380]]},{"leaf_elements":[16958726938849683403,10875530189931472805,6054586235927586326,162432521457988459,1151014558373158571,17962740469277268716,11030068484039962472,17731123995427297436,16684204601359774365,4308670232432837043,2914589022182390203,14533848267084207505,268273182689661692,600581687496789580,4080509580073401445,14906367988793191864],"proof":[[1459850088972214919,3986680624316605514,13400098262234586728,5445993222336769697],[4213291846039844252,10965957485328695802,2250057951549804409,5162799714996935749],[17877257286514845180,12747361025166555217,18323825012785056325,2866833786801379115],[10480143162542983953,10005264364751487890,16249199396454902727,16847756179724237210],[15373747089165342149,8446417246633354790,2168933626765629604,10835946271035668339],[5229393015382659833,2426544411635041687,9037544686632232072,12758221788714885245],[4198322127273791792,12197865292148269655,11418249522640573987,12452287583911006930],[10295839067717165754,1531392427958963753,7666834954631640743,11890794952648870106],[13054918815962330582,3046040949158179645,5184659745103323578,8974409062646442042],[14295434801479632874,16995200288116348859,776903632202100390,15575553808252629596],[10451027598658794289,1409017892025884115,1441116716198485217,8515659924305447215]]},{"leaf_elements":[16716328354560344446,352976601230935218,8918907767824764979,7883865367097469026,3183233494927875418,6595445854289651161,11842128948874160626,14769932185966126402,11166065472002918850,14403896218524925298,17821821115154434126,2144990707616247106,6746427903431665035,17848350668072853364,9132406899254113266,11380381621900481103],"proof":[[6518156175867497191,18108882262740203156,10412470455754629989,12148168809783612643],[9612512744051759379,11063623265629350143,14204576946605912292,431899773940301855],[2334170608520906452,11490871706754420754,10094319662175730946,7467711043021332095],[3528946676541384931,3262447212503471551,1860607067501612014,1868076466271491089],[14009293596536785735,16805996442340693969,14800350028427121020,5841548135054892978],[18313043610486582318,896193245136174137,9483790698188484498,1647936170584199550],[5536165752182131798,9929382143180799801,18423748697702302070,2756294044769054717],[11283839272348111020,6063065441510746998,683150689620058394,17700376312019760627]]},{"leaf_elements":[12450184476550690660,11646436176910957621,3668075750912987109,5336554197795753099,12084941357487546284,314948721491965028,14362686014051087646,5597875912493762640,10923450970435077795,7672452794483640269,17338625870843564994,9218024164185833826,2081942871813725014,13201555051331390782,1088948108045486010,12407155392283992402],"proof":[[5032422087174105101,472624062493680083,371008152380901965,717376467793621731],[4978717999909031485,9322716204993597528,15541319064456129100,15918705084759384330],[13685048358902440036,2980665525301855879,13414442736276745285,10964997179087722071],[153614523888197626,3831270908457420952,17468571913123373758,12003599467361797195],[3577803525313655451,1801329653411590312,11522787841478459221,16021617102567237239]]},{"leaf_elements":[2355092831518217399,13291208007397555096,16112562303614477948,6283778926193439922,8015297497572453768,6144906371828301093,10795234163397836453,15317047556002133258,11803210352662175508,13964960512557523158,14371730922491567815,8615468377972021231,5245619743684049418,5589714974433316690,2225411792490568876,7951315786847606418],"proof":[[6659689063559870066,342080100962376558,2937060353910455897,13102301432676217499],[8172119166490220643,1715341192280120671,9751970656955179684,3510476705473611346]]},{"leaf_elements":[1275295786118718478,7488170357634863325,4283449960128273261,10193008459420986025,4238185187837649128,6318479223569512088,16394860438500661164,4148361282767282169],"proof":[]}]},{"witness_query":{"leaf_elements":[10103937135367643045,16245636752330427083,4175967288886164822,5091712382441382802,16917321570617753297,1727233950558959544,6802177350682991440,10653413019138639891,16148253630386747634,11390647935684857860,8767043630066394335,5196572033797759985,4757898936993272533,2857239085722438824,15505939548105547449,14284464941359236623,11483636430579514958,9091294837424349878,216398330710442304,10232404764692925500,1777352631262245307,11651946378707404827,412457747337558582,13992533998903917269,12693621436400077498,8683686611821243049,3569513722344576177,717906220547802521,1902370097110706758,13351715562016484619,4139901973454209787,17187097777143381359,14525724327968908853,9151405501203726240,12455433364711755490,3367124800236699886,12905516695539784943,17821461888437094714,9303308358069245265,6887936493630356756,15389536879614283203,15822308507186698546,11794943389114164435,5539216329265605591,6767140701352869588,17631213320157519955,10780334487899519008,17847423028011337343,18400255620093305329,9379051187239660249,2435094074950430720,14045505925784763958,11915503514246529709,6937722958839297765,14271663066532636065,6856910891654353913,7579735050214589435,18283163627868278797,515965981806070402,12724029095859853015,16260165732481809957,10126737632910473137,16002196353711185284,1859362531076368815,8439143105787720866,12016537889772752317,14996542947640572956,6994942128645696448,4429628195257899627,903869997523835986,13441169160226529467,15685727197150927865,17037323402461832727,4858419749104916047,4384414596986344172,1546778669459913295,10138277887215861050,14714847607916563247,10592673561765172713,17533231920026012866,15132555641577886595,10330038612646097399,5891076126854593583,151803318267183190,10780460055282389632,8872328213976145495,12842364680686963731,16587527826205116663,8670663554613243874,751810907518668755,10254540880163827858,364803792196053527,5136714634075443051,9626607881332885607,4947692940001503890,16985109702073243516,8720458041559731417,13562139441885315161,7570218791536571606,11052179021110461818,799512851460729039,7781125166713013022,1691147130940681373,11358114318757473722,8847468016486884760,8684290678774644230,17114756978039464171,4501321287745984548,17802681511809156982,189067035335350311,13530920499140950765,4190406070376345520,11110511820831904219,15257348800516483800,16335509270860896395,668657436345948530,1479408846835752921,4374818396513688828,12422009496086281328,4957407825370533884,9793515949509047400,3330711532717306170,15559539080200298097,16615171742033047379,3196936436582323041,15845576380587541283,13179797065309930106,3736281385294018406,1861347703464018649,8434148610181242988,9546600501385982781,11166713306090834117,17302841805953123618,15625547638184807666,9871666092937856538,3843860694178208906,12182693978056258169,17932142945926892099,356609210769991268,1829762101475053662,12125520530487346064,15703431522899440888,15461039330153883922,17904378441381196978],"proof":[[10287959343737565122,17362557867997963505,8162141352910438402,678119683065295665],[5722175189416883864,15520988870843580268,16469144947882539448,2516543360945967038],[12579470103243065573,5685148220534216468,7715875411490490525,445078276596018720],[4968106824281009581,13767547315373399937,14710864095515300375,4330285176684716416],[12890910002286847507,635358076315014788,4913118528003592135,4816563635226574658],[2442641185446322332,17990519373188917135,9147824050876075532,14824078142872597925],[6028040183965356593,13250830683302357470,12239371944225036231,2972334301352352634],[13751990731954733872,12354525272501067628,17311648953151055923,4426107354542687465],[15828720476840968389,13445196626029726015,6024812808419357230,11745964293687153585],[7086410697115995561,15195351299126914284,8230703624254784188,7674288000897716541],[14882756184268571186,834279933322984070,11619618294482603014,18387627240586927387],[10098054313730450574,10616762780574500888,11467428010735665759,15910208349944339941],[15500083863935628756,62174415362201978,15778199659227445871,13896038984894780683],[8713851099241618597,6879737947265293538,16971636493462110017,18216212207037349975],[695532765124306660,341464608995242497,16015505394538850808,10728078421172540651],[9258696388259646266,17598517151173297928,4711376074229708222,5650504760284536662],[8962983601327175991,9655400076779378322,9372067540546984264,18437205832166210823]]},"stage_2_query":{"leaf_elements":[15488837898820948271,10089193853627146769,16653517358172290019,14421063784564777429,13718181868504382708,11247800903549195639,13572667736087321731,17862671548635698851,17015676141161730906,8646627641236289129,16145113505870606361,6230930512610379577,9957321038092411864,13036272205206955454,18057359323824104073,3506468462822085397,14630749380285271209,3735105510690383481,6186144752395070062,2432803412706414424,16684151154907095814,14794454701887254288,6868555291655311175,8743434760574030800,17584455429105687892,6992485436431672692,10230755129537232122,1013350902973186898,15225687996045114695,16302808739699599096,8451345556557870797,4146850028175076640,3655802134555031665,147937557413014210,13531325531414276757,16561695661791663782,13457041646508775606,4456806874075187681,7389306799784947554,8964933459447392906,3470904795970702707,803850659950032541,9623670638237421873,11111413349938037695,11571490295821639516,12589974832136169142],"proof":[[17218109392326281371,15482181736779604091,8074614383184901703,639862257589194988],[18046238421035331175,10802995282890033181,2744639655749453760,5189556911564630792],[4138525210467341871,9624266861620766012,12717967977422044599,5151200478997729815],[2902181355610196492,4032419095044091815,8872697650068643913,1497780319888508022],[9102520377494041148,14419142147510883435,2875685860017887469,4302784553016699978],[2585501458938331079,4150949866478394928,14150861479808125934,14239918084550666107],[3473959084476750002,16550612444922323250,7420627378316555937,1621994856422030468],[16415957790160877063,4380621912195872886,13495574916644794045,15376532295125908343],[24092562624495200,4984549132754682944,6465439027557845983,1316028967768134898],[986499831180100312,12977516759804682157,14654897374847771905,5002029900591184796],[13879235709217028635,14249713847368565212,2852121529828353081,4724486412058607451],[562321894955629352,1701540224692172022,16861095451603203175,3314108434579614975],[4271644993741361804,11449436330090285612,4420628305054109973,5115469046919128046],[11167037854456077198,16817416028712524762,17665022390575497747,10296190971746387664],[9255581476233952050,2450983896953873997,4193322371303978493,13904401512600849874],[6333286269642657053,17140459283162829619,12326919124775573624,2052845357278183538],[1911347836580775672,3246100548763748938,467751161131197312,9129819829973384756]]},"quotient_query":{"leaf_elements":[729396258908406879,15518729870174239875,12262141638755049217,14558852219440716228,3926958752464927834,10003908218835156667,17898312954488947944,10198922136352105023,4525298106619790483,13887975691694877812,11605596147685246343,14537605026095831675,18176694726091157953,17199374837073833366,10654938842231337822,1778699880953528048],"proof":[[17781904601938778490,16575909128868014883,8597092905549349149,15022797764924124863],[12420425511213660768,17799939783921771102,8983814028306962701,14773670333340247239],[2626660196838519856,7980389102186099632,8510174767806626942,9088729199298699241],[7632821536974741379,10524904154102964657,8028064243824150612,12460623597411059275],[17343045435849671372,8314738740966048260,517260662439669957,15922836409732978491],[15447188652451591981,16533544299353443107,550040311191157710,18079426961645739595],[6238355071669830316,18112409451890447369,17949533552366864031,8655429254533061788],[1745060213088763110,2940883958245612529,15355173213138484141,18165877597620327600],[5784837089021559312,15056553922139775037,16464420733731923973,7252499228309981736],[13507470921708366462,5746486226002890796,16026720904955166199,4689656169665791900],[325871711681514731,18202448011454382424,15389458146944038643,2941811906608192458],[3683382732898915629,3256176748332943461,12188151602955475597,10862899426410824921],[12951463030812972840,2681427665686784257,951796667340200489,5224791814187363051],[15645135936456238174,13173261967170265246,17704915233701440473,7727053493333509203],[7917421530150943644,12815583707332367767,12710402908285206198,10774468467915163892],[11730836521037516166,1828634444375258535,2019516141894869084,16751645220763745696],[822135299882928769,6832536832869235243,17165440014740463881,14363198558232023699]]},"setup_query":{"leaf_elements":[14369919317318682394,12027919839500373916,80653753202234219,13606025913651613453,18244823862574918343,8933487133780494299,11429884618910521210,10664503936842104706,14594618130351545278,3303731329142456135,17953231535076469579,11817033619017912149,16034158021083891199,773985367850846693,1869986436458014782,13707439490643972402,14177385684322335320,15994359873027936606,17683091538081525430,14284289179605237743,13344911524788137130,6557923208383362136,5849949736844809716,3596979486155182669,9038639497919942898,12707598409091801817,9828869408531036299,10482497102950141483,5704681429375913894,11489135758760587008,5027627712830904304,7082235142666588332,1440709161941405032,17777083417895103840,5149954740800430097,17043375163434119865,9615333815156995301,349679176775714600,9948626745968863262,330459093465360457,14237261224830540756,2709091285588250994,15282212234962177265,8923243370938247230,16680485705192242929,3589515051060610420,13167260109791957826,10102218456188420732,11465735895042003870,15088185922322289850,18428975131138149182,16336696267560244151,16494028984066044388,14333277703193826272,17370610660017606385,13124075737382662975,2105396247306019762,17924146675992130950,17598042148980856420,16944736998005775034,12750301896787038879,64513803733248581,5379803482728766245,17871628266833423090,6374319651532454513,13675735173011900786,10362172740546484225,5459740119711632941,17080095488398905316,7500752626154586480,155708962918232536,1193873126580776494,11370477213116237265,16135629472590337408,5896361978460531123,1331249549346169108,7430813508096069536,1721961933687337874,3067029261784385224,11382080239127446923,6974100263589684786,1036357885864755546,1284025544243216389,2374407124971467885,5382861075024850502,17339167056637814953,1347133023743859954,3662514683324856351,5341534007685076472,5685576929827909306,2293447092220963890,15489603634280411211,4648094380751918147,16018794056108444682,11894483836199105622,10872244638602875498,15147234547523096117,7896301149124193776,4787734326575415810,3356859534319604556,12123711667705354774,7419497324482952141,14042463745030377191,10982660469156917492,11641739284487715558,8688660297415564401,7257450809111234695,6983567238788109403,12594257194140177227,304864557714895076,12173941192208871174,3425809271134470648,13618897430687760529,11003376972561593738,4120454838173099774,16478873624717886190,7440513697232267683,14063920223647084521,15636707017201711838,16288555720392431504,8297976879927150598,12413236957282163773,15361636172898317016,10916652938307545413,15883856760990605566,351064447354340119,1442796658375430008,11258539981440871004,11254098786818228224,466798096345881557,12651966019955566391,13054519713746234684,13953773183497795709,11403713020579059257,12067205466645138267,14506041475189135340,12972680124026645259,8645389517449710828,18326376440165085810,17744111113909279269,3185484845102834904,13900852513675802412,11361037630194691276,12435894570710883816,1791997065590714682,11055263435408881351,8545829262350298285,2394164441253680346,1272139496133501597,3300710175735132561,6511185034385585875,5277347675282821250,3395887912333683185,12919595232124649086,12056317667618280797,580433573398595071],"proof":[[4483624179195711550,11134539804744152522,3127727773115684042,11499231045507567703],[12672121253229312332,11825995381287382280,6991360780619485463,7661908085886103923],[8692883546872777731,7335483993811544084,1988535028692393921,1894987010296123228],[9717088900852716198,12647416279555578023,5456508205183604641,9080628189751473370],[13393871907550625082,11929354984337336331,15515738474799210807,10380900804661118605],[13610130413348009971,5701056970049327270,2911674727138568884,14355635199124780790],[537239931004294239,317918705751109260,5119912267970096854,3342962226206644102],[2717166358448881605,16940613330620975706,1434307633696739210,17667006029072043151],[5849954905212336274,16588163536470239892,13218337957940275912,5784775175966431760],[2117019178975668921,8011139974160665403,13244324421241408063,10778112350208057548],[17533360009427319192,6535307511056054837,11890756185573778956,476945996389593581],[5480975395847658808,3087694988336556855,11752692849787194029,1024216750412542154],[12615121543682662578,271702634884249449,288561472127345304,7013247396501557632],[17907800137443519668,16473147767374197707,5325104696977301332,13530159621636252809],[18192591667847856473,16892136302715642313,2782808864676715606,12945478483836509585],[16737497394283627010,11649289685888163732,10908735700891821988,9254629283264086320],[8150671396367591155,4374957965196029991,10091316552250686626,14304794448001423245]]},"fri_queries":[{"leaf_elements":[2688984332145240842,5974059538009688391,15028518510354550540,17119397580172344994,15870138972385257838,2738562232495737934,14588636745658309774,4648837414542907381,7078605733503634303,4966881488469524130,637614172313042075,5084137940849208823,4251734956637819726,5961381083027862695,15288729532650436054,17693535424110716575],"proof":[[17601201739508807114,11283483527909792628,4102115942734901246,9804370991610857797],[12938758605980714370,6468544372986946869,4052923968989428599,613843849772401497],[15231430062544278112,11365531317456746034,10267381245609025684,6719822966677587155],[14407107956087338168,8968516269958429293,6166362586487303978,2816239280570444867],[13275595552761072421,17185125458020885281,3148721836972539585,14658597444195169664],[15992765488270945194,8070107102377727701,11698516413880068362,15067269272228089884],[6062221371033821333,7520882940112049630,10935114825855043835,17723407498680325111],[10701185819551666010,9387048820467167486,2854094012378037146,16039150942167439376],[16598578115697125201,6230291337358702363,2027282395789791044,18155964451596127207],[16037670650029262624,17128707072798064815,8099398004065816354,8228809220793185690],[600692910846813293,18209229611358332267,8461107434019772992,2709895249595952820],[3975274358366625065,9064316847339186782,15622777942613490910,6563394446599934845],[339703385633183973,7670437397318837846,18048821532852590125,8406083420087351532],[9886176930643768256,3509706781999382685,16706751567586875992,15900181631248865387]]},{"leaf_elements":[11264768286345739425,16300142439039027803,10039987132815482507,10581628548044006244,10173663017241414788,18031045119316271166,14188603177845349747,9059506954586935829,1172043136762673618,6481793174958795024,6721833684362896380,4882693801513802160,13486018016342319278,2957254418013125134,13656013287795060256,12467802584196914563],"proof":[[16368713699279367425,12378125414964348992,17679396954726709780,363605134691472508],[18065873691607918510,8186501908019026520,14163384073024019526,6421585428067432488],[4873611790211349029,1393320399222261414,15030407456672379659,7555384246072424951],[10301555574169398257,5656600922192556408,1360192692177728013,16079788734472766617],[8918327358327346540,8767390243313822586,1955290173355046315,5024192789646036409],[12935828821474535165,16881393408809613635,14535291916730414980,16255811343837086291],[2403994057691461617,1983780140900142245,283202185954544669,7851427497218735989],[7156650460800415885,8843064734774087436,17620747038090504003,4210593882631255891],[2004138876243440554,4788271692036112291,1550926504030835515,10812846577480743109],[12841953666056688777,5361563003631872390,14660902111531508412,9774313833785861662],[10540896754816519323,1746180075358321372,9865956469169334927,4589766901983917581]]},{"leaf_elements":[17603753722553089296,9301034798236243795,16916855912690794146,13864908315531365093,2292409066007584088,3327874390740034171,12919768150855478535,17420839237369355841,17836538040869382104,4016232385227729698,1543116770559892357,680355240463479643,16368799665288922663,7680433903358060899,1367126880062436625,16163509662206121480],"proof":[[14453357952105119778,14989955142554784453,2838540386172792152,6701495364574676006],[10550394588709288355,14338880985488472740,2745197349890462286,16520485581944408715],[13797713974518524619,1567203709141465983,304497890380872748,14320304027893780267],[8756104265064915261,7542373922964147531,6982944695127174738,1582665167128408312],[3049201556508476694,1490331663946983883,15610605595668672491,12623196003885962327],[5710779744768831729,2518887386509994917,8949810535837772395,180965953386733103],[6064294541870818696,13668918464227909034,1418615694861108410,14140178517947142363],[11336173358147927605,3544125422924662561,6152060134110928826,10783791288329227367]]},{"leaf_elements":[17146734845235141160,10975568231352595133,3357049901723747271,10640021222293645429,7373892338385256625,2909001076622652469,12703581352181517893,6250324389935128398,8040068781618745284,2884540022163412791,13137172532350670275,1525986545850604433,17837083791065818596,18233817687308582329,11720112969296031705,9816446217956603990],"proof":[[4459294044518147943,14767647655530432593,14371843798494457117,12040332593051505579],[17175456382740162649,16593798400148658431,2798136215757264087,14204720510408468849],[3811680734306935958,13646341538164981139,12401168569629545345,3916256778238669042],[5214742837520213826,17181281553215454143,16067227234442976705,12411500705198646514],[16976949461203448459,8268644666328080056,14706620297076897348,10709889567794796744]]},{"leaf_elements":[10594062497747178768,6384452250181563199,15120224220169110739,14257094230388822829,12275186352644083754,13115723322657344614,14792667758968283071,16646530487404452813,12684016013882922324,14181686528498407957,6147051580776037258,12391221252508774151,4652914516088146984,17172279302994484655,4065624863213034231,9390611246858647274],"proof":[[5193648225052607111,2473523997048599759,9699913891496939882,4155138417900049372],[14983243035340635343,13554744403256603391,9231851320950367445,18031029812144592016]]},{"leaf_elements":[1275295786118718478,7488170357634863325,4283449960128273261,10193008459420986025,4238185187837649128,6318479223569512088,16394860438500661164,4148361282767282169],"proof":[]}]},{"witness_query":{"leaf_elements":[309336264980449909,1448502324916874813,3631426876397689173,4485388070956869117,14202242212296860349,13364390882756842434,15484475606206948829,17091218774415903105,3447195371219189260,18278935269628851459,1293350983581690282,14323320810094713247,11000691075897561397,1683316512256969690,16085561952184662391,15212778690903664211,10327745482766766823,10241192262018550295,3854781001269852686,18168853420994299048,8733884530004277205,13782411754291672226,14124015036467563639,2718813763309417114,2192084155715250726,4377836490750545481,12058510682844592002,13610620107145455426,15822916812262841133,12922055971354347431,6291596315628358848,5495045700119691104,7683761478293317992,10978861617008293458,45971642360206479,15421112483444888607,17769259602871986133,7894766737832643489,4084353415443074930,111009080224424532,11788982756943111056,8591200587079680604,2806465801404940869,2734941829571324051,10917499363491659905,9841227832073464419,14880891419383435377,18290701238426510766,1138568595311164948,9652377641384255895,4393920085825105819,16171437299203029592,7532796748313627311,13740814455515572890,11167433891514959026,1478460076437027322,2989734362820861691,12502853905496150030,4415503292541985076,5989759822452937306,15803034912304964785,9920095982728968560,5792107425339961140,12977110688733297263,2051281398422602175,16149802747521752534,16678119341843614512,15549426617739347648,10024447701632282784,17406030668192870454,729762019802325526,12036198592990091518,8925162235567833990,14377895266720031629,8114952434108586791,8452947577443632196,14870525193340330913,5011896332014954083,7283990294194083732,17234278473683654068,5370135472156711465,2491705111317412858,5473904408615676624,611758561269727516,2127410914237411572,2865845357950560601,601655743264712220,15880329453269235478,14365341403347045746,4000789662184438873,268769504947950137,15226607672733361900,15036592737810963112,1508444940792265281,3640343451116383549,15934697154195239213,1881042083820997428,14404059674787482640,14250486471506809653,7927509824459763117,5545760102516965548,8835134607641476202,10179621093514608814,18246542858330373546,7908647130147932728,9325146527481362318,15091405439140437882,13716305916372895182,5856311412404763755,13696379484500765101,684791972439841299,15557765291670575332,3176095224099758561,1117346941927809841,12691088464880208876,11678113765184967175,11696041139638992468,11234203022656897573,18431995901796110156,16810243916887197874,1158454017241154923,14483200713784712363,13689417512224614291,3400467194350059853,3279249241435831020,4563836215736250058,18190168303811577,3502012096681409242,7060992070757743728,1922283093760569304,9991686383887172903,16656471460429076605,6590425368336907991,7113223375125721938,16707918177767330302,14531877669417328613,15781389806782102809,17452861946459601360,9795615172133755293,13962815780228897721,17576979688660659400,10126216850866374212,1061028956788832171,7668510185799506345],"proof":[[5204256115385470511,11209679349196555088,14714637585812316893,7999321996502015004],[8930859530892030719,16007009308180639868,4204169389951818174,17818187317574209106],[13570377294992382080,15960320098928960435,15392922515369791950,3865866629099119504],[7643421824084612141,10728984090314976494,17426591093352881976,14119814565082757304],[1557328246280860837,8354015300171930256,15664608274004510810,15589133333039935464],[17448878034213126780,12791791610071434438,15887409664808346262,10961164293059724727],[16800754784741079859,3868596933420409763,4981932258693731475,10666971207197790862],[8884216467274391861,3995578604677450535,4777223489395717249,12126666940363537215],[5076647929354704841,16940845631709946124,13827272909635661033,3562635058173165227],[3422708554368606684,15942586053449943590,11319818429460578651,4484398718499380998],[11962962655414622301,262139573544555055,9131405474370852092,15756187055432766371],[9221386656999573377,5634749593643500557,15657506097988535563,7475885320641773326],[2822339873732093868,8392808902048373525,10867033706154981544,15723169382541379038],[12362550512280214339,7301222296323467027,946909366182026066,14917149844365441035],[14764954617591504419,591994197062546129,4764821114693595378,2081082897634909172],[4660153396613228210,7319074183465722094,11910719470206088219,12234748405667649771],[7668237077592825004,5957116417149945187,16233895935611871800,17838538969050014477]]},"stage_2_query":{"leaf_elements":[1441033384032873978,16468815482709378717,16824930455369357653,5773033628902224401,3840180341331798916,14801048389094369784,1804117768086369076,12840923112354378205,7832072831902929202,10378929369311471248,16164410849654346273,5304061405403327348,13816974625286681530,7974430751206536447,2826105896962408676,11647646663193252533,5808483183286427540,7330734168222272402,14365921143152093823,7253348573565017436,14896487696902761455,5699788245519073763,17749340984165066657,515970478235646130,4343466521056858096,12973277392304631687,6855417481668703813,18273789629298743762,2922606928775994088,10372509493242789757,17916261347871901607,17278486047175010826,7164659525499711238,14601750125019741546,3429090518753032293,6879889630224439760,10245573446326270807,17746879771746867112,14849743296791589628,722052757941117301,10742392096734846582,5206228745184897899,1155597867686851867,17518944594237156720,2029687602467841278,13297073007485592804],"proof":[[18011007986230719904,2980977217160272354,16946021545980086269,9976869376014916117],[1555469606512022537,3740752318376477773,6925468287546006848,16049395588994618295],[2251982412665193089,7000173546084411664,16724988489609497238,3618435686653304062],[6759209744323034883,16257472410806529112,12025803230269635590,9678564301133877200],[8632244482964516436,18286975854512255832,6726684121786269082,8294481742146468465],[8631242394933406609,13222773172363964799,9855780419993973740,18234645130559942205],[4840616572917543453,16594397108725891625,10085204134107791257,9310167165950576725],[16727256120015524870,7192938362146938691,498353901972299177,4341039305517415884],[9122844657885273262,17673512795313104104,17183778677304588530,4200607195464510109],[7333940202103543503,7189561219792610527,12774437342174726324,13938114059583921455],[10775870692084716449,2110512447053748130,15565951624370273642,18400748250945096681],[18418676371797832965,4470033993164593951,10766683107812514947,16362222270432298022],[17614027846182425171,8821876891961750926,7260375258529498575,16099171483721881519],[15215503179028663333,615205142234189804,9395469026505961067,2526177543320111085],[8155062647038186858,13824706416672988014,2032929102959790223,16353717565863963140],[10362281280639356971,7426813909066805825,9183188488298461024,16457279526025997478],[4282750637154906697,11193865276873436640,16027026646227156219,7229065506905931669]]},"quotient_query":{"leaf_elements":[9055782923401035415,16175176205985717777,16322616877182621126,18085475952374050900,16644083462128702118,8938560765605756864,9929641319483552151,9985997645763665743,6328899497867305959,6927586443143323920,13001010369899040065,15622925141274933385,2154139175659715430,9969724459578918952,11798702092484045107,1538136976163946984],"proof":[[5763684464803868359,12816472696492279785,14001333765381343753,731795740989034158],[5477552811040197016,7773623564842580983,6465785013483810139,13643739147312546697],[15338920533165230983,14338024625579744977,18335210893113519349,17625429943102990064],[5637104816049018758,11726677283859068780,10164631816876885612,12794431000324203980],[3013014102113671325,2703294633555354546,15729050257305691964,16170991732883291796],[5774592028037345951,2154398094243252028,242745541132322240,15812579908004318819],[13590189607400795731,9779939491887413489,13153339133441776802,9052376141841655731],[297956544879728031,14050559626497120734,4537499231556720494,11097714580024267088],[17931216465046754466,15916818581290663185,8480417527451205994,10133560880493997804],[2370865211215018463,4737154109832011844,15651039046268803849,11349354195334708178],[10616498587413095407,6141321262925385619,4823771692338168842,3043797307759828955],[18292878354267696442,15718303347633726848,2771463613541806268,4255463139924061704],[7903079704963845862,10571315490025203062,17522067644624491379,3809380910134193098],[1735825259002246803,5285745385255683211,16905735802687296776,6832045500081751702],[5300964561718551913,3688436530938695422,3672013875141401262,398755123019428852],[17144836120125926459,15201353506706726057,8965384436568764932,3461521867335494087],[412161255135997019,7426697135882287011,15407766786379248748,4603043754552020108]]},"setup_query":{"leaf_elements":[12736015454189928029,7915599282960302552,9378422919876481781,16884444830938433170,7493092040275377255,4153253900723645817,17859727615835685953,6584536687351386865,16645300304573586576,17473863517098165015,11219992537864574742,1423066902330159428,10131014381129085235,16188393967239984009,12063969030481326248,15447346565006000620,15330206060850520032,14487495183619610931,243578915816367731,5328483984756170611,11209101268351117938,10910482607988392640,9171998302057580048,1554000149114690975,823089893015323196,14926325763554520533,9208293155236818858,17041224858159197978,6261681340449649357,11241383869845327941,14110082451501828757,3073757085147515125,4629510395348495903,2539185965326743563,911876823471179212,8551817426303343329,5564552243092645323,981878715605542095,2940621195491877997,9371319388732754992,4750328827468923125,10673985818088496596,14270558330522489763,18428762299574294593,4652194975743421568,7201135031118797646,15088261540290640798,3388043425698694702,4251290976314369722,13797775028877309883,14958803434829160859,3635406346026730559,12050719306017097043,11008837537951998142,1627360502219366437,17554717112519816211,1813265412495756133,15044616067439507677,10826235440733350863,9581323601268088007,1278731822195154807,16950189583398058258,18408683543507958441,16782827960674999306,17220308680457860416,10033585374338734011,14998181713953826524,17832509248824921863,13573408889126087941,9382303670661480216,12694412524767440039,18101346202686589629,5628003576949558027,4422329770209442057,15508682633279223721,6653517449226633827,7953800921567605191,969820699558250,12513355461804989600,15334319359271389206,9301048333367513470,14369794794806160974,1778241650832239891,17963349035162709295,1575521702498307227,10908667069178926674,9338673721976023817,8751913669835763968,15472891120860357403,5613074916133443354,9539667250026477573,17983962924371460064,5843849900540814504,1539237553060982686,4811358375695347773,6111937384642468545,12670772043567681194,226548202183580271,11577299376591388089,15921768560837372345,7638432144383599537,5721064707434385317,5005979277104720446,16416568426479873955,15961057505739029048,6802632453868650267,9029269407218952309,8762899702898506242,1323738515704360251,10237374922254308584,2871195902245999392,15896535428397508684,4916844076894728598,11835127427874794546,5708035101770834086,10312346169148145424,3685283887070238917,8146207086609722045,16409262999204940813,10467611827942503141,9755782430732161804,17931177274377636777,15490236016457301061,6042158893662239049,14327694397048110064,17273152161466125063,15011644062838903419,12728273243299538989,5650091978924656613,13435620320408445012,17985214966985480305,14097093252329160759,8759982910991813761,11218676317147492457,3123746065765738311,10609290232870209830,4524171450694579671,10280801762674573697,63054010150958869,16806768479850837607,11500312695182990097,17427678848116841421,5227266411490491682,2491270952078637803,16546829666364969967,16790519993288461719,9201215975626486122,4366564822926936020,6518014442450285606,9027059084240595273,2819377174919502397,7517725360321471380,1693814221581322428,18071812264976035311,7301145927470587053,6363089855645095781],"proof":[[11887940584583987356,11649355881421192908,14078027712373351407,11814184118573358684],[12459621980520758419,2857253261405087607,10942363160565825070,6775749019089608031],[9974630231092021791,9333482524735248729,12532500351538612957,5491219015231296176],[9371505450155412868,7389306620122040136,15710065265737735190,13909829355816108400],[7306217561011846957,3255265208825032761,14098959517462200513,7088436509984289640],[6975934873465012189,9256128166925234366,17211938763073558593,13095437200344480726],[3503710867953452481,3106508845030552602,5375116613832071833,17369563136510627494],[15011872921054655442,15613486550494536783,691393003374757145,8288511232793492248],[11291730602920864225,7286911326416353370,1235209735256128755,2910831995038873870],[7610889655683306534,14169491388583617823,5478587463686282828,4731980811264257357],[6859086393351980446,6173373524281170329,9246276174662770833,2351834509024964130],[16726641306752611329,12303475760032963008,13607383413206491979,15472992984646615682],[2086327863442687126,16649138097498246218,10260535607242132782,5104170916603274525],[17383828041651844833,2281693514439338593,10750892937003260468,15997750768080342934],[8879598469516946668,16416350209891696449,16637641980725237203,9684281082136478126],[7148597397650241926,1704733478978426128,1137154492670237907,9481674803390495620],[11103322097618702733,2127780295349214531,9279168850811705515,12312144320251496219]]},"fri_queries":[{"leaf_elements":[10906337075874299824,10772761948264155738,7348762563181233740,18174134054408303918,2368002622150238444,15059152693261017738,14285408304224086400,3681639960706405405,17569707940680744390,2956406472299276940,7502556353819549827,14896996841157666870,4647157413723479296,9887633998486287329,15606570717141901797,3669899272014546544],"proof":[[572889694292482857,3822878814984130480,17546056417908327713,4356648993101108851],[1980144674023170535,6949033245653824222,16084299326710932675,16003795396144840861],[9784272121833480733,10717346402236450212,14813472595200548258,1465099224742510870],[6632273036793335494,16629299770539514256,6180432669496550844,14293878088318351819],[6196673166575719425,14351496410322680632,4499326214447341265,268217157335850890],[9595105827866743361,8454796219518086589,16537488421038895558,11083461294117511365],[16397920590950995183,9587821279991405735,9378224250966294080,11672833889727299536],[9457093574210018127,3633269758691403527,15309608494602073939,11875179105597989451],[6850408848324193767,7543551416143402157,803659704720972021,16235569475269627586],[9026155342685264471,11290520056333961924,14563692815874377336,12295145713590624305],[12673859192211394501,16771163903931146451,17690026192092667518,10422078678471562424],[7862377849054715433,14071879779472163367,7776909037993620490,7385994024884082094],[9716404334617796419,15150862758478461036,10116738246206876770,16159310944564628093],[9921314296445597352,12607643182737737336,924539792316356819,5516451865609828541]]},{"leaf_elements":[12965113872426369470,6854575471260055491,9920153815812222128,17110494213133118835,17350341468003006836,14483697587084981552,4517405308292469392,7488740497788636350,7222807378505856567,17660311427610451495,18422250349130545152,12249875561508103965,15930430141691226148,13554982726860051394,9366180635132584777,17917397424207948479],"proof":[[10076347546440925162,1692177150776002531,10732928561953137968,13673811619465078002],[18240818412515533659,15613884094833713926,3507107567560255586,8294215572245838359],[17785738459530453424,10186810274177225905,8864987609480881223,7870912759321017314],[13896547723922576767,11241813410970575016,15164064907967017539,7120523587562415601],[8891917696860545702,13526398206859399080,16710948033130225193,11264957502626489349],[13407182289982223699,1944237784548486477,17575031380501467073,9332578350701074410],[13124621918398238031,14269397488431515309,9637075759243217281,1374692847079806106],[14380219811590412422,9850558203365847216,8103723932688736129,8558059708465338399],[13229281141534379196,7452617037223227285,7165584774954677330,11435236973695414597],[3419930858868890386,8376773629383943160,18099467646165415649,106843137514098629],[1035045995526660610,13644572249133237998,11620012939398060486,7212075288884837126]]},{"leaf_elements":[11500678044688825258,382580981430898946,15874192432960641005,17806399601813739957,4813736506423850686,4187774975742165767,10816409241455335841,17162998235229998823,16323017463352793316,2615668318270793970,2139530053860106230,15987651337810863545,11521410886275651854,1085159693373121918,17139422314905861826,3403554675440070918],"proof":[[17144954563211163176,7080258565190931068,5965847410227483537,14657456415607814993],[14059575451272618879,11055518196889839646,15450240891352012220,9839942943777016363],[8748890997246498611,3743381067745415922,2841448412063611091,13220297505486881346],[18044574462078730935,7820425394316889645,11190855850097649249,3871374339757775025],[17440655271801898477,16788427887561402250,4703255539404539829,13109024628181737046],[15546076668546903780,2487767760765576264,9680070786425229558,4857489791950133344],[10687968705601249996,18083595299393111625,15633247368662652480,1216968033895479174],[12226308802717355526,10631940034649103891,18308154700960691799,11171411898695195914]]},{"leaf_elements":[18207050576054863925,3154941660543458647,5268717156954502128,9427722507446504274,9662944282244051109,3574384285127468250,3857009401822053031,669713249134480193,6319163699964819570,15827065830409691418,11556745883782074773,10457956556481883268,10172483704248151091,15846527610302064405,3741414667054275728,10857047333627110949],"proof":[[6156925175526582550,2080008407224307417,15479512628423699819,10957467831492747861],[12191078918878418998,13841524061515945460,14381708293353206820,14522642575501060555],[16610717167823960674,3486907729776690083,8106730628631496224,4361396367403325232],[11440096460337808210,4507072505727704764,358471103796110339,1530173096672055472],[8537000182364138753,9846641187754615169,5492652896324277680,353362856001838847]]},{"leaf_elements":[17422870121820784949,9279649763883458558,10392649704438649206,4275716394208445319,14923458923996159321,13441693995813286063,5538784996620329588,2291025495255618999,8987325732237904852,4674522562884064771,5646039796703103303,16954647411338512743,6043644490882419722,13918267068453747259,13542531026347326988,14851488079789523248],"proof":[[10485259444215048698,10568962927375070722,9662708587694725555,9951838211578437977],[7146818340987684729,13421072458407422161,12178806875058478953,82408401134322510]]},{"leaf_elements":[12636509829310569228,1221361967083405863,5202005031054329410,3979567876410885304,1779072914486373873,17530329254161706299,17673969969636411403,1918506755882003],"proof":[]}]},{"witness_query":{"leaf_elements":[9666075152832077339,10064938293480302578,8675019723866321473,337513391938029709,9319590978797405468,17189191199519182853,12221523913011893418,6747994200212116163,14557340809296093080,1465716548734019835,12768220340325711829,17770951094619274454,13829315952423512242,12120624984251112204,8135545293705229207,5734817842197560232,12824992190190915975,7191118720324049469,2214582035697726787,12204514208002756901,4497355646167146463,6075863586901726755,3703456614092338784,10590478192747912095,12452250267983994074,318943517312702684,2790454800178430918,14296571353889882665,17088627099771990999,16985323369834476312,6465385930660359588,17336960502865583751,3653489947361746305,13028198365953600126,8010392001623380438,9425372969969847023,1020853383060997463,1885467669700149844,14655024431112968780,10785320783763050300,15664269969168177738,16320307451080328163,7877104754530501920,6740519541526160966,17767567679713536618,17144877605072658557,2848246100216446808,15280854677163848989,2582978785206890380,16857131883791811823,16697888326195072024,16919775577506941059,10477199520778965793,9888645367624218509,13636227644654967741,8001510202265301819,13581924748321075283,5121649079298375816,7856373636988358587,7519588086260315760,6442778093261199499,11647893385378039834,9463054383909942532,8182285270705959276,12065198258109676059,14201953113527193315,11346661731619411368,1591685593233672173,4947791558596403024,12363196757319152946,10739584446431572177,15701776106128283335,17349958640221361279,7346202791951890190,17924012442384338881,6231228328580909651,17925873009219385406,12124568464664175454,4662454927448128140,10750586831326659127,17258022398529598929,1038522331389269623,12276145376302905903,17183956548287689735,3921656608650318221,597623646889262889,13526796595085353680,13996743347207948128,9219169843522915131,15248408426155360809,1602396185660023514,15444135388161439029,18309118923241786953,4342850519094721992,3696504294046862819,14288883516346885646,14886685467847993070,1899917520331778035,13911773692561993750,7774236361890110744,8901793064826563482,13105716439617919377,8197529753883436319,1578300163383339178,2444320948238065003,18136914292404066952,12962628675943303878,4725973789767152947,6068293935549651799,5796856522882843351,14723409827137270403,13512720424448127922,6018732018480675516,4069021736900527677,4675912433309816090,14917224105608325698,16457698894958378161,6431447423716472722,11298881970888766559,13312673865713381563,13540790109552487162,14886299820649277213,4173105899651940590,17492558952535874922,5755764543251849134,15790327108412350830,10548247868179643188,5059059735394559526,7246089890468848931,15416504492232859286,15782998190030178305,14194553189355080328,14668866486671200996,7113178221623108981,5096192549332264077,1594333050523450931,17771995402862769452,7271327670651847078,15057307763973575606,4265369263873482944,8458036879186567251,3111935785763459603,1424537203976518633,9503509101139669388],"proof":[[5927024786116464005,5158050091935319346,12061395250182966048,17847727279102696556],[2651026968690340608,14828162065929403656,16237298884577247262,5206351076026623655],[10784383268321437663,14944846313430509857,16021764586740425191,4897082954062450605],[10105625868056577830,3886383888400889298,9470626077539773000,10519196709864667412],[6779666367052269614,10596105459278296860,9292636638068546851,8965097653351525857],[4180071938058368745,1637341614338807292,4762672418775623432,3965564439672430892],[5406271246786556795,12318284974790888212,1762627763113416578,9260758176395673548],[2421898700773098723,850896703043699556,17994849163635718488,7118944663569524713],[15427379577447940459,8931631920072021013,17287403469733335421,17300062019268317091],[7860209416359235479,15742004846978473248,4851734507040315851,16564380228641829443],[4630329682680940736,17420256889718642634,18002771675266354203,18000560868506837897],[16793243690081374502,6563075173228520355,11962001364831532584,14394637709193498206],[16896742987308219164,9780159683144431849,18004510248671595240,6625343484376121967],[11084259147082850268,11392741821937288795,5322319358660221873,7390072201019132186],[4250191650554789398,18214215864297379788,6347716538130768735,2845062300142290670],[12634189585880371814,11039581249811674275,6231385938126440099,11349900292245790782],[667075809834928833,5991294366952926453,3234520755801828472,11803630721642567180]]},"stage_2_query":{"leaf_elements":[6240962728890939791,3748429674769185479,472418783623819352,1867304893602358886,9885104641145465962,15493931971063022136,12298395156182388750,10735034112179503687,8388547478204346155,2620886661050040175,4887091190903679601,437268746875974478,8271630879310512023,13664769000252061478,217162235079344215,11050076149822607315,4670225359960949609,7207135323189378135,5795180412594883432,1186265831264885329,9717592434827656325,4432356175860248545,16167033151753171156,14897642573268669356,2730755201317281356,16675443725554488198,13749747258141014170,13371071153752946073,15300107465728234732,16245849798164366401,10907057494357247396,12877670355581622802,13126087167855009899,8877095955819928541,11445064336382501810,16614903443587791620,5457755405223637134,1497847976643513622,1700481714054768765,5500172563240759185,18112491621636213556,14477333891188094767,16899375525271361420,17372967591081323740,10013096782642305863,15157477270416174167],"proof":[[5787290063833026868,11286218884334731887,6405428419580463291,13486674148414023743],[15748073913068030164,13209487757950632380,6831447133515522631,13640908159880440064],[11381282178883004092,5246305532091649364,296154535269070995,3204320899927488245],[4912111324228841838,3163129471828896848,16315188866211682241,15623679601226182889],[13001550170824124869,9166132664004259256,4765776059358857472,9178312643060277135],[535024488490350764,13534263395331479848,18003875867590890779,4388943815548902842],[1706740603749752730,10053193637377935017,897091340298741294,3086969738605312682],[1382979449292947461,7636727565219722149,4075775596777581515,6048612728084168872],[6587596037744290154,17946580324814788676,13482832696775570416,9934679892858363860],[13654965215235900398,1931001963935167990,2567165509078800483,9620051584184189366],[5890249310703919176,15065607302645966219,12143651597245919921,4933601880273434017],[12139746959034422952,16793548942986498593,1842976027731806586,7576969764770362053],[15073629187592424900,14934711818713560184,10736525556889751792,410918229093543484],[15810660196757165846,4981995851443959553,15652384154376877111,4403201464483656774],[14695571663124619820,18051006928267900374,8752173224795291412,3959160267781023030],[11736029788203618694,3366834839034831936,4471200710256718226,14721360103719272090],[9207694402130270883,11419654200426216451,1427563265836939032,8959631267510654977]]},"quotient_query":{"leaf_elements":[7870080897096713973,16440442034340414240,1781285108419504587,9912878365071625999,13063990478463168935,9449501073253426015,16208974610096855986,17541316533625382360,8479302669222998843,14343154494872062747,2104072188237173266,7334338557512255903,13638166822032358357,13121453895355080157,15421226230786621565,1469698399860644714],"proof":[[17967948641565953401,13228542775858770071,7969357534733511667,13313848118051522125],[1638844367694449788,14486800379546189939,8707896044024192023,7551234534556678861],[10732920275612640104,16866593764254310745,14601095413933130000,1627881723938088075],[12097649035595139644,14855613508519744393,4529944052612263693,6245560189768515766],[3188379298382788228,13805105245150141904,18260451936067301582,15273599664353534393],[17581395342087729712,14353751244139640568,15814013977996933951,4090311033800782412],[17177514778618225946,1662463816859548174,10060199827753933457,16461217959748481762],[8591671629730407341,16276359873116511928,5109344818756626508,11580524256290096790],[15034403283532834351,1400726289691959031,15191089898273914100,8416723284581991564],[4190811280438735822,13999305400755160563,13474104452473808513,1293694451577299125],[12280502993538194610,16179447586478968070,1830336881183191642,1351006053312609732],[7565556431501814561,10466155399798029643,16985034312236295208,11852979488729343066],[11636527163137977843,14689624370135893965,17266241460552973083,3909463190673555749],[7553544410232880777,15925118777566117759,15079944356926239868,3663063508808163845],[6750637709422966584,14655968476928391943,15296941372109286937,15816872147405376070],[8457859900747567093,11023554797682160521,8041785559699237870,9054497301565934105],[15302778404576921720,11814066077929029710,10522112645627058746,2170028931474566010]]},"setup_query":{"leaf_elements":[6586376997400465371,10629278975106877238,7395349235530486480,6838294090250215844,1417398828524855042,10138860000177100844,633688080118993845,1125276726080967872,12968924553757271031,2483853384869371607,1194448577344464076,2839963743118303668,16027604774716647502,9646894359546480517,4493922567933808559,14012935276815106244,6988986764503331378,8246934542482650781,7318079755112534524,15870274110831712560,13511465776391616994,3592112567433475852,13331310840845247649,16454855730679522460,12874712414838890839,1948298249406540554,12742411648337468520,11112408792171999768,11127374395699900216,10766353349098470828,13345575307049393037,4510719450229034049,10198398940589407514,2080409759355046179,495363148373851186,966093402070238842,12177771250704343883,17323644920405469043,13548944404684194278,7894178660476283948,6234929116242525043,12451133373905394361,10032158345104801346,9368736835372499653,15081856226970949208,12830679921969272990,17369678421860947291,10878340002887248236,16523630048110716284,3669786711193150871,13057694309834960283,7958171700388336976,5737030145260187138,7057118874108392678,13645984797807100338,5185834638891848774,12781982215315894577,16347989956973129951,5663450464577382383,8112316290942830482,14495095918513701618,16655665800547252233,3719723358874338678,14958702705619425439,13999305406763129827,13160951680767638371,2572115359061576503,699718293701090550,17392886293749446411,7395455740284756930,17709588031983265279,3987424368582384083,1292514350324181026,559921302296867877,8238624778661601557,4739240455326592411,13608283983224056284,10876711660708844827,2148465903710054197,16947687819571646018,14012254454952406945,16808323968434791585,1564386647964867743,1821638174560131670,16810805506726274410,6253129943496119275,4112184989877245366,13342763567479500592,3233442332835471460,10215941015057869372,13740372369613386839,9033031237333546429,18028156682550952412,8048444017528301115,10507788347206348054,6344320291041833705,7826257560594206879,8336542383598297710,8796647939260807968,3525769736906509010,10838103225130443333,12044261216510815004,7092279473759909748,11170428526568843633,12135425345853106200,16733470898535410603,11477945851897938627,7575330264585959592,11280365842085410826,7008529758037710823,1540228022375628504,3092421233025188975,11543346663447770471,10224936021660693688,8083394696377458422,5786178855461783985,15410050260406726590,15088645393376730140,14108655151737633002,1596481027664597543,9372013534998196194,15634758797486110060,10209329009678453192,7760023543676546651,17571672222926511935,3054766931247334426,17325573664247572701,3910131060371635536,6277303399316433796,6654793047289693101,18050569048069731890,8510865358449737955,16834020544286855457,13159990168782620922,190136792757905241,13837293855116883109,2128498432931598070,8455063752242155550,2426582436244248412,16844610327708289519,16465336886549047865,11429899605092335388,11063688344788153785,8174762076383841903,11014032336883404467,11866404114463390610,6874917735840307198,7514643211267949184,7646738069976972859,6775024672282713604,10295196567185164353,16253197275939076398,14461933596715559797,18350288826817428126,13449303641564823151,8488466406507324942],"proof":[[4605367637919980171,2992389396451650302,15641763927300920127,362268774824095951],[12880807934715966981,1506006829199407456,3641570881486173626,10024180962961974635],[129149171434758933,5510548929066607744,12739068846807459985,17557491149409943203],[15721414737928290768,12274961900191922357,10225205261502533689,6316833334966118240],[13262431070318568807,14190945657277941557,15958463779727484972,6617231506062970869],[1991322429239869580,10449753972377932915,10634333647790944096,13710862182506208829],[9324056208669524502,11439026063774421979,16805391437837602545,11689768675063994521],[5579519316414249565,14112261799731849268,7807867539685790395,16278604966278694175],[6116436111318055853,16491985464322395894,11218544821991195941,10328594626167134877],[13402676139838273631,6934178231023835803,6311660192190823368,8452458599681991472],[729002309467323533,11819843510993775436,6490408764374406551,18312326459917132222],[3011447313462566160,18082381080895352820,15972553084804066261,10525089006682281685],[15817744640854213658,1661543123813758745,7097518486230174583,10845765794154466395],[10604238578350086399,4162637092384360470,18193900970957773868,5176300351729523600],[6936375391091485604,7838459346469681638,10126631508919175423,11796846634798213516],[6839262883155696775,14636454072565808037,17986829962653856079,16954616439061611458],[7120720126365939453,9301679779098522440,14567674671977422259,5737163305740258263]]},"fri_queries":[{"leaf_elements":[17246589540543431450,5207280316025115219,10150159930720515316,5606579363660488274,4197753326633329252,789499940171225324,10840234854688430380,4215929343638729928,13288705817326459455,16169245288434936958,16104382633356908758,17953534572949086271,8730350319941908552,16163055482990725124,10374337169997432655,14183670000347727875],"proof":[[14780874984618671915,4809803828052560995,12949271703238345129,17686437103163817878],[1058033301808713549,15550398385613131756,7543890514640094659,5543635120533252660],[13856290135059064469,5212593088741270816,18293522447408813360,13340621537549498980],[2717529668895328300,11269031404326775772,9385949494844543297,2574158667141355101],[14675970736083216617,16922641525896395828,2259846276733774978,5032080559653281028],[4438711940272612013,5004346351736682708,15729710825701219088,14394286483232926881],[11672863254792594474,13535437645611041769,7983813451855674112,5662227879176294697],[6548581057738305201,6693202777530418029,6056276735894762383,15797930501403731210],[8658268078640461435,14160557988914180647,11978469775965955540,1686943413448093880],[4734279218151369494,7938082306279552680,15203436987066701926,4771578757922426208],[14273713328247001015,11867679305814130780,15589324627063805671,13585497263705141639],[16456106666545409235,14096373991941519109,7357214633443861643,13411669160496059819],[2409453229632560186,14637470331093135900,17769103887618170120,15232686395332082864],[3402040197144832143,16624859650092102648,9771646739874512713,9644679865246592281]]},{"leaf_elements":[1274957898394288474,1254977507087552932,6633180566713428191,4527123786576254592,9816772998570118476,11806240678728243360,15920882954423469337,129050891438154674,1725214136604487381,3272381507840921508,1584078853317525964,12223454876622917170,14273446547314363524,9045721214597112783,12528302305106479987,12261284281632879035],"proof":[[9423944237120834434,414529869565865231,3348586999987048437,18242138238820112327],[12484618580738024840,11619253314253822645,7718791701035653118,12310419447955238583],[8155622463467163518,13265167511853962809,11021742581087412535,4058848318586251654],[4832012988857202179,7955071247174511648,10804576162591268828,12149570465953140005],[16228658493708889963,17424543443727873035,2209712131428660749,168669240457213058],[6257594899277714055,1791307445424796438,3743860797405929160,8377105167980496229],[16234678189624372439,6795737612666146466,11605190264035813820,14059995215704546118],[12133309703297154295,17036808870150166554,1049519452444359739,13092369784231770890],[12470120042262744554,9041482703562957402,7467578509064975701,9193327395618044100],[8198011633178231785,4338451769064680171,3469740648946686407,16177771307732142306],[18351435286393245396,2865657294868377891,12507805816395302687,10169105071705863335]]},{"leaf_elements":[17254398213779135093,8529961999100893947,13946095779713559055,12409694722572381157,7295020241133982870,3904056982455663700,9682560366277517062,3556592703522035494,14722359343292541799,14794997230125428464,4380179383254310545,2408852894515179245,10193370696701270137,12814149223301699053,10408598261242359743,7319623634894797674],"proof":[[15901135905007242812,12280169574018358304,17318838972716213678,11421456998747608529],[392588964349221249,17326836597552290643,9099958994477114590,9105069581057118711],[18394316711540434585,8827120311134523298,4910258002036347859,877500266966828687],[2596914916858421315,18036855226310110375,16628472314656185121,8566133627068649963],[1761422477715881734,9029479235577686306,6217697310788197446,2526555829570696756],[16281954906476392402,13746449904646615658,17676700984655787689,982903866851202644],[731073139101116486,2374056337424730611,9081295610148386648,14095045334082447191],[3007305652148126886,3973547783666200093,3625693024435444758,6853635343299758316]]},{"leaf_elements":[6526549792186519303,4357100748798339290,8790663663679245045,14612574812508074006,14744024561235814875,5700714426762461684,1201033294477141028,363631239366584847,2318841942877649751,12851714579314175415,8588637088490162112,6823327226148622604,11434522851661212506,3181136581532958531,13457744930567124829,9532888265534895412],"proof":[[1769636513568403787,8781841783388881585,10657296369928912570,4418128255724254964],[416609320153883142,8150797988108640886,10616583336032377372,7014421754706780030],[10293440612286135102,128428062580387206,312538945724137603,14405971949760284177],[3572167046127305299,16999318335924234013,9026160449259726606,2968251498515825824],[9511959561061228326,12142498241637411804,13247686500668664919,9845123999379242829]]},{"leaf_elements":[11543424105301683429,12923864838794113899,1535160299484128979,11075524133121684246,8482515784209504506,5102967239528307818,15527559594073359956,4973840040591704279,2274442554747215692,10509379957165122735,11776267374157344962,11551294505041757342,17448478975076065315,9184062444929334409,2666663240625679228,16106550509543621089],"proof":[[6423150653854867372,17541860340290684305,6317508872110343260,3720150516183724282],[4012994884363358194,13188108686276194801,17251058977930729867,1715204375964092596]]},{"leaf_elements":[8059053765769322751,13417580637374693909,2911351709503266961,17513728947462283680,18357528550657626748,6795100929311303227,3237676158979040141,13444877005340907045],"proof":[]}]},{"witness_query":{"leaf_elements":[6581751985650159194,11796340997432676305,14356467926287026482,10929918321648071660,5081091617403091083,14224251327486894105,15501637833561525839,17294550633472971664,8772170392069310879,9581086135029526829,5227620864253538900,1022316702997395478,17004474686731729654,279174908477534501,16570308257516860947,15094790205323656200,10238929496337310880,7103310953923695956,14010319088700229083,6312787154663495106,4935004693909621935,15089309891583447452,15198252724856047934,13687477922235205279,9949572777829465173,9425215674734310172,18394033354620065163,11831877583994761,1502910478391528059,17155099293799651700,11033431617527725588,1483093723887745725,89159248935228604,11578730089789124630,15217344681662962923,15753567039906658683,2592459944214745574,1109868407885680312,14818869448426408551,11393694789722199294,13640457634174552469,12241005243334129678,15011645078887857846,1504617813532602686,5175959484020810411,5349049767646497217,15792656772080616545,18009424285167543384,12816576735768826581,11007955210392504553,15808507705923485551,11849373999297556609,8129897910077282757,15373072757037521337,12649327528881469608,6762424836738345479,11152827813955477413,10838943059437844796,9597669856818569695,18085678945996596883,7714388407525148422,12414274452770331173,43671285248224980,7772934809009363589,17445539780325048918,7820538012804048065,16034848562437866063,9184009508401537686,17261919146950511759,3969417809196213585,11304593198227362343,16208075774023013889,7094895745224772203,8990685295718846329,7558758209751895396,1193936946316240316,8620753816213583202,9961119666800078345,836415074221278364,7986494206238937209,871866445579265527,6203656375643413976,10169367614236335952,11141307246694880519,13496917708866034939,8532237075339340547,9666018103722750237,10772151512893824194,16329585311201129363,17358281055910798734,9651609332846536022,15648581704278748873,7342426418575092689,167726886442155843,1380302752889341026,15368173977759001163,5752304148613925531,9593240503023574490,12947999590117159887,970609642259871815,18067254491793798798,3399294425326509206,5072108169375788485,596371446025111057,5609086412357768356,8173002266538748861,1079733416254307837,3099446325719190070,6780886507262811046,10659193069916101661,3518038544903362620,16187240280122019510,10853978053019822576,10396675656840724572,12981515936815899173,15288165148638673299,587805154850945873,13759472650343988827,2830820703905275422,3559748457493513106,6145342247516308353,10664812292806618633,1880034149518249525,5114969651962278099,4034961708512625600,16544622533545291,3839152372615897800,3507203991281932254,13965280392587964790,15839975650959913613,10909838522034102375,3194964354245480542,8644721502473714862,16484806767262711574,10262187942716572692,2710993262597886722,15324530897988561420,9672996948220224890,102012732456833427,7337041363241737749,9804411078155969983,701581473711673417,4270095352687751887,9986222517423370893],"proof":[[10169276221792575860,7449305483751989953,1289944791344880124,16561347696430919739],[14009816553602974599,11975989823093608297,5678123267088075760,16191716528822118451],[16955810683015764433,14921146215200853301,4734861544455328200,3590468108949624429],[9447215755789046104,1291690940601568168,9896089311560744885,7964028853007370647],[16782550616002452226,3715717394126368610,17910155743477019092,12202217170444051124],[389171909263708969,4033859356785378498,5704607282364241612,11529868628900930822],[4716338244855335968,14196833275308385778,17128556739320875191,496961877034056777],[7426819402846089412,5468686357030691660,4701448497786238184,7112362783784865322],[17298470562639518808,1137883606310931028,417597648754804612,10743486324127896929],[5302276803112433986,7796692933443566923,433816473847848925,7131504906810686264],[5442419185732342261,7416819862642503092,1414531599961056323,2373980622209244313],[984598136568971216,13741425020965744734,14968107082708357387,13233935102279111551],[11712635813587682026,14352935624784733631,611587402667071352,1252792997581522946],[12241345739495474533,17502430209627618101,15600656413599727686,1718980172441832242],[9247864576178678300,12187660577901889360,17364779845902630975,16946601767117017313],[7354436357839288666,12082643543700376778,280108160058116531,17014871619892454146],[3883284310189859620,7676597025747981463,3650032175723990472,11390775373782083020]]},"stage_2_query":{"leaf_elements":[13730984959048336415,1352696326429470465,8977034186771630032,18293526186567715442,5990846392321400248,5916793407828095764,17405101775992860840,14992924612020004616,14544786338873274891,10431944754728654343,16412929812728592240,16843172510439041203,528589001996151405,2777677942325077743,5673070204549620412,4685923544606960834,16392266249163203453,11001727716386894835,11079320791139459788,3201422548937730331,2767087529774434208,6084386613318436948,15423413544717499104,2235460314534017181,15034422451251526214,126653715539378262,5991374269402736294,6704220103658265296,1761357361724697463,15894571481487124913,14461853672462798480,17698397899141784326,6741132856612858359,7925361113891300671,16251500024140727773,7735054669462953519,9639552344939411336,1040891633021416633,11361552196382776795,5818186587747051370,17395850161629155371,7660759208213145213,6550759532564729230,4357212838017773918,7934665554816130103,5439084122280859606],"proof":[[5743509973018008245,6066302622614617753,12946598379028543664,11166215143701915127],[11001477209330357047,15646315190873373740,4261164293776680534,7795435364514694116],[11053553400153749969,4754851648122398139,13649047581749039104,10630794404000894332],[2516772526301093031,6504293897076699945,15647962976664218615,3526043044907284502],[12380417699411784160,13829854854531496898,14001077706534410261,2936545256257163898],[10001130968191160663,5755729418800928207,17019654271562336050,6469216142406156199],[17778574408634881638,5221123060914187632,16107555727129029300,11932116945426053408],[12236439851875869840,15456602272717244070,13290427786236674630,16556825531323198993],[2570432484380222358,15632645437268062593,17991939677231861187,12214632614540359282],[15916228925934235089,15771780276775286170,5703132367896268730,3625642164564196297],[11457357734889114193,2010475569603948055,210574492876723012,7076805181909680508],[11475025037899163726,3606307185509883320,860713347454516840,3493989620151826049],[725042568761775667,6244897515153533151,17351701747442275145,5661879730334858551],[17204495008324418183,13953046580876343423,15152110320397422066,10558594270505177456],[12390227908474322124,14646364990979851205,10804123508353031655,11165302666534899722],[9677293254283709663,6198258204789557791,9766902500534389182,12639953718878500384],[18059672708599699147,3626647889309550399,13109312682243250983,14598660130279273427]]},"quotient_query":{"leaf_elements":[3952648528800732824,15477066983093064209,16007651482530251000,427291103693389504,4609761217545277782,9833678912757478603,12199351810122042229,12017099706033063935,18285348652859124794,12939932151184046409,11072611908943410976,12353585059151956075,10669715778397062519,5153085548917043935,144622260001398875,642740025237486904],"proof":[[7210573667592856978,13349486591271186375,15156496984877853799,11455546780930798133],[2529414610162339354,239553789783421020,16265618439316961529,1089527273555786179],[12400971167784550691,13654755100760476440,1838216132922297689,6592914798145393450],[17409524852460703914,373175133282432837,12192530396094756403,2626296060908929547],[13937995862273933115,6988200919493014993,10228543409354087674,17885058025225500315],[5343622574362049369,2766162938597620117,9679038823952585204,872764441709005678],[4338838569982733894,13097366683025237519,8695355648277754635,509950501753140509],[14549679161046700878,16907472358829263381,17950049294163602005,17647489063280572613],[8875431348735895041,2968533745209457441,18078647111172719115,5761291494893194526],[4245411841459328926,12731860673501494191,10371537950710174651,15194788310017370357],[2418900662001043374,18145260603769309909,255378399567629821,15031308596847884128],[15756781557014827084,12395730194846112912,808970486847376853,8036081723904398977],[479248795881687551,13303279111698739920,1345078112998317694,5185529515149610913],[15489982934711090394,1247978218490214677,9738238891582313748,1578616155401384068],[14261206796815749683,9498317958839068116,6514919220174778849,5007637692427432885],[16742362310854990558,14117436772204862881,15144344191271085712,10789693940005752321],[653159094080667989,10430837805542535024,14984435384011427799,14538001483269804720]]},"setup_query":{"leaf_elements":[2448665888682157579,2437510333991999264,1194240217071021766,16370227408282881274,6032367276390458493,15058165446195625847,16551232435244324174,13118985761181377512,5480161870068072910,16442132084777925498,17931736387907470964,3372184482453582696,1613059313861834760,4773671952182720686,2861823427679194441,2029576080397678028,12958922134781136086,10883774930231615007,570529243294285079,194179010765546218,11567432973790991530,610102502043872344,10811228712190863422,16816797357242401734,7221865487018558046,3678988883103827981,16175259107334216168,1549306782739962659,15941191480233813820,7140843507870444792,5585571325779367442,15442596752953255755,8446044681124813754,8247778841155543618,2358166465757402564,8651465016419573865,16303052891536138814,641317806197052295,10974966975295532246,12402925317086697758,14078494587319505682,8721708843045532749,5640742582100397744,7454460960339775566,12177284614430652056,10411558361921225181,5570590314529949164,7518655875771158867,10005282373705003546,12601307668592270244,1016310703279758577,17814389920809318776,7814550983480367889,5724275504001579617,9793158735696271460,4974020360753003885,13070736639604852813,5587471688637341977,10305474555786608575,13939805389648350444,7100714715988154007,11037532826376375099,17185625705515155475,5895073202804983130,11894244949120604945,3282387294330675617,6131953291023682008,10273708530539816755,9212813182554214396,4599799219461686219,17866302534269037579,5955152252482487901,455231744199511934,7562495010805916734,2453469601366923957,14163893457209182600,4645320041216047072,18193051866451681121,15902059035003844102,5049875323768656013,2736997726734684055,175223004222347625,16925436098050087752,14059559981254640249,7839739592922882734,16590273725971099814,13492525577397566852,3831172752371125608,5573702640104251439,13172742050545426594,3932850352843260384,2398248898225990788,18419273135002996472,11631673887799037699,14802511368401113506,9677334761503643322,15491792233384526641,6364887744512488014,8328145518249303211,12353109538853625830,6064798819014363311,15913545074191100236,10139819486796091163,4506780963831575721,1268931627669009539,17556388003773722984,6508780337884308665,10967859688521014086,16064168461830043847,15036023079828642380,8411202090072123344,10862285260417078374,4621224484223996743,8438328445643514145,4187179287929995314,303376763948830176,14792971706624876416,10198933916453801976,11809462227553798081,11749046541501898893,9562196165912784243,12748299566865757382,12084701451673870330,4169872831196420648,727253234956429861,12465025285758774195,9431418482249393202,13403927906474637324,6453972013993387674,14230892641038268689,11897641370354359484,3312318588706990580,3453421172262248024,14749803730646018977,3328937464519583456,14532686217380703597,14349095947884928266,8457848255848344853,10074343073396307200,13384226423623497038,11868669970785807120,14856592962660958826,16145321836622369492,8747202329005418613,12190287227588921093,11788296070765683624,18384485261886797247,1371843055372633663,4673532131040013025,10343548764392762729,8760876151131864319,11570436662117321603,15504021299534754768,18032417401814520601,4257441303241731273,10695082140506307894],"proof":[[15979121529868758779,9081885472051603946,18159169126586909599,6142016917666707837],[9614447284917311815,10259150577341384468,6358779755773674119,10753183227422811518],[4713337036716897900,1542378513476303668,14558235652520895435,12303870758863770749],[14940958880003409944,5239638577951156158,5401539375634521867,7484865488260069296],[4467985303744398757,9668015829194633230,2541752758084866195,12886082695403726102],[14178386062758708738,14435562091668578522,17164910870434662117,5473662338955851218],[11401631092065435066,6998028912495291288,4983866170469832375,14256180120473517007],[18277906121687442494,11538893897006559342,3835107007135389211,12154086797674832378],[3001469948876277945,7302928222972116785,10259528259762049136,13241678447177821186],[6640646606450113561,164010289372986327,17953706708453170275,1931453526624438337],[10953881973454319436,15134567695131472150,998972083212473110,16520177893109144840],[7643222686910460164,3268515482506783060,16278610692931978692,8938036545257731180],[2056811367540405744,10307632482395065690,3907806711770945196,10498845393788468130],[16250169497930798234,8099990130964050765,11454538258461118151,13786204341776562174],[5934491484209541180,11004074432966316791,17577076188727297148,4922390807189366636],[4663876502325890420,8654762232196905587,16734656447485941072,15071254870337968247],[11228374418859754127,7869861460320656809,4514881828000421755,14657212534562479643]]},"fri_queries":[{"leaf_elements":[11243035672992201346,16036281546006539625,11256756198061547702,6740543705700563117,1817643435224377571,8422190075564120756,4000496287055663643,4588507851730913838,2429181496692587688,12888540334682006732,12984354795707841773,3496043974086715384,3883069566780006439,10667816238988633310,16582564167217232253,1936399204621686537],"proof":[[14512843130964098276,8644503417623601735,5647994945027733185,1025791700210542235],[13479649333416820590,6589020498154122127,8512605502565549947,11642537460487173510],[10016751382360972088,17393329802402721171,4497185841867331574,3215703498435296867],[9560952082757475563,734197806306669007,5246029944722375859,18298075646937046502],[330730527304885041,16692257212757687113,4130082294488551084,10330198177594888622],[8968702269259657562,17660337560793636119,4757615096020145877,13306499580499958643],[5717216860296970310,201803431335957389,9823113774983235470,6074274517625025050],[3573498118910888681,3623785468067906462,440132512182886071,3222352293744005074],[7396476233187995973,6042219708221552717,14179806432448800491,8614200881055964213],[2970174582477038226,2060908538290627721,6633961599541020680,4162423163851491634],[261106310660952814,12116222595168677978,14833873334602746692,12758936992075847380],[12503134643657674726,16920158509120895407,13385687889550598018,7026520852875507395],[3052130999427531982,2255549665879319941,11827629733103638912,12405045442270509996],[181482071234688135,8563533219904562640,16669203832554260429,17038176883649817178]]},{"leaf_elements":[16106268102783955797,3890541165928494351,4177271484004298162,1378548769186331249,7816382601852841027,1644869720614474888,354474531635049033,875113078068605682,15433869839775185158,11793688502420280392,5736069030491168901,11872253596893500358,12214077508443142872,17749683505664016112,13774701936930283208,18433466129726938251],"proof":[[6619626957526299398,5816989394409683313,15756693251364863758,15332381625789968908],[2823937872607427614,5357184305654492693,15456590854233786441,4956878764186133708],[1788186753796765450,17318322241913118228,4643348690313580261,1135107941105447834],[8371377520545513742,5546426981102252001,16254802443652706730,13884817768697838057],[3963901374373566298,11118167862070526801,1363069029524176652,2200272259370616129],[4758395581346402207,14496762802489255658,4866274569865213796,814859531192068831],[3018281359594060558,27754404806613619,9691241529185152703,5208019045898312602],[18121133552364585981,16599155851862636607,3827257393076347539,14884145901495408721],[16301377417511984210,177240009328571463,3845742692065181607,5218850812625011362],[15105011491011841213,14909572274630527065,10419140981967275327,3282967174693510293],[2860472450149144442,14189702544160429628,18276503934486022571,18112866393663550016]]},{"leaf_elements":[3241658694285183223,7363521984159571696,1517462601378804462,6486050219820411917,2927712212573729006,2790127019492106892,14971107954384340401,4211940985563287860,17834263710329307979,3562547412663950789,13811908442933720367,148584946609655786,13075762786134732631,7443324817722927772,18340982612559725881,8723899281454260001],"proof":[[397952762639797710,3598720217534288757,13326898988494062014,8334444518208277738],[18276457432019078080,10384902773962142073,14890438038077826117,14542888698582065896],[5764050699368634785,7779597479974680686,8170785646241245355,4214076484213513473],[9762114038726927798,3741061843965462521,4464945866018573511,18276818197268730725],[8259773234058047960,10551317687037317374,6414531992567696575,13797993108585971522],[16510109020784572808,4353145326548807607,13902847241762767667,7149549264301364668],[1691181825296109044,1780607758188462609,9188244828479296460,1671532837712644191],[16877487539376805290,17822316446890167282,8091809687634183636,8055010344141776647]]},{"leaf_elements":[9563056237014952133,3461261894936654238,8694399782605060901,9500136125259759351,5491347272208850801,16944621936617623647,7709644290825968710,11272069465257142006,12855536441229305379,5543840644965635453,3215037218828293284,8995500414802649857,685184743808154346,17797768787732191581,11090558206495779227,8866347072200028322],"proof":[[12865858119330977530,5832231624927342103,13166594154767230911,13801581670328567218],[5653212007108327147,18354535400435241139,1924728585457864016,11477736835227082660],[15686276187974000974,8829744048997693622,3244410055286319785,4004620695906014529],[10327013491816373923,9954848296284770479,1711086289429214616,5132441257657786702],[9181542189477090001,613172552818761688,14718008491295352709,8482914810890405616]]},{"leaf_elements":[5159436603524296679,10889395874919559776,3107723298166608748,13349175717760433673,17910039933207467019,4323517003455799218,8891829952593278955,7164353897887300479,1708562727030488690,11235029051672314152,4418798510408590799,7308091322410341339,14034854568052795125,8369111118442959337,3562226089429009154,1697140999675812682],"proof":[[2813622536336505620,14479272795469733425,353568531505167949,10662899902756403524],[14339942350011889958,9816417643239928610,18148598331444068220,16136246690981782472]]},{"leaf_elements":[10934508164646927795,12314719184668898168,7161347650890243018,5323539938734047040,427222851664169786,16835810319965862076,8726096516971579929,1018351776603887044],"proof":[]}]},{"witness_query":{"leaf_elements":[2539223367126549911,8256396146505486136,5255032785575384144,17884429096993876231,2824108780031516423,17238364461831624640,14891340276356591570,9362400839400757922,3715678060664605991,2443797851679076792,12026089471781407335,7446066530604113361,13240098941553946360,18226667455360905697,9549152048824848300,4111069302940153441,17196042177538410736,11310196982232702872,14951466833246700968,14456052366746128583,12597577877508941020,10424035775610285868,4071105488638930361,2412145417476059694,4625728509177797372,864711586838650820,17997803767594847445,2729704061883328525,2766858475870191487,6914837048500087756,3569868331872653278,11756640571022791321,9447562273936683726,15503754079407352202,18184278529560373066,2470830262988126154,12634815895648719492,18098433246550689693,16434869502732875196,17863425698485309907,11314521563961706658,7402848491789423604,2200890695316261168,10248646693478274462,3525416878531137137,14468131830676527229,7961370435021859403,3477131836686918536,17577451543621653090,6217725604344267383,7157105032324194243,3114920311319056674,5477069365269728830,13758794898689352736,17818582983488002489,16561891536536616916,4490928017753635921,276924020367191693,913871438522095070,10715861003341517850,14762776311655160065,5904702689282333843,15768065172131045843,11130512972711180167,12059216995380587086,16949455798973455083,13107844308676777398,3931512969620095033,15848880500077649647,2670221386832063676,3833923227244305920,1425839565741131136,15381526164962014007,8981105606947723101,2203685643349635314,2442716326045770194,5309118842104147596,1607031717082742454,12119750995907081153,846435718413866913,10117019233370993388,4629703634732026276,9571434746324653800,10631576546404702537,4765875822319506829,1979678794542929995,8417236910492802956,143859954309767859,17405145861161915553,11637207906441434728,7196142768006054284,17396106378530702101,7018450217110453629,12660774524736314728,16802428035783112256,5640402179536216854,17349023800459991370,5253616261220777770,18418984389416384215,11680016124513934387,5447041445419927232,9804739978311907973,2692360064975184440,15779811244538069936,18150657613827227866,9258297166831357698,10679027870617035344,7532113063448399720,6567400723387322196,15765368724773597708,2571860162838781665,10993214014919694016,12096030708267175403,17188002213267437843,5607229476754765848,15022138125818746834,11165051835676676231,4943389182672785826,14573369668646262783,13240408701701495964,5711753562316083288,7692903016480232552,5904426650312809621,14835372390568332441,6535468365287050371,7021815760500799915,12441207139379084755,10331860945853779999,4922805333981625903,11932608518751330206,11488203649672649311,2108914099188035658,3658152646830237340,18444570443520894729,11370107111393349600,9149720788543516019,2688742255480630927,13295177437278657637,3731133029682063597,5196793741089101110,10125624836154524580,4195568548274780685,11115046492095443978,1368817366785991879],"proof":[[13146481120112129526,9185791965980834908,10750292369857408408,516734406351708857],[2772949767310016321,18102998440878340907,17654643969657334057,11202946231877169820],[6424686894036245069,15419466544300216671,15437563444669632108,3940943081950990889],[6738634306530077223,16585699492539451020,16994558805911404168,15827490348481486193],[692789839382241890,13675062765899305794,9180066082411875310,14504856611999260434],[415449423304359142,1133445868955386335,5261214285935782887,17703184144081045808],[5837642880028964535,10819130191298628063,3918954795658228621,2187542950810534737],[6471303889006260735,15190821004880768824,12715717878082185722,1522011799840459782],[18442095533291018148,1637689765110402053,16845004827888497529,14194938486473846795],[2087669288803495192,9339063967949099634,12499268591477936195,14092238105535069550],[18283175517685687036,11044959016987738283,3217843488150345889,17837777872441677423],[11032481282398266658,16469302595234575990,8790669568176780850,11459389085748665244],[16711192004937073893,7812945539203058736,12235824629598624857,18222678834960857436],[14642826941721830992,12199323220814497001,7619709942261643440,1324529611099754234],[499601021688771915,490594726026214526,2436752795675718753,8091982212759487229],[11527782358675222967,7329642938926174414,14341101577487875752,14986603775519913343],[4131246993864415573,13941769014960634211,14244756967470440488,13400230066119539514]]},"stage_2_query":{"leaf_elements":[13987044139714155041,17193865441550852054,4946118015158484742,3265951237957762556,17002711500281673773,9722110580653500104,9640737914420103433,8229593756738565456,6095565991526686306,1881637776631212068,7786980972754155324,1014412447430037485,5456796019918119001,3551289381536522988,3171366830622219781,3958525159504645524,257838013485655391,3341560888282533368,1120915688333072778,6869858948501752389,17459649829993107670,4307479731302243344,9282202449255458280,6283839636932935872,3314505203151879446,11203864202736503151,391298492505140530,10697349070072370110,254180857385290082,4699830683169138999,13834418586930336016,18047060053662131620,2168818922634580007,8531517630584876842,9103914633317088169,16894027258706151180,3670333875323806510,4532772584904164539,18224432527009009952,14732670683890871374,951828796344413212,14217964752565934181,7663977270967992786,18407793309527051743,11463917487453012004,11006800897757207547],"proof":[[2334193471903554385,6225258135107095295,5365960358307258756,5122810436585812271],[9638861497587855624,1464252159125237209,6424814653042907177,18300242302404175326],[5505214241127336666,11814922117992094913,1875113320542360125,12715512842828419330],[8019589569104042152,7733465219145620575,4481373998791150583,10859880432416695494],[8812660938391666615,11710089713165653348,9294795827276748820,16303519080970668793],[12264476418638304052,10837817995421356758,15049934533184093163,12519787198609752920],[17904236928662184209,18089315561477614513,10940985848088861875,2408174953957991853],[17801808846801834790,13089967639483013764,1849668170672189211,6195179124357902469],[9509496150890893332,10671899624817430582,8985091200323314828,7100769729537370634],[14848773180014454387,4480732316530824450,4733918732353913041,2529486051274011726],[17903276812497294737,11665977844963595016,14250480809778419784,15755383399897077988],[8363313522928966451,5295983636440527046,10724845929913554488,278837369416798153],[16598715099807633831,791292817591699767,12928270581987876032,11432526976877124495],[15457821812336345357,7746547016285884839,1290081010883453512,8948561470809249257],[16223035612808764380,11332721853906273158,16464367561192575616,10150487068375660440],[10693398880102404674,15442008528330274585,5658332399759345394,10702521366286461221],[12940350048878081686,18318030771015011443,16734511954444878893,8710777237650930866]]},"quotient_query":{"leaf_elements":[9034746490222709128,18200065658062780799,7633266355140666207,3355811765259134176,1462248321912695897,2260788816887681556,612004286518055294,6603753773345132588,16118693215405690391,9173785427679484050,14166174802047160209,10479913419764539533,13965485089607120578,5802097434242420776,10569848942405471243,11319269605561921374],"proof":[[18169227305467855398,15418575796974280015,3202780705298630899,11158936450100391200],[9037834751015049226,2185772148679530300,8194870161748083125,6101192916740507912],[9867215169123039940,14990300185135654216,18290604843147873090,11957074703693323192],[17345577424097568846,5384306935341767219,5361041413537323900,18270988932543029585],[12782959014812691941,13293378270172678335,303154100539051094,7503660528440307136],[17022798197593380722,18166555838702883304,15593029465143784366,10792503004539863823],[8460576837167465116,14374510308576134631,15970350383189120061,15797546874594303044],[5545253434797137192,568816379770286979,6546679900155930961,8629330750146524444],[17609833109638528667,13544399119708465899,16525428732103431194,16382462096363453651],[6430271023281914703,5316649674957486825,1470536433043203479,10680275337208847679],[4109907152924542158,1539362816177733743,5301713498445927057,5673644794159564723],[13924061941423192286,18318101077984458026,10764522885730042005,7947298450032556928],[18185391110668183143,18215760411189788847,6673327027046071524,12923235176070648566],[13740077252299184982,15068673551029823094,11228632027412380143,15734194994631345399],[11529839688148445478,9904672654954967038,1533087469050591783,3940373389184848924],[1920978485513619324,11039587626305768913,8541043003930432246,9136120106669000367],[4907767893259991028,8054542250148444320,2777251878088069259,14509779907815603908]]},"setup_query":{"leaf_elements":[9847112268745501226,14863256989785059644,349688606916822351,15694120449419358935,2712773837634543404,10522424605833338205,14085184374841136508,6069918389210846419,3427562952182533088,2531575013474942921,15912736268523125226,3557317839901725641,11328581752504058914,1336373109860255696,13986541396146308324,1694018301009324553,7585312282959233303,371474624200700691,18059674843874403948,1085992884587723477,12663313968939036689,1257392927020974936,16594009267227938502,4884703240743000889,6049923190018890998,2761349310642573395,14009616999231095675,16310356976277664866,17864669994533477426,7250668337453683036,3909300674191450167,5978623081654488279,8282610713323821408,10323657647180814783,3351574063715032935,10325376115213222201,3473009822984903584,4598106253357859919,9292438715611767079,1691559135535517335,15173290351920667210,13962756659686943429,3871851402964821256,5518685134982141246,7347142348965310781,18067579199056621293,7058054749395625501,2295299251314344930,9225945918854641426,6149697160867650619,3909020796337248301,474919214088218637,868782303261647176,6484687933042063193,2265689714485278036,5837437468098573799,5658489973898614130,623441085929681789,3407391187209059512,9979554215401291053,5389104131796939164,5523192364643182644,7981796187271176985,3009932394087457350,12193093893480731460,15646197005839689756,5628975011787870259,5650467036270923145,15118240365572232432,7326184939541605813,1005217692159910724,4196851694715726067,9625878846314543101,939163659251859895,6920483536580801243,15213329408413246652,13404381659070992579,5914435126077839616,18317164568429261865,16768213763932430077,13504842997071441058,105002564659650142,14050065092672792756,9660056935508378319,5544643868713870804,1913949576653934635,9393952804650966802,905793669539940258,6250070085165370155,16513826894904653579,9420359963697561531,360590795966264818,10224230669999868484,4090925504221196068,7332465264498201387,15347610512140147334,15738626481754790595,11472166407947855916,5221437398391458030,10817629080879014727,716644000642676164,3940197647570366509,801988373914291763,5151874206502347228,14575631488181898312,3042187906824830852,15271723190998140596,5519962806238146055,4008946884323616329,7309602282026722844,1756615709681278277,17729580445805436347,2777227848579872259,1076811628933167879,12722407982475747240,16534694298025460006,1092508339881969640,11356310790619681719,9490760975334538252,6343556919322455150,15272600860734854756,6317988626061641562,12274103785798444130,7643200948298159863,5965329134630635420,4947237432587935590,13908938106022462731,8365640705949430771,8393288374629989484,804046812965968242,9836911585785887741,13820540785246211740,1438006391358268612,16243687257120624146,13708617143127117396,14994942717515120769,3118409434602578209,6563353560882620340,8414948479918367052,2002534729034789864,9110943935275025512,14977907159935148410,12261473773402788399,11688116310440394408,725331950036027082,8042939971016115147,14520910428343464737,7063896586131215772,1612949164649851240,18251853177859048092,2530504944129059120,15092656742512427898,16526801408538281985,16678434784492883200,4136791651952583882,17370212944058056780],"proof":[[14410782256413367035,13501737704347689019,3348192987498705759,13337313958705184233],[5269074950010541289,17910322299674407523,9949799340730344509,13252495836092081227],[17431090549283262494,10037180095904889922,17707888723647439490,4960602182209885668],[6671654188098359451,791120222789711645,16967938660249829281,12345699763094447654],[7115179684365655054,11087549471711987795,3396482068079184850,14470345314532133376],[3598752005644391076,8057997089264768613,8598793576036305211,813696204582146458],[6142966532688409548,8678054258493996339,10785255898062154655,6428945261704683984],[13798412575247676531,16778077181183808703,4362982174942031144,16115277514257586965],[13996378062085603307,14387989171474585301,2026443631455873140,5489558827131239581],[10421817129206714306,6166366212924142666,11628349744810386410,4545054262664242098],[113752680822964121,15318191326839510705,16958772958120008832,9515081578836876391],[14937943737946176103,4405961166687550302,17057938047725210063,13996623502609083202],[17209551076106149000,623414069502809208,15701950207712034025,5427103313699549425],[14934602439866889910,1958290372258237956,7349388584616373206,1722421424693135390],[9553734045390339084,13739943575955771714,16836990449829495936,10396004934391702266],[12126118751853742528,10995391132364676709,13052548977393997118,9094159610493951972],[6870603959408415557,5624116706049520422,7652133964888741811,10524187432264972050]]},"fri_queries":[{"leaf_elements":[7005193504463512539,10312564243110233255,6009298725027369527,18436241158626228916,17105434015703392996,14371587337998151564,17841962367419947199,7344609178887982841,11926782224416658961,376272068680274478,6108709165247911700,5863541093732712173,3768028158959380914,8902308761791900482,3270501005113337597,17812765793821913086],"proof":[[5735305150724840566,4072703148189481345,3421555708725907609,8244522312860917121],[17575105128728287479,15998582116200305941,7201418650052972472,9641123601816952169],[10100825692572788055,9950622481072869773,13361603681665060658,3151097152638427416],[13177964424639837281,301829932552681826,7503210248459928201,13357805968474947538],[1667098042376191171,18167547811534278480,18268042939529830495,4420668445410173134],[15499197185235059311,495611887781878729,4332259672504334000,691052825050225327],[9004950370946487996,12570089313924370021,16518323138287209069,6963471675282988768],[3464628453154075495,921360145671331023,17174030346037678751,12826978997540647305],[2356031750414985107,499005322091788481,11274932151855943876,14347835558937160449],[6850739216739437522,1991981573598440838,224862685657895013,17236561622899199432],[12866980302777582486,290096082835060991,18431716523446414284,7160222833120432566],[15497876071108069164,7267249099480991535,14195085342664102842,3863787869330240822],[14227907531368981851,3299918352090377063,9079540946813844040,14067106316619862699],[17797284224233237864,12190792518859977071,10373917212654131311,7623241933351057876]]},{"leaf_elements":[6483428527470928147,15478126957331177937,5555792943780085487,3538435076738036285,15954591115731884987,6128154245706220861,17248778223501771315,16700231759109218821,12218461332234549729,5082882024505077299,10151094282750938947,8750720493646199705,12908851723040499958,3837777774033529085,4913256552680243691,12591772742872719318],"proof":[[1751706317497563731,1088684879054624425,18143194171304255725,15287865251775795661],[9864552705088320962,11518081697123429231,10973150130338137767,9706601167763508287],[18069446062588835485,18400366603440914241,4903943246779913441,7835231563887589156],[16288467067411143722,15816893699626103386,10464951101596748586,4375501906276658565],[9886686409888646622,2540769535485054673,4653479460943427468,9770247196649252326],[1070241023406632403,13453127608259434884,7701579118412363104,8807039395925421542],[13433093794480466141,15097901308960559572,721038654390063402,15836375296366803101],[6543494407947251108,2320088005411466123,17304701090263275607,11443022229421587014],[8831854704239338220,9745829563333514899,14537234298913550395,990052432487534416],[2083731320593879527,11321298316090969006,14658969833713519578,11366407245708934581],[8161171072864732734,10440603802106643560,6180756988961224215,6889831446143809249]]},{"leaf_elements":[9943766261598493501,8182128098700521240,14011444399726522923,12770216437933224134,11233971097253562423,6608280339333585702,1707860739121387435,8328895556478205130,7783687121442495399,11863384967396528436,1259494329793639127,17565459179558184779,2948929579649542745,5750523206019924405,6980182916644433452,6678830063589830167],"proof":[[782330598267839258,9256855415004502294,5522259475955373817,16733426199855002053],[7990733860922449399,3850926122450431863,10288714449264322445,4759878732164719624],[12154408264117150297,13863871230540473925,18386015156625389282,18011157902414611892],[15776500364805525040,12494315058410096906,3547183112152248770,8204912220626784856],[16780545202679094870,4421446789133509357,6458186716248289919,10143174203777788009],[10025392773632267332,18240246690218643046,6220026842322683119,13482069706163222707],[5944087289303131341,1366526878480810646,13928333602637998699,15146785386909763270],[6720534697580595973,13474766828711122676,2473097082919214989,18068252403595198348]]},{"leaf_elements":[12898014418559939118,9154919369982118954,9481807210717182305,10234985040534927397,3609481773949654083,8148875968297585551,18009249938179049669,13253422983311474586,2823994841341609093,11319935741460911811,17658344989180559323,6672331962362140102,4506237893309668810,4335217073371288306,3924676789128789710,2227341659097296973],"proof":[[10101894524495599140,11978961337931191753,14058927862508671707,17508774854439258995],[6750790458204797338,4171680792352138157,7888727325318655949,13840400938334682386],[13009134129400542353,8929842038923907829,2772279457740204155,2164536622126645809],[12847039190984953006,13174639818116613790,11504371774753153665,9076017712480606856],[7745958475259728694,2873250920535013732,94873201471673482,1565932192576522106]]},{"leaf_elements":[14593400273275102508,6309906633185327112,11951149523269201712,3153226618731590137,15587889054422217223,6392110987823427023,3621125936573809567,14576880692054719856,17099860724011204251,6185746063294943650,4190495433158066683,1382854502718839598,11821090327081663632,6488081574875153781,12460988453342024029,5740494408679326104],"proof":[[15293729950173134341,12922832714615665733,859236950517306116,15306405013353736461],[17656621556331237756,3884539910827412734,5169394874961648628,18423172052389089955]]},{"leaf_elements":[3103352029016043777,11936003578925779291,2481494059698405049,16760758113560209882,17943014902864064829,11760753107849584284,16263520714716793081,17159242401050750845],"proof":[]}]},{"witness_query":{"leaf_elements":[15484969893779983172,16404790872780911258,3638357847975950254,13445849603652968307,12394127623939676304,16853598497023887441,14456714421163946890,5897865976521186492,14271458741074087556,17541523492689832170,11455103457883170205,6987407328384627973,889622316607502176,2204417331380457339,3619253615586580627,18022334083458443937,3912106198468567343,2354890124138636079,1125826663042611326,14927434081995289920,785081099202880799,11666692293223979328,3268772427103258669,1077805627839640158,13837567584239762693,8597642333374546789,10617194570485231565,18347693647180245573,5403318457354687678,3389216363054420641,8973965714234766487,788356962877069738,16170656868453491096,12656994809355706792,15806013654745885997,18154652144361731420,1475831120340920493,8632653429633772720,2100121829747315009,15085974901198928183,17150859179206107374,2998175041926619302,5613553772043564579,13085534378593180832,5562310616823538198,12164323026675651293,7958613927693670492,9561734147254958087,4305164006174891106,9920809607893458471,3880174429835022432,4834374256751883477,18111148939115231539,6114712754520368094,2346942084802967415,14128888159089510648,575281749755571684,4811342432871293099,15875878808372939505,16204217386982257487,3837451212138916985,14147065756518660501,336974006149469399,13544129751164668009,458073186031852881,14241850893978345363,10595698804741810109,4265000440360643137,10575937774221284937,13941241052522265001,4921611780672741009,238469804645273479,7089829807712520263,8705181872317375025,15116986236267839325,4844387747260606750,6836067089822227192,1738508364229111946,6567093168328192427,13133253994411693829,10315737035599033255,17249930131373362364,14362180293274692538,3569223662426792559,12300615762412392363,1172299740152313017,17604901503629353345,15105184895124935870,9679953554752172642,9797735462833398865,10459957231294395293,2301476908965579269,12599205615554253339,7338224259604359447,10211219496611503146,5059074147845002698,5659676917240996721,4826427748961278604,12595346505473856496,10748433136809695028,2532387917132485549,3838217961921437252,17703999077318478258,5322206204640109227,3237716466816023397,3394784186517789001,15142284690569934719,16274561748938804368,528963796187997668,1133784458891888631,13758579116422198721,10231602246452222377,12166164947226557033,1563751333726229813,11183490356346153306,12972343494345013453,15955575184980103945,3590510770252310947,7578892510451069370,15688623130754318195,2027851247346710300,14631883282510249633,4046840413989331807,999935868768153978,15390750759855844806,11436973773470601445,2468645091946542456,17021691782604805381,9749103544931597292,7641282295776490966,11598592251958979765,13690705069237777867,1356979206647977877,7598413268122372023,6335018284281058993,6138729835077211339,13726545881738989889,6476301308010892476,12501136741565140367,5187889120963923806,2261071579720792143,13560472147047962336,14907163552444502733,9020584885846999926],"proof":[[1624923112968931775,5106126978764825849,5413722437250814639,2165855395916688257],[3614112261046251651,14602314542353125544,2422661697302793483,17135104618124537643],[460366710963983232,18122656500251388719,11780651389743860092,4747733889303737290],[12118163677226285787,910385579471823520,3038460897937910146,16105918142010147748],[4155628187883503821,727155655284370489,14287373514543488144,2371729631266785860],[2291034390183332835,7697191472101354212,9756041753377462399,4789690009901122704],[17484780334331560494,15575757043828503563,11727632382453818002,13502871512799951964],[5390016214762325554,10851196380068793367,16988442855865926175,83788981355002034],[786441388492963718,13758580703169602471,11744124203043308054,5830538077931609340],[11651441392750296396,15949588274052351422,8956129014634212738,7932464238797103938],[1835101863768445557,5187956695340464216,10531972415855199022,12016062993120168232],[9361907073787619363,11723377463080128422,2905404315918842535,7900257036775401359],[17739908035755184067,16219824495391583069,13670227207845731465,4908013266839012338],[10245913580121522780,314097629865385397,1760805267685651146,13360821470845174991],[10580330045952631618,18210109412306871855,15185603242483274353,16601870024971746666],[17134617493362201888,187842468183985438,11980778488272843485,13795208586381332089],[12698140864963633855,419357374229537337,9620795343936707768,5865575737066574990]]},"stage_2_query":{"leaf_elements":[9797267199371253375,5313837382957023098,7715259683385248290,2071552139179406395,3856889798090710726,8626748221601388769,16960154993484050881,6751215284315873088,2424455282657400268,8511516148175370117,11405820200296946849,10552507534741653482,16654735706002578562,6749801474733584262,13227709145280050110,2808390147478388908,6144834174678336215,8329701542974675424,1796873138072809794,17171758176351903031,15700918757665033211,4398690313323238014,7698216258355535627,8015181653735944137,6155640194728641888,18064529381532057716,11034473796494159840,16180183242264976068,2985075449135395926,9260383368003010182,5051812170421302689,4334035007567729729,1698037208633626921,7816687560107802956,979808884937518536,13362070495291286975,12291198247181403425,11833308028264198582,13572555128674464110,8423649046437053732,12219534189836174080,16937054554372137983,7911023305735549827,178128998414866778,3001298127946668952,16645403611704546115],"proof":[[14728517244821547398,7557259836790941850,7544748747992470012,17809657671344117611],[5155339422072152794,3900637643226024732,9236062612488121564,16999355682044855637],[7355624347331802597,16341767346560296339,11724203377209178469,14983771323502273831],[14366239323829945292,3532380574121349587,1220101114932881814,10173503564360231766],[3319186534684769837,9521227230544816430,10785328165606260771,14065208305413373008],[1557076701805470776,7347856716024492481,17343645909910130157,13586625844125122950],[14135137450284730452,624629281214782784,14116233492949741526,296368295139786995],[18358600532428557138,7364370598344765116,13717658818102621494,2640228408590061974],[3501847009184745178,11372206115312105825,7070504295262554958,16240739278217553127],[1504317100343724675,12511713842417137902,8335254647105757247,10236038454873930623],[8554551216920004660,2230492512752866285,9186725936289462337,2332307091211769238],[11573390644175841493,1706872778806479106,7499624804684556292,7980822485025137391],[9703601148945395751,14934500836301919567,5915507350171533854,8832292617288758099],[8119863575180118851,1504742555409947432,1237279018876096856,13235858065688540904],[367898424570566896,8137755050054760145,10379342972369113947,18298303448950534836],[1574636867628112338,14593397744862756232,4669446545421119623,16109745754166260757],[13885167953277892178,8555964237507770117,4719750036722080927,12815453938056583397]]},"quotient_query":{"leaf_elements":[16788466307711536843,8064253309033876,378041552792315984,1371249109212483070,11111590278459719488,16058144106100942614,10119608378351257743,3331915406691746163,10509462122110057651,15899189353405859710,9844883865352630097,12595098509497107316,17851671054513637049,13904575620071865895,10945504020895536641,4749339289607447017],"proof":[[13348514001388727957,4775767111145105033,13716727901572135420,16913631903608477065],[985573322626424623,18132770051292578857,8512133998600391875,14861540189418315404],[4448436927559971018,7462219060656090230,4606387613564260404,14216483377171477788],[6310332647099474802,12341776567769510746,12553378408523605649,3281381194218903166],[2814586428646048469,4914696901107287047,11746101773098873795,4689953276262682158],[16779373940697849237,2216047868858285160,880958383171957681,6801896278683858784],[13039189684547838186,16373937501729003856,9961606196955276496,9412737541228309147],[12637789825160298601,6860979467135972329,2193906317471375850,15900322147239963103],[470389365580833231,7596684158760063226,4659507514059600635,7421862034774373109],[7642905228113030541,7309583316719070826,15348635879907545515,9560031339382139634],[14278490819726701021,4919297605431769744,14826380101300481024,15726985841394717702],[1981546024166746561,13079795299479465484,324931632398405565,15109013050619810022],[12567317101561953514,13290842681111748723,1381092996400490715,1909375608145969388],[2560919096651721762,13233136808376946884,16885630051650527221,8099021027132558044],[9534380799511855413,495072294960755210,1717921508308021765,15616678203382664111],[4357853304662596133,17214980539843074930,14850088797960313577,9017137664508958350],[642646296282338947,11452596773553033960,8795257061196785695,10386969935657262527]]},"setup_query":{"leaf_elements":[17555962764024878231,10689553405452693483,2339335014584241148,7372770531598001566,10358076237292283344,1931581405320425640,9324741830460121282,2834286311072554138,12850932528319326037,15438639500731229943,16084043642014827031,4867708430977905837,6576622912060240697,6087576892240357770,4989779880649264461,15999636326026631784,2333829836206507492,7761942423226141193,15399736414714446569,10427634009995025494,17499194510238908546,1425119310742634634,1508148843146281271,17298996814872777933,17492559308148252474,10323609011096585468,12921469760289147981,1173737987663400779,17897387103877557626,14374550823277728359,12414882425600483670,15033388552377863616,10598812745777421634,15380749416554706898,4447810874596639267,70902532678786538,16271052358061211597,16937575199558627297,5604023577456587995,7511371580719013991,2849486636307700282,17480057610937531291,16823331979562041527,5248428432937043469,2969886247915648417,1597959185623997544,3765393491208016658,8399762545566567470,5171228187443174999,3109696851998198397,5692634473089314019,2443058941655303129,14741443433776068483,4290949032479558436,11780508174563424560,75553811956934062,5162723722933057431,13017438083407719647,13107695538774032373,1915076587740523464,5434432973489823740,16192607791371495964,18061562685556623009,15767296227364725156,13827547517779765340,2189830094061997690,12219800784964367416,9417805862903774930,2158120913868142172,6551050751956084509,1561967700874577036,16946297510725051036,4637056833722973568,5233566443385751994,8588598393102407766,16322120407879429377,7825257772497874313,17014639791554312030,6851151760461060957,8217200778221709954,7999727589316796771,5027439959337086543,8616707266094492576,9753957041541675217,5645686270366171237,256397725868850869,17569419098433903420,15356816008316539484,16284611219527193112,11308555861594241428,1515472262449639085,15754936051945194359,16882822435821253761,1493265815711574081,12270688576781704689,724463745768634261,6139801903574449774,17045418429493023502,8019564589444741054,16110158951438839984,9023513725139822961,9317950783786870432,3912685905299028939,12024000444880839201,5878369233967050364,3099133997370807662,3029517611070086049,17585238654547307342,18225208098883326765,2072412327175246566,17082710542552118150,8625480855749401712,15618444095872652921,11458364634481723036,11498742298575837500,9983092942238156440,41049455995095929,6406033061338496308,2945815151106755199,3342827634783361397,3273780618713820051,17534202971331848913,13183459980465466914,2298806603096061480,6894855184253768584,5477465404781381864,14741434816136346231,2281757698909921732,12209759392212069628,9948957321291651663,1986327895609513233,18385267377268804273,15964041097687150518,9879469288013266718,9927877372813556265,16493740576761880185,17718086476502993002,8057336982824063012,12033263952543598906,9269879903962365113,14542512669013646200,13417053571136831647,3733372555400315305,8965312049977255458,9136174242304032127,7577096021894883804,15674038534781262110,8247568016268672103,17068744247570579740,5012497521329256434,12281582953359193594,11028757807596337899,8708290968731503553,12899176611378180777,5630087904901501967,1306262437978348307],"proof":[[10190831711301242022,18330658660778653249,14342660725949831343,11467885911193174221],[8876201167896478507,9971995083455776913,15977288206464054535,5007854947523457064],[2175536961500113592,1246534400055277752,914882209391700391,6809037848833384378],[1852030523826232269,12690438630971668133,8733871324073146871,9171262214105646605],[10990868194332182166,3644530417560725813,18175908593487472383,6314605509301110245],[18214826868310229807,13613783478290133984,7588687512572951071,16602332615073397981],[15379201660668038795,12626938904886708537,7349707382579508778,650889269943125872],[3854199320173569978,3429273351487467907,8895806683292568283,17418475041855237561],[8413795665223034881,9559325172268293359,1324684807602859933,10727223736965766402],[2711423310633012990,5979565916169019359,10623450811694047510,9333052169816511916],[2640271470041261709,1301800209291041064,7824330746973652010,9305970443696344329],[17653752633954684352,16619185501096330396,12540253026364555625,10982015277113659632],[14657119838366641283,386967185317241864,8629343301032476597,11065994328433094960],[2086135352802682066,3433527093313683307,5344819223215075625,16969387060499637929],[5352150956151545359,17778094890981291229,6058404588388026177,18212855547165826657],[8190593271882194398,7115468430098159643,17784251794283646679,14448971095443897031],[786433969103539048,8122187790720253298,17324655261546370362,16556773082047786574]]},"fri_queries":[{"leaf_elements":[15344072486699660870,15608740012258086988,339176732495448197,16179181821407623438,4384937548088823695,1154014296944041362,10998006160905424517,16445744954717022491,10169694962383059018,2315947343715270608,12829607703804996261,13283324814789499486,14192956538290351819,15042222663656656418,886638965421948113,3664606682118522843],"proof":[[10272384609781128936,10387470774900492470,11747948197758447340,11065408375971246674],[7894028212502128670,17245653577857183968,9966120356000612361,16300801758702273382],[912585983178784044,12101945379636669073,5403896392706329386,15557795074221606409],[1768119287636515181,1233958615458743152,10042301351732886168,6623303431715344691],[5415492669650599361,5393650888898812351,16374847815185125186,14915598927817750108],[11311110246263363236,16203065529866530458,12074739612408120163,6827727850150678641],[17272881451068009604,11617544328917201733,17478220585293447131,13460898045192811732],[12626824287263035655,17059067618263967132,5609533836057345896,11262155038715588574],[13460775936018346968,16048424944628198281,14885796378618711977,13709622175698657453],[2055506257223019935,13854659738590296314,7795448576275559987,7397535023477921437],[10309129858498558341,6707513808464721997,3181325029145303126,15838403000973530471],[15604979734507043997,11610233492028050863,6709863941018542612,7080527578284617478],[10229615385892962512,1718756580777323066,4707382564778896886,9389804507582440790],[950518108147387034,14461496559104778806,13917507090447352020,6484097189552047977]]},{"leaf_elements":[13816283767222566016,15710045906571122779,9831429162093352692,12133534435285074602,6474758998830906114,1927276835852157170,17713086918454250797,11510685858080295548,9590104718685455120,14090460143984783983,15511927784281794666,14812147608796438761,7843432202803839306,6414582019529857395,13773432157150353879,14412354849431032315],"proof":[[7367190210609497932,6792124208727916627,17355779610891329128,744721822602945008],[15302694157462099895,4890486676024890292,14138008394662120891,15319077797435592770],[4495659095285925578,16240294365195296588,5499149392571046748,8588658982664260430],[16716247142705997326,13097682224076673694,4707323891317879631,4137495623442163871],[14244611181634510956,18202564341609757507,13396863049128334145,2625723341699382083],[238946023092786894,4360320110080826398,10095686805910538366,6720743249110826262],[1156910476083878593,10157363500216602745,12593788263289470587,3160003526294531774],[17920507623839357683,98780277043006418,1878497180475598760,6821677784625668547],[9121011749794439349,2536714253601986745,7296479366594970617,13068223385451608737],[11507929926413888592,3952646010530610676,1079003151158642278,6120734590715615278],[15418802502015684347,3748451402095185069,4925493761703378520,17844205222826790497]]},{"leaf_elements":[4786013804868900496,14329642390359785380,8398517051440462495,3894791586860590453,8037958176754907445,7030600524172165420,11680233595583961151,15366091127769016147,1517229660373688098,8871918447460390287,4702409710888421572,17790936247840551045,4681633408346216602,5509471649624717277,4093471091998756510,14313008062453097814],"proof":[[9406570761810760105,11673100106138198833,16060933285945519098,7792707379878654534],[4912401433170240798,4660067821302573843,12922849740471237920,7322116717879664799],[10504325250082457714,2082076710191031433,6305881596660369196,8851181754916662974],[6864425559969077119,12375710812272867183,16407519134426205116,1320986962894536029],[13707951117873825411,17670465992030569648,15415769927799120366,16955928906728301690],[4548528687289471365,398903681704784651,17996135182076109005,699358910855226803],[12456869959304718661,7739810951929326255,10104392169542390190,2294294866746549694],[3212075062214438924,357583838110179765,1255898485944832398,18404599682258834503]]},{"leaf_elements":[18241718037583134033,3370136073031854997,13333413530372334933,2879079407008121167,1058182467719417382,248238192176740762,16353901370063422460,12312457941522386783,10228228439629197984,9915624794689150816,13865398289816650231,13216917397950521640,16185161406481406127,7663932125843158164,3303423351718240425,10902922593051309409],"proof":[[15880311672788884307,15313789695633289480,6949350373793959076,822922811929514720],[16967162214540809313,7917239221655762357,15381347874007882853,1891334634707504568],[114106257567448089,5039424733170728636,9391311288302047408,15182568808806756339],[2672309755977980332,5187402289000152348,6778195048294274822,862334714937443092],[16725837145914548581,1125423394101345531,17017529173301036278,3401633365302970415]]},{"leaf_elements":[16104655806175047737,1881940834397824730,17411786609115749057,1091790505454646865,17323693140772335757,6447543619076328413,104715464376403502,5872382279492108153,16474304650616669804,17578052387928834119,16898786332104516971,18196806415198528929,16245969746828663680,16558604784865910672,2785721629986159908,13051111598487616997],"proof":[[1145646106485540453,14046992658961309318,14640986759384052772,3130139382246868039],[15514906446679858530,10979498789109703592,12967136000864485334,17159923573772454695]]},{"leaf_elements":[5913797713474501816,14390836815188810001,2598086964460305874,4219281277613110736,4341490336555859025,6837138495876505826,5182460282140934405,12936941785162437742],"proof":[]}]},{"witness_query":{"leaf_elements":[13326289478042825853,11109708657707204824,11557312146861909763,9636348464942397684,8686510103159860307,11687059724224091359,3539689750723943967,16603489391290891520,10019758475080527574,7868894263944646077,12129842550308838,18367657601325925642,13632843128049058937,7199066221958421984,11090348715382759640,11558973673909125353,106447245055353435,16642032170644180137,10629732085908703725,4795203058297657706,1083445840839813857,2778582291154529565,13229496585174815149,7539664432550014023,11572261600047805759,3429635303216599463,8541466138059000405,12881159658300180351,16489671183239989332,1513404390757997108,4161240333154044726,632605784371348401,5986732085102746669,3633254459901925288,3417353167319134182,7602442821370749208,10064208152277673008,17466649666567993891,11804243713755823490,9391830605591922051,17685360647353605883,15442926385484201078,6584762417585910677,5830432632547044156,4670604909494658774,10491187670216848824,11205224721561028079,1664743820373405029,14559432674447249044,12483343650251205406,17670113256303894828,141667222097656790,3978925448615661365,14982042598069006320,11240893378413234734,10892698333834151715,14871727494961868580,16469926183334452713,8455620798351429218,12197124609991253042,16864217873256898354,16703174306627561577,12899613285347488487,9618816731127601974,13719261291190306109,7015287475794392018,8717392087599504702,1899438151096431667,9911082180437627216,4468468229036345854,7478810016707126444,15462572817814439705,11368136257632929190,17648294342901788657,12117185284048967599,2093215493035244499,1232800482629164500,17132095935942110374,12002222601977041079,2362829918347235149,7111271876490034702,8070405740650984326,2698970499274211906,11688263884144235836,16915859123788745424,4827427722970645428,8251213235780563421,2313449370205429600,14348883855276941135,638818848110559053,2423981746157700467,5643120073295161596,15355143814390995556,15582920238269821338,3899096735845731776,6351846413871211390,12346317789511329978,17246093975003795644,9554074678814191347,1677832223034094923,16718542192408174644,17894027576166781244,16392465022469541005,3722948703072581474,6874597649638116264,5975585767675433466,12920692170056168041,12660994416695104226,15716131204794137040,769285278330193761,6162739823110166958,15036077676259038086,5292752666502884782,3823764418134904833,11612299339731473087,3205136143754430394,15293970374921582681,11985400222030586154,788496636369660147,12065483549043865907,9002106842352012082,1463853514415646490,15592379601474572651,13553486752401680923,16107166631786581545,6621302353084265732,14396953484092753940,3618125361572526595,9334031460710601166,5603607756918906122,3379656937740395029,8844690557304764545,9495253695864306111,12692954519114337969,6816307861124126356,18034689743951176485,1935164008637598643,11640473155404190079,11632636698671206935,8297666479459697724,14660837145734014394,1163833419396610076,2934897239111932328,9732546866319232614],"proof":[[3647475877196914301,3668755484710131982,10178942639111759762,6975682192513983637],[2106808004053606513,17530690127283217658,10001708660852302093,6867900967629577671],[12514177009156792285,14498012765764878140,13981273563239660936,13525871854354651648],[9316050890976076238,1322289508249245750,6314042465547576127,15891732781060697592],[11976204240525828111,2841921546977541330,10022318815254870116,18109884159244881370],[14238026050928894691,11337310925385690169,3097139113081559046,15765277139232582319],[2521706050712445289,13442187023118481201,1159182596056525252,3271049044226257260],[18208129810451891109,4681831263069403224,9495988495582609580,3130704073389320856],[13277275513279645176,1967433308365449917,4336618160630215535,11679149961071103937],[5792738517822104313,5726289230829928253,1364046979983631237,5996540861965322464],[6864903911755997932,3860618574327056983,16921851956668434155,16093035218572493499],[12607200742277758880,1554046750202627738,2752274073753057688,109912063920933042],[1613876561022366168,5237525684964956447,11611810854796406778,10434029443750251768],[16425940434546164982,6034328021784302709,6899879194600605099,2885107160658482568],[5224331917109680441,6598835313364140741,5627357161473253854,10409932730424475483],[1485233880896638379,12071662103515543055,2139412878003956338,12505221719775911968],[1360073737404009268,6704211837639141409,13662088324981550234,3380234095738789957]]},"stage_2_query":{"leaf_elements":[7166901174942085858,13529024550169086850,8003943963129790140,10969692123409826476,11580431348155149953,13329617331228498877,3874813182489953287,11765541075111308209,6315091434836362717,4047230561008794390,4216477808339601977,14259196197570433706,14132294740937110348,2399069177809470010,18165972629834829145,6021928656835606493,4897694428404822371,13414662497635202461,17407695624925118271,16268575344770535802,9883387873005043405,5424729284219009946,14069685421327380472,18270238823639790885,6263802066077866826,10397043340959564265,14336169420120745995,17262023014874913974,17163083779672296078,16069756585942251916,7069731050941928436,9439076520338503919,12132922436144503088,16433830840767012439,17007401350422771315,7332924434933235363,12966354586848911871,13590836892582646261,9000428306913662603,11920337303504703731,2329705660034436258,16823046376912550459,12645041346765965377,17101845545628520696,1133462717435699165,2497541010203595607],"proof":[[8642372382013104033,17872363296200641952,5958390009248734426,16973567527889515687],[302909627261535069,18286937452459712898,9966670867079602470,15633934724964978790],[9792008756145516865,1838211835299036893,18443930211559080181,3456584919232689662],[15304237023431767914,1679792989951385729,9804988539756934816,12923727070583329901],[3328293993854552719,15798652761280375784,4995082914595751741,816742519201041687],[12991443060303087070,14705466647208674143,15435735711148274673,15916270461017310667],[14984244187545271372,7111764737465519172,8054314038390032655,12130183986883339081],[4514835824955944106,14448623082859173732,13452018500389561124,10793616110441612994],[11243957932167277171,14124144671165445914,13499645724994837925,11447766023609553653],[11884099729988116521,11287512620187152034,6830401052407182558,11925100498828103319],[13514951670610375659,14681185509983928587,5041801165798822936,11424890581114026453],[3730379830003662872,2832362808420591367,15408106602485674955,198679265606850869],[16493261453128877173,12384080278155528808,12222553323281314245,5587456436943752803],[13217849053950293295,8810306331426449680,7511852718845653018,2151327522979438716],[15305483213261681942,3870622862172377250,12772033365770669216,7358212229418854563],[8319008327255715913,16607857083414074991,17654496975262618756,15647971105491672436],[9361241096660372388,7871199822756612728,13057621005758402560,12934406087966475422]]},"quotient_query":{"leaf_elements":[12892091433528829512,1028758891697580040,16794627998613103529,11875156462117373899,10974880471783800797,4744869989323830519,277809768593521722,12084043592475942788,16189967407550143184,7994508897716860827,6087468449270463333,1350715655620752520,13849568489316670409,17135454794210319103,4120787299048258028,94080242750450396],"proof":[[8971219264313037255,2896216489450263307,2301473607752991741,5790294485226631745],[17328502509683787767,14767364604090007829,5353345486797735651,15748808631486596773],[1282232373722793607,2083852525779851986,8872158622318973705,6201045315873907941],[12945334896462064799,1693658605700108130,6539188404005832695,9629792158246063566],[11065183787271110680,7160043448271647542,8103853947879270996,12311816716435197703],[16659475568864599335,11707445139049078641,15870922876879770753,12580926693168553619],[9128693647035003059,7728854707056410935,13014378949296974099,17585435883915682138],[18411488046389844538,15332301342932439104,4359132846802609113,16009047039821803963],[11307022649390936454,1157366756597673783,8465181947230868362,9675317293506070865],[6469717236616926646,17841086961258713309,17213526586268725866,6162280905767571397],[12581451596386716060,2555340059885748621,5575152366719166081,15416947082557166862],[16514868936207407480,14551282570718029445,12655011472701039392,17383720014603443795],[7527078186015878869,13402401721443749944,14678893776117095567,4848018425951262440],[11217521206377606096,12154164283530182626,9567627729392084738,8058973431646063114],[13434498397880401649,1377437689243008671,6414084363350325787,8876393564240908015],[16270142854963809435,17117357370502291560,4036575513188496805,7297495482732776731],[15725155024730071472,2846784656528433399,1476956847549245851,3176915357345878490]]},"setup_query":{"leaf_elements":[12575508643566000557,3528069568567100344,1400662062931434453,10276263504756901603,5229729896479732077,14941178812550315540,15560514048148136116,3789709833625304508,2856713551192327803,9157054296491053693,17189478246014503060,4116436162404584170,16216759632610098626,11452139548190973922,11432401329356387967,17043393606282976661,6352816472559161051,11234721012635611024,6378707547853592726,9205952990125550900,3761422205481713058,10067931437475896994,3565736832396713842,8694948652936277790,7213826824337766498,12741886020981790522,17510180342263161016,11464581299873790089,10488915570545403168,1091684810990984058,9142168358159614502,4406498242851898708,9085740712653781828,5555483768898625621,10499387684445856709,14517498955200894824,16216228100216248356,7190522054916244551,12094096182087528299,9535062914390348462,9291904491784644202,5282923746052922116,6549017739422549643,12791749472370683223,7972299397052943472,14480106854642425135,16309640570714688867,11476518524977993543,3334868638963825652,15803773865445508581,7912652673367347572,15905655939552407840,16685796180640506101,7610956835455929719,12657795614459258512,16737461780985481559,8637352881100403889,15238749891266067492,16221719344354084182,2769850954703832313,1102565297666249066,6743467027701865081,445762476599639875,5717627377930946192,12716092967203976451,8676015524280149924,9949262682390039760,12102514582283975408,6666014105043580973,2748849788981033797,14488689693401802142,11143515979916443897,8785083357698260960,7015161090437673990,18122189527770700291,6155141386089099922,18019044993148986587,5276498594139217304,2788250008736576155,12696696894496887082,2102053826402183794,51315439135008877,1485029995035075479,8358745636363144386,12532257651303802724,7670617791091496654,17495862870393979659,8498591118055892547,3296488660743849423,5102624814919387783,1070411740672994068,9877288721064737095,11620679100308798129,262329344502464727,15575859801157065570,13616031337439343865,6379077056347361529,15726681970810225633,1864163926867927968,8724094312924594621,10843625364993488256,16725913463878838679,18435056658929951733,7550428434226551221,13464265163188534066,5682725104533097524,6956048158520710696,6125366756853606401,13378897099137714742,18288586697850977557,2769254992013685819,3777284613079513893,17371142552771299678,6895113899652003283,7801874550185897170,11687852664405523505,9305717641564468664,11213578963323441608,3639778148595408868,7337596043409945572,3782710745241648361,251809031158524948,17488877080702895837,5376098872534364460,13876061279957316736,6399373363523365101,15414647887725532494,13770843179755407749,7450088567009367747,2689417148893633174,16379717361034557531,13128253831627184139,12674394352102197289,17298378642923650351,5514044097716932968,18377157524863642528,5593331808266271954,15514139287339252513,17479242226853058066,13222241046474593739,9883251512094160618,11867564182178112776,3812345289318876178,10882280017914361170,8219501671206911429,1702607464504738190,18283962588379252828,5661980946174793195,14012065146342989717,552499173858495450,18065342696274378302,1404019401800826324,14708917611679612156,12758914771998850649,12546992912675476941,5615169306033041489],"proof":[[3831650847472630723,7076550687052507347,15100951131292847609,15295935235869958413],[11657109017944878746,14094206149475745416,12528470839470573017,16322602990996483242],[8758723573048310652,2633067816792461516,6605934745060135821,1644619354010070977],[16407223699143842644,12071565276790910980,49878654030711931,9547708094008396103],[6884860028044323863,10598192201148461424,9536466351082558081,4269249298946406844],[7224231303248773087,16571144029853424695,11100202380750920481,5883430914896515966],[1699852806647865416,13503865151998238426,3164714637635577197,4886553155112353471],[3718126377668973633,9763733549432328049,18387343956333676352,23072039891052489],[2963188898724327615,8162020491821704038,1674916845075644380,5022635387923113971],[1751161361632104017,10443334829745033669,9687153580098254423,6286474863940691037],[12055721152106414882,218385414478667260,14283960294381934102,2014030622741831024],[2890229681228630709,2933422400286050639,15984584708072311587,15019791296190173633],[16684607790621837112,16988770583498445980,11270264058737885934,8350229230711328503],[12174556676598530745,15333450606408254329,14139691777670182862,16450487331077132329],[13153488764905338662,17294234018794914879,383266437505029734,10715325043533038166],[15832722289687690706,5355226235880548863,4170637444115930380,14904023068600351306],[7584630324897337125,5855445357232526401,15406563887835073472,17749225028109240870]]},"fri_queries":[{"leaf_elements":[12743597111682583977,12488908739736265809,6890254996069362929,17066428392058157362,15674743729080788257,8099544508180893543,13776107957130476189,11734769535243912803,2098233475348010769,919164596914597286,11281650304656879568,15448654392594321942,5387073636301129953,11310045450968928503,12603014942666468083,3769007176296358848],"proof":[[8464351763873894965,16531565864131344935,15024792333336681119,16487712343705907132],[9878874153059875834,6977422588758077829,10064785586304782579,11005807565594634919],[18268628918473115024,9409747901121093960,14130651266684959147,17659143180853763626],[844962290253876555,4015357986769725804,7742983752646273884,15323493181651281528],[7970495815956665719,12415251024837522817,7151921417533901832,380565164597685456],[11092432564968568840,7620387273018559445,14558355710294094577,9285333043037538611],[12394014066040246033,8994799122017889449,10482916137897431137,12027427338056570354],[701508895340354924,1478033512417217249,12944124503788626306,17477755248621621368],[4102434096821044751,14477778486183807176,14492182044619378832,3514086170322238352],[8932169428407099249,10925628745810867130,5191466425092912259,151032757473300622],[14957369705071757116,6652474286024299822,12198126967323416043,9215416062832593315],[3424565659697107575,2212386926341110099,2945411392726584410,1986064473197972921],[12022107492789539694,14827703569735874720,11010683985336556729,2708594108380546783],[885017883695360673,13435321449249769282,5466777689613489543,15313896769676842091]]},{"leaf_elements":[13215619623282840684,3098892213772551643,6066951228197877211,15830911547857823910,1229263952608114164,529019640519013533,4007302738837666486,2459917041839801187,9654195780754442612,9554258083099300058,4623807388085552044,2109436193243029093,9163389263172831487,2830755721161717787,8529414163557584994,14501057705599401271],"proof":[[3204748608458670117,5867042010002325835,14623527284904854248,5191829463771232451],[8469734700266959931,14245440891752472700,8382284786897236055,12089171889094329173],[9469428537213670097,2323194690139045602,15669725586594188486,4134009759038443720],[4879520755202922496,1229729270664450104,5122138039078891900,4788531365470904598],[17658067801670610869,3459689155580785924,14712441106291927133,7014288870866755784],[12510615570717009615,14898032833870394867,16680825446401523927,7883225016351216057],[1751885307770287114,5977292093414606493,10085019601675372462,10397951966679620935],[62276868874798566,8061258349636094117,9400553617561751834,5774252142759418224],[6403746061435475432,15913864629493149740,3308487274169460013,11203944096163982866],[13500830884699680927,15306338317233456995,3299836681659625374,18226561178672362281],[2991006853592388490,8934783177013465999,9854609272269142038,8184295943294888051]]},{"leaf_elements":[5547256756089442335,18312516593335713730,6676232650169160189,17744829995242695929,4171042998326956996,2060111164152652841,3673385474286198058,9912671928756721250,1058575128308317441,4505523943275063870,12726855342053616159,8872274753453006727,12088314609993668818,11375540487689566332,9172387141918215368,6641400959025733173],"proof":[[17312162414459717009,2618621735880422711,2794286298781677267,14074573010857632506],[9815134544235601824,6253862642064772468,17519979566572815843,8398330058372601295],[17361259827307158688,17399029972225295312,14785760625305859477,2550687862850179506],[14657797627150835162,14807588208612398323,14062090023149583303,8169953114503850771],[4889116832836800720,16151933435339874907,16125095080934870867,5827233914720210990],[9653031288271274176,7368529689121526004,14430692323790644160,8836060061319362932],[1806088966856210746,14248697546475838012,8730757304671791597,1502249710639534215],[12483543229731015254,6228922028592210696,6804550060647530973,7609776898298193025]]},{"leaf_elements":[14809948860820008579,10029796172483617922,1933859746959284940,11238130416823652931,1312974523545228654,7851410662834737122,14075821118074670673,18180594622933379287,8491170366512660486,17990335592587281173,1110565176396379461,8551400869737371999,7826810521994925909,8437141641479853800,15063225046035696378,13027607530635390145],"proof":[[8891844701991569546,15290893479532557606,3570407523652159024,14545233243181023494],[16305553938686749035,4039952297608569171,14969718736921923453,8449198395836460635],[18262645052720567710,18348730857695951440,14721440193968122228,5552481305078184410],[120353459084075878,11977129796923774441,3691473483747185222,4915274756070214257],[7378436202281888958,11263343018560466750,12515193662408163156,17578933933619023765]]},{"leaf_elements":[9189383041842988590,6965146586893804418,4220618660081283782,9999429366986671194,4630406983623020347,13765611947963961084,6123428965095967777,15132008706310555292,12812442353949431520,500786186807618677,1689459190315911207,16785331210584185479,10900878928231131599,10840504036657509228,4695360181196839233,10671523540088974323],"proof":[[8007485682100854625,16814109845768904116,1453178838105146259,14110354663391078558],[1130374547257051060,8284282418257759999,7393623318517703239,16641200946473051398]]},{"leaf_elements":[10934508164646927795,12314719184668898168,7161347650890243018,5323539938734047040,427222851664169786,16835810319965862076,8726096516971579929,1018351776603887044],"proof":[]}]},{"witness_query":{"leaf_elements":[12919161045689589183,3475719504899381044,14494215634553770007,656547904164490213,4575068998630595214,8706977981251784557,15302979669323383475,4450665103820604700,12722380272961919275,15159413040132151992,6018461975627943575,7772982282955097702,5000553019601475496,633705626616462576,927996713413802003,2133474598694675882,9590428624074912622,13439630493495573196,3480076593719698154,9303185694339243567,14397908183193439713,10042782297650660804,593121945259252314,14558012505044353284,1431748809985117216,3004084429450334274,9975768162852853276,3860308915321086206,6733930253669217987,8744149774635350612,17387410123680992829,9920662330220240864,1446051052655020857,5304321817232773564,598018609993416817,14220887085180473207,15616140602084880451,14377482155148954933,2956225382280014362,12752003518063386096,14879739934633452726,18330639981302553426,3249189224008488488,13384730124377767122,73892161958430926,15895498896343365306,4005558028793954382,16807711783840071217,415816922077592460,1994689679904675010,16800259103824800876,3993723204228095576,17062095750302774698,18224020890990322452,2083591120689300240,8497107775520057284,16683797501232564234,17780652206240971502,9051442023580024659,3860042175105116645,2658770024707097923,4458074409081508565,13051793366988796121,10735092550849160067,8029788744274390335,13320891967780458344,12766783684802514589,4657548239599268418,1419291489520226635,8108103664601918533,15770465911436898853,11549979908318058798,788038242994847634,4637003735744469483,16278007495582282547,14519328576398997391,8090683823951953895,12204426935697027095,5398089537153398865,16926542496443459715,9732229303102925914,5844937235370651668,6555126181608308502,598632965457998713,13611060291156888733,3117674643580904151,9401052761522725607,14249391133358359713,9471050900328702483,16379425142630352009,12048789339546558983,16976396481746794746,1673228721368678174,12629995644616997237,16589924677039874595,10087849046115135949,8577567025706666472,1179139319507934319,1338881466420525863,1574745782854315903,5585527107949516909,9863000138163008519,16350892257433819883,8737775443659954484,16573060505016125444,11286861684147056953,7290221018012374974,17483430928594996178,14848015442757091207,3887421625981370037,15480197647842765958,14442403943961037337,5378890276226575434,6976997198262650496,4114674963039530188,9665714821471614545,6416046171736024363,7955613251799089612,2967698073011307102,18008299764746472769,16577771414030874303,3260530397670270886,612953005121741219,8039035167501600589,10836380004631559992,10137627431131333802,10221910868643444916,6789486497186696022,9257714631868978744,10615656608315694806,9149989162562681529,16151402164576996734,14433015124662436002,1049885948360122499,3204339175033190499,4886281588306201218,13435180419059339696,9593359280005854349,13632033329977344201,8186914783870598212,4847852357259483896,8730686581771709019,3802115391210444258,12420257402470460679],"proof":[[3480826445427916275,6274867169494227712,9207968659124800139,4386743971074993108],[11130161334559237902,13251945884756002701,18290782354548448132,13768639657033795785],[4885754606861232499,16427276132535153680,5509142100128987294,93232278063816888],[9380061634349297335,8035242052912586960,8207057323111602011,1047589508259246751],[205325254727086833,13500951348182291662,8926317246330576552,11608872704322067960],[1636213491368079416,2650027708928788877,662657391576753155,2209729293878401096],[7161579393562727881,5419269997836392333,8160823450155874452,8943827047947885807],[15395864583528351150,13728913036902823344,11034616424234590946,1909795887666522851],[18363915400446737114,751058279961267185,12597730027024136279,10534361389429313033],[2149570350838569620,12502948830846038177,16517061833041990915,457739288198080827],[16522976523388455706,9320884575423409636,16472051977308250652,14463379031320236397],[7809441201026223575,9517006082670216099,17542594309689298187,12997417013649810096],[779702173475713928,10268414702834552320,16439780457929098689,8359123390627922411],[812964626811219364,13492657107426116310,4292823667651574528,5634146459382591900],[8994450480713180978,12808670063373988272,3312245676680118161,5681115170205008632],[4956536191860962690,9740002573886859770,7965922547144827009,9881948363159305843],[12698140864963633855,419357374229537337,9620795343936707768,5865575737066574990]]},"stage_2_query":{"leaf_elements":[1156206339403327071,13642511800476976206,11737851138015053574,17152248282868989163,15885288940291489978,7403951322480035869,9711427988458338592,4710407794924338354,6213817268677596485,5546911030256512943,8202861015582980166,747085297053659629,10016848091234776526,11511566325814717722,5268785196968760462,12704592709890020040,16803697584328244322,15958643700866529184,17233601544862175105,1809505457187807552,8885720416279742447,7370643862873355676,714026572726331313,3060031005496225200,9792101722769287922,13107980511569371010,10689230652613234448,15303461112456499265,1428876828172433660,15338437605906814903,17689455495179203412,5514109174558616206,9453121558106790715,8642323206224994482,6938581421239951153,11572695846957675671,11385677868193601134,13670528757462536390,2154302684302161924,9411444444668965228,11548275955513205823,6144917863426296231,2032010044263522007,17036643376326056828,3774432023856438860,14239893089345255412],"proof":[[11413403890540263898,7865407827126757947,9950674715626315759,15570849932129138030],[12904470842615459149,4033107232463430089,5467478057665256783,13685840488000523520],[11967518561535805242,17775746306790965166,17076416522974380885,7911657004103836260],[17406698054492920403,13333961719934615637,7634635134355708711,8176863732758034011],[15632317979554731305,10966984635890472318,1959163591963802904,17664960523077038984],[10684337720134426511,722807551591976739,1982153142844699424,18313501113135677366],[15544898268997268141,3376387849190740767,12576776624203415345,14263657422553603861],[66613824956044717,6020676513546557723,13206649772681694195,15889740151320145601],[10343983660602771371,13536282979314237106,12701118799692541089,7791699800907730750],[16477182210083722725,8892733930461590927,13156488715002109512,8407507012883969122],[15078046221870275907,3116579132215497072,17828269142451092963,4763352679493361143],[4332054618437965433,7026984501649204094,10842341431423243009,1106894383822093954],[5713936751142558819,5161664529312251768,2240205573894992255,1875343010946585333],[1110164411740831112,6097014061654298498,10340966577274791763,18239753433822917824],[4178988488198794634,3945639405656170453,3338672611256894684,8947185355948714227],[4368029160520258810,7161438462072646830,16152631782368806991,12236771943529764097],[13885167953277892178,8555964237507770117,4719750036722080927,12815453938056583397]]},"quotient_query":{"leaf_elements":[13520072807979192549,168718131276904460,11770846679468653042,12844890185473749579,16414396108835265015,4441500321102856733,2477657358929990993,7608576709020495393,3629823489542742401,18427614211049268468,11365109016755827718,12147534261572700219,13860873496786430159,18259462896241926829,2095115552928938894,1893235277346972959],"proof":[[11390723537715283651,5531665188208220083,1309814456600940531,5276566105184638186],[1926500661758168491,15329718702242929210,17846092898086981672,5695406623450697773],[7538541511958320032,17425130464986538677,14108290108801950330,7754666088275830429],[11616588072256162902,6787225058124414727,8743244907096671458,9404570527774003424],[8983565195798337407,5811026932871915417,4735491164853245033,4948175438431779298],[17044766075438183683,3198155100116283113,6513587747111577417,4041628166276750323],[4438002489259297532,15773475924744399128,6976526259624150397,14698569323142281468],[13408247974913539356,6893845122393942464,15858856809867623668,17328465367005696710],[18226665369232128696,9373045522113653141,4712029892910914048,2457921362639727028],[18396811892481142703,3073070838357053616,10513323721855802007,8890584307702278320],[14531729078084452826,12842865583239215954,17298708677440659200,18417264278904153243],[17448576628133481919,3766735263109209166,3190530365807627063,8411346186621326174],[11978295391448876517,17894190311088104425,2291115261024459808,8309367512024619695],[14533937050223034876,5134986175978935309,15991182943304623963,14741398786087685133],[1587885473651027469,435689603289496298,1198639496131916799,12121841847572499378],[14507401648781074682,5481093608352663045,1665047443890160083,13045093494271559918],[642646296282338947,11452596773553033960,8795257061196785695,10386969935657262527]]},"setup_query":{"leaf_elements":[7031407749764842071,2522568696571521035,16579911950456217158,273219118655641142,309432341300056046,8767149648369158731,11775891876187638795,12009176317577903348,7947605727169510969,5933343239537808650,10563047128115285904,8269798921478723185,9940540256602837021,11860288435084287409,11931015756680517613,7975311019005537396,6604397290770361790,10714711407457326895,10260484810889532669,944953331853957568,15086174780727518062,1810134364215048271,6868103911612476299,6643829117128602361,16267147456775189879,1818638844606369587,6889885148087776755,5123286041326305125,16690280540425923323,3661381480637602884,15790186960927616635,3201626922873672692,11690130494109975557,13336963766680261330,6747522763236573725,10894845598490554640,17520211628257288607,8913016098939718699,7659345577385712061,16963440818333173502,10148891370113646360,14225772517407663170,6382051948964216258,2215967065247579098,16206300938537333189,7718959991034871163,16241810867615142738,15649645107411288691,13788644696134729576,3694678749054738389,4552620887644280511,10885549905064536128,946369972638477327,13048064179985831431,15288345359535002981,12898831702952099318,9589549119229663381,17859786944805946289,15334607194096278556,11292398674244865799,11275100044484793797,1181238414805304239,16594208225565774972,3101896499233912440,10063256393386878262,1467158715052122465,5792851189216661976,13837638766815605426,11475554772503765263,94106254772114606,2816942740922873722,17610788373276736245,4249446952508935648,14004078063665991746,7358736329851159243,6033753568111634769,13265119195999165324,8981631833410123457,14463520379354090720,1648836837669886223,7103459972424647910,9424295611943555032,9488689208827533813,7923772748798889927,609233624307817473,8723761083915201928,14968863001186434328,12826495865033634911,8816012354512542947,12251640749292461795,12715742644671142253,14020372264622451420,13914698350165399908,9484693611534793210,15493914570373236107,17940608367565221629,1434557458462648378,4081603639853192184,8474357688767025348,14719159495910497897,1579251418147427893,15083615588038310271,14465129020318706427,501092261111987609,8798120624379100912,12296826086826354882,1944350980984085454,10184872637243555906,12816359356234814653,6737423413038876593,7160853369163452516,8338289002200547853,5999386242787892913,9374246608904102607,12220019987376171062,1228319841101948948,9140054306181067937,5505828504207802477,12053331154070042913,9586989339375888899,1105199421940235058,16023598289971017146,7775318046164491828,16585232510832674157,15584579155950027527,13606766550151398196,3506122541191011568,16003640441385102510,2109443079493056398,2609985254647440608,8000838924943743555,14383047523619948342,4359865292426789447,8668851626403069322,5688398312363876097,6691240799668523905,2208792510804153337,6321744244308712141,18291541626034346534,16306945269608188243,3850120188637471836,14555798160610221275,4021750331546906886,6589292745464908040,1722753715362206443,12428749941523424756,3539148693858537793,13067633299138444216,2235166570839455309,3563248274622986691,845385822003556192,3944533425978632432,4071404958233969207,13814066169719975877,17635513354099837400,17339770374568017252],"proof":[[7800691296643335471,17287063989583979723,9427406796289420436,9726716686113556155],[5460777968693102538,17366121479938238810,3176448965220876672,16877103471177497011],[4244722161728669649,13874851491343375018,4522948854102796857,10599906344568622036],[15764427531520117742,1633572241336084854,11354947436929045060,11142945166746958314],[13124419020887678671,12603907802554464495,12822361603332323610,1485894651627215427],[5121125336217963269,10322881264331817220,5137544667902375590,4720240934142314036],[14705682598569786346,274142278798063383,14265337158826533225,863854864759953933],[18343647757049575457,4109195030720840955,8413004257034372026,5879652134327270444],[7183580873790936363,15602444420826032824,2774781638711057458,4295290860203620812],[10766647058119717481,11797168447105201046,7952034335469432341,6307347063532980261],[8850577335538475332,13844998842550736497,4190400706833668111,8048638807077158685],[16754974107426926930,18047822104571790053,8857020570872766698,15125698848784482376],[10578944867171266649,10039895329584372671,2771805351510669792,10111817157161415549],[10870069940900057628,5218874568561289813,10508388403405146622,15040261969436673074],[17361770725807522427,14729458579348163080,10228599255241899186,4409021679407842319],[4461952551025463037,3023088726574070982,17982674338935786519,9685827106554591550],[786433969103539048,8122187790720253298,17324655261546370362,16556773082047786574]]},"fri_queries":[{"leaf_elements":[7538382581490905084,10546618395866955979,15531282555051910038,6489338996359726805,17012379632636483625,17022081191129305872,16827129293894096825,2593873359621131778,5767878363735899150,2243949080924455447,2717163616533517591,13994530076207576989,185757248866653918,641305013351386257,11422724177309896601,12848298352856959481],"proof":[[13729261913968181197,5422381189378574867,4615010752703338733,4655859058951186399],[2738830438649564837,13536945675605817138,16082316958947791440,17697574442987400850],[1286579447220475556,11804563973472229577,17729697095856013490,18324803288676302469],[7845266606747608872,2820204338293190477,11232767392391703169,4221023779753523359],[13830808306257558716,2361010886554212915,16785640427996740920,1910850732720861033],[2404200894713915946,11561659419502714545,15512516505563521634,8277487971202156345],[15568363017696523440,6861739486585189470,2790692471597275310,11096355136063698351],[1438568789672858043,9381077307126731506,1841530742161470193,4253390503890974467],[15009981434981445454,7526587824740764804,16886804120577747185,13571769409343653060],[10397616549542754282,4658245454129694433,13550387863645909106,15157127141428840903],[5796702095385337064,5929727471834422664,14987364184734223060,12680636211064123178],[15065778828105432257,10013615733743590390,13304884605210688153,7218938378334712230],[633006299616784563,11139233886430462112,14538861665720934038,17078736384713939743],[950518108147387034,14461496559104778806,13917507090447352020,6484097189552047977]]},{"leaf_elements":[14096742076104615601,14262465368795876726,13224883068497391582,13126545322908687483,14025427249026577863,11211870449820551520,14602316456484375766,2135444860667005021,6257180446195071808,877692447460144819,419553848372165957,17870588529417284053,17122101298151467839,2778283743135046926,2628180891959229864,9478416405746806968],"proof":[[10627910621316738918,298697433635233365,9151876556223918765,11983917186135484687],[5691299715226737669,10640063640917013701,16242392073112561588,16483875112789996858],[1223478592527258218,8660498098277358529,1574603094176870743,5791637441862090324],[4895584282910133623,16056366445031422011,3093320871234493156,14071444753489604567],[6097556710344212802,10501168456134653549,15462609527426900417,7213677357911340890],[2234685539686188970,1665538510364274571,14223649326459231114,4589229071474060478],[4357927833858828146,860108016601072008,11977906996352393633,13910209213106316447],[3823167905000593996,3194907685507499972,2356535569810701762,7159725989631623802],[10222771338731633041,17361017823122605221,2714690534464596000,8911117393961323959],[11727157629316029541,1250806423073151966,891800793544898678,3305784069475612933],[15418802502015684347,3748451402095185069,4925493761703378520,17844205222826790497]]},{"leaf_elements":[11567683458886036451,1597283992820790889,2463181429253551621,10799071716901397289,15169912424644872129,9611320004045589445,4746255087604989682,17184294765678500093,2485836897953053665,3254830123001649458,16912848291020007697,673457783856504658,7868569308096024785,10764972113212156849,4124608890816253394,752546200863919447],"proof":[[13716014969991794645,9247776130298763978,13580075455739344240,1077004111098491101],[3266092384688199826,15877784068316748370,16394463390144686061,262184052284935992],[12407038142244075545,11649280445622811941,4214923072429868503,17248309233300783000],[16292805959215884557,6654700504076876774,7293837888008988575,2100624510177338552],[15848063422878047621,9277802629097193765,11862907028495847627,729298618029698035],[3977738057721108586,3070379765737344393,8174808616426452332,9119824238271489461],[3309760038805872449,3631375083889281026,16237336208109412891,4696666898883299182],[3212075062214438924,357583838110179765,1255898485944832398,18404599682258834503]]},{"leaf_elements":[10216675240639862713,269849901696522388,16494438958069438958,4545063749225696748,13778744576486926198,12699564477560996075,18308454314714130487,5652899461663756610,7764275779490772545,16100576254953554641,11230807292924754692,4923775983990519278,1087561690060562802,15402585458484697379,10119843917602734617,14566460307300826562],"proof":[[1341071131959760797,9226088062341522242,15436177155727890332,12094800177096082154],[16773331195215763653,10401524539972891714,12812701435394831260,11763617065129856659],[14222300175489054809,2267038271584479440,17141794906431139061,8444591244767840963],[5044779916256531052,2331765407222297206,13413041339537916887,6356322448670778330],[16725837145914548581,1125423394101345531,17017529173301036278,3401633365302970415]]},{"leaf_elements":[8077129660493228735,4858281455775931419,9738227539308241978,8050169102116844847,958630553091151607,4272321284588196009,14067102189345055928,11594738691112592425,17695426800051813913,1734969492251892270,6619316802958639459,17588832284713609068,10653512817480937953,1880283887890030755,6288995053754109063,17657381800227068251],"proof":[[7234137796739021793,11668650209537815079,16507941039562116065,5221555160632642940],[15514906446679858530,10979498789109703592,12967136000864485334,17159923573772454695]]},{"leaf_elements":[5913797713474501816,14390836815188810001,2598086964460305874,4219281277613110736,4341490336555859025,6837138495876505826,5182460282140934405,12936941785162437742],"proof":[]}]},{"witness_query":{"leaf_elements":[15846137739129878644,11196463275398289267,2827541369173654787,17983363044563064828,17501839100909668534,16412094318169957041,6117145429161115351,11172316874185724871,3045106262773520778,1474914569461688480,3683603957463710074,18029801417780343845,4474068018935174397,7960777532457269581,14077134784058754436,11089666433969088515,11233287459194599453,14445014176740073799,17704911572994682783,16787430755491249172,11776514945224398669,4107445740342161248,5054825238963517596,8576711382947282440,15454257289555250558,6503324263100627283,145983195675444382,12842189549117627448,1664236742866762618,5812899617004845776,2825829755940581457,10871965906999212763,7928318045909675714,12622524013023549898,15609093410551352690,4461112861515466402,6540912091300220051,7421714943964710624,6830894356312412307,2143883903621026340,2994020512053640972,17787350020802856005,17638039330012029835,181450189551534838,5843251571008785830,4839050639554115000,7169892029173365470,10767374340156685299,5826930332080864757,16766639517162166741,12657678366141327310,10941658619775125466,10886300556839495437,13394907842419933101,17016507874270891793,3648720806071728586,12109869435080059699,8761161303187611386,17570620533730474726,5900002733468562954,18368194166624397595,8373293431678776616,857579805680222191,15878580249263759397,1068261860855737657,1943372591941154324,17202909861041256671,6117381209163094856,12162079475214907017,7887179572029471503,11084615954450430651,13440345178919448347,483898565753471375,8383743158482030931,12080180244088494338,12564490866985064409,11062682327420418779,889927505765727636,15257250176367718687,14561125145438495192,15179753201738112879,14896937007015992666,16358786616839621320,17560085382861842335,8643507206376541484,10225751009055436534,11311325616485140650,3524163244657080569,8435792020289859119,6226692687615972745,3438884740775552050,9435607782525218995,3420909158951593897,7116592035985383571,11800358743940203577,18372747808121861228,1642521583521639262,2698682903952781893,17010264146003417646,9566663358194486334,11032641107142587429,15008742875989165517,15117201384689008664,8201832786005763880,8470750915545772403,2607278137313970395,15915146056829548473,17527194968638140577,18397308171283851245,16142442809860498532,7511369514280405177,15217312309947292934,14635827177117381414,12628378820046005338,12013091280558434617,15453315058631091632,7225149365344000301,4916837265683910056,780849813265191726,3822993970543127649,16197455038673971935,13550867060325673354,4498389841136463215,17941984012453981756,10774838459736810830,7129028403611344926,3466049015582367825,13349528566926464993,8389887877875481023,16976968259675700098,12669903434196202213,1306638626943787415,3416000464429746008,3930676824092457419,8588472991686788872,4221553172569615998,12710712145888741410,17484863446048600534,13331073419422340895,15965734965509719843,5823671857893237998,14271532285382266590,16364131106712306806,15456095783155476062],"proof":[[2426537938825858575,6520033314136799996,15774250857921533966,3247526448459340761],[5882235955674554129,5955704777616097202,8049551778020720773,16660442208679011834],[17677072955052205952,4850442282957189968,11303546256435914037,11093159423859030033],[12965878872999499338,1756568248855910193,6499039166203382880,14516778349606931256],[2044733701591207209,15375549064485412504,16577559936149187766,9410886649306937395],[5228516976197868001,15533831848764475565,279337903683315122,10750062057640891959],[9532040179263829604,14440646011210133439,15197438604311774771,967028515049133462],[5450747250702320532,9361000052462407607,8570839223385833999,3593292635919603587],[14908673082115880379,9675289731000039430,3430718926758566861,17613410417223813362],[17952288696581288794,8638925328197072565,15606547504527235002,13534444524763824697],[5606161142385371321,4119540449749274023,10829818940131983033,15821000412539954064],[6123023364939751436,10597865986585749622,14925897647132930838,8878888250364189331],[17731628210514597555,15701096503196873358,16274407354958062243,3200345007673517630],[5229330436031763403,4934249764988974366,7864138570360332358,7187995720325724870],[3066409994391931675,17931054695955975068,14409118067836507221,8073427200857987684],[3842324479603033363,4753883796722324137,996743413852659708,7080313112542370590],[5215536602320635037,14251933243871324531,11901504793503171564,4410319055582773978]]},"stage_2_query":{"leaf_elements":[16729949787855028485,3968580637975247588,5442889020678718353,752987003397826722,18017712311165264111,18262992076819479147,12033817746889320402,2967924685054939414,5540608334955273892,1797992182806940984,15736950302416113277,16971933097768691016,11387284302945339272,10269263558122730395,18041465821857969740,11899976569069131317,10344395625352910693,7137421946010322800,2730862550574864242,1975986538559865525,13939597391906489738,7380606300202534308,15852442987160296879,7866339804388122227,11810487540830408828,16231519545272487980,17772091435884538217,18365148754402012777,11807732714552715808,12769299204077412731,11155245678841889277,15471899536974199906,5274331266577626392,1947870503305608864,16939411950118367849,14184898991879987863,17637773721798189794,14852205835903603767,4331292413547593649,14373958905244335380,8234838872445524002,14901213191516218117,4155791215933128230,11834475204980073052,14644621343370208954,792582438854197190],"proof":[[11770859560476647463,11614246131889586218,1207954315330383961,16638398595723147956],[11064110412844258581,8543171558058412632,6583435166488629664,16313279313279852190],[5722622128503384786,8383628640145995713,15117911289495741547,11535914741537431501],[3140995293143521084,18443629323152705385,12920987450155227262,13773634855416190158],[4901036367014693119,15555685948318586218,17022065097217957792,16069429519353024603],[8364164590855920775,2160899028079526412,4780245866631885554,6526226230756655478],[1053905977774183,16773494991421157225,4504291950992727978,16807186217163517599],[11532713696625503127,10776330000969638809,8674051412172617836,3136468614809707620],[15821163326366866852,555273758510000513,12520563255951744174,16382634528702566452],[1253556866494065013,8031484511869830684,12613387472270927963,11360424765666729166],[14767465158194129191,3761244636883710431,6849424720639377550,566381095227871379],[11270978787041982438,3794913265303966201,6510526684702501323,16864995141705186890],[3369088569486229964,6719347207152324122,14634867372313332391,6073275210843394956],[6090058692781856397,2288935420156891787,16862230000526207459,9665037698479697800],[10253418077415502460,510522615733517269,10984778422433217658,8467631808147575013],[15066487968136584680,10748893798959565870,17849425289372712802,7091762293707477544],[15709091770705664402,10049110614717720455,3752215127558376869,542242508725039489]]},"quotient_query":{"leaf_elements":[8773454438810582334,6299275930490876610,5993377856073593974,3189473184932421585,9339327300816416484,9287522034632499794,12133669483160294177,12305020993570541958,12733182043986677920,14471251692187121820,9563800898080289421,449320728776735825,6976382706030981646,14360936062308484664,2581583057090215606,10280292844432264900],"proof":[[13832654407403196393,7115566370012663035,2108301029032617475,9975751127650663739],[4823375312881930569,10401976147433397259,2122555892187607544,5145452779812879031],[11169518221226282429,4171043283122616342,8499054825106202365,9819083547706360702],[8180814005769427239,6247290279951815721,13166964300223692926,4035292658703455511],[10853390053150518847,5674749161995154147,15001192655547335059,5114941702336763816],[6648443781017820592,16676681935929641165,997628246123793453,13957952154789755929],[3487741531330726596,7951981577417984535,5220632543101073342,12980753900816721380],[14421332611354198605,17340857337045376315,2879873173497433165,11369520798000523527],[11278990161017262690,7586272487874973417,14744753524410472348,880430246995684012],[1844219489162660172,9796048744678873564,14115677329975544082,14429353227994094403],[7254162636026584822,5101472688900977357,9939852715403508696,11101076650167582474],[13633501376388375860,16201824478793893823,15950538212885390956,3497557226306223137],[2227968144492786679,16947365825526596177,5125402622807769757,11885469979591167829],[16767430783345696130,16516468350160824067,11851903174222244591,3185020659794543821],[6640216247820107371,12195020463030337182,105899641608409333,16156266672647552676],[12263676989284392594,8510713884196198992,12470107030909895174,12012457562114486062],[18400306852838558706,238886437693955427,400059893464688571,13855449120686775870]]},"setup_query":{"leaf_elements":[5557336481078994773,5853739194093591255,4347629608429127798,11118786368810651181,11202877699716129011,11995565217487540438,6355470162286969655,15817569629948973297,15066837733255163432,17117830438110479998,2824652332706435980,9120887368410261670,14458462304872286129,18294663003806260743,1883169723359688595,717787173029792152,14372741200757863249,17322164419124459768,4809161298360432747,7843861832856942235,13536746004999786641,5204891772262441274,17228613269849320699,5682453573206793357,11258350304771138513,7849194889051383516,16608315025759771884,5784782343730463247,13460515511311446746,1913013363004250152,4797605064992905017,15040286310674530985,14875591063969184597,7135951033979053719,8741655784520886465,18307807721081251268,1728197104200080307,7561914872938161581,5648175665392013880,6430191959850786111,18074602448773543902,6675913569489288606,5666463626241080797,8848778699902763953,1540287740643678403,3493281059104068727,11357738375180381397,3076882828594655108,13539366385284438298,7715849800192028617,15456610022422953066,8603492812560746679,10435510684225393949,15335129773197723425,9939751705695665467,7978806880674795615,624005525479785878,6730320917401101668,16972969935955447505,9180769471838047654,3119121611089335377,3072297952838068337,1595731922514402231,13791887455343426635,12336166039802180801,16534895871390920571,13183692580808471973,7932597284741129753,17881452509584359485,6484170671525159670,697021848078401529,13873677881321916007,2188488503743648373,11617294848345337732,2524531104753094521,8211807904210825474,8325947890087023853,8484584877581483175,10500099166060742012,14565028442223662829,17447466062007255617,1968394155491545448,13334781292919949673,15086250421261867497,6334880755571206544,7818719179442051989,15635949706316108972,12079802571555813548,12128344446670289062,4444362984336915936,17774644596702539088,2506061848549502938,7433924351846048456,10507272534796011872,13610391956274936033,10874019858697600259,840026617145425716,14583669180147005173,1901118679851269632,13619474571827291254,3608169804924066440,14408480485919888454,12258522399042459430,8123749876121741122,8602778400904065376,2730389801049714556,17984343984446034485,10057889676799416893,10882721721628247348,1984506381894650797,14248458831854962434,919750876007791,11223975260591370579,4654509595554126848,8062902733485064586,1917670049409094253,16919459756675847349,9080518025037891836,7474792516900470268,8533770296299099854,6144545256834775309,18040879215061933496,567812336062501960,16437373403584949247,40485100496780680,12322399338950464389,3641127568330693357,13427881418812282026,2422330416793830712,5747718875871266197,1098518127076770432,8194556939012339692,2961263095508831533,6208475355434182491,6774440368414647343,15600268360384725568,100275177835793536,15264689427722060742,5502852744756683490,9189855001635146548,5157062283691762698,2483918641385607733,9150308969828942638,18041924850739200499,6514546459906474542,247120578668260720,9114503202928808394,13567155390321476955,2263901787220766954,15179044267704393093,1177110212068659368,13653187534815397163,14949137130136717950,5890401575982407295,12298604589019676283,7002177866646059696],"proof":[[3625649038339988411,3246254293804917345,18086820123984039793,11952827487470777900],[4589780195956480840,11276625194061995048,4589550670467347904,12230975742522497858],[1456260722243699538,9459234465159886628,2866057055465680233,17466454573817652197],[1142502052399079337,3836088589650361050,10712382944612024,17546617924431082729],[2163274117638247366,110417535869620583,1639844553029984037,5183690024457090800],[4961493029125720642,2924157167253518857,4342639792109570770,3600782393882736010],[15109397435342356710,16046190162060755148,14147293699806050575,8335914011040424530],[12103834615695246482,4433221794839768938,3374297473488650175,4406680910250113941],[2647497889877832387,16559588695708590112,16179222746277148053,3823697683857615043],[1203427055108824728,12121046930287839170,13478359423099147026,2815614527373911575],[8986043708637424107,6110364785587010437,6690217109860079331,4705888477458444378],[11803135984216556786,1107187649647708240,17862421884792310341,13207181929455024160],[17231883905422333513,15763912380620804226,4815017667415384580,14267569445844397841],[16793965731495516574,1550215886543636012,9995868868474314954,6302961282075634269],[15977193871017265340,7074927534431925933,10280375710052340886,6851979077984539004],[8082532824431749284,3843126820375714518,9921638987202456600,4700374442741404830],[7984657953714852832,15734075477941574236,12214476408838324436,16357190233096441477]]},"fri_queries":[{"leaf_elements":[16448771625656138676,3400042507543908908,12419905086860126633,15055654363953493041,4208742211440081807,928087825762572790,996809878381533850,6789832103113402800,3990391941106300319,3675016484601821054,7614247968422139742,3490515183782863213,13417154771365534035,3951165814046896417,8616804306504461694,15106825751250980529],"proof":[[5628284783659784187,2997713796404452852,5908133776561220102,4596485053719646787],[4730543443315202908,15823322956459468841,2181500581870921495,17994960551005149428],[11323668174565232296,373001309887623440,13333557710802274472,11155867056764146468],[3089458969952101500,2065446866809866717,9366580986332740921,12341331588791038047],[6117261190990211407,10346523333512211105,6595716597736172642,14755820887185929740],[4190441899499685894,1425068892803657196,11748355134850493401,11836641578498024251],[6898961040661893028,5525123842120579593,17907530211506078984,12687861406722982289],[10411166016225134353,7098123086764128803,15211068885370486905,1456691012342473535],[11907425269741932205,7949689760931278092,14788500495897679740,10780392391266733405],[1142737189720377518,18174069979835776269,2582134196459876091,6423760962075881530],[8865225499950872263,6403393481847298634,15591632753240980944,16179591510887418279],[1427628853032500544,17873585991291573604,6487117564694564778,16950231015599290553],[212621411862146511,8903151658637067423,18251638345583523812,12207401644271428315],[870959045068062007,13190212933665272848,4148349890064256493,5894738798348384315]]},{"leaf_elements":[11724795994936833970,7735617210826740729,10893304777027281471,2261356103135751255,2270655885721431157,3781496142186171015,12244169145588957821,1862446307299701115,4843600589076402989,1024173753953112020,15029740655106404533,13910936540567176608,5911146537735775315,17121620368191014902,6894306876971775757,6033781569688059820],"proof":[[1160124168944612132,10693057492817378436,15807299716389565643,11929830706833542286],[4161056477793661916,439140376570681194,2487989282670914177,17504038654437393197],[3412932949549551667,7663041802722791144,3688942639165652787,4322001217811850290],[11756213622882355990,17288006071813214244,9988348674327824497,782884684470306444],[5541300091263313053,171812544538135034,968925556676719565,7727497660203809722],[819660774318801512,9609740120318586423,16811093804293420707,15382196046157457142],[14075093469738267436,11151692093072933518,6120872349020328471,3237363262340736209],[11299155147564582328,13982070608473495999,13108669296848053651,12068729268879694688],[8675336644938332162,12776268104812848307,7241131060343632576,586889771863734648],[2487148934501296196,3983692171113856117,7941658709054989526,7308480547553899285],[1918395912208850369,15595168596087110741,7847666842944273172,13450074119918273287]]},{"leaf_elements":[3124189810713723243,13208913804970568856,3830570350947253234,8736039572610781263,224928997854929875,11214880863160681253,15989379564713192,15779236768461919596,12437097479488881016,6674830117336839481,2590145734822713086,6385308423455139905,15074250259554465934,3802905456651796735,16452940680112503954,10900669561581276919],"proof":[[6624293038550320990,5844753049635531238,2535116347569039955,3380208989504379943],[13766674837194431067,6198860973069672524,14781968708620292937,6766853221149165995],[11034946112821749207,6422163838305251655,9360450385653658911,13897793319017443470],[7081952983612881276,2737967012461164550,15687122793155969836,4605473405306707524],[1751938786139310609,15717846900891317022,6790404132347081908,5826439197753965678],[5959570890659043898,4545656654320257697,357324409198966268,12855665872828152111],[15721991068237019347,4547321401710826365,3508635116086454310,9455975844866674381],[1902792532381728571,8661050412531662077,13331374864731157815,14587068449346603177]]},{"leaf_elements":[12315728203552618754,4472851632317088858,15397728744035953393,7503357544666359374,6935935027508001878,8406069985609886580,1681573942763852677,17708667908697443985,7661200443118192726,9987384535502244738,3745418853191938836,10450071935820061610,8718627836032893751,15296961806639126257,10894029399387486250,16075145499587887989],"proof":[[5711354586026645493,9590542260843481161,814304959521415962,3795274242750265986],[16464829746627495844,18012875463509795397,8588206179357292897,14358970623277843012],[1680741443765471065,3223380830214410898,4604283891098503971,8862800834554039786],[843276462998301450,17812695627880111594,4064030155738183492,7685901774517416374],[1131135611643424584,14374117323723228443,5408462005651363443,4195584784838765836]]},{"leaf_elements":[8831762582281426707,8849679125304178455,1163634422775562171,1214511418988627632,245761212292741986,855271111985650865,821644234077548527,8219783424990092525,13673513761143997212,9144940770014330210,492584385794290158,1704642129888627330,9671690423847147211,3137862290104727289,10330794113950435655,9406112070867154275],"proof":[[5621136431675156442,16038549556823953128,7179633459019492285,5092742752241552913],[12639043879551777198,3116432281338880680,16966569225874343934,15833611935762388359]]},{"leaf_elements":[9390894857537177134,6775050549137632293,10212697533785944089,8397297093669755354,1622143564591104592,10285492781803425441,11612578074530589,9279746851921347959],"proof":[]}]},{"witness_query":{"leaf_elements":[4957234650759720272,16382423738549110381,15576354268469204643,6699203424975943113,9817594297696318174,5815320395621749277,18293445217160989220,10211082256878767699,13573652081743175603,2568330949975368192,12041278915009883489,6309844621950548314,7984774360609936253,6513162023504328152,12091259474609888816,5917870621007866610,8605686855529324319,3801590830122007386,4792739008789731021,12122640006059382441,12944285634778857789,1595665196686206834,3878270414748524648,5780429742351920378,6026727697256963690,3201019878688997030,12881038127348661285,2800927194773235921,8265498778423656387,1762865028028426021,15388047705009614738,256633237842056672,18150462118867715272,3283157080057953882,11740491206871902864,14845435138052025161,4224802751161647554,7492337833842516167,14487755079526213703,565844100828310593,373075665986747924,6894974074279901820,12903884165798679336,10685927093858959576,14951861871896247708,18157743669501473057,15191541936630698448,7468912080110466992,17682984743257652771,15034924517335891701,16439480478373160744,8908705794368793470,3127989414801156446,12374886255928275605,1644031168218941146,12083967095283985676,14565855397735395670,10267460161190145882,8676423061565746751,2580892681351455817,8805973650605622592,6996537079111514651,372185659154208644,5368731401886457407,5708054337939943336,11853850377677033433,1303621820544027708,5529361803730718445,14129380456308616143,1182914902803897153,6755042939254066976,10161604938622888268,9252215436909075442,4309800584446010619,8444172705250582795,8268063751515695765,15140888494471906007,3302208009844360092,9460382305352489947,506127095670116916,11964349711521758446,15204469888794163332,12196589875796393477,12634475398151791131,17576322489725332047,16910281039210846632,17700612838875954207,4390371477657469779,2278891890406759878,2955108897630005663,6220990288131528155,18249695525365252206,6163695138548917450,10159871209358049063,5496158663715404149,14183154552014544014,5008945010407099512,7933748584831565084,14124317084726134173,13090977492825036486,10064353390110230688,7994832894002639944,13371910354373484554,11256210445817893737,15701219528318475332,9292748275495665265,13132217726055277666,12101894997245374889,7196741111799188577,12803235794536335561,17544325319496780955,10966140477990711132,8957745042088134733,7631456081101009170,7971718581538380761,7686761585544878250,8373526640508115975,13419023009418487685,7879763625445979816,498703669018482855,10965014938981462522,10743655192647305096,9572166665882709917,228240053747274865,14642627307357551365,2789810053139563491,2988871169710075963,5942644975621652254,7000610344494390644,12297201703132890520,5086926237247513609,17910719427146080022,6740674549985323071,8876611663398098520,67753478762229324,5657088382190693613,6178282489533920448,7097025046598955049,1241440983505485690,17634294035187096466,15711001558122727044,11739280184273575429,9853328840547701625,4115721178403801469],"proof":[[1168463864355612003,14457187181408694469,13089320029770848835,10043558702570131200],[11810562184248674431,1180917639370519160,4816831541154386111,14004084458911608159],[2210981814965431362,6846399296022816035,14773164807875721884,15150148653245087600],[11775143099847214503,6590212210997343129,16097383287787591137,3310698103992073210],[17087708074546533349,5462150405173267758,16689418260470612704,16891742089414577872],[2749550027506928810,14392123061687613912,4876233175025940313,18798468054302364],[2297359009390924166,4490024594643272742,11349787467993856507,1932401817236583444],[4581333893022471509,1641510266033323997,1915561572545526706,7591131666828996728],[14139698203121589667,2981040052189824589,10101239791026317244,9055855788437555571],[8898221220992745298,10586422790881918345,14736263522987228343,10978410056999501868],[2714850430831235366,404539188520236147,2205081481623338591,12734816223591974724],[16886383332844761420,7437060237097397775,4169000431572509186,16579326625930432241],[11782110360761586725,1274171552300931764,11573358115877026836,5366322292067934446],[1393752377341301622,4957460193024770497,15654895271120231978,10305821013872721411],[1399022381119202149,8824423027309941673,12748656623110904120,1133472269972651264],[13380447448771906792,15140179737725168073,9655633318004916907,12245789944545549073],[3401274946295047068,8424190892080195937,11580290105623139539,16275105661111298956]]},"stage_2_query":{"leaf_elements":[4598141434557974316,3669749483588223758,11795931495739427988,13377099190978376708,17935469218622858677,8236095135304026601,5504679549177905020,8533077082554646460,18398187657323153762,13535677824985792785,6356463147795742290,328114182034377592,7314526848111786054,4338990383213178367,6194466111026533790,5666914218068707412,5806622729102546254,13381122399283934891,1574676665427288180,16947854670073709840,3024483733206264592,4638084600873357531,9695041702892904012,16640359932424301336,15095508265065317549,17455283740479232610,1863081346341273263,6519464943023164011,10432285089324322480,17238011103734771892,8849848832955598599,9559315305689835509,2563889368583777697,15926241696042743240,5434387468605875153,5567318772376556583,2362907391650992670,8379927264687865755,11098855380349087365,12053715172609644148,5653919897194675868,14212914363419093302,8672219463273929034,9984413475816254573,5432870777801995750,15619194645037822667],"proof":[[13561764977334109594,3075450377554767612,7518982368483764645,2136410760644932757],[103714410763193876,15047970824480703730,13857406779488142756,7928440906424570933],[18118309846397395607,11711261308781434886,15432244399481158146,1651753334278390948],[1439920245839943486,12392433821317219381,17595025147917268628,2982517401964235076],[7543098455285271311,14229696530264825913,11306079086087166430,6724093115638196162],[6336647717349374244,14339614250178540626,11979212973645843553,3851251357487454810],[6154424953033336977,18333811333982141035,9910323273682156868,4169927192474800058],[16038670513368641603,16974553939963370206,227617911126165422,17132837108392186283],[14942653465979147059,17224383827518016683,14834875091896366172,6477644034975243593],[6985842405108813679,15191125654544909457,14787637400783758415,10269608739204061175],[11610161887665895976,16681731284820290404,12758380253952455731,6597893372156279209],[1315474760300303241,11606371937314076691,1284381679644042567,6902201974092529107],[2566940915678118477,829483043431290138,8026275425197157355,3202635617517186241],[6073362053647782214,17496567088002971909,4170552539450700345,8913481643662934593],[149635083866202409,9196227554316130674,16918962897315668403,8797067627771319903],[4432108823753938526,358074734187401680,1357964490549541375,8521473370250666666],[1943009159876413561,12861816066895743824,15774015485100450464,3732444378655268395]]},"quotient_query":{"leaf_elements":[13535864371018702829,16368161979902051692,11934102347897379160,13420116220122019178,15758333067608388267,17645462837365338895,17594518831347524915,2564458134713518069,16584206469601392246,715193464054093885,10254405139786323929,14905641131830987210,3888568128851497114,18040237104914756111,488521637146613245,8615151261728942562],"proof":[[10329555504540626629,11185125067654067908,5952587420692783743,2715404600640683142],[33232445029645454,12001685091317794540,18117297896420584069,10291726835373400682],[12845941963372284207,10606376108548746986,1309330751048310807,2035752734198535237],[9274200886840016241,3907036121944490775,16791891407284848745,1850582019059148424],[10262237943237013599,75797932726083911,5554452764158644291,3523707803449452706],[1497363819467890214,8594164775772263817,7151390861357105093,11398126625713121388],[8116678593361514504,15804136005596315540,2276167738335283057,623256906136184493],[1661415698692514929,6866609263164987904,13811977897036225336,4865195396009205383],[4298359681950751383,13854328651229707769,914882600222273915,4178778340296052512],[15745692960199229841,13104957909875256020,16190718395620895727,2383498606235859804],[6302585141850272006,545214234196286677,1372787488715052983,1313467029317835433],[8658000949282851613,10067101439138519573,11378691049564638118,4102147016657390658],[13136846090080134022,15982491966124622618,14772383367636243232,5542315907800436514],[6491705172025076417,16043856796234768325,4231186306530882733,10835292505202951828],[15587071894665413778,12302957750724334846,17201513568675921610,17348060708181821741],[16645669721233895446,10806886762814503286,6576961679365604492,413775811906723930],[7194083927807340288,10418393286838300943,6856990265218893508,8327449156721763660]]},"setup_query":{"leaf_elements":[4627604802889781701,12497437353629745877,10836482270256236890,1284199152317276967,5424018351081675310,8115056599152838948,14889228242495540601,14957459385859683780,6647634692712820863,13269332240534293930,3416048653981376440,15297923097334261139,12689466880341297669,9006253584470965631,10057443482735773271,5809672899204374409,1334203233811714730,16171597420494662153,3624738185143617802,3539632771185112000,3213037617751016220,3790960150202942074,6257168259803284119,7035984836885655719,10032893244325298718,1756553525213137340,9209320135217261972,5373178345104321866,3521269331582335680,17480316019509529768,11772413558128010634,17568530495152102860,12010504309073473037,8324486976473168073,2123997768643130151,10132181925035390526,2976251402537342582,10387910875362067015,1668690058679514173,12016369583609349555,2427480559529569594,5169220806263726186,16389578657310682809,3594111834049844479,410173435685477354,13250761346665001009,15950775148494566635,4598061295186525650,17770499574031025015,14924204733643196425,654347330554325720,5397267951811884109,5285563993020569631,16811187561715345785,4423931801282675045,10682255922381483421,12263325145414825340,15445202295834867595,9526496113048999301,13321688276923489547,12598236731063307482,15708804562406017211,15729031103877172492,62760660961264986,16240288146014043575,187170408750571863,1955562288974564519,17756302762550802274,3381449450259520076,12863663382306293496,9988424114830872054,11754345437463283361,723458528812006924,4096363887019398741,10879461965679299007,4438172248016292844,9685022343614073597,13680325349299679753,1911078042295004982,5279948144797375490,4375747196145162253,6458553473057373569,13618530760399758114,15751205782618979543,12397869741963209607,2247114008043310356,5960297859120976695,8239728757096583162,1595484440718957555,7462322291690440428,2213979217840547069,80446171866921905,18093670671820303793,250979384070212402,10333864005208513038,9894039157675925115,5829819245392492395,239407591894800431,11812393041940892200,8128088229908723073,6671829993316355987,8002277742499908380,12953130596796000006,8817647323650623644,10759679814722884131,6433889881248958748,3381421372704597089,354817172718516207,17320396911625772989,10253337138273616287,14041836237848387534,15604112227327775586,10364772040032657248,2162160746950013874,1487369245753334015,8307107663666437645,14813158642452418451,9583745970719445262,3842965579249685006,3458383036684479735,7476575291544663947,4674151773236384931,9947726769326883896,14432654703594785889,11173731377690469551,15061239111650598421,14568061031982962000,4624224220303865379,5335415432259285201,2292452772715796500,10149804895587931702,11608487205265031287,9603432459634241952,8743896554126930597,2220095810068531754,6334196223305371701,14224083117700956223,17019626368961362885,12835623273291027011,10891932018591976780,14929727848288380051,2895615616668270137,16142023921089255327,2699491759004404654,4602743118595390802,5057198960093610437,8931494419336132744,10775265471677927124,14046470888407111300,6908630764845228790,8360334594428164908,2311485330189390269,2048626745415738006,11837897290689435481,3204799956119728301,2941209520638729728],"proof":[[10691849467824588373,15884181740839990857,2386764582738051287,5663037989110270497],[16690946351660073736,15929566628560131922,12093557576697032605,9032484454978720610],[5338317366342003694,1067966068944387061,5727878151610146531,11960636388670533620],[1616534665397835119,338095079227230602,17551999128427989773,10323715722471088819],[8392597714564380405,12000577123959510972,15318899530195361971,3324204141844028825],[3415983186388618531,7115030182504929871,4671967942161868016,2747169479387961034],[12989659047194825216,5065291206898501751,10820702077174915264,11596798090961398422],[701280560946585547,7032480906030962010,6288144071400608929,3213142306069689527],[5714490159016814151,12005008069783473334,4337147927976336177,7359124993718297087],[18392326319156658777,8119890496430490139,14829153423617230453,16149893564805275062],[4582627220081205591,15582962440996011659,1387216833346679018,18257898666857696648],[698775853709258689,5359666735833950443,7338468142833727444,5920240290006275531],[13440325202532969550,2422301353864621389,7312354651968364369,6743902662627224202],[10167504214068969414,17275783975050382611,7829513473937501879,5765211767587919682],[16163093068747923369,5597978852676795872,16746711562898710916,16030292510473701541],[3918334860846535770,8707871540319840071,14086948121447848654,6808088471214817594],[14683017277288766136,409482300754268912,12378642238663961193,4952042936790383930]]},"fri_queries":[{"leaf_elements":[3362949176412886195,10816892097724591669,7130143819945225748,16438414456472147091,14539314104829731345,18122666972914669207,13042081849170390554,6217514098342041839,3788879753987709901,13592805440743466762,6961617212324444306,12399237080045308014,17268538662635294443,5893328261343227710,16953513446949226761,4111648941673548660],"proof":[[2700561701237713138,11177355880428508279,1997138453448698747,5373165116815554403],[9836928430625290071,18145893107800453636,6616227806463249011,1700859877999796481],[4999863428365489904,18117422648453898414,12707915935526967664,3229844057272972668],[2044334444593893460,4504984181353042071,5616610603055389180,13034921397229958804],[8497996495746007678,5461473491603734884,3075217874871347034,4001693836957382355],[13508244256639312605,15091065459029893249,10373904305075255501,3384071347115296235],[16864669272623496445,14466327047972472116,10176699999370197553,10227309820882815746],[10161912296847307314,18057954608617289395,15711072285528048231,12599582563255421284],[7179189851777865153,2291304068317865300,5386719777813214207,728346327977395500],[2181263023133443258,6234602217639684875,8709480131299772633,4273651065802682016],[9128486508852216608,8819755393499384097,8009884140796200783,5994557822673599227],[9678542729223795399,4738156468002712971,6286314307084062772,3390947276834014668],[8592015823160018843,4930774121962969686,11749478578590972533,4583678039023188102],[4259394374024321065,17425767052978994711,8179526746516672277,18038901638969221100]]},{"leaf_elements":[8288613305688838879,14180716416293764021,11475962970667568708,4292370067509097109,2571108438691727105,9537420821698548033,1524025682977396448,17934289234504689499,2397766991024578017,3350966542727833174,9989829517907635822,2230143635524191018,8498054669342883139,9500376590057600362,11283442030834781627,16654012422672792137],"proof":[[10464478013582845055,4975461008043945129,11996786242950052099,10680572758316276588],[18084834791691145266,4882614377124123747,4350829637346603182,17901197313592632704],[14565709391696508303,17970382867933687261,2144456689683828104,12575186617920174183],[8054185460985912315,17763288324081264805,3982127652237594206,13456112548250163886],[1649714068662132249,1066686290557031969,857449239541994293,15176769010071112487],[14729071311944170849,14713935871746607287,3648615568974089251,752453308699174999],[9562258557085948048,13372547626824009132,13236061662241470682,15612491835979002003],[1233927046198327477,16220051897132639797,16751611198785434687,4638626826517380373],[16997941248592605046,17357968689782668798,14117769338499298416,2452147352998598589],[5504258463987775390,4744121616222564485,4825860202296571959,9338645996048956618],[8980352979061308667,4598086631642156324,15533811750110744452,5517823221210662581]]},{"leaf_elements":[14626212736951583567,8903812811671659390,943119015001362506,5514625348229924362,6500353639644228835,5608009304040769657,15630966441339825527,13730630780786709585,3865863300303889626,1598074313403819382,8762577189265617459,7245021249575763846,1900426643395912110,6692470231000995002,758928419505942595,16564514846586691851],"proof":[[1817177965970477397,8892903816253465209,16693195518075372462,9597185461132641288],[8910157188061733037,8466121562721879851,12449971917374069384,15500789830269129233],[5891058475207402589,4749835522559585484,6483950710923490120,232832232271083754],[5294368000165470492,11614591583172126369,16667284920530638323,6575356461443334266],[3976837518371252442,15145345293521712923,9504294945427805858,6027509702242254296],[16263266941290388872,17382400537907487584,1224957197371930140,5413518745064896438],[12323642744090754601,8980082697403579304,3111027397215033561,6417939318202186527],[16061952923498168553,16842310330857708265,11456761709518579701,3208021872079498902]]},{"leaf_elements":[15920267745571211396,4654825836443712265,11489547206156672302,9716990820680749898,16608042961997007537,16288816873143975357,721635220683406523,4184711368906764311,14661776132073859467,3918254157819892121,13606426240187649376,5627801054846146761,13147617616818053988,17764187421975352752,6777134865883206770,4775321732727601202],"proof":[[18328600893238886200,14926948431011685725,3753299204105057096,4176920912488337566],[5982737508334746388,18121691574276278795,14042433880786536653,5889533264492936668],[11432961825429401099,11631875093749276301,10225396294454584523,5968815864007108426],[4525450369756862700,5708442494930066805,13764900236268214640,4883551394992262656],[6342957419655092904,14172751108096951608,559494499594709813,3806044507701688912]]},{"leaf_elements":[10001320883607625951,9093031184929360643,10693821488289199576,9477059595222498433,3277838132968701658,1911020951661265509,11445807731458614206,1188234046453733095,10489821863570627262,11333554708981475035,9177113753387358828,2623489504672596750,8467125174367998342,16142184445885892764,3786254101673252313,12795390327148649935],"proof":[[13715166892825954575,14682792909909775522,9787162420788442307,15548546982992970603],[11944921505594949346,3273714288328913880,11792623587127901118,14297905018534565992]]},{"leaf_elements":[12636509829310569228,1221361967083405863,5202005031054329410,3979567876410885304,1779072914486373873,17530329254161706299,17673969969636411403,1918506755882003],"proof":[]}]},{"witness_query":{"leaf_elements":[6745681052838910153,12941375688572390561,16577478721743811738,926023632264588450,7710903659105692073,516896783919785666,4326793014116619901,3777234786138824024,17286705439107376668,3193461169964857561,5687576945504647333,3099838663163256448,7799226495820800254,7153906996068871125,2675176817175639029,4337117446110366902,15972295167430668429,15210034730254088787,10589597732302301584,11835957034342936803,9344085683508489231,12301288001019267539,16884275841593447711,17359960087207055695,1019584513692683517,17441649641622542923,2092385481254238077,925497253730144408,1200458054205881439,4748440807866824497,15809110809013267726,15312509346907151098,8258209203816106942,15412143947359451249,8923520141891503075,13467478098939356081,12076203331443765790,8441470077700966847,7812095336435903796,16776870448704171333,10850053854545478618,6975481648721959419,16153745552372483446,10702896308225127493,9692388182895016871,1366675514618640337,17564034078173020580,7164133016591738916,15691521148869593839,5169599724815195885,15721071727389911440,9294350160573231928,7912678006547417412,7195991441735551688,9312885283306062167,13603782331823961715,5672019862725748216,10951714409665394813,12021123548191434159,13531749213261485592,6259688154498468036,657782077806249801,2863538395482153357,7121633067662257683,12944658956757310394,13065144402026283704,10808650309278480853,7573170362565928403,6391201777213223845,1597099850951020057,5090670068600911213,15303069339947433955,14945859619948630025,9442375542343387612,6044889465776597415,12793206040648549168,6798863229651108845,3852070103203806444,6328494762657829734,5800503676295570664,9774421342021826811,14667834641347939277,8395531933672210435,10661157427642613995,2431284100759915406,15470964643254524428,427822476496524809,5785339246929709766,14994546888794229570,2742392363101580562,1853526988526684086,3620254506245537551,9961846889199812664,7730070332818751902,214792975549571815,5880274302266971611,3147840348504254929,886674872424813065,8704074213175269338,1472454855419188016,9056626184982967888,204115347447393680,10730326655388529193,3816396860354761265,2453157908681557115,15379813516346165492,786738198580036213,17078291496074537299,8229596635104753988,12125249364534167471,1433383391148420792,3138378903484876330,10280189146497138866,1978947228685616027,13417428734580321458,8775297566161878969,2056607981269765123,12726586711685048327,6350057325523237928,2380126376930980184,11919685932796948379,10196926048133592928,3910397619218531940,14404245476473385870,8298015478948219617,17718731625727534892,8562770354560860795,9537104663954165554,593763280901492524,11889944212184278288,12095697026791498706,8179416460810042682,17770090522071140259,11528790985034541155,3435466002674680832,2903609240173634822,15769066349768315745,16703732116676971325,11205907648274055080,4767106234188800992,14967170875616160671,6250935836380721551,3150633435041250193,3910083402608297558],"proof":[[14291349090873439834,15828628404780013159,8419116574275268378,8623518889829188925],[15915231892067003352,16630752108157860611,16769561565448483421,2228697355870960838],[16359679837678031304,9009615898187278497,17624580497062134316,5361812016025895853],[7830415767409816827,16258655580529786313,658098159401143213,11142491026398394757],[11893280188026719872,6782652385941718892,17644808241477715699,16269811047079103031],[14335016949261856282,5973277219492829316,15737446979812044899,9799668899901468701],[3705932496644132264,9171000318007425709,16392347564584433955,15370645975799089736],[3596373838954873048,14897740085966912184,14026149665183578208,4192417308972101499],[4564809403960943374,8423566513632107814,1707614683921813902,5326221468262702696],[7691850121106187764,1459827651604039227,7555069735617777129,5929877826115281054],[16391006856544855101,13174509387560656158,16514689757875822745,1038430209706556579],[1497940655967358214,13630156479411054750,730122436998461860,15673002231968579690],[4276970651465757230,4798106957721691826,1394546242758998038,1766152576825261249],[2226996013236191607,14128718582098188230,4002719679309472257,16825846405825999845],[12940949825567938851,4178454130160556830,342376924229593311,14217117434969245408],[6823154124807899260,7966338225703430134,14719678606785559608,2396330595089434142],[4209660706171061763,15569665661657088303,9863745563231888711,4660762711415287022]]},"stage_2_query":{"leaf_elements":[15895642770668956942,12524310135386053074,17018294963059309495,15332880918955727167,3973592571901330877,12795761651432312349,3372247900713225631,18200213545113767045,16698788243995770915,9795998057615065932,14424406865708123407,10194935701378890903,17391448278098374517,15698027993687121432,4697481917717142069,17222012456573157121,16464474718864892034,15855439518738096440,9886191982249330765,11164970156286991410,17259283959956647441,12331789052785038818,3019871900518676652,8653783460624461279,8545075464184479520,14013811618215565105,13003417013466559739,1587489847297642090,12894571166567135756,9935861185430007784,6387674488044190627,8717248614186501093,13082928497577038962,13128516317592174392,2324048229697291134,13528133726884076441,11374381800263008228,12176979445848442168,3154002212980158688,13308221893329510974,13735453913062634577,5620259139885796052,3751759820576118251,1410720622594353804,11379875536208898755,1993502936964916646],"proof":[[5877030466462980836,1443898282466420063,16188034313248186849,153760464241689520],[15976580890486505156,9530566900335781102,6622101464097990270,12484967580212569897],[7675423036555550008,8180757152026412711,1456010401532812657,5073248995825763893],[12947228664721652455,7737482022480202020,15502192064745096266,18323572581552377668],[8092552758866526783,7945546526578713087,3442144992588456016,7025631137156193222],[10386980966803420413,5501044459914586953,9511707946858951190,10999217174947301624],[11312361510719349582,16452581178596213342,2052906767792374129,5879970705849642547],[4009249058772774298,760309567975117506,13885108303416320464,166344386169508870],[10874123821528932837,13258142343378984003,15239147464628754454,18360017335940045070],[14978581286327516697,17703601796488540982,17193906800188988583,3879545956313253703],[17485239565064882432,202698123668627040,16266738887308234523,4927921842445378086],[1522296109555796448,7335861267616889960,2428169126766825938,2423283291925625394],[2840418089244531045,6956509510038926798,4451505430699884505,8918330838650895060],[1535036617928300946,16884700650939292095,2255577599557234712,2056119169410775759],[15431745197486954435,13874496971823189738,3228584593985708849,16074675891240748779],[7162058758784531182,14467555510605993018,15067973510751214330,5027069747263159001],[9665480788566780535,15441174219972231479,18344208163066031937,3462579523809054127]]},"quotient_query":{"leaf_elements":[17945362439411971160,6468106319511652833,14756282797743926482,16224360547265996585,7591800316350551933,903093369446153215,10949819999957768502,16113891983029779340,14819844101044460906,15651824485891311351,12700727141270559363,18362326263735862261,5953717500260390055,12830909692362474343,3293540218344970744,16244192521824348366],"proof":[[15176873606960491987,804582004741056880,2924720689490260627,14750449509554215950],[4667957958630783732,2536229006894716838,3854407832907693623,16378183848296959510],[16906451600558827431,6205988369922937351,1805276213105129588,11506747013763678431],[6378844126945196514,3567318861025726114,12963613362390397879,14353911132932998773],[11763171870578575571,9043169069097649462,8187594492972276035,8534754293204882899],[13282787742507002878,14032122490972646833,15766345075123519490,5445126681414734555],[7149343205135467896,10103209794522520795,15673230615805023392,14821660524331112284],[9941598818770516018,16631200086373358514,4247641541841014435,7151541392003085536],[10604092727072880196,7083171609172604006,3785692916825685281,17883509024529488527],[5168974361080477499,5174402539904383060,6060131578374657558,3795044660063127388],[15322208846274842073,12145861525834611746,2954645224074674508,17232497199946141497],[13840576523102872980,15527695559810996528,13348250711211958048,6207171018495804016],[18319549917575372191,801163873808455738,7280157197373974138,11268447807634885255],[7708493307756473619,12121183682785668320,1806404105643427132,16670385897322179545],[15689308649803000821,15483749582084170235,15811237707733338168,2319812932780226284],[12895396197185972449,11126740586049677724,3419648526910130387,4052341779871279080],[7272481940847367093,12648501695579666994,5565709819533877885,8039129685255867198]]},"setup_query":{"leaf_elements":[8269022768085175965,4269074570531681556,8204429041223745469,14495797952726541940,6769032871906690308,9021059175369869044,12557752409631170489,5969923088749728477,2936848108920028913,15645356266941091325,1304218098327857879,6934865036786052445,4308275838927031578,9583228807283382900,4292691830145022732,2397096478595774720,7396310766280833324,11154678553237576545,11861020824068371689,10719764195184994575,8848897255315076574,12112884386332038855,12397235793512519616,7472216296859826789,14762844600967491843,1904432373786440814,2308928283878329561,17612623503487583329,12453106614184454460,13960246333414655153,17119124078613150613,11825203268965417259,15081740064235856061,16905503938535562203,10986723050985092700,8333477297776563092,4211648910937852249,17268122184972295080,2165957024067707441,14769144858450475500,1437956749483704928,6640558238414681584,6572118278395584631,13746940447554427420,7711211176184356130,18398791922225078289,7952249603731872160,520990492542531899,14390931121018065813,17906205171301448638,7065685827829859768,2636460002793106302,9019091162363809449,4464725388802521960,3310329563117533327,18205454908490449075,2125466282408087844,18375610375554120373,12642206725097667990,16711434108717348760,8846914950433461372,1299946575153536018,13499914979333364769,5028068449309924225,635948521506236308,12439223239945694507,9209838538702054472,11975429449559663421,11565335954448058856,14324798924556126104,9087734123979445095,14972429589644839066,3550948981493949236,4247490008650876074,2298292960995724790,11356766782381642543,6704545804800575576,6851064189296126409,2986923650232771180,2046737841865079533,11184195896669549409,11568450703880518210,8190558657555481893,13760384876007957504,7334465383008813535,4491806723969356632,7204421771621936886,6209798271119549184,4757634547762555407,11529624917136634449,2586294948008657495,7793391117258145768,2620422568462170539,7318092423786406149,3006132155297965568,17796500450950005900,11125716213569339430,990535265030734503,3823969200179426579,6188197809795887932,1214963169532924730,11407272251069061675,16278937014982376228,11671769954176642126,16034806206061328797,16556662585384031292,6541274127711370240,4970590513191713287,9327821886048292412,15256758568268022159,1153992631134250740,299494419110226598,16370362108995065186,1671428687249881959,12810993168112063611,15680412416290180230,1455265542865993362,2641421616625323618,15177328321875456876,5685696952369295453,12294518114590784491,5620234792143866140,16564401232482368456,8906380447788435498,14439535261596614752,13747166655353794009,3692854804680363876,11478568334692246107,9567520017637519119,8893652859049532995,4307820281764150431,12130993775434993174,14489715109180053197,771276716503849477,18249485853687271517,1969363113180059458,17153827700047277742,14101685100906436972,9117484834538354699,16714875808490063779,13675533234923834265,11082553855206456448,10808695894329113766,6611559628356893211,14905485616012090114,15544397671078706605,181671184297065778,15994386207370161568,9216959693615879380,155285145572773227,8864661939487886952,8025186729438816278,8019407724991194809,17362566004549049326,13595070902443545532,525295565117530081],"proof":[[14262593878734552657,4378387058871747444,9588461280374552573,5607178602123328567],[18420303499757187265,6207646028878006735,13074907441713185961,15626832596356854238],[5486688357522386573,16824223302559427032,9444794115438137475,8769830472655455562],[17353449868732154982,569769328674237173,3350073081077646534,2975838085854168822],[10696045581052840132,14395340946712377098,14534655342528337840,15667893210813251898],[8512598111152655598,8116077895680511946,13641043419018546127,9289025958912332154],[17113568062663711633,17079833357055392120,18266278014009980474,3156098904460813352],[12253492073265563165,9700415046234740764,14183449364801145308,5351260978144151476],[15668945522020870769,4098541368474706563,5663810471645052261,4910054282372367479],[10404875677777355099,8985115833914853190,15612204070982088220,3785758692260583007],[11260971097244220691,7791039234591438235,10259104585702269215,4521452020017224772],[6122420837302521484,9947821095257964846,16603583892148472185,11132875291048575935],[2730090891668888485,11822281037325051731,9400332450289659958,14637513002475153706],[1313300316188339233,10325956126307398984,10190652798675369087,1944091416312057643],[3858575300639543276,10545337542137529372,14217355428455828410,16209981948095272600],[428113797058758715,13603508601850025584,10691442901423439437,17871764610276256917],[7509741136347436482,3376409090404699080,7106851404074101484,15631598259633138714]]},"fri_queries":[{"leaf_elements":[489782013027748073,11453275241271924676,10781237671110180753,969264926569633012,6692836468204808494,14753496804054347887,15715830714901871190,11964580217740063810,2281890398451664,14384314998718215558,11452048610856964425,1823434781873519929,15957142669993559435,8859163207715120314,15256574684277325230,624647393143371654],"proof":[[5022096199048379672,6199622503392962752,1202666141558861612,746268622481768287],[14365770230395738360,17171499855047015331,2640884445742131376,3015110766363619115],[16316173435049325677,13554716149590985328,8370368108081348543,11730728595765136830],[7159451299840455347,1271302581397020445,17766652294300840879,17540590388690009270],[5379248944947567230,323363112964724108,1917746157943201025,4325475152780453558],[3449300485016786761,15089613031139774962,5266901922031172751,718627129065433504],[17033216936989073572,2053623912332283263,628131056313608018,5621174195149428922],[14877138496700979542,2215650922341520242,17911593516004854715,3942738312052823031],[10504395268979174997,14651771572968327922,15515753677725703514,17934982231393336422],[11683671531453992147,13960625176451837304,10788275555342768328,17467736906827999334],[15350683390789110051,15301405518210977135,10633127717102012778,13182292509634827356],[1791203694204585075,9187582029172557044,7233169940615514914,16099199555419632043],[14115097976854659465,15136337476635248132,617789316714937483,14741986668452770457],[8305776603362009226,1749975925679637043,12013609855588987408,14181483331819815011]]},{"leaf_elements":[6119698241724892971,15423463725945079918,11010327639047684244,7961208171554170218,8770043139210911259,244330069363021639,3590479239367381862,16307185478320037042,12020816775104831506,4015850030362087066,1816814058589911911,8347118432632179853,5994410054919755674,10818194923019336103,13512151832118029791,5434884427438902142],"proof":[[14903489969825873690,9382857854254471459,4239085181559393192,5715764225859896286],[1062481981392742937,9444423770895134111,6502383159224058287,10341248162199207854],[5030642402457813861,10419871788267039395,11702514835087537856,17622663803026706732],[9800507819878807182,3075833452315741040,12118580961539213895,8797252280784323846],[17559312392800279223,18175497990603696084,8649871887668393630,12765121594294544983],[10874252238558705797,16074751216685145546,12603326444886541271,16534763517346681215],[15469252601513200575,3186494292667773295,1479135708602784059,7186028669680243559],[13241601053237036052,1330499277562910818,308272140772223189,262869933712395207],[10353525029826121855,13475160485997056505,6260135248553038880,2021269807864529964],[7043298236281489658,5602865514217982209,10327341924659808751,14784042079067273139],[9089877299035286039,13211086284025128974,7103523635707635640,6143338230424736938]]},{"leaf_elements":[16912256254456137660,1076813285078972891,4748926420692429130,12610470485142703829,6312707769111196468,8994750170667166877,9686502592923559076,12136213819458670276,8261550132417147117,10421899122397309624,15297914183337414649,8727541663440280080,15808163255053239696,14135997183685096629,14763601431124675445,3328753367320439826],"proof":[[10281606010203289143,16832518416909921974,1854592011826265710,10353405996920885975],[2906803526197436251,411875867238100611,11996081639041191967,16502131573966292982],[17595661940868878767,178554794071102683,8127064672874581339,9987911056960307269],[918236989993081279,8225660018259151576,14790738802796286716,808225962276981779],[6026551991664605866,17755459923519443375,2214720157149308011,17482386775843006040],[35613239000976675,13419531204909925872,8182684402580739388,14249127998515460481],[11252694563654801628,10472470631434382152,7554028300558442778,12245882522027797483],[1523028420938813456,8383364562886835624,128497755588736195,17828178017860490490]]},{"leaf_elements":[8917920591746116402,8369040465166755778,9266451786985739694,11976445151789528260,9568995249128830054,17089597216308556517,18441300720855450858,9775341939747152677,4573632014101767630,15260932933221905705,17198318056576131201,13269290420609480752,15086827637449209093,309795920942949666,13497456220615090059,13837421645013311758],"proof":[[6288990722466582874,4605079513621284237,3332179363455649575,17887213794744386508],[10088467014977835931,824403521465322214,14371228890815165463,8668220266809457246],[7002479991510914494,17543255792695242769,6074089933033443272,13175673634540668571],[2442968217613959615,10116005101438868226,14441291019434002343,8737391483828600256],[6261215226436674216,15743080239327813690,1842525900557292747,17693706794580574465]]},{"leaf_elements":[4055331174193476774,12532707642948001435,12022388871363304741,15867611124762664086,10963337660646232085,12351399747807263981,13060729164749376717,9887290939388018134,6851889979818403137,14974206683912561298,7041517762395965468,3706114119568658296,3645262288933893539,12210277724026313443,4460587325738147426,9164151194468956853],"proof":[[17344826569041680859,17915507149662931101,17844090822775430663,4162774940712551771],[13176973524804019933,16965119035393196808,5769199517311706096,9495579311777928719]]},{"leaf_elements":[16371276844632437187,5763442631456442294,9612659274689155166,12661874354129793348,4727490084259142759,16024340444489255688,11060965350812909448,11778191179252601154],"proof":[]}]},{"witness_query":{"leaf_elements":[18410189389930604503,18154715959919261188,14434367190785138591,2934485332302589171,11391912591421678560,15163354685511330783,9024348649437955706,9783512535768952176,10205613093492719828,1399545465139121132,15816736650149080104,933714328127816442,4300787294196706642,7700104550187356737,6676950885477842872,15425046038607622805,3998512972023589236,5470923394378160102,1179907868898041258,12865446585152624551,15858172415620167602,11926347700981906882,1951376942621468884,9881502576688312626,8585938732118689375,9494835757382027048,1160018794899587861,699595285727368398,6632452187385102036,12426359689422242741,6188961019458799402,15133148597737668854,7752448391234280889,7496661363333628314,17601611510511140988,9663032078877696753,11844932802566097477,8556520447533130590,16140625473542788185,4734663793504308945,18169137788784862378,12720838106405953052,1997798037241161086,8438672923031476907,15295907894298157576,17259691637764073223,2804536453471893900,5892657753562829528,16556392429111165628,10201153080376112174,16709228901477365684,15335930781373410217,2767355110493230652,1092284673344274722,11740636712838904525,12710015416097500863,8710337995170941252,8822699593607896811,5188437837451321205,11326215160224707692,595328505266083966,1221254516682546715,142563984239395332,9519058442122222946,3618112415215991920,11711583970682149020,15105784553912319514,8659408422435175068,8572139224783425325,15895243344055183945,5401692923302864219,3487643059991438758,11943573902876806346,4246921689287809375,4346925815589073842,14189350729543852582,15259410727171808202,10061312729170466366,13356928542456783044,1153843496190249817,11270328450107823097,14065420433754244815,11825095816590081541,8722798750598820462,1868642307357021175,5547624624716805519,6793157422354185256,5255971053889106898,9182388496421739984,14043550143016649588,17415550661595321827,1005541849924892355,1253004094959594861,4573649074588799909,18140615423012259700,16835685826986110552,5476133490126687355,562517606221713509,11401845593289546413,8826711396166610453,2077217968633662473,15006391400644641360,3208334370696501434,11725942161873847922,15044929777477408813,15283028296250510310,15626575894642640748,128415798639828145,12457700550299579532,1608819424680907760,1359229620454759794,1794130685735588343,9312585426422146224,3338585652541566613,6340901937487754890,17020054138961407404,15666344837746835361,2941941990184354484,12344693584212532043,2493038218316832487,13449899069612483247,3519365399748412183,5113020956875258357,8048437828067426761,14473111708305511334,14625257354367488069,13942301985218636095,12048301060564933370,11532193038121530884,17952219536462397150,14430239839109294672,3337516362747756585,14977927028479613555,15902319625631962520,287469517608802845,1482726627006150611,1814156165198946892,3082835563767150023,7930958433248368615,13790756459965601810,17743846805647826835,7144171537804805474,17049793455458907879,3846784116054664478],"proof":[[13768442067150088017,463355899439133343,17044542480150814251,13260034947253325712],[1852399995120484576,13604197703011944567,12997638577105042374,11107276864245645270],[3364387599135598202,10164066852089168250,17613449692465367204,8218928381508074230],[3944753481835945000,1227842462121872735,7458351566003199156,130994185814389353],[17128158850137638415,5041699123094217455,12207825475368667974,4049293047457082585],[3938673445437199558,1836997926260250736,12471683894370286770,3319027949423823246],[16611275512678610172,14048741912722930974,2945255706930796434,3344982845225472646],[2452068023597954674,272260472092398395,3288745266927531499,2063053845688451420],[9150421958808154062,4337939613002765002,3103468421164272027,14607876935040166035],[14168253955453588073,16345684185131846662,5379130466470483665,11888000574428950606],[13201004233505234968,6692337209231229818,8543998868166961843,1726316670518440042],[11263541386650162705,18443438024272103079,10598250626068474724,17067289173094336409],[8062010876177787173,3840777413081073327,14111094449181610678,5825167940148926658],[13716458291870264565,2789114948348205192,6034087798742107843,11522583514686048338],[6942566360073020908,226008521621697994,5017838677763192877,17930497863218078985],[1283360576568911999,9024752693137239367,11803197830612791194,14692967384855259076],[8193979718528806600,8375224386207577318,1516291403550624483,7080112769819207072]]},"stage_2_query":{"leaf_elements":[18223694927726114557,15860510948665405355,10547585572833681610,17727936133194420882,16435318071026511114,9548156267439359461,2517181597978222997,13528535886983293234,4522784573640744813,5331499884068873967,12082962748719825805,17007350161607343433,14361818741976432359,7353986543363698225,12823096349042301053,11392967122154316669,8043480094413458394,2874288500868896693,7198008960775051084,2465371080014366787,12550018457024057862,14516778898743593752,12011390085274983914,8871214142702888770,5667611597680036243,12116839735107523443,16316586687273034897,15162462045350527906,18194669272687594455,8144264481644945102,14945903733050668144,16888876276622893244,1802375654772608342,3511037273128939948,6654310627834629588,14358640579680984510,1934428868596319597,987894175756715461,14956018287018183084,15694744506677347213,15075294017339165894,676940014253603512,4323411678281414632,17147218266180235530,11412767465252073323,587966354990153527],"proof":[[2757980599932267500,10613342384995796303,14833056700903571258,8714843559924025939],[17356598272958028388,6640837016033804655,8848381566037547436,4257328167802179477],[9938805377344610068,15652045927399326266,1921955658623962855,1342883685407151034],[4467372041623959228,9213553500250381650,2204244102463756613,10145410978261744881],[8574753049075697142,8402562347805200129,11982429493873602637,10357063950926808150],[11870291540257141512,1381739147602801307,10286717902921729160,2286113809442287133],[4198078538928811753,16376455811401392805,12334828913859292028,7358729174603313689],[7929207369217985871,4110923725880211616,2481228118863770784,18294823387234248187],[11139256488617601260,13412969434281082736,7826014659196411962,7470213374152012430],[8149031197470083663,18216113138193488772,13879358762115018393,11133612210944786250],[921448064421712080,1856540427908146643,17637612841063460469,2049457455388888935],[9646072908308207947,18205973964492597629,14806885295145170011,16896101033468033564],[908455440545677961,16655508009941010922,11733308755913606202,6095636759632813401],[16428134918643207199,8588225536303592139,12972439535044213832,11270598530371317661],[5162489818349268973,13349589710043054500,13023245767734892101,14132766903244354303],[6735894668517342114,2254395315240689940,15407949256100964303,4355345966601743125],[2156372198160320375,10758004586682519094,11754802890427400344,1564423923851060793]]},"quotient_query":{"leaf_elements":[3457511424861946245,436023615336954216,17799624762456499252,5038425588156854247,17676586131788385418,4043290383629744894,15531079099950365651,17108619774375551300,8447931523945145057,13088691725069275201,11616323102682622637,17319556399109860398,18406291754827009413,12851001672129110347,10917376650272288984,18042013314557779789],"proof":[[14617517238948669691,7954284420507999311,8585350815431667410,2935945392899106240],[13589117950927040357,9746269337847543804,11599663230105045227,8520875320488959613],[7008433469047891840,10405323074430240981,10175438812375341575,2128364958714245294],[10753966614022991229,9372073107205046109,4318225097083049239,15488389183480188216],[16352370274749706530,11818398831358702054,993415446791205956,3719282552639581931],[1969292286257130673,10983318117921567171,1035554867910042468,16497714016212218128],[5481740534414554512,14797883308463908771,14829855373651071125,75479475831071593],[8455383424353923705,4628263674153915324,15617697091599944314,15680390066073526704],[3575471459474931405,9880541081711272412,17494197746459880868,5776057185043690694],[13966929060669608677,11865281989402128190,16595489153700676965,7026656356306489574],[10489893684444205728,2013719584446375395,2207240940844288531,6590566214497674288],[9059011333609586149,9284104833472812604,8899715584787857144,16803969831728306352],[1711505184057674261,10716735790710893884,16554889277181397930,8889379984108888864],[3589834444339647547,11608186530418399524,18361536291754176615,14391988654379542291],[5244316050377477640,2696165019547237091,4062687655695369211,13729444231827613489],[8088998488997634110,13089346029432649081,8293343074735624269,7646789556839383591],[6781824673145116271,11884988964241063795,2786037544787052384,18285016945696491669]]},"setup_query":{"leaf_elements":[8927518685956390048,11212911429401899542,16865695952414654518,18213766207877288276,3990866878590832477,18021039260795035591,18029070900587935816,13903110454330784318,3096573101082601046,15032246084316960021,13325679924433916656,18396173718042626738,13793758763428443472,4956658101285299395,6685902276857780588,6897458809495175454,6580789565056086689,1203486675570814550,9213009161397478080,9142508813974705084,17407234494795291387,12523297654632150644,1496102142901437348,9117849562932542991,16092175071170699822,12935960170124926322,6420521428281662342,6871367244321298765,8886328400280086578,2557749853534304471,16963920400900058441,3875505358614433274,4272680327253624146,10364369494854035742,781314083181970255,9738545653504976306,7332374652785266868,11261467429497632567,17501934694116290050,13069720005812323632,16150244064662059356,9588038329514639112,12919815692487021106,6982598584203204471,3210743430624607986,14891573033010083884,11163363040951534100,5245639274337829441,596425923959758938,6952591045759629236,10093867742658924097,16144180907257157058,17149697262919167967,10605991540772170507,4892242060236499910,11672762094569605763,6756452632492817796,14398420394269406791,3826868449336016689,15102147205578674168,10778915834992095170,6844512651595672234,5052970754861353735,2491876962475850469,10371152033336391078,3033286658801889588,1179458374852154857,17820706738687894507,4379324354986861160,6354232233054005814,13303235293896137655,6912473606933338102,11119642902364698800,5259062208341869295,14837328670404809888,4302200913302510644,45733904563030751,18062175851643938247,247826870423497646,8972833494047060214,3304962657220086210,15138287803061977509,1949522166476252989,13567171300165522372,16024354733257996175,14875343461962552314,3817961751539547528,3966714308892849326,14956299871628342664,7193572902068170529,1366157392991248866,13022018516860022815,3792362246668962805,8925839339022595135,14665250993759987599,2491930331275352167,13404292836914523880,16448113486430150456,4831750605553715065,8003306141968986342,15286425033848263987,4204531793878707260,303862731373965383,10210082772191947589,6580769026755234956,79046096349554238,1172605028838544760,18164821141354054428,14083133584095156845,18314785612382187687,17882132195888363305,5392320397191935525,16442672932646407887,8263998345223694708,18025457492102899569,16876512671482583097,14811140202880623370,17322823165987616402,8388158356619047022,15847369589751429711,6165062115493405310,16509391999876114191,16772180624303639208,17124764067488659825,14721973923182186346,14837063077239990121,5568167623352927139,15753270103619636312,7834889194693969730,4316703794352237124,11109171997892898517,14895455131422669029,1636610487261345714,10839767416627869760,13324901083603964368,8629645337209356350,15118181651156940347,688456155306510400,3987938598932931766,5445154438841059558,15323939916355222821,10788783486711133456,1658225077446332753,11284148598369998603,2640427469646530168,1956235482064567869,4587829335079172881,4334122950886666031,5625505394065288991,18001044738171892642,8993179567564023350,453059132893612088,10528353886915958295,9909603312964822545,10772496021495488120,2976395662556461109],"proof":[[13131906532376152569,6465419644883827188,452226117784419159,2049681050008953531],[14067513361448678491,13238555191361562918,10158650003773665679,9242040510123154518],[2092261697634969359,10377044202688865494,16039205169850022803,6655669261177697992],[9207402209022873134,7641224134800687215,5921631175216071442,3506663126470954420],[17430319030547723052,16769416834300287697,2364575168523438811,1976873686135723884],[4774513408937394596,2753246574431522839,13107965977229167816,2743204171783260441],[6229381674441752772,1797194851596496582,13208727732938309748,5499122550994273],[17700373936785417418,15040472574135128963,3171053821966580989,16974161304486646814],[7211421386576141163,4137581158691924646,5748268315552895764,911966703017936632],[5937992383381055702,2317825300736465292,4124649405995142132,15599387190386157240],[17961235087298699401,18269628890759992878,16834530784013184633,18176014327005758373],[16504858662289506279,4690872895837906583,9291029835773317660,16366989395948893097],[1260258328600239552,3453908788641516378,13265558268735863031,14698513191522519609],[13950601968270291668,15943456506064495863,4248004125393776783,15061216520601992517],[6719564331213569590,11700843812568255064,7614464127953014769,11412413557214697481],[1118519530963883209,10848321333738772205,5330177198722116980,7353880659786792866],[6927789725927369932,16315812677162299352,8615590175857271490,8798523207874952519]]},"fri_queries":[{"leaf_elements":[12446675911922990400,7456678175094102198,1633782755558384256,4905734231601698245,4489208498331693583,13530094146343844467,11863602774923686913,8483167836979029063,11982868198317276058,3816298412120322829,2211364415767186640,823542571258455537,18209380040868663983,11124987520278812449,16996686366198907638,15884990663484606982],"proof":[[8717797785066230437,8484063210579564697,554223030047021075,5897911127323812181],[14776680320638941284,17228601325981009358,8587243351490896397,5298078449506634517],[17129895806268183878,801620766543156947,386391049283822928,10793898888884636691],[6381554541707916478,79700003853928735,4399371854116456340,6398791613859758755],[1128689386857144848,7333294753418960567,11760951841935104,12332217304484008408],[15183897116471918141,580919517151135604,12118055403592717550,5890010245747913988],[10758279073038900243,8807120153498095119,70975928125675916,4464543196402104255],[15816146118589258517,16085705309196697922,17884383323758218227,8591847605776600438],[16999925699634698559,14483301804494837555,11837935346939550257,14065040525768931391],[5560993721180125321,6206337421014483717,14941332103167783219,507647879905143421],[12524904950758693883,15899538688643250929,12665904056683340882,17046672169430198528],[13998472697584385936,17825694877373857327,13203337312014412736,17059353964402039261],[4823775090622523102,17377176146413885058,14886167961571781759,10386264933094300949],[14128138712872929702,1370874517542577445,17278172058011345670,7215150699576622869]]},{"leaf_elements":[5434397384204886932,1647367220139493755,13246493836745550841,1877281810070180055,648116456579518418,1460975152700504130,13074158624496823028,11703528518063766903,8436873645409789012,3193121870698497719,12462586201825210504,10755251525693329859,7519600075454557984,9173654905148175482,16531177615334822166,14584578681191832461],"proof":[[5320036643224632112,12125643764498842246,1045097466232450625,9719319257135260649],[11790771257394537527,9278511265911390009,13624092585985876139,235371087104883309],[17291760958371457501,6952748381731719502,10032569079471479205,3498879544559551690],[15780984547304911066,7464395814112035304,15992935099138313257,4584081055321057007],[13967830332532341793,7482900298188227585,3459953845061587654,2210944362901622291],[14225451960670226365,8682217005644736271,11736695591540912794,12812734629788952274],[11289909508784099499,233125539365859016,11747806001665158950,16879288390629328042],[5872310973465794002,8260387407507048286,17652874718847876366,9110814415591849431],[7663575497281316599,17016911603090047615,411057048560235095,15612828308844454255],[4504277996475953278,5048606525951268932,6329136227013387494,2728520336002152165],[12455615997980745569,6899641713496781723,3754459214410385641,5180782410589882794]]},{"leaf_elements":[4262321395863275571,13055337459452134153,12823271544982717291,13666401640947027681,17848936720258199519,7411565822077766344,3143333798965076162,14167750576438600908,17892470072781358699,10339989638211424725,14412834185781020681,16940475597288184177,7893808023878905030,14191281471272481270,11093550990803372819,15694007820642955142],"proof":[[8724032853710871660,15788008031823430178,12269058368328186757,12736406265053058841],[2793991506243677404,14195714828766125899,3870249537643338499,13322576793566121703],[13248239782513560201,8784636858037838358,12520162877350819230,16620597097712562824],[2540766925508008322,10000173882653329046,8654223011714599410,17736264187743334296],[11612781542648993884,10632861874340440575,8360153784511232952,12726282625267808558],[9533854291173997999,12634206107364485225,1042326679792034388,5882742689339055840],[4360551918683084081,5932106819593999164,3453896156327546243,13720849880176096220],[653609557330627868,14023145008717793735,9829013459427154980,4354604016037302551]]},{"leaf_elements":[17279666219687147631,8855429946592777211,4309255342613976455,4764814780513735144,4751621937901369701,14083194174134446459,14573227944072914671,7550597534809402983,4544329788757732053,15159291154471660431,16382589713811376650,18431205336565575992,10735689804459165358,11836617020555155297,16693147256681878461,16462192705382895500],"proof":[[10189440289794170276,17870132800611705169,17263899104802865952,11916110557878413169],[10519833401156300202,3420776128056826162,2401266947226965221,16213283588940499713],[4497714539340775887,3327503397694115431,1519925895300368621,11764076300692608910],[14217058136595866010,6147447817722482822,17513986941361204491,12360345635939740895],[9177491066822616147,5431401594819627928,1355274528698398268,6660308507820893921]]},{"leaf_elements":[9546429611733237515,1140136910027212754,14343156404839747194,703485673038560043,8941717885765512809,6005222077910030650,10120684140967795619,15074687717830685338,1277873869438304195,5877538223715750234,12170856735981246404,10120348378771498645,13471658678519707183,17206871714988631181,16417718761255008528,7814049447191432369],"proof":[[8363529080180658138,6254582814694413754,9462479987058175578,1198865157323622910],[6872717206768702692,11989125647797140964,2137644504125081380,9069676152651109583]]},{"leaf_elements":[10632746266096061438,6757646590349987949,13549814758625843258,704655662152719460,11622797146708305149,15759578015746123756,4397608871267503275,12640380755777952922],"proof":[]}]},{"witness_query":{"leaf_elements":[10799198268787379246,18068740036264633285,11153928154673392074,9206140597506679530,2653962175042095749,13720052414029364206,15636968938527541040,11516795223301797117,10626652134984059081,1574618725449147541,2395283310654308827,7058475271192969560,16061838297911114269,13921926053663567914,18140480263354336606,12702182217725400967,11625007817817025369,10479243650876687111,7071641526746354979,13798404115186862152,5596595932700947100,13691589937864238328,10751316064431744019,12129621519524903446,7524719548537036266,573078990368579084,9649057416074958718,6067488907448161704,16796194176966562046,9137735415812613191,16316356114288622400,6071476089162490564,6621804354232251481,3634475672571780426,10811980383628468394,6002901338771998124,3202442562472558495,14318373718123950559,12900141072498950762,13037080931050816136,15214386191451157986,12428996891504125075,13452281550149168512,12454043115616062309,5869925397205653516,3383138240901139253,1742773743731188867,7116232035281512276,11112687542376948918,11687537333048610313,13533852650405573813,15843068238436088966,4011525734542878363,14035693666158423233,4654374658017086766,2861452434891155258,1400612291229070751,5848949828751121809,14623225261752311961,1537388475303542324,4384227369825279981,7190042115069690339,13625987342368883343,4971029449689877937,13667247726469193173,17849696670558731955,1334097132126787018,18394729643476964905,14073296718360885293,7540032082895151456,14569958324834775296,8950721665297138534,3802379561731326959,7335113829742137426,197835326654995689,10950222968872363959,16228004697271355371,11115527257866266007,10211874878733653013,10595815764124182976,724133030209564338,15180910990924524596,1485655866499676368,5590738591653960150,18179084644573193240,10923811786003024707,11062699893062493936,4206878041010719294,7347301542135708120,4268098688786278337,16158408618605305595,14404556761119805999,10611819000466546639,17585270790688889666,1457727820900679894,9090193927561894942,4508519514304498329,8193442805273067256,12436332436369438973,129618804485453873,4289049093998585738,2660140642218487396,7730927886406244077,6011837768899765039,8260560196348168206,7149234119427701766,6386953810123638601,2692444499047606626,6689964033366251279,9862459842328985859,6727403032234106659,5696130497046216575,11702039947828420852,3437844018825400047,15965903232785478901,14140787270586991329,9945737946827202187,8763216141205434697,13554924182155000085,8032800846374581099,13595479582275707175,13387383462913682958,14591737761085947500,2089461465360241179,2167146265457988358,11173929392704524315,16099424710618374054,515060473984948668,12979497703990038669,1776438963859210402,7518815309783952779,10732062028602976942,12241784785293404885,18312054409319933995,2341498394209999279,5950546892465630168,12141655769860888783,14544787755658775325,8488521046463590210,12774143749940555431,1563092532442511622,4928871745656549727,2321522917070920587,10590902770471187379],"proof":[[12475918715082021796,17221912255755477014,6826464264107626779,3769353501887067515],[17651203386232522402,13086699723765324742,341374573939509720,5095351965450074977],[4008376716446744326,6853393764795316587,10309313975289672349,11565866992474068206],[6750331184380337113,10575683384455557690,14306189253337136187,7059403429553146153],[6078984443799967803,3841908149048026723,2855343132066027683,16614588290390068401],[12340571523387227214,15555166431423107094,5302906478425883592,2417855906059181334],[8548817474169303317,17685764909591952363,12931238055979587948,8170212941906195410],[6815625894695306109,4220413194132291288,10986461608443358781,6627468877477913480],[7372054610533935394,15800393290741430245,2653358877455638148,5171758412769439997],[6777325188367458369,10127849247387955812,4763241778513040300,10253779554104972317],[10692112391609062562,13652730886460284754,344838544685866440,6831129619583220857],[9256750090946359798,6195576108749903505,11569382056554426208,2379337198073711084],[12171468388752563465,3974905172621117607,707886176418403587,5424617864171359525],[16813931685102365799,5825206935765550028,2650311132652818727,2796713724659760683],[8607331835335745171,5198647886119040389,8029907983066020265,10547498145789355232],[13239482398054249942,2673767639284143452,2322923916887495121,8336621435945842114],[8962983601327175991,9655400076779378322,9372067540546984264,18437205832166210823]]},"stage_2_query":{"leaf_elements":[7668595378775949116,15503547684475222061,13903762803620121620,14032252731354389961,5431684347307053852,14457738987863171438,11448967095430642901,18276955384594957041,98941771868952586,841801723981902865,14305052338347060110,13883668394246560168,8638266811269335253,17999328935682492416,3311547716592622412,9897431607643672771,985052819800512746,16324711288509953695,17655460992251973699,11054750825279191660,9813800407722938702,9775381504639847154,16475938127535088835,17473660321268938322,1781334275046093363,16819219404280762227,12535563999649300712,1946805825864894433,15270198205111616722,1020759047241416823,3760250762394814225,13425220215388801556,12207824287478513631,905326520747222557,7245376008482264122,12796244249060172774,10035937288214637421,6993076135870606509,10562909594363074224,9478526068587389201,2528249171572245352,14709509563626212790,4864148540560111164,5737587369862384141,17122553856126050582,3737236018812645567],"proof":[[8622085639504993491,9881580253793518595,11751628475340925017,5571386978532560973],[5871028473736120703,8231706962139958526,3726297889875336799,17911940343666927744],[7157174333672310430,14759335859141859694,14104204659718732710,7184918787259054027],[4780116778938880505,10473868448073551508,9769321339286437107,16923743115399900517],[10629856968351208529,13616654034659519351,1359813895559109002,8296302053414356407],[16242171195366031569,15528425435132712173,1618805108542458885,6185085674560196892],[14146802486146372149,8777940987482558882,15163930091204416146,7317219141810636187],[15496868145191569807,8448931192373515484,14083989035049650771,11271641037324691267],[15492684505762134155,7434478122601579456,1965494755912553079,5841777264947372356],[7666294219524560718,3046471056182383449,7231747833909283098,10481641838461252110],[10014299857088676238,9586490996629304215,18138123262759462019,12035228185452305485],[4970037015940752331,10220899103832988816,107520530470454562,9081136768900615765],[6883050908451920084,13258490328327274825,3362656289417267426,9658916423143002879],[1066574399309555827,13861956427340046859,8068094826638353963,7730774632107968837],[7588865767032220312,193914219782039569,7696748358993613800,16934781195789449244],[7868377146465893942,12855249661258455866,14376170410156481376,12632632809800891006],[1911347836580775672,3246100548763748938,467751161131197312,9129819829973384756]]},"quotient_query":{"leaf_elements":[3612445947218116719,3202934754768458838,14871837639508110630,18036148293584513203,9281772046620376374,15987568322035193283,1663111280056494824,8556504318060163740,400808503479080891,3917257523292041034,9678019039392384847,5171599751542144492,6461108441884199601,18141585950528745867,14144318943092630651,9621258842631832096],"proof":[[18289611862776643962,15486663004416754905,3161988572810111629,4051898831841191042],[5321874565723417865,9782642787343953421,1791444564576055579,6113784478627337498],[5851709828624111932,7964914492686103328,12605840059363645451,13724010111360605557],[16738600421124419843,1074517889282401330,1017506583827968559,17807804086364776487],[12064889172080859444,17287943384466982894,10587828730055288362,12014770237244092388],[5670718906361907609,7817414159116313396,10760202497832027793,14530496549244229813],[5272510603788718276,7977995217043948145,4410317769640083431,7407631788023368694],[1651342655650552871,3918770933666285547,15956177268016068087,12452285937127511066],[473156210732659691,921090530664611965,10879334813379328767,14055947036684019093],[4422174463399873598,404157732127176452,14505004020507702417,11689884969919064003],[17278564172126390355,15861262025737836245,1307465624687996323,15599007317178906437],[17968143651393336078,6343643663470436517,10100993998626151706,16231234035198532363],[10869358835726026339,8786592670801120292,1067552455154773576,15199038818399629532],[5726755206137347640,11504357598657247128,8453423272579862173,8494886719386744077],[11791972715873763438,9131695644539513217,13662595149188886189,9110307681402947124],[3750321380710082681,5816539556762857119,376379246827409819,6573078953659508109],[822135299882928769,6832536832869235243,17165440014740463881,14363198558232023699]]},"setup_query":{"leaf_elements":[996858091970742284,15161552003016254631,3384982252044379031,8342884692221166771,3695905709588088899,1787597219973930686,8054767053071486234,196754334111305738,14236111731547315621,8850711307306562864,9769312793893973897,10730240088963052419,6180737472292406558,5376148549955945927,1055626566126493145,17296523380918592358,14088049556816633781,517880080763341834,10980044653713666009,14062416823139533991,3171629539227204538,15761604864705127115,8524255728204594428,13991799890737157814,7567004959286939387,161251591922628466,9456486609401786218,10841342032950287633,15243394628789697064,4505581206240648636,8433758736422403609,3930857769130650288,16613490340721166748,9945513376941707036,5897860262084346863,11607329287448428997,2010926241298403619,5295881672635606002,8863233455006547696,11258522387511570307,10135916521341151072,3398437145843000129,6211152460079174031,12386701983901662136,5626194148764176760,15483086611693714614,12253307715443441041,12766534767347155692,15024939701427803850,6803974538146239975,8432535245296813242,12689563117401548263,5625242640985475406,12228112788467227272,3155727582202108090,9730704359361338379,8012188486919346992,16583224613558197051,7452386171738568821,17930018242953223673,7461271244624047581,2169899992354563010,13505943408052074802,6980867237970292738,4392353084681421113,8003876655517259136,13800608864362281118,16258050983475086989,16697471134101512383,17057358981347513790,13462028293269134315,13512349798851061013,12127894606949238410,15662706007099375855,12059838024347559390,18027789513434746187,11602361094371109460,18352210520018999209,8790947814115267210,1268423567773950971,14212303039668902403,13307660835395315663,3608694376210649224,9750126664179906055,15888678436743596953,9994196470819895087,6782038793977558139,13522687721822360274,10850859656792748066,318641374977126757,17366744654264311354,841998180038456176,506041159782319584,10658439771381288679,9114925879178582688,14990796396478513125,17813401678289438509,18443466070345593385,14594982000546987707,14935672580991692477,9831498083503581401,9964992285234303009,2451995792442650381,15069291512958653529,9823734938015055525,13620569424596184340,3821852819199769668,15761841055103148691,4670634577177040042,4818817709955557750,14713759833084525203,13540183784693287897,8914321585121886764,6539965495247871993,9280538234087915794,4226312896923334481,2232375544169420981,8502426364116476355,4366479943122179354,938351097563105273,2181788818829963325,156209618608596499,10328647953047360747,16002001192772889185,14800203709050085818,8989817597057682924,958308477790442908,7125915185725039120,18341841880167620714,11146551735339667246,5997537884553218331,15051651708339718019,11601760343934950600,10971693993321127471,18226008886657602939,2639430819302864896,11961010627942727049,5457563439961978769,2079052719631993224,5950986239076938179,14619068137802491822,10471835974176176014,13029934206654332009,5432671745302186445,16982810125139542183,4014173364080023182,17805401118728325166,14412890969469079137,11281281330979584944,4317656880360007810,5773289414740745921,8119090823619304964,7099930827089130458,10452773585574395605,18027589252596174687,15993672524360054193],"proof":[[16681542878662346802,16525418686196086154,4272004226295823059,1424926054681607325],[10187233255226893963,12470064312243518506,8737500388747308893,700796257671668483],[16806839549847440485,6499941928963180508,17606364828439087127,16524552895627515510],[811587496495980501,13978223573189324714,12830813330367056445,3644376438202651212],[8038104984192438808,11554302508308879321,13561155399236723502,11205792802438943073],[12702770489147715053,17725105942176346839,15785279592212959816,4924690412572086249],[2653213916672305477,16782489359844343205,14678506264709838901,1253973381452522603],[15820117615849052820,4303395305574862786,11092735442587157399,1241677156029348711],[1158927368588800185,9734830222807123703,14567336083151162598,18441848779621781265],[11251355469994826902,11950863575868749796,478198963007039589,7854814420475460381],[5218361711950935335,716925063547578866,7125747380395881046,4375805245787176327],[3003050229408030489,6121496092745291975,5083786187706897548,15665096224231391224],[15756672942519370749,16074711355497705026,13696263220648647550,13022462473875923444],[5429260478033976428,4621875931443180758,11301723517424046019,9830652928388405242],[9843170289675800805,7995296849457435679,18405160568102689865,1598108397849921183],[7763034114238797210,2612653954970864313,9874548532761189295,11950095805038490746],[8150671396367591155,4374957965196029991,10091316552250686626,14304794448001423245]]},"fri_queries":[{"leaf_elements":[12569964782023722985,18089884888128941487,2640587423830377694,12631485792755589919,9702774975933929050,17400155822569050334,11230761564889390192,18233434717505906578,9369597211716974228,8139451533365319942,10253203092226032954,11807271772261660176,15793959154398863246,13768344381292340187,7123527054772861226,4156361559709396682],"proof":[[6105290563465721839,7401487624424825444,6276904319000719763,9975437905341095452],[184801294887200778,18262905201800540815,11532909220838124754,16537201000470707538],[4991859810490387759,4378075723168986191,17654012237066114268,9501232143766920082],[16621197876699004083,6610448341582544349,10655882036226330635,2698931149739831499],[1973177230398370287,4666533756200562929,4071532510975263892,727904590674236162],[16170950323112571067,7995953437986530188,13770291967175296018,509214785503620728],[17139418755728035195,420508876888372129,10650707190352047368,13917203785143135351],[8473388142568254340,12363954361302677611,16710265677884030359,10035079514650217706],[13212075939307842319,11872535553378648165,5362238111505083010,16673009782675931438],[2276869002312310789,12401813723099263282,4500577639405661464,4220881837525096965],[12804266039777223056,16617134972034215403,18052193349293890632,31956772440529670],[12964310144795253432,9359572043478289460,6142865816189849397,10075952539003905660],[2036743038621850211,5423246773758321676,8041016251608296685,17855908391359447905],[9886176930643768256,3509706781999382685,16706751567586875992,15900181631248865387]]},{"leaf_elements":[17681066026058599288,17088923411556830249,8864419958177427520,4721740169080706901,12479279657389972724,11232191380137783915,13785331888965507863,8721253180203864409,1521453266690530320,8829784044085051530,8199111305855629588,5143309562342865314,5712779477934938650,9476445256877059551,4290452914811870382,848484376821221408],"proof":[[6549399283885283128,12356420447326217694,7901479380547797233,12461606609374635301],[13250081473924644611,18351359410347972393,14658770994169693771,9941795286532361201],[2229743263890511775,11797567579834177002,8324069364362218267,7666408508985819601],[13028416757163809500,1277015059432956342,7821837138154556742,10612622123426737869],[17988356703889614878,7592976855302187605,1692579413642763385,18272807123782107542],[1324867912688693108,16453186601214787160,6619762080785909612,17752115918178743268],[17494869305395753337,4961433545005658623,7911884974694246971,5116307041215190463],[3606198615680283068,8341826419673431755,17045999887938912802,8300154233453410827],[5026636560436696287,13883418723755199122,9321075151687256125,8471223717683390813],[7449431501732386882,11031208553786558036,13638679846530505981,12224306339616136851],[10540896754816519323,1746180075358321372,9865956469169334927,4589766901983917581]]},{"leaf_elements":[11810758584317519315,6421333944359502825,14711899107253209562,10039318695516060832,12441924327031041461,11412621291522578847,11603067686391236542,5497810538704222783,1480878166689846525,5513695738671650668,15830090065130675317,2952579713666160534,8372994276334994022,5055540193111726087,10945302768439574805,2138696121384455822],"proof":[[10539791574557803667,12861250350397460048,12602443473783676758,12757414653549858227],[1218879069259005180,8155738191137078378,4055729702935778513,15036670355692589945],[15188015420307663230,1443972785254896526,7261898789273661035,12217802353950193718],[4464668195902016821,1567142276250821161,7318222863089100348,602040788114977681],[10614996888964200154,2796560394353300974,1204347974457658853,16839839034326824896],[4663954751585035587,12804534650387228562,12411396753901938927,13525409144612957816],[14450638296737090204,1943028934310837098,14316870729705224232,15060349458129626311],[11336173358147927605,3544125422924662561,6152060134110928826,10783791288329227367]]},{"leaf_elements":[209644660992467470,7981236624670252726,11932920748403604872,4361343008001914034,7643521429816577838,6703440668344515679,2465083859564679079,17291541084766694631,9303620243513280971,14518020312985471219,3479481489197743092,17766924277817490653,13984420254708705247,17804411537871026809,14977985963247086579,4657640788002236389],"proof":[[1765660568392667954,16612828980820299877,17777668650555512136,15728030860423917603],[3584789609523557763,6774249465229561907,2318642676291387236,9349036952032406618],[9709768892637899703,6190342253731074664,3593410900898446460,8749794855477996890],[8431282242568030943,10132639644794228227,14548814393084832958,11257210547446171232],[16976949461203448459,8268644666328080056,14706620297076897348,10709889567794796744]]},{"leaf_elements":[9306828645540789088,14829391157001254424,9378227111629524164,11716745019895415222,1848398401099685924,11084788197227462359,7893267969825095172,3640734689388496039,13110229117454893753,13024444064704880195,8942605042497989081,18096099345285820199,6836986349229157748,11440143176033232175,6539666487464362440,6381810964383519537],"proof":[[17328635329280208295,6571238372153749382,14827737472456699520,16135031428133869750],[14983243035340635343,13554744403256603391,9231851320950367445,18031029812144592016]]},{"leaf_elements":[1275295786118718478,7488170357634863325,4283449960128273261,10193008459420986025,4238185187837649128,6318479223569512088,16394860438500661164,4148361282767282169],"proof":[]}]},{"witness_query":{"leaf_elements":[962543764480990767,9790478694895714839,13869657413555572805,12043347175053606569,9088602620876353685,1129781383665051610,1124488131239236774,9654497641306719621,240049959663894164,15982810596629938496,7891665826977680023,365184171765512131,4674594715722944145,10697877052838875750,3519016630502318575,3328598027682917367,17071947520638739141,8723843191673825062,10199843960884047606,17994430773749291028,16790422896248298076,6285127567242535712,11245627516861863150,9511460255800755779,2545153887714516782,6994831950507563198,2531837527690924986,7475786312227631089,2958422493039817005,15283942240265056545,5510256604853637463,5094579309998723122,11311397799750989926,8500539238289983196,11913080880923893173,1460907011976702355,9266293915372765854,2438695589732168242,5946090088235899243,17964443586552408664,6663540646594456684,5254686296318316329,12172760475649144570,322876121745909715,6585055050286179093,18259226013008945559,14202919580187457935,14365016347442204567,4903721090985057228,6476055106378289655,3790610219760823077,3902481380144437399,6535138979105330491,15214393197451121648,1890750321996398774,10919983607005679852,7328156285560263438,3315204303971880577,5220922141605304325,3990926496185028277,3527339020447361842,1063186961466754095,5357417843446535971,11470743272450710558,16663036017601049373,16789725729033230645,6709191523393128043,14720647817850333273,14627285558603849504,7817687530895601915,17714109848495377259,6525941626758915567,13938331537410944337,1304801458811967603,14667549372441433188,3580903003028916509,15102550162022095019,11729538421873451571,7115645374610536809,10016614273183469498,2218773629827819503,12101553696356161851,5816988309345331575,5052791059980346649,15392326055790680099,15429509891051585669,1355138419876196400,4005180944232710141,3661889642131483670,7660856038515895345,3019133405258919872,6598191841276932286,14509389461920972551,15168148775119213276,15428468309768493886,3732746173759970391,18398978646591117693,14686531464894367623,7563247499481007961,5197934417392009343,4118190930058123807,17558899507444085530,15511608780000116939,905812068763953495,4056037803529731500,10638907263194648858,4427689293262509390,5717703521956537,17690072293727945933,15999438916257618210,10493309904533249738,7464272960194332290,7905243722643288306,9403987000723689045,7969690333020627384,16987652118854086750,15417972915565749844,9090849114184610647,4341973625816139999,6394530133380728689,13295688072983600108,14091135055130292513,3767465428775307628,2742570146094587375,16970259979040973698,3236911481340606702,13291950745595183706,16479870552166304454,13971267698725314199,14650038117742924548,14175323390935335282,11370889964162978037,2510055981526483163,2616862424533435352,5896537935622088088,6723956939449591926,4299061479282444437,17686769348718342491,5912542408074252873,13017669440885621686,4830652091932463306,8258820059078066610,7867240997174637248,4911596056038789159],"proof":[[2160586731004797568,16669976917957763264,8695427173585811960,1907407007973974796],[12393194328019426166,2702022311485245722,14963756022051636487,17746153623460152765],[7788848277751610699,1955672594591610864,12243757980200199721,10686698981038676956],[15716815097730679978,10390709770521537034,8949948574645782238,2140525648173871825],[11418673040100949758,2633272619335369701,7325628184278767864,4146029320095949794],[1456024589332262354,8372546904977441595,606656369223581800,14058234013364572369],[11999400564730534905,13139627443112491397,14537675676262052982,13563467249206094703],[13441847558887863438,9718827731850522215,13095901435583480973,17890695898276822980],[13208056181814743801,16406711712732304152,15021181443787121254,8832187101429998357],[341128648956184765,15537226037705854982,8831957098320084677,15755743652015724147],[12001217750480440234,9554757812349437231,8708018891068038810,15496400027664365107],[621119540339327407,7394532388193304695,1346953693518743401,8171014714679719720],[11192557884134429346,13936271776851846129,16935828077821843303,6441598658011974182],[12756153472076262821,11823419683496555401,9377948782734553012,17307180851149203689],[8694984196385831170,10377557517300121577,1303216994812448465,1093394040747371251],[15346668047248116441,2526726310755198274,3435646062692882897,12890230126974746074],[14592655159823375692,4886438218661956004,11773371646111906104,1577097193499964970]]},"stage_2_query":{"leaf_elements":[13473101018129866910,11508266811260202270,12007963368828906751,16263168934747207213,6067290374024879571,11006200644613612853,4514528378873668899,18369560051542733415,10319955394339820426,2183414836125124083,1262631097942020085,3710060362063342255,10967768808004014440,16905010707227163240,2879549163845874345,5844694858917002516,4441958628991574007,3698571204031864756,9885392874195905174,11938783998424279813,9018796329708264818,10504518020003760185,10186138891453231525,4083367915170641773,313563116869546501,1303986688120432362,3953521593731883770,3993520766062745952,11257478345682180915,4696882890059875764,12458656898955875531,186607309543037396,10534274969037943528,12477596745077994676,5993011190245674055,2090225133150811278,18060040448146185376,12113813604773659618,8347792970183072375,14736027040133157367,18259865507269581091,17817330237965629903,111167176869091335,6600740039254764110,11999582322492258280,9861955287253577517],"proof":[[10320564585642901015,1691836924246946470,14151892366252713181,2858107695655748250],[16037823707508610344,13007779577495989929,13085240279676124663,366968239980575868],[2149465181961357421,5920984572688345075,14428782954691458831,5279379131053387587],[15877330500684381206,554638013607047391,3705840931014579440,16929194591036230323],[4427414548576216290,17118184715432547811,8401260795072041652,14067943169607345773],[17908858763915685049,23830377750464756,14891072702964242283,17779148279340690642],[7910289463077214955,2542153644673964924,5838625174809448679,11028810870044317748],[11622576874695388845,16941134958432076329,4428319256346511782,4528744628301077157],[3383964537745209039,6661508844135421203,7689862909044658460,1898029568594427799],[7067127426295495118,14510919203066549047,15815999439977272880,3656465310424128428],[11278314806766806320,6562209075793317491,18154571919846583372,14105652427593700443],[15798866322157949464,5628452693019097750,12147058456259917239,13608666879464318690],[17351831067031926850,13073705821167718358,878325901321159050,1147235378273085650],[13311727995642040165,17116652294159426363,11443022982720948295,8125816725703023611],[10545993604532934878,10528420384796372810,7261146220497387840,3242804158690056784],[4551867285975537203,12482358037606313884,5878331143723473561,16657304009053288735],[6300385583840829135,3508707821927913265,5255373578022653255,11410137574386606844]]},"quotient_query":{"leaf_elements":[8732544776090435248,6829558859596821615,16048789184789349933,14757690616493172695,10317117779518782888,4700158289933633386,6458206820681052509,17185284263790656501,14716867779884377163,8031654879016095529,8698598218863652073,14916487269709839380,11936520331767662314,13565732675454029051,13980113801430586443,9327099207746254414],"proof":[[7241334440440452104,1462988024030371080,7848054205967963516,6207989241482257818],[7260525046945196627,15378828949793860442,14081067087148367205,8407897803307430074],[15639795698195098827,4492385558154213748,14041741730563429061,9374612930097763806],[5809264801476076410,7093756149124454468,16651521538964191896,14003513131951270188],[3139366528294930164,1842761905820452873,5950862739723856414,11654029746088304536],[755506814710230480,7436529710761935473,9343411269311358163,14126056675753061672],[6345985217045108715,15009899409453069989,7721794895226875389,1672784823934901453],[7710233880949845438,15347449655763199602,16973641197054195408,8423392024306193774],[17590088356006846427,10436634965473311474,4861272124725331963,10210785969318814808],[12580118267850973932,15570178946490964976,4757714268103928194,3699835563392782198],[14827112857090083206,12498657264657997710,12201986760149698950,8927550220450339411],[4591570091464717598,9408309912895708245,968269066391735616,2816859179518595640],[2445268512523980988,4848025345664641189,3616820369626697447,6582411498978013429],[11417965489048702553,6887990736505551970,771904684706104089,7738600763714262413],[11300409796497706097,9731925357132144884,1094570406514492297,14706170954544622210],[12737530948504826777,16198149493584598394,13562122960665280839,12900254218326374689],[3678234868369141147,5283638782478520511,821763301433200291,12666613813678185860]]},"setup_query":{"leaf_elements":[14361617609395765171,14716195771048100355,11586359865825615291,358431711730803012,2852138839635012726,11696750353838393160,348503657630653640,12271352340783914404,3011508235420234354,2913530810825829562,7523882818723404774,6172621996574199117,11475606511004564026,16492169673590658168,7985195650476919072,2328643312426773820,15201663729451921459,6159539795358282746,15899881275007957337,7444746047431604356,2092880328103872489,2329891594048424508,1633599454019461964,12048651212030435634,13721157279313467585,8146410503887083570,2059742688573272098,10286548106260091181,7525905469910826715,16844236140991325260,4131203670104872051,14627893542988035925,9355715683596392422,8589056057618047552,6668392467740900150,3047541174690130848,6888971125532699434,348187181260746207,17312349016480315474,16477678683945070435,7699569921036045689,3730340943856317112,15189244572437778691,667209075192944912,6551935589946101243,1079604350270427050,741268235332529216,3950905366762271124,895207290702505086,2015093308159417386,17032746290467356295,3671909227695687573,6918260289489521589,5244640808521714230,2182813655429810419,680637133065710225,15360639487081568929,17077380526483125788,5010308106492304944,3881419584363724071,3832527542146279000,288686433571232274,7493521510153307674,31085065591215635,16011480487110288625,7311267252053490715,15529672929396298058,2425575547438018010,14617502763605908061,14777944571880543910,6653573010934156399,7261077248134534528,15878754766026868436,15806722585228748001,3279367236782631769,8545456887784792957,6021338644937849529,18028841807090697444,13766454391970907950,1224829023039158227,8620023522701066951,4478655965307023603,3846490828282182645,11173292704968034817,11263623826225925786,6550576226175490675,6132216579567118402,1064648680834713492,11901121993323377199,11774434557843586227,10855231275863183484,14333543216998404495,6294215299764437678,5066514643447554384,6692000662484618030,12912391286977177213,29672929144363031,11318300631535947908,4413701281252629663,17307611136710930311,13547105235949603613,9654199880386726780,1845924193224465523,17740899374918624465,5037119059674169356,4664781606202889520,12518355730856574268,8644135519735871930,5077967048533453556,12030849210158969617,8760572722779467688,5890353071343651146,2822237601306157144,1432119416893457474,9348979923638274756,10375281979122444990,2401222140395723108,1599194778815571871,17980655220955962466,12403632843259432917,18007908618741377266,1426296150508062428,3320710621771641523,1863472600278465867,5537328691447434176,17462978901935230623,18147157988562947289,3619937819502059483,16462550442557702723,15471873107211468566,13403575159395301988,2618408941890877026,11375803347894312901,6476738173081482226,8846701143708600480,14240343591592353245,10244059869061970309,319238552555948587,17947593763752818390,12616704838004564681,441509370006145377,294850312497169079,10752539154098479165,12694497768292898675,8890697256708159347,17476650235641660762,17620883859803701355,6396603490527401975,541790391147164915,1735148065023525144,15578523551253782995,14326091851950431649,7351132689950955618,15638911729468908698,4597298957195318974,576621087540694119],"proof":[[5859486053042975600,8542751424193046826,7525236283253854018,12442766273363664350],[9562287812988880882,1574692253814016268,7841191784670044666,6303576214402036289],[13657231527524001591,11760660796994131854,7920850013366333278,5970504259448072931],[6513986488380384010,14211979949624793593,3489343529341997035,11825118960457275766],[7831610922245367881,3419784883369453692,2913961383317113117,11151642654674562117],[13757607659958364235,16122603098602458729,7110036915938162275,7956221986108296775],[5452139006896351777,13705510576941420321,2740813304016439263,15534577464961301103],[16146653515965334344,15202150661742980840,5410790148544344317,1646821815622678194],[3650259297564933428,2459877754992417475,17940545204955518520,3255021432799356979],[10697457156075732615,3898640503690225552,3636912597041709431,10182697981075166270],[15405126242375565379,15495761049579237151,16152207995789183478,13775130247663489770],[4777540058468810000,4295088888814684364,17659910818688793145,11212353397369000927],[12684293717741082472,9052391683385497328,12355018871795983614,8040185737804032060],[10846596146374530680,6439652907334445380,17694756985870183299,418786656865738685],[1306832656619515287,9764804451951828868,6479109755049317156,1962897658694048219],[1604331307223421191,13365993051588967226,8588985829317977614,3926111662093512656],[16354204956433885405,13679537276615897443,10956784370045293126,16160403238752695896]]},"fri_queries":[{"leaf_elements":[3380430511598912821,3364945717078355733,6192066860292432389,15770158374096331448,17794115403599962052,9905786637952639324,3768119779010403073,7321028807451054115,10365966582729289055,8414510499841692291,18428226387893877069,14605093517059961680,350489545049474954,14779899111881000740,13665699183748120273,4501048970925404744],"proof":[[1900537679310948217,3899403695751925705,8693367565976990428,2131590372065951163],[5156881298118299745,12978732311887643570,756852392312251248,8540129137199693186],[10722512857478275857,9931141096695178644,2485652812036211033,14198085255133806429],[7862398128721026105,6643714362538890972,10505240836156725858,3893747400555841066],[8002621538359001365,2046403871466256583,10459269661081712486,2453952331030065331],[17196867408137409970,2614042674284719812,9155354770126960090,12852511643288607441],[12438860889875389050,10972782197648696704,18093796242210254467,11457682111145825594],[3836726238341685946,10079168969762852131,3707670051783397345,11432481772331923463],[6234477583062929500,16233509046874979108,3799137749997784664,17369566115354690442],[16226722186025184926,17693783690898548251,5696597435566175827,9002755841729060102],[14907223291319924982,12861382532814708885,14845924582340091506,1045781553147400066],[10464480329745872290,18095765198530670135,15973523973771035502,14445717066983072635],[16653975507766997525,5852361545422212783,4542679570729558458,6286968683788957014],[15841979698184688428,6766978167612976972,6988718529989188967,10317852718069604352]]},{"leaf_elements":[1017320026251361784,4641370182097136894,11988304422418252680,7926440288883991872,8057828690307956152,10612253304130693162,14237536914084552543,15011610923683514993,7026486835130608262,1260145754453093295,1307770716182595868,5741411415852471554,16274114817744372679,6544717127075101492,3785821052936117980,11274164910819089781],"proof":[[6650631887856024273,9730514297950239957,6403023681134821185,8616896439488676689],[4912366103131291856,14080718427305213021,568912489574138790,2095060229683750658],[864325577666479807,14080330293327226381,11272976988257578733,3485097881682879867],[6872367757123053598,8802815915631202364,11414306041135231497,6215050866233424820],[14962140908226045779,11460423041832783336,17035372071083024450,6127024752977847906],[17901993249926394237,15592774075548184888,11973266304709751608,5228508862428895243],[9261932072719496463,1732880658612232297,1757057380923141906,5729594146579091951],[9855187397619384484,11965590780756612056,17878326641116136075,14115206121431344812],[3328040420158164936,11165030521055605488,16709879237159342819,10050784542656473286],[15738158813134786993,3418264850276457326,10335140839884698714,2264973671078968161],[4620940820684181288,6218150265279905101,4394142517619279316,11376274407012839491]]},{"leaf_elements":[13713871400471515026,5105851072197809770,14347176796179315240,1060578361966774779,1890200282205157456,8395901905656475785,7614492144335804984,10499068230968331576,4402033734427494624,2538394005315067832,2661516888082042181,14700249145191952079,1351049870791636616,14232559915038444846,7198655618667140494,4006272436470889421],"proof":[[14898395012003271928,1708728697999280854,15844499921824334298,6058461129983249084],[13391807803485242915,1561322950512284726,6112540951335961064,567883398652138552],[10032461682450604986,774482194185406858,7448749113079130964,6650355820063834383],[5821954786998141726,17395087391869507378,932575361593848572,7011666957116936189],[18136518950016492913,3446196409981501224,3305478383428301974,11228373037873852684],[176306145803066522,5103082738707997207,2246879073538169788,11813999213871271566],[18157687998917215258,16763460318887211847,934215623952467888,16511182297630279563],[13141057789689340553,2448709708255569924,10951846470074346402,15630920576161203827]]},{"leaf_elements":[18008750123803443756,16783646190608621850,1218716906253685443,17527763562736679576,17009704451381297904,15514828105146821904,11591824136999617349,10141133867558695741,10040478892319366775,10356395597819727055,10302721792901033057,4949277830327608350,443817731075712960,9260510812446255709,10332033129550315450,1190371033251799840],"proof":[[6095056834816468848,1235033246879491277,4658499611331575862,16791861771849062753],[9056137171644731333,15839044044753202734,10383072268509844182,17074048888521335562],[11702396021756725980,6341214669014431916,15614636811617511183,3329397537271826463],[18105499576403946718,4385796141796696880,14788005547233371370,11971365134580477349],[18094368428717041921,10947070686492808250,14391504912823517373,16135841269932707575]]},{"leaf_elements":[10436843727865497361,17846276555127019869,5922784516808728109,6563996082027773457,584050490551381099,15548329999239472536,7506827572629213845,9991002189841428580,5484499667580979130,8499433419154611987,17438216066036198705,4590668035734578888,884955262166708534,7181494639364029331,10730017351734604780,8530100638143981646],"proof":[[6389906513795140626,18102858087891980784,3468257514373005665,7876526185786639359],[3419541161667130895,17696456370165664112,6168864541569884414,1311020060133671248]]},{"leaf_elements":[13912788208633012260,16592364955197622110,12930883254427910878,5599575569218380943,5682660096836901399,4069773254031359724,17686759155637027087,11829746095036037227],"proof":[]}]},{"witness_query":{"leaf_elements":[6098557726281640283,7144598297132702012,13970179099357113074,4695747960695012386,10696629641580236086,4686616071915692151,8793613820719832798,6759295947612107040,12178027865395988653,8183395475245243929,605627682363541891,12935807259286867044,15690436185131997556,17909865388748841443,16968166414746940955,16994138106080238879,6010329704795697510,7791178853273991191,9905575640016664015,10210330685175595673,13279045021519808323,17410003731732291843,4177675334094389822,7677117615034338910,5842776648563386921,14912767874955992067,17195689678634123493,7397434871337530671,14738056109064085358,10063868826755054187,14454601578664518099,9793352142299549376,12029906312899208266,9000840181330619968,4568057934765727610,7417830975892964363,11740146703107576211,10953663951756810100,2200857761730945028,11352535260054286618,7752855551301435479,776874133674723701,1647409654082900692,15237858418670512161,15759582057110893778,5570088738289171891,5240425119600348409,8074924433170910923,12162307574066862589,8703205883464723830,1389919037526631441,9247093177824670111,15409324254359064854,14252514413663460007,10823431455592517856,2639212712487523345,16949366628987185464,9423856333660584939,18260427980821108550,1825562616721966915,11008244716286364086,6827028710000704338,381495106794627977,18097628516254141295,18361346493916973628,16417656680043164401,11180589505108481156,12479021942380694146,5342917861140633680,12028047736811734747,1137294288516918023,126980491308112311,17565200478171532611,12259726343951286323,4514262545718782924,2347644797635038260,2762576311653636257,2607568319389048142,8704363126417868835,7633784861786995789,7104207178802290745,9981496826027917536,6594375862188504127,7664919593857353011,14113064126944441267,5279033401868884757,8628070075871768932,18240992033742399295,15262972561258135437,8424625794390758398,4744865647302686904,1384310479267791742,5842752656093383698,13907433252819447884,13006119551930448591,9109726810962687111,8847509631556415876,7072683285233906439,7377119065871902784,7534791405578626285,5977629124034314498,2796154278897596091,8089538642843036613,3655154790074530250,7169377353157442680,10138426488344084259,6742881975742996874,13054152598007858003,13226849088347718547,9296074290639598524,12856968461060892723,14310944404489594501,3298295202450434811,14225503089217240910,7866727135389509985,8011520177618483362,10836517837964147660,13364785673480469131,6175987522856368933,783647147191068972,8299449430202438982,115768301671188607,3092585966736259094,13665711160100446474,13485489916250672650,1410470348156128838,7472216788513704241,13017487324768849263,8108650565637757838,15839769298425704235,11047463520473546658,14214024812638901372,1953528616039311215,1990515626177838517,4536482665791536663,12621322609466661059,9972937322378988404,1748383293257022157,1840604043340795939,17271608387996891686,17182888906021040578,11138840029543661737,13545180859831192189,10981199989648865111],"proof":[[14131708806875512725,6801200218157802674,13162759381250524787,1887698701750635484],[10325235329564675712,14891182431618471776,2697165478910836530,9047509041608204484],[9529264687108991703,2258921767913916111,18174100475530712495,2563729320969071731],[10044166536633183918,16614443145782571281,2693525458990848815,17314846685777066047],[18199874980467547715,16866496933136149401,49904244399627758,10747456392902510379],[14527379311773678625,12576275911361023468,8409790789627626961,2178052236262090821],[15975396514508784565,9300555346683297418,353735587077899999,16959148275327516182],[14319043466811952065,4867772149460427292,6595964648083350899,1187197695395009872],[1950083671390585506,4758225399093568404,4875013187446959993,6452548930385382814],[10324220820306539141,6305811769648214879,13043321332079610206,11913614221470831833],[13624655667899685032,11334756758757134955,2375936784545738395,5371925656175677897],[4074160570535076440,8043168632818971329,16105727044416389234,16946044955617495200],[4472327006228494930,11650099656022050772,11323060203700655853,14384838467436796222],[17013601653888395377,7181258041684432725,14890879044533451566,7250811802975538031],[10580330045952631618,18210109412306871855,15185603242483274353,16601870024971746666],[17134617493362201888,187842468183985438,11980778488272843485,13795208586381332089],[12698140864963633855,419357374229537337,9620795343936707768,5865575737066574990]]},"stage_2_query":{"leaf_elements":[11383008683998387603,1450774430943183692,17161940485803675434,16077882623154462633,3796408923154271385,13850799852571582164,16297776969442060953,7016667437754992532,4932838165910251274,15233611405799014322,13077612400123668181,3123054861910177910,8742550366354697532,500122827124976853,10718561189917255993,9936466671136854361,427590737976719946,16652346340224001288,15155147908245812759,6120299254462090527,7115443171315007113,1178883731130259366,7398553007262547476,16993310641066806763,17030507880661251977,16838417085185177672,3967296435820761149,2875014449304197643,8848092008535954307,3995803097028584409,7134910653806698368,3007470729932746425,13391506736467831538,9529039019435667308,3147535724865621035,6878725941563670172,6011268334232553030,7740152905608575636,7179618071904512139,17373856416092273262,14924071148597370269,9589000601117107243,12916952664869786707,16262189994458785375,915785757362520558,12970915432165569314],"proof":[[15211932308430483975,5905666429286353246,6751206599119713164,10002011267415872260],[7011756834232805059,6607065483099357259,7687032928103254734,7242720958493015417],[3748923979842968559,18393360123102860778,9258626693922630989,7134252803866283434],[5748181084395467269,1912974160082026161,11685050918105112469,3220111490398522116],[12120467774462418763,10247112255066552457,674543413786779780,13114698755645139352],[3109019163453488640,12918443568161929724,17503882605992658708,2141284066257659639],[12133351917052634522,2163769288661289108,16807387652669781220,12442198588528053283],[17725780827711967209,9110141307284661704,14830092611762817159,16554718980018182321],[2434559525982128928,1075373593497746206,13944350915131981818,5357784020610901697],[11995952899828771320,8804578854797028238,2787217550875857892,1438286532867869704],[10144505640281745034,12532889282393492064,1105989254135243042,15884033704398224275],[5706057561334655756,10408046302542889570,8014185075687008120,6560147262633630351],[13969516050786863809,3441289653888523837,10889794370033735994,15626096336357908249],[9516444592356662370,11378272857582721347,4048632104377713935,15015437443446213250],[367898424570566896,8137755050054760145,10379342972369113947,18298303448950534836],[1574636867628112338,14593397744862756232,4669446545421119623,16109745754166260757],[13885167953277892178,8555964237507770117,4719750036722080927,12815453938056583397]]},"quotient_query":{"leaf_elements":[9226060753074325239,6851735941555433237,17085673014756913905,17527541009289459830,15750973572086049745,270448344585790588,1186943593517500287,17559825786575754066,11344621778073461998,8510060045759047271,10994779218431986499,10910414352462345728,10026741139986625582,15321466735987748011,2364440729680951740,10813467817918625013],"proof":[[18438659671560454671,18165957433813534285,768101275350170668,14782663312696075809],[17150895711717386740,15395366477546991509,7173451609164297784,2344276533626872896],[1781302147089294045,10266391720003187922,15968519018901107480,15690458296230955427],[10042656396326619389,7051971264781451429,5715967263243970215,13469327843421070104],[1200011812491392760,17085820761137864184,18010154069882246100,11459976929393762264],[6145077569378795274,1417856670996367047,16738572714405781048,4976661767813034805],[17052665408415758862,5666270769581036035,15160404691618301827,7259830211135156841],[3225223401769193953,13127840018062921367,5459542688463869794,12020723967666274795],[15856264530507837660,14890092157064019162,17486598134428695040,15958899369646692475],[14385639934362578612,5971562019688860881,10525660972275277420,17673426430256231408],[364280135604617896,7541465375563105354,7756049376149105605,9521105051396295902],[8893526814529327900,17216299897784617201,7050679418812568113,4851116665215398128],[1157120995834017672,5859631489120510324,10810681840373346546,4366505028669289102],[5571749197931755700,6877649227788159671,14100717490040360238,8047007383072030702],[9534380799511855413,495072294960755210,1717921508308021765,15616678203382664111],[4357853304662596133,17214980539843074930,14850088797960313577,9017137664508958350],[642646296282338947,11452596773553033960,8795257061196785695,10386969935657262527]]},"setup_query":{"leaf_elements":[1811569458845522401,244460564962017438,4323986592476582491,354517612587555187,12893078640110933206,9560259219446126073,16992318033232434302,15087448701733033313,11702759358933946913,13966364164224895197,3346949920017828994,4648895947007604564,6724486385628607350,16569721813640122101,13617434267873064050,701676266880681960,10600563791578474248,5640016798256333551,7099762489242003385,1751914490525333402,11837075715493002411,2201221168685228580,16418516501788932429,6032915064056281933,11047366920135465180,12544335696797100512,9579887141270207294,5543710633148129290,3701463468898659097,7221805737983124327,14015487505547998031,2425936238711416589,1880476062288170447,1295759831548549579,12519129032260243970,4426970028388656591,15448504525766634625,16332807745131275245,2381356341970768941,5949347289480323481,5680398432625692954,2244567162549544377,18105291723073134555,5717145288327574488,8180648361823478243,14843456568071138031,1383736390737129254,1068575603719970718,1145053978666232608,17710191540155430927,5014390946178068399,13439719613833624710,2085540306701243886,13961096553659749207,10135733744801415640,8687749892809149242,3064081008612036309,3345284001429731509,5351894499841394013,11357526355545123179,2266047574417360673,16530228162800004379,18248574400541792254,16269273093218659637,1736468762672730110,4588504500348982441,18390818226898715692,3113442817928848359,13870802912025303254,763677769643146341,18202836620271015429,17979851191534540808,6148206196896116877,16343635480445500681,16605286612565748697,1901569261876229418,14337653961498906890,1362416205442981909,16858972609773900643,2599324942515814368,5887708529411704939,4106577714584043321,3005019026982384793,2651018542509529252,15828350769186198010,10071615037314756087,956928764039845446,17494737775785447438,9431988690851299374,10605098350370375563,11933827026442880725,5849473456055359356,13089142591811433073,6810155265258459614,11954660157984326031,2626990464879607796,7467342248298758296,9942378936410297952,743675199598238859,5853277589469196044,851971286033987135,12288810171666242278,1115444884898656675,14260086916422012870,5974481628500167243,771134135838115006,6634781981733387403,12761083381549001901,505517208693519867,18125709941394210061,911369566829484130,16219975562414570037,12295798273654757527,8594802517095380133,16889007515329363037,6367067682279812661,15197980880237964267,6121712727713748857,1506499412766681924,8308078744538092243,9711236453999727108,12028236201931761250,10664648832841080867,2865964326861511079,6577334810112107955,3870292348168459413,17616964197540739483,18192264589155217568,4683874065434190906,4474698881783826645,3395791862359183305,13988194041926000520,899478669751619067,16483940128669110524,9956877837976300307,17659013619617636367,8345414028840208412,14424461416501373531,15343227166972192381,2267657999173410074,1669250227092525483,4124431486537182461,18431267638241279675,15986424320645776567,8399820513587071992,15684080836934697224,9340103262181495002,11890706138760863740,243109170424152764,14419055115644568351,18356920322754748261,17514820580401313341,12106739956019032368,14947208330609997581,1262991512467936643,18368547908659707581],"proof":[[11767100448843436852,7384225530722575675,18215154412725453266,928863519506205931],[6591810365469337571,3412290877034836557,9719021465883100804,13832491446727958136],[5548334064240326492,688443227357397923,2038281121169102315,4199737666908163832],[11481369762077772297,7728272627968294708,10078667523946009557,11774498068007903194],[15778592020679157186,4970419342397300673,3356696272744485457,10092361440977428770],[16080407074293443032,11873422543299534370,15412153977449816096,3941408776054449648],[4450992664692313054,1479685433004308231,15314631769547730190,10305415979407448941],[5021206123462048915,2701127048112495988,16008099036505580033,18000061798350577166],[2517979596097086140,7447542988222932038,9672575106595328714,8138151421668043448],[9509238752270969996,3025601277984635406,1935829189436785944,11674910973495766928],[6197558001540972453,9648983121678871783,9897226771258074607,8605471403729808976],[18107168331764032313,931984165055913954,3190652887697998765,10605557907360924642],[13404695200881476958,14003763711418077500,2823589979017393365,18419705034713121749],[1206793951439572652,3240057310943138611,12777979774879813966,6090535044155986861],[5352150956151545359,17778094890981291229,6058404588388026177,18212855547165826657],[8190593271882194398,7115468430098159643,17784251794283646679,14448971095443897031],[786433969103539048,8122187790720253298,17324655261546370362,16556773082047786574]]},"fri_queries":[{"leaf_elements":[16040349638026543323,13624031033876689564,4344344189538563734,10772649674909249384,353075521062819998,11911927462802565496,4486712682049044338,15272267474778208252,4995333872609801714,14288812910735874100,10229864257465680628,801907839958949062,17486265927917782632,6674846406791132233,5571963976683633774,1246544173816434650],"proof":[[1774544990579535308,5894627093653405689,8054789820069501137,16154627313840528550],[5690605058724258345,14330840504200843615,4127484054844915519,12926283711329463923],[17834446920942845110,10197260481144579125,10197049343592918913,4091604185981968388],[2456295894333460054,6463118483096871870,15257078250082554646,4989217334074078563],[6405549615418721917,869104235800412581,5716158314194909220,15454945185492167292],[401116012481107233,13632613859255967968,17588581215021306859,6712919633965136447],[12119447412517393943,5612481766234308740,8671467275296446398,7044588815720600125],[18044780949359645706,1326823153981796138,2871797630926407435,2618384127409654322],[7677631816239297915,5817834771059706391,8798019568208575717,11249978963659791189],[7003929633449539,17543331618223683837,15245149001714046150,4842595598998155591],[9753582873000194069,15714268352121796103,17489641046966051125,9573165452856098112],[15604979734507043997,11610233492028050863,6709863941018542612,7080527578284617478],[10229615385892962512,1718756580777323066,4707382564778896886,9389804507582440790],[950518108147387034,14461496559104778806,13917507090447352020,6484097189552047977]]},{"leaf_elements":[18046861393636404492,2588861871544559390,15902981142838276480,2590447686271964962,8836482085848567362,7693589122639863586,3872421383160644368,10178395369092506006,18164055542678770279,3162583490057983911,17273138491915491866,11574747208145452047,12123290748482800818,12245741129429923013,2220311742618769747,10703913673863481168],"proof":[[782070173084278169,1502440033886429106,16020585266434619150,17881335269035844201],[15849645211963623731,8456462387367842616,4086120357352090887,12844223532879431131],[8596421956587948225,14620036314082509656,17510001204576769391,16202303840699646803],[13654761758151639864,4478212579236098180,809849708496463731,4660183837073233521],[1026242843196253651,13654498068159113644,380283490351590715,10176218319508341870],[6854921752117792939,1846472350588322776,14122939828748457276,6682849300353908358],[7824736261622928727,2790176680958121019,6694649370308943926,15658477214473093682],[13968158917406751446,6748857748057787663,16801528556990827400,7112089288919322738],[9121011749794439349,2536714253601986745,7296479366594970617,13068223385451608737],[11507929926413888592,3952646010530610676,1079003151158642278,6120734590715615278],[15418802502015684347,3748451402095185069,4925493761703378520,17844205222826790497]]},{"leaf_elements":[17407839103139930721,6399178407616750727,7193857414958684563,1272046906441736328,13711638386719965148,17800030911867382425,14832555368397594602,6122350887175298269,17491539382619844044,13304434405080205712,9686718326192721159,10468053275191632318,5328034198502404413,9604723885197505465,1109515946525055515,2740893205308582809],"proof":[[10441821099602858090,16185481355563203555,2313096870552936691,10076336582442640506],[8924751511534869206,3514254485201541890,11176660853867181106,17771663942502343647],[2525632278119711878,2081271203472538197,14098517249098684320,18184676452438551544],[5366161170260597906,17260824508777275072,10166589009980735938,11376665321007317418],[9156037377531935087,8970572349018138833,3132039825181669659,5516197660221193868],[4548528687289471365,398903681704784651,17996135182076109005,699358910855226803],[12456869959304718661,7739810951929326255,10104392169542390190,2294294866746549694],[3212075062214438924,357583838110179765,1255898485944832398,18404599682258834503]]},{"leaf_elements":[10827563137443123512,6564079519561029141,3785708150385474433,7368176874480740736,9421232567063335549,16874526162037474022,3583637343140589069,2682389595243150911,1664631967048508347,608075356033982274,9786082612603596644,634514440513399054,1462513210429768666,5883092825499990694,11044809816619727134,12704861737268672694],"proof":[[6191447960000595900,16915568308146643324,6236670374429367141,1281497129581894048],[1294320808522303890,9911618821930217027,4060929396840542143,9938602981826797593],[114106257567448089,5039424733170728636,9391311288302047408,15182568808806756339],[2672309755977980332,5187402289000152348,6778195048294274822,862334714937443092],[16725837145914548581,1125423394101345531,17017529173301036278,3401633365302970415]]},{"leaf_elements":[16104655806175047737,1881940834397824730,17411786609115749057,1091790505454646865,17323693140772335757,6447543619076328413,104715464376403502,5872382279492108153,16474304650616669804,17578052387928834119,16898786332104516971,18196806415198528929,16245969746828663680,16558604784865910672,2785721629986159908,13051111598487616997],"proof":[[1145646106485540453,14046992658961309318,14640986759384052772,3130139382246868039],[15514906446679858530,10979498789109703592,12967136000864485334,17159923573772454695]]},{"leaf_elements":[5913797713474501816,14390836815188810001,2598086964460305874,4219281277613110736,4341490336555859025,6837138495876505826,5182460282140934405,12936941785162437742],"proof":[]}]},{"witness_query":{"leaf_elements":[10297987923101466376,11678098760958493820,5219175883205836543,17028895804225215673,886364654060011980,2185592411255256026,11114763938218616499,13256904214058392977,16505857717429583374,3670489892249318326,11919299816263473190,11119449973956035315,218053576295522189,1389961018911206760,4405207863473836426,12523874798969122441,7390202641031942068,18007267095711659572,6730457590465792347,17330777917818285281,9323041580546865390,7717023105463515609,1205911114751660418,3841975417235397601,1460030009849146836,10169959135135246166,7845158454601176598,15946977479316065229,11183889116013263664,9099605292099118049,3616186926900514425,17276612083277050814,3378396513086246331,7434649879465403597,8885321683690494804,17412862341346966692,9376366006956335809,178663267266715688,3576656244302502964,7374842700594679592,17807142479728222668,4301981874973916669,6600242976159902030,6288363495225583325,14143926079634724483,2200894250867945681,9181865268380611418,9173068698386598434,11655654096628957081,6753414600310921425,16277611389930345916,6060347918995855513,12556322521684818664,12597145140816489592,5982344193175906796,9295522217472835433,9297795830115174657,15684250388311779917,16427543393651583719,15926051674587067533,7216054742207116814,7694146309049203250,15622630448269400685,8963808236506394038,12285982572667830923,15200747323604112329,11870804813583995761,2023659550564782311,16051808084756162275,1666508256238100515,4481509761324723403,16795323722713652019,15303893028696784450,6774616775050609469,8174589428743660055,249218920924886471,7230106857250541723,10547946818240759913,6064462166767313182,1549839433757367861,10589237586570594170,9022038190161370647,13469149881567365990,13419935063267038270,3457468410890045909,10055200213503276855,12542744416852030838,17262413752206430200,3049673654082409136,2573661679588721830,6184742126370372963,11904599673452055421,9775968094923421219,7911288237748275702,326512948812441150,13499016509205781635,12187906807642639721,2355567888644959239,16265942595090661544,15926868496819996950,7509971325152221029,9261555402243096283,4476063756452958227,1395308738237386852,6810490061796206979,2796092050066399264,5913746707561439452,17805518733728393118,16018499965671060133,7470121844039915135,6980761631848541396,9219743713399433392,5752763416094986718,6976810390002346146,149230796205895060,16643887179081341531,13498150897276431536,11844816701035609382,12333501465682010690,5238375030828309655,15907865517730755530,18200690922298097024,856622482494772483,46485849509504480,15742181076436550362,17762960281713589227,147863985311379256,17108298017953209521,15706232322836100239,16112170945798155960,6491259354432181054,2988518776126495159,16949813461626990947,6806166171619323905,11930169972403465144,6434197814675298701,13149171364001782708,10056612477299315036,18376092245656377551,17020637802132171216,12147362843334294376,11184909368142500717,11658820849518672872,11085509052427311348],"proof":[[2728300210722813377,13191561350601549610,6143115229169667594,17838843445466626704],[1074386492669236189,2342066776644211997,14219283926506853519,11570918833240323193],[10902400918056782857,18121533392816200779,13634412574064688769,11233245194258126263],[1348146305348303864,8050978586276888531,8845371185275132731,2045655461366236303],[11216837020263631770,8185219838929361509,6587439075498900306,6636200218983836873],[12238858581121135711,8236922352714825,347165927059221184,2190842739946981200],[9649407806240642555,12648843168970938,4905368355618682446,1930586134923796818],[2383893104637416296,4163550412960308694,2439102157280751501,15654318134012549216],[4730040503186690711,5432584781737050898,13317295195282454492,1234078488466549274],[9974394571823514219,4433067874860415624,1216514259768625331,4370525608908709475],[14844767360176221819,275248410624795675,6307101653699141223,9741475442273453993],[1004871640215402157,205673213934680921,15774625605479059884,15121144679756499597],[5813689550043339290,13313248924656926357,13604417308836705824,6296914790374881751],[14078595607086964039,108323526473581094,11225385385346511571,5515185956017066989],[11728708719257457868,14025933209678301021,6291704182898352070,161351983032848869],[14522712409405351831,15213773262045569840,13601261310463794647,6012949829838098909],[17749797669654443142,4009991232882674734,605325695833004585,6573277157088601865]]},"stage_2_query":{"leaf_elements":[9275763503440316454,13573339524095638507,18029953468233342878,11467151353223875476,14783809043622129511,16334605502248585987,13011910476283990114,799872917476767742,14991471824430296639,6256407689821941033,9327312974535013946,4436917299207043443,15821574181365208952,17509812329798079781,13374722273390141929,13262659533469078884,18395248750706946313,8430598877561868106,10927143612406824185,4496774902918177563,10095108127717378969,16742227690245831956,15996553392301852268,4857257718331388173,5065194519403205431,8956750826020644689,8786219579533250044,123418478613938448,15775324457206311540,17799166789767882340,12937718581806773488,6587400053843781300,10248603301471756348,13454662741034035152,5139332418814824912,652183128513386701,10277357651750648853,1625641377049696765,7308997137622333238,11964660305424358244,1845658207563651588,5765076831580342935,6120108792220831422,12092385168868885680,18147736845069594860,10636351018148274078],"proof":[[6413068880557935308,15073122692830855493,6388305920431744773,17646498831648723830],[3627968982031077975,6071619002705201233,6007554295302626770,1120292869450837638],[2204549827169767887,8800135339372919380,723758215737995659,14910987395382390603],[9113774879982320271,17520899033380128645,14768966731263726117,7619375822925214380],[13710648722308626726,6666888010042707858,10009307208698915626,6061133158959148512],[17063696951461195262,2608359157263013361,5838013600314320644,12578070661003432347],[3732515552192797128,18240869330473467275,7895367575533910544,14187168150101220286],[9772503107239655553,13187787698308928617,10931630066642714910,3525148862134715290],[14800263398277303320,14029630708534042187,17965006655722952948,5168049525712506397],[4963730729166908063,9877714473730981679,2198273961076629039,17924109542255568690],[4751795063467391053,1989043734914209139,5091354197997179391,1246423282233096767],[8459484975213720669,18160162756093305248,9729399378799996236,15095958847496514477],[17533158579453012101,11514391927251259031,842561374513930224,12009112587218381879],[11844614367538632837,12350955668358762779,1146844080689057844,11482354062348557864],[16889796439405109493,1498507539339781266,14683744232357773189,2392027625498531379],[14654549554724599708,11486363989339565874,3768422005632984435,13721579883788157799],[2715413528194906888,9925031826019529185,245639860247107963,3124596961874203968]]},"quotient_query":{"leaf_elements":[5363062148540561893,12700976815586024294,16907991985089504793,5973196074679274255,2569951429544089010,4377628331549122768,18105297349479358139,705966818943700759,11691682963461510791,3517020766919747832,5520939741263512974,477806352877610959,11731921608625689027,12059993984760878046,5200420349747751255,7900325029299792374],"proof":[[14143551972918072004,11839088904354394844,13408929411923579338,12960795296808217955],[14245619049255183047,7315349409567147709,16196052898520593411,6469061980824221205],[7926997074937090592,5164072272928399576,7826134545805635323,15750146431726142026],[8059202156668124574,6235036795773617833,10137459169916218776,15419729573212872521],[3469033386027574262,10761514977144347621,8019515322198999264,3667177179851992323],[2060097639811269958,15363803403292418101,11052249698899258852,3470077564037606840],[16498264480024346844,7765657197970935595,3303710588322968062,6427176372531444748],[13645932454961129918,18142323455262253385,2863944925027297555,10020330913503834662],[18146504240669928209,11601434008300601703,7784214075260054884,2901318184559239508],[4236256440301101204,14358727301137781587,8620365567090454083,13398880468582580146],[2705660662591392823,11300560103320538337,5380123795612236504,6894139750845852021],[17666306879225852694,17819986153370674681,7082447377895533559,508816906060598348],[14452134117399130958,16057723699793028610,17043226200380126076,14713367444346716279],[14947197237220831490,1220049908890862824,17696926672665430845,29096663022144848],[12708698973753233638,11573456461250296829,11888986915739358349,10995144321951841877],[12465033209451074569,8889737597273733470,4108873554727163017,4591906862301429851],[12614190965028526896,1433231526985104969,7403404578079225471,7543970622185024684]]},"setup_query":{"leaf_elements":[11042134823990472693,3980768081924811369,715008905534824776,9554673190611830911,10487497103281658167,8461774715985823849,12482685169805737587,7779457333879505997,8720979858241338469,2242748706351969960,1849265765158465699,17393167299054476293,10512500169519117522,6490360725996191488,3007849760955995500,6870737424252721789,1335171597139082666,15905907593412356020,7555865304268609883,11111866305901493069,9924393507588988822,2149965149786669051,13906513639669958,2395794363932039661,6872092076915161255,1653723371174634156,14202985752588584070,455819697220256419,14635383313852832803,8928093217853939092,9578264427477566544,1235246319301838255,13920276163361147985,1831411664603297247,1670823343774120975,7193040619899334955,17293735973784109998,16878185703872667338,16754250902284432266,17511817001736576085,15088061301955323748,842099820608660580,17101394870879320925,1376205296668346353,16053220412451641211,11177830668201438311,12017636548131635509,17934805042680335088,134341028199874192,7152009044635102951,9941414865126084602,14698441470472552392,8038125760957429100,13599337107856798550,10382549864813848885,5462488514605947066,13064356561809425400,6936270155545237971,4127078739325561823,9385677036403792236,6751078809413993364,2650440293008356613,103860061640053876,3761760938230684,1533653662566685544,17030342120771121346,4856544654769030375,16717042907701740217,18298621171178695337,14912235491428512879,11503392652066461497,16242648390811823612,15769311994651122380,14026705955771175548,12971924947563441319,4501180071603750465,742271953734869262,7376944026670443625,6181156474953003168,5581633956058130248,16805536946997599204,16107378836967567986,562793247492918865,16258337259072733194,241973663368515793,1485472852112245388,12198250340267448518,13118818258386793210,706027355652284372,1782698336163880175,16335083672426644957,324425868913492946,17928241832991368957,17449864420129345525,2077430208844509255,4644343972778993677,7452296442178126428,5332329368653100532,2153892814277680695,6333722260131601574,13046924623560274258,14614839933377710358,10614693526388864737,1282697299667274588,10191838908130391523,9177018661507197055,14947745900227872287,14206001383182098469,12306370834447369336,12050167549818002263,2699552888692640875,16039990322271616271,18062092459195473385,3347501856402195911,4002885131521807109,453787216204568636,14722604488388945747,8529558194727511000,9189461189574449496,3709464056056700994,12606857124110571221,3380358503424465532,15220832953937379864,17100455140310548755,15450818305955409169,15568552851930040495,1852671426809967783,13795551387744347592,14044982921578885289,3594599461111396426,12157356632105864715,9788035837962550985,7532795527090556828,5807790739600748461,11051902020224899360,3296516095419358370,14450109960164896679,7257457915667309582,12695760620533652986,1929129978332653229,5314830906838348785,5356706140471667407,5478581128527639418,4373689847134478456,7708041181943423669,5006259137259330787,4040980009553472663,15993304207948724759,40036130728198340,9636342456771650968,11243232694278024595,13437880945646813862,3316474112408078516,4498650994442691114,16496644758431263495,12683540273353597399],"proof":[[6358430620111710172,4607730105480117670,6054508300517925595,8469441729879492111],[14018271382512707710,8829915214818239574,8815530623001855052,3310807411690518836],[2104985184111766908,13952507580351087930,10210412474948668024,9786422047461613027],[16244731168915063068,8694937365092201571,9993522163984881254,10458784935939628029],[3401201571758148324,1626835927954995333,11447723282795136067,7314687438927768218],[6050648570485055740,16797589443756379230,13720321119726362660,8896219002181989019],[9080878752669394670,13143802027380557613,10246026442797091187,14631608640712934708],[9294109637937582780,1544035679060230025,15807741953122179637,7708939446157043637],[4430170182683743883,8487047046741382415,4354582712566623914,10718752205286779641],[4528641792434238406,17466665929598328025,10787746704084254700,5976610105206418975],[14667922077413153203,8398201825199343865,989851745636104649,5679675276451072415],[275484188656815367,1104195928690266839,5087905654012693975,11504939407800002514],[12974417159837881482,7071024129975307192,5370817591163706060,16833811523931507244],[5329916693594924873,5667004775006046362,10827483705946340331,8627167323307225009],[14901256797741168767,17838690882237494157,3705289826457381645,9636422005091148007],[15371374387885407526,8685491745212620194,13163784829883592546,7547825941223451083],[6589670078010939968,16725824113563304687,8885655980294268245,4567844467747420596]]},"fri_queries":[{"leaf_elements":[16466578148243354294,9959276427399552479,1417603990756808576,17127911858693193470,5276647994423046972,1637834041636054343,16809969678411192591,2618453206544017270,16602342560706694681,5058276880803720485,2619512662854558385,9227062599710898249,2410020161263054791,4414282152154083270,6429234503405700001,9890453778960167019],"proof":[[16669894404332081282,17013051463213620617,10605478721362381718,5417669007197733518],[4616972231479243525,11323294745424639348,12343004252507504283,13326272981821581999],[9425176473780805977,10356231781063536611,5375899583451462912,13970466191932541148],[1984378672334534685,6613245993159861728,8488614931524125236,597341138184757603],[7700021806605026404,5799013496811164951,10125822224458126777,10606970835182701134],[9836894164101088967,18083020708882907942,3743809839694762975,5142436105451981135],[15938890513554012009,4542531613830354492,5933512078914198651,12444488924629871491],[16908790446637798655,2395098174137949885,10204233072090022604,4517986277362568196],[8147789233557950370,7430842358444141282,4789712662156791067,14027329484088489508],[32729498729269040,9606989266040962453,14949785540195314183,8270464933054355911],[1064686109343253603,2074664320246688695,17686529023249968162,6803455168627291561],[1091165913412891865,8386080094201909993,13009770338395592840,6194275185768172539],[1895521780704649777,8991823475733331878,7484748699384182252,7366833260708446792],[2021873893557404952,15786744563948742915,13683315706066140808,9697021181175829557]]},{"leaf_elements":[10054948546052299221,8935518218853586210,2058721283716273674,10544439173708640599,2885669967668928610,12522346526383477931,5284868761139109824,15334252911464680892,17660064381047091000,15107781754975039441,8721694296596018095,546689595352193117,16307280762782386457,3568885356468283147,9939926724309000449,17444978826989262150],"proof":[[15602114310113809079,6318245941557553894,1905641447198243907,3867483365068022828],[15635771062415224008,8033449456404218363,8182741178539228988,2177719182740331605],[6431277366659959050,17425147148344534819,17271148144957266015,15500203403196240108],[14503854246007755524,3565985612042551707,75266467919934493,4111000063819530771],[2443892203207524026,14829584876457012923,12445777945063973990,3409923645061186873],[16888165413084761119,17416378683918058166,9419643674103986516,4521262678749689067],[17565169724868021608,4954203120049774586,12757638693610180815,5994866984556545485],[8128905524186394718,3643943256932899279,2034780189434031016,9178669753715354352],[15758218496497248022,8865093179922133380,5752675990048382795,8343831207594861719],[10343868663674651126,8127561503514773993,5527201278790405639,17718889373263565246],[1834334951414258443,1616263108559885528,2565690566078155455,11602153308567131946]]},{"leaf_elements":[8669777577516406498,1695490716788508989,2967092161999640079,7936698658992118283,10893006534313655703,3448776749282387017,930408584052640846,12842069390201814093,16690004696233183863,10099212487698656348,10769831163938191097,7616517869281883551,6784658656073683538,9193526702078903978,10472998934084832081,11731980012794458574],"proof":[[2658070989893188516,5935040491715925744,9273520067718146304,8269372501647256345],[17708889435897883861,6583170425196902550,8311416907550617940,9621787685260339472],[3787565611203967255,15161412150754850540,11281611543870445728,6921831670488876612],[5359515228315103442,12974810781388931046,3256592436319509332,14212260080726330834],[3995132075017338247,4153215563717888847,1232953199973611028,5024076957985408000],[5679219282483392710,12511621214620647190,16867269641400942585,112191277226003564],[14266591822652003389,16622128119992855114,2733013300156663258,8791590359176234421],[3346736718718744883,13933060122817757739,10193934182905661484,13653016100923550432]]},{"leaf_elements":[8659051514553595676,5614073603402861378,6752382749781598059,9202916182942689123,5199413723472881194,17802690258561267727,3799273920931686811,3369502114892467958,7971265058561178711,11411443606100745412,16390593651802579491,16730091582017425852,7437669741598787792,9856043004443285628,5330307750097254131,11871260957135299150],"proof":[[7356908184391737794,260039539103394611,15748939441679732511,7432736073691072312],[13530243444216923997,18134359066601416291,14458730918118400701,10464402396102675892],[9898582313581563831,9709885617096418299,14927849922964276275,4974414385086258843],[5986899989542747634,7209899241095846241,7873852244144218351,12255365231712678083],[4358907288188110431,7712808693960648347,4185965397487066865,12918764144379557939]]},{"leaf_elements":[12199324850597158104,9782727375351487690,5473507619835610132,15881130542143490058,10395303409417573587,4298532577135512676,14231655167026880729,15684793290514496686,11444656957323270420,7986382268478562263,12673414891009437861,701446789790066754,10525480379987296020,4404352060219070641,16709184108221917744,1407800375821478739],"proof":[[10044257435132172528,9295391428745607650,4140727700879387792,9766810491439745597],[10681033929559715168,10548561920915882694,13557244669854761596,12042341239689273021]]},{"leaf_elements":[16371276844632437187,5763442631456442294,9612659274689155166,12661874354129793348,4727490084259142759,16024340444489255688,11060965350812909448,11778191179252601154],"proof":[]}]},{"witness_query":{"leaf_elements":[1589773684120437060,1820044577761226177,7117071666591780831,8606624462417433216,1783999379448041283,7901409204132474743,7023836858159014961,6975569141271731633,6544801542968121243,10810312157041098602,18426386275147502702,5628419943666990289,15041469385925368549,17493597355759896660,10255724231961750286,18015160468561335829,5167687332789500456,11821987075385551584,11658522053340779284,10446253816213150165,5878223853369158291,18184268614025497864,8110432708023319598,17633971435755824709,3848033883642512019,18082619214878433132,18374576314354889364,13699569739548558875,14051912074869886536,17563345384408071887,12166793578559296078,15644143028689060557,11440239529316329147,8907460914900061826,6792390454153463001,12622306847094649615,6554740229553940932,9866412057901014736,12392708547603727463,10918495519722929718,7980369958062680136,14076097075589898146,8812418280777159419,17047368044641489705,4759448510182368350,16592717842875607095,1212298789176979924,6007021798883842089,17586314523282789432,769162913601332775,4760109272349855252,4025656038184096020,8001633455689613784,733110872129423710,12795182096775140697,3867647663880219746,7570548466374452189,4094057312040952506,16577482597587134950,10393109241950463081,8136192722002553974,9090595319413389991,3958039078486924746,2735725985170449489,14028117252164986985,3927561020797864583,10569834045038917315,14482187250983723801,11443337925150310067,10250872572607390627,411014563657531046,6343342152745268074,1787799127874674167,12062087878619721970,18098055705123206139,6919714828189481038,16430208840403004362,18318320598252725977,9337406732873609063,17049140832456383262,7871679145993033135,2754737567781638380,10037402185284907032,13908041699083660080,10820576299425808074,3936847711054621955,8553701111745940683,5071884743775205276,10265931541177730576,12929914959137315913,11851914658161046727,15816050482963620376,7865856745088592225,3866147173666114636,14560311195872850554,13367502306360328837,18192613185843176308,8061302375766424445,18188615572986853751,4186537157092050310,571354768495491423,2778686945418555165,11647982923725250159,13284880534890090475,16517609887791402707,16653691370508042726,7661399235608791534,7850455189740738350,11063250374913177563,13031539651213108534,1925467488702052653,4136185419960435170,13705066779533997083,7194261541736788458,15176516589256075287,6553585962704048767,5389396364978438261,14668190101029865166,7794183430527674132,5242842367149982777,13891044196016728955,2550923062452325158,17303173127233078502,10288142908872602234,14818519578219502351,16183281307726495069,6109625005978549494,981887455862939784,8766230952999989689,2109910848426767413,6830525943886951631,3092474199461196100,8669918116022772814,165013806696530973,3733048335537793723,7933311271186038807,5925027040749686738,2949322507301932922,6677140884132725735,1997194158592856785,16806667573913541834,12308529407782263091,8434616934080677083,3386252381236447160],"proof":[[4682894385249792336,3401091496866648070,14760504847275765135,5121162156925667301],[13657108005007133965,10019060718969912002,5833080005575213135,10362340583428410145],[1543409561185834623,12686820324042951194,4616118256519933478,1638432881093866521],[7403759814344640986,10918133089097324786,9788243263307013936,15594723584135666637],[1757142648863172007,245924197722150969,6914728797847783675,10616600760604205904],[9383812165168045085,1605093387888942781,5778936336991297323,10624637704759380071],[11520132554432694180,16728226825174048304,11683588452335379422,17682373151088559591],[5848275570765951005,14860382736255988013,17139757533336588148,15597383452811308073],[11476665468575211718,10047001730296146072,17872284831937968878,7795958168733949931],[13487752007161763914,6257184033889234754,9808380206301196899,378065195805476880],[14415768237578192673,15278438156548473148,1234353474331312932,11956790177288139745],[16943833492897282820,11026735900030683718,15612801109070413578,13221738198923144043],[15797261961855665479,18419733200791378565,14893072305620294556,11861525192172366935],[869562166817833727,6750439612033308469,13915621429654110358,16069848433767030447],[17399315722107599347,9975763854577449947,18206249874266513158,8851869651638131737],[13956091290665605269,7893671946068161603,17280842991379820366,14844174942388040798],[446318376307115417,3375364935197782891,1913390476604132002,14742194311215528796]]},"stage_2_query":{"leaf_elements":[13329840537248055267,3754996178091362885,10599986930106483701,6027911412727618706,5496841886098089896,14145011904837591741,10993960292488082169,6041205246024642228,15358847700349124941,15072983068730465951,6254256705694982272,12497468480048738128,43333919746268548,8577193086127698733,7505002982299693642,7481755715383471483,6343201584682849318,998649954034946679,8388534815973621378,3893321365729397062,830379794576940661,9020212447807339084,12536746593149553496,5767112358348254473,9621073513548755127,1153023383864887568,8026806182764970794,17511216933278504733,1647891554343429305,5094475140264985669,10490059814941590,8390981446940949612,15317381415408388080,14920991262666644530,12128045218504295724,4330813531738012720,5918513508690713495,12323166975281347422,13755178027330638866,10242811675002481536,9474255489204770632,12448038060792580027,211220652404640042,12792864810130923467,8971617559502411511,3599469637759740886],"proof":[[14254316573887027774,7497681100787055962,6730007371273862580,11253925156338792515],[5803965017287154265,9422542504866257875,10357562669806572490,6150017827020917413],[10923444658747336444,10190270851780460704,17811655858782453983,11967235441252674022],[9824382440882085834,10643239906589238613,2147976818586638486,13983689874075701296],[3961220190184564756,1996316155684671205,1342697116677266479,9975307525411565390],[222706007513883366,4250510925181524656,2104741661755811245,8208802951197154726],[9153768655188133567,1985344737241569636,17724688837841544245,7182892420130565779],[2737572313546700734,14908956316124648142,14534033091266540605,9893669137265878635],[15206009852625297828,4565164879433909176,17540354696176501353,13078893512845353342],[14052065646754409239,2969317304569307997,12149473549709150488,8552898515100037956],[17418995621560659911,12897689351628987581,6975472149034263409,7807394114431780202],[1029691582593165560,17017044503352497595,14206939374883131718,7300648322191711566],[11722106174857687153,10361119607130041510,4907172358500934855,9988838965366578867],[14052966467386858443,11425255595548855161,14934395077750463412,17479362390152699594],[7213591029217635396,11273666069304860178,2440722841686736503,6840017750781558337],[15351827245894792358,9295638853386574934,1602616796632692872,13047387633705632052],[1283005982263822647,5576217357074790266,4838152385037052151,3671493702847934836]]},"quotient_query":{"leaf_elements":[2062851562522694347,14129102164648849645,13495225321717216645,11026566027418980669,8868540016999323970,1175435636771117688,12657033963294342103,17764807616844843,14902708568073857675,3977651584399232770,4261980878550701712,17696547365052662393,4267910816545786061,3200234289208154173,15692983625950153583,11167187501846455792],"proof":[[15449911486372010178,15644936028631367597,8728719922361973864,16592328522869247426],[4172746345822531433,3039057485567472758,6767765597182891248,7966473383811409318],[12416872271019958688,9034690581986988994,15825677226679261021,4331044669691205236],[14774062981113527469,7401281678228981718,4182425034084173081,10420197098055606834],[8003494892564471738,17275484906493260347,8910756432929875159,2600675326533813128],[4576360596395326337,14548742775918042366,10976566299057059294,12887411392692389952],[9636208965981946768,7158180466123978008,14885644285004707387,13324008179729460639],[6963048673308538606,7115383421579446235,9920738674811188959,2415898900337526936],[12327085230103572409,902177304719047954,5381835671249032123,14216805795518021294],[9387165997217312541,6047599643810929953,2505409282427153542,10011253495154419089],[12827822166640566348,9999882584608664786,17992656498297771381,9881161557461236195],[5806814168233794596,6711780473104277013,15351945908228390110,5005645660591158355],[15066008337994614300,2644828517157788327,14040955393908674193,3722254758517225694],[5537033682917984415,8273816598235921735,1177787098648190802,2536047258685688281],[2517254183832167733,18189810458877796117,7350733677052505173,17241227777780402038],[12383435537749213360,7913388594304678688,7500054166861163716,17121339375120288845],[2756204060012982104,11181890352814265502,17993618182006171151,16194213402389489504]]},"setup_query":{"leaf_elements":[14584845952365961840,3913139405356707070,7968023956898946531,1438009193416054851,5167814021493700725,16699220129357136060,1644068896365924207,13261331250885194038,129279959054131621,9417667867728562292,731742068034825220,4781196999734585537,12414203741202186855,7262860088210210702,11298143057978128118,12097619358329230090,705787971975612549,10279092558584045218,2441858385601244643,11105017816136758734,5604546860531698880,2854876162308966304,10390661721216220229,3098606440396267945,1287691560353035030,5792356047817227977,847060865574904971,9637434937978824075,14339273604000422079,7507886090905371942,12427886113777142401,6993811503656173005,3141817098938975303,7515036206589224372,8202771044908081168,7583059261795691924,10187743642770300368,441815292034484952,4574439969533340750,5841531281725097081,7079433128408240388,14948742449246108341,2289119612288931960,18094472925812896712,11152805722643268025,11980929341077433053,11795745588316394840,13502494538257083928,14482097803423963191,11334515625753008714,9211913969167246238,15976473550917716205,17149691694692010898,699504569806068787,18217513233795295364,13195695694309881700,16207949449277754985,12700714097608177308,16051305160318468483,358478341069352886,2766865516515028055,16422743051809038711,6636513233899580806,12988054621622156103,5225888428652805342,12701410197735432896,9233811141468513501,2740166866799732896,9058306528992107688,12429816951547883183,2509121329105162515,9595023231160680015,10349236453673636601,17177987327074293369,3509505851130917948,3202489066111923196,5770564274506599463,2732122133816749382,7272701101086234794,10923788260642756441,3138536691003455822,14996295531153798116,7203706627047415990,5877482061644321398,13706969499740005293,16803742262569401519,1922241047538941570,5236924942287509286,14095718826178226281,10034551800018104351,5638180355735312765,3709330219041625381,6250246573880706319,17254330016650458552,1881363643490893335,7773782776790138254,17785192827404378738,4731440812577593045,9364406915544580012,14453828427124086549,7626703130065278393,8592112345493410909,14289220635114951263,16680586273025042197,7724816641095824615,7161948477271105170,11842769034737837156,8496171295582170194,4416563478132282198,12045218737058513075,13349101734584356567,4501135452611171429,6859263294111429247,2705453494251378781,1435646728249746325,14922449533929217362,4467697328081899624,621006239106000559,12585892715600816207,5628057968273096287,3256830947731922635,5586374693162399882,16047604041579538183,6188575155915010124,3343112001078629846,12159229158630440614,365375576583620824,9490304693505960647,17539077819963828431,1686342806243239377,8402237930084082072,6324017984986446878,4754968002801182382,7702451371019251966,3075220706274965758,11616668481412876496,14628407242208143979,18042118344557567517,6049858242106410998,5699837410549544268,18226833037969557614,1516908304526514389,16160484158871156001,6235047301937087082,9390579075946384484,273586994028971912,8407152025631134880,15620224732601043072,5138597641059823642,242937505761073161,5235914103510889092,16660303973301302789,17840049607252391615,7517563942418134329,10969797982891961964,16233760269466792991],"proof":[[6880694784915467320,2672052984207493273,6025374397733045036,14500716121822563886],[13232287336763573031,17127456888099004278,2972493591651511508,5853408361623976964],[9542930228402073911,5952967327688963287,10670606336004788062,8372854773940438486],[16579856516987421253,4776881456747262116,18323733261274334858,5560068955272256468],[13805955484691757468,15309141685833798861,9381549768613733686,17268314162056274608],[6239975387740357753,2611425150401439146,3355773339413067223,5160193881347925660],[7730653318759084636,6009427997699366774,2241804087360119519,11835784021141563395],[739357361994505335,10770314297773851026,13061386249338211894,3642301014680032662],[72578635986731443,6440283774611444227,4694338515370194790,14692620235755801722],[14635085583809466143,2962382283780323750,16003904612789912075,1916200478478391970],[2272871818006334816,463078427234426686,5410864414052933352,15641402682277305278],[3719219034861163795,17640329975317406028,13118509565377634110,6132920078473306138],[8167487927923742794,1190555549016775463,1457169123257951481,3371167701461113393],[12707349254868250716,17192249626583540578,10297575062334643323,15274346379212809897],[11464192866181959546,16507321561919748636,12292824181903010950,4854829283203017429],[6552520117544810486,16587019088306324507,6380014223602582641,16116898179121020620],[119942016992425815,7641812824221345957,717302696007773285,8607632033190912232]]},"fri_queries":[{"leaf_elements":[10058368115688764314,5201034360465840299,13195622420275887571,2457008448355130592,10241216610567670592,16703733028560836113,9434594471682658906,4923193186379569189,4574512962053676967,9123397706286621951,6162008747930881376,4648978151128310438,2654247839368472442,15500192004589446459,6578325428699412379,18110131666638535415],"proof":[[16594956475808289129,3239267313951339326,5285778273470971576,14007442975736028554],[13885439443653565321,7515123264394720912,12252769846154363424,2205551973967756145],[14154213399207812658,1549691022692904280,12039167468181727504,9409559670560382422],[8860723863790505536,12487986826288960455,7088591903586718737,1466432882977549537],[17912976620384025327,7469410729025863347,3599487608167775638,14023015417750309864],[10912102105054676230,12952318564073091109,4046529170359211442,3368236844237669891],[11466126321000594773,4511036643921548922,12340500254175269410,9025651076895922955],[10279628564117445935,7250846243583386246,15521861249770533465,5610998244670926111],[16342611461833903434,12397819488075276039,9629510609503985963,14838460272987688494],[3696083825128641553,5711510420357342722,8535525401240600523,11986441831519947422],[17339955107256989097,1641019884911129666,841565240646883791,8922187284743974510],[10964313202421950351,5630947744251068434,7004972551600042285,10845042182834146527],[9828755776288769143,13986765444697018228,17216114589747554748,11737062743669164398],[9497522330654010607,10428746838159854411,17282797116643625741,9370446250429457167]]},{"leaf_elements":[7394650273904820989,8452199664718520686,9726698789055284068,4173543720448891322,68907756338401939,10326182076130664722,15611682453593620307,502162814496181521,17848246661469458293,11500994125738466994,686017391140560705,2244416871758507471,17980696935542617350,4783829264311205651,9332172568767951767,8394134073231989966],"proof":[[4117494593831555657,6350268119131905233,17452018092010900845,8306794255902520428],[14829816884199545210,13973694264297150609,16114143540289256202,2428714871356093632],[6287719632222679812,9563518758299822449,10343484755668179773,17186025119844700920],[11697291366636369133,3519005606273353735,10129182409176022973,5567850833026539472],[4573699643718962665,3728976661826459822,5651872064247170598,9543359601784515521],[1120445619456161197,5010923179301656771,2391576663220982626,12191036373167424913],[17099410842129256970,4716779524218783122,1953186427108680809,14908685986728932924],[14776554399792262843,137313972572654050,730836889369817572,10798294068820836149],[14572539141946693120,932423997073474659,2314406510198147272,6370293398431955989],[10995142404837032615,18037828248629944783,3621605584051744,18272512998774485959],[843411343929838404,8361740330644747194,2332379768699751226,10226462084284657766]]},{"leaf_elements":[1597406260740562926,11372056233836328717,7709241059014631717,3514502540782981008,14386904535564589295,2299211519590690171,8814969884889156432,9151817630044389533,11628673505546202398,1149156151642501055,11410352390757230519,15176509502900888788,4458453727624330495,17117932303974578425,12241230450396972625,15622810343796489367],"proof":[[16130219931576754565,1922353363694864467,7130677183091801328,3399025259369647662],[17736926761604892623,18204009291078614788,16898271007819319962,8235820017835188373],[16949352652207010466,3667000804394517340,9382830122611892006,8027926170396289993],[8368196205213842900,11253301038588197728,14861811582229950463,14557996189241895328],[599767199512435036,1967984730182154248,11785011876590664411,4327671152219501889],[5667355671482229712,4260810179119353854,3301767374709718245,14970505800725926762],[6093544420987595980,9570713105163657521,16834300732272845917,4954962326226044419],[9196460362043655518,11124783458111663969,6628625323182741542,8138792676882935518]]},{"leaf_elements":[11734811684791492892,11496421411149008491,8545204023403909401,14283519692455568894,15915690833890621488,8919422023793882510,17322128581506759303,1142484619860086402,12707333476999047496,14645961321398790185,7459501646435206382,7820066391643854281,11643082740495809985,6935983510048108998,7796963605095913976,6765377049253903565],"proof":[[16058233757224156043,17682433058570192546,16543820826271662626,10080578562730959404],[13906769319968368818,9787540702194157681,13558457436249390342,12843237014538744532],[1886952331324614014,18408455444181824419,16919638281214785380,18298698280380929486],[6748302237752748816,11050683019842041066,10744285173980642168,2830567593414132163],[4195745188892480400,1278917477926341115,858660738527305749,12026569133742582051]]},{"leaf_elements":[17243346552149652517,10882619986357177751,8096803201503556482,5222497194179763350,1473082545781564758,18086100824368415238,12291573177398886098,1525169808899722843,10361841926233051838,11515798859454192158,13069490598638279614,13771904632740530077,6153907696260295489,6369593925792411855,5785431625204876738,15730679172607800300],"proof":[[16997450673583468054,2529071262208839696,7011471064570615138,7786772006240297790],[16070927894096146171,7499309042979267285,15222708687563261277,7377423658769375210]]},{"leaf_elements":[8872244034292046542,14961388654118324654,5802056968775514489,18302383666416428067,3933647026650259001,8825851261617385151,8616213839298888053,10450361630528634353],"proof":[]}]},{"witness_query":{"leaf_elements":[12861189716531826768,7017071353671343551,15183266194256937296,16579316048538211270,807728281606480250,1873164319221781308,18337307709491746274,2774257794288188910,2569998884848670755,9325674236195862755,1483854871440268640,3079542310674567986,2274860457836079689,6798778631653450451,11714915053226982854,5875195366266521360,5116106652038598680,11055610663875210712,11924601951813531096,11076242536246180408,10696047795522077531,14494893653927805674,9188960910912644726,14977839782194761865,18287054251678864030,13965398790148474910,16906859222867306511,15102514747958632269,15082492446115712802,17749549288860761611,17875795529502065790,13649994843538329721,6078669221873140970,13296169096556984290,13421881354778653970,7276050373683246212,1757997390797758920,9143965897854463820,15891921316895199703,6608049809117961090,5850826528829964870,5722382984292584234,162765357742027118,13760693824492174380,9284195688341283497,4496300212846893080,3585297494624753974,3252557677785845435,14935607043338714845,8135292113850418638,9629542657247998692,933892281627492292,15914943071861863721,9207603375718617931,15638237583855315381,17577718624080272910,14598657742303698230,1651114015216895227,7583961910384354034,6648172982237054789,8118145978741984858,12850437812763271209,11880172222513495241,507303084718041940,17142724460883802603,5390331062144146550,16094026964568347745,15611489544999735562,17266593892105422493,17625200029846773577,17650579035195934306,10664137723569322537,2473803099457924370,17468787981380229310,16844413202384807357,12012915881809714215,1677758069384046326,17084039083235733685,4747669036405435021,2569113354695279307,9291430697451311210,15012392467551737130,1822752170168607805,17361208454617831470,11737747930138122206,3066649156000856503,3203649856496377523,2385376236498189467,11168469338481062474,10830687617191373899,3118622201505699050,15359191379941711910,15871571818458880600,11848918034902252613,18131271790460542684,6116896383406159974,4893560957542523305,16199005211925613503,17339376474458607256,15261283338500043859,16483434311866273705,1384095066133952566,13692798507375081210,6259772980000091370,1947408551003840906,17009452913649414125,13141552795074067800,16333461962488770189,17210315424496825722,2943329567433862924,15132057061788589393,14283427256972562350,10586904005111189611,8399022267388182238,1947895601794917965,7158701272173484727,11607902459899578394,16474479998143888386,2359320804386496372,16600578773420334297,3496758018278090579,18263415241883805579,11824958925764454458,14369725674197523009,17847599378973892748,16049383286096569954,14138266648303066129,2125801334016253589,17037755656051544972,8020550029877135257,1240223013541041818,5513017540984328435,1268564300079144892,11496668076083516906,4213147866344667893,17956526993063587636,7405217063701125522,8007808081708647822,11124592590858037805,12722809709822305384,5017593793487492258,8419034557272602586,4465417300642727889,9847340594191345383],"proof":[[13440666466521455081,11080219490416462737,385737599801313048,15174662176721078708],[9922237377286965226,13490191191562308311,14888732615851136612,15772587860754291275],[16243638339337019877,3785031732096796204,16152041457522938751,4876508551553297405],[14842894735197673591,12196576431610462358,12177198786758935129,2127654866462624696],[16285361814592511501,9306782451980532944,16693518350886020321,17542498043676186204],[2684817524473829275,4000431149458605026,4062355375879423277,15136353234888588760],[4534895530718643112,10469056015777582011,6188445963502541135,1007603929820043380],[13944869903902352014,10364824502431680470,10560118347285288976,16976707835161075193],[7907273406846010871,6213338062030589908,6863626792938596630,9411709795606821143],[11273110877965312168,5880131875710444642,12902910128891560728,4666176543880769345],[1333530583756526800,7668102851111953432,13083171916504122089,7266861241415173466],[16589584468516352274,6268876542438165419,6538050334215000895,14979595140988394037],[10836237883108837931,16410191064433558764,10550410945322270108,5678950086586461912],[3283636597972222288,7288474524168050271,16024548925130376568,3352233630372491665],[3491042110256019772,1161971018629106266,8281119082522022064,4862276033296485552],[2945863120708241171,8159151197294358715,11089913621284039627,16546757420143232732],[1860896835063429843,1652403080417522212,2261129679748469386,13254769866375557538]]},"stage_2_query":{"leaf_elements":[5924293082273757184,1515081069315758013,5712803422553544816,9878140712149101538,4721623112183936438,7670850865628293806,18355012632319459110,31044951602424079,15836512884758577221,12055247298712030812,15803271584513875422,12731619478454336805,6296794389221890072,12806143822968509708,1346646720899695274,335391853676189756,15547180698880093134,1894523276867378291,18311576309608423098,46220846664302938,18086497405449462802,17325698732363543491,7147329963126407269,16364576136279626580,13474618635433967806,9619993012506767935,4325815604298320681,15699364837995947548,456013362426791920,14338377905254860153,2430932815259161384,6314500683573957359,11327195521036593697,9901392985167845777,13127831841462096996,12318181892973664568,12111928801687068958,13781492001346552351,2607781023590755832,15999409951354580510,14836334276866353501,8044578937798353752,14322635126916517534,2673592812213365322,16715375367328134170,4349751325705896973],"proof":[[13089280072355169668,4855403532737128793,10212867733809797230,14023459732371418031],[11146230407303056266,18410548976781024301,3365557948434098660,12260205943256175383],[7897903002975350304,6418890383145880905,17393115373268765882,14132111544197247749],[16741283669249076090,12971911730648073253,46594058272498584,14922934569778814674],[6744179285418405542,6943189200170347029,9377242293829887205,8503046905402812093],[3864218648843374301,16334052125891292159,169073843813800457,141958251861087191],[14666563810620324194,12497088874243226351,18053395482954580711,10277449653281005931],[1311038967923843890,6093054747328082482,4913852388775291710,6348855788000405107],[4143860812137532070,2286434847674009020,5301564064244848944,16390143297626824561],[15883648205881842144,8550850296915141714,3708217365825742566,5018937413866941329],[11828578745677873025,17230234555465175745,4745826467197250004,2566369350947608950],[3586730840961007465,18261721612640701061,5266975955842474210,14673740905772250517],[16941197672819495788,4721265264652584660,10863697158704235885,12311401325677877088],[14550953470705599752,2112269725922430213,16643291326338337817,5260652324281093432],[15258258073458333284,10672206657780689266,17415983125950091192,8063373172354891960],[15306544927634013289,2794978091120379871,3796300467670037656,12741519776787740542],[1323240375839521967,18311725375579224908,3996149533677948373,10325837003394018898]]},"quotient_query":{"leaf_elements":[8753147492349431905,13413331007776290176,7262786660125297330,9266222972801806058,13140007002369568634,1185949395549703312,13694417710698133664,7350027906468004952,2780298456678608038,14438864441007804249,8764871681279440674,7689263187069949446,1582777059225482552,740651500953762063,1167520838997236094,3409907439831030307],"proof":[[16928672214325798507,13423800059238396504,16216720709686375975,7141953843927259025],[15318374747111388861,18165902757942012072,13169242641124997822,14949125493446160237],[17730216590191098957,3177024258620721448,8530934671146140440,7152015745440584931],[10469116969065605019,11188619753182290138,9253187186091299107,7778517757495261247],[9267516773624100278,8663412944883177085,17479333241000898118,18221292939762693941],[11379287967144226729,10492618190660660003,12393137950713486000,18287051665351110864],[14395845065355599948,12170112258295937921,5794429731813316134,7786813184855422645],[6130192780775377837,16941729626782772807,13582434095934725819,15779512881385871595],[13772756172974754918,17350209255119799039,11517895506046700576,169344295175490718],[14528502837024301550,16666998953176897246,1241435351053741762,4775047752375266432],[6334437140444922329,10392231504870984459,3731963203168608801,16929983155392727236],[6859416017158657003,7357541102580321081,13750752214251437448,4241657287929316975],[17243374584032864898,15037430164978664525,14103465616053177700,1991224089639920828],[9133562286421519063,11001832078613525512,6439656094287682047,12286418393063777611],[13790484360128987984,10436487963915467307,8412047174155606715,4339586144243861652],[7934424558305572021,10873720953167864,5363924606283357776,7247229629047154687],[16275865454186967714,8029517013225501122,10889177156594922072,17199111512595852426]]},"setup_query":{"leaf_elements":[8042061925186496296,388938718033208889,9617631191757294178,6943799571597184516,13935937870842736135,12574431918830421079,8728930241714514305,9215668919926400691,17366736574810883728,12933494324736480335,17668546761002262998,16568011919900360645,8924235909553386913,6226115156505265931,8292895325964189995,194469094424016486,13950519956597854799,5488695731978024501,2499758420402968978,7458822069613260615,14187742454860480551,3399895066564669667,7971823099235156252,6881498489954703362,15112322401537378300,14067752715747632546,13532554236958688719,7742023426367279271,13349033864093810340,14942357675219503962,11478508361559682568,3488944832869125692,631260953859651825,3456721552574407072,18100066950076422682,13051924929276623543,7395118029970435897,12255277054953387212,10493184687895295707,10988973605976072257,3383901312231933873,5244410504090292534,16394675158245416460,1761358448542820043,4022047896065572387,15826211118702075044,10219275397715862160,8482320365000458590,11678126302493837836,6117521991480431734,13213893139485004685,7533450873150013596,16217047882218983046,9508366278347144333,7709289760856416007,3915064089560162093,9809211137208621290,10728004868679355592,8369522496039476517,11803075056822186438,3207324578434470160,11046354229258249086,12185309150431089546,13317562760180279088,16548045645316209718,15278149090116123642,14931862760069480136,10760707380618245246,2028935745357569895,12092236498993057616,15950614518310057258,10041225958667872417,16481577503914229569,6799777143872956822,13606988775167370387,9090075637495062381,12424920646799738179,674901378136444535,4926976174482721838,1243153302405341732,2547396449425191647,5754227484739206507,8667254635250834933,6651290623672940564,1332455468666201440,13051663039477096221,12801849910485726562,17047848487445410409,6510326146427560457,11169529177495754830,15818422364089224369,1939121021228692739,9167403525315103427,3554474424063673381,7127896462479129943,13895141911916498179,6035291429083748773,2980547876557687483,4162087067200470432,9596196871986770131,16426802195169625732,557699134284866229,10181890825383000065,3347633555734284407,13048137347562222490,13877030157352242492,14066465593811014867,7307711508901568883,2479477193859085383,6051501969518994967,17713796898200789275,7145433214375205581,10738541751515339299,16229166229089290269,5117703668711125385,618411539187562056,3832349568883385469,3937651505286674320,5046907670496180577,10097318327255731353,129912830360031579,11375564970614971493,1025604196523368791,3690533423759121456,5620343353138824433,10820775643805639935,5523636376542389342,5130133656488775952,14681224854901761758,8638618961777407842,6782874555456204086,3687638291703477776,392598997428519011,6937671855597121127,2793691964835350602,11506155141871843948,9326221402804775248,13126976151139013155,18205269140927759842,11253708839082652221,8380381148983187936,5034097716507676742,15995730040327044373,18043656652695439786,10356398493023746632,14903201926836538098,5453622729933244239,8838345496524614108,11645060865250591068,11662755071378786078,12795154470723520493,14308183644767415187,17185146485778578332,3660297208338097040,4985810248560024286,14767729359436037418],"proof":[[9618301208438163189,9352568473042154652,14612879758398610718,15269215155830146917],[5719241661403964226,14563921125217464323,3756452467503184865,12971402697159961489],[9281133100558808425,4369697507958304918,6318818199828006375,158136342803322985],[8550806604790333191,2039414440648331524,538631256554274137,3584376703059685715],[4479040218245103980,13310730838575824704,3294584275810271979,16540491485559801880],[8513623262262169718,16412257752422316213,4850380163756209417,14576413530812423283],[14634430538798740868,7370234689949917980,16907539290198894066,4031545076022906426],[16435131756665374998,11423648361484065653,9058072036430995473,17345495448564363112],[4351484154888731423,7287051023889977128,2524224489791824888,8646770336435562329],[13544144357807708045,13752902268425736506,8423514026310272563,16222435034655313015],[12030177539155590166,3828109147472839898,1005142376351783369,11059322694234128862],[10096192567569986060,14257864909892221679,9657227244010067265,6682246082715098967],[3638511898085420839,3179248175659244316,6966358445046006558,16996260168411663505],[14443555148601692528,9640016152684889053,3368972803826341179,12755398397911894359],[8043777399769696325,17183778562638322950,10955985433162856519,7059132494937717124],[5577749902235936610,2508071626695287737,7946159595134479104,11003049146131669942],[5614327065933285653,3328995280875371920,12239808749654718222,7079628069834605315]]},"fri_queries":[{"leaf_elements":[15895823289411683321,6730350629733207617,18097825053425536484,16358448228681473825,10303071479173709558,1802774262925512241,13262966590407409961,16752444094851299851,10964169009487793282,15158626343670932087,14272985295877747048,4942360827787187188,10676203262565450775,8470661647372723471,3082684048405914398,527104532958437823],"proof":[[1617304215631078617,2479682279045285503,14644492308795359157,15288490920203606762],[13182997589674622013,1017153469387530912,6154952424088911205,3820701497676453128],[13507323733688080188,1393486423775015368,7317406083561222659,10862402317432803487],[3865608958227933644,17605489043572566114,13535278550575559120,432463526794024843],[3388696122865453691,8176024953272934818,16141145785228704338,252674363311382803],[6384695365606721719,15438625288966793745,8804482663875593117,7985614098935853429],[1015061048294037607,8141493865360884381,18069592433667333031,2119344254534796290],[11513933261132035489,16210114377387526505,15675366440523174189,10380123251160857401],[115096535975879814,10021121502156721636,4791744537289813527,15480263810929920805],[9541764299127653241,13493621633396557893,14884626649963930185,3309875209469843341],[2387324608500645006,4140793481154030295,595790944404911408,12403919511392011557],[13436962952931688363,313578304777135673,12943383523096528212,7788496274352859422],[11286457568846676776,5013727499813089893,11504919871425148630,15623363243145632533],[17617671789936036600,4392943681491727174,15270466481397815535,18102028030276323478]]},{"leaf_elements":[1854344904873172954,5234075663632995179,5619384126273649917,12306901520403231867,1296639678142252362,16228881975562402373,283041020160146034,597014917787220769,4815032098454692012,6148155100063970319,7974325007880366320,11440821587156157317,6042825588737739553,801818939156045173,18151396045982941827,9273872289174744860],"proof":[[4682620429629747727,14056657451937174159,10403648851493539366,9070384578802791826],[11904767591562993407,11084255618434723871,7775468186153036496,15593199918901338718],[3745044934324490894,5513765923890562916,14515336352103709881,14998981248114150693],[14573043313129570256,9967326734904663030,4963847880326906001,16705504662573308584],[1357201077420550615,10618244789959362406,13794832300928482477,11295982473491392977],[4952201594596290153,2584739518918917675,13711676516857419771,5040697615545382964],[4878924620659130842,899552634420909709,8508914978536999170,15704410465215346659],[11871385939122677794,13367586360632717409,7864762835787563830,15553462167501423839],[15526104121499366199,2646838561013226410,2040208358482844691,17739700510970552755],[2344129626308277772,13326602000778477657,14561961681591881594,1659854109029037560],[5204416224914363540,7631047996102225273,12862164145984685228,13063266225627597449]]},{"leaf_elements":[4750274927643032969,11211931533161976771,14696959313455672971,2511929737985426032,13086560156915498835,17242784249951003304,14383128823525561593,9567737379489935425,15109340924953463544,11835190212259807265,12904122830735311565,14023067632376028570,16505759782271383818,4790794610465800260,9379522940792463105,17587473928555370326],"proof":[[15016370893361915631,3027283329830653463,18094762838633196881,18193936706763481660],[5746536455212631108,4064360456676868750,10290240706842394399,15569437643125202924],[8433527206197023310,982241698426970742,1168908345227608910,5209849369047975304],[8962437811712365808,15135915785702352978,9421406246708114780,5248145797083067172],[7026166053187864812,5378731199789079497,4657954624022317014,4430342519422396195],[5159804935821369984,13994200553260237109,9445835667234478224,14066561529742879119],[11576929916273111458,7010067740305565866,13591390134299720398,13448355386671437584],[1770868264315023480,7812579801998129002,524698746031729832,10714744940176785641]]},{"leaf_elements":[1981873168355696839,10071469924429387742,3243358467018858758,9423856983682387373,12136610342874607839,18320842015638575116,9552894453304109524,12782153175948824335,1200921814067761851,12547995606491641057,13726229927039070014,620550873979188277,9133324122770055244,2026500123778881675,18389756386844305263,4018533361310258238],"proof":[[755263300796871198,8869469359583206924,17868635431207288441,16213111950745689054],[10564411463071116620,12115268395853191647,5951460800004337870,15539274182663975177],[4265438436947304753,14342861525172112993,17967674316163775908,6834470526382201714],[11305800191859317577,3493003457645852143,14744895160582527818,294976057195894225],[2352908338701448330,7592253344295024086,1427121771405932881,4783686535469269471]]},{"leaf_elements":[16070831778730322167,17146922037619272738,4121320938849791840,5818432618082194181,1370020225682757378,5144995496371304514,14040903937101183461,1775940530187431237,5178406466832460837,6764289863066862362,16700697179272300234,1701592600056653324,7605391755963925717,9462490642760313982,18040264532904337779,7581728628523268145],"proof":[[4187436726221841529,1184190036992878583,7683626526765293269,6799112461399047134],[5266687653515500013,4022039819281218887,498832073896150918,3983130288007996505]]},{"leaf_elements":[11907939937929050222,12199976274714464765,3239066403731203959,17951336118807113373,16307121117972480027,16234899209723555345,8364706858358154655,7274458572308793086],"proof":[]}]},{"witness_query":{"leaf_elements":[1390571429705569600,2840202995562761014,1882534098315954830,9036001223205917830,11368590675395915737,6479878483946851902,2182375361819758477,2654427251257906632,4899867846092012228,11347196166340884994,10894086170523868926,2980273052781849643,15965445244805296163,2157518914993514550,15399983247123052672,5675664336850031905,820052080482648482,4052911931733917934,16161753499490148151,10299158736720422778,17260101095674110364,13675968549174268178,12653191312165970799,16683821645988188478,3936074270808658220,4707855817710923454,8994106827039346606,5448112593290803356,6292371497232357627,599272034610788817,8275825785598772524,13240554064395585792,4572961187039522105,16698101303874722099,6306148967467267427,778487658026762087,7656091002428337650,14693192823064338202,4284196362764606288,2091872672252577699,5727099310866943690,10403346208775876953,10613175021457959477,5716331315056059131,2600891424587110996,7195412803444935252,13926658956916459850,1067365522350067903,2333874482265593062,9084657685801581554,13109593318295705248,2776087568994079182,6452970042874564632,12933080848799437833,5632385107202719372,3656627910487937086,7210420240778346652,14163707713930917858,3809504037346582914,14354531236463782025,7740405969826373526,12268937029092456045,16079187669836605487,4376933324760268005,14450777757802701969,14370997396907136790,3243079645697934734,15211221769651480660,15247461050693998044,10982193680072687468,18071976827843986688,9777792063111928311,3727272552542146554,10058420644580483001,645270635979111845,9405228061523249559,5088157764399620118,5511368191525324869,11213948111533549432,7166212958100513492,15487178926369761671,1023908479016226121,16836256560499722838,6086892746645890353,14145638448427390307,18084352045432784262,13030934362030875117,15170680012775227463,2537833745427468534,13905958697951988513,10225804896390204082,5628122339788725923,13274696525758824181,14151181690618875154,14142584284849541466,18300437798036822935,7498515648670324665,5805683118109288950,14682603511669963856,928423338925785580,8153607257448460598,1047439268907411670,3783310065190809074,3543537522692982338,14439870757642270305,2250228027795706705,16894809841490684899,9916525474421379392,14487873306899725278,11023331158915786076,3336919633796703446,6987278770033615861,12725495618963729610,3259226140253463532,12517852479020433302,17426013599298648371,8620124438826325500,9776025087785077036,4684445058485739991,560160745072642711,2941074163463241773,13857374589190311579,15930662264485623828,17276566008928167654,7781818339919685621,12368578341189437359,14309601057976707352,713278498726735823,18403534909953205795,12741852590724288786,3037149275674702878,14456931189052656298,18210394812725591808,18130367970928708627,11055794745249243376,1802988082435479278,16852883122181118127,14830373821465328790,5993047924137263636,4391663307865870217,4631459160247161564,3155540228905002421,13151801327596978934,3618379039852136841],"proof":[[3326307541661263725,3481446593890282749,8008551394576795403,7257004741735272500],[7186431374277295928,9815099401387589480,8579981639790441706,4314234460339909937],[10657484871088304017,16040133664109745046,5031369337552347164,9365824240067723824],[11142516678625191715,13596752265473085697,14592996817306231263,4720325382142245145],[16265652637448542137,16009230060387244525,9968900353680065180,7288022095860503373],[8587411964943994313,3549803723255143799,3623085440585777779,7190360542705230394],[4064054604251692700,1826297950120013413,3824299762731485807,8860825302588330273],[1901105089995285788,12258872519885521232,1704763452271351264,18364873986927052885],[17097810010985893823,10239896738180002160,2194404823822540781,4412594867111324563],[17243170565471588877,15261698926618591264,13272677143545176282,7927817038181823539],[94136317843747034,2889483824117055291,1019937781014277058,3949258012931301511],[2618783267483195016,13499014778298917189,10489320130393222408,14218864167717052105],[17561038544529199124,2375014493858914118,15602883410529025592,3663244971967955137],[9714531483145365960,16894183649244534607,816882588231631249,14160951003713058087],[13574424545670813282,16246266465723571960,980516060382199145,12088861962205845310],[15274373577981662228,15605721384725955519,14137137246038505395,16386547822368355859],[17879821579325065783,6649443265734486208,9491814198976533687,11159383410032190617]]},"stage_2_query":{"leaf_elements":[4160259188075725369,12877160604481548462,7393468444655928041,13435808526721693213,4775272054421589801,10567557544776296954,15373192705227298867,8734966673373996561,5705343671145054961,8174850405170231834,2763137037933313364,13496033484754734611,3061178438461166350,8524273190095976182,9802491296434088947,18099243316085650325,13117781143788276219,5620101521597043593,5975508469375711428,3011940430461360436,9716351885926944009,2589921670573971615,13804968143746539084,15497914372425128690,18311636932928429788,8691115048452402202,8680085995287937212,9264560517739958262,3874026783293737098,3506292341091633236,13922112883963777395,8147414938704800917,5072428847925812557,13348327565458204298,4763949158849617872,2712499796229047397,1265121274850126783,11962661924231059114,11421699942236596429,13222704486210817252,17613294116096578079,16336914175517885196,576834157509663068,14349306017024458000,2607859303693056388,14810043313089493288],"proof":[[16866689924438041637,10573721141705834638,15964870942190490773,2553299212615628272],[3974185759456342200,6356975666746878131,4379333660673378364,8622991476352468482],[10821122892819174200,13912720124640616625,11424498819591947048,3001993094864631868],[16580765983770295430,8737967645335529690,8896445648120745387,18381730506922438787],[18067124772614236981,11697720571445513982,7291057481456007871,16035544815351011668],[8399350757589766566,9703749278455412004,14152590955431213973,18078194091051596774],[8375092080238713766,2501583701617792645,4459583094471994216,13395597287599545362],[9274525761923607140,1303058622211892675,11183117005893017869,2587308389267677988],[3037705757550819068,13786049003421994555,13827800118765974078,3797290621087351121],[13260520706114560394,16220687996228816319,5067175479492727310,12187952968277816751],[4422924722141377334,12140073345068470230,8465990978591604874,1315027292822016672],[4743105481716034863,10162249528121619323,12642326481805040822,9798740205449691954],[1237270874127457172,12704630456402802259,8183370940905000511,3306817192274245192],[1217988415998051787,8741560061102598969,14664366509103241693,14548760555498858094],[11261356809108521923,2948780766492279028,15561391550834763980,1768139922510957427],[12063825608225733461,6322149961823329931,15619414256018680954,2792100305321666296],[16521583954962655393,9557593269745687393,17921423893223793548,15448423342774533883]]},"quotient_query":{"leaf_elements":[728609721327991345,5099584941402401152,5286805544283095377,293229872264608459,2588398155932050445,7020352990844882377,10505025517158212760,12063463337332616335,4518427537254823489,10210621856998064863,4500866591155194824,11842335554711007939,17145928399140700025,17277143331357351996,14914614344547944297,816947971497626892],"proof":[[4814142767109571528,4696879988155512319,14872016149675486932,8588176840704897361],[17404537966339822706,11519627687701081776,6146572764214470137,17770650176428903866],[3692383924764090085,1679817847045181983,294981780236455072,15317493220804905076],[14398805595315563027,8249542444688521169,7291847119250251394,13828364076791802770],[1535053083740695705,8045444732244940743,12962574725799121926,14978038456004089110],[15945922926306239058,16794541896836590558,7563974291501573025,8850848266704978578],[12661602890659920359,12845257622444997768,5457792638303923509,16478604439770228624],[5843298435967761114,2090086794910658176,3632517912047837951,4086546781729000059],[15174545302294628579,5654818909519740039,6185365827853945859,14351719818336719399],[5174626942071237438,15788959375764594978,8739702084678126615,13630721922851930060],[15553448270965294575,12577992282556033048,13596483449447757106,12175578473671278186],[2040661481099962468,1276392639802706331,8656085028898796314,14834190236386356191],[9017042532315825521,5341780908765591446,5000834741291902171,17225254562887505381],[4766862100233760493,10716519217209799400,757400469599698273,4652039211470619325],[4192894158600205744,2808237757672253607,10273100990197647871,11143431622448644728],[11211697874633547288,1762799027098974912,13565693103866034480,12618016415636578257],[6311716979724664824,16821031972561536210,11877482923314788859,8112528724885179665]]},"setup_query":{"leaf_elements":[3441809055907672606,1926799643308551257,5984781122461207493,922340441325595114,10876956993999908078,10108997698952815873,3564742759998520489,10152424471480599480,8143282539836338512,4513224210362061044,17597335896066416775,16530709120107239798,2311100177627253359,10077813162777222673,9206568216191136381,17318831902395594276,10694508918870055264,13039474853084322206,15334449667471681840,4261782627780214288,16383404847694561065,1162871972350072375,8158586607057113477,12196806167419434287,2003166557417495662,12428548139177221754,5241841002621603290,17851931966426145766,80455536823076091,11109778837669444489,4298464906383271456,17380539925809956552,9249873690869043424,10559203942623244995,5753785954256033305,10167321589896282300,18214516208391103702,11135982318187513906,2703431844412373836,6173265043239185388,13849788984591981659,3984901425702976964,358488970294950993,134737173420956739,14611055535073005966,5240662502938855458,13328328741055995634,4728013299891507568,7679658188112544277,17211272792893389805,8023775916254092691,7350872417369117713,17895350052925405998,14310384094812564313,6922028510361919252,5828052429387206782,3913424843219259573,12792621583673130106,5539584422492810691,4595898542962868311,18180600522610564738,12983739834693723249,12003028236030533422,1155569357690255596,2238155616536758838,17036575165678065573,5580306001915490951,16740420506046113249,15025849123292018770,8875922339273057735,13539992181862894955,13890548957226325702,9785625454715167104,12803927194315708346,14646518374577299560,17840146318726380654,17029678461104188350,4623958902641206129,12714846610478666411,3828562896799388547,3711958928094952338,7065482234598810588,11870287021218500160,11477869293233118878,3808482008989023446,12993139537486479373,3218397036843459440,12042725733345607350,17739692179689919655,14223838492543555558,13864035037290366628,751759250572729961,2106257173307315081,12946644482296231772,12280931914203713790,14384040509690455741,4159485681281608497,6791527148762413308,16938481313656970863,10361999070273754509,10941307119449937605,15316558263687351176,7472377936599749761,17560401251221597601,12591181322332360864,90524634374270583,7908982512355666770,18262173424721424851,196601069187749869,5383666004985970408,10349321021485247448,1952377218479275609,7946179836090272742,6087654339119643537,3209157952167493059,1923092271914670623,84889229767212967,1608713490194617890,14017910484495517078,15015415525695924646,10599878836437415415,17626874551752054404,16991841828126064577,843314572724481752,12311320169482971516,4296961449463531331,6296254717540452820,5440294863369677905,4624978732690617925,16755040111855507879,3520462801186139663,13238276408075378666,17414624484567195135,2538635656968268142,4199651926994151782,5518255306927659899,17727480179054510821,10423361099609786156,7289124034396782404,10683063744770985963,5318797688641036988,225531669654121529,13819679616332141850,17917956032719732208,7639121231205805235,16147333962505178100,2447399617186792286,9443735893907248841,12819455040990995717,5198018250729612810,8838185130307946902,12318764029352062319,442445125287277383,11610670686611304387,5443483897586101511,12857285158532007835],"proof":[[4165211127948754852,10707435912189179823,2523923041669944841,4882221471492373125],[15474804633133657526,6091079992655923003,17824562819955696537,1193452901902170409],[6637859522384554129,13498998118803798113,6800645332597520017,18001864453717344099],[6316709122882295946,1254671983250571951,15829616181054838215,3077202290984737426],[128627710402361874,8421602823157160641,4535753571674100953,16476310028236606810],[7735847764735109524,16783630009498469484,2725293281390699067,14276335304509656330],[7672020280152623630,14073245628680401480,11812960114681540694,3962507852710582981],[17523984346860384406,10880357603661148937,9411173829536242339,2144246351161984175],[12863902227775642393,16751913923637440737,9209355438205946903,2026017174535799214],[8450699580561277352,11758847138004647906,11243685013597056375,18144625022204944748],[1615240171295284988,5605588424116451090,1200245979803602472,10377870349781448989],[14266858065115430140,5911934695628169713,5066851379965707455,4437524839515838605],[17457479777007685871,18050974268488674190,11539839813507960994,7632042374556507813],[877144097703360895,4872825114896739066,61549541118361647,5441817829950501654],[10664597121867486917,4595390270492939196,3945013113036316459,7261353233542256988],[12593866387740982228,14070397310566741034,2287342099561489904,274830820208748588],[8144721794827539814,2146513623129816116,3416333900443617820,4841827425225321775]]},"fri_queries":[{"leaf_elements":[1314318691067007836,1208931231608254144,17718717322600451460,3118259206971641613,16694078006537818262,2360266843443772134,7168904159537019000,14796904925015934187,312560845098594793,13661208367335825824,15238001267372824481,11381320688021364192,272687783071640625,1460285663499664667,2507705599148766133,12905757719744835229],"proof":[[13391176714763549206,5135326283318842588,12308007050467539225,11886351270133306657],[15465006981037053689,7659070959205428503,16722296733291136652,11070127319289800759],[16723148157858278233,8847082338433264369,5279495792717453788,13676459666523481892],[10075378182963535389,13245736540347809046,15824155710699115335,1401220399807144680],[8428309898707196048,8624313307669897874,15279390997089580274,15995610400285580911],[5967097199693023038,5837800836735534755,7371832016815187835,6131072012587117878],[10709002824446168946,17688837166629789107,5811256298202797805,9546831670687060599],[9079485435716706187,5099853708592758975,4255236819122164665,12552868799390295418],[7004231915890988494,12400342102625576957,10577214015197611946,10383798463636487187],[6667751753567085405,15708054726113621642,8900790866004077879,2434658048937255114],[914097118824988485,4403076729082035759,7332670796030453382,9850758854160985538],[12103092453203300192,13880199300973955723,12731650023193941545,5056040918070042416],[18221425556018982994,9115032815973623114,11799003823144475470,7734101059848489508],[6630524455774668230,5117679727870628309,9166887966999579390,5116603448009800263]]},{"leaf_elements":[11541332058801969803,14905067044916492600,12475239147127188183,16843321412750081674,17640393813708295643,9958386046101112130,5542303144981748901,217860865131034948,8342642635443078437,11040621278069958722,1339807907742063150,13622360918329447769,6737611873366543707,4809158753897013177,7301052422563360141,13666525270038348134],"proof":[[15140507024933950906,14340907775524391398,18374081711465233844,9203396152139639847],[13806178714989854351,4046060415819345740,7360936931001587775,4858213277388886552],[13240582765426009095,16233183010066064625,6745371425364240545,6166791479610163658],[17508700499256319166,5545820886358540521,600375112693548553,4792893002039463657],[2354230688863537839,5033886666791118920,6030901104821318833,1635521895694569007],[15701874065799099436,14516290326366265275,17538158350299216966,15306748513766288550],[17480399221795318178,12249813739278864832,4568731579365633511,7909980563442852397],[3321066434223610296,15662662881602464256,16259690109309788220,2412408726829245068],[17063736117362232954,3224691512197021613,5569398676807733162,4079704342614482561],[534481713233138106,17127940592515161019,5522352044483774215,13742814405080338764],[4034940692541443669,11036217326715356695,6227438620314195771,12660036423694691894]]},{"leaf_elements":[7950163874382385737,14003398748650230112,9404513454714679384,1937631269905006264,8135896192604019324,9774669982286693527,7414148900099100630,18376362396872962772,2463878055524438238,8412558315459936539,966424818023269001,17975546378099374479,5266457886412056541,10204931908873680667,18311038894613087685,15646803680882490553],"proof":[[5519017273790831422,8423877717585994416,5499310280956224890,13645832416107375458],[15765507282505673276,12323008812358061474,14728985655052656737,2297572784799418073],[15733562687871252212,12211676886776267390,10049652462196832494,15624412152310718429],[15686384237006999692,2033391415049338116,15755345649092600550,13438505864026453624],[6473536370930476322,1534423108632814184,8068173255898843933,375238311312379387],[15404623646528637292,4962458600769724558,9475562410270918437,5966602148697896566],[12022590120329774003,16875814378689878355,1771791742104122096,5678859877716800397],[1379488454746872398,17916228227992931737,501841052943054703,5426894775225945436]]},{"leaf_elements":[10321537731556997688,6838690295674783599,8392317508165093126,9110956075796198225,14563589713815541502,15147152399856601876,7573435992079225498,13513608842827073689,12111462684115794975,13997022757838147078,3187442671284547684,2641473950268333921,4275294958270202743,16983064853821881069,12220037902382780130,8566739138049568156],"proof":[[12718194034261566611,3142619287520133460,3601008460097624844,4933920057887122380],[17790260203611120808,3281220319258484267,9228886400423347629,13206108085929273448],[2450866223755852384,7135962935798821085,7252240504569732006,17338734047721859282],[112787629113696126,4657594194377421508,15904119824690091587,15206508107109735081],[47396622137321381,6545335423758879995,8146839398956233891,10138960066666637062]]},{"leaf_elements":[5266756501767011035,16929014085826009818,16123181449129545921,11053770951348750732,18355275479546270336,14813579620838043268,18179435709646758053,17066073613390001048,6081201138231631295,6864188344561447083,6178787482743033785,5265716337967601431,7251920354496204176,3620231163335991486,14736583203378796474,14089691435193975928],"proof":[[16219298966173044482,12286202864096587754,7522842907221992818,14235796302757838182],[86857399830398919,5940265118539918641,9583279796935607145,5072367504773675634]]},{"leaf_elements":[1182631706988909812,5518244554391670520,917746562024176830,17733293859730176239,6201899089295260902,7290692953056460497,5989223798508600986,8968599394470802659],"proof":[]}]},{"witness_query":{"leaf_elements":[2352695969679099733,9243468605514599505,15391159193538275187,14621094717025618581,8372841754035053315,11724953239246443211,5875355210255142034,994765096872213324,7917992536677503686,15778435861189853243,12320816915036997383,7971488025982108767,1289325013820806888,10066031658615321170,883590796370097058,15756063981534734491,16341439274996511709,4028872704464234810,12925761166564189035,12130075821903081738,16518086382860261899,1526722358032082220,7073326603741988434,3245725270255672241,15399970504753247243,9788344029207020468,8784720671035337085,6597802059052373142,17798854426697954426,12145050149245823933,6061160997220915,15719479768365613862,13786528781586639194,8758792990910482480,6867392250792783040,6731910029985818312,3442364836694947610,10811810932337388397,5939530943477075798,17906924663286716111,16839961217105996737,18308839689430557352,10590655022848874293,11448447492516543612,7543946334919188021,7383843185306491118,14682994923712050980,14233030366734712589,335078742904288380,8304874603672697422,1308598160145888501,10288687412351329011,17602557061663726787,12226648902343110585,14882085333717892974,3848130816536561691,2274836524675661797,4257752922249581338,12927419184364131760,14428881976465320733,3540181073902269614,16056709751876047990,7069777286182834684,12647088843911334788,6493973440205319722,1403055551143527993,8134203014008728987,12912885029720644974,1951888247483778189,12725945072052298127,3437214166634567888,2721520660038152401,4738122788457453372,16793426570770208739,15096534091116911652,8551579904173446100,12470101437634671632,14245340703690220734,9905757306123933331,7333660752142588712,6580136790955454163,6530380814044383223,10326596921642129231,1727770728967975648,12593551391834698160,10269008080445937711,9300274944672842047,14050818588905410739,257292482870962834,2116616193963441264,3591649120969146960,7062901245896539517,1092452580123376846,14001260228689669780,3700055993539898761,13249486404123858017,8045908022279021539,18291751735090217410,9335133304831631503,2957808927672055404,4807410362239270811,4587942344793774034,11752030287293667673,15558434153757336050,4255223229300887759,5149544767427078177,49039210146629239,5994765292571068487,3953634042360945930,5836299022323800949,16049228069860482376,2801109273955094434,11090350394813016557,273032797330742299,8095504404319684547,4473221966793148115,12625362084089847791,3315541816121873321,13451063741517936127,598522547564179053,11362779756596561515,5022667120211941823,7680005541920613491,6190624743179947074,1673648087418881477,2790277672792242761,12720820399210081201,14712083269249069593,4877269788978764788,12344877786780561244,10097743954033800202,12748867082570771355,12092272672333602866,5819573155807420371,9724562888818327950,10715090384573372440,6037079238306089642,17392359276678919527,8194338729885361066,14921761057554266793,1116731130858947211,8501966502711204652,1682752330367044872,11453463077131808908],"proof":[[6146147620131206336,2044518781890778829,5606610458208958671,9976957268392002283],[3439475370754032318,9154125113013891433,11757674275490814799,9277815318085799411],[3737291838573881986,2919182757203230518,17259085890226123884,15194855636113660549],[5576633982211608726,12007551685740147632,9076847704579550141,9042644003263281188],[12591408663307389684,3675953560322147820,7475858251577879713,15763156704246002773],[5965219228502746362,1165077582456777567,4899426795604180996,10712218068947979959],[14647912210121186043,17814027375958199426,13939613746988439438,5370468879566419459],[15301316369740273464,12980583118887730262,686810972296334980,4401361791992440918],[12364072039811515619,11636371286462529856,6752032522646314439,11124695817275420822],[13127983389851682644,13987187817946506389,2947791053552169119,8411528442157644254],[17067576403718518746,10687066733113016097,11463953208832851703,14027466439385627654],[18049043963999742420,15337421470594970987,13856150812828455096,1315725112562554645],[12922896603524319544,6392263800875645224,1182314293811431528,15462087032812066458],[5432969548009313535,11133407864262325390,5969890303957820882,3227936230728845962],[5806994660673667695,8282429710284881794,2364600395318054616,8008403610765871677],[9926660428113497998,6267066272347900846,2134114056503813535,17298158552949330694],[14867216664302836752,12562456856035097602,7756423531439073568,3128883302367687612]]},"stage_2_query":{"leaf_elements":[6599354503018587775,5788923309793352562,7915408294430385618,17547983642941716471,10981067844067565715,134253222626951202,6306481226107727132,15813457024184637349,9661524602219015681,309764891249809657,17163914434877130160,10574354185267679005,14214106229043456309,1654419085593475197,8772559915865844623,11147080408784185592,16946255104138737985,13223554205879884433,3241071232080211362,4757132450445308078,15211946578533010399,9571632444005521167,407233768905397818,17221472348801355587,13253967497965577982,15108800798858365134,12061191566128219616,6511829593146709245,9863172740656130928,10741626481290790485,10773176318322732400,1164809971198059874,15039340413399607759,15440615760702046754,1038052590258065941,7105161926236276136,9992196258707936381,15491403597205738718,10952469910265329768,18097290770072347430,1131301582950138854,16991948752193061063,6989344236258658992,13874993229640682575,13307775107783478995,2676167934462593423],"proof":[[11035995946448796227,9716758055211389048,13405578706624436173,4128960135476656352],[1193622863048639398,16115784377029455627,8829876222634611393,13738928503638495424],[11925655013723234652,10272276695742262270,3484171292734319091,11413058575369234998],[9318069403723782624,12950173901662888672,5831197749288024031,8759192455570910525],[13682859781811807259,11887943608171866509,11036276635195415568,14648497339666694490],[11636584519816036249,2672998340409448733,11713132839811374115,14337586303650025907],[12993595469927025372,7484524902635020205,13214785243723254849,243324371356438835],[9393034834121562395,16091226390701644481,9560483763360180514,5346818195623872546],[6392621351615135726,8989320994027540086,4464656466259836633,13605831029863078880],[15864549595505750004,7524817648799406880,17058530048438016110,16891008860376969719],[6954242434100930042,14204138852797946114,10234543890178323881,7042231589037357821],[14255746454742354807,17687917181382117,1980576681203019475,3488813512425236572],[5523845428396375059,17046611772250778077,17313278262267546559,16155013806733455928],[7359701790722219826,4829171600031074852,5366538551030637937,10836270934422073305],[5905107550622897785,15676816695345529426,14943089701756460754,4990638008784590803],[12325599187125427775,17031099229203075872,10298027793122574664,3335155613261841157],[14260353508351826515,15997840699848638873,5926302242716405762,16396812349572820247]]},"quotient_query":{"leaf_elements":[12331292661571309566,17522279915815362358,11702113195584847793,4465385662059015314,10544946231727078738,5960568294189587096,1890404834554688140,15071016151246023803,89915975792341402,16403989523727308592,10127804444148777538,8338852047005645412,15646507753634203826,13674514044552369078,12532714134468268228,3455288696820600784],"proof":[[10062485895512449399,2789383614742685477,573830426206211536,14597929726824887221],[14691962111525420152,13257586742969049914,49133418792104234,13965845810704165903],[16574725031416132059,3748746000735311804,5999912081973878069,15067789298586022332],[1692055728343783325,18251604681901262575,11664567616416355487,13847686638537274497],[6625684653463996333,1505872925503124560,1920602113893837205,16484034736295759771],[3574280557472386346,15366642238597249978,12505598917696043645,9367769624081586107],[18269384728864702766,6407641908772465511,11512613781423304653,15780051769308351822],[10061265230288591918,14150694509544822381,13301249232766213034,16900792239526913765],[9104647164832193978,17680560733647223395,1811191595176388273,12870316684580774520],[16979811946289030469,2799471193409233477,10306085298730075983,16697973620923808184],[8115741389471228863,10922946194830605214,6720402191596418005,1832581867640859713],[9185468372815680846,967469008311255800,16310297442332466099,7475312921555979211],[8711461975191420563,2605147414835901377,1078908624067059341,14350840008340663308],[13997296690547632369,8356378572216653295,1778483782954601771,2309480387207818542],[10536090504536668172,18185852200633445009,906928979678786579,16954838268946672528],[9535674946377222374,17853419219018445682,7210785550365260009,14496947166993698046],[6428516624234788705,9287937350807014828,2717092354687218549,16008904268343540721]]},"setup_query":{"leaf_elements":[4457821327581032320,4574323302860944586,17956719281179390640,8344613563726633964,5656875541192430961,15992715617357427757,16501775793762962573,14065216373226079510,16327731055085164965,16456088119481869422,3344027121490739840,8320340495671471462,11453762729631202112,3373078362181981238,1087970843518730944,5295212885572796393,2168870130354398854,15618648446633844080,7474456040328843990,18022074289804280156,8462087920334944897,7995754477313360579,16878393947055579384,3886156991803910831,14383633274069535368,13489537567171167791,16113445794256868104,8786072805930263359,4977119754222658394,3774513209098956919,2581726943335536786,14106070977906985121,8773120959704254578,10209261616643070362,5363309605431319143,5883608026412711598,17549369210769571318,1631764230129420986,17067534257305101509,17612199217688976896,16633488700636788904,5817119669951003277,2881840449674665059,17663608780863807031,2365293086075857738,16782388672822204237,9614003806803847798,13964617183086143209,9966443992089081595,13131622317092885499,15871236022141630088,7028696623735756902,14393163843142308731,4035663865755890522,2109148468168303404,2837696418085061270,14944506531837802558,6126320388298093154,6621547069191670289,4442692542183710126,3229707088333652173,7863433169707604634,5535302126745706484,9881477996391781374,12290560867283520567,3556388761525918282,9707561681292056798,2117409220865366576,17130292642418401064,3020129336285190524,4306997908714028615,17888556458736241866,13156121638172636759,7516592947106066752,17530056865660499094,8859111710393671857,11003808892553808503,243794589236375207,4196393830106437467,3670903864707893875,17543414996260996035,12229301147981884843,2445858961647428240,10920046472772789308,16035770151558355133,11573070420586957118,8126816150117053911,12983853736159036165,7096298401522704225,5456823893435470938,10062548583521146540,1940738495507340386,4555582461986115554,10562684997208590049,16222652602737401806,933946423345388519,10782236547726694399,6721711046964463697,10678724016196465080,11463998281572358616,13745820580712058460,13712625623498608021,9482575883973756580,11162995784159261951,13999617978703959064,3416602896350225802,14706413086515934242,2955024676616957755,17151315180565791604,13009248678785585993,4789427132676303588,12302184626696608113,7819731458864708757,12435796640263093848,6187666061496714122,15346689289648526347,418024105569777328,2035487564225597126,18162281303580582908,1557839892131080587,13057526790827383370,396171089690652555,16102906920278355205,18248462261313262243,9031607720025098343,16948709654108444789,2796081452226588167,13319322685340633519,14840514488612015055,13342565406353683511,16656808663898152330,578811120268081675,16392176508136076522,6353431720045987183,11029882499314943647,618110244059295043,14627232132245502979,8028327278104906313,14473862665991275173,2626775237662268699,16746884603465659303,11750873494065737418,3213367503880890143,18339199698257511324,16819801292088137574,10819642512437421324,12102091011567573634,153458935759863283,3551466407246836436,10298425851688060415,9469770386318384830,9600539196811422902,13937981616197791211,16426838475004552770,16872346445127091193,12168989331622422800],"proof":[[10912796223128730742,9648202220030636328,16808328998595913091,11344638029545298058],[8748556607100510869,10223734568489738214,8446287565092187983,15831507913388624415],[11343110157437020376,10836415920562749062,2246460257488354512,17284309452907666642],[8364326111865029563,14739664410650231543,9371082977965394281,7727244338289613554],[10307992442196561362,16587176967719777666,6982402652938589478,6007946639802124823],[10486429212267397434,3072798722335598614,6575990517668200624,2183148607143497031],[11031845651788913592,9701788143254187339,12139048480916621923,11837780396611095757],[4255235829755090905,14602388504621401569,6737860791557899069,4229539873736384240],[11665517522298775784,16595680109790651848,14579402099352569089,9739234825399080806],[2943793493605331609,13928556100210185906,7058055138684101584,9253399456047541401],[11949840173006352954,18316971752536244822,13052394665096083923,6112429671162498162],[9041455331773409498,2772001861147894083,16672274650320101973,1508160363404558110],[530239508192576781,5195767747259627485,6520874140445881524,2757334530459410888],[14055993480332103527,12712981076926275460,17994087062730284830,1358347729845612584],[13782108116632303185,5819458452297287582,12212174525258300713,1748984254276553832],[17857902469397623891,17664440104555915936,12305219403009730448,3018465272199973818],[232796533062090112,4701081437590138433,1090891335699248712,16484287474631432090]]},"fri_queries":[{"leaf_elements":[5685000509828656948,9453034467898879905,200908220406782650,3632629421243453,15075421377730691037,11488487366450808331,5413763487555999770,2564733049703941894,18016333591206399346,7701517441004854211,11065494054674420908,18170400362765430328,17201013974208948985,8554747507718000980,16817621585557981780,16230966578115047850],"proof":[[5430494887831356516,9989723786172953109,18375027670241326972,7562870664978384901],[16205805444441807017,15710929543156871365,9913410460968040357,14272907919486888111],[6845836546065754224,16708634501018963126,6095387876876373766,2358353601840862604],[8762653206659884839,11353294797301938701,18200617589518934783,17736776912370876673],[14594935141685641559,12031528684081957127,13284970813974334832,10255318035486050964],[17920275193548909116,6121063220829891595,15264168922900795189,12938589406428440887],[6412751684046828559,5575204819416671381,14706308445496920056,4248685691916901105],[9721802112363747456,5871394528557761711,11489610713883573968,7789149477577889957],[5659295232400466470,8604865512690690828,17086982375246646716,12151041258461288508],[10271172994880270498,9155329447162884660,464166935889390473,11883974880329894024],[1049022374328324742,7738199243509922408,8053610425436592621,1399723564065335569],[1364519309008866472,8307080152458003301,16994353107366147531,15699535778810695187],[7721061104706327468,3078950425117453684,4321428170273408066,8025265308058761849],[6169857227742315395,13357582364418817607,5697734732019327995,15965541982362316595]]},{"leaf_elements":[12737446929132988922,16614718597548637112,4435725631463946503,16241310301328498490,15497180899509845769,4496488806428805598,12476751018535946241,15476505688971667722,18048384163243127851,9542960885562746068,5071348054479080071,1799490237809114727,12284919335229916328,16785661987029692479,7286362816242577205,3175494695954907499],"proof":[[12228572368625713000,10935838718523031608,9706050962525443195,8177884620620239883],[9467689989633145867,4315924290821016007,13962564751954885276,6820398154481346138],[5944667261887907988,3204702272897158784,3557500549510102847,5936262282006773318],[10072498989957239732,3044476212720626331,3487212544607403700,7476695799612987135],[14216320641994472330,13986638977346734985,3677282484011804261,14774926925908773541],[5567751501843909253,8630025448540799044,15898850236389998815,324477392681087995],[16775040576051295909,7884805446463743308,18319367733244267578,7912753272716953843],[1923058217938705866,14009864367895262963,12492022972423009312,14910246097692452173],[13004541666879588761,1883145583663247703,7728130545679710796,13113742623565001906],[9027247964270597467,8154606436868237285,6842214611531512186,18031591689994944019],[13767557634651448597,14275372649907910762,13782730872602003299,5632469238773170118]]},{"leaf_elements":[9566631151698325534,9084219771264198213,17439123416710327520,367201977915708238,193260709385156339,7459940982273422207,14185107513173265595,7239985050829614028,7111643117607560916,13149064018562514070,18443736993870025845,10634066860884063155,2994819641515999271,16116773226517839056,8408551104376247747,13869732540896344423],"proof":[[16245547043982677155,16882538883990440502,9403974505685102499,10087335922177995327],[12142616283214501001,18303978592559335320,8814034818689547022,8944250954624576377],[16539797305480936127,1810385184250379226,14701101303386620906,7046510400743715819],[10638502527533447059,6131023661019217317,2427634406693754461,3931878746738727691],[17548029548686734610,3978005025751739756,4301469388643701604,5401313001719372253],[7057023880750893295,17534613156649330817,10534770618675884620,3558453987377968243],[10726006675864965269,10412444321227706545,13766451279109910579,9820516533098999059],[8453612859827862692,15597950537987769407,14607321109355321458,12321877943907868015]]},{"leaf_elements":[14924916200437692011,8631008072148923016,4368310596471046353,14284076811987108870,5426902615884976648,4194698318709776893,18295212089535422921,16608775580181313912,9645213288321769913,7595562540221542073,2017383635099387052,5596851433715236214,3307095895750107570,4262038156707896701,8960439271530970367,7083145301820319758],"proof":[[4189226093362038855,13322832489952952229,3457266372408883412,13299449817463913802],[10546206324491760226,5701106981027960726,3499277688928613860,7441686464021892513],[4495732265760910274,13942876163224753290,17912585964056779204,11178587633694350677],[18234500022953575530,14055399872597315795,3427577728342593250,12547579893448064404],[9732057508331218338,17742413443053399360,1687316217664623535,7873157723082167597]]},{"leaf_elements":[9387637197062045130,4652150522521588239,15637073202795890068,2447469261090042352,8500272786629289830,4094976198972476677,517297902365875451,9000026468635167921,7061611386518741297,15620241781818337298,3690660075841803327,8137137771409335909,16415713597184981924,10016555926185050401,2829838984487282123,14101446198618882559],"proof":[[7892846885318146075,2646950059645177715,10326596799699919609,6852025232699733221],[6156120735936047017,6378596361573101966,12234030277201030515,15524298584112405956]]},{"leaf_elements":[11907939937929050222,12199976274714464765,3239066403731203959,17951336118807113373,16307121117972480027,16234899209723555345,8364706858358154655,7274458572308793086],"proof":[]}]},{"witness_query":{"leaf_elements":[1952045461057232570,2956592103548980962,5966702087408087993,16419185018825719080,8632374924401700204,2101288160083889411,13883503956430237715,11057735002582875389,8501299574553583132,17720812955231017778,17945049271000631834,17731041316979994878,133004685670332478,5692645395495006345,8575776555449181246,15913281022763406068,5771175500653081719,14932311659540335849,4394755903905583229,1659087919036494388,15810138537102859330,7095485610858836389,7827966866662473200,6541687200254690268,18380667615558040720,14456684000849306941,957411611304188065,16996812788125451060,3861486902529992007,3321627155486357697,10589366142068129716,13201812737542271838,9831734014501686992,5936890781139697849,8877312473674132516,10294240263547210765,16332370043336562905,14650064989160190355,14197433648843535117,1512460082401300515,12278043421135398269,2638455960895677644,13901645380078758437,14000616005318653050,15857743708722379015,14557587338121298061,14640339419303522647,380955509398087837,8447480118279925614,16909874129786273067,9113805334103695961,9369428755294714122,11773585862512043399,1543445495650708978,5356367340073294576,8886180518314459030,9439588827787330503,4639021586841998900,16144006271353457695,4576009362227083231,9876861592379901886,270987883107369312,16578536960896967540,249893809474025708,4242413957291152387,17362334896666703482,9356867616463194782,8291442709420038535,9070520260424610380,10213730174269801533,7246129236049233068,7478788666398749990,11826624917892213643,10875881118493719956,8845712396940887582,4141512748233672334,2721115656054151956,398753713462369539,17022381260160618170,17544698755933725004,3956971962285923043,10556051289991047613,9705236664937638090,5729108873485404722,1613347786019525134,16740147771981138355,14269050426546616680,14725431584357955423,11359404937274377551,9893704698541962845,6720749846929086046,11320619197465395774,6856415389864639266,13839702711702219090,10196238990917220562,17637524400495580456,225212195083670221,83619833794383632,3653583739542383709,5868745903529289204,3855277915494829353,5465310452768458311,12544708197223886629,17087088230893359311,15583449996705769017,11476441828395015662,18226315039856361396,13835230149198220544,11693861811071104718,9709584481257211974,12779529522171770735,12423222263542671318,16083166366383503716,1877965700682974315,9746011889314247063,12977300693273951042,4930428483525420733,8886958028823457589,9218936494408657057,8066015688598972203,14792241026884898853,4065847795871961399,12788541441587595794,1948289288445310106,17237709705703316768,1413357686906859464,18003374285372645217,12461281325850053980,6052254323402674683,5116945190237214191,11212194011375103325,12135001732321264354,1040778594419559691,252345098175899591,3043370559552992611,6485368869031752271,5400890573007490502,171751464926176124,14551400884181102563,14925998444982375443,15082914318273099824,8470599683955013978,15630842798145297997,2546824110199120259],"proof":[[2920657075032637105,4611626931569030112,11106596429621473377,11195364607139261625],[4805883308033170930,14035586473449432453,11504837797382939086,18319588285311309750],[2153470008813548484,18094417780331397088,7469058826443076290,14588556279718236576],[376846863027909470,12767615952983019800,14356098218099362539,15159614368288424326],[166155647425582031,17623164346780440846,9755594266492645482,16425521375021601335],[5960714253383041581,5293639883768593360,6918976110902225933,13894515241252179743],[13888111089898475967,734383469659400705,12330427719947452510,1255693413906415918],[1870944429651737606,9746419160674441493,1013464985917958980,8049659427420255554],[14694360182316823021,2967472183381082671,14440793681722987365,7765649111988306859],[4510733759291953615,16119245266665727384,11424773805499155904,13155744218537647272],[11698495877004197020,13662117363877437955,1153670465872987143,16140824283012074384],[7447236057380074983,9624570290540892030,4988899375552678727,4337544345035042535],[11516246897559145157,7358904227388598021,16569547665808240713,6392422475041286424],[4071699731824197497,7348607267254775041,7842502761016962206,14563212829901723849],[12672404864828430091,16324094638260594187,2313435301723238678,4649088493050093927],[9934413130397605857,13402205192491210424,6232788080482235432,663435445677615599],[3917596628354293155,5216102744746703452,567594964081413321,3215432225810112365]]},"stage_2_query":{"leaf_elements":[13368058563693223085,9403933489521209365,5957848787727064040,1347613587314365877,12353306208753262492,1571431164330715319,12949119312116236540,4562709762027737092,2949053398725218034,13908648046209432243,13868002022216633133,2708870456315774708,4457181039016681264,5667167632936257888,16260101058726742258,2136243970127707056,12327978247022383555,13305927542608340970,6642506090194279859,15004562274189213847,8787460551502863564,1313413908462767556,9955450077890245588,5084933091136696359,2281328510584992666,13519719856702536608,8943426481936208255,12451710627344349292,11969058090731906591,17828006839259854024,15442971974376010446,5110013908837596587,13008863096210951997,13252485127970905778,15481395457582072207,13824700641394758600,445071496009473266,9925378576236544634,2559445477782650644,17771635009643417714,5968921405367622303,12470468351097740406,3307155281270058266,12030353300356038919,3721559281336911180,13874916698060316728],"proof":[[14223065038336852976,11469677272050777152,16246409750062745008,17360572928888402301],[2386806781247241842,7290266954824380476,9230773844834484278,2608335436223144289],[13602622488360281535,4604251576693972527,6232366550973571545,12833950318027784202],[9818899406904757151,4524666707211440392,9783099107399967099,17437839812126565363],[13198088415791782929,4049681311876647715,11249961849037645411,2935747149713092163],[9422604016852409205,13592578390218385147,11181829949947795876,17823920066843527986],[7369411165703303147,9355496204249752091,10789727799385742804,789773824892759580],[17018168500702969588,7321978629016186306,15359253748451995142,9202310138921016031],[3010165022352008852,13644634949027658139,8180416057521761702,15579101274360238449],[4354198601189364885,11225698027485400282,7473336541884843491,9061899279609056749],[10708246102870765706,3370246895019772595,7869450678869362749,1080464527128154209],[2731578309778611696,16842703595037140791,7990664747331755450,14016217439690533634],[9031241756418536480,15544786578870554293,3487188140489702352,7399757850101214295],[3441420987268877044,16976446275612350645,7992656113709788617,14692792976460670212],[9733133502584576602,4356795375226647592,2170224589051217274,13809189237294151122],[10057898774761953077,10581605903789021883,9560256431104546167,3813804416739869427],[2790166171694431987,8776512649030213805,14001141908799450988,12523224147355573140]]},"quotient_query":{"leaf_elements":[5470095438936103297,4824056209038235629,16017094448370701263,16065618349021559674,7870447056849844236,17472122325368487698,14000156583456180367,9803987767939295310,15068252273928900341,4849077581951232457,9999636365014180605,9470809981468484883,18231140371187015394,8947156487141418387,12757733215427856075,14243805961831294328],"proof":[[3449244904940487798,8613237528920059075,5481668286199156327,6297962299777832909],[802944765693493233,2476290475471820279,2705889552734906392,17867354342039972921],[8597336805778240941,14330133228725881740,9588013283977632784,16058867905678947201],[11633092658769033355,10127568946695612527,9157007937753566033,8804575580548363326],[9814102535344039421,53402929290286052,4261832632484710004,1919393944800132723],[16811375525633170106,15226242734956649845,5596497867442900514,13856128440326869195],[2977428055678048330,11985495800318703271,2042301549344631649,5696134886303748350],[11927090170650821658,6402557474443629485,16999517160424070832,1335923863712798142],[16434919457183895268,10300009321057773355,12667495509934951938,7143564505932635647],[14516333706927616735,10286583283277959483,13290663850471069192,4210728113850320594],[11134346521368344374,3796918852242820111,168002314752784242,9402866907712337394],[1068695487164643518,11838908658558080091,3515500674878650373,6134934958796502894],[10118759166073134741,15781044097057329633,5120474766532124613,6351530544449194072],[4173864293808347891,18101171385311918436,2811214422102404495,15058028571401656149],[11990025304520412681,5038913276082118790,8969551320479994847,8455374462918098148],[10312649194611834923,15865594176571807967,7006251104761621593,14300776019847126991],[14827574826222641753,2016236490897640195,15541113978067643161,9328589100278504453]]},"setup_query":{"leaf_elements":[7867838720927766395,10264397849851547868,1976587153865684561,7444821203905838545,4025585170646567304,17979361000174444633,8087475489560877664,16770596161329183161,3121573225144652373,4445968405490016017,8859073770142215094,6059960098025885877,3814847555191608841,11170825221116595085,18435085161072701789,16157139934485990479,709996689031500619,10393720318154866726,10647922979088405757,1152042177894262838,13553381764744906015,2239317900997088734,12077117584629106238,9247167327329715181,18059816017153103930,7544542133367493987,244277610941781851,16686240713020443277,1671188995951966371,17275894801029121143,5715107488421487689,14244384286093505631,1040626937458303818,14758028063161312323,9086206669564235696,16230722632195785844,11374005259814407128,4528774772773792984,7876206854411233032,6963065343909326398,12334985368793948732,1359918252910498825,9842290539419599813,12439858449513171857,13793997200785532307,4556263554031713514,12103066271578459950,4137064399319467997,6369843364802716256,16756898524717303948,14467227456107641728,17989129465393446128,7187128139194001663,4748365683756073836,5043104784853133591,9760359365949064645,15107343556088600939,16805941084989282602,18133489045623081878,7312097592479312313,18306079801169753578,15119237852171947887,12393516539528239388,9915831962066750109,10133589137433997716,17178595479527375300,8716175267423721841,13515326740559555168,2723687073255471744,17846317450491495635,17676568450798654312,14455786227450886240,16638447537615757439,8266094302776971190,15816054000429509728,18410106213000924831,17356578540187652181,1718576498502868366,13060839870302812056,9604782928076236506,9295965311533606077,8941433404419365855,12997652457759874318,13886868476256905355,665300053214796469,6338272366804285241,6684669197250809744,11286134111239660247,15380862882514927399,13843655501039087559,5460582462152672486,13794377451123253431,2543888243571019773,8337456078628838964,6619470207225805328,10253956294661047191,5888176089158450177,2555029636249638425,6352600290732701144,13992569397331474642,3994118706781275469,5374319544565462112,16103983632725587754,5429511320922601289,5473050926897251936,4940535826823463150,14593744842732386780,10709061724855244822,5302102666671696434,9381742835260146688,1443816862366251984,3101426841277962242,9579245897102813805,11583202765103509459,5530588623528630519,12777194749136297424,14315390884908489114,10871415066372883075,9606954611519874443,12413576505142354661,12588183053896564959,12893711081981845164,18076657383157564331,14950104139859542668,18035462208482358925,11066196122072717739,1372816370934739102,15826052522708645737,11749146242998217658,14695376183598807202,16295566006667841116,8912831416352604145,14637630254940466784,4141097631994423593,996085591169639275,5167150963228820193,4959310371947709498,2364173763615135490,1890048621245991485,17066268904034252172,3287174976646597859,6819598516273836988,2166255886581842448,8161588108701807024,330655865837803784,18007449537991898562,4827726343273451857,15621556625499988982,174803676503831793,8813235454021168029,12299878954492485473,16218028751414230122,10127802913859351223,17691360230721152697,6707659663224449423,16741321628967606897],"proof":[[15752325757423544458,2130539124139099163,10970859312218115407,2837497957058669666],[6710920411603376447,1137738545225071005,14310240018182028292,15826771874787926888],[17641085333198071342,15424035486139596254,4913408987872088062,9206255286424040988],[1192617371952095406,5543399257733843572,7259896553002883192,16545412270627445174],[3465714453591190733,4228248776995914070,12552444789855539214,419069683551199104],[13193074603466685398,2927506092650755479,1123396912720454343,18043342579840489030],[1704538979851828195,12713481715098717502,2140330920201970148,18087952982012103953],[10386736605622944679,2400924507958089349,9589936790946888965,10340390618476819499],[18379528053599361174,16742029110486328368,18167848180033723489,11162107701734971754],[10899477397544757230,10604826096562377079,5314203000135394622,8010246482017352492],[14262266183384378833,2586047155290664163,8517301666931208156,4625136187010276171],[15510460174073414313,15076927582463024954,15251316088772468538,4012952879879270675],[4905201394947827534,12778326213691447978,11985110172323156338,1277629384190222612],[7144905410686436022,11650185401879641137,7312796672732178623,1826823341916269245],[10301378716901445670,16725322369043268821,12338633818774462677,8994881978756494900],[2575883822216182171,9239828627651006461,10772246847052595521,2870593119168986675],[4934888255329451731,1299074057986496668,1571136916485237263,15408557579809708270]]},"fri_queries":[{"leaf_elements":[11954006601250434168,10358203129603882125,18398036561525581075,7197964075136548063,15349914352867789310,5581420833514738551,9488100233169257373,1962525071716486556,9638772399209436856,16473841944790217086,15968117841787588236,9710782324675105244,17658313603512273436,8991986747976266909,5428777512236889053,15101456014529529714],"proof":[[16785866357843430787,5542808864441326274,17621388059661895387,10936603291836682230],[4784254222358131985,16480893145435450319,9993767762066941353,8668684154655507016],[14797728148186761595,2321770883460448462,13377832720760261253,9326340431256710605],[10126309022010945335,9994782578006329818,8612225341474110340,10077348159492786995],[5180750604312651267,1701388991630544603,1436298439186779029,125703315295587176],[18288592503854142699,4212834754392500210,11865296375010591179,12110827941873496169],[5225786132671063698,1358160891782990954,6981226203983507162,11327881949629570434],[10571018230040274981,12871906720291102034,1473318213311426995,14523955947331672782],[9253556019049333193,5153557191562736551,9845428876803292374,9507456506306428662],[12452486968650596266,13314560400339027852,8612167747149666139,2802119812432712162],[15647750884619681396,9646377613272761104,10399433003940167657,2887722920354858323],[11598442774843046336,12157568009270846748,12461397747222426269,7858021883621097307],[14416345196959892746,9428756985438100933,10494463369581090140,3803263855815061081],[641015916041718214,5697532741910532451,13423081019210976144,13295319889382710901]]},{"leaf_elements":[8054241164120673957,14875660980644852139,14542061967823662589,13725845895454577398,14235718905889944137,9461753242114708417,14628076225296115090,12788413006635488930,4725960154201546524,6404749306209546021,14031496430360372946,5868525365391993596,17802341839249595382,10220092877547979807,5018198001990062741,2224322829589776331],"proof":[[7161490756258693441,695350550397196308,3186524457381061458,8841586635095320933],[2177856791408882401,2716348359830004088,10228715033218963884,8082379063615743889],[13036197690452462888,17835998458232170991,3189232575382360622,16972808450508541285],[10590492902782777882,6286100363693705153,12477652887531278147,6375330021005722240],[14029439892425311386,5131877021338433200,17241874508195600445,11256271929347877134],[7769351982451611777,9707954160186859632,6845159931252553472,10247708778419607172],[6463463327467427450,18280232442912514476,12323180574366748318,15324098379320798061],[7802204288581963154,4467067739542246187,5257810742851236856,14601392878718007609],[15066345983259560149,13262963764220617686,10102829050400350770,16495126262120487324],[18023760257219333211,9751828409011572,10992775207099962909,3358011652476087224],[13964360843438099738,5308142120266251153,15132423796157510014,11027328105767835661]]},{"leaf_elements":[9687278181883048535,12210630589783639746,3018606577179493417,12534517990040477844,66533474572264341,6927009168492784174,15876129293710444854,5778894842811726890,7545160305634648440,11913228648280714731,13462828212978595999,4413925053503271133,7811158911915830702,4469971028191978461,1494790593491851931,11067086417423554814],"proof":[[12330240907333934702,10150486503670510595,5029945043082819877,16104708406672288722],[624287055642566323,11676333981540693754,8457602997056767857,10753428243178490167],[6163083264730313079,6002703564635802498,2798197688638103939,8146943264866520762],[3825184596289630589,9902773312145679871,4290434351807817414,15822548027524736004],[886667765267053630,4563346787203176770,1923265470361416649,7884842862668564084],[1400326867911871511,12272177682516534855,6622820746802870880,13963492605760033762],[2486172754220345396,14963411064573677020,4789167863079739481,14123521854310607301],[12257679492692059374,18190169789673338868,5420267801344425857,6718007291386775040]]},{"leaf_elements":[9650536626594743201,5822722389871349321,11116735064435481788,7928148892287372813,9580957505558512668,14562717744076004259,15249472736983147716,13895203672893012316,39552645940272632,18045711947077756864,5031192097266908324,15045451678730884928,143021782565461478,14225255208073269727,9697745358737116854,12719403642084933158],"proof":[[1149602583871118964,11997542175204226722,15757838919841266014,2117886650475872572],[11558942498377516640,11917410261352559254,12548172635107465720,3286869769421686276],[1827694709821479163,5619737627455938507,6791312308018072118,14038027268438884820],[8203831361491437865,10979634854535117980,130267463721204906,9287544244822819514],[12203878495608607889,2768485086897537620,12912318947888615320,7822068476628361097]]},{"leaf_elements":[16570911748114215410,16530288560763304867,3997674632761880264,1181074722834853105,3200774299449535100,4772246859195732101,5029862650774772323,5229147631763340936,13228295481671440304,14438301137999137242,15891608995937218468,12683242992618263208,4463235911121816006,4434522489904115992,3873595925194082388,12388063705406146388],"proof":[[4073895050581560297,15945479120057557144,8043568530177061877,17470004614314366183],[7490477249103747300,14890821926391065169,12528894470063621292,17457008754437276116]]},{"leaf_elements":[10666499788113613538,12946354179588810142,2978942579100575765,17219500348011935376,18432379563349423049,17978726315520234670,91014601379555257,582079298344061305],"proof":[]}]},{"witness_query":{"leaf_elements":[2026174631088670434,9316140418545665129,11301858453193775262,3339885450301539237,9022598738337460134,10238101387706232979,11968301076002672672,7407892809213351221,18023895329857268405,6001263811395531912,17212097309928373156,9438977802860081842,16140123150043841440,12355330229209646456,15775397351081733266,4181736314671054673,15825932401975323519,5710896001653510838,6995820060492744031,4889798598050184409,3989883184997211919,12376784692033988079,2834477197917096443,3754965417149660585,9809467626047027565,10053715374971345156,4529285051011508703,9686813787233529688,7071997517706365463,16835934857023168862,4097190151694596269,4816843837473568205,16447547219769409443,1920145913850006163,10362178412704808242,14041329449321335110,2212292615240912188,915194620520413060,13586758730244457727,14115634047255212828,6954553349083936701,7521431378549929311,4304709538826936118,446236378651816571,889484079938823444,15784506627254542799,8198717387768628403,170119399530642613,8726229314494747220,11872277271223515166,10722802805846950468,7275901961752984267,16922355821404860451,3472018201556430452,12095958247311409621,18332759144070274708,3579369194861830686,2133300201829007079,4608706179393171953,10697376132324910157,15551107665258375808,2826290668084385251,10317944777543387752,3129108944915010481,6976500401111663779,8535394412970854261,6337235258357293610,10516723315849905780,3912911673961099628,12920909778939575534,15503230134859875696,10443555139381216816,12884710795118523774,4157846069139593548,11926522608352066943,15064769550456830925,672762313276179604,10162103680910880190,4526754985999960447,4149832612484578296,1246396603892327872,8986846604779153538,10399357048925888505,11261975475605589500,18078842407765580368,11991212748988051129,6807577638902519494,11310988302498106292,17407635549442247161,3785700682876104355,11051625818993481544,11998102987555975497,4300903932851314606,15333555276953409458,18380845452444353182,13322417862424375559,8856823359685862150,14958367996013624716,8290497964079435268,15317493130571105779,11922358848674462657,15493621779129687773,12115716944951481127,1448391683516266522,14189356229136831735,9902043554541991349,6429264319327048844,12815964997624610311,2824040378850895062,4004500251702819696,12660522164857155494,15116758879592389635,13632085862993686223,17303265549731410588,4892174741859576536,1020023466335966810,3543385181919831658,14521095362595659003,5759635551860035997,5809654431670836883,5789472568718322519,14761145535239471230,13472687537748697213,6634425753219802700,4754492630555768782,17261480335688708405,645599759630523209,4386173139054207620,8816780613485215572,10604102006636434569,5716432148457351567,728394620127084998,16909054417966840193,11407814784377222766,17599965903143323901,11604944335516377412,10374752503972871284,5775309701450998068,14799646468066508432,4234634017943221013,2359960513893286168,9743871342770650430,15606731767425155835,6154352937510710876],"proof":[[2904707218967445871,2872889019082562074,6217804266322102489,16294155019882106376],[2176743752123890975,11016721744166113721,8643284292141178284,15845867551260144752],[13490664807520157672,1971912425125636987,13031093930716348915,13311418465542336549],[10547071874672035765,12936088944397276448,16923991969500241329,1982134480149170907],[15478993946285048666,12236440933710429646,5400561401969704759,2304221965775159399],[11624944832624054275,8330991430377246328,3453963977359120338,7814588662704260862],[7028240421297658280,9404997436821050362,5781808828756348895,15440448439482334166],[12179300032367877726,4017678188931431899,15031237997911267807,3155484095466676334],[15729405173831457681,15789845341284442726,12675973657834316767,7456666091556344886],[5890313593176269583,11380342031464479622,3848886451351207250,3706325332995851085],[12657069520094343334,508881445062555168,885974717778061628,5653325798745273420],[16587591622154399367,2866273688860914141,12026318606046789964,12280443727937060654],[5709858757507220602,4888524306574939147,1714909035341136724,959615318448458032],[9750567047644501139,13844518585595065915,7632643288759407304,12043571830356816744],[4996557048175460529,17851583821386386985,11253596238582458324,7542363437482269115],[14034414997052711832,14893374635863818345,16986584032796040498,17293213109590606660],[15531624426577644058,13865094955186564174,8472382933617714768,9186383827036465161]]},"stage_2_query":{"leaf_elements":[14293272153516393709,13966382834711343083,16039329523504290838,13951859949907358385,623053277460386858,2515044680876878549,6687711999119700609,14819170827823161997,16003245378159882055,16032287382884318639,14862311333925839077,6574608945713683284,10009372382977045704,7471541467270550461,7837952005758539656,11258337206937130046,8033674891989358791,5113999281017636940,1886872173864280519,1772542835304394696,6568052354582367654,8040663751248180420,1322229212296806708,1533198453496886865,17312259012498741595,1888907028546328142,13957848357165407888,5258291300073308191,16351920862470072031,15683690831069665637,260340341807560723,11296624698185510572,15049579427758421718,14844176582585251386,3270771426147672186,15246246600538588373,3570150074992380411,16576470559051131432,4086385492570838640,2196074329211359351,309809523556442261,17038815517204401035,11224408381568348336,13427413103934762669,9670353277054224270,6742727304221992138],"proof":[[5729326525442946224,13468526591974249732,14626013938775784507,15368211519237547820],[6309930012516844301,10340910528864729497,16066573284183970057,3805227743004980052],[461781088387544527,13846430439273823458,15251191299578225049,5317893562408036824],[5611647655182604687,2812968675790723445,8842480772513462557,12008621954011995721],[9276540439620575908,7192454186072166870,14054215387148102640,1501627264160930402],[13463824208149728952,10895955243037056779,9440607428255573338,10138196626125512568],[15243697371829683320,7610885898290266180,6848361637579049846,8889546625396246439],[228965528963991872,5747255005605577082,9313008804858435614,10344500659138630606],[16284822993304373635,1199108249814080506,15410503894962165392,6085339033807174871],[12895203813709781257,12236961414418757636,9840536382002241378,13940440825764569380],[8069427157917310577,8399838579739266987,524828283451316833,16250985617684355173],[16168858512918261501,17902716863828544697,8095298552983419933,9640547561733761979],[17807216778297036360,17958562047458111439,12788983087691881170,9776985125725436200],[12354236467023675614,16480915642671696334,9303951048075695336,8746116926896487377],[15060897915257951753,12736289068079176248,12779797559331548559,4295349546416198607],[11738265202271299082,7513143787268185751,9043497564785427717,15504718279411844824],[11139769588175042309,3395418516901826134,16872320672903789189,13422806634613587681]]},"quotient_query":{"leaf_elements":[10960237595173637738,9951556351411025273,17646165384553407114,17362973795574984067,12462031509184057681,2685950166605524040,17988390709511590415,16195036841158654335,3514857400148686026,11880875444249868040,17243283702047813995,10187380469756634368,13933659647890867805,9492736232205609442,16540959283492903620,11840964349189395119],"proof":[[4006942416188906650,17356795018222411049,12387734032376318035,18200719410875572537],[14813669171726131821,5422278915912278014,4856141863098089023,8017740306250688231],[2747524744284253175,17388398878496365799,17596632192903574921,2767118158220175391],[16008255149445599243,6729165031630989188,687198465366835219,3682447738203778792],[13628874657792549935,13257233119667881825,10066311772510355172,10438615523735573720],[7141418787146462608,5771651007354229991,5743244572868245269,6779941226374630863],[1804957883729958244,6240667622439664667,1062621612769190509,12764871236728139950],[2095840909231624464,10584725202497186400,1368936238479241391,4725290975303797144],[11622436846979622367,14191219963521368297,3101209712778075011,5329668121272380500],[16625254237251524839,8093000743052582056,16074890324480826699,15559589813741989941],[17731494556834593843,9216780288688463301,6508913229984259445,16893944473468638219],[4343731166540374562,15548374770097419961,11482794883305925590,10503955849823627437],[4762210852519722109,11400256565804648200,7736315899650311500,9025994073978703270],[9260931963442537963,3174298197325979758,8310069325022515909,1127079205503223098],[7670050504191084362,1476462062121130664,7993614259296515063,10167751791431669377],[10791028033538748070,4109874439397604943,15979341848850862164,18261187895047911533],[11697277180110068323,12262495074403684463,10030620939404639532,17419393265831488427]]},"setup_query":{"leaf_elements":[3998485893932851289,11883015582609828576,16578416194075103284,6935082895640194342,6043402277234149722,5191584838866718225,5598251913289724089,2151549372428876278,3195672779576846087,13235864453775821166,11957954994082636202,15146987647720457676,14440382749322407067,7390201924410719465,3697691564057611853,17101783204112172465,3198680121155828791,8597061795432411539,712338699728412298,4367674085963384292,8655638089031638264,11617346590856550012,11440039762403169016,10038939770846036401,7187529700566948690,16792300740339014719,9748294247883948718,18359874353583228153,9152182908209471122,16752444674298124095,5948258625054215454,13788223095029061270,13820394966593254161,4875105380984756642,14856434768176316881,9754461894519641754,16214118963445384674,17695820619959445187,1981782950452232998,17480095858055115789,10034725044416280615,3671555624585958707,13304100423598338702,13045069165288149354,12647076982086774273,9451142677160836143,13554575084221377963,9036342506532093473,14420406486851760334,8274669509198251906,12224313422923342877,5683895152085486571,7099311366094824844,7629723352153798707,16886541919978742223,10536736356881270177,14451883986847855586,3873564077168526519,3227209745519545981,2160068980266957773,13936348101688206018,4635278922250607336,2022666327934252696,18400963971719105365,18127379999651366072,16432670831942942255,10493480581522749416,2012722484141016735,17625161587824914253,13499435755263783383,16621645096260877200,11470496244865907506,3407669455688242032,1577442569913132438,10444446820418031120,17487044525535617128,10451119535159486241,15583525194644682370,15569892339832526748,6525533049530004013,12310346499896308367,17471309408144347574,5350131523722423458,4854917924420688535,2941320496181986695,190943759253100404,15599534302191733717,619562415531307461,7310278110283007056,3595225081935059126,12597432645437392726,11596846969999661657,224403745115993185,11099678927299688290,18055344741094870957,12227023322162300717,4749757652556691510,9599532860337100128,7649052185154619026,605968145183150013,14034337630650445619,2154078702197111639,11003240620312058820,17821730452507356347,17405135686108472215,2417040393048193552,7139623843804895890,5877182017444332603,5980230685847555452,15435248109087947507,10395421443627615799,2933609137526459625,13119292408350616066,17131522222668503540,6403226854145041515,187975570474654706,17398596704085817990,8258326596435945713,4798423312623184108,138764465797627824,952816689985181967,8429235058874975649,6424241820520173583,485612253162428941,1481847505290861917,6112724977102343488,9171822909018791141,12198081917221494234,2149937162215625309,15434959051627189361,2854879114030283604,16080255838454067400,6668696673647118822,2105376015869955006,13936963500980180040,17096021188329382426,1702927511588765697,11045352620481697010,17876670294374341555,504275582755561341,10469348636925736892,11214769989385485591,16799494208867557763,3582443809460675720,12042710874592879966,10548161748697554157,3223658709347483,14279256582820123641,7655313736205750044,7839197381968778276,8660733392322734791,5597392879568131311,3563579578929407863,16822600730962497294,6453595626492003823,17592493557322815964],"proof":[[4704641943609618707,10404044077077345822,5567494576487879841,10419000422941071924],[7651692926788918823,4286528937477502435,8161020306722751050,5439851309372045069],[6804481919416834784,5425875625548012536,3602400001003725441,12690740634141138183],[16414615327619554191,11345756664361415470,14527102577574495044,6604905796846701672],[3088483289949343317,12521295389038551931,5896878913933579056,7836863388756269285],[1628876749236249122,7408215101937095733,12886086265618577545,699546969222674250],[11233994381957980729,14889100861391300805,8169136522751651206,15185788753579314772],[11212191293411473569,11961782625592106561,1881616335780453337,11786039283223029714],[5871528197191969879,17148369549426390161,9442286169831320133,17993295854378298497],[10944355606631603956,18244664955806723206,6413297613079216248,8621464330438458980],[3808738117002340780,11535002723835477319,7439329770047875554,15428178027790971168],[4231687067948407733,10376308275091625563,16223333197804824521,15135947993412645996],[3473588446478231444,16544495152316415743,4133083025666029676,14210112065278219993],[7335176244300350959,5005477121178585220,17183984935017323443,495489470573645480],[16264160496517768675,9271061522385427981,3226131667032249205,16037666003240219664],[9676647294001563612,4587545366509394949,12033910989332946581,7226820379374084328],[9581065928976518234,12135839458439982826,14501700026775568689,10922824617600197260]]},"fri_queries":[{"leaf_elements":[17023898770647987071,625677898035619683,683386068250480581,2127742470673987702,9707826957764363036,6609251239389854767,18191122502818449164,13349116925755531360,9401356943833610517,15145966852140972331,6050250559450295275,6066261867904871217,8727289534984361716,10860198695907316801,17370981594038499879,10802037213511015565],"proof":[[1651203955798449263,13531627272631066021,18444411835396588656,9334926655261382365],[15561816435779306287,13575230503571511033,18208437286761366704,4095442333549030272],[14503544552877828392,17124974731411774749,9675220419936771509,1482438611625034704],[4009271705824549894,47748832233671186,15946511689223411595,16520287301758879317],[11708432845316207198,9923482627567555826,5494481246287931897,17928903564745120687],[16329031972913212203,8915590994008296650,7749693226967129532,17866378867421670028],[6394292866521747707,349873619328541707,1981953207737482756,10919082014524409468],[2414110187012837301,6873059135027892448,11338458957407079028,6925835460283904143],[747444670386025747,2577157493345571593,16738224592076886659,1090938125532656929],[11400179580368420578,7328792023893141258,8239760104803017970,5418364011972272150],[16466796997655727502,14104073446516797766,7857223128845358467,2827895396410865669],[12398277755984637761,9460608937147350399,7196091147265038573,13346471787158328021],[15005966612007360400,1431977922302695871,1177736259942994653,17400996889243361556],[4013925711984337952,12808912816756715575,14647408150579817702,3065942723487455518]]},{"leaf_elements":[13992177181277202218,9654877727734393378,1242364079598485149,9414082409252601054,17191758887318481847,4836343255706568342,2536876664171437870,955937144683615752,11926261908179135054,15423672314823257986,10690871104590333521,4199126798840205507,3046214129296871159,16403238709590483005,12609937986554731097,13612054762559642105],"proof":[[14068773914899631721,11816600664477957513,17270444837954321767,6257883418346506360],[7753082078803896207,15724452427367996593,14438939094971885201,13236679498668501856],[8453410351770008543,18292442860664632348,7606595232095574788,4863673788363254002],[13105393884932559933,9413364935710952110,12340214748196631842,1863104832137299457],[15050636354848667324,15532683189688504455,6778482283519056750,16714400662342366428],[7490618006807066568,14586753937068003023,6225944725336917271,4731653632269086479],[9455412045865413283,5178210602746360955,69421045725144328,15269834097162847614],[3280366836954143893,10326769593668636542,7755063953294749401,2798054903362502041],[14946590403716798176,16368745312715393330,4564980359062683843,7613405144591927290],[660121896653698508,2615494633143535926,17865241936453067229,9659061675828751218],[14386605697277095907,14780595627292032292,7787645265485481351,7681369631244592202]]},{"leaf_elements":[934570796797471560,496819399395952253,15665993691000494808,6958042415559317529,7114999753937263819,3275377975379402089,11467290254947473181,4880667991393309676,9455924831206370034,4356218166991984432,10982451124487084710,1253115191185597077,1725983859351994355,460532430650442746,15782378461038912361,4380502867607256652],"proof":[[10580727160025652657,1528339902283629176,11373611902543063182,837033237025322833],[16471120260275724879,1385514716260609640,12771153238487234567,17710394240263473986],[1625136714065657,14362112203349561009,16635345038316304605,4447344876081460921],[15716007407395502196,1827145627234250199,2754660725418383452,17787898689147455497],[11751519032020799334,13573171038593233188,7514566182225350493,10037279570837211522],[9533751165966520108,3265459692097438872,9703000926270708323,2446467999332885585],[5379444491755980401,15287514266393012157,1126692829345639492,7193155467476189195],[2140196684590980130,4475900447607608036,10467238145322070967,6718390191579177126]]},{"leaf_elements":[14231033499191237827,18152997614806513150,6030138577150915847,3799483195828553075,7196060941001153563,13336580697169234174,10325508582249401488,17114557962390607433,10378516215677625164,11736578277657878974,1087974718674744566,11453673205274346779,12138748578212644395,13796876278046736121,17084900491001263305,13032595568389581092],"proof":[[17262951685768878525,9005168044520825699,10797492749657132604,11861848539951363719],[15348225373668513403,10678793635484479457,8931877108970987682,6247244011777018918],[644725609120860967,14283313690926225141,9095430792474973801,17095016410901616399],[13847260915943289328,7231088768512174588,12473270287618164047,1468883089539587837],[4058304179733633736,18279683539181582970,17086072377035853914,1947585076045058930]]},{"leaf_elements":[3221203812947425954,4776480711736028486,14854471758325003586,723394777628576593,10559113229382962286,7044056609319450609,15678065343016711250,3676117961452887078,3469857637292270309,11370187252055686311,2690063810280093633,6876217586987550217,2517539040035780845,12092852791791718659,11508306557774896471,3741840411611553812],"proof":[[16663994794023663320,15887877226693521847,18039921424950442736,17468433594623281691],[1459326226627952671,7768976976853534276,5200236173962639007,3670101928990175113]]},{"leaf_elements":[3103352029016043777,11936003578925779291,2481494059698405049,16760758113560209882,17943014902864064829,11760753107849584284,16263520714716793081,17159242401050750845],"proof":[]}]},{"witness_query":{"leaf_elements":[8905597522411157722,7862252043976774187,6448300052874086648,15644900078671726081,3133466635732892694,3231490045762748507,14819854226529764455,7358825673140836488,10451799887165021227,4422851590067486894,1129354542039587172,15073822958927099643,12257820595464848304,11942640112017879665,4947488957357257273,14074178155994621318,13758628591286652231,17635173460095960690,7869338304305314991,1461052480617617294,18290385303137370878,10244294036821031205,7641125472393314170,9072169548067298303,5789045403837164575,4900829865590025103,18257688830638562346,9928400714225681247,5024769408963689373,6919853157010647315,16362977294735472682,5040339221089471873,5125319168081501536,8867248193312450591,11197887014468038493,11180937966405842832,9420561431712457434,8824573338560658026,8876323810639910565,12899954900140505612,15266714321746329130,14916396021233543674,9927449858191860545,5107716403406375636,3816587382036575762,6024717810479965684,8922934265194886026,4782901993489158672,3202066345152682042,17164837167576408672,12229939042207977475,11065627186537895642,15521550528448944467,13587832773589956565,18252105981764103323,5783627522329970460,3623819894074516134,9437313637414167263,12976855899679139579,6659194813080455729,1301860824465865498,1755698358175068956,1698965243782194281,4414589342441076681,17509012471129382423,2408081991598179501,4096447431922599941,15195655702092704579,16532834957172628576,11416980683296511139,4000462358753466867,12591686524195158032,8080871875035069154,8575963455331574570,4926190732915859780,11296750098664572441,14902181085616662590,11225425595801169927,14123909835822540527,11966284327913666482,7171677366070834056,8071061991545287369,4472236186476018727,11018009635407624857,3606587528621078003,4842292801161044802,2929730719086687134,8096183967935728555,4465465611753226747,4226756444022559980,10849071507495611621,15943080956764198863,4388345854292035092,11568820587000325468,10882582905257938106,9483025030454527594,14409369332134917893,17650257209175316606,745635384908605940,13283901803349495626,1110934723790720846,16170218199489948880,3747970939457401198,16754945384061407459,13720377838443052121,547449486909926373,14537050489956458232,11253524690358719499,3198071767776438994,3059451828628090655,12822681958130058805,12573103627587824689,9611367170035028954,434349494549159224,13300101637400230384,1071794547614767340,17351018431372911347,8260389558159346192,5922907024077855776,15629310411567066302,12720119185160379511,17219749074742465652,2889350504790461988,12571314902862560381,6146728430932997888,16802056140216147138,2504006690925074779,3357088074001013379,1268194735713047350,167448948157172779,13519425913439698328,3813477427971749528,12220410644057787499,4619759911373869158,2166434742946924993,8140706788596958823,18432060218075975575,1961498732700828210,4806493097265972201,13473900736656547357,259838619566170168,15608828594236098483,10206065246301737983,3433086259394270829],"proof":[[13218800270114549444,6296736687643193960,13326180665637398179,7242692973064816917],[2811389141135969061,1314954739379428713,4526371166111048043,17606442275179103466],[16436648410579580692,17116894625184457938,14289158215117177723,821752740696069826],[6289638349834411137,11274412761127838957,10530084169153335150,5352841718292560190],[7937210580940628585,4822759754993901523,12528526384280183317,5306087818017099336],[7786753833443333979,1593338773346106658,5390348389652500613,5355369135981676659],[15457881358539716654,18215565596411151035,9826632210696877583,14022181886064285922],[9628725374088103306,11675979372812455330,7970130530753619029,653208105473723844],[5920198958129420509,9647667495541235621,16962319019840032332,7517570701324079222],[5439000121444629963,3128963277084391739,15929936839406527078,10132725221364750193],[10670954624360155651,7067338899355518293,10507325540364875094,6206558691590447674],[9006134238257798142,8903640365300174339,15735092679130190268,8368976581873511850],[13719700680319148770,6391147310774473129,8541950467369052252,8429823802760091263],[437421618044709753,16425728410163267465,4098272564559904988,7962384917249165811],[10501895538598481717,5489495293732291623,8804003625075038949,2348206231500931279],[14318865710282918210,5741474211368349158,12458935003719419447,10294143874918395069],[7668237077592825004,5957116417149945187,16233895935611871800,17838538969050014477]]},"stage_2_query":{"leaf_elements":[136123727278029427,12556580708412097303,16762784673935272561,14245294503388756884,14821252118035159610,2591743841995532637,8881387079432026805,13560672860502975280,12687183125533472259,6613919467842707615,4903495377530145795,14948930349860622168,1680675979110110031,14250348296873904507,3981929373802545964,2285301728343761871,312175720715628873,6338463896637900675,16294781786946093591,123513758015555116,5727085293853475540,3398722210106780320,7580170532604153887,9060366335594634127,11407229428838148078,4302591579086599933,12039692208928881717,13138294751684565024,1085239935215237527,7009820319471343906,3562231764250048823,9108138598342865052,5446080196987416705,18238518112293870750,4524211387688120530,5724426673317419402,7458899333562772722,2722762241325857853,9004972921790799662,708283541695909931,10064583784079837930,14692336551061528994,8973519816531603544,5768353897969884061,5100747832907202132,12954401678248595728],"proof":[[6288476013827132368,7438126991109259407,17485976792649856626,7710368058227858351],[1678025028070821400,8173606594979060987,5072050358141168164,14579157736379844888],[1638175202686468431,1897139489709207920,10583577455513735323,5399289842850950403],[3729802695790956743,6193666554888647132,9338493283917752829,16545828456234635694],[4834445651515124884,9370380969307234613,12234681955865501668,3887758090093852461],[14307135135689674433,11417951759573516070,5864063976337152779,16676426519104568706],[3545765639028264400,10671450695314756247,9304195663590861461,15713990276026138456],[14503046580732506601,10552832859431873107,7279762764453469550,5578525231923926374],[2023187592182980628,6946850866394851718,830481990352916901,10675551685370377577],[7824290703644788105,13204168621565019769,11274813285824737879,16674037343636657275],[11634452178167978438,11779821776544418089,11484691179013957328,15087663376236373565],[15896056889509048815,14584253674638800714,15630071326327355079,3307704176788053468],[2628152504502725978,11386942604113278255,5716582630262885894,6452556991727496550],[2573007268382025329,2772617492525853406,390288181537486697,648168437047458777],[9682289933051252600,16852380091689185220,17955125068522841286,16135836899495162084],[17458482284124265712,7636738432796604739,1329449607180233240,3153295355585276737],[4282750637154906697,11193865276873436640,16027026646227156219,7229065506905931669]]},"quotient_query":{"leaf_elements":[17679833094421242926,2420318591582137965,6217077287437543215,6961492950714326491,3419359423480560803,17454262755878107479,6155775500271839649,9740858561570025755,2187891075497436202,9493462245987536064,17127855256758119806,16790405798502378076,13250996824491809190,10137381439773780364,11012454694873929306,9212992945484137584],"proof":[[13076584600560211321,14212192897156589393,8437426625703714471,628001790666231490],[5239409540466485560,9541636621301618819,8150907903820322027,10241355646231369463],[5122815092266727740,6457661818604473517,31314197891916366,10479871897168549312],[14082756491615483342,10232437711297387675,1022784296101486590,2182091988429443789],[15165818741055965050,17770833018553989628,4302250794474038796,4852640532652528636],[16748005865401538900,1337957140809818094,5393115381768569186,16994146770218055446],[16554097377246078400,5039313457375092115,15832799620307998064,10104000663506912779],[11422524834398294779,16246716657509968513,817675541896378606,16925778352591143510],[18307043695300121683,12267011093989250192,13824029291689543204,7251661300465214308],[437461969933882953,36637526348125119,4940185386210920693,17529977074755590212],[7883318889504085579,13519691718565839077,17687916248850613821,11966966319256763077],[8080375745920311954,17413316568796273733,17810999027441492091,15233790372393121716],[8168958885687956554,1809754907385263983,7374113485381909554,5717012512219159863],[10325076017043793116,13011196047567275855,2042328390684122023,6997392016414586374],[8952982376123489158,9806380777280906804,8090804364061644820,13729315972386126005],[18338880881081270581,7670635627058739926,10769764012749354808,12962823785062236883],[412161255135997019,7426697135882287011,15407766786379248748,4603043754552020108]]},"setup_query":{"leaf_elements":[6772692277968924141,17528701297880060356,5766643487893530078,18346136182498372658,5730221056988359599,5708526544682528285,8832429338833733295,5348571935018742381,1432719882114239189,12711694980990625053,10168821817483285115,13082041270073700598,17885543346792922953,11326013001217621483,9287557408487858287,15166802672696752016,339544835408334579,12303438171635953491,4421570801984242417,773531064130457333,14748843588468426503,9600325741291633303,17675457894359648709,6184504971785866256,7961422101249840561,16377224297249050429,4324401040784677576,893682629868987978,18238775137015309608,15756092734900345675,5278167125352989117,13643581834730737367,13341029072370040873,17628308119657729430,10639682455878798535,6699212670813162060,7070462687015509459,14508006379655637648,9371836052884134377,13908296785028233657,2139243569616704083,5490086141949625500,1783885505750232973,9722896420831047784,10393893290746237070,1217085788201969615,13121295894861215454,9267552761357547129,15245482332054633360,9594227205395139692,9231653286825817834,1800518056805095460,7831657115824252728,4283032116308425506,7992236906800657513,16625087049896265933,13805093726612857948,12873684429423644179,11592554872748855702,2204902828950120722,15891380447480853543,8472045138136706484,2000646827699570506,18130760977630782967,3925878849853232647,3112091757837574025,16056201993625793008,5954949000547546255,3304868422038911631,10649673424215823083,17863555145858241349,10109782891079194532,2174980065294285120,7854279710624103727,17853231559730120034,15391019233790270157,15141046145590217229,10358431193846475945,8394104770796388186,2987840248657535781,1076319688613332657,15446797181854120761,13060983401350264922,7754438987578845653,631548817707796310,10623303632412290686,2236296602046953587,15445317342021957097,8224038762312045178,13179712362426060197,6451023238416168833,10179964263708275448,14327967842390032527,6119018335234325213,265049307187641838,4847833929585777990,2752766699200227024,14946158860928191485,16633368717145482180,18364244163179070419,12469445943754294325,3369126816244329139,12244835093549083716,2096173360692618904,17058422785275307071,11518404329293468568,17611091989205297020,3625122132681523201,9121608980962056531,16308621913393272552,1488551912153949307,15082123974191853063,17121520401212550153,1346526746988673596,8768842733353238416,3835355301363551951,4014040481370433553,14644909936768365471,14095705397442454665,3882865075362035088,16755457519407660301,6828757639265247558,11485006045782460646,10542102169581966454,9392026301823313178,7529820281402520199,129984122693668124,12907988692311259587,5436930908002340788,10568419471385960118,9302903949158863206,15108634140827653652,9243212677480456841,10090457549336683629,15231881410262763151,5630198345589614306,3006425564009142262,13539612730985524454,10678391888063722150,15621415600765383987,12812416708214497120,12357979781184310559,15070661254736795008,6935436832897147792,11513424738736009529,4813659852951674283,1022380630073189078,6368063352443515349,1098549213955809903,12092894595745339792,1233560448221141485,9709502479039764012,8164146196112582850,3846062707888620172,9263031858049170820,837336013346573292],"proof":[[10412124692984824682,6206418427379531463,3973576783620130357,5698591616397602951],[8082289574903726209,16901525895817983327,17736790438357249291,545766380674601735],[9451916715852926139,11724072639324155362,3675816649901218756,17669494207572943993],[1850409839241852719,3644301213302072719,11610892742114437158,6979895492645275812],[4671073788197235755,18054737608942596046,16065164865383699737,15586585365468273526],[4434491182357113345,14879906685350021158,6401400230841762405,8366824102267861426],[10441442302793928270,6735478479312419024,10365450509125147218,17547274117805490694],[4954852901938785354,6586751084309026111,9614796915124936486,864806126848182143],[13064108132151816122,680594366912728279,2511367644970034109,2744847026217184846],[3546112014251004288,854500529601139121,2107205127740302210,10566686476163738852],[1832499788137788154,15847776396384743370,17731484233182307738,14499920790281898047],[16735626584940643707,17384775727652388639,2435380560104464592,12003530635685917928],[2675678120633173975,7394789645580477317,16710951907895769047,1839789174373245749],[17027005821994123986,10928712723055902211,16984552371661192494,3934720495504006996],[8178359739216137357,14977204680214841025,2424582693580705030,16899685035701547896],[1539699789013850388,2981073122727877110,3812085800536557924,8797903769238194041],[11103322097618702733,2127780295349214531,9279168850811705515,12312144320251496219]]},"fri_queries":[{"leaf_elements":[1860877670997664994,5388408102207721066,645564047043291510,13062254277282891602,7732043420586313422,896456324546167199,11785239564275583706,14218569416869744671,16262776470275862638,9630670076457665255,6554144379413533307,18185014643211170378,2456102822570101120,513693580970948545,11539132629257697352,18380822760096465087],"proof":[[13358623442757756563,8833430639829619718,16929258723719426304,10331575581276378782],[893240966964085045,18071177180955932480,5520122654869999164,4135288512058046968],[15564670884986013424,746458258478026493,5841982473776905134,2183190940858754144],[4084115577685444338,3855896125370832073,16864360829804221487,11819523798010682934],[14360507787173625692,15103430781452511144,14863935465617879117,16254320162873399920],[7006107009317077067,7583884724038132042,1796944502238434411,14680289978038813044],[17489868594774887088,3083267190404842817,6344772760789227520,13270390994345567170],[13675734471451540189,6533192206661435073,14307218537277897055,4114485087652107803],[14302780209286406486,6431481776995227673,16466989976861076886,1474302377512116828],[7839297457140317013,5006906433647671358,16016947166628592540,10183824298700344604],[7668575369174873113,11158069251303271663,4890625517417480552,5415882827688024458],[2062430009406765046,14882149576876536375,16716254510975338811,4771002468652202279],[12686552432373382343,12661217818922331666,16156381937606103183,8925675043816386808],[9921314296445597352,12607643182737737336,924539792316356819,5516451865609828541]]},{"leaf_elements":[2806353579595608838,17697797248991142260,4549965139711855063,17393361268425603195,1647870165737643151,3910665192512855614,8883675062807396175,13159617595844401274,18131716796800479786,14107514044710704500,6951314280310417656,8041335120102881096,18323998058107964447,7236547191137435213,9813503635444970264,16104898039370953275],"proof":[[18392629468056325432,7753126343826676921,4260559144048432608,2499075254262453002],[12077596538193112221,13981512856199868811,16402169125577277738,1841482162742291024],[6587112157049282448,7731564071485650039,15871681300519806000,6110605723594968110],[9930844348382067487,5323109041951656577,12981341530627876309,4901635892626782846],[7406882510546812077,9086450400879611392,10502354272921058970,10532037136635348738],[17158913474424017701,9161461254189652908,1296050057289614690,12143115683489294207],[2755805408186367945,4879133130798656321,10231348108772486225,14962313395693991363],[17654149838987726611,3680987196670491704,8197349503441214258,15128511221037919026],[13624171875195494832,6494417038506954028,10793221574842776668,5148472764418051850],[1461215653448981346,9570671307149000459,1348381780776465963,14351841442080063601],[1035045995526660610,13644572249133237998,11620012939398060486,7212075288884837126]]},{"leaf_elements":[3154606356187625355,1993938824987450538,2276944362564366962,13437895759081248410,18001392647234907683,3761444841462858452,2698884563472621776,15762153962503324210,9681126799990041622,7783261667165329627,10878804868589678114,4444080079052192357,6561802025952126775,7264496797771736207,16347746598130597457,712189392236961306],"proof":[[15876043189392486682,4166648989101092281,16790400443653925732,18332226616145633424],[15794060703060037602,4325132366149267330,4079690560537689677,13604665530857276859],[14823546471179124161,1125271272240555455,13285837090544440996,10066871303322212359],[2175034619752666110,9262256355291393352,17350193550267304501,11689941878895000778],[11380583862071755469,1346896608898203444,13434990700652744787,9470051398379951488],[15394349523973318735,17336711265823853294,10919515735340034835,15862248813783704950],[2066346422929198433,17499329808015624069,516375324508219695,11217097038680137144],[12226308802717355526,10631940034649103891,18308154700960691799,11171411898695195914]]},{"leaf_elements":[15246669479210668255,10695568160074480706,16938874713803992083,10268028877417390818,18349244471697362019,5214764424116031991,1280066323425741039,8677624347711614709,7312752010145422023,3982302598194040536,7033421544556792726,14953773683539159533,5984273550865748284,2147414275937356386,16499216987236392021,12113774893148705713],"proof":[[16090424104729241874,9097361746052723787,15653696932054791249,5146282865014927987],[480203577341113584,14696700868350960422,558929927097648611,5586435892258544776],[18247310342355240670,14304530206337163974,8987923828123951146,6377038653174527623],[1290425238906911655,15962925294338408384,14316253718990198213,6064324594049324521],[8537000182364138753,9846641187754615169,5492652896324277680,353362856001838847]]},{"leaf_elements":[10838168835753604667,2299991056132118220,6570445257786035080,10758647784950337428,9545278103310250826,8263509158155297636,14698272947932211536,2656006990466818711,17753523287766406902,3492226437675608434,13644330110393865073,6209949977396132539,2956888758551495102,2746828063378415803,3233160404410269145,9573768860349655806],"proof":[[17204719555083928490,5094144905267329558,16223431311138337216,16292513214806367905],[7146818340987684729,13421072458407422161,12178806875058478953,82408401134322510]]},{"leaf_elements":[12636509829310569228,1221361967083405863,5202005031054329410,3979567876410885304,1779072914486373873,17530329254161706299,17673969969636411403,1918506755882003],"proof":[]}]},{"witness_query":{"leaf_elements":[18120850112657673335,2202072261828447353,9988389395958182972,10693477968325612472,10065460227155711071,12380832045437542714,4357730922072782440,12607865756930158932,15980241134046952830,4078212840029837189,17483417626287440385,7293711228868062882,1609611449555965264,10992297245385352118,7188319798925755555,13716125808700421312,5266412404456307557,8556686574521733153,16309605746213047459,17651974770456490210,15137996523490606707,7924430750179941469,7150827176290726041,11110401630712139556,15994614509169571517,11647659051576084559,18281974903551085116,11079302061079150736,15257990434501349700,5323616512182030881,8381522629148725976,948040992145583672,10489949509109915878,8951149418707831134,10120716480231474711,7505506727864893167,11687409839592426920,14079653386235506618,9652049857042153941,8422960367299950022,9410260809113089137,18229369334512510541,5982706364347745933,2612229534966881416,14301782674836630100,6953066017466350244,12438359673108331499,7270797430841109269,6265481584517730995,6037258033926620326,17575822238197223126,14704946937486265469,10872839806243290875,16924724956017697169,6326425580073644735,11289259551451413913,931615345973246397,12465484195249978155,8872189477414206431,18042764118583516887,13918449613689524973,15459870552019850323,1909741371289236275,6690455311447750094,14462748058505731071,8853676257556203172,7094959269556179919,8493498202837654504,2778753776304698522,6941621826345640240,2966923013167572035,14666533261300709595,17288790999052372872,6484076277344192214,2950492127210216465,18171151707420548035,10180673485935719719,14039785762008502432,1427786310830787516,9769726288776693284,2452032780104970878,5319501495862313279,4808063356593862548,6130066825294198806,15250998236207694486,2105655573052211319,4334985683427547175,10985275360840512764,5341677684585358334,10879802256399923974,4469490548508494762,10339325639234488416,15804764284108891410,13371926643013090228,3467962228892208732,9630670635841089894,9705578828258308119,8709649416824161265,12483149498918826979,5880389432022364325,4339708903824829464,10399698872835617626,12557467165261799069,1384209339158099286,13980124179405691502,7560952652293482561,11133527896725926482,2944493593826572295,9126227849079463540,14873804457983004883,4684772727795107701,17911477634662200545,15056240897871656946,3767817761898176033,12959004461897622005,601798105405400723,12310535979224325706,9536653912765467026,13573539703638636631,4707430137765394634,7477432784657458847,9534957762528132296,4660376159847226166,6175867787541988833,11215552592247809073,8960170031008924822,401385590292940681,6213431942651516464,9316616562653467201,9724686395230826580,15389729112656479179,346779282301078139,10232841582369188904,6758289873237395746,7134874394273874674,10472080828176094271,12849905800423374012,13023260306139831149,11374970891684959818,1638494450637428714,13635156556230137820,10639695317693034531,6221392188536402169,12112668497820221657],"proof":[[17663259520038225598,3089942287646829872,11753607571862785948,226170676976676043],[9062713630020693739,1257367757213928978,16227512928313536503,9190968185176542381],[7108187761893681767,7698499185583413401,1212461881144838866,13873761629899876738],[11567527849133708481,14605209644006496772,17703726352059150379,2856721392213944279],[9416573084879188666,12006268602791009347,2420451024611437677,15727541995214512890],[16797744570433124392,1279564361760521490,7043876354707102389,14464983607752812621],[2966471202450313808,5695599702675476740,11691688554468974095,16537373384626807872],[2556168941951574342,7591931711051819235,4410088097985689717,14479181746389222237],[532680958595275366,14645330069140388157,12689155835316534554,2866527599415170731],[8027767757642169299,4609027724291529729,5005767625937426133,4565827827389827865],[6000452700036918212,6766491068913855796,14312873968646641375,2069917084659123457],[11132451660882260396,12700030244645250266,13312385249128500410,1204130498441350376],[6377208783336966507,11185535457167165315,2582001691010872816,6987904663951101170],[3318722789260821557,13420963214617934432,1723960784902408094,3132617332068000993],[10593578804212306784,9590944874138068749,4212487341278254657,13243196346763584774],[8396869664660839843,4046427985503139531,3237205386988153706,17721058804519625408],[4209660706171061763,15569665661657088303,9863745563231888711,4660762711415287022]]},"stage_2_query":{"leaf_elements":[9917851640614692439,16748592416008496246,1202114930847480494,6180725024280848956,17594825002670535251,18157395767859657812,13866130603342482115,12897636403095339965,10707766813416503979,11311618174302502414,4967003045280025079,9410155272646263700,328596254506755501,13376486357004654818,18037240191551538795,13869786961103064275,8810718414477805835,17847132947087405837,1697485005043076117,6360381164564319220,15282424322936005768,7010386033171835650,7307744403629700271,16769208356344084201,5200613058496522854,8736915985340010101,12493026003267594490,5058127893326435362,5954483284032866459,388218220429894556,3861465703645557334,17640305779590393901,2794688086181074426,2748613693247780883,3244453407139348866,12101501879936054279,2201648525290884412,13387532820775414967,17844723285574643208,6638992272662302916,15112216539064104969,12428467600851088930,17307767993247066310,2539456911950047107,833746002637001862,14868729355160112158],"proof":[[15620599162459299623,5788080195276857552,8044258698856585078,11314009328858831342],[11319049983291846598,12245412459617585048,5050575495189315962,15894318914056107903],[10923363303030417979,142657663518558874,1627786446081009285,14713596803821058000],[12454010434129592996,15752526703202939695,15527952194135483533,4392283236089254891],[7079266794192246259,11643257635156498501,12578178719309165642,5655765144230112303],[14590969749642798941,9896376910053458920,17859826766401115208,295526998633959192],[12388981721375296535,2129072645747985238,8361665537126775990,5318966035419617389],[2349172645552773903,6079769990301481622,3586151739947884560,2805910329620965372],[7648960433119694014,7075084356833076598,3108288644544196828,17511759294807500072],[12126192309167071029,12358273931015556467,2429513458259318902,5861015960934894103],[15381742028723402892,3402225182062511116,628468795528937818,14499411108973546409],[5042634484934762679,2893866692812539302,17066004051914474874,14419261090189003879],[14393581389849931505,17962259038859093025,16985012039963490865,5507950102793531328],[2111500825086826249,2983234331546904250,2229872821799882262,14619576935581665746],[2534013508880660664,4390893983114200810,1819666122795611315,8761907613634381222],[7646490553739686282,18029096139897674319,6731970851428661196,17512975805660313014],[9665480788566780535,15441174219972231479,18344208163066031937,3462579523809054127]]},"quotient_query":{"leaf_elements":[12933825059874087466,6610876757201761165,2267762413408928286,15754633562741716599,8580208598942268337,11894536016732675141,11248925895301453648,8338083489454928575,3980185414812673169,2342073269826689186,5448800684777802501,984211172115935545,10138023707469466426,6227875487990222891,9774257861316752868,2927345343287286406],"proof":[[14549031294978717027,17224485965841013676,17127072808862561491,17196425718143195269],[354918674128911417,10945317213126938211,10990228386520998508,14457636328052482308],[650872581087861471,6898491200230778635,5664886785620441270,1175272320832129296],[487964534930814875,8488067537068934087,10943922135772000714,4511499329468382607],[4532711622729908269,17113965363276354510,14269513312428302866,14427433498791978917],[13680552580360258161,13083064298385857279,17700576304302115264,11978834221645582007],[3229618483379845506,16245682132945249266,7084015973172980604,9329063075961664353],[450584258600706835,2759636118990786341,14869010062790623075,17476741415665151090],[5155952211464922104,8556270514671384131,7076157465327216081,13816642791874494288],[18435005959872202293,5668435469448694652,9074832687653745579,9230549394986377179],[17746321864821111193,3515769712823768862,16649566378456328672,6340871538384864707],[17937903170322500847,7700802109264123553,13524684745912343925,3340301604875580883],[13457582491622521763,1096954808311043652,1794319165791597391,306930781434544328],[17285199409592457406,2758310416695366808,8237193976256550627,6093240168989564798],[14853222784245912369,16410199900208906551,17141817584029801940,1083810476721892822],[15013675915085111688,2842710086883176632,1159327259408318063,649441773392074836],[7272481940847367093,12648501695579666994,5565709819533877885,8039129685255867198]]},"setup_query":{"leaf_elements":[6546190023957830436,16713803208610894801,10439648316795873865,5070781686075251863,461224075287406207,11435323149415781323,5339063107842989322,7828293997152259748,13605326970862468796,7809155054394626496,71790908225912211,13410518652757334232,2233857125784084459,11917387078872638817,12355488668051667981,4593569782385462828,3955369311740322411,11522654243806336442,16999119824614219534,2501607153514182861,14315749719982030509,17344779674498568057,13869069652765880581,4761740877507928728,14582925401905599798,16849709535020818153,17133139075156416634,12390498727564131488,5968342579957148954,194961844089578196,5653766886402100878,7453142380687378651,4079616396758357539,14924023820294538101,10598429189704294079,1900191130116904366,18091263236089440156,8870046497642464921,16799499345670692044,12902118968164079715,17150479903675777167,5795795189652203436,3350325790647275754,5283379268345622084,8362109505549783698,8959182986332984052,2285717790691157912,8324639420436035096,9035030457153053542,3689597700694177420,14224722284537353943,10399249411020804407,17819182139996196328,11243478496371517845,17214663823592815942,10622118607974829517,4463744685025740610,7212896868212713158,14633200471203819535,14371863207283970486,6559647699880869982,2535120532493614176,14961921428896570031,7617979551050821939,2251353871100181747,852776779688560221,5067190959058316751,16717307678516892580,263188807922956164,7538668185364198704,17547910542588985184,2549841899849532188,14774469853346336045,2973398921301963812,3089022020617452284,15937075459932785227,17477566872597754206,15434414112040796010,3296590690185712794,17843426861184392008,14936757027489575321,2482999019851778842,17306778093065011448,7581863627261829588,13345554191185389139,16848803050248000664,18412525415670566070,12911094837346347389,16084972166344763364,2619982536697154866,6268472607617824760,15767828170195778396,17463903663339616693,3182169001614618532,9711066949872070463,6684302419812207663,16121084474130868356,7951580188644178385,8926335944333335806,5252287107587056096,12283084668428059935,15432669841370764410,1591811615401591100,4405911243544677476,8034833833122242327,9188244659391718907,6240608129130434528,14773527679190862414,18112338750904154700,3580987742317627353,10048355839381318019,17106619561354376222,17759987358353841945,14633986945983562433,15076376246848491091,12436338155206721115,2941217684562168076,9145164619604430213,1185110388861923202,8467423346194653367,17868395476748047066,7500132357617063500,9608673434181743086,16729564894735799010,8585928459479419240,12710773637788240034,2739974449137972040,15947449785251508164,14387985584402579136,1338921488594730686,5735473549099854146,14676744282811198323,9622581136825781137,10164176774522548120,3804831455125351576,6512060846259016235,17388109926513978711,1117699248517089026,3077227947217875500,15196222990926620370,14290989908470528958,13852841689152408893,16540036966469831634,3228101142738458790,16790080786145295079,9677152484193595144,2074159760594962669,12218696057725100531,1540007747196640977,12989357800319284135,17590618853801577502,5764775746511136847,12978309907068810418,13046938358170362193,7552201896554646657,1692183081534890305],"proof":[[6691180824600207743,14532106118527706004,157327226491638277,11369431100345179877],[14199180132004305570,7413379431857785998,945171298377197859,2714111521394203798],[604275863688107883,13955731045107738344,17659725083245439587,10829832620248049452],[16850152055588391569,12745273127945157371,13217249884863616629,4600443928682331948],[11111827749727826010,7751432412948445370,13011741953517339478,10432873485847594159],[11384680358069226458,2617322636209480099,15082295488212055534,9682011816151575685],[15997996226884286610,17970764673622979675,13303933278135940442,13851194628253011003],[10725896724032430082,10863189478048943711,15598045526229792442,11106392370933367016],[5163932972041757457,18141445431625106864,1128427863697650146,17919322582966792029],[10105648151221163253,11605520092883957610,4673509233968694340,16927527064781567054],[11011686696598558475,251600076049196662,1633339074090832544,1583904099045571471],[10094679410073046269,4569438291536956087,8209124707705427145,4393808043568546015],[8934957188677338509,18169224408802927486,10778216288641272636,3150940845343546348],[5481882698971702965,9429405813677119984,12373528057427837688,16339504801477580697],[2778855892220175863,5388834393739426372,12471499031309919579,12654310588233897770],[4624068110822808250,4839714791712233337,7066342103347822231,2975375521514554411],[7509741136347436482,3376409090404699080,7106851404074101484,15631598259633138714]]},"fri_queries":[{"leaf_elements":[8445796026604785041,11945043365338769489,9560200952327043126,2184786201731876209,15193826077199313676,10913348440581784663,13378583997279521856,4734723952207812708,7055400732924306408,14133037916379028212,17745615253493244976,11384010863029253015,7111730049253452665,15312506126764498171,6246539505624019070,18156083167368134104],"proof":[[16755814658296271512,9068093896455848734,3899391673202129551,16375194862950924947],[7351580104658355466,146115284762987821,7106930940780104940,12210191816000691448],[12014743274322472635,1598494779429841871,7947353730333028925,13570511449609355803],[12833794408035890532,16537574006821834658,14991185500160423940,633278964490567891],[17856175050966943891,431231725329246764,10892400272181394534,13308074677065016152],[6202351507090020236,15842785303862217155,14771311767673211913,15232375906888967937],[17947713317569909237,9070343484603454121,8155199418860939901,13866750635096229875],[8855227801886821210,9108375030029535276,5657598002590242880,17252062559031684977],[4141968026553409913,5564092606461822368,8745593622017803084,4316938809314037263],[7327188530847363778,4102407566460804427,1054987757420467456,6492219529146472815],[8084442009836266508,6207473532914909068,17403328363939497717,1864263349879798507],[15010000374226804596,15833705053849325719,12285249782077649055,12385220874491185446],[15662665379730259046,17641414915734853081,15470380340658135082,862978176182788628],[8305776603362009226,1749975925679637043,12013609855588987408,14181483331819815011]]},{"leaf_elements":[8977762396814420619,12736179974868532336,14693552025421896783,15557777327410162820,17666045397031615195,15751269990286720645,12108465819347920216,17956061455335102575,6338370708687768643,14298259250732523817,15807574007554163081,1749278795001249074,468518921897905057,11835990564278932333,15526865987763224324,9633115199544385780],"proof":[[17528880803211097283,5056917924245900521,8424193375416301002,12552742963176309445],[16479410145959799310,8355255806420656224,263216267001497770,3371772765472137078],[13595333709001718128,5968031955947958795,568638126234184847,2013910219658340447],[6448635016658666628,15334974680687790548,9040352674975069322,15394199191825276473],[18366703750380224972,9137073519255044169,14140465716885585146,1572229265230621287],[14476967034540072936,18144625678554734116,11065664353966621309,3849395059252234220],[8012553520489721916,8721911134275936545,4610631596733989990,423370177788788053],[5994530341222767645,9939949274562545854,16239304287256498903,17906841975666837810],[758007960593770914,13785541215754450779,8018208474724663070,9288521653921426207],[6558311215278925279,15840445465967687222,7772766605136687382,15972645483194393560],[9089877299035286039,13211086284025128974,7103523635707635640,6143338230424736938]]},{"leaf_elements":[15056751157781251313,16908774522522736426,7508682051807281376,2549622036801723581,15304814962799157113,16221641313930848549,12776071171321987005,15285783109940484257,721794475760752042,1767203254144694152,17420062690715629028,92505493132757467,8146192149527278600,17257335680567538251,4682635131554270122,9072352267519959619],"proof":[[15931591451899131028,2848765484549863861,10307383079424528079,9221420617331764993],[911692119221152495,7240673798306424632,12271985000212629658,16744901520234193273],[15603267433509388572,8510443870349387086,17860904983854270130,18433516411396615857],[12219292277469065907,8308321877076151782,17193918982362317504,6001894734906060567],[4569229391948749147,9264270729747525889,10146356862857636906,9737716341652315332],[16850121369624651589,15493576925611962527,2159695954185854510,7345827141619488390],[11777973429637587896,2196711819418615457,6737532320013191690,3017665391597334600],[1523028420938813456,8383364562886835624,128497755588736195,17828178017860490490]]},{"leaf_elements":[16187081171866802844,11263564098651815480,12883308121129154110,8657987168253325102,12672666976306478214,7234295855891976691,4741620317183150528,11286475117050093229,13251898703993897151,17133561484860506192,8518486979676529746,11169071959032894341,1214693823439717056,105016283161821899,11144517728725711880,9252277016506905764],"proof":[[12541581298833999481,14400257432377595782,5312807663066934874,16762259780585024787],[12819693733678940276,4901835563159907164,4002611156762758758,15641780577613939150],[473471159832084222,12853875238854799722,3103619453438341861,3824402943842324258],[5022159673865659873,3882161217869360293,12737074131411203235,5268074348042876177],[6261215226436674216,15743080239327813690,1842525900557292747,17693706794580574465]]},{"leaf_elements":[8146988832432016400,4031049489709357359,7908697783540354457,1440221181542630175,10186283415753225149,9860045376790193298,17825662987895089565,11197202384009084836,7717196534648088793,6509681059572037081,9026339780428362777,797494352562912410,4842010430528115743,1984490153396563342,12307213242561184541,8486878505086012483],"proof":[[6054026354341905116,7281874755023425128,8092996408459971936,18161371729260239341],[13176973524804019933,16965119035393196808,5769199517311706096,9495579311777928719]]},{"leaf_elements":[16371276844632437187,5763442631456442294,9612659274689155166,12661874354129793348,4727490084259142759,16024340444489255688,11060965350812909448,11778191179252601154],"proof":[]}]},{"witness_query":{"leaf_elements":[12234138519240774005,5203408223090366605,879854897179202600,4970334567606078569,6116866712445881240,4067381199956700691,9532885184119567297,5623931956961585579,12524721532260180821,2028975318468940107,3477226104352013994,13632171630710220204,5053377834271283660,16513569715255929131,14129920664070484298,1599586660038759620,11862657531706135347,1095849738441181632,602918153607551949,8597684388061770626,13493927065250466512,16848407655663437134,860646404633082164,9157546438834327394,14592108322676348415,15448271701570257432,17911235546092068748,9805345387302789078,8218983230706240172,10679369351509011202,1386316934703361341,1963948690675299696,14917070534936999745,5957076081068583793,1942319979698293682,16640423066026313754,6800693763314928713,4172934440389703232,3242414833502163958,4143727350781468457,12291630959294405917,11192482093283970974,5030806196535065845,8316765832757835861,7809374788393421198,11862357249591664715,14813374009908213318,6029896497146420599,2145002043686370222,870149322495016634,960795081974952110,17792268954535875625,14209736078511441390,5177359308440349198,9045625375358837747,18413992895902617262,14469016401936263777,2965155224956452074,14769872742470224258,10248373979329371208,6169478044532441861,14194485119384603775,8354951951596407690,14970499275929193080,16556638657709530317,7568646646980370668,8858233776305453496,18439877075800497834,1249884522882510105,13107993194782696041,1587391144282946407,15796628048723381454,4705099758399700035,13603678060313058843,1726539817674345509,3203523467561804791,16179254804422386353,17250509955516655498,12642783636757667368,9694223116425759545,11122364970016455812,3868493085058055583,4074180428972875972,3455802556438259871,8222054459208877061,14410281388389827235,181714901332230223,12812082654992459448,1849868922803136208,15960790752601045702,10050493928413486251,1949176801744839516,12507517915124182040,11767751359281084715,5053976229819789549,7079418545594075426,3588230509343235530,13760552235765529098,3031932422198300347,6991369823690668951,11004551258554685755,7560083498480897656,1762013245963398112,4618370400304453602,10132805494837053183,17227323430920263518,9897789576160500658,3529875346076542378,1384047317042665454,15635669301112728390,17523013934020312150,393367606489774107,10754690930655048925,5792359728771664019,17300035090451822818,3959723170995025330,944876589962884920,6691092772983071524,16238954470646238385,2564056286273185960,12807811869068041454,757644110985758236,13040103488457894795,8180036262775290007,16351898762633574444,7352397637934081216,10352417443877338140,14620793394326474499,8837803526084385328,12519392222694661655,1663766278045961224,5263247629568167681,3108245033478466913,8152912258239968251,11029198117903127623,1917443991432878862,18089600807947556980,10327172246589394460,7036779469659607851,4712236720831258471,13515797538243159629,12295922749506956741,16353569863922346386,12649110123673959909],"proof":[[15190524323809186130,2430288775144595668,14592256032346771650,16015011153800888145],[15062193473238860046,4066443090993912535,6008350229544408490,4778254955246713322],[11957463854912514152,10361491487124281565,6335428264746640625,13653327480688182392],[11378551759743461441,17892981770505647101,16245024338420580201,5722914430230706862],[4857391409482474148,16276989557034042453,2577838438365477465,10258048575069305289],[11024567653672871039,7166977699519736447,2354478922729314350,16275333756810081619],[1526377981702937479,13062245330863331452,1630732778248311499,2102783396015458348],[12947184255394991123,4176456254712057549,6987507633576794118,3093747939469925905],[9141710654111892448,6064543331941794217,18166322548358573756,10522018090076153068],[5314675864829991894,11260710746465719626,13493005207954148761,3388396264735753441],[8010593851450754969,8790424738342847999,4144790575810244703,8156351004420962606],[10721937920844614334,3202872504651517606,9328233719508175502,4172904779604591362],[15150478482441871183,8029322704188586161,9785919068403295688,1608545728860524621],[202984742022642600,10230155860889783169,15501436747777945556,17711255359188865471],[7784751560184670288,11996423442728406511,1782752551996145445,8579091933030898133],[4146934872585813086,11413803922668765491,16437265005265623523,6712625173325394434],[7496285285731941015,8499315508080853662,473345457475729204,11805382148206819207]]},"stage_2_query":{"leaf_elements":[16613352730267245304,7129406709727007298,11786559432197707205,10689610981620923010,295834241749611816,12095537668951959245,17770025030762908491,8578943029979708048,4663167654132269946,10672888070479826813,11970109638864218701,1425764119922186307,12454989110508722890,1857369155419364156,7665392320274439919,18135538937034658111,15937155408024294538,12584166664532469231,924305957748943416,717726064136062517,15138410557861425818,3834826132024957701,5948517565825500858,2448234342244685579,9913949961771342464,11069734120296318,3680321399778635822,2548367615217380610,5783109919922719685,5242084243791410990,17417666995544743674,8966068784744926343,12354530760907908176,12576357316907925836,16442827834180124212,6611797292038995526,15822597606281147830,17401503990331160364,8970823740085729665,5374326427161138889,4251673341685722246,10430683244780618967,15259595685213378529,13207621763532186058,18271000831813521967,13787743573577925940],"proof":[[13403246239085854694,11145947294088953003,539247842672458783,7100639894229610489],[11773218146024428448,4986107020955004965,17903896393943304017,5253973926508560439],[7702971221597430439,12916608511869629809,6356820463666326440,731989638519854159],[15010937772644532271,8927868948833399209,1435044346618018938,5248526054900474939],[17157789743558019342,10635144022929641396,15768637132644402793,6216435553908370349],[14982892108247705408,17576172871843976715,6567764197443249611,9881587735189565097],[8804428451587489411,11582125785385958515,2766295711194484288,1058793065646771846],[1158346261109107968,5546815442566579169,15524512888045704909,8701899605520481628],[15523613372434090511,16537733003470854147,1294488796177616473,7082063969105726908],[10964157453809836738,5225750269135950699,11247627969082277056,12810370996470947614],[14952717161234078451,4712715817301164516,12163924230251169164,10820783494313964158],[8427040176639515583,2496631387539966254,5541580612703558832,16419249427394602250],[8509204348517933890,10871453817774557064,12207616438657563560,13357913556606980120],[4141435053031136324,8350646724490079596,12445971572262493182,2542238335058389877],[16970054402679479181,14725115415796546287,1821788169337132277,14303149078316516355],[2286994826564482799,12246719381081139382,4334338262466681524,16554473844655618503],[5142946944478076970,986898338813114171,7166217363221429812,161025064090010519]]},"quotient_query":{"leaf_elements":[8390685204913133862,9534974951261232736,9943298245878601536,11173413560400109266,13987678126961092672,11279178474043703416,7605529255774674981,12139873929844967511,5046858204517195221,6979762007812262554,7425110398400655132,8827736713617050710,11282341643884134736,6384426984542882560,9813314180166570248,10797509908439980970],"proof":[[11078148694360471159,12657308210476234995,3806786472421925148,16724131212448301615],[10371977442856819340,11761124064008221227,6585643523648327759,5123952601334331516],[4229155358560475920,157981873531754733,10256759215823961310,17340947548797767834],[1602074857771607747,17547864029413157121,1489557327437715508,10958655154607693511],[6967215464464113339,9298914569507873329,14856747715593651627,11873120687025842180],[10422255648236701750,16532990825829667089,8310039300293077937,3221279592326426812],[11998365024054835361,3685596620438785268,2874498846367000807,16510459834869654091],[939288699581424180,9694796102189737562,14039244839957158277,16846728729137994934],[12768505845763992422,1474696162158789253,10263450564083850999,13309847951100710170],[14318338616790780090,13122804389742807951,14285299048137800400,707844451993265274],[15585690171665951202,1245435610996782633,14781759762510620606,3898506352868431898],[4727184434986188443,4076560665543478795,5159250494986169706,11832205172102313295],[9532266632959694526,2070704443550493842,4250479907705782770,11040973536799819309],[6981453999934379204,5524185233110163508,15653648280891022745,4601126935348768527],[14459774786047474111,14714747695538424859,8110206515282050653,8681391839343562384],[16637929116839631465,13263553341713559061,17167228477952612042,2928214159247846121],[2446409545039768405,7227926324246186594,854384392011511427,8044654895162765687]]},"setup_query":{"leaf_elements":[16699164383291628280,14102020033786395760,9650088676018770098,8800898947947306351,12194745276841770530,10908414914875754213,1391089277026093504,10454044832481190153,5812282995839474673,1877606716414104892,9830099327154548280,15790509604044075106,8750170839993687683,18269364163450217735,3811454597444554596,398519495369893790,12562171021224744640,3332462768843712447,6712569581323466745,3672216413217618751,2158308941789160070,15354882372911577262,16532645966722867181,17972848453599456764,9883529369531378408,17870109942431989169,12583045615976946706,8335664159883121648,4919513188531575501,14819852499873689532,8385683588123774439,12647371110130957384,11468245447260233124,16429300399069847419,16930947247827745971,13770790807626596745,17324034701462087285,335550558573625680,6427686505373424432,3073836625076967012,1687540978207576292,5390040551705225156,9933492498199126443,6749255151633752471,9038762090663819300,10460427202001056232,5062456781141196179,4068957133936457805,3800591630449587977,5060318243207155748,10326081733756719380,4310483506466366469,17911664769510377145,16997230130624551931,945357447545477113,1703426112883065013,6443216918358577224,3170366167934902124,10197089713141305114,9420686650176642167,1532410791074690809,6777448268154895053,8990493685632014910,10325272638426078503,17118002374131176343,3910850810739640086,10908833228917416437,7358182614482949604,5840703618775242366,10842431003283261048,1198099515705370424,9732436571259899184,3887977351396024609,18208731116071512635,15839890038707538563,4754114903485666173,14103085511649204153,9566431052935483757,7206742024492544281,4658576294932755139,11105010335878691187,7992703729030846830,988660316227625015,12196668599037689771,2714485756368105509,12762581788765060381,16334620252296473087,3048761003519215344,8431434549763850098,14940189167615106400,4831016479053914710,17463757415449952773,14741228776048751818,7063228188114161780,18299438961053949060,17959944053918696798,18291630922526607746,3070482145060111768,10936916867308751099,8392045289647143568,17063707296824013,6218154319336524892,2826636260093547945,5676028837883750102,13869482816106627943,6903254523014125390,7667223307351312523,14101479549167511073,13766908563355052826,4357788533320487414,9542853114289138653,12510624120839341726,11965460294127858075,864873872630466340,12731902165449999311,390624410488857729,4687822079832805481,6650869908600676668,6655163314807012945,17988994746720619862,17613892929278940175,3215533684061659663,13710128857193235307,6856658095768934380,15033486093556164433,1662367914746981904,6294294866676747918,8102657413465235957,1219975525990835565,12306511755233696564,16638551753718872202,16153154108209000780,12498947764563974447,8666325294175467727,330086073012325395,10993434311986262541,11489592243663775726,15121792748360134944,1997680653909694253,5270972162869960130,10063211712402757701,12053186889066560514,17535770301375440817,10378489410866478887,17381860255464809651,17081724426993979194,14082491611888920069,12013968535008368524,15811317571592057422,4430452466018173231,4135052398642016886,16208608100259598902,14044560235078483632,14862318359525524583,740073534231790234,15596124692937338297],"proof":[[600213823098488586,2074582822565439848,2777037191536011400,3557485573087113311],[11198405371618243870,8280309167798722444,441053074594511679,2290171028245768850],[8459753448657869618,13857744504193413700,344087136122608501,4213379991976170383],[2584050599337373295,16475293831411003692,5605987900878488061,2694764601034172677],[10725787572477428113,11488989339998933648,795322292246430332,17812550179110555051],[16008626858024947929,2277061085940768791,6396000544524636423,3826856800040560858],[17830764357177156410,11360817138993400811,11351500406243218132,18148585669292402218],[1655474570987787550,11639905473106782348,3812614494459776689,7604543039438231016],[5307371553010221465,7756724243402109310,1660961708165688770,6698541811637319909],[10401882859368285710,340842544928306624,3876342513234865053,4457843047421535010],[1579089799403281471,6502145959685610237,4391212764799793791,7644066512069122565],[16109647070648329197,12509421017814577196,16816828683812373226,8725300778480338973],[7468719276587574567,15504512972269945136,7886655549450052338,12450013892562951503],[9919796506425205213,2744583778478870955,16691779043041378375,13470789256622189854],[12778984818186417577,10012533138721985471,12483449237362054992,7449333580142074146],[1079939598361570015,8642427234489314443,8435609466637694818,2795196955749707956],[605714035794641895,17662932137553231899,11267508260417819854,16646936890915875827]]},"fri_queries":[{"leaf_elements":[2858988493561870865,9891968297871782314,5272893391518951389,17601700239409595617,699418527976240576,5816768997038758540,406241422548828252,7724575634257283636,1690520866876696671,11121022274732326636,14571859414206717575,7395115847938358846,5313353836717146609,7082912476617770243,15083884202989614643,7921366577921367557],"proof":[[17652810185934042151,101142203681899855,4993812381121886352,8690452577538191343],[10734669566892795994,18441507305412194908,5214398421957258027,3254086875334228082],[4123635978106562200,10935523018387244979,8006611210481629856,381847685556336642],[6568286699999109995,14132958895547160961,15870261269674031324,10510391951709038397],[12341803485739283349,7874889150759119498,9991142388824831732,10565463457074599010],[5895618809559428239,2847328026415056895,4790937498343294819,14032215296876195816],[12378722434676714986,4336377084050128582,6099778176850312880,3572151789347361360],[8968527075291279441,3069391704156346973,17097769880794598799,18074527439303048584],[10059128628677972406,978281944117446322,6258179694486728113,1528344403373968999],[2154003225266018399,11163058610580428386,14042994774808367719,6005620865599443599],[14745740992522128995,10085499856624561194,40085382459133307,989119349028582376],[11376321556523587551,6202658985257505129,7833571134144247688,7624910880885988279],[17197698495030117635,2215419403352574195,16743504784072665023,3469723686803272667],[12622435136088813530,14088618649142867045,17064798125148309400,9557743827860148380]]},{"leaf_elements":[17175807784770055146,6608085766191513863,18089139647250209741,13571250937599484759,1254239647294042218,5659555282467734720,3331357720156498233,5758498157496788502,17079987945411689833,18328394350117553896,7808613597336117555,11452623202836005580,810572591551541223,12058026560553399996,8786135816551137138,14132755136948228248],"proof":[[9169379093193093674,166080613085923203,13077662821691701419,6934914580213812877],[16576284014864796347,5203898349652846885,1793391360541344418,17257446568265526680],[18241295563851211474,17639221415687121499,1182979570335009325,11640100039857723700],[7531617012513882745,7835880568979646972,16475494401388631271,11972256701587124146],[11652447837397673350,7754530250188842756,14449188691206274519,9021103013348267705],[11059132511640199600,5790085231875795469,12984580201047692826,4273908724400058746],[10834055839828292246,2333224848116276725,15926209741012735992,5821878704831957496],[1180288127739086766,9220276375279487432,14736409781736338126,10849245266134690643],[2016657672324022978,14408800636722975760,177804520689215894,7628264519973742109],[16555979434498585687,11710821205755729459,5652038497165172040,8282830142664516819],[10451027598658794289,1409017892025884115,1441116716198485217,8515659924305447215]]},{"leaf_elements":[9912506178028495422,10026530118595517590,16523263978097861267,7632991758044745865,14925545988762419817,701377832068197908,8444584437854509500,6830157045714985654,15589429035571918855,6021245622957481599,2039635436430268494,1248947624114019905,15625946496450484154,3246343406730286239,4168532761031037498,646899914325015642],"proof":[[14442942378986321983,1267441668136861459,16446760927159897117,5361533852386117357],[7447704063492016990,8839507244523951147,5570693660884505566,3090879420199240858],[804173148029147171,12747666029242454067,8471602854979626635,8100160261772971659],[546545472076814137,4433599460955352642,3164436788910188456,8589119110159027787],[7997757194626449330,14602104283278433257,5716851813770849726,18217423780507082589],[13643981478094584065,17918736407672050524,16718323211105475866,16246939284508955051],[10930543794139587389,9554308869986361657,17234575239037536085,4536468301844216431],[11283839272348111020,6063065441510746998,683150689620058394,17700376312019760627]]},{"leaf_elements":[5174667694368720095,16076150709799955101,18186395452781198375,3108073340713547769,15372189816915440867,8208948346245834798,4841905708019940524,1675473705753179030,6117091994509829213,8687780349970717972,9656712267153723303,33573765883812589,4306485839208433936,8727016542116762012,2083283615770750235,5831341872748583207],"proof":[[9991200076894687932,14612803094360749844,10487714947049493176,1078596743588521864],[15646820344248820626,13156504838767900437,9650145656106459656,16840250548106231193],[9092522145706340648,14722196523370037077,12880621846270297445,1322518335415327610],[1324744494246631718,17707813215942072541,16530794507243939848,8659701412493029251],[3577803525313655451,1801329653411590312,11522787841478459221,16021617102567237239]]},{"leaf_elements":[12766798318862983192,12161872791102292792,11380754369143413577,10480276433635731396,13519265442678483444,13943625016213242697,5284125657469801984,3027528827075361674,6247613008656775397,750596372060493244,18423349510416952326,16841099676862758012,7114443930631291962,5621953462251588734,14864954168617241041,12182977464947139504],"proof":[[13885224155690749503,861508918219797427,13783296567338048004,18425782869094667051],[8172119166490220643,1715341192280120671,9751970656955179684,3510476705473611346]]},{"leaf_elements":[1275295786118718478,7488170357634863325,4283449960128273261,10193008459420986025,4238185187837649128,6318479223569512088,16394860438500661164,4148361282767282169],"proof":[]}]},{"witness_query":{"leaf_elements":[5960795672334425896,4468310274311957189,13492346006676673419,5027779436751861903,14141485722934785353,6283264941453343574,17671018747034829307,7284961096510213282,14054838766031183264,11751303690338043648,14395323930563854654,17547602884984318946,12944454089518257221,3090697117723133345,6913265180154034783,527512269022669965,10633545568167159617,13303911404135068964,14090057019088449552,17239218662795245326,17558887253146616272,8608588652251847527,2591189198593228630,10974244438511261494,13469600214848285445,15224848217987015779,9052171953870620593,15774022344920837761,751614459336596388,10906597241464198303,16222383484394567399,1311077149211484532,15808359551607184947,1914526437010471156,3453524343993711916,1396654017484347068,16410867831543546275,11497866695580878064,4866478446253658810,15893892257137033130,12275516051826405543,18046657215764346492,5755313266609416415,12992616160381833168,12131452625178695604,17429271763179594289,15170966934144017440,13526320945838989590,2625446141481843300,6985242448163802573,4219012846642678874,7161514370885329223,12605409590658819066,12339375910438847496,3743928212052693939,8814221695744483268,12990863695212482570,80785120557108521,17589896847456482577,5328372054994899191,8830963025440801963,6664766106219304980,4142655224224725458,3198839694769653798,1178547221511095358,1016204545694444648,884402660946626103,17627654370685542389,11798936213688559419,7173149953674421315,10425998107700715430,14986874602010392182,13113641253363314358,13276910499459055852,7137890584700313822,1946525872331833291,13279532296953987093,12240885812723148764,8126476368537219218,537475972242509572,12100550077677966290,5648336610414014418,2763819663414458995,16912915722605559677,2101103417414697460,16890338489408143741,12301853124460758725,16754480450240774986,1964938239978447980,12137369047147771767,1257939791130689278,16872339781297937982,1365737689546874136,12599163715019912545,11960665929801351702,1745180716870679093,14039043838586349676,2466390355666235161,746030584828114458,16936469131249750184,2297864583198498308,4858692266242459697,1204151476628319085,17044860898427057023,18087786774419500214,4758328669697034843,3107917149706390745,13134293472057102824,11015316650460173907,166373455027363717,12391716399073666149,13726580911812466345,18275147314873502060,12053475549072212504,7309543990180895949,10472788011520924678,16226028517424650867,2092739668780919999,826534007017476870,5556177639614000071,1215346821499296619,14279460233702822625,13611427403954876363,1776253569323645545,17528709549083994242,7756476880035811126,5153170352660972073,1622139714661294539,1930540158350576809,2535489221502952020,4967068140668324389,5103154420486315427,16158565361791233365,5105503248209962541,50695067602240317,4124602440613925967,2805968262233901335,620102090518847258,17921289297383491579,13521724247424315080,3148919923967927173,3618995739170260369,18383139841725506902,97354743953883124],"proof":[[7060960563087906017,11374576537611015204,16987173869471803976,6404823084731509547],[18144671252539953511,17844482250428240108,14704788751879804311,5984475993394001236],[717208078994786573,7942378210580315453,13261474561870820751,13963889366121029758],[11409688828929353509,13839581365222444895,13949947814474148834,7617359047683675706],[11113769972188252605,11962280853986717591,9157862331434555099,16705063504859539201],[6616051996676251079,10320095991810808452,9610914794543607022,5203764813740663956],[9315188446232101214,10017853983497743309,11401147358881643624,14682316013742838186],[11683235988078107997,4225983785402751358,12716949983611293915,16854264600823557017],[16961153940947847189,12496715047381616652,2265123522980106576,8153910413759188649],[6774249695407695322,16254190957225199223,14274250827272416139,12989747593348067434],[16850069790995756358,8603718021401864818,1857511230385104473,5782788039516580951],[12269053012421966332,10136536538358931342,10692002870926572844,951736057360706210],[8510090512079553397,139144014335827284,316363419107304549,10457819941267041081],[5964268708656415028,2982608257027347385,18127813092266797393,18445447482958021242],[9237554099053705855,16568279526101698338,2781267282975776279,9775237465899860567],[9420332865811579355,4622499120691314564,9084399043824776706,12854986252812867905],[3401274946295047068,8424190892080195937,11580290105623139539,16275105661111298956]]},"stage_2_query":{"leaf_elements":[2220115183587533112,8660945042966379703,4807813257527010776,4974230818718272300,10793667289159067396,2643694548804565043,6470831923072442360,8124005088297166243,4870418146675505020,14094934584601124601,3870909916143992821,16876128797702674098,8167214880102132115,5460391392397553244,3966822631266558234,7636685440163094706,4488218012861092813,14838972825559852245,12145903235905854528,5484215209519995803,13649241415096214416,492727567321719663,9965065136246514209,3731996858172113055,7143011382678408958,9003690398891562552,8599196622049130369,11974440667614321087,14834584178921490173,10904559719701529492,10228379995078959563,16327406242691473968,15942426670328303982,11078017979261848640,2913917433245975879,16843604664228383434,18176720727156222968,7808897785051285513,4554597311603220060,9271415420147490427,13908781436074807045,6722924114618838530,16441870161769829653,717660160294642175,2461953505784619813,9310281061103392231],"proof":[[8779589290038560662,493208514025164276,1290269686901745318,17677571655033012421],[11205878764031831167,17283127767839065821,18221893488964256237,11670577741918923407],[17759212607405042150,16815792880431423586,16766916963386750789,5246712097685244599],[16835512250000593958,6924865196408001942,5840224543138614547,574558447244317235],[7003902359778017890,3474504915340555619,2640877179870240681,15737437167994704431],[2909283669006886258,2339146225652508433,15548799145295815327,14567443988281338712],[2963167930618050127,6146344285978463250,9108680497938357545,16613909582259203833],[1487904554547952446,11808967618597596927,14252533068767608300,1411632759834686016],[14399697480316466980,17674982819388253141,15154906677372741883,14409460929203546494],[5276141880462760824,16525437206616178669,11316178118030937592,13492903226534662953],[17530555688177139498,17305325431201503001,12892900825141841841,16419742275002568006],[11484009474127132132,1470083730738353268,16680602800871783367,11623781887805192656],[4834811840346460370,6095929151666123311,17313980188685133848,8890156325495617908],[14373585986759769388,13226941343801140846,8615572774725092141,4581041152681578835],[3946605776281468679,4313557575302496352,8700536389805859579,8103502675114645139],[14961001578562283387,5142262369149257943,5186579681044251245,14909593013194023491],[1943009159876413561,12861816066895743824,15774015485100450464,3732444378655268395]]},"quotient_query":{"leaf_elements":[1309946402167570803,2955418920095140528,9102859415848059180,18320600868966717709,10952601239100061920,3278655674245281542,1548424553789507337,6489625775014920922,15035361491796973832,9459280429730391583,8917333016473079341,17966914933046586429,16198752753746690234,12631212965580789075,16819655208534896953,14054094500781258121],"proof":[[16526868808222720045,1051998912265649950,14175537407846056618,14775411446814444100],[3855849032629334408,14960245750357486879,13202272442517399782,1845215013817288231],[7361756991216478511,11582162966514897475,878061803965999620,1765487579586277915],[3576541504435706191,851440043761194501,16604725739160943808,8091008697046616445],[16024828002694753808,7826908993758455275,16216463797730396418,10365814531861680634],[10539472371508086913,202998819238936939,183438145755396118,12313007313507501194],[2942682553898012931,3632698953984963655,14398680257539060461,8394962306193429088],[14642526358070939141,17191625473370509004,6871622788037256932,10233895294511737964],[1202692403751412526,7233337108607218784,4171517446932176937,10174926660622640092],[12940681156085811903,7763503033280375163,11402359654493816660,7077106235163855420],[10590296975517281905,16641235034121341713,16807961205725919725,14326186938537330912],[14386001115045535339,10851762662213557511,54255763336682198,8723117036525326090],[10343601533049269526,10189479201525899479,1940385022126033858,17532662534844918746],[10255509413615773513,18171786372834168757,743096606812244966,3320015318519293153],[1513209000652315262,12246189970716765469,1142870257796531216,7775891531003900384],[6730040436321217121,13059403003301161734,2077814071973998481,13095451059515861817],[7194083927807340288,10418393286838300943,6856990265218893508,8327449156721763660]]},"setup_query":{"leaf_elements":[13956664407971499717,13432346866606271871,8606636200739398705,705002838842307926,14633256801307879012,1001366729044358704,6548125982050029500,4998994319556420161,4727743605760582900,11374414043125197034,10017381003604528564,9191222756601748147,14672644665598406434,12816574568353069129,2054449634054810570,14821362537870356762,7167440049646948540,4646166712107547758,1027346962143197298,9747592374791569907,493503890922593946,15228715782930093451,12701020810843781090,542859764848281170,7073856957299551703,15861105387688903306,932691894169838108,12134813096794071361,13226333210045266558,11312007647182442373,10256776344013291274,12651243263092582833,3824720824514520026,2773938843293719167,17410545138750140811,5380174734900433088,12106032255798288318,3051459037692525186,13836598994208659278,9463454548528778338,280673501634574929,10019684373900964759,3766908964346483155,5553815904062325729,12991452629629518727,12013214411237714663,15849232973221466336,6917061202844201796,4641287726443741603,5391234348901917467,12081925854563355485,1931473554135354122,7633598176637589229,15326980901641218595,895996844000493771,2768843730933324739,6835877133689502035,14983576821549759695,13083959172272244972,17395020277192146506,18207060408669840958,2392978091526624364,4924182912772344073,5496800158606435065,828916807579830951,9436350413286873354,2069905360624203911,3040386834939756016,4429473329381042883,10663168838850881735,4833751174858083555,13163278961737357209,14298147072437555594,9172307551500885581,3771906919721363987,10888456480816642869,8010867277012223427,7926192977520915823,17088071399042720813,10807526488339165392,14467861174870424941,4850017203368006871,5398436779946877025,12676970020824007827,6282782346947318004,5312332497657553460,7778329804416476611,9868467975245046753,3028913074732166165,9658579530225234503,6951098686416276955,9708753035339401424,5908697864378099873,7240079895726319296,17504913811729590289,10956787377533126493,2123622083459706495,8174936137645038910,4708019607612699500,6589821468504951039,11104821165482346540,7632228239195116532,3670745544956927703,15474422567100408555,13721517305132939218,830356003473904829,10915445599389678608,14736689422608952477,13893487143142733423,2019907648391927148,16575091242737485082,8353018882587811361,15869790354168589472,18123328246234221837,14485726281901545441,3119064699015443539,17468683934940757518,6629701618094903050,5744696376200609632,13739177185004286382,2100170127757458769,2893979871883945851,10321442786511815443,17001571985407745892,3577628543551905295,16129956450468261557,14510756048782756873,6271657454193092523,114963887481997826,3524055823218649842,14291391205717346638,13246005228271488572,14535036953593375457,2864128659253485603,2822653557386312665,4899783904009902410,10571993418322373359,4372335797509724241,16863590061181610521,4833370870116922040,14356490633543372744,15749779252627624829,14810240608249084720,6760290989399996946,1689878719958201656,3557753687614992955,15969483624888794926,6577308154612007961,6644748112287146755,6029870233095401043,16364025177715488948,3075835907862337549,16266441900546507542,7789260338682279827,9007192435355845997,17296809894314944793],"proof":[[8739383855767308042,13118821984165067362,7790963132677186791,126186397794864415],[3274590325836983287,12098132686248630864,1025531758203323563,1013011156339885371],[15864998357891163010,12052992777205238761,7792615338602520053,9166814226549158639],[8027086664153472809,14947964669455947631,15009349265331640691,14790197708656565387],[16403244830720244775,12881481147477551236,16739880817801117856,7734135408399353105],[2143111133087453929,14864846531732885903,5443166168481213236,2321867266374908769],[3851036949160119451,13859760378696213991,9742357166248096282,4867179571574896501],[6781461571904042583,11413586396442641816,7618533642301793162,8827181949520676909],[292355536120509686,257007852473089517,7298008195083033404,14949749126984381584],[15316782114476468537,4259173412518243407,5475764012908601881,15419495714528074804],[3884673413391953434,17048641181087780013,3811566922551365735,15603022278018773874],[4567334385255971844,1639567090494254,3267017246430122969,5134551708391382128],[10463785441305190266,3652109028899440008,12817806065585798990,6704205892520121055],[1668565204363740319,4411411794858276558,17456383412627073248,17947315660081406836],[17019239756297715686,17854420995082206976,4145866395001690121,11648788492992991970],[9920824145006412032,16301131657583376630,10160051904981951901,5530452865049245361],[14683017277288766136,409482300754268912,12378642238663961193,4952042936790383930]]},"fri_queries":[{"leaf_elements":[2668624145312161170,12389213459877339084,10875953376746866068,14758917908521434217,1596799569279465364,2714534740459270029,7618903032192159444,4884711122371426699,7952390700655927624,8670520644109332446,1349219212326576264,16707732335998512980,2700606545153985216,4814850475710541695,18305898533214960003,16353774216154458657],"proof":[[12939577931135498133,12543297280880923199,8371927661502920242,507505750841276032],[2807706543008838799,11059284589998175902,14507578746869847572,10352757500488269893],[10610724582936597755,17501927303450583669,2708035929717036184,7889371005458892103],[13659330136747340884,4014171536868931157,5425416424819019543,16568714556982253557],[6769424877434840187,15679558263355310380,7849778127124426237,13224932873911921013],[15496533456909856008,5102883392549891954,8091675230063727098,406366970023097469],[7077390272289942564,10197626836699975752,14651928013769199654,3074923122272805123],[2373293367355911619,8569436948121962425,11135338767267116676,3065173177802075805],[9047519817285469682,8468357317428228844,3743490372877685750,2616622294642693805],[15413113037248225892,13481724808295038436,14842053594893558360,8725800213232691790],[13311546156468514822,1467607428547881321,4001449121521801902,7566466480555575528],[9741020487098191809,13053544365402694958,3420869874330033935,9088624945424041073],[631677879826893965,18013237760711813392,17806016106857295738,9615124885541408862],[4259394374024321065,17425767052978994711,8179526746516672277,18038901638969221100]]},{"leaf_elements":[1767633408753680638,11520719778731657846,15182896115302938047,3781503254843534953,831257794824544607,7545202914595525439,16246015367775839895,16080402744443513531,1088274411042708021,17080492917064218572,8672721479660515519,13587474501629800407,11893478680739738044,8192898443344230085,2005364605169802030,13254025511594960239],"proof":[[12052588009822078114,14233454880490476079,13053206753280448526,11070953888125480895],[14803585311996491961,5488670443790777878,13059811823618409877,13994150545143713852],[11710854110487725571,14908794789064027524,2748035810202935201,7822469492815171132],[9600848337641610228,1295866928641049745,2935184854771621746,16034138307697723164],[7508246041464125982,305485755113739523,10002241354024962325,8151247811254206204],[15230863987324972867,7950249668728291681,6184235179705201064,11310225070935063178],[15837704129272339515,15916767079238935884,6176354981637833828,3794969624395201714],[9564837109000988934,1226990192212308803,15763295951433541688,4058841415295376950],[7407185752722179582,3583188494649295533,149858038015292861,15166906744093798914],[13674945336663942705,14354992621533319813,5475031711482859314,11999773617730618193],[8980352979061308667,4598086631642156324,15533811750110744452,5517823221210662581]]},{"leaf_elements":[16514248606163011616,195241106740240589,14222815499634381044,15166160002596373438,5674052724399960779,4679286183296432762,15973533849375688683,1400344189098687037,2218587017000175311,10461532822684448145,3897731118774337250,18343484078750116351,18223555997159928594,10797727687165080267,4836809744250753958,7927839701388979626],"proof":[[12081882673178130911,4229090311159548389,13408586319998474658,3268921208315153050],[7798035889754515175,70120185539676268,17668829493985696357,2551984724255863291],[14077490584813277697,5731216811219494927,8648648498737769595,16859211915850574910],[11814189259007495636,105250214709309897,18364717852683354419,1579353199328195897],[6040787691940862246,12902415597006760844,5671733018671366466,5202085300179746636],[14591431512610624133,17309277624825473729,13056358497079918733,9692017970299333368],[15686372807665432581,11198066736475935539,14919008793557504930,14511586066093995904],[16061952923498168553,16842310330857708265,11456761709518579701,3208021872079498902]]},{"leaf_elements":[15637668410482702515,5102308161696374624,15435483517269318270,17176421582649373589,9655518128085528642,16146536372669472857,1854898954259493659,1618536415782987013,394047324198460565,14876411808826968196,14931922822160391974,17059595749815950855,7028086279182993715,134751051434613006,15783758586635767909,3721980997865096210],"proof":[[8868415139225543079,16456847029919614595,10960478527994616204,11924344049171087401],[17538880299414225123,9183298950698886834,14517359220255562228,3411075331691450826],[4892343048144236207,3983404964263927822,7424915040157663426,10303572249363541112],[7008702710324737022,6720471067042171407,13275666798379088582,10606458578082796807],[6342957419655092904,14172751108096951608,559494499594709813,3806044507701688912]]},{"leaf_elements":[5877864812842876296,2145706903452504433,18273069180052729267,17570618951407667505,18420943633002912593,5408221168937528727,7516264033370054577,5104730696085836488,8516470570027736291,9419993892384641063,14012961344136931888,10349760909632886917,18396344424288953401,10839429233194349873,7780725790045026183,16021819947987440683],"proof":[[17711655340670770457,4948081213775608023,6230293974577710174,3504385216397740622],[11944921505594949346,3273714288328913880,11792623587127901118,14297905018534565992]]},{"leaf_elements":[12636509829310569228,1221361967083405863,5202005031054329410,3979567876410885304,1779072914486373873,17530329254161706299,17673969969636411403,1918506755882003],"proof":[]}]},{"witness_query":{"leaf_elements":[8783800789704142423,5317815451861749380,5578938657104261041,15576813566830200789,17827877786875708593,6681883107847274124,6692494018939227896,7994857736806944914,8900922680000332048,8674932286176561731,15902380483450162787,13753748402283667888,6399030347246680328,5989553702719859726,5546518421737069832,10034754999817572165,2606444048875747943,5228419005521728695,14957485582653336911,11332576639152323075,16754742557387177365,12488610603706042268,16247617748325735844,5870840575512983531,114144338083935741,9516578911609901653,14574334001035757454,4713465709262876198,10591486317362484602,11664283162486445282,7163917940865827999,4811467853086607824,13478945115508340433,8539255239003652888,5092007921214637259,7191262994939572532,18122385447625177417,17198690706686246814,4675347653954809884,6277416987766522459,3639192264984346885,1253428814781223746,3478982770591831916,12758158287663451690,9937870103268825649,12585142378611638418,6288336262624432059,17727494142194309064,3863218949202067905,8700257677535335799,4724021052343283207,15034368104480634373,12617381326298602250,2316158719197831664,17405042449909217042,980279934612156996,2320512492320499082,2202729671013063410,7204335076340929188,5947420484241596475,6498927441019834956,17313331417987661238,10613200260723908595,10838982710815595350,8796721242339638454,3012226757178268494,16558877929617631003,17251171757131228058,7867372250218993485,4154990008043745690,10228360065218855066,7563734721830617978,12165501306314707982,7130600032734050090,3055708461736973597,4891399542630934065,6754195187464485235,12420823775713734246,3293735342764990921,14653492237148842496,8223727970070594336,180294517644164177,4002885299028148102,9507846451994641845,9471491430938249170,4719784493495059811,12086793039071504180,8743940394132485339,4080440847169900678,6203736078287035742,3320312174035072264,6766942139150679221,3234658188030779726,13436033348427388290,16713913493396275784,9663048693720691347,16001156115706715313,3446189114028058691,18089757780831223077,9082411552007529233,1386129991570516734,3081684527486451584,3703300994776738349,14102054146250058024,16633649364503516060,12277220566265834521,12387266938757889586,5494240294339265422,8438759877884021090,3978921375209323341,11321962907084015946,1937765285865026947,4255174512064732667,4850141839273589970,4819827266413525260,8375519134921589661,12214567693934964252,11050832924530298899,3524863389788287798,9810639695262864882,18018197018245344521,16529410988676055996,5907337676468596609,6077824316144981630,10904860569222069165,12547542787710106212,15700853259346125531,6956492093660420342,5763449945298569610,4781756245748175215,9913209113051852476,12308421710585129612,3082802484562611262,1515614987633268161,17748463798529094041,16666063690273002152,7233114187538703687,12696086950824695265,13770197223781896788,6580241095172600892,11956207822122021840,13383411882170762461,10483605007058589281,11375264506752019071],"proof":[[8721780118095110816,8733344727429615759,11099678362982755732,11173990758752633405],[1474313847377596575,4866031985896935620,16233015482806191909,10005068233684266763],[16559016521719432178,564110322355680239,13397446521574485156,14247547360139352558],[18211787331293329046,16970415579403215743,7587921712678931700,14877840451659875862],[10129733490473573473,8998636406750119144,6034737052084117607,7539130873948518780],[6266131199125225618,13630040771150755481,3770141962917753935,16830220202543292199],[8664964089370490335,5430186118256084110,1964341170536160194,12820869093441430969],[13636121722081363371,7211476075691327893,15646842615318355444,10035702097858568374],[8209621554567433651,4108695699600147185,3623774563569599334,10974290986747981185],[15519949731693458569,9037942353782915688,5514567648583518018,4623898385840702372],[7046499540222773862,17711766708640406085,1570239447380987466,10142390329816269938],[2447727420673796421,1115059691678600285,7965037187442079061,1430007384238646642],[2721130354134571205,8511377222515384585,5805330097834559154,5884825477301732261],[14570541469371826931,8105619315177205943,17726663575373301212,13803226630579596691],[4660572962271898448,9082544899590433816,2580316377905151451,4183227265128843792],[14564977802862828331,7107947054129761850,16319810749129171183,14624716937834000139],[5215536602320635037,14251933243871324531,11901504793503171564,4410319055582773978]]},"stage_2_query":{"leaf_elements":[13835150043028372181,12612836181594157360,2039753544986493811,2921219844515563257,9686048222461913714,4004085847523367203,7368345788296689398,1287821540226506630,3347815303175459154,17809285289126389147,17013935830262259671,2350807845211390735,1229190949679018295,10347697551023299348,16232201552624280458,14095541567918165970,8083569889346124788,2736122867950627316,9522647896723968905,7629877718583852352,5238608873372718722,657581083883740659,13281080704100404093,13907033429388550567,11924922476234490846,1710305778242994803,10609402747534063512,17027237027732441273,6249315477714653929,3866229628019358649,17093721301636437034,4961608693478621924,18008670335095287925,10571269579581008992,17436849316913252552,12742036673494716718,11198590905427992864,1193321990109832400,5345714065054166835,5051051039477311618,3777698994644648323,6857077506483815977,6876737997055715090,10820506040522277082,2805188591871334497,780593343262789664],"proof":[[14123355760200802426,9974443225123625416,7892476065424811909,13384329199953099591],[18367604706060122381,15946079346098917542,2668054008290004606,16510047455540659928],[863462610247318057,7730100686134166324,943367871800954661,3022564149211976898],[5667374359369689871,4575389711219938364,6140771630629393391,5154821561699164627],[2549877730423128086,12860582078809494336,6271120542722694802,1046706553998979095],[16004905278944841708,9476823612012107587,17445772025387755767,9325525075131063472],[2408470087231364044,12779037770022712096,7580962225274445043,16995357286935172527],[3066672822020187094,3963197301402358285,9541378354341886805,15219442132810617336],[3214564184311936393,5017178644808384846,7604843261474889477,7461646716488663039],[7833151679191060551,1646540819908460091,6562203347788570867,13691035737610736824],[4957465864332006810,9289845107692453233,12980654235317558021,11406224833360138711],[1295689991012875449,18293200405012189251,10460527440502810743,11156098128986750091],[5807011406833964624,3764356956133515317,596810823005671882,8477435287340830156],[9940810449814428804,12508990420628788792,7154176602446474979,17523096636723839054],[17317688702681325410,1087607947732887864,9182299176713639279,6767444272939131382],[17186565986145930912,7539552432213423413,11126468937050766919,1645715194395441380],[15709091770705664402,10049110614717720455,3752215127558376869,542242508725039489]]},"quotient_query":{"leaf_elements":[10264484830624969534,1775669390707216295,9108982125904254757,9992157680770315235,8478779656796125130,1658568844827458168,6944202200320941840,2957228633661719307,2221550450087379539,15608476397221309915,817371037081022846,15890094294490943853,16389378121338388840,12978751726991494897,15036542334480180878,6827506997887293916],"proof":[[7384212166569473409,1176156166718586160,16783700516561134767,16810237350837436981],[5540182665085348496,16360802322077984429,10624389020746174468,562320875578367327],[13857706333659730346,11814592773830846483,8331326756744430942,11013646135847656355],[2874563717993896760,8861299764715919958,13279523018370399140,4883891813713140440],[1925442964226734706,1641220976929296174,3941968704406727873,8724674572233816367],[7455340339635733152,3000177134325957291,11836293833733707478,10474017271755675625],[2728127963976477637,5666958348826081050,14802084821504158791,8152496511577049936],[811394192771948705,1584231845474430824,8173643367138467076,6305334177420724371],[14111536067826719000,6411913562352047822,1273395515883036492,7190622564700089900],[1202037761069117932,29810026263035149,3461933316189123391,10451680510050702864],[5329621710111545894,666748480975351699,17352329698437125241,10327902925821011643],[7646982003496522436,10002004038087505653,12098664229902093848,10058108332371680780],[12052807406867009031,13274651902728868746,17828171290180636276,1474286275420648751],[13442043211789165875,18184268338071228706,9097855916032208812,1669821466354760727],[5064888594784756405,2114198884652123248,9782266107182395241,11856690824309365734],[17096550237870348451,15771482629534505501,9337473033614775828,11055706582407411371],[18400306852838558706,238886437693955427,400059893464688571,13855449120686775870]]},"setup_query":{"leaf_elements":[15880136496463128394,6614681155877022367,13737028547061571515,2271023410257712555,10724732951713605226,10278331995023363802,8431606874678514079,2917971006071726860,1138208631432920567,12017798049751736587,5495125487617256227,5691747759653636064,14569474557162348708,17024606955348790152,13758018949195182211,10619256114465979681,18175543925196857644,1630042109762560400,2728255887813523408,4599331747115517404,14741062965007565295,15226919828976416411,164054567950865602,13733162877298384911,10799001228927414569,15222292051800430996,5094929314330919106,59233907426581437,13915579610241401854,5740317282063735259,11840528979123456250,7807443794263361721,17852267000632047316,2319496949385666640,10096611651377332595,3068912979724268684,5716918437012318565,10666451758240555960,1196839554831943739,16942633974818604572,10514777886901298253,9002737987773293916,11685671118367512705,9442691109275363031,15479822058298060898,14417782543321725991,5581074070075663386,1476128450236306546,7278752167521952342,5318513140638134491,17111940357146041443,16591617788833401939,7885055995211071365,2586895796516963949,13388571361802491933,10577083416276756601,3258192809342629985,5277980924821154808,15174571572493553003,6934988098181287720,11969999896880588979,12044628463583334405,15002355909214273422,3357450819588244704,14291848856290807482,3330953922725322066,18136459260853110151,3041054448909749021,6963677010540505110,13088446827566299666,2977271197104236910,12590888958562646701,162375602147464369,14911223369709723038,17724764302253207887,1016116140065084207,4629503260202126869,12126300536696028324,3154843841626329203,10193824009996339618,9589826724563370627,17104482171411576994,7996627795997412530,5910621824929075405,13178993839768882096,4975538188949487401,8187714257930568806,1762797663680320202,8163883327447004856,14652659375654822707,4756002048802716160,11903864595698773603,2159794070695817229,13154360394182303607,13309140295534762709,18067210254773243309,8502050886538250849,8961859101687919019,13701961506215149309,16766213252067793946,7085134744927021883,11464697762049962417,13103202723021221233,12040228548329638279,5405508222437258287,13664164977826519408,12803314678454089786,5144992647389301363,18206452941574951182,13101318930085975632,3970050951928175072,10012452653819798653,7973608798182507539,13015278684693571542,3085526709396113689,15685056167918197880,1995030717935655622,4503804415412246973,5922934337259987410,13796808928026550921,12792818861127499199,1880096763805592779,16892593567047690258,4746128350167658144,17531167771460566556,1142893625872171471,2305936232293620268,12236140063238231412,13323316267966257801,9042970923583579588,17080688337537578514,1689248688462912797,3410408588986347976,16151386635530491864,13161645902924666578,17558405148244857156,1305002340125089205,18376057281514904060,10923525799382879310,15236854415554716775,17432883255845957012,2090264821005553877,8273896584520950528,8966986951106356422,201471939611533699,12558924482387670946,16140919233991928287,1839213118197932786,10889413326629075151,6857468571754278858,4247570083201083674,301857198712470085,5281979103614929644,14235253301062914251,12021102386673047383,5895800362567242397],"proof":[[16906127030554680385,18148074371446657282,2855340486082614576,11617125032932619025],[11414457443937414775,1063697232133720315,3274001471183878994,1578149594767132944],[10081455565042079665,1212263301355028699,13655143710272770692,2894428772473383304],[1208881110811300753,2741367036561830652,3780272934668052461,17586129919057860777],[10823181727221221430,1499647618564818249,15681190328697926836,7862967512345861306],[11519544971048018624,14100507291155891199,957557109158699671,7926361311105544629],[13226738165363945307,897761825035223417,12807474398341922492,9029436891183961568],[8866676272374086169,5140899790540193753,11383545586216502184,1468881712047033656],[1822080052794958584,6438145765801776910,14537912941189414313,17078297239952428755],[1237760802097231275,17236920010297910289,7225061355940783945,3425190341414690149],[7975420686159917289,12220789804778587822,7293693497067249850,16808427919259604988],[8629773442926086548,4442981920210649565,16089621093252826562,11670066640003420412],[4566942276310186401,9956442866425015799,874017531182706585,7658433680242113256],[728210329438413688,17459365978059127204,7123748397761718196,16328226287628765249],[9336502509115180612,15688860984682809609,3241040278803753581,11943649151745373634],[10495349565935744108,10523484220850788410,16033793991847427980,10208651003669928415],[7984657953714852832,15734075477941574236,12214476408838324436,16357190233096441477]]},"fri_queries":[{"leaf_elements":[15661458364121947879,13029324266393462467,11599675961193976149,2613996685255386941,8699752608932096393,10836324829868125013,5242297327952336563,15396655989381980985,11074339058246210235,15475261637237757418,682869621414997021,4090399690674774008,11989955286057871095,14100903908995791005,14010890807131637225,2483053036595572448],"proof":[[10954156951229110524,2175297241818255070,699033006085545324,10195879994784248141],[16017103217725077446,8668456046503459569,5358375813720328708,16140607711608266246],[1833055672518650150,9948812171509200946,5027201094060863032,14577934520392800098],[6607608009891734895,12623691656594080403,919684894687382578,2627302376353626587],[18420567033687140350,5217866934490958240,562082258184318368,2716323758900961176],[11538600444698679860,12149673138071145134,7505553160222055719,16442644219219506959],[1942107074553740714,14655083612765593434,14925185905303889942,2087049736502045094],[3191070570723899612,4618384514654081048,11262491856017800210,11356530209689110449],[17391975647409704825,17805458304329438381,2908674988728328430,4485514352911646653],[16804140180105488166,18383443870045228062,15057012055223900670,12198949945870197707],[6537688738620020758,13239019670203497488,805261194925383237,6545130562114800260],[574517572074453511,16569378236613606817,11156370688896418904,3350059894465703147],[8513768214835546417,12836338239336445551,3721852914805223446,3961994658659772435],[870959045068062007,13190212933665272848,4148349890064256493,5894738798348384315]]},{"leaf_elements":[13336871836119757840,15121951730507616515,14081193006936351129,16478226451570043299,4035260497239398873,3662931859430466062,6066933711056882177,11774341107276017775,11941696767758938967,10226434669816630846,1843137778520385609,8968942153461056494,6800701315527924474,4141196333688441015,8164264874117449997,18403760833782808302],"proof":[[7433413141183876280,9705480064669001119,210281035558743836,4637141593220595264],[12526210199397852899,11797189603104662330,18013286337817794007,18415351154346208171],[5382522168072577429,18383756962542017482,16737962984525090645,6410592001001736283],[17096342529802124022,9373571451549397982,3999657289263461739,15714716039485156872],[4515139133168462959,4774173688507328524,11926308465867677195,3784127764708917499],[7144426573630652647,16641218436518298686,16368396783625709715,4627691780256045388],[6928599437495358748,4197390053976458202,14738976437926414923,4832956173733690855],[17386370346850870849,14012929824225015785,3613585757878657040,12881863969526808481],[8491238720500584099,15423206597619195528,3493256228184201840,15550589890010252695],[12549895727911728202,2743420063884892159,11322878888850766955,16694882427815903729],[1918395912208850369,15595168596087110741,7847666842944273172,13450074119918273287]]},{"leaf_elements":[1600652112425884884,13431781657949737475,7347360511686935661,16220109120344237341,13670444516381017735,17750234434904980867,14720347182880371281,15532373869794926262,2403586650460743143,1610074697785385859,6690573230451208141,13922936107693156188,16003397207168916515,726952509971720960,1998950574288717358,17076003492137758204],"proof":[[8750377789128068668,5856985919505063373,15912440923213772313,10872419461200449868],[6645514407851020618,1153482613808052736,8221676176991660503,1585998408701181909],[3850272637867109302,12476607464904082392,15777157944374792975,783588310687815805],[2524912333730585142,5249643485697492695,15887720956028091670,17205001858925971212],[94564575577221252,16654621849764258989,16394665298603300182,17972499412835081110],[5038749263859834895,14950803381483777928,6248155915262172888,10603216727197578097],[9451832930033417695,17143111883000491382,10677321528751237295,17829990805462604524],[1902792532381728571,8661050412531662077,13331374864731157815,14587068449346603177]]},{"leaf_elements":[4936911523709727749,8970129560458740322,10199261985226438704,10894706755032099683,11844541950424584534,4081323836217680952,12629132548946648014,5738661727084055814,9293128191069710812,9286483652954102391,8962039063687172532,13497138146780859620,16666865187836050963,16232798368682099069,2814392199554924416,2256502350811410651],"proof":[[6476017135534724899,5511305996957492135,5851983812443439275,603605318312892987],[17879480462545065836,6606186149915159441,12192121414542005198,12242081272669797591],[11640461364506923724,13861127652636335693,1110492522765501226,2547959442394092644],[12549748346560687705,8852920067056597539,2667995279655759750,2136124138599761449],[1131135611643424584,14374117323723228443,5408462005651363443,4195584784838765836]]},{"leaf_elements":[12716186838572933887,17200929327288102301,3124456179251578358,2067761240693230971,7590522196512492193,14047944451970450851,6690190054909534976,3148025694971539694,13404792078066607517,181974365398026575,17866107998725538066,7223408817875775508,2832643315526925390,10788368836573547979,6827284116962964316,8064538816532037964],"proof":[[1399223465754392137,11226727034138140712,11883668718465949616,8835611200943863811],[12639043879551777198,3116432281338880680,16966569225874343934,15833611935762388359]]},{"leaf_elements":[9390894857537177134,6775050549137632293,10212697533785944089,8397297093669755354,1622143564591104592,10285492781803425441,11612578074530589,9279746851921347959],"proof":[]}]},{"witness_query":{"leaf_elements":[15589271717281103960,9111736367816408919,16626260329631382124,8479902432263444518,17172902359743321308,10435375884820479561,3380060074120783934,13939155668655139081,1245722110071589625,10715502907605735562,2087411993158320988,16703091672374980064,3871257309027695346,14366473619321615264,4510709466089849424,660891079546301511,17743945529394411204,17263190240898854050,1520121569654248949,9029051558527480401,3736607967897651555,16572793435120630700,4229571070326408829,14408608020459844039,2319864703715742576,16728850867348567047,12821476268807641498,14828263726806787170,13945326082731151298,9288943771245838559,15235931637459614286,4971477948827118241,9271427296137912090,8058820152059044726,5078011622233079707,1633848541569986063,8020104443657835932,9084480317960087792,2138763174038203479,15391005596339997881,6482079003007111357,265197542617433647,11476205383149545492,44624953929992860,12587918314948463796,16221512647200942868,4123281195291069678,18372546079099718980,15567845662952751781,686839444157226296,17083005450874634036,15600483221626784106,153556762940947650,6828067498191348309,17508576081082596359,3451642511565432944,17105932710501491120,10873746977647103688,16428751819783372615,111145483021781700,10155168907955208090,14520459464400349029,13623647552536296454,1083523279441214653,3066276202696985964,16619870682320174570,2229679626561999333,13224761746536807154,5652245966580341290,10226557940431557658,8579269789105681840,1925105053345325362,4966315674609998797,177444090962957403,740120406017766904,1072183471547353550,1628763893186099540,8758652664971796217,907825252193419740,174501161711685728,11381717505159558091,189892335197264162,13627219373323723205,3227761976423193905,12228938938553882129,1556994748272677007,11538441113422916830,13617238047674452809,2741699409015878778,16653989127203815647,13020567983256254012,13339596349187401313,3165015573943350105,4359263714527251723,6710892094653251630,5593651977996555413,5005572501163855949,10615828306835351491,1294255836653626503,9426210434444744843,12837345703398409585,4095289716322481679,4608494540765853684,4837983434683552960,4176442334781277673,14993645486121973418,9498808980225129994,6575497620204047863,7912796696027384212,17513299957033283062,16349641370581951793,1179269501315650196,105056957762694838,8314995631544597902,16539413931385200586,15692230201861879005,5902912273627478491,3682887151234448770,17807428852914020771,4323604715659760658,10857946570106783229,10231325110172467351,3618315292330123891,12167849133100662702,3639729886973318082,17080810020016448781,2741891100792959248,2496932076384966190,18419953067035169359,14890227214984466618,14068109581666013664,2870185404103875125,10955421346067129362,2316980052663230099,12486065642278574034,7476265659509720960,14845896676161421674,11866139104779813386,11535645226088952848,5886861973046601661,12768658822383780596,4613057184296243913,355341470739628209,10833429959508779008],"proof":[[12534162400473685711,5364967166929891203,14688687229016762663,9391375631654922809],[2296275534708749949,15958131436757986348,7564220577642523864,13950566428254095193],[12022848517013818413,15567068549053803245,15851374136163948533,5833783784326747904],[1533995443482232282,18201165486684486041,16094677961584867793,17925385494665592569],[3787545548593960922,13094670427993792239,9393394455230609577,9775770992617215951],[11775284516906214552,288857621506661246,13320145606144593151,11808891614689692939],[8617663316956019998,16076486986972257815,18253661983754735779,5244961237229975266],[16903971658145980159,8998540764574581250,12507422585415422749,1112357014547297659],[11706563242557530231,4101358514669351453,13682971715006774797,8504464406271912359],[5399815516465982015,17943932278762889755,11712823473738196163,2682594582006008294],[11543251096148805230,14108034244657139817,6985867690950775663,6612116332848641360],[2070247787857890231,14003087137306142253,7163592919056814604,17137135164629306532],[8177104830136069286,3362053586308183266,579828275106639627,10056469841141519793],[2917519997001573494,1846164167680021987,2897509696874207070,16215836058018329692],[15544351026640428253,16664542032675314289,3793469854707451638,2061914490897817468],[5151659993604751115,645557760056141545,4654911061998168919,4128363658395254435],[8193979718528806600,8375224386207577318,1516291403550624483,7080112769819207072]]},"stage_2_query":{"leaf_elements":[4531247847959310044,16014632300573365564,8499918891003980984,7385131928894670847,7503668006790464679,7813971145182823566,9626529224842527389,2813161908587224476,8763089342714000687,10186976430287579026,7534584314400050708,9029380928237107206,14673379555667450156,2862053434457901033,9095630753077858636,14169921163652932642,17655354759255105027,17390044276845144849,6961266686239669355,850649877470174844,6821483054783438213,6948878339500956694,17778122843452357369,9993413309977185178,7229405912954435963,3795445933418972024,16429984201389459799,9116214283778384408,3569332844647287486,5304603102002015216,17713149314322829731,1936358637449800771,10714901203583373342,3534803611160242905,1324245075007977990,15285011327357742589,12679271193558967825,10133575713641248573,17135418612350291365,14891691260485576743,8043437897650434693,11533896617299014761,18192880387627294761,14311250438332622950,1905654801475939308,12046012703398076246],"proof":[[6148592378934724958,10471316524886249980,13239253095088894945,14127303866973400561],[7466482713358741177,5519984491951814457,18302355883587598692,15522615354593317074],[2200956225389420302,8277047439881750468,4183057591382111735,8695471015977172211],[8044982380498178357,11976358635972551007,925071876469465769,9896367818405217032],[3403392731549579153,15177585855646224213,10667714387913181694,3633842397142544909],[17703116783253582587,13250205900840025495,18321793190447266264,14373741034720698368],[17751756156779725593,10104252402968841138,7723024895124566506,4798475507289005257],[14397928837826065134,4592432623852817976,6010833167771264377,8416738591061182640],[16596632230812517706,7786685556974500126,13987086190209721898,10663819704517210891],[11793327005724974279,10777556131413583507,3842058661738840767,1456509288163233592],[4254547001042437613,8099182997633133352,8521386144866640928,8820235046154119534],[18311985244348702352,18327460314601580224,778919530732439942,4727956664986274585],[16927854769648860999,3544991850509568566,8744712443504842790,9229166243856714320],[15498037729794350089,16043964718105919235,14417193127772871561,11808217657136607554],[14389400424703654529,5728229013465273740,1620393258125587939,4898587107104186394],[8160668943952387841,15113233575098833141,17900040174636689252,14690530551601386128],[2156372198160320375,10758004586682519094,11754802890427400344,1564423923851060793]]},"quotient_query":{"leaf_elements":[17025863983109135565,3907067343807273745,126141222578777616,1517651540635572583,8918720954237956222,4935973303624582632,3138460401321260806,15775358266390745946,3736584268478793965,6839403301912493094,12486438513899704861,17580015364582768113,6305868020617705467,11849569168577222271,10047512899734928649,8686417896207778402],"proof":[[12852866310095103737,4949784364793741529,7083782716631733468,1620057499449927493],[14623832118099687425,373629440899450497,14402603901409663838,7158698803029309773],[2703300320945967597,2169831569891194989,7820545166809916829,7671586500414064975],[17641166058428975940,1867255894824426594,13713793629317690339,10689772865733204824],[9672813258405400437,11808920394416048142,12857849292169958405,13132939471292830155],[14647650696574399076,2020528883813851640,14045350773325621947,634111112335708248],[691917854574119419,15075300328835707026,7996898093071452244,2680543088562412401],[9649812618393868563,13336854821785931681,14842647607976657455,15989033090663348249],[16137349190864768611,9282932684885226526,8025259428364742440,11396758313396451654],[3888002446283062319,9118705717127294949,10328738078823683589,5353498503575314395],[5570127580553701682,17783268236180445110,6158738945207061600,149472614642594129],[11190770604363994823,12619595846559163985,13081543149710595959,4652510611727085998],[5488991972291488507,12632382415108977106,11060312788228043638,13699624751106551156],[9240266446297291248,9825088994194987469,2568645450120350596,5811150130066331448],[7249478780677482838,11962943810305152810,16203087488686938907,11175210214515286520],[23346753238032871,11726231107646689909,18446617914928111271,6867169717337366453],[6781824673145116271,11884988964241063795,2786037544787052384,18285016945696491669]]},"setup_query":{"leaf_elements":[6906142744888242757,17618652110240954077,5067825315871556460,16376141100173966508,17171208927158456476,12537351239182009,8348935889017127177,5598668133496814601,6247664751267924625,9526514883637664692,4176931069840341373,9005716655349955657,8228922079849643386,17918559194572276942,17359163364470264198,6985632470010314656,2476411805912199537,18281044751840233512,4903485540063401597,4823969479969497988,6099688410368312277,14880699524519391826,2989565955385134402,1877307067647269425,12248854180217074791,13884535611564977296,289514567160747424,12438221964525781025,10607628889924020029,12308615491886598984,1574170401547282611,1466268241080277872,7929872500106111032,396049225684840479,12149666186369607842,13335716709544675746,1981225681387414814,11403616469617689146,8520696050680333423,931700038281805366,2323072535547376294,3278803613679409723,16656607590650132693,806178542377003098,8158577186381805333,1838412235937931937,15015477858275672045,8961489255415420232,1503245907335919799,10398594488398596804,13110134433659159439,8592921397138688404,8182550446542243959,65107913166339445,12642114508234565149,15311579484499188209,8035085324128499372,4425655760782505316,11646098433977370414,1191087334921041332,1120676560149594206,6394860980644229255,14346978837835727976,18291858141837315643,8427089071321794088,10163287860645392895,12031016812241413261,14885458174191651952,9508784521974880627,1579449631358211156,1566060367943312325,772531119605119753,15975095767241539702,7252615827031782276,5436855841504743646,7853944040041374728,3571101584777279947,6851039335276999066,11059669404258917521,8418272596269591346,15240713055816093496,13588480252281945194,10509469868794877989,13671220842847523522,9754302639693615569,9411410864336488960,15438241379093585963,2182506768357853469,12110463941117788851,9797705685533410568,11120183009106349832,17061785082130364080,3984025793887868752,11623130153625808889,299292771731163244,10750543496766179415,6683549876765334216,4319534472979022310,17972595074066516555,5244859959095041925,606928651439316430,6342514987270799928,5663190924405020088,11185270372016455936,1682816224556500243,478209534346123225,4310006692385097642,2702057449714427910,15754396769787005216,11082181704376158028,9189855912848076614,16358771185220234755,8381479994720416111,10249026499521740980,10585346230271513613,14370799000342627004,5662497274997029869,9634077693862298965,3523329912731612357,128503138055592770,13855443410076447885,8995526937226940802,9241457513348823145,1379399560568893521,2111608773928677004,596325182848355806,3662261619396631308,1226298471700958899,16841264339980154133,13136153878311198754,10117601976849106400,3566233966290105483,18193927434757084088,9709650857262236681,4988720590933424850,15839371971065305972,11696087134570082325,10222224767443162582,11526268804218490647,12781474541054088027,10788334457365720216,14501705059344771536,7317920562682410915,12090245970378015165,17887791976334091597,6986727100757000024,16641329568285792492,5300457359192049042,13037453206311735186,15814294879331459115,6458013192883270282,5385106289720942633,12580191197648810992,8475982749297955796,4152254405741196455,17468800389845953524],"proof":[[131296495237156586,4338048686620373843,11935157704716465000,6691874693270003630],[3602326294285400863,4125843301063030453,12088689298582080070,15037552476908148101],[969713498051783916,8047673962799991213,11385859893511940039,397527507839209979],[12237741795835931369,2049325328604632107,7292073512991851887,6989449076711157616],[17642695901113084058,8261322164294610516,18406487983691467792,2650599372006780607],[2526987527179743336,2573378539359079043,11101034097330831542,10430327354136805508],[17170011042158640711,9168459844283579729,7835789009515431941,3502931840400146922],[9553177720579824955,505987498843801857,17203193526373399240,7888802398879062875],[14469034829064778025,1075959772340967960,17717148265648857885,15050266746701088406],[17826362294390730861,17697739816082441707,16876375227029160896,13753422897863487060],[12860682416281230317,16212674906553151769,10211702467444021990,9715399606982153907],[13001056231917868090,6632414499366063896,14545767763870223484,15302734549782391837],[17440365876126856524,16161123310809785501,13605032171562971246,16583720722926719918],[6913272146366729301,3889228635009012488,1938622518373406094,13620718092658179959],[11536297571503551137,6988476425824431457,10733993600214099676,15165029585949695467],[6693758018881043178,17163178482231601620,18394111945980300726,8057694723322035056],[6927789725927369932,16315812677162299352,8615590175857271490,8798523207874952519]]},"fri_queries":[{"leaf_elements":[16860590709178267331,5494397032123936700,6986160544279654692,5163166111541041705,114150674997145754,3995958809719632580,2659801562844189009,5550116304405713644,13904582094501490613,4264079098346081677,12339820767638964934,15426947390168697206,13538412274287638672,13157833848118169746,7652384938441546794,3205500285018454985],"proof":[[2372723291553900108,733567206311813075,15452731296056396119,15820873943612618570],[12276704975579034975,12542905286008771743,5641427682113716466,16110790470703344324],[2899589251187307595,3245000024091182400,395661784519957261,3058234219201963427],[834115143251221505,9026596059440487678,17381038298457875249,6209072665056058245],[4258473322400740569,6849602083311511052,13825760165079791815,8530614431636991599],[13664412927819799514,8994118337502988131,9208819500873867212,1827049295252684347],[18032850568100118375,14248647706163760280,16065686872985420983,14929590334132200480],[45541209651322316,17494704618426859827,8466939160034800562,6110088405217542385],[9021850778417777047,7629148339455878065,16386271962411742864,10702282915066531611],[3428739592281158129,8432113626558483769,2028751881470579229,17946476993579216458],[15947222802029325966,13400858739470772708,9493000277321359547,13168775753406720707],[18212893585142838476,9783772644328034385,15316994782106476312,16710059087839086961],[15977936783553298065,7883991643266293292,6140878641507662900,3647299902647897688],[14128138712872929702,1370874517542577445,17278172058011345670,7215150699576622869]]},{"leaf_elements":[4039420578989127059,3720900475479282911,7004158582933747209,4216102810307026629,8623135289022123190,11403944373237357960,4639553074846238180,1804769167509608711,17636973106156824156,12280534945409855804,3951224584023221138,7821567608780300832,7919084095761017822,16412103228822690559,6433961573076646494,18061876100765592254],"proof":[[5866258862796837468,12515860422685114914,8946803346561203196,6807831868335446631],[17767955596219973935,9674634911134281,15729900648903481079,10424714415807940812],[956815684391768650,16388758716183616510,12495962014782966531,6028963670080916697],[14166475039021410086,5615608104664976668,2598816176016649386,17199524904631247826],[15822223951262460521,10954172657658627008,7632165049358273687,16045233512798342325],[2101384314977543401,8451925434508046192,12968350552366626436,3484725542016480771],[2898289304315594974,343013059653361362,5562971539007480499,1860190843438982918],[16180694803602515161,2649501901537715830,8406573072965860686,13059219061054432008],[12493369875508989842,4025515444913769318,6994036029812473475,2364720931976867574],[18331591439139592594,3424784786448365084,3142444139132171757,4272927789110192094],[12455615997980745569,6899641713496781723,3754459214410385641,5180782410589882794]]},{"leaf_elements":[6339332025993269272,7863613654555837343,4403666546205053992,9000901699364155723,1476208426193922366,2952315380587985143,5807107923063948845,4886321206964252250,16212298938822280248,8005665770582761211,17610919961129390428,3885777813256714234,12955370106821748508,10486777358997789603,8934130394420853245,1771654187927138172],"proof":[[61876469488728509,14329093014449878983,4411021768569636506,17674690890852015946],[13879367913781109486,14822817144620633019,11599302012173189393,11179533300594722013],[17398772487921028245,15036911312244996059,5104304114950253228,14276680655525333819],[12418310284643811412,5165424976847313250,7048818914879804206,10274385467715652022],[15367729352120613067,7349417891013346452,8298204879609028094,2571063516298628550],[4106268852492397033,189587160016102801,2799038724498290629,15143849028774563269],[2651109751430335033,11439206719483041059,16110394345713369638,10184638098901079706],[653609557330627868,14023145008717793735,9829013459427154980,4354604016037302551]]},{"leaf_elements":[12682661322653651038,9860011993361162754,3808962108998241697,17879100491685600420,9548428244077755547,7656174255174711906,8267360681208753112,11253827805615502901,12237572932279442679,17208447098273108332,12821908799028806126,5885276163763619533,9382162049208065896,3601631992627844798,3479252498711180224,9220127272596183280],"proof":[[6026877609137263847,10551472539717150996,15923547926738270977,5541143362207349041],[351616569541012887,1317360750312426528,2925985099391626740,2518594886404044851],[7967361218271946802,2459424386439785929,13914933594261909152,15978298734219702444],[7624181206374835069,16639945051842694695,1627165198208021593,17909495709380549978],[9177491066822616147,5431401594819627928,1355274528698398268,6660308507820893921]]},{"leaf_elements":[14886676399737703560,13931663038602304496,5280470600619763712,1602784438155796746,6479264596726780000,9993197544143353723,6492683510011167601,17140074783765260898,2942983150467580832,9921602828685932366,10671825697004583395,186956216834001891,2326717636085023591,10627251099606495890,5711740284682674751,14130161378460007906],"proof":[[17970726031724212930,18098966392717033744,18329467923396995518,15033918897766573074],[6872717206768702692,11989125647797140964,2137644504125081380,9069676152651109583]]},{"leaf_elements":[10632746266096061438,6757646590349987949,13549814758625843258,704655662152719460,11622797146708305149,15759578015746123756,4397608871267503275,12640380755777952922],"proof":[]}]},{"witness_query":{"leaf_elements":[6379653975639563594,10870785954291037774,1399102232613163597,7143896407198312970,10133828942265929160,1807336334009680332,15603155194137544803,18084631218519896618,12327103667454512925,4275838861157420163,12380270498868341737,5742252614997980998,11844389649192731410,1486223855601789601,350972000031482618,10625010918223374887,7072748342152328716,11194112304052801314,1396644780225510949,12337204470482503093,6033302874746652925,4733905383323130602,14739148847883454674,17227358015025566928,2212009345181247815,12174154738626790081,2076300487865438989,4444301229928864718,14307751115368103313,7251482140286755819,10510193696500795310,14749290698343899848,16491038500390200152,5864645417879172144,2174188580581912499,4615942361512513845,752354638463334675,10183099607415188080,1587551351200322778,7108728946330719225,15111481775194730851,16451895793570722049,7718413689001697785,4417405577956905872,6144910292748892499,16231836403886583366,8403391484199426948,18043584559273692932,9371214217484054174,5457184057582416477,3056369209540265121,4579545541206916254,16265962978688093012,17257822183381486857,1683486536551903412,15437007474311049413,11005928566374434098,10006180798422416373,11301963978242330836,13725410063100253068,8493861986943039481,7200117944720433735,2411790160600274217,16837640779634447853,10090913291304438066,5923646766619934807,1960542012158745268,11428062857955743351,6250175788047030051,17448820667434951583,7726244214817225177,15305443451445284783,3488363774795293164,17600341216079552050,4788647711877947556,12404161005450727054,4805609153800188305,12899248551852061561,14168899015274684053,2818008847296280030,13058899617597471112,17804503242650521308,10287077760219209959,17259229375824480506,1849097569638429698,12167792862959257492,3589442417270812794,18070119014168804110,17425781314503512590,6841584379014866511,3877891705987819232,12944012585190491916,6411020310521251695,15984819967003931596,11461110432179319056,9559936331730121199,11296535342994643561,10935159603372448237,3888165465322719433,4306965344855371236,5852291678172604490,11454131117148702795,11746925810664986502,13619616356918739247,17103245287183613996,3101490886030447821,7903335154459029782,1103583033720598798,15042035131330336621,7179101666183879406,10792527165187046259,9993476929443859199,8901854581183905108,3283063388951746198,8180481725336982026,18013394695956997188,180164830857027524,1638688006697917978,4964889000607991429,6961083609382190199,12753644601302798302,4728343452681529917,13027245816878104128,4882628306740048616,11130638532436270432,16123644424685584286,12488983467556277146,5987985515844264890,18380235168730871885,2028838553268618923,15431257630477665064,11555393589522144791,1749466193953002147,13190926134931930481,14158343988579592127,17559331196626198888,14744586377344933170,2984191712939637385,304076836618268874,9575349282860521354,12623137945027942212,11150854364189243984,7025524911357711857,4741692161504027931],"proof":[[15550310924176178941,11458541468186242247,18025066928190009020,9321042435292733886],[15351052600256426695,10890017364335244714,3728561225587503426,5877065223724661891],[3898320505608222452,11771743791219047703,3492331017211792493,2480570191835465893],[13679389780417369433,2736515402425184394,9691741693326679721,12779724402248126570],[17885824641312077259,18434540224466140840,6017571329136348164,18054472573661083512],[17036874353101617165,17787056871867187817,12233769307889592097,3196442806582073713],[8052892970702352855,13373836019274781638,6990299775786565346,10582797729200183754],[17705767808097782618,15025470061320566385,17507474312790408647,11984007757437706606],[10987005673120843859,12511652279167376075,15714900857107078967,11248052035447396686],[4871110398504696757,15334684717161729927,9598380887191361258,17991272297066547477],[16853493124937966106,2222296911215672674,10382667377777468808,12494600606222152182],[6063718067723806623,16876044129938972690,10043038684174985056,7106670378522509053],[16493909330047309444,9564318055823261154,12909317369523141668,13743432328173145936],[15700152003912929379,4863797385026850033,17300447292632405246,9107101725458285195],[4250191650554789398,18214215864297379788,6347716538130768735,2845062300142290670],[12634189585880371814,11039581249811674275,6231385938126440099,11349900292245790782],[667075809834928833,5991294366952926453,3234520755801828472,11803630721642567180]]},"stage_2_query":{"leaf_elements":[15822416162921986133,16046593469184022850,13041802715153740330,14825329959339150641,10504762147542787166,17318835543627913112,14816119310432175540,6557737788128752178,10308765239306163205,9603027442481205260,4156783914242998927,2550899887051254151,15722745341304189046,12257313503174577594,7315996735714829072,7567570437052240615,11029591829974696880,17910436025000516591,5327583261555815682,12764916065161134841,17490776246896452784,1337270660361585848,14678033514659714821,15378377209188420749,11008975291356425997,16571821022460250784,1263997244951779697,1812595682538370468,4060928136102643780,1327071749698648381,4650157976570307622,445148150410822334,4245579927307522250,4927537162488716059,12973220275446849620,13763932373426404100,6006786422870665532,5630160648998655958,8622910546948874386,3023397699959251492,10817661092199365206,13589860016420551282,6117984939800712573,17487368928106303857,2187365626280275255,16716400005068759714],"proof":[[14303498938554746909,10897978621048967527,10511000244776656443,8736041209111412802],[17590040813812666261,7823437116699507693,17052053189916853305,13515276925183184156],[12561964300112179941,12157193349314559825,9229179297483542872,1569801270939104017],[6548165833728760322,14849903113468189656,15076186908991059464,13152277509222533834],[15112705053548115696,7480151002984591540,12802446632498756458,14400098971403051454],[7218059489686815867,6095083784095943764,12709388651658552538,7500180599973261052],[17310039736659564383,5109572258348746749,5122109901138756797,6546863927436059331],[7549847102198958851,9700113836872868859,16855555658379192691,17247382499419128795],[1687910160158448600,17284308148926040926,7210042271861041986,12741655649932948589],[17780036645801363636,6896512583500684623,10880854685231301713,6006608514306953491],[8742272658203045048,6328687705024998635,9195863961791565190,6144843590589314093],[223566510612248165,9100875161452331821,10162290324595145121,14205552777217200329],[16498463128666414295,12962944906814664548,8761034449359003858,9509564491324366358],[1415336894886863375,9312171091654343643,13425594313172425071,14801320316244372195],[14695571663124619820,18051006928267900374,8752173224795291412,3959160267781023030],[11736029788203618694,3366834839034831936,4471200710256718226,14721360103719272090],[9207694402130270883,11419654200426216451,1427563265836939032,8959631267510654977]]},"quotient_query":{"leaf_elements":[4066446540333013301,14779800524248880745,13675129863248441774,17867740037276188491,3704158684206547141,17370383750285568130,10524836268341049989,4693692451146891709,6037190558044898142,8774094258324824252,9014403317850858331,365014909662340385,232374688993239789,1322358643293135066,11365551135095201456,4776620246894711175],"proof":[[3184931795248127430,1802323764932874662,10920534073225813050,18390596616178058438],[11823583685231107099,7288674772093116597,11103583009771986716,7200309125199687684],[16878554667206910712,4234955336188844079,371110741287241260,13782898028123594830],[12609902369198550787,15128986179809011062,13674812106266562661,8435566015960608012],[17219067677279928263,2168450707595079432,5986462221435079338,2322315333075825093],[16924686936256301416,7999034042135800378,5305241085461351771,12321558427826469425],[6580210438684611123,9703136215711956908,1908687062535702597,5377204354127943411],[17381201333509576590,13673679769286649848,887164324717677608,16322234830614998981],[9937379837670961820,17104259677047896799,1204854727025563467,12005209837933842788],[2630921429167387383,13776347501536693755,17730035537804212393,17410828843925709184],[7834444258539708708,11076823588697427834,332208025098327807,3452184557002277829],[13844179101823799048,427680527231174624,16771506604800190908,2445468707294555903],[12987782856714570468,14151130318832273964,3226975095025825934,3965624286999889050],[12929315540816068695,1426748375566063043,12162803263508691885,2910804510123366287],[6750637709422966584,14655968476928391943,15296941372109286937,15816872147405376070],[8457859900747567093,11023554797682160521,8041785559699237870,9054497301565934105],[15302778404576921720,11814066077929029710,10522112645627058746,2170028931474566010]]},"setup_query":{"leaf_elements":[10363082637849198723,16268077996849607903,5452260199807940797,15740895390855660421,17906237853185860226,14226038068960232666,5456320515573696319,11476186285033949980,9397384898520057895,14550938536470751936,6059741082249724028,7431991072660336148,11735521449488046187,4029714168819383375,10579701440534916195,871969142982907981,12332727460029045931,16849414799447022615,16545967701513198408,10321944099778984435,11569307243093806159,2103851998829804260,16905758248743642897,8258198317945800841,15433850544745556500,976848406734698270,2993873649760695037,6400359344041446295,14556276280576391527,7225750398784192751,9238278088784899028,5530407249360700679,1308795695259438257,16739996431386012680,14909454398699779653,17524037661041726574,17301381927984616864,15675601719480797236,18405384701447152959,3752329644870046389,10025286323657491936,10670357095199746089,17707141660575094402,7257165858945356116,10873462502198776973,12607462331317183599,7543365646842207151,14874064064238913051,10261881034459340374,10310256450393030634,6686454229231909642,6329369530894157385,2725869998342071965,7942495191517437272,18066374873459312166,13804898488512110571,3123430873648209655,13077728776751900037,4909057114454925499,1020673778536078924,13803053564393675649,9249882970315128000,17799916942595331230,14524759940091392173,13377416909816551406,6140687594584670819,17068396749308072336,15863664754052675115,14200150131252110211,17407257716495099209,1296346704974101245,6326664505392583477,1802303385362459838,1298194905104277517,11425390268125516195,10452229839823007750,16286663024241594161,12381260779918751967,15663467051774771013,10405611796285217346,15086352803166255085,11227858911598543752,10932271426384252501,6875797885927908916,7901677204668350125,8515759014919574857,3901885463160044407,3330939521039300776,9822988045176763626,5236415406680093368,13274407231635583733,6475165871418953191,1767681187902832574,17773983732375214064,8290544009703270014,8812959269768942209,5392454703063305326,16238210300490032373,18020142369341825090,3646142427383451506,9354076009729663645,9200055427467578662,9148998420417512383,12710554862180910141,12243333165590719700,5512176663441924585,12468975888471598846,1622466728289422509,14687839937937291380,14566318439769092769,17054397424793177281,8934881803579922216,1746957548302259431,5824488503562168162,3264523252273851392,10695872452459622543,18135443489659192551,741305094410504383,1876825145536130885,2651436794325998481,8609413207968641985,8662608684539217971,10002095298740764384,15796149428540674834,11717068390615410148,16551114357157741899,251996717348914646,2833419000807243175,8554937176591404101,10343575814480269049,15074201521009179612,7688043660738654793,11409757315702792551,7272509132440193720,18246524815766526069,5441717269073624743,7275528652059040102,15014841309964372183,7688956551109300901,17529983950302141060,14380318720775369163,4717743376038352642,8319678365119415296,7631180731550144525,15847986394983813370,7819935917798389773,12704669674430347755,4836424495961283211,13716180419547085191,9754779731857607583,15418282773766851023,1717916836450856207,3074423552355162738,10408384249146635004,3876351919267343988,1423938002853445300],"proof":[[4815729550153836300,8704298468984381064,3516282363089762655,4041448882893858216],[6200401712261003718,7337570455230437438,1908487138894179331,15500525445219661870],[14234460524039252424,558633080861445137,11815659975363174263,7855842277067953705],[2794209653670717454,10596878313266362845,2640749809960916101,16447317821744891026],[14915539290610758483,14582038018220472553,925056217791812829,5081196387462617573],[11564169420683849722,5723520326134035209,3742605923013160059,14018527065523109146],[12778556140360148723,17003688272632632224,4982072541238970482,8881172592292687791],[6844346970636506793,3241703576156466704,16607363783562361716,4483992718251517420],[14594506240149164078,7106415441566069247,959658832618915515,4520038858081679680],[1443140741163971771,10508263310943333885,6332885700275832799,11364482617115168499],[2666049591236546793,5810438266481621558,17967669950677189195,17951903504923384921],[9145109847928546065,5023517039785754999,10841696593194257954,13111786712708965208],[1070009339139556649,13513657357709109732,6708927528034053225,555594984455832497],[18156368415561316129,10275182740279620020,6511999450968770470,13797741414627375537],[6936375391091485604,7838459346469681638,10126631508919175423,11796846634798213516],[6839262883155696775,14636454072565808037,17986829962653856079,16954616439061611458],[7120720126365939453,9301679779098522440,14567674671977422259,5737163305740258263]]},"fri_queries":[{"leaf_elements":[2845338666302670952,1748122943986722712,4983929730178355228,7943805594197454077,15745236923522617979,12847639976787447563,2660971062079109216,9920479939141746184,1161978952885509267,12411718326501952264,14904511592010077605,8355271137641079648,13361217715891409843,40813874077964520,4357004098424233499,1233717216642063388],"proof":[[17979088806772097402,7947053049729593181,15200943847692648465,4157514155114536920],[2749541427538473398,11421865276090902688,8433026486440959136,7969028424931279724],[7240320749347097143,9816880796823595100,16039957653133294241,768286627966136137],[17897090826576936673,2819409217439128760,13119425684377443457,16776738441308962590],[7382505351658028226,6204952994946494238,14797165342617543126,946078750801028999],[7461647971194609043,3679992730913933569,17651193441609768170,756258422538622766],[18286612870578013238,3418439512124378436,9750657797630363375,14943381034555095220],[4929176800977222380,9751544531258305485,17357147035414087743,12436725092035557172],[1967483114730251531,8481915994589779638,17171613442866440649,3452736096930432587],[17247027030488865105,11782864807792457431,17037572218826986556,16236881964302085356],[17577439929924212478,13630851451934144818,474796676466513590,11551380038468199909],[16456106666545409235,14096373991941519109,7357214633443861643,13411669160496059819],[2409453229632560186,14637470331093135900,17769103887618170120,15232686395332082864],[3402040197144832143,16624859650092102648,9771646739874512713,9644679865246592281]]},{"leaf_elements":[18435902870288040497,15325469116023389121,1365138820331353208,14008847080638919781,8555334724674841228,10121024922034965620,16782891609427508786,3738556825171502318,13544108433043096041,6388046251556429059,13904230869716963018,11721546725961817454,3483444437011386286,15032303410717011743,13260680437278193856,7038875238581622428],"proof":[[9994763690618335837,3013377437687708780,5131114566320718672,2061263674748221973],[4467845016842626687,17594423380853338205,16467208569382015818,15446758658375632401],[6352646227519571377,17306292844364225135,14511286774559062521,8668064150358120172],[17310203776467115715,17532536109870406411,12792429712221430540,5260056217947694541],[12144491012940239163,5425970815783229221,345984385689878485,10811000786860914647],[1703397724048080582,6570064232369953571,11646111979180990615,17878857270175872727],[14907426373074521995,1192219362759619155,1094497536072204513,2758311821770186079],[14129432099226838105,244228042830266687,13851098620456059067,12200982902042032405],[12470120042262744554,9041482703562957402,7467578509064975701,9193327395618044100],[8198011633178231785,4338451769064680171,3469740648946686407,16177771307732142306],[18351435286393245396,2865657294868377891,12507805816395302687,10169105071705863335]]},{"leaf_elements":[17743876990690030446,145416734808344560,12802284106755665685,17073100643715976134,4022586686215147237,17832945321530083543,6913088829409796267,9686623795402876760,3376100791429465410,9605665209381327667,16839509603829477466,18371663530627982747,7409867870975192935,9130980179083263857,3431451752639794290,146341340357490859],"proof":[[16860048510200926104,9414122562208137434,4184844798318632373,6677614523389987247],[15851764675579461424,9198465028589125800,4325347022224592289,4296911886747006062],[282483901457014435,7364734564668491134,6141674709603324292,2825409181057875720],[6950680431367864879,11859998264191939679,15215536849707274440,17468204928600671869],[16453928670459759866,4540195425694141863,14324370854736443147,9085509575414117966],[16281954906476392402,13746449904646615658,17676700984655787689,982903866851202644],[731073139101116486,2374056337424730611,9081295610148386648,14095045334082447191],[3007305652148126886,3973547783666200093,3625693024435444758,6853635343299758316]]},{"leaf_elements":[10606210932455999271,3529784193069972334,7518450151843559761,14646997015711519975,5453669872048377811,990485355650320390,15153310601026304717,7218828005050155030,3692445742302503551,2805151070789201809,14126897501883764404,7000944334235287712,17851358903161014062,17702871051018966592,12137536566938130657,15302423563280281719],"proof":[[50913475070719006,17604099555322071478,4754147006062721422,15227136176231414557],[15306723561783573826,7246164354009428206,16274887164199312395,13962145729203886558],[10293440612286135102,128428062580387206,312538945724137603,14405971949760284177],[3572167046127305299,16999318335924234013,9026160449259726606,2968251498515825824],[9511959561061228326,12142498241637411804,13247686500668664919,9845123999379242829]]},{"leaf_elements":[11543424105301683429,12923864838794113899,1535160299484128979,11075524133121684246,8482515784209504506,5102967239528307818,15527559594073359956,4973840040591704279,2274442554747215692,10509379957165122735,11776267374157344962,11551294505041757342,17448478975076065315,9184062444929334409,2666663240625679228,16106550509543621089],"proof":[[6423150653854867372,17541860340290684305,6317508872110343260,3720150516183724282],[4012994884363358194,13188108686276194801,17251058977930729867,1715204375964092596]]},{"leaf_elements":[8059053765769322751,13417580637374693909,2911351709503266961,17513728947462283680,18357528550657626748,6795100929311303227,3237676158979040141,13444877005340907045],"proof":[]}]},{"witness_query":{"leaf_elements":[4255324482078076263,7255934118124132652,772190810455201039,17959576822711592003,12921530464303433114,137933159048733057,9746586303569754033,13805191912974699015,741469464523873210,14875121425059811352,12130362308258886954,12286448181917338021,11696468899664259371,13839260757368460529,10957322820322313715,11769659747227731066,13142922988123258268,15073193552858361022,12252841891808426364,9927953487670315594,18420831693986719755,9400324801574973468,11066306517648750743,18191561972323242526,942408121530211093,6884487128669585253,6874343311312541685,1318605937052639269,3573471743316177655,15142084327262157280,1299190912767209051,16073314742091654864,5268170509892135228,10432171076580284782,6585256402318189737,18080817128299966265,14986819703259632611,6408309767631165331,15761256413554707510,16944174822232528001,13111832579955925218,1982380798468731793,11108132151114114557,2614513145628335110,7340289474176505103,3439217964403596654,1197629327385524857,5848008740332723626,584284515927777585,15271108519536706691,13788170271824523798,1406110096486303088,11041893751185143959,17772517674257803627,8230073622966254800,9751341512649034156,12074627891516917642,3014181978769004935,15696717537472631558,4039983257846741939,1168660541720527988,2901488714050507811,6221987044736985509,5561725980721065349,10100598701954635785,5984258956848779123,1061702143188085379,11968124141166357197,15592060605910248956,13880132977165127494,9012696870892300993,12840395121230810279,2618728629167529122,14249718336935017794,16825707618279471695,3823536751995447806,12839332260170351437,177710247016420866,8818997842304405405,5449059014775474325,6046561424354298152,16261926050335547230,11834490325815470150,10045450942030128116,7272327416338113483,9626395554070482928,10619193477733924570,10436101677766236147,17163053670917032271,14382005732642919870,2807387244686855774,16704994663250940157,6122234314244347014,8930849624225898905,1182559745847976995,11399990066148406522,9174884069485727008,4726442233438682332,14439454487258700119,6418388895217165638,6583977658845676948,2883163073776258988,16951738970677901082,1726013908305490459,6255568260477376561,8531967926692221438,11233944290431429091,9619569159660531304,8864941742678309785,13656385301166356862,17486641023406372322,6776132672993281624,12038698293130219285,6218671748868291014,17934626104271094811,13107622046325314791,2740012361256213781,6731299253762702006,12503048750990109093,15305391106663147329,18077156618635161742,2897955270657450740,5916674478081612141,6586388205453374696,13411767670047748944,14567863666650880348,8358203212025775233,17206978885314752702,16614345768329268942,9812916157868830831,15916619898528334264,3006711704964657663,10845933105136853855,10076617941032529380,14000023853733368387,9422983024773201693,259847204802024301,7321762394549154603,10625152683025657542,9033003985226367501,13330037952961599787,10541834179395816428,14497493678664377838,3241193982807299549],"proof":[[6488913986748461961,15429441523977916404,18159913011486778637,16682305985433952522],[4795808417049143241,10343563363365566438,2385088292063168671,1752845783267621046],[16758723059946516148,17697469900931512810,5006657132905326965,11434697902567007013],[18152825663932313838,11546528491550227316,13166978278980666386,9792403360694885146],[3129408613232761429,2961538795709651826,14032215401178255269,13739399889618514007],[11674509778759929790,12817724386830390926,11922358652152327512,12241467669041224471],[11925128855347797834,8052980194836801125,2766183948800003437,17219862781640409650],[14704703698652196400,15765011901200171668,14304109238371285297,13299600070907217916],[9321775175608797504,12779832459598328242,12672953929318550055,2131909664553096994],[12198142673741150095,6527758916548720028,4299554854204121024,4406818943969520707],[17115700657737976710,10521276456066221502,469750831749372941,11775364338834694681],[7733722255493570015,16287124236618518765,7155460805878006208,16645045380323632579],[1437634391592603512,6858451045763299420,10984741553690768004,2202232512039982984],[17928413948672814830,408258338378604731,12473617573889445635,3254220635894273354],[3401213546233727545,4160889313185188485,3444574503188552940,9739772980445261360],[17636075311908780014,17353848808359985749,12075875312595441458,13651145607292130396],[1360073737404009268,6704211837639141409,13662088324981550234,3380234095738789957]]},"stage_2_query":{"leaf_elements":[17048404412809422467,18339488689816116020,4231085771257516183,8504926401069882066,16967090242954846788,12880291281537678843,5862112751940674879,1051305287403801603,15526762101747788021,4656624920291305665,9332799576509436205,5816471898905095560,268314489982842377,15905531294115988580,11915876236860150995,11056036208724344342,13995508806381279737,14309986161367790226,1960854637080183273,18416377085645006426,15136560662013289139,160961766837579241,1499816688895066549,306606796017942511,1935744577486133936,1405776424949937394,16721670079351975788,10838313311207561928,14231897259052843505,12955080317464942903,14182908138496071683,14562303434160523909,479445927393114163,9597952103206005829,14175209141276746291,2187348646314641586,15523629079852978223,16238081134630351108,18424195029281017237,2278815451775539830,11807690185590722712,3485088991863587554,1791380786361233288,9210167759532583423,17713102148457098373,10066296594304784470],"proof":[[16651191119130190091,10215980576378285368,11118729114655338447,10560099972016930622],[2761479235313320115,8886529930680198537,12779542907536825796,1446203788884654467],[14629438496475610121,1612589856807825850,10400061085902670916,11997120491826428678],[3462934613424623242,18400317781814912488,12920502672925210674,6542058025246441216],[6112093704170629846,12926720180616683211,16579296859263432869,7531179756361843857],[13406686311896863873,14489994658962854075,4837320984240971622,10805039828744766796],[8094555038053052652,5456742084534815747,9308981605796296056,8058073506343301143],[4663798953268544026,7645842411285682195,4011462380606117396,12796475741911450571],[1244958721098107099,6865827727890584375,5763184949719085538,5024484378369385756],[860172641211418589,3049325492872455911,10544371285926922684,8633788995760397731],[5585614427680525570,7434806137567666742,10040927463244937746,13157766076226438698],[7971543820775815328,15084329866545172654,6483230507961962882,7983673826349140392],[14064834480931138371,5474325042610801014,15922184629274827417,4184885445676446991],[1494751650944989641,4855926199395823799,2261247279723346682,8319945380284323817],[6005332309773229662,15757169263984814236,2719457185003340351,1696502891371203748],[15501394167900749995,11197586135871419193,935706737801708135,1241914365515805231],[9361241096660372388,7871199822756612728,13057621005758402560,12934406087966475422]]},"quotient_query":{"leaf_elements":[5808846131667510730,4289741904174027446,17658697952854868147,7102664298785083520,6162361858217965341,11539467997330048912,476349617163142725,5443895251976304828,435030660955895685,8803388941484523942,3757051008134794092,2304699461013449428,11071798014296817401,14266577725894881861,5744602504892579146,5819605310073634806],"proof":[[2232195621323396381,7866784316165167695,10681994685883810425,2422914144272464983],[15806812393016610977,6181661129107175248,11387239429977760640,13600867545308103846],[16256652861038695648,4395187445557573823,15092070462733251119,11271887289653499343],[16868711293395351493,17953296519112720655,15281624814889258398,14460531095408593879],[3272826982310849117,6633072913955832115,16667692300010202489,3896330581384593891],[2585105133651552807,4997264165725358547,11017881753634872898,5052817619898177235],[985246547362435775,929275881499149904,8290696521272781821,6914169846990121540],[17298665779622879356,5749640845600332153,13991184364659816954,5097243143885893891],[14993766190956387279,11973766374340632709,2939482301448641824,3388347981868191218],[3131708874017644950,16415734110276637656,3285519313281445279,16568982526906320676],[16886903001347876711,3651219738137058385,14073440378710780585,12599446174964837342],[8220125938001221667,11058094337373297533,5488388399698002090,10153551105242469234],[989904798337934294,282757575708528790,12163434559545754174,8419516576581128010],[1068144709555781031,17134646516778793279,10886744829654936223,1652588056569689490],[15135291086388792592,16576068135324548800,4881722155945816270,9411245027368093085],[13250766141660135960,11386093487756629881,9978779752784877204,3582753556722114631],[15725155024730071472,2846784656528433399,1476956847549245851,3176915357345878490]]},"setup_query":{"leaf_elements":[14239570245671925882,258389785384525,4552225888178271454,12877835904446718233,7848538981450071134,1220038359194652233,15841892611784316371,13427104444140253023,9649114640037025596,14430796507370775731,2544319803675543277,15194173117547320702,8852817692473976581,4948880560580507723,10601285014435026536,291456062527439885,14787621174552647251,4433269578397431779,6249863039028049103,8113514234398327543,217401948819174728,13251828516236527028,1397615487748856392,15115314549006069026,15626248089728102929,12810901286064816798,13274169557351041877,10920009043843077422,2130602312522501223,8094592388203649678,18012409175390603859,3729129682290033969,16121222492868475804,77027107343735348,8948588722279439806,7098826626628650793,9853146853317537719,12435675607086492592,3860394155359800409,4920901550011702240,10066350872543608323,17282973692635220227,11110738848396770306,1385622697383466634,13259324445540612082,5583668878680368422,8808137722506031129,15739969739406879030,8618336209897893199,3687650450590032055,8387494690948994821,7985627927014007518,13511979128714892920,13206512015483176361,4226367814993674,2484195417538257038,16224787357749917799,4587117230017002365,7996989723267613502,10765667315561647567,11998307049568156540,11770747274369045057,3571800415457169196,16744576124106873446,5970027674950101737,7141735579018052621,5615626522997266337,16038398224088455051,2863132438669110672,11885068171753215165,14177479151023299744,697647866645886092,13629783272362888643,12988799268040635997,11882449754095801633,13575066053960382275,17499852361350966855,362016569071669765,5110812704711653089,18102019695538436772,13536738316956296115,16936227765997824463,17229052833421728167,2993319984639748600,14039611725879119642,16668842525677334364,9389534744798906835,10416877556709888229,13806666016286899308,15207422050115772003,1895833571391205487,15627279828388950289,5143458224613233762,11969449749108406384,3830887280276815369,17574979289394982185,6998289782862241913,2404438558239155086,17050337675794133294,6008527326252199539,8640455058286143700,4107853682489989219,816630405929196865,6641714873589705362,4720028142873112984,17782722520818019677,14439711750488481006,4366003941306661296,13507439091274375831,9369878778613106086,1831368700367944712,10260946109570761306,8016251152975064648,9354758251785033549,7253852850696974249,15251960992344910115,6427159539430266711,9274977617717305577,9249989783765265640,9402706553644481715,18308032156583223383,883639259391432717,8809384365907358343,3707299459503830352,6002017505377941927,5873417981985976759,9713967447365429783,7903272886526495736,7672977987113616118,10476054854848283551,88515662021312709,16698377387559040330,17920109780620112896,14655552752112576305,9990958000143538725,10531814362410212580,15151231891262123157,11231243182708600,8947940464239987965,15820609993873257184,15456175805248960806,2008192896675162398,16555984342485582280,2029103809050587166,13161187513951435130,837869106075803376,11934177541344928984,13051319832964328447,710192797537460238,14037759884775177862,12185691333513885531,9241651618784302615,3339282685606430562,16795940672957981423,11164629226581768632,17349955701489744255],"proof":[[13353246746353356343,6996336915158681313,15443338422382943028,9064551905424520875],[15724079937311247603,12008197474585303059,2309436152688054788,14287387493828751758],[1692709470826818994,9851992330690785430,3468949907495374703,11637959494556502964],[10220256917796807264,7525637757085614624,3181866905381638440,10390955207929016500],[8968908594511692013,9170356790149835977,9832530832544274915,557248382611937086],[8170268325212874962,1404880941274510860,4826261489562880891,13809073014241629306],[17308252007824004439,5323629319349244184,5196984217450197338,3168703541354222962],[4849163924949804106,12785419431232957161,15979826086217377021,15286308999202096087],[17470665274740456813,746486039979767874,6745788508362194447,14312206870053290104],[10006078626197854145,17221487994775438775,7211281381918295826,6336183152769738502],[406837109193505159,5518335085222912967,4865359215700255798,5736073833691942793],[4370672053424969652,2352028303633985522,5206548024280726408,5333071895013855824],[6271959883885264567,9295536432579716406,13278294665578730624,9571598578951885365],[3899532789242128361,11628736177085521353,10067531440842893782,11679012921497484831],[6030633041335087284,17706683855528030775,9824200195094009319,2733486558048934832],[352131923286179634,7794124398289854836,5479446117613665341,14090023505397123381],[7584630324897337125,5855445357232526401,15406563887835073472,17749225028109240870]]},"fri_queries":[{"leaf_elements":[11873390364241369363,1504412723886708227,11034985105529253805,6541552385841139757,14146471341521180887,138932585415698304,12143898966391732742,13840591862223978885,2540574028348217699,2885242609443596676,17434705320729253633,3083934675871444076,12654744195380444327,7536626419485297110,16633647960306820405,628602424884120027],"proof":[[1060034464248583660,11944531413281081319,482166326538207610,13312757840484086671],[12974824788067929476,5006233957202522285,10219029139821258408,15962481107090021062],[4703161936305342515,3982408496733086295,11635032273093383028,3303122794520636846],[15403543755072625887,13923914996112775513,16387845688497276364,11030498492034221447],[14374619072416614324,13793296291704109696,15436182806648085581,14921459977608950143],[4576053845746173008,16158083314973881177,8321450093104633292,9507052420709212389],[13191971468435311163,6603963473579748332,12361951005442512261,3945200425637142193],[13503171235800645587,385583500399120988,11480568321272761930,17829653141709327434],[15156746035344658115,3540952233308005644,4615907507296989110,18138466889660062345],[34833584625226353,3204485825324736939,11848724350850507263,10431367419770806935],[1326506175436423968,1571248614759699973,6847344490977799629,6183086454468175638],[15767380546039469353,8342564351532261737,983077915371187554,12353250988297461735],[6658853470708666258,14288061462074838470,16021201117273385315,13823279494601147756],[885017883695360673,13435321449249769282,5466777689613489543,15313896769676842091]]},{"leaf_elements":[16638751635251750511,3160121270821611077,1136906196684410399,1644820443459839554,336303348808975976,10148803383650134191,14808604279825695078,14556456728039335372,16933109132410407929,13233446248953332019,8565434340358040428,8843485761312575227,12129356254402334142,18061359952563164859,24350955573709283,4377596209860977362],"proof":[[137033989095693759,3281745485639758170,2824790004991332510,15055006252589555149],[7004938964885926177,11441887896521997288,13197209822717378860,406277920735287331],[12871219642507131791,356542892199496169,4475754907783449483,17377882679822450066],[4897376734115488118,16059728854436022389,11521707079482142854,16380756424842848881],[5656833748713722113,7043279263900632249,15613468897652233000,4447016120048726758],[2728521064225248240,13544783821177020103,2220064815488782033,16203489595326099345],[16105670809104023343,15431465476928078152,14995082894835398157,4855654091828359294],[13781885337818544856,14461237025771959236,18360801144793493739,4192053575046995500],[17027911532715879223,14803249834572817034,5646057547018057837,2014488055503808674],[11020032155216820905,14239460558716090538,2553107458770358029,1954654636233882204],[2991006853592388490,8934783177013465999,9854609272269142038,8184295943294888051]]},{"leaf_elements":[1530443270619937967,16678805299158093348,8050043345939895876,1932123006576572273,4145093227196587745,4815343250501582030,12334991574731663517,12060132090151367911,147644334964324460,11008393591490547392,13136167945468199831,4480554949723947944,7054632971106413405,5525919155852587678,17586920920786594971,5740293086977075558],"proof":[[1511397182686085447,4714341456087357220,14686947742078657865,4666816878389141504],[1284924912691982372,16752193941964432406,11429352312858916273,15659257616254586790],[15960705729855600020,16409079039220485557,1506660362052408701,1515673427187767171],[8623922682323979828,1838317359990936165,9503137199557974518,13834808556783480056],[12563558347604222961,3434765312328719200,724459958012981210,2224123711773883009],[8300291083138878412,5069198424524338217,17136951357450084520,3601331646298722144],[9993083837760948409,5970939434941899773,3978708845555665730,17755052416559584430],[12483543229731015254,6228922028592210696,6804550060647530973,7609776898298193025]]},{"leaf_elements":[12771437701191968190,5047522929304205120,9777781168185552875,10102941443985578613,8699403785763767671,9601830289223259758,3232789279715211589,17976305129960500984,8791316851808138439,998353713804312226,10225255233315583875,13612137092200032459,8264088573001031606,15675920651928254487,18277926179641765609,9961577198454518193],"proof":[[7976242558569634284,16826515925178015043,5064713880625387400,13825119735124709972],[2509582715415957318,11057579848539901228,5953462678329807096,14830390329896879513],[12544621958116887805,15976446210261604567,18444223475325847570,14527295136129465393],[5113091748394536210,1209714313524782154,747485470438991072,17485143069284963853],[7378436202281888958,11263343018560466750,12515193662408163156,17578933933619023765]]},{"leaf_elements":[11156938043986047455,8058800495604043138,16105805660982524567,2267992820469558720,12663960685322860493,10046903392075626890,5534413413444273804,3415369278833693594,17539053464684713302,17119473303060456797,1193395596228754704,7397800834845770752,8467912030867365571,838702488467335514,13889134140680315451,11793796394214456165],"proof":[[8918299459814526725,16890029929897481883,6563368210199774689,1850949772037457808],[1130374547257051060,8284282418257759999,7393623318517703239,16641200946473051398]]},{"leaf_elements":[10934508164646927795,12314719184668898168,7161347650890243018,5323539938734047040,427222851664169786,16835810319965862076,8726096516971579929,1018351776603887044],"proof":[]}]},{"witness_query":{"leaf_elements":[9243849291804545253,14325912636495939420,16011677746054158942,12930383858959471528,10002356338321737114,133914711754027958,2987245079399997031,14710461013968129324,3843329169645959925,7404272125549814905,5609610750533276222,5418531730760318959,15076327796164069745,16501619057725415371,3745114568274685756,14192928281748792237,9310394374700700000,6081326691428620624,12714989907066969003,802117669883297986,3369857682976893801,635386993168772758,2557164440365368271,9500649410822299242,15979359149560712679,14070699587276776214,11405422950568976731,16026394937375962232,15076974429891023580,8074308477430636414,330236220628946521,279385322835519133,6096770870215299357,524310409044075156,3180318535681106428,281617994038408564,6790105851231544493,4865473569071685032,1569551185224224933,10434610171889878086,6380547757854192797,4826583047585174316,2317217597350400531,10628898906600201800,6167685644412734481,2857724881516146324,13950210587145527294,4895322647248885314,585759280119810067,4575878745946073100,16270454307349158326,13945902269175548286,8832443821723965676,10870429816657997439,11489142943601188162,10976546621998816896,2835116694686606284,11852024174524746696,1725504053307945485,11211217936160649302,7896016802508482653,40230247376601382,15369846083913186500,7183339566172855167,2434710505890391480,8850729236674068911,3256787496268500718,10045184731450065382,11279821099608533044,13000302816800340750,9928725324673439103,11525774318612402831,14344790618098784592,18035686025526182861,16392501353460034952,17668281135389315338,11172874775088102293,16722480673310474348,15258811799075344474,7844088803016890245,9856210660145220393,6482445150695265596,9166901915256506286,16477049401845547123,6969171645977364827,8783434347840119866,4232657337659827589,6761111924354958011,16586947972265694572,5761595144591402936,10301878768811775046,726202410926518804,9069628700317818557,11927930080761742726,3651086835678021071,7042216535173737083,5090577004188193592,5973174599547815036,6009599528251664309,16681617843398482545,7548778192354255005,15550087352318333225,7644331294443662671,11752664957254911086,10225948241138269451,6380474673247160792,10732749472918343577,15049830534507823739,12875804596326151236,10920605350545764565,7851484941148346266,5523829014526516908,12026392067979932772,13506339386575908357,1559280086755727640,12719601994853228954,1787048992266423574,6745056458973965510,5968764449828891559,2525627482444456412,16827934608626227211,4214474244565625677,9158057105285248904,3602812177392318774,2830665330178797048,13154091710129633682,14860675087558554487,9856016171651913082,14299736785997763891,7312785564056235589,1447526485859362025,2422649007906435626,12208278927769196559,14570041958707665369,11097224705774340433,6684475223805030344,8541840283734086583,3907949531443587772,1048807045777405899,9846327544127135372,2344228615691252053,11575984007493213062,9077920718013664719,3000195991330363328],"proof":[[740428461501299363,9157467299191169097,13089576873659950954,15310835349572930588],[9642221041472258499,12436039277326965540,955226046222344858,8268523347701612222],[4775875522517128860,16197228364735222691,7622627950937701691,1504770704364433351],[16731800280014741940,13787973214902533012,16727717710822078357,5772557359114967875],[4481481580228411115,8576967955710625541,6732222928371426080,14892922255897072175],[18356928341813099766,6826704505396912285,2847425041418775080,7217781984122755635],[14070587968716874890,16485561252059288657,3636788285962414153,4825596255223296769],[14663866911709283115,18266412883262425479,6732661267515300430,4162459104619422132],[12383690901574534877,15725921574560955236,9760111970271435853,3882257700259277129],[3509609841816409986,1875222894920358850,4049458554996642972,17291582507519511250],[10181481139528795034,7362352860062048270,12097889314192413161,3516607431736363284],[1094853921598482180,13517530789415017244,7824488999489564080,17419864070309859669],[12648044226947071686,11183402059915378931,11997357237669024929,6288194467082723342],[365853687983279010,12982723795007105120,4158164774758393705,6283238807100895841],[5224331917109680441,6598835313364140741,5627357161473253854,10409932730424475483],[1485233880896638379,12071662103515543055,2139412878003956338,12505221719775911968],[1360073737404009268,6704211837639141409,13662088324981550234,3380234095738789957]]},"stage_2_query":{"leaf_elements":[4966211301332734929,3055358647599729355,11233884423714931252,15973980301235398380,16726729033176618732,16208194879243230024,14595782120953982405,1971325693209187955,12099561052070906233,453619628665073701,10071850165252729415,1555230116039264927,12053016166640495146,13567751717782278619,4744456175043697051,1964779482956635691,10980250837915225556,12713939517129704271,2739477515727027886,3536448010757845728,6651173625460812374,427043026229658749,11493708631205497602,11795971069217234938,11472152610542413169,9743063309796081454,14170642490999826663,15640456859253411842,17167319063870427569,6917210322479705782,5150938317882497087,14390674471639404372,16011656814052543255,9908150000594210313,5026366401355224049,9283206308185860513,10328938396705121993,13417638895110040545,4818434514701779827,14992980384742120002,4896633001297733404,17586520064697672134,8188621697737716471,2895632938806020933,16379031666327457446,10319978489652714393],"proof":[[11707881959592504071,3051957013188246432,1051478425148853188,13439821010886182050],[9193570332561586718,1781907411556917325,7803047040360480747,222528767498748697],[6286511524416199192,18327759145047357193,8902128927278911325,13429013839372359327],[6193181354567392378,9972495073536797072,12287262852887124677,17169018360614876898],[16661896435377823196,17534217317302270031,16281458592530083260,13127163064361409590],[11410394515925883964,2860671312736156620,10929175560136833585,15158111594072708702],[10097010071138329650,87933032073243477,16424604533549538682,4261706852049529059],[13100454913634582508,8640298908776776512,47015934071279596,11871439332284126083],[8516185359388411128,12874883888474191376,3874149598552393257,5462071980562227798],[15784963065579817637,3541994665135236705,15033413282683426494,16030033718596396980],[6982264178750937733,15913684890019870762,5754002414358984964,3713005939527346164],[6668741004946678525,15574604184256630122,3945968025080809674,2410948583179462838],[13175056293718725493,2352145847162242361,7347630899830391223,10524187683754548126],[17684428011770412940,13926910399479652257,9921951111939917461,15607398847386075208],[15305483213261681942,3870622862172377250,12772033365770669216,7358212229418854563],[8319008327255715913,16607857083414074991,17654496975262618756,15647971105491672436],[9361241096660372388,7871199822756612728,13057621005758402560,12934406087966475422]]},"quotient_query":{"leaf_elements":[3413253757156549565,10779031375504531229,12121556453041807464,13008700401070577699,16070090226369079976,9858857943009776460,12636232301195693511,2913018542377425501,17683951676911752838,2330080532369744773,9335423586632197954,5932973095651526861,521284876661527128,5914419467038864933,17840630575175672288,7422198997023489580],"proof":[[7654621619834870595,4322991686885087117,11303174483278456137,11463495726961096230],[10537828486702493674,12449021552230262075,9622179611607223800,13919737481500282996],[15749153490724875971,4595498049966229118,8884854954607488312,2885128028592844407],[18013784336956099042,182579876878163666,5954916978718752463,1525315038545943789],[11979292299404366775,7265790532961317258,2509046652512365787,16092158667927309315],[3093595478848581829,6633005157012664715,15758362233730972112,9133956514063476454],[15867021917228619650,2006759114871532360,14684293932392693845,9721909516884698149],[10900435420994237624,393352068152876083,5027633924444999932,14227702092935259962],[14386322984543424121,17676906146568519915,16119674968594802982,10331352955730002281],[4582463463640765755,402362464787023077,2351802973960240720,7146507527597238465],[2914945288849863980,1655660127046433376,14438962975399087714,2263073314056397737],[73315089426189248,6241751074850668474,16204365349049135341,5332883172663138967],[8598157565685120086,17829017884044581368,13521900008315514848,1199344820299523508],[11907433163258754287,4102402208178005313,11373680436316053231,1160586008651705573],[13434498397880401649,1377437689243008671,6414084363350325787,8876393564240908015],[16270142854963809435,17117357370502291560,4036575513188496805,7297495482732776731],[15725155024730071472,2846784656528433399,1476956847549245851,3176915357345878490]]},"setup_query":{"leaf_elements":[12949968471819967829,15408720835095986262,10194084236466230820,8936087654452433268,396262300692176600,5716725463655080999,14989322950521504810,12721676218604913196,17268090445563229026,18434746460817969259,17474217255588087992,9999455990561115998,8190461391270750279,10631378718079963332,1135604125099350230,9053726547361075981,4404647608401929893,17147962581511958814,8030772370211178087,13581454039770533132,3177701790071338739,17231229934401739704,9671253843457602712,7619156480766209194,1045760485495950398,16317903839755457595,15387414538265916926,14865780893149785273,6174670427260826048,6934536661248348658,4961899844529247335,7883588151397443058,14921650694735577882,10688817944002005682,7990009406022573352,16106097984549369371,2053925884174800244,18013006220646941141,10235828288111860553,16365090528013735864,17155429997821405092,75927137521452365,6635319181292721671,6403603168230942326,1951857109281535951,15839020641661496117,12647636483147157600,7062478990421398546,4939658892504213406,17583533353435826345,12023871525118378567,13947157581421917728,13055936646453924825,7467679327605546743,8495104694664822570,8037354528100008154,16908186252052506591,7702136638919225053,9928727892436506231,10603695196197987873,7654708345963532807,8217738541470615126,16604805493774604341,4939171346654774955,17558005115932546305,9214915774405654361,16350399277990742877,5741964990409183418,15608947456348952006,8101836426169704014,11457020311794520081,12155375235709046095,11035516762635163037,4898827795895034044,16290337646347567729,9838238940276119281,5856307969838655129,5365758940587413529,3022051815856581593,18088223270096492738,12373649021525995342,3535981633467342353,7842704307051444514,8350184066131234760,14999199062203746040,5609618479123485113,8240306700243659991,2120474241097613611,4650442673316364677,4179032112025909798,11858356027977362402,723587370374916921,11388261112938861911,7402184714486821058,3005897050553952054,4850855919785259866,5780972284408772292,14346263975371056828,10699794672876291758,6631282423528397623,17581087535750658210,10626965807396254212,3808006642974054562,14615320491029110402,6774317003562184527,110076539641418139,7099504044080081090,17104906933963298739,9132792247868300954,10413663565401170485,1174890648695554041,1211181695462451728,4441223739000311585,5174715011203497358,12857002632478771307,6871617463624014329,17278978445008895632,10292909327441458781,829936659291263124,17318320396336382514,6871424352443995562,11737774610976168341,13303360537746413685,1014473496394768298,11321568906979940270,13394292465006237746,10582251036901744892,15638765685540890476,14794824350603647518,3273612747576266954,2937533130605775945,9363202200825922907,4531125517069352402,3953034384208148115,2758643674082431645,6746656594245609536,16517759776989777045,11975853119248882088,683870489138790541,5017427489496469654,4939064776534909388,6909834511347198347,3122769274653834221,9175008050539853704,14639906372534093127,11814098019606322881,6070959551705132994,11669039521725381053,11403661925487220416,16814373147792891036,4178480158295526589,17058892071367654105,12057371462269872862,16763792110118468237,16506901262178056946,1321432849076844139],"proof":[[9838813637322605821,18113171428948148577,14693607927462614806,15049742729687391589],[16987931536222578278,3746900993980322255,14288729496118553527,5344985733122113714],[6957584770069233581,6038426268785227176,2760202052146583591,13108678824475605175],[10288874032001677018,7146309893332648372,10953598584082329691,3296643132469818514],[8630696675624304983,6525700174702813341,10384990562328730230,6823234593775662076],[16928633468419108395,17279631491891207123,15328762559750238914,6614376675774966873],[13279893844487660522,3763927548388654289,1155339926051251335,16231070008590404255],[17214385042885469800,4489379753811229684,3120420575113619674,17409152257724559998],[10166606034258789735,7194371298769308878,13879223398927479060,17464161893043273332],[1838304141179052427,6916114132443897314,17320516382433345836,9018509390496459592],[1194877290241580232,9526678796593065660,11065520208056975637,1802415101530690900],[4436484802067496190,18018809521677935540,17680402534391607806,14920244924261544819],[18418843398912362028,1882277031497938854,8190254225414390979,3640102980966577172],[14590444149286529261,12613365926211339319,15071631742151426368,17200315270947518517],[13153488764905338662,17294234018794914879,383266437505029734,10715325043533038166],[15832722289687690706,5355226235880548863,4170637444115930380,14904023068600351306],[7584630324897337125,5855445357232526401,15406563887835073472,17749225028109240870]]},"fri_queries":[{"leaf_elements":[16143322054863960976,7456454834373841699,16960840710855589532,7989905430013531430,13236344434917041767,5379091065760808739,3485338798073020458,720712913528309710,641718700348633745,8365594107823008176,5857852405466929457,2068897643232429602,4014453842140578117,629508210485313480,2668924456458585740,11574926037100588903],"proof":[[3108940313665049530,1029215631395163896,14580081809417037996,17337664446888275127],[16987400281884189609,12119712367998734309,3511754018840675954,13449437983878051721],[12743754996609132974,14567020729370813022,13940630266625166400,1403847572936051704],[4746256970545643886,12334587734424493549,10238685618417628220,518442844986854027],[6752258946593087767,5972196659179722409,7966474044003885359,3907588242978060402],[15379394124158042849,1727839643729369182,9721449131139770090,12851734484865086021],[12788929117840009982,8110695254943841864,11326998508922838754,1666884174758460728],[14380723204061628091,2426623333572072519,5921161288471898018,8355796719173952117],[11474589009258660059,17116959284069596098,9113843330138103060,849608150865603954],[14334425450809270460,9093880966772178480,269137093715398240,968745273070822257],[14634351391148075774,4173936561396501268,7974056935802094082,9214873540013714245],[3424565659697107575,2212386926341110099,2945411392726584410,1986064473197972921],[12022107492789539694,14827703569735874720,11010683985336556729,2708594108380546783],[885017883695360673,13435321449249769282,5466777689613489543,15313896769676842091]]},{"leaf_elements":[1490096332908086286,9580875482749187003,6312024051612588492,6860296188735838518,2081437891698948173,1817135679941619701,9640811777632194480,1171093072439887732,6318747644596755688,3608205377328731654,17892733863297858154,2617710745988810218,4217799239316845235,4065530943642865263,3685354833866847210,2511561938184946632],"proof":[[6208818213709657441,10624440523109212010,17283468808587605133,6173533566580005983],[10402328271758140840,6316065367697395393,12838300076422115074,12153844900091913885],[18008014029107360488,5380405561600565016,18093467042020964922,9805893618285176928],[4836542425201654433,17789721920054995804,10720343810060537122,3307831724787070809],[11338290731979066828,10943652332631336068,18308861725845744224,12961783123914572934],[16587625111889360753,1587399539221367389,4610177925181791749,12815094719178842252],[12728683888496822726,7825207925577372487,11712873655727604806,4464249637934300226],[17436251114921806417,16535798766211800611,4851878849710974566,4277226705572747051],[6403746061435475432,15913864629493149740,3308487274169460013,11203944096163982866],[13500830884699680927,15306338317233456995,3299836681659625374,18226561178672362281],[2991006853592388490,8934783177013465999,9854609272269142038,8184295943294888051]]},{"leaf_elements":[2549513404262042269,14077637812338416503,7573726873668166474,3267296257094693042,9886105725401039182,8394013095279252129,1253054858179470099,15084940532367328074,8971948051850424077,3657355262206386495,3958626388955775906,15403584505119959478,2697429180589595281,609521984863856476,7848359834751854158,65418356726267212],"proof":[[17722997117907374425,9384608142515575408,4602689798759608502,9511902871205750467],[9889806703621353270,9580407361178586371,11101234551724338241,3389546319509333079],[9566071512551529885,14008071294681184896,11168312399455446316,17060932572561002818],[9668992045097784803,2375742991858771817,2368289079950439987,16265946648965297977],[526920546931521716,8212976993424576662,4218974118067087499,3073881240728208286],[9653031288271274176,7368529689121526004,14430692323790644160,8836060061319362932],[1806088966856210746,14248697546475838012,8730757304671791597,1502249710639534215],[12483543229731015254,6228922028592210696,6804550060647530973,7609776898298193025]]},{"leaf_elements":[624011700170694186,16249766355757404097,10325164365043784356,2210293684905222512,94342270689669136,18394521652221401455,8166123255373193429,2623450016759433165,9871805180363165689,6137360800756881370,6014283743216838902,10256881392402960233,10627864012119849884,14344957726658472771,11232446996252744592,14352954499688768895],"proof":[[4370858313825853847,12445031081590722686,16609101338940950694,3506890032205510940],[12837418204452230580,5880114232396079693,17219826641796858692,7119944924535700114],[18262645052720567710,18348730857695951440,14721440193968122228,5552481305078184410],[120353459084075878,11977129796923774441,3691473483747185222,4915274756070214257],[7378436202281888958,11263343018560466750,12515193662408163156,17578933933619023765]]},{"leaf_elements":[9189383041842988590,6965146586893804418,4220618660081283782,9999429366986671194,4630406983623020347,13765611947963961084,6123428965095967777,15132008706310555292,12812442353949431520,500786186807618677,1689459190315911207,16785331210584185479,10900878928231131599,10840504036657509228,4695360181196839233,10671523540088974323],"proof":[[8007485682100854625,16814109845768904116,1453178838105146259,14110354663391078558],[1130374547257051060,8284282418257759999,7393623318517703239,16641200946473051398]]},{"leaf_elements":[10934508164646927795,12314719184668898168,7161347650890243018,5323539938734047040,427222851664169786,16835810319965862076,8726096516971579929,1018351776603887044],"proof":[]}]},{"witness_query":{"leaf_elements":[527686254833490171,16111493692270859329,15779497864132046645,8534108100106089212,892218251953891522,17848580857626214731,6649062943456163137,7414871324600973046,10663658786504950379,8239730226277397003,8539213605937100618,851832003246707510,9983191040783089465,6380196973263840373,7177279178958362102,8477994228742352553,1368330814921524976,11772547251653646301,8119742370777071780,18023095918045050212,10894458333822353728,8880108230141502318,2812138359948801495,6158443297768674442,3205293913568222980,16064147244168365057,10031092953881493141,6711799713940261157,11530882553842951037,5022515893217270477,6856345374423624631,15497694023384220837,230403019761455035,4329033650565041053,7660857317782030599,7977520493178274409,12853585121674449250,13750353302470666573,156303459621358073,11107401698455281117,812452244343504673,8387941177688353117,5011508549750888997,2138721851995977500,18165560192519169061,13932485178859521342,16384433222804272448,9412072127731952667,13149627107083217344,10288792119295571249,14082436391443092477,1903023956674530017,12026152967779840193,2770284648810299495,6485096687354824024,7650481406300376618,1406735595805678699,4246973351136447668,17328648689715346199,17961557515521472588,5932273476295554739,5000870854188845353,11649677517622250088,4689289345593610385,12689477649867643281,3057502104318126869,410153810783195795,17527771412696317749,17880398805527373503,16691844249130384795,8425412124590105792,11518740686050239604,2673747338583661379,14050104063745452530,12575979211635526456,2587829616797493191,3148472186103537692,14012974825375246844,4296546026020905417,7735377543418367183,5000734209464353761,13536817174769625192,4596513041127943094,14123596766003199534,16757698965649686142,5913034887978559827,15092705523575019732,17315074477753454004,1606265589036164468,7725139834416490592,1262725500214084846,10420262375102746766,11056737203830923073,7138670602633718051,4759631244405042737,10992512945657102599,4644020776118228192,4998291032242880239,5785081618550542602,17400729548139877072,2449454709952503197,4488904533759378080,2450396012440691652,2220930964605101545,18328175285202663121,6239800630367162163,8722875783909997093,1578583907646229022,1367210978048205979,18017699444686408753,8973206767012283598,10854310934904094841,17918797361915754508,17048162337911671687,1234590471912142607,15356633066852092481,16929161203553928232,3953956115806121723,579281252239916026,16420431766859822033,11543836401798190008,6281229597072847063,10769985967197301099,4620245936514878798,12871313236019427235,10062232474154036159,358009637183013569,10383359261288662250,12795080507772264333,887601667093639123,16575737490973833840,14161957172558752853,13935125291047274332,14775170954288539090,5880025027977875312,1270562547326387767,4997024107205980739,8683119675381955358,13617304912654883794,6336391632011092605,6028974690155095770,14133980339486836294,5103373084034357344,3980730027816602504],"proof":[[11674530342964211931,11756532872751369448,17073020165239390993,2715265558427653485],[9864262181393464339,8659634507541036641,17082925525718803011,5151591125634083229],[8510367787931892288,9632156448572002219,2908958197196687267,10105878725716193072],[15557244598092594515,11830979960257698554,15154528229951259943,11671810451644472141],[262588468838996231,13917262831446388743,11042137055011028401,3484937864025174968],[13669226703451404998,8995297696135550475,10558782975922649390,13425173408911662040],[4463890633466846035,3104152308265178786,5904098552552893644,7398228438898014048],[4164764436556671124,14642932682764488724,4192918821654293696,2614616142941070115],[11501088581408775307,8865478881805814657,5966913638363551248,10531917959307637396],[5093417941490303135,17017740945428141285,17039912353552605609,11160173896595374220],[9291788227405193616,1098772704607483926,12779368622788970183,12885348264364661870],[1048685461010128882,11747662658968850497,7442779832110571828,15014641332127534678],[12096612533138217490,6327992540407241914,5694209118220416568,14747179122768316783],[1697462419149322373,7978531051850176898,17319845532610696288,14813635994939137566],[9073581951084630430,9074960744553192112,7645099772428998840,4812123668712614518],[9926660428113497998,6267066272347900846,2134114056503813535,17298158552949330694],[14867216664302836752,12562456856035097602,7756423531439073568,3128883302367687612]]},"stage_2_query":{"leaf_elements":[16768533339361295922,1503649508344632089,16320216611719692766,4968642259611252972,861313329259365959,1607855310971399101,2019258595636615750,13524084338558464195,7549666990316258844,15186220936901716433,1651953376174341236,17978888394957000006,14384055489690425434,9255558465394430838,8421313940976236456,4519332015626202050,5739292319658201582,12800410791030288663,1193495724406115959,9566902988930177356,3273219721522570239,15044698429797730355,12970557047694010610,16335136079444136064,18330412071311702730,5428000842572847986,13608985902853111902,5153796552496700439,14184146698251968548,11545625261619647294,7027369761496431093,6907864405825605467,4629018318635430197,8763136505336318077,10715599584485044126,17628731647161517218,1923393131144392296,15607335570066184365,13049847301938038086,1489712995065065868,15519433252573186554,13900569098938849813,11347421510237250043,5349870484704464041,11285673933797014824,4299562065049958733],"proof":[[16802740738265506096,7369202470746658695,2471327479828988968,4619415440692761097],[13140030922219383394,2013094529137377136,15645583934111892029,17707789992854352557],[3002794943737087249,7307888091625340302,13505184273016853467,9316659179910211684],[17207518882501045617,2680186012792600294,5960765802287800774,12684115233213052246],[1071670197680780890,17080435783809490304,11439875867044689954,12314642877254440526],[15196622817940393648,2870574621547182773,517133846100517999,1786869972106376129],[10068352499063983748,13900483908083488742,8037035078500705832,5184263494538607114],[6196412730559870091,9654826572111648065,2883543499553653706,12976097725180451214],[1525383200907315567,6968911617388816867,17348329584177446125,11240526627099144294],[1054527834311330469,7032167935146042671,2233691530444422034,13529437336818436353],[17265839451803927654,939370559771170344,9365110641488766077,7344775745813873850],[7026841541454218939,1921330458041396193,3441745416812320210,12766549984463799280],[5748442948757984682,13457778698059646577,9182445113543399169,7891972012293123208],[15672199239702077907,3864188327992887019,16563061175442416237,12505953796713034607],[5732202671083685557,4214781925403313636,5740841911921625670,15856568051689401189],[12325599187125427775,17031099229203075872,10298027793122574664,3335155613261841157],[14260353508351826515,15997840699848638873,5926302242716405762,16396812349572820247]]},"quotient_query":{"leaf_elements":[1351486609985849533,16683865967144700616,9346351971848800529,4465522090096989027,7365010361602576803,14706992947352405026,16425567804647667757,18197841028657027971,12759422848387937973,12367761417101925389,11806925246619581741,13055951315106508070,10249609437361444009,12055454054881743265,8254581716697009284,1191379262184794670],"proof":[[8311021565129262252,7452328139388306088,8738493575525600269,4525926093520561191],[4593823392066599936,17528044698238537101,12445506495166683060,12383939533836281868],[7561085562412324943,4132902286013257882,776111578946270128,18301504528885703199],[5261165739686560219,10175113305575416271,3583776642427068402,2666322816443621598],[17044394771667441638,16700976034386728190,8684378885378681754,3191552822111743445],[7901136625261281629,2994794872099583346,8808725450615695040,5545121895170421719],[12592288941167196797,14839600432411289223,11835984391701730157,568157988735688089],[6132567772411173057,2753369713477395484,18108791637809506476,16006750509615832831],[1574573356952839322,7403197130783566231,10717887861421380369,10860681823899671690],[5277194889751624252,15633374442034794416,14989705639580648105,16441401915082207197],[2741334890481348508,10838653869657822968,17204952486398301581,15052462828574086288],[5021655680101174045,10657974976520508056,3706682661668701196,15885737458364046119],[4175252758098445114,10487730627054284759,2727378226316783594,12270793705458268603],[2284677350046796365,11241974875573871675,9875778099136208958,9865054903493935145],[15747924263585238379,6130441633511803075,10534956700300714876,10623067958403260140],[9535674946377222374,17853419219018445682,7210785550365260009,14496947166993698046],[6428516624234788705,9287937350807014828,2717092354687218549,16008904268343540721]]},"setup_query":{"leaf_elements":[5126196489758634707,1571692052557875816,8616974353139512887,5169976522198782609,11553213263953909584,12582756963739509574,694448162172715780,6987861791086108456,11155619493205399348,3033781750383534690,17688015407021339405,4165548714020712659,8769960895842001422,15526187977661295888,171695435281075505,12228837816580734868,1335725384582304878,6725700039539717774,12873707306434606463,2540950343175734186,4416994242660591318,11119696798761016234,8732490595240394284,8764854681515535498,15850941647224669639,16930616961391789173,15436892504288788033,3738068796715109708,12075101865139461269,16899721512861191117,15335208725312330922,6199269524911027165,13325437995469880725,6065816616712050953,15155713586347462608,6294579328339285341,6571608054185109419,6337177514350315655,9686704986209121219,15722679941036038668,2367283672412029938,341431783692821859,17802095639715052166,9358412968137046822,114853188891084960,1260159808018508894,12908542043514495266,8791668213807567588,17772659631690481544,6862166652306186203,11625760502225017086,11289986704962016845,12682715801807933086,13264352010926425920,9081360891755726057,6696230589459369214,6263736257964604782,9503147732231475426,1549778152899765318,11965514709918071127,17925474723972076666,4387097660748805329,16734233522676708589,4831858856385435186,4136419328269904617,1446843208652730321,8921613367333814917,7581073853998857607,17889843332252973232,7644871069842865422,1427231201211254929,2341587148621126521,17880630535954425181,4007777508986366603,8723952123863094189,14679769804403856746,4679895602455678403,15392021109847843853,13696427029126537723,6714815628575485930,1907594740487016286,9119108536327368704,1280163320227207084,12063222354506518674,17421325251355109084,8905198690516547997,10189031671976598687,17693316916752776397,2375271820170652091,13994607307779834291,10491950511447089469,17735570342974215514,2107440011975534842,18065369472080063990,9012139228922986911,16175858094766175854,12358002288991966277,7867124701156263395,960615598582414203,13220241703523956319,10466975107379617430,16648977737194386067,13902716298754271211,11502712073381286663,4660750203817669752,3380724408323322117,7024750902192767720,8194381254116273246,17038958351771903947,6735923723273130857,6147340840831914763,3474634178590192277,13673754807485525153,7732950154913101760,18159024597050172729,15099145542443968384,5623102990184168674,8557540843028565215,11232977217440036248,11237600519231407567,3168490287356724177,18372516063442240080,12327790438244082218,15525678401471657210,13023944161862406687,14668764380102834415,8555359962468430357,12156805844475851666,4217560958291639738,2721923059771642347,15551618372008301212,3873109124867934477,2776680370654923856,7828626994265239663,1920051195756728141,6647437633711787443,11642074207140894770,6222396562087048373,3350146183020679498,2006932211728363803,9308802017956815880,9376505095579031053,6004616884456210539,5352484254751705696,2817130481119960433,6856315917040483379,1693043945883034854,6198197457715805233,7760019357249574508,7198226037133981325,8003879149156870299,918138262772515929,17834092515459512524,7126522585616800569,4752632575241340113,995137999817953894],"proof":[[8586605601523077457,17794073368935060923,13946497955638416744,3663345388631336828],[11896914549279812720,7290087836589737602,17929928661003259984,2629936929181090961],[18216128334229402045,12268670088308264137,1225985548570540346,4957138105765752927],[12720591600071214242,12939636172935532650,8208058025473074094,17728167332779245189],[11459770088260408321,11031752983655892185,1547257324023974172,11388072949808697138],[16086152224673091737,890043340999775222,992425598171647137,8384749451994304560],[1933199040617785196,17239340032791118038,11322787890241799873,6298615725676956206],[13168909472819459193,5686065833531604357,3915493464464311242,12232015441498968296],[14466396166697918364,269395100117757139,10260619227988654301,17277047510167995879],[15624140017152286911,17949730574323367317,2115221292684650783,5880100370643227656],[3554057813793223678,13811801172823373108,16050835753633060706,1409946284791533001],[12755423280985573321,10227310029787774371,103778598279315009,3145081380435020700],[9945846170858205955,16792910940443524136,13319280992828904584,8339489942473499134],[3723822754732587774,16475616592808410387,14885906478355696786,4713293042870865981],[480545794970438510,8732235402003808864,6173170454636831622,2043219653410716263],[17857902469397623891,17664440104555915936,12305219403009730448,3018465272199973818],[232796533062090112,4701081437590138433,1090891335699248712,16484287474631432090]]},"fri_queries":[{"leaf_elements":[10052841183675627076,11831780007038780383,12672308673150989945,2444318794886048185,18065758829018351172,11313755358246830816,15822338768396784077,5332495258112555223,9758108052955135295,533725555787512004,235836044044659828,1035779504536927084,10101593157204954470,6682647937805309448,1144648850237268437,2265215018969182491],"proof":[[8109128946133714094,5620799610704692793,2403393919952285002,7743215955286105608],[1221329211315188191,15997252607110123042,4985070350578217332,14934047804271481622],[13575340618692410738,9640115438034588607,11454479717905476017,13800825008952416065],[2778649796306287137,13327726145260683772,732996316193903384,12229453027359710441],[6363088697929561447,8477447234183371377,3674994786764514478,14550757310218791391],[13720910484111779733,6318001985837466192,10771781690833982207,13299299428905126933],[6323755619633274408,10508336134600584176,18099478069788018861,8814116210398057668],[12150041233508579311,10860393420214476407,2445806917069230963,13288833939157329425],[12914157908063554285,17052777227626504180,11986249279325548359,14561620252169023105],[9081301388671950952,6188058853588071927,1629387254143814977,7288547943301811619],[4319403839767694328,5866565044044195640,8862433651137477326,8835361410716022936],[10215674024073860752,5148762293169648068,6052755727892241992,18414250955180193510],[7721061104706327468,3078950425117453684,4321428170273408066,8025265308058761849],[6169857227742315395,13357582364418817607,5697734732019327995,15965541982362316595]]},{"leaf_elements":[6047025639141661679,11621156064174640478,15531689446569923568,18232621452889981584,3646104319124450810,10380781211264036344,10795156152556759717,6569814191225447378,1794321564714069850,15000576667493171184,14003251170160021268,4229867218443589176,15548556679703855103,13059068064801797042,254717725494264316,13157407574974530085],"proof":[[9567015527242744539,7265715490378853314,6139916053783245727,352602798918261163],[11208419367696038006,8046472604741388515,1690859274124298702,17539195936362899043],[2163293446346317389,10510436292464653737,13071669377988807463,4851424833827421405],[14617985442795329544,13043565886499667743,5118185161850844683,2355704478272770241],[15338609392459520721,15553180650880929545,8274603037001228504,9715559982157501929],[18082740761445806679,3896227859964392083,18270206040685489593,6317492807708705002],[6560406556913753470,508164590927354970,637752069692035269,17613994411761692022],[15884720337207313835,17964067912062646796,15295560029957470279,6291607903378198221],[13603085314785962027,3141572424395308695,1271333253185227249,2684651342162071363],[9027247964270597467,8154606436868237285,6842214611531512186,18031591689994944019],[13767557634651448597,14275372649907910762,13782730872602003299,5632469238773170118]]},{"leaf_elements":[14677254757376657019,1700198052186205782,2279943958759076500,7010978898883408281,6190507509436339721,16450879068977914843,11025598663296880407,9329367979967879988,3956466515354724798,17231532869166301936,4418508827721150301,8644679274259905812,2036564268668614369,12444864091956658447,4222236575291958876,334797204595051343],"proof":[[1734936296849358529,6963727289283119872,9645803333521398199,5233574866255519243],[8597036915966455994,10833052720640508168,16489911399569574624,7336363946402953567],[9236789505143476660,4385518614149458630,8110169562969036197,2526270978744243805],[5413899640669831312,7230681680359989155,12035875232601044527,8187944965122609719],[10726236407679584418,11505520150699338112,13148173730673261147,12729753778425358821],[8922442677676624790,10499632036774738363,14688965054874806440,1675396503030019406],[10726006675864965269,10412444321227706545,13766451279109910579,9820516533098999059],[8453612859827862692,15597950537987769407,14607321109355321458,12321877943907868015]]},{"leaf_elements":[15028288332617363772,5047672619688167231,15322493938566321290,4206182343813683357,8518958231609371795,17446667675233913996,4643497483794082227,14480306435468444479,14637182743223863945,7600980294546306183,12972003565837506793,10945335541448917522,2502845991949719851,14476347936677507979,14022860052400705894,16169438373228909487],"proof":[[2860677367704675273,7700833567747303599,4302415069543314395,8336543201190730811],[7813655253012569315,5732092303136636900,11051110244439255770,2502443877189860117],[937495756267934455,17219799417155133659,8217850018124047868,1916092206616157154],[18234500022953575530,14055399872597315795,3427577728342593250,12547579893448064404],[9732057508331218338,17742413443053399360,1687316217664623535,7873157723082167597]]},{"leaf_elements":[9387637197062045130,4652150522521588239,15637073202795890068,2447469261090042352,8500272786629289830,4094976198972476677,517297902365875451,9000026468635167921,7061611386518741297,15620241781818337298,3690660075841803327,8137137771409335909,16415713597184981924,10016555926185050401,2829838984487282123,14101446198618882559],"proof":[[7892846885318146075,2646950059645177715,10326596799699919609,6852025232699733221],[6156120735936047017,6378596361573101966,12234030277201030515,15524298584112405956]]},{"leaf_elements":[11907939937929050222,12199976274714464765,3239066403731203959,17951336118807113373,16307121117972480027,16234899209723555345,8364706858358154655,7274458572308793086],"proof":[]}]},{"witness_query":{"leaf_elements":[597581723669704931,11483811183210478205,13480850716706804104,26558141795275081,18202513864808945393,17580462681689480592,7236795308807567905,376714315829870383,17097505599804182251,811579694938012605,2170431193298214079,7741603635475945927,6264862497656339401,10031047375994584580,16158306682107989448,14204459169292220827,11716051980347791916,5736511079799915906,13086836282250352738,8369738629273797476,7391512088085232344,4668068606746930714,7808423793338816330,1845143964933065203,6096682448976852960,2753512403196975526,17246441724659884102,6862302424073691061,3644386284311498120,17889023284773797852,14496045709108585486,4387591249879394083,7427887950635243443,3825072334616965261,37751114538372363,4000580274592730974,9316009211891800794,8552695024712046531,2371128161219965606,15280856345603292417,2777693170312710221,3101279718695623089,15958123529420023885,14467707227086110681,11089266508164750185,1958447265846859150,17456495685418377955,6206254270190589718,9067802851068211785,17201306217461898830,14598025846697799150,13650369269037573243,16048965115721340294,12294611367047556881,10035047775095894113,11811265743257452586,10871163287452840091,6033859404599809370,10402044684355319998,6074176579148270908,6567520730171689606,14247041550950248902,8653961467896179924,6782343590222605354,3899701045417667344,10877736499377268797,8415805068604688576,13063336111179453337,10666891006935641227,10063857792539672049,12650242752114818225,10069082086335056268,13270107466488185367,8404304598595282269,5937922943616061332,11769718588731177820,8977489424024426052,722560789418221227,16586555442675456989,12639105065892458237,17559982647991582372,6069376585961326612,590565321009471642,895901858853548115,3554346367012231747,13707744916565973160,7426133470177312212,7358369750237191498,6790810546775018761,3713187151252179733,8001306547469131078,15148912345743867962,2784157366090955570,1725716417061027714,10914033190769806364,16630617399281928412,11039835824235641155,9095638852585040956,1578818523601781739,11206186826483534960,6162510216855595745,7821449928956837366,4842935390350397605,11103664703822661044,4324366766536189532,152234569490444315,18029521929731024550,8994297046114137893,13066113338520646769,2335749731553073842,9443072811065509841,14552557279593099280,9976716905429632952,3448467999021424388,1923708676623262821,10750497830272984348,17017156223799082139,13303661393290549674,14020493571509284108,12652758703945661160,18218071987588115246,1719019424611861508,15665332818253944665,16106513861157780576,1210534899364640059,12490018874724752939,14947070572292613527,2014725910421980074,357846255728739891,4293515276553246717,16951041016664929808,3770894057239272163,15032125565447651311,18363000873541084003,2084768209169880181,5311408871087585214,15071619225636089546,15966621092904767215,11425855782970550925,11569911608475259705,5899586966824594414,6212015977633201834,2866735152639078015,2175858419970455218],"proof":[[12338592312929082084,18236407173987083099,14166069837360250855,6789746590249886969],[6240411110968515620,15100138130856034498,907570308846943586,8725908944315712760],[16230342619235256884,26620020558326059,8095414036051993143,957371991617023338],[16622283513601664692,8738173006781992701,9758789684623547791,9357565262627620310],[16341581003476985653,9666427547900163449,18009352798732603264,5212730820302754413],[16256232980491054414,2660344046326204780,561639204120154082,9384363765950502833],[13733099855611131689,13666696547475614098,5023048200241529273,14880248134966374360],[9299318138479085606,12266656024480650893,7889179169577797565,9407720846711975693],[9577150886757731025,11321564383941497888,14769300465359622934,6473175308706673217],[12269519963109008377,12928567914997251251,4894104614508578691,12939222869323355621],[4254530681953652599,14260730258858953438,3991431175077424759,14597459045329510709],[7499352686288023623,17004453447018618704,14978796641339928757,13845083938660066625],[10836237883108837931,16410191064433558764,10550410945322270108,5678950086586461912],[3283636597972222288,7288474524168050271,16024548925130376568,3352233630372491665],[3491042110256019772,1161971018629106266,8281119082522022064,4862276033296485552],[2945863120708241171,8159151197294358715,11089913621284039627,16546757420143232732],[1860896835063429843,1652403080417522212,2261129679748469386,13254769866375557538]]},"stage_2_query":{"leaf_elements":[2267800607167934958,8891221023995172858,17633761909830724358,14794425376476426217,63979172807164195,7131153663147265305,2028010642682824981,10688797036774714514,11340210619853932884,16510423480009489117,13110032090201079315,6662791682143914571,3320557694458299285,4428606931531116166,12017670083355642062,13131277513570409048,4039671647034702120,5492350127079102286,15117818027119048939,15388124970184118398,14793638681723638679,2271942054695780944,13880993021801864232,7194276088087268514,4941717821931740711,11094005007032666566,984795098527649218,4038102290544902420,14860497640697622408,9196443496609694642,3194790195881011759,1611292111654882420,9376774849232655350,8026597940086880425,11287036445596512500,13672938098678193406,9123667640135162356,11120448686333536495,694369537394524476,13304853921614954047,12185455772540499231,8803232060524214232,10842002387794089073,14908508010390086751,12107331617562626819,12409632940823364026],"proof":[[4899239489711838668,5480521066104860489,13126015072342188099,8925654305726375296],[5046618188102336613,13218809244049291908,17508325253517992852,5836109031278628467],[17777995628906737849,9350529169662385885,17600549978512575320,9004113099279482396],[10428640614545772598,3669850956544226725,5275051991842039231,8737972349707160286],[13149286535786516188,14383532225548504824,1702117025113646302,13838101505955770422],[13781997794466925416,628075231548290160,14522903427276472436,18337766479623457143],[6276473680273876342,6113769593096147826,444501557738312924,15889387260371616959],[12973472685233393756,17360784640976875404,18172422228984164481,12367227174403317914],[16460713505299445494,9608586369538052069,206351842636511840,14126809932425732244],[15101490334542513396,16840222220869599091,579306773651645721,17571536323504014743],[226665066103146340,18396128700124356893,15456323967322047613,13864896222838841279],[17837445506431240105,12255351894409096090,2719453863898210461,5055681090912677810],[16941197672819495788,4721265264652584660,10863697158704235885,12311401325677877088],[14550953470705599752,2112269725922430213,16643291326338337817,5260652324281093432],[15258258073458333284,10672206657780689266,17415983125950091192,8063373172354891960],[15306544927634013289,2794978091120379871,3796300467670037656,12741519776787740542],[1323240375839521967,18311725375579224908,3996149533677948373,10325837003394018898]]},"quotient_query":{"leaf_elements":[17876492221511753598,7352361459915159723,13478429034379340161,7104900331457851226,18444902700037764269,16521198960547262181,6253722761757958966,11959200721148806392,12893885304573769661,10507876182743863555,16541097721536553117,1802816763168078721,5727970133837913092,5410586873117469757,14056680295646637527,6881458202282611941],"proof":[[3954180139990374346,7123262524907236488,12820645879840655803,1578243064039942003],[4231942461370576722,17311664688515494269,17259293951157775568,10223878605548552003],[14875939783705742164,14169807592495608259,73984227469764414,3718239274606723884],[11341675744450381148,17979464416960850373,379141074533355095,14036995974015094023],[15903608655657732026,8162415937342737044,5153381413531721233,6413871521720046446],[5248306743924740109,17284258347361535333,3482379783364593365,12924365221173147478],[16051693907200136526,11628183755699090284,11994601251726009781,9661439170388476735],[17216803134474967086,7731290686928670270,13309643687506182626,1853053519577613399],[17269332560637326821,8277068495686499053,12743287803048263303,2687333892991742296],[950165964719008875,8194051581386302020,3755870409343114321,14638919671099495918],[10973587589818800525,15336674133737869952,1836306483946793649,14778989488594590615],[3684833465994888964,8223477171200680778,17871176733955364742,6375169217543786805],[17243374584032864898,15037430164978664525,14103465616053177700,1991224089639920828],[9133562286421519063,11001832078613525512,6439656094287682047,12286418393063777611],[13790484360128987984,10436487963915467307,8412047174155606715,4339586144243861652],[7934424558305572021,10873720953167864,5363924606283357776,7247229629047154687],[16275865454186967714,8029517013225501122,10889177156594922072,17199111512595852426]]},"setup_query":{"leaf_elements":[1521209087580579809,11084828352185763274,4553241339193383535,14797923302937620773,11917336936405177331,14005102106925817812,14940292979163674379,18061746618581360853,8987064801565017204,2477902455581161057,8611614665045776813,8231820368651201582,1916735908525509658,5610139733877366618,17812134350952238303,16811609085298832864,5779883449848592523,16906112577046659348,17871236748452932637,8815537115441592018,7170475030454090244,8538065481961848442,5460265664382596132,11024696736346270043,140041693568638042,9044293969852120066,17753207837202124890,12575562887743374083,1250424203327130126,7419275807054117885,5857482907138044316,14435986796192663592,10350087018945364103,3928436997306378513,83487797518626060,14062015802235773347,11050351590454631831,9223963889862588112,1984714800021651831,18389725137444949781,11755253684628019091,12782960529165846185,11206498712118306499,9560336668851498728,9761391202798795321,9824290933242467572,8721123237675992246,11711672750044918152,1215193251424064101,2819683855104280731,13380545319398075777,16937860925656736722,1710886719881259230,6430697034558271306,12079140230108289891,4846393692449801295,6389677084433221674,14130870035418652623,16609778623664567008,17897940082166232304,7729049098232440621,10238375628486455450,14069745812403911476,4334594613541930571,2967993389973270452,3379303232194045766,4628730807703327420,15340532518871315020,16207078798025099729,9423240384733230420,6431976051040983444,1007190575873531622,9565655151968948089,11362493902780188891,9063808516283201253,10003848439085294385,1661902200221776914,8882757323985964612,18384211186609847302,9757284706846421763,6012799109211339859,3827731284852693885,15308741315787732599,14815490502967320208,435734169386785347,6226708862298265231,14539500983953755785,4334744767614090643,15723518533049143155,3608605164700907064,17849968828100077871,12801583390191709756,8406296439640884400,10427150973200913341,1202159634629041605,8451216187280902927,684951310553812018,10846730200103468127,16883460882981948968,6477152717447246443,14913544285307164867,7271841577109024876,10853363012769623454,17567679711269646802,6122378019861265584,13313351873324038664,5167608362174171083,9799644338057437262,5131402102142672183,4127413221483953296,13996220982007915221,12541341702837238007,2590956919198991751,71548567016238704,1976366114331612105,4681741741986874272,15881063878641314772,12619148735311981097,7729766971274571823,1494315050371330120,9196857250870800464,5521230860327554694,11709441377581747977,17497166423110666231,10682063722101006007,6403085659924821850,18221009244991503834,6003731335561528310,14591699942818418850,6912835651997461723,12162724655447607033,9578151654797669000,12713789214697519240,18281918878544704855,8160120206197856928,2805795202641942010,739987729484414667,16442314613474553441,7402299512610019798,11639738622021399780,17867278047357498179,3760069485616521045,16356501158844650302,5456096316660455020,3770427164909416966,9978490964328555391,904649741238014725,847131762289713809,14984239516787386048,118040670918332183,12974690841077024692,7018826902837770267,14295210741185191706,7107800077476363875,17678591586094337283,4975013933407762709],"proof":[[9209284567942284141,7734772017616701165,13907694380834602471,4685100441823257285],[9987683851943041995,10036189393169500473,17892329338599569561,5823317192964419806],[9903201278501628746,14535285457817652356,28228531153723231,12016164235497672072],[14701727265121405756,18430348753290728304,9813342144112724693,3486361218175751064],[10678553877889579639,2461985038143846411,13148425122712563579,17343289383414216690],[10987838784358567893,7316802466263220336,1248370442988549369,9587869934718881999],[3050620342826133101,7766775964342889272,543953739702731885,14309378254073454457],[15218315648146704066,7603277088550891521,8849202251967612813,8808919350566241010],[2265038016829384795,16726775859873433042,4336458781644949195,6734206310450991205],[3642326367658442314,17972781567176668485,4820364502156784071,16315026449438647759],[13915027657740533210,5649339403759936510,14510035267831628465,818850601367201192],[3170286147645144951,12883635783080513232,10464800272365985516,14780516910904583155],[3638511898085420839,3179248175659244316,6966358445046006558,16996260168411663505],[14443555148601692528,9640016152684889053,3368972803826341179,12755398397911894359],[8043777399769696325,17183778562638322950,10955985433162856519,7059132494937717124],[5577749902235936610,2508071626695287737,7946159595134479104,11003049146131669942],[5614327065933285653,3328995280875371920,12239808749654718222,7079628069834605315]]},"fri_queries":[{"leaf_elements":[15235628202078388733,3550814894522306255,3294284137290888693,11269761697139385552,15223710538102796020,14619069492222367974,14350958114013221281,3657789528482042394,16955875701121455862,14906158337760134040,1789434177662685252,7103590313089212109,6262489933833180451,4790823722168905197,11565515977138409948,3630604797294085436],"proof":[[12161805446134933012,3634230046283868025,11169057484966271558,10322362808783924365],[11460518932886841191,8917172780942820759,1791188953873391723,1440294816879339387],[6996195153695691555,11303953632879881644,14102103826907844478,6324974719813240400],[6130681047618776221,15307127268911942334,17056419798852092032,16763567659199282712],[2071279282278515267,31681278477928677,17964197173216191377,17087199427107286134],[11796555173677619242,822806531129331649,172792434062446605,13920996975191023180],[15466720427487984649,11409237269088807092,4748128863694667983,5433973766036395040],[9663694873514661023,15429609718895998423,3540482866418396366,13383200253526980746],[4048934840292311842,9313957438382828291,9374785399950528218,13858174559870028504],[9541764299127653241,13493621633396557893,14884626649963930185,3309875209469843341],[2387324608500645006,4140793481154030295,595790944404911408,12403919511392011557],[13436962952931688363,313578304777135673,12943383523096528212,7788496274352859422],[11286457568846676776,5013727499813089893,11504919871425148630,15623363243145632533],[17617671789936036600,4392943681491727174,15270466481397815535,18102028030276323478]]},{"leaf_elements":[7315180320252689892,14628784686124728742,16099490222644491539,201595587083949540,17299878329601753313,8122704075010470985,6231969687083886888,11687410165317946077,10203919568016028746,6365525380302694405,9496814169259547867,132288566514184584,1969197050402183481,1019132637184887606,14652622237378801932,5667049072361536444],"proof":[[3749598375387821244,8474649223997121905,9015029858891449310,3683963557038896640],[3116502903599378814,8318542187408289077,4140434944929707749,8671931685115255557],[10076686732861425089,5937717613998435433,7770717964537045044,4634271851439203841],[14541476495664667182,335936619702658520,56918890777439245,6759404351362720095],[12042638647872813214,16335729600343424694,3351171139691801623,10947939828716727777],[12987078213193349906,12881501575327527996,13962227031895311201,9585139364765906785],[4878924620659130842,899552634420909709,8508914978536999170,15704410465215346659],[11871385939122677794,13367586360632717409,7864762835787563830,15553462167501423839],[15526104121499366199,2646838561013226410,2040208358482844691,17739700510970552755],[2344129626308277772,13326602000778477657,14561961681591881594,1659854109029037560],[5204416224914363540,7631047996102225273,12862164145984685228,13063266225627597449]]},{"leaf_elements":[14159976386976445649,6758015488708232332,6714019928629188679,9073449616489872834,11633703535980193042,2745644330664206131,3744008839124660234,8089061244499904415,4735395408247420840,10875040271678055834,14123619622900823170,13819659009077305757,7908540076949679288,17938101464698001019,4630035991717660085,13196247698269486910],"proof":[[13823812379657818094,5317352810608634684,8529294596459790597,487383492964328654],[17590179219958320387,2910568237962741580,17781762729758351091,15180076401483791520],[16326585908562888439,10451708807082004744,14370368462882808379,13227593414358279216],[8962437811712365808,15135915785702352978,9421406246708114780,5248145797083067172],[7026166053187864812,5378731199789079497,4657954624022317014,4430342519422396195],[5159804935821369984,13994200553260237109,9445835667234478224,14066561529742879119],[11576929916273111458,7010067740305565866,13591390134299720398,13448355386671437584],[1770868264315023480,7812579801998129002,524698746031729832,10714744940176785641]]},{"leaf_elements":[1981873168355696839,10071469924429387742,3243358467018858758,9423856983682387373,12136610342874607839,18320842015638575116,9552894453304109524,12782153175948824335,1200921814067761851,12547995606491641057,13726229927039070014,620550873979188277,9133324122770055244,2026500123778881675,18389756386844305263,4018533361310258238],"proof":[[755263300796871198,8869469359583206924,17868635431207288441,16213111950745689054],[10564411463071116620,12115268395853191647,5951460800004337870,15539274182663975177],[4265438436947304753,14342861525172112993,17967674316163775908,6834470526382201714],[11305800191859317577,3493003457645852143,14744895160582527818,294976057195894225],[2352908338701448330,7592253344295024086,1427121771405932881,4783686535469269471]]},{"leaf_elements":[16070831778730322167,17146922037619272738,4121320938849791840,5818432618082194181,1370020225682757378,5144995496371304514,14040903937101183461,1775940530187431237,5178406466832460837,6764289863066862362,16700697179272300234,1701592600056653324,7605391755963925717,9462490642760313982,18040264532904337779,7581728628523268145],"proof":[[4187436726221841529,1184190036992878583,7683626526765293269,6799112461399047134],[5266687653515500013,4022039819281218887,498832073896150918,3983130288007996505]]},{"leaf_elements":[11907939937929050222,12199976274714464765,3239066403731203959,17951336118807113373,16307121117972480027,16234899209723555345,8364706858358154655,7274458572308793086],"proof":[]}]},{"witness_query":{"leaf_elements":[9010069649085754941,5733666713866216043,8483914391472998681,3387439287976892453,12451202944000799580,3802983519773659834,14636336672468201669,11632380075329513184,7888570261167169108,5822395280754058400,4044363865615696915,1991190026154264796,5685174301968936141,4519171379409859717,11320151622924946565,5624225328229662766,1050633128924069112,11707836385845793647,17263953712125722654,10250611946479902025,2526631749233720272,11345081157943089386,9075709489396867551,8149006473063025070,13940459863441871575,15097182269636073551,7961792366036791679,9335900691389676498,1705122063231882741,165154687260014778,3350123438165036213,7036560420058962063,17177748848922062099,18179362450692475599,5063012568464263829,17688271283908304510,6851825646798822642,10929052007535500851,106484831985210571,14285647017370304546,1113680894062907348,14160802233341953212,745854207992088175,9660437674384275315,16692352468578534962,11259295659782360823,8937403656119102433,1393587215166684615,15156606494026669597,3993626643211999012,17428729562409110326,495804105739192108,5089162432035348401,8678814431870250630,7469656245646123284,3020257674349743794,13433170051698461119,12660316583327083522,1017724398132153051,2739412426292362213,2019598849150455025,13872410619361456510,14336610374273553607,12935733393225844356,15983737898200541531,11419277040463499006,7904642407190979911,17975643940235868712,3570192130231818705,4515669901403444411,10654884226347525415,5992420493442478816,12706455115260639332,10586476276350372156,6143065565961800349,14760386706566491832,11471581608345057655,14753176973452302748,1801684202645889771,9458789990302051955,8881737124686066164,15161984616980119539,6285181026333285557,14876724050674292777,2614079869330107424,13340242023459746685,11384108278245113980,14057685236838984625,3316318778020213246,2537849510702174445,11401857597062627878,16601418389989983516,883634629644193037,7902892214985463351,9880192232030625785,15148944747550237820,17131804875003609760,5162108004287913472,13000831760210920627,9563176862657673678,5254020518491181179,2974714032348474604,3377196602677848754,14061963424087827081,5250036488924861284,7523333532319528453,3214583391173298109,9356563013876695763,10738494668668035418,2977741677506265615,4170783172154599661,16340378673695516174,45191210622580396,5793144371719685549,16030566052205714750,3410970068826866489,4261605271217322068,9729105092915491486,12079053046036399983,2324803044801240103,8070182591522093307,16386390767839183839,5636641250586295879,1708406231463445221,7093351294410602631,14571204256419408226,13493763689757325009,7549951256001986934,14501811352855338144,1514532203296901371,13235946634832400084,14468301454549472764,2377974365715330938,3423175590168922309,18418601347965177841,139881777432762213,614861241085838436,15991041233331755471,17858698735518003900,973559026460625223,12503172804851701507,1997348061067370063,12329235030262650166,1730003414545367638],"proof":[[11843265586792029682,12030251457644026483,9373726057968283243,1435754400775853975],[9624095373519600015,5817706042664516872,10740334124184885727,10094245476364104514],[2413310367223610188,1164234241753928361,16223829690789962657,14171286624660072810],[5877970749761866882,11261809007944025391,18315093382045724656,8387085253320958774],[13177016219604447231,16557101393195109150,9942822820488378282,6897016821935409678],[11989919510436653346,1175295082919147659,1545068170556646899,14242825853012152296],[4274527734033237217,16544154819471771212,9091673571650354817,2918563671659371024],[12953904104620987764,8980120286096154879,12040395258703969717,4915834769232168046],[1534643765180051214,2047953454480689125,4974614570624768327,10836811146860130752],[5159982410178905848,8149320952644159952,1078418948221040884,4258405145976225083],[7331760503373712013,12757737044061437234,5919583232791099138,15824774945936651643],[4698302230471719095,16783684979767942106,16313810545418666116,1283976252300669518],[7912825832377005962,4961049671745134576,15585586047688520750,3933221773833776863],[1137089374085783694,6737681319230843924,810532076227271327,10252904549093219456],[14664973368043267692,6302240280479285078,18190229405361045139,10093720497376073960],[15751304304590378692,3540380807527523619,18241216454753406294,13195695456519316584],[7469098604000971809,18097563392066223627,11227341610261445307,6019606818644862245]]},"stage_2_query":{"leaf_elements":[9354740462424488780,14939215448618793052,299053341207513055,235117560450049732,9199408740406812176,5438539157931561453,4619107093926401686,13674734864102693438,13249588221495321415,2574461320987297402,13647984693904050405,11336074910173405479,8832052953050973884,7219978875551704868,14646426935067369590,10375907229978128040,4807466595817168248,5111781941852885561,13417267867211947280,438225766009699809,7522310715287604148,3006810180162852271,13802559747943981311,3683238164208891952,16075557574131026092,6106745455205590597,1019703751869983559,9438151439189197565,14371798706914153524,18300349672555164980,3218762663478579578,18272311172943958505,11703246658622755089,13404081488861827784,6529737521466411180,8901770347255887433,8652850628886455488,16314729962231113948,5305152765219827643,12642327683609644636,15226675507595865895,1679630370908374759,3118811428775992971,17791653421563968709,7827105662776203307,12656168581427344784],"proof":[[2471425885399453975,12641875107924980674,9617798374582130212,5886673684211330595],[3356653265608494808,16378761570140055982,15785758461692406824,3872751947704451497],[11816965493749429027,13057843348082400684,17880571150504380089,16399127114686822265],[16847083820238713391,12326433059910146073,11894677881360606260,14205545871071049119],[10826429619370102506,17197440561044279535,17297926332264556820,4069225348745335103],[13160508027558033170,15741007139524976328,133968205034857492,2578757959836654203],[2937625029649553947,913559025598741268,9865558740391727283,1044660101673599983],[15283688281546084530,15264890811934644191,6349338906922040681,5620233079172676249],[7822029787399584620,8062544352898977969,5720261720434787612,17713512582990534285],[6377558976298771142,14445105836483474028,2081980192191703604,9358795536087168007],[6279441612166106448,5071876685026113067,3718141699637811436,9588833789704825543],[8889246345684052081,12699543213626937078,18333129963514541821,4989461721945455707],[8627607015419034754,12335950004888637320,17537650834879832055,526006895763722483],[5836766556719968650,10139878487298000979,12027958358623086641,3151682264008158222],[14896100249541593412,10740588667362832004,810547956664126567,4065347682811655484],[6339192725081551224,10382534389118847236,18390739725709008981,17041814705167592999],[4069576357456985224,5364972339274971361,10552631821080538803,16628088351488721545]]},"quotient_query":{"leaf_elements":[8757457487410288288,775480845993433925,5680992966356008824,15232904268054991924,3463112040280648392,7902261437573327319,17631285687602157601,13090857933608821173,9969536523216942793,11143036827933504976,5370853908154488688,17324353739932253310,12554915703051428454,13096317287205219706,2625192337579716584,12219114122244360851],"proof":[[10364288695626480848,4066234147778282961,2875101587297769972,14316707575932967500],[3628838792162011031,14998407010686341096,15814462049748889054,3374526407230103720],[1004715831067324995,1535696951953982190,12817165912872237873,5299672722272592330],[2976392331872566831,9056639352620938607,16079676128735750173,4320906135814462386],[9440678713933671191,15779764784431504965,15958788868135230128,15081302377564706591],[2140753296708435579,14877369053008022131,12513478725178882567,6171049374640314140],[14175413557389139085,4441032191059702678,17293715436735292811,13832152979374976810],[12275274099422676925,18311901306435379141,13974228488395058079,3790635718022557308],[419873052482128138,7535927844688803687,12754308478596096242,6377449511094354059],[17734907738027442957,3986762258234487708,13910821834552355504,3317203692945190779],[5681761711541522476,9860087152081679614,9110306923570458242,2644775505749697637],[16081587429641097162,4883090848522473835,7262351739710649217,16668621357997880790],[5655885031427317387,12858290671228616591,2897016662166208149,6502653675724435737],[6961931089698773361,14614968526447074052,7919505213590673806,8921426035938054522],[6546789652415849824,2171576846982443026,10479185749672692703,415479615494547079],[8050082971923925554,8006058097169400734,16917719109238936495,15231213998508485901],[16735507931988475280,8372437731710315497,11240048427889227812,13735935605106250657]]},"setup_query":{"leaf_elements":[1822607149380023695,18136945865216641329,9825156840635178290,13323496346770731581,15473229125834056180,15812773598374196049,1217715133082491670,13027084544033427917,15151095302134410645,13488725499313280766,10425885985383683519,9426858576255245119,13272852139356146668,7173523283111346209,3582167682128659100,6627565771659133860,10925257049513652858,5540991424997648695,6726593585353303083,2629048267126943267,397319691829429875,14829452077241320942,1832405656191553412,13116082102165474701,16554509439211752575,9961239249392076513,3122317875848281663,12252819002786807130,16071680913048804688,13714340362511041002,759811311622459475,12854534468674783955,8581151214560664287,13700454842489916798,7077983973361872417,11254753173819456727,552946156750213390,653825807442086373,7383092080805357878,6001553985492172179,3767541200822391059,1530154295011089144,3720887833766409675,5091233725195834869,10362539602925243902,3375467927797598426,15588082959542638667,18007000461750785102,3778068300966233172,15961722676206123008,2544235262691674233,4671786820229370734,10899507025868654294,11167858501701825822,12439360912051700299,14828686677406252941,11684923384965153163,7253954083835993692,8176300254279124081,10976880764859371848,927098068736769285,7494454109128279054,8858124384121919698,9428554106470075726,1542605781860935278,12054456138360428169,15005212228726145267,8057319927957793335,10436382456470065993,13478237129338130660,18358788292005604754,15003488903837383346,14907143784774044830,16688465359734833596,9872050534116330185,8467819467132430772,16030669979064027217,2896362714182971056,13398279998088349496,12042040798581345340,7223989090358472469,6544969340839337815,7190777010786315398,2998245841202985401,8767007858856755915,4042991801560862135,8009031437509430754,11980310636371247401,17202800464326471299,15946864996564975019,10380482202811460266,10800019087562874546,7852163181433767898,609166136237925835,5200012491752841406,11937482449711240800,2133317360801614539,16824210325138174525,12739679526557767431,1210749473991729159,10815193931180359960,10552088985144892935,17731959454466890140,7375714495284728667,3403497386015119811,17762770219496999770,3889867360587467010,4760687711781702528,6988544355069586010,17664756044020848312,16514868877326530304,7604681265009151644,9038082147987669304,17345112430342105021,909051265620309534,6762098720540499854,10322275037838581577,9222597101899321321,13085065668778512612,14976722602404945381,2201154115666241169,16970428866278110053,3525742608594572866,2554939052172889514,7403477061980597483,4617319170959320464,2811826256185677238,5872491476533233531,13433154933918682278,2805132847469453807,1053629839477797683,8716740794502362835,1925526233149393600,10798609530882878879,7140997588893536992,10419767949613231403,7214508474281157425,2091295464936532045,1572766426504249299,9596415270854619217,16725183961048779805,138067934741143065,10253632561731604410,10025282984074660158,13201567680048284878,5924277167789335710,16318885075744085641,16266386575356868517,183736123771725475,8341485726799736667,17798772658463376637,7330215279704362264,16598408818878583510,8349347945215680277,13523073095000413461,12174198868581431327],"proof":[[8874300372261218408,2944007571034220165,6225334664262740365,3973639127251934146],[7039430783391713334,5493408053007586185,18329851575024001990,2722992384412844952],[4230932531033419591,2054395629289235504,1536105736652709941,2557547779046144357],[15056740268826310834,13739690389429891709,16171957455622505444,76164707152986158],[12630035943659556345,2228641076813395812,8440711531395799131,10365948516343661697],[2697375535535357855,2744108585885553565,13342482400809675086,15211161407960858488],[17976853448078100897,2379964816648076653,14767728346389921943,14016913547100065560],[4276295899007080811,3096641566585125395,17630248080921771858,6544232585362512737],[14799665863560010105,8608154028969498544,15423043926455795126,15178188549649394685],[14548070229489657312,15678909058163317295,13458929263972817232,11791191544073804676],[8417453876657271136,8790747554218502899,8180490737124517357,14058431415797540355],[10187214598379961656,9936420421015708923,13827315943737647253,9856312908710010077],[7629695198834215290,13051437750495039481,17800068255193346118,7551001316253763413],[2273336062518222252,9933743136608455163,10423872819203071797,12816625883535522528],[12759047054646879916,13404714067553027786,12333811605158117741,17635642104697326851],[4471224076001378926,16919955007946926881,11222855981915690559,9841493882299524028],[8550157948290753848,14777161903517275534,5173375215622667146,2888172977515519708]]},"fri_queries":[{"leaf_elements":[17552128848321407028,2686888482383221672,4328882096731005146,13012513425743016992,9498440875469715081,14077007160197036169,12552179029459852938,8577478583552309694,14902515532913974996,18403841989983343327,8229027775355562938,7112772706436590453,11805610176311348260,4505316893243113270,13583282199323143774,1220708384657570522],"proof":[[290260086253908905,4750902246097589153,4982741215505923404,10063265907376909693],[4431713319185330027,10998356812590256170,17754970787463965455,8208444736558383214],[3702826469252774421,9386442463207383104,1572126731267275645,3315705361353803797],[2257751747456136182,16653705124430523954,5352215789478383257,6698547841970009218],[7776700466695579128,17651397159688623232,5942718010339265208,9698490965564166528],[9244900908870488282,1313036497052920010,2850159487821800579,13670312472670516317],[12136934320719814912,1601890875184730553,7329617373049440501,11464264324584539235],[2206692183830725261,1508638171370629808,10768574238625226471,17622154240565681260],[18109082537249638115,6309766007196581228,10296184770340777574,10686948581688909771],[16615077412376936097,5480496182624743645,5666077662090172056,12234171799112633172],[12371328815030114262,16627278201741900868,12723239769339426235,17922905995442887848],[7124350690673156726,7604555951491579863,14478931012297683564,17341827219769589443],[10918749277507258907,15937554421065481845,9961006941026448436,11221466693294064974],[16045127423565279178,15906367393634530664,11775646977459072100,2875908643413602654]]},{"leaf_elements":[14867295056910110767,10017020479481709646,2947945756274206671,12620747546981052594,11477227760262436512,15825800096484445331,18446052729758866386,11293687481825438301,5432022065972106463,2330785298833716460,3057580823837530250,4985590192496565964,9776699671088015926,3379880142228055557,13468281384300159842,9155012616461903441],"proof":[[1769347632854996924,13493604695013167812,4816175002391696212,18366973140612210749],[8473654399614660047,691931065723673400,3160013996729844090,1385066504465235377],[331766365666763820,15583769430868975247,10270836158135713783,2325098662938622844],[18250376690763451962,3577458192470729037,10374883189164671106,10565710318386456940],[447478513596808107,10280362772124709993,3057420500001664004,13346735781031167565],[14170587763490030509,1995404131558541520,381757933873728166,14345773627937773835],[2571102026902322639,7201802792277709787,2016050472671574913,2400380199655278705],[14221534981168051979,12840643260319216198,2286487191953438388,11666611587496191544],[12257773556420523434,11930029915295624476,10608816307510260650,14476529811793321325],[18330321698974098681,12073493146449843580,2864180908336594691,8469172028578557498],[1355231242388292694,2363504736459679002,17928632709021131134,7081248891809449452]]},{"leaf_elements":[9079608053789295789,4213689221998192894,14779771666477412613,4105364783472742251,16057866148815168780,13866118660464663405,10877898788543578489,3529104146683854924,7337189519737889739,1508862463799573777,12565451422416220044,17571026462845699708,18088021202197211933,6079433309570319721,3970260505567870112,500272531809087770],"proof":[[16045047409640076553,6453988847879959859,1479242600300677998,13155463060844794113],[13386135850226421172,16824517532408641539,7426024813782487699,12066726585274756738],[4876437977165388100,8127673569187535632,7423402360702869671,6832218576798152850],[2727491458688074412,16748947529943899494,5077265948447811413,6605484575774192986],[7012361804814112867,12680092451325765097,7065187832314659019,17199444447821342466],[14907370466185883422,14680073902656054330,1584953365792223413,8168612595713362400],[12421488938905378470,18062404312917423353,15665723535158187769,16625498805882016561],[431402881678253979,18091544763766368937,14751318003736167124,16253948255518091428]]},{"leaf_elements":[6678940023239117613,2779761113298506702,11892811036346897143,13889421149552484779,1041499254806243581,8471998738174911431,17945967410806220152,6522534146182091780,15636924448148838483,5808392943145833101,9973242951309118469,12470188441409541543,3286410031962270601,12199799102744630026,9175758180099672618,5593868091530564957],"proof":[[10528968680013509317,13781840344844974161,8101080273624742452,6819757007923374781],[13378164124871731129,11646483083622243990,3264987825019592089,16753961549359499682],[11515808058377872797,5734428844475359259,1269855302693389815,3008625966617241974],[1870669179865382900,2596651411578378175,1834193077299643303,8120095647143482754],[17113838174225687235,7224995886151952082,4762201158946606763,12881944118389080413]]},{"leaf_elements":[18286348947164058465,11377092030570334368,1421803648746151023,16707603233984701343,4379013689828691433,8729476751978380975,7323316470318307920,4596420029769418429,9056421102513166258,13293194514334493965,14511881958811571381,9436290237315571450,14816197378386910985,15122615505320944093,10390551496344211922,8285349748796832763],"proof":[[12454276069602081935,9464837808133476698,12878105912982939478,14528712268168600680],[2792975807591822981,16413146020481345508,3907179070562068391,11008946275232062117]]},{"leaf_elements":[1182631706988909812,5518244554391670520,917746562024176830,17733293859730176239,6201899089295260902,7290692953056460497,5989223798508600986,8968599394470802659],"proof":[]}]},{"witness_query":{"leaf_elements":[14434346903001216263,15219634185614064888,2140286109021211629,1074189518568471090,9703489627331680481,12144364921926843822,1750944924691243268,2361422072397323839,7318953352556843491,4264123373867960395,11232050163221645576,14293427367248755537,7736956231456085111,18150118321224706606,13604880880533376929,15777862334358963200,5672306123313963034,4136426414772796752,12860823291295340833,2097267923041697051,4694895869455838463,8515042082452229761,17458611882114604671,12410920597717976568,2418527054495153348,16375417225905440134,13812411482714570456,2203677749882949969,7399831632377562636,1641874565654783538,15624035271025159828,16803119261700331042,10892542874555486946,14481203281970296210,9447026214126620031,4083560137220974463,619166059042035105,8880410094838898638,6494066330839958690,14824670092695090979,3058908451006929764,6272045553110246926,10756388834307845654,14343070317254611367,1021946874666941657,618305150903454134,12773423543731443756,13509077386257027697,10819226948855040266,421467448044114097,15415280924796474502,9873406950043655705,5441171914443235893,9219196958936975104,15189964890827084013,7386328110814878417,1166145421518689841,10443125646950854010,8044415157009101546,8002187235977097857,14391298149788240529,8027416980400274275,8036676545916318356,3517056788338391639,7430561616130954788,7514427460419660705,9072821244748755608,15966506219150346492,8251997911108547056,8965747864732321427,3232299040504146584,443146391515463404,13959488929796562425,10112189563090896099,12146293860087384859,4818243320223761282,8195132592708329381,13362518986769141147,2657414868156280191,5867974360559129058,4896454641193721460,16901412130612062597,7318604813214643810,8311885705067116428,4941574711503771427,15845435774261777922,9669481813512190336,11433384888755428334,39586278271306488,16209938401200569878,5756049118640466312,18356778086308446207,8141466663428109564,12288640498120687170,2004710437219299730,10020399165904173780,9549408900325359451,10149543593032648598,3480809143960122532,1173976158488009675,8409286225702899729,15136470420619105757,14749209485227188124,17386526510558993264,4926817924317300337,1803364964413509200,5818701732825781802,18076665879266039248,14953366660236480737,15223061367969058285,10463162062782419568,18243154618492370244,13127507505029272466,13077703871743183384,8755924396407438851,1681465152743672423,9836115034673040044,17715905475741741274,10451846249654807046,15223171890185916751,5395248247127211591,12216155056750539285,6657794874253252174,15934863172705341928,381507279708759377,12131120676355097619,12250101152926701865,14528854521868328709,4896361662845202345,17575134244287626595,17229184984878684025,14417668266962146441,682915917667600216,15759994985353228685,15610589251778253245,16372475760913307906,11473072159240313389,7042184497530546905,10729158695857990257,17966391199706962198,8784346189854951414,15758873568840860167,16877672925488320714,10767002124412303997],"proof":[[2611582864467539780,14105282470731867227,11893623040149559330,69083207846880572],[16348319968005004968,2148141350759701495,4038206330972911751,12372443114182502756],[17213490642211817512,2409320588725807208,16963985483353644055,3946711644303859421],[3715994893032977566,5536313238932027099,8690080663108776084,15685450106509324219],[14132209083319078479,9274686828135450350,15704126909272571362,16727067334909751003],[15852004224633988997,17943447727271468293,12717026408252436680,8445986149224342094],[5100833231042816230,5949972119794513561,18311357425826294367,10102830833498203070],[10310472061416639347,6026270955841713873,15196648947142932539,9528219757546786158],[16451675253435897500,6038786770447482403,5658257771345001635,11084984162133091814],[981647161479964731,9400347978840398022,16889817562889725651,11730020919706096875],[9439099048368117311,4777108622164561910,4187072359151749591,3468255696583583237],[11047758640483624475,16984200383519418058,16268020894038710535,3302247963068923720],[12817576498564940692,1866695360454547471,14769828063138173325,9864571079789513014],[365853687983279010,12982723795007105120,4158164774758393705,6283238807100895841],[5224331917109680441,6598835313364140741,5627357161473253854,10409932730424475483],[1485233880896638379,12071662103515543055,2139412878003956338,12505221719775911968],[1360073737404009268,6704211837639141409,13662088324981550234,3380234095738789957]]},"stage_2_query":{"leaf_elements":[8289231840131250909,6533190974746141972,6479864742162654858,686154299557676687,15924308314139099152,18003170913661690505,15806453469887580413,6154334475564374565,13631929894826834366,9705576545941561676,4083741926489518447,17731378804921977092,10778670690050694144,11254045296840951259,7014134516947627211,16394976791031120444,5302712974154491615,1897926954545953539,12605220653009745403,2081464674032737788,5744408164889178136,2349321802012215462,17318515222031802450,3434911521761012599,8728249064009669221,9480836779694638521,9609479575769361870,10893018625721744459,9398919243908023903,10910926310004993452,987706391453415874,1907301827969419396,43821939402078281,13114200912003932112,713591533066492524,12887602583566801249,8113766336805685840,1158339975974485087,5866955677630160903,12243020882072224942,8396525178362841842,14325949222547990264,1705570928320826744,246044140351518851,13595570378092447522,4833093496066966620],"proof":[[8502685896376495207,2340295014022351985,3520972569697974579,16858530858930142365],[1463778836515214886,16774252475617167934,9119672303026701857,16283892582666180386],[9782642969789339284,12872212003479967169,7665838062723560404,12244585226792698654],[2018362494699368301,6880852050007934668,16403906522197867277,15194619667796250533],[12569671257680300010,10976797478450373239,10224244242819557208,5731545763257313331],[3507632816127945704,18400326481504017232,13175733923204448153,15728832346228149416],[409831165810393081,14594229220217749956,6207890715894845205,13476044318657872181],[1873014360979551906,16031779478751540327,1518654477572133046,13182999076006307136],[5329014981329784228,15782930461076684653,17370394901141342296,15890540306158316012],[29122371957734193,10490772261776745501,7856120516891672372,8254096232671074793],[18127120958578250100,10389267088542636373,18277792132677950196,17048552237629931390],[8508171158704162796,5774342675597165773,17927971774027923626,5221775259752833030],[15011692302861657930,15080247585004111797,2562611607130292584,15388758212090818179],[17684428011770412940,13926910399479652257,9921951111939917461,15607398847386075208],[15305483213261681942,3870622862172377250,12772033365770669216,7358212229418854563],[8319008327255715913,16607857083414074991,17654496975262618756,15647971105491672436],[9361241096660372388,7871199822756612728,13057621005758402560,12934406087966475422]]},"quotient_query":{"leaf_elements":[12797268605174356675,8185704347436358048,380628027207638157,13384008960388803378,5388202839504132833,7508382255204888307,10833285595437600551,5794801014367334162,8258400886528111139,5657406138317649105,7387582854190740888,1508437124349744135,6665675556862780259,10651518099906115325,8594521693811800887,12539353151210428780],"proof":[[8399057607246760036,14981192154173241343,1065570185993742480,13805397066717186714],[16707006265005368572,6482551694305305264,13215634561056797810,1951891611611017197],[5384803055384267676,14856783066722082435,7302958522799114269,5950778990851157170],[13093186269344503890,711594755203738697,6606422326082758865,243033811563709423],[12705126920692078974,3724237739826700621,6527031301002497266,3330054403896265416],[5347606976014999819,14451836628623980217,16284312704261370953,6435508084764833139],[11463452318130764662,207583948910874442,17033368040398489607,14059402173324368386],[10511724847329181902,11008794503571320041,3779347878556223885,11597516354663510052],[10652301247201658145,1942393642908674302,14760916437836396465,4049388858295562741],[14805201729377506633,18083855039046498110,11069782983934550098,13979138018626855982],[8882312873457481637,2953829140884807969,14035762614425823219,9990264639552317990],[778193218629707685,5282534011743753118,10297551237645519250,20573563652249323],[6828958930081040986,14840791760062723710,456607985866232076,6934378731152011589],[11907433163258754287,4102402208178005313,11373680436316053231,1160586008651705573],[13434498397880401649,1377437689243008671,6414084363350325787,8876393564240908015],[16270142854963809435,17117357370502291560,4036575513188496805,7297495482732776731],[15725155024730071472,2846784656528433399,1476956847549245851,3176915357345878490]]},"setup_query":{"leaf_elements":[6751830539053191351,15216398135355428537,14179631852977120120,10459593760203524964,3774659101338685082,13937377831291784715,8633942856614652901,11680639551554730479,6859133065725607758,17011033113014092122,11301758744044121672,6865407503670142430,14778322126411902613,17220312047474594869,13022266086295549349,911846303834172754,10816870555613184148,10857958657067617391,16072893052466805273,16736166884476777645,17288160641413263184,783491924603709975,2058936248492307424,12474118003831678491,10366614971865292976,3469852785489949584,246453449487479384,6232958955256330022,10713677153342096745,1249956178700926960,13411812240779268554,11665732047468770824,2182237179064462078,17453508128809611614,15241483089693873920,18225835674943220616,10639107054318582465,4018885127359045524,14323149630420794886,18404292455697575537,6654154990153095948,2839971605919594962,3207133870455166487,9174718666956364510,1434647784115215635,5755522220976940684,5323708458985224873,13861431629787312721,10432913509562524876,14008584497158359181,5023216234638648476,808596443593968595,17198323340798026629,9623486908308860384,13691784083746227974,15748410337034040810,7195393104130305209,13590619924171481322,7473769467124878137,4265303361453341196,9304364544015107861,875008176544985605,12682590122317744097,3776706880288762222,4902004453326334836,9289300149658569339,5996388885629984748,15234814269969242711,6561512353772897060,698958613327509824,6578651220784106069,10280217531179903872,9710554554540984469,7960987123304285747,2975720717475016760,4589678772069588674,12716049379913115500,5870797649788372066,14011065238446713938,10365598628758498657,2864582031824706880,29594135137718874,18278282149382953213,2469419711802440111,15713091278609083368,17556995261505148213,5392440727420865992,6193544242115110985,4528585084962059435,5198548535632615666,5014986666252548157,8198404400940062179,15429625759162896675,14958685965313163068,3387510212603428352,8753312951954941822,16626149707961280071,17958144571389060914,17490658232954617379,14653372498464401418,8544028675585748708,3219104279296639661,11827070804776126770,8780480227545722732,14850040750967199697,7688953871321554476,2156579786601716860,18251694376446378120,183782561124525422,8925910346044196963,11360089492344351240,16865191899950434913,16601745855336901513,8509750441429949155,3280674696138859374,6492300915771210094,4607654809317555381,11185545303705087064,10280273046668288575,14992701170920617710,1849345138592259854,12926212269774919185,1500476278630787189,13045243167563646567,16057324525948906770,8518490166139428025,3293451218349686789,8377749959541217781,16180521055933594241,16326175453417601676,410619798590600752,18008166100145496249,1825425665172781538,6530005290602270482,2621683255390541132,12568968655947767674,5085593557370868745,1628122839447188955,6204760261653328153,16763155384248067108,2494437278798922900,17003538798582598288,8325160299698730921,14013289957910803901,15336120091421463153,1936685517811999996,1479254736346420644,7131843600975686276,1654177587002234504,4321565551589593349,8845065005544035171,4163001926280321700,9258318410026761163,9075217132479289482,10140488717543470617,15553233059239350567],"proof":[[3474088060804902806,14858696466913198312,13966877419973857951,9442355658715303677],[4136758302650079213,10092992268250674796,9595024073624404079,15282022072850537086],[1899863012573245772,2650064793176870426,5780567399566249449,8094211404998109541],[3613572500852830275,10966183892993329192,15774755006354615328,5685250573204105418],[14543093978191438476,14642635743165865581,1081734282880546111,3885271080792443110],[8715891087375962199,14873452569424612764,17638901284864236206,1187413444308705555],[13075157465978797649,4488047031353425868,1137423384013308473,14414803034628709220],[14044763454512582894,8721409619427743264,9769133934288786835,17578869766570290453],[12952971318660740016,18430313467677255872,12729663361482184481,6418264895962775282],[99439957040181412,7994998393138806877,7719790061861963760,16473950265591291976],[12921997444891240321,15890972480789822820,12642091399206722227,953988482219592745],[11730137416814401624,423438915546666608,2099281906882024493,16583795909988272978],[2916993484026457950,6583976772020465971,16852688558880855548,12588061038153119212],[14590444149286529261,12613365926211339319,15071631742151426368,17200315270947518517],[13153488764905338662,17294234018794914879,383266437505029734,10715325043533038166],[15832722289687690706,5355226235880548863,4170637444115930380,14904023068600351306],[7584630324897337125,5855445357232526401,15406563887835073472,17749225028109240870]]},"fri_queries":[{"leaf_elements":[15698883646827094967,10928985723372661970,10358699854650139992,8563855085766685122,5759757845943841015,1577677713659498258,6650658078140865119,11850082463120478509,13916641153129126221,8392467956988247693,6082395176161893065,1057904048785957364,13587189851193014296,17048522457880475984,18191974941699520856,2111355949596867664],"proof":[[9496608042451940640,1572664412286151772,17678207601992453184,12389130684504411143],[38933523528137483,16650568611368912100,653640782464899405,4112303738208740403],[9840760769847451834,16409228538054309649,1302732433619487881,12156191119062099148],[10797275466646660237,9337476002614959757,577852721867944334,17193805410204842329],[881007847545524099,13314744771870379545,8511970335482064907,3920353858797410404],[13473012406319159844,3207127419258891504,2562551558268759368,1097821231067119537],[17142464164777845593,3699588097384339920,6539236548875358511,11246887342944167639],[3583804644945053652,8206354773074083632,10264600689991177722,11028875269099083403],[1568257114030640343,2562247597312589323,3053310881425505745,18339235712485345577],[3965991598093447603,10683840766763117205,11275259230154665039,5829906487355709148],[14634351391148075774,4173936561396501268,7974056935802094082,9214873540013714245],[3424565659697107575,2212386926341110099,2945411392726584410,1986064473197972921],[12022107492789539694,14827703569735874720,11010683985336556729,2708594108380546783],[885017883695360673,13435321449249769282,5466777689613489543,15313896769676842091]]},{"leaf_elements":[12380705872332739597,17791497800349454644,12682347862022433623,17013840165091389110,11222735427855391305,17212024144733104666,5240352281098215088,17800348232099790210,2701727573155228096,1910451526875946917,13568158694166814380,11032165087345362840,18154249778996217146,2858996154084864546,11962825847603270381,14624658895283276578],"proof":[[6847598066582080454,11581016084927730414,15776497171788286167,8613580583023579658],[416326310183945802,9889189634935863589,3212957282342252346,31334195165178605],[17969927874778944372,18379412795390580858,5691210647267126747,7519318058602680506],[4564710143730998389,2777184382925127898,17695536463678354412,472647763564904333],[4491892029871452575,13542237039087217788,638035651808517628,13378970198166970262],[14491890933850965910,12747221833578753115,4692852081650758708,4006423073482120889],[6291580503925751859,14219855627521945191,2598982771713925021,7794731877184715469],[17436251114921806417,16535798766211800611,4851878849710974566,4277226705572747051],[6403746061435475432,15913864629493149740,3308487274169460013,11203944096163982866],[13500830884699680927,15306338317233456995,3299836681659625374,18226561178672362281],[2991006853592388490,8934783177013465999,9854609272269142038,8184295943294888051]]},{"leaf_elements":[11983166891573296386,12171394055093569788,2962063648383424406,5547236480379729089,13215803455970139386,7274570291732707283,7072242219966900849,2644125595918562893,9868632601310838212,157946950818665415,14737731513675871438,8670438780222278938,16987004282164945397,11239857683904754480,17539330909532587939,7312669094162741242],"proof":[[9113627062273258206,16704730837798744008,12490870670911389411,13910517430563541942],[1524464295688982726,13612896226666751147,13686596747355762906,11730193189012600605],[5369008810544528330,16281222133587340993,15069774462124843259,820713554413579821],[16436273173799198432,14488596143786945820,1893337975122508643,16628209297467130580],[526920546931521716,8212976993424576662,4218974118067087499,3073881240728208286],[9653031288271274176,7368529689121526004,14430692323790644160,8836060061319362932],[1806088966856210746,14248697546475838012,8730757304671791597,1502249710639534215],[12483543229731015254,6228922028592210696,6804550060647530973,7609776898298193025]]},{"leaf_elements":[16220555948562470282,16294092828564379295,7454752263197886872,11760545156373845810,13682514345110781278,2182756736131513620,14986653900015969526,4618887156097244636,8981297501724218652,6588889935404339318,2519622556567680192,13352227269741458591,15444258869272420391,14222534219808279662,5683718844753269840,14359860386355514792],"proof":[[12144930190416831919,14988997305901146768,7208392182777998702,11618126824868607831],[12837418204452230580,5880114232396079693,17219826641796858692,7119944924535700114],[18262645052720567710,18348730857695951440,14721440193968122228,5552481305078184410],[120353459084075878,11977129796923774441,3691473483747185222,4915274756070214257],[7378436202281888958,11263343018560466750,12515193662408163156,17578933933619023765]]},{"leaf_elements":[9189383041842988590,6965146586893804418,4220618660081283782,9999429366986671194,4630406983623020347,13765611947963961084,6123428965095967777,15132008706310555292,12812442353949431520,500786186807618677,1689459190315911207,16785331210584185479,10900878928231131599,10840504036657509228,4695360181196839233,10671523540088974323],"proof":[[8007485682100854625,16814109845768904116,1453178838105146259,14110354663391078558],[1130374547257051060,8284282418257759999,7393623318517703239,16641200946473051398]]},{"leaf_elements":[10934508164646927795,12314719184668898168,7161347650890243018,5323539938734047040,427222851664169786,16835810319965862076,8726096516971579929,1018351776603887044],"proof":[]}]},{"witness_query":{"leaf_elements":[1480038345120795157,4630530906202207199,3512980560198237762,14221563389033110195,8405816781256078393,9916070646320094642,10648149384888656791,7849521282779764547,13448879430622394862,16833729104945137548,11829508089708469243,2758717364483327850,18403235351278799708,11864515437777987558,18127291596814695936,8367265287699424881,17174132290024460711,5024684428200838217,7185902941189102903,1616045177779275435,1949220878581478089,7279628024099988009,252927158355500940,3853383519760800212,7913616528995077588,17193838281952106692,8590004658847374725,15221715930818812693,7346495564814262261,3551241294658025972,7226447272295676790,5656873332452513823,15069159161436826210,17155364196813470163,13481605428013328864,13291228953012040132,5198017339950094423,12166880298058323814,13789681036459986428,11525010936124560057,11392676282979195113,15951253757909973577,18092927329613403119,4200923243282568003,2313440727901496262,4287201561704394200,13146640052759250836,16387074548910099994,7309770276374233325,9184274548114714848,3600066773388097324,7354161002514792119,7224436733765859961,4039733157531499675,3530088531055291708,14523453812232206865,4434697828922727213,5580014632934556069,8153354467428774367,3354576923191698200,1938540557795094844,1151330215374973181,7662172432700062431,12969571250586637317,15953897445892900926,16876276106968143194,14304359228167479410,6132137291337054408,17973958784105521828,7506003723265844310,10545474773627383547,12267154929010282703,12225038071508179161,100720593441142101,3880645503655032616,488783094604439404,10200890483610322424,3418762676676046434,644539814044028868,17182784945349288485,13286578419078330784,11801615900043104628,2462828986510170419,4422258900012306209,17142449070789132519,8173044149064620078,716469905984406055,15571132276122113934,5809132468181677118,12027036853452209358,12086937880342035675,3853667031077051336,13618186014156781275,5662184664924201392,3232417826492691804,486196803820401583,1714666940489759516,3591206862117506525,5071361874618921476,2957360424550861208,7188946394213043769,12769018620735820570,14610588681548044439,9758737912340558314,4961685378016718474,12154045648313775727,4472417508403530565,16954498147621906197,10447506995410268509,3254114366657063096,11460607755665023894,11257733367799056505,9406354356130966975,11032162728130622767,17384244531159629040,8226080795564867174,15564348668843595210,5200504801446222205,9814034989140460377,5481622538033494773,2111383773583076233,2693960247578875704,8225631502903260275,14688154232455415328,7802716193701589115,10733595868391674594,8944082067165536376,8592233073295175244,2166957567811988606,9926520444927750466,5638107803243484042,16111800408109393199,8997246705118174788,7656059573099664907,16434708312095062036,2993275896824574909,2788705128580510757,8763737346716550182,15462011112845657138,8153937736453361985,5763541592597141734,10319347457882277629,6577300343334526719,2799357680400210025],"proof":[[110357077633000309,12365037268262668008,4266825720273907663,359848712331478568],[16651202251846341181,14601586760917610612,11342222232464003380,11805131237331060610],[382121400027050013,12593922247025491858,6427592476730343357,17906086696142076146],[17848048808915405714,10263119788031538844,1472334496050337886,15574932530430820701],[5542133019206543416,15851500518013512557,14556914385220296595,13754842278248719612],[5892796745063592531,9139548411830153740,17297957356386193992,12854154279361005731],[3886124349599819283,8779112478154053430,4794769159612223964,9047906629068528577],[3202062314088344814,8863997784750273067,7241032853382394911,1789312350750669521],[8260812684582363784,10542213315504453830,961556286685910266,2880251382323643359],[13160918415965432076,7243896521311329886,6894086016816861747,295513574566804764],[11146156363755592322,8028508216655582666,11570827133717997099,6706358090020939306],[7329302667884629645,7690244725198522355,15236833018991581379,13241444249915573404],[17433710892879156096,10238627036001646048,262893625728523734,17387302355483106471],[11417001867770394839,10815503810624463835,2986195245611370314,13684545219650477029],[1014892719475835252,5534399983075720018,15649497001945431568,7866652983415669141],[6112895983571799427,4240048187258497468,16493330722301361592,3110541017215186877],[3917596628354293155,5216102744746703452,567594964081413321,3215432225810112365]]},"stage_2_query":{"leaf_elements":[5572931571912507909,14644099045482657514,6160937013790555066,5182176017461641607,9256169755559108866,14838117508036740594,15119777365536883805,8720828933874299965,3569770760073483407,6679954549539621204,17363124109946592288,2027912430786386334,9281283531125910029,7669464013657970443,11901550226042379860,10299754215948755397,14758351067697276991,1249143525406838722,4971759279202563058,5149654938453024178,2715888353100412909,10011767040894234659,3527002876094780487,8508184301075659561,12675157663527911022,7142518171037351653,5317319015371974851,6177010601225274175,8273462106360475589,7502319755425062821,8573471199478785906,7293571330006902564,8285379358500325836,14982762555200945092,13562727434039258124,682308595005371963,12752450751752907590,3833747980346708877,3537730228476290289,10274261291392227063,3377137734509859919,385576589947422927,13151323561449545641,12527518439725601457,5374445350948965802,9576779622345342329],"proof":[[932603209947708083,13737112973742025301,11923725329266548269,7807595078795840773],[8450097276628070325,1798702779772305810,12527448520331839998,17040369160638013177],[197508408331611876,16413872533357781323,17840869668501721060,10302176314516206154],[12402441673675999448,10641258057931145774,4041154883528890486,5027023683407561287],[17582485065344580936,2816587258671790011,796016445509048330,16048067204210383650],[8756984225029390408,1253939906980306966,11685390773858576986,3001820772890819567],[6154564686681150346,5387117607821797784,13163677832670488159,15968094115867390516],[11994385222985044449,11965931398718100925,7730900987651918777,15906617620442564573],[15580223185280172112,3390809875448623686,17860761388549255751,17729160519376984798],[3198814203681490571,6547831606655154560,9637082751998342007,5347812240079372403],[5215848992486547025,12747421252104587774,18058942292001438642,13421746854318002169],[2087056134756616798,13324622617578587647,16342078592839235865,18130487356160313563],[6473714834145717518,2690711345648987920,12526173524740235782,9073061457414391592],[8839465242727558562,8985980585370998199,16412494146552421299,7542810653537521871],[4999927446683795855,1106032345656295935,18082680541043644376,1700516947900960559],[815400835381777564,10965329387145003484,17785693756176053637,17120317219553773140],[2790166171694431987,8776512649030213805,14001141908799450988,12523224147355573140]]},"quotient_query":{"leaf_elements":[8325672638733478395,3329781594660324090,13690442055185095757,7048912632338415447,2422527416135016582,15199038222852415611,18104935196533305952,4474328506139389778,14288500907296170655,17338099053554521764,14236130956456817585,11717308121461737956,402985999712911960,18099534961577384699,9289782122417978742,7117395065062899951],"proof":[[13542042405604558889,18379267346465770183,13725660143538906625,13350011627113706446],[14502489182626375046,2079896878722654790,13096098075489950795,11530809125590541319],[8004745924576408264,13741599634779245015,13392192477284340997,5726015905961411377],[797562201672591367,1486622223637672444,12073732724582408984,10179580539453725549],[1872731584095558197,17260278331324536666,3879664162984541874,7040720889115523819],[8861024282265084410,3356057331633149083,6349857624046184507,976081393799816020],[15485379729076946215,16978490574560985824,6369591432015908594,10084787195846289866],[8467160335544429316,7466588779896268513,17884289736053747480,16969429226995243577],[5174461120835464363,9608522845249471429,12129499797299757872,1035559179431554155],[8361284189764107934,14472464605597449759,8524736940092364432,9023965405288158611],[16115528602221183358,16796201086900483953,11326707467637196299,17095229778167063118],[18150050040364611202,8361366268431655749,11689404414812842256,12998642894831808690],[9552647039709861758,6694545141868499457,165348086875426480,44931973174307340],[8139752835634804613,2707795023180908895,14660550316433897534,11909614671470094019],[11117642378076169156,1092705557287338393,9950254602380288730,7855935964053626581],[14881425184387053810,17184713853013655860,11417084575215904291,2268517284729831118],[14827574826222641753,2016236490897640195,15541113978067643161,9328589100278504453]]},"setup_query":{"leaf_elements":[3157282287054612540,1778080705784495816,5547457330144296561,16112304276541297131,18225682609196724137,18210351804573610674,5720440917800249339,11699887741749410255,17644288401123274966,7261025836567491340,3349781566572921045,1208691379626859107,6620953670245814287,11333125861809630259,12192358012573686829,13994989977043596674,1720069075555650623,4521352615039023907,11699655987623119781,18126622070802413179,8520229787928464494,2031128827326485202,4833425891527609843,9054646184695532484,2009067776244241166,12594254443154960650,1958087588221724029,1142358931176213360,15537978349771533050,3962054760760885780,12675161632361998822,2829118668263856844,12196419679463673121,5686003953620425302,3816829901229381871,10234400215716794834,8711720768040883750,11338645534976782570,13635433345799329006,15827752110281491314,9550815079115403944,3911607880132841194,3736979745236084149,10567936903872857253,5617437292317684176,5854177999157618246,1783390759102858196,12194798610267858720,11128774078195573501,64112820345142066,468275583487208814,9663075588673991260,16476732003686238355,12982993448998783065,14294283483025282713,6257358336123336579,5312584269686985588,17538060199952430613,8181877233450501820,5708104301761236494,9946024066799529944,16099330350776144708,13660861515972869695,13808204132455849761,12889513113757071789,2383093714366265505,2732224834931841904,4922274567371731519,7155874425574997166,1385930889776036913,14854918282459584211,12048508605486757180,8216193661227059687,13992220672021594165,2585250010033237791,11246313063380679689,7332651194227849768,854472751990375919,18112176419440032518,6399825635176357676,4112425350863561758,3036438862144004261,11744998992612836671,12040591159105957133,18301199154648188329,9659376316520437486,13267551151133764482,13764030005732647522,18316599708814378738,11744877105252989614,13674393160432875684,8824641261430507011,5593212382208807482,6583533468665716336,5225333153951837771,2937449209630837255,7866434364365627025,153490411664049753,16525531136567337218,5700280896152025742,11886767942295459561,4898775076599632065,16026203703293311760,18378799496914353962,8560526019906027063,2919971088684440530,6947889096721025493,17780051563033577861,12640560147568575403,1681738182936210966,17836414304023069260,15521801543141988536,17584164453255607042,13791837622003441173,10169570628922912852,11117732265303106211,15492084761958278784,10630864925080272021,7597366359103721684,13544686522018145815,989311961874357515,13904903595019075582,11004096014655583565,6285998346960293491,13167493104489730722,568524774378943674,3395817405837454687,7634827188033358007,12187749891192846451,1262468021050129434,895274083599194162,17562079214013056148,15151963773135671051,18227807115434069432,16790156942021760500,3007845653073479054,13059089163335202528,15324046948913749658,13806687427599290669,9259365180901825908,2921240592211750514,3821435676672347300,11897477223336363432,5444271601586735051,10002313861486536862,8378103168279855083,2644598834095125901,4630893624632126930,17044695567941651461,3237474676666948746,2413484540060000013,14890846462389528609,17108079399826739987,4379680425620485519,12763188785625846929,17116099796281670547],"proof":[[7951858298330777132,1605147294472822809,1353511191486689106,6660223470546882711],[11233770618628284135,12628792171793660269,12469722795242202962,12483663285198823795],[570502975210174432,11407056118948168662,3444848406758890334,11121627618696731052],[17167740682740237717,2798339616113529579,4892879789094216722,15726301171893966821],[11433360933248375601,8357706819877166769,7702681140712438450,8392572034320907049],[5373016442822881704,14155056752387237819,6787912820008977676,9517912208021326675],[520382194264169558,9656307497430940280,5244448751278497450,13572930925569302924],[8636518873250514530,6193824265862124080,8791640849988443716,11600211368300241009],[9372518412529645434,4608099084589636051,5172922474809422613,16121076552397793975],[13888979119920032713,1975199480154507282,5918512060070948560,2267238759920108898],[14060500660239718319,7057525425939236399,11302943849891408278,17586909898269271448],[7164355892403360769,5406480543505702664,14128373472819943035,17014640348521626410],[5418086259919896294,7381727609056062826,12426857512924026571,10439839575926447663],[1540503649849364748,11626327836616355004,18324976427192345599,8560881246103540397],[10576329465915927635,4738325228382125594,5403335011308195883,7734415700659360615],[1833644971259862079,12190373408006751623,18315229541642544120,735754289676257334],[4934888255329451731,1299074057986496668,1571136916485237263,15408557579809708270]]},"fri_queries":[{"leaf_elements":[12614710340544927491,5999179581353198477,647630422394827771,14593250967300561577,4044475170380202851,12625665663356664159,9815836514024897551,14433053707518434541,10402261532703066119,5232202818454793983,365713963016033593,18380845219067017664,2726169071824779297,9636848990423304494,2340508308746419270,10167461675363231659],"proof":[[15845578791268306153,4278235548473724632,5487240171817702704,5262388046136535078],[12710906556605711598,17028991396444821546,6841391012442594636,10698890127955389800],[4812470693795277675,13697281636886894096,11039458894689521647,11431933707270282102],[4464413113878054410,8515940001198260909,7556048955137067922,1641163796785245662],[10233594036261852656,5395985522939649162,15517576583591808480,15324847564373380740],[13947796327158137735,7388507113226613291,5599535623675453052,6474106817486258584],[10417267234873177684,13640208270035933641,4482063159122790565,5929207068903968332],[3290561836098468217,1634992328514947216,9629702123923297751,6800564166037787285],[17234639074248059615,10637495665886292622,14912573761962391652,10856384552707988981],[6779940994184252214,14578537533848514398,14703571506616763044,3269387733613162799],[10802302014040267326,3413542503612401624,8533235359906075328,14059570968824284954],[7712941196332384158,2234253642028677440,3623094376245498056,16770080918995439317],[8297876022787439987,5765429358297417092,6969424009045859554,11505474989538549772],[641015916041718214,5697532741910532451,13423081019210976144,13295319889382710901]]},{"leaf_elements":[17622875681894808503,7126438550651397226,3607229521307654264,2660158727810583952,1914472475043451455,5756363317582046181,8744429854372150815,2409833060864817304,2247329997868719955,562692740170696937,15258560279418086957,10075693077921145531,7927074806834071007,12821192579654457083,8013641343744013770,15921270688488317841],"proof":[[9515704869508954976,14845403505525829565,6071273764529113441,7176616485725128042],[1500854251037481441,12735065041078570986,10164952935498589577,17299776703484196862],[4777852072791265583,11078492212500592569,13088397241050204134,14577796803064934209],[18068019996331904087,14114776019544135809,6662825569068303372,8054752282238805144],[16820181625316061590,4488955860915401640,1194697834481333595,1663521993849440032],[4436486571118890909,15670356911689519841,7021530468001216692,10778852721448716254],[8013841618710806005,10565919178978700527,10088084411897710176,16565268417768170613],[13893555686248499061,6610207263665711925,2795932916831993898,5439159017067286],[12818563448789787201,18230280399724100202,18362585760769373013,7130112083746564049],[9157312705825459678,1109992508509457527,8694797752288670585,5363340447168050883],[13964360843438099738,5308142120266251153,15132423796157510014,11027328105767835661]]},{"leaf_elements":[7715753706040434497,15483653026281113504,3713069581048278067,11329061366587525334,14314304938398388822,15279103397876729487,18088150594850356702,8490883997152494148,3644846197320962249,4307700863175158927,2508004638731413613,2925214375857976414,15849924311605970471,5983978492681437846,5025829999083498820,7063214566035354135],"proof":[[3798521499318682129,269501411922608015,11074729228858548813,13559327299147909510],[15745522213596498657,17814958180677767044,13010688594513606249,17762697629865560667],[12638110077261880993,333520514039719618,8198939631535480802,7489898513678704296],[13192801077940301167,6365675821048678250,8681937347693881030,9080300600282784055],[16682524478217890027,2190762685788231574,12910941506765017698,8357720508366249309],[6747782692601933709,13610112329823081262,1986966564149620850,8551507595686945431],[11116643235427525610,14518903188011855710,15245943531208690321,5486400384080011241],[12257679492692059374,18190169789673338868,5420267801344425857,6718007291386775040]]},{"leaf_elements":[7358705260540110366,9252548167623699948,14778184190702708612,373114598971644777,16099081584093451659,13174692258963732292,5299482950361964048,9839070334588674785,17229420914193542975,17033815981834841029,1208536868399220767,5427931961766620542,2624660586014077843,7983550004494447350,1194243664907014391,1069516778587495191],"proof":[[13272419615778600047,13121285898819267084,16514870643035028148,8427033442707220417],[8980714397682066143,18219726998984852357,7991067685261845073,9317556618812029841],[14304120753733070429,15277994571207337038,17439988261715131418,1201022336830506282],[12065489398050746200,929195210530829821,15415105721406184926,3929055976248099660],[12203878495608607889,2768485086897537620,12912318947888615320,7822068476628361097]]},{"leaf_elements":[7392993070805491309,11552045744772046427,12496133539668439015,3003604817670474346,14135850980729636528,9388815079706249576,5958986795123143048,13826572263215382441,11512753704284846525,145982144781285033,3583019029112201192,13479869214696378003,1795656544638975181,11892787737611374688,4571898229303955360,12823271620420939304],"proof":[[6314543590119612951,16919554272777727026,768741617701059578,18038188886235418151],[7490477249103747300,14890821926391065169,12528894470063621292,17457008754437276116]]},{"leaf_elements":[10666499788113613538,12946354179588810142,2978942579100575765,17219500348011935376,18432379563349423049,17978726315520234670,91014601379555257,582079298344061305],"proof":[]}]},{"witness_query":{"leaf_elements":[17025080575283761639,7024442429312216909,7640178754968845150,6239435979880187643,10186487639706300571,7553079611862741285,10919845474461431022,15071495307494998178,11287953816369346655,2972073390461177293,5108594841067799830,13042096084391132478,5593037882813052674,17099356791454765821,15025386599452516289,4196477735355346920,12540448570526144597,456060549956886104,3402259061066406478,3786208762485741075,14968556061256325379,825043516652570602,8661093239041254832,5451792317114508883,15275976555644962610,3089314536730227409,14081626843669677606,11703198615657305862,11440298882649296536,3085715463564330284,120326170904172124,3885154888460452931,1929688716947429404,7668431305778875360,4645109061894204916,6318507329982661917,1238808372958057947,1201640866409442731,8864467799361582995,2224126206463323341,1648795702178991075,16090245869513541009,3671889639699940597,4033377612089920940,7540445775635873997,188029343763679248,12193571689875676314,1857785328307422872,7163284034067061442,2400639964754571564,17387197069786162787,223130693484863332,17245406571298179771,3569528163389823889,7460458089514818393,668125894310674081,17252272306223457935,5139092256529944065,3845435176265411725,17841345903544664633,1358491478314693746,16551831396477783746,11269952955156767546,16337489982512862091,17641841220341764072,15551695145069566456,4992609850974534253,4873113538025434336,5196184237180915892,16802715020414746669,5711427120128145438,10034073714622715445,11744626072400469884,4928508356816211908,12874784176783369147,10500111633781142992,11720202003752904765,9208939638239703572,12719185213851854767,13215045227844747097,17788314811688617740,7813445376780173902,17767992634016960501,827547371409326639,15992726505237210985,11108756486301025835,2497487064016881479,15686296747334578582,36880320331208976,4602659582174974355,5241753489314464727,15015726935665089613,4349556476449915211,10807723565205514760,11026913361843994698,5985402446639731154,10509498223374406014,13032153759712783428,6276624516775655165,11172546202494252695,3106785940667842047,7632243776079932465,5498068081679273502,1310647214235644309,12350332998901299827,8280501312704355261,15383670342515678712,15144682444084747862,16134173224063045879,6490060994793239623,704714053550290456,5437000709575903409,1458866311135186579,2180423011644720070,6595101077122108486,16567568904950836127,8345790223648493515,11558180103765920379,2430719188141246705,10267878816125287820,2293684741395709532,13311665232754787385,6736206692235651945,368252103714723227,10930367944747706434,14891070870025877493,3109700771876633785,2826580672193310787,16327381361206904431,18206284458288652058,831391410268978810,15076980382824256017,3970706106839312252,12114958143805322267,18386420509833759316,12342794149098900500,1838056937879585445,8094262086444720912,10759428537262228238,13148213583699352171,9644408063655190235,320894338540872322,10971287531091406922,2203594177036710272],"proof":[[4945788068892683733,18083165213166025646,16692861497965358431,6907746196388386040],[9761621422824968566,5319111906747407411,9479583839477121360,14176243845870748624],[16174726570241965549,3155779229874451985,4824486913119814415,7959586901546650510],[9089815412698296702,14522094061137183,6880902271222926057,5688172176805785218],[8249629605967888939,16699152789326682688,9454949076069916387,7075408495126749070],[13985699840033057696,5538669635993689291,7240469163162254264,12277782612609846194],[12448090056570006318,10632989702163840035,13745101495354701404,3601532255498560812],[10069155085892944595,6718967106605766322,12209225838151596164,4919703680132460516],[16257123831857180442,15930375842760636943,6690131918970315792,2318356037203920680],[3558996199471052651,370381270500917739,14576119491286185044,13480741336006335310],[14790750445898040201,15547092544308623962,6341417547943285049,1695560939164710659],[6749730055132205474,5521459689762521685,4757375426647836117,5687686242524003080],[1982872129896966371,16421422455307435458,6033855772725791638,523091488060169203],[2140620345695808662,17355368533352956164,3457190195744214967,14814315369125319841],[11951827357206309229,13097214819727585193,2036367471187991867,12943832126383923209],[9980410839683514472,7322550027951755367,3541525573975756140,14982918748775531105],[446318376307115417,3375364935197782891,1913390476604132002,14742194311215528796]]},"stage_2_query":{"leaf_elements":[16718864114497043492,14798836075430671113,12457709193111961697,12395774185453522467,17069644305617031925,13064530599116491393,13843202830818666986,9295728855021218095,11242712880761361819,14223738824104057761,17853962794152139815,713579447374493650,12032149576609900134,12959698540466489745,4513791981115668198,1523177753282857849,5990839877180823218,1989617334001234299,10074742598697760897,3701190487971038557,11200654539941949832,2560843393032362377,16106030840826058661,11273742056870267948,5979964374794246504,17801446222147338017,4014829443969295077,2697746473227335104,14566874778063658981,11175698919253212872,2969188220266349027,3924658724986336738,3800461220518123774,4664437907287336247,1236737563085490676,18144048287900231596,5680765123539012027,14469634807096791494,6340596041102826101,5337261502068185924,10739422522960985797,11121488313682151276,647991767748690420,9140119873549250340,9948704981471134031,7512283961195473748],"proof":[[15249594842141579221,554710762720159095,18227414156808355897,7362432223189521483],[18296653389746803306,1280519009641902023,10395155358622014918,4297285479258776111],[9271989933989195371,15311473276839109921,5112948093946089224,8444795176261456954],[9617150375772605098,13950635100214919671,5603680917931034183,10383483645500555744],[862877391930173424,13932652629023153254,12735224893881093995,3472981257188013922],[15403364086358439401,7101678028612222121,647055484934046309,8819526851920391019],[4706018188676161334,3923733691114401042,6795096826612580107,5678015707380120691],[16898636462935566216,6300453432892578937,16707937143190142869,14575009732120928997],[14834038408131239794,13154872324811150759,2489180430670580717,17044340837079686621],[8051874349216306435,1194883663709663493,8249412820991802553,10527464725673705465],[5390034172052015305,523988375768503877,3360706967712663383,10802445154570898401],[15352473958213147210,13707198408914894865,7664992019769842776,4492833076830641408],[12250027472988859084,9906838565907780395,17282877811165988697,7573179783871897611],[4473087033341194905,6577066188905207355,12643674693770159128,5530704844735218405],[10914958427844876499,12282454562936516529,7096338018838841972,13961594818376461985],[15746818743837445237,2985640451447576772,6733483411823019191,6575594278664829228],[1283005982263822647,5576217357074790266,4838152385037052151,3671493702847934836]]},"quotient_query":{"leaf_elements":[14940385072701952729,16591642717046233787,6692327694732029132,10226441911544153326,286070978856743931,7758287986396700592,1265990994533930277,4118569195540019500,10990429079935543828,10479050113884029260,3113631930474858599,18374461476161167230,2598094843555372763,10386999767490418388,5673916839337446739,2009422715770988016],"proof":[[16278894403799366809,3938523742673356563,7049845073366863033,17975240212493365827],[13785473219402383487,2742038554059202995,7766497475555670791,17423240938061423150],[10143968681351477919,13335385118471792546,849801237109011568,8293599488997796101],[16755776816279788907,8329960494074425493,11891664498066655631,10212018147005075040],[11931037950052283835,292218424365805740,2836489070628598287,6824944562748614493],[12141864469345084305,6126175312017409354,2965838303744954129,5410260975323048071],[14746139948806392623,2746308993532159693,16525987958847866479,16499960128553820634],[8148831119352489565,9093135196423735619,13861947933010752519,1094511237796032900],[15210375394052135070,11586847673890753446,5370462858215294087,9661205131676868293],[17298448088077683205,17915205840531984130,6978354368736762866,4155234899584333720],[15160794092015738273,7823973703493189777,3225117782516355430,14274843252422849221],[227243133201143365,8089359389016143828,13977155590911333445,12337003073516715508],[11818462408121038067,16434017117883809501,7154103643301148752,8658845977399811661],[8151549188992794708,14291217109933088059,5162015206749826315,16072450646956129237],[14717752442514341439,13981289008847674605,13603209049062031231,4295238302453043424],[3689109562764849626,366021334287970053,14460318300993859375,15450980280223614390],[2756204060012982104,11181890352814265502,17993618182006171151,16194213402389489504]]},"setup_query":{"leaf_elements":[6852751104712330238,7194732435481557168,1325875479912803403,14567736121916973319,10774136550714583974,8591709566010515080,8804029572301370852,7896927903550004504,1703645870030951072,7024506177737949217,11426413818652225379,8364947171655496637,9522020762304125864,11411894863894830177,12181066441238938436,12365131501031697813,12052722302595239243,16371327399206790985,7778247585070180647,10623275222019305175,13228781100312742039,8998622166480635770,11642252111598879625,1512648478735026426,15118938195788693723,14430353003955037715,8458032755608559414,9466668616880372234,819855802985908295,5080781713405950078,18242381851428788842,12419299539680601195,7498138715266762821,12825501826547331186,6820815444457119106,16520826349653449227,5252361790594367728,10442047138263188584,1424936428042020217,4730280441569902257,16270880271208506076,13660022482740533058,12157500420943987552,6475975908348693451,12863944612270913398,2960229177019788646,2586779847592179118,17343005940351569990,16264127691744533431,16540453483087252458,14511022758659119997,17383771439792448622,8356831490246998695,17346452325523853572,14407527778001101612,10397260577105658630,11811784256012671214,3399193146927534949,9226844903840182473,1419628245791421697,9519663917136030538,1603309165910101280,5665012464196359914,10652101481180720034,515355943663871957,15748884629834849826,11463408816615546385,2356174226073925134,4026912497162555442,9803268737695325273,3466138377525275343,16727195322807998924,16037133977124096776,8411046003490170161,12709445621220774385,5351153348455962538,13846869067616877142,18139596576981769043,4371417687735005591,13707893092900760268,1958068618587530642,3821583511070144941,3125743931506907310,16961885439988276830,7709619547903302442,7990482294028176751,2838284726233290415,7032761238698389295,1713320501104570849,2678923743828332109,9866747113310123236,10310481623057354675,3188409991128373026,3729452547231909790,7122955832282022982,3373697298831233700,6183485878214684992,154735747144127745,12060864224400007700,9348665984241255448,17853536761511095715,15544660240512020828,17909078013789921657,9404657640431504173,14606869322064385787,523591306608375190,4570058037339981054,2629638568980228410,1080706601297559044,4982884315324255391,16929903741157315373,16435531296287827413,1857543029567487852,18150575797394401586,15643519776398173943,17875277300638034336,4558591440261069853,14162013873990931118,7771810650785294223,18285217859326120079,3506010784558373120,11587338609312888649,12112236192957884938,9591371214630663944,9982159281943740940,2176834024528978498,10954460108436595984,17821645324347995676,6110578716521660529,16635573946252180248,2831045643182493053,12606855764787741230,10955572186510742023,5534779212378826404,18219080351143430564,12874356611195152340,13035959035323587529,17687717990236938632,489413700267871804,11125565914661018668,7264073481749846077,10978829358604646,190339327963876732,12368293234643576612,14019145227154368347,18211520621749077975,6716474084417289071,4875009210232601962,9880645667819331117,7424559206557938932,10543660167294584666,4869592890217222026,7863474393945168229,13602932468278110338,2074314840279451248,8719579258854024504],"proof":[[9527636930014251288,18263771125587084752,10433838195806965469,14555422690857276867],[5205695494290689899,9979480434406084660,9237229836788272488,16469117273728860596],[14481751523679552043,8580642154342653313,15511773179293654587,12084209238964146564],[841091385458913996,18364334081551677121,17879547267672971242,11798222394882019444],[3426029262013693102,14097346469758523860,12663708549368160239,10981881312934249758],[4836379694403332742,3318436330974235817,3056671152788236008,8529969828791151577],[5941312449121186098,16296169019269276263,10402062781427274140,117769072775182630],[10223164386551020003,956031560563824517,17047400088235558106,2845875624714619391],[1155305827599650489,7023967536655163200,11132646724337935465,11925384226868733731],[17771855953648723589,2538390932718822204,5056276178893824110,11101145939608539246],[16328476827748662022,6839878181327630308,6342148001187493610,667855336757923237],[7925333781893792158,3195054428162523657,15266822188084093017,10927713320948788988],[16423651999356327862,15236988452512929806,1740126609028208541,3947742250968482882],[18116677117884776531,18190039508294493617,10170924942196989904,8600647547038082942],[4948683317486886608,7487393901776645461,6837397248267998270,11397513462846164754],[15572169563599132323,12343102909949677132,4166028430645002977,10454462429890612665],[119942016992425815,7641812824221345957,717302696007773285,8607632033190912232]]},"fri_queries":[{"leaf_elements":[11123993299713629186,1054757351996849621,1525746806624982044,17951773102579971130,6093752083077486257,17491647883557690805,18049018143132736100,7051691197175502520,5359023840046512410,6153541596107418855,2184285290849845658,11297435460166133271,2363725838399725981,15931037453015663888,5259489404686746732,1971956737912738601],"proof":[[14079798077806014261,13120608911831613902,11217846910480630173,10774555253750767442],[4517374090363507601,18065511173933180311,554580431127124436,10556593488715224002],[12584878439153585144,6883922030602512830,1640630604026594219,15873294637355338569],[6898465604480719909,9575658349682842191,5409249872101608951,4152831302939916138],[2844310710359931777,11168144352255173228,12415683327100346719,4855293872387117894],[5328329891871749219,9892911156358775285,17660952559057492690,6716352443869331523],[14281205790211628004,2759380947665232986,4995025008814319139,414352597056471621],[2484755784406921545,8299353571622914296,6834249439278944705,1228704148440771713],[14900760352722124607,6550940412649129067,18123975104593021639,13573104226602815857],[7625476291268004364,8013076229905388812,14009550676249496302,1661625964252709811],[12689699574537352100,16869873833182078432,827686016031246424,4612442477576389535],[7348396166919247276,16263404970388382454,2142379876581275148,2942414570241630678],[7027844335128081170,10129972155212038019,16401628726279509279,16456211717365178169],[9497522330654010607,10428746838159854411,17282797116643625741,9370446250429457167]]},{"leaf_elements":[13128028622120028627,16802196579221219708,9276285701620140747,13787641884951859713,1403453543342995532,2156840990893981700,6088040437671589617,17546039716855784504,7017991549076251636,17523941377537102629,1921093508627839245,10837548454496607908,9842305197848799845,6855900773323761369,16990993908500143870,11208199635199441867],"proof":[[1722680127782541065,5415092306175286823,3567557079724066921,4642288487929285629],[8754836203814533684,13097757395851818696,16141795539539691083,1533922307774342819],[15050497773192098592,10211769778140080506,8814911916451814094,5571604023052475109],[143973265220220647,15444442828624509641,17273523207813760624,6591459453285451858],[17376575368627268637,11048182352653912656,8712115315256847133,16235388471772813830],[7394236545009466777,11969232646000417979,3531348497350587564,158304381424582528],[6659417859279758625,17926714376553970511,236507658092605876,10812751496113561048],[13390545111612319389,1205746715804681740,16615507862939638980,5308728382904331482],[7585271640700190864,18291211731480065701,9035414603451998978,870184051879949350],[7259483814939175432,9308379871861495517,9174850034895773180,11667434776828581520],[843411343929838404,8361740330644747194,2332379768699751226,10226462084284657766]]},{"leaf_elements":[2900268611856737968,5612880980310642497,3455207164651618951,3320375107406938930,494266919274150573,12132607850405119422,14679523617676744941,16333903136510393457,15952616483512979822,12650683886507355709,46294427535504030,13889793975883438398,752765564572600741,17756779963400605356,3439259589979586396,8929746763896781513],"proof":[[6433853100300686520,4426388288213757435,2885522735597939405,16755840542107089200],[4985249195850071600,7746847965770001267,9736377305751095328,17510458089327172325],[17197313095438969673,2572308448285340168,9834969403562932809,14936381827050301920],[15234182616218258260,12563574592336039759,2313093562209261277,1934170974959321930],[16567448744096545537,3732207049566888348,10242330901349945915,15858518909867275710],[2490798402822011519,6029075995711532609,10209603759146943077,3041891424170958311],[5626976220079211998,8278137800848799186,11465004431706415804,7425384378577539552],[9196460362043655518,11124783458111663969,6628625323182741542,8138792676882935518]]},{"leaf_elements":[6608639324031281654,9701950207170292583,461073053219399971,6986845739421472578,9324739551803892223,17990188353242922347,2798202646662081480,13233547605061735728,16461574502585518484,7420743069995967764,3706225623913289464,7736231674288769349,4411460400396141167,4861263064334788288,15286903239964097818,1356027025464437376],"proof":[[17737258935125856596,315578468230011918,12440055843854170745,4725449642183565352],[13861428052915354879,6958595065401372938,17861956757320225247,2422553483355887586],[1757108959004317661,12150813522724279935,11278123630790057196,9521192206715480589],[1083676519607914320,4441070181462611819,7752158295056961851,4667463103369543388],[4195745188892480400,1278917477926341115,858660738527305749,12026569133742582051]]},{"leaf_elements":[3042246220767584763,5961267606790053738,3559887806305008337,12317224916301103859,8124994906015625402,10898482425804395082,11052780135917769558,16398846206887122599,14733290436189784745,1767138289286919366,3896055115106055191,17020053650901645609,17018099229898616363,12843003703710192669,3954991896419468685,13020405056681120945],"proof":[[14146218265997383420,8880798799092325101,15074502922591213158,18215518835096624766],[16070927894096146171,7499309042979267285,15222708687563261277,7377423658769375210]]},{"leaf_elements":[8872244034292046542,14961388654118324654,5802056968775514489,18302383666416428067,3933647026650259001,8825851261617385151,8616213839298888053,10450361630528634353],"proof":[]}]},{"witness_query":{"leaf_elements":[7882589746160823200,1032975242184768448,3830648983552454374,10509699402039483099,16810953105243795723,14732400603630160682,16093825848233434121,11964222477534498396,8421794788646091790,4098487220198001164,14165010588980691790,3095078592269809973,8168364431502158008,4377507561543826055,10848747745260060843,2039011076878733867,2460324809366920425,12356550012054594938,8752398520014483898,13369770563150792902,6799826376045016977,2413195705175596243,17120983113760547826,7338490128029977904,7560822685656005693,3759330860609079558,9885815710621249069,7311568231248889447,1818323215688585110,12060377054081861613,12068836404468208709,15687703993515641446,4638489395135430912,9739444367166138322,6791160737359380582,3627415012343184620,15919399310641750832,10360313353951045250,17841292477663732872,8601629042686307160,17049932602738390272,8550238144060634191,5832384150348512851,3317337816043999269,5306106964133076595,3720633666301400373,5662857943626848,16488323151997523004,4728213361206535957,13007030471161791960,10080996684922276070,8128641674604619989,1201189830791235213,17146348976920848024,4116819399575545991,11294931565838096449,14912668254268486871,8805011307746401304,15473598098968008813,9998716514793356380,1974331924175433885,1136346763182311920,9782537248648147399,8962123134004592014,16227050942245238332,13414986943526530207,5671778304554910471,7532438991167465378,2439453316468543690,13369098563796844415,13582004499362700366,1267528998743240984,13841790213027835885,3960064337083129776,789177355650151169,4012445341740507739,4107071724168523751,13648070889270710403,4537589369314033242,3191759366308978722,5347746473488355719,14080225897044609321,16258407007413522622,4676121816116015937,833174941518712185,15766990689307412112,616090723292147519,2128208349691911638,6368175945042695595,3834043937032723407,2383922244792855696,1588923777223935522,12860441846005517078,5805584801814162334,15303958111549180038,10146649044713591874,10279717604041954177,1904492159695525763,17239931229994500690,14792967937136254230,48922800472946227,18207523568845394522,16085878011099475889,10425319762099155269,7614778895581463747,2629787213607949722,5148712512971355999,16633835291180267200,7250382756353327505,10061937799044199079,2630450885928909336,749958330394147898,17290516138483283595,18322493821843294132,951701272200656418,12441903934174666922,1646317242002600112,10767839103379625910,17032619390681745916,5616099930540425960,15775353019178720268,17308022408366722860,908161045674412817,12610758994927255404,3644565815151650778,9538816994705318550,2504098890291520740,5954879932979250013,1715048839853342222,4228324634955439099,9011722094817443629,3154301702617510223,6271630326203221797,2539470445261849417,16123166376083924099,1503703166024370635,17720671062179311462,8299005680933203137,5700486053216050049,7437024844824974526,4463433356124906949,4446442099646912430,1324463513366934739,10751161422988048784],"proof":[[11687190186427986183,9678147317233533897,4279995266947246565,17694177344616932333],[15160453111295598899,227702149377481854,18402661072844711399,9740823516421047715],[11400806488574427362,12170744423790142683,16813459670035340047,1957174916043517389],[9397529151061517704,2142759835948667942,18206115519648610158,13858732589235093040],[15295806283864007403,14539748235954216677,8844829575047508988,14038074125720632351],[4399177377131203370,4494502904679268403,10543993289752070990,14675814789508762898],[1981419470967213031,961667515915333286,14208727384588936699,2179186776350641353],[2675996788164614298,12733254265605770672,18138188203148765439,4319114576099121278],[9451575836503615545,46208642867376875,2676383161361946164,1161222186885526271],[9066124952702153385,2439921335870956645,17142577211986010319,8546152575627545458],[6725817172374102848,17888759833291644583,4840094253233150310,6515948523303257913],[17655922924495187591,18180419882604072945,6061190518074259185,14927674684691554259],[15608995302328023564,8556360148318843131,13399048431430319074,5617133510514138808],[16416313127879497767,11283712842195255990,7891409969594794740,14888188863113442943],[398231122643392427,1077515630903111632,8171464226775056111,3773838388961395314],[7049343954157092833,14391493793205640963,7395172756984581331,5113072916745052878],[14710339626193100422,5166397287786674443,12877026722859487242,10407735240586944831]]},"stage_2_query":{"leaf_elements":[5597998218205532541,10829736265490800637,5273380132980153226,1668407060764963533,143660357428574740,12167959249134659071,2983700547084106777,6176866668474275780,2493450150627684994,18237442169876048287,2051502635224066217,9384720915757033742,5683825274014566942,942202636038496660,16579202390293785592,15971768019191347456,18354257397869901999,1570124172115223126,14632041803086284779,17922926684078391445,1051806684186384704,14052969516262374199,12168095769036172951,141041848947059476,4536277833825382638,3093852239559685589,1727722657899955326,4645424779914182032,13208599174828300373,5620575927920947162,10957600137905453869,4839937462348438305,16134216896766087374,15686455439503654879,8991456426102619342,2014428094560921903,9535333236667388695,10697778912778038795,5410747775451583740,11500832650412042597,14694853786512817013,6295117011621835414,3821405549916325683,17430378671235421985,14936838303336980682,6204401587382564564],"proof":[[10701987820414064685,332835256437363836,18445831567752164734,17757766462649691189],[14384799654876059138,13901382261059765262,5290335881611275909,16691228023551290029],[1561036411933057600,179487338663076679,9278173937338536021,16134611567562764108],[15528055954123654787,10389887632144856689,16882813935044405431,9788104865505108704],[527179181053475298,537174802304752318,8756391855346864271,13220785072081428192],[4150613835185512047,9403223019000667712,198880261694874512,9921130657249539095],[13135984412306013982,3923515085244432953,4188429090818056721,15804933536924212355],[9905035497980140184,11429214623774258445,3421962529032404935,6140218734246226960],[16559617160045519878,6341062906939985723,3043642379453089126,2946041512496703801],[5294843553959562077,1819017366968987897,16159755612998486061,3141529206692587558],[7526497836052394635,17093198524557436844,17814404314621068435,3083827683049327230],[11591190717429212268,8678239946486423682,18257312865707065491,8046858397001299254],[16648543337952441084,13271429242078458635,1511135963640374609,8926433556463817371],[12148236292999639054,7590710492859760345,1980637592013849352,3723113238523705697],[9088403170230633298,4772161975431710649,11728304519422826717,9718595746418649269],[9069739529505737466,793676914951333750,14464203160743970347,10684389483843064330],[1135997963394111510,13275752990064275231,6348311180324878415,7982923292041772706]]},"quotient_query":{"leaf_elements":[8943036502302463981,15523333226118826262,2706561459972172566,399349842471034745,15113611700979320116,7687850732112284865,2223984646288388350,16886247039422721918,13562541301401788970,1092794918079197472,1630271268125179156,9718073340487294309,14578199807345456420,11364101001895753845,6135008464840538483,16166672717846669787],"proof":[[17410008047103375345,13361309293504673897,12625834814403729267,18010428171032391533],[1199552449394990287,2570438953304295123,1617542134752389280,14992142656661224537],[9813092402062631193,10984788121868621716,17225731443474018636,8813862574479912066],[14021882764879949862,8713309752276859601,4229483568049559056,15161855900489097748],[4939298441337771769,18332394734651429095,10756492254758446566,6528647002297445884],[13578869146365058275,1474945815627300186,11752787329713882099,7552470292061543911],[3213435441372905182,1781011341817748267,7376827131280167405,4911949045516673151],[7826127010234011536,4703554990713465634,17287367403913441674,13316368502939096394],[4170253223916085895,78271179695524826,13804966298554743122,562539837753726512],[5193745934396755718,7104964226298426042,4386438212470366346,17672744436986436882],[16732628786526800702,12584432281369083104,3853781828295324915,4478701398741824768],[2805871521155111531,4689510363882655769,14731945303755200436,1858115073669336488],[15952706285246864768,1998916597599547458,16327236304705589609,14085674312090836033],[16720737551778299070,6117863868663704696,7095011387297801312,1982089210033508086],[4185821918032747897,15735348166646380793,5064113847745346115,8556318307176491458],[4359957004431156532,8965941034467977781,1773912866110419813,4664342605257984095],[12530437638825942509,9467813558315705039,1660881245341910574,6918973135087974952]]},"setup_query":{"leaf_elements":[14141903795237908606,6065954492228363505,1118746527192395554,3124321001289884918,9194518215931598988,14202787254318405782,14152529242739662089,7183328478645767984,4546888419256644761,6470314387598018601,9987855939937752851,10048612201658552428,10229472819549103087,6357082276648934532,10745117122103925493,4279580005051337703,2242319386019060613,4691565799179362024,4100582390074133048,13495540956314525174,14587118802530526595,16282401281679407284,4960100129577806561,7138024245966964110,17327361790804557283,6202276308645739015,10682135521916600553,15298107876874757793,3081175706725527163,7684170879539118092,14406767800636215571,5826257691759426330,17917399372125896960,12617521250699839641,10737288032746805204,3921622746034218259,2743313130146878415,3524336934938110651,7415471977285377936,3226267968687535787,1994377942544528315,16076085372637484268,10305116276872717380,14882960674479484688,4867692141227399815,47569140283461136,8534099390525130955,13346788799706091639,3439593304124000393,4794256735906335149,12896219098962619601,3405388134739831576,9430408053258993788,3580528059464434128,10698573082260255379,5073597099812151607,3908153112036669200,16408023262758269763,8444701075350407397,15971814342586795651,14703685117926271585,1775939014928063306,11315896565873838223,6138109176020595787,13288607812457765861,8186487896352694121,14510727189767804625,13035292127752009971,12773095653869454210,1000692394589950350,13242432745505679916,14405671919739636876,2818614040775495130,9481354319531135432,5453472310946387455,926450301391552633,1934212604384644745,15814058978209740199,17143025176919203107,14405007333926896071,17826099295341960967,9270753809057368588,571310183883661661,17983845950550838776,13435251144955559330,9140554226931546495,15510053685848349804,4387596081372273521,5158367166595636784,2226010654531921748,6317030539338336877,12460932900824997573,15108976507935630838,17230138597064550372,11526601212530317123,10610956760072748935,8541030556424432770,7012978803153927299,7181454511130559782,2801734660449959930,16813962610468465535,7049347074553243108,16915409177582524598,6774689547395425590,16674630010855239629,5162666754538916354,14439783119934280282,2402906239416011574,12767028256235069213,9634853417668598294,135004491411670371,11672047905154301129,4181245011159768027,1545467558093192033,13426110954990883181,7111996588791206209,5603400029652520643,5302496585446535112,15127993961627320298,3190207264494978272,10031599356648239554,6934409619705099135,4978962951505241683,1165801852744866462,5169845025606063292,17945919819879565304,10046692399352572228,1512287061660674571,15952481037098074974,5330410022056603370,5599575716131468977,6729709098105795889,12121508835384398934,7580672847935907448,8272182727582896397,15990629796593139481,9647663468145100435,10408483567779268741,7964371113017822467,1717497802475478630,18327658668227895097,417235157669191210,9216938194489312062,5886046623322004791,9242009954313843194,16303170715213291396,16016827476201451326,17553340692839274219,5919537091956519204,2380237474725297571,4983922898519866563,12027062018626078561,14283545425896716632,131821887702477155,14106438380335227032,3809480822538220870],"proof":[[16565300043465208158,6667096480954492113,9545889755455410597,12954520201330207206],[2960080042338967274,8180265849877920150,250221484987021950,5849079974897059374],[5903450423875462883,13382242308054641906,6656348312630300099,7322441941185038729],[15269553750041397030,5340853508991283493,14120526579627964610,11170761517323768824],[4539585485414903298,9762008182620446732,3385665391450658806,17002453864911270037],[5879420235826530955,8134034426620264086,10426921444637336818,10329327632785036970],[3154037953677710507,16315181022373450804,12024915273008287770,610296656311867144],[17845062657033182857,15913282993052566184,6347112922615302162,6717159371524833099],[12932195954534658305,12079850629597505989,13898957953737805704,5457299192208212574],[9998246981313053538,18101269830291677675,12698742349848459269,18117314524747317501],[13946965364760698487,5273451305728374463,15706861638350158937,511583958271890034],[4935839224670305226,1832716591068684636,13168844855013860480,16480563788388842870],[1375700962287347759,12020400834294607653,9879132133855187619,6691589929512728570],[16166008489637773246,1279799760342066913,11042046517293120016,13606881585610663231],[9994972003397564105,2959648603750529511,14163024019547965359,2585123501789816162],[7472052915157579580,6454707544650764846,13241508517962884643,7658945900870394285],[11786672773418549703,2339467107386851422,12140533047963330746,7373381974425188538]]},"fri_queries":[{"leaf_elements":[10633084027718398509,16490902790097459785,7941275088390920893,1551039904676074662,14505724438921842712,671654979317167203,4389980888459447565,3314362158533799344,16767534315124232920,16014597915680054529,2866287803712145145,10563240108502795579,7574677992455121158,10919230716399009391,13936588509634543826,5812310324940438870],"proof":[[761859655979766677,15697094745404303344,11568571009073017678,1817898698125705244],[1641359828960059893,3255192408394843742,3481840125248492654,12723587146120064474],[7260319309608953903,4122930786958447877,14309385031416848277,7403961014463156634],[13151013111864796514,11187734252033782299,9424548747177020335,15496088953962711899],[8545613724310281112,6333522946908036013,11411338189549684924,8418172677284419534],[13959132739376283293,3726627433766746297,2772549308283939639,6789882486128450858],[15593123953986154801,80498373906189171,4674527721303547769,9747535463579092065],[10066474903146116112,7202179892047094464,10586851348591350011,15921558146957690680],[563754545076310091,16763912036283228910,11561840306258104640,14368611567301233795],[11272002526626578023,5427598802636515292,3773710033059537848,15832664246309474244],[4491773661715036764,14171176404481372813,661677434233046938,5497373734903659592],[15540064237382094286,3313093377055220107,7825057548834223934,5345285968476203704],[8565450714688367775,13371411646079149581,7669076451911119034,5609613507105328615],[2065112813907786203,6898755846797313237,17320045911186699311,10677055216998779661]]},{"leaf_elements":[2904366912697228685,8677976880653134859,11219049900452736456,5094706038908882542,17752085836877146406,16800418427671492814,17054886026516010310,5026048479333127187,4903573071932254786,2298659573760879655,10194502610860907483,1072677394557176501,874587534225051556,2326660280496238995,12131214006459285858,17277702007844455283],"proof":[[11193031802943668473,7987049730960981140,7677123583949103884,1038754055199954168],[11432307648273394361,2911295115061640636,17104446561123018804,11896208840509053186],[18214079620138754563,5287969070058199032,7019133395766155966,16003433682737925525],[1853418151298238767,11747195164774176373,10964246708887158088,5781660165119525347],[12961765551757995901,7731216670832391843,9101584968640544660,13565294233807600975],[15922966721300381128,12114611508031723947,5340455823407334870,14290998518553674881],[10713706782693528331,4935912931353745650,1129401303703327283,17860025989730220195],[4012238349150723203,15475834714837565938,13798406662550217730,6671721927003531189],[542848223190788416,1506785852940021233,3207114844624851525,9598216552803946550],[7872375859433308862,12547335083355183725,2049786543156448692,9084700728308976857],[6068200341678021668,17238405178273883915,16254243979175388415,6326469122072930844]]},{"leaf_elements":[17652736753114557563,3334748995350341024,208546750966866589,4928673404378099331,17304481622108571974,2448586570067706774,701144200668938410,10184311872565869128,14399736763297297812,14714734614170387356,10615517095291199684,1694848781779025283,10608925774297970845,5216166785229516278,12768826339330642074,15886143824314649375],"proof":[[12526214581858026954,15712228691709226721,6549118893865779338,13302717818931628083],[18128549733673643435,14906907917503553436,3684150223878486400,15694804418174849325],[5007897155765349411,6949929722893305115,13626887572779363155,3733968131452470009],[6475818328961283508,8940952660664851514,3308949792502190551,10391139601156471978],[1029864909632161683,229958764587629181,2852611746439144198,17317535500545670382],[14752200600324885730,15916928362011918693,17708939923110433162,3063340899749603662],[4425897915657748671,812478123278601336,14446386344517017273,2479368791048095681],[6284005312668722525,13175024327537991261,5546811104920909949,2703000136490581107]]},{"leaf_elements":[6551662525282789288,16208142134764444489,977216874194405984,2170844392685281746,9781379251461706956,18361929464481996800,17444211960628069486,16969832633753669139,173022253111966539,16882744181751820565,9567333069946477519,15754678768933442894,12880075638742304836,13426551052833744263,3054627486387932868,2782412775534597191],"proof":[[5509278074795699640,2086544807818607647,12729445175004622996,11413092067484645704],[734501117818705858,5836905463483849422,5571639830852080378,13195914388199850733],[9996949731472101347,15815289785699759353,16091488387712227042,7938774201082856478],[15183664090613473060,1501067564438234346,2135154504861079625,2969398395681691923],[17991506096714915795,4636722536725601757,13865614444769694335,8815772354958363399]]},{"leaf_elements":[10912580827303826969,13112124498184870572,5166031771435844608,4246959628546674791,8337537940124154336,2808515550656452715,896327017507608806,14965286150849039867,12366897045461968021,11139471698543338371,14093486012080335828,4141646308185794490,9103831047924060398,3762366279174691358,11512998418801433510,1220189138193510249],"proof":[[10958797391945941300,8725990360423169908,5482578788976588944,8844326393553402907],[10835623355140351544,2411159751067968680,17855867681805886030,86569936236411870]]},{"leaf_elements":[13912788208633012260,16592364955197622110,12930883254427910878,5599575569218380943,5682660096836901399,4069773254031359724,17686759155637027087,11829746095036037227],"proof":[]}]},{"witness_query":{"leaf_elements":[2283964007145409492,3582703873544489500,14414011065364329125,7060682307802297334,10278380401092607911,18189228571604698836,17641968712001448321,15544405380749202470,10889019888265878620,7565977310725438208,14698935151228495524,3671499329899945820,16558169351838823290,4210091698313410548,1000139557384507886,9790926217514088195,1550939468599701703,15469942520188439122,9733508911775059194,15935995669165270803,8363543473322700313,709989450165382455,7321545380329336327,17597907084851465938,10417178894400426618,11991805745258613222,16826749005831814864,13455796185266976867,3898745053069495649,1503587424694428505,13247832179457453003,17577035266754188173,3194231914042794416,14674724951892762560,2537906905392705890,16465796469087300144,401903687028849118,506592574106582361,7236908770355518603,17776675783686544891,3036835461956353704,5156867326722255325,9526153356771611901,274295383133006205,18435355944700670204,13423495338561865029,4061627250680375221,7827351803689126212,7824088001415911028,12100301109072663008,15918224865481066801,10829905567396924800,2841455278548467109,13617067508142297675,10155856646415053298,11810602361151546367,5775024890052656216,2706103847648930274,8980716760289313047,3441330358935628780,1804549288055598094,483194238374861676,11402943865226386574,5281452567978020902,10545222193918574926,16163618395437577692,8774503746407014033,5633675736540774867,3303091707833890711,6299924291540273805,12802014236420436773,10259333135132477412,9487018971105813443,36624894465604161,2896524067483026996,16123816417331597620,4614741065343640223,541493027984629002,9894875611576902980,16347751342763639660,8459809953218218485,3230139334281777873,17719741566386307301,2361263213738943331,2642508975118838814,6162572365301228954,12928655143361314341,15793377084605522583,4637711664995814938,18317319584565030676,11768990276985534921,15357077343172247021,5177670464685155723,13395413085975901082,18097231532330446444,2045858627669713757,7743208021319505700,18352237390870263483,1187580572184432666,2796895031771390339,9289867795659459586,14434959508935927033,10589802246990530801,6981256961663050187,10889047607527677852,6022382010223158035,12182144017610151883,15016840388422551258,737278979042433000,7927281490814917535,12423032858399570122,13682775796974860237,17573338500846605226,5374224323183170215,8414261470589943437,9668619860414114002,12491739695414852350,3900576679831828558,5104509118375988630,1649080451838164337,8322018569380629624,7541075235529836375,6014655906815474799,18021979919979261291,2363959656871751029,2175179194115574678,7924922995736105703,9954288791205313951,16425497435943757749,6940029372980546606,17043463788563628707,3510087555969385346,3835474369826733717,3893040853747098277,4833114571109428838,9517022067710197510,18279765372707666266,9097758008183132688,4501841322986882056,10041706663854253676,7623099870140126123,13446227293752157027,6213969791327589651,15778257376817838647],"proof":[[7106385183518144962,9792526810458172325,1521143166228514764,3756444867136440300],[17171119709981335678,4786408406033165777,3433537007749823431,9303435622926419346],[5361892192719647801,18066724347244181567,15182436813657064417,10002350658367201436],[15931565227371630159,9481138165725889376,404477858948511929,14695040066428819068],[1380226548585152761,13101192877538599087,4684971203280065385,478566295098653235],[13153299411969004643,9046658107988005397,7062924161185485786,747269652608763825],[5640512280629172850,13298115704672556684,10165184200377847476,16794235640282726495],[4854010800264380125,1029004321231923539,12114060316279923630,10862744236394352239],[532680958595275366,14645330069140388157,12689155835316534554,2866527599415170731],[8027767757642169299,4609027724291529729,5005767625937426133,4565827827389827865],[6000452700036918212,6766491068913855796,14312873968646641375,2069917084659123457],[11132451660882260396,12700030244645250266,13312385249128500410,1204130498441350376],[6377208783336966507,11185535457167165315,2582001691010872816,6987904663951101170],[3318722789260821557,13420963214617934432,1723960784902408094,3132617332068000993],[10593578804212306784,9590944874138068749,4212487341278254657,13243196346763584774],[8396869664660839843,4046427985503139531,3237205386988153706,17721058804519625408],[4209660706171061763,15569665661657088303,9863745563231888711,4660762711415287022]]},"stage_2_query":{"leaf_elements":[6089436680737954533,17049842551158772755,7997310976613668270,4561685794922215614,2569342368904570191,16661204275418885687,18322132212644175239,14535437481212394337,3632167713115094066,16713321515676738494,256581253316016090,12678348576592401339,6712859825645497173,6278520843376245846,11327383750259073735,17854530825969467295,13310753596211685358,13901840982139685491,1990634601036036200,360753154211488024,1444795798264342604,13248208559457512838,16726722613532267619,3237046030205777287,118598850030477184,417293367088059371,11040275368803075234,9335529624108995914,4339686435499223049,11396507905357195127,18338078255286690311,4275408028822977899,8854273910161848184,3888313692926764445,14310718155046526210,12381056693809926851,9286031893160943374,13045729865131952364,2941226740855114449,973797097801988169,1286070944949629992,6970523765130552277,927632406186135750,7198464952019642453,9457779787847242855,8658826390837035891],"proof":[[11897892531376565179,3634792591940219629,16081444716236444255,14565666631364832088],[12354973717232279410,8465696851968322231,10963537574461437714,9126030798941592011],[10735004598074638907,2239036033055106350,17598804936823702810,12850954252966166144],[11003383781694084654,4544256267085035416,8124590256839030681,8250323763689599492],[12178526154533611670,6081154153435582946,15121693787815133981,3421155926116410289],[15662104472732476136,9516732610596010587,9211126814600606253,12165897509428739391],[4337176306629000431,10347284930935603981,5011879436538854602,16129153139508755815],[8553197883412112864,7966699687616456373,7539883244885613152,7407237371709000024],[7648960433119694014,7075084356833076598,3108288644544196828,17511759294807500072],[12126192309167071029,12358273931015556467,2429513458259318902,5861015960934894103],[15381742028723402892,3402225182062511116,628468795528937818,14499411108973546409],[5042634484934762679,2893866692812539302,17066004051914474874,14419261090189003879],[14393581389849931505,17962259038859093025,16985012039963490865,5507950102793531328],[2111500825086826249,2983234331546904250,2229872821799882262,14619576935581665746],[2534013508880660664,4390893983114200810,1819666122795611315,8761907613634381222],[7646490553739686282,18029096139897674319,6731970851428661196,17512975805660313014],[9665480788566780535,15441174219972231479,18344208163066031937,3462579523809054127]]},"quotient_query":{"leaf_elements":[11267854405494898057,13493511380202799467,1453302228925467556,1638364965354032355,11230376314869590666,43426953770178190,9877905938311280131,3012252918700834388,1479662866965317039,10978686823335120294,17178431816644738324,10564229565281877194,1722697407114336378,17401626367562739630,5286833452647506841,3888157178206321417],"proof":[[2099810033916550904,8800657322549343403,2991387514248829361,15967335517879628285],[15199910905051789765,17678819955347584234,8743906533305103375,5644550811707812731],[9115912697859881312,348063014482172007,5851945907816650334,6177154724884229819],[2871700163816048069,14419393272885231676,11658055196338930587,12829532281897134081],[18296010672518784639,12596478805077376244,14950348454569251187,16145217423310218359],[3019879570599311216,5367777417118762148,4918270176580853783,132902009576585681],[8229411224015330207,3726103914230906948,13634456734458612591,15022742606325759477],[8548014953572307876,15930036846574129980,9596911119515873261,2756187544788643603],[5155952211464922104,8556270514671384131,7076157465327216081,13816642791874494288],[18435005959872202293,5668435469448694652,9074832687653745579,9230549394986377179],[17746321864821111193,3515769712823768862,16649566378456328672,6340871538384864707],[17937903170322500847,7700802109264123553,13524684745912343925,3340301604875580883],[13457582491622521763,1096954808311043652,1794319165791597391,306930781434544328],[17285199409592457406,2758310416695366808,8237193976256550627,6093240168989564798],[14853222784245912369,16410199900208906551,17141817584029801940,1083810476721892822],[15013675915085111688,2842710086883176632,1159327259408318063,649441773392074836],[7272481940847367093,12648501695579666994,5565709819533877885,8039129685255867198]]},"setup_query":{"leaf_elements":[2652769108821043925,17320751438480708126,17318407823443724344,15725746522722326429,8200186748103657313,3622843446533599093,12093360048839596385,8274714163522538916,12017622070060179409,14858023251751042750,11493727507621887552,3938064003691421058,15622857811531214483,8304798276373150064,706607466339649372,905977447152933649,17786834890605189101,61547515277366301,5133090513396008834,16380914710023764833,5658936522711040767,17116753409703318932,498057067523391708,1241819289626306327,15245476405949568172,15027560213191392109,12808358597209696131,7821926755311632855,18243489522520058264,10873050002836321376,3655532932171686411,17217353382653710700,11627985119021783466,8814994204997775182,16786009728110885331,2915939896735401872,14103035262660006323,4058098666831513749,11079150291102290426,2526155388524874277,1729656962964650279,3652199610285991631,14741507780735955179,10026942893202772267,5626737730630134293,15427673688985198201,6980170982267059647,15057931514181332786,1858332033869910989,16361346181752289329,18265192149287864412,14100635121766644192,5090547728160098716,15087556653523908401,10864857295213105534,17588461801799093542,15549990516065307144,575120886379344869,318656793653835483,17606586633361232399,13132110047566836855,2869847155884377992,15998053636018714633,5426608794410842245,14295436305432105017,17755857256011489827,10370937738599682386,10365958151761582612,4891197215643174523,11899139854520598082,1014721550766096450,13510352313209535441,10128128339072124582,1464316193267963187,12388788404980924306,479491293526149705,18042508286976244255,8746060078178934988,12243940969049510263,17339419775643600393,13846498905160235335,10683432592696987867,3958683886392465656,10471663723088655843,2346048645040960297,7542571529075560751,16216540175448086677,17325062765733391768,12978493154845698810,7292404258021151388,5123821666859179302,7287219937097165433,4619765980461398633,6245113241647687581,18120543109001196714,2639207019740800629,13829885995377745255,17854299740077808180,9064063631152126785,2014327511580695488,4354676163549881366,12684154959159900591,1807361846711035153,8781918116170965560,18001751594666985898,12534443606780053593,11218375072428465927,8403893705536578160,13223927808208924470,3403256940011301332,16380539442177181663,88749116541286777,7749648719936321130,5987440057128599987,12965344125107703493,17057285647237810486,12037212235408965734,1007113425581250162,13796236230723496601,13617542204077222455,2020205829760519740,9910467392286190071,15270731880230158223,14151794548692958132,3162442251796389285,12958808429150127431,2864812273740520734,13631359498731603770,12839741900153078329,17484684327952409477,16219105917655686584,14209309154338470708,17676622689161114573,9833424455341914194,16049398881036123203,16686698964500838532,7249054689679478257,3314314264725286740,10723872096949749293,8024093910959637716,3636628748350612677,4018883930842198655,3348975979186809382,6258020187750607572,2258063457405176991,17319894499236272925,17161468683684188138,5314588084480617021,17591324806562047948,9391196889351408028,2995636221215493088,5657695495540208308,11187421580591672052,6283269804711255648,12062344288555071646,14448075245041888042],"proof":[[1301982528055993198,7840630128499952922,2483869434830007983,11901566985622504595],[1004925594850811743,13814706941454438102,10854510908162435452,7230943584321944679],[9442758760041106790,10814455139742984384,5847636828779960737,4645844337630831095],[14345546658957069063,10209759847637463054,16088899884108226158,12813879418285519217],[17112429222086614864,7002050390127902039,12089438960048672016,11778044861283119376],[17182409096880734687,1070021254445882465,3717890830033033461,15019535596692830477],[3499450190705853745,11247765038748738432,7010071576040079575,2244750127006650185],[17021920782927813832,8942538953569724211,16261416576717885440,16675539267656282435],[5163932972041757457,18141445431625106864,1128427863697650146,17919322582966792029],[10105648151221163253,11605520092883957610,4673509233968694340,16927527064781567054],[11011686696598558475,251600076049196662,1633339074090832544,1583904099045571471],[10094679410073046269,4569438291536956087,8209124707705427145,4393808043568546015],[8934957188677338509,18169224408802927486,10778216288641272636,3150940845343546348],[5481882698971702965,9429405813677119984,12373528057427837688,16339504801477580697],[2778855892220175863,5388834393739426372,12471499031309919579,12654310588233897770],[4624068110822808250,4839714791712233337,7066342103347822231,2975375521514554411],[7509741136347436482,3376409090404699080,7106851404074101484,15631598259633138714]]},"fri_queries":[{"leaf_elements":[6561334442333290745,5629785858873792138,11462406519752585482,3919968612685965421,14541998509747225755,15079531882168782452,2117776104646638468,768898890509464320,3817400336694563465,2730955586743516413,16165277824324266605,11621226384432985023,11852429736415000666,4528827843140040895,6568318467818163280,9798424349275694209],"proof":[[2440386485447650112,3096477717061358748,14496077004252324421,17307132483859542465],[6762689032308605863,16461714550449828080,16230145751323718238,12314665895571709582],[15547583352068700083,13631368926203963866,1046972286807126665,1311592251503046372],[2781653899605776571,3674096377815493440,8551986403618915502,1362832010545288729],[18087654266424144106,1997415033479398718,17575087431715487426,4501642258705695934],[6202351507090020236,15842785303862217155,14771311767673211913,15232375906888967937],[17947713317569909237,9070343484603454121,8155199418860939901,13866750635096229875],[8855227801886821210,9108375030029535276,5657598002590242880,17252062559031684977],[4141968026553409913,5564092606461822368,8745593622017803084,4316938809314037263],[7327188530847363778,4102407566460804427,1054987757420467456,6492219529146472815],[8084442009836266508,6207473532914909068,17403328363939497717,1864263349879798507],[15010000374226804596,15833705053849325719,12285249782077649055,12385220874491185446],[15662665379730259046,17641414915734853081,15470380340658135082,862978176182788628],[8305776603362009226,1749975925679637043,12013609855588987408,14181483331819815011]]},{"leaf_elements":[12424725187644873962,17684670143996230664,7085179117516792293,7921463492270171886,1628899993767651666,6672914600935296312,2668638871695434696,5392567432025041097,12339018735222660408,14102988999234077791,18355597001805883920,13015163755774290422,16353847637215985623,16061082360002807463,2811502201154830733,8801621817751132400],"proof":[[6486544307863507438,5593082272153425401,7092606152541536821,3208138813481270592],[12071209963586330645,8215215753492458153,446013299663461684,2816983134670681242],[13595333709001718128,5968031955947958795,568638126234184847,2013910219658340447],[6448635016658666628,15334974680687790548,9040352674975069322,15394199191825276473],[18366703750380224972,9137073519255044169,14140465716885585146,1572229265230621287],[14476967034540072936,18144625678554734116,11065664353966621309,3849395059252234220],[8012553520489721916,8721911134275936545,4610631596733989990,423370177788788053],[5994530341222767645,9939949274562545854,16239304287256498903,17906841975666837810],[758007960593770914,13785541215754450779,8018208474724663070,9288521653921426207],[6558311215278925279,15840445465967687222,7772766605136687382,15972645483194393560],[9089877299035286039,13211086284025128974,7103523635707635640,6143338230424736938]]},{"leaf_elements":[15056751157781251313,16908774522522736426,7508682051807281376,2549622036801723581,15304814962799157113,16221641313930848549,12776071171321987005,15285783109940484257,721794475760752042,1767203254144694152,17420062690715629028,92505493132757467,8146192149527278600,17257335680567538251,4682635131554270122,9072352267519959619],"proof":[[15931591451899131028,2848765484549863861,10307383079424528079,9221420617331764993],[911692119221152495,7240673798306424632,12271985000212629658,16744901520234193273],[15603267433509388572,8510443870349387086,17860904983854270130,18433516411396615857],[12219292277469065907,8308321877076151782,17193918982362317504,6001894734906060567],[4569229391948749147,9264270729747525889,10146356862857636906,9737716341652315332],[16850121369624651589,15493576925611962527,2159695954185854510,7345827141619488390],[11777973429637587896,2196711819418615457,6737532320013191690,3017665391597334600],[1523028420938813456,8383364562886835624,128497755588736195,17828178017860490490]]},{"leaf_elements":[16187081171866802844,11263564098651815480,12883308121129154110,8657987168253325102,12672666976306478214,7234295855891976691,4741620317183150528,11286475117050093229,13251898703993897151,17133561484860506192,8518486979676529746,11169071959032894341,1214693823439717056,105016283161821899,11144517728725711880,9252277016506905764],"proof":[[12541581298833999481,14400257432377595782,5312807663066934874,16762259780585024787],[12819693733678940276,4901835563159907164,4002611156762758758,15641780577613939150],[473471159832084222,12853875238854799722,3103619453438341861,3824402943842324258],[5022159673865659873,3882161217869360293,12737074131411203235,5268074348042876177],[6261215226436674216,15743080239327813690,1842525900557292747,17693706794580574465]]},{"leaf_elements":[8146988832432016400,4031049489709357359,7908697783540354457,1440221181542630175,10186283415753225149,9860045376790193298,17825662987895089565,11197202384009084836,7717196534648088793,6509681059572037081,9026339780428362777,797494352562912410,4842010430528115743,1984490153396563342,12307213242561184541,8486878505086012483],"proof":[[6054026354341905116,7281874755023425128,8092996408459971936,18161371729260239341],[13176973524804019933,16965119035393196808,5769199517311706096,9495579311777928719]]},{"leaf_elements":[16371276844632437187,5763442631456442294,9612659274689155166,12661874354129793348,4727490084259142759,16024340444489255688,11060965350812909448,11778191179252601154],"proof":[]}]},{"witness_query":{"leaf_elements":[162996810165732114,13452058386632736161,2565933900689481005,8181422892080811642,8566676472648008350,4285308198069707222,1682074279966361422,17732627333394586660,8941827855635239214,7544801525387630020,8395166086635358999,14479132987568440771,12531937863315134230,5381061400062850021,11641325820091713666,2858105155597691861,7339645453783146426,15850289092679787439,9951081846927604149,7341766659021256745,14801824323395850036,1489854684900215002,8336695393893501422,6900239612464327187,779829127733189898,9398148495671870038,16291512394891928541,10174643216688969831,14396446188496177029,11774998032268044682,5680342850777563183,13916812426384938709,11997920850955814999,16646026100444360306,2371271578350583511,8677205989299571802,3345745444224130374,8610035609581984554,17723288590991993611,10672191840068354095,12034838635025856591,12199663452283901759,933095527567066169,10620904270584514846,11330102979333060311,3879513811155015894,4213405608435661259,159149770862932768,11621759335201372402,6373520732789212818,4856646654400813242,11854687404912556247,10746659095852215563,5226987251509085883,3091046334755932910,15650200334469462298,10024574107496815238,1688555213657279406,4294257844921997019,15791150626592227982,12887143866975888395,890996441574185728,8833681118386274692,14993563694933648106,4502801367279897571,3297881726533283171,1232023964428020638,6715046347375087510,6100971084553024236,184422058429614854,14147263824405226252,11319372719364352239,5711847644964797655,1825868070708572703,16737344198954215952,16380137598348363802,6425866596638358092,10378919571161346388,8879448931158310277,10263527490047964934,11811822479194687565,12345262150218884298,8948946089759361855,12128231437979664466,13993589729905723215,4682078469503765896,14763414789836159473,13386497193116480390,12756239184680946293,263972685594205753,12748125151867019623,891217857500876832,1248012455665709982,10095305911126784450,9164134286532780901,2055520584702820525,8160863578052650806,9430651415085816045,11154287782130084642,5106581315010963891,16043518460727524014,2743405024778382352,8417461836830257559,2779046157033796086,2782829044623693716,14316581071882727156,1568622640770069725,13733810108078216416,15003097109766109606,13613190532542680256,8137190542329411490,12732857508904704339,6569000689064921147,15112281159244601309,13464371978444513993,9744859841729612733,641935322141316949,6504525953317309176,13439373873986728813,14794111104499222076,8758053786126011819,16604561482463867264,4567613875459335836,15446910033157487855,216100263515411524,17967813201371502509,7258471791315107018,416533851747118943,2255704247934944275,273887949398473855,11937300014525764223,11294806193461972873,9707457490368254048,2835525378683554832,5394903410825203551,13940776757869134878,1250562559571881295,1411833326714421256,12075601318256441748,13611172240576208452,5461040713153812329,10562984295378838062,6337749988191515204,13517255317659034317],"proof":[[13826303974720637020,5368083978838155544,6450688633308280016,14951371912889846293],[344375951578663062,7783053808042403199,13063743226970528501,17077604882820698247],[4536365916005509656,10811261169754993567,17839879401445782343,16124841565933558538],[5227676614591815823,6330359114094321689,210822361407890213,15643971449464497348],[13404300201740252438,13041873683790868599,6699857658630351887,18410122731443100679],[238948097967364549,309173973582395157,9502952205359015968,15057620089843005086],[302295723619705173,9686125264864211438,17184610269130230756,2590209964379827726],[14454497503585791097,13646018060089512244,6918498684315437171,1639762406521167133],[8623354094430929876,17292915724877273574,10979617936647418176,18271163162664141985],[2235800881189777665,12387210955092215910,4775665406695454529,3483335930417653482],[17208713169295798124,17113813571434356747,12163520268102123859,765224945228477721],[1944917204745638900,16957113833431272825,3955885919869271400,16098883445644769558],[7817062961323572541,6342558196852159986,16032250096144956420,17787833890817030677],[5525131382242011560,13656625897954370207,7401150232560812161,840833934115724567],[12930917157411894529,5584788079337312893,5173145933195817647,14947976524614303626],[6112895983571799427,4240048187258497468,16493330722301361592,3110541017215186877],[3917596628354293155,5216102744746703452,567594964081413321,3215432225810112365]]},"stage_2_query":{"leaf_elements":[6947877989279442484,8497739479184047715,328190983140332793,9755910278899353119,9578091178428983680,6506605701236137417,5563515725387208505,1323736096582189457,7767357131278810994,3202450339021636498,432000950525509486,18082882936414263546,12934960306346947455,6571952505110522903,5757274177346020267,7971263660702122888,14854201356752442301,4494490375076974731,14370266761046917925,14286200906240682410,12123026100736094633,3169011679607775727,5827103764835162908,1182118930301975668,16907085238464287252,16274331150513992408,11005106823256206556,137821720112493323,189242526769349425,11992711510550421238,2875109658458703954,1973937369945390244,15669610717907515646,9982797744922780639,10449301410768105658,5798910766937166163,4357758355427381760,16461826078494184858,15668255958331856783,7978194798524902186,6301014854901511998,11978508778620802948,14230333551721969048,7657124131524231772,6079277493731909528,3400799916803019169],"proof":[[1850119536306568832,11863325681375648269,14519215525108236705,325413740008622627],[15475289555882150870,14975025516804849525,11762916956061062150,5503694910610745059],[8942500468533502316,1665355485952899258,15239121073643810383,16955360653188047956],[10466057309418371608,15034924161993359866,15906869095391949805,118911847340749107],[17918552193704503069,6379125710711564506,11172093077204755740,12955440443736881853],[2625935524126553311,5931261354373341048,10694533729186716520,16685530562626175169],[10940082710658168147,2820040663781479269,7362676538467196954,288480229645175406],[14491712741059512902,15254892773194192234,3834699389182558229,8972253062449742010],[551985275853086380,17024439259205591188,6140349720526997137,4679051900899919515],[1353368401227519982,10696870289722542334,13443312944856926593,8540941836067721401],[11453549598473507446,14003943735992439910,13264423984471296295,10205424663801587350],[10368739899520073556,16262020048915944610,12587887875891879982,2937125788767597281],[6647276280205988381,6018531737902395607,3890625351607267429,2466606769911670272],[1590430572751467558,17038966990732163694,7553596611376978464,10679878667881400022],[10545184918225245226,11508571480398981013,16280944745057885877,7346629544702177230],[815400835381777564,10965329387145003484,17785693756176053637,17120317219553773140],[2790166171694431987,8776512649030213805,14001141908799450988,12523224147355573140]]},"quotient_query":{"leaf_elements":[7107996829732085505,4305951592781999758,2916998207376974504,17775647225049492226,14253862401523223157,11812958870341619079,5220436326076901662,18264532399042080608,5258524882514382181,566944115873752084,17265615662153864009,7626854552976411313,11325474988735338851,4045732558392250750,3535008953854959788,8590309274946620128],"proof":[[2884355832551904558,7108895812172364185,14026891324528577785,15948743959563067847],[15443571723956676303,15049458818676519185,8296655198320878414,16718922656552456979],[8710764261261642963,8364590331140138617,8225456852900042754,2961551443812948281],[3460640942937696112,6661859068496867102,17095068467395735210,15005920839842492719],[4118389650123693467,4780416424590262771,14933948728019754413,9781006139979649715],[18425787453230595080,958253203811811226,1627366285034291372,18111301265380730773],[1984314338185569041,16685407790604133643,6124100612251471809,3796167233178858425],[13950556948606802969,1400699542118430187,11253767371015438446,12945858836069244026],[13578027280656399448,1116498754452314992,8698272588038532064,16055772531593709178],[14345973743338665278,15812022218693989136,1552493449249389588,251266866303859560],[11385901120549685173,11781550395756145939,7196801201669003787,5322370569453566895],[7610954297233598136,2929168918375766522,15608693667607408269,11039494247616740113],[7185631344594915271,16406168622624218368,15565709243365676931,12425033669829162376],[3310373014230036922,12671713993406008607,7160744654619467430,17193604848929565859],[6196730141671624366,2432890396104110274,15463496787475619772,15556657960144150988],[14881425184387053810,17184713853013655860,11417084575215904291,2268517284729831118],[14827574826222641753,2016236490897640195,15541113978067643161,9328589100278504453]]},"setup_query":{"leaf_elements":[15225129987154123128,16353096024739631836,12804474316450739455,16732178018316197890,17526849204188868297,9821364578381792708,4018286050663161047,13312621650910567750,14103715500049522836,16784260754992883407,1492658415280676216,6055373692592149070,6108091744987024076,18286536900635282543,1463155585540407749,6593498318613868758,10036625003427125646,13510696034894909324,5658931600335356027,16816366955439272774,2526769037923967370,17686176734810550382,14822520274550896492,6977479176816388828,8090761451976332930,17007418552378288490,4379081638324828077,15916413900466393697,15281308885029114314,14867981131701069588,4569642914217321787,1010458980768073183,5198969732313600187,4107065782125610509,2781533146377040638,8435951242138999200,7572176091671989176,12891431787511408865,6653678819220112382,17730063552581569812,16041929193304872920,9830798305188828443,859456672291808263,16882868880880913885,16631139618886804071,13442910750220962902,1720180506756248925,16875880620124869435,8446568075279997824,1728717744773370121,5778626308898967539,14897821748675562507,5072994419262683001,10591376938764572212,10384707576196030741,1435431394844834314,8441790000443459499,12266394650909626120,11030352805741299972,12537965926133207175,8855332251235065989,7890405048922932017,10772039418241115480,2366891407225374106,5958056314293421984,11570621091935078960,10090563868332017641,12588243254732319778,18238717725809476692,15470550176893019679,1639533250952100860,17902307556156263091,11081285424966762634,17838660505899778300,3103752850281018517,7469088545318222621,13347067222190707687,15418600245842817223,6804484752090917917,7112164526299650095,7703171395595277584,5055078736645090489,12561540413777312937,14632463661251204648,9803190638836676079,7427443277278728502,16171692186334478708,14292383532700135337,14436717299627938033,7278994837688024105,17280973783856200541,5229499799130013548,6163266353112542302,3621442912137047862,1978326507571243430,86879006485757175,17066267740650421561,17693963800696078234,9929447072759822453,15493322363073950269,3810861289106005874,13059176493698452200,10557617368999849329,1048381412793964974,4542986219631906634,8093689896662961549,4780578775699614332,5552658267617913095,10588168398254515479,17676599411668016867,9634970413754745538,15625503638958814766,7117373463149674075,16910844920352139642,16716886162350873107,10020480772482751985,9209894882893366173,11255759496933567302,5368615137733037425,5040792450983824761,13904525480069276096,105001313353711305,1136965842390893247,11839069268223707227,559273050980353474,2604973046781477935,5558455198926700660,1087065126286625744,17312564322536985893,18109776141502153973,6731269118299007081,3910508387209643367,8404944738149796953,6228980838624142877,10105834473544013398,10628417448854093737,8824330144996609602,5533393789096825873,9955071649112162006,8064582523573699332,11517562237920877835,10738229250191763201,17987360340162445644,5333917128881564746,5638093341262447155,7006806731434543859,1503951641940350826,16477866037596772890,7569864841747454217,12386283841425224391,4374725901703738484,13920439571820987168,16837468005912896995,8144580919426146432,15766966377726615904,6332823799957030668],"proof":[[14441893786829757584,4939104258058673444,6649685936531075939,16409691327952650166],[11393683806102622398,18304447383582074594,18438905658008175072,10812810666033446382],[15019424855287756909,13346805944112338169,16282062958768202418,6197785794077513782],[8629850404768632002,6012776366654431388,16721882994939147177,968692423553999919],[6770716856728619414,6986029253415539878,11977191232842459243,13716002489750719241],[967399396557783635,8283043152351917305,171725976909458958,1290382223354493339],[12094592327071116881,11921793084760983108,11793295391564100110,3050959041566796802],[11033246652920352919,12663605823770259245,8602307028398775445,9540211093410754519],[15305854465197047093,18312062770143107564,15908973381333527483,14043804241716505612],[6616082957407096288,15462193376404106540,11761562460343937498,11027647237551421635],[2202737822026416727,8529391987943442603,10655888094085579917,11716952580127364870],[1278631741144591613,9514373279256214642,3578678288011731031,13650859385966821668],[1663612679804380581,4703453038414876103,620408521116312014,4186585023712899427],[9863258440644397683,15620581748845396363,15126912528729623962,6615398419202767899],[14101929740269108858,4531165545992840162,9016966929385774269,2516603409779901050],[1833644971259862079,12190373408006751623,18315229541642544120,735754289676257334],[4934888255329451731,1299074057986496668,1571136916485237263,15408557579809708270]]},"fri_queries":[{"leaf_elements":[461746494114995965,221681366555476978,4416090983163616487,10021476493340865743,4973444935140130797,12385417949582897131,5689309363633532871,8573145755442454288,13523066968570962478,8449506543604250991,18399582997960464046,6249466997995233217,5493764574798948674,4635553283028031958,2853498878483671223,9233578974489979418],"proof":[[17117323034982074412,10478616753501179085,16673488888003594297,11970652064284058284],[17200113174979360393,13723642779159467078,14907126142182493456,7863378565875657827],[11963834849164979341,7259939345099769649,15454309802859238460,16360062083001407272],[8641981006501828355,17820700736133285817,16318333466631146332,11002807741644974335],[4020807894348627262,17845959090066678838,18314714350904206340,17235278780577445826],[1950953444091678297,3179797228387646980,14849840856595907480,7936616882139698433],[9630408447202637755,6484589690398989687,6700529755004139799,17792146846942463510],[16694866571533975865,12708402410028479399,5416316328757130866,71388496161149743],[12508199716444306516,12370782785507811479,13261534002224954169,15945329734027800964],[9791987552225688387,13513724777750824229,9741328542406963511,11819978626784652462],[9264839476621212491,2639859479979438401,15400071820496236515,16467909526924852748],[6643562897288041607,16245562208327552285,10525507878211808860,3198543694160485943],[8297876022787439987,5765429358297417092,6969424009045859554,11505474989538549772],[641015916041718214,5697532741910532451,13423081019210976144,13295319889382710901]]},{"leaf_elements":[6904059144368132231,4013535079777209686,16142797022418961101,11388701194479925591,18272589072644768966,17038277264021282829,7388021650061829301,8901785482922436229,14805900986551087280,2293381895944899299,1743183741070691831,2530406689363687637,1670692328113211473,1742907312226906984,2386208642256034394,9071990289515744571],"proof":[[8532480164113671068,3918737611339634917,5879247831307624490,3343485029128691369],[11953778754761145828,6743847101771539463,7277199548225463796,2339318811621764961],[9168467722266694599,995044618681258257,4962536020927942885,8705655316163880952],[6952831365986564002,13005026038415208240,9842963948826515157,9577013952698778756],[11913926838049605665,14124312103484708308,16073708112527848609,16811257084794667581],[16335212529300616860,1713781243051858748,14566615060869675142,7240896704737472132],[10133312225206815407,3117085187269598290,11756931240034474500,15785737163125873961],[17928804320165416181,1541150392102041288,8485553717377709294,9432800344547553061],[11190247424737578103,18067699002572432012,6907709368532349934,4146195336745577454],[9157312705825459678,1109992508509457527,8694797752288670585,5363340447168050883],[13964360843438099738,5308142120266251153,15132423796157510014,11027328105767835661]]},{"leaf_elements":[5436631475707718096,5741683703888860196,2088103695704682391,7344720278883153929,17851843032840268866,7043571357456212146,905033432608927587,18289393261990005119,17142716031415867156,13111123542123709630,1838481566342599458,13876342155242087466,11485118300129206071,6423243640585299503,7342930012680212959,3430146384817650820],"proof":[[920847005075830928,14730921658199469527,7067818530113554892,12620051856424999611],[6687133903389110685,4896733765816856537,16381532140122467140,6903346279229242445],[9969962182373030918,2342937407124551990,15525329976007523779,12921010312886691777],[1322448092591695066,12088680995336910275,781530633137377698,16070821913291493989],[10208488047773417551,1075860379670750720,18199675155860251044,6690838435154826404],[16141181139632923106,5982653358795817327,10299402092765800255,4628533391384550172],[11116643235427525610,14518903188011855710,15245943531208690321,5486400384080011241],[12257679492692059374,18190169789673338868,5420267801344425857,6718007291386775040]]},{"leaf_elements":[15437908806593523962,6355975406100665224,1331645535720368843,2024773293279594279,315141318716231135,5938127786946046201,10110755675301391457,2512182382605658631,15186692834594728572,11898277183324100998,8194647364354593828,2887850066919760934,7708666622181818639,18325633296982174590,17475113659221680683,4255787410663518361],"proof":[[9183913016777057377,187943500426012245,7291864318649055456,2407165935023302679],[14598764822858044113,16847730331554281120,10312022800483273388,16280152262159524473],[3813880757158590155,7811563653661705682,4916015429192880519,10454947779716853558],[12065489398050746200,929195210530829821,15415105721406184926,3929055976248099660],[12203878495608607889,2768485086897537620,12912318947888615320,7822068476628361097]]},{"leaf_elements":[7392993070805491309,11552045744772046427,12496133539668439015,3003604817670474346,14135850980729636528,9388815079706249576,5958986795123143048,13826572263215382441,11512753704284846525,145982144781285033,3583019029112201192,13479869214696378003,1795656544638975181,11892787737611374688,4571898229303955360,12823271620420939304],"proof":[[6314543590119612951,16919554272777727026,768741617701059578,18038188886235418151],[7490477249103747300,14890821926391065169,12528894470063621292,17457008754437276116]]},{"leaf_elements":[10666499788113613538,12946354179588810142,2978942579100575765,17219500348011935376,18432379563349423049,17978726315520234670,91014601379555257,582079298344061305],"proof":[]}]},{"witness_query":{"leaf_elements":[5484669594037719969,9762122327625403839,3254912646666013108,2313096267300242480,144044462165673050,1540277873231267479,17119345203316735321,3591888957323940579,6401313998771847843,17550872125322313785,2425659329355673977,10250966077626802529,13320299732857082251,1711489079103966390,4370408629833293588,12464470573318029017,11495287063743981009,10824297195736008025,12647044019453820712,3812998455858279780,1700656388067293359,17759177340210449751,15601006167515310589,18383970137967242739,1962214927984891970,17724886566003745044,285400757561634251,6205403520359039300,4372634428926204794,6263183284407811968,7526933270134628395,3545119563413602501,1108187370847954448,500043843168480659,8447775039280806372,467766441910802139,5893191255618177423,13292166996908389962,10528257324611921993,10344318344138067767,17577779949144904317,14083855943519933122,8496456535617796657,708856997516538649,18185607646849343468,16017106988631051826,14821794318575316130,17052505578552455417,6570410496619420631,15500928670574786404,12287590021784658719,15827880841394959925,9892716034946732929,1363895575380293438,4300634714504300617,10727827065068704571,7118187051121335849,18390505779067684155,16707254112652562332,13975473949444091809,11369002401811611886,5014113887444892609,4213133856830632715,14285965632372355997,4826400067814283851,10391695425721579587,3507267705157920491,5456075129904229015,12349715153674134360,12438758100608619582,3949180512619623081,2195462870928893468,16200084146307491534,11105278240250018027,17053700811321731,6281686074644814409,13026220832164315055,6825882082565320351,1537780578483013035,12932253790501098702,13736833996326381389,15151014913876116186,193497116899004211,16172258722043133571,2494419360808617419,16179346816364021970,1863984306942287045,6163379257775871879,9262943081495189098,8248229750038185624,16043083436350573718,5654257091506825624,15013492544569199297,17179674865462993456,10847112868009782551,2357862898328398047,709345190514597750,7175631778625035304,7107303804463955942,17819881025910952465,6511454899649366913,12768848594121031749,5246651774967901018,16835015314048475452,13333138292577082758,7910979151149018115,5941536705995574303,2944901839623939011,16390634352366085583,2670372803905699095,2656327309206425059,11974494316483228496,15504694827437478212,2386621592416368657,9039939998451277517,8866377264298573433,14992578308561760867,12278100476632172582,13874053689559452722,14781102409745229968,16580779694553233895,15692875270638152659,18050893152361385985,8445249143226480411,12508781389079069553,14169427241467491404,16943113471374570940,10001471008421346840,1473504201619815383,756997177400330731,16331429803370292540,16124951072854304511,4419761013774795912,8790128518286433711,1708220586253435214,10459770972521077353,15475333167954061935,10271707985673004556,14205270535591010445,11617565477386657106,1273225360008006080,9532263276920172482,2022033649341657680,18019491012346677022],"proof":[[10496783740837506832,17771878562273463653,7330859018813982855,284189134989935986],[830176826853833011,5667210157909725686,6526550169041548942,7357153346330785268],[13723619286491655821,2584674414703076609,17175247237271929627,10578666923560371711],[13898721494690994556,10686028351901376678,14843926108910066626,9426039686150885983],[6608740211237382140,14785048703114450452,16437358501940290606,2492293144267215852],[18375278186264933825,1839070518186232940,5305979127290195731,14372584783911459173],[13450140577868190705,6591438097057839482,2864785810754032608,14452938293970569902],[15897785845920984544,4348664322630956120,14764354941798523459,13828435266629509585],[16533065588840454959,3674965623594844058,18180556407286453016,11481956545781603965],[2746353642569742326,14747824587469449638,17793131366634465289,6277728461909882041],[2101223692657671570,2677759580708396601,17371905796911384900,11214733512046747407],[1836167282121244425,4875954967567023140,14211191905440358037,9793379964617639999],[1354270901506171532,16531576969354654624,11530540604237919118,2392225738246132694],[10876236623291074629,17704425983208254795,7023845394027235875,714250843636187220],[7811854712348774083,4229127313957557093,7175873490261613800,7185565740634223877],[5842862372493840362,4419987147756751034,5274089670470245935,6900253945413329044],[657464003103820608,18051834357822608389,9775036011758413450,6995553827537371936]]},"stage_2_query":{"leaf_elements":[7906540743267763302,14917254865892813969,8665363589966753610,7836473875559553512,8708142026488738728,13984344379137567116,7436403781809394511,11346586464765490104,18336566602951683741,12975003291876610659,8190997551192026832,8736444249501268321,5195495870673178332,11774547455669068444,6715275062783761238,15430677694199955389,1051759979740638618,5550807805357370311,3424978957659453605,3529494159905284746,10349393861804159244,14030487839322496259,3413626619875582179,5392135445857032738,9939160648559995582,6560206783222292681,7924752000647338414,15584854707934869026,13884541225833211511,6333269768219100180,3643927685072268912,11860644991764654943,5755455400466931342,17241654687135732610,13527196492877874683,2720366761514399737,15418912031589771645,14295477398787283329,7853117999275131996,11621251438951750791,18365310663436736077,9636181565295618227,5860213455967242593,3121230095692852369,16204167457148390844,6429731607548418568],"proof":[[4533256551879707138,4873594252028229087,12538070520640329392,15655237826852773848],[2574908655767988262,15701009680538716408,12588057893401549003,5031062773905288340],[9319525789775556764,3745310387825472791,17464620954346599714,8907502178682461894],[9147665923761416351,14557299259943017595,11453544354950833921,8749278372216221496],[10490051779741407445,6113346570689250389,18230762952793392113,6403067120165201982],[10847816853146405110,7407182745475830204,10305126545288484323,13702713479822808210],[1157571190882646353,1750312417612408391,13964383731105789745,2437111250737199127],[13816014475660028152,10387274571287640585,6597584300895685851,691866061513656306],[1466378945105253512,8693571977077431070,18307495945876653044,11837547945010479761],[10220624772627778951,10865265806861741174,10286318088393620,9383478240033982240],[6461965674194037973,9766438684693841265,2197037544513026475,8738579849696316556],[9890444910292408160,5848689431204735935,2456883576289425153,895505073237623852],[6415920278592257562,17053307762703629795,17643467402346881692,7639295107298538221],[16176827556983520330,12537514931516769396,5525235868169588295,1773989508763688013],[17240730004711609813,1451398228495558980,2003197422114068600,8787310142669983353],[11029074888953688084,8461350975820626340,919935607430691210,11334059599028770023],[12706731794626747017,11719674778025120124,5964403704915957363,9524754660533535982]]},"quotient_query":{"leaf_elements":[11176108114967792955,15599034160450292754,8095762370288693387,6110847102236260915,2159914656476315088,8506973408920299419,17023969974230880064,10824863115903502871,54066584363469730,11616026265956577541,17649991128702905084,4723739406192577470,8384988499028567419,10777793167082773114,16409948658039898779,12710074568303763741],"proof":[[2715873746458774475,2008292589511664161,14721944592662477117,12178516212708889350],[10664571158321732122,14931711773702056318,12515373586984009399,10780423986014761790],[15979948230325516664,194094027549388596,4304091767984543218,4917066212863286946],[16174616359825305125,11019161202882986666,7303058666552232810,13831817438230164302],[17893403990255762766,9561768902138972814,5015111612363977224,2175503144199940014],[13140221191485269888,4684685136171947724,10693309215290436113,4757897140784084405],[1734193546651117637,6509329516815584801,7424921472639509905,17525459320226013690],[1001531490916329263,5666100688198296834,6114954799851154725,16167053182609030231],[6715381787925378005,2738968797650397579,10823178765668446098,9157475146287322123],[10138759219914662646,321911332799875980,13301874009576326805,17537963415256438380],[12712865786863044033,11485106435945066817,6479953605101439777,13602534503249517332],[4548341097923231756,16130093609926729444,7563804592411649072,8664479820751444290],[14602174838128768649,12947191141309054440,3441853929669167736,18236526275305101135],[5563919703633045803,1907064623580344684,1875148101085110690,3823329069122183174],[16851658058688507142,5837738220107537123,4340964641389879440,17525487054740518100],[7677310295194187998,4478398034771600907,2103078363966798017,16048691372118785725],[3292643728846219931,7130372862270552011,2316465473473904261,15497022000498555190]]},"setup_query":{"leaf_elements":[17377101099432573426,6702098008113429379,15443352434941799234,7919263538456199307,7734476252195394911,7701531899644436158,2848702291395667929,434798336297451896,970607412994323595,5548796103440337266,11013116251096025185,10340702473919675827,6260373178310122424,3058495086224174271,16896556197895050287,5870305335125362066,7192291590244947859,3775759289939385504,4430498969256603928,5503570209824747343,11770325368395584334,16334660014232416101,1509606745392621294,1364633355237329032,1002923476404596683,3443742258985010075,12270223160026508254,7106596673469238823,2807480941455651773,1320061468100825157,1012133757453259034,5844038484446762640,17006553434894675648,8359233700601749142,1342180095263361505,14384786264847658489,2332295734865722180,15681036113769783847,12163227838214992743,12737632048842721961,4330985616765113283,3581707893781964600,12737608532851364358,13396984590203381184,14830250895123176745,3140246886834559956,16077401637118035609,3785436413477338507,16587342864575769122,13099316267477899511,14978887712569862112,13278107468880170960,9849996212841710022,9946632157593047407,5800564402029746490,4926024591313115669,13508112049414581277,4631619373491547680,7662732436455737776,1195950598100228799,15144310966451387995,6418969207742473201,9352916012776528205,7845478167717495757,13422678039389905842,15447803032304248070,2447467414591416955,9968724047130826160,1782756263155508668,5154328269300658134,5012963082855407924,7461069044861878313,3617689929038636835,10265923892431940576,8427696168004380606,3503070060661702008,14587814552241551207,5222216356085529897,1975314630230781899,6077388008944476352,17422643894141920427,7535752827991936305,15151635362401949484,7487176082739321977,1740577985542030194,6608792633527152346,5576466613480189109,9225649666314521424,2353216184971894070,12058638589041114048,9118972417579315463,10573613167787970376,16311743104171464355,4224538575556523491,4926418099774030753,5960116938654691520,7007666328140078115,12150430381458460540,7976763056770700721,14523470446106657760,11345868233278720,2195698372352204543,10082897854242963846,11716503563474511523,2523087776079771202,13880039359363453454,16203660201912153757,10254546128586622787,14882766323257039514,17654656256361674253,13864150436176237555,8818752647395973300,8137883667123038269,7966201736779124339,1323147647355472224,9007135391775435602,14786595556278941709,5203055955733649859,14729757209257807835,8567645152028499010,8655504405439589371,7060452546816083564,17099610586304088619,13270737939696594817,17725269688999163962,7626290520505889325,477574751679268735,12469466928312917771,13202349770636906228,6297060079157712330,813293707068118953,3980957831293679744,9676013410400727506,17713322014822735983,11654948459900918004,16084719719747706517,2704921827456793566,15276505760776475991,12759060894932778571,15071647506864798116,17380704855795821956,16536382062328953453,9391996843914144321,6200728641548116882,9308752180215591246,11023784319583794573,639221730652943076,16789544216086463037,17949233915059956366,5584599002581600161,18037036850240240123,5904648493047638969,12272541987155477112,1310390569536145273,4918055164877446965,5798003558103629637],"proof":[[15283722054972105022,3526778832791146424,3022293689361969116,5062720646749192209],[4668953065402356131,8861920209572499108,6494562306578106634,16170575945696132681],[7039510368432861593,15952046471741250555,4259695425148858998,12689388904386128010],[1318641385739636844,5965443888898262086,11942256081797690740,10747517198085027219],[16146898314822909247,12076929455858927623,14906253165149842512,17386188115277748496],[11305107276135328577,11302336277512958304,16397108044521353047,5836276547325740804],[2934276727720213629,16273340027344608036,14662715081658473723,11942475104202376743],[8796106276968645371,15381392813534537654,12845015927874577689,2533879013762408754],[12105977716219578028,4502604962959217171,13671043806848164254,9078086432189173722],[15314015045273116251,16915761032472350811,11300847179377429858,7705210528166836879],[6092670464150394242,4615748622029987890,12518258810626401895,1936000712315184172],[5461825192585890858,12483098642149599722,16474680203889198190,16441603783818402948],[10600990542492004087,13241669805357536810,2159210779770314112,11215913608676053870],[3301172663035200123,9921955188221116452,9897416639368958165,11364721785998609615],[10276911144259452837,3540202624203899377,12956242649464148528,3606563826822569142],[15813802719490999839,4135174724138796582,5535223636549765342,12480207431359131668],[16679192678542896906,14747097410254745119,16237487296940217112,972287692697978548]]},"fri_queries":[{"leaf_elements":[12806314307780826578,15646706625193582810,8776061099371052280,6575321766866965034,8955891195158036493,14120131745533554566,10516362855743553824,8926261593594983229,17719287912522271373,7395634614902084110,7843064252415595800,15655441798233709406,13992321097531976104,10847971935710001894,18103552914974557636,832735382365188155],"proof":[[7017254579817787302,2293973258248627208,15945874728013137764,3625841031683203837],[5891812947720065822,15929240173119987194,14061404688286217442,6836587724955492102],[8564920287178620312,10408729291684682221,14403224612241650806,4290540420139826734],[1392966069296221203,13711829425035777021,4100164665051181881,15550216204467078784],[5370576492792459548,13136078418712537,1108705659820442088,8898708069916041471],[4091589960314379534,14499624349313321586,3619418224379698031,3215570537805881778],[2704337060299583103,2918353911921003770,13834716850062281259,7131889334591065432],[11218401088590015630,3473369130232110348,13466837149393796597,18109467964584461473],[17521876347947621110,5378654188826459088,3225241754620698910,16638797409339492814],[14929276988868092735,440377328913572709,14399793510981571035,2189804101054857987],[10764190588005973160,11290273018691221267,11737675101131653589,15357936735307553384],[8010849756213096063,3542115481254150389,5366158786065687870,15569208031430746272],[5983278801683356809,11416592500359325489,18104226594227151824,3486755586664005068],[15137927872877174065,4063887293700444569,14085032058186376720,17564918044722656100]]},{"leaf_elements":[6037876955750774951,8125825260297102634,14382951487787111092,15583728724463211447,4279686821321742124,8593526192944979715,3255334258388859031,17073508207755563914,10902209085873582427,1100758390837873967,3111449552851309980,363705019126007878,12853165315796161685,15567516911373176275,17249395462453325477,10510698586252110767],"proof":[[12147798528140615816,7094922294975238054,12700381842423828578,14787057543324211320],[10958016789212744490,13601037036388220320,6514532683313391142,9574445013895913100],[4855775301680981540,5419494349962634723,16036840652568707544,14130198444656004476],[8951453782171032530,9483874112724120666,12690855164735654786,137213848971425840],[16818861740275366018,7757328182814538368,18005376523922551326,12913046943370027892],[14964453817687147820,9891799426391118584,10350630749143030695,12451736135230802385],[15927516599066117460,4236107286855786218,5900834541646426700,15257577995093515113],[8605662730554730627,9972844056861200967,280513046507040083,8431059768787509172],[9703825831331273425,2353015539976819766,6115384723138097519,3323111008708227039],[18016650655720253273,11557918271749346640,10670240823395031503,16148141828966990373],[9554452067839416698,13821169543404032119,11680377439586710339,7377252515340819820]]},{"leaf_elements":[15746908833361032654,18418214228858564831,13511692061282927912,14679124743805394981,8084683804698995632,9819547087435394465,17684134634293305516,4254296211062767502,17018094662206285818,14480083755248889440,17599905288636856542,11141894022104249815,14176241963245567598,9011934555134748590,5345938304359585980,3273479317977202799],"proof":[[14470951765102918547,2249041179085576358,3333507600355131800,12969249834877018461],[5137583913032681881,18010793423224410218,2331414701048823056,6136539453496625564],[17469027701202291436,9326757014918217152,2703673046898381651,7485908936614990045],[16481681762947318300,15186598193373296248,4732349187828296994,12461544259943686680],[9860035862602200487,829890782186849889,1396762250924150469,157973924588728608],[11056139876191807496,13300627344779674475,10920353254732866683,1842347254290903088],[12704956856128171649,13388789190673818353,5566723771759658175,9518083660387101057],[3277633674429368545,4292845282575922901,6776626176108948204,78040119539530551]]},{"leaf_elements":[9617503468971928211,17287914689588483897,10280738642886205341,7071337662128244164,2649470455380266068,13816886849292234767,14402420451135499389,7833294771180969479,16510303427036995438,7180122895002319303,9218026745749475955,10346931512942118204,12747517855250936346,8089798381610563869,473147403606271365,13016118174951520791],"proof":[[10237305638178507232,12878874800519598904,10762558000416663381,16099813758472269465],[6896441420515455647,11247814696248534860,9955268529905374034,1414296861897428169],[2645864603048017454,3979217271037812449,7352222321273508864,218173703314943547],[16073072268525559718,6429355660773841582,5696227252770174861,7565376776667980817],[7093499495969330606,5406737810320872939,8863888484963851667,1781102728667246792]]},{"leaf_elements":[693929662056446243,12376315053809756249,17621603109394541669,9464223933671941010,2831867122956605789,14869239967824417282,1395927379863112570,8554565839043981092,14011550505448682394,5377909270454991165,10646669474658201429,17339025867947106425,16032097035354618645,6110075666034690926,17489810267226617305,1702281671423279042],"proof":[[1659850341596547547,10642565317074664205,18060257547166102824,2480861522348345467],[15387130948766109852,17477231919109179114,6282442447671925386,13982494802655535565]]},{"leaf_elements":[9963697324120512130,6935802622808596880,17106977806795412206,5253618945110997920,6891196272247429548,9013941163798537644,13032579693020402188,7112978098992766075],"proof":[]}]},{"witness_query":{"leaf_elements":[3755354809325307744,8673827011449465688,14827348703780239310,16155731569493078607,9405338974695319705,9439581678988151026,4174175278758838007,12500115558731351451,13957090570155410920,13002389038738317567,7193399825758240198,12565923943534653213,5821042734810945358,1448085742156165568,17497294467946826222,3053046150792074126,2630367009671767466,1583239743427729662,10445835162260102634,8783572995965810277,12644755105045572427,628154600626024125,8689540878824620509,3770940882328018386,1808277104062608952,11088801829995923781,12382964969415006063,10162749477639157841,7086015508193777590,8272225538108047955,1988480011374045352,12441883708442070047,17121851443974855806,16673322755637728039,14991078021666671954,10990093274242539751,3266209858627112139,12180928428475833171,5748283636121472764,6655113585491172226,8472335188702192202,12940296735911201448,3580252398532325511,8792008886275172073,6864522497064721678,10468658351516367359,12576268252942223121,1778105232062670446,12086614131879715739,3712200469789935995,17131041448244703891,9276629036284663414,17892126932638412689,10449405176379245805,4332932465191277701,7555783122603989471,16184684414155093412,10683017256833293158,18409585259561766321,2086181972934652287,12227109422261725568,4547009212630503787,6381478462462336814,7128215301776582863,14009621685696784812,205784577279572072,2500084702250165699,4046019051973811458,3535605972452674534,14111690109609329836,7176500594476758214,3039885470248283994,10707467267751571380,10719890501517781156,866068365451962028,6392518482047535985,5739970247478322039,13610571029038660612,4161526090366621808,7338156026298804774,1141512766685859880,5368234151722182171,1423363290470965314,10797008368600489474,3301125607519008258,7911426523328870571,5637942774148074034,2340351204024062430,6126820249261047846,14326968569762655054,10478421266641344601,11253175863896881952,16298884423548624847,6196451814618029772,9799280047206971187,8409004950158363740,15597240889674297,8550106528641447551,13770789561062564541,16156864895835808457,6581737841947445884,5743322703634748999,7909617112900579142,18234417878030739592,12865052710894181115,13671626952760568171,14619219075816419510,17543938405800741364,4373731981452712516,8602194258866199875,4913973096244710025,11660170025393849782,6857025420391910131,8620369185370728012,6000286963816952480,6781929841007081743,3831214315327464234,2823122353051225224,6596443218662226588,13732406834557000863,15023837158763462186,10524876916501579165,5899158778531277594,5529111350113672704,14299838672425113452,316038731719695046,9310271725723163379,13455425583150114044,13854154751412797861,7140570315225844365,7042649190808355997,8222096663660972393,7450813561851514084,15119172964636827159,2606704110737548076,7740571627317015260,610406606201229012,7146980378753012235,6502665899353967484,17775609899140292805,6799895043279194869,15980869385717519964,2200135375297939151,11363276413035368426],"proof":[[17749363616713949192,7920858186195869377,4963325843908435329,8578237552306740919],[8822133337673181657,12287136451027098981,8361053218445315302,5875193664571801972],[8221051805799106315,417236202661752913,12263266050322184975,2898923084565059948],[7623959968574109651,9148304669945467442,1546203223232350608,1323619501836912879],[11343808857549093877,4875972792205460270,8523099690507003226,12897494469842999910],[51660574499912786,8363976618105369032,560927626308933296,5293488111533871065],[6394985796185122661,15487781716488003959,10650720667003755121,9488306955013727465],[15729377325967360253,12843093770617755193,4730938109980151347,2338213607162646880],[110157467096890299,14179093643550545236,16676446743901942024,13242521296071466401],[11624889232267130659,18109088478126343454,15216502194631315969,1157966344382394633],[1039086492237682012,15138420665389412387,4024518663046900028,18406435302030377739],[15122369572749380043,12357506818312560194,17202723098713988109,10495592944213296388],[5009899980663921583,16207203681746695506,2707941311753912495,11495458862485981928],[3283636597972222288,7288474524168050271,16024548925130376568,3352233630372491665],[3491042110256019772,1161971018629106266,8281119082522022064,4862276033296485552],[2945863120708241171,8159151197294358715,11089913621284039627,16546757420143232732],[1860896835063429843,1652403080417522212,2261129679748469386,13254769866375557538]]},"stage_2_query":{"leaf_elements":[5928332370140812008,15208963541311742253,18330812558091792412,16106241577019598329,16275219588639903437,9303446616895109073,11100700992967425835,3518267520105351702,12148405450356367499,11879620311118598082,13692826924131112836,2389514971066545734,16376782862769183794,1956372068579492064,9925350274699164205,15644121008912626616,6571103754438574720,4670273686073610780,11272335818811372094,2018097713046990282,9723730149468080074,1153092198722047143,14728606547100861949,12394911535102985228,9490772904616125579,4370683621082692412,3130179033174513571,6895622920456028412,683427027079186039,13589442245468883984,7084150138395359529,2335025775628507762,3042725001259451949,5757785214980202696,5987730027359730847,3468408440374247576,3716982599070399304,6105920983663368925,11293046742530738618,6382175492565497185,14313366721867383351,8614987891902608233,10368330087019429333,11037301181842392096,16617095558238262313,10256188184881661294],"proof":[[16470306418524238048,13081614395778302322,12016456946554848866,13221218602146040733],[5147593760536229767,785665487300349772,7049386436036482240,14342614056762840054],[3598001481749431975,6144125657361232685,7893080469094027534,12591728675267028389],[1734807365207764104,7729300728941354509,2159572748844844580,6241391634200909564],[6927151704115350981,14539185164577734198,11483927064116349340,1586218118850943666],[7304133635271071568,15449248404491000806,3971816040362754280,16700517598798433520],[7978239636399610315,4089717382775530316,10578451584365588869,7640941211256321309],[813987239090163685,12691987973538793299,9776155840333713269,11868372301496178765],[379258137126056989,10157452086085275382,15856539317324142592,17819974271724728902],[17394817714544493565,16963483298208807489,10236233796296168631,9629307733668642546],[10082028369032254645,1145726441537643275,2295125563845058707,15335172704546286],[1197908260871997570,4523200197166111995,8009773783217017443,13564014807695471773],[8453299306843886906,11379205407486068262,5059485877306823791,13471030045422341375],[14550953470705599752,2112269725922430213,16643291326338337817,5260652324281093432],[15258258073458333284,10672206657780689266,17415983125950091192,8063373172354891960],[15306544927634013289,2794978091120379871,3796300467670037656,12741519776787740542],[1323240375839521967,18311725375579224908,3996149533677948373,10325837003394018898]]},"quotient_query":{"leaf_elements":[1028667875746593489,8795792390725928072,7133970701110963978,7825938941099300656,7903790271558139878,5187577628921876049,16135491960582923111,14530904412731695485,9408460513081585330,7839963702728151040,13669689652857810200,3203321856802999649,1443653968330883065,9032067439748422934,12582030522551991936,8613968738188504792],"proof":[[17021366044281780749,13310744107329889715,3578638017827862169,10896161058866796385],[14917112830978496139,7472757602315925978,16842505507568048143,8544602106049767128],[5312164879471637214,14557924255312895087,14043747690546079778,114512787837097385],[14208876660297871093,14108622696237687333,11623842082371376801,12024016126366329810],[15020068188794734218,8104078078992865095,8821573129941550488,14033038213842516300],[15369956483730523482,10028701165961631583,8885414499178106226,5541161014764501483],[15122209573346631928,652899339386419648,941191683092607844,390395784059219650],[15020135632340493336,1379321016518994081,15921883215274399366,11811316801434546783],[17851693488988562942,4576423481356881248,14489739810029714178,13611242731881720342],[507765055943938360,16272278062447249941,4567856171998742344,16532391621944476546],[8870622925787353094,17150937272057797867,6628768392169077656,4328326396080701930],[13937110469714741211,13808081936088514758,14621808796968332168,7508509798674530786],[13826289837590481743,11110069187307239313,18241819352797994400,9603507861490967622],[9133562286421519063,11001832078613525512,6439656094287682047,12286418393063777611],[13790484360128987984,10436487963915467307,8412047174155606715,4339586144243861652],[7934424558305572021,10873720953167864,5363924606283357776,7247229629047154687],[16275865454186967714,8029517013225501122,10889177156594922072,17199111512595852426]]},"setup_query":{"leaf_elements":[11186640977524699412,14550557979604306051,12008030074356964627,15932839875365642258,1873639487523021843,14246314179651609448,11460248468830010041,15473771835900765471,7441164815699879105,9331675892220735767,2924716085216609725,15603521795056657196,15076186745521225204,7295542020765903544,5014596878500266712,4595391084689519854,9893978720020155408,10196285439443371015,2612655864052299449,2020172301255163878,5338038970103938268,6466212708731799983,1580785592138283112,8131679332600207740,3685613764122633636,7946782666714573334,1831404199881282405,14397559305597712976,5173421694822478467,17345354199669648591,13411520152749252684,12693067276785371988,6986353438725010892,1995334066076977511,18345411568265125126,2470919372066990489,1423052974019494387,3250723630988190301,1779570211334522075,8666975920830895880,10368447487697166977,2435969694284636455,6659626413817531319,9904561931984472690,4088452907138092925,808312887165444627,2502166196379682878,15937795645018902730,8463927625503281586,14226860221420502941,14139028611352696674,10823216829017734732,10301291370882555164,3794580384579558915,8123638401322579515,2061350053204859846,14692594604502856390,15828900976237648630,10836764718400693535,6449424045567183113,10233117689061951260,16339858769575412673,12899467007517716457,7373295036804946404,14502726107947625659,16871162538830352052,17474995533904316822,5480852905219239162,11400441714677575031,1462816400054007073,15794827513591709804,3339860370037411524,13535385404879269367,7264862100670978631,13569194522791666251,5166251065311653569,5753986439815298688,14888589695944882363,15056347862205022356,16526023005554791222,1635100570755892653,7632325657972510314,11311922837779712301,11675881197459379008,2391283473587745207,8919510954688618828,13584970798442303133,9215445045210349460,2908166883684229386,1444394372481669690,5208415022875789092,13868975505287919580,11638112689019656275,13434110110671092852,11354216099622160203,3862148589219167956,3338946276815140862,2616243842269309816,13903568367412704708,6171939786861032265,7205182984091988821,18154597865297222233,2782728341830380554,12693615141080690115,13425432982354539010,13644459333829356368,9041895049179433290,7362953167421093726,7703681808134211046,7123306749130874655,6036967311442559457,2732348078130044387,2103688665350612497,1359606578695497808,11211780344933103258,13468987098916110920,18046438117512015231,761224375738759511,11348079136084803951,6124749766011913845,4552161125475785805,15330196171941550350,12425816563905395956,416402227443267098,12713303052123175567,198036162568997615,10830953538999863880,5683378554965300016,8031348577389032728,9660561994094060413,7208928795479763567,14476635804666829177,10992892189437968619,7155776160632674802,6480484305858294866,2200142526112205572,5164533489281272061,4895097694807377552,16649769820992116319,8483140764463779213,12589432151589639921,8998728399009526144,12027478513533168634,6775582664247288647,16299145766972498709,11905942872621704563,18353314110731374160,7098469824388160441,10177720482554432573,12454588009632957148,1231763805817126638,3873588725783167723,7774183502533393189,13112376969692568173,5782292279502783416,6039152943395376404],"proof":[[16396900534666490441,3025684661574081871,12326985603818260781,4717509800208703536],[13416042356503575338,17875821970543719825,11317063390786862617,13009774296568175847],[15401973011699630471,15049482546379779744,1071596869613025745,1900757206768145687],[2619864290235186145,15730965039338821612,8700856716133183740,13199393363816186759],[477200788059447277,13937206426046276392,12060136070014029938,13600529341135837726],[16728421060606064673,4758803248298024016,15045628358469898798,11726323931569161844],[11066086274282913065,13711605380391937021,18151002660464814470,4484253227076737410],[10286398252155014829,9689061598052440330,1585266739256375582,11492256698385254503],[80831872474802578,12271465381094368896,4005758879567499500,6073665533626291378],[5894502531401919379,6817131338677184983,2610099966816288348,9762554802431180921],[4780423424014080821,16131058389658474606,10225667467083450197,17109456999478760931],[11167594839789586679,13438296926884695075,4733464988184505538,15690764723043397119],[13063949596206015516,15854070745682911008,14181429489296679112,13848150072237251005],[14443555148601692528,9640016152684889053,3368972803826341179,12755398397911894359],[8043777399769696325,17183778562638322950,10955985433162856519,7059132494937717124],[5577749902235936610,2508071626695287737,7946159595134479104,11003049146131669942],[5614327065933285653,3328995280875371920,12239808749654718222,7079628069834605315]]},"fri_queries":[{"leaf_elements":[1104288285844702552,18377336845799067755,588373184328460025,15935545596495743750,10003204033534022951,2541578502742912773,1060419818907026290,17646694740403979869,9713575172992004754,3824562304909621051,14858680962583942521,17576033980681137153,14863141297533401268,16985722344310919425,1359248945897716402,7827758184585057661],"proof":[[5749994817038769445,9909320528066540650,7676302439647450777,8845224838644065998],[18184932490441785315,3531954130566184513,14300036710353444759,12824919673455898474],[4309834927613864004,18025368052810178112,6897473711447673652,3108586578506834096],[13296161813861136376,13934606249645374022,3288432166557294630,16245888234571056760],[6016547465291044052,15975408231995168338,18093917773343042243,12039634836365725299],[1786864846261898842,6214147293410290766,14667384482088269963,13962267147028541248],[16184609982492221845,11606547682064410046,4393993332401398013,2880930822851860832],[8541541440846176986,17497156836215442722,16075445285877949504,1397193978363669076],[17703533296821708859,5082191446632824957,12905061807701653154,17238286166851288774],[15597678925054857076,4145219974631726511,2136483969192430284,15917001645571141773],[2387324608500645006,4140793481154030295,595790944404911408,12403919511392011557],[13436962952931688363,313578304777135673,12943383523096528212,7788496274352859422],[11286457568846676776,5013727499813089893,11504919871425148630,15623363243145632533],[17617671789936036600,4392943681491727174,15270466481397815535,18102028030276323478]]},{"leaf_elements":[7621016059550999379,3579755843580996276,4727089557457530457,17365122482960486502,601975499387850500,5352156900784603126,15558122290901709445,2633665965755146260,13564412746170093730,11594055424540763731,5031611372994301020,7078210466922898447,12817532617186834184,10105078777487697561,4314811756418174281,14092063983138229650],"proof":[[3950429310461430973,13233081202076793782,1217405938857586831,13336315305530439596],[10109554031150912460,8730656601802623228,15749397733140997324,17730528049418912983],[10403532289142861048,129832011673364743,1271037495443939526,523565767932746370],[14456762619374438429,8612661451145135258,3839758488049627452,1112169412701690084],[15796384086769991354,7555323675449113340,15227684030557786750,9841708838192385117],[13198890900463840525,5182673518958555163,14133189365320641577,17082527795055601524],[11776338676738482290,4892568267228483787,3683331623973855707,8479529531841762164],[11871385939122677794,13367586360632717409,7864762835787563830,15553462167501423839],[15526104121499366199,2646838561013226410,2040208358482844691,17739700510970552755],[2344129626308277772,13326602000778477657,14561961681591881594,1659854109029037560],[5204416224914363540,7631047996102225273,12862164145984685228,13063266225627597449]]},{"leaf_elements":[1342849455334770847,16402608344001361142,7763440993655504456,9942740820016981994,17979430361949952024,6569538972884859117,16649273984948012743,10579816635566172130,3431036783953920103,10073763323566135536,9834235616715475070,11993811700844570762,204591589414976360,12879376135019948044,7386610373544702069,16714868830762831460],"proof":[[4824689034054955000,13788330130892436514,6207447617844442445,7480214862719463456],[7715275109271425184,10688944616716672310,6835567988738619025,10810144312949750604],[17734945186802422770,15439238498173977764,4880161706432104130,3032918884617295093],[9075900903902215502,7301012355203988902,1211532750332315432,13398420516902345862],[7026166053187864812,5378731199789079497,4657954624022317014,4430342519422396195],[5159804935821369984,13994200553260237109,9445835667234478224,14066561529742879119],[11576929916273111458,7010067740305565866,13591390134299720398,13448355386671437584],[1770868264315023480,7812579801998129002,524698746031729832,10714744940176785641]]},{"leaf_elements":[13070374629953726641,6853543137504980319,6860639164571416591,4659138557043512407,3758493698929616499,13017491769890069800,6515071657698977236,16373794190619233176,13325652682157551841,5065895582404482605,6003453450922311827,18358740524900458472,12356656092825926206,94364651790368756,3441157449227019230,1740839741667970749],"proof":[[4678265096259228107,16022601727913158666,6833390918123288680,298533604244584253],[10564411463071116620,12115268395853191647,5951460800004337870,15539274182663975177],[4265438436947304753,14342861525172112993,17967674316163775908,6834470526382201714],[11305800191859317577,3493003457645852143,14744895160582527818,294976057195894225],[2352908338701448330,7592253344295024086,1427121771405932881,4783686535469269471]]},{"leaf_elements":[16070831778730322167,17146922037619272738,4121320938849791840,5818432618082194181,1370020225682757378,5144995496371304514,14040903937101183461,1775940530187431237,5178406466832460837,6764289863066862362,16700697179272300234,1701592600056653324,7605391755963925717,9462490642760313982,18040264532904337779,7581728628523268145],"proof":[[4187436726221841529,1184190036992878583,7683626526765293269,6799112461399047134],[5266687653515500013,4022039819281218887,498832073896150918,3983130288007996505]]},{"leaf_elements":[11907939937929050222,12199976274714464765,3239066403731203959,17951336118807113373,16307121117972480027,16234899209723555345,8364706858358154655,7274458572308793086],"proof":[]}]},{"witness_query":{"leaf_elements":[12448302045820070532,2586040774463746611,14265555691082788181,14456754752880191235,14027407212409505013,11596127757124874753,14048572352798085832,10219514855645808906,18098984462148689528,11293356535354505604,11489181629146007989,10001383175920680355,16707661610885140105,16525402280820204368,11290591910318067660,365544371511475976,4050648183460069892,12000683209143924257,12924777065918324889,1412028282541033888,769828851966951921,382748801984026350,8981692666775046506,2740553766895756118,5945458995756335146,5574073481565829549,15931861754936769405,1637343043190566267,18176281330866609758,8879509144520726870,17284232988240844574,8372369496809589109,13459065476227083420,3289870790258291993,2580246000625783737,11257732299292853036,12021528787063613116,540208054085256272,14170433821827973633,14734949924604315569,15729713956810878415,5102907190263793384,8986281457358850750,15055780957667145882,1633855939914689871,8588669681617051440,17539289510459326735,2238348477034632539,14392422539691647466,11687990183133267523,2759593044816959884,8113018838302807030,15813707108945303858,9891855418479467435,17790205852977011808,915070461324694776,16332288763285430418,18296521292150744476,8512403516726187053,13659707702235652598,6372966054433466824,18202556988910763116,18173667424809205098,18393729374194006080,4614690877144414980,11215893933792762633,4370202869027916858,335302008095637128,1984698463709657051,14691259202512280170,5598562481412116243,12022254286485337553,58929157583377904,1696771762368256106,8926758078722351538,8662971286525469135,937235040727910925,2516160037969452579,16389722161092337071,3821551550208442772,8331755081266684483,10062772593235855927,4169238186635681266,3418228203551955996,14141594348046970069,9717638310724523435,5242254797144415741,15621350828261054975,8661681751623288049,6264013367529192737,8573106525176950418,16835916789543057979,8814832439068649934,3745454097934045753,8011975348850556550,7505842016322960483,16204992363548389310,11488845543873053021,5167071649164767079,1516054556741090157,10386086599631544171,8927824256627499529,12347510049874657608,3138785246330824422,10339073149301612900,4158846319191897658,8701887636667567212,7560299746198975494,14648120548609724924,7153005778509501258,18149724686243679955,3279840387699052455,3434300503260534417,16133016202621082639,563661672340129004,4433567965061765345,16113286753461893150,16847200570780237727,16326439260252874056,14118078796557336544,16139038005514257859,2681001380976673372,7268664645323970694,13660895983313604971,15859157950570125726,18113594408834500248,14703567372080051686,10611503408253862663,6513310457508467039,9653238300367253196,7170849066743521064,13141505297702519799,7932713612229412360,10327074463453183246,16721060835606636136,4433443930379558150,15120380678583545366,2244307902157799349,13981841540000681216,11094319056636083854,5145028566246455492,15521078122118655941,7242491518042280854,8744451221785612935],"proof":[[764816116313196517,5617960505016252894,1509189019199178881,15572064992779697250],[13517476293002738201,17019018861993500881,13302493847788762223,7934575812559956623],[7628769553818350249,11593914811142549175,14437272313496203650,8114354599213742904],[18359492823852985543,11903886308908833043,11733095622521444872,3437871251633975597],[14466719067211207871,17039242065684089093,1672154405518519966,3133007073054832802],[15163993230843870496,11540740952325075448,7714570976080633561,8244639496833748615],[2398024669161723505,15869946633831196243,14794256064139901451,12526253959775662169],[6808361199158751463,5239362657872078227,95665105946405528,4338862876399480316],[1980732755212410937,66378765896085877,7631598864678211032,1589657249860361484],[10086825883841297269,11789862243401154898,16838488793932529490,16783631441104812078],[5103519169715958797,5585179671992208692,2968257239813999400,1570120473292105574],[4213775100237983736,4517163483324359656,9633206620635335143,8095938695815633220],[15167194113787317702,2636600743560235640,11490066092941303146,7598207130287517355],[1137089374085783694,6737681319230843924,810532076227271327,10252904549093219456],[14664973368043267692,6302240280479285078,18190229405361045139,10093720497376073960],[15751304304590378692,3540380807527523619,18241216454753406294,13195695456519316584],[7469098604000971809,18097563392066223627,11227341610261445307,6019606818644862245]]},"stage_2_query":{"leaf_elements":[10550351418177231764,15329975297171282647,17973409215529932824,2938195056161818854,14128415533073277787,15400286775656437047,9368333161319917248,893322889397547759,3349751614054478034,18008999849841990619,2084571815318651739,8195899202504885442,7306460901060637341,2408172392628592407,9637671812620715671,16249911715725509809,4587177516475853346,18204985858086009592,7017242486635822982,2119478249175800040,9210193387216038682,862535472912383699,12034557395110235683,266674052692275224,5048535045028718207,17779583652775114163,5421400376818335693,12083580300146877139,18161021953936184661,2760623110008137279,14406405473599612116,10752479486073458510,4476243772591359708,17102072402988410202,11660980832531812697,12159545661032079311,12542814512047435511,13334315306835302882,7889187735082004684,6607991114029624500,1519894058854650110,15978654513569838943,9575812842669162187,5208282846113322986,8943622458411700278,866398142336313481],"proof":[[12246137723293935939,6643235650513608055,7283003891294771905,6132552481194451464],[9690946938049477613,5225213124166645832,2150828523921495886,13296170099298637148],[8777307546050627616,5813122155051042257,18383825028898490934,18077514460310252788],[16361314998199854278,3242948847533761068,9937460066170877620,7454772255927476486],[11182576212513734590,4604636575201168277,11286079029443783182,4989778741409611415],[3922469383953992331,2661283461403408563,40379284063834611,16342563097769648848],[2960630584453770610,10833730487692434284,16600901844508840972,9467647835738203542],[12540613967097367679,2197790649044649728,14032217334721311792,9616995582283888874],[17948900005603562517,914408252347228226,3472395921882224974,5868200900297636860],[13262184047697921979,14740859908811072310,10524844329739242611,100603598206014374],[3700059918787411459,2925521356728910751,16930896622089221767,1961288770529309573],[9271006962463342625,9311183093082086030,16750923198055684607,6128188644218777835],[1726816414034003479,8442616795601680503,8754263214504106523,14877216052820170967],[5836766556719968650,10139878487298000979,12027958358623086641,3151682264008158222],[14896100249541593412,10740588667362832004,810547956664126567,4065347682811655484],[6339192725081551224,10382534389118847236,18390739725709008981,17041814705167592999],[4069576357456985224,5364972339274971361,10552631821080538803,16628088351488721545]]},"quotient_query":{"leaf_elements":[11203955242863302262,4777656662436532196,1757896493178349780,16100660929887354832,9738036607112937063,452786513868995813,14485885417034738809,3986749357888373016,9313890467200860275,708868692398731460,5126246332038140532,1934999754454368470,1078042857686108310,13857372716028579006,12312028773020325494,7928107765482467479],"proof":[[17214130049406905023,12386243678908557911,15058782204009484493,15676367952351708773],[4646171832991369667,5073167045719730862,14647744345789264182,2339351609034107416],[2008569873040192554,12435735228542503810,15158497155522966349,2326741134599532139],[8978200517802804777,13808773582884607782,4520383286053374982,11247531182629348333],[11676565337810690204,9494433642768602172,16406824361944851328,3891344333027772340],[15963437276614838297,13318503240939724808,9181193479258214362,14507775381778221823],[7924228764008272979,12095231957617971691,16313919845525040522,5354568174967000555],[7811573358638980108,13606118875751907286,16324530891834077111,9317510931735499467],[8881669757089743678,8290112191312006082,14778933405049323787,17331049538467348227],[15208887150440901842,6026348876780467340,17560352306129307447,17598153067286010088],[13646426083812132921,912214399789408145,5121108007365645041,2933150076646163983],[10753666339602285944,5386018950561662642,1595785324109937103,13128679522053193681],[13103299229148560210,18131438441561444877,10378666748957323127,10729564721184740058],[6961931089698773361,14614968526447074052,7919505213590673806,8921426035938054522],[6546789652415849824,2171576846982443026,10479185749672692703,415479615494547079],[8050082971923925554,8006058097169400734,16917719109238936495,15231213998508485901],[16735507931988475280,8372437731710315497,11240048427889227812,13735935605106250657]]},"setup_query":{"leaf_elements":[2638604774222065896,6575358980239061187,15861082491560949998,16877165713972287410,9722918559798645350,1825168252992679383,16076034443276270403,13011891921693818703,4119363957481664709,14777846685711762586,14551920422304590132,18072590662291598086,2960695123131750724,7920270178899971304,11095423381555644845,17771925064242578756,18281352203422880594,14092232560515030413,6985264823302190387,7297495272046826085,7875873942761731459,2817202040925030538,1583720176715591255,5606125782808778750,16901360182140197318,879423270703637262,4793838082972770042,8354501614478452251,8431146511408309875,3487613555205200714,2785966747574101949,6694759493997404403,7304189717265223287,4310088099192730852,14652493586220621307,10631279523082842479,14866610885751069891,2172262621930026151,7647588290471181475,2125834154814881896,2668884836494277217,14614677719835738273,16099742283051154737,7992982909926687024,146510267280656942,7030242130006862666,17061069979451634627,16576572631314601448,14808786123696621464,13749312669954750332,15285802393092003646,14641077874124183991,12268418586864752482,15194132269752426175,9837133093984397327,5781620768314316942,11806751729201535152,13701298389653918140,4099541648676184683,7834486090156850588,9233543121386733961,8552896406626079494,4322272400651081232,7854308724950433216,12915563996271618644,3623158524384850613,4389538849134989646,8754085447362385244,13319672139277151239,13496697218272484358,16386437856513937704,3534217338710624542,13877018885097024064,13102042294494570092,14944700331432888886,12455550635173410860,9086123158434909875,8936676539466090080,2821022729343254980,8562540711570144965,16816587553814394587,16908798712731616354,12163877928796347685,11194365490941381940,9371307610526179682,4443767091083666767,766868047316770676,2525703906013347083,15361302808110968082,1534353253692448671,3307870436153198321,13368672647362719764,4629746397457196428,6814492363391643361,8722765476892159434,18157337179931098933,7480997050536082007,10879704637913923375,277679503401187623,7727136612712940423,388059909747876520,7128653128778357503,16172268203767578778,922143815397156046,1385737571788681305,16442051500187791405,7190517202572613496,16042470030478785429,2200974504620640552,9643446882339073376,4932039789335015173,11305962281838671239,17981603757209828959,9923143732577146662,11285876605120972221,1117585123072937939,18220193362610608663,15902388527326899466,8479334011483365550,13384825845169886812,11075583117985840284,6383309287007160278,1892673322023392482,1089292374367404850,7404556209124183553,17189022574683904526,5991268576358040615,2816105568123737338,17970006256501981603,12681307364257167258,686043653910172281,3982226351908048502,12100152334866685588,5436742506100145408,6517306792277964473,16317398512499948714,13973510876625389138,7928749497570121453,11564768473259259750,17987407849992125299,8555889504037265671,6931809061166018813,16957153444039947957,13719654478530923600,16843834269274306473,5053642598184470727,11719262358384944545,18314859029934736133,7805710254522545292,10196080983980047919,8787236978987913251,7241633025592720880,5001253517554440143,12110571214293036693,15552851586590450174,8381915080176450663],"proof":[[1850613218875776,4447384000028162854,9919128485004036923,2283636441748134079],[13491165728344144712,15444193461469175031,426279934585690514,3045285471802628324],[8332595791661154471,16518453522086134967,5239342484371143058,12965981222304458958],[7121764039544831329,15432022050661864056,14148395180018505892,3975106851954777155],[6691939877530183534,7066925591441415854,5790116928986484573,6252393946114609346],[14554059730475920296,3558912145944140485,6179167671606761008,7626002624642424181],[972379090584679712,12552650656078334997,12345375380672621136,2389511756312320092],[4728708315277201724,13553772047245708298,593661747084798727,16868032575013253403],[5371634357326581144,12556496110798197819,8994259728210879581,5905514683047484095],[3325583001263877928,17319457930142224705,17730003612106170924,3906978798330005694],[9183930061101530293,12452031442003825528,8943699126833083783,18012181176630286427],[10129915438058355414,9680827733010256441,2863641571811702058,11296193391625066882],[18425535839931913979,4291459840248731197,11646446124117639451,11333220336022545654],[2273336062518222252,9933743136608455163,10423872819203071797,12816625883535522528],[12759047054646879916,13404714067553027786,12333811605158117741,17635642104697326851],[4471224076001378926,16919955007946926881,11222855981915690559,9841493882299524028],[8550157948290753848,14777161903517275534,5173375215622667146,2888172977515519708]]},"fri_queries":[{"leaf_elements":[11424137027393036989,14799768602495335574,11331274111019873500,1669236932643751119,12680643881260816394,4574703762334984232,14167404938686417721,9862189074070718664,9904792551120817257,18038002951656429483,11345177681097094250,2796606210254087577,3731694807342796437,9829867834227314317,3593868249629087364,14837574374929256320],"proof":[[12282220204407996198,18379619490301825708,11781228938888605127,16146618803819829126],[8211605908683814234,13149631294738061955,7493502754175899788,3656251077707215919],[7613101260825731569,10927133274811381064,2709016297319314547,1304630218483540527],[10983834939473187396,6626732584507878380,3516080441660159856,6379436011331972590],[6704697903778874483,12391962209868699303,3737291300365624312,12497255563891791305],[3960801562105890956,18227618273995113906,3495788629587051365,17409784851989595384],[6923356941832711384,8543568876113064808,3796720822904618543,10919559079970030390],[11296377547144268202,1101130189354375351,5708304887448539005,13554128917077756313],[18164445230507902560,5924531076309994092,10548815445785825028,1698566604951767171],[15157076946004477722,7716276294530906287,2488425097709500099,5027999491196409305],[12371328815030114262,16627278201741900868,12723239769339426235,17922905995442887848],[7124350690673156726,7604555951491579863,14478931012297683564,17341827219769589443],[10918749277507258907,15937554421065481845,9961006941026448436,11221466693294064974],[16045127423565279178,15906367393634530664,11775646977459072100,2875908643413602654]]},{"leaf_elements":[15486978097526174411,15785584786464303061,10818218425512469624,13405075785224695670,12685535550788110343,9828835361119843804,1589232857185001222,5589976474025694733,453407114638277206,9475009596689647326,1768477632060670807,7815040372473112422,12957404521884165911,11049677226323135732,8539553903801750771,17322079033099908502],"proof":[[2251537030945916396,12585181169431393806,887511728540559134,15798586767433544136],[8626810892379462731,2575784098999210577,9867920018371439557,4916414453743202841],[10586465903619488067,9402259511291842836,12167931101826096972,6184842348114163113],[6684820578275167672,8177292104062361819,238038256446091394,11055351140610293279],[6574049139535806163,7963684205811950830,7812289396330138358,7119447547497630871],[16541479632534071638,17944739177768051404,13867591777801154902,6765151538357444882],[17656252420244388391,6411070494008870389,14200917800302051119,6385657262698305816],[14221534981168051979,12840643260319216198,2286487191953438388,11666611587496191544],[12257773556420523434,11930029915295624476,10608816307510260650,14476529811793321325],[18330321698974098681,12073493146449843580,2864180908336594691,8469172028578557498],[1355231242388292694,2363504736459679002,17928632709021131134,7081248891809449452]]},{"leaf_elements":[13883774935127879577,3639144904091933540,4011756208359694692,10592958857942371276,13969666291599262842,2288215630243721062,8827563380577764187,13767484910088683535,17788620854734107600,11956688901853826649,10272826787267007623,6255720778516903469,9024567140902122929,15791747138567237670,7614339180131402728,12263784357703039714],"proof":[[16447112016642385401,8985999835676231397,2915798250679966053,6234235317549474537],[2168278791374468730,4113688911971594217,7912440200486597244,8050804222786456683],[3861568373019176139,4517739036713527685,1498222150639807780,5213084906986500621],[1219338937053675092,4002937114256711290,12681175950279215726,13040328099602123068],[7012361804814112867,12680092451325765097,7065187832314659019,17199444447821342466],[14907370466185883422,14680073902656054330,1584953365792223413,8168612595713362400],[12421488938905378470,18062404312917423353,15665723535158187769,16625498805882016561],[431402881678253979,18091544763766368937,14751318003736167124,16253948255518091428]]},{"leaf_elements":[3781452042834956765,13888735080907785300,12176200810195173769,6789047036088162244,14083859855827590072,9781048682227360741,3660469477936375041,5801932464176700441,15592869618096443324,2226995300798307901,11203687496983334197,14877530394086669337,1530779307649445283,1124320451028825504,14687789503130209508,775387588174695821],"proof":[[14375519844451808218,10105205964443008475,4904964165673890647,18129155869923329874],[13378164124871731129,11646483083622243990,3264987825019592089,16753961549359499682],[11515808058377872797,5734428844475359259,1269855302693389815,3008625966617241974],[1870669179865382900,2596651411578378175,1834193077299643303,8120095647143482754],[17113838174225687235,7224995886151952082,4762201158946606763,12881944118389080413]]},{"leaf_elements":[18286348947164058465,11377092030570334368,1421803648746151023,16707603233984701343,4379013689828691433,8729476751978380975,7323316470318307920,4596420029769418429,9056421102513166258,13293194514334493965,14511881958811571381,9436290237315571450,14816197378386910985,15122615505320944093,10390551496344211922,8285349748796832763],"proof":[[12454276069602081935,9464837808133476698,12878105912982939478,14528712268168600680],[2792975807591822981,16413146020481345508,3907179070562068391,11008946275232062117]]},{"leaf_elements":[1182631706988909812,5518244554391670520,917746562024176830,17733293859730176239,6201899089295260902,7290692953056460497,5989223798508600986,8968599394470802659],"proof":[]}]},{"witness_query":{"leaf_elements":[12132980564971592390,12236518284604286911,15774373308318732441,9554507392318780171,6823485533880854271,15617945754945659537,840131858253774181,15617595368453956701,5163203922277086967,17120745819779665804,12069680123912863781,9423936053387000811,13902590740456606609,15096909295505629189,102279448622305981,10113867584063579257,10315508944212129738,8324789171925588474,2826006912300290374,13049631002549965932,9879463081932707274,13959918396692577330,3170687718214377628,2356560431274296154,15024902356726453371,16549600649707541257,9949693377394729264,7964216300101898358,16336907628046793194,7747148471273208481,7283889706535719323,2285236737088116373,17238657210138359589,9161227992753582211,15309095076958417892,9695886777785995254,9218022066916423032,12627479664989611964,4994155831137023078,13134317875188963860,15952370424354074537,6226002055724548755,9651845548840027495,15368125538723863297,891477289650982669,14440077710806910892,12726676135005157880,16215744924595156192,8968570470157443224,2084913720180809295,17842305551781239582,11891268076072127061,9212270762049594366,1911547233797871247,8030534139574209728,5010367849835090399,7542818587533485118,437597187951020916,17837627089449733172,4757485796870453986,15980635992226755996,7697307358034063016,16115970420664269542,3017267823937615367,1339699577361514591,15114632510426584915,4743637384826110679,16533801055814838131,7313891366792609005,15816534296312725523,6197399095303003631,3837610277468828851,11236573412853618395,8229237195243167289,8011044710030708974,1289011312616549735,14424772907278892720,9370203343736848072,14720423827078558834,4551281807512112730,12176812801359017487,6546130060130051717,10193034185976874981,4068123933570024481,8822090905406608037,9347727896342999754,6749561872658779488,1162275589164144929,15109566884360120414,6771017181679419709,4802100567571638358,15135899778128508217,2452914965029308330,6033539511917533379,1577798040644149229,17029359216580452956,7728145045941942596,13437934230559381167,729814632956808495,11877138189628254852,9967842663547150794,4503839344898189661,12131846003010198692,12280138098772729370,547309198294674347,1198483807160933967,11277737563401430169,7598873474357341293,7219967750102513074,2170545400323419325,18027977236832277827,2671911476411939702,10537384614950413544,1106602947407073767,4133795241141185775,326739201446378107,16841193281389454444,16968332224876845558,5905926049042978045,155447336004174815,11422251950822705432,4782797184047135086,6295836348763060292,7510121068955342130,8932955849087769758,3244013204408932261,8951367515417099011,3619875081519396213,10061606793761879213,18198696374705502065,11220199973684382256,12891499003674282033,15278728931972533933,1455679290297569488,11704994640408293623,13191725724124869503,3386693183925647003,12752052256533717496,6556062836796129078,9231431806550884036,14647817125377327289,17610379037505174431,11712988307487270961,853487987311679414],"proof":[[14449219133887636137,4337152811680056243,6135075608732245800,191378071313328633],[14106262219540021107,5069955024532011588,13325331646905018789,13034321143416790199],[9222522872393484064,7901241623226793684,17171614683185315820,1671309799085827000],[11361565815337652113,16823178045235460173,13891229254574958330,1830818247948699199],[4164843120140389832,16308458797484396951,13183151141382139247,16892112800337983985],[1419079687059014020,6061952106853808979,6611025607147158388,842852369436531753],[1284545009258576875,15052091730549386968,15359952798656909900,6291688381381748226],[13138058629084998479,6156695042853433904,18200621689383110964,9995448827951000860],[255510503251271462,13128525926794084907,6041649836117384493,1891011317585724408],[9884327106467527447,1084342993449327181,15257753245209432039,13329648106784415732],[4026525344652250583,2002992068190454988,1267945008416490893,8569309854718075647],[10450186829188117439,425470936779940016,15056237556273760471,1606884533592117898],[16409654714386123374,13707859358208732515,4564824854939205269,12309446635756371807],[6875873230070790453,15210412867090385670,12464354602378664878,15915041473210370968],[1014892719475835252,5534399983075720018,15649497001945431568,7866652983415669141],[6112895983571799427,4240048187258497468,16493330722301361592,3110541017215186877],[3917596628354293155,5216102744746703452,567594964081413321,3215432225810112365]]},"stage_2_query":{"leaf_elements":[6987210822523618622,2914324478125939379,882840368849863563,9760262505324197894,4142856072675593994,1907970809562269190,12032644774850406867,3208802933004224959,2759092160677198682,14278250007605983980,10190122472393441759,10773469248576380277,5948557310220227010,17969790645844553975,14328020606994874242,6587519943030434035,10840789610589900142,4980117897414619338,5984741441657493540,14424025864886418275,6629676936192455858,8586506042466865961,3898795192577535879,6494304125503928718,12543244038122419110,15806414591414226878,10102928413544056884,10729581939053972312,16271286395852648421,4008916420524021459,2598008384102661501,14657936391237597673,18005057011440534167,4582712456713828588,7190497631315589497,12036138832401602656,6192487083842229944,4635643506149610441,16356751544292575619,9006751413736358770,8281843068220326563,6532992991804730343,8898639041963234051,8172324285236650388,13244347419524899161,9735029169439859087],"proof":[[13103990583632123597,10227276606259889154,2896683290985357657,154212692497482983],[533139069708931677,10036384539671986787,8401491945129367143,12515722870729033430],[1971585768256246997,6889173504071171225,18150704996545424797,17874056722711332255],[4682346846617198700,15499914868946333992,4262570617100386118,1774549505552823013],[8564137750555082845,2265385945428519365,4410283701556508930,2368827022283742278],[18177468653743604589,9951965110729182855,3938296854659760370,394518507851635757],[12223466712697170399,13605962896131599911,10024660830407115000,13735892687544529152],[3645382985673860696,8448472468672470596,5100180810085645146,13925606932804714681],[10634374441793508405,3241216900804930901,11264998608685670229,851096266163126077],[7739562037954721366,10428922130401410843,14202017291465176851,16889470831951853225],[963597795474005392,15152540296631850209,15330477327548761142,17666468557495743856],[8911936457684663401,5565503966691508373,16779651840242060113,14896289379165894023],[6774444140399679958,15608801145626095067,5057258369079870852,4205453775672547701],[12821429741374847024,14138900760417728097,1563127160220910093,15377545388453462078],[4999927446683795855,1106032345656295935,18082680541043644376,1700516947900960559],[815400835381777564,10965329387145003484,17785693756176053637,17120317219553773140],[2790166171694431987,8776512649030213805,14001141908799450988,12523224147355573140]]},"quotient_query":{"leaf_elements":[5668044820153981967,6725347781281388570,6879073244026419290,14651343203929038263,14519988909651907122,15005724486476798699,16725495237678789527,7646891605818561978,9515984297014962013,6820563636244421125,8779593922363822284,16692972942773861780,17941429771405609106,10059784422372815002,17919778697857383357,1017078789865351396],"proof":[[1500214446020666229,6382265280830968479,16113865044204212866,11337976641962826865],[12507819285238382257,5593735334174676424,3800439540006638157,10278206749192188935],[15882042543735109306,12325388090872526802,10080382965016616784,969417012717639812],[16186977566961334696,8327348046189629638,13697013957835954287,7419251379708430695],[17161381568977889773,3299476984302423690,16672413001935709648,14674746595793955069],[828709193475195343,17486475531008615043,7961170872336821774,15551502624793477843],[4087468320907170075,2559425454596817486,7233741404081903295,1674590803342445500],[17935294082705564830,14627753603281295562,17072406123347970434,6335218320024427343],[5255275668381048125,12069362798330947934,6301958045990010816,17855850595007978892],[12682097454588791484,9854367214145722302,951363006210090991,15687495845905059247],[587194478786360309,14632116369375178982,10039630981911037303,6234942649198413695],[14194096445167096181,1552334421748332864,14722649194040210363,2243225833830434641],[11548717383767212974,12292714841743969688,8497360857481904779,5075192913591568067],[2570942267941681323,4432839070633158690,11909025833729997276,1066280926405428431],[11117642378076169156,1092705557287338393,9950254602380288730,7855935964053626581],[14881425184387053810,17184713853013655860,11417084575215904291,2268517284729831118],[14827574826222641753,2016236490897640195,15541113978067643161,9328589100278504453]]},"setup_query":{"leaf_elements":[14077910014558673748,7932279363142661097,2419049063814533602,3698368628905445220,1383043618899196229,619040463723543754,11247006000833271646,842622125694787576,9697773432604541471,16875564391545544282,1785803652088440062,2126341948193587146,17860529337349031437,4363704820418157646,5643880392155483722,6325928575119741503,17749945813494300694,15796854344760173081,7822915535785002167,6029333622110590323,783791734564133731,1844683343466007844,3378666896238178593,598448107623321471,4045072266585823513,11305967238462580195,13788613383916921294,11152776686480242733,13700311879998282488,13363004123840189422,5906675426055261860,6531525307565870850,13541421944598329558,15376334997655122113,5737200314609942233,3042204259979568278,17448550712176127073,12630814315813041428,5873018214443195197,2358544531239349346,13400475793570924268,4393002578642991416,8075517055548435863,9288711728401650299,14497384465560055575,10606286893853568552,13692144540059438616,392869084207576293,8210094844837176094,17878153908846805339,8332926108646115240,15273065331186135325,602798932031704345,2458209472276390675,8183372963763035914,6266524346145252100,623947562234900429,8373465245008341853,10038659226964904314,10336020656617355226,6509771241528418737,5697889146249305990,14648808113708730196,17950317188836539120,6478644054872570529,1474801954013346822,13709089230585347685,11624148317153924610,17365326448881796708,8467759531381549614,10883914519796431150,14057002955542527918,10626614017985904919,14860045355766991685,3593212067763340768,7923979123037045558,10554185313135516842,16733478841926997863,3338679009043890575,13247807696518338632,2302335395121742229,4984368284780723648,5535052819670216329,4959273094626718863,11865490199006390600,3651941706720379889,5335057963846928770,12086121652132767462,16712452258930679238,7515094752891147370,3138234480400359514,3277378130343117578,15762654253516530891,962568285204819519,17271707099171527013,1111084774362879832,13557994282354889036,733016167912629557,16488537584748541060,5254628334099610774,10455695793993399452,7740765019283513736,10605695587011377743,3985332415876483503,15783715082841383344,470329724122907558,11686020782590140682,6498178891664969955,14789511721715748644,15611051736218911698,11258132494928672686,18259570376480790894,5293544393100776722,15711298222898227064,4083732170721080933,16605262920371183910,16392266667804896925,7284239529513836246,11064681974002243090,15818767054612151279,5788528811829395849,3648400420536247235,10597937820885197851,10475258276970921523,15379579382367471163,6273958883173485247,6552313604420458389,5258185192612435770,5912482110389059794,12443389431808640415,8627822058771371596,5613711294033872881,3707590007686231110,96046764096249976,13534879353657509820,12479105452691621920,18278088943478087598,1866812440937284351,3727270414860118073,5504509161368605457,13032093101814084051,7679208707424837633,10343060331752656430,16053643800006827428,6553113641135763985,2797124077396346695,9417959801112448045,17005492392003206415,14446439392375520614,6264698279018400864,8832025715556913399,16815033319792397295,112739776488275062,17368175962067825233,12906391062234878851,4527634146990718038],"proof":[[4460624826808329890,14227879177477681952,10404962121846086748,966338854455537305],[12462169728080692269,3096568430525113272,3928041783689639127,14267000827469526826],[5237595231531259374,6385276372224476913,13862592314593425218,16791101063906431205],[9573731668518854419,8011920706035149889,3379886130203084414,1040027170693727450],[560876884010537741,4456158151972163208,4748589983450645086,8085797705479302199],[3184835300972199980,15442158790143716731,14103211562241464863,15693826157168753450],[2695566161280631838,4154933197031728744,11210054200726042234,15102027506562465156],[6412183628493153697,115762811952183707,15657954064362670213,9603435154222705282],[11609491129009512584,15411302831364658689,12054468001508510991,686988998736187831],[5887962743768273296,4430462497283119874,491741860564320994,17182000326106306302],[15254981616325261341,4972636463396155968,2270065924626939977,12178467305335419345],[15365801509307100589,17191667674807009210,10951390457764151743,987502607324077984],[17039734879471951012,18122033279330913105,1763066344158931419,10699292524489772916],[14064206278291580949,11092190317171169652,11612376465197396627,13423452926455479983],[10576329465915927635,4738325228382125594,5403335011308195883,7734415700659360615],[1833644971259862079,12190373408006751623,18315229541642544120,735754289676257334],[4934888255329451731,1299074057986496668,1571136916485237263,15408557579809708270]]},"fri_queries":[{"leaf_elements":[6884633451242657262,8692623872074134689,4068894806755813213,10954798157721633515,3779836050289487585,8821892754864107582,9013580954026816886,15301967237768102075,642626991290421956,678431828759528035,9844254457223256485,11519476364640969626,15796015957292356803,4246387041600302308,4148138344740946417,7943684375647536302],"proof":[[6864836457311144037,2653176809229151155,10948748937997794875,4743835444521851097],[3644069696910263287,115054569296149850,5419919591252740189,6431153605657381639],[12102508501997637913,2567081640463430525,12982138695858014329,12004963790740458828],[2681970583150131851,4067916653955213270,17313653853972925709,8225764907123271740],[17410961166166999288,2613878182120223083,845200281820657343,6853418783638936155],[2149899140108807914,9415685529391309412,6387900755992026898,11098653367129453796],[14678718353154848144,3789640641386012822,9493269413279697551,2322135149227193929],[16631500976487011023,4588969120222633560,10634756281538005105,16672220610763136123],[3804837616209548762,4166031772833386407,7021031953234411374,13517316645248425421],[14942718976561154101,13651115472447676437,691687125167245530,16928710966747092613],[1175593161848741006,9382420582848209558,15293159040457021681,15488611536821350638],[7712941196332384158,2234253642028677440,3623094376245498056,16770080918995439317],[8297876022787439987,5765429358297417092,6969424009045859554,11505474989538549772],[641015916041718214,5697532741910532451,13423081019210976144,13295319889382710901]]},{"leaf_elements":[17562178382145072577,4951986098745019816,5899871855378339334,11549258438668733981,11061749098685108883,18441116707434430690,17785246689211282758,17453761558375224906,5814483076022223067,6308067749453051475,10675893764387418954,7409844274478329324,4722708172856863302,16377528791753205469,5296316131753396327,14330741546024598805],"proof":[[4130932721793558510,10101782800079571890,5097390301349362422,13679603096998821264],[5667994579275418405,9215876941678436174,9241866556510571740,3468032746970497593],[12720790088688948054,17270230136577075687,17896148084675500087,627355301927443207],[10062877417760082897,15433512106136387387,8820279618931304202,7381022330309279050],[17187882539819514295,17811128933382715537,66867193162288150,6894693750609503229],[11783129216259597489,14258708814863855072,11923606406040852414,11476191276121845038],[13016460621557619698,15166034347491538025,16795430281937462555,4165386588687813376],[9140051427320848024,15696172125802703834,15132153026331813497,10267851586863086140],[12818563448789787201,18230280399724100202,18362585760769373013,7130112083746564049],[9157312705825459678,1109992508509457527,8694797752288670585,5363340447168050883],[13964360843438099738,5308142120266251153,15132423796157510014,11027328105767835661]]},{"leaf_elements":[3065616578933283649,809469639415749157,17703320139607025895,6035212705805873892,14557627492559837978,17970521708149516602,7573050155133472076,13514905007896141582,2329660015920895112,4477401311668638990,1485734325435684870,18417531379311955576,3686381939923051433,5879942305589956067,14565635342820533017,12850555890183535725],"proof":[[10386801594006951871,12129492527680624954,6431297834656713844,10219064323082317168],[4534539872290798172,12006475551195211719,1129401858224803007,7585612977317723589],[3203910729161793000,9017854101314675219,9668339187278050711,9047507799548497581],[7917674012194929995,1558956610867296306,7399170756154594283,10892821154725777234],[2539793843392839361,6450453583156934903,12629726922193268137,6066235799774225006],[6747782692601933709,13610112329823081262,1986966564149620850,8551507595686945431],[11116643235427525610,14518903188011855710,15245943531208690321,5486400384080011241],[12257679492692059374,18190169789673338868,5420267801344425857,6718007291386775040]]},{"leaf_elements":[16102787223641535408,13878558897556829860,4640172332519526445,2179442680396532475,16053347958250840784,5613925042428729566,13762789628497320654,13003475320867908713,6741988952261842737,1216171137133535937,17892027796047447684,13090432895953697706,13902524829996140163,3528687435139380202,6476691907923295585,14996222948407387107],"proof":[[2643867831413294641,9883507010179198073,6018460768102885485,1614156431741858764],[9865338281839101887,17402543729361858960,836202404772636955,80534226618370096],[14304120753733070429,15277994571207337038,17439988261715131418,1201022336830506282],[12065489398050746200,929195210530829821,15415105721406184926,3929055976248099660],[12203878495608607889,2768485086897537620,12912318947888615320,7822068476628361097]]},{"leaf_elements":[7392993070805491309,11552045744772046427,12496133539668439015,3003604817670474346,14135850980729636528,9388815079706249576,5958986795123143048,13826572263215382441,11512753704284846525,145982144781285033,3583019029112201192,13479869214696378003,1795656544638975181,11892787737611374688,4571898229303955360,12823271620420939304],"proof":[[6314543590119612951,16919554272777727026,768741617701059578,18038188886235418151],[7490477249103747300,14890821926391065169,12528894470063621292,17457008754437276116]]},{"leaf_elements":[10666499788113613538,12946354179588810142,2978942579100575765,17219500348011935376,18432379563349423049,17978726315520234670,91014601379555257,582079298344061305],"proof":[]}]},{"witness_query":{"leaf_elements":[10477497002842894740,8406046702066316514,5324670827393147982,9915137230378013292,2804355991276958645,14789378773989756684,11039486992708136431,5210926684056647004,10781901117161540736,9170328793353173497,15257568655227492674,1014814888636684404,11271703776952683041,9789718954517497400,4923497189872734493,9494076128267914280,3765366577836060729,15515613140349434155,22234901424952896,2364186049256878720,10071689670252400165,10623740008491944748,13976753490782831381,8283518917136071416,8353039225026272364,6384933332742322165,2859061692798718862,17982556858448800626,8864415693432222298,7868671252057138189,13603671222038164305,17524199201108512246,12369684690047733701,3891080350776351683,9908060206576351885,13339072789287583919,7423034754572086079,6276373804590635916,12489266418086249362,6412205009345267998,14077956338373790055,14116350803157232926,2608597809614747998,15915192272936856983,8568089407045891375,5382115929551950990,18004023459908714324,10522841359437517120,3652751917564039372,7997616096484918883,15750377963736198262,7260783528545503530,4697972080598856343,3939640690959710347,4645779972622769293,5067472540765793721,7145512989047070285,1790410587392744123,12134771106711639960,10494739790377312688,12238712828600692903,16886845193995750602,3928803495165496253,17887010316565233296,13307377744129941270,14537882708240038103,15780342548002265593,6993992100585666056,2913869405613285586,13117231932218672271,5412149074726810560,18433822587044724689,9922080446399437045,4164971640458280857,13233949408947546964,11702230578448791417,9637269487716674257,4614402256153194226,3254232249116179169,9846542313654671393,12352100406455987704,2216786340694069473,16453488052258601850,17682685490760110109,318727960677793948,17307708614947958991,1331507181090909598,7073381747789543166,16133784309789263465,4185709073650332731,600698989212539920,16535518968922354184,10366240972862735354,8950653586731304993,6418785217401855878,2561346366987315293,15996859785916261590,3718621390958971324,13384944090019757474,17615392235401212162,5880686111605361972,12568706810065303201,7479150103989831298,9948492918699878109,8143296783656375185,13244505044304178760,7964390037900482896,3775675727643301613,15721690695682208871,7454289209419270204,15501580921950900823,2677614538590562046,2174977118637615550,7521807002623511895,12615267739917666571,10623651086464505615,8349743401982263513,16226196298193202404,15978138775502287491,4060770982852663467,3924608301035015307,17102351528248122625,877935135400472420,1166721668700654892,16705703273524544675,2044531323910900480,16737236516527607064,15943850265419961441,12333988490307274964,4896108906705484613,15511993989975967722,6608303394751843200,8334449693077088235,2093976505390253499,17539451560233692532,14840807776231667321,6642015041619596502,6226212254767171363,11898909533860531883,3817137015012436195,13281458557025607845,6106496748577619305,4131108536642300423,13536322855743274232],"proof":[[12146837507861291620,16807413564308261960,4391280510875198428,15177879281167421636],[8652345626953611226,10329163679340569048,8760396717807436651,9864550844466619984],[6559421410568115089,7327682679891224787,15639804996721293990,2936546385665254342],[6758752939435909141,7473921849691497490,17405481787436564731,12599888197560797284],[12281303693491087053,3277863787273732324,5572485736980187617,10708353949767090241],[8666455669769184739,3485659046636834709,7784344132326297692,15401233364111244001],[6757596543009649516,12872032691673821208,17566623671584323278,4868689011216489260],[13111613379627152867,511491663283491632,4225778835210901384,14777279069087109608],[11477489414184418050,14433522026972119219,93300355230129936,10288730206217931176],[301708461035886449,10337760169999331224,12420755749718632222,9014692331478555098],[6135685216695317485,4918317846396581074,7803951271382985470,4865986471413202952],[3829177578207616085,15638881683030079259,15960954560232755581,12430352098091457898],[11075286537567319700,4307649845141505043,17724019913575324183,10036295847102201717],[5242550418629246874,92570360352761261,614878937710331724,4078521584977100527],[10985303208368791456,13709899495695098623,9629973457805386912,3672085093139973951],[8396869664660839843,4046427985503139531,3237205386988153706,17721058804519625408],[4209660706171061763,15569665661657088303,9863745563231888711,4660762711415287022]]},"stage_2_query":{"leaf_elements":[5927431831831970999,12742262846278501911,14874016658590329232,10339533498986372974,6161681485585455634,3237965469625943189,954326974441622787,7800622858501622339,8260131935205190273,17134392127481534016,11931245690695526370,14731608168849449667,11318165304071606945,8578095660201415442,8792139676520503198,5275391807754081349,13127926740686050311,5740240099717014248,9627178390884997054,2349378554544967423,13507669333174177895,6794482120244411783,4322889742178100380,903225275101931160,2284321264681889696,14992163644123915568,15313516836353525892,5717152095462830184,13656400743465242376,124323885667202091,6540905238278643687,2482788944472862577,4962395432198351209,9579409335613576513,5306179620032510733,10547074523557850121,15892633617807341336,3642156267679088357,673783017028401875,16163320545376729277,13476464552258736881,13652657723074984330,7635467196974026217,105839860293344991,16634003702412422855,1868613128998935042],"proof":[[4471988219852452667,8416627091909141194,8941132573909650324,7129058852399695157],[7913426912911865941,11043967179541276220,15750957352583522505,13583354660821253529],[3135351521499472967,790254743343615990,1898972424079290844,15838190016095544556],[7842222721399922034,8105708073687448925,2998611883045476226,5551696091823739836],[1865650394115314216,921025084548063941,15908006986337790164,8711777424095293848],[14151290432584763475,10095536531188988268,15922687709017370714,14794764879149518229],[17329200591087681662,6095684014085115673,10250238759325211460,6189270939376496828],[3118118332162868323,12209416502251386276,7319946115868482501,4362749076572175800],[5558180096724817008,16820760522965806263,3743987365111567120,13632040584209721925],[1261968916156420050,2991358735202179397,12065163920558394429,634062817018143744],[8683273543689725736,6057057259593436154,11606955062423297960,17379810652029608130],[1531063891146749121,10359927564225554502,8639245941404501742,17133427752657737048],[10099019031979450736,6103048476404618300,14883829959329301977,7615922110322284944],[4287943421651599049,6996909519905205708,16345462682197814357,829047850417962229],[15670819847331207209,3563836220103850918,12809201937394459568,14497708026532651257],[7646490553739686282,18029096139897674319,6731970851428661196,17512975805660313014],[9665480788566780535,15441174219972231479,18344208163066031937,3462579523809054127]]},"quotient_query":{"leaf_elements":[18133923753723508324,9000860313696503638,11880179620259146975,1662401523946370502,2437675853191919767,3638625257156649143,791700911611565856,17354194662042216192,1467077152797007311,15143410763497781528,13029274124909698158,11603527730990363820,12484454517388990668,8494233572203374464,12424840910018840751,10048570918148922556],"proof":[[4544013623188002351,17103434464025943873,7687617740578056247,14352962506779299413],[2641558094803245997,16759501198650399941,8012320832148296065,16431819287354158276],[18121298668957034664,10977982707721593861,14263119560350316068,8908835045374502550],[9551774956698505391,8444137675816982193,12879679204215278500,14595691793776250461],[17139022871593456528,16880566617698187111,15497694088913915055,1487656176383771321],[3891155712695251715,7466155066820252025,17268238158638526578,13372668808804410486],[3883566065664457049,9080225834919547831,11611267454280513982,1032567766943558521],[8899665817500293417,5358838357011905522,8317674612287798554,17202434603272401665],[5045554828576284608,16720552333754440054,7653010261962977641,12588432582838377451],[2798920324432227065,18178488025826673208,10652086686391788516,5772710561308187731],[13661740278344805408,14499087463844791583,9990621142958229450,11098222877477209403],[5042219879556979411,14017857850326033005,12341108040117912535,14171369526300687890],[1804442549998420486,16846260894165509079,3203020875213745661,9797297930882463629],[13719202852684448884,6994249685895987626,7525119765857391751,11768181420716738971],[1529414015425066589,6044917455069492317,1732080283112454500,40493384127783761],[15013675915085111688,2842710086883176632,1159327259408318063,649441773392074836],[7272481940847367093,12648501695579666994,5565709819533877885,8039129685255867198]]},"setup_query":{"leaf_elements":[749059944056169152,9894855214554202877,7902353005215934637,614029492993087720,9153588239134707605,245140930473296618,17867204988778616023,14725039846807207328,3081276507713536017,9844938391265624723,8474887377504075859,14096541104117559786,3728785689235000975,1462702927058635842,14197718723235026760,7102619500037579921,13816687856313799422,6027024050787518149,13582130454952202449,2278740620576341891,16654585407969667126,16760473400401534633,11756593092475343920,12622623641618180283,17179811145568806069,15262567671209118914,9363269454696215366,5530688445623801576,5939836730309298179,6037878861132663490,8589010251344439934,1412492468933812360,17175709745058918365,10367885502468552032,15684199823041523097,1855229129087124691,9197547985253420600,866983256317561991,10286995728080534173,7141513531651633890,2341391745773792575,5672246130662602138,4566198195090406993,13024056728336157872,9171289241227632192,17429334372336661282,11481276729572623918,6811625104848254987,4711193104566216303,4767704580034093555,13342057691799737491,4509264466401727559,16253677287521355922,8902794335002001659,17487318810137773014,17654359115813452201,2828973395160113861,3156710041928827241,727136241880158575,17335916877237460540,13985265599397708937,56787506310629244,12995031999032134836,14256448333740912893,1367697318196260367,10585200052247438747,4384529995294366346,15693162481423254118,13096446386832962766,166035559918135187,13182850354535676810,2147481343021638047,13587651370700384303,771182419540766297,13125435152446591114,14720834146795601619,2423069238026557068,12372285520789815748,13354847174734795358,8060363832253812826,76354990606622013,17088925740137729410,9927397107640514184,10893164757142573188,3909795930137219167,8113623231356115264,15024709093679431298,15812524884238969013,17456713873471453094,2329683812586953158,4482911054986976618,13636937789961679890,3061073412333544679,13553331082407536940,12689325433399907827,11879945005550020749,9768058912091177840,7028452990530139664,5563809265075999125,3456076485947636241,9477326690561276394,12035133355608531555,2711662047169652107,15482873007986708591,2058720537706839072,10184372330391327849,12506620534345446260,10325233273852446116,3824878359936042071,17937142314030328543,12287861926882215555,500037281528608283,2994322986549779209,17650202603379407463,957891018310030556,13147749068402330548,15281338835121222382,16558878405858709664,13271839713390616221,755190429221601050,10522998319458304245,8882038799577583402,11006317515620354552,8649123399075159612,14510952996402078420,12010472742521606550,12002260614816608679,8931948750974986841,7215692666705047189,16154547732325654143,14328976653656016870,4013100197724752291,11515521175953091595,5399831111133807443,4797741193087160767,4931197858824354822,1615253083020537626,7983686151119019109,3565305482321501709,14923967981952571520,18030622473485936570,15014471327172290874,17332331557070620928,15617136166775618393,10538902617136410780,13793625379618780095,1664837782063686059,10876035073348204621,16296605009852580977,16503372934537508196,15277899099880710906,8541101764695874325,17502397923894674835,805695421327138442,4100272298243466725,6933016730528742927],"proof":[[6411562239481810153,7150780347668102321,4463889567315086256,14491204824901906009],[11097178366395522643,4829032594339240931,12986002090117158309,16254717044991124738],[6971855959766335988,18194264582249803872,12962768269881971496,16340981516287976879],[13225325698642724888,2144696615535990309,13327224737868011261,12274672052039993313],[17748113152555068503,17165308861412880072,2190348055379769808,17543331679047706857],[4112562603249878323,15313672476377070187,2117263594037054126,11039711090770732976],[11532185216300310234,12695144431761915501,18369817662649672790,982646985088246589],[17856804457471723878,2588787221130512627,11007982001588804791,2307354550456899695],[18278336203574626030,2535714128220259614,6696250012024379633,1515290146850276790],[11253749498430649984,18141219971662009396,3465632280788154150,10223115014310358068],[12607611319941309012,15437052004023557036,9925503741161662599,4346229975805900898],[6688889657259316119,5034341553864229965,10481336931925675864,717851119110148223],[1500426430459010808,11547274691202587590,13322185519149413437,16346505986943537266],[16909532968410481549,11067087157551834315,7409492506767194271,3961023686324827636],[898927757211047018,16939205819420610510,1877130765258853362,5032395757516220922],[4624068110822808250,4839714791712233337,7066342103347822231,2975375521514554411],[7509741136347436482,3376409090404699080,7106851404074101484,15631598259633138714]]},"fri_queries":[{"leaf_elements":[7875909156264110550,12130064362421631398,4001009671264160596,539603337045135616,17386206691834964069,7104394520819083611,6044419888732965362,956800356173935201,8675132716129387470,7904950367962887212,2302169199392953978,13279411649586857687,6788024294720248421,4408031907080046391,7493213076057805586,10181878333584129470],"proof":[[5554935241695750261,15130068430346176536,8956270719324671627,14889787550485108963],[1106517817904946702,13013908296962900186,5152602442823503659,12887924331064704330],[2436994541749816401,16576568036864317241,14089242227106892431,12340900082635696769],[10660937762996194075,3505346544228833331,11925589116277606267,12019091015579393026],[8992014666565856175,3774770893708763209,12998979034515714277,1248927885005504189],[6224682887627971280,2821566101527551788,11961460740025537598,5788121963420667640],[4733207053184239032,1725728353497857616,4865102668193744436,8826908858400021692],[2403837796131476702,2304650264661488208,13308582824587915230,9306982587524892739],[12368135948825595844,7521778084352598356,13883685154786514162,6979132700558379738],[13921524753942304378,17889220285035858746,9984766609444179343,13843644985789559229],[5128983568353867918,8974817821389471160,12845865994303996905,13627483385299930284],[15099960922874994369,10576811369664491288,5657176972628164090,11310109931305821334],[15662665379730259046,17641414915734853081,15470380340658135082,862978176182788628],[8305776603362009226,1749975925679637043,12013609855588987408,14181483331819815011]]},{"leaf_elements":[4554908427140712162,18267114894578200179,1252179703087453509,5072970868739856377,5844768796330970258,18123897327375626917,4670701712004487363,10095228473390554715,10948378898135494529,11658428833197281657,16253471815197799679,6144013113658055359,13979460202884255139,5457674055539327848,12510658530327220845,12843824137059334457],"proof":[[11189041212657961555,7831195380856882123,6204147950971804494,11886694385692450353],[5035499892454739878,1961903324395392623,16177871156896939694,9101106037846182483],[15796415017229775525,13937689097681522612,4953256838604254037,12965842617132999356],[1668399916635188478,16957939214086300872,1414004049261476464,14812774545751905617],[6724173615387508824,14473959984810300125,2665112406994726297,207868736976448244],[13338886015888054590,8252598487674913960,853836823820163827,17113355130407544000],[11915875312313908042,1902138689073812943,7382556173216410711,8797944715659153643],[2872834427668099991,5685477263449385474,983485802109942934,8431077053116944865],[11775449608342167471,892466289848791026,17727727865644233519,9085730026782791009],[6558311215278925279,15840445465967687222,7772766605136687382,15972645483194393560],[9089877299035286039,13211086284025128974,7103523635707635640,6143338230424736938]]},{"leaf_elements":[8476852840977464644,4752404035872014814,1092517666951690273,9353081096546229576,17935233863862605061,8457428695425416041,3164685623025414869,13281983290604615401,1513228111673919466,4190194786847164212,559070461095310201,4485202377521262369,8676887454094435512,3945389691116307491,385095683631757690,4741774832558101250],"proof":[[12048607141076702409,16314941916464555472,16882419467750304202,8462044725238300067],[12303885784087230795,9841253708293083357,17828178060368440659,7315719902144342927],[12620393735559176352,8816404507450018907,949980504202863244,5147071210155528010],[7636614544007739000,9523574603949347667,3719865722948601480,14649155984924818],[15629507718205052470,15506136390638200653,2376929046329231716,15870846800934966971],[17440799618768943199,6139678357102523783,11538364179401807007,16879327867521515308],[11777973429637587896,2196711819418615457,6737532320013191690,3017665391597334600],[1523028420938813456,8383364562886835624,128497755588736195,17828178017860490490]]},{"leaf_elements":[16608221428421927196,4882183883600845313,1075102645808603835,9241845451796714558,10571910889063255001,14132873555290113525,13258837890909068273,14961696446814609148,1652792067878143362,14889668860677725790,14668163795289752334,16280292122696971030,470614833672807472,893013600340565241,17368953703563924492,5028473259661626622],"proof":[[7807022862680379308,14784927861526253224,1071233528323521161,10588523438357998880],[4956467796252080478,13006382373956274307,10178650484771808401,15770271647627325520],[9239679179100785491,16832673426475161940,7165219559830828231,13879227543797727631],[5022159673865659873,3882161217869360293,12737074131411203235,5268074348042876177],[6261215226436674216,15743080239327813690,1842525900557292747,17693706794580574465]]},{"leaf_elements":[8146988832432016400,4031049489709357359,7908697783540354457,1440221181542630175,10186283415753225149,9860045376790193298,17825662987895089565,11197202384009084836,7717196534648088793,6509681059572037081,9026339780428362777,797494352562912410,4842010430528115743,1984490153396563342,12307213242561184541,8486878505086012483],"proof":[[6054026354341905116,7281874755023425128,8092996408459971936,18161371729260239341],[13176973524804019933,16965119035393196808,5769199517311706096,9495579311777928719]]},{"leaf_elements":[16371276844632437187,5763442631456442294,9612659274689155166,12661874354129793348,4727490084259142759,16024340444489255688,11060965350812909448,11778191179252601154],"proof":[]}]},{"witness_query":{"leaf_elements":[4526268834383039043,5007346849241617090,7530941838835910778,4940254501906817781,3034332747592171133,4352985875955673430,10465898860824176623,11811910951449662052,1534368589456933483,4401030497203353780,16918412691021359945,12680709986925837085,11408435176079958680,15822251371462569135,710050603613016642,6831482047341893374,7124175137748856534,3039257944721583381,614803763483176978,7905808864152692978,8047100132560547781,3102785458368218485,1920366603122012233,6999162581305182578,9123827681718661359,11990225796327172896,9291427593851566093,15786376326503489077,7516312650992523751,2895496940450858798,3577909292982421150,12579142553047201564,15634385715108283455,8419880228191514521,7022296136385069,5237169669292334969,12291149770303473746,1058023365327969425,7308912816734417649,8969812406419370034,10061357393739161711,9350095150867153803,2656998242055210100,10229488404147127889,3050368064072761525,426829319966393224,5464697326959172222,10313442528145954375,6893964478958755051,104108026462400619,10875765930477146971,9418728763074329309,6492608276998010737,825466384681534706,1249357311021407438,14353644806650443003,16662082639402421875,11221522033447111592,7366475367513174331,17780430806894996610,14607283191073928213,4726437085061382483,17443395019354765779,7109940297083242931,12102344951647304719,718672971800478987,3374556199762296545,3943366009280806478,6067669402757094364,454000606825144172,14878824661381345923,11069895947814371389,12911327263944203093,10613998871461031908,5713307622868989139,16047050149598058651,7073668781588871035,14226686782361392834,8892765689736886147,8771410315860378221,3481049859147002094,16453547344872435369,4741517810562927527,8621695389804379639,2716203159152581088,10263790804268201862,14096832779966032099,5571004166654626533,14277998031288128101,9941602504421849289,2251237715893207872,2978026207481961049,16581298734596361548,12821793108985404272,8214954171175355191,4358298489778063349,10893921431672951563,17013790833007954337,15534590158039232601,5516631923821428937,3565847594486144673,3578875558492965483,8511402655175735081,9973103981039757157,12161777544838439862,17710815900611121689,46112977852436163,8289828473869903200,1190005192699481116,10952390658790066509,12254962997537563652,15412607267381172143,14517000597518689646,17336757082245116541,16142140329488888868,1321566937549531451,12190604650502220686,1021253414840548233,9565799990475673127,5881115997407858520,4141961096469220915,17923667752667898996,15009886421121897750,14747575976401532301,14325553796755339289,16558070088204892771,4415340644712459356,16781123062342137026,2214256606257757535,6529585417217656733,723538333338469323,6822283362351339201,13294634808023267963,8148576955081441748,4662899699749826223,282569058191660792,9502003390151747105,15642533100281171814,15356681005219255842,725004379316535260,4342498122502927452,4177059650723308691,6743053407538581230,11353889314366638671],"proof":[[6353220297630023698,3527208243657906880,12280752941640363681,13201493256816595028],[2624821044553913214,14193895006679992305,4744689515558031684,8299838715534997229],[12100524877520377411,3834548683043657475,9025591216960487225,7255931905916762040],[6669742142628161735,9762347712519439824,5730679340604010096,14397376991181512720],[2376876326528453935,6917825433766779914,4593687987044150371,17293323725211631158],[1724326992213289131,13081047826309142750,6052822204646138615,18156954576352590912],[15119202789351230167,9126542613616309172,2085941159947698659,16376976148139429262],[3047862597739367729,3221657129498435371,16793527533684451606,13339906249388364977],[3484469580988630928,13548547034758559374,11559377998652964414,8087877827642448736],[8522723531764830322,5533982180056785695,3625745312183258584,13940448909599164493],[8975632768496254072,155642304551625883,17321719008824573638,15998815893528981798],[3176711722381037903,12303205548022574475,3034492504575942003,2956811392984804946],[13001494979276044543,6312230894682349712,5436797631673658361,13283387634996955885],[17125543799305020858,10026576533847843283,16877388252348969932,5537533410846223466],[15579098262426588497,13865866812732672591,17836250686864857730,10498047853852233970],[15009272789597223464,1793747896466623244,4154965185377302103,1318697924097471620],[14710339626193100422,5166397287786674443,12877026722859487242,10407735240586944831]]},"stage_2_query":{"leaf_elements":[13479299751277169503,18088939189048877009,6469031769863604330,16503705838526192839,1869208687165117188,1659051936309133706,6389194978241860721,4900966110895443027,10473892860835705860,3661271904278907545,1254698677980560611,17465590887830874758,8750661643981036812,3464119438178975421,1166211543989901857,17145246592123986487,17680885682688545831,2915600211959614080,15154011057983954348,274552686085840391,17480846157115543586,9608312888561968814,13198078112162525656,9812969400484769001,12447278128182344379,9456488139734603561,16340356384204777365,5952384076991924744,7850554614622455156,9963744919260902785,4568786002659291564,5458743081308490854,257563095642981229,13812820758277780473,17562529015964502351,11837591910331599078,14304423745349706794,18260507095465697070,17272640332607741554,17896389224452500849,13488020274839553041,13759851866715900128,10831174006588071825,14865174307302064879,6183876224952171977,5021653435450078793],"proof":[[8055699676874850992,15003988916767989062,13311351217135139573,9344910155677298774],[8254638534815670671,9818314171974218531,15545652082037868799,10199266610289057359],[11717617520932314621,4797462126141900232,3353071169815082365,3329285816954487282],[10010032600443354234,17388281681393579873,7551124160065377938,4371399819927132767],[15108229123569262486,13565292064653689886,3090321800429186947,9020888507047307377],[14952885935880752536,1455544687359654829,15127231412205708693,6873118511752160314],[4428763160085006719,2661896083702338576,6268269209036960499,5191156057380441749],[11984388154267216327,11761918919635199013,11438835900193965412,3334329818758833085],[10017519148668450155,779255187849644927,15172153533392407094,15841915719840136706],[8140282448221305205,9756137290243625525,7463342680172427396,7068596838826790175],[6019295920320842994,2486436992835636213,8554202945330334696,5593416843627184076],[265689098271037432,15922653576719966778,1449122800631332810,9078679629730424552],[1236536876540077462,12387136382301184711,17474088253699323480,9072486956559194975],[8183198715699164738,738014075434142480,1354511201448740202,7034921587789332847],[490746899832428633,12992224363703155910,15787947879673969026,3593687760304015700],[11511868158734641022,13379677230417986929,13834832617723560419,8351544216255033565],[1135997963394111510,13275752990064275231,6348311180324878415,7982923292041772706]]},"quotient_query":{"leaf_elements":[17996582858283757650,15877133224841459,8741732261479374709,2072525542191807960,14565743779303010937,10331945249201417372,1284720072210915879,5939090210801417536,6015425174458089676,1501798433067996254,4046476868242736209,12449772947705493096,12708173037017039626,6724387060926185395,11705299260264868618,16560943854874167125],"proof":[[362762006117693452,3215241488593531949,8332622118176302327,10535285819390644528],[14525238762855957577,15923262212079348476,14885914080080648607,17909427967906359920],[8757119317729858998,4046440983365043652,18206436558856751791,11872989809784171032],[10819987788113036909,5652466194477950386,5987922202601758221,10788338085249875732],[18135646362976474416,16602167996550860690,7077471579478640828,5732576759921727355],[10815050581878595714,2007980674562034740,8458958110736693761,11915425126058769851],[11495726536632277193,8221388796606255241,9007460647798355745,8562900817048734494],[16201208002169939367,6579531811554750893,10079341463042169627,70888405786608266],[4531817573822256689,7911250220142956378,9377098825810288485,200866159751253516],[7763446513118288955,12654163604382141020,6967095254003873100,9870644747930855308],[10317265899927539802,13614822980616741251,11725931685391952987,6613125658318001368],[11133930857587230756,5255674720268683394,3389033476094906302,14521803061094236901],[13886858484674618308,11511054456731713517,11286001126053748287,2478166553140609655],[5133280839161038720,12610659432277386232,9626144218036353500,4229872403561432704],[21945758629596873,12996781153543123628,1608033497780247254,14676304894754406943],[743715637329255100,10066940987687814209,220670241976254492,3608508566499664047],[12530437638825942509,9467813558315705039,1660881245341910574,6918973135087974952]]},"setup_query":{"leaf_elements":[6168852792323819757,13126462670288310716,9924185475735745189,2965296160508188818,10215318276941307644,5958339257650627027,13329985033220532186,3889189463331763225,18278973484266443373,13681007107537735076,9052930276395141394,4125024682002595664,6733682723556623426,2522844897361671519,9079555163289212856,3158757229083513428,15009341376483638693,15463534319928706091,11656596819609049693,7820977000249404335,8959201014043309539,4676941855928825,9358090587046506767,9490174299408729597,13269546950044711083,7819649764372311445,6263940412876785110,8562907567183667205,12687624298548388090,7547973023933600560,15929988656062813691,1575911103340773226,3452480803249867695,1269828417604597410,17546471441826965203,11216421317052956188,2775539500106801309,16090915411040542631,4482247924163340768,6545414280187049788,5519683186427326712,15629747614134393938,2996183993390838091,10045806223953558716,6980707747876149917,13495667190125628574,17709866949066500836,14179313834648534769,1816134247225730852,6485424393898832094,14313678161844062905,2725629749703543480,166806015217032200,4774768984549158829,9387641653397167063,6657044845564792406,5592682413341550750,11174130795805038527,16816324501408399968,9127114218216343057,2054916867793583249,5354027025836149836,9901605838691120172,15859943152427769026,1254513951434225965,12198714094624188907,5419768191676348400,15404376370079573331,6918321564675610929,12873600392482602220,2671860795002050923,5215352484220158177,202139753046696847,5409524410624062428,8331297953386015310,4817494390318930602,13944438363083469339,2956653579313588277,10098129142270595112,14458442753364333370,4561334833827844722,4805408224186246905,8130966784216138795,6053172976034326924,17264800974117800363,18161296110541841780,7696142278228596855,10920506780921406635,13492663013993520437,3848986836625766009,259641289984889480,8078733647518169908,12371975947960470711,17784115755562088637,15813190413853679647,9164311918733817111,5039127819357557266,1011098514388179188,17361302892612820353,13422638934640784464,14160000492010093562,16088834989944110183,1430703422527041855,7835632172058734930,5736004100643063751,14442454508089139923,14039186971698168959,7235112250670930758,9556320340147475646,18044476963439323361,7762252238397536532,4608342725731835975,15858546020897949496,6092809423246305459,311464176162813732,4020110649474629453,2287136623190006892,9238355867679957572,13155707141600116936,6102089998445045347,16738462365443614567,11090641590417898338,14363724168800330074,13806606283886629793,7876077343132221612,119452752677234977,9084830511329792607,9166293622558536354,41247969329425828,14776108883804922863,8967683594427971348,14160686353018453428,9850900489464313896,17515960077779517732,15846843667020582749,4134086389342474820,16463542659790714702,6639733298881614723,13697756006987267159,10102820147430531051,4974072928885421817,17741493394410825871,3867951344006312109,12342015607397348813,6868826382029168055,11731977097446415000,16603579216002182590,5564835743630338145,18320600645053030026,2768625565229573553,13874146653955211473,15722544332267455372,2863619498567037527,3288056930198301279,14150940905454322662,14824876602598607724],"proof":[[6847029404930087414,9055711230690805315,11749318645745509668,6686464095723229236],[14777447493976569001,4541875063698845700,7735015437933184140,14301253568067107338],[1722624589109427887,7024927664962052358,14662916555569971970,1860548887843669657],[9128633345736256690,3626161381389115918,14228036250707739298,16778559862339550743],[15712831044087048123,3194505951061370020,15519540579744627548,18372120484713064108],[5512805599725896419,10007028431670405123,15532025807956659332,8784499252837532813],[11713800768742967648,10148234538673160123,8874721767094823529,16307689789178259869],[3201943725721780721,3819734911283209340,10536983671581089715,8003161688669255662],[5801518703258041729,17606069668583374500,10548704863614817714,3549405091040001935],[10476058863325939699,13592480466336166025,15708374636957918011,15561421541502090646],[5851956504137258411,14909812668848737622,722967110207520265,6197702395571669852],[16908858400987644340,3901092805671870805,9190752121981532693,14717072802162039598],[2371940280908767003,2227831686904688576,16183948505690259593,6819303273904258587],[16084715401820580875,17139649039343983420,4931072339640378751,13064826456508673317],[2559709855265775978,9420977012747697977,10546923407583687326,18079878489559260407],[1155622468097280682,5323416548298108832,8022893987892584074,11953756625309878271],[11786672773418549703,2339467107386851422,12140533047963330746,7373381974425188538]]},"fri_queries":[{"leaf_elements":[6536737208838165739,17249159640006371676,13767572948116688810,2516998825754651306,388332272171288264,12700098228511575443,12867685145501231186,7025652357351298908,10051053681541981695,17964704814597870833,14594674015795468771,18277832141903311630,10465287365144011281,14339893844125228852,6260813261256123696,12066813154766663202],"proof":[[7723453669268970792,11491774789370187442,9460734914539154922,5316641379955260266],[11293835378125974389,3258320166948000117,3394228613098110210,2158780778237716910],[6454971730711497509,7027115757363548836,7787455487473535998,10729867545003096808],[16101882104158438142,1562667412167937894,5385510715030396491,15426752241691800928],[13464280845497212098,14628855211076383555,1519310631074309641,13117682102695991811],[7744505544311950492,13674666152969945720,14128574392372018379,16970287536516996971],[4342253147128995090,5727709925794079366,10736727241272798680,2015998134424667819],[7213206274891549141,3930993609643687724,17673445339169076826,1638909492307573506],[4599869082511111677,3863090791427460485,4976836847767066772,412107408737249947],[18403770757462666079,17288378842486198690,4746957059905235445,17460193858140928009],[18115450878062651436,9152656500398518652,13405780111444924178,8685051947409958058],[11948194080735439216,2463819223034670666,15701834681935596458,12070105663219033374],[9910303583025534766,1414356923107848953,13001764951355095740,3311228748280393472],[2065112813907786203,6898755846797313237,17320045911186699311,10677055216998779661]]},{"leaf_elements":[5614007467493719527,6503262366340839315,15584630572821921513,16498593266847952987,12482537262753337869,13595789969312910006,2165422361077433842,9330749423163983321,9428670835932372726,11127657328278558301,17478942670850160566,5100518610161713862,9282499493140330705,15843750764590795660,464895373280537308,17732551421625053757],"proof":[[10790712884751664063,9021107515434467458,474428894591926868,13413789275163646788],[3227273819131884845,14337532857987207918,17274988279788960959,9202799561991865295],[8371339505832142890,13855805018851170659,10479077624629608713,12672891801794802863],[15963931307679198270,15924550192751668576,15576151615316790917,15623024381813446399],[16635879407810688840,16550690244716926279,18129903339858859564,15912731857341007363],[6459224938217821801,16566562977063724109,14594690255957553056,4856193209242268474],[6313382633861915078,10980323783462148276,3969007149837459555,3299968345505189777],[5645737817601946018,6587930092089236297,13464879524137976417,12291823247354636936],[15643732945916809190,11266243715318254434,2940805036850120554,14074173594759758235],[15586760640357510652,17199437880074354068,8452752432785340667,2190745931362611588],[6068200341678021668,17238405178273883915,16254243979175388415,6326469122072930844]]},{"leaf_elements":[10194056904795245152,3333016191472565494,9835725003527969143,9458241766391563393,2982221860314805784,11259265914274678939,601817202856648742,6310695883448990004,15176215543828502970,17002316532982965307,5053836982046387101,5039567713144745983,4984909859509618320,8721980444474352612,2189977715879085280,14368929262414567532],"proof":[[15331487571934396464,6914809789527058880,1105090226218646196,14945707375794172162],[11748654245012738490,8720642713029214346,11515813804153653634,11434734957024202980],[1333663144659652041,7410315369766549353,13608580545625803028,3728231209390816614],[11877813558170512249,12500196283383136515,9519024970960965125,1531556265592904167],[13705266667328854523,7748110574139822780,14715918756834797294,9160697352495517729],[5036421843426609079,2717960193275286909,4832191221247902823,6732713160220783492],[383955214807640705,16818216626337424042,13232217085098681904,241005896151116121],[6284005312668722525,13175024327537991261,5546811104920909949,2703000136490581107]]},{"leaf_elements":[5903790659010133386,12293963651478413275,5945582479254481701,9178357066591916279,6484695814169432519,17682641788112832877,2871903237843931601,18350168810450922662,14563817790369774468,4679100031591930708,13457058952516170364,5606207746644359688,7475562758202354159,13900793087067010758,16237898650593741535,10918244431301010688],"proof":[[10895415551973258311,11083174536631075269,4898328213406756068,15996704094995595368],[17821878836551654606,17448112396751849516,4844269611241526509,8677006151663820295],[5413826987307175895,1371044190043739939,11039913453499570096,292260259255786948],[700619608235653952,12943330703004030898,2480455716292619428,8323977305965432970],[17991506096714915795,4636722536725601757,13865614444769694335,8815772354958363399]]},{"leaf_elements":[10709399384505901433,8410325356231090929,15561720818054825268,14595136295749910987,3096112296966750560,3421660690568712333,3091144484682138335,18310247230512460785,9482461499428884128,589864126313932898,16665152423982453751,5925405038121600556,17725199030289479468,1096803743263879443,146129809745760679,5540267174767141550],"proof":[[17994419247383461759,8679941398660402734,3461954500207538403,10904733956278157357],[10835623355140351544,2411159751067968680,17855867681805886030,86569936236411870]]},{"leaf_elements":[13912788208633012260,16592364955197622110,12930883254427910878,5599575569218380943,5682660096836901399,4069773254031359724,17686759155637027087,11829746095036037227],"proof":[]}]},{"witness_query":{"leaf_elements":[11552715707386823726,13650249126910778409,3633885269250476722,1144446624765627305,7320981149862737698,6790593384135057355,11243387113326552377,7606316851073364257,4351740839399227051,2326114741295006048,1815499072008389230,723943952957083119,2392751934781737971,9697864153322866033,12890047577313207290,16844428319850659206,13668775918664240789,3522973356737352367,10523866557823208653,4597328886638043591,2478125786721470768,1271311473025158757,1451365028583467252,12087736153532672382,5844326909192746756,2127880404925533255,15971555234478296730,12272129650828269914,14423755299634259888,15431585626501476827,10335642799313370681,7908554249322512040,2945089840010419370,14389535592569171112,4263985444204319497,7298287552168843849,12461767890722990509,17480622301714353086,12802562938492790016,5140954922357938149,16444948796275534467,4712666572072510888,4167088893607452578,13049953205826498521,4325274214583279357,2041461190815053214,15649983060449554144,7927088379049740293,11706287336285671996,8361570477918973,16747245019468934626,9770304532874346731,8060592695701343568,8580311332098947780,11935100247899711527,3006428297716200118,4891183972371533202,2710589350479016455,15091899313171504639,17351150804774170802,11819148356572862102,8230605128773161065,11137931373201836969,12933021753223182757,6308787992741531287,350588495762310944,1290259843533239714,12010202742121983274,9264663391839557866,17606445519381768548,18020072015672269518,8921107576158417567,197795025054593188,7648108247024719723,9180369316732011183,571265688741107792,8139007330157164006,7527949700780625630,16937794892557674524,13485365957343209293,1002007500136951957,11620559989027211427,11203964537379649853,5034937694924762753,7113876128467217558,9130210118168045168,7324498850366321051,4259815224803114814,16230551546511502845,4022470721223927448,4152790704501311159,15237613398190621140,13495321308139305192,18266841627796779043,4601731601856071714,10547473855413386251,2499526862006976685,18222701777008654533,12641967013650327721,17705549973498775762,18106223865097367908,2581448898793701715,8926169824263102097,16843035649660729539,2126473254859311408,6496827830035794338,16952021587778396088,1276423982875417929,9958519268972254475,1022144221395471633,11694104277261141611,5929659209770369510,7363558249358957159,4689420286572379079,614718373437676075,15095261566770585079,15806215049268526653,15268921095615399293,7940640839548008833,4686064068018394095,1021261827745894993,15205044151507824854,565962330015516208,2304577595479273511,17432494199382202254,17749677836946197949,17586187071919631360,12070317861919908904,2790646234513940145,16084975005201326464,13665001515293894660,16206549444478018321,5224027625582300906,4816647625950629642,8613149559542819008,16997646635975825860,4416311652145968000,9661557290569556700,13626171011798711255,14668619047782286927,9398982181833153735,17954355116216741752,3823118249344645819,4939809609522492854],"proof":[[7401298169354182885,9198613479208682113,11918540377611220968,7972858915477704174],[184547022408490914,18126899314576416740,3736184714926642245,13992959214537039707],[17757436312164677679,6196745946268433543,17438860160768435862,17851490988682461096],[4662429303085560990,18289280228161406299,16945158745413516678,10101481072922412314],[9684978047047872374,5532882270371206841,15355479539261121208,3027777815862808682],[5061891838909530343,585983652291378712,15472670855997757761,3368684232779005776],[10454109572863118585,5895392468316002441,17327256873580514671,6508498047940429805],[1243582547515147131,12821335634742513006,12708637399433965065,5762502640660129063],[12104834208610837159,6265797147635740401,8388630213684143471,5758441855259265211],[3116692699790244108,16684270451004136085,1299459435551039338,17093239187314097352],[8981000275086540413,7347647700393155457,10019287012246641651,1694982678887347697],[18161390784910784927,1166315030486009066,11219278471020624413,9880108201304772216],[6450219638148886640,5724197100945772141,12055598377373503373,4503731715310713563],[8137508611682258854,5855762844320421239,16354737363349070614,10558026841575125842],[8694984196385831170,10377557517300121577,1303216994812448465,1093394040747371251],[15346668047248116441,2526726310755198274,3435646062692882897,12890230126974746074],[14592655159823375692,4886438218661956004,11773371646111906104,1577097193499964970]]},"stage_2_query":{"leaf_elements":[14557665095182691368,12601169447447487280,13632865298232761590,4062348818426097162,16347597281017818457,8959483180840086692,10874852350792719679,7856555854701158255,13557690052312471870,16053049325470338381,10562182977184098059,17357619753807321437,16534376389579718449,14088916447757286388,13410242785825457063,15616837657397229306,10147111417382480179,8296431386256237547,17213181418232412571,4984270227302594944,16966905153676606847,1633809087562498402,4134978025063471774,6577409625674912161,16786536653181626234,8412226793173263026,5146824136306705838,13240614774936161839,10918741744102070609,10340143431649983148,2262415339308038288,7993889048490274227,238299265262824964,7483630564878422135,17067810139587070328,84168613644823158,1519541284038169516,7564046755772952362,11446685937084990795,4961652923001229543,5142982816413178456,9829979004835224789,15341518575493435433,12070395380797044341,15951535722217292961,2579020834604178316],"proof":[[14648311616559449914,7935709867012779325,4892830379940549872,10498013922620328109],[3710073944648079017,12383545489737293137,89105979598506377,15286927968447057929],[6575420112690281782,17788055199367169730,12255306702039001669,1379050733720596679],[703964150639830822,10933856177259875596,10015201848962245906,5315493864023876757],[12007821808196278792,8169825056588069341,16420399230179207250,14480916868259421150],[15498335575724157644,1627139897662956433,18164110554062722722,3757207870445824295],[3072798526807463292,7834134263499718562,15189471549943253515,14844675904860656728],[4191545895409638554,6210530026102335095,14435950549533403127,10731263791714249681],[7072782243831277769,444508035909386581,17309199191922524914,2268998520083839759],[371807157237400292,6625677688856889838,5208084044969844056,16516747801784215930],[622922014032189896,12694138162689227433,14544914120650646818,14589609698489867430],[2146183527969667967,17770801564986935333,6960663295187378592,8693290821996993099],[17106223265327318157,8477168543739465187,16504592997297021186,16063423192267387796],[8279886929519359676,16692403396310744128,14311590197381956767,15970717827132947364],[10545993604532934878,10528420384796372810,7261146220497387840,3242804158690056784],[4551867285975537203,12482358037606313884,5878331143723473561,16657304009053288735],[6300385583840829135,3508707821927913265,5255373578022653255,11410137574386606844]]},"quotient_query":{"leaf_elements":[12934991074197405356,2993419431765829858,17181575871208181290,8014902612361466282,14450303704174802088,6542153138728836111,11231245529848101352,4034669826730897848,1108143210920637010,2081249103711299094,87588315393813632,9183068881905917640,12172805424363868339,8254505002417413761,6102509851483898540,10648765293082885698],"proof":[[10516208447565015872,17238497285760114467,13666301564886793471,13194462969942330228],[1181932943294347596,10508797822479226765,16950842325803718770,7709134748509799503],[15582884748289878373,9243877767211645793,7172616754350391421,5960109849890472623],[7704680997625494423,15080953190552441340,14268961537280834882,475357742439738398],[17958479049226036847,11738047817704651233,6094889595933440924,1625408353023878832],[5133260700760229909,8709884739974736605,10582265139081767663,1199163255611519686],[16326751554437958373,17094794186828984904,10227344425730055191,7278211510866234197],[16896033204426642676,16967689444663400783,11444739784947723659,7746756561309955987],[14832155221757802125,10852042425431608423,9889414802501967042,17073268955727504592],[6998053485672782915,15638677357070359302,1559588553976239738,13030001703716774692],[10246929636803127361,655065453241713283,8025589606595850881,13670017086946637021],[3961339232963428624,9186276487805507852,10719563367097710613,13756044186554335806],[3107246410958514185,7384376169366024694,5032336558073650928,7194796732849161685],[1235396319334814848,11802820632454788368,1200752496264341375,3818641202823064654],[11300409796497706097,9731925357132144884,1094570406514492297,14706170954544622210],[12737530948504826777,16198149493584598394,13562122960665280839,12900254218326374689],[3678234868369141147,5283638782478520511,821763301433200291,12666613813678185860]]},"setup_query":{"leaf_elements":[1955516938171788026,11411565875178503885,8421377933752388033,13820577632914044519,2428189900896554702,13466706472956803693,6603984122097671172,6970402154451475669,8437589460151229068,1885694898391758520,9671212843937089250,9310452711648270488,4247584930964113239,4172788054812500014,1998517790730170990,15107964821391967144,11026310884245577269,3050892459295841088,5236218365743502754,4567710376575702298,15928221771709446883,15382883350249245810,11543047954843404021,6764035630425257480,6290023739039743800,8153535225910925413,1581885010136804810,3086749484068102115,6845479612347810771,12016334311413868095,7760058121226096683,9636423400403088478,5483786030273877758,5529195577297641596,15089905279213270582,9786037287057436596,13376214554418469258,5406553745347057124,16104943514250998311,8422050136329975738,10768873982624431425,2162887424739240885,5486255195604909585,6219564013002085738,17843613264594820927,7383806230058749000,17103577769251156262,15523144567457947475,354428248319390749,18391648382671905085,1377557898399934573,13996896654641283657,13532203110985259480,7015704606559542814,12978230903465027235,12028288520613584280,13910613722741282168,13376547427895363863,16837938311163179110,1037892435491239277,843166631303603136,6839654295156093568,14988349976371666764,4741604409636062811,9831065344487408609,16714211142783630821,2076541467464306348,3054727018892440872,16792846468149934299,14469509904280149355,2984004076417046981,9446078547127428936,9889798215890364012,1538011129112435561,15998895778984673997,14721842629157073658,8935532235499547070,13294994665186721080,12612388513945206203,2971865105294349391,16814662479634893026,5511548257186817686,4894247709745635114,12305911526835569435,6047033018643640354,11406091112413369804,6218935831926533423,1354386597481881955,16363027206479349646,1748529831463700830,15231798023312856082,6913422830337720182,1476026204643877568,5822360999858356899,11880079159972404127,17192046288256748489,16732287566321761891,17579023911217816731,12220729024934576515,11603081400915451623,17935367017478880115,1106655254264166453,3442802855988626218,18155585491553889375,3494273967905047357,5446950843301233616,14991554110611164973,661745047920966941,7892085634916111007,15823823703205801782,10312441594254594419,11554733664050252010,6068048052696414201,2409970097666383598,14908110515347762521,2568170177644596668,3771781665231862216,15183369720992228913,3499703018403721673,17906520175314258478,579826097375550676,17082039046016714649,18077400635791330052,5802407278102108258,17584758608422607428,8551349042406753413,13986444937790191667,8669865498317781002,3340456941127929515,16360245516150632049,4488343837097152250,7516094004968248043,5796087506091616464,11291532446814020739,2659238188194297797,3369091604929147369,16586161372944998288,17586405156305072621,2401025728223205043,18341965445315653888,17594999643359896862,6714880298665833462,3496869655546657443,13441542257373343573,3437974159780136139,579453550794514202,17738109322549407634,4843334173228326478,4225517445514431762,13895025343118192793,17029244553516332876,15774546125441453461,13078071656079381594,3292085303154942745,13287183222884120188,10534787766471130950],"proof":[[9031885106999771931,5006411346102444757,6159742070478721552,561977792449287654],[14858172910296404134,6270475129171839228,10989004181648007373,13032217258193837068],[7332582613599677005,1392804950054304029,15148833149727144061,11202928741141521889],[8326045242637426075,3662054310417414559,5701870244606263744,16064663877395201981],[14225363230825132186,1039299082276254596,12154311054774794011,4083662009737259236],[12099313272023640233,896896283398594313,7008350594561626464,718817187300403394],[13033789756911908279,3061076374271964225,5974526780328778020,10810533915766954482],[279995398065572874,1465477114754269,14861754124438427506,11203331378710341613],[2435682594219964307,5130213916766619659,10119064491609396029,4231059437895622733],[12870622888796906705,11522839198646796082,8918570532346893707,3543100907745676182],[6928374297844571534,7725005404231496783,7218574274204170156,6981287840142015751],[11616864119140125464,11418927037419666287,6948807235299839683,2436546326541107597],[13955613438460057163,15425357621222094193,16992715692019522766,5856221123280919643],[2648865763950453266,6808326315801217378,11255378763008622469,2200284983376021543],[1306832656619515287,9764804451951828868,6479109755049317156,1962897658694048219],[1604331307223421191,13365993051588967226,8588985829317977614,3926111662093512656],[16354204956433885405,13679537276615897443,10956784370045293126,16160403238752695896]]},"fri_queries":[{"leaf_elements":[719570890895564504,11047620937326388905,16139640137686966509,8000763487807571045,11598176198451056013,6674450007402316898,12300459740417390923,18099709868539645848,2567706684567712394,2554345580102475919,9944028571310275464,11769441465592176317,7883955002058723979,9219133519851408700,16686438022559518811,14802211680703867094],"proof":[[13302141312644454200,10429451915485803678,17364703659228093545,15425045513596781486],[11774549959690617460,7086800195605268907,15223925648857755300,13148973315440394382],[16663529916700746296,8909497206316809318,8948639563417018889,5001675306358580975],[13431720867987790644,2819559050997907052,18433652890392067094,7647529531022422279],[16864943552816106668,15868664383764859667,11141367347418821967,6223963078370768093],[10081392858292431155,16066139985243601628,17146309192424819622,1641735188085328637],[13353727606886635090,17999443332023512371,12245346739597241280,3424958754977401123],[7352504687647310349,5911145125247257785,11504998893191862944,9317528522457388144],[17223942279658445088,8937271338522296467,4650548469942051747,5960456757167393858],[634167519989804287,6386574796747018875,2809796335891007081,12593472765553115817],[11476590493392317427,7480509271030032116,10686135903965722242,99623947424102660],[10464480329745872290,18095765198530670135,15973523973771035502,14445717066983072635],[16653975507766997525,5852361545422212783,4542679570729558458,6286968683788957014],[15841979698184688428,6766978167612976972,6988718529989188967,10317852718069604352]]},{"leaf_elements":[16354691761531883763,2624464309239739030,7514086582286795681,14806290442633950129,85450038011018839,13547100156633156632,6019670967698748159,16653542023617717629,393304321896871987,2372863150373671700,11625964168663763778,4609326097123035966,227022363687689590,17470389399536098581,14045715211404151275,8555797707859827911],"proof":[[15053067545887223977,6815119701918963822,10913000231700671645,17206375739377024396],[12686689024140079860,4247596485677513063,9870433874706824640,13514551851329494167],[14366297851212138548,4675938486328677987,12778855329576926,9704531409240512186],[5846280663965101968,6363310091474123959,8491451533809893139,14751386803120569231],[3554180253220981153,4638346930036897435,1520350135925642368,15240506027806357606],[13848129516404363504,10384026634460096883,5629537999235516964,2541972974347893316],[2103773419216705859,3075750162851246350,17324594470052054795,18121900479550072291],[154797224536042480,12010537174793965595,10403751799067532690,5036096589072284302],[3328040420158164936,11165030521055605488,16709879237159342819,10050784542656473286],[15738158813134786993,3418264850276457326,10335140839884698714,2264973671078968161],[4620940820684181288,6218150265279905101,4394142517619279316,11376274407012839491]]},{"leaf_elements":[12235002128326449331,3722448386839127148,7033544125148452682,2011239291297120592,5308032169750687743,7006024943317629215,15630394796576253362,5076756276486084569,5736216031572138357,11482013194262159897,1683242541755531243,2884166961982461106,16398109744052679640,9442670336885621179,16963066219580467526,3037177616651462731],"proof":[[3722868527574926978,8958346625722784737,1061524533837807665,11620898149454573398],[1108434567417020726,6316260425757120389,4495911809880966270,554990776301257244],[3048442484970304780,10326825208812019475,15501638508701255086,123835922116415406],[3386250954219514127,13955244007380830881,7677743227025685317,719771410440390200],[6091288008839088636,16906752255943282137,13878254740913414596,5744322849365894639],[176306145803066522,5103082738707997207,2246879073538169788,11813999213871271566],[18157687998917215258,16763460318887211847,934215623952467888,16511182297630279563],[13141057789689340553,2448709708255569924,10951846470074346402,15630920576161203827]]},{"leaf_elements":[11184453654207258652,13479915145919538527,9422577556551793444,7957019455081282939,7536211513887694158,15914170627176904555,15928081081966925745,17849246727014504936,6836983417115546223,11650684190792608997,12283527087989012971,913907329657906607,8893186538158956396,3669435456191859551,10301656102993033058,7314278845107578981],"proof":[[15789993644125181025,5675006386668348370,722552271137575560,14631144309024861851],[14785813650959399347,2697240108937837453,17773905176894375180,14551062159270954151],[11702396021756725980,6341214669014431916,15614636811617511183,3329397537271826463],[18105499576403946718,4385796141796696880,14788005547233371370,11971365134580477349],[18094368428717041921,10947070686492808250,14391504912823517373,16135841269932707575]]},{"leaf_elements":[10436843727865497361,17846276555127019869,5922784516808728109,6563996082027773457,584050490551381099,15548329999239472536,7506827572629213845,9991002189841428580,5484499667580979130,8499433419154611987,17438216066036198705,4590668035734578888,884955262166708534,7181494639364029331,10730017351734604780,8530100638143981646],"proof":[[6389906513795140626,18102858087891980784,3468257514373005665,7876526185786639359],[3419541161667130895,17696456370165664112,6168864541569884414,1311020060133671248]]},{"leaf_elements":[13912788208633012260,16592364955197622110,12930883254427910878,5599575569218380943,5682660096836901399,4069773254031359724,17686759155637027087,11829746095036037227],"proof":[]}]},{"witness_query":{"leaf_elements":[922442758311459288,10757997575762010502,8197940760787480379,3730450478730976152,18208652893278483261,10625154198300830180,3267647691760182424,8309727435793544233,13187591091853573339,7469062811800812900,1113550488606568692,16098688755540950202,3302310479437579013,4699564832132584042,17722007729615779305,1293658763056956580,335741122373946249,17863180446996974061,7560562781721157327,6014006554505701911,2427318115434094417,4729345397585624826,6216175223439685716,18251316442378369928,16141006411241292432,5626794103460331664,6231396408144559126,12195617970730082173,17867208123338970362,6946251483784810357,14626734244080687939,7861712150067767902,7947771792720166194,1467292950430988770,94421610939377311,15388794461489974615,1868354100195351686,6240964179708580494,15728009161962140447,11580792047468181929,16239209464385061570,17147443872035330806,5702213852597419764,10282606535354242809,4014648077216672808,17703263163710093949,15674884906816767965,3550466930883196330,7461722733187464148,14431236720013936141,9530802986373630922,14970706701932364098,10150974307945116344,13594596192652093607,3782634499822102378,2573792458509583591,13395809244818193725,7451140424713009703,1836063629862786646,14295014784963219816,2136784686519705569,6192194732503331419,505497173865116991,14093342849652513194,14733044615091462896,13944164922690600867,11422978858256582852,16012577887608460347,2182623471936467136,6025892570801119321,17507565568073770038,16693817423495908053,4106950598851108522,3543768151551279709,14895592999872828966,16579998006178464785,988019645222668327,324320117375945948,11142615454265259686,9328549534740610237,17184489253242801919,10580475858766027025,17711534117162504411,16930124465731658361,8180626260377427586,14126163522033835955,6327688920892236111,586414989508470316,5572437811736563841,3160278568158110609,5030837952620037020,10961524687318506615,6044867521574639758,254559405981715136,8510873865679896305,8745092553289791573,2094367138045017833,11332079968575403381,556037172648690335,12904991496172741833,7158585816048847953,10262963863160901277,7048965591154657394,4417218998658977475,9593358386231175839,16427116957124938619,3494607034923353882,1770042855822510692,18187116346260974791,903062084615842750,10184209343597533791,12352522956030017074,17279038164484329034,6466785257222787399,17294196940673094454,5658948000961143003,14784712737081460640,6183234106952595554,6062606189204945835,10830410790331067943,6769472521845291634,7031532459246552656,9708403274988987589,8671974534707489451,3125354675742672570,5303035221136558109,11782830960357572104,9374389735220760654,18228637132251082698,14369110512083599356,6557127971013104378,10839890234308034995,9459994682197417675,17544581352976974608,16723569867620150220,8275970092507060602,9012731189392402360,12359299247544738790,11841350581021418257,9681065724903295178,12921117090815352932,1174093539627178182,16123679597518211289,17513629746159743509],"proof":[[8699578790305188815,9041373296635945263,7287560646506543660,16765976740219781735],[1238107066901592741,7529046061201692943,515057306874199937,3069573165655831160],[15424217702526364760,923902896979913314,6537223800838616838,4052853556584776273],[154618540863692159,12505220439414651092,17205906883553691520,14642862678534589311],[17531970011291322326,2146598581432347940,14559839281893873187,2026471595065732909],[557740503677533891,7404670452520842759,5349959711079699914,6242865578177043957],[9047071447201699595,16922378725529386019,16079878135678320944,13095764636915271590],[6657979554209218977,10775560962635431702,13951536619926714737,13058184002727719503],[12590114287335792384,4410887935367961858,15694717778441858062,439998260751085219],[14434256150981484024,1756330255328730489,17118109968815860778,4147717830026986863],[6798919040581327033,6199818896593972089,1557229879238283713,16980246361598177299],[13119339309292949967,9635473826035978617,11274573139210885376,438001985064451135],[4847756457301555319,1645179045085731100,18064933395556175244,2094029873342025830],[7764175583973500148,12485042341701848425,6364006273523567092,16645004919038639331],[11570365403514652091,5131108839995309838,13436096712837637085,2826914455136052931],[17907250398855742610,8678154903017087161,11473143306396016008,1459438111087825539],[1953798436690953238,2147321071292191388,14284794412897050288,10182010349254562119]]},"stage_2_query":{"leaf_elements":[17836258392086567878,16847956033014536800,11933767070304632357,2183858194162132502,4161709179046576023,3280085170615898211,17600798338612131432,13774690430915215067,6661796173554528521,4765426796263887,17937197037152374751,14509293801882128953,17361817347976700717,14796777754153357033,4414323382908612787,10945890889707638508,17561578818381715196,21843802805261249,13807534345056043700,12517486787675580231,9780820426497383398,12326162666792979678,2806557020135651859,14341805164466751271,8388099184841936057,10336697017826166367,14677290054067592779,16053191856876314982,6827699772667830904,11674687923700005603,2480998291087240407,15306064182673292302,17995857914231991797,7826576291525255183,12141173291225658564,9867275717361217962,11164331864215379536,1410087579742409624,12277460083686919987,6180245210588165153,18398450729113864560,1192990494990770900,7645527767704118968,11674584791878564390,16794898048525147636,9261239123514288278],"proof":[[13151504832496436195,17211767233309133542,14256520462757788326,4308076196173008906],[13257851272868729724,12376130649491392675,7661567305293448577,2028243662523862102],[5043593847812830277,3647791146014053216,17682221899725761182,18207444103344040126],[2145879050342672124,10803255017828078995,17713918303753987919,17670214158617981472],[10859060410219965790,3097554899582485308,1741664093766705792,13557800101540186684],[5654212211144984880,5315545351788588837,14130634682404960414,17783970843195503253],[14693919603663600799,2432866385785984527,9301412607470502263,27010729784066331],[296540890687294239,7344644735549004129,4640528301686360217,15943448818866129769],[14076173083711862866,5789281495590731439,16087306375658528292,9110200413048047993],[17792592327427936067,12065316794163003306,10973390361330326324,7449075705689579670],[13602123342617282982,632516341858646250,3789887055311250505,10588667979334772639],[1346782186936068341,7010987980046224642,16580359490688063207,5249907796727681390],[14399458094985930382,2444029179237144814,632182600028923246,16550775990090096329],[323117525627969507,16964271343244708374,1054209335605652949,1720308389972206763],[5135443234391372159,16881109168846730603,6801740906229576173,7343428589293605307],[9975604549588905575,1824706258669744359,5392396303539209245,11542055698015273686],[4885762215220938472,8498695306163120439,15353549138751841550,724186417904133468]]},"quotient_query":{"leaf_elements":[5307661719131079458,5465465510592080179,10869128834535021519,11489809355612208037,17399868118199406329,4889764012584375165,8803121867894995686,1619024662843724629,12388542331257293730,15628582765329083135,14905262090959589480,2650709010364134813,16234609279812606211,14469125483144357504,11694510606286932434,6068765406358418660],"proof":[[14512577532621661021,3437128455425712547,14979310789741077815,15383088174966260688],[1272739311222635547,6082633779623103146,6065748767947616500,8237945829573392490],[2074842511478624700,11272593194195634799,16210003902212828320,9625281323879858742],[760103614234130459,9623835506754858116,1840269611121955695,10859624306668360271],[11061047534306528659,7070044382678310577,8738681450368578796,6426554483004265743],[3549750331044920076,5454497230577152899,6963310328883073404,18221915264818206923],[2007785492386476793,7815732518394060303,14917138549105333790,79124563828128036],[15297753995951624973,12969507201588328053,12532795200750068900,4269871331861520245],[2625404783808244018,12881564628313248318,3678963821033594184,1975534720827338489],[16914207714630963405,15811286265691632216,11075895550238018513,18012497650523321851],[11726903200933088012,11732755463852095821,4351762721755730565,6759594066450483890],[12396077437916390306,9820642823536008214,11930434883515082165,1197849956910991937],[9045983757143980963,8337365418494381955,45119603733103669,2014227179722539003],[4400820244214361148,15541837358262565337,6282162906505261973,9445169305880183680],[13380447701799521579,11732155157571283402,18090664594133313237,12735064449864221941],[10003524696851630151,1663844393538571562,3435398644819706821,2451679245357733173],[16596895484028765537,5749472348574443297,15124699585505040979,10983306082536664468]]},"setup_query":{"leaf_elements":[5991570525767499938,4928266891806396749,14506794411556417789,9845460903862481907,13123347910527310070,11104960313541866588,8337626668811263521,2917127678267401674,17767670978101206163,4745426634208659205,11142251319736431500,9357956308766908389,5609616184586828468,15505300623722194115,4896252185531538462,8073089594682878891,1209158912756019623,14640042246415781692,11525212715002596257,3452191619760227075,10280443709715668692,17544832772947519179,11540655584858274715,7400803100035511039,4388181576503983615,7636756457749223789,5871930184301644343,15592846796259685651,7307625157873716937,15154091850698479541,12481878973974818037,9368980236478523721,7696234720836301609,12270657054577667619,972249140297087324,5658388951602488274,11440772241447173110,5969409407799966152,6770278636860824716,14661607354198164006,10673840929995820071,4616248439147541146,826290726653270559,9329261603256037192,18124942298341586868,6427870456186649500,9089882600008082810,15331379847038613770,9783649259579642378,4690245139638821467,14846792010681915955,9551133833487944295,379041201297300382,4750500908440694213,13777956749571794787,7537760228505121340,2685508690770640511,7585388171544861186,6429831379639795079,1168929190195028929,6828388582724650163,9984987772804649714,6508178614527201223,5065626015188536176,4848697108999409683,6682413171951753765,700205906973783228,1344451460943308362,3499547192438753399,17614985822200601688,8241185547640598811,3880426629791624744,14065947963419617852,13768985044900932908,14130890908253114590,12386757078034781010,8535069348775439770,10222349138009865903,2763589859396840339,658192487169950715,15782802364541223040,8068604817179309198,9714724051375151671,4664784537642457061,11009497351437868227,15888821000285131480,5642674470635645204,10345870595566408257,8879955739477259885,2039701427436930640,10389082030362038027,12847504000277502317,11163890417337794935,15782476486724800233,17187172888151980997,9867701868726612097,10371296375347062322,1227416708552460462,2734557001526019020,10733721243116708676,728299821043313290,10941819778783698162,3289523858931015774,6215340938838591532,12574203516676918899,11931750827878454495,6210237482423511375,7285261380736086506,1736514729501346197,11246626455076923215,14748694319218975770,24927362281875012,5247894428439279462,15884850493443657605,4324421528872133061,11688235331143786211,16739191032182936818,9696253174811626358,2563922688487841638,15845848131340499527,6648155036932743475,14055172000842914577,14176109478569842993,11044248542276171695,11400380828943027838,10364884100810119051,17643186628493880790,16372344212336929370,13320948054501576935,9982899484499775120,1106984110572963565,481260131191285734,6140622922532179423,8628529606515442267,6123441414392296193,5229210526883123534,1773089112096925807,7799540034043563920,1185882697071226239,9823717997634660982,9926376789569999480,15465179351702123690,527791660637738785,2457021659186440243,8316448361124508565,9753841546488059261,4878024680749583299,3520841832458877414,15177454900104460632,5643749363623677774,3914943134758445442,4366035465363512787,16773933374945514733,16661260558052264751,1163221322822393980,1703089729442863613],"proof":[[3088874696976513682,17358747272949638145,3564623183745842923,3228394835043022107],[14163718649308845957,15859999403037534405,4090300071498179260,17986075333594717857],[13145335137918360477,6518800019822838247,5148073840495908501,13235508478920599808],[15827463615817668871,13128958215250646803,7784521420818659663,11977081687595760808],[15223544402648120614,3639883351689026539,7768832856095362344,1723668107561820043],[14766023577001810543,17828638606599369893,4640427057614280184,10509902657556263705],[5991624436415449927,11688461797227149600,12529316725221853061,17338250026439436312],[12637474542496912773,3815840629421035992,13759153227268744986,10792436796612526863],[2066004265400264842,4965127513114296403,541707777752640843,7726602754138176422],[11690671374793833044,15088123299656530102,14706703096916514676,15098298922114166802],[10603679187458070348,17319394628090394438,11820928600274197560,2722982701890535618],[9507798739439870121,7606284190128121800,6951875681597709660,16377914834148311101],[5619301737102924011,14775082786780715279,307541062104398644,6889290011752236511],[7259430778143046870,8293017620574525991,4133439522070424510,11234377026881486478],[2940521838520616775,11477928091948012626,12167581423934155205,4955877619143175140],[18047606209329986503,10738227401048529214,16298149603797539366,15495186002013996416],[14058783525262674831,1223734685381543111,3472322076695179989,12739283938439908737]]},"fri_queries":[{"leaf_elements":[13397915943826870938,16947895103550880162,5783389743945307663,8275652969588621896,2131860148633275655,6376082162412486952,9492757825412376714,16888978187711703689,17964403399841080854,10984216941289822344,9198433062046983844,18331824506285458989,12775061593678700102,2488549923333640572,1793653297345847638,13041907167404322407],"proof":[[15698219598118067328,18297617932320989380,15747117213303248350,9362533733114768564],[1964457888268997240,10112773256547071326,5574555973326188146,12522031787470680098],[9772279868473040195,10566849979528879441,14648295398788841557,16275560248016570841],[8953471217008520814,8772276668900963447,5777464127986865965,4895560232124945599],[9262581939344839053,12824716544357372151,9468871270201625258,2322211581590091276],[5364728823629425494,14344916585464748662,9233317860419211832,3333079980786366775],[15639707734563158462,13785101656869701447,16271417181973758638,12916035736287379780],[948854478180077417,6529505101529889784,5275694498737932442,12485923633627149793],[17850690558959119071,10217863393066617355,17346796954772572921,5221434162623217039],[1790136992174139128,12696089152356255502,10958451648141598660,15162096148412735652],[2812768679214768835,4092980877222401628,6184159480298575966,11058982784693650004],[9081840967099004440,16297800312546087344,1934588819428312997,10796357708372011791],[2986977370207837202,18300972849351820970,17739195549338001345,16074444311480818131],[10351333275933153941,12142588681261912147,4012798614446165582,10948289742999808665]]},{"leaf_elements":[8155685682220752606,3824239235411814316,14317023257739722373,12595042713335509919,11711366628836059124,11013235121414265808,15144541099133410812,582539225536652881,3163431298967752751,16630924656635095249,4551782994099518315,16394226000236118736,2467881693050827253,7359928572033863426,6785893792138916331,8751225594020905760],"proof":[[8623859370589984193,6468177526539511319,5877191136527214004,11834156385956686369],[8779148939508431102,2014896871652204875,9030187973565399550,1443319617964552900],[2822554099847093234,7564307691392821169,8466236771680640403,16378626700604247895],[8076304776202734257,6426932622645052224,10214010792018043524,8341193752164394754],[14151393013608437467,11590213114343015709,1138170072208546865,12738830820309397125],[14956279408351798736,6895215915363241488,17893656778546261509,14408901927552705943],[9775460369958115816,18444659418710685990,9965064174978136873,2862895842269176168],[4828681860859509595,1785371461929898780,16281724930576194279,10294968503670216512],[10453808489991199077,17586271292625587220,2524452334099466042,2676509106699777609],[3921395357408339610,1815982159148549213,17359695498000327935,8277185601112428886],[5276127892358659024,16578295356712318542,15127043412970318387,12736306873740238832]]},{"leaf_elements":[143924188370091504,7907335201150856807,9596590549692672102,7619985072698213682,3253549821195592701,13459173347241162134,2644407729803278190,13974918821445061017,1343967457027817769,5835341306263741839,1866740582708397978,3379327275739190714,4879130307177786622,6949444834642206758,16381013527069410261,7154946374637394842],"proof":[[12227647218871936988,11677635736404281267,7855652007868679649,12130309584382618469],[15287430521611478922,7101048062266823551,2181156135270439319,7265642224707551036],[16671504215688559424,15592648104893349752,11144440700350789389,13648772807945586900],[13865131234398391282,15785449107489905440,3033695275957115029,12945043522187092787],[5486819472719801351,5705479126063846689,5952615917288955841,4323652854314468826],[5061989284998579182,15928242000425564085,13559441918700527495,7465476271954528828],[12967370157233506634,6667836837318204947,16547997799085215030,13027721537280115781],[14020349378869571117,12637582428669394796,15734502401402495762,5695164799417959082]]},{"leaf_elements":[8065486774780727294,5393291303671627427,16591399022383722304,4854580384518945409,9105808773771145965,10443277458216773356,17979919629591238478,2754345096871462510,1727547927276227268,1404430232833566145,2102328717767609356,8127588210423447064,14542007065242248406,5871876136638553055,10746462661940238399,18183108236766273771],"proof":[[4124244922184563416,7202605483359178097,9364997729425715915,4332278109208874162],[11034208515549849546,14494702719609423617,624033261352765,2535093821690603735],[1868144444317028745,1395960387979900487,8695513133646423562,2330792039904582606],[6679635891365566143,682205358412136840,13896968747246606838,5224070476772127426],[18349052270228711893,11686217883027640403,17714450851383567286,10630403265852227136]]},{"leaf_elements":[10287523190471247348,897210614073718379,18441679849373382329,4485827908214150765,3107282490961492465,2351426309246153571,12315507020173417032,7341251817684311007,5276673695752053540,1845318109484277894,11441560554184134962,958403972325686093,13803900106114871682,15521248736040797213,1648730060677547573,5538801914434055045],"proof":[[16771983573080283622,17536032010488196217,5988464352651277970,2448381212290990025],[1572026914896846847,15703434778445970145,18039674663595608947,12269104932850371711]]},{"leaf_elements":[8872244034292046542,14961388654118324654,5802056968775514489,18302383666416428067,3933647026650259001,8825851261617385151,8616213839298888053,10450361630528634353],"proof":[]}]},{"witness_query":{"leaf_elements":[5724639103916504522,2289917164504172182,16209405542005269341,7169478834462436912,12992868146008509412,18059847969878455520,3809919027333223545,7939790012219483508,10590666501775179950,7847950432656233971,6492006175407454297,9098899646352496864,14081102854717110054,8766400706658010000,14375155506917685736,8514035739728141873,7115198983304163386,11904254863169546076,408666904275587231,11909643094346777174,13927307209980522961,9500158810156675648,10215962412227635709,6126965712074630983,15992291321315621742,260987932376908448,2365925121444471752,16991679137661050159,1014367279074783801,3443511473068099815,11332365561018941818,4456450552099454634,769851178858850984,181197249433710999,15662037082035504918,917134809394046683,17188124216586376445,14901397989531890187,15132223884751251175,17479983731505888838,10545485550568096708,8065414857256774416,8419892368895997962,13827579129399422086,16845938598349176035,10813391186015789122,12403806400373826214,3570147495507307279,12777784704513460301,338916511316194162,15842925625572716822,13526791408272182024,9865554620106573281,6090161900036439275,5710406252938915802,6484836796287412338,10518207160305758759,12543534798974746737,14869163752014184923,756483738848616665,15412506692464173733,592105835831212462,5585614922996701818,6147368653541082504,15947818125443923667,7317402067579422061,4515028298339948341,16441520507245855425,16460769085449629159,7440257908904331527,603352706954385031,559902588137608653,11536238707588255443,14255521502467779321,17696425254586589989,13990829059907277628,1143953485643673996,14190751232841747900,15404823488281486469,18226770696247099059,8771635523839170109,11363963264087962693,6999597287596179328,8364199394007946042,8927888161557358629,14039777223657273882,5515330074312756926,10927632459241302368,2832628531182238617,12293095819540610877,12001716221907092174,886500271942709256,9686597233519820939,3172506551503575741,8188590838891212006,7547678316848721133,12159142784198217017,16770996440579287662,11456567043430173859,10534076573862801615,7732586431232805866,8628751309942582207,13413588241852320902,17575596649575950551,4360214375777798430,6842146078172789618,12237371785673611360,4753665285282742005,15315244291962349780,8213898724488237699,8201099977373449536,10550685815006909920,17136094531920702474,13427901358820454306,4925235910908031758,2715533638557736943,2296490545933768346,2854604217156801977,14843856974852636290,507521703802855377,16208479947963488597,17351289248534550468,16063501898683703560,4686800430040263627,9296486739311120511,10097596236791508141,8005063970264268044,10137672690823946739,12535147403361764404,75099801728816912,8602431123798211909,12854189167227465377,7337932535593518219,7598380019063336923,15189689516582524526,3259640550887675921,16483987714719295194,18150913050767267080,15308655009182294311,8990967005623573072,12970116944345713840,9452314917309248389,16926594724221366975,1981280247811694386],"proof":[[12022677472226963721,17913298779207257539,14673495840786579780,6282822367678213742],[8598302101088082722,445458135358750960,5149636578981575459,3477543094306723590],[14410942524941348677,675866589371112418,5070324508116057898,8175218012929180659],[368892930798260328,1961553487174240156,14904764897793120327,3491645119041086752],[16639815938621826883,15183975236346910672,5316348835862020028,9802261458695527262],[9538862498024128186,8594847655612468070,9827842794013806393,15163248674349818746],[2389992078052098789,17409675495938468870,8266354376525747944,3250227817861908636],[15304453078767778677,10161777382990845174,8717327243000306767,11432273995591130325],[7848101052130517233,1419577088312264928,10462397055232659899,11236731398317879639],[6497554260509839332,14313462652083508064,2568790827820223125,11906124312721959298],[10692112391609062562,13652730886460284754,344838544685866440,6831129619583220857],[9256750090946359798,6195576108749903505,11569382056554426208,2379337198073711084],[12171468388752563465,3974905172621117607,707886176418403587,5424617864171359525],[16813931685102365799,5825206935765550028,2650311132652818727,2796713724659760683],[8607331835335745171,5198647886119040389,8029907983066020265,10547498145789355232],[13239482398054249942,2673767639284143452,2322923916887495121,8336621435945842114],[8962983601327175991,9655400076779378322,9372067540546984264,18437205832166210823]]},"stage_2_query":{"leaf_elements":[14938318172860876625,13343807100800957809,12328963868584161357,187659058227741482,6181020420294132859,16448549796423536721,3553974672888134017,5267061145172272656,16264071154606067277,1222578946931416828,7805687370880658504,15170079872701460195,8523332645863317489,6182921864499318375,12077800345031761875,9294859847574142258,12674398294468541274,2674744859312015495,3514727488798465487,7265203092238202314,7937895456522327730,2371619939573864089,990533347192277426,5320608900750764479,9392252222412420188,10004205452945619183,10984137506183847456,6904407522651067724,13806819163917324106,8442040979626453910,992877015820268127,8695956500043236176,2077813020930312018,15031307705665212593,1953620364152977419,18134232091018771652,1872536037310990890,1834671901958374476,1203103087877351827,11671248823321009964,7626967877819326820,4912589922270542879,5843642646252743713,8699015547282476490,14506202043415769533,13305338808791859679],"proof":[[14918428453944033003,15776803792824012478,884065150506701605,12428024903850391879],[15330326499968421115,13199303399870444313,15651840416467158862,7579295826199275449],[12271772498431564805,441287445215801840,11493171858972146960,16112177292869650055],[10374102178399818914,7116435912886503814,6523062732535983289,10806412475891006540],[9044671419512851133,8778536327771361576,7314884484014138042,14896191543430213526],[14633666636678927124,14645039514975191525,6032322489044869859,12438741197521566570],[4709246111980343062,729023948248095392,11685910481179942894,8496473075850830937],[13432953038778014343,9010559724758768973,10614942387537755586,17687784948912521891],[16351466542799314953,10651624332694560062,17672072767270240395,15939873301986676623],[524688644619881512,7040290219789755729,7380581046507396344,10433692266940495639],[10014299857088676238,9586490996629304215,18138123262759462019,12035228185452305485],[4970037015940752331,10220899103832988816,107520530470454562,9081136768900615765],[6883050908451920084,13258490328327274825,3362656289417267426,9658916423143002879],[1066574399309555827,13861956427340046859,8068094826638353963,7730774632107968837],[7588865767032220312,193914219782039569,7696748358993613800,16934781195789449244],[7868377146465893942,12855249661258455866,14376170410156481376,12632632809800891006],[1911347836580775672,3246100548763748938,467751161131197312,9129819829973384756]]},"quotient_query":{"leaf_elements":[9939356140369799951,1866983427579094335,6622416813423396457,6169871759272418361,15563108174138580993,7677961428705143495,17334661996391474441,6191511919462455597,13516974966449156824,16166692185878351266,3740771911429863964,1122759493001070358,1829292519312733123,11880124001103009678,16441265095094540891,5851183465595391535],"proof":[[9604366690191179827,13360990862129011949,13294122783065532946,6464982112670305790],[10834412256628216449,2553937548204968529,13398521777008915391,3557841818292959321],[17080715258393858997,15118133311250357164,922931481418023610,9791187431477659179],[18354484335600669519,15263683383857894375,9881132475463374280,17792817485385510028],[17001906819266288035,8324707495365116725,17184585261469829801,16556643354576552964],[1690808241867475055,3855980353132794336,9219003817785560207,3367520214422868040],[97222433655649368,2692378469124405568,18430136375602882854,3146765731992592698],[7173772378572553594,4022681678075440121,16028061176636288526,17540583092462259337],[15708933328935286775,5121104142902395072,17270430299878288583,18320157877133246106],[17594216562827415068,4864732803988022113,3554782846960713385,1585647563713420358],[17278564172126390355,15861262025737836245,1307465624687996323,15599007317178906437],[17968143651393336078,6343643663470436517,10100993998626151706,16231234035198532363],[10869358835726026339,8786592670801120292,1067552455154773576,15199038818399629532],[5726755206137347640,11504357598657247128,8453423272579862173,8494886719386744077],[11791972715873763438,9131695644539513217,13662595149188886189,9110307681402947124],[3750321380710082681,5816539556762857119,376379246827409819,6573078953659508109],[822135299882928769,6832536832869235243,17165440014740463881,14363198558232023699]]},"setup_query":{"leaf_elements":[4743675405352767774,11814809134573051575,5592304246149604624,14749450401556232417,4156394858895936348,3338051855483263872,9382275781625714753,9588110943553261140,10729737600208160008,7985231272698705360,12264707105533620556,8715764070860109277,8338498619194367865,14342572829076821262,17444544070301522069,3391177080887613283,9952209462826350621,8019289741476610740,3217396816052140024,4784353203201475841,1635068554892316381,8429502460737633223,8591907263486918779,11631701647809216247,14746217989393121642,5829129917299224558,250941141064966165,3394862473269490635,6916365920673291557,15997342636091583752,6513966331810297232,17614175028165021417,3105770070575856585,14614776509748547971,10112621233936345028,1602553297813470170,6852114268373419574,10465662345542161175,9095176830388621531,15332872280332176029,18176081215824916029,4109546696607255353,635325129686720048,11074952167205044449,9883074087785522017,1639754100401955022,8926495425269614125,11541072319176668135,12522008830938243012,13139511852105469158,8895569343213879917,4062099495279579919,1910386732305504145,689389963068562408,15910662288591897065,11021366230227760821,5525099393651664427,3111074328689986016,10236672441175495697,13227274429846143341,1331208134147174326,15294331341342618597,16123579141541194339,16703575643262252391,17264926359878484112,4396161188992037773,9973215782760262593,14368143052305690028,9289995378241390101,12609528423710700697,844751103204476243,5400755566374147178,10452896480887124005,8608437829906426226,2864000242460414140,16163371318044069307,4945045744976278519,18140822397567159158,16597064226068141234,3957543286984331651,15012246780930594325,2005832849613854920,1976281278881400628,11738958779036150975,13210403134515056349,3459434370791748449,17219582905940044396,14287377419159619849,15570831240275199027,13378188770624581309,18016861426981151653,6075192992266024350,14328371231766618646,3247672141949102655,1098883601136511560,176562477664715490,1663458950386276509,13581771457015168674,803800992384811750,3093053668379467413,14414894920421502146,14507943457433042119,4511167355898521816,15054794524593022330,369114746077410974,8498807852870008980,8422071172430872672,3082989614733269481,13711758771329919598,8644123029323090197,9618483693422523634,12301860594582652746,11391987689491339639,402961773411297884,7576139499658278275,11651779623448653613,50904892444931773,8147917668079548144,12940242305022834506,1256147020957626662,4924993971426636281,372760599745800421,17197735182419091156,8255170654123129311,8315975702613972206,14951982763586094457,4648912784274076056,13039755705086108112,11872486496766053325,16716263699969158946,14365442379442533379,861931919508431749,2985272828903321772,18338304023511432688,16741893969764558324,10739137414027099747,5844214715960410990,6129236283267019634,7929774522370510666,14349599070664377976,4038580681517710658,7600902632929431668,2263929039989731349,15831840899168185639,17461879473493130699,5074339669772891671,17629082704295747288,13923371816654681359,14512660267600851672,5883827868839787080,17094994612018440288,6377974614740052612,9362162865948900807,3055267161598600354,1160183525271239400,1430403342114687958],"proof":[[7526851438461913012,5709938879651452586,2281225966860913827,15673277738445548228],[1395809118246031918,8785980464292610128,17955564243819479390,7371277378129129293],[18050047053748378050,14615497605706625704,12552825762777287388,5514321030767716509],[6180204231407494099,5318746628775884898,5660457228528853798,18058967369971167978],[7473327842308697362,14467325891751741832,14268396488159907710,17276927111308896315],[16993455883935009001,12710676642724770763,18251793523708036443,10730995968712612098],[17022701980767664402,12129457082486740663,12046143395580346947,8904949409215328713],[11043655108371336171,15181963815722703578,16825024442695580708,10569735348586022637],[9056540224149996747,13147014928232113389,11721222895023794643,11930854007388629087],[6774340935459858619,18195117430750592725,9560929350774033570,10999676413424678791],[5218361711950935335,716925063547578866,7125747380395881046,4375805245787176327],[3003050229408030489,6121496092745291975,5083786187706897548,15665096224231391224],[15756672942519370749,16074711355497705026,13696263220648647550,13022462473875923444],[5429260478033976428,4621875931443180758,11301723517424046019,9830652928388405242],[9843170289675800805,7995296849457435679,18405160568102689865,1598108397849921183],[7763034114238797210,2612653954970864313,9874548532761189295,11950095805038490746],[8150671396367591155,4374957965196029991,10091316552250686626,14304794448001423245]]},"fri_queries":[{"leaf_elements":[4540323811732595366,6315368707914008684,7242407201022182107,2777888998008401620,16229057659681113432,12889899478468686231,12855031854549045041,8462842855323448429,5918291291190988851,14596616570874678614,17210559160296164074,15000361358350044991,6215192805484360511,12132080874454384376,782195967885510705,18360504281823728729],"proof":[[10243360425624329641,16809592658672826665,13890986603547093152,4272165378643966243],[7041025878491431604,15549404957991292091,7632091701581283257,11803086426826258065],[2462494551267956418,1976140994864773300,3759995384276386944,2306017805568211741],[8320851416651557024,13076012895655144133,12667178588603917124,5390331993432100585],[9243699029388891479,9223811726611969891,2535819837412839425,9520254112505673250],[11302531819765824645,4140646396742332551,18005258670593869267,9914035816546406474],[16931739820220579299,8272421091613144910,2733803432459694725,10028706579348968962],[8473388142568254340,12363954361302677611,16710265677884030359,10035079514650217706],[13212075939307842319,11872535553378648165,5362238111505083010,16673009782675931438],[2276869002312310789,12401813723099263282,4500577639405661464,4220881837525096965],[12804266039777223056,16617134972034215403,18052193349293890632,31956772440529670],[12964310144795253432,9359572043478289460,6142865816189849397,10075952539003905660],[2036743038621850211,5423246773758321676,8041016251608296685,17855908391359447905],[9886176930643768256,3509706781999382685,16706751567586875992,15900181631248865387]]},{"leaf_elements":[12513731750195810475,6671926135007327111,13199273034170689127,9576897592066760462,8181168849218576550,18424898230645908122,17210320690824923737,1415905110499200498,2006229190090816706,5155681263547073444,8335022571399563157,1628529760041901577,16576023099286601651,16009126333354155148,11499015879237704451,2969604523908934319],"proof":[[1565890954207112093,2878493173851927934,15885008417459296466,6169715250246484457],[12940768073897945450,14328069787978029434,11953729865858446946,17132536488531874588],[5105236920770024705,9855535207586661287,16655389080170975694,1182115077720963373],[13159307396523625635,1238104595308189132,3099979952921426312,9204789396636293200],[17988356703889614878,7592976855302187605,1692579413642763385,18272807123782107542],[1324867912688693108,16453186601214787160,6619762080785909612,17752115918178743268],[17494869305395753337,4961433545005658623,7911884974694246971,5116307041215190463],[3606198615680283068,8341826419673431755,17045999887938912802,8300154233453410827],[5026636560436696287,13883418723755199122,9321075151687256125,8471223717683390813],[7449431501732386882,11031208553786558036,13638679846530505981,12224306339616136851],[10540896754816519323,1746180075358321372,9865956469169334927,4589766901983917581]]},{"leaf_elements":[1796545138338985215,3484572919585895530,7085612092304264907,6089160605952106109,7188003031674863476,14669965468925820393,16294617742765384450,10599474045360556297,10633643836319094331,11299147828191075341,2456928471244335033,15267238706621540551,6783700991884609364,2509206650933122506,13872887014972697928,72518675394654330],"proof":[[1830399293959224413,9701916983859038841,8881314782024994432,10303837338470201430],[1218879069259005180,8155738191137078378,4055729702935778513,15036670355692589945],[15188015420307663230,1443972785254896526,7261898789273661035,12217802353950193718],[4464668195902016821,1567142276250821161,7318222863089100348,602040788114977681],[10614996888964200154,2796560394353300974,1204347974457658853,16839839034326824896],[4663954751585035587,12804534650387228562,12411396753901938927,13525409144612957816],[14450638296737090204,1943028934310837098,14316870729705224232,15060349458129626311],[11336173358147927605,3544125422924662561,6152060134110928826,10783791288329227367]]},{"leaf_elements":[209644660992467470,7981236624670252726,11932920748403604872,4361343008001914034,7643521429816577838,6703440668344515679,2465083859564679079,17291541084766694631,9303620243513280971,14518020312985471219,3479481489197743092,17766924277817490653,13984420254708705247,17804411537871026809,14977985963247086579,4657640788002236389],"proof":[[1765660568392667954,16612828980820299877,17777668650555512136,15728030860423917603],[3584789609523557763,6774249465229561907,2318642676291387236,9349036952032406618],[9709768892637899703,6190342253731074664,3593410900898446460,8749794855477996890],[8431282242568030943,10132639644794228227,14548814393084832958,11257210547446171232],[16976949461203448459,8268644666328080056,14706620297076897348,10709889567794796744]]},{"leaf_elements":[9306828645540789088,14829391157001254424,9378227111629524164,11716745019895415222,1848398401099685924,11084788197227462359,7893267969825095172,3640734689388496039,13110229117454893753,13024444064704880195,8942605042497989081,18096099345285820199,6836986349229157748,11440143176033232175,6539666487464362440,6381810964383519537],"proof":[[17328635329280208295,6571238372153749382,14827737472456699520,16135031428133869750],[14983243035340635343,13554744403256603391,9231851320950367445,18031029812144592016]]},{"leaf_elements":[1275295786118718478,7488170357634863325,4283449960128273261,10193008459420986025,4238185187837649128,6318479223569512088,16394860438500661164,4148361282767282169],"proof":[]}]},{"witness_query":{"leaf_elements":[13342357507363825738,5295585531670477394,8898636051726604304,8575907528634466252,15122303812888819490,12948397300613746516,17152449189853543937,10407551142261049595,20691682448381416,13414802790316657110,857310877859925347,7504683891494080163,12762920537374419057,10877149011244740093,2580751971665185911,11435654315189054900,5292751558668245230,14099670520675058547,3119509924885429004,9787068606522464324,16742986206552490804,9635262281905086522,3027341062797072879,5851493154987871546,6108276056076944681,10076508498720482976,10517309454354728940,18132945197639265615,6381133000000800106,16121251603879884095,13313121931048437889,18153927370465873611,7918936036411572912,10008319296520360262,4037536033164143780,3390352057741530725,5487476246121108928,11141726975137985557,1069142527907272173,9294406215638368131,2579573714553244955,18364526667184721588,3669142378907939228,3404281856800489307,17543301229666659784,17213206791359241168,15350222691090546656,7842828201778763521,11988723954302018601,15349460790914424304,6229901468535089229,801744417136771866,11626357553613040796,3561982469392063092,2285043582060682165,16474289273111348626,5999302326410027695,3471838863065181922,17315712085117192278,1844364089957738595,17943255534011317383,16301842831424488666,16717188977444246994,9205407134397174272,16616656330032289492,12357269779379759507,8674333124338385285,5917985342841472530,4599539327134964503,11321715480341617146,3171604934547239634,5910455989581162687,4872705531403656582,11825135399939510480,3459659842011900830,6263794107824840863,18408462056110593482,9217786861399928003,6031408939641738217,11095503567904161307,485694058869796587,17959530696711749201,533383624159816147,282978671864803835,706778276867464281,9301440713707442636,687377674154234897,2577156058473975985,13590609883429836178,13868202398097961692,4889760902981073598,9986803843215980734,4751687079307724497,871215934940606123,6137380755945996746,13362245077467000131,10621136025334130070,1116019962645888089,11960502773121146522,2779822607173951221,14045761432740776727,17633527570376017502,7924857230867742609,2355392157928481001,10341038905708531881,8853313423030247655,10414023617158266927,8814996202751952943,17961392034197389852,6258322326999406369,7567837247430084463,16211945047901045193,2979565812752356177,764433182337046246,18422862299889012326,15101914783437647719,7326654999075512770,12329057271088812861,2485293770639488077,17208518511626470863,8848490752410991533,15256184403534343798,6716079914659136768,7815285137770537910,8080906666770081304,7492174049486694294,10251591279410568289,10757508970947433202,3999496187172137440,12234175576788219620,12931784833311259895,10924231931400900540,13890842675297187356,5401101543937062028,15235383180636298573,9448570866800507131,17583289811320378543,740140331898429023,10848468805089647561,16295204097730348798,12213189851135269825,639055171691319390,16957185591939751253,10135871177360498143],"proof":[[17179580260952452600,1544371121156072785,13475457998832991944,13723738459304957120],[14063504047179955966,8583255095440357362,13758779598546855709,8043972384385682690],[2389134902299753633,5707453332605310309,9003688342394033335,5248525833896687519],[4824859737366439596,2618069817505737641,12178236919082431175,9686026559978760549],[5428481079223792626,6199936612574362956,15781174217488327745,9100640838110788018],[8339696998911388265,626713293720091548,1346736307136870478,4056015620928507918],[7674984443705507523,11441695058138920390,16017643404724919904,15397832677513386963],[2678980202867088375,557979961491686180,16062831548875536113,608158947238389720],[13643619077006731020,2071802867292067185,4482071943089292286,9066305201492422943],[6356108634134976228,17853415264480678256,3427194179448673208,462654865215937991],[15427603608227617939,13049107299125386948,11421543772995161,6334830872109472608],[1731142344910135215,9704577252865892497,2506900752408523378,15905783351535000272],[15773026558347686787,8941110883531957061,16128044707023393947,4103383067921866244],[2599110953492299543,16445433041266899079,15310725646533348689,3752669276386948495],[3190744768793536238,5187551680543924474,12462003973924477240,14938803969108644071],[15009272789597223464,1793747896466623244,4154965185377302103,1318697924097471620],[14710339626193100422,5166397287786674443,12877026722859487242,10407735240586944831]]},"stage_2_query":{"leaf_elements":[4331675916899798253,3725899356709071473,7918739370308550050,17280264742357788929,6221119363900637868,7774403364168879499,10468051049520223267,13081285166377029715,8947272661676429818,9432316943246923576,9749575072278618618,7809290470323093041,15419054324864633648,2338561623234307141,17537396089727205271,14794029216906721339,15593717907342895928,17521451544926946657,9900639406880132893,8931316809054675107,17973372112490775219,8087675983147334543,1964230702014511539,16308920541899683887,1109841687404741571,6921137631204541972,10535589295581989247,1587581914835961383,8528537533989900285,2813938170763722263,3858442479193208823,1705281873496224654,7205649596786715611,3391726477506412759,649009166547919423,2833207312068258641,3658234001207525404,16538405875849249430,11426104351017537782,5503464931709447363,6957497237136058891,2208955482928353731,10615255738592349941,17744547939151424984,6837582045757201831,4811321735920062635],"proof":[[6439121391553305366,8623579492481269743,1493573690985434245,17468323542602264100],[6741205523189248618,6425150911095673053,13917552597736701708,11698989187081976857],[3303026497706094585,6348344681052533567,6226933810194106695,17408007989160088293],[15865405468584620970,18445334820182969643,9249383756707029366,7704296706872023789],[13382560913871765761,325326626791142456,14619844932768836555,4527997267781148754],[11696738946080531369,13672455795454456826,2443221231119780511,12022876174492836131],[298494483869949137,13480042199565970852,18058613955244696441,18242710966012953834],[17636146512875890904,8993171401155692023,1463211565698818190,1050184405676317375],[5674381872014227638,4452337425199325188,7445626351945827061,17107173390134099641],[4205412609011356756,10982411590137358904,3688204922736944000,670840478443294658],[15399018669327210131,17224068759311859878,7355217184735306584,10564319569525446667],[5036732624473701578,10736652521067589215,215081799119890801,6841813121839480070],[9772473069276292048,10618926486353324337,1881457444397612920,10960387243700322956],[9960593405479888625,8113027595493202359,10427956466321531438,16865727042739732471],[7973967139164471259,7242352344671373559,1700715075142582428,18301175903709491195],[11511868158734641022,13379677230417986929,13834832617723560419,8351544216255033565],[1135997963394111510,13275752990064275231,6348311180324878415,7982923292041772706]]},"quotient_query":{"leaf_elements":[1710807019748816038,17417689534034764746,7805871703016825326,15530136150321397927,1243996528372660156,3042020756652657971,234619105135725699,6719995900466963105,7625844759279376219,17759954134513492556,17588235193959150215,12157580366073827745,9911905294132912457,5102491411310178925,4241561194480458231,7445257308201244848],"proof":[[17430283655948955805,6609072371705232549,7350919449409163026,8283733224834336777],[16940387600920282137,14366282931485933756,7286258793747485533,9385721307823961975],[4959271946805761332,15934301878653952290,5552670730753914626,7807766052127942777],[12741195517043280207,8798795797515209860,28463212158003062,1671377043816111365],[1171394784130835835,3351664801576538232,10867526152908466138,1311411266491887112],[9810351878881008716,14755725386173235891,5679231712586449422,162503253536473619],[17239320562524351556,9432978736823924018,13130025549489607525,5737863486747302237],[5459202447379986063,13843619958597738062,11596017022577431536,7138512112294778575],[6683774359462808257,13796141062416825489,16026369686564371696,2591255852890719519],[3647224644597503559,16459937577315622733,6871553723120984481,8274895175830127385],[9362693729257813297,17957175316587868926,7036175651798931963,4686791021028730060],[18401102016197222355,9305852783324541195,13884135614196216322,7578722644881969427],[8263529008245859895,10727560431526131987,15691398609452521948,3570296683069301205],[1715641539140575462,14007700721554265090,3203330286389002312,9042769257566901468],[6108497889351340802,5398986692742181177,13895256427289640102,466566345596639332],[743715637329255100,10066940987687814209,220670241976254492,3608508566499664047],[12530437638825942509,9467813558315705039,1660881245341910574,6918973135087974952]]},"setup_query":{"leaf_elements":[18124385418729529581,7715051483951122421,9270964474344470624,15342980553217303603,18024549596932630598,9260268552709564991,3641429508367276353,12910480462585126363,2472996266097361212,18445769187887709234,1032385503759748550,14570391876899544690,11433200243123758358,2806765026725006240,7868496405082111029,714875959619174394,8383196776306707367,16179406572911309500,16515964280433936837,7488644882212409619,17193446493667882427,8592039955197235382,13950687305561112726,9024867045144656358,14135100666984990182,14483413155315031031,16486627375032054237,13339487837307712046,6605644936397874602,12225271328535656591,12983696853340830818,1628078539083106439,3814817415493827274,3874446136054791064,17337308604132787875,4258350335713071524,14977491160173666893,4248705660445455573,12765763395686358001,14928949827085668673,9567738093083696706,13136051297073930554,5736428090030339810,11770234907740779582,14140749603798789469,846838163559159592,314305461025063210,2379658117782201177,11647341412799186511,4995422596211827915,6538218805372644928,14130988708312003874,7131104808019598851,566788111301851031,2652446629594717115,16324939613671601106,6367900003329655014,7914468305967403115,9851331274756703075,9782632246663031567,5131927748613622225,972721249582478945,7244226788083404624,4262713521054833214,11698795738098334205,144826069301936287,12671148162292742263,7122844771005705645,1424648548995323717,9225357425714258759,7132572857386441997,6424716565142175581,10939051167463429876,2733286947044515777,15977873590001051821,11035047742489130877,18190475119736936843,5721717414002077924,7093927363185052109,3647660120581841740,8278427499331592245,6839453298425617220,12480198556503908266,17982040476493306037,16054513391863584563,6847586349998858163,18033945884305671774,11650804031012121816,16760518078498782439,12209994671447237923,3734046821226193348,2487546745606198315,16751104674948149885,8035412466503614801,500850866458845445,9621207172285434514,811375097205749054,17060947237410522285,16886533914283926722,10249512836614896395,7281028051321817742,2740903919682159987,17131356678427764485,4607044417710283270,10348625848110844653,6269745300976542616,13819914178365281216,2804846161064424695,7922003727756520808,1526550397311751859,8184928845831150367,6696461733968963996,9199796526128188004,4668729993978427914,4173478139848207222,17691888337611464468,18022868275610077683,2915094721645764279,16457008737805296925,5534465656387663801,7770807979012246275,10058050675262002905,9810867746152797894,1365547434514031371,1688132482825277034,1134162870186457570,6266030394316813738,6813945652895107222,2374972488175075661,14453154555669453300,12306994982348651205,5525745150395677870,1222425616659623893,6095506820307548244,5967673815275910889,3662674164892174409,5051109521513823993,57784527728664216,18316061817499150277,17024926941517651667,4569412997772719727,17296755120323465296,4554787178620597145,2135190176316102471,5809081220389920451,17479323268645582326,4477636670985871192,7717822409569601767,12441618167221279138,12918097048876527698,8075337731748832785,13362861211268164622,2252723709150640359,9127183436525976681,13711795140216113848,14233673577895799768],"proof":[[1318066259889645752,9212873141534200016,12412231204968148733,13784788700019577361],[1919858986401205219,9563392634476241993,15486670244717063348,7179837847751238410],[12010516381692123684,14961914102866972951,11579039891730793584,11545703665557471113],[4194509029783818212,14274678847219794406,9909430512406050418,14724466114119341487],[3816968067011367589,17303253948002034282,7813080621838419458,12471589745130473227],[8536354177517163897,17968651609971253021,6501117541673284498,17827710663890075705],[17417976269872994454,11692679028122858387,3850288570183391935,2902778421408611605],[11206256514779062635,11995857859016934127,8244205755635907264,2415287843955038306],[3783193939274299974,15814966523636335523,9145737728359132003,2394139822016332321],[12841265882968194618,11405403841732133952,15093907903169632730,15053174054899767779],[15931200815119870230,2061856803540642584,14459014515141469292,15554992960284551696],[15869372326322959033,5870554572981269523,13523220258239537328,3898206378352065223],[4150798483942068026,8551121592021827451,3000730340879179295,7114111892405901418],[8767721595337212539,16278729301795318642,1461021613127318371,11383014273284099454],[12905882776999238470,10574484417424369917,15012986911913400699,4685670864673593800],[1155622468097280682,5323416548298108832,8022893987892584074,11953756625309878271],[11786672773418549703,2339467107386851422,12140533047963330746,7373381974425188538]]},"fri_queries":[{"leaf_elements":[17742918210535808922,9353816514088163485,14570841325877288711,12428471545655755036,9105001913003313878,12494189000537373716,16862382061287519496,437141620497655388,6428162936523530061,4808523215410755241,13412306086576346734,12071284847089001019,17084702074527675118,2008879762832126197,5353220823863474560,8352234627631968168],"proof":[[1934081693809950040,605508061484441048,493932799040601382,12085874572066054125],[14636711276466731161,17796695046807176142,2260883084597241322,622413911977510327],[4640528557586945651,16424468529250566153,18032012792438652014,18135104945098401397],[5179587150470669236,16733046910123818740,759910505861052258,14148624304842301320],[5929745370637030752,1876159884259109896,14726966194924648442,10690624560014386933],[6714828987675782473,9911794491188218628,1967746749991568020,7415761166075983981],[2493370877817663489,13624635374769841789,1056634309179350461,2122793020643717353],[1546214379943971568,10867466875726655292,8244961191816976723,13762697747029191750],[7438542645453244680,17614921622888401411,13011812016849870916,1978038554483451581],[5463267335997506451,13534722284440411233,18062461291995898623,9106472810200647932],[13358613261555114715,10411274019882998102,4461738657058286723,4991096931689027227],[15267790849070639342,6466212133871265129,4581505514599380446,10610508530949688217],[9910303583025534766,1414356923107848953,13001764951355095740,3311228748280393472],[2065112813907786203,6898755846797313237,17320045911186699311,10677055216998779661]]},{"leaf_elements":[843587895869918858,4748783424654754959,4730260608158470747,4305474991974600761,5444973318984038457,3872626316758222403,4157971217342338061,3620310139316064068,1192679242820232667,2094299023593322335,6101518537672815095,13159262217762499683,7309176379689020499,13272910888222367113,17943598363706986338,3797315014242127225],"proof":[[10599657848522671651,18145786146406462560,6939483685770171838,3568116405167513959],[4426176286191133785,17028939034493710265,443700879044079649,11242677830783505905],[6802366782024959707,8185958127047172909,18312537124245666106,2755141050697131832],[5353825037299837863,7780622415574271132,4827168550821464478,9352644626939334433],[16229642057023415095,10971029868115920373,3674738636382179346,7092062962818362771],[7048329003707001554,10488934788883815565,14604280999087637807,16724356893706124430],[4001239265053551901,3209297191348667928,12021947644663424174,2694320066776354940],[9733887757658192713,6768675164008008308,17201532427793889158,13093464504717849431],[12309313557163945685,13438460833138649064,1362127772746089769,6791297938156535339],[15586760640357510652,17199437880074354068,8452752432785340667,2190745931362611588],[6068200341678021668,17238405178273883915,16254243979175388415,6326469122072930844]]},{"leaf_elements":[1282922890311273371,7123060783484836950,5224810146536145944,586652482980969493,605143960895336834,3579590035565108540,5123726911923078540,13458555784813366486,5075060999431010367,12108387429791565482,5344437957932109067,15185256010074792228,5030595386216088032,12781181494813591598,14647436698991373404,5284310777231456983],"proof":[[10067857875920413915,6920187229563362847,13920953532788237753,14893689923410147227],[143719022231804197,6143544411949500785,11530983331438624971,15536839195140703496],[13311346422198542645,17926596202896767252,7743468170031081123,14655157588957604243],[5718437344868869591,12250103576197189539,1874265026196170511,16769759781974881012],[4037202797787696282,1693057410348181795,5551088463183606843,8211320577655265337],[15240139933297949284,1462587790837629184,17966711357235993021,3407100832053152973],[383955214807640705,16818216626337424042,13232217085098681904,241005896151116121],[6284005312668722525,13175024327537991261,5546811104920909949,2703000136490581107]]},{"leaf_elements":[13606403901548273773,16656653801622474035,10551471422682297614,8067953291469800757,11085831344258804100,222750601323691545,36739491026352339,11109322111886526445,10741170670615676682,5578873342610539450,2596625072133970446,4124652878806158263,15247422926875095389,14231385130616567165,16163131946330963864,5283643670710519286],"proof":[[6620500251684474855,8461428866542369809,12531407600245109983,14913403865237721268],[6517220859100365477,11012649566548009520,1344252813115912406,1669752903032142566],[5564564252235922998,12681884071870719668,17256616812607015190,2076042361274142078],[700619608235653952,12943330703004030898,2480455716292619428,8323977305965432970],[17991506096714915795,4636722536725601757,13865614444769694335,8815772354958363399]]},{"leaf_elements":[10709399384505901433,8410325356231090929,15561720818054825268,14595136295749910987,3096112296966750560,3421660690568712333,3091144484682138335,18310247230512460785,9482461499428884128,589864126313932898,16665152423982453751,5925405038121600556,17725199030289479468,1096803743263879443,146129809745760679,5540267174767141550],"proof":[[17994419247383461759,8679941398660402734,3461954500207538403,10904733956278157357],[10835623355140351544,2411159751067968680,17855867681805886030,86569936236411870]]},{"leaf_elements":[13912788208633012260,16592364955197622110,12930883254427910878,5599575569218380943,5682660096836901399,4069773254031359724,17686759155637027087,11829746095036037227],"proof":[]}]},{"witness_query":{"leaf_elements":[8615149690747108858,699657143167520765,706104675582639781,7721756196277615465,5479150564923537926,7941251107827994068,8085229733304494329,4323399820653748578,9462033318647568674,11329749021931445307,15311826647318272885,12050551159923351466,11183948190875080636,8062322050628609235,5902820061731598022,8074270950758134842,13386849182968741436,14730136725885240988,10157612087083161117,15526297386862669397,2616590977838269674,16941845974102602721,1512106571332825217,12712867475108580902,15587778367518566718,14024901117736144340,8681833644735375401,1696644809256009224,5824685491613677535,14472373429147762280,18334464526906890378,4399426736260640911,17256339152414913297,13810227785021350198,1117095079387327800,14331081530606051665,12891797309282335301,3543170001583071703,7032928134477235136,10199432042536833937,5950941287942871599,5331253668143481869,4097166541588997758,7540000757162102617,11742657227754672967,3775197579535368498,13256727324230943925,14870648972739770539,6207675694141981379,6327114641554932339,12438249777602970545,1938448518688895344,16340585055434656275,12410847672889619924,16021129664011667425,307547175483307918,12237737635033383584,11663933464541124135,5280477511694893747,18292665468439118220,9706904546772796267,4747275561472758097,14206312032217458847,13146219211749567146,8073394342733392137,3251974583905601199,5740520012871407063,14913430343752576445,8356174858474813561,2851859213562779143,17870188000505209045,14596235372560274184,7383215184321395984,14400815615095915690,6643709418886186843,11522264384656489887,16927094457273389224,1939831880565020758,1616755555450579923,13000620408687566077,3743844996506326575,5471040721019808934,2411260413189477156,14675961548294578036,5075011437739883697,15757391432787641764,14597371646787156574,9813543047169038122,8919660897089814938,5991660069719329576,11292240457490557283,14433758785475914489,14563923787198601303,6866900132815101179,15154607085807105452,6922146701185260351,12889808335629412210,16253366571755629480,66498219016554105,15927101168427004126,1653478179667505474,12510340576729014125,4719876669637340464,3784158551674949019,1671587639627317822,17492575529976932554,9784305555286616881,9289468521704329712,5221967801656134722,1237561232089744708,3740901296729427480,5691796037860888712,5468259594789440172,5945936288156882686,7211147862989925540,10641838347039462019,17440377771773633425,6026583687571112613,16502747773042246843,8997118110773551952,17846387129392493532,13449398886458905407,9255195582053425676,15447469082210936419,3642638656607192517,17243304965137430156,5614398916942627111,5884460123062468602,12408004080846658781,10624883863704929524,1208464892658822538,15904045521960285979,1606234045727147401,10679933372817821752,4240198459516460299,17779074036150194558,2810551682448334777,16582547437228764467,6793549030691255632,847734099320355965,4502604647368265188,1649704487916420528,5155167139213754364,2435935628080659672],"proof":[[889230553136905243,6196026930428796688,13948031214171032903,16998744637182183662],[770422692163011386,3761453726872270110,7039781476327374391,8632187869111697970],[7565855855824531123,12247373060395829826,6165964323589999272,12667920501039673749],[3935780929810394828,11119662055778976407,11626831524673039585,16301762254070874291],[17808390210029936151,8190481990088117695,17313875362623957606,3780744052432823208],[7569087471664645526,14150233534874996257,2187580277755110438,14753763025995365765],[3799625557505524819,15127633672113799873,7245290233199275178,10345960902690528004],[8586619796728871724,3767687480295916441,14975654108486826355,18064673251450061097],[15269051171499173946,6520378744943238883,16346386173682061753,14659941479760611436],[16761754927493071153,12738112145220436956,5511875005755682412,17767805988420812571],[5188448161792603985,11202450264744214269,1438358976572347120,1732977169496549935],[3227634403342056844,15051411164650703945,11557064871714791757,8048186356181179391],[6731780313392188669,8949906578384192643,3039315485735299712,5020846763009810114],[7025992036755329687,2417860101639432463,3827191828562693623,17616648178967878874],[17702999246007089937,3811648026115179293,2755143529176567273,1054777199578183153],[13956091290665605269,7893671946068161603,17280842991379820366,14844174942388040798],[446318376307115417,3375364935197782891,1913390476604132002,14742194311215528796]]},"stage_2_query":{"leaf_elements":[17192219788033759923,4793193820922070862,18338758809987369919,847896544127981168,11374644332749144771,17270202289869511797,14503564328528517433,2488313275047780582,10306388050541966940,704120009548275850,12786793754930882083,15107536629327122525,2778219604036102444,13380181948108972439,8685472600239655344,15404889431067338441,6322138972776974844,17857413818832126163,14058331519798466250,889279122177003728,14297666316380107975,7703035309975880407,14364163880014531741,5718567863349981826,15568904539049991080,15914758586071706808,4894084074350593665,5562305829105168705,1866055506101294066,1722455076731715780,4840090932899971775,7238724059456490095,12142003804286161332,6480941742817590419,7769076923818989170,12898576739151031933,17492530090362876283,13822879200979014622,4777093870058610356,10070839994484010030,17681278538691630869,2165200931707227003,8754232673429563610,11164456191294874304,3660097253396358985,18251423381297210909],"proof":[[8909054722264643527,13457577711790738507,3101307105069836016,5513593384281627421],[14340241847421924250,6692675913350635407,15650284558989220763,18051662084463954568],[7034310735433914908,2075209411011995041,9965058843383120760,3655431916612813567],[2044241086529370266,12048655265203812511,17289394327218932581,5710107059820593294],[15897281149712000110,16471977253118331463,2584911067568084738,2013787934889224170],[9472281519245636298,16052549715832804632,13892930511968212019,7392125480700858834],[15700653500931844520,11057613604501002965,7111190650949369486,2196037116929590234],[7891712413996677359,6634553961013855101,6901166636279808730,12282325051947926419],[17138528694951338684,17680388043234208286,1471199159881789399,14487673733439902905],[9895031852446619269,15559916581684344531,9909580656860814461,6898923355705893033],[9133808510565510011,17833936580850095172,2392688500705539504,15152853327791348603],[5093573538589376289,5964552622019512874,15372412479524487989,2071031654937023262],[816363246763676853,3068988487145481290,12531420455779022784,9602244667682561714],[6140361723618379037,17485510299358327199,13481739743734739084,307070496537051704],[12980845372799363278,15753420493061081197,17075042185243211581,10635054727364082425],[15351827245894792358,9295638853386574934,1602616796632692872,13047387633705632052],[1283005982263822647,5576217357074790266,4838152385037052151,3671493702847934836]]},"quotient_query":{"leaf_elements":[9828181322224612259,4858452147354775898,11165435333156764641,10794621184266421703,1397112530643785483,18122586252739053624,6010364652005403718,3055567750607355821,9938424052509742730,909992718387092206,1140814761975846729,14786203216325070167,2812524305046694183,17259287498335541358,2585707745174783593,6624161597510796468],"proof":[[2023312273914655992,2335011639818323365,13775641543105869460,2926354024341877674],[203092873609096796,3946296584311623984,8379814372499858771,13858239456573115467],[10405247697671247353,14186292563912759137,1610468068672072250,1783431696448043471],[14698626676068328770,8541701693291744485,10477457883093957451,14850294386730746536],[14867085263570642468,12284138639384646168,13017753420567305169,17591090160944478572],[500905553916406111,630745916045162458,15358035488846716957,5198844801225527415],[4755715618898415630,5331543478790512732,5059935757297730778,15380781474547687976],[18002225724586527364,10287578110617487431,6588333688857854673,8016096908749444700],[5772781426225045610,2581394773700571022,17710700655135758650,1119006911673114003],[17938874447780409167,12622317174473023942,7079906003791412137,15579934878848351218],[12507891114537327170,4092934184303697577,10537652034283301671,8552600311387292798],[6743980406311537971,4744516413841642816,12898570936878805612,9989475403612067108],[18284235977441646110,6662955873831215041,12907632622924363288,13365711075457114818],[7180453766065528754,9326151003147226890,3307793939844726354,3255889907921952092],[6066733790775045238,5005353158914861700,5846673783605795012,7509535415846890078],[12383435537749213360,7913388594304678688,7500054166861163716,17121339375120288845],[2756204060012982104,11181890352814265502,17993618182006171151,16194213402389489504]]},"setup_query":{"leaf_elements":[3980205979074544584,8831098865268377095,8395007496884576072,6626220762571266673,3177636275142603168,10797495977818848862,319695984504870672,11254958305218082164,1722754045414556925,2292548348221341876,15347837959559809637,17576277661166170152,11916079634769115094,6813917131081163130,16022264076125661057,12545608902710166400,14948289722511509138,4342845301212512368,9185511619131434567,7249787132588385862,5835655212253819233,6041867235294823034,5015280083233342821,138864440576627119,2299067738939576413,634831433947131364,4029034753588957191,8606210068023127970,2206124811391351679,3115511972704877672,18149340822217972193,7844106388848534180,17002152305467431747,7973747945948082217,17122786171500801971,17391587455386743153,17305122252522769568,8138922570161973899,6935014374939856923,5525468096765874624,8767018019600425526,10989042992959732004,9078556241413471849,16258310300043532527,6578073429299513176,4798526577639840307,11547105289552743457,4473044900536477582,15139449059892233208,11247695935285951490,18409179259927583146,14886359372075069301,965812329515878175,12425329273801869982,11645520910515259906,12289764792609922313,14277113889073158180,220315864773815617,16305095042290011936,76745906084241997,14053262369657406000,3496982653679746095,17340490627190063456,6681793071555118312,14835088207204046641,6999439293121285470,13228762357282709725,16864564257578890700,9808926074389026344,6849536065492682139,8418028565784936677,17090117026521322402,14818172647824901506,2604078560631467627,12399405090545819569,2727644149352041719,2643854040711436852,1855774738723247992,13784225164013541882,17755990873282429677,11011941355116811731,15804603210220218407,6223277626433548147,10919109423735033480,11581081997741052553,8597199352796022293,4422442246365941781,15450558545088054861,454597483745662129,16221685919213930619,7752418745997420628,12225295427516235854,415678259753396435,7203760531739744399,7863971077224946758,17771877974154128444,6243948127529798263,6253095125492046163,11486218562535994320,8838202264983285527,9134027260910237219,9553624768082086759,7878153233811505076,2620360273918182167,6213196357850673486,11592840705760803497,16583444843019831126,3226452038360929713,9401067565381760853,8966090939774230052,3787225250482020688,15613780412585968390,7494956086408216297,3731687432393584777,11562141015202660228,1226893224612724218,5516441939071002345,12980878944277015137,11225255820361087658,3598649617731771182,13865735976097827706,12050669524686142462,16294219873089953427,4226487845869990243,6019895837152146877,12988508568134166547,5437103557549618580,884021247313544637,1236646925176128750,4523887748052866885,1219358974578178198,1459713994505597742,16312026826464959129,6638830526908980573,12141497605487077135,132461171365763763,15395374983543161448,8463523179084670901,15898950774102188739,8621978196645536713,5189579999858053325,17310563659629486327,11428079114365382175,16037196610952636739,5998046010463841462,8096726372958705426,15337586342802806132,14207910796037707169,1378348994435820783,4681987881145114318,7247623381720778823,15137095758763417737,5602263913598705147,494535239459348714,17443484823831305864,15454483033650436366],"proof":[[5961533645969270404,5031014654976589616,17428488408525997217,17145078473955375605],[5749250222728788159,5359876347764562835,6371953565339139859,2670639667715988871],[6644487535427562603,16591048407368562458,508967175655963979,12515024999293127804],[15524544036105756782,6534155939326832787,1360139417456165574,8084535053195760659],[10595216043285656608,5802341653764798423,5218829354602959614,10547393601703368108],[4923721676974259088,9649416816024959657,1689604526283044236,5059167900632307730],[9319347408879923008,17090019000704637756,17889715138592382987,10704011429462712683],[9935619672136563718,16625085125142034023,15394280367838034151,14643117794355163805],[8049677077529246980,33581027516781663,6577009959718955605,3604496236348359369],[13453863756464232381,1845379509350374018,7251593572613250205,12566644829243057490],[14044103831496582581,883801141661785492,16822386699523463154,11900042415705169653],[437320982325459603,15014061136191546939,16975595938576228272,9105394232755834092],[916579546586067812,7861102953071708394,875247665753976704,16185763403374176385],[5083865295085259741,2281251523687941260,14042014418477568256,14407812877857631952],[9891311356354517440,5282382816694754454,4494318116444376223,6065032175189985675],[6552520117544810486,16587019088306324507,6380014223602582641,16116898179121020620],[119942016992425815,7641812824221345957,717302696007773285,8607632033190912232]]},"fri_queries":[{"leaf_elements":[7562765610953520274,6173293863891342412,898344546143314178,4367933274909713499,15202269973046371953,11906314372656793226,9605714058034718875,9607037364536568290,14223580715678417486,6541173691309488351,5142271092122257048,8437341153190778523,2907542105274967370,12513984938235147379,9390548416295662875,10192282912749852414],"proof":[[5659169569825157329,15424510997679710283,2047922402100697256,2594025699393213987],[8105112553719862300,4010150880924481527,12028415244022023372,11253824050261972204],[11693488578131776669,13794042984358808265,16815592759400165850,12232250275661077007],[11765038555924125913,5662599786632045454,3917651847408908195,18024600252916965999],[8599683287552309454,10434231543861536761,7963998612985473826,5398225293101075074],[9641651132633729242,14689935338148463166,15164183403682234833,4359358548020283744],[13252159323899000045,9441931754680400332,3846189857851254402,13735633379806572186],[5167590271344622574,9048380768911284355,5441321972126004089,15158873871706330921],[16336327356049267787,2758709038519724113,3242896155714647638,1875125191796691444],[13841622428241325749,13684700875603281465,3149475554957905161,11947389253073190086],[1330293925407066336,12440364171342603449,13672239413972184767,3512695617410144980],[10253321460663486329,10449222444378462148,9722058340557600917,13948584960239118661],[9828755776288769143,13986765444697018228,17216114589747554748,11737062743669164398],[9497522330654010607,10428746838159854411,17282797116643625741,9370446250429457167]]},{"leaf_elements":[3175501965870029965,3380066251050270274,7696968799289086063,5095448728412709035,3989445798775297670,8039952031867241297,6244159380493195724,1345276671742610140,15984309498884780318,15360868193462557220,10369062903941051190,12413660811484700474,13957148503373961075,7409374082899611611,1792124184004866430,10003964303953551598],"proof":[[13386581192450392764,7155006363427753332,15459841232674062283,14560870790507786889],[6392973223852269054,9396913813714768353,6438330657014293859,9616592691555244383],[8951120440192733807,5780149860330072330,12236560766471131364,6547583016805157440],[6887983184157222388,7663015127575544607,4059231087851048977,3801169680098916010],[4096554756718736909,6989049581946238939,3860906397193000119,5445782550882572225],[8214877416180368939,5182129174586703008,12408384589026124279,3120318893896718459],[12333368891041101607,14488716853031759732,16333608830385744051,4156249993553409714],[7000788273743971765,16518003888922863693,637799991971665987,17487916366247177305],[997686064899684157,13647643616532934033,1254051800427624242,3344803847678085691],[10995142404837032615,18037828248629944783,3621605584051744,18272512998774485959],[843411343929838404,8361740330644747194,2332379768699751226,10226462084284657766]]},{"leaf_elements":[13131925551149426486,11538557266939474700,2262339181720759255,12098505333435199844,12979654406505273771,13311627616908809951,10899771219846871059,14460038032003847092,3955710418166300376,13713318679138084967,15765579327956905507,10374690074435956931,1631289432835059826,16030945649168412079,17468812103183560120,5287763633786632741],"proof":[[11394633225841529280,13924939776120112878,15221666454383507822,16869977488810058699],[9922763575734273229,17984755554774288495,9646796241144592496,17387832252796207905],[15356235392519146831,4410081687782837855,15580965317726470950,11740946286483820311],[5187785918485803015,16715426164470967518,8094872188317661245,6535183909745812285],[1204228932153953417,15868332670127542544,2523597841791210510,12091367901699948777],[16315957910231156012,8141027457693889578,10668308287477273628,1674759928877200019],[6093544420987595980,9570713105163657521,16834300732272845917,4954962326226044419],[9196460362043655518,11124783458111663969,6628625323182741542,8138792676882935518]]},{"leaf_elements":[7415164103549633129,16910983397873592519,11343593399090805849,6232698252533549683,8318345985880097145,18317044240662693848,16800501786753299539,7238169235938247230,13808764861920680134,12717276412222214593,3561018531906903310,8795449999006241331,13549815296522270003,5155429127281259774,16033831745855059163,617466501284080620],"proof":[[14745333330272485439,16406024530826424794,5506182683420101204,1461486835363780956],[14598429050582168260,11212019143973573308,12293340356251034235,11338794077559704456],[8134286010036830101,15244981524117054960,1665178868477393466,8604977290959447098],[6748302237752748816,11050683019842041066,10744285173980642168,2830567593414132163],[4195745188892480400,1278917477926341115,858660738527305749,12026569133742582051]]},{"leaf_elements":[17243346552149652517,10882619986357177751,8096803201503556482,5222497194179763350,1473082545781564758,18086100824368415238,12291573177398886098,1525169808899722843,10361841926233051838,11515798859454192158,13069490598638279614,13771904632740530077,6153907696260295489,6369593925792411855,5785431625204876738,15730679172607800300],"proof":[[16997450673583468054,2529071262208839696,7011471064570615138,7786772006240297790],[16070927894096146171,7499309042979267285,15222708687563261277,7377423658769375210]]},{"leaf_elements":[8872244034292046542,14961388654118324654,5802056968775514489,18302383666416428067,3933647026650259001,8825851261617385151,8616213839298888053,10450361630528634353],"proof":[]}]}],"pow_challenge":0,"_marker":null}} \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/recursion_layer/vk_1.json b/crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/recursion_layer/vk_1.json new file mode 100644 index 0000000..6813465 --- /dev/null +++ b/crates/zkevm_test_harness/src/proof_wrapper_utils/testdata/proof_compression/recursion_layer/vk_1.json @@ -0,0 +1,270 @@ +{ + "SchedulerCircuit": { + "fixed_parameters": { + "parameters": { + "num_columns_under_copy_permutation": 130, + "num_witness_columns": 0, + "num_constant_columns": 4, + "max_allowed_constraint_degree": 8 + }, + "lookup_parameters": { + "UseSpecializedColumnsWithTableIdAsConstant": { + "width": 3, + "num_repetitions": 4, + "share_table_id": true + } + }, + "domain_size": 1048576, + "total_tables_len": 132096, + "public_inputs_locations": [ + [ + 0, + 1043851 + ], + [ + 1, + 1043851 + ], + [ + 2, + 1043851 + ], + [ + 3, + 1043851 + ] + ], + "extra_constant_polys_for_selectors": 4, + "table_ids_column_idxes": [ + 8 + ], + "quotient_degree": 8, + "selectors_placement": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 1, + "num_constants": 0, + "degree": 7, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "Fork": { + "left": { + "Fork": { + "left": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 4, + "num_constants": 4, + "degree": 3, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "Fork": { + "left": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 5, + "num_constants": 1, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 6, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + } + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 2, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 7, + "num_constants": 0, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + } + } + } + } + } + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 9, + "num_constants": 4, + "degree": 2, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 0, + "num_constants": 4, + "degree": 1, + "needs_selector": true, + "is_lookup": false + } + } + } + } + } + }, + "right": { + "Fork": { + "left": { + "GateOnly": { + "gate_idx": 3, + "num_constants": 2, + "degree": 3, + "needs_selector": true, + "is_lookup": false + } + }, + "right": { + "GateOnly": { + "gate_idx": 8, + "num_constants": 0, + "degree": 0, + "needs_selector": true, + "is_lookup": false + } + } + } + } + } + } + } + }, + "fri_lde_factor": 2, + "cap_size": 16 + }, + "setup_merkle_tree_cap": [ + [ + 3222775253831274323, + 7005451573242101297, + 13218069708139816321, + 15065230911623069290 + ], + [ + 2906246303524823183, + 10168239474433048789, + 16488600074184243473, + 14068144680293063532 + ], + [ + 5078902865087892469, + 672291765248265664, + 15277477812424690542, + 17325394377787243681 + ], + [ + 5446989015037708680, + 13342828707351402504, + 4873006944282181054, + 16984206329151476057 + ], + [ + 11219324558907876554, + 5479470557620113770, + 8957185821919863727, + 7833444913522903402 + ], + [ + 18030817369016886057, + 6288674395533283610, + 15956699468354901345, + 9433261916719273849 + ], + [ + 3149463872145506414, + 3046597791490436624, + 5341677205035062877, + 18434415602609361590 + ], + [ + 13470081587238141254, + 15537547589399092974, + 293149548016914548, + 2704153237947834916 + ], + [ + 7643257520426192679, + 6059502391108638843, + 14837299445409172884, + 3410231969967450579 + ], + [ + 12621396656059849765, + 14508516386523831879, + 14033332488871001390, + 7702007894886986551 + ], + [ + 12684611914933469319, + 2034252690388271254, + 7119191709737541010, + 11457960371424072338 + ], + [ + 10582865913010000302, + 9135715701035942343, + 7758958748575126999, + 14150728756075961483 + ], + [ + 9817589145714694186, + 5996996229641948337, + 1793258173627709316, + 1763439738663065972 + ], + [ + 2036237842552189562, + 5692368816720483641, + 6484522643680891633, + 1376994531467322637 + ], + [ + 16519600991599942452, + 7992087915107681012, + 9948441287743016667, + 9965686898709044637 + ], + [ + 12342321636042375252, + 6423168244598782505, + 9971387075780091094, + 12343214473254770804 + ] + ] + } +} \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/proof_wrapper_utils/utils.rs b/crates/zkevm_test_harness/src/proof_wrapper_utils/utils.rs new file mode 100644 index 0000000..5a34558 --- /dev/null +++ b/crates/zkevm_test_harness/src/proof_wrapper_utils/utils.rs @@ -0,0 +1,74 @@ +use super::*; + +pub(crate) const CRS_FILE_ENV_VAR: &str = "CRS_FILE"; + +/// Just to check if the file and environment variable are not forgotten +pub fn check_trusted_setup_file_existace() { + let crs_file_str = std::env::var(CRS_FILE_ENV_VAR).expect("CRS_FILE env variable:"); + let crs_file_path = std::path::Path::new(&crs_file_str); + let _crs_file = std::fs::File::open(&crs_file_path) + .expect(format!("Trying to open CRS FILE: {:?}", crs_file_path).as_str()); +} + +/// Uploads trusted setup file to the RAM +pub fn get_trusted_setup() -> Crs { + let crs_file_str = std::env::var(CRS_FILE_ENV_VAR).expect("CRS_FILE env variable:"); + let crs_file_path = std::path::Path::new(&crs_file_str); + let crs_file = std::fs::File::open(&crs_file_path) + .expect(format!("Trying to open CRS FILE: {:?}", crs_file_path).as_str()); + Crs::read(&crs_file).expect(format!("Trying to read CRS FILE: {:?}", crs_file_path).as_str()) +} + +/// Computes wrapper public input from stark one +/// Stark PI consist of 4 7-byte elements and we just want to concatenate them +pub fn compress_stark_pi_to_snark_pi( + stark_pi: [GoldilocksField; NUM_SCHEDULER_PUBLIC_INPUTS], +) -> Fr { + let chunk_bit_size = (GoldilocksField::CAPACITY_BITS / 8) * 8; + assert!( + stark_pi.len() * chunk_bit_size <= Fr::CAPACITY as usize, + "scalar field capacity is not enough to fit all public inputs" + ); + + let mut coeff = Fr::one(); + let mut shift = ::Repr::from(1); + shift.shl(chunk_bit_size as u32); + let shift = Fr::from_repr(shift).unwrap(); + + let mut result = Fr::zero(); + for chunk in stark_pi.iter().rev() { + let mut chunk_fr = + Fr::from_repr(::Repr::from(chunk.as_u64_reduced())).unwrap(); + chunk_fr.mul_assign(&coeff); + result.add_assign(&chunk_fr); + coeff.mul_assign(&shift); + } + + result +} + +pub fn get_proof_for_previous_circuit( + source: &DS, + circuit_type: u8, +) -> SourceResult { + match circuit_type { + 1 => source.get_scheduler_proof().map(|proof| proof.into_inner()), + circuit_type => source + .get_compression_proof(circuit_type - 1) + .map(|proof| proof.into_inner()), + } +} + +pub fn get_vk_for_previous_circuit( + source: &DS, + circuit_type: u8, +) -> SourceResult { + match circuit_type { + 1 => source + .get_recursion_layer_vk(ZkSyncRecursionLayerStorageType::SchedulerCircuit as u8) + .map(|vk| vk.into_inner()), + circuit_type => source + .get_compression_vk(circuit_type - 1) + .map(|vk| vk.into_inner()), + } +} diff --git a/crates/zkevm_test_harness/src/proof_wrapper_utils/wrapper.rs b/crates/zkevm_test_harness/src/proof_wrapper_utils/wrapper.rs new file mode 100644 index 0000000..ce97b59 --- /dev/null +++ b/crates/zkevm_test_harness/src/proof_wrapper_utils/wrapper.rs @@ -0,0 +1,278 @@ +use super::*; + +pub const L1_VERIFIER_DOMAIN_SIZE_LOG: usize = 24; + +pub fn get_wrapper_setup_and_vk_from_compression_vk( + vk: ZkSyncCompressionForWrapperVerificationKey, + config: WrapperConfig, +) -> (ZkSyncSnarkWrapperSetup, ZkSyncSnarkWrapperVK) { + check_trusted_setup_file_existace(); + + let worker = BellmanWorker::new(); + + println!("Computing Bn256 wrapper setup"); + let snark_setup = compute_wrapper_setup_inner(vk, config, &worker); + println!("Loading CRS"); + let crs_mons = get_trusted_setup(); + println!("Computing Bn256 wrapper vk"); + let snark_vk = SnarkVK::from_setup(&snark_setup, &worker, &crs_mons).unwrap(); + + let wrapper_type = config.get_wrapper_type(); + ( + ZkSyncSnarkWrapperSetup::from_inner(wrapper_type, Arc::new(snark_setup)), + ZkSyncSnarkWrapperVK::from_inner(wrapper_type, snark_vk), + ) +} + +pub(crate) fn compute_wrapper_proof_and_vk( + source: &mut DS, + config: WrapperConfig, + worker: &BellmanWorker, +) { + let wrapper_type = config.get_wrapper_type(); + + // { + // let proof = source + // .get_compression_for_wrapper_proof(wrapper_type) + // .unwrap(); + // let vk = source.get_compression_for_wrapper_vk(wrapper_type).unwrap(); + + // fn dump_proof(proof: &impl serde::Serialize) { + // let mut file = std::fs::File::create("proof_dump.bin").unwrap(); + // bincode::serialize_into(&mut file, proof).unwrap(); + // } + + // fn dump_vk(vk: &impl serde::Serialize) { + // let mut file = std::fs::File::create("vk_dump.bin").unwrap(); + // bincode::serialize_into(&mut file, vk).unwrap(); + // } + + // dump_proof(&proof); + // dump_vk(&vk); + + // test_wrapper_circuit_inner(proof, vk, config); + // println!("Wrapper Bellman circuit over Bn256 is satisfied"); + // } + + println!("Computing Bn256 wrapper setup"); + if source.get_wrapper_setup(wrapper_type).is_err() { + let vk = source.get_compression_for_wrapper_vk(wrapper_type).unwrap(); + + let snark_setup = compute_wrapper_setup_inner(vk, config, worker); + + let snark_setup = + ZkSyncCompressionLayerStorage::from_inner(wrapper_type, Arc::new(snark_setup)); + source.set_wrapper_setup(snark_setup).unwrap(); + } + + println!("Computing Bn256 wrapper vk"); + if source.get_wrapper_vk(wrapper_type).is_err() { + let start = std::time::Instant::now(); + let snark_setup = source.get_wrapper_setup(wrapper_type).unwrap(); + + let crs_mons = get_trusted_setup(); + let snark_vk = SnarkVK::from_setup(&snark_setup.into_inner(), worker, &crs_mons).unwrap(); + + println!( + "Wrapper vk {} is done, taken {:?}", + wrapper_type, + start.elapsed() + ); + + let snark_vk = ZkSyncCompressionLayerStorage::from_inner(wrapper_type, snark_vk); + source.set_wrapper_vk(snark_vk).unwrap(); + } + + println!("Computing Bn256 wrapper proof"); + if source.get_wrapper_proof(wrapper_type).is_err() { + let proof = source + .get_compression_for_wrapper_proof(wrapper_type) + .unwrap(); + let vk = source.get_compression_for_wrapper_vk(wrapper_type).unwrap(); + + let snark_setup = source.get_wrapper_setup(wrapper_type).unwrap(); + + let snark_proof = compute_wrapper_proof_inner(proof, vk, snark_setup, config, worker); + + println!("Verifying"); + let snark_vk = source.get_wrapper_vk(wrapper_type).unwrap(); + use crate::snark_wrapper::franklin_crypto::bellman::plonk::better_better_cs::verifier::verify; + let is_valid = + verify::<_, _, RollingKeccakTranscript>(&snark_vk.into_inner(), &snark_proof, None) + .unwrap(); + assert!(is_valid); + + let snark_proof = ZkSyncCompressionLayerStorage::from_inner(wrapper_type, snark_proof); + source.set_wrapper_proof(snark_proof).unwrap(); + } +} + +pub(crate) fn compute_wrapper_setup_inner( + vk: ZkSyncCompressionForWrapperVerificationKey, + config: WrapperConfig, + worker: &BellmanWorker, +) -> SnarkSetup { + let start = std::time::Instant::now(); + let wrapper_type = config.get_wrapper_type(); + + let compression_for_wrapper_type = config.get_compression_for_wrapper_type(); + assert_eq!(compression_for_wrapper_type, vk.numeric_circuit_type()); + let vk = vk.into_inner(); + + let mut assembly = SetupAssembly::< + Bn256, + PlonkCsWidth4WithNextStepAndCustomGatesParams, + SelectorOptimizedWidth4MainGateWithDNext, + >::new(); + + let fixed_parameters = vk.fixed_parameters.clone(); + + let wrapper_function = ZkSyncCompressionWrapper::from_numeric_circuit_type(wrapper_type); + let wrapper_circuit = WrapperCircuit::<_, _, TreeHasherForWrapper, TranscriptForWrapper, _> { + witness: None, + vk: vk, + fixed_parameters, + transcript_params: (), + wrapper_function, + }; + + println!("Synthesizing into Bn256 setup assembly"); + wrapper_circuit.synthesize(&mut assembly).unwrap(); + + assembly.finalize_to_size_log_2(L1_VERIFIER_DOMAIN_SIZE_LOG); + assert!(assembly.is_satisfied()); + + println!("Creating Bn256 setup"); + let setup = + assembly + .create_setup::>(worker) + .unwrap(); + + println!( + "Wrapper setup {} is done, taken {:?}", + wrapper_type, + start.elapsed() + ); + + setup +} + +#[allow(dead_code)] +pub(crate) fn test_wrapper_circuit_inner( + proof: ZkSyncCompressionForWrapperProof, + vk: ZkSyncCompressionForWrapperVerificationKey, + config: WrapperConfig, +) { + let wrapper_type = config.get_wrapper_type(); + + let compression_for_wrapper_type = config.get_compression_for_wrapper_type(); + assert_eq!(compression_for_wrapper_type, proof.numeric_circuit_type()); + assert_eq!(compression_for_wrapper_type, vk.numeric_circuit_type()); + + let proof = proof.into_inner(); + let vk = vk.into_inner(); + + let mut assembly = ProvingAssembly::< + Bn256, + PlonkCsWidth4WithNextStepAndCustomGatesParams, + SelectorOptimizedWidth4MainGateWithDNext, + >::new(); + + let fixed_parameters = vk.fixed_parameters.clone(); + + let wrapper_function = ZkSyncCompressionWrapper::from_numeric_circuit_type(wrapper_type); + let wrapper_circuit = WrapperCircuit::<_, _, TreeHasherForWrapper, TranscriptForWrapper, _> { + witness: Some(proof), + vk: vk, + fixed_parameters, + transcript_params: (), + wrapper_function, + }; + + println!("Synthesizing Bn256 Bellman wrapping proof"); + wrapper_circuit.synthesize(&mut assembly).unwrap(); + + assembly.finalize_to_size_log_2(L1_VERIFIER_DOMAIN_SIZE_LOG); + assert!(assembly.is_satisfied()); + println!("Bn256 Bellman wrapper circuit is SATISFIED"); +} + +fn compute_wrapper_proof_inner( + proof: ZkSyncCompressionForWrapperProof, + vk: ZkSyncCompressionForWrapperVerificationKey, + snark_setup: ZkSyncSnarkWrapperSetup, + config: WrapperConfig, + worker: &BellmanWorker, +) -> SnarkProof { + check_trusted_setup_file_existace(); + + let start = std::time::Instant::now(); + let wrapper_type = config.get_wrapper_type(); + + let compression_for_wrapper_type = config.get_compression_for_wrapper_type(); + assert_eq!(compression_for_wrapper_type, proof.numeric_circuit_type()); + assert_eq!(compression_for_wrapper_type, vk.numeric_circuit_type()); + assert_eq!(wrapper_type, snark_setup.numeric_circuit_type()); + + let proof = proof.into_inner(); + let vk = vk.into_inner(); + let snark_setup = snark_setup.into_inner(); + + let mut assembly = ProvingAssembly::< + Bn256, + PlonkCsWidth4WithNextStepAndCustomGatesParams, + SelectorOptimizedWidth4MainGateWithDNext, + >::new(); + + let fixed_parameters = vk.fixed_parameters.clone(); + + let wrapper_function = ZkSyncCompressionWrapper::from_numeric_circuit_type(wrapper_type); + let wrapper_circuit = WrapperCircuit::<_, _, TreeHasherForWrapper, TranscriptForWrapper, _> { + witness: Some(proof), + vk: vk, + fixed_parameters, + transcript_params: (), + wrapper_function, + }; + + println!("Synthesizing Bn256 Bellman wrapping proof"); + wrapper_circuit.synthesize(&mut assembly).unwrap(); + + assembly.finalize_to_size_log_2(L1_VERIFIER_DOMAIN_SIZE_LOG); + assert!(assembly.is_satisfied()); + println!("Bn256 Bellman wrapper circuit is SATISFIED"); + + println!( + "Wrapper benchmark: {} gates for mode {}", + assembly.n(), + wrapper_type + ); + + let crs_mons = get_trusted_setup(); + + println!("Proving"); + let proof = + assembly + .create_proof::, RollingKeccakTranscript>(worker, &snark_setup, &crs_mons, None) + .unwrap(); + + println!( + "Wrapper proof {} is done, taken {:?}", + wrapper_type, + start.elapsed() + ); + + proof +} diff --git a/crates/zkevm_test_harness/src/prover_utils.rs b/crates/zkevm_test_harness/src/prover_utils.rs new file mode 100644 index 0000000..6cb4011 --- /dev/null +++ b/crates/zkevm_test_harness/src/prover_utils.rs @@ -0,0 +1,903 @@ +use super::*; + +use crate::boojum::algebraic_props::round_function::AbsorptionModeOverwrite; +use crate::boojum::algebraic_props::sponge::GoldilocksPoseidon2Sponge; +use crate::boojum::config::*; +use crate::boojum::cs::implementations::hints::*; +use crate::boojum::cs::implementations::polynomial_storage::*; +use crate::boojum::cs::implementations::verifier::*; +use crate::boojum::cs::oracle::merkle_tree::*; +use crate::boojum::field::goldilocks::GoldilocksExt2; +use crate::boojum::worker::Worker; +use crate::GoldilocksField; + +use circuit_definitions::boojum::cs::implementations::reference_cs::CSReferenceAssembly; +use circuit_definitions::circuit_definitions::aux_layer::{compression::*, *}; +use circuit_definitions::circuit_definitions::base_layer::ZkSyncBaseLayerCircuit; +use circuit_definitions::circuit_definitions::recursion_layer::verifier_builder::dyn_verifier_builder_for_recursive_circuit_type; +use circuit_definitions::circuit_definitions::recursion_layer::*; +use circuit_definitions::circuit_definitions::verifier_builder::dyn_verifier_builder_for_circuit_type; + +use circuit_definitions::ZkSyncDefaultRoundFunction; + +use rescue_poseidon::poseidon2::transcript::Poseidon2Transcript; +use rescue_poseidon::poseidon2::Poseidon2Sponge; +use snark_wrapper::franklin_crypto::bellman::pairing::bn256::{Bn256, Fr}; +use snark_wrapper::implementations::poseidon2::tree_hasher::AbsorptionModeReplacement; + +type F = GoldilocksField; +type P = GoldilocksField; +type TR = GoldilocksPoisedon2Transcript; + +type EXT = GoldilocksExt2; +type H = GoldilocksPoseidon2Sponge; + +use crate::boojum::cs::implementations::setup::FinalizationHintsForProver; + +pub fn create_base_layer_setup_data( + circuit: ZkSyncBaseLayerCircuit, + worker: &Worker, + fri_lde_factor: usize, + merkle_tree_cap_size: usize, +) -> ( + SetupBaseStorage, + SetupStorage, + VerificationKey, + MerkleTreeWithCap, + DenseVariablesCopyHint, + DenseWitnessCopyHint, + FinalizationHintsForProver, +) { + use crate::boojum::cs::cs_builder::new_builder; + use crate::boojum::cs::cs_builder_reference::CsReferenceImplementationBuilder; + + let geometry = circuit.geometry(); + let (max_trace_len, num_vars) = circuit.size_hint(); + + let builder_impl = CsReferenceImplementationBuilder::::new( + geometry, + max_trace_len.unwrap(), + ); + + let builder = new_builder::<_, GoldilocksField>(builder_impl); + + let (cs, finalization_hint) = match circuit { + ZkSyncBaseLayerCircuit::MainVM(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + let (_, finalization_hint) = cs.pad_and_shrink(); + (cs.into_assembly::(), finalization_hint) + } + ZkSyncBaseLayerCircuit::CodeDecommittmentsSorter(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + let (_, finalization_hint) = cs.pad_and_shrink(); + (cs.into_assembly::(), finalization_hint) + } + ZkSyncBaseLayerCircuit::CodeDecommitter(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + let (_, finalization_hint) = cs.pad_and_shrink(); + (cs.into_assembly::(), finalization_hint) + } + ZkSyncBaseLayerCircuit::LogDemuxer(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + let (_, finalization_hint) = cs.pad_and_shrink(); + (cs.into_assembly::(), finalization_hint) + } + ZkSyncBaseLayerCircuit::KeccakRoundFunction(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + let (_, finalization_hint) = cs.pad_and_shrink(); + (cs.into_assembly::(), finalization_hint) + } + ZkSyncBaseLayerCircuit::Sha256RoundFunction(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + let (_, finalization_hint) = cs.pad_and_shrink(); + (cs.into_assembly::(), finalization_hint) + } + ZkSyncBaseLayerCircuit::ECRecover(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + let (_, finalization_hint) = cs.pad_and_shrink(); + (cs.into_assembly::(), finalization_hint) + } + ZkSyncBaseLayerCircuit::RAMPermutation(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + let (_, finalization_hint) = cs.pad_and_shrink(); + (cs.into_assembly::(), finalization_hint) + } + ZkSyncBaseLayerCircuit::StorageSorter(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + let (_, finalization_hint) = cs.pad_and_shrink(); + (cs.into_assembly::(), finalization_hint) + } + ZkSyncBaseLayerCircuit::StorageApplication(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + let (_, finalization_hint) = cs.pad_and_shrink(); + (cs.into_assembly::(), finalization_hint) + } + ZkSyncBaseLayerCircuit::EventsSorter(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + let (_, finalization_hint) = cs.pad_and_shrink(); + (cs.into_assembly::(), finalization_hint) + } + ZkSyncBaseLayerCircuit::L1MessagesSorter(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + let (_, finalization_hint) = cs.pad_and_shrink(); + (cs.into_assembly::(), finalization_hint) + } + ZkSyncBaseLayerCircuit::L1MessagesHasher(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + let (_, finalization_hint) = cs.pad_and_shrink(); + (cs.into_assembly::(), finalization_hint) + } + ZkSyncBaseLayerCircuit::TransientStorageSorter(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + let (_, finalization_hint) = cs.pad_and_shrink(); + (cs.into_assembly::(), finalization_hint) + } + ZkSyncBaseLayerCircuit::Secp256r1Verify(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + let (_, finalization_hint) = cs.pad_and_shrink(); + (cs.into_assembly::(), finalization_hint) + } + ZkSyncBaseLayerCircuit::EIP4844Repack(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + let (_, finalization_hint) = cs.pad_and_shrink(); + (cs.into_assembly::(), finalization_hint) + } + }; + + let (setup_base, setup, vk, setup_tree, vars_hint, witness_hints) = + cs.get_full_setup(worker, fri_lde_factor, merkle_tree_cap_size); + + ( + setup_base, + setup, + vk, + setup_tree, + vars_hint, + witness_hints, + finalization_hint, + ) +} + +use crate::boojum::cs::implementations::proof::Proof; +use crate::boojum::cs::implementations::prover::ProofConfig; +use crate::boojum::cs::implementations::transcript::GoldilocksPoisedon2Transcript; + +use crate::boojum::cs::implementations::pow::PoWRunner; + +pub fn prove_base_layer_circuit( + circuit: ZkSyncBaseLayerCircuit, + worker: &Worker, + proof_config: ProofConfig, + setup_base: &SetupBaseStorage, + setup: &SetupStorage, + setup_tree: &MerkleTreeWithCap, + vk: &VerificationKey, + vars_hint: &DenseVariablesCopyHint, + wits_hint: &DenseWitnessCopyHint, + finalization_hint: &FinalizationHintsForProver, +) -> Proof { + use crate::boojum::cs::cs_builder::new_builder; + use crate::boojum::cs::cs_builder_reference::CsReferenceImplementationBuilder; + + let geometry = circuit.geometry(); + let (max_trace_len, num_vars) = circuit.size_hint(); + + let builder_impl = CsReferenceImplementationBuilder::::new( + geometry, + max_trace_len.unwrap(), + ); + let builder = new_builder::<_, GoldilocksField>(builder_impl); + + let cs = match circuit { + ZkSyncBaseLayerCircuit::MainVM(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + cs.pad_and_shrink_using_hint(finalization_hint); + cs.into_assembly::() + } + ZkSyncBaseLayerCircuit::CodeDecommittmentsSorter(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + cs.pad_and_shrink_using_hint(finalization_hint); + cs.into_assembly::() + } + ZkSyncBaseLayerCircuit::CodeDecommitter(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + cs.pad_and_shrink_using_hint(finalization_hint); + cs.into_assembly::() + } + ZkSyncBaseLayerCircuit::LogDemuxer(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + cs.pad_and_shrink_using_hint(finalization_hint); + cs.into_assembly::() + } + ZkSyncBaseLayerCircuit::KeccakRoundFunction(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + cs.pad_and_shrink_using_hint(finalization_hint); + cs.into_assembly::() + } + ZkSyncBaseLayerCircuit::Sha256RoundFunction(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + cs.pad_and_shrink_using_hint(finalization_hint); + cs.into_assembly::() + } + ZkSyncBaseLayerCircuit::ECRecover(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + cs.pad_and_shrink_using_hint(finalization_hint); + cs.into_assembly::() + } + ZkSyncBaseLayerCircuit::RAMPermutation(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + cs.pad_and_shrink_using_hint(finalization_hint); + cs.into_assembly::() + } + ZkSyncBaseLayerCircuit::StorageSorter(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + cs.pad_and_shrink_using_hint(finalization_hint); + cs.into_assembly::() + } + ZkSyncBaseLayerCircuit::StorageApplication(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + cs.pad_and_shrink_using_hint(finalization_hint); + cs.into_assembly::() + } + ZkSyncBaseLayerCircuit::EventsSorter(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + cs.pad_and_shrink_using_hint(finalization_hint); + cs.into_assembly::() + } + ZkSyncBaseLayerCircuit::L1MessagesSorter(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + cs.pad_and_shrink_using_hint(finalization_hint); + cs.into_assembly::() + } + ZkSyncBaseLayerCircuit::L1MessagesHasher(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + cs.pad_and_shrink_using_hint(finalization_hint); + cs.into_assembly::() + } + ZkSyncBaseLayerCircuit::TransientStorageSorter(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + cs.pad_and_shrink_using_hint(finalization_hint); + cs.into_assembly::() + } + ZkSyncBaseLayerCircuit::Secp256r1Verify(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + cs.pad_and_shrink_using_hint(finalization_hint); + cs.into_assembly::() + } + ZkSyncBaseLayerCircuit::EIP4844Repack(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + cs.pad_and_shrink_using_hint(finalization_hint); + cs.into_assembly::() + } + }; + + cs.prove_from_precomputations::( + proof_config, + setup_base, + setup, + setup_tree, + vk, + vars_hint, + wits_hint, + (), + worker, + ) +} + +pub fn verify_base_layer_proof( + circuit: &ZkSyncBaseLayerCircuit, + proof: &Proof, + vk: &VerificationKey, +) -> bool { + let verifier_builder = dyn_verifier_builder_for_circuit_type(circuit.numeric_circuit_type()); + let verifier = verifier_builder.create_verifier(); + verifier.verify::((), vk, proof) +} + +pub fn verify_base_layer_proof_for_type( + circuit_type: u8, + proof: &Proof, + vk: &VerificationKey, +) -> bool { + let verifier_builder = dyn_verifier_builder_for_circuit_type(circuit_type); + let verifier = verifier_builder.create_verifier(); + verifier.verify::((), vk, proof) +} + +pub fn create_recursive_layer_setup_data( + circuit: ZkSyncRecursiveLayerCircuit, + worker: &Worker, + fri_lde_factor: usize, + merkle_tree_cap_size: usize, +) -> ( + SetupBaseStorage, + SetupStorage, + VerificationKey, + MerkleTreeWithCap, + DenseVariablesCopyHint, + DenseWitnessCopyHint, + FinalizationHintsForProver, +) { + use crate::boojum::cs::cs_builder::new_builder; + use crate::boojum::cs::cs_builder_reference::CsReferenceImplementationBuilder; + + let round_function = ZkSyncDefaultRoundFunction::default(); + + let geometry = circuit.geometry(); + let (max_trace_len, num_vars) = circuit.size_hint(); + + let builder_impl = CsReferenceImplementationBuilder::::new( + geometry, + max_trace_len.unwrap(), + ); + let builder = new_builder::<_, GoldilocksField>(builder_impl); + + let (cs, finalization_hint) = match circuit { + ZkSyncRecursiveLayerCircuit::SchedulerCircuit(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables(&mut cs); + inner.synthesize_into_cs(&mut cs, &round_function); + let (_, finalization_hint) = cs.pad_and_shrink(); + (cs.into_assembly::(), finalization_hint) + } + ZkSyncRecursiveLayerCircuit::NodeLayerCircuit(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables(&mut cs); + inner.synthesize_into_cs(&mut cs, &round_function); + let (_, finalization_hint) = cs.pad_and_shrink(); + (cs.into_assembly::(), finalization_hint) + } + ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForMainVM(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForCodeDecommittmentsSorter(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForCodeDecommitter(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForLogDemuxer(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForKeccakRoundFunction(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForSha256RoundFunction(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForECRecover(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForRAMPermutation(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForStorageSorter(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForStorageApplication(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForEventsSorter(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForL1MessagesSorter(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForL1MessagesHasher(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForTransientStorageSorter(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForSecp256r1Verify(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForEIP4844Repack(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables(&mut cs); + inner.synthesize_into_cs(&mut cs, &round_function); + let (_, finalization_hint) = cs.pad_and_shrink(); + (cs.into_assembly::(), finalization_hint) + } + ZkSyncRecursiveLayerCircuit::RecursionTipCircuit(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables(&mut cs); + inner.synthesize_into_cs(&mut cs, &round_function); + let (_, finalization_hint) = cs.pad_and_shrink(); + (cs.into_assembly::(), finalization_hint) + } + }; + + let (setup_base, setup, vk, setup_tree, vars_hint, witness_hints) = + cs.get_full_setup(worker, fri_lde_factor, merkle_tree_cap_size); + + ( + setup_base, + setup, + vk, + setup_tree, + vars_hint, + witness_hints, + finalization_hint, + ) +} + +pub fn prove_recursion_layer_circuit( + circuit: ZkSyncRecursiveLayerCircuit, + worker: &Worker, + proof_config: ProofConfig, + setup_base: &SetupBaseStorage, + setup: &SetupStorage, + setup_tree: &MerkleTreeWithCap, + vk: &VerificationKey, + vars_hint: &DenseVariablesCopyHint, + wits_hint: &DenseWitnessCopyHint, + finalization_hint: &FinalizationHintsForProver, +) -> Proof { + use crate::boojum::cs::cs_builder::new_builder; + use crate::boojum::cs::cs_builder_reference::CsReferenceImplementationBuilder; + + let round_function = ZkSyncDefaultRoundFunction::default(); + + let geometry = circuit.geometry(); + let (max_trace_len, num_vars) = circuit.size_hint(); + + use crate::boojum::config::CSConfig; + let builder_impl = CsReferenceImplementationBuilder::< + GoldilocksField, + P, + ProvingCSConfig, + crate::boojum::dag::StCircuitResolver< + GoldilocksField, + ::ResolverConfig, + >, + >::new(geometry, max_trace_len.unwrap()); + let builder = new_builder::<_, GoldilocksField>(builder_impl); + + let cs = match circuit { + ZkSyncRecursiveLayerCircuit::SchedulerCircuit(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables(&mut cs); + inner.synthesize_into_cs(&mut cs, &round_function); + cs.pad_and_shrink_using_hint(finalization_hint); + cs.into_assembly::() + } + ZkSyncRecursiveLayerCircuit::NodeLayerCircuit(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables(&mut cs); + inner.synthesize_into_cs(&mut cs, &round_function); + cs.pad_and_shrink_using_hint(finalization_hint); + cs.into_assembly::() + } + ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForMainVM(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForCodeDecommittmentsSorter(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForCodeDecommitter(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForLogDemuxer(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForKeccakRoundFunction(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForSha256RoundFunction(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForECRecover(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForRAMPermutation(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForStorageSorter(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForStorageApplication(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForEventsSorter(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForL1MessagesSorter(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForL1MessagesHasher(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForTransientStorageSorter(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForSecp256r1Verify(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForEIP4844Repack(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables(&mut cs); + inner.synthesize_into_cs(&mut cs, &round_function); + cs.pad_and_shrink_using_hint(finalization_hint); + cs.into_assembly::() + } + ZkSyncRecursiveLayerCircuit::RecursionTipCircuit(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables(&mut cs); + inner.synthesize_into_cs(&mut cs, &round_function); + cs.pad_and_shrink_using_hint(finalization_hint); + cs.into_assembly::() + } + }; + + cs.prove_from_precomputations::( + proof_config, + setup_base, + setup, + setup_tree, + vk, + vars_hint, + wits_hint, + (), + worker, + ) +} + +pub fn verify_recursion_layer_proof( + circuit: &ZkSyncRecursiveLayerCircuit, + proof: &Proof, + vk: &VerificationKey, +) -> bool { + let verifier_builder = circuit.into_dyn_verifier_builder(); + let verifier = verifier_builder.create_verifier(); + verifier.verify::((), vk, proof) +} + +pub fn verify_recursion_layer_proof_for_type( + circuit_type: ZkSyncRecursionLayerStorageType, + proof: &Proof, + vk: &VerificationKey, +) -> bool { + let verifier_builder = dyn_verifier_builder_for_recursive_circuit_type(circuit_type); + let verifier = verifier_builder.create_verifier(); + verifier.verify::((), vk, proof) +} + +pub fn create_compression_layer_setup_data( + circuit: ZkSyncCompressionLayerCircuit, + worker: &Worker, + fri_lde_factor: usize, + merkle_tree_cap_size: usize, +) -> ( + SetupBaseStorage, + SetupStorage, + VerificationKey, + MerkleTreeWithCap, + DenseVariablesCopyHint, + DenseWitnessCopyHint, + FinalizationHintsForProver, +) { + use crate::boojum::cs::cs_builder::new_builder; + use crate::boojum::cs::cs_builder_reference::CsReferenceImplementationBuilder; + + fn synthesize_inner( + circuit: CompressionLayerCircuit, + ) -> ( + CSReferenceAssembly, + FinalizationHintsForProver, + ) { + let geometry = circuit.geometry(); + let (max_trace_len, num_vars) = circuit.size_hint(); + + let builder_impl = + CsReferenceImplementationBuilder::::new( + geometry, + max_trace_len.unwrap(), + ); + let builder = new_builder::<_, GoldilocksField>(builder_impl); + + let builder = circuit.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + circuit.add_tables(&mut cs); + circuit.synthesize_into_cs(&mut cs); + let (_, finalization_hint) = cs.pad_and_shrink(); + (cs.into_assembly::(), finalization_hint) + } + + let (cs, finalization_hint) = match circuit { + ZkSyncCompressionLayerCircuit::CompressionMode1Circuit(inner) => synthesize_inner(inner), + ZkSyncCompressionLayerCircuit::CompressionMode2Circuit(inner) => synthesize_inner(inner), + ZkSyncCompressionLayerCircuit::CompressionMode3Circuit(inner) => synthesize_inner(inner), + ZkSyncCompressionLayerCircuit::CompressionMode4Circuit(inner) => synthesize_inner(inner), + ZkSyncCompressionLayerCircuit::CompressionMode5Circuit(inner) => synthesize_inner(inner), + }; + + let (setup_base, setup, vk, setup_tree, vars_hint, witness_hints) = + cs.get_full_setup(worker, fri_lde_factor, merkle_tree_cap_size); + + ( + setup_base, + setup, + vk, + setup_tree, + vars_hint, + witness_hints, + finalization_hint, + ) +} + +pub fn prove_compression_layer_circuit( + circuit: ZkSyncCompressionLayerCircuit, + worker: &Worker, + proof_config: ProofConfig, + setup_base: &SetupBaseStorage, + setup: &SetupStorage, + setup_tree: &MerkleTreeWithCap, + vk: &VerificationKey, + vars_hint: &DenseVariablesCopyHint, + wits_hint: &DenseWitnessCopyHint, + finalization_hint: &FinalizationHintsForProver, +) -> Proof { + use crate::boojum::cs::cs_builder::new_builder; + use crate::boojum::cs::cs_builder_reference::CsReferenceImplementationBuilder; + + fn synthesize_inner( + circuit: CompressionLayerCircuit, + finalization_hint: &FinalizationHintsForProver, + ) -> CSReferenceAssembly { + let geometry = circuit.geometry(); + let (max_trace_len, num_vars) = circuit.size_hint(); + + let builder_impl = + CsReferenceImplementationBuilder::::new( + geometry, + max_trace_len.unwrap(), + ); + let builder = new_builder::<_, GoldilocksField>(builder_impl); + + let builder = circuit.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + circuit.add_tables(&mut cs); + circuit.synthesize_into_cs(&mut cs); + cs.pad_and_shrink_using_hint(finalization_hint); + cs.into_assembly::() + } + + let cs = match circuit { + ZkSyncCompressionLayerCircuit::CompressionMode1Circuit(inner) => { + synthesize_inner(inner, finalization_hint) + } + ZkSyncCompressionLayerCircuit::CompressionMode2Circuit(inner) => { + synthesize_inner(inner, finalization_hint) + } + ZkSyncCompressionLayerCircuit::CompressionMode3Circuit(inner) => { + synthesize_inner(inner, finalization_hint) + } + ZkSyncCompressionLayerCircuit::CompressionMode4Circuit(inner) => { + synthesize_inner(inner, finalization_hint) + } + ZkSyncCompressionLayerCircuit::CompressionMode5Circuit(inner) => { + synthesize_inner(inner, finalization_hint) + } + }; + + cs.prove_from_precomputations::( + proof_config, + setup_base, + setup, + setup_tree, + vk, + vars_hint, + wits_hint, + (), + worker, + ) +} + +pub fn verify_compression_layer_proof( + circuit: &ZkSyncCompressionLayerCircuit, + proof: &Proof, + vk: &VerificationKey, +) -> bool { + let verifier_builder = circuit.into_dyn_verifier_builder(); + let verifier = verifier_builder.create_verifier(); + verifier.verify::((), vk, proof) +} + +pub type TreeHasherForWrapper = Poseidon2Sponge, 2, 3>; +pub type TranscriptForWrapper = Poseidon2Transcript, 2, 3>; + +pub fn create_compression_for_wrapper_setup_data( + circuit: ZkSyncCompressionForWrapperCircuit, + worker: &Worker, + fri_lde_factor: usize, + merkle_tree_cap_size: usize, +) -> ( + SetupBaseStorage, + SetupStorage, + VerificationKey, + MerkleTreeWithCap, + DenseVariablesCopyHint, + DenseWitnessCopyHint, + FinalizationHintsForProver, +) { + use crate::boojum::cs::cs_builder::new_builder; + use crate::boojum::cs::cs_builder_reference::CsReferenceImplementationBuilder; + + fn synthesize_inner( + circuit: CompressionLayerCircuit, + ) -> ( + CSReferenceAssembly, + FinalizationHintsForProver, + ) { + let geometry = circuit.geometry(); + let (max_trace_len, num_vars) = circuit.size_hint(); + + let builder_impl = + CsReferenceImplementationBuilder::::new( + geometry, + max_trace_len.unwrap(), + ); + let builder = new_builder::<_, GoldilocksField>(builder_impl); + + let builder = circuit.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + circuit.add_tables(&mut cs); + circuit.synthesize_into_cs(&mut cs); + let (_, finalization_hint) = cs.pad_and_shrink(); + (cs.into_assembly::(), finalization_hint) + } + + let (cs, finalization_hint) = match circuit { + ZkSyncCompressionForWrapperCircuit::CompressionMode1Circuit(inner) => { + synthesize_inner(inner) + } + ZkSyncCompressionForWrapperCircuit::CompressionMode2Circuit(inner) => { + synthesize_inner(inner) + } + ZkSyncCompressionForWrapperCircuit::CompressionMode3Circuit(inner) => { + synthesize_inner(inner) + } + ZkSyncCompressionForWrapperCircuit::CompressionMode4Circuit(inner) => { + synthesize_inner(inner) + } + ZkSyncCompressionForWrapperCircuit::CompressionMode5Circuit(inner) => { + synthesize_inner(inner) + } + }; + + let (setup_base, setup, vk, setup_tree, vars_hint, witness_hints) = + cs.get_full_setup(worker, fri_lde_factor, merkle_tree_cap_size); + + ( + setup_base, + setup, + vk, + setup_tree, + vars_hint, + witness_hints, + finalization_hint, + ) +} + +pub fn prove_compression_for_wrapper_circuit( + circuit: ZkSyncCompressionForWrapperCircuit, + worker: &Worker, + proof_config: ProofConfig, + setup_base: &SetupBaseStorage, + setup: &SetupStorage, + setup_tree: &MerkleTreeWithCap, + vk: &VerificationKey, + vars_hint: &DenseVariablesCopyHint, + wits_hint: &DenseWitnessCopyHint, + finalization_hint: &FinalizationHintsForProver, +) -> Proof { + use crate::boojum::cs::cs_builder::new_builder; + use crate::boojum::cs::cs_builder_reference::CsReferenceImplementationBuilder; + + fn synthesize_inner( + circuit: CompressionLayerCircuit, + finalization_hint: &FinalizationHintsForProver, + ) -> CSReferenceAssembly { + let geometry = circuit.geometry(); + let (max_trace_len, num_vars) = circuit.size_hint(); + + let builder_impl = + CsReferenceImplementationBuilder::::new( + geometry, + max_trace_len.unwrap(), + ); + let builder = new_builder::<_, GoldilocksField>(builder_impl); + + let builder = circuit.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + circuit.add_tables(&mut cs); + circuit.synthesize_into_cs(&mut cs); + cs.pad_and_shrink_using_hint(finalization_hint); + cs.into_assembly::() + } + + let cs = match circuit { + ZkSyncCompressionForWrapperCircuit::CompressionMode1Circuit(inner) => { + synthesize_inner(inner, finalization_hint) + } + ZkSyncCompressionForWrapperCircuit::CompressionMode2Circuit(inner) => { + synthesize_inner(inner, finalization_hint) + } + ZkSyncCompressionForWrapperCircuit::CompressionMode3Circuit(inner) => { + synthesize_inner(inner, finalization_hint) + } + ZkSyncCompressionForWrapperCircuit::CompressionMode4Circuit(inner) => { + synthesize_inner(inner, finalization_hint) + } + ZkSyncCompressionForWrapperCircuit::CompressionMode5Circuit(inner) => { + synthesize_inner(inner, finalization_hint) + } + }; + + cs.prove_from_precomputations::( + proof_config, + setup_base, + setup, + setup_tree, + vk, + vars_hint, + wits_hint, + (), + worker, + ) +} + +pub fn verify_compression_for_wrapper_proof( + circuit: &ZkSyncCompressionForWrapperCircuit, + proof: &Proof, + vk: &VerificationKey, +) -> bool { + let verifier_builder = circuit.into_dyn_verifier_builder(); + let verifier = verifier_builder.create_verifier(); + verifier.verify::((), vk, proof) +} diff --git a/crates/zkevm_test_harness/src/run_vms.rs b/crates/zkevm_test_harness/src/run_vms.rs new file mode 100644 index 0000000..3dce3fa --- /dev/null +++ b/crates/zkevm_test_harness/src/run_vms.rs @@ -0,0 +1,638 @@ +use crate::blake2::Blake2s256; +use crate::boojum::field::goldilocks::GoldilocksField; +use crate::boojum::gadgets::traits::allocatable::*; +use crate::entry_point::*; +use crate::snark_wrapper::boojum::field::goldilocks::GoldilocksExt2; +use crate::snark_wrapper::boojum::gadgets::recursion::recursive_tree_hasher::CircuitGoldilocksPoseidon2Sponge; +use crate::toolset::create_tools; +use crate::toolset::GeometryConfig; +use crate::witness::oracle::create_artifacts_from_tracer; +use crate::witness::oracle::WitnessGenerationArtifact; +use crate::witness::tracer::tracer::WitnessTracer; +use crate::witness::tree::BinarySparseStorageTree; +use crate::witness::tree::ZkSyncStorageLeaf; +use crate::witness::utils::{ + take_queue_state_from_simulator, take_sponge_like_queue_state_from_simulator, +}; +use crate::zk_evm::abstractions::Storage; +use crate::zk_evm::abstractions::*; +use crate::zk_evm::aux_structures::*; +use crate::zk_evm::bytecode_to_code_hash; +use crate::zk_evm::contract_bytecode_to_words; +use crate::zk_evm::witness_trace::VmWitnessTracer; +use crate::zk_evm::GenericNoopTracer; +use crate::zkevm_circuits::linear_hasher::input::LinearHasherOutputDataWitness; +use crate::zkevm_circuits::scheduler::block_header::BlockAuxilaryOutputWitness; +use crate::zkevm_circuits::{ + base_structures::vm_state::FULL_SPONGE_QUEUE_STATE_WIDTH, + eip_4844::input::*, + scheduler::{block_header::MAX_4844_BLOBS_PER_BLOCK, input::SchedulerCircuitInstanceWitness}, +}; +use crate::{ + ethereum_types::{Address, U256}, + utils::{calldata_to_aligned_data, u64_as_u32_le}, +}; +use circuit_definitions::boojum::field::Field; +use circuit_definitions::circuit_definitions::base_layer::ZkSyncBaseLayerCircuit; +use circuit_definitions::encodings::recursion_request::RecursionQueueSimulator; +use circuit_definitions::zk_evm::reference_impls::memory::SimpleMemory; +use circuit_definitions::zk_evm::tracing::Tracer; +use circuit_definitions::zk_evm::zkevm_opcode_defs::VersionedHashLen32; +use circuit_definitions::zkevm_circuits::fsm_input_output::ClosedFormInputCompactFormWitness; +use circuit_definitions::{Field as MainField, ZkSyncDefaultRoundFunction}; +use std::collections::VecDeque; + +pub const SCHEDULER_TIMESTAMP: u32 = 1; + +#[derive(Debug)] +pub enum RunVmError { + InvalidInput(String), + OutOfCircuitExecutionError(String), +} + +pub type RunVMsResult = ( + SchedulerCircuitInstanceWitness, + BlockAuxilaryOutputWitness, +); + +/// Executes a given set of instructions, and returns things necessary to do the proving: +/// - all circuits as a callback +/// - circuit recursion queues and associated inputs as a callback +/// - partial witness for the scheduler circuit (later we have to add proof witnesses for the nodes) +/// - witness with AUX data (with information that might be useful during verification to generate the public input) +/// +/// This function will setup the environment and will run out-of-circuit and then in-circuit +pub fn run_vms( + caller: Address, // for real block must be zero + entry_point_address: Address, // for real block must be the bootloader + entry_point_code: Vec<[u8; 32]>, // for read block must be a bootloader code + initial_heap_content: Vec, // bootloader starts with non-deterministic heap + zk_porter_is_available: bool, + default_aa_code_hash: U256, + evm_simulator_code_hash: U256, + used_bytecodes: std::collections::HashMap>, // auxilary information to avoid passing a full set of all used codes + ram_verification_queries: Vec<(u32, U256)>, // we may need to check that after the bootloader's memory is filled + cycle_limit: usize, + geometry: GeometryConfig, + storage: S, + tree: impl BinarySparseStorageTree<256, 32, 32, 8, 32, Blake2s256, ZkSyncStorageLeaf>, + trusted_setup_path: &str, + eip_4844_repack_inputs: [Option>; MAX_4844_BLOBS_PER_BLOCK], + artifacts_callback: CB, + out_of_circuit_tracer: &mut impl Tracer, +) -> Result { + let round_function = ZkSyncDefaultRoundFunction::default(); + + if zk_porter_is_available { + return Err(RunVmError::InvalidInput("zk porter not allowed".to_owned())); + } + + if !ram_verification_queries.is_empty() { + return Err(RunVmError::InvalidInput("ram_verification_queries isn't empty; for now it's implemented such that we do not need it".to_owned())); + } + + let initial_rollup_root = tree.root(); + let initial_rollup_enumeration_counter = tree.next_enumeration_index(); + + let bytecode_hash = bytecode_to_code_hash(&entry_point_code).unwrap(); + + let mut tools = create_tools(storage, &geometry); + + // fill the tools + let mut to_fill = vec![]; + let entry_point_code_hash_as_u256 = U256::from_big_endian(&bytecode_hash); + if !used_bytecodes.contains_key(&entry_point_code_hash_as_u256) { + to_fill.push(( + entry_point_code_hash_as_u256, + contract_bytecode_to_words(&entry_point_code), + )); + } + for (k, v) in used_bytecodes.into_iter() { + to_fill.push((k, contract_bytecode_to_words(&v))); + } + tools.decommittment_processor.populate(to_fill); + + let heap_writes = calldata_to_aligned_data(&initial_heap_content); + let num_non_deterministic_heap_queries = heap_writes.len(); + + let (header, normalized_preimage) = crate::zk_evm::zkevm_opcode_defs::definitions::versioned_hash::ContractCodeSha256Format::normalize_for_decommitment(&bytecode_hash); + + // bootloader decommit query + let entry_point_decommittment_query = DecommittmentQuery { + header, + normalized_preimage, + timestamp: Timestamp(SCHEDULER_TIMESTAMP), + memory_page: MemoryPage(crate::zk_evm::zkevm_opcode_defs::BOOTLOADER_CODE_PAGE), + decommitted_length: entry_point_code.len() as u16, + is_fresh: true, + }; + + // manually decommit entry point + let prepared_entry_point_decommittment_query = tools + .decommittment_processor + .prepare_to_decommit(0, entry_point_decommittment_query) + .expect("must prepare decommit of entry point"); + tools + .witness_tracer + .prepare_for_decommittment(0, entry_point_decommittment_query); + let entry_point_decommittment_query_witness = tools + .decommittment_processor + .decommit_into_memory( + 0, + prepared_entry_point_decommittment_query, + &mut tools.memory, + ) + .expect("must execute decommit of entry point"); + let entry_point_decommittment_query_witness = entry_point_decommittment_query_witness.unwrap(); + tools.witness_tracer.execute_decommittment( + 0, + entry_point_decommittment_query, + entry_point_decommittment_query_witness.clone(), + ); + + let block_properties = create_out_of_circuit_global_context( + zk_porter_is_available, + default_aa_code_hash, + evm_simulator_code_hash, + ); + + use crate::toolset::create_out_of_circuit_vm; + + let mut out_of_circuit_vm = + create_out_of_circuit_vm(tools, block_properties, caller, entry_point_address); + + // first there exists non-deterministic writes into the heap of the bootloader's heap and calldata + // heap + + for (idx, el) in heap_writes.into_iter().enumerate() { + let query = MemoryQuery { + timestamp: Timestamp(0), + location: MemoryLocation { + memory_type: MemoryType::Heap, + page: MemoryPage(crate::zk_evm::zkevm_opcode_defs::BOOTLOADER_HEAP_PAGE), + index: MemoryIndex(idx as u32), + }, + rw_flag: true, + value: el, + value_is_pointer: false, + }; + out_of_circuit_vm.witness_tracer.add_memory_query(0, query); + out_of_circuit_vm.memory.execute_partial_query(0, query); + } + + // tracing::debug!("Running out of circuit for {} cycles", cycle_limit); + println!("Running out of circuit for {} cycles", cycle_limit); + let mut next_snapshot_will_capture_end_of_execution = false; + let mut snapshots_len = None; + for _cycle in 0..cycle_limit { + if out_of_circuit_vm.execution_has_ended() { + // we formally have to let VM run as it resets some of the state in a process + if next_snapshot_will_capture_end_of_execution == false { + next_snapshot_will_capture_end_of_execution = true; + snapshots_len = Some(out_of_circuit_vm.witness_tracer.vm_snapshots.len()); + } else { + if snapshots_len.unwrap() != out_of_circuit_vm.witness_tracer.vm_snapshots.len() { + // snapshot has captured the final state + break; + } + } + } + out_of_circuit_vm + .cycle(out_of_circuit_tracer) + .expect("cycle should finish succesfully"); + } + + if !out_of_circuit_vm.execution_has_ended() { + return Err(RunVmError::OutOfCircuitExecutionError( + "VM execution didn't finish".to_owned(), + )); + } + if out_of_circuit_vm.local_state.callstack.current.pc != 0 { + return Err(RunVmError::OutOfCircuitExecutionError( + "root frame ended up with panic".to_owned(), + )); + } + + println!("Out of circuit tracing is complete, now running witness generation"); + + let vm_local_state = out_of_circuit_vm.local_state.clone(); + + if !next_snapshot_will_capture_end_of_execution { + // perform the final snapshot + let current_cycle_counter = out_of_circuit_vm.witness_tracer.current_cycle_counter; + use crate::witness::tracer::vm_snapshot::VmSnapshot; + let snapshot = VmSnapshot { + local_state: vm_local_state.clone(), + at_cycle: current_cycle_counter, + }; + out_of_circuit_vm.witness_tracer.vm_snapshots.push(snapshot); + } + + let witness_tracer = out_of_circuit_vm.witness_tracer.clone(); + drop(out_of_circuit_vm); + + let (basic_circuits, compact_form_witnesses, eip4844_circuits) = create_artifacts_from_tracer( + witness_tracer, + &round_function, + &geometry, + ( + entry_point_decommittment_query, + entry_point_decommittment_query_witness, + ), + tree, + num_non_deterministic_heap_queries, + zk_porter_is_available, + default_aa_code_hash, + evm_simulator_code_hash, + eip_4844_repack_inputs.clone(), + trusted_setup_path, + artifacts_callback, + ); + + let (scheduler_circuit_witness, aux_data) = { + use crate::zkevm_circuits::scheduler::block_header::*; + use crate::zkevm_circuits::scheduler::input::*; + + let prev_rollup_state = PerShardStateWitness { + enumeration_counter: u64_as_u32_le(initial_rollup_enumeration_counter), + state_root: initial_rollup_root, + }; + + let prev_porter_state = PerShardStateWitness { + enumeration_counter: [0; 2], + state_root: [0u8; 32], + }; + + let previous_block_passthrough = BlockPassthroughDataWitness { + per_shard_states: [prev_rollup_state, prev_porter_state], + }; + + // now we need parameters and aux + // parameters + + let block_meta_parameters = BlockMetaParametersWitness { + bootloader_code_hash: entry_point_code_hash_as_u256, + default_aa_code_hash: default_aa_code_hash, + zkporter_is_available: zk_porter_is_available, + evm_simulator_code_hash: evm_simulator_code_hash, + }; + + use crate::zkevm_circuits::base_structures::vm_state::QUEUE_STATE_WIDTH; + + let t = basic_circuits + .events_sorter_circuits + .last + .as_ref() + .map(|wit| wit.observable_output.final_queue_state.tail.tail) + .unwrap_or([MainField::ZERO; QUEUE_STATE_WIDTH]); + + use crate::finalize_queue_state; + use crate::finalized_queue_state_as_bytes; + + let events_queue_state = finalize_queue_state(t, &round_function); + let events_queue_state = finalized_queue_state_as_bytes(events_queue_state); + + let t = basic_circuits + .main_vm_circuits + .first + .as_ref() + .map(|wit| wit.observable_input.memory_queue_initial_state.tail) + .unwrap_or([MainField::ZERO; FULL_SPONGE_QUEUE_STATE_WIDTH]); + + let bootloader_heap_initial_content = finalize_queue_state(t, &round_function); + let bootloader_heap_initial_content = + finalized_queue_state_as_bytes(bootloader_heap_initial_content); + + let rollup_state_diff_for_compression = basic_circuits + .storage_application_circuits + .last + .as_ref() + .map(|wit| wit.observable_output.state_diffs_keccak256_hash) + .unwrap_or([0u8; 32]); + + let l1_messages_linear_hash = basic_circuits + .l1_messages_hasher_circuits + .last + .as_ref() + .map(|wit| wit.observable_output.keccak256_hash) + .unwrap_or([0u8; 32]); + + // aux + let aux_data = BlockAuxilaryOutputWitness:: { + events_queue_state, + bootloader_heap_initial_content, + rollup_state_diff_for_compression, + l1_messages_linear_hash: l1_messages_linear_hash, + eip4844_linear_hashes: [[0u8; 32]; MAX_4844_BLOBS_PER_BLOCK], + eip4844_output_commitment_hashes: [[0u8; 32]; MAX_4844_BLOBS_PER_BLOCK], + }; + + // here we perform a logic that is similar to what is in scheduler when we require of some circuit type is skipped, then + // we ignore/constraint it's output + + // VM can not be skipped + + use crate::witness::artifacts::LogQueueStates; + use circuit_definitions::encodings::memory_query::MemoryQueueSimulator; + + let empty_log_queue_state = take_queue_state_from_simulator( + &LogQueueStates::::default().simulator, + ); + let empty_sponge_like_queue_state = take_sponge_like_queue_state_from_simulator( + &MemoryQueueSimulator::::empty(), + ); + + // decommitter must output empty sequence (unreachable in practice, but still...) + let decommits_sorter_observable_output = if let Some(last) = + basic_circuits.code_decommittments_sorter_circuits.last + { + let observable_output = last.observable_output; + + observable_output + } else { + // form it manually + use crate::zkevm_circuits::sort_decommittment_requests::input::CodeDecommittmentsDeduplicatorOutputDataWitness; + CodeDecommittmentsDeduplicatorOutputDataWitness:: { + final_queue_state: empty_sponge_like_queue_state.clone(), + } + }; + + // decommitter must produce the same memory sequence + let code_decommitter_observable_output = if let Some(last) = + basic_circuits.code_decommitter_circuits.last + { + let observable_output = last.observable_output; + + observable_output + } else { + // form it manually + use crate::zkevm_circuits::code_unpacker_sha256::input::CodeDecommitterOutputDataWitness; + CodeDecommitterOutputDataWitness:: { + memory_queue_final_state: empty_sponge_like_queue_state.clone(), + } + }; + + // demux must produce empty output + let log_demuxer_observable_output = + if let Some(last) = basic_circuits.log_demux_circuits.last { + let observable_output = last.observable_output; + + observable_output + } else { + // form it manually + use crate::zkevm_circuits::demux_log_queue::input::LogDemuxerOutputDataWitness; + LogDemuxerOutputDataWitness:: { + output_queue_states: std::array::from_fn(|_| empty_log_queue_state.clone()), + } + }; + + // all precompiles must output the same memory sequence + use crate::zkevm_circuits::base_structures::precompile_input_outputs::{ + PrecompileFunctionOutputData, PrecompileFunctionOutputDataWitness, + }; + let dummy_precompile_output = + PrecompileFunctionOutputData::::placeholder_witness(); + let mut outputs = std::array::from_fn(|_| dummy_precompile_output.clone()); + let mut previous_memory_state = code_decommitter_observable_output + .memory_queue_final_state + .clone(); + let testsing_locations = [ + basic_circuits + .keccak_precompile_circuits + .last + .as_ref() + .map(|wit| wit.observable_output.clone()), + basic_circuits + .sha256_precompile_circuits + .last + .as_ref() + .map(|wit| wit.observable_output.clone()), + basic_circuits + .ecrecover_precompile_circuits + .last + .as_ref() + .map(|wit| wit.observable_output.clone()), + basic_circuits + .secp256r1_verify_circuits + .last + .as_ref() + .map(|wit| wit.observable_output.clone()), + ]; + + for (dst, src) in outputs.iter_mut().zip(testsing_locations.into_iter()) { + if let Some(last) = src { + *dst = last; + } else { + *dst = PrecompileFunctionOutputDataWitness { + final_memory_state: previous_memory_state.clone(), + }; + } + previous_memory_state = dst.final_memory_state.clone(); + } + + let [keccak256_observable_output, sha256_observable_output, ecrecover_observable_output, secp256r1_verify_observable_output] = + outputs; + + // storage sorter must produce empty output + let storage_sorter_observable_output = if let Some(last) = + basic_circuits.storage_sorter_circuits.last + { + let observable_output = last.observable_output; + + observable_output + } else { + // form it manually + use crate::zkevm_circuits::storage_validity_by_grand_product::input::StorageDeduplicatorOutputDataWitness; + StorageDeduplicatorOutputDataWitness:: { + final_sorted_queue_state: empty_log_queue_state.clone(), + } + }; + + // storage application must return the same root + let storage_application_observable_output = if let Some(last) = + basic_circuits.storage_application_circuits.last + { + let observable_output = last.observable_output; + + observable_output + } else { + // form it manually + use crate::zkevm_circuits::storage_application::input::StorageApplicationOutputDataWitness; + StorageApplicationOutputDataWitness:: { + new_root_hash: initial_rollup_root, + new_next_enumeration_counter: u64_as_u32_le(initial_rollup_enumeration_counter), + state_diffs_keccak256_hash: [0u8; 32], + } + }; + + // event sorter must produce an empty queue + let events_sorter_observable_output = + if let Some(last) = basic_circuits.events_sorter_circuits.last { + let observable_output = last.observable_output; + + observable_output + } else { + // form it manually + use crate::zkevm_circuits::log_sorter::input::EventsDeduplicatorOutputDataWitness; + EventsDeduplicatorOutputDataWitness:: { + final_queue_state: empty_log_queue_state.clone(), + } + }; + + // same for L2 to L1 logs + let l1messages_sorter_observable_output = + if let Some(last) = basic_circuits.l1_messages_sorter_circuits.last { + let observable_output = last.observable_output; + + observable_output + } else { + // form it manually + use crate::zkevm_circuits::log_sorter::input::EventsDeduplicatorOutputDataWitness; + EventsDeduplicatorOutputDataWitness:: { + final_queue_state: empty_log_queue_state.clone(), + } + }; + + // also create intermediate queue states if needed + let ram_sorted_queue_state = if let Some(state) = basic_circuits + .ram_permutation_circuits + .first + .map(|wit| wit.observable_input.sorted_queue_initial_state) + { + state.tail + } else { + empty_sponge_like_queue_state.clone().tail + }; + + let decommits_sorter_intermediate_queue_state = if let Some(state) = basic_circuits + .code_decommittments_sorter_circuits + .first + .map(|wit| wit.observable_input.sorted_queue_initial_state) + { + state.tail + } else { + empty_sponge_like_queue_state.clone().tail + }; + + let events_sorter_intermediate_queue_state = if let Some(state) = basic_circuits + .events_sorter_circuits + .first + .map(|wit| wit.observable_input.intermediate_sorted_queue_state) + { + state.tail + } else { + empty_log_queue_state.clone().tail + }; + + let l1messages_sorter_intermediate_queue_state = if let Some(state) = basic_circuits + .l1_messages_sorter_circuits + .first + .map(|wit| wit.observable_input.intermediate_sorted_queue_state) + { + state.tail + } else { + empty_log_queue_state.clone().tail + }; + + let rollup_storage_sorter_intermediate_queue_state = if let Some(state) = basic_circuits + .storage_sorter_circuits + .first + .map(|wit| wit.observable_input.intermediate_sorted_queue_state) + { + state.tail + } else { + empty_log_queue_state.clone().tail + }; + + let transient_storage_sorter_intermediate_queue_state = if let Some(state) = basic_circuits + .transient_storage_sorter_circuits + .first + .map(|wit| wit.observable_input.intermediate_sorted_queue_state) + { + state.tail + } else { + empty_log_queue_state.clone().tail + }; + + let l1messages_linear_hasher_observable_output = + if let Some(last) = basic_circuits.l1_messages_hasher_circuits.last { + last.observable_output + } else { + let mut empty_digest = [0u8; 32]; + use crate::zk_evm::zkevm_opcode_defs::sha3::{Digest, Keccak256}; + let mut hasher = Keccak256::new(); + hasher.update(&[]); + let digest = hasher.finalize(); + empty_digest.copy_from_slice(digest.as_slice()); + LinearHasherOutputDataWitness { + keccak256_hash: empty_digest, + } + }; + + let mut eip4844_witnesses: [Option>; + MAX_4844_BLOBS_PER_BLOCK] = std::array::from_fn(|_| None); + for (eip4844_circuit, dst) in eip4844_circuits + .into_iter() + .zip(eip4844_witnesses.iter_mut()) + { + *dst = Some(eip4844_circuit.closed_form_input.observable_output) + } + + let scheduler_circuit_witness = SchedulerCircuitInstanceWitness { + prev_block_data: previous_block_passthrough, + block_meta_parameters, + // at least one exists + vm_end_of_execution_observable_output: basic_circuits + .main_vm_circuits + .last + .unwrap() + .observable_output, + decommits_sorter_observable_output, + code_decommitter_observable_output, + log_demuxer_observable_output, + keccak256_observable_output, + sha256_observable_output, + ecrecover_observable_output, + secp256r1_verify_observable_output, + storage_sorter_observable_output, + storage_application_observable_output, + events_sorter_observable_output, + l1messages_sorter_observable_output, + l1messages_linear_hasher_observable_output, + // global value + storage_log_tail: basic_circuits + .main_vm_circuits + .first + .as_ref() + .unwrap() + .observable_input + .rollback_queue_tail_for_block, + per_circuit_closed_form_inputs: compact_form_witnesses.into(), + + // always exists + bootloader_heap_memory_state: basic_circuits + .main_vm_circuits + .first + .unwrap() + .observable_input + .memory_queue_initial_state, + ram_sorted_queue_state, + decommits_sorter_intermediate_queue_state, + events_sorter_intermediate_queue_state, + l1messages_sorter_intermediate_queue_state, + rollup_storage_sorter_intermediate_queue_state, + transient_storage_sorter_intermediate_queue_state, + + previous_block_meta_hash: [0u8; 32], + previous_block_aux_hash: [0u8; 32], + + eip4844_witnesses, + + proof_witnesses: VecDeque::new(), + }; + + (scheduler_circuit_witness, aux_data) + }; + + Ok((scheduler_circuit_witness, aux_data)) +} diff --git a/crates/zkevm_test_harness/src/snark_wrapper_test/mod.rs b/crates/zkevm_test_harness/src/snark_wrapper_test/mod.rs new file mode 100644 index 0000000..ba5f41b --- /dev/null +++ b/crates/zkevm_test_harness/src/snark_wrapper_test/mod.rs @@ -0,0 +1,115 @@ +#[cfg(test)] +mod test { + use crate::snark_wrapper::franklin_crypto::bellman::pairing::bn256::Bn256; + use crate::snark_wrapper::franklin_crypto::bellman::plonk::better_better_cs::cs::*; + use crate::snark_wrapper::franklin_crypto::plonk::circuit::bigint_new::BITWISE_LOGICAL_OPS_TABLE_NAME; + use crate::snark_wrapper::implementations::poseidon2::transcript::CircuitPoseidon2Transcript; + use crate::snark_wrapper::implementations::poseidon2::CircuitPoseidon2Sponge; + + use crate::boojum::cs::implementations::proof::Proof; + + use crate::boojum::field::goldilocks::{GoldilocksExt2 as GLExt2, GoldilocksField as GL}; + + // use crate::snark_wrapper; + use crate::snark_wrapper::verifier_structs::allocated_proof::AllocatedProof; + use crate::snark_wrapper::verifier_structs::allocated_vk::AllocatedVerificationKey; + + use circuit_definitions::circuit_definitions::aux_layer::compression::CompressionMode2ForWrapperCircuitBuilder; + use circuit_definitions::circuit_definitions::aux_layer::compression::ProofCompressionFunction; + use circuit_definitions::circuit_definitions::aux_layer::compression_modes::CompressionMode2ForWrapper; + + #[ignore = "Currently broken"] + #[test] + fn test_verify_circuit_size() { + // Create testing constraint system + + let mut assembly = TrivialAssembly::< + Bn256, + PlonkCsWidth4WithNextStepParams, + Width4MainGateWithDNext, + >::new(); + let before = assembly.n(); + + // add table for range check + let columns3 = vec![ + PolyIdentifier::VariablesPolynomial(0), + PolyIdentifier::VariablesPolynomial(1), + PolyIdentifier::VariablesPolynomial(2), + ]; + + let name = BITWISE_LOGICAL_OPS_TABLE_NAME; + let bitwise_logic_table = LookupTableApplication::new( + name, + TwoKeysOneValueBinopTable::::new(8, name), + columns3.clone(), + None, + true, + ); + assembly.add_table(bitwise_logic_table).unwrap(); + + // Allocate proof and vk + use crate::snark_wrapper::traits::circuit::ErasedBuilderForWrapperVerifier; + let verifier_builder = CompressionMode2ForWrapperCircuitBuilder::default(); + let verifier = verifier_builder.create_wrapper_verifier(&mut assembly); + + let proof_config = CompressionMode2ForWrapper::proof_config_for_compression_step(); + + let proof_file = std::fs::File::open("compression_2_for_wrapper_proof.json").unwrap(); + let proof: Proof< + GL, + ::ThisLayerHasher, + GLExt2, + > = serde_json::from_reader(proof_file).unwrap(); + + let vk_file_file = std::fs::File::open("compression_2_for_wrapper_vk.json").unwrap(); + let vk: crate::boojum::cs::implementations::verifier::VerificationKey< + GL, + ::ThisLayerHasher, + > = serde_json::from_reader(vk_file_file).unwrap(); + + let fixed_parameters = vk.fixed_parameters.clone(); + + let proof: AllocatedProof> = + AllocatedProof::allocate_from_witness( + &mut assembly, + &Some(proof), + &verifier, + &fixed_parameters, + &proof_config, + ) + .unwrap(); + + let vk: AllocatedVerificationKey> = + AllocatedVerificationKey::allocate_from_witness( + &mut assembly, + Some(vk), + &fixed_parameters, + ) + .unwrap(); + + // Verify proof + crate::snark_wrapper::verifier::verify::< + _, + _, + _, + CircuitPoseidon2Transcript, + >( + &mut assembly, + (), + &proof_config, + &proof, + &verifier, + &fixed_parameters, + &vk, + ) + .unwrap(); + + let after = assembly.n(); + + dbg!(after - before); + + assert!(assembly.is_satisfied()); + + dbg!(assembly.gates); + } +} diff --git a/crates/zkevm_test_harness/src/tests/complex_tests/invididual_debugs.rs b/crates/zkevm_test_harness/src/tests/complex_tests/invididual_debugs.rs new file mode 100644 index 0000000..58419bc --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/complex_tests/invididual_debugs.rs @@ -0,0 +1,54 @@ +#[cfg(test)] +mod test { + use crate::proof_wrapper_utils::wrap_proof; + + use super::super::*; + use std::io::Read; + + #[ignore = "For manual running only"] + #[test] + fn read_and_run() { + let circuit_file_name = "prover_jobs_23_05.bin"; + let buffer = std::fs::read(circuit_file_name).unwrap(); + debug::debug_circuit(&buffer); + } + + #[ignore = "For manual running only"] + #[test] + fn test_and_run_recursive() { + let circuit_file_name = "prover_jobs_fri_38142_0_3_NodeAggregation_1_raw.bin"; + let buffer = std::fs::read(circuit_file_name).unwrap(); + debug::debug_circuit(&buffer); + } + + #[derive(serde::Serialize, serde::Deserialize)] + pub enum FriProofWrapper { + Base(ZkSyncBaseLayerProof), + Recursive(ZkSyncRecursionLayerProof), + } + + #[ignore = "For manual running only"] + #[test] + fn test_wrapper_layer() { + let proof_file_name = "proofs_fri_proof_33908687.bin"; + + let mut content = std::fs::File::open(proof_file_name).unwrap(); + let mut buffer = vec![]; + content.read_to_end(&mut buffer).unwrap(); + let proof: FriProofWrapper = bincode::deserialize(&buffer).unwrap(); + + let vk_file_name = "scheduler_vk.json"; + + let mut content = std::fs::File::open(vk_file_name).unwrap(); + let mut buffer = vec![]; + content.read_to_end(&mut buffer).unwrap(); + let vk: ZkSyncRecursionLayerVerificationKey = serde_json::from_slice(&buffer).unwrap(); + + let FriProofWrapper::Recursive(proof) = proof else { + panic!(); + }; + + let config = WrapperConfig::new(1); + let _ = wrap_proof(proof, vk, config); + } +} diff --git a/crates/zkevm_test_harness/src/tests/complex_tests/mod.rs b/crates/zkevm_test_harness/src/tests/complex_tests/mod.rs new file mode 100644 index 0000000..932846e --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/complex_tests/mod.rs @@ -0,0 +1,1396 @@ +pub mod utils; + +pub mod invididual_debugs; +#[cfg(test)] +mod test_synthesis; + +#[cfg(test)] +pub mod testing_wrapper; +#[cfg(test)] +mod wrapper_negative_tests; + +use std::collections::{HashMap, HashSet, VecDeque}; + +use super::*; +use crate::boojum::cs::implementations::pow::NoPow; +use crate::boojum::cs::implementations::prover::ProofConfig; +use crate::boojum::cs::implementations::setup::FinalizationHintsForProver; +use crate::boojum::field::goldilocks::GoldilocksExt2; +use crate::boojum::field::U64Representable; +use crate::boojum::gadgets::traits::allocatable::CSAllocatable; +use crate::compute_setups::*; +use crate::entry_point::create_out_of_circuit_global_context; +use crate::ethereum_types::*; +use crate::helper::artifact_utils::TestArtifact; +use crate::proof_wrapper_utils::{WrapperConfig, DEFAULT_WRAPPER_CONFIG}; +use crate::prover_utils::*; +use crate::tests::complex_tests::utils::empty_node_proof; +use crate::toolset::{create_tools, GeometryConfig}; +use crate::witness::oracle::create_artifacts_from_tracer; +use crate::witness::tree::{BinarySparseStorageTree, ZKSyncTestingTree}; +use crate::witness::utils::*; +use crate::zk_evm::abstractions::*; +use crate::zk_evm::aux_structures::DecommittmentQuery; +use crate::zk_evm::aux_structures::*; +use crate::zk_evm::testing::storage::InMemoryStorage; +use crate::zk_evm::utils::{bytecode_to_code_hash, contract_bytecode_to_words}; +use crate::zk_evm::witness_trace::VmWitnessTracer; +use crate::zk_evm::GenericNoopTracer; +use crate::zkevm_circuits::eip_4844::input::*; +use crate::zkevm_circuits::scheduler::block_header::MAX_4844_BLOBS_PER_BLOCK; +use crate::zkevm_circuits::scheduler::input::SchedulerCircuitInstanceWitness; +use boojum::gadgets::queue::full_state_queue::FullStateCircuitQueueRawWitness; +use circuit_definitions::aux_definitions::witness_oracle::VmWitnessOracle; +use circuit_definitions::circuit_definitions::aux_layer::compression::{ + self, CompressionMode1Circuit, +}; +use circuit_definitions::circuit_definitions::aux_layer::wrapper::*; +use circuit_definitions::circuit_definitions::base_layer::*; +use circuit_definitions::circuit_definitions::recursion_layer::leaf_layer::ZkSyncLeafLayerRecursiveCircuit; +use circuit_definitions::circuit_definitions::recursion_layer::scheduler::SchedulerCircuit; +use circuit_definitions::circuit_definitions::recursion_layer::*; +use circuit_definitions::encodings::recursion_request::RecursionQueueSimulator; +use circuit_definitions::zkevm_circuits::fsm_input_output::ClosedFormInputCompactFormWitness; +use circuit_definitions::zkevm_circuits::scheduler::aux::NUM_CIRCUIT_TYPES_TO_SCHEDULE; +use circuit_definitions::{ + base_layer_proof_config, recursion_layer_proof_config, BASE_LAYER_CAP_SIZE, + BASE_LAYER_FRI_LDE_FACTOR, RECURSION_LAYER_CAP_SIZE, RECURSION_LAYER_FRI_LDE_FACTOR, +}; +use circuit_definitions::{Field, RoundFunction}; +use utils::read_basic_test_artifact; + +use witness::oracle::WitnessGenerationArtifact; +use zkevm_assembly::Assembly; + +#[ignore = "Too slow"] +#[test] +fn basic_test() { + let test_artifact = read_basic_test_artifact(); + let blobs = std::array::from_fn(|i| { + if i == 0 { + Some(vec![0xff; ENCODABLE_BYTES_PER_BLOB]) + } else { + None + } + }); + let options = Options { + use_production_geometry: true, + ..Default::default() + }; + run_and_try_create_witness_inner(test_artifact, 40000, blobs, &options); + // run_and_try_create_witness_inner(test_artifact, 16); +} + +#[ignore = "Too slow, requires CRS"] +#[test] +fn test_single_compression() { + let config = testing_wrapper::get_testing_wrapper_config(); + + testing_wrapper::test_compression_for_compression_num(config); +} + +#[ignore = "Too slow, requires CRS"] +#[test] +fn test_compression_all_modes() { + for compression in 1..=WrapperConfig::MAX_COMPRESSION_LAYERS { + println!("Testing wrapper for mode {}", compression); + let config = WrapperConfig::new(compression as u8); + testing_wrapper::test_compression_for_compression_num(config); + } +} + +use crate::zkevm_circuits::recursion::compression::CompressionRecursionConfig; +use circuit_definitions::circuit_definitions::aux_layer::compression_modes::*; +use circuit_definitions::circuit_definitions::aux_layer::*; +use circuit_definitions::circuit_definitions::aux_layer::compression::ProofCompressionFunction; +use circuit_definitions::circuit_definitions::aux_layer::ZkSyncCompressionLayerVerificationKey; +use crate::data_source::{local_file_data_source::LocalFileDataSource, SetupDataSource, BlockDataSource}; +use circuit_definitions::circuit_definitions::aux_layer::compression::*; +use snark_wrapper::verifier_structs::allocated_vk::AllocatedVerificationKey; +use snark_wrapper::franklin_crypto::plonk::circuit::bigint_new::BITWISE_LOGICAL_OPS_TABLE_NAME; +use snark_wrapper::franklin_crypto::bellman::plonk::better_better_cs::cs::*; +use snark_wrapper::franklin_crypto::bellman::plonk::commitments::transcript::{ + keccak_transcript::RollingKeccakTranscript, + Prng +}; +use snark_wrapper::franklin_crypto::bellman::pairing::bn256::{Bn256, Fr}; +use snark_wrapper::franklin_crypto::bellman::kate_commitment::{Crs, CrsForMonomialForm}; +use snark_wrapper::verifier::WrapperCircuit; +use rescue_poseidon::poseidon2::Poseidon2Sponge; +use rescue_poseidon::poseidon2::transcript::Poseidon2Transcript; +use snark_wrapper::implementations::poseidon2::tree_hasher::AbsorptionModeReplacement; +use snark_wrapper::implementations::poseidon2::CircuitPoseidon2Sponge; +use snark_wrapper::implementations::poseidon2::transcript::CircuitPoseidon2Transcript; +use snark_wrapper::franklin_crypto::bellman::plonk::better_better_cs::setup::VerificationKey as SnarkVK; +use snark_wrapper::franklin_crypto::bellman::plonk::better_better_cs::gates + ::selector_optimized_with_d_next::SelectorOptimizedWidth4MainGateWithDNext; + +use crate::boojum::algebraic_props::round_function::AbsorptionModeOverwrite; +use crate::boojum::algebraic_props::sponge::GoldilocksPoseidon2Sponge; +use crate::boojum::gadgets::recursion::recursive_tree_hasher::CircuitGoldilocksPoseidon2Sponge; +use crate::data_source::in_memory_data_source::InMemoryDataSource; +use crate::witness::artifacts::*; + +/// Lover memory requirements +/// Used only for base layer debugging +fn get_testing_geometry_config() -> GeometryConfig { + GeometryConfig { + // cycles_per_vm_snapshot: 1, + cycles_per_vm_snapshot: 1024, + cycles_per_ram_permutation: 1024, + cycles_per_code_decommitter: 256, + cycles_per_storage_application: 4, + cycles_per_keccak256_circuit: 7, + cycles_per_sha256_circuit: 7, + cycles_per_ecrecover_circuit: 2, + // cycles_code_decommitter_sorter: 512, + cycles_code_decommitter_sorter: 3, + cycles_per_log_demuxer: 16, + cycles_per_storage_sorter: 16, + cycles_per_events_or_l1_messages_sorter: 4, + cycles_per_secp256r1_verify_circuit: 2, + cycles_per_transient_storage_sorter: 16, + + limit_for_l1_messages_pudata_hasher: 32, + } +} + +pub(crate) fn generate_base_layer( + mut test_artifact: TestArtifact, + cycle_limit: usize, + geometry: GeometryConfig, + blobs: [Option>; MAX_4844_BLOBS_PER_BLOCK], +) -> ( + Vec, + Vec<( + u64, + RecursionQueueSimulator, + Vec>, + )>, + SchedulerCircuitInstanceWitness< + GoldilocksField, + CircuitGoldilocksPoseidon2Sponge, + GoldilocksExt2, + >, +) { + use crate::zk_evm::zkevm_opcode_defs::system_params::BOOTLOADER_FORMAL_ADDRESS; + + use crate::external_calls::run; + use crate::toolset::GeometryConfig; + + let mut storage_impl = InMemoryStorage::new(); + let mut tree = ZKSyncTestingTree::empty(); + + test_artifact.entry_point_address = + *zk_evm::zkevm_opcode_defs::system_params::BOOTLOADER_FORMAL_ADDRESS; + + let predeployed_contracts = test_artifact + .predeployed_contracts + .clone() + .into_iter() + .chain(Some(( + test_artifact.entry_point_address, + test_artifact.entry_point_code.clone(), + ))) + .collect::>(); + save_predeployed_contracts(&mut storage_impl, &mut tree, &predeployed_contracts); + + let used_bytecodes = HashMap::from_iter( + test_artifact + .predeployed_contracts + .iter() + .map(|(_, bytecode)| { + ( + bytecode_to_code_hash(&bytecode).unwrap().into(), + bytecode.clone(), + ) + }) + .chain( + Some(test_artifact.default_account_code.clone()).map(|bytecode| { + ( + bytecode_to_code_hash(&bytecode).unwrap().into(), + bytecode.clone(), + ) + }), + ), + ); + for (k, _) in used_bytecodes.iter() { + println!("Have bytecode hash 0x{:x}", k); + } + use sha3::{Digest, Keccak256}; + + let previous_enumeration_index = tree.next_enumeration_index(); + let previous_root = tree.root(); + // simualate content hash + + let mut hasher = Keccak256::new(); + hasher.update(&previous_enumeration_index.to_be_bytes()); + hasher.update(&previous_root); + hasher.update(&0u64.to_be_bytes()); // porter shard + hasher.update(&[0u8; 32]); // porter shard + + let mut previous_data_hash = [0u8; 32]; + (&mut previous_data_hash[..]).copy_from_slice(&hasher.finalize().as_slice()); + + let previous_aux_hash = [0u8; 32]; + let previous_meta_hash = [0u8; 32]; + + // simulate block header + + let mut hasher = Keccak256::new(); + hasher.update(&previous_data_hash); + hasher.update(&previous_meta_hash); + hasher.update(&previous_aux_hash); + + let mut previous_content_hash = [0u8; 32]; + (&mut previous_content_hash[..]).copy_from_slice(&hasher.finalize().as_slice()); + + let default_account_codehash = + bytecode_to_code_hash(&test_artifact.default_account_code).unwrap(); + let default_account_codehash = U256::from_big_endian(&default_account_codehash); + + let evm_simulator_code_hash = bytecode_to_code_hash(&test_artifact.evm_simulator_code).unwrap(); + let evm_simulator_code_hash = U256::from_big_endian(&evm_simulator_code_hash); + + println!("Default AA code hash 0x{:x}", default_account_codehash); + println!("EVM simulator code hash 0x{:x}", evm_simulator_code_hash); + + let mut basic_block_circuits = vec![]; + let mut recursion_queues = vec![]; + let mut unsorted_memory_queue_witnesses = vec![]; + let mut sorted_memory_queue_witnesses = vec![]; + + let artifacts_callback = |artifact: WitnessGenerationArtifact| match artifact { + WitnessGenerationArtifact::BaseLayerCircuit(circuit) => basic_block_circuits.push(circuit), + WitnessGenerationArtifact::RecursionQueue((a, b, c)) => recursion_queues.push(( + a, + b, + c.into_iter() + .map(|x| ZkSyncBaseLayerStorage::from_inner(a as u8, x)) + .collect(), + )), + WitnessGenerationArtifact::MemoryQueueWitness((witnesses, sorted)) => { + if sorted { + sorted_memory_queue_witnesses.push(witnesses); + } else { + unsorted_memory_queue_witnesses.push(witnesses); + } + } + }; + + let (scheduler_partial_input, _aux_data) = run( + Address::zero(), + test_artifact.entry_point_address, + test_artifact.entry_point_code, + vec![], + false, + default_account_codehash, + evm_simulator_code_hash, + used_bytecodes, + vec![], + cycle_limit, + geometry, + storage_impl, + tree, + "kzg/src/trusted_setup.json", + blobs, + artifacts_callback, + ); + + let mut unsorted_memory_queue_witnesses_it = unsorted_memory_queue_witnesses.into_iter(); + let mut sorted_memory_queue_witnesses = sorted_memory_queue_witnesses.into_iter(); + for el in basic_block_circuits.iter_mut() { + match &el { + ZkSyncBaseLayerCircuit::RAMPermutation(inner) => { + let mut witness = inner.witness.take().unwrap(); + witness.sorted_queue_witness = FullStateCircuitQueueRawWitness { + elements: sorted_memory_queue_witnesses.next().unwrap().into(), + }; + witness.unsorted_queue_witness = FullStateCircuitQueueRawWitness { + elements: unsorted_memory_queue_witnesses_it.next().unwrap().into(), + }; + + inner.witness.store(Some(witness)); + } + _ => {} + } + } + + ( + basic_block_circuits, + recursion_queues, + scheduler_partial_input, + ) +} + +/// Test that does the basic circuit verification - but only one circuit from each kind +/// and it uses test geometry to run faster (as it has smaller circuits). +#[test] +fn basic_layer_test_one_per_kind() { + let test_artifact = read_basic_test_artifact(); + let blobs = std::array::from_fn(|i| { + if i == 0 { + Some(vec![0xff; ENCODABLE_BYTES_PER_BLOB]) + } else { + None + } + }); + + // Using smaller geometry to speed things up. + let geometry = get_testing_geometry_config(); + + let (basic_block_circuits, _, _) = generate_base_layer(test_artifact, 40000, geometry, blobs); + + let mut checked = HashSet::new(); + + for el in basic_block_circuits.into_iter() { + if checked.contains(&el.numeric_circuit_type()) { + continue; + } else { + checked.insert(el.numeric_circuit_type()); + + let descr = el.short_description(); + println!("Checking circuit type {}", descr); + + base_test_circuit(el); + } + } +} + +struct Options { + // Additional tests over the basic circuits. + test_base_circuits: bool, + // If true, will use production geometry (less circuits, but more memory). + // If false, will use 'testing' geometry (more circuits, but smaller and less memory). + use_production_geometry: bool, + + /// If true, then the test will try to reuse existing artifacts (like proofs etc). + /// This allows test to not repeat things that it already did. + /// If false, everything will be computed from scratch. + try_reuse_artifacts: bool, +} + +impl Default for Options { + fn default() -> Self { + Self { + test_base_circuits: false, + use_production_geometry: false, + try_reuse_artifacts: true, + } + } +} + +/// Running the end-to-end tests, using the bytecodes from test_artifact and blobs. +/// Please see the Options to adjust the testing behavior. +#[allow(dead_code)] +fn run_and_try_create_witness_inner( + test_artifact: TestArtifact, + cycle_limit: usize, + blobs: [Option>; MAX_4844_BLOBS_PER_BLOCK], + options: &Options, +) { + use crate::external_calls::run; + use crate::toolset::GeometryConfig; + + let geometry = if options.use_production_geometry { + crate::geometry_config::get_geometry_config() + } else { + get_testing_geometry_config() + }; + + let (basic_block_circuits, mut recursion_queues, scheduler_partial_input) = + generate_base_layer(test_artifact, cycle_limit, geometry, blobs.clone()); + + // It is important that recursion queries are in sorted order - as we later match them with respective proofs. + recursion_queues.sort_by_key(|(circuit, _, _)| circuit.clone()); + + if options.test_base_circuits { + for (idx, el) in basic_block_circuits.clone().into_iter().enumerate() { + let descr = el.short_description(); + println!("Doing {}: {}", idx, descr); + + // if idx < 398 { + // continue; + // } + + // match &el { + // ZkSyncBaseLayerCircuit::LogDemuxer(inner) => { + // dbg!(&*inner.config); + // // let witness = inner.clone_witness().unwrap(); + // // dbg!(&witness.closed_form_input); + // // dbg!(witness.closed_form_input.start_flag); + // // dbg!(witness.closed_form_input.completion_flag); + // } + // _ => { + // continue; + // } + // } + + base_test_circuit(el); + } + } + + let worker = Worker::new_with_num_threads(8); + + let mut previous_circuit_type = 0; + + let mut instance_idx = 0; + + let mut setup_data = None; + + let mut source = LocalFileDataSource::default(); + source.create_folders_for_storing_data(); + + use crate::data_source::*; + + let circuits_len = basic_block_circuits.len(); + + for (idx, el) in basic_block_circuits.clone().into_iter().enumerate() { + let descr = el.short_description(); + println!("Doing {} / {}: {}", idx, circuits_len, descr); + + if el.numeric_circuit_type() != previous_circuit_type { + instance_idx = 0; + } + + if options.try_reuse_artifacts { + if let Ok(_) = source.get_base_layer_proof(el.numeric_circuit_type(), instance_idx) { + instance_idx += 1; + previous_circuit_type = el.numeric_circuit_type(); + continue; + } + } + + if el.numeric_circuit_type() != previous_circuit_type || setup_data.is_none() { + println!( + "Regenerating setup data for {} from {}", + el.numeric_circuit_type(), + previous_circuit_type, + ); + let (setup_base, setup, vk, setup_tree, vars_hint, wits_hint, finalization_hint) = + create_base_layer_setup_data( + el.clone(), + &worker, + BASE_LAYER_FRI_LDE_FACTOR, + BASE_LAYER_CAP_SIZE, + ); + + source + .set_base_layer_vk(ZkSyncBaseLayerVerificationKey::from_inner( + el.numeric_circuit_type(), + vk.clone(), + )) + .unwrap(); + source + .set_base_layer_finalization_hint(ZkSyncBaseLayerFinalizationHint::from_inner( + el.numeric_circuit_type(), + finalization_hint.clone(), + )) + .unwrap(); + + setup_data = Some(( + setup_base, + setup, + vk, + setup_tree, + vars_hint, + wits_hint, + finalization_hint, + )); + + previous_circuit_type = el.numeric_circuit_type(); + } + + println!("Proving!"); + let now = std::time::Instant::now(); + + let (setup_base, setup, vk, setup_tree, vars_hint, wits_hint, finalization_hint) = + setup_data.as_ref().unwrap(); + + let proof = prove_base_layer_circuit::( + el.clone(), + &worker, + base_layer_proof_config(), + &setup_base, + &setup, + &setup_tree, + &vk, + &vars_hint, + &wits_hint, + &finalization_hint, + ); + + println!("Proving is DONE, taken {:?}", now.elapsed()); + + let is_valid = verify_base_layer_proof::(&el, &proof, &vk); + + assert!(is_valid); + + source + .set_base_layer_proof( + instance_idx, + ZkSyncBaseLayerProof::from_inner(el.numeric_circuit_type(), proof.clone()), + ) + .unwrap(); + + instance_idx += 1; + } + + println!("Assembling keys"); + + let mut proofs = vec![]; + let mut verification_keys = vec![]; + + for (circuit_id, queue_simulator, inputs) in recursion_queues.iter() { + let circuit_type = *circuit_id as u8; + let mut proofs_for_circuit_type = vec![]; + for idx in 0..inputs.len() { + println!("Reading base layer proof: {:?} {:?}", circuit_type, idx); + + match source.get_base_layer_proof(circuit_type, idx) { + Ok(proof) => { + proofs_for_circuit_type.push(proof); + } + Err(_) => { + if idx == 0 && queue_simulator.num_items == 0 { + println!("Skipping - assuming that there were no circuits") + } else { + panic!("Missing for - {} {}", circuit_type, idx); + } + } + } + } + + let vk = source.get_base_layer_vk(circuit_type).unwrap(); + verification_keys.push(vk); + + proofs.push(proofs_for_circuit_type); + } + + println!("Computing leaf vks"); + + for base_circuit_type in ((BaseLayerCircuitType::VM as u8) + ..=(BaseLayerCircuitType::Secp256r1Verify as u8)) + .chain(std::iter::once(BaseLayerCircuitType::EIP4844Repack as u8)) + { + let recursive_circuit_type = base_circuit_type_into_recursive_leaf_circuit_type( + BaseLayerCircuitType::from_numeric_value(base_circuit_type), + ); + + if !options.try_reuse_artifacts + || source + .get_recursion_layer_vk(recursive_circuit_type as u8) + .is_err() + { + println!( + "Computing leaf layer VK for type {:?}", + recursive_circuit_type + ); + use crate::zkevm_circuits::recursion::leaf_layer::input::*; + let input = RecursionLeafInput::placeholder_witness(); + let vk = source.get_base_layer_vk(base_circuit_type).unwrap(); + + use crate::boojum::gadgets::queue::full_state_queue::FullStateCircuitQueueRawWitness; + let witness = RecursionLeafInstanceWitness { + input, + vk_witness: vk.clone().into_inner(), + queue_witness: FullStateCircuitQueueRawWitness { + elements: VecDeque::new(), + }, + proof_witnesses: VecDeque::new(), + }; + + use crate::zkevm_circuits::recursion::leaf_layer::LeafLayerRecursionConfig; + let config = LeafLayerRecursionConfig { + proof_config: recursion_layer_proof_config(), + vk_fixed_parameters: vk.into_inner().fixed_parameters, + capacity: RECURSION_ARITY, + _marker: std::marker::PhantomData, + }; + let circuit = ZkSyncLeafLayerRecursiveCircuit { + base_layer_circuit_type: BaseLayerCircuitType::from_numeric_value( + base_circuit_type, + ), + witness: witness, + config: config, + transcript_params: (), + _marker: std::marker::PhantomData, + }; + + let circuit = ZkSyncRecursiveLayerCircuit::leaf_circuit_from_base_type( + BaseLayerCircuitType::from_numeric_value(base_circuit_type), + circuit, + ); + + let (_setup_base, _setup, vk, _setup_tree, _vars_hint, _wits_hint, finalization_hint) = + create_recursive_layer_setup_data( + circuit, + &worker, + RECURSION_LAYER_FRI_LDE_FACTOR, + RECURSION_LAYER_CAP_SIZE, + ); + + let finalization_hint = ZkSyncRecursionLayerFinalizationHint::from_inner( + recursive_circuit_type as u8, + finalization_hint, + ); + source + .set_recursion_layer_finalization_hint(finalization_hint) + .unwrap(); + let vk = + ZkSyncRecursionLayerVerificationKey::from_inner(recursive_circuit_type as u8, vk); + source.set_recursion_layer_vk(vk).unwrap(); + } + } + + println!("Computing leaf params"); + use crate::compute_setups::compute_leaf_params; + use crate::zkevm_circuits::scheduler::aux::BaseLayerCircuitType; + let leaf_vk_commits = compute_leaf_params(&mut source).unwrap(); + + let mut all_leaf_aggregations = vec![]; + use crate::witness::recursive_aggregation::create_leaf_witnesses; + + println!("Creating leaf aggregation circuits"); + + let mut all_closed_form_inputs_for_scheduler = vec![]; + + assert_eq!(recursion_queues.len(), proofs.len()); + assert_eq!(recursion_queues.len(), verification_keys.len()); + + for ((subset, proofs), vk) in recursion_queues + .clone() + .into_iter() + .zip(proofs.into_iter()) + .zip(verification_keys.iter().cloned()) + { + let param = leaf_vk_commits + .iter() + .find(|el| el.0 == subset.0 as u8) + .cloned() + .unwrap(); + + let (aggregations, recursive_circuits, _closed_form_inputs) = + create_leaf_witnesses(subset, proofs, vk, param); + all_leaf_aggregations.push((aggregations, recursive_circuits)); + all_closed_form_inputs_for_scheduler.extend(_closed_form_inputs); + } + + println!("Proving leaf aggregation circuits"); + + let mut previous_circuit_type = 0; + + use circuit_definitions::circuit_definitions::recursion_layer::*; + + for (aggregations_for_circuit_type, recursive_circuits) in all_leaf_aggregations.iter() { + if aggregations_for_circuit_type.is_empty() { + continue; + } + + let mut instance_idx = 0; + let mut setup_data = None; + for (idx, el) in recursive_circuits.iter().enumerate() { + let descr = el.short_description(); + println!("Doing {}: {}", idx, descr); + + // test_recursive_circuit(el.clone()); + // println!("Circuit is satisfied"); + + if options.try_reuse_artifacts { + if let Ok(_proof) = + source.get_leaf_layer_proof(el.numeric_circuit_type(), instance_idx) + { + instance_idx += 1; + continue; + } + } + + if el.numeric_circuit_type() != previous_circuit_type || setup_data.is_none() { + let (setup_base, setup, vk, setup_tree, vars_hint, wits_hint, finalization_hint) = + create_recursive_layer_setup_data( + el.clone(), + &worker, + RECURSION_LAYER_FRI_LDE_FACTOR, + RECURSION_LAYER_CAP_SIZE, + ); + + // let other_vk = source + // .get_recursion_layer_vk(el.numeric_circuit_type()) + // .unwrap() + // .into_inner(); + + // assert_eq!(&other_vk, &vk); + + // let other_finalization_hint = source + // .get_recursion_layer_finalization_hint(el.numeric_circuit_type()) + // .unwrap() + // .into_inner(); + + // assert_eq!(&other_finalization_hint, &finalization_hint); + + source + .set_recursion_layer_vk(ZkSyncRecursionLayerVerificationKey::from_inner( + el.numeric_circuit_type(), + vk.clone(), + )) + .unwrap(); + source + .set_recursion_layer_finalization_hint( + ZkSyncRecursionLayerFinalizationHint::from_inner( + el.numeric_circuit_type(), + finalization_hint.clone(), + ), + ) + .unwrap(); + + setup_data = Some(( + setup_base, + setup, + vk, + setup_tree, + vars_hint, + wits_hint, + finalization_hint, + )); + + previous_circuit_type = el.numeric_circuit_type(); + } + + println!("Proving!"); + let now = std::time::Instant::now(); + + let (setup_base, setup, vk, setup_tree, vars_hint, wits_hint, finalization_hint) = + setup_data.as_ref().unwrap(); + + let proof = prove_recursion_layer_circuit::( + el.clone(), + &worker, + recursion_layer_proof_config(), + &setup_base, + &setup, + &setup_tree, + &vk, + &vars_hint, + &wits_hint, + &finalization_hint, + ); + + println!("Proving is DONE, taken {:?}", now.elapsed()); + + let is_valid = verify_recursion_layer_proof::(&el, &proof, &vk); + + assert!(is_valid); + + source + .set_leaf_layer_proof( + instance_idx, + ZkSyncRecursionLayerProof::from_inner(el.numeric_circuit_type(), proof.clone()), + ) + .unwrap(); + + instance_idx += 1; + } + } + + // do that once in setup-mode only + + if source.get_recursion_layer_node_vk().is_err() { + use crate::zkevm_circuits::recursion::node_layer::input::*; + let input = RecursionNodeInput::placeholder_witness(); + + let input_vk = source + .get_recursion_layer_vk( + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForMainVM as u8, + ) + .unwrap(); + let witness = RecursionNodeInstanceWitness { + input, + vk_witness: input_vk.clone().into_inner(), + split_points: VecDeque::new(), + proof_witnesses: VecDeque::new(), + }; + + use crate::zkevm_circuits::recursion::node_layer::NodeLayerRecursionConfig; + use circuit_definitions::circuit_definitions::recursion_layer::node_layer::ZkSyncNodeLayerRecursiveCircuit; + let config = NodeLayerRecursionConfig { + proof_config: recursion_layer_proof_config(), + vk_fixed_parameters: input_vk.clone().into_inner().fixed_parameters, + leaf_layer_capacity: RECURSION_ARITY, + node_layer_capacity: RECURSION_ARITY, + _marker: std::marker::PhantomData, + }; + let circuit = ZkSyncNodeLayerRecursiveCircuit { + witness: witness, + config: config, + transcript_params: (), + _marker: std::marker::PhantomData, + }; + + let circuit = ZkSyncRecursiveLayerCircuit::NodeLayerCircuit(circuit); + + let (_setup_base, _setup, vk, _setup_tree, _vars_hint, _wits_hint, finalization_hint) = + create_recursive_layer_setup_data( + circuit, + &worker, + RECURSION_LAYER_FRI_LDE_FACTOR, + RECURSION_LAYER_CAP_SIZE, + ); + + let finalization_hint = + ZkSyncRecursionLayerFinalizationHint::NodeLayerCircuit(finalization_hint); + source + .set_recursion_layer_node_finalization_hint(finalization_hint.clone()) + .unwrap(); + let vk = ZkSyncRecursionLayerVerificationKey::NodeLayerCircuit(vk); + source.set_recursion_layer_node_vk(vk.clone()).unwrap(); + + let input = RecursionNodeInput::placeholder_witness(); + let input_vk2 = source + .get_recursion_layer_vk( + ZkSyncRecursionLayerStorageType::LeafLayerCircuitForCodeDecommittmentsSorter as u8, + ) + .unwrap(); + let witness = RecursionNodeInstanceWitness { + input, + vk_witness: input_vk2.clone().into_inner(), + split_points: VecDeque::new(), + proof_witnesses: VecDeque::new(), + }; + + let config = NodeLayerRecursionConfig { + proof_config: recursion_layer_proof_config(), + vk_fixed_parameters: input_vk2.clone().into_inner().fixed_parameters, + leaf_layer_capacity: RECURSION_ARITY, + node_layer_capacity: RECURSION_ARITY, + _marker: std::marker::PhantomData, + }; + let circuit = ZkSyncNodeLayerRecursiveCircuit { + witness: witness, + config: config, + transcript_params: (), + _marker: std::marker::PhantomData, + }; + + assert_eq!( + input_vk.clone().into_inner().fixed_parameters, + input_vk2.clone().into_inner().fixed_parameters + ); + + let circuit = ZkSyncRecursiveLayerCircuit::NodeLayerCircuit(circuit); + + let ( + _setup_base_2, + _setup_2, + vk_2, + _setup_tree_2, + _vars_hint_2, + _wits_hint_2, + finalization_hint_2, + ) = create_recursive_layer_setup_data( + circuit, + &worker, + RECURSION_LAYER_FRI_LDE_FACTOR, + RECURSION_LAYER_CAP_SIZE, + ); + + assert_eq!(_vars_hint, _vars_hint_2); + assert_eq!(_wits_hint, _wits_hint_2); + assert_eq!(finalization_hint.into_inner(), finalization_hint_2); + + for (idx, (a, b)) in _setup_base + .constant_columns + .iter() + .zip(_setup_base_2.constant_columns.iter()) + .enumerate() + { + assert_eq!(a, b, "failed at index {}", idx); + } + for (idx, (a, b)) in _setup_base + .copy_permutation_polys + .iter() + .zip(_setup_base_2.copy_permutation_polys.iter()) + .enumerate() + { + assert_eq!(a, b, "failed at index {}", idx); + } + for (idx, (a, b)) in _setup_base + .lookup_tables_columns + .iter() + .zip(_setup_base_2.lookup_tables_columns.iter()) + .enumerate() + { + assert_eq!(a, b, "failed at index {}", idx); + } + assert_eq!(_setup_base, _setup_base_2); + assert_eq!(_setup, _setup_2); + assert_eq!(_setup_tree, _setup_tree_2); + + assert_eq!(vk.into_inner(), vk_2); + } + + let node_vk = source.get_recursion_layer_node_vk().unwrap(); + use crate::witness::recursive_aggregation::compute_node_vk_commitment; + let node_vk_commitment = compute_node_vk_commitment(node_vk); + + println!("Continuing into nodes leaf aggregation circuits"); + for (per_circuit_subtree, _) in all_leaf_aggregations.into_iter() { + let mut depth = 0; + let mut next_aggregations = per_circuit_subtree; + + if next_aggregations.len() == 0 { + // There are no leaf circuits of this type. + continue; + } + + let base_circuit_type = next_aggregations[0].0 as u8; + let circuit_type_enum = BaseLayerCircuitType::from_numeric_value(base_circuit_type); + println!( + "Continuing into node aggregation for circuit type {:?}", + circuit_type_enum + ); + + let recursive_circuit_type = + base_circuit_type_into_recursive_leaf_circuit_type(circuit_type_enum); + + use crate::witness::recursive_aggregation::create_node_witnesses; + let vk = if depth == 0 { + source + .get_recursion_layer_vk(recursive_circuit_type as u8) + .unwrap() + } else { + source.get_recursion_layer_node_vk().unwrap() + }; + + let mut setup_data = None; + + loop { + println!("Working on depth {}", depth); + let mut proofs = vec![]; + for idx in 0..next_aggregations.len() { + let proof = if depth == 0 { + source + .get_leaf_layer_proof(recursive_circuit_type as u8, idx) + .unwrap() + } else { + source + .get_node_layer_proof(recursive_circuit_type as u8, depth, idx) + .unwrap() + }; + + proofs.push(proof); + } + let (new_aggregations, recursive_circuits) = create_node_witnesses( + next_aggregations, + proofs, + vk.clone(), + node_vk_commitment, + &leaf_vk_commits, + ); + next_aggregations = new_aggregations; + + for (idx, el) in recursive_circuits.iter().enumerate() { + // test_recursive_circuit(el.clone()); + // println!("Circuit is satisfied"); + + if let Ok(_proof) = + source.get_node_layer_proof(recursive_circuit_type as u8, depth, idx) + { + continue; + } + + if setup_data.is_none() { + let ( + setup_base, + setup, + vk, + setup_tree, + vars_hint, + wits_hint, + finalization_hint, + ) = create_recursive_layer_setup_data( + el.clone(), + &worker, + RECURSION_LAYER_FRI_LDE_FACTOR, + RECURSION_LAYER_CAP_SIZE, + ); + + let other_vk = source.get_recursion_layer_node_vk().unwrap().into_inner(); + + assert_eq!(&other_vk, &vk); + + let other_finalization_hint = source + .get_recursion_layer_node_finalization_hint() + .unwrap() + .into_inner(); + + assert_eq!(&other_finalization_hint, &finalization_hint); + + // // we did it above + // source.set_recursion_layer_node_vk(ZkSyncRecursionLayerVerificationKey::NodeLayerCircuit(vk)).unwrap(); + // source.set_recursion_layer_node_finalization_hint(ZkSyncRecursionLayerFinalizationHint::NodeLayerCircuit(finalization_hint)).unwrap(); + + setup_data = Some(( + setup_base, + setup, + vk, + setup_tree, + vars_hint, + wits_hint, + finalization_hint, + )); + } + + // prove + println!("Proving!"); + let now = std::time::Instant::now(); + + let (setup_base, setup, vk, setup_tree, vars_hint, wits_hint, finalization_hint) = + setup_data.as_ref().unwrap(); + + let proof = prove_recursion_layer_circuit::( + el.clone(), + &worker, + recursion_layer_proof_config(), + &setup_base, + &setup, + &setup_tree, + &vk, + &vars_hint, + &wits_hint, + &finalization_hint, + ); + + println!("Proving is DONE, taken {:?}", now.elapsed()); + + let is_valid = verify_recursion_layer_proof::(&el, &proof, &vk); + + assert!(is_valid); + + source + .set_node_layer_proof( + recursive_circuit_type as u8, + depth, + idx, + ZkSyncRecursionLayerProof::NodeLayerCircuit(proof.clone()), + ) + .unwrap(); + } + + if next_aggregations.len() == 1 { + // end + + // let proof = source + // .get_node_layer_proof(recursive_circuit_type as u8, depth, 0) + // .unwrap(); + + break; + } + + depth += 1; + } + } + + // do everything for recursion tip + if source.get_recursion_tip_vk().is_err() { + use crate::zkevm_circuits::recursion::recursion_tip::input::*; + // replicate compute_setups::* + todo!(); + } + + // collect for recursion tip. We know that is this test depth is 0 + let mut recursion_tip_proofs = vec![]; + for recursive_circuit_type in (ZkSyncRecursionLayerStorageType::LeafLayerCircuitForMainVM as u8) + ..=(ZkSyncRecursionLayerStorageType::LeafLayerCircuitForEIP4844Repack as u8) + { + match source.get_node_layer_proof(recursive_circuit_type, 0, 0) { + Ok(proof) => recursion_tip_proofs.push(proof.into_inner()), + Err(_) => { + println!( + "Missing node proof for {} - using empty one instead", + recursive_circuit_type + ); + recursion_tip_proofs.push(empty_node_proof().into_inner()); + } + }; + } + + assert_eq!(recursion_tip_proofs.len(), NUM_CIRCUIT_TYPES_TO_SCHEDULE); + + // node VK + let node_vk = source.get_recursion_layer_node_vk().unwrap(); + // leaf params + use crate::zkevm_circuits::recursion::leaf_layer::input::RecursionLeafParametersWitness; + let leaf_layer_params: [RecursionLeafParametersWitness; 16] = leaf_vk_commits + .iter() + .map(|el| el.1.clone()) + .collect::>() + .try_into() + .unwrap(); + + // compute single(for now) recursion tip proof + + let tip_proof = if source.get_recursive_tip_proof().is_err() || !options.try_reuse_artifacts { + let node_layer_vk_commitment = compute_node_vk_commitment(node_vk.clone()); + use crate::boojum::gadgets::queue::*; + use crate::zkevm_circuits::recursion::recursion_tip::input::*; + use circuit_definitions::boojum::field::Field; + let mut branch_circuit_type_set = [GoldilocksField::ZERO; RECURSION_TIP_ARITY]; + assert!(branch_circuit_type_set.len() >= recursion_queues.len()); + let mut queue_sets: [_; RECURSION_TIP_ARITY] = + std::array::from_fn(|_| QueueState::placeholder_witness()); + + for ((circuit_type, queue_state), (src_type, src_queue, _)) in branch_circuit_type_set + .iter_mut() + .zip(queue_sets.iter_mut()) + .zip(recursion_queues.iter()) + { + *circuit_type = GoldilocksField::from_u64_unchecked(*src_type); + *queue_state = take_sponge_like_queue_state_from_simulator(src_queue); + println!( + "Circuit: {:?} num items:{:?}", + circuit_type, src_queue.num_items + ); + } + + let input = RecursionTipInputWitness { + leaf_layer_parameters: leaf_layer_params.clone(), + node_layer_vk_commitment: node_layer_vk_commitment, + branch_circuit_type_set: branch_circuit_type_set, + queue_set: queue_sets, + }; + + dbg!(&input); + + let witness = RecursionTipInstanceWitness { + input, + vk_witness: node_vk.clone().into_inner(), + proof_witnesses: recursion_tip_proofs.into(), + }; + + use crate::zkevm_circuits::recursion::recursion_tip::*; + use circuit_definitions::circuit_definitions::recursion_layer::recursion_tip::*; + + let config = RecursionTipConfig { + proof_config: recursion_layer_proof_config(), + vk_fixed_parameters: node_vk.clone().into_inner().fixed_parameters, + _marker: std::marker::PhantomData, + }; + + let circuit = RecursionTipCircuit { + witness, + config, + transcript_params: (), + _marker: std::marker::PhantomData, + }; + + let circuit = ZkSyncRecursiveLayerCircuit::RecursionTipCircuit(circuit); + // prove it + + // test_recursive_circuit(circuit.clone()); + + println!("Creating setup data for recursion tip"); + + let (setup_base, setup, vk, setup_tree, vars_hint, wits_hint, finalization_hint) = + create_recursive_layer_setup_data( + circuit.clone(), + &worker, + RECURSION_LAYER_FRI_LDE_FACTOR, + RECURSION_LAYER_CAP_SIZE, + ); + + assert_eq!(source.get_recursion_tip_vk().unwrap().into_inner(), vk); + + println!("Proving recursion tip"); + + let proof = prove_recursion_layer_circuit::( + circuit.clone(), + &worker, + recursion_layer_proof_config(), + &setup_base, + &setup, + &setup_tree, + &vk, + &vars_hint, + &wits_hint, + &finalization_hint, + ); + + println!("Verifying recursion tip"); + + let is_valid = verify_recursion_layer_proof::(&circuit, &proof, &vk); + + assert!(is_valid); + + source + .set_recursive_tip_proof(ZkSyncRecursionLayerProof::RecursionTipCircuit( + proof.clone(), + )) + .unwrap(); + + ZkSyncRecursionLayerProof::RecursionTipCircuit(proof) + } else { + source.get_recursive_tip_proof().unwrap() + }; + + let recursion_tip_vk = source.get_recursion_tip_vk().unwrap().into_inner(); + + // ideally we need to fill previous block meta and aux hashes, but here we are fine + + use crate::zkevm_circuits::scheduler::SchedulerConfig; + + let config = SchedulerConfig { + proof_config: recursion_layer_proof_config(), + leaf_layer_parameters: leaf_layer_params.clone(), + node_layer_vk: node_vk.into_inner(), + recursion_tip_vk: recursion_tip_vk.clone(), + vk_fixed_parameters: recursion_tip_vk.fixed_parameters, + capacity: SCHEDULER_CAPACITY, + _marker: std::marker::PhantomData, + }; + + let mut scheduler_witness = scheduler_partial_input; + // we need to reassign block specific data, and proofs + + // proofs + let recursion_tip_proof = tip_proof.into_inner(); + scheduler_witness.proof_witnesses = vec![recursion_tip_proof].into(); + + // blobs + let eip4844_witnesses: [_; MAX_4844_BLOBS_PER_BLOCK] = blobs.map(|blob| { + blob.map(|blob| { + let (_blob_arr, linear_hash, _versioned_hash, output_hash) = + generate_eip4844_witness::(&blob, "kzg/src/trusted_setup.json"); + use crate::zkevm_circuits::eip_4844::input::BlobChunkWitness; + use crate::zkevm_circuits::eip_4844::input::EIP4844CircuitInstanceWitness; + use crate::zkevm_circuits::eip_4844::input::EIP4844InputOutputWitness; + use crate::zkevm_circuits::eip_4844::input::EIP4844OutputDataWitness; + use circuit_definitions::circuit_definitions::base_layer::EIP4844Circuit; + use crossbeam::atomic::AtomicCell; + use std::collections::VecDeque; + use std::sync::Arc; + + let witness = EIP4844OutputDataWitness { + linear_hash, + output_hash, + }; + + witness + }) + }); + scheduler_witness.eip4844_witnesses = eip4844_witnesses; + + let scheduler_circuit = SchedulerCircuit { + witness: scheduler_witness.clone(), + config, + transcript_params: (), + _marker: std::marker::PhantomData, + }; + + println!("Computing scheduler proof"); + + let scheduler_circuit = ZkSyncRecursiveLayerCircuit::SchedulerCircuit(scheduler_circuit); + + if source.get_scheduler_proof().is_err() || !options.try_reuse_artifacts { + test_recursive_circuit(scheduler_circuit.clone()); + println!("Circuit is satisfied"); + + let (setup_base, setup, vk, setup_tree, vars_hint, wits_hint, finalization_hint) = + create_recursive_layer_setup_data( + scheduler_circuit.clone(), + &worker, + RECURSION_LAYER_FRI_LDE_FACTOR, + RECURSION_LAYER_CAP_SIZE, + ); + + // we did it above + source + .set_recursion_layer_vk(ZkSyncRecursionLayerVerificationKey::SchedulerCircuit( + vk.clone(), + )) + .unwrap(); + source + .set_recursion_layer_finalization_hint( + ZkSyncRecursionLayerFinalizationHint::SchedulerCircuit(finalization_hint.clone()), + ) + .unwrap(); + + // prove + println!("Proving!"); + let now = std::time::Instant::now(); + + let proof = prove_recursion_layer_circuit::( + scheduler_circuit.clone(), + &worker, + recursion_layer_proof_config(), + &setup_base, + &setup, + &setup_tree, + &vk, + &vars_hint, + &wits_hint, + &finalization_hint, + ); + + println!("Proving is DONE, taken {:?}", now.elapsed()); + + let is_valid = verify_recursion_layer_proof::(&scheduler_circuit, &proof, &vk); + + assert!(is_valid); + + source + .set_scheduler_proof(ZkSyncRecursionLayerProof::SchedulerCircuit(proof)) + .unwrap(); + } + + println!("DONE"); +} + +#[ignore = "broken test"] +#[test] +fn run_single() { + use crate::boojum::cs::implementations::transcript::GoldilocksPoisedon2Transcript; + use crate::boojum::gadgets::recursion::recursive_transcript::CircuitAlgebraicSpongeBasedTranscript; + use crate::data_source::*; + use circuit_definitions::circuit_definitions::recursion_layer::verifier_builder::dyn_verifier_builder_for_recursive_circuit_type; + + type TR = GoldilocksPoisedon2Transcript; + type H = GoldilocksPoseidon2Sponge; + + let f = std::fs::File::open("tmp.json").unwrap(); + let circuit: ZkSyncRecursiveLayerCircuit = serde_json::from_reader(f).unwrap(); + let ZkSyncRecursiveLayerCircuit::SchedulerCircuit(inner) = &circuit else { + panic!() + }; + + assert_eq!( + inner.witness.proof_witnesses.len(), + NUM_CIRCUIT_TYPES_TO_SCHEDULE + ); + + let verifier_builder = dyn_verifier_builder_for_recursive_circuit_type( + ZkSyncRecursionLayerStorageType::NodeLayerCircuit, + ); + let verifier = verifier_builder.create_verifier(); + + let source = LocalFileDataSource::default(); + source.create_folders_for_storing_data(); + let vk = source.get_recursion_layer_node_vk().unwrap().into_inner(); + + for (idx, proof) in inner.witness.proof_witnesses.iter().enumerate() { + let is_valid = verifier.verify::((), &vk, &proof); + assert!(is_valid, "failed at step {}", idx); + } + + for circuit_type in (ZkSyncRecursionLayerStorageType::LeafLayerCircuitForMainVM as u8) + ..=(ZkSyncRecursionLayerStorageType::LeafLayerCircuitForL1MessagesHasher as u8) + { + let proof = source + .get_node_layer_proof(circuit_type, 0, 0) + .unwrap() + .into_inner(); + let is_valid = verifier.verify::((), &vk, &proof); + assert!(is_valid, "failed for circuit type {}", circuit_type); + } + + test_recursive_circuit(circuit); +} diff --git a/crates/zkevm_test_harness/src/tests/complex_tests/test_artifacts/basic_test.json b/crates/zkevm_test_harness/src/tests/complex_tests/test_artifacts/basic_test.json new file mode 100644 index 0000000..02d9144 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/complex_tests/test_artifacts/basic_test.json @@ -0,0 +1 @@ +{"predeployed_contracts":{"0x0000000000000000000000000000000000000000":[[0,0,0,1,1,32,1,144,0,0,0,4,0,0,193,61,0,0,0,0,1,0,0,25,0,0,0,17,0,1,4,46],[0,0,0,128,1,0,0,57,0,0,0,64,0,16,4,63,0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75],[0,0,0,14,0,0,193,61,0,0,0,32,1,0,0,57,0,0,1,0,0,16,4,67,0,0,1,32,0,0,4,67],[0,0,0,5,1,0,0,65,0,0,0,17,0,1,4,46,0,0,0,0,1,0,0,25,0,0,0,18,0,1,4,48],[0,0,0,16,0,0,4,50,0,0,0,17,0,1,4,46,0,0,0,18,0,1,4,48,0,0,0,0,0,0,0,0],[0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,1,0,0,0,0,0,0,0,0,0],[175,66,242,103,141,4,1,110,33,198,129,151,108,128,65,227,125,97,137,230,206,140,232,80,64,84,68,121,2,83,255,78]],"0x0000000000000000000000000000000000000001":[[0,0,0,1,2,32,1,144,0,0,0,32,0,0,193,61,0,0,0,96,2,16,3,112,0,0,0,0,2,2,4,59],[0,0,0,12,5,32,0,65,0,0,0,64,3,16,3,112,0,0,0,0,3,3,4,59,0,0,0,12,6,48,0,65],[0,0,0,32,4,16,3,112,0,0,0,0,4,4,4,59,0,0,0,29,7,64,0,138,0,0,0,2,8,0,0,138],[0,0,0,0,7,135,0,75,0,0,0,30,0,0,65,61,0,0,0,13,6,96,0,156,0,0,0,30,0,0,65,61],[0,0,0,12,5,80,0,156,0,0,0,30,0,0,161,61,0,0,0,0,1,1,4,59,0,0,0,0,0,16,4,53],[0,0,0,27,1,64,0,138,0,0,0,32,0,16,4,63,0,0,0,64,0,48,4,63,0,0,0,96,0,32,4,63],[0,0,27,88,1,0,0,57,0,0,0,14,2,0,0,65,0,0,0,0,1,18,4,32,0,0,0,0,2,0,4,51],[0,0,0,0,1,18,1,112,0,0,0,37,0,0,193,61,0,0,0,0,1,0,0,25,0,0,0,40,0,1,4,46],[0,0,0,32,1,0,0,57,0,0,1,0,0,16,4,67,0,0,1,32,0,0,4,67,0,0,0,11,1,0,0,65],[0,0,0,40,0,1,4,46,0,0,0,15,1,0,0,65,0,0,0,40,0,1,4,46,0,0,0,39,0,0,4,50],[0,0,0,40,0,1,4,46,0,0,0,41,0,1,4,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,1,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,69,81,35,25,80,183,95,196,64,45,161,115,47,201,190,191],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,69,81,35,25,80,183,95,196,64,45,161,115,47,201,190,192],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,4,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,32,0,0,0,0,0,0,0,0],[179,68,59,65,142,145,24,29,2,67,103,34,93,183,33,202,28,183,196,203,84,235,179,0,253,132,216,164,97,35,28,11]],"0x0000000000000000000000000000000000000002":[[0,0,0,1,2,32,1,144,0,0,0,51,0,0,193,61,0,0,0,0,2,1,0,25,0,0,0,96,3,32,2,112],[0,0,0,31,4,48,1,143,0,0,0,17,2,48,1,151,0,0,0,5,5,32,2,114,0,0,0,16,0,0,97,61],[0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,113,3,79,0,0,0,0,8,8,4,59],[0,0,0,0,0,135,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,0,9,0,0,65,61],[0,0,0,0,6,4,0,75,0,0,0,30,0,0,97,61,0,0,0,3,4,64,2,16,0,0,0,5,5,80,2,16],[0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47,0,0,0,0,1,81,3,79],[0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207],[0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,0,18,1,0,0,65,0,0,0,0,0,18,4,53],[0,0,0,8,1,48,0,57,0,0,0,63,1,16,1,143,0,0,0,0,1,18,0,73,0,0,0,195,2,32,2,16],[0,0,0,64,3,16,0,57,0,0,0,0,0,35,4,53,0,0,0,72,1,16,0,57,0,0,0,27,2,16,2,16],[0,0,0,19,2,32,1,151,0,0,0,6,1,16,2,112,0,0,0,192,3,16,2,16,0,0,0,0,2,50,1,159],[0,0,0,20,2,32,1,199,0,0,0,7,49,16,0,201,0,0,0,0,1,18,4,32,0,0,0,0,1,1,0,75],[0,0,0,56,0,0,193,61,0,0,0,0,1,0,0,25,0,0,0,60,0,1,4,48,0,0,0,32,1,0,0,57],[0,0,1,0,0,16,4,67,0,0,1,32,0,0,4,67,0,0,0,16,1,0,0,65,0,0,0,59,0,1,4,46],[0,0,0,21,1,0,0,65,0,0,0,59,0,1,4,46,0,0,0,58,0,0,4,50,0,0,0,59,0,1,4,46],[0,0,0,60,0,1,4,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,1,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255],[128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,254,255,255,255,255,255,255,255,255,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0],[228,246,96,45,71,192,105,208,154,38,228,162,159,15,59,143,57,108,106,187,164,190,80,74,187,89,113,131,24,79,249,176]],"0x0000000000000000000000000000000000000006":[[0,4,0,0,0,0,0,2,0,0,0,1,2,32,1,144,0,0,0,17,0,0,193,61,0,0,0,96,2,16,3,112],[0,0,0,0,2,2,4,59,0,0,0,64,3,16,3,112,0,0,0,0,3,3,4,59,0,0,0,0,5,50,1,159],[0,0,0,0,20,1,4,60,0,0,0,0,1,1,4,59,0,0,0,0,6,65,1,159,0,0,0,0,7,101,1,160],[0,0,0,22,0,0,193,61,0,0,0,0,0,0,4,53,0,0,0,32,0,0,4,63,0,0,0,132,1,0,0,65],[0,0,1,228,0,1,4,46,0,0,0,32,1,0,0,57,0,0,1,0,0,16,4,67,0,0,1,32,0,0,4,67],[0,0,0,122,1,0,0,65,0,0,1,228,0,1,4,46,0,0,0,0,7,5,0,75,0,0,0,82,0,0,97,61],[0,0,0,0,7,6,0,75,0,0,0,82,0,0,193,61,0,0,0,123,1,48,0,156,0,0,0,30,0,0,33,61],[0,0,0,123,1,32,0,156,0,0,0,32,0,0,161,61,0,0,0,0,1,0,4,20,0,0,0,0,1,16,4,32],[0,0,0,0,1,3,0,75,0,0,0,124,65,48,0,209,0,0,0,1,4,64,192,57,0,0,0,125,81,48,0,209],[0,0,0,126,81,16,0,209,0,0,0,0,1,84,0,25,0,0,0,123,4,16,0,156,0,0,0,127,1,16,32,65],[0,0,0,0,84,17,0,170,0,0,0,1,5,80,192,57,0,0,0,128,100,64,0,209,0,0,0,126,100,64,0,209],[0,0,0,0,4,101,0,25,0,0,0,123,5,64,0,156,0,0,0,127,4,64,32,65,0,0,0,0,65,20,0,170],[0,0,0,1,4,64,192,57,0,0,0,0,5,2,0,75,0,0,0,124,101,32,0,209,0,0,0,1,6,96,192,57],[0,0,0,125,117,32,0,209,0,0,0,126,117,80,0,209,0,0,0,0,5,118,0,25,0,0,0,123,6,80,0,156],[0,0,0,127,5,80,32,65,0,0,0,0,101,85,0,170,0,0,0,1,6,96,192,57,0,0,0,128,113,16,0,209],[0,0,0,128,117,80,0,209,0,0,0,126,113,16,0,209,0,0,0,0,1,116,0,25,0,0,0,126,84,80,0,209],[0,0,0,0,4,86,0,25,0,0,0,123,5,16,0,156,0,0,0,127,1,16,32,65,0,0,0,123,5,64,0,156],[0,0,0,127,4,64,32,65,0,0,0,129,5,0,0,65,0,0,0,130,6,0,0,65,0,0,0,131,7,16,0,156],[0,0,0,0,6,5,160,25,0,0,0,0,1,22,0,25,0,0,0,0,1,20,0,75,0,0,0,78,0,0,97,61],[0,0,0,0,1,0,4,20,0,0,0,0,1,16,4,32,0,0,0,0,0,48,4,53,0,0,0,32,0,32,4,63],[0,0,0,132,1,0,0,65,0,0,1,228,0,1,4,46,0,0,0,123,7,16,0,156,0,0,0,0,7,0,0,25],[0,0,0,1,7,0,32,57,0,0,0,123,8,64,0,156,0,0,0,1,7,112,33,191,0,0,0,0,6,6,0,75],[0,0,0,143,0,0,97,61,0,0,0,0,5,5,0,75,0,0,0,143,0,0,193,61,0,0,0,1,2,112,1,144],[0,0,0,95,0,0,97,61,0,0,0,0,2,0,4,20,0,0,0,0,2,32,4,32,0,0,0,0,2,4,0,75],[0,0,0,124,50,64,0,209,0,0,0,1,3,48,192,57,0,0,0,125,82,64,0,209,0,0,0,126,82,32,0,209],[0,0,0,0,2,83,0,25,0,0,0,123,3,32,0,156,0,0,0,127,2,32,32,65,0,0,0,0,83,34,0,170],[0,0,0,1,5,80,192,57,0,0,0,128,99,48,0,209,0,0,0,126,99,48,0,209,0,0,0,0,3,101,0,25],[0,0,0,123,5,48,0,156,0,0,0,127,3,48,32,65,0,0,0,0,50,35,0,170,0,0,0,1,3,48,192,57],[0,0,0,0,5,1,0,75,0,0,0,124,101,16,0,209,0,0,0,1,6,96,192,57,0,0,0,125,117,16,0,209],[0,0,0,126,117,80,0,209,0,0,0,0,5,118,0,25,0,0,0,123,6,80,0,156,0,0,0,127,5,80,32,65],[0,0,0,0,101,85,0,170,0,0,0,1,6,96,192,57,0,0,0,128,114,32,0,209,0,0,0,128,117,80,0,209],[0,0,0,126,114,32,0,209,0,0,0,0,2,115,0,25,0,0,0,126,83,80,0,209,0,0,0,0,3,86,0,25],[0,0,0,123,5,32,0,156,0,0,0,127,2,32,32,65,0,0,0,123,5,48,0,156,0,0,0,127,3,48,32,65],[0,0,0,129,5,0,0,65,0,0,0,130,6,0,0,65,0,0,0,131,7,32,0,156,0,0,0,0,6,5,160,25],[0,0,0,0,2,38,0,25,0,0,0,0,2,35,0,75,0,0,0,141,0,0,97,61,0,0,0,0,2,0,4,20],[0,0,0,0,2,32,4,32,0,0,0,0,0,64,4,53,0,0,1,162,0,0,1,61,0,0,0,1,5,112,1,144],[0,0,0,147,0,0,97,61,0,0,0,0,5,0,4,20,0,0,0,0,5,80,4,32,0,0,0,123,5,48,0,156],[0,0,0,151,0,0,33,61,0,0,0,126,5,32,0,156,0,0,0,153,0,0,65,61,0,0,0,0,5,0,4,20],[0,0,0,0,5,80,4,32,0,0,0,126,6,16,0,153,0,0,0,126,103,96,1,42,0,0,0,0,7,52,0,75],[0,0,0,223,0,0,193,61,0,0,0,0,6,38,0,75,0,0,0,223,0,0,193,61,0,0,0,0,3,4,0,75],[0,0,0,124,83,64,0,209,0,0,0,1,5,80,192,57,0,0,0,125,67,64,0,209,0,0,0,126,67,48,0,209],[0,0,0,0,3,69,0,25,0,0,0,123,4,48,0,156,0,0,0,127,3,48,32,65,0,0,0,0,84,51,0,170],[0,0,0,1,5,80,192,57,0,0,0,128,100,64,0,209,0,0,0,126,100,64,0,209,0,0,0,0,4,101,0,25],[0,0,0,123,5,64,0,156,0,0,0,127,4,64,32,65,0,0,0,0,52,52,0,170,0,0,0,1,3,48,192,57],[0,0,0,0,5,2,0,75,0,0,0,124,101,32,0,209,0,0,0,1,6,96,192,57,0,0,0,125,82,32,0,209],[0,0,0,126,82,32,0,209,0,0,0,0,2,86,0,25,0,0,0,123,5,32,0,156,0,0,0,127,2,32,32,65],[0,0,0,0,82,34,0,170,0,0,0,1,5,80,192,57,0,0,0,0,6,1,0,75,0,0,0,124,118,16,0,209],[0,0,0,1,7,112,192,57,0,0,0,125,97,16,0,209,0,0,0,126,97,16,0,209,0,0,0,0,1,103,0,25],[0,0,0,123,6,16,0,156,0,0,0,127,1,16,32,65,0,0,0,0,118,17,0,170,0,0,0,1,7,112,192,57],[0,0,0,128,20,64,0,209,0,0,0,128,33,32,0,209,0,0,0,126,33,16,0,209,0,0,0,0,1,37,0,25],[0,0,0,128,82,96,0,209,0,0,0,126,84,64,0,209,0,0,0,0,3,83,0,25,0,0,0,123,4,48,0,156],[0,0,0,127,3,48,32,65,0,0,0,123,4,16,0,156,0,0,0,127,1,16,32,65,0,0,0,126,66,32,0,209],[0,0,0,0,4,71,0,25,0,0,0,123,2,64,0,156,0,0,0,127,4,64,32,65,0,0,0,129,2,0,0,65],[0,0,0,130,5,0,0,65,0,0,0,131,6,48,0,156,0,0,0,0,5,2,160,25,0,0,0,0,2,53,0,25],[0,0,0,0,3,36,0,75,0,0,0,220,0,0,193,61,0,0,0,0,1,33,0,75,0,0,0,13,0,0,97,61],[0,0,0,0,1,0,4,20,0,0,0,0,1,16,4,32,0,0,0,13,0,0,1,61,0,0,0,126,5,32,0,153],[0,0,0,126,86,80,1,42,0,0,0,0,6,52,0,75,0,0,0,233,0,0,193,61,0,0,0,0,5,81,0,75],[0,0,0,233,0,0,97,61,0,0,0,0,5,33,0,75,0,0,0,233,0,0,97,61,0,0,0,0,5,0,4,20],[0,0,0,0,5,80,4,32,0,0,0,0,5,4,0,75,0,0,0,124,101,64,0,209,0,0,0,1,6,96,192,57],[0,0,0,125,117,64,0,209,0,0,0,126,117,80,0,209,0,0,0,0,12,118,0,25,0,0,0,123,5,192,0,156],[0,0,0,127,12,192,32,65,0,0,0,0,101,204,0,170,0,0,0,1,6,96,192,57,0,0,0,128,117,80,0,209],[0,0,0,126,117,80,0,209,0,0,0,0,5,118,0,25,0,0,0,123,6,80,0,156,0,0,0,127,5,80,32,65],[0,0,0,0,101,197,0,170,0,0,0,1,6,96,192,57,0,0,0,0,7,1,0,75,0,0,0,124,135,16,0,209],[0,0,0,1,8,128,192,57,0,0,0,125,151,16,0,209,0,0,0,126,151,112,0,209,0,0,0,0,13,152,0,25],[0,0,0,123,7,208,0,156,0,0,0,127,13,208,32,65,0,0,0,0,135,221,0,170,0,0,0,1,8,128,192,57],[0,0,0,128,149,80,0,209,0,0,0,128,151,112,0,209,0,0,0,126,149,80,0,209,0,0,0,0,9,150,0,25],[0,0,0,126,101,112,0,209,0,0,0,0,5,104,0,25,0,0,0,123,6,144,0,156,0,0,0,127,9,144,32,65],[0,0,0,123,6,80,0,156,0,0,0,127,5,80,32,65,0,0,0,129,7,0,0,65,0,0,0,130,6,0,0,65],[0,0,0,131,8,144,0,156,0,0,0,0,8,7,0,25,0,0,0,0,8,6,32,25,0,0,0,0,8,152,0,25],[0,0,0,0,4,52,0,75,0,4,0,0,0,12,0,29,0,0,1,72,0,0,193,61,0,0,0,0,1,33,0,75],[0,0,1,72,0,0,193,61,0,3,0,0,0,13,0,29,0,0,0,0,1,133,0,75,0,0,1,30,0,0,97,61],[0,0,0,0,1,0,4,20,0,0,0,0,1,16,4,32,0,0,0,0,1,12,0,25,0,0,0,0,2,12,0,25],[1,227,1,172,0,0,4,15,0,0,0,126,33,16,1,42,0,0,0,1,1,32,2,16,0,0,0,126,49,16,1,42],[0,0,0,0,1,35,0,25,0,0,0,126,18,16,1,42,0,0,0,3,2,0,0,41,0,0,0,126,50,32,1,42],[0,0,0,1,2,48,2,16,0,0,0,126,35,32,1,42,1,227,1,180,0,0,4,15,0,2,0,0,0,1,0,29],[0,0,0,0,2,1,0,25,1,227,1,172,0,0,4,15,0,0,0,4,2,0,0,41,0,0,0,126,50,32,1,42],[0,0,0,1,2,48,2,16,0,0,0,126,66,32,1,42,0,0,0,126,2,64,0,153,0,0,0,126,66,32,1,42],[0,0,0,126,33,16,1,42,0,0,0,0,1,66,0,25,0,0,0,126,33,16,1,42,0,4,0,0,0,2,0,29],[0,0,0,126,1,32,0,153,0,0,0,126,33,16,1,42,0,0,0,0,1,50,0,25,0,0,0,126,33,16,1,42],[0,0,0,2,1,0,0,41,1,227,1,172,0,0,4,15,0,2,0,0,0,1,0,29,0,0,0,4,1,0,0,41],[1,227,1,165,0,0,4,15,0,0,0,126,3,0,0,65,0,0,0,3,2,48,0,106,0,0,0,126,50,32,1,42],[0,0,0,2,2,0,0,41,0,0,0,126,66,32,1,42,0,0,0,0,2,52,0,25,0,0,1,156,0,0,1,61],[0,0,0,0,1,3,0,75,0,0,0,124,65,48,0,209,0,0,0,1,4,64,192,57,0,0,0,125,49,48,0,209],[0,0,0,126,49,16,0,209,0,0,0,0,3,52,0,25,0,0,0,123,1,48,0,156,0,0,0,127,3,48,32,65],[0,0,0,0,65,51,0,170,0,0,0,1,4,64,192,57,0,0,0,128,145,16,0,209,0,0,0,126,145,16,0,209],[0,0,0,0,1,148,0,25,0,0,0,123,4,16,0,156,0,0,0,127,1,16,32,65,0,0,0,0,148,49,0,170],[0,0,0,1,9,144,192,57,0,0,0,0,1,2,0,75,0,0,0,124,161,32,0,209,0,0,0,1,10,160,192,57],[0,0,0,125,33,32,0,209,0,0,0,126,33,16,0,209,0,0,0,0,1,42,0,25,0,0,0,123,2,16,0,156],[0,0,0,127,1,16,32,65,0,0,0,0,162,17,0,170,0,0,0,1,10,160,192,57,0,0,0,128,180,64,0,209],[0,0,0,128,43,32,0,209,0,0,0,126,66,64,0,209,0,0,0,0,2,73,0,25,0,0,0,126,148,176,0,209],[0,0,0,0,4,154,0,25,0,0,0,123,9,32,0,156,0,0,0,127,2,32,32,65,0,0,0,123,9,64,0,156],[0,0,0,127,4,64,32,65,0,0,0,131,9,32,0,156,0,0,0,0,6,7,160,25,0,0,0,0,5,133,0,75],[0,0,1,116,0,0,193,61,0,0,0,0,2,38,0,25,0,0,0,0,2,36,0,75,0,0,1,118,0,0,97,61],[0,0,0,0,2,0,4,20,0,0,0,0,2,32,4,32,0,0,0,126,2,208,0,153,0,0,0,126,66,32,1,42],[0,3,0,0,0,4,0,29,0,0,0,126,33,16,1,42,0,0,0,0,1,66,0,25,0,0,0,126,18,16,1,42],[0,0,0,126,2,192,0,153,0,0,0,126,66,32,1,42,0,0,0,126,50,48,1,42,0,1,0,0,0,3,0,29],[0,0,0,0,2,67,0,25,0,0,0,126,35,32,1,42,1,227,1,180,0,0,4,15,0,2,0,0,0,1,0,29],[0,0,0,0,2,1,0,25,1,227,1,172,0,0,4,15,0,0,0,4,2,0,0,41,0,0,0,126,50,32,1,42],[0,0,0,1,2,48,0,41,0,0,0,126,66,32,1,42,0,0,0,126,2,64,0,153,0,0,0,126,66,32,1,42],[0,0,0,126,33,16,1,42,0,0,0,0,1,66,0,25,0,0,0,126,33,16,1,42,0,4,0,0,0,2,0,29],[0,0,0,126,1,32,0,153,0,0,0,126,33,16,1,42,0,0,0,0,1,50,0,25,0,0,0,126,33,16,1,42],[0,0,0,2,1,0,0,41,1,227,1,172,0,0,4,15,0,2,0,0,0,1,0,29,0,0,0,4,1,0,0,41],[1,227,1,165,0,0,4,15,0,0,0,2,2,0,0,41,0,0,0,126,50,32,1,42,0,0,0,3,2,48,0,41],[0,0,0,126,35,32,1,42,0,4,0,0,0,1,0,29,0,0,0,0,1,2,0,25,1,227,1,165,0,0,4,15],[0,0,0,4,2,0,0,41,0,0,0,0,0,32,4,53,0,0,0,32,0,16,4,63,0,0,0,132,1,0,0,65],[0,0,1,228,0,1,4,46,0,0,0,0,2,1,0,75,0,0,0,128,33,16,0,209,0,0,0,126,18,16,0,209],[0,0,0,1,1,16,192,57,0,0,0,123,2,16,0,156,0,0,0,127,1,16,32,65,0,0,0,0,0,1,4,45],[0,0,0,0,33,18,0,170,0,0,0,1,2,32,192,57,0,0,0,128,49,16,0,209,0,0,0,126,49,16,0,209],[0,0,0,0,1,50,0,25,0,0,0,123,2,16,0,156,0,0,0,127,1,16,32,65,0,0,0,0,0,1,4,45],[0,0,0,124,3,0,0,65,0,0,0,1,4,32,0,140,0,0,1,219,0,0,97,61,0,0,0,126,5,0,0,65],[0,0,0,124,3,0,0,65,0,0,0,0,4,0,0,25,0,0,0,1,6,32,1,144,0,0,1,194,0,0,193,61],[0,0,0,1,6,48,1,144,0,0,0,126,3,48,192,65,0,0,0,2,6,32,1,144,0,0,0,1,2,32,2,112],[0,0,0,1,3,48,2,112,0,0,1,188,0,0,97,61,0,0,0,1,6,80,1,144,0,0,1,202,0,0,193,61],[0,0,0,1,6,64,1,144,0,0,0,126,4,64,192,65,0,0,0,2,6,80,1,144,0,0,0,1,5,80,2,112],[0,0,0,1,4,64,2,112,0,0,1,196,0,0,97,61,0,0,0,0,6,37,0,75,0,0,1,209,0,0,161,61],[0,0,0,0,6,52,0,75,0,0,0,126,4,64,64,65,0,0,0,0,4,52,0,73,0,0,0,0,5,37,0,73],[0,0,1,213,0,0,1,61,0,0,0,0,6,67,0,75,0,0,0,126,3,48,64,65,0,0,0,0,3,67,0,73],[0,0,0,0,2,82,0,73,0,0,0,1,6,32,0,140,0,0,1,217,0,0,97,61,0,0,0,1,6,80,0,140],[0,0,1,186,0,0,193,61,0,0,0,1,2,32,0,140,0,0,0,0,3,4,192,25,0,0,0,0,33,19,0,170],[0,0,0,1,2,32,192,57,0,0,0,128,49,16,0,209,0,0,0,126,49,16,0,209,0,0,0,0,1,50,0,25],[0,0,0,123,2,16,0,156,0,0,0,127,1,16,32,65,0,0,0,0,0,1,4,45,0,0,1,227,0,0,4,50],[0,0,1,228,0,1,4,46,0,0,1,229,0,1,4,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,1,0,0,0,0,0,0,0,0,0],[48,100,78,114,225,49,160,41,184,80,69,182,129,129,88,93,151,129,106,145,104,113,202,141,60,32,140,22,216,124,253,70],[6,216,159,113,202,184,53,31,71,171,30,255,10,65,127,246,181,231,25,17,212,69,1,251,243,44,252,91,83,138,250,137],[74,71,70,38,35,160,74,122,176,116,165,134,128,115,1,58,233,101,225,118,124,212,192,134,243,174,216,161,155,249,14,81],[48,100,78,114,225,49,160,41,184,80,69,182,129,129,88,93,151,129,106,145,104,113,202,141,60,32,140,22,216,124,253,71],[207,155,177,141,30,206,95,214,71,175,186,73,126,126,167,162,104,126,149,110,151,142,53,114,195,223,115,233,39,131,2,185],[245,122,34,183,145,136,140,107,216,175,203,208,24,51,218,128,158,222,125,101,30,202,106,201,135,210,7,130,228,134,99,137],[42,31,103,68,206,23,157,142,51,75,234,78,105,107,210,132,31,106,193,122,225,85,33,185,122,23,202,169,80,173,40,215],[249,187,24,209,236,229,253,100,122,251,164,151,231,234,122,38,135,233,86,233,120,227,87,44,61,247,62,146,120,48,43,144],[6,68,231,46,19,26,2,155,133,4,91,104,24,21,133,217,120,22,169,22,135,28,168,211,194,8,193,109,135,207,212,111],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[112,3,123,40,239,21,61,241,7,226,49,20,4,23,166,169,17,183,164,86,35,38,142,101,153,108,207,226,194,198,0,221]],"0x0000000000000000000000000000000000000007":[[0,1,0,0,0,0,0,2,0,2,0,0,0,0,0,2,0,0,0,0,0,1,3,85,0,0,0,1,2,32,1,144],[0,0,0,74,0,0,193,61,0,0,0,32,2,16,3,112,0,0,0,0,3,2,4,59,0,0,0,0,4,1,4,59],[0,0,0,174,2,64,0,156,0,0,0,12,0,0,33,61,0,0,0,175,2,48,0,156,0,0,0,15,0,0,65,61],[0,0,0,0,1,0,4,20,0,0,0,0,1,16,4,32,0,0,0,0,1,0,3,103,0,0,0,0,2,67,1,160],[0,0,0,64,1,16,3,112,0,0,0,0,6,1,4,59,0,0,0,79,0,0,97,61,0,0,0,0,1,4,0,75],[0,0,0,176,33,64,0,209,0,0,0,1,2,32,192,57,0,0,0,177,81,64,0,209,0,0,0,175,81,16,0,209],[0,0,0,0,1,82,0,25,0,0,0,174,2,16,0,156,0,0,0,178,1,16,32,65,0,0,0,0,82,17,0,170],[0,0,0,1,5,80,192,57,0,0,0,179,114,32,0,209,0,0,0,175,114,32,0,209,0,0,0,0,2,117,0,25],[0,0,0,174,5,32,0,156,0,0,0,178,2,32,32,65,0,0,0,0,117,18,0,170,0,0,0,1,7,112,192,57],[0,0,0,0,2,3,0,75,0,0,0,176,130,48,0,209,0,0,0,1,8,128,192,57,0,0,0,177,146,48,0,209],[0,0,0,175,146,32,0,209,0,0,0,0,2,152,0,25,0,0,0,174,8,32,0,156,0,0,0,178,2,32,32,65],[0,0,0,0,152,34,0,170,0,0,0,1,9,144,192,57,0,0,0,179,165,80,0,209,0,0,0,179,168,128,0,209],[0,0,0,175,165,80,0,209,0,0,0,0,5,167,0,25,0,0,0,175,135,128,0,209,0,0,0,0,7,137,0,25],[0,0,0,174,8,80,0,156,0,0,0,178,5,80,32,65,0,0,0,174,8,112,0,156,0,0,0,178,7,112,32,65],[0,0,0,180,8,0,0,65,0,0,0,181,9,0,0,65,0,0,0,182,10,80,0,156,0,0,0,0,9,8,160,25],[0,0,0,0,5,89,0,25,0,0,0,0,5,87,0,75,0,0,0,65,0,0,97,61,0,0,0,0,5,0,4,20],[0,0,0,0,5,80,4,32,0,0,0,0,5,6,0,75,0,0,0,79,0,0,97,61,0,0,0,1,5,96,0,140],[0,0,0,81,0,0,97,61,0,0,0,2,3,96,0,140,0,0,0,85,0,0,193,61,0,0,0,183,3,0,0,65],[2,176,2,84,0,0,4,15,0,0,2,7,0,0,1,61,0,0,0,32,1,0,0,57,0,0,1,0,0,16,4,67],[0,0,1,32,0,0,4,67,0,0,0,173,1,0,0,65,0,0,2,177,0,1,4,46,0,0,0,184,1,0,0,65],[0,0,2,177,0,1,4,46,0,0,0,0,0,64,4,53,0,0,0,32,0,48,4,63,0,0,0,184,1,0,0,65],[0,0,2,177,0,1,4,46,0,0,0,183,8,0,0,65,0,0,0,0,3,0,0,25,0,0,0,183,4,0,0,65],[0,0,0,0,14,0,0,25,0,0,0,188,0,0,1,61,0,0,0,0,10,0,0,25,0,0,0,0,152,34,0,170],[0,0,0,179,184,128,0,209,0,0,0,175,184,128,0,209,0,0,0,1,11,176,192,57,0,0,0,0,8,155,0,25],[0,0,0,174,9,128,0,156,0,0,0,178,8,128,32,65,0,0,0,1,9,128,2,16,0,0,0,2,11,128,2,16],[0,0,0,174,9,144,0,156,0,0,0,185,11,176,32,65,0,0,0,0,201,119,0,170,0,0,0,179,217,144,0,209],[0,0,0,175,217,144,0,209,0,0,0,1,13,208,192,57,0,0,0,0,12,205,0,25,0,0,0,0,151,39,0,170],[0,0,0,179,215,112,0,209,0,0,0,175,215,112,0,209,0,0,0,1,13,208,192,57,0,0,0,0,7,157,0,25],[0,0,0,1,9,176,2,16,0,0,0,174,11,176,0,156,0,0,0,185,9,144,32,65,0,0,0,174,11,192,0,156],[0,0,0,178,12,192,32,65,0,0,0,0,186,162,0,169,0,0,0,0,219,18,0,169,0,0,0,0,10,173,0,25],[0,0,0,0,33,33,0,170,0,0,0,179,33,16,0,209,0,0,0,175,33,16,0,209,0,0,0,1,2,32,192,57],[0,0,0,0,2,162,0,25,0,0,0,0,1,12,0,75,0,0,0,186,161,192,0,209,0,0,0,1,10,160,192,57],[0,0,0,47,177,192,0,201,0,0,0,175,177,16,0,209,0,0,0,0,1,186,0,25,0,0,0,174,10,16,0,156],[0,0,0,178,1,16,32,65,0,0,0,174,10,32,0,156,0,0,0,178,2,32,32,65,0,0,0,1,10,16,2,16],[0,0,0,187,11,16,0,156,0,0,0,178,10,160,32,65,0,0,0,0,10,26,0,25,0,0,0,174,11,160,0,156],[0,0,0,178,10,160,32,65,0,0,0,0,10,168,0,73,0,0,0,178,11,160,0,156,0,0,0,0,10,11,128,25],[0,0,0,0,178,42,0,170,0,0,0,1,11,176,192,57,0,0,0,0,8,129,0,25,0,0,0,174,12,128,0,156],[0,0,0,178,8,128,32,65,0,0,0,0,168,138,0,170,0,0,0,1,10,160,192,57,0,0,0,174,12,144,0,156],[0,0,0,178,9,144,32,65,0,0,0,0,220,25,0,170,0,0,0,1,13,208,192,57,0,0,0,174,1,112,0,156],[0,0,0,178,7,112,32,65,0,0,0,0,151,121,0,170,0,0,0,1,9,144,192,57,0,0,0,179,33,32,0,209],[0,0,0,175,33,16,0,209,0,0,0,0,2,43,0,25,0,0,0,1,1,32,2,16,0,0,0,174,2,32,0,156],[0,0,0,185,1,16,32,65,0,0,0,179,130,128,0,209,0,0,0,179,139,192,0,209,0,0,0,179,135,112,0,209],[0,0,0,175,130,32,0,209,0,0,0,0,2,138,0,25,0,0,0,175,135,112,0,209,0,0,0,0,8,137,0,25],[0,0,0,174,7,128,0,156,0,0,0,178,8,128,32,65,0,0,0,175,151,176,0,209,0,0,0,0,7,157,0,25],[0,0,0,174,9,16,0,156,0,0,0,178,1,16,32,65,0,0,0,174,9,32,0,156,0,0,0,178,2,32,32,65],[0,0,0,174,9,112,0,156,0,0,0,178,7,112,32,65,0,0,0,0,2,114,0,25,0,0,0,174,7,32,0,156],[0,0,0,178,2,32,32,65,0,0,0,1,7,96,0,140,0,0,0,1,6,96,2,112,0,0,2,5,0,0,161,61],[0,0,0,0,7,8,0,25,0,0,0,1,8,96,1,144,0,0,0,90,0,0,97,61,0,0,0,0,8,3,0,75],[0,0,1,69,0,0,97,61,0,0,0,0,152,49,0,170,0,0,0,1,9,144,192,57,0,0,0,0,186,126,0,170],[0,0,0,1,11,176,192,57,0,2,0,0,0,14,0,29,0,0,0,0,237,116,0,170,0,0,0,1,14,224,192,57],[0,0,0,0,95,50,0,170,0,0,0,1,5,80,192,57,0,0,0,179,202,160,0,209,0,0,0,175,202,160,0,209],[0,0,0,0,12,203,0,25,0,0,0,179,168,128,0,209,0,0,0,174,10,192,0,156,0,0,0,178,12,192,32,65],[0,0,0,175,168,128,0,209,0,0,0,0,11,169,0,25,0,0,0,174,8,176,0,156,0,0,0,178,11,176,32,65],[0,0,0,179,152,208,0,209,0,0,0,175,152,128,0,209,0,0,0,0,10,158,0,25,0,0,0,0,9,203,0,73],[0,0,0,178,8,144,0,156,0,0,0,0,9,8,128,25,0,0,0,174,8,160,0,156,0,0,0,178,10,160,32,65],[0,0,0,179,216,240,0,209,0,0,0,175,216,128,0,209,0,0,0,0,8,213,0,25,0,0,0,174,5,128,0,156],[0,0,0,178,8,128,32,65,0,0,0,0,10,168,0,73,0,0,0,178,5,160,0,156,0,0,0,0,10,5,128,25],[0,0,0,0,5,169,1,160,0,0,1,166,0,0,97,61,0,0,0,0,67,55,0,170,0,0,0,1,4,64,192,57],[0,0,0,0,213,170,0,170,0,0,0,1,13,208,192,57,0,2,0,0,240,153,0,174,0,0,0,1,15,240,192,57],[0,0,0,179,227,48,0,209,0,0,0,175,227,48,0,209,0,0,0,0,3,228,0,25,0,0,0,174,4,48,0,156],[0,0,0,178,3,48,32,65,0,0,0,179,84,80,0,209,0,0,0,175,84,64,0,209,0,0,0,0,4,93,0,25],[0,0,0,174,5,64,0,156,0,0,0,178,4,64,32,65,0,0,0,0,237,52,0,170,0,0,0,1,14,224,192,57],[0,0,0,0,4,188,0,25,0,0,0,174,5,64,0,156,0,0,0,178,4,64,32,65,0,0,0,2,5,0,0,41],[0,0,0,179,197,80,0,209,0,0,0,175,197,80,0,209,0,0,0,0,5,207,0,25,0,0,0,174,12,80,0,156],[0,0,0,178,5,80,32,65,0,0,0,0,252,69,0,170,0,0,0,1,15,240,192,57,0,2,0,0,0,7,0,29],[0,0,0,0,123,181,0,170,0,0,0,1,7,112,192,57,0,1,0,0,64,149,0,174,0,0,0,1,4,64,192,57],[0,0,0,179,92,192,0,209,0,0,0,175,197,192,0,209,0,0,0,0,5,207,0,25,0,0,0,174,12,80,0,156],[0,0,0,178,5,80,32,65,0,0,0,179,220,208,0,209,0,0,0,175,220,192,0,209,0,0,0,0,12,222,0,25],[0,0,0,174,13,192,0,156,0,0,0,178,12,192,32,65,0,0,0,0,5,92,0,73,0,0,0,179,203,176,0,209],[0,0,0,178,12,80,0,156,0,0,0,0,5,12,128,25,0,0,0,175,203,176,0,209,0,0,0,0,7,199,0,25],[0,0,0,174,11,112,0,156,0,0,0,178,7,112,32,65,0,0,0,0,7,87,0,73,0,0,0,178,11,112,0,156],[0,0,0,0,7,11,128,25,0,0,0,0,167,167,0,170,0,0,0,1,10,160,192,57,0,0,0,0,149,149,0,170],[0,0,0,1,9,144,192,57,0,0,0,1,11,0,0,41,0,0,0,179,203,176,0,209,0,0,0,175,203,176,0,209],[0,0,0,0,4,196,0,25,0,0,0,174,11,64,0,156,0,0,0,178,4,64,32,65,0,0,0,0,184,132,0,170],[0,0,0,1,11,176,192,57,0,0,0,0,67,52,0,170,0,0,0,1,4,64,192,57,0,0,0,179,199,112,0,209],[0,0,0,175,199,112,0,209,0,0,0,0,7,202,0,25,0,0,0,179,165,80,0,209,0,0,0,179,168,128,0,209],[0,0,0,175,168,128,0,209,0,0,0,0,8,171,0,25,0,0,0,174,10,112,0,156,0,0,0,178,7,112,32,65],[0,0,0,175,165,80,0,209,0,0,0,0,14,169,0,25,0,0,0,174,5,128,0,156,0,0,0,178,8,128,32,65],[0,0,0,179,83,48,0,209,0,0,0,175,83,48,0,209,0,0,0,0,3,84,0,25,0,0,0,174,4,48,0,156],[0,0,0,178,3,48,32,65,0,0,0,0,4,135,0,73,0,0,0,2,7,0,0,41,0,0,0,178,5,64,0,156],[0,0,0,0,4,5,128,25,0,0,0,174,5,224,0,156,0,0,0,178,14,224,32,65,0,0,0,0,10,0,0,25],[0,0,0,91,0,0,1,61,0,0,0,0,67,34,0,170,0,0,0,1,4,64,192,57,0,0,0,179,83,48,0,209],[0,0,0,175,83,48,0,209,0,0,0,0,4,84,0,25,0,0,0,174,3,64,0,156,0,0,0,178,4,64,32,65],[0,0,0,1,3,64,2,16,0,0,0,2,9,64,2,16,0,0,0,174,3,48,0,156,0,0,0,185,9,144,32,65],[0,0,0,0,186,119,0,170,0,0,0,1,11,176,192,57,0,0,0,0,220,33,0,170,0,0,0,1,13,208,192,57],[0,0,0,0,88,39,0,170,0,0,0,1,5,80,192,57,0,0,0,1,3,144,2,16,0,0,0,174,9,144,0,156],[0,0,0,185,3,48,32,65,0,0,0,179,169,160,0,209,0,0,0,175,169,144,0,209,0,0,0,0,9,171,0,25],[0,0,0,174,10,144,0,156,0,0,0,178,9,144,32,65,0,0,0,0,10,9,0,75,0,0,0,186,186,144,0,209],[0,0,0,1,11,176,192,57,0,0,0,179,202,192,0,209,0,0,0,47,201,144,0,201,0,0,0,175,201,144,0,209],[0,0,0,0,9,203,0,25,0,0,0,175,186,160,0,209,0,0,0,0,10,189,0,25,0,0,0,174,11,144,0,156],[0,0,0,178,9,144,32,65,0,0,0,174,11,160,0,156,0,0,0,178,10,160,32,65,0,0,0,1,11,144,2,16],[0,0,0,187,12,144,0,156,0,0,0,178,11,176,32,65,0,0,0,0,11,155,0,25,0,0,0,174,12,176,0,156],[0,0,0,178,11,176,32,65,0,0,0,0,11,180,0,73,0,0,0,178,12,176,0,156,0,0,0,0,11,12,128,25],[0,0,0,0,202,171,0,170,0,0,0,1,12,192,192,57,0,0,0,0,4,73,0,25,0,0,0,174,13,64,0,156],[0,0,0,178,4,64,32,65,0,0,0,0,180,75,0,170,0,0,0,1,11,176,192,57,0,0,0,174,13,48,0,156],[0,0,0,178,3,48,32,65,0,0,0,0,217,57,0,170,0,0,0,1,13,208,192,57,0,0,0,179,232,128,0,209],[0,0,0,175,232,128,0,209,0,0,0,0,5,229,0,25,0,0,0,174,8,80,0,156,0,0,0,178,5,80,32,65],[0,0,0,0,83,83,0,170,0,0,0,1,5,80,192,57,0,0,0,179,168,160,0,209,0,0,0,175,168,128,0,209],[0,0,0,0,8,172,0,25,0,0,0,1,10,128,2,16,0,0,0,174,8,128,0,156,0,0,0,185,10,160,32,65],[0,0,0,179,132,64,0,209,0,0,0,179,137,144,0,209,0,0,0,179,131,48,0,209,0,0,0,175,132,64,0,209],[0,0,0,0,4,139,0,25,0,0,0,175,131,48,0,209,0,0,0,0,8,133,0,25,0,0,0,174,3,128,0,156],[0,0,0,178,8,128,32,65,0,0,0,175,83,144,0,209,0,0,0,0,3,93,0,25,0,0,0,174,5,160,0,156],[0,0,0,178,10,160,32,65,0,0,0,174,5,64,0,156,0,0,0,178,4,64,32,65,0,0,0,174,5,48,0,156],[0,0,0,178,3,48,32,65,0,0,0,0,3,52,0,25,0,0,0,174,4,48,0,156,0,0,0,178,3,48,32,65],[0,0,0,0,14,1,0,25,0,0,0,0,1,10,0,25,0,0,0,0,4,2,0,25,0,0,0,0,2,3,0,25],[0,0,0,0,3,7,0,25,0,0,0,185,0,0,1,61,0,0,0,0,33,68,0,170,0,0,0,1,2,32,192,57],[0,0,0,179,81,16,0,209,0,0,0,175,81,16,0,209,0,0,0,0,2,82,0,25,0,0,0,174,1,32,0,156],[0,0,0,178,2,32,32,65,0,0,0,1,1,32,2,16,0,0,0,2,5,32,2,16,0,0,0,174,1,16,0,156],[0,0,0,185,5,80,32,65,0,0,0,0,135,51,0,170,0,0,0,1,8,128,192,57,0,0,0,2,169,64,0,186],[0,0,0,1,10,160,192,57,0,0,0,0,52,52,0,170,0,0,0,1,3,48,192,57,0,0,0,1,1,80,2,16],[0,0,0,174,5,80,0,156,0,0,0,185,1,16,32,65,0,0,0,179,117,112,0,209,0,0,0,175,117,80,0,209],[0,0,0,0,5,120,0,25,0,0,0,174,7,80,0,156,0,0,0,178,5,80,32,65,0,0,0,0,7,5,0,75],[0,0,0,186,135,80,0,209,0,0,0,1,8,128,192,57,0,0,0,179,151,144,0,209,0,0,0,47,149,80,0,201],[0,0,0,175,149,80,0,209,0,0,0,0,5,152,0,25,0,0,0,175,135,112,0,209,0,0,0,0,7,138,0,25],[0,0,0,174,8,80,0,156,0,0,0,178,5,80,32,65,0,0,0,174,8,112,0,156,0,0,0,178,7,112,32,65],[0,0,0,1,8,80,2,16,0,0,0,187,9,80,0,156,0,0,0,178,8,128,32,65,0,0,0,0,8,88,0,25],[0,0,0,174,9,128,0,156,0,0,0,178,8,128,32,65,0,0,0,0,8,130,0,73,0,0,0,178,9,128,0,156],[0,0,0,0,8,9,128,25,0,0,0,0,151,120,0,170,0,0,0,1,9,144,192,57,0,0,0,0,2,37,0,25],[0,0,0,174,10,32,0,156,0,0,0,178,2,32,32,65,0,0,0,0,130,40,0,170,0,0,0,1,8,128,192,57],[0,0,0,174,10,16,0,156,0,0,0,178,1,16,32,65,0,0,0,0,165,81,0,170,0,0,0,1,10,160,192,57],[0,0,0,179,180,64,0,209,0,0,0,175,180,64,0,209,0,0,0,0,3,179,0,25,0,0,0,174,4,48,0,156],[0,0,0,178,3,48,32,65,0,0,0,0,49,49,0,170,0,0,0,1,3,48,192,57,0,0,0,179,116,112,0,209],[0,0,0,175,116,64,0,209,0,0,0,0,4,121,0,25,0,0,0,1,14,64,2,16,0,0,0,174,4,64,0,156],[0,0,0,185,14,224,32,65,0,0,0,179,66,32,0,209,0,0,0,179,84,80,0,209,0,0,0,179,81,16,0,209],[0,0,0,175,82,32,0,209,0,0,0,0,2,88,0,25,0,0,0,175,81,16,0,209,0,0,0,0,8,83,0,25],[0,0,0,174,1,128,0,156,0,0,0,178,8,128,32,65,0,0,0,175,49,64,0,209,0,0,0,0,1,58,0,25],[0,0,0,174,3,224,0,156,0,0,0,178,14,224,32,65,0,0,0,174,3,32,0,156,0,0,0,178,2,32,32,65],[0,0,0,174,3,16,0,156,0,0,0,178,1,16,32,65,0,0,0,0,4,18,0,25,0,0,0,174,1,64,0,156],[0,0,0,178,4,64,32,65,0,0,0,0,1,14,0,25,0,0,0,0,2,4,0,25,0,0,0,0,3,8,0,25],[0,0,0,185,0,0,1,61,0,0,0,0,1,14,0,25,0,0,0,0,2,4,0,25,2,176,2,25,0,0,4,15],[0,2,0,0,0,2,0,29,2,176,2,18,0,0,4,15,0,1,0,0,0,1,0,29,0,0,0,2,1,0,0,41],[2,176,2,18,0,0,4,15,0,0,0,1,2,0,0,41,0,0,0,0,0,32,4,53,0,0,0,32,0,16,4,63],[0,0,0,184,1,0,0,65,0,0,2,177,0,1,4,46,0,0,0,0,2,1,0,75,0,0,0,179,33,16,0,209],[0,0,0,175,18,16,0,209,0,0,0,1,1,16,192,57,0,0,0,174,2,16,0,156,0,0,0,178,1,16,32,65],[0,0,0,0,0,1,4,45,0,0,0,0,4,3,0,75,0,0,0,0,4,3,0,25,0,0,2,81,0,0,97,61],[0,0,0,176,4,0,0,65,0,0,0,1,5,48,0,140,0,0,2,67,0,0,97,61,0,0,0,175,6,0,0,65],[0,0,0,176,4,0,0,65,0,0,0,0,5,0,0,25,0,0,0,1,7,48,1,144,0,0,2,42,0,0,193,61],[0,0,0,1,7,64,1,144,0,0,0,175,4,64,192,65,0,0,0,2,7,48,1,144,0,0,0,1,3,48,2,112],[0,0,0,1,4,64,2,112,0,0,2,36,0,0,97,61,0,0,0,1,7,96,1,144,0,0,2,50,0,0,193,61],[0,0,0,1,7,80,1,144,0,0,0,175,5,80,192,65,0,0,0,2,7,96,1,144,0,0,0,1,6,96,2,112],[0,0,0,1,5,80,2,112,0,0,2,44,0,0,97,61,0,0,0,0,7,54,0,75,0,0,2,57,0,0,161,61],[0,0,0,0,7,69,0,75,0,0,0,175,5,80,64,65,0,0,0,0,5,69,0,73,0,0,0,0,6,54,0,73],[0,0,2,61,0,0,1,61,0,0,0,0,7,84,0,75,0,0,0,175,4,64,64,65,0,0,0,0,4,84,0,73],[0,0,0,0,3,99,0,73,0,0,0,1,7,48,0,140,0,0,2,65,0,0,97,61,0,0,0,1,7,96,0,140],[0,0,2,34,0,0,193,61,0,0,0,1,3,48,0,140,0,0,0,0,4,5,192,25,0,0,0,0,49,20,0,170],[0,0,0,1,3,48,192,57,0,0,0,0,66,36,0,170,0,0,0,1,4,64,192,57,0,0,0,179,82,32,0,209],[0,0,0,175,82,32,0,209,0,0,0,0,4,84,0,25,0,0,0,174,2,64,0,156,0,0,0,178,4,64,32,65],[0,0,0,179,33,16,0,209,0,0,0,175,33,16,0,209,0,0,0,0,3,35,0,25,0,0,0,174,1,48,0,156],[0,0,0,178,3,48,32,65,0,0,0,0,1,3,0,25,0,0,0,0,2,4,0,25,0,0,0,0,0,1,4,45],[0,0,0,0,84,34,0,170,0,0,0,1,5,80,192,57,0,0,0,179,100,64,0,209,0,0,0,175,100,64,0,209],[0,0,0,0,4,101,0,25,0,0,0,174,5,64,0,156,0,0,0,178,4,64,32,65,0,0,0,1,5,64,2,16],[0,0,0,2,6,64,2,16,0,0,0,174,5,80,0,156,0,0,0,185,6,96,32,65,0,0,0,0,117,51,0,170],[0,0,0,1,7,112,192,57,0,0,0,0,152,18,0,170,0,0,0,1,9,144,192,57,0,0,0,0,35,35,0,170],[0,0,0,1,2,32,192,57,0,0,0,1,1,96,2,16,0,0,0,174,6,96,0,156,0,0,0,185,1,16,32,65],[0,0,0,179,101,80,0,209,0,0,0,175,101,80,0,209,0,0,0,0,5,103,0,25,0,0,0,174,6,80,0,156],[0,0,0,178,5,80,32,65,0,0,0,0,6,5,0,75,0,0,0,186,118,80,0,209,0,0,0,1,7,112,192,57],[0,0,0,179,134,128,0,209,0,0,0,47,133,80,0,201,0,0,0,175,133,80,0,209,0,0,0,0,5,135,0,25],[0,0,0,175,118,96,0,209,0,0,0,0,6,121,0,25,0,0,0,174,7,80,0,156,0,0,0,178,5,80,32,65],[0,0,0,174,7,96,0,156,0,0,0,178,6,96,32,65,0,0,0,1,7,80,2,16,0,0,0,187,8,80,0,156],[0,0,0,178,7,112,32,65,0,0,0,0,7,87,0,25,0,0,0,174,8,112,0,156,0,0,0,178,7,112,32,65],[0,0,0,0,7,116,0,73,0,0,0,178,8,112,0,156,0,0,0,0,7,8,128,25,0,0,0,0,134,103,0,170],[0,0,0,1,8,128,192,57,0,0,0,0,4,69,0,25,0,0,0,174,9,64,0,156,0,0,0,178,4,64,32,65],[0,0,0,0,116,71,0,170,0,0,0,1,7,112,192,57,0,0,0,174,9,16,0,156,0,0,0,178,1,16,32,65],[0,0,0,0,149,21,0,170,0,0,0,1,9,144,192,57,0,0,0,179,163,48,0,209,0,0,0,175,163,48,0,209],[0,0,0,0,2,162,0,25,0,0,0,174,3,32,0,156,0,0,0,178,2,32,32,65,0,0,0,0,50,33,0,170],[0,0,0,1,3,48,192,57,0,0,0,179,97,96,0,209,0,0,0,175,97,16,0,209,0,0,0,0,6,104,0,25],[0,0,0,1,1,96,2,16,0,0,0,174,6,96,0,156,0,0,0,185,1,16,32,65,0,0,0,179,100,64,0,209],[0,0,0,179,101,80,0,209,0,0,0,179,98,32,0,209,0,0,0,175,100,64,0,209,0,0,0,0,4,103,0,25],[0,0,0,175,98,32,0,209,0,0,0,0,3,99,0,25,0,0,0,174,2,48,0,156,0,0,0,178,3,48,32,65],[0,0,0,175,82,80,0,209,0,0,0,0,2,89,0,25,0,0,0,174,5,16,0,156,0,0,0,178,1,16,32,65],[0,0,0,174,5,64,0,156,0,0,0,178,4,64,32,65,0,0,0,174,5,32,0,156,0,0,0,178,2,32,32,65],[0,0,0,0,2,36,0,25,0,0,0,174,4,32,0,156,0,0,0,178,2,32,32,65,0,0,0,0,0,1,4,45],[0,0,2,176,0,0,4,50,0,0,2,177,0,1,4,46,0,0,2,178,0,1,4,48,0,0,0,0,0,0,0,0],[0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,1,0,0,0,0,0,0,0,0,0],[48,100,78,114,225,49,160,41,184,80,69,182,129,129,88,93,151,129,106,145,104,113,202,141,60,32,140,22,216,124,253,70],[48,100,78,114,225,49,160,41,184,80,69,182,129,129,88,93,151,129,106,145,104,113,202,141,60,32,140,22,216,124,253,71],[6,216,159,113,202,184,53,31,71,171,30,255,10,65,127,246,181,231,25,17,212,69,1,251,243,44,252,91,83,138,250,137],[74,71,70,38,35,160,74,122,176,116,165,134,128,115,1,58,233,101,225,118,124,212,192,134,243,174,216,161,155,249,14,81],[207,155,177,141,30,206,95,214,71,175,186,73,126,126,167,162,104,126,149,110,151,142,53,114,195,223,115,233,39,131,2,185],[245,122,34,183,145,136,140,107,216,175,203,208,24,51,218,128,158,222,125,101,30,202,106,201,135,210,7,130,228,134,99,137],[42,31,103,68,206,23,157,142,51,75,234,78,105,107,210,132,31,106,193,122,225,85,33,185,122,23,202,169,80,173,40,215],[249,187,24,209,236,229,253,100,122,251,164,151,231,234,122,38,135,233,86,233,120,227,87,44,61,247,62,146,120,48,43,144],[6,68,231,46,19,26,2,155,133,4,91,104,24,21,133,217,120,22,169,22,135,28,168,211,194,8,193,109,135,207,212,111],[14,10,119,193,154,7,223,47,102,110,163,111,120,121,70,44,10,120,235,40,245,199,11,61,211,93,67,141,197,143,13,157],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0],[159,55,99,26,61,156,191,172,143,95,116,146,252,253,79,68,208,253,42,221,47,28,106,229,135,190,231,210,79,6,5,114],[29,149,152,232,167,227,152,87,41,67,51,126,57,64,198,209,47,61,111,77,211,27,208,17,246,6,71,206,65,13,127,247],[24,50,39,57,112,152,208,20,220,40,34,219,64,192,172,46,203,192,181,72,180,56,229,70,158,16,70,11,108,62,126,163],[23,60,161,90,105,175,158,70,46,186,112,111,230,169,254,53,96,109,166,223,91,52,118,50,129,165,209,164,255,39,6,111]],"0x0000000000000000000000000000000000008001":[[0,0,0,1,1,32,1,144,0,0,0,4,0,0,193,61,0,0,0,0,1,0,0,25,0,0,0,17,0,1,4,46],[0,0,0,128,1,0,0,57,0,0,0,64,0,16,4,63,0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75],[0,0,0,14,0,0,193,61,0,0,0,32,1,0,0,57,0,0,1,0,0,16,4,67,0,0,1,32,0,0,4,67],[0,0,0,5,1,0,0,65,0,0,0,17,0,1,4,46,0,0,0,0,1,0,0,25,0,0,0,18,0,1,4,48],[0,0,0,16,0,0,4,50,0,0,0,17,0,1,4,46,0,0,0,18,0,1,4,48,0,0,0,0,0,0,0,0],[0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,1,0,0,0,0,0,0,0,0,0],[175,66,242,103,141,4,1,110,33,198,129,151,108,128,65,227,125,97,137,230,206,140,232,80,64,84,68,121,2,83,255,78]],"0x0000000000000000000000000000000000008002":[[0,2,0,0,0,0,0,2,0,0,0,128,4,0,0,57,0,0,0,64,0,64,4,63,0,0,0,0,3,1,0,25],[0,0,0,96,3,48,2,112,0,0,0,87,3,48,1,151,0,0,0,1,2,32,1,144,0,0,0,32,0,0,193,61],[0,0,0,4,2,48,0,140,0,0,0,219,0,0,65,61,0,0,0,0,2,1,4,59,0,0,0,224,2,32,2,112],[0,0,0,89,5,32,0,156,0,0,0,40,0,0,33,61,0,0,0,93,4,32,0,156,0,0,0,128,0,0,97,61],[0,0,0,94,4,32,0,156,0,0,0,155,0,0,97,61,0,0,0,95,2,32,0,156,0,0,0,219,0,0,193,61],[0,0,0,0,2,0,4,22,0,0,0,0,2,2,0,75,0,0,0,219,0,0,193,61,0,0,0,4,2,48,0,138],[0,0,0,32,2,32,0,140,0,0,0,219,0,0,65,61,0,0,0,4,1,16,3,112,0,0,0,0,1,1,4,59],[0,0,0,97,2,16,0,156,0,0,0,219,0,0,33,61,0,0,0,0,1,1,4,26,0,0,0,178,0,0,1,61],[0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75,0,0,0,219,0,0,193,61,0,0,0,32,1,0,0,57],[0,0,1,0,0,16,4,67,0,0,1,32,0,0,4,67,0,0,0,88,1,0,0,65,0,0,1,86,0,1,4,46],[0,0,0,90,5,32,0,156,0,0,0,181,0,0,97,61,0,0,0,91,5,32,0,156,0,0,0,209,0,0,97,61],[0,0,0,92,2,32,0,156,0,0,0,219,0,0,193,61,0,0,0,0,2,0,4,22,0,0,0,0,2,2,0,75],[0,0,0,219,0,0,193,61,0,0,0,4,2,48,0,138,0,0,0,32,2,32,0,140,0,0,0,219,0,0,65,61],[0,0,0,96,3,0,0,65,0,0,0,4,1,16,3,112,0,0,0,0,1,1,4,59,0,0,0,97,1,16,1,151],[0,0,1,0,2,16,0,140,0,0,0,124,0,0,65,61,0,0,0,128,4,0,0,57,0,0,0,0,5,1,4,26],[0,0,0,0,2,5,0,75,0,0,0,120,0,0,193,61,0,2,0,0,0,5,0,29,0,0,0,98,2,0,0,65],[0,0,0,128,0,32,4,63,0,0,0,132,0,16,4,63,0,0,0,87,1,0,0,65,0,0,0,0,2,0,4,20],[0,0,0,87,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,0,99,1,16,1,199],[0,0,128,3,2,0,0,57,1,85,1,80,0,0,4,15,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112],[0,0,0,87,3,48,1,151,0,0,0,32,4,48,0,140,0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57],[0,0,0,31,5,64,1,143,0,0,0,5,6,64,2,114,0,0,0,92,0,0,97,61,0,0,0,0,7,0,0,25],[0,0,0,5,8,112,2,16,0,0,0,0,9,129,3,79,0,0,0,0,9,9,4,59,0,0,0,128,8,128,0,57],[0,0,0,0,0,152,4,53,0,0,0,1,7,112,0,57,0,0,0,0,8,103,0,75,0,0,0,84,0,0,65,61],[0,0,0,0,7,5,0,75,0,0,0,107,0,0,97,61,0,0,0,5,6,96,2,16,0,0,0,0,7,97,3,79],[0,0,0,3,5,80,2,16,0,0,0,128,6,96,0,57,0,0,0,0,8,6,4,51,0,0,0,0,8,88,1,207],[0,0,0,0,8,88,2,47,0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137,0,0,0,0,7,87,2,47],[0,0,0,0,5,87,1,207,0,0,0,0,5,133,1,159,0,0,0,0,0,86,4,53,0,0,0,1,2,32,1,144],[0,0,0,253,0,0,97,61,0,0,0,31,1,64,0,57,0,0,0,96,1,16,1,143,0,0,0,128,4,16,1,191],[0,0,0,64,0,64,4,63,0,0,0,32,1,48,0,140,0,0,0,219,0,0,65,61,0,0,0,128,1,0,4,61],[0,0,0,0,1,1,0,75,0,0,0,96,3,0,0,65,0,0,0,2,5,0,0,41,0,0,0,124,0,0,193,61],[0,0,0,100,1,80,1,151,0,0,0,96,3,0,0,65,0,0,0,101,1,16,0,156,0,0,0,0,3,5,192,25],[0,0,0,0,0,52,4,53,0,0,0,64,1,64,2,16,0,0,0,102,1,16,1,199,0,0,1,86,0,1,4,46],[0,0,0,0,2,0,4,22,0,0,0,0,2,2,0,75,0,0,0,219,0,0,193,61,0,0,0,4,2,48,0,138],[0,0,0,64,2,32,0,140,0,0,0,219,0,0,65,61,0,0,0,4,2,16,3,112,0,0,0,0,2,2,4,59],[0,0,0,97,3,32,0,156,0,0,0,219,0,0,33,61,0,0,0,36,1,16,3,112,0,0,0,0,1,1,4,59],[0,0,0,0,3,0,4,17,0,0,128,6,3,48,0,140,0,0,0,241,0,0,193,61,0,0,0,100,3,16,1,152],[0,0,0,238,0,0,97,61,0,0,0,106,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57],[0,0,0,132,0,16,4,63,0,0,0,43,1,0,0,57,0,0,0,164,0,16,4,63,0,0,0,110,1,0,0,65],[0,0,0,196,0,16,4,63,0,0,0,111,1,0,0,65,0,0,0,250,0,0,1,61,0,0,0,0,2,0,4,22],[0,0,0,0,2,2,0,75,0,0,0,219,0,0,193,61,0,0,0,4,2,48,0,138,0,0,0,32,2,32,0,140],[0,0,0,219,0,0,65,61,0,0,0,4,1,16,3,112,0,0,0,0,1,1,4,59,0,0,0,97,1,16,1,151],[0,0,1,0,2,16,0,140,0,0,0,0,2,0,0,25,0,0,0,1,2,0,64,57,0,0,0,0,1,1,4,26],[0,0,0,0,3,1,0,75,0,0,0,1,2,32,97,191,0,0,0,100,3,16,1,151,0,0,0,101,3,48,0,156],[0,0,0,0,3,0,0,25,0,0,0,1,3,0,96,57,0,0,0,0,2,50,1,160,0,0,0,219,1,16,2,112],[0,0,0,105,1,16,1,151,0,0,0,0,1,0,192,25,0,0,0,128,0,16,4,63,0,0,0,104,1,0,0,65],[0,0,1,86,0,1,4,46,0,0,0,0,2,0,4,22,0,0,0,0,2,2,0,75,0,0,0,219,0,0,193,61],[0,0,0,4,2,48,0,138,0,0,0,64,2,32,0,140,0,0,0,219,0,0,65,61,0,0,0,4,2,16,3,112],[0,0,0,0,3,2,4,59,0,0,0,97,2,48,0,156,0,0,0,219,0,0,33,61,0,0,0,36,1,16,3,112],[0,0,0,0,1,1,4,59,0,2,0,0,0,1,0,29,0,0,0,0,1,0,4,17,0,0,128,6,1,16,0,140],[0,0,0,0,1,0,0,25,0,0,0,1,1,0,96,57,0,1,0,0,0,3,0,29,1,85,1,32,0,0,4,15],[0,0,0,2,1,0,0,41,0,0,0,100,1,16,1,151,0,0,0,101,1,16,0,156,0,0,0,0,1,0,0,25],[0,0,0,1,1,0,96,57,1,85,1,56,0,0,4,15,0,0,0,2,1,0,0,41,0,0,0,1,2,0,0,41],[0,0,0,238,0,0,1,61,0,0,0,0,2,0,4,22,0,0,0,0,2,2,0,75,0,0,0,219,0,0,193,61],[0,0,0,4,2,48,0,138,0,0,0,32,2,32,0,140,0,0,0,219,0,0,65,61,0,0,0,4,1,16,3,112],[0,0,0,0,2,1,4,59,0,0,0,97,1,32,0,156,0,0,0,221,0,0,161,61,0,0,0,0,1,0,0,25],[0,0,1,87,0,1,4,48,0,0,0,0,1,0,4,17,0,0,128,6,1,16,0,140,0,0,0,0,1,0,0,25],[0,0,0,1,1,0,96,57,0,2,0,0,0,2,0,29,1,85,1,32,0,0,4,15,0,0,0,2,1,0,0,41],[0,0,0,0,1,1,4,26,0,1,0,0,0,1,0,29,0,0,0,100,1,16,1,151,0,0,0,101,1,16,0,156],[0,0,0,0,1,0,0,25,0,0,0,1,1,0,96,57,1,85,1,56,0,0,4,15,0,0,0,1,1,0,0,41],[0,0,0,103,1,16,1,151,0,0,0,2,2,0,0,41,0,0,0,0,0,18,4,27,0,0,0,0,1,0,0,25],[0,0,1,86,0,1,4,46,0,0,0,106,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57],[0,0,0,132,0,16,4,63,0,0,0,45,1,0,0,57,0,0,0,164,0,16,4,63,0,0,0,107,1,0,0,65],[0,0,0,196,0,16,4,63,0,0,0,108,1,0,0,65,0,0,0,228,0,16,4,63,0,0,0,109,1,0,0,65],[0,0,1,87,0,1,4,48,0,0,0,64,2,0,4,61,0,0,0,31,4,48,1,143,0,0,0,5,5,48,2,114],[0,0,1,10,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25],[0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57],[0,0,0,0,7,86,0,75,0,0,1,2,0,0,65,61,0,0,0,0,6,4,0,75,0,0,1,25,0,0,97,61],[0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16],[0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59],[0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159],[0,0,0,0,0,21,4,53,0,0,0,87,1,0,0,65,0,0,0,87,4,32,0,156,0,0,0,0,2,1,128,25],[0,0,0,64,1,32,2,16,0,0,0,96,2,48,2,16,0,0,0,0,1,33,1,159,0,0,1,87,0,1,4,48],[0,0,0,0,1,1,0,75,0,0,1,35,0,0,97,61,0,0,0,0,0,1,4,45,0,0,0,64,1,0,4,61],[0,0,0,100,2,16,0,57,0,0,0,108,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,68,2,16,0,57],[0,0,0,107,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,45,3,0,0,57],[0,0,0,0,0,50,4,53,0,0,0,106,2,0,0,65,0,0,0,0,0,33,4,53,0,0,0,4,2,16,0,57],[0,0,0,32,3,0,0,57,0,0,0,0,0,50,4,53,0,0,0,87,2,0,0,65,0,0,0,87,3,16,0,156],[0,0,0,0,1,2,128,25,0,0,0,64,1,16,2,16,0,0,0,112,1,16,1,199,0,0,1,87,0,1,4,48],[0,0,0,0,1,1,0,75,0,0,1,59,0,0,97,61,0,0,0,0,0,1,4,45,0,0,0,64,1,0,4,61],[0,0,0,100,2,16,0,57,0,0,0,113,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,68,2,16,0,57],[0,0,0,114,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,46,3,0,0,57],[0,0,0,0,0,50,4,53,0,0,0,106,2,0,0,65,0,0,0,0,0,33,4,53,0,0,0,4,2,16,0,57],[0,0,0,32,3,0,0,57,0,0,0,0,0,50,4,53,0,0,0,87,2,0,0,65,0,0,0,87,3,16,0,156],[0,0,0,0,1,2,128,25,0,0,0,64,1,16,2,16,0,0,0,112,1,16,1,199,0,0,1,87,0,1,4,48],[0,0,1,83,0,33,4,35,0,0,0,1,2,0,0,57,0,0,0,0,0,1,4,45,0,0,0,0,2,0,0,25],[0,0,0,0,0,1,4,45,0,0,1,85,0,0,4,50,0,0,1,86,0,1,4,46,0,0,1,87,0,1,4,48],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255],[0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,1,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,79,30,27,223],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,79,30,27,224],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,194,228,255,151],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,224,63,225,119],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,13,70,81,170],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,6,170,24],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,77,226,228,104],[197,210,70,1,134,247,35,60,146,126,125,178,220,199,3,192,229,0,182,83,202,130,39,59,123,250,216,4,93,133,164,112],[0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],[90,169,182,181,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,0,0,0,128,0,0,0,0,0,0,0,0],[0,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0],[255,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,128,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,255,224],[8,195,121,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[67,97,108,108,97,98,108,101,32,111,110,108,121,32,98,121,32,116,104,101,32,100,101,112,108,111,121,101,114,32,115,121],[115,116,101,109,32,99,111,110,116,114,97,99,116,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,0,0,0,128,0,0,0,0,0,0,0,0],[67,111,100,101,32,104,97,115,104,32,105,115,32,110,111,116,32,102,111,114,32,97,32,99,111,110,115,116,114,117,99,116],[101,100,32,99,111,110,116,114,97,99,116,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,0,0,0,0,0,0,0,0,0,0,0,0],[111,110,32,99,111,110,115,116,114,117,99,116,111,114,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[67,111,100,101,32,104,97,115,104,32,105,115,32,110,111,116,32,102,111,114,32,97,32,99,111,110,116,114,97,99,116,32],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[82,196,187,126,10,190,153,114,73,167,8,60,46,101,7,88,142,193,49,235,112,99,230,237,86,241,15,160,122,8,120,133]],"0x0000000000000000000000000000000000008003":[[0,1,0,0,0,0,0,2,0,5,0,0,0,0,0,2,0,0,0,0,6,1,3,79,0,0,0,0,0,6,3,85],[0,0,0,128,1,0,0,57,0,0,0,64,0,16,4,63,0,0,0,0,1,6,0,25,0,0,0,96,1,16,2,112],[0,0,0,187,1,16,1,151,0,0,0,1,3,32,1,144,0,0,0,38,0,0,193,61,0,0,0,4,3,16,0,140],[0,0,2,107,0,0,65,61,0,0,0,0,3,6,4,59,0,0,0,224,3,48,2,112,0,0,0,189,4,48,0,156],[0,0,0,46,0,0,33,61,0,0,0,196,4,48,0,156,0,0,0,71,0,0,161,61,0,0,0,197,4,48,0,156],[0,0,1,0,0,0,97,61,0,0,0,198,2,48,0,156,0,0,1,25,0,0,97,61,0,0,0,199,2,48,0,156],[0,0,2,107,0,0,193,61,0,0,0,0,2,0,4,22,0,0,0,0,2,2,0,75,0,0,2,107,0,0,193,61],[0,0,0,4,1,16,0,138,0,0,0,32,1,16,0,140,0,0,2,107,0,0,65,61,0,0,0,4,1,96,3,112],[0,0,0,0,1,1,4,59,0,0,0,202,2,16,0,156,0,0,2,107,0,0,33,61,0,0,0,0,0,16,4,53],[0,0,0,32,0,0,4,63,0,0,1,43,0,0,1,61,0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75],[0,0,2,107,0,0,193,61,0,0,0,32,1,0,0,57,0,0,1,0,0,16,4,67,0,0,1,32,0,0,4,67],[0,0,0,188,1,0,0,65,0,0,2,231,0,1,4,46,0,0,0,190,4,48,0,156,0,0,0,99,0,0,161,61],[0,0,0,191,4,48,0,156,0,0,1,49,0,0,97,61,0,0,0,192,4,48,0,156,0,0,1,66,0,0,97,61],[0,0,0,193,2,48,0,156,0,0,2,107,0,0,193,61,0,0,0,0,2,0,4,22,0,0,0,0,2,2,0,75],[0,0,2,107,0,0,193,61,0,0,0,4,1,16,0,138,0,0,0,32,1,16,0,140,0,0,2,107,0,0,65,61],[0,0,0,4,1,96,3,112,0,0,0,0,1,1,4,59,0,0,0,202,2,16,0,156,0,0,2,107,0,0,33,61],[0,0,0,0,0,16,4,53,0,0,0,32,0,0,4,63,0,0,0,0,1,0,0,25,2,230,2,202,0,0,4,15],[0,0,0,0,1,1,4,26,0,0,0,128,1,16,2,112,0,0,1,46,0,0,1,61,0,0,0,200,4,48,0,156],[0,0,0,115,0,0,97,61,0,0,0,201,2,48,0,156,0,0,2,107,0,0,193,61,0,0,0,0,2,0,4,22],[0,0,0,0,2,2,0,75,0,0,2,107,0,0,193,61,0,0,0,4,1,16,0,138,0,0,0,32,1,16,0,140],[0,0,2,107,0,0,65,61,0,0,0,4,1,96,3,112,0,0,0,0,1,1,4,59,0,0,0,202,2,16,0,156],[0,0,2,107,0,0,33,61,0,0,0,0,2,0,4,17,0,0,128,6,2,32,0,140,0,0,1,178,0,0,193,61],[0,5,0,0,0,1,0,29,2,230,2,109,0,0,4,15,0,0,0,0,1,1,4,26,0,4,0,0,0,1,0,29],[0,0,0,5,1,0,0,41,2,230,2,109,0,0,4,15,0,0,0,4,3,0,0,41,0,0,0,218,2,48,0,65],[0,0,0,0,0,33,4,27,0,0,0,128,1,48,2,112,0,0,1,135,0,0,1,61,0,0,0,194,2,48,0,156],[0,0,0,207,0,0,97,61,0,0,0,195,2,48,0,156,0,0,2,107,0,0,193,61,0,0,0,0,2,0,4,22],[0,0,0,0,2,2,0,75,0,0,2,107,0,0,193,61,0,0,0,4,1,16,0,138,0,0,0,32,1,16,0,140],[0,0,2,107,0,0,65,61,0,0,0,4,1,96,3,112,0,0,0,0,1,1,4,59,0,0,0,202,2,16,0,156],[0,0,2,107,0,0,33,61,2,230,2,125,0,0,4,15,0,0,1,135,0,0,1,61,0,0,0,0,3,0,4,22],[0,0,0,0,3,3,0,75,0,0,2,107,0,0,193,61,0,0,0,4,1,16,0,138,0,0,0,64,1,16,0,140],[0,0,2,107,0,0,65,61,0,0,0,0,3,0,4,17,0,0,0,36,1,96,3,112,0,0,0,0,5,1,4,59],[0,0,0,4,1,96,3,112,0,0,0,0,4,1,4,59,0,0,0,2,1,32,1,144,0,0,0,130,0,0,193,61],[0,0,0,219,1,48,0,156,0,0,1,77,0,0,129,61,0,5,0,0,0,5,0,29,0,4,0,0,0,4,0,29],[0,0,0,220,1,0,0,65,0,0,0,128,0,16,4,63,0,3,0,0,0,3,0,29,0,0,0,202,1,48,1,151],[0,2,0,0,0,1,0,29,0,0,0,132,0,16,4,63,0,0,0,187,1,0,0,65,0,0,0,0,2,0,4,20],[0,0,0,187,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,0,221,1,16,1,199],[0,0,128,6,2,0,0,57,2,230,2,225,0,0,4,15,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112],[0,0,0,187,3,48,1,151,0,0,0,64,4,48,0,140,0,0,0,0,4,3,0,25,0,0,0,64,4,0,128,57],[0,0,0,31,5,64,1,143,0,0,0,5,6,64,2,114,0,0,0,164,0,0,97,61,0,0,0,0,7,0,0,25],[0,0,0,5,8,112,2,16,0,0,0,0,9,129,3,79,0,0,0,0,9,9,4,59,0,0,0,128,8,128,0,57],[0,0,0,0,0,152,4,53,0,0,0,1,7,112,0,57,0,0,0,0,8,103,0,75,0,0,0,156,0,0,65,61],[0,0,0,0,7,5,0,75,0,0,0,179,0,0,97,61,0,0,0,5,6,96,2,16,0,0,0,0,7,97,3,79],[0,0,0,3,5,80,2,16,0,0,0,128,6,96,0,57,0,0,0,0,8,6,4,51,0,0,0,0,8,88,1,207],[0,0,0,0,8,88,2,47,0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137,0,0,0,0,7,87,2,47],[0,0,0,0,5,87,1,207,0,0,0,0,5,133,1,159,0,0,0,0,0,86,4,53,0,0,0,1,2,32,1,144],[0,0,1,143,0,0,97,61,0,0,0,31,1,64,0,57,0,0,0,224,1,16,1,143,0,0,0,128,2,16,0,57],[0,0,0,64,0,32,4,63,0,0,0,64,3,48,0,140,0,0,2,107,0,0,65,61,0,0,0,192,3,16,0,57],[0,0,0,64,0,48,4,63,0,0,0,128,3,0,4,61,0,0,0,1,4,48,0,140,0,0,2,107,0,0,33,61],[0,0,0,0,0,50,4,53,0,0,0,160,2,0,4,61,0,0,0,1,3,32,0,140,0,0,2,107,0,0,33,61],[0,0,0,160,1,16,0,57,0,0,0,0,0,33,4,53,0,0,0,5,1,0,0,107,0,0,1,245,0,0,193,61],[0,0,0,64,1,0,4,61,0,0,0,68,2,16,0,57,0,0,0,225,3,0,0,65,0,0,0,0,0,50,4,53],[0,0,0,36,2,16,0,57,0,0,0,30,3,0,0,57,0,0,1,194,0,0,1,61,0,0,0,0,2,0,4,22],[0,0,0,0,2,2,0,75,0,0,2,107,0,0,193,61,0,0,0,4,1,16,0,138,0,0,0,96,1,16,0,140],[0,0,2,107,0,0,65,61,0,0,0,4,1,96,3,112,0,0,0,0,3,1,4,59,0,0,0,202,1,48,0,156],[0,0,2,107,0,0,33,61,0,0,0,68,1,96,3,112,0,0,0,0,2,1,4,59,0,0,0,0,1,2,0,75],[0,0,0,0,1,0,0,25,0,0,0,1,1,0,192,57,0,5,0,0,0,2,0,29,0,0,0,0,1,18,0,75],[0,0,2,107,0,0,193,61,0,0,0,36,1,96,3,112,0,0,0,0,1,1,4,59,0,3,0,0,0,1,0,29],[0,0,0,0,0,48,4,53,0,0,0,32,0,0,4,63,0,0,0,187,1,0,0,65,0,0,0,0,2,0,4,20],[0,4,0,0,0,3,0,29,0,0,0,187,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16],[0,0,0,204,1,16,1,199,0,0,128,16,2,0,0,57,2,230,2,225,0,0,4,15,0,0,0,4,3,0,0,41],[0,0,0,1,2,32,1,144,0,0,2,107,0,0,97,61,0,0,0,0,1,1,4,59,0,0,0,0,1,1,4,26],[0,0,0,205,1,16,1,151,0,0,0,3,1,16,0,108,0,0,1,206,0,0,161,61,0,0,0,5,1,0,0,107],[0,0,2,63,0,0,193,61,0,0,0,64,1,0,4,61,0,0,0,68,2,16,0,57,0,0,0,211,3,0,0,65],[0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,28,3,0,0,57,0,0,1,194,0,0,1,61],[0,0,0,0,3,0,4,22,0,0,0,0,3,3,0,75,0,0,2,107,0,0,193,61,0,0,0,4,1,16,0,138],[0,0,0,32,1,16,0,140,0,0,2,107,0,0,65,61,0,0,0,4,1,96,3,112,0,0,0,0,3,1,4,59],[0,0,0,2,1,32,1,144,0,0,1,13,0,0,193,61,0,0,0,0,1,0,4,17,0,0,255,255,1,16,0,140],[0,0,1,77,0,0,33,61,0,0,0,212,1,48,0,156,0,0,1,120,0,0,65,61,0,0,0,207,1,0,0,65],[0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63,0,0,0,48,1,0,0,57],[0,0,0,164,0,16,4,63,0,0,0,213,1,0,0,65,0,0,0,196,0,16,4,63,0,0,0,214,1,0,0,65],[0,0,1,86,0,0,1,61,0,0,0,0,2,0,4,22,0,0,0,0,2,2,0,75,0,0,2,107,0,0,193,61],[0,0,0,4,1,16,0,138,0,0,0,32,1,16,0,140,0,0,2,107,0,0,65,61,0,0,0,0,1,0,4,17],[0,0,0,0,0,16,4,53,0,0,0,1,1,0,0,57,0,0,0,32,0,16,4,63,0,0,0,0,1,0,0,25],[0,5,0,0,0,6,3,83,2,230,2,202,0,0,4,15,0,0,0,5,2,0,3,95,0,0,0,4,2,32,3,112],[0,0,0,0,2,2,4,59,0,0,0,0,0,32,4,53,0,0,0,32,0,16,4,63,0,0,0,0,1,0,0,25],[2,230,2,202,0,0,4,15,0,0,0,0,1,1,4,26,0,0,0,128,0,16,4,63,0,0,0,203,1,0,0,65],[0,0,2,231,0,1,4,46,0,0,0,0,2,0,4,22,0,0,0,0,2,2,0,75,0,0,2,107,0,0,193,61],[0,0,0,4,1,16,0,138,0,0,0,64,1,16,0,140,0,0,2,107,0,0,65,61,0,0,0,4,1,96,3,112],[0,0,0,0,1,1,4,59,0,0,0,202,2,16,0,156,0,0,2,107,0,0,33,61,0,0,0,36,2,96,3,112],[0,0,0,0,2,2,4,59,2,230,2,144,0,0,4,15,0,0,0,0,1,1,0,75,0,0,0,0,1,0,0,25],[0,0,0,1,1,0,192,57,0,0,1,135,0,0,1,61,0,0,0,0,3,0,4,22,0,0,0,0,3,3,0,75],[0,0,2,107,0,0,193,61,0,0,0,4,1,16,0,138,0,0,0,32,1,16,0,140,0,0,2,107,0,0,65,61],[0,0,0,0,3,0,4,17,0,0,0,2,1,32,1,144,0,0,1,89,0,0,193,61,0,0,255,255,1,48,0,140],[0,0,1,89,0,0,161,61,0,0,0,207,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57],[0,0,0,132,0,16,4,63,0,0,0,36,1,0,0,57,0,0,0,164,0,16,4,63,0,0,0,226,1,0,0,65],[0,0,0,196,0,16,4,63,0,0,0,227,1,0,0,65,0,0,0,228,0,16,4,63,0,0,0,215,1,0,0,65],[0,0,2,232,0,1,4,48,0,5,0,0,0,3,0,29,0,0,0,0,0,48,4,53,0,0,0,32,0,0,4,63],[0,0,0,187,1,0,0,65,0,0,0,0,2,0,4,20,0,0,0,187,3,32,0,156,0,0,0,0,2,1,128,25],[0,0,0,192,1,32,2,16,0,0,0,204,1,16,1,199,0,0,128,16,2,0,0,57,2,230,2,225,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,2,107,0,0,97,61,0,0,0,4,2,0,0,57,0,0,0,0,2,32,3,103],[0,0,0,0,2,2,4,59,0,0,0,0,1,1,4,59,0,0,0,0,1,1,4,26,0,0,0,205,3,16,1,151],[0,0,0,0,2,35,0,75,0,0,1,188,0,0,193,61,0,0,0,5,2,0,0,41,0,0,0,0,0,32,4,53],[0,0,0,32,0,0,4,63,0,5,0,1,0,16,0,61,0,0,0,0,1,0,0,25,2,230,2,202,0,0,4,15],[0,0,0,5,2,0,0,41,0,0,0,0,0,33,4,27,0,0,0,0,1,0,0,25,0,0,2,231,0,1,4,46],[0,0,0,0,1,0,4,17,0,4,0,0,0,1,0,29,0,0,0,0,0,16,4,53,0,0,0,32,0,0,4,63],[0,0,0,0,1,0,0,25,0,5,0,0,0,3,0,29,2,230,2,202,0,0,4,15,0,0,0,0,1,1,4,26],[0,3,0,0,0,1,0,29,0,0,0,4,1,0,0,41,2,230,2,109,0,0,4,15,0,0,0,3,3,0,0,41],[0,0,0,5,2,48,0,41,0,0,0,0,0,33,4,27,0,0,0,205,1,48,1,151,0,0,0,64,2,0,4,61],[0,0,0,0,0,18,4,53,0,0,0,187,1,0,0,65,0,0,0,187,3,32,0,156,0,0,0,0,2,1,128,25],[0,0,0,64,1,32,2,16,0,0,0,209,1,16,1,199,0,0,2,231,0,1,4,46,0,0,0,64,2,0,4,61],[0,0,0,31,4,48,1,143,0,0,0,5,5,48,2,114,0,0,1,156,0,0,97,61,0,0,0,0,6,0,0,25],[0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59],[0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,1,148,0,0,65,61],[0,0,0,0,6,4,0,75,0,0,1,171,0,0,97,61,0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79],[0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207],[0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47],[0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,0,187,1,0,0,65],[0,0,0,187,4,32,0,156,0,0,0,0,2,1,128,25,0,0,0,64,1,32,2,16,0,0,0,96,2,48,2,16],[0,0,0,0,1,33,1,159,0,0,2,232,0,1,4,48,0,0,0,207,1,0,0,65,0,0,0,128,0,16,4,63],[0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63,0,0,0,61,1,0,0,57,0,0,0,164,0,16,4,63],[0,0,0,216,1,0,0,65,0,0,0,196,0,16,4,63,0,0,0,217,1,0,0,65,0,0,1,86,0,0,1,61],[0,0,0,64,1,0,4,61,0,0,0,68,2,16,0,57,0,0,0,206,3,0,0,65,0,0,0,0,0,50,4,53],[0,0,0,36,2,16,0,57,0,0,0,15,3,0,0,57,0,0,0,0,0,50,4,53,0,0,0,207,2,0,0,65],[0,0,0,0,0,33,4,53,0,0,0,4,2,16,0,57,0,0,0,32,3,0,0,57,0,0,0,0,0,50,4,53],[0,0,0,187,2,0,0,65,0,0,0,187,3,16,0,156,0,0,0,0,1,2,128,25,0,0,0,64,1,16,2,16],[0,0,0,208,1,16,1,199,0,0,2,232,0,1,4,48,0,0,0,0,0,48,4,53,0,0,0,1,1,0,0,57],[0,0,0,32,0,16,4,63,0,0,0,187,3,0,0,65,0,0,0,0,1,0,4,20,0,0,0,187,2,16,0,156],[0,0,0,0,1,3,128,25,0,0,0,192,1,16,2,16,0,0,0,204,1,16,1,199,0,0,128,16,2,0,0,57],[2,230,2,225,0,0,4,15,0,0,0,1,2,32,1,144,0,0,2,107,0,0,97,61,0,0,0,0,1,1,4,59],[0,0,0,3,2,0,0,41,0,0,0,0,0,32,4,53,0,0,0,32,0,16,4,63,0,0,0,0,1,0,4,20],[0,0,0,187,2,16,0,156,0,0,0,187,1,0,128,65,0,0,0,192,1,16,2,16,0,0,0,204,1,16,1,199],[0,0,128,16,2,0,0,57,2,230,2,225,0,0,4,15,0,0,0,1,2,32,1,144,0,0,2,107,0,0,97,61],[0,0,0,0,1,1,4,59,0,0,0,0,1,1,4,26,0,0,0,0,1,1,0,75,0,0,0,247,0,0,193,61],[0,0,0,5,1,0,0,107,0,0,2,63,0,0,97,61,0,0,0,64,1,0,4,61,0,0,0,68,2,16,0,57],[0,0,0,210,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,29,3,0,0,57],[0,0,1,194,0,0,1,61,0,0,0,0,1,2,0,75,0,0,2,13,0,0,193,61,0,0,0,4,1,0,0,107],[0,0,2,13,0,0,97,61,0,0,0,2,1,0,0,41,0,0,0,0,0,16,4,53,0,0,0,32,0,0,4,63],[0,0,0,187,1,0,0,65,0,0,0,0,2,0,4,20,0,0,0,187,3,32,0,156,0,0,0,0,2,1,128,25],[0,0,0,192,1,32,2,16,0,0,0,204,1,16,1,199,0,0,128,16,2,0,0,57,2,230,2,225,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,2,107,0,0,97,61,0,0,0,4,2,0,0,41,0,1,0,1,0,32,0,146],[0,0,0,0,1,1,4,59,0,0,0,0,1,1,4,26,0,0,0,205,1,16,1,151,0,0,0,1,1,16,0,108],[0,0,2,65,0,0,161,61,0,0,0,3,1,0,0,41,0,0,0,0,0,16,4,53,0,0,0,1,1,0,0,57],[0,0,0,32,0,16,4,63,0,0,0,187,3,0,0,65,0,0,0,0,1,0,4,20,0,0,0,187,2,16,0,156],[0,0,0,0,1,3,128,25,0,0,0,192,1,16,2,16,0,0,0,204,1,16,1,199,0,0,128,16,2,0,0,57],[2,230,2,225,0,0,4,15,0,0,0,1,2,32,1,144,0,0,2,107,0,0,97,61,0,0,0,0,1,1,4,59],[0,0,0,4,2,0,0,41,0,0,0,0,0,32,4,53,0,0,0,32,0,16,4,63,0,0,0,0,1,0,4,20],[0,0,0,187,2,16,0,156,0,0,0,187,1,0,128,65,0,0,0,192,1,16,2,16,0,0,0,204,1,16,1,199],[0,0,128,16,2,0,0,57,2,230,2,225,0,0,4,15,0,0,0,1,2,32,1,144,0,0,2,107,0,0,97,61],[0,0,0,0,1,1,4,59,0,0,0,5,2,0,0,41,0,0,0,0,0,33,4,27,0,0,0,64,1,0,4,61],[0,0,0,0,0,33,4,53,0,0,0,187,2,0,0,65,0,0,0,0,3,0,4,20,0,0,0,187,4,48,0,156],[0,0,0,0,3,2,128,25,0,0,0,187,4,16,0,156,0,0,0,0,1,2,128,25,0,0,0,64,1,16,2,16],[0,0,0,192,2,48,2,16,0,0,0,0,1,18,1,159,0,0,0,223,1,16,1,199,0,0,128,13,2,0,0,57],[0,0,0,3,3,0,0,57,0,0,0,224,4,0,0,65,0,0,0,3,5,0,0,41,0,0,0,4,6,0,0,41],[2,230,2,220,0,0,4,15,0,0,0,1,1,32,1,144,0,0,2,107,0,0,97,61,0,0,0,0,1,0,0,25],[0,0,2,231,0,1,4,46,0,0,0,2,1,0,0,41,0,0,0,0,0,16,4,53,0,0,0,1,1,0,0,57],[0,0,0,32,0,16,4,63,0,0,0,187,3,0,0,65,0,0,0,0,1,0,4,20,0,0,0,187,2,16,0,156],[0,0,0,0,1,3,128,25,0,0,0,192,1,16,2,16,0,0,0,204,1,16,1,199,0,0,128,16,2,0,0,57],[2,230,2,225,0,0,4,15,0,0,0,1,2,32,1,144,0,0,2,107,0,0,97,61,0,0,0,0,1,1,4,59],[0,0,0,1,2,0,0,41,0,0,0,0,0,32,4,53,0,0,0,32,0,16,4,63,0,0,0,0,1,0,4,20],[0,0,0,187,2,16,0,156,0,0,0,187,1,0,128,65,0,0,0,192,1,16,2,16,0,0,0,204,1,16,1,199],[0,0,128,16,2,0,0,57,2,230,2,225,0,0,4,15,0,0,0,1,2,32,1,144,0,0,2,107,0,0,97,61],[0,0,0,0,1,1,4,59,0,0,0,0,1,1,4,26,0,0,0,0,1,1,0,75,0,0,2,13,0,0,193,61],[0,0,0,64,1,0,4,61,0,0,0,68,2,16,0,57,0,0,0,222,3,0,0,65,0,0,0,0,0,50,4,53],[0,0,0,207,2,0,0,65,0,0,0,0,0,33,4,53,0,0,0,36,2,16,0,57,0,0,0,32,3,0,0,57],[0,0,0,0,0,50,4,53,0,0,0,4,2,16,0,57,0,0,1,199,0,0,1,61,0,0,0,0,1,0,0,25],[0,0,2,232,0,1,4,48,0,0,0,0,0,16,4,53,0,0,0,32,0,0,4,63,0,0,0,187,1,0,0,65],[0,0,0,0,2,0,4,20,0,0,0,187,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16],[0,0,0,204,1,16,1,199,0,0,128,16,2,0,0,57,2,230,2,225,0,0,4,15,0,0,0,1,2,32,1,144],[0,0,2,123,0,0,97,61,0,0,0,0,1,1,4,59,0,0,0,0,0,1,4,45,0,0,0,0,1,0,0,25],[0,0,2,232,0,1,4,48,0,0,0,202,1,16,1,151,0,0,0,0,0,16,4,53,0,0,0,32,0,0,4,63],[0,0,0,187,1,0,0,65,0,0,0,0,2,0,4,20,0,0,0,187,3,32,0,156,0,0,0,0,2,1,128,25],[0,0,0,192,1,32,2,16,0,0,0,204,1,16,1,199,0,0,128,16,2,0,0,57,2,230,2,225,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,2,142,0,0,97,61,0,0,0,0,1,1,4,59,0,0,0,0,1,1,4,26],[0,0,0,205,1,16,1,151,0,0,0,0,0,1,4,45,0,0,0,0,1,0,0,25,0,0,2,232,0,1,4,48],[0,2,0,0,0,0,0,2,0,2,0,0,0,2,0,29,0,0,0,202,1,16,1,151,0,1,0,0,0,1,0,29],[0,0,0,0,0,16,4,53,0,0,0,32,0,0,4,63,0,0,0,187,1,0,0,65,0,0,0,0,2,0,4,20],[0,0,0,187,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,0,204,1,16,1,199],[0,0,128,16,2,0,0,57,2,230,2,225,0,0,4,15,0,0,0,1,2,32,1,144,0,0,2,200,0,0,97,61],[0,0,0,1,2,0,0,57,0,0,0,0,1,1,4,59,0,0,0,0,1,1,4,26,0,0,0,205,1,16,1,151],[0,0,0,2,1,16,0,108,0,0,2,198,0,0,33,61,0,0,0,1,1,0,0,41,0,0,0,0,0,16,4,53],[0,0,0,1,1,0,0,57,0,0,0,32,0,16,4,63,0,0,0,187,4,0,0,65,0,0,0,0,1,0,4,20],[0,0,0,187,2,16,0,156,0,0,0,0,1,4,128,25,0,0,0,192,1,16,2,16,0,0,0,204,1,16,1,199],[0,0,128,16,2,0,0,57,2,230,2,225,0,0,4,15,0,0,0,1,2,32,1,144,0,0,2,200,0,0,97,61],[0,0,0,0,1,1,4,59,0,0,0,2,2,0,0,41,0,0,0,0,0,32,4,53,0,0,0,32,0,16,4,63],[0,0,0,0,1,0,4,20,0,0,0,187,2,16,0,156,0,0,0,187,1,0,128,65,0,0,0,192,1,16,2,16],[0,0,0,204,1,16,1,199,0,0,128,16,2,0,0,57,2,230,2,225,0,0,4,15,0,0,0,1,2,32,1,144],[0,0,2,200,0,0,97,61,0,0,0,0,1,1,4,59,0,0,0,0,1,1,4,26,0,0,0,0,1,1,0,75],[0,0,0,0,2,0,0,25,0,0,0,1,2,0,192,57,0,0,0,1,1,32,1,143,0,0,0,0,0,1,4,45],[0,0,0,0,1,0,0,25,0,0,2,232,0,1,4,48,0,0,0,187,2,0,0,65,0,0,0,187,3,16,0,156],[0,0,0,0,1,2,128,25,0,0,0,0,3,0,4,20,0,0,0,187,4,48,0,156,0,0,0,0,3,2,128,25],[0,0,0,192,2,48,2,16,0,0,0,64,1,16,2,16,0,0,0,0,1,33,1,159,0,0,0,204,1,16,1,199],[0,0,128,16,2,0,0,57,2,230,2,225,0,0,4,15,0,0,0,1,2,32,1,144,0,0,2,218,0,0,97,61],[0,0,0,0,1,1,4,59,0,0,0,0,0,1,4,45,0,0,0,0,1,0,0,25,0,0,2,232,0,1,4,48],[0,0,2,223,0,33,4,33,0,0,0,1,2,0,0,57,0,0,0,0,0,1,4,45,0,0,0,0,2,0,0,25],[0,0,0,0,0,1,4,45,0,0,2,228,0,33,4,35,0,0,0,1,2,0,0,57,0,0,0,0,0,1,4,45],[0,0,0,0,2,0,0,25,0,0,0,0,0,1,4,45,0,0,2,230,0,0,4,50,0,0,2,231,0,1,4,46],[0,0,2,232,0,1,4,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255],[0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,1,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,110,225,220,31],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,202,183,232,234],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,202,183,232,235],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,225,35,156,216],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,251,26,154,87],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,110,225,220,32],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,137,105,9,220],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,56,167,128,145],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,56,167,128,146],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,85,211,93,24],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,90,169,182,181],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,21,95,210,122],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,48,99,149,198],[0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,128,0,0,0,0,0,0,0,0],[2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],[73,110,99,111,114,114,101,99,116,32,110,111,110,99,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[8,195,121,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0],[84,104,101,32,110,111,110,99,101,32,119,97,115,32,110,111,116,32,115,101,116,32,97,115,32,117,115,101,100,0,0,0],[82,101,117,115,105,110,103,32,116,104,101,32,115,97,109,101,32,110,111,110,99,101,32,116,119,105,99,101,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1],[84,104,101,32,118,97,108,117,101,32,102,111,114,32,105,110,99,114,101,109,101,110,116,105,110,103,32,116,104,101,32,110],[111,110,99,101,32,105,115,32,116,111,111,32,104,105,103,104,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,0,0,0,128,0,0,0,0,0,0,0,0],[79,110,108,121,32,116,104,101,32,99,111,110,116,114,97,99,116,32,100,101,112,108,111,121,101,114,32,99,97,110,32,105],[110,99,114,101,109,101,110,116,32,116,104,101,32,100,101,112,108,111,121,109,101,110,116,32,110,111,110,99,101,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0],[123,81,15,232,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,0,0,0,128,0,0,0,0,0,0,0,0],[80,114,101,118,105,111,117,115,32,110,111,110,99,101,32,104,97,115,32,110,111,116,32,98,101,101,110,32,117,115,101,100],[2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0],[218,43,113,110,90,93,95,96,43,154,88,66,188,216,156,33,91,18,82,88,223,234,39,26,3,229,224,232,1,217,58,140],[78,111,110,99,101,32,118,97,108,117,101,32,99,97,110,110,111,116,32,98,101,32,115,101,116,32,116,111,32,48,0,0],[84,104,105,115,32,109,101,116,104,111,100,32,114,101,113,117,105,114,101,32,115,121,115,116,101,109,32,99,97,108,108,32],[102,108,97,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[238,152,20,73,192,75,47,189,183,87,11,76,164,100,204,154,164,103,88,254,46,21,212,154,172,49,16,103,0,70,176,79]],"0x0000000000000000000000000000000000008004":[[0,1,0,0,0,0,0,2,0,8,0,0,0,0,0,2,0,0,0,0,0,1,3,85,0,0,0,128,3,0,0,57],[0,0,0,64,0,48,4,63,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,0,95,3,48,1,151],[0,0,0,1,2,32,1,144,0,0,0,32,0,0,193,61,0,0,0,4,2,48,0,140,0,0,1,24,0,0,65,61],[0,0,0,0,2,1,4,59,0,0,0,224,2,32,2,112,0,0,0,97,4,32,0,156,0,0,0,40,0,0,97,61],[0,0,0,98,4,32,0,156,0,0,0,127,0,0,97,61,0,0,0,99,2,32,0,156,0,0,1,24,0,0,193,61],[0,0,0,0,2,0,4,22,0,0,0,0,2,2,0,75,0,0,1,24,0,0,193,61,0,0,0,4,2,48,0,138],[0,0,0,32,2,32,0,140,0,0,1,24,0,0,65,61,0,0,0,4,1,16,3,112,0,0,0,0,1,1,4,59],[0,0,0,0,1,1,4,26,0,0,0,128,0,16,4,63,0,0,0,123,1,0,0,65,0,0,1,121,0,1,4,46],[0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75,0,0,1,24,0,0,193,61,0,0,0,32,1,0,0,57],[0,0,1,0,0,16,4,67,0,0,1,32,0,0,4,67,0,0,0,96,1,0,0,65,0,0,1,121,0,1,4,46],[0,0,0,0,2,0,4,22,0,0,0,0,2,2,0,75,0,0,1,24,0,0,193,61,0,0,0,4,2,48,0,138],[0,0,0,64,2,32,0,140,0,0,1,24,0,0,65,61,0,0,0,4,2,16,3,112,0,0,0,0,4,2,4,59],[0,0,0,0,2,4,0,75,0,0,0,0,2,0,0,25,0,0,0,1,2,0,192,57,0,2,0,0,0,4,0,29],[0,0,0,0,2,36,0,75,0,0,1,24,0,0,193,61,0,0,0,36,2,16,3,112,0,0,0,0,2,2,4,59],[0,0,0,100,4,32,0,156,0,0,1,24,0,0,33,61,0,0,0,35,4,32,0,57,0,0,0,101,5,0,0,65],[0,0,0,0,6,52,0,75,0,0,0,0,6,0,0,25,0,0,0,0,6,5,128,25,0,0,0,101,4,64,1,151],[0,0,0,0,7,4,0,75,0,0,0,0,5,0,128,25,0,0,0,101,4,64,0,156,0,0,0,0,5,6,192,25],[0,0,0,0,4,5,0,75,0,0,1,24,0,0,193,61,0,0,0,4,4,32,0,57,0,0,0,0,4,65,3,79],[0,0,0,0,4,4,4,59,0,8,0,0,0,4,0,29,0,0,0,100,4,64,0,156,0,0,1,24,0,0,33,61],[0,7,0,36,0,32,0,61,0,0,0,8,2,0,0,41,0,0,0,5,2,32,2,16,0,0,0,7,2,32,0,41],[0,0,0,0,2,50,0,75,0,0,1,24,0,0,33,61,0,0,0,0,2,0,4,17,0,0,128,1,2,32,0,140],[0,0,0,192,0,0,193,61,0,0,0,8,2,0,0,107,0,0,0,190,0,0,97,61,0,0,0,2,2,0,0,107],[0,0,0,200,0,0,193,61,0,5,0,1,0,0,0,61,0,4,128,13,0,0,0,61,0,3,0,3,0,0,0,61],[0,0,0,0,4,0,0,25,0,0,0,97,0,0,1,61,0,0,0,1,4,64,0,57,0,0,0,8,2,64,0,108],[0,0,0,190,0,0,129,61,0,0,0,5,2,64,2,16,0,0,0,7,2,32,0,41,0,0,0,0,2,33,3,79],[0,0,0,0,5,2,4,59,0,0,0,0,2,5,4,26,0,0,0,0,2,2,0,75,0,0,0,94,0,0,193,61],[0,0,0,105,1,80,1,151,0,0,0,106,1,16,0,156,0,0,1,26,0,0,193,61,0,6,0,0,0,4,0,29],[0,0,0,107,1,80,1,152,0,0,1,47,0,0,97,61,0,0,0,5,1,0,0,41,0,0,0,0,0,21,4,27],[0,0,0,0,1,0,4,20,0,0,0,95,2,16,0,156,0,0,0,95,1,0,128,65,0,0,0,192,1,16,2,16],[0,0,0,113,1,16,1,199,0,0,0,4,2,0,0,41,0,0,0,3,3,0,0,41,0,0,0,114,4,0,0,65],[0,0,0,0,6,0,0,25,1,120,1,110,0,0,4,15,0,0,0,0,1,0,3,103,0,0,0,1,2,32,1,144],[0,0,0,6,4,0,0,41,0,0,0,94,0,0,193,61,0,0,1,24,0,0,1,61,0,0,0,0,2,0,4,22],[0,0,0,0,2,2,0,75,0,0,1,24,0,0,193,61,0,0,0,4,2,48,0,138,0,0,0,32,2,32,0,140],[0,0,1,24,0,0,65,61,0,0,0,4,1,16,3,112,0,0,0,0,5,1,4,59,0,0,0,0,1,0,4,17],[0,0,128,14,1,16,0,140,0,0,0,153,0,0,193,61,0,0,0,0,1,5,4,26,0,0,0,0,1,1,0,75],[0,0,0,190,0,0,193,61,0,0,0,105,1,80,1,151,0,0,0,106,1,16,0,156,0,0,0,163,0,0,193,61],[0,0,0,107,1,80,1,152,0,0,0,175,0,0,193,61,0,0,0,102,1,0,0,65,0,0,0,128,0,16,4,63],[0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63,0,0,0,164,0,16,4,63,0,0,0,119,1,0,0,65],[0,0,0,160,0,0,1,61,0,0,0,102,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57],[0,0,0,132,0,16,4,63,0,0,0,31,1,0,0,57,0,0,0,164,0,16,4,63,0,0,0,121,1,0,0,65],[0,0,0,196,0,16,4,63,0,0,0,104,1,0,0,65,0,0,1,122,0,1,4,48,0,0,0,102,1,0,0,65],[0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63,0,0,0,34,1,0,0,57],[0,0,0,164,0,16,4,63,0,0,0,117,1,0,0,65,0,0,0,196,0,16,4,63,0,0,0,116,1,0,0,65],[0,0,0,228,0,16,4,63,0,0,0,122,1,0,0,65,0,0,1,122,0,1,4,48,0,0,0,1,1,0,0,57],[0,0,0,0,0,21,4,27,0,0,0,95,1,0,0,65,0,0,0,0,2,0,4,20,0,0,0,95,3,32,0,156],[0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,0,113,1,16,1,199,0,0,128,13,2,0,0,57],[0,0,0,3,3,0,0,57,0,0,0,114,4,0,0,65,0,0,0,0,6,0,0,25,1,120,1,110,0,0,4,15],[0,0,0,1,1,32,1,144,0,0,1,24,0,0,97,61,0,0,0,0,1,0,0,25,0,0,1,121,0,1,4,46],[0,0,0,102,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63],[0,0,0,31,1,0,0,57,0,0,0,164,0,16,4,63,0,0,0,103,1,0,0,65,0,0,0,160,0,0,1,61],[0,5,128,8,0,0,0,61,0,1,128,2,0,0,0,61,0,0,0,0,4,0,0,25,0,0,0,207,0,0,1,61],[0,0,0,1,4,64,0,57,0,0,0,8,2,64,0,108,0,0,0,190,0,0,129,61,0,0,0,5,2,64,2,16],[0,0,0,7,2,32,0,41,0,0,0,0,2,33,3,79,0,0,0,0,3,2,4,59,0,0,0,0,2,3,4,26],[0,0,0,0,2,2,0,75,0,0,0,204,0,0,193,61,0,0,0,105,1,48,1,151,0,0,0,106,1,16,0,156],[0,0,1,26,0,0,193,61,0,4,0,0,0,4,0,29,0,6,0,0,0,3,0,29,0,0,0,107,1,48,1,152],[0,0,1,47,0,0,97,61,0,0,0,108,1,0,0,65,0,0,0,0,0,16,4,57,0,0,0,5,1,0,0,41],[0,0,0,4,0,16,4,67,0,0,0,0,1,0,4,20,0,0,0,95,2,16,0,156,0,0,0,95,1,0,128,65],[0,0,0,192,1,16,2,16,0,0,0,109,1,16,1,199,0,0,0,1,2,0,0,41,1,120,1,115,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,1,64,0,0,97,61,0,0,0,0,1,1,4,59,0,0,0,0,1,1,0,75],[0,0,0,6,2,0,0,41,0,0,1,24,0,0,97,61,0,0,0,64,4,0,4,61,0,0,0,110,1,0,0,65],[0,0,0,0,0,20,4,53,0,0,0,4,1,64,0,57,0,0,0,0,0,33,4,53,0,0,0,0,1,0,4,20],[0,0,0,95,2,16,0,156,0,0,0,95,3,0,0,65,0,0,0,0,1,3,128,25,0,0,0,95,2,64,0,156],[0,3,0,0,0,4,0,29,0,0,0,0,2,3,0,25,0,0,0,0,2,4,64,25,0,0,0,64,2,32,2,16],[0,0,0,192,1,16,2,16,0,0,0,0,1,33,1,159,0,0,0,111,1,16,1,199,0,0,0,5,2,0,0,41],[1,120,1,110,0,0,4,15,0,0,0,1,2,32,1,144,0,0,1,65,0,0,97,61,0,0,0,3,2,0,0,41],[0,0,0,112,1,32,0,156,0,0,1,103,0,0,129,61,0,0,0,64,0,32,4,63,0,0,0,1,1,0,0,57],[0,0,0,6,5,0,0,41,0,0,0,0,0,21,4,27,0,0,0,0,1,0,4,20,0,0,0,95,2,16,0,156],[0,0,0,95,1,0,128,65,0,0,0,192,1,16,2,16,0,0,0,113,1,16,1,199,0,0,128,13,2,0,0,57],[0,0,0,3,3,0,0,57,0,0,0,114,4,0,0,65,0,0,0,2,6,0,0,41,1,120,1,110,0,0,4,15],[0,0,0,0,1,0,3,103,0,0,0,1,2,32,1,144,0,0,0,4,4,0,0,41,0,0,0,204,0,0,193,61],[0,0,0,0,1,0,0,25,0,0,1,122,0,1,4,48,0,0,0,64,1,0,4,61,0,0,0,100,2,16,0,57],[0,0,0,116,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,68,2,16,0,57,0,0,0,117,3,0,0,65],[0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,34,3,0,0,57,0,0,0,0,0,50,4,53],[0,0,0,102,2,0,0,65,0,0,0,0,0,33,4,53,0,0,0,4,2,16,0,57,0,0,0,32,3,0,0,57],[0,0,0,0,0,50,4,53,0,0,0,95,2,0,0,65,0,0,0,95,3,16,0,156,0,0,0,0,1,2,128,25],[0,0,0,64,1,16,2,16,0,0,0,118,1,16,1,199,0,0,1,122,0,1,4,48,0,0,0,64,1,0,4,61],[0,0,0,68,2,16,0,57,0,0,0,119,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,102,2,0,0,65],[0,0,0,0,0,33,4,53,0,0,0,36,2,16,0,57,0,0,0,32,3,0,0,57,0,0,0,0,0,50,4,53],[0,0,0,4,2,16,0,57,0,0,0,0,0,50,4,53,0,0,0,95,2,0,0,65,0,0,0,95,3,16,0,156],[0,0,0,0,1,2,128,25,0,0,0,64,1,16,2,16,0,0,0,120,1,16,1,199,0,0,1,122,0,1,4,48],[0,0,0,0,0,1,4,47,0,0,0,64,2,0,4,61,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112],[0,0,0,31,4,48,1,143,0,0,0,95,3,48,1,151,0,0,0,5,5,48,2,114,0,0,1,81,0,0,97,61],[0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79],[0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75],[0,0,1,73,0,0,65,61,0,0,0,0,6,4,0,75,0,0,1,96,0,0,97,61,0,0,0,5,5,80,2,16],[0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51],[0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137],[0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53],[0,0,0,95,1,0,0,65,0,0,0,95,4,32,0,156,0,0,0,0,2,1,128,25,0,0,0,64,1,32,2,16],[0,0,0,96,2,48,2,16,0,0,0,0,1,33,1,159,0,0,1,122,0,1,4,48,0,0,0,115,1,0,0,65],[0,0,0,0,0,16,4,53,0,0,0,65,1,0,0,57,0,0,0,4,0,16,4,63,0,0,0,111,1,0,0,65],[0,0,1,122,0,1,4,48,0,0,0,0,0,1,4,47,0,0,1,113,0,33,4,33,0,0,0,1,2,0,0,57],[0,0,0,0,0,1,4,45,0,0,0,0,2,0,0,25,0,0,0,0,0,1,4,45,0,0,1,118,0,33,4,35],[0,0,0,1,2,0,0,57,0,0,0,0,0,1,4,45,0,0,0,0,2,0,0,25,0,0,0,0,0,1,4,45],[0,0,1,120,0,0,4,50,0,0,1,121,0,1,4,46,0,0,1,122,0,1,4,48,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255],[0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,1,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,229,22,118,30],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,121,196,249,41],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,76,99,20,240],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255],[128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[8,195,121,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[67,97,108,108,97,98,108,101,32,111,110,108,121,32,98,121,32,116,104,101,32,98,111,111,116,108,111,97,100,101,114,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,128,0,0,0,0,0,0,0,0],[255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[24,6,170,24,150,187,242,101,104,232,132,167,55,75,65,224,2,80,9,98,202,186,106,21,2,58,141,144,232,80,139,131],[2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,0,0,0,0,0,0],[57,179,76,110,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0],[2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[201,71,34,255,19,234,207,83,84,124,71,65,218,181,34,131,83,160,89,56,255,205,213,212,162,213,51,174,14,97,130,135],[78,72,123,113,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[115,104,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[73,110,99,111,114,114,101,99,116,108,121,32,102,111,114,109,97,116,116,101,100,32,98,121,116,101,99,111,100,101,72,97],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,0,0,0,0,0,0,0,0,0,0,0,0],[67,111,100,101,32,108,101,110,103,116,104,32,105,110,32,119,111,114,100,115,32,109,117,115,116,32,98,101,32,111,100,100],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,0,0,0,0,0,0,0,0,0],[67,97,108,108,97,98,108,101,32,111,110,108,121,32,98,121,32,116,104,101,32,99,111,109,112,114,101,115,115,111,114,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,0,0,0,128,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,128,0,0,0,0,0,0,0,0],[223,62,89,255,156,144,170,174,13,205,165,30,150,164,78,216,159,84,11,25,213,242,218,240,40,96,109,57,50,104,146,64]],"0x0000000000000000000000000000000000008005":[[0,1,0,0,0,0,0,2,0,7,0,0,0,0,0,2,0,0,0,0,7,1,3,79,0,0,0,0,0,7,3,85],[0,0,0,128,1,0,0,57,0,0,0,64,0,16,4,63,0,0,0,0,1,7,0,25,0,0,0,96,1,16,2,112],[0,0,0,47,1,16,1,151,0,0,0,1,2,32,1,144,0,0,0,45,0,0,193,61,0,0,0,4,2,16,0,140],[0,0,0,92,0,0,65,61,0,0,0,0,2,7,4,59,0,0,0,224,2,32,2,112,0,0,0,49,3,32,0,156],[0,0,0,53,0,0,97,61,0,0,0,50,2,32,0,156,0,0,0,92,0,0,193,61,0,0,0,0,2,0,4,22],[0,0,0,0,2,2,0,75,0,0,0,92,0,0,193,61,0,0,0,4,1,16,0,138,0,0,0,64,1,16,0,140],[0,0,0,92,0,0,65,61,0,0,0,4,1,112,3,112,0,0,0,0,1,1,4,59,0,0,0,51,2,16,0,156],[0,0,0,92,0,0,33,61,0,0,0,0,0,16,4,53,0,0,0,32,0,0,4,63,0,0,0,0,1,0,0,25],[0,7,0,0,0,7,3,83,0,184,0,161,0,0,4,15,0,0,0,7,2,0,3,95,0,0,0,36,2,32,3,112],[0,0,0,0,2,2,4,59,0,0,0,0,0,32,4,53,0,0,0,32,0,16,4,63,0,0,0,0,1,0,0,25],[0,184,0,161,0,0,4,15,0,0,0,0,1,1,4,26,0,0,0,128,0,16,4,63,0,0,0,59,1,0,0,65],[0,0,0,185,0,1,4,46,0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75,0,0,0,92,0,0,193,61],[0,0,0,32,1,0,0,57,0,0,1,0,0,16,4,67,0,0,1,32,0,0,4,67,0,0,0,48,1,0,0,65],[0,0,0,185,0,1,4,46,0,0,0,0,2,0,4,22,0,0,0,0,2,2,0,75,0,0,0,92,0,0,193,61],[0,0,0,4,2,16,0,138,0,0,0,64,2,32,0,140,0,0,0,92,0,0,65,61,0,0,0,4,2,112,3,112],[0,0,0,0,2,2,4,59,0,3,0,0,0,2,0,29,0,0,0,51,2,32,0,156,0,0,0,92,0,0,33,61],[0,0,0,36,2,112,3,112,0,0,0,0,2,2,4,59,0,0,0,52,3,32,0,156,0,0,0,92,0,0,33,61],[0,0,0,35,3,32,0,57,0,0,0,53,4,0,0,65,0,0,0,0,5,19,0,75,0,0,0,0,5,0,0,25],[0,0,0,0,5,4,128,25,0,0,0,53,3,48,1,151,0,0,0,0,6,3,0,75,0,0,0,0,4,0,128,25],[0,0,0,53,3,48,0,156,0,0,0,0,4,5,192,25,0,0,0,0,3,4,0,75,0,0,0,92,0,0,193,61],[0,0,0,4,3,32,0,57,0,0,0,0,3,55,3,79,0,0,0,0,3,3,4,59,0,2,0,0,0,3,0,29],[0,0,0,52,3,48,0,156,0,0,0,92,0,0,33,61,0,1,0,36,0,32,0,61,0,0,0,2,2,0,0,41],[0,0,0,6,2,32,2,16,0,0,0,1,2,32,0,41,0,0,0,0,1,18,0,75,0,0,0,94,0,0,161,61],[0,0,0,0,1,0,0,25,0,0,0,186,0,1,4,48,0,0,0,0,1,0,4,17,0,0,128,6,1,16,0,140],[0,0,0,149,0,0,193,61,0,0,0,2,1,0,0,107,0,0,0,147,0,0,97,61,0,0,0,47,4,0,0,65],[0,0,128,16,5,0,0,57,0,0,0,0,2,0,0,25,0,7,0,0,0,5,0,29,0,5,0,0,0,2,0,29],[0,0,0,6,1,32,2,16,0,0,0,1,1,16,0,41,0,0,0,32,2,16,0,57,0,0,0,0,2,32,3,103],[0,0,0,0,1,16,3,103,0,0,0,0,1,1,4,59,0,6,0,0,0,1,0,29,0,0,0,0,1,2,4,59],[0,4,0,0,0,1,0,29,0,0,0,3,1,0,0,41,0,0,0,0,0,16,4,53,0,0,0,32,0,0,4,63],[0,0,0,0,1,0,4,20,0,0,0,47,2,16,0,156,0,0,0,0,1,4,128,25,0,0,0,192,1,16,2,16],[0,0,0,58,1,16,1,199,0,0,0,0,2,5,0,25,0,184,0,179,0,0,4,15,0,0,0,1,2,32,1,144],[0,0,0,92,0,0,97,61,0,0,0,0,1,1,4,59,0,0,0,6,2,0,0,41,0,0,0,0,0,32,4,53],[0,0,0,32,0,16,4,63,0,0,0,0,1,0,4,20,0,0,0,47,2,16,0,156,0,0,0,47,1,0,128,65],[0,0,0,192,1,16,2,16,0,0,0,58,1,16,1,199,0,0,0,7,2,0,0,41,0,184,0,179,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,0,92,0,0,97,61,0,0,0,0,1,1,4,59,0,0,0,4,2,0,0,41],[0,0,0,0,0,33,4,27,0,0,0,5,2,0,0,41,0,0,0,1,2,32,0,57,0,0,0,2,1,32,0,108],[0,0,0,47,4,0,0,65,0,0,0,7,5,0,0,41,0,0,0,103,0,0,65,61,0,0,0,0,1,0,0,25],[0,0,0,185,0,1,4,46,0,0,0,54,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57],[0,0,0,132,0,16,4,63,0,0,0,45,1,0,0,57,0,0,0,164,0,16,4,63,0,0,0,55,1,0,0,65],[0,0,0,196,0,16,4,63,0,0,0,56,1,0,0,65,0,0,0,228,0,16,4,63,0,0,0,57,1,0,0,65],[0,0,0,186,0,1,4,48,0,0,0,47,2,0,0,65,0,0,0,47,3,16,0,156,0,0,0,0,1,2,128,25],[0,0,0,0,3,0,4,20,0,0,0,47,4,48,0,156,0,0,0,0,3,2,128,25,0,0,0,192,2,48,2,16],[0,0,0,64,1,16,2,16,0,0,0,0,1,33,1,159,0,0,0,58,1,16,1,199,0,0,128,16,2,0,0,57],[0,184,0,179,0,0,4,15,0,0,0,1,2,32,1,144,0,0,0,177,0,0,97,61,0,0,0,0,1,1,4,59],[0,0,0,0,0,1,4,45,0,0,0,0,1,0,0,25,0,0,0,186,0,1,4,48,0,0,0,182,0,33,4,35],[0,0,0,1,2,0,0,57,0,0,0,0,0,1,4,45,0,0,0,0,2,0,0,25,0,0,0,0,0,1,4,45],[0,0,0,184,0,0,4,50,0,0,0,185,0,1,4,46,0,0,0,186,0,1,4,48,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255],[0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,1,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,173,126,35,46],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,49,10,176,137],[0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255],[128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[8,195,121,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[67,97,108,108,97,98,108,101,32,111,110,108,121,32,98,121,32,116,104,101,32,100,101,112,108,111,121,101,114,32,115,121],[115,116,101,109,32,99,111,110,116,114,97,99,116,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,0,0,0,128,0,0,0,0,0,0,0,0],[2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,128,0,0,0,0,0,0,0,0],[81,102,191,199,126,113,54,183,221,66,149,62,165,26,231,44,138,209,202,232,57,191,9,202,204,131,225,161,39,117,207,250]],"0x0000000000000000000000000000000000008006":[[0,18,0,0,0,0,0,2,0,11,0,0,0,0,0,2,0,0,0,0,3,2,0,25,0,0,0,0,2,1,0,25],[0,0,0,96,4,32,2,112,0,0,4,194,2,64,1,151,0,1,0,0,0,33,3,85,0,2,0,0,0,33,3,85],[0,3,0,0,0,33,3,85,0,4,0,0,0,33,3,85,0,5,0,0,0,33,3,85,0,6,0,0,0,33,3,85],[0,7,0,0,0,33,3,85,0,8,0,0,0,33,3,85,0,9,0,0,0,33,3,85,0,10,0,0,0,33,3,85],[0,11,0,0,0,33,3,85,0,12,0,0,0,33,3,85,0,13,0,0,0,33,3,85,0,14,0,0,0,33,3,85],[0,15,0,0,0,33,3,85,0,16,0,0,0,33,3,85,0,17,0,0,0,1,3,85,0,0,4,194,0,64,1,157],[0,0,0,128,4,0,0,57,0,0,0,64,0,64,4,63,0,0,0,1,4,48,1,144,0,0,0,99,0,0,193,61],[0,0,0,4,4,32,0,140,0,0,3,41,0,0,65,61,0,0,0,0,4,1,4,59,0,0,0,224,4,64,2,112],[0,0,4,196,5,64,0,156,0,0,0,107,0,0,33,61,0,0,4,204,5,64,0,156,0,0,0,159,0,0,33,61],[0,0,4,208,5,64,0,156,0,0,1,52,0,0,97,61,0,0,4,209,5,64,0,156,0,0,2,72,0,0,97,61],[0,0,4,210,4,64,0,156,0,0,3,41,0,0,193,61,0,0,0,0,4,0,4,22,0,0,0,0,4,4,0,75],[0,0,3,41,0,0,193,61,0,0,0,4,2,32,0,138,0,0,0,32,2,32,0,140,0,0,3,41,0,0,65,61],[0,0,0,4,1,16,3,112,0,0,0,0,1,1,4,59,0,11,0,0,0,1,0,29,0,0,0,1,1,16,0,140],[0,0,3,41,0,0,33,61,0,0,0,0,2,0,4,17,0,0,0,2,1,48,1,144,0,0,0,58,0,0,193,61],[0,0,255,255,1,32,0,140,0,0,2,60,0,0,33,61,0,10,0,0,0,2,0,29,0,0,0,0,0,32,4,53],[0,0,0,32,0,0,4,63,0,0,4,194,3,0,0,65,0,0,0,0,1,0,4,20,0,0,4,194,2,16,0,156],[0,0,0,0,1,3,128,25,0,0,0,192,1,16,2,16,0,0,4,219,1,16,1,199,0,0,128,16,2,0,0,57],[19,2,18,242,0,0,4,15,0,0,0,1,2,32,1,144,0,0,3,41,0,0,97,61,0,0,0,0,1,1,4,59],[0,0,0,0,2,1,4,26,0,0,1,0,3,0,0,138,0,0,0,0,2,50,1,111,0,0,0,11,3,0,0,41],[0,0,0,0,2,50,1,159,0,0,0,0,0,33,4,27,0,0,0,64,1,0,4,61,0,0,0,0,0,49,4,53],[0,0,0,0,2,0,4,20,0,0,4,194,3,32,0,156,0,0,4,194,4,0,0,65,0,0,0,0,2,4,128,25],[0,0,4,194,3,16,0,156,0,0,0,0,1,4,128,25,0,0,0,64,1,16,2,16,0,0,0,192,2,32,2,16],[0,0,0,0,1,18,1,159,0,0,4,253,1,16,1,199,0,0,128,13,2,0,0,57,0,0,0,2,3,0,0,57],[0,0,5,14,4,0,0,65,0,0,0,10,5,0,0,41,19,2,18,237,0,0,4,15,0,0,0,1,1,32,1,144],[0,0,3,41,0,0,97,61,0,0,0,0,1,0,0,25,0,0,19,3,0,1,4,46,0,0,0,0,1,0,4,22],[0,0,0,0,1,1,0,75,0,0,3,41,0,0,193,61,0,0,0,32,1,0,0,57,0,0,1,0,0,16,4,67],[0,0,1,32,0,0,4,67,0,0,4,195,1,0,0,65,0,0,19,3,0,1,4,46,0,0,4,197,5,64,0,156],[0,0,0,195,0,0,33,61,0,0,4,201,5,64,0,156,0,0,1,75,0,0,97,61,0,0,4,202,3,64,0,156],[0,0,2,185,0,0,97,61,0,0,4,203,3,64,0,156,0,0,3,41,0,0,193,61,0,0,0,4,3,32,0,138],[0,0,0,32,3,48,0,140,0,0,3,41,0,0,65,61,0,0,0,4,3,16,3,112,0,0,0,0,3,3,4,59],[0,5,0,0,0,3,0,29,0,0,4,211,3,48,0,156,0,0,3,41,0,0,33,61,0,0,0,5,3,0,0,41],[0,0,0,35,3,48,0,57,0,0,4,212,4,0,0,65,0,0,0,0,5,35,0,75,0,0,0,0,5,0,0,25],[0,0,0,0,5,4,128,25,0,0,4,212,3,48,1,151,0,0,0,0,6,3,0,75,0,0,0,0,4,0,128,25],[0,0,4,212,3,48,0,156,0,0,0,0,4,5,192,25,0,0,0,0,3,4,0,75,0,0,3,41,0,0,193,61],[0,0,0,5,3,0,0,41,0,0,0,4,3,48,0,57,0,0,0,0,3,49,3,79,0,0,0,0,13,3,4,59],[0,0,4,211,3,208,0,156,0,0,3,41,0,0,33,61,0,0,0,5,3,0,0,41,0,0,0,36,14,48,0,57],[0,0,0,5,3,208,2,16,0,0,0,0,3,227,0,25,0,0,0,0,3,35,0,75,0,0,3,41,0,0,33,61],[0,0,0,9,4,0,0,138,0,0,0,0,3,0,4,17,0,0,0,0,4,67,1,111,0,0,128,7,4,64,0,140],[0,0,3,183,0,0,193,61,0,0,0,0,4,13,0,75,0,0,3,242,0,0,193,61,0,0,0,0,1,0,4,22],[0,0,0,0,1,1,0,75,0,0,0,97,0,0,97,61,0,0,5,38,0,0,1,61,0,0,4,205,5,64,0,156],[0,0,1,182,0,0,97,61,0,0,4,206,3,64,0,156,0,0,2,237,0,0,97,61,0,0,4,207,3,64,0,156],[0,0,3,41,0,0,193,61,0,0,0,0,3,0,4,22,0,0,0,0,3,3,0,75,0,0,3,41,0,0,193,61],[0,0,0,4,3,32,0,138,0,0,0,128,3,48,0,140,0,0,3,41,0,0,65,61,0,0,0,4,3,16,3,112],[0,0,0,0,3,3,4,59,0,11,0,0,0,3,0,29,0,0,4,213,3,48,0,156,0,0,3,41,0,0,33,61],[0,0,0,100,1,16,3,112,0,0,0,0,1,1,4,59,0,0,4,211,3,16,0,156,0,0,3,41,0,0,33,61],[0,0,0,4,1,16,0,57,19,2,9,95,0,0,4,15,0,0,0,17,4,0,3,103,0,0,0,68,3,64,3,112],[0,0,0,0,3,3,4,59,0,0,0,36,4,64,3,112,0,0,0,0,4,4,4,59,0,0,0,0,5,1,0,25],[0,0,0,0,6,2,0,25,0,0,0,11,1,0,0,41,0,0,0,0,2,4,0,25,0,0,0,0,4,5,0,25],[0,0,0,0,5,6,0,25,19,2,9,121,0,0,4,15,0,0,1,66,0,0,1,61,0,0,4,198,5,64,0,156],[0,0,2,44,0,0,97,61,0,0,4,199,5,64,0,156,0,0,3,38,0,0,97,61,0,0,4,200,3,64,0,156],[0,0,3,41,0,0,193,61,0,0,0,4,3,32,0,138,0,0,0,64,3,48,0,140,0,0,3,41,0,0,65,61],[0,0,0,4,3,16,3,112,0,0,0,0,3,3,4,59,0,11,0,0,0,3,0,29,0,0,4,211,3,48,0,156],[0,0,3,41,0,0,33,61,0,0,0,11,4,32,0,106,0,0,4,212,2,0,0,65,0,0,0,164,3,64,0,140],[0,0,0,0,3,0,0,25,0,0,0,0,3,2,64,25,0,10,0,0,0,4,0,29,0,0,4,212,4,64,1,151],[0,0,0,0,5,4,0,75,0,0,0,0,2,0,160,25,0,0,4,212,4,64,0,156,0,0,0,0,2,3,192,25],[0,0,0,0,2,2,0,75,0,0,3,41,0,0,193,61,0,0,0,36,2,16,3,112,0,0,0,0,2,2,4,59],[0,9,0,0,0,2,0,29,0,0,4,213,2,32,0,156,0,0,3,41,0,0,33,61,0,0,0,0,3,0,4,16],[0,0,0,0,2,0,4,17,0,0,0,0,2,50,0,75,0,0,3,173,0,0,193,61,0,6,0,0,0,3,0,29],[0,0,0,11,2,0,0,41,0,8,0,4,0,32,0,61,0,0,0,8,1,16,3,96,0,0,0,0,2,1,4,59],[0,0,4,217,1,0,0,65,0,0,0,128,0,16,4,63,0,7,0,0,0,2,0,29,0,0,0,132,0,32,4,63],[0,0,4,194,1,0,0,65,0,0,0,0,2,0,4,20,0,0,4,194,3,32,0,156,0,0,0,0,2,1,128,25],[0,0,0,192,1,32,2,16,0,0,4,218,1,16,1,199,0,0,128,4,2,0,0,57,19,2,18,242,0,0,4,15],[0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,4,194,3,48,1,151,0,0,0,32,4,48,0,140],[0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57,0,0,0,31,5,64,1,143,0,0,0,5,6,64,2,114],[0,0,1,10,0,0,97,61,0,0,0,0,7,0,0,25,0,0,0,5,8,112,2,16,0,0,0,0,9,129,3,79],[0,0,0,0,9,9,4,59,0,0,0,128,8,128,0,57,0,0,0,0,0,152,4,53,0,0,0,1,7,112,0,57],[0,0,0,0,8,103,0,75,0,0,1,2,0,0,65,61,0,0,0,0,7,5,0,75,0,0,1,25,0,0,97,61],[0,0,0,5,6,96,2,16,0,0,0,0,7,97,3,79,0,0,0,3,5,80,2,16,0,0,0,128,6,96,0,57],[0,0,0,0,8,6,4,51,0,0,0,0,8,88,1,207,0,0,0,0,8,88,2,47,0,0,0,0,7,7,4,59],[0,0,1,0,5,80,0,137,0,0,0,0,7,87,2,47,0,0,0,0,5,87,1,207,0,0,0,0,5,133,1,159],[0,0,0,0,0,86,4,53,0,0,0,1,2,32,1,144,0,0,3,213,0,0,97,61,0,0,0,31,1,64,0,57],[0,0,0,96,1,16,1,143,0,0,0,128,2,16,1,191,0,5,0,0,0,2,0,29,0,0,0,64,0,32,4,63],[0,0,0,32,2,48,0,140,0,0,3,41,0,0,65,61,0,0,0,128,2,0,4,61,0,0,0,0,2,2,0,75],[0,0,5,177,0,0,193,61,0,0,4,214,2,0,0,65,0,0,0,5,4,0,0,41,0,0,0,0,0,36,4,53],[0,0,0,132,2,16,1,191,0,0,0,32,3,0,0,57,0,0,0,0,0,50,4,53,0,0,0,196,2,16,0,57],[0,0,4,245,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,164,1,16,0,57,0,0,0,26,2,0,0,57],[0,0,0,0,0,33,4,53,0,0,0,64,1,64,2,16,0,0,4,224,1,16,1,199,0,0,19,4,0,1,4,48],[0,0,0,0,3,0,4,22,0,0,0,0,3,3,0,75,0,0,3,41,0,0,193,61,0,0,0,4,2,32,0,138],[0,0,0,64,2,32,0,140,0,0,3,41,0,0,65,61,0,0,0,4,2,16,3,112,0,0,0,0,3,2,4,59],[0,0,4,213,2,48,0,156,0,0,3,41,0,0,33,61,0,0,0,36,1,16,3,112,0,0,0,0,2,1,4,59],[0,0,0,0,1,3,0,25,19,2,10,68,0,0,4,15,0,0,4,213,1,16,1,151,0,0,0,64,2,0,4,61],[0,0,0,0,0,18,4,53,0,0,4,194,1,0,0,65,0,0,4,194,3,32,0,156,0,0,0,0,2,1,128,25],[0,0,0,64,1,32,2,16,0,0,4,248,1,16,1,199,0,0,19,3,0,1,4,46,0,0,0,4,4,32,0,138],[0,0,0,96,4,64,0,140,0,0,3,41,0,0,65,61,0,0,0,36,4,16,3,112,0,0,0,0,4,4,4,59],[0,11,0,0,0,4,0,29,0,0,0,68,4,16,3,112,0,0,0,0,4,4,4,59,0,0,4,211,5,64,0,156],[0,0,3,41,0,0,33,61,0,0,0,35,5,64,0,57,0,0,4,212,6,0,0,65,0,0,0,0,7,37,0,75],[0,0,0,0,7,0,0,25,0,0,0,0,7,6,128,25,0,0,4,212,5,80,1,151,0,0,0,0,8,5,0,75],[0,0,0,0,6,0,128,25,0,0,4,212,5,80,0,156,0,0,0,0,6,7,192,25,0,0,0,0,5,6,0,75],[0,0,3,41,0,0,193,61,0,0,0,4,5,64,0,57,0,0,0,0,1,81,3,79,0,0,0,0,1,1,4,59],[0,10,0,0,0,1,0,29,0,0,4,211,1,16,0,156,0,0,3,41,0,0,33,61,0,0,0,36,4,64,0,57],[0,9,0,0,0,4,0,29,0,0,0,10,1,64,0,41,0,0,0,0,1,33,0,75,0,0,3,41,0,0,33,61],[0,0,0,2,1,48,1,144,0,0,0,1,1,16,2,112,0,0,1,115,0,0,193,61,0,0,0,0,1,0,4,17],[0,0,4,246,1,16,0,156,0,0,0,0,1,0,0,25,0,0,0,1,1,0,64,57,0,0,0,0,1,1,0,75],[0,0,2,60,0,0,97,61,0,0,4,247,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,0,1,0,4,17],[0,8,0,0,0,1,0,29,0,0,0,132,0,16,4,63,0,0,4,194,1,0,0,65,0,0,0,0,2,0,4,20],[0,0,4,194,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,4,218,1,16,1,199],[0,0,128,3,2,0,0,57,19,2,18,237,0,0,4,15,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112],[0,0,4,194,3,48,1,151,0,0,0,32,4,48,0,140,0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57],[0,0,0,31,5,64,1,143,0,0,0,5,6,64,2,114,0,0,1,148,0,0,97,61,0,0,0,0,7,0,0,25],[0,0,0,5,8,112,2,16,0,0,0,0,9,129,3,79,0,0,0,0,9,9,4,59,0,0,0,128,8,128,0,57],[0,0,0,0,0,152,4,53,0,0,0,1,7,112,0,57,0,0,0,0,8,103,0,75,0,0,1,140,0,0,65,61],[0,0,0,0,7,5,0,75,0,0,1,163,0,0,97,61,0,0,0,5,6,96,2,16,0,0,0,0,7,97,3,79],[0,0,0,3,5,80,2,16,0,0,0,128,6,96,0,57,0,0,0,0,8,6,4,51,0,0,0,0,8,88,1,207],[0,0,0,0,8,88,2,47,0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137,0,0,0,0,7,87,2,47],[0,0,0,0,5,87,1,207,0,0,0,0,5,133,1,159,0,0,0,0,0,86,4,53,0,0,0,1,2,32,1,144],[0,0,4,236,0,0,97,61,0,0,0,31,1,64,0,57,0,0,0,96,1,16,1,143,0,0,0,128,1,16,1,191],[0,0,0,64,0,16,4,63,0,0,0,32,1,48,0,140,0,0,3,41,0,0,65,61,0,0,0,128,2,0,4,61],[0,0,0,8,1,0,0,41,19,2,10,68,0,0,4,15,0,0,0,0,2,1,0,25,0,8,0,0,0,2,0,29],[0,0,0,11,1,0,0,41,0,0,0,9,3,0,0,41,0,0,0,10,4,0,0,41,19,2,10,112,0,0,4,15],[0,0,0,8,1,0,0,41,0,0,1,66,0,0,1,61,0,0,0,4,4,32,0,138,0,0,0,128,4,64,0,140],[0,0,3,41,0,0,65,61,0,0,0,36,4,16,3,112,0,0,0,0,4,4,4,59,0,11,0,0,0,4,0,29],[0,0,0,4,4,16,3,112,0,0,0,0,4,4,4,59,0,10,0,0,0,4,0,29,0,0,0,68,4,16,3,112],[0,0,0,0,4,4,4,59,0,0,4,211,5,64,0,156,0,0,3,41,0,0,33,61,0,0,0,35,5,64,0,57],[0,0,4,212,6,0,0,65,0,0,0,0,7,37,0,75,0,0,0,0,7,0,0,25,0,0,0,0,7,6,128,25],[0,0,4,212,5,80,1,151,0,0,0,0,8,5,0,75,0,0,0,0,6,0,128,25,0,0,4,212,5,80,0,156],[0,0,0,0,6,7,192,25,0,0,0,0,5,6,0,75,0,0,3,41,0,0,193,61,0,0,0,4,5,64,0,57],[0,0,0,0,5,81,3,79,0,0,0,0,5,5,4,59,0,9,0,0,0,5,0,29,0,0,4,211,5,80,0,156],[0,0,3,41,0,0,33,61,0,0,0,36,5,64,0,57,0,8,0,0,0,5,0,29,0,0,0,9,4,80,0,41],[0,0,0,0,2,36,0,75,0,0,3,41,0,0,33,61,0,0,0,100,1,16,3,112,0,0,0,0,1,1,4,59],[0,7,0,0,0,1,0,29,0,0,0,1,1,16,0,140,0,0,3,41,0,0,33,61,0,0,0,2,1,48,1,144],[0,0,0,1,1,16,2,112,0,0,1,230,0,0,193,61,0,0,0,0,1,0,4,17,0,0,4,246,1,16,0,156],[0,0,0,0,1,0,0,25,0,0,0,1,1,0,64,57,0,0,0,0,1,1,0,75,0,0,2,60,0,0,97,61],[0,0,4,247,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,0,1,0,4,17,0,6,0,0,0,1,0,29],[0,0,0,132,0,16,4,63,0,0,4,194,1,0,0,65,0,0,0,0,2,0,4,20,0,0,4,194,3,32,0,156],[0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,4,218,1,16,1,199,0,0,128,3,2,0,0,57],[19,2,18,237,0,0,4,15,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,4,194,3,48,1,151],[0,0,0,32,4,48,0,140,0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57,0,0,0,31,5,64,1,143],[0,0,0,5,6,64,2,114,0,0,2,7,0,0,97,61,0,0,0,0,7,0,0,25,0,0,0,5,8,112,2,16],[0,0,0,0,9,129,3,79,0,0,0,0,9,9,4,59,0,0,0,128,8,128,0,57,0,0,0,0,0,152,4,53],[0,0,0,1,7,112,0,57,0,0,0,0,8,103,0,75,0,0,1,255,0,0,65,61,0,0,0,0,7,5,0,75],[0,0,2,22,0,0,97,61,0,0,0,5,6,96,2,16,0,0,0,0,7,97,3,79,0,0,0,3,5,80,2,16],[0,0,0,128,6,96,0,57,0,0,0,0,8,6,4,51,0,0,0,0,8,88,1,207,0,0,0,0,8,88,2,47],[0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137,0,0,0,0,7,87,2,47,0,0,0,0,5,87,1,207],[0,0,0,0,5,133,1,159,0,0,0,0,0,86,4,53,0,0,0,1,2,32,1,144,0,0,5,113,0,0,97,61],[0,0,0,31,1,64,0,57,0,0,0,96,1,16,1,143,0,0,0,128,1,16,1,191,0,0,0,64,0,16,4,63],[0,0,0,32,1,48,0,140,0,0,3,41,0,0,65,61,0,0,0,6,1,0,0,41,0,0,0,11,2,0,0,41],[0,0,0,10,3,0,0,41,0,0,0,8,4,0,0,41,0,0,0,9,5,0,0,41,19,2,9,121,0,0,4,15],[0,0,0,0,2,1,0,25,0,10,0,0,0,2,0,29,0,0,0,11,1,0,0,41,0,0,0,7,3,0,0,41],[0,0,0,8,4,0,0,41,0,0,0,9,5,0,0,41,19,2,14,171,0,0,4,15,0,0,2,183,0,0,1,61],[0,0,0,0,4,0,4,22,0,0,0,0,4,4,0,75,0,0,3,41,0,0,193,61,0,0,0,4,2,32,0,138],[0,0,0,32,2,32,0,140,0,0,3,41,0,0,65,61,0,0,0,4,1,16,3,112,0,0,0,0,1,1,4,59],[0,11,0,0,0,1,0,29,0,0,0,1,1,16,0,140,0,0,3,41,0,0,33,61,0,0,0,0,2,0,4,17],[0,0,0,2,1,48,1,144,0,0,3,153,0,0,193,61,0,0,255,255,1,32,0,140,0,0,3,153,0,0,161,61],[0,0,4,214,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63],[0,0,0,36,1,0,0,57,0,0,0,164,0,16,4,63,0,0,5,15,1,0,0,65,0,0,0,196,0,16,4,63],[0,0,5,16,1,0,0,65,0,0,0,228,0,16,4,63,0,0,5,17,1,0,0,65,0,0,19,4,0,1,4,48],[0,0,0,4,4,32,0,138,0,0,0,96,4,64,0,140,0,0,3,41,0,0,65,61,0,0,0,36,4,16,3,112],[0,0,0,0,4,4,4,59,0,11,0,0,0,4,0,29,0,0,0,4,4,16,3,112,0,0,0,0,4,4,4,59],[0,10,0,0,0,4,0,29,0,0,0,68,4,16,3,112,0,0,0,0,4,4,4,59,0,0,4,211,5,64,0,156],[0,0,3,41,0,0,33,61,0,0,0,35,5,64,0,57,0,0,4,212,6,0,0,65,0,0,0,0,7,37,0,75],[0,0,0,0,7,0,0,25,0,0,0,0,7,6,128,25,0,0,4,212,5,80,1,151,0,0,0,0,8,5,0,75],[0,0,0,0,6,0,128,25,0,0,4,212,5,80,0,156,0,0,0,0,6,7,192,25,0,0,0,0,5,6,0,75],[0,0,3,41,0,0,193,61,0,0,0,4,5,64,0,57,0,0,0,0,1,81,3,79,0,0,0,0,1,1,4,59],[0,9,0,0,0,1,0,29,0,0,4,211,1,16,0,156,0,0,3,41,0,0,33,61,0,0,0,36,4,64,0,57],[0,8,0,0,0,4,0,29,0,0,0,9,1,64,0,41,0,0,0,0,1,33,0,75,0,0,3,41,0,0,33,61],[0,0,0,2,1,48,1,144,0,0,0,1,1,16,2,112,0,0,2,115,0,0,193,61,0,0,0,0,1,0,4,17],[0,0,4,246,1,16,0,156,0,0,0,0,1,0,0,25,0,0,0,1,1,0,64,57,0,0,0,0,1,1,0,75],[0,0,2,60,0,0,97,61,0,0,4,247,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,0,1,0,4,17],[0,7,0,0,0,1,0,29,0,0,0,132,0,16,4,63,0,0,4,194,1,0,0,65,0,0,0,0,2,0,4,20],[0,0,4,194,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,4,218,1,16,1,199],[0,0,128,3,2,0,0,57,19,2,18,237,0,0,4,15,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112],[0,0,4,194,3,48,1,151,0,0,0,32,4,48,0,140,0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57],[0,0,0,31,5,64,1,143,0,0,0,5,6,64,2,114,0,0,2,148,0,0,97,61,0,0,0,0,7,0,0,25],[0,0,0,5,8,112,2,16,0,0,0,0,9,129,3,79,0,0,0,0,9,9,4,59,0,0,0,128,8,128,0,57],[0,0,0,0,0,152,4,53,0,0,0,1,7,112,0,57,0,0,0,0,8,103,0,75,0,0,2,140,0,0,65,61],[0,0,0,0,7,5,0,75,0,0,2,163,0,0,97,61,0,0,0,5,6,96,2,16,0,0,0,0,7,97,3,79],[0,0,0,3,5,80,2,16,0,0,0,128,6,96,0,57,0,0,0,0,8,6,4,51,0,0,0,0,8,88,1,207],[0,0,0,0,8,88,2,47,0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137,0,0,0,0,7,87,2,47],[0,0,0,0,5,87,1,207,0,0,0,0,5,133,1,159,0,0,0,0,0,86,4,53,0,0,0,1,2,32,1,144],[0,0,5,9,0,0,97,61,0,0,0,31,1,64,0,57,0,0,0,96,1,16,1,143,0,0,0,128,1,16,1,191],[0,0,0,64,0,16,4,63,0,0,0,32,1,48,0,140,0,0,3,41,0,0,65,61,0,0,0,7,1,0,0,41],[0,0,0,11,2,0,0,41,0,0,0,10,3,0,0,41,0,0,0,8,4,0,0,41,0,0,0,9,5,0,0,41],[19,2,9,121,0,0,4,15,0,0,0,0,2,1,0,25,0,10,0,0,0,2,0,29,0,0,0,11,1,0,0,41],[0,0,0,8,3,0,0,41,0,0,0,9,4,0,0,41,19,2,10,112,0,0,4,15,0,0,0,10,1,0,0,41],[0,0,1,66,0,0,1,61,0,0,0,0,3,0,4,22,0,0,0,0,3,3,0,75,0,0,3,41,0,0,193,61],[0,0,0,4,2,32,0,138,0,0,0,32,2,32,0,140,0,0,3,41,0,0,65,61,0,0,0,4,1,16,3,112],[0,0,0,0,1,1,4,59,0,11,0,0,0,1,0,29,0,0,4,213,1,16,0,156,0,0,3,41,0,0,33,61],[0,0,0,11,1,0,0,41,0,0,0,0,0,16,4,53,0,0,0,32,0,0,4,63,0,0,4,194,1,0,0,65],[0,0,0,0,2,0,4,20,0,0,4,194,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16],[0,0,4,219,1,16,1,199,0,0,128,16,2,0,0,57,19,2,18,242,0,0,4,15,0,0,0,1,2,32,1,144],[0,0,3,41,0,0,97,61,0,0,0,64,2,0,4,61,0,0,4,236,3,32,0,156,0,0,3,169,0,0,33,61],[0,0,0,0,1,1,4,59,0,0,0,64,3,32,0,57,0,0,0,64,0,48,4,63,0,0,0,0,1,1,4,26],[0,0,0,255,3,16,1,143,0,0,0,1,4,48,0,140,0,0,3,207,0,0,33,61,0,0,0,0,3,50,4,54],[0,0,0,8,1,16,2,112,0,0,0,255,1,16,1,143,0,0,0,1,4,16,0,140,0,0,3,207,0,0,33,61],[0,0,0,0,0,19,4,53,0,0,0,0,2,2,4,51,0,0,0,1,1,32,0,140,0,0,3,207,0,0,33,61],[0,0,0,1,1,0,0,57,0,0,0,0,2,2,0,75,0,0,1,67,0,0,193,61,0,0,0,11,1,0,0,41],[0,0,5,10,1,16,1,152,0,0,0,0,1,0,0,25,0,0,6,108,0,0,193,61,0,0,0,1,1,16,1,143],[0,0,1,67,0,0,1,61,0,0,0,0,3,0,4,22,0,0,0,0,3,3,0,75,0,0,3,41,0,0,193,61],[0,0,0,4,2,32,0,138,0,0,0,32,2,32,0,140,0,0,3,41,0,0,65,61,0,0,0,4,1,16,3,112],[0,0,0,0,1,1,4,59,0,0,4,213,2,16,0,156,0,0,3,41,0,0,33,61,0,0,0,192,2,0,0,57],[0,0,0,64,0,32,4,63,0,0,0,128,0,0,4,63,0,0,0,160,0,0,4,63,0,0,0,0,0,16,4,53],[0,0,0,32,0,0,4,63,0,0,4,194,1,0,0,65,0,0,0,0,2,0,4,20,0,0,4,194,3,32,0,156],[0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,4,219,1,16,1,199,0,0,128,16,2,0,0,57],[19,2,18,242,0,0,4,15,0,0,0,1,2,32,1,144,0,0,3,41,0,0,97,61,0,0,0,64,2,0,4,61],[0,0,5,12,3,32,0,156,0,0,3,169,0,0,129,61,0,0,0,0,1,1,4,59,0,0,0,64,3,32,0,57],[0,0,0,64,0,48,4,63,0,0,0,0,3,1,4,26,0,0,0,255,1,48,1,143,0,0,0,2,4,16,0,140],[0,0,3,207,0,0,129,61,0,0,0,0,1,18,4,54,0,0,0,8,3,48,2,112,0,0,0,255,3,48,1,143],[0,0,0,1,4,48,0,140,0,0,3,207,0,0,33,61,0,0,0,0,0,49,4,53,0,0,0,0,3,2,4,51],[0,0,0,1,2,48,0,140,0,0,3,207,0,0,33,61,0,0,0,64,2,0,4,61,0,0,0,0,3,50,4,54],[0,0,0,0,1,1,4,51,0,0,0,1,4,16,0,140,0,0,3,207,0,0,33,61,0,0,0,0,0,19,4,53],[0,0,4,194,1,0,0,65,0,0,4,194,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,64,1,32,2,16],[0,0,5,13,1,16,1,199,0,0,19,3,0,1,4,46,0,0,0,4,4,32,0,138,0,0,0,128,4,64,0,140],[0,0,3,43,0,0,129,61,0,0,0,0,1,0,0,25,0,0,19,4,0,1,4,48,0,0,0,36,4,16,3,112],[0,0,0,0,4,4,4,59,0,11,0,0,0,4,0,29,0,0,0,68,4,16,3,112,0,0,0,0,4,4,4,59],[0,0,4,211,5,64,0,156,0,0,3,41,0,0,33,61,0,0,0,35,5,64,0,57,0,0,4,212,6,0,0,65],[0,0,0,0,7,37,0,75,0,0,0,0,7,0,0,25,0,0,0,0,7,6,128,25,0,0,4,212,5,80,1,151],[0,0,0,0,8,5,0,75,0,0,0,0,6,0,128,25,0,0,4,212,5,80,0,156,0,0,0,0,6,7,192,25],[0,0,0,0,5,6,0,75,0,0,3,41,0,0,193,61,0,0,0,4,5,64,0,57,0,0,0,0,5,81,3,79],[0,0,0,0,5,5,4,59,0,10,0,0,0,5,0,29,0,0,4,211,5,80,0,156,0,0,3,41,0,0,33,61],[0,0,0,36,5,64,0,57,0,9,0,0,0,5,0,29,0,0,0,10,4,80,0,41,0,0,0,0,2,36,0,75],[0,0,3,41,0,0,33,61,0,0,0,100,1,16,3,112,0,0,0,0,1,1,4,59,0,8,0,0,0,1,0,29],[0,0,0,1,1,16,0,140,0,0,3,41,0,0,33,61,0,0,0,2,1,48,1,144,0,0,0,1,1,16,2,112],[0,0,3,85,0,0,193,61,0,0,0,0,1,0,4,17,0,0,4,246,1,16,0,156,0,0,0,0,1,0,0,25],[0,0,0,1,1,0,64,57,0,0,0,0,1,1,0,75,0,0,2,60,0,0,97,61,0,0,4,247,1,0,0,65],[0,0,0,128,0,16,4,63,0,0,0,0,1,0,4,17,0,7,0,0,0,1,0,29,0,0,0,132,0,16,4,63],[0,0,4,194,1,0,0,65,0,0,0,0,2,0,4,20,0,0,4,194,3,32,0,156,0,0,0,0,2,1,128,25],[0,0,0,192,1,32,2,16,0,0,4,218,1,16,1,199,0,0,128,3,2,0,0,57,19,2,18,237,0,0,4,15],[0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,4,194,3,48,1,151,0,0,0,32,4,48,0,140],[0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57,0,0,0,31,5,64,1,143,0,0,0,5,6,64,2,114],[0,0,3,118,0,0,97,61,0,0,0,0,7,0,0,25,0,0,0,5,8,112,2,16,0,0,0,0,9,129,3,79],[0,0,0,0,9,9,4,59,0,0,0,128,8,128,0,57,0,0,0,0,0,152,4,53,0,0,0,1,7,112,0,57],[0,0,0,0,8,103,0,75,0,0,3,110,0,0,65,61,0,0,0,0,7,5,0,75,0,0,3,133,0,0,97,61],[0,0,0,5,6,96,2,16,0,0,0,0,7,97,3,79,0,0,0,3,5,80,2,16,0,0,0,128,6,96,0,57],[0,0,0,0,8,6,4,51,0,0,0,0,8,88,1,207,0,0,0,0,8,88,2,47,0,0,0,0,7,7,4,59],[0,0,1,0,5,80,0,137,0,0,0,0,7,87,2,47,0,0,0,0,5,87,1,207,0,0,0,0,5,133,1,159],[0,0,0,0,0,86,4,53,0,0,0,1,2,32,1,144,0,0,5,142,0,0,97,61,0,0,0,31,1,64,0,57],[0,0,0,96,1,16,1,143,0,0,0,128,1,16,1,191,0,0,0,64,0,16,4,63,0,0,0,32,1,48,0,140],[0,0,3,41,0,0,65,61,0,0,0,128,2,0,4,61,0,0,0,7,1,0,0,41,19,2,10,68,0,0,4,15],[0,0,0,0,2,1,0,25,0,7,0,0,0,2,0,29,0,0,0,11,1,0,0,41,0,0,0,8,3,0,0,41],[0,0,0,9,4,0,0,41,0,0,0,10,5,0,0,41,19,2,14,171,0,0,4,15,0,0,0,7,1,0,0,41],[0,0,1,66,0,0,1,61,0,10,0,0,0,2,0,29,0,0,0,0,0,32,4,53,0,0,0,32,0,0,4,63],[0,0,4,194,1,0,0,65,0,0,0,0,2,0,4,20,0,0,4,194,3,32,0,156,0,0,0,0,2,1,128,25],[0,0,0,192,1,32,2,16,0,0,4,219,1,16,1,199,0,0,128,16,2,0,0,57,19,2,18,242,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,3,41,0,0,97,61,0,0,0,64,4,0,4,61,0,0,4,236,2,64,0,156],[0,0,3,195,0,0,161,61,0,0,5,6,1,0,0,65,0,0,0,0,0,16,4,53,0,0,0,65,1,0,0,57],[0,0,3,210,0,0,1,61,0,0,4,214,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57],[0,0,0,132,0,16,4,63,0,0,0,21,1,0,0,57,0,0,0,164,0,16,4,63,0,0,4,215,1,0,0,65],[0,0,0,196,0,16,4,63,0,0,4,216,1,0,0,65,0,0,19,4,0,1,4,48,0,0,4,214,1,0,0,65],[0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63,0,0,0,65,1,0,0,57],[0,0,0,164,0,16,4,63,0,0,4,255,1,0,0,65,0,0,0,196,0,16,4,63,0,0,5,0,1,0,0,65],[0,0,0,228,0,16,4,63,0,0,5,1,1,0,0,65,0,0,5,49,0,0,1,61,0,0,0,0,1,1,4,59],[0,0,0,64,2,64,0,57,0,0,0,64,0,32,4,63,0,0,0,0,1,1,4,26,0,0,0,255,2,16,1,143],[0,0,0,1,3,32,0,140,0,0,3,207,0,0,33,61,0,0,0,0,3,36,4,54,0,0,0,8,1,16,2,112],[0,0,0,255,1,16,1,143,0,0,0,1,2,16,0,140,0,0,5,52,0,0,161,61,0,0,5,6,1,0,0,65],[0,0,0,0,0,16,4,53,0,0,0,33,1,0,0,57,0,0,0,4,0,16,4,63,0,0,4,235,1,0,0,65],[0,0,19,4,0,1,4,48,0,0,0,64,2,0,4,61,0,0,0,31,4,48,1,143,0,0,0,5,5,48,2,114],[0,0,3,226,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25],[0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57],[0,0,0,0,7,86,0,75,0,0,3,218,0,0,65,61,0,0,0,0,6,4,0,75,0,0,3,241,0,0,97,61],[0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16],[0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59],[0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159],[0,0,0,0,0,21,4,53,0,0,5,170,0,0,1,61,0,0,0,5,5,0,0,41,0,0,0,0,4,82,0,73],[0,0,0,132,2,80,0,57,0,0,0,195,4,64,0,138,0,0,4,212,6,0,0,65,0,0,0,0,7,0,0,25],[0,0,0,0,5,0,0,25,0,0,0,5,8,112,2,16,0,0,0,0,8,232,0,25,0,0,0,0,8,129,3,79],[0,0,0,0,8,8,4,59,0,0,0,0,9,72,0,75,0,0,0,0,9,0,0,25,0,0,0,0,9,6,128,25],[0,0,4,212,10,64,1,151,0,0,4,212,11,128,1,151,0,0,0,0,12,171,0,75,0,0,0,0,12,0,0,25],[0,0,0,0,12,6,64,25,0,0,0,0,10,171,1,63,0,0,4,212,10,160,0,156,0,0,0,0,12,9,192,25],[0,0,0,0,9,12,0,75,0,0,3,41,0,0,193,61,0,0,0,0,8,130,0,25,0,0,0,0,8,129,3,79],[0,0,0,0,8,8,4,59,0,0,0,0,5,88,0,25,0,0,0,0,8,133,0,75,0,0,0,0,8,0,0,25],[0,0,0,1,8,0,64,57,0,0,0,1,8,128,1,144,0,0,7,58,0,0,193,61,0,0,0,1,7,112,0,57],[0,0,0,0,8,215,0,75,0,0,3,249,0,0,65,61,0,0,0,0,1,0,4,22,0,0,0,0,1,81,0,75],[0,0,5,38,0,0,193,61,0,4,4,213,0,48,1,155,0,0,4,212,8,0,0,65,0,0,0,0,9,0,0,25],[0,8,0,0,0,13,0,29,0,7,0,0,0,14,0,29,0,0,0,5,1,144,2,16,0,0,0,0,2,225,0,25],[0,0,0,17,1,0,3,103,0,0,0,0,2,33,3,79,0,0,0,0,2,2,4,59,0,0,0,5,3,0,0,41],[0,0,0,0,3,48,0,121,0,0,0,195,3,48,0,138,0,0,0,0,4,50,0,75,0,0,0,0,4,0,0,25],[0,0,0,0,4,8,128,25,0,0,4,212,3,48,1,151,0,0,4,212,5,32,1,151,0,0,0,0,6,53,0,75],[0,0,0,0,6,0,0,25,0,0,0,0,6,8,64,25,0,0,0,0,3,53,1,63,0,0,4,212,3,48,0,156],[0,0,0,0,6,4,192,25,0,0,0,0,3,6,0,75,0,0,3,41,0,0,193,61,0,11,0,0,0,9,0,29],[0,0,0,0,2,226,0,25,0,10,0,0,0,2,0,29,0,0,0,96,2,32,0,57,0,0,0,0,1,33,3,79],[0,0,0,0,1,1,4,59,0,6,0,0,0,1,0,29,0,0,4,221,1,0,0,65,0,0,0,0,0,16,4,57],[0,0,0,0,1,0,4,16,0,9,0,0,0,1,0,29,0,0,0,4,0,16,4,67,0,0,0,0,1,0,4,20],[0,0,4,194,2,16,0,156,0,0,4,194,1,0,128,65,0,0,0,192,1,16,2,16,0,0,4,222,1,16,1,199],[0,0,128,2,2,0,0,57,19,2,18,242,0,0,4,15,0,0,0,1,2,32,1,144,0,0,9,3,0,0,97,61],[0,0,0,0,1,1,4,59,0,0,0,0,1,1,0,75,0,0,0,8,13,0,0,41,0,0,0,7,14,0,0,41],[0,0,4,212,8,0,0,65,0,0,0,11,9,0,0,41,0,0,0,10,11,0,0,41,0,0,3,41,0,0,97,61],[0,0,0,64,10,0,4,61,0,0,5,3,1,0,0,65,0,0,0,0,0,26,4,53,0,0,0,4,1,160,0,57],[0,0,0,64,2,0,0,57,0,0,0,0,0,33,4,53,0,0,0,17,1,0,3,103,0,0,0,0,2,177,3,79],[0,0,0,0,2,2,4,59,0,0,0,68,3,160,0,57,0,0,0,0,0,35,4,53,0,0,0,32,2,176,0,57],[0,0,0,0,3,33,3,79,0,0,0,0,3,3,4,59,0,0,4,213,4,48,0,156,0,0,3,41,0,0,33,61],[0,0,0,100,4,160,0,57,0,0,0,0,0,52,4,53,0,0,0,32,2,32,0,57,0,0,0,0,3,33,3,79],[0,0,0,0,3,3,4,59,0,0,0,0,4,3,0,75,0,0,0,0,4,0,0,25,0,0,0,1,4,0,192,57],[0,0,0,0,4,67,0,75,0,0,3,41,0,0,193,61,0,0,0,132,4,160,0,57,0,0,0,0,0,52,4,53],[0,0,0,32,3,32,0,57,0,0,0,0,3,49,3,79,0,0,0,0,3,3,4,59,0,0,0,164,4,160,0,57],[0,0,0,0,0,52,4,53,0,0,0,64,2,32,0,57,0,0,0,0,2,33,3,79,0,0,0,0,2,2,4,59],[0,0,0,0,3,0,0,49,0,0,0,0,4,179,0,73,0,0,0,31,4,64,0,138,0,0,0,0,5,66,0,75],[0,0,0,0,5,0,0,25,0,0,0,0,5,8,128,25,0,0,4,212,4,64,1,151,0,0,4,212,6,32,1,151],[0,0,0,0,7,70,0,75,0,0,0,0,7,0,0,25,0,0,0,0,7,8,64,25,0,0,0,0,4,70,1,63],[0,0,4,212,4,64,0,156,0,0,0,0,7,5,192,25,0,0,0,0,4,7,0,75,0,0,3,41,0,0,193,61],[0,0,0,0,4,178,0,25,0,0,0,0,2,65,3,79,0,0,0,0,2,2,4,59,0,0,4,211,5,32,0,156],[0,0,3,41,0,0,33,61,0,0,0,32,4,64,0,57,0,0,0,0,3,35,0,73,0,0,0,0,5,52,0,75],[0,0,0,0,5,0,0,25,0,0,0,0,5,8,32,25,0,0,4,212,3,48,1,151,0,0,4,212,6,64,1,151],[0,0,0,0,7,54,0,75,0,0,0,0,7,0,0,25,0,0,0,0,7,8,64,25,0,0,0,0,3,54,1,63],[0,0,4,212,3,48,0,156,0,0,0,0,7,5,192,25,0,0,0,0,3,7,0,75,0,0,3,41,0,0,193,61],[0,0,0,196,3,160,0,57,0,0,0,160,5,0,0,57,0,0,0,0,0,83,4,53,0,0,0,228,3,160,0,57],[0,0,0,0,0,35,4,53,0,0,0,0,3,65,3,79,0,0,1,4,1,160,0,57,0,0,0,5,4,32,2,114],[0,0,4,170,0,0,97,61,0,0,0,0,5,0,0,25,0,0,0,5,6,80,2,16,0,0,0,0,7,97,0,25],[0,0,0,0,6,99,3,79,0,0,0,0,6,6,4,59,0,0,0,0,0,103,4,53,0,0,0,1,5,80,0,57],[0,0,0,0,6,69,0,75,0,0,4,162,0,0,65,61,0,0,0,31,5,32,1,144,0,0,4,185,0,0,97,61],[0,0,0,5,4,64,2,16,0,0,0,0,3,67,3,79,0,0,0,0,4,65,0,25,0,0,0,3,5,80,2,16],[0,0,0,0,6,4,4,51,0,0,0,0,6,86,1,207,0,0,0,0,6,86,2,47,0,0,0,0,3,3,4,59],[0,0,1,0,5,80,0,137,0,0,0,0,3,83,2,47,0,0,0,0,3,83,1,207,0,0,0,0,3,99,1,159],[0,0,0,0,0,52,4,53,0,0,0,0,1,18,0,25,0,0,0,0,0,1,4,53,0,0,0,36,1,160,0,57],[0,0,0,4,3,0,0,41,0,0,0,0,0,49,4,53,0,0,0,0,1,0,4,20,0,0,0,9,4,0,0,41],[0,0,0,4,3,64,0,140,0,0,4,229,0,0,97,61,0,0,0,31,2,32,0,57,0,0,0,32,3,0,0,138],[0,0,0,0,2,50,1,111,0,0,5,4,3,32,0,156,0,0,5,4,2,0,128,65,0,0,4,194,3,160,0,156],[0,0,4,194,5,0,0,65,0,10,0,0,0,10,0,29,0,0,0,0,3,5,0,25,0,0,0,0,3,10,64,25],[0,0,0,64,3,48,2,16,0,0,0,96,2,32,2,16,0,0,0,0,2,50,1,159,0,0,4,194,3,16,0,156],[0,0,0,0,1,5,128,25,0,0,0,192,1,16,2,16,0,0,0,0,1,18,1,159,0,0,5,5,1,16,0,65],[0,0,0,6,3,0,0,41,0,0,0,0,2,3,0,75,0,0,4,220,0,0,97,61,0,0,4,243,1,16,1,199],[0,0,128,9,2,0,0,57,0,0,0,0,5,0,0,25,19,2,18,237,0,0,4,15,0,0,4,222,0,0,1,61],[0,0,0,0,2,4,0,25,19,2,18,237,0,0,4,15,0,0,0,1,2,32,1,144,0,0,0,8,13,0,0,41],[0,0,0,7,14,0,0,41,0,0,4,212,8,0,0,65,0,0,0,11,9,0,0,41,0,0,0,10,10,0,0,41],[0,0,6,211,0,0,97,61,0,0,4,211,1,160,0,156,0,0,3,169,0,0,33,61,0,0,0,64,0,160,4,63],[0,0,0,1,9,144,0,57,0,0,0,0,1,217,0,75,0,0,4,30,0,0,65,61,0,0,0,97,0,0,1,61],[0,0,0,64,2,0,4,61,0,0,0,31,4,48,1,143,0,0,0,5,5,48,2,114,0,0,4,249,0,0,97,61],[0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79],[0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75],[0,0,4,241,0,0,65,61,0,0,0,0,6,4,0,75,0,0,5,8,0,0,97,61,0,0,0,5,5,80,2,16],[0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51],[0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137],[0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53],[0,0,5,170,0,0,1,61,0,0,0,64,2,0,4,61,0,0,0,31,4,48,1,143,0,0,0,5,5,48,2,114],[0,0,5,22,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25],[0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57],[0,0,0,0,7,86,0,75,0,0,5,14,0,0,65,61,0,0,0,0,6,4,0,75,0,0,5,170,0,0,97,61],[0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16],[0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59],[0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159],[0,0,0,0,0,21,4,53,0,0,5,170,0,0,1,61,0,0,4,214,1,0,0,65,0,0,0,128,0,16,4,63],[0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63,0,0,0,69,1,0,0,57,0,0,0,164,0,16,4,63],[0,0,5,7,1,0,0,65,0,0,0,196,0,16,4,63,0,0,5,8,1,0,0,65,0,0,0,228,0,16,4,63],[0,0,5,9,1,0,0,65,0,0,1,4,0,16,4,63,0,0,5,2,1,0,0,65,0,0,19,4,0,1,4,48],[0,9,0,0,0,4,0,29,0,0,0,0,0,19,4,53,0,0,0,11,2,0,0,41,0,0,0,1,2,32,0,140],[0,0,6,84,0,0,193,61,0,0,0,0,1,1,0,75,0,0,6,84,0,0,193,61,0,0,0,1,1,0,0,57],[0,11,0,0,0,3,0,29,0,8,0,0,0,1,0,29,0,0,0,0,0,19,4,53,0,0,0,10,1,0,0,41],[0,0,4,213,1,16,1,151,0,0,0,0,0,16,4,53,0,0,0,32,0,0,4,63,0,0,4,194,1,0,0,65],[0,0,0,0,2,0,4,20,0,0,4,194,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16],[0,0,4,219,1,16,1,199,0,0,128,16,2,0,0,57,19,2,18,242,0,0,4,15,0,0,0,1,2,32,1,144],[0,0,3,41,0,0,97,61,0,0,0,9,2,0,0,41,0,0,0,0,2,2,4,51,0,0,0,1,3,32,0,140],[0,0,0,11,5,0,0,41,0,0,3,207,0,0,33,61,0,0,0,0,1,1,4,59,0,0,0,0,3,1,4,26],[0,0,1,0,4,0,0,138,0,0,0,0,3,67,1,111,0,0,0,0,2,35,1,159,0,0,0,0,0,33,4,27],[0,0,0,0,3,5,4,51,0,0,0,1,4,48,0,140,0,0,3,207,0,0,33,61,0,0,4,220,2,32,1,151],[0,0,0,8,3,48,2,16,0,0,255,0,3,48,1,143,0,0,0,0,2,35,1,159,0,0,0,0,0,33,4,27],[0,0,0,64,1,0,4,61,0,0,0,8,2,0,0,41,0,0,0,0,0,33,4,53,0,0,4,194,2,0,0,65],[0,0,0,0,3,0,4,20,0,0,4,194,4,48,0,156,0,0,0,0,3,2,128,25,0,0,4,194,4,16,0,156],[0,0,0,0,1,2,128,25,0,0,0,64,1,16,2,16,0,0,0,192,2,48,2,16,0,0,0,0,1,18,1,159],[0,0,4,253,1,16,1,199,0,0,128,13,2,0,0,57,0,0,0,2,3,0,0,57,0,0,4,254,4,0,0,65],[0,0,0,93,0,0,1,61,0,0,0,64,2,0,4,61,0,0,0,31,4,48,1,143,0,0,0,5,5,48,2,114],[0,0,5,126,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25],[0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57],[0,0,0,0,7,86,0,75,0,0,5,118,0,0,65,61,0,0,0,0,6,4,0,75,0,0,5,141,0,0,97,61],[0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16],[0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59],[0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159],[0,0,0,0,0,21,4,53,0,0,5,170,0,0,1,61,0,0,0,64,2,0,4,61,0,0,0,31,4,48,1,143],[0,0,0,5,5,48,2,114,0,0,5,155,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16],[0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53],[0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,5,147,0,0,65,61,0,0,0,0,6,4,0,75],[0,0,5,170,0,0,97,61,0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25],[0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47],[0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207],[0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,4,194,1,0,0,65,0,0,4,194,4,32,0,156],[0,0,0,0,2,1,128,25,0,0,0,64,1,32,2,16,0,0,0,96,2,48,2,16,0,0,0,0,1,33,1,159],[0,0,19,4,0,1,4,48,0,0,0,192,2,16,0,57,0,0,0,64,0,32,4,63,0,0,0,5,2,0,0,41],[0,0,0,0,0,2,4,53,0,0,0,160,1,16,0,57,0,4,0,0,0,1,0,29,0,0,0,0,0,1,4,53],[0,0,0,8,1,0,0,41,0,0,0,32,1,16,0,57,0,3,0,0,0,1,0,29,0,0,0,17,1,16,3,103],[0,0,0,0,1,1,4,59,0,8,0,0,0,1,0,29,0,0,4,213,1,16,0,156,0,0,3,41,0,0,33,61],[0,0,0,8,1,0,0,41,0,0,0,0,0,16,4,53,0,0,0,32,0,0,4,63,0,0,4,194,1,0,0,65],[0,0,0,0,2,0,4,20,0,0,4,194,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16],[0,0,4,219,1,16,1,199,0,0,128,16,2,0,0,57,19,2,18,242,0,0,4,15,0,0,0,1,2,32,1,144],[0,0,3,41,0,0,97,61,0,0,0,5,2,0,0,41,0,0,0,0,2,2,4,51,0,0,0,1,3,32,0,140],[0,0,3,207,0,0,33,61,0,0,0,0,1,1,4,59,0,0,0,0,3,1,4,26,0,0,1,0,4,0,0,138],[0,0,0,0,3,67,1,111,0,0,0,0,2,35,1,159,0,0,0,0,0,33,4,27,0,0,0,4,3,0,0,41],[0,0,0,0,3,3,4,51,0,0,0,1,4,48,0,140,0,0,3,207,0,0,33,61,0,0,4,220,2,32,1,151],[0,0,0,8,3,48,2,16,0,0,255,0,3,48,1,143,0,0,0,0,2,35,1,159,0,0,0,0,0,33,4,27],[0,0,0,3,1,0,0,41,0,0,0,96,2,16,0,57,0,0,0,17,1,0,3,103,0,0,0,0,3,33,3,79],[0,0,0,0,3,3,4,59,0,0,0,10,4,0,0,41,0,0,0,35,4,64,0,138,0,0,4,212,5,0,0,65],[0,0,0,0,6,67,0,75,0,0,0,0,6,0,0,25,0,0,0,0,6,5,128,25,0,0,4,212,4,64,1,151],[0,0,4,212,7,48,1,151,0,0,0,0,8,71,0,75,0,0,0,0,5,0,128,25,0,0,0,0,4,71,1,63],[0,0,4,212,4,64,0,156,0,0,0,0,5,6,192,25,0,0,0,0,4,5,0,75,0,0,3,41,0,0,193,61],[0,0,0,11,3,48,0,41,0,0,0,4,4,48,0,57,0,0,0,0,4,65,3,79,0,0,0,0,4,4,4,59],[0,11,0,0,0,4,0,29,0,0,4,211,4,64,0,156,0,0,3,41,0,0,33,61,0,0,0,11,4,0,0,41],[0,0,0,0,4,64,0,121,0,0,0,36,6,48,0,57,0,0,4,212,3,0,0,65,0,0,0,0,5,70,0,75],[0,0,0,0,5,0,0,25,0,0,0,0,5,3,32,25,0,0,4,212,4,64,1,151,0,10,0,0,0,6,0,29],[0,0,4,212,6,96,1,151,0,0,0,0,7,70,0,75,0,0,0,0,3,0,128,25,0,0,0,0,4,70,1,63],[0,0,4,212,4,64,0,156,0,0,0,0,3,5,192,25,0,0,0,0,3,3,0,75,0,0,3,41,0,0,193,61],[0,0,0,64,2,32,0,138,0,0,0,0,1,33,3,79,0,0,0,0,1,1,4,59,0,0,0,0,2,1,0,75],[0,0,0,0,2,0,0,25,0,0,0,1,2,0,192,57,0,0,0,0,2,33,0,75,0,0,3,41,0,0,193,61],[0,0,0,0,2,0,4,22,0,5,0,0,0,2,0,29,0,0,0,0,1,1,0,75,0,0,6,243,0,0,193,61],[0,0,0,5,1,0,0,107,0,0,7,62,0,0,193,61,0,0,4,221,1,0,0,65,0,0,0,0,0,16,4,57],[0,0,128,2,2,0,0,57,0,0,0,4,0,32,4,67,0,0,4,194,1,0,0,65,0,0,0,0,3,0,4,20],[0,0,4,194,4,48,0,156,0,0,0,0,3,1,128,25,0,0,0,192,1,48,2,16,0,0,4,222,1,16,1,199],[19,2,18,242,0,0,4,15,0,0,0,1,2,32,1,144,0,0,9,3,0,0,97,61,0,0,0,0,1,1,4,59],[0,0,0,0,1,1,0,75,0,0,3,41,0,0,97,61,0,0,0,64,4,0,4,61,0,0,0,36,1,64,0,57],[0,0,0,7,2,0,0,41,0,0,0,0,0,33,4,53,0,0,4,242,1,0,0,65,0,0,0,0,0,20,4,53],[0,0,0,4,1,64,0,57,0,0,0,8,2,0,0,41,0,0,0,0,0,33,4,53,0,0,4,194,1,0,0,65],[0,0,0,0,2,0,4,20,0,0,4,194,3,32,0,156,0,0,0,0,2,1,128,25,0,0,4,194,3,64,0,156],[0,11,0,0,0,4,0,29,0,0,0,0,1,4,64,25,0,0,0,64,1,16,2,16,0,0,0,192,2,32,2,16],[0,0,0,0,1,18,1,159,0,0,4,228,1,16,1,199,0,0,128,2,2,0,0,57,19,2,18,237,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,7,166,0,0,97,61,0,0,0,11,1,0,0,41,0,0,4,211,1,16,0,156],[0,0,3,169,0,0,33,61,0,0,0,11,1,0,0,41,0,0,0,64,0,16,4,63,0,0,4,194,1,0,0,65],[0,0,0,0,2,0,4,20,0,0,4,194,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16],[0,0,4,243,1,16,1,199,0,0,128,13,2,0,0,57,0,0,0,4,3,0,0,57,0,0,4,244,4,0,0,65],[0,0,0,9,5,0,0,41,0,0,0,7,6,0,0,41,0,0,0,8,7,0,0,41,0,0,0,94,0,0,1,61],[0,0,0,64,1,0,4,61,0,0,0,132,2,16,0,57,0,0,4,249,3,0,0,65,0,0,0,0,0,50,4,53],[0,0,0,100,2,16,0,57,0,0,4,250,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,68,2,16,0,57],[0,0,4,251,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,67,3,0,0,57],[0,0,0,0,0,50,4,53,0,0,4,214,2,0,0,65,0,0,0,0,0,33,4,53,0,0,0,4,2,16,0,57],[0,0,0,32,3,0,0,57,0,0,0,0,0,50,4,53,0,0,4,194,2,0,0,65,0,0,4,194,3,16,0,156],[0,0,0,0,1,2,128,25,0,0,0,64,1,16,2,16,0,0,4,252,1,16,1,199,0,0,19,4,0,1,4,48],[0,0,0,64,4,0,4,61,0,10,0,0,0,4,0,29,0,0,5,11,1,0,0,65,0,0,0,0,0,20,4,53],[0,0,0,4,1,64,0,57,0,0,0,11,2,0,0,41,0,0,0,0,0,33,4,53,0,0,4,194,1,0,0,65],[0,0,0,0,2,0,4,20,0,0,4,194,3,32,0,156,0,0,0,0,2,1,128,25,0,0,4,194,3,64,0,156],[0,0,0,0,1,4,64,25,0,0,0,64,1,16,2,16,0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159],[0,0,4,235,1,16,1,199,0,0,128,2,2,0,0,57,19,2,18,242,0,0,4,15,0,0,0,10,10,0,0,41],[0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,4,194,3,48,1,151,0,0,0,32,4,48,0,140],[0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57,0,0,0,31,5,64,1,143,0,0,0,5,6,64,2,114],[0,0,6,146,0,0,97,61,0,0,0,0,7,0,0,25,0,0,0,5,8,112,2,16,0,0,0,0,9,138,0,25],[0,0,0,0,8,129,3,79,0,0,0,0,8,8,4,59,0,0,0,0,0,137,4,53,0,0,0,1,7,112,0,57],[0,0,0,0,8,103,0,75,0,0,6,138,0,0,65,61,0,0,0,0,9,10,0,25,0,0,0,0,7,5,0,75],[0,0,6,162,0,0,97,61,0,0,0,5,6,96,2,16,0,0,0,0,7,97,3,79,0,0,0,0,6,105,0,25],[0,0,0,3,5,80,2,16,0,0,0,0,8,6,4,51,0,0,0,0,8,88,1,207,0,0,0,0,8,88,2,47],[0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137,0,0,0,0,7,87,2,47,0,0,0,0,5,87,1,207],[0,0,0,0,5,133,1,159,0,0,0,0,0,86,4,53,0,0,0,1,2,32,1,144,0,0,6,182,0,0,97,61],[0,0,0,31,1,64,0,57,0,0,0,96,2,16,1,143,0,0,0,0,1,146,0,25,0,0,0,0,2,33,0,75],[0,0,0,0,2,0,0,25,0,0,0,1,2,0,64,57,0,0,4,211,4,16,0,156,0,0,3,169,0,0,33,61],[0,0,0,1,2,32,1,144,0,0,3,169,0,0,193,61,0,0,0,64,0,16,4,63,0,0,0,32,1,48,0,140],[0,0,3,41,0,0,65,61,0,0,0,0,1,9,4,51,0,0,0,0,1,1,0,75,0,0,0,0,1,0,0,25],[0,0,0,1,1,0,96,57,0,0,2,235,0,0,1,61,0,0,0,64,2,0,4,61,0,0,0,31,4,48,1,143],[0,0,0,5,5,48,2,114,0,0,6,195,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16],[0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53],[0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,6,187,0,0,65,61,0,0,0,0,6,4,0,75],[0,0,6,210,0,0,97,61,0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25],[0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47],[0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207],[0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,5,170,0,0,1,61,0,0,0,64,2,0,4,61],[0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,0,31,4,48,1,143,0,0,4,194,3,48,1,151],[0,0,0,5,5,48,2,114,0,0,6,227,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16],[0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53],[0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,6,219,0,0,65,61,0,0,0,0,6,4,0,75],[0,0,6,242,0,0,97,61,0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25],[0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47],[0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207],[0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,5,170,0,0,1,61,0,0,0,5,1,0,0,107],[0,0,7,83,0,0,193,61,0,0,4,221,1,0,0,65,0,0,0,0,0,16,4,57,0,0,128,2,2,0,0,57],[0,0,0,4,0,32,4,67,0,0,4,194,1,0,0,65,0,0,0,0,3,0,4,20,0,0,4,194,4,48,0,156],[0,0,0,0,3,1,128,25,0,0,0,192,1,48,2,16,0,0,4,222,1,16,1,199,19,2,18,242,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,9,3,0,0,97,61,0,0,0,0,1,1,4,59,0,0,0,0,1,1,0,75],[0,0,3,41,0,0,97,61,0,0,0,64,4,0,4,61,0,0,4,225,1,0,0,65,0,0,0,0,0,20,4,53],[0,0,0,4,2,64,0,57,0,0,0,8,1,0,0,41,0,4,0,0,0,2,0,29,0,0,0,0,0,18,4,53],[0,0,0,7,1,0,0,41,0,0,4,226,1,16,1,151,0,0,4,227,1,16,1,199,0,0,0,36,2,64,0,57],[0,3,0,0,0,2,0,29,0,0,0,0,0,18,4,53,0,0,4,194,1,0,0,65,0,0,0,0,2,0,4,20],[0,0,4,194,3,32,0,156,0,0,0,0,2,1,128,25,0,0,4,194,3,64,0,156,0,6,0,0,0,4,0,29],[0,0,0,0,1,4,64,25,0,2,0,64,0,16,2,24,0,0,0,192,1,32,2,16,0,0,0,2,1,16,1,175],[0,0,4,228,1,16,1,199,0,0,128,2,2,0,0,57,0,1,0,0,0,2,0,29,19,2,18,237,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,7,134,0,0,97,61,0,0,0,6,1,0,0,41,0,0,4,211,1,16,0,156],[0,0,3,169,0,0,33,61,0,0,0,6,1,0,0,41,0,0,0,64,0,16,4,63,0,0,0,5,1,0,0,107],[0,0,7,44,0,0,97,61,0,0,0,5,1,0,0,41,0,0,4,229,1,16,1,151,0,0,0,0,0,1,4,23],[0,0,0,10,4,0,0,41,0,0,4,194,2,64,1,151,0,0,0,0,1,0,4,20,0,0,0,17,3,0,3,103],[0,1,0,0,0,35,3,85,0,0,0,11,4,64,0,41,0,0,0,11,5,64,0,108,0,0,0,0,5,0,0,25],[0,0,0,1,5,0,64,57,0,0,0,1,5,80,1,144,0,0,7,58,0,0,193,61,0,0,0,0,5,0,0,49],[0,0,0,0,6,69,0,75,0,0,7,230,0,0,129,61,0,0,5,6,1,0,0,65,0,0,0,0,0,16,4,53],[0,0,0,17,1,0,0,57,0,0,3,210,0,0,1,61,0,0,0,64,1,0,4,61,0,0,0,100,2,16,0,57],[0,0,4,239,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,68,2,16,0,57,0,0,4,240,3,0,0,65],[0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,56,3,0,0,57,0,0,0,0,0,50,4,53],[0,0,4,214,2,0,0,65,0,0,0,0,0,33,4,53,0,0,0,4,2,16,0,57,0,0,0,32,3,0,0,57],[0,0,0,0,0,50,4,53,0,0,4,194,2,0,0,65,0,0,4,194,3,16,0,156,0,0,0,0,1,2,128,25],[0,0,0,64,1,16,2,16,0,0,4,241,1,16,1,199,0,0,19,4,0,1,4,48,0,0,4,221,1,0,0,65],[0,0,0,0,0,16,4,57,0,0,128,10,1,0,0,57,0,0,0,4,0,16,4,67,0,0,4,194,1,0,0,65],[0,0,0,0,2,0,4,20,0,0,4,194,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16],[0,0,4,222,1,16,1,199,0,0,128,2,2,0,0,57,19,2,18,242,0,0,4,15,0,0,0,1,2,32,1,144],[0,0,9,3,0,0,97,61,0,0,0,0,1,1,4,59,0,0,0,0,1,1,0,75,0,0,3,41,0,0,97,61],[0,0,0,64,4,0,4,61,0,0,0,68,1,64,0,57,0,0,0,5,2,0,0,41,0,0,0,0,0,33,4,53],[0,0,0,36,1,64,0,57,0,0,0,8,2,0,0,41,0,0,0,0,0,33,4,53,0,0,4,223,1,0,0,65],[0,0,0,0,0,20,4,53,0,0,0,6,1,0,0,41,0,0,4,213,1,16,1,151,0,0,0,4,2,64,0,57],[0,0,0,0,0,18,4,53,0,0,4,194,1,0,0,65,0,0,0,0,2,0,4,20,0,0,4,194,3,32,0,156],[0,0,0,0,2,1,128,25,0,0,4,194,3,64,0,156,0,6,0,0,0,4,0,29,0,0,0,0,1,4,64,25],[0,0,0,64,1,16,2,16,0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159,0,0,4,224,1,16,1,199],[0,0,128,10,2,0,0,57,19,2,18,237,0,0,4,15,0,0,0,1,2,32,1,144,0,0,7,198,0,0,97,61],[0,0,0,6,1,0,0,41,0,0,4,211,1,16,0,156,0,0,3,169,0,0,33,61,0,0,0,6,1,0,0,41],[0,0,0,64,0,16,4,63,0,0,6,245,0,0,1,61,0,0,0,64,2,0,4,61,0,0,0,0,3,1,0,25],[0,0,0,96,3,48,2,112,0,0,0,31,4,48,1,143,0,0,4,194,3,48,1,151,0,0,0,5,5,48,2,114],[0,0,7,150,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25],[0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57],[0,0,0,0,7,86,0,75,0,0,7,142,0,0,65,61,0,0,0,0,6,4,0,75,0,0,7,165,0,0,97,61],[0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16],[0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59],[0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159],[0,0,0,0,0,21,4,53,0,0,5,170,0,0,1,61,0,0,0,64,2,0,4,61,0,0,0,0,3,1,0,25],[0,0,0,96,3,48,2,112,0,0,0,31,4,48,1,143,0,0,4,194,3,48,1,151,0,0,0,5,5,48,2,114],[0,0,7,182,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25],[0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57],[0,0,0,0,7,86,0,75,0,0,7,174,0,0,65,61,0,0,0,0,6,4,0,75,0,0,7,197,0,0,97,61],[0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16],[0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59],[0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159],[0,0,0,0,0,21,4,53,0,0,5,170,0,0,1,61,0,0,0,64,2,0,4,61,0,0,0,0,3,1,0,25],[0,0,0,96,3,48,2,112,0,0,0,31,4,48,1,143,0,0,4,194,3,48,1,151,0,0,0,5,5,48,2,114],[0,0,7,214,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25],[0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57],[0,0,0,0,7,86,0,75,0,0,7,206,0,0,65,61,0,0,0,0,6,4,0,75,0,0,7,229,0,0,97,61],[0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16],[0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59],[0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159],[0,0,0,0,0,21,4,53,0,0,5,170,0,0,1,61,0,0,0,0,2,35,3,79,0,0,0,0,3,69,0,73],[0,0,4,194,3,48,1,151,0,1,0,0,0,50,3,229,0,0,4,230,4,16,0,156,0,0,7,251,0,0,65,61],[0,0,4,214,1,0,0,65,0,0,0,6,2,0,0,41,0,0,0,0,0,18,4,53,0,0,0,32,1,0,0,57],[0,0,0,4,3,0,0,41,0,0,0,0,0,19,4,53,0,0,0,8,1,0,0,57,0,0,0,3,3,0,0,41],[0,0,0,0,0,19,4,53,0,0,0,68,1,32,0,57,0,0,4,238,2,0,0,65,0,0,0,0,0,33,4,53],[0,0,0,2,1,0,0,41,0,0,4,224,1,16,1,199,0,0,19,4,0,1,4,48,0,0,0,0,2,50,3,223],[0,0,0,192,1,16,2,16,0,0,4,231,1,16,1,151,0,0,4,232,1,16,1,199,0,1,0,0,0,18,3,181],[0,0,0,0,1,18,3,175,0,0,0,8,2,0,0,41,0,0,0,9,13,0,0,41,19,2,18,252,0,0,4,15],[0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,4,194,3,48,1,151,0,0,0,1,2,32,1,144],[0,0,9,4,0,0,97,61,0,0,0,63,2,48,0,57,0,0,4,233,2,32,1,151,0,0,0,64,4,0,4,61],[0,0,0,0,2,36,0,25,0,11,0,0,0,4,0,29,0,0,0,0,4,66,0,75,0,0,0,0,4,0,0,25],[0,0,0,1,4,0,64,57,0,0,4,211,5,32,0,156,0,0,3,169,0,0,33,61,0,0,0,1,4,64,1,144],[0,0,3,169,0,0,193,61,0,0,0,64,0,32,4,63,0,0,0,11,2,0,0,41,0,0,0,0,8,50,4,54],[0,0,0,31,2,48,0,57,0,0,0,5,2,32,2,114,0,0,8,38,0,0,97,61,0,0,0,0,4,0,0,49],[0,0,0,17,4,64,3,103,0,0,0,0,5,0,0,25,0,0,0,5,6,80,2,16,0,0,0,0,7,104,0,25],[0,0,0,0,6,100,3,79,0,0,0,0,6,6,4,59,0,0,0,0,0,103,4,53,0,0,0,1,5,80,0,57],[0,0,0,0,6,37,0,75,0,0,8,30,0,0,65,61,0,6,0,0,0,8,0,29,0,0,0,0,2,0,0,75],[0,0,8,41,0,0,97,61,0,0,0,31,2,48,1,143,0,0,0,5,3,48,2,114,0,0,0,6,7,0,0,41],[0,0,8,54,0,0,97,61,0,0,0,0,4,0,0,25,0,0,0,5,5,64,2,16,0,0,0,0,6,87,0,25],[0,0,0,0,5,81,3,79,0,0,0,0,5,5,4,59,0,0,0,0,0,86,4,53,0,0,0,1,4,64,0,57],[0,0,0,0,5,52,0,75,0,0,8,46,0,0,65,61,0,0,0,0,4,2,0,75,0,0,8,69,0,0,97,61],[0,0,0,5,3,48,2,16,0,0,0,0,1,49,3,79,0,0,0,6,3,48,0,41,0,0,0,3,2,32,2,16],[0,0,0,0,4,3,4,51,0,0,0,0,4,36,1,207,0,0,0,0,4,36,2,47,0,0,0,0,1,1,4,59],[0,0,1,0,2,32,0,137,0,0,0,0,1,33,2,47,0,0,0,0,1,33,1,207,0,0,0,0,1,65,1,159],[0,0,0,0,0,19,4,53,0,0,4,221,1,0,0,65,0,0,0,0,0,16,4,57,0,0,0,1,2,0,0,41],[0,0,0,4,0,32,4,67,0,0,4,194,1,0,0,65,0,0,0,0,4,0,4,20,0,0,4,194,3,64,0,156],[0,0,0,0,4,1,128,25,0,0,0,192,1,64,2,16,0,0,4,222,1,16,1,199,19,2,18,242,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,9,3,0,0,97,61,0,0,0,0,1,1,4,59,0,0,0,0,1,1,0,75],[0,0,3,41,0,0,97,61,0,0,0,64,4,0,4,61,0,0,4,234,1,0,0,65,0,0,0,0,0,20,4,53],[0,0,0,4,1,64,0,57,0,0,0,8,2,0,0,41,0,0,0,0,0,33,4,53,0,0,4,194,1,0,0,65],[0,0,0,0,2,0,4,20,0,0,4,194,3,32,0,156,0,0,0,0,2,1,128,25,0,0,4,194,3,64,0,156],[0,10,0,0,0,4,0,29,0,0,0,0,1,4,64,25,0,0,0,64,1,16,2,16,0,0,0,192,2,32,2,16],[0,0,0,0,1,18,1,159,0,0,4,235,1,16,1,199,0,0,128,2,2,0,0,57,19,2,18,237,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,9,31,0,0,97,61,0,0,0,10,1,0,0,41,0,0,4,211,1,16,0,156],[0,0,3,169,0,0,33,61,0,0,0,10,1,0,0,41,0,0,0,64,0,16,4,63,0,0,0,11,1,0,0,41],[0,0,0,0,1,1,4,51,0,0,4,212,2,0,0,65,0,0,0,32,3,16,0,140,0,0,0,0,3,0,0,25],[0,0,0,0,3,2,64,25,0,0,4,212,4,16,1,151,0,0,0,0,5,4,0,75,0,0,0,0,2,0,160,25],[0,0,4,212,4,64,0,156,0,0,0,0,2,3,192,25,0,0,0,0,2,2,0,75,0,0,3,41,0,0,193,61],[0,0,0,6,2,0,0,41,0,0,0,0,2,2,4,51,0,0,4,211,3,32,0,156,0,0,3,41,0,0,33,61],[0,0,0,6,1,16,0,41,0,0,0,6,2,32,0,41,0,0,0,31,3,32,0,57,0,0,4,212,4,0,0,65],[0,0,0,0,5,19,0,75,0,0,0,0,5,0,0,25,0,0,0,0,5,4,128,25,0,0,4,212,3,48,1,151],[0,0,4,212,6,16,1,151,0,0,0,0,7,99,0,75,0,0,0,0,4,0,128,25,0,0,0,0,3,99,1,63],[0,0,4,212,3,48,0,156,0,0,0,0,4,5,192,25,0,0,0,0,3,4,0,75,0,0,3,41,0,0,193,61],[0,0,0,0,35,2,4,52,0,0,4,211,4,48,0,156,0,0,3,169,0,0,33,61,0,0,0,5,4,48,2,16],[0,0,0,63,4,64,0,57,0,0,0,32,5,0,0,138,0,0,0,0,4,84,1,111,0,0,0,10,4,64,0,41],[0,0,4,211,5,64,0,156,0,0,3,169,0,0,33,61,0,0,0,64,0,64,4,63,0,0,0,10,4,0,0,41],[0,0,0,0,0,52,4,53,0,0,0,6,3,48,2,16,0,0,0,0,3,35,0,25,0,0,0,0,4,19,0,75],[0,0,3,41,0,0,33,61,0,0,0,0,4,50,0,75,0,0,8,191,0,0,129,61,0,0,4,212,4,0,0,65],[0,0,0,10,5,0,0,41,0,0,0,0,6,33,0,73,0,0,0,64,7,96,0,140,0,0,0,0,7,0,0,25],[0,0,0,0,7,4,64,25,0,0,4,212,6,96,1,151,0,0,0,0,8,6,0,75,0,0,0,0,8,0,0,25],[0,0,0,0,8,4,32,25,0,0,4,212,6,96,0,156,0,0,0,0,8,7,192,25,0,0,0,0,6,8,0,75],[0,0,3,41,0,0,193,61,0,0,0,64,6,0,4,61,0,0,4,236,7,96,0,156,0,0,3,169,0,0,33,61],[0,0,0,32,5,80,0,57,0,0,0,64,7,96,0,57,0,0,0,64,0,112,4,63,0,0,0,0,135,2,4,52],[0,0,0,0,7,118,4,54,0,0,0,0,8,8,4,51,0,0,0,0,0,135,4,53,0,0,0,0,0,101,4,53],[0,0,0,64,2,32,0,57,0,0,0,0,6,50,0,75,0,0,8,165,0,0,65,61,0,0,4,221,1,0,0,65],[0,0,0,0,0,16,4,57,0,0,128,5,1,0,0,57,0,0,0,4,0,16,4,67,0,0,4,194,1,0,0,65],[0,0,0,0,2,0,4,20,0,0,4,194,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16],[0,0,4,222,1,16,1,199,0,0,128,2,2,0,0,57,19,2,18,242,0,0,4,15,0,0,0,1,2,32,1,144],[0,0,9,3,0,0,97,61,0,0,0,0,1,1,4,59,0,0,0,0,1,1,0,75,0,0,3,41,0,0,97,61],[0,0,0,64,3,0,4,61,0,0,0,36,1,48,0,57,0,0,0,64,2,0,0,57,0,0,0,0,0,33,4,53],[0,0,4,237,1,0,0,65,0,0,0,0,0,19,4,53,0,0,0,4,1,48,0,57,0,0,0,8,2,0,0,41],[0,0,0,0,0,33,4,53,0,0,0,10,1,0,0,41,0,0,0,0,1,1,4,51,0,0,0,68,2,48,0,57],[0,0,0,0,0,18,4,53,0,11,0,0,0,3,0,29,0,0,0,100,2,48,0,57,0,0,0,0,3,1,0,75],[0,0,8,238,0,0,97,61,0,0,0,0,3,0,0,25,0,0,0,10,4,0,0,41,0,0,0,32,4,64,0,57],[0,10,0,0,0,4,0,29,0,0,0,0,4,4,4,51,0,0,0,0,84,4,4,52,0,0,0,0,4,66,4,54],[0,0,0,0,5,5,4,51,0,0,0,0,0,84,4,53,0,0,0,64,2,32,0,57,0,0,0,1,3,48,0,57],[0,0,0,0,4,19,0,75,0,0,8,226,0,0,65,61,0,0,0,11,4,0,0,41,0,0,0,0,1,66,0,73],[0,0,4,194,2,0,0,65,0,0,4,194,3,64,0,156,0,0,0,0,3,2,0,25,0,0,0,0,3,4,64,25],[0,0,0,64,3,48,2,16,0,0,4,194,4,16,0,156,0,0,0,0,1,2,128,25,0,0,0,96,1,16,2,16],[0,0,0,0,1,49,1,159,0,0,0,0,3,0,4,20,0,0,4,194,4,48,0,156,0,0,0,0,3,2,128,25],[0,0,0,192,2,48,2,16,0,0,0,0,1,33,1,159,0,0,128,5,2,0,0,57,19,2,18,237,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,9,63,0,0,97,61,0,0,6,66,0,0,1,61,0,0,0,0,0,1,4,47],[0,0,0,31,4,48,1,143,0,0,0,5,2,48,2,114,0,0,9,15,0,0,97,61,0,0,0,0,5,0,0,25],[0,0,0,5,6,80,2,16,0,0,0,0,7,97,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,118,4,53],[0,0,0,1,5,80,0,57,0,0,0,0,6,37,0,75,0,0,9,8,0,0,65,61,0,0,0,0,5,4,0,75],[0,0,9,29,0,0,97,61,0,0,0,3,4,64,2,16,0,0,0,5,2,32,2,16,0,0,0,0,5,2,4,51],[0,0,0,0,5,69,1,207,0,0,0,0,5,69,2,47,0,0,0,0,1,33,3,79,0,0,0,0,1,1,4,59],[0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,81,1,159],[0,0,0,0,0,18,4,53,0,0,0,96,1,48,2,16,0,0,19,4,0,1,4,48,0,0,0,64,2,0,4,61],[0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,0,31,4,48,1,143,0,0,4,194,3,48,1,151],[0,0,0,5,5,48,2,114,0,0,9,47,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16],[0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53],[0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,9,39,0,0,65,61,0,0,0,0,6,4,0,75],[0,0,9,62,0,0,97,61,0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25],[0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47],[0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207],[0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,5,170,0,0,1,61,0,0,0,64,2,0,4,61],[0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,0,31,4,48,1,143,0,0,4,194,3,48,1,151],[0,0,0,5,5,48,2,114,0,0,9,79,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16],[0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53],[0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,9,71,0,0,65,61,0,0,0,0,6,4,0,75],[0,0,9,94,0,0,97,61,0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25],[0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47],[0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207],[0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,5,170,0,0,1,61,0,0,0,31,3,16,0,57],[0,0,4,212,4,0,0,65,0,0,0,0,5,35,0,75,0,0,0,0,5,0,0,25,0,0,0,0,5,4,64,25],[0,0,4,212,6,32,1,151,0,0,4,212,3,48,1,151,0,0,0,0,7,99,0,75,0,0,0,0,4,0,160,25],[0,0,0,0,3,99,1,63,0,0,4,212,3,48,0,156,0,0,0,0,4,5,192,25,0,0,0,0,3,4,0,75],[0,0,9,119,0,0,97,61,0,0,0,17,3,16,3,103,0,0,0,0,3,3,4,59,0,0,4,211,4,48,0,156],[0,0,9,119,0,0,33,61,0,0,0,32,1,16,0,57,0,0,0,0,4,49,0,25,0,0,0,0,2,36,0,75],[0,0,9,119,0,0,33,61,0,0,0,0,2,3,0,25,0,0,0,0,0,1,4,45,0,0,0,0,1,0,0,25],[0,0,19,4,0,1,4,48,0,3,0,0,0,0,0,2,0,0,4,194,9,64,1,151,0,0,0,0,8,0,4,20],[0,0,0,17,7,0,3,103,0,1,0,0,0,151,3,85,0,0,0,0,4,69,0,25,0,0,0,0,5,84,0,75],[0,0,0,0,5,0,0,25,0,0,0,1,5,0,64,57,0,0,0,1,5,80,1,144,0,0,10,5,0,0,193,61],[0,0,0,0,5,0,0,49,0,0,0,0,6,69,0,75,0,0,10,5,0,0,65,61,0,1,0,0,0,2,0,29],[0,2,0,0,0,1,0,29,0,3,0,0,0,3,0,29,0,0,0,0,2,151,3,79,0,0,0,0,3,69,0,73],[0,0,4,194,3,48,1,151,0,1,0,0,0,50,3,229,0,0,4,230,4,128,0,156,0,0,10,15,0,0,129,61],[0,0,0,0,2,50,3,223,0,0,0,192,1,128,2,16,0,0,4,231,1,16,1,151,0,0,5,18,1,16,1,199],[0,1,0,0,0,18,3,181,0,0,0,0,1,18,3,175,0,0,128,16,2,0,0,57,19,2,18,247,0,0,4,15],[0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,4,194,3,48,1,151,0,0,0,1,2,32,1,144],[0,0,10,22,0,0,97,61,0,0,0,63,2,48,0,57,0,0,4,233,4,32,1,151,0,0,0,64,2,0,4,61],[0,0,0,0,4,66,0,25,0,0,0,0,5,36,0,75,0,0,0,0,5,0,0,25,0,0,0,1,5,0,64,57],[0,0,4,211,6,64,0,156,0,0,10,9,0,0,33,61,0,0,0,1,5,80,1,144,0,0,10,9,0,0,193,61],[0,0,0,64,0,64,4,63,0,0,0,0,4,50,4,54,0,0,0,31,5,48,0,57,0,0,0,5,5,80,2,114],[0,0,9,184,0,0,97,61,0,0,0,0,6,0,0,49,0,0,0,17,6,96,3,103,0,0,0,0,7,0,0,25],[0,0,0,5,8,112,2,16,0,0,0,0,9,132,0,25,0,0,0,0,8,134,3,79,0,0,0,0,8,8,4,59],[0,0,0,0,0,137,4,53,0,0,0,1,7,112,0,57,0,0,0,0,8,87,0,75,0,0,9,176,0,0,65,61],[0,0,0,0,5,0,0,75,0,0,9,186,0,0,97,61,0,0,0,31,5,48,1,143,0,0,0,5,3,48,2,114],[0,0,0,1,9,0,0,41,0,0,9,199,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16],[0,0,0,0,8,116,0,25,0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53],[0,0,0,1,6,96,0,57,0,0,0,0,7,54,0,75,0,0,9,191,0,0,65,61,0,0,0,0,6,5,0,75],[0,0,9,214,0,0,97,61,0,0,0,5,3,48,2,16,0,0,0,0,1,49,3,79,0,0,0,0,3,52,0,25],[0,0,0,3,5,80,2,16,0,0,0,0,6,3,4,51,0,0,0,0,6,86,1,207,0,0,0,0,6,86,2,47],[0,0,0,0,1,1,4,59,0,0,1,0,5,80,0,137,0,0,0,0,1,81,2,47,0,0,0,0,1,81,1,207],[0,0,0,0,1,97,1,159,0,0,0,0,0,19,4,53,0,0,0,64,1,0,4,61,0,0,0,0,2,2,4,51],[0,0,0,32,2,32,0,140,0,0,0,3,5,0,0,41,0,0,0,2,6,0,0,41,0,0,10,49,0,0,193,61],[0,0,0,0,2,4,4,51,0,0,0,160,3,16,0,57,0,0,0,0,0,35,4,53,0,0,0,128,2,16,0,57],[0,0,0,0,0,146,4,53,0,0,0,96,2,16,0,57,0,0,0,0,0,82,4,53,0,0,4,213,2,96,1,151],[0,0,0,64,3,16,0,57,0,0,0,0,0,35,4,53,0,0,0,32,2,16,0,57,0,0,5,20,3,0,0,65],[0,0,0,0,0,50,4,53,0,0,0,160,3,0,0,57,0,0,0,0,0,49,4,53,0,0,5,21,3,16,0,156],[0,0,10,9,0,0,33,61,0,0,0,192,3,16,0,57,0,0,0,64,0,48,4,63,0,0,4,194,3,0,0,65],[0,0,4,194,4,32,0,156,0,0,0,0,2,3,128,25,0,0,0,64,2,32,2,16,0,0,0,0,1,1,4,51],[0,0,4,194,4,16,0,156,0,0,0,0,1,3,128,25,0,0,0,96,1,16,2,16,0,0,0,0,1,33,1,159],[0,0,0,0,2,0,4,20,0,0,4,194,4,32,0,156,0,0,0,0,2,3,128,25,0,0,0,192,2,32,2,16],[0,0,0,0,1,18,1,159,0,0,4,243,1,16,1,199,0,0,128,16,2,0,0,57,19,2,18,242,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,10,66,0,0,97,61,0,0,0,0,1,1,4,59,0,0,4,213,1,16,1,151],[0,0,0,0,0,1,4,45,0,0,5,6,1,0,0,65,0,0,0,0,0,16,4,53,0,0,0,17,1,0,0,57],[0,0,10,12,0,0,1,61,0,0,5,6,1,0,0,65,0,0,0,0,0,16,4,53,0,0,0,65,1,0,0,57],[0,0,0,4,0,16,4,63,0,0,4,235,1,0,0,65,0,0,19,4,0,1,4,48,0,0,0,64,1,0,4,61],[0,0,0,68,2,16,0,57,0,0,4,238,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57],[0,0,0,8,3,0,0,57,0,0,10,54,0,0,1,61,0,0,0,31,4,48,1,143,0,0,0,5,2,48,2,114],[0,0,10,33,0,0,97,61,0,0,0,0,5,0,0,25,0,0,0,5,6,80,2,16,0,0,0,0,7,97,3,79],[0,0,0,0,7,7,4,59,0,0,0,0,0,118,4,53,0,0,0,1,5,80,0,57,0,0,0,0,6,37,0,75],[0,0,10,26,0,0,65,61,0,0,0,0,5,4,0,75,0,0,10,47,0,0,97,61,0,0,0,3,4,64,2,16],[0,0,0,5,2,32,2,16,0,0,0,0,5,2,4,51,0,0,0,0,5,69,1,207,0,0,0,0,5,69,2,47],[0,0,0,0,1,33,3,79,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47],[0,0,0,0,1,65,1,207,0,0,0,0,1,81,1,159,0,0,0,0,0,18,4,53,0,0,0,96,1,48,2,16],[0,0,19,4,0,1,4,48,0,0,0,68,2,16,0,57,0,0,5,19,3,0,0,65,0,0,0,0,0,50,4,53],[0,0,0,36,2,16,0,57,0,0,0,31,3,0,0,57,0,0,0,0,0,50,4,53,0,0,4,214,2,0,0,65],[0,0,0,0,0,33,4,53,0,0,0,4,2,16,0,57,0,0,0,32,3,0,0,57,0,0,0,0,0,50,4,53],[0,0,4,194,2,0,0,65,0,0,4,194,3,16,0,156,0,0,0,0,1,2,128,25,0,0,0,64,1,16,2,16],[0,0,4,224,1,16,1,199,0,0,19,4,0,1,4,48,0,0,0,0,1,0,0,25,0,0,19,4,0,1,4,48],[0,0,0,64,3,0,4,61,0,0,0,96,4,48,0,57,0,0,0,0,0,36,4,53,0,0,4,213,1,16,1,151],[0,0,0,64,2,48,0,57,0,0,0,0,0,18,4,53,0,0,0,96,1,0,0,57,0,0,0,0,1,19,4,54],[0,0,5,22,2,0,0,65,0,0,0,0,0,33,4,53,0,0,5,23,2,48,0,156,0,0,10,104,0,0,129,61],[0,0,0,128,2,48,0,57,0,0,0,64,0,32,4,63,0,0,4,194,2,0,0,65,0,0,4,194,4,16,0,156],[0,0,0,0,1,2,128,25,0,0,0,64,1,16,2,16,0,0,0,0,3,3,4,51,0,0,4,194,4,48,0,156],[0,0,0,0,3,2,128,25,0,0,0,96,3,48,2,16,0,0,0,0,1,19,1,159,0,0,0,0,3,0,4,20],[0,0,4,194,4,48,0,156,0,0,0,0,3,2,128,25,0,0,0,192,2,48,2,16,0,0,0,0,1,18,1,159],[0,0,4,243,1,16,1,199,0,0,128,16,2,0,0,57,19,2,18,242,0,0,4,15,0,0,0,1,2,32,1,144],[0,0,10,110,0,0,97,61,0,0,0,0,1,1,4,59,0,0,4,213,1,16,1,151,0,0,0,0,0,1,4,45],[0,0,5,6,1,0,0,65,0,0,0,0,0,16,4,53,0,0,0,65,1,0,0,57,0,0,0,4,0,16,4,63],[0,0,4,235,1,0,0,65,0,0,19,4,0,1,4,48,0,0,0,0,1,0,0,25,0,0,19,4,0,1,4,48],[0,10,0,0,0,0,0,2,0,6,0,0,0,4,0,29,0,5,0,0,0,3,0,29,0,0,0,64,4,0,4,61],[0,0,0,4,3,64,0,57,0,9,0,0,0,1,0,29,0,0,0,0,1,1,0,75,0,0,13,64,0,0,97,61],[0,4,0,0,0,2,0,29,0,0,4,213,1,32,1,151,0,0,255,255,2,16,0,140,0,0,13,74,0,0,161,61],[0,0,5,24,2,0,0,65,0,0,0,0,0,36,4,53,0,10,0,0,0,1,0,29,0,0,0,0,0,19,4,53],[0,0,4,194,1,0,0,65,0,0,0,0,2,0,4,20,0,0,4,194,3,32,0,156,0,0,0,0,2,1,128,25],[0,0,4,194,3,64,0,156,0,0,0,0,1,4,64,25,0,0,0,64,1,16,2,16,0,0,0,192,2,32,2,16],[0,0,0,0,1,18,1,159,0,0,4,235,1,16,1,199,0,0,128,2,2,0,0,57,0,7,0,0,0,2,0,29],[0,8,0,0,0,4,0,29,19,2,18,242,0,0,4,15,0,0,0,8,10,0,0,41,0,0,0,0,3,1,0,25],[0,0,0,96,3,48,2,112,0,0,4,194,3,48,1,151,0,0,0,32,4,48,0,140,0,0,0,0,4,3,0,25],[0,0,0,32,4,0,128,57,0,0,0,31,5,64,1,143,0,0,0,5,6,64,2,114,0,0,10,161,0,0,97,61],[0,0,0,0,7,0,0,25,0,0,0,5,8,112,2,16,0,0,0,0,9,138,0,25,0,0,0,0,8,129,3,79],[0,0,0,0,8,8,4,59,0,0,0,0,0,137,4,53,0,0,0,1,7,112,0,57,0,0,0,0,8,103,0,75],[0,0,10,153,0,0,65,61,0,0,0,0,7,5,0,75,0,0,10,176,0,0,97,61,0,0,0,5,6,96,2,16],[0,0,0,0,7,97,3,79,0,0,0,0,6,106,0,25,0,0,0,3,5,80,2,16,0,0,0,0,8,6,4,51],[0,0,0,0,8,88,1,207,0,0,0,0,8,88,2,47,0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137],[0,0,0,0,7,87,2,47,0,0,0,0,5,87,1,207,0,0,0,0,5,133,1,159,0,0,0,0,0,86,4,53],[0,0,0,1,2,32,1,144,0,0,13,93,0,0,97,61,0,0,0,31,1,64,0,57,0,0,0,96,1,16,1,143],[0,0,0,0,4,161,0,25,0,0,0,0,1,20,0,75,0,0,0,0,1,0,0,25,0,0,0,1,1,0,64,57],[0,0,4,211,2,64,0,156,0,0,13,49,0,0,33,61,0,0,0,1,1,16,1,144,0,0,13,49,0,0,193,61],[0,0,0,64,0,64,4,63,0,0,0,31,1,48,0,140,0,0,13,47,0,0,161,61,0,0,0,4,1,64,0,57],[0,0,0,0,2,10,4,51,0,0,0,0,2,2,0,75,0,0,13,122,0,0,193,61,0,0,5,26,2,0,0,65],[0,0,0,0,0,36,4,53,0,0,0,10,2,0,0,41,0,0,0,0,0,33,4,53,0,0,4,194,1,0,0,65],[0,0,0,0,2,0,4,20,0,0,4,194,3,32,0,156,0,0,0,0,2,1,128,25,0,0,4,194,3,64,0,156],[0,0,0,0,1,4,64,25,0,0,0,64,1,16,2,16,0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159],[0,0,4,235,1,16,1,199,0,0,128,3,2,0,0,57,0,8,0,0,0,4,0,29,19,2,18,242,0,0,4,15],[0,0,0,8,10,0,0,41,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,4,194,3,48,1,151],[0,0,0,32,4,48,0,140,0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57,0,0,0,31,5,64,1,143],[0,0,0,5,6,64,2,114,0,0,10,231,0,0,97,61,0,0,0,0,7,0,0,25,0,0,0,5,8,112,2,16],[0,0,0,0,9,138,0,25,0,0,0,0,8,129,3,79,0,0,0,0,8,8,4,59,0,0,0,0,0,137,4,53],[0,0,0,1,7,112,0,57,0,0,0,0,8,103,0,75,0,0,10,223,0,0,65,61,0,0,0,0,7,5,0,75],[0,0,10,246,0,0,97,61,0,0,0,5,6,96,2,16,0,0,0,0,7,97,3,79,0,0,0,0,6,106,0,25],[0,0,0,3,5,80,2,16,0,0,0,0,8,6,4,51,0,0,0,0,8,88,1,207,0,0,0,0,8,88,2,47],[0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137,0,0,0,0,7,87,2,47,0,0,0,0,5,87,1,207],[0,0,0,0,5,133,1,159,0,0,0,0,0,86,4,53,0,0,0,1,2,32,1,144,0,0,13,132,0,0,97,61],[0,0,0,31,1,64,0,57,0,0,0,96,1,16,1,143,0,0,0,0,4,161,0,25,0,0,4,211,1,64,0,156],[0,0,13,49,0,0,33,61,0,0,0,64,0,64,4,63,0,0,0,32,1,48,0,140,0,0,13,47,0,0,65,61],[0,0,0,4,1,64,0,57,0,0,0,0,2,10,4,51,0,0,0,0,2,2,0,75,0,0,13,161,0,0,193,61],[0,0,4,217,2,0,0,65,0,0,0,0,0,36,4,53,0,0,0,9,2,0,0,41,0,0,0,0,0,33,4,53],[0,0,4,194,1,0,0,65,0,0,0,0,2,0,4,20,0,0,4,194,3,32,0,156,0,0,0,0,2,1,128,25],[0,0,4,194,3,64,0,156,0,0,0,0,1,4,64,25,0,0,0,64,1,16,2,16,0,0,0,192,2,32,2,16],[0,0,0,0,1,18,1,159,0,0,4,235,1,16,1,199,0,0,128,4,2,0,0,57,0,8,0,0,0,4,0,29],[19,2,18,242,0,0,4,15,0,0,0,8,10,0,0,41,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112],[0,0,4,194,3,48,1,151,0,0,0,32,4,48,0,140,0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57],[0,0,0,31,5,64,1,143,0,0,0,5,6,64,2,114,0,0,11,40,0,0,97,61,0,0,0,0,7,0,0,25],[0,0,0,5,8,112,2,16,0,0,0,0,9,138,0,25,0,0,0,0,8,129,3,79,0,0,0,0,8,8,4,59],[0,0,0,0,0,137,4,53,0,0,0,1,7,112,0,57,0,0,0,0,8,103,0,75,0,0,11,32,0,0,65,61],[0,0,0,0,7,5,0,75,0,0,11,55,0,0,97,61,0,0,0,5,6,96,2,16,0,0,0,0,7,97,3,79],[0,0,0,0,6,106,0,25,0,0,0,3,5,80,2,16,0,0,0,0,8,6,4,51,0,0,0,0,8,88,1,207],[0,0,0,0,8,88,2,47,0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137,0,0,0,0,7,87,2,47],[0,0,0,0,5,87,1,207,0,0,0,0,5,133,1,159,0,0,0,0,0,86,4,53,0,0,0,1,2,32,1,144],[0,0,13,171,0,0,97,61,0,0,0,31,1,64,0,57,0,0,0,96,1,16,1,143,0,0,0,0,4,161,0,25],[0,0,4,211,1,64,0,156,0,0,13,49,0,0,33,61,0,0,0,64,0,64,4,63,0,0,0,32,1,48,0,140],[0,0,13,47,0,0,65,61,0,0,0,0,1,10,4,51,0,0,0,0,1,1,0,75,0,0,13,200,0,0,97,61],[0,0,4,236,1,64,0,156,0,0,13,49,0,0,33,61,0,0,0,64,1,64,0,57,0,0,0,64,0,16,4,63],[0,0,0,0,1,4,4,54,0,3,0,0,0,1,0,29,0,0,0,0,0,1,4,53,0,0,0,10,1,0,0,41],[0,0,0,0,0,16,4,53,0,0,0,32,0,0,4,63,0,0,4,194,1,0,0,65,0,0,0,0,2,0,4,20],[0,0,4,194,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,4,219,1,16,1,199],[0,0,128,16,2,0,0,57,0,8,0,0,0,4,0,29,19,2,18,242,0,0,4,15,0,0,0,8,3,0,0,41],[0,0,0,1,2,32,1,144,0,0,13,47,0,0,97,61,0,0,0,0,2,3,4,51,0,0,0,2,3,32,0,140],[0,0,13,56,0,0,129,61,0,0,0,0,1,1,4,59,0,0,0,0,3,1,4,26,0,0,1,0,4,0,0,138],[0,0,0,0,3,67,1,111,0,0,0,0,2,35,1,159,0,0,0,0,0,33,4,27,0,0,0,3,3,0,0,41],[0,0,0,0,3,3,4,51,0,0,0,1,4,48,0,140,0,0,13,56,0,0,33,61,0,0,4,220,2,32,1,151],[0,0,0,8,3,48,2,16,0,0,255,0,3,48,1,143,0,0,0,0,2,35,1,159,0,0,0,0,0,33,4,27],[0,0,4,221,1,0,0,65,0,0,0,0,0,16,4,57,0,0,0,0,1,0,4,22,0,8,0,0,0,1,0,29],[0,0,0,0,1,1,0,75,0,0,11,214,0,0,97,61,0,0,128,10,1,0,0,57,0,0,0,4,0,16,4,67],[0,0,4,194,1,0,0,65,0,0,0,0,2,0,4,20,0,0,4,194,3,32,0,156,0,0,0,0,2,1,128,25],[0,0,0,192,1,32,2,16,0,0,4,222,1,16,1,199,0,0,128,2,2,0,0,57,0,3,0,0,0,2,0,29],[19,2,18,242,0,0,4,15,0,0,0,1,2,32,1,144,0,0,13,55,0,0,97,61,0,0,0,0,1,1,4,59],[0,0,0,0,1,1,0,75,0,0,13,47,0,0,97,61,0,0,0,64,4,0,4,61,0,0,0,68,1,64,0,57],[0,0,0,8,2,0,0,41,0,0,0,0,0,33,4,53,0,0,0,36,1,64,0,57,0,0,0,10,2,0,0,41],[0,0,0,0,0,33,4,53,0,0,4,223,1,0,0,65,0,0,0,0,0,20,4,53,0,0,0,0,1,0,4,16],[0,0,4,213,1,16,1,151,0,0,0,4,2,64,0,57,0,0,0,0,0,18,4,53,0,0,4,194,1,0,0,65],[0,0,0,0,2,0,4,20,0,0,4,194,3,32,0,156,0,0,0,0,2,1,128,25,0,0,4,194,3,64,0,156],[0,2,0,0,0,4,0,29,0,0,0,0,1,4,64,25,0,0,0,64,1,16,2,16,0,0,0,192,2,32,2,16],[0,0,0,0,1,18,1,159,0,0,4,224,1,16,1,199,0,0,128,10,2,0,0,57,19,2,18,237,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,14,69,0,0,97,61,0,0,0,2,2,0,0,41,0,0,4,211,1,32,0,156],[0,0,13,49,0,0,33,61,0,0,0,64,0,32,4,63,0,0,4,221,1,0,0,65,0,0,0,0,0,16,4,57],[0,0,0,3,2,0,0,41,0,0,0,4,0,32,4,67,0,0,4,194,1,0,0,65,0,0,0,0,4,0,4,20],[0,0,4,194,3,64,0,156,0,0,0,0,4,1,128,25,0,0,0,192,1,64,2,16,0,0,4,222,1,16,1,199],[19,2,18,242,0,0,4,15,0,0,0,1,2,32,1,144,0,0,13,55,0,0,97,61,0,0,0,0,1,1,4,59],[0,0,0,0,1,1,0,75,0,0,13,47,0,0,97,61,0,0,0,64,4,0,4,61,0,0,4,225,1,0,0,65],[0,0,0,0,0,20,4,53,0,0,0,4,2,64,0,57,0,0,0,10,1,0,0,41,0,2,0,0,0,2,0,29],[0,0,0,0,0,18,4,53,0,0,0,9,1,0,0,41,0,0,4,226,1,16,1,151,0,0,4,227,1,16,1,199],[0,0,0,36,2,64,0,57,0,1,0,0,0,2,0,29,0,0,0,0,0,18,4,53,0,0,4,194,1,0,0,65],[0,0,0,0,2,0,4,20,0,0,4,194,3,32,0,156,0,0,0,0,2,1,128,25,0,0,4,194,3,64,0,156],[0,3,0,0,0,4,0,29,0,0,0,0,1,4,64,25,0,0,0,64,1,16,2,16,0,0,0,192,2,32,2,16],[0,0,0,0,1,18,1,159,0,0,4,228,1,16,1,199,0,0,128,2,2,0,0,57,19,2,18,237,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,14,101,0,0,97,61,0,0,0,3,8,0,0,41,0,0,4,211,1,128,0,156],[0,0,13,49,0,0,33,61,0,0,0,64,0,128,4,63,0,0,0,8,1,0,0,41,0,0,4,229,1,16,1,151],[0,0,0,0,0,1,4,23,0,0,12,4,0,0,1,61,0,0,0,7,2,0,0,41,0,0,0,4,0,32,4,67],[0,0,4,194,1,0,0,65,0,0,0,0,4,0,4,20,0,0,4,194,3,64,0,156,0,0,0,0,4,1,128,25],[0,0,0,192,1,64,2,16,0,0,4,222,1,16,1,199,19,2,18,242,0,0,4,15,0,0,0,1,2,32,1,144],[0,0,13,55,0,0,97,61,0,0,0,0,1,1,4,59,0,0,0,0,1,1,0,75,0,0,13,47,0,0,97,61],[0,0,0,64,4,0,4,61,0,0,4,225,1,0,0,65,0,0,0,0,0,20,4,53,0,0,0,4,2,64,0,57],[0,0,0,10,1,0,0,41,0,2,0,0,0,2,0,29,0,0,0,0,0,18,4,53,0,0,0,9,1,0,0,41],[0,0,4,226,1,16,1,151,0,0,4,227,1,16,1,199,0,0,0,36,2,64,0,57,0,1,0,0,0,2,0,29],[0,0,0,0,0,18,4,53,0,0,4,194,1,0,0,65,0,0,0,0,2,0,4,20,0,0,4,194,3,32,0,156],[0,0,0,0,2,1,128,25,0,0,4,194,3,64,0,156,0,3,0,0,0,4,0,29,0,0,0,0,1,4,64,25],[0,0,0,64,1,16,2,16,0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159,0,0,4,228,1,16,1,199],[0,0,128,2,2,0,0,57,19,2,18,237,0,0,4,15,0,0,0,1,2,32,1,144,0,0,14,133,0,0,97,61],[0,0,0,3,8,0,0,41,0,0,4,211,1,128,0,156,0,0,13,49,0,0,33,61,0,0,0,64,0,128,4,63],[0,0,0,5,4,0,0,41,0,0,4,194,2,64,1,151,0,0,0,0,1,0,4,20,0,0,0,17,3,0,3,103],[0,1,0,0,0,35,3,85,0,0,0,0,7,0,4,17,0,0,0,6,4,64,0,41,0,0,0,6,5,64,0,108],[0,0,0,0,5,0,0,25,0,0,0,1,5,0,64,57,0,0,0,1,5,80,1,144,0,0,13,60,0,0,193,61],[0,0,0,0,5,0,0,49,0,0,0,0,6,69,0,75,0,0,13,60,0,0,65,61,0,0,0,0,2,35,3,79],[0,0,0,0,3,69,0,73,0,0,4,194,3,48,1,151,0,1,0,0,0,50,3,229,0,0,4,230,4,16,0,156],[0,0,13,217,0,0,129,61,0,0,0,0,2,50,3,223,0,0,0,192,1,16,2,16,0,0,4,231,1,16,1,151],[0,0,4,232,1,16,1,199,0,1,0,0,0,18,3,181,0,0,0,0,1,18,3,175,0,5,0,0,0,7,0,29],[0,0,4,213,13,112,1,151,0,0,0,4,2,0,0,41,19,2,18,252,0,0,4,15,0,0,0,0,3,1,0,25],[0,0,0,96,3,48,2,112,0,0,4,194,3,48,1,151,0,0,0,1,2,32,1,144,0,0,13,234,0,0,97,61],[0,0,0,63,2,48,0,57,0,0,4,233,2,32,1,151,0,0,0,64,6,0,4,61,0,0,0,0,2,38,0,25],[0,0,0,0,4,98,0,75,0,0,0,0,4,0,0,25,0,0,0,1,4,0,64,57,0,0,4,211,5,32,0,156],[0,0,13,49,0,0,33,61,0,0,0,1,4,64,1,144,0,0,13,49,0,0,193,61,0,0,0,64,0,32,4,63],[0,6,0,0,0,6,0,29,0,0,0,0,8,54,4,54,0,0,0,31,2,48,0,57,0,0,0,5,2,32,2,114],[0,0,12,68,0,0,97,61,0,0,0,0,4,0,0,49,0,0,0,17,4,64,3,103,0,0,0,0,5,0,0,25],[0,0,0,5,6,80,2,16,0,0,0,0,7,104,0,25,0,0,0,0,6,100,3,79,0,0,0,0,6,6,4,59],[0,0,0,0,0,103,4,53,0,0,0,1,5,80,0,57,0,0,0,0,6,37,0,75,0,0,12,60,0,0,65,61],[0,0,0,0,2,0,0,75,0,0,12,70,0,0,97,61,0,0,0,31,2,48,1,143,0,0,0,5,3,48,2,114],[0,0,12,82,0,0,97,61,0,0,0,0,4,0,0,25,0,0,0,5,5,64,2,16,0,0,0,0,6,88,0,25],[0,0,0,0,5,81,3,79,0,0,0,0,5,5,4,59,0,0,0,0,0,86,4,53,0,0,0,1,4,64,0,57],[0,0,0,0,5,52,0,75,0,0,12,74,0,0,65,61,0,0,0,0,4,2,0,75,0,0,12,97,0,0,97,61],[0,0,0,5,3,48,2,16,0,0,0,0,1,49,3,79,0,0,0,0,3,56,0,25,0,0,0,3,2,32,2,16],[0,0,0,0,4,3,4,51,0,0,0,0,4,36,1,207,0,0,0,0,4,36,2,47,0,0,0,0,1,1,4,59],[0,0,1,0,2,32,0,137,0,0,0,0,1,33,2,47,0,0,0,0,1,33,1,207,0,0,0,0,1,65,1,159],[0,0,0,0,0,19,4,53,0,8,0,0,0,8,0,29,0,0,4,221,1,0,0,65,0,0,0,0,0,16,4,57],[0,0,0,7,2,0,0,41,0,0,0,4,0,32,4,67,0,0,4,194,1,0,0,65,0,0,0,0,4,0,4,20],[0,0,4,194,3,64,0,156,0,0,0,0,4,1,128,25,0,0,0,192,1,64,2,16,0,0,4,222,1,16,1,199],[19,2,18,242,0,0,4,15,0,0,0,1,2,32,1,144,0,0,13,55,0,0,97,61,0,0,0,0,1,1,4,59],[0,0,0,0,1,1,0,75,0,0,13,47,0,0,97,61,0,0,0,64,4,0,4,61,0,0,4,234,1,0,0,65],[0,0,0,0,0,20,4,53,0,0,0,4,1,64,0,57,0,0,0,10,2,0,0,41,0,0,0,0,0,33,4,53],[0,0,4,194,1,0,0,65,0,0,0,0,2,0,4,20,0,0,4,194,3,32,0,156,0,0,0,0,2,1,128,25],[0,0,4,194,3,64,0,156,0,7,0,0,0,4,0,29,0,0,0,0,1,4,64,25,0,0,0,64,1,16,2,16],[0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159,0,0,4,235,1,16,1,199,0,0,128,2,2,0,0,57],[19,2,18,237,0,0,4,15,0,0,0,1,2,32,1,144,0,0,14,5,0,0,97,61,0,0,0,7,9,0,0,41],[0,0,4,211,1,144,0,156,0,0,0,6,1,0,0,41,0,0,13,49,0,0,33,61,0,0,0,64,0,144,4,63],[0,0,0,0,1,1,4,51,0,0,4,212,2,0,0,65,0,0,0,32,3,16,0,140,0,0,0,0,3,0,0,25],[0,0,0,0,3,2,64,25,0,0,4,212,4,16,1,151,0,0,0,0,5,4,0,75,0,0,0,0,2,0,160,25],[0,0,4,212,4,64,0,156,0,0,0,0,2,3,192,25,0,0,0,0,2,2,0,75,0,0,13,47,0,0,193,61],[0,0,0,8,2,0,0,41,0,0,0,0,2,2,4,51,0,0,4,211,3,32,0,156,0,0,13,47,0,0,33,61],[0,0,0,8,1,16,0,41,0,0,0,8,2,32,0,41,0,0,0,31,3,32,0,57,0,0,4,212,4,0,0,65],[0,0,0,0,5,19,0,75,0,0,0,0,5,0,0,25,0,0,0,0,5,4,128,25,0,0,4,212,3,48,1,151],[0,0,4,212,6,16,1,151,0,0,0,0,7,99,0,75,0,0,0,0,4,0,128,25,0,0,0,0,3,99,1,63],[0,0,4,212,3,48,0,156,0,0,0,0,4,5,192,25,0,0,0,0,3,4,0,75,0,0,13,47,0,0,193,61],[0,0,0,0,35,2,4,52,0,0,4,211,4,48,0,156,0,0,13,49,0,0,33,61,0,0,0,5,4,48,2,16],[0,0,0,63,4,64,0,57,0,0,0,32,5,0,0,138,0,0,0,0,4,84,1,111,0,0,0,0,4,148,0,25],[0,0,4,211,5,64,0,156,0,0,13,49,0,0,33,61,0,0,0,64,0,64,4,63,0,0,0,0,0,57,4,53],[0,0,0,6,3,48,2,16,0,0,0,0,3,35,0,25,0,0,0,0,4,19,0,75,0,0,13,47,0,0,33,61],[0,0,0,0,4,50,0,75,0,0,12,218,0,0,129,61,0,0,4,212,4,0,0,65,0,0,0,0,5,9,0,25],[0,0,0,0,6,33,0,73,0,0,0,64,7,96,0,140,0,0,0,0,7,0,0,25,0,0,0,0,7,4,64,25],[0,0,4,212,6,96,1,151,0,0,0,0,8,6,0,75,0,0,0,0,8,0,0,25,0,0,0,0,8,4,32,25],[0,0,4,212,6,96,0,156,0,0,0,0,8,7,192,25,0,0,0,0,6,8,0,75,0,0,13,47,0,0,193,61],[0,0,0,64,6,0,4,61,0,0,4,236,7,96,0,156,0,0,13,49,0,0,33,61,0,0,0,32,5,80,0,57],[0,0,0,64,7,96,0,57,0,0,0,64,0,112,4,63,0,0,0,0,135,2,4,52,0,0,0,0,7,118,4,54],[0,0,0,0,8,8,4,51,0,0,0,0,0,135,4,53,0,0,0,0,0,101,4,53,0,0,0,64,2,32,0,57],[0,0,0,0,6,50,0,75,0,0,12,192,0,0,65,61,0,0,4,221,1,0,0,65,0,0,0,0,0,16,4,57],[0,0,128,5,1,0,0,57,0,0,0,4,0,16,4,67,0,0,4,194,1,0,0,65,0,0,0,0,2,0,4,20],[0,0,4,194,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,4,222,1,16,1,199],[0,0,128,2,2,0,0,57,19,2,18,242,0,0,4,15,0,0,0,1,2,32,1,144,0,0,13,55,0,0,97,61],[0,0,0,0,1,1,4,59,0,0,0,0,1,1,0,75,0,0,0,7,6,0,0,41,0,0,13,47,0,0,97,61],[0,0,0,64,7,0,4,61,0,0,0,36,1,112,0,57,0,0,0,64,2,0,0,57,0,0,0,0,0,33,4,53],[0,0,4,237,1,0,0,65,0,0,0,0,0,23,4,53,0,0,0,4,1,112,0,57,0,0,0,10,2,0,0,41],[0,0,0,0,0,33,4,53,0,0,0,0,1,6,4,51,0,0,0,68,2,112,0,57,0,0,0,0,0,18,4,53],[0,0,0,100,2,112,0,57,0,0,0,0,3,1,0,75,0,0,13,6,0,0,97,61,0,0,0,0,3,0,0,25],[0,0,0,32,6,96,0,57,0,0,0,0,4,6,4,51,0,0,0,0,84,4,4,52,0,0,0,0,4,66,4,54],[0,0,0,0,5,5,4,51,0,0,0,0,0,84,4,53,0,0,0,64,2,32,0,57,0,0,0,1,3,48,0,57],[0,0,0,0,4,19,0,75,0,0,12,252,0,0,65,61,0,0,0,0,1,114,0,73,0,0,4,194,2,0,0,65],[0,0,4,194,3,112,0,156,0,0,0,0,3,2,0,25,0,0,0,0,3,7,64,25,0,0,0,64,3,48,2,16],[0,0,4,194,4,16,0,156,0,0,0,0,1,2,128,25,0,0,0,96,1,16,2,16,0,0,0,0,1,49,1,159],[0,0,0,0,3,0,4,20,0,0,4,194,4,48,0,156,0,0,0,0,3,2,128,25,0,0,0,192,2,48,2,16],[0,0,0,0,1,33,1,159,0,0,128,5,2,0,0,57,0,8,0,0,0,7,0,29,19,2,18,237,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,14,37,0,0,97,61,0,0,0,8,2,0,0,41,0,0,4,211,1,32,0,156],[0,0,0,0,1,2,0,25,0,0,13,49,0,0,33,61,0,0,0,64,0,16,4,63,0,0,4,194,1,0,0,65],[0,0,0,0,2,0,4,20,0,0,4,194,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16],[0,0,4,243,1,16,1,199,0,0,128,13,2,0,0,57,0,0,0,4,3,0,0,57,0,0,4,244,4,0,0,65],[0,0,0,5,5,0,0,41,0,0,0,9,6,0,0,41,0,0,0,10,7,0,0,41,19,2,18,237,0,0,4,15],[0,0,0,1,1,32,1,144,0,0,13,47,0,0,97,61,0,0,0,0,0,1,4,45,0,0,0,0,1,0,0,25],[0,0,19,4,0,1,4,48,0,0,5,6,1,0,0,65,0,0,0,0,0,16,4,53,0,0,0,65,1,0,0,57],[0,0,0,4,0,16,4,63,0,0,4,235,1,0,0,65,0,0,19,4,0,1,4,48,0,0,0,0,0,1,4,47],[0,0,5,6,1,0,0,65,0,0,0,0,0,16,4,53,0,0,0,33,1,0,0,57,0,0,13,52,0,0,1,61],[0,0,5,6,1,0,0,65,0,0,0,0,0,16,4,53,0,0,0,17,1,0,0,57,0,0,13,52,0,0,1,61],[0,0,4,214,2,0,0,65,0,0,0,0,0,36,4,53,0,0,0,32,2,0,0,57,0,0,0,0,0,35,4,53],[0,0,0,68,1,64,0,57,0,0,5,30,2,0,0,65,0,0,0,0,0,33,4,53,0,0,0,36,1,64,0,57],[0,0,0,27,2,0,0,57,0,0,13,210,0,0,1,61,0,0,4,214,2,0,0,65,0,0,0,0,0,36,4,53],[0,0,0,32,2,0,0,57,0,0,0,0,0,35,4,53,0,0,0,100,1,64,0,57,0,0,5,28,2,0,0,65],[0,0,0,0,0,33,4,53,0,0,0,68,1,64,0,57,0,0,5,29,2,0,0,65,0,0,0,0,0,33,4,53],[0,0,0,36,1,64,0,57,0,0,0,40,2,0,0,57,0,0,0,0,0,33,4,53,0,0,4,194,1,0,0,65],[0,0,4,194,2,64,0,156,0,0,0,0,4,1,128,25,0,0,0,64,1,64,2,16,0,0,4,241,1,16,1,199],[0,0,19,4,0,1,4,48,0,0,0,64,2,0,4,61,0,0,0,31,4,48,1,143,0,0,0,5,5,48,2,114],[0,0,13,106,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25],[0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57],[0,0,0,0,7,86,0,75,0,0,13,98,0,0,65,61,0,0,0,0,6,4,0,75,0,0,14,164,0,0,97,61],[0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16],[0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59],[0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159],[0,0,0,0,0,21,4,53,0,0,14,164,0,0,1,61,0,0,4,214,2,0,0,65,0,0,0,0,0,36,4,53],[0,0,0,32,2,0,0,57,0,0,0,0,0,33,4,53,0,0,0,68,1,64,0,57,0,0,5,25,2,0,0,65],[0,0,0,0,0,33,4,53,0,0,0,36,1,64,0,57,0,0,0,21,2,0,0,57,0,0,13,210,0,0,1,61],[0,0,0,64,2,0,4,61,0,0,0,31,4,48,1,143,0,0,0,5,5,48,2,114,0,0,13,145,0,0,97,61],[0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79],[0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75],[0,0,13,137,0,0,65,61,0,0,0,0,6,4,0,75,0,0,13,160,0,0,97,61,0,0,0,5,5,80,2,16],[0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51],[0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137],[0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53],[0,0,14,164,0,0,1,61,0,0,4,214,2,0,0,65,0,0,0,0,0,36,4,53,0,0,0,32,2,0,0,57],[0,0,0,0,0,33,4,53,0,0,0,68,1,64,0,57,0,0,5,27,2,0,0,65,0,0,0,0,0,33,4,53],[0,0,0,36,1,64,0,57,0,0,0,19,2,0,0,57,0,0,13,210,0,0,1,61,0,0,0,64,2,0,4,61],[0,0,0,31,4,48,1,143,0,0,0,5,5,48,2,114,0,0,13,184,0,0,97,61,0,0,0,0,6,0,0,25],[0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59],[0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,13,176,0,0,65,61],[0,0,0,0,6,4,0,75,0,0,13,199,0,0,97,61,0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79],[0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207],[0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47],[0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,14,164,0,0,1,61],[0,0,0,68,1,64,0,57,0,0,4,245,2,0,0,65,0,0,0,0,0,33,4,53,0,0,0,36,1,64,0,57],[0,0,0,26,2,0,0,57,0,0,0,0,0,33,4,53,0,0,4,214,1,0,0,65,0,0,0,0,0,20,4,53],[0,0,0,4,1,64,0,57,0,0,0,32,2,0,0,57,0,0,0,0,0,33,4,53,0,0,4,194,1,0,0,65],[0,0,4,194,2,64,0,156,0,0,0,0,4,1,128,25,0,0,0,64,1,64,2,16,0,0,4,224,1,16,1,199],[0,0,19,4,0,1,4,48,0,0,4,214,1,0,0,65,0,0,0,0,0,24,4,53,0,0,0,32,1,0,0,57],[0,0,0,2,2,0,0,41,0,0,0,0,0,18,4,53,0,0,0,8,1,0,0,57,0,0,0,1,2,0,0,41],[0,0,0,0,0,18,4,53,0,0,0,68,1,128,0,57,0,0,4,238,2,0,0,65,0,0,0,0,0,33,4,53],[0,0,4,194,1,0,0,65,0,0,4,194,2,128,0,156,0,0,0,0,8,1,128,25,0,0,0,64,1,128,2,16],[0,0,4,224,1,16,1,199,0,0,19,4,0,1,4,48,0,0,0,31,4,48,1,143,0,0,0,5,2,48,2,114],[0,0,13,245,0,0,97,61,0,0,0,0,5,0,0,25,0,0,0,5,6,80,2,16,0,0,0,0,7,97,3,79],[0,0,0,0,7,7,4,59,0,0,0,0,0,118,4,53,0,0,0,1,5,80,0,57,0,0,0,0,6,37,0,75],[0,0,13,238,0,0,65,61,0,0,0,0,5,4,0,75,0,0,14,3,0,0,97,61,0,0,0,3,4,64,2,16],[0,0,0,5,2,32,2,16,0,0,0,0,5,2,4,51,0,0,0,0,5,69,1,207,0,0,0,0,5,69,2,47],[0,0,0,0,1,33,3,79,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47],[0,0,0,0,1,65,1,207,0,0,0,0,1,81,1,159,0,0,0,0,0,18,4,53,0,0,0,96,1,48,2,16],[0,0,19,4,0,1,4,48,0,0,0,64,2,0,4,61,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112],[0,0,0,31,4,48,1,143,0,0,4,194,3,48,1,151,0,0,0,5,5,48,2,114,0,0,14,21,0,0,97,61],[0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79],[0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75],[0,0,14,13,0,0,65,61,0,0,0,0,6,4,0,75,0,0,14,36,0,0,97,61,0,0,0,5,5,80,2,16],[0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51],[0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137],[0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53],[0,0,14,164,0,0,1,61,0,0,0,64,2,0,4,61,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112],[0,0,0,31,4,48,1,143,0,0,4,194,3,48,1,151,0,0,0,5,5,48,2,114,0,0,14,53,0,0,97,61],[0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79],[0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75],[0,0,14,45,0,0,65,61,0,0,0,0,6,4,0,75,0,0,14,68,0,0,97,61,0,0,0,5,5,80,2,16],[0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51],[0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137],[0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53],[0,0,14,164,0,0,1,61,0,0,0,64,2,0,4,61,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112],[0,0,0,31,4,48,1,143,0,0,4,194,3,48,1,151,0,0,0,5,5,48,2,114,0,0,14,85,0,0,97,61],[0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79],[0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75],[0,0,14,77,0,0,65,61,0,0,0,0,6,4,0,75,0,0,14,100,0,0,97,61,0,0,0,5,5,80,2,16],[0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51],[0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137],[0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53],[0,0,14,164,0,0,1,61,0,0,0,64,2,0,4,61,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112],[0,0,0,31,4,48,1,143,0,0,4,194,3,48,1,151,0,0,0,5,5,48,2,114,0,0,14,117,0,0,97,61],[0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79],[0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75],[0,0,14,109,0,0,65,61,0,0,0,0,6,4,0,75,0,0,14,132,0,0,97,61,0,0,0,5,5,80,2,16],[0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51],[0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137],[0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53],[0,0,14,164,0,0,1,61,0,0,0,64,2,0,4,61,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112],[0,0,0,31,4,48,1,143,0,0,4,194,3,48,1,151,0,0,0,5,5,48,2,114,0,0,14,149,0,0,97,61],[0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79],[0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75],[0,0,14,141,0,0,65,61,0,0,0,0,6,4,0,75,0,0,14,164,0,0,97,61,0,0,0,5,5,80,2,16],[0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51],[0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137],[0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53],[0,0,4,194,1,0,0,65,0,0,4,194,4,32,0,156,0,0,0,0,2,1,128,25,0,0,0,64,1,32,2,16],[0,0,0,96,2,48,2,16,0,0,0,0,1,33,1,159,0,0,19,4,0,1,4,48,0,10,0,0,0,0,0,2],[0,5,0,0,0,5,0,29,0,4,0,0,0,4,0,29,0,6,0,0,0,3,0,29,0,0,0,64,4,0,4,61],[0,0,0,4,3,64,0,57,0,9,0,0,0,1,0,29,0,0,0,0,1,1,0,75,0,0,17,129,0,0,97,61],[0,3,0,0,0,2,0,29,0,0,4,213,1,32,1,151,0,0,255,255,2,16,0,140,0,0,17,139,0,0,161,61],[0,0,5,24,2,0,0,65,0,0,0,0,0,36,4,53,0,10,0,0,0,1,0,29,0,0,0,0,0,19,4,53],[0,0,4,194,1,0,0,65,0,0,0,0,2,0,4,20,0,0,4,194,3,32,0,156,0,0,0,0,2,1,128,25],[0,0,4,194,3,64,0,156,0,0,0,0,1,4,64,25,0,0,0,64,1,16,2,16,0,0,0,192,2,32,2,16],[0,0,0,0,1,18,1,159,0,0,4,235,1,16,1,199,0,0,128,2,2,0,0,57,0,7,0,0,0,2,0,29],[0,8,0,0,0,4,0,29,19,2,18,242,0,0,4,15,0,0,0,8,10,0,0,41,0,0,0,0,3,1,0,25],[0,0,0,96,3,48,2,112,0,0,4,194,3,48,1,151,0,0,0,32,4,48,0,140,0,0,0,0,4,3,0,25],[0,0,0,32,4,0,128,57,0,0,0,31,5,64,1,143,0,0,0,5,6,64,2,114,0,0,14,221,0,0,97,61],[0,0,0,0,7,0,0,25,0,0,0,5,8,112,2,16,0,0,0,0,9,138,0,25,0,0,0,0,8,129,3,79],[0,0,0,0,8,8,4,59,0,0,0,0,0,137,4,53,0,0,0,1,7,112,0,57,0,0,0,0,8,103,0,75],[0,0,14,213,0,0,65,61,0,0,0,0,7,5,0,75,0,0,14,236,0,0,97,61,0,0,0,5,6,96,2,16],[0,0,0,0,7,97,3,79,0,0,0,0,6,106,0,25,0,0,0,3,5,80,2,16,0,0,0,0,8,6,4,51],[0,0,0,0,8,88,1,207,0,0,0,0,8,88,2,47,0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137],[0,0,0,0,7,87,2,47,0,0,0,0,5,87,1,207,0,0,0,0,5,133,1,159,0,0,0,0,0,86,4,53],[0,0,0,1,2,32,1,144,0,0,17,158,0,0,97,61,0,0,0,31,1,64,0,57,0,0,0,96,1,16,1,143],[0,0,0,0,4,161,0,25,0,0,0,0,1,20,0,75,0,0,0,0,1,0,0,25,0,0,0,1,1,0,64,57],[0,0,4,211,2,64,0,156,0,0,17,114,0,0,33,61,0,0,0,1,1,16,1,144,0,0,17,114,0,0,193,61],[0,0,0,64,0,64,4,63,0,0,0,31,1,48,0,140,0,0,17,112,0,0,161,61,0,0,0,4,1,64,0,57],[0,0,0,0,2,10,4,51,0,0,0,0,2,2,0,75,0,0,17,187,0,0,193,61,0,0,5,26,2,0,0,65],[0,0,0,0,0,36,4,53,0,0,0,10,2,0,0,41,0,0,0,0,0,33,4,53,0,0,4,194,1,0,0,65],[0,0,0,0,2,0,4,20,0,0,4,194,3,32,0,156,0,0,0,0,2,1,128,25,0,0,4,194,3,64,0,156],[0,0,0,0,1,4,64,25,0,0,0,64,1,16,2,16,0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159],[0,0,4,235,1,16,1,199,0,0,128,3,2,0,0,57,0,8,0,0,0,4,0,29,19,2,18,242,0,0,4,15],[0,0,0,8,10,0,0,41,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,4,194,3,48,1,151],[0,0,0,32,4,48,0,140,0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57,0,0,0,31,5,64,1,143],[0,0,0,5,6,64,2,114,0,0,15,35,0,0,97,61,0,0,0,0,7,0,0,25,0,0,0,5,8,112,2,16],[0,0,0,0,9,138,0,25,0,0,0,0,8,129,3,79,0,0,0,0,8,8,4,59,0,0,0,0,0,137,4,53],[0,0,0,1,7,112,0,57,0,0,0,0,8,103,0,75,0,0,15,27,0,0,65,61,0,0,0,0,7,5,0,75],[0,0,15,50,0,0,97,61,0,0,0,5,6,96,2,16,0,0,0,0,7,97,3,79,0,0,0,0,6,106,0,25],[0,0,0,3,5,80,2,16,0,0,0,0,8,6,4,51,0,0,0,0,8,88,1,207,0,0,0,0,8,88,2,47],[0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137,0,0,0,0,7,87,2,47,0,0,0,0,5,87,1,207],[0,0,0,0,5,133,1,159,0,0,0,0,0,86,4,53,0,0,0,1,2,32,1,144,0,0,17,197,0,0,97,61],[0,0,0,31,1,64,0,57,0,0,0,96,1,16,1,143,0,0,0,0,4,161,0,25,0,0,4,211,1,64,0,156],[0,0,17,114,0,0,33,61,0,0,0,64,0,64,4,63,0,0,0,32,1,48,0,140,0,0,17,112,0,0,65,61],[0,0,0,4,1,64,0,57,0,0,0,0,2,10,4,51,0,0,0,0,2,2,0,75,0,0,17,226,0,0,193,61],[0,0,4,217,2,0,0,65,0,0,0,0,0,36,4,53,0,0,0,9,2,0,0,41,0,0,0,0,0,33,4,53],[0,0,4,194,1,0,0,65,0,0,0,0,2,0,4,20,0,0,4,194,3,32,0,156,0,0,0,0,2,1,128,25],[0,0,4,194,3,64,0,156,0,0,0,0,1,4,64,25,0,0,0,64,1,16,2,16,0,0,0,192,2,32,2,16],[0,0,0,0,1,18,1,159,0,0,4,235,1,16,1,199,0,0,128,4,2,0,0,57,0,8,0,0,0,4,0,29],[19,2,18,242,0,0,4,15,0,0,0,8,10,0,0,41,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112],[0,0,4,194,3,48,1,151,0,0,0,32,4,48,0,140,0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57],[0,0,0,31,5,64,1,143,0,0,0,5,6,64,2,114,0,0,15,100,0,0,97,61,0,0,0,0,7,0,0,25],[0,0,0,5,8,112,2,16,0,0,0,0,9,138,0,25,0,0,0,0,8,129,3,79,0,0,0,0,8,8,4,59],[0,0,0,0,0,137,4,53,0,0,0,1,7,112,0,57,0,0,0,0,8,103,0,75,0,0,15,92,0,0,65,61],[0,0,0,0,7,5,0,75,0,0,15,115,0,0,97,61,0,0,0,5,6,96,2,16,0,0,0,0,7,97,3,79],[0,0,0,0,6,106,0,25,0,0,0,3,5,80,2,16,0,0,0,0,8,6,4,51,0,0,0,0,8,88,1,207],[0,0,0,0,8,88,2,47,0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137,0,0,0,0,7,87,2,47],[0,0,0,0,5,87,1,207,0,0,0,0,5,133,1,159,0,0,0,0,0,86,4,53,0,0,0,1,2,32,1,144],[0,0,17,236,0,0,97,61,0,0,0,31,1,64,0,57,0,0,0,96,1,16,1,143,0,0,0,0,4,161,0,25],[0,0,4,211,1,64,0,156,0,0,17,114,0,0,33,61,0,0,0,64,0,64,4,63,0,0,0,32,1,48,0,140],[0,0,17,112,0,0,65,61,0,0,0,0,1,10,4,51,0,0,0,0,1,1,0,75,0,0,18,9,0,0,97,61],[0,0,4,236,1,64,0,156,0,0,17,114,0,0,33,61,0,0,0,64,1,64,0,57,0,0,0,64,0,16,4,63],[0,0,0,0,3,4,4,54,0,0,0,0,0,3,4,53,0,0,0,6,2,0,0,41,0,0,0,2,1,32,0,140],[0,0,17,121,0,0,129,61,0,0,0,0,0,36,4,53,0,6,0,0,0,3,0,29,0,0,0,0,0,3,4,53],[0,0,0,10,1,0,0,41,0,0,0,0,0,16,4,53,0,0,0,32,0,0,4,63,0,0,4,194,1,0,0,65],[0,0,0,0,2,0,4,20,0,0,4,194,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16],[0,0,4,219,1,16,1,199,0,0,128,16,2,0,0,57,0,8,0,0,0,4,0,29,19,2,18,242,0,0,4,15],[0,0,0,8,3,0,0,41,0,0,0,1,2,32,1,144,0,0,17,112,0,0,97,61,0,0,0,0,2,3,4,51],[0,0,0,1,3,32,0,140,0,0,0,6,5,0,0,41,0,0,17,121,0,0,33,61,0,0,0,0,1,1,4,59],[0,0,0,0,3,1,4,26,0,0,1,0,4,0,0,138,0,0,0,0,3,67,1,111,0,0,0,0,2,35,1,159],[0,0,0,0,0,33,4,27,0,0,0,0,3,5,4,51,0,0,0,1,4,48,0,140,0,0,17,121,0,0,33,61],[0,0,4,220,2,32,1,151,0,0,0,8,3,48,2,16,0,0,255,0,3,48,1,143,0,0,0,0,2,35,1,159],[0,0,0,0,0,33,4,27,0,0,4,221,1,0,0,65,0,0,0,0,0,16,4,57,0,0,0,0,1,0,4,22],[0,8,0,0,0,1,0,29,0,0,0,0,1,1,0,75,0,0,16,23,0,0,97,61,0,0,128,10,1,0,0,57],[0,0,0,4,0,16,4,67,0,0,4,194,1,0,0,65,0,0,0,0,2,0,4,20,0,0,4,194,3,32,0,156],[0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,4,222,1,16,1,199,0,0,128,2,2,0,0,57],[0,6,0,0,0,2,0,29,19,2,18,242,0,0,4,15,0,0,0,1,2,32,1,144,0,0,17,120,0,0,97,61],[0,0,0,0,1,1,4,59,0,0,0,0,1,1,0,75,0,0,17,112,0,0,97,61,0,0,0,64,4,0,4,61],[0,0,0,68,1,64,0,57,0,0,0,8,2,0,0,41,0,0,0,0,0,33,4,53,0,0,0,36,1,64,0,57],[0,0,0,10,2,0,0,41,0,0,0,0,0,33,4,53,0,0,4,223,1,0,0,65,0,0,0,0,0,20,4,53],[0,0,0,0,1,0,4,16,0,0,4,213,1,16,1,151,0,0,0,4,2,64,0,57,0,0,0,0,0,18,4,53],[0,0,4,194,1,0,0,65,0,0,0,0,2,0,4,20,0,0,4,194,3,32,0,156,0,0,0,0,2,1,128,25],[0,0,4,194,3,64,0,156,0,2,0,0,0,4,0,29,0,0,0,0,1,4,64,25,0,0,0,64,1,16,2,16],[0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159,0,0,4,224,1,16,1,199,0,0,128,10,2,0,0,57],[19,2,18,237,0,0,4,15,0,0,0,1,2,32,1,144,0,0,18,134,0,0,97,61,0,0,0,2,2,0,0,41],[0,0,4,211,1,32,0,156,0,0,17,114,0,0,33,61,0,0,0,64,0,32,4,63,0,0,4,221,1,0,0,65],[0,0,0,0,0,16,4,57,0,0,0,6,2,0,0,41,0,0,0,4,0,32,4,67,0,0,4,194,1,0,0,65],[0,0,0,0,4,0,4,20,0,0,4,194,3,64,0,156,0,0,0,0,4,1,128,25,0,0,0,192,1,64,2,16],[0,0,4,222,1,16,1,199,19,2,18,242,0,0,4,15,0,0,0,1,2,32,1,144,0,0,17,120,0,0,97,61],[0,0,0,0,1,1,4,59,0,0,0,0,1,1,0,75,0,0,17,112,0,0,97,61,0,0,0,64,4,0,4,61],[0,0,4,225,1,0,0,65,0,0,0,0,0,20,4,53,0,0,0,4,2,64,0,57,0,0,0,10,1,0,0,41],[0,2,0,0,0,2,0,29,0,0,0,0,0,18,4,53,0,0,0,9,1,0,0,41,0,0,4,226,1,16,1,151],[0,0,4,227,1,16,1,199,0,0,0,36,2,64,0,57,0,1,0,0,0,2,0,29,0,0,0,0,0,18,4,53],[0,0,4,194,1,0,0,65,0,0,0,0,2,0,4,20,0,0,4,194,3,32,0,156,0,0,0,0,2,1,128,25],[0,0,4,194,3,64,0,156,0,6,0,0,0,4,0,29,0,0,0,0,1,4,64,25,0,0,0,64,1,16,2,16],[0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159,0,0,4,228,1,16,1,199,0,0,128,2,2,0,0,57],[19,2,18,237,0,0,4,15,0,0,0,1,2,32,1,144,0,0,18,166,0,0,97,61,0,0,0,6,8,0,0,41],[0,0,4,211,1,128,0,156,0,0,17,114,0,0,33,61,0,0,0,64,0,128,4,63,0,0,0,8,1,0,0,41],[0,0,4,229,1,16,1,151,0,0,0,0,0,1,4,23,0,0,16,69,0,0,1,61,0,0,0,7,2,0,0,41],[0,0,0,4,0,32,4,67,0,0,4,194,1,0,0,65,0,0,0,0,4,0,4,20,0,0,4,194,3,64,0,156],[0,0,0,0,4,1,128,25,0,0,0,192,1,64,2,16,0,0,4,222,1,16,1,199,19,2,18,242,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,17,120,0,0,97,61,0,0,0,0,1,1,4,59,0,0,0,0,1,1,0,75],[0,0,17,112,0,0,97,61,0,0,0,64,4,0,4,61,0,0,4,225,1,0,0,65,0,0,0,0,0,20,4,53],[0,0,0,4,2,64,0,57,0,0,0,10,1,0,0,41,0,2,0,0,0,2,0,29,0,0,0,0,0,18,4,53],[0,0,0,9,1,0,0,41,0,0,4,226,1,16,1,151,0,0,4,227,1,16,1,199,0,0,0,36,2,64,0,57],[0,1,0,0,0,2,0,29,0,0,0,0,0,18,4,53,0,0,4,194,1,0,0,65,0,0,0,0,2,0,4,20],[0,0,4,194,3,32,0,156,0,0,0,0,2,1,128,25,0,0,4,194,3,64,0,156,0,6,0,0,0,4,0,29],[0,0,0,0,1,4,64,25,0,0,0,64,1,16,2,16,0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159],[0,0,4,228,1,16,1,199,0,0,128,2,2,0,0,57,19,2,18,237,0,0,4,15,0,0,0,1,2,32,1,144],[0,0,18,198,0,0,97,61,0,0,0,6,8,0,0,41,0,0,4,211,1,128,0,156,0,0,17,114,0,0,33,61],[0,0,0,64,0,128,4,63,0,0,0,4,4,0,0,41,0,0,4,194,2,64,1,151,0,0,0,0,1,0,4,20],[0,0,0,17,3,0,3,103,0,1,0,0,0,35,3,85,0,0,0,0,7,0,4,17,0,0,0,5,4,64,0,41],[0,0,0,5,5,64,0,108,0,0,0,0,5,0,0,25,0,0,0,1,5,0,64,57,0,0,0,1,5,80,1,144],[0,0,17,125,0,0,193,61,0,0,0,0,5,0,0,49,0,0,0,0,6,69,0,75,0,0,17,125,0,0,65,61],[0,0,0,0,2,35,3,79,0,0,0,0,3,69,0,73,0,0,4,194,3,48,1,151,0,1,0,0,0,50,3,229],[0,0,4,230,4,16,0,156,0,0,18,26,0,0,129,61,0,0,0,0,2,50,3,223,0,0,0,192,1,16,2,16],[0,0,4,231,1,16,1,151,0,0,4,232,1,16,1,199,0,1,0,0,0,18,3,181,0,0,0,0,1,18,3,175],[0,5,0,0,0,7,0,29,0,0,4,213,13,112,1,151,0,0,0,3,2,0,0,41,19,2,18,252,0,0,4,15],[0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,4,194,3,48,1,151,0,0,0,1,2,32,1,144],[0,0,18,43,0,0,97,61,0,0,0,63,2,48,0,57,0,0,4,233,2,32,1,151,0,0,0,64,6,0,4,61],[0,0,0,0,2,38,0,25,0,0,0,0,4,98,0,75,0,0,0,0,4,0,0,25,0,0,0,1,4,0,64,57],[0,0,4,211,5,32,0,156,0,0,17,114,0,0,33,61,0,0,0,1,4,64,1,144,0,0,17,114,0,0,193,61],[0,0,0,64,0,32,4,63,0,6,0,0,0,6,0,29,0,0,0,0,8,54,4,54,0,0,0,31,2,48,0,57],[0,0,0,5,2,32,2,114,0,0,16,133,0,0,97,61,0,0,0,0,4,0,0,49,0,0,0,17,4,64,3,103],[0,0,0,0,5,0,0,25,0,0,0,5,6,80,2,16,0,0,0,0,7,104,0,25,0,0,0,0,6,100,3,79],[0,0,0,0,6,6,4,59,0,0,0,0,0,103,4,53,0,0,0,1,5,80,0,57,0,0,0,0,6,37,0,75],[0,0,16,125,0,0,65,61,0,0,0,0,2,0,0,75,0,0,16,135,0,0,97,61,0,0,0,31,2,48,1,143],[0,0,0,5,3,48,2,114,0,0,16,147,0,0,97,61,0,0,0,0,4,0,0,25,0,0,0,5,5,64,2,16],[0,0,0,0,6,88,0,25,0,0,0,0,5,81,3,79,0,0,0,0,5,5,4,59,0,0,0,0,0,86,4,53],[0,0,0,1,4,64,0,57,0,0,0,0,5,52,0,75,0,0,16,139,0,0,65,61,0,0,0,0,4,2,0,75],[0,0,16,162,0,0,97,61,0,0,0,5,3,48,2,16,0,0,0,0,1,49,3,79,0,0,0,0,3,56,0,25],[0,0,0,3,2,32,2,16,0,0,0,0,4,3,4,51,0,0,0,0,4,36,1,207,0,0,0,0,4,36,2,47],[0,0,0,0,1,1,4,59,0,0,1,0,2,32,0,137,0,0,0,0,1,33,2,47,0,0,0,0,1,33,1,207],[0,0,0,0,1,65,1,159,0,0,0,0,0,19,4,53,0,8,0,0,0,8,0,29,0,0,4,221,1,0,0,65],[0,0,0,0,0,16,4,57,0,0,0,7,2,0,0,41,0,0,0,4,0,32,4,67,0,0,4,194,1,0,0,65],[0,0,0,0,4,0,4,20,0,0,4,194,3,64,0,156,0,0,0,0,4,1,128,25,0,0,0,192,1,64,2,16],[0,0,4,222,1,16,1,199,19,2,18,242,0,0,4,15,0,0,0,1,2,32,1,144,0,0,17,120,0,0,97,61],[0,0,0,0,1,1,4,59,0,0,0,0,1,1,0,75,0,0,17,112,0,0,97,61,0,0,0,64,4,0,4,61],[0,0,4,234,1,0,0,65,0,0,0,0,0,20,4,53,0,0,0,4,1,64,0,57,0,0,0,10,2,0,0,41],[0,0,0,0,0,33,4,53,0,0,4,194,1,0,0,65,0,0,0,0,2,0,4,20,0,0,4,194,3,32,0,156],[0,0,0,0,2,1,128,25,0,0,4,194,3,64,0,156,0,7,0,0,0,4,0,29,0,0,0,0,1,4,64,25],[0,0,0,64,1,16,2,16,0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159,0,0,4,235,1,16,1,199],[0,0,128,2,2,0,0,57,19,2,18,237,0,0,4,15,0,0,0,1,2,32,1,144,0,0,18,70,0,0,97,61],[0,0,0,7,9,0,0,41,0,0,4,211,1,144,0,156,0,0,0,6,1,0,0,41,0,0,17,114,0,0,33,61],[0,0,0,64,0,144,4,63,0,0,0,0,1,1,4,51,0,0,4,212,2,0,0,65,0,0,0,32,3,16,0,140],[0,0,0,0,3,0,0,25,0,0,0,0,3,2,64,25,0,0,4,212,4,16,1,151,0,0,0,0,5,4,0,75],[0,0,0,0,2,0,160,25,0,0,4,212,4,64,0,156,0,0,0,0,2,3,192,25,0,0,0,0,2,2,0,75],[0,0,17,112,0,0,193,61,0,0,0,8,2,0,0,41,0,0,0,0,2,2,4,51,0,0,4,211,3,32,0,156],[0,0,17,112,0,0,33,61,0,0,0,8,1,16,0,41,0,0,0,8,2,32,0,41,0,0,0,31,3,32,0,57],[0,0,4,212,4,0,0,65,0,0,0,0,5,19,0,75,0,0,0,0,5,0,0,25,0,0,0,0,5,4,128,25],[0,0,4,212,3,48,1,151,0,0,4,212,6,16,1,151,0,0,0,0,7,99,0,75,0,0,0,0,4,0,128,25],[0,0,0,0,3,99,1,63,0,0,4,212,3,48,0,156,0,0,0,0,4,5,192,25,0,0,0,0,3,4,0,75],[0,0,17,112,0,0,193,61,0,0,0,0,35,2,4,52,0,0,4,211,4,48,0,156,0,0,17,114,0,0,33,61],[0,0,0,5,4,48,2,16,0,0,0,63,4,64,0,57,0,0,0,32,5,0,0,138,0,0,0,0,4,84,1,111],[0,0,0,0,4,148,0,25,0,0,4,211,5,64,0,156,0,0,17,114,0,0,33,61,0,0,0,64,0,64,4,63],[0,0,0,0,0,57,4,53,0,0,0,6,3,48,2,16,0,0,0,0,3,35,0,25,0,0,0,0,4,19,0,75],[0,0,17,112,0,0,33,61,0,0,0,0,4,50,0,75,0,0,17,27,0,0,129,61,0,0,4,212,4,0,0,65],[0,0,0,0,5,9,0,25,0,0,0,0,6,33,0,73,0,0,0,64,7,96,0,140,0,0,0,0,7,0,0,25],[0,0,0,0,7,4,64,25,0,0,4,212,6,96,1,151,0,0,0,0,8,6,0,75,0,0,0,0,8,0,0,25],[0,0,0,0,8,4,32,25,0,0,4,212,6,96,0,156,0,0,0,0,8,7,192,25,0,0,0,0,6,8,0,75],[0,0,17,112,0,0,193,61,0,0,0,64,6,0,4,61,0,0,4,236,7,96,0,156,0,0,17,114,0,0,33,61],[0,0,0,32,5,80,0,57,0,0,0,64,7,96,0,57,0,0,0,64,0,112,4,63,0,0,0,0,135,2,4,52],[0,0,0,0,7,118,4,54,0,0,0,0,8,8,4,51,0,0,0,0,0,135,4,53,0,0,0,0,0,101,4,53],[0,0,0,64,2,32,0,57,0,0,0,0,6,50,0,75,0,0,17,1,0,0,65,61,0,0,4,221,1,0,0,65],[0,0,0,0,0,16,4,57,0,0,128,5,1,0,0,57,0,0,0,4,0,16,4,67,0,0,4,194,1,0,0,65],[0,0,0,0,2,0,4,20,0,0,4,194,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16],[0,0,4,222,1,16,1,199,0,0,128,2,2,0,0,57,19,2,18,242,0,0,4,15,0,0,0,1,2,32,1,144],[0,0,17,120,0,0,97,61,0,0,0,0,1,1,4,59,0,0,0,0,1,1,0,75,0,0,0,7,6,0,0,41],[0,0,17,112,0,0,97,61,0,0,0,64,7,0,4,61,0,0,0,36,1,112,0,57,0,0,0,64,2,0,0,57],[0,0,0,0,0,33,4,53,0,0,4,237,1,0,0,65,0,0,0,0,0,23,4,53,0,0,0,4,1,112,0,57],[0,0,0,10,2,0,0,41,0,0,0,0,0,33,4,53,0,0,0,0,1,6,4,51,0,0,0,68,2,112,0,57],[0,0,0,0,0,18,4,53,0,0,0,100,2,112,0,57,0,0,0,0,3,1,0,75,0,0,17,71,0,0,97,61],[0,0,0,0,3,0,0,25,0,0,0,32,6,96,0,57,0,0,0,0,4,6,4,51,0,0,0,0,84,4,4,52],[0,0,0,0,4,66,4,54,0,0,0,0,5,5,4,51,0,0,0,0,0,84,4,53,0,0,0,64,2,32,0,57],[0,0,0,1,3,48,0,57,0,0,0,0,4,19,0,75,0,0,17,61,0,0,65,61,0,0,0,0,1,114,0,73],[0,0,4,194,2,0,0,65,0,0,4,194,3,112,0,156,0,0,0,0,3,2,0,25,0,0,0,0,3,7,64,25],[0,0,0,64,3,48,2,16,0,0,4,194,4,16,0,156,0,0,0,0,1,2,128,25,0,0,0,96,1,16,2,16],[0,0,0,0,1,49,1,159,0,0,0,0,3,0,4,20,0,0,4,194,4,48,0,156,0,0,0,0,3,2,128,25],[0,0,0,192,2,48,2,16,0,0,0,0,1,33,1,159,0,0,128,5,2,0,0,57,0,8,0,0,0,7,0,29],[19,2,18,237,0,0,4,15,0,0,0,1,2,32,1,144,0,0,18,102,0,0,97,61,0,0,0,8,2,0,0,41],[0,0,4,211,1,32,0,156,0,0,0,0,1,2,0,25,0,0,17,114,0,0,33,61,0,0,0,64,0,16,4,63],[0,0,4,194,1,0,0,65,0,0,0,0,2,0,4,20,0,0,4,194,3,32,0,156,0,0,0,0,2,1,128,25],[0,0,0,192,1,32,2,16,0,0,4,243,1,16,1,199,0,0,128,13,2,0,0,57,0,0,0,4,3,0,0,57],[0,0,4,244,4,0,0,65,0,0,0,5,5,0,0,41,0,0,0,9,6,0,0,41,0,0,0,10,7,0,0,41],[19,2,18,237,0,0,4,15,0,0,0,1,1,32,1,144,0,0,17,112,0,0,97,61,0,0,0,0,0,1,4,45],[0,0,0,0,1,0,0,25,0,0,19,4,0,1,4,48,0,0,5,6,1,0,0,65,0,0,0,0,0,16,4,53],[0,0,0,65,1,0,0,57,0,0,0,4,0,16,4,63,0,0,4,235,1,0,0,65,0,0,19,4,0,1,4,48],[0,0,0,0,0,1,4,47,0,0,5,6,1,0,0,65,0,0,0,0,0,16,4,53,0,0,0,33,1,0,0,57],[0,0,17,117,0,0,1,61,0,0,5,6,1,0,0,65,0,0,0,0,0,16,4,53,0,0,0,17,1,0,0,57],[0,0,17,117,0,0,1,61,0,0,4,214,2,0,0,65,0,0,0,0,0,36,4,53,0,0,0,32,2,0,0,57],[0,0,0,0,0,35,4,53,0,0,0,68,1,64,0,57,0,0,5,30,2,0,0,65,0,0,0,0,0,33,4,53],[0,0,0,36,1,64,0,57,0,0,0,27,2,0,0,57,0,0,18,19,0,0,1,61,0,0,4,214,2,0,0,65],[0,0,0,0,0,36,4,53,0,0,0,32,2,0,0,57,0,0,0,0,0,35,4,53,0,0,0,100,1,64,0,57],[0,0,5,28,2,0,0,65,0,0,0,0,0,33,4,53,0,0,0,68,1,64,0,57,0,0,5,29,2,0,0,65],[0,0,0,0,0,33,4,53,0,0,0,36,1,64,0,57,0,0,0,40,2,0,0,57,0,0,0,0,0,33,4,53],[0,0,4,194,1,0,0,65,0,0,4,194,2,64,0,156,0,0,0,0,4,1,128,25,0,0,0,64,1,64,2,16],[0,0,4,241,1,16,1,199,0,0,19,4,0,1,4,48,0,0,0,64,2,0,4,61,0,0,0,31,4,48,1,143],[0,0,0,5,5,48,2,114,0,0,17,171,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16],[0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53],[0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,17,163,0,0,65,61,0,0,0,0,6,4,0,75],[0,0,18,229,0,0,97,61,0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25],[0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47],[0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207],[0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,18,229,0,0,1,61,0,0,4,214,2,0,0,65],[0,0,0,0,0,36,4,53,0,0,0,32,2,0,0,57,0,0,0,0,0,33,4,53,0,0,0,68,1,64,0,57],[0,0,5,25,2,0,0,65,0,0,0,0,0,33,4,53,0,0,0,36,1,64,0,57,0,0,0,21,2,0,0,57],[0,0,18,19,0,0,1,61,0,0,0,64,2,0,4,61,0,0,0,31,4,48,1,143,0,0,0,5,5,48,2,114],[0,0,17,210,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25],[0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57],[0,0,0,0,7,86,0,75,0,0,17,202,0,0,65,61,0,0,0,0,6,4,0,75,0,0,17,225,0,0,97,61],[0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16],[0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59],[0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159],[0,0,0,0,0,21,4,53,0,0,18,229,0,0,1,61,0,0,4,214,2,0,0,65,0,0,0,0,0,36,4,53],[0,0,0,32,2,0,0,57,0,0,0,0,0,33,4,53,0,0,0,68,1,64,0,57,0,0,5,27,2,0,0,65],[0,0,0,0,0,33,4,53,0,0,0,36,1,64,0,57,0,0,0,19,2,0,0,57,0,0,18,19,0,0,1,61],[0,0,0,64,2,0,4,61,0,0,0,31,4,48,1,143,0,0,0,5,5,48,2,114,0,0,17,249,0,0,97,61],[0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79],[0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75],[0,0,17,241,0,0,65,61,0,0,0,0,6,4,0,75,0,0,18,8,0,0,97,61,0,0,0,5,5,80,2,16],[0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51],[0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137],[0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53],[0,0,18,229,0,0,1,61,0,0,0,68,1,64,0,57,0,0,4,245,2,0,0,65,0,0,0,0,0,33,4,53],[0,0,0,36,1,64,0,57,0,0,0,26,2,0,0,57,0,0,0,0,0,33,4,53,0,0,4,214,1,0,0,65],[0,0,0,0,0,20,4,53,0,0,0,4,1,64,0,57,0,0,0,32,2,0,0,57,0,0,0,0,0,33,4,53],[0,0,4,194,1,0,0,65,0,0,4,194,2,64,0,156,0,0,0,0,4,1,128,25,0,0,0,64,1,64,2,16],[0,0,4,224,1,16,1,199,0,0,19,4,0,1,4,48,0,0,4,214,1,0,0,65,0,0,0,0,0,24,4,53],[0,0,0,32,1,0,0,57,0,0,0,2,2,0,0,41,0,0,0,0,0,18,4,53,0,0,0,8,1,0,0,57],[0,0,0,1,2,0,0,41,0,0,0,0,0,18,4,53,0,0,0,68,1,128,0,57,0,0,4,238,2,0,0,65],[0,0,0,0,0,33,4,53,0,0,4,194,1,0,0,65,0,0,4,194,2,128,0,156,0,0,0,0,8,1,128,25],[0,0,0,64,1,128,2,16,0,0,4,224,1,16,1,199,0,0,19,4,0,1,4,48,0,0,0,31,4,48,1,143],[0,0,0,5,2,48,2,114,0,0,18,54,0,0,97,61,0,0,0,0,5,0,0,25,0,0,0,5,6,80,2,16],[0,0,0,0,7,97,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,118,4,53,0,0,0,1,5,80,0,57],[0,0,0,0,6,37,0,75,0,0,18,47,0,0,65,61,0,0,0,0,5,4,0,75,0,0,18,68,0,0,97,61],[0,0,0,3,4,64,2,16,0,0,0,5,2,32,2,16,0,0,0,0,5,2,4,51,0,0,0,0,5,69,1,207],[0,0,0,0,5,69,2,47,0,0,0,0,1,33,3,79,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137],[0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,81,1,159,0,0,0,0,0,18,4,53],[0,0,0,96,1,48,2,16,0,0,19,4,0,1,4,48,0,0,0,64,2,0,4,61,0,0,0,0,3,1,0,25],[0,0,0,96,3,48,2,112,0,0,0,31,4,48,1,143,0,0,4,194,3,48,1,151,0,0,0,5,5,48,2,114],[0,0,18,86,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25],[0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57],[0,0,0,0,7,86,0,75,0,0,18,78,0,0,65,61,0,0,0,0,6,4,0,75,0,0,18,101,0,0,97,61],[0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16],[0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59],[0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159],[0,0,0,0,0,21,4,53,0,0,18,229,0,0,1,61,0,0,0,64,2,0,4,61,0,0,0,0,3,1,0,25],[0,0,0,96,3,48,2,112,0,0,0,31,4,48,1,143,0,0,4,194,3,48,1,151,0,0,0,5,5,48,2,114],[0,0,18,118,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25],[0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57],[0,0,0,0,7,86,0,75,0,0,18,110,0,0,65,61,0,0,0,0,6,4,0,75,0,0,18,133,0,0,97,61],[0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16],[0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59],[0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159],[0,0,0,0,0,21,4,53,0,0,18,229,0,0,1,61,0,0,0,64,2,0,4,61,0,0,0,0,3,1,0,25],[0,0,0,96,3,48,2,112,0,0,0,31,4,48,1,143,0,0,4,194,3,48,1,151,0,0,0,5,5,48,2,114],[0,0,18,150,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25],[0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57],[0,0,0,0,7,86,0,75,0,0,18,142,0,0,65,61,0,0,0,0,6,4,0,75,0,0,18,165,0,0,97,61],[0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16],[0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59],[0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159],[0,0,0,0,0,21,4,53,0,0,18,229,0,0,1,61,0,0,0,64,2,0,4,61,0,0,0,0,3,1,0,25],[0,0,0,96,3,48,2,112,0,0,0,31,4,48,1,143,0,0,4,194,3,48,1,151,0,0,0,5,5,48,2,114],[0,0,18,182,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25],[0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57],[0,0,0,0,7,86,0,75,0,0,18,174,0,0,65,61,0,0,0,0,6,4,0,75,0,0,18,197,0,0,97,61],[0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16],[0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59],[0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159],[0,0,0,0,0,21,4,53,0,0,18,229,0,0,1,61,0,0,0,64,2,0,4,61,0,0,0,0,3,1,0,25],[0,0,0,96,3,48,2,112,0,0,0,31,4,48,1,143,0,0,4,194,3,48,1,151,0,0,0,5,5,48,2,114],[0,0,18,214,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25],[0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57],[0,0,0,0,7,86,0,75,0,0,18,206,0,0,65,61,0,0,0,0,6,4,0,75,0,0,18,229,0,0,97,61],[0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16],[0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59],[0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159],[0,0,0,0,0,21,4,53,0,0,4,194,1,0,0,65,0,0,4,194,4,32,0,156,0,0,0,0,2,1,128,25],[0,0,0,64,1,32,2,16,0,0,0,96,2,48,2,16,0,0,0,0,1,33,1,159,0,0,19,4,0,1,4,48],[0,0,0,0,0,1,4,47,0,0,18,240,0,33,4,33,0,0,0,1,2,0,0,57,0,0,0,0,0,1,4,45],[0,0,0,0,2,0,0,25,0,0,0,0,0,1,4,45,0,0,18,245,0,33,4,35,0,0,0,1,2,0,0,57],[0,0,0,0,0,1,4,45,0,0,0,0,2,0,0,25,0,0,0,0,0,1,4,45,0,0,18,250,0,33,4,35],[0,0,0,1,2,0,0,57,0,0,0,0,0,1,4,45,0,0,0,0,2,0,0,25,0,0,0,0,0,1,4,45],[0,0,0,0,15,13,0,25,0,0,19,0,0,33,4,41,0,0,0,1,2,0,0,57,0,0,0,0,0,1,4,45],[0,0,0,0,2,0,0,25,0,0,0,0,0,1,4,45,0,0,19,2,0,0,4,50,0,0,19,3,0,1,4,46],[0,0,19,4,0,1,4,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255],[0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,1,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,156,77,83,90],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,236,128,103,198],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,236,128,103,199],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,236,249,91,138],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,243,56,95,182],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,156,77,83,91],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,187,15,214,16],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,233,241,140,23],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,93,56,38,255],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,93,56,39,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,123,81,15,232],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,218,31,180],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,117,152,165],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,60,218,51,81],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,87,24,9,129],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255],[128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],[8,195,121,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[67,97,108,108,97,98,108,101,32,111,110,108,121,32,98,121,32,115,101,108,102,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,128,0,0,0,0,0,0,0,0],[76,99,20,240,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,0,0,0,128,0,0,0,0,0,0,0,0],[2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0],[255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,255],[24,6,170,24,150,187,242,101,104,232,132,167,55,75,65,224,2,80,9,98,202,186,106,21,2,58,141,144,232,80,139,131],[2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,0,0,0,0,0,0],[87,153,82,252,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,0,0,0,0,0,0,0,0,0],[79,30,27,224,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[255,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],[0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0],[0,0,0,0,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,255,255,255,224],[194,228,255,151,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,191],[173,126,35,46,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[79,118,101,114,102,108,111,119,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[110,111,116,32,99,97,108,108,32,116,104,101,32,99,111,110,115,116,114,117,99,116,111,114,0,0,0,0,0,0,0,0],[84,104,101,32,118,97,108,117,101,32,109,117,115,116,32,98,101,32,122,101,114,111,32,105,102,32,119,101,32,100,111,32],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,0,0,0,0,0,0,0,0,0,0,0,0],[13,70,81,170,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[41,10,253,174,35,26,63,192,187,174,139,26,246,54,152,176,161,215,155,33,173,23,223,3,66,223,185,82,254,116,248,229],[84,104,101,32,99,111,100,101,32,104,97,115,104,32,105,115,32,110,111,116,32,107,110,111,119,110,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0],[48,99,149,198,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0],[105,110,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[111,109,32,115,101,113,117,101,110,116,105,97,108,32,116,111,32,97,114,98,105,116,114,97,114,121,32,111,114,100,101,114],[73,116,32,105,115,32,111,110,108,121,32,112,111,115,115,105,98,108,101,32,116,111,32,99,104,97,110,103,101,32,102,114],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,164,0,0,0,0,0,0,0,0,0,0,0,0],[2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0],[199,84,65,148,218,179,139,22,82,243,84,57,185,180,128,109,139,113,225,19,242,207,92,19,81,203,46,207,124,131,149,154],[67,97,110,32,111,110,108,121,32,98,101,32,99,97,108,108,101,100,32,98,121,32,70,79,82,67,69,95,68,69,80,76],[79,89,69,82,32,111,114,32,67,79,77,80,76,69,88,95,85,80,71,82,65,68,69,82,95,67,79,78,84,82,65,67],[84,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,164,0,0,0,128,0,0,0,0,0,0,0,0],[243,56,95,182,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,254,251],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,4,0,0,0,0,0,0,0,0,0,0,0,0],[78,72,123,113,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[96,118,97,108,117,101,96,32,112,114,111,118,105,100,101,100,32,105,115,32,110,111,116,32,101,113,117,97,108,32,116,111],[32,116,104,101,32,99,111,109,98,105,110,101,100,32,96,118,97,108,117,101,96,115,32,111,102,32,100,101,112,108,111,121],[109,101,110,116,115,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0],[77,226,228,104,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,192],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0],[63,182,244,241,93,221,74,117,88,140,169,52,137,74,210,205,202,178,90,80,18,226,81,94,23,131,67,61,1,40,97,26],[84,104,105,115,32,109,101,116,104,111,100,32,114,101,113,117,105,114,101,32,115,121,115,116,101,109,32,99,97,108,108,32],[102,108,97,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,0,0,0,128,0,0,0,0,0,0,0,0],[0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[107,101,99,99,97,107,50,53,54,32,114,101,116,117,114,110,101,100,32,105,110,118,97,108,105,100,32,100,97,116,97,0],[32,32,219,169,27,48,204,0,6,24,138,247,148,194,251,48,221,133,32,219,126,44,8,139,127,199,193,3,192,12,164,148],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,63],[99,186,227,169,149,29,56,232,163,251,183,183,9,9,175,193,32,6,16,252,91,197,90,222,36,47,129,89,116,103,79,35],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,128],[224,63,225,119,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[67,111,100,101,32,104,97,115,104,32,105,115,32,110,111,110,45,122,101,114,111,0,0,0,0,0,0,0,0,0,0,0],[90,169,182,181,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[65,99,99,111,117,110,116,32,105,115,32,111,99,99,117,112,105,101,100,0,0,0,0,0,0,0,0,0,0,0,0,0],[101,108,32,115,112,97,99,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[67,97,110,32,110,111,116,32,100,101,112,108,111,121,32,99,111,110,116,114,97,99,116,115,32,105,110,32,107,101,114,110],[66,121,116,101,99,111,100,101,72,97,115,104,32,99,97,110,110,111,116,32,98,101,32,122,101,114,111,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[102,160,219,144,188,18,229,126,186,185,180,16,164,164,78,192,138,235,127,123,45,162,126,219,57,164,176,218,172,217,136,253]],"0x0000000000000000000000000000000000008008":[[0,18,0,0,0,0,0,2,0,14,0,0,0,0,0,2,0,0,0,0,3,1,0,25,0,0,0,96,5,48,2,112],[0,0,2,104,3,80,1,151,0,1,0,0,0,49,3,85,0,2,0,0,0,49,3,85,0,3,0,0,0,49,3,85],[0,4,0,0,0,49,3,85,0,5,0,0,0,49,3,85,0,6,0,0,0,49,3,85,0,7,0,0,0,49,3,85],[0,8,0,0,0,49,3,85,0,9,0,0,0,49,3,85,0,10,0,0,0,49,3,85,0,11,0,0,0,49,3,85],[0,12,0,0,0,49,3,85,0,13,0,0,0,49,3,85,0,14,0,0,0,49,3,85,0,15,0,0,0,49,3,85],[0,16,0,0,0,49,3,85,0,17,0,0,0,1,3,85,0,0,2,104,0,80,1,157,0,0,0,128,4,0,0,57],[0,0,0,64,0,64,4,63,0,0,0,1,2,32,1,144,0,0,0,65,0,0,193,61,0,0,0,4,2,48,0,140],[0,0,4,38,0,0,65,61,0,0,0,0,2,1,4,59,0,0,0,224,2,32,2,112,0,0,2,106,6,32,0,156],[0,0,0,73,0,0,33,61,0,0,2,109,4,32,0,156,0,0,0,134,0,0,97,61,0,0,2,110,2,32,0,156],[0,0,4,38,0,0,193,61,0,0,0,0,2,0,4,22,0,0,0,0,2,2,0,75,0,0,4,38,0,0,193,61],[0,0,0,4,2,48,0,138,0,0,0,96,2,32,0,140,0,0,4,38,0,0,65,61,0,0,0,4,1,16,3,112],[0,0,0,0,3,1,4,59,0,0,0,0,1,3,0,75,0,0,0,0,1,0,0,25,0,0,0,1,1,0,192,57],[0,0,0,0,1,19,0,75,0,0,4,38,0,0,193,61,0,0,0,0,2,0,4,17,0,0,2,175,1,32,0,156],[0,0,1,3,0,0,65,61,0,0,2,132,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57],[0,0,0,132,0,16,4,63,0,0,0,52,1,0,0,57,0,0,0,164,0,16,4,63,0,0,2,177,1,0,0,65],[0,0,0,196,0,16,4,63,0,0,2,178,1,0,0,65,0,0,0,228,0,16,4,63,0,0,2,179,1,0,0,65],[0,0,9,158,0,1,4,48,0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75,0,0,4,38,0,0,193,61],[0,0,0,32,1,0,0,57,0,0,1,0,0,16,4,67,0,0,1,32,0,0,4,67,0,0,2,105,1,0,0,65],[0,0,9,157,0,1,4,46,0,0,2,107,6,32,0,156,0,0,0,197,0,0,97,61,0,0,2,108,2,32,0,156],[0,0,4,38,0,0,193,61,0,0,0,0,2,0,4,22,0,0,0,0,2,2,0,75,0,0,4,38,0,0,193,61],[0,0,0,4,2,48,0,138,0,0,0,32,2,32,0,140,0,0,4,38,0,0,65,61,0,0,0,4,2,16,3,112],[0,0,0,0,2,2,4,59,0,0,2,111,6,32,0,156,0,0,4,38,0,0,33,61,0,0,0,35,6,32,0,57],[0,0,2,112,7,0,0,65,0,0,0,0,8,54,0,75,0,0,0,0,8,0,0,25,0,0,0,0,8,7,128,25],[0,0,2,112,6,96,1,151,0,0,0,0,9,6,0,75,0,0,0,0,7,0,128,25,0,0,2,112,6,96,0,156],[0,0,0,0,7,8,192,25,0,0,0,0,6,7,0,75,0,0,4,38,0,0,193,61,0,0,0,4,6,32,0,57],[0,0,0,0,6,97,3,79,0,0,0,0,7,6,4,59,0,0,2,111,6,112,0,156,0,0,4,38,0,0,33,61],[0,0,0,36,6,32,0,57,0,0,0,0,2,103,0,25,0,0,0,0,3,35,0,75,0,0,4,38,0,0,65,61],[0,0,2,104,3,96,1,151,0,0,0,0,1,49,3,79,0,0,0,0,2,37,0,73,0,0,2,104,2,32,1,151],[0,0,0,0,8,0,4,20,0,0,0,0,3,0,4,20,0,1,0,0,0,33,3,229,0,0,2,113,5,48,0,156],[0,0,2,18,0,0,65,61,0,0,0,68,1,64,0,57,0,0,2,134,2,0,0,65,0,0,0,0,0,33,4,53],[0,0,0,36,1,64,0,57,0,0,0,8,2,0,0,57,0,0,0,0,0,33,4,53,0,0,2,132,1,0,0,65],[0,0,0,0,0,20,4,53,0,0,0,4,1,64,0,57,0,0,0,32,2,0,0,57,0,0,0,0,0,33,4,53],[0,0,2,104,1,0,0,65,0,0,2,104,2,64,0,156,0,0,0,0,4,1,128,25,0,0,0,64,1,64,2,16],[0,0,2,133,1,16,1,199,0,0,9,158,0,1,4,48,0,0,0,0,2,0,4,22,0,0,0,0,2,2,0,75],[0,0,4,38,0,0,193,61,0,0,0,4,2,48,0,138,0,0,0,32,2,32,0,140,0,0,4,38,0,0,65,61],[0,0,0,0,2,0,4,17,0,0,128,4,2,32,0,140,0,0,0,249,0,0,193,61,0,0,0,4,1,16,3,112],[0,0,0,0,2,1,4,59,0,0,0,3,1,0,0,57,0,13,0,0,0,1,0,29,0,0,0,0,1,1,4,26],[0,0,0,160,0,16,4,63,0,14,0,0,0,2,0,29,0,0,0,192,0,32,4,63,0,0,0,64,1,0,0,57],[0,0,0,128,0,16,4,63,0,0,0,224,1,0,0,57,0,0,0,64,0,16,4,63,0,0,2,104,1,0,0,65],[0,0,0,0,2,0,4,20,0,0,2,104,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16],[0,0,2,181,1,16,1,199,0,0,128,16,2,0,0,57,9,156,9,146,0,0,4,15,0,0,0,1,2,32,1,144],[0,0,4,38,0,0,97,61,0,0,0,0,1,1,4,59,0,0,0,13,2,0,0,41,0,0,0,0,0,18,4,27],[0,0,0,14,6,0,0,41,0,0,0,224,1,96,2,112,0,0,255,255,2,16,1,143,0,0,0,1,1,32,2,112],[0,0,0,1,3,16,0,57,0,0,0,7,65,48,0,201,0,0,0,7,84,16,1,26,0,0,0,0,3,67,0,75],[0,0,2,98,0,0,193,61,0,0,0,5,2,32,2,16,0,0,0,4,2,32,1,191,0,0,0,80,67,32,0,201],[0,0,0,80,84,48,1,26,0,0,0,0,4,66,0,75,0,0,2,98,0,0,193,61,0,0,0,0,1,49,0,25],[0,0,0,32,2,32,2,16,0,0,0,0,1,33,1,159,0,0,0,40,1,16,0,57,0,0,0,0,2,16,4,32],[0,0,0,64,1,0,4,61,0,0,0,0,2,2,0,75,0,0,2,112,0,0,193,61,0,0,0,68,2,16,0,57],[0,0,2,131,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,20,3,0,0,57],[0,0,7,41,0,0,1,61,0,0,0,0,2,0,4,22,0,0,0,0,2,2,0,75,0,0,4,38,0,0,193,61],[0,0,0,4,2,48,0,138,0,0,0,32,2,32,0,140,0,0,4,38,0,0,65,61,0,0,0,4,2,16,3,112],[0,0,0,0,2,2,4,59,0,0,2,111,4,32,0,156,0,0,4,38,0,0,33,61,0,0,0,35,4,32,0,57],[0,0,2,112,5,0,0,65,0,0,0,0,6,52,0,75,0,0,0,0,6,0,0,25,0,0,0,0,6,5,128,25],[0,0,2,112,4,64,1,151,0,0,0,0,7,4,0,75,0,0,0,0,5,0,128,25,0,0,2,112,4,64,0,156],[0,0,0,0,5,6,192,25,0,0,0,0,4,5,0,75,0,0,4,38,0,0,193,61,0,0,0,4,4,32,0,57],[0,0,0,0,5,65,3,79,0,0,0,0,5,5,4,59,0,11,0,0,0,5,0,29,0,0,2,111,5,80,0,156],[0,0,4,38,0,0,33,61,0,0,0,36,2,32,0,57,0,10,0,0,0,2,0,29,0,0,0,11,2,32,0,41],[0,0,0,0,2,50,0,75,0,0,4,38,0,0,33,61,0,0,0,0,2,0,4,17,0,0,128,1,2,32,0,140],[0,0,2,104,0,0,193,61,0,0,0,11,2,0,0,41,0,0,0,4,2,32,0,140,0,0,4,38,0,0,65,61],[0,0,0,32,2,64,0,57,0,0,0,0,2,33,3,79,0,0,0,0,4,2,4,59,0,0,2,137,2,64,0,156],[0,0,2,158,0,0,65,61,0,0,2,132,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57],[0,0,0,132,0,16,4,63,0,0,0,20,1,0,0,57,0,0,0,164,0,16,4,63,0,0,2,174,1,0,0,65],[0,0,1,0,0,0,1,61,0,0,2,132,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57],[0,0,0,132,0,16,4,63,0,0,0,20,1,0,0,57,0,0,0,164,0,16,4,63,0,0,2,180,1,0,0,65],[0,0,0,196,0,16,4,63,0,0,2,136,1,0,0,65,0,0,9,158,0,1,4,48,0,14,0,0,0,3,0,29],[0,13,0,0,0,2,0,29,0,0,2,119,1,0,0,65,0,0,0,128,0,16,4,63,0,0,2,104,1,0,0,65],[0,0,0,0,2,0,4,20,0,0,2,104,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16],[0,0,2,176,1,16,1,199,0,0,128,11,2,0,0,57,9,156,9,146,0,0,4,15,0,0,0,0,3,1,0,25],[0,0,0,96,3,48,2,112,0,0,2,104,3,48,1,151,0,0,0,32,4,48,0,140,0,0,0,0,4,3,0,25],[0,0,0,32,4,0,128,57,0,0,0,31,5,64,1,143,0,0,0,5,6,64,2,114,0,0,1,33,0,0,97,61],[0,0,0,0,7,0,0,25,0,0,0,5,8,112,2,16,0,0,0,0,9,129,3,79,0,0,0,0,9,9,4,59],[0,0,0,128,8,128,0,57,0,0,0,0,0,152,4,53,0,0,0,1,7,112,0,57,0,0,0,0,8,103,0,75],[0,0,1,25,0,0,65,61,0,0,0,0,7,5,0,75,0,0,1,48,0,0,97,61,0,0,0,5,6,96,2,16],[0,0,0,0,7,97,3,79,0,0,0,3,5,80,2,16,0,0,0,128,6,96,0,57,0,0,0,0,8,6,4,51],[0,0,0,0,8,88,1,207,0,0,0,0,8,88,2,47,0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137],[0,0,0,0,7,87,2,47,0,0,0,0,5,87,1,207,0,0,0,0,5,133,1,159,0,0,0,0,0,86,4,53],[0,0,0,1,2,32,1,144,0,0,1,239,0,0,97,61,0,0,0,31,1,64,0,57,0,0,0,96,2,16,1,143],[0,0,0,128,8,32,1,191,0,0,0,64,0,128,4,63,0,0,0,32,1,48,0,140,0,0,0,14,5,0,0,41],[0,0,4,38,0,0,65,61,0,0,0,128,1,0,4,61,0,0,255,255,3,16,0,140,0,0,4,38,0,0,33,61],[0,0,1,64,3,32,0,57,0,0,0,64,0,48,4,63,0,0,0,0,0,8,4,53,0,0,0,160,3,32,0,57],[0,11,0,0,0,3,0,29,0,0,0,0,0,83,4,53,0,0,2,123,4,0,0,65,0,0,0,0,3,5,0,75],[0,0,0,0,4,0,96,25,0,0,0,224,3,32,0,57,0,14,0,0,0,3,0,29,0,0,0,13,9,0,0,41],[0,0,0,0,0,147,4,53,0,0,0,192,3,32,0,57,0,9,0,0,0,3,0,29,0,0,0,0,0,19,4,53],[0,0,0,17,3,0,3,103,0,0,0,36,5,48,3,112,0,0,0,0,5,5,4,59,0,0,1,32,7,32,0,57],[0,0,1,0,2,32,1,191,0,10,0,0,0,2,0,29,0,0,0,0,0,82,4,53,0,0,0,68,2,48,3,112],[0,0,0,0,6,2,4,59,0,12,0,0,0,7,0,29,0,0,0,0,0,103,4,53,0,0,0,0,2,8,4,51],[0,0,0,248,7,32,2,16,0,0,0,64,2,0,4,61,0,0,0,32,3,32,0,57,0,0,0,0,0,115,4,53],[0,0,0,33,7,32,0,57,0,0,0,0,0,71,4,53,0,0,0,240,1,16,2,16,0,0,0,34,4,32,0,57],[0,0,0,0,0,20,4,53,0,0,0,96,1,144,2,16,0,0,0,36,4,32,0,57,0,0,0,0,0,20,4,53],[0,0,0,88,1,32,0,57,0,0,0,0,0,97,4,53,0,0,0,56,1,32,0,57,0,0,0,0,0,81,4,53],[0,0,0,88,1,0,0,57,0,0,0,0,0,18,4,53,0,0,2,124,1,32,0,156,0,0,3,195,0,0,33,61],[0,0,0,128,1,32,0,57,0,0,0,64,0,16,4,63,0,0,2,104,1,0,0,65,0,0,2,104,4,48,0,156],[0,0,0,0,3,1,128,25,0,0,0,64,3,48,2,16,0,0,0,0,2,2,4,51,0,0,2,104,4,32,0,156],[0,0,0,0,2,1,128,25,0,0,0,96,2,32,2,16,0,0,0,0,2,50,1,159,0,0,0,0,3,0,4,20],[0,0,2,104,4,48,0,156,0,0,0,0,3,1,128,25,0,0,0,192,1,48,2,16,0,0,0,0,1,33,1,159],[0,0,2,118,1,16,1,199,0,0,128,16,2,0,0,57,0,13,0,0,0,8,0,29,9,156,9,146,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,4,38,0,0,97,61,0,0,0,0,2,1,4,59,0,0,0,64,1,0,4,61],[0,0,0,64,3,16,0,57,0,0,0,0,4,0,4,26,0,0,0,0,0,35,4,53,0,0,0,32,2,16,0,57],[0,0,0,0,0,66,4,53,0,0,0,64,3,0,0,57,0,0,0,0,0,49,4,53,0,0,2,117,3,16,0,156],[0,0,3,195,0,0,33,61,0,0,0,96,3,16,0,57,0,0,0,64,0,48,4,63,0,0,2,104,3,0,0,65],[0,0,2,104,4,32,0,156,0,0,0,0,2,3,128,25,0,0,0,64,2,32,2,16,0,0,0,0,1,1,4,51],[0,0,2,104,4,16,0,156,0,0,0,0,1,3,128,25,0,0,0,96,1,16,2,16,0,0,0,0,1,33,1,159],[0,0,0,0,2,0,4,20,0,0,2,104,4,32,0,156,0,0,0,0,2,3,128,25,0,0,0,192,2,32,2,16],[0,0,0,0,1,18,1,159,0,0,2,118,1,16,1,199,0,0,128,16,2,0,0,57,9,156,9,146,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,4,38,0,0,97,61,0,0,0,0,1,1,4,59,0,0,0,0,0,16,4,27],[0,0,0,1,3,0,0,57,0,0,0,0,2,3,4,26,0,0,0,1,1,0,0,138,0,8,0,0,0,2,0,29],[0,0,0,0,1,18,0,75,0,0,2,98,0,0,97,61,0,0,0,8,1,0,0,41,0,0,0,1,1,16,0,57],[0,0,0,0,0,19,4,27,0,0,0,13,1,0,0,41,0,0,0,0,1,1,4,51,0,0,0,255,1,16,1,143],[0,0,0,64,2,0,4,61,0,0,0,0,1,18,4,54,0,0,0,11,4,0,0,41,0,0,0,0,4,4,4,51],[0,0,0,0,4,4,0,75,0,0,0,0,4,0,0,25,0,0,0,1,4,0,192,57,0,0,0,0,0,65,4,53],[0,0,0,9,1,0,0,41,0,0,0,0,1,1,4,51,0,0,255,255,1,16,1,143,0,0,0,64,4,32,0,57],[0,0,0,0,0,20,4,53,0,0,0,14,1,0,0,41,0,0,0,0,1,1,4,51,0,0,2,122,1,16,1,151],[0,0,0,96,4,32,0,57,0,0,0,0,0,20,4,53,0,0,0,10,1,0,0,41,0,0,0,0,1,1,4,51],[0,0,0,128,4,32,0,57,0,0,0,0,0,20,4,53,0,0,0,12,1,0,0,41,0,0,0,0,1,1,4,51],[0,0,0,160,4,32,0,57,0,0,0,0,0,20,4,53,0,0,2,104,5,0,0,65,0,0,2,104,1,32,0,156],[0,0,0,0,2,5,128,25,0,0,0,0,1,0,4,20,0,0,2,104,4,16,0,156,0,0,0,0,1,5,128,25],[0,0,0,64,2,32,2,16,0,0,0,192,1,16,2,16,0,0,0,0,1,33,1,159,0,0,2,125,1,16,1,199],[0,0,128,13,2,0,0,57,0,0,2,126,4,0,0,65,9,156,9,141,0,0,4,15,0,0,0,1,1,32,1,144],[0,0,4,38,0,0,97,61,0,0,0,120,1,0,0,57,0,0,0,0,3,16,4,32,0,0,0,64,1,0,4,61],[0,0,2,104,2,16,0,156,0,0,2,104,2,0,0,65,0,0,0,0,2,1,64,25,0,0,0,64,2,32,2,16],[0,0,0,0,3,3,0,75,0,0,4,96,0,0,193,61,0,0,0,68,3,16,0,57,0,0,2,131,4,0,0,65],[0,0,0,0,0,67,4,53,0,0,0,36,3,16,0,57,0,0,0,20,4,0,0,57,0,0,0,0,0,67,4,53],[0,0,2,132,3,0,0,65,0,0,0,0,0,49,4,53,0,0,0,4,1,16,0,57,0,0,0,32,3,0,0,57],[0,0,0,0,0,49,4,53,0,0,2,133,1,32,1,199,0,0,9,158,0,1,4,48,0,0,0,64,2,0,4,61],[0,0,0,31,4,48,1,143,0,0,0,5,5,48,2,114,0,0,1,252,0,0,97,61,0,0,0,0,6,0,0,25],[0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59],[0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,1,244,0,0,65,61],[0,0,0,0,6,4,0,75,0,0,2,11,0,0,97,61,0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79],[0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207],[0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47],[0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,2,104,1,0,0,65],[0,0,2,104,4,32,0,156,0,0,0,0,2,1,128,25,0,0,0,64,1,32,2,16,0,0,0,96,2,48,2,16],[0,0,0,0,1,33,1,159,0,0,9,158,0,1,4,48,0,14,0,0,0,8,0,29,0,12,0,0,0,6,0,29],[0,13,0,0,0,7,0,29,0,0,0,0,1,33,3,223,0,0,0,192,2,48,2,16,0,0,2,114,2,32,1,151],[0,0,2,115,2,32,1,199,0,1,0,0,0,33,3,181,0,0,0,0,1,33,3,175,0,0,128,16,2,0,0,57],[9,156,9,151,0,0,4,15,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,2,104,3,48,1,151],[0,0,0,1,2,32,1,144,0,0,2,131,0,0,97,61,0,0,0,63,2,48,0,57,0,0,2,116,4,32,1,151],[0,0,0,64,2,0,4,61,0,0,0,0,4,66,0,25,0,0,0,0,5,36,0,75,0,0,0,0,5,0,0,25],[0,0,0,1,5,0,64,57,0,0,2,111,6,64,0,156,0,0,3,195,0,0,33,61,0,0,0,1,5,80,1,144],[0,0,3,195,0,0,193,61,0,0,0,64,0,64,4,63,0,0,0,0,4,50,4,54,0,0,0,31,5,48,0,57],[0,0,0,5,5,80,2,114,0,0,2,61,0,0,97,61,0,0,0,0,6,0,0,49,0,0,0,17,6,96,3,103],[0,0,0,0,7,0,0,25,0,0,0,5,8,112,2,16,0,0,0,0,9,132,0,25,0,0,0,0,8,134,3,79],[0,0,0,0,8,8,4,59,0,0,0,0,0,137,4,53,0,0,0,1,7,112,0,57,0,0,0,0,8,87,0,75],[0,0,2,53,0,0,65,61,0,0,0,0,5,0,0,75,0,0,2,63,0,0,97,61,0,0,0,31,5,48,1,143],[0,0,0,5,3,48,2,114,0,0,2,75,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16],[0,0,0,0,8,116,0,25,0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53],[0,0,0,1,6,96,0,57,0,0,0,0,7,54,0,75,0,0,2,67,0,0,65,61,0,0,0,0,6,5,0,75],[0,0,2,90,0,0,97,61,0,0,0,5,3,48,2,16,0,0,0,0,1,49,3,79,0,0,0,0,3,52,0,25],[0,0,0,3,5,80,2,16,0,0,0,0,6,3,4,51,0,0,0,0,6,86,1,207,0,0,0,0,6,86,2,47],[0,0,0,0,1,1,4,59,0,0,1,0,5,80,0,137,0,0,0,0,1,81,2,47,0,0,0,0,1,81,1,207],[0,0,0,0,1,97,1,159,0,0,0,0,0,19,4,53,0,0,0,0,1,2,4,51,0,0,0,32,1,16,0,140],[0,0,0,14,1,0,0,41,0,0,7,35,0,0,193,61,0,0,0,0,4,4,4,51,0,0,0,0,2,0,4,20],[0,0,0,0,1,33,0,75,0,0,3,180,0,0,129,61,0,0,2,172,1,0,0,65,0,0,0,0,0,16,4,53],[0,0,0,17,1,0,0,57,0,0,0,4,0,16,4,63,0,0,2,173,1,0,0,65,0,0,9,158,0,1,4,48],[0,0,2,132,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63],[0,0,0,31,1,0,0,57,0,0,0,164,0,16,4,63,0,0,2,135,1,0,0,65,0,0,1,0,0,0,1,61],[0,0,0,0,0,97,4,53,0,0,2,104,2,0,0,65,0,0,0,0,3,0,4,20,0,0,2,104,4,48,0,156],[0,0,0,0,3,2,128,25,0,0,2,104,4,16,0,156,0,0,0,0,1,2,128,25,0,0,0,64,1,16,2,16],[0,0,0,192,2,48,2,16,0,0,0,0,1,18,1,159,0,0,2,182,1,16,1,199,0,0,128,13,2,0,0,57],[0,0,0,1,3,0,0,57,0,0,2,183,4,0,0,65,9,156,9,141,0,0,4,15,0,0,0,1,1,32,1,144],[0,0,4,38,0,0,97,61,0,0,0,0,1,0,0,25,0,0,9,157,0,1,4,46,0,0,0,31,4,48,1,143],[0,0,0,5,2,48,2,114,0,0,2,142,0,0,97,61,0,0,0,0,5,0,0,25,0,0,0,5,6,80,2,16],[0,0,0,0,7,97,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,118,4,53,0,0,0,1,5,80,0,57],[0,0,0,0,6,37,0,75,0,0,2,135,0,0,65,61,0,0,0,0,5,4,0,75,0,0,2,156,0,0,97,61],[0,0,0,3,4,64,2,16,0,0,0,5,2,32,2,16,0,0,0,0,5,2,4,51,0,0,0,0,5,69,1,207],[0,0,0,0,5,69,2,47,0,0,0,0,1,33,3,79,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137],[0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,81,1,159,0,0,0,0,0,18,4,53],[0,0,0,96,1,48,2,16,0,0,9,158,0,1,4,48,0,0,0,0,1,49,3,79,0,6,0,0,0,4,0,29],[0,0,0,224,7,64,2,112,0,0,2,138,2,0,0,65,0,0,0,64,0,32,4,63,0,0,64,0,2,0,0,57],[0,7,0,0,0,2,0,29,0,0,0,128,0,32,4,63,0,0,0,160,2,0,0,57,0,0,0,0,3,0,0,25],[0,0,0,5,4,48,2,16,0,0,0,0,4,65,3,79,0,0,0,0,4,4,4,59,0,0,0,0,2,66,4,54],[0,0,0,1,3,48,0,57,0,0,64,0,4,48,0,140,0,0,2,168,0,0,65,61,0,0,0,4,2,0,0,57],[0,0,0,6,1,0,0,41,0,0,2,115,1,16,0,156,0,0,0,0,9,0,0,25,0,0,3,13,0,0,129,61],[0,0,0,0,1,0,4,26,0,0,0,0,1,25,0,75,0,0,3,159,0,0,193,61,0,13,0,0,0,2,0,29],[0,0,0,6,1,0,0,41,0,0,2,142,1,16,0,156,0,0,2,197,0,0,33,61,0,0,2,143,1,0,0,65],[0,0,0,128,2,0,4,61,0,0,0,0,2,114,0,75,0,0,3,9,0,0,161,61,0,0,0,5,2,112,2,16],[0,0,0,160,2,32,0,57,0,0,0,0,0,18,4,53,0,0,63,255,2,112,0,140,0,0,0,1,7,112,0,57],[0,0,2,188,0,0,65,61,0,9,0,64,0,0,0,61,0,8,128,16,0,0,0,61,0,0,0,7,1,0,0,41],[0,6,0,0,0,1,0,29,0,7,0,1,0,16,2,120,0,0,0,0,4,0,0,25,0,0,0,1,1,64,2,16],[0,0,0,128,2,0,4,61,0,0,0,0,3,18,0,75,0,0,3,9,0,0,161,61,0,0,0,1,1,16,1,191],[0,0,0,0,2,18,0,75,0,0,3,9,0,0,161,61,0,0,0,5,1,16,2,16,0,0,0,160,1,16,0,57],[0,0,0,0,2,1,4,51,0,14,0,0,0,4,0,29,0,0,0,6,1,64,2,16,0,0,0,160,1,16,0,57],[0,12,0,0,0,1,0,29,0,0,0,0,3,1,4,51,0,0,0,64,1,0,4,61,0,0,0,64,4,16,0,57],[0,0,0,0,0,36,4,53,0,0,0,32,2,16,0,57,0,0,0,0,0,50,4,53,0,0,0,9,3,0,0,41],[0,0,0,0,0,49,4,53,0,0,2,117,3,16,0,156,0,0,3,195,0,0,33,61,0,0,0,96,3,16,0,57],[0,0,0,64,0,48,4,63,0,0,2,104,3,32,0,156,0,0,2,104,4,0,0,65,0,0,0,0,2,4,128,25],[0,0,0,64,2,32,2,16,0,0,0,0,1,1,4,51,0,0,2,104,3,16,0,156,0,0,0,0,1,4,128,25],[0,0,0,96,1,16,2,16,0,0,0,0,1,33,1,159,0,0,0,0,2,0,4,20,0,0,2,104,3,32,0,156],[0,0,0,0,2,4,128,25,0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159,0,0,2,118,1,16,1,199],[0,0,0,8,2,0,0,41,9,156,9,146,0,0,4,15,0,0,0,1,2,32,1,144,0,0,4,38,0,0,97,61],[0,0,0,128,2,0,4,61,0,0,0,14,4,0,0,41,0,0,0,0,2,66,0,75,0,0,3,9,0,0,161,61],[0,0,0,5,2,64,2,16,0,0,0,12,2,32,0,105,0,0,0,0,1,1,4,59,0,0,0,0,0,18,4,53],[0,0,0,1,4,64,0,57,0,0,0,7,1,64,0,108,0,0,2,203,0,0,65,61,0,0,0,6,1,0,0,41],[0,0,0,3,1,16,0,140,0,0,2,199,0,0,33,61,0,0,0,128,1,0,4,61,0,0,0,0,1,1,0,75],[0,0,5,23,0,0,193,61,0,0,2,172,1,0,0,65,0,0,0,0,0,16,4,53,0,0,0,50,1,0,0,57],[0,0,2,101,0,0,1,61,0,0,0,4,1,0,0,57,0,9,0,89,0,0,0,146,0,0,0,0,8,0,0,25],[0,0,0,0,9,0,0,25,0,8,0,0,0,7,0,29,0,0,0,88,3,16,0,57,0,13,0,0,0,3,0,29],[0,0,0,11,2,48,0,108,0,0,4,38,0,0,33,61,0,0,0,10,4,16,0,41,0,0,2,104,2,64,1,151],[0,0,0,0,1,0,4,20,0,0,0,17,3,0,3,103,0,1,0,0,0,35,3,85,0,0,0,9,5,64,0,108],[0,0,2,98,0,0,33,61,0,0,0,88,4,64,0,57,0,0,0,0,5,0,0,49,0,0,0,0,6,69,0,75],[0,0,2,98,0,0,65,61,0,12,0,0,0,9,0,29,0,14,0,0,0,8,0,29,0,0,0,0,2,35,3,79],[0,0,0,0,3,69,0,73,0,0,2,104,3,48,1,151,0,1,0,0,0,50,3,229,0,0,2,113,4,16,0,156],[0,0,8,14,0,0,129,61,0,0,0,0,2,50,3,223,0,0,0,192,1,16,2,16,0,0,2,114,1,16,1,151],[0,0,2,115,1,16,1,199,0,1,0,0,0,18,3,181,0,0,0,0,1,18,3,175,0,0,128,16,2,0,0,57],[9,156,9,151,0,0,4,15,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,2,104,3,48,1,151],[0,0,0,1,2,32,1,144,0,0,4,40,0,0,97,61,0,0,0,63,2,48,0,57,0,0,2,116,4,32,1,151],[0,0,0,64,2,0,4,61,0,0,0,0,4,66,0,25,0,0,0,0,5,36,0,75,0,0,0,0,5,0,0,25],[0,0,0,1,5,0,64,57,0,0,2,111,6,64,0,156,0,0,3,195,0,0,33,61,0,0,0,1,5,80,1,144],[0,0,3,195,0,0,193,61,0,0,0,64,0,64,4,63,0,0,0,0,4,50,4,54,0,0,0,31,5,48,0,57],[0,0,0,5,5,80,2,114,0,0,3,81,0,0,97,61,0,0,0,0,6,0,0,49,0,0,0,17,6,96,3,103],[0,0,0,0,7,0,0,25,0,0,0,5,8,112,2,16,0,0,0,0,9,132,0,25,0,0,0,0,8,134,3,79],[0,0,0,0,8,8,4,59,0,0,0,0,0,137,4,53,0,0,0,1,7,112,0,57,0,0,0,0,8,87,0,75],[0,0,3,73,0,0,65,61,0,0,0,0,5,0,0,75,0,0,3,83,0,0,97,61,0,0,0,5,5,48,2,114],[0,0,0,12,9,0,0,41,0,0,3,95,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16],[0,0,0,0,8,116,0,25,0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53],[0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,3,87,0,0,65,61,0,0,0,31,3,48,1,144],[0,0,3,110,0,0,97,61,0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,84,0,25],[0,0,0,3,3,48,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,54,1,207,0,0,0,0,6,54,2,47],[0,0,0,0,1,1,4,59,0,0,1,0,3,48,0,137,0,0,0,0,1,49,2,47,0,0,0,0,1,49,1,207],[0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,0,0,1,2,4,51,0,0,0,32,1,16,0,140],[0,0,0,14,3,0,0,41,0,0,7,35,0,0,193,61,0,0,0,128,1,0,4,61,0,0,0,0,1,49,0,75],[0,0,3,9,0,0,161,61,0,0,0,0,2,4,4,51,0,0,0,5,1,48,2,16,0,0,0,160,1,16,0,57],[0,0,0,0,0,33,4,53,0,0,0,64,1,0,4,61,0,0,0,64,3,16,0,57,0,0,0,0,0,35,4,53],[0,0,0,64,2,0,0,57,0,0,0,0,2,33,4,54,0,0,0,0,0,146,4,53,0,0,2,117,3,16,0,156],[0,0,3,195,0,0,33,61,0,0,0,96,3,16,0,57,0,0,0,64,0,48,4,63,0,0,2,104,3,32,0,156],[0,0,2,104,4,0,0,65,0,0,0,0,2,4,128,25,0,0,0,64,2,32,2,16,0,0,0,0,1,1,4,51],[0,0,2,104,3,16,0,156,0,0,0,0,1,4,128,25,0,0,0,96,1,16,2,16,0,0,0,0,1,33,1,159],[0,0,0,0,2,0,4,20,0,0,2,104,3,32,0,156,0,0,0,0,2,4,128,25,0,0,0,192,2,32,2,16],[0,0,0,0,1,18,1,159,0,0,2,118,1,16,1,199,0,0,128,16,2,0,0,57,9,156,9,146,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,0,8,7,0,0,41,0,0,0,14,8,0,0,41,0,0,4,38,0,0,97,61],[0,0,0,0,9,1,4,59,0,0,0,1,8,128,0,57,0,0,0,0,1,120,0,75,0,0,0,13,2,0,0,41],[0,0,0,0,1,2,0,25,0,0,3,18,0,0,65,61,0,0,2,180,0,0,1,61,0,0,0,64,1,0,4,61],[0,0,0,100,2,16,0,57,0,0,2,139,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,68,2,16,0,57],[0,0,2,140,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,60,3,0,0,57],[0,0,0,0,0,50,4,53,0,0,2,132,2,0,0,65,0,0,0,0,0,33,4,53,0,0,0,4,2,16,0,57],[0,0,0,32,3,0,0,57,0,0,0,0,0,50,4,53,0,0,2,104,2,0,0,65,0,0,2,104,3,16,0,156],[0,0,0,0,1,2,128,25,0,0,0,64,1,16,2,16,0,0,2,141,1,16,1,199,0,0,9,158,0,1,4,48],[0,8,0,0,0,2,0,29,0,0,0,2,1,0,0,57,0,11,0,0,0,1,0,29,0,0,0,0,3,1,4,26],[0,0,0,64,1,0,4,61,0,0,0,64,2,16,0,57,0,10,0,0,0,4,0,29,0,0,0,0,0,66,4,53],[0,0,0,32,2,16,0,57,0,0,0,0,0,50,4,53,0,0,0,64,3,0,0,57,0,9,0,0,0,3,0,29],[0,0,0,0,0,49,4,53,0,0,2,117,3,16,0,156,0,0,3,199,0,0,161,61,0,0,2,172,1,0,0,65],[0,0,0,0,0,16,4,53,0,0,0,65,1,0,0,57,0,0,2,101,0,0,1,61,0,0,0,96,3,16,0,57],[0,0,0,64,0,48,4,63,0,0,2,104,4,0,0,65,0,0,2,104,3,32,0,156,0,0,0,0,2,4,128,25],[0,0,0,64,2,32,2,16,0,0,0,0,1,1,4,51,0,0,2,104,3,16,0,156,0,0,0,0,1,4,128,25],[0,0,0,96,1,16,2,16,0,0,0,0,1,33,1,159,0,0,0,0,2,0,4,20,0,0,2,104,3,32,0,156],[0,0,0,0,2,4,128,25,0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159,0,0,2,118,1,16,1,199],[0,0,128,16,2,0,0,57,9,156,9,146,0,0,4,15,0,0,0,1,2,32,1,144,0,0,4,38,0,0,97,61],[0,0,0,0,1,1,4,59,0,0,0,11,2,0,0,41,0,0,0,0,0,18,4,27,0,0,2,119,1,0,0,65],[0,0,0,64,4,0,4,61,0,11,0,0,0,4,0,29,0,0,0,0,0,20,4,53,0,0,0,0,1,0,4,20],[0,0,2,104,2,16,0,156,0,0,2,104,3,0,0,65,0,0,0,0,1,3,128,25,0,0,2,104,2,64,0,156],[0,0,0,0,3,4,64,25,0,0,0,64,2,48,2,16,0,0,0,192,1,16,2,16,0,0,0,0,1,33,1,159],[0,0,2,120,1,16,1,199,0,0,128,11,2,0,0,57,9,156,9,146,0,0,4,15,0,0,0,11,10,0,0,41],[0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,2,104,3,48,1,151,0,0,0,32,4,48,0,140],[0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57,0,0,0,31,5,64,1,143,0,0,0,5,6,64,2,114],[0,0,4,2,0,0,97,61,0,0,0,0,7,0,0,25,0,0,0,5,8,112,2,16,0,0,0,0,9,138,0,25],[0,0,0,0,8,129,3,79,0,0,0,0,8,8,4,59,0,0,0,0,0,137,4,53,0,0,0,1,7,112,0,57],[0,0,0,0,8,103,0,75,0,0,3,250,0,0,65,61,0,0,0,0,9,10,0,25,0,0,0,0,7,5,0,75],[0,0,4,18,0,0,97,61,0,0,0,5,6,96,2,16,0,0,0,0,7,97,3,79,0,0,0,0,6,105,0,25],[0,0,0,3,5,80,2,16,0,0,0,0,8,6,4,51,0,0,0,0,8,88,1,207,0,0,0,0,8,88,2,47],[0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137,0,0,0,0,7,87,2,47,0,0,0,0,5,87,1,207],[0,0,0,0,5,133,1,159,0,0,0,0,0,86,4,53,0,0,0,1,2,32,1,144,0,0,4,67,0,0,97,61],[0,0,0,31,1,64,0,57,0,0,0,96,1,16,1,143,0,0,0,0,2,145,0,25,0,0,0,0,1,18,0,75],[0,0,0,0,1,0,0,25,0,0,0,1,1,0,64,57,0,7,0,0,0,2,0,29,0,0,2,111,2,32,0,156],[0,0,3,195,0,0,33,61,0,0,0,1,1,16,1,144,0,0,3,195,0,0,193,61,0,0,0,7,1,0,0,41],[0,0,0,64,0,16,4,63,0,0,0,32,1,48,0,140,0,0,4,38,0,0,65,61,0,0,0,0,1,9,4,51],[0,0,255,255,2,16,0,140,0,0,4,100,0,0,161,61,0,0,0,0,1,0,0,25,0,0,9,158,0,1,4,48],[0,0,0,31,4,48,1,143,0,0,0,5,2,48,2,114,0,0,4,51,0,0,97,61,0,0,0,0,5,0,0,25],[0,0,0,5,6,80,2,16,0,0,0,0,7,97,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,118,4,53],[0,0,0,1,5,80,0,57,0,0,0,0,6,37,0,75,0,0,4,44,0,0,65,61,0,0,0,0,5,4,0,75],[0,0,4,65,0,0,97,61,0,0,0,3,4,64,2,16,0,0,0,5,2,32,2,16,0,0,0,0,5,2,4,51],[0,0,0,0,5,69,1,207,0,0,0,0,5,69,2,47,0,0,0,0,1,33,3,79,0,0,0,0,1,1,4,59],[0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,81,1,159],[0,0,0,0,0,18,4,53,0,0,0,96,1,48,2,16,0,0,9,158,0,1,4,48,0,0,0,64,2,0,4,61],[0,0,0,31,4,48,1,143,0,0,0,5,5,48,2,114,0,0,4,80,0,0,97,61,0,0,0,0,6,0,0,25],[0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59],[0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,4,72,0,0,65,61],[0,0,0,0,6,4,0,75,0,0,4,95,0,0,97,61,0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79],[0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207],[0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47],[0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,2,11,0,0,1,61],[0,0,0,8,3,0,0,41,0,0,0,0,0,49,4,53,0,0,2,130,1,32,1,199,0,0,9,157,0,1,4,46],[0,0,0,7,2,0,0,41,0,0,2,121,2,32,0,156,0,0,3,195,0,0,33,61,0,0,0,7,3,0,0,41],[0,0,0,192,2,48,0,57,0,0,0,64,0,32,4,63,0,0,0,0,4,0,4,16,0,0,2,122,2,64,1,151],[0,0,0,96,5,48,0,57,0,5,0,0,0,5,0,29,0,0,0,0,0,37,4,53,0,0,0,32,5,48,0,57],[0,0,0,1,2,0,0,57,0,11,0,0,0,2,0,29,0,3,0,0,0,5,0,29,0,0,0,0,0,37,4,53],[0,0,0,160,2,48,0,57,0,0,0,10,7,0,0,41,0,6,0,0,0,2,0,29,0,0,0,0,0,114,4,53],[0,0,0,128,2,48,0,57,0,0,0,0,8,0,4,17,0,4,0,0,0,2,0,29,0,0,0,0,0,130,4,53],[0,0,0,0,0,3,4,53,0,0,0,64,2,48,0,57,0,2,0,0,0,2,0,29,0,0,0,0,0,18,4,53],[0,0,0,64,2,0,4,61,0,0,0,32,3,32,0,57,0,0,0,0,0,3,4,53,0,0,0,33,5,32,0,57],[0,0,2,123,6,0,0,65,0,0,0,0,0,101,4,53,0,0,0,240,1,16,2,16,0,0,0,34,5,32,0,57],[0,0,0,0,0,21,4,53,0,0,0,96,1,64,2,16,0,0,0,36,4,32,0,57,0,0,0,0,0,20,4,53],[0,0,0,88,1,32,0,57,0,0,0,0,0,113,4,53,0,0,0,88,1,0,0,57,0,0,0,0,0,18,4,53],[0,0,0,56,1,32,0,57,0,1,0,0,0,8,0,29,0,0,0,0,0,129,4,53,0,0,2,124,1,32,0,156],[0,0,3,195,0,0,33,61,0,0,0,128,1,32,0,57,0,0,0,64,0,16,4,63,0,0,2,104,1,0,0,65],[0,0,2,104,4,48,0,156,0,0,0,0,3,1,128,25,0,0,0,64,3,48,2,16,0,0,0,0,2,2,4,51],[0,0,2,104,4,32,0,156,0,0,0,0,2,1,128,25,0,0,0,96,2,32,2,16,0,0,0,0,2,50,1,159],[0,0,0,0,3,0,4,20,0,0,2,104,4,48,0,156,0,0,0,0,3,1,128,25,0,0,0,192,1,48,2,16],[0,0,0,0,1,33,1,159,0,0,2,118,1,16,1,199,0,0,128,16,2,0,0,57,9,156,9,146,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,4,38,0,0,97,61,0,0,0,0,2,1,4,59,0,0,0,64,1,0,4,61],[0,0,0,64,3,16,0,57,0,0,0,0,4,0,4,26,0,0,0,0,0,35,4,53,0,0,0,32,2,16,0,57],[0,0,0,0,0,66,4,53,0,0,0,9,3,0,0,41,0,0,0,0,0,49,4,53,0,0,2,117,3,16,0,156],[0,0,3,195,0,0,33,61,0,0,0,96,3,16,0,57,0,0,0,64,0,48,4,63,0,0,2,104,3,0,0,65],[0,0,2,104,4,32,0,156,0,0,0,0,2,3,128,25,0,0,0,64,2,32,2,16,0,0,0,0,1,1,4,51],[0,0,2,104,4,16,0,156,0,0,0,0,1,3,128,25,0,0,0,96,1,16,2,16,0,0,0,0,1,33,1,159],[0,0,0,0,2,0,4,20,0,0,2,104,4,32,0,156,0,0,0,0,2,3,128,25,0,0,0,192,2,32,2,16],[0,0,0,0,1,18,1,159,0,0,2,118,1,16,1,199,0,0,128,16,2,0,0,57,9,156,9,146,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,4,38,0,0,97,61,0,0,0,0,1,1,4,59,0,0,0,0,0,16,4,27],[0,0,0,11,1,0,0,41,0,0,0,0,1,1,4,26,0,0,0,1,2,0,0,138,0,0,0,0,2,33,0,75],[0,0,2,98,0,0,97,61,0,0,0,1,1,16,0,57,0,0,0,11,3,0,0,41,0,0,0,0,0,19,4,27],[0,0,0,7,1,0,0,41,0,0,0,0,1,1,4,51,0,0,0,255,1,16,1,143,0,0,0,64,2,0,4,61],[0,0,0,0,1,18,4,54,0,0,0,3,4,0,0,41,0,0,0,0,4,4,4,51,0,0,0,0,4,4,0,75],[0,0,0,0,4,0,0,25,0,0,0,1,4,0,192,57,0,0,0,0,0,65,4,53,0,0,0,2,1,0,0,41],[0,0,0,0,1,1,4,51,0,0,255,255,1,16,1,143,0,0,0,64,4,32,0,57,0,0,0,0,0,20,4,53],[0,0,0,5,1,0,0,41,0,0,0,0,1,1,4,51,0,0,2,122,1,16,1,151,0,0,0,96,4,32,0,57],[0,0,0,0,0,20,4,53,0,0,0,4,1,0,0,41,0,0,0,0,1,1,4,51,0,0,0,128,4,32,0,57],[0,0,0,0,0,20,4,53,0,0,0,6,1,0,0,41,0,0,0,0,1,1,4,51,0,0,0,160,4,32,0,57],[0,0,0,0,0,20,4,53,0,0,2,104,1,0,0,65,0,0,2,104,4,32,0,156,0,0,0,0,2,1,128,25],[0,0,0,0,5,0,4,20,0,0,2,104,4,80,0,156,0,0,0,0,5,1,128,25,0,0,0,64,1,32,2,16],[0,0,0,192,2,80,2,16,0,0,0,0,1,18,1,159,0,0,2,125,1,16,1,199,0,0,128,13,2,0,0,57],[0,0,2,126,4,0,0,65,9,156,9,141,0,0,4,15,0,0,0,1,1,32,1,144,0,0,4,38,0,0,97,61],[0,0,0,8,2,0,0,41,0,0,0,14,2,32,0,105,0,0,0,161,1,0,0,138,0,0,0,0,1,18,0,75],[0,0,2,98,0,0,33,61,0,0,0,13,1,0,0,41,0,0,0,92,1,16,0,57,0,0,0,80,67,16,0,201],[0,0,2,127,4,48,1,151,0,0,0,80,84,64,1,26,0,0,0,0,4,65,0,75,0,0,2,98,0,0,193,61],[0,0,0,160,4,32,0,57,0,0,0,0,2,52,0,25,0,0,0,0,3,66,0,75,0,0,0,0,3,0,0,25],[0,0,0,1,3,0,64,57,0,0,0,1,3,48,1,144,0,0,2,98,0,0,193,61,0,0,2,113,3,32,0,156],[0,0,8,34,0,0,65,61,0,0,0,64,4,0,4,61,0,0,0,117,0,0,1,61,0,0,0,5,1,0,0,138],[0,8,0,0,0,1,0,29,0,0,0,13,1,16,0,107,0,0,2,98,0,0,33,61,0,0,0,13,1,0,0,41],[0,0,0,4,3,16,0,57,0,0,0,11,1,48,0,108,0,0,4,38,0,0,33,61,0,0,0,160,1,0,4,61],[0,5,0,0,0,1,0,29,0,0,0,13,2,0,0,41,0,0,0,10,1,32,0,41,0,0,0,17,1,16,3,103],[0,0,0,0,1,1,4,59,0,0,2,115,2,16,0,156,0,0,0,0,9,0,0,25,0,0,6,138,0,0,129,61],[0,0,0,2,1,0,0,57,0,4,0,0,0,1,0,29,0,0,0,0,1,1,4,26,0,0,0,0,1,25,0,75],[0,0,7,53,0,0,193,61,0,0,0,0,2,3,0,25,0,0,0,8,1,32,0,108,0,0,2,98,0,0,33,61],[0,0,0,4,3,32,0,57,0,0,0,11,1,48,0,108,0,0,4,38,0,0,33,61,0,0,0,10,1,32,0,41],[0,0,0,17,1,16,3,103,0,0,0,0,1,1,4,59,0,0,2,115,2,16,0,156,0,0,0,0,9,0,0,25],[0,0,7,104,0,0,129,61,0,0,0,0,5,3,0,25,0,0,0,3,1,0,0,57,0,13,0,0,0,1,0,29],[0,0,0,0,1,1,4,26,0,0,0,0,1,25,0,75,0,0,8,21,0,0,193,61,0,0,0,11,1,80,0,108],[0,0,3,9,0,0,129,61,0,0,0,10,1,80,0,41,0,0,0,17,2,0,3,103,0,0,0,0,3,18,3,79],[0,0,0,0,3,3,4,59,0,0,2,161,3,48,1,151,0,0,2,123,3,48,0,156,0,0,8,112,0,0,193,61],[0,0,0,0,4,5,0,25,0,0,0,8,3,64,0,108,0,0,2,98,0,0,33,61,0,0,0,4,3,64,0,57],[0,0,0,11,4,48,0,108,0,0,4,38,0,0,33,61,0,0,0,1,1,16,0,57,0,0,0,0,1,18,3,79],[0,0,0,0,1,1,4,59,0,0,0,11,4,48,0,108,0,0,3,9,0,0,129,61,0,0,0,232,1,16,2,112],[0,0,0,10,3,48,0,41,0,0,0,0,4,50,3,79,0,0,0,5,3,80,0,57,0,12,0,0,0,49,0,29],[0,0,0,12,5,16,0,107,0,0,0,0,6,0,0,25,0,0,0,1,6,0,64,57,0,0,0,0,5,4,4,59],[0,0,0,1,4,96,1,144,0,0,2,98,0,0,193,61,0,0,0,12,6,0,0,41,0,0,0,11,4,96,0,108],[0,0,4,38,0,0,33,61,0,0,0,12,6,0,0,41,0,0,0,8,4,96,0,108,0,0,2,98,0,0,33,61],[0,0,0,12,4,0,0,41,0,0,0,4,7,64,0,57,0,0,0,11,4,112,0,108,0,0,4,38,0,0,33,61],[0,0,0,12,6,0,0,41,0,0,0,10,4,96,0,41,0,0,0,0,4,66,3,79,0,0,0,0,8,4,4,59],[0,0,0,224,6,128,2,112,0,0,1,16,148,96,0,201,0,0,2,115,9,128,0,156,0,0,5,115,0,0,65,61],[0,0,0,0,169,100,0,217,0,0,1,16,9,144,0,140,0,0,2,98,0,0,193,61,0,9,0,0,0,116,0,29],[0,0,0,9,9,64,0,107,0,0,0,0,9,0,0,25,0,0,0,1,9,0,64,57,0,0,0,1,9,144,1,144],[0,0,2,98,0,0,193,61,0,0,0,9,10,0,0,41,0,0,0,11,9,160,0,108,0,0,4,38,0,0,33,61],[0,0,2,115,8,128,0,156,0,0,5,129,0,0,65,61,0,0,0,0,152,100,0,217,0,0,1,16,8,128,0,140],[0,0,2,98,0,0,193,61,0,0,0,248,5,80,2,112,0,0,0,10,7,112,0,41,0,0,0,64,10,0,4,61],[0,0,0,68,8,160,0,57,0,0,0,128,9,0,0,57,0,0,0,0,0,152,4,53,0,0,0,36,8,160,0,57],[0,0,0,0,0,88,4,53,0,0,2,164,5,0,0,65,0,0,0,0,0,90,4,53,0,0,0,0,7,114,3,79],[0,0,0,132,5,160,0,57,0,0,0,0,0,69,4,53,0,0,0,4,5,160,0,57,0,0,0,0,0,101,4,53],[0,0,0,31,8,64,1,143,0,14,0,0,0,10,0,29,0,0,0,164,6,160,0,57,0,0,0,5,9,64,2,114],[0,0,5,158,0,0,97,61,0,0,0,0,10,0,0,25,0,0,0,5,11,160,2,16,0,0,0,0,12,182,0,25],[0,0,0,0,11,183,3,79,0,0,0,0,11,11,4,59,0,0,0,0,0,188,4,53,0,0,0,1,10,160,0,57],[0,0,0,0,11,154,0,75,0,0,5,150,0,0,65,61,0,0,0,10,3,48,0,41,0,0,0,0,10,8,0,75],[0,0,5,174,0,0,97,61,0,0,0,5,9,144,2,16,0,0,0,0,7,151,3,79,0,0,0,0,9,150,0,25],[0,0,0,3,8,128,2,16,0,0,0,0,10,9,4,51,0,0,0,0,10,138,1,207,0,0,0,0,10,138,2,47],[0,0,0,0,7,7,4,59,0,0,1,0,8,128,0,137,0,0,0,0,7,135,2,47,0,0,0,0,7,135,1,207],[0,0,0,0,7,167,1,159,0,0,0,0,0,121,4,53,0,0,0,0,7,70,0,25,0,0,0,0,0,7,4,53],[0,0,0,31,4,64,0,57,0,0,2,165,4,64,1,151,0,0,0,0,6,70,0,25,0,0,0,0,4,86,0,73],[0,0,0,14,5,0,0,41,0,0,0,100,5,80,0,57,0,0,0,0,0,69,4,53,0,0,0,0,4,50,3,79],[0,0,0,31,3,16,1,143,0,0,0,0,2,22,4,54,0,0,0,5,5,16,2,114,0,0,5,197,0,0,97,61],[0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25,0,0,0,0,7,116,3,79],[0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75],[0,0,5,189,0,0,65,61,0,0,0,0,6,3,0,75,0,0,5,212,0,0,97,61,0,0,0,5,5,80,2,16],[0,0,0,0,4,84,3,79,0,0,0,0,5,82,0,25,0,0,0,3,3,48,2,16,0,0,0,0,6,5,4,51],[0,0,0,0,6,54,1,207,0,0,0,0,6,54,2,47,0,0,0,0,4,4,4,59,0,0,1,0,3,48,0,137],[0,0,0,0,4,52,2,47,0,0,0,0,3,52,1,207,0,0,0,0,3,99,1,159,0,0,0,0,0,53,4,53],[0,0,0,0,3,18,0,25,0,0,0,0,0,3,4,53,0,0,0,31,1,16,0,57,0,0,2,166,1,16,1,151],[0,0,0,14,4,0,0,41,0,0,0,0,1,65,0,73,0,0,0,0,1,33,0,25,0,0,2,104,2,0,0,65],[0,0,2,104,3,64,0,156,0,0,0,0,3,2,0,25,0,0,0,0,3,4,64,25,0,0,0,64,3,48,2,16],[0,0,2,104,4,16,0,156,0,0,0,0,1,2,128,25,0,0,0,96,1,16,2,16,0,0,0,0,1,49,1,159],[0,0,0,0,3,0,4,20,0,0,2,104,4,48,0,156,0,0,0,0,3,2,128,25,0,0,0,192,2,48,2,16],[0,0,0,0,1,18,1,159,0,0,128,14,2,0,0,57,9,156,9,141,0,0,4,15,0,0,0,0,3,1,0,25],[0,0,0,96,3,48,2,112,0,0,2,104,3,48,1,151,0,0,0,32,4,48,0,140,0,0,0,0,4,3,0,25],[0,0,0,32,4,0,128,57,0,0,0,31,5,64,1,143,0,0,0,5,6,64,2,114,0,0,5,253,0,0,97,61],[0,0,0,0,7,0,0,25,0,0,0,5,8,112,2,16,0,0,0,14,9,128,0,41,0,0,0,0,8,129,3,79],[0,0,0,0,8,8,4,59,0,0,0,0,0,137,4,53,0,0,0,1,7,112,0,57,0,0,0,0,8,103,0,75],[0,0,5,245,0,0,65,61,0,0,0,0,7,5,0,75,0,0,6,12,0,0,97,61,0,0,0,5,6,96,2,16],[0,0,0,0,7,97,3,79,0,0,0,14,6,96,0,41,0,0,0,3,5,80,2,16,0,0,0,0,8,6,4,51],[0,0,0,0,8,88,1,207,0,0,0,0,8,88,2,47,0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137],[0,0,0,0,7,87,2,47,0,0,0,0,5,87,1,207,0,0,0,0,5,133,1,159,0,0,0,0,0,86,4,53],[0,0,0,1,2,32,1,144,0,0,8,170,0,0,97,61,0,0,0,31,1,64,0,57,0,0,0,96,2,16,1,143],[0,0,0,14,1,32,0,41,0,0,0,0,2,33,0,75,0,0,0,0,2,0,0,25,0,0,0,1,2,0,64,57],[0,0,2,111,4,16,0,156,0,0,3,195,0,0,33,61,0,0,0,1,2,32,1,144,0,0,3,195,0,0,193,61],[0,0,0,64,0,16,4,63,0,0,0,32,2,48,0,140,0,0,4,38,0,0,65,61,0,0,0,9,3,0,0,41],[0,0,0,11,2,48,0,108,0,0,8,199,0,0,193,61,0,0,0,14,1,0,0,41,0,0,0,0,1,1,4,51],[0,14,0,0,0,1,0,29,0,0,2,169,1,0,0,65,0,0,0,0,0,16,4,57,0,0,128,17,1,0,0,57],[0,0,0,4,0,16,4,67,0,0,2,104,1,0,0,65,0,0,0,0,2,0,4,20,0,0,2,104,3,32,0,156],[0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,2,170,1,16,1,199,0,0,128,2,2,0,0,57],[9,156,9,146,0,0,4,15,0,0,0,1,2,32,1,144,0,0,8,208,0,0,97,61,0,0,0,0,1,1,4,59],[0,0,0,0,1,1,0,75,0,0,4,38,0,0,97,61,0,0,0,64,3,0,4,61,0,0,2,171,1,0,0,65],[0,0,0,0,0,19,4,53,0,0,0,4,1,48,0,57,0,0,0,32,2,0,0,57,0,0,0,0,0,33,4,53],[0,0,0,36,1,48,0,57,0,0,0,12,4,0,0,41,0,0,0,0,0,65,4,53,0,0,0,31,2,64,1,143],[0,11,0,0,0,3,0,29,0,0,0,68,1,48,0,57,0,0,0,10,3,0,0,41,0,0,0,17,3,48,3,103],[0,0,0,5,4,64,2,114,0,0,6,75,0,0,97,61,0,0,0,0,5,0,0,25,0,0,0,5,6,80,2,16],[0,0,0,0,7,97,0,25,0,0,0,0,6,99,3,79,0,0,0,0,6,6,4,59,0,0,0,0,0,103,4,53],[0,0,0,1,5,80,0,57,0,0,0,0,6,69,0,75,0,0,6,67,0,0,65,61,0,0,0,0,5,2,0,75],[0,0,6,90,0,0,97,61,0,0,0,5,4,64,2,16,0,0,0,0,3,67,3,79,0,0,0,0,4,65,0,25],[0,0,0,3,2,32,2,16,0,0,0,0,5,4,4,51,0,0,0,0,5,37,1,207,0,0,0,0,5,37,2,47],[0,0,0,0,3,3,4,59,0,0,1,0,2,32,0,137,0,0,0,0,3,35,2,47,0,0,0,0,2,35,1,207],[0,0,0,0,2,82,1,159,0,0,0,0,0,36,4,53,0,0,0,12,2,0,0,41,0,0,0,0,1,33,0,25],[0,0,0,0,0,1,4,53,0,0,0,31,1,32,0,57,0,0,0,32,2,0,0,138,0,0,0,0,1,33,1,111],[0,0,2,104,2,0,0,65,0,0,0,11,4,0,0,41,0,0,2,104,3,64,0,156,0,0,0,0,3,2,0,25],[0,0,0,0,3,4,64,25,0,0,0,64,3,48,2,16,0,0,0,68,1,16,0,57,0,0,2,104,4,16,0,156],[0,0,0,0,1,2,128,25,0,0,0,96,1,16,2,16,0,0,0,0,1,19,1,159,0,0,0,0,3,0,4,20],[0,0,2,104,4,48,0,156,0,0,0,0,3,2,128,25,0,0,0,192,2,48,2,16,0,0,0,0,1,18,1,159],[0,0,128,17,2,0,0,57,9,156,9,141,0,0,4,15,0,0,0,1,2,32,1,144,0,0,8,209,0,0,97,61],[0,0,0,11,1,0,0,41,0,0,2,111,1,16,0,156,0,0,3,195,0,0,33,61,0,0,0,11,1,0,0,41],[0,0,0,64,0,16,4,63,0,0,0,5,1,0,0,41,0,0,0,0,0,16,4,29,0,0,0,10,1,0,0,41],[0,0,0,12,2,0,0,41,9,156,8,241,0,0,4,15,0,0,0,1,2,0,0,57,0,0,0,0,0,18,4,29],[0,0,0,4,1,0,0,41,0,0,0,14,3,0,0,41,0,0,0,0,0,49,4,29,0,0,0,0,0,0,4,27],[0,0,0,0,0,2,4,27,0,0,0,0,0,1,4,27,0,0,0,13,1,0,0,41,0,0,0,0,0,1,4,27],[0,0,0,0,1,0,0,25,0,0,9,157,0,1,4,46,0,7,0,224,0,16,2,120,0,0,0,0,8,0,0,25],[0,0,0,0,9,0,0,25,0,0,0,8,1,48,0,108,0,0,2,98,0,0,33,61,0,0,0,4,2,48,0,57],[0,0,0,11,1,32,0,108,0,0,4,38,0,0,33,61,0,0,0,10,3,48,0,41,0,0,0,17,1,0,3,103],[0,0,0,0,3,49,3,79,0,0,0,0,3,3,4,59,0,0,0,224,3,48,2,112,0,0,0,0,7,35,0,25],[0,0,0,0,4,55,0,75,0,0,0,0,4,0,0,25,0,0,0,1,4,0,64,57,0,0,0,1,4,64,1,144],[0,0,2,98,0,0,193,61,0,0,0,11,4,112,0,108,0,0,4,38,0,0,33,61,0,0,0,10,5,32,0,41],[0,0,2,104,4,80,1,151,0,0,0,0,2,0,4,20,0,1,0,0,0,65,3,85,0,0,0,0,5,83,0,25],[0,0,0,0,3,53,0,75,0,0,0,0,3,0,0,25,0,0,0,1,3,0,64,57,0,0,0,1,3,48,1,144],[0,0,2,98,0,0,193,61,0,0,0,0,3,0,0,49,0,0,0,0,6,83,0,75,0,0,2,98,0,0,65,61],[0,14,0,0,0,9,0,29,0,12,0,0,0,8,0,29,0,13,0,0,0,7,0,29,0,0,0,0,1,65,3,79],[0,0,0,0,3,83,0,73,0,0,2,104,3,48,1,151,0,1,0,0,0,49,3,229,0,0,2,104,4,32,0,156],[0,0,8,14,0,0,33,61,0,0,0,0,1,49,3,223,0,0,0,192,2,32,2,16,0,0,2,114,2,32,1,151],[0,0,2,115,2,32,1,199,0,1,0,0,0,33,3,181,0,0,0,0,1,33,3,175,0,0,128,16,2,0,0,57],[9,156,9,151,0,0,4,15,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,2,104,3,48,1,151],[0,0,0,1,2,32,1,144,0,0,7,77,0,0,97,61,0,0,0,63,2,48,0,57,0,0,2,116,4,32,1,151],[0,0,0,64,2,0,4,61,0,0,0,0,4,66,0,25,0,0,0,0,5,36,0,75,0,0,0,0,5,0,0,25],[0,0,0,1,5,0,64,57,0,0,2,111,6,64,0,156,0,0,3,195,0,0,33,61,0,0,0,1,5,80,1,144],[0,0,3,195,0,0,193,61,0,0,0,64,0,64,4,63,0,0,0,0,4,50,4,54,0,0,0,31,5,48,0,57],[0,0,0,5,5,80,2,114,0,0,6,221,0,0,97,61,0,0,0,0,6,0,0,49,0,0,0,17,6,96,3,103],[0,0,0,0,7,0,0,25,0,0,0,5,8,112,2,16,0,0,0,0,9,132,0,25,0,0,0,0,8,134,3,79],[0,0,0,0,8,8,4,59,0,0,0,0,0,137,4,53,0,0,0,1,7,112,0,57,0,0,0,0,8,87,0,75],[0,0,6,213,0,0,65,61,0,0,0,0,5,0,0,75,0,0,6,223,0,0,97,61,0,0,0,5,5,48,2,114],[0,0,0,14,9,0,0,41,0,0,6,235,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16],[0,0,0,0,8,116,0,25,0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53],[0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,6,227,0,0,65,61,0,0,0,31,3,48,1,144],[0,0,6,250,0,0,97,61,0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,84,0,25],[0,0,0,3,3,48,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,54,1,207,0,0,0,0,6,54,2,47],[0,0,0,0,1,1,4,59,0,0,1,0,3,48,0,137,0,0,0,0,1,49,2,47,0,0,0,0,1,49,1,207],[0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,0,0,1,2,4,51,0,0,0,32,1,16,0,140],[0,0,7,35,0,0,193,61,0,0,0,0,2,4,4,51,0,0,0,64,1,0,4,61,0,0,0,64,3,16,0,57],[0,0,0,0,0,35,4,53,0,0,0,32,2,16,0,57,0,0,0,0,0,146,4,53,0,0,0,9,3,0,0,41],[0,0,0,0,0,49,4,53,0,0,2,117,3,16,0,156,0,0,3,195,0,0,33,61,0,0,0,96,3,16,0,57],[0,0,0,64,0,48,4,63,0,0,2,104,3,32,0,156,0,0,2,104,4,0,0,65,0,0,0,0,2,4,128,25],[0,0,0,64,2,32,2,16,0,0,0,0,1,1,4,51,0,0,2,104,3,16,0,156,0,0,0,0,1,4,128,25],[0,0,0,96,1,16,2,16,0,0,0,0,1,33,1,159,0,0,0,0,2,0,4,20,0,0,2,104,3,32,0,156],[0,0,0,0,2,4,128,25,0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159,0,0,2,118,1,16,1,199],[0,0,128,16,2,0,0,57,9,156,9,146,0,0,4,15,0,0,0,1,2,32,1,144,0,0,0,13,3,0,0,41],[0,0,0,12,8,0,0,41,0,0,4,38,0,0,97,61,0,0,0,0,9,1,4,59,0,0,0,1,8,128,0,57],[0,0,0,7,1,128,0,108,0,0,6,141,0,0,65,61,0,0,5,40,0,0,1,61,0,0,0,64,1,0,4,61],[0,0,0,68,2,16,0,57,0,0,2,144,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57],[0,0,0,31,3,0,0,57,0,0,0,0,0,50,4,53,0,0,2,132,2,0,0,65,0,0,0,0,0,33,4,53],[0,0,0,4,2,16,0,57,0,0,0,32,3,0,0,57,0,0,0,0,0,50,4,53,0,0,2,104,2,0,0,65],[0,0,2,104,3,16,0,156,0,0,0,0,1,2,128,25,0,0,0,64,1,16,2,16,0,0,2,133,1,16,1,199],[0,0,9,158,0,1,4,48,0,0,0,64,1,0,4,61,0,0,0,132,2,16,0,57,0,0,2,145,3,0,0,65],[0,0,0,0,0,50,4,53,0,0,0,100,2,16,0,57,0,0,2,146,3,0,0,65,0,0,0,0,0,50,4,53],[0,0,0,68,2,16,0,57,0,0,2,147,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57],[0,0,0,68,3,0,0,57,0,0,0,0,0,50,4,53,0,0,2,132,2,0,0,65,0,0,0,0,0,33,4,53],[0,0,0,4,2,16,0,57,0,0,0,32,3,0,0,57,0,0,0,0,0,50,4,53,0,0,2,104,2,0,0,65],[0,0,2,104,3,16,0,156,0,0,0,0,1,2,128,25,0,0,0,64,1,16,2,16,0,0,2,148,1,16,1,199],[0,0,9,158,0,1,4,48,0,0,0,31,4,48,1,143,0,0,0,5,2,48,2,114,0,0,7,88,0,0,97,61],[0,0,0,0,5,0,0,25,0,0,0,5,6,80,2,16,0,0,0,0,7,97,3,79,0,0,0,0,7,7,4,59],[0,0,0,0,0,118,4,53,0,0,0,1,5,80,0,57,0,0,0,0,6,37,0,75,0,0,7,81,0,0,65,61],[0,0,0,0,5,4,0,75,0,0,7,102,0,0,97,61,0,0,0,3,4,64,2,16,0,0,0,5,2,32,2,16],[0,0,0,0,5,2,4,51,0,0,0,0,5,69,1,207,0,0,0,0,5,69,2,47,0,0,0,0,1,33,3,79],[0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207],[0,0,0,0,1,81,1,159,0,0,0,0,0,18,4,53,0,0,0,96,1,48,2,16,0,0,9,158,0,1,4,48],[0,6,0,224,0,16,2,120,0,0,0,0,8,0,0,25,0,0,0,0,9,0,0,25,0,0,0,8,1,48,0,108],[0,0,2,98,0,0,33,61,0,0,0,4,2,48,0,57,0,0,0,11,1,32,0,108,0,0,4,38,0,0,33,61],[0,0,0,10,3,48,0,41,0,0,0,17,1,0,3,103,0,0,0,0,3,49,3,79,0,0,0,0,3,3,4,59],[0,0,0,224,10,48,2,112,0,0,0,0,7,42,0,25,0,0,0,0,4,167,0,75,0,0,0,0,4,0,0,25],[0,0,0,1,4,0,64,57,0,0,0,1,4,64,1,144,0,0,2,98,0,0,193,61,0,0,0,11,4,112,0,108],[0,0,4,38,0,0,33,61,0,0,2,149,4,48,1,152,0,0,8,122,0,0,193,61,0,0,2,151,4,48,0,156],[0,0,8,126,0,0,129,61,0,0,2,152,3,48,1,152,0,0,8,130,0,0,97,61,0,0,0,10,4,32,0,41],[0,0,2,104,3,64,1,151,0,0,0,0,2,0,4,20,0,1,0,0,0,49,3,85,0,0,0,0,4,74,0,25],[0,0,0,0,5,164,0,75,0,0,0,0,5,0,0,25,0,0,0,1,5,0,64,57,0,0,0,1,5,80,1,144],[0,0,2,98,0,0,193,61,0,0,0,0,5,0,0,49,0,0,0,0,6,69,0,75,0,0,2,98,0,0,65,61],[0,13,0,0,0,10,0,29,0,14,0,0,0,9,0,29,0,7,0,0,0,8,0,29,0,12,0,0,0,7,0,29],[0,0,0,0,1,49,3,79,0,0,0,0,3,69,0,73,0,0,2,104,3,48,1,151,0,1,0,0,0,49,3,229],[0,0,2,104,4,32,0,156,0,0,8,14,0,0,33,61,0,0,0,0,1,49,3,223,0,0,0,192,2,32,2,16],[0,0,2,114,2,32,1,151,0,0,2,115,2,32,1,199,0,1,0,0,0,33,3,181,0,0,0,0,1,33,3,175],[0,0,0,2,2,0,0,57,9,156,9,151,0,0,4,15,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112],[0,0,2,104,3,48,1,151,0,0,0,1,2,32,1,144,0,0,8,137,0,0,97,61,0,0,0,63,2,48,0,57],[0,0,2,116,4,32,1,151,0,0,0,64,2,0,4,61,0,0,0,0,4,66,0,25,0,0,0,0,5,36,0,75],[0,0,0,0,5,0,0,25,0,0,0,1,5,0,64,57,0,0,2,111,6,64,0,156,0,0,3,195,0,0,33,61],[0,0,0,1,5,80,1,144,0,0,3,195,0,0,193,61,0,0,0,64,0,64,4,63,0,0,0,0,4,50,4,54],[0,0,0,31,5,48,0,57,0,0,0,5,5,80,2,114,0,0,0,13,10,0,0,41,0,0,7,195,0,0,97,61],[0,0,0,0,6,0,0,49,0,0,0,17,6,96,3,103,0,0,0,0,7,0,0,25,0,0,0,5,8,112,2,16],[0,0,0,0,9,132,0,25,0,0,0,0,8,134,3,79,0,0,0,0,8,8,4,59,0,0,0,0,0,137,4,53],[0,0,0,1,7,112,0,57,0,0,0,0,8,87,0,75,0,0,7,187,0,0,65,61,0,0,0,0,5,0,0,75],[0,0,7,197,0,0,97,61,0,0,0,5,5,48,2,114,0,0,0,14,9,0,0,41,0,0,7,209,0,0,97,61],[0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,116,0,25,0,0,0,0,7,113,3,79],[0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75],[0,0,7,201,0,0,65,61,0,0,0,31,3,48,1,144,0,0,7,224,0,0,97,61,0,0,0,5,5,80,2,16],[0,0,0,0,1,81,3,79,0,0,0,0,5,84,0,25,0,0,0,3,3,48,2,16,0,0,0,0,6,5,4,51],[0,0,0,0,6,54,1,207,0,0,0,0,6,54,2,47,0,0,0,0,1,1,4,59,0,0,1,0,3,48,0,137],[0,0,0,0,1,49,2,47,0,0,0,0,1,49,1,207,0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53],[0,0,0,64,1,0,4,61,0,0,0,0,2,2,4,51,0,0,0,32,2,32,0,140,0,0,8,164,0,0,193,61],[0,0,0,0,2,4,4,51,0,0,2,154,2,32,1,151,0,0,0,219,3,160,2,16,0,0,2,155,3,48,1,151],[0,0,0,0,2,35,1,159,0,0,2,123,2,32,1,199,0,0,0,64,3,16,0,57,0,0,0,0,0,35,4,53],[0,0,0,32,2,16,0,57,0,0,0,0,0,146,4,53,0,0,0,9,3,0,0,41,0,0,0,0,0,49,4,53],[0,0,2,117,3,16,0,156,0,0,3,195,0,0,33,61,0,0,0,96,3,16,0,57,0,0,0,64,0,48,4,63],[0,0,2,104,3,32,0,156,0,0,2,104,4,0,0,65,0,0,0,0,2,4,128,25,0,0,0,64,2,32,2,16],[0,0,0,0,1,1,4,51,0,0,2,104,3,16,0,156,0,0,0,0,1,4,128,25,0,0,0,96,1,16,2,16],[0,0,0,0,1,33,1,159,0,0,0,0,2,0,4,20,0,0,2,104,3,32,0,156,0,0,0,0,2,4,128,25],[0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159,0,0,2,118,1,16,1,199,0,0,128,16,2,0,0,57],[9,156,9,146,0,0,4,15,0,0,0,1,2,32,1,144,0,0,0,12,3,0,0,41,0,0,0,7,8,0,0,41],[0,0,4,38,0,0,97,61,0,0,0,0,9,1,4,59,0,0,0,1,8,128,0,57,0,0,0,6,1,128,0,108],[0,0,7,107,0,0,65,61,0,0,5,57,0,0,1,61,0,0,0,64,1,0,4,61,0,0,0,68,2,16,0,57],[0,0,2,134,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,8,3,0,0,57],[0,0,7,41,0,0,1,61,0,0,0,64,1,0,4,61,0,0,0,132,2,16,0,57,0,0,2,158,3,0,0,65],[0,0,0,0,0,50,4,53,0,0,0,100,2,16,0,57,0,0,2,159,3,0,0,65,0,0,0,0,0,50,4,53],[0,0,0,68,2,16,0,57,0,0,2,160,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57],[0,0,0,94,3,0,0,57,0,0,7,65,0,0,1,61,0,0,0,32,1,16,2,16,0,0,2,128,1,16,1,151],[0,0,0,0,1,18,1,159,0,0,0,0,2,16,4,32,0,0,0,64,1,0,4,61,0,0,0,0,2,2,0,75],[0,0,8,42,0,0,193,61,0,0,0,191,0,0,1,61,0,0,0,32,2,0,0,57,0,0,0,0,2,33,4,54],[0,0,0,13,5,0,0,41,0,0,0,0,0,82,4,53,0,0,0,31,3,80,1,143,0,0,0,64,2,16,0,57],[0,0,0,12,4,0,0,41,0,0,0,17,4,64,3,103,0,0,0,5,5,80,2,114,0,0,8,61,0,0,97,61],[0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25,0,0,0,0,7,116,3,79],[0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75],[0,0,8,53,0,0,65,61,0,0,0,0,6,3,0,75,0,0,8,76,0,0,97,61,0,0,0,5,5,80,2,16],[0,0,0,0,4,84,3,79,0,0,0,0,5,82,0,25,0,0,0,3,3,48,2,16,0,0,0,0,6,5,4,51],[0,0,0,0,6,54,1,207,0,0,0,0,6,54,2,47,0,0,0,0,4,4,4,59,0,0,1,0,3,48,0,137],[0,0,0,0,4,52,2,47,0,0,0,0,3,52,1,207,0,0,0,0,3,99,1,159,0,0,0,0,0,53,4,53],[0,0,0,13,3,0,0,41,0,0,0,0,2,50,0,25,0,0,0,0,0,2,4,53,0,0,0,95,2,48,0,57],[0,0,0,32,3,0,0,138,0,0,0,0,2,50,1,111,0,0,2,104,4,0,0,65,0,0,2,104,3,16,0,156],[0,0,0,0,1,4,128,25,0,0,0,64,1,16,2,16,0,0,2,104,3,32,0,156,0,0,0,0,2,4,128,25],[0,0,0,96,2,32,2,16,0,0,0,0,1,33,1,159,0,0,0,0,2,0,4,20,0,0,2,104,3,32,0,156],[0,0,0,0,2,4,128,25,0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159,0,0,2,118,1,16,1,199],[0,0,128,13,2,0,0,57,0,0,0,3,3,0,0,57,0,0,2,129,4,0,0,65,0,0,0,1,5,0,0,41],[0,0,0,10,6,0,0,41,9,156,9,141,0,0,4,15,0,0,0,1,1,32,1,144,0,0,4,38,0,0,97,61],[0,0,0,64,1,0,4,61,0,0,0,10,2,0,0,41,0,0,0,0,0,33,4,53,0,0,2,104,2,16,0,156],[0,0,2,104,1,0,128,65,0,0,0,64,1,16,2,16,0,0,2,130,1,16,1,199,0,0,9,157,0,1,4,46],[0,0,0,64,1,0,4,61,0,0,0,100,2,16,0,57,0,0,2,162,3,0,0,65,0,0,0,0,0,50,4,53],[0,0,0,68,2,16,0,57,0,0,2,163,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57],[0,0,0,39,3,0,0,57,0,0,3,168,0,0,1,61,0,0,0,64,1,0,4,61,0,0,0,68,2,16,0,57],[0,0,2,150,3,0,0,65,0,0,8,133,0,0,1,61,0,0,0,64,1,0,4,61,0,0,0,68,2,16,0,57],[0,0,2,157,3,0,0,65,0,0,8,133,0,0,1,61,0,0,0,64,1,0,4,61,0,0,0,68,2,16,0,57],[0,0,2,156,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,4,3,0,0,41],[0,0,7,41,0,0,1,61,0,0,0,31,4,48,1,143,0,0,0,5,2,48,2,114,0,0,8,148,0,0,97,61],[0,0,0,0,5,0,0,25,0,0,0,5,6,80,2,16,0,0,0,0,7,97,3,79,0,0,0,0,7,7,4,59],[0,0,0,0,0,118,4,53,0,0,0,1,5,80,0,57,0,0,0,0,6,37,0,75,0,0,8,141,0,0,65,61],[0,0,0,0,5,4,0,75,0,0,8,162,0,0,97,61,0,0,0,3,4,64,2,16,0,0,0,5,2,32,2,16],[0,0,0,0,5,2,4,51,0,0,0,0,5,69,1,207,0,0,0,0,5,69,2,47,0,0,0,0,1,33,3,79],[0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207],[0,0,0,0,1,81,1,159,0,0,0,0,0,18,4,53,0,0,0,96,1,48,2,16,0,0,9,158,0,1,4,48],[0,0,0,68,2,16,0,57,0,0,2,153,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57],[0,0,0,25,3,0,0,57,0,0,7,41,0,0,1,61,0,0,0,64,2,0,4,61,0,0,0,31,4,48,1,143],[0,0,0,5,5,48,2,114,0,0,8,183,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16],[0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53],[0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,8,175,0,0,65,61,0,0,0,0,6,4,0,75],[0,0,8,198,0,0,97,61,0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25],[0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47],[0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207],[0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,2,11,0,0,1,61,0,0,0,100,2,16,0,57],[0,0,2,167,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,68,2,16,0,57,0,0,2,168,3,0,0,65],[0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,42,3,0,0,57,0,0,3,168,0,0,1,61],[0,0,0,0,0,1,4,47,0,0,0,64,2,0,4,61,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112],[0,0,0,31,4,48,1,143,0,0,2,104,3,48,1,151,0,0,0,5,5,48,2,114,0,0,8,225,0,0,97,61],[0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79],[0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75],[0,0,8,217,0,0,65,61,0,0,0,0,6,4,0,75,0,0,8,240,0,0,97,61,0,0,0,5,5,80,2,16],[0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51],[0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137],[0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53],[0,0,2,11,0,0,1,61,0,0,2,104,4,16,1,151,0,0,0,0,3,0,4,20,0,0,0,17,5,0,3,103],[0,1,0,0,0,69,3,85,0,0,0,0,1,18,0,25,0,0,0,0,2,33,0,75,0,0,0,0,2,0,0,25],[0,0,0,1,2,0,64,57,0,0,0,1,2,32,1,144,0,0,9,78,0,0,193,61,0,0,0,0,6,0,0,49],[0,0,0,0,2,22,0,75,0,0,9,78,0,0,65,61,0,0,0,0,2,69,3,79,0,0,0,0,1,22,0,73],[0,0,2,104,1,16,1,151,0,1,0,0,0,18,3,229,0,0,2,113,4,48,0,156,0,0,9,82,0,0,129,61],[0,0,0,0,1,18,3,223,0,0,0,192,2,48,2,16,0,0,2,114,2,32,1,151,0,0,2,115,2,32,1,199],[0,1,0,0,0,33,3,181,0,0,0,0,1,33,3,175,0,0,128,16,2,0,0,57,9,156,9,151,0,0,4,15],[0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,2,104,3,48,1,151,0,0,0,1,2,32,1,144],[0,0,9,89,0,0,97,61,0,0,0,63,2,48,0,57,0,0,2,116,4,32,1,151,0,0,0,64,2,0,4,61],[0,0,0,0,4,66,0,25,0,0,0,0,5,36,0,75,0,0,0,0,5,0,0,25,0,0,0,1,5,0,64,57],[0,0,2,111,6,64,0,156,0,0,9,116,0,0,33,61,0,0,0,1,5,80,1,144,0,0,9,116,0,0,193,61],[0,0,0,64,0,64,4,63,0,0,0,0,4,50,4,54,0,0,0,31,5,48,0,57,0,0,0,5,5,80,2,114],[0,0,9,44,0,0,97,61,0,0,0,0,6,0,0,49,0,0,0,17,6,96,3,103,0,0,0,0,7,0,0,25],[0,0,0,5,8,112,2,16,0,0,0,0,9,132,0,25,0,0,0,0,8,134,3,79,0,0,0,0,8,8,4,59],[0,0,0,0,0,137,4,53,0,0,0,1,7,112,0,57,0,0,0,0,8,87,0,75,0,0,9,36,0,0,65,61],[0,0,0,0,5,0,0,75,0,0,9,46,0,0,97,61,0,0,0,31,5,48,1,143,0,0,0,5,3,48,2,114],[0,0,9,58,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,116,0,25],[0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57],[0,0,0,0,7,54,0,75,0,0,9,50,0,0,65,61,0,0,0,0,6,5,0,75,0,0,9,73,0,0,97,61],[0,0,0,5,3,48,2,16,0,0,0,0,1,49,3,79,0,0,0,0,3,52,0,25,0,0,0,3,5,80,2,16],[0,0,0,0,6,3,4,51,0,0,0,0,6,86,1,207,0,0,0,0,6,86,2,47,0,0,0,0,1,1,4,59],[0,0,1,0,5,80,0,137,0,0,0,0,1,81,2,47,0,0,0,0,1,81,1,207,0,0,0,0,1,97,1,159],[0,0,0,0,0,19,4,53,0,0,0,0,1,2,4,51,0,0,0,32,1,16,0,140,0,0,9,122,0,0,193,61],[0,0,0,0,1,4,4,51,0,0,0,0,0,1,4,45,0,0,2,172,1,0,0,65,0,0,0,0,0,16,4,53],[0,0,0,17,1,0,0,57,0,0,9,119,0,0,1,61,0,0,0,64,1,0,4,61,0,0,0,68,2,16,0,57],[0,0,2,134,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,8,3,0,0,57],[0,0,9,128,0,0,1,61,0,0,0,31,4,48,1,143,0,0,0,5,2,48,2,114,0,0,9,100,0,0,97,61],[0,0,0,0,5,0,0,25,0,0,0,5,6,80,2,16,0,0,0,0,7,97,3,79,0,0,0,0,7,7,4,59],[0,0,0,0,0,118,4,53,0,0,0,1,5,80,0,57,0,0,0,0,6,37,0,75,0,0,9,93,0,0,65,61],[0,0,0,0,5,4,0,75,0,0,9,114,0,0,97,61,0,0,0,3,4,64,2,16,0,0,0,5,2,32,2,16],[0,0,0,0,5,2,4,51,0,0,0,0,5,69,1,207,0,0,0,0,5,69,2,47,0,0,0,0,1,33,3,79],[0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207],[0,0,0,0,1,81,1,159,0,0,0,0,0,18,4,53,0,0,0,96,1,48,2,16,0,0,9,158,0,1,4,48],[0,0,2,172,1,0,0,65,0,0,0,0,0,16,4,53,0,0,0,65,1,0,0,57,0,0,0,4,0,16,4,63],[0,0,2,173,1,0,0,65,0,0,9,158,0,1,4,48,0,0,0,64,1,0,4,61,0,0,0,68,2,16,0,57],[0,0,2,144,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,31,3,0,0,57],[0,0,0,0,0,50,4,53,0,0,2,132,2,0,0,65,0,0,0,0,0,33,4,53,0,0,0,4,2,16,0,57],[0,0,0,32,3,0,0,57,0,0,0,0,0,50,4,53,0,0,2,104,2,0,0,65,0,0,2,104,3,16,0,156],[0,0,0,0,1,2,128,25,0,0,0,64,1,16,2,16,0,0,2,133,1,16,1,199,0,0,9,158,0,1,4,48],[0,0,0,0,0,1,4,47,0,0,9,144,0,33,4,33,0,0,0,1,2,0,0,57,0,0,0,0,0,1,4,45],[0,0,0,0,2,0,0,25,0,0,0,0,0,1,4,45,0,0,9,149,0,33,4,35,0,0,0,1,2,0,0,57],[0,0,0,0,0,1,4,45,0,0,0,0,2,0,0,25,0,0,0,0,0,1,4,45,0,0,9,154,0,33,4,35],[0,0,0,1,2,0,0,57,0,0,0,0,0,1,4,45,0,0,0,0,2,0,0,25,0,0,0,0,0,1,4,45],[0,0,9,156,0,0,4,50,0,0,9,157,0,1,4,46,0,0,9,158,0,1,4,48,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255],[0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,1,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,98,139,99,109],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,98,139,99,110],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,98,248,75,36],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,57,179,76,110],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,86,7,154,200],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255],[128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0],[0,0,0,0,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,255,255,255,224],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,159],[2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[138,200,76,14,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,63],[0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,127],[2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,0,0,0,0,0,0,0,0,0,0,0,0],[39,254,140,11,73,244,149,7,185,212,254,89,104,201,244,158,223,229,201,223,39,125,67,58,7,160,113,126,222,151,99,141],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,240],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,0,0,0,0],[58,54,228,114,145,244,32,31,175,19,127,171,8,29,146,41,91,206,45,83,190,44,108,166,139,168,44,127,170,156,226,65],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0],[70,97,105,108,101,100,32,116,111,32,99,104,97,114,103,101,32,103,97,115,0,0,0,0,0,0,0,0,0,0,0,0],[8,195,121,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,0,0,0,0,0,0,0,0,0],[79,118,101,114,102,108,111,119,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[67,97,108,108,97,98,108,101,32,111,110,108,121,32,98,121,32,116,104,101,32,98,111,111,116,108,111,97,100,101,114,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,128,0,0,0,0,0,0,0,0],[0,0,64,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,0,160],[110,111,116,32,101,113,117,97,108,32,116,111,32,99,104,97,105,110,101,100,76,111,103,115,72,97,115,104,0,0,0,0],[114,101,99,111,110,115,116,114,117,99,116,101,100,67,104,97,105,110,101,100,76,111,103,115,72,97,115,104,32,105,115,32],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,63,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],[114,171,238,69,181,158,52,74,248,166,229,32,36,28,71,68,175,242,110,212,17,244,196,176,15,138,240,154,218,218,67,186],[107,101,99,99,97,107,50,53,54,32,114,101,116,117,114,110,101,100,32,105,110,118,97,108,105,100,32,100,97,116,97,0],[72,97,115,104,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[32,105,115,32,110,111,116,32,101,113,117,97,108,32,116,111,32,99,104,97,105,110,101,100,77,101,115,115,97,103,101,115],[114,101,99,111,110,115,116,114,117,99,116,101,100,67,104,97,105,110,101,100,77,101,115,115,97,103,101,115,72,97,115,104],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,164,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[112,111,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[115,104,97,32,114,101,116,117,114,110,101,100,32,105,110,118,97,108,105,100,32,100,97,116,97,0,0,0,0,0,0,0],[0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],[6,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[112,114,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[112,112,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[97,105,110,101,100,76,49,66,121,116,101,99,111,100,101,115,82,101,118,101,97,108,68,97,116,97,72,97,115,104,0,0],[101,118,101,97,108,68,97,116,97,72,97,115,104,32,105,115,32,110,111,116,32,101,113,117,97,108,32,116,111,32,99,104],[114,101,99,111,110,115,116,114,117,99,116,101,100,67,104,97,105,110,101,100,76,49,66,121,116,101,99,111,100,101,115,82],[255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[105,115,109,97,116,99,104,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[115,116,97,116,101,32,100,105,102,102,32,99,111,109,112,114,101,115,115,105,111,110,32,118,101,114,115,105,111,110,32,109],[96,6,216,181,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,255,255,255,255,224],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,255,255,224],[100,97,116,97,32,97,114,114,97,121,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[69,120,116,114,97,32,100,97,116,97,32,105,110,32,116,104,101,32,116,111,116,97,108,76,50,84,111,76,49,80,117,98],[24,6,170,24,150,187,242,101,104,232,132,167,55,75,65,224,2,80,9,98,202,186,106,21,2,58,141,144,232,80,139,131],[2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,0,0,0,0,0,0],[37,85,210,193,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[78,72,123,113,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,0,0,0,0,0,0],[84,111,111,32,109,97,110,121,32,76,50,45,62,76,49,32,108,111,103,115,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,128,0,0,0,0,0,0,0,0],[84,104,105,115,32,109,101,116,104,111,100,32,114,101,113,117,105,114,101,32,116,104,101,32,99,97,108,108,101,114,32,116],[111,32,98,101,32,115,121,115,116,101,109,32,99,111,110,116,114,97,99,116,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,0,0,0,128,0,0,0,0,0,0,0,0],[73,110,97,112,112,114,111,112,114,105,97,116,101,32,99,97,108,108,101,114,0,0,0,0,0,0,0,0,0,0,0,0],[2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,160,0,0,0,0,0,0,0,0],[2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0],[72,13,60,159,114,123,94,92,18,3,212,198,31,177,133,211,127,8,230,178,220,94,155,191,152,89,27,26,122,221,245,124],[67,48,27,71,80,219,106,244,192,73,13,165,34,158,240,54,250,134,179,144,112,97,207,15,207,177,199,38,59,63,228,240]],"0x0000000000000000000000000000000000008009":[[0,18,0,0,0,0,0,2,0,7,0,0,0,0,0,2,0,0,0,0,6,1,0,25,0,0,0,96,7,96,2,112],[0,0,0,82,8,112,1,151,0,1,0,0,0,129,3,85,0,2,0,0,0,129,3,85,0,3,0,0,0,129,3,85],[0,4,0,0,0,129,3,85,0,5,0,0,0,129,3,85,0,6,0,0,0,129,3,85,0,7,0,0,0,129,3,85],[0,8,0,0,0,129,3,85,0,9,0,0,0,129,3,85,0,10,0,0,0,129,3,85,0,11,0,0,0,129,3,85],[0,12,0,0,0,129,3,85,0,13,0,0,0,129,3,85,0,14,0,0,0,129,3,85,0,15,0,0,0,129,3,85],[0,16,0,0,0,129,3,85,0,17,0,0,0,1,3,85,0,0,0,82,0,112,1,157,0,0,0,128,6,0,0,57],[0,0,0,64,0,96,4,63,0,0,0,0,9,0,4,22,0,0,0,1,6,32,1,144,0,0,0,47,0,0,193,61],[0,0,0,0,6,9,0,75,0,0,1,9,0,0,193,61,0,0,0,2,2,32,1,144,0,0,0,54,0,0,193,61],[0,0,0,0,2,0,4,17,0,0,0,84,2,32,0,156,0,0,0,54,0,0,65,61,0,0,0,97,1,0,0,65],[0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63,0,0,0,36,1,0,0,57],[0,0,0,164,0,16,4,63,0,0,0,101,1,0,0,65,0,0,0,196,0,16,4,63,0,0,0,102,1,0,0,65],[0,0,0,228,0,16,4,63,0,0,0,103,1,0,0,65,0,0,1,68,0,1,4,48,0,0,0,0,1,9,0,75],[0,0,1,9,0,0,193,61,0,0,0,32,1,0,0,57,0,0,1,0,0,16,4,67,0,0,1,32,0,0,4,67],[0,0,0,83,1,0,0,65,0,0,1,67,0,1,4,46,0,0,0,0,2,0,4,20,0,0,105,120,9,32,0,138],[0,0,105,121,2,32,0,140,0,0,0,0,9,0,64,25,0,0,0,85,6,64,1,151,0,0,0,0,2,0,4,16],[0,0,0,0,2,38,0,75,0,0,0,72,0,0,193,61,0,0,0,97,1,0,0,65,0,0,0,128,0,16,4,63],[0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63,0,0,0,30,1,0,0,57,0,0,0,164,0,16,4,63],[0,0,0,99,1,0,0,65,0,0,0,196,0,16,4,63,0,0,0,100,1,0,0,65,0,0,1,68,0,1,4,48],[0,0,0,0,2,3,0,75,0,0,0,166,0,0,193,61,0,0,0,0,10,0,4,17,0,0,0,0,0,0,4,23],[0,0,0,0,2,8,0,25,0,0,0,0,2,114,0,73,0,0,0,82,2,32,1,151,0,1,0,0,0,33,3,229],[0,0,0,82,3,144,0,156,0,0,0,247,0,0,33,61,0,0,0,1,3,80,1,144,0,0,0,0,1,33,3,223],[0,0,0,93,2,0,0,65,0,0,0,94,3,0,0,65,0,0,0,0,3,2,192,25,0,0,0,192,2,144,2,16],[0,0,0,95,2,32,1,151,0,0,0,0,2,50,1,159,0,1,0,0,0,33,3,181,0,0,0,0,1,33,3,175],[0,0,0,85,13,160,1,151,0,0,0,0,2,6,0,25,1,66,1,60,0,0,4,15,0,0,0,0,3,1,0,25],[0,0,0,96,3,48,2,112,0,0,0,82,3,48,1,151,0,0,0,1,2,32,1,144,0,0,1,17,0,0,97,61],[0,0,0,63,2,48,0,57,0,0,0,88,4,32,1,151,0,0,0,64,2,0,4,61,0,0,0,0,4,66,0,25],[0,0,0,0,5,36,0,75,0,0,0,0,5,0,0,25,0,0,0,1,5,0,64,57,0,0,0,89,6,64,0,156],[0,0,1,11,0,0,33,61,0,0,0,1,5,80,1,144,0,0,1,11,0,0,193,61,0,0,0,64,0,64,4,63],[0,0,0,0,4,50,4,54,0,0,0,31,5,48,0,57,0,0,0,5,5,80,2,114,0,0,0,127,0,0,97,61],[0,0,0,0,6,0,0,49,0,0,0,17,6,96,3,103,0,0,0,0,7,0,0,25,0,0,0,5,8,112,2,16],[0,0,0,0,9,132,0,25,0,0,0,0,8,134,3,79,0,0,0,0,8,8,4,59,0,0,0,0,0,137,4,53],[0,0,0,1,7,112,0,57,0,0,0,0,8,87,0,75,0,0,0,119,0,0,65,61,0,0,0,0,5,0,0,75],[0,0,0,129,0,0,97,61,0,0,0,31,5,48,1,143,0,0,0,5,3,48,2,114,0,0,0,141,0,0,97,61],[0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,116,0,25,0,0,0,0,7,113,3,79],[0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,54,0,75],[0,0,0,133,0,0,65,61,0,0,0,0,6,5,0,75,0,0,0,156,0,0,97,61,0,0,0,5,3,48,2,16],[0,0,0,0,1,49,3,79,0,0,0,0,3,52,0,25,0,0,0,3,5,80,2,16,0,0,0,0,6,3,4,51],[0,0,0,0,6,86,1,207,0,0,0,0,6,86,2,47,0,0,0,0,1,1,4,59,0,0,1,0,5,80,0,137],[0,0,0,0,1,81,2,47,0,0,0,0,1,81,1,207,0,0,0,0,1,97,1,159,0,0,0,0,0,19,4,53],[0,0,0,0,1,2,4,51,0,0,0,82,2,0,0,65,0,0,0,82,3,16,0,156,0,0,0,0,1,2,128,25],[0,0,0,82,3,64,0,156,0,0,0,0,4,2,128,25,0,0,0,64,2,64,2,16,0,0,0,96,1,16,2,16],[0,0,0,0,1,33,1,159,0,0,1,67,0,1,4,46,0,3,0,0,0,9,0,29,0,5,0,0,0,8,0,29],[0,6,0,0,0,7,0,29,0,7,0,0,0,5,0,29,0,0,0,86,1,0,0,65,0,0,0,160,0,16,4,63],[0,0,0,0,1,0,4,17,0,1,0,0,0,1,0,29,0,0,0,85,1,16,1,151,0,0,0,164,0,16,4,63],[0,2,0,0,0,6,0,29,0,0,0,196,0,96,4,63,0,4,0,0,0,3,0,29,0,0,0,228,0,48,4,63],[0,0,0,100,1,0,0,57,0,0,0,128,0,16,4,63,0,0,1,32,1,0,0,57,0,0,0,64,0,16,4,63],[0,0,0,82,1,0,0,65,0,0,0,0,2,0,4,20,0,0,0,82,3,32,0,156,0,0,0,0,2,1,128,25],[0,0,0,192,1,32,2,16,0,0,0,87,1,16,1,199,0,0,128,10,2,0,0,57,1,66,1,55,0,0,4,15],[0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,0,82,5,48,1,152,0,0,0,236,0,0,97,61],[0,0,0,63,3,80,0,57,0,0,0,88,3,48,1,151,0,0,0,64,4,0,4,61,0,0,0,0,3,52,0,25],[0,0,0,0,6,67,0,75,0,0,0,0,6,0,0,25,0,0,0,1,6,0,64,57,0,0,0,89,7,48,0,156],[0,0,1,11,0,0,33,61,0,0,0,1,6,96,1,144,0,0,1,11,0,0,193,61,0,0,0,64,0,48,4,63],[0,0,0,31,3,80,1,143,0,0,0,0,4,84,4,54,0,0,0,5,5,80,2,114,0,0,0,221,0,0,97,61],[0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,116,0,25,0,0,0,0,7,113,3,79],[0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75],[0,0,0,213,0,0,65,61,0,0,0,0,6,3,0,75,0,0,0,236,0,0,97,61,0,0,0,5,5,80,2,16],[0,0,0,0,1,81,3,79,0,0,0,0,4,84,0,25,0,0,0,3,3,48,2,16,0,0,0,0,5,4,4,51],[0,0,0,0,5,53,1,207,0,0,0,0,5,53,2,47,0,0,0,0,1,1,4,59,0,0,1,0,3,48,0,137],[0,0,0,0,1,49,2,47,0,0,0,0,1,49,1,207,0,0,0,0,1,81,1,159,0,0,0,0,0,20,4,53],[0,0,0,1,1,32,1,144,0,0,0,7,5,0,0,41,0,0,0,6,7,0,0,41,0,0,0,5,3,0,0,41],[0,0,0,4,4,0,0,41,0,0,0,3,9,0,0,41,0,0,1,9,0,0,97,61,0,0,0,90,1,64,0,156],[0,0,0,2,6,0,0,41,0,0,0,1,10,0,0,41,0,0,1,44,0,0,65,61,0,0,0,64,1,0,4,61],[0,0,0,68,2,16,0,57,0,0,0,96,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57],[0,0,0,8,3,0,0,57,0,0,0,0,0,50,4,53,0,0,0,97,2,0,0,65,0,0,0,0,0,33,4,53],[0,0,0,4,2,16,0,57,0,0,0,32,3,0,0,57,0,0,0,0,0,50,4,53,0,0,0,82,2,0,0,65],[0,0,0,82,3,16,0,156,0,0,0,0,1,2,128,25,0,0,0,64,1,16,2,16,0,0,0,98,1,16,1,199],[0,0,1,68,0,1,4,48,0,0,0,0,1,0,0,25,0,0,1,68,0,1,4,48,0,0,0,91,1,0,0,65],[0,0,0,0,0,16,4,53,0,0,0,65,1,0,0,57,0,0,0,4,0,16,4,63,0,0,0,92,1,0,0,65],[0,0,1,68,0,1,4,48,0,0,0,31,4,48,1,143,0,0,0,5,2,48,2,114,0,0,1,28,0,0,97,61],[0,0,0,0,5,0,0,25,0,0,0,5,6,80,2,16,0,0,0,0,7,97,3,79,0,0,0,0,7,7,4,59],[0,0,0,0,0,118,4,53,0,0,0,1,5,80,0,57,0,0,0,0,6,37,0,75,0,0,1,21,0,0,65,61],[0,0,0,0,5,4,0,75,0,0,1,42,0,0,97,61,0,0,0,3,4,64,2,16,0,0,0,5,2,32,2,16],[0,0,0,0,5,2,4,51,0,0,0,0,5,69,1,207,0,0,0,0,5,69,2,47,0,0,0,0,1,33,3,79],[0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207],[0,0,0,0,1,81,1,159,0,0,0,0,0,18,4,53,0,0,0,96,1,48,2,16,0,0,1,68,0,1,4,48],[0,0,0,0,2,0,0,49,0,0,0,17,1,0,3,103,0,0,0,0,0,4,4,23,0,1,0,0,0,1,3,85],[0,0,8,252,9,144,0,57,0,0,0,0,3,50,0,75,0,0,0,77,0,0,129,61,0,0,0,91,1,0,0,65],[0,0,0,0,0,16,4,53,0,0,0,17,1,0,0,57,0,0,1,14,0,0,1,61,0,0,1,58,0,33,4,33],[0,0,0,1,2,0,0,57,0,0,0,0,0,1,4,45,0,0,0,0,2,0,0,25,0,0,0,0,0,1,4,45],[0,0,0,0,15,13,0,25,0,0,1,64,0,33,4,41,0,0,0,1,2,0,0,57,0,0,0,0,0,1,4,45],[0,0,0,0,2,0,0,25,0,0,0,0,0,1,4,45,0,0,1,66,0,0,4,50,0,0,1,67,0,1,4,46],[0,0,1,68,0,1,4,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255],[0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,1,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],[87,153,82,252,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,160,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,255,255,255,224],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[78,72,123,113,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,0,0,0,0,0,0],[1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[79,118,101,114,102,108,111,119,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[8,195,121,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,0,0,0,0,0,0,0,0,0],[77,115,103,86,97,108,117,101,83,105,109,117,108,97,116,111,114,32,99,97,108,108,115,32,105,116,115,101,108,102,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,128,0,0,0,0,0,0,0,0],[84,104,105,115,32,109,101,116,104,111,100,32,114,101,113,117,105,114,101,32,115,121,115,116,101,109,32,99,97,108,108,32],[102,108,97,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,0,0,0,128,0,0,0,0,0,0,0,0],[34,10,122,216,106,86,85,195,94,88,55,242,140,26,244,22,221,183,6,50,184,65,139,51,50,146,77,156,176,109,14,138]],"0x000000000000000000000000000000000000800a":[[0,5,0,0,0,0,0,2,0,0,0,128,3,0,0,57,0,0,0,64,0,48,4,63,0,0,0,0,3,1,0,25],[0,0,0,96,3,48,2,112,0,0,0,216,3,48,1,151,0,0,0,1,2,32,1,144,0,0,0,36,0,0,193,61],[0,0,0,4,2,48,0,140,0,0,3,11,0,0,65,61,0,0,0,0,2,1,4,59,0,0,0,224,2,32,2,112],[0,0,0,218,4,32,0,156,0,0,0,44,0,0,161,61,0,0,0,219,4,32,0,156,0,0,0,56,0,0,161,61],[0,0,0,220,4,32,0,156,0,0,0,178,0,0,97,61,0,0,0,221,4,32,0,156,0,0,2,4,0,0,97,61],[0,0,0,222,2,32,0,156,0,0,3,11,0,0,193,61,0,0,0,0,2,0,4,22,0,0,0,0,2,2,0,75],[0,0,3,11,0,0,193,61,0,0,0,4,2,48,0,138,0,0,0,32,2,32,0,140,0,0,3,11,0,0,65,61],[0,0,0,4,1,16,3,112,0,0,0,0,1,1,4,59,0,0,0,230,1,16,1,151,0,0,0,0,0,16,4,53],[0,0,0,32,0,0,4,63,0,0,0,0,1,0,0,25,3,89,3,61,0,0,4,15,0,0,0,54,0,0,1,61],[0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75,0,0,3,11,0,0,193,61,0,0,0,32,1,0,0,57],[0,0,1,0,0,16,4,67,0,0,1,32,0,0,4,67,0,0,0,217,1,0,0,65,0,0,3,90,0,1,4,46],[0,0,0,225,4,32,0,156,0,0,0,122,0,0,33,61,0,0,0,228,1,32,0,156,0,0,1,194,0,0,97,61],[0,0,0,229,1,32,0,156,0,0,3,11,0,0,193,61,0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75],[0,0,3,11,0,0,193,61,0,0,0,1,1,0,0,57,0,0,0,0,1,1,4,26,0,0,2,1,0,0,1,61],[0,0,0,223,4,32,0,156,0,0,1,203,0,0,97,61,0,0,0,224,2,32,0,156,0,0,3,11,0,0,193,61],[0,0,0,0,2,0,4,22,0,0,0,0,2,2,0,75,0,0,3,11,0,0,193,61,0,0,0,4,2,48,0,138],[0,0,0,96,2,32,0,140,0,0,3,11,0,0,65,61,0,0,0,4,2,16,3,112,0,0,0,0,4,2,4,59],[0,0,0,230,2,64,0,156,0,0,3,11,0,0,33,61,0,0,0,36,2,16,3,112,0,0,0,0,2,2,4,59],[0,0,0,230,5,32,1,151,0,0,0,230,2,32,0,156,0,0,3,11,0,0,33,61,0,0,0,68,1,16,3,112],[0,0,0,0,1,1,4,59,0,4,0,0,0,1,0,29,0,0,0,0,1,0,4,17,0,0,128,1,2,16,0,140],[0,0,0,85,0,0,97,61,0,0,128,6,2,16,0,140,0,0,0,85,0,0,97,61,0,0,128,9,1,16,0,140],[0,0,2,148,0,0,193,61,0,0,0,0,0,64,4,53,0,0,0,32,0,0,4,63,0,0,0,216,1,0,0,65],[0,0,0,0,2,0,4,20,0,0,0,216,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16],[0,0,0,236,1,16,1,199,0,0,128,16,2,0,0,57,0,5,0,0,0,4,0,29,0,3,0,0,0,5,0,29],[3,89,3,84,0,0,4,15,0,0,0,5,3,0,0,41,0,0,0,1,2,32,1,144,0,0,3,11,0,0,97,61],[0,0,0,0,1,1,4,59,0,0,0,0,2,1,4,26,0,0,0,4,1,32,0,108,0,0,2,195,0,0,129,61],[0,0,0,64,1,0,4,61,0,0,0,68,2,16,0,57,0,0,0,243,3,0,0,65,0,0,0,0,0,50,4,53],[0,0,0,36,2,16,0,57,0,0,0,31,3,0,0,57,0,0,0,0,0,50,4,53,0,0,0,244,2,0,0,65],[0,0,0,0,0,33,4,53,0,0,0,4,2,16,0,57,0,0,0,32,3,0,0,57,0,0,0,0,0,50,4,53],[0,0,0,216,2,0,0,65,0,0,0,216,3,16,0,156,0,0,0,0,1,2,128,25,0,0,0,64,1,16,2,16],[0,0,0,245,1,16,1,199,0,0,3,91,0,1,4,48,0,0,0,226,4,32,0,156,0,0,1,253,0,0,97,61],[0,0,0,227,2,32,0,156,0,0,3,11,0,0,193,61,0,0,0,0,2,0,4,22,0,0,0,0,2,2,0,75],[0,0,3,11,0,0,193,61,0,0,0,4,2,48,0,138,0,0,0,64,2,32,0,140,0,0,3,11,0,0,65,61],[0,0,0,4,2,16,3,112,0,0,0,0,4,2,4,59,0,0,0,230,2,64,0,156,0,0,3,11,0,0,33,61],[0,0,0,36,1,16,3,112,0,0,0,0,5,1,4,59,0,0,0,0,1,0,4,17,0,0,128,1,1,16,0,140],[0,0,2,25,0,0,193,61,0,0,0,1,1,0,0,57,0,0,0,0,3,1,4,26,0,0,0,0,2,83,0,25],[0,0,0,0,3,50,0,75,0,0,0,0,3,0,0,25,0,0,0,1,3,0,64,57,0,0,0,1,3,48,1,144],[0,0,0,174,0,0,193,61,0,4,0,0,0,5,0,29,0,0,0,0,0,33,4,27,0,0,0,0,0,64,4,53],[0,0,0,32,0,0,4,63,0,0,0,216,1,0,0,65,0,0,0,0,2,0,4,20,0,0,0,216,3,32,0,156],[0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,0,236,1,16,1,199,0,0,128,16,2,0,0,57],[0,5,0,0,0,4,0,29,3,89,3,84,0,0,4,15,0,0,0,5,5,0,0,41,0,0,0,1,2,32,1,144],[0,0,3,11,0,0,97,61,0,0,0,0,1,1,4,59,0,0,0,0,3,1,4,26,0,0,0,4,4,0,0,41],[0,0,0,0,2,67,0,25,0,0,0,0,3,50,0,75,0,0,0,0,3,0,0,25,0,0,0,1,3,0,64,57],[0,0,0,1,3,48,1,144,0,0,2,246,0,0,97,61,0,0,0,251,1,0,0,65,0,0,0,0,0,16,4,53],[0,0,0,17,1,0,0,57,0,0,1,250,0,0,1,61,0,0,0,4,2,48,0,138,0,0,0,64,2,32,0,140],[0,0,3,11,0,0,65,61,0,0,0,4,2,16,3,112,0,0,0,0,8,2,4,59,0,0,0,230,2,128,0,156],[0,0,3,11,0,0,33,61,0,0,0,36,2,16,3,112,0,0,0,0,4,2,4,59,0,0,0,234,2,64,0,156],[0,0,3,11,0,0,33,61,0,0,0,35,2,64,0,57,0,0,0,235,5,0,0,65,0,0,0,0,6,50,0,75],[0,0,0,0,6,0,0,25,0,0,0,0,6,5,128,25,0,0,0,235,2,32,1,151,0,0,0,0,7,2,0,75],[0,0,0,0,5,0,128,25,0,0,0,235,2,32,0,156,0,0,0,0,5,6,192,25,0,0,0,0,2,5,0,75],[0,0,3,11,0,0,193,61,0,0,0,4,5,64,0,57,0,0,0,0,2,81,3,79,0,0,0,0,2,2,4,59],[0,0,0,234,6,32,0,156,0,0,1,247,0,0,33,61,0,0,0,191,6,32,0,57,0,0,0,32,9,0,0,138],[0,0,0,0,6,150,1,111,0,0,0,234,7,96,0,156,0,0,1,247,0,0,33,61,0,0,0,64,0,96,4,63],[0,0,0,128,0,32,4,63,0,0,0,0,4,36,0,25,0,0,0,36,4,64,0,57,0,0,0,0,3,52,0,75],[0,0,3,11,0,0,33,61,0,0,0,32,3,80,0,57,0,0,0,0,1,49,3,79,0,0,0,31,3,32,1,143],[0,0,0,5,4,32,2,114,0,0,0,231,0,0,97,61,0,0,0,0,5,0,0,25,0,0,0,5,6,80,2,16],[0,0,0,0,7,97,3,79,0,0,0,0,7,7,4,59,0,0,0,160,6,96,0,57,0,0,0,0,0,118,4,53],[0,0,0,1,5,80,0,57,0,0,0,0,6,69,0,75,0,0,0,223,0,0,65,61,0,4,0,0,0,9,0,29],[0,5,0,0,0,8,0,29,0,0,0,0,5,3,0,75,0,0,0,248,0,0,97,61,0,0,0,5,4,64,2,16],[0,0,0,0,1,65,3,79,0,0,0,3,3,48,2,16,0,0,0,160,4,64,0,57,0,0,0,0,5,4,4,51],[0,0,0,0,5,53,1,207,0,0,0,0,5,53,2,47,0,0,0,0,1,1,4,59,0,0,1,0,3,48,0,137],[0,0,0,0,1,49,2,47,0,0,0,0,1,49,1,207,0,0,0,0,1,81,1,159,0,0,0,0,0,20,4,53],[0,0,0,160,1,32,0,57,0,0,0,0,0,1,4,53,0,0,0,0,1,0,4,16,0,0,0,0,0,16,4,53],[0,0,0,32,0,0,4,63,0,0,0,216,1,0,0,65,0,0,0,0,2,0,4,20,0,0,0,216,3,32,0,156],[0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,0,236,1,16,1,199,0,0,128,16,2,0,0,57],[3,89,3,84,0,0,4,15,0,0,0,1,2,32,1,144,0,0,0,5,4,0,0,41,0,0,0,4,7,0,0,41],[0,0,3,11,0,0,97,61,0,0,0,0,1,1,4,59,0,0,0,0,2,1,4,26,0,0,0,0,9,0,4,22],[0,0,0,0,2,146,0,73,0,0,0,0,0,33,4,27,0,0,0,1,1,0,0,57,0,0,0,0,2,1,4,26],[0,0,0,0,2,146,0,73,0,0,0,0,0,33,4,27,0,0,0,237,2,0,0,65,0,0,0,64,1,0,4,61],[0,0,0,32,3,16,0,57,0,0,0,0,0,35,4,53,0,0,0,96,2,64,2,16,0,0,0,36,3,16,0,57],[0,0,0,0,0,35,4,53,0,0,0,0,8,0,4,17,0,0,0,96,2,128,2,16,0,0,0,88,3,16,0,57],[0,0,0,0,0,35,4,53,0,0,0,56,2,16,0,57,0,0,0,0,0,146,4,53,0,0,0,108,3,16,0,57],[0,0,0,128,2,0,4,61,0,0,0,0,4,2,0,75,0,0,1,43,0,0,97,61,0,0,0,0,4,0,0,25],[0,0,0,0,5,52,0,25,0,0,0,160,6,64,0,57,0,0,0,0,6,6,4,51,0,0,0,0,0,101,4,53],[0,0,0,32,4,64,0,57,0,0,0,0,5,36,0,75,0,0,1,36,0,0,65,61,0,0,0,0,3,50,0,25],[0,0,0,0,0,3,4,53,0,0,0,76,3,32,0,57,0,0,0,0,0,49,4,53,0,0,0,139,2,32,0,57],[0,0,0,0,2,114,1,111,0,0,0,0,10,18,0,25,0,0,0,0,2,42,0,75,0,0,0,0,2,0,0,25],[0,0,0,1,2,0,64,57,0,0,0,234,3,160,0,156,0,0,1,247,0,0,33,61,0,0,0,1,2,32,1,144],[0,0,1,247,0,0,193,61,0,1,0,0,0,9,0,29,0,2,0,0,0,8,0,29,0,0,0,64,0,160,4,63],[0,0,0,238,2,0,0,65,0,0,0,0,0,42,4,53,0,0,0,4,2,160,0,57,0,0,0,32,3,0,0,57],[0,0,0,0,0,50,4,53,0,0,0,0,2,1,4,51,0,0,0,36,3,160,0,57,0,0,0,0,0,35,4,53],[0,0,0,68,3,160,0,57,0,0,0,0,4,2,0,75,0,0,1,79,0,0,97,61,0,0,0,0,4,0,0,25],[0,0,0,0,5,52,0,25,0,0,0,32,4,64,0,57,0,0,0,0,6,20,0,25,0,0,0,0,6,6,4,51],[0,0,0,0,0,101,4,53,0,0,0,0,5,36,0,75,0,0,1,72,0,0,65,61,0,0,0,0,1,50,0,25],[0,0,0,0,0,1,4,53,0,0,0,31,1,32,0,57,0,0,0,0,1,113,1,111,0,0,0,216,2,0,0,65],[0,0,0,216,3,160,0,156,0,0,0,0,3,2,0,25,0,0,0,0,3,10,64,25,0,0,0,64,3,48,2,16],[0,0,0,68,1,16,0,57,0,0,0,216,4,16,0,156,0,0,0,0,1,2,128,25,0,0,0,96,1,16,2,16],[0,0,0,0,1,49,1,159,0,0,0,0,3,0,4,20,0,0,0,216,4,48,0,156,0,0,0,0,3,2,128,25],[0,0,0,192,2,48,2,16,0,0,0,0,1,18,1,159,0,0,128,8,2,0,0,57,0,3,0,0,0,10,0,29],[3,89,3,79,0,0,4,15,0,0,0,3,10,0,0,41,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112],[0,0,0,216,3,48,1,151,0,0,0,32,4,48,0,140,0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57],[0,0,0,31,5,64,1,143,0,0,0,5,6,64,2,114,0,0,1,120,0,0,97,61,0,0,0,0,7,0,0,25],[0,0,0,5,8,112,2,16,0,0,0,0,9,138,0,25,0,0,0,0,8,129,3,79,0,0,0,0,8,8,4,59],[0,0,0,0,0,137,4,53,0,0,0,1,7,112,0,57,0,0,0,0,8,103,0,75,0,0,1,112,0,0,65,61],[0,0,0,0,7,5,0,75,0,0,1,135,0,0,97,61,0,0,0,5,6,96,2,16,0,0,0,0,7,97,3,79],[0,0,0,0,6,106,0,25,0,0,0,3,5,80,2,16,0,0,0,0,8,6,4,51,0,0,0,0,8,88,1,207],[0,0,0,0,8,88,2,47,0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137,0,0,0,0,7,87,2,47],[0,0,0,0,5,87,1,207,0,0,0,0,5,133,1,159,0,0,0,0,0,86,4,53,0,0,0,1,2,32,1,144],[0,0,3,13,0,0,97,61,0,0,0,31,1,64,0,57,0,0,0,96,2,16,1,143,0,0,0,0,1,162,0,25],[0,0,0,0,2,33,0,75,0,0,0,0,2,0,0,25,0,0,0,1,2,0,64,57,0,0,0,234,4,16,0,156],[0,0,0,5,4,0,0,41,0,0,1,247,0,0,33,61,0,0,0,1,2,32,1,144,0,0,1,247,0,0,193,61],[0,0,0,64,0,16,4,63,0,0,0,32,2,48,0,140,0,0,3,11,0,0,65,61,0,0,0,32,2,16,0,57],[0,0,0,64,3,0,0,57,0,0,0,0,0,50,4,53,0,0,0,1,2,0,0,41,0,0,0,0,0,33,4,53],[0,0,0,64,3,16,0,57,0,0,0,128,2,0,4,61,0,0,0,0,0,35,4,53,0,0,0,96,3,16,0,57],[0,0,0,230,6,64,1,151,0,0,0,0,4,2,0,75,0,0,1,171,0,0,97,61,0,0,0,0,4,0,0,25],[0,0,0,0,5,52,0,25,0,0,0,160,7,64,0,57,0,0,0,0,7,7,4,51,0,0,0,0,0,117,4,53],[0,0,0,32,4,64,0,57,0,0,0,0,5,36,0,75,0,0,1,164,0,0,65,61,0,0,0,0,3,50,0,25],[0,0,0,0,0,3,4,53,0,0,0,127,2,32,0,57,0,0,0,4,2,32,1,127,0,0,0,216,3,0,0,65],[0,0,0,216,4,16,0,156,0,0,0,0,1,3,128,25,0,0,0,64,1,16,2,16,0,0,0,216,4,32,0,156],[0,0,0,0,2,3,128,25,0,0,0,96,2,32,2,16,0,0,0,0,1,18,1,159,0,0,0,0,2,0,4,20],[0,0,0,216,4,32,0,156,0,0,0,0,2,3,128,25,0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159],[0,0,0,239,1,16,1,199,0,0,128,13,2,0,0,57,0,0,0,3,3,0,0,57,0,0,0,240,4,0,0,65],[0,0,0,2,5,0,0,41,0,0,3,6,0,0,1,61,0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75],[0,0,3,11,0,0,193,61,0,0,0,192,1,0,0,57,0,0,0,64,0,16,4,63,0,0,0,5,1,0,0,57],[0,0,0,128,0,16,4,63,0,0,1,0,1,0,0,65,0,0,2,12,0,0,1,61,0,0,0,4,2,48,0,138],[0,0,0,32,2,32,0,140,0,0,3,11,0,0,65,61,0,0,0,4,1,16,3,112,0,0,0,0,4,1,4,59],[0,0,0,230,1,64,0,156,0,0,3,11,0,0,33,61,0,0,0,0,1,0,4,16,0,0,0,0,0,16,4,53],[0,0,0,32,0,0,4,63,0,0,0,216,1,0,0,65,0,0,0,0,2,0,4,20,0,0,0,216,3,32,0,156],[0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,0,236,1,16,1,199,0,0,128,16,2,0,0,57],[0,5,0,0,0,4,0,29,3,89,3,84,0,0,4,15,0,0,0,5,4,0,0,41,0,0,0,1,2,32,1,144],[0,0,3,11,0,0,97,61,0,0,0,0,1,1,4,59,0,0,0,0,2,1,4,26,0,0,0,0,5,0,4,22],[0,0,0,0,2,82,0,73,0,0,0,0,0,33,4,27,0,0,0,1,1,0,0,57,0,0,0,0,2,1,4,26],[0,0,0,0,2,82,0,73,0,0,0,0,0,33,4,27,0,0,0,237,2,0,0,65,0,0,0,64,1,0,4,61],[0,0,0,32,3,16,0,57,0,0,0,0,0,35,4,53,0,0,0,96,2,64,2,16,0,0,0,36,3,16,0,57],[0,0,0,0,0,35,4,53,0,0,0,56,2,0,0,57,0,0,0,0,0,33,4,53,0,0,0,56,2,16,0,57],[0,0,0,0,0,82,4,53,0,0,0,249,2,16,0,156,0,0,2,35,0,0,65,61,0,0,0,251,1,0,0,65],[0,0,0,0,0,16,4,53,0,0,0,65,1,0,0,57,0,0,0,4,0,16,4,63,0,0,0,252,1,0,0,65],[0,0,3,91,0,1,4,48,0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75,0,0,3,11,0,0,193,61],[0,0,0,18,1,0,0,57,0,0,0,128,0,16,4,63,0,0,0,231,1,0,0,65,0,0,3,90,0,1,4,46],[0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75,0,0,3,11,0,0,193,61,0,0,0,192,1,0,0,57],[0,0,0,64,0,16,4,63,0,0,0,3,1,0,0,57,0,0,0,128,0,16,4,63,0,0,0,232,1,0,0,65],[0,0,0,160,0,16,4,63,0,0,0,32,1,0,0,57,0,0,0,192,0,16,4,63,0,0,0,128,1,0,0,57],[0,0,0,224,2,0,0,57,3,89,3,42,0,0,4,15,0,0,0,192,1,16,0,138,0,0,0,216,2,0,0,65],[0,0,0,216,3,16,0,156,0,0,0,0,1,2,128,25,0,0,0,96,1,16,2,16,0,0,0,233,1,16,1,199],[0,0,3,90,0,1,4,46,0,0,0,244,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57],[0,0,0,132,0,16,4,63,0,0,0,31,1,0,0,57,0,0,0,164,0,16,4,63,0,0,0,253,1,0,0,65],[0,0,0,196,0,16,4,63,0,0,0,254,1,0,0,65,0,0,3,91,0,1,4,48,0,3,0,0,0,5,0,29],[0,0,0,96,7,16,0,57,0,0,0,64,0,112,4,63,0,0,0,238,2,0,0,65,0,0,0,0,0,39,4,53],[0,0,0,100,2,16,0,57,0,0,0,32,3,0,0,57,0,0,0,0,0,50,4,53,0,0,0,132,3,16,0,57],[0,0,0,0,2,1,4,51,0,0,0,0,0,35,4,53,0,0,0,164,3,16,0,57,0,0,0,0,4,2,0,75],[0,0,2,57,0,0,97,61,0,0,0,0,4,0,0,25,0,0,0,0,5,52,0,25,0,0,0,32,4,64,0,57],[0,0,0,0,6,20,0,25,0,0,0,0,6,6,4,51,0,0,0,0,0,101,4,53,0,0,0,0,5,36,0,75],[0,0,2,50,0,0,65,61,0,0,0,0,1,50,0,25,0,0,0,0,0,1,4,53,0,0,0,31,1,32,0,57],[0,0,0,32,2,0,0,138,0,0,0,0,1,33,1,111,0,0,0,216,2,0,0,65,0,0,0,216,3,112,0,156],[0,0,0,0,3,2,0,25,0,0,0,0,3,7,64,25,0,0,0,64,3,48,2,16,0,0,0,68,1,16,0,57],[0,0,0,216,4,16,0,156,0,0,0,0,1,2,128,25,0,0,0,96,1,16,2,16,0,0,0,0,1,49,1,159],[0,0,0,0,3,0,4,20,0,0,0,216,4,48,0,156,0,0,0,0,3,2,128,25,0,0,0,192,2,48,2,16],[0,0,0,0,1,18,1,159,0,0,128,8,2,0,0,57,0,4,0,0,0,7,0,29,3,89,3,79,0,0,4,15],[0,0,0,4,10,0,0,41,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,0,216,3,48,1,151],[0,0,0,32,4,48,0,140,0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57,0,0,0,31,5,64,1,143],[0,0,0,5,6,64,2,114,0,0,2,99,0,0,97,61,0,0,0,0,7,0,0,25,0,0,0,5,8,112,2,16],[0,0,0,0,9,138,0,25,0,0,0,0,8,129,3,79,0,0,0,0,8,8,4,59,0,0,0,0,0,137,4,53],[0,0,0,1,7,112,0,57,0,0,0,0,8,103,0,75,0,0,2,91,0,0,65,61,0,0,0,0,7,5,0,75],[0,0,2,114,0,0,97,61,0,0,0,5,6,96,2,16,0,0,0,0,7,97,3,79,0,0,0,0,6,106,0,25],[0,0,0,3,5,80,2,16,0,0,0,0,8,6,4,51,0,0,0,0,8,88,1,207,0,0,0,0,8,88,2,47],[0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137,0,0,0,0,7,87,2,47,0,0,0,0,5,87,1,207],[0,0,0,0,5,133,1,159,0,0,0,0,0,86,4,53,0,0,0,1,2,32,1,144,0,0,2,160,0,0,97,61],[0,0,0,31,1,64,0,57,0,0,0,96,2,16,1,143,0,0,0,0,1,162,0,25,0,0,0,0,2,33,0,75],[0,0,0,0,2,0,0,25,0,0,0,1,2,0,64,57,0,0,0,234,4,16,0,156,0,0,0,5,5,0,0,41],[0,0,0,3,4,0,0,41,0,0,1,247,0,0,33,61,0,0,0,1,2,32,1,144,0,0,1,247,0,0,193,61],[0,0,0,64,0,16,4,63,0,0,0,32,2,48,0,140,0,0,3,11,0,0,65,61,0,0,0,0,0,65,4,53],[0,0,0,216,2,0,0,65,0,0,0,0,3,0,4,20,0,0,0,216,4,48,0,156,0,0,0,0,3,2,128,25],[0,0,0,216,4,16,0,156,0,0,0,0,1,2,128,25,0,0,0,64,1,16,2,16,0,0,0,192,2,48,2,16],[0,0,0,0,1,18,1,159,0,0,0,241,1,16,1,199,0,0,0,230,6,80,1,151,0,0,128,13,2,0,0,57],[0,0,0,3,3,0,0,57,0,0,0,0,5,0,4,17,0,0,0,250,4,0,0,65,0,0,3,6,0,0,1,61],[0,0,0,244,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63],[0,0,0,62,1,0,0,57,0,0,0,164,0,16,4,63,0,0,0,246,1,0,0,65,0,0,0,196,0,16,4,63],[0,0,0,247,1,0,0,65,0,0,0,228,0,16,4,63,0,0,0,248,1,0,0,65,0,0,3,91,0,1,4,48],[0,0,0,64,2,0,4,61,0,0,0,31,4,48,1,143,0,0,0,5,5,48,2,114,0,0,2,173,0,0,97,61],[0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79],[0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75],[0,0,2,165,0,0,65,61,0,0,0,0,6,4,0,75,0,0,2,188,0,0,97,61,0,0,0,5,5,80,2,16],[0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51],[0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137],[0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53],[0,0,0,216,1,0,0,65,0,0,0,216,4,32,0,156,0,0,0,0,2,1,128,25,0,0,0,64,1,32,2,16],[0,0,0,96,2,48,2,16,0,0,0,0,1,33,1,159,0,0,3,91,0,1,4,48,0,2,0,0,0,2,0,29],[0,0,0,0,0,48,4,53,0,0,0,32,0,0,4,63,0,0,0,216,3,0,0,65,0,0,0,0,1,0,4,20],[0,0,0,216,2,16,0,156,0,0,0,0,1,3,128,25,0,0,0,192,1,16,2,16,0,0,0,236,1,16,1,199],[0,0,128,16,2,0,0,57,3,89,3,84,0,0,4,15,0,0,0,3,3,0,0,41,0,0,0,1,2,32,1,144],[0,0,3,11,0,0,97,61,0,0,0,2,4,0,0,41,0,0,0,4,2,64,0,106,0,0,0,0,1,1,4,59],[0,0,0,0,0,33,4,27,0,0,0,0,0,48,4,53,0,0,0,0,1,0,4,20,0,0,0,216,2,16,0,156],[0,0,0,216,1,0,128,65,0,0,0,192,1,16,2,16,0,0,0,236,1,16,1,199,0,0,128,16,2,0,0,57],[3,89,3,84,0,0,4,15,0,0,0,3,6,0,0,41,0,0,0,5,5,0,0,41,0,0,0,1,2,32,1,144],[0,0,3,11,0,0,97,61,0,0,0,0,1,1,4,59,0,0,0,0,2,1,4,26,0,0,0,4,3,0,0,41],[0,0,0,0,2,50,0,25,0,0,0,0,0,33,4,27,0,0,0,64,1,0,4,61,0,0,0,0,0,49,4,53],[0,0,0,216,2,0,0,65,0,0,0,0,3,0,4,20,0,0,0,216,4,48,0,156,0,0,0,0,3,2,128,25],[0,0,0,216,4,16,0,156,0,0,0,0,1,2,128,25,0,0,0,64,1,16,2,16,0,0,0,192,2,48,2,16],[0,0,0,0,1,18,1,159,0,0,0,241,1,16,1,199,0,0,128,13,2,0,0,57,0,0,0,3,3,0,0,57],[0,0,0,242,4,0,0,65,0,0,3,6,0,0,1,61,0,0,0,0,0,33,4,27,0,0,0,64,1,0,4,61],[0,0,0,0,0,65,4,53,0,0,0,216,2,0,0,65,0,0,0,0,3,0,4,20,0,0,0,216,4,48,0,156],[0,0,0,0,3,2,128,25,0,0,0,216,4,16,0,156,0,0,0,0,1,2,128,25,0,0,0,64,1,16,2,16],[0,0,0,192,2,48,2,16,0,0,0,0,1,18,1,159,0,0,0,241,1,16,1,199,0,0,128,13,2,0,0,57],[0,0,0,2,3,0,0,57,0,0,0,255,4,0,0,65,3,89,3,79,0,0,4,15,0,0,0,1,1,32,1,144],[0,0,3,11,0,0,97,61,0,0,0,0,1,0,0,25,0,0,3,90,0,1,4,46,0,0,0,0,1,0,0,25],[0,0,3,91,0,1,4,48,0,0,0,64,2,0,4,61,0,0,0,31,4,48,1,143,0,0,0,5,5,48,2,114],[0,0,3,26,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25],[0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57],[0,0,0,0,7,86,0,75,0,0,3,18,0,0,65,61,0,0,0,0,6,4,0,75,0,0,3,41,0,0,97,61],[0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16],[0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59],[0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159],[0,0,0,0,0,21,4,53,0,0,2,188,0,0,1,61,0,0,0,0,3,1,4,51,0,0,0,0,2,50,4,54],[0,0,0,0,4,3,0,75,0,0,3,54,0,0,97,61,0,0,0,0,4,0,0,25,0,0,0,0,5,36,0,25],[0,0,0,32,4,64,0,57,0,0,0,0,6,20,0,25,0,0,0,0,6,6,4,51,0,0,0,0,0,101,4,53],[0,0,0,0,5,52,0,75,0,0,3,47,0,0,65,61,0,0,0,0,1,35,0,25,0,0,0,0,0,1,4,53],[0,0,0,31,1,48,0,57,0,0,0,32,3,0,0,138,0,0,0,0,1,49,1,111,0,0,0,0,1,18,0,25],[0,0,0,0,0,1,4,45,0,0,0,216,2,0,0,65,0,0,0,216,3,16,0,156,0,0,0,0,1,2,128,25],[0,0,0,0,3,0,4,20,0,0,0,216,4,48,0,156,0,0,0,0,3,2,128,25,0,0,0,192,2,48,2,16],[0,0,0,64,1,16,2,16,0,0,0,0,1,33,1,159,0,0,0,236,1,16,1,199,0,0,128,16,2,0,0,57],[3,89,3,84,0,0,4,15,0,0,0,1,2,32,1,144,0,0,3,77,0,0,97,61,0,0,0,0,1,1,4,59],[0,0,0,0,0,1,4,45,0,0,0,0,1,0,0,25,0,0,3,91,0,1,4,48,0,0,3,82,0,33,4,33],[0,0,0,1,2,0,0,57,0,0,0,0,0,1,4,45,0,0,0,0,2,0,0,25,0,0,0,0,0,1,4,45],[0,0,3,87,0,33,4,35,0,0,0,1,2,0,0,57,0,0,0,0,0,1,4,45,0,0,0,0,2,0,0,25],[0,0,0,0,0,1,4,45,0,0,3,89,0,0,4,50,0,0,3,90,0,1,4,46,0,0,3,91,0,1,4,48],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255],[0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,1,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,81,207,248,216],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,188,62,175],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,188,62,176],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,149,216,155,65],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,156,199,247,8],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,81,207,248,217],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,87,153,82,252],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,49,60,229,102],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,49,60,229,103],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,193,15,25],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,253,222,3],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,22,13,221],[0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,128,0,0,0,0,0,0,0,0],[69,84,72,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255],[128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0],[108,9,96,249,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[98,248,75,36,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[196,5,254,137,88,65,11,186,240,199,59,122,12,62,32,133,158,134,202,22,138,76,155,13,239,156,84,210,85,90,48,107],[2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0],[221,242,82,173,27,226,200,155,105,194,176,104,252,55,141,170,149,43,167,241,99,196,161,22,40,245,90,77,245,35,179,239],[84,114,97,110,115,102,101,114,32,97,109,111,117,110,116,32,101,120,99,101,101,100,115,32,98,97,108,97,110,99,101,0],[8,195,121,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,0,0,0,0,0,0,0,0,0],[79,110,108,121,32,115,121,115,116,101,109,32,99,111,110,116,114,97,99,116,115,32,119,105,116,104,32,115,112,101,99,105],[97,108,32,97,99,99,101,115,115,32,99,97,110,32,99,97,108,108,32,116,104,105,115,32,109,101,116,104,111,100,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,0,0,0,128,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,160],[39,23,234,214,185,32,13,210,53,170,212,104,201,128,158,164,0,254,51,172,105,181,191,170,109,62,144,252,146,43,99,152],[78,72,123,113,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,0,0,0,0,0,0],[67,97,108,108,97,98,108,101,32,111,110,108,121,32,98,121,32,116,104,101,32,98,111,111,116,108,111,97,100,101,114,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,128,0,0,0,0,0,0,0,0],[15,103,152,165,96,121,58,84,195,188,254,134,169,60,222,30,115,8,125,148,76,14,162,5,68,19,125,65,33,57,104,133],[69,116,104,101,114,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[87,133,150,243,102,125,100,44,247,228,170,104,216,74,35,175,46,168,47,32,204,114,133,255,17,151,6,212,83,54,59,33]],"0x000000000000000000000000000000000000800b":[[0,1,0,0,0,0,0,2,0,6,0,0,0,0,0,2,0,0,0,0,0,1,3,85,0,0,0,128,4,0,0,57],[0,0,0,64,0,64,4,63,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,1,60,3,48,1,151],[0,0,0,1,2,32,1,144,0,0,0,33,0,0,193,61,0,0,0,4,2,48,0,140,0,0,3,252,0,0,65,61],[0,0,0,0,2,1,4,59,0,0,0,224,2,32,2,112,0,0,1,64,5,32,0,156,0,0,0,52,0,0,161,61],[0,0,1,65,4,32,0,156,0,0,0,104,0,0,33,61,0,0,1,77,4,32,0,156,0,0,0,163,0,0,33,61],[0,0,1,83,4,32,0,156,0,0,1,12,0,0,33,61,0,0,1,86,4,32,0,156,0,0,0,223,0,0,97,61],[0,0,1,87,1,32,0,156,0,0,3,252,0,0,193,61,0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75],[0,0,3,252,0,0,193,61,0,0,1,14,1,0,0,57,0,0,0,0,1,1,4,26,0,0,255,255,1,16,1,143],[0,0,2,112,0,0,1,61,0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75,0,0,3,252,0,0,193,61],[0,0,1,60,1,0,0,65,0,0,0,3,2,0,0,57,0,0,0,0,0,18,4,27,0,0,0,4,1,0,0,57],[0,0,0,0,2,1,4,26,0,0,1,61,2,32,1,151,0,0,128,1,2,32,1,191,0,0,0,0,0,33,4,27],[0,0,1,62,1,0,0,65,0,0,0,5,2,0,0,57,0,0,0,0,0,18,4,27,0,0,0,32,1,0,0,57],[0,0,1,0,0,16,4,67,0,0,1,32,0,0,4,67,0,0,1,63,1,0,0,65,0,0,4,235,0,1,4,46],[0,0,1,88,5,32,0,156,0,0,0,128,0,0,161,61,0,0,1,89,4,32,0,156,0,0,0,177,0,0,33,61],[0,0,1,95,1,32,0,156,0,0,1,21,0,0,33,61,0,0,1,98,1,32,0,156,0,0,1,123,0,0,97,61],[0,0,1,99,1,32,0,156,0,0,3,252,0,0,193,61,0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75],[0,0,3,252,0,0,193,61,0,0,1,15,1,0,0,57,0,0,0,0,1,1,4,26,0,0,1,64,2,0,0,57],[0,0,0,64,0,32,4,63,0,0,0,0,2,0,4,19,0,0,1,60,3,32,1,151,0,0,0,128,0,48,4,63],[0,0,0,64,4,32,2,112,0,0,1,60,4,64,1,151,0,0,0,160,0,64,4,63,0,0,0,96,4,32,2,112],[0,0,1,60,4,64,1,151,0,0,0,192,0,64,4,63,0,0,0,224,4,32,2,112,0,0,0,255,4,64,1,143],[0,0,0,224,0,64,4,63,0,0,0,232,4,32,2,112,0,0,0,255,4,64,1,143,0,0,1,0,0,64,4,63],[0,0,0,240,2,32,2,112,0,0,0,255,2,32,1,143,0,0,1,32,0,32,4,63,0,0,1,16,2,0,0,57],[0,0,0,0,2,2,4,26,0,0,0,0,2,35,0,73,0,0,0,0,3,50,0,75,0,0,0,0,3,0,0,25],[0,0,0,1,3,0,32,57,0,0,0,0,3,3,0,75,0,0,0,0,2,0,192,25,0,0,0,0,67,18,0,169],[0,0,0,0,4,1,0,75,0,0,0,101,0,0,97,61,0,0,0,0,65,19,0,217,0,0,0,0,1,18,0,75],[0,0,2,79,0,0,193,61,0,0,1,64,0,48,4,63,0,0,1,121,1,0,0,65,0,0,4,235,0,1,4,46],[0,0,1,66,4,32,0,156,0,0,0,217,0,0,33,61,0,0,1,72,4,32,0,156,0,0,1,30,0,0,33,61],[0,0,1,75,4,32,0,156,0,0,1,130,0,0,97,61,0,0,1,76,1,32,0,156,0,0,3,252,0,0,193,61],[0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75,0,0,3,252,0,0,193,61,0,0,0,4,1,48,0,138],[0,0,0,32,1,16,0,140,0,0,3,252,0,0,65,61,0,0,0,0,1,0,4,17,0,0,128,1,1,16,0,140],[0,0,0,0,1,0,0,25,0,0,0,1,1,0,96,57,4,234,4,94,0,0,4,15,0,0,0,4,1,0,0,57],[0,0,0,0,1,16,3,103,0,0,0,0,1,1,4,59,0,0,0,2,2,0,0,57,0,0,2,104,0,0,1,61],[0,0,1,100,5,32,0,156,0,0,0,238,0,0,161,61,0,0,1,101,1,32,0,156,0,0,1,39,0,0,33,61],[0,0,1,104,1,32,0,156,0,0,1,151,0,0,97,61,0,0,1,105,1,32,0,156,0,0,3,252,0,0,193,61],[0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75,0,0,3,252,0,0,193,61,0,0,0,4,1,48,0,138],[0,0,0,96,1,16,0,140,0,0,3,252,0,0,65,61,0,0,0,0,1,0,4,17,0,0,128,1,1,16,0,140],[0,0,0,0,1,0,0,25,0,0,0,1,1,0,96,57,4,234,4,94,0,0,4,15,0,0,0,64,1,0,4,61],[4,234,4,158,0,0,4,15,0,0,0,0,1,0,3,103,0,0,0,36,2,16,3,112,0,0,0,0,2,2,4,59],[0,0,0,128,2,32,2,16,0,0,0,4,3,16,3,112,0,0,0,0,3,3,4,59,0,0,1,110,3,48,1,151],[0,0,0,0,2,35,1,159,0,0,0,7,3,0,0,57,0,0,0,0,0,35,4,27,0,0,0,68,1,16,3,112],[0,0,0,0,1,1,4,59,0,0,0,6,2,0,0,57,0,0,2,104,0,0,1,61,0,0,1,78,1,32,0,156],[0,0,1,55,0,0,33,61,0,0,1,81,1,32,0,156,0,0,1,156,0,0,97,61,0,0,1,82,1,32,0,156],[0,0,3,252,0,0,193,61,0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75,0,0,3,252,0,0,193,61],[4,234,4,169,0,0,4,15,0,0,1,110,2,32,1,151,0,0,0,128,1,16,2,16,0,0,0,0,1,33,1,159],[0,0,2,60,0,0,1,61,0,0,1,90,4,32,0,156,0,0,1,66,0,0,33,61,0,0,1,93,1,32,0,156],[0,0,1,161,0,0,97,61,0,0,1,94,1,32,0,156,0,0,3,252,0,0,193,61,0,0,0,0,1,0,4,22],[0,0,0,0,1,1,0,75,0,0,3,252,0,0,193,61,0,0,0,0,1,0,4,17,0,0,128,1,1,16,0,140],[0,0,2,129,0,0,193,61,0,0,0,7,1,0,0,57,0,0,0,0,3,1,4,26,0,0,1,110,1,48,1,151],[0,0,0,128,0,16,4,63,0,0,0,128,2,48,2,112,0,0,0,160,0,32,4,63,0,0,1,0,2,0,0,57],[0,0,0,64,0,32,4,63,0,0,0,9,2,0,0,57,0,0,0,0,4,2,4,26,0,0,1,110,2,64,1,151],[0,0,0,192,0,32,4,63,0,0,0,128,4,64,2,112,0,0,0,224,0,64,4,63,0,0,1,110,3,48,0,156],[0,0,2,139,0,0,33,61,0,0,1,117,1,0,0,65,0,0,1,0,0,16,4,63,0,0,0,32,1,0,0,57],[0,0,1,4,0,16,4,63,0,0,0,47,1,0,0,57,0,0,1,36,0,16,4,63,0,0,1,118,1,0,0,65],[0,0,1,68,0,16,4,63,0,0,1,119,1,0,0,65,0,0,1,100,0,16,4,63,0,0,1,120,1,0,0,65],[0,0,4,236,0,1,4,48,0,0,1,67,4,32,0,156,0,0,1,114,0,0,33,61,0,0,1,70,4,32,0,156],[0,0,1,34,0,0,97,61,0,0,1,71,2,32,0,156,0,0,3,252,0,0,193,61,0,0,0,0,2,0,4,22],[0,0,0,0,2,2,0,75,0,0,3,252,0,0,193,61,0,0,0,4,2,48,0,138,0,0,0,32,2,32,0,140],[0,0,3,252,0,0,65,61,0,0,0,4,1,16,3,112,0,0,0,0,1,1,4,59,0,0,0,0,0,16,4,53],[0,0,0,8,1,0,0,57,0,0,0,32,0,16,4,63,0,0,0,64,2,0,0,57,0,0,0,0,1,0,0,25],[4,234,4,207,0,0,4,15,0,0,2,111,0,0,1,61,0,0,1,106,5,32,0,156,0,0,1,168,0,0,97,61],[0,0,1,107,5,32,0,156,0,0,1,234,0,0,97,61,0,0,1,108,2,32,0,156,0,0,3,252,0,0,193,61],[0,0,0,0,2,0,4,22,0,0,0,0,2,2,0,75,0,0,3,252,0,0,193,61,0,0,0,4,2,48,0,138],[0,0,0,32,2,32,0,140,0,0,3,252,0,0,65,61,0,0,0,0,2,0,4,17,0,0,128,1,2,32,0,140],[0,0,2,129,0,0,193,61,0,0,0,10,2,0,0,57,0,6,0,0,0,2,0,29,0,0,0,0,2,2,4,26],[0,0,0,160,0,32,4,63,0,0,0,4,1,16,3,112,0,0,0,0,1,1,4,59,0,0,0,192,0,16,4,63],[0,0,0,64,2,0,0,57,0,0,0,128,0,32,4,63,0,0,0,224,1,0,0,57,0,0,0,64,0,16,4,63],[0,0,0,160,1,0,0,57,4,234,4,207,0,0,4,15,0,0,0,6,2,0,0,41,0,0,2,104,0,0,1,61],[0,0,1,84,1,32,0,156,0,0,2,35,0,0,97,61,0,0,1,85,1,32,0,156,0,0,3,252,0,0,193,61],[0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75,0,0,3,252,0,0,193,61,0,0,0,1,1,0,0,57],[0,0,1,63,0,0,1,61,0,0,1,96,1,32,0,156,0,0,2,51,0,0,97,61,0,0,1,97,1,32,0,156],[0,0,3,252,0,0,193,61,0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75,0,0,3,252,0,0,193,61],[0,0,0,3,1,0,0,57,0,0,2,111,0,0,1,61,0,0,1,73,1,32,0,156,0,0,2,56,0,0,97,61],[0,0,1,74,1,32,0,156,0,0,3,252,0,0,193,61,0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75],[0,0,3,252,0,0,193,61,4,234,4,169,0,0,4,15,0,0,2,39,0,0,1,61,0,0,1,102,1,32,0,156],[0,0,2,68,0,0,97,61,0,0,1,103,1,32,0,156,0,0,3,252,0,0,193,61,0,0,0,0,1,0,4,22],[0,0,0,0,1,1,0,75,0,0,3,252,0,0,193,61,0,0,0,0,1,0,4,17,0,0,128,1,1,16,0,140],[0,0,0,0,1,0,0,25,0,0,0,1,1,0,96,57,4,234,4,94,0,0,4,15,0,0,1,14,1,0,0,57],[0,0,0,0,2,1,4,26,0,0,1,122,2,32,1,151,0,0,2,156,0,0,1,61,0,0,1,79,1,32,0,156],[0,0,2,85,0,0,97,61,0,0,1,80,1,32,0,156,0,0,3,252,0,0,193,61,0,0,0,0,1,0,4,22],[0,0,0,0,1,1,0,75,0,0,3,252,0,0,193,61,0,0,0,4,1,0,0,57,0,0,0,0,1,1,4,26],[0,0,1,113,1,16,1,151,0,0,2,112,0,0,1,61,0,0,1,91,4,32,0,156,0,0,2,107,0,0,97,61],[0,0,1,92,2,32,0,156,0,0,3,252,0,0,193,61,0,0,0,0,2,0,4,22,0,0,0,0,2,2,0,75],[0,0,3,252,0,0,193,61,0,0,0,4,2,48,0,138,0,0,0,32,2,32,0,140,0,0,3,252,0,0,65,61],[0,0,0,4,1,16,3,112,0,0,0,0,1,1,4,59,0,0,1,12,2,0,0,57,0,0,0,0,2,2,4,26],[0,0,0,192,3,0,0,57,0,0,0,64,0,48,4,63,0,0,0,128,6,32,2,112,0,0,1,13,2,0,0,57],[0,0,0,0,3,2,4,26,0,0,1,110,5,48,1,151,0,0,0,128,0,80,4,63,0,0,0,128,2,48,2,112],[0,0,0,160,0,32,4,63,0,0,0,0,4,22,0,75,0,0,0,0,4,0,0,25,0,0,2,175,0,0,161,61],[0,0,0,0,4,22,0,73,0,0,1,1,4,64,0,140,0,0,0,0,4,0,0,25,0,0,2,175,0,0,129,61],[0,0,0,0,4,81,0,75,0,0,2,145,0,0,129,61,0,0,0,0,0,16,4,53,0,0,0,8,1,0,0,57],[0,0,0,32,0,16,4,63,0,0,1,60,1,0,0,65,0,0,0,0,2,0,4,20,0,0,1,60,3,32,0,156],[0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,1,116,1,16,1,199,0,0,128,16,2,0,0,57],[4,234,4,229,0,0,4,15,0,0,0,1,2,32,1,144,0,0,3,252,0,0,97,61,0,0,0,0,1,1,4,59],[0,0,0,0,4,1,4,26,0,0,2,175,0,0,1,61,0,0,1,68,4,32,0,156,0,0,2,115,0,0,97,61],[0,0,1,69,1,32,0,156,0,0,3,252,0,0,193,61,0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75],[0,0,3,252,0,0,193,61,0,0,0,2,1,0,0,57,0,0,2,111,0,0,1,61,0,0,0,0,1,0,4,22],[0,0,0,0,1,1,0,75,0,0,3,252,0,0,193,61,0,0,1,12,1,0,0,57,0,0,0,0,1,1,4,26],[0,0,0,128,1,16,2,112,0,0,2,112,0,0,1,61,0,0,0,0,2,0,4,22,0,0,0,0,2,2,0,75],[0,0,3,252,0,0,193,61,0,0,0,4,2,48,0,138,0,0,0,32,2,32,0,140,0,0,3,252,0,0,65,61],[0,0,0,4,1,16,3,112,0,0,0,0,1,1,4,59,0,6,0,0,0,1,0,29,0,0,1,113,1,16,0,156],[0,0,3,252,0,0,33,61,0,0,0,0,1,0,4,17,0,0,128,1,1,16,0,140,0,0,0,0,1,0,0,25],[0,0,0,1,1,0,96,57,4,234,4,94,0,0,4,15,0,0,0,1,1,0,0,57,0,0,0,0,2,1,4,26],[0,0,1,61,2,32,1,151,0,0,0,6,2,32,1,175,0,0,2,156,0,0,1,61,0,0,0,0,1,0,4,22],[0,0,0,0,1,1,0,75,0,0,3,252,0,0,193,61,0,0,0,5,1,0,0,57,0,0,2,111,0,0,1,61],[0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75,0,0,3,252,0,0,193,61,0,0,0,0,1,0,4,26],[0,0,2,112,0,0,1,61,0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75,0,0,3,252,0,0,193,61],[0,0,1,12,1,0,0,57,0,0,0,0,1,1,4,26,0,0,1,110,1,16,1,151,0,0,2,112,0,0,1,61],[0,0,0,0,2,0,4,22,0,0,0,0,2,2,0,75,0,0,3,252,0,0,193,61,0,0,0,4,2,48,0,138],[0,0,0,128,2,32,0,140,0,0,3,252,0,0,65,61,0,0,0,4,2,16,3,112,0,0,0,0,2,2,4,59],[0,5,0,0,0,2,0,29,0,0,0,36,2,16,3,112,0,0,0,0,2,2,4,59,0,6,0,0,0,2,0,29],[0,0,1,110,2,32,0,156,0,0,3,252,0,0,33,61,0,0,0,68,1,16,3,112,0,0,0,0,1,1,4,59],[0,4,0,0,0,1,0,29,0,0,1,110,1,16,0,156,0,0,3,252,0,0,33,61,0,0,0,0,1,0,4,17],[0,0,128,1,1,16,0,140,0,0,2,129,0,0,193,61,0,0,0,192,1,0,0,57,0,0,0,64,0,16,4,63],[0,0,0,7,4,0,0,57,0,0,0,0,1,4,4,26,0,0,1,110,2,16,1,151,0,0,0,128,0,32,4,63],[0,0,0,128,1,16,2,112,0,0,0,160,0,16,4,63,0,0,0,6,2,32,0,107,0,0,2,183,0,0,161,61],[0,0,1,110,2,16,0,156,0,0,2,79,0,0,97,61,0,0,0,1,2,16,0,57,0,0,0,4,2,32,0,108],[0,0,2,192,0,0,193,61,0,3,0,0,0,4,0,29,0,0,0,9,2,0,0,57,0,0,0,0,2,2,4,26],[0,0,1,110,2,32,1,151,0,0,0,6,2,32,0,107,0,0,2,204,0,0,161,61,0,0,0,0,0,16,4,53],[0,0,0,8,1,0,0,57,0,0,0,32,0,16,4,63,0,0,1,60,1,0,0,65,0,0,0,0,2,0,4,20],[0,0,1,60,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,1,116,1,16,1,199],[0,0,128,16,2,0,0,57,4,234,4,229,0,0,4,15,0,0,0,1,2,32,1,144,0,0,3,252,0,0,97,61],[0,0,0,0,1,1,4,59,0,0,0,5,2,0,0,41,0,0,0,0,0,33,4,27,0,0,0,64,1,0,4,61],[0,0,1,141,2,16,0,156,0,0,3,120,0,0,161,61,0,0,1,170,1,0,0,65,0,0,0,0,0,16,4,53],[0,0,0,65,1,0,0,57,0,0,2,82,0,0,1,61,0,0,0,0,2,0,4,22,0,0,0,0,2,2,0,75],[0,0,3,252,0,0,193,61,0,0,0,4,2,48,0,138,0,0,0,160,2,32,0,140,0,0,3,252,0,0,65,61],[0,0,0,4,2,16,3,112,0,0,0,0,2,2,4,59,0,6,0,0,0,2,0,29,0,0,1,110,2,32,0,156],[0,0,3,252,0,0,33,61,0,0,0,36,2,16,3,112,0,0,0,0,2,2,4,59,0,5,0,0,0,2,0,29],[0,0,1,110,2,32,0,156,0,0,3,252,0,0,33,61,0,0,0,68,2,16,3,112,0,0,0,0,2,2,4,59],[0,4,0,0,0,2,0,29,0,0,0,100,2,16,3,112,0,0,0,0,2,2,4,59,0,0,0,0,3,2,0,75],[0,0,0,0,3,0,0,25,0,0,0,1,3,0,192,57,0,0,0,0,3,50,0,75,0,0,3,252,0,0,193,61],[0,0,0,132,1,16,3,112,0,0,0,0,1,1,4,59,0,3,0,0,0,1,0,29,0,0,1,110,1,16,0,156],[0,0,3,252,0,0,33,61,0,0,0,0,1,0,4,17,0,0,128,1,1,16,0,140,0,0,2,129,0,0,193,61],[0,0,0,0,1,2,0,75,0,0,2,232,0,0,97,61,0,0,0,7,1,0,0,57,0,0,0,0,1,1,4,26],[0,0,1,110,1,16,1,151,0,0,0,5,1,16,0,107,0,0,2,218,0,0,129,61,0,0,1,117,1,0,0,65],[0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63,0,0,0,97,1,0,0,57],[0,0,0,164,0,16,4,63,0,0,1,126,1,0,0,65,0,0,0,196,0,16,4,63,0,0,1,127,1,0,0,65],[0,0,0,228,0,16,4,63,0,0,1,128,1,0,0,65,0,0,1,4,0,16,4,63,0,0,1,129,1,0,0,65],[0,0,1,36,0,16,4,63,0,0,1,130,1,0,0,65,0,0,4,236,0,1,4,48,0,0,0,0,1,0,4,22],[0,0,0,0,1,1,0,75,0,0,3,252,0,0,193,61,4,234,4,188,0,0,4,15,0,0,1,110,2,32,1,151],[0,0,0,64,3,0,4,61,0,0,0,32,4,48,0,57,0,0,0,0,0,36,4,53,0,0,1,110,1,16,1,151],[0,0,0,0,0,19,4,53,0,0,1,60,1,0,0,65,0,0,1,60,2,48,0,156,0,0,0,0,3,1,128,25],[0,0,0,64,1,48,2,16,0,0,1,111,1,16,1,199,0,0,4,235,0,1,4,46,0,0,0,0,1,0,4,22],[0,0,0,0,1,1,0,75,0,0,3,252,0,0,193,61,0,0,0,6,1,0,0,57,0,0,2,111,0,0,1,61],[0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75,0,0,3,252,0,0,193,61,4,234,4,115,0,0,4,15],[0,0,0,64,2,0,4,61,0,0,0,0,0,18,4,53,0,0,1,60,1,0,0,65,0,0,1,60,3,32,0,156],[0,0,0,0,2,1,128,25,0,0,0,64,1,32,2,16,0,0,1,112,1,16,1,199,0,0,4,235,0,1,4,46],[0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75,0,0,3,252,0,0,193,61,0,0,0,0,1,0,4,17],[0,0,128,1,1,16,0,140,0,0,2,129,0,0,193,61,0,0,1,14,1,0,0,57,0,0,0,0,2,1,4,26],[0,0,255,255,3,32,1,143,0,0,255,255,4,48,0,140,0,0,2,153,0,0,193,61,0,0,1,170,1,0,0,65],[0,0,0,0,0,16,4,53,0,0,0,17,1,0,0,57,0,0,0,4,0,16,4,63,0,0,1,171,1,0,0,65],[0,0,4,236,0,1,4,48,0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75,0,0,3,252,0,0,193,61],[0,0,0,4,1,48,0,138,0,0,0,64,1,16,0,140,0,0,3,252,0,0,65,61,0,0,0,0,1,0,4,17],[0,0,128,1,1,16,0,140,0,0,0,0,1,0,0,25,0,0,0,1,1,0,96,57,4,234,4,94,0,0,4,15],[0,0,0,0,1,0,3,103,0,0,0,36,2,16,3,112,0,0,0,0,2,2,4,59,0,0,1,16,3,0,0,57],[0,0,0,0,0,35,4,27,0,0,0,4,1,16,3,112,0,0,0,0,1,1,4,59,0,0,1,15,2,0,0,57],[0,0,0,0,0,18,4,27,0,0,0,0,1,0,0,25,0,0,4,235,0,1,4,46,0,0,0,0,1,0,4,22],[0,0,0,0,1,1,0,75,0,0,3,252,0,0,193,61,0,0,1,15,1,0,0,57,0,0,0,0,1,1,4,26],[0,0,0,128,0,16,4,63,0,0,1,109,1,0,0,65,0,0,4,235,0,1,4,46,0,0,0,0,2,0,4,22],[0,0,0,0,2,2,0,75,0,0,3,252,0,0,193,61,0,0,0,4,2,48,0,138,0,0,0,32,2,32,0,140],[0,0,3,252,0,0,65,61,0,0,0,0,2,0,4,17,0,0,128,7,2,32,0,140,0,0,3,252,0,0,193,61],[0,0,0,4,1,16,3,112,0,0,0,0,1,1,4,59,0,0,0,0,0,16,4,27,0,0,0,0,1,0,0,25],[0,0,4,235,0,1,4,46,0,0,1,117,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57],[0,0,0,132,0,16,4,63,0,0,0,31,1,0,0,57,0,0,0,164,0,16,4,63,0,0,1,161,1,0,0,65],[0,0,0,196,0,16,4,63,0,0,1,162,1,0,0,65,0,0,4,236,0,1,4,48,0,0,0,128,1,16,2,16],[0,0,0,0,1,18,1,159,0,0,0,3,2,0,0,57,0,0,0,0,0,18,4,28,0,0,0,0,1,0,0,25],[0,0,4,235,0,1,4,46,0,0,1,114,3,48,0,156,0,0,2,159,0,0,65,61,0,0,0,0,2,33,0,75],[0,0,2,159,0,0,65,61,0,0,1,1,33,16,1,26,0,0,0,11,1,32,0,57,0,0,0,0,4,1,4,26],[0,0,2,175,0,0,1,61,0,0,1,122,2,32,1,151,0,0,0,1,3,48,0,57,0,0,0,0,2,35,1,159],[0,0,0,0,0,33,4,27,0,0,0,0,1,0,0,25,0,0,4,235,0,1,4,46,0,0,0,224,0,16,4,63],[0,0,0,32,1,0,0,57,0,0,0,192,0,16,4,63,0,0,1,0,1,0,0,57,0,0,0,64,0,16,4,63],[0,0,1,60,1,0,0,65,0,0,0,0,2,0,4,20,0,0,1,60,3,32,0,156,0,0,0,0,2,1,128,25],[0,0,0,192,1,32,2,16,0,0,1,115,1,16,1,199,0,0,128,16,2,0,0,57,4,234,4,229,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,3,252,0,0,97,61,0,0,0,0,4,1,4,59,0,0,0,64,1,0,4,61],[0,0,0,0,0,65,4,53,0,0,1,60,2,0,0,65,0,0,1,60,3,16,0,156,0,0,0,0,1,2,128,25],[0,0,0,64,1,16,2,16,0,0,1,112,1,16,1,199,0,0,4,235,0,1,4,46,0,0,1,117,1,0,0,65],[0,0,0,192,0,16,4,63,0,0,0,32,1,0,0,57,0,0,0,196,0,16,4,63,0,0,0,228,0,16,4,63],[0,0,1,163,1,0,0,65,0,0,1,4,0,16,4,63,0,0,1,132,1,0,0,65,0,0,4,236,0,1,4,48],[0,0,1,117,1,0,0,65,0,0,0,192,0,16,4,63,0,0,0,32,1,0,0,57,0,0,0,196,0,16,4,63],[0,0,0,40,1,0,0,57,0,0,0,228,0,16,4,63,0,0,1,164,1,0,0,65,0,0,1,4,0,16,4,63],[0,0,1,165,1,0,0,65,0,0,1,36,0,16,4,63,0,0,1,144,1,0,0,65,0,0,4,236,0,1,4,48],[0,0,1,117,1,0,0,65,0,0,0,192,0,16,4,63,0,0,0,32,1,0,0,57,0,0,0,196,0,16,4,63],[0,0,0,83,1,0,0,57,0,0,0,228,0,16,4,63,0,0,1,166,1,0,0,65,0,0,1,4,0,16,4,63],[0,0,1,167,1,0,0,65,0,0,1,36,0,16,4,63,0,0,1,168,1,0,0,65,0,0,1,68,0,16,4,63],[0,0,1,169,1,0,0,65,0,0,4,236,0,1,4,48,0,0,0,3,1,0,0,107,0,0,2,232,0,0,193,61],[0,0,1,117,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63],[0,0,0,63,1,0,0,57,0,0,0,164,0,16,4,63,0,0,1,123,1,0,0,65,0,0,0,196,0,16,4,63],[0,0,1,124,1,0,0,65,0,0,0,228,0,16,4,63,0,0,1,125,1,0,0,65,0,0,4,236,0,1,4,48],[0,0,0,192,1,0,0,57,0,0,0,64,0,16,4,63,0,0,0,9,1,0,0,57,0,1,0,0,0,1,0,29],[0,0,0,0,3,1,4,26,0,0,1,110,1,48,1,151,0,2,0,0,0,1,0,29,0,0,0,128,0,16,4,63],[0,0,0,128,1,48,2,112,0,0,0,160,0,16,4,63,0,0,1,110,3,48,0,156,0,0,3,2,0,0,33,61],[0,0,0,2,3,0,0,107,0,0,3,7,0,0,193,61,0,0,0,0,1,2,0,75,0,0,3,100,0,0,193,61],[0,0,1,117,1,0,0,65,0,0,0,192,0,16,4,63,0,0,0,32,1,0,0,57,0,0,0,196,0,16,4,63],[0,0,0,33,1,0,0,57,0,0,0,228,0,16,4,63,0,0,1,159,1,0,0,65,0,0,1,4,0,16,4,63],[0,0,1,160,1,0,0,65,0,0,2,201,0,0,1,61,0,0,0,6,3,16,0,108,0,0,3,9,0,0,97,61],[0,0,1,110,2,16,0,156,0,0,2,79,0,0,97,61,0,0,3,36,0,0,1,61,0,0,0,6,3,16,0,108],[0,0,3,36,0,0,193,61,0,0,0,0,1,2,0,75,0,0,3,90,0,0,193,61,0,0,0,2,2,0,0,41],[0,0,0,5,1,32,0,108,0,0,3,142,0,0,193,61,0,0,0,6,1,0,0,41,0,0,0,1,1,16,0,138],[0,0,1,110,2,16,0,156,0,0,2,79,0,0,33,61,0,0,1,110,1,16,1,151,0,0,1,1,33,16,1,26],[0,0,0,11,1,32,0,57,0,0,0,0,1,1,4,26,0,0,0,4,1,16,0,107,0,0,3,254,0,0,193,61],[0,0,0,3,1,0,0,107,0,0,3,202,0,0,97,61,0,0,1,117,1,0,0,65,0,0,0,192,0,16,4,63],[0,0,0,32,1,0,0,57,0,0,0,196,0,16,4,63,0,0,0,60,1,0,0,57,0,0,0,228,0,16,4,63],[0,0,1,149,1,0,0,65,0,0,1,4,0,16,4,63,0,0,1,150,1,0,0,65,0,0,2,201,0,0,1,61],[0,0,0,1,2,16,0,57,0,0,0,6,2,32,0,108,0,0,3,112,0,0,193,61,0,0,0,1,2,16,0,138],[0,0,1,110,3,32,0,156,0,0,2,79,0,0,33,61,0,0,0,10,3,0,0,57,0,0,0,0,3,3,4,26],[0,0,1,110,2,32,1,151,0,0,1,1,82,32,1,26,0,0,0,11,2,80,0,57,0,0,0,0,2,2,4,26],[0,0,0,224,0,16,4,63,0,0,0,2,1,0,0,41,0,0,1,0,0,16,4,63,0,0,1,32,0,32,4,63],[0,0,1,64,0,48,4,63,0,0,0,192,0,64,4,63,0,0,1,96,1,0,0,57,0,0,0,64,0,16,4,63],[0,0,1,60,1,0,0,65,0,0,0,0,2,0,4,20,0,0,1,60,3,32,0,156,0,0,0,0,2,1,128,25],[0,0,0,192,1,32,2,16,0,0,1,133,1,16,1,199,0,0,128,16,2,0,0,57,4,234,4,229,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,3,252,0,0,97,61,0,0,0,64,2,0,4,61,0,0,0,0,1,1,4,59],[0,0,0,4,1,16,0,107,0,0,4,8,0,0,193,61,0,0,0,2,3,0,0,41,0,0,0,5,1,48,0,107],[0,0,4,43,0,0,161,61,0,0,1,141,1,32,0,156,0,0,1,230,0,0,33,61,0,0,0,64,1,32,0,57],[0,0,0,64,0,16,4,63,0,0,0,32,1,32,0,57,0,0,0,6,4,0,0,41,0,0,0,0,0,65,4,53],[0,0,0,5,3,0,0,41,0,0,0,0,0,50,4,53,0,0,0,128,1,64,2,16,0,0,0,0,1,19,1,159],[0,0,0,1,2,0,0,41,0,0,0,0,0,18,4,27,0,0,0,1,1,64,0,138,0,0,1,110,2,16,0,156],[0,0,2,79,0,0,33,61,0,0,3,195,0,0,1,61,0,0,1,117,1,0,0,65,0,0,0,192,0,16,4,63],[0,0,0,32,1,0,0,57,0,0,0,196,0,16,4,63,0,0,0,53,1,0,0,57,0,0,0,228,0,16,4,63],[0,0,1,142,1,0,0,65,0,0,1,4,0,16,4,63,0,0,1,143,1,0,0,65,0,0,2,201,0,0,1,61],[0,0,0,6,1,0,0,107,0,0,3,152,0,0,193,61,0,0,1,117,1,0,0,65,0,0,0,192,0,16,4,63],[0,0,0,32,1,0,0,57,0,0,0,196,0,16,4,63,0,0,0,44,1,0,0,57,0,0,0,228,0,16,4,63],[0,0,1,157,1,0,0,65,0,0,1,4,0,16,4,63,0,0,1,158,1,0,0,65,0,0,2,201,0,0,1,61],[0,0,1,117,1,0,0,65,0,0,0,192,0,16,4,63,0,0,0,32,1,0,0,57,0,0,0,196,0,16,4,63],[0,0,0,27,1,0,0,57,0,0,0,228,0,16,4,63,0,0,1,131,1,0,0,65,0,0,2,189,0,0,1,61],[0,0,0,64,2,16,0,57,0,0,0,64,0,32,4,63,0,0,0,32,2,16,0,57,0,0,0,4,3,0,0,41],[0,0,0,0,0,50,4,53,0,0,0,6,2,0,0,41,0,0,0,0,0,33,4,53,0,0,0,128,1,48,2,16],[0,0,1,110,2,32,1,151,0,0,0,0,1,18,1,159,0,0,0,3,2,0,0,41,0,0,0,0,0,18,4,27],[0,0,0,100,1,0,0,57,0,0,0,0,1,16,3,103,0,0,0,0,1,1,4,59,0,0,0,6,2,0,0,57],[0,0,0,0,0,18,4,27,0,0,0,4,1,0,0,57,0,0,0,5,2,0,0,41,0,0,0,0,0,33,4,28],[0,0,0,0,1,0,0,25,0,0,4,235,0,1,4,46,0,0,1,117,1,0,0,65,0,0,0,192,0,16,4,63],[0,0,0,32,1,0,0,57,0,0,0,196,0,16,4,63,0,0,0,47,1,0,0,57,0,0,0,228,0,16,4,63],[0,0,1,145,1,0,0,65,0,0,1,4,0,16,4,63,0,0,1,146,1,0,0,65,0,0,2,201,0,0,1,61],[0,0,0,6,1,0,0,41,0,0,1,110,1,16,0,65,0,2,0,0,0,1,0,29,0,0,0,224,1,16,2,16],[0,0,0,224,0,16,4,63,0,0,0,4,1,0,0,57,0,0,0,192,0,16,4,63,0,0,1,0,1,0,0,57],[0,0,0,64,0,16,4,63,0,0,1,60,1,0,0,65,0,0,0,0,2,0,4,20,0,0,1,60,3,32,0,156],[0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,1,151,1,16,1,199,0,0,128,16,2,0,0,57],[4,234,4,229,0,0,4,15,0,0,0,1,2,32,1,144,0,0,3,252,0,0,97,61,0,0,0,64,2,0,4,61],[0,0,0,0,1,1,4,59,0,0,0,4,1,16,0,108,0,0,4,17,0,0,193,61,0,0,0,2,1,0,0,41],[0,0,1,110,1,16,1,151,0,0,1,1,49,16,1,26,0,0,0,11,1,48,0,57,0,0,0,4,3,0,0,41],[0,0,0,0,0,49,4,27,0,0,1,141,1,32,0,156,0,0,1,230,0,0,33,61,0,0,0,64,1,32,0,57],[0,0,0,64,0,16,4,63,0,0,0,32,1,32,0,57,0,0,0,6,4,0,0,41,0,0,0,0,0,65,4,53],[0,0,0,5,3,0,0,41,0,0,0,0,0,50,4,53,0,0,0,128,1,64,2,16,0,0,0,0,1,19,1,159],[0,0,0,1,2,0,0,41,0,0,0,0,0,18,4,27,0,0,0,1,1,64,0,138,0,0,1,110,1,16,1,151],[0,0,1,1,33,16,1,26,0,0,0,11,1,32,0,57,0,0,0,4,2,0,0,41,0,0,0,0,0,33,4,27],[0,0,0,10,1,0,0,57,0,0,0,0,0,1,4,27,0,0,1,13,1,0,0,57,0,0,0,0,2,1,4,26],[0,0,1,114,3,32,0,156,0,0,4,37,0,0,129,61,0,0,0,64,3,0,4,61,0,0,1,141,4,48,0,156],[0,0,1,230,0,0,33,61,0,0,0,64,4,48,0,57,0,0,0,64,0,64,4,63,0,0,1,12,4,0,0,57],[0,0,0,0,6,4,4,26,0,0,1,110,4,96,1,151,0,0,0,0,4,67,4,54,0,0,0,128,5,96,2,112],[0,0,0,0,0,84,4,53,0,0,1,110,6,96,0,156,0,0,4,66,0,0,33,61,0,0,0,0,6,3,4,51],[0,0,1,110,6,96,1,152,0,0,4,66,0,0,193,61,0,0,0,7,5,0,0,57,0,0,0,0,5,5,4,26],[0,0,0,128,5,80,2,112,0,0,0,0,0,84,4,53,0,0,1,154,2,32,1,151,0,0,0,0,2,37,1,159],[0,0,0,0,0,33,4,27,0,0,0,3,6,0,0,107,0,0,4,69,0,0,193,61,0,0,0,64,1,0,4,61],[0,0,0,100,2,16,0,57,0,0,1,155,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,68,2,16,0,57],[0,0,1,156,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,40,3,0,0,57],[0,0,0,0,0,50,4,53,0,0,1,117,2,0,0,65,0,0,0,0,0,33,4,53,0,0,0,4,2,16,0,57],[0,0,0,32,3,0,0,57,0,0,0,0,0,50,4,53,0,0,1,60,2,0,0,65,0,0,1,60,3,16,0,156],[0,0,0,0,1,2,128,25,0,0,0,64,1,16,2,16,0,0,1,136,1,16,1,199,0,0,4,236,0,1,4,48],[0,0,0,0,1,0,0,25,0,0,4,236,0,1,4,48,0,0,1,117,1,0,0,65,0,0,0,192,0,16,4,63],[0,0,0,32,1,0,0,57,0,0,0,196,0,16,4,63,0,0,0,51,1,0,0,57,0,0,0,228,0,16,4,63],[0,0,1,147,1,0,0,65,0,0,1,4,0,16,4,63,0,0,1,148,1,0,0,65,0,0,2,201,0,0,1,61],[0,0,0,100,1,32,0,57,0,0,1,134,3,0,0,65,0,0,0,0,0,49,4,53,0,0,0,68,1,32,0,57],[0,0,1,135,3,0,0,65,0,0,0,0,0,49,4,53,0,0,0,36,1,32,0,57,0,0,0,38,3,0,0,57],[0,0,4,25,0,0,1,61,0,0,0,100,1,32,0,57,0,0,1,152,3,0,0,65,0,0,0,0,0,49,4,53],[0,0,0,68,1,32,0,57,0,0,1,153,3,0,0,65,0,0,0,0,0,49,4,53,0,0,0,36,1,32,0,57],[0,0,0,39,3,0,0,57,0,0,0,0,0,49,4,53,0,0,1,117,1,0,0,65,0,0,0,0,0,18,4,53],[0,0,0,4,1,32,0,57,0,0,0,32,3,0,0,57,0,0,0,0,0,49,4,53,0,0,1,60,1,0,0,65],[0,0,1,60,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,64,1,32,2,16,0,0,1,136,1,16,1,199],[0,0,4,236,0,1,4,48,0,0,0,1,1,0,0,41,0,0,0,0,1,1,4,26,0,0,1,12,2,0,0,57],[0,0,0,0,0,18,4,27,0,0,0,0,1,0,0,25,0,0,4,235,0,1,4,46,0,0,0,132,1,32,0,57],[0,0,1,137,3,0,0,65,0,0,0,0,0,49,4,53,0,0,0,100,1,32,0,57,0,0,1,138,3,0,0,65],[0,0,0,0,0,49,4,53,0,0,0,68,1,32,0,57,0,0,1,139,3,0,0,65,0,0,0,0,0,49,4,53],[0,0,0,36,1,32,0,57,0,0,0,93,3,0,0,57,0,0,0,0,0,49,4,53,0,0,1,117,1,0,0,65],[0,0,0,0,0,18,4,53,0,0,0,4,1,32,0,57,0,0,0,32,3,0,0,57,0,0,0,0,0,49,4,53],[0,0,1,60,1,0,0,65,0,0,1,60,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,64,1,32,2,16],[0,0,1,140,1,16,1,199,0,0,4,236,0,1,4,48,0,0,0,3,6,0,0,107,0,0,4,71,0,0,193,61],[0,0,4,41,0,0,1,61,0,0,0,3,6,0,0,41,0,3,0,1,0,96,0,146,0,0,0,3,5,80,0,41],[0,0,1,110,6,80,0,156,0,0,2,79,0,0,33,61,0,0,0,0,0,84,4,53,0,0,0,5,5,0,0,41],[0,0,0,0,0,83,4,53,0,0,0,0,5,4,4,51,0,0,1,110,6,80,1,151,0,0,0,6,6,96,0,108],[0,0,4,83,0,0,129,61,0,0,0,128,5,80,2,16,0,0,4,90,0,0,1,61,0,0,0,6,6,0,0,41],[0,0,0,128,5,96,2,16,0,0,0,0,2,82,1,159,0,0,0,0,0,33,4,27,0,0,0,0,0,100,4,53],[0,0,0,0,1,3,4,51,0,5,0,0,0,1,0,29,0,0,0,5,1,0,0,41,0,0,1,110,1,16,1,151],[0,0,0,0,1,81,1,159,0,0,4,39,0,0,1,61,0,0,0,0,1,1,0,75,0,0,4,97,0,0,97,61],[0,0,0,0,0,1,4,45,0,0,0,64,1,0,4,61,0,0,0,68,2,16,0,57,0,0,1,161,3,0,0,65],[0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,31,3,0,0,57,0,0,0,0,0,50,4,53],[0,0,1,117,2,0,0,65,0,0,0,0,0,33,4,53,0,0,0,4,2,16,0,57,0,0,0,32,3,0,0,57],[0,0,0,0,0,50,4,53,0,0,1,60,2,0,0,65,0,0,1,60,3,16,0,156,0,0,0,0,1,2,128,25],[0,0,0,64,1,16,2,16,0,0,1,172,1,16,1,199,0,0,4,236,0,1,4,48,0,0,0,64,1,0,4,61],[0,0,1,173,2,16,0,156,0,0,4,152,0,0,129,61,0,0,0,192,2,16,0,57,0,0,0,64,0,32,4,63],[0,0,0,0,2,0,4,19,0,0,0,240,3,32,2,112,0,0,0,255,3,48,1,143,0,0,0,160,4,16,0,57],[0,0,0,0,0,52,4,53,0,0,0,232,3,32,2,112,0,0,0,255,3,48,1,143,0,0,0,128,4,16,0,57],[0,0,0,0,0,52,4,53,0,0,0,224,3,32,2,112,0,0,0,255,3,48,1,143,0,0,0,96,4,16,0,57],[0,0,0,0,0,52,4,53,0,0,0,96,3,32,2,112,0,0,1,60,3,48,1,151,0,0,0,64,4,16,0,57],[0,0,0,0,0,52,4,53,0,0,0,64,3,32,2,112,0,0,1,60,3,48,1,151,0,0,0,32,4,16,0,57],[0,0,0,0,0,52,4,53,0,0,1,60,2,32,1,151,0,0,0,0,0,33,4,53,0,0,1,16,1,0,0,57],[0,0,0,0,1,1,4,26,0,0,0,0,1,18,0,73,0,0,0,0,2,33,0,75,0,0,0,0,2,0,0,25],[0,0,0,1,2,0,32,57,0,0,0,0,2,2,0,75,0,0,0,0,1,0,192,25,0,0,0,0,0,1,4,45],[0,0,1,170,1,0,0,65,0,0,0,0,0,16,4,53,0,0,0,65,1,0,0,57,0,0,0,4,0,16,4,63],[0,0,1,171,1,0,0,65,0,0,4,236,0,1,4,48,0,0,1,174,2,16,0,156,0,0,4,163,0,0,129,61],[0,0,0,64,1,16,0,57,0,0,0,64,0,16,4,63,0,0,0,0,0,1,4,45,0,0,1,170,1,0,0,65],[0,0,0,0,0,16,4,53,0,0,0,65,1,0,0,57,0,0,0,4,0,16,4,63,0,0,1,171,1,0,0,65],[0,0,4,236,0,1,4,48,0,0,0,64,3,0,4,61,0,0,1,174,1,48,0,156,0,0,4,182,0,0,129,61],[0,0,0,64,1,48,0,57,0,0,0,64,0,16,4,63,0,0,0,7,1,0,0,57,0,0,0,0,2,1,4,26],[0,0,0,32,4,48,0,57,0,0,0,128,1,32,2,112,0,0,0,0,0,20,4,53,0,0,1,110,2,32,1,151],[0,0,0,0,0,35,4,53,0,0,0,0,0,1,4,45,0,0,1,170,1,0,0,65,0,0,0,0,0,16,4,53],[0,0,0,65,1,0,0,57,0,0,0,4,0,16,4,63,0,0,1,171,1,0,0,65,0,0,4,236,0,1,4,48],[0,0,0,64,3,0,4,61,0,0,1,174,1,48,0,156,0,0,4,201,0,0,129,61,0,0,0,64,1,48,0,57],[0,0,0,64,0,16,4,63,0,0,0,9,1,0,0,57,0,0,0,0,2,1,4,26,0,0,0,32,4,48,0,57],[0,0,0,128,1,32,2,112,0,0,0,0,0,20,4,53,0,0,1,110,2,32,1,151,0,0,0,0,0,35,4,53],[0,0,0,0,0,1,4,45,0,0,1,170,1,0,0,65,0,0,0,0,0,16,4,53,0,0,0,65,1,0,0,57],[0,0,0,4,0,16,4,63,0,0,1,171,1,0,0,65,0,0,4,236,0,1,4,48,0,0,1,60,3,0,0,65],[0,0,1,60,4,16,0,156,0,0,0,0,1,3,128,25,0,0,0,64,1,16,2,16,0,0,1,60,4,32,0,156],[0,0,0,0,2,3,128,25,0,0,0,96,2,32,2,16,0,0,0,0,1,18,1,159,0,0,0,0,2,0,4,20],[0,0,1,60,4,32,0,156,0,0,0,0,2,3,128,25,0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159],[0,0,1,175,1,16,1,199,0,0,128,16,2,0,0,57,4,234,4,229,0,0,4,15,0,0,0,1,2,32,1,144],[0,0,4,227,0,0,97,61,0,0,0,0,1,1,4,59,0,0,0,0,0,1,4,45,0,0,0,0,1,0,0,25],[0,0,4,236,0,1,4,48,0,0,4,232,0,33,4,35,0,0,0,1,2,0,0,57,0,0,0,0,0,1,4,45],[0,0,0,0,2,0,0,25,0,0,0,0,0,1,4,45,0,0,4,234,0,0,4,50,0,0,4,235,0,1,4,46],[0,0,4,236,0,1,4,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255],[255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,8,225,188,155,240,64,0],[0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,1,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,133,223,81,252],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,168,81,174,119],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,212,164,202,12],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,239,14,47,243],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,239,14,47,244],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,254,23,59,151],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,212,164,202,13],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,221,234,168,230],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,213,185,72],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,213,185,73],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,208,242,198,99],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,168,81,174,120],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,191,31,228,32],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,154,138,5,145],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,162,37,239,202],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,162,37,239,203],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,166,174,10,172],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,154,138,5,146],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,160,128,62,247],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,142,138,207,134],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,142,138,207,135],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,147,139,95,50],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,133,223,81,253],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,138,200,76,14],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66,203,177,91],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,121,107,137,184],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,124,185,53,125],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,124,185,53,126],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,180,18,70],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,121,107,137,185],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,124,155,209,243],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,110,242,92,57],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,110,242,92,58],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,120,119,167,151],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66,203,177,92],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,75,233,158,29],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25,202,228,97],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,48,229,204,188],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,48,229,204,189],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,54,53,243,230],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25,202,228,98],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,41,241,114,173],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,250,87,121],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,190,208,54],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,231,81,123],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,128,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,224,0,0,0,0,0,0,0,0],[2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0],[8,195,121,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[84,104,101,32,99,117,114,114,101,110,116,32,98,97,116,99,104,32,110,117,109,98,101,114,32,109,117,115,116,32,98,101],[32,103,114,101,97,116,101,114,32,116,104,97,110,32,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,0,0,1,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,1,64,0,0,0,0,0,0,0,0],[255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0],[84,104,101,114,101,32,109,117,115,116,32,98,101,32,97,32,118,105,114,116,117,97,108,32,98,108,111,99,107,32,99,114],[101,97,116,101,100,32,97,116,32,116,104,101,32,115,116,97,114,116,32,111,102,32,116,104,101,32,98,97,116,99,104,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,0,0,0,128,0,0,0,0,0,0,0,0],[84,104,101,32,116,105,109,101,115,116,97,109,112,32,111,102,32,116,104,101,32,76,50,32,98,108,111,99,107,32,109,117],[115,116,32,98,101,32,103,114,101,97,116,101,114,32,116,104,97,110,32,111,114,32,101,113,117,97,108,32,116,111,32,116],[104,101,32,116,105,109,101,115,116,97,109,112,32,111,102,32,116,104,101,32,99,117,114,114,101,110,116,32,98,97,116,99],[104,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,196,0,0,0,128,0,0,0,0,0,0,0,0],[73,110,118,97,108,105,100,32,110,101,119,32,76,50,32,98,108,111,99,107,32,110,117,109,98,101,114,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,192,0,0,0,0,0,0,0,0],[2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,224,0,0,0,0,0,0,0,0],[111,114,114,101,99,116,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[84,104,101,32,99,117,114,114,101,110,116,32,76,50,32,98,108,111,99,107,32,104,97,115,104,32,105,115,32,105,110,99],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,0,0,0,0,0,0,0,0,0,0,0,0],[116,97,109,112,32,111,102,32,116,104,101,32,112,114,101,118,105,111,117,115,32,76,50,32,98,108,111,99,107,0,0,0],[107,32,109,117,115,116,32,98,101,32,103,114,101,97,116,101,114,32,116,104,97,110,32,116,104,101,32,116,105,109,101,115],[84,104,101,32,116,105,109,101,115,116,97,109,112,32,111,102,32,116,104,101,32,110,101,119,32,76,50,32,98,108,111,99],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,164,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,191],[67,97,110,32,110,111,116,32,114,101,117,115,101,32,76,50,32,98,108,111,99,107,32,110,117,109,98,101,114,32,102,114],[111,109,32,116,104,101,32,112,114,101,118,105,111,117,115,32,98,97,116,99,104,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,0,0,0,192,0,0,0,0,0,0,0,0],[84,104,101,32,116,105,109,101,115,116,97,109,112,32,111,102,32,116,104,101,32,115,97,109,101,32,76,50,32,98,108,111],[99,107,32,109,117,115,116,32,98,101,32,115,97,109,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[84,104,101,32,112,114,101,118,105,111,117,115,32,104,97,115,104,32,111,102,32,116,104,101,32,115,97,109,101,32,76,50],[32,98,108,111,99,107,32,109,117,115,116,32,98,101,32,115,97,109,101,0,0,0,0,0,0,0,0,0,0,0,0,0],[67,97,110,32,110,111,116,32,99,114,101,97,116,101,32,118,105,114,116,117,97,108,32,98,108,111,99,107,115,32,105,110],[32,116,104,101,32,109,105,100,100,108,101,32,111,102,32,116,104,101,32,109,105,110,105,98,108,111,99,107,0,0,0,0],[2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,224,0,0,0,0,0,0,0,0],[99,111,114,114,101,99,116,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[84,104,101,32,112,114,101,118,105,111,117,115,32,76,50,32,98,108,111,99,107,32,104,97,115,104,32,105,115,32,105,110],[255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[97,108,32,98,108,111,99,107,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[67,97,110,39,116,32,105,110,105,116,105,97,108,105,122,101,32,116,104,101,32,102,105,114,115,116,32,118,105,114,116,117],[76,50,32,98,108,111,99,107,32,110,117,109,98,101,114,32,105,115,32,110,101,118,101,114,32,101,120,112,101,99,116,101],[100,32,116,111,32,98,101,32,122,101,114,111,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[85,112,103,114,97,100,101,32,116,114,97,110,115,97,99,116,105,111,110,32,109,117,115,116,32,98,101,32,102,105,114,115],[116,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[67,97,108,108,97,98,108,101,32,111,110,108,121,32,98,121,32,116,104,101,32,98,111,111,116,108,111,97,100,101,114,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,128,0,0,0,0,0,0,0,0],[84,105,109,101,115,116,97,109,112,115,32,115,104,111,117,108,100,32,98,101,32,105,110,99,114,101,109,101,110,116,97,108],[84,104,101,32,112,114,111,118,105,100,101,100,32,98,97,116,99,104,32,110,117,109,98,101,114,32,105,115,32,110,111,116],[32,99,111,114,114,101,99,116,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[84,104,101,32,116,105,109,101,115,116,97,109,112,32,111,102,32,116,104,101,32,98,97,116,99,104,32,109,117,115,116,32],[98,101,32,103,114,101,97,116,101,114,32,116,104,97,110,32,116,104,101,32,116,105,109,101,115,116,97,109,112,32,111,102],[32,116,104,101,32,112,114,101,118,105,111,117,115,32,98,108,111,99,107,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,164,0,0,0,192,0,0,0,0,0,0,0,0],[78,72,123,113,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,64],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,192],[2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[8,46,192,117,217,203,84,36,60,38,104,21,28,13,84,56,81,134,80,14,26,183,203,50,90,1,112,186,248,175,212,147]],"0x000000000000000000000000000000000000800c":[[0,18,0,0,0,0,0,2,0,17,0,0,0,0,0,2,0,0,0,0,3,1,0,25,0,0,0,96,5,48,2,112],[0,0,7,164,3,80,1,151,0,1,0,0,0,49,3,85,0,2,0,0,0,49,3,85,0,3,0,0,0,49,3,85],[0,4,0,0,0,49,3,85,0,5,0,0,0,49,3,85,0,6,0,0,0,49,3,85,0,7,0,0,0,49,3,85],[0,8,0,0,0,49,3,85,0,9,0,0,0,49,3,85,0,10,0,0,0,49,3,85,0,11,0,0,0,49,3,85],[0,12,0,0,0,49,3,85,0,13,0,0,0,49,3,85,0,14,0,0,0,49,3,85,0,15,0,0,0,49,3,85],[0,16,0,0,0,49,3,85,0,17,0,0,0,1,3,85,0,0,7,164,0,80,1,157,0,0,0,128,4,0,0,57],[0,0,0,64,0,64,4,63,0,0,0,1,2,32,1,144,0,0,0,154,0,0,193,61,0,0,0,4,2,48,0,140],[0,0,0,204,0,0,65,61,0,0,0,0,2,1,4,59,0,0,7,166,2,32,1,151,0,0,7,167,2,32,0,156],[0,0,0,204,0,0,193,61,0,0,0,0,2,0,4,22,0,0,0,0,2,2,0,75,0,0,0,204,0,0,193,61],[0,0,0,4,2,48,0,138,0,0,0,32,6,32,0,140,0,0,0,204,0,0,65,61,0,0,0,4,6,16,3,112],[0,0,0,0,13,6,4,59,0,0,7,168,6,208,0,156,0,0,0,204,0,0,33,61,0,0,0,0,2,210,0,73],[0,0,7,169,6,0,0,65,0,0,2,96,7,32,0,140,0,0,0,0,7,0,0,25,0,0,0,0,7,6,64,25],[0,0,7,169,2,32,1,151,0,0,0,0,8,2,0,75,0,0,0,0,6,0,160,25,0,0,7,169,2,32,0,156],[0,0,0,0,6,7,192,25,0,0,0,0,2,6,0,75,0,0,0,204,0,0,193,61,0,0,0,4,12,208,0,57],[0,0,0,0,2,193,3,79,0,0,0,0,2,2,4,59,0,0,0,1,6,32,0,140,0,0,0,162,0,0,33,61],[0,0,0,0,4,2,0,75,0,0,0,216,0,0,97,61,0,0,0,1,1,32,0,140,0,0,0,206,0,0,193,61],[0,12,0,0,0,13,0,29,0,11,0,0,0,12,0,29,0,0,7,170,1,0,0,65,0,0,0,0,0,16,4,57],[0,0,7,164,1,0,0,65,0,0,0,0,2,0,4,20,0,0,7,164,3,32,0,156,0,0,0,0,2,1,128,25],[0,0,0,192,1,32,2,16,0,0,7,171,1,16,1,199,0,0,128,11,2,0,0,57,30,139,30,129,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,25,2,0,0,97,61,0,0,0,64,3,0,4,61,0,0,0,0,4,1,4,59],[0,0,0,128,1,64,0,140,0,0,2,41,0,0,65,61,0,0,0,128,1,64,2,112,0,0,7,174,2,64,0,156],[0,0,0,0,1,4,160,25,0,0,7,174,2,64,0,156,0,0,0,0,2,0,0,25,0,0,0,16,2,0,32,57],[0,0,0,8,5,32,1,191,0,0,7,168,6,16,0,156,0,0,0,0,5,2,160,25,0,0,0,64,2,16,2,112],[0,0,7,168,6,16,0,156,0,0,0,0,2,1,160,25,0,0,0,4,1,80,1,191,0,0,7,164,6,32,0,156],[0,0,0,0,1,5,160,25,0,0,0,32,6,32,2,112,0,0,7,164,5,32,0,156,0,0,0,0,6,2,160,25],[0,0,0,2,5,16,1,191,0,0,255,255,2,96,0,140,0,0,0,0,5,1,160,25,0,0,0,16,1,96,2,112],[0,0,0,0,1,6,160,25,0,0,0,255,1,16,0,140,0,0,0,1,5,80,32,57,0,0,0,32,1,0,0,138],[0,0,0,65,2,80,0,57,0,0,0,0,1,18,1,111,0,0,0,0,1,19,0,25,0,0,0,0,2,49,0,75],[0,0,0,0,2,0,0,25,0,0,0,1,2,0,64,57,0,0,7,168,6,16,0,156,0,0,4,10,0,0,33,61],[0,0,0,1,2,32,1,144,0,0,4,10,0,0,193,61,0,0,0,64,0,16,4,63,0,0,0,2,1,80,0,57],[0,0,0,0,6,19,4,54,0,0,0,17,1,0,3,103,0,0,0,0,2,0,0,49,0,0,0,33,7,80,0,57],[0,0,0,5,7,112,2,114,0,0,0,136,0,0,97,61,0,0,0,0,8,33,3,79,0,0,0,0,9,0,0,25],[0,0,0,5,10,144,2,16,0,0,0,0,11,166,0,25,0,0,0,0,10,168,3,79,0,0,0,0,10,10,4,59],[0,0,0,0,0,171,4,53,0,0,0,1,9,144,0,57,0,0,0,0,10,121,0,75,0,0,0,128,0,0,65,61],[0,0,0,0,7,0,0,75,0,0,0,138,0,0,97,61,0,0,0,0,7,3,4,51,0,0,0,0,7,7,0,75],[0,0,4,250,0,0,97,61,0,0,0,0,7,6,4,51,0,0,7,173,7,112,1,151,0,0,0,248,8,80,2,16],[0,0,0,0,7,120,1,159,0,0,7,175,7,112,0,65,0,0,0,0,0,118,4,53,0,0,0,3,5,80,2,16],[0,0,0,248,5,80,0,137,0,0,0,0,4,84,1,207,0,0,0,255,5,80,0,140,0,0,0,0,4,0,32,25],[0,0,0,33,5,48,0,57,0,0,2,59,0,0,1,61,0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75],[0,0,0,204,0,0,193,61,0,0,0,32,1,0,0,57,0,0,1,0,0,16,4,67,0,0,1,32,0,0,4,67],[0,0,7,165,1,0,0,65,0,0,30,140,0,1,4,46,0,0,0,2,6,32,0,140,0,0,1,27,0,0,97,61],[0,0,0,113,2,32,0,140,0,0,0,206,0,0,193,61,0,0,1,196,2,208,0,57,0,0,0,0,2,33,3,79],[0,0,0,0,6,211,0,73,0,0,0,35,6,96,0,138,0,0,0,0,2,2,4,59,0,0,7,169,7,0,0,65],[0,0,0,0,8,98,0,75,0,0,0,0,8,0,0,25,0,0,0,0,8,7,128,25,0,0,7,169,6,96,1,151],[0,0,7,169,9,32,1,151,0,0,0,0,10,105,0,75,0,0,0,0,7,0,128,25,0,0,0,0,6,105,1,63],[0,0,7,169,6,96,0,156,0,0,0,0,7,8,192,25,0,0,0,0,6,7,0,75,0,0,0,204,0,0,193,61],[0,0,0,0,6,194,0,25,0,0,0,0,2,97,3,79,0,0,0,0,2,2,4,59,0,0,7,168,7,32,0,156],[0,0,0,204,0,0,33,61,0,0,0,0,8,35,0,73,0,0,0,32,7,96,0,57,0,0,7,169,6,0,0,65],[0,0,0,0,9,135,0,75,0,0,0,0,9,0,0,25,0,0,0,0,9,6,32,25,0,0,7,169,8,128,1,151],[0,0,7,169,10,112,1,151,0,0,0,0,11,138,0,75,0,0,0,0,6,0,128,25,0,0,0,0,8,138,1,63],[0,0,7,169,8,128,0,156,0,0,0,0,6,9,192,25,0,0,0,0,6,6,0,75,0,0,2,233,0,0,97,61],[0,0,0,0,1,0,0,25,0,0,30,141,0,1,4,48,0,0,7,188,1,0,0,65,0,0,0,128,0,16,4,63],[0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63,0,0,0,23,1,0,0,57,0,0,0,164,0,16,4,63],[0,0,7,206,1,0,0,65,0,0,0,196,0,16,4,63,0,0,7,207,1,0,0,65,0,0,30,141,0,1,4,48],[0,0,0,0,2,49,3,79,0,0,1,0,5,192,0,57,0,0,0,0,4,81,3,79,0,0,0,0,4,4,4,59],[0,0,0,128,6,64,0,140,0,0,1,117,0,0,65,61,0,0,0,128,6,64,2,112,0,0,7,174,7,64,0,156],[0,0,0,0,6,4,160,25,0,0,7,174,7,64,0,156,0,0,0,0,7,0,0,25,0,0,0,16,7,0,32,57],[0,0,0,8,8,112,1,191,0,0,7,168,9,96,0,156,0,0,0,0,8,7,160,25,0,0,0,64,7,96,2,112],[0,0,7,168,9,96,0,156,0,0,0,0,7,6,160,25,0,0,0,4,9,128,1,191,0,0,7,164,6,112,0,156],[0,0,0,0,9,8,160,25,0,0,0,32,8,112,2,112,0,0,7,164,6,112,0,156,0,0,0,0,8,7,160,25],[0,0,0,2,6,144,1,191,0,0,255,255,7,128,0,140,0,0,0,0,6,9,160,25,0,0,0,16,7,128,2,112],[0,0,0,0,7,8,160,25,0,0,0,255,7,112,0,140,0,0,0,1,6,96,32,57,0,0,0,32,7,0,0,138],[0,0,0,193,8,96,0,57,0,0,0,0,7,120,1,111,0,0,0,64,0,112,4,63,0,0,0,2,7,96,0,57],[0,0,0,128,0,112,4,63,0,0,0,33,7,96,0,57,0,0,0,5,7,112,2,114,0,0,1,9,0,0,97,61],[0,0,0,0,8,0,0,25,0,0,0,5,9,128,2,16,0,0,0,0,10,146,3,79,0,0,0,0,10,10,4,59],[0,0,0,160,9,144,0,57,0,0,0,0,0,169,4,53,0,0,0,1,8,128,0,57,0,0,0,0,9,120,0,75],[0,0,1,1,0,0,65,61,0,0,0,0,7,0,0,75,0,0,1,11,0,0,97,61,0,0,0,128,7,0,4,61],[0,0,0,0,7,7,0,75,0,0,4,250,0,0,97,61,0,0,0,160,7,0,4,61,0,0,7,173,7,112,1,151],[0,0,0,248,8,96,2,16,0,0,0,0,7,120,1,159,0,0,7,175,7,112,0,65,0,0,0,160,0,112,4,63],[0,0,0,3,6,96,2,16,0,0,0,248,6,96,0,137,0,0,0,0,4,100,1,207,0,0,0,255,6,96,0,140],[0,0,0,0,4,0,32,25,0,0,0,161,0,64,4,63,0,0,1,129,0,0,1,61,0,12,0,0,0,13,0,29],[0,11,0,0,0,12,0,29,0,0,7,170,1,0,0,65,0,0,0,0,0,16,4,57,0,0,7,164,1,0,0,65],[0,0,0,0,2,0,4,20,0,0,7,164,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16],[0,0,7,171,1,16,1,199,0,0,128,11,2,0,0,57,30,139,30,129,0,0,4,15,0,0,0,1,2,32,1,144],[0,0,25,2,0,0,97,61,0,0,0,64,3,0,4,61,0,0,0,0,4,1,4,59,0,0,0,128,1,64,0,140],[0,0,2,137,0,0,65,61,0,0,0,128,1,64,2,112,0,0,7,174,2,64,0,156,0,0,0,0,1,4,160,25],[0,0,7,174,2,64,0,156,0,0,0,0,2,0,0,25,0,0,0,16,2,0,32,57,0,0,0,8,5,32,1,191],[0,0,7,168,6,16,0,156,0,0,0,0,5,2,160,25,0,0,0,64,2,16,2,112,0,0,7,168,6,16,0,156],[0,0,0,0,2,1,160,25,0,0,0,4,1,80,1,191,0,0,7,164,6,32,0,156,0,0,0,0,1,5,160,25],[0,0,0,32,6,32,2,112,0,0,7,164,5,32,0,156,0,0,0,0,6,2,160,25,0,0,0,2,5,16,1,191],[0,0,255,255,2,96,0,140,0,0,0,0,5,1,160,25,0,0,0,16,1,96,2,112,0,0,0,0,1,6,160,25],[0,0,0,255,1,16,0,140,0,0,0,1,5,80,32,57,0,0,0,32,1,0,0,138,0,0,0,65,2,80,0,57],[0,0,0,0,1,18,1,111,0,0,0,0,1,19,0,25,0,0,0,0,2,49,0,75,0,0,0,0,2,0,0,25],[0,0,0,1,2,0,64,57,0,0,7,168,6,16,0,156,0,0,4,10,0,0,33,61,0,0,0,1,2,32,1,144],[0,0,4,10,0,0,193,61,0,0,0,64,0,16,4,63,0,0,0,2,1,80,0,57,0,0,0,0,6,19,4,54],[0,0,0,17,1,0,3,103,0,0,0,0,2,0,0,49,0,0,0,33,7,80,0,57,0,0,0,5,7,112,2,114],[0,0,1,99,0,0,97,61,0,0,0,0,8,33,3,79,0,0,0,0,9,0,0,25,0,0,0,5,10,144,2,16],[0,0,0,0,11,166,0,25,0,0,0,0,10,168,3,79,0,0,0,0,10,10,4,59,0,0,0,0,0,171,4,53],[0,0,0,1,9,144,0,57,0,0,0,0,10,121,0,75,0,0,1,91,0,0,65,61,0,0,0,0,7,0,0,75],[0,0,1,101,0,0,97,61,0,0,0,0,7,3,4,51,0,0,0,0,7,7,0,75,0,0,4,250,0,0,97,61],[0,0,0,0,7,6,4,51,0,0,7,173,7,112,1,151,0,0,0,248,8,80,2,16,0,0,0,0,7,120,1,159],[0,0,7,175,7,112,0,65,0,0,0,0,0,118,4,53,0,0,0,3,5,80,2,16,0,0,0,248,5,80,0,137],[0,0,0,0,4,84,1,207,0,0,0,255,5,80,0,140,0,0,0,0,4,0,32,25,0,0,0,33,5,48,0,57],[0,0,2,155,0,0,1,61,0,0,0,248,6,64,2,16,0,0,7,169,7,0,0,65,0,0,0,0,4,4,0,75],[0,0,0,0,7,6,192,25,0,0,0,192,4,0,0,57,0,0,0,64,0,64,4,63,0,0,0,1,4,0,0,57],[0,0,0,128,0,64,4,63,0,0,0,0,4,2,4,59,0,0,7,173,4,64,1,151,0,0,0,0,4,116,1,159],[0,0,0,160,0,64,4,63,0,12,0,0,0,13,0,29,0,11,0,0,0,12,0,29,0,0,0,64,4,0,4,61],[0,0,0,96,5,80,0,138,0,0,0,0,6,81,3,79,0,0,0,0,6,6,4,59,0,0,0,128,7,96,0,140],[0,0,1,206,0,0,65,61,0,0,0,128,7,96,2,112,0,0,7,174,8,96,0,156,0,0,0,0,7,6,160,25],[0,0,7,174,8,96,0,156,0,0,0,0,8,0,0,25,0,0,0,16,8,0,32,57,0,0,0,8,9,128,1,191],[0,0,7,168,10,112,0,156,0,0,0,0,9,8,160,25,0,0,0,64,8,112,2,112,0,0,7,168,10,112,0,156],[0,0,0,0,8,7,160,25,0,0,0,4,10,144,1,191,0,0,7,164,7,128,0,156,0,0,0,0,10,9,160,25],[0,0,0,32,9,128,2,112,0,0,7,164,7,128,0,156,0,0,0,0,9,8,160,25,0,0,0,2,7,160,1,191],[0,0,255,255,8,144,0,140,0,0,0,0,7,10,160,25,0,0,0,16,8,144,2,112,0,0,0,0,8,9,160,25],[0,0,0,255,8,128,0,140,0,0,0,1,7,112,32,57,0,0,0,32,8,0,0,138,0,0,0,65,9,112,0,57],[0,0,0,0,8,137,1,111,0,0,0,0,8,132,0,25,0,0,0,0,9,72,0,75,0,0,0,0,9,0,0,25],[0,0,0,1,9,0,64,57,0,0,7,168,10,128,0,156,0,0,4,10,0,0,33,61,0,0,0,1,9,144,1,144],[0,0,4,10,0,0,193,61,0,0,0,64,0,128,4,63,0,0,0,2,8,112,0,57,0,0,0,0,8,132,4,54],[0,0,0,33,9,112,0,57,0,0,0,5,9,144,2,114,0,0,1,188,0,0,97,61,0,0,0,0,10,0,0,25],[0,0,0,5,11,160,2,16,0,0,0,0,12,184,0,25,0,0,0,0,11,178,3,79,0,0,0,0,11,11,4,59],[0,0,0,0,0,188,4,53,0,0,0,1,10,160,0,57,0,0,0,0,11,154,0,75,0,0,1,180,0,0,65,61],[0,0,0,0,9,0,0,75,0,0,1,190,0,0,97,61,0,0,0,0,9,4,4,51,0,0,0,0,9,9,0,75],[0,0,4,250,0,0,97,61,0,0,0,0,9,8,4,51,0,0,7,173,9,144,1,151,0,0,0,248,10,112,2,16],[0,0,0,0,9,154,1,159,0,0,7,175,9,144,0,65,0,0,0,0,0,152,4,53,0,0,0,3,7,112,2,16],[0,0,0,248,7,112,0,137,0,0,0,0,6,118,1,207,0,0,0,255,7,112,0,140,0,0,0,0,6,0,32,25],[0,0,0,33,7,64,0,57,0,0,1,221,0,0,1,61,0,0,7,172,7,64,0,156,0,0,4,10,0,0,33,61],[0,0,0,64,7,64,0,57,0,0,0,64,0,112,4,63,0,0,0,1,7,0,0,58,0,0,0,0,7,116,4,54],[0,0,0,0,8,2,4,59,0,0,0,0,0,135,4,53,0,0,4,250,0,0,97,61,0,0,0,248,9,96,2,16],[0,0,7,169,10,0,0,65,0,0,0,0,6,6,0,75,0,0,0,0,10,9,192,25,0,0,7,173,6,128,1,151],[0,0,0,0,6,166,1,159,0,0,0,0,0,103,4,53,0,0,0,64,5,80,0,138,0,0,0,0,6,81,3,79],[0,0,0,64,5,0,4,61,0,0,0,0,6,6,4,59,0,0,0,128,7,96,0,140,0,0,3,13,0,0,65,61],[0,0,0,128,7,96,2,112,0,0,7,174,8,96,0,156,0,0,0,0,7,6,160,25,0,0,7,174,8,96,0,156],[0,0,0,0,8,0,0,25,0,0,0,16,8,0,32,57,0,0,0,8,9,128,1,191,0,0,7,168,10,112,0,156],[0,0,0,0,9,8,160,25,0,0,0,64,8,112,2,112,0,0,7,168,10,112,0,156,0,0,0,0,8,7,160,25],[0,0,0,4,10,144,1,191,0,0,7,164,7,128,0,156,0,0,0,0,10,9,160,25,0,0,0,32,9,128,2,112],[0,0,7,164,7,128,0,156,0,0,0,0,9,8,160,25,0,0,0,2,7,160,1,191,0,0,255,255,8,144,0,140],[0,0,0,0,7,10,160,25,0,0,0,16,8,144,2,112,0,0,0,0,8,9,160,25,0,0,0,255,8,128,0,140],[0,0,0,1,7,112,32,57,0,0,0,32,8,0,0,138,0,0,0,65,9,112,0,57,0,0,0,0,8,137,1,111],[0,0,0,0,8,133,0,25,0,0,0,0,9,88,0,75,0,0,0,0,9,0,0,25,0,0,0,1,9,0,64,57],[0,0,7,168,10,128,0,156,0,0,4,10,0,0,33,61,0,0,0,1,9,144,1,144,0,0,4,10,0,0,193,61],[0,0,0,64,0,128,4,63,0,0,0,2,8,112,0,57,0,0,0,0,8,133,4,54,0,0,0,33,9,112,0,57],[0,0,0,5,9,144,2,114,0,0,2,23,0,0,97,61,0,0,0,0,10,0,0,25,0,0,0,5,11,160,2,16],[0,0,0,0,12,184,0,25,0,0,0,0,11,178,3,79,0,0,0,0,11,11,4,59,0,0,0,0,0,188,4,53],[0,0,0,1,10,160,0,57,0,0,0,0,11,154,0,75,0,0,2,15,0,0,65,61,0,0,0,0,9,0,0,75],[0,0,2,25,0,0,97,61,0,0,0,0,9,5,4,51,0,0,0,0,9,9,0,75,0,0,4,250,0,0,97,61],[0,0,0,0,9,8,4,51,0,0,7,173,9,144,1,151,0,0,0,248,10,112,2,16,0,0,0,0,9,154,1,159],[0,0,7,175,9,144,0,65,0,0,0,0,0,152,4,53,0,0,0,3,7,112,2,16,0,0,0,248,7,112,0,137],[0,0,0,0,6,118,1,207,0,0,0,255,7,112,0,140,0,0,0,0,6,0,32,25,0,0,0,33,7,80,0,57],[0,0,3,28,0,0,1,61,0,0,7,172,1,48,0,156,0,0,4,10,0,0,33,61,0,0,0,64,1,48,0,57],[0,0,0,64,0,16,4,63,0,0,0,1,1,0,0,58,0,0,0,0,5,19,4,54,0,0,0,0,2,0,0,49],[0,0,0,17,1,0,3,103,0,0,0,0,6,33,3,79,0,0,0,0,6,6,4,59,0,0,0,0,0,101,4,53],[0,0,4,250,0,0,97,61,0,0,0,248,7,64,2,16,0,0,7,169,8,0,0,65,0,0,0,0,4,4,0,75],[0,0,0,0,8,7,192,25,0,0,7,173,4,96,1,151,0,0,0,0,4,132,1,159,0,0,0,0,0,69,4,53],[0,0,0,64,4,0,4,61,0,0,0,12,5,0,0,41,0,0,1,4,6,80,0,57,0,0,0,0,5,97,3,79],[0,0,0,0,5,5,4,59,0,0,0,128,7,80,0,140,0,0,3,171,0,0,65,61,0,0,0,128,7,80,2,112],[0,0,7,174,8,80,0,156,0,0,0,0,7,5,160,25,0,0,7,174,8,80,0,156,0,0,0,0,8,0,0,25],[0,0,0,16,8,0,32,57,0,0,0,8,9,128,1,191,0,0,7,168,10,112,0,156,0,0,0,0,9,8,160,25],[0,0,0,64,8,112,2,112,0,0,7,168,10,112,0,156,0,0,0,0,8,7,160,25,0,0,0,4,10,144,1,191],[0,0,7,164,7,128,0,156,0,0,0,0,10,9,160,25,0,0,0,32,9,128,2,112,0,0,7,164,7,128,0,156],[0,0,0,0,9,8,160,25,0,0,0,2,7,160,1,191,0,0,255,255,8,144,0,140,0,0,0,0,7,10,160,25],[0,0,0,16,8,144,2,112,0,0,0,0,8,9,160,25,0,0,0,255,8,128,0,140,0,0,0,1,7,112,32,57],[0,0,0,32,8,0,0,138,0,0,0,65,9,112,0,57,0,0,0,0,8,137,1,111,0,0,0,0,8,132,0,25],[0,0,0,0,9,72,0,75,0,0,0,0,9,0,0,25,0,0,0,1,9,0,64,57,0,0,7,168,10,128,0,156],[0,0,4,10,0,0,33,61,0,0,0,1,9,144,1,144,0,0,4,10,0,0,193,61,0,0,0,64,0,128,4,63],[0,0,0,2,8,112,0,57,0,0,0,0,8,132,4,54,0,0,0,33,9,112,0,57,0,0,0,5,9,144,2,114],[0,0,2,119,0,0,97,61,0,0,0,0,10,33,3,79,0,0,0,0,11,0,0,25,0,0,0,5,12,176,2,16],[0,0,0,0,13,200,0,25,0,0,0,0,12,202,3,79,0,0,0,0,12,12,4,59,0,0,0,0,0,205,4,53],[0,0,0,1,11,176,0,57,0,0,0,0,12,155,0,75,0,0,2,111,0,0,65,61,0,0,0,0,9,0,0,75],[0,0,2,121,0,0,97,61,0,0,0,0,9,4,4,51,0,0,0,0,9,9,0,75,0,0,4,250,0,0,97,61],[0,0,0,0,9,8,4,51,0,0,7,173,9,144,1,151,0,0,0,248,10,112,2,16,0,0,0,0,9,154,1,159],[0,0,7,175,9,144,0,65,0,0,0,0,0,152,4,53,0,0,0,3,7,112,2,16,0,0,0,248,7,112,0,137],[0,0,0,0,5,117,1,207,0,0,0,255,7,112,0,140,0,0,0,0,5,0,32,25,0,0,0,33,7,64,0,57],[0,0,3,187,0,0,1,61,0,0,7,172,1,48,0,156,0,0,4,10,0,0,33,61,0,0,0,64,1,48,0,57],[0,0,0,64,0,16,4,63,0,0,0,1,1,0,0,58,0,0,0,0,5,19,4,54,0,0,0,0,2,0,0,49],[0,0,0,17,1,0,3,103,0,0,0,0,6,33,3,79,0,0,0,0,6,6,4,59,0,0,0,0,0,101,4,53],[0,0,4,250,0,0,97,61,0,0,0,248,7,64,2,16,0,0,7,169,8,0,0,65,0,0,0,0,4,4,0,75],[0,0,0,0,8,7,192,25,0,0,7,173,4,96,1,151,0,0,0,0,4,132,1,159,0,0,0,0,0,69,4,53],[0,0,0,64,4,0,4,61,0,0,0,12,5,0,0,41,0,0,1,4,6,80,0,57,0,0,0,0,5,97,3,79],[0,0,0,0,5,5,4,59,0,0,0,128,7,80,0,140,0,0,4,8,0,0,65,61,0,0,0,128,7,80,2,112],[0,0,7,174,8,80,0,156,0,0,0,0,7,5,160,25,0,0,7,174,8,80,0,156,0,0,0,0,8,0,0,25],[0,0,0,16,8,0,32,57,0,0,0,8,9,128,1,191,0,0,7,168,10,112,0,156,0,0,0,0,9,8,160,25],[0,0,0,64,8,112,2,112,0,0,7,168,10,112,0,156,0,0,0,0,8,7,160,25,0,0,0,4,10,144,1,191],[0,0,7,164,7,128,0,156,0,0,0,0,10,9,160,25,0,0,0,32,9,128,2,112,0,0,7,164,7,128,0,156],[0,0,0,0,9,8,160,25,0,0,0,2,7,160,1,191,0,0,255,255,8,144,0,140,0,0,0,0,7,10,160,25],[0,0,0,16,8,144,2,112,0,0,0,0,8,9,160,25,0,0,0,255,8,128,0,140,0,0,0,1,7,112,32,57],[0,0,0,32,8,0,0,138,0,0,0,65,9,112,0,57,0,0,0,0,8,137,1,111,0,0,0,0,8,132,0,25],[0,0,0,0,9,72,0,75,0,0,0,0,9,0,0,25,0,0,0,1,9,0,64,57,0,0,7,168,10,128,0,156],[0,0,4,10,0,0,33,61,0,0,0,1,9,144,1,144,0,0,4,10,0,0,193,61,0,0,0,64,0,128,4,63],[0,0,0,2,8,112,0,57,0,0,0,0,8,132,4,54,0,0,0,33,9,112,0,57,0,0,0,5,9,144,2,114],[0,0,2,215,0,0,97,61,0,0,0,0,10,33,3,79,0,0,0,0,11,0,0,25,0,0,0,5,12,176,2,16],[0,0,0,0,13,200,0,25,0,0,0,0,12,202,3,79,0,0,0,0,12,12,4,59,0,0,0,0,0,205,4,53],[0,0,0,1,11,176,0,57,0,0,0,0,12,155,0,75,0,0,2,207,0,0,65,61,0,0,0,0,9,0,0,75],[0,0,2,217,0,0,97,61,0,0,0,0,9,4,4,51,0,0,0,0,9,9,0,75,0,0,4,250,0,0,97,61],[0,0,0,0,9,8,4,51,0,0,7,173,9,144,1,151,0,0,0,248,10,112,2,16,0,0,0,0,9,154,1,159],[0,0,7,175,9,144,0,65,0,0,0,0,0,152,4,53,0,0,0,3,7,112,2,16,0,0,0,248,7,112,0,137],[0,0,0,0,5,117,1,207,0,0,0,255,7,112,0,140,0,0,0,0,5,0,32,25,0,0,0,33,7,64,0,57],[0,0,5,126,0,0,1,61,0,0,7,164,8,112,1,151,0,0,0,0,6,0,4,20,0,1,0,0,0,129,3,85],[0,0,0,0,7,114,0,25,0,0,0,0,2,39,0,75,0,0,0,0,2,0,0,25,0,0,0,1,2,0,64,57],[0,0,0,1,2,32,1,144,0,0,24,254,0,0,193,61,0,0,0,0,2,115,0,75,0,0,24,254,0,0,65,61],[0,12,0,0,0,13,0,29,0,11,0,0,0,12,0,29,0,0,0,0,1,129,3,79,0,0,0,0,2,117,0,73],[0,0,7,164,2,32,1,151,0,1,0,0,0,33,3,229,0,0,7,182,3,96,0,156,0,0,4,14,0,0,65,61],[0,0,0,68,1,64,0,57,0,0,7,198,2,0,0,65,0,0,0,0,0,33,4,53,0,0,0,36,1,64,0,57],[0,0,0,8,2,0,0,57,0,0,0,0,0,33,4,53,0,0,7,188,1,0,0,65,0,0,0,0,0,20,4,53],[0,0,0,4,1,64,0,57,0,0,0,32,2,0,0,57,0,0,0,0,0,33,4,53,0,0,7,164,1,0,0,65],[0,0,7,164,2,64,0,156,0,0,0,0,4,1,128,25,0,0,0,64,1,64,2,16,0,0,7,189,1,16,1,199],[0,0,30,141,0,1,4,48,0,0,7,172,7,80,0,156,0,0,4,10,0,0,33,61,0,0,0,64,7,80,0,57],[0,0,0,64,0,112,4,63,0,0,0,1,7,0,0,58,0,0,0,0,7,117,4,54,0,0,0,0,8,2,4,59],[0,0,0,0,0,135,4,53,0,0,4,250,0,0,97,61,0,0,0,248,9,96,2,16,0,0,7,169,10,0,0,65],[0,0,0,0,6,6,0,75,0,0,0,0,10,9,192,25,0,0,7,173,6,128,1,151,0,0,0,0,6,166,1,159],[0,0,0,0,0,103,4,53,0,0,0,64,6,0,4,61,0,10,0,0,0,6,0,29,0,0,0,32,6,96,0,57],[0,0,0,0,7,4,4,51,0,0,0,0,8,7,0,75,0,0,3,43,0,0,97,61,0,0,0,0,8,0,0,25],[0,0,0,0,9,104,0,25,0,0,0,32,8,128,0,57,0,0,0,0,10,72,0,25,0,0,0,0,10,10,4,51],[0,0,0,0,0,169,4,53,0,0,0,0,9,120,0,75,0,0,3,36,0,0,65,61,0,0,0,0,4,103,0,25],[0,0,0,0,0,4,4,53,0,0,0,0,6,5,4,51,0,0,0,0,7,6,0,75,0,0,3,56,0,0,97,61],[0,0,0,0,7,0,0,25,0,0,0,0,8,71,0,25,0,0,0,32,7,112,0,57,0,0,0,0,9,87,0,25],[0,0,0,0,9,9,4,51,0,0,0,0,0,152,4,53,0,0,0,0,8,103,0,75,0,0,3,49,0,0,65,61],[0,0,0,0,4,70,0,25,0,0,0,0,0,4,4,53,0,0,0,10,6,0,0,41,0,0,0,0,4,100,0,73],[0,0,0,32,5,64,0,138,0,0,0,0,0,86,4,53,0,0,0,31,4,64,0,57,0,8,0,32,0,0,0,146],[0,0,0,8,4,64,1,127,0,0,0,0,5,100,0,25,0,0,0,0,4,69,0,75,0,0,0,0,4,0,0,25],[0,0,0,1,4,0,64,57,0,9,0,0,0,5,0,29,0,0,7,168,5,80,0,156,0,0,4,10,0,0,33,61],[0,0,0,1,4,64,1,144,0,0,4,10,0,0,193,61,0,0,0,9,4,0,0,41,0,0,0,64,0,64,4,63],[0,0,7,172,4,64,0,156,0,0,4,10,0,0,33,61,0,0,0,12,7,0,0,41,0,0,0,68,4,112,0,57],[0,0,0,0,4,65,3,79,0,0,0,0,4,4,4,59,0,0,0,9,8,0,0,41,0,0,0,64,5,128,0,57],[0,0,0,64,0,80,4,63,0,0,0,32,5,128,0,57,0,0,7,176,6,0,0,65,0,0,0,0,0,101,4,53],[0,0,0,21,5,0,0,57,0,0,0,0,0,88,4,53,0,0,0,96,4,64,2,16,0,0,0,33,5,128,0,57],[0,0,0,0,0,69,4,53,0,0,1,36,4,112,0,57,0,0,0,0,5,65,3,79,0,0,0,64,6,0,4,61],[0,7,0,0,0,6,0,29,0,0,0,0,5,5,4,59,0,0,0,128,6,80,0,140,0,0,6,40,0,0,65,61],[0,0,0,128,6,80,2,112,0,0,7,174,7,80,0,156,0,0,0,0,6,5,160,25,0,0,7,174,7,80,0,156],[0,0,0,0,7,0,0,25,0,0,0,16,7,0,32,57,0,0,0,8,8,112,1,191,0,0,7,168,9,96,0,156],[0,0,0,0,8,7,160,25,0,0,0,64,7,96,2,112,0,0,7,168,9,96,0,156,0,0,0,0,7,6,160,25],[0,0,0,4,9,128,1,191,0,0,7,164,6,112,0,156,0,0,0,0,9,8,160,25,0,0,0,32,8,112,2,112],[0,0,7,164,6,112,0,156,0,0,0,0,8,7,160,25,0,0,0,2,6,144,1,191,0,0,255,255,7,128,0,140],[0,0,0,0,6,9,160,25,0,0,0,16,7,128,2,112,0,0,0,0,7,8,160,25,0,0,0,255,7,112,0,140],[0,0,0,1,6,96,32,57,0,0,0,65,7,96,0,57,0,0,0,8,7,112,1,127,0,0,0,7,7,112,0,41],[0,0,0,7,8,112,0,108,0,0,0,0,8,0,0,25,0,0,0,1,8,0,64,57,0,0,7,168,9,112,0,156],[0,0,4,10,0,0,33,61,0,0,0,1,8,128,1,144,0,0,4,10,0,0,193,61,0,0,0,64,0,112,4,63],[0,0,0,2,7,96,0,57,0,0,0,7,8,0,0,41,0,0,0,0,7,120,4,54,0,0,0,33,8,96,0,57],[0,0,0,5,8,128,2,114,0,0,3,151,0,0,97,61,0,0,0,0,9,0,0,25,0,0,0,5,10,144,2,16],[0,0,0,0,11,167,0,25,0,0,0,0,10,162,3,79,0,0,0,0,10,10,4,59,0,0,0,0,0,171,4,53],[0,0,0,1,9,144,0,57,0,0,0,0,10,137,0,75,0,0,3,143,0,0,65,61,0,0,0,0,8,0,0,75],[0,0,3,153,0,0,97,61,0,0,0,7,8,0,0,41,0,0,0,0,8,8,4,51,0,0,0,0,8,8,0,75],[0,0,4,250,0,0,97,61,0,0,0,0,8,7,4,51,0,0,7,173,8,128,1,151,0,0,0,248,9,96,2,16],[0,0,0,0,8,137,1,159,0,0,7,175,8,128,0,65,0,0,0,0,0,135,4,53,0,0,0,3,6,96,2,16],[0,0,0,248,6,96,0,137,0,0,0,0,5,101,1,207,0,0,0,255,6,96,0,140,0,0,0,0,5,0,32,25],[0,0,0,7,6,0,0,41,0,0,0,33,6,96,0,57,0,0,6,57,0,0,1,61,0,0,7,172,7,64,0,156],[0,0,4,10,0,0,33,61,0,0,0,64,7,64,0,57,0,0,0,64,0,112,4,63,0,0,0,0,8,33,3,79],[0,0,0,1,7,0,0,58,0,0,0,0,7,116,4,54,0,0,0,0,8,8,4,59,0,0,0,0,0,135,4,53],[0,0,4,250,0,0,97,61,0,0,0,248,9,80,2,16,0,0,7,169,10,0,0,65,0,0,0,0,5,5,0,75],[0,0,0,0,10,9,192,25,0,0,7,173,5,128,1,151,0,0,0,0,5,165,1,159,0,0,0,0,0,87,4,53],[0,0,0,64,5,0,4,61,0,0,0,96,6,96,0,138,0,0,0,0,7,97,3,79,0,0,0,0,7,7,4,59],[0,0,0,128,8,112,0,140,0,0,5,0,0,0,65,61,0,0,0,128,8,112,2,112,0,0,7,174,9,112,0,156],[0,0,0,0,8,7,160,25,0,0,7,174,9,112,0,156,0,0,0,0,9,0,0,25,0,0,0,16,9,0,32,57],[0,0,0,8,10,144,1,191,0,0,7,168,11,128,0,156,0,0,0,0,10,9,160,25,0,0,0,64,9,128,2,112],[0,0,7,168,11,128,0,156,0,0,0,0,9,8,160,25,0,0,0,4,11,160,1,191,0,0,7,164,8,144,0,156],[0,0,0,0,11,10,160,25,0,0,0,32,10,144,2,112,0,0,7,164,8,144,0,156,0,0,0,0,10,9,160,25],[0,0,0,2,8,176,1,191,0,0,255,255,9,160,0,140,0,0,0,0,8,11,160,25,0,0,0,16,9,160,2,112],[0,0,0,0,9,10,160,25,0,0,0,255,9,144,0,140,0,0,0,1,8,128,32,57,0,0,0,32,9,0,0,138],[0,0,0,65,10,128,0,57,0,0,0,0,9,154,1,111,0,0,0,0,9,149,0,25,0,0,0,0,10,89,0,75],[0,0,0,0,10,0,0,25,0,0,0,1,10,0,64,57,0,0,7,168,11,144,0,156,0,0,4,10,0,0,33,61],[0,0,0,1,10,160,1,144,0,0,4,10,0,0,193,61,0,0,0,64,0,144,4,63,0,0,0,2,9,128,0,57],[0,0,0,0,9,149,4,54,0,0,0,33,10,128,0,57,0,0,0,5,10,160,2,114,0,0,3,246,0,0,97,61],[0,0,0,0,11,33,3,79,0,0,0,0,12,0,0,25,0,0,0,5,13,192,2,16,0,0,0,0,14,217,0,25],[0,0,0,0,13,219,3,79,0,0,0,0,13,13,4,59,0,0,0,0,0,222,4,53,0,0,0,1,12,192,0,57],[0,0,0,0,13,172,0,75,0,0,3,238,0,0,65,61,0,0,0,0,10,0,0,75,0,0,3,248,0,0,97,61],[0,0,0,0,10,5,4,51,0,0,0,0,10,10,0,75,0,0,4,250,0,0,97,61,0,0,0,0,10,9,4,51],[0,0,7,173,10,160,1,151,0,0,0,248,11,128,2,16,0,0,0,0,10,171,1,159,0,0,7,175,10,160,0,65],[0,0,0,0,0,169,4,53,0,0,0,3,8,128,2,16,0,0,0,248,8,128,0,137,0,0,0,0,7,135,1,207],[0,0,0,255,8,128,0,140,0,0,0,0,7,0,32,25,0,0,0,33,8,80,0,57,0,0,5,16,0,0,1,61],[0,0,7,172,7,64,0,156,0,0,4,242,0,0,161,61,0,0,7,201,1,0,0,65,0,0,0,0,0,16,4,53],[0,0,0,65,1,0,0,57,0,0,4,253,0,0,1,61,0,0,0,0,1,33,3,223,0,0,0,192,2,96,2,16],[0,0,7,183,2,32,1,151,0,0,7,184,2,32,1,199,0,1,0,0,0,33,3,181,0,0,0,0,1,33,3,175],[0,0,128,16,2,0,0,57,30,139,30,134,0,0,4,15,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112],[0,0,7,164,5,48,1,151,0,0,0,1,2,32,1,144,0,0,5,93,0,0,97,61,0,0,0,63,2,80,0,57],[0,0,7,185,2,32,1,151,0,0,0,64,6,0,4,61,0,0,0,0,2,38,0,25,0,0,0,0,3,98,0,75],[0,0,0,0,3,0,0,25,0,0,0,1,3,0,64,57,0,0,7,168,4,32,0,156,0,0,4,10,0,0,33,61],[0,0,0,1,3,48,1,144,0,0,4,10,0,0,193,61,0,0,0,64,0,32,4,63,0,0,0,0,4,86,4,54],[0,0,0,17,2,0,3,103,0,0,0,0,3,0,0,49,0,0,0,31,7,80,0,57,0,0,0,5,7,112,2,114],[0,0,4,55,0,0,97,61,0,0,0,0,8,50,3,79,0,0,0,0,9,0,0,25,0,0,0,5,10,144,2,16],[0,0,0,0,11,164,0,25,0,0,0,0,10,168,3,79,0,0,0,0,10,10,4,59,0,0,0,0,0,171,4,53],[0,0,0,1,9,144,0,57,0,0,0,0,10,121,0,75,0,0,4,47,0,0,65,61,0,0,0,0,7,0,0,75],[0,0,4,57,0,0,97,61,0,0,0,31,7,80,1,143,0,0,0,5,5,80,2,114,0,0,4,69,0,0,97,61],[0,0,0,0,8,0,0,25,0,0,0,5,9,128,2,16,0,0,0,0,10,148,0,25,0,0,0,0,9,145,3,79],[0,0,0,0,9,9,4,59,0,0,0,0,0,154,4,53,0,0,0,1,8,128,0,57,0,0,0,0,9,88,0,75],[0,0,4,61,0,0,65,61,0,0,0,0,8,7,0,75,0,0,4,84,0,0,97,61,0,0,0,5,5,80,2,16],[0,0,0,0,1,81,3,79,0,0,0,0,5,84,0,25,0,0,0,3,7,112,2,16,0,0,0,0,8,5,4,51],[0,0,0,0,8,120,1,207,0,0,0,0,8,120,2,47,0,0,0,0,1,1,4,59,0,0,1,0,7,112,0,137],[0,0,0,0,1,113,2,47,0,0,0,0,1,113,1,207,0,0,0,0,1,129,1,159,0,0,0,0,0,21,4,53],[0,0,0,0,1,6,4,51,0,0,0,32,1,16,0,140,0,0,12,153,0,0,193,61,0,0,0,12,6,0,0,41],[0,0,0,0,1,99,0,73,0,0,0,35,5,16,0,138,0,10,2,4,0,96,0,61,0,0,0,10,1,32,3,96],[0,0,0,0,1,1,4,59,0,0,7,169,6,0,0,65,0,0,0,0,7,81,0,75,0,0,0,0,7,0,0,25],[0,0,0,0,7,6,128,25,0,0,7,169,5,80,1,151,0,0,7,169,8,16,1,151,0,0,0,0,9,88,0,75],[0,0,0,0,6,0,128,25,0,0,0,0,5,88,1,63,0,0,7,169,5,80,0,156,0,0,0,0,6,7,192,25],[0,0,0,0,5,6,0,75,0,0,0,11,5,0,0,41,0,0,0,204,0,0,193,61,0,0,0,0,4,4,4,51],[0,9,0,0,0,4,0,29,0,0,0,0,1,81,0,25,0,0,0,0,4,18,3,79,0,0,0,0,5,4,4,59],[0,0,7,168,4,80,0,156,0,0,0,204,0,0,33,61,0,0,0,5,4,80,2,16,0,0,0,0,3,67,0,73],[0,0,0,32,6,16,0,57,0,0,7,169,1,0,0,65,0,0,0,0,7,54,0,75,0,0,0,0,7,0,0,25],[0,0,0,0,7,1,32,25,0,0,7,169,3,48,1,151,0,0,7,169,8,96,1,151,0,0,0,0,9,56,0,75],[0,0,0,0,1,0,128,25,0,0,0,0,3,56,1,63,0,0,7,169,3,48,0,156,0,0,0,0,1,7,192,25],[0,0,0,0,1,1,0,75,0,0,0,204,0,0,193,61,0,0,0,64,1,0,4,61,0,0,0,32,3,16,0,57],[0,0,7,186,5,80,1,152,0,0,4,144,0,0,97,61,0,0,0,0,2,98,3,79,0,0,0,0,6,0,0,25],[0,0,0,5,7,96,2,16,0,0,0,0,8,115,0,25,0,0,0,0,7,114,3,79,0,0,0,0,7,7,4,59],[0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,4,136,0,0,65,61],[0,0,0,0,2,0,0,75,0,0,4,146,0,0,97,61,0,0,0,0,0,65,4,53,0,0,0,63,2,64,0,57],[0,0,0,32,4,0,0,138,0,0,0,0,2,66,1,111,0,0,0,0,2,33,0,25,0,0,0,0,4,18,0,75],[0,0,0,0,4,0,0,25,0,0,0,1,4,0,64,57,0,0,7,168,5,32,0,156,0,0,4,10,0,0,33,61],[0,0,0,1,4,64,1,144,0,0,4,10,0,0,193,61,0,0,0,64,0,32,4,63,0,0,7,164,2,0,0,65],[0,0,7,164,4,48,0,156,0,0,0,0,3,2,128,25,0,0,0,64,3,48,2,16,0,0,0,0,1,1,4,51],[0,0,7,164,4,16,0,156,0,0,0,0,1,2,128,25,0,0,0,96,1,16,2,16,0,0,0,0,1,49,1,159],[0,0,0,0,3,0,4,20,0,0,7,164,4,48,0,156,0,0,0,0,3,2,128,25,0,0,0,192,2,48,2,16],[0,0,0,0,1,18,1,159,0,0,7,181,1,16,1,199,0,0,128,16,2,0,0,57,30,139,30,129,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,0,11,10,0,0,41,0,0,0,12,3,0,0,41,0,0,0,204,0,0,97,61],[0,0,0,0,2,0,0,49,0,0,0,0,3,50,0,73,0,0,0,35,5,48,0,138,0,0,0,10,3,0,0,41],[0,0,0,32,4,48,0,57,0,0,0,17,3,0,3,103,0,0,0,0,4,67,3,79,0,0,0,0,4,4,4,59],[0,0,7,169,6,0,0,65,0,0,0,0,7,84,0,75,0,0,0,0,7,0,0,25,0,0,0,0,7,6,128,25],[0,0,7,169,5,80,1,151,0,0,7,169,8,64,1,151,0,0,0,0,9,88,0,75,0,0,0,0,6,0,128,25],[0,0,0,0,5,88,1,63,0,0,7,169,5,80,0,156,0,0,0,0,6,7,192,25,0,0,0,0,1,1,4,59],[0,10,0,0,0,1,0,29,0,0,0,0,1,6,0,75,0,0,0,204,0,0,193,61,0,0,0,0,4,164,0,25],[0,0,0,0,1,67,3,79,0,0,0,0,1,1,4,59,0,0,7,168,5,16,0,156,0,0,0,204,0,0,33,61],[0,0,0,0,6,18,0,73,0,0,0,32,5,64,0,57,0,0,7,169,4,0,0,65,0,0,0,0,7,101,0,75],[0,0,0,0,7,0,0,25,0,0,0,0,7,4,32,25,0,0,7,169,6,96,1,151,0,0,7,169,8,80,1,151],[0,0,0,0,9,104,0,75,0,0,0,0,4,0,128,25,0,0,0,0,6,104,1,63,0,0,7,169,6,96,0,156],[0,0,0,0,4,7,192,25,0,0,0,0,4,4,0,75,0,0,0,204,0,0,193,61,0,0,7,164,6,80,1,151],[0,0,0,0,4,0,4,20,0,1,0,0,0,99,3,85,0,0,0,0,5,81,0,25,0,0,0,0,1,21,0,75],[0,0,0,0,1,0,0,25,0,0,0,1,1,0,64,57,0,0,0,1,1,16,1,144,0,0,24,254,0,0,193,61],[0,0,0,0,1,82,0,75,0,0,24,254,0,0,65,61,0,0,0,0,1,99,3,79,0,0,0,0,2,82,0,73],[0,0,7,164,2,32,1,151,0,1,0,0,0,33,3,229,0,0,7,182,3,64,0,156,0,0,11,164,0,0,65,61],[0,0,0,64,4,0,4,61,0,0,2,252,0,0,1,61,0,0,0,64,7,64,0,57,0,0,0,64,0,112,4,63],[0,0,0,0,8,33,3,79,0,0,0,1,7,0,0,58,0,0,0,0,7,116,4,54,0,0,0,0,8,8,4,59],[0,0,0,0,0,135,4,53,0,0,5,120,0,0,193,61,0,0,7,201,1,0,0,65,0,0,0,0,0,16,4,53],[0,0,0,50,1,0,0,57,0,0,0,4,0,16,4,63,0,0,7,202,1,0,0,65,0,0,30,141,0,1,4,48],[0,0,7,172,8,80,0,156,0,0,4,10,0,0,33,61,0,0,0,64,8,80,0,57,0,0,0,64,0,128,4,63],[0,0,0,0,9,33,3,79,0,0,0,1,8,0,0,58,0,0,0,0,8,133,4,54,0,0,0,0,9,9,4,59],[0,0,0,0,0,152,4,53,0,0,4,250,0,0,97,61,0,0,0,248,10,112,2,16,0,0,7,169,11,0,0,65],[0,0,0,0,7,7,0,75,0,0,0,0,11,10,192,25,0,0,7,173,7,144,1,151,0,0,0,0,7,183,1,159],[0,0,0,0,0,120,4,53,0,0,0,64,7,0,4,61,0,0,0,64,6,96,0,138,0,0,0,0,8,97,3,79],[0,0,0,0,8,8,4,59,0,0,0,128,9,128,0,140,0,0,6,128,0,0,65,61,0,0,0,128,9,128,2,112],[0,0,7,174,10,128,0,156,0,0,0,0,9,8,160,25,0,0,7,174,10,128,0,156,0,0,0,0,10,0,0,25],[0,0,0,16,10,0,32,57,0,0,0,8,11,160,1,191,0,0,7,168,12,144,0,156,0,0,0,0,11,10,160,25],[0,0,0,64,10,144,2,112,0,0,7,168,12,144,0,156,0,0,0,0,10,9,160,25,0,0,0,4,12,176,1,191],[0,0,7,164,9,160,0,156,0,0,0,0,12,11,160,25,0,0,0,32,11,160,2,112,0,0,7,164,9,160,0,156],[0,0,0,0,11,10,160,25,0,0,0,2,9,192,1,191,0,0,255,255,10,176,0,140,0,0,0,0,9,12,160,25],[0,0,0,16,10,176,2,112,0,0,0,0,10,11,160,25,0,0,0,255,10,160,0,140,0,0,0,1,9,144,32,57],[0,0,0,32,10,0,0,138,0,0,0,65,11,144,0,57,0,0,0,0,10,171,1,111,0,0,0,0,10,167,0,25],[0,0,0,0,11,122,0,75,0,0,0,0,11,0,0,25,0,0,0,1,11,0,64,57,0,0,7,168,12,160,0,156],[0,0,4,10,0,0,33,61,0,0,0,1,11,176,1,144,0,0,4,10,0,0,193,61,0,0,0,64,0,160,4,63],[0,0,0,2,10,144,0,57,0,0,0,0,10,167,4,54,0,0,0,33,11,144,0,57,0,0,0,5,11,176,2,114],[0,0,5,75,0,0,97,61,0,0,0,0,12,33,3,79,0,0,0,0,13,0,0,25,0,0,0,5,14,208,2,16],[0,0,0,0,15,234,0,25,0,0,0,0,14,236,3,79,0,0,0,0,14,14,4,59,0,0,0,0,0,239,4,53],[0,0,0,1,13,208,0,57,0,0,0,0,14,189,0,75,0,0,5,67,0,0,65,61,0,0,0,0,11,0,0,75],[0,0,5,77,0,0,97,61,0,0,0,0,11,7,4,51,0,0,0,0,11,11,0,75,0,0,4,250,0,0,97,61],[0,0,0,0,11,10,4,51,0,0,7,173,11,176,1,151,0,0,0,248,12,144,2,16,0,0,0,0,11,188,1,159],[0,0,7,175,11,176,0,65,0,0,0,0,0,186,4,53,0,0,0,3,9,144,2,16,0,0,0,248,9,144,0,137],[0,0,0,0,8,152,1,207,0,0,0,255,9,144,0,140,0,0,0,0,8,0,32,25,0,0,0,33,9,112,0,57],[0,0,6,144,0,0,1,61,0,0,0,31,3,80,1,143,0,0,0,5,2,80,2,114,0,0,5,104,0,0,97,61],[0,0,0,0,4,0,0,25,0,0,0,5,6,64,2,16,0,0,0,0,7,97,3,79,0,0,0,0,7,7,4,59],[0,0,0,0,0,118,4,53,0,0,0,1,4,64,0,57,0,0,0,0,6,36,0,75,0,0,5,97,0,0,65,61],[0,0,0,0,4,3,0,75,0,0,5,118,0,0,97,61,0,0,0,3,3,48,2,16,0,0,0,5,2,32,2,16],[0,0,0,0,4,2,4,51,0,0,0,0,4,52,1,207,0,0,0,0,4,52,2,47,0,0,0,0,1,33,3,79],[0,0,0,0,1,1,4,59,0,0,1,0,3,48,0,137,0,0,0,0,1,49,2,47,0,0,0,0,1,49,1,207],[0,0,0,0,1,65,1,159,0,0,0,0,0,18,4,53,0,0,0,96,1,80,2,16,0,0,30,141,0,1,4,48],[0,0,0,248,9,80,2,16,0,0,7,169,10,0,0,65,0,0,0,0,5,5,0,75,0,0,0,0,10,9,192,25],[0,0,7,173,5,128,1,151,0,0,0,0,5,165,1,159,0,0,0,0,0,87,4,53,0,0,0,64,5,0,4,61],[0,0,0,64,7,96,0,138,0,0,0,0,6,113,3,79,0,0,0,0,6,6,4,59,0,0,0,128,8,96,0,140],[0,0,5,203,0,0,65,61,0,0,0,128,8,96,2,112,0,0,7,174,9,96,0,156,0,0,0,0,8,6,160,25],[0,0,7,174,9,96,0,156,0,0,0,0,9,0,0,25,0,0,0,16,9,0,32,57,0,0,0,8,10,144,1,191],[0,0,7,168,11,128,0,156,0,0,0,0,10,9,160,25,0,0,0,64,9,128,2,112,0,0,7,168,11,128,0,156],[0,0,0,0,9,8,160,25,0,0,0,4,11,160,1,191,0,0,7,164,8,144,0,156,0,0,0,0,11,10,160,25],[0,0,0,32,10,144,2,112,0,0,7,164,8,144,0,156,0,0,0,0,10,9,160,25,0,0,0,2,8,176,1,191],[0,0,255,255,9,160,0,140,0,0,0,0,8,11,160,25,0,0,0,16,9,160,2,112,0,0,0,0,9,10,160,25],[0,0,0,255,9,144,0,140,0,0,0,1,8,128,32,57,0,0,0,32,9,0,0,138,0,0,0,65,10,128,0,57],[0,0,0,0,9,154,1,111,0,0,0,0,9,149,0,25,0,0,0,0,10,89,0,75,0,0,0,0,10,0,0,25],[0,0,0,1,10,0,64,57,0,0,7,168,11,144,0,156,0,0,4,10,0,0,33,61,0,0,0,1,10,160,1,144],[0,0,4,10,0,0,193,61,0,0,0,64,0,144,4,63,0,0,0,2,9,128,0,57,0,0,0,0,9,149,4,54],[0,0,0,33,10,128,0,57,0,0,0,5,10,160,2,114,0,0,5,185,0,0,97,61,0,0,0,0,11,33,3,79],[0,0,0,0,12,0,0,25,0,0,0,5,13,192,2,16,0,0,0,0,14,217,0,25,0,0,0,0,13,219,3,79],[0,0,0,0,13,13,4,59,0,0,0,0,0,222,4,53,0,0,0,1,12,192,0,57,0,0,0,0,13,172,0,75],[0,0,5,177,0,0,65,61,0,0,0,0,10,0,0,75,0,0,5,187,0,0,97,61,0,0,0,0,10,5,4,51],[0,0,0,0,10,10,0,75,0,0,4,250,0,0,97,61,0,0,0,0,10,9,4,51,0,0,7,173,10,160,1,151],[0,0,0,248,11,128,2,16,0,0,0,0,10,171,1,159,0,0,7,175,10,160,0,65,0,0,0,0,0,169,4,53],[0,0,0,3,8,128,2,16,0,0,0,248,8,128,0,137,0,0,0,0,6,134,1,207,0,0,0,255,8,128,0,140],[0,0,0,0,6,0,32,25,0,0,0,33,8,80,0,57,0,0,5,219,0,0,1,61,0,0,7,172,8,80,0,156],[0,0,4,10,0,0,33,61,0,0,0,64,8,80,0,57,0,0,0,64,0,128,4,63,0,0,0,0,9,33,3,79],[0,0,0,1,8,0,0,58,0,0,0,0,8,133,4,54,0,0,0,0,9,9,4,59,0,0,0,0,0,152,4,53],[0,0,4,250,0,0,97,61,0,0,0,248,10,96,2,16,0,0,7,169,11,0,0,65,0,0,0,0,6,6,0,75],[0,0,0,0,11,10,192,25,0,0,7,173,6,144,1,151,0,0,0,0,6,182,1,159,0,0,0,0,0,104,4,53],[0,0,0,64,6,0,4,61,0,0,0,32,7,112,0,138,0,0,0,0,8,113,3,79,0,0,0,0,8,8,4,59],[0,0,0,128,9,128,0,140,0,0,6,240,0,0,65,61,0,0,0,128,9,128,2,112,0,0,7,174,10,128,0,156],[0,0,0,0,9,8,160,25,0,0,7,174,10,128,0,156,0,0,0,0,10,0,0,25,0,0,0,16,10,0,32,57],[0,0,0,8,11,160,1,191,0,0,7,168,12,144,0,156,0,0,0,0,11,10,160,25,0,0,0,64,10,144,2,112],[0,0,7,168,12,144,0,156,0,0,0,0,10,9,160,25,0,0,0,4,12,176,1,191,0,0,7,164,9,160,0,156],[0,0,0,0,12,11,160,25,0,0,0,32,11,160,2,112,0,0,7,164,9,160,0,156,0,0,0,0,11,10,160,25],[0,0,0,2,9,192,1,191,0,0,255,255,10,176,0,140,0,0,0,0,9,12,160,25,0,0,0,16,10,176,2,112],[0,0,0,0,10,11,160,25,0,0,0,255,10,160,0,140,0,0,0,1,9,144,32,57,0,0,0,32,10,0,0,138],[0,0,0,65,11,144,0,57,0,0,0,0,10,171,1,111,0,0,0,0,10,166,0,25,0,0,0,0,11,106,0,75],[0,0,0,0,11,0,0,25,0,0,0,1,11,0,64,57,0,0,7,168,12,160,0,156,0,0,4,10,0,0,33,61],[0,0,0,1,11,176,1,144,0,0,4,10,0,0,193,61,0,0,0,64,0,160,4,63,0,0,0,2,10,144,0,57],[0,0,0,0,10,166,4,54,0,0,0,33,11,144,0,57,0,0,0,5,11,176,2,114,0,0,6,22,0,0,97,61],[0,0,0,0,12,33,3,79,0,0,0,0,13,0,0,25,0,0,0,5,14,208,2,16,0,0,0,0,15,234,0,25],[0,0,0,0,14,236,3,79,0,0,0,0,14,14,4,59,0,0,0,0,0,239,4,53,0,0,0,1,13,208,0,57],[0,0,0,0,14,189,0,75,0,0,6,14,0,0,65,61,0,0,0,0,11,0,0,75,0,0,6,24,0,0,97,61],[0,0,0,0,11,6,4,51,0,0,0,0,11,11,0,75,0,0,4,250,0,0,97,61,0,0,0,0,11,10,4,51],[0,0,7,173,11,176,1,151,0,0,0,248,12,144,2,16,0,0,0,0,11,188,1,159,0,0,7,175,11,176,0,65],[0,0,0,0,0,186,4,53,0,0,0,3,9,144,2,16,0,0,0,248,9,144,0,137,0,0,0,0,8,152,1,207],[0,0,0,255,9,144,0,140,0,0,0,0,8,0,32,25,0,0,0,33,9,96,0,57,0,0,7,0,0,0,1,61],[0,0,0,7,6,0,0,41,0,0,7,172,6,96,0,156,0,0,4,10,0,0,33,61,0,0,0,7,7,0,0,41],[0,0,0,64,6,112,0,57,0,0,0,64,0,96,4,63,0,0,0,1,6,0,0,58,0,0,0,0,6,103,4,54],[0,0,0,0,7,2,4,59,0,0,0,0,0,118,4,53,0,0,4,250,0,0,97,61,0,0,0,248,8,80,2,16],[0,0,7,169,9,0,0,65,0,0,0,0,5,5,0,75,0,0,0,0,9,8,192,25,0,0,7,173,5,112,1,151],[0,0,0,0,5,149,1,159,0,0,0,0,0,86,4,53,0,0,0,11,11,0,0,41,0,0,0,0,5,179,0,73],[0,0,0,160,6,64,0,57,0,0,0,0,4,97,3,79,0,0,0,0,4,4,4,59,0,0,0,31,5,80,0,138],[0,0,7,169,7,80,1,151,0,0,7,169,8,64,1,151,0,0,7,169,9,0,0,65,0,0,0,0,10,120,0,75],[0,0,0,0,10,0,0,25,0,0,0,0,10,9,64,25,0,0,0,0,7,120,1,63,0,0,0,0,8,84,0,75],[0,0,0,0,9,0,64,25,0,0,7,169,7,112,0,156,0,0,0,0,10,9,192,25,0,0,0,0,7,10,0,75],[0,0,0,204,0,0,193,61,0,0,0,0,8,180,0,25,0,0,0,0,7,129,3,79,0,0,0,0,7,7,4,59],[0,0,7,168,9,112,0,156,0,0,0,204,0,0,33,61,0,0,0,0,9,115,0,73,0,0,0,32,8,128,0,57],[0,0,7,169,10,0,0,65,0,0,0,0,11,152,0,75,0,0,0,0,11,0,0,25,0,0,0,0,11,10,32,25],[0,0,7,169,9,144,1,151,0,0,7,169,12,128,1,151,0,0,0,0,13,156,0,75,0,0,0,0,10,0,128,25],[0,0,0,0,9,156,1,63,0,0,7,169,9,144,0,156,0,0,0,0,10,11,192,25,0,0,0,0,9,10,0,75],[0,0,0,204,0,0,193,61,0,0,0,1,9,112,0,140,0,0,8,120,0,0,193,61,0,0,0,0,2,129,3,79],[0,0,0,0,2,2,4,59,0,0,0,1,7,0,0,138,0,0,7,169,8,0,0,65,0,0,0,0,7,114,0,75],[0,0,0,0,7,0,0,25,0,0,0,0,7,8,32,25,0,0,7,169,2,32,1,151,0,0,7,169,9,32,0,156],[0,0,0,0,8,0,128,25,0,0,7,169,2,32,1,103,0,0,7,169,2,32,0,156,0,0,0,0,8,7,192,25],[0,6,0,96,0,0,0,61,0,0,0,0,2,8,0,75,0,0,9,117,0,0,193,61,0,0,0,64,2,0,4,61],[0,6,0,0,0,2,0,29,0,0,7,172,2,32,0,156,0,0,4,10,0,0,33,61,0,0,0,6,8,0,0,41],[0,0,0,64,2,128,0,57,0,0,0,64,0,32,4,63,0,0,0,32,2,128,0,57,0,0,7,175,7,0,0,65],[0,0,0,0,0,114,4,53,0,0,0,1,2,0,0,57,0,0,0,0,0,40,4,53,0,0,9,117,0,0,1,61],[0,0,7,172,9,112,0,156,0,0,4,10,0,0,33,61,0,0,0,64,9,112,0,57,0,0,0,64,0,144,4,63],[0,0,0,0,10,33,3,79,0,0,0,1,9,0,0,58,0,0,0,0,9,151,4,54,0,0,0,0,10,10,4,59],[0,0,0,0,0,169,4,53,0,0,4,250,0,0,97,61,0,0,0,248,11,128,2,16,0,0,7,169,12,0,0,65],[0,0,0,0,8,8,0,75,0,0,0,0,12,11,192,25,0,0,7,173,8,160,1,151,0,0,0,0,8,200,1,159],[0,0,0,0,0,137,4,53,0,0,0,64,9,0,4,61,0,0,7,172,8,144,0,156,0,0,4,10,0,0,33,61],[0,0,0,32,8,96,0,138,0,0,0,0,8,129,3,79,0,0,0,0,8,8,4,59,0,0,0,64,10,144,0,57],[0,0,0,64,0,160,4,63,0,0,0,32,10,144,0,57,0,0,7,176,11,0,0,65,0,0,0,0,0,186,4,53],[0,0,0,21,10,0,0,57,0,0,0,0,0,169,4,53,0,0,0,96,8,128,2,16,0,0,0,33,10,144,0,57],[0,0,0,0,0,138,4,53,0,0,0,192,6,96,0,57,0,0,0,0,6,97,3,79,0,0,0,64,8,0,4,61],[0,0,0,0,6,6,4,59,0,10,0,0,0,6,0,29,0,0,0,128,10,96,0,140,0,0,7,194,0,0,65,61],[0,0,0,10,6,0,0,41,0,0,0,128,10,96,2,112,0,0,7,174,11,96,0,156,0,0,0,0,10,6,160,25],[0,0,7,174,11,96,0,156,0,0,0,0,11,0,0,25,0,0,0,16,11,0,32,57,0,0,0,8,12,176,1,191],[0,0,7,168,13,160,0,156,0,0,0,0,12,11,160,25,0,0,0,64,11,160,2,112,0,0,7,168,13,160,0,156],[0,0,0,0,11,10,160,25,0,0,0,4,13,192,1,191,0,0,7,164,10,176,0,156,0,0,0,0,13,12,160,25],[0,0,0,32,12,176,2,112,0,0,7,164,10,176,0,156,0,0,0,0,12,11,160,25,0,0,0,2,10,208,1,191],[0,0,255,255,11,192,0,140,0,0,0,0,10,13,160,25,0,0,0,16,11,192,2,112,0,0,0,0,11,12,160,25],[0,0,0,255,11,176,0,140,0,0,0,1,10,160,32,57,0,0,0,32,11,0,0,138,0,0,0,65,12,160,0,57],[0,0,0,0,11,188,1,111,0,0,0,0,11,184,0,25,0,0,0,0,12,139,0,75,0,0,0,0,12,0,0,25],[0,0,0,1,12,0,64,57,0,0,7,168,13,176,0,156,0,0,4,10,0,0,33,61,0,0,0,1,12,192,1,144],[0,0,4,10,0,0,193,61,0,0,0,64,0,176,4,63,0,0,0,2,11,160,0,57,0,0,0,0,11,184,4,54],[0,0,0,33,12,160,0,57,0,0,0,5,12,192,2,114,0,0,6,221,0,0,97,61,0,0,0,0,13,33,3,79],[0,0,0,0,14,0,0,25,0,0,0,5,15,224,2,16,0,0,0,0,6,251,0,25,0,0,0,0,15,253,3,79],[0,0,0,0,15,15,4,59,0,0,0,0,0,246,4,53,0,0,0,1,14,224,0,57,0,0,0,0,6,206,0,75],[0,0,6,213,0,0,65,61,0,0,0,0,6,0,0,75,0,0,6,223,0,0,97,61,0,0,0,0,6,8,4,51],[0,0,0,0,6,6,0,75,0,0,4,250,0,0,97,61,0,0,0,0,6,11,4,51,0,0,7,173,6,96,1,151],[0,0,0,248,12,160,2,16,0,0,0,0,6,108,1,159,0,0,7,175,6,96,0,65,0,0,0,0,0,107,4,53],[0,0,0,3,6,160,2,16,0,0,0,248,6,96,0,137,0,0,0,10,10,96,1,239,0,0,0,255,6,96,0,140],[0,0,0,0,10,0,32,25,0,0,0,33,6,128,0,57,0,0,0,0,0,166,4,53,0,0,7,212,0,0,1,61],[0,0,7,172,9,96,0,156,0,0,4,10,0,0,33,61,0,0,0,64,9,96,0,57,0,0,0,64,0,144,4,63],[0,0,0,0,10,33,3,79,0,0,0,1,9,0,0,58,0,0,0,0,9,150,4,54,0,0,0,0,10,10,4,59],[0,0,0,0,0,169,4,53,0,0,4,250,0,0,97,61,0,0,0,248,11,128,2,16,0,0,7,169,12,0,0,65],[0,0,0,0,8,8,0,75,0,0,0,0,12,11,192,25,0,0,7,173,8,160,1,151,0,0,0,0,8,200,1,159],[0,0,0,0,0,137,4,53,0,0,0,64,8,0,4,61,0,10,0,64,0,112,0,146,0,0,0,10,9,16,3,96],[0,0,0,0,9,9,4,59,0,0,0,128,10,144,0,140,0,0,7,78,0,0,65,61,0,0,0,128,10,144,2,112],[0,0,7,174,11,144,0,156,0,0,0,0,10,9,160,25,0,0,7,174,11,144,0,156,0,0,0,0,11,0,0,25],[0,0,0,16,11,0,32,57,0,0,0,8,12,176,1,191,0,0,7,168,13,160,0,156,0,0,0,0,12,11,160,25],[0,0,0,64,11,160,2,112,0,0,7,168,13,160,0,156,0,0,0,0,11,10,160,25,0,0,0,4,13,192,1,191],[0,0,7,164,10,176,0,156,0,0,0,0,13,12,160,25,0,0,0,32,12,176,2,112,0,0,7,164,10,176,0,156],[0,0,0,0,12,11,160,25,0,0,0,2,10,208,1,191,0,0,255,255,11,192,0,140,0,0,0,0,10,13,160,25],[0,0,0,16,11,192,2,112,0,0,0,0,11,12,160,25,0,0,0,255,11,176,0,140,0,0,0,1,10,160,32,57],[0,0,0,32,11,0,0,138,0,0,0,65,12,160,0,57,0,0,0,0,11,188,1,111,0,0,0,0,11,184,0,25],[0,0,0,0,12,139,0,75,0,0,0,0,12,0,0,25,0,0,0,1,12,0,64,57,0,0,7,168,13,176,0,156],[0,0,4,10,0,0,33,61,0,0,0,1,12,192,1,144,0,0,4,10,0,0,193,61,0,0,0,64,0,176,4,63],[0,0,0,2,11,160,0,57,0,0,0,0,11,184,4,54,0,0,0,33,12,160,0,57,0,0,0,5,12,192,2,114],[0,0,7,59,0,0,97,61,0,0,0,0,13,33,3,79,0,0,0,0,14,0,0,25,0,0,0,5,15,224,2,16],[0,0,0,0,7,251,0,25,0,0,0,0,15,253,3,79,0,0,0,0,15,15,4,59,0,0,0,0,0,247,4,53],[0,0,0,1,14,224,0,57,0,0,0,0,7,206,0,75,0,0,7,51,0,0,65,61,0,0,0,0,7,0,0,75],[0,0,7,61,0,0,97,61,0,0,0,0,7,8,4,51,0,0,0,0,7,7,0,75,0,0,4,250,0,0,97,61],[0,0,0,0,7,11,4,51,0,0,7,173,7,112,1,151,0,0,0,248,12,160,2,16,0,0,0,0,7,124,1,159],[0,0,7,175,7,112,0,65,0,0,0,0,0,123,4,53,0,0,0,3,7,160,2,16,0,0,0,248,7,112,0,137],[0,0,0,0,9,121,1,207,0,0,0,255,7,112,0,140,0,0,0,0,9,0,32,25,0,0,0,33,7,128,0,57],[0,0,0,0,0,151,4,53,0,0,7,95,0,0,1,61,0,0,7,172,7,128,0,156,0,0,4,10,0,0,33,61],[0,0,0,64,7,128,0,57,0,0,0,64,0,112,4,63,0,0,0,0,7,33,3,79,0,0,0,1,10,0,0,58],[0,0,0,0,10,168,4,54,0,0,0,0,11,7,4,59,0,0,0,0,0,186,4,53,0,0,4,250,0,0,97,61],[0,0,0,248,7,144,2,16,0,0,7,169,12,0,0,65,0,0,0,0,9,9,0,75,0,0,0,0,12,7,192,25],[0,0,7,173,7,176,1,151,0,0,0,0,7,199,1,159,0,0,0,0,0,122,4,53,0,0,0,64,10,0,4,61],[0,0,7,172,7,160,0,156,0,0,4,10,0,0,33,61,0,0,0,10,12,0,0,41,0,0,0,32,7,192,0,138],[0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,64,9,160,0,57,0,0,0,64,0,144,4,63],[0,0,0,32,9,160,0,57,0,0,7,176,11,0,0,65,0,0,0,0,0,185,4,53,0,0,0,21,9,0,0,57],[0,0,0,0,0,154,4,53,0,0,0,96,7,112,2,16,0,0,0,33,9,160,0,57,0,0,0,0,0,121,4,53],[0,0,0,192,7,192,0,57,0,0,0,0,7,113,3,79,0,0,0,64,9,0,4,61,0,0,0,0,7,7,4,59],[0,10,0,0,0,7,0,29,0,0,0,128,11,112,0,140,0,0,8,162,0,0,65,61,0,0,0,10,7,0,0,41],[0,0,0,128,11,112,2,112,0,0,7,174,12,112,0,156,0,0,0,0,11,7,160,25,0,0,7,174,12,112,0,156],[0,0,0,0,12,0,0,25,0,0,0,16,12,0,32,57,0,0,0,8,13,192,1,191,0,0,7,168,14,176,0,156],[0,0,0,0,13,12,160,25,0,0,0,64,12,176,2,112,0,0,7,168,14,176,0,156,0,0,0,0,12,11,160,25],[0,0,0,4,14,208,1,191,0,0,7,164,11,192,0,156,0,0,0,0,14,13,160,25,0,0,0,32,13,192,2,112],[0,0,7,164,11,192,0,156,0,0,0,0,13,12,160,25,0,0,0,2,7,224,1,191,0,0,255,255,12,208,0,140],[0,0,0,0,7,14,160,25,0,0,0,16,12,208,2,112,0,0,0,0,12,13,160,25,0,0,0,255,12,192,0,140],[0,0,0,1,7,112,32,57,0,0,0,32,12,0,0,138,0,9,0,0,0,7,0,29,0,0,0,65,13,112,0,57],[0,0,0,0,12,205,1,111,0,0,0,0,12,201,0,25,0,0,0,0,13,156,0,75,0,0,0,0,13,0,0,25],[0,0,0,1,13,0,64,57,0,0,7,168,14,192,0,156,0,0,4,10,0,0,33,61,0,0,0,1,13,208,1,144],[0,0,4,10,0,0,193,61,0,0,0,64,0,192,4,63,0,0,0,9,7,0,0,41,0,0,0,2,12,112,0,57],[0,0,0,0,12,201,4,54,0,0,0,33,13,112,0,57,0,0,0,5,13,208,2,114,0,0,7,174,0,0,97,61],[0,0,0,0,14,33,3,79,0,0,0,0,15,0,0,25,0,0,0,5,7,240,2,16,0,0,0,0,11,124,0,25],[0,0,0,0,7,126,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,123,4,53,0,0,0,1,15,240,0,57],[0,0,0,0,7,223,0,75,0,0,7,166,0,0,65,61,0,0,0,0,7,0,0,75,0,0,7,176,0,0,97,61],[0,0,0,0,7,9,4,51,0,0,0,0,7,7,0,75,0,0,4,250,0,0,97,61,0,0,0,0,7,12,4,51],[0,0,7,173,7,112,1,151,0,0,0,9,13,0,0,41,0,0,0,248,11,208,2,16,0,0,0,0,7,123,1,159],[0,0,7,175,7,112,0,65,0,0,0,0,0,124,4,53,0,0,0,3,7,208,2,16,0,0,0,248,7,112,0,137],[0,0,0,10,11,112,1,239,0,0,0,255,7,112,0,140,0,0,0,0,11,0,32,25,0,0,0,33,7,144,0,57],[0,0,0,0,0,183,4,53,0,0,8,180,0,0,1,61,0,0,7,172,6,128,0,156,0,0,4,10,0,0,33,61],[0,0,0,64,6,128,0,57,0,0,0,64,0,96,4,63,0,0,0,0,6,33,3,79,0,0,0,1,10,0,0,58],[0,0,0,0,10,168,4,54,0,0,0,0,11,6,4,59,0,0,0,0,0,186,4,53,0,0,4,250,0,0,97,61],[0,0,0,10,13,0,0,41,0,0,0,248,6,208,2,16,0,0,7,169,12,0,0,65,0,0,0,0,13,13,0,75],[0,0,0,0,12,6,192,25,0,0,7,173,6,176,1,151,0,0,0,0,6,198,1,159,0,0,0,0,0,106,4,53],[0,0,0,64,6,0,4,61,0,0,0,32,10,96,0,57,0,0,0,0,11,3,4,51,0,0,0,0,12,11,0,75],[0,0,7,225,0,0,97,61,0,0,0,0,12,0,0,25,0,0,0,0,13,172,0,25,0,0,0,32,12,192,0,57],[0,0,0,0,14,60,0,25,0,0,0,0,14,14,4,51,0,0,0,0,0,237,4,53,0,0,0,0,13,188,0,75],[0,0,7,218,0,0,65,61,0,0,0,0,3,171,0,25,0,0,0,0,0,3,4,53,0,0,0,0,10,4,4,51],[0,0,0,0,11,10,0,75,0,0,7,238,0,0,97,61,0,0,0,0,11,0,0,25,0,0,0,0,12,59,0,25],[0,0,0,32,11,176,0,57,0,0,0,0,13,75,0,25,0,0,0,0,13,13,4,51,0,0,0,0,0,220,4,53],[0,0,0,0,12,171,0,75,0,0,7,231,0,0,65,61,0,0,0,0,3,58,0,25,0,0,0,0,0,3,4,53],[0,0,0,0,4,5,4,51,0,0,0,0,10,4,0,75,0,0,7,251,0,0,97,61,0,0,0,0,10,0,0,25],[0,0,0,0,11,58,0,25,0,0,0,32,10,160,0,57,0,0,0,0,12,90,0,25,0,0,0,0,12,12,4,51],[0,0,0,0,0,203,4,53,0,0,0,0,11,74,0,75,0,0,7,244,0,0,65,61,0,0,0,0,3,52,0,25],[0,0,0,0,0,3,4,53,0,0,0,0,4,7,4,51,0,0,0,0,5,4,0,75,0,0,8,8,0,0,97,61],[0,0,0,0,5,0,0,25,0,0,0,0,10,53,0,25,0,0,0,32,5,80,0,57,0,0,0,0,11,117,0,25],[0,0,0,0,11,11,4,51,0,0,0,0,0,186,4,53,0,0,0,0,10,69,0,75,0,0,8,1,0,0,65,61],[0,0,0,0,3,52,0,25,0,0,0,0,0,3,4,53,0,0,0,0,4,9,4,51,0,0,0,0,5,4,0,75],[0,0,8,21,0,0,97,61,0,0,0,0,5,0,0,25,0,0,0,0,7,53,0,25,0,0,0,32,5,80,0,57],[0,0,0,0,10,149,0,25,0,0,0,0,10,10,4,51,0,0,0,0,0,167,4,53,0,0,0,0,7,69,0,75],[0,0,8,14,0,0,65,61,0,0,0,0,3,52,0,25,0,0,0,0,0,3,4,53,0,0,0,0,4,8,4,51],[0,0,0,0,5,4,0,75,0,0,8,34,0,0,97,61,0,0,0,0,5,0,0,25,0,0,0,0,7,53,0,25],[0,0,0,32,5,80,0,57,0,0,0,0,9,133,0,25,0,0,0,0,9,9,4,51,0,0,0,0,0,151,4,53],[0,0,0,0,7,69,0,75,0,0,8,27,0,0,65,61,0,0,0,0,3,52,0,25,0,0,0,0,0,3,4,53],[0,0,0,0,3,99,0,73,0,0,0,32,4,48,0,138,0,0,0,0,0,70,4,53,0,0,0,31,4,48,0,57],[0,0,0,32,3,0,0,138,0,0,0,0,4,52,1,111,0,0,0,0,7,100,0,25,0,0,0,0,4,71,0,75],[0,0,0,0,4,0,0,25,0,0,0,1,4,0,64,57,0,0,7,168,5,112,0,156,0,0,4,10,0,0,33,61],[0,0,0,1,4,64,1,144,0,0,4,10,0,0,193,61,0,0,0,64,0,112,4,63,0,0,0,12,5,0,0,41],[0,0,1,196,4,80,0,57,0,0,0,0,4,65,3,79,0,0,0,0,5,82,0,73,0,0,0,35,5,80,0,138],[0,0,0,0,4,4,4,59,0,0,7,169,8,0,0,65,0,0,0,0,9,84,0,75,0,0,0,0,9,0,0,25],[0,0,0,0,9,8,128,25,0,0,7,169,5,80,1,151,0,0,7,169,10,64,1,151,0,0,0,0,11,90,0,75],[0,0,0,0,8,0,128,25,0,0,0,0,5,90,1,63,0,0,7,169,5,80,0,156,0,0,0,0,8,9,192,25],[0,0,0,0,5,8,0,75,0,0,0,11,5,0,0,41,0,0,0,204,0,0,193,61,0,0,0,0,5,84,0,25],[0,0,0,0,4,81,3,79,0,0,0,0,4,4,4,59,0,0,7,168,8,64,0,156,0,0,0,204,0,0,33,61],[0,0,0,0,8,66,0,73,0,0,0,32,5,80,0,57,0,0,7,169,9,0,0,65,0,0,0,0,10,133,0,75],[0,0,0,0,10,0,0,25,0,0,0,0,10,9,32,25,0,0,7,169,8,128,1,151,0,0,7,169,11,80,1,151],[0,0,0,0,12,139,0,75,0,0,0,0,9,0,128,25,0,0,0,0,8,139,1,63,0,0,7,169,8,128,0,156],[0,0,0,0,9,10,192,25,0,0,0,0,8,9,0,75,0,0,0,204,0,0,193,61,0,0,0,1,8,64,0,140],[0,0,10,100,0,0,193,61,0,0,0,0,8,81,3,79,0,0,0,0,8,8,4,59,0,0,0,1,9,0,0,138],[0,0,7,169,10,0,0,65,0,0,0,0,9,152,0,75,0,0,0,0,9,0,0,25,0,0,0,0,9,10,32,25],[0,0,7,169,8,128,1,151,0,0,7,169,11,128,0,156,0,0,0,0,10,0,128,25,0,0,7,169,8,128,1,103],[0,0,7,169,8,128,0,156,0,0,0,0,10,9,192,25,0,0,0,96,8,0,0,57,0,0,0,0,9,10,0,75],[0,0,12,187,0,0,193,61,0,0,7,172,8,112,0,156,0,0,4,10,0,0,33,61,0,0,0,64,8,112,0,57],[0,0,0,64,0,128,4,63,0,0,0,32,8,112,0,57,0,0,7,175,9,0,0,65,0,0,0,0,0,152,4,53],[0,0,0,1,8,0,0,57,0,0,0,0,0,135,4,53,0,0,0,0,8,7,0,25,0,0,12,187,0,0,1,61],[0,0,0,64,8,0,4,61,0,6,0,0,0,8,0,29,0,0,0,56,8,112,0,140,0,0,9,101,0,0,65,61],[0,0,0,32,9,112,2,112,0,0,7,164,8,112,0,156,0,0,0,0,9,7,160,25,0,0,7,164,8,112,0,156],[0,0,0,0,10,0,0,25,0,0,0,4,10,0,32,57,0,0,0,2,8,160,1,191,0,0,255,255,11,144,0,140],[0,0,0,0,8,10,160,25,0,0,0,16,10,144,2,112,0,0,0,0,10,9,160,25,0,0,0,255,9,160,0,140],[0,0,0,0,9,0,0,25,0,0,0,1,9,0,32,57,0,0,0,6,10,0,0,41,0,0,7,172,10,160,0,156],[0,0,4,10,0,0,33,61,0,0,0,0,8,152,1,159,0,0,0,6,10,0,0,41,0,0,0,64,9,160,0,57],[0,0,0,64,0,144,4,63,0,0,0,2,9,128,0,58,0,0,0,0,9,154,4,54,0,0,0,0,2,2,4,59],[0,0,0,0,0,41,4,53,0,0,4,250,0,0,97,61,0,0,7,173,2,32,1,151,0,0,0,248,10,128,2,16],[0,0,0,0,2,42,1,159,0,0,7,177,2,32,1,199,0,0,0,0,0,41,4,53,0,0,0,3,2,128,2,16],[0,0,0,248,2,32,1,95,0,0,0,0,2,39,1,207,0,0,0,6,7,0,0,41,0,0,0,33,7,112,0,57],[0,0,0,0,0,39,4,53,0,0,9,117,0,0,1,61,0,0,7,172,7,144,0,156,0,0,4,10,0,0,33,61],[0,0,0,64,7,144,0,57,0,0,0,64,0,112,4,63,0,0,0,0,7,33,3,79,0,0,0,1,11,0,0,58],[0,0,0,0,11,185,4,54,0,0,0,0,12,7,4,59,0,0,0,0,0,203,4,53,0,0,4,250,0,0,97,61],[0,0,0,10,14,0,0,41,0,0,0,248,7,224,2,16,0,0,7,169,13,0,0,65,0,0,0,0,14,14,0,75],[0,0,0,0,13,7,192,25,0,0,7,173,7,192,1,151,0,0,0,0,7,215,1,159,0,0,0,0,0,123,4,53],[0,0,0,64,7,0,4,61,0,0,0,32,11,112,0,57,0,0,0,0,12,3,4,51,0,0,0,0,13,12,0,75],[0,0,8,193,0,0,97,61,0,0,0,0,13,0,0,25,0,0,0,0,14,189,0,25,0,0,0,32,13,208,0,57],[0,0,0,0,15,61,0,25,0,0,0,0,15,15,4,51,0,0,0,0,0,254,4,53,0,0,0,0,14,205,0,75],[0,0,8,186,0,0,65,61,0,0,0,0,3,188,0,25,0,0,0,0,0,3,4,53,0,0,0,0,11,4,4,51],[0,0,0,0,12,11,0,75,0,0,8,206,0,0,97,61,0,0,0,0,12,0,0,25,0,0,0,0,13,60,0,25],[0,0,0,32,12,192,0,57,0,0,0,0,14,76,0,25,0,0,0,0,14,14,4,51,0,0,0,0,0,237,4,53],[0,0,0,0,13,188,0,75,0,0,8,199,0,0,65,61,0,0,0,0,3,59,0,25,0,0,0,0,0,3,4,53],[0,0,0,0,4,5,4,51,0,0,0,0,11,4,0,75,0,0,8,219,0,0,97,61,0,0,0,0,11,0,0,25],[0,0,0,0,12,59,0,25,0,0,0,32,11,176,0,57,0,0,0,0,13,91,0,25,0,0,0,0,13,13,4,51],[0,0,0,0,0,220,4,53,0,0,0,0,12,75,0,75,0,0,8,212,0,0,65,61,0,0,0,0,3,52,0,25],[0,0,0,0,0,3,4,53,0,0,0,0,4,6,4,51,0,0,0,0,5,4,0,75,0,0,8,232,0,0,97,61],[0,0,0,0,5,0,0,25,0,0,0,0,11,53,0,25,0,0,0,32,5,80,0,57,0,0,0,0,12,101,0,25],[0,0,0,0,12,12,4,51,0,0,0,0,0,203,4,53,0,0,0,0,11,69,0,75,0,0,8,225,0,0,65,61],[0,0,0,0,3,52,0,25,0,0,0,0,0,3,4,53,0,0,0,0,4,8,4,51,0,0,0,0,5,4,0,75],[0,0,8,245,0,0,97,61,0,0,0,0,5,0,0,25,0,0,0,0,6,53,0,25,0,0,0,32,5,80,0,57],[0,0,0,0,11,133,0,25,0,0,0,0,11,11,4,51,0,0,0,0,0,182,4,53,0,0,0,0,6,69,0,75],[0,0,8,238,0,0,65,61,0,0,0,0,3,52,0,25,0,0,0,0,0,3,4,53,0,0,0,0,4,10,4,51],[0,0,0,0,5,4,0,75,0,0,9,2,0,0,97,61,0,0,0,0,5,0,0,25,0,0,0,0,6,53,0,25],[0,0,0,32,5,80,0,57,0,0,0,0,8,165,0,25,0,0,0,0,8,8,4,51,0,0,0,0,0,134,4,53],[0,0,0,0,6,69,0,75,0,0,8,251,0,0,65,61,0,0,0,0,3,52,0,25,0,0,0,0,0,3,4,53],[0,0,0,0,4,9,4,51,0,0,0,0,5,4,0,75,0,0,9,15,0,0,97,61,0,0,0,0,5,0,0,25],[0,0,0,0,6,53,0,25,0,0,0,32,5,80,0,57,0,0,0,0,8,149,0,25,0,0,0,0,8,8,4,51],[0,0,0,0,0,134,4,53,0,0,0,0,6,69,0,75,0,0,9,8,0,0,65,61,0,0,0,0,3,52,0,25],[0,0,0,0,0,3,4,53,0,0,0,0,3,115,0,73,0,0,0,32,4,48,0,138,0,0,0,0,0,71,4,53],[0,0,0,31,4,48,0,57,0,0,0,32,3,0,0,138,0,0,0,0,4,52,1,111,0,0,0,0,6,116,0,25],[0,0,0,0,4,70,0,75,0,0,0,0,4,0,0,25,0,0,0,1,4,0,64,57,0,0,7,168,5,96,0,156],[0,0,4,10,0,0,33,61,0,0,0,1,4,64,1,144,0,0,4,10,0,0,193,61,0,0,0,64,0,96,4,63],[0,0,0,12,5,0,0,41,0,0,1,196,4,80,0,57,0,0,0,0,4,65,3,79,0,0,0,0,5,82,0,73],[0,0,0,35,5,80,0,138,0,0,0,0,4,4,4,59,0,0,7,169,8,0,0,65,0,0,0,0,9,84,0,75],[0,0,0,0,9,0,0,25,0,0,0,0,9,8,128,25,0,0,7,169,5,80,1,151,0,0,7,169,10,64,1,151],[0,0,0,0,11,90,0,75,0,0,0,0,8,0,128,25,0,0,0,0,5,90,1,63,0,0,7,169,5,80,0,156],[0,0,0,0,8,9,192,25,0,0,0,0,5,8,0,75,0,0,0,11,5,0,0,41,0,0,0,204,0,0,193,61],[0,0,0,0,5,84,0,25,0,0,0,0,4,81,3,79,0,0,0,0,4,4,4,59,0,0,7,168,8,64,0,156],[0,0,0,204,0,0,33,61,0,0,0,0,8,66,0,73,0,0,0,32,5,80,0,57,0,0,7,169,9,0,0,65],[0,0,0,0,10,133,0,75,0,0,0,0,10,0,0,25,0,0,0,0,10,9,32,25,0,0,7,169,8,128,1,151],[0,0,7,169,11,80,1,151,0,0,0,0,12,139,0,75,0,0,0,0,9,0,128,25,0,0,0,0,8,139,1,63],[0,0,7,169,8,128,0,156,0,0,0,0,9,10,192,25,0,0,0,0,8,9,0,75,0,0,0,204,0,0,193,61],[0,0,0,1,8,64,0,140,0,0,12,245,0,0,193,61,0,0,0,0,8,81,3,79,0,0,0,0,8,8,4,59],[0,0,0,1,9,0,0,138,0,0,7,169,10,0,0,65,0,0,0,0,9,152,0,75,0,0,0,0,9,0,0,25],[0,0,0,0,9,10,32,25,0,0,7,169,8,128,1,151,0,0,7,169,11,128,0,156,0,0,0,0,10,0,128,25],[0,0,7,169,8,128,1,103,0,0,7,169,8,128,0,156,0,0,0,0,10,9,192,25,0,0,0,96,8,0,0,57],[0,0,0,0,9,10,0,75,0,0,13,196,0,0,193,61,0,0,7,172,8,96,0,156,0,0,4,10,0,0,33,61],[0,0,0,64,8,96,0,57,0,0,0,64,0,128,4,63,0,0,0,32,8,96,0,57,0,0,7,175,9,0,0,65],[0,0,0,0,0,152,4,53,0,0,0,1,8,0,0,57,0,0,0,0,0,134,4,53,0,0,0,0,8,6,0,25],[0,0,13,196,0,0,1,61,0,0,0,6,8,0,0,41,0,0,7,172,8,128,0,156,0,0,4,10,0,0,33,61],[0,0,0,6,9,0,0,41,0,0,0,64,8,144,0,57,0,0,0,64,0,128,4,63,0,0,0,1,8,0,0,58],[0,0,0,0,8,137,4,54,0,0,0,0,2,2,4,59,0,0,0,0,0,40,4,53,0,0,4,250,0,0,97,61],[0,0,0,248,7,112,2,16,0,0,7,173,2,32,1,151,0,0,0,0,2,114,1,159,0,0,7,169,2,32,1,103],[0,0,0,0,0,40,4,53,0,0,0,128,2,96,0,138,0,0,0,0,6,33,3,79,0,0,0,96,2,0,0,57],[0,0,0,0,6,6,4,59,0,0,0,0,6,6,0,75,0,0,9,213,0,0,193,61,0,0,7,169,6,0,0,65],[0,0,0,0,7,84,0,75,0,0,0,0,7,0,0,25,0,0,0,0,7,6,128,25,0,0,7,169,5,80,1,151],[0,0,7,169,8,64,1,151,0,0,0,0,9,88,0,75,0,0,0,0,6,0,128,25,0,0,0,0,5,88,1,63],[0,0,7,169,5,80,0,156,0,0,0,0,6,7,192,25,0,0,0,0,5,6,0,75,0,0,0,11,5,0,0,41],[0,0,0,204,0,0,193,61,0,0,0,10,6,0,0,41,0,0,0,0,6,6,4,51,0,0,0,128,7,0,4,61],[0,0,0,9,8,0,0,41,0,0,0,0,8,8,4,51,0,0,0,7,9,0,0,41,0,0,0,0,9,9,4,51],[0,0,0,6,10,0,0,41,0,0,0,0,10,10,4,51,0,0,0,0,5,84,0,25,0,0,0,0,4,81,3,79],[0,0,0,0,4,4,4,59,0,0,7,168,11,64,0,156,0,0,0,204,0,0,33,61,0,0,0,0,11,67,0,73],[0,0,0,32,5,80,0,57,0,0,7,169,12,0,0,65,0,0,0,0,13,181,0,75,0,0,0,0,13,0,0,25],[0,0,0,0,13,12,32,25,0,0,7,169,11,176,1,151,0,0,7,169,14,80,1,151,0,0,0,0,15,190,0,75],[0,0,0,0,12,0,128,25,0,0,0,0,11,190,1,63,0,0,7,169,11,176,0,156,0,0,0,0,12,13,192,25],[0,0,0,0,11,12,0,75,0,0,0,204,0,0,193,61,0,0,0,0,6,118,0,25,0,0,0,0,6,134,0,25],[0,0,0,0,6,150,0,25,0,0,0,0,6,166,0,25,0,0,0,0,6,70,0,25,0,0,0,0,7,2,4,51],[0,0,0,0,6,118,0,25,0,0,0,64,7,0,4,61,0,0,7,168,6,96,1,151,0,0,0,56,8,96,0,140],[0,0,10,139,0,0,65,61,0,0,0,32,9,96,2,112,0,0,7,164,8,96,0,156,0,0,0,0,9,6,160,25],[0,0,7,164,8,96,0,156,0,0,0,0,10,0,0,25,0,0,0,4,10,0,32,57,0,0,0,2,8,160,1,191],[0,0,255,255,11,144,0,140,0,0,0,0,8,10,160,25,0,0,0,16,10,144,2,112,0,0,0,0,10,9,160,25],[0,0,0,255,9,160,0,140,0,0,0,0,9,0,0,25,0,0,0,1,9,0,32,57,0,0,7,172,10,112,0,156],[0,0,4,10,0,0,33,61,0,0,0,0,8,152,1,159,0,0,0,64,9,112,0,57,0,0,0,64,0,144,4,63],[0,0,0,0,9,49,3,79,0,0,0,2,3,128,0,58,0,0,0,0,3,55,4,54,0,0,0,0,9,9,4,59],[0,0,0,0,0,147,4,53,0,0,4,250,0,0,97,61,0,0,7,173,9,144,1,151,0,0,0,248,10,128,2,16],[0,0,0,0,9,154,1,159,0,0,7,179,9,144,1,199,0,0,0,0,0,147,4,53,0,0,0,3,3,128,2,16],[0,0,0,248,3,48,1,95,0,0,0,0,3,54,1,207,0,0,0,33,6,112,0,57,0,0,0,0,0,54,4,53],[0,0,10,154,0,0,1,61,0,0,7,170,1,0,0,65,0,0,0,0,0,16,4,57,0,0,7,164,1,0,0,65],[0,0,0,0,2,0,4,20,0,0,7,164,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16],[0,0,7,171,1,16,1,199,0,0,128,11,2,0,0,57,30,139,30,129,0,0,4,15,0,0,0,1,2,32,1,144],[0,0,25,2,0,0,97,61,0,0,0,64,4,0,4,61,0,0,0,0,2,1,4,59,0,0,0,128,1,32,0,140],[0,0,10,44,0,0,65,61,0,0,0,128,1,32,2,112,0,0,7,174,3,32,0,156,0,0,0,0,1,2,160,25],[0,0,7,174,3,32,0,156,0,0,0,0,3,0,0,25,0,0,0,16,3,0,32,57,0,0,0,8,5,48,1,191],[0,0,7,168,6,16,0,156,0,0,0,0,5,3,160,25,0,0,0,64,3,16,2,112,0,0,7,168,6,16,0,156],[0,0,0,0,3,1,160,25,0,0,0,4,1,80,1,191,0,0,7,164,6,48,0,156,0,0,0,0,1,5,160,25],[0,0,0,32,6,48,2,112,0,0,7,164,5,48,0,156,0,0,0,0,6,3,160,25,0,0,0,2,5,16,1,191],[0,0,255,255,3,96,0,140,0,0,0,0,5,1,160,25,0,0,0,16,1,96,2,112,0,0,0,0,1,6,160,25],[0,0,0,255,1,16,0,140,0,0,0,1,5,80,32,57,0,0,0,65,1,80,0,57,0,0,0,8,1,16,1,127],[0,0,0,0,1,20,0,25,0,0,0,0,3,65,0,75,0,0,0,0,3,0,0,25,0,0,0,1,3,0,64,57],[0,0,7,168,6,16,0,156,0,0,4,10,0,0,33,61,0,0,0,1,3,48,1,144,0,0,4,10,0,0,193,61],[0,0,0,64,0,16,4,63,0,0,0,2,1,80,0,57,0,0,0,0,6,20,4,54,0,0,0,17,1,0,3,103],[0,0,0,0,3,0,0,49,0,0,0,33,7,80,0,57,0,0,0,5,7,112,2,114,0,0,10,26,0,0,97,61],[0,0,0,0,8,49,3,79,0,0,0,0,9,0,0,25,0,0,0,5,10,144,2,16,0,0,0,0,11,166,0,25],[0,0,0,0,10,168,3,79,0,0,0,0,10,10,4,59,0,0,0,0,0,171,4,53,0,0,0,1,9,144,0,57],[0,0,0,0,10,121,0,75,0,0,10,18,0,0,65,61,0,0,0,0,7,0,0,75,0,0,10,28,0,0,97,61],[0,0,0,0,7,4,4,51,0,0,0,0,7,7,0,75,0,0,4,250,0,0,97,61,0,0,0,0,7,6,4,51],[0,0,7,173,7,112,1,151,0,0,0,248,8,80,2,16,0,0,0,0,7,120,1,159,0,0,7,175,7,112,0,65],[0,0,0,0,0,118,4,53,0,0,0,3,5,80,2,16,0,0,0,248,5,80,0,137,0,0,0,0,2,82,1,207],[0,0,0,255,5,80,0,140,0,0,0,0,2,0,32,25,0,0,0,33,5,64,0,57,0,0,10,62,0,0,1,61],[0,0,7,172,1,64,0,156,0,0,4,10,0,0,33,61,0,0,0,64,1,64,0,57,0,0,0,64,0,16,4,63],[0,0,0,1,1,0,0,58,0,0,0,0,5,20,4,54,0,0,0,0,3,0,0,49,0,0,0,17,1,0,3,103],[0,0,0,0,6,49,3,79,0,0,0,0,6,6,4,59,0,0,0,0,0,101,4,53,0,0,4,250,0,0,97,61],[0,0,0,248,7,32,2,16,0,0,7,169,8,0,0,65,0,0,0,0,2,2,0,75,0,0,0,0,8,7,192,25],[0,0,7,173,2,96,1,151,0,0,0,0,2,130,1,159,0,0,0,0,0,37,4,53,0,0,0,64,2,0,4,61],[0,0,0,32,5,32,0,57,0,0,0,0,6,4,4,51,0,0,0,0,7,6,0,75,0,0,10,76,0,0,97,61],[0,0,0,0,7,0,0,25,0,0,0,0,8,87,0,25,0,0,0,32,7,112,0,57,0,0,0,0,9,71,0,25],[0,0,0,0,9,9,4,51,0,0,0,0,0,152,4,53,0,0,0,0,8,103,0,75,0,0,10,69,0,0,65,61],[0,0,0,0,4,86,0,25,0,0,7,199,5,0,0,65,0,0,0,0,0,84,4,53,0,0,0,0,4,36,0,73],[0,0,0,30,5,64,0,138,0,0,0,0,0,82,4,53,0,0,0,33,4,64,0,57,0,0,0,8,5,64,1,127],[0,0,0,0,4,37,0,25,0,0,0,0,5,84,0,75,0,0,0,0,5,0,0,25,0,0,0,1,5,0,64,57],[0,0,7,168,6,64,0,156,0,0,4,10,0,0,33,61,0,0,0,1,5,80,1,144,0,0,4,10,0,0,193,61],[0,0,0,12,6,0,0,41,0,0,1,196,5,96,0,57,0,0,0,64,0,64,4,63,0,0,0,0,4,81,3,79],[0,0,0,0,5,99,0,73,0,0,0,35,5,80,0,138,0,0,0,0,4,4,4,59,0,0,9,123,0,0,1,61],[0,0,0,56,8,64,0,140,0,0,12,171,0,0,65,61,0,0,0,32,9,64,2,112,0,0,7,164,8,64,0,156],[0,0,0,0,9,4,160,25,0,0,7,164,8,64,0,156,0,0,0,0,10,0,0,25,0,0,0,4,10,0,32,57],[0,0,0,2,8,160,1,191,0,0,255,255,11,144,0,140,0,0,0,0,8,10,160,25,0,0,0,16,10,144,2,112],[0,0,0,0,10,9,160,25,0,0,0,255,9,160,0,140,0,0,0,0,9,0,0,25,0,0,0,1,9,0,32,57],[0,0,7,172,10,112,0,156,0,0,4,10,0,0,33,61,0,0,0,0,8,152,1,159,0,0,0,64,9,112,0,57],[0,0,0,64,0,144,4,63,0,0,0,0,10,33,3,79,0,0,0,2,9,128,0,58,0,0,0,0,9,151,4,54],[0,0,0,0,10,10,4,59,0,0,0,0,0,169,4,53,0,0,4,250,0,0,97,61,0,0,7,173,10,160,1,151],[0,0,0,248,11,128,2,16,0,0,0,0,10,171,1,159,0,0,7,177,10,160,1,199,0,0,0,0,0,169,4,53],[0,0,0,3,8,128,2,16,0,0,0,248,8,128,1,95,0,0,0,0,8,132,1,207,0,0,0,33,9,112,0,57],[0,0,0,0,0,137,4,53,0,0,0,0,8,7,0,25,0,0,12,187,0,0,1,61,0,0,7,172,8,112,0,156],[0,0,4,10,0,0,33,61,0,0,0,64,8,112,0,57,0,0,0,64,0,128,4,63,0,0,0,0,8,49,3,79],[0,0,0,1,3,0,0,58,0,0,0,0,3,55,4,54,0,0,0,0,8,8,4,59,0,0,0,0,0,131,4,53],[0,0,4,250,0,0,97,61,0,0,7,173,8,128,1,151,0,0,0,248,6,96,2,16,0,0,0,0,6,134,1,159],[0,0,7,178,6,96,0,65,0,0,0,0,0,99,4,53,0,0,0,64,3,0,4,61,0,0,0,32,6,48,0,57],[0,0,0,0,8,7,4,51,0,0,0,0,9,8,0,75,0,0,10,167,0,0,97,61,0,0,0,0,9,0,0,25],[0,0,0,0,10,105,0,25,0,0,0,32,9,144,0,57,0,0,0,0,11,121,0,25,0,0,0,0,11,11,4,51],[0,0,0,0,0,186,4,53,0,0,0,0,10,137,0,75,0,0,10,160,0,0,65,61,0,0,0,0,7,104,0,25],[0,0,0,0,0,7,4,53,0,0,0,128,8,0,4,61,0,0,0,0,9,8,0,75,0,0,10,180,0,0,97,61],[0,0,0,0,9,0,0,25,0,0,0,0,10,121,0,25,0,0,0,160,11,144,0,57,0,0,0,0,11,11,4,51],[0,0,0,0,0,186,4,53,0,0,0,32,9,144,0,57,0,0,0,0,10,137,0,75,0,0,10,173,0,0,65,61],[0,0,0,0,7,120,0,25,0,0,0,0,0,7,4,53,0,0,0,10,12,0,0,41,0,0,0,0,8,12,4,51],[0,0,0,0,9,8,0,75,0,0,10,194,0,0,97,61,0,0,0,0,9,0,0,25,0,0,0,0,10,121,0,25],[0,0,0,32,9,144,0,57,0,0,0,0,11,201,0,25,0,0,0,0,11,11,4,51,0,0,0,0,0,186,4,53],[0,0,0,0,10,137,0,75,0,0,10,187,0,0,65,61,0,0,0,0,7,120,0,25,0,0,0,0,0,7,4,53],[0,0,0,9,12,0,0,41,0,0,0,0,8,12,4,51,0,0,0,0,9,8,0,75,0,0,10,208,0,0,97,61],[0,0,0,0,9,0,0,25,0,0,0,0,10,121,0,25,0,0,0,32,9,144,0,57,0,0,0,0,11,201,0,25],[0,0,0,0,11,11,4,51,0,0,0,0,0,186,4,53,0,0,0,0,10,137,0,75,0,0,10,201,0,0,65,61],[0,0,0,0,7,120,0,25,0,0,0,0,0,7,4,53,0,0,0,7,12,0,0,41,0,0,0,0,8,12,4,51],[0,0,0,0,9,8,0,75,0,0,10,222,0,0,97,61,0,0,0,0,9,0,0,25,0,0,0,0,10,121,0,25],[0,0,0,32,9,144,0,57,0,0,0,0,11,201,0,25,0,0,0,0,11,11,4,51,0,0,0,0,0,186,4,53],[0,0,0,0,10,137,0,75,0,0,10,215,0,0,65,61,0,0,0,0,7,120,0,25,0,0,0,0,0,7,4,53],[0,0,0,6,12,0,0,41,0,0,0,0,8,12,4,51,0,0,0,0,9,8,0,75,0,0,10,236,0,0,97,61],[0,0,0,0,9,0,0,25,0,0,0,0,10,121,0,25,0,0,0,32,9,144,0,57,0,0,0,0,11,201,0,25],[0,0,0,0,11,11,4,51,0,0,0,0,0,186,4,53,0,0,0,0,10,137,0,75,0,0,10,229,0,0,65,61],[0,0,0,0,5,81,3,79,0,0,0,0,1,120,0,25,0,0,0,31,7,64,1,143,0,0,0,0,0,1,4,53],[0,0,0,5,8,64,2,114,0,0,10,251,0,0,97,61,0,0,0,0,9,0,0,25,0,0,0,5,10,144,2,16],[0,0,0,0,11,161,0,25,0,0,0,0,10,165,3,79,0,0,0,0,10,10,4,59,0,0,0,0,0,171,4,53],[0,0,0,1,9,144,0,57,0,0,0,0,10,137,0,75,0,0,10,243,0,0,65,61,0,0,0,0,9,7,0,75],[0,0,11,10,0,0,97,61,0,0,0,5,8,128,2,16,0,0,0,0,5,133,3,79,0,0,0,0,8,129,0,25],[0,0,0,3,7,112,2,16,0,0,0,0,9,8,4,51,0,0,0,0,9,121,1,207,0,0,0,0,9,121,2,47],[0,0,0,0,5,5,4,59,0,0,1,0,7,112,0,137,0,0,0,0,5,117,2,47,0,0,0,0,5,117,1,207],[0,0,0,0,5,149,1,159,0,0,0,0,0,88,4,53,0,0,0,0,1,65,0,25,0,0,0,0,0,1,4,53],[0,0,0,0,4,2,4,51,0,0,0,0,5,4,0,75,0,0,11,23,0,0,97,61,0,0,0,0,5,0,0,25],[0,0,0,0,7,21,0,25,0,0,0,32,5,80,0,57,0,0,0,0,8,37,0,25,0,0,0,0,8,8,4,51],[0,0,0,0,0,135,4,53,0,0,0,0,7,69,0,75,0,0,11,16,0,0,65,61,0,0,0,0,1,20,0,25],[0,0,0,0,0,1,4,53,0,0,0,0,1,49,0,73,0,0,0,32,2,16,0,138,0,0,0,0,0,35,4,53],[0,0,0,31,1,16,0,57,0,0,0,8,2,16,1,127,0,0,0,0,1,50,0,25,0,0,0,0,2,33,0,75],[0,0,0,0,2,0,0,25,0,0,0,1,2,0,64,57,0,0,7,168,4,16,0,156,0,0,4,10,0,0,33,61],[0,0,0,1,2,32,1,144,0,0,4,10,0,0,193,61,0,0,0,64,0,16,4,63,0,0,7,164,1,0,0,65],[0,0,7,164,2,96,0,156,0,0,0,0,6,1,128,25,0,0,0,64,2,96,2,16,0,0,0,0,3,3,4,51],[0,0,7,164,4,48,0,156,0,0,0,0,3,1,128,25,0,0,0,96,3,48,2,16,0,0,0,0,2,35,1,159],[0,0,0,0,3,0,4,20,0,0,7,164,4,48,0,156,0,0,0,0,3,1,128,25,0,0,0,192,1,48,2,16],[0,0,0,0,1,33,1,159,0,0,7,181,1,16,1,199,0,0,128,16,2,0,0,57,30,139,30,129,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,0,11,3,0,0,41,0,0,0,12,2,0,0,41,0,0,0,204,0,0,97,61],[0,12,0,0,0,2,0,29,0,0,0,17,2,0,3,103,0,11,0,0,0,3,0,29,0,0,0,0,3,50,3,79],[0,0,0,0,1,1,4,59,0,10,0,0,0,1,0,29,0,17,0,0,0,1,0,29,0,0,0,0,1,3,4,59],[0,0,0,1,3,16,0,140,0,0,13,254,0,0,33,61,0,0,0,0,3,1,0,75,0,0,14,210,0,0,97,61],[0,0,0,1,1,16,0,140,0,0,15,126,0,0,193,61,0,0,0,0,1,0,4,21,0,10,0,0,0,1,0,29],[0,0,7,170,1,0,0,65,0,0,0,0,0,16,4,57,0,0,7,164,1,0,0,65,0,0,0,0,2,0,4,20],[0,0,7,164,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,7,171,1,16,1,199],[0,0,128,11,2,0,0,57,30,139,30,129,0,0,4,15,0,0,0,1,2,32,1,144,0,0,25,2,0,0,97,61],[0,0,0,64,3,0,4,61,0,0,0,0,4,1,4,59,0,0,0,128,1,64,0,140,0,0,15,229,0,0,65,61],[0,0,0,128,1,64,2,112,0,0,7,174,2,64,0,156,0,0,0,0,1,4,160,25,0,0,7,174,2,64,0,156],[0,0,0,0,2,0,0,25,0,0,0,16,2,0,32,57,0,0,0,8,5,32,1,191,0,0,7,168,6,16,0,156],[0,0,0,0,5,2,160,25,0,0,0,64,2,16,2,112,0,0,7,168,6,16,0,156,0,0,0,0,2,1,160,25],[0,0,0,4,1,80,1,191,0,0,7,164,6,32,0,156,0,0,0,0,1,5,160,25,0,0,0,32,6,32,2,112],[0,0,7,164,5,32,0,156,0,0,0,0,6,2,160,25,0,0,0,2,5,16,1,191,0,0,255,255,2,96,0,140],[0,0,0,0,5,1,160,25,0,0,0,16,1,96,2,112,0,0,0,0,1,6,160,25,0,0,0,255,1,16,0,140],[0,0,0,1,5,80,32,57,0,0,0,32,1,0,0,138,0,0,0,65,2,80,0,57,0,0,0,0,1,18,1,111],[0,0,0,0,1,19,0,25,0,0,0,0,2,49,0,75,0,0,0,0,2,0,0,25,0,0,0,1,2,0,64,57],[0,0,7,168,6,16,0,156,0,0,4,10,0,0,33,61,0,0,0,1,2,32,1,144,0,0,4,10,0,0,193,61],[0,0,0,64,0,16,4,63,0,0,0,2,1,80,0,57,0,0,0,0,6,19,4,54,0,0,0,17,1,0,3,103],[0,0,0,0,2,0,0,49,0,0,0,33,7,80,0,57,0,0,0,5,7,112,2,114,0,0,11,146,0,0,97,61],[0,0,0,0,8,33,3,79,0,0,0,0,9,0,0,25,0,0,0,5,10,144,2,16,0,0,0,0,11,166,0,25],[0,0,0,0,10,168,3,79,0,0,0,0,10,10,4,59,0,0,0,0,0,171,4,53,0,0,0,1,9,144,0,57],[0,0,0,0,10,121,0,75,0,0,11,138,0,0,65,61,0,0,0,0,7,0,0,75,0,0,11,148,0,0,97,61],[0,0,0,0,7,3,4,51,0,0,0,0,7,7,0,75,0,0,4,250,0,0,97,61,0,0,0,0,7,6,4,51],[0,0,7,173,7,112,1,151,0,0,0,248,8,80,2,16,0,0,0,0,7,120,1,159,0,0,7,175,7,112,0,65],[0,0,0,0,0,118,4,53,0,0,0,3,5,80,2,16,0,0,0,248,5,80,0,137,0,0,0,0,4,84,1,207],[0,0,0,255,5,80,0,140,0,0,0,0,4,0,32,25,0,0,0,33,5,48,0,57,0,0,15,247,0,0,1,61],[0,0,0,0,1,33,3,223,0,0,0,192,2,64,2,16,0,0,7,183,2,32,1,151,0,0,7,184,2,32,1,199],[0,1,0,0,0,33,3,181,0,0,0,0,1,33,3,175,0,0,128,16,2,0,0,57,30,139,30,134,0,0,4,15],[0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,7,164,4,48,1,151,0,0,0,1,2,32,1,144],[0,0,13,28,0,0,97,61,0,0,0,63,2,64,0,57,0,0,7,185,2,32,1,151,0,0,0,64,5,0,4,61],[0,0,0,0,2,37,0,25,0,0,0,0,3,82,0,75,0,0,0,0,3,0,0,25,0,0,0,1,3,0,64,57],[0,0,7,168,6,32,0,156,0,0,4,10,0,0,33,61,0,0,0,1,3,48,1,144,0,0,4,10,0,0,193,61],[0,0,0,64,0,32,4,63,0,0,0,0,2,69,4,54,0,0,0,17,3,0,3,103,0,0,0,31,6,64,0,57],[0,0,0,5,6,96,2,114,0,0,11,204,0,0,97,61,0,0,0,0,7,48,3,104,0,0,0,0,8,0,0,25],[0,0,0,5,9,128,2,16,0,0,0,0,10,146,0,25,0,0,0,0,9,151,3,79,0,0,0,0,9,9,4,59],[0,0,0,0,0,154,4,53,0,0,0,1,8,128,0,57,0,0,0,0,9,104,0,75,0,0,11,196,0,0,65,61],[0,0,0,0,6,0,0,75,0,0,11,206,0,0,97,61,0,0,0,31,6,64,1,143,0,0,0,5,4,64,2,114],[0,0,11,218,0,0,97,61,0,0,0,0,7,0,0,25,0,0,0,5,8,112,2,16,0,0,0,0,9,130,0,25],[0,0,0,0,8,129,3,79,0,0,0,0,8,8,4,59,0,0,0,0,0,137,4,53,0,0,0,1,7,112,0,57],[0,0,0,0,8,71,0,75,0,0,11,210,0,0,65,61,0,0,0,0,7,6,0,75,0,0,11,233,0,0,97,61],[0,0,0,5,4,64,2,16,0,0,0,0,1,65,3,79,0,0,0,0,4,66,0,25,0,0,0,3,6,96,2,16],[0,0,0,0,7,4,4,51,0,0,0,0,7,103,1,207,0,0,0,0,7,103,2,47,0,0,0,0,1,1,4,59],[0,0,1,0,6,96,0,137,0,0,0,0,1,97,2,47,0,0,0,0,1,97,1,207,0,0,0,0,1,113,1,159],[0,0,0,0,0,20,4,53,0,0,0,0,1,5,4,51,0,0,0,32,1,16,0,140,0,0,12,153,0,0,193,61],[0,0,0,12,11,0,0,41,0,0,0,100,1,176,0,57,0,0,0,0,1,19,3,79,0,0,0,68,4,176,0,57],[0,0,0,0,5,67,3,79,0,0,0,36,4,176,0,57,0,0,0,0,4,67,3,79,0,0,1,36,6,176,0,57],[0,0,0,0,6,99,3,79,0,0,1,4,7,176,0,57,0,0,0,0,7,115,3,79,0,0,0,228,8,176,0,57],[0,0,0,0,8,131,3,79,0,0,0,196,9,176,0,57,0,0,0,0,9,147,3,79,0,0,0,164,10,176,0,57],[0,0,0,0,10,163,3,79,0,0,0,132,11,176,0,57,0,0,0,0,11,179,3,79,0,0,0,11,3,48,3,96],[0,0,0,0,3,3,4,59,0,0,0,0,4,4,4,59,0,0,0,0,5,5,4,59,0,0,0,0,12,1,4,59],[0,0,0,0,11,11,4,59,0,0,0,0,10,10,4,59,0,0,0,0,9,9,4,59,0,0,0,0,8,8,4,59],[0,0,0,0,7,7,4,59,0,0,0,0,6,6,4,59,0,0,0,0,2,2,4,51,0,0,0,64,1,0,4,61],[0,0,1,192,13,16,0,57,0,0,0,0,0,45,4,53,0,0,1,160,2,16,0,57,0,0,0,10,13,0,0,41],[0,0,0,0,0,210,4,53,0,0,1,128,2,16,0,57,0,0,0,9,13,0,0,41,0,0,0,0,0,210,4,53],[0,0,1,96,2,16,0,57,0,0,0,0,0,98,4,53,0,0,1,64,2,16,0,57,0,0,0,0,0,114,4,53],[0,0,1,32,2,16,0,57,0,0,0,0,0,130,4,53,0,0,1,0,2,16,0,57,0,0,0,0,0,146,4,53],[0,0,0,224,2,16,0,57,0,0,0,0,0,162,4,53,0,0,0,192,2,16,0,57,0,0,0,0,0,178,4,53],[0,0,0,160,2,16,0,57,0,0,0,0,0,194,4,53,0,0,0,128,2,16,0,57,0,0,0,0,0,82,4,53],[0,0,0,96,2,16,0,57,0,0,0,0,0,66,4,53,0,0,0,64,2,16,0,57,0,0,0,0,0,50,4,53],[0,0,0,32,2,16,0,57,0,0,7,190,3,0,0,65,0,0,0,0,0,50,4,53,0,0,1,192,3,0,0,57],[0,0,0,0,0,49,4,53,0,0,7,191,3,16,0,156,0,0,4,10,0,0,33,61,0,0,1,224,3,16,0,57],[0,0,0,64,0,48,4,63,0,0,7,164,4,0,0,65,0,0,7,164,3,32,0,156,0,0,0,0,2,4,128,25],[0,0,0,64,2,32,2,16,0,0,0,0,1,1,4,51,0,0,7,164,3,16,0,156,0,0,0,0,1,4,128,25],[0,0,0,96,1,16,2,16,0,0,0,0,1,33,1,159,0,0,0,0,2,0,4,20,0,0,7,164,3,32,0,156],[0,0,0,0,2,4,128,25,0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159,0,0,7,181,1,16,1,199],[0,0,128,16,2,0,0,57,30,139,30,129,0,0,4,15,0,0,0,1,2,32,1,144,0,0,0,204,0,0,97,61],[0,0,0,0,1,1,4,59,0,9,0,0,0,1,0,29,0,0,0,64,1,0,4,61,0,10,0,0,0,1,0,29],[0,0,7,170,1,0,0,65,0,0,0,0,0,16,4,57,0,0,0,0,1,0,4,20,0,0,7,164,2,16,0,156],[0,0,7,164,1,0,128,65,0,0,0,192,1,16,2,16,0,0,7,171,1,16,1,199,0,0,128,11,2,0,0,57],[30,139,30,129,0,0,4,15,0,0,0,1,2,32,1,144,0,0,25,2,0,0,97,61,0,0,0,10,4,0,0,41],[0,0,0,32,2,64,0,57,0,0,0,0,1,1,4,59,0,0,7,192,3,0,0,65,0,0,0,0,0,50,4,53],[0,0,0,128,3,64,0,57,0,0,0,0,0,19,4,53,0,0,0,96,1,64,0,57,0,0,7,193,3,0,0,65],[0,0,0,0,0,49,4,53,0,0,0,64,1,64,0,57,0,0,7,194,3,0,0,65,0,0,0,0,0,49,4,53],[0,0,0,128,1,0,0,57,0,0,0,0,0,20,4,53,0,0,7,195,1,64,0,156,0,0,4,10,0,0,33,61],[0,0,0,10,4,0,0,41,0,0,0,160,1,64,0,57,0,0,0,64,0,16,4,63,0,0,7,164,1,0,0,65],[0,0,7,164,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,64,2,32,2,16,0,0,0,0,3,4,4,51],[0,0,7,164,4,48,0,156,0,0,0,0,3,1,128,25,0,0,0,96,3,48,2,16,0,0,0,0,2,35,1,159],[0,0,0,0,3,0,4,20,0,0,7,164,4,48,0,156,0,0,0,0,3,1,128,25,0,0,0,192,1,48,2,16],[0,0,0,0,1,33,1,159,0,0,7,181,1,16,1,199,0,0,128,16,2,0,0,57,30,139,30,129,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,0,204,0,0,97,61,0,0,0,0,3,1,4,59,0,0,0,64,1,0,4,61],[0,0,0,66,2,16,0,57,0,0,0,9,4,0,0,41,0,0,0,0,0,66,4,53,0,0,0,32,2,16,0,57],[0,0,7,196,4,0,0,65,0,0,0,0,0,66,4,53,0,0,0,34,4,16,0,57,0,0,0,0,0,52,4,53],[0,0,0,66,3,0,0,57,0,0,0,0,0,49,4,53,0,0,7,197,3,16,0,156,0,0,4,10,0,0,33,61],[0,0,0,128,3,16,0,57,0,0,0,64,0,48,4,63,0,0,7,164,3,0,0,65,0,0,7,164,4,32,0,156],[0,0,0,0,2,3,128,25,0,0,0,64,2,32,2,16,0,0,0,0,1,1,4,51,0,0,7,164,4,16,0,156],[0,0,0,0,1,3,128,25,0,0,0,96,1,16,2,16,0,0,0,0,1,33,1,159,0,0,0,0,2,0,4,20],[0,0,7,164,4,32,0,156,0,0,0,0,2,3,128,25,0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159],[0,0,11,53,0,0,1,61,0,0,0,64,1,0,4,61,0,0,0,68,2,16,0,57,0,0,7,187,3,0,0,65],[0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,31,3,0,0,57,0,0,0,0,0,50,4,53],[0,0,7,188,2,0,0,65,0,0,0,0,0,33,4,53,0,0,0,4,2,16,0,57,0,0,0,32,3,0,0,57],[0,0,0,0,0,50,4,53,0,0,7,164,2,0,0,65,0,0,7,164,3,16,0,156,0,0,0,0,1,2,128,25],[0,0,0,64,1,16,2,16,0,0,7,189,1,16,1,199,0,0,30,141,0,1,4,48,0,0,7,172,8,112,0,156],[0,0,4,10,0,0,33,61,0,0,0,64,8,112,0,57,0,0,0,64,0,128,4,63,0,0,0,0,9,33,3,79],[0,0,0,1,8,0,0,58,0,0,0,0,8,135,4,54,0,0,0,0,9,9,4,59,0,0,0,0,0,152,4,53],[0,0,4,250,0,0,97,61,0,0,0,248,10,64,2,16,0,0,7,173,9,144,1,151,0,0,0,0,9,169,1,159],[0,0,7,169,9,144,1,103,0,0,0,0,0,152,4,53,0,0,0,0,8,7,0,25,0,0,0,64,7,0,4,61],[0,0,7,172,9,112,0,156,0,0,4,10,0,0,33,61,0,0,0,64,9,112,0,57,0,0,0,64,0,144,4,63],[0,0,0,0,2,33,3,79,0,0,0,1,12,0,0,58,0,0,0,0,9,199,4,54,0,0,0,0,11,2,4,59],[0,0,0,0,0,185,4,53,0,0,4,250,0,0,97,61,0,0,7,173,2,176,1,151,0,0,7,178,10,32,1,199],[0,0,0,0,0,169,4,53,0,0,0,0,9,6,4,51,0,0,0,0,9,73,0,25,0,0,0,0,10,8,4,51],[0,0,0,0,9,169,0,25,0,0,0,0,10,7,4,51,0,0,0,0,9,169,0,25,0,0,0,64,10,0,4,61],[0,0,7,168,9,144,1,151,0,0,0,56,13,144,0,140,0,0,13,55,0,0,65,61,0,0,0,32,13,144,2,112],[0,0,7,164,12,144,0,156,0,0,0,0,13,9,160,25,0,0,7,164,12,144,0,156,0,0,0,0,14,0,0,25],[0,0,0,4,14,0,32,57,0,0,0,2,12,224,1,191,0,0,255,255,15,208,0,140,0,0,0,0,12,14,160,25],[0,0,0,16,14,208,2,112,0,0,0,0,14,13,160,25,0,0,0,255,13,224,0,140,0,0,0,0,13,0,0,25],[0,0,0,1,13,0,32,57,0,0,7,172,14,160,0,156,0,0,4,10,0,0,33,61,0,0,0,0,12,220,1,159],[0,0,0,64,13,160,0,57,0,0,0,64,0,208,4,63,0,0,0,32,13,160,0,57,0,0,0,0,0,189,4,53],[0,0,0,2,11,192,0,58,0,0,0,0,0,186,4,53,0,0,4,250,0,0,97,61,0,0,0,248,11,192,2,16],[0,0,0,0,2,43,1,159,0,0,7,179,2,32,1,199,0,0,0,0,0,45,4,53,0,0,0,3,2,192,2,16],[0,0,0,248,2,32,1,95,0,0,0,0,2,41,1,207,0,0,0,33,9,160,0,57,0,0,0,0,0,41,4,53],[0,0,13,68,0,0,1,61,0,0,0,56,8,64,0,140,0,0,13,180,0,0,65,61,0,0,0,32,9,64,2,112],[0,0,7,164,8,64,0,156,0,0,0,0,9,4,160,25,0,0,7,164,8,64,0,156,0,0,0,0,10,0,0,25],[0,0,0,4,10,0,32,57,0,0,0,2,8,160,1,191,0,0,255,255,11,144,0,140,0,0,0,0,8,10,160,25],[0,0,0,16,10,144,2,112,0,0,0,0,10,9,160,25,0,0,0,255,9,160,0,140,0,0,0,0,9,0,0,25],[0,0,0,1,9,0,32,57,0,0,7,172,10,96,0,156,0,0,4,10,0,0,33,61,0,0,0,0,8,152,1,159],[0,0,0,64,9,96,0,57,0,0,0,64,0,144,4,63,0,0,0,0,10,33,3,79,0,0,0,2,9,128,0,58],[0,0,0,0,9,150,4,54,0,0,0,0,10,10,4,59,0,0,0,0,0,169,4,53,0,0,4,250,0,0,97,61],[0,0,7,173,10,160,1,151,0,0,0,248,11,128,2,16,0,0,0,0,10,171,1,159,0,0,7,177,10,160,1,199],[0,0,0,0,0,169,4,53,0,0,0,3,8,128,2,16,0,0,0,248,8,128,1,95,0,0,0,0,8,132,1,207],[0,0,0,33,9,96,0,57,0,0,0,0,0,137,4,53,0,0,0,0,8,6,0,25,0,0,13,196,0,0,1,61],[0,0,0,31,3,64,1,143,0,0,0,5,2,64,2,114,0,0,13,39,0,0,97,61,0,0,0,0,5,0,0,25],[0,0,0,5,6,80,2,16,0,0,0,0,7,97,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,118,4,53],[0,0,0,1,5,80,0,57,0,0,0,0,6,37,0,75,0,0,13,32,0,0,65,61,0,0,0,0,5,3,0,75],[0,0,13,53,0,0,97,61,0,0,0,3,3,48,2,16,0,0,0,5,2,32,2,16,0,0,0,0,5,2,4,51],[0,0,0,0,5,53,1,207,0,0,0,0,5,53,2,47,0,0,0,0,1,33,3,79,0,0,0,0,1,1,4,59],[0,0,1,0,3,48,0,137,0,0,0,0,1,49,2,47,0,0,0,0,1,49,1,207,0,0,0,0,1,81,1,159],[0,0,0,0,0,18,4,53,0,0,0,96,1,64,2,16,0,0,30,141,0,1,4,48,0,0,7,172,13,160,0,156],[0,0,4,10,0,0,33,61,0,0,0,64,13,160,0,57,0,0,0,64,0,208,4,63,0,0,0,32,13,160,0,57],[0,0,0,0,0,189,4,53,0,0,0,0,0,202,4,53,0,0,0,0,11,12,0,75,0,0,4,250,0,0,97,61],[0,0,0,248,9,144,2,16,0,0,0,0,2,41,1,159,0,0,7,178,2,32,0,65,0,0,0,0,0,45,4,53],[0,0,0,64,2,0,4,61,0,0,0,32,9,32,0,57,0,0,7,180,11,0,0,65,0,0,0,0,0,185,4,53],[0,0,0,33,11,32,0,57,0,0,0,0,12,10,4,51,0,0,0,0,13,12,0,75,0,0,13,84,0,0,97,61],[0,0,0,0,13,0,0,25,0,0,0,0,14,189,0,25,0,0,0,32,13,208,0,57,0,0,0,0,15,173,0,25],[0,0,0,0,15,15,4,51,0,0,0,0,0,254,4,53,0,0,0,0,14,205,0,75,0,0,13,77,0,0,65,61],[0,0,0,0,10,188,0,25,0,0,0,0,0,10,4,53,0,0,0,0,11,6,4,51,0,0,0,0,12,11,0,75],[0,0,13,97,0,0,97,61,0,0,0,0,12,0,0,25,0,0,0,0,13,172,0,25,0,0,0,32,12,192,0,57],[0,0,0,0,14,108,0,25,0,0,0,0,14,14,4,51,0,0,0,0,0,237,4,53,0,0,0,0,13,188,0,75],[0,0,13,90,0,0,65,61,0,0,0,0,6,171,0,25,0,0,0,0,0,6,4,53,0,0,0,0,10,8,4,51],[0,0,0,0,11,10,0,75,0,0,13,110,0,0,97,61,0,0,0,0,11,0,0,25,0,0,0,0,12,107,0,25],[0,0,0,32,11,176,0,57,0,0,0,0,13,139,0,25,0,0,0,0,13,13,4,51,0,0,0,0,0,220,4,53],[0,0,0,0,12,171,0,75,0,0,13,103,0,0,65,61,0,0,0,0,5,81,3,79,0,0,0,0,1,106,0,25],[0,0,0,31,6,64,1,143,0,0,0,0,0,1,4,53,0,0,0,5,8,64,2,114,0,0,13,125,0,0,97,61],[0,0,0,0,10,0,0,25,0,0,0,5,11,160,2,16,0,0,0,0,12,177,0,25,0,0,0,0,11,181,3,79],[0,0,0,0,11,11,4,59,0,0,0,0,0,188,4,53,0,0,0,1,10,160,0,57,0,0,0,0,11,138,0,75],[0,0,13,117,0,0,65,61,0,0,0,0,10,6,0,75,0,0,13,140,0,0,97,61,0,0,0,5,8,128,2,16],[0,0,0,0,5,133,3,79,0,0,0,0,8,129,0,25,0,0,0,3,6,96,2,16,0,0,0,0,10,8,4,51],[0,0,0,0,10,106,1,207,0,0,0,0,10,106,2,47,0,0,0,0,5,5,4,59,0,0,1,0,6,96,0,137],[0,0,0,0,5,101,2,47,0,0,0,0,5,101,1,207,0,0,0,0,5,165,1,159,0,0,0,0,0,88,4,53],[0,0,0,0,1,65,0,25,0,0,0,0,0,1,4,53,0,0,0,0,4,7,4,51,0,0,0,0,5,4,0,75],[0,0,13,153,0,0,97,61,0,0,0,0,5,0,0,25,0,0,0,0,6,21,0,25,0,0,0,32,5,80,0,57],[0,0,0,0,8,117,0,25,0,0,0,0,8,8,4,51,0,0,0,0,0,134,4,53,0,0,0,0,6,69,0,75],[0,0,13,146,0,0,65,61,0,0,0,0,1,20,0,25,0,0,0,0,0,1,4,53,0,0,0,0,1,33,0,73],[0,0,0,32,4,16,0,138,0,0,0,0,0,66,4,53,0,0,0,31,1,16,0,57,0,0,0,0,3,49,1,111],[0,0,0,0,1,35,0,25,0,0,0,0,3,49,0,75,0,0,0,0,3,0,0,25,0,0,0,1,3,0,64,57],[0,0,7,168,4,16,0,156,0,0,4,10,0,0,33,61,0,0,0,1,3,48,1,144,0,0,4,10,0,0,193,61],[0,0,0,64,0,16,4,63,0,0,7,164,1,0,0,65,0,0,7,164,3,144,0,156,0,0,0,0,9,1,128,25],[0,0,0,64,3,144,2,16,0,0,0,0,2,2,4,51,0,0,7,164,4,32,0,156,0,0,0,0,2,1,128,25],[0,0,0,96,2,32,2,16,0,0,0,0,2,50,1,159,0,0,0,0,3,0,4,20,0,0,11,49,0,0,1,61],[0,0,7,172,8,96,0,156,0,0,4,10,0,0,33,61,0,0,0,64,8,96,0,57,0,0,0,64,0,128,4,63],[0,0,0,0,9,33,3,79,0,0,0,1,8,0,0,58,0,0,0,0,8,134,4,54,0,0,0,0,9,9,4,59],[0,0,0,0,0,152,4,53,0,0,4,250,0,0,97,61,0,0,0,248,10,64,2,16,0,0,7,173,9,144,1,151],[0,0,0,0,9,169,1,159,0,0,7,169,9,144,1,103,0,0,0,0,0,152,4,53,0,0,0,0,8,6,0,25],[0,0,0,64,6,0,4,61,0,0,7,172,9,96,0,156,0,0,4,10,0,0,33,61,0,0,0,64,9,96,0,57],[0,0,0,64,0,144,4,63,0,0,0,0,2,33,3,79,0,0,0,1,12,0,0,58,0,0,0,0,9,198,4,54],[0,0,0,0,11,2,4,59,0,0,0,0,0,185,4,53,0,0,4,250,0,0,97,61,0,0,7,173,2,176,1,151],[0,0,7,178,10,32,1,199,0,0,0,0,0,169,4,53,0,0,0,0,9,7,4,51,0,0,0,0,9,73,0,25],[0,0,0,0,10,8,4,51,0,0,0,0,9,169,0,25,0,0,0,0,10,6,4,51,0,0,0,0,9,169,0,25],[0,0,0,64,10,0,4,61,0,0,7,168,9,144,1,151,0,0,0,56,13,144,0,140,0,0,14,85,0,0,65,61],[0,0,0,32,13,144,2,112,0,0,7,164,12,144,0,156,0,0,0,0,13,9,160,25,0,0,7,164,12,144,0,156],[0,0,0,0,14,0,0,25,0,0,0,4,14,0,32,57,0,0,0,2,12,224,1,191,0,0,255,255,15,208,0,140],[0,0,0,0,12,14,160,25,0,0,0,16,14,208,2,112,0,0,0,0,14,13,160,25,0,0,0,255,13,224,0,140],[0,0,0,0,13,0,0,25,0,0,0,1,13,0,32,57,0,0,7,172,14,160,0,156,0,0,4,10,0,0,33,61],[0,0,0,0,12,220,1,159,0,0,0,64,13,160,0,57,0,0,0,64,0,208,4,63,0,0,0,32,13,160,0,57],[0,0,0,0,0,189,4,53,0,0,0,2,11,192,0,58,0,0,0,0,0,186,4,53,0,0,4,250,0,0,97,61],[0,0,0,248,11,192,2,16,0,0,0,0,2,43,1,159,0,0,7,179,2,32,1,199,0,0,0,0,0,45,4,53],[0,0,0,3,2,192,2,16,0,0,0,248,2,32,1,95,0,0,0,0,2,41,1,207,0,0,0,33,9,160,0,57],[0,0,0,0,0,41,4,53,0,0,14,98,0,0,1,61,0,0,0,2,3,16,0,140,0,0,15,36,0,0,97,61],[0,0,0,113,1,16,0,140,0,0,15,126,0,0,193,61,0,0,0,11,9,0,0,41,0,0,1,224,1,144,0,57],[0,0,0,0,3,18,3,79,0,0,0,0,1,0,0,49,0,0,0,12,4,16,0,106,0,0,0,35,4,64,0,138],[0,0,0,0,3,3,4,59,0,0,7,169,5,0,0,65,0,0,0,0,6,67,0,75,0,0,0,0,6,0,0,25],[0,0,0,0,6,5,128,25,0,0,7,169,4,64,1,151,0,0,7,169,7,48,1,151,0,0,0,0,8,71,0,75],[0,0,0,0,5,0,128,25,0,0,0,0,4,71,1,63,0,0,7,169,4,64,0,156,0,0,0,0,5,6,192,25],[0,0,0,0,4,5,0,75,0,0,0,204,0,0,193,61,0,0,0,0,3,147,0,25,0,0,0,0,2,50,3,79],[0,0,0,0,2,2,4,59,0,0,7,168,4,32,0,156,0,0,0,204,0,0,33,61,0,0,0,0,4,33,0,73],[0,0,0,32,1,48,0,57,0,0,7,169,3,0,0,65,0,0,0,0,5,65,0,75,0,0,0,0,5,0,0,25],[0,0,0,0,5,3,32,25,0,0,7,169,4,64,1,151,0,0,7,169,6,16,1,151,0,0,0,0,7,70,0,75],[0,0,0,0,3,0,128,25,0,0,0,0,4,70,1,63,0,0,7,169,4,64,0,156,0,0,0,0,3,5,192,25],[0,0,0,0,3,3,0,75,0,0,0,204,0,0,193,61,30,139,29,229,0,0,4,15,0,0,0,64,2,0,4,61],[0,0,0,64,3,32,0,57,0,0,0,0,0,19,4,53,0,0,0,64,1,0,0,57,0,0,0,0,1,18,4,54],[0,0,0,10,3,0,0,41,0,0,0,0,0,49,4,53,0,0,7,203,3,32,0,156,0,0,4,10,0,0,33,61],[0,0,0,96,3,32,0,57,0,0,0,64,0,48,4,63,0,0,7,164,3,0,0,65,0,0,7,164,4,16,0,156],[0,0,0,0,1,3,128,25,0,0,0,64,1,16,2,16,0,0,0,0,2,2,4,51,0,0,7,164,4,32,0,156],[0,0,0,0,2,3,128,25,0,0,0,96,2,32,2,16,0,0,0,0,1,18,1,159,0,0,0,0,2,0,4,20],[0,0,7,164,4,32,0,156,0,0,0,0,2,3,128,25,0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159],[0,0,7,181,1,16,1,199,0,0,128,16,2,0,0,57,30,139,30,129,0,0,4,15,0,0,0,1,2,32,1,144],[0,0,0,204,0,0,97,61,0,0,0,0,1,1,4,59,0,0,0,64,2,0,4,61,0,0,0,32,3,32,0,57],[0,0,0,17,4,0,0,41,0,0,0,0,0,67,4,53,0,0,0,0,0,18,4,53,0,0,7,164,1,0,0,65],[0,0,7,164,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,64,1,32,2,16,0,0,7,204,1,16,1,199],[0,0,30,140,0,1,4,46,0,0,7,172,13,160,0,156,0,0,4,10,0,0,33,61,0,0,0,64,13,160,0,57],[0,0,0,64,0,208,4,63,0,0,0,32,13,160,0,57,0,0,0,0,0,189,4,53,0,0,0,0,0,202,4,53],[0,0,0,0,11,12,0,75,0,0,4,250,0,0,97,61,0,0,0,248,9,144,2,16,0,0,0,0,2,41,1,159],[0,0,7,178,2,32,0,65,0,0,0,0,0,45,4,53,0,0,0,64,2,0,4,61,0,0,0,32,9,32,0,57],[0,0,7,181,11,0,0,65,0,0,0,0,0,185,4,53,0,0,0,33,11,32,0,57,0,0,0,0,12,10,4,51],[0,0,0,0,13,12,0,75,0,0,14,114,0,0,97,61,0,0,0,0,13,0,0,25,0,0,0,0,14,189,0,25],[0,0,0,32,13,208,0,57,0,0,0,0,15,173,0,25,0,0,0,0,15,15,4,51,0,0,0,0,0,254,4,53],[0,0,0,0,14,205,0,75,0,0,14,107,0,0,65,61,0,0,0,0,10,188,0,25,0,0,0,0,0,10,4,53],[0,0,0,0,11,7,4,51,0,0,0,0,12,11,0,75,0,0,14,127,0,0,97,61,0,0,0,0,12,0,0,25],[0,0,0,0,13,172,0,25,0,0,0,32,12,192,0,57,0,0,0,0,14,124,0,25,0,0,0,0,14,14,4,51],[0,0,0,0,0,237,4,53,0,0,0,0,13,188,0,75,0,0,14,120,0,0,65,61,0,0,0,0,7,171,0,25],[0,0,0,0,0,7,4,53,0,0,0,0,10,8,4,51,0,0,0,0,11,10,0,75,0,0,14,140,0,0,97,61],[0,0,0,0,11,0,0,25,0,0,0,0,12,123,0,25,0,0,0,32,11,176,0,57,0,0,0,0,13,139,0,25],[0,0,0,0,13,13,4,51,0,0,0,0,0,220,4,53,0,0,0,0,12,171,0,75,0,0,14,133,0,0,65,61],[0,0,0,0,5,81,3,79,0,0,0,0,1,122,0,25,0,0,0,31,7,64,1,143,0,0,0,0,0,1,4,53],[0,0,0,5,8,64,2,114,0,0,14,155,0,0,97,61,0,0,0,0,10,0,0,25,0,0,0,5,11,160,2,16],[0,0,0,0,12,177,0,25,0,0,0,0,11,181,3,79,0,0,0,0,11,11,4,59,0,0,0,0,0,188,4,53],[0,0,0,1,10,160,0,57,0,0,0,0,11,138,0,75,0,0,14,147,0,0,65,61,0,0,0,0,10,7,0,75],[0,0,14,170,0,0,97,61,0,0,0,5,8,128,2,16,0,0,0,0,5,133,3,79,0,0,0,0,8,129,0,25],[0,0,0,3,7,112,2,16,0,0,0,0,10,8,4,51,0,0,0,0,10,122,1,207,0,0,0,0,10,122,2,47],[0,0,0,0,5,5,4,59,0,0,1,0,7,112,0,137,0,0,0,0,5,117,2,47,0,0,0,0,5,117,1,207],[0,0,0,0,5,165,1,159,0,0,0,0,0,88,4,53,0,0,0,0,1,65,0,25,0,0,0,0,0,1,4,53],[0,0,0,0,4,6,4,51,0,0,0,0,5,4,0,75,0,0,14,183,0,0,97,61,0,0,0,0,5,0,0,25],[0,0,0,0,7,21,0,25,0,0,0,32,5,80,0,57,0,0,0,0,8,101,0,25,0,0,0,0,8,8,4,51],[0,0,0,0,0,135,4,53,0,0,0,0,7,69,0,75,0,0,14,176,0,0,65,61,0,0,0,0,1,20,0,25],[0,0,0,0,0,1,4,53,0,0,0,0,1,33,0,73,0,0,0,32,4,16,0,138,0,0,0,0,0,66,4,53],[0,0,0,31,1,16,0,57,0,0,0,0,3,49,1,111,0,0,0,0,1,35,0,25,0,0,0,0,3,49,0,75],[0,0,0,0,3,0,0,25,0,0,0,1,3,0,64,57,0,0,7,168,4,16,0,156,0,0,4,10,0,0,33,61],[0,0,0,1,3,48,1,144,0,0,4,10,0,0,193,61,0,0,0,64,0,16,4,63,0,0,7,164,1,0,0,65],[0,0,7,164,3,144,0,156,0,0,0,0,9,1,128,25,0,0,0,64,3,144,2,16,0,0,0,0,2,2,4,51],[0,0,7,164,4,32,0,156,0,0,0,0,2,1,128,25,0,0,0,96,2,32,2,16,0,0,0,0,2,50,1,159],[0,0,0,0,3,0,4,20,0,0,11,49,0,0,1,61,0,0,0,64,1,0,4,61,0,10,0,0,0,1,0,29],[0,0,0,11,1,0,0,41,0,0,1,0,4,16,0,57,0,0,0,0,1,66,3,79,0,0,0,0,3,1,4,59],[0,0,0,128,1,48,0,140,0,0,15,133,0,0,65,61,0,0,0,128,1,48,2,112,0,0,7,174,5,48,0,156],[0,0,0,0,1,3,160,25,0,0,7,174,5,48,0,156,0,0,0,0,5,0,0,25,0,0,0,16,5,0,32,57],[0,0,0,8,6,80,1,191,0,0,7,168,7,16,0,156,0,0,0,0,6,5,160,25,0,0,0,64,5,16,2,112],[0,0,7,168,7,16,0,156,0,0,0,0,5,1,160,25,0,0,0,4,1,96,1,191,0,0,7,164,7,80,0,156],[0,0,0,0,1,6,160,25,0,0,0,32,6,80,2,112,0,0,7,164,7,80,0,156,0,0,0,0,6,5,160,25],[0,0,0,2,5,16,1,191,0,0,255,255,7,96,0,140,0,0,0,0,5,1,160,25,0,0,0,16,1,96,2,112],[0,0,0,0,1,6,160,25,0,0,0,255,1,16,0,140,0,0,0,1,5,80,32,57,0,0,0,32,1,0,0,138],[0,0,0,65,6,80,0,57,0,0,0,0,1,22,1,111,0,0,0,10,1,16,0,41,0,0,0,10,6,16,0,108],[0,0,0,0,6,0,0,25,0,0,0,1,6,0,64,57,0,0,7,168,7,16,0,156,0,0,4,10,0,0,33,61],[0,0,0,1,6,96,1,144,0,0,4,10,0,0,193,61,0,0,0,64,0,16,4,63,0,0,0,2,1,80,0,57],[0,0,0,10,6,0,0,41,0,0,0,0,6,22,4,54,0,0,0,0,1,0,0,49,0,0,0,33,7,80,0,57],[0,0,0,5,7,112,2,114,0,0,15,16,0,0,97,61,0,0,0,0,8,18,3,79,0,0,0,0,9,0,0,25],[0,0,0,5,10,144,2,16,0,0,0,0,11,166,0,25,0,0,0,0,10,168,3,79,0,0,0,0,10,10,4,59],[0,0,0,0,0,171,4,53,0,0,0,1,9,144,0,57,0,0,0,0,10,121,0,75,0,0,15,8,0,0,65,61],[0,0,0,0,7,0,0,75,0,0,15,18,0,0,97,61,0,0,0,10,7,0,0,41,0,0,0,0,7,7,4,51],[0,0,0,0,7,7,0,75,0,0,4,250,0,0,97,61,0,0,0,0,7,6,4,51,0,0,7,173,7,112,1,151],[0,0,0,248,8,80,2,16,0,0,0,0,7,120,1,159,0,0,7,175,7,112,0,65,0,0,0,0,0,118,4,53],[0,0,0,3,5,80,2,16,0,0,0,248,5,80,0,137,0,0,0,0,3,83,1,207,0,0,0,255,5,80,0,140],[0,0,0,0,3,0,32,25,0,0,0,10,5,0,0,41,0,0,0,33,5,80,0,57,0,0,15,152,0,0,1,61],[0,0,0,0,1,0,4,21,0,10,0,0,0,1,0,29,0,0,7,170,1,0,0,65,0,0,0,0,0,16,4,57],[0,0,7,164,1,0,0,65,0,0,0,0,2,0,4,20,0,0,7,164,3,32,0,156,0,0,0,0,2,1,128,25],[0,0,0,192,1,32,2,16,0,0,7,171,1,16,1,199,0,0,128,11,2,0,0,57,30,139,30,129,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,25,2,0,0,97,61,0,0,0,64,3,0,4,61,0,0,0,0,4,1,4,59],[0,0,0,128,1,64,0,140,0,0,16,69,0,0,65,61,0,0,0,128,1,64,2,112,0,0,7,174,2,64,0,156],[0,0,0,0,1,4,160,25,0,0,7,174,2,64,0,156,0,0,0,0,2,0,0,25,0,0,0,16,2,0,32,57],[0,0,0,8,5,32,1,191,0,0,7,168,6,16,0,156,0,0,0,0,5,2,160,25,0,0,0,64,2,16,2,112],[0,0,7,168,6,16,0,156,0,0,0,0,2,1,160,25,0,0,0,4,1,80,1,191,0,0,7,164,6,32,0,156],[0,0,0,0,1,5,160,25,0,0,0,32,6,32,2,112,0,0,7,164,5,32,0,156,0,0,0,0,6,2,160,25],[0,0,0,2,5,16,1,191,0,0,255,255,2,96,0,140,0,0,0,0,5,1,160,25,0,0,0,16,1,96,2,112],[0,0,0,0,1,6,160,25,0,0,0,255,1,16,0,140,0,0,0,1,5,80,32,57,0,0,0,32,1,0,0,138],[0,0,0,65,2,80,0,57,0,0,0,0,1,18,1,111,0,0,0,0,1,19,0,25,0,0,0,0,2,49,0,75],[0,0,0,0,2,0,0,25,0,0,0,1,2,0,64,57,0,0,7,168,6,16,0,156,0,0,4,10,0,0,33,61],[0,0,0,1,2,32,1,144,0,0,4,10,0,0,193,61,0,0,0,64,0,16,4,63,0,0,0,2,1,80,0,57],[0,0,0,0,6,19,4,54,0,0,0,17,1,0,3,103,0,0,0,0,2,0,0,49,0,0,0,33,7,80,0,57],[0,0,0,5,7,112,2,114,0,0,15,108,0,0,97,61,0,0,0,0,8,33,3,79,0,0,0,0,9,0,0,25],[0,0,0,5,10,144,2,16,0,0,0,0,11,166,0,25,0,0,0,0,10,168,3,79,0,0,0,0,10,10,4,59],[0,0,0,0,0,171,4,53,0,0,0,1,9,144,0,57,0,0,0,0,10,121,0,75,0,0,15,100,0,0,65,61],[0,0,0,0,7,0,0,75,0,0,15,110,0,0,97,61,0,0,0,0,7,3,4,51,0,0,0,0,7,7,0,75],[0,0,4,250,0,0,97,61,0,0,0,0,7,6,4,51,0,0,7,173,7,112,1,151,0,0,0,248,8,80,2,16],[0,0,0,0,7,120,1,159,0,0,7,175,7,112,0,65,0,0,0,0,0,118,4,53,0,0,0,3,5,80,2,16],[0,0,0,248,5,80,0,137,0,0,0,0,4,84,1,207,0,0,0,255,5,80,0,140,0,0,0,0,4,0,32,25],[0,0,0,33,5,48,0,57,0,0,16,87,0,0,1,61,0,0,0,64,1,0,4,61,0,0,0,68,2,16,0,57],[0,0,7,205,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,19,3,0,0,57],[0,0,12,159,0,0,1,61,0,0,0,10,1,0,0,41,0,0,7,172,1,16,0,156,0,0,4,10,0,0,33,61],[0,0,0,10,5,0,0,41,0,0,0,64,1,80,0,57,0,0,0,64,0,16,4,63,0,0,0,1,1,0,0,58],[0,0,0,0,5,21,4,54,0,0,0,0,1,0,0,49,0,0,0,0,6,18,3,79,0,0,0,0,6,6,4,59],[0,0,0,0,0,101,4,53,0,0,4,250,0,0,97,61,0,0,0,248,7,48,2,16,0,0,7,169,8,0,0,65],[0,0,0,0,3,3,0,75,0,0,0,0,8,7,192,25,0,0,7,173,3,96,1,151,0,0,0,0,3,131,1,159],[0,0,0,0,0,53,4,53,0,0,0,64,3,0,4,61,0,0,0,96,4,64,0,138,0,0,0,0,5,66,3,79],[0,0,0,0,5,5,4,59,0,0,0,128,6,80,0,140,0,0,16,165,0,0,65,61,0,0,0,128,6,80,2,112],[0,0,7,174,7,80,0,156,0,0,0,0,6,5,160,25,0,0,7,174,7,80,0,156,0,0,0,0,7,0,0,25],[0,0,0,16,7,0,32,57,0,0,0,8,8,112,1,191,0,0,7,168,9,96,0,156,0,0,0,0,8,7,160,25],[0,0,0,64,7,96,2,112,0,0,7,168,9,96,0,156,0,0,0,0,7,6,160,25,0,0,0,4,9,128,1,191],[0,0,7,164,6,112,0,156,0,0,0,0,9,8,160,25,0,0,0,32,8,112,2,112,0,0,7,164,6,112,0,156],[0,0,0,0,8,7,160,25,0,0,0,2,6,144,1,191,0,0,255,255,7,128,0,140,0,0,0,0,6,9,160,25],[0,0,0,16,7,128,2,112,0,0,0,0,7,8,160,25,0,0,0,255,7,112,0,140,0,0,0,1,6,96,32,57],[0,0,0,32,7,0,0,138,0,0,0,65,8,96,0,57,0,0,0,0,7,120,1,111,0,0,0,0,7,115,0,25],[0,0,0,0,8,55,0,75,0,0,0,0,8,0,0,25,0,0,0,1,8,0,64,57,0,0,7,168,9,112,0,156],[0,0,4,10,0,0,33,61,0,0,0,1,8,128,1,144,0,0,4,10,0,0,193,61,0,0,0,64,0,112,4,63],[0,0,0,2,7,96,0,57,0,0,0,0,7,115,4,54,0,0,0,33,8,96,0,57,0,0,0,5,8,128,2,114],[0,0,15,211,0,0,97,61,0,0,0,0,9,18,3,79,0,0,0,0,10,0,0,25,0,0,0,5,11,160,2,16],[0,0,0,0,12,183,0,25,0,0,0,0,11,185,3,79,0,0,0,0,11,11,4,59,0,0,0,0,0,188,4,53],[0,0,0,1,10,160,0,57,0,0,0,0,11,138,0,75,0,0,15,203,0,0,65,61,0,0,0,0,8,0,0,75],[0,0,15,213,0,0,97,61,0,0,0,0,8,3,4,51,0,0,0,0,8,8,0,75,0,0,4,250,0,0,97,61],[0,0,0,0,8,7,4,51,0,0,7,173,8,128,1,151,0,0,0,248,9,96,2,16,0,0,0,0,8,137,1,159],[0,0,7,175,8,128,0,65,0,0,0,0,0,135,4,53,0,0,0,3,6,96,2,16,0,0,0,248,6,96,0,137],[0,0,0,0,5,101,1,207,0,0,0,255,6,96,0,140,0,0,0,0,5,0,32,25,0,0,0,33,6,48,0,57],[0,0,16,181,0,0,1,61,0,0,7,172,1,48,0,156,0,0,4,10,0,0,33,61,0,0,0,64,1,48,0,57],[0,0,0,64,0,16,4,63,0,0,0,1,1,0,0,58,0,0,0,0,5,19,4,54,0,0,0,0,2,0,0,49],[0,0,0,17,1,0,3,103,0,0,0,0,6,33,3,79,0,0,0,0,6,6,4,59,0,0,0,0,0,101,4,53],[0,0,4,250,0,0,97,61,0,0,0,248,7,64,2,16,0,0,7,169,8,0,0,65,0,0,0,0,4,4,0,75],[0,0,0,0,8,7,192,25,0,0,7,173,4,96,1,151,0,0,0,0,4,132,1,159,0,0,0,0,0,69,4,53],[0,0,0,64,5,0,4,61,0,0,0,12,4,0,0,41,0,0,1,4,4,64,0,57,0,0,0,0,6,65,3,79],[0,0,0,0,6,6,4,59,0,0,0,128,7,96,0,140,0,0,17,2,0,0,65,61,0,0,0,128,7,96,2,112],[0,0,7,174,8,96,0,156,0,0,0,0,7,6,160,25,0,0,7,174,8,96,0,156,0,0,0,0,8,0,0,25],[0,0,0,16,8,0,32,57,0,0,0,8,9,128,1,191,0,0,7,168,10,112,0,156,0,0,0,0,9,8,160,25],[0,0,0,64,8,112,2,112,0,0,7,168,10,112,0,156,0,0,0,0,8,7,160,25,0,0,0,4,10,144,1,191],[0,0,7,164,7,128,0,156,0,0,0,0,10,9,160,25,0,0,0,32,9,128,2,112,0,0,7,164,7,128,0,156],[0,0,0,0,9,8,160,25,0,0,0,2,7,160,1,191,0,0,255,255,8,144,0,140,0,0,0,0,7,10,160,25],[0,0,0,16,8,144,2,112,0,0,0,0,8,9,160,25,0,0,0,255,8,128,0,140,0,0,0,1,7,112,32,57],[0,0,0,32,8,0,0,138,0,0,0,65,9,112,0,57,0,0,0,0,8,137,1,111,0,0,0,0,8,133,0,25],[0,0,0,0,9,88,0,75,0,0,0,0,9,0,0,25,0,0,0,1,9,0,64,57,0,0,7,168,10,128,0,156],[0,0,4,10,0,0,33,61,0,0,0,1,9,144,1,144,0,0,4,10,0,0,193,61,0,0,0,64,0,128,4,63],[0,0,0,2,8,112,0,57,0,0,0,0,8,133,4,54,0,0,0,33,9,112,0,57,0,0,0,5,9,144,2,114],[0,0,16,51,0,0,97,61,0,0,0,0,10,33,3,79,0,0,0,0,11,0,0,25,0,0,0,5,12,176,2,16],[0,0,0,0,13,200,0,25,0,0,0,0,12,202,3,79,0,0,0,0,12,12,4,59,0,0,0,0,0,205,4,53],[0,0,0,1,11,176,0,57,0,0,0,0,12,155,0,75,0,0,16,43,0,0,65,61,0,0,0,0,9,0,0,75],[0,0,16,53,0,0,97,61,0,0,0,0,9,5,4,51,0,0,0,0,9,9,0,75,0,0,4,250,0,0,97,61],[0,0,0,0,9,8,4,51,0,0,7,173,9,144,1,151,0,0,0,248,10,112,2,16,0,0,0,0,9,154,1,159],[0,0,7,175,9,144,0,65,0,0,0,0,0,152,4,53,0,0,0,3,7,112,2,16,0,0,0,248,7,112,0,137],[0,0,0,0,6,118,1,207,0,0,0,255,7,112,0,140,0,0,0,0,6,0,32,25,0,0,0,33,7,80,0,57],[0,0,17,18,0,0,1,61,0,0,7,172,1,48,0,156,0,0,4,10,0,0,33,61,0,0,0,64,1,48,0,57],[0,0,0,64,0,16,4,63,0,0,0,1,1,0,0,58,0,0,0,0,5,19,4,54,0,0,0,0,2,0,0,49],[0,0,0,17,1,0,3,103,0,0,0,0,6,33,3,79,0,0,0,0,6,6,4,59,0,0,0,0,0,101,4,53],[0,0,4,250,0,0,97,61,0,0,0,248,7,64,2,16,0,0,7,169,8,0,0,65,0,0,0,0,4,4,0,75],[0,0,0,0,8,7,192,25,0,0,7,173,4,96,1,151,0,0,0,0,4,132,1,159,0,0,0,0,0,69,4,53],[0,0,0,64,5,0,4,61,0,0,0,12,4,0,0,41,0,0,1,4,4,64,0,57,0,0,0,0,6,65,3,79],[0,0,0,0,6,6,4,59,0,0,0,128,7,96,0,140,0,0,17,95,0,0,65,61,0,0,0,128,7,96,2,112],[0,0,7,174,8,96,0,156,0,0,0,0,7,6,160,25,0,0,7,174,8,96,0,156,0,0,0,0,8,0,0,25],[0,0,0,16,8,0,32,57,0,0,0,8,9,128,1,191,0,0,7,168,10,112,0,156,0,0,0,0,9,8,160,25],[0,0,0,64,8,112,2,112,0,0,7,168,10,112,0,156,0,0,0,0,8,7,160,25,0,0,0,4,10,144,1,191],[0,0,7,164,7,128,0,156,0,0,0,0,10,9,160,25,0,0,0,32,9,128,2,112,0,0,7,164,7,128,0,156],[0,0,0,0,9,8,160,25,0,0,0,2,7,160,1,191,0,0,255,255,8,144,0,140,0,0,0,0,7,10,160,25],[0,0,0,16,8,144,2,112,0,0,0,0,8,9,160,25,0,0,0,255,8,128,0,140,0,0,0,1,7,112,32,57],[0,0,0,32,8,0,0,138,0,0,0,65,9,112,0,57,0,0,0,0,8,137,1,111,0,0,0,0,8,133,0,25],[0,0,0,0,9,88,0,75,0,0,0,0,9,0,0,25,0,0,0,1,9,0,64,57,0,0,7,168,10,128,0,156],[0,0,4,10,0,0,33,61,0,0,0,1,9,144,1,144,0,0,4,10,0,0,193,61,0,0,0,64,0,128,4,63],[0,0,0,2,8,112,0,57,0,0,0,0,8,133,4,54,0,0,0,33,9,112,0,57,0,0,0,5,9,144,2,114],[0,0,16,147,0,0,97,61,0,0,0,0,10,33,3,79,0,0,0,0,11,0,0,25,0,0,0,5,12,176,2,16],[0,0,0,0,13,200,0,25,0,0,0,0,12,202,3,79,0,0,0,0,12,12,4,59,0,0,0,0,0,205,4,53],[0,0,0,1,11,176,0,57,0,0,0,0,12,155,0,75,0,0,16,139,0,0,65,61,0,0,0,0,9,0,0,75],[0,0,16,149,0,0,97,61,0,0,0,0,9,5,4,51,0,0,0,0,9,9,0,75,0,0,4,250,0,0,97,61],[0,0,0,0,9,8,4,51,0,0,7,173,9,144,1,151,0,0,0,248,10,112,2,16,0,0,0,0,9,154,1,159],[0,0,7,175,9,144,0,65,0,0,0,0,0,152,4,53,0,0,0,3,7,112,2,16,0,0,0,248,7,112,0,137],[0,0,0,0,6,118,1,207,0,0,0,255,7,112,0,140,0,0,0,0,6,0,32,25,0,0,0,33,7,80,0,57],[0,0,17,111,0,0,1,61,0,0,7,172,6,48,0,156,0,0,4,10,0,0,33,61,0,0,0,64,6,48,0,57],[0,0,0,64,0,96,4,63,0,0,0,0,7,18,3,79,0,0,0,1,6,0,0,58,0,0,0,0,6,99,4,54],[0,0,0,0,7,7,4,59,0,0,0,0,0,118,4,53,0,0,4,250,0,0,97,61,0,0,0,248,8,80,2,16],[0,0,7,169,9,0,0,65,0,0,0,0,5,5,0,75,0,0,0,0,9,8,192,25,0,0,7,173,5,112,1,151],[0,0,0,0,5,149,1,159,0,0,0,0,0,86,4,53,0,0,0,64,4,64,0,138,0,0,0,0,5,66,3,79],[0,0,0,64,4,0,4,61,0,0,0,0,5,5,4,59,0,0,0,128,6,80,0,140,0,0,17,188,0,0,65,61],[0,0,0,128,6,80,2,112,0,0,7,174,7,80,0,156,0,0,0,0,6,5,160,25,0,0,7,174,7,80,0,156],[0,0,0,0,7,0,0,25,0,0,0,16,7,0,32,57,0,0,0,8,8,112,1,191,0,0,7,168,9,96,0,156],[0,0,0,0,8,7,160,25,0,0,0,64,7,96,2,112,0,0,7,168,9,96,0,156,0,0,0,0,7,6,160,25],[0,0,0,4,9,128,1,191,0,0,7,164,6,112,0,156,0,0,0,0,9,8,160,25,0,0,0,32,8,112,2,112],[0,0,7,164,6,112,0,156,0,0,0,0,8,7,160,25,0,0,0,2,6,144,1,191,0,0,255,255,7,128,0,140],[0,0,0,0,6,9,160,25,0,0,0,16,7,128,2,112,0,0,0,0,7,8,160,25,0,0,0,255,7,112,0,140],[0,0,0,1,6,96,32,57,0,0,0,32,7,0,0,138,0,0,0,65,8,96,0,57,0,0,0,0,7,120,1,111],[0,0,0,0,7,116,0,25,0,0,0,0,8,71,0,75,0,0,0,0,8,0,0,25,0,0,0,1,8,0,64,57],[0,0,7,168,9,112,0,156,0,0,4,10,0,0,33,61,0,0,0,1,8,128,1,144,0,0,4,10,0,0,193,61],[0,0,0,64,0,112,4,63,0,0,0,2,7,96,0,57,0,0,0,0,7,116,4,54,0,0,0,33,8,96,0,57],[0,0,0,5,8,128,2,114,0,0,16,240,0,0,97,61,0,0,0,0,9,18,3,79,0,0,0,0,10,0,0,25],[0,0,0,5,11,160,2,16,0,0,0,0,12,183,0,25,0,0,0,0,11,185,3,79,0,0,0,0,11,11,4,59],[0,0,0,0,0,188,4,53,0,0,0,1,10,160,0,57,0,0,0,0,11,138,0,75,0,0,16,232,0,0,65,61],[0,0,0,0,8,0,0,75,0,0,16,242,0,0,97,61,0,0,0,0,8,4,4,51,0,0,0,0,8,8,0,75],[0,0,4,250,0,0,97,61,0,0,0,0,8,7,4,51,0,0,7,173,8,128,1,151,0,0,0,248,9,96,2,16],[0,0,0,0,8,137,1,159,0,0,7,175,8,128,0,65,0,0,0,0,0,135,4,53,0,0,0,3,6,96,2,16],[0,0,0,248,6,96,0,137,0,0,0,0,5,101,1,207,0,0,0,255,6,96,0,140,0,0,0,0,5,0,32,25],[0,0,0,33,6,64,0,57,0,0,17,204,0,0,1,61,0,0,7,172,7,80,0,156,0,0,4,10,0,0,33,61],[0,0,0,64,7,80,0,57,0,0,0,64,0,112,4,63,0,0,0,0,8,33,3,79,0,0,0,1,7,0,0,58],[0,0,0,0,7,117,4,54,0,0,0,0,8,8,4,59,0,0,0,0,0,135,4,53,0,0,4,250,0,0,97,61],[0,0,0,248,9,96,2,16,0,0,7,169,10,0,0,65,0,0,0,0,6,6,0,75,0,0,0,0,10,9,192,25],[0,0,7,173,6,128,1,151,0,0,0,0,6,166,1,159,0,0,0,0,0,103,4,53,0,0,0,64,6,0,4,61],[0,0,0,96,4,64,0,138,0,0,0,0,7,65,3,79,0,0,0,0,7,7,4,59,0,0,0,128,8,112,0,140],[0,0,18,92,0,0,65,61,0,0,0,128,8,112,2,112,0,0,7,174,9,112,0,156,0,0,0,0,8,7,160,25],[0,0,7,174,9,112,0,156,0,0,0,0,9,0,0,25,0,0,0,16,9,0,32,57,0,0,0,8,10,144,1,191],[0,0,7,168,11,128,0,156,0,0,0,0,10,9,160,25,0,0,0,64,9,128,2,112,0,0,7,168,11,128,0,156],[0,0,0,0,9,8,160,25,0,0,0,4,11,160,1,191,0,0,7,164,8,144,0,156,0,0,0,0,11,10,160,25],[0,0,0,32,10,144,2,112,0,0,7,164,8,144,0,156,0,0,0,0,10,9,160,25,0,0,0,2,8,176,1,191],[0,0,255,255,9,160,0,140,0,0,0,0,8,11,160,25,0,0,0,16,9,160,2,112,0,0,0,0,9,10,160,25],[0,0,0,255,9,144,0,140,0,0,0,1,8,128,32,57,0,0,0,32,9,0,0,138,0,0,0,65,10,128,0,57],[0,0,0,0,9,154,1,111,0,0,0,0,9,150,0,25,0,0,0,0,10,105,0,75,0,0,0,0,10,0,0,25],[0,0,0,1,10,0,64,57,0,0,7,168,11,144,0,156,0,0,4,10,0,0,33,61,0,0,0,1,10,160,1,144],[0,0,4,10,0,0,193,61,0,0,0,64,0,144,4,63,0,0,0,2,9,128,0,57,0,0,0,0,9,150,4,54],[0,0,0,33,10,128,0,57,0,0,0,5,10,160,2,114,0,0,17,77,0,0,97,61,0,0,0,0,11,33,3,79],[0,0,0,0,12,0,0,25,0,0,0,5,13,192,2,16,0,0,0,0,14,217,0,25,0,0,0,0,13,219,3,79],[0,0,0,0,13,13,4,59,0,0,0,0,0,222,4,53,0,0,0,1,12,192,0,57,0,0,0,0,13,172,0,75],[0,0,17,69,0,0,65,61,0,0,0,0,10,0,0,75,0,0,17,79,0,0,97,61,0,0,0,0,10,6,4,51],[0,0,0,0,10,10,0,75,0,0,4,250,0,0,97,61,0,0,0,0,10,9,4,51,0,0,7,173,10,160,1,151],[0,0,0,248,11,128,2,16,0,0,0,0,10,171,1,159,0,0,7,175,10,160,0,65,0,0,0,0,0,169,4,53],[0,0,0,3,8,128,2,16,0,0,0,248,8,128,0,137,0,0,0,0,7,135,1,207,0,0,0,255,8,128,0,140],[0,0,0,0,7,0,32,25,0,0,0,33,8,96,0,57,0,0,18,108,0,0,1,61,0,0,7,172,7,80,0,156],[0,0,4,10,0,0,33,61,0,0,0,64,7,80,0,57,0,0,0,64,0,112,4,63,0,0,0,0,8,33,3,79],[0,0,0,1,7,0,0,58,0,0,0,0,7,117,4,54,0,0,0,0,8,8,4,59,0,0,0,0,0,135,4,53],[0,0,4,250,0,0,97,61,0,0,0,248,9,96,2,16,0,0,7,169,10,0,0,65,0,0,0,0,6,6,0,75],[0,0,0,0,10,9,192,25,0,0,7,173,6,128,1,151,0,0,0,0,6,166,1,159,0,0,0,0,0,103,4,53],[0,0,0,64,6,0,4,61,0,0,0,64,4,64,0,138,0,0,0,0,7,65,3,79,0,0,0,0,7,7,4,59],[0,0,0,128,8,112,0,140,0,0,18,185,0,0,65,61,0,0,0,128,8,112,2,112,0,0,7,174,9,112,0,156],[0,0,0,0,8,7,160,25,0,0,7,174,9,112,0,156,0,0,0,0,9,0,0,25,0,0,0,16,9,0,32,57],[0,0,0,8,10,144,1,191,0,0,7,168,11,128,0,156,0,0,0,0,10,9,160,25,0,0,0,64,9,128,2,112],[0,0,7,168,11,128,0,156,0,0,0,0,9,8,160,25,0,0,0,4,11,160,1,191,0,0,7,164,8,144,0,156],[0,0,0,0,11,10,160,25,0,0,0,32,10,144,2,112,0,0,7,164,8,144,0,156,0,0,0,0,10,9,160,25],[0,0,0,2,8,176,1,191,0,0,255,255,9,160,0,140,0,0,0,0,8,11,160,25,0,0,0,16,9,160,2,112],[0,0,0,0,9,10,160,25,0,0,0,255,9,144,0,140,0,0,0,1,8,128,32,57,0,0,0,32,9,0,0,138],[0,0,0,65,10,128,0,57,0,0,0,0,9,154,1,111,0,0,0,0,9,150,0,25,0,0,0,0,10,105,0,75],[0,0,0,0,10,0,0,25,0,0,0,1,10,0,64,57,0,0,7,168,11,144,0,156,0,0,4,10,0,0,33,61],[0,0,0,1,10,160,1,144,0,0,4,10,0,0,193,61,0,0,0,64,0,144,4,63,0,0,0,2,9,128,0,57],[0,0,0,0,9,150,4,54,0,0,0,33,10,128,0,57,0,0,0,5,10,160,2,114,0,0,17,170,0,0,97,61],[0,0,0,0,11,33,3,79,0,0,0,0,12,0,0,25,0,0,0,5,13,192,2,16,0,0,0,0,14,217,0,25],[0,0,0,0,13,219,3,79,0,0,0,0,13,13,4,59,0,0,0,0,0,222,4,53,0,0,0,1,12,192,0,57],[0,0,0,0,13,172,0,75,0,0,17,162,0,0,65,61,0,0,0,0,10,0,0,75,0,0,17,172,0,0,97,61],[0,0,0,0,10,6,4,51,0,0,0,0,10,10,0,75,0,0,4,250,0,0,97,61,0,0,0,0,10,9,4,51],[0,0,7,173,10,160,1,151,0,0,0,248,11,128,2,16,0,0,0,0,10,171,1,159,0,0,7,175,10,160,0,65],[0,0,0,0,0,169,4,53,0,0,0,3,8,128,2,16,0,0,0,248,8,128,0,137,0,0,0,0,7,135,1,207],[0,0,0,255,8,128,0,140,0,0,0,0,7,0,32,25,0,0,0,33,8,96,0,57,0,0,18,201,0,0,1,61],[0,0,7,172,6,64,0,156,0,0,4,10,0,0,33,61,0,0,0,64,6,64,0,57,0,0,0,64,0,96,4,63],[0,0,0,0,7,18,3,79,0,0,0,1,6,0,0,58,0,0,0,0,6,100,4,54,0,0,0,0,7,7,4,59],[0,0,0,0,0,118,4,53,0,0,4,250,0,0,97,61,0,0,0,248,8,80,2,16,0,0,7,169,9,0,0,65],[0,0,0,0,5,5,0,75,0,0,0,0,9,8,192,25,0,0,7,173,5,112,1,151,0,0,0,0,5,149,1,159],[0,0,0,0,0,86,4,53,0,0,0,64,5,0,4,61,0,9,0,0,0,5,0,29,0,0,0,32,5,80,0,57],[0,0,0,0,6,3,4,51,0,0,0,0,7,6,0,75,0,0,17,219,0,0,97,61,0,0,0,0,7,0,0,25],[0,0,0,0,8,87,0,25,0,0,0,32,7,112,0,57,0,0,0,0,9,55,0,25,0,0,0,0,9,9,4,51],[0,0,0,0,0,152,4,53,0,0,0,0,8,103,0,75,0,0,17,212,0,0,65,61,0,0,0,0,3,86,0,25],[0,0,0,0,0,3,4,53,0,0,0,0,5,4,4,51,0,0,0,0,6,5,0,75,0,0,17,232,0,0,97,61],[0,0,0,0,6,0,0,25,0,0,0,0,7,54,0,25,0,0,0,32,6,96,0,57,0,0,0,0,8,70,0,25],[0,0,0,0,8,8,4,51,0,0,0,0,0,135,4,53,0,0,0,0,7,86,0,75,0,0,17,225,0,0,65,61],[0,0,0,0,3,53,0,25,0,0,0,0,0,3,4,53,0,0,0,9,5,0,0,41,0,0,0,0,3,83,0,73],[0,0,0,32,4,48,0,138,0,0,0,0,0,69,4,53,0,0,0,31,3,48,0,57,0,7,0,32,0,0,0,146],[0,0,0,7,3,48,1,127,0,0,0,0,4,83,0,25,0,0,0,0,3,52,0,75,0,0,0,0,3,0,0,25],[0,0,0,1,3,0,64,57,0,8,0,0,0,4,0,29,0,0,7,168,4,64,0,156,0,0,4,10,0,0,33,61],[0,0,0,1,3,48,1,144,0,0,4,10,0,0,193,61,0,0,0,8,3,0,0,41,0,0,0,64,0,48,4,63],[0,0,7,172,3,48,0,156,0,0,4,10,0,0,33,61,0,0,0,12,6,0,0,41,0,0,0,68,3,96,0,57],[0,0,0,0,3,50,3,79,0,0,0,0,3,3,4,59,0,0,0,8,7,0,0,41,0,0,0,64,4,112,0,57],[0,0,0,64,0,64,4,63,0,0,0,32,4,112,0,57,0,0,7,176,5,0,0,65,0,0,0,0,0,84,4,53],[0,0,0,21,4,0,0,57,0,0,0,0,0,71,4,53,0,0,0,96,3,48,2,16,0,0,0,33,4,112,0,57],[0,0,0,0,0,52,4,53,0,0,1,36,3,96,0,57,0,0,0,0,4,50,3,79,0,0,0,64,5,0,4,61],[0,6,0,0,0,5,0,29,0,0,0,0,4,4,4,59,0,0,0,128,5,64,0,140,0,0,19,228,0,0,65,61],[0,0,0,128,5,64,2,112,0,0,7,174,6,64,0,156,0,0,0,0,5,4,160,25,0,0,7,174,6,64,0,156],[0,0,0,0,6,0,0,25,0,0,0,16,6,0,32,57,0,0,0,8,7,96,1,191,0,0,7,168,8,80,0,156],[0,0,0,0,7,6,160,25,0,0,0,64,6,80,2,112,0,0,7,168,8,80,0,156,0,0,0,0,6,5,160,25],[0,0,0,4,8,112,1,191,0,0,7,164,5,96,0,156,0,0,0,0,8,7,160,25,0,0,0,32,7,96,2,112],[0,0,7,164,5,96,0,156,0,0,0,0,7,6,160,25,0,0,0,2,5,128,1,191,0,0,255,255,6,112,0,140],[0,0,0,0,5,8,160,25,0,0,0,16,6,112,2,112,0,0,0,0,6,7,160,25,0,0,0,255,6,96,0,140],[0,0,0,1,5,80,32,57,0,0,0,65,6,80,0,57,0,0,0,7,6,96,1,127,0,0,0,6,6,96,0,41],[0,0,0,6,7,96,0,108,0,0,0,0,7,0,0,25,0,0,0,1,7,0,64,57,0,0,7,168,8,96,0,156],[0,0,4,10,0,0,33,61,0,0,0,1,7,112,1,144,0,0,4,10,0,0,193,61,0,0,0,64,0,96,4,63],[0,0,0,2,6,80,0,57,0,0,0,6,7,0,0,41,0,0,0,0,6,103,4,54,0,0,0,33,7,80,0,57],[0,0,0,5,7,112,2,114,0,0,18,72,0,0,97,61,0,0,0,0,8,18,3,79,0,0,0,0,9,0,0,25],[0,0,0,5,10,144,2,16,0,0,0,0,11,166,0,25,0,0,0,0,10,168,3,79,0,0,0,0,10,10,4,59],[0,0,0,0,0,171,4,53,0,0,0,1,9,144,0,57,0,0,0,0,10,121,0,75,0,0,18,64,0,0,65,61],[0,0,0,0,7,0,0,75,0,0,18,74,0,0,97,61,0,0,0,6,7,0,0,41,0,0,0,0,7,7,4,51],[0,0,0,0,7,7,0,75,0,0,4,250,0,0,97,61,0,0,0,0,7,6,4,51,0,0,7,173,7,112,1,151],[0,0,0,248,8,80,2,16,0,0,0,0,7,120,1,159,0,0,7,175,7,112,0,65,0,0,0,0,0,118,4,53],[0,0,0,3,5,80,2,16,0,0,0,248,5,80,0,137,0,0,0,0,4,84,1,207,0,0,0,255,5,80,0,140],[0,0,0,0,4,0,32,25,0,0,0,6,5,0,0,41,0,0,0,33,5,80,0,57,0,0,19,246,0,0,1,61],[0,0,7,172,8,96,0,156,0,0,4,10,0,0,33,61,0,0,0,64,8,96,0,57,0,0,0,64,0,128,4,63],[0,0,0,0,9,33,3,79,0,0,0,1,8,0,0,58,0,0,0,0,8,134,4,54,0,0,0,0,9,9,4,59],[0,0,0,0,0,152,4,53,0,0,4,250,0,0,97,61,0,0,0,248,10,112,2,16,0,0,7,169,11,0,0,65],[0,0,0,0,7,7,0,75,0,0,0,0,11,10,192,25,0,0,7,173,7,144,1,151,0,0,0,0,7,183,1,159],[0,0,0,0,0,120,4,53,0,0,0,64,7,0,4,61,0,0,0,64,4,64,0,138,0,0,0,0,8,65,3,79],[0,0,0,0,8,8,4,59,0,0,0,128,9,128,0,140,0,0,19,22,0,0,65,61,0,0,0,128,9,128,2,112],[0,0,7,174,10,128,0,156,0,0,0,0,9,8,160,25,0,0,7,174,10,128,0,156,0,0,0,0,10,0,0,25],[0,0,0,16,10,0,32,57,0,0,0,8,11,160,1,191,0,0,7,168,12,144,0,156,0,0,0,0,11,10,160,25],[0,0,0,64,10,144,2,112,0,0,7,168,12,144,0,156,0,0,0,0,10,9,160,25,0,0,0,4,12,176,1,191],[0,0,7,164,9,160,0,156,0,0,0,0,12,11,160,25,0,0,0,32,11,160,2,112,0,0,7,164,9,160,0,156],[0,0,0,0,11,10,160,25,0,0,0,2,9,192,1,191,0,0,255,255,10,176,0,140,0,0,0,0,9,12,160,25],[0,0,0,16,10,176,2,112,0,0,0,0,10,11,160,25,0,0,0,255,10,160,0,140,0,0,0,1,9,144,32,57],[0,0,0,32,10,0,0,138,0,0,0,65,11,144,0,57,0,0,0,0,10,171,1,111,0,0,0,0,10,167,0,25],[0,0,0,0,11,122,0,75,0,0,0,0,11,0,0,25,0,0,0,1,11,0,64,57,0,0,7,168,12,160,0,156],[0,0,4,10,0,0,33,61,0,0,0,1,11,176,1,144,0,0,4,10,0,0,193,61,0,0,0,64,0,160,4,63],[0,0,0,2,10,144,0,57,0,0,0,0,10,167,4,54,0,0,0,33,11,144,0,57,0,0,0,5,11,176,2,114],[0,0,18,167,0,0,97,61,0,0,0,0,12,33,3,79,0,0,0,0,13,0,0,25,0,0,0,5,14,208,2,16],[0,0,0,0,15,234,0,25,0,0,0,0,14,236,3,79,0,0,0,0,14,14,4,59,0,0,0,0,0,239,4,53],[0,0,0,1,13,208,0,57,0,0,0,0,14,189,0,75,0,0,18,159,0,0,65,61,0,0,0,0,11,0,0,75],[0,0,18,169,0,0,97,61,0,0,0,0,11,7,4,51,0,0,0,0,11,11,0,75,0,0,4,250,0,0,97,61],[0,0,0,0,11,10,4,51,0,0,7,173,11,176,1,151,0,0,0,248,12,144,2,16,0,0,0,0,11,188,1,159],[0,0,7,175,11,176,0,65,0,0,0,0,0,186,4,53,0,0,0,3,9,144,2,16,0,0,0,248,9,144,0,137],[0,0,0,0,8,152,1,207,0,0,0,255,9,144,0,140,0,0,0,0,8,0,32,25,0,0,0,33,9,112,0,57],[0,0,19,38,0,0,1,61,0,0,7,172,8,96,0,156,0,0,4,10,0,0,33,61,0,0,0,64,8,96,0,57],[0,0,0,64,0,128,4,63,0,0,0,0,9,33,3,79,0,0,0,1,8,0,0,58,0,0,0,0,8,134,4,54],[0,0,0,0,9,9,4,59,0,0,0,0,0,152,4,53,0,0,4,250,0,0,97,61,0,0,0,248,10,112,2,16],[0,0,7,169,11,0,0,65,0,0,0,0,7,7,0,75,0,0,0,0,11,10,192,25,0,0,7,173,7,144,1,151],[0,0,0,0,7,183,1,159,0,0,0,0,0,120,4,53,0,0,0,64,7,0,4,61,0,0,0,32,4,64,0,138],[0,0,0,0,8,65,3,79,0,0,0,0,8,8,4,59,0,0,0,128,9,128,0,140,0,0,19,134,0,0,65,61],[0,0,0,128,9,128,2,112,0,0,7,174,10,128,0,156,0,0,0,0,9,8,160,25,0,0,7,174,10,128,0,156],[0,0,0,0,10,0,0,25,0,0,0,16,10,0,32,57,0,0,0,8,11,160,1,191,0,0,7,168,12,144,0,156],[0,0,0,0,11,10,160,25,0,0,0,64,10,144,2,112,0,0,7,168,12,144,0,156,0,0,0,0,10,9,160,25],[0,0,0,4,12,176,1,191,0,0,7,164,9,160,0,156,0,0,0,0,12,11,160,25,0,0,0,32,11,160,2,112],[0,0,7,164,9,160,0,156,0,0,0,0,11,10,160,25,0,0,0,2,9,192,1,191,0,0,255,255,10,176,0,140],[0,0,0,0,9,12,160,25,0,0,0,16,10,176,2,112,0,0,0,0,10,11,160,25,0,0,0,255,10,160,0,140],[0,0,0,1,9,144,32,57,0,0,0,32,10,0,0,138,0,0,0,65,11,144,0,57,0,0,0,0,10,171,1,111],[0,0,0,0,10,167,0,25,0,0,0,0,11,122,0,75,0,0,0,0,11,0,0,25,0,0,0,1,11,0,64,57],[0,0,7,168,12,160,0,156,0,0,4,10,0,0,33,61,0,0,0,1,11,176,1,144,0,0,4,10,0,0,193,61],[0,0,0,64,0,160,4,63,0,0,0,2,10,144,0,57,0,0,0,0,10,167,4,54,0,0,0,33,11,144,0,57],[0,0,0,5,11,176,2,114,0,0,19,4,0,0,97,61,0,0,0,0,12,33,3,79,0,0,0,0,13,0,0,25],[0,0,0,5,14,208,2,16,0,0,0,0,15,234,0,25,0,0,0,0,14,236,3,79,0,0,0,0,14,14,4,59],[0,0,0,0,0,239,4,53,0,0,0,1,13,208,0,57,0,0,0,0,14,189,0,75,0,0,18,252,0,0,65,61],[0,0,0,0,11,0,0,75,0,0,19,6,0,0,97,61,0,0,0,0,11,7,4,51,0,0,0,0,11,11,0,75],[0,0,4,250,0,0,97,61,0,0,0,0,11,10,4,51,0,0,7,173,11,176,1,151,0,0,0,248,12,144,2,16],[0,0,0,0,11,188,1,159,0,0,7,175,11,176,0,65,0,0,0,0,0,186,4,53,0,0,0,3,9,144,2,16],[0,0,0,248,9,144,0,137,0,0,0,0,8,152,1,207,0,0,0,255,9,144,0,140,0,0,0,0,8,0,32,25],[0,0,0,33,9,112,0,57,0,0,19,150,0,0,1,61,0,0,7,172,9,112,0,156,0,0,4,10,0,0,33,61],[0,0,0,64,9,112,0,57,0,0,0,64,0,144,4,63,0,0,0,0,10,33,3,79,0,0,0,1,9,0,0,58],[0,0,0,0,9,151,4,54,0,0,0,0,10,10,4,59,0,0,0,0,0,169,4,53,0,0,4,250,0,0,97,61],[0,0,0,248,11,128,2,16,0,0,7,169,12,0,0,65,0,0,0,0,8,8,0,75,0,0,0,0,12,11,192,25],[0,0,7,173,8,160,1,151,0,0,0,0,8,200,1,159,0,0,0,0,0,137,4,53,0,0,0,64,9,0,4,61],[0,0,7,172,8,144,0,156,0,0,4,10,0,0,33,61,0,0,0,32,8,64,0,138,0,0,0,0,8,129,3,79],[0,0,0,0,8,8,4,59,0,0,0,64,10,144,0,57,0,0,0,64,0,160,4,63,0,0,0,32,10,144,0,57],[0,0,7,176,11,0,0,65,0,0,0,0,0,186,4,53,0,0,0,21,10,0,0,57,0,0,0,0,0,169,4,53],[0,0,0,96,8,128,2,16,0,0,0,33,10,144,0,57,0,0,0,0,0,138,4,53,0,0,0,192,4,64,0,57],[0,0,0,0,4,65,3,79,0,0,0,64,8,0,4,61,0,0,0,0,4,4,4,59,0,9,0,0,0,4,0,29],[0,0,0,128,10,64,0,140,0,0,20,177,0,0,65,61,0,0,0,9,4,0,0,41,0,0,0,128,10,64,2,112],[0,0,7,174,11,64,0,156,0,0,0,0,10,4,160,25,0,0,7,174,11,64,0,156,0,0,0,0,11,0,0,25],[0,0,0,16,11,0,32,57,0,0,0,8,12,176,1,191,0,0,7,168,13,160,0,156,0,0,0,0,12,11,160,25],[0,0,0,64,11,160,2,112,0,0,7,168,13,160,0,156,0,0,0,0,11,10,160,25,0,0,0,4,13,192,1,191],[0,0,7,164,10,176,0,156,0,0,0,0,13,12,160,25,0,0,0,32,12,176,2,112,0,0,7,164,10,176,0,156],[0,0,0,0,12,11,160,25,0,0,0,2,10,208,1,191,0,0,255,255,11,192,0,140,0,0,0,0,10,13,160,25],[0,0,0,16,11,192,2,112,0,0,0,0,11,12,160,25,0,0,0,255,11,176,0,140,0,0,0,1,10,160,32,57],[0,0,0,32,11,0,0,138,0,0,0,65,12,160,0,57,0,0,0,0,11,188,1,111,0,0,0,0,11,184,0,25],[0,0,0,0,12,139,0,75,0,0,0,0,12,0,0,25,0,0,0,1,12,0,64,57,0,0,7,168,13,176,0,156],[0,0,4,10,0,0,33,61,0,0,0,1,12,192,1,144,0,0,4,10,0,0,193,61,0,0,0,64,0,176,4,63],[0,0,0,2,11,160,0,57,0,0,0,0,11,184,4,54,0,0,0,33,12,160,0,57,0,0,0,5,12,192,2,114],[0,0,19,115,0,0,97,61,0,0,0,0,13,33,3,79,0,0,0,0,14,0,0,25,0,0,0,5,15,224,2,16],[0,0,0,0,4,251,0,25,0,0,0,0,15,253,3,79,0,0,0,0,15,15,4,59,0,0,0,0,0,244,4,53],[0,0,0,1,14,224,0,57,0,0,0,0,4,206,0,75,0,0,19,107,0,0,65,61,0,0,0,0,4,0,0,75],[0,0,19,117,0,0,97,61,0,0,0,0,4,8,4,51,0,0,0,0,4,4,0,75,0,0,4,250,0,0,97,61],[0,0,0,0,4,11,4,51,0,0,7,173,4,64,1,151,0,0,0,248,12,160,2,16,0,0,0,0,4,76,1,159],[0,0,7,175,4,64,0,65,0,0,0,0,0,75,4,53,0,0,0,3,4,160,2,16,0,0,0,248,4,64,0,137],[0,0,0,9,10,64,1,239,0,0,0,255,4,64,0,140,0,0,0,0,10,0,32,25,0,0,0,33,4,128,0,57],[0,0,0,0,0,164,4,53,0,0,20,195,0,0,1,61,0,0,7,172,9,112,0,156,0,0,4,10,0,0,33,61],[0,0,0,64,9,112,0,57,0,0,0,64,0,144,4,63,0,0,0,0,10,33,3,79,0,0,0,1,9,0,0,58],[0,0,0,0,9,151,4,54,0,0,0,0,10,10,4,59,0,0,0,0,0,169,4,53,0,0,4,250,0,0,97,61],[0,0,0,248,11,128,2,16,0,0,7,169,12,0,0,65,0,0,0,0,8,8,0,75,0,0,0,0,12,11,192,25],[0,0,7,173,8,160,1,151,0,0,0,0,8,200,1,159,0,0,0,0,0,137,4,53,0,0,0,64,8,0,4,61],[0,9,0,64,0,64,0,146,0,0,0,9,9,16,3,96,0,0,0,0,9,9,4,59,0,0,0,128,10,144,0,140],[0,0,20,61,0,0,65,61,0,0,0,128,10,144,2,112,0,0,7,174,11,144,0,156,0,0,0,0,10,9,160,25],[0,0,7,174,11,144,0,156,0,0,0,0,11,0,0,25,0,0,0,16,11,0,32,57,0,0,0,8,12,176,1,191],[0,0,7,168,13,160,0,156,0,0,0,0,12,11,160,25,0,0,0,64,11,160,2,112,0,0,7,168,13,160,0,156],[0,0,0,0,11,10,160,25,0,0,0,4,13,192,1,191,0,0,7,164,10,176,0,156,0,0,0,0,13,12,160,25],[0,0,0,32,12,176,2,112,0,0,7,164,10,176,0,156,0,0,0,0,12,11,160,25,0,0,0,2,10,208,1,191],[0,0,255,255,11,192,0,140,0,0,0,0,10,13,160,25,0,0,0,16,11,192,2,112,0,0,0,0,11,12,160,25],[0,0,0,255,11,176,0,140,0,0,0,1,10,160,32,57,0,0,0,32,11,0,0,138,0,0,0,65,12,160,0,57],[0,0,0,0,11,188,1,111,0,0,0,0,11,184,0,25,0,0,0,0,12,139,0,75,0,0,0,0,12,0,0,25],[0,0,0,1,12,0,64,57,0,0,7,168,13,176,0,156,0,0,4,10,0,0,33,61,0,0,0,1,12,192,1,144],[0,0,4,10,0,0,193,61,0,0,0,64,0,176,4,63,0,0,0,2,11,160,0,57,0,0,0,0,11,184,4,54],[0,0,0,33,12,160,0,57,0,0,0,5,12,192,2,114,0,0,19,209,0,0,97,61,0,0,0,0,13,33,3,79],[0,0,0,0,14,0,0,25,0,0,0,5,15,224,2,16,0,0,0,0,4,251,0,25,0,0,0,0,15,253,3,79],[0,0,0,0,15,15,4,59,0,0,0,0,0,244,4,53,0,0,0,1,14,224,0,57,0,0,0,0,4,206,0,75],[0,0,19,201,0,0,65,61,0,0,0,0,4,0,0,75,0,0,19,211,0,0,97,61,0,0,0,0,4,8,4,51],[0,0,0,0,4,4,0,75,0,0,4,250,0,0,97,61,0,0,0,0,4,11,4,51,0,0,7,173,4,64,1,151],[0,0,0,248,12,160,2,16,0,0,0,0,4,76,1,159,0,0,7,175,4,64,0,65,0,0,0,0,0,75,4,53],[0,0,0,3,4,160,2,16,0,0,0,248,4,64,0,137,0,0,0,0,9,73,1,207,0,0,0,255,4,64,0,140],[0,0,0,0,9,0,32,25,0,0,0,33,4,128,0,57,0,0,0,0,0,148,4,53,0,0,20,78,0,0,1,61],[0,0,0,6,5,0,0,41,0,0,7,172,5,80,0,156,0,0,4,10,0,0,33,61,0,0,0,6,7,0,0,41],[0,0,0,64,5,112,0,57,0,0,0,64,0,80,4,63,0,0,0,0,6,18,3,79,0,0,0,1,5,0,0,58],[0,0,0,0,5,87,4,54,0,0,0,0,6,6,4,59,0,0,0,0,0,101,4,53,0,0,4,250,0,0,97,61],[0,0,0,248,7,64,2,16,0,0,7,169,8,0,0,65,0,0,0,0,4,4,0,75,0,0,0,0,8,7,192,25],[0,0,7,173,4,96,1,151,0,0,0,0,4,132,1,159,0,0,0,0,0,69,4,53,0,0,0,11,10,0,0,41],[0,0,0,0,6,161,0,73,0,0,0,160,4,48,0,57,0,0,0,0,3,66,3,79,0,0,0,0,5,3,4,59],[0,0,0,31,3,96,0,138,0,0,7,169,6,48,1,151,0,0,7,169,7,80,1,151,0,0,7,169,8,0,0,65],[0,0,0,0,9,103,0,75,0,0,0,0,9,0,0,25,0,0,0,0,9,8,64,25,0,0,0,0,6,103,1,63],[0,0,0,0,7,53,0,75,0,0,0,0,8,0,64,25,0,0,7,169,6,96,0,156,0,0,0,0,9,8,192,25],[0,0,0,0,6,9,0,75,0,0,0,204,0,0,193,61,0,0,0,0,6,165,0,25,0,0,0,0,5,98,3,79],[0,0,0,0,5,5,4,59,0,0,7,168,7,80,0,156,0,0,0,204,0,0,33,61,0,0,0,0,7,81,0,73],[0,0,0,32,6,96,0,57,0,0,7,169,8,0,0,65,0,0,0,0,9,118,0,75,0,0,0,0,9,0,0,25],[0,0,0,0,9,8,32,25,0,0,7,169,7,112,1,151,0,0,7,169,10,96,1,151,0,0,0,0,11,122,0,75],[0,0,0,0,8,0,128,25,0,0,0,0,7,122,1,63,0,0,7,169,7,112,0,156,0,0,0,0,8,9,192,25],[0,0,0,0,7,8,0,75,0,0,0,204,0,0,193,61,0,0,0,1,7,80,0,140,0,0,22,44,0,0,193,61],[0,0,0,0,5,98,3,79,0,0,0,0,5,5,4,59,0,0,0,1,6,0,0,138,0,0,7,169,7,0,0,65],[0,0,0,0,6,101,0,75,0,0,0,0,6,0,0,25,0,0,0,0,6,7,32,25,0,0,7,169,5,80,1,151],[0,0,7,169,8,80,0,156,0,0,0,0,7,0,128,25,0,0,7,169,5,80,1,103,0,0,7,169,5,80,0,156],[0,0,0,0,7,6,192,25,0,5,0,96,0,0,0,61,0,0,0,0,5,7,0,75,0,0,22,104,0,0,193,61],[0,0,0,64,5,0,4,61,0,5,0,0,0,5,0,29,0,0,7,172,5,80,0,156,0,0,4,10,0,0,33,61],[0,0,0,5,7,0,0,41,0,0,0,64,5,112,0,57,0,0,0,64,0,80,4,63,0,0,0,32,5,112,0,57],[0,0,7,175,6,0,0,65,0,0,0,0,0,101,4,53,0,0,0,1,5,0,0,57,0,0,0,0,0,87,4,53],[0,0,22,104,0,0,1,61,0,0,7,172,4,128,0,156,0,0,4,10,0,0,33,61,0,0,0,64,4,128,0,57],[0,0,0,64,0,64,4,63,0,0,0,0,4,33,3,79,0,0,0,1,10,0,0,58,0,0,0,0,10,168,4,54],[0,0,0,0,11,4,4,59,0,0,0,0,0,186,4,53,0,0,4,250,0,0,97,61,0,0,0,248,4,144,2,16],[0,0,7,169,12,0,0,65,0,0,0,0,9,9,0,75,0,0,0,0,12,4,192,25,0,0,7,173,4,176,1,151],[0,0,0,0,4,196,1,159,0,0,0,0,0,74,4,53,0,0,0,64,10,0,4,61,0,0,7,172,4,160,0,156],[0,0,4,10,0,0,33,61,0,0,0,9,12,0,0,41,0,0,0,32,4,192,0,138,0,0,0,0,4,65,3,79],[0,0,0,0,4,4,4,59,0,0,0,64,9,160,0,57,0,0,0,64,0,144,4,63,0,0,0,32,9,160,0,57],[0,0,7,176,11,0,0,65,0,0,0,0,0,185,4,53,0,0,0,21,9,0,0,57,0,0,0,0,0,154,4,53],[0,0,0,96,4,64,2,16,0,0,0,33,9,160,0,57,0,0,0,0,0,73,4,53,0,0,0,192,4,192,0,57],[0,0,0,0,4,65,3,79,0,0,0,64,9,0,4,61,0,0,0,0,4,4,4,59,0,9,0,0,0,4,0,29],[0,0,0,128,11,64,0,140,0,0,21,104,0,0,65,61,0,0,0,9,4,0,0,41,0,0,0,128,11,64,2,112],[0,0,7,174,12,64,0,156,0,0,0,0,11,4,160,25,0,0,7,174,12,64,0,156,0,0,0,0,12,0,0,25],[0,0,0,16,12,0,32,57,0,0,0,8,13,192,1,191,0,0,7,168,14,176,0,156,0,0,0,0,13,12,160,25],[0,0,0,64,12,176,2,112,0,0,7,168,14,176,0,156,0,0,0,0,12,11,160,25,0,0,0,4,14,208,1,191],[0,0,7,164,11,192,0,156,0,0,0,0,14,13,160,25,0,0,0,32,13,192,2,112,0,0,7,164,11,192,0,156],[0,0,0,0,13,12,160,25,0,0,0,2,4,224,1,191,0,0,255,255,12,208,0,140,0,0,0,0,4,14,160,25],[0,0,0,16,12,208,2,112,0,0,0,0,12,13,160,25,0,0,0,255,12,192,0,140,0,0,0,1,4,64,32,57],[0,0,0,32,12,0,0,138,0,8,0,0,0,4,0,29,0,0,0,65,13,64,0,57,0,0,0,0,12,205,1,111],[0,0,0,0,12,201,0,25,0,0,0,0,13,156,0,75,0,0,0,0,13,0,0,25,0,0,0,1,13,0,64,57],[0,0,7,168,14,192,0,156,0,0,4,10,0,0,33,61,0,0,0,1,13,208,1,144,0,0,4,10,0,0,193,61],[0,0,0,64,0,192,4,63,0,0,0,8,4,0,0,41,0,0,0,2,12,64,0,57,0,0,0,0,12,201,4,54],[0,0,0,33,13,64,0,57,0,0,0,5,13,208,2,114,0,0,20,157,0,0,97,61,0,0,0,0,14,33,3,79],[0,0,0,0,15,0,0,25,0,0,0,5,4,240,2,16,0,0,0,0,11,76,0,25,0,0,0,0,4,78,3,79],[0,0,0,0,4,4,4,59,0,0,0,0,0,75,4,53,0,0,0,1,15,240,0,57,0,0,0,0,4,223,0,75],[0,0,20,149,0,0,65,61,0,0,0,0,4,0,0,75,0,0,20,159,0,0,97,61,0,0,0,0,4,9,4,51],[0,0,0,0,4,4,0,75,0,0,4,250,0,0,97,61,0,0,0,0,4,12,4,51,0,0,7,173,4,64,1,151],[0,0,0,8,13,0,0,41,0,0,0,248,11,208,2,16,0,0,0,0,4,75,1,159,0,0,7,175,4,64,0,65],[0,0,0,0,0,76,4,53,0,0,0,3,4,208,2,16,0,0,0,248,4,64,0,137,0,0,0,9,11,64,1,239],[0,0,0,255,4,64,0,140,0,0,0,0,11,0,32,25,0,0,0,33,4,144,0,57,0,0,0,0,0,180,4,53],[0,0,21,122,0,0,1,61,0,0,7,172,4,128,0,156,0,0,4,10,0,0,33,61,0,0,0,64,4,128,0,57],[0,0,0,64,0,64,4,63,0,0,0,0,4,33,3,79,0,0,0,1,10,0,0,58,0,0,0,0,10,168,4,54],[0,0,0,0,11,4,4,59,0,0,0,0,0,186,4,53,0,0,4,250,0,0,97,61,0,0,0,9,13,0,0,41],[0,0,0,248,4,208,2,16,0,0,7,169,12,0,0,65,0,0,0,0,13,13,0,75,0,0,0,0,12,4,192,25],[0,0,7,173,4,176,1,151,0,0,0,0,4,196,1,159,0,0,0,0,0,74,4,53,0,0,0,64,4,0,4,61],[0,0,0,32,10,64,0,57,0,0,0,0,11,3,4,51,0,0,0,0,12,11,0,75,0,0,20,208,0,0,97,61],[0,0,0,0,12,0,0,25,0,0,0,0,13,172,0,25,0,0,0,32,12,192,0,57,0,0,0,0,14,60,0,25],[0,0,0,0,14,14,4,51,0,0,0,0,0,237,4,53,0,0,0,0,13,188,0,75,0,0,20,201,0,0,65,61],[0,0,0,0,3,171,0,25,0,0,0,0,0,3,4,53,0,0,0,0,10,5,4,51,0,0,0,0,11,10,0,75],[0,0,20,221,0,0,97,61,0,0,0,0,11,0,0,25,0,0,0,0,12,59,0,25,0,0,0,32,11,176,0,57],[0,0,0,0,13,91,0,25,0,0,0,0,13,13,4,51,0,0,0,0,0,220,4,53,0,0,0,0,12,171,0,75],[0,0,20,214,0,0,65,61,0,0,0,0,3,58,0,25,0,0,0,0,0,3,4,53,0,0,0,0,5,6,4,51],[0,0,0,0,10,5,0,75,0,0,20,234,0,0,97,61,0,0,0,0,10,0,0,25,0,0,0,0,11,58,0,25],[0,0,0,32,10,160,0,57,0,0,0,0,12,106,0,25,0,0,0,0,12,12,4,51,0,0,0,0,0,203,4,53],[0,0,0,0,11,90,0,75,0,0,20,227,0,0,65,61,0,0,0,0,3,53,0,25,0,0,0,0,0,3,4,53],[0,0,0,0,5,7,4,51,0,0,0,0,6,5,0,75,0,0,20,247,0,0,97,61,0,0,0,0,6,0,0,25],[0,0,0,0,10,54,0,25,0,0,0,32,6,96,0,57,0,0,0,0,11,118,0,25,0,0,0,0,11,11,4,51],[0,0,0,0,0,186,4,53,0,0,0,0,10,86,0,75,0,0,20,240,0,0,65,61,0,0,0,0,3,53,0,25],[0,0,0,0,0,3,4,53,0,0,0,0,5,9,4,51,0,0,0,0,6,5,0,75,0,0,21,4,0,0,97,61],[0,0,0,0,6,0,0,25,0,0,0,0,7,54,0,25,0,0,0,32,6,96,0,57,0,0,0,0,10,150,0,25],[0,0,0,0,10,10,4,51,0,0,0,0,0,167,4,53,0,0,0,0,7,86,0,75,0,0,20,253,0,0,65,61],[0,0,0,0,3,53,0,25,0,0,0,0,0,3,4,53,0,0,0,0,5,8,4,51,0,0,0,0,6,5,0,75],[0,0,21,17,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,0,7,54,0,25,0,0,0,32,6,96,0,57],[0,0,0,0,9,134,0,25,0,0,0,0,9,9,4,51,0,0,0,0,0,151,4,53,0,0,0,0,7,86,0,75],[0,0,21,10,0,0,65,61,0,0,0,0,3,53,0,25,0,0,0,0,0,3,4,53,0,0,0,0,3,67,0,73],[0,0,0,32,5,48,0,138,0,0,0,0,0,84,4,53,0,0,0,31,5,48,0,57,0,0,0,32,3,0,0,138],[0,0,0,0,5,53,1,111,0,0,0,0,7,69,0,25,0,0,0,0,5,87,0,75,0,0,0,0,5,0,0,25],[0,0,0,1,5,0,64,57,0,0,7,168,6,112,0,156,0,0,4,10,0,0,33,61,0,0,0,1,5,80,1,144],[0,0,4,10,0,0,193,61,0,0,0,64,0,112,4,63,0,0,0,11,12,0,0,41,0,0,0,0,6,194,0,73],[0,0,0,12,5,0,0,41,0,0,1,196,13,80,0,57,0,0,0,0,5,209,3,79,0,0,0,0,5,5,4,59],[0,0,0,31,9,96,0,138,0,0,7,169,6,144,1,151,0,0,7,169,8,80,1,151,0,0,7,169,10,0,0,65],[0,0,0,0,11,104,0,75,0,0,0,0,11,0,0,25,0,0,0,0,11,10,64,25,0,0,0,0,6,104,1,63],[0,0,0,0,8,149,0,75,0,0,0,0,10,0,64,25,0,0,7,169,6,96,0,156,0,0,0,0,11,10,192,25],[0,0,0,0,6,11,0,75,0,0,0,204,0,0,193,61,0,0,0,0,6,197,0,25,0,0,0,0,5,97,3,79],[0,0,0,0,5,5,4,59,0,0,7,168,8,80,0,156,0,0,0,204,0,0,33,61,0,0,0,0,8,82,0,73],[0,0,0,32,6,96,0,57,0,0,7,169,10,0,0,65,0,0,0,0,11,134,0,75,0,0,0,0,11,0,0,25],[0,0,0,0,11,10,32,25,0,0,7,169,8,128,1,151,0,12,0,0,0,6,0,29,0,0,7,169,12,96,1,151],[0,0,0,0,14,140,0,75,0,0,0,0,10,0,128,25,0,0,0,0,8,140,1,63,0,0,7,169,8,128,0,156],[0,0,0,0,10,11,192,25,0,0,0,0,8,10,0,75,0,0,0,204,0,0,193,61,0,0,0,1,8,80,0,140],[0,0,22,221,0,0,193,61,0,0,0,12,8,16,3,96,0,0,0,0,8,8,4,59,0,0,0,1,10,0,0,138],[0,0,7,169,11,0,0,65,0,0,0,0,10,168,0,75,0,0,0,0,10,0,0,25,0,0,0,0,10,11,32,25],[0,0,7,169,8,128,1,151,0,0,7,169,12,128,0,156,0,0,0,0,11,0,128,25,0,0,7,169,8,128,1,103],[0,0,7,169,8,128,0,156,0,0,0,0,11,10,192,25,0,0,0,96,8,0,0,57,0,0,0,0,10,11,0,75],[0,0,23,20,0,0,193,61,0,0,7,172,8,112,0,156,0,0,4,10,0,0,33,61,0,0,0,64,8,112,0,57],[0,0,0,64,0,128,4,63,0,0,0,32,8,112,0,57,0,0,7,175,10,0,0,65,0,0,0,0,0,168,4,53],[0,0,0,1,8,0,0,57,0,0,0,0,0,135,4,53,0,0,0,0,8,7,0,25,0,0,23,20,0,0,1,61],[0,0,7,172,4,144,0,156,0,0,4,10,0,0,33,61,0,0,0,64,4,144,0,57,0,0,0,64,0,64,4,63],[0,0,0,0,4,33,3,79,0,0,0,1,11,0,0,58,0,0,0,0,11,185,4,54,0,0,0,0,12,4,4,59],[0,0,0,0,0,203,4,53,0,0,4,250,0,0,97,61,0,0,0,9,14,0,0,41,0,0,0,248,4,224,2,16],[0,0,7,169,13,0,0,65,0,0,0,0,14,14,0,75,0,0,0,0,13,4,192,25,0,0,7,173,4,192,1,151],[0,0,0,0,4,212,1,159,0,0,0,0,0,75,4,53,0,0,0,64,4,0,4,61,0,0,0,32,11,64,0,57],[0,0,0,0,12,3,4,51,0,0,0,0,13,12,0,75,0,0,21,135,0,0,97,61,0,0,0,0,13,0,0,25],[0,0,0,0,14,189,0,25,0,0,0,32,13,208,0,57,0,0,0,0,15,61,0,25,0,0,0,0,15,15,4,51],[0,0,0,0,0,254,4,53,0,0,0,0,14,205,0,75,0,0,21,128,0,0,65,61,0,0,0,0,3,188,0,25],[0,0,0,0,0,3,4,53,0,0,0,0,11,5,4,51,0,0,0,0,12,11,0,75,0,0,21,148,0,0,97,61],[0,0,0,0,12,0,0,25,0,0,0,0,13,60,0,25,0,0,0,32,12,192,0,57,0,0,0,0,14,92,0,25],[0,0,0,0,14,14,4,51,0,0,0,0,0,237,4,53,0,0,0,0,13,188,0,75,0,0,21,141,0,0,65,61],[0,0,0,0,3,59,0,25,0,0,0,0,0,3,4,53,0,0,0,0,5,6,4,51,0,0,0,0,11,5,0,75],[0,0,21,161,0,0,97,61,0,0,0,0,11,0,0,25,0,0,0,0,12,59,0,25,0,0,0,32,11,176,0,57],[0,0,0,0,13,107,0,25,0,0,0,0,13,13,4,51,0,0,0,0,0,220,4,53,0,0,0,0,12,91,0,75],[0,0,21,154,0,0,65,61,0,0,0,0,3,53,0,25,0,0,0,0,0,3,4,53,0,0,0,0,5,7,4,51],[0,0,0,0,6,5,0,75,0,0,21,174,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,0,11,54,0,25],[0,0,0,32,6,96,0,57,0,0,0,0,12,118,0,25,0,0,0,0,12,12,4,51,0,0,0,0,0,203,4,53],[0,0,0,0,11,86,0,75,0,0,21,167,0,0,65,61,0,0,0,0,3,53,0,25,0,0,0,0,0,3,4,53],[0,0,0,0,5,8,4,51,0,0,0,0,6,5,0,75,0,0,21,187,0,0,97,61,0,0,0,0,6,0,0,25],[0,0,0,0,7,54,0,25,0,0,0,32,6,96,0,57,0,0,0,0,11,134,0,25,0,0,0,0,11,11,4,51],[0,0,0,0,0,183,4,53,0,0,0,0,7,86,0,75,0,0,21,180,0,0,65,61,0,0,0,0,3,53,0,25],[0,0,0,0,0,3,4,53,0,0,0,0,5,10,4,51,0,0,0,0,6,5,0,75,0,0,21,200,0,0,97,61],[0,0,0,0,6,0,0,25,0,0,0,0,7,54,0,25,0,0,0,32,6,96,0,57,0,0,0,0,8,166,0,25],[0,0,0,0,8,8,4,51,0,0,0,0,0,135,4,53,0,0,0,0,7,86,0,75,0,0,21,193,0,0,65,61],[0,0,0,0,3,53,0,25,0,0,0,0,0,3,4,53,0,0,0,0,5,9,4,51,0,0,0,0,6,5,0,75],[0,0,21,213,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,0,7,54,0,25,0,0,0,32,6,96,0,57],[0,0,0,0,8,150,0,25,0,0,0,0,8,8,4,51,0,0,0,0,0,135,4,53,0,0,0,0,7,86,0,75],[0,0,21,206,0,0,65,61,0,0,0,0,3,53,0,25,0,0,0,0,0,3,4,53,0,0,0,0,3,67,0,73],[0,0,0,32,5,48,0,138,0,0,0,0,0,84,4,53,0,0,0,31,5,48,0,57,0,0,0,32,3,0,0,138],[0,0,0,0,5,53,1,111,0,0,0,0,7,69,0,25,0,0,0,0,5,87,0,75,0,0,0,0,5,0,0,25],[0,0,0,1,5,0,64,57,0,0,7,168,6,112,0,156,0,0,4,10,0,0,33,61,0,0,0,1,5,80,1,144],[0,0,4,10,0,0,193,61,0,0,0,64,0,112,4,63,0,0,0,11,12,0,0,41,0,0,0,0,6,194,0,73],[0,0,0,12,5,0,0,41,0,0,1,196,13,80,0,57,0,0,0,0,5,209,3,79,0,0,0,0,5,5,4,59],[0,0,0,31,9,96,0,138,0,0,7,169,6,144,1,151,0,0,7,169,8,80,1,151,0,0,7,169,10,0,0,65],[0,0,0,0,11,104,0,75,0,0,0,0,11,0,0,25,0,0,0,0,11,10,64,25,0,0,0,0,6,104,1,63],[0,0,0,0,8,149,0,75,0,0,0,0,10,0,64,25,0,0,7,169,6,96,0,156,0,0,0,0,11,10,192,25],[0,0,0,0,6,11,0,75,0,0,0,204,0,0,193,61,0,0,0,0,6,197,0,25,0,0,0,0,5,97,3,79],[0,0,0,0,5,5,4,59,0,0,7,168,8,80,0,156,0,0,0,204,0,0,33,61,0,0,0,0,8,82,0,73],[0,0,0,32,6,96,0,57,0,0,7,169,10,0,0,65,0,0,0,0,11,134,0,75,0,0,0,0,11,0,0,25],[0,0,0,0,11,10,32,25,0,0,7,169,8,128,1,151,0,12,0,0,0,6,0,29,0,0,7,169,12,96,1,151],[0,0,0,0,14,140,0,75,0,0,0,0,10,0,128,25,0,0,0,0,8,140,1,63,0,0,7,169,8,128,0,156],[0,0,0,0,10,11,192,25,0,0,0,0,8,10,0,75,0,0,0,204,0,0,193,61,0,0,0,1,8,80,0,140],[0,0,24,1,0,0,193,61,0,0,0,12,8,16,3,96,0,0,0,0,8,8,4,59,0,0,0,1,10,0,0,138],[0,0,7,169,11,0,0,65,0,0,0,0,10,168,0,75,0,0,0,0,10,0,0,25,0,0,0,0,10,11,32,25],[0,0,7,169,8,128,1,151,0,0,7,169,12,128,0,156,0,0,0,0,11,0,128,25,0,0,7,169,8,128,1,103],[0,0,7,169,8,128,0,156,0,0,0,0,11,10,192,25,0,0,0,96,8,0,0,57,0,0,0,0,10,11,0,75],[0,0,24,56,0,0,193,61,0,0,7,172,8,112,0,156,0,0,4,10,0,0,33,61,0,0,0,64,8,112,0,57],[0,0,0,64,0,128,4,63,0,0,0,32,8,112,0,57,0,0,7,175,10,0,0,65,0,0,0,0,0,168,4,53],[0,0,0,1,8,0,0,57,0,0,0,0,0,135,4,53,0,0,0,0,8,7,0,25,0,0,24,56,0,0,1,61],[0,0,0,64,6,0,4,61,0,5,0,0,0,6,0,29,0,0,0,56,6,80,0,140,0,0,22,87,0,0,65,61],[0,0,0,32,7,80,2,112,0,0,7,164,6,80,0,156,0,0,0,0,7,5,160,25,0,0,7,164,6,80,0,156],[0,0,0,0,8,0,0,25,0,0,0,4,8,0,32,57,0,0,0,2,6,128,1,191,0,0,255,255,9,112,0,140],[0,0,0,0,6,8,160,25,0,0,0,16,8,112,2,112,0,0,0,0,8,7,160,25,0,0,0,255,7,128,0,140],[0,0,0,0,7,0,0,25,0,0,0,1,7,0,32,57,0,0,0,5,8,0,0,41,0,0,7,172,8,128,0,156],[0,0,4,10,0,0,33,61,0,0,0,0,6,118,1,159,0,0,0,5,9,0,0,41,0,0,0,64,7,144,0,57],[0,0,0,64,0,112,4,63,0,0,0,0,8,18,3,79,0,0,0,2,7,96,0,58,0,0,0,0,7,121,4,54],[0,0,0,0,8,8,4,59,0,0,0,0,0,135,4,53,0,0,4,250,0,0,97,61,0,0,7,173,8,128,1,151],[0,0,0,248,9,96,2,16,0,0,0,0,8,137,1,159,0,0,7,177,8,128,1,199,0,0,0,0,0,135,4,53],[0,0,0,3,6,96,2,16,0,0,0,248,6,96,1,95,0,0,0,0,5,101,1,207,0,0,0,5,6,0,0,41],[0,0,0,33,6,96,0,57,0,0,0,0,0,86,4,53,0,0,22,104,0,0,1,61,0,0,0,5,6,0,0,41],[0,0,7,172,6,96,0,156,0,0,4,10,0,0,33,61,0,0,0,5,8,0,0,41,0,0,0,64,6,128,0,57],[0,0,0,64,0,96,4,63,0,0,0,0,7,18,3,79,0,0,0,1,6,0,0,58,0,0,0,0,6,104,4,54],[0,0,0,0,7,7,4,59,0,0,0,0,0,118,4,53,0,0,4,250,0,0,97,61,0,0,0,248,5,80,2,16],[0,0,7,173,7,112,1,151,0,0,0,0,5,87,1,159,0,0,7,169,5,80,1,103,0,0,0,0,0,86,4,53],[0,0,0,32,4,64,0,57,0,0,0,0,4,66,3,79,0,0,0,0,4,4,4,59,0,0,7,169,5,0,0,65],[0,0,0,0,6,52,0,75,0,0,0,0,6,0,0,25,0,0,0,0,6,5,128,25,0,0,7,169,3,48,1,151],[0,0,7,169,7,64,1,151,0,0,0,0,8,55,0,75,0,0,0,0,5,0,128,25,0,0,0,0,3,55,1,63],[0,0,7,169,3,48,0,156,0,0,0,0,5,6,192,25,0,0,0,0,3,5,0,75,0,0,0,11,3,0,0,41],[0,0,0,204,0,0,193,61,0,0,0,0,4,52,0,25,0,0,0,0,3,66,3,79,0,0,0,0,3,3,4,59],[0,0,7,168,5,48,0,156,0,0,0,204,0,0,33,61,0,0,0,32,5,48,0,140,0,0,0,204,0,0,65,61],[0,0,0,0,5,49,0,73,0,0,0,32,4,64,0,57,0,0,7,169,6,0,0,65,0,0,0,0,7,84,0,75],[0,0,0,0,7,0,0,25,0,0,0,0,7,6,32,25,0,0,7,169,5,80,1,151,0,0,7,169,8,64,1,151],[0,0,0,0,9,88,0,75,0,0,0,0,6,0,128,25,0,0,0,0,5,88,1,63,0,0,7,169,5,80,0,156],[0,0,0,0,6,7,192,25,0,0,0,0,5,6,0,75,0,0,0,204,0,0,193,61,0,0,0,0,5,66,3,79],[0,0,0,64,6,0,4,61,0,4,0,0,0,6,0,29,0,0,0,0,5,5,4,59,0,0,0,128,6,80,0,140],[0,0,23,157,0,0,65,61,0,0,0,128,6,80,2,112,0,0,7,174,7,80,0,156,0,0,0,0,6,5,160,25],[0,0,7,174,7,80,0,156,0,0,0,0,7,0,0,25,0,0,0,16,7,0,32,57,0,0,0,8,8,112,1,191],[0,0,7,168,9,96,0,156,0,0,0,0,8,7,160,25,0,0,0,64,7,96,2,112,0,0,7,168,9,96,0,156],[0,0,0,0,7,6,160,25,0,0,0,4,9,128,1,191,0,0,7,164,6,112,0,156,0,0,0,0,9,8,160,25],[0,0,0,32,8,112,2,112,0,0,7,164,6,112,0,156,0,0,0,0,8,7,160,25,0,0,0,2,6,144,1,191],[0,0,255,255,7,128,0,140,0,0,0,0,6,9,160,25,0,0,0,16,7,128,2,112,0,0,0,0,7,8,160,25],[0,0,0,255,7,112,0,140,0,0,0,1,6,96,32,57,0,0,0,65,7,96,0,57,0,0,0,7,7,112,1,127],[0,0,0,4,7,112,0,41,0,0,0,4,8,112,0,108,0,0,0,0,8,0,0,25,0,0,0,1,8,0,64,57],[0,0,7,168,9,112,0,156,0,0,4,10,0,0,33,61,0,0,0,1,8,128,1,144,0,0,4,10,0,0,193,61],[0,0,0,64,0,112,4,63,0,0,0,2,7,96,0,57,0,0,0,4,8,0,0,41,0,0,0,0,7,120,4,54],[0,0,0,33,8,96,0,57,0,0,0,5,8,128,2,114,0,0,22,201,0,0,97,61,0,0,0,0,9,18,3,79],[0,0,0,0,10,0,0,25,0,0,0,5,11,160,2,16,0,0,0,0,12,183,0,25,0,0,0,0,11,185,3,79],[0,0,0,0,11,11,4,59,0,0,0,0,0,188,4,53,0,0,0,1,10,160,0,57,0,0,0,0,11,138,0,75],[0,0,22,193,0,0,65,61,0,0,0,0,8,0,0,75,0,0,22,203,0,0,97,61,0,0,0,4,8,0,0,41],[0,0,0,0,8,8,4,51,0,0,0,0,8,8,0,75,0,0,4,250,0,0,97,61,0,0,0,0,8,7,4,51],[0,0,7,173,8,128,1,151,0,0,0,248,9,96,2,16,0,0,0,0,8,137,1,159,0,0,7,175,8,128,0,65],[0,0,0,0,0,135,4,53,0,0,0,3,6,96,2,16,0,0,0,248,6,96,0,137,0,0,0,0,5,101,1,207],[0,0,0,255,6,96,0,140,0,0,0,0,5,0,32,25,0,0,0,4,6,0,0,41,0,0,0,33,6,96,0,57],[0,0,23,175,0,0,1,61,0,0,0,56,8,80,0,140,0,0,23,4,0,0,65,61,0,0,0,32,10,80,2,112],[0,0,7,164,8,80,0,156,0,0,0,0,10,5,160,25,0,0,7,164,8,80,0,156,0,0,0,0,11,0,0,25],[0,0,0,4,11,0,32,57,0,0,0,2,8,176,1,191,0,0,255,255,12,160,0,140,0,0,0,0,8,11,160,25],[0,0,0,16,11,160,2,112,0,0,0,0,11,10,160,25,0,0,0,255,10,176,0,140,0,0,0,0,10,0,0,25],[0,0,0,1,10,0,32,57,0,0,7,172,11,112,0,156,0,0,4,10,0,0,33,61,0,0,0,0,8,168,1,159],[0,0,0,64,10,112,0,57,0,0,0,64,0,160,4,63,0,0,0,0,11,33,3,79,0,0,0,2,10,128,0,58],[0,0,0,0,10,167,4,54,0,0,0,0,11,11,4,59,0,0,0,0,0,186,4,53,0,0,4,250,0,0,97,61],[0,0,7,173,11,176,1,151,0,0,0,248,12,128,2,16,0,0,0,0,11,188,1,159,0,0,7,177,11,176,1,199],[0,0,0,0,0,186,4,53,0,0,0,3,8,128,2,16,0,0,0,248,8,128,1,95,0,0,0,0,8,133,1,207],[0,0,0,33,10,112,0,57,0,0,0,0,0,138,4,53,0,0,0,0,8,7,0,25,0,0,23,20,0,0,1,61],[0,0,7,172,8,112,0,156,0,0,4,10,0,0,33,61,0,0,0,64,8,112,0,57,0,0,0,64,0,128,4,63],[0,0,0,0,10,33,3,79,0,0,0,1,8,0,0,58,0,0,0,0,8,135,4,54,0,0,0,0,10,10,4,59],[0,0,0,0,0,168,4,53,0,0,4,250,0,0,97,61,0,0,0,248,11,80,2,16,0,0,7,173,10,160,1,151],[0,0,0,0,10,186,1,159,0,0,7,169,10,160,1,103,0,0,0,0,0,168,4,53,0,0,0,0,8,7,0,25],[0,0,0,64,7,0,4,61,0,0,7,172,10,112,0,156,0,0,4,10,0,0,33,61,0,0,0,64,10,112,0,57],[0,0,0,64,0,160,4,63,0,0,0,0,14,33,3,79,0,0,0,1,6,0,0,58,0,8,0,0,0,6,0,29],[0,0,0,0,10,103,4,54,0,0,0,0,6,14,4,59,0,9,0,0,0,6,0,29,0,0,0,0,0,106,4,53],[0,0,4,250,0,0,97,61,0,0,0,9,6,0,0,41,0,0,7,173,6,96,1,151,0,7,0,0,0,6,0,29],[0,0,7,178,15,96,1,199,0,0,0,0,0,250,4,53,0,0,0,32,10,208,0,57,0,0,0,0,10,161,3,79],[0,0,0,0,10,10,4,59,0,0,7,169,13,0,0,65,0,0,0,0,15,154,0,75,0,0,0,0,15,0,0,25],[0,0,0,0,15,13,128,25,0,0,7,169,9,144,1,151,0,0,7,169,12,160,1,151,0,0,0,0,11,156,0,75],[0,0,0,0,13,0,128,25,0,0,0,0,9,156,1,63,0,0,7,169,9,144,0,156,0,0,0,0,13,15,192,25],[0,0,0,0,9,13,0,75,0,0,0,11,6,0,0,41,0,0,0,204,0,0,193,61,0,0,0,0,9,106,0,25],[0,0,0,0,10,145,3,79,0,0,0,0,6,10,4,59,0,11,0,0,0,6,0,29,0,0,7,168,10,96,0,156],[0,0,0,204,0,0,33,61,0,0,0,11,6,0,0,41,0,0,0,32,10,96,0,140,0,0,0,204,0,0,65,61],[0,0,0,11,2,32,0,106,0,0,0,32,13,144,0,57,0,0,7,169,9,0,0,65,0,0,0,0,10,45,0,75],[0,0,0,0,10,0,0,25,0,0,0,0,10,9,32,25,0,0,7,169,2,32,1,151,0,0,7,169,11,208,1,151],[0,0,0,0,12,43,0,75,0,0,0,0,9,0,128,25,0,0,0,0,2,43,1,63,0,0,7,169,2,32,0,156],[0,0,0,0,9,10,192,25,0,0,0,0,2,9,0,75,0,0,0,204,0,0,193,61,0,0,0,0,9,209,3,79],[0,0,0,64,2,0,4,61,0,0,0,0,6,9,4,59,0,6,0,0,0,6,0,29,0,0,0,128,9,96,0,140],[0,0,25,3,0,0,65,61,0,0,0,6,6,0,0,41,0,0,0,128,9,96,2,112,0,0,7,174,10,96,0,156],[0,0,0,0,9,6,160,25,0,0,7,174,10,96,0,156,0,0,0,0,10,0,0,25,0,0,0,16,10,0,32,57],[0,0,0,8,11,160,1,191,0,0,7,168,12,144,0,156,0,0,0,0,11,10,160,25,0,0,0,64,10,144,2,112],[0,0,7,168,12,144,0,156,0,0,0,0,10,9,160,25,0,0,0,4,9,176,1,191,0,0,7,164,12,160,0,156],[0,0,0,0,9,11,160,25,0,0,0,32,11,160,2,112,0,0,7,164,12,160,0,156,0,0,0,0,11,10,160,25],[0,0,0,2,6,144,1,191,0,0,255,255,10,176,0,140,0,0,0,0,6,9,160,25,0,0,0,16,9,176,2,112],[0,0,0,0,9,11,160,25,0,0,0,255,9,144,0,140,0,0,0,1,6,96,32,57,0,5,0,0,0,6,0,29],[0,0,0,65,9,96,0,57,0,0,0,0,9,57,1,111,0,0,0,0,9,146,0,25,0,0,0,0,10,41,0,75],[0,0,0,0,10,0,0,25,0,0,0,1,10,0,64,57,0,0,7,168,11,144,0,156,0,0,4,10,0,0,33,61],[0,0,0,1,10,160,1,144,0,0,4,10,0,0,193,61,0,0,0,64,0,144,4,63,0,0,0,5,6,0,0,41],[0,0,0,2,9,96,0,57,0,0,0,0,10,146,4,54,0,0,0,33,9,96,0,57,0,0,0,5,9,144,2,114],[0,0,23,138,0,0,97,61,0,0,0,0,15,0,0,25,0,0,0,5,11,240,2,16,0,0,0,0,12,186,0,25],[0,0,0,0,11,190,3,79,0,0,0,0,11,11,4,59,0,0,0,0,0,188,4,53,0,0,0,1,15,240,0,57],[0,0,0,0,11,159,0,75,0,0,23,130,0,0,65,61,0,0,0,0,6,0,0,75,0,0,23,140,0,0,97,61],[0,0,0,0,9,2,4,51,0,0,0,0,9,9,0,75,0,0,4,250,0,0,97,61,0,0,0,0,9,10,4,51],[0,0,7,173,9,144,1,151,0,0,0,5,6,0,0,41,0,0,0,248,11,96,2,16,0,0,0,0,9,155,1,159],[0,0,7,175,9,144,0,65,0,0,0,0,0,154,4,53,0,0,0,3,9,96,2,16,0,0,0,248,9,144,0,137],[0,0,0,6,10,144,1,239,0,0,0,255,9,144,0,140,0,0,0,0,10,0,32,25,0,0,0,33,9,32,0,57],[0,0,25,20,0,0,1,61,0,0,0,4,6,0,0,41,0,0,7,172,6,96,0,156,0,0,4,10,0,0,33,61],[0,0,0,4,8,0,0,41,0,0,0,64,6,128,0,57,0,0,0,64,0,96,4,63,0,0,0,0,7,18,3,79],[0,0,0,1,6,0,0,58,0,0,0,0,6,104,4,54,0,0,0,0,7,7,4,59,0,0,0,0,0,118,4,53],[0,0,4,250,0,0,97,61,0,0,0,248,8,80,2,16,0,0,7,169,9,0,0,65,0,0,0,0,5,5,0,75],[0,0,0,0,9,8,192,25,0,0,7,173,5,112,1,151,0,0,0,0,5,149,1,159,0,0,0,0,0,86,4,53],[0,0,0,64,5,48,0,140,0,0,0,204,0,0,65,61,0,0,0,64,5,0,4,61,0,3,0,0,0,5,0,29],[0,0,0,32,4,64,0,57,0,0,0,0,5,66,3,79,0,0,0,0,5,5,4,59,0,0,0,128,6,80,0,140],[0,0,24,193,0,0,65,61,0,0,0,128,6,80,2,112,0,0,7,174,7,80,0,156,0,0,0,0,6,5,160,25],[0,0,7,174,7,80,0,156,0,0,0,0,7,0,0,25,0,0,0,16,7,0,32,57,0,0,0,8,8,112,1,191],[0,0,7,168,9,96,0,156,0,0,0,0,8,7,160,25,0,0,0,64,7,96,2,112,0,0,7,168,9,96,0,156],[0,0,0,0,7,6,160,25,0,0,0,4,9,128,1,191,0,0,7,164,6,112,0,156,0,0,0,0,9,8,160,25],[0,0,0,32,8,112,2,112,0,0,7,164,6,112,0,156,0,0,0,0,8,7,160,25,0,0,0,2,6,144,1,191],[0,0,255,255,7,128,0,140,0,0,0,0,6,9,160,25,0,0,0,16,7,128,2,112,0,0,0,0,7,8,160,25],[0,0,0,255,7,112,0,140,0,0,0,1,6,96,32,57,0,0,0,65,7,96,0,57,0,0,0,7,7,112,1,127],[0,0,0,3,7,112,0,41,0,0,0,3,8,112,0,108,0,0,0,0,8,0,0,25,0,0,0,1,8,0,64,57],[0,0,7,168,9,112,0,156,0,0,4,10,0,0,33,61,0,0,0,1,8,128,1,144,0,0,4,10,0,0,193,61],[0,0,0,64,0,112,4,63,0,0,0,2,7,96,0,57,0,0,0,3,8,0,0,41,0,0,0,0,7,120,4,54],[0,0,0,33,8,96,0,57,0,0,0,5,8,128,2,114,0,0,23,237,0,0,97,61,0,0,0,0,1,18,3,79],[0,0,0,0,9,0,0,25,0,0,0,5,10,144,2,16,0,0,0,0,11,167,0,25,0,0,0,0,10,161,3,79],[0,0,0,0,10,10,4,59,0,0,0,0,0,171,4,53,0,0,0,1,9,144,0,57,0,0,0,0,10,137,0,75],[0,0,23,229,0,0,65,61,0,0,0,0,1,0,0,75,0,0,23,239,0,0,97,61,0,0,0,3,1,0,0,41],[0,0,0,0,1,1,4,51,0,0,0,0,1,1,0,75,0,0,4,250,0,0,97,61,0,0,0,0,1,7,4,51],[0,0,7,173,1,16,1,151,0,0,0,248,8,96,2,16,0,0,0,0,1,24,1,159,0,0,7,175,1,16,0,65],[0,0,0,0,0,23,4,53,0,0,0,3,1,96,2,16,0,0,0,248,1,16,0,137,0,0,0,0,5,21,1,207],[0,0,0,255,1,16,0,140,0,0,0,0,5,0,32,25,0,0,0,3,1,0,0,41,0,0,0,33,1,16,0,57],[0,0,24,211,0,0,1,61,0,0,0,56,8,80,0,140,0,0,24,40,0,0,65,61,0,0,0,32,10,80,2,112],[0,0,7,164,8,80,0,156,0,0,0,0,10,5,160,25,0,0,7,164,8,80,0,156,0,0,0,0,11,0,0,25],[0,0,0,4,11,0,32,57,0,0,0,2,8,176,1,191,0,0,255,255,12,160,0,140,0,0,0,0,8,11,160,25],[0,0,0,16,11,160,2,112,0,0,0,0,11,10,160,25,0,0,0,255,10,176,0,140,0,0,0,0,10,0,0,25],[0,0,0,1,10,0,32,57,0,0,7,172,11,112,0,156,0,0,4,10,0,0,33,61,0,0,0,0,8,168,1,159],[0,0,0,64,10,112,0,57,0,0,0,64,0,160,4,63,0,0,0,0,11,33,3,79,0,0,0,2,10,128,0,58],[0,0,0,0,10,167,4,54,0,0,0,0,11,11,4,59,0,0,0,0,0,186,4,53,0,0,4,250,0,0,97,61],[0,0,7,173,11,176,1,151,0,0,0,248,12,128,2,16,0,0,0,0,11,188,1,159,0,0,7,177,11,176,1,199],[0,0,0,0,0,186,4,53,0,0,0,3,8,128,2,16,0,0,0,248,8,128,1,95,0,0,0,0,8,133,1,207],[0,0,0,33,10,112,0,57,0,0,0,0,0,138,4,53,0,0,0,0,8,7,0,25,0,0,24,56,0,0,1,61],[0,0,7,172,8,112,0,156,0,0,4,10,0,0,33,61,0,0,0,64,8,112,0,57,0,0,0,64,0,128,4,63],[0,0,0,0,10,33,3,79,0,0,0,1,8,0,0,58,0,0,0,0,8,135,4,54,0,0,0,0,10,10,4,59],[0,0,0,0,0,168,4,53,0,0,4,250,0,0,97,61,0,0,0,248,11,80,2,16,0,0,7,173,10,160,1,151],[0,0,0,0,10,186,1,159,0,0,7,169,10,160,1,103,0,0,0,0,0,168,4,53,0,0,0,0,8,7,0,25],[0,0,0,64,7,0,4,61,0,0,7,172,10,112,0,156,0,0,4,10,0,0,33,61,0,0,0,64,10,112,0,57],[0,0,0,64,0,160,4,63,0,0,0,0,14,33,3,79,0,0,0,1,6,0,0,58,0,8,0,0,0,6,0,29],[0,0,0,0,10,103,4,54,0,0,0,0,6,14,4,59,0,9,0,0,0,6,0,29,0,0,0,0,0,106,4,53],[0,0,4,250,0,0,97,61,0,0,0,9,6,0,0,41,0,0,7,173,6,96,1,151,0,7,0,0,0,6,0,29],[0,0,7,178,12,96,1,199,0,0,0,0,0,202,4,53,0,0,0,32,10,208,0,57,0,0,0,0,10,161,3,79],[0,0,0,0,10,10,4,59,0,0,7,169,12,0,0,65,0,0,0,0,13,154,0,75,0,0,0,0,13,0,0,25],[0,0,0,0,13,12,128,25,0,0,7,169,9,144,1,151,0,0,7,169,15,160,1,151,0,0,0,0,11,159,0,75],[0,0,0,0,12,0,128,25,0,0,0,0,9,159,1,63,0,0,7,169,9,144,0,156,0,0,0,0,12,13,192,25],[0,0,0,0,9,12,0,75,0,0,0,11,6,0,0,41,0,0,0,204,0,0,193,61,0,0,0,0,9,106,0,25],[0,0,0,0,10,145,3,79,0,0,0,0,6,10,4,59,0,11,0,0,0,6,0,29,0,0,7,168,10,96,0,156],[0,0,0,204,0,0,33,61,0,0,0,11,6,0,0,41,0,0,0,32,10,96,0,140,0,0,0,204,0,0,65,61],[0,0,0,11,2,32,0,106,0,0,0,32,6,144,0,57,0,0,7,169,9,0,0,65,0,0,0,0,10,38,0,75],[0,0,0,0,10,0,0,25,0,0,0,0,10,9,32,25,0,0,7,169,2,32,1,151,0,5,0,0,0,6,0,29],[0,0,7,169,11,96,1,151,0,0,0,0,12,43,0,75,0,0,0,0,9,0,128,25,0,0,0,0,2,43,1,63],[0,0,7,169,2,32,0,156,0,0,0,0,9,10,192,25,0,0,0,0,2,9,0,75,0,0,0,204,0,0,193,61],[0,0,0,5,9,16,3,96,0,0,0,64,2,0,4,61,0,0,0,0,6,9,4,59,0,6,0,0,0,6,0,29],[0,0,0,128,9,96,0,140,0,0,0,32,13,32,0,57,0,0,25,105,0,0,65,61,0,0,0,6,6,0,0,41],[0,0,0,128,9,96,2,112,0,0,7,174,10,96,0,156,0,0,0,0,9,6,160,25,0,0,7,174,10,96,0,156],[0,0,0,0,10,0,0,25,0,0,0,16,10,0,32,57,0,0,0,8,11,160,1,191,0,0,7,168,12,144,0,156],[0,0,0,0,11,10,160,25,0,0,0,64,10,144,2,112,0,0,7,168,12,144,0,156,0,0,0,0,10,9,160,25],[0,0,0,4,9,176,1,191,0,0,7,164,12,160,0,156,0,0,0,0,9,11,160,25,0,0,0,32,11,160,2,112],[0,0,7,164,12,160,0,156,0,0,0,0,11,10,160,25,0,0,0,2,15,144,1,191,0,0,255,255,10,176,0,140],[0,0,0,0,15,9,160,25,0,0,0,16,9,176,2,112,0,0,0,0,9,11,160,25,0,0,0,255,9,144,0,140],[0,0,0,1,15,240,32,57,0,0,0,65,9,240,0,57,0,0,0,0,9,57,1,111,0,0,0,0,9,146,0,25],[0,0,0,0,10,41,0,75,0,0,0,0,10,0,0,25,0,0,0,1,10,0,64,57,0,0,7,168,11,144,0,156],[0,0,4,10,0,0,33,61,0,0,0,1,10,160,1,144,0,0,4,10,0,0,193,61,0,0,0,64,0,144,4,63],[0,0,0,2,9,240,0,57,0,0,0,0,0,146,4,53,0,0,0,33,9,240,0,57,0,0,0,5,10,144,2,114],[0,0,24,174,0,0,97,61,0,0,0,0,9,0,0,25,0,0,0,5,11,144,2,16,0,0,0,0,12,189,0,25],[0,0,0,0,11,190,3,79,0,0,0,0,11,11,4,59,0,0,0,0,0,188,4,53,0,0,0,1,9,144,0,57],[0,0,0,0,11,169,0,75,0,0,24,166,0,0,65,61,0,0,0,0,6,0,0,75,0,0,24,176,0,0,97,61],[0,0,0,0,9,2,4,51,0,0,0,0,9,9,0,75,0,0,4,250,0,0,97,61,0,0,0,0,9,13,4,51],[0,0,7,173,9,144,1,151,0,0,0,248,10,240,2,16,0,0,0,0,9,154,1,159,0,0,7,175,9,144,0,65],[0,0,0,0,0,157,4,53,0,0,0,3,9,240,2,16,0,0,0,248,9,144,0,137,0,0,0,6,10,144,1,239],[0,0,0,255,9,144,0,140,0,0,0,0,10,0,32,25,0,0,0,33,9,32,0,57,0,0,0,0,0,169,4,53],[0,0,25,122,0,0,1,61,0,0,0,3,6,0,0,41,0,0,7,172,6,96,0,156,0,0,4,10,0,0,33,61],[0,0,0,3,7,0,0,41,0,0,0,64,6,112,0,57,0,0,0,64,0,96,4,63,0,0,0,0,6,18,3,79],[0,0,0,1,1,0,0,58,0,0,0,0,1,23,4,54,0,0,0,0,6,6,4,59,0,0,0,0,0,97,4,53],[0,0,4,250,0,0,97,61,0,0,0,248,7,80,2,16,0,0,7,169,8,0,0,65,0,0,0,0,5,5,0,75],[0,0,0,0,8,7,192,25,0,0,7,173,5,96,1,151,0,0,0,0,5,133,1,159,0,0,0,0,0,81,4,53],[0,0,0,65,1,48,0,140,0,0,4,250,0,0,65,61,0,0,0,32,1,64,0,57,0,0,0,0,1,18,3,79],[0,0,0,0,1,1,4,59,0,0,0,248,1,16,2,112,0,2,0,0,0,1,0,29,0,0,0,27,1,16,0,138],[0,0,0,2,1,16,0,140,0,0,27,90,0,0,129,61,0,0,0,12,1,0,0,41,0,1,1,68,0,16,0,61],[0,0,0,1,1,32,3,96,0,0,0,0,1,1,4,59,0,0,0,0,1,1,0,75,0,0,26,147,0,0,97,61],[0,0,7,170,1,0,0,65,0,0,0,0,0,16,4,57,0,0,7,164,1,0,0,65,0,0,0,0,2,0,4,20],[0,0,7,164,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,7,171,1,16,1,199],[0,0,128,11,2,0,0,57,30,139,30,129,0,0,4,15,0,0,0,1,2,32,1,144,0,0,25,2,0,0,97,61],[0,0,0,0,2,1,4,59,0,0,0,1,1,32,2,16,0,0,0,0,3,2,0,75,0,0,24,250,0,0,97,61],[0,0,0,9,3,0,0,138,0,0,0,0,3,49,0,75,0,0,24,254,0,0,33,61,0,0,0,0,50,33,0,217],[0,0,0,2,2,32,0,140,0,0,24,254,0,0,193,61,0,0,0,2,1,16,0,41,0,0,0,8,3,16,0,57],[0,0,0,2,1,48,0,108,0,0,25,207,0,0,129,61,0,0,7,201,1,0,0,65,0,0,0,0,0,16,4,53],[0,0,0,17,1,0,0,57,0,0,4,253,0,0,1,61,0,0,0,0,0,1,4,47,0,0,7,172,9,32,0,156],[0,0,4,10,0,0,33,61,0,0,0,64,9,32,0,57,0,0,0,64,0,144,4,63,0,0,0,32,9,32,0,57],[0,0,0,9,6,0,0,41,0,0,0,0,0,105,4,53,0,0,0,8,6,0,0,41,0,0,0,0,0,98,4,53],[0,0,0,0,10,6,0,75,0,0,4,250,0,0,97,61,0,0,0,6,6,0,0,41,0,0,0,248,10,96,2,16],[0,0,7,169,11,0,0,65,0,0,0,0,12,6,0,75,0,0,0,0,11,10,192,25,0,0,0,7,10,176,1,175],[0,0,0,0,0,169,4,53,0,0,0,11,6,0,0,41,0,0,0,64,9,96,0,140,0,0,0,204,0,0,65,61],[0,0,0,64,9,0,4,61,0,4,0,32,0,208,0,61,0,0,0,4,10,16,3,96,0,0,0,0,6,10,4,59],[0,6,0,0,0,6,0,29,0,0,0,128,10,96,0,140,0,0,0,32,15,144,0,57,0,0,26,27,0,0,65,61],[0,0,0,6,6,0,0,41,0,0,0,128,10,96,2,112,0,0,7,174,11,96,0,156,0,0,0,0,10,6,160,25],[0,0,7,174,11,96,0,156,0,0,0,0,11,0,0,25,0,0,0,16,11,0,32,57,0,0,0,8,12,176,1,191],[0,0,7,168,13,160,0,156,0,0,0,0,12,11,160,25,0,0,0,64,11,160,2,112,0,0,7,168,13,160,0,156],[0,0,0,0,11,10,160,25,0,0,0,4,10,192,1,191,0,0,7,164,13,176,0,156,0,0,0,0,10,12,160,25],[0,0,0,32,12,176,2,112,0,0,7,164,13,176,0,156,0,0,0,0,12,11,160,25,0,0,0,2,6,160,1,191],[0,0,255,255,11,192,0,140,0,0,0,0,6,10,160,25,0,0,0,16,10,192,2,112,0,0,0,0,10,12,160,25],[0,0,0,255,10,160,0,140,0,0,0,1,6,96,32,57,0,5,0,0,0,6,0,29,0,0,0,65,10,96,0,57],[0,0,0,0,10,58,1,111,0,0,0,0,10,169,0,25,0,0,0,0,11,154,0,75,0,0,0,0,13,0,0,25],[0,0,0,1,13,0,64,57,0,0,7,168,11,160,0,156,0,0,4,10,0,0,33,61,0,0,0,1,11,208,1,144],[0,0,4,10,0,0,193,61,0,0,0,64,0,160,4,63,0,0,0,5,6,0,0,41,0,0,0,2,10,96,0,57],[0,0,0,0,0,169,4,53,0,0,0,33,10,96,0,57,0,0,0,5,10,160,2,114,0,0,25,85,0,0,97,61],[0,0,0,0,13,0,0,25,0,0,0,5,11,208,2,16,0,0,0,0,12,191,0,25,0,0,0,0,11,190,3,79],[0,0,0,0,11,11,4,59,0,0,0,0,0,188,4,53,0,0,0,1,13,208,0,57,0,0,0,0,11,173,0,75],[0,0,25,77,0,0,65,61,0,0,0,0,6,0,0,75,0,0,25,87,0,0,97,61,0,0,0,0,10,9,4,51],[0,0,0,0,10,10,0,75,0,0,4,250,0,0,97,61,0,0,0,0,10,15,4,51,0,0,7,173,10,160,1,151],[0,0,0,5,6,0,0,41,0,0,0,248,11,96,2,16,0,0,0,0,10,171,1,159,0,0,7,175,10,160,0,65],[0,0,0,0,0,175,4,53,0,0,0,3,10,96,2,16,0,0,0,248,10,160,0,137,0,0,0,6,11,160,1,239],[0,0,0,255,10,160,0,140,0,0,0,0,11,0,32,25,0,0,0,33,10,144,0,57,0,0,0,0,0,186,4,53],[0,0,26,44,0,0,1,61,0,0,7,172,9,32,0,156,0,0,4,10,0,0,33,61,0,0,0,64,9,32,0,57],[0,0,0,64,0,144,4,63,0,0,0,9,6,0,0,41,0,0,0,0,0,109,4,53,0,0,0,8,6,0,0,41],[0,0,0,0,0,98,4,53,0,0,0,0,9,6,0,75,0,0,4,250,0,0,97,61,0,0,0,6,6,0,0,41],[0,0,0,248,9,96,2,16,0,0,7,169,10,0,0,65,0,0,0,0,11,6,0,75,0,0,0,0,10,9,192,25],[0,0,0,7,9,160,1,175,0,0,0,0,0,157,4,53,0,0,0,11,6,0,0,41,0,0,0,64,9,96,0,140],[0,0,0,204,0,0,65,61,0,0,0,64,9,0,4,61,0,0,0,5,6,0,0,41,0,4,0,32,0,96,0,61],[0,0,0,4,10,16,3,96,0,0,0,0,6,10,4,59,0,6,0,0,0,6,0,29,0,0,0,128,10,96,0,140],[0,0,0,32,13,144,0,57,0,0,26,87,0,0,65,61,0,0,0,6,6,0,0,41,0,0,0,128,10,96,2,112],[0,0,7,174,11,96,0,156,0,0,0,0,10,6,160,25,0,0,7,174,11,96,0,156,0,0,0,0,11,0,0,25],[0,0,0,16,11,0,32,57,0,0,0,8,12,176,1,191,0,0,7,168,15,160,0,156,0,0,0,0,12,11,160,25],[0,0,0,64,11,160,2,112,0,0,7,168,15,160,0,156,0,0,0,0,11,10,160,25,0,0,0,4,15,192,1,191],[0,0,7,164,10,176,0,156,0,0,0,0,15,12,160,25,0,0,0,32,12,176,2,112,0,0,7,164,10,176,0,156],[0,0,0,0,12,11,160,25,0,0,0,2,6,240,1,191,0,0,255,255,11,192,0,140,0,0,0,0,6,15,160,25],[0,0,0,16,11,192,2,112,0,0,0,0,11,12,160,25,0,0,0,255,11,176,0,140,0,0,0,1,6,96,32,57],[0,5,0,0,0,6,0,29,0,0,0,65,11,96,0,57,0,0,0,0,11,59,1,111,0,0,0,0,12,185,0,25],[0,0,0,0,11,156,0,75,0,0,0,0,15,0,0,25,0,0,0,1,15,0,64,57,0,0,7,168,11,192,0,156],[0,0,4,10,0,0,33,61,0,0,0,1,11,240,1,144,0,0,4,10,0,0,193,61,0,0,0,64,0,192,4,63],[0,0,0,5,6,0,0,41,0,0,0,2,11,96,0,57,0,0,0,0,0,185,4,53,0,0,0,33,11,96,0,57],[0,0,0,5,15,176,2,114,0,0,25,187,0,0,97,61,0,0,0,0,12,0,0,25,0,0,0,5,11,192,2,16],[0,0,0,0,10,189,0,25,0,0,0,0,11,190,3,79,0,0,0,0,11,11,4,59,0,0,0,0,0,186,4,53],[0,0,0,1,12,192,0,57,0,0,0,0,10,252,0,75,0,0,25,179,0,0,65,61,0,0,0,0,6,0,0,75],[0,0,25,189,0,0,97,61,0,0,0,0,10,9,4,51,0,0,0,0,10,10,0,75,0,0,4,250,0,0,97,61],[0,0,0,0,10,13,4,51,0,0,7,173,10,160,1,151,0,0,0,5,6,0,0,41,0,0,0,248,11,96,2,16],[0,0,0,0,10,171,1,159,0,0,7,175,10,160,0,65,0,0,0,0,0,173,4,53,0,0,0,3,10,96,2,16],[0,0,0,248,10,160,0,137,0,0,0,6,11,160,1,239,0,0,0,255,10,160,0,140,0,0,0,0,11,0,32,25],[0,0,0,33,10,144,0,57,0,0,0,0,0,186,4,53,0,0,26,104,0,0,1,61,0,0,0,128,1,48,0,140],[0,2,0,0,0,3,0,29,0,0,26,147,0,0,65,61,0,0,0,128,1,48,2,112,0,0,7,174,2,48,0,156],[0,0,0,0,1,3,160,25,0,0,7,174,2,48,0,156,0,0,0,0,2,0,0,25,0,0,0,16,2,0,32,57],[0,0,0,8,4,32,1,191,0,0,7,168,5,16,0,156,0,0,0,0,4,2,160,25,0,0,0,64,2,16,2,112],[0,0,7,168,5,16,0,156,0,0,0,0,2,1,160,25,0,0,0,4,1,64,1,191,0,0,7,164,5,32,0,156],[0,0,0,0,1,4,160,25,0,0,0,32,4,32,2,112,0,0,7,164,5,32,0,156,0,0,0,0,4,2,160,25],[0,0,0,2,5,16,1,191,0,0,255,255,2,64,0,140,0,0,0,0,5,1,160,25,0,0,0,16,1,64,2,112],[0,0,0,0,1,4,160,25,0,0,0,255,1,16,0,140,0,0,0,1,5,80,32,57,0,0,0,65,1,80,0,57],[0,0,0,7,2,16,1,127,0,0,0,64,1,0,4,61,0,0,0,0,2,33,0,25,0,0,0,0,4,18,0,75],[0,0,0,0,4,0,0,25,0,0,0,1,4,0,64,57,0,0,7,168,6,32,0,156,0,0,4,10,0,0,33,61],[0,0,0,1,4,64,1,144,0,0,4,10,0,0,193,61,0,0,0,64,0,32,4,63,0,0,0,2,2,80,0,57],[0,0,0,0,6,33,4,54,0,0,0,17,2,0,3,103,0,0,0,0,4,0,0,49,0,0,0,33,7,80,0,57],[0,0,0,5,7,112,2,114,0,0,26,8,0,0,97,61,0,0,0,0,8,66,3,79,0,0,0,0,9,0,0,25],[0,0,0,5,10,144,2,16,0,0,0,0,11,166,0,25,0,0,0,0,10,168,3,79,0,0,0,0,10,10,4,59],[0,0,0,0,0,171,4,53,0,0,0,1,9,144,0,57,0,0,0,0,10,121,0,75,0,0,26,0,0,0,65,61],[0,0,0,0,7,0,0,75,0,0,26,10,0,0,97,61,0,0,0,0,7,1,4,51,0,0,0,0,7,7,0,75],[0,0,4,250,0,0,97,61,0,0,0,0,7,6,4,51,0,0,7,173,7,112,1,151,0,0,0,248,8,80,2,16],[0,0,0,0,7,120,1,159,0,0,7,175,7,112,0,65,0,0,0,0,0,118,4,53,0,0,0,3,5,80,2,16],[0,0,0,248,5,80,0,137,0,0,0,0,3,83,1,207,0,0,0,255,5,80,0,140,0,0,0,0,3,0,32,25],[0,0,0,33,5,16,0,57,0,0,0,0,0,53,4,53,0,0,26,168,0,0,1,61,0,0,7,172,10,144,0,156],[0,0,4,10,0,0,33,61,0,0,0,64,10,144,0,57,0,0,0,64,0,160,4,63,0,0,0,9,6,0,0,41],[0,0,0,0,0,111,4,53,0,0,0,8,6,0,0,41,0,0,0,0,0,105,4,53,0,0,0,0,10,6,0,75],[0,0,4,250,0,0,97,61,0,0,0,6,6,0,0,41,0,0,0,248,10,96,2,16,0,0,7,169,11,0,0,65],[0,0,0,0,12,6,0,75,0,0,0,0,11,10,192,25,0,0,0,7,10,176,1,175,0,0,0,0,0,175,4,53],[0,0,0,11,6,0,0,41,0,0,0,65,10,96,0,140,0,0,4,250,0,0,65,61,0,0,0,4,6,0,0,41],[0,0,0,32,10,96,0,57,0,0,0,0,11,161,3,79,0,0,0,0,10,0,4,21,0,0,0,16,10,160,0,138],[0,0,0,5,10,160,2,16,0,0,0,0,11,11,4,59,0,0,0,248,13,176,2,112,0,0,0,27,11,208,0,140],[0,0,0,0,14,0,0,25,0,0,27,16,0,0,97,61,0,0,0,28,10,208,0,140,0,0,27,90,0,0,193,61],[0,0,0,0,10,0,4,21,0,0,0,15,10,160,0,138,0,0,0,5,10,160,2,16,0,0,0,27,14,208,0,138],[0,0,0,128,11,224,0,140,0,0,27,16,0,0,65,61,0,0,0,64,13,0,4,61,0,0,7,172,10,208,0,156],[0,0,4,10,0,0,33,61,0,0,0,64,10,208,0,57,0,0,0,64,0,160,4,63,0,0,0,32,10,208,0,57],[0,0,0,9,6,0,0,41,0,0,0,0,0,106,4,53,0,0,0,2,11,0,0,58,0,0,0,0,0,189,4,53],[0,0,4,250,0,0,97,61,0,0,0,7,6,0,0,41,0,0,7,175,11,96,1,199,0,0,0,0,0,186,4,53],[0,0,0,248,10,224,2,16,0,0,0,33,11,208,0,57,0,0,0,0,0,171,4,53,0,0,0,0,10,0,4,21],[0,0,0,15,10,160,0,138,0,0,0,5,10,160,2,16,0,0,27,34,0,0,1,61,0,0,7,172,10,144,0,156],[0,0,4,10,0,0,33,61,0,0,0,64,10,144,0,57,0,0,0,64,0,160,4,63,0,0,0,9,6,0,0,41],[0,0,0,0,0,109,4,53,0,0,0,8,6,0,0,41,0,0,0,0,0,105,4,53,0,0,0,0,10,6,0,75],[0,0,4,250,0,0,97,61,0,0,0,6,6,0,0,41,0,0,0,248,10,96,2,16,0,0,7,169,11,0,0,65],[0,0,0,0,12,6,0,75,0,0,0,0,11,10,192,25,0,0,0,7,10,176,1,175,0,0,0,0,0,173,4,53],[0,0,0,11,6,0,0,41,0,0,0,65,10,96,0,140,0,0,4,250,0,0,65,61,0,0,0,4,6,0,0,41],[0,0,0,32,10,96,0,57,0,0,0,0,11,161,3,79,0,0,0,0,10,0,4,21,0,0,0,14,10,160,0,138],[0,0,0,5,10,160,2,16,0,0,0,0,11,11,4,59,0,0,0,248,13,176,2,112,0,0,0,27,11,208,0,140],[0,0,0,0,14,0,0,25,0,0,27,97,0,0,97,61,0,0,0,28,10,208,0,140,0,0,27,90,0,0,193,61],[0,0,0,0,10,0,4,21,0,0,0,13,10,160,0,138,0,0,0,5,10,160,2,16,0,0,0,27,14,208,0,138],[0,0,0,128,11,224,0,140,0,0,27,97,0,0,65,61,0,0,0,64,13,0,4,61,0,0,7,172,10,208,0,156],[0,0,4,10,0,0,33,61,0,0,0,64,10,208,0,57,0,0,0,64,0,160,4,63,0,0,0,32,10,208,0,57],[0,0,0,9,6,0,0,41,0,0,0,0,0,106,4,53,0,0,0,2,11,0,0,58,0,0,0,0,0,189,4,53],[0,0,4,250,0,0,97,61,0,0,0,7,6,0,0,41,0,0,7,175,11,96,1,199,0,0,0,0,0,186,4,53],[0,0,0,248,10,224,2,16,0,0,0,33,11,208,0,57,0,0,0,0,0,171,4,53,0,0,0,0,10,0,4,21],[0,0,0,13,10,160,0,138,0,0,0,5,10,160,2,16,0,0,27,115,0,0,1,61,0,0,0,64,1,0,4,61],[0,0,7,172,2,16,0,156,0,0,4,10,0,0,33,61,0,0,0,64,2,16,0,57,0,0,0,64,0,32,4,63],[0,0,0,1,2,0,0,58,0,0,0,0,3,33,4,54,0,0,0,0,4,0,0,49,0,0,0,17,2,0,3,103],[0,0,0,0,5,66,3,79,0,0,0,0,5,5,4,59,0,0,0,0,0,83,4,53,0,0,4,250,0,0,97,61],[0,0,0,2,8,0,0,41,0,0,0,248,6,128,2,16,0,0,7,169,7,0,0,65,0,0,0,0,8,8,0,75],[0,0,0,0,7,6,192,25,0,0,7,173,5,80,1,151,0,0,0,0,5,117,1,159,0,0,0,0,0,83,4,53],[0,0,0,1,3,0,0,41,0,0,0,128,3,48,0,57,0,0,0,0,3,50,3,79,0,0,0,12,5,64,0,106],[0,0,0,35,5,80,0,138,0,0,0,0,3,3,4,59,0,0,7,169,6,0,0,65,0,0,0,0,7,83,0,75],[0,0,0,0,7,0,0,25,0,0,0,0,7,6,128,25,0,0,7,169,5,80,1,151,0,0,7,169,8,48,1,151],[0,0,0,0,9,88,0,75,0,0,0,0,6,0,128,25,0,0,0,0,5,88,1,63,0,0,7,169,5,80,0,156],[0,0,0,0,6,7,192,25,0,0,0,0,5,6,0,75,0,0,0,11,6,0,0,41,0,0,0,204,0,0,193,61],[0,0,0,10,5,0,0,41,0,0,0,0,5,5,4,51,0,0,0,9,7,0,0,41,0,0,0,0,7,7,4,51],[0,0,0,8,8,0,0,41,0,0,0,0,8,8,4,51,0,0,0,6,9,0,0,41,0,0,0,0,9,9,4,51],[0,0,0,5,10,0,0,41,0,0,0,0,10,10,4,51,0,0,0,0,6,99,0,25,0,0,0,0,3,98,3,79],[0,0,0,0,3,3,4,59,0,0,7,168,11,48,0,156,0,0,0,204,0,0,33,61,0,0,0,0,11,52,0,73],[0,0,0,32,6,96,0,57,0,0,7,169,12,0,0,65,0,0,0,0,13,182,0,75,0,0,0,0,13,0,0,25],[0,0,0,0,13,12,32,25,0,0,7,169,11,176,1,151,0,0,7,169,14,96,1,151,0,0,0,0,15,190,0,75],[0,0,0,0,12,0,128,25,0,0,0,0,11,190,1,63,0,0,7,169,11,176,0,156,0,0,0,0,12,13,192,25],[0,0,0,0,11,12,0,75,0,0,0,204,0,0,193,61,0,0,0,0,5,87,0,25,0,0,0,0,5,133,0,25],[0,0,0,0,5,149,0,25,0,0,0,0,5,165,0,25,0,0,0,0,5,53,0,25,0,0,0,4,7,0,0,41],[0,0,0,0,7,7,4,51,0,0,0,0,5,117,0,25,0,0,0,3,7,0,0,41,0,0,0,0,7,7,4,51],[0,0,0,0,5,117,0,25,0,0,0,0,7,1,4,51,0,0,0,0,5,117,0,25,0,0,0,64,7,0,4,61],[0,0,7,168,5,80,1,151,0,0,0,56,8,80,0,140,0,0,0,64,9,112,0,57,0,0,0,0,8,66,3,79],[0,0,0,32,4,112,0,57,0,0,27,171,0,0,65,61,0,0,0,32,11,80,2,112,0,0,7,164,10,80,0,156],[0,0,0,0,11,5,160,25,0,0,7,164,10,80,0,156,0,0,0,0,12,0,0,25,0,0,0,4,12,0,32,57],[0,0,0,2,10,192,1,191,0,0,255,255,13,176,0,140,0,0,0,0,10,12,160,25,0,0,0,16,12,176,2,112],[0,0,0,0,12,11,160,25,0,0,0,255,11,192,0,140,0,0,0,0,11,0,0,25,0,0,0,1,11,0,32,57],[0,0,7,172,12,112,0,156,0,0,4,10,0,0,33,61,0,0,0,0,10,186,1,159,0,0,0,64,0,144,4,63],[0,0,0,2,9,160,0,58,0,0,0,0,0,151,4,53,0,0,0,0,8,8,4,59,0,0,0,0,0,132,4,53],[0,0,4,250,0,0,97,61,0,0,7,173,8,128,1,151,0,0,0,248,9,160,2,16,0,0,0,0,8,137,1,159],[0,0,7,179,8,128,1,199,0,0,0,0,0,132,4,53,0,0,0,3,4,160,2,16,0,0,0,248,4,64,1,95],[0,0,0,0,4,69,1,207,0,0,0,33,5,112,0,57,0,0,0,0,0,69,4,53,0,0,27,184,0,0,1,61],[0,0,0,64,13,0,4,61,0,0,7,172,11,208,0,156,0,0,4,10,0,0,33,61,0,0,0,64,11,208,0,57],[0,0,0,64,0,176,4,63,0,0,0,32,15,208,0,57,0,0,0,9,6,0,0,41,0,0,0,0,0,111,4,53],[0,0,0,8,6,0,0,41,0,0,0,0,0,109,4,53,0,0,0,0,11,6,0,75,0,0,4,250,0,0,97,61],[0,0,0,248,11,224,2,16,0,0,7,169,12,0,0,65,0,0,0,0,14,14,0,75,0,0,0,0,12,11,192,25],[0,0,0,7,11,192,1,175,0,0,0,0,0,191,4,53,0,0,0,5,10,160,2,112,0,0,0,0,10,13,0,31],[0,0,0,0,10,4,4,51,0,0,0,0,10,90,0,25,0,0,0,0,11,8,4,51,0,0,0,0,10,186,0,25],[0,0,0,0,11,7,4,51,0,0,0,0,10,186,0,25,0,0,0,0,11,2,4,51,0,0,0,0,10,186,0,25],[0,0,0,0,11,9,4,51,0,0,0,0,10,186,0,25,0,0,0,0,11,13,4,51,0,0,0,0,10,186,0,25],[0,0,0,64,14,0,4,61,0,0,7,168,10,160,1,151,0,0,0,56,11,160,0,140,0,6,0,64,0,224,0,61],[0,11,0,32,0,224,0,61,0,0,28,119,0,0,65,61,0,0,0,32,11,160,2,112,0,0,7,164,12,160,0,156],[0,0,0,0,11,10,160,25,0,0,7,164,12,160,0,156,0,0,0,0,6,0,0,25,0,0,0,4,6,0,32,57],[0,0,0,2,12,96,1,191,0,0,255,255,15,176,0,140,0,0,0,0,12,6,160,25,0,0,0,16,15,176,2,112],[0,0,0,0,15,11,160,25,0,0,0,255,11,240,0,140,0,0,0,0,6,0,0,25,0,0,0,1,6,0,32,57],[0,0,7,172,11,224,0,156,0,0,4,10,0,0,33,61,0,0,0,0,12,108,1,159,0,0,0,6,6,0,0,41],[0,0,0,64,0,96,4,63,0,0,0,9,6,0,0,41,0,0,0,11,11,0,0,41,0,0,0,0,0,107,4,53],[0,0,0,2,11,192,0,58,0,0,0,0,0,190,4,53,0,0,4,250,0,0,97,61,0,0,0,248,11,192,2,16],[0,0,0,7,11,176,1,175,0,0,7,179,11,176,1,199,0,0,0,11,6,0,0,41,0,0,0,0,0,182,4,53],[0,0,0,3,11,192,2,16,0,0,0,248,11,176,1,95,0,0,0,0,10,186,1,207,0,0,0,33,11,224,0,57],[0,0,0,0,0,171,4,53,0,0,28,135,0,0,1,61,0,0,0,64,1,0,4,61,0,0,0,68,2,16,0,57],[0,0,7,200,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,15,3,0,0,57],[0,0,12,159,0,0,1,61,0,0,0,64,13,0,4,61,0,0,7,172,11,208,0,156,0,0,4,10,0,0,33,61],[0,0,0,64,11,208,0,57,0,0,0,64,0,176,4,63,0,0,0,32,15,208,0,57,0,0,0,9,6,0,0,41],[0,0,0,0,0,111,4,53,0,0,0,8,6,0,0,41,0,0,0,0,0,109,4,53,0,0,0,0,11,6,0,75],[0,0,4,250,0,0,97,61,0,0,0,248,11,224,2,16,0,0,7,169,12,0,0,65,0,0,0,0,14,14,0,75],[0,0,0,0,12,11,192,25,0,0,0,7,11,192,1,175,0,0,0,0,0,191,4,53,0,0,0,5,10,160,2,112],[0,0,0,0,10,13,0,31,0,0,0,0,10,4,4,51,0,0,0,0,10,90,0,25,0,0,0,0,11,8,4,51],[0,0,0,0,10,186,0,25,0,0,0,0,11,7,4,51,0,0,0,0,10,186,0,25,0,0,0,0,11,2,4,51],[0,0,0,0,10,186,0,25,0,0,0,0,11,9,4,51,0,0,0,0,10,186,0,25,0,0,0,0,11,13,4,51],[0,0,0,0,10,186,0,25,0,0,0,64,14,0,4,61,0,0,7,168,10,160,1,151,0,0,0,56,11,160,0,140],[0,6,0,64,0,224,0,61,0,11,0,32,0,224,0,61,0,0,29,44,0,0,65,61,0,0,0,32,11,160,2,112],[0,0,7,164,12,160,0,156,0,0,0,0,11,10,160,25,0,0,7,164,12,160,0,156,0,0,0,0,6,0,0,25],[0,0,0,4,6,0,32,57,0,0,0,2,12,96,1,191,0,0,255,255,15,176,0,140,0,0,0,0,12,6,160,25],[0,0,0,16,15,176,2,112,0,0,0,0,15,11,160,25,0,0,0,255,11,240,0,140,0,0,0,0,6,0,0,25],[0,0,0,1,6,0,32,57,0,0,7,172,11,224,0,156,0,0,4,10,0,0,33,61,0,0,0,0,12,108,1,159],[0,0,0,6,6,0,0,41,0,0,0,64,0,96,4,63,0,0,0,9,6,0,0,41,0,0,0,11,11,0,0,41],[0,0,0,0,0,107,4,53,0,0,0,2,11,192,0,58,0,0,0,0,0,190,4,53,0,0,4,250,0,0,97,61],[0,0,0,248,11,192,2,16,0,0,0,7,11,176,1,175,0,0,7,179,11,176,1,199,0,0,0,11,6,0,0,41],[0,0,0,0,0,182,4,53,0,0,0,3,11,192,2,16,0,0,0,248,11,176,1,95,0,0,0,0,10,186,1,207],[0,0,0,33,11,224,0,57,0,0,0,0,0,171,4,53,0,0,29,60,0,0,1,61,0,0,7,172,10,112,0,156],[0,0,4,10,0,0,33,61,0,0,0,64,0,144,4,63,0,0,0,1,9,0,0,58,0,0,0,0,0,151,4,53],[0,0,0,0,8,8,4,59,0,0,0,0,0,132,4,53,0,0,4,250,0,0,97,61,0,0,7,173,8,128,1,151],[0,0,0,248,5,80,2,16,0,0,0,0,5,133,1,159,0,0,7,178,5,80,0,65,0,0,0,0,0,84,4,53],[0,0,0,64,4,0,4,61,0,0,0,32,5,64,0,57,0,0,0,0,8,7,4,51,0,0,0,0,9,8,0,75],[0,0,27,197,0,0,97,61,0,0,0,0,9,0,0,25,0,0,0,0,10,89,0,25,0,0,0,32,9,144,0,57],[0,0,0,0,11,121,0,25,0,0,0,0,11,11,4,51,0,0,0,0,0,186,4,53,0,0,0,0,10,137,0,75],[0,0,27,190,0,0,65,61,0,0,0,0,7,88,0,25,0,0,0,0,0,7,4,53,0,0,0,10,8,0,0,41],[0,0,0,0,8,8,4,51,0,0,0,0,9,8,0,75,0,0,27,211,0,0,97,61,0,0,0,0,9,0,0,25],[0,0,0,0,10,121,0,25,0,0,0,32,9,144,0,57,0,0,0,10,11,144,0,41,0,0,0,0,11,11,4,51],[0,0,0,0,0,186,4,53,0,0,0,0,10,137,0,75,0,0,27,204,0,0,65,61,0,0,0,0,7,120,0,25],[0,0,0,0,0,7,4,53,0,0,0,9,8,0,0,41,0,0,0,0,8,8,4,51,0,0,0,0,9,8,0,75],[0,0,27,225,0,0,97,61,0,0,0,0,9,0,0,25,0,0,0,0,10,121,0,25,0,0,0,32,9,144,0,57],[0,0,0,9,11,144,0,41,0,0,0,0,11,11,4,51,0,0,0,0,0,186,4,53,0,0,0,0,10,137,0,75],[0,0,27,218,0,0,65,61,0,0,0,0,7,120,0,25,0,0,0,0,0,7,4,53,0,0,0,8,8,0,0,41],[0,0,0,0,8,8,4,51,0,0,0,0,9,8,0,75,0,0,27,239,0,0,97,61,0,0,0,0,9,0,0,25],[0,0,0,0,10,121,0,25,0,0,0,32,9,144,0,57,0,0,0,8,11,144,0,41,0,0,0,0,11,11,4,51],[0,0,0,0,0,186,4,53,0,0,0,0,10,137,0,75,0,0,27,232,0,0,65,61,0,0,0,0,7,120,0,25],[0,0,0,0,0,7,4,53,0,0,0,6,8,0,0,41,0,0,0,0,8,8,4,51,0,0,0,0,9,8,0,75],[0,0,27,253,0,0,97,61,0,0,0,0,9,0,0,25,0,0,0,0,10,121,0,25,0,0,0,32,9,144,0,57],[0,0,0,6,11,144,0,41,0,0,0,0,11,11,4,51,0,0,0,0,0,186,4,53,0,0,0,0,10,137,0,75],[0,0,27,246,0,0,65,61,0,0,0,0,7,120,0,25,0,0,0,0,0,7,4,53,0,0,0,5,8,0,0,41],[0,0,0,0,8,8,4,51,0,0,0,0,9,8,0,75,0,0,28,11,0,0,97,61,0,0,0,0,9,0,0,25],[0,0,0,0,10,121,0,25,0,0,0,32,9,144,0,57,0,0,0,5,11,144,0,41,0,0,0,0,11,11,4,51],[0,0,0,0,0,186,4,53,0,0,0,0,10,137,0,75,0,0,28,4,0,0,65,61,0,0,0,0,6,98,3,79],[0,0,0,0,2,120,0,25,0,0,0,31,7,48,1,143,0,0,0,0,0,2,4,53,0,0,0,5,8,48,2,114],[0,0,28,26,0,0,97,61,0,0,0,0,9,0,0,25,0,0,0,5,10,144,2,16,0,0,0,0,11,162,0,25],[0,0,0,0,10,166,3,79,0,0,0,0,10,10,4,59,0,0,0,0,0,171,4,53,0,0,0,1,9,144,0,57],[0,0,0,0,10,137,0,75,0,0,28,18,0,0,65,61,0,0,0,0,9,7,0,75,0,0,28,41,0,0,97,61],[0,0,0,5,8,128,2,16,0,0,0,0,6,134,3,79,0,0,0,0,8,130,0,25,0,0,0,3,7,112,2,16],[0,0,0,0,9,8,4,51,0,0,0,0,9,121,1,207,0,0,0,0,9,121,2,47,0,0,0,0,6,6,4,59],[0,0,1,0,7,112,0,137,0,0,0,0,6,118,2,47,0,0,0,0,6,118,1,207,0,0,0,0,6,150,1,159],[0,0,0,0,0,104,4,53,0,0,0,0,2,50,0,25,0,0,0,0,0,2,4,53,0,0,0,0,3,1,4,51],[0,0,0,0,6,3,0,75,0,0,28,54,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,0,7,38,0,25],[0,0,0,32,6,96,0,57,0,0,0,0,8,22,0,25,0,0,0,0,8,8,4,51,0,0,0,0,0,135,4,53],[0,0,0,0,7,54,0,75,0,0,28,47,0,0,65,61,0,0,0,0,1,35,0,25,0,0,0,0,0,1,4,53],[0,0,0,4,2,0,0,41,0,0,0,0,2,2,4,51,0,0,0,0,3,2,0,75,0,0,28,68,0,0,97,61],[0,0,0,0,3,0,0,25,0,0,0,0,6,19,0,25,0,0,0,32,3,48,0,57,0,0,0,4,7,48,0,41],[0,0,0,0,7,7,4,51,0,0,0,0,0,118,4,53,0,0,0,0,6,35,0,75,0,0,28,61,0,0,65,61],[0,0,0,0,1,18,0,25,0,0,0,0,0,1,4,53,0,0,0,3,2,0,0,41,0,0,0,0,2,2,4,51],[0,0,0,0,3,2,0,75,0,0,28,82,0,0,97,61,0,0,0,0,3,0,0,25,0,0,0,0,6,19,0,25],[0,0,0,32,3,48,0,57,0,0,0,3,7,48,0,41,0,0,0,0,7,7,4,51,0,0,0,0,0,118,4,53],[0,0,0,0,6,35,0,75,0,0,28,75,0,0,65,61,0,0,0,0,1,18,0,25,0,0,0,0,0,1,4,53],[0,0,0,0,1,65,0,73,0,0,0,32,2,16,0,138,0,0,0,0,0,36,4,53,0,0,0,31,1,16,0,57],[0,0,0,7,2,16,1,127,0,0,0,0,1,66,0,25,0,0,0,0,2,33,0,75,0,0,0,0,2,0,0,25],[0,0,0,1,2,0,64,57,0,0,7,168,3,16,0,156,0,0,4,10,0,0,33,61,0,0,0,1,2,32,1,144],[0,0,4,10,0,0,193,61,0,0,0,64,0,16,4,63,0,0,7,164,1,0,0,65,0,0,7,164,2,80,0,156],[0,0,0,0,5,1,128,25,0,0,0,64,2,80,2,16,0,0,0,0,3,4,4,51,0,0,7,164,4,48,0,156],[0,0,0,0,3,1,128,25,0,0,0,96,3,48,2,16,0,0,0,0,2,35,1,159,0,0,0,0,3,0,4,20],[0,0,7,164,4,48,0,156,0,0,0,0,3,1,128,25,0,0,0,192,1,48,2,16,0,0,0,0,1,33,1,159],[0,0,7,181,1,16,1,199,0,0,128,16,2,0,0,57,30,139,30,129,0,0,4,15,0,0,0,1,2,32,1,144],[0,0,0,204,0,0,97,61,0,0,0,0,1,1,4,59,0,0,14,74,0,0,1,61,0,0,7,172,11,224,0,156],[0,0,4,10,0,0,33,61,0,0,0,6,6,0,0,41,0,0,0,64,0,96,4,63,0,0,0,9,6,0,0,41],[0,0,0,11,11,0,0,41,0,0,0,0,0,107,4,53,0,0,0,8,6,0,0,41,0,0,0,0,0,110,4,53],[0,0,0,0,11,6,0,75,0,0,4,250,0,0,97,61,0,0,0,248,10,160,2,16,0,0,0,7,10,160,1,175],[0,0,7,178,10,160,0,65,0,0,0,11,6,0,0,41,0,0,0,0,0,166,4,53,0,0,0,64,6,0,4,61],[0,0,0,32,10,96,0,57,0,0,7,180,11,0,0,65,0,9,0,0,0,10,0,29,0,0,0,0,0,186,4,53],[0,11,0,0,0,6,0,29,0,0,0,33,12,96,0,57,0,0,0,0,15,14,4,51,0,0,0,0,11,15,0,75],[0,0,28,153,0,0,97,61,0,0,0,0,11,0,0,25,0,0,0,0,10,203,0,25,0,0,0,32,11,176,0,57],[0,0,0,0,6,235,0,25,0,0,0,0,6,6,4,51,0,0,0,0,0,106,4,53,0,0,0,0,6,251,0,75],[0,0,28,146,0,0,65,61,0,0,0,0,12,207,0,25,0,0,0,0,0,12,4,53,0,0,0,0,14,4,4,51],[0,0,0,0,6,14,0,75,0,0,28,166,0,0,97,61,0,0,0,0,11,0,0,25,0,0,0,0,6,203,0,25],[0,0,0,32,11,176,0,57,0,0,0,0,10,75,0,25,0,0,0,0,10,10,4,51,0,0,0,0,0,166,4,53],[0,0,0,0,6,235,0,75,0,0,28,159,0,0,65,61,0,0,0,0,12,206,0,25,0,0,0,0,0,12,4,53],[0,0,0,0,14,8,4,51,0,0,0,0,4,14,0,75,0,0,28,179,0,0,97,61,0,0,0,0,4,0,0,25],[0,0,0,0,6,196,0,25,0,0,0,32,4,64,0,57,0,0,0,0,10,132,0,25,0,0,0,0,10,10,4,51],[0,0,0,0,0,166,4,53,0,0,0,0,6,228,0,75,0,0,28,172,0,0,65,61,0,0,0,12,4,16,3,96],[0,0,0,0,1,206,0,25,0,0,0,31,6,80,1,143,0,0,0,0,0,1,4,53,0,0,0,5,8,80,2,114],[0,0,28,194,0,0,97,61,0,0,0,0,12,0,0,25,0,0,0,5,10,192,2,16,0,0,0,0,11,161,0,25],[0,0,0,0,10,164,3,79,0,0,0,0,10,10,4,59,0,0,0,0,0,171,4,53,0,0,0,1,12,192,0,57],[0,0,0,0,10,140,0,75,0,0,28,186,0,0,65,61,0,0,0,0,10,6,0,75,0,0,28,209,0,0,97,61],[0,0,0,5,8,128,2,16,0,0,0,0,4,132,3,79,0,0,0,0,8,129,0,25,0,0,0,3,6,96,2,16],[0,0,0,0,10,8,4,51,0,0,0,0,10,106,1,207,0,0,0,0,10,106,2,47,0,0,0,0,4,4,4,59],[0,0,1,0,6,96,0,137,0,0,0,0,4,100,2,47,0,0,0,0,4,100,1,207,0,0,0,0,4,164,1,159],[0,0,0,0,0,72,4,53,0,0,0,0,1,81,0,25,0,0,0,0,0,1,4,53,0,0,0,0,4,7,4,51],[0,0,0,0,5,4,0,75,0,0,28,222,0,0,97,61,0,0,0,0,5,0,0,25,0,0,0,0,6,21,0,25],[0,0,0,32,5,80,0,57,0,0,0,0,8,117,0,25,0,0,0,0,8,8,4,51,0,0,0,0,0,134,4,53],[0,0,0,0,6,69,0,75,0,0,28,215,0,0,65,61,0,0,0,0,1,20,0,25,0,0,0,0,0,1,4,53],[0,0,0,0,4,13,4,51,0,0,0,0,5,4,0,75,0,0,28,235,0,0,97,61,0,0,0,0,5,0,0,25],[0,0,0,0,6,21,0,25,0,0,0,32,5,80,0,57,0,0,0,0,7,213,0,25,0,0,0,0,7,7,4,51],[0,0,0,0,0,118,4,53,0,0,0,0,6,69,0,75,0,0,28,228,0,0,65,61,0,0,0,0,1,20,0,25],[0,0,0,0,0,1,4,53,0,0,0,0,4,2,4,51,0,0,0,0,5,4,0,75,0,0,28,248,0,0,97,61],[0,0,0,0,5,0,0,25,0,0,0,0,6,21,0,25,0,0,0,32,5,80,0,57,0,0,0,0,7,37,0,25],[0,0,0,0,7,7,4,51,0,0,0,0,0,118,4,53,0,0,0,0,6,69,0,75,0,0,28,241,0,0,65,61],[0,0,0,0,1,20,0,25,0,0,0,0,0,1,4,53,0,0,0,0,2,9,4,51,0,0,0,0,4,2,0,75],[0,0,29,5,0,0,97,61,0,0,0,0,4,0,0,25,0,0,0,0,5,20,0,25,0,0,0,32,4,64,0,57],[0,0,0,0,6,148,0,25,0,0,0,0,6,6,4,51,0,0,0,0,0,101,4,53,0,0,0,0,5,36,0,75],[0,0,28,254,0,0,65,61,0,0,0,0,1,18,0,25,0,0,0,0,0,1,4,53,0,0,0,11,4,0,0,41],[0,0,0,0,1,65,0,73,0,0,0,32,2,16,0,138,0,0,0,0,0,36,4,53,0,0,0,31,1,16,0,57],[0,0,0,0,2,49,1,111,0,0,0,0,1,66,0,25,0,0,0,0,2,33,0,75,0,0,0,0,2,0,0,25],[0,0,0,1,2,0,64,57,0,0,7,168,3,16,0,156,0,0,4,10,0,0,33,61,0,0,0,1,2,32,1,144],[0,0,4,10,0,0,193,61,0,0,0,64,0,16,4,63,0,0,7,164,1,0,0,65,0,0,0,9,3,0,0,41],[0,0,7,164,2,48,0,156,0,0,0,0,3,1,128,25,0,0,0,64,2,48,2,16,0,0,0,11,3,0,0,41],[0,0,0,0,3,3,4,51,0,0,7,164,4,48,0,156,0,0,0,0,3,1,128,25,0,0,0,96,3,48,2,16],[0,0,0,0,2,35,1,159,0,0,0,0,3,0,4,20,0,0,7,164,4,48,0,156,0,0,0,0,3,1,128,25],[0,0,0,192,1,48,2,16,0,0,0,0,1,33,1,159,0,0,7,181,1,16,1,199,0,0,128,16,2,0,0,57],[30,139,30,129,0,0,4,15,0,0,0,1,2,32,1,144,0,0,0,204,0,0,97,61,0,0,29,224,0,0,1,61],[0,0,7,172,11,224,0,156,0,0,4,10,0,0,33,61,0,0,0,6,6,0,0,41,0,0,0,64,0,96,4,63],[0,0,0,9,6,0,0,41,0,0,0,11,11,0,0,41,0,0,0,0,0,107,4,53,0,0,0,8,6,0,0,41],[0,0,0,0,0,110,4,53,0,0,0,0,11,6,0,75,0,0,4,250,0,0,97,61,0,0,0,248,10,160,2,16],[0,0,0,7,10,160,1,175,0,0,7,178,10,160,0,65,0,0,0,11,6,0,0,41,0,0,0,0,0,166,4,53],[0,0,0,64,6,0,4,61,0,0,0,32,10,96,0,57,0,0,7,181,11,0,0,65,0,9,0,0,0,10,0,29],[0,0,0,0,0,186,4,53,0,11,0,0,0,6,0,29,0,0,0,33,12,96,0,57,0,0,0,0,15,14,4,51],[0,0,0,0,11,15,0,75,0,0,29,78,0,0,97,61,0,0,0,0,11,0,0,25,0,0,0,0,10,203,0,25],[0,0,0,32,11,176,0,57,0,0,0,0,6,235,0,25,0,0,0,0,6,6,4,51,0,0,0,0,0,106,4,53],[0,0,0,0,6,251,0,75,0,0,29,71,0,0,65,61,0,0,0,0,12,207,0,25,0,0,0,0,0,12,4,53],[0,0,0,0,14,4,4,51,0,0,0,0,6,14,0,75,0,0,29,91,0,0,97,61,0,0,0,0,11,0,0,25],[0,0,0,0,6,203,0,25,0,0,0,32,11,176,0,57,0,0,0,0,10,75,0,25,0,0,0,0,10,10,4,51],[0,0,0,0,0,166,4,53,0,0,0,0,6,235,0,75,0,0,29,84,0,0,65,61,0,0,0,0,12,206,0,25],[0,0,0,0,0,12,4,53,0,0,0,0,14,8,4,51,0,0,0,0,4,14,0,75,0,0,29,104,0,0,97,61],[0,0,0,0,4,0,0,25,0,0,0,0,6,196,0,25,0,0,0,32,4,64,0,57,0,0,0,0,10,132,0,25],[0,0,0,0,10,10,4,51,0,0,0,0,0,166,4,53,0,0,0,0,6,228,0,75,0,0,29,97,0,0,65,61],[0,0,0,12,4,16,3,96,0,0,0,0,1,206,0,25,0,0,0,31,6,80,1,143,0,0,0,0,0,1,4,53],[0,0,0,5,8,80,2,114,0,0,29,119,0,0,97,61,0,0,0,0,12,0,0,25,0,0,0,5,10,192,2,16],[0,0,0,0,11,161,0,25,0,0,0,0,10,164,3,79,0,0,0,0,10,10,4,59,0,0,0,0,0,171,4,53],[0,0,0,1,12,192,0,57,0,0,0,0,10,140,0,75,0,0,29,111,0,0,65,61,0,0,0,0,10,6,0,75],[0,0,29,134,0,0,97,61,0,0,0,5,8,128,2,16,0,0,0,0,4,132,3,79,0,0,0,0,8,129,0,25],[0,0,0,3,6,96,2,16,0,0,0,0,10,8,4,51,0,0,0,0,10,106,1,207,0,0,0,0,10,106,2,47],[0,0,0,0,4,4,4,59,0,0,1,0,6,96,0,137,0,0,0,0,4,100,2,47,0,0,0,0,4,100,1,207],[0,0,0,0,4,164,1,159,0,0,0,0,0,72,4,53,0,0,0,0,1,81,0,25,0,0,0,0,0,1,4,53],[0,0,0,0,4,7,4,51,0,0,0,0,5,4,0,75,0,0,29,147,0,0,97,61,0,0,0,0,5,0,0,25],[0,0,0,0,6,21,0,25,0,0,0,32,5,80,0,57,0,0,0,0,8,117,0,25,0,0,0,0,8,8,4,51],[0,0,0,0,0,134,4,53,0,0,0,0,6,69,0,75,0,0,29,140,0,0,65,61,0,0,0,0,1,20,0,25],[0,0,0,0,0,1,4,53,0,0,0,0,4,13,4,51,0,0,0,0,5,4,0,75,0,0,29,160,0,0,97,61],[0,0,0,0,5,0,0,25,0,0,0,0,6,21,0,25,0,0,0,32,5,80,0,57,0,0,0,0,7,213,0,25],[0,0,0,0,7,7,4,51,0,0,0,0,0,118,4,53,0,0,0,0,6,69,0,75,0,0,29,153,0,0,65,61],[0,0,0,0,1,20,0,25,0,0,0,0,0,1,4,53,0,0,0,0,4,2,4,51,0,0,0,0,5,4,0,75],[0,0,29,173,0,0,97,61,0,0,0,0,5,0,0,25,0,0,0,0,6,21,0,25,0,0,0,32,5,80,0,57],[0,0,0,0,7,37,0,25,0,0,0,0,7,7,4,51,0,0,0,0,0,118,4,53,0,0,0,0,6,69,0,75],[0,0,29,166,0,0,65,61,0,0,0,0,1,20,0,25,0,0,0,0,0,1,4,53,0,0,0,0,2,9,4,51],[0,0,0,0,4,2,0,75,0,0,29,186,0,0,97,61,0,0,0,0,4,0,0,25,0,0,0,0,5,20,0,25],[0,0,0,32,4,64,0,57,0,0,0,0,6,148,0,25,0,0,0,0,6,6,4,51,0,0,0,0,0,101,4,53],[0,0,0,0,5,36,0,75,0,0,29,179,0,0,65,61,0,0,0,0,1,18,0,25,0,0,0,0,0,1,4,53],[0,0,0,11,4,0,0,41,0,0,0,0,1,65,0,73,0,0,0,32,2,16,0,138,0,0,0,0,0,36,4,53],[0,0,0,31,1,16,0,57,0,0,0,0,2,49,1,111,0,0,0,0,1,66,0,25,0,0,0,0,2,33,0,75],[0,0,0,0,2,0,0,25,0,0,0,1,2,0,64,57,0,0,7,168,3,16,0,156,0,0,4,10,0,0,33,61],[0,0,0,1,2,32,1,144,0,0,4,10,0,0,193,61,0,0,0,64,0,16,4,63,0,0,7,164,1,0,0,65],[0,0,0,9,3,0,0,41,0,0,7,164,2,48,0,156,0,0,0,0,3,1,128,25,0,0,0,64,2,48,2,16],[0,0,0,11,3,0,0,41,0,0,0,0,3,3,4,51,0,0,7,164,4,48,0,156,0,0,0,0,3,1,128,25],[0,0,0,96,3,48,2,16,0,0,0,0,2,35,1,159,0,0,0,0,3,0,4,20,0,0,7,164,4,48,0,156],[0,0,0,0,3,1,128,25,0,0,0,192,1,48,2,16,0,0,0,0,1,33,1,159,0,0,7,181,1,16,1,199],[0,0,128,16,2,0,0,57,30,139,30,129,0,0,4,15,0,0,0,1,2,32,1,144,0,0,0,204,0,0,97,61],[0,0,0,0,1,1,4,59,0,0,0,0,2,0,4,21,0,0,0,10,2,32,0,105,0,0,0,0,2,0,0,2],[0,0,14,74,0,0,1,61,0,0,7,164,4,16,1,151,0,0,0,0,3,0,4,20,0,0,0,17,5,0,3,103],[0,1,0,0,0,69,3,85,0,0,0,0,1,18,0,25,0,0,0,0,2,33,0,75,0,0,0,0,2,0,0,25],[0,0,0,1,2,0,64,57,0,0,0,1,2,32,1,144,0,0,30,66,0,0,193,61,0,0,0,0,6,0,0,49],[0,0,0,0,2,22,0,75,0,0,30,66,0,0,65,61,0,0,0,0,2,69,3,79,0,0,0,0,1,22,0,73],[0,0,7,164,1,16,1,151,0,1,0,0,0,18,3,229,0,0,7,182,4,48,0,156,0,0,30,70,0,0,129,61],[0,0,0,0,1,18,3,223,0,0,0,192,2,48,2,16,0,0,7,183,2,32,1,151,0,0,7,184,2,32,1,199],[0,1,0,0,0,33,3,181,0,0,0,0,1,33,3,175,0,0,128,16,2,0,0,57,30,139,30,134,0,0,4,15],[0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,7,164,3,48,1,151,0,0,0,1,2,32,1,144],[0,0,30,77,0,0,97,61,0,0,0,63,2,48,0,57,0,0,7,185,4,32,1,151,0,0,0,64,2,0,4,61],[0,0,0,0,4,66,0,25,0,0,0,0,5,36,0,75,0,0,0,0,5,0,0,25,0,0,0,1,5,0,64,57],[0,0,7,168,6,64,0,156,0,0,30,104,0,0,33,61,0,0,0,1,5,80,1,144,0,0,30,104,0,0,193,61],[0,0,0,64,0,64,4,63,0,0,0,0,4,50,4,54,0,0,0,31,5,48,0,57,0,0,0,5,5,80,2,114],[0,0,30,32,0,0,97,61,0,0,0,0,6,0,0,49,0,0,0,17,6,96,3,103,0,0,0,0,7,0,0,25],[0,0,0,5,8,112,2,16,0,0,0,0,9,132,0,25,0,0,0,0,8,134,3,79,0,0,0,0,8,8,4,59],[0,0,0,0,0,137,4,53,0,0,0,1,7,112,0,57,0,0,0,0,8,87,0,75,0,0,30,24,0,0,65,61],[0,0,0,0,5,0,0,75,0,0,30,34,0,0,97,61,0,0,0,31,5,48,1,143,0,0,0,5,3,48,2,114],[0,0,30,46,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,116,0,25],[0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57],[0,0,0,0,7,54,0,75,0,0,30,38,0,0,65,61,0,0,0,0,6,5,0,75,0,0,30,61,0,0,97,61],[0,0,0,5,3,48,2,16,0,0,0,0,1,49,3,79,0,0,0,0,3,52,0,25,0,0,0,3,5,80,2,16],[0,0,0,0,6,3,4,51,0,0,0,0,6,86,1,207,0,0,0,0,6,86,2,47,0,0,0,0,1,1,4,59],[0,0,1,0,5,80,0,137,0,0,0,0,1,81,2,47,0,0,0,0,1,81,1,207,0,0,0,0,1,97,1,159],[0,0,0,0,0,19,4,53,0,0,0,0,1,2,4,51,0,0,0,32,1,16,0,140,0,0,30,110,0,0,193,61],[0,0,0,0,1,4,4,51,0,0,0,0,0,1,4,45,0,0,7,201,1,0,0,65,0,0,0,0,0,16,4,53],[0,0,0,17,1,0,0,57,0,0,30,107,0,0,1,61,0,0,0,64,1,0,4,61,0,0,0,68,2,16,0,57],[0,0,7,198,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,8,3,0,0,57],[0,0,30,116,0,0,1,61,0,0,0,31,4,48,1,143,0,0,0,5,2,48,2,114,0,0,30,88,0,0,97,61],[0,0,0,0,5,0,0,25,0,0,0,5,6,80,2,16,0,0,0,0,7,97,3,79,0,0,0,0,7,7,4,59],[0,0,0,0,0,118,4,53,0,0,0,1,5,80,0,57,0,0,0,0,6,37,0,75,0,0,30,81,0,0,65,61],[0,0,0,0,5,4,0,75,0,0,30,102,0,0,97,61,0,0,0,3,4,64,2,16,0,0,0,5,2,32,2,16],[0,0,0,0,5,2,4,51,0,0,0,0,5,69,1,207,0,0,0,0,5,69,2,47,0,0,0,0,1,33,3,79],[0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207],[0,0,0,0,1,81,1,159,0,0,0,0,0,18,4,53,0,0,0,96,1,48,2,16,0,0,30,141,0,1,4,48],[0,0,7,201,1,0,0,65,0,0,0,0,0,16,4,53,0,0,0,65,1,0,0,57,0,0,0,4,0,16,4,63],[0,0,7,202,1,0,0,65,0,0,30,141,0,1,4,48,0,0,0,64,1,0,4,61,0,0,0,68,2,16,0,57],[0,0,7,187,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,31,3,0,0,57],[0,0,0,0,0,50,4,53,0,0,7,188,2,0,0,65,0,0,0,0,0,33,4,53,0,0,0,4,2,16,0,57],[0,0,0,32,3,0,0,57,0,0,0,0,0,50,4,53,0,0,7,164,2,0,0,65,0,0,7,164,3,16,0,156],[0,0,0,0,1,2,128,25,0,0,0,64,1,16,2,16,0,0,7,189,1,16,1,199,0,0,30,141,0,1,4,48],[0,0,0,0,0,1,4,47,0,0,30,132,0,33,4,35,0,0,0,1,2,0,0,57,0,0,0,0,0,1,4,45],[0,0,0,0,2,0,0,25,0,0,0,0,0,1,4,45,0,0,30,137,0,33,4,35,0,0,0,1,2,0,0,57],[0,0,0,0,0,1,4,45,0,0,0,0,2,0,0,25,0,0,0,0,0,1,4,45,0,0,30,139,0,0,4,50],[0,0,30,140,0,1,4,46,0,0,30,141,0,1,4,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255],[0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,1,0,0,0,0,0,0,0,0,0],[255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[235,228,163,215,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255],[128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[154,138,5,146,172,137,197,173,59,198,223,130,36,193,123,72,89,118,245,151,223,16,78,226,13,13,244,21,36,31,103,11],[2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,191],[0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],[129,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[148,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[184,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[192,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[248,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0],[0,0,0,0,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,255,255,255,224],[7,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],[107,101,99,99,97,107,50,53,54,32,114,101,116,117,114,110,101,100,32,105,110,118,97,108,105,100,32,100,97,116,97,0],[8,195,121,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,0,0,0,0,0,0,0,0,0],[132,142,27,250,26,196,227,87,107,114,139,218,103,33,178,21,199,10,119,153,165,180,134,98,130,167,27,171,149,75,170,200],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,254,31],[194,248,120,113,118,184,172,107,247,33,91,74,220,193,224,105,191,74,184,45,154,177,223,5,165,122,145,212,37,147,91,110],[173,124,91,239,2,120,22,168,0,218,23,54,68,79,181,138,128,126,244,201,96,59,120,72,103,63,126,58,104,235,20,165],[25,180,83,206,69,170,170,243,163,0,245,169,236,149,134,155,79,40,171,16,67,11,87,46,226,24,195,166,165,224,125,111],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,95],[25,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,127],[79,118,101,114,102,108,111,119,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[128,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[73,110,118,97,108,105,100,32,118,32,118,97,108,117,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[78,72,123,113,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,159],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0],[85,110,115,117,112,112,111,114,116,101,100,32,116,120,32,116,121,112,101,0,0,0,0,0,0,0,0,0,0,0,0,0],[69,110,99,111,100,105,110,103,32,117,110,115,117,112,112,111,114,116,101,100,32,116,120,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,128,0,0,0,0,0,0,0,0],[174,196,155,218,68,154,152,84,42,179,140,69,242,32,6,193,149,34,94,126,187,249,182,101,208,88,111,31,201,177,65,6]],"0x000000000000000000000000000000000000800d":[[0,0,0,0,8,1,0,25,0,0,0,96,8,128,2,112,0,0,0,17,8,128,1,151,0,0,0,1,9,32,1,144],[0,0,0,56,0,0,193,61,0,0,0,2,2,32,1,144,0,0,0,54,0,0,97,61,0,0,0,5,2,48,0,140],[0,0,0,54,0,0,129,61,0,0,0,32,2,128,2,16,0,0,0,0,2,35,0,25,0,0,0,1,2,32,0,57],[0,0,0,0,9,0,4,17,0,0,0,0,0,146,4,31,0,0,0,1,2,48,0,140,0,0,0,26,0,0,161,61],[0,0,0,2,2,48,0,140,0,0,0,34,0,0,97,61,0,0,0,3,2,48,0,140,0,0,0,37,0,0,97,61],[0,0,0,4,2,48,0,140,0,0,0,54,0,0,193,61,0,0,0,0,0,84,4,30,0,0,0,0,0,118,4,30],[0,0,0,0,3,0,0,25,0,0,0,41,0,0,1,61,0,0,0,0,2,3,0,75,0,0,0,41,0,0,97,61],[0,0,0,1,2,48,0,140,0,0,0,54,0,0,193,61,0,0,0,0,2,1,4,59,0,0,0,0,0,36,4,30],[0,0,0,32,3,0,0,57,0,0,0,41,0,0,1,61,0,0,0,0,0,84,4,30,0,0,0,0,3,0,0,25],[0,0,0,41,0,0,1,61,0,0,0,0,0,84,4,30,0,0,0,0,2,1,4,59,0,0,0,0,0,38,4,30],[0,0,0,32,3,0,0,57,0,0,0,0,2,131,0,75,0,0,0,52,0,0,129,61,0,0,0,32,2,48,0,57],[0,0,0,0,2,33,3,79,0,0,0,0,4,49,3,79,0,0,0,0,4,4,4,59,0,0,0,0,2,2,4,59],[0,0,0,0,0,36,4,30,0,0,0,64,3,48,0,57,0,0,0,0,2,131,0,75,0,0,0,43,0,0,65,61],[0,0,0,0,1,0,0,25,0,0,0,0,0,1,4,45,0,0,0,0,1,0,0,25,0,0,0,63,0,1,4,48],[0,0,0,32,1,0,0,57,0,0,1,0,0,16,4,67,0,0,1,32,0,0,4,67,0,0,0,18,1,0,0,65],[0,0,0,62,0,1,4,46,0,0,0,61,0,0,4,50,0,0,0,62,0,1,4,46,0,0,0,63,0,1,4,48],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255],[0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,1,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[221,20,130,158,8,71,137,243,160,83,8,122,158,110,111,137,21,66,92,151,31,136,99,209,24,178,150,169,144,41,162,168]],"0x000000000000000000000000000000000000800e":[[0,18,0,0,0,0,0,2,0,12,0,0,0,0,0,2,0,0,0,0,3,1,0,25,0,0,0,96,4,48,2,112],[0,0,1,56,3,64,1,151,0,1,0,0,0,49,3,85,0,2,0,0,0,49,3,85,0,3,0,0,0,49,3,85],[0,4,0,0,0,49,3,85,0,5,0,0,0,49,3,85,0,6,0,0,0,49,3,85,0,7,0,0,0,49,3,85],[0,8,0,0,0,49,3,85,0,9,0,0,0,49,3,85,0,10,0,0,0,49,3,85,0,11,0,0,0,49,3,85],[0,12,0,0,0,49,3,85,0,13,0,0,0,49,3,85,0,14,0,0,0,49,3,85,0,15,0,0,0,49,3,85],[0,16,0,0,0,49,3,85,0,17,0,0,0,1,3,85,0,2,0,0,0,4,0,29,0,0,1,56,0,64,1,157],[0,0,0,128,4,0,0,57,0,0,0,64,0,64,4,63,0,0,0,1,2,32,1,144,0,0,1,244,0,0,193,61],[0,0,0,4,2,48,0,140,0,0,2,80,0,0,65,61,0,0,0,0,2,1,4,59,0,0,0,224,2,32,2,112],[0,0,1,58,4,32,0,156,0,0,1,155,0,0,193,61,0,0,0,4,2,48,0,138,0,0,0,128,2,32,0,140],[0,0,2,80,0,0,65,61,0,0,0,4,2,16,3,112,0,0,0,0,8,2,4,59,0,0,0,68,2,16,3,112],[0,0,0,0,4,2,4,59,0,0,0,36,2,16,3,112,0,0,0,0,14,2,4,59,0,7,0,0,0,4,0,29],[0,0,1,60,2,64,0,156,0,0,2,80,0,0,33,61,0,0,0,7,2,0,0,41,0,0,0,35,2,32,0,57],[0,0,1,61,4,0,0,65,0,0,0,0,5,50,0,75,0,0,0,0,5,0,0,25,0,0,0,0,5,4,128,25],[0,0,1,61,2,32,1,151,0,0,0,0,6,2,0,75,0,0,0,0,4,0,128,25,0,0,1,61,2,32,0,156],[0,0,0,0,4,5,192,25,0,0,0,0,2,4,0,75,0,0,2,80,0,0,193,61,0,0,0,7,2,0,0,41],[0,0,0,4,2,32,0,57,0,0,0,0,2,33,3,79,0,0,0,0,6,2,4,59,0,0,1,60,2,96,0,156],[0,0,2,80,0,0,33,61,0,0,0,7,2,0,0,41,0,0,0,36,5,32,0,57,0,1,0,0,0,86,0,29],[0,0,0,1,2,48,0,108,0,0,2,80,0,0,65,61,0,0,0,100,2,16,3,112,0,0,0,0,2,2,4,59],[0,10,0,0,0,2,0,29,0,0,1,60,2,32,0,156,0,0,2,80,0,0,33,61,0,0,0,10,2,0,0,41],[0,0,0,35,2,32,0,57,0,0,1,61,4,0,0,65,0,0,0,0,7,50,0,75,0,0,0,0,7,0,0,25],[0,0,0,0,7,4,128,25,0,0,1,61,2,32,1,151,0,0,0,0,9,2,0,75,0,0,0,0,4,0,128,25],[0,0,1,61,2,32,0,156,0,0,0,0,4,7,192,25,0,0,0,0,2,4,0,75,0,0,2,80,0,0,193,61],[0,0,0,10,2,0,0,41,0,0,0,4,2,32,0,57,0,0,0,0,2,33,3,79,0,0,0,0,2,2,4,59],[0,12,0,0,0,2,0,29,0,0,1,60,2,32,0,156,0,0,2,80,0,0,33,61,0,0,0,10,2,0,0,41],[0,0,0,36,4,32,0,57,0,11,0,0,0,4,0,29,0,0,0,12,2,64,0,41,0,0,0,0,2,50,0,75],[0,0,2,80,0,0,33,61,0,0,0,0,2,0,4,17,0,0,128,8,2,32,0,140,0,0,1,252,0,0,193,61],[0,0,0,9,2,224,0,140,0,0,2,4,0,0,129,61,0,0,0,2,11,0,0,57,0,0,1,16,41,128,0,201],[0,0,1,17,10,0,0,138,0,9,0,0,0,0,0,29,0,0,0,0,3,0,0,25,0,6,0,0,0,14,0,29],[0,0,0,0,2,8,0,75,0,0,0,117,0,0,97,61,0,0,0,0,66,137,0,217,0,0,1,16,2,32,0,140],[0,0,2,246,0,0,193,61,0,0,0,0,2,147,0,75,0,0,0,227,0,0,129,61,0,0,0,0,2,163,0,75],[0,0,2,246,0,0,33,61,0,0,1,16,4,48,0,57,0,0,0,0,2,100,0,75,0,0,2,80,0,0,33,61],[0,0,0,0,2,83,0,25,0,0,0,60,2,32,0,57,0,0,0,0,3,33,3,79,0,0,0,0,3,3,4,59],[0,0,1,60,3,48,1,152,0,0,0,0,3,4,0,25,0,0,0,112,0,0,193,61,0,0,0,1,13,0,0,138],[0,0,0,9,3,208,0,107,0,0,2,246,0,0,97,61,0,0,0,11,3,176,0,41,0,0,0,0,3,49,3,79],[0,0,0,8,7,32,0,138,0,0,0,0,2,113,3,79,0,0,0,0,3,3,4,59,0,0,0,0,2,2,4,59],[0,0,0,0,2,50,0,75,0,0,2,44,0,0,193,61,0,0,0,33,2,0,0,138,0,0,0,0,2,43,0,75],[0,0,2,246,0,0,33,61,0,0,0,32,2,176,0,57,0,0,0,12,3,32,0,108,0,0,1,113,0,0,129,61],[0,0,0,11,2,32,0,41,0,0,0,0,2,33,3,79,0,0,0,0,15,2,4,59,0,0,1,99,2,240,1,152],[0,0,0,251,3,240,2,112,0,0,0,32,3,0,96,57,0,0,0,33,2,176,0,57,0,0,0,0,11,35,0,25],[0,0,0,0,12,59,0,75,0,0,0,0,12,0,0,25,0,0,0,1,12,0,64,57,0,0,0,1,12,192,1,144],[0,0,2,246,0,0,193,61,0,0,0,12,12,176,0,108,0,0,2,80,0,0,33,61,0,0,0,11,2,32,0,41],[0,0,0,72,12,112,0,57,0,0,0,0,12,193,3,79,0,0,0,40,7,112,0,57,0,0,0,0,14,113,3,79],[0,0,0,0,2,33,3,79,0,0,0,0,7,2,4,59,0,0,0,0,2,14,4,59,0,5,0,0,0,2,0,29],[0,0,0,6,14,0,0,41,0,0,0,0,2,12,4,59,0,8,0,0,0,2,0,29,0,0,0,31,2,48,0,140],[0,0,0,3,2,48,2,16,0,0,0,188,0,0,33,61,0,0,1,0,12,32,0,137,0,0,0,0,12,205,1,207],[0,0,0,0,13,32,0,73,0,0,1,0,14,0,0,138,0,0,0,0,13,237,0,75,0,0,0,6,14,0,0,41],[0,0,0,0,12,0,64,25,0,0,0,0,7,199,1,111,0,0,0,0,12,3,0,75,0,0,0,225,0,0,97,61],[0,0,1,0,12,32,0,140,0,0,2,246,0,0,33,61,0,0,0,0,195,50,0,217,0,0,0,8,3,48,0,140],[0,0,2,246,0,0,193,61,0,0,1,0,3,32,0,137,0,0,0,0,3,55,2,47,0,0,0,0,2,2,0,75],[0,0,0,0,3,0,96,25,0,0,0,9,2,0,0,41,0,9,0,1,0,32,0,61,0,0,0,248,2,240,2,112],[0,0,0,7,2,32,1,143,0,0,0,1,7,32,0,140,0,0,0,212,0,0,33,61,0,0,0,0,7,2,0,75],[0,0,0,216,0,0,97,61,0,0,0,1,2,32,0,140,0,0,1,127,0,0,193,61,0,0,0,5,2,48,0,41],[0,0,0,8,2,32,0,108,0,0,0,0,3,4,0,25,0,0,0,112,0,0,97,61,0,0,1,145,0,0,1,61],[0,0,0,2,7,32,0,140,0,0,0,220,0,0,97,61,0,0,0,3,2,32,0,140,0,0,1,127,0,0,193,61],[0,0,0,8,2,48,0,108,0,0,0,0,3,4,0,25,0,0,0,112,0,0,97,61,0,0,1,117,0,0,1,61],[0,0,0,5,2,48,0,105,0,0,0,8,2,32,0,108,0,0,0,0,3,4,0,25,0,0,0,112,0,0,97,61],[0,0,1,135,0,0,1,61,0,0,0,0,3,0,0,25,0,0,0,197,0,0,1,61,0,0,0,10,2,0,0,41],[0,0,0,6,2,32,0,57,0,0,0,0,2,33,3,79,0,0,0,0,2,2,4,59,0,0,255,255,2,32,1,143],[0,0,0,9,2,32,0,107,0,0,2,14,0,0,193,61,0,0,0,3,3,224,2,16,0,0,1,0,2,48,0,137],[0,0,0,1,4,0,0,138,0,8,0,0,0,2,0,29,0,4,0,0,0,4,0,29,0,0,0,0,4,36,1,207],[0,0,0,0,2,48,0,73,0,3,1,0,0,0,0,146,0,0,0,3,2,32,0,108,0,0,0,0,4,0,64,25],[0,5,0,0,0,4,0,29,0,10,0,0,0,3,0,29,0,0,1,0,2,48,0,140,0,0,2,24,0,0,33,61],[0,0,0,0,7,0,0,25,0,0,0,253,0,0,1,61,0,0,0,0,2,55,0,75,0,0,0,0,7,4,0,25],[0,0,1,117,0,0,193,61,0,0,0,0,2,8,0,75,0,0,1,2,0,0,97,61,0,0,0,0,50,137,0,217],[0,0,1,16,2,32,0,140,0,0,2,246,0,0,193,61,0,0,0,0,2,151,0,75,0,0,2,82,0,0,129,61],[0,0,0,0,2,167,0,75,0,0,2,246,0,0,33,61,0,0,1,16,4,112,0,57,0,0,0,0,2,100,0,75],[0,0,2,80,0,0,33,61,0,0,0,0,2,87,0,25,0,0,0,60,3,32,0,57,0,0,0,0,2,49,3,79],[0,0,0,0,2,2,4,59,0,0,1,60,15,32,1,152,0,0,0,0,7,4,0,25,0,0,0,253,0,0,97,61],[0,0,0,0,13,235,0,25,0,0,0,0,2,189,0,75,0,0,0,0,2,0,0,25,0,0,0,1,2,0,64,57],[0,0,0,1,2,32,1,144,0,0,2,246,0,0,193,61,0,0,0,12,2,208,0,108,0,0,2,80,0,0,33,61],[0,0,0,11,2,176,0,41,0,0,0,0,2,33,3,79,0,0,0,0,2,2,4,59,0,0,0,31,7,224,0,140],[0,0,1,32,0,0,33,61,0,0,0,5,2,32,1,127,0,0,0,0,7,14,0,75,0,0,2,238,0,0,97,61],[0,0,0,10,183,224,0,249,0,0,0,8,7,112,0,140,0,0,2,246,0,0,193,61,0,0,0,10,7,0,0,107],[0,0,2,238,0,0,97,61,0,0,0,8,2,32,2,80,0,0,0,0,2,47,0,75,0,0,2,238,0,0,193,61],[0,0,0,12,2,208,0,108,0,0,1,113,0,0,129,61,0,0,0,11,2,208,0,41,0,0,0,0,2,33,3,79],[0,0,0,0,15,2,4,59,0,0,1,99,2,240,1,152,0,0,0,251,7,240,2,112,0,0,0,32,7,0,96,57],[0,0,0,1,2,208,0,57,0,0,0,0,11,39,0,25,0,0,0,0,12,219,0,75,0,0,2,246,0,0,161,61],[0,0,0,12,12,176,0,108,0,0,2,80,0,0,33,61,0,0,0,11,2,32,0,41,0,0,0,64,12,48,0,57],[0,0,0,0,12,193,3,79,0,0,0,32,3,48,0,57,0,0,0,0,3,49,3,79,0,0,0,0,2,33,3,79],[0,0,0,0,2,2,4,59,0,0,0,0,3,3,4,59,0,9,0,0,0,3,0,29,0,0,0,0,3,12,4,59],[0,0,0,31,12,112,0,140,0,0,0,3,12,112,2,16,0,0,1,80,0,0,33,61,0,0,1,0,14,192,0,137],[0,0,0,4,14,224,1,239,0,0,0,0,13,192,0,73,0,7,0,0,0,3,0,29,0,0,0,0,3,11,0,25],[0,0,0,3,13,208,0,108,0,0,0,0,11,3,0,25,0,0,0,7,3,0,0,41,0,0,0,0,14,0,64,25],[0,0,0,0,2,226,1,111,0,0,0,6,14,0,0,41,0,0,0,0,13,7,0,75,0,0,1,111,0,0,97,61],[0,0,1,0,13,192,0,140,0,0,2,246,0,0,33,61,0,0,0,0,215,124,0,217,0,0,0,8,7,112,0,140],[0,0,2,246,0,0,193,61,0,0,1,0,7,192,0,137,0,0,0,0,7,114,2,47,0,0,0,0,2,12,0,75],[0,0,0,0,7,0,96,25,0,0,0,248,2,240,2,112,0,0,0,7,2,32,1,143,0,0,0,1,12,32,0,140],[0,0,1,102,0,0,33,61,0,0,0,0,12,2,0,75,0,0,0,250,0,0,97,61,0,0,0,1,2,32,0,140],[0,0,1,127,0,0,193,61,0,0,0,9,2,112,0,41,0,0,0,0,2,50,0,75,0,0,0,0,7,4,0,25],[0,0,0,253,0,0,97,61,0,0,1,145,0,0,1,61,0,0,0,3,12,32,0,140,0,0,0,250,0,0,97,61],[0,0,0,2,2,32,0,140,0,0,1,127,0,0,193,61,0,0,0,9,2,112,0,105,0,0,0,0,2,50,0,75],[0,0,0,0,7,4,0,25,0,0,0,253,0,0,97,61,0,0,1,135,0,0,1,61,0,0,0,0,7,0,0,25],[0,0,1,89,0,0,1,61,0,0,1,104,1,0,0,65,0,0,0,0,0,16,4,53,0,0,0,50,1,0,0,57],[0,0,2,249,0,0,1,61,0,0,1,62,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57],[0,0,0,132,0,16,4,63,0,0,0,58,1,0,0,57,0,0,0,164,0,16,4,63,0,0,1,112,1,0,0,65],[0,0,0,196,0,16,4,63,0,0,1,113,1,0,0,65,0,0,2,112,0,0,1,61,0,0,1,62,1,0,0,65],[0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63,0,0,0,21,1,0,0,57],[0,0,0,164,0,16,4,63,0,0,1,114,1,0,0,65,0,0,2,100,0,0,1,61,0,0,1,62,1,0,0,65],[0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63,0,0,0,47,1,0,0,57],[0,0,0,164,0,16,4,63,0,0,1,108,1,0,0,65,0,0,0,196,0,16,4,63,0,0,1,109,1,0,0,65],[0,0,2,112,0,0,1,61,0,0,1,62,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57],[0,0,0,132,0,16,4,63,0,0,0,46,1,0,0,57,0,0,0,164,0,16,4,63,0,0,1,110,1,0,0,65],[0,0,0,196,0,16,4,63,0,0,1,111,1,0,0,65,0,0,2,112,0,0,1,61,0,0,1,59,2,32,0,156],[0,0,2,80,0,0,193,61,0,0,0,4,2,48,0,138,0,0,0,64,2,32,0,140,0,0,2,80,0,0,65,61],[0,0,0,4,2,16,3,112,0,0,0,0,5,2,4,59,0,0,1,60,2,80,0,156,0,0,2,80,0,0,33,61],[0,0,0,35,2,80,0,57,0,0,1,61,4,0,0,65,0,0,0,0,6,50,0,75,0,0,0,0,6,0,0,25],[0,0,0,0,6,4,128,25,0,0,1,61,2,32,1,151,0,0,0,0,7,2,0,75,0,0,0,0,4,0,128,25],[0,0,1,61,2,32,0,156,0,0,0,0,4,6,192,25,0,0,0,0,2,4,0,75,0,0,2,80,0,0,193,61],[0,0,0,4,2,80,0,57,0,0,0,0,2,33,3,79,0,0,0,0,2,2,4,59,0,11,0,0,0,2,0,29],[0,0,1,60,2,32,0,156,0,0,2,80,0,0,33,61,0,0,0,36,4,80,0,57,0,0,0,11,2,64,0,41],[0,0,0,0,6,35,0,75,0,0,2,80,0,0,65,61,0,0,0,36,6,16,3,112,0,0,0,0,6,6,4,59],[0,0,1,60,7,96,0,156,0,0,2,80,0,0,33,61,0,0,0,35,7,96,0,57,0,0,1,61,8,0,0,65],[0,0,0,0,9,55,0,75,0,0,0,0,9,0,0,25,0,0,0,0,9,8,128,25,0,0,1,61,7,112,1,151],[0,0,0,0,10,7,0,75,0,0,0,0,8,0,128,25,0,0,1,61,7,112,0,156,0,0,0,0,8,9,192,25],[0,0,0,0,7,8,0,75,0,0,2,80,0,0,193,61,0,0,0,4,7,96,0,57,0,0,0,0,8,113,3,79],[0,0,0,0,8,8,4,59,0,10,0,0,0,8,0,29,0,0,1,60,8,128,0,156,0,0,2,80,0,0,33,61],[0,0,0,36,9,96,0,57,0,9,0,0,0,9,0,29,0,0,0,10,8,144,0,41,0,0,0,0,3,56,0,75],[0,0,2,80,0,0,33,61,0,0,0,0,3,0,4,17,0,0,128,1,3,48,0,140,0,0,2,252,0,0,193,61],[0,0,0,2,3,112,0,57,0,0,0,0,3,49,3,79,0,0,0,0,3,3,4,59,0,0,0,3,3,48,2,16],[0,0,1,65,3,48,1,151,0,0,0,2,8,48,1,191,0,0,0,10,7,128,0,107,0,0,2,80,0,0,65,61],[0,0,0,10,7,128,0,105,0,0,0,2,9,112,2,16,0,0,0,11,9,144,0,108,0,0,3,4,0,0,193,61],[0,0,0,1,9,112,2,112,0,0,0,3,10,48,2,112,0,0,0,0,9,154,0,75,0,0,3,18,0,0,161,61],[0,0,1,62,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63],[0,0,0,77,1,0,0,57,0,0,0,164,0,16,4,63,0,0,1,93,1,0,0,65,0,0,0,196,0,16,4,63],[0,0,1,94,1,0,0,65,0,0,0,228,0,16,4,63,0,0,1,95,1,0,0,65,0,0,3,15,0,0,1,61],[0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75,0,0,2,80,0,0,193,61,0,0,0,32,1,0,0,57],[0,0,1,0,0,16,4,67,0,0,1,32,0,0,4,67,0,0,1,57,1,0,0,65,0,0,4,220,0,1,4,46],[0,0,1,62,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63],[0,0,0,20,1,0,0,57,0,0,0,164,0,16,4,63,0,0,1,96,1,0,0,65,0,0,2,100,0,0,1,61],[0,0,1,62,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63],[0,0,0,35,1,0,0,57,0,0,0,164,0,16,4,63,0,0,1,115,1,0,0,65,0,0,0,196,0,16,4,63],[0,0,1,116,1,0,0,65,0,0,2,112,0,0,1,61,0,0,1,62,1,0,0,65,0,0,0,128,0,16,4,63],[0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63,0,0,0,41,1,0,0,57,0,0,0,164,0,16,4,63],[0,0,1,97,1,0,0,65,0,0,0,196,0,16,4,63,0,0,1,98,1,0,0,65,0,0,2,112,0,0,1,61],[0,0,0,0,2,8,0,75,0,0,2,52,0,0,193,61,0,0,0,7,2,0,0,41,0,0,0,96,2,32,0,57],[0,0,0,0,3,0,0,25,0,0,0,6,8,0,0,41,0,0,0,0,4,147,0,75,0,0,2,82,0,0,129,61],[0,0,0,0,4,163,0,75,0,0,2,246,0,0,33,61,0,0,1,16,4,48,0,57,0,0,0,0,7,100,0,75],[0,0,2,80,0,0,33,61,0,0,0,0,3,50,0,25,0,0,0,0,3,49,3,79,0,0,0,0,3,3,4,59],[0,0,1,60,3,48,1,152,0,0,0,0,3,4,0,25,0,0,2,30,0,0,97,61,0,0,2,72,0,0,1,61],[0,0,1,62,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63],[0,0,0,24,1,0,0,57,0,0,0,164,0,16,4,63,0,0,1,107,1,0,0,65,0,0,2,100,0,0,1,61],[0,0,0,0,50,137,0,217,0,0,1,16,2,32,0,140,0,0,0,6,8,0,0,41,0,0,2,246,0,0,193,61],[0,0,0,7,2,0,0,41,0,0,0,96,2,32,0,57,0,0,0,0,3,0,0,25,0,0,0,0,4,147,0,75],[0,0,2,82,0,0,129,61,0,0,0,0,4,163,0,75,0,0,2,246,0,0,33,61,0,0,1,16,4,48,0,57],[0,0,0,0,7,100,0,75,0,0,2,80,0,0,33,61,0,0,0,0,3,50,0,25,0,0,0,0,3,49,3,79],[0,0,0,0,3,3,4,59,0,0,1,60,3,48,1,152,0,0,0,0,3,4,0,25,0,0,2,59,0,0,97,61],[0,0,0,0,1,139,0,25,0,0,0,0,2,177,0,75,0,0,0,0,2,0,0,25,0,0,0,1,2,0,64,57],[0,0,0,1,2,32,1,144,0,0,2,246,0,0,193,61,0,0,0,12,1,16,0,108,0,0,2,236,0,0,161,61],[0,0,0,0,1,0,0,25,0,0,4,221,0,1,4,48,0,0,0,12,2,176,0,108,0,0,2,103,0,0,193,61],[0,0,1,56,2,80,1,151,0,0,0,0,1,33,3,79,0,0,0,1,3,0,0,41,0,0,0,2,2,48,0,105],[0,0,1,56,3,32,1,151,0,0,0,0,2,0,4,20,0,1,0,0,0,49,3,229,0,0,1,102,4,32,0,156],[0,0,2,115,0,0,65,61,0,0,1,62,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57],[0,0,0,132,0,16,4,63,0,0,0,8,1,0,0,57,0,0,0,164,0,16,4,63,0,0,1,105,1,0,0,65],[0,0,0,196,0,16,4,63,0,0,1,64,1,0,0,65,0,0,4,221,0,1,4,48,0,0,1,62,1,0,0,65],[0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63,0,0,0,35,1,0,0,57],[0,0,0,164,0,16,4,63,0,0,1,100,1,0,0,65,0,0,0,196,0,16,4,63,0,0,1,101,1,0,0,65],[0,0,0,228,0,16,4,63,0,0,1,72,1,0,0,65,0,0,4,221,0,1,4,48,0,0,0,0,1,49,3,223],[0,0,0,192,2,32,2,16,0,0,1,77,2,32,1,151,0,0,1,78,2,32,1,199,0,1,0,0,0,33,3,181],[0,0,0,0,1,33,3,175,0,0,128,16,2,0,0,57,4,219,4,214,0,0,4,15,0,0,0,0,3,1,0,25],[0,0,0,96,3,48,2,112,0,0,1,56,3,48,1,151,0,0,0,1,2,32,1,144,0,0,2,196,0,0,97,61],[0,0,0,63,2,48,0,57,0,0,1,79,4,32,1,151,0,0,0,64,2,0,4,61,0,0,0,0,4,66,0,25],[0,0,0,0,5,36,0,75,0,0,0,0,5,0,0,25,0,0,0,1,5,0,64,57,0,0,1,60,6,64,0,156],[0,0,4,82,0,0,33,61,0,0,0,1,5,80,1,144,0,0,4,82,0,0,193,61,0,0,0,64,0,64,4,63],[0,0,0,0,4,50,4,54,0,0,0,31,5,48,0,57,0,0,0,5,5,80,2,114,0,0,2,155,0,0,97,61],[0,0,0,0,6,0,0,49,0,0,0,17,6,96,3,103,0,0,0,0,7,0,0,25,0,0,0,5,8,112,2,16],[0,0,0,0,9,132,0,25,0,0,0,0,8,134,3,79,0,0,0,0,8,8,4,59,0,0,0,0,0,137,4,53],[0,0,0,1,7,112,0,57,0,0,0,0,8,87,0,75,0,0,2,147,0,0,65,61,0,0,0,0,5,0,0,75],[0,0,2,157,0,0,97,61,0,0,0,31,5,48,1,143,0,0,0,5,3,48,2,114,0,0,2,169,0,0,97,61],[0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,116,0,25,0,0,0,0,7,113,3,79],[0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,54,0,75],[0,0,2,161,0,0,65,61,0,0,0,0,6,5,0,75,0,0,2,184,0,0,97,61,0,0,0,5,3,48,2,16],[0,0,0,0,1,49,3,79,0,0,0,0,3,52,0,25,0,0,0,3,5,80,2,16,0,0,0,0,6,3,4,51],[0,0,0,0,6,86,1,207,0,0,0,0,6,86,2,47,0,0,0,0,1,1,4,59,0,0,1,0,5,80,0,137],[0,0,0,0,1,81,2,47,0,0,0,0,1,81,1,207,0,0,0,0,1,97,1,159,0,0,0,0,0,19,4,53],[0,0,1,56,3,0,0,65,0,0,0,64,1,0,4,61,0,0,1,56,5,16,0,156,0,0,0,0,3,1,64,25],[0,0,0,64,3,48,2,16,0,0,0,0,2,2,4,51,0,0,0,32,2,32,0,140,0,0,2,223,0,0,193,61],[0,0,0,0,2,4,4,51,0,0,0,0,0,33,4,53,0,0,1,90,1,48,1,199,0,0,4,220,0,1,4,46],[0,0,0,31,4,48,1,143,0,0,0,5,2,48,2,114,0,0,2,207,0,0,97,61,0,0,0,0,5,0,0,25],[0,0,0,5,6,80,2,16,0,0,0,0,7,97,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,118,4,53],[0,0,0,1,5,80,0,57,0,0,0,0,6,37,0,75,0,0,2,200,0,0,65,61,0,0,0,0,5,4,0,75],[0,0,2,221,0,0,97,61,0,0,0,3,4,64,2,16,0,0,0,5,2,32,2,16,0,0,0,0,5,2,4,51],[0,0,0,0,5,69,1,207,0,0,0,0,5,69,2,47,0,0,0,0,1,33,3,79,0,0,0,0,1,1,4,59],[0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,81,1,159],[0,0,0,0,0,18,4,53,0,0,0,96,1,48,2,16,0,0,4,221,0,1,4,48,0,0,0,68,2,16,0,57],[0,0,1,103,4,0,0,65,0,0,0,0,0,66,4,53,0,0,0,36,2,16,0,57,0,0,0,31,4,0,0,57],[0,0,0,0,0,66,4,53,0,0,1,62,2,0,0,65,0,0,0,0,0,33,4,53,0,0,0,4,1,16,0,57],[0,0,0,32,2,0,0,57,0,0,0,0,0,33,4,53,0,0,1,81,1,48,1,199,0,0,4,221,0,1,4,48],[0,0,0,0,1,8,0,75,0,0,2,246,0,0,193,61,0,0,1,62,1,0,0,65,0,0,0,128,0,16,4,63],[0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63,0,0,0,21,1,0,0,57,0,0,0,164,0,16,4,63],[0,0,1,106,1,0,0,65,0,0,2,100,0,0,1,61,0,0,1,104,1,0,0,65,0,0,0,0,0,16,4,53],[0,0,0,17,1,0,0,57,0,0,0,4,0,16,4,63,0,0,1,89,1,0,0,65,0,0,4,221,0,1,4,48],[0,0,1,62,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63],[0,0,0,31,1,0,0,57,0,0,0,164,0,16,4,63,0,0,1,63,1,0,0,65,0,0,2,100,0,0,1,61],[0,0,1,62,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63],[0,0,0,72,1,0,0,57,0,0,0,164,0,16,4,63,0,0,1,66,1,0,0,65,0,0,0,196,0,16,4,63],[0,0,1,67,1,0,0,65,0,0,0,228,0,16,4,63,0,0,1,68,1,0,0,65,0,0,1,4,0,16,4,63],[0,0,1,69,1,0,0,65,0,0,4,221,0,1,4,48,0,0,0,10,9,128,0,107,0,0,3,45,0,0,97,61],[0,0,0,6,9,96,0,57,0,0,0,0,8,152,0,25,0,0,0,14,6,96,0,57,0,0,0,12,5,80,0,57],[0,0,0,0,9,0,0,25,0,0,0,0,10,152,0,25,0,0,0,0,10,161,3,79,0,0,0,0,10,10,4,59],[0,0,0,3,10,160,2,16,0,0,1,65,10,160,1,151,0,0,0,0,11,58,0,75,0,0,3,67,0,0,129,61],[0,0,0,0,10,166,0,25,0,0,0,2,11,144,2,16,0,0,0,0,11,181,0,25,0,0,0,0,11,177,3,79],[0,0,0,0,10,161,3,79,0,0,0,0,10,10,4,59,0,0,0,0,11,11,4,59,0,0,0,0,10,186,1,63],[0,0,1,60,10,160,1,152,0,0,3,77,0,0,193,61,0,0,0,2,9,144,0,57,0,0,0,0,10,121,0,75],[0,0,3,25,0,0,65,61,0,0,0,11,3,0,0,41,0,0,0,31,3,48,1,144,0,0,3,59,0,0,193,61],[0,0,0,11,3,0,0,41,0,0,1,76,3,48,0,156,0,0,3,87,0,0,65,61,0,0,1,62,1,0,0,65],[0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63,0,0,0,2,1,0,0,57],[0,0,0,164,0,16,4,63,0,0,1,92,1,0,0,65,0,0,2,100,0,0,1,61,0,0,1,62,1,0,0,65],[0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63,0,0,0,2,1,0,0,57],[0,0,0,164,0,16,4,63,0,0,1,75,1,0,0,65,0,0,2,100,0,0,1,61,0,0,1,62,1,0,0,65],[0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63,0,0,0,36,1,0,0,57],[0,0,0,164,0,16,4,63,0,0,1,70,1,0,0,65,0,0,0,196,0,16,4,63,0,0,1,71,1,0,0,65],[0,0,2,112,0,0,1,61,0,0,1,62,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57],[0,0,0,132,0,16,4,63,0,0,0,50,1,0,0,57,0,0,0,164,0,16,4,63,0,0,1,73,1,0,0,65],[0,0,0,196,0,16,4,63,0,0,1,74,1,0,0,65,0,0,2,112,0,0,1,61,0,0,0,11,3,0,0,41],[0,0,0,32,3,48,1,144,0,0,3,98,0,0,193,61,0,0,1,62,1,0,0,65,0,0,0,128,0,16,4,63],[0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63,0,0,0,2,1,0,0,57,0,0,0,164,0,16,4,63],[0,0,1,91,1,0,0,65,0,0,2,100,0,0,1,61,0,0,1,56,3,64,1,151,0,0,0,0,1,49,3,79],[0,0,0,2,2,32,0,105,0,0,1,56,3,32,1,151,0,0,0,0,2,0,4,20,0,1,0,0,0,49,3,229],[0,0,1,56,4,32,0,156,0,0,2,93,0,0,33,61,0,0,0,0,1,49,3,223,0,0,0,192,2,32,2,16],[0,0,1,77,2,32,1,151,0,0,1,78,2,32,1,199,0,1,0,0,0,33,3,181,0,0,0,0,1,33,3,175],[0,0,0,2,2,0,0,57,4,219,4,214,0,0,4,15,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112],[0,0,1,56,3,48,1,151,0,0,0,1,2,32,1,144,0,0,4,86,0,0,97,61,0,0,0,63,2,48,0,57],[0,0,1,79,4,32,1,151,0,0,0,64,2,0,4,61,0,0,0,0,4,66,0,25,0,0,0,0,5,36,0,75],[0,0,0,0,5,0,0,25,0,0,0,1,5,0,64,57,0,0,1,60,6,64,0,156,0,0,4,82,0,0,33,61],[0,0,0,1,5,80,1,144,0,0,4,82,0,0,193,61,0,0,0,64,0,64,4,63,0,0,0,0,5,50,4,54],[0,0,0,17,4,0,3,103,0,0,0,31,6,48,0,57,0,0,0,5,6,96,2,114,0,0,3,146,0,0,97,61],[0,0,0,0,7,64,3,104,0,0,0,0,8,0,0,25,0,0,0,5,9,128,2,16,0,0,0,0,10,149,0,25],[0,0,0,0,9,151,3,79,0,0,0,0,9,9,4,59,0,0,0,0,0,154,4,53,0,0,0,1,8,128,0,57],[0,0,0,0,9,104,0,75,0,0,3,138,0,0,65,61,0,0,0,0,6,0,0,75,0,0,3,148,0,0,97,61],[0,0,0,31,6,48,1,143,0,0,0,5,3,48,2,114,0,0,3,160,0,0,97,61,0,0,0,0,7,0,0,25],[0,0,0,5,8,112,2,16,0,0,0,0,9,133,0,25,0,0,0,0,8,129,3,79,0,0,0,0,8,8,4,59],[0,0,0,0,0,137,4,53,0,0,0,1,7,112,0,57,0,0,0,0,8,55,0,75,0,0,3,152,0,0,65,61],[0,0,0,0,7,6,0,75,0,0,3,175,0,0,97,61,0,0,0,5,3,48,2,16,0,0,0,0,1,49,3,79],[0,0,0,0,3,53,0,25,0,0,0,3,6,96,2,16,0,0,0,0,7,3,4,51,0,0,0,0,7,103,1,207],[0,0,0,0,7,103,2,47,0,0,0,0,1,1,4,59,0,0,1,0,6,96,0,137,0,0,0,0,1,97,2,47],[0,0,0,0,1,97,1,207,0,0,0,0,1,113,1,159,0,0,0,0,0,19,4,53,0,0,0,64,6,0,4,61],[0,0,0,68,1,96,0,57,0,0,0,36,3,96,0,57,0,12,0,0,0,6,0,29,0,0,0,4,6,96,0,57],[0,0,0,0,2,2,4,51,0,0,0,32,2,32,0,140,0,0,4,113,0,0,193,61,0,0,0,0,5,5,4,51],[0,0,1,82,2,0,0,65,0,0,0,12,7,0,0,41,0,0,0,0,0,39,4,53,0,0,0,32,2,0,0,57],[0,0,0,0,0,38,4,53,0,0,0,10,6,0,0,41,0,0,0,0,0,99,4,53,0,0,0,9,2,64,3,96],[0,0,1,83,3,80,1,151,0,0,0,11,4,0,0,41,0,0,0,219,4,64,2,16,0,0,1,84,4,64,1,151],[0,0,0,0,4,52,1,159,0,0,0,31,3,96,1,143,0,11,1,85,0,64,1,203,0,0,0,5,4,96,2,114],[0,0,3,210,0,0,97,61,0,0,0,0,5,0,0,25,0,0,0,5,6,80,2,16,0,0,0,0,7,97,0,25],[0,0,0,0,6,98,3,79,0,0,0,0,6,6,4,59,0,0,0,0,0,103,4,53,0,0,0,1,5,80,0,57],[0,0,0,0,6,69,0,75,0,0,3,202,0,0,65,61,0,0,0,0,5,3,0,75,0,0,3,225,0,0,97,61],[0,0,0,5,4,64,2,16,0,0,0,0,2,66,3,79,0,0,0,0,4,65,0,25,0,0,0,3,3,48,2,16],[0,0,0,0,5,4,4,51,0,0,0,0,5,53,1,207,0,0,0,0,5,53,2,47,0,0,0,0,2,2,4,59],[0,0,1,0,3,48,0,137,0,0,0,0,2,50,2,47,0,0,0,0,2,50,1,207,0,0,0,0,2,82,1,159],[0,0,0,0,0,36,4,53,0,0,0,10,2,0,0,41,0,0,0,0,1,33,0,25,0,0,0,0,0,1,4,53],[0,0,0,31,1,32,0,57,0,0,0,32,2,0,0,138,0,0,0,0,1,33,1,111,0,0,1,56,2,0,0,65],[0,0,0,12,4,0,0,41,0,0,1,56,3,64,0,156,0,0,0,0,3,2,0,25,0,0,0,0,3,4,64,25],[0,0,0,64,3,48,2,16,0,0,0,68,1,16,0,57,0,0,1,56,4,16,0,156,0,0,0,0,1,2,128,25],[0,0,0,96,1,16,2,16,0,0,0,0,1,19,1,159,0,0,0,0,3,0,4,20,0,0,1,56,4,48,0,156],[0,0,0,0,3,2,128,25,0,0,0,192,2,48,2,16,0,0,0,0,1,18,1,159,0,0,128,8,2,0,0,57],[4,219,4,204,0,0,4,15,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,1,56,3,48,1,151],[0,0,0,32,4,48,0,140,0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57,0,0,0,31,5,64,1,143],[0,0,0,5,6,64,2,114,0,0,4,11,0,0,97,61,0,0,0,0,7,0,0,25,0,0,0,5,8,112,2,16],[0,0,0,12,9,128,0,41,0,0,0,0,8,129,3,79,0,0,0,0,8,8,4,59,0,0,0,0,0,137,4,53],[0,0,0,1,7,112,0,57,0,0,0,0,8,103,0,75,0,0,4,3,0,0,65,61,0,0,0,0,7,5,0,75],[0,0,4,26,0,0,97,61,0,0,0,5,6,96,2,16,0,0,0,0,7,97,3,79,0,0,0,12,6,96,0,41],[0,0,0,3,5,80,2,16,0,0,0,0,8,6,4,51,0,0,0,0,8,88,1,207,0,0,0,0,8,88,2,47],[0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137,0,0,0,0,7,87,2,47,0,0,0,0,5,87,1,207],[0,0,0,0,5,133,1,159,0,0,0,0,0,86,4,53,0,0,0,1,2,32,1,144,0,0,4,128,0,0,97,61],[0,0,0,31,1,64,0,57,0,0,0,96,2,16,1,143,0,0,0,12,1,32,0,41,0,0,0,0,2,33,0,75],[0,0,0,0,2,0,0,25,0,0,0,1,2,0,64,57,0,0,1,60,4,16,0,156,0,0,4,82,0,0,33,61],[0,0,0,1,2,32,1,144,0,0,4,82,0,0,193,61,0,0,0,64,0,16,4,63,0,0,0,32,1,48,0,140],[0,0,2,80,0,0,65,61,0,0,1,86,1,0,0,65,0,0,0,0,0,16,4,57,0,0,128,4,1,0,0,57],[0,0,0,4,0,16,4,67,0,0,1,56,1,0,0,65,0,0,0,0,2,0,4,20,0,0,1,56,3,32,0,156],[0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,1,87,1,16,1,199,0,0,128,2,2,0,0,57],[4,219,4,209,0,0,4,15,0,0,0,1,2,32,1,144,0,0,4,163,0,0,97,61,0,0,0,0,1,1,4,59],[0,0,0,0,1,1,0,75,0,0,2,80,0,0,97,61,0,0,0,64,4,0,4,61,0,0,1,88,1,0,0,65],[0,0,0,0,0,20,4,53,0,0,0,4,1,64,0,57,0,0,0,11,2,0,0,41,0,0,0,0,0,33,4,53],[0,0,1,56,1,0,0,65,0,0,0,0,2,0,4,20,0,0,1,56,3,32,0,156,0,0,0,0,2,1,128,25],[0,0,1,56,3,64,0,156,0,12,0,0,0,4,0,29,0,0,0,0,1,4,64,25,0,10,0,64,0,16,2,24],[0,0,0,192,1,32,2,16,0,0,0,10,1,16,1,175,0,0,1,89,1,16,1,199,0,0,128,4,2,0,0,57],[4,219,4,204,0,0,4,15,0,0,0,1,2,32,1,144,0,0,4,164,0,0,97,61,0,0,0,12,1,0,0,41],[0,0,1,60,1,16,0,156,0,0,4,196,0,0,161,61,0,0,1,104,1,0,0,65,0,0,0,0,0,16,4,53],[0,0,0,65,1,0,0,57,0,0,2,249,0,0,1,61,0,0,0,31,4,48,1,143,0,0,0,5,2,48,2,114],[0,0,4,97,0,0,97,61,0,0,0,0,5,0,0,25,0,0,0,5,6,80,2,16,0,0,0,0,7,97,3,79],[0,0,0,0,7,7,4,59,0,0,0,0,0,118,4,53,0,0,0,1,5,80,0,57,0,0,0,0,6,37,0,75],[0,0,4,90,0,0,65,61,0,0,0,0,5,4,0,75,0,0,4,111,0,0,97,61,0,0,0,3,4,64,2,16],[0,0,0,5,2,32,2,16,0,0,0,0,5,2,4,51,0,0,0,0,5,69,1,207,0,0,0,0,5,69,2,47],[0,0,0,0,1,33,3,79,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47],[0,0,0,0,1,65,1,207,0,0,0,0,1,81,1,159,0,0,0,0,0,18,4,53,0,0,0,96,1,48,2,16],[0,0,4,221,0,1,4,48,0,0,1,62,2,0,0,65,0,0,0,12,4,0,0,41,0,0,0,0,0,36,4,53],[0,0,0,32,2,0,0,57,0,0,0,0,0,38,4,53,0,0,0,25,2,0,0,57,0,0,0,0,0,35,4,53],[0,0,1,80,2,0,0,65,0,0,0,0,0,33,4,53,0,0,1,56,1,0,0,65,0,0,1,56,2,64,0,156],[0,0,0,0,4,1,128,25,0,0,0,64,1,64,2,16,0,0,1,81,1,16,1,199,0,0,4,221,0,1,4,48],[0,0,0,64,2,0,4,61,0,0,0,31,4,48,1,143,0,0,0,5,5,48,2,114,0,0,4,141,0,0,97,61],[0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79],[0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75],[0,0,4,133,0,0,65,61,0,0,0,0,6,4,0,75,0,0,4,156,0,0,97,61,0,0,0,5,5,80,2,16],[0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51],[0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137],[0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53],[0,0,1,56,1,0,0,65,0,0,1,56,4,32,0,156,0,0,0,0,2,1,128,25,0,0,0,64,1,32,2,16],[0,0,0,96,2,48,2,16,0,0,0,0,1,33,1,159,0,0,4,221,0,1,4,48,0,0,0,0,0,1,4,47],[0,0,0,64,2,0,4,61,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,0,31,4,48,1,143],[0,0,1,56,3,48,1,151,0,0,0,5,5,48,2,114,0,0,4,180,0,0,97,61,0,0,0,0,6,0,0,25],[0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59],[0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,4,172,0,0,65,61],[0,0,0,0,6,4,0,75,0,0,4,195,0,0,97,61,0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79],[0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207],[0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47],[0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,4,156,0,0,1,61],[0,0,0,12,2,0,0,41,0,0,0,64,0,32,4,63,0,0,0,11,1,0,0,41,0,0,0,0,0,18,4,53],[0,0,0,10,1,0,0,41,0,0,1,90,1,16,1,199,0,0,4,220,0,1,4,46,0,0,0,0,0,1,4,47],[0,0,4,207,0,33,4,33,0,0,0,1,2,0,0,57,0,0,0,0,0,1,4,45,0,0,0,0,2,0,0,25],[0,0,0,0,0,1,4,45,0,0,4,212,0,33,4,35,0,0,0,1,2,0,0,57,0,0,0,0,0,1,4,45],[0,0,0,0,2,0,0,25,0,0,0,0,0,1,4,45,0,0,4,217,0,33,4,35,0,0,0,1,2,0,0,57],[0,0,0,0,0,1,4,45,0,0,0,0,2,0,0,25,0,0,0,0,0,1,4,45,0,0,4,219,0,0,4,50],[0,0,4,220,0,1,4,46,0,0,4,221,0,1,4,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255],[0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,1,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,96,6,216,181],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,245,230,154,71],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255],[128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[8,195,121,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[67,97,108,108,97,98,108,101,32,111,110,108,121,32,98,121,32,116,104,101,32,98,111,111,116,108,111,97,100,101,114,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,128,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,7,255,248],[69,110,99,111,100,101,100,32,100,97,116,97,32,108,101,110,103,116,104,32,115,104,111,117,108,100,32,98,101,32,52,32],[116,105,109,101,115,32,115,104,111,114,116,101,114,32,116,104,97,110,32,116,104,101,32,111,114,105,103,105,110,97,108,32],[98,121,116,101,99,111,100,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,164,0,0,0,128,0,0,0,0,0,0,0,0],[69,110,99,111,100,101,100,32,99,104,117,110,107,32,105,110,100,101,120,32,105,115,32,111,117,116,32,111,102,32,98,111],[117,110,100,115,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,0,0,0,128,0,0,0,0,0,0,0,0],[69,110,99,111,100,101,100,32,99,104,117,110,107,32,100,111,101,115,32,110,111,116,32,109,97,116,99,104,32,116,104,101],[32,111,114,105,103,105,110,97,108,32,98,121,116,101,99,111,100,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[112,111,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0],[0,0,0,0,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,255,255,255,224],[115,104,97,32,114,101,116,117,114,110,101,100,32,105,110,118,97,108,105,100,32,100,97,116,97,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,0,0,0,0,0,0,0,0,0],[98,248,75,36,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],[254,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[24,6,170,24,150,187,242,101,104,232,132,167,55,75,65,224,2,80,9,98,202,186,106,21,2,58,141,144,232,80,139,131],[2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,0,0,0,0,0,0],[121,196,249,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0],[112,114,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[112,112,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[68,105,99,116,105,111,110,97,114,121,32,115,104,111,117,108,100,32,104,97,118,101,32,97,116,32,109,111,115,116,32,116],[104,101,32,115,97,109,101,32,110,117,109,98,101,114,32,111,102,32,101,110,116,114,105,101,115,32,97,115,32,116,104,101],[32,101,110,99,111,100,101,100,32,100,97,116,97,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[73,110,97,112,112,114,111,112,114,105,97,116,101,32,99,97,108,108,101,114,0,0,0,0,0,0,0,0,0,0,0,0],[73,110,99,111,114,114,101,99,116,32,110,117,109,98,101,114,32,111,102,32,105,110,105,116,105,97,108,32,115,116,111,114],[97,103,101,32,100,105,102,102,115,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[69,120,116,114,97,32,100,97,116,97,32,105,110,32,95,99,111,109,112,114,101,115,115,101,100,83,116,97,116,101,68,105],[102,102,115,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0],[107,101,99,99,97,107,50,53,54,32,114,101,116,117,114,110,101,100,32,105,110,118,97,108,105,100,32,100,97,116,97,0],[78,72,123,113,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[79,118,101,114,102,108,111,119,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[114,119,58,32,101,110,117,109,32,107,101,121,32,109,105,115,109,97,116,99,104,0,0,0,0,0,0,0,0,0,0,0],[105,119,58,32,105,110,105,116,105,97,108,32,107,101,121,32,109,105,115,109,97,116,99,104,0,0,0,0,0,0,0,0],[115,117,98,58,32,105,110,105,116,105,97,108,32,109,105,110,117,115,32,99,111,110,118,101,114,116,101,100,32,110,111,116],[32,101,113,117,97,108,32,116,111,32,102,105,110,97,108,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[97,100,100,58,32,105,110,105,116,105,97,108,32,112,108,117,115,32,99,111,110,118,101,114,116,101,100,32,110,111,116,32],[101,113,117,97,108,32,116,111,32,102,105,110,97,108,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[116,114,97,110,115,102,111,114,109,32,111,114,32,110,111,32,99,111,109,112,114,101,115,115,105,111,110,58,32,99,111,109],[112,114,101,115,115,101,100,32,97,110,100,32,102,105,110,97,108,32,109,105,115,109,97,116,99,104,0,0,0,0,0,0],[117,110,115,117,112,112,111,114,116,101,100,32,111,112,101,114,97,116,105,111,110,0,0,0,0,0,0,0,0,0,0,0],[101,110,117,109,101,114,97,116,105,111,110,32,105,110,100,101,120,32,115,105,122,101,32,105,115,32,116,111,111,32,108,97],[114,103,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[21,31,210,149,32,255,255,206,159,199,138,190,121,22,125,2,131,202,146,162,133,154,29,16,180,83,90,19,230,186,220,75]],"0x000000000000000000000000000000000000800f":[[0,3,0,0,0,0,0,2,0,4,0,0,0,0,0,2,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112],[0,0,0,65,3,48,1,151,0,2,0,0,0,49,3,85,0,1,0,0,0,1,3,85,0,0,0,128,8,0,0,57],[0,0,0,64,0,128,4,63,0,0,0,1,2,32,1,144,0,0,0,90,0,0,193,61,0,0,0,4,2,48,0,140],[0,0,0,98,0,0,65,61,0,0,0,0,2,1,4,59,0,0,0,67,2,32,1,151,0,0,0,68,2,32,0,156],[0,0,0,98,0,0,193,61,0,0,0,4,2,48,0,138,0,0,0,64,2,32,0,140,0,0,0,98,0,0,65,61],[0,0,0,4,2,16,3,112,0,0,0,0,9,2,4,59,0,0,0,69,2,144,0,156,0,0,0,98,0,0,33,61],[0,0,0,36,2,16,3,112,0,0,0,0,2,2,4,59,0,0,0,70,4,32,0,156,0,0,0,98,0,0,33,61],[0,0,0,35,4,32,0,57,0,0,0,71,5,0,0,65,0,0,0,0,6,52,0,75,0,0,0,0,6,0,0,25],[0,0,0,0,6,5,128,25,0,0,0,71,4,64,1,151,0,0,0,0,7,4,0,75,0,0,0,0,5,0,128,25],[0,0,0,71,4,64,0,156,0,0,0,0,5,6,192,25,0,0,0,0,4,5,0,75,0,0,0,98,0,0,193,61],[0,0,0,4,5,32,0,57,0,0,0,0,1,81,3,79,0,0,0,0,4,1,4,59,0,0,0,70,1,64,0,156],[0,0,0,98,0,0,33,61,0,0,0,0,1,66,0,25,0,0,0,36,1,16,0,57,0,0,0,0,1,49,0,75],[0,0,0,98,0,0,33,61,0,0,0,0,1,0,4,17,0,0,128,7,1,16,0,140,0,0,0,100,0,0,193,61],[0,1,0,0,0,5,0,29,0,2,0,0,0,4,0,29,0,4,0,0,0,8,0,29,0,0,0,76,1,0,0,65],[0,0,0,0,0,16,4,57,0,3,0,0,0,9,0,29,0,0,0,4,0,144,4,67,0,0,0,65,1,0,0,65],[0,0,0,0,2,0,4,20,0,0,0,65,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16],[0,0,0,77,1,16,1,199,0,0,128,2,2,0,0,57,0,253,0,243,0,0,4,15,0,0,0,1,2,32,1,144],[0,0,0,112,0,0,97,61,0,0,0,64,8,0,4,61,0,0,0,0,1,1,4,59,0,0,0,0,1,1,0,75],[0,0,0,113,0,0,193,61,0,0,0,68,1,128,0,57,0,0,0,81,3,0,0,65,0,0,0,0,0,49,4,53],[0,0,0,36,1,128,0,57,0,0,0,19,3,0,0,57,0,0,0,0,0,49,4,53,0,0,0,72,1,0,0,65],[0,0,0,0,0,24,4,53,0,0,0,4,1,128,0,57,0,0,0,32,3,0,0,57,0,0,0,0,0,49,4,53],[0,0,0,65,1,0,0,65,0,0,0,65,3,128,0,156,0,0,0,0,8,1,128,25,0,0,0,64,1,128,2,16],[0,0,0,82,1,16,1,199,0,0,0,255,0,1,4,48,0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75],[0,0,0,98,0,0,193,61,0,0,0,32,1,0,0,57,0,0,1,0,0,16,4,67,0,0,1,32,0,0,4,67],[0,0,0,66,1,0,0,65,0,0,0,254,0,1,4,46,0,0,0,0,1,0,0,25,0,0,0,255,0,1,4,48],[0,0,0,72,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63],[0,0,0,36,1,0,0,57,0,0,0,164,0,16,4,63,0,0,0,73,1,0,0,65,0,0,0,196,0,16,4,63],[0,0,0,74,1,0,0,65,0,0,0,228,0,16,4,63,0,0,0,75,1,0,0,65,0,0,0,255,0,1,4,48],[0,0,0,0,0,1,4,47,0,0,0,2,9,0,0,41,0,0,0,31,1,144,1,143,0,0,0,1,2,0,0,41],[0,0,0,32,3,32,0,57,0,0,0,1,3,48,3,103,0,0,0,5,4,144,2,114,0,0,0,129,0,0,97,61],[0,0,0,0,5,0,0,25,0,0,0,5,6,80,2,16,0,0,0,0,7,104,0,25,0,0,0,0,6,99,3,79],[0,0,0,0,6,6,4,59,0,0,0,0,0,103,4,53,0,0,0,1,5,80,0,57,0,0,0,0,6,69,0,75],[0,0,0,121,0,0,65,61,0,0,0,0,5,1,0,75,0,0,0,3,2,0,0,41,0,0,0,145,0,0,97,61],[0,0,0,5,4,64,2,16,0,0,0,0,3,67,3,79,0,0,0,0,4,72,0,25,0,0,0,3,1,16,2,16],[0,0,0,0,5,4,4,51,0,0,0,0,5,21,1,207,0,0,0,0,5,21,2,47,0,0,0,0,3,3,4,59],[0,0,1,0,1,16,0,137,0,0,0,0,3,19,2,47,0,0,0,0,1,19,1,207,0,0,0,0,1,81,1,159],[0,0,0,0,0,20,4,53,0,0,0,0,1,152,0,25,0,0,0,0,0,1,4,53,0,0,0,0,1,0,4,20],[0,0,0,4,3,32,0,140,0,0,0,153,0,0,193,61,0,0,0,0,3,0,0,49,0,0,0,0,2,0,0,25],[0,0,0,171,0,0,1,61,0,0,0,65,3,0,0,65,0,0,0,65,4,144,0,156,0,0,0,0,9,3,128,25],[0,0,0,96,4,144,2,16,0,0,0,65,5,128,0,156,0,0,0,0,8,3,128,25,0,0,0,64,5,128,2,16],[0,0,0,0,5,69,1,159,0,0,0,65,4,16,0,156,0,0,0,0,1,3,128,25,0,0,0,192,1,16,2,16],[0,0,0,0,1,81,1,159,0,253,0,248,0,0,4,15,0,0,0,1,2,32,1,95,0,2,0,0,0,1,3,85],[0,0,0,96,1,16,2,112,0,0,0,65,0,16,1,157,0,0,0,65,3,16,1,151,0,0,0,4,9,0,0,41],[0,0,0,96,1,0,0,57,0,0,0,0,4,3,0,75,0,0,0,187,0,0,193,61,0,0,0,1,2,32,1,144],[0,0,0,240,0,0,97,61,0,0,0,0,1,1,4,51,0,0,0,65,2,0,0,65,0,0,0,65,3,16,0,156],[0,0,0,0,1,2,128,25,0,0,0,65,3,144,0,156,0,0,0,0,9,2,128,25,0,0,0,64,2,144,2,16],[0,0,0,96,1,16,2,16,0,0,0,0,1,33,1,159,0,0,0,255,0,1,4,48,0,0,0,78,1,48,0,156],[0,0,0,234,0,0,129,61,0,0,0,31,1,48,0,57,0,0,0,32,4,0,0,138,0,0,0,0,1,65,1,111],[0,0,0,63,1,16,0,57,0,0,0,0,4,65,1,111,0,0,0,64,1,0,4,61,0,0,0,0,4,65,0,25],[0,0,0,0,5,20,0,75,0,0,0,0,5,0,0,25,0,0,0,1,5,0,64,57,0,0,0,70,6,64,0,156],[0,0,0,234,0,0,33,61,0,0,0,1,5,80,1,144,0,0,0,234,0,0,193,61,0,0,0,64,0,64,4,63],[0,0,0,31,4,48,1,143,0,0,0,0,9,49,4,54,0,0,0,2,5,0,3,103,0,0,0,5,3,48,2,114],[0,0,0,218,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,121,0,25],[0,0,0,0,7,117,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57],[0,0,0,0,7,54,0,75,0,0,0,210,0,0,65,61,0,0,0,0,6,4,0,75,0,0,0,175,0,0,97,61],[0,0,0,5,3,48,2,16,0,0,0,0,5,53,3,79,0,0,0,0,3,57,0,25,0,0,0,3,4,64,2,16],[0,0,0,0,6,3,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47,0,0,0,0,5,5,4,59],[0,0,1,0,4,64,0,137,0,0,0,0,5,69,2,47,0,0,0,0,4,69,1,207,0,0,0,0,4,100,1,159],[0,0,0,0,0,67,4,53,0,0,0,175,0,0,1,61,0,0,0,79,1,0,0,65,0,0,0,0,0,16,4,53],[0,0,0,65,1,0,0,57,0,0,0,4,0,16,4,63,0,0,0,80,1,0,0,65,0,0,0,255,0,1,4,48],[0,0,0,0,1,0,0,25,0,0,0,254,0,1,4,46,0,0,0,0,0,1,4,47,0,0,0,246,0,33,4,35],[0,0,0,1,2,0,0,57,0,0,0,0,0,1,4,45,0,0,0,0,2,0,0,25,0,0,0,0,0,1,4,45],[0,0,0,251,0,33,4,37,0,0,0,1,2,0,0,57,0,0,0,0,0,1,4,45,0,0,0,0,2,0,0,25],[0,0,0,0,0,1,4,45,0,0,0,253,0,0,4,50,0,0,0,254,0,1,4,46,0,0,0,255,0,1,4,48],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255],[0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,1,0,0,0,0,0,0,0,0,0],[255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[201,135,51,108,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255],[128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[8,195,121,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[67,97,110,32,111,110,108,121,32,98,101,32,99,97,108,108,101,100,32,98,121,32,70,79,82,67,69,95,68,69,80,76],[79,89,69,82,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,0,0,0,128,0,0,0,0,0,0,0,0],[24,6,170,24,150,187,242,101,104,232,132,167,55,75,65,224,2,80,9,98,202,186,106,21,2,58,141,144,232,80,139,131],[2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0],[78,72,123,113,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,0,0,0,0,0,0],[68,101,108,101,103,97,116,101,101,32,105,115,32,97,110,32,69,79,65,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[80,212,93,190,122,101,126,250,163,160,39,229,249,220,119,35,139,87,150,226,104,208,87,146,236,160,207,106,136,19,24,195]],"0x0000000000000000000000000000000000008010":[[0,0,0,1,2,32,1,144,0,0,0,20,0,0,193,61,0,0,0,96,2,16,2,16,0,0,0,9,2,32,1,151],[0,0,0,64,3,16,2,112,0,0,0,10,4,48,1,151,0,0,0,0,2,66,1,159,0,0,0,11,3,48,1,151],[0,0,0,0,2,50,1,159,0,0,0,12,2,32,1,199,0,0,0,96,1,16,2,112,0,0,0,10,1,16,1,151],[0,0,0,136,49,16,1,26,0,0,0,40,49,16,0,201,0,0,0,40,1,16,0,57,0,0,0,0,1,18,4,32],[0,0,0,0,1,1,0,75,0,0,0,25,0,0,193,61,0,0,0,0,1,0,0,25,0,0,0,29,0,1,4,48],[0,0,0,32,1,0,0,57,0,0,1,0,0,16,4,67,0,0,1,32,0,0,4,67,0,0,0,8,1,0,0,65],[0,0,0,28,0,1,4,46,0,0,0,13,1,0,0,65,0,0,0,28,0,1,4,46,0,0,0,27,0,0,4,50],[0,0,0,28,0,1,4,46,0,0,0,29,0,1,4,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,1,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0],[171,242,174,109,142,229,242,151,29,166,152,164,72,217,11,237,215,175,17,73,255,158,65,52,150,122,253,42,115,72,201,111]],"0x0000000000000000000000000000000000008012":[[0,16,0,0,0,0,0,2,0,1,0,0,0,0,0,2,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112],[0,0,0,28,3,48,1,151,0,1,0,0,0,49,3,85,0,0,0,0,0,49,3,85,0,2,0,0,0,49,3,85],[0,3,0,0,0,49,3,85,0,4,0,0,0,49,3,85,0,5,0,0,0,49,3,85,0,6,0,0,0,49,3,85],[0,7,0,0,0,49,3,85,0,8,0,0,0,49,3,85,0,9,0,0,0,49,3,85,0,10,0,0,0,49,3,85],[0,11,0,0,0,49,3,85,0,12,0,0,0,49,3,85,0,13,0,0,0,49,3,85,0,14,0,0,0,49,3,85],[0,15,0,0,0,49,3,85,0,0,0,1,2,32,1,144,0,0,0,94,0,0,193,61,0,0,0,0,2,1,4,59],[0,0,0,30,1,0,0,65,0,0,0,0,0,16,4,53,0,1,0,0,0,2,0,29,0,0,0,4,0,32,4,63],[0,0,0,28,1,0,0,65,0,0,0,0,2,0,4,20,0,0,0,28,3,32,0,156,0,0,0,0,2,1,128,25],[0,0,0,192,1,32,2,16,0,0,0,31,1,16,1,199,0,0,128,4,2,0,0,57,0,106,0,101,0,0,4,15],[0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,0,28,3,48,1,151,0,0,0,32,4,48,0,140],[0,0,0,32,3,0,128,57,0,0,0,31,4,48,1,143,0,0,0,5,3,48,2,114,0,0,0,52,0,0,97,61],[0,0,0,0,5,0,0,25,0,0,0,5,6,80,2,16,0,0,0,0,7,97,3,79,0,0,0,0,7,7,4,59],[0,0,0,0,0,118,4,53,0,0,0,1,5,80,0,57,0,0,0,0,6,53,0,75,0,0,0,45,0,0,65,61],[0,0,0,0,5,4,0,75,0,0,0,66,0,0,97,61,0,0,0,3,4,64,2,16,0,0,0,5,3,48,2,16],[0,0,0,0,5,3,4,51,0,0,0,0,5,69,1,207,0,0,0,0,5,69,2,47,0,0,0,0,1,49,3,79],[0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207],[0,0,0,0,1,81,1,159,0,0,0,0,0,19,4,53,0,0,0,1,1,32,1,144,0,0,0,99,0,0,97,61],[0,0,0,1,1,0,0,41,0,0,0,32,1,16,1,151,0,0,0,0,2,0,4,51,0,0,0,0,2,2,0,75],[0,0,0,99,0,0,97,61,0,0,0,33,1,16,0,156,0,0,0,99,0,0,193,61,0,0,0,1,3,0,0,41],[0,0,0,224,1,48,2,112,0,0,255,255,1,16,1,144,0,0,0,2,2,16,2,16,0,0,0,0,2,35,4,69],[0,0,0,0,0,2,3,85,0,0,0,90,0,0,97,61,0,0,0,0,3,0,0,25,0,0,0,5,4,48,2,16],[0,0,0,0,5,66,3,79,0,0,0,0,5,5,4,59,0,0,0,0,0,84,4,53,0,0,0,1,3,48,0,57],[0,0,0,0,4,19,0,75,0,0,0,83,0,0,65,61,0,0,0,0,2,0,0,75,0,0,0,92,0,0,97,61],[0,0,0,101,1,16,2,16,0,0,0,107,0,1,4,46,0,0,0,32,1,0,0,57,0,0,1,0,0,16,4,67],[0,0,1,32,0,0,4,67,0,0,0,29,1,0,0,65,0,0,0,107,0,1,4,46,0,0,0,0,1,0,0,25],[0,0,0,108,0,1,4,48,0,0,0,104,0,33,4,35,0,0,0,1,2,0,0,57,0,0,0,0,0,1,4,45],[0,0,0,0,2,0,0,25,0,0,0,0,0,1,4,45,0,0,0,106,0,0,4,50,0,0,0,107,0,1,4,46],[0,0,0,108,0,1,4,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255],[0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,1,0,0,0,0,0,0,0,0,0],[76,99,20,240,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,0,0,0,0,0,0],[255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[220,56,99,58,84,35,238,219,229,209,0,53,91,250,45,9,189,236,187,119,228,37,29,166,230,56,135,76,97,175,68,16]],"0x0000000000000000000000000000000000000100":[[0,0,0,1,2,32,1,144,0,0,0,31,0,0,193,61,0,0,0,0,2,1,0,25,0,0,0,12,2,32,1,151],[0,0,0,13,2,32,0,156,0,0,0,29,0,0,193,61,0,0,0,128,2,16,3,112,0,0,0,0,2,2,4,59],[0,0,0,96,3,16,3,112,0,0,0,0,3,3,4,59,0,0,0,64,4,16,3,112,0,0,0,0,4,4,4,59],[0,0,0,32,5,16,3,112,0,0,0,0,5,5,4,59,0,0,0,0,1,1,4,59,0,0,0,0,0,16,4,53],[0,0,0,32,0,80,4,63,0,0,0,64,0,64,4,63,0,0,0,96,0,48,4,63,0,0,0,128,0,32,4,63],[0,0,46,224,1,0,0,57,0,0,0,14,2,0,0,65,0,0,0,0,1,18,4,32,0,0,0,0,2,0,4,51],[0,0,0,0,1,18,1,112,0,0,0,29,0,0,97,61,0,0,0,32,1,0,4,61,0,0,0,0,1,1,0,75],[0,0,0,36,0,0,193,61,0,0,0,0,1,0,0,25,0,0,0,39,0,1,4,46,0,0,0,32,1,0,0,57],[0,0,1,0,0,16,4,67,0,0,1,32,0,0,4,67,0,0,0,11,1,0,0,65,0,0,0,39,0,1,4,46],[0,0,0,15,1,0,0,65,0,0,0,39,0,1,4,46,0,0,0,38,0,0,4,50,0,0,0,39,0,1,4,46],[0,0,0,40,0,1,4,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,1,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,160,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,5,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,32,0,0,0,0,0,0,0,0],[99,70,236,230,212,100,45,10,78,238,109,18,132,249,45,147,54,61,78,53,205,95,103,7,180,47,225,23,164,222,237,12]],"0x0000000000000000000000000000000000008011":[[0,3,0,0,0,0,0,2,0,0,0,128,3,0,0,57,0,0,0,64,0,48,4,63,0,0,0,0,3,1,0,25],[0,0,0,96,3,48,2,112,0,0,0,53,3,48,1,151,0,0,0,1,2,32,1,144,0,0,0,60,0,0,193,61],[0,0,0,4,2,48,0,140,0,0,0,195,0,0,65,61,0,0,0,0,2,1,4,59,0,0,0,55,2,32,1,151],[0,0,0,56,2,32,0,156,0,0,0,195,0,0,193,61,0,0,0,0,2,0,4,22,0,0,0,0,2,2,0,75],[0,0,0,195,0,0,193,61,0,0,0,4,2,48,0,138,0,0,0,32,2,32,0,140,0,0,0,195,0,0,65,61],[0,0,0,4,2,16,3,112,0,0,0,0,4,2,4,59,0,0,0,57,2,64,0,156,0,0,0,195,0,0,33,61],[0,0,0,35,2,64,0,57,0,0,0,58,5,0,0,65,0,0,0,0,6,50,0,75,0,0,0,0,6,0,0,25],[0,0,0,0,6,5,128,25,0,0,0,58,2,32,1,151,0,0,0,0,7,2,0,75,0,0,0,0,5,0,128,25],[0,0,0,58,2,32,0,156,0,0,0,0,5,6,192,25,0,0,0,0,2,5,0,75,0,0,0,195,0,0,193,61],[0,0,0,4,2,64,0,57,0,0,0,0,5,33,3,79,0,0,0,0,5,5,4,59,0,2,0,0,0,5,0,29],[0,0,0,57,5,80,0,156,0,0,0,195,0,0,33,61,0,0,0,2,4,64,0,41,0,0,0,36,4,64,0,57],[0,0,0,0,4,52,0,75,0,0,0,195,0,0,33,61,0,0,0,0,4,0,4,17,0,0,128,8,4,64,0,140],[0,0,0,68,0,0,193,61,0,0,0,2,4,0,0,41,0,0,0,62,4,64,0,156,0,0,0,78,0,0,65,61],[0,0,0,59,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63],[0,0,0,29,1,0,0,57,0,0,0,164,0,16,4,63,0,0,0,70,1,0,0,65,0,0,0,75,0,0,1,61],[0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75,0,0,0,195,0,0,193,61,0,0,0,32,1,0,0,57],[0,0,1,0,0,16,4,67,0,0,1,32,0,0,4,67,0,0,0,54,1,0,0,65,0,0,0,208,0,1,4,46],[0,0,0,59,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63],[0,0,0,20,1,0,0,57,0,0,0,164,0,16,4,63,0,0,0,60,1,0,0,65,0,0,0,196,0,16,4,63],[0,0,0,61,1,0,0,65,0,0,0,209,0,1,4,48,0,0,0,6,4,0,0,57,0,0,0,128,0,64,4,63],[0,0,0,0,3,49,3,79,0,0,0,160,4,0,0,57,0,0,0,0,5,0,0,25,0,0,0,5,6,80,2,16],[0,0,0,0,6,99,3,79,0,0,0,0,6,6,4,59,0,0,0,0,4,100,4,54,0,0,0,1,5,80,0,57],[0,0,0,6,6,80,0,140,0,0,0,83,0,0,65,61,0,0,0,63,4,0,0,65,0,0,0,64,0,64,4,63],[0,0,0,64,4,0,0,65,0,0,1,96,0,64,4,63,0,0,1,128,4,0,0,57,0,0,0,0,5,0,0,25],[0,0,0,5,6,80,2,16,0,0,0,0,6,99,3,79,0,0,0,0,6,6,4,59,0,0,0,0,4,100,4,54],[0,0,0,1,5,80,0,57,0,0,93,0,6,80,0,140,0,0,0,96,0,0,65,61,0,0,0,32,2,32,0,57],[0,0,0,0,1,33,3,79,0,0,0,2,3,0,0,41,0,0,0,31,2,48,1,143,0,0,0,5,3,48,2,114],[0,0,0,118,0,0,97,61,0,0,0,0,4,0,0,25,0,0,0,5,5,64,2,16,0,0,0,0,6,81,3,79],[0,0,0,0,6,6,4,59,0,0,1,128,5,80,0,57,0,0,0,0,0,101,4,53,0,0,0,1,4,64,0,57],[0,0,0,0,5,52,0,75,0,0,0,110,0,0,65,61,0,0,0,0,4,2,0,75,0,0,0,133,0,0,97,61],[0,0,0,5,3,48,2,16,0,0,0,0,1,49,3,79,0,0,0,3,2,32,2,16,0,0,1,128,3,48,0,57],[0,0,0,0,4,3,4,51,0,0,0,0,4,36,1,207,0,0,0,0,4,36,2,47,0,0,0,0,1,1,4,59],[0,0,1,0,2,32,0,137,0,0,0,0,1,33,2,47,0,0,0,0,1,33,1,207,0,0,0,0,1,65,1,159],[0,0,0,0,0,19,4,53,0,1,128,16,0,0,0,61,0,0,0,0,3,0,0,25,0,0,0,65,33,48,0,209],[0,0,0,2,1,16,0,108,0,0,0,161,0,0,129,61,0,0,0,0,1,0,4,20,0,0,0,53,2,16,0,156],[0,0,0,53,1,0,128,65,0,0,0,192,1,16,2,16,0,3,0,0,0,3,0,29,0,0,0,66,50,48,0,209],[0,0,0,0,1,18,1,159,0,0,0,67,1,16,1,199,0,0,0,1,2,0,0,41,0,207,0,202,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,0,195,0,0,97,61,0,0,0,128,2,0,4,61,0,0,0,3,3,0,0,41],[0,0,0,0,2,50,0,75,0,0,0,189,0,0,161,61,0,0,0,0,1,1,4,59,0,0,0,5,2,48,2,16],[0,0,0,160,2,32,0,57,0,0,0,0,0,18,4,53,0,0,0,5,1,48,0,140,0,0,0,1,3,48,0,57],[0,0,0,135,0,0,65,61,0,0,0,128,1,0,4,61,0,0,0,0,2,1,0,75,0,0,0,189,0,0,97,61],[0,0,0,160,2,0,4,61,0,0,0,7,3,0,0,57,0,0,0,0,0,35,4,29,0,0,0,1,2,16,0,140],[0,0,0,189,0,0,97,61,0,0,0,192,2,0,4,61,0,0,0,8,3,0,0,57,0,0,0,0,0,35,4,29],[0,0,0,3,2,16,0,140,0,0,0,189,0,0,65,61,0,0,0,224,2,0,4,61,0,0,0,9,3,0,0,57],[0,0,0,0,0,35,4,29,0,0,0,3,2,16,0,140,0,0,0,189,0,0,97,61,0,0,1,0,2,0,4,61],[0,0,0,10,3,0,0,57,0,0,0,0,0,35,4,29,0,0,0,5,2,16,0,140,0,0,0,189,0,0,65,61],[0,0,1,32,2,0,4,61,0,0,0,11,3,0,0,57,0,0,0,0,0,35,4,29,0,0,0,5,1,16,0,140],[0,0,0,197,0,0,193,61,0,0,0,68,1,0,0,65,0,0,0,0,0,16,4,53,0,0,0,50,1,0,0,57],[0,0,0,4,0,16,4,63,0,0,0,69,1,0,0,65,0,0,0,209,0,1,4,48,0,0,0,0,1,0,0,25],[0,0,0,209,0,1,4,48,0,0,1,64,1,0,4,61,0,0,0,12,2,0,0,57,0,0,0,0,0,18,4,29],[0,0,0,0,1,0,0,25,0,0,0,208,0,1,4,46,0,0,0,205,0,33,4,35,0,0,0,1,2,0,0,57],[0,0,0,0,0,1,4,45,0,0,0,0,2,0,0,25,0,0,0,0,0,1,4,45,0,0,0,207,0,0,4,50],[0,0,0,208,0,1,4,46,0,0,0,209,0,1,4,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255],[0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,1,0,0,0,0,0,0,0,0,0],[255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[37,85,210,193,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255],[128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[8,195,121,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[73,110,97,112,112,114,111,112,114,105,97,116,101,32,99,97,108,108,101,114,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,128,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,160,1],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,161,128],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,160,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,240,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,240,0,0,0,0,0,0,0,0,0],[2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,240,0,0,0,1,128,0,0,0,0,0,0,0,0],[78,72,123,113,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,0,0,0,0,0,0],[112,117,98,100,97,116,97,32,115,104,111,117,108,100,32,102,105,116,32,105,110,32,54,32,98,108,111,98,115,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[235,231,24,156,100,163,130,150,41,177,204,215,93,125,130,10,59,34,25,228,38,125,89,36,215,89,232,130,185,34,33,202]]},"default_account_code":[[0,20,0,0,0,0,0,2,0,12,0,0,0,0,0,2,0,0,0,0,3,1,0,25,0,0,0,96,7,48,2,112],[0,0,5,8,6,112,1,151,0,19,0,0,0,97,3,85,0,2,0,0,0,97,3,85,0,3,0,0,0,97,3,85],[0,4,0,0,0,97,3,85,0,5,0,0,0,97,3,85,0,6,0,0,0,97,3,85,0,7,0,0,0,97,3,85],[0,8,0,0,0,97,3,85,0,9,0,0,0,97,3,85,0,10,0,0,0,97,3,85,0,11,0,0,0,97,3,85],[0,12,0,0,0,97,3,85,0,13,0,0,0,97,3,85,0,14,0,0,0,97,3,85,0,15,0,0,0,97,3,85],[0,16,0,0,0,97,3,85,0,17,0,0,0,97,3,85,0,18,0,0,0,1,3,85,0,0,5,8,0,112,1,157],[0,0,0,128,4,0,0,57,0,0,0,64,0,64,4,63,0,0,0,1,2,32,1,144,0,0,0,60,0,0,193,61],[0,0,0,4,2,96,0,140,0,0,0,68,0,0,65,61,0,0,0,0,2,1,4,59,0,0,0,224,2,32,2,112],[0,0,5,10,3,32,0,156,0,0,0,84,0,0,161,61,0,0,5,11,3,32,0,156,0,0,0,168,0,0,97,61],[0,0,5,12,3,32,0,156,0,0,0,215,0,0,97,61,0,0,5,13,2,32,0,156,0,0,0,70,0,0,193,61],[0,0,0,4,2,96,0,138,0,0,0,32,3,32,0,140,0,0,1,57,0,0,65,61,0,0,0,4,1,16,3,112],[0,0,0,0,1,1,4,59,0,0,5,16,3,16,0,156,0,0,1,57,0,0,33,61,0,0,0,0,1,18,0,73],[0,0,5,17,2,0,0,65,0,0,2,96,3,16,0,140,0,0,0,0,3,0,0,25,0,0,0,0,3,2,64,25],[0,0,5,17,1,16,1,151,0,0,0,0,4,1,0,75,0,0,0,0,2,0,160,25,0,0,5,17,1,16,0,156],[0,0,0,0,2,3,192,25,0,0,0,0,1,2,0,75,0,0,4,34,0,0,97,61,0,0,1,57,0,0,1,61],[0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75,0,0,1,57,0,0,193,61,0,0,0,32,1,0,0,57],[0,0,1,0,0,16,4,67,0,0,1,32,0,0,4,67,0,0,5,9,1,0,0,65,0,0,20,29,0,1,4,46],[0,0,0,0,1,6,0,75,0,0,4,34,0,0,97,61,0,0,0,0,1,0,4,18,0,0,5,18,1,16,1,151],[0,0,0,0,2,0,4,16,0,0,0,0,1,33,0,75,0,0,4,34,0,0,193,61,0,0,0,0,1,0,4,17],[0,0,128,1,1,16,0,140,0,0,4,34,0,0,193,61,0,0,5,94,1,0,0,65,0,0,0,0,0,16,4,53],[0,0,0,1,1,0,0,57,0,0,0,4,0,16,4,63,0,0,5,95,1,0,0,65,0,0,20,30,0,1,4,48],[0,0,5,14,3,32,0,156,0,0,1,35,0,0,97,61,0,10,0,0,0,4,0,29,0,0,5,15,2,32,0,156],[0,0,0,70,0,0,193,61,0,0,0,4,2,96,0,138,0,0,0,96,2,32,0,140,0,0,1,57,0,0,65,61],[0,0,0,68,2,16,3,112,0,0,0,0,3,2,4,59,0,0,5,16,2,48,0,156,0,0,1,57,0,0,33,61],[0,0,0,4,4,48,0,57,0,0,0,0,5,70,0,73,0,0,5,17,2,0,0,65,0,0,2,96,7,80,0,140],[0,0,0,0,7,0,0,25,0,0,0,0,7,2,64,25,0,0,5,17,8,80,1,151,0,0,0,0,9,8,0,75],[0,0,0,0,2,0,160,25,0,0,5,17,8,128,0,156,0,0,0,0,2,7,192,25,0,0,0,0,2,2,0,75],[0,0,1,57,0,0,193,61,0,0,0,0,2,0,4,17,0,0,128,1,2,32,0,140,0,0,4,34,0,0,193,61],[0,0,0,0,2,0,4,18,0,0,5,18,7,32,1,151,0,0,0,0,2,0,4,16,0,0,0,0,7,39,0,75],[0,0,4,34,0,0,193,61,0,0,2,36,3,48,0,57,0,0,0,0,7,49,3,79,0,0,0,0,7,7,4,59],[0,0,0,31,5,80,0,138,0,0,5,17,8,0,0,65,0,0,0,0,9,87,0,75,0,0,0,0,9,0,0,25],[0,0,0,0,9,8,128,25,0,0,5,17,5,80,1,151,0,0,5,17,10,112,1,151,0,0,0,0,11,90,0,75],[0,0,0,0,8,0,128,25,0,0,0,0,5,90,1,63,0,0,5,17,5,80,0,156,0,0,0,0,8,9,192,25],[0,0,0,0,5,8,0,75,0,0,1,57,0,0,193,61,0,0,0,0,5,71,0,25,0,0,0,0,4,81,3,79],[0,0,0,0,4,4,4,59,0,0,5,16,7,64,0,156,0,0,1,57,0,0,33,61,0,0,0,0,7,70,0,73],[0,0,0,32,5,80,0,57,0,0,5,17,8,0,0,65,0,0,0,0,9,117,0,75,0,0,0,0,9,0,0,25],[0,0,0,0,9,8,32,25,0,0,5,17,7,112,1,151,0,0,5,17,10,80,1,151,0,0,0,0,11,122,0,75],[0,0,0,0,8,0,128,25,0,0,0,0,7,122,1,63,0,0,5,17,7,112,0,156,0,0,0,0,8,9,192,25],[0,0,0,0,7,8,0,75,0,0,1,57,0,0,193,61,0,0,0,3,7,64,0,140,0,0,2,92,0,0,33,61],[0,0,5,22,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63],[0,0,0,58,1,0,0,57,0,0,0,164,0,16,4,63,0,0,5,57,1,0,0,65,0,0,0,196,0,16,4,63],[0,0,5,58,1,0,0,65,0,0,0,228,0,16,4,63,0,0,5,55,1,0,0,65,0,0,20,30,0,1,4,48],[0,0,0,4,2,96,0,138,0,0,0,96,2,32,0,140,0,0,1,57,0,0,65,61,0,0,0,68,2,16,3,112],[0,0,0,0,3,2,4,59,0,0,5,16,2,48,0,156,0,0,1,57,0,0,33,61,0,0,0,4,2,48,0,57],[0,0,0,0,5,38,0,73,0,0,5,17,4,0,0,65,0,0,2,96,8,80,0,140,0,0,0,0,8,0,0,25],[0,0,0,0,8,4,64,25,0,0,5,17,9,80,1,151,0,0,0,0,10,9,0,75,0,0,0,0,4,0,160,25],[0,0,5,17,9,144,0,156,0,0,0,0,4,8,192,25,0,0,0,0,4,4,0,75,0,0,1,57,0,0,193,61],[0,0,0,0,4,0,4,17,0,0,128,1,4,64,0,140,0,0,4,34,0,0,193,61,0,0,0,0,4,0,4,18],[0,0,5,18,4,64,1,151,0,0,0,0,8,0,4,16,0,0,0,0,4,132,0,75,0,0,4,34,0,0,193,61],[0,0,0,68,4,48,0,57,0,0,0,0,4,65,3,79,0,0,1,36,8,48,0,57,0,0,0,0,3,129,3,79],[0,0,0,0,4,4,4,59,0,0,5,18,4,64,1,151,0,0,0,0,3,3,4,59,0,0,5,24,9,48,0,156],[0,0,2,24,0,0,65,61,0,0,5,22,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57],[0,0,0,132,0,16,4,63,0,0,0,8,1,0,0,57,0,0,0,164,0,16,4,63,0,0,5,34,1,0,0,65],[0,0,0,196,0,16,4,63,0,0,5,35,1,0,0,65,0,0,20,30,0,1,4,48,0,0,0,4,3,96,0,138],[0,0,0,96,2,48,0,140,0,0,1,57,0,0,65,61,0,0,0,68,2,16,3,112,0,0,0,0,2,2,4,59],[0,0,5,16,4,32,0,156,0,0,1,57,0,0,33,61,0,0,0,0,3,35,0,73,0,0,5,17,4,0,0,65],[0,0,2,96,5,48,0,140,0,0,0,0,5,0,0,25,0,0,0,0,5,4,64,25,0,0,5,17,3,48,1,151],[0,0,0,0,6,3,0,75,0,0,0,0,4,0,160,25,0,0,5,17,3,48,0,156,0,0,0,0,4,5,192,25],[0,0,0,0,3,4,0,75,0,0,1,57,0,0,193,61,0,0,0,0,3,0,4,17,0,0,128,1,3,48,0,140],[0,0,4,34,0,0,193,61,0,0,0,0,3,0,4,18,0,0,5,18,3,48,1,151,0,0,0,0,4,0,4,16],[0,0,0,0,3,67,0,75,0,0,4,34,0,0,193,61,0,0,0,164,3,32,0,57,0,0,0,0,3,49,3,79],[0,0,0,100,2,32,0,57,0,0,0,0,1,33,3,79,0,0,0,0,1,1,4,59,0,0,0,0,2,3,4,59],[0,0,0,0,3,2,0,75,0,0,2,0,0,0,193,61,0,0,0,0,4,0,4,21,0,0,0,12,4,64,0,138],[0,0,0,5,4,64,2,16,0,0,0,0,1,0,4,20,0,12,0,0,0,0,0,29,0,10,0,0,0,4,0,29],[0,0,5,8,2,0,0,65,0,0,5,8,3,16,0,156,0,0,0,0,1,2,128,25,0,0,0,192,1,16,2,16],[0,0,128,1,2,0,0,57,20,28,20,8,0,0,4,15,0,0,0,10,3,0,0,41,0,19,0,0,0,1,3,85],[0,0,0,96,1,16,2,112,0,1,5,8,0,16,1,157,0,0,0,5,1,48,2,112,0,0,0,1,1,32,1,149],[0,0,0,1,1,32,1,144,0,0,4,34,0,0,193,61,0,0,0,64,1,0,4,61,0,0,0,100,2,16,0,57],[0,0,5,20,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,68,2,16,0,57,0,0,5,21,3,0,0,65],[0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,37,3,0,0,57,0,0,0,0,0,50,4,53],[0,0,5,22,2,0,0,65,0,0,0,0,0,33,4,53,0,0,0,4,2,16,0,57,0,0,0,32,3,0,0,57],[0,0,0,0,0,50,4,53,0,0,5,8,2,0,0,65,0,0,5,8,3,16,0,156,0,0,0,0,1,2,128,25],[0,0,0,64,1,16,2,16,0,0,5,23,1,16,1,199,0,0,20,30,0,1,4,48,0,0,0,4,2,96,0,138],[0,0,0,96,2,32,0,140,0,0,1,57,0,0,65,61,0,0,0,68,2,16,3,112,0,0,0,0,2,2,4,59],[0,10,0,0,0,2,0,29,0,0,5,16,2,32,0,156,0,0,1,57,0,0,33,61,0,0,0,10,2,0,0,41],[0,9,0,4,0,32,0,61,0,0,0,9,2,96,0,106,0,0,5,17,3,0,0,65,0,0,2,96,4,32,0,140],[0,0,0,0,4,0,0,25,0,0,0,0,4,3,64,25,0,0,5,17,2,32,1,151,0,0,0,0,5,2,0,75],[0,0,0,0,3,0,160,25,0,0,5,17,2,32,0,156,0,0,0,0,3,4,192,25,0,0,0,0,2,3,0,75],[0,0,1,59,0,0,97,61,0,0,0,0,1,0,0,25,0,0,20,30,0,1,4,48,0,0,0,36,2,16,3,112],[0,0,0,0,2,2,4,59,0,8,0,0,0,2,0,29,0,0,0,0,2,0,4,17,0,0,128,1,2,32,0,140],[0,0,4,34,0,0,193,61,0,0,0,0,2,0,4,18,0,0,5,18,2,32,1,151,0,0,0,0,3,0,4,16],[0,7,0,0,0,3,0,29,0,0,0,0,2,50,0,75,0,0,4,34,0,0,193,61,0,0,0,0,2,0,4,20],[0,0,5,59,3,0,0,65,0,0,0,160,0,48,4,63,0,0,0,10,3,0,0,41,0,6,1,4,0,48,0,61],[0,0,0,6,1,16,3,96,0,0,0,0,1,1,4,59,0,0,0,164,0,16,4,63,0,0,0,36,1,0,0,57],[0,0,0,128,0,16,4,63,0,0,0,224,1,0,0,57,0,0,0,64,0,16,4,63,0,0,0,192,1,32,2,16],[0,0,5,31,1,16,1,151,0,0,5,60,1,16,1,199,0,0,128,3,2,0,0,57,0,0,0,0,3,0,0,25],[0,0,0,0,4,0,0,25,0,0,0,0,5,0,0,25,0,0,0,0,6,0,0,25,20,28,20,8,0,0,4,15],[0,19,0,0,0,1,3,85,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,1,5,8,0,48,1,157],[0,0,5,8,8,48,1,151,0,0,0,63,3,128,0,57,0,0,5,61,4,48,1,151,0,0,0,64,6,0,4,61],[0,0,0,0,3,100,0,25,0,0,0,0,4,67,0,75,0,0,0,0,4,0,0,25,0,0,0,1,4,0,64,57],[0,0,5,16,5,48,0,156,0,0,19,58,0,0,33,61,0,0,0,1,4,64,1,144,0,0,19,58,0,0,193,61],[0,0,0,64,0,48,4,63,0,0,0,0,7,134,4,54,0,0,0,18,3,0,3,103,0,0,0,0,4,0,0,49],[0,0,0,0,5,67,3,79,0,0,0,31,9,128,0,57,0,0,0,5,9,144,2,114,0,0,1,125,0,0,97,61],[0,0,0,0,10,0,0,25,0,0,0,5,11,160,2,16,0,0,0,0,12,183,0,25,0,0,0,0,11,181,3,79],[0,0,0,0,11,11,4,59,0,0,0,0,0,188,4,53,0,0,0,1,10,160,0,57,0,0,0,0,11,154,0,75],[0,0,1,117,0,0,65,61,0,0,0,0,9,0,0,75,0,0,1,127,0,0,97,61,0,0,0,31,9,128,1,143],[0,0,0,5,8,128,2,114,0,0,1,139,0,0,97,61,0,0,0,0,10,0,0,25,0,0,0,5,11,160,2,16],[0,0,0,0,12,183,0,25,0,0,0,0,11,177,3,79,0,0,0,0,11,11,4,59,0,0,0,0,0,188,4,53],[0,0,0,1,10,160,0,57,0,0,0,0,11,138,0,75,0,0,1,131,0,0,65,61,0,0,0,0,10,9,0,75],[0,0,1,154,0,0,97,61,0,0,0,5,8,128,2,16,0,0,0,0,1,129,3,79,0,0,0,0,8,135,0,25],[0,0,0,3,9,144,2,16,0,0,0,0,10,8,4,51,0,0,0,0,10,154,1,207,0,0,0,0,10,154,2,47],[0,0,0,0,1,1,4,59,0,0,1,0,9,144,0,137,0,0,0,0,1,145,2,47,0,0,0,0,1,145,1,207],[0,0,0,0,1,161,1,159,0,0,0,0,0,24,4,53,0,0,0,1,1,32,1,144,0,0,2,82,0,0,97,61],[0,0,0,8,1,0,0,107,0,0,18,1,0,0,193,61,0,0,0,6,1,0,0,41,0,0,1,0,1,16,0,138],[0,0,0,0,1,19,3,79,0,0,0,0,1,1,4,59,0,0,0,1,2,16,0,140,0,0,2,111,0,0,33,61],[0,0,0,0,2,1,0,75,0,0,2,196,0,0,97,61,0,0,0,1,1,16,0,140,0,0,2,178,0,0,193,61],[0,0,5,62,1,0,0,65,0,0,0,0,0,16,4,57,0,0,5,8,1,0,0,65,0,0,0,0,2,0,4,20],[0,0,5,8,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,5,63,1,16,1,199],[0,0,128,11,2,0,0,57,20,28,20,13,0,0,4,15,0,0,0,1,2,32,1,144,0,0,18,65,0,0,97,61],[0,0,0,64,3,0,4,61,0,0,0,0,4,1,4,59,0,0,0,128,1,64,0,140,0,0,4,63,0,0,65,61],[0,0,0,128,1,64,2,112,0,0,5,66,2,64,0,156,0,0,0,0,1,4,160,25,0,0,5,66,2,64,0,156],[0,0,0,0,2,0,0,25,0,0,0,16,2,0,32,57,0,0,0,8,5,32,1,191,0,0,5,16,6,16,0,156],[0,0,0,0,5,2,160,25,0,0,0,64,2,16,2,112,0,0,5,16,6,16,0,156,0,0,0,0,2,1,160,25],[0,0,0,4,1,80,1,191,0,0,5,8,6,32,0,156,0,0,0,0,1,5,160,25,0,0,0,32,6,32,2,112],[0,0,5,8,5,32,0,156,0,0,0,0,6,2,160,25,0,0,0,2,5,16,1,191,0,0,255,255,2,96,0,140],[0,0,0,0,5,1,160,25,0,0,0,16,1,96,2,112,0,0,0,0,1,6,160,25,0,0,0,255,1,16,0,140],[0,0,0,1,5,80,32,57,0,0,0,32,1,0,0,138,0,0,0,65,2,80,0,57,0,0,0,0,1,18,1,111],[0,0,0,0,1,19,0,25,0,0,0,0,2,49,0,75,0,0,0,0,2,0,0,25,0,0,0,1,2,0,64,57],[0,0,5,16,6,16,0,156,0,0,19,58,0,0,33,61,0,0,0,1,2,32,1,144,0,0,19,58,0,0,193,61],[0,0,0,64,0,16,4,63,0,0,0,2,1,80,0,57,0,0,0,0,6,19,4,54,0,0,0,18,1,0,3,103],[0,0,0,0,2,0,0,49,0,0,0,33,7,80,0,57,0,0,0,5,7,112,2,114,0,0,1,238,0,0,97,61],[0,0,0,0,8,33,3,79,0,0,0,0,9,0,0,25,0,0,0,5,10,144,2,16,0,0,0,0,11,166,0,25],[0,0,0,0,10,168,3,79,0,0,0,0,10,10,4,59,0,0,0,0,0,171,4,53,0,0,0,1,9,144,0,57],[0,0,0,0,10,121,0,75,0,0,1,230,0,0,65,61,0,0,0,0,7,0,0,75,0,0,1,240,0,0,97,61],[0,0,0,0,7,3,4,51,0,0,0,0,7,7,0,75,0,0,9,198,0,0,97,61,0,0,0,0,7,6,4,51],[0,0,5,65,7,112,1,151,0,0,0,248,8,80,2,16,0,0,0,0,7,120,1,159,0,0,5,67,7,112,0,65],[0,0,0,0,0,118,4,53,0,0,0,3,5,80,2,16,0,0,0,248,5,80,0,137,0,0,0,0,4,84,1,207],[0,0,0,255,5,80,0,140,0,0,0,0,4,0,32,25,0,0,0,33,5,48,0,57,0,0,4,81,0,0,1,61],[0,0,0,0,67,18,0,169,0,0,0,0,66,35,0,217,0,0,0,0,1,18,0,75,0,0,18,29,0,0,193,61],[0,0,0,0,4,0,4,21,0,0,0,11,4,64,0,138,0,0,0,5,4,64,2,16,0,0,0,0,1,0,4,20],[0,11,0,0,0,0,0,29,0,0,0,0,2,3,0,75,0,0,0,255,0,0,97,61,0,0,5,8,2,0,0,65],[0,0,5,8,4,16,0,156,0,0,0,0,1,2,128,25,0,0,0,192,1,16,2,16,0,0,5,19,1,16,1,199],[0,0,128,9,2,0,0,57,0,0,128,1,4,0,0,57,0,0,0,0,5,0,0,25,20,28,20,8,0,0,4,15],[0,0,0,0,3,0,4,21,0,0,0,11,3,48,0,138,0,0,0,5,3,48,2,16,0,0,1,7,0,0,1,61],[0,0,0,160,8,128,0,57,0,0,0,0,8,129,3,79,0,0,0,0,8,8,4,59,0,0,0,31,5,80,0,138],[0,0,5,17,9,0,0,65,0,0,0,0,10,88,0,75,0,0,0,0,10,0,0,25,0,0,0,0,10,9,128,25],[0,0,5,17,5,80,1,151,0,0,5,17,11,128,1,151,0,0,0,0,12,91,0,75,0,0,0,0,9,0,128,25],[0,0,0,0,5,91,1,63,0,0,5,17,5,80,0,156,0,0,0,0,9,10,192,25,0,0,0,0,5,9,0,75],[0,0,1,57,0,0,193,61,0,0,0,0,2,40,0,25,0,0,0,0,5,33,3,79,0,0,0,0,8,5,4,59],[0,0,5,16,5,128,0,156,0,0,1,57,0,0,33,61,0,0,0,0,5,134,0,73,0,0,0,32,9,32,0,57],[0,0,5,17,2,0,0,65,0,0,0,0,10,89,0,75,0,0,0,0,10,0,0,25,0,0,0,0,10,2,32,25],[0,0,5,17,5,80,1,151,0,0,5,17,11,144,1,151,0,0,0,0,12,91,0,75,0,0,0,0,2,0,128,25],[0,0,0,0,5,91,1,63,0,0,5,17,5,80,0,156,0,0,0,0,2,10,192,25,0,0,0,0,2,2,0,75],[0,0,1,57,0,0,193,61,0,0,0,0,2,0,4,20,0,0,5,8,5,32,0,156,0,0,0,205,0,0,33,61],[0,0,128,6,5,64,0,140,0,0,0,0,5,0,0,25,0,0,3,243,0,0,193,61,0,0,0,4,5,128,0,140],[0,0,0,0,5,0,0,25,0,0,3,243,0,0,65,61,0,0,0,0,10,145,3,79,0,0,0,1,5,0,0,57],[0,0,0,0,10,10,4,59,0,0,5,25,10,160,1,151,0,0,5,26,11,160,0,156,0,0,3,239,0,0,33,61],[0,0,5,29,11,160,0,156,0,0,3,243,0,0,97,61,0,0,5,30,10,160,0,156,0,0,3,243,0,0,97,61],[0,0,0,0,5,0,0,25,0,0,3,243,0,0,1,61,0,0,0,0,1,6,4,51,0,0,5,8,2,0,0,65],[0,0,5,8,3,16,0,156,0,0,0,0,1,2,128,25,0,0,5,8,3,112,0,156,0,0,0,0,7,2,128,25],[0,0,0,64,2,112,2,16,0,0,0,96,1,16,2,16,0,0,0,0,1,33,1,159,0,0,20,30,0,1,4,48],[0,0,0,0,7,81,3,79,0,0,0,0,7,7,4,59,0,0,5,25,7,112,1,151,0,0,5,36,8,112,0,156],[0,0,4,34,0,0,97,61,0,0,5,37,7,112,0,156,0,0,3,106,0,0,193,61,0,0,0,67,4,64,0,140],[0,0,3,208,0,0,33,61,0,0,5,22,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57],[0,0,0,132,0,16,4,63,0,0,0,64,1,0,0,57,0,0,0,164,0,16,4,63,0,0,5,53,1,0,0,65],[0,0,0,196,0,16,4,63,0,0,5,54,1,0,0,65,0,0,0,165,0,0,1,61,0,0,0,2,2,16,0,140],[0,0,3,18,0,0,97,61,0,0,0,113,1,16,0,140,0,0,2,178,0,0,193,61,0,0,0,10,2,0,0,41],[0,0,1,196,1,32,0,57,0,0,0,0,1,19,3,79,0,0,0,0,2,36,0,73,0,0,0,35,2,32,0,138],[0,0,0,0,1,1,4,59,0,0,5,17,5,0,0,65,0,0,0,0,6,33,0,75,0,0,0,0,6,0,0,25],[0,0,0,0,6,5,128,25,0,0,5,17,2,32,1,151,0,0,5,17,7,16,1,151,0,0,0,0,8,39,0,75],[0,0,0,0,5,0,128,25,0,0,0,0,2,39,1,63,0,0,5,17,2,32,0,156,0,0,0,0,5,6,192,25],[0,0,0,0,2,5,0,75,0,0,1,57,0,0,193,61,0,0,0,9,2,16,0,41,0,0,0,0,1,35,3,79],[0,0,0,0,1,1,4,59,0,0,5,16,5,16,0,156,0,0,1,57,0,0,33,61,0,0,0,0,6,20,0,73],[0,0,0,32,5,32,0,57,0,0,5,17,2,0,0,65,0,0,0,0,7,101,0,75,0,0,0,0,7,0,0,25],[0,0,0,0,7,2,32,25,0,0,5,17,6,96,1,151,0,0,5,17,8,80,1,151,0,0,0,0,9,104,0,75],[0,0,0,0,2,0,128,25,0,0,0,0,6,104,1,63,0,0,5,17,6,96,0,156,0,0,0,0,2,7,192,25],[0,0,0,0,2,2,0,75,0,0,1,57,0,0,193,61,0,0,5,8,6,80,1,151,0,0,0,0,2,0,4,20],[0,2,0,0,0,99,3,85,0,0,0,0,5,81,0,25,0,0,0,0,1,21,0,75,0,0,0,0,1,0,0,25],[0,0,0,1,1,0,64,57,0,0,0,1,1,16,1,144,0,0,18,29,0,0,193,61,0,0,0,0,1,84,0,75],[0,0,18,29,0,0,65,61,0,0,0,0,1,99,3,79,0,0,0,0,3,84,0,73,0,0,5,8,3,48,1,151],[0,2,0,0,0,49,3,229,0,0,5,73,4,32,0,156,0,0,6,137,0,0,65,61,0,0,0,64,1,0,4,61],[0,0,0,68,2,16,0,57,0,0,5,34,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57],[0,0,0,8,3,0,0,57,0,0,2,184,0,0,1,61,0,0,0,64,1,0,4,61,0,0,0,68,2,16,0,57],[0,0,5,96,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,23,3,0,0,57],[0,0,0,0,0,50,4,53,0,0,5,22,2,0,0,65,0,0,0,0,0,33,4,53,0,0,0,4,2,16,0,57],[0,0,0,32,3,0,0,57,0,0,0,0,0,50,4,53,0,0,5,8,2,0,0,65,0,0,5,8,3,16,0,156],[0,0,0,0,1,2,128,25,0,0,0,64,1,16,2,16,0,0,5,52,1,16,1,199,0,0,20,30,0,1,4,48],[0,0,0,6,1,48,3,96,0,0,0,64,2,0,4,61,0,8,0,0,0,2,0,29,0,0,0,0,1,1,4,59],[0,0,0,128,2,16,0,140,0,0,3,114,0,0,65,61,0,0,0,128,2,16,2,112,0,0,5,66,6,16,0,156],[0,0,0,0,2,1,160,25,0,0,5,66,6,16,0,156,0,0,0,0,6,0,0,25,0,0,0,16,6,0,32,57],[0,0,0,8,7,96,1,191,0,0,5,16,8,32,0,156,0,0,0,0,7,6,160,25,0,0,0,64,6,32,2,112],[0,0,5,16,8,32,0,156,0,0,0,0,6,2,160,25,0,0,0,4,8,112,1,191,0,0,5,8,2,96,0,156],[0,0,0,0,8,7,160,25,0,0,0,32,7,96,2,112,0,0,5,8,2,96,0,156,0,0,0,0,7,6,160,25],[0,0,0,2,2,128,1,191,0,0,255,255,6,112,0,140,0,0,0,0,2,8,160,25,0,0,0,16,6,112,2,112],[0,0,0,0,6,7,160,25,0,0,0,255,6,96,0,140,0,0,0,1,2,32,32,57,0,0,0,32,6,0,0,138],[0,0,0,65,7,32,0,57,0,0,0,0,6,103,1,111,0,0,0,8,6,96,0,41,0,0,0,8,7,96,0,108],[0,0,0,0,7,0,0,25,0,0,0,1,7,0,64,57,0,0,5,16,8,96,0,156,0,0,19,58,0,0,33,61],[0,0,0,1,7,112,1,144,0,0,19,58,0,0,193,61,0,0,0,64,0,96,4,63,0,0,0,2,6,32,0,57],[0,0,0,8,7,0,0,41,0,0,0,0,6,103,4,54,0,0,0,33,7,32,0,57,0,0,0,5,7,112,2,114],[0,0,2,254,0,0,97,61,0,0,0,0,8,0,0,25,0,0,0,5,9,128,2,16,0,0,0,0,10,150,0,25],[0,0,0,0,9,149,3,79,0,0,0,0,9,9,4,59,0,0,0,0,0,154,4,53,0,0,0,1,8,128,0,57],[0,0,0,0,9,120,0,75,0,0,2,246,0,0,65,61,0,0,0,0,7,0,0,75,0,0,3,0,0,0,97,61],[0,0,0,8,7,0,0,41,0,0,0,0,7,7,4,51,0,0,0,0,7,7,0,75,0,0,9,198,0,0,97,61],[0,0,0,0,7,6,4,51,0,0,5,65,7,112,1,151,0,0,0,248,8,32,2,16,0,0,0,0,7,120,1,159],[0,0,5,67,7,112,0,65,0,0,0,0,0,118,4,53,0,0,0,3,2,32,2,16,0,0,0,248,2,32,0,137],[0,0,0,0,1,33,1,207,0,0,0,255,2,32,0,140,0,0,0,0,1,0,32,25,0,0,0,8,2,0,0,41],[0,0,0,33,2,32,0,57,0,0,3,131,0,0,1,61,0,0,5,62,1,0,0,65,0,0,0,0,0,16,4,57],[0,0,5,8,1,0,0,65,0,0,0,0,2,0,4,20,0,0,5,8,3,32,0,156,0,0,0,0,2,1,128,25],[0,0,0,192,1,32,2,16,0,0,5,63,1,16,1,199,0,0,128,11,2,0,0,57,20,28,20,13,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,18,65,0,0,97,61,0,0,0,64,3,0,4,61,0,0,0,0,4,1,4,59],[0,0,0,128,1,64,0,140,0,0,4,157,0,0,65,61,0,0,0,128,1,64,2,112,0,0,5,66,2,64,0,156],[0,0,0,0,1,4,160,25,0,0,5,66,2,64,0,156,0,0,0,0,2,0,0,25,0,0,0,16,2,0,32,57],[0,0,0,8,5,32,1,191,0,0,5,16,6,16,0,156,0,0,0,0,5,2,160,25,0,0,0,64,2,16,2,112],[0,0,5,16,6,16,0,156,0,0,0,0,2,1,160,25,0,0,0,4,1,80,1,191,0,0,5,8,6,32,0,156],[0,0,0,0,1,5,160,25,0,0,0,32,6,32,2,112,0,0,5,8,5,32,0,156,0,0,0,0,6,2,160,25],[0,0,0,2,5,16,1,191,0,0,255,255,2,96,0,140,0,0,0,0,5,1,160,25,0,0,0,16,1,96,2,112],[0,0,0,0,1,6,160,25,0,0,0,255,1,16,0,140,0,0,0,1,5,80,32,57,0,0,0,32,1,0,0,138],[0,0,0,65,2,80,0,57,0,0,0,0,1,18,1,111,0,0,0,0,1,19,0,25,0,0,0,0,2,49,0,75],[0,0,0,0,2,0,0,25,0,0,0,1,2,0,64,57,0,0,5,16,6,16,0,156,0,0,19,58,0,0,33,61],[0,0,0,1,2,32,1,144,0,0,19,58,0,0,193,61,0,0,0,64,0,16,4,63,0,0,0,2,1,80,0,57],[0,0,0,0,6,19,4,54,0,0,0,18,1,0,3,103,0,0,0,0,2,0,0,49,0,0,0,33,7,80,0,57],[0,0,0,5,7,112,2,114,0,0,3,88,0,0,97,61,0,0,0,0,8,33,3,79,0,0,0,0,9,0,0,25],[0,0,0,5,10,144,2,16,0,0,0,0,11,166,0,25,0,0,0,0,10,168,3,79,0,0,0,0,10,10,4,59],[0,0,0,0,0,171,4,53,0,0,0,1,9,144,0,57,0,0,0,0,10,121,0,75,0,0,3,80,0,0,65,61],[0,0,0,0,7,0,0,75,0,0,3,90,0,0,97,61,0,0,0,0,7,3,4,51,0,0,0,0,7,7,0,75],[0,0,9,198,0,0,97,61,0,0,0,0,7,6,4,51,0,0,5,65,7,112,1,151,0,0,0,248,8,80,2,16],[0,0,0,0,7,120,1,159,0,0,5,67,7,112,0,65,0,0,0,0,0,118,4,53,0,0,0,3,5,80,2,16],[0,0,0,248,5,80,0,137,0,0,0,0,4,84,1,207,0,0,0,255,5,80,0,140,0,0,0,0,4,0,32,25],[0,0,0,33,5,48,0,57,0,0,4,175,0,0,1,61,0,0,5,22,1,0,0,65,0,0,0,128,0,16,4,63],[0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63,0,0,0,26,1,0,0,57,0,0,0,164,0,16,4,63],[0,0,5,56,1,0,0,65,0,0,0,212,0,0,1,61,0,0,0,8,2,0,0,41,0,0,5,64,2,32,0,156],[0,0,19,58,0,0,33,61,0,0,0,8,6,0,0,41,0,0,0,64,2,96,0,57,0,0,0,64,0,32,4,63],[0,0,0,1,2,0,0,58,0,0,0,0,2,38,4,54,0,0,0,0,6,5,4,59,0,0,0,0,0,98,4,53],[0,0,9,198,0,0,97,61,0,0,0,248,7,16,2,16,0,0,5,17,8,0,0,65,0,0,0,0,1,1,0,75],[0,0,0,0,8,7,192,25,0,0,5,65,1,96,1,151,0,0,0,0,1,129,1,159,0,0,0,0,0,18,4,53],[0,0,0,64,1,0,4,61,0,0,0,6,2,0,0,41,0,0,0,96,2,32,0,138,0,0,0,0,6,35,3,79],[0,0,0,0,6,6,4,59,0,0,0,128,7,96,0,140,0,0,4,251,0,0,65,61,0,0,0,128,7,96,2,112],[0,0,5,66,8,96,0,156,0,0,0,0,7,6,160,25,0,0,5,66,8,96,0,156,0,0,0,0,8,0,0,25],[0,0,0,16,8,0,32,57,0,0,0,8,9,128,1,191,0,0,5,16,10,112,0,156,0,0,0,0,9,8,160,25],[0,0,0,64,8,112,2,112,0,0,5,16,10,112,0,156,0,0,0,0,8,7,160,25,0,0,0,4,10,144,1,191],[0,0,5,8,7,128,0,156,0,0,0,0,10,9,160,25,0,0,0,32,9,128,2,112,0,0,5,8,7,128,0,156],[0,0,0,0,9,8,160,25,0,0,0,2,7,160,1,191,0,0,255,255,8,144,0,140,0,0,0,0,7,10,160,25],[0,0,0,16,8,144,2,112,0,0,0,0,8,9,160,25,0,0,0,255,8,128,0,140,0,0,0,1,7,112,32,57],[0,0,0,32,8,0,0,138,0,0,0,65,9,112,0,57,0,0,0,0,8,137,1,111,0,0,0,0,8,129,0,25],[0,0,0,0,9,24,0,75,0,0,0,0,9,0,0,25,0,0,0,1,9,0,64,57,0,0,5,16,10,128,0,156],[0,0,19,58,0,0,33,61,0,0,0,1,9,144,1,144,0,0,19,58,0,0,193,61,0,0,0,64,0,128,4,63],[0,0,0,2,8,112,0,57,0,0,0,0,8,129,4,54,0,0,0,33,9,112,0,57,0,0,0,5,9,144,2,114],[0,0,3,190,0,0,97,61,0,0,0,0,10,0,0,25,0,0,0,5,11,160,2,16,0,0,0,0,12,184,0,25],[0,0,0,0,11,181,3,79,0,0,0,0,11,11,4,59,0,0,0,0,0,188,4,53,0,0,0,1,10,160,0,57],[0,0,0,0,11,154,0,75,0,0,3,182,0,0,65,61,0,0,0,0,9,0,0,75,0,0,3,192,0,0,97,61],[0,0,0,0,9,1,4,51,0,0,0,0,9,9,0,75,0,0,9,198,0,0,97,61,0,0,0,0,9,8,4,51],[0,0,5,65,9,144,1,151,0,0,0,248,10,112,2,16,0,0,0,0,9,154,1,159,0,0,5,67,9,144,0,65],[0,0,0,0,0,152,4,53,0,0,0,3,7,112,2,16,0,0,0,248,7,112,0,137,0,0,0,0,6,118,1,207],[0,0,0,255,7,112,0,140,0,0,0,0,6,0,32,25,0,0,0,33,7,16,0,57,0,0,5,10,0,0,1,61],[0,0,0,4,4,80,0,57,0,0,0,0,5,65,3,79,0,0,0,0,5,5,4,59,0,9,0,0,0,5,0,29],[0,0,5,18,5,80,0,156,0,0,1,57,0,0,33,61,0,0,1,64,3,48,0,138,0,0,0,0,3,49,3,79],[0,0,0,32,4,64,0,57,0,0,0,0,4,65,3,79,0,0,0,0,4,4,4,59,0,8,0,0,0,4,0,29],[0,0,0,0,3,3,4,59,0,0,5,38,4,0,0,65,0,0,0,128,0,64,4,63,0,0,5,18,2,32,1,151],[0,6,0,0,0,2,0,29,0,0,0,132,0,32,4,63,0,0,5,18,2,48,1,151,0,7,0,0,0,2,0,29],[0,0,0,164,0,32,4,63,0,0,0,0,2,0,4,20,0,0,0,9,3,0,0,41,0,0,0,4,3,48,0,140],[0,0,5,86,0,0,193,61,0,0,0,0,1,97,3,79,0,0,0,1,3,0,0,49,0,0,0,32,2,48,0,140],[0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57,0,0,5,130,0,0,1,61,0,0,5,27,11,160,0,156],[0,0,3,243,0,0,97,61,0,0,5,28,10,160,0,156,0,0,0,0,5,0,192,25,0,0,0,0,10,152,0,25],[0,0,0,0,6,166,0,75,0,0,0,0,6,0,0,25,0,0,0,1,6,0,64,57,0,0,0,0,8,138,0,75],[0,0,0,1,6,96,65,191,0,0,5,8,8,144,1,151,0,2,0,0,0,129,3,85,0,0,0,0,1,129,3,79],[0,0,0,0,8,3,0,75,0,0,4,14,0,0,193,61,0,0,0,1,3,96,1,144,0,0,18,29,0,0,193,61],[0,0,5,32,3,0,0,65,0,0,5,33,6,0,0,65,0,0,0,0,5,5,0,75,0,0,0,0,6,3,192,25],[0,0,0,192,2,32,2,16,0,0,5,31,2,32,1,151,0,0,0,0,2,38,1,159,0,0,0,0,3,167,0,73],[0,0,5,8,3,48,1,151,0,0,0,0,1,49,3,223,0,2,0,0,0,33,3,181,0,0,0,0,1,33,3,175],[0,0,0,0,2,4,0,25,0,0,4,26,0,0,1,61,0,0,0,1,6,96,1,144,0,0,18,29,0,0,193,61],[0,0,0,0,6,167,0,73,0,0,5,8,6,96,1,151,0,0,0,0,1,97,3,223,0,0,0,192,2,32,2,16],[0,0,5,31,2,32,1,151,0,0,5,32,2,32,1,199,0,2,0,0,0,33,3,181,0,0,0,0,1,33,3,175],[0,0,128,9,2,0,0,57,0,0,0,0,6,0,0,25,20,28,20,18,0,0,4,15,0,19,0,0,0,1,3,85],[0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,1,5,8,0,48,1,157,0,0,5,8,3,48,1,151],[0,0,0,1,2,32,1,144,0,0,4,36,0,0,97,61,0,0,0,0,1,0,0,25,0,0,20,29,0,1,4,46],[0,0,0,31,4,48,1,143,0,0,0,5,2,48,2,114,0,0,4,47,0,0,97,61,0,0,0,0,5,0,0,25],[0,0,0,5,6,80,2,16,0,0,0,0,7,97,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,118,4,53],[0,0,0,1,5,80,0,57,0,0,0,0,6,37,0,75,0,0,4,40,0,0,65,61,0,0,0,0,5,4,0,75],[0,0,4,61,0,0,97,61,0,0,0,3,4,64,2,16,0,0,0,5,2,32,2,16,0,0,0,0,5,2,4,51],[0,0,0,0,5,69,1,207,0,0,0,0,5,69,2,47,0,0,0,0,1,33,3,79,0,0,0,0,1,1,4,59],[0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,81,1,159],[0,0,0,0,0,18,4,53,0,0,0,96,1,48,2,16,0,0,20,30,0,1,4,48,0,0,5,64,1,48,0,156],[0,0,19,58,0,0,33,61,0,0,0,64,1,48,0,57,0,0,0,64,0,16,4,63,0,0,0,1,1,0,0,58],[0,0,0,0,5,19,4,54,0,0,0,0,2,0,0,49,0,0,0,18,1,0,3,103,0,0,0,0,6,33,3,79],[0,0,0,0,6,6,4,59,0,0,0,0,0,101,4,53,0,0,9,198,0,0,97,61,0,0,0,248,7,64,2,16],[0,0,5,17,8,0,0,65,0,0,0,0,4,4,0,75,0,0,0,0,8,7,192,25,0,0,5,65,4,96,1,151],[0,0,0,0,4,132,1,159,0,0,0,0,0,69,4,53,0,0,0,6,5,16,3,96,0,0,0,64,4,0,4,61],[0,0,0,0,5,5,4,59,0,0,0,128,6,80,0,140,0,0,5,170,0,0,65,61,0,0,0,128,6,80,2,112],[0,0,5,66,7,80,0,156,0,0,0,0,6,5,160,25,0,0,5,66,7,80,0,156,0,0,0,0,7,0,0,25],[0,0,0,16,7,0,32,57,0,0,0,8,8,112,1,191,0,0,5,16,9,96,0,156,0,0,0,0,8,7,160,25],[0,0,0,64,7,96,2,112,0,0,5,16,9,96,0,156,0,0,0,0,7,6,160,25,0,0,0,4,9,128,1,191],[0,0,5,8,6,112,0,156,0,0,0,0,9,8,160,25,0,0,0,32,8,112,2,112,0,0,5,8,6,112,0,156],[0,0,0,0,8,7,160,25,0,0,0,2,6,144,1,191,0,0,255,255,7,128,0,140,0,0,0,0,6,9,160,25],[0,0,0,16,7,128,2,112,0,0,0,0,7,8,160,25,0,0,0,255,7,112,0,140,0,0,0,1,6,96,32,57],[0,0,0,32,7,0,0,138,0,0,0,65,8,96,0,57,0,0,0,0,7,120,1,111,0,0,0,0,7,116,0,25],[0,0,0,0,8,71,0,75,0,0,0,0,8,0,0,25,0,0,0,1,8,0,64,57,0,0,5,16,9,112,0,156],[0,0,19,58,0,0,33,61,0,0,0,1,8,128,1,144,0,0,19,58,0,0,193,61,0,0,0,64,0,112,4,63],[0,0,0,2,7,96,0,57,0,0,0,0,7,116,4,54,0,0,0,33,8,96,0,57,0,0,0,5,8,128,2,114],[0,0,4,139,0,0,97,61,0,0,0,0,9,33,3,79,0,0,0,0,10,0,0,25,0,0,0,5,11,160,2,16],[0,0,0,0,12,183,0,25,0,0,0,0,11,185,3,79,0,0,0,0,11,11,4,59,0,0,0,0,0,188,4,53],[0,0,0,1,10,160,0,57,0,0,0,0,11,138,0,75,0,0,4,131,0,0,65,61,0,0,0,0,8,0,0,75],[0,0,4,141,0,0,97,61,0,0,0,0,8,4,4,51,0,0,0,0,8,8,0,75,0,0,9,198,0,0,97,61],[0,0,0,0,8,7,4,51,0,0,5,65,8,128,1,151,0,0,0,248,9,96,2,16,0,0,0,0,8,137,1,159],[0,0,5,67,8,128,0,65,0,0,0,0,0,135,4,53,0,0,0,3,6,96,2,16,0,0,0,248,6,96,0,137],[0,0,0,0,5,101,1,207,0,0,0,255,6,96,0,140,0,0,0,0,5,0,32,25,0,0,0,33,6,64,0,57],[0,0,5,186,0,0,1,61,0,0,5,64,1,48,0,156,0,0,19,58,0,0,33,61,0,0,0,64,1,48,0,57],[0,0,0,64,0,16,4,63,0,0,0,1,1,0,0,58,0,0,0,0,5,19,4,54,0,0,0,0,2,0,0,49],[0,0,0,18,1,0,3,103,0,0,0,0,6,33,3,79,0,0,0,0,6,6,4,59,0,0,0,0,0,101,4,53],[0,0,9,198,0,0,97,61,0,0,0,248,7,64,2,16,0,0,5,17,8,0,0,65,0,0,0,0,4,4,0,75],[0,0,0,0,8,7,192,25,0,0,5,65,4,96,1,151,0,0,0,0,4,132,1,159,0,0,0,0,0,69,4,53],[0,0,0,6,5,16,3,96,0,0,0,64,4,0,4,61,0,0,0,0,5,5,4,59,0,0,0,128,6,80,0,140],[0,0,6,8,0,0,65,61,0,0,0,128,6,80,2,112,0,0,5,66,7,80,0,156,0,0,0,0,6,5,160,25],[0,0,5,66,7,80,0,156,0,0,0,0,7,0,0,25,0,0,0,16,7,0,32,57,0,0,0,8,8,112,1,191],[0,0,5,16,9,96,0,156,0,0,0,0,8,7,160,25,0,0,0,64,7,96,2,112,0,0,5,16,9,96,0,156],[0,0,0,0,7,6,160,25,0,0,0,4,9,128,1,191,0,0,5,8,6,112,0,156,0,0,0,0,9,8,160,25],[0,0,0,32,8,112,2,112,0,0,5,8,6,112,0,156,0,0,0,0,8,7,160,25,0,0,0,2,6,144,1,191],[0,0,255,255,7,128,0,140,0,0,0,0,6,9,160,25,0,0,0,16,7,128,2,112,0,0,0,0,7,8,160,25],[0,0,0,255,7,112,0,140,0,0,0,1,6,96,32,57,0,0,0,32,7,0,0,138,0,0,0,65,8,96,0,57],[0,0,0,0,7,120,1,111,0,0,0,0,7,116,0,25,0,0,0,0,8,71,0,75,0,0,0,0,8,0,0,25],[0,0,0,1,8,0,64,57,0,0,5,16,9,112,0,156,0,0,19,58,0,0,33,61,0,0,0,1,8,128,1,144],[0,0,19,58,0,0,193,61,0,0,0,64,0,112,4,63,0,0,0,2,7,96,0,57,0,0,0,0,7,116,4,54],[0,0,0,33,8,96,0,57,0,0,0,5,8,128,2,114,0,0,4,233,0,0,97,61,0,0,0,0,9,33,3,79],[0,0,0,0,10,0,0,25,0,0,0,5,11,160,2,16,0,0,0,0,12,183,0,25,0,0,0,0,11,185,3,79],[0,0,0,0,11,11,4,59,0,0,0,0,0,188,4,53,0,0,0,1,10,160,0,57,0,0,0,0,11,138,0,75],[0,0,4,225,0,0,65,61,0,0,0,0,8,0,0,75,0,0,4,235,0,0,97,61,0,0,0,0,8,4,4,51],[0,0,0,0,8,8,0,75,0,0,9,198,0,0,97,61,0,0,0,0,8,7,4,51,0,0,5,65,8,128,1,151],[0,0,0,248,9,96,2,16,0,0,0,0,8,137,1,159,0,0,5,67,8,128,0,65,0,0,0,0,0,135,4,53],[0,0,0,3,6,96,2,16,0,0,0,248,6,96,0,137,0,0,0,0,5,101,1,207,0,0,0,255,6,96,0,140],[0,0,0,0,5,0,32,25,0,0,0,33,6,64,0,57,0,0,6,24,0,0,1,61,0,0,5,64,7,16,0,156],[0,0,19,58,0,0,33,61,0,0,0,64,7,16,0,57,0,0,0,64,0,112,4,63,0,0,0,1,7,0,0,58],[0,0,0,0,7,113,4,54,0,0,0,0,8,5,4,59,0,0,0,0,0,135,4,53,0,0,9,198,0,0,97,61],[0,0,0,248,9,96,2,16,0,0,5,17,10,0,0,65,0,0,0,0,6,6,0,75,0,0,0,0,10,9,192,25],[0,0,5,65,6,128,1,151,0,0,0,0,6,166,1,159,0,0,0,0,0,103,4,53,0,0,0,64,2,32,0,138],[0,0,0,0,6,35,3,79,0,0,0,64,2,0,4,61,0,0,0,0,6,6,4,59,0,0,0,128,7,96,0,140],[0,0,8,96,0,0,65,61,0,0,0,128,7,96,2,112,0,0,5,66,8,96,0,156,0,0,0,0,7,6,160,25],[0,0,5,66,8,96,0,156,0,0,0,0,8,0,0,25,0,0,0,16,8,0,32,57,0,0,0,8,9,128,1,191],[0,0,5,16,10,112,0,156,0,0,0,0,9,8,160,25,0,0,0,64,8,112,2,112,0,0,5,16,10,112,0,156],[0,0,0,0,8,7,160,25,0,0,0,4,10,144,1,191,0,0,5,8,7,128,0,156,0,0,0,0,10,9,160,25],[0,0,0,32,9,128,2,112,0,0,5,8,7,128,0,156,0,0,0,0,9,8,160,25,0,0,0,2,7,160,1,191],[0,0,255,255,8,144,0,140,0,0,0,0,7,10,160,25,0,0,0,16,8,144,2,112,0,0,0,0,8,9,160,25],[0,0,0,255,8,128,0,140,0,0,0,1,7,112,32,57,0,0,0,32,8,0,0,138,0,0,0,65,9,112,0,57],[0,0,0,0,8,137,1,111,0,0,0,0,8,130,0,25,0,0,0,0,9,40,0,75,0,0,0,0,9,0,0,25],[0,0,0,1,9,0,64,57,0,0,5,16,10,128,0,156,0,0,19,58,0,0,33,61,0,0,0,1,9,144,1,144],[0,0,19,58,0,0,193,61,0,0,0,64,0,128,4,63,0,0,0,2,8,112,0,57,0,0,0,0,8,130,4,54],[0,0,0,33,9,112,0,57,0,0,0,5,9,144,2,114,0,0,5,68,0,0,97,61,0,0,0,0,10,0,0,25],[0,0,0,5,11,160,2,16,0,0,0,0,12,184,0,25,0,0,0,0,11,181,3,79,0,0,0,0,11,11,4,59],[0,0,0,0,0,188,4,53,0,0,0,1,10,160,0,57,0,0,0,0,11,154,0,75,0,0,5,60,0,0,65,61],[0,0,0,0,9,0,0,75,0,0,5,70,0,0,97,61,0,0,0,0,9,2,4,51,0,0,0,0,9,9,0,75],[0,0,9,198,0,0,97,61,0,0,0,0,9,8,4,51,0,0,5,65,9,144,1,151,0,0,0,248,10,112,2,16],[0,0,0,0,9,154,1,159,0,0,5,67,9,144,0,65,0,0,0,0,0,152,4,53,0,0,0,3,7,112,2,16],[0,0,0,248,7,112,0,137,0,0,0,0,6,118,1,207,0,0,0,255,7,112,0,140,0,0,0,0,6,0,32,25],[0,0,0,33,7,32,0,57,0,0,8,111,0,0,1,61,0,0,5,8,1,0,0,65,0,0,5,8,3,32,0,156],[0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,5,39,1,16,1,199,0,0,0,9,2,0,0,41],[20,28,20,13,0,0,4,15,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,5,8,3,48,1,151],[0,0,0,32,4,48,0,140,0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57,0,0,0,31,5,64,1,143],[0,0,0,5,6,64,2,114,0,0,5,111,0,0,97,61,0,0,0,0,7,0,0,25,0,0,0,5,8,112,2,16],[0,0,0,0,9,129,3,79,0,0,0,0,9,9,4,59,0,0,0,128,8,128,0,57,0,0,0,0,0,152,4,53],[0,0,0,1,7,112,0,57,0,0,0,0,8,103,0,75,0,0,5,103,0,0,65,61,0,0,0,0,7,5,0,75],[0,0,5,126,0,0,97,61,0,0,0,5,6,96,2,16,0,0,0,0,7,97,3,79,0,0,0,3,5,80,2,16],[0,0,0,128,6,96,0,57,0,0,0,0,8,6,4,51,0,0,0,0,8,88,1,207,0,0,0,0,8,88,2,47],[0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137,0,0,0,0,7,87,2,47,0,0,0,0,5,87,1,207],[0,0,0,0,5,133,1,159,0,0,0,0,0,86,4,53,0,1,0,0,0,3,0,31,0,19,0,0,0,1,3,85],[0,0,0,1,2,32,1,144,0,0,6,102,0,0,97,61,0,0,0,31,2,64,0,57,0,0,0,96,5,32,1,143],[0,0,0,128,2,80,1,191,0,0,0,64,0,32,4,63,0,0,0,32,4,48,0,140,0,0,1,57,0,0,65,61],[0,0,0,128,4,0,4,61,0,0,0,8,4,64,0,108,0,0,4,34,0,0,129,61,0,0,0,160,4,80,0,57],[0,0,5,40,6,0,0,65,0,0,0,0,0,100,4,53,0,0,0,164,6,80,0,57,0,0,0,7,7,0,0,41],[0,0,0,0,0,118,4,53,0,0,0,196,6,80,0,57,0,0,0,0,0,6,4,53,0,0,0,68,6,0,0,57],[0,1,0,0,0,6,0,29,0,0,0,0,0,98,4,53,0,0,1,64,6,80,0,57,0,0,0,64,0,96,4,63],[0,0,1,32,7,80,0,57,0,0,5,41,6,0,0,65,0,3,0,0,0,7,0,29,0,0,0,0,0,103,4,53],[0,0,1,0,6,80,1,191,0,0,0,32,5,0,0,57,0,4,0,0,0,5,0,29,0,2,0,0,0,6,0,29],[0,0,0,0,0,86,4,53,0,0,0,0,5,2,4,51,0,0,0,0,2,0,4,20,0,0,0,9,6,0,0,41],[0,0,0,4,6,96,0,140,0,0,8,253,0,0,193,61,0,0,0,1,2,0,0,57,0,0,5,16,4,48,0,156],[0,0,19,58,0,0,33,61,0,0,9,17,0,0,1,61,0,0,5,64,6,64,0,156,0,0,19,58,0,0,33,61],[0,0,0,64,6,64,0,57,0,0,0,64,0,96,4,63,0,0,0,0,7,33,3,79,0,0,0,1,6,0,0,58],[0,0,0,0,6,100,4,54,0,0,0,0,7,7,4,59,0,0,0,0,0,118,4,53,0,0,9,198,0,0,97,61],[0,0,0,248,8,80,2,16,0,0,5,17,9,0,0,65,0,0,0,0,5,5,0,75,0,0,0,0,9,8,192,25],[0,0,5,65,5,112,1,151,0,0,0,0,5,149,1,159,0,0,0,0,0,86,4,53,0,0,0,64,5,0,4,61],[0,0,0,6,6,0,0,41,0,0,0,96,6,96,0,138,0,0,0,0,7,97,3,79,0,0,0,0,7,7,4,59],[0,0,0,128,8,112,0,140,0,0,9,95,0,0,65,61,0,0,0,128,8,112,2,112,0,0,5,66,9,112,0,156],[0,0,0,0,8,7,160,25,0,0,5,66,9,112,0,156,0,0,0,0,9,0,0,25,0,0,0,16,9,0,32,57],[0,0,0,8,10,144,1,191,0,0,5,16,11,128,0,156,0,0,0,0,10,9,160,25,0,0,0,64,9,128,2,112],[0,0,5,16,11,128,0,156,0,0,0,0,9,8,160,25,0,0,0,4,11,160,1,191,0,0,5,8,8,144,0,156],[0,0,0,0,11,10,160,25,0,0,0,32,10,144,2,112,0,0,5,8,8,144,0,156,0,0,0,0,10,9,160,25],[0,0,0,2,8,176,1,191,0,0,255,255,9,160,0,140,0,0,0,0,8,11,160,25,0,0,0,16,9,160,2,112],[0,0,0,0,9,10,160,25,0,0,0,255,9,144,0,140,0,0,0,1,8,128,32,57,0,0,0,32,9,0,0,138],[0,0,0,65,10,128,0,57,0,0,0,0,9,154,1,111,0,0,0,0,9,149,0,25,0,0,0,0,10,89,0,75],[0,0,0,0,10,0,0,25,0,0,0,1,10,0,64,57,0,0,5,16,11,144,0,156,0,0,19,58,0,0,33,61],[0,0,0,1,10,160,1,144,0,0,19,58,0,0,193,61,0,0,0,64,0,144,4,63,0,0,0,2,9,128,0,57],[0,0,0,0,9,149,4,54,0,0,0,33,10,128,0,57,0,0,0,5,10,160,2,114,0,0,5,246,0,0,97,61],[0,0,0,0,11,33,3,79,0,0,0,0,12,0,0,25,0,0,0,5,13,192,2,16,0,0,0,0,14,217,0,25],[0,0,0,0,13,219,3,79,0,0,0,0,13,13,4,59,0,0,0,0,0,222,4,53,0,0,0,1,12,192,0,57],[0,0,0,0,13,172,0,75,0,0,5,238,0,0,65,61,0,0,0,0,10,0,0,75,0,0,5,248,0,0,97,61],[0,0,0,0,10,5,4,51,0,0,0,0,10,10,0,75,0,0,9,198,0,0,97,61,0,0,0,0,10,9,4,51],[0,0,5,65,10,160,1,151,0,0,0,248,11,128,2,16,0,0,0,0,10,171,1,159,0,0,5,67,10,160,0,65],[0,0,0,0,0,169,4,53,0,0,0,3,8,128,2,16,0,0,0,248,8,128,0,137,0,0,0,0,7,135,1,207],[0,0,0,255,8,128,0,140,0,0,0,0,7,0,32,25,0,0,0,33,8,80,0,57,0,0,9,111,0,0,1,61],[0,0,5,64,6,64,0,156,0,0,19,58,0,0,33,61,0,0,0,64,6,64,0,57,0,0,0,64,0,96,4,63],[0,0,0,0,7,33,3,79,0,0,0,1,6,0,0,58,0,0,0,0,6,100,4,54,0,0,0,0,7,7,4,59],[0,0,0,0,0,118,4,53,0,0,9,198,0,0,97,61,0,0,0,248,8,80,2,16,0,0,5,17,9,0,0,65],[0,0,0,0,5,5,0,75,0,0,0,0,9,8,192,25,0,0,5,65,5,112,1,151,0,0,0,0,5,149,1,159],[0,0,0,0,0,86,4,53,0,0,0,64,5,0,4,61,0,0,0,6,6,0,0,41,0,0,0,64,7,96,0,138],[0,0,0,0,6,113,3,79,0,0,0,0,6,6,4,59,0,0,0,128,8,96,0,140,0,0,9,188,0,0,65,61],[0,0,0,128,8,96,2,112,0,0,5,66,9,96,0,156,0,0,0,0,8,6,160,25,0,0,5,66,9,96,0,156],[0,0,0,0,9,0,0,25,0,0,0,16,9,0,32,57,0,0,0,8,10,144,1,191,0,0,5,16,11,128,0,156],[0,0,0,0,10,9,160,25,0,0,0,64,9,128,2,112,0,0,5,16,11,128,0,156,0,0,0,0,9,8,160,25],[0,0,0,4,11,160,1,191,0,0,5,8,8,144,0,156,0,0,0,0,11,10,160,25,0,0,0,32,10,144,2,112],[0,0,5,8,8,144,0,156,0,0,0,0,10,9,160,25,0,0,0,2,8,176,1,191,0,0,255,255,9,160,0,140],[0,0,0,0,8,11,160,25,0,0,0,16,9,160,2,112,0,0,0,0,9,10,160,25,0,0,0,255,9,144,0,140],[0,0,0,1,8,128,32,57,0,0,0,32,9,0,0,138,0,0,0,65,10,128,0,57,0,0,0,0,9,154,1,111],[0,0,0,0,9,149,0,25,0,0,0,0,10,89,0,75,0,0,0,0,10,0,0,25,0,0,0,1,10,0,64,57],[0,0,5,16,11,144,0,156,0,0,19,58,0,0,33,61,0,0,0,1,10,160,1,144,0,0,19,58,0,0,193,61],[0,0,0,64,0,144,4,63,0,0,0,2,9,128,0,57,0,0,0,0,9,149,4,54,0,0,0,33,10,128,0,57],[0,0,0,5,10,160,2,114,0,0,6,84,0,0,97,61,0,0,0,0,11,33,3,79,0,0,0,0,12,0,0,25],[0,0,0,5,13,192,2,16,0,0,0,0,14,217,0,25,0,0,0,0,13,219,3,79,0,0,0,0,13,13,4,59],[0,0,0,0,0,222,4,53,0,0,0,1,12,192,0,57,0,0,0,0,13,172,0,75,0,0,6,76,0,0,65,61],[0,0,0,0,10,0,0,75,0,0,6,86,0,0,97,61,0,0,0,0,10,5,4,51,0,0,0,0,10,10,0,75],[0,0,9,198,0,0,97,61,0,0,0,0,10,9,4,51,0,0,5,65,10,160,1,151,0,0,0,248,11,128,2,16],[0,0,0,0,10,171,1,159,0,0,5,67,10,160,0,65,0,0,0,0,0,169,4,53,0,0,0,3,8,128,2,16],[0,0,0,248,8,128,0,137,0,0,0,0,6,134,1,207,0,0,0,255,8,128,0,140,0,0,0,0,6,0,32,25],[0,0,0,33,8,80,0,57,0,0,10,129,0,0,1,61,0,0,0,64,2,0,4,61,0,0,0,31,4,48,1,143],[0,0,0,5,5,48,2,114,0,0,6,115,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16],[0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53],[0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,6,107,0,0,65,61,0,0,0,0,6,4,0,75],[0,0,6,130,0,0,97,61,0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25],[0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47],[0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207],[0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,5,8,1,0,0,65,0,0,5,8,4,32,0,156],[0,0,0,0,2,1,128,25,0,0,0,64,1,32,2,16,0,0,0,96,2,48,2,16,0,0,0,0,1,33,1,159],[0,0,20,30,0,1,4,48,0,0,0,0,1,49,3,223,0,0,0,192,2,32,2,16,0,0,5,31,2,32,1,151],[0,0,5,33,2,32,1,199,0,2,0,0,0,33,3,181,0,0,0,0,1,33,3,175,0,0,128,16,2,0,0,57],[20,28,20,23,0,0,4,15,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,1,5,8,0,48,1,157],[0,0,5,8,5,48,1,151,0,19,0,0,0,1,3,85,0,0,0,1,2,32,1,144,0,0,9,202,0,0,97,61],[0,0,0,63,2,80,0,57,0,0,5,61,2,32,1,151,0,0,0,64,6,0,4,61,0,0,0,0,2,38,0,25],[0,0,0,0,3,98,0,75,0,0,0,0,3,0,0,25,0,0,0,1,3,0,64,57,0,0,5,16,4,32,0,156],[0,0,19,58,0,0,33,61,0,0,0,1,3,48,1,144,0,0,19,58,0,0,193,61,0,0,0,64,0,32,4,63],[0,0,0,0,4,86,4,54,0,0,0,18,2,0,3,103,0,0,0,0,3,0,0,49,0,0,0,31,7,80,0,57],[0,0,0,5,7,112,2,114,0,0,6,180,0,0,97,61,0,0,0,0,8,50,3,79,0,0,0,0,9,0,0,25],[0,0,0,5,10,144,2,16,0,0,0,0,11,164,0,25,0,0,0,0,10,168,3,79,0,0,0,0,10,10,4,59],[0,0,0,0,0,171,4,53,0,0,0,1,9,144,0,57,0,0,0,0,10,121,0,75,0,0,6,172,0,0,65,61],[0,0,0,0,7,0,0,75,0,0,6,182,0,0,97,61,0,0,0,31,7,80,1,143,0,0,0,5,5,80,2,114],[0,0,6,194,0,0,97,61,0,0,0,0,8,0,0,25,0,0,0,5,9,128,2,16,0,0,0,0,10,148,0,25],[0,0,0,0,9,145,3,79,0,0,0,0,9,9,4,59,0,0,0,0,0,154,4,53,0,0,0,1,8,128,0,57],[0,0,0,0,9,88,0,75,0,0,6,186,0,0,65,61,0,0,0,0,8,7,0,75,0,0,6,209,0,0,97,61],[0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,84,0,25,0,0,0,3,7,112,2,16],[0,0,0,0,8,5,4,51,0,0,0,0,8,120,1,207,0,0,0,0,8,120,2,47,0,0,0,0,1,1,4,59],[0,0,1,0,7,112,0,137,0,0,0,0,1,113,2,47,0,0,0,0,1,113,1,207,0,0,0,0,1,129,1,159],[0,0,0,0,0,21,4,53,0,0,0,0,1,6,4,51,0,0,0,32,1,16,0,140,0,0,10,4,0,0,193,61],[0,0,0,10,6,0,0,41,0,0,0,0,1,99,0,73,0,0,0,35,5,16,0,138,0,8,2,4,0,96,0,61],[0,0,0,8,1,32,3,96,0,0,0,0,1,1,4,59,0,0,5,17,6,0,0,65,0,0,0,0,7,81,0,75],[0,0,0,0,7,0,0,25,0,0,0,0,7,6,128,25,0,0,5,17,5,80,1,151,0,0,5,17,8,16,1,151],[0,0,0,0,9,88,0,75,0,0,0,0,6,0,128,25,0,0,0,0,5,88,1,63,0,0,5,17,5,80,0,156],[0,0,0,0,6,7,192,25,0,0,0,0,5,6,0,75,0,0,1,57,0,0,193,61,0,0,0,0,4,4,4,51],[0,5,0,0,0,4,0,29,0,0,0,9,1,16,0,41,0,0,0,0,4,18,3,79,0,0,0,0,5,4,4,59],[0,0,5,16,4,80,0,156,0,0,1,57,0,0,33,61,0,0,0,5,4,80,2,16,0,0,0,0,3,67,0,73],[0,0,0,32,6,16,0,57,0,0,5,17,1,0,0,65,0,0,0,0,7,54,0,75,0,0,0,0,7,0,0,25],[0,0,0,0,7,1,32,25,0,0,5,17,3,48,1,151,0,0,5,17,8,96,1,151,0,0,0,0,9,56,0,75],[0,0,0,0,1,0,128,25,0,0,0,0,3,56,1,63,0,0,5,17,3,48,0,156,0,0,0,0,1,7,192,25],[0,0,0,0,1,1,0,75,0,0,1,57,0,0,193,61,0,0,0,64,1,0,4,61,0,0,0,32,3,16,0,57],[0,0,5,74,5,80,1,152,0,0,7,12,0,0,97,61,0,0,0,0,2,98,3,79,0,0,0,0,6,0,0,25],[0,0,0,5,7,96,2,16,0,0,0,0,8,115,0,25,0,0,0,0,7,114,3,79,0,0,0,0,7,7,4,59],[0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,7,4,0,0,65,61],[0,0,0,0,2,0,0,75,0,0,7,14,0,0,97,61,0,0,0,0,0,65,4,53,0,0,0,63,2,64,0,57],[0,0,0,32,4,0,0,138,0,0,0,0,2,66,1,111,0,0,0,0,2,33,0,25,0,0,0,0,4,18,0,75],[0,0,0,0,4,0,0,25,0,0,0,1,4,0,64,57,0,0,5,16,5,32,0,156,0,0,19,58,0,0,33,61],[0,0,0,1,4,64,1,144,0,0,19,58,0,0,193,61,0,0,0,64,0,32,4,63,0,0,5,8,2,0,0,65],[0,0,5,8,4,48,0,156,0,0,0,0,3,2,128,25,0,0,0,64,3,48,2,16,0,0,0,0,1,1,4,51],[0,0,5,8,4,16,0,156,0,0,0,0,1,2,128,25,0,0,0,96,1,16,2,16,0,0,0,0,1,49,1,159],[0,0,0,0,3,0,4,20,0,0,5,8,4,48,0,156,0,0,0,0,3,2,128,25,0,0,0,192,2,48,2,16],[0,0,0,0,1,18,1,159,0,0,5,19,1,16,1,199,0,0,128,16,2,0,0,57,20,28,20,13,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,1,57,0,0,97,61,0,0,0,0,2,0,0,49,0,0,0,10,3,32,0,106],[0,0,0,35,5,48,0,138,0,0,0,8,3,0,0,41,0,0,0,32,4,48,0,57,0,0,0,18,3,0,3,103],[0,0,0,0,4,67,3,79,0,0,0,0,4,4,4,59,0,0,5,17,6,0,0,65,0,0,0,0,7,84,0,75],[0,0,0,0,7,0,0,25,0,0,0,0,7,6,128,25,0,0,5,17,5,80,1,151,0,0,5,17,8,64,1,151],[0,0,0,0,9,88,0,75,0,0,0,0,6,0,128,25,0,0,0,0,5,88,1,63,0,0,5,17,5,80,0,156],[0,0,0,0,6,7,192,25,0,0,0,0,1,1,4,59,0,8,0,0,0,1,0,29,0,0,0,0,1,6,0,75],[0,0,1,57,0,0,193,61,0,0,0,9,4,64,0,41,0,0,0,0,1,67,3,79,0,0,0,0,1,1,4,59],[0,0,5,16,5,16,0,156,0,0,1,57,0,0,33,61,0,0,0,0,6,18,0,73,0,0,0,32,5,64,0,57],[0,0,5,17,4,0,0,65,0,0,0,0,7,101,0,75,0,0,0,0,7,0,0,25,0,0,0,0,7,4,32,25],[0,0,5,17,6,96,1,151,0,0,5,17,8,80,1,151,0,0,0,0,9,104,0,75,0,0,0,0,4,0,128,25],[0,0,0,0,6,104,1,63,0,0,5,17,6,96,0,156,0,0,0,0,4,7,192,25,0,0,0,0,4,4,0,75],[0,0,1,57,0,0,193,61,0,0,5,8,6,80,1,151,0,0,0,0,4,0,4,20,0,2,0,0,0,99,3,85],[0,0,0,0,5,81,0,25,0,0,0,0,1,21,0,75,0,0,0,0,1,0,0,25,0,0,0,1,1,0,64,57],[0,0,0,1,1,16,1,144,0,0,18,29,0,0,193,61,0,0,0,0,1,82,0,75,0,0,18,29,0,0,65,61],[0,0,0,0,1,99,3,79,0,0,0,0,2,82,0,73,0,0,5,8,2,32,1,151,0,2,0,0,0,33,3,229],[0,0,5,8,3,64,0,156,0,0,2,171,0,0,33,61,0,0,0,0,1,33,3,223,0,0,0,192,2,64,2,16],[0,0,5,31,2,32,1,151,0,0,5,33,2,32,1,199,0,2,0,0,0,33,3,181,0,0,0,0,1,33,3,175],[0,0,128,16,2,0,0,57,20,28,20,23,0,0,4,15,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112],[0,1,5,8,0,48,1,157,0,0,5,8,3,48,1,151,0,19,0,0,0,1,3,85,0,0,0,1,2,32,1,144],[0,0,17,47,0,0,97,61,0,0,0,63,2,48,0,57,0,0,5,61,2,32,1,151,0,0,0,64,5,0,4,61],[0,0,0,0,2,37,0,25,0,0,0,0,4,82,0,75,0,0,0,0,4,0,0,25,0,0,0,1,4,0,64,57],[0,0,5,16,6,32,0,156,0,0,19,58,0,0,33,61,0,0,0,1,4,64,1,144,0,0,19,58,0,0,193,61],[0,0,0,64,0,32,4,63,0,0,0,0,2,53,4,54,0,0,0,18,4,0,3,103,0,0,0,31,6,48,0,57],[0,0,0,5,6,96,2,114,0,0,7,148,0,0,97,61,0,0,0,0,7,64,3,104,0,0,0,0,8,0,0,25],[0,0,0,5,9,128,2,16,0,0,0,0,10,146,0,25,0,0,0,0,9,151,3,79,0,0,0,0,9,9,4,59],[0,0,0,0,0,154,4,53,0,0,0,1,8,128,0,57,0,0,0,0,9,104,0,75,0,0,7,140,0,0,65,61],[0,0,0,0,6,0,0,75,0,0,7,150,0,0,97,61,0,0,0,31,6,48,1,143,0,0,0,5,3,48,2,114],[0,0,7,162,0,0,97,61,0,0,0,0,7,0,0,25,0,0,0,5,8,112,2,16,0,0,0,0,9,130,0,25],[0,0,0,0,8,129,3,79,0,0,0,0,8,8,4,59,0,0,0,0,0,137,4,53,0,0,0,1,7,112,0,57],[0,0,0,0,8,55,0,75,0,0,7,154,0,0,65,61,0,0,0,0,7,6,0,75,0,0,7,177,0,0,97,61],[0,0,0,5,3,48,2,16,0,0,0,0,1,49,3,79,0,0,0,0,3,50,0,25,0,0,0,3,6,96,2,16],[0,0,0,0,7,3,4,51,0,0,0,0,7,103,1,207,0,0,0,0,7,103,2,47,0,0,0,0,1,1,4,59],[0,0,1,0,6,96,0,137,0,0,0,0,1,97,2,47,0,0,0,0,1,97,1,207,0,0,0,0,1,113,1,159],[0,0,0,0,0,19,4,53,0,0,0,0,1,5,4,51,0,0,0,32,1,16,0,140,0,0,10,4,0,0,193,61],[0,0,0,10,12,0,0,41,0,0,0,100,1,192,0,57,0,0,0,0,1,20,3,79,0,0,0,68,3,192,0,57],[0,0,0,0,5,52,3,79,0,0,0,36,3,192,0,57,0,0,0,0,6,52,3,79,0,0,1,36,3,192,0,57],[0,0,0,0,7,52,3,79,0,0,0,6,8,64,3,96,0,0,0,228,3,192,0,57,0,0,0,0,9,52,3,79],[0,0,0,196,3,192,0,57,0,0,0,0,10,52,3,79,0,0,0,164,3,192,0,57,0,0,0,0,11,52,3,79],[0,0,0,132,3,192,0,57,0,0,0,0,12,52,3,79,0,0,0,9,3,64,3,96,0,0,0,0,3,3,4,59],[0,0,0,0,4,6,4,59,0,0,0,0,5,5,4,59,0,0,0,0,6,1,4,59,0,0,0,0,12,12,4,59],[0,0,0,0,11,11,4,59,0,0,0,0,10,10,4,59,0,0,0,0,9,9,4,59,0,0,0,0,8,8,4,59],[0,0,0,0,7,7,4,59,0,0,0,0,2,2,4,51,0,0,0,64,1,0,4,61,0,0,1,192,13,16,0,57],[0,0,0,0,0,45,4,53,0,0,1,160,2,16,0,57,0,0,0,8,13,0,0,41,0,0,0,0,0,210,4,53],[0,0,1,128,2,16,0,57,0,0,0,5,13,0,0,41,0,0,0,0,0,210,4,53,0,0,1,96,2,16,0,57],[0,0,0,0,0,114,4,53,0,0,1,64,2,16,0,57,0,0,0,0,0,130,4,53,0,0,1,32,2,16,0,57],[0,0,0,0,0,146,4,53,0,0,1,0,2,16,0,57,0,0,0,0,0,162,4,53,0,0,0,224,2,16,0,57],[0,0,0,0,0,178,4,53,0,0,0,192,2,16,0,57,0,0,0,0,0,194,4,53,0,0,0,160,2,16,0,57],[0,0,0,0,0,98,4,53,0,0,0,128,2,16,0,57,0,0,0,0,0,82,4,53,0,0,0,96,2,16,0,57],[0,0,0,0,0,66,4,53,0,0,0,64,2,16,0,57,0,0,0,0,0,50,4,53,0,0,0,32,2,16,0,57],[0,0,5,76,3,0,0,65,0,0,0,0,0,50,4,53,0,0,1,192,3,0,0,57,0,0,0,0,0,49,4,53],[0,0,5,77,3,16,0,156,0,0,19,58,0,0,33,61,0,0,1,224,3,16,0,57,0,0,0,64,0,48,4,63],[0,0,5,8,4,0,0,65,0,0,5,8,3,32,0,156,0,0,0,0,2,4,128,25,0,0,0,64,2,32,2,16],[0,0,0,0,1,1,4,51,0,0,5,8,3,16,0,156,0,0,0,0,1,4,128,25,0,0,0,96,1,16,2,16],[0,0,0,0,1,33,1,159,0,0,0,0,2,0,4,20,0,0,5,8,3,32,0,156,0,0,0,0,2,4,128,25],[0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159,0,0,5,19,1,16,1,199,0,0,128,16,2,0,0,57],[20,28,20,13,0,0,4,15,0,0,0,1,2,32,1,144,0,0,1,57,0,0,97,61,0,0,0,0,1,1,4,59],[0,6,0,0,0,1,0,29,0,0,0,64,1,0,4,61,0,8,0,0,0,1,0,29,0,0,5,62,1,0,0,65],[0,0,0,0,0,16,4,57,0,0,0,0,1,0,4,20,0,0,5,8,2,16,0,156,0,0,5,8,1,0,128,65],[0,0,0,192,1,16,2,16,0,0,5,63,1,16,1,199,0,0,128,11,2,0,0,57,20,28,20,13,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,18,65,0,0,97,61,0,0,0,8,4,0,0,41,0,0,0,32,2,64,0,57],[0,0,0,0,1,1,4,59,0,0,5,78,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,128,3,64,0,57],[0,0,0,0,0,19,4,53,0,0,0,96,1,64,0,57,0,0,5,79,3,0,0,65,0,0,0,0,0,49,4,53],[0,0,0,64,1,64,0,57,0,0,5,80,3,0,0,65,0,0,0,0,0,49,4,53,0,0,0,128,1,0,0,57],[0,0,0,0,0,20,4,53,0,0,5,81,1,64,0,156,0,0,19,58,0,0,33,61,0,0,0,8,4,0,0,41],[0,0,0,160,1,64,0,57,0,0,0,64,0,16,4,63,0,0,5,8,1,0,0,65,0,0,5,8,3,32,0,156],[0,0,0,0,2,1,128,25,0,0,0,64,2,32,2,16,0,0,0,0,3,4,4,51,0,0,5,8,4,48,0,156],[0,0,0,0,3,1,128,25,0,0,0,96,3,48,2,16,0,0,0,0,2,35,1,159,0,0,0,0,3,0,4,20],[0,0,5,8,4,48,0,156,0,0,0,0,3,1,128,25,0,0,0,192,1,48,2,16,0,0,0,0,1,33,1,159],[0,0,5,19,1,16,1,199,0,0,128,16,2,0,0,57,20,28,20,13,0,0,4,15,0,0,0,1,2,32,1,144],[0,0,1,57,0,0,97,61,0,0,0,0,3,1,4,59,0,0,0,64,1,0,4,61,0,0,0,66,2,16,0,57],[0,0,0,6,4,0,0,41,0,0,0,0,0,66,4,53,0,0,0,32,2,16,0,57,0,0,5,82,4,0,0,65],[0,0,0,0,0,66,4,53,0,0,0,34,4,16,0,57,0,0,0,0,0,52,4,53,0,0,0,66,3,0,0,57],[0,0,0,0,0,49,4,53,0,0,5,47,3,16,0,156,0,0,19,58,0,0,33,61,0,0,0,128,3,16,0,57],[0,0,0,64,0,48,4,63,0,0,5,8,3,0,0,65,0,0,5,8,4,32,0,156,0,0,0,0,2,3,128,25],[0,0,0,64,2,32,2,16,0,0,0,0,1,1,4,51,0,0,5,8,4,16,0,156,0,0,0,0,1,3,128,25],[0,0,0,96,1,16,2,16,0,0,0,0,1,33,1,159,0,0,0,0,2,0,4,20,0,0,5,8,4,32,0,156],[0,0,0,0,2,3,128,25,0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159,0,0,17,249,0,0,1,61],[0,0,5,64,7,32,0,156,0,0,19,58,0,0,33,61,0,0,0,64,7,32,0,57,0,0,0,64,0,112,4,63],[0,0,0,1,7,0,0,58,0,0,0,0,7,114,4,54,0,0,0,0,8,5,4,59,0,0,0,0,0,135,4,53],[0,0,9,198,0,0,97,61,0,0,0,248,9,96,2,16,0,0,5,17,10,0,0,65,0,0,0,0,6,6,0,75],[0,0,0,0,10,9,192,25,0,0,5,65,6,128,1,151,0,0,0,0,6,166,1,159,0,0,0,0,0,103,4,53],[0,0,0,64,6,0,4,61,0,6,0,0,0,6,0,29,0,0,0,32,7,96,0,57,0,0,0,0,6,1,4,51],[0,0,0,0,8,6,0,75,0,0,8,126,0,0,97,61,0,0,0,0,8,0,0,25,0,0,0,0,9,120,0,25],[0,0,0,32,8,128,0,57,0,0,0,0,10,24,0,25,0,0,0,0,10,10,4,51,0,0,0,0,0,169,4,53],[0,0,0,0,9,104,0,75,0,0,8,119,0,0,65,61,0,0,0,0,1,118,0,25,0,0,0,0,0,1,4,53],[0,0,0,0,7,2,4,51,0,0,0,0,8,7,0,75,0,0,8,139,0,0,97,61,0,0,0,0,8,0,0,25],[0,0,0,0,9,24,0,25,0,0,0,32,8,128,0,57,0,0,0,0,10,40,0,25,0,0,0,0,10,10,4,51],[0,0,0,0,0,169,4,53,0,0,0,0,9,120,0,75,0,0,8,132,0,0,65,61,0,0,0,0,1,23,0,25],[0,0,0,0,0,1,4,53,0,0,0,0,1,103,0,25,0,0,0,6,6,0,0,41,0,0,0,0,0,22,4,53],[0,0,0,63,1,16,0,57,0,2,0,32,0,0,0,146,0,0,0,2,1,16,1,127,0,0,0,0,2,97,0,25],[0,0,0,0,1,18,0,75,0,0,0,0,1,0,0,25,0,0,0,1,1,0,64,57,0,5,0,0,0,2,0,29],[0,0,5,16,2,32,0,156,0,0,19,58,0,0,33,61,0,0,0,1,1,16,1,144,0,0,19,58,0,0,193,61],[0,0,0,5,1,0,0,41,0,0,0,64,0,16,4,63,0,0,5,64,1,16,0,156,0,0,19,58,0,0,33,61],[0,0,0,10,7,0,0,41,0,0,0,68,1,112,0,57,0,0,0,0,1,19,3,79,0,0,0,0,1,1,4,59],[0,0,0,5,8,0,0,41,0,0,0,64,2,128,0,57,0,0,0,64,0,32,4,63,0,0,0,32,2,128,0,57],[0,0,5,68,6,0,0,65,0,0,0,0,0,98,4,53,0,0,0,21,2,0,0,57,0,0,0,0,0,40,4,53],[0,0,0,96,1,16,2,16,0,0,0,33,2,128,0,57,0,0,0,0,0,18,4,53,0,0,1,36,1,112,0,57],[0,0,0,0,2,19,3,79,0,0,0,64,6,0,4,61,0,4,0,0,0,6,0,29,0,0,0,0,2,2,4,59],[0,0,0,128,6,32,0,140,0,0,11,44,0,0,65,61,0,0,0,128,6,32,2,112,0,0,5,66,7,32,0,156],[0,0,0,0,6,2,160,25,0,0,5,66,7,32,0,156,0,0,0,0,7,0,0,25,0,0,0,16,7,0,32,57],[0,0,0,8,8,112,1,191,0,0,5,16,9,96,0,156,0,0,0,0,8,7,160,25,0,0,0,64,7,96,2,112],[0,0,5,16,9,96,0,156,0,0,0,0,7,6,160,25,0,0,0,4,9,128,1,191,0,0,5,8,6,112,0,156],[0,0,0,0,9,8,160,25,0,0,0,32,8,112,2,112,0,0,5,8,6,112,0,156,0,0,0,0,8,7,160,25],[0,0,0,2,6,144,1,191,0,0,255,255,7,128,0,140,0,0,0,0,6,9,160,25,0,0,0,16,7,128,2,112],[0,0,0,0,7,8,160,25,0,0,0,255,7,112,0,140,0,0,0,1,6,96,32,57,0,0,0,65,7,96,0,57],[0,0,0,2,7,112,1,127,0,0,0,4,7,112,0,41,0,0,0,4,8,112,0,108,0,0,0,0,8,0,0,25],[0,0,0,1,8,0,64,57,0,0,5,16,9,112,0,156,0,0,19,58,0,0,33,61,0,0,0,1,8,128,1,144],[0,0,19,58,0,0,193,61,0,0,0,64,0,112,4,63,0,0,0,2,7,96,0,57,0,0,0,4,8,0,0,41],[0,0,0,0,7,120,4,54,0,0,0,33,8,96,0,57,0,0,0,5,8,128,2,114,0,0,8,233,0,0,97,61],[0,0,0,0,9,0,0,25,0,0,0,5,10,144,2,16,0,0,0,0,11,167,0,25,0,0,0,0,10,165,3,79],[0,0,0,0,10,10,4,59,0,0,0,0,0,171,4,53,0,0,0,1,9,144,0,57,0,0,0,0,10,137,0,75],[0,0,8,225,0,0,65,61,0,0,0,0,8,0,0,75,0,0,8,235,0,0,97,61,0,0,0,4,8,0,0,41],[0,0,0,0,8,8,4,51,0,0,0,0,8,8,0,75,0,0,9,198,0,0,97,61,0,0,0,0,8,7,4,51],[0,0,5,65,8,128,1,151,0,0,0,248,9,96,2,16,0,0,0,0,8,137,1,159,0,0,5,67,8,128,0,65],[0,0,0,0,0,135,4,53,0,0,0,3,6,96,2,16,0,0,0,248,6,96,0,137,0,0,0,0,2,98,1,207],[0,0,0,255,6,96,0,140,0,0,0,0,2,0,32,25,0,0,0,4,6,0,0,41,0,0,0,33,6,96,0,57],[0,0,11,61,0,0,1,61,0,0,5,8,1,0,0,65,0,0,5,8,3,80,0,156,0,0,0,0,5,1,128,25],[0,0,0,96,3,80,2,16,0,0,0,64,4,64,2,16,0,0,0,0,3,67,1,159,0,0,5,8,4,32,0,156],[0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,0,0,1,19,1,159,0,0,0,9,2,0,0,41],[20,28,20,8,0,0,4,15,0,5,0,96,0,0,0,61,0,0,0,1,2,32,1,143,0,19,0,0,0,1,3,85],[0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,1,5,8,0,48,1,157,0,0,5,8,3,48,1,152],[0,0,9,61,0,0,97,61,0,0,0,63,4,48,0,57,0,0,0,32,5,0,0,138,0,0,0,0,4,84,1,111],[0,0,0,64,5,0,4,61,0,0,0,0,4,69,0,25,0,5,0,0,0,5,0,29,0,0,0,0,5,84,0,75],[0,0,0,0,5,0,0,25,0,0,0,1,5,0,64,57,0,0,5,16,6,64,0,156,0,0,19,58,0,0,33,61],[0,0,0,1,5,80,1,144,0,0,19,58,0,0,193,61,0,0,0,64,0,64,4,63,0,0,0,31,4,48,1,143],[0,0,0,5,5,0,0,41,0,0,0,0,8,53,4,54,0,0,0,5,3,48,2,114,0,0,9,45,0,0,97,61],[0,0,0,0,5,0,0,25,0,0,0,5,6,80,2,16,0,0,0,0,7,104,0,25,0,0,0,0,6,97,3,79],[0,0,0,0,6,6,4,59,0,0,0,0,0,103,4,53,0,0,0,1,5,80,0,57,0,0,0,0,6,53,0,75],[0,0,9,37,0,0,65,61,0,10,0,0,0,8,0,29,0,0,0,0,5,4,0,75,0,0,9,61,0,0,97,61],[0,0,0,5,3,48,2,16,0,0,0,0,1,49,3,79,0,0,0,10,3,48,0,41,0,0,0,3,4,64,2,16],[0,0,0,0,5,3,4,51,0,0,0,0,5,69,1,207,0,0,0,0,5,69,2,47,0,0,0,0,1,1,4,59],[0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,81,1,159],[0,0,0,0,0,19,4,53,0,0,0,5,1,0,0,41,0,0,0,0,1,1,4,51,0,0,0,0,2,2,0,75],[0,0,9,229,0,0,193,61,0,0,0,0,2,1,0,75,0,0,9,87,0,0,193,61,0,0,0,64,4,0,4,61],[0,10,0,0,0,4,0,29,0,0,5,22,1,0,0,65,0,0,0,0,0,20,4,53,0,0,0,4,1,64,0,57],[0,0,0,4,2,0,0,41,0,0,0,0,0,33,4,53,0,0,0,2,1,0,0,41,0,0,0,0,3,1,4,51],[0,9,0,0,0,3,0,29,0,0,0,36,1,64,0,57,0,0,0,0,0,49,4,53,0,0,0,68,2,64,0,57],[0,0,0,3,1,0,0,41,20,28,19,250,0,0,4,15,0,0,0,9,1,0,0,41,0,0,0,31,1,16,0,57],[0,0,0,32,2,0,0,138,0,0,0,0,1,33,1,111,0,0,0,68,1,16,0,57,0,0,5,8,2,0,0,65],[0,0,5,8,3,16,0,156,0,0,0,0,1,2,128,25,0,0,0,10,4,0,0,41,0,0,5,8,3,64,0,156],[0,0,0,0,4,2,128,25,0,0,0,64,2,64,2,16,0,0,2,89,0,0,1,61,0,0,5,64,8,80,0,156],[0,0,19,58,0,0,33,61,0,0,0,64,8,80,0,57,0,0,0,64,0,128,4,63,0,0,0,0,9,33,3,79],[0,0,0,1,8,0,0,58,0,0,0,0,8,133,4,54,0,0,0,0,9,9,4,59,0,0,0,0,0,152,4,53],[0,0,9,198,0,0,97,61,0,0,0,248,10,112,2,16,0,0,5,17,11,0,0,65,0,0,0,0,7,7,0,75],[0,0,0,0,11,10,192,25,0,0,5,65,7,144,1,151,0,0,0,0,7,183,1,159,0,0,0,0,0,120,4,53],[0,0,0,64,7,0,4,61,0,0,0,64,6,96,0,138,0,0,0,0,8,97,3,79,0,0,0,0,8,8,4,59],[0,0,0,128,9,128,0,140,0,0,10,11,0,0,65,61,0,0,0,128,9,128,2,112,0,0,5,66,10,128,0,156],[0,0,0,0,9,8,160,25,0,0,5,66,10,128,0,156,0,0,0,0,10,0,0,25,0,0,0,16,10,0,32,57],[0,0,0,8,11,160,1,191,0,0,5,16,12,144,0,156,0,0,0,0,11,10,160,25,0,0,0,64,10,144,2,112],[0,0,5,16,12,144,0,156,0,0,0,0,10,9,160,25,0,0,0,4,12,176,1,191,0,0,5,8,9,160,0,156],[0,0,0,0,12,11,160,25,0,0,0,32,11,160,2,112,0,0,5,8,9,160,0,156,0,0,0,0,11,10,160,25],[0,0,0,2,9,192,1,191,0,0,255,255,10,176,0,140,0,0,0,0,9,12,160,25,0,0,0,16,10,176,2,112],[0,0,0,0,10,11,160,25,0,0,0,255,10,160,0,140,0,0,0,1,9,144,32,57,0,0,0,32,10,0,0,138],[0,0,0,65,11,144,0,57,0,0,0,0,10,171,1,111,0,0,0,0,10,167,0,25,0,0,0,0,11,122,0,75],[0,0,0,0,11,0,0,25,0,0,0,1,11,0,64,57,0,0,5,16,12,160,0,156,0,0,19,58,0,0,33,61],[0,0,0,1,11,176,1,144,0,0,19,58,0,0,193,61,0,0,0,64,0,160,4,63,0,0,0,2,10,144,0,57],[0,0,0,0,10,167,4,54,0,0,0,33,11,144,0,57,0,0,0,5,11,176,2,114,0,0,9,170,0,0,97,61],[0,0,0,0,12,33,3,79,0,0,0,0,13,0,0,25,0,0,0,5,14,208,2,16,0,0,0,0,15,234,0,25],[0,0,0,0,14,236,3,79,0,0,0,0,14,14,4,59,0,0,0,0,0,239,4,53,0,0,0,1,13,208,0,57],[0,0,0,0,14,189,0,75,0,0,9,162,0,0,65,61,0,0,0,0,11,0,0,75,0,0,9,172,0,0,97,61],[0,0,0,0,11,7,4,51,0,0,0,0,11,11,0,75,0,0,9,198,0,0,97,61,0,0,0,0,11,10,4,51],[0,0,5,65,11,176,1,151,0,0,0,248,12,144,2,16,0,0,0,0,11,188,1,159,0,0,5,67,11,176,0,65],[0,0,0,0,0,186,4,53,0,0,0,3,9,144,2,16,0,0,0,248,9,144,0,137,0,0,0,0,8,152,1,207],[0,0,0,255,9,144,0,140,0,0,0,0,8,0,32,25,0,0,0,33,9,112,0,57,0,0,10,27,0,0,1,61],[0,0,5,64,8,80,0,156,0,0,19,58,0,0,33,61,0,0,0,64,8,80,0,57,0,0,0,64,0,128,4,63],[0,0,0,0,9,33,3,79,0,0,0,1,8,0,0,58,0,0,0,0,8,133,4,54,0,0,0,0,9,9,4,59],[0,0,0,0,0,152,4,53,0,0,10,123,0,0,193,61,0,0,5,94,1,0,0,65,0,0,0,0,0,16,4,53],[0,0,0,50,1,0,0,57,0,0,0,81,0,0,1,61,0,0,0,31,3,80,1,143,0,0,0,5,2,80,2,114],[0,0,9,213,0,0,97,61,0,0,0,0,4,0,0,25,0,0,0,5,6,64,2,16,0,0,0,0,7,97,3,79],[0,0,0,0,7,7,4,59,0,0,0,0,0,118,4,53,0,0,0,1,4,64,0,57,0,0,0,0,6,36,0,75],[0,0,9,206,0,0,65,61,0,0,0,0,4,3,0,75,0,0,9,227,0,0,97,61,0,0,0,3,3,48,2,16],[0,0,0,5,2,32,2,16,0,0,0,0,4,2,4,51,0,0,0,0,4,52,1,207,0,0,0,0,4,52,2,47],[0,0,0,0,1,33,3,79,0,0,0,0,1,1,4,59,0,0,1,0,3,48,0,137,0,0,0,0,1,49,2,47],[0,0,0,0,1,49,1,207,0,0,0,0,1,65,1,159,0,0,0,0,0,18,4,53,0,0,0,96,1,80,2,16],[0,0,20,30,0,1,4,48,0,0,0,0,2,1,0,75,0,0,11,135,0,0,193,61,0,0,5,42,1,0,0,65],[0,0,0,0,0,16,4,57,0,0,0,9,1,0,0,41,0,0,0,4,0,16,4,67,0,0,5,8,1,0,0,65],[0,0,0,0,2,0,4,20,0,0,5,8,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16],[0,0,5,43,1,16,1,199,0,0,128,2,2,0,0,57,20,28,20,13,0,0,4,15,0,0,0,1,2,32,1,144],[0,0,18,65,0,0,97,61,0,0,0,0,1,1,4,59,0,0,0,0,1,1,0,75,0,0,11,131,0,0,193,61],[0,0,0,64,1,0,4,61,0,0,0,68,2,16,0,57,0,0,5,51,3,0,0,65,0,0,0,0,0,50,4,53],[0,0,0,36,2,16,0,57,0,0,0,29,3,0,0,57,0,0,0,0,0,50,4,53,0,0,5,22,2,0,0,65],[0,0,0,0,0,33,4,53,0,0,0,4,2,16,0,57,0,0,0,4,3,0,0,41,0,0,2,189,0,0,1,61],[0,0,0,64,1,0,4,61,0,0,0,68,2,16,0,57,0,0,5,75,3,0,0,65,0,0,0,0,0,50,4,53],[0,0,0,36,2,16,0,57,0,0,0,31,3,0,0,57,0,0,2,184,0,0,1,61,0,0,5,64,9,112,0,156],[0,0,19,58,0,0,33,61,0,0,0,64,9,112,0,57,0,0,0,64,0,144,4,63,0,0,0,0,10,33,3,79],[0,0,0,1,9,0,0,58,0,0,0,0,9,151,4,54,0,0,0,0,10,10,4,59,0,0,0,0,0,169,4,53],[0,0,9,198,0,0,97,61,0,0,0,248,11,128,2,16,0,0,5,17,12,0,0,65,0,0,0,0,8,8,0,75],[0,0,0,0,12,11,192,25,0,0,5,65,8,160,1,151,0,0,0,0,8,200,1,159,0,0,0,0,0,137,4,53],[0,0,0,64,9,0,4,61,0,0,5,64,8,144,0,156,0,0,19,58,0,0,33,61,0,0,0,32,8,96,0,138],[0,0,0,0,8,129,3,79,0,0,0,0,8,8,4,59,0,0,0,64,10,144,0,57,0,0,0,64,0,160,4,63],[0,0,0,32,10,144,0,57,0,0,5,68,11,0,0,65,0,0,0,0,0,186,4,53,0,0,0,21,10,0,0,57],[0,0,0,0,0,169,4,53,0,0,0,96,8,128,2,16,0,0,0,33,10,144,0,57,0,0,0,0,0,138,4,53],[0,0,0,192,6,96,0,57,0,0,0,0,6,97,3,79,0,0,0,64,8,0,4,61,0,0,0,0,6,6,4,59],[0,8,0,0,0,6,0,29,0,0,0,128,10,96,0,140,0,0,12,152,0,0,65,61,0,0,0,8,6,0,0,41],[0,0,0,128,10,96,2,112,0,0,5,66,11,96,0,156,0,0,0,0,10,6,160,25,0,0,5,66,11,96,0,156],[0,0,0,0,11,0,0,25,0,0,0,16,11,0,32,57,0,0,0,8,12,176,1,191,0,0,5,16,13,160,0,156],[0,0,0,0,12,11,160,25,0,0,0,64,11,160,2,112,0,0,5,16,13,160,0,156,0,0,0,0,11,10,160,25],[0,0,0,4,13,192,1,191,0,0,5,8,10,176,0,156,0,0,0,0,13,12,160,25,0,0,0,32,12,176,2,112],[0,0,5,8,10,176,0,156,0,0,0,0,12,11,160,25,0,0,0,2,10,208,1,191,0,0,255,255,11,192,0,140],[0,0,0,0,10,13,160,25,0,0,0,16,11,192,2,112,0,0,0,0,11,12,160,25,0,0,0,255,11,176,0,140],[0,0,0,1,10,160,32,57,0,0,0,32,11,0,0,138,0,0,0,65,12,160,0,57,0,0,0,0,11,188,1,111],[0,0,0,0,11,184,0,25,0,0,0,0,12,139,0,75,0,0,0,0,12,0,0,25,0,0,0,1,12,0,64,57],[0,0,5,16,13,176,0,156,0,0,19,58,0,0,33,61,0,0,0,1,12,192,1,144,0,0,19,58,0,0,193,61],[0,0,0,64,0,176,4,63,0,0,0,2,11,160,0,57,0,0,0,0,11,184,4,54,0,0,0,33,12,160,0,57],[0,0,0,5,12,192,2,114,0,0,10,104,0,0,97,61,0,0,0,0,13,33,3,79,0,0,0,0,14,0,0,25],[0,0,0,5,15,224,2,16,0,0,0,0,6,251,0,25,0,0,0,0,15,253,3,79,0,0,0,0,15,15,4,59],[0,0,0,0,0,246,4,53,0,0,0,1,14,224,0,57,0,0,0,0,6,206,0,75,0,0,10,96,0,0,65,61],[0,0,0,0,6,0,0,75,0,0,10,106,0,0,97,61,0,0,0,0,6,8,4,51,0,0,0,0,6,6,0,75],[0,0,9,198,0,0,97,61,0,0,0,0,6,11,4,51,0,0,5,65,6,96,1,151,0,0,0,248,12,160,2,16],[0,0,0,0,6,108,1,159,0,0,5,67,6,96,0,65,0,0,0,0,0,107,4,53,0,0,0,3,6,160,2,16],[0,0,0,248,6,96,0,137,0,0,0,8,10,96,1,239,0,0,0,255,6,96,0,140,0,0,0,0,10,0,32,25],[0,0,0,33,6,128,0,57,0,0,0,0,0,166,4,53,0,0,12,170,0,0,1,61,0,0,0,248,10,96,2,16],[0,0,5,17,11,0,0,65,0,0,0,0,6,6,0,75,0,0,0,0,11,10,192,25,0,0,5,65,6,144,1,151],[0,0,0,0,6,182,1,159,0,0,0,0,0,104,4,53,0,0,0,64,6,0,4,61,0,0,0,32,7,112,0,138],[0,0,0,0,8,113,3,79,0,0,0,0,8,8,4,59,0,0,0,128,9,128,0,140,0,0,10,206,0,0,65,61],[0,0,0,128,9,128,2,112,0,0,5,66,10,128,0,156,0,0,0,0,9,8,160,25,0,0,5,66,10,128,0,156],[0,0,0,0,10,0,0,25,0,0,0,16,10,0,32,57,0,0,0,8,11,160,1,191,0,0,5,16,12,144,0,156],[0,0,0,0,11,10,160,25,0,0,0,64,10,144,2,112,0,0,5,16,12,144,0,156,0,0,0,0,10,9,160,25],[0,0,0,4,12,176,1,191,0,0,5,8,9,160,0,156,0,0,0,0,12,11,160,25,0,0,0,32,11,160,2,112],[0,0,5,8,9,160,0,156,0,0,0,0,11,10,160,25,0,0,0,2,9,192,1,191,0,0,255,255,10,176,0,140],[0,0,0,0,9,12,160,25,0,0,0,16,10,176,2,112,0,0,0,0,10,11,160,25,0,0,0,255,10,160,0,140],[0,0,0,1,9,144,32,57,0,0,0,32,10,0,0,138,0,0,0,65,11,144,0,57,0,0,0,0,10,171,1,111],[0,0,0,0,10,166,0,25,0,0,0,0,11,106,0,75,0,0,0,0,11,0,0,25,0,0,0,1,11,0,64,57],[0,0,5,16,12,160,0,156,0,0,19,58,0,0,33,61,0,0,0,1,11,176,1,144,0,0,19,58,0,0,193,61],[0,0,0,64,0,160,4,63,0,0,0,2,10,144,0,57,0,0,0,0,10,166,4,54,0,0,0,33,11,144,0,57],[0,0,0,5,11,176,2,114,0,0,10,188,0,0,97,61,0,0,0,0,12,33,3,79,0,0,0,0,13,0,0,25],[0,0,0,5,14,208,2,16,0,0,0,0,15,234,0,25,0,0,0,0,14,236,3,79,0,0,0,0,14,14,4,59],[0,0,0,0,0,239,4,53,0,0,0,1,13,208,0,57,0,0,0,0,14,189,0,75,0,0,10,180,0,0,65,61],[0,0,0,0,11,0,0,75,0,0,10,190,0,0,97,61,0,0,0,0,11,6,4,51,0,0,0,0,11,11,0,75],[0,0,9,198,0,0,97,61,0,0,0,0,11,10,4,51,0,0,5,65,11,176,1,151,0,0,0,248,12,144,2,16],[0,0,0,0,11,188,1,159,0,0,5,67,11,176,0,65,0,0,0,0,0,186,4,53,0,0,0,3,9,144,2,16],[0,0,0,248,9,144,0,137,0,0,0,0,8,152,1,207,0,0,0,255,9,144,0,140,0,0,0,0,8,0,32,25],[0,0,0,33,9,96,0,57,0,0,10,222,0,0,1,61,0,0,5,64,9,96,0,156,0,0,19,58,0,0,33,61],[0,0,0,64,9,96,0,57,0,0,0,64,0,144,4,63,0,0,0,0,10,33,3,79,0,0,0,1,9,0,0,58],[0,0,0,0,9,150,4,54,0,0,0,0,10,10,4,59,0,0,0,0,0,169,4,53,0,0,9,198,0,0,97,61],[0,0,0,248,11,128,2,16,0,0,5,17,12,0,0,65,0,0,0,0,8,8,0,75,0,0,0,0,12,11,192,25],[0,0,5,65,8,160,1,151,0,0,0,0,8,200,1,159,0,0,0,0,0,137,4,53,0,0,0,64,8,0,4,61],[0,8,0,64,0,112,0,146,0,0,0,8,9,16,3,96,0,0,0,0,9,9,4,59,0,0,0,128,10,144,0,140],[0,0,11,189,0,0,65,61,0,0,0,128,10,144,2,112,0,0,5,66,11,144,0,156,0,0,0,0,10,9,160,25],[0,0,5,66,11,144,0,156,0,0,0,0,11,0,0,25,0,0,0,16,11,0,32,57,0,0,0,8,12,176,1,191],[0,0,5,16,13,160,0,156,0,0,0,0,12,11,160,25,0,0,0,64,11,160,2,112,0,0,5,16,13,160,0,156],[0,0,0,0,11,10,160,25,0,0,0,4,13,192,1,191,0,0,5,8,10,176,0,156,0,0,0,0,13,12,160,25],[0,0,0,32,12,176,2,112,0,0,5,8,10,176,0,156,0,0,0,0,12,11,160,25,0,0,0,2,10,208,1,191],[0,0,255,255,11,192,0,140,0,0,0,0,10,13,160,25,0,0,0,16,11,192,2,112,0,0,0,0,11,12,160,25],[0,0,0,255,11,176,0,140,0,0,0,1,10,160,32,57,0,0,0,32,11,0,0,138,0,0,0,65,12,160,0,57],[0,0,0,0,11,188,1,111,0,0,0,0,11,184,0,25,0,0,0,0,12,139,0,75,0,0,0,0,12,0,0,25],[0,0,0,1,12,0,64,57,0,0,5,16,13,176,0,156,0,0,19,58,0,0,33,61,0,0,0,1,12,192,1,144],[0,0,19,58,0,0,193,61,0,0,0,64,0,176,4,63,0,0,0,2,11,160,0,57,0,0,0,0,11,184,4,54],[0,0,0,33,12,160,0,57,0,0,0,5,12,192,2,114,0,0,11,25,0,0,97,61,0,0,0,0,13,33,3,79],[0,0,0,0,14,0,0,25,0,0,0,5,15,224,2,16,0,0,0,0,7,251,0,25,0,0,0,0,15,253,3,79],[0,0,0,0,15,15,4,59,0,0,0,0,0,247,4,53,0,0,0,1,14,224,0,57,0,0,0,0,7,206,0,75],[0,0,11,17,0,0,65,61,0,0,0,0,7,0,0,75,0,0,11,27,0,0,97,61,0,0,0,0,7,8,4,51],[0,0,0,0,7,7,0,75,0,0,9,198,0,0,97,61,0,0,0,0,7,11,4,51,0,0,5,65,7,112,1,151],[0,0,0,248,12,160,2,16,0,0,0,0,7,124,1,159,0,0,5,67,7,112,0,65,0,0,0,0,0,123,4,53],[0,0,0,3,7,160,2,16,0,0,0,248,7,112,0,137,0,0,0,0,9,121,1,207,0,0,0,255,7,112,0,140],[0,0,0,0,9,0,32,25,0,0,0,33,7,128,0,57,0,0,0,0,0,151,4,53,0,0,11,206,0,0,1,61],[0,0,0,4,6,0,0,41,0,0,5,64,6,96,0,156,0,0,19,58,0,0,33,61,0,0,0,4,7,0,0,41],[0,0,0,64,6,112,0,57,0,0,0,64,0,96,4,63,0,0,0,1,6,0,0,58,0,0,0,0,6,103,4,54],[0,0,0,0,7,5,4,59,0,0,0,0,0,118,4,53,0,0,9,198,0,0,97,61,0,0,0,248,8,32,2,16],[0,0,5,17,9,0,0,65,0,0,0,0,2,2,0,75,0,0,0,0,9,8,192,25,0,0,5,65,2,112,1,151],[0,0,0,0,2,146,1,159,0,0,0,0,0,38,4,53,0,0,0,9,6,64,0,106,0,0,0,160,1,16,0,57],[0,0,0,0,2,19,3,79,0,0,0,0,2,2,4,59,0,0,0,31,6,96,0,138,0,0,5,17,7,96,1,151],[0,0,5,17,8,32,1,151,0,0,5,17,9,0,0,65,0,0,0,0,10,120,0,75,0,0,0,0,10,0,0,25],[0,0,0,0,10,9,64,25,0,0,0,0,7,120,1,63,0,0,0,0,8,98,0,75,0,0,0,0,9,0,64,25],[0,0,5,17,7,112,0,156,0,0,0,0,10,9,192,25,0,0,0,0,7,10,0,75,0,0,1,57,0,0,193,61],[0,0,0,9,8,32,0,41,0,0,0,0,7,131,3,79,0,0,0,0,7,7,4,59,0,0,5,16,9,112,0,156],[0,0,1,57,0,0,33,61,0,0,0,0,9,116,0,73,0,0,0,32,8,128,0,57,0,0,5,17,10,0,0,65],[0,0,0,0,11,152,0,75,0,0,0,0,11,0,0,25,0,0,0,0,11,10,32,25,0,0,5,17,9,144,1,151],[0,0,5,17,12,128,1,151,0,0,0,0,13,156,0,75,0,0,0,0,10,0,128,25,0,0,0,0,9,156,1,63],[0,0,5,17,9,144,0,156,0,0,0,0,10,11,192,25,0,0,0,0,9,10,0,75,0,0,1,57,0,0,193,61],[0,0,0,1,9,112,0,140,0,0,14,78,0,0,193,61,0,0,0,0,5,131,3,79,0,0,0,0,5,5,4,59],[0,0,0,1,7,0,0,138,0,0,5,17,8,0,0,65,0,0,0,0,7,117,0,75,0,0,0,0,7,0,0,25],[0,0,0,0,7,8,32,25,0,0,5,17,5,80,1,151,0,0,5,17,9,80,0,156,0,0,0,0,8,0,128,25],[0,0,5,17,5,80,1,103,0,0,5,17,5,80,0,156,0,0,0,0,8,7,192,25,0,3,0,96,0,0,0,61],[0,0,0,0,5,8,0,75,0,0,14,136,0,0,193,61,0,0,0,64,5,0,4,61,0,3,0,0,0,5,0,29],[0,0,5,64,5,80,0,156,0,0,19,58,0,0,33,61,0,0,0,3,8,0,0,41,0,0,0,64,5,128,0,57],[0,0,0,64,0,80,4,63,0,0,0,32,5,128,0,57,0,0,5,67,7,0,0,65,0,0,0,0,0,117,4,53],[0,0,0,1,5,0,0,57,0,0,0,0,0,88,4,53,0,0,14,136,0,0,1,61,0,0,0,5,1,0,0,41],[0,0,0,0,1,1,4,51,0,0,0,0,2,1,0,75,0,0,11,170,0,0,97,61,0,0,5,17,2,0,0,65],[0,0,0,32,3,16,0,140,0,0,0,0,3,0,0,25,0,0,0,0,3,2,64,25,0,0,5,17,1,16,1,151],[0,0,0,0,4,1,0,75,0,0,0,0,2,0,160,25,0,0,5,17,1,16,0,156,0,0,0,0,2,3,192,25],[0,0,0,0,1,2,0,75,0,0,1,57,0,0,193,61,0,0,0,10,1,0,0,41,0,0,0,0,1,1,4,51],[0,0,0,0,2,1,0,75,0,0,0,0,2,0,0,25,0,0,0,1,2,0,192,57,0,0,0,0,2,33,0,75],[0,0,1,57,0,0,193,61,0,0,0,0,1,1,0,75,0,0,11,170,0,0,193,61,0,0,0,64,1,0,4,61],[0,0,0,100,2,16,0,57,0,0,5,49,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,68,2,16,0,57],[0,0,5,50,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,42,3,0,0,57],[0,0,0,0,0,50,4,53,0,0,5,22,2,0,0,65,0,0,0,0,0,33,4,53,0,0,0,4,2,16,0,57],[0,0,0,4,3,0,0,41,0,0,1,28,0,0,1,61,0,0,0,64,3,0,4,61,0,0,0,36,1,48,0,57],[0,0,0,7,2,0,0,41,0,0,0,0,0,33,4,53,0,0,5,38,1,0,0,65,0,0,0,0,0,19,4,53],[0,10,0,0,0,3,0,29,0,0,0,4,1,48,0,57,0,0,0,6,2,0,0,41,0,0,0,0,0,33,4,53],[0,0,0,0,1,0,4,20,0,0,0,9,2,0,0,41,0,0,0,4,2,32,0,140,0,0,12,49,0,0,193,61],[0,0,0,1,3,0,0,49,0,0,0,32,1,48,0,140,0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57],[0,0,12,99,0,0,1,61,0,0,5,64,7,128,0,156,0,0,19,58,0,0,33,61,0,0,0,64,7,128,0,57],[0,0,0,64,0,112,4,63,0,0,0,0,7,33,3,79,0,0,0,1,10,0,0,58,0,0,0,0,10,168,4,54],[0,0,0,0,11,7,4,59,0,0,0,0,0,186,4,53,0,0,9,198,0,0,97,61,0,0,0,248,7,144,2,16],[0,0,5,17,12,0,0,65,0,0,0,0,9,9,0,75,0,0,0,0,12,7,192,25,0,0,5,65,7,176,1,151],[0,0,0,0,7,199,1,159,0,0,0,0,0,122,4,53,0,0,0,64,10,0,4,61,0,0,5,64,7,160,0,156],[0,0,19,58,0,0,33,61,0,0,0,8,12,0,0,41,0,0,0,32,7,192,0,138,0,0,0,0,7,113,3,79],[0,0,0,0,7,7,4,59,0,0,0,64,9,160,0,57,0,0,0,64,0,144,4,63,0,0,0,32,9,160,0,57],[0,0,5,68,11,0,0,65,0,0,0,0,0,185,4,53,0,0,0,21,9,0,0,57,0,0,0,0,0,154,4,53],[0,0,0,96,7,112,2,16,0,0,0,33,9,160,0,57,0,0,0,0,0,121,4,53,0,0,0,192,7,192,0,57],[0,0,0,0,7,113,3,79,0,0,0,64,9,0,4,61,0,0,0,0,7,7,4,59,0,8,0,0,0,7,0,29],[0,0,0,128,11,112,0,140,0,0,13,116,0,0,65,61,0,0,0,8,7,0,0,41,0,0,0,128,11,112,2,112],[0,0,5,66,12,112,0,156,0,0,0,0,11,7,160,25,0,0,5,66,12,112,0,156,0,0,0,0,12,0,0,25],[0,0,0,16,12,0,32,57,0,0,0,8,13,192,1,191,0,0,5,16,14,176,0,156,0,0,0,0,13,12,160,25],[0,0,0,64,12,176,2,112,0,0,5,16,14,176,0,156,0,0,0,0,12,11,160,25,0,0,0,4,14,208,1,191],[0,0,5,8,11,192,0,156,0,0,0,0,14,13,160,25,0,0,0,32,13,192,2,112,0,0,5,8,11,192,0,156],[0,0,0,0,13,12,160,25,0,0,0,2,7,224,1,191,0,0,255,255,12,208,0,140,0,0,0,0,7,14,160,25],[0,0,0,16,12,208,2,112,0,0,0,0,12,13,160,25,0,0,0,255,12,192,0,140,0,0,0,1,7,112,32,57],[0,0,0,32,12,0,0,138,0,6,0,0,0,7,0,29,0,0,0,65,13,112,0,57,0,0,0,0,12,205,1,111],[0,0,0,0,12,201,0,25,0,0,0,0,13,156,0,75,0,0,0,0,13,0,0,25,0,0,0,1,13,0,64,57],[0,0,5,16,14,192,0,156,0,0,19,58,0,0,33,61,0,0,0,1,13,208,1,144,0,0,19,58,0,0,193,61],[0,0,0,64,0,192,4,63,0,0,0,6,7,0,0,41,0,0,0,2,12,112,0,57,0,0,0,0,12,201,4,54],[0,0,0,33,13,112,0,57,0,0,0,5,13,208,2,114,0,0,12,29,0,0,97,61,0,0,0,0,14,33,3,79],[0,0,0,0,15,0,0,25,0,0,0,5,7,240,2,16,0,0,0,0,11,124,0,25,0,0,0,0,7,126,3,79],[0,0,0,0,7,7,4,59,0,0,0,0,0,123,4,53,0,0,0,1,15,240,0,57,0,0,0,0,7,223,0,75],[0,0,12,21,0,0,65,61,0,0,0,0,7,0,0,75,0,0,12,31,0,0,97,61,0,0,0,0,7,9,4,51],[0,0,0,0,7,7,0,75,0,0,9,198,0,0,97,61,0,0,0,0,7,12,4,51,0,0,5,65,7,112,1,151],[0,0,0,6,13,0,0,41,0,0,0,248,11,208,2,16,0,0,0,0,7,123,1,159,0,0,5,67,7,112,0,65],[0,0,0,0,0,124,4,53,0,0,0,3,7,208,2,16,0,0,0,248,7,112,0,137,0,0,0,8,11,112,1,239],[0,0,0,255,7,112,0,140,0,0,0,0,11,0,32,25,0,0,0,33,7,144,0,57,0,0,0,0,0,183,4,53],[0,0,13,134,0,0,1,61,0,0,5,8,2,0,0,65,0,0,5,8,3,16,0,156,0,0,0,0,1,2,128,25],[0,0,0,10,4,0,0,41,0,0,5,8,3,64,0,156,0,0,0,0,2,4,64,25,0,0,0,64,2,32,2,16],[0,0,0,192,1,16,2,16,0,0,0,0,1,33,1,159,0,0,5,44,1,16,1,199,0,0,0,9,2,0,0,41],[20,28,20,13,0,0,4,15,0,0,0,10,10,0,0,41,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112],[0,0,5,8,3,48,1,151,0,0,0,32,4,48,0,140,0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57],[0,0,0,31,5,64,1,143,0,0,0,5,6,64,2,114,0,0,12,80,0,0,97,61,0,0,0,0,7,0,0,25],[0,0,0,5,8,112,2,16,0,0,0,0,9,138,0,25,0,0,0,0,8,129,3,79,0,0,0,0,8,8,4,59],[0,0,0,0,0,137,4,53,0,0,0,1,7,112,0,57,0,0,0,0,8,103,0,75,0,0,12,72,0,0,65,61],[0,0,0,0,7,5,0,75,0,0,12,95,0,0,97,61,0,0,0,5,6,96,2,16,0,0,0,0,7,97,3,79],[0,0,0,10,6,96,0,41,0,0,0,3,5,80,2,16,0,0,0,0,8,6,4,51,0,0,0,0,8,88,1,207],[0,0,0,0,8,88,2,47,0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137,0,0,0,0,7,87,2,47],[0,0,0,0,5,87,1,207,0,0,0,0,5,133,1,159,0,0,0,0,0,86,4,53,0,1,0,0,0,3,0,31],[0,19,0,0,0,1,3,85,0,0,0,1,2,32,1,144,0,0,13,87,0,0,97,61,0,0,0,31,1,64,0,57],[0,0,0,96,2,16,1,143,0,0,0,10,1,32,0,41,0,0,0,0,2,33,0,75,0,0,0,0,2,0,0,25],[0,0,0,1,2,0,64,57,0,0,5,16,4,16,0,156,0,0,19,58,0,0,33,61,0,0,0,1,2,32,1,144],[0,0,19,58,0,0,193,61,0,0,0,64,0,16,4,63,0,0,0,32,2,48,0,140,0,0,1,57,0,0,65,61],[0,0,0,68,4,16,0,57,0,0,0,36,5,16,0,57,0,0,0,10,2,0,0,41,0,0,0,0,2,2,4,51],[0,0,0,0,2,2,0,75,0,0,14,66,0,0,193,61,0,0,0,32,2,16,0,57,0,0,5,40,6,0,0,65],[0,0,0,0,0,98,4,53,0,0,0,7,6,0,0,41,0,0,0,0,0,101,4,53,0,0,0,8,5,0,0,41],[0,0,0,0,0,84,4,53,0,0,0,1,4,0,0,41,0,0,0,0,0,65,4,53,0,0,5,47,4,16,0,156],[0,0,19,58,0,0,33,61,0,0,0,128,4,16,0,57,0,10,0,0,0,4,0,29,0,0,0,64,0,64,4,63],[0,0,5,48,4,16,0,156,0,0,19,58,0,0,33,61,0,0,0,192,4,16,0,57,0,0,0,64,0,64,4,63],[0,0,0,4,4,0,0,41,0,0,0,10,5,0,0,41,0,0,0,0,0,69,4,53,0,0,0,160,5,16,0,57],[0,0,5,41,4,0,0,65,0,7,0,0,0,5,0,29,0,0,0,0,0,69,4,53,0,0,0,0,4,1,4,51],[0,0,0,0,1,0,4,20,0,0,0,9,5,0,0,41,0,0,0,4,5,80,0,140,0,0,15,63,0,0,193,61],[0,0,0,1,2,0,0,57,0,0,5,16,1,48,0,156,0,0,19,58,0,0,33,61,0,0,15,85,0,0,1,61],[0,0,5,64,6,128,0,156,0,0,19,58,0,0,33,61,0,0,0,64,6,128,0,57,0,0,0,64,0,96,4,63],[0,0,0,0,6,33,3,79,0,0,0,1,10,0,0,58,0,0,0,0,10,168,4,54,0,0,0,0,11,6,4,59],[0,0,0,0,0,186,4,53,0,0,9,198,0,0,97,61,0,0,0,8,13,0,0,41,0,0,0,248,6,208,2,16],[0,0,5,17,12,0,0,65,0,0,0,0,13,13,0,75,0,0,0,0,12,6,192,25,0,0,5,65,6,176,1,151],[0,0,0,0,6,198,1,159,0,0,0,0,0,106,4,53,0,0,0,64,6,0,4,61,0,0,0,32,11,96,0,57],[0,0,0,0,10,3,4,51,0,0,0,0,12,10,0,75,0,0,12,183,0,0,97,61,0,0,0,0,12,0,0,25],[0,0,0,0,13,188,0,25,0,0,0,32,12,192,0,57,0,0,0,0,14,60,0,25,0,0,0,0,14,14,4,51],[0,0,0,0,0,237,4,53,0,0,0,0,13,172,0,75,0,0,12,176,0,0,65,61,0,0,0,0,3,186,0,25],[0,0,0,0,0,3,4,53,0,0,0,0,3,106,0,25,0,0,0,32,11,48,0,57,0,0,0,0,10,4,4,51],[0,0,0,0,12,10,0,75,0,0,12,198,0,0,97,61,0,0,0,0,12,0,0,25,0,0,0,0,13,188,0,25],[0,0,0,32,12,192,0,57,0,0,0,0,14,76,0,25,0,0,0,0,14,14,4,51,0,0,0,0,0,237,4,53],[0,0,0,0,13,172,0,75,0,0,12,191,0,0,65,61,0,0,0,0,4,186,0,25,0,0,0,0,0,4,4,53],[0,0,0,0,3,58,0,25,0,0,0,32,10,48,0,57,0,0,0,0,4,5,4,51,0,0,0,0,11,4,0,75],[0,0,12,213,0,0,97,61,0,0,0,0,11,0,0,25,0,0,0,0,12,171,0,25,0,0,0,32,11,176,0,57],[0,0,0,0,13,91,0,25,0,0,0,0,13,13,4,51,0,0,0,0,0,220,4,53,0,0,0,0,12,75,0,75],[0,0,12,206,0,0,65,61,0,0,0,0,5,164,0,25,0,0,0,0,0,5,4,53,0,0,0,0,3,52,0,25],[0,0,0,32,5,48,0,57,0,0,0,0,4,7,4,51,0,0,0,0,10,4,0,75,0,0,12,228,0,0,97,61],[0,0,0,0,10,0,0,25,0,0,0,0,11,90,0,25,0,0,0,32,10,160,0,57,0,0,0,0,12,122,0,25],[0,0,0,0,12,12,4,51,0,0,0,0,0,203,4,53,0,0,0,0,11,74,0,75,0,0,12,221,0,0,65,61],[0,0,0,0,5,84,0,25,0,0,0,0,0,5,4,53,0,0,0,0,3,52,0,25,0,0,0,32,5,48,0,57],[0,0,0,0,4,9,4,51,0,0,0,0,7,4,0,75,0,0,12,243,0,0,97,61,0,0,0,0,7,0,0,25],[0,0,0,0,10,87,0,25,0,0,0,32,7,112,0,57,0,0,0,0,11,151,0,25,0,0,0,0,11,11,4,51],[0,0,0,0,0,186,4,53,0,0,0,0,10,71,0,75,0,0,12,236,0,0,65,61,0,0,0,0,5,84,0,25],[0,0,0,0,0,5,4,53,0,0,0,0,3,52,0,25,0,0,0,32,5,48,0,57,0,0,0,0,4,8,4,51],[0,0,0,0,7,4,0,75,0,0,13,2,0,0,97,61,0,0,0,0,7,0,0,25,0,0,0,0,9,87,0,25],[0,0,0,32,7,112,0,57,0,0,0,0,10,135,0,25,0,0,0,0,10,10,4,51,0,0,0,0,0,169,4,53],[0,0,0,0,9,71,0,75,0,0,12,251,0,0,65,61,0,0,0,0,5,84,0,25,0,0,0,0,0,5,4,53],[0,0,0,0,3,99,0,73,0,0,0,0,3,52,0,25,0,0,0,0,0,54,4,53,0,0,0,63,4,48,0,57],[0,0,0,32,3,0,0,138,0,0,0,0,4,52,1,111,0,0,0,0,7,100,0,25,0,0,0,0,4,71,0,75],[0,0,0,0,4,0,0,25,0,0,0,1,4,0,64,57,0,0,5,16,5,112,0,156,0,0,19,58,0,0,33,61],[0,0,0,1,4,64,1,144,0,0,19,58,0,0,193,61,0,0,0,64,0,112,4,63,0,0,0,10,5,0,0,41],[0,0,1,196,4,80,0,57,0,0,0,0,4,65,3,79,0,0,0,0,5,82,0,73,0,0,0,35,5,80,0,138],[0,0,0,0,4,4,4,59,0,0,5,17,8,0,0,65,0,0,0,0,9,84,0,75,0,0,0,0,9,0,0,25],[0,0,0,0,9,8,128,25,0,0,5,17,5,80,1,151,0,0,5,17,10,64,1,151,0,0,0,0,11,90,0,75],[0,0,0,0,8,0,128,25,0,0,0,0,5,90,1,63,0,0,5,17,5,80,0,156,0,0,0,0,8,9,192,25],[0,0,0,0,5,8,0,75,0,0,1,57,0,0,193,61,0,0,0,9,5,64,0,41,0,0,0,0,4,81,3,79],[0,0,0,0,4,4,4,59,0,0,5,16,8,64,0,156,0,0,1,57,0,0,33,61,0,0,0,0,8,66,0,73],[0,0,0,32,5,80,0,57,0,0,5,17,9,0,0,65,0,0,0,0,10,133,0,75,0,0,0,0,10,0,0,25],[0,0,0,0,10,9,32,25,0,0,5,17,8,128,1,151,0,0,5,17,11,80,1,151,0,0,0,0,12,139,0,75],[0,0,0,0,9,0,128,25,0,0,0,0,8,139,1,63,0,0,5,17,8,128,0,156,0,0,0,0,9,10,192,25],[0,0,0,0,8,9,0,75,0,0,1,57,0,0,193,61,0,0,0,1,8,64,0,140,0,0,15,161,0,0,193,61],[0,0,0,0,8,81,3,79,0,0,0,0,8,8,4,59,0,0,0,1,9,0,0,138,0,0,5,17,10,0,0,65],[0,0,0,0,9,152,0,75,0,0,0,0,9,0,0,25,0,0,0,0,9,10,32,25,0,0,5,17,8,128,1,151],[0,0,5,17,11,128,0,156,0,0,0,0,10,0,128,25,0,0,5,17,8,128,1,103,0,0,5,17,8,128,0,156],[0,0,0,0,10,9,192,25,0,0,0,96,8,0,0,57,0,0,0,0,9,10,0,75,0,0,16,59,0,0,193,61],[0,0,5,64,8,112,0,156,0,0,19,58,0,0,33,61,0,0,0,64,8,112,0,57,0,0,0,64,0,128,4,63],[0,0,0,32,8,112,0,57,0,0,5,67,9,0,0,65,0,0,0,0,0,152,4,53,0,0,0,1,8,0,0,57],[0,0,0,0,0,135,4,53,0,0,0,0,8,7,0,25,0,0,16,59,0,0,1,61,0,0,0,64,2,0,4,61],[0,0,0,31,4,48,1,143,0,0,0,5,5,48,2,114,0,0,13,100,0,0,97,61,0,0,0,0,6,0,0,25],[0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59],[0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,13,92,0,0,65,61],[0,0,0,0,6,4,0,75,0,0,13,115,0,0,97,61,0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79],[0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207],[0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47],[0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,6,130,0,0,1,61],[0,0,5,64,7,144,0,156,0,0,19,58,0,0,33,61,0,0,0,64,7,144,0,57,0,0,0,64,0,112,4,63],[0,0,0,0,7,33,3,79,0,0,0,1,11,0,0,58,0,0,0,0,11,185,4,54,0,0,0,0,12,7,4,59],[0,0,0,0,0,203,4,53,0,0,9,198,0,0,97,61,0,0,0,8,14,0,0,41,0,0,0,248,7,224,2,16],[0,0,5,17,13,0,0,65,0,0,0,0,14,14,0,75,0,0,0,0,13,7,192,25,0,0,5,65,7,192,1,151],[0,0,0,0,7,215,1,159,0,0,0,0,0,123,4,53,0,0,0,64,7,0,4,61,0,0,0,32,12,112,0,57],[0,0,0,0,11,3,4,51,0,0,0,0,13,11,0,75,0,0,13,147,0,0,97,61,0,0,0,0,13,0,0,25],[0,0,0,0,14,205,0,25,0,0,0,32,13,208,0,57,0,0,0,0,15,61,0,25,0,0,0,0,15,15,4,51],[0,0,0,0,0,254,4,53,0,0,0,0,14,189,0,75,0,0,13,140,0,0,65,61,0,0,0,0,3,203,0,25],[0,0,0,0,0,3,4,53,0,0,0,0,3,123,0,25,0,0,0,32,12,48,0,57,0,0,0,0,11,4,4,51],[0,0,0,0,13,11,0,75,0,0,13,162,0,0,97,61,0,0,0,0,13,0,0,25,0,0,0,0,14,205,0,25],[0,0,0,32,13,208,0,57,0,0,0,0,15,77,0,25,0,0,0,0,15,15,4,51,0,0,0,0,0,254,4,53],[0,0,0,0,14,189,0,75,0,0,13,155,0,0,65,61,0,0,0,0,4,203,0,25,0,0,0,0,0,4,4,53],[0,0,0,0,3,59,0,25,0,0,0,32,11,48,0,57,0,0,0,0,4,5,4,51,0,0,0,0,12,4,0,75],[0,0,13,177,0,0,97,61,0,0,0,0,12,0,0,25,0,0,0,0,13,188,0,25,0,0,0,32,12,192,0,57],[0,0,0,0,14,92,0,25,0,0,0,0,14,14,4,51,0,0,0,0,0,237,4,53,0,0,0,0,13,76,0,75],[0,0,13,170,0,0,65,61,0,0,0,0,5,180,0,25,0,0,0,0,0,5,4,53,0,0,0,0,3,52,0,25],[0,0,0,32,5,48,0,57,0,0,0,0,4,6,4,51,0,0,0,0,11,4,0,75,0,0,13,192,0,0,97,61],[0,0,0,0,11,0,0,25,0,0,0,0,12,91,0,25,0,0,0,32,11,176,0,57,0,0,0,0,13,107,0,25],[0,0,0,0,13,13,4,51,0,0,0,0,0,220,4,53,0,0,0,0,12,75,0,75,0,0,13,185,0,0,65,61],[0,0,0,0,5,84,0,25,0,0,0,0,0,5,4,53,0,0,0,0,3,52,0,25,0,0,0,32,5,48,0,57],[0,0,0,0,4,8,4,51,0,0,0,0,6,4,0,75,0,0,13,207,0,0,97,61,0,0,0,0,6,0,0,25],[0,0,0,0,11,86,0,25,0,0,0,32,6,96,0,57,0,0,0,0,12,134,0,25,0,0,0,0,12,12,4,51],[0,0,0,0,0,203,4,53,0,0,0,0,11,70,0,75,0,0,13,200,0,0,65,61,0,0,0,0,5,84,0,25],[0,0,0,0,0,5,4,53,0,0,0,0,3,52,0,25,0,0,0,32,5,48,0,57,0,0,0,0,4,10,4,51],[0,0,0,0,6,4,0,75,0,0,13,222,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,0,8,86,0,25],[0,0,0,32,6,96,0,57,0,0,0,0,11,166,0,25,0,0,0,0,11,11,4,51,0,0,0,0,0,184,4,53],[0,0,0,0,8,70,0,75,0,0,13,215,0,0,65,61,0,0,0,0,5,84,0,25,0,0,0,0,0,5,4,53],[0,0,0,0,3,52,0,25,0,0,0,32,5,48,0,57,0,0,0,0,4,9,4,51,0,0,0,0,6,4,0,75],[0,0,13,237,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,0,8,86,0,25,0,0,0,32,6,96,0,57],[0,0,0,0,10,150,0,25,0,0,0,0,10,10,4,51,0,0,0,0,0,168,4,53,0,0,0,0,8,70,0,75],[0,0,13,230,0,0,65,61,0,0,0,0,5,84,0,25,0,0,0,0,0,5,4,53,0,0,0,0,3,115,0,73],[0,0,0,0,3,52,0,25,0,0,0,0,0,55,4,53,0,0,0,63,4,48,0,57,0,0,0,32,3,0,0,138],[0,0,0,0,4,52,1,111,0,0,0,0,6,116,0,25,0,0,0,0,4,70,0,75,0,0,0,0,4,0,0,25],[0,0,0,1,4,0,64,57,0,0,5,16,5,96,0,156,0,0,19,58,0,0,33,61,0,0,0,1,4,64,1,144],[0,0,19,58,0,0,193,61,0,0,0,64,0,96,4,63,0,0,0,10,5,0,0,41,0,0,1,196,4,80,0,57],[0,0,0,0,4,65,3,79,0,0,0,0,5,82,0,73,0,0,0,35,5,80,0,138,0,0,0,0,4,4,4,59],[0,0,5,17,8,0,0,65,0,0,0,0,9,84,0,75,0,0,0,0,9,0,0,25,0,0,0,0,9,8,128,25],[0,0,5,17,5,80,1,151,0,0,5,17,10,64,1,151,0,0,0,0,11,90,0,75,0,0,0,0,8,0,128,25],[0,0,0,0,5,90,1,63,0,0,5,17,5,80,0,156,0,0,0,0,8,9,192,25,0,0,0,0,5,8,0,75],[0,0,1,57,0,0,193,61,0,0,0,9,5,64,0,41,0,0,0,0,4,81,3,79,0,0,0,0,4,4,4,59],[0,0,5,16,8,64,0,156,0,0,1,57,0,0,33,61,0,0,0,0,8,66,0,73,0,0,0,32,5,80,0,57],[0,0,5,17,9,0,0,65,0,0,0,0,10,133,0,75,0,0,0,0,10,0,0,25,0,0,0,0,10,9,32,25],[0,0,5,17,8,128,1,151,0,0,5,17,11,80,1,151,0,0,0,0,12,139,0,75,0,0,0,0,9,0,128,25],[0,0,0,0,8,139,1,63,0,0,5,17,8,128,0,156,0,0,0,0,9,10,192,25,0,0,0,0,8,9,0,75],[0,0,1,57,0,0,193,61,0,0,0,1,8,64,0,140,0,0,17,74,0,0,193,61,0,0,0,0,8,81,3,79],[0,0,0,0,8,8,4,59,0,0,0,1,9,0,0,138,0,0,5,17,10,0,0,65,0,0,0,0,9,152,0,75],[0,0,0,0,9,0,0,25,0,0,0,0,9,10,32,25,0,0,5,17,8,128,1,151,0,0,5,17,11,128,0,156],[0,0,0,0,10,0,128,25,0,0,5,17,8,128,1,103,0,0,5,17,8,128,0,156,0,0,0,0,10,9,192,25],[0,0,0,96,8,0,0,57,0,0,0,0,9,10,0,75,0,0,19,55,0,0,193,61,0,0,5,64,8,96,0,156],[0,0,19,58,0,0,33,61,0,0,0,64,8,96,0,57,0,0,0,64,0,128,4,63,0,0,0,32,8,96,0,57],[0,0,5,67,9,0,0,65,0,0,0,0,0,152,4,53,0,0,0,1,8,0,0,57,0,0,0,0,0,134,4,53],[0,0,0,0,8,6,0,25,0,0,19,55,0,0,1,61,0,0,5,22,2,0,0,65,0,0,0,0,0,33,4,53],[0,0,0,4,2,16,0,57,0,0,0,4,3,0,0,41,0,0,0,0,0,50,4,53,0,0,0,54,2,0,0,57],[0,0,0,0,0,37,4,53,0,0,5,45,2,0,0,65,0,0,0,0,0,36,4,53,0,0,0,100,2,16,0,57],[0,0,5,46,3,0,0,65,0,0,1,28,0,0,1,61,0,0,0,64,8,0,4,61,0,3,0,0,0,8,0,29],[0,0,0,56,8,112,0,140,0,0,14,120,0,0,65,61,0,0,0,32,9,112,2,112,0,0,5,8,8,112,0,156],[0,0,0,0,9,7,160,25,0,0,5,8,8,112,0,156,0,0,0,0,10,0,0,25,0,0,0,4,10,0,32,57],[0,0,0,2,8,160,1,191,0,0,255,255,11,144,0,140,0,0,0,0,8,10,160,25,0,0,0,16,10,144,2,112],[0,0,0,0,10,9,160,25,0,0,0,255,9,160,0,140,0,0,0,0,9,0,0,25,0,0,0,1,9,0,32,57],[0,0,0,3,10,0,0,41,0,0,5,64,10,160,0,156,0,0,19,58,0,0,33,61,0,0,0,0,8,152,1,159],[0,0,0,3,10,0,0,41,0,0,0,64,9,160,0,57,0,0,0,64,0,144,4,63,0,0,0,2,9,128,0,58],[0,0,0,0,9,154,4,54,0,0,0,0,5,5,4,59,0,0,0,0,0,89,4,53,0,0,9,198,0,0,97,61],[0,0,5,65,5,80,1,151,0,0,0,248,10,128,2,16,0,0,0,0,5,90,1,159,0,0,5,69,5,80,1,199],[0,0,0,0,0,89,4,53,0,0,0,3,5,128,2,16,0,0,0,248,5,80,1,95,0,0,0,0,5,87,1,207],[0,0,0,3,7,0,0,41,0,0,0,33,7,112,0,57,0,0,0,0,0,87,4,53,0,0,14,136,0,0,1,61],[0,0,0,3,8,0,0,41,0,0,5,64,8,128,0,156,0,0,19,58,0,0,33,61,0,0,0,3,9,0,0,41],[0,0,0,64,8,144,0,57,0,0,0,64,0,128,4,63,0,0,0,1,8,0,0,58,0,0,0,0,8,137,4,54],[0,0,0,0,5,5,4,59,0,0,0,0,0,88,4,53,0,0,9,198,0,0,97,61,0,0,0,248,7,112,2,16],[0,0,5,65,5,80,1,151,0,0,0,0,5,117,1,159,0,0,5,17,5,80,1,103,0,0,0,0,0,88,4,53],[0,0,0,128,1,16,0,138,0,0,0,0,5,19,3,79,0,0,0,96,1,0,0,57,0,0,0,0,5,5,4,59],[0,0,0,0,5,5,0,75,0,0,14,232,0,0,193,61,0,0,5,17,5,0,0,65,0,0,0,0,7,98,0,75],[0,0,0,0,7,0,0,25,0,0,0,0,7,5,128,25,0,0,5,17,6,96,1,151,0,0,5,17,8,32,1,151],[0,0,0,0,9,104,0,75,0,0,0,0,5,0,128,25,0,0,0,0,6,104,1,63,0,0,5,17,6,96,0,156],[0,0,0,0,5,7,192,25,0,0,0,0,5,5,0,75,0,0,1,57,0,0,193,61,0,0,0,8,5,0,0,41],[0,0,0,0,6,5,4,51,0,0,0,6,5,0,0,41,0,0,0,0,7,5,4,51,0,0,0,5,5,0,0,41],[0,0,0,0,8,5,4,51,0,0,0,4,5,0,0,41,0,0,0,0,9,5,4,51,0,0,0,3,5,0,0,41],[0,0,0,0,10,5,4,51,0,0,0,9,5,32,0,41,0,0,0,0,2,83,3,79,0,0,0,0,2,2,4,59],[0,0,5,16,11,32,0,156,0,0,1,57,0,0,33,61,0,0,0,0,11,36,0,73,0,0,0,32,5,80,0,57],[0,0,5,17,12,0,0,65,0,0,0,0,13,181,0,75,0,0,0,0,13,0,0,25,0,0,0,0,13,12,32,25],[0,0,5,17,11,176,1,151,0,0,5,17,14,80,1,151,0,0,0,0,15,190,0,75,0,0,0,0,12,0,128,25],[0,0,0,0,11,190,1,63,0,0,5,17,11,176,0,156,0,0,0,0,12,13,192,25,0,0,0,0,11,12,0,75],[0,0,1,57,0,0,193,61,0,0,0,0,6,103,0,25,0,0,0,0,6,134,0,25,0,0,0,0,6,150,0,25],[0,0,0,0,6,166,0,25,0,0,0,0,6,38,0,25,0,0,0,0,7,1,4,51,0,0,0,0,6,118,0,25],[0,0,0,64,7,0,4,61,0,0,5,16,6,96,1,151,0,0,0,56,8,96,0,140,0,0,16,122,0,0,65,61],[0,0,0,32,9,96,2,112,0,0,5,8,8,96,0,156,0,0,0,0,9,6,160,25,0,0,5,8,8,96,0,156],[0,0,0,0,10,0,0,25,0,0,0,4,10,0,32,57,0,0,0,2,8,160,1,191,0,0,255,255,11,144,0,140],[0,0,0,0,8,10,160,25,0,0,0,16,10,144,2,112,0,0,0,0,10,9,160,25,0,0,0,255,9,160,0,140],[0,0,0,0,9,0,0,25,0,0,0,1,9,0,32,57,0,0,5,64,10,112,0,156,0,0,19,58,0,0,33,61],[0,0,0,0,8,152,1,159,0,0,0,64,9,112,0,57,0,0,0,64,0,144,4,63,0,0,0,0,9,67,3,79],[0,0,0,2,4,128,0,58,0,0,0,0,4,71,4,54,0,0,0,0,9,9,4,59,0,0,0,0,0,148,4,53],[0,0,9,198,0,0,97,61,0,0,5,65,9,144,1,151,0,0,0,248,10,128,2,16,0,0,0,0,9,154,1,159],[0,0,5,71,9,144,1,199,0,0,0,0,0,148,4,53,0,0,0,3,4,128,2,16,0,0,0,248,4,64,1,95],[0,0,0,0,4,70,1,207,0,0,0,33,6,112,0,57,0,0,0,0,0,70,4,53,0,0,16,137,0,0,1,61],[0,0,5,62,1,0,0,65,0,0,0,0,0,16,4,57,0,0,5,8,1,0,0,65,0,0,0,0,2,0,4,20],[0,0,5,8,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,5,63,1,16,1,199],[0,0,128,11,2,0,0,57,20,28,20,13,0,0,4,15,0,0,0,1,2,32,1,144,0,0,18,65,0,0,97,61],[0,0,0,64,2,0,4,61,0,0,0,0,1,1,4,59,0,0,0,128,3,16,0,140,0,0,15,200,0,0,65,61],[0,0,0,128,3,16,2,112,0,0,5,66,4,16,0,156,0,0,0,0,3,1,160,25,0,0,5,66,4,16,0,156],[0,0,0,0,4,0,0,25,0,0,0,16,4,0,32,57,0,0,0,8,5,64,1,191,0,0,5,16,6,48,0,156],[0,0,0,0,5,4,160,25,0,0,0,64,4,48,2,112,0,0,5,16,6,48,0,156,0,0,0,0,4,3,160,25],[0,0,0,4,3,80,1,191,0,0,5,8,6,64,0,156,0,0,0,0,3,5,160,25,0,0,0,32,6,64,2,112],[0,0,5,8,5,64,0,156,0,0,0,0,6,4,160,25,0,0,0,2,5,48,1,191,0,0,255,255,4,96,0,140],[0,0,0,0,5,3,160,25,0,0,0,16,3,96,2,112,0,0,0,0,3,6,160,25,0,0,0,255,3,48,0,140],[0,0,0,1,5,80,32,57,0,0,0,65,3,80,0,57,0,0,0,2,3,48,1,127,0,0,0,0,3,50,0,25],[0,0,0,0,4,35,0,75,0,0,0,0,4,0,0,25,0,0,0,1,4,0,64,57,0,0,5,16,6,48,0,156],[0,0,19,58,0,0,33,61,0,0,0,1,4,64,1,144,0,0,19,58,0,0,193,61,0,0,0,64,0,48,4,63],[0,0,0,2,3,80,0,57,0,0,0,0,6,50,4,54,0,0,0,18,3,0,3,103,0,0,0,0,4,0,0,49],[0,0,0,33,7,80,0,57,0,0,0,5,7,112,2,114,0,0,15,45,0,0,97,61,0,0,0,0,8,67,3,79],[0,0,0,0,9,0,0,25,0,0,0,5,10,144,2,16,0,0,0,0,11,166,0,25,0,0,0,0,10,168,3,79],[0,0,0,0,10,10,4,59,0,0,0,0,0,171,4,53,0,0,0,1,9,144,0,57,0,0,0,0,10,121,0,75],[0,0,15,37,0,0,65,61,0,0,0,0,7,0,0,75,0,0,15,47,0,0,97,61,0,0,0,0,7,2,4,51],[0,0,0,0,7,7,0,75,0,0,9,198,0,0,97,61,0,0,0,0,7,6,4,51,0,0,5,65,7,112,1,151],[0,0,0,248,8,80,2,16,0,0,0,0,7,120,1,159,0,0,5,67,7,112,0,65,0,0,0,0,0,118,4,53],[0,0,0,3,5,80,2,16,0,0,0,248,5,80,0,137,0,0,0,0,1,81,1,207,0,0,0,255,5,80,0,140],[0,0,0,0,1,0,32,25,0,0,0,33,5,32,0,57,0,0,15,218,0,0,1,61,0,0,5,8,3,0,0,65],[0,0,5,8,5,32,0,156,0,0,0,0,2,3,128,25,0,0,0,64,2,32,2,16,0,0,5,8,5,64,0,156],[0,0,0,0,4,3,128,25,0,0,0,96,4,64,2,16,0,0,0,0,2,36,1,159,0,0,5,8,4,16,0,156],[0,0,0,0,1,3,128,25,0,0,0,192,1,16,2,16,0,0,0,0,1,18,1,159,0,0,0,9,2,0,0,41],[20,28,20,8,0,0,4,15,0,8,0,96,0,0,0,61,0,6,0,128,0,0,0,61,0,0,0,1,2,32,1,143],[0,19,0,0,0,1,3,85,0,0,0,96,1,16,2,112,0,1,5,8,0,16,1,157,0,0,5,8,3,16,1,152],[0,0,15,130,0,0,97,61,0,0,0,63,1,48,0,57,0,0,0,32,4,0,0,138,0,0,0,0,1,65,1,111],[0,0,0,64,4,0,4,61,0,0,0,0,1,20,0,25,0,8,0,0,0,4,0,29,0,0,0,0,4,65,0,75],[0,0,0,0,4,0,0,25,0,0,0,1,4,0,64,57,0,0,5,16,5,16,0,156,0,0,19,58,0,0,33,61],[0,0,0,1,4,64,1,144,0,0,19,58,0,0,193,61,0,0,0,64,0,16,4,63,0,0,0,31,1,48,1,143],[0,0,0,8,4,0,0,41,0,0,0,0,8,52,4,54,0,0,0,19,4,0,3,103,0,0,0,5,3,48,2,114],[0,0,15,114,0,0,97,61,0,0,0,0,5,0,0,25,0,0,0,5,6,80,2,16,0,0,0,0,7,104,0,25],[0,0,0,0,6,100,3,79,0,0,0,0,6,6,4,59,0,0,0,0,0,103,4,53,0,0,0,1,5,80,0,57],[0,0,0,0,6,53,0,75,0,0,15,106,0,0,65,61,0,6,0,0,0,8,0,29,0,0,0,0,5,1,0,75],[0,0,15,130,0,0,97,61,0,0,0,5,3,48,2,16,0,0,0,0,4,52,3,79,0,0,0,6,3,48,0,41],[0,0,0,3,1,16,2,16,0,0,0,0,5,3,4,51,0,0,0,0,5,21,1,207,0,0,0,0,5,21,2,47],[0,0,0,0,4,4,4,59,0,0,1,0,1,16,0,137,0,0,0,0,4,20,2,47,0,0,0,0,1,20,1,207],[0,0,0,0,1,81,1,159,0,0,0,0,0,19,4,53,0,0,0,8,1,0,0,41,0,0,0,0,1,1,4,51],[0,0,0,0,2,2,0,75,0,0,15,255,0,0,193,61,0,0,0,0,2,1,0,75,0,0,16,117,0,0,193,61],[0,0,0,64,4,0,4,61,0,9,0,0,0,4,0,29,0,0,5,22,1,0,0,65,0,0,0,0,0,20,4,53],[0,0,0,4,1,64,0,57,0,0,0,4,2,0,0,41,0,0,0,0,0,33,4,53,0,0,0,10,1,0,0,41],[0,0,0,0,3,1,4,51,0,10,0,0,0,3,0,29,0,0,0,36,1,64,0,57,0,0,0,0,0,49,4,53],[0,0,0,68,2,64,0,57,0,0,0,7,1,0,0,41,20,28,19,250,0,0,4,15,0,0,0,10,1,0,0,41],[0,0,0,31,1,16,0,57,0,0,0,32,2,0,0,138,0,0,0,0,1,33,1,111,0,0,0,68,1,16,0,57],[0,0,5,8,2,0,0,65,0,0,5,8,3,16,0,156,0,0,0,0,1,2,128,25,0,0,0,9,4,0,0,41],[0,0,9,91,0,0,1,61,0,0,0,56,8,64,0,140,0,0,16,43,0,0,65,61,0,0,0,32,9,64,2,112],[0,0,5,8,8,64,0,156,0,0,0,0,9,4,160,25,0,0,5,8,8,64,0,156,0,0,0,0,10,0,0,25],[0,0,0,4,10,0,32,57,0,0,0,2,8,160,1,191,0,0,255,255,11,144,0,140,0,0,0,0,8,10,160,25],[0,0,0,16,10,144,2,112,0,0,0,0,10,9,160,25,0,0,0,255,9,160,0,140,0,0,0,0,9,0,0,25],[0,0,0,1,9,0,32,57,0,0,5,64,10,112,0,156,0,0,19,58,0,0,33,61,0,0,0,0,8,152,1,159],[0,0,0,64,9,112,0,57,0,0,0,64,0,144,4,63,0,0,0,0,10,33,3,79,0,0,0,2,9,128,0,58],[0,0,0,0,9,151,4,54,0,0,0,0,10,10,4,59,0,0,0,0,0,169,4,53,0,0,9,198,0,0,97,61],[0,0,5,65,10,160,1,151,0,0,0,248,11,128,2,16,0,0,0,0,10,171,1,159,0,0,5,69,10,160,1,199],[0,0,0,0,0,169,4,53,0,0,0,3,8,128,2,16,0,0,0,248,8,128,1,95,0,0,0,0,8,132,1,207],[0,0,0,33,9,112,0,57,0,0,0,0,0,137,4,53,0,0,0,0,8,7,0,25,0,0,16,59,0,0,1,61],[0,0,5,64,3,32,0,156,0,0,19,58,0,0,33,61,0,0,0,64,3,32,0,57,0,0,0,64,0,48,4,63],[0,0,0,1,3,0,0,58,0,0,0,0,5,50,4,54,0,0,0,0,4,0,0,49,0,0,0,18,3,0,3,103],[0,0,0,0,6,67,3,79,0,0,0,0,6,6,4,59,0,0,0,0,0,101,4,53,0,0,9,198,0,0,97,61],[0,0,0,248,7,16,2,16,0,0,5,17,8,0,0,65,0,0,0,0,1,1,0,75,0,0,0,0,8,7,192,25],[0,0,5,65,1,96,1,151,0,0,0,0,1,129,1,159,0,0,0,0,0,21,4,53,0,0,0,64,1,0,4,61],[0,0,0,32,6,16,0,57,0,0,0,0,5,2,4,51,0,0,0,0,7,5,0,75,0,0,15,232,0,0,97,61],[0,0,0,0,7,0,0,25,0,0,0,0,8,103,0,25,0,0,0,32,7,112,0,57,0,0,0,0,9,39,0,25],[0,0,0,0,9,9,4,51,0,0,0,0,0,152,4,53,0,0,0,0,8,87,0,75,0,0,15,225,0,0,65,61],[0,0,0,0,2,101,0,25,0,0,5,83,6,0,0,65,0,0,0,0,0,98,4,53,0,0,0,2,2,80,0,57],[0,0,0,0,0,33,4,53,0,0,0,65,2,80,0,57,0,0,0,2,5,32,1,127,0,0,0,0,2,21,0,25],[0,0,0,0,5,82,0,75,0,0,0,0,5,0,0,25,0,0,0,1,5,0,64,57,0,0,5,16,6,32,0,156],[0,0,19,58,0,0,33,61,0,0,0,1,5,80,1,144,0,0,19,58,0,0,193,61,0,0,0,10,6,0,0,41],[0,0,1,196,5,96,0,57,0,0,0,64,0,32,4,63,0,0,0,0,2,83,3,79,0,0,0,0,5,100,0,73],[0,0,0,35,6,80,0,138,0,0,0,0,2,2,4,59,0,0,14,142,0,0,1,61,0,0,0,0,2,1,0,75],[0,0,16,22,0,0,193,61,0,0,5,42,1,0,0,65,0,0,0,0,0,16,4,57,0,0,0,9,1,0,0,41],[0,0,0,4,0,16,4,67,0,0,5,8,1,0,0,65,0,0,0,0,2,0,4,20,0,0,5,8,3,32,0,156],[0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,5,43,1,16,1,199,0,0,128,2,2,0,0,57],[20,28,20,13,0,0,4,15,0,0,0,1,2,32,1,144,0,0,18,65,0,0,97,61,0,0,0,0,1,1,4,59],[0,0,0,0,1,1,0,75,0,0,9,248,0,0,97,61,0,0,0,8,1,0,0,41,0,0,0,0,1,1,4,51],[0,0,0,0,2,1,0,75,0,0,4,34,0,0,97,61,0,0,5,17,2,0,0,65,0,0,0,32,3,16,0,140],[0,0,0,0,3,0,0,25,0,0,0,0,3,2,64,25,0,0,5,17,1,16,1,151,0,0,0,0,4,1,0,75],[0,0,0,0,2,0,160,25,0,0,5,17,1,16,0,156,0,0,0,0,2,3,192,25,0,0,0,0,1,2,0,75],[0,0,1,57,0,0,193,61,0,0,0,6,1,0,0,41,0,0,0,0,1,1,4,51,0,0,0,0,2,1,0,75],[0,0,0,0,2,0,0,25,0,0,0,1,2,0,192,57,0,0,0,0,2,33,0,75,0,0,1,57,0,0,193,61],[0,0,0,0,1,1,0,75,0,0,4,34,0,0,193,61,0,0,11,155,0,0,1,61,0,0,5,64,8,112,0,156],[0,0,19,58,0,0,33,61,0,0,0,64,8,112,0,57,0,0,0,64,0,128,4,63,0,0,0,0,9,33,3,79],[0,0,0,1,8,0,0,58,0,0,0,0,8,135,4,54,0,0,0,0,9,9,4,59,0,0,0,0,0,152,4,53],[0,0,9,198,0,0,97,61,0,0,0,248,10,64,2,16,0,0,5,65,9,144,1,151,0,0,0,0,9,169,1,159],[0,0,5,17,9,144,1,103,0,0,0,0,0,152,4,53,0,0,0,0,8,7,0,25,0,0,0,64,7,0,4,61],[0,0,5,64,9,112,0,156,0,0,19,58,0,0,33,61,0,0,0,64,9,112,0,57,0,0,0,64,0,144,4,63],[0,0,0,0,2,33,3,79,0,0,0,1,12,0,0,58,0,0,0,0,9,199,4,54,0,0,0,0,11,2,4,59],[0,0,0,0,0,185,4,53,0,0,9,198,0,0,97,61,0,0,5,65,2,176,1,151,0,0,5,70,10,32,1,199],[0,0,0,0,0,169,4,53,0,0,0,0,9,6,4,51,0,0,0,0,9,73,0,25,0,0,0,0,10,8,4,51],[0,0,0,0,9,169,0,25,0,0,0,0,10,7,4,51,0,0,0,0,9,169,0,25,0,0,0,64,10,0,4,61],[0,0,5,16,9,144,1,151,0,0,0,56,13,144,0,140,0,0,17,113,0,0,65,61,0,0,0,32,13,144,2,112],[0,0,5,8,12,144,0,156,0,0,0,0,13,9,160,25,0,0,5,8,12,144,0,156,0,0,0,0,14,0,0,25],[0,0,0,4,14,0,32,57,0,0,0,2,12,224,1,191,0,0,255,255,15,208,0,140,0,0,0,0,12,14,160,25],[0,0,0,16,14,208,2,112,0,0,0,0,14,13,160,25,0,0,0,255,13,224,0,140,0,0,0,0,13,0,0,25],[0,0,0,1,13,0,32,57,0,0,5,64,14,160,0,156,0,0,19,58,0,0,33,61,0,0,0,0,12,220,1,159],[0,0,0,64,13,160,0,57,0,0,0,64,0,208,4,63,0,0,0,32,13,160,0,57,0,0,0,0,0,189,4,53],[0,0,0,2,11,192,0,58,0,0,0,0,0,186,4,53,0,0,9,198,0,0,97,61,0,0,0,248,11,192,2,16],[0,0,0,0,2,43,1,159,0,0,5,71,2,32,1,199,0,0,0,0,0,45,4,53,0,0,0,3,2,192,2,16],[0,0,0,248,2,32,1,95,0,0,0,0,2,41,1,207,0,0,0,33,9,160,0,57,0,0,0,0,0,41,4,53],[0,0,17,126,0,0,1,61,0,0,5,8,2,0,0,65,0,0,5,8,3,16,0,156,0,0,0,0,1,2,128,25],[0,0,0,6,4,0,0,41,0,0,9,91,0,0,1,61,0,0,5,64,8,112,0,156,0,0,19,58,0,0,33,61],[0,0,0,64,8,112,0,57,0,0,0,64,0,128,4,63,0,0,0,0,8,67,3,79,0,0,0,1,4,0,0,58],[0,0,0,0,4,71,4,54,0,0,0,0,8,8,4,59,0,0,0,0,0,132,4,53,0,0,9,198,0,0,97,61],[0,0,5,65,8,128,1,151,0,0,0,248,6,96,2,16,0,0,0,0,6,134,1,159,0,0,5,70,6,96,0,65],[0,0,0,0,0,100,4,53,0,0,0,64,4,0,4,61,0,0,0,32,6,64,0,57,0,0,0,0,8,7,4,51],[0,0,0,0,9,8,0,75,0,0,16,150,0,0,97,61,0,0,0,0,9,0,0,25,0,0,0,0,10,105,0,25],[0,0,0,32,9,144,0,57,0,0,0,0,11,121,0,25,0,0,0,0,11,11,4,51,0,0,0,0,0,186,4,53],[0,0,0,0,10,137,0,75,0,0,16,143,0,0,65,61,0,0,0,0,7,104,0,25,0,0,0,0,0,7,4,53],[0,0,0,0,7,72,0,25,0,0,0,32,9,112,0,57,0,0,0,8,8,0,0,41,0,0,0,0,8,8,4,51],[0,0,0,0,10,8,0,75,0,0,16,166,0,0,97,61,0,0,0,0,10,0,0,25,0,0,0,0,11,154,0,25],[0,0,0,32,10,160,0,57,0,0,0,8,12,160,0,41,0,0,0,0,12,12,4,51,0,0,0,0,0,203,4,53],[0,0,0,0,11,138,0,75,0,0,16,159,0,0,65,61,0,0,0,0,9,152,0,25,0,0,0,0,0,9,4,53],[0,0,0,0,7,120,0,25,0,0,0,32,9,112,0,57,0,0,0,6,8,0,0,41,0,0,0,0,8,8,4,51],[0,0,0,0,10,8,0,75,0,0,16,182,0,0,97,61,0,0,0,0,10,0,0,25,0,0,0,0,11,154,0,25],[0,0,0,32,10,160,0,57,0,0,0,6,12,160,0,41,0,0,0,0,12,12,4,51,0,0,0,0,0,203,4,53],[0,0,0,0,11,138,0,75,0,0,16,175,0,0,65,61,0,0,0,0,9,152,0,25,0,0,0,0,0,9,4,53],[0,0,0,0,7,120,0,25,0,0,0,32,9,112,0,57,0,0,0,5,8,0,0,41,0,0,0,0,8,8,4,51],[0,0,0,0,10,8,0,75,0,0,16,198,0,0,97,61,0,0,0,0,10,0,0,25,0,0,0,0,11,154,0,25],[0,0,0,32,10,160,0,57,0,0,0,5,12,160,0,41,0,0,0,0,12,12,4,51,0,0,0,0,0,203,4,53],[0,0,0,0,11,138,0,75,0,0,16,191,0,0,65,61,0,0,0,0,9,152,0,25,0,0,0,0,0,9,4,53],[0,0,0,0,7,120,0,25,0,0,0,32,9,112,0,57,0,0,0,4,8,0,0,41,0,0,0,0,8,8,4,51],[0,0,0,0,10,8,0,75,0,0,16,214,0,0,97,61,0,0,0,0,10,0,0,25,0,0,0,0,11,154,0,25],[0,0,0,32,10,160,0,57,0,0,0,4,12,160,0,41,0,0,0,0,12,12,4,51,0,0,0,0,0,203,4,53],[0,0,0,0,11,138,0,75,0,0,16,207,0,0,65,61,0,0,0,0,9,152,0,25,0,0,0,0,0,9,4,53],[0,0,0,0,7,120,0,25,0,0,0,32,9,112,0,57,0,0,0,3,8,0,0,41,0,0,0,0,8,8,4,51],[0,0,0,0,10,8,0,75,0,0,16,230,0,0,97,61,0,0,0,0,10,0,0,25,0,0,0,0,11,154,0,25],[0,0,0,32,10,160,0,57,0,0,0,3,12,160,0,41,0,0,0,0,12,12,4,51,0,0,0,0,0,203,4,53],[0,0,0,0,11,138,0,75,0,0,16,223,0,0,65,61,0,0,0,0,9,152,0,25,0,0,0,0,0,9,4,53],[0,0,0,0,5,83,3,79,0,0,0,0,3,120,0,25,0,0,0,31,7,32,1,143,0,0,0,32,8,48,0,57],[0,0,0,5,9,32,2,114,0,0,16,247,0,0,97,61,0,0,0,0,10,0,0,25,0,0,0,5,11,160,2,16],[0,0,0,0,12,184,0,25,0,0,0,0,11,181,3,79,0,0,0,0,11,11,4,59,0,0,0,0,0,188,4,53],[0,0,0,1,10,160,0,57,0,0,0,0,11,154,0,75,0,0,16,239,0,0,65,61,0,0,0,0,10,7,0,75],[0,0,17,6,0,0,97,61,0,0,0,5,9,144,2,16,0,0,0,0,5,149,3,79,0,0,0,0,8,152,0,25],[0,0,0,3,7,112,2,16,0,0,0,0,9,8,4,51,0,0,0,0,9,121,1,207,0,0,0,0,9,121,2,47],[0,0,0,0,5,5,4,59,0,0,1,0,7,112,0,137,0,0,0,0,5,117,2,47,0,0,0,0,5,117,1,207],[0,0,0,0,5,149,1,159,0,0,0,0,0,88,4,53,0,0,0,0,2,35,0,25,0,0,0,32,5,32,0,57],[0,0,0,0,0,5,4,53,0,0,0,0,3,1,4,51,0,0,0,0,7,3,0,75,0,0,17,20,0,0,97,61],[0,0,0,0,7,0,0,25,0,0,0,0,8,87,0,25,0,0,0,32,7,112,0,57,0,0,0,0,9,23,0,25],[0,0,0,0,9,9,4,51,0,0,0,0,0,152,4,53,0,0,0,0,8,55,0,75,0,0,17,13,0,0,65,61],[0,0,0,0,1,83,0,25,0,0,0,0,0,1,4,53,0,0,0,0,1,66,0,73,0,0,0,0,1,19,0,25],[0,0,0,0,0,20,4,53,0,0,0,63,1,16,0,57,0,0,0,2,2,16,1,127,0,0,0,0,1,66,0,25],[0,0,0,0,2,33,0,75,0,0,0,0,2,0,0,25,0,0,0,1,2,0,64,57,0,0,5,16,3,16,0,156],[0,0,19,58,0,0,33,61,0,0,0,1,2,32,1,144,0,0,19,58,0,0,193,61,0,0,0,64,0,16,4,63],[0,0,5,8,1,0,0,65,0,0,5,8,2,96,0,156,0,0,0,0,6,1,128,25,0,0,0,64,2,96,2,16],[0,0,0,0,3,4,4,51,0,0,5,8,4,48,0,156,0,0,0,0,3,1,128,25,0,0,0,96,3,48,2,16],[0,0,0,0,2,35,1,159,0,0,0,0,3,0,4,20,0,0,17,245,0,0,1,61,0,0,0,31,4,48,1,143],[0,0,0,5,2,48,2,114,0,0,17,58,0,0,97,61,0,0,0,0,5,0,0,25,0,0,0,5,6,80,2,16],[0,0,0,0,7,97,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,118,4,53,0,0,0,1,5,80,0,57],[0,0,0,0,6,37,0,75,0,0,17,51,0,0,65,61,0,0,0,0,5,4,0,75,0,0,17,72,0,0,97,61],[0,0,0,3,4,64,2,16,0,0,0,5,2,32,2,16,0,0,0,0,5,2,4,51,0,0,0,0,5,69,1,207],[0,0,0,0,5,69,2,47,0,0,0,0,1,33,3,79,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137],[0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,81,1,159,0,0,0,0,0,18,4,53],[0,0,0,96,1,48,2,16,0,0,20,30,0,1,4,48,0,0,0,56,8,64,0,140,0,0,19,39,0,0,65,61],[0,0,0,32,9,64,2,112,0,0,5,8,8,64,0,156,0,0,0,0,9,4,160,25,0,0,5,8,8,64,0,156],[0,0,0,0,10,0,0,25,0,0,0,4,10,0,32,57,0,0,0,2,8,160,1,191,0,0,255,255,11,144,0,140],[0,0,0,0,8,10,160,25,0,0,0,16,10,144,2,112,0,0,0,0,10,9,160,25,0,0,0,255,9,160,0,140],[0,0,0,0,9,0,0,25,0,0,0,1,9,0,32,57,0,0,5,64,10,96,0,156,0,0,19,58,0,0,33,61],[0,0,0,0,8,152,1,159,0,0,0,64,9,96,0,57,0,0,0,64,0,144,4,63,0,0,0,0,10,33,3,79],[0,0,0,2,9,128,0,58,0,0,0,0,9,150,4,54,0,0,0,0,10,10,4,59,0,0,0,0,0,169,4,53],[0,0,9,198,0,0,97,61,0,0,5,65,10,160,1,151,0,0,0,248,11,128,2,16,0,0,0,0,10,171,1,159],[0,0,5,69,10,160,1,199,0,0,0,0,0,169,4,53,0,0,0,3,8,128,2,16,0,0,0,248,8,128,1,95],[0,0,0,0,8,132,1,207,0,0,0,33,9,96,0,57,0,0,0,0,0,137,4,53,0,0,0,0,8,6,0,25],[0,0,19,55,0,0,1,61,0,0,5,64,13,160,0,156,0,0,19,58,0,0,33,61,0,0,0,64,13,160,0,57],[0,0,0,64,0,208,4,63,0,0,0,32,13,160,0,57,0,0,0,0,0,189,4,53,0,0,0,0,0,202,4,53],[0,0,0,0,11,12,0,75,0,0,9,198,0,0,97,61,0,0,0,248,9,144,2,16,0,0,0,0,2,41,1,159],[0,0,5,70,2,32,0,65,0,0,0,0,0,45,4,53,0,0,0,64,2,0,4,61,0,0,0,32,9,32,0,57],[0,0,5,72,11,0,0,65,0,0,0,0,0,185,4,53,0,0,0,33,12,32,0,57,0,0,0,0,11,10,4,51],[0,0,0,0,13,11,0,75,0,0,17,142,0,0,97,61,0,0,0,0,13,0,0,25,0,0,0,0,14,205,0,25],[0,0,0,32,13,208,0,57,0,0,0,0,15,173,0,25,0,0,0,0,15,15,4,51,0,0,0,0,0,254,4,53],[0,0,0,0,14,189,0,75,0,0,17,135,0,0,65,61,0,0,0,0,10,203,0,25,0,0,0,0,0,10,4,53],[0,0,0,0,10,43,0,25,0,0,0,33,12,160,0,57,0,0,0,0,11,6,4,51,0,0,0,0,13,11,0,75],[0,0,17,157,0,0,97,61,0,0,0,0,13,0,0,25,0,0,0,0,14,205,0,25,0,0,0,32,13,208,0,57],[0,0,0,0,15,109,0,25,0,0,0,0,15,15,4,51,0,0,0,0,0,254,4,53,0,0,0,0,14,189,0,75],[0,0,17,150,0,0,65,61,0,0,0,0,6,203,0,25,0,0,0,0,0,6,4,53,0,0,0,0,6,171,0,25],[0,0,0,33,11,96,0,57,0,0,0,0,10,8,4,51,0,0,0,0,12,10,0,75,0,0,17,172,0,0,97,61],[0,0,0,0,12,0,0,25,0,0,0,0,13,188,0,25,0,0,0,32,12,192,0,57,0,0,0,0,14,140,0,25],[0,0,0,0,14,14,4,51,0,0,0,0,0,237,4,53,0,0,0,0,13,172,0,75,0,0,17,165,0,0,65,61],[0,0,0,0,8,186,0,25,0,0,0,0,0,8,4,53,0,0,0,0,5,81,3,79,0,0,0,0,1,106,0,25],[0,0,0,31,6,64,1,143,0,0,0,33,8,16,0,57,0,0,0,5,10,64,2,114,0,0,17,189,0,0,97,61],[0,0,0,0,11,0,0,25,0,0,0,5,12,176,2,16,0,0,0,0,13,200,0,25,0,0,0,0,12,197,3,79],[0,0,0,0,12,12,4,59,0,0,0,0,0,205,4,53,0,0,0,1,11,176,0,57,0,0,0,0,12,171,0,75],[0,0,17,181,0,0,65,61,0,0,0,0,11,6,0,75,0,0,17,204,0,0,97,61,0,0,0,5,10,160,2,16],[0,0,0,0,5,165,3,79,0,0,0,0,8,168,0,25,0,0,0,3,6,96,2,16,0,0,0,0,10,8,4,51],[0,0,0,0,10,106,1,207,0,0,0,0,10,106,2,47,0,0,0,0,5,5,4,59,0,0,1,0,6,96,0,137],[0,0,0,0,5,101,2,47,0,0,0,0,5,101,1,207,0,0,0,0,5,165,1,159,0,0,0,0,0,88,4,53],[0,0,0,0,1,65,0,25,0,0,0,33,5,16,0,57,0,0,0,0,0,5,4,53,0,0,0,0,4,7,4,51],[0,0,0,0,6,4,0,75,0,0,17,218,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,0,8,86,0,25],[0,0,0,32,6,96,0,57,0,0,0,0,10,118,0,25,0,0,0,0,10,10,4,51,0,0,0,0,0,168,4,53],[0,0,0,0,8,70,0,75,0,0,17,211,0,0,65,61,0,0,0,0,5,84,0,25,0,0,0,0,0,5,4,53],[0,0,0,0,1,33,0,73,0,0,0,0,1,20,0,25,0,0,0,1,4,16,0,57,0,0,0,0,0,66,4,53],[0,0,0,64,1,16,0,57,0,0,0,0,3,49,1,111,0,0,0,0,1,35,0,25,0,0,0,0,3,49,0,75],[0,0,0,0,3,0,0,25,0,0,0,1,3,0,64,57,0,0,5,16,4,16,0,156,0,0,19,58,0,0,33,61],[0,0,0,1,3,48,1,144,0,0,19,58,0,0,193,61,0,0,0,64,0,16,4,63,0,0,5,8,1,0,0,65],[0,0,5,8,3,144,0,156,0,0,0,0,9,1,128,25,0,0,0,64,3,144,2,16,0,0,0,0,2,2,4,51],[0,0,5,8,4,32,0,156,0,0,0,0,2,1,128,25,0,0,0,96,2,32,2,16,0,0,0,0,2,50,1,159],[0,0,0,0,3,0,4,20,0,0,5,8,4,48,0,156,0,0,0,0,3,1,128,25,0,0,0,192,1,48,2,16],[0,0,0,0,1,33,1,159,0,0,5,19,1,16,1,199,0,0,128,16,2,0,0,57,20,28,20,13,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,1,57,0,0,97,61,0,0,0,18,3,0,3,103,0,0,0,0,1,1,4,59],[0,8,0,0,0,1,0,29,0,0,0,10,1,0,0,41,0,0,0,228,4,16,0,57,0,0,0,0,1,67,3,79],[0,0,0,0,1,1,4,59,0,0,5,18,1,16,1,152,0,5,0,0,0,4,0,29,0,0,18,33,0,0,193,61],[0,0,0,128,1,64,0,138,0,0,0,0,2,19,3,79,0,0,0,64,1,64,0,138,0,0,0,0,5,19,3,79],[0,0,0,0,4,2,4,59,0,0,0,0,5,5,4,59,0,0,0,0,98,69,0,169,0,0,0,0,6,5,0,75],[0,0,18,20,0,0,97,61,0,0,0,0,101,82,0,217,0,0,0,0,4,69,0,75,0,0,18,29,0,0,193,61],[0,0,0,128,1,16,0,57,0,0,0,0,1,19,3,79,0,0,0,0,1,1,4,59,0,6,0,0,0,33,0,29],[0,0,0,6,1,16,0,107,0,0,0,0,1,0,0,25,0,0,0,1,1,0,64,57,0,0,0,1,1,16,1,144],[0,0,18,38,0,0,97,61,0,0,5,94,1,0,0,65,0,0,0,0,0,16,4,53,0,0,0,17,1,0,0,57],[0,0,0,81,0,0,1,61,0,0,0,10,1,0,0,41,0,0,1,36,1,16,0,57,0,0,0,0,1,19,3,79],[0,0,0,0,1,1,4,59,0,6,0,0,0,1,0,29,0,0,5,84,1,0,0,65,0,0,0,0,0,16,4,57],[0,0,0,7,1,0,0,41,0,0,0,4,0,16,4,67,0,0,5,8,1,0,0,65,0,0,0,0,2,0,4,20],[0,0,5,8,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,5,43,1,16,1,199],[0,0,128,10,2,0,0,57,20,28,20,13,0,0,4,15,0,0,0,1,2,32,1,144,0,0,18,65,0,0,97,61],[0,0,0,0,1,1,4,59,0,0,0,6,1,16,0,107,0,0,18,66,0,0,161,61,0,0,0,64,1,0,4,61],[0,0,0,100,2,16,0,57,0,0,5,92,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,68,2,16,0,57],[0,0,5,93,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,34,3,0,0,57],[0,0,1,23,0,0,1,61,0,0,0,0,0,1,4,47,0,0,0,0,4,0,0,49,0,0,0,10,1,64,0,106],[0,0,0,35,2,16,0,138,0,0,0,5,1,0,0,41,0,0,1,0,1,16,0,57,0,0,0,18,3,0,3,103],[0,0,0,0,1,19,3,79,0,0,0,0,1,1,4,59,0,0,5,17,5,0,0,65,0,0,0,0,6,33,0,75],[0,0,0,0,6,0,0,25,0,0,0,0,6,5,128,25,0,0,5,17,2,32,1,151,0,0,5,17,7,16,1,151],[0,0,0,0,8,39,0,75,0,0,0,0,5,0,128,25,0,0,0,0,2,39,1,63,0,0,5,17,2,32,0,156],[0,0,0,0,5,6,192,25,0,0,0,0,2,5,0,75,0,0,1,57,0,0,193,61,0,0,0,9,2,16,0,41],[0,0,0,0,1,35,3,79,0,0,0,0,1,1,4,59,0,0,5,16,5,16,0,156,0,0,1,57,0,0,33,61],[0,0,0,0,5,20,0,73,0,0,0,32,6,32,0,57,0,0,5,17,2,0,0,65,0,0,0,0,7,86,0,75],[0,0,0,0,7,0,0,25,0,0,0,0,7,2,32,25,0,0,5,17,5,80,1,151,0,0,5,17,8,96,1,151],[0,0,0,0,9,88,0,75,0,0,0,0,2,0,128,25,0,0,0,0,5,88,1,63,0,0,5,17,5,80,0,156],[0,0,0,0,2,7,192,25,0,0,0,0,2,2,0,75,0,0,1,57,0,0,193,61,0,0,0,63,2,16,0,57],[0,0,0,32,5,0,0,138,0,0,0,0,5,82,1,111,0,0,0,64,2,0,4,61,0,0,0,0,5,82,0,25],[0,0,0,0,7,37,0,75,0,0,0,0,7,0,0,25,0,0,0,1,7,0,64,57,0,0,5,16,8,80,0,156],[0,0,19,58,0,0,33,61,0,0,0,1,7,112,1,144,0,0,19,58,0,0,193,61,0,0,0,64,0,80,4,63],[0,0,0,0,5,18,4,54,0,0,0,0,7,97,0,25,0,0,0,0,4,71,0,75,0,0,1,57,0,0,33,61],[0,0,0,0,4,99,3,79,0,0,0,31,3,16,1,143,0,0,0,5,6,16,2,114,0,0,18,137,0,0,97,61],[0,0,0,0,7,0,0,25,0,0,0,5,8,112,2,16,0,0,0,0,9,133,0,25,0,0,0,0,8,132,3,79],[0,0,0,0,8,8,4,59,0,0,0,0,0,137,4,53,0,0,0,1,7,112,0,57,0,0,0,0,8,103,0,75],[0,0,18,129,0,0,65,61,0,0,0,0,7,3,0,75,0,0,18,152,0,0,97,61,0,0,0,5,6,96,2,16],[0,0,0,0,4,100,3,79,0,0,0,0,6,101,0,25,0,0,0,3,3,48,2,16,0,0,0,0,7,6,4,51],[0,0,0,0,7,55,1,207,0,0,0,0,7,55,2,47,0,0,0,0,4,4,4,59,0,0,1,0,3,48,0,137],[0,0,0,0,4,52,2,47,0,0,0,0,3,52,1,207,0,0,0,0,3,115,1,159,0,0,0,0,0,54,4,53],[0,0,0,0,1,21,0,25,0,0,0,0,0,1,4,53,0,0,0,64,1,0,4,61,0,0,0,0,3,2,4,51],[0,0,0,65,3,48,0,140,0,0,18,171,0,0,193,61,0,0,0,65,3,32,0,57,0,0,0,0,3,3,4,51],[0,0,0,255,3,48,1,143,0,0,0,29,4,48,0,138,0,0,0,3,6,0,0,138,0,0,0,0,4,100,0,75],[0,0,18,177,0,0,33,61,0,0,0,68,2,16,0,57,0,0,5,91,3,0,0,65,0,0,0,0,0,50,4,53],[0,0,0,36,2,16,0,57,0,0,0,22,3,0,0,57,0,0,2,184,0,0,1,61,0,0,0,68,2,16,0,57],[0,0,5,85,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,29,3,0,0,57],[0,0,2,184,0,0,1,61,0,0,0,0,4,5,4,51,0,0,0,64,2,32,0,57,0,0,0,0,2,2,4,51],[0,0,5,86,5,32,0,156,0,0,18,188,0,0,65,61,0,0,0,68,2,16,0,57,0,0,5,90,3,0,0,65],[0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,9,3,0,0,57,0,0,2,184,0,0,1,61],[0,0,0,96,5,16,0,57,0,0,0,0,0,37,4,53,0,0,0,64,2,16,0,57,0,0,0,0,0,66,4,53],[0,0,0,32,2,16,0,57,0,0,0,0,0,50,4,53,0,0,0,8,2,0,0,41,0,0,0,0,0,33,4,53],[0,0,0,0,0,0,4,53,0,0,5,8,2,0,0,65,0,0,0,0,3,0,4,20,0,0,5,8,4,48,0,156],[0,0,0,0,3,2,128,25,0,0,5,8,4,16,0,156,0,0,0,0,1,2,128,25,0,0,0,64,1,16,2,16],[0,0,0,192,2,48,2,16,0,0,0,0,1,18,1,159,0,0,5,87,1,16,1,199,0,0,0,1,2,0,0,57],[20,28,20,13,0,0,4,15,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,5,8,3,48,1,151],[0,0,0,32,4,48,0,140,0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57,0,0,0,31,5,64,1,143],[0,0,0,5,4,64,2,114,0,0,18,226,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16],[0,0,0,0,8,113,3,79,0,0,0,0,8,8,4,59,0,0,0,0,0,135,4,53,0,0,0,1,6,96,0,57],[0,0,0,0,7,70,0,75,0,0,18,219,0,0,65,61,0,0,0,0,6,5,0,75,0,0,18,240,0,0,97,61],[0,0,0,3,5,80,2,16,0,0,0,5,4,64,2,16,0,0,0,0,6,4,4,51,0,0,0,0,6,86,1,207],[0,0,0,0,6,86,2,47,0,0,0,0,7,65,3,79,0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137],[0,0,0,0,7,87,2,47,0,0,0,0,5,87,1,207,0,0,0,0,5,101,1,159,0,0,0,0,0,84,4,53],[0,1,0,0,0,3,0,31,0,19,0,0,0,1,3,85,0,0,0,64,4,0,4,61,0,0,0,1,2,32,1,144],[0,0,19,7,0,0,97,61,0,0,0,0,1,0,4,51,0,0,5,18,1,16,1,151,0,0,0,7,2,16,0,108],[0,0,0,0,2,0,0,25,0,0,0,1,2,0,192,57,0,0,0,0,1,1,0,75,0,0,0,0,1,0,0,25],[0,0,0,1,1,0,96,57,0,0,0,0,1,18,1,160,0,0,5,88,1,0,0,65,0,0,0,0,1,0,192,25],[0,0,0,0,0,20,4,53,0,0,5,8,1,0,0,65,0,0,5,8,2,64,0,156,0,0,0,0,4,1,128,25],[0,0,0,64,1,64,2,16,0,0,5,89,1,16,1,199,0,0,20,29,0,1,4,46,0,0,0,31,2,48,1,143],[0,0,0,5,5,48,2,114,0,0,19,19,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16],[0,0,0,0,8,116,0,25,0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53],[0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,19,11,0,0,65,61,0,0,0,0,6,2,0,75],[0,0,19,34,0,0,97,61,0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,84,0,25],[0,0,0,3,2,32,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,38,1,207,0,0,0,0,6,38,2,47],[0,0,0,0,1,1,4,59,0,0,1,0,2,32,0,137,0,0,0,0,1,33,2,47,0,0,0,0,1,33,1,207],[0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,5,8,1,0,0,65,0,0,5,8,2,64,0,156],[0,0,0,0,4,1,128,25,0,0,0,64,1,64,2,16,0,0,6,134,0,0,1,61,0,0,5,64,8,96,0,156],[0,0,19,58,0,0,33,61,0,0,0,64,8,96,0,57,0,0,0,64,0,128,4,63,0,0,0,0,9,33,3,79],[0,0,0,1,8,0,0,58,0,0,0,0,8,134,4,54,0,0,0,0,9,9,4,59,0,0,0,0,0,152,4,53],[0,0,9,198,0,0,97,61,0,0,0,248,10,64,2,16,0,0,5,65,9,144,1,151,0,0,0,0,9,169,1,159],[0,0,5,17,9,144,1,103,0,0,0,0,0,152,4,53,0,0,0,0,8,6,0,25,0,0,0,64,6,0,4,61],[0,0,5,64,9,96,0,156,0,0,19,62,0,0,161,61,0,0,5,94,1,0,0,65,0,0,0,0,0,16,4,53],[0,0,0,65,1,0,0,57,0,0,0,81,0,0,1,61,0,0,0,64,9,96,0,57,0,0,0,64,0,144,4,63],[0,0,0,0,2,33,3,79,0,0,0,1,12,0,0,58,0,0,0,0,9,198,4,54,0,0,0,0,11,2,4,59],[0,0,0,0,0,185,4,53,0,0,9,198,0,0,97,61,0,0,5,65,2,176,1,151,0,0,5,70,10,32,1,199],[0,0,0,0,0,169,4,53,0,0,0,0,9,7,4,51,0,0,0,0,9,73,0,25,0,0,0,0,10,8,4,51],[0,0,0,0,9,169,0,25,0,0,0,0,10,6,4,51,0,0,0,0,9,169,0,25,0,0,0,64,10,0,4,61],[0,0,5,16,9,144,1,151,0,0,0,56,13,144,0,140,0,0,19,117,0,0,65,61,0,0,0,32,13,144,2,112],[0,0,5,8,12,144,0,156,0,0,0,0,13,9,160,25,0,0,5,8,12,144,0,156,0,0,0,0,14,0,0,25],[0,0,0,4,14,0,32,57,0,0,0,2,12,224,1,191,0,0,255,255,15,208,0,140,0,0,0,0,12,14,160,25],[0,0,0,16,14,208,2,112,0,0,0,0,14,13,160,25,0,0,0,255,13,224,0,140,0,0,0,0,13,0,0,25],[0,0,0,1,13,0,32,57,0,0,5,64,14,160,0,156,0,0,19,58,0,0,33,61,0,0,0,0,12,220,1,159],[0,0,0,64,13,160,0,57,0,0,0,64,0,208,4,63,0,0,0,32,13,160,0,57,0,0,0,0,0,189,4,53],[0,0,0,2,11,192,0,58,0,0,0,0,0,186,4,53,0,0,9,198,0,0,97,61,0,0,0,248,11,192,2,16],[0,0,0,0,2,43,1,159,0,0,5,71,2,32,1,199,0,0,0,0,0,45,4,53,0,0,0,3,2,192,2,16],[0,0,0,248,2,32,1,95,0,0,0,0,2,41,1,207,0,0,0,33,9,160,0,57,0,0,0,0,0,41,4,53],[0,0,19,130,0,0,1,61,0,0,5,64,13,160,0,156,0,0,19,58,0,0,33,61,0,0,0,64,13,160,0,57],[0,0,0,64,0,208,4,63,0,0,0,32,13,160,0,57,0,0,0,0,0,189,4,53,0,0,0,0,0,202,4,53],[0,0,0,0,11,12,0,75,0,0,9,198,0,0,97,61,0,0,0,248,9,144,2,16,0,0,0,0,2,41,1,159],[0,0,5,70,2,32,0,65,0,0,0,0,0,45,4,53,0,0,0,64,2,0,4,61,0,0,0,32,9,32,0,57],[0,0,5,19,11,0,0,65,0,0,0,0,0,185,4,53,0,0,0,33,12,32,0,57,0,0,0,0,11,10,4,51],[0,0,0,0,13,11,0,75,0,0,19,146,0,0,97,61,0,0,0,0,13,0,0,25,0,0,0,0,14,205,0,25],[0,0,0,32,13,208,0,57,0,0,0,0,15,173,0,25,0,0,0,0,15,15,4,51,0,0,0,0,0,254,4,53],[0,0,0,0,14,189,0,75,0,0,19,139,0,0,65,61,0,0,0,0,10,203,0,25,0,0,0,0,0,10,4,53],[0,0,0,0,10,43,0,25,0,0,0,33,12,160,0,57,0,0,0,0,11,7,4,51,0,0,0,0,13,11,0,75],[0,0,19,161,0,0,97,61,0,0,0,0,13,0,0,25,0,0,0,0,14,205,0,25,0,0,0,32,13,208,0,57],[0,0,0,0,15,125,0,25,0,0,0,0,15,15,4,51,0,0,0,0,0,254,4,53,0,0,0,0,14,189,0,75],[0,0,19,154,0,0,65,61,0,0,0,0,7,203,0,25,0,0,0,0,0,7,4,53,0,0,0,0,7,171,0,25],[0,0,0,33,11,112,0,57,0,0,0,0,10,8,4,51,0,0,0,0,12,10,0,75,0,0,19,176,0,0,97,61],[0,0,0,0,12,0,0,25,0,0,0,0,13,188,0,25,0,0,0,32,12,192,0,57,0,0,0,0,14,140,0,25],[0,0,0,0,14,14,4,51,0,0,0,0,0,237,4,53,0,0,0,0,13,172,0,75,0,0,19,169,0,0,65,61],[0,0,0,0,8,186,0,25,0,0,0,0,0,8,4,53,0,0,0,0,5,81,3,79,0,0,0,0,1,122,0,25],[0,0,0,31,7,64,1,143,0,0,0,33,8,16,0,57,0,0,0,5,10,64,2,114,0,0,19,193,0,0,97,61],[0,0,0,0,11,0,0,25,0,0,0,5,12,176,2,16,0,0,0,0,13,200,0,25,0,0,0,0,12,197,3,79],[0,0,0,0,12,12,4,59,0,0,0,0,0,205,4,53,0,0,0,1,11,176,0,57,0,0,0,0,12,171,0,75],[0,0,19,185,0,0,65,61,0,0,0,0,11,7,0,75,0,0,19,208,0,0,97,61,0,0,0,5,10,160,2,16],[0,0,0,0,5,165,3,79,0,0,0,0,8,168,0,25,0,0,0,3,7,112,2,16,0,0,0,0,10,8,4,51],[0,0,0,0,10,122,1,207,0,0,0,0,10,122,2,47,0,0,0,0,5,5,4,59,0,0,1,0,7,112,0,137],[0,0,0,0,5,117,2,47,0,0,0,0,5,117,1,207,0,0,0,0,5,165,1,159,0,0,0,0,0,88,4,53],[0,0,0,0,1,65,0,25,0,0,0,33,5,16,0,57,0,0,0,0,0,5,4,53,0,0,0,0,4,6,4,51],[0,0,0,0,7,4,0,75,0,0,19,222,0,0,97,61,0,0,0,0,7,0,0,25,0,0,0,0,8,87,0,25],[0,0,0,32,7,112,0,57,0,0,0,0,10,103,0,25,0,0,0,0,10,10,4,51,0,0,0,0,0,168,4,53],[0,0,0,0,8,71,0,75,0,0,19,215,0,0,65,61,0,0,0,0,5,84,0,25,0,0,0,0,0,5,4,53],[0,0,0,0,1,33,0,73,0,0,0,0,1,20,0,25,0,0,0,1,4,16,0,57,0,0,0,0,0,66,4,53],[0,0,0,64,1,16,0,57,0,0,0,0,3,49,1,111,0,0,0,0,1,35,0,25,0,0,0,0,3,49,0,75],[0,0,0,0,3,0,0,25,0,0,0,1,3,0,64,57,0,0,5,16,4,16,0,156,0,0,19,58,0,0,33,61],[0,0,0,1,3,48,1,144,0,0,19,58,0,0,193,61,0,0,0,64,0,16,4,63,0,0,5,8,1,0,0,65],[0,0,5,8,3,144,0,156,0,0,0,0,9,1,128,25,0,0,0,64,3,144,2,16,0,0,0,0,2,2,4,51],[0,0,5,8,4,32,0,156,0,0,0,0,2,1,128,25,0,0,0,96,2,32,2,16,0,0,0,0,2,50,1,159],[0,0,0,0,3,0,4,20,0,0,17,245,0,0,1,61,0,0,0,0,4,3,0,75,0,0,20,4,0,0,97,61],[0,0,0,0,4,0,0,25,0,0,0,0,5,36,0,25,0,0,0,0,6,20,0,25,0,0,0,0,6,6,4,51],[0,0,0,0,0,101,4,53,0,0,0,32,4,64,0,57,0,0,0,0,5,52,0,75,0,0,19,253,0,0,65,61],[0,0,0,0,1,35,0,25,0,0,0,0,0,1,4,53,0,0,0,0,0,1,4,45,0,0,0,0,0,1,4,47],[0,0,20,11,0,33,4,33,0,0,0,1,2,0,0,57,0,0,0,0,0,1,4,45,0,0,0,0,2,0,0,25],[0,0,0,0,0,1,4,45,0,0,20,16,0,33,4,35,0,0,0,1,2,0,0,57,0,0,0,0,0,1,4,45],[0,0,0,0,2,0,0,25,0,0,0,0,0,1,4,45,0,0,20,21,0,33,4,33,0,0,0,1,2,0,0,57],[0,0,0,0,0,1,4,45,0,0,0,0,2,0,0,25,0,0,0,0,0,1,4,45,0,0,20,26,0,33,4,35],[0,0,0,1,2,0,0,57,0,0,0,0,0,1,4,45,0,0,0,0,2,0,0,25,0,0,0,0,0,1,4,45],[0,0,20,28,0,0,4,50,0,0,20,29,0,1,4,46,0,0,20,30,0,1,4,48,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255],[0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,1,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,223,156,21,136],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,223,156,21,137],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,226,243,24,227],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,238,184,203,9],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,43,204,231],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,162,140,26,238],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255],[128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],[2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[114,97,116,111,114,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[70,97,105,108,101,100,32,116,111,32,112,97,121,32,116,104,101,32,102,101,101,32,116,111,32,116,104,101,32,111,112,101],[8,195,121,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[156,77,83,90,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],[156,77,83,91,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[236,249,91,138,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[60,218,51,81,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[93,56,39,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[79,118,101,114,102,108,111,119,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,128,0,0,0,0,0,0,0,0],[140,90,52,69,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[148,148,49,220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[221,98,237,62,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,0,0,0,128,0,0,0,0,0,0,0,0],[9,94,167,179,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[83,97,102,101,69,82,67,50,48,58,32,108,111,119,45,108,101,118,101,108,32,99,97,108,108,32,102,97,105,108,101,100],[24,6,170,24,150,187,242,101,104,232,132,167,55,75,65,224,2,80,9,98,202,186,106,21,2,58,141,144,232,80,139,131],[2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,0,0,0,0,0,0,0,0,0,0,0,0],[83,97,102,101,69,82,67,50,48,58,32,97,112,112,114,111,118,101,32,102,114,111,109,32,110,111,110,45,122,101,114,111],[32,116,111,32,110,111,110,45,122,101,114,111,32,97,108,108,111,119,97,110,99,101,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,127],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,63],[111,116,32,115,117,99,99,101,101,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[83,97,102,101,69,82,67,50,48,58,32,69,82,67,50,48,32,111,112,101,114,97,116,105,111,110,32,100,105,100,32,110],[65,100,100,114,101,115,115,58,32,99,97,108,108,32,116,111,32,110,111,110,45,99,111,110,116,114,97,99,116,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,0,0,0,0,0,0,0,0,0],[84,104,101,32,97,112,112,114,111,118,97,108,66,97,115,101,100,32,112,97,121,109,97,115,116,101,114,32,105,110,112,117],[116,32,109,117,115,116,32,98,101,32,97,116,32,108,101,97,115,116,32,54,56,32,98,121,116,101,115,32,108,111,110,103],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,0,0,0,128,0,0,0,0,0,0,0,0],[85,110,115,117,112,112,111,114,116,101,100,32,112,97,121,109,97,115,116,101,114,32,102,108,111,119,0,0,0,0,0,0],[84,104,101,32,115,116,97,110,100,97,114,100,32,112,97,121,109,97,115,116,101,114,32,105,110,112,117,116,32,109,117,115],[116,32,98,101,32,97,116,32,108,101,97,115,116,32,52,32,98,121,116,101,115,32,108,111,110,103,0,0,0,0,0,0],[225,35,156,216,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,0,0,0,160,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,255,255,255,224],[154,138,5,146,172,137,197,173,59,198,223,130,36,193,123,72,89,118,245,151,223,16,78,226,13,13,244,21,36,31,103,11],[2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,191],[0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],[129,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[148,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[184,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[192,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[248,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0],[7,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],[107,101,99,99,97,107,50,53,54,32,114,101,116,117,114,110,101,100,32,105,110,118,97,108,105,100,32,100,97,116,97,0],[132,142,27,250,26,196,227,87,107,114,139,218,103,33,178,21,199,10,119,153,165,180,134,98,130,167,27,171,149,75,170,200],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,254,31],[194,248,120,113,118,184,172,107,247,33,91,74,220,193,224,105,191,74,184,45,154,177,223,5,165,122,145,212,37,147,91,110],[173,124,91,239,2,120,22,168,0,218,23,54,68,79,181,138,128,126,244,201,96,59,120,72,103,63,126,58,104,235,20,165],[25,180,83,206,69,170,170,243,163,0,245,169,236,149,134,155,79,40,171,16,67,11,87,46,226,24,195,166,165,224,125,111],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,95],[25,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[128,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[156,199,247,8,175,198,89,68,130,155,212,135,185,11,114,83,107,25,81,134,79,191,193,78,18,95,201,114,166,80,127,57],[83,105,103,110,97,116,117,114,101,32,108,101,110,103,116,104,32,105,115,32,105,110,99,111,114,114,101,99,116,0,0,0],[127,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,93,87,110,115,87,164,80,29,223,233,47,70,104,27,32,161],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0],[32,43,204,231,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0],[73,110,118,97,108,105,100,32,115,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[118,32,105,115,32,110,101,105,116,104,101,114,32,50,55,32,110,111,114,32,50,56,0,0,0,0,0,0,0,0,0,0],[117,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[78,111,116,32,101,110,111,117,103,104,32,98,97,108,97,110,99,101,32,102,111,114,32,102,101,101,32,43,32,118,97,108],[78,72,123,113,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,0,0,0,0,0,0],[69,110,99,111,100,105,110,103,32,117,110,115,117,112,112,111,114,116,101,100,32,116,120,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[123,9,174,214,17,35,121,18,1,120,40,210,252,224,88,7,87,230,120,117,80,34,1,169,203,222,160,152,112,237,204,243]],"evm_simulator_code":[[0,20,0,0,0,0,0,2,0,12,0,0,0,0,0,2,0,0,0,0,3,1,0,25,0,0,0,96,7,48,2,112],[0,0,5,8,6,112,1,151,0,19,0,0,0,97,3,85,0,2,0,0,0,97,3,85,0,3,0,0,0,97,3,85],[0,4,0,0,0,97,3,85,0,5,0,0,0,97,3,85,0,6,0,0,0,97,3,85,0,7,0,0,0,97,3,85],[0,8,0,0,0,97,3,85,0,9,0,0,0,97,3,85,0,10,0,0,0,97,3,85,0,11,0,0,0,97,3,85],[0,12,0,0,0,97,3,85,0,13,0,0,0,97,3,85,0,14,0,0,0,97,3,85,0,15,0,0,0,97,3,85],[0,16,0,0,0,97,3,85,0,17,0,0,0,97,3,85,0,18,0,0,0,1,3,85,0,0,5,8,0,112,1,157],[0,0,0,128,4,0,0,57,0,0,0,64,0,64,4,63,0,0,0,1,2,32,1,144,0,0,0,60,0,0,193,61],[0,0,0,4,2,96,0,140,0,0,0,68,0,0,65,61,0,0,0,0,2,1,4,59,0,0,0,224,2,32,2,112],[0,0,5,10,3,32,0,156,0,0,0,84,0,0,161,61,0,0,5,11,3,32,0,156,0,0,0,168,0,0,97,61],[0,0,5,12,3,32,0,156,0,0,0,215,0,0,97,61,0,0,5,13,2,32,0,156,0,0,0,70,0,0,193,61],[0,0,0,4,2,96,0,138,0,0,0,32,3,32,0,140,0,0,1,57,0,0,65,61,0,0,0,4,1,16,3,112],[0,0,0,0,1,1,4,59,0,0,5,16,3,16,0,156,0,0,1,57,0,0,33,61,0,0,0,0,1,18,0,73],[0,0,5,17,2,0,0,65,0,0,2,96,3,16,0,140,0,0,0,0,3,0,0,25,0,0,0,0,3,2,64,25],[0,0,5,17,1,16,1,151,0,0,0,0,4,1,0,75,0,0,0,0,2,0,160,25,0,0,5,17,1,16,0,156],[0,0,0,0,2,3,192,25,0,0,0,0,1,2,0,75,0,0,4,34,0,0,97,61,0,0,1,57,0,0,1,61],[0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75,0,0,1,57,0,0,193,61,0,0,0,32,1,0,0,57],[0,0,1,0,0,16,4,67,0,0,1,32,0,0,4,67,0,0,5,9,1,0,0,65,0,0,20,29,0,1,4,46],[0,0,0,0,1,6,0,75,0,0,4,34,0,0,97,61,0,0,0,0,1,0,4,18,0,0,5,18,1,16,1,151],[0,0,0,0,2,0,4,16,0,0,0,0,1,33,0,75,0,0,4,34,0,0,193,61,0,0,0,0,1,0,4,17],[0,0,128,1,1,16,0,140,0,0,4,34,0,0,193,61,0,0,5,94,1,0,0,65,0,0,0,0,0,16,4,53],[0,0,0,1,1,0,0,57,0,0,0,4,0,16,4,63,0,0,5,95,1,0,0,65,0,0,20,30,0,1,4,48],[0,0,5,14,3,32,0,156,0,0,1,35,0,0,97,61,0,10,0,0,0,4,0,29,0,0,5,15,2,32,0,156],[0,0,0,70,0,0,193,61,0,0,0,4,2,96,0,138,0,0,0,96,2,32,0,140,0,0,1,57,0,0,65,61],[0,0,0,68,2,16,3,112,0,0,0,0,3,2,4,59,0,0,5,16,2,48,0,156,0,0,1,57,0,0,33,61],[0,0,0,4,4,48,0,57,0,0,0,0,5,70,0,73,0,0,5,17,2,0,0,65,0,0,2,96,7,80,0,140],[0,0,0,0,7,0,0,25,0,0,0,0,7,2,64,25,0,0,5,17,8,80,1,151,0,0,0,0,9,8,0,75],[0,0,0,0,2,0,160,25,0,0,5,17,8,128,0,156,0,0,0,0,2,7,192,25,0,0,0,0,2,2,0,75],[0,0,1,57,0,0,193,61,0,0,0,0,2,0,4,17,0,0,128,1,2,32,0,140,0,0,4,34,0,0,193,61],[0,0,0,0,2,0,4,18,0,0,5,18,7,32,1,151,0,0,0,0,2,0,4,16,0,0,0,0,7,39,0,75],[0,0,4,34,0,0,193,61,0,0,2,36,3,48,0,57,0,0,0,0,7,49,3,79,0,0,0,0,7,7,4,59],[0,0,0,31,5,80,0,138,0,0,5,17,8,0,0,65,0,0,0,0,9,87,0,75,0,0,0,0,9,0,0,25],[0,0,0,0,9,8,128,25,0,0,5,17,5,80,1,151,0,0,5,17,10,112,1,151,0,0,0,0,11,90,0,75],[0,0,0,0,8,0,128,25,0,0,0,0,5,90,1,63,0,0,5,17,5,80,0,156,0,0,0,0,8,9,192,25],[0,0,0,0,5,8,0,75,0,0,1,57,0,0,193,61,0,0,0,0,5,71,0,25,0,0,0,0,4,81,3,79],[0,0,0,0,4,4,4,59,0,0,5,16,7,64,0,156,0,0,1,57,0,0,33,61,0,0,0,0,7,70,0,73],[0,0,0,32,5,80,0,57,0,0,5,17,8,0,0,65,0,0,0,0,9,117,0,75,0,0,0,0,9,0,0,25],[0,0,0,0,9,8,32,25,0,0,5,17,7,112,1,151,0,0,5,17,10,80,1,151,0,0,0,0,11,122,0,75],[0,0,0,0,8,0,128,25,0,0,0,0,7,122,1,63,0,0,5,17,7,112,0,156,0,0,0,0,8,9,192,25],[0,0,0,0,7,8,0,75,0,0,1,57,0,0,193,61,0,0,0,3,7,64,0,140,0,0,2,92,0,0,33,61],[0,0,5,22,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63],[0,0,0,58,1,0,0,57,0,0,0,164,0,16,4,63,0,0,5,57,1,0,0,65,0,0,0,196,0,16,4,63],[0,0,5,58,1,0,0,65,0,0,0,228,0,16,4,63,0,0,5,55,1,0,0,65,0,0,20,30,0,1,4,48],[0,0,0,4,2,96,0,138,0,0,0,96,2,32,0,140,0,0,1,57,0,0,65,61,0,0,0,68,2,16,3,112],[0,0,0,0,3,2,4,59,0,0,5,16,2,48,0,156,0,0,1,57,0,0,33,61,0,0,0,4,2,48,0,57],[0,0,0,0,5,38,0,73,0,0,5,17,4,0,0,65,0,0,2,96,8,80,0,140,0,0,0,0,8,0,0,25],[0,0,0,0,8,4,64,25,0,0,5,17,9,80,1,151,0,0,0,0,10,9,0,75,0,0,0,0,4,0,160,25],[0,0,5,17,9,144,0,156,0,0,0,0,4,8,192,25,0,0,0,0,4,4,0,75,0,0,1,57,0,0,193,61],[0,0,0,0,4,0,4,17,0,0,128,1,4,64,0,140,0,0,4,34,0,0,193,61,0,0,0,0,4,0,4,18],[0,0,5,18,4,64,1,151,0,0,0,0,8,0,4,16,0,0,0,0,4,132,0,75,0,0,4,34,0,0,193,61],[0,0,0,68,4,48,0,57,0,0,0,0,4,65,3,79,0,0,1,36,8,48,0,57,0,0,0,0,3,129,3,79],[0,0,0,0,4,4,4,59,0,0,5,18,4,64,1,151,0,0,0,0,3,3,4,59,0,0,5,24,9,48,0,156],[0,0,2,24,0,0,65,61,0,0,5,22,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57],[0,0,0,132,0,16,4,63,0,0,0,8,1,0,0,57,0,0,0,164,0,16,4,63,0,0,5,34,1,0,0,65],[0,0,0,196,0,16,4,63,0,0,5,35,1,0,0,65,0,0,20,30,0,1,4,48,0,0,0,4,3,96,0,138],[0,0,0,96,2,48,0,140,0,0,1,57,0,0,65,61,0,0,0,68,2,16,3,112,0,0,0,0,2,2,4,59],[0,0,5,16,4,32,0,156,0,0,1,57,0,0,33,61,0,0,0,0,3,35,0,73,0,0,5,17,4,0,0,65],[0,0,2,96,5,48,0,140,0,0,0,0,5,0,0,25,0,0,0,0,5,4,64,25,0,0,5,17,3,48,1,151],[0,0,0,0,6,3,0,75,0,0,0,0,4,0,160,25,0,0,5,17,3,48,0,156,0,0,0,0,4,5,192,25],[0,0,0,0,3,4,0,75,0,0,1,57,0,0,193,61,0,0,0,0,3,0,4,17,0,0,128,1,3,48,0,140],[0,0,4,34,0,0,193,61,0,0,0,0,3,0,4,18,0,0,5,18,3,48,1,151,0,0,0,0,4,0,4,16],[0,0,0,0,3,67,0,75,0,0,4,34,0,0,193,61,0,0,0,164,3,32,0,57,0,0,0,0,3,49,3,79],[0,0,0,100,2,32,0,57,0,0,0,0,1,33,3,79,0,0,0,0,1,1,4,59,0,0,0,0,2,3,4,59],[0,0,0,0,3,2,0,75,0,0,2,0,0,0,193,61,0,0,0,0,4,0,4,21,0,0,0,12,4,64,0,138],[0,0,0,5,4,64,2,16,0,0,0,0,1,0,4,20,0,12,0,0,0,0,0,29,0,10,0,0,0,4,0,29],[0,0,5,8,2,0,0,65,0,0,5,8,3,16,0,156,0,0,0,0,1,2,128,25,0,0,0,192,1,16,2,16],[0,0,128,1,2,0,0,57,20,28,20,8,0,0,4,15,0,0,0,10,3,0,0,41,0,19,0,0,0,1,3,85],[0,0,0,96,1,16,2,112,0,1,5,8,0,16,1,157,0,0,0,5,1,48,2,112,0,0,0,1,1,32,1,149],[0,0,0,1,1,32,1,144,0,0,4,34,0,0,193,61,0,0,0,64,1,0,4,61,0,0,0,100,2,16,0,57],[0,0,5,20,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,68,2,16,0,57,0,0,5,21,3,0,0,65],[0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,37,3,0,0,57,0,0,0,0,0,50,4,53],[0,0,5,22,2,0,0,65,0,0,0,0,0,33,4,53,0,0,0,4,2,16,0,57,0,0,0,32,3,0,0,57],[0,0,0,0,0,50,4,53,0,0,5,8,2,0,0,65,0,0,5,8,3,16,0,156,0,0,0,0,1,2,128,25],[0,0,0,64,1,16,2,16,0,0,5,23,1,16,1,199,0,0,20,30,0,1,4,48,0,0,0,4,2,96,0,138],[0,0,0,96,2,32,0,140,0,0,1,57,0,0,65,61,0,0,0,68,2,16,3,112,0,0,0,0,2,2,4,59],[0,10,0,0,0,2,0,29,0,0,5,16,2,32,0,156,0,0,1,57,0,0,33,61,0,0,0,10,2,0,0,41],[0,9,0,4,0,32,0,61,0,0,0,9,2,96,0,106,0,0,5,17,3,0,0,65,0,0,2,96,4,32,0,140],[0,0,0,0,4,0,0,25,0,0,0,0,4,3,64,25,0,0,5,17,2,32,1,151,0,0,0,0,5,2,0,75],[0,0,0,0,3,0,160,25,0,0,5,17,2,32,0,156,0,0,0,0,3,4,192,25,0,0,0,0,2,3,0,75],[0,0,1,59,0,0,97,61,0,0,0,0,1,0,0,25,0,0,20,30,0,1,4,48,0,0,0,36,2,16,3,112],[0,0,0,0,2,2,4,59,0,8,0,0,0,2,0,29,0,0,0,0,2,0,4,17,0,0,128,1,2,32,0,140],[0,0,4,34,0,0,193,61,0,0,0,0,2,0,4,18,0,0,5,18,2,32,1,151,0,0,0,0,3,0,4,16],[0,7,0,0,0,3,0,29,0,0,0,0,2,50,0,75,0,0,4,34,0,0,193,61,0,0,0,0,2,0,4,20],[0,0,5,59,3,0,0,65,0,0,0,160,0,48,4,63,0,0,0,10,3,0,0,41,0,6,1,4,0,48,0,61],[0,0,0,6,1,16,3,96,0,0,0,0,1,1,4,59,0,0,0,164,0,16,4,63,0,0,0,36,1,0,0,57],[0,0,0,128,0,16,4,63,0,0,0,224,1,0,0,57,0,0,0,64,0,16,4,63,0,0,0,192,1,32,2,16],[0,0,5,31,1,16,1,151,0,0,5,60,1,16,1,199,0,0,128,3,2,0,0,57,0,0,0,0,3,0,0,25],[0,0,0,0,4,0,0,25,0,0,0,0,5,0,0,25,0,0,0,0,6,0,0,25,20,28,20,8,0,0,4,15],[0,19,0,0,0,1,3,85,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,1,5,8,0,48,1,157],[0,0,5,8,8,48,1,151,0,0,0,63,3,128,0,57,0,0,5,61,4,48,1,151,0,0,0,64,6,0,4,61],[0,0,0,0,3,100,0,25,0,0,0,0,4,67,0,75,0,0,0,0,4,0,0,25,0,0,0,1,4,0,64,57],[0,0,5,16,5,48,0,156,0,0,19,58,0,0,33,61,0,0,0,1,4,64,1,144,0,0,19,58,0,0,193,61],[0,0,0,64,0,48,4,63,0,0,0,0,7,134,4,54,0,0,0,18,3,0,3,103,0,0,0,0,4,0,0,49],[0,0,0,0,5,67,3,79,0,0,0,31,9,128,0,57,0,0,0,5,9,144,2,114,0,0,1,125,0,0,97,61],[0,0,0,0,10,0,0,25,0,0,0,5,11,160,2,16,0,0,0,0,12,183,0,25,0,0,0,0,11,181,3,79],[0,0,0,0,11,11,4,59,0,0,0,0,0,188,4,53,0,0,0,1,10,160,0,57,0,0,0,0,11,154,0,75],[0,0,1,117,0,0,65,61,0,0,0,0,9,0,0,75,0,0,1,127,0,0,97,61,0,0,0,31,9,128,1,143],[0,0,0,5,8,128,2,114,0,0,1,139,0,0,97,61,0,0,0,0,10,0,0,25,0,0,0,5,11,160,2,16],[0,0,0,0,12,183,0,25,0,0,0,0,11,177,3,79,0,0,0,0,11,11,4,59,0,0,0,0,0,188,4,53],[0,0,0,1,10,160,0,57,0,0,0,0,11,138,0,75,0,0,1,131,0,0,65,61,0,0,0,0,10,9,0,75],[0,0,1,154,0,0,97,61,0,0,0,5,8,128,2,16,0,0,0,0,1,129,3,79,0,0,0,0,8,135,0,25],[0,0,0,3,9,144,2,16,0,0,0,0,10,8,4,51,0,0,0,0,10,154,1,207,0,0,0,0,10,154,2,47],[0,0,0,0,1,1,4,59,0,0,1,0,9,144,0,137,0,0,0,0,1,145,2,47,0,0,0,0,1,145,1,207],[0,0,0,0,1,161,1,159,0,0,0,0,0,24,4,53,0,0,0,1,1,32,1,144,0,0,2,82,0,0,97,61],[0,0,0,8,1,0,0,107,0,0,18,1,0,0,193,61,0,0,0,6,1,0,0,41,0,0,1,0,1,16,0,138],[0,0,0,0,1,19,3,79,0,0,0,0,1,1,4,59,0,0,0,1,2,16,0,140,0,0,2,111,0,0,33,61],[0,0,0,0,2,1,0,75,0,0,2,196,0,0,97,61,0,0,0,1,1,16,0,140,0,0,2,178,0,0,193,61],[0,0,5,62,1,0,0,65,0,0,0,0,0,16,4,57,0,0,5,8,1,0,0,65,0,0,0,0,2,0,4,20],[0,0,5,8,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,5,63,1,16,1,199],[0,0,128,11,2,0,0,57,20,28,20,13,0,0,4,15,0,0,0,1,2,32,1,144,0,0,18,65,0,0,97,61],[0,0,0,64,3,0,4,61,0,0,0,0,4,1,4,59,0,0,0,128,1,64,0,140,0,0,4,63,0,0,65,61],[0,0,0,128,1,64,2,112,0,0,5,66,2,64,0,156,0,0,0,0,1,4,160,25,0,0,5,66,2,64,0,156],[0,0,0,0,2,0,0,25,0,0,0,16,2,0,32,57,0,0,0,8,5,32,1,191,0,0,5,16,6,16,0,156],[0,0,0,0,5,2,160,25,0,0,0,64,2,16,2,112,0,0,5,16,6,16,0,156,0,0,0,0,2,1,160,25],[0,0,0,4,1,80,1,191,0,0,5,8,6,32,0,156,0,0,0,0,1,5,160,25,0,0,0,32,6,32,2,112],[0,0,5,8,5,32,0,156,0,0,0,0,6,2,160,25,0,0,0,2,5,16,1,191,0,0,255,255,2,96,0,140],[0,0,0,0,5,1,160,25,0,0,0,16,1,96,2,112,0,0,0,0,1,6,160,25,0,0,0,255,1,16,0,140],[0,0,0,1,5,80,32,57,0,0,0,32,1,0,0,138,0,0,0,65,2,80,0,57,0,0,0,0,1,18,1,111],[0,0,0,0,1,19,0,25,0,0,0,0,2,49,0,75,0,0,0,0,2,0,0,25,0,0,0,1,2,0,64,57],[0,0,5,16,6,16,0,156,0,0,19,58,0,0,33,61,0,0,0,1,2,32,1,144,0,0,19,58,0,0,193,61],[0,0,0,64,0,16,4,63,0,0,0,2,1,80,0,57,0,0,0,0,6,19,4,54,0,0,0,18,1,0,3,103],[0,0,0,0,2,0,0,49,0,0,0,33,7,80,0,57,0,0,0,5,7,112,2,114,0,0,1,238,0,0,97,61],[0,0,0,0,8,33,3,79,0,0,0,0,9,0,0,25,0,0,0,5,10,144,2,16,0,0,0,0,11,166,0,25],[0,0,0,0,10,168,3,79,0,0,0,0,10,10,4,59,0,0,0,0,0,171,4,53,0,0,0,1,9,144,0,57],[0,0,0,0,10,121,0,75,0,0,1,230,0,0,65,61,0,0,0,0,7,0,0,75,0,0,1,240,0,0,97,61],[0,0,0,0,7,3,4,51,0,0,0,0,7,7,0,75,0,0,9,198,0,0,97,61,0,0,0,0,7,6,4,51],[0,0,5,65,7,112,1,151,0,0,0,248,8,80,2,16,0,0,0,0,7,120,1,159,0,0,5,67,7,112,0,65],[0,0,0,0,0,118,4,53,0,0,0,3,5,80,2,16,0,0,0,248,5,80,0,137,0,0,0,0,4,84,1,207],[0,0,0,255,5,80,0,140,0,0,0,0,4,0,32,25,0,0,0,33,5,48,0,57,0,0,4,81,0,0,1,61],[0,0,0,0,67,18,0,169,0,0,0,0,66,35,0,217,0,0,0,0,1,18,0,75,0,0,18,29,0,0,193,61],[0,0,0,0,4,0,4,21,0,0,0,11,4,64,0,138,0,0,0,5,4,64,2,16,0,0,0,0,1,0,4,20],[0,11,0,0,0,0,0,29,0,0,0,0,2,3,0,75,0,0,0,255,0,0,97,61,0,0,5,8,2,0,0,65],[0,0,5,8,4,16,0,156,0,0,0,0,1,2,128,25,0,0,0,192,1,16,2,16,0,0,5,19,1,16,1,199],[0,0,128,9,2,0,0,57,0,0,128,1,4,0,0,57,0,0,0,0,5,0,0,25,20,28,20,8,0,0,4,15],[0,0,0,0,3,0,4,21,0,0,0,11,3,48,0,138,0,0,0,5,3,48,2,16,0,0,1,7,0,0,1,61],[0,0,0,160,8,128,0,57,0,0,0,0,8,129,3,79,0,0,0,0,8,8,4,59,0,0,0,31,5,80,0,138],[0,0,5,17,9,0,0,65,0,0,0,0,10,88,0,75,0,0,0,0,10,0,0,25,0,0,0,0,10,9,128,25],[0,0,5,17,5,80,1,151,0,0,5,17,11,128,1,151,0,0,0,0,12,91,0,75,0,0,0,0,9,0,128,25],[0,0,0,0,5,91,1,63,0,0,5,17,5,80,0,156,0,0,0,0,9,10,192,25,0,0,0,0,5,9,0,75],[0,0,1,57,0,0,193,61,0,0,0,0,2,40,0,25,0,0,0,0,5,33,3,79,0,0,0,0,8,5,4,59],[0,0,5,16,5,128,0,156,0,0,1,57,0,0,33,61,0,0,0,0,5,134,0,73,0,0,0,32,9,32,0,57],[0,0,5,17,2,0,0,65,0,0,0,0,10,89,0,75,0,0,0,0,10,0,0,25,0,0,0,0,10,2,32,25],[0,0,5,17,5,80,1,151,0,0,5,17,11,144,1,151,0,0,0,0,12,91,0,75,0,0,0,0,2,0,128,25],[0,0,0,0,5,91,1,63,0,0,5,17,5,80,0,156,0,0,0,0,2,10,192,25,0,0,0,0,2,2,0,75],[0,0,1,57,0,0,193,61,0,0,0,0,2,0,4,20,0,0,5,8,5,32,0,156,0,0,0,205,0,0,33,61],[0,0,128,6,5,64,0,140,0,0,0,0,5,0,0,25,0,0,3,243,0,0,193,61,0,0,0,4,5,128,0,140],[0,0,0,0,5,0,0,25,0,0,3,243,0,0,65,61,0,0,0,0,10,145,3,79,0,0,0,1,5,0,0,57],[0,0,0,0,10,10,4,59,0,0,5,25,10,160,1,151,0,0,5,26,11,160,0,156,0,0,3,239,0,0,33,61],[0,0,5,29,11,160,0,156,0,0,3,243,0,0,97,61,0,0,5,30,10,160,0,156,0,0,3,243,0,0,97,61],[0,0,0,0,5,0,0,25,0,0,3,243,0,0,1,61,0,0,0,0,1,6,4,51,0,0,5,8,2,0,0,65],[0,0,5,8,3,16,0,156,0,0,0,0,1,2,128,25,0,0,5,8,3,112,0,156,0,0,0,0,7,2,128,25],[0,0,0,64,2,112,2,16,0,0,0,96,1,16,2,16,0,0,0,0,1,33,1,159,0,0,20,30,0,1,4,48],[0,0,0,0,7,81,3,79,0,0,0,0,7,7,4,59,0,0,5,25,7,112,1,151,0,0,5,36,8,112,0,156],[0,0,4,34,0,0,97,61,0,0,5,37,7,112,0,156,0,0,3,106,0,0,193,61,0,0,0,67,4,64,0,140],[0,0,3,208,0,0,33,61,0,0,5,22,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57],[0,0,0,132,0,16,4,63,0,0,0,64,1,0,0,57,0,0,0,164,0,16,4,63,0,0,5,53,1,0,0,65],[0,0,0,196,0,16,4,63,0,0,5,54,1,0,0,65,0,0,0,165,0,0,1,61,0,0,0,2,2,16,0,140],[0,0,3,18,0,0,97,61,0,0,0,113,1,16,0,140,0,0,2,178,0,0,193,61,0,0,0,10,2,0,0,41],[0,0,1,196,1,32,0,57,0,0,0,0,1,19,3,79,0,0,0,0,2,36,0,73,0,0,0,35,2,32,0,138],[0,0,0,0,1,1,4,59,0,0,5,17,5,0,0,65,0,0,0,0,6,33,0,75,0,0,0,0,6,0,0,25],[0,0,0,0,6,5,128,25,0,0,5,17,2,32,1,151,0,0,5,17,7,16,1,151,0,0,0,0,8,39,0,75],[0,0,0,0,5,0,128,25,0,0,0,0,2,39,1,63,0,0,5,17,2,32,0,156,0,0,0,0,5,6,192,25],[0,0,0,0,2,5,0,75,0,0,1,57,0,0,193,61,0,0,0,9,2,16,0,41,0,0,0,0,1,35,3,79],[0,0,0,0,1,1,4,59,0,0,5,16,5,16,0,156,0,0,1,57,0,0,33,61,0,0,0,0,6,20,0,73],[0,0,0,32,5,32,0,57,0,0,5,17,2,0,0,65,0,0,0,0,7,101,0,75,0,0,0,0,7,0,0,25],[0,0,0,0,7,2,32,25,0,0,5,17,6,96,1,151,0,0,5,17,8,80,1,151,0,0,0,0,9,104,0,75],[0,0,0,0,2,0,128,25,0,0,0,0,6,104,1,63,0,0,5,17,6,96,0,156,0,0,0,0,2,7,192,25],[0,0,0,0,2,2,0,75,0,0,1,57,0,0,193,61,0,0,5,8,6,80,1,151,0,0,0,0,2,0,4,20],[0,2,0,0,0,99,3,85,0,0,0,0,5,81,0,25,0,0,0,0,1,21,0,75,0,0,0,0,1,0,0,25],[0,0,0,1,1,0,64,57,0,0,0,1,1,16,1,144,0,0,18,29,0,0,193,61,0,0,0,0,1,84,0,75],[0,0,18,29,0,0,65,61,0,0,0,0,1,99,3,79,0,0,0,0,3,84,0,73,0,0,5,8,3,48,1,151],[0,2,0,0,0,49,3,229,0,0,5,73,4,32,0,156,0,0,6,137,0,0,65,61,0,0,0,64,1,0,4,61],[0,0,0,68,2,16,0,57,0,0,5,34,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57],[0,0,0,8,3,0,0,57,0,0,2,184,0,0,1,61,0,0,0,64,1,0,4,61,0,0,0,68,2,16,0,57],[0,0,5,96,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,23,3,0,0,57],[0,0,0,0,0,50,4,53,0,0,5,22,2,0,0,65,0,0,0,0,0,33,4,53,0,0,0,4,2,16,0,57],[0,0,0,32,3,0,0,57,0,0,0,0,0,50,4,53,0,0,5,8,2,0,0,65,0,0,5,8,3,16,0,156],[0,0,0,0,1,2,128,25,0,0,0,64,1,16,2,16,0,0,5,52,1,16,1,199,0,0,20,30,0,1,4,48],[0,0,0,6,1,48,3,96,0,0,0,64,2,0,4,61,0,8,0,0,0,2,0,29,0,0,0,0,1,1,4,59],[0,0,0,128,2,16,0,140,0,0,3,114,0,0,65,61,0,0,0,128,2,16,2,112,0,0,5,66,6,16,0,156],[0,0,0,0,2,1,160,25,0,0,5,66,6,16,0,156,0,0,0,0,6,0,0,25,0,0,0,16,6,0,32,57],[0,0,0,8,7,96,1,191,0,0,5,16,8,32,0,156,0,0,0,0,7,6,160,25,0,0,0,64,6,32,2,112],[0,0,5,16,8,32,0,156,0,0,0,0,6,2,160,25,0,0,0,4,8,112,1,191,0,0,5,8,2,96,0,156],[0,0,0,0,8,7,160,25,0,0,0,32,7,96,2,112,0,0,5,8,2,96,0,156,0,0,0,0,7,6,160,25],[0,0,0,2,2,128,1,191,0,0,255,255,6,112,0,140,0,0,0,0,2,8,160,25,0,0,0,16,6,112,2,112],[0,0,0,0,6,7,160,25,0,0,0,255,6,96,0,140,0,0,0,1,2,32,32,57,0,0,0,32,6,0,0,138],[0,0,0,65,7,32,0,57,0,0,0,0,6,103,1,111,0,0,0,8,6,96,0,41,0,0,0,8,7,96,0,108],[0,0,0,0,7,0,0,25,0,0,0,1,7,0,64,57,0,0,5,16,8,96,0,156,0,0,19,58,0,0,33,61],[0,0,0,1,7,112,1,144,0,0,19,58,0,0,193,61,0,0,0,64,0,96,4,63,0,0,0,2,6,32,0,57],[0,0,0,8,7,0,0,41,0,0,0,0,6,103,4,54,0,0,0,33,7,32,0,57,0,0,0,5,7,112,2,114],[0,0,2,254,0,0,97,61,0,0,0,0,8,0,0,25,0,0,0,5,9,128,2,16,0,0,0,0,10,150,0,25],[0,0,0,0,9,149,3,79,0,0,0,0,9,9,4,59,0,0,0,0,0,154,4,53,0,0,0,1,8,128,0,57],[0,0,0,0,9,120,0,75,0,0,2,246,0,0,65,61,0,0,0,0,7,0,0,75,0,0,3,0,0,0,97,61],[0,0,0,8,7,0,0,41,0,0,0,0,7,7,4,51,0,0,0,0,7,7,0,75,0,0,9,198,0,0,97,61],[0,0,0,0,7,6,4,51,0,0,5,65,7,112,1,151,0,0,0,248,8,32,2,16,0,0,0,0,7,120,1,159],[0,0,5,67,7,112,0,65,0,0,0,0,0,118,4,53,0,0,0,3,2,32,2,16,0,0,0,248,2,32,0,137],[0,0,0,0,1,33,1,207,0,0,0,255,2,32,0,140,0,0,0,0,1,0,32,25,0,0,0,8,2,0,0,41],[0,0,0,33,2,32,0,57,0,0,3,131,0,0,1,61,0,0,5,62,1,0,0,65,0,0,0,0,0,16,4,57],[0,0,5,8,1,0,0,65,0,0,0,0,2,0,4,20,0,0,5,8,3,32,0,156,0,0,0,0,2,1,128,25],[0,0,0,192,1,32,2,16,0,0,5,63,1,16,1,199,0,0,128,11,2,0,0,57,20,28,20,13,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,18,65,0,0,97,61,0,0,0,64,3,0,4,61,0,0,0,0,4,1,4,59],[0,0,0,128,1,64,0,140,0,0,4,157,0,0,65,61,0,0,0,128,1,64,2,112,0,0,5,66,2,64,0,156],[0,0,0,0,1,4,160,25,0,0,5,66,2,64,0,156,0,0,0,0,2,0,0,25,0,0,0,16,2,0,32,57],[0,0,0,8,5,32,1,191,0,0,5,16,6,16,0,156,0,0,0,0,5,2,160,25,0,0,0,64,2,16,2,112],[0,0,5,16,6,16,0,156,0,0,0,0,2,1,160,25,0,0,0,4,1,80,1,191,0,0,5,8,6,32,0,156],[0,0,0,0,1,5,160,25,0,0,0,32,6,32,2,112,0,0,5,8,5,32,0,156,0,0,0,0,6,2,160,25],[0,0,0,2,5,16,1,191,0,0,255,255,2,96,0,140,0,0,0,0,5,1,160,25,0,0,0,16,1,96,2,112],[0,0,0,0,1,6,160,25,0,0,0,255,1,16,0,140,0,0,0,1,5,80,32,57,0,0,0,32,1,0,0,138],[0,0,0,65,2,80,0,57,0,0,0,0,1,18,1,111,0,0,0,0,1,19,0,25,0,0,0,0,2,49,0,75],[0,0,0,0,2,0,0,25,0,0,0,1,2,0,64,57,0,0,5,16,6,16,0,156,0,0,19,58,0,0,33,61],[0,0,0,1,2,32,1,144,0,0,19,58,0,0,193,61,0,0,0,64,0,16,4,63,0,0,0,2,1,80,0,57],[0,0,0,0,6,19,4,54,0,0,0,18,1,0,3,103,0,0,0,0,2,0,0,49,0,0,0,33,7,80,0,57],[0,0,0,5,7,112,2,114,0,0,3,88,0,0,97,61,0,0,0,0,8,33,3,79,0,0,0,0,9,0,0,25],[0,0,0,5,10,144,2,16,0,0,0,0,11,166,0,25,0,0,0,0,10,168,3,79,0,0,0,0,10,10,4,59],[0,0,0,0,0,171,4,53,0,0,0,1,9,144,0,57,0,0,0,0,10,121,0,75,0,0,3,80,0,0,65,61],[0,0,0,0,7,0,0,75,0,0,3,90,0,0,97,61,0,0,0,0,7,3,4,51,0,0,0,0,7,7,0,75],[0,0,9,198,0,0,97,61,0,0,0,0,7,6,4,51,0,0,5,65,7,112,1,151,0,0,0,248,8,80,2,16],[0,0,0,0,7,120,1,159,0,0,5,67,7,112,0,65,0,0,0,0,0,118,4,53,0,0,0,3,5,80,2,16],[0,0,0,248,5,80,0,137,0,0,0,0,4,84,1,207,0,0,0,255,5,80,0,140,0,0,0,0,4,0,32,25],[0,0,0,33,5,48,0,57,0,0,4,175,0,0,1,61,0,0,5,22,1,0,0,65,0,0,0,128,0,16,4,63],[0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63,0,0,0,26,1,0,0,57,0,0,0,164,0,16,4,63],[0,0,5,56,1,0,0,65,0,0,0,212,0,0,1,61,0,0,0,8,2,0,0,41,0,0,5,64,2,32,0,156],[0,0,19,58,0,0,33,61,0,0,0,8,6,0,0,41,0,0,0,64,2,96,0,57,0,0,0,64,0,32,4,63],[0,0,0,1,2,0,0,58,0,0,0,0,2,38,4,54,0,0,0,0,6,5,4,59,0,0,0,0,0,98,4,53],[0,0,9,198,0,0,97,61,0,0,0,248,7,16,2,16,0,0,5,17,8,0,0,65,0,0,0,0,1,1,0,75],[0,0,0,0,8,7,192,25,0,0,5,65,1,96,1,151,0,0,0,0,1,129,1,159,0,0,0,0,0,18,4,53],[0,0,0,64,1,0,4,61,0,0,0,6,2,0,0,41,0,0,0,96,2,32,0,138,0,0,0,0,6,35,3,79],[0,0,0,0,6,6,4,59,0,0,0,128,7,96,0,140,0,0,4,251,0,0,65,61,0,0,0,128,7,96,2,112],[0,0,5,66,8,96,0,156,0,0,0,0,7,6,160,25,0,0,5,66,8,96,0,156,0,0,0,0,8,0,0,25],[0,0,0,16,8,0,32,57,0,0,0,8,9,128,1,191,0,0,5,16,10,112,0,156,0,0,0,0,9,8,160,25],[0,0,0,64,8,112,2,112,0,0,5,16,10,112,0,156,0,0,0,0,8,7,160,25,0,0,0,4,10,144,1,191],[0,0,5,8,7,128,0,156,0,0,0,0,10,9,160,25,0,0,0,32,9,128,2,112,0,0,5,8,7,128,0,156],[0,0,0,0,9,8,160,25,0,0,0,2,7,160,1,191,0,0,255,255,8,144,0,140,0,0,0,0,7,10,160,25],[0,0,0,16,8,144,2,112,0,0,0,0,8,9,160,25,0,0,0,255,8,128,0,140,0,0,0,1,7,112,32,57],[0,0,0,32,8,0,0,138,0,0,0,65,9,112,0,57,0,0,0,0,8,137,1,111,0,0,0,0,8,129,0,25],[0,0,0,0,9,24,0,75,0,0,0,0,9,0,0,25,0,0,0,1,9,0,64,57,0,0,5,16,10,128,0,156],[0,0,19,58,0,0,33,61,0,0,0,1,9,144,1,144,0,0,19,58,0,0,193,61,0,0,0,64,0,128,4,63],[0,0,0,2,8,112,0,57,0,0,0,0,8,129,4,54,0,0,0,33,9,112,0,57,0,0,0,5,9,144,2,114],[0,0,3,190,0,0,97,61,0,0,0,0,10,0,0,25,0,0,0,5,11,160,2,16,0,0,0,0,12,184,0,25],[0,0,0,0,11,181,3,79,0,0,0,0,11,11,4,59,0,0,0,0,0,188,4,53,0,0,0,1,10,160,0,57],[0,0,0,0,11,154,0,75,0,0,3,182,0,0,65,61,0,0,0,0,9,0,0,75,0,0,3,192,0,0,97,61],[0,0,0,0,9,1,4,51,0,0,0,0,9,9,0,75,0,0,9,198,0,0,97,61,0,0,0,0,9,8,4,51],[0,0,5,65,9,144,1,151,0,0,0,248,10,112,2,16,0,0,0,0,9,154,1,159,0,0,5,67,9,144,0,65],[0,0,0,0,0,152,4,53,0,0,0,3,7,112,2,16,0,0,0,248,7,112,0,137,0,0,0,0,6,118,1,207],[0,0,0,255,7,112,0,140,0,0,0,0,6,0,32,25,0,0,0,33,7,16,0,57,0,0,5,10,0,0,1,61],[0,0,0,4,4,80,0,57,0,0,0,0,5,65,3,79,0,0,0,0,5,5,4,59,0,9,0,0,0,5,0,29],[0,0,5,18,5,80,0,156,0,0,1,57,0,0,33,61,0,0,1,64,3,48,0,138,0,0,0,0,3,49,3,79],[0,0,0,32,4,64,0,57,0,0,0,0,4,65,3,79,0,0,0,0,4,4,4,59,0,8,0,0,0,4,0,29],[0,0,0,0,3,3,4,59,0,0,5,38,4,0,0,65,0,0,0,128,0,64,4,63,0,0,5,18,2,32,1,151],[0,6,0,0,0,2,0,29,0,0,0,132,0,32,4,63,0,0,5,18,2,48,1,151,0,7,0,0,0,2,0,29],[0,0,0,164,0,32,4,63,0,0,0,0,2,0,4,20,0,0,0,9,3,0,0,41,0,0,0,4,3,48,0,140],[0,0,5,86,0,0,193,61,0,0,0,0,1,97,3,79,0,0,0,1,3,0,0,49,0,0,0,32,2,48,0,140],[0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57,0,0,5,130,0,0,1,61,0,0,5,27,11,160,0,156],[0,0,3,243,0,0,97,61,0,0,5,28,10,160,0,156,0,0,0,0,5,0,192,25,0,0,0,0,10,152,0,25],[0,0,0,0,6,166,0,75,0,0,0,0,6,0,0,25,0,0,0,1,6,0,64,57,0,0,0,0,8,138,0,75],[0,0,0,1,6,96,65,191,0,0,5,8,8,144,1,151,0,2,0,0,0,129,3,85,0,0,0,0,1,129,3,79],[0,0,0,0,8,3,0,75,0,0,4,14,0,0,193,61,0,0,0,1,3,96,1,144,0,0,18,29,0,0,193,61],[0,0,5,32,3,0,0,65,0,0,5,33,6,0,0,65,0,0,0,0,5,5,0,75,0,0,0,0,6,3,192,25],[0,0,0,192,2,32,2,16,0,0,5,31,2,32,1,151,0,0,0,0,2,38,1,159,0,0,0,0,3,167,0,73],[0,0,5,8,3,48,1,151,0,0,0,0,1,49,3,223,0,2,0,0,0,33,3,181,0,0,0,0,1,33,3,175],[0,0,0,0,2,4,0,25,0,0,4,26,0,0,1,61,0,0,0,1,6,96,1,144,0,0,18,29,0,0,193,61],[0,0,0,0,6,167,0,73,0,0,5,8,6,96,1,151,0,0,0,0,1,97,3,223,0,0,0,192,2,32,2,16],[0,0,5,31,2,32,1,151,0,0,5,32,2,32,1,199,0,2,0,0,0,33,3,181,0,0,0,0,1,33,3,175],[0,0,128,9,2,0,0,57,0,0,0,0,6,0,0,25,20,28,20,18,0,0,4,15,0,19,0,0,0,1,3,85],[0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,1,5,8,0,48,1,157,0,0,5,8,3,48,1,151],[0,0,0,1,2,32,1,144,0,0,4,36,0,0,97,61,0,0,0,0,1,0,0,25,0,0,20,29,0,1,4,46],[0,0,0,31,4,48,1,143,0,0,0,5,2,48,2,114,0,0,4,47,0,0,97,61,0,0,0,0,5,0,0,25],[0,0,0,5,6,80,2,16,0,0,0,0,7,97,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,118,4,53],[0,0,0,1,5,80,0,57,0,0,0,0,6,37,0,75,0,0,4,40,0,0,65,61,0,0,0,0,5,4,0,75],[0,0,4,61,0,0,97,61,0,0,0,3,4,64,2,16,0,0,0,5,2,32,2,16,0,0,0,0,5,2,4,51],[0,0,0,0,5,69,1,207,0,0,0,0,5,69,2,47,0,0,0,0,1,33,3,79,0,0,0,0,1,1,4,59],[0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,81,1,159],[0,0,0,0,0,18,4,53,0,0,0,96,1,48,2,16,0,0,20,30,0,1,4,48,0,0,5,64,1,48,0,156],[0,0,19,58,0,0,33,61,0,0,0,64,1,48,0,57,0,0,0,64,0,16,4,63,0,0,0,1,1,0,0,58],[0,0,0,0,5,19,4,54,0,0,0,0,2,0,0,49,0,0,0,18,1,0,3,103,0,0,0,0,6,33,3,79],[0,0,0,0,6,6,4,59,0,0,0,0,0,101,4,53,0,0,9,198,0,0,97,61,0,0,0,248,7,64,2,16],[0,0,5,17,8,0,0,65,0,0,0,0,4,4,0,75,0,0,0,0,8,7,192,25,0,0,5,65,4,96,1,151],[0,0,0,0,4,132,1,159,0,0,0,0,0,69,4,53,0,0,0,6,5,16,3,96,0,0,0,64,4,0,4,61],[0,0,0,0,5,5,4,59,0,0,0,128,6,80,0,140,0,0,5,170,0,0,65,61,0,0,0,128,6,80,2,112],[0,0,5,66,7,80,0,156,0,0,0,0,6,5,160,25,0,0,5,66,7,80,0,156,0,0,0,0,7,0,0,25],[0,0,0,16,7,0,32,57,0,0,0,8,8,112,1,191,0,0,5,16,9,96,0,156,0,0,0,0,8,7,160,25],[0,0,0,64,7,96,2,112,0,0,5,16,9,96,0,156,0,0,0,0,7,6,160,25,0,0,0,4,9,128,1,191],[0,0,5,8,6,112,0,156,0,0,0,0,9,8,160,25,0,0,0,32,8,112,2,112,0,0,5,8,6,112,0,156],[0,0,0,0,8,7,160,25,0,0,0,2,6,144,1,191,0,0,255,255,7,128,0,140,0,0,0,0,6,9,160,25],[0,0,0,16,7,128,2,112,0,0,0,0,7,8,160,25,0,0,0,255,7,112,0,140,0,0,0,1,6,96,32,57],[0,0,0,32,7,0,0,138,0,0,0,65,8,96,0,57,0,0,0,0,7,120,1,111,0,0,0,0,7,116,0,25],[0,0,0,0,8,71,0,75,0,0,0,0,8,0,0,25,0,0,0,1,8,0,64,57,0,0,5,16,9,112,0,156],[0,0,19,58,0,0,33,61,0,0,0,1,8,128,1,144,0,0,19,58,0,0,193,61,0,0,0,64,0,112,4,63],[0,0,0,2,7,96,0,57,0,0,0,0,7,116,4,54,0,0,0,33,8,96,0,57,0,0,0,5,8,128,2,114],[0,0,4,139,0,0,97,61,0,0,0,0,9,33,3,79,0,0,0,0,10,0,0,25,0,0,0,5,11,160,2,16],[0,0,0,0,12,183,0,25,0,0,0,0,11,185,3,79,0,0,0,0,11,11,4,59,0,0,0,0,0,188,4,53],[0,0,0,1,10,160,0,57,0,0,0,0,11,138,0,75,0,0,4,131,0,0,65,61,0,0,0,0,8,0,0,75],[0,0,4,141,0,0,97,61,0,0,0,0,8,4,4,51,0,0,0,0,8,8,0,75,0,0,9,198,0,0,97,61],[0,0,0,0,8,7,4,51,0,0,5,65,8,128,1,151,0,0,0,248,9,96,2,16,0,0,0,0,8,137,1,159],[0,0,5,67,8,128,0,65,0,0,0,0,0,135,4,53,0,0,0,3,6,96,2,16,0,0,0,248,6,96,0,137],[0,0,0,0,5,101,1,207,0,0,0,255,6,96,0,140,0,0,0,0,5,0,32,25,0,0,0,33,6,64,0,57],[0,0,5,186,0,0,1,61,0,0,5,64,1,48,0,156,0,0,19,58,0,0,33,61,0,0,0,64,1,48,0,57],[0,0,0,64,0,16,4,63,0,0,0,1,1,0,0,58,0,0,0,0,5,19,4,54,0,0,0,0,2,0,0,49],[0,0,0,18,1,0,3,103,0,0,0,0,6,33,3,79,0,0,0,0,6,6,4,59,0,0,0,0,0,101,4,53],[0,0,9,198,0,0,97,61,0,0,0,248,7,64,2,16,0,0,5,17,8,0,0,65,0,0,0,0,4,4,0,75],[0,0,0,0,8,7,192,25,0,0,5,65,4,96,1,151,0,0,0,0,4,132,1,159,0,0,0,0,0,69,4,53],[0,0,0,6,5,16,3,96,0,0,0,64,4,0,4,61,0,0,0,0,5,5,4,59,0,0,0,128,6,80,0,140],[0,0,6,8,0,0,65,61,0,0,0,128,6,80,2,112,0,0,5,66,7,80,0,156,0,0,0,0,6,5,160,25],[0,0,5,66,7,80,0,156,0,0,0,0,7,0,0,25,0,0,0,16,7,0,32,57,0,0,0,8,8,112,1,191],[0,0,5,16,9,96,0,156,0,0,0,0,8,7,160,25,0,0,0,64,7,96,2,112,0,0,5,16,9,96,0,156],[0,0,0,0,7,6,160,25,0,0,0,4,9,128,1,191,0,0,5,8,6,112,0,156,0,0,0,0,9,8,160,25],[0,0,0,32,8,112,2,112,0,0,5,8,6,112,0,156,0,0,0,0,8,7,160,25,0,0,0,2,6,144,1,191],[0,0,255,255,7,128,0,140,0,0,0,0,6,9,160,25,0,0,0,16,7,128,2,112,0,0,0,0,7,8,160,25],[0,0,0,255,7,112,0,140,0,0,0,1,6,96,32,57,0,0,0,32,7,0,0,138,0,0,0,65,8,96,0,57],[0,0,0,0,7,120,1,111,0,0,0,0,7,116,0,25,0,0,0,0,8,71,0,75,0,0,0,0,8,0,0,25],[0,0,0,1,8,0,64,57,0,0,5,16,9,112,0,156,0,0,19,58,0,0,33,61,0,0,0,1,8,128,1,144],[0,0,19,58,0,0,193,61,0,0,0,64,0,112,4,63,0,0,0,2,7,96,0,57,0,0,0,0,7,116,4,54],[0,0,0,33,8,96,0,57,0,0,0,5,8,128,2,114,0,0,4,233,0,0,97,61,0,0,0,0,9,33,3,79],[0,0,0,0,10,0,0,25,0,0,0,5,11,160,2,16,0,0,0,0,12,183,0,25,0,0,0,0,11,185,3,79],[0,0,0,0,11,11,4,59,0,0,0,0,0,188,4,53,0,0,0,1,10,160,0,57,0,0,0,0,11,138,0,75],[0,0,4,225,0,0,65,61,0,0,0,0,8,0,0,75,0,0,4,235,0,0,97,61,0,0,0,0,8,4,4,51],[0,0,0,0,8,8,0,75,0,0,9,198,0,0,97,61,0,0,0,0,8,7,4,51,0,0,5,65,8,128,1,151],[0,0,0,248,9,96,2,16,0,0,0,0,8,137,1,159,0,0,5,67,8,128,0,65,0,0,0,0,0,135,4,53],[0,0,0,3,6,96,2,16,0,0,0,248,6,96,0,137,0,0,0,0,5,101,1,207,0,0,0,255,6,96,0,140],[0,0,0,0,5,0,32,25,0,0,0,33,6,64,0,57,0,0,6,24,0,0,1,61,0,0,5,64,7,16,0,156],[0,0,19,58,0,0,33,61,0,0,0,64,7,16,0,57,0,0,0,64,0,112,4,63,0,0,0,1,7,0,0,58],[0,0,0,0,7,113,4,54,0,0,0,0,8,5,4,59,0,0,0,0,0,135,4,53,0,0,9,198,0,0,97,61],[0,0,0,248,9,96,2,16,0,0,5,17,10,0,0,65,0,0,0,0,6,6,0,75,0,0,0,0,10,9,192,25],[0,0,5,65,6,128,1,151,0,0,0,0,6,166,1,159,0,0,0,0,0,103,4,53,0,0,0,64,2,32,0,138],[0,0,0,0,6,35,3,79,0,0,0,64,2,0,4,61,0,0,0,0,6,6,4,59,0,0,0,128,7,96,0,140],[0,0,8,96,0,0,65,61,0,0,0,128,7,96,2,112,0,0,5,66,8,96,0,156,0,0,0,0,7,6,160,25],[0,0,5,66,8,96,0,156,0,0,0,0,8,0,0,25,0,0,0,16,8,0,32,57,0,0,0,8,9,128,1,191],[0,0,5,16,10,112,0,156,0,0,0,0,9,8,160,25,0,0,0,64,8,112,2,112,0,0,5,16,10,112,0,156],[0,0,0,0,8,7,160,25,0,0,0,4,10,144,1,191,0,0,5,8,7,128,0,156,0,0,0,0,10,9,160,25],[0,0,0,32,9,128,2,112,0,0,5,8,7,128,0,156,0,0,0,0,9,8,160,25,0,0,0,2,7,160,1,191],[0,0,255,255,8,144,0,140,0,0,0,0,7,10,160,25,0,0,0,16,8,144,2,112,0,0,0,0,8,9,160,25],[0,0,0,255,8,128,0,140,0,0,0,1,7,112,32,57,0,0,0,32,8,0,0,138,0,0,0,65,9,112,0,57],[0,0,0,0,8,137,1,111,0,0,0,0,8,130,0,25,0,0,0,0,9,40,0,75,0,0,0,0,9,0,0,25],[0,0,0,1,9,0,64,57,0,0,5,16,10,128,0,156,0,0,19,58,0,0,33,61,0,0,0,1,9,144,1,144],[0,0,19,58,0,0,193,61,0,0,0,64,0,128,4,63,0,0,0,2,8,112,0,57,0,0,0,0,8,130,4,54],[0,0,0,33,9,112,0,57,0,0,0,5,9,144,2,114,0,0,5,68,0,0,97,61,0,0,0,0,10,0,0,25],[0,0,0,5,11,160,2,16,0,0,0,0,12,184,0,25,0,0,0,0,11,181,3,79,0,0,0,0,11,11,4,59],[0,0,0,0,0,188,4,53,0,0,0,1,10,160,0,57,0,0,0,0,11,154,0,75,0,0,5,60,0,0,65,61],[0,0,0,0,9,0,0,75,0,0,5,70,0,0,97,61,0,0,0,0,9,2,4,51,0,0,0,0,9,9,0,75],[0,0,9,198,0,0,97,61,0,0,0,0,9,8,4,51,0,0,5,65,9,144,1,151,0,0,0,248,10,112,2,16],[0,0,0,0,9,154,1,159,0,0,5,67,9,144,0,65,0,0,0,0,0,152,4,53,0,0,0,3,7,112,2,16],[0,0,0,248,7,112,0,137,0,0,0,0,6,118,1,207,0,0,0,255,7,112,0,140,0,0,0,0,6,0,32,25],[0,0,0,33,7,32,0,57,0,0,8,111,0,0,1,61,0,0,5,8,1,0,0,65,0,0,5,8,3,32,0,156],[0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,5,39,1,16,1,199,0,0,0,9,2,0,0,41],[20,28,20,13,0,0,4,15,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,5,8,3,48,1,151],[0,0,0,32,4,48,0,140,0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57,0,0,0,31,5,64,1,143],[0,0,0,5,6,64,2,114,0,0,5,111,0,0,97,61,0,0,0,0,7,0,0,25,0,0,0,5,8,112,2,16],[0,0,0,0,9,129,3,79,0,0,0,0,9,9,4,59,0,0,0,128,8,128,0,57,0,0,0,0,0,152,4,53],[0,0,0,1,7,112,0,57,0,0,0,0,8,103,0,75,0,0,5,103,0,0,65,61,0,0,0,0,7,5,0,75],[0,0,5,126,0,0,97,61,0,0,0,5,6,96,2,16,0,0,0,0,7,97,3,79,0,0,0,3,5,80,2,16],[0,0,0,128,6,96,0,57,0,0,0,0,8,6,4,51,0,0,0,0,8,88,1,207,0,0,0,0,8,88,2,47],[0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137,0,0,0,0,7,87,2,47,0,0,0,0,5,87,1,207],[0,0,0,0,5,133,1,159,0,0,0,0,0,86,4,53,0,1,0,0,0,3,0,31,0,19,0,0,0,1,3,85],[0,0,0,1,2,32,1,144,0,0,6,102,0,0,97,61,0,0,0,31,2,64,0,57,0,0,0,96,5,32,1,143],[0,0,0,128,2,80,1,191,0,0,0,64,0,32,4,63,0,0,0,32,4,48,0,140,0,0,1,57,0,0,65,61],[0,0,0,128,4,0,4,61,0,0,0,8,4,64,0,108,0,0,4,34,0,0,129,61,0,0,0,160,4,80,0,57],[0,0,5,40,6,0,0,65,0,0,0,0,0,100,4,53,0,0,0,164,6,80,0,57,0,0,0,7,7,0,0,41],[0,0,0,0,0,118,4,53,0,0,0,196,6,80,0,57,0,0,0,0,0,6,4,53,0,0,0,68,6,0,0,57],[0,1,0,0,0,6,0,29,0,0,0,0,0,98,4,53,0,0,1,64,6,80,0,57,0,0,0,64,0,96,4,63],[0,0,1,32,7,80,0,57,0,0,5,41,6,0,0,65,0,3,0,0,0,7,0,29,0,0,0,0,0,103,4,53],[0,0,1,0,6,80,1,191,0,0,0,32,5,0,0,57,0,4,0,0,0,5,0,29,0,2,0,0,0,6,0,29],[0,0,0,0,0,86,4,53,0,0,0,0,5,2,4,51,0,0,0,0,2,0,4,20,0,0,0,9,6,0,0,41],[0,0,0,4,6,96,0,140,0,0,8,253,0,0,193,61,0,0,0,1,2,0,0,57,0,0,5,16,4,48,0,156],[0,0,19,58,0,0,33,61,0,0,9,17,0,0,1,61,0,0,5,64,6,64,0,156,0,0,19,58,0,0,33,61],[0,0,0,64,6,64,0,57,0,0,0,64,0,96,4,63,0,0,0,0,7,33,3,79,0,0,0,1,6,0,0,58],[0,0,0,0,6,100,4,54,0,0,0,0,7,7,4,59,0,0,0,0,0,118,4,53,0,0,9,198,0,0,97,61],[0,0,0,248,8,80,2,16,0,0,5,17,9,0,0,65,0,0,0,0,5,5,0,75,0,0,0,0,9,8,192,25],[0,0,5,65,5,112,1,151,0,0,0,0,5,149,1,159,0,0,0,0,0,86,4,53,0,0,0,64,5,0,4,61],[0,0,0,6,6,0,0,41,0,0,0,96,6,96,0,138,0,0,0,0,7,97,3,79,0,0,0,0,7,7,4,59],[0,0,0,128,8,112,0,140,0,0,9,95,0,0,65,61,0,0,0,128,8,112,2,112,0,0,5,66,9,112,0,156],[0,0,0,0,8,7,160,25,0,0,5,66,9,112,0,156,0,0,0,0,9,0,0,25,0,0,0,16,9,0,32,57],[0,0,0,8,10,144,1,191,0,0,5,16,11,128,0,156,0,0,0,0,10,9,160,25,0,0,0,64,9,128,2,112],[0,0,5,16,11,128,0,156,0,0,0,0,9,8,160,25,0,0,0,4,11,160,1,191,0,0,5,8,8,144,0,156],[0,0,0,0,11,10,160,25,0,0,0,32,10,144,2,112,0,0,5,8,8,144,0,156,0,0,0,0,10,9,160,25],[0,0,0,2,8,176,1,191,0,0,255,255,9,160,0,140,0,0,0,0,8,11,160,25,0,0,0,16,9,160,2,112],[0,0,0,0,9,10,160,25,0,0,0,255,9,144,0,140,0,0,0,1,8,128,32,57,0,0,0,32,9,0,0,138],[0,0,0,65,10,128,0,57,0,0,0,0,9,154,1,111,0,0,0,0,9,149,0,25,0,0,0,0,10,89,0,75],[0,0,0,0,10,0,0,25,0,0,0,1,10,0,64,57,0,0,5,16,11,144,0,156,0,0,19,58,0,0,33,61],[0,0,0,1,10,160,1,144,0,0,19,58,0,0,193,61,0,0,0,64,0,144,4,63,0,0,0,2,9,128,0,57],[0,0,0,0,9,149,4,54,0,0,0,33,10,128,0,57,0,0,0,5,10,160,2,114,0,0,5,246,0,0,97,61],[0,0,0,0,11,33,3,79,0,0,0,0,12,0,0,25,0,0,0,5,13,192,2,16,0,0,0,0,14,217,0,25],[0,0,0,0,13,219,3,79,0,0,0,0,13,13,4,59,0,0,0,0,0,222,4,53,0,0,0,1,12,192,0,57],[0,0,0,0,13,172,0,75,0,0,5,238,0,0,65,61,0,0,0,0,10,0,0,75,0,0,5,248,0,0,97,61],[0,0,0,0,10,5,4,51,0,0,0,0,10,10,0,75,0,0,9,198,0,0,97,61,0,0,0,0,10,9,4,51],[0,0,5,65,10,160,1,151,0,0,0,248,11,128,2,16,0,0,0,0,10,171,1,159,0,0,5,67,10,160,0,65],[0,0,0,0,0,169,4,53,0,0,0,3,8,128,2,16,0,0,0,248,8,128,0,137,0,0,0,0,7,135,1,207],[0,0,0,255,8,128,0,140,0,0,0,0,7,0,32,25,0,0,0,33,8,80,0,57,0,0,9,111,0,0,1,61],[0,0,5,64,6,64,0,156,0,0,19,58,0,0,33,61,0,0,0,64,6,64,0,57,0,0,0,64,0,96,4,63],[0,0,0,0,7,33,3,79,0,0,0,1,6,0,0,58,0,0,0,0,6,100,4,54,0,0,0,0,7,7,4,59],[0,0,0,0,0,118,4,53,0,0,9,198,0,0,97,61,0,0,0,248,8,80,2,16,0,0,5,17,9,0,0,65],[0,0,0,0,5,5,0,75,0,0,0,0,9,8,192,25,0,0,5,65,5,112,1,151,0,0,0,0,5,149,1,159],[0,0,0,0,0,86,4,53,0,0,0,64,5,0,4,61,0,0,0,6,6,0,0,41,0,0,0,64,7,96,0,138],[0,0,0,0,6,113,3,79,0,0,0,0,6,6,4,59,0,0,0,128,8,96,0,140,0,0,9,188,0,0,65,61],[0,0,0,128,8,96,2,112,0,0,5,66,9,96,0,156,0,0,0,0,8,6,160,25,0,0,5,66,9,96,0,156],[0,0,0,0,9,0,0,25,0,0,0,16,9,0,32,57,0,0,0,8,10,144,1,191,0,0,5,16,11,128,0,156],[0,0,0,0,10,9,160,25,0,0,0,64,9,128,2,112,0,0,5,16,11,128,0,156,0,0,0,0,9,8,160,25],[0,0,0,4,11,160,1,191,0,0,5,8,8,144,0,156,0,0,0,0,11,10,160,25,0,0,0,32,10,144,2,112],[0,0,5,8,8,144,0,156,0,0,0,0,10,9,160,25,0,0,0,2,8,176,1,191,0,0,255,255,9,160,0,140],[0,0,0,0,8,11,160,25,0,0,0,16,9,160,2,112,0,0,0,0,9,10,160,25,0,0,0,255,9,144,0,140],[0,0,0,1,8,128,32,57,0,0,0,32,9,0,0,138,0,0,0,65,10,128,0,57,0,0,0,0,9,154,1,111],[0,0,0,0,9,149,0,25,0,0,0,0,10,89,0,75,0,0,0,0,10,0,0,25,0,0,0,1,10,0,64,57],[0,0,5,16,11,144,0,156,0,0,19,58,0,0,33,61,0,0,0,1,10,160,1,144,0,0,19,58,0,0,193,61],[0,0,0,64,0,144,4,63,0,0,0,2,9,128,0,57,0,0,0,0,9,149,4,54,0,0,0,33,10,128,0,57],[0,0,0,5,10,160,2,114,0,0,6,84,0,0,97,61,0,0,0,0,11,33,3,79,0,0,0,0,12,0,0,25],[0,0,0,5,13,192,2,16,0,0,0,0,14,217,0,25,0,0,0,0,13,219,3,79,0,0,0,0,13,13,4,59],[0,0,0,0,0,222,4,53,0,0,0,1,12,192,0,57,0,0,0,0,13,172,0,75,0,0,6,76,0,0,65,61],[0,0,0,0,10,0,0,75,0,0,6,86,0,0,97,61,0,0,0,0,10,5,4,51,0,0,0,0,10,10,0,75],[0,0,9,198,0,0,97,61,0,0,0,0,10,9,4,51,0,0,5,65,10,160,1,151,0,0,0,248,11,128,2,16],[0,0,0,0,10,171,1,159,0,0,5,67,10,160,0,65,0,0,0,0,0,169,4,53,0,0,0,3,8,128,2,16],[0,0,0,248,8,128,0,137,0,0,0,0,6,134,1,207,0,0,0,255,8,128,0,140,0,0,0,0,6,0,32,25],[0,0,0,33,8,80,0,57,0,0,10,129,0,0,1,61,0,0,0,64,2,0,4,61,0,0,0,31,4,48,1,143],[0,0,0,5,5,48,2,114,0,0,6,115,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16],[0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53],[0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,6,107,0,0,65,61,0,0,0,0,6,4,0,75],[0,0,6,130,0,0,97,61,0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25],[0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47],[0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207],[0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,5,8,1,0,0,65,0,0,5,8,4,32,0,156],[0,0,0,0,2,1,128,25,0,0,0,64,1,32,2,16,0,0,0,96,2,48,2,16,0,0,0,0,1,33,1,159],[0,0,20,30,0,1,4,48,0,0,0,0,1,49,3,223,0,0,0,192,2,32,2,16,0,0,5,31,2,32,1,151],[0,0,5,33,2,32,1,199,0,2,0,0,0,33,3,181,0,0,0,0,1,33,3,175,0,0,128,16,2,0,0,57],[20,28,20,23,0,0,4,15,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,1,5,8,0,48,1,157],[0,0,5,8,5,48,1,151,0,19,0,0,0,1,3,85,0,0,0,1,2,32,1,144,0,0,9,202,0,0,97,61],[0,0,0,63,2,80,0,57,0,0,5,61,2,32,1,151,0,0,0,64,6,0,4,61,0,0,0,0,2,38,0,25],[0,0,0,0,3,98,0,75,0,0,0,0,3,0,0,25,0,0,0,1,3,0,64,57,0,0,5,16,4,32,0,156],[0,0,19,58,0,0,33,61,0,0,0,1,3,48,1,144,0,0,19,58,0,0,193,61,0,0,0,64,0,32,4,63],[0,0,0,0,4,86,4,54,0,0,0,18,2,0,3,103,0,0,0,0,3,0,0,49,0,0,0,31,7,80,0,57],[0,0,0,5,7,112,2,114,0,0,6,180,0,0,97,61,0,0,0,0,8,50,3,79,0,0,0,0,9,0,0,25],[0,0,0,5,10,144,2,16,0,0,0,0,11,164,0,25,0,0,0,0,10,168,3,79,0,0,0,0,10,10,4,59],[0,0,0,0,0,171,4,53,0,0,0,1,9,144,0,57,0,0,0,0,10,121,0,75,0,0,6,172,0,0,65,61],[0,0,0,0,7,0,0,75,0,0,6,182,0,0,97,61,0,0,0,31,7,80,1,143,0,0,0,5,5,80,2,114],[0,0,6,194,0,0,97,61,0,0,0,0,8,0,0,25,0,0,0,5,9,128,2,16,0,0,0,0,10,148,0,25],[0,0,0,0,9,145,3,79,0,0,0,0,9,9,4,59,0,0,0,0,0,154,4,53,0,0,0,1,8,128,0,57],[0,0,0,0,9,88,0,75,0,0,6,186,0,0,65,61,0,0,0,0,8,7,0,75,0,0,6,209,0,0,97,61],[0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,84,0,25,0,0,0,3,7,112,2,16],[0,0,0,0,8,5,4,51,0,0,0,0,8,120,1,207,0,0,0,0,8,120,2,47,0,0,0,0,1,1,4,59],[0,0,1,0,7,112,0,137,0,0,0,0,1,113,2,47,0,0,0,0,1,113,1,207,0,0,0,0,1,129,1,159],[0,0,0,0,0,21,4,53,0,0,0,0,1,6,4,51,0,0,0,32,1,16,0,140,0,0,10,4,0,0,193,61],[0,0,0,10,6,0,0,41,0,0,0,0,1,99,0,73,0,0,0,35,5,16,0,138,0,8,2,4,0,96,0,61],[0,0,0,8,1,32,3,96,0,0,0,0,1,1,4,59,0,0,5,17,6,0,0,65,0,0,0,0,7,81,0,75],[0,0,0,0,7,0,0,25,0,0,0,0,7,6,128,25,0,0,5,17,5,80,1,151,0,0,5,17,8,16,1,151],[0,0,0,0,9,88,0,75,0,0,0,0,6,0,128,25,0,0,0,0,5,88,1,63,0,0,5,17,5,80,0,156],[0,0,0,0,6,7,192,25,0,0,0,0,5,6,0,75,0,0,1,57,0,0,193,61,0,0,0,0,4,4,4,51],[0,5,0,0,0,4,0,29,0,0,0,9,1,16,0,41,0,0,0,0,4,18,3,79,0,0,0,0,5,4,4,59],[0,0,5,16,4,80,0,156,0,0,1,57,0,0,33,61,0,0,0,5,4,80,2,16,0,0,0,0,3,67,0,73],[0,0,0,32,6,16,0,57,0,0,5,17,1,0,0,65,0,0,0,0,7,54,0,75,0,0,0,0,7,0,0,25],[0,0,0,0,7,1,32,25,0,0,5,17,3,48,1,151,0,0,5,17,8,96,1,151,0,0,0,0,9,56,0,75],[0,0,0,0,1,0,128,25,0,0,0,0,3,56,1,63,0,0,5,17,3,48,0,156,0,0,0,0,1,7,192,25],[0,0,0,0,1,1,0,75,0,0,1,57,0,0,193,61,0,0,0,64,1,0,4,61,0,0,0,32,3,16,0,57],[0,0,5,74,5,80,1,152,0,0,7,12,0,0,97,61,0,0,0,0,2,98,3,79,0,0,0,0,6,0,0,25],[0,0,0,5,7,96,2,16,0,0,0,0,8,115,0,25,0,0,0,0,7,114,3,79,0,0,0,0,7,7,4,59],[0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,7,4,0,0,65,61],[0,0,0,0,2,0,0,75,0,0,7,14,0,0,97,61,0,0,0,0,0,65,4,53,0,0,0,63,2,64,0,57],[0,0,0,32,4,0,0,138,0,0,0,0,2,66,1,111,0,0,0,0,2,33,0,25,0,0,0,0,4,18,0,75],[0,0,0,0,4,0,0,25,0,0,0,1,4,0,64,57,0,0,5,16,5,32,0,156,0,0,19,58,0,0,33,61],[0,0,0,1,4,64,1,144,0,0,19,58,0,0,193,61,0,0,0,64,0,32,4,63,0,0,5,8,2,0,0,65],[0,0,5,8,4,48,0,156,0,0,0,0,3,2,128,25,0,0,0,64,3,48,2,16,0,0,0,0,1,1,4,51],[0,0,5,8,4,16,0,156,0,0,0,0,1,2,128,25,0,0,0,96,1,16,2,16,0,0,0,0,1,49,1,159],[0,0,0,0,3,0,4,20,0,0,5,8,4,48,0,156,0,0,0,0,3,2,128,25,0,0,0,192,2,48,2,16],[0,0,0,0,1,18,1,159,0,0,5,19,1,16,1,199,0,0,128,16,2,0,0,57,20,28,20,13,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,1,57,0,0,97,61,0,0,0,0,2,0,0,49,0,0,0,10,3,32,0,106],[0,0,0,35,5,48,0,138,0,0,0,8,3,0,0,41,0,0,0,32,4,48,0,57,0,0,0,18,3,0,3,103],[0,0,0,0,4,67,3,79,0,0,0,0,4,4,4,59,0,0,5,17,6,0,0,65,0,0,0,0,7,84,0,75],[0,0,0,0,7,0,0,25,0,0,0,0,7,6,128,25,0,0,5,17,5,80,1,151,0,0,5,17,8,64,1,151],[0,0,0,0,9,88,0,75,0,0,0,0,6,0,128,25,0,0,0,0,5,88,1,63,0,0,5,17,5,80,0,156],[0,0,0,0,6,7,192,25,0,0,0,0,1,1,4,59,0,8,0,0,0,1,0,29,0,0,0,0,1,6,0,75],[0,0,1,57,0,0,193,61,0,0,0,9,4,64,0,41,0,0,0,0,1,67,3,79,0,0,0,0,1,1,4,59],[0,0,5,16,5,16,0,156,0,0,1,57,0,0,33,61,0,0,0,0,6,18,0,73,0,0,0,32,5,64,0,57],[0,0,5,17,4,0,0,65,0,0,0,0,7,101,0,75,0,0,0,0,7,0,0,25,0,0,0,0,7,4,32,25],[0,0,5,17,6,96,1,151,0,0,5,17,8,80,1,151,0,0,0,0,9,104,0,75,0,0,0,0,4,0,128,25],[0,0,0,0,6,104,1,63,0,0,5,17,6,96,0,156,0,0,0,0,4,7,192,25,0,0,0,0,4,4,0,75],[0,0,1,57,0,0,193,61,0,0,5,8,6,80,1,151,0,0,0,0,4,0,4,20,0,2,0,0,0,99,3,85],[0,0,0,0,5,81,0,25,0,0,0,0,1,21,0,75,0,0,0,0,1,0,0,25,0,0,0,1,1,0,64,57],[0,0,0,1,1,16,1,144,0,0,18,29,0,0,193,61,0,0,0,0,1,82,0,75,0,0,18,29,0,0,65,61],[0,0,0,0,1,99,3,79,0,0,0,0,2,82,0,73,0,0,5,8,2,32,1,151,0,2,0,0,0,33,3,229],[0,0,5,8,3,64,0,156,0,0,2,171,0,0,33,61,0,0,0,0,1,33,3,223,0,0,0,192,2,64,2,16],[0,0,5,31,2,32,1,151,0,0,5,33,2,32,1,199,0,2,0,0,0,33,3,181,0,0,0,0,1,33,3,175],[0,0,128,16,2,0,0,57,20,28,20,23,0,0,4,15,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112],[0,1,5,8,0,48,1,157,0,0,5,8,3,48,1,151,0,19,0,0,0,1,3,85,0,0,0,1,2,32,1,144],[0,0,17,47,0,0,97,61,0,0,0,63,2,48,0,57,0,0,5,61,2,32,1,151,0,0,0,64,5,0,4,61],[0,0,0,0,2,37,0,25,0,0,0,0,4,82,0,75,0,0,0,0,4,0,0,25,0,0,0,1,4,0,64,57],[0,0,5,16,6,32,0,156,0,0,19,58,0,0,33,61,0,0,0,1,4,64,1,144,0,0,19,58,0,0,193,61],[0,0,0,64,0,32,4,63,0,0,0,0,2,53,4,54,0,0,0,18,4,0,3,103,0,0,0,31,6,48,0,57],[0,0,0,5,6,96,2,114,0,0,7,148,0,0,97,61,0,0,0,0,7,64,3,104,0,0,0,0,8,0,0,25],[0,0,0,5,9,128,2,16,0,0,0,0,10,146,0,25,0,0,0,0,9,151,3,79,0,0,0,0,9,9,4,59],[0,0,0,0,0,154,4,53,0,0,0,1,8,128,0,57,0,0,0,0,9,104,0,75,0,0,7,140,0,0,65,61],[0,0,0,0,6,0,0,75,0,0,7,150,0,0,97,61,0,0,0,31,6,48,1,143,0,0,0,5,3,48,2,114],[0,0,7,162,0,0,97,61,0,0,0,0,7,0,0,25,0,0,0,5,8,112,2,16,0,0,0,0,9,130,0,25],[0,0,0,0,8,129,3,79,0,0,0,0,8,8,4,59,0,0,0,0,0,137,4,53,0,0,0,1,7,112,0,57],[0,0,0,0,8,55,0,75,0,0,7,154,0,0,65,61,0,0,0,0,7,6,0,75,0,0,7,177,0,0,97,61],[0,0,0,5,3,48,2,16,0,0,0,0,1,49,3,79,0,0,0,0,3,50,0,25,0,0,0,3,6,96,2,16],[0,0,0,0,7,3,4,51,0,0,0,0,7,103,1,207,0,0,0,0,7,103,2,47,0,0,0,0,1,1,4,59],[0,0,1,0,6,96,0,137,0,0,0,0,1,97,2,47,0,0,0,0,1,97,1,207,0,0,0,0,1,113,1,159],[0,0,0,0,0,19,4,53,0,0,0,0,1,5,4,51,0,0,0,32,1,16,0,140,0,0,10,4,0,0,193,61],[0,0,0,10,12,0,0,41,0,0,0,100,1,192,0,57,0,0,0,0,1,20,3,79,0,0,0,68,3,192,0,57],[0,0,0,0,5,52,3,79,0,0,0,36,3,192,0,57,0,0,0,0,6,52,3,79,0,0,1,36,3,192,0,57],[0,0,0,0,7,52,3,79,0,0,0,6,8,64,3,96,0,0,0,228,3,192,0,57,0,0,0,0,9,52,3,79],[0,0,0,196,3,192,0,57,0,0,0,0,10,52,3,79,0,0,0,164,3,192,0,57,0,0,0,0,11,52,3,79],[0,0,0,132,3,192,0,57,0,0,0,0,12,52,3,79,0,0,0,9,3,64,3,96,0,0,0,0,3,3,4,59],[0,0,0,0,4,6,4,59,0,0,0,0,5,5,4,59,0,0,0,0,6,1,4,59,0,0,0,0,12,12,4,59],[0,0,0,0,11,11,4,59,0,0,0,0,10,10,4,59,0,0,0,0,9,9,4,59,0,0,0,0,8,8,4,59],[0,0,0,0,7,7,4,59,0,0,0,0,2,2,4,51,0,0,0,64,1,0,4,61,0,0,1,192,13,16,0,57],[0,0,0,0,0,45,4,53,0,0,1,160,2,16,0,57,0,0,0,8,13,0,0,41,0,0,0,0,0,210,4,53],[0,0,1,128,2,16,0,57,0,0,0,5,13,0,0,41,0,0,0,0,0,210,4,53,0,0,1,96,2,16,0,57],[0,0,0,0,0,114,4,53,0,0,1,64,2,16,0,57,0,0,0,0,0,130,4,53,0,0,1,32,2,16,0,57],[0,0,0,0,0,146,4,53,0,0,1,0,2,16,0,57,0,0,0,0,0,162,4,53,0,0,0,224,2,16,0,57],[0,0,0,0,0,178,4,53,0,0,0,192,2,16,0,57,0,0,0,0,0,194,4,53,0,0,0,160,2,16,0,57],[0,0,0,0,0,98,4,53,0,0,0,128,2,16,0,57,0,0,0,0,0,82,4,53,0,0,0,96,2,16,0,57],[0,0,0,0,0,66,4,53,0,0,0,64,2,16,0,57,0,0,0,0,0,50,4,53,0,0,0,32,2,16,0,57],[0,0,5,76,3,0,0,65,0,0,0,0,0,50,4,53,0,0,1,192,3,0,0,57,0,0,0,0,0,49,4,53],[0,0,5,77,3,16,0,156,0,0,19,58,0,0,33,61,0,0,1,224,3,16,0,57,0,0,0,64,0,48,4,63],[0,0,5,8,4,0,0,65,0,0,5,8,3,32,0,156,0,0,0,0,2,4,128,25,0,0,0,64,2,32,2,16],[0,0,0,0,1,1,4,51,0,0,5,8,3,16,0,156,0,0,0,0,1,4,128,25,0,0,0,96,1,16,2,16],[0,0,0,0,1,33,1,159,0,0,0,0,2,0,4,20,0,0,5,8,3,32,0,156,0,0,0,0,2,4,128,25],[0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159,0,0,5,19,1,16,1,199,0,0,128,16,2,0,0,57],[20,28,20,13,0,0,4,15,0,0,0,1,2,32,1,144,0,0,1,57,0,0,97,61,0,0,0,0,1,1,4,59],[0,6,0,0,0,1,0,29,0,0,0,64,1,0,4,61,0,8,0,0,0,1,0,29,0,0,5,62,1,0,0,65],[0,0,0,0,0,16,4,57,0,0,0,0,1,0,4,20,0,0,5,8,2,16,0,156,0,0,5,8,1,0,128,65],[0,0,0,192,1,16,2,16,0,0,5,63,1,16,1,199,0,0,128,11,2,0,0,57,20,28,20,13,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,18,65,0,0,97,61,0,0,0,8,4,0,0,41,0,0,0,32,2,64,0,57],[0,0,0,0,1,1,4,59,0,0,5,78,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,128,3,64,0,57],[0,0,0,0,0,19,4,53,0,0,0,96,1,64,0,57,0,0,5,79,3,0,0,65,0,0,0,0,0,49,4,53],[0,0,0,64,1,64,0,57,0,0,5,80,3,0,0,65,0,0,0,0,0,49,4,53,0,0,0,128,1,0,0,57],[0,0,0,0,0,20,4,53,0,0,5,81,1,64,0,156,0,0,19,58,0,0,33,61,0,0,0,8,4,0,0,41],[0,0,0,160,1,64,0,57,0,0,0,64,0,16,4,63,0,0,5,8,1,0,0,65,0,0,5,8,3,32,0,156],[0,0,0,0,2,1,128,25,0,0,0,64,2,32,2,16,0,0,0,0,3,4,4,51,0,0,5,8,4,48,0,156],[0,0,0,0,3,1,128,25,0,0,0,96,3,48,2,16,0,0,0,0,2,35,1,159,0,0,0,0,3,0,4,20],[0,0,5,8,4,48,0,156,0,0,0,0,3,1,128,25,0,0,0,192,1,48,2,16,0,0,0,0,1,33,1,159],[0,0,5,19,1,16,1,199,0,0,128,16,2,0,0,57,20,28,20,13,0,0,4,15,0,0,0,1,2,32,1,144],[0,0,1,57,0,0,97,61,0,0,0,0,3,1,4,59,0,0,0,64,1,0,4,61,0,0,0,66,2,16,0,57],[0,0,0,6,4,0,0,41,0,0,0,0,0,66,4,53,0,0,0,32,2,16,0,57,0,0,5,82,4,0,0,65],[0,0,0,0,0,66,4,53,0,0,0,34,4,16,0,57,0,0,0,0,0,52,4,53,0,0,0,66,3,0,0,57],[0,0,0,0,0,49,4,53,0,0,5,47,3,16,0,156,0,0,19,58,0,0,33,61,0,0,0,128,3,16,0,57],[0,0,0,64,0,48,4,63,0,0,5,8,3,0,0,65,0,0,5,8,4,32,0,156,0,0,0,0,2,3,128,25],[0,0,0,64,2,32,2,16,0,0,0,0,1,1,4,51,0,0,5,8,4,16,0,156,0,0,0,0,1,3,128,25],[0,0,0,96,1,16,2,16,0,0,0,0,1,33,1,159,0,0,0,0,2,0,4,20,0,0,5,8,4,32,0,156],[0,0,0,0,2,3,128,25,0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159,0,0,17,249,0,0,1,61],[0,0,5,64,7,32,0,156,0,0,19,58,0,0,33,61,0,0,0,64,7,32,0,57,0,0,0,64,0,112,4,63],[0,0,0,1,7,0,0,58,0,0,0,0,7,114,4,54,0,0,0,0,8,5,4,59,0,0,0,0,0,135,4,53],[0,0,9,198,0,0,97,61,0,0,0,248,9,96,2,16,0,0,5,17,10,0,0,65,0,0,0,0,6,6,0,75],[0,0,0,0,10,9,192,25,0,0,5,65,6,128,1,151,0,0,0,0,6,166,1,159,0,0,0,0,0,103,4,53],[0,0,0,64,6,0,4,61,0,6,0,0,0,6,0,29,0,0,0,32,7,96,0,57,0,0,0,0,6,1,4,51],[0,0,0,0,8,6,0,75,0,0,8,126,0,0,97,61,0,0,0,0,8,0,0,25,0,0,0,0,9,120,0,25],[0,0,0,32,8,128,0,57,0,0,0,0,10,24,0,25,0,0,0,0,10,10,4,51,0,0,0,0,0,169,4,53],[0,0,0,0,9,104,0,75,0,0,8,119,0,0,65,61,0,0,0,0,1,118,0,25,0,0,0,0,0,1,4,53],[0,0,0,0,7,2,4,51,0,0,0,0,8,7,0,75,0,0,8,139,0,0,97,61,0,0,0,0,8,0,0,25],[0,0,0,0,9,24,0,25,0,0,0,32,8,128,0,57,0,0,0,0,10,40,0,25,0,0,0,0,10,10,4,51],[0,0,0,0,0,169,4,53,0,0,0,0,9,120,0,75,0,0,8,132,0,0,65,61,0,0,0,0,1,23,0,25],[0,0,0,0,0,1,4,53,0,0,0,0,1,103,0,25,0,0,0,6,6,0,0,41,0,0,0,0,0,22,4,53],[0,0,0,63,1,16,0,57,0,2,0,32,0,0,0,146,0,0,0,2,1,16,1,127,0,0,0,0,2,97,0,25],[0,0,0,0,1,18,0,75,0,0,0,0,1,0,0,25,0,0,0,1,1,0,64,57,0,5,0,0,0,2,0,29],[0,0,5,16,2,32,0,156,0,0,19,58,0,0,33,61,0,0,0,1,1,16,1,144,0,0,19,58,0,0,193,61],[0,0,0,5,1,0,0,41,0,0,0,64,0,16,4,63,0,0,5,64,1,16,0,156,0,0,19,58,0,0,33,61],[0,0,0,10,7,0,0,41,0,0,0,68,1,112,0,57,0,0,0,0,1,19,3,79,0,0,0,0,1,1,4,59],[0,0,0,5,8,0,0,41,0,0,0,64,2,128,0,57,0,0,0,64,0,32,4,63,0,0,0,32,2,128,0,57],[0,0,5,68,6,0,0,65,0,0,0,0,0,98,4,53,0,0,0,21,2,0,0,57,0,0,0,0,0,40,4,53],[0,0,0,96,1,16,2,16,0,0,0,33,2,128,0,57,0,0,0,0,0,18,4,53,0,0,1,36,1,112,0,57],[0,0,0,0,2,19,3,79,0,0,0,64,6,0,4,61,0,4,0,0,0,6,0,29,0,0,0,0,2,2,4,59],[0,0,0,128,6,32,0,140,0,0,11,44,0,0,65,61,0,0,0,128,6,32,2,112,0,0,5,66,7,32,0,156],[0,0,0,0,6,2,160,25,0,0,5,66,7,32,0,156,0,0,0,0,7,0,0,25,0,0,0,16,7,0,32,57],[0,0,0,8,8,112,1,191,0,0,5,16,9,96,0,156,0,0,0,0,8,7,160,25,0,0,0,64,7,96,2,112],[0,0,5,16,9,96,0,156,0,0,0,0,7,6,160,25,0,0,0,4,9,128,1,191,0,0,5,8,6,112,0,156],[0,0,0,0,9,8,160,25,0,0,0,32,8,112,2,112,0,0,5,8,6,112,0,156,0,0,0,0,8,7,160,25],[0,0,0,2,6,144,1,191,0,0,255,255,7,128,0,140,0,0,0,0,6,9,160,25,0,0,0,16,7,128,2,112],[0,0,0,0,7,8,160,25,0,0,0,255,7,112,0,140,0,0,0,1,6,96,32,57,0,0,0,65,7,96,0,57],[0,0,0,2,7,112,1,127,0,0,0,4,7,112,0,41,0,0,0,4,8,112,0,108,0,0,0,0,8,0,0,25],[0,0,0,1,8,0,64,57,0,0,5,16,9,112,0,156,0,0,19,58,0,0,33,61,0,0,0,1,8,128,1,144],[0,0,19,58,0,0,193,61,0,0,0,64,0,112,4,63,0,0,0,2,7,96,0,57,0,0,0,4,8,0,0,41],[0,0,0,0,7,120,4,54,0,0,0,33,8,96,0,57,0,0,0,5,8,128,2,114,0,0,8,233,0,0,97,61],[0,0,0,0,9,0,0,25,0,0,0,5,10,144,2,16,0,0,0,0,11,167,0,25,0,0,0,0,10,165,3,79],[0,0,0,0,10,10,4,59,0,0,0,0,0,171,4,53,0,0,0,1,9,144,0,57,0,0,0,0,10,137,0,75],[0,0,8,225,0,0,65,61,0,0,0,0,8,0,0,75,0,0,8,235,0,0,97,61,0,0,0,4,8,0,0,41],[0,0,0,0,8,8,4,51,0,0,0,0,8,8,0,75,0,0,9,198,0,0,97,61,0,0,0,0,8,7,4,51],[0,0,5,65,8,128,1,151,0,0,0,248,9,96,2,16,0,0,0,0,8,137,1,159,0,0,5,67,8,128,0,65],[0,0,0,0,0,135,4,53,0,0,0,3,6,96,2,16,0,0,0,248,6,96,0,137,0,0,0,0,2,98,1,207],[0,0,0,255,6,96,0,140,0,0,0,0,2,0,32,25,0,0,0,4,6,0,0,41,0,0,0,33,6,96,0,57],[0,0,11,61,0,0,1,61,0,0,5,8,1,0,0,65,0,0,5,8,3,80,0,156,0,0,0,0,5,1,128,25],[0,0,0,96,3,80,2,16,0,0,0,64,4,64,2,16,0,0,0,0,3,67,1,159,0,0,5,8,4,32,0,156],[0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,0,0,1,19,1,159,0,0,0,9,2,0,0,41],[20,28,20,8,0,0,4,15,0,5,0,96,0,0,0,61,0,0,0,1,2,32,1,143,0,19,0,0,0,1,3,85],[0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,1,5,8,0,48,1,157,0,0,5,8,3,48,1,152],[0,0,9,61,0,0,97,61,0,0,0,63,4,48,0,57,0,0,0,32,5,0,0,138,0,0,0,0,4,84,1,111],[0,0,0,64,5,0,4,61,0,0,0,0,4,69,0,25,0,5,0,0,0,5,0,29,0,0,0,0,5,84,0,75],[0,0,0,0,5,0,0,25,0,0,0,1,5,0,64,57,0,0,5,16,6,64,0,156,0,0,19,58,0,0,33,61],[0,0,0,1,5,80,1,144,0,0,19,58,0,0,193,61,0,0,0,64,0,64,4,63,0,0,0,31,4,48,1,143],[0,0,0,5,5,0,0,41,0,0,0,0,8,53,4,54,0,0,0,5,3,48,2,114,0,0,9,45,0,0,97,61],[0,0,0,0,5,0,0,25,0,0,0,5,6,80,2,16,0,0,0,0,7,104,0,25,0,0,0,0,6,97,3,79],[0,0,0,0,6,6,4,59,0,0,0,0,0,103,4,53,0,0,0,1,5,80,0,57,0,0,0,0,6,53,0,75],[0,0,9,37,0,0,65,61,0,10,0,0,0,8,0,29,0,0,0,0,5,4,0,75,0,0,9,61,0,0,97,61],[0,0,0,5,3,48,2,16,0,0,0,0,1,49,3,79,0,0,0,10,3,48,0,41,0,0,0,3,4,64,2,16],[0,0,0,0,5,3,4,51,0,0,0,0,5,69,1,207,0,0,0,0,5,69,2,47,0,0,0,0,1,1,4,59],[0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,81,1,159],[0,0,0,0,0,19,4,53,0,0,0,5,1,0,0,41,0,0,0,0,1,1,4,51,0,0,0,0,2,2,0,75],[0,0,9,229,0,0,193,61,0,0,0,0,2,1,0,75,0,0,9,87,0,0,193,61,0,0,0,64,4,0,4,61],[0,10,0,0,0,4,0,29,0,0,5,22,1,0,0,65,0,0,0,0,0,20,4,53,0,0,0,4,1,64,0,57],[0,0,0,4,2,0,0,41,0,0,0,0,0,33,4,53,0,0,0,2,1,0,0,41,0,0,0,0,3,1,4,51],[0,9,0,0,0,3,0,29,0,0,0,36,1,64,0,57,0,0,0,0,0,49,4,53,0,0,0,68,2,64,0,57],[0,0,0,3,1,0,0,41,20,28,19,250,0,0,4,15,0,0,0,9,1,0,0,41,0,0,0,31,1,16,0,57],[0,0,0,32,2,0,0,138,0,0,0,0,1,33,1,111,0,0,0,68,1,16,0,57,0,0,5,8,2,0,0,65],[0,0,5,8,3,16,0,156,0,0,0,0,1,2,128,25,0,0,0,10,4,0,0,41,0,0,5,8,3,64,0,156],[0,0,0,0,4,2,128,25,0,0,0,64,2,64,2,16,0,0,2,89,0,0,1,61,0,0,5,64,8,80,0,156],[0,0,19,58,0,0,33,61,0,0,0,64,8,80,0,57,0,0,0,64,0,128,4,63,0,0,0,0,9,33,3,79],[0,0,0,1,8,0,0,58,0,0,0,0,8,133,4,54,0,0,0,0,9,9,4,59,0,0,0,0,0,152,4,53],[0,0,9,198,0,0,97,61,0,0,0,248,10,112,2,16,0,0,5,17,11,0,0,65,0,0,0,0,7,7,0,75],[0,0,0,0,11,10,192,25,0,0,5,65,7,144,1,151,0,0,0,0,7,183,1,159,0,0,0,0,0,120,4,53],[0,0,0,64,7,0,4,61,0,0,0,64,6,96,0,138,0,0,0,0,8,97,3,79,0,0,0,0,8,8,4,59],[0,0,0,128,9,128,0,140,0,0,10,11,0,0,65,61,0,0,0,128,9,128,2,112,0,0,5,66,10,128,0,156],[0,0,0,0,9,8,160,25,0,0,5,66,10,128,0,156,0,0,0,0,10,0,0,25,0,0,0,16,10,0,32,57],[0,0,0,8,11,160,1,191,0,0,5,16,12,144,0,156,0,0,0,0,11,10,160,25,0,0,0,64,10,144,2,112],[0,0,5,16,12,144,0,156,0,0,0,0,10,9,160,25,0,0,0,4,12,176,1,191,0,0,5,8,9,160,0,156],[0,0,0,0,12,11,160,25,0,0,0,32,11,160,2,112,0,0,5,8,9,160,0,156,0,0,0,0,11,10,160,25],[0,0,0,2,9,192,1,191,0,0,255,255,10,176,0,140,0,0,0,0,9,12,160,25,0,0,0,16,10,176,2,112],[0,0,0,0,10,11,160,25,0,0,0,255,10,160,0,140,0,0,0,1,9,144,32,57,0,0,0,32,10,0,0,138],[0,0,0,65,11,144,0,57,0,0,0,0,10,171,1,111,0,0,0,0,10,167,0,25,0,0,0,0,11,122,0,75],[0,0,0,0,11,0,0,25,0,0,0,1,11,0,64,57,0,0,5,16,12,160,0,156,0,0,19,58,0,0,33,61],[0,0,0,1,11,176,1,144,0,0,19,58,0,0,193,61,0,0,0,64,0,160,4,63,0,0,0,2,10,144,0,57],[0,0,0,0,10,167,4,54,0,0,0,33,11,144,0,57,0,0,0,5,11,176,2,114,0,0,9,170,0,0,97,61],[0,0,0,0,12,33,3,79,0,0,0,0,13,0,0,25,0,0,0,5,14,208,2,16,0,0,0,0,15,234,0,25],[0,0,0,0,14,236,3,79,0,0,0,0,14,14,4,59,0,0,0,0,0,239,4,53,0,0,0,1,13,208,0,57],[0,0,0,0,14,189,0,75,0,0,9,162,0,0,65,61,0,0,0,0,11,0,0,75,0,0,9,172,0,0,97,61],[0,0,0,0,11,7,4,51,0,0,0,0,11,11,0,75,0,0,9,198,0,0,97,61,0,0,0,0,11,10,4,51],[0,0,5,65,11,176,1,151,0,0,0,248,12,144,2,16,0,0,0,0,11,188,1,159,0,0,5,67,11,176,0,65],[0,0,0,0,0,186,4,53,0,0,0,3,9,144,2,16,0,0,0,248,9,144,0,137,0,0,0,0,8,152,1,207],[0,0,0,255,9,144,0,140,0,0,0,0,8,0,32,25,0,0,0,33,9,112,0,57,0,0,10,27,0,0,1,61],[0,0,5,64,8,80,0,156,0,0,19,58,0,0,33,61,0,0,0,64,8,80,0,57,0,0,0,64,0,128,4,63],[0,0,0,0,9,33,3,79,0,0,0,1,8,0,0,58,0,0,0,0,8,133,4,54,0,0,0,0,9,9,4,59],[0,0,0,0,0,152,4,53,0,0,10,123,0,0,193,61,0,0,5,94,1,0,0,65,0,0,0,0,0,16,4,53],[0,0,0,50,1,0,0,57,0,0,0,81,0,0,1,61,0,0,0,31,3,80,1,143,0,0,0,5,2,80,2,114],[0,0,9,213,0,0,97,61,0,0,0,0,4,0,0,25,0,0,0,5,6,64,2,16,0,0,0,0,7,97,3,79],[0,0,0,0,7,7,4,59,0,0,0,0,0,118,4,53,0,0,0,1,4,64,0,57,0,0,0,0,6,36,0,75],[0,0,9,206,0,0,65,61,0,0,0,0,4,3,0,75,0,0,9,227,0,0,97,61,0,0,0,3,3,48,2,16],[0,0,0,5,2,32,2,16,0,0,0,0,4,2,4,51,0,0,0,0,4,52,1,207,0,0,0,0,4,52,2,47],[0,0,0,0,1,33,3,79,0,0,0,0,1,1,4,59,0,0,1,0,3,48,0,137,0,0,0,0,1,49,2,47],[0,0,0,0,1,49,1,207,0,0,0,0,1,65,1,159,0,0,0,0,0,18,4,53,0,0,0,96,1,80,2,16],[0,0,20,30,0,1,4,48,0,0,0,0,2,1,0,75,0,0,11,135,0,0,193,61,0,0,5,42,1,0,0,65],[0,0,0,0,0,16,4,57,0,0,0,9,1,0,0,41,0,0,0,4,0,16,4,67,0,0,5,8,1,0,0,65],[0,0,0,0,2,0,4,20,0,0,5,8,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16],[0,0,5,43,1,16,1,199,0,0,128,2,2,0,0,57,20,28,20,13,0,0,4,15,0,0,0,1,2,32,1,144],[0,0,18,65,0,0,97,61,0,0,0,0,1,1,4,59,0,0,0,0,1,1,0,75,0,0,11,131,0,0,193,61],[0,0,0,64,1,0,4,61,0,0,0,68,2,16,0,57,0,0,5,51,3,0,0,65,0,0,0,0,0,50,4,53],[0,0,0,36,2,16,0,57,0,0,0,29,3,0,0,57,0,0,0,0,0,50,4,53,0,0,5,22,2,0,0,65],[0,0,0,0,0,33,4,53,0,0,0,4,2,16,0,57,0,0,0,4,3,0,0,41,0,0,2,189,0,0,1,61],[0,0,0,64,1,0,4,61,0,0,0,68,2,16,0,57,0,0,5,75,3,0,0,65,0,0,0,0,0,50,4,53],[0,0,0,36,2,16,0,57,0,0,0,31,3,0,0,57,0,0,2,184,0,0,1,61,0,0,5,64,9,112,0,156],[0,0,19,58,0,0,33,61,0,0,0,64,9,112,0,57,0,0,0,64,0,144,4,63,0,0,0,0,10,33,3,79],[0,0,0,1,9,0,0,58,0,0,0,0,9,151,4,54,0,0,0,0,10,10,4,59,0,0,0,0,0,169,4,53],[0,0,9,198,0,0,97,61,0,0,0,248,11,128,2,16,0,0,5,17,12,0,0,65,0,0,0,0,8,8,0,75],[0,0,0,0,12,11,192,25,0,0,5,65,8,160,1,151,0,0,0,0,8,200,1,159,0,0,0,0,0,137,4,53],[0,0,0,64,9,0,4,61,0,0,5,64,8,144,0,156,0,0,19,58,0,0,33,61,0,0,0,32,8,96,0,138],[0,0,0,0,8,129,3,79,0,0,0,0,8,8,4,59,0,0,0,64,10,144,0,57,0,0,0,64,0,160,4,63],[0,0,0,32,10,144,0,57,0,0,5,68,11,0,0,65,0,0,0,0,0,186,4,53,0,0,0,21,10,0,0,57],[0,0,0,0,0,169,4,53,0,0,0,96,8,128,2,16,0,0,0,33,10,144,0,57,0,0,0,0,0,138,4,53],[0,0,0,192,6,96,0,57,0,0,0,0,6,97,3,79,0,0,0,64,8,0,4,61,0,0,0,0,6,6,4,59],[0,8,0,0,0,6,0,29,0,0,0,128,10,96,0,140,0,0,12,152,0,0,65,61,0,0,0,8,6,0,0,41],[0,0,0,128,10,96,2,112,0,0,5,66,11,96,0,156,0,0,0,0,10,6,160,25,0,0,5,66,11,96,0,156],[0,0,0,0,11,0,0,25,0,0,0,16,11,0,32,57,0,0,0,8,12,176,1,191,0,0,5,16,13,160,0,156],[0,0,0,0,12,11,160,25,0,0,0,64,11,160,2,112,0,0,5,16,13,160,0,156,0,0,0,0,11,10,160,25],[0,0,0,4,13,192,1,191,0,0,5,8,10,176,0,156,0,0,0,0,13,12,160,25,0,0,0,32,12,176,2,112],[0,0,5,8,10,176,0,156,0,0,0,0,12,11,160,25,0,0,0,2,10,208,1,191,0,0,255,255,11,192,0,140],[0,0,0,0,10,13,160,25,0,0,0,16,11,192,2,112,0,0,0,0,11,12,160,25,0,0,0,255,11,176,0,140],[0,0,0,1,10,160,32,57,0,0,0,32,11,0,0,138,0,0,0,65,12,160,0,57,0,0,0,0,11,188,1,111],[0,0,0,0,11,184,0,25,0,0,0,0,12,139,0,75,0,0,0,0,12,0,0,25,0,0,0,1,12,0,64,57],[0,0,5,16,13,176,0,156,0,0,19,58,0,0,33,61,0,0,0,1,12,192,1,144,0,0,19,58,0,0,193,61],[0,0,0,64,0,176,4,63,0,0,0,2,11,160,0,57,0,0,0,0,11,184,4,54,0,0,0,33,12,160,0,57],[0,0,0,5,12,192,2,114,0,0,10,104,0,0,97,61,0,0,0,0,13,33,3,79,0,0,0,0,14,0,0,25],[0,0,0,5,15,224,2,16,0,0,0,0,6,251,0,25,0,0,0,0,15,253,3,79,0,0,0,0,15,15,4,59],[0,0,0,0,0,246,4,53,0,0,0,1,14,224,0,57,0,0,0,0,6,206,0,75,0,0,10,96,0,0,65,61],[0,0,0,0,6,0,0,75,0,0,10,106,0,0,97,61,0,0,0,0,6,8,4,51,0,0,0,0,6,6,0,75],[0,0,9,198,0,0,97,61,0,0,0,0,6,11,4,51,0,0,5,65,6,96,1,151,0,0,0,248,12,160,2,16],[0,0,0,0,6,108,1,159,0,0,5,67,6,96,0,65,0,0,0,0,0,107,4,53,0,0,0,3,6,160,2,16],[0,0,0,248,6,96,0,137,0,0,0,8,10,96,1,239,0,0,0,255,6,96,0,140,0,0,0,0,10,0,32,25],[0,0,0,33,6,128,0,57,0,0,0,0,0,166,4,53,0,0,12,170,0,0,1,61,0,0,0,248,10,96,2,16],[0,0,5,17,11,0,0,65,0,0,0,0,6,6,0,75,0,0,0,0,11,10,192,25,0,0,5,65,6,144,1,151],[0,0,0,0,6,182,1,159,0,0,0,0,0,104,4,53,0,0,0,64,6,0,4,61,0,0,0,32,7,112,0,138],[0,0,0,0,8,113,3,79,0,0,0,0,8,8,4,59,0,0,0,128,9,128,0,140,0,0,10,206,0,0,65,61],[0,0,0,128,9,128,2,112,0,0,5,66,10,128,0,156,0,0,0,0,9,8,160,25,0,0,5,66,10,128,0,156],[0,0,0,0,10,0,0,25,0,0,0,16,10,0,32,57,0,0,0,8,11,160,1,191,0,0,5,16,12,144,0,156],[0,0,0,0,11,10,160,25,0,0,0,64,10,144,2,112,0,0,5,16,12,144,0,156,0,0,0,0,10,9,160,25],[0,0,0,4,12,176,1,191,0,0,5,8,9,160,0,156,0,0,0,0,12,11,160,25,0,0,0,32,11,160,2,112],[0,0,5,8,9,160,0,156,0,0,0,0,11,10,160,25,0,0,0,2,9,192,1,191,0,0,255,255,10,176,0,140],[0,0,0,0,9,12,160,25,0,0,0,16,10,176,2,112,0,0,0,0,10,11,160,25,0,0,0,255,10,160,0,140],[0,0,0,1,9,144,32,57,0,0,0,32,10,0,0,138,0,0,0,65,11,144,0,57,0,0,0,0,10,171,1,111],[0,0,0,0,10,166,0,25,0,0,0,0,11,106,0,75,0,0,0,0,11,0,0,25,0,0,0,1,11,0,64,57],[0,0,5,16,12,160,0,156,0,0,19,58,0,0,33,61,0,0,0,1,11,176,1,144,0,0,19,58,0,0,193,61],[0,0,0,64,0,160,4,63,0,0,0,2,10,144,0,57,0,0,0,0,10,166,4,54,0,0,0,33,11,144,0,57],[0,0,0,5,11,176,2,114,0,0,10,188,0,0,97,61,0,0,0,0,12,33,3,79,0,0,0,0,13,0,0,25],[0,0,0,5,14,208,2,16,0,0,0,0,15,234,0,25,0,0,0,0,14,236,3,79,0,0,0,0,14,14,4,59],[0,0,0,0,0,239,4,53,0,0,0,1,13,208,0,57,0,0,0,0,14,189,0,75,0,0,10,180,0,0,65,61],[0,0,0,0,11,0,0,75,0,0,10,190,0,0,97,61,0,0,0,0,11,6,4,51,0,0,0,0,11,11,0,75],[0,0,9,198,0,0,97,61,0,0,0,0,11,10,4,51,0,0,5,65,11,176,1,151,0,0,0,248,12,144,2,16],[0,0,0,0,11,188,1,159,0,0,5,67,11,176,0,65,0,0,0,0,0,186,4,53,0,0,0,3,9,144,2,16],[0,0,0,248,9,144,0,137,0,0,0,0,8,152,1,207,0,0,0,255,9,144,0,140,0,0,0,0,8,0,32,25],[0,0,0,33,9,96,0,57,0,0,10,222,0,0,1,61,0,0,5,64,9,96,0,156,0,0,19,58,0,0,33,61],[0,0,0,64,9,96,0,57,0,0,0,64,0,144,4,63,0,0,0,0,10,33,3,79,0,0,0,1,9,0,0,58],[0,0,0,0,9,150,4,54,0,0,0,0,10,10,4,59,0,0,0,0,0,169,4,53,0,0,9,198,0,0,97,61],[0,0,0,248,11,128,2,16,0,0,5,17,12,0,0,65,0,0,0,0,8,8,0,75,0,0,0,0,12,11,192,25],[0,0,5,65,8,160,1,151,0,0,0,0,8,200,1,159,0,0,0,0,0,137,4,53,0,0,0,64,8,0,4,61],[0,8,0,64,0,112,0,146,0,0,0,8,9,16,3,96,0,0,0,0,9,9,4,59,0,0,0,128,10,144,0,140],[0,0,11,189,0,0,65,61,0,0,0,128,10,144,2,112,0,0,5,66,11,144,0,156,0,0,0,0,10,9,160,25],[0,0,5,66,11,144,0,156,0,0,0,0,11,0,0,25,0,0,0,16,11,0,32,57,0,0,0,8,12,176,1,191],[0,0,5,16,13,160,0,156,0,0,0,0,12,11,160,25,0,0,0,64,11,160,2,112,0,0,5,16,13,160,0,156],[0,0,0,0,11,10,160,25,0,0,0,4,13,192,1,191,0,0,5,8,10,176,0,156,0,0,0,0,13,12,160,25],[0,0,0,32,12,176,2,112,0,0,5,8,10,176,0,156,0,0,0,0,12,11,160,25,0,0,0,2,10,208,1,191],[0,0,255,255,11,192,0,140,0,0,0,0,10,13,160,25,0,0,0,16,11,192,2,112,0,0,0,0,11,12,160,25],[0,0,0,255,11,176,0,140,0,0,0,1,10,160,32,57,0,0,0,32,11,0,0,138,0,0,0,65,12,160,0,57],[0,0,0,0,11,188,1,111,0,0,0,0,11,184,0,25,0,0,0,0,12,139,0,75,0,0,0,0,12,0,0,25],[0,0,0,1,12,0,64,57,0,0,5,16,13,176,0,156,0,0,19,58,0,0,33,61,0,0,0,1,12,192,1,144],[0,0,19,58,0,0,193,61,0,0,0,64,0,176,4,63,0,0,0,2,11,160,0,57,0,0,0,0,11,184,4,54],[0,0,0,33,12,160,0,57,0,0,0,5,12,192,2,114,0,0,11,25,0,0,97,61,0,0,0,0,13,33,3,79],[0,0,0,0,14,0,0,25,0,0,0,5,15,224,2,16,0,0,0,0,7,251,0,25,0,0,0,0,15,253,3,79],[0,0,0,0,15,15,4,59,0,0,0,0,0,247,4,53,0,0,0,1,14,224,0,57,0,0,0,0,7,206,0,75],[0,0,11,17,0,0,65,61,0,0,0,0,7,0,0,75,0,0,11,27,0,0,97,61,0,0,0,0,7,8,4,51],[0,0,0,0,7,7,0,75,0,0,9,198,0,0,97,61,0,0,0,0,7,11,4,51,0,0,5,65,7,112,1,151],[0,0,0,248,12,160,2,16,0,0,0,0,7,124,1,159,0,0,5,67,7,112,0,65,0,0,0,0,0,123,4,53],[0,0,0,3,7,160,2,16,0,0,0,248,7,112,0,137,0,0,0,0,9,121,1,207,0,0,0,255,7,112,0,140],[0,0,0,0,9,0,32,25,0,0,0,33,7,128,0,57,0,0,0,0,0,151,4,53,0,0,11,206,0,0,1,61],[0,0,0,4,6,0,0,41,0,0,5,64,6,96,0,156,0,0,19,58,0,0,33,61,0,0,0,4,7,0,0,41],[0,0,0,64,6,112,0,57,0,0,0,64,0,96,4,63,0,0,0,1,6,0,0,58,0,0,0,0,6,103,4,54],[0,0,0,0,7,5,4,59,0,0,0,0,0,118,4,53,0,0,9,198,0,0,97,61,0,0,0,248,8,32,2,16],[0,0,5,17,9,0,0,65,0,0,0,0,2,2,0,75,0,0,0,0,9,8,192,25,0,0,5,65,2,112,1,151],[0,0,0,0,2,146,1,159,0,0,0,0,0,38,4,53,0,0,0,9,6,64,0,106,0,0,0,160,1,16,0,57],[0,0,0,0,2,19,3,79,0,0,0,0,2,2,4,59,0,0,0,31,6,96,0,138,0,0,5,17,7,96,1,151],[0,0,5,17,8,32,1,151,0,0,5,17,9,0,0,65,0,0,0,0,10,120,0,75,0,0,0,0,10,0,0,25],[0,0,0,0,10,9,64,25,0,0,0,0,7,120,1,63,0,0,0,0,8,98,0,75,0,0,0,0,9,0,64,25],[0,0,5,17,7,112,0,156,0,0,0,0,10,9,192,25,0,0,0,0,7,10,0,75,0,0,1,57,0,0,193,61],[0,0,0,9,8,32,0,41,0,0,0,0,7,131,3,79,0,0,0,0,7,7,4,59,0,0,5,16,9,112,0,156],[0,0,1,57,0,0,33,61,0,0,0,0,9,116,0,73,0,0,0,32,8,128,0,57,0,0,5,17,10,0,0,65],[0,0,0,0,11,152,0,75,0,0,0,0,11,0,0,25,0,0,0,0,11,10,32,25,0,0,5,17,9,144,1,151],[0,0,5,17,12,128,1,151,0,0,0,0,13,156,0,75,0,0,0,0,10,0,128,25,0,0,0,0,9,156,1,63],[0,0,5,17,9,144,0,156,0,0,0,0,10,11,192,25,0,0,0,0,9,10,0,75,0,0,1,57,0,0,193,61],[0,0,0,1,9,112,0,140,0,0,14,78,0,0,193,61,0,0,0,0,5,131,3,79,0,0,0,0,5,5,4,59],[0,0,0,1,7,0,0,138,0,0,5,17,8,0,0,65,0,0,0,0,7,117,0,75,0,0,0,0,7,0,0,25],[0,0,0,0,7,8,32,25,0,0,5,17,5,80,1,151,0,0,5,17,9,80,0,156,0,0,0,0,8,0,128,25],[0,0,5,17,5,80,1,103,0,0,5,17,5,80,0,156,0,0,0,0,8,7,192,25,0,3,0,96,0,0,0,61],[0,0,0,0,5,8,0,75,0,0,14,136,0,0,193,61,0,0,0,64,5,0,4,61,0,3,0,0,0,5,0,29],[0,0,5,64,5,80,0,156,0,0,19,58,0,0,33,61,0,0,0,3,8,0,0,41,0,0,0,64,5,128,0,57],[0,0,0,64,0,80,4,63,0,0,0,32,5,128,0,57,0,0,5,67,7,0,0,65,0,0,0,0,0,117,4,53],[0,0,0,1,5,0,0,57,0,0,0,0,0,88,4,53,0,0,14,136,0,0,1,61,0,0,0,5,1,0,0,41],[0,0,0,0,1,1,4,51,0,0,0,0,2,1,0,75,0,0,11,170,0,0,97,61,0,0,5,17,2,0,0,65],[0,0,0,32,3,16,0,140,0,0,0,0,3,0,0,25,0,0,0,0,3,2,64,25,0,0,5,17,1,16,1,151],[0,0,0,0,4,1,0,75,0,0,0,0,2,0,160,25,0,0,5,17,1,16,0,156,0,0,0,0,2,3,192,25],[0,0,0,0,1,2,0,75,0,0,1,57,0,0,193,61,0,0,0,10,1,0,0,41,0,0,0,0,1,1,4,51],[0,0,0,0,2,1,0,75,0,0,0,0,2,0,0,25,0,0,0,1,2,0,192,57,0,0,0,0,2,33,0,75],[0,0,1,57,0,0,193,61,0,0,0,0,1,1,0,75,0,0,11,170,0,0,193,61,0,0,0,64,1,0,4,61],[0,0,0,100,2,16,0,57,0,0,5,49,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,68,2,16,0,57],[0,0,5,50,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,42,3,0,0,57],[0,0,0,0,0,50,4,53,0,0,5,22,2,0,0,65,0,0,0,0,0,33,4,53,0,0,0,4,2,16,0,57],[0,0,0,4,3,0,0,41,0,0,1,28,0,0,1,61,0,0,0,64,3,0,4,61,0,0,0,36,1,48,0,57],[0,0,0,7,2,0,0,41,0,0,0,0,0,33,4,53,0,0,5,38,1,0,0,65,0,0,0,0,0,19,4,53],[0,10,0,0,0,3,0,29,0,0,0,4,1,48,0,57,0,0,0,6,2,0,0,41,0,0,0,0,0,33,4,53],[0,0,0,0,1,0,4,20,0,0,0,9,2,0,0,41,0,0,0,4,2,32,0,140,0,0,12,49,0,0,193,61],[0,0,0,1,3,0,0,49,0,0,0,32,1,48,0,140,0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57],[0,0,12,99,0,0,1,61,0,0,5,64,7,128,0,156,0,0,19,58,0,0,33,61,0,0,0,64,7,128,0,57],[0,0,0,64,0,112,4,63,0,0,0,0,7,33,3,79,0,0,0,1,10,0,0,58,0,0,0,0,10,168,4,54],[0,0,0,0,11,7,4,59,0,0,0,0,0,186,4,53,0,0,9,198,0,0,97,61,0,0,0,248,7,144,2,16],[0,0,5,17,12,0,0,65,0,0,0,0,9,9,0,75,0,0,0,0,12,7,192,25,0,0,5,65,7,176,1,151],[0,0,0,0,7,199,1,159,0,0,0,0,0,122,4,53,0,0,0,64,10,0,4,61,0,0,5,64,7,160,0,156],[0,0,19,58,0,0,33,61,0,0,0,8,12,0,0,41,0,0,0,32,7,192,0,138,0,0,0,0,7,113,3,79],[0,0,0,0,7,7,4,59,0,0,0,64,9,160,0,57,0,0,0,64,0,144,4,63,0,0,0,32,9,160,0,57],[0,0,5,68,11,0,0,65,0,0,0,0,0,185,4,53,0,0,0,21,9,0,0,57,0,0,0,0,0,154,4,53],[0,0,0,96,7,112,2,16,0,0,0,33,9,160,0,57,0,0,0,0,0,121,4,53,0,0,0,192,7,192,0,57],[0,0,0,0,7,113,3,79,0,0,0,64,9,0,4,61,0,0,0,0,7,7,4,59,0,8,0,0,0,7,0,29],[0,0,0,128,11,112,0,140,0,0,13,116,0,0,65,61,0,0,0,8,7,0,0,41,0,0,0,128,11,112,2,112],[0,0,5,66,12,112,0,156,0,0,0,0,11,7,160,25,0,0,5,66,12,112,0,156,0,0,0,0,12,0,0,25],[0,0,0,16,12,0,32,57,0,0,0,8,13,192,1,191,0,0,5,16,14,176,0,156,0,0,0,0,13,12,160,25],[0,0,0,64,12,176,2,112,0,0,5,16,14,176,0,156,0,0,0,0,12,11,160,25,0,0,0,4,14,208,1,191],[0,0,5,8,11,192,0,156,0,0,0,0,14,13,160,25,0,0,0,32,13,192,2,112,0,0,5,8,11,192,0,156],[0,0,0,0,13,12,160,25,0,0,0,2,7,224,1,191,0,0,255,255,12,208,0,140,0,0,0,0,7,14,160,25],[0,0,0,16,12,208,2,112,0,0,0,0,12,13,160,25,0,0,0,255,12,192,0,140,0,0,0,1,7,112,32,57],[0,0,0,32,12,0,0,138,0,6,0,0,0,7,0,29,0,0,0,65,13,112,0,57,0,0,0,0,12,205,1,111],[0,0,0,0,12,201,0,25,0,0,0,0,13,156,0,75,0,0,0,0,13,0,0,25,0,0,0,1,13,0,64,57],[0,0,5,16,14,192,0,156,0,0,19,58,0,0,33,61,0,0,0,1,13,208,1,144,0,0,19,58,0,0,193,61],[0,0,0,64,0,192,4,63,0,0,0,6,7,0,0,41,0,0,0,2,12,112,0,57,0,0,0,0,12,201,4,54],[0,0,0,33,13,112,0,57,0,0,0,5,13,208,2,114,0,0,12,29,0,0,97,61,0,0,0,0,14,33,3,79],[0,0,0,0,15,0,0,25,0,0,0,5,7,240,2,16,0,0,0,0,11,124,0,25,0,0,0,0,7,126,3,79],[0,0,0,0,7,7,4,59,0,0,0,0,0,123,4,53,0,0,0,1,15,240,0,57,0,0,0,0,7,223,0,75],[0,0,12,21,0,0,65,61,0,0,0,0,7,0,0,75,0,0,12,31,0,0,97,61,0,0,0,0,7,9,4,51],[0,0,0,0,7,7,0,75,0,0,9,198,0,0,97,61,0,0,0,0,7,12,4,51,0,0,5,65,7,112,1,151],[0,0,0,6,13,0,0,41,0,0,0,248,11,208,2,16,0,0,0,0,7,123,1,159,0,0,5,67,7,112,0,65],[0,0,0,0,0,124,4,53,0,0,0,3,7,208,2,16,0,0,0,248,7,112,0,137,0,0,0,8,11,112,1,239],[0,0,0,255,7,112,0,140,0,0,0,0,11,0,32,25,0,0,0,33,7,144,0,57,0,0,0,0,0,183,4,53],[0,0,13,134,0,0,1,61,0,0,5,8,2,0,0,65,0,0,5,8,3,16,0,156,0,0,0,0,1,2,128,25],[0,0,0,10,4,0,0,41,0,0,5,8,3,64,0,156,0,0,0,0,2,4,64,25,0,0,0,64,2,32,2,16],[0,0,0,192,1,16,2,16,0,0,0,0,1,33,1,159,0,0,5,44,1,16,1,199,0,0,0,9,2,0,0,41],[20,28,20,13,0,0,4,15,0,0,0,10,10,0,0,41,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112],[0,0,5,8,3,48,1,151,0,0,0,32,4,48,0,140,0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57],[0,0,0,31,5,64,1,143,0,0,0,5,6,64,2,114,0,0,12,80,0,0,97,61,0,0,0,0,7,0,0,25],[0,0,0,5,8,112,2,16,0,0,0,0,9,138,0,25,0,0,0,0,8,129,3,79,0,0,0,0,8,8,4,59],[0,0,0,0,0,137,4,53,0,0,0,1,7,112,0,57,0,0,0,0,8,103,0,75,0,0,12,72,0,0,65,61],[0,0,0,0,7,5,0,75,0,0,12,95,0,0,97,61,0,0,0,5,6,96,2,16,0,0,0,0,7,97,3,79],[0,0,0,10,6,96,0,41,0,0,0,3,5,80,2,16,0,0,0,0,8,6,4,51,0,0,0,0,8,88,1,207],[0,0,0,0,8,88,2,47,0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137,0,0,0,0,7,87,2,47],[0,0,0,0,5,87,1,207,0,0,0,0,5,133,1,159,0,0,0,0,0,86,4,53,0,1,0,0,0,3,0,31],[0,19,0,0,0,1,3,85,0,0,0,1,2,32,1,144,0,0,13,87,0,0,97,61,0,0,0,31,1,64,0,57],[0,0,0,96,2,16,1,143,0,0,0,10,1,32,0,41,0,0,0,0,2,33,0,75,0,0,0,0,2,0,0,25],[0,0,0,1,2,0,64,57,0,0,5,16,4,16,0,156,0,0,19,58,0,0,33,61,0,0,0,1,2,32,1,144],[0,0,19,58,0,0,193,61,0,0,0,64,0,16,4,63,0,0,0,32,2,48,0,140,0,0,1,57,0,0,65,61],[0,0,0,68,4,16,0,57,0,0,0,36,5,16,0,57,0,0,0,10,2,0,0,41,0,0,0,0,2,2,4,51],[0,0,0,0,2,2,0,75,0,0,14,66,0,0,193,61,0,0,0,32,2,16,0,57,0,0,5,40,6,0,0,65],[0,0,0,0,0,98,4,53,0,0,0,7,6,0,0,41,0,0,0,0,0,101,4,53,0,0,0,8,5,0,0,41],[0,0,0,0,0,84,4,53,0,0,0,1,4,0,0,41,0,0,0,0,0,65,4,53,0,0,5,47,4,16,0,156],[0,0,19,58,0,0,33,61,0,0,0,128,4,16,0,57,0,10,0,0,0,4,0,29,0,0,0,64,0,64,4,63],[0,0,5,48,4,16,0,156,0,0,19,58,0,0,33,61,0,0,0,192,4,16,0,57,0,0,0,64,0,64,4,63],[0,0,0,4,4,0,0,41,0,0,0,10,5,0,0,41,0,0,0,0,0,69,4,53,0,0,0,160,5,16,0,57],[0,0,5,41,4,0,0,65,0,7,0,0,0,5,0,29,0,0,0,0,0,69,4,53,0,0,0,0,4,1,4,51],[0,0,0,0,1,0,4,20,0,0,0,9,5,0,0,41,0,0,0,4,5,80,0,140,0,0,15,63,0,0,193,61],[0,0,0,1,2,0,0,57,0,0,5,16,1,48,0,156,0,0,19,58,0,0,33,61,0,0,15,85,0,0,1,61],[0,0,5,64,6,128,0,156,0,0,19,58,0,0,33,61,0,0,0,64,6,128,0,57,0,0,0,64,0,96,4,63],[0,0,0,0,6,33,3,79,0,0,0,1,10,0,0,58,0,0,0,0,10,168,4,54,0,0,0,0,11,6,4,59],[0,0,0,0,0,186,4,53,0,0,9,198,0,0,97,61,0,0,0,8,13,0,0,41,0,0,0,248,6,208,2,16],[0,0,5,17,12,0,0,65,0,0,0,0,13,13,0,75,0,0,0,0,12,6,192,25,0,0,5,65,6,176,1,151],[0,0,0,0,6,198,1,159,0,0,0,0,0,106,4,53,0,0,0,64,6,0,4,61,0,0,0,32,11,96,0,57],[0,0,0,0,10,3,4,51,0,0,0,0,12,10,0,75,0,0,12,183,0,0,97,61,0,0,0,0,12,0,0,25],[0,0,0,0,13,188,0,25,0,0,0,32,12,192,0,57,0,0,0,0,14,60,0,25,0,0,0,0,14,14,4,51],[0,0,0,0,0,237,4,53,0,0,0,0,13,172,0,75,0,0,12,176,0,0,65,61,0,0,0,0,3,186,0,25],[0,0,0,0,0,3,4,53,0,0,0,0,3,106,0,25,0,0,0,32,11,48,0,57,0,0,0,0,10,4,4,51],[0,0,0,0,12,10,0,75,0,0,12,198,0,0,97,61,0,0,0,0,12,0,0,25,0,0,0,0,13,188,0,25],[0,0,0,32,12,192,0,57,0,0,0,0,14,76,0,25,0,0,0,0,14,14,4,51,0,0,0,0,0,237,4,53],[0,0,0,0,13,172,0,75,0,0,12,191,0,0,65,61,0,0,0,0,4,186,0,25,0,0,0,0,0,4,4,53],[0,0,0,0,3,58,0,25,0,0,0,32,10,48,0,57,0,0,0,0,4,5,4,51,0,0,0,0,11,4,0,75],[0,0,12,213,0,0,97,61,0,0,0,0,11,0,0,25,0,0,0,0,12,171,0,25,0,0,0,32,11,176,0,57],[0,0,0,0,13,91,0,25,0,0,0,0,13,13,4,51,0,0,0,0,0,220,4,53,0,0,0,0,12,75,0,75],[0,0,12,206,0,0,65,61,0,0,0,0,5,164,0,25,0,0,0,0,0,5,4,53,0,0,0,0,3,52,0,25],[0,0,0,32,5,48,0,57,0,0,0,0,4,7,4,51,0,0,0,0,10,4,0,75,0,0,12,228,0,0,97,61],[0,0,0,0,10,0,0,25,0,0,0,0,11,90,0,25,0,0,0,32,10,160,0,57,0,0,0,0,12,122,0,25],[0,0,0,0,12,12,4,51,0,0,0,0,0,203,4,53,0,0,0,0,11,74,0,75,0,0,12,221,0,0,65,61],[0,0,0,0,5,84,0,25,0,0,0,0,0,5,4,53,0,0,0,0,3,52,0,25,0,0,0,32,5,48,0,57],[0,0,0,0,4,9,4,51,0,0,0,0,7,4,0,75,0,0,12,243,0,0,97,61,0,0,0,0,7,0,0,25],[0,0,0,0,10,87,0,25,0,0,0,32,7,112,0,57,0,0,0,0,11,151,0,25,0,0,0,0,11,11,4,51],[0,0,0,0,0,186,4,53,0,0,0,0,10,71,0,75,0,0,12,236,0,0,65,61,0,0,0,0,5,84,0,25],[0,0,0,0,0,5,4,53,0,0,0,0,3,52,0,25,0,0,0,32,5,48,0,57,0,0,0,0,4,8,4,51],[0,0,0,0,7,4,0,75,0,0,13,2,0,0,97,61,0,0,0,0,7,0,0,25,0,0,0,0,9,87,0,25],[0,0,0,32,7,112,0,57,0,0,0,0,10,135,0,25,0,0,0,0,10,10,4,51,0,0,0,0,0,169,4,53],[0,0,0,0,9,71,0,75,0,0,12,251,0,0,65,61,0,0,0,0,5,84,0,25,0,0,0,0,0,5,4,53],[0,0,0,0,3,99,0,73,0,0,0,0,3,52,0,25,0,0,0,0,0,54,4,53,0,0,0,63,4,48,0,57],[0,0,0,32,3,0,0,138,0,0,0,0,4,52,1,111,0,0,0,0,7,100,0,25,0,0,0,0,4,71,0,75],[0,0,0,0,4,0,0,25,0,0,0,1,4,0,64,57,0,0,5,16,5,112,0,156,0,0,19,58,0,0,33,61],[0,0,0,1,4,64,1,144,0,0,19,58,0,0,193,61,0,0,0,64,0,112,4,63,0,0,0,10,5,0,0,41],[0,0,1,196,4,80,0,57,0,0,0,0,4,65,3,79,0,0,0,0,5,82,0,73,0,0,0,35,5,80,0,138],[0,0,0,0,4,4,4,59,0,0,5,17,8,0,0,65,0,0,0,0,9,84,0,75,0,0,0,0,9,0,0,25],[0,0,0,0,9,8,128,25,0,0,5,17,5,80,1,151,0,0,5,17,10,64,1,151,0,0,0,0,11,90,0,75],[0,0,0,0,8,0,128,25,0,0,0,0,5,90,1,63,0,0,5,17,5,80,0,156,0,0,0,0,8,9,192,25],[0,0,0,0,5,8,0,75,0,0,1,57,0,0,193,61,0,0,0,9,5,64,0,41,0,0,0,0,4,81,3,79],[0,0,0,0,4,4,4,59,0,0,5,16,8,64,0,156,0,0,1,57,0,0,33,61,0,0,0,0,8,66,0,73],[0,0,0,32,5,80,0,57,0,0,5,17,9,0,0,65,0,0,0,0,10,133,0,75,0,0,0,0,10,0,0,25],[0,0,0,0,10,9,32,25,0,0,5,17,8,128,1,151,0,0,5,17,11,80,1,151,0,0,0,0,12,139,0,75],[0,0,0,0,9,0,128,25,0,0,0,0,8,139,1,63,0,0,5,17,8,128,0,156,0,0,0,0,9,10,192,25],[0,0,0,0,8,9,0,75,0,0,1,57,0,0,193,61,0,0,0,1,8,64,0,140,0,0,15,161,0,0,193,61],[0,0,0,0,8,81,3,79,0,0,0,0,8,8,4,59,0,0,0,1,9,0,0,138,0,0,5,17,10,0,0,65],[0,0,0,0,9,152,0,75,0,0,0,0,9,0,0,25,0,0,0,0,9,10,32,25,0,0,5,17,8,128,1,151],[0,0,5,17,11,128,0,156,0,0,0,0,10,0,128,25,0,0,5,17,8,128,1,103,0,0,5,17,8,128,0,156],[0,0,0,0,10,9,192,25,0,0,0,96,8,0,0,57,0,0,0,0,9,10,0,75,0,0,16,59,0,0,193,61],[0,0,5,64,8,112,0,156,0,0,19,58,0,0,33,61,0,0,0,64,8,112,0,57,0,0,0,64,0,128,4,63],[0,0,0,32,8,112,0,57,0,0,5,67,9,0,0,65,0,0,0,0,0,152,4,53,0,0,0,1,8,0,0,57],[0,0,0,0,0,135,4,53,0,0,0,0,8,7,0,25,0,0,16,59,0,0,1,61,0,0,0,64,2,0,4,61],[0,0,0,31,4,48,1,143,0,0,0,5,5,48,2,114,0,0,13,100,0,0,97,61,0,0,0,0,6,0,0,25],[0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59],[0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,13,92,0,0,65,61],[0,0,0,0,6,4,0,75,0,0,13,115,0,0,97,61,0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79],[0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207],[0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47],[0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,6,130,0,0,1,61],[0,0,5,64,7,144,0,156,0,0,19,58,0,0,33,61,0,0,0,64,7,144,0,57,0,0,0,64,0,112,4,63],[0,0,0,0,7,33,3,79,0,0,0,1,11,0,0,58,0,0,0,0,11,185,4,54,0,0,0,0,12,7,4,59],[0,0,0,0,0,203,4,53,0,0,9,198,0,0,97,61,0,0,0,8,14,0,0,41,0,0,0,248,7,224,2,16],[0,0,5,17,13,0,0,65,0,0,0,0,14,14,0,75,0,0,0,0,13,7,192,25,0,0,5,65,7,192,1,151],[0,0,0,0,7,215,1,159,0,0,0,0,0,123,4,53,0,0,0,64,7,0,4,61,0,0,0,32,12,112,0,57],[0,0,0,0,11,3,4,51,0,0,0,0,13,11,0,75,0,0,13,147,0,0,97,61,0,0,0,0,13,0,0,25],[0,0,0,0,14,205,0,25,0,0,0,32,13,208,0,57,0,0,0,0,15,61,0,25,0,0,0,0,15,15,4,51],[0,0,0,0,0,254,4,53,0,0,0,0,14,189,0,75,0,0,13,140,0,0,65,61,0,0,0,0,3,203,0,25],[0,0,0,0,0,3,4,53,0,0,0,0,3,123,0,25,0,0,0,32,12,48,0,57,0,0,0,0,11,4,4,51],[0,0,0,0,13,11,0,75,0,0,13,162,0,0,97,61,0,0,0,0,13,0,0,25,0,0,0,0,14,205,0,25],[0,0,0,32,13,208,0,57,0,0,0,0,15,77,0,25,0,0,0,0,15,15,4,51,0,0,0,0,0,254,4,53],[0,0,0,0,14,189,0,75,0,0,13,155,0,0,65,61,0,0,0,0,4,203,0,25,0,0,0,0,0,4,4,53],[0,0,0,0,3,59,0,25,0,0,0,32,11,48,0,57,0,0,0,0,4,5,4,51,0,0,0,0,12,4,0,75],[0,0,13,177,0,0,97,61,0,0,0,0,12,0,0,25,0,0,0,0,13,188,0,25,0,0,0,32,12,192,0,57],[0,0,0,0,14,92,0,25,0,0,0,0,14,14,4,51,0,0,0,0,0,237,4,53,0,0,0,0,13,76,0,75],[0,0,13,170,0,0,65,61,0,0,0,0,5,180,0,25,0,0,0,0,0,5,4,53,0,0,0,0,3,52,0,25],[0,0,0,32,5,48,0,57,0,0,0,0,4,6,4,51,0,0,0,0,11,4,0,75,0,0,13,192,0,0,97,61],[0,0,0,0,11,0,0,25,0,0,0,0,12,91,0,25,0,0,0,32,11,176,0,57,0,0,0,0,13,107,0,25],[0,0,0,0,13,13,4,51,0,0,0,0,0,220,4,53,0,0,0,0,12,75,0,75,0,0,13,185,0,0,65,61],[0,0,0,0,5,84,0,25,0,0,0,0,0,5,4,53,0,0,0,0,3,52,0,25,0,0,0,32,5,48,0,57],[0,0,0,0,4,8,4,51,0,0,0,0,6,4,0,75,0,0,13,207,0,0,97,61,0,0,0,0,6,0,0,25],[0,0,0,0,11,86,0,25,0,0,0,32,6,96,0,57,0,0,0,0,12,134,0,25,0,0,0,0,12,12,4,51],[0,0,0,0,0,203,4,53,0,0,0,0,11,70,0,75,0,0,13,200,0,0,65,61,0,0,0,0,5,84,0,25],[0,0,0,0,0,5,4,53,0,0,0,0,3,52,0,25,0,0,0,32,5,48,0,57,0,0,0,0,4,10,4,51],[0,0,0,0,6,4,0,75,0,0,13,222,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,0,8,86,0,25],[0,0,0,32,6,96,0,57,0,0,0,0,11,166,0,25,0,0,0,0,11,11,4,51,0,0,0,0,0,184,4,53],[0,0,0,0,8,70,0,75,0,0,13,215,0,0,65,61,0,0,0,0,5,84,0,25,0,0,0,0,0,5,4,53],[0,0,0,0,3,52,0,25,0,0,0,32,5,48,0,57,0,0,0,0,4,9,4,51,0,0,0,0,6,4,0,75],[0,0,13,237,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,0,8,86,0,25,0,0,0,32,6,96,0,57],[0,0,0,0,10,150,0,25,0,0,0,0,10,10,4,51,0,0,0,0,0,168,4,53,0,0,0,0,8,70,0,75],[0,0,13,230,0,0,65,61,0,0,0,0,5,84,0,25,0,0,0,0,0,5,4,53,0,0,0,0,3,115,0,73],[0,0,0,0,3,52,0,25,0,0,0,0,0,55,4,53,0,0,0,63,4,48,0,57,0,0,0,32,3,0,0,138],[0,0,0,0,4,52,1,111,0,0,0,0,6,116,0,25,0,0,0,0,4,70,0,75,0,0,0,0,4,0,0,25],[0,0,0,1,4,0,64,57,0,0,5,16,5,96,0,156,0,0,19,58,0,0,33,61,0,0,0,1,4,64,1,144],[0,0,19,58,0,0,193,61,0,0,0,64,0,96,4,63,0,0,0,10,5,0,0,41,0,0,1,196,4,80,0,57],[0,0,0,0,4,65,3,79,0,0,0,0,5,82,0,73,0,0,0,35,5,80,0,138,0,0,0,0,4,4,4,59],[0,0,5,17,8,0,0,65,0,0,0,0,9,84,0,75,0,0,0,0,9,0,0,25,0,0,0,0,9,8,128,25],[0,0,5,17,5,80,1,151,0,0,5,17,10,64,1,151,0,0,0,0,11,90,0,75,0,0,0,0,8,0,128,25],[0,0,0,0,5,90,1,63,0,0,5,17,5,80,0,156,0,0,0,0,8,9,192,25,0,0,0,0,5,8,0,75],[0,0,1,57,0,0,193,61,0,0,0,9,5,64,0,41,0,0,0,0,4,81,3,79,0,0,0,0,4,4,4,59],[0,0,5,16,8,64,0,156,0,0,1,57,0,0,33,61,0,0,0,0,8,66,0,73,0,0,0,32,5,80,0,57],[0,0,5,17,9,0,0,65,0,0,0,0,10,133,0,75,0,0,0,0,10,0,0,25,0,0,0,0,10,9,32,25],[0,0,5,17,8,128,1,151,0,0,5,17,11,80,1,151,0,0,0,0,12,139,0,75,0,0,0,0,9,0,128,25],[0,0,0,0,8,139,1,63,0,0,5,17,8,128,0,156,0,0,0,0,9,10,192,25,0,0,0,0,8,9,0,75],[0,0,1,57,0,0,193,61,0,0,0,1,8,64,0,140,0,0,17,74,0,0,193,61,0,0,0,0,8,81,3,79],[0,0,0,0,8,8,4,59,0,0,0,1,9,0,0,138,0,0,5,17,10,0,0,65,0,0,0,0,9,152,0,75],[0,0,0,0,9,0,0,25,0,0,0,0,9,10,32,25,0,0,5,17,8,128,1,151,0,0,5,17,11,128,0,156],[0,0,0,0,10,0,128,25,0,0,5,17,8,128,1,103,0,0,5,17,8,128,0,156,0,0,0,0,10,9,192,25],[0,0,0,96,8,0,0,57,0,0,0,0,9,10,0,75,0,0,19,55,0,0,193,61,0,0,5,64,8,96,0,156],[0,0,19,58,0,0,33,61,0,0,0,64,8,96,0,57,0,0,0,64,0,128,4,63,0,0,0,32,8,96,0,57],[0,0,5,67,9,0,0,65,0,0,0,0,0,152,4,53,0,0,0,1,8,0,0,57,0,0,0,0,0,134,4,53],[0,0,0,0,8,6,0,25,0,0,19,55,0,0,1,61,0,0,5,22,2,0,0,65,0,0,0,0,0,33,4,53],[0,0,0,4,2,16,0,57,0,0,0,4,3,0,0,41,0,0,0,0,0,50,4,53,0,0,0,54,2,0,0,57],[0,0,0,0,0,37,4,53,0,0,5,45,2,0,0,65,0,0,0,0,0,36,4,53,0,0,0,100,2,16,0,57],[0,0,5,46,3,0,0,65,0,0,1,28,0,0,1,61,0,0,0,64,8,0,4,61,0,3,0,0,0,8,0,29],[0,0,0,56,8,112,0,140,0,0,14,120,0,0,65,61,0,0,0,32,9,112,2,112,0,0,5,8,8,112,0,156],[0,0,0,0,9,7,160,25,0,0,5,8,8,112,0,156,0,0,0,0,10,0,0,25,0,0,0,4,10,0,32,57],[0,0,0,2,8,160,1,191,0,0,255,255,11,144,0,140,0,0,0,0,8,10,160,25,0,0,0,16,10,144,2,112],[0,0,0,0,10,9,160,25,0,0,0,255,9,160,0,140,0,0,0,0,9,0,0,25,0,0,0,1,9,0,32,57],[0,0,0,3,10,0,0,41,0,0,5,64,10,160,0,156,0,0,19,58,0,0,33,61,0,0,0,0,8,152,1,159],[0,0,0,3,10,0,0,41,0,0,0,64,9,160,0,57,0,0,0,64,0,144,4,63,0,0,0,2,9,128,0,58],[0,0,0,0,9,154,4,54,0,0,0,0,5,5,4,59,0,0,0,0,0,89,4,53,0,0,9,198,0,0,97,61],[0,0,5,65,5,80,1,151,0,0,0,248,10,128,2,16,0,0,0,0,5,90,1,159,0,0,5,69,5,80,1,199],[0,0,0,0,0,89,4,53,0,0,0,3,5,128,2,16,0,0,0,248,5,80,1,95,0,0,0,0,5,87,1,207],[0,0,0,3,7,0,0,41,0,0,0,33,7,112,0,57,0,0,0,0,0,87,4,53,0,0,14,136,0,0,1,61],[0,0,0,3,8,0,0,41,0,0,5,64,8,128,0,156,0,0,19,58,0,0,33,61,0,0,0,3,9,0,0,41],[0,0,0,64,8,144,0,57,0,0,0,64,0,128,4,63,0,0,0,1,8,0,0,58,0,0,0,0,8,137,4,54],[0,0,0,0,5,5,4,59,0,0,0,0,0,88,4,53,0,0,9,198,0,0,97,61,0,0,0,248,7,112,2,16],[0,0,5,65,5,80,1,151,0,0,0,0,5,117,1,159,0,0,5,17,5,80,1,103,0,0,0,0,0,88,4,53],[0,0,0,128,1,16,0,138,0,0,0,0,5,19,3,79,0,0,0,96,1,0,0,57,0,0,0,0,5,5,4,59],[0,0,0,0,5,5,0,75,0,0,14,232,0,0,193,61,0,0,5,17,5,0,0,65,0,0,0,0,7,98,0,75],[0,0,0,0,7,0,0,25,0,0,0,0,7,5,128,25,0,0,5,17,6,96,1,151,0,0,5,17,8,32,1,151],[0,0,0,0,9,104,0,75,0,0,0,0,5,0,128,25,0,0,0,0,6,104,1,63,0,0,5,17,6,96,0,156],[0,0,0,0,5,7,192,25,0,0,0,0,5,5,0,75,0,0,1,57,0,0,193,61,0,0,0,8,5,0,0,41],[0,0,0,0,6,5,4,51,0,0,0,6,5,0,0,41,0,0,0,0,7,5,4,51,0,0,0,5,5,0,0,41],[0,0,0,0,8,5,4,51,0,0,0,4,5,0,0,41,0,0,0,0,9,5,4,51,0,0,0,3,5,0,0,41],[0,0,0,0,10,5,4,51,0,0,0,9,5,32,0,41,0,0,0,0,2,83,3,79,0,0,0,0,2,2,4,59],[0,0,5,16,11,32,0,156,0,0,1,57,0,0,33,61,0,0,0,0,11,36,0,73,0,0,0,32,5,80,0,57],[0,0,5,17,12,0,0,65,0,0,0,0,13,181,0,75,0,0,0,0,13,0,0,25,0,0,0,0,13,12,32,25],[0,0,5,17,11,176,1,151,0,0,5,17,14,80,1,151,0,0,0,0,15,190,0,75,0,0,0,0,12,0,128,25],[0,0,0,0,11,190,1,63,0,0,5,17,11,176,0,156,0,0,0,0,12,13,192,25,0,0,0,0,11,12,0,75],[0,0,1,57,0,0,193,61,0,0,0,0,6,103,0,25,0,0,0,0,6,134,0,25,0,0,0,0,6,150,0,25],[0,0,0,0,6,166,0,25,0,0,0,0,6,38,0,25,0,0,0,0,7,1,4,51,0,0,0,0,6,118,0,25],[0,0,0,64,7,0,4,61,0,0,5,16,6,96,1,151,0,0,0,56,8,96,0,140,0,0,16,122,0,0,65,61],[0,0,0,32,9,96,2,112,0,0,5,8,8,96,0,156,0,0,0,0,9,6,160,25,0,0,5,8,8,96,0,156],[0,0,0,0,10,0,0,25,0,0,0,4,10,0,32,57,0,0,0,2,8,160,1,191,0,0,255,255,11,144,0,140],[0,0,0,0,8,10,160,25,0,0,0,16,10,144,2,112,0,0,0,0,10,9,160,25,0,0,0,255,9,160,0,140],[0,0,0,0,9,0,0,25,0,0,0,1,9,0,32,57,0,0,5,64,10,112,0,156,0,0,19,58,0,0,33,61],[0,0,0,0,8,152,1,159,0,0,0,64,9,112,0,57,0,0,0,64,0,144,4,63,0,0,0,0,9,67,3,79],[0,0,0,2,4,128,0,58,0,0,0,0,4,71,4,54,0,0,0,0,9,9,4,59,0,0,0,0,0,148,4,53],[0,0,9,198,0,0,97,61,0,0,5,65,9,144,1,151,0,0,0,248,10,128,2,16,0,0,0,0,9,154,1,159],[0,0,5,71,9,144,1,199,0,0,0,0,0,148,4,53,0,0,0,3,4,128,2,16,0,0,0,248,4,64,1,95],[0,0,0,0,4,70,1,207,0,0,0,33,6,112,0,57,0,0,0,0,0,70,4,53,0,0,16,137,0,0,1,61],[0,0,5,62,1,0,0,65,0,0,0,0,0,16,4,57,0,0,5,8,1,0,0,65,0,0,0,0,2,0,4,20],[0,0,5,8,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,5,63,1,16,1,199],[0,0,128,11,2,0,0,57,20,28,20,13,0,0,4,15,0,0,0,1,2,32,1,144,0,0,18,65,0,0,97,61],[0,0,0,64,2,0,4,61,0,0,0,0,1,1,4,59,0,0,0,128,3,16,0,140,0,0,15,200,0,0,65,61],[0,0,0,128,3,16,2,112,0,0,5,66,4,16,0,156,0,0,0,0,3,1,160,25,0,0,5,66,4,16,0,156],[0,0,0,0,4,0,0,25,0,0,0,16,4,0,32,57,0,0,0,8,5,64,1,191,0,0,5,16,6,48,0,156],[0,0,0,0,5,4,160,25,0,0,0,64,4,48,2,112,0,0,5,16,6,48,0,156,0,0,0,0,4,3,160,25],[0,0,0,4,3,80,1,191,0,0,5,8,6,64,0,156,0,0,0,0,3,5,160,25,0,0,0,32,6,64,2,112],[0,0,5,8,5,64,0,156,0,0,0,0,6,4,160,25,0,0,0,2,5,48,1,191,0,0,255,255,4,96,0,140],[0,0,0,0,5,3,160,25,0,0,0,16,3,96,2,112,0,0,0,0,3,6,160,25,0,0,0,255,3,48,0,140],[0,0,0,1,5,80,32,57,0,0,0,65,3,80,0,57,0,0,0,2,3,48,1,127,0,0,0,0,3,50,0,25],[0,0,0,0,4,35,0,75,0,0,0,0,4,0,0,25,0,0,0,1,4,0,64,57,0,0,5,16,6,48,0,156],[0,0,19,58,0,0,33,61,0,0,0,1,4,64,1,144,0,0,19,58,0,0,193,61,0,0,0,64,0,48,4,63],[0,0,0,2,3,80,0,57,0,0,0,0,6,50,4,54,0,0,0,18,3,0,3,103,0,0,0,0,4,0,0,49],[0,0,0,33,7,80,0,57,0,0,0,5,7,112,2,114,0,0,15,45,0,0,97,61,0,0,0,0,8,67,3,79],[0,0,0,0,9,0,0,25,0,0,0,5,10,144,2,16,0,0,0,0,11,166,0,25,0,0,0,0,10,168,3,79],[0,0,0,0,10,10,4,59,0,0,0,0,0,171,4,53,0,0,0,1,9,144,0,57,0,0,0,0,10,121,0,75],[0,0,15,37,0,0,65,61,0,0,0,0,7,0,0,75,0,0,15,47,0,0,97,61,0,0,0,0,7,2,4,51],[0,0,0,0,7,7,0,75,0,0,9,198,0,0,97,61,0,0,0,0,7,6,4,51,0,0,5,65,7,112,1,151],[0,0,0,248,8,80,2,16,0,0,0,0,7,120,1,159,0,0,5,67,7,112,0,65,0,0,0,0,0,118,4,53],[0,0,0,3,5,80,2,16,0,0,0,248,5,80,0,137,0,0,0,0,1,81,1,207,0,0,0,255,5,80,0,140],[0,0,0,0,1,0,32,25,0,0,0,33,5,32,0,57,0,0,15,218,0,0,1,61,0,0,5,8,3,0,0,65],[0,0,5,8,5,32,0,156,0,0,0,0,2,3,128,25,0,0,0,64,2,32,2,16,0,0,5,8,5,64,0,156],[0,0,0,0,4,3,128,25,0,0,0,96,4,64,2,16,0,0,0,0,2,36,1,159,0,0,5,8,4,16,0,156],[0,0,0,0,1,3,128,25,0,0,0,192,1,16,2,16,0,0,0,0,1,18,1,159,0,0,0,9,2,0,0,41],[20,28,20,8,0,0,4,15,0,8,0,96,0,0,0,61,0,6,0,128,0,0,0,61,0,0,0,1,2,32,1,143],[0,19,0,0,0,1,3,85,0,0,0,96,1,16,2,112,0,1,5,8,0,16,1,157,0,0,5,8,3,16,1,152],[0,0,15,130,0,0,97,61,0,0,0,63,1,48,0,57,0,0,0,32,4,0,0,138,0,0,0,0,1,65,1,111],[0,0,0,64,4,0,4,61,0,0,0,0,1,20,0,25,0,8,0,0,0,4,0,29,0,0,0,0,4,65,0,75],[0,0,0,0,4,0,0,25,0,0,0,1,4,0,64,57,0,0,5,16,5,16,0,156,0,0,19,58,0,0,33,61],[0,0,0,1,4,64,1,144,0,0,19,58,0,0,193,61,0,0,0,64,0,16,4,63,0,0,0,31,1,48,1,143],[0,0,0,8,4,0,0,41,0,0,0,0,8,52,4,54,0,0,0,19,4,0,3,103,0,0,0,5,3,48,2,114],[0,0,15,114,0,0,97,61,0,0,0,0,5,0,0,25,0,0,0,5,6,80,2,16,0,0,0,0,7,104,0,25],[0,0,0,0,6,100,3,79,0,0,0,0,6,6,4,59,0,0,0,0,0,103,4,53,0,0,0,1,5,80,0,57],[0,0,0,0,6,53,0,75,0,0,15,106,0,0,65,61,0,6,0,0,0,8,0,29,0,0,0,0,5,1,0,75],[0,0,15,130,0,0,97,61,0,0,0,5,3,48,2,16,0,0,0,0,4,52,3,79,0,0,0,6,3,48,0,41],[0,0,0,3,1,16,2,16,0,0,0,0,5,3,4,51,0,0,0,0,5,21,1,207,0,0,0,0,5,21,2,47],[0,0,0,0,4,4,4,59,0,0,1,0,1,16,0,137,0,0,0,0,4,20,2,47,0,0,0,0,1,20,1,207],[0,0,0,0,1,81,1,159,0,0,0,0,0,19,4,53,0,0,0,8,1,0,0,41,0,0,0,0,1,1,4,51],[0,0,0,0,2,2,0,75,0,0,15,255,0,0,193,61,0,0,0,0,2,1,0,75,0,0,16,117,0,0,193,61],[0,0,0,64,4,0,4,61,0,9,0,0,0,4,0,29,0,0,5,22,1,0,0,65,0,0,0,0,0,20,4,53],[0,0,0,4,1,64,0,57,0,0,0,4,2,0,0,41,0,0,0,0,0,33,4,53,0,0,0,10,1,0,0,41],[0,0,0,0,3,1,4,51,0,10,0,0,0,3,0,29,0,0,0,36,1,64,0,57,0,0,0,0,0,49,4,53],[0,0,0,68,2,64,0,57,0,0,0,7,1,0,0,41,20,28,19,250,0,0,4,15,0,0,0,10,1,0,0,41],[0,0,0,31,1,16,0,57,0,0,0,32,2,0,0,138,0,0,0,0,1,33,1,111,0,0,0,68,1,16,0,57],[0,0,5,8,2,0,0,65,0,0,5,8,3,16,0,156,0,0,0,0,1,2,128,25,0,0,0,9,4,0,0,41],[0,0,9,91,0,0,1,61,0,0,0,56,8,64,0,140,0,0,16,43,0,0,65,61,0,0,0,32,9,64,2,112],[0,0,5,8,8,64,0,156,0,0,0,0,9,4,160,25,0,0,5,8,8,64,0,156,0,0,0,0,10,0,0,25],[0,0,0,4,10,0,32,57,0,0,0,2,8,160,1,191,0,0,255,255,11,144,0,140,0,0,0,0,8,10,160,25],[0,0,0,16,10,144,2,112,0,0,0,0,10,9,160,25,0,0,0,255,9,160,0,140,0,0,0,0,9,0,0,25],[0,0,0,1,9,0,32,57,0,0,5,64,10,112,0,156,0,0,19,58,0,0,33,61,0,0,0,0,8,152,1,159],[0,0,0,64,9,112,0,57,0,0,0,64,0,144,4,63,0,0,0,0,10,33,3,79,0,0,0,2,9,128,0,58],[0,0,0,0,9,151,4,54,0,0,0,0,10,10,4,59,0,0,0,0,0,169,4,53,0,0,9,198,0,0,97,61],[0,0,5,65,10,160,1,151,0,0,0,248,11,128,2,16,0,0,0,0,10,171,1,159,0,0,5,69,10,160,1,199],[0,0,0,0,0,169,4,53,0,0,0,3,8,128,2,16,0,0,0,248,8,128,1,95,0,0,0,0,8,132,1,207],[0,0,0,33,9,112,0,57,0,0,0,0,0,137,4,53,0,0,0,0,8,7,0,25,0,0,16,59,0,0,1,61],[0,0,5,64,3,32,0,156,0,0,19,58,0,0,33,61,0,0,0,64,3,32,0,57,0,0,0,64,0,48,4,63],[0,0,0,1,3,0,0,58,0,0,0,0,5,50,4,54,0,0,0,0,4,0,0,49,0,0,0,18,3,0,3,103],[0,0,0,0,6,67,3,79,0,0,0,0,6,6,4,59,0,0,0,0,0,101,4,53,0,0,9,198,0,0,97,61],[0,0,0,248,7,16,2,16,0,0,5,17,8,0,0,65,0,0,0,0,1,1,0,75,0,0,0,0,8,7,192,25],[0,0,5,65,1,96,1,151,0,0,0,0,1,129,1,159,0,0,0,0,0,21,4,53,0,0,0,64,1,0,4,61],[0,0,0,32,6,16,0,57,0,0,0,0,5,2,4,51,0,0,0,0,7,5,0,75,0,0,15,232,0,0,97,61],[0,0,0,0,7,0,0,25,0,0,0,0,8,103,0,25,0,0,0,32,7,112,0,57,0,0,0,0,9,39,0,25],[0,0,0,0,9,9,4,51,0,0,0,0,0,152,4,53,0,0,0,0,8,87,0,75,0,0,15,225,0,0,65,61],[0,0,0,0,2,101,0,25,0,0,5,83,6,0,0,65,0,0,0,0,0,98,4,53,0,0,0,2,2,80,0,57],[0,0,0,0,0,33,4,53,0,0,0,65,2,80,0,57,0,0,0,2,5,32,1,127,0,0,0,0,2,21,0,25],[0,0,0,0,5,82,0,75,0,0,0,0,5,0,0,25,0,0,0,1,5,0,64,57,0,0,5,16,6,32,0,156],[0,0,19,58,0,0,33,61,0,0,0,1,5,80,1,144,0,0,19,58,0,0,193,61,0,0,0,10,6,0,0,41],[0,0,1,196,5,96,0,57,0,0,0,64,0,32,4,63,0,0,0,0,2,83,3,79,0,0,0,0,5,100,0,73],[0,0,0,35,6,80,0,138,0,0,0,0,2,2,4,59,0,0,14,142,0,0,1,61,0,0,0,0,2,1,0,75],[0,0,16,22,0,0,193,61,0,0,5,42,1,0,0,65,0,0,0,0,0,16,4,57,0,0,0,9,1,0,0,41],[0,0,0,4,0,16,4,67,0,0,5,8,1,0,0,65,0,0,0,0,2,0,4,20,0,0,5,8,3,32,0,156],[0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,5,43,1,16,1,199,0,0,128,2,2,0,0,57],[20,28,20,13,0,0,4,15,0,0,0,1,2,32,1,144,0,0,18,65,0,0,97,61,0,0,0,0,1,1,4,59],[0,0,0,0,1,1,0,75,0,0,9,248,0,0,97,61,0,0,0,8,1,0,0,41,0,0,0,0,1,1,4,51],[0,0,0,0,2,1,0,75,0,0,4,34,0,0,97,61,0,0,5,17,2,0,0,65,0,0,0,32,3,16,0,140],[0,0,0,0,3,0,0,25,0,0,0,0,3,2,64,25,0,0,5,17,1,16,1,151,0,0,0,0,4,1,0,75],[0,0,0,0,2,0,160,25,0,0,5,17,1,16,0,156,0,0,0,0,2,3,192,25,0,0,0,0,1,2,0,75],[0,0,1,57,0,0,193,61,0,0,0,6,1,0,0,41,0,0,0,0,1,1,4,51,0,0,0,0,2,1,0,75],[0,0,0,0,2,0,0,25,0,0,0,1,2,0,192,57,0,0,0,0,2,33,0,75,0,0,1,57,0,0,193,61],[0,0,0,0,1,1,0,75,0,0,4,34,0,0,193,61,0,0,11,155,0,0,1,61,0,0,5,64,8,112,0,156],[0,0,19,58,0,0,33,61,0,0,0,64,8,112,0,57,0,0,0,64,0,128,4,63,0,0,0,0,9,33,3,79],[0,0,0,1,8,0,0,58,0,0,0,0,8,135,4,54,0,0,0,0,9,9,4,59,0,0,0,0,0,152,4,53],[0,0,9,198,0,0,97,61,0,0,0,248,10,64,2,16,0,0,5,65,9,144,1,151,0,0,0,0,9,169,1,159],[0,0,5,17,9,144,1,103,0,0,0,0,0,152,4,53,0,0,0,0,8,7,0,25,0,0,0,64,7,0,4,61],[0,0,5,64,9,112,0,156,0,0,19,58,0,0,33,61,0,0,0,64,9,112,0,57,0,0,0,64,0,144,4,63],[0,0,0,0,2,33,3,79,0,0,0,1,12,0,0,58,0,0,0,0,9,199,4,54,0,0,0,0,11,2,4,59],[0,0,0,0,0,185,4,53,0,0,9,198,0,0,97,61,0,0,5,65,2,176,1,151,0,0,5,70,10,32,1,199],[0,0,0,0,0,169,4,53,0,0,0,0,9,6,4,51,0,0,0,0,9,73,0,25,0,0,0,0,10,8,4,51],[0,0,0,0,9,169,0,25,0,0,0,0,10,7,4,51,0,0,0,0,9,169,0,25,0,0,0,64,10,0,4,61],[0,0,5,16,9,144,1,151,0,0,0,56,13,144,0,140,0,0,17,113,0,0,65,61,0,0,0,32,13,144,2,112],[0,0,5,8,12,144,0,156,0,0,0,0,13,9,160,25,0,0,5,8,12,144,0,156,0,0,0,0,14,0,0,25],[0,0,0,4,14,0,32,57,0,0,0,2,12,224,1,191,0,0,255,255,15,208,0,140,0,0,0,0,12,14,160,25],[0,0,0,16,14,208,2,112,0,0,0,0,14,13,160,25,0,0,0,255,13,224,0,140,0,0,0,0,13,0,0,25],[0,0,0,1,13,0,32,57,0,0,5,64,14,160,0,156,0,0,19,58,0,0,33,61,0,0,0,0,12,220,1,159],[0,0,0,64,13,160,0,57,0,0,0,64,0,208,4,63,0,0,0,32,13,160,0,57,0,0,0,0,0,189,4,53],[0,0,0,2,11,192,0,58,0,0,0,0,0,186,4,53,0,0,9,198,0,0,97,61,0,0,0,248,11,192,2,16],[0,0,0,0,2,43,1,159,0,0,5,71,2,32,1,199,0,0,0,0,0,45,4,53,0,0,0,3,2,192,2,16],[0,0,0,248,2,32,1,95,0,0,0,0,2,41,1,207,0,0,0,33,9,160,0,57,0,0,0,0,0,41,4,53],[0,0,17,126,0,0,1,61,0,0,5,8,2,0,0,65,0,0,5,8,3,16,0,156,0,0,0,0,1,2,128,25],[0,0,0,6,4,0,0,41,0,0,9,91,0,0,1,61,0,0,5,64,8,112,0,156,0,0,19,58,0,0,33,61],[0,0,0,64,8,112,0,57,0,0,0,64,0,128,4,63,0,0,0,0,8,67,3,79,0,0,0,1,4,0,0,58],[0,0,0,0,4,71,4,54,0,0,0,0,8,8,4,59,0,0,0,0,0,132,4,53,0,0,9,198,0,0,97,61],[0,0,5,65,8,128,1,151,0,0,0,248,6,96,2,16,0,0,0,0,6,134,1,159,0,0,5,70,6,96,0,65],[0,0,0,0,0,100,4,53,0,0,0,64,4,0,4,61,0,0,0,32,6,64,0,57,0,0,0,0,8,7,4,51],[0,0,0,0,9,8,0,75,0,0,16,150,0,0,97,61,0,0,0,0,9,0,0,25,0,0,0,0,10,105,0,25],[0,0,0,32,9,144,0,57,0,0,0,0,11,121,0,25,0,0,0,0,11,11,4,51,0,0,0,0,0,186,4,53],[0,0,0,0,10,137,0,75,0,0,16,143,0,0,65,61,0,0,0,0,7,104,0,25,0,0,0,0,0,7,4,53],[0,0,0,0,7,72,0,25,0,0,0,32,9,112,0,57,0,0,0,8,8,0,0,41,0,0,0,0,8,8,4,51],[0,0,0,0,10,8,0,75,0,0,16,166,0,0,97,61,0,0,0,0,10,0,0,25,0,0,0,0,11,154,0,25],[0,0,0,32,10,160,0,57,0,0,0,8,12,160,0,41,0,0,0,0,12,12,4,51,0,0,0,0,0,203,4,53],[0,0,0,0,11,138,0,75,0,0,16,159,0,0,65,61,0,0,0,0,9,152,0,25,0,0,0,0,0,9,4,53],[0,0,0,0,7,120,0,25,0,0,0,32,9,112,0,57,0,0,0,6,8,0,0,41,0,0,0,0,8,8,4,51],[0,0,0,0,10,8,0,75,0,0,16,182,0,0,97,61,0,0,0,0,10,0,0,25,0,0,0,0,11,154,0,25],[0,0,0,32,10,160,0,57,0,0,0,6,12,160,0,41,0,0,0,0,12,12,4,51,0,0,0,0,0,203,4,53],[0,0,0,0,11,138,0,75,0,0,16,175,0,0,65,61,0,0,0,0,9,152,0,25,0,0,0,0,0,9,4,53],[0,0,0,0,7,120,0,25,0,0,0,32,9,112,0,57,0,0,0,5,8,0,0,41,0,0,0,0,8,8,4,51],[0,0,0,0,10,8,0,75,0,0,16,198,0,0,97,61,0,0,0,0,10,0,0,25,0,0,0,0,11,154,0,25],[0,0,0,32,10,160,0,57,0,0,0,5,12,160,0,41,0,0,0,0,12,12,4,51,0,0,0,0,0,203,4,53],[0,0,0,0,11,138,0,75,0,0,16,191,0,0,65,61,0,0,0,0,9,152,0,25,0,0,0,0,0,9,4,53],[0,0,0,0,7,120,0,25,0,0,0,32,9,112,0,57,0,0,0,4,8,0,0,41,0,0,0,0,8,8,4,51],[0,0,0,0,10,8,0,75,0,0,16,214,0,0,97,61,0,0,0,0,10,0,0,25,0,0,0,0,11,154,0,25],[0,0,0,32,10,160,0,57,0,0,0,4,12,160,0,41,0,0,0,0,12,12,4,51,0,0,0,0,0,203,4,53],[0,0,0,0,11,138,0,75,0,0,16,207,0,0,65,61,0,0,0,0,9,152,0,25,0,0,0,0,0,9,4,53],[0,0,0,0,7,120,0,25,0,0,0,32,9,112,0,57,0,0,0,3,8,0,0,41,0,0,0,0,8,8,4,51],[0,0,0,0,10,8,0,75,0,0,16,230,0,0,97,61,0,0,0,0,10,0,0,25,0,0,0,0,11,154,0,25],[0,0,0,32,10,160,0,57,0,0,0,3,12,160,0,41,0,0,0,0,12,12,4,51,0,0,0,0,0,203,4,53],[0,0,0,0,11,138,0,75,0,0,16,223,0,0,65,61,0,0,0,0,9,152,0,25,0,0,0,0,0,9,4,53],[0,0,0,0,5,83,3,79,0,0,0,0,3,120,0,25,0,0,0,31,7,32,1,143,0,0,0,32,8,48,0,57],[0,0,0,5,9,32,2,114,0,0,16,247,0,0,97,61,0,0,0,0,10,0,0,25,0,0,0,5,11,160,2,16],[0,0,0,0,12,184,0,25,0,0,0,0,11,181,3,79,0,0,0,0,11,11,4,59,0,0,0,0,0,188,4,53],[0,0,0,1,10,160,0,57,0,0,0,0,11,154,0,75,0,0,16,239,0,0,65,61,0,0,0,0,10,7,0,75],[0,0,17,6,0,0,97,61,0,0,0,5,9,144,2,16,0,0,0,0,5,149,3,79,0,0,0,0,8,152,0,25],[0,0,0,3,7,112,2,16,0,0,0,0,9,8,4,51,0,0,0,0,9,121,1,207,0,0,0,0,9,121,2,47],[0,0,0,0,5,5,4,59,0,0,1,0,7,112,0,137,0,0,0,0,5,117,2,47,0,0,0,0,5,117,1,207],[0,0,0,0,5,149,1,159,0,0,0,0,0,88,4,53,0,0,0,0,2,35,0,25,0,0,0,32,5,32,0,57],[0,0,0,0,0,5,4,53,0,0,0,0,3,1,4,51,0,0,0,0,7,3,0,75,0,0,17,20,0,0,97,61],[0,0,0,0,7,0,0,25,0,0,0,0,8,87,0,25,0,0,0,32,7,112,0,57,0,0,0,0,9,23,0,25],[0,0,0,0,9,9,4,51,0,0,0,0,0,152,4,53,0,0,0,0,8,55,0,75,0,0,17,13,0,0,65,61],[0,0,0,0,1,83,0,25,0,0,0,0,0,1,4,53,0,0,0,0,1,66,0,73,0,0,0,0,1,19,0,25],[0,0,0,0,0,20,4,53,0,0,0,63,1,16,0,57,0,0,0,2,2,16,1,127,0,0,0,0,1,66,0,25],[0,0,0,0,2,33,0,75,0,0,0,0,2,0,0,25,0,0,0,1,2,0,64,57,0,0,5,16,3,16,0,156],[0,0,19,58,0,0,33,61,0,0,0,1,2,32,1,144,0,0,19,58,0,0,193,61,0,0,0,64,0,16,4,63],[0,0,5,8,1,0,0,65,0,0,5,8,2,96,0,156,0,0,0,0,6,1,128,25,0,0,0,64,2,96,2,16],[0,0,0,0,3,4,4,51,0,0,5,8,4,48,0,156,0,0,0,0,3,1,128,25,0,0,0,96,3,48,2,16],[0,0,0,0,2,35,1,159,0,0,0,0,3,0,4,20,0,0,17,245,0,0,1,61,0,0,0,31,4,48,1,143],[0,0,0,5,2,48,2,114,0,0,17,58,0,0,97,61,0,0,0,0,5,0,0,25,0,0,0,5,6,80,2,16],[0,0,0,0,7,97,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,118,4,53,0,0,0,1,5,80,0,57],[0,0,0,0,6,37,0,75,0,0,17,51,0,0,65,61,0,0,0,0,5,4,0,75,0,0,17,72,0,0,97,61],[0,0,0,3,4,64,2,16,0,0,0,5,2,32,2,16,0,0,0,0,5,2,4,51,0,0,0,0,5,69,1,207],[0,0,0,0,5,69,2,47,0,0,0,0,1,33,3,79,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137],[0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,81,1,159,0,0,0,0,0,18,4,53],[0,0,0,96,1,48,2,16,0,0,20,30,0,1,4,48,0,0,0,56,8,64,0,140,0,0,19,39,0,0,65,61],[0,0,0,32,9,64,2,112,0,0,5,8,8,64,0,156,0,0,0,0,9,4,160,25,0,0,5,8,8,64,0,156],[0,0,0,0,10,0,0,25,0,0,0,4,10,0,32,57,0,0,0,2,8,160,1,191,0,0,255,255,11,144,0,140],[0,0,0,0,8,10,160,25,0,0,0,16,10,144,2,112,0,0,0,0,10,9,160,25,0,0,0,255,9,160,0,140],[0,0,0,0,9,0,0,25,0,0,0,1,9,0,32,57,0,0,5,64,10,96,0,156,0,0,19,58,0,0,33,61],[0,0,0,0,8,152,1,159,0,0,0,64,9,96,0,57,0,0,0,64,0,144,4,63,0,0,0,0,10,33,3,79],[0,0,0,2,9,128,0,58,0,0,0,0,9,150,4,54,0,0,0,0,10,10,4,59,0,0,0,0,0,169,4,53],[0,0,9,198,0,0,97,61,0,0,5,65,10,160,1,151,0,0,0,248,11,128,2,16,0,0,0,0,10,171,1,159],[0,0,5,69,10,160,1,199,0,0,0,0,0,169,4,53,0,0,0,3,8,128,2,16,0,0,0,248,8,128,1,95],[0,0,0,0,8,132,1,207,0,0,0,33,9,96,0,57,0,0,0,0,0,137,4,53,0,0,0,0,8,6,0,25],[0,0,19,55,0,0,1,61,0,0,5,64,13,160,0,156,0,0,19,58,0,0,33,61,0,0,0,64,13,160,0,57],[0,0,0,64,0,208,4,63,0,0,0,32,13,160,0,57,0,0,0,0,0,189,4,53,0,0,0,0,0,202,4,53],[0,0,0,0,11,12,0,75,0,0,9,198,0,0,97,61,0,0,0,248,9,144,2,16,0,0,0,0,2,41,1,159],[0,0,5,70,2,32,0,65,0,0,0,0,0,45,4,53,0,0,0,64,2,0,4,61,0,0,0,32,9,32,0,57],[0,0,5,72,11,0,0,65,0,0,0,0,0,185,4,53,0,0,0,33,12,32,0,57,0,0,0,0,11,10,4,51],[0,0,0,0,13,11,0,75,0,0,17,142,0,0,97,61,0,0,0,0,13,0,0,25,0,0,0,0,14,205,0,25],[0,0,0,32,13,208,0,57,0,0,0,0,15,173,0,25,0,0,0,0,15,15,4,51,0,0,0,0,0,254,4,53],[0,0,0,0,14,189,0,75,0,0,17,135,0,0,65,61,0,0,0,0,10,203,0,25,0,0,0,0,0,10,4,53],[0,0,0,0,10,43,0,25,0,0,0,33,12,160,0,57,0,0,0,0,11,6,4,51,0,0,0,0,13,11,0,75],[0,0,17,157,0,0,97,61,0,0,0,0,13,0,0,25,0,0,0,0,14,205,0,25,0,0,0,32,13,208,0,57],[0,0,0,0,15,109,0,25,0,0,0,0,15,15,4,51,0,0,0,0,0,254,4,53,0,0,0,0,14,189,0,75],[0,0,17,150,0,0,65,61,0,0,0,0,6,203,0,25,0,0,0,0,0,6,4,53,0,0,0,0,6,171,0,25],[0,0,0,33,11,96,0,57,0,0,0,0,10,8,4,51,0,0,0,0,12,10,0,75,0,0,17,172,0,0,97,61],[0,0,0,0,12,0,0,25,0,0,0,0,13,188,0,25,0,0,0,32,12,192,0,57,0,0,0,0,14,140,0,25],[0,0,0,0,14,14,4,51,0,0,0,0,0,237,4,53,0,0,0,0,13,172,0,75,0,0,17,165,0,0,65,61],[0,0,0,0,8,186,0,25,0,0,0,0,0,8,4,53,0,0,0,0,5,81,3,79,0,0,0,0,1,106,0,25],[0,0,0,31,6,64,1,143,0,0,0,33,8,16,0,57,0,0,0,5,10,64,2,114,0,0,17,189,0,0,97,61],[0,0,0,0,11,0,0,25,0,0,0,5,12,176,2,16,0,0,0,0,13,200,0,25,0,0,0,0,12,197,3,79],[0,0,0,0,12,12,4,59,0,0,0,0,0,205,4,53,0,0,0,1,11,176,0,57,0,0,0,0,12,171,0,75],[0,0,17,181,0,0,65,61,0,0,0,0,11,6,0,75,0,0,17,204,0,0,97,61,0,0,0,5,10,160,2,16],[0,0,0,0,5,165,3,79,0,0,0,0,8,168,0,25,0,0,0,3,6,96,2,16,0,0,0,0,10,8,4,51],[0,0,0,0,10,106,1,207,0,0,0,0,10,106,2,47,0,0,0,0,5,5,4,59,0,0,1,0,6,96,0,137],[0,0,0,0,5,101,2,47,0,0,0,0,5,101,1,207,0,0,0,0,5,165,1,159,0,0,0,0,0,88,4,53],[0,0,0,0,1,65,0,25,0,0,0,33,5,16,0,57,0,0,0,0,0,5,4,53,0,0,0,0,4,7,4,51],[0,0,0,0,6,4,0,75,0,0,17,218,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,0,8,86,0,25],[0,0,0,32,6,96,0,57,0,0,0,0,10,118,0,25,0,0,0,0,10,10,4,51,0,0,0,0,0,168,4,53],[0,0,0,0,8,70,0,75,0,0,17,211,0,0,65,61,0,0,0,0,5,84,0,25,0,0,0,0,0,5,4,53],[0,0,0,0,1,33,0,73,0,0,0,0,1,20,0,25,0,0,0,1,4,16,0,57,0,0,0,0,0,66,4,53],[0,0,0,64,1,16,0,57,0,0,0,0,3,49,1,111,0,0,0,0,1,35,0,25,0,0,0,0,3,49,0,75],[0,0,0,0,3,0,0,25,0,0,0,1,3,0,64,57,0,0,5,16,4,16,0,156,0,0,19,58,0,0,33,61],[0,0,0,1,3,48,1,144,0,0,19,58,0,0,193,61,0,0,0,64,0,16,4,63,0,0,5,8,1,0,0,65],[0,0,5,8,3,144,0,156,0,0,0,0,9,1,128,25,0,0,0,64,3,144,2,16,0,0,0,0,2,2,4,51],[0,0,5,8,4,32,0,156,0,0,0,0,2,1,128,25,0,0,0,96,2,32,2,16,0,0,0,0,2,50,1,159],[0,0,0,0,3,0,4,20,0,0,5,8,4,48,0,156,0,0,0,0,3,1,128,25,0,0,0,192,1,48,2,16],[0,0,0,0,1,33,1,159,0,0,5,19,1,16,1,199,0,0,128,16,2,0,0,57,20,28,20,13,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,1,57,0,0,97,61,0,0,0,18,3,0,3,103,0,0,0,0,1,1,4,59],[0,8,0,0,0,1,0,29,0,0,0,10,1,0,0,41,0,0,0,228,4,16,0,57,0,0,0,0,1,67,3,79],[0,0,0,0,1,1,4,59,0,0,5,18,1,16,1,152,0,5,0,0,0,4,0,29,0,0,18,33,0,0,193,61],[0,0,0,128,1,64,0,138,0,0,0,0,2,19,3,79,0,0,0,64,1,64,0,138,0,0,0,0,5,19,3,79],[0,0,0,0,4,2,4,59,0,0,0,0,5,5,4,59,0,0,0,0,98,69,0,169,0,0,0,0,6,5,0,75],[0,0,18,20,0,0,97,61,0,0,0,0,101,82,0,217,0,0,0,0,4,69,0,75,0,0,18,29,0,0,193,61],[0,0,0,128,1,16,0,57,0,0,0,0,1,19,3,79,0,0,0,0,1,1,4,59,0,6,0,0,0,33,0,29],[0,0,0,6,1,16,0,107,0,0,0,0,1,0,0,25,0,0,0,1,1,0,64,57,0,0,0,1,1,16,1,144],[0,0,18,38,0,0,97,61,0,0,5,94,1,0,0,65,0,0,0,0,0,16,4,53,0,0,0,17,1,0,0,57],[0,0,0,81,0,0,1,61,0,0,0,10,1,0,0,41,0,0,1,36,1,16,0,57,0,0,0,0,1,19,3,79],[0,0,0,0,1,1,4,59,0,6,0,0,0,1,0,29,0,0,5,84,1,0,0,65,0,0,0,0,0,16,4,57],[0,0,0,7,1,0,0,41,0,0,0,4,0,16,4,67,0,0,5,8,1,0,0,65,0,0,0,0,2,0,4,20],[0,0,5,8,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,5,43,1,16,1,199],[0,0,128,10,2,0,0,57,20,28,20,13,0,0,4,15,0,0,0,1,2,32,1,144,0,0,18,65,0,0,97,61],[0,0,0,0,1,1,4,59,0,0,0,6,1,16,0,107,0,0,18,66,0,0,161,61,0,0,0,64,1,0,4,61],[0,0,0,100,2,16,0,57,0,0,5,92,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,68,2,16,0,57],[0,0,5,93,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,34,3,0,0,57],[0,0,1,23,0,0,1,61,0,0,0,0,0,1,4,47,0,0,0,0,4,0,0,49,0,0,0,10,1,64,0,106],[0,0,0,35,2,16,0,138,0,0,0,5,1,0,0,41,0,0,1,0,1,16,0,57,0,0,0,18,3,0,3,103],[0,0,0,0,1,19,3,79,0,0,0,0,1,1,4,59,0,0,5,17,5,0,0,65,0,0,0,0,6,33,0,75],[0,0,0,0,6,0,0,25,0,0,0,0,6,5,128,25,0,0,5,17,2,32,1,151,0,0,5,17,7,16,1,151],[0,0,0,0,8,39,0,75,0,0,0,0,5,0,128,25,0,0,0,0,2,39,1,63,0,0,5,17,2,32,0,156],[0,0,0,0,5,6,192,25,0,0,0,0,2,5,0,75,0,0,1,57,0,0,193,61,0,0,0,9,2,16,0,41],[0,0,0,0,1,35,3,79,0,0,0,0,1,1,4,59,0,0,5,16,5,16,0,156,0,0,1,57,0,0,33,61],[0,0,0,0,5,20,0,73,0,0,0,32,6,32,0,57,0,0,5,17,2,0,0,65,0,0,0,0,7,86,0,75],[0,0,0,0,7,0,0,25,0,0,0,0,7,2,32,25,0,0,5,17,5,80,1,151,0,0,5,17,8,96,1,151],[0,0,0,0,9,88,0,75,0,0,0,0,2,0,128,25,0,0,0,0,5,88,1,63,0,0,5,17,5,80,0,156],[0,0,0,0,2,7,192,25,0,0,0,0,2,2,0,75,0,0,1,57,0,0,193,61,0,0,0,63,2,16,0,57],[0,0,0,32,5,0,0,138,0,0,0,0,5,82,1,111,0,0,0,64,2,0,4,61,0,0,0,0,5,82,0,25],[0,0,0,0,7,37,0,75,0,0,0,0,7,0,0,25,0,0,0,1,7,0,64,57,0,0,5,16,8,80,0,156],[0,0,19,58,0,0,33,61,0,0,0,1,7,112,1,144,0,0,19,58,0,0,193,61,0,0,0,64,0,80,4,63],[0,0,0,0,5,18,4,54,0,0,0,0,7,97,0,25,0,0,0,0,4,71,0,75,0,0,1,57,0,0,33,61],[0,0,0,0,4,99,3,79,0,0,0,31,3,16,1,143,0,0,0,5,6,16,2,114,0,0,18,137,0,0,97,61],[0,0,0,0,7,0,0,25,0,0,0,5,8,112,2,16,0,0,0,0,9,133,0,25,0,0,0,0,8,132,3,79],[0,0,0,0,8,8,4,59,0,0,0,0,0,137,4,53,0,0,0,1,7,112,0,57,0,0,0,0,8,103,0,75],[0,0,18,129,0,0,65,61,0,0,0,0,7,3,0,75,0,0,18,152,0,0,97,61,0,0,0,5,6,96,2,16],[0,0,0,0,4,100,3,79,0,0,0,0,6,101,0,25,0,0,0,3,3,48,2,16,0,0,0,0,7,6,4,51],[0,0,0,0,7,55,1,207,0,0,0,0,7,55,2,47,0,0,0,0,4,4,4,59,0,0,1,0,3,48,0,137],[0,0,0,0,4,52,2,47,0,0,0,0,3,52,1,207,0,0,0,0,3,115,1,159,0,0,0,0,0,54,4,53],[0,0,0,0,1,21,0,25,0,0,0,0,0,1,4,53,0,0,0,64,1,0,4,61,0,0,0,0,3,2,4,51],[0,0,0,65,3,48,0,140,0,0,18,171,0,0,193,61,0,0,0,65,3,32,0,57,0,0,0,0,3,3,4,51],[0,0,0,255,3,48,1,143,0,0,0,29,4,48,0,138,0,0,0,3,6,0,0,138,0,0,0,0,4,100,0,75],[0,0,18,177,0,0,33,61,0,0,0,68,2,16,0,57,0,0,5,91,3,0,0,65,0,0,0,0,0,50,4,53],[0,0,0,36,2,16,0,57,0,0,0,22,3,0,0,57,0,0,2,184,0,0,1,61,0,0,0,68,2,16,0,57],[0,0,5,85,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,29,3,0,0,57],[0,0,2,184,0,0,1,61,0,0,0,0,4,5,4,51,0,0,0,64,2,32,0,57,0,0,0,0,2,2,4,51],[0,0,5,86,5,32,0,156,0,0,18,188,0,0,65,61,0,0,0,68,2,16,0,57,0,0,5,90,3,0,0,65],[0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,9,3,0,0,57,0,0,2,184,0,0,1,61],[0,0,0,96,5,16,0,57,0,0,0,0,0,37,4,53,0,0,0,64,2,16,0,57,0,0,0,0,0,66,4,53],[0,0,0,32,2,16,0,57,0,0,0,0,0,50,4,53,0,0,0,8,2,0,0,41,0,0,0,0,0,33,4,53],[0,0,0,0,0,0,4,53,0,0,5,8,2,0,0,65,0,0,0,0,3,0,4,20,0,0,5,8,4,48,0,156],[0,0,0,0,3,2,128,25,0,0,5,8,4,16,0,156,0,0,0,0,1,2,128,25,0,0,0,64,1,16,2,16],[0,0,0,192,2,48,2,16,0,0,0,0,1,18,1,159,0,0,5,87,1,16,1,199,0,0,0,1,2,0,0,57],[20,28,20,13,0,0,4,15,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,5,8,3,48,1,151],[0,0,0,32,4,48,0,140,0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57,0,0,0,31,5,64,1,143],[0,0,0,5,4,64,2,114,0,0,18,226,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16],[0,0,0,0,8,113,3,79,0,0,0,0,8,8,4,59,0,0,0,0,0,135,4,53,0,0,0,1,6,96,0,57],[0,0,0,0,7,70,0,75,0,0,18,219,0,0,65,61,0,0,0,0,6,5,0,75,0,0,18,240,0,0,97,61],[0,0,0,3,5,80,2,16,0,0,0,5,4,64,2,16,0,0,0,0,6,4,4,51,0,0,0,0,6,86,1,207],[0,0,0,0,6,86,2,47,0,0,0,0,7,65,3,79,0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137],[0,0,0,0,7,87,2,47,0,0,0,0,5,87,1,207,0,0,0,0,5,101,1,159,0,0,0,0,0,84,4,53],[0,1,0,0,0,3,0,31,0,19,0,0,0,1,3,85,0,0,0,64,4,0,4,61,0,0,0,1,2,32,1,144],[0,0,19,7,0,0,97,61,0,0,0,0,1,0,4,51,0,0,5,18,1,16,1,151,0,0,0,7,2,16,0,108],[0,0,0,0,2,0,0,25,0,0,0,1,2,0,192,57,0,0,0,0,1,1,0,75,0,0,0,0,1,0,0,25],[0,0,0,1,1,0,96,57,0,0,0,0,1,18,1,160,0,0,5,88,1,0,0,65,0,0,0,0,1,0,192,25],[0,0,0,0,0,20,4,53,0,0,5,8,1,0,0,65,0,0,5,8,2,64,0,156,0,0,0,0,4,1,128,25],[0,0,0,64,1,64,2,16,0,0,5,89,1,16,1,199,0,0,20,29,0,1,4,46,0,0,0,31,2,48,1,143],[0,0,0,5,5,48,2,114,0,0,19,19,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16],[0,0,0,0,8,116,0,25,0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53],[0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,19,11,0,0,65,61,0,0,0,0,6,2,0,75],[0,0,19,34,0,0,97,61,0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,84,0,25],[0,0,0,3,2,32,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,38,1,207,0,0,0,0,6,38,2,47],[0,0,0,0,1,1,4,59,0,0,1,0,2,32,0,137,0,0,0,0,1,33,2,47,0,0,0,0,1,33,1,207],[0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,5,8,1,0,0,65,0,0,5,8,2,64,0,156],[0,0,0,0,4,1,128,25,0,0,0,64,1,64,2,16,0,0,6,134,0,0,1,61,0,0,5,64,8,96,0,156],[0,0,19,58,0,0,33,61,0,0,0,64,8,96,0,57,0,0,0,64,0,128,4,63,0,0,0,0,9,33,3,79],[0,0,0,1,8,0,0,58,0,0,0,0,8,134,4,54,0,0,0,0,9,9,4,59,0,0,0,0,0,152,4,53],[0,0,9,198,0,0,97,61,0,0,0,248,10,64,2,16,0,0,5,65,9,144,1,151,0,0,0,0,9,169,1,159],[0,0,5,17,9,144,1,103,0,0,0,0,0,152,4,53,0,0,0,0,8,6,0,25,0,0,0,64,6,0,4,61],[0,0,5,64,9,96,0,156,0,0,19,62,0,0,161,61,0,0,5,94,1,0,0,65,0,0,0,0,0,16,4,53],[0,0,0,65,1,0,0,57,0,0,0,81,0,0,1,61,0,0,0,64,9,96,0,57,0,0,0,64,0,144,4,63],[0,0,0,0,2,33,3,79,0,0,0,1,12,0,0,58,0,0,0,0,9,198,4,54,0,0,0,0,11,2,4,59],[0,0,0,0,0,185,4,53,0,0,9,198,0,0,97,61,0,0,5,65,2,176,1,151,0,0,5,70,10,32,1,199],[0,0,0,0,0,169,4,53,0,0,0,0,9,7,4,51,0,0,0,0,9,73,0,25,0,0,0,0,10,8,4,51],[0,0,0,0,9,169,0,25,0,0,0,0,10,6,4,51,0,0,0,0,9,169,0,25,0,0,0,64,10,0,4,61],[0,0,5,16,9,144,1,151,0,0,0,56,13,144,0,140,0,0,19,117,0,0,65,61,0,0,0,32,13,144,2,112],[0,0,5,8,12,144,0,156,0,0,0,0,13,9,160,25,0,0,5,8,12,144,0,156,0,0,0,0,14,0,0,25],[0,0,0,4,14,0,32,57,0,0,0,2,12,224,1,191,0,0,255,255,15,208,0,140,0,0,0,0,12,14,160,25],[0,0,0,16,14,208,2,112,0,0,0,0,14,13,160,25,0,0,0,255,13,224,0,140,0,0,0,0,13,0,0,25],[0,0,0,1,13,0,32,57,0,0,5,64,14,160,0,156,0,0,19,58,0,0,33,61,0,0,0,0,12,220,1,159],[0,0,0,64,13,160,0,57,0,0,0,64,0,208,4,63,0,0,0,32,13,160,0,57,0,0,0,0,0,189,4,53],[0,0,0,2,11,192,0,58,0,0,0,0,0,186,4,53,0,0,9,198,0,0,97,61,0,0,0,248,11,192,2,16],[0,0,0,0,2,43,1,159,0,0,5,71,2,32,1,199,0,0,0,0,0,45,4,53,0,0,0,3,2,192,2,16],[0,0,0,248,2,32,1,95,0,0,0,0,2,41,1,207,0,0,0,33,9,160,0,57,0,0,0,0,0,41,4,53],[0,0,19,130,0,0,1,61,0,0,5,64,13,160,0,156,0,0,19,58,0,0,33,61,0,0,0,64,13,160,0,57],[0,0,0,64,0,208,4,63,0,0,0,32,13,160,0,57,0,0,0,0,0,189,4,53,0,0,0,0,0,202,4,53],[0,0,0,0,11,12,0,75,0,0,9,198,0,0,97,61,0,0,0,248,9,144,2,16,0,0,0,0,2,41,1,159],[0,0,5,70,2,32,0,65,0,0,0,0,0,45,4,53,0,0,0,64,2,0,4,61,0,0,0,32,9,32,0,57],[0,0,5,19,11,0,0,65,0,0,0,0,0,185,4,53,0,0,0,33,12,32,0,57,0,0,0,0,11,10,4,51],[0,0,0,0,13,11,0,75,0,0,19,146,0,0,97,61,0,0,0,0,13,0,0,25,0,0,0,0,14,205,0,25],[0,0,0,32,13,208,0,57,0,0,0,0,15,173,0,25,0,0,0,0,15,15,4,51,0,0,0,0,0,254,4,53],[0,0,0,0,14,189,0,75,0,0,19,139,0,0,65,61,0,0,0,0,10,203,0,25,0,0,0,0,0,10,4,53],[0,0,0,0,10,43,0,25,0,0,0,33,12,160,0,57,0,0,0,0,11,7,4,51,0,0,0,0,13,11,0,75],[0,0,19,161,0,0,97,61,0,0,0,0,13,0,0,25,0,0,0,0,14,205,0,25,0,0,0,32,13,208,0,57],[0,0,0,0,15,125,0,25,0,0,0,0,15,15,4,51,0,0,0,0,0,254,4,53,0,0,0,0,14,189,0,75],[0,0,19,154,0,0,65,61,0,0,0,0,7,203,0,25,0,0,0,0,0,7,4,53,0,0,0,0,7,171,0,25],[0,0,0,33,11,112,0,57,0,0,0,0,10,8,4,51,0,0,0,0,12,10,0,75,0,0,19,176,0,0,97,61],[0,0,0,0,12,0,0,25,0,0,0,0,13,188,0,25,0,0,0,32,12,192,0,57,0,0,0,0,14,140,0,25],[0,0,0,0,14,14,4,51,0,0,0,0,0,237,4,53,0,0,0,0,13,172,0,75,0,0,19,169,0,0,65,61],[0,0,0,0,8,186,0,25,0,0,0,0,0,8,4,53,0,0,0,0,5,81,3,79,0,0,0,0,1,122,0,25],[0,0,0,31,7,64,1,143,0,0,0,33,8,16,0,57,0,0,0,5,10,64,2,114,0,0,19,193,0,0,97,61],[0,0,0,0,11,0,0,25,0,0,0,5,12,176,2,16,0,0,0,0,13,200,0,25,0,0,0,0,12,197,3,79],[0,0,0,0,12,12,4,59,0,0,0,0,0,205,4,53,0,0,0,1,11,176,0,57,0,0,0,0,12,171,0,75],[0,0,19,185,0,0,65,61,0,0,0,0,11,7,0,75,0,0,19,208,0,0,97,61,0,0,0,5,10,160,2,16],[0,0,0,0,5,165,3,79,0,0,0,0,8,168,0,25,0,0,0,3,7,112,2,16,0,0,0,0,10,8,4,51],[0,0,0,0,10,122,1,207,0,0,0,0,10,122,2,47,0,0,0,0,5,5,4,59,0,0,1,0,7,112,0,137],[0,0,0,0,5,117,2,47,0,0,0,0,5,117,1,207,0,0,0,0,5,165,1,159,0,0,0,0,0,88,4,53],[0,0,0,0,1,65,0,25,0,0,0,33,5,16,0,57,0,0,0,0,0,5,4,53,0,0,0,0,4,6,4,51],[0,0,0,0,7,4,0,75,0,0,19,222,0,0,97,61,0,0,0,0,7,0,0,25,0,0,0,0,8,87,0,25],[0,0,0,32,7,112,0,57,0,0,0,0,10,103,0,25,0,0,0,0,10,10,4,51,0,0,0,0,0,168,4,53],[0,0,0,0,8,71,0,75,0,0,19,215,0,0,65,61,0,0,0,0,5,84,0,25,0,0,0,0,0,5,4,53],[0,0,0,0,1,33,0,73,0,0,0,0,1,20,0,25,0,0,0,1,4,16,0,57,0,0,0,0,0,66,4,53],[0,0,0,64,1,16,0,57,0,0,0,0,3,49,1,111,0,0,0,0,1,35,0,25,0,0,0,0,3,49,0,75],[0,0,0,0,3,0,0,25,0,0,0,1,3,0,64,57,0,0,5,16,4,16,0,156,0,0,19,58,0,0,33,61],[0,0,0,1,3,48,1,144,0,0,19,58,0,0,193,61,0,0,0,64,0,16,4,63,0,0,5,8,1,0,0,65],[0,0,5,8,3,144,0,156,0,0,0,0,9,1,128,25,0,0,0,64,3,144,2,16,0,0,0,0,2,2,4,51],[0,0,5,8,4,32,0,156,0,0,0,0,2,1,128,25,0,0,0,96,2,32,2,16,0,0,0,0,2,50,1,159],[0,0,0,0,3,0,4,20,0,0,17,245,0,0,1,61,0,0,0,0,4,3,0,75,0,0,20,4,0,0,97,61],[0,0,0,0,4,0,0,25,0,0,0,0,5,36,0,25,0,0,0,0,6,20,0,25,0,0,0,0,6,6,4,51],[0,0,0,0,0,101,4,53,0,0,0,32,4,64,0,57,0,0,0,0,5,52,0,75,0,0,19,253,0,0,65,61],[0,0,0,0,1,35,0,25,0,0,0,0,0,1,4,53,0,0,0,0,0,1,4,45,0,0,0,0,0,1,4,47],[0,0,20,11,0,33,4,33,0,0,0,1,2,0,0,57,0,0,0,0,0,1,4,45,0,0,0,0,2,0,0,25],[0,0,0,0,0,1,4,45,0,0,20,16,0,33,4,35,0,0,0,1,2,0,0,57,0,0,0,0,0,1,4,45],[0,0,0,0,2,0,0,25,0,0,0,0,0,1,4,45,0,0,20,21,0,33,4,33,0,0,0,1,2,0,0,57],[0,0,0,0,0,1,4,45,0,0,0,0,2,0,0,25,0,0,0,0,0,1,4,45,0,0,20,26,0,33,4,35],[0,0,0,1,2,0,0,57,0,0,0,0,0,1,4,45,0,0,0,0,2,0,0,25,0,0,0,0,0,1,4,45],[0,0,20,28,0,0,4,50,0,0,20,29,0,1,4,46,0,0,20,30,0,1,4,48,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255],[0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,1,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,223,156,21,136],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,223,156,21,137],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,226,243,24,227],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,238,184,203,9],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,43,204,231],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,162,140,26,238],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255],[128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],[2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[114,97,116,111,114,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[70,97,105,108,101,100,32,116,111,32,112,97,121,32,116,104,101,32,102,101,101,32,116,111,32,116,104,101,32,111,112,101],[8,195,121,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[156,77,83,90,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],[156,77,83,91,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[236,249,91,138,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[60,218,51,81,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[93,56,39,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[79,118,101,114,102,108,111,119,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,128,0,0,0,0,0,0,0,0],[140,90,52,69,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[148,148,49,220,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[221,98,237,62,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,0,0,0,128,0,0,0,0,0,0,0,0],[9,94,167,179,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[83,97,102,101,69,82,67,50,48,58,32,108,111,119,45,108,101,118,101,108,32,99,97,108,108,32,102,97,105,108,101,100],[24,6,170,24,150,187,242,101,104,232,132,167,55,75,65,224,2,80,9,98,202,186,106,21,2,58,141,144,232,80,139,131],[2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,0,0,0,0,0,0,0,0,0,0,0,0],[83,97,102,101,69,82,67,50,48,58,32,97,112,112,114,111,118,101,32,102,114,111,109,32,110,111,110,45,122,101,114,111],[32,116,111,32,110,111,110,45,122,101,114,111,32,97,108,108,111,119,97,110,99,101,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,127],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,63],[111,116,32,115,117,99,99,101,101,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[83,97,102,101,69,82,67,50,48,58,32,69,82,67,50,48,32,111,112,101,114,97,116,105,111,110,32,100,105,100,32,110],[65,100,100,114,101,115,115,58,32,99,97,108,108,32,116,111,32,110,111,110,45,99,111,110,116,114,97,99,116,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,0,0,0,0,0,0,0,0,0],[84,104,101,32,97,112,112,114,111,118,97,108,66,97,115,101,100,32,112,97,121,109,97,115,116,101,114,32,105,110,112,117],[116,32,109,117,115,116,32,98,101,32,97,116,32,108,101,97,115,116,32,54,56,32,98,121,116,101,115,32,108,111,110,103],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,0,0,0,128,0,0,0,0,0,0,0,0],[85,110,115,117,112,112,111,114,116,101,100,32,112,97,121,109,97,115,116,101,114,32,102,108,111,119,0,0,0,0,0,0],[84,104,101,32,115,116,97,110,100,97,114,100,32,112,97,121,109,97,115,116,101,114,32,105,110,112,117,116,32,109,117,115],[116,32,98,101,32,97,116,32,108,101,97,115,116,32,52,32,98,121,116,101,115,32,108,111,110,103,0,0,0,0,0,0],[225,35,156,216,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,0,0,0,160,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,255,255,255,224],[154,138,5,146,172,137,197,173,59,198,223,130,36,193,123,72,89,118,245,151,223,16,78,226,13,13,244,21,36,31,103,11],[2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,191],[0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],[129,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[148,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[184,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[192,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[248,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0],[7,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],[107,101,99,99,97,107,50,53,54,32,114,101,116,117,114,110,101,100,32,105,110,118,97,108,105,100,32,100,97,116,97,0],[132,142,27,250,26,196,227,87,107,114,139,218,103,33,178,21,199,10,119,153,165,180,134,98,130,167,27,171,149,75,170,200],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,254,31],[194,248,120,113,118,184,172,107,247,33,91,74,220,193,224,105,191,74,184,45,154,177,223,5,165,122,145,212,37,147,91,110],[173,124,91,239,2,120,22,168,0,218,23,54,68,79,181,138,128,126,244,201,96,59,120,72,103,63,126,58,104,235,20,165],[25,180,83,206,69,170,170,243,163,0,245,169,236,149,134,155,79,40,171,16,67,11,87,46,226,24,195,166,165,224,125,111],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,95],[25,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[128,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[156,199,247,8,175,198,89,68,130,155,212,135,185,11,114,83,107,25,81,134,79,191,193,78,18,95,201,114,166,80,127,57],[83,105,103,110,97,116,117,114,101,32,108,101,110,103,116,104,32,105,115,32,105,110,99,111,114,114,101,99,116,0,0,0],[127,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,93,87,110,115,87,164,80,29,223,233,47,70,104,27,32,161],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0],[32,43,204,231,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0],[73,110,118,97,108,105,100,32,115,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[118,32,105,115,32,110,101,105,116,104,101,114,32,50,55,32,110,111,114,32,50,56,0,0,0,0,0,0,0,0,0,0],[117,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[78,111,116,32,101,110,111,117,103,104,32,98,97,108,97,110,99,101,32,102,111,114,32,102,101,101,32,43,32,118,97,108],[78,72,123,113,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,0,0,0,0,0,0],[69,110,99,111,100,105,110,103,32,117,110,115,117,112,112,111,114,116,101,100,32,116,120,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[123,9,174,214,17,35,121,18,1,120,40,210,252,224,88,7,87,230,120,117,80,34,1,169,203,222,160,152,112,237,204,243]],"entry_point_address":"0xc54E30ABB6a3eeD1b9DC0494D90c9C22D76FbA7e","entry_point_code":[[0,4,0,0,0,0,0,2,0,11,0,0,0,0,0,2,0,0,0,0,3,1,0,25,0,0,0,96,4,48,2,112],[0,0,6,86,3,64,1,151,0,3,0,0,0,49,3,85,0,2,0,0,0,1,3,85,0,0,6,86,0,64,1,157],[0,0,0,1,2,32,1,144,0,0,0,34,0,0,193,61,0,0,0,128,2,0,0,57,0,0,0,64,0,32,4,63],[0,0,0,4,2,48,0,140,0,0,0,85,0,0,65,61,0,0,0,0,2,1,4,59,0,0,0,224,2,32,2,112],[0,0,6,179,4,32,0,156,0,0,0,120,0,0,161,61,0,0,6,180,4,32,0,156,0,0,0,135,0,0,33,61],[0,0,6,190,4,32,0,156,0,0,0,198,0,0,161,61,0,0,6,191,1,32,0,156,0,0,0,240,0,0,33,61],[0,0,6,194,1,32,0,156,0,0,1,95,0,0,97,61,0,0,6,195,1,32,0,156,0,0,5,1,0,0,193,61],[0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75,0,0,5,1,0,0,193,61,25,83,23,213,0,0,4,15],[0,0,0,0,1,0,0,25,0,0,25,84,0,1,4,46,0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75],[0,0,5,1,0,0,193,61,0,0,6,87,1,0,0,65,0,0,0,0,0,16,4,57,0,0,0,0,1,0,4,16],[0,11,0,0,0,1,0,29,0,0,0,4,0,16,4,67,0,0,6,86,1,0,0,65,0,0,0,0,2,0,4,20],[0,0,6,86,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,6,88,1,16,1,199],[0,0,128,2,2,0,0,57,25,83,25,78,0,0,4,15,0,0,0,1,2,32,1,144,0,0,10,8,0,0,97,61],[0,0,0,0,1,1,4,59,0,0,0,0,1,1,0,75,0,0,5,1,0,0,193,61,0,0,6,89,1,0,0,65],[0,0,0,0,0,16,4,57,0,0,0,11,1,0,0,41,0,0,0,4,0,16,4,67,0,0,6,86,1,0,0,65],[0,0,0,0,2,0,4,20,0,0,6,86,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16],[0,0,6,88,1,16,1,199,0,0,128,2,2,0,0,57,25,83,25,78,0,0,4,15,0,0,0,1,2,32,1,144],[0,0,10,8,0,0,97,61,0,0,0,0,1,1,4,59,0,0,6,90,1,16,0,156,0,0,5,1,0,0,193,61],[0,0,6,91,1,0,0,65,0,0,0,160,0,16,4,63,0,0,0,4,1,0,0,57,0,0,0,128,0,16,4,63],[0,0,0,192,1,0,0,57,0,0,0,64,0,16,4,63,0,0,0,0,1,0,4,20,0,0,0,11,2,0,0,41],[0,0,0,4,3,32,0,140,0,0,2,6,0,0,193,61,0,0,0,1,2,0,0,57,0,0,0,1,3,0,0,49],[0,0,2,17,0,0,1,61,0,0,0,0,1,3,0,75,0,0,5,1,0,0,193,61,0,0,6,96,1,0,0,65],[0,0,0,0,2,1,4,26,0,0,0,0,2,2,0,75,0,0,5,1,0,0,193,61,0,0,0,1,2,0,0,57],[0,6,0,0,0,2,0,29,0,0,0,0,0,33,4,27,0,0,0,0,1,0,4,18,0,0,6,97,1,16,1,151],[0,0,0,0,2,0,4,16,0,0,0,0,1,33,0,75,0,0,0,166,0,0,193,61,0,3,0,0,0,2,0,29],[0,0,6,101,1,0,0,65,0,0,0,0,0,16,4,57,0,0,6,86,1,0,0,65,0,0,0,0,2,0,4,20],[0,0,6,86,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,6,102,1,16,1,199],[0,0,128,11,2,0,0,57,25,83,25,78,0,0,4,15,0,0,0,1,2,32,1,144,0,0,10,8,0,0,97,61],[0,0,0,0,2,1,4,59,0,0,3,233,1,0,0,138,0,0,0,0,1,18,0,75,0,0,2,30,0,0,161,61],[0,0,6,224,1,0,0,65,0,0,0,0,0,16,4,53,0,0,0,17,1,0,0,57,0,0,3,213,0,0,1,61],[0,0,6,199,1,32,0,156,0,0,0,152,0,0,161,61,0,0,6,200,1,32,0,156,0,0,0,187,0,0,161,61],[0,0,6,201,1,32,0,156,0,0,0,221,0,0,33,61,0,0,6,204,1,32,0,156,0,0,1,87,0,0,97,61],[0,0,6,205,1,32,0,156,0,0,5,1,0,0,193,61,0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75],[0,0,5,1,0,0,193,61,0,0,0,8,1,0,0,57,0,0,2,2,0,0,1,61,0,0,6,181,4,32,0,156],[0,0,0,210,0,0,161,61,0,0,6,182,4,32,0,156,0,0,1,53,0,0,33,61,0,0,6,185,4,32,0,156],[0,0,1,101,0,0,97,61,0,0,6,186,1,32,0,156,0,0,5,1,0,0,193,61,0,0,0,0,1,0,4,22],[0,0,0,0,1,1,0,75,0,0,5,1,0,0,193,61,0,0,0,100,1,0,0,57,0,0,0,0,0,16,4,27],[0,0,0,1,1,0,0,57,0,0,0,0,0,16,4,71,0,0,0,0,1,0,0,25,0,0,25,84,0,1,4,46],[0,0,6,209,1,32,0,156,0,0,0,176,0,0,33,61,0,0,6,213,1,32,0,156,0,0,1,75,0,0,97,61],[0,0,6,214,1,32,0,156,0,0,1,62,0,0,97,61,0,0,6,215,1,32,0,156,0,0,5,1,0,0,193,61],[0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75,0,0,5,1,0,0,193,61,25,83,14,25,0,0,4,15],[0,0,0,0,1,0,0,25,0,0,25,84,0,1,4,46,0,0,6,98,1,0,0,65,0,0,0,128,0,16,4,63],[0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63,0,0,0,16,1,0,0,57,0,0,0,164,0,16,4,63],[0,0,6,99,1,0,0,65,0,0,0,196,0,16,4,63,0,0,6,100,1,0,0,65,0,0,25,85,0,1,4,48],[0,0,6,210,1,32,0,156,0,0,1,82,0,0,97,61,0,0,6,211,1,32,0,156,0,0,1,68,0,0,97,61],[0,0,6,212,1,32,0,156,0,0,5,1,0,0,193,61,0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75],[0,0,5,1,0,0,193,61,0,0,0,7,1,0,0,57,0,0,2,2,0,0,1,61,0,0,6,206,1,32,0,156],[0,0,1,227,0,0,97,61,0,0,6,207,1,32,0,156,0,0,1,136,0,0,97,61,0,0,6,208,1,32,0,156],[0,0,5,1,0,0,193,61,0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75,0,0,5,1,0,0,193,61],[0,0,0,10,1,0,0,57,0,0,1,79,0,0,1,61,0,0,6,196,4,32,0,156,0,0,1,233,0,0,97,61],[0,0,6,197,1,32,0,156,0,0,1,217,0,0,97,61,0,0,6,198,1,32,0,156,0,0,5,1,0,0,193,61],[0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75,0,0,5,1,0,0,193,61,25,83,19,33,0,0,4,15],[0,0,0,0,1,0,0,25,0,0,25,84,0,1,4,46,0,0,6,187,1,32,0,156,0,0,1,254,0,0,97,61],[0,0,6,188,1,32,0,156,0,0,1,222,0,0,97,61,0,0,6,189,1,32,0,156,0,0,5,1,0,0,193,61],[0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75,0,0,5,1,0,0,193,61,0,0,0,6,1,0,0,57],[0,0,2,2,0,0,1,61,0,0,6,202,1,32,0,156,0,0,1,90,0,0,97,61,0,0,6,203,1,32,0,156],[0,0,5,1,0,0,193,61,0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75,0,0,5,1,0,0,193,61],[0,0,0,13,1,0,0,57,0,0,0,0,5,1,4,26,0,0,0,0,2,5,0,75,0,0,4,5,0,0,193,61],[0,0,6,98,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63],[0,0,0,1,1,0,0,57,0,0,0,164,0,16,4,63,0,0,6,178,1,0,0,65,0,0,0,173,0,0,1,61],[0,0,6,192,1,32,0,156,0,0,1,125,0,0,97,61,0,0,6,193,1,32,0,156,0,0,5,1,0,0,193,61],[0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75,0,0,5,1,0,0,193,61,0,0,6,220,1,0,0,65],[0,0,0,128,0,16,4,63,0,0,6,86,1,0,0,65,0,0,0,0,2,0,4,20,0,0,6,86,3,32,0,156],[0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,6,221,1,16,1,199,0,0,0,2,2,0,0,57],[25,83,25,78,0,0,4,15,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,6,86,3,48,1,151],[0,0,0,32,4,48,0,140,0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57,0,0,0,31,5,64,1,143],[0,0,0,5,4,64,2,114,0,0,1,18,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16],[0,0,0,0,8,113,3,79,0,0,0,0,8,8,4,59,0,0,0,0,0,135,4,53,0,0,0,1,6,96,0,57],[0,0,0,0,7,70,0,75,0,0,1,11,0,0,65,61,0,0,0,0,6,5,0,75,0,0,1,32,0,0,97,61],[0,0,0,3,5,80,2,16,0,0,0,5,4,64,2,16,0,0,0,0,6,4,4,51,0,0,0,0,6,86,1,207],[0,0,0,0,6,86,2,47,0,0,0,0,7,65,3,79,0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137],[0,0,0,0,7,87,2,47,0,0,0,0,5,87,1,207,0,0,0,0,5,101,1,159,0,0,0,0,0,84,4,53],[0,1,0,0,0,3,0,31,0,3,0,0,0,1,3,85,0,0,0,64,8,0,4,61,0,0,0,1,2,32,1,144],[0,0,4,82,0,0,97,61,0,0,0,0,1,0,4,51,0,0,6,222,1,16,1,103,0,0,0,64,2,128,0,57],[0,0,0,0,0,18,4,53,0,0,0,32,1,128,0,57,0,0,6,222,2,0,0,65,0,0,0,0,0,33,4,53],[0,0,0,64,1,0,0,57,0,0,0,0,0,24,4,53,0,0,0,0,1,8,0,25,0,11,0,0,0,8,0,29],[25,83,11,78,0,0,4,15,0,0,0,11,1,0,0,41,25,83,24,189,0,0,4,15,0,0,0,0,1,0,0,25],[0,0,25,85,0,1,4,48,0,0,6,183,1,32,0,156,0,0,1,130,0,0,97,61,0,0,6,184,1,32,0,156],[0,0,5,1,0,0,193,61,0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75,0,0,5,1,0,0,193,61],[0,0,0,5,1,0,0,57,0,0,1,79,0,0,1,61,0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75],[0,0,5,1,0,0,193,61,25,83,11,89,0,0,4,15,0,0,0,0,1,0,0,25,0,0,25,84,0,1,4,46],[0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75,0,0,5,1,0,0,193,61,0,0,0,3,1,0,0,57],[0,0,0,0,1,1,4,26,0,0,0,224,1,16,2,16,0,0,2,3,0,0,1,61,0,0,0,0,1,0,4,22],[0,0,0,0,1,1,0,75,0,0,5,1,0,0,193,61,0,0,0,1,1,0,0,57,0,0,0,0,1,1,4,26],[0,0,6,97,1,16,1,151,0,0,2,3,0,0,1,61,0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75],[0,0,5,1,0,0,193,61,0,0,0,4,1,0,0,57,0,0,2,2,0,0,1,61,25,83,18,136,0,0,4,15],[0,0,0,0,1,0,0,25,0,0,25,84,0,1,4,46,0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75],[0,0,5,1,0,0,193,61,0,0,0,11,1,0,0,57,0,0,2,2,0,0,1,61,0,0,0,0,1,0,4,22],[0,0,0,0,1,1,0,75,0,0,5,1,0,0,193,61,25,83,21,189,0,0,4,15,0,0,0,0,1,0,0,25],[0,0,25,84,0,1,4,46,0,0,0,0,2,0,4,22,0,0,0,0,2,2,0,75,0,0,5,1,0,0,193,61],[0,0,0,4,2,48,0,138,0,0,0,32,2,32,0,140,0,0,5,1,0,0,65,61,0,0,0,255,2,0,0,57],[0,0,0,0,2,2,4,70,0,0,0,4,1,16,3,112,0,0,0,0,1,1,4,59,0,0,0,0,1,18,0,75],[0,0,1,252,0,0,97,61,0,0,6,98,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57],[0,0,0,132,0,16,4,63,0,0,0,55,1,0,0,57,0,0,0,164,0,16,4,63,0,0,6,217,1,0,0,65],[0,0,0,196,0,16,4,63,0,0,6,218,1,0,0,65,0,0,0,228,0,16,4,63,0,0,6,219,1,0,0,65],[0,0,25,85,0,1,4,48,0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75,0,0,5,1,0,0,193,61],[0,0,6,91,1,0,0,65,0,0,2,3,0,0,1,61,0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75],[0,0,5,1,0,0,193,61,25,83,24,126,0,0,4,15,0,0,0,0,1,0,0,25,0,0,25,84,0,1,4,46],[0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75,0,0,5,1,0,0,193,61,0,0,6,87,1,0,0,65],[0,0,0,0,0,16,4,57,0,0,0,0,1,0,4,16,0,11,0,0,0,1,0,29,0,0,0,4,0,16,4,67],[0,0,6,86,1,0,0,65,0,0,0,0,2,0,4,20,0,0,6,86,3,32,0,156,0,0,0,0,2,1,128,25],[0,0,0,192,1,32,2,16,0,0,6,88,1,16,1,199,0,0,128,2,2,0,0,57,25,83,25,78,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,10,8,0,0,97,61,0,0,0,0,1,1,4,59,0,0,0,0,1,1,0,75],[0,0,5,1,0,0,97,61,0,0,0,64,4,0,4,61,0,0,6,225,1,0,0,65,0,0,0,0,5,20,4,54],[0,0,0,4,1,64,0,57,0,0,3,232,2,0,0,57,0,10,0,0,0,2,0,29,0,0,0,0,0,33,4,53],[0,0,0,36,7,64,0,57,0,0,0,0,0,7,4,53,0,0,0,0,1,0,4,20,0,0,0,11,6,0,0,41],[0,0,0,4,2,96,0,140,0,0,1,195,0,0,97,61,0,0,6,86,2,0,0,65,0,0,6,86,3,16,0,156],[0,0,0,0,1,2,128,25,0,0,6,86,3,64,0,156,0,0,0,0,2,4,64,25,0,0,0,64,2,32,2,16],[0,0,0,192,1,16,2,16,0,0,0,0,1,33,1,159,0,0,6,226,1,16,1,199,0,0,0,0,2,6,0,25],[0,9,0,0,0,5,0,29,0,8,0,0,0,4,0,29,0,7,0,0,0,7,0,29,25,83,25,73,0,0,4,15],[0,0,0,7,7,0,0,41,0,0,0,8,4,0,0,41,0,0,0,9,5,0,0,41,0,0,0,11,6,0,0,41],[0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,1,6,86,0,48,1,157,0,0,6,86,3,48,1,151],[0,3,0,0,0,1,3,85,0,0,0,1,2,32,1,144,0,0,4,124,0,0,97,61,0,0,6,94,1,64,0,156],[0,0,3,210,0,0,33,61,0,0,0,64,0,64,4,63,0,0,6,225,1,0,0,65,0,0,0,0,0,21,4,53],[0,0,1,244,1,0,0,57,0,0,0,0,0,23,4,53,0,0,0,68,1,64,0,57,0,0,0,1,2,0,0,57],[0,0,0,0,0,33,4,53,0,0,0,68,1,0,0,57,0,0,0,0,0,20,4,53,0,0,6,140,1,64,0,156],[0,0,3,210,0,0,33,61,0,0,0,128,1,64,0,57,0,0,0,64,0,16,4,63,0,0,0,0,3,4,4,51],[0,0,0,0,1,0,4,20,0,0,0,4,4,96,0,140,0,0,4,157,0,0,193,61,0,0,0,1,1,0,0,49],[0,0,4,175,0,0,1,61,0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75,0,0,5,1,0,0,193,61],[0,0,0,9,1,0,0,57,0,0,2,2,0,0,1,61,0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75],[0,0,5,1,0,0,193,61,0,0,0,12,1,0,0,57,0,0,2,2,0,0,1,61,0,0,0,0,1,0,4,22],[0,0,0,0,1,1,0,75,0,0,5,1,0,0,193,61,25,83,17,104,0,0,4,15,0,0,0,0,1,0,0,25],[0,0,25,84,0,1,4,46,0,0,0,0,2,0,4,22,0,0,0,0,2,2,0,75,0,0,5,1,0,0,193,61],[0,0,0,4,2,48,0,138,0,0,0,64,2,32,0,140,0,0,5,1,0,0,65,61,0,0,0,36,2,16,3,112],[0,0,0,0,2,2,4,59,0,0,0,0,3,2,0,75,0,0,0,0,3,0,0,25,0,0,0,1,3,0,192,57],[0,0,0,0,3,50,0,75,0,0,5,1,0,0,193,61,0,0,0,4,1,16,3,112,0,0,0,0,1,1,4,59],[0,0,0,255,3,0,0,57,0,0,0,0,0,19,4,71,0,0,0,0,1,2,0,75,0,0,4,116,0,0,193,61],[0,0,0,0,1,0,0,25,0,0,25,84,0,1,4,46,0,0,0,0,1,0,4,22,0,0,0,0,1,1,0,75],[0,0,5,1,0,0,193,61,0,0,0,2,1,0,0,57,0,0,0,0,1,1,4,26,0,0,0,128,0,16,4,63],[0,0,6,216,1,0,0,65,0,0,25,84,0,1,4,46,0,0,6,86,4,0,0,65,0,0,6,86,3,16,0,156],[0,0,0,0,1,4,128,25,0,0,0,192,1,16,2,16,0,0,6,92,1,16,1,199,25,83,25,73,0,0,4,15],[0,0,0,1,2,32,1,143,0,3,0,0,0,1,3,85,0,0,0,96,1,16,2,112,0,1,6,86,0,16,1,157],[0,0,6,86,3,16,1,151,0,0,0,96,1,0,0,57,0,0,0,0,4,3,0,75,0,0,3,208,0,0,193,61],[0,0,0,0,2,2,0,75,0,0,5,1,0,0,97,61,0,0,0,0,1,1,4,51,0,0,0,0,1,1,0,75],[0,0,5,1,0,0,193,61,0,0,0,32,1,0,0,57,0,0,1,0,0,16,4,67,0,0,1,32,0,0,4,67],[0,0,6,95,1,0,0,65,0,0,25,84,0,1,4,46,0,11,0,0,0,2,0,29,0,0,6,103,1,0,0,65],[0,0,0,0,0,16,4,57,0,0,6,86,3,0,0,65,0,0,0,0,1,0,4,20,0,0,6,86,2,16,0,156],[0,0,0,0,1,3,128,25,0,0,0,192,1,16,2,16,0,0,6,102,1,16,1,199,0,0,128,11,2,0,0,57],[25,83,25,78,0,0,4,15,0,0,0,1,2,32,1,144,0,0,10,8,0,0,97,61,0,0,0,0,1,1,4,59],[0,0,0,11,2,0,0,57,0,0,0,0,0,18,4,27,0,0,6,104,1,0,0,65,0,0,0,0,0,16,4,57],[0,0,0,0,1,0,4,20,0,0,6,86,2,16,0,156,0,0,6,86,1,0,128,65,0,0,0,192,1,16,2,16],[0,0,6,102,1,16,1,199,0,0,128,11,2,0,0,57,25,83,25,78,0,0,4,15,0,0,0,1,2,32,1,144],[0,0,10,8,0,0,97,61,0,0,0,0,1,1,4,59,0,0,0,10,2,0,0,57,0,0,0,0,3,2,4,26],[0,0,6,105,3,48,1,151,0,0,0,0,1,19,1,159,0,0,0,0,0,18,4,27,0,0,6,106,1,0,0,65],[0,0,0,0,0,16,4,57,0,0,6,86,3,0,0,65,0,0,0,0,1,0,4,20,0,0,6,86,2,16,0,156],[0,0,0,0,1,3,128,25,0,0,0,192,1,16,2,16,0,0,6,102,1,16,1,199,0,0,128,11,2,0,0,57],[25,83,25,78,0,0,4,15,0,0,0,1,2,32,1,144,0,0,10,8,0,0,97,61,0,0,0,0,1,1,4,59],[0,0,0,9,2,0,0,57,0,0,0,0,0,18,4,27,0,0,6,107,1,0,0,65,0,0,0,0,0,16,4,57],[0,0,0,0,1,0,4,20,0,0,6,86,2,16,0,156,0,0,6,86,1,0,128,65,0,0,0,192,1,16,2,16],[0,0,6,102,1,16,1,199,0,0,128,11,2,0,0,57,25,83,25,78,0,0,4,15,0,0,0,1,2,32,1,144],[0,0,10,8,0,0,97,61,0,0,0,0,1,1,4,59,0,0,0,8,2,0,0,57,0,0,0,0,0,18,4,27],[0,0,6,108,1,0,0,65,0,0,0,0,0,16,4,57,0,0,6,86,3,0,0,65,0,0,0,0,1,0,4,20],[0,0,6,86,2,16,0,156,0,0,0,0,1,3,128,25,0,0,0,192,1,16,2,16,0,0,6,102,1,16,1,199],[0,0,128,11,2,0,0,57,25,83,25,78,0,0,4,15,0,0,0,1,2,32,1,144,0,0,10,8,0,0,97,61],[0,0,0,0,1,1,4,59,0,0,0,7,2,0,0,57,0,0,0,0,0,18,4,27,0,0,6,109,1,0,0,65],[0,0,0,0,0,16,4,57,0,0,0,0,1,0,4,20,0,0,6,86,2,16,0,156,0,0,6,86,1,0,128,65],[0,0,0,192,1,16,2,16,0,0,6,102,1,16,1,199,0,0,128,11,2,0,0,57,25,83,25,78,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,10,8,0,0,97,61,0,0,0,0,1,1,4,59,0,0,0,4,2,0,0,57],[0,0,0,0,0,18,4,27,0,0,6,110,1,0,0,65,0,0,0,0,0,16,4,57,0,0,6,86,1,0,0,65],[0,0,0,0,2,0,4,20,0,0,6,86,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16],[0,0,6,102,1,16,1,199,0,0,128,11,2,0,0,57,25,83,25,78,0,0,4,15,0,0,0,1,2,32,1,144],[0,0,10,8,0,0,97,61,0,0,0,0,1,1,4,59,0,0,6,97,1,16,1,151,0,0,0,5,2,0,0,57],[0,0,0,0,3,2,4,26,0,0,6,105,3,48,1,151,0,0,0,0,1,19,1,159,0,0,0,0,0,18,4,27],[0,0,0,3,1,0,0,57,0,0,0,0,2,1,4,26,0,0,6,111,2,32,1,151,0,0,0,2,3,0,3,103],[0,0,0,0,3,3,4,59,0,0,0,224,3,48,2,112,0,0,0,0,2,50,1,159,0,0,0,0,0,33,4,27],[0,0,0,6,1,0,0,57,0,0,0,11,2,0,0,41,0,0,0,0,0,33,4,27,0,0,0,0,2,0,4,22],[0,0,0,12,1,0,0,57,0,1,0,0,0,2,0,29,0,0,0,0,0,33,4,27,0,0,0,0,1,0,4,20],[0,2,0,0,0,1,0,29,0,0,0,64,1,0,4,61,0,0,0,0,5,1,0,25,0,0,6,112,1,16,0,156],[0,0,3,210,0,0,33,61,0,0,0,160,1,80,0,57,0,0,0,64,0,16,4,63,0,0,0,128,1,80,0,57],[0,0,6,113,2,0,0,65,0,0,0,0,0,33,4,53,0,0,0,96,1,80,0,57,0,0,6,114,2,0,0,65],[0,0,0,0,0,33,4,53,0,0,0,64,1,80,0,57,0,0,6,115,2,0,0,65,0,0,0,0,0,33,4,53],[0,0,0,122,1,0,0,57,0,0,0,0,10,21,4,54,0,0,6,116,1,0,0,65,0,0,0,0,0,26,4,53],[0,5,128,16,0,0,0,61,0,9,0,0,0,0,0,29,0,11,0,0,0,5,0,29,0,0,6,86,1,160,0,156],[0,0,6,86,4,0,0,65,0,0,0,0,10,4,128,25,0,0,0,64,1,160,2,16,0,0,0,0,2,5,4,51],[0,0,6,86,3,32,0,156,0,0,0,0,2,4,128,25,0,0,0,96,2,32,2,16,0,0,0,0,1,18,1,159],[0,0,0,0,2,0,4,20,0,0,6,86,3,32,0,156,0,0,0,0,2,4,128,25,0,0,0,192,2,32,2,16],[0,0,0,0,1,18,1,159,0,0,6,117,1,16,1,199,0,0,0,5,2,0,0,41,25,83,25,78,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,5,1,0,0,97,61,0,0,0,64,2,0,4,61,0,0,0,0,1,1,4,59],[0,10,0,0,0,1,0,29,0,0,0,11,6,0,0,41,0,0,0,0,1,6,4,51,0,0,0,0,3,1,0,75],[0,0,2,213,0,0,97,61,0,0,0,0,3,0,0,25,0,0,0,0,4,35,0,25,0,0,0,32,3,48,0,57],[0,0,0,0,5,99,0,25,0,0,0,0,5,5,4,51,0,0,0,0,0,84,4,53,0,0,0,0,4,19,0,75],[0,0,2,206,0,0,65,61,0,0,0,0,3,33,0,25,0,0,0,0,0,3,4,53,0,0,6,86,3,32,0,156],[0,0,6,86,4,0,0,65,0,0,0,0,2,4,128,25,0,0,0,64,2,32,2,16,0,0,6,86,3,16,0,156],[0,0,0,0,1,4,128,25,0,0,0,96,1,16,2,16,0,0,0,0,1,33,1,159,0,0,0,0,2,0,4,20],[0,0,6,86,3,32,0,156,0,0,0,0,2,4,128,25,0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159],[0,0,0,2,2,0,0,57,25,83,25,78,0,0,4,15,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112],[0,0,6,86,3,48,1,151,0,0,0,32,4,48,0,140,0,0,0,0,5,3,0,25,0,0,0,32,5,0,128,57],[0,0,0,5,4,80,2,114,0,0,2,246,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16],[0,0,0,0,8,113,3,79,0,0,0,0,8,8,4,59,0,0,0,0,0,135,4,53,0,0,0,1,6,96,0,57],[0,0,0,0,7,70,0,75,0,0,2,239,0,0,65,61,0,0,0,31,5,80,1,144,0,0,3,4,0,0,97,61],[0,0,0,3,5,80,2,16,0,0,0,5,4,64,2,16,0,0,0,0,6,4,4,51,0,0,0,0,6,86,1,207],[0,0,0,0,6,86,2,47,0,0,0,0,7,65,3,79,0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137],[0,0,0,0,7,87,2,47,0,0,0,0,5,87,1,207,0,0,0,0,5,101,1,159,0,0,0,0,0,84,4,53],[0,1,0,0,0,3,0,31,0,3,0,0,0,1,3,85,0,0,0,64,11,0,4,61,0,0,0,1,2,32,1,144],[0,0,5,71,0,0,97,61,0,0,0,0,2,0,4,51,0,0,0,32,12,176,0,57,0,0,0,11,6,0,0,41],[0,0,0,0,1,6,4,51,0,0,0,0,3,1,0,75,0,0,3,23,0,0,97,61,0,0,0,0,3,0,0,25],[0,0,0,0,4,195,0,25,0,0,0,32,3,48,0,57,0,0,0,0,5,99,0,25,0,0,0,0,5,5,4,51],[0,0,0,0,0,84,4,53,0,0,0,0,4,19,0,75,0,0,3,16,0,0,65,61,0,0,0,10,2,32,1,79],[0,0,0,0,3,193,0,25,0,0,0,0,0,35,4,53,0,0,0,32,3,16,0,57,0,0,0,0,0,59,4,53],[0,0,0,95,3,16,0,57,0,0,0,32,1,0,0,138,0,0,0,0,3,19,1,111,0,0,0,0,13,179,0,25],[0,0,0,0,3,61,0,75,0,0,0,0,3,0,0,25,0,0,0,1,3,0,64,57,0,0,6,94,4,208,0,156],[0,0,3,210,0,0,33,61,0,0,0,1,3,48,1,144,0,0,3,210,0,0,193,61,0,0,0,64,0,208,4,63],[0,0,0,13,10,0,0,57,0,0,0,0,3,10,4,26,0,0,6,94,4,48,0,156,0,0,3,210,0,0,33,61],[0,0,0,1,4,48,0,57,0,0,0,0,0,74,4,27,0,0,0,0,0,160,4,53,0,0,6,118,3,48,0,65],[0,0,0,0,0,35,4,27,0,0,0,0,3,10,4,26,0,0,0,0,4,3,0,75,0,0,0,116,0,0,97,61],[0,0,0,1,6,48,0,140,0,0,0,6,3,0,0,41,0,0,3,80,0,0,97,61,0,0,0,0,3,10,4,26],[0,0,0,0,4,99,0,75,0,0,6,75,0,0,161,61,0,0,0,1,4,96,0,138,0,0,0,1,5,64,2,112],[0,0,0,0,7,83,0,75,0,0,6,75,0,0,161,61,0,0,6,118,7,96,0,65,0,0,0,0,9,7,4,26],[0,0,0,0,0,160,4,53,0,0,6,118,6,80,0,65,0,0,0,0,8,6,4,26,0,0,0,0,9,137,0,75],[0,0,3,80,0,0,161,61,0,0,0,0,0,135,4,27,0,0,0,0,3,10,4,26,0,0,0,0,3,83,0,75],[0,0,6,75,0,0,161,61,0,0,0,0,0,38,4,27,0,0,0,2,3,64,0,140,0,0,0,0,6,5,0,25],[0,0,3,55,0,0,129,61,0,0,0,0,3,10,4,26,0,0,0,0,2,3,0,75,0,0,0,116,0,0,97,61],[0,0,0,1,2,48,0,138,0,0,0,0,2,35,1,112,0,0,3,92,0,0,193,61,0,0,0,14,2,0,0,57],[0,0,0,0,3,2,4,26,0,0,6,94,4,48,1,151,0,0,6,94,5,64,0,156,0,0,0,116,0,0,97,61],[0,0,6,119,3,48,1,151,0,0,0,1,4,64,0,57,0,0,0,0,3,52,1,159,0,0,0,0,0,50,4,27],[0,8,0,0,0,12,0,29,0,11,0,0,0,10,0,29,0,0,6,120,2,0,0,65,0,0,0,0,0,45,4,53],[0,0,0,4,2,208,0,57,0,0,0,32,3,0,0,57,0,4,0,0,0,3,0,29,0,0,0,0,0,50,4,53],[0,0,0,0,2,11,4,51,0,0,0,36,3,208,0,57,0,0,0,0,0,35,4,53,0,0,0,68,3,208,0,57],[0,0,0,0,4,2,0,75,0,0,3,114,0,0,97,61,0,0,0,0,4,0,0,25,0,0,0,0,5,52,0,25],[0,0,0,32,4,64,0,57,0,0,0,0,6,180,0,25,0,0,0,0,6,6,4,51,0,0,0,0,0,101,4,53],[0,0,0,0,5,36,0,75,0,0,3,107,0,0,65,61,0,10,0,0,0,11,0,29,0,0,0,0,3,50,0,25],[0,0,0,0,0,3,4,53,0,0,0,31,2,32,0,57,0,0,0,0,1,18,1,111,0,0,6,86,2,208,0,156],[0,0,6,86,4,0,0,65,0,0,0,0,2,4,0,25,0,0,0,0,2,13,64,25,0,0,0,64,2,32,2,16],[0,0,0,68,1,16,0,57,0,0,6,86,3,16,0,156,0,0,0,0,1,4,128,25,0,0,0,96,1,16,2,16],[0,0,0,0,1,33,1,159,0,0,0,0,2,0,4,20,0,0,6,86,3,32,0,156,0,0,0,0,2,4,128,25],[0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159,0,0,128,8,2,0,0,57,0,7,0,0,0,13,0,29],[25,83,25,73,0,0,4,15,0,0,0,7,11,0,0,41,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112],[0,0,6,86,3,48,1,151,0,0,0,32,4,48,0,140,0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57],[0,0,0,5,5,64,2,114,0,0,3,155,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16],[0,0,0,0,8,123,0,25,0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53],[0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,3,147,0,0,65,61,0,0,0,31,6,64,1,144],[0,0,0,11,9,0,0,41,0,0,0,8,10,0,0,41,0,0,3,172,0,0,97,61,0,0,0,5,5,80,2,16],[0,0,0,0,7,81,3,79,0,0,0,0,5,91,0,25,0,0,0,3,6,96,2,16,0,0,0,0,8,5,4,51],[0,0,0,0,8,104,1,207,0,0,0,0,8,104,2,47,0,0,0,0,7,7,4,59,0,0,1,0,6,96,0,137],[0,0,0,0,7,103,2,47,0,0,0,0,6,103,1,207,0,0,0,0,6,134,1,159,0,0,0,0,0,101,4,53],[0,1,0,0,0,3,0,31,0,3,0,0,0,1,3,85,0,0,0,1,2,32,1,144,0,0,0,10,5,0,0,41],[0,0,5,103,0,0,97,61,0,0,0,31,1,64,0,57,0,0,0,96,2,16,1,143,0,0,0,0,1,178,0,25],[0,0,0,0,2,33,0,75,0,0,0,0,2,0,0,25,0,0,0,1,2,0,64,57,0,0,6,94,4,16,0,156],[0,0,3,210,0,0,33,61,0,0,0,1,2,32,1,144,0,0,3,210,0,0,193,61,0,0,0,64,0,16,4,63],[0,0,0,32,2,48,0,140,0,0,5,1,0,0,65,61,0,0,0,9,3,0,0,41,0,0,0,2,2,48,0,140],[0,9,0,1,0,48,0,61,0,0,2,178,0,0,161,61,0,0,0,0,2,9,4,26,0,0,0,0,3,2,0,75],[0,0,5,132,0,0,193,61,0,0,0,68,2,16,0,57,0,0,6,178,3,0,0,65,0,0,0,0,0,50,4,53],[0,0,0,36,2,16,0,57,0,0,0,1,3,0,0,57,0,0,0,0,0,50,4,53,0,0,6,98,2,0,0,65],[0,0,0,0,0,33,4,53,0,0,0,4,2,16,0,57,0,0,0,4,3,0,0,41,0,0,4,190,0,0,1,61],[0,0,6,93,1,48,0,156,0,0,3,216,0,0,65,61,0,0,6,224,1,0,0,65,0,0,0,0,0,16,4,53],[0,0,0,65,1,0,0,57,0,0,0,4,0,16,4,63,0,0,6,166,1,0,0,65,0,0,25,85,0,1,4,48],[0,0,0,31,1,48,0,57,0,0,0,32,4,0,0,138,0,0,0,0,1,65,1,111,0,0,0,63,1,16,0,57],[0,0,0,0,4,65,1,111,0,0,0,64,1,0,4,61,0,0,0,0,4,65,0,25,0,0,0,0,5,20,0,75],[0,0,0,0,5,0,0,25,0,0,0,1,5,0,64,57,0,0,6,94,6,64,0,156,0,0,3,210,0,0,33,61],[0,0,0,1,5,80,1,144,0,0,3,210,0,0,193,61,0,0,0,64,0,64,4,63,0,0,0,31,4,48,1,143],[0,0,0,0,5,49,4,54,0,0,0,3,6,0,3,103,0,0,0,5,3,48,2,114,0,0,3,245,0,0,97,61],[0,0,0,0,7,0,0,25,0,0,0,5,8,112,2,16,0,0,0,0,9,133,0,25,0,0,0,0,8,134,3,79],[0,0,0,0,8,8,4,59,0,0,0,0,0,137,4,53,0,0,0,1,7,112,0,57,0,0,0,0,8,55,0,75],[0,0,3,237,0,0,65,61,0,0,0,0,7,4,0,75,0,0,2,20,0,0,97,61,0,0,0,5,3,48,2,16],[0,0,0,0,6,54,3,79,0,0,0,0,3,53,0,25,0,0,0,3,4,64,2,16,0,0,0,0,5,3,4,51],[0,0,0,0,5,69,1,207,0,0,0,0,5,69,2,47,0,0,0,0,6,6,4,59,0,0,1,0,4,64,0,137],[0,0,0,0,6,70,2,47,0,0,0,0,4,70,1,207,0,0,0,0,4,84,1,159,0,0,0,0,0,67,4,53],[0,0,2,20,0,0,1,61,0,0,6,118,2,0,0,65,0,0,0,1,3,0,0,57,0,0,6,124,4,0,0,65],[0,0,4,17,0,0,1,61,0,0,0,1,6,0,0,138,0,0,0,0,6,101,0,75,0,0,0,116,0,0,97,61],[0,0,0,1,6,80,0,57,0,0,0,0,6,86,1,112,0,0,4,72,0,0,97,61,0,0,0,0,6,5,0,75],[0,0,5,3,0,0,97,61,0,0,6,121,6,80,0,65,0,0,0,0,7,6,4,26,0,0,0,0,0,114,4,27],[0,0,0,0,0,6,4,27,0,0,0,1,5,80,0,138,0,0,0,0,0,81,4,27,0,0,0,2,6,80,0,140],[0,0,4,12,0,0,65,61,0,0,0,0,8,3,0,25,0,0,0,0,9,0,0,25,0,0,0,0,7,0,0,25],[0,0,0,2,10,144,0,57,0,0,0,0,6,90,0,75,0,0,0,0,6,8,0,25,0,0,4,39,0,0,129,61],[0,0,6,122,6,144,0,65,0,0,0,0,6,6,4,26,0,0,6,123,9,144,0,65,0,0,0,0,9,9,4,26],[0,0,0,0,6,105,0,75,0,0,0,0,6,8,0,25,0,0,0,0,6,10,64,25,0,0,0,0,8,101,0,75],[0,0,6,75,0,0,161,61,0,0,6,118,8,96,0,65,0,0,0,0,9,117,0,75,0,0,6,75,0,0,161,61],[0,0,0,0,9,8,4,26,0,0,6,118,10,112,0,65,0,0,0,0,7,10,4,26,0,0,0,0,11,121,0,75],[0,0,4,9,0,0,161,61,0,0,0,0,0,154,4,27,0,0,0,0,5,1,4,26,0,0,0,0,5,101,0,75],[0,0,6,75,0,0,161,61,0,0,0,0,0,120,4,27,0,0,0,0,5,6,0,75,0,0,0,0,5,0,0,25],[0,0,0,0,5,4,64,25,0,0,6,124,7,96,1,151,0,0,0,0,8,7,0,75,0,0,0,0,8,0,0,25],[0,0,0,0,8,4,32,25,0,0,6,124,7,112,0,156,0,0,0,0,8,5,192,25,0,0,0,0,5,8,0,75],[0,0,0,116,0,0,193,61,0,0,0,0,5,1,4,26,0,0,0,1,9,96,2,16,0,0,0,1,8,144,1,191],[0,0,0,0,7,88,0,75,0,0,0,0,7,6,0,25,0,0,4,28,0,0,65,61,0,0,4,9,0,0,1,61],[0,0,0,14,6,0,0,57,0,0,0,0,7,6,4,26,0,0,6,94,8,112,1,151,0,0,0,1,8,128,0,138],[0,0,6,94,9,128,0,156,0,0,0,116,0,0,33,61,0,0,6,119,7,112,1,151,0,0,0,0,7,120,1,159],[0,0,0,0,0,118,4,27,0,0,4,15,0,0,1,61,0,0,0,31,2,48,1,143,0,0,0,5,4,48,2,114],[0,0,4,94,0,0,97,61,0,0,0,0,5,0,0,25,0,0,0,5,6,80,2,16,0,0,0,0,7,104,0,25],[0,0,0,0,6,97,3,79,0,0,0,0,6,6,4,59,0,0,0,0,0,103,4,53,0,0,0,1,5,80,0,57],[0,0,0,0,6,69,0,75,0,0,4,86,0,0,65,61,0,0,0,0,5,2,0,75,0,0,4,109,0,0,97,61],[0,0,0,5,4,64,2,16,0,0,0,0,1,65,3,79,0,0,0,0,4,72,0,25,0,0,0,3,2,32,2,16],[0,0,0,0,5,4,4,51,0,0,0,0,5,37,1,207,0,0,0,0,5,37,2,47,0,0,0,0,1,1,4,59],[0,0,1,0,2,32,0,137,0,0,0,0,1,33,2,47,0,0,0,0,1,33,1,207,0,0,0,0,1,81,1,159],[0,0,0,0,0,20,4,53,0,0,6,86,1,0,0,65,0,0,6,86,2,128,0,156,0,0,0,0,8,1,128,25],[0,0,0,64,1,128,2,16,0,0,0,96,2,48,2,16,0,0,0,0,1,33,1,159,0,0,25,85,0,1,4,48],[0,0,6,98,1,0,0,65,0,0,0,128,0,16,4,63,0,0,0,32,1,0,0,57,0,0,0,132,0,16,4,63],[0,0,0,26,1,0,0,57,0,0,0,164,0,16,4,63,0,0,6,223,1,0,0,65,0,0,0,173,0,0,1,61],[0,0,0,64,2,0,4,61,0,0,0,31,4,48,1,143,0,0,0,5,5,48,2,114,0,0,4,137,0,0,97,61],[0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79],[0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75],[0,0,4,129,0,0,65,61,0,0,0,0,6,4,0,75,0,0,4,152,0,0,97,61,0,0,0,5,5,80,2,16],[0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51],[0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137],[0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53],[0,0,6,86,1,0,0,65,0,0,6,86,4,32,0,156,0,0,0,0,2,1,128,25,0,0,0,64,1,32,2,16],[0,0,4,113,0,0,1,61,0,0,6,86,2,0,0,65,0,0,6,86,4,80,0,156,0,0,0,0,5,2,128,25],[0,0,0,64,4,80,2,16,0,0,6,86,5,48,0,156,0,0,0,0,3,2,128,25,0,0,0,96,3,48,2,16],[0,0,0,0,3,67,1,159,0,0,6,86,4,16,0,156,0,0,0,0,1,2,128,25,0,0,0,192,1,16,2,16],[0,0,0,0,1,19,1,159,0,0,0,0,2,6,0,25,25,83,25,73,0,0,4,15,0,3,0,0,0,1,3,85],[0,0,0,96,1,16,2,112,0,1,6,86,0,16,1,157,0,0,6,86,1,16,1,151,0,0,0,0,3,1,0,75],[0,0,4,197,0,0,193,61,0,0,0,1,1,32,1,144,0,0,4,240,0,0,97,61,0,0,0,64,1,0,4,61],[0,0,0,68,2,16,0,57,0,0,6,228,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57],[0,0,0,27,3,0,0,57,0,0,0,0,0,50,4,53,0,0,6,98,2,0,0,65,0,0,0,0,0,33,4,53],[0,0,0,4,2,16,0,57,0,0,0,32,3,0,0,57,0,0,0,0,0,50,4,53,0,0,6,86,2,0,0,65],[0,0,6,86,3,16,0,156,0,0,0,0,1,2,128,25,0,0,0,64,1,16,2,16,0,0,6,126,1,16,1,199],[0,0,25,85,0,1,4,48,0,0,0,63,3,16,0,57,0,0,0,32,4,0,0,138,0,0,0,0,3,67,1,111],[0,0,0,64,4,0,4,61,0,0,0,0,3,52,0,25,0,0,0,0,5,67,0,75,0,0,0,0,5,0,0,25],[0,0,0,1,5,0,64,57,0,0,6,94,6,48,0,156,0,0,3,210,0,0,33,61,0,0,0,1,5,80,1,144],[0,0,3,210,0,0,193,61,0,0,0,64,0,48,4,63,0,0,0,31,3,16,1,143,0,0,0,0,4,20,4,54],[0,0,0,3,5,0,3,103,0,0,0,5,1,16,2,114,0,0,4,224,0,0,97,61,0,0,0,0,6,0,0,25],[0,0,0,5,7,96,2,16,0,0,0,0,8,116,0,25,0,0,0,0,7,117,3,79,0,0,0,0,7,7,4,59],[0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,22,0,75,0,0,4,216,0,0,65,61],[0,0,0,0,6,3,0,75,0,0,4,177,0,0,97,61,0,0,0,5,1,16,2,16,0,0,0,0,5,21,3,79],[0,0,0,0,1,20,0,25,0,0,0,3,3,48,2,16,0,0,0,0,4,1,4,51,0,0,0,0,4,52,1,207],[0,0,0,0,4,52,2,47,0,0,0,0,5,5,4,59,0,0,1,0,3,48,0,137,0,0,0,0,5,53,2,47],[0,0,0,0,3,53,1,207,0,0,0,0,3,67,1,159,0,0,0,0,0,49,4,53,0,0,4,177,0,0,1,61],[0,0,6,87,1,0,0,65,0,0,0,0,0,16,4,57,0,0,0,11,1,0,0,41,0,0,0,4,0,16,4,67],[0,0,6,86,1,0,0,65,0,0,0,0,2,0,4,20,0,0,6,86,3,32,0,156,0,0,0,0,2,1,128,25],[0,0,0,192,1,32,2,16,0,0,6,88,1,16,1,199,0,0,128,2,2,0,0,57,25,83,25,78,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,10,8,0,0,97,61,0,0,0,0,1,1,4,59,0,0,0,0,1,1,0,75],[0,0,5,5,0,0,193,61,0,0,0,0,1,0,0,25,0,0,25,85,0,1,4,48,0,0,0,0,0,16,4,53],[0,0,0,232,0,0,1,61,0,0,0,64,2,0,4,61,0,0,6,227,1,0,0,65,0,0,0,0,0,18,4,53],[0,9,0,0,0,2,0,29,0,0,0,4,1,32,0,57,0,0,0,10,2,0,0,41,0,0,0,0,0,33,4,53],[0,0,0,0,1,0,4,20,0,0,0,11,2,0,0,41,0,0,0,4,2,32,0,140,0,0,5,35,0,0,97,61],[0,0,6,86,2,0,0,65,0,0,6,86,3,16,0,156,0,0,0,0,1,2,128,25,0,0,0,9,4,0,0,41],[0,0,6,86,3,64,0,156,0,0,0,0,2,4,64,25,0,0,0,64,2,32,2,16,0,0,0,192,1,16,2,16],[0,0,0,0,1,33,1,159,0,0,6,166,1,16,1,199,0,0,0,11,2,0,0,41,25,83,25,73,0,0,4,15],[0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,1,6,86,0,48,1,157,0,0,6,86,3,48,1,151],[0,3,0,0,0,1,3,85,0,0,0,1,2,32,1,144,0,0,5,42,0,0,97,61,0,0,0,9,1,0,0,41],[0,0,6,94,1,16,0,156,0,0,3,210,0,0,33,61,0,0,0,9,1,0,0,41,0,0,0,64,0,16,4,63],[0,0,0,0,1,0,0,25,0,0,25,84,0,1,4,46,0,0,0,64,2,0,4,61,0,0,0,31,4,48,1,143],[0,0,0,5,5,48,2,114,0,0,5,55,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16],[0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53],[0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,5,47,0,0,65,61,0,0,0,0,6,4,0,75],[0,0,5,70,0,0,97,61,0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25],[0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47],[0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207],[0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,4,152,0,0,1,61,0,0,0,31,2,48,1,143],[0,0,0,5,4,48,2,114,0,0,5,83,0,0,97,61,0,0,0,0,5,0,0,25,0,0,0,5,6,80,2,16],[0,0,0,0,7,107,0,25,0,0,0,0,6,97,3,79,0,0,0,0,6,6,4,59,0,0,0,0,0,103,4,53],[0,0,0,1,5,80,0,57,0,0,0,0,6,69,0,75,0,0,5,75,0,0,65,61,0,0,0,0,5,2,0,75],[0,0,5,98,0,0,97,61,0,0,0,5,4,64,2,16,0,0,0,0,1,65,3,79,0,0,0,0,4,75,0,25],[0,0,0,3,2,32,2,16,0,0,0,0,5,4,4,51,0,0,0,0,5,37,1,207,0,0,0,0,5,37,2,47],[0,0,0,0,1,1,4,59,0,0,1,0,2,32,0,137,0,0,0,0,1,33,2,47,0,0,0,0,1,33,1,207],[0,0,0,0,1,81,1,159,0,0,0,0,0,20,4,53,0,0,6,86,1,0,0,65,0,0,6,86,2,176,0,156],[0,0,0,0,11,1,128,25,0,0,0,64,1,176,2,16,0,0,4,113,0,0,1,61,0,0,0,64,2,0,4,61],[0,0,0,31,4,48,1,143,0,0,0,5,5,48,2,114,0,0,5,116,0,0,97,61,0,0,0,0,6,0,0,25],[0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59],[0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,5,108,0,0,65,61],[0,0,0,0,6,4,0,75,0,0,5,131,0,0,97,61,0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79],[0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207],[0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47],[0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,4,152,0,0,1,61],[0,0,6,121,3,32,0,65,0,0,0,0,4,3,4,26,0,0,6,118,5,0,0,65,0,0,0,0,0,69,4,27],[0,0,0,11,10,0,0,41,0,0,0,0,0,160,4,53,0,0,0,0,0,3,4,27,0,0,0,1,3,32,0,138],[0,0,0,0,0,58,4,27,0,0,0,2,2,48,0,140,0,0,5,194,0,0,65,61,0,0,0,1,6,0,0,57],[0,0,6,124,2,0,0,65,0,0,0,0,7,0,0,25,0,0,0,0,5,0,0,25,0,0,0,2,8,112,0,57],[0,0,0,0,4,56,0,75,0,0,0,0,4,6,0,25,0,0,5,158,0,0,129,61,0,0,6,122,4,112,0,65],[0,0,0,0,4,4,4,26,0,0,6,123,7,112,0,65,0,0,0,0,7,7,4,26,0,0,0,0,4,71,0,75],[0,0,0,0,4,6,0,25,0,0,0,0,4,8,64,25,0,0,0,0,6,67,0,75,0,0,6,75,0,0,161,61],[0,0,6,118,6,64,0,65,0,0,0,0,7,83,0,75,0,0,6,75,0,0,161,61,0,0,0,0,7,6,4,26],[0,0,0,0,0,160,4,53,0,0,6,118,8,80,0,65,0,0,0,0,5,8,4,26,0,0,0,0,9,87,0,75],[0,0,5,191,0,0,161,61,0,0,0,0,0,120,4,27,0,0,0,0,3,10,4,26,0,0,0,0,3,67,0,75],[0,0,6,75,0,0,161,61,0,0,0,0,0,86,4,27,0,0,0,0,3,4,0,75,0,0,0,0,3,0,0,25],[0,0,0,0,3,2,64,25,0,0,6,124,5,64,1,151,0,0,0,0,6,5,0,75,0,0,0,0,6,0,0,25],[0,0,0,0,6,2,32,25,0,0,6,124,5,80,0,156,0,0,0,0,6,3,192,25,0,0,0,0,3,6,0,75],[0,0,0,116,0,0,193,61,0,0,0,0,3,10,4,26,0,0,0,1,7,64,2,16,0,0,0,1,6,112,1,191],[0,0,0,0,5,54,0,75,0,0,0,0,5,4,0,25,0,0,5,147,0,0,65,61,0,0,0,1,2,0,0,138],[0,0,0,0,2,35,0,75,0,0,0,116,0,0,97,61,0,0,0,1,2,48,0,57,0,0,0,0,2,50,1,112],[0,0,5,206,0,0,193,61,0,0,0,14,2,0,0,57,0,0,0,0,3,2,4,26,0,0,6,94,4,48,1,151],[0,0,0,1,4,64,0,138,0,0,6,94,5,64,0,156,0,0,0,116,0,0,33,61,0,0,6,119,3,48,1,151],[0,0,0,0,3,52,1,159,0,0,0,0,0,50,4,27,0,0,0,0,3,0,4,20,0,9,0,0,0,3,0,29],[0,0,0,2,2,48,0,107,0,0,6,79,0,0,161,61,0,0,0,10,6,0,0,41,0,0,0,0,2,6,4,51],[0,0,0,0,3,2,0,75,0,0,5,222,0,0,97,61,0,0,0,0,3,0,0,25,0,0,0,0,4,19,0,25],[0,0,0,32,3,48,0,57,0,0,0,0,5,99,0,25,0,0,0,0,5,5,4,51,0,0,0,0,0,84,4,53],[0,0,0,0,4,35,0,75,0,0,5,215,0,0,65,61,0,0,0,0,3,18,0,25,0,0,0,0,0,3,4,53],[0,0,6,86,4,0,0,65,0,0,6,86,3,16,0,156,0,0,0,0,1,4,128,25,0,0,0,64,1,16,2,16],[0,0,6,86,3,32,0,156,0,0,0,0,2,4,128,25,0,0,0,96,2,32,2,16,0,0,0,0,1,18,1,159],[0,0,0,0,2,0,4,20,0,0,6,86,3,32,0,156,0,0,0,0,2,4,128,25,0,0,0,192,2,32,2,16],[0,0,0,0,1,18,1,159,0,0,6,117,1,16,1,199,0,0,128,16,2,0,0,57,25,83,25,78,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,5,1,0,0,97,61,0,0,0,9,3,0,0,41,0,0,0,2,2,48,0,105],[0,0,0,0,5,1,4,59,0,0,0,64,1,0,4,61,0,0,0,0,0,33,4,53,0,0,0,0,2,0,4,20],[0,0,6,86,3,32,0,156,0,0,6,86,4,0,0,65,0,0,0,0,2,4,128,25,0,0,6,86,3,16,0,156],[0,0,0,0,1,4,128,25,0,0,0,64,1,16,2,16,0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159],[0,0,6,127,1,16,1,199,0,0,128,13,2,0,0,57,0,0,0,2,3,0,0,57,0,0,6,128,4,0,0,65],[25,83,25,73,0,0,4,15,0,0,0,11,5,0,0,41,0,0,0,1,1,32,1,144,0,0,5,1,0,0,97,61],[0,0,0,64,2,0,4,61,0,0,6,129,1,32,0,156,0,0,3,210,0,0,33,61,0,0,0,192,1,32,0,57],[0,0,0,64,0,16,4,63,0,0,0,160,1,32,0,57,0,0,6,130,3,0,0,65,0,0,0,0,0,49,4,53],[0,0,0,128,3,32,0,57,0,0,6,131,1,0,0,65,0,0,0,0,0,19,4,53,0,0,0,96,3,32,0,57],[0,0,0,0,0,19,4,53,0,0,0,64,3,32,0,57,0,0,0,0,0,19,4,53,0,0,0,32,3,32,0,57],[0,0,0,0,0,19,4,53,0,0,0,135,3,0,0,57,0,0,0,0,0,50,4,53,0,0,0,64,2,0,4,61],[0,0,6,129,3,32,0,156,0,0,3,210,0,0,33,61,0,0,0,192,3,32,0,57,0,0,0,64,0,48,4,63],[0,0,0,160,3,32,0,57,0,0,6,132,4,0,0,65,0,0,0,0,0,67,4,53,0,0,0,128,3,32,0,57],[0,0,0,0,0,19,4,53,0,0,0,96,3,32,0,57,0,0,0,0,0,19,4,53,0,0,0,64,3,32,0,57],[0,0,0,0,0,19,4,53,0,0,0,32,3,32,0,57,0,0,0,0,0,19,4,53,0,0,0,136,1,0,0,57],[0,0,0,0,0,18,4,53,0,0,0,64,1,0,4,61,0,0,6,129,2,16,0,156,0,0,3,210,0,0,33,61],[0,0,0,192,2,16,0,57,0,0,0,64,0,32,4,63,0,0,0,160,2,16,0,57,0,0,6,133,3,0,0,65],[0,0,0,0,0,50,4,53,0,0,0,128,2,16,0,57,0,0,6,131,3,0,0,65,0,0,0,0,0,50,4,53],[0,0,0,96,2,16,0,57,0,0,0,0,0,50,4,53,0,0,0,64,2,16,0,57,0,0,0,0,0,50,4,53],[0,0,0,32,2,16,0,57,0,0,0,0,0,50,4,53,0,0,0,137,2,0,0,57,0,0,0,0,0,33,4,53],[0,0,0,0,1,5,4,26,0,10,0,0,0,1,0,29,0,0,0,0,1,1,0,75,0,0,6,85,0,0,193,61],[0,0,0,64,1,0,4,61,0,0,0,68,2,16,0,57,0,0,6,177,3,0,0,65,0,0,0,0,0,50,4,53],[0,0,0,36,2,16,0,57,0,0,0,24,3,0,0,57,0,0,3,202,0,0,1,61,0,0,6,224,1,0,0,65],[0,0,0,0,0,16,4,53,0,0,0,50,1,0,0,57,0,0,3,213,0,0,1,61,0,0,0,68,2,16,0,57],[0,0,6,125,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,18,3,0,0,57],[0,0,3,202,0,0,1,61,0,0,6,87,1,0,0,65,0,0,0,0,0,16,4,57,0,0,0,3,1,0,0,41],[0,0,0,4,0,16,4,67,0,0,6,86,1,0,0,65,0,0,0,0,2,0,4,20,0,0,6,86,3,32,0,156],[0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,6,88,1,16,1,199,0,0,128,2,2,0,0,57],[25,83,25,78,0,0,4,15,0,0,0,1,2,32,1,144,0,0,10,8,0,0,97,61,0,0,0,0,1,1,4,59],[0,0,0,0,1,1,0,75,0,0,5,1,0,0,97,61,0,0,0,64,2,0,4,61,0,0,6,134,1,0,0,65],[0,9,0,0,0,2,0,29,0,0,0,0,0,18,4,53,0,0,0,0,1,0,4,20,0,0,0,3,2,0,0,41],[0,0,0,4,2,32,0,140,0,0,6,128,0,0,97,61,0,0,6,86,2,0,0,65,0,0,6,86,3,16,0,156],[0,0,0,0,1,2,128,25,0,0,0,9,4,0,0,41,0,0,6,86,3,64,0,156,0,0,0,0,2,4,64,25],[0,0,0,64,2,32,2,16,0,0,0,192,1,16,2,16,0,0,0,0,1,33,1,159,0,0,6,135,1,16,1,199],[0,0,0,3,2,0,0,41,25,83,25,73,0,0,4,15,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112],[0,1,6,86,0,48,1,157,0,3,0,0,0,1,3,85,0,0,0,1,1,32,1,144,0,0,6,150,0,0,97,61],[0,0,0,9,1,0,0,41,0,0,6,94,1,16,0,156,0,0,3,210,0,0,33,61,0,0,0,9,3,0,0,41],[0,0,0,64,0,48,4,63,0,0,0,68,1,48,0,57,0,0,6,176,2,0,0,65,0,0,0,0,0,33,4,53],[0,0,0,36,1,48,0,57,0,0,0,23,2,0,0,57,0,0,0,0,0,33,4,53,0,0,6,98,1,0,0,65],[0,0,0,0,0,19,4,53,0,0,0,4,1,48,0,57,0,0,0,4,2,0,0,41,0,0,0,0,0,33,4,53],[0,0,6,86,1,0,0,65,0,0,6,86,2,48,0,156,0,0,0,0,3,1,128,25,0,0,0,64,1,48,2,16],[0,0,6,126,1,16,1,199,0,0,25,85,0,1,4,48,0,0,0,11,1,0,0,41,0,0,0,0,1,1,4,26],[0,0,0,10,1,16,0,108,0,0,6,215,0,0,193,61,0,0,6,87,1,0,0,65,0,0,0,0,0,16,4,57],[0,0,0,3,1,0,0,41,0,0,0,4,0,16,4,67,0,0,6,86,1,0,0,65,0,0,0,0,2,0,4,20],[0,0,6,86,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,6,88,1,16,1,199],[0,0,128,2,2,0,0,57,25,83,25,78,0,0,4,15,0,0,0,1,2,32,1,144,0,0,10,8,0,0,97,61],[0,0,0,0,1,1,4,59,0,0,0,0,1,1,0,75,0,0,5,1,0,0,97,61,0,0,0,64,4,0,4,61],[0,0,6,137,1,0,0,65,0,0,0,0,0,20,4,53,0,0,6,86,1,0,0,65,0,0,0,0,2,0,4,20],[0,0,6,86,3,32,0,156,0,0,0,0,2,1,128,25,0,0,6,86,3,64,0,156,0,11,0,0,0,4,0,29],[0,0,0,0,1,4,64,25,0,10,0,64,0,16,2,24,0,0,0,192,1,32,2,16,0,0,0,10,1,16,1,175],[0,0,6,135,1,16,1,199,0,0,0,3,2,0,0,41,25,83,25,73,0,0,4,15,0,0,0,0,3,1,0,25],[0,0,0,96,3,48,2,112,0,1,6,86,0,48,1,157,0,3,0,0,0,1,3,85,0,0,0,1,1,32,1,144],[0,0,6,222,0,0,97,61,0,0,0,11,1,0,0,41,0,0,6,94,1,16,0,156,0,0,3,210,0,0,33,61],[0,0,0,11,3,0,0,41,0,0,0,64,0,48,4,63,0,0,0,100,1,48,0,57,0,0,6,174,2,0,0,65],[0,0,0,0,0,33,4,53,0,0,0,68,1,48,0,57,0,0,6,175,2,0,0,65,0,0,0,0,0,33,4,53],[0,0,0,36,1,48,0,57,0,0,0,38,2,0,0,57,0,0,0,0,0,33,4,53,0,0,6,98,1,0,0,65],[0,0,0,0,0,19,4,53,0,0,0,4,1,48,0,57,0,0,0,4,2,0,0,41,0,0,0,0,0,33,4,53],[0,0,0,10,1,0,0,41,0,0,6,171,1,16,1,199,0,0,25,85,0,1,4,48,0,0,0,64,1,0,4,61],[0,0,0,68,2,16,0,57,0,0,6,136,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57],[0,0,0,27,3,0,0,57,0,0,3,202,0,0,1,61,0,0,0,64,1,0,4,61,0,0,6,138,2,16,0,156],[0,0,3,210,0,0,33,61,0,0,0,96,2,16,0,57,0,0,0,64,0,32,4,63,0,0,6,139,2,0,0,65],[0,0,0,0,2,33,4,54,0,0,0,64,4,0,4,61,0,0,6,140,3,64,0,156,0,0,3,210,0,0,33,61],[0,0,0,128,3,64,0,57,0,0,0,64,0,48,4,63,0,0,0,96,3,64,0,57,0,0,6,141,5,0,0,65],[0,0,0,0,0,83,4,53,0,0,0,64,3,64,0,57,0,0,6,142,5,0,0,65,0,0,0,0,0,83,4,53],[0,0,0,32,3,64,0,57,0,0,6,143,5,0,0,65,0,0,0,0,0,83,4,53,0,0,0,65,3,0,0,57],[0,10,0,0,0,3,0,29,0,0,0,0,0,52,4,53,0,0,0,64,3,16,0,57,0,0,6,144,5,0,0,65],[0,0,0,0,0,83,4,53,0,0,0,0,0,66,4,53,0,0,0,64,4,0,4,61,0,11,0,0,0,4,0,29],[0,0,6,138,4,64,0,156,0,0,3,210,0,0,33,61,0,0,0,11,5,0,0,41,0,0,0,96,4,80,0,57],[0,0,0,64,0,64,4,63,0,0,6,145,4,0,0,65,0,0,0,0,4,69,4,54,0,9,0,0,0,4,0,29],[0,0,0,64,4,0,4,61,0,0,6,140,5,64,0,156,0,0,3,210,0,0,33,61,0,0,0,128,5,64,0,57],[0,0,0,64,0,80,4,63,0,0,0,96,5,64,0,57,0,0,6,141,6,0,0,65,0,0,0,0,0,101,4,53],[0,0,0,64,5,64,0,57,0,0,6,146,6,0,0,65,0,0,0,0,0,101,4,53,0,0,0,32,5,64,0,57],[0,0,6,147,6,0,0,65,0,0,0,0,0,101,4,53,0,0,0,10,5,0,0,41,0,0,0,0,0,84,4,53],[0,0,0,11,5,0,0,41,0,0,0,64,6,80,0,57,0,0,6,148,5,0,0,65,0,8,0,0,0,6,0,29],[0,0,0,0,0,86,4,53,0,0,0,9,5,0,0,41,0,0,0,0,0,69,4,53,0,0,0,0,2,2,4,51],[0,0,0,0,84,2,4,52,0,0,0,65,4,64,0,140,0,0,5,1,0,0,193,61,0,0,0,65,4,32,0,57],[0,0,0,0,4,4,4,51,0,0,0,255,4,64,1,143,0,0,0,27,6,64,0,138,0,0,0,1,6,96,0,140],[0,0,5,1,0,0,33,61,0,0,0,0,3,3,4,51,0,7,0,0,0,3,0,29,0,0,0,0,1,1,4,51],[0,0,0,0,3,5,4,51,0,0,0,64,2,32,0,57,0,0,0,0,2,2,4,51,0,0,0,64,5,0,4,61],[0,0,0,96,6,80,0,57,0,0,0,0,0,38,4,53,0,0,0,64,2,80,0,57,0,0,0,0,0,50,4,53],[0,0,0,32,2,80,0,57,0,0,0,0,0,66,4,53,0,0,0,0,0,21,4,53,0,0,0,0,0,0,4,53],[0,0,6,86,1,0,0,65,0,0,0,0,2,0,4,20,0,0,6,86,3,32,0,156,0,0,0,0,2,1,128,25],[0,0,6,86,3,80,0,156,0,0,0,0,5,1,128,25,0,0,0,64,1,80,2,16,0,0,0,192,2,32,2,16],[0,0,0,0,1,18,1,159,0,0,6,149,1,16,1,199,0,0,0,1,2,0,0,57,25,83,25,78,0,0,4,15],[0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,6,86,3,48,1,151,0,0,0,32,4,48,0,140],[0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57,0,0,0,31,5,64,1,143,0,0,0,5,4,64,2,114],[0,0,7,81,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,113,3,79],[0,0,0,0,8,8,4,59,0,0,0,0,0,135,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,70,0,75],[0,0,7,74,0,0,65,61,0,0,0,0,6,5,0,75,0,0,7,95,0,0,97,61,0,0,0,3,5,80,2,16],[0,0,0,5,4,64,2,16,0,0,0,0,6,4,4,51,0,0,0,0,6,86,1,207,0,0,0,0,6,86,2,47],[0,0,0,0,7,65,3,79,0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137,0,0,0,0,7,87,2,47],[0,0,0,0,5,87,1,207,0,0,0,0,5,101,1,159,0,0,0,0,0,84,4,53,0,1,0,0,0,3,0,31],[0,3,0,0,0,1,3,85,0,0,0,1,2,32,1,144,0,0,10,9,0,0,97,61,0,0,0,0,1,0,4,51],[0,0,0,7,1,16,1,79,0,0,6,97,1,16,1,152,0,0,5,1,0,0,193,61,0,0,0,9,1,0,0,41],[0,0,0,0,1,1,4,51,0,0,0,0,50,1,4,52,0,0,0,65,2,32,0,140,0,0,5,1,0,0,193,61],[0,0,0,65,2,16,0,57,0,0,0,0,2,2,4,51,0,0,0,255,2,32,1,143,0,0,0,27,4,32,0,138],[0,0,0,1,4,64,0,140,0,0,5,1,0,0,33,61,0,0,0,8,4,0,0,41,0,0,0,0,4,4,4,51],[0,9,0,0,0,4,0,29,0,0,0,11,4,0,0,41,0,0,0,0,4,4,4,51,0,0,0,0,3,3,4,51],[0,0,0,64,1,16,0,57,0,0,0,0,1,1,4,51,0,0,0,64,5,0,4,61,0,0,0,96,6,80,0,57],[0,0,0,0,0,22,4,53,0,0,0,64,1,80,0,57,0,0,0,0,0,49,4,53,0,0,0,32,1,80,0,57],[0,0,0,0,0,33,4,53,0,0,0,0,0,69,4,53,0,0,0,0,0,0,4,53,0,0,6,86,1,0,0,65],[0,0,0,0,2,0,4,20,0,0,6,86,3,32,0,156,0,0,0,0,2,1,128,25,0,0,6,86,3,80,0,156],[0,0,0,0,5,1,128,25,0,0,0,64,1,80,2,16,0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159],[0,0,6,149,1,16,1,199,0,0,0,1,2,0,0,57,25,83,25,78,0,0,4,15,0,0,0,0,3,1,0,25],[0,0,0,96,3,48,2,112,0,0,6,86,3,48,1,151,0,0,0,32,4,48,0,140,0,0,0,0,4,3,0,25],[0,0,0,32,4,0,128,57,0,0,0,31,5,64,1,143,0,0,0,5,4,64,2,114,0,0,7,160,0,0,97,61],[0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,113,3,79,0,0,0,0,8,8,4,59],[0,0,0,0,0,135,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,70,0,75,0,0,7,153,0,0,65,61],[0,0,0,0,6,5,0,75,0,0,7,174,0,0,97,61,0,0,0,3,5,80,2,16,0,0,0,5,4,64,2,16],[0,0,0,0,6,4,4,51,0,0,0,0,6,86,1,207,0,0,0,0,6,86,2,47,0,0,0,0,7,65,3,79],[0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137,0,0,0,0,7,87,2,47,0,0,0,0,5,87,1,207],[0,0,0,0,5,101,1,159,0,0,0,0,0,84,4,53,0,1,0,0,0,3,0,31,0,3,0,0,0,1,3,85],[0,0,0,1,2,32,1,144,0,0,10,38,0,0,97,61,0,0,0,0,1,0,4,51,0,0,0,9,1,16,1,79],[0,0,6,97,1,16,1,152,0,0,5,1,0,0,193,61,0,0,0,64,1,0,4,61,0,0,6,138,2,16,0,156],[0,0,3,210,0,0,33,61,0,0,0,96,2,16,0,57,0,0,0,64,0,32,4,63,0,0,0,0,5,1,4,54],[0,0,0,64,2,0,4,61,0,0,6,140,3,32,0,156,0,0,3,210,0,0,33,61,0,0,0,128,3,32,0,57],[0,0,0,64,0,48,4,63,0,0,0,96,3,32,0,57,0,0,6,141,4,0,0,65,0,0,0,0,0,67,4,53],[0,0,0,64,3,32,0,57,0,0,6,150,4,0,0,65,0,0,0,0,0,67,4,53,0,0,0,32,4,32,0,57],[0,0,6,151,6,0,0,65,0,0,0,0,0,100,4,53,0,0,0,10,6,0,0,41,0,0,0,0,0,98,4,53],[0,0,0,64,6,16,0,57,0,0,6,152,7,0,0,65,0,0,0,0,0,118,4,53,0,0,0,0,0,37,4,53],[0,0,0,0,5,2,4,51,0,0,0,65,5,80,0,140,0,0,5,1,0,0,193,61,0,0,0,65,2,32,0,57],[0,0,0,0,2,2,4,51,0,0,0,255,2,32,1,143,0,0,0,27,5,32,0,138,0,0,0,1,5,80,0,140],[0,0,5,1,0,0,33,61,0,0,0,0,1,1,4,51,0,0,0,0,4,4,4,51,0,0,0,0,3,3,4,51],[0,0,0,64,5,0,4,61,0,0,0,96,6,80,0,57,0,0,0,0,0,54,4,53,0,0,0,64,3,80,0,57],[0,0,0,0,0,67,4,53,0,0,0,32,3,80,0,57,0,0,0,0,0,35,4,53,0,0,0,0,0,21,4,53],[0,0,0,0,0,0,4,53,0,0,6,86,1,0,0,65,0,0,0,0,2,0,4,20,0,0,6,86,3,32,0,156],[0,0,0,0,2,1,128,25,0,0,6,86,3,80,0,156,0,0,0,0,5,1,128,25,0,0,0,64,1,80,2,16],[0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159,0,0,6,149,1,16,1,199,0,0,0,1,2,0,0,57],[25,83,25,78,0,0,4,15,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,6,86,3,48,1,151],[0,0,0,32,4,48,0,140,0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57,0,0,0,31,5,64,1,143],[0,0,0,5,4,64,2,114,0,0,8,2,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16],[0,0,0,0,8,113,3,79,0,0,0,0,8,8,4,59,0,0,0,0,0,135,4,53,0,0,0,1,6,96,0,57],[0,0,0,0,7,70,0,75,0,0,7,251,0,0,65,61,0,0,0,0,6,5,0,75,0,0,8,16,0,0,97,61],[0,0,0,3,5,80,2,16,0,0,0,5,4,64,2,16,0,0,0,0,6,4,4,51,0,0,0,0,6,86,1,207],[0,0,0,0,6,86,2,47,0,0,0,0,7,65,3,79,0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137],[0,0,0,0,7,87,2,47,0,0,0,0,5,87,1,207,0,0,0,0,5,101,1,159,0,0,0,0,0,84,4,53],[0,1,0,0,0,3,0,31,0,3,0,0,0,1,3,85,0,0,0,1,2,32,1,144,0,0,10,67,0,0,97,61],[0,0,0,0,1,0,4,51,0,0,6,97,1,16,1,151,0,0,6,152,1,16,0,156,0,0,5,1,0,0,193,61],[0,0,0,64,1,0,4,61,0,0,6,138,2,16,0,156,0,0,3,210,0,0,33,61,0,0,0,96,2,16,0,57],[0,0,0,64,0,32,4,63,0,0,6,153,2,0,0,65,0,0,0,0,5,33,4,54,0,0,0,64,2,0,4,61],[0,0,6,140,3,32,0,156,0,0,3,210,0,0,33,61,0,0,0,128,3,32,0,57,0,0,0,64,0,48,4,63],[0,0,0,96,3,32,0,57,0,0,6,154,4,0,0,65,0,0,0,0,0,67,4,53,0,0,0,64,3,32,0,57],[0,0,6,155,4,0,0,65,0,0,0,0,0,67,4,53,0,0,0,32,4,32,0,57,0,0,6,156,6,0,0,65],[0,0,0,0,0,100,4,53,0,0,0,10,6,0,0,41,0,0,0,0,0,98,4,53,0,0,0,0,0,37,4,53],[0,0,0,64,5,16,0,57,0,0,0,0,0,5,4,53,0,0,0,0,5,2,4,51,0,0,0,65,5,80,0,140],[0,0,5,1,0,0,193,61,0,0,0,65,2,32,0,57,0,0,0,0,2,2,4,51,0,0,0,255,2,32,1,143],[0,0,0,27,5,32,0,138,0,0,0,1,5,80,0,140,0,0,5,1,0,0,33,61,0,0,0,0,1,1,4,51],[0,0,0,0,4,4,4,51,0,0,0,0,3,3,4,51,0,0,0,64,5,0,4,61,0,0,0,96,6,80,0,57],[0,0,0,0,0,54,4,53,0,0,0,64,3,80,0,57,0,0,0,0,0,67,4,53,0,0,0,32,3,80,0,57],[0,0,0,0,0,35,4,53,0,0,0,0,0,21,4,53,0,0,0,0,0,0,4,53,0,0,6,86,1,0,0,65],[0,0,0,0,2,0,4,20,0,0,6,86,3,32,0,156,0,0,0,0,2,1,128,25,0,0,6,86,3,80,0,156],[0,0,0,0,5,1,128,25,0,0,0,64,1,80,2,16,0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159],[0,0,6,149,1,16,1,199,0,0,0,1,2,0,0,57,25,83,25,78,0,0,4,15,0,0,0,0,3,1,0,25],[0,0,0,96,3,48,2,112,0,0,6,86,3,48,1,151,0,0,0,32,4,48,0,140,0,0,0,0,4,3,0,25],[0,0,0,32,4,0,128,57,0,0,0,31,5,64,1,143,0,0,0,5,4,64,2,114,0,0,8,100,0,0,97,61],[0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,113,3,79,0,0,0,0,8,8,4,59],[0,0,0,0,0,135,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,70,0,75,0,0,8,93,0,0,65,61],[0,0,0,0,6,5,0,75,0,0,8,114,0,0,97,61,0,0,0,3,5,80,2,16,0,0,0,5,4,64,2,16],[0,0,0,0,6,4,4,51,0,0,0,0,6,86,1,207,0,0,0,0,6,86,2,47,0,0,0,0,7,65,3,79],[0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137,0,0,0,0,7,87,2,47,0,0,0,0,5,87,1,207],[0,0,0,0,5,101,1,159,0,0,0,0,0,84,4,53,0,1,0,0,0,3,0,31,0,3,0,0,0,1,3,85],[0,0,0,1,2,32,1,144,0,0,10,96,0,0,97,61,0,0,0,0,1,0,4,51,0,0,6,97,1,16,1,152],[0,0,5,1,0,0,193,61,0,0,0,64,1,0,4,61,0,0,6,138,2,16,0,156,0,0,3,210,0,0,33,61],[0,0,0,96,2,16,0,57,0,0,0,64,0,32,4,63,0,0,6,157,2,0,0,65,0,0,0,0,5,33,4,54],[0,0,0,64,2,0,4,61,0,0,6,140,3,32,0,156,0,0,3,210,0,0,33,61,0,0,0,128,3,32,0,57],[0,0,0,64,0,48,4,63,0,0,0,96,3,32,0,57,0,0,6,141,4,0,0,65,0,0,0,0,0,67,4,53],[0,0,0,64,3,32,0,57,0,0,6,158,4,0,0,65,0,0,0,0,0,67,4,53,0,0,0,32,4,32,0,57],[0,0,6,159,6,0,0,65,0,0,0,0,0,100,4,53,0,0,0,10,6,0,0,41,0,0,0,0,0,98,4,53],[0,0,0,64,6,16,0,57,0,0,6,160,7,0,0,65,0,0,0,0,0,118,4,53,0,0,0,0,0,37,4,53],[0,0,0,0,5,2,4,51,0,0,0,65,5,80,0,140,0,0,5,1,0,0,193,61,0,0,0,65,2,32,0,57],[0,0,0,0,2,2,4,51,0,0,0,255,2,32,1,143,0,0,0,27,5,32,0,138,0,0,0,1,5,80,0,140],[0,0,5,1,0,0,33,61,0,0,0,0,1,1,4,51,0,0,0,0,4,4,4,51,0,0,0,0,3,3,4,51],[0,0,0,64,5,0,4,61,0,0,0,96,6,80,0,57,0,0,0,0,0,54,4,53,0,0,0,64,3,80,0,57],[0,0,0,0,0,67,4,53,0,0,0,32,3,80,0,57,0,0,0,0,0,35,4,53,0,0,0,0,0,21,4,53],[0,0,0,0,0,0,4,53,0,0,6,86,1,0,0,65,0,0,0,0,2,0,4,20,0,0,6,86,3,32,0,156],[0,0,0,0,2,1,128,25,0,0,6,86,3,80,0,156,0,0,0,0,5,1,128,25,0,0,0,64,1,80,2,16],[0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159,0,0,6,149,1,16,1,199,0,0,0,1,2,0,0,57],[25,83,25,78,0,0,4,15,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,6,86,3,48,1,151],[0,0,0,32,4,48,0,140,0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57,0,0,0,31,5,64,1,143],[0,0,0,5,4,64,2,114,0,0,8,198,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16],[0,0,0,0,8,113,3,79,0,0,0,0,8,8,4,59,0,0,0,0,0,135,4,53,0,0,0,1,6,96,0,57],[0,0,0,0,7,70,0,75,0,0,8,191,0,0,65,61,0,0,0,0,6,5,0,75,0,0,8,212,0,0,97,61],[0,0,0,3,5,80,2,16,0,0,0,5,4,64,2,16,0,0,0,0,6,4,4,51,0,0,0,0,6,86,1,207],[0,0,0,0,6,86,2,47,0,0,0,0,7,65,3,79,0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137],[0,0,0,0,7,87,2,47,0,0,0,0,5,87,1,207,0,0,0,0,5,101,1,159,0,0,0,0,0,84,4,53],[0,1,0,0,0,3,0,31,0,3,0,0,0,1,3,85,0,0,0,1,2,32,1,144,0,0,10,125,0,0,97,61],[0,0,0,0,1,0,4,51,0,0,6,97,1,16,1,151,0,0,6,160,1,16,0,156,0,0,5,1,0,0,193,61],[25,83,11,89,0,0,4,15,0,0,6,87,1,0,0,65,0,0,0,0,0,16,4,57,0,0,0,3,1,0,0,41],[0,0,0,4,0,16,4,67,0,0,6,86,1,0,0,65,0,0,0,0,2,0,4,20,0,0,6,86,3,32,0,156],[0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,6,88,1,16,1,199,0,0,128,2,2,0,0,57],[25,83,25,78,0,0,4,15,0,0,0,1,2,32,1,144,0,0,10,8,0,0,97,61,0,0,0,0,1,1,4,59],[0,0,0,0,1,1,0,75,0,0,5,1,0,0,97,61,0,0,0,64,4,0,4,61,0,0,6,161,1,0,0,65],[0,0,0,0,0,20,4,53,0,0,6,86,1,0,0,65,0,0,0,0,2,0,4,20,0,0,6,86,3,32,0,156],[0,0,0,0,2,1,128,25,0,0,6,86,3,64,0,156,0,11,0,0,0,4,0,29,0,0,0,0,1,4,64,25],[0,0,0,64,1,16,2,16,0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159,0,0,6,135,1,16,1,199],[0,0,0,3,2,0,0,41,25,83,25,73,0,0,4,15,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112],[0,1,6,86,0,48,1,157,0,0,6,86,3,48,1,151,0,3,0,0,0,1,3,85,0,0,0,1,2,32,1,144],[0,0,10,154,0,0,97,61,0,0,0,11,1,0,0,41,0,0,6,94,1,16,0,156,0,0,3,210,0,0,33,61],[0,0,0,11,1,0,0,41,0,0,0,64,0,16,4,63,0,0,6,87,1,0,0,65,0,0,0,0,0,16,4,57],[0,0,0,3,1,0,0,41,0,0,0,4,0,16,4,67,0,0,6,86,1,0,0,65,0,0,0,0,2,0,4,20],[0,0,6,86,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,6,88,1,16,1,199],[0,0,128,2,2,0,0,57,25,83,25,78,0,0,4,15,0,0,0,1,2,32,1,144,0,0,10,8,0,0,97,61],[0,0,0,0,1,1,4,59,0,0,0,0,1,1,0,75,0,0,5,1,0,0,97,61,0,0,0,64,4,0,4,61],[0,0,6,162,1,0,0,65,0,0,0,0,0,20,4,53,0,0,6,86,1,0,0,65,0,0,0,0,2,0,4,20],[0,0,6,86,3,32,0,156,0,0,0,0,2,1,128,25,0,0,6,86,3,64,0,156,0,11,0,0,0,4,0,29],[0,0,0,0,1,4,64,25,0,0,0,64,1,16,2,16,0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159],[0,0,6,135,1,16,1,199,0,0,0,3,2,0,0,41,25,83,25,73,0,0,4,15,0,0,0,0,3,1,0,25],[0,0,0,96,3,48,2,112,0,1,6,86,0,48,1,157,0,0,6,86,3,48,1,151,0,3,0,0,0,1,3,85],[0,0,0,1,2,32,1,144,0,0,10,183,0,0,97,61,0,0,0,11,1,0,0,41,0,0,6,94,1,16,0,156],[0,0,3,210,0,0,33,61,0,0,0,11,1,0,0,41,0,0,0,64,0,16,4,63,25,83,14,25,0,0,4,15],[0,0,0,7,2,0,0,57,0,0,6,163,1,0,0,65,0,11,0,0,0,2,0,29,25,83,25,78,0,0,4,15],[0,3,0,0,0,1,3,85,0,0,0,0,2,1,0,25,0,0,0,96,2,32,2,112,0,1,6,86,0,32,1,157],[0,0,6,86,4,32,1,152,0,0,9,106,0,0,97,61,0,0,0,63,2,64,0,57,0,0,6,164,2,32,1,151],[0,0,0,64,3,0,4,61,0,0,0,0,2,35,0,25,0,0,0,0,5,50,0,75,0,0,0,0,5,0,0,25],[0,0,0,1,5,0,64,57,0,0,6,94,6,32,0,156,0,0,3,210,0,0,33,61,0,0,0,1,5,80,1,144],[0,0,3,210,0,0,193,61,0,0,0,64,0,32,4,63,0,0,0,31,2,64,1,143,0,0,0,0,3,67,4,54],[0,0,0,5,4,64,2,114,0,0,9,91,0,0,97,61,0,0,0,0,5,0,0,25,0,0,0,5,6,80,2,16],[0,0,0,0,7,99,0,25,0,0,0,0,6,97,3,79,0,0,0,0,6,6,4,59,0,0,0,0,0,103,4,53],[0,0,0,1,5,80,0,57,0,0,0,0,6,69,0,75,0,0,9,83,0,0,65,61,0,0,0,0,5,2,0,75],[0,0,9,106,0,0,97,61,0,0,0,5,4,64,2,16,0,0,0,0,1,65,3,79,0,0,0,0,3,67,0,25],[0,0,0,3,2,32,2,16,0,0,0,0,4,3,4,51,0,0,0,0,4,36,1,207,0,0,0,0,4,36,2,47],[0,0,0,0,1,1,4,59,0,0,1,0,2,32,0,137,0,0,0,0,1,33,2,47,0,0,0,0,1,33,1,207],[0,0,0,0,1,65,1,159,0,0,0,0,0,19,4,53,0,0,0,64,4,0,4,61,0,0,6,165,1,0,0,65],[0,0,0,0,0,20,4,53,0,0,0,4,1,64,0,57,0,0,0,11,2,0,0,41,0,0,0,0,0,33,4,53],[0,0,6,86,1,0,0,65,0,0,0,0,2,0,4,20,0,0,6,86,3,32,0,156,0,0,0,0,2,1,128,25],[0,0,6,86,3,64,0,156,0,11,0,0,0,4,0,29,0,0,0,0,1,4,64,25,0,0,0,64,1,16,2,16],[0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159,0,0,6,166,1,16,1,199,0,0,128,2,2,0,0,57],[25,83,25,78,0,0,4,15,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,6,86,3,48,1,151],[0,0,0,32,4,48,0,140,0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57,0,0,0,31,5,64,1,143],[0,0,0,5,6,64,2,114,0,0,9,143,0,0,97,61,0,0,0,0,7,0,0,25,0,0,0,5,8,112,2,16],[0,0,0,11,9,128,0,41,0,0,0,0,8,129,3,79,0,0,0,0,8,8,4,59,0,0,0,0,0,137,4,53],[0,0,0,1,7,112,0,57,0,0,0,0,8,103,0,75,0,0,9,135,0,0,65,61,0,0,0,0,7,5,0,75],[0,0,9,158,0,0,97,61,0,0,0,5,6,96,2,16,0,0,0,0,7,97,3,79,0,0,0,11,6,96,0,41],[0,0,0,3,5,80,2,16,0,0,0,0,8,6,4,51,0,0,0,0,8,88,1,207,0,0,0,0,8,88,2,47],[0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137,0,0,0,0,7,87,2,47,0,0,0,0,5,87,1,207],[0,0,0,0,5,133,1,159,0,0,0,0,0,86,4,53,0,1,0,0,0,3,0,31,0,3,0,0,0,1,3,85],[0,0,0,1,2,32,1,144,0,0,10,212,0,0,97,61,0,0,0,31,1,64,0,57,0,0,0,96,2,16,1,143],[0,0,0,11,1,32,0,41,0,0,0,0,2,33,0,75,0,0,0,0,2,0,0,25,0,0,0,1,2,0,64,57],[0,0,6,94,4,16,0,156,0,0,3,210,0,0,33,61,0,0,0,1,2,32,1,144,0,0,3,210,0,0,193,61],[0,0,0,64,0,16,4,63,0,0,0,32,2,48,0,140,0,0,5,1,0,0,65,61,0,0,0,11,2,0,0,41],[0,0,0,0,3,2,4,51,0,0,0,4,2,0,0,41,0,0,0,0,2,33,4,54,0,9,0,0,0,3,0,29],[0,0,0,0,0,50,4,53,0,0,6,167,3,16,0,156,0,0,3,210,0,0,33,61,0,0,0,64,3,16,0,57],[0,0,0,64,0,48,4,63,0,0,6,86,3,0,0,65,0,0,6,86,4,32,0,156,0,0,0,0,2,3,128,25],[0,0,0,64,2,32,2,16,0,0,0,0,4,0,4,20,0,11,0,0,0,4,0,29,0,0,0,0,1,1,4,51],[0,0,6,86,4,16,0,156,0,0,0,0,1,3,128,25,0,0,0,96,1,16,2,16,0,0,0,0,1,33,1,159],[0,0,0,0,2,0,4,20,0,0,6,86,4,32,0,156,0,0,0,0,2,3,128,25,0,0,0,192,2,32,2,16],[0,0,0,0,1,33,1,159,0,0,128,18,2,0,0,57,25,83,25,78,0,0,4,15,0,0,0,0,3,1,0,25],[0,0,0,96,3,48,2,112,0,1,6,86,0,48,1,157,0,3,0,0,0,1,3,85,0,0,0,0,1,0,4,20],[0,10,0,0,0,1,0,29,0,0,0,11,1,16,0,107,0,0,0,116,0,0,65,61,0,0,0,1,1,32,1,144],[0,0,10,241,0,0,97,61,0,0,0,64,1,0,4,61,0,0,0,4,2,0,0,41,0,0,0,0,2,33,4,54],[0,0,0,9,3,0,0,41,0,0,0,0,0,50,4,53,0,0,6,167,3,16,0,156,0,0,3,210,0,0,33,61],[0,0,0,64,3,16,0,57,0,0,0,64,0,48,4,63,0,0,6,86,3,0,0,65,0,0,6,86,4,32,0,156],[0,0,0,0,2,3,128,25,0,0,0,64,2,32,2,16,0,0,0,0,4,0,4,20,0,9,0,0,0,4,0,29],[0,0,0,0,1,1,4,51,0,0,6,86,4,16,0,156,0,0,0,0,1,3,128,25,0,0,0,96,1,16,2,16],[0,0,0,0,1,33,1,159,0,0,0,0,2,0,4,20,0,0,6,86,4,32,0,156,0,0,0,0,2,3,128,25],[0,0,0,192,2,32,2,16,0,0,0,0,1,33,1,159,0,0,128,18,2,0,0,57,25,83,25,78,0,0,4,15],[0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,1,6,86,0,48,1,157,0,3,0,0,0,1,3,85],[0,0,0,0,1,0,4,20,0,0,0,9,4,0,0,41,0,0,0,9,3,16,0,107,0,0,0,116,0,0,65,61],[0,0,0,1,2,32,1,144,0,0,10,241,0,0,97,61,0,0,0,10,3,0,0,41,0,0,0,11,2,48,0,105],[0,0,0,0,1,20,0,73,0,0,0,0,1,18,0,75,0,0,10,248,0,0,193,61,0,0,6,86,1,0,0,65],[0,0,0,0,2,0,4,20,0,0,6,86,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16],[0,0,0,1,2,0,0,107,0,0,11,13,0,0,193,61,0,0,6,172,2,0,0,65,0,0,11,18,0,0,1,61],[0,0,0,0,0,1,4,47,0,0,0,64,2,0,4,61,0,0,0,31,4,48,1,143,0,0,0,5,5,48,2,114],[0,0,10,22,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25],[0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57],[0,0,0,0,7,86,0,75,0,0,10,14,0,0,65,61,0,0,0,0,6,4,0,75,0,0,10,37,0,0,97,61],[0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16],[0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59],[0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159],[0,0,0,0,0,21,4,53,0,0,4,152,0,0,1,61,0,0,0,64,2,0,4,61,0,0,0,31,4,48,1,143],[0,0,0,5,5,48,2,114,0,0,10,51,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16],[0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53],[0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,10,43,0,0,65,61,0,0,0,0,6,4,0,75],[0,0,10,66,0,0,97,61,0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25],[0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47],[0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207],[0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,4,152,0,0,1,61,0,0,0,64,2,0,4,61],[0,0,0,31,4,48,1,143,0,0,0,5,5,48,2,114,0,0,10,80,0,0,97,61,0,0,0,0,6,0,0,25],[0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59],[0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,10,72,0,0,65,61],[0,0,0,0,6,4,0,75,0,0,10,95,0,0,97,61,0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79],[0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207],[0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47],[0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,4,152,0,0,1,61],[0,0,0,64,2,0,4,61,0,0,0,31,4,48,1,143,0,0,0,5,5,48,2,114,0,0,10,109,0,0,97,61],[0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79],[0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75],[0,0,10,101,0,0,65,61,0,0,0,0,6,4,0,75,0,0,10,124,0,0,97,61,0,0,0,5,5,80,2,16],[0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51],[0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137],[0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53],[0,0,4,152,0,0,1,61,0,0,0,64,2,0,4,61,0,0,0,31,4,48,1,143,0,0,0,5,5,48,2,114],[0,0,10,138,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25],[0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57],[0,0,0,0,7,86,0,75,0,0,10,130,0,0,65,61,0,0,0,0,6,4,0,75,0,0,10,153,0,0,97,61],[0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16],[0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59],[0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159],[0,0,0,0,0,21,4,53,0,0,4,152,0,0,1,61,0,0,0,64,2,0,4,61,0,0,0,31,4,48,1,143],[0,0,0,5,5,48,2,114,0,0,10,167,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16],[0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53],[0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,10,159,0,0,65,61,0,0,0,0,6,4,0,75],[0,0,10,182,0,0,97,61,0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25],[0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47],[0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207],[0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,4,152,0,0,1,61,0,0,0,64,2,0,4,61],[0,0,0,31,4,48,1,143,0,0,0,5,5,48,2,114,0,0,10,196,0,0,97,61,0,0,0,0,6,0,0,25],[0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59],[0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,10,188,0,0,65,61],[0,0,0,0,6,4,0,75,0,0,10,211,0,0,97,61,0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79],[0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207],[0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47],[0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,4,152,0,0,1,61],[0,0,0,64,2,0,4,61,0,0,0,31,4,48,1,143,0,0,0,5,5,48,2,114,0,0,10,225,0,0,97,61],[0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79],[0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75],[0,0,10,217,0,0,65,61,0,0,0,0,6,4,0,75,0,0,10,240,0,0,97,61,0,0,0,5,5,80,2,16],[0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51],[0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137],[0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53],[0,0,4,152,0,0,1,61,0,0,0,64,1,0,4,61,0,0,0,68,2,16,0,57,0,0,6,168,3,0,0,65],[0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,22,3,0,0,57,0,0,3,202,0,0,1,61],[0,0,0,64,1,0,4,61,0,0,0,100,2,16,0,57,0,0,6,169,3,0,0,65,0,0,0,0,0,50,4,53],[0,0,0,68,2,16,0,57,0,0,6,170,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57],[0,0,0,33,3,0,0,57,0,0,0,0,0,50,4,53,0,0,6,98,2,0,0,65,0,0,0,0,0,33,4,53],[0,0,0,4,2,16,0,57,0,0,0,4,3,0,0,41,0,0,0,0,0,50,4,53,0,0,6,86,2,0,0,65],[0,0,6,86,3,16,0,156,0,0,0,0,1,2,128,25,0,0,0,64,1,16,2,16,0,0,6,171,1,16,1,199],[0,0,25,85,0,1,4,48,0,0,6,117,1,16,1,199,0,0,128,9,2,0,0,57,0,0,0,1,3,0,0,41],[0,0,6,172,4,0,0,65,0,0,0,0,5,0,0,25,25,83,25,73,0,0,4,15,0,3,0,0,0,1,3,85],[0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,1,6,86,0,48,1,157,0,0,6,86,5,48,1,152],[0,0,11,65,0,0,97,61,0,0,0,63,3,80,0,57,0,0,6,164,3,48,1,151,0,0,0,64,4,0,4,61],[0,0,0,0,3,52,0,25,0,0,0,0,6,67,0,75,0,0,0,0,6,0,0,25,0,0,0,1,6,0,64,57],[0,0,6,94,7,48,0,156,0,0,3,210,0,0,33,61,0,0,0,1,6,96,1,144,0,0,3,210,0,0,193,61],[0,0,0,64,0,48,4,63,0,0,0,31,3,80,1,143,0,0,0,0,4,84,4,54,0,0,0,5,5,80,2,114],[0,0,11,50,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,116,0,25],[0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57],[0,0,0,0,7,86,0,75,0,0,11,42,0,0,65,61,0,0,0,0,6,3,0,75,0,0,11,65,0,0,97,61],[0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,4,84,0,25,0,0,0,3,3,48,2,16],[0,0,0,0,5,4,4,51,0,0,0,0,5,53,1,207,0,0,0,0,5,53,2,47,0,0,0,0,1,1,4,59],[0,0,1,0,3,48,0,137,0,0,0,0,1,49,2,47,0,0,0,0,1,49,1,207,0,0,0,0,1,81,1,159],[0,0,0,0,0,20,4,53,0,0,0,1,1,32,1,144,0,0,11,71,0,0,97,61,0,0,6,96,1,0,0,65],[0,0,0,0,0,1,4,27,0,0,0,0,1,0,0,25,0,0,25,84,0,1,4,46,0,0,0,64,1,0,4,61],[0,0,0,68,2,16,0,57,0,0,6,173,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57],[0,0,0,20,3,0,0,57,0,0,3,202,0,0,1,61,0,0,6,229,2,16,0,156,0,0,11,83,0,0,129,61],[0,0,0,96,1,16,0,57,0,0,0,64,0,16,4,63,0,0,0,0,0,1,4,45,0,0,6,224,1,0,0,65],[0,0,0,0,0,16,4,53,0,0,0,65,1,0,0,57,0,0,0,4,0,16,4,63,0,0,6,166,1,0,0,65],[0,0,25,85,0,1,4,48,0,8,0,0,0,0,0,2,0,0,0,64,1,0,4,61,0,8,0,0,0,1,0,29],[0,0,6,230,1,16,0,156,0,0,13,227,0,0,129,61,0,0,0,8,6,0,0,41,0,0,0,192,1,96,0,57],[0,0,0,64,0,16,4,63,0,0,0,5,1,0,0,57,0,0,0,0,3,22,4,54,0,0,0,0,1,0,0,49],[0,0,0,2,1,16,3,103,0,0,0,0,2,0,0,25,0,7,0,0,0,3,0,29,0,0,0,5,4,32,2,16],[0,0,0,0,4,65,3,79,0,0,0,0,4,4,4,59,0,0,0,0,3,67,4,54,0,0,0,1,2,32,0,57],[0,0,0,5,4,32,0,140,0,0,11,103,0,0,65,61,0,0,0,0,1,6,4,51,0,0,0,0,1,1,0,75],[0,0,13,223,0,0,97,61,0,0,6,231,1,0,0,65,0,0,0,7,2,0,0,41,0,0,0,0,0,18,4,53],[0,0,0,0,1,6,4,51,0,0,0,2,1,16,0,140,0,0,13,223,0,0,65,61,0,0,0,64,1,96,0,57],[0,0,6,232,2,0,0,65,0,0,0,0,0,33,4,53,0,0,0,0,1,6,4,51,0,0,0,3,1,16,0,140],[0,0,13,223,0,0,65,61,0,0,0,96,2,96,0,57,0,0,6,233,1,0,0,65,0,1,0,0,0,2,0,29],[0,0,0,0,0,18,4,53,0,0,0,0,1,6,4,51,0,0,0,4,1,16,0,140,0,0,13,223,0,0,65,61],[0,0,0,128,1,96,0,57,0,0,6,234,2,0,0,65,0,0,0,0,0,33,4,53,0,0,0,0,1,6,4,51],[0,0,0,5,1,16,0,140,0,0,13,223,0,0,65,61,0,0,0,160,1,96,0,57,0,0,6,235,2,0,0,65],[0,0,0,0,0,33,4,53,0,0,0,64,1,0,4,61,0,0,0,32,2,16,0,57,0,0,0,0,3,6,4,51],[0,0,0,0,4,3,0,75,0,0,0,0,4,2,0,25,0,0,11,155,0,0,97,61,0,0,0,0,5,0,0,25],[0,0,0,0,4,2,0,25,0,0,0,32,6,96,0,57,0,0,0,0,7,6,4,51,0,0,0,0,4,116,4,54],[0,0,0,1,5,80,0,57,0,0,0,0,7,53,0,75,0,0,11,149,0,0,65,61,0,0,0,0,3,20,0,73],[0,0,0,32,4,48,0,138,0,0,0,0,0,65,4,53,0,0,0,31,3,48,0,57,0,6,0,32,0,0,0,146],[0,0,0,6,4,48,1,127,0,0,0,0,3,20,0,25,0,0,0,0,4,67,0,75,0,0,0,0,4,0,0,25],[0,0,0,1,4,0,64,57,0,0,6,94,5,48,0,156,0,0,13,227,0,0,33,61,0,0,0,1,4,64,1,144],[0,0,13,227,0,0,193,61,0,0,0,64,0,48,4,63,0,0,6,86,3,0,0,65,0,0,6,86,4,32,0,156],[0,0,0,0,2,3,128,25,0,0,0,64,2,32,2,16,0,0,0,0,1,1,4,51,0,0,6,86,4,16,0,156],[0,0,0,0,1,3,128,25,0,0,0,96,1,16,2,16,0,0,0,0,1,33,1,159,0,0,0,0,2,0,4,20],[0,0,6,86,4,32,0,156,0,0,0,0,2,3,128,25,0,0,0,192,2,32,2,16,0,0,0,0,1,33,1,159],[0,0,1,0,2,0,0,57,25,83,25,78,0,0,4,15,0,0,0,96,4,0,0,57,0,0,0,128,3,0,0,57],[0,3,0,0,0,1,3,85,0,0,0,0,5,1,0,25,0,0,0,96,5,80,2,112,0,1,6,86,0,80,1,157],[0,0,6,86,6,80,1,152,0,0,11,234,0,0,97,61,0,0,0,63,3,96,0,57,0,0,6,164,3,48,1,151],[0,0,0,64,4,0,4,61,0,0,0,0,3,52,0,25,0,0,0,0,5,67,0,75,0,0,0,0,5,0,0,25],[0,0,0,1,5,0,64,57,0,0,6,94,7,48,0,156,0,0,13,227,0,0,33,61,0,0,0,1,5,80,1,144],[0,0,13,227,0,0,193,61,0,0,0,64,0,48,4,63,0,0,0,31,5,96,1,143,0,0,0,0,3,100,4,54],[0,0,0,5,6,96,2,114,0,0,11,219,0,0,97,61,0,0,0,0,7,0,0,25,0,0,0,5,8,112,2,16],[0,0,0,0,9,131,0,25,0,0,0,0,8,129,3,79,0,0,0,0,8,8,4,59,0,0,0,0,0,137,4,53],[0,0,0,1,7,112,0,57,0,0,0,0,8,103,0,75,0,0,11,211,0,0,65,61,0,0,0,0,7,5,0,75],[0,0,11,234,0,0,97,61,0,0,0,5,6,96,2,16,0,0,0,0,1,97,3,79,0,0,0,0,6,99,0,25],[0,0,0,3,5,80,2,16,0,0,0,0,7,6,4,51,0,0,0,0,7,87,1,207,0,0,0,0,7,87,2,47],[0,0,0,0,1,1,4,59,0,0,1,0,5,80,0,137,0,0,0,0,1,81,2,47,0,0,0,0,1,81,1,207],[0,0,0,0,1,113,1,159,0,0,0,0,0,22,4,53,0,0,0,1,1,32,1,144,0,0,13,233,0,0,97,61],[0,0,0,0,1,4,4,51,0,0,6,124,2,0,0,65,0,0,0,31,4,16,0,140,0,0,0,0,4,0,0,25],[0,0,0,0,4,2,32,25,0,0,6,124,1,16,1,151,0,0,0,0,5,1,0,75,0,0,0,0,2,0,128,25],[0,0,6,124,1,16,0,156,0,0,0,0,2,4,192,25,0,0,0,0,1,2,0,75,0,0,0,8,7,0,0,41],[0,0,14,16,0,0,97,61,0,0,0,0,1,3,4,51,0,0,0,0,2,1,0,75,0,0,0,0,2,0,0,25],[0,0,0,1,2,0,192,57,0,0,0,0,2,33,0,75,0,0,14,16,0,0,193,61,0,0,0,0,1,1,0,75],[0,0,14,18,0,0,97,61,0,0,0,0,2,0,0,25,0,0,0,0,1,7,4,51,0,0,0,0,1,33,0,75],[0,0,13,223,0,0,161,61,0,5,0,0,0,2,0,29,0,0,0,5,1,32,2,16,0,0,0,7,1,16,0,41],[0,0,0,0,2,1,4,51,0,3,0,0,0,2,0,29,0,4,0,0,0,1,0,29,0,0,0,0,0,1,4,53],[0,0,0,64,1,0,4,61,0,0,0,32,2,16,0,57,0,0,0,0,3,7,4,51,0,0,0,0,4,3,0,75],[0,0,0,0,4,2,0,25,0,0,12,27,0,0,97,61,0,0,0,0,5,0,0,25,0,0,0,0,6,7,0,25],[0,0,0,0,4,2,0,25,0,0,0,32,6,96,0,57,0,0,0,0,7,6,4,51,0,0,0,0,4,116,4,54],[0,0,0,1,5,80,0,57,0,0,0,0,7,53,0,75,0,0,12,21,0,0,65,61,0,0,0,0,3,20,0,73],[0,0,0,32,4,48,0,138,0,0,0,0,0,65,4,53,0,0,0,31,3,48,0,57,0,0,0,6,4,48,1,127],[0,0,0,0,3,20,0,25,0,0,0,0,4,67,0,75,0,0,0,0,4,0,0,25,0,0,0,1,4,0,64,57],[0,0,6,94,5,48,0,156,0,0,13,227,0,0,33,61,0,0,0,1,4,64,1,144,0,0,13,227,0,0,193,61],[0,0,0,64,0,48,4,63,0,0,6,86,3,32,0,156,0,0,6,86,4,0,0,65,0,0,0,0,2,4,128,25],[0,0,0,64,2,32,2,16,0,0,0,0,1,1,4,51,0,0,6,86,3,16,0,156,0,0,0,0,1,4,128,25],[0,0,0,96,1,16,2,16,0,0,0,0,1,33,1,159,0,0,0,0,2,0,4,20,0,0,6,86,3,32,0,156],[0,0,0,0,2,4,128,25,0,0,0,192,2,32,2,16,0,0,0,0,1,33,1,159,0,0,1,0,2,0,0,57],[25,83,25,78,0,0,4,15,0,0,0,96,3,0,0,57,0,3,0,0,0,1,3,85,0,0,0,0,4,1,0,25],[0,0,0,96,4,64,2,112,0,1,6,86,0,64,1,157,0,0,6,86,4,64,1,152,0,0,12,103,0,0,97,61],[0,0,0,63,3,64,0,57,0,0,6,164,5,48,1,151,0,0,0,64,3,0,4,61,0,0,0,0,5,83,0,25],[0,0,0,0,6,53,0,75,0,0,0,0,6,0,0,25,0,0,0,1,6,0,64,57,0,0,6,94,7,80,0,156],[0,0,13,227,0,0,33,61,0,0,0,1,6,96,1,144,0,0,13,227,0,0,193,61,0,0,0,64,0,80,4,63],[0,0,0,0,5,67,4,54,0,0,0,5,6,64,2,114,0,0,12,88,0,0,97,61,0,0,0,0,7,0,0,25],[0,0,0,5,8,112,2,16,0,0,0,0,9,133,0,25,0,0,0,0,8,129,3,79,0,0,0,0,8,8,4,59],[0,0,0,0,0,137,4,53,0,0,0,1,7,112,0,57,0,0,0,0,8,103,0,75,0,0,12,80,0,0,65,61],[0,0,0,31,4,64,1,144,0,0,12,103,0,0,97,61,0,0,0,5,6,96,2,16,0,0,0,0,1,97,3,79],[0,0,0,0,5,101,0,25,0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207],[0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47],[0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,0,1,1,32,1,144],[0,0,13,233,0,0,97,61,0,0,0,0,1,3,4,51,0,0,0,0,1,1,0,75,0,0,0,8,7,0,0,41],[0,0,13,251,0,0,193,61,0,0,0,0,1,7,4,51,0,0,0,5,2,0,0,41,0,0,0,0,1,33,0,75],[0,0,13,223,0,0,161,61,0,0,0,4,1,0,0,41,0,0,0,3,3,0,0,41,0,0,0,0,0,49,4,53],[0,0,0,4,1,32,0,140,0,0,0,1,2,32,0,57,0,0,12,2,0,0,65,61,0,0,0,1,2,0,0,57],[0,0,0,0,1,7,4,51,0,0,0,0,1,33,0,75,0,0,13,223,0,0,161,61,0,5,0,0,0,2,0,29],[0,0,0,5,1,32,2,16,0,0,0,7,2,16,0,41,0,0,0,0,1,2,4,51,0,3,0,0,0,1,0,29],[0,0,6,236,1,0,0,65,0,4,0,0,0,2,0,29,0,0,0,0,0,18,4,53,0,0,0,64,1,0,4,61],[0,0,0,32,2,16,0,57,0,0,0,0,3,7,4,51,0,0,0,0,4,3,0,75,0,0,0,0,4,2,0,25],[0,0,12,146,0,0,97,61,0,0,0,0,5,0,0,25,0,0,0,0,6,7,0,25,0,0,0,0,4,2,0,25],[0,0,0,32,6,96,0,57,0,0,0,0,7,6,4,51,0,0,0,0,4,116,4,54,0,0,0,1,5,80,0,57],[0,0,0,0,7,53,0,75,0,0,12,140,0,0,65,61,0,0,0,0,3,20,0,73,0,0,0,32,4,48,0,138],[0,0,0,0,0,65,4,53,0,0,0,31,3,48,0,57,0,0,0,6,4,48,1,127,0,0,0,0,3,20,0,25],[0,0,0,0,4,67,0,75,0,0,0,0,4,0,0,25,0,0,0,1,4,0,64,57,0,0,6,94,5,48,0,156],[0,0,13,227,0,0,33,61,0,0,0,1,4,64,1,144,0,0,13,227,0,0,193,61,0,0,0,64,0,48,4,63],[0,0,6,86,3,32,0,156,0,0,6,86,4,0,0,65,0,0,0,0,2,4,128,25,0,0,0,64,2,32,2,16],[0,0,0,0,1,1,4,51,0,0,6,86,3,16,0,156,0,0,0,0,1,4,128,25,0,0,0,96,1,16,2,16],[0,0,0,0,1,33,1,159,0,0,0,0,2,0,4,20,0,0,6,86,3,32,0,156,0,0,0,0,2,4,128,25],[0,0,0,192,2,32,2,16,0,0,0,0,1,33,1,159,0,0,1,0,2,0,0,57,25,83,25,78,0,0,4,15],[0,0,0,96,3,0,0,57,0,3,0,0,0,1,3,85,0,0,0,0,4,1,0,25,0,0,0,96,4,64,2,112],[0,1,6,86,0,64,1,157,0,0,6,86,4,64,1,152,0,0,12,222,0,0,97,61,0,0,0,63,3,64,0,57],[0,0,6,164,5,48,1,151,0,0,0,64,3,0,4,61,0,0,0,0,5,83,0,25,0,0,0,0,6,53,0,75],[0,0,0,0,6,0,0,25,0,0,0,1,6,0,64,57,0,0,6,94,7,80,0,156,0,0,13,227,0,0,33,61],[0,0,0,1,6,96,1,144,0,0,13,227,0,0,193,61,0,0,0,64,0,80,4,63,0,0,0,0,5,67,4,54],[0,0,0,5,6,64,2,114,0,0,12,207,0,0,97,61,0,0,0,0,7,0,0,25,0,0,0,5,8,112,2,16],[0,0,0,0,9,133,0,25,0,0,0,0,8,129,3,79,0,0,0,0,8,8,4,59,0,0,0,0,0,137,4,53],[0,0,0,1,7,112,0,57,0,0,0,0,8,103,0,75,0,0,12,199,0,0,65,61,0,0,0,31,4,64,1,144],[0,0,12,222,0,0,97,61,0,0,0,5,6,96,2,16,0,0,0,0,1,97,3,79,0,0,0,0,5,101,0,25],[0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47],[0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207],[0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,0,1,1,32,1,144,0,0,13,233,0,0,97,61],[0,0,0,0,1,3,4,51,0,0,0,0,1,1,0,75,0,0,0,8,7,0,0,41,0,0,13,251,0,0,193,61],[0,0,0,0,1,7,4,51,0,0,0,5,2,0,0,41,0,0,0,0,1,33,0,75,0,0,13,223,0,0,161,61],[0,0,0,4,1,0,0,41,0,0,0,3,3,0,0,41,0,0,0,0,0,49,4,53,0,0,0,2,1,32,0,140],[0,0,0,1,2,32,0,57,0,0,12,120,0,0,65,61,0,0,0,3,2,0,0,57,0,2,0,1,0,0,0,61],[0,0,0,0,1,7,4,51,0,0,0,0,1,33,0,75,0,0,13,223,0,0,161,61,0,5,0,0,0,2,0,29],[0,0,0,5,1,32,2,16,0,0,0,7,2,16,0,41,0,0,0,0,1,2,4,51,0,3,0,0,0,1,0,29],[0,0,0,2,1,0,0,41,0,4,0,0,0,2,0,29,0,0,0,0,0,18,4,53,0,0,0,64,1,0,4,61],[0,0,0,32,2,16,0,57,0,0,0,0,3,7,4,51,0,0,0,0,4,3,0,75,0,0,0,0,4,2,0,25],[0,0,13,10,0,0,97,61,0,0,0,0,5,0,0,25,0,0,0,0,6,7,0,25,0,0,0,0,4,2,0,25],[0,0,0,32,6,96,0,57,0,0,0,0,7,6,4,51,0,0,0,0,4,116,4,54,0,0,0,1,5,80,0,57],[0,0,0,0,7,53,0,75,0,0,13,4,0,0,65,61,0,0,0,0,3,20,0,73,0,0,0,32,4,48,0,138],[0,0,0,0,0,65,4,53,0,0,0,31,3,48,0,57,0,0,0,6,4,48,1,127,0,0,0,0,3,20,0,25],[0,0,0,0,4,67,0,75,0,0,0,0,4,0,0,25,0,0,0,1,4,0,64,57,0,0,6,94,5,48,0,156],[0,0,13,227,0,0,33,61,0,0,0,1,4,64,1,144,0,0,13,227,0,0,193,61,0,0,0,64,0,48,4,63],[0,0,6,86,3,32,0,156,0,0,6,86,4,0,0,65,0,0,0,0,2,4,128,25,0,0,0,64,2,32,2,16],[0,0,0,0,1,1,4,51,0,0,6,86,3,16,0,156,0,0,0,0,1,4,128,25,0,0,0,96,1,16,2,16],[0,0,0,0,1,33,1,159,0,0,0,0,2,0,4,20,0,0,6,86,3,32,0,156,0,0,0,0,2,4,128,25],[0,0,0,192,2,32,2,16,0,0,0,0,1,33,1,159,0,0,1,0,2,0,0,57,25,83,25,78,0,0,4,15],[0,0,0,96,3,0,0,57,0,3,0,0,0,1,3,85,0,0,0,0,4,1,0,25,0,0,0,96,4,64,2,112],[0,1,6,86,0,64,1,157,0,0,6,86,4,64,1,152,0,0,13,86,0,0,97,61,0,0,0,63,3,64,0,57],[0,0,6,164,5,48,1,151,0,0,0,64,3,0,4,61,0,0,0,0,5,83,0,25,0,0,0,0,6,53,0,75],[0,0,0,0,6,0,0,25,0,0,0,1,6,0,64,57,0,0,6,94,7,80,0,156,0,0,13,227,0,0,33,61],[0,0,0,1,6,96,1,144,0,0,13,227,0,0,193,61,0,0,0,64,0,80,4,63,0,0,0,0,5,67,4,54],[0,0,0,5,6,64,2,114,0,0,13,71,0,0,97,61,0,0,0,0,7,0,0,25,0,0,0,5,8,112,2,16],[0,0,0,0,9,133,0,25,0,0,0,0,8,129,3,79,0,0,0,0,8,8,4,59,0,0,0,0,0,137,4,53],[0,0,0,1,7,112,0,57,0,0,0,0,8,103,0,75,0,0,13,63,0,0,65,61,0,0,0,31,4,64,1,144],[0,0,13,86,0,0,97,61,0,0,0,5,6,96,2,16,0,0,0,0,1,97,3,79,0,0,0,0,5,101,0,25],[0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47],[0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207],[0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,0,1,1,32,1,144,0,0,13,233,0,0,97,61],[0,0,0,0,1,3,4,51,0,0,0,0,1,1,0,75,0,0,0,8,7,0,0,41,0,0,13,251,0,0,193,61],[0,0,0,0,1,7,4,51,0,0,0,5,2,0,0,41,0,0,0,0,1,33,0,75,0,0,13,223,0,0,161,61],[0,0,0,4,1,0,0,41,0,0,0,3,3,0,0,41,0,0,0,0,0,49,4,53,0,0,0,4,1,32,0,140],[0,0,0,1,2,32,0,57,0,0,12,240,0,0,65,61,0,0,0,0,1,7,4,51,0,0,0,3,1,16,0,140],[0,0,13,223,0,0,65,61,0,0,6,239,1,0,0,65,0,0,0,1,2,0,0,41,0,0,0,0,0,18,4,53],[0,0,0,64,1,0,4,61,0,0,0,32,2,16,0,57,0,0,0,0,3,7,4,51,0,0,0,0,4,3,0,75],[0,0,0,0,4,2,0,25,0,0,13,122,0,0,97,61,0,0,0,0,5,0,0,25,0,0,0,0,4,2,0,25],[0,0,0,32,7,112,0,57,0,0,0,0,6,7,4,51,0,0,0,0,4,100,4,54,0,0,0,1,5,80,0,57],[0,0,0,0,6,53,0,75,0,0,13,116,0,0,65,61,0,0,0,0,3,20,0,73,0,0,0,32,4,48,0,138],[0,0,0,0,0,65,4,53,0,0,0,31,3,48,0,57,0,0,0,6,4,48,1,127,0,0,0,0,3,20,0,25],[0,0,0,0,4,67,0,75,0,0,0,0,4,0,0,25,0,0,0,1,4,0,64,57,0,0,6,94,5,48,0,156],[0,0,13,227,0,0,33,61,0,0,0,1,4,64,1,144,0,0,13,227,0,0,193,61,0,0,0,64,0,48,4,63],[0,0,6,86,3,0,0,65,0,0,6,86,4,32,0,156,0,0,0,0,2,3,128,25,0,0,0,64,2,32,2,16],[0,0,0,0,1,1,4,51,0,0,6,86,4,16,0,156,0,0,0,0,1,3,128,25,0,0,0,96,1,16,2,16],[0,0,0,0,1,33,1,159,0,0,0,0,2,0,4,20,0,0,6,86,4,32,0,156,0,0,0,0,2,3,128,25],[0,0,0,192,2,32,2,16,0,0,0,0,1,33,1,159,0,0,1,0,2,0,0,57,25,83,25,78,0,0,4,15],[0,0,0,96,4,0,0,57,0,0,0,128,3,0,0,57,0,3,0,0,0,1,3,85,0,0,0,0,5,1,0,25],[0,0,0,96,5,80,2,112,0,1,6,86,0,80,1,157,0,0,6,86,6,80,1,152,0,0,13,200,0,0,97,61],[0,0,0,63,3,96,0,57,0,0,6,164,3,48,1,151,0,0,0,64,4,0,4,61,0,0,0,0,3,52,0,25],[0,0,0,0,5,67,0,75,0,0,0,0,5,0,0,25,0,0,0,1,5,0,64,57,0,0,6,94,7,48,0,156],[0,0,13,227,0,0,33,61,0,0,0,1,5,80,1,144,0,0,13,227,0,0,193,61,0,0,0,64,0,48,4,63],[0,0,0,31,5,96,1,143,0,0,0,0,3,100,4,54,0,0,0,5,6,96,2,114,0,0,13,185,0,0,97,61],[0,0,0,0,7,0,0,25,0,0,0,5,8,112,2,16,0,0,0,0,9,131,0,25,0,0,0,0,8,129,3,79],[0,0,0,0,8,8,4,59,0,0,0,0,0,137,4,53,0,0,0,1,7,112,0,57,0,0,0,0,8,103,0,75],[0,0,13,177,0,0,65,61,0,0,0,0,7,5,0,75,0,0,13,200,0,0,97,61,0,0,0,5,6,96,2,16],[0,0,0,0,1,97,3,79,0,0,0,0,6,99,0,25,0,0,0,3,5,80,2,16,0,0,0,0,7,6,4,51],[0,0,0,0,7,87,1,207,0,0,0,0,7,87,2,47,0,0,0,0,1,1,4,59,0,0,1,0,5,80,0,137],[0,0,0,0,1,81,2,47,0,0,0,0,1,81,1,207,0,0,0,0,1,113,1,159,0,0,0,0,0,22,4,53],[0,0,0,1,1,32,1,144,0,0,13,233,0,0,97,61,0,0,0,0,1,4,4,51,0,0,6,124,2,0,0,65],[0,0,0,32,4,16,0,140,0,0,0,0,4,0,0,25,0,0,0,0,4,2,64,25,0,0,6,124,1,16,1,151],[0,0,0,0,5,1,0,75,0,0,0,0,2,0,160,25,0,0,6,124,1,16,0,156,0,0,0,0,2,4,192,25],[0,0,0,0,1,2,0,75,0,0,14,16,0,0,193,61,0,0,0,0,1,3,4,51,0,0,0,0,2,1,0,75],[0,0,0,0,2,0,0,25,0,0,0,1,2,0,192,57,0,0,0,0,2,33,0,75,0,0,14,16,0,0,193,61],[0,0,0,0,1,1,0,75,0,0,14,18,0,0,97,61,0,0,0,0,0,1,4,45,0,0,6,224,1,0,0,65],[0,0,0,0,0,16,4,53,0,0,0,50,1,0,0,57,0,0,13,230,0,0,1,61,0,0,6,224,1,0,0,65],[0,0,0,0,0,16,4,53,0,0,0,65,1,0,0,57,0,0,0,4,0,16,4,63,0,0,6,166,1,0,0,65],[0,0,25,85,0,1,4,48,0,0,0,64,1,0,4,61,0,0,0,68,2,16,0,57,0,0,6,240,3,0,0,65],[0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,22,3,0,0,57,0,0,0,0,0,50,4,53],[0,0,6,98,2,0,0,65,0,0,0,0,0,33,4,53,0,0,0,4,2,16,0,57,0,0,0,32,3,0,0,57],[0,0,0,0,0,50,4,53,0,0,6,86,2,0,0,65,0,0,6,86,3,16,0,156,0,0,0,0,1,2,128,25],[0,0,0,64,1,16,2,16,0,0,6,126,1,16,1,199,0,0,25,85,0,1,4,48,0,0,0,64,1,0,4,61],[0,0,0,100,2,16,0,57,0,0,6,237,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,68,2,16,0,57],[0,0,6,238,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,45,3,0,0,57],[0,0,0,0,0,50,4,53,0,0,6,98,2,0,0,65,0,0,0,0,0,33,4,53,0,0,0,4,2,16,0,57],[0,0,0,32,3,0,0,57,0,0,0,0,0,50,4,53,0,0,6,86,2,0,0,65,0,0,6,86,3,16,0,156],[0,0,0,0,1,2,128,25,0,0,0,64,1,16,2,16,0,0,6,171,1,16,1,199,0,0,25,85,0,1,4,48],[0,0,0,0,1,0,0,25,0,0,25,85,0,1,4,48,0,0,0,64,1,0,4,61,0,0,0,100,2,16,0,57],[0,0,6,241,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,68,2,16,0,57,0,0,6,242,3,0,0,65],[0,0,14,1,0,0,1,61,0,7,0,0,0,0,0,2,0,0,0,64,4,0,4,61,0,7,0,0,0,4,0,29],[0,0,6,165,1,0,0,65,0,0,0,0,0,20,4,53,0,0,0,4,1,64,0,57,0,0,0,6,2,0,0,57],[0,0,0,0,0,33,4,53,0,0,6,86,1,0,0,65,0,0,0,0,2,0,4,20,0,0,6,86,3,32,0,156],[0,0,0,0,2,1,128,25,0,0,6,86,3,64,0,156,0,0,0,0,1,4,64,25,0,0,0,64,1,16,2,16],[0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159,0,0,6,166,1,16,1,199,0,0,128,2,2,0,0,57],[25,83,25,78,0,0,4,15,0,0,0,7,10,0,0,41,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112],[0,0,6,86,3,48,1,151,0,0,0,32,4,48,0,140,0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57],[0,0,0,31,5,64,1,143,0,0,0,5,6,64,2,114,0,0,14,64,0,0,97,61,0,0,0,0,7,0,0,25],[0,0,0,5,8,112,2,16,0,0,0,0,9,138,0,25,0,0,0,0,8,129,3,79,0,0,0,0,8,8,4,59],[0,0,0,0,0,137,4,53,0,0,0,1,7,112,0,57,0,0,0,0,8,103,0,75,0,0,14,56,0,0,65,61],[0,0,0,0,7,5,0,75,0,0,14,79,0,0,97,61,0,0,0,5,6,96,2,16,0,0,0,0,7,97,3,79],[0,0,0,0,6,106,0,25,0,0,0,3,5,80,2,16,0,0,0,0,8,6,4,51,0,0,0,0,8,88,1,207],[0,0,0,0,8,88,2,47,0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137,0,0,0,0,7,87,2,47],[0,0,0,0,5,87,1,207,0,0,0,0,5,133,1,159,0,0,0,0,0,86,4,53,0,1,0,0,0,3,0,31],[0,3,0,0,0,1,3,85,0,0,0,1,2,32,1,144,0,0,16,182,0,0,97,61,0,0,0,31,1,64,0,57],[0,0,0,96,2,16,1,143,0,0,0,0,1,162,0,25,0,0,0,0,2,33,0,75,0,0,0,0,2,0,0,25],[0,0,0,1,2,0,64,57,0,0,6,94,4,16,0,156,0,0,16,147,0,0,33,61,0,0,0,1,2,32,1,144],[0,0,16,147,0,0,193,61,0,0,0,64,0,16,4,63,0,0,0,31,2,48,0,140,0,0,16,211,0,0,161,61],[0,0,0,0,2,10,4,51,0,7,0,0,0,2,0,29,0,0,0,32,2,0,0,57,0,6,0,0,0,2,0,29],[0,0,0,0,2,33,4,54,0,0,0,0,0,2,4,53,0,0,6,167,3,16,0,156,0,0,16,147,0,0,33,61],[0,0,0,64,3,16,0,57,0,0,0,64,0,48,4,63,0,0,6,86,3,0,0,65,0,0,6,86,4,32,0,156],[0,0,0,0,2,3,128,25,0,0,0,64,2,32,2,16,0,0,0,0,1,1,4,51,0,0,6,86,4,16,0,156],[0,0,0,0,1,3,128,25,0,0,0,96,1,16,2,16,0,0,0,0,1,33,1,159,0,0,0,0,2,0,4,20],[0,0,6,86,4,32,0,156,0,0,0,0,2,3,128,25,0,0,0,192,2,32,2,16,0,0,0,0,1,33,1,159],[0,0,128,18,2,0,0,57,25,83,25,78,0,0,4,15,0,3,0,0,0,1,3,85,0,0,0,0,2,1,0,25],[0,0,0,96,2,32,2,112,0,1,6,86,0,32,1,157,0,0,6,86,4,32,1,152,0,0,14,168,0,0,97,61],[0,0,0,63,2,64,0,57,0,0,6,164,2,32,1,151,0,0,0,64,3,0,4,61,0,0,0,0,2,35,0,25],[0,0,0,0,5,50,0,75,0,0,0,0,5,0,0,25,0,0,0,1,5,0,64,57,0,0,6,94,6,32,0,156],[0,0,16,147,0,0,33,61,0,0,0,1,5,80,1,144,0,0,16,147,0,0,193,61,0,0,0,64,0,32,4,63],[0,0,0,31,2,64,1,143,0,0,0,0,3,67,4,54,0,0,0,5,4,64,2,114,0,0,14,153,0,0,97,61],[0,0,0,0,5,0,0,25,0,0,0,5,6,80,2,16,0,0,0,0,7,99,0,25,0,0,0,0,6,97,3,79],[0,0,0,0,6,6,4,59,0,0,0,0,0,103,4,53,0,0,0,1,5,80,0,57,0,0,0,0,6,69,0,75],[0,0,14,145,0,0,65,61,0,0,0,0,5,2,0,75,0,0,14,168,0,0,97,61,0,0,0,5,4,64,2,16],[0,0,0,0,1,65,3,79,0,0,0,0,3,67,0,25,0,0,0,3,2,32,2,16,0,0,0,0,4,3,4,51],[0,0,0,0,4,36,1,207,0,0,0,0,4,36,2,47,0,0,0,0,1,1,4,59,0,0,1,0,2,32,0,137],[0,0,0,0,1,33,2,47,0,0,0,0,1,33,1,207,0,0,0,0,1,65,1,159,0,0,0,0,0,19,4,53],[0,0,0,0,1,0,4,20,0,5,0,0,0,1,0,29,0,0,0,64,1,0,4,61,0,0,0,6,2,0,0,41],[0,0,0,0,2,33,4,54,0,0,0,7,3,0,0,41,0,0,0,0,0,50,4,53,0,0,6,167,3,16,0,156],[0,0,16,147,0,0,33,61,0,0,0,64,3,16,0,57,0,0,0,64,0,48,4,63,0,0,6,86,3,0,0,65],[0,0,6,86,4,32,0,156,0,0,0,0,2,3,128,25,0,0,0,64,2,32,2,16,0,0,0,0,1,1,4,51],[0,0,6,86,4,16,0,156,0,0,0,0,1,3,128,25,0,0,0,96,1,16,2,16,0,0,0,0,1,33,1,159],[0,0,0,0,2,0,4,20,0,0,6,86,4,32,0,156,0,0,0,0,2,3,128,25,0,0,0,192,2,32,2,16],[0,0,0,0,1,33,1,159,0,0,128,18,2,0,0,57,25,83,25,78,0,0,4,15,0,0,0,96,3,0,0,57],[0,3,0,0,0,1,3,85,0,0,0,0,4,1,0,25,0,0,0,96,4,64,2,112,0,1,6,86,0,64,1,157],[0,0,6,86,6,64,1,152,0,0,14,242,0,0,97,61,0,0,0,63,3,96,0,57,0,0,6,164,4,48,1,151],[0,0,0,64,3,0,4,61,0,0,0,0,4,67,0,25,0,0,0,0,5,52,0,75,0,0,0,0,5,0,0,25],[0,0,0,1,5,0,64,57,0,0,6,94,7,64,0,156,0,0,16,147,0,0,33,61,0,0,0,1,5,80,1,144],[0,0,16,147,0,0,193,61,0,0,0,64,0,64,4,63,0,0,0,31,4,96,1,143,0,0,0,0,5,99,4,54],[0,0,0,5,6,96,2,114,0,0,14,227,0,0,97,61,0,0,0,0,7,0,0,25,0,0,0,5,8,112,2,16],[0,0,0,0,9,133,0,25,0,0,0,0,8,129,3,79,0,0,0,0,8,8,4,59,0,0,0,0,0,137,4,53],[0,0,0,1,7,112,0,57,0,0,0,0,8,103,0,75,0,0,14,219,0,0,65,61,0,0,0,0,7,4,0,75],[0,0,14,242,0,0,97,61,0,0,0,5,6,96,2,16,0,0,0,0,1,97,3,79,0,0,0,0,5,101,0,25],[0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47],[0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207],[0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,0,0,4,0,4,20,0,3,0,0,0,4,0,29],[0,0,0,5,1,64,0,107,0,0,16,151,0,0,65,61,0,0,0,1,1,32,1,144,0,0,16,157,0,0,97,61],[0,0,0,0,6,3,4,51,0,0,0,31,1,96,1,144,0,0,16,164,0,0,193,61,0,0,6,243,1,96,0,156],[0,0,16,168,0,0,129,61,0,0,0,64,1,0,4,61,0,0,0,32,2,96,1,144,0,0,16,213,0,0,97,61],[0,0,0,0,2,0,0,25,0,0,0,0,4,18,0,25,0,0,0,32,2,32,0,57,0,0,0,0,5,50,0,25],[0,0,0,0,5,5,4,51,0,0,0,0,0,84,4,53,0,0,0,0,4,98,0,75,0,0,15,1,0,0,65,61],[0,0,0,0,2,97,0,25,0,0,0,0,0,2,4,53,0,0,6,86,2,0,0,65,0,0,6,86,3,96,0,156],[0,4,0,0,0,6,0,29,0,0,0,0,3,2,0,25,0,0,0,0,3,6,64,25,0,0,0,96,3,48,2,16],[0,0,6,86,4,16,0,156,0,0,0,0,1,2,128,25,0,0,0,64,1,16,2,16,0,0,0,0,1,49,1,159],[0,0,0,0,3,0,4,20,0,0,6,86,4,48,0,156,0,0,0,0,3,2,128,25,0,0,0,192,2,48,2,16],[0,0,0,0,1,18,1,159,0,0,0,2,2,0,0,57,0,1,0,0,0,2,0,29,25,83,25,78,0,0,4,15],[0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,6,86,3,48,1,151,0,0,0,32,4,48,0,140],[0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57,0,0,0,31,5,64,1,143,0,0,0,5,4,64,2,114],[0,0,15,45,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,113,3,79],[0,0,0,0,8,8,4,59,0,0,0,0,0,135,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,70,0,75],[0,0,15,38,0,0,65,61,0,0,0,0,6,5,0,75,0,0,15,59,0,0,97,61,0,0,0,3,5,80,2,16],[0,0,0,5,4,64,2,16,0,0,0,0,6,4,4,51,0,0,0,0,6,86,1,207,0,0,0,0,6,86,2,47],[0,0,0,0,7,65,3,79,0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137,0,0,0,0,7,87,2,47],[0,0,0,0,5,87,1,207,0,0,0,0,5,101,1,159,0,0,0,0,0,84,4,53,0,1,0,0,0,3,0,31],[0,3,0,0,0,1,3,85,0,0,0,1,2,32,1,144,0,0,16,219,0,0,97,61,0,0,0,0,1,0,4,51],[0,0,6,244,1,16,1,151,0,0,0,4,2,0,0,41,0,0,0,219,2,32,2,16,0,0,6,245,2,32,1,151],[0,0,0,0,1,18,1,159,0,0,6,246,1,16,1,199,0,0,0,7,3,0,0,41,0,0,0,0,1,49,0,75],[0,0,16,172,0,0,193,61,0,0,0,0,1,0,4,20,0,4,0,0,0,1,0,29,0,0,0,64,1,0,4,61],[0,0,0,6,2,0,0,41,0,0,0,0,2,33,4,54,0,0,0,0,0,50,4,53,0,0,6,167,3,16,0,156],[0,0,16,147,0,0,33,61,0,0,0,64,3,16,0,57,0,0,0,64,0,48,4,63,0,0,6,86,3,0,0,65],[0,0,6,86,4,32,0,156,0,0,0,0,2,3,128,25,0,0,0,64,2,32,2,16,0,0,0,0,1,1,4,51],[0,0,6,86,4,16,0,156,0,0,0,0,1,3,128,25,0,0,0,96,1,16,2,16,0,0,0,0,1,33,1,159],[0,0,0,0,2,0,4,20,0,0,6,86,4,32,0,156,0,0,0,0,2,3,128,25,0,0,0,192,2,32,2,16],[0,0,0,0,1,33,1,159,0,0,128,18,2,0,0,57,25,83,25,78,0,0,4,15,0,0,0,96,3,0,0,57],[0,3,0,0,0,1,3,85,0,0,0,0,4,1,0,25,0,0,0,96,4,64,2,112,0,1,6,86,0,64,1,157],[0,0,6,86,6,64,1,152,0,0,15,146,0,0,97,61,0,0,0,63,3,96,0,57,0,0,6,164,4,48,1,151],[0,0,0,64,3,0,4,61,0,0,0,0,4,67,0,25,0,0,0,0,5,52,0,75,0,0,0,0,5,0,0,25],[0,0,0,1,5,0,64,57,0,0,6,94,7,64,0,156,0,0,16,147,0,0,33,61,0,0,0,1,5,80,1,144],[0,0,16,147,0,0,193,61,0,0,0,64,0,64,4,63,0,0,0,31,4,96,1,143,0,0,0,0,5,99,4,54],[0,0,0,5,6,96,2,114,0,0,15,131,0,0,97,61,0,0,0,0,7,0,0,25,0,0,0,5,8,112,2,16],[0,0,0,0,9,133,0,25,0,0,0,0,8,129,3,79,0,0,0,0,8,8,4,59,0,0,0,0,0,137,4,53],[0,0,0,1,7,112,0,57,0,0,0,0,8,103,0,75,0,0,15,123,0,0,65,61,0,0,0,0,7,4,0,75],[0,0,15,146,0,0,97,61,0,0,0,5,6,96,2,16,0,0,0,0,1,97,3,79,0,0,0,0,5,101,0,25],[0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47],[0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207],[0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,0,0,4,0,4,20,0,2,0,0,0,4,0,29],[0,0,0,4,1,64,0,107,0,0,16,151,0,0,65,61,0,0,0,1,1,32,1,144,0,0,16,157,0,0,97,61],[0,0,0,0,6,3,4,51,0,0,0,31,1,96,1,144,0,0,16,164,0,0,193,61,0,0,6,247,1,96,0,156],[0,0,16,168,0,0,33,61,0,0,0,64,1,0,4,61,0,0,0,32,2,96,1,144,0,0,17,21,0,0,97,61],[0,0,0,3,4,0,0,41,0,3,0,5,0,64,0,113,0,0,0,0,2,0,0,25,0,0,0,0,4,18,0,25],[0,0,0,32,2,32,0,57,0,0,0,0,5,50,0,25,0,0,0,0,5,5,4,51,0,0,0,0,0,84,4,53],[0,0,0,0,4,98,0,75,0,0,15,163,0,0,65,61,0,0,0,0,2,97,0,25,0,0,0,0,0,2,4,53],[0,0,6,86,2,0,0,65,0,0,6,86,3,96,0,156,0,5,0,0,0,6,0,29,0,0,0,0,3,2,0,25],[0,0,0,0,3,6,64,25,0,0,0,96,3,48,2,16,0,0,6,86,4,16,0,156,0,0,0,0,1,2,128,25],[0,0,0,64,1,16,2,16,0,0,0,0,1,49,1,159,0,0,0,0,3,0,4,20,0,0,6,86,4,48,0,156],[0,0,0,0,3,2,128,25,0,0,0,192,2,48,2,16,0,0,0,0,1,18,1,159,0,0,0,2,2,0,0,57],[0,1,0,0,0,2,0,29,25,83,25,78,0,0,4,15,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112],[0,0,6,86,3,48,1,151,0,0,0,32,4,48,0,140,0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57],[0,0,0,31,5,64,1,143,0,0,0,5,4,64,2,114,0,0,15,207,0,0,97,61,0,0,0,0,6,0,0,25],[0,0,0,5,7,96,2,16,0,0,0,0,8,113,3,79,0,0,0,0,8,8,4,59,0,0,0,0,0,135,4,53],[0,0,0,1,6,96,0,57,0,0,0,0,7,70,0,75,0,0,15,200,0,0,65,61,0,0,0,0,6,5,0,75],[0,0,15,221,0,0,97,61,0,0,0,3,5,80,2,16,0,0,0,5,4,64,2,16,0,0,0,0,6,4,4,51],[0,0,0,0,6,86,1,207,0,0,0,0,6,86,2,47,0,0,0,0,7,65,3,79,0,0,0,0,7,7,4,59],[0,0,1,0,5,80,0,137,0,0,0,0,7,87,2,47,0,0,0,0,5,87,1,207,0,0,0,0,5,101,1,159],[0,0,0,0,0,84,4,53,0,1,0,0,0,3,0,31,0,3,0,0,0,1,3,85,0,0,0,1,2,32,1,144],[0,0,16,248,0,0,97,61,0,0,0,0,1,0,4,51,0,0,6,244,1,16,1,151,0,0,0,5,2,0,0,41],[0,0,0,219,2,32,2,16,0,0,6,245,2,32,1,151,0,0,0,0,1,18,1,159,0,0,6,246,1,16,1,199],[0,0,0,7,3,0,0,41,0,0,0,0,1,49,0,75,0,0,16,172,0,0,193,61,0,0,0,0,1,0,4,20],[0,5,0,0,0,1,0,29,0,0,0,64,1,0,4,61,0,0,0,6,2,0,0,41,0,0,0,0,2,33,4,54],[0,0,0,0,0,50,4,53,0,0,6,167,3,16,0,156,0,0,16,147,0,0,33,61,0,0,0,64,3,16,0,57],[0,0,0,64,0,48,4,63,0,0,6,86,3,0,0,65,0,0,6,86,4,32,0,156,0,0,0,0,2,3,128,25],[0,0,0,64,2,32,2,16,0,0,0,0,1,1,4,51,0,0,6,86,4,16,0,156,0,0,0,0,1,3,128,25],[0,0,0,96,1,16,2,16,0,0,0,0,1,33,1,159,0,0,0,0,2,0,4,20,0,0,6,86,4,32,0,156],[0,0,0,0,2,3,128,25,0,0,0,192,2,32,2,16,0,0,0,0,1,33,1,159,0,0,128,18,2,0,0,57],[25,83,25,78,0,0,4,15,0,0,0,96,3,0,0,57,0,3,0,0,0,1,3,85,0,0,0,0,4,1,0,25],[0,0,0,96,4,64,2,112,0,1,6,86,0,64,1,157,0,0,6,86,6,64,1,152,0,0,16,52,0,0,97,61],[0,0,0,63,3,96,0,57,0,0,6,164,4,48,1,151,0,0,0,64,3,0,4,61,0,0,0,0,4,67,0,25],[0,0,0,0,5,52,0,75,0,0,0,0,5,0,0,25,0,0,0,1,5,0,64,57,0,0,6,94,7,64,0,156],[0,0,16,147,0,0,33,61,0,0,0,1,5,80,1,144,0,0,16,147,0,0,193,61,0,0,0,64,0,64,4,63],[0,0,0,31,4,96,1,143,0,0,0,0,5,99,4,54,0,0,0,5,6,96,2,114,0,0,16,37,0,0,97,61],[0,0,0,0,7,0,0,25,0,0,0,5,8,112,2,16,0,0,0,0,9,133,0,25,0,0,0,0,8,129,3,79],[0,0,0,0,8,8,4,59,0,0,0,0,0,137,4,53,0,0,0,1,7,112,0,57,0,0,0,0,8,103,0,75],[0,0,16,29,0,0,65,61,0,0,0,0,7,4,0,75,0,0,16,52,0,0,97,61,0,0,0,5,6,96,2,16],[0,0,0,0,1,97,3,79,0,0,0,0,5,101,0,25,0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51],[0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137],[0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53],[0,0,0,0,4,0,4,20,0,0,0,5,1,64,0,107,0,0,16,151,0,0,65,61,0,0,0,1,1,32,1,144],[0,0,16,157,0,0,97,61,0,0,0,0,6,3,4,51,0,0,0,31,1,96,1,144,0,0,16,164,0,0,193,61],[0,0,6,247,1,96,0,156,0,0,16,168,0,0,33,61,0,0,0,64,1,0,4,61,0,0,0,32,2,96,1,144],[0,0,17,21,0,0,97,61,0,1,0,0,0,4,0,29,0,0,0,2,4,0,0,41,0,2,0,4,0,64,0,113],[0,0,0,0,2,0,0,25,0,0,0,0,4,18,0,25,0,0,0,32,2,32,0,57,0,0,0,0,5,50,0,25],[0,0,0,0,5,5,4,51,0,0,0,0,0,84,4,53,0,0,0,0,4,98,0,75,0,0,16,69,0,0,65,61],[0,0,0,0,2,97,0,25,0,0,0,0,0,2,4,53,0,0,6,86,2,0,0,65,0,0,6,86,3,96,0,156],[0,4,0,0,0,6,0,29,0,0,0,0,3,2,0,25,0,0,0,0,3,6,64,25,0,0,0,96,3,48,2,16],[0,0,6,86,4,16,0,156,0,0,0,0,1,2,128,25,0,0,0,64,1,16,2,16,0,0,0,0,1,49,1,159],[0,0,0,0,3,0,4,20,0,0,6,86,4,48,0,156,0,0,0,0,3,2,128,25,0,0,0,192,2,48,2,16],[0,0,0,0,1,18,1,159,0,0,0,2,2,0,0,57,25,83,25,78,0,0,4,15,0,0,0,0,3,1,0,25],[0,0,0,96,3,48,2,112,0,0,6,86,3,48,1,151,0,0,0,32,4,48,0,140,0,0,0,0,4,3,0,25],[0,0,0,32,4,0,128,57,0,0,0,31,5,64,1,143,0,0,0,5,4,64,2,114,0,0,16,112,0,0,97,61],[0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,113,3,79,0,0,0,0,8,8,4,59],[0,0,0,0,0,135,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,70,0,75,0,0,16,105,0,0,65,61],[0,0,0,0,6,5,0,75,0,0,16,126,0,0,97,61,0,0,0,3,5,80,2,16,0,0,0,5,4,64,2,16],[0,0,0,0,6,4,4,51,0,0,0,0,6,86,1,207,0,0,0,0,6,86,2,47,0,0,0,0,7,65,3,79],[0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137,0,0,0,0,7,87,2,47,0,0,0,0,5,87,1,207],[0,0,0,0,5,101,1,159,0,0,0,0,0,84,4,53,0,1,0,0,0,3,0,31,0,3,0,0,0,1,3,85],[0,0,0,1,2,32,1,144,0,0,17,38,0,0,97,61,0,0,0,0,1,0,4,51,0,0,6,244,1,16,1,151],[0,0,0,4,2,0,0,41,0,0,0,219,2,32,2,16,0,0,6,245,2,32,1,151,0,0,0,0,1,18,1,159],[0,0,6,246,1,16,1,199,0,0,0,7,1,16,0,108,0,0,0,1,2,0,0,41,0,0,16,172,0,0,193,61],[0,0,0,2,3,0,0,41,0,0,0,3,1,48,0,107,0,0,17,73,0,0,161,61,0,0,0,5,1,32,0,105],[0,0,0,0,1,19,0,75,0,0,17,83,0,0,193,61,0,0,0,0,0,1,4,45,0,0,6,224,1,0,0,65],[0,0,0,0,0,16,4,53,0,0,0,65,1,0,0,57,0,0,16,154,0,0,1,61,0,0,6,224,1,0,0,65],[0,0,0,0,0,16,4,53,0,0,0,17,1,0,0,57,0,0,0,4,0,16,4,63,0,0,6,166,1,0,0,65],[0,0,25,85,0,1,4,48,0,0,0,64,1,0,4,61,0,0,0,68,2,16,0,57,0,0,6,168,3,0,0,65],[0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,22,3,0,0,57,0,0,17,26,0,0,1,61],[0,0,0,64,1,0,4,61,0,0,0,68,2,16,0,57,0,0,6,248,3,0,0,65,0,0,16,215,0,0,1,61],[0,0,0,64,1,0,4,61,0,0,0,68,2,16,0,57,0,0,6,254,3,0,0,65,0,0,16,215,0,0,1,61],[0,0,0,64,1,0,4,61,0,0,0,100,2,16,0,57,0,0,6,249,3,0,0,65,0,0,0,0,0,50,4,53],[0,0,0,68,2,16,0,57,0,0,6,250,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57],[0,0,0,50,3,0,0,57,0,0,17,92,0,0,1,61,0,0,0,64,2,0,4,61,0,0,0,31,4,48,1,143],[0,0,0,5,5,48,2,114,0,0,16,195,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16],[0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53],[0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,16,187,0,0,65,61,0,0,0,0,6,4,0,75],[0,0,17,66,0,0,97,61,0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25],[0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47],[0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207],[0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,17,66,0,0,1,61,0,0,0,0,1,0,0,25],[0,0,25,85,0,1,4,48,0,0,0,68,2,16,0,57,0,0,6,253,3,0,0,65,0,0,0,0,0,50,4,53],[0,0,0,36,2,16,0,57,0,0,0,2,3,0,0,57,0,0,17,26,0,0,1,61,0,0,0,64,2,0,4,61],[0,0,0,31,4,48,1,143,0,0,0,5,5,48,2,114,0,0,16,232,0,0,97,61,0,0,0,0,6,0,0,25],[0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59],[0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,16,224,0,0,65,61],[0,0,0,0,6,4,0,75,0,0,16,247,0,0,97,61,0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79],[0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207],[0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47],[0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,17,66,0,0,1,61],[0,0,0,64,2,0,4,61,0,0,0,31,4,48,1,143,0,0,0,5,5,48,2,114,0,0,17,5,0,0,97,61],[0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79],[0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75],[0,0,16,253,0,0,65,61,0,0,0,0,6,4,0,75,0,0,17,20,0,0,97,61,0,0,0,5,5,80,2,16],[0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51],[0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137],[0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53],[0,0,17,66,0,0,1,61,0,0,0,68,2,16,0,57,0,0,6,253,3,0,0,65,0,0,0,0,0,50,4,53],[0,0,0,36,2,16,0,57,0,0,0,1,3,0,0,41,0,0,0,0,0,50,4,53,0,0,6,98,2,0,0,65],[0,0,0,0,0,33,4,53,0,0,0,4,2,16,0,57,0,0,0,6,3,0,0,41,0,0,0,0,0,50,4,53],[0,0,6,86,2,0,0,65,0,0,6,86,3,16,0,156,0,0,0,0,1,2,128,25,0,0,0,64,1,16,2,16],[0,0,6,126,1,16,1,199,0,0,25,85,0,1,4,48,0,0,0,64,2,0,4,61,0,0,0,31,4,48,1,143],[0,0,0,5,5,48,2,114,0,0,17,51,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16],[0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53],[0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,17,43,0,0,65,61,0,0,0,0,6,4,0,75],[0,0,17,66,0,0,97,61,0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25],[0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47],[0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207],[0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,6,86,1,0,0,65,0,0,6,86,4,32,0,156],[0,0,0,0,2,1,128,25,0,0,0,64,1,32,2,16,0,0,0,96,2,48,2,16,0,0,0,0,1,33,1,159],[0,0,25,85,0,1,4,48,0,0,0,64,1,0,4,61,0,0,0,100,2,16,0,57,0,0,6,169,3,0,0,65],[0,0,0,0,0,50,4,53,0,0,0,68,2,16,0,57,0,0,6,170,3,0,0,65,0,0,0,0,0,50,4,53],[0,0,0,36,2,16,0,57,0,0,0,33,3,0,0,57,0,0,17,92,0,0,1,61,0,0,0,64,1,0,4,61],[0,0,0,100,2,16,0,57,0,0,6,251,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,68,2,16,0,57],[0,0,6,252,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,47,3,0,0,57],[0,0,0,0,0,50,4,53,0,0,6,98,2,0,0,65,0,0,0,0,0,33,4,53,0,0,0,4,2,16,0,57],[0,0,0,6,3,0,0,41,0,0,0,0,0,50,4,53,0,0,6,86,2,0,0,65,0,0,6,86,3,16,0,156],[0,0,0,0,1,2,128,25,0,0,0,64,1,16,2,16,0,0,6,171,1,16,1,199,0,0,25,85,0,1,4,48],[0,4,0,0,0,0,0,2,0,0,0,7,2,0,0,57,0,0,6,163,1,0,0,65,0,4,0,0,0,2,0,29],[25,83,25,78,0,0,4,15,0,3,0,0,0,1,3,85,0,0,0,0,2,1,0,25,0,0,0,96,2,32,2,112],[0,1,6,86,0,32,1,157,0,0,6,86,4,32,1,152,0,0,17,155,0,0,97,61,0,0,0,63,2,64,0,57],[0,0,6,164,2,32,1,151,0,0,0,64,3,0,4,61,0,0,0,0,2,35,0,25,0,0,0,0,5,50,0,75],[0,0,0,0,5,0,0,25,0,0,0,1,5,0,64,57,0,0,6,94,6,32,0,156,0,0,18,50,0,0,33,61],[0,0,0,1,5,80,1,144,0,0,18,50,0,0,193,61,0,0,0,64,0,32,4,63,0,0,0,31,2,64,1,143],[0,0,0,0,3,67,4,54,0,0,0,5,4,64,2,114,0,0,17,140,0,0,97,61,0,0,0,0,5,0,0,25],[0,0,0,5,6,80,2,16,0,0,0,0,7,99,0,25,0,0,0,0,6,97,3,79,0,0,0,0,6,6,4,59],[0,0,0,0,0,103,4,53,0,0,0,1,5,80,0,57,0,0,0,0,6,69,0,75,0,0,17,132,0,0,65,61],[0,0,0,0,5,2,0,75,0,0,17,155,0,0,97,61,0,0,0,5,4,64,2,16,0,0,0,0,1,65,3,79],[0,0,0,0,3,67,0,25,0,0,0,3,2,32,2,16,0,0,0,0,4,3,4,51,0,0,0,0,4,36,1,207],[0,0,0,0,4,36,2,47,0,0,0,0,1,1,4,59,0,0,1,0,2,32,0,137,0,0,0,0,1,33,2,47],[0,0,0,0,1,33,1,207,0,0,0,0,1,65,1,159,0,0,0,0,0,19,4,53,0,0,0,64,4,0,4,61],[0,3,0,0,0,4,0,29,0,0,6,165,1,0,0,65,0,0,0,0,0,20,4,53,0,0,0,4,1,64,0,57],[0,0,0,4,2,0,0,41,0,0,0,0,0,33,4,53,0,0,6,86,1,0,0,65,0,0,0,0,2,0,4,20],[0,0,6,86,3,32,0,156,0,0,0,0,2,1,128,25,0,0,6,86,3,64,0,156,0,0,0,0,1,4,64,25],[0,0,0,64,1,16,2,16,0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159,0,0,6,166,1,16,1,199],[0,0,128,2,2,0,0,57,25,83,25,78,0,0,4,15,0,0,0,3,10,0,0,41,0,0,0,0,3,1,0,25],[0,0,0,96,3,48,2,112,0,0,6,86,3,48,1,151,0,0,0,32,4,48,0,140,0,0,0,0,4,3,0,25],[0,0,0,32,4,0,128,57,0,0,0,31,5,64,1,143,0,0,0,5,6,64,2,114,0,0,17,193,0,0,97,61],[0,0,0,0,7,0,0,25,0,0,0,5,8,112,2,16,0,0,0,0,9,138,0,25,0,0,0,0,8,129,3,79],[0,0,0,0,8,8,4,59,0,0,0,0,0,137,4,53,0,0,0,1,7,112,0,57,0,0,0,0,8,103,0,75],[0,0,17,185,0,0,65,61,0,0,0,0,7,5,0,75,0,0,17,208,0,0,97,61,0,0,0,5,6,96,2,16],[0,0,0,0,7,97,3,79,0,0,0,0,6,106,0,25,0,0,0,3,5,80,2,16,0,0,0,0,8,6,4,51],[0,0,0,0,8,88,1,207,0,0,0,0,8,88,2,47,0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137],[0,0,0,0,7,87,2,47,0,0,0,0,5,87,1,207,0,0,0,0,5,133,1,159,0,0,0,0,0,86,4,53],[0,1,0,0,0,3,0,31,0,3,0,0,0,1,3,85,0,0,0,1,2,32,1,144,0,0,18,78,0,0,97,61],[0,0,0,31,1,64,0,57,0,0,0,96,2,16,1,143,0,0,0,0,1,162,0,25,0,0,0,0,2,33,0,75],[0,0,0,0,2,0,0,25,0,0,0,1,2,0,64,57,0,0,6,94,4,16,0,156,0,0,18,50,0,0,33,61],[0,0,0,1,2,32,1,144,0,0,18,50,0,0,193,61,0,0,0,64,0,16,4,63,0,0,0,31,2,48,0,140],[0,0,18,113,0,0,161,61,0,0,0,0,3,10,4,51,0,0,0,32,2,0,0,57,0,3,0,0,0,2,0,29],[0,0,0,0,2,33,4,54,0,2,0,0,0,3,0,29,0,0,0,0,0,50,4,53,0,0,6,167,3,16,0,156],[0,0,18,50,0,0,33,61,0,0,0,64,3,16,0,57,0,0,0,64,0,48,4,63,0,0,6,86,3,0,0,65],[0,0,6,86,4,32,0,156,0,0,0,0,2,3,128,25,0,0,0,64,2,32,2,16,0,0,0,0,4,0,4,20],[0,4,0,0,0,4,0,29,0,0,0,0,1,1,4,51,0,0,6,86,4,16,0,156,0,0,0,0,1,3,128,25],[0,0,0,96,1,16,2,16,0,0,0,0,1,33,1,159,0,0,0,0,2,0,4,20,0,0,6,86,4,32,0,156],[0,0,0,0,2,3,128,25,0,0,0,192,2,32,2,16,0,0,0,0,1,33,1,159,0,0,128,18,2,0,0,57],[25,83,25,78,0,0,4,15,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,1,6,86,0,48,1,157],[0,3,0,0,0,1,3,85,0,0,0,0,1,0,4,20,0,1,0,0,0,1,0,29,0,0,0,4,1,16,0,107],[0,0,18,54,0,0,65,61,0,0,0,1,1,32,1,144,0,0,18,60,0,0,97,61,0,0,0,64,1,0,4,61],[0,0,0,3,2,0,0,41,0,0,0,0,2,33,4,54,0,0,0,2,3,0,0,41,0,0,0,0,0,50,4,53],[0,0,6,167,3,16,0,156,0,0,18,50,0,0,33,61,0,0,0,64,3,16,0,57,0,0,0,64,0,48,4,63],[0,0,6,86,3,0,0,65,0,0,6,86,4,32,0,156,0,0,0,0,2,3,128,25,0,0,0,64,2,32,2,16],[0,0,0,0,4,0,4,20,0,2,0,0,0,4,0,29,0,0,0,0,1,1,4,51,0,0,6,86,4,16,0,156],[0,0,0,0,1,3,128,25,0,0,0,96,1,16,2,16,0,0,0,0,1,33,1,159,0,0,0,0,2,0,4,20],[0,0,6,86,4,32,0,156,0,0,0,0,2,3,128,25,0,0,0,192,2,32,2,16,0,0,0,0,1,33,1,159],[0,0,128,18,2,0,0,57,25,83,25,78,0,0,4,15,0,0,0,2,4,0,0,41,0,0,0,0,3,1,0,25],[0,0,0,96,3,48,2,112,0,1,6,86,0,48,1,157,0,3,0,0,0,1,3,85,0,0,0,0,1,0,4,20],[0,0,0,0,3,20,0,75,0,0,18,54,0,0,65,61,0,0,0,1,2,32,1,144,0,0,18,60,0,0,97,61],[0,0,0,1,3,0,0,41,0,0,0,4,2,48,0,105,0,0,0,0,1,20,0,73,0,0,0,0,1,18,0,75],[0,0,18,115,0,0,193,61,0,0,0,0,0,1,4,45,0,0,6,224,1,0,0,65,0,0,0,0,0,16,4,53],[0,0,0,65,1,0,0,57,0,0,18,57,0,0,1,61,0,0,6,224,1,0,0,65,0,0,0,0,0,16,4,53],[0,0,0,17,1,0,0,57,0,0,0,4,0,16,4,63,0,0,6,166,1,0,0,65,0,0,25,85,0,1,4,48],[0,0,0,64,1,0,4,61,0,0,0,68,2,16,0,57,0,0,6,168,3,0,0,65,0,0,0,0,0,50,4,53],[0,0,0,36,2,16,0,57,0,0,0,22,3,0,0,57,0,0,0,0,0,50,4,53,0,0,6,98,2,0,0,65],[0,0,0,0,0,33,4,53,0,0,0,4,2,16,0,57,0,0,0,3,3,0,0,41,0,0,0,0,0,50,4,53],[0,0,6,86,2,0,0,65,0,0,6,86,3,16,0,156,0,0,0,0,1,2,128,25,0,0,0,64,1,16,2,16],[0,0,6,126,1,16,1,199,0,0,25,85,0,1,4,48,0,0,0,64,2,0,4,61,0,0,0,31,4,48,1,143],[0,0,0,5,5,48,2,114,0,0,18,91,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16],[0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53],[0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,18,83,0,0,65,61,0,0,0,0,6,4,0,75],[0,0,18,106,0,0,97,61,0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25],[0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47],[0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207],[0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,6,86,1,0,0,65,0,0,6,86,4,32,0,156],[0,0,0,0,2,1,128,25,0,0,0,64,1,32,2,16,0,0,0,96,2,48,2,16,0,0,0,0,1,33,1,159],[0,0,25,85,0,1,4,48,0,0,0,0,1,0,0,25,0,0,25,85,0,1,4,48,0,0,0,64,1,0,4,61],[0,0,0,100,2,16,0,57,0,0,6,169,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,68,2,16,0,57],[0,0,6,170,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,33,3,0,0,57],[0,0,0,0,0,50,4,53,0,0,6,98,2,0,0,65,0,0,0,0,0,33,4,53,0,0,0,4,2,16,0,57],[0,0,0,3,3,0,0,41,0,0,0,0,0,50,4,53,0,0,6,86,2,0,0,65,0,0,6,86,3,16,0,156],[0,0,0,0,1,2,128,25,0,0,0,64,1,16,2,16,0,0,6,171,1,16,1,199,0,0,25,85,0,1,4,48],[0,1,0,0,0,0,0,2,0,0,0,0,1,0,0,50,0,0,19,25,0,0,193,61,0,0,6,101,1,0,0,65],[0,0,0,0,0,16,4,57,0,0,6,86,1,0,0,65,0,0,0,0,2,0,4,20,0,0,6,86,3,32,0,156],[0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,6,102,1,16,1,199,0,0,128,11,2,0,0,57],[25,83,25,78,0,0,4,15,0,0,0,1,2,32,1,144,0,0,19,24,0,0,97,61,0,0,0,0,2,1,4,59],[0,0,3,233,1,0,0,138,0,1,0,0,0,2,0,29,0,0,0,0,1,18,0,75,0,0,19,27,0,0,33,61],[0,0,6,103,1,0,0,65,0,0,0,0,0,16,4,57,0,0,6,86,3,0,0,65,0,0,0,0,1,0,4,20],[0,0,6,86,2,16,0,156,0,0,0,0,1,3,128,25,0,0,0,192,1,16,2,16,0,0,6,102,1,16,1,199],[0,0,128,11,2,0,0,57,25,83,25,78,0,0,4,15,0,0,0,1,2,32,1,144,0,0,19,24,0,0,97,61],[0,0,0,0,1,1,4,59,0,0,0,11,2,0,0,57,0,0,0,0,0,18,4,27,0,0,6,104,1,0,0,65],[0,0,0,0,0,16,4,57,0,0,0,0,1,0,4,20,0,0,6,86,2,16,0,156,0,0,6,86,1,0,128,65],[0,0,0,192,1,16,2,16,0,0,6,102,1,16,1,199,0,0,128,11,2,0,0,57,25,83,25,78,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,19,24,0,0,97,61,0,0,0,0,1,1,4,59,0,0,0,10,2,0,0,57],[0,0,0,0,3,2,4,26,0,0,6,105,3,48,1,151,0,0,0,0,1,19,1,159,0,0,0,0,0,18,4,27],[0,0,6,106,1,0,0,65,0,0,0,0,0,16,4,57,0,0,6,86,3,0,0,65,0,0,0,0,1,0,4,20],[0,0,6,86,2,16,0,156,0,0,0,0,1,3,128,25,0,0,0,192,1,16,2,16,0,0,6,102,1,16,1,199],[0,0,128,11,2,0,0,57,25,83,25,78,0,0,4,15,0,0,0,1,2,32,1,144,0,0,19,24,0,0,97,61],[0,0,0,0,1,1,4,59,0,0,0,9,2,0,0,57,0,0,0,0,0,18,4,27,0,0,6,107,1,0,0,65],[0,0,0,0,0,16,4,57,0,0,0,0,1,0,4,20,0,0,6,86,2,16,0,156,0,0,6,86,1,0,128,65],[0,0,0,192,1,16,2,16,0,0,6,102,1,16,1,199,0,0,128,11,2,0,0,57,25,83,25,78,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,19,24,0,0,97,61,0,0,0,0,1,1,4,59,0,0,0,8,2,0,0,57],[0,0,0,0,0,18,4,27,0,0,6,108,1,0,0,65,0,0,0,0,0,16,4,57,0,0,6,86,3,0,0,65],[0,0,0,0,1,0,4,20,0,0,6,86,2,16,0,156,0,0,0,0,1,3,128,25,0,0,0,192,1,16,2,16],[0,0,6,102,1,16,1,199,0,0,128,11,2,0,0,57,25,83,25,78,0,0,4,15,0,0,0,1,2,32,1,144],[0,0,19,24,0,0,97,61,0,0,0,0,1,1,4,59,0,0,0,7,2,0,0,57,0,0,0,0,0,18,4,27],[0,0,6,109,1,0,0,65,0,0,0,0,0,16,4,57,0,0,0,0,1,0,4,20,0,0,6,86,2,16,0,156],[0,0,6,86,1,0,128,65,0,0,0,192,1,16,2,16,0,0,6,102,1,16,1,199,0,0,128,11,2,0,0,57],[25,83,25,78,0,0,4,15,0,0,0,1,2,32,1,144,0,0,19,24,0,0,97,61,0,0,0,0,1,1,4,59],[0,0,0,4,2,0,0,57,0,0,0,0,0,18,4,27,0,0,6,110,1,0,0,65,0,0,0,0,0,16,4,57],[0,0,6,86,1,0,0,65,0,0,0,0,2,0,4,20,0,0,6,86,3,32,0,156,0,0,0,0,2,1,128,25],[0,0,0,192,1,32,2,16,0,0,6,102,1,16,1,199,0,0,128,11,2,0,0,57,25,83,25,78,0,0,4,15],[0,0,0,1,2,32,1,144,0,0,19,24,0,0,97,61,0,0,0,0,1,1,4,59,0,0,6,97,1,16,1,151],[0,0,0,5,2,0,0,57,0,0,0,0,3,2,4,26,0,0,6,105,3,48,1,151,0,0,0,0,1,19,1,159],[0,0,0,0,0,18,4,27,0,0,0,3,1,0,0,57,0,0,0,0,2,1,4,26,0,0,6,111,2,32,1,151],[0,0,0,2,3,0,3,103,0,0,0,0,3,3,4,59,0,0,0,224,3,48,2,112,0,0,0,0,2,50,1,159],[0,0,0,0,0,33,4,27,0,0,0,6,1,0,0,57,0,0,0,1,2,0,0,41,0,0,0,0,0,33,4,27],[0,0,0,0,1,0,4,22,0,0,0,12,2,0,0,57,0,0,0,0,0,18,4,27,0,0,0,0,0,1,4,45],[0,0,0,0,0,1,4,47,0,0,0,0,1,0,0,25,0,0,25,85,0,1,4,48,0,0,6,224,1,0,0,65],[0,0,0,0,0,16,4,53,0,0,0,17,1,0,0,57,0,0,0,4,0,16,4,63,0,0,6,166,1,0,0,65],[0,0,25,85,0,1,4,48,0,5,0,0,0,0,0,2,0,0,0,64,1,0,4,61,0,0,6,229,2,16,0,156],[0,0,21,32,0,0,129,61,0,0,0,96,2,16,0,57,0,0,0,64,0,32,4,63,0,0,6,139,2,0,0,65],[0,0,0,0,2,33,4,54,0,0,0,64,4,0,4,61,0,0,6,140,3,64,0,156,0,0,21,32,0,0,33,61],[0,0,0,128,3,64,0,57,0,0,0,64,0,48,4,63,0,0,0,96,3,64,0,57,0,0,6,141,5,0,0,65],[0,0,0,0,0,83,4,53,0,0,0,64,3,64,0,57,0,0,6,142,5,0,0,65,0,0,0,0,0,83,4,53],[0,0,0,32,3,64,0,57,0,0,6,143,5,0,0,65,0,0,0,0,0,83,4,53,0,0,0,65,3,0,0,57],[0,5,0,0,0,3,0,29,0,0,0,0,0,52,4,53,0,0,0,64,3,16,0,57,0,0,6,144,5,0,0,65],[0,0,0,0,0,83,4,53,0,0,0,0,0,66,4,53,0,0,0,64,7,0,4,61,0,0,6,138,4,112,0,156],[0,0,21,32,0,0,33,61,0,0,0,96,4,112,0,57,0,0,0,64,0,64,4,63,0,0,6,145,4,0,0,65],[0,0,0,0,8,71,4,54,0,0,0,64,4,0,4,61,0,0,6,140,5,64,0,156,0,0,21,32,0,0,33,61],[0,0,0,128,5,64,0,57,0,0,0,64,0,80,4,63,0,0,0,96,5,64,0,57,0,0,6,141,6,0,0,65],[0,0,0,0,0,101,4,53,0,0,0,64,5,64,0,57,0,0,6,146,6,0,0,65,0,0,0,0,0,101,4,53],[0,0,0,32,5,64,0,57,0,0,6,147,6,0,0,65,0,0,0,0,0,101,4,53,0,0,0,5,5,0,0,41],[0,0,0,0,0,84,4,53,0,0,0,64,6,112,0,57,0,0,6,148,5,0,0,65,0,1,0,0,0,6,0,29],[0,0,0,0,0,86,4,53,0,0,0,0,0,72,4,53,0,0,0,0,2,2,4,51,0,0,0,0,84,2,4,52],[0,0,0,65,4,64,0,140,0,0,21,30,0,0,193,61,0,0,0,65,4,32,0,57,0,0,0,0,4,4,4,51],[0,0,0,255,4,64,1,143,0,0,0,27,6,64,0,138,0,0,0,1,6,96,0,140,0,0,21,30,0,0,33,61],[0,4,0,0,0,8,0,29,0,3,0,0,0,7,0,29,0,0,0,0,3,3,4,51,0,2,0,0,0,3,0,29],[0,0,0,0,1,1,4,51,0,0,0,0,3,5,4,51,0,0,0,64,2,32,0,57,0,0,0,0,2,2,4,51],[0,0,0,64,5,0,4,61,0,0,0,96,6,80,0,57,0,0,0,0,0,38,4,53,0,0,0,64,2,80,0,57],[0,0,0,0,0,50,4,53,0,0,0,32,2,80,0,57,0,0,0,0,0,66,4,53,0,0,0,0,0,21,4,53],[0,0,0,0,0,0,4,53,0,0,6,86,1,0,0,65,0,0,0,0,2,0,4,20,0,0,6,86,3,32,0,156],[0,0,0,0,2,1,128,25,0,0,6,86,3,80,0,156,0,0,0,0,5,1,128,25,0,0,0,64,1,80,2,16],[0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159,0,0,6,149,1,16,1,199,0,0,0,1,2,0,0,57],[25,83,25,78,0,0,4,15,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,6,86,3,48,1,151],[0,0,0,32,4,48,0,140,0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57,0,0,0,31,5,64,1,143],[0,0,0,5,4,64,2,114,0,0,19,146,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16],[0,0,0,0,8,113,3,79,0,0,0,0,8,8,4,59,0,0,0,0,0,135,4,53,0,0,0,1,6,96,0,57],[0,0,0,0,7,70,0,75,0,0,19,139,0,0,65,61,0,0,0,0,6,5,0,75,0,0,19,160,0,0,97,61],[0,0,0,3,5,80,2,16,0,0,0,5,4,64,2,16,0,0,0,0,6,4,4,51,0,0,0,0,6,86,1,207],[0,0,0,0,6,86,2,47,0,0,0,0,7,65,3,79,0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137],[0,0,0,0,7,87,2,47,0,0,0,0,5,87,1,207,0,0,0,0,5,101,1,159,0,0,0,0,0,84,4,53],[0,1,0,0,0,3,0,31,0,3,0,0,0,1,3,85,0,0,0,1,2,32,1,144,0,0,0,4,2,0,0,41],[0,0,21,38,0,0,97,61,0,0,0,0,1,0,4,51,0,0,0,2,1,16,1,79,0,0,6,97,1,16,1,152],[0,0,0,3,5,0,0,41,0,0,21,30,0,0,193,61,0,0,0,0,1,2,4,51,0,0,0,0,50,1,4,52],[0,0,0,65,2,32,0,140,0,0,21,30,0,0,193,61,0,0,0,65,2,16,0,57,0,0,0,0,2,2,4,51],[0,0,0,255,2,32,1,143,0,0,0,27,4,32,0,138,0,0,0,1,4,64,0,140,0,0,21,30,0,0,33,61],[0,0,0,1,4,0,0,41,0,0,0,0,4,4,4,51,0,4,0,0,0,4,0,29,0,0,0,0,4,5,4,51],[0,0,0,0,3,3,4,51,0,0,0,64,1,16,0,57,0,0,0,0,1,1,4,51,0,0,0,64,5,0,4,61],[0,0,0,96,6,80,0,57,0,0,0,0,0,22,4,53,0,0,0,64,1,80,0,57,0,0,0,0,0,49,4,53],[0,0,0,32,1,80,0,57,0,0,0,0,0,33,4,53,0,0,0,0,0,69,4,53,0,0,0,0,0,0,4,53],[0,0,6,86,1,0,0,65,0,0,0,0,2,0,4,20,0,0,6,86,3,32,0,156,0,0,0,0,2,1,128,25],[0,0,6,86,3,80,0,156,0,0,0,0,5,1,128,25,0,0,0,64,1,80,2,16,0,0,0,192,2,32,2,16],[0,0,0,0,1,18,1,159,0,0,6,149,1,16,1,199,0,0,0,1,2,0,0,57,25,83,25,78,0,0,4,15],[0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,6,86,3,48,1,151,0,0,0,32,4,48,0,140],[0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57,0,0,0,31,5,64,1,143,0,0,0,5,4,64,2,114],[0,0,19,225,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,113,3,79],[0,0,0,0,8,8,4,59,0,0,0,0,0,135,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,70,0,75],[0,0,19,218,0,0,65,61,0,0,0,0,6,5,0,75,0,0,19,239,0,0,97,61,0,0,0,3,5,80,2,16],[0,0,0,5,4,64,2,16,0,0,0,0,6,4,4,51,0,0,0,0,6,86,1,207,0,0,0,0,6,86,2,47],[0,0,0,0,7,65,3,79,0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137,0,0,0,0,7,87,2,47],[0,0,0,0,5,87,1,207,0,0,0,0,5,101,1,159,0,0,0,0,0,84,4,53,0,1,0,0,0,3,0,31],[0,3,0,0,0,1,3,85,0,0,0,1,2,32,1,144,0,0,21,67,0,0,97,61,0,0,0,0,1,0,4,51],[0,0,0,4,1,16,1,79,0,0,6,97,1,16,1,152,0,0,21,30,0,0,193,61,0,0,0,64,1,0,4,61],[0,0,6,138,2,16,0,156,0,0,21,32,0,0,33,61,0,0,0,96,2,16,0,57,0,0,0,64,0,32,4,63],[0,0,0,0,5,1,4,54,0,0,0,64,2,0,4,61,0,0,6,140,3,32,0,156,0,0,21,32,0,0,33,61],[0,0,0,128,3,32,0,57,0,0,0,64,0,48,4,63,0,0,0,96,3,32,0,57,0,0,6,141,4,0,0,65],[0,0,0,0,0,67,4,53,0,0,0,64,3,32,0,57,0,0,6,150,4,0,0,65,0,0,0,0,0,67,4,53],[0,0,0,32,4,32,0,57,0,0,6,151,6,0,0,65,0,0,0,0,0,100,4,53,0,0,0,5,6,0,0,41],[0,0,0,0,0,98,4,53,0,0,0,64,6,16,0,57,0,0,6,152,7,0,0,65,0,0,0,0,0,118,4,53],[0,0,0,0,0,37,4,53,0,0,0,0,5,2,4,51,0,0,0,65,5,80,0,140,0,0,21,30,0,0,193,61],[0,0,0,65,2,32,0,57,0,0,0,0,2,2,4,51,0,0,0,255,2,32,1,143,0,0,0,27,5,32,0,138],[0,0,0,1,5,80,0,140,0,0,21,30,0,0,33,61,0,0,0,0,1,1,4,51,0,0,0,0,4,4,4,51],[0,0,0,0,3,3,4,51,0,0,0,64,5,0,4,61,0,0,0,96,6,80,0,57,0,0,0,0,0,54,4,53],[0,0,0,64,3,80,0,57,0,0,0,0,0,67,4,53,0,0,0,32,3,80,0,57,0,0,0,0,0,35,4,53],[0,0,0,0,0,21,4,53,0,0,0,0,0,0,4,53,0,0,6,86,1,0,0,65,0,0,0,0,2,0,4,20],[0,0,6,86,3,32,0,156,0,0,0,0,2,1,128,25,0,0,6,86,3,80,0,156,0,0,0,0,5,1,128,25],[0,0,0,64,1,80,2,16,0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159,0,0,6,149,1,16,1,199],[0,0,0,1,2,0,0,57,25,83,25,78,0,0,4,15,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112],[0,0,6,86,3,48,1,151,0,0,0,32,4,48,0,140,0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57],[0,0,0,31,5,64,1,143,0,0,0,5,4,64,2,114,0,0,20,67,0,0,97,61,0,0,0,0,6,0,0,25],[0,0,0,5,7,96,2,16,0,0,0,0,8,113,3,79,0,0,0,0,8,8,4,59,0,0,0,0,0,135,4,53],[0,0,0,1,6,96,0,57,0,0,0,0,7,70,0,75,0,0,20,60,0,0,65,61,0,0,0,0,6,5,0,75],[0,0,20,81,0,0,97,61,0,0,0,3,5,80,2,16,0,0,0,5,4,64,2,16,0,0,0,0,6,4,4,51],[0,0,0,0,6,86,1,207,0,0,0,0,6,86,2,47,0,0,0,0,7,65,3,79,0,0,0,0,7,7,4,59],[0,0,1,0,5,80,0,137,0,0,0,0,7,87,2,47,0,0,0,0,5,87,1,207,0,0,0,0,5,101,1,159],[0,0,0,0,0,84,4,53,0,1,0,0,0,3,0,31,0,3,0,0,0,1,3,85,0,0,0,1,2,32,1,144],[0,0,21,96,0,0,97,61,0,0,0,0,1,0,4,51,0,0,6,97,1,16,1,151,0,0,6,152,1,16,0,156],[0,0,21,30,0,0,193,61,0,0,0,64,1,0,4,61,0,0,6,138,2,16,0,156,0,0,21,32,0,0,33,61],[0,0,0,96,2,16,0,57,0,0,0,64,0,32,4,63,0,0,6,153,2,0,0,65,0,0,0,0,5,33,4,54],[0,0,0,64,2,0,4,61,0,0,6,140,3,32,0,156,0,0,21,32,0,0,33,61,0,0,0,128,3,32,0,57],[0,0,0,64,0,48,4,63,0,0,0,96,3,32,0,57,0,0,6,154,4,0,0,65,0,0,0,0,0,67,4,53],[0,0,0,64,3,32,0,57,0,0,6,155,4,0,0,65,0,0,0,0,0,67,4,53,0,0,0,32,4,32,0,57],[0,0,6,156,6,0,0,65,0,0,0,0,0,100,4,53,0,0,0,5,6,0,0,41,0,0,0,0,0,98,4,53],[0,0,0,0,0,37,4,53,0,0,0,64,5,16,0,57,0,0,0,0,0,5,4,53,0,0,0,0,5,2,4,51],[0,0,0,65,5,80,0,140,0,0,21,30,0,0,193,61,0,0,0,65,2,32,0,57,0,0,0,0,2,2,4,51],[0,0,0,255,2,32,1,143,0,0,0,27,5,32,0,138,0,0,0,1,5,80,0,140,0,0,21,30,0,0,33,61],[0,0,0,0,1,1,4,51,0,0,0,0,4,4,4,51,0,0,0,0,3,3,4,51,0,0,0,64,5,0,4,61],[0,0,0,96,6,80,0,57,0,0,0,0,0,54,4,53,0,0,0,64,3,80,0,57,0,0,0,0,0,67,4,53],[0,0,0,32,3,80,0,57,0,0,0,0,0,35,4,53,0,0,0,0,0,21,4,53,0,0,0,0,0,0,4,53],[0,0,6,86,1,0,0,65,0,0,0,0,2,0,4,20,0,0,6,86,3,32,0,156,0,0,0,0,2,1,128,25],[0,0,6,86,3,80,0,156,0,0,0,0,5,1,128,25,0,0,0,64,1,80,2,16,0,0,0,192,2,32,2,16],[0,0,0,0,1,18,1,159,0,0,6,149,1,16,1,199,0,0,0,1,2,0,0,57,25,83,25,78,0,0,4,15],[0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,6,86,3,48,1,151,0,0,0,32,4,48,0,140],[0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57,0,0,0,31,5,64,1,143,0,0,0,5,4,64,2,114],[0,0,20,165,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,113,3,79],[0,0,0,0,8,8,4,59,0,0,0,0,0,135,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,70,0,75],[0,0,20,158,0,0,65,61,0,0,0,0,6,5,0,75,0,0,20,179,0,0,97,61,0,0,0,3,5,80,2,16],[0,0,0,5,4,64,2,16,0,0,0,0,6,4,4,51,0,0,0,0,6,86,1,207,0,0,0,0,6,86,2,47],[0,0,0,0,7,65,3,79,0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137,0,0,0,0,7,87,2,47],[0,0,0,0,5,87,1,207,0,0,0,0,5,101,1,159,0,0,0,0,0,84,4,53,0,1,0,0,0,3,0,31],[0,3,0,0,0,1,3,85,0,0,0,1,2,32,1,144,0,0,21,125,0,0,97,61,0,0,0,0,1,0,4,51],[0,0,6,97,1,16,1,152,0,0,21,30,0,0,193,61,0,0,0,64,1,0,4,61,0,0,6,138,2,16,0,156],[0,0,21,32,0,0,33,61,0,0,0,96,2,16,0,57,0,0,0,64,0,32,4,63,0,0,6,157,2,0,0,65],[0,0,0,0,5,33,4,54,0,0,0,64,2,0,4,61,0,0,6,140,3,32,0,156,0,0,21,32,0,0,33,61],[0,0,0,128,3,32,0,57,0,0,0,64,0,48,4,63,0,0,0,96,3,32,0,57,0,0,6,141,4,0,0,65],[0,0,0,0,0,67,4,53,0,0,0,64,3,32,0,57,0,0,6,158,4,0,0,65,0,0,0,0,0,67,4,53],[0,0,0,32,4,32,0,57,0,0,6,159,6,0,0,65,0,0,0,0,0,100,4,53,0,0,0,5,6,0,0,41],[0,0,0,0,0,98,4,53,0,0,0,64,6,16,0,57,0,0,6,160,7,0,0,65,0,0,0,0,0,118,4,53],[0,0,0,0,0,37,4,53,0,0,0,0,5,2,4,51,0,0,0,65,5,80,0,140,0,0,21,30,0,0,193,61],[0,0,0,65,2,32,0,57,0,0,0,0,2,2,4,51,0,0,0,255,2,32,1,143,0,0,0,27,5,32,0,138],[0,0,0,1,5,80,0,140,0,0,21,30,0,0,33,61,0,0,0,0,1,1,4,51,0,0,0,0,4,4,4,51],[0,0,0,0,3,3,4,51,0,0,0,64,5,0,4,61,0,0,0,96,6,80,0,57,0,0,0,0,0,54,4,53],[0,0,0,64,3,80,0,57,0,0,0,0,0,67,4,53,0,0,0,32,3,80,0,57,0,0,0,0,0,35,4,53],[0,0,0,0,0,21,4,53,0,0,0,0,0,0,4,53,0,0,6,86,1,0,0,65,0,0,0,0,2,0,4,20],[0,0,6,86,3,32,0,156,0,0,0,0,2,1,128,25,0,0,6,86,3,80,0,156,0,0,0,0,5,1,128,25],[0,0,0,64,1,80,2,16,0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159,0,0,6,149,1,16,1,199],[0,0,0,1,2,0,0,57,25,83,25,78,0,0,4,15,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112],[0,0,6,86,3,48,1,151,0,0,0,32,4,48,0,140,0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57],[0,0,0,31,5,64,1,143,0,0,0,5,4,64,2,114,0,0,21,7,0,0,97,61,0,0,0,0,6,0,0,25],[0,0,0,5,7,96,2,16,0,0,0,0,8,113,3,79,0,0,0,0,8,8,4,59,0,0,0,0,0,135,4,53],[0,0,0,1,6,96,0,57,0,0,0,0,7,70,0,75,0,0,21,0,0,0,65,61,0,0,0,0,6,5,0,75],[0,0,21,21,0,0,97,61,0,0,0,3,5,80,2,16,0,0,0,5,4,64,2,16,0,0,0,0,6,4,4,51],[0,0,0,0,6,86,1,207,0,0,0,0,6,86,2,47,0,0,0,0,7,65,3,79,0,0,0,0,7,7,4,59],[0,0,1,0,5,80,0,137,0,0,0,0,7,87,2,47,0,0,0,0,5,87,1,207,0,0,0,0,5,101,1,159],[0,0,0,0,0,84,4,53,0,1,0,0,0,3,0,31,0,3,0,0,0,1,3,85,0,0,0,1,2,32,1,144],[0,0,21,154,0,0,97,61,0,0,0,0,1,0,4,51,0,0,6,97,1,16,1,151,0,0,6,160,1,16,0,156],[0,0,21,30,0,0,193,61,0,0,0,0,0,1,4,45,0,0,0,0,1,0,0,25,0,0,25,85,0,1,4,48],[0,0,6,224,1,0,0,65,0,0,0,0,0,16,4,53,0,0,0,65,1,0,0,57,0,0,0,4,0,16,4,63],[0,0,6,166,1,0,0,65,0,0,25,85,0,1,4,48,0,0,0,64,2,0,4,61,0,0,0,31,4,48,1,143],[0,0,0,5,5,48,2,114,0,0,21,51,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16],[0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53],[0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,21,43,0,0,65,61,0,0,0,0,6,4,0,75],[0,0,21,182,0,0,97,61,0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25],[0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47],[0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207],[0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,21,182,0,0,1,61,0,0,0,64,2,0,4,61],[0,0,0,31,4,48,1,143,0,0,0,5,5,48,2,114,0,0,21,80,0,0,97,61,0,0,0,0,6,0,0,25],[0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59],[0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,21,72,0,0,65,61],[0,0,0,0,6,4,0,75,0,0,21,95,0,0,97,61,0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79],[0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207],[0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47],[0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,21,182,0,0,1,61],[0,0,0,64,2,0,4,61,0,0,0,31,4,48,1,143,0,0,0,5,5,48,2,114,0,0,21,109,0,0,97,61],[0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79],[0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75],[0,0,21,101,0,0,65,61,0,0,0,0,6,4,0,75,0,0,21,124,0,0,97,61,0,0,0,5,5,80,2,16],[0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51],[0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137],[0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53],[0,0,21,182,0,0,1,61,0,0,0,64,2,0,4,61,0,0,0,31,4,48,1,143,0,0,0,5,5,48,2,114],[0,0,21,138,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25],[0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57],[0,0,0,0,7,86,0,75,0,0,21,130,0,0,65,61,0,0,0,0,6,4,0,75,0,0,21,153,0,0,97,61],[0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16],[0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59],[0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159],[0,0,0,0,0,21,4,53,0,0,21,182,0,0,1,61,0,0,0,64,2,0,4,61,0,0,0,31,4,48,1,143],[0,0,0,5,5,48,2,114,0,0,21,167,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16],[0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53],[0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,21,159,0,0,65,61,0,0,0,0,6,4,0,75],[0,0,21,182,0,0,97,61,0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25],[0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47],[0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207],[0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,6,86,1,0,0,65,0,0,6,86,4,32,0,156],[0,0,0,0,2,1,128,25,0,0,0,64,1,32,2,16,0,0,0,96,2,48,2,16,0,0,0,0,1,33,1,159],[0,0,25,85,0,1,4,48,0,8,0,0,0,0,0,2,0,0,0,0,1,0,4,20,0,1,0,0,0,1,0,29],[0,0,0,64,5,0,4,61,0,0,6,255,1,80,0,156,0,0,23,113,0,0,129,61,0,0,0,160,1,80,0,57],[0,0,0,64,0,16,4,63,0,0,0,128,1,80,0,57,0,0,6,113,2,0,0,65,0,0,0,0,0,33,4,53],[0,0,0,96,1,80,0,57,0,0,6,114,2,0,0,65,0,0,0,0,0,33,4,53,0,0,0,64,1,80,0,57],[0,0,6,115,2,0,0,65,0,0,0,0,0,33,4,53,0,0,0,122,1,0,0,57,0,0,0,0,9,21,4,54],[0,0,6,116,1,0,0,65,0,0,0,0,0,25,4,53,0,3,128,16,0,0,0,61,0,0,0,0,3,0,0,25],[0,8,0,0,0,5,0,29,0,6,0,0,0,3,0,29,0,0,6,86,1,144,0,156,0,0,6,86,4,0,0,65],[0,0,0,0,9,4,128,25,0,0,0,64,1,144,2,16,0,0,0,0,2,5,4,51,0,0,6,86,3,32,0,156],[0,0,0,0,2,4,128,25,0,0,0,96,2,32,2,16,0,0,0,0,1,18,1,159,0,0,0,0,2,0,4,20],[0,0,6,86,3,32,0,156,0,0,0,0,2,4,128,25,0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159],[0,0,6,117,1,16,1,199,0,0,0,3,2,0,0,41,25,83,25,78,0,0,4,15,0,0,0,1,2,32,1,144],[0,0,23,121,0,0,97,61,0,0,0,64,2,0,4,61,0,0,0,0,1,1,4,59,0,7,0,0,0,1,0,29],[0,0,0,8,6,0,0,41,0,0,0,0,1,6,4,51,0,0,0,0,3,1,0,75,0,0,21,248,0,0,97,61],[0,0,0,0,3,0,0,25,0,0,0,0,4,35,0,25,0,0,0,32,3,48,0,57,0,0,0,0,5,99,0,25],[0,0,0,0,5,5,4,51,0,0,0,0,0,84,4,53,0,0,0,0,4,19,0,75,0,0,21,241,0,0,65,61],[0,0,0,0,3,33,0,25,0,0,0,0,0,3,4,53,0,0,6,86,3,32,0,156,0,0,6,86,4,0,0,65],[0,0,0,0,2,4,128,25,0,0,0,64,2,32,2,16,0,0,6,86,3,16,0,156,0,0,0,0,1,4,128,25],[0,0,0,96,1,16,2,16,0,0,0,0,1,33,1,159,0,0,0,0,2,0,4,20,0,0,6,86,3,32,0,156],[0,0,0,0,2,4,128,25,0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159,0,0,0,2,2,0,0,57],[25,83,25,78,0,0,4,15,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,6,86,3,48,1,151],[0,0,0,32,4,48,0,140,0,0,0,0,5,3,0,25,0,0,0,32,5,0,128,57,0,0,0,5,4,80,2,114],[0,0,22,25,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,113,3,79],[0,0,0,0,8,8,4,59,0,0,0,0,0,135,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,70,0,75],[0,0,22,18,0,0,65,61,0,0,0,31,5,80,1,144,0,0,22,39,0,0,97,61,0,0,0,3,5,80,2,16],[0,0,0,5,4,64,2,16,0,0,0,0,6,4,4,51,0,0,0,0,6,86,1,207,0,0,0,0,6,86,2,47],[0,0,0,0,7,65,3,79,0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137,0,0,0,0,7,87,2,47],[0,0,0,0,5,87,1,207,0,0,0,0,5,101,1,159,0,0,0,0,0,84,4,53,0,1,0,0,0,3,0,31],[0,3,0,0,0,1,3,85,0,0,0,64,10,0,4,61,0,0,0,1,2,32,1,144,0,0,23,123,0,0,97,61],[0,0,0,0,2,0,4,51,0,0,0,32,12,160,0,57,0,0,0,8,6,0,0,41,0,0,0,0,1,6,4,51],[0,0,0,0,3,1,0,75,0,0,22,58,0,0,97,61,0,0,0,0,3,0,0,25,0,0,0,0,4,195,0,25],[0,0,0,32,3,48,0,57,0,0,0,0,5,99,0,25,0,0,0,0,5,5,4,51,0,0,0,0,0,84,4,53],[0,0,0,0,4,19,0,75,0,0,22,51,0,0,65,61,0,0,0,7,2,32,1,79,0,0,0,0,3,193,0,25],[0,0,0,0,0,35,4,53,0,0,0,32,3,16,0,57,0,0,0,0,0,58,4,53,0,0,0,95,3,16,0,57],[0,0,0,32,1,0,0,138,0,0,0,0,3,19,1,111,0,0,0,0,13,163,0,25,0,0,0,0,3,61,0,75],[0,0,0,0,3,0,0,25,0,0,0,1,3,0,64,57,0,0,6,94,4,208,0,156,0,0,23,113,0,0,33,61],[0,0,0,1,3,48,1,144,0,0,23,113,0,0,193,61,0,0,0,64,0,208,4,63,0,0,0,13,11,0,0,57],[0,0,0,0,3,11,4,26,0,0,6,94,4,48,0,156,0,0,23,113,0,0,33,61,0,0,0,1,4,48,0,57],[0,0,0,0,0,75,4,27,0,0,0,0,0,176,4,53,0,0,6,118,3,48,0,65,0,0,0,0,0,35,4,27],[0,0,0,0,4,11,4,26,0,0,0,0,3,4,0,75,0,0,23,117,0,0,97,61,0,0,0,1,3,0,0,57],[0,0,0,1,6,64,0,140,0,0,22,115,0,0,97,61,0,0,0,0,3,11,4,26,0,0,0,0,4,99,0,75],[0,0,23,107,0,0,161,61,0,0,0,1,4,96,0,138,0,0,0,1,5,64,2,112,0,0,0,0,7,83,0,75],[0,0,23,107,0,0,161,61,0,0,6,118,7,96,0,65,0,0,0,0,9,7,4,26,0,0,0,0,0,176,4,53],[0,0,6,118,6,80,0,65,0,0,0,0,8,6,4,26,0,0,0,0,9,137,0,75,0,0,22,115,0,0,161,61],[0,0,0,0,0,135,4,27,0,0,0,0,3,11,4,26,0,0,0,0,3,83,0,75,0,0,23,107,0,0,161,61],[0,0,0,0,0,38,4,27,0,0,0,2,3,64,0,140,0,0,0,0,6,5,0,25,0,0,22,90,0,0,129,61],[0,0,0,0,3,11,4,26,0,0,0,0,2,3,0,75,0,0,23,117,0,0,97,61,0,0,0,1,2,48,0,138],[0,0,0,0,2,35,1,112,0,0,22,127,0,0,193,61,0,0,0,14,2,0,0,57,0,0,0,0,3,2,4,26],[0,0,6,94,4,48,1,151,0,0,6,94,5,64,0,156,0,0,23,117,0,0,97,61,0,0,6,119,3,48,1,151],[0,0,0,1,4,64,0,57,0,0,0,0,3,52,1,159,0,0,0,0,0,50,4,27,0,5,0,0,0,12,0,29],[0,7,0,0,0,11,0,29,0,0,6,120,2,0,0,65,0,0,0,0,0,45,4,53,0,0,0,4,2,208,0,57],[0,0,0,32,3,0,0,57,0,2,0,0,0,3,0,29,0,0,0,0,0,50,4,53,0,0,0,0,2,10,4,51],[0,0,0,36,3,208,0,57,0,0,0,0,0,35,4,53,0,0,0,68,3,208,0,57,0,0,0,0,4,2,0,75],[0,0,22,149,0,0,97,61,0,0,0,0,4,0,0,25,0,0,0,0,5,52,0,25,0,0,0,32,4,64,0,57],[0,0,0,0,6,164,0,25,0,0,0,0,6,6,4,51,0,0,0,0,0,101,4,53,0,0,0,0,5,36,0,75],[0,0,22,142,0,0,65,61,0,8,0,0,0,10,0,29,0,0,0,0,3,50,0,25,0,0,0,0,0,3,4,53],[0,0,0,31,2,32,0,57,0,0,0,0,1,18,1,111,0,0,6,86,2,208,0,156,0,0,6,86,4,0,0,65],[0,0,0,0,2,4,0,25,0,0,0,0,2,13,64,25,0,0,0,64,2,32,2,16,0,0,0,68,1,16,0,57],[0,0,6,86,3,16,0,156,0,0,0,0,1,4,128,25,0,0,0,96,1,16,2,16,0,0,0,0,1,33,1,159],[0,0,0,0,2,0,4,20,0,0,6,86,3,32,0,156,0,0,0,0,2,4,128,25,0,0,0,192,2,32,2,16],[0,0,0,0,1,18,1,159,0,0,128,8,2,0,0,57,0,4,0,0,0,13,0,29,25,83,25,73,0,0,4,15],[0,0,0,4,12,0,0,41,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,0,6,86,3,48,1,151],[0,0,0,32,4,48,0,140,0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57,0,0,0,5,5,64,2,114],[0,0,22,190,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,124,0,25],[0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57],[0,0,0,0,7,86,0,75,0,0,22,182,0,0,65,61,0,0,0,31,6,64,1,144,0,0,0,7,11,0,0,41],[0,0,0,5,9,0,0,41,0,0,22,207,0,0,97,61,0,0,0,5,5,80,2,16,0,0,0,0,7,81,3,79],[0,0,0,0,5,92,0,25,0,0,0,3,6,96,2,16,0,0,0,0,8,5,4,51,0,0,0,0,8,104,1,207],[0,0,0,0,8,104,2,47,0,0,0,0,7,7,4,59,0,0,1,0,6,96,0,137,0,0,0,0,7,103,2,47],[0,0,0,0,6,103,1,207,0,0,0,0,6,134,1,159,0,0,0,0,0,101,4,53,0,1,0,0,0,3,0,31],[0,3,0,0,0,1,3,85,0,0,0,1,2,32,1,144,0,0,0,8,10,0,0,41,0,0,23,155,0,0,97,61],[0,0,0,31,1,64,0,57,0,0,0,96,2,16,1,143,0,0,0,0,1,194,0,25,0,0,0,0,2,33,0,75],[0,0,0,0,2,0,0,25,0,0,0,1,2,0,64,57,0,0,6,94,4,16,0,156,0,0,23,113,0,0,33,61],[0,0,0,1,2,32,1,144,0,0,23,113,0,0,193,61,0,0,0,64,0,16,4,63,0,0,0,32,2,48,0,140],[0,0,23,121,0,0,65,61,0,0,0,6,3,0,0,41,0,0,0,2,2,48,0,140,0,0,0,1,3,48,0,57],[0,0,0,0,5,10,0,25,0,0,21,212,0,0,161,61,0,0,0,0,2,11,4,26,0,0,0,0,3,2,0,75],[0,0,23,190,0,0,97,61,0,0,6,121,3,32,0,65,0,0,0,0,4,3,4,26,0,0,6,118,5,0,0,65],[0,0,0,0,0,69,4,27,0,0,0,0,0,176,4,53,0,0,0,0,0,3,4,27,0,0,0,1,3,32,0,138],[0,0,0,0,0,59,4,27,0,0,0,2,2,48,0,140,0,0,23,38,0,0,65,61,0,0,0,1,6,0,0,57],[0,0,6,124,2,0,0,65,0,0,0,0,7,0,0,25,0,0,0,0,5,0,0,25,0,0,0,2,8,112,0,57],[0,0,0,0,4,56,0,75,0,0,0,0,4,6,0,25,0,0,23,2,0,0,129,61,0,0,6,122,4,112,0,65],[0,0,0,0,4,4,4,26,0,0,6,123,7,112,0,65,0,0,0,0,7,7,4,26,0,0,0,0,4,71,0,75],[0,0,0,0,4,6,0,25,0,0,0,0,4,8,64,25,0,0,0,0,6,67,0,75,0,0,23,107,0,0,161,61],[0,0,6,118,6,64,0,65,0,0,0,0,7,83,0,75,0,0,23,107,0,0,161,61,0,0,0,0,7,6,4,26],[0,0,0,0,0,176,4,53,0,0,6,118,8,80,0,65,0,0,0,0,5,8,4,26,0,0,0,0,9,87,0,75],[0,0,23,35,0,0,161,61,0,0,0,0,0,120,4,27,0,0,0,0,3,11,4,26,0,0,0,0,3,67,0,75],[0,0,23,107,0,0,161,61,0,0,0,0,0,86,4,27,0,0,0,0,3,4,0,75,0,0,0,0,3,0,0,25],[0,0,0,0,3,2,64,25,0,0,6,124,5,64,1,151,0,0,0,0,6,5,0,75,0,0,0,0,6,0,0,25],[0,0,0,0,6,2,32,25,0,0,6,124,5,80,0,156,0,0,0,0,6,3,192,25,0,0,0,0,3,6,0,75],[0,0,23,117,0,0,193,61,0,0,0,0,3,11,4,26,0,0,0,1,7,64,2,16,0,0,0,1,6,112,1,191],[0,0,0,0,5,54,0,75,0,0,0,0,5,4,0,25,0,0,22,247,0,0,65,61,0,0,0,1,2,0,0,138],[0,0,0,0,2,35,0,75,0,0,23,117,0,0,97,61,0,0,0,1,2,48,0,57,0,0,0,0,2,50,1,112],[0,0,23,50,0,0,193,61,0,0,0,14,2,0,0,57,0,0,0,0,3,2,4,26,0,0,6,94,4,48,1,151],[0,0,0,1,4,64,0,138,0,0,6,94,5,64,0,156,0,0,23,117,0,0,33,61,0,0,6,119,3,48,1,151],[0,0,0,0,3,52,1,159,0,0,0,0,0,50,4,27,0,0,0,0,3,0,4,20,0,0,0,1,2,48,0,107],[0,0,23,196,0,0,161,61,0,7,0,0,0,3,0,29,0,0,0,0,2,10,4,51,0,0,0,0,3,2,0,75],[0,0,23,65,0,0,97,61,0,0,0,0,3,0,0,25,0,0,0,0,4,19,0,25,0,0,0,32,3,48,0,57],[0,0,0,0,5,163,0,25,0,0,0,0,5,5,4,51,0,0,0,0,0,84,4,53,0,0,0,0,4,35,0,75],[0,0,23,58,0,0,65,61,0,0,0,0,3,18,0,25,0,0,0,0,0,3,4,53,0,0,6,86,4,0,0,65],[0,0,6,86,3,16,0,156,0,0,0,0,1,4,128,25,0,0,0,64,1,16,2,16,0,0,6,86,3,32,0,156],[0,0,0,0,2,4,128,25,0,0,0,96,2,32,2,16,0,0,0,0,1,18,1,159,0,0,0,0,2,0,4,20],[0,0,6,86,3,32,0,156,0,0,0,0,2,4,128,25,0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159],[0,0,6,117,1,16,1,199,0,0,128,16,2,0,0,57,25,83,25,78,0,0,4,15,0,0,0,1,2,32,1,144],[0,0,23,121,0,0,97,61,0,0,0,7,3,0,0,41,0,0,0,1,2,48,0,105,0,0,0,0,5,1,4,59],[0,0,0,64,1,0,4,61,0,0,0,0,0,33,4,53,0,0,0,0,2,0,4,20,0,0,6,86,3,32,0,156],[0,0,6,86,4,0,0,65,0,0,0,0,2,4,128,25,0,0,6,86,3,16,0,156,0,0,0,0,1,4,128,25],[0,0,0,64,1,16,2,16,0,0,0,192,2,32,2,16,0,0,0,0,1,18,1,159,0,0,6,127,1,16,1,199],[0,0,128,13,2,0,0,57,0,0,0,2,3,0,0,57,0,0,6,128,4,0,0,65,25,83,25,73,0,0,4,15],[0,0,0,1,1,32,1,144,0,0,23,121,0,0,97,61,0,0,0,0,0,1,4,45,0,0,6,224,1,0,0,65],[0,0,0,0,0,16,4,53,0,0,0,50,1,0,0,57,0,0,0,4,0,16,4,63,0,0,6,166,1,0,0,65],[0,0,25,85,0,1,4,48,0,0,6,224,1,0,0,65,0,0,0,0,0,16,4,53,0,0,0,65,1,0,0,57],[0,0,23,110,0,0,1,61,0,0,6,224,1,0,0,65,0,0,0,0,0,16,4,53,0,0,0,17,1,0,0,57],[0,0,23,110,0,0,1,61,0,0,0,0,1,0,0,25,0,0,25,85,0,1,4,48,0,0,0,31,2,48,1,143],[0,0,0,5,4,48,2,114,0,0,23,135,0,0,97,61,0,0,0,0,5,0,0,25,0,0,0,5,6,80,2,16],[0,0,0,0,7,106,0,25,0,0,0,0,6,97,3,79,0,0,0,0,6,6,4,59,0,0,0,0,0,103,4,53],[0,0,0,1,5,80,0,57,0,0,0,0,6,69,0,75,0,0,23,127,0,0,65,61,0,0,0,0,5,2,0,75],[0,0,23,150,0,0,97,61,0,0,0,5,4,64,2,16,0,0,0,0,1,65,3,79,0,0,0,0,4,74,0,25],[0,0,0,3,2,32,2,16,0,0,0,0,5,4,4,51,0,0,0,0,5,37,1,207,0,0,0,0,5,37,2,47],[0,0,0,0,1,1,4,59,0,0,1,0,2,32,0,137,0,0,0,0,1,33,2,47,0,0,0,0,1,33,1,207],[0,0,0,0,1,81,1,159,0,0,0,0,0,20,4,53,0,0,6,86,1,0,0,65,0,0,6,86,2,160,0,156],[0,0,0,0,10,1,128,25,0,0,0,64,1,160,2,16,0,0,23,187,0,0,1,61,0,0,0,64,2,0,4,61],[0,0,0,31,4,48,1,143,0,0,0,5,5,48,2,114,0,0,23,168,0,0,97,61,0,0,0,0,6,0,0,25],[0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59],[0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,23,160,0,0,65,61],[0,0,0,0,6,4,0,75,0,0,23,183,0,0,97,61,0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79],[0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207],[0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47],[0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,6,86,1,0,0,65],[0,0,6,86,4,32,0,156,0,0,0,0,2,1,128,25,0,0,0,64,1,32,2,16,0,0,0,96,2,48,2,16],[0,0,0,0,1,33,1,159,0,0,25,85,0,1,4,48,0,0,0,68,2,16,0,57,0,0,6,178,3,0,0,65],[0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57,0,0,0,1,3,0,0,57,0,0,23,201,0,0,1,61],[0,0,0,68,2,16,0,57,0,0,6,125,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,36,2,16,0,57],[0,0,0,18,3,0,0,57,0,0,0,0,0,50,4,53,0,0,6,98,2,0,0,65,0,0,0,0,0,33,4,53],[0,0,0,4,2,16,0,57,0,0,0,2,3,0,0,41,0,0,0,0,0,50,4,53,0,0,6,86,2,0,0,65],[0,0,6,86,3,16,0,156,0,0,0,0,1,2,128,25,0,0,0,64,1,16,2,16,0,0,6,126,1,16,1,199],[0,0,25,85,0,1,4,48,0,2,0,0,0,0,0,2,0,0,6,87,1,0,0,65,0,0,0,0,0,16,4,57],[0,0,0,0,1,0,4,16,0,2,0,0,0,1,0,29,0,0,0,4,0,16,4,67,0,0,6,86,1,0,0,65],[0,0,0,0,2,0,4,20,0,0,6,86,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16],[0,0,6,88,1,16,1,199,0,0,128,2,2,0,0,57,25,83,25,78,0,0,4,15,0,0,0,1,2,32,1,144],[0,0,24,53,0,0,97,61,0,0,0,0,1,1,4,59,0,0,0,0,1,1,0,75,0,0,24,54,0,0,97,61],[0,0,0,64,5,0,4,61,0,0,6,161,1,0,0,65,0,0,0,0,0,21,4,53,0,0,0,0,1,0,4,20],[0,0,0,2,4,0,0,41,0,0,0,4,2,64,0,140,0,0,24,4,0,0,97,61,0,0,6,86,2,0,0,65],[0,0,6,86,3,16,0,156,0,0,0,0,1,2,128,25,0,0,6,86,3,80,0,156,0,0,0,0,2,5,64,25],[0,0,0,64,2,32,2,16,0,0,0,192,1,16,2,16,0,0,0,0,1,33,1,159,0,0,6,135,1,16,1,199],[0,0,0,0,2,4,0,25,0,1,0,0,0,5,0,29,25,83,25,73,0,0,4,15,0,0,0,1,5,0,0,41],[0,0,0,2,4,0,0,41,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112,0,1,6,86,0,48,1,157],[0,0,6,86,3,48,1,151,0,3,0,0,0,1,3,85,0,0,0,1,2,32,1,144,0,0,24,62,0,0,97,61],[0,0,6,93,1,80,0,156,0,0,24,56,0,0,129,61,0,0,0,64,0,80,4,63,0,0,6,87,1,0,0,65],[0,0,0,0,0,16,4,57,0,0,0,4,0,64,4,67,0,0,6,86,1,0,0,65,0,0,0,0,2,0,4,20],[0,0,6,86,3,32,0,156,0,0,0,0,2,1,128,25,0,0,0,192,1,32,2,16,0,0,6,88,1,16,1,199],[0,0,128,2,2,0,0,57,25,83,25,78,0,0,4,15,0,0,0,1,2,32,1,144,0,0,24,53,0,0,97,61],[0,0,0,0,1,1,4,59,0,0,0,0,1,1,0,75,0,0,24,54,0,0,97,61,0,0,0,64,5,0,4,61],[0,0,6,162,1,0,0,65,0,0,0,0,0,21,4,53,0,0,0,0,1,0,4,20,0,0,0,2,2,0,0,41],[0,0,0,4,3,32,0,140,0,0,24,49,0,0,97,61,0,0,6,86,4,0,0,65,0,0,6,86,3,16,0,156],[0,0,0,0,1,4,128,25,0,0,6,86,3,80,0,156,0,0,0,0,4,5,64,25,0,0,0,64,3,64,2,16],[0,0,0,192,1,16,2,16,0,0,0,0,1,49,1,159,0,0,6,135,1,16,1,199,0,2,0,0,0,5,0,29],[25,83,25,73,0,0,4,15,0,0,0,2,5,0,0,41,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112],[0,1,6,86,0,48,1,157,0,0,6,86,3,48,1,151,0,3,0,0,0,1,3,85,0,0,0,1,2,32,1,144],[0,0,24,91,0,0,97,61,0,0,6,94,1,80,0,156,0,0,24,56,0,0,33,61,0,0,0,64,0,80,4,63],[0,0,0,0,0,1,4,45,0,0,0,0,0,1,4,47,0,0,0,0,1,0,0,25,0,0,25,85,0,1,4,48],[0,0,6,224,1,0,0,65,0,0,0,0,0,16,4,53,0,0,0,65,1,0,0,57,0,0,0,4,0,16,4,63],[0,0,6,166,1,0,0,65,0,0,25,85,0,1,4,48,0,0,0,64,2,0,4,61,0,0,0,31,4,48,1,143],[0,0,0,5,5,48,2,114,0,0,24,75,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16],[0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53],[0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,24,67,0,0,65,61,0,0,0,0,6,4,0,75],[0,0,24,119,0,0,97,61,0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25],[0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47],[0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207],[0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,24,119,0,0,1,61,0,0,0,64,2,0,4,61],[0,0,0,31,4,48,1,143,0,0,0,5,5,48,2,114,0,0,24,104,0,0,97,61,0,0,0,0,6,0,0,25],[0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25,0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59],[0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57,0,0,0,0,7,86,0,75,0,0,24,96,0,0,65,61],[0,0,0,0,6,4,0,75,0,0,24,119,0,0,97,61,0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79],[0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16,0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207],[0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59,0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47],[0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159,0,0,0,0,0,21,4,53,0,0,6,86,1,0,0,65],[0,0,6,86,4,32,0,156,0,0,0,0,2,1,128,25,0,0,0,64,1,32,2,16,0,0,0,96,2,48,2,16],[0,0,0,0,1,33,1,159,0,0,25,85,0,1,4,48,0,0,0,64,2,0,4,61,0,0,6,230,1,32,0,156],[0,0,24,183,0,0,129,61,0,0,0,192,1,32,0,57,0,0,0,64,0,16,4,63,0,0,0,160,1,32,0,57],[0,0,6,130,3,0,0,65,0,0,0,0,0,49,4,53,0,0,0,128,3,32,0,57,0,0,6,131,1,0,0,65],[0,0,0,0,0,19,4,53,0,0,0,96,3,32,0,57,0,0,0,0,0,19,4,53,0,0,0,64,3,32,0,57],[0,0,0,0,0,19,4,53,0,0,0,32,3,32,0,57,0,0,0,0,0,19,4,53,0,0,0,135,3,0,0,57],[0,0,0,0,0,50,4,53,0,0,0,64,2,0,4,61,0,0,6,129,3,32,0,156,0,0,24,183,0,0,33,61],[0,0,0,192,3,32,0,57,0,0,0,64,0,48,4,63,0,0,0,160,3,32,0,57,0,0,6,132,4,0,0,65],[0,0,0,0,0,67,4,53,0,0,0,128,3,32,0,57,0,0,0,0,0,19,4,53,0,0,0,96,3,32,0,57],[0,0,0,0,0,19,4,53,0,0,0,64,3,32,0,57,0,0,0,0,0,19,4,53,0,0,0,32,3,32,0,57],[0,0,0,0,0,19,4,53,0,0,0,136,1,0,0,57,0,0,0,0,0,18,4,53,0,0,0,64,1,0,4,61],[0,0,6,129,2,16,0,156,0,0,24,183,0,0,33,61,0,0,0,192,2,16,0,57,0,0,0,64,0,32,4,63],[0,0,0,160,2,16,0,57,0,0,6,133,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,128,2,16,0,57],[0,0,6,131,3,0,0,65,0,0,0,0,0,50,4,53,0,0,0,96,2,16,0,57,0,0,0,0,0,50,4,53],[0,0,0,64,2,16,0,57,0,0,0,0,0,50,4,53,0,0,0,32,2,16,0,57,0,0,0,0,0,50,4,53],[0,0,0,137,2,0,0,57,0,0,0,0,0,33,4,53,0,0,0,0,0,1,4,45,0,0,6,224,1,0,0,65],[0,0,0,0,0,16,4,53,0,0,0,65,1,0,0,57,0,0,0,4,0,16,4,63,0,0,6,166,1,0,0,65],[0,0,25,85,0,1,4,48,0,1,0,0,0,0,0,2,0,0,0,64,7,0,4,61,0,0,6,120,2,0,0,65],[0,0,0,0,0,39,4,53,0,0,0,4,2,112,0,57,0,0,0,32,3,0,0,57,0,0,0,0,0,50,4,53],[0,0,0,0,2,1,4,51,0,0,0,36,3,112,0,57,0,0,0,0,0,35,4,53,0,0,0,68,3,112,0,57],[0,0,0,0,4,2,0,75,0,0,24,210,0,0,97,61,0,0,0,0,4,0,0,25,0,0,0,0,5,52,0,25],[0,0,0,32,4,64,0,57,0,0,0,0,6,20,0,25,0,0,0,0,6,6,4,51,0,0,0,0,0,101,4,53],[0,0,0,0,5,36,0,75,0,0,24,203,0,0,65,61,0,0,0,0,1,50,0,25,0,0,0,0,0,1,4,53],[0,0,0,31,1,32,0,57,0,0,0,32,2,0,0,138,0,0,0,0,1,33,1,111,0,0,6,86,2,0,0,65],[0,0,6,86,3,112,0,156,0,0,0,0,3,2,0,25,0,0,0,0,3,7,64,25,0,0,0,64,3,48,2,16],[0,0,0,68,1,16,0,57,0,0,6,86,4,16,0,156,0,0,0,0,1,2,128,25,0,0,0,96,1,16,2,16],[0,0,0,0,1,49,1,159,0,0,0,0,3,0,4,20,0,0,6,86,4,48,0,156,0,0,0,0,3,2,128,25],[0,0,0,192,2,48,2,16,0,0,0,0,1,18,1,159,0,0,128,8,2,0,0,57,0,1,0,0,0,7,0,29],[25,83,25,73,0,0,4,15,0,0,0,1,10,0,0,41,0,0,0,0,3,1,0,25,0,0,0,96,3,48,2,112],[0,0,6,86,3,48,1,151,0,0,0,32,4,48,0,140,0,0,0,0,4,3,0,25,0,0,0,32,4,0,128,57],[0,0,0,31,5,64,1,143,0,0,0,5,6,64,2,114,0,0,24,252,0,0,97,61,0,0,0,0,7,0,0,25],[0,0,0,5,8,112,2,16,0,0,0,0,9,138,0,25,0,0,0,0,8,129,3,79,0,0,0,0,8,8,4,59],[0,0,0,0,0,137,4,53,0,0,0,1,7,112,0,57,0,0,0,0,8,103,0,75,0,0,24,244,0,0,65,61],[0,0,0,0,7,5,0,75,0,0,25,11,0,0,97,61,0,0,0,5,6,96,2,16,0,0,0,0,7,97,3,79],[0,0,0,0,6,106,0,25,0,0,0,3,5,80,2,16,0,0,0,0,8,6,4,51,0,0,0,0,8,88,1,207],[0,0,0,0,8,88,2,47,0,0,0,0,7,7,4,59,0,0,1,0,5,80,0,137,0,0,0,0,7,87,2,47],[0,0,0,0,5,87,1,207,0,0,0,0,5,133,1,159,0,0,0,0,0,86,4,53,0,1,0,0,0,3,0,31],[0,3,0,0,0,1,3,85,0,0,0,1,2,32,1,144,0,0,25,29,0,0,97,61,0,0,0,31,1,64,0,57],[0,0,0,96,2,16,1,143,0,0,0,0,1,162,0,25,0,0,0,0,2,33,0,75,0,0,0,0,2,0,0,25],[0,0,0,1,2,0,64,57,0,0,6,94,4,16,0,156,0,0,25,64,0,0,33,61,0,0,0,1,2,32,1,144],[0,0,25,64,0,0,193,61,0,0,0,64,0,16,4,63,0,0,0,31,1,48,0,140,0,0,25,70,0,0,161,61],[0,0,0,0,0,1,4,45,0,0,0,64,2,0,4,61,0,0,0,31,4,48,1,143,0,0,0,5,5,48,2,114],[0,0,25,42,0,0,97,61,0,0,0,0,6,0,0,25,0,0,0,5,7,96,2,16,0,0,0,0,8,114,0,25],[0,0,0,0,7,113,3,79,0,0,0,0,7,7,4,59,0,0,0,0,0,120,4,53,0,0,0,1,6,96,0,57],[0,0,0,0,7,86,0,75,0,0,25,34,0,0,65,61,0,0,0,0,6,4,0,75,0,0,25,57,0,0,97,61],[0,0,0,5,5,80,2,16,0,0,0,0,1,81,3,79,0,0,0,0,5,82,0,25,0,0,0,3,4,64,2,16],[0,0,0,0,6,5,4,51,0,0,0,0,6,70,1,207,0,0,0,0,6,70,2,47,0,0,0,0,1,1,4,59],[0,0,1,0,4,64,0,137,0,0,0,0,1,65,2,47,0,0,0,0,1,65,1,207,0,0,0,0,1,97,1,159],[0,0,0,0,0,21,4,53,0,0,6,86,1,0,0,65,0,0,6,86,4,32,0,156,0,0,0,0,2,1,128,25],[0,0,0,64,1,32,2,16,0,0,0,96,2,48,2,16,0,0,0,0,1,33,1,159,0,0,25,85,0,1,4,48],[0,0,6,224,1,0,0,65,0,0,0,0,0,16,4,53,0,0,0,65,1,0,0,57,0,0,0,4,0,16,4,63],[0,0,6,166,1,0,0,65,0,0,25,85,0,1,4,48,0,0,0,0,1,0,0,25,0,0,25,85,0,1,4,48],[0,0,0,0,0,1,4,47,0,0,25,76,0,33,4,33,0,0,0,1,2,0,0,57,0,0,0,0,0,1,4,45],[0,0,0,0,2,0,0,25,0,0,0,0,0,1,4,45,0,0,25,81,0,33,4,35,0,0,0,1,2,0,0,57],[0,0,0,0,0,1,4,45,0,0,0,0,2,0,0,25,0,0,0,0,0,1,4,45,0,0,25,83,0,0,4,50],[0,0,25,84,0,1,4,46,0,0,25,85,0,1,4,48,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255],[24,6,170,24,150,187,242,101,104,232,132,167,55,75,65,224,2,80,9,98,202,186,106,21,2,58,141,144,232,80,139,131],[2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,0,0,0,0,0,0],[224,63,225,119,187,5,10,64,234,27,62,205,100,18,26,63,160,99,169,75,109,64,75,47,69,198,70,151,85,94,254,14],[197,210,70,1,134,247,35,60,146,126,125,178,220,199,3,192,229,0,182,83,202,130,39,59,123,250,216,4,93,133,164,112],[153,58,4,183,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,160,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255],[0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,1,0,0,0,0,0,0,0,0,0],[142,148,254,212,66,57,235,35,20,171,122,64,99,69,230,197,168,240,204,237,243,182,0,222,61,0,78,103,44,51,171,244],[0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],[8,195,121,160,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[105,110,32,100,101,108,101,103,97,116,101,32,99,97,108,108,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,128,0,0,0,0,0,0,0,0],[66,203,177,92,205,195,202,214,38,107,14,122,8,192,69,75,35,191,41,220,45,247,75,111,60,32,158,147,54,70,91,209],[2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0],[25,202,228,98,154,45,215,137,0,54,208,209,246,168,39,66,132,91,119,139,113,132,227,141,91,235,253,76,206,59,24,30],[166,174,10,172,21,139,45,92,154,156,146,133,116,52,25,214,42,50,246,114,122,100,9,85,228,206,142,228,21,3,199,132],[255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[120,119,167,151,254,109,202,67,33,243,63,217,84,20,218,7,154,183,142,105,141,118,21,20,192,28,237,146,17,175,38,126],[254,23,59,151,237,154,162,99,35,108,82,250,62,179,52,208,119,65,173,217,94,151,45,23,53,45,118,129,107,74,174,163],[154,138,5,146,172,137,197,173,59,198,223,130,36,193,123,72,89,118,245,151,223,16,78,226,13,13,244,21,36,31,103,11],[121,107,137,185,22,68,188,152,205,147,149,142,76,144,56,39,93,98,33,131,226,90,197,175,8,204,107,93,149,83,145,50],[147,139,95,50,153,161,243,177,142,69,133,100,239,187,149,7,51,34,96,20,238,206,38,250,225,144,18,216,80,180,141,131],[255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,95],[116,104,101,32,105,110,100,117,115,116,114,121,39,115,32,115,116,97,110,100,97,114,100,46,46,46,0,0,0,0,0,0],[32,105,110,100,117,115,116,114,121,46,32,76,111,114,101,109,32,73,112,115,117,109,32,104,97,115,32,98,101,101,110,32],[32,111,102,32,116,104,101,32,112,114,105,110,116,105,110,103,32,97,110,100,32,116,121,112,101,115,101,116,116,105,110,103],[76,111,114,101,109,32,73,112,115,117,109,32,105,115,32,115,105,109,112,108,121,32,100,117,109,109,121,32,116,101,120,116],[2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[215,182,153,1,5,113,145,1,218,190,183,113,68,242,163,56,92,128,51,172,211,175,151,233,66,58,105,94,129,173,30,181],[255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0],[98,248,75,36,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[215,182,153,1,5,113,145,1,218,190,183,113,68,242,163,56,92,128,51,172,211,175,151,233,66,58,105,94,129,173,30,180],[215,182,153,1,5,113,145,1,218,190,183,113,68,242,163,56,92,128,51,172,211,175,151,233,66,58,105,94,129,173,30,183],[215,182,153,1,5,113,145,1,218,190,183,113,68,242,163,56,92,128,51,172,211,175,151,233,66,58,105,94,129,173,30,182],[128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[83,111,109,101,32,101,114,114,111,114,32,109,101,115,115,97,103,101,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,0,0,0,0,0,0,0,0,0],[2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0],[133,189,45,42,160,229,82,140,202,50,72,223,177,233,146,208,17,58,85,56,2,215,146,79,223,4,154,233,237,29,91,48],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,63],[97,97,97,97,97,97,97,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97],[97,97,97,97,97,97,97,97,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[97,97,97,97,97,97,97,97,97,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[102,3,194,241,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0],[72,101,97,112,32,115,104,111,117,108,100,32,110,111,116,32,98,101,32,109,111,100,105,102,105,101,100,0,0,0,0,0],[171,37,105,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,159],[20,67,19,57,18,139,210,95,44,127,147,186,166,17,227,103,71,32,72,117,127,74,214,127,109,113,165,202,13,165,80,245],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,127],[28,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[70,234,191,53,104,3,40,226,110,244,87,156,175,138,235,44,249,236,224,93,191,103,164,243,209,242,140,123,29,14,53,70],[81,228,219,187,206,186,222,105,90,63,15,223,16,190,184,181,248,63,218,22,30,26,49,5,161,76,65,22,139,243,220,224],[0,0,0,0,0,0,0,0,0,0,0,0,127,139,59,4,191,52,97,143,74,23,35,251,169,107,93,178,17,39,154,43],[224,104,47,212,162,96,50,175,255,59,24,5,58,12,51,210,166,196,101,192,225,156,177,228,193,14,176,169,73,242,130,124],[11,219,95,10,199,157,26,126,253,194,85,243,153,160,69,3,140,27,67,62,157,6,193,177,171,213,138,95,202,171,51,241],[196,108,220,80,166,111,77,7,198,233,161,39,167,39,126,136,47,178,27,207,181,176,104,242,181,140,127,114,131,153,59,121],[0,0,0,0,0,0,0,0,0,0,0,0,8,101,167,125,77,104,199,227,205,210,25,212,49,207,238,146,113,144,80,116],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0],[46,56,93,100,142,59,225,148,212,95,187,31,114,41,239,16,197,183,238,28,124,48,20,90,164,221,249,56,14,171,90,3],[155,55,233,20,69,233,43,20,35,53,72,37,170,51,216,65,216,60,172,253,216,149,211,22,174,136,218,188,49,115,105,150],[0,0,0,0,0,0,0,0,0,0,0,0,158,21,153,225,16,206,239,79,21,232,238,112,106,217,205,74,91,142,198,237],[221,105,233,149,15,82,221,220,188,103,81,253,187,105,73,120,124,193,184,74,196,2,10,176,97,126,200,173,149,14,85,74],[27,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[64,104,245,181,230,196,180,66,232,63,203,123,98,144,82,14,187,94,7,124,209,13,59,216,108,244,49,202,75,100,1,98],[176,9,134,216,187,82,238,122,203,6,202,191,166,194,192,153,216,144,76,124,141,86,112,122,38,125,219,175,215,174,208,112],[222,36,37,129,75,195,76,70,242,125,90,200,53,42,194,120,152,251,22,36,71,137,39,215,0,176,92,214,240,227,180,58],[197,97,156,222,156,163,223,139,22,168,181,115,26,106,182,110,82,122,176,220,60,175,49,157,70,253,64,248,50,252,227,74],[172,234,161,127,251,123,250,254,21,226,192,38,128,20,0,86,72,84,201,131,154,22,101,182,95,24,178,40,221,85,235,205],[0,0,0,0,0,0,0,0,0,0,0,0,124,173,80,73,162,188,160,49,198,228,85,140,144,41,227,102,58,220,148,142],[211,243,158,103,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[66,32,205,118,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,3,232,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,255,255,255,224],[77,226,228,104,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,36,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,191],[67,111,100,101,79,114,97,99,108,101,32,99,97,108,108,32,102,97,105,108,101,100,0,0,0,0,0,0,0,0,0,0],[100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[68,101,99,111,109,109,105,116,109,101,110,116,32,99,111,115,116,32,119,97,115,110,116,32,97,109,111,114,116,105,122,101],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238,238],[102,97,105,108,101,100,32,116,114,97,110,115,102,101,114,32,99,97,108,108,0,0,0,0,0,0,0,0,0,0,0,0],[102,97,105,108,101,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[115,101,110,100,105,110,103,32,108,49,32,109,101,115,115,97,103,101,115,32,116,101,115,116,32,115,104,111,117,108,100,32],[104,101,97,112,32,116,101,115,116,32,115,104,111,117,108,100,32,102,97,105,108,101,100,0,0,0,0,0,0,0,0,0],[72,101,97,112,32,115,104,111,117,108,100,32,110,111,116,32,98,101,32,101,109,112,116,121,0,0,0,0,0,0,0,0],[119,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,70,249,29],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,175,100,13,14],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,208,127,66,15],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,246,42,183],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,230,246,42,184],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,251,56,170,86],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,208,127,66,16],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,211,243,158,103],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,175,100,13,15],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,190,139,17,32],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,198,249,104,132],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,135,78,143,142],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,153,58,4,182],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,153,58,4,183],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,171,37,105,15],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,135,78,143,143],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,147,174,83,70],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,103,70,249,30],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,119,55,221,231],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,213,148,97],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,208,170,240],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,87,154,227,235],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,94,254,75,179],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,94,254,75,180],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,102,3,194,241],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,87,154,227,236],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,89,48,143,15],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,51,208,170,241],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,66,32,205,118],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,72,64,160,81],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25,216,172,96],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,25,216,172,97],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,34,132,79,188],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,42,187,215,72],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,208,93,63],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,77,67,16],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,183,38,49],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,128,0,0,0,0,0,0,0,0],[84,104,101,32,118,97,108,117,101,32,105,110,32,116,114,97,110,115,105,101,110,116,32,115,116,111,114,97,103,101,32,105],[115,32,110,111,116,32,119,104,97,116,32,119,97,115,32,101,120,112,101,99,116,101,100,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,132,0,0,0,128,0,0,0,0,0,0,0,0],[84,101,115,116,32,109,101,115,115,97,103,101,32,50,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,0,0,0,128,0,0,0,0,0,0,0,0],[62,169,138,246,227,81,65,251,202,204,23,36,225,79,93,118,185,181,142,65,246,195,93,14,138,226,226,4,230,102,149,235],[84,104,105,115,32,109,101,116,104,111,100,32,97,108,119,97,121,115,32,114,101,118,101,114,116,115,0,0,0,0,0,0],[78,72,123,113,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[103,70,249,30,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,68,0,0,0,0,0,0,0,0,0,0,0,0],[208,127,66,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[84,104,101,32,99,97,108,108,32,115,104,111,117,108,100,32,104,97,118,101,32,102,97,105,108,101,100,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,160],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,64],[246,238,190,171,224,135,139,78,225,22,236,14,189,243,137,181,100,71,233,145,192,87,59,242,118,52,253,55,47,152,163,196],[112,134,164,241,173,132,202,164,176,88,116,111,203,82,28,181,97,129,88,209,207,156,76,91,121,198,230,11,97,218,64,154],[210,162,228,96,106,47,165,99,156,127,151,232,109,33,140,136,82,91,164,227,17,75,162,206,135,176,211,80,117,20,194,101],[28,203,233,28,7,95,199,244,240,51,191,162,72,219,143,204,211,86,93,233,75,191,177,47,60,89,255,70,194,113,191,131],[206,64,20,198,136,17,249,162,26,31,219,44,14,97,19,224,109,183,202,147,183,64,78,120,220,124,205,92,168,154,76,169],[255,255,255,255,0,0,0,0,255,255,255,255,255,255,255,255,188,230,250,173,167,23,158,132,243,185,202,194,252,99,37,81],[98,117,116,32,115,117,99,99,101,101,100,101,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[80,50,53,54,32,86,101,114,105,102,121,32,115,104,111,117,108,100,32,104,97,118,101,32,102,97,105,108,101,100,44,32],[45,93,27,158,149,208,90,157,99,128,104,23,146,222,115,119,106,139,85,202,149,203,251,182,108,8,247,114,135,78,98,236],[80,50,53,54,32,86,101,114,105,102,121,32,104,97,115,32,102,97,105,108,101,100,0,0,0,0,0,0,0,0,0,0],[100,44,32,98,117,116,32,102,97,105,108,101,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[80,50,53,54,32,86,101,114,105,102,121,32,115,104,111,117,108,100,32,104,97,118,101,32,115,117,99,99,101,101,100,101],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0],[0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255],[254,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,255,255],[112,113,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[32,116,104,101,32,101,120,112,101,99,116,101,100,32,104,97,115,104,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[82,101,116,117,114,110,101,100,32,98,121,116,101,99,111,100,101,32,100,111,101,115,32,110,111,116,32,109,97,116,99,104],[116,119,101,101,110,32,116,119,111,32,99,97,108,108,115,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[68,101,99,111,109,109,105,116,109,101,110,116,32,99,111,115,116,32,119,97,115,110,116,32,101,113,117,97,108,32,98,101],[112,115,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[112,112,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,96],[128,137,191,37,238,147,34,244,143,45,218,177,28,206,250,96,96,242,96,216,66,28,39,113,96,107,205,238,78,237,163,243]]} \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/complex_tests/test_artifacts/basic_test_commit_hash b/crates/zkevm_test_harness/src/tests/complex_tests/test_artifacts/basic_test_commit_hash new file mode 100644 index 0000000..e3a2e85 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/complex_tests/test_artifacts/basic_test_commit_hash @@ -0,0 +1 @@ +8d5f6eac7b92f9c5a92dd5668d918fb00249bfb \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/complex_tests/test_artifacts/compiler_metadata b/crates/zkevm_test_harness/src/tests/complex_tests/test_artifacts/compiler_metadata new file mode 100644 index 0000000..7e28949 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/complex_tests/test_artifacts/compiler_metadata @@ -0,0 +1 @@ +{"solc_compiler_version":"v0.8.20","zksolc_compiler_version":"v1.3.18"} \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/complex_tests/test_artifacts/empty_proof.bin b/crates/zkevm_test_harness/src/tests/complex_tests/test_artifacts/empty_proof.bin new file mode 100644 index 0000000000000000000000000000000000000000..f302d76bb19f42c280b366a9a573358839d62d5c GIT binary patch literal 716417 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

rQSI%Q^-2Zh94+%CGw*Hz`c=B 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

oV&FRp8}=X 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%0Ag%>sdJv5JJk%E!xi_5yy&HPJR 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�b9C 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%0Dv>!FQi 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 z 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ⅆYSK0ZW#;mj+byu?gnemf_g*ilA`O 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

&pv!*C9whQ4?ax<=cHe>4E$7FyL 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.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 z�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�T8Jv7=N&b;|*;GG+u$ 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

p$cOpuS>*1Q{vscy*X7rDk@ywRZZ!G}aq z9hBeQ(GI(6z1iS@-}+0W)>CVik~DXdfS?&W{{}AI-j3E@kgX@w_Cy*T%0DP)d42~}hsl|D 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 Jh0DFz{{h()z~cY_ literal 0 HcmV?d00001 diff --git a/crates/zkevm_test_harness/src/tests/complex_tests/test_artifacts/system_contracts_commit_hash b/crates/zkevm_test_harness/src/tests/complex_tests/test_artifacts/system_contracts_commit_hash new file mode 100644 index 0000000..14fb3cd --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/complex_tests/test_artifacts/system_contracts_commit_hash @@ -0,0 +1 @@ +51f5f0a4901216b5d7080ff4461f626956b9b39 \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/complex_tests/test_synthesis.rs b/crates/zkevm_test_harness/src/tests/complex_tests/test_synthesis.rs new file mode 100644 index 0000000..53d2de1 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/complex_tests/test_synthesis.rs @@ -0,0 +1,36 @@ +use crate::boojum::worker::Worker; +use crate::prover_utils::create_base_layer_setup_data; +use crate::tests::complex_tests::generate_base_layer; +use crate::tests::complex_tests::utils::read_basic_test_artifact; +use circuit_definitions::boojum::field::goldilocks::GoldilocksField; +use circuit_definitions::zkevm_circuits::eip_4844::input::ENCODABLE_BYTES_PER_BLOB; +use circuit_definitions::{BASE_LAYER_CAP_SIZE, BASE_LAYER_FRI_LDE_FACTOR}; +use std::time::Instant; + +#[test] +fn test_base_layer_circuit_synthesis() { + let test_artifact = read_basic_test_artifact(); + let geometry = crate::geometry_config::get_geometry_config(); + let blobs = std::array::from_fn(|i| { + if i == 0 { + Some(vec![0xff; ENCODABLE_BYTES_PER_BLOB]) + } else { + None + } + }); + let (base_layer_circuit, _, _) = generate_base_layer(test_artifact, 40000, geometry, blobs); + let circuit = base_layer_circuit + .into_iter() + .next() + .expect("failed to get circuit"); + let worker = Worker::new_with_num_threads(8); + let (_, _, _, _, _, _, finalization_hint) = create_base_layer_setup_data( + circuit.clone(), + &worker, + BASE_LAYER_FRI_LDE_FACTOR, + BASE_LAYER_CAP_SIZE, + ); + let started_at = Instant::now(); + circuit.synthesis::(&finalization_hint); + println!("synthesis took {:?}", started_at.elapsed()); +} diff --git a/crates/zkevm_test_harness/src/tests/complex_tests/testing_wrapper.rs b/crates/zkevm_test_harness/src/tests/complex_tests/testing_wrapper.rs new file mode 100644 index 0000000..9e0c5e3 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/complex_tests/testing_wrapper.rs @@ -0,0 +1,139 @@ +use super::*; + +use crate::proof_wrapper_utils::WrapperConfig; +use crate::proof_wrapper_utils::{ + compress_stark_pi_to_snark_pi, compute_compression_circuits, + compute_compression_for_wrapper_circuit, compute_wrapper_proof_and_vk, +}; + +use snark_wrapper::franklin_crypto::bellman::worker::Worker as BellmanWorker; + +pub(crate) fn test_compression_for_compression_num(config: WrapperConfig) { + let worker = Worker::new(); + let bellman_worker = BellmanWorker::new(); + + let mut file_source = LocalFileDataSource::default(); + file_source.create_folders_for_storing_data(); + let mut source = InMemoryDataSource::new(); + + // Load scheduler proof and vk + source + .set_scheduler_proof(file_source.get_scheduler_proof().unwrap()) + .unwrap(); + source + .set_recursion_layer_vk( + file_source + .get_recursion_layer_vk(ZkSyncRecursionLayerStorageType::SchedulerCircuit as u8) + .unwrap(), + ) + .unwrap(); + + compute_compression_circuits(&mut source, config, &worker); + compute_compression_for_wrapper_circuit(&mut source, config, &worker); + compute_wrapper_proof_and_vk(&mut source, config, &bellman_worker); + + // Write wrapper proof and vk + let wrapper_type = config.get_wrapper_type(); + file_source + .set_wrapper_proof(source.get_wrapper_proof(wrapper_type).unwrap()) + .unwrap(); + file_source + .set_wrapper_vk(source.get_wrapper_vk(wrapper_type).unwrap()) + .unwrap(); +} + +pub(crate) fn test_wrapper_pi_inner( + source: &mut DS, + config: WrapperConfig, +) { + let scheduler_proof = source + .get_scheduler_proof() + .expect("scheduler proof should be present") + .into_inner(); + + let wrapper_type = config.get_wrapper_type(); + let wrapper_proof = source + .get_wrapper_proof(wrapper_type) + .expect("wrapper proof should be present") + .into_inner(); + + let scheduler_pi = scheduler_proof.public_inputs.try_into().unwrap(); + let wrapper_pi = wrapper_proof.inputs[0]; + assert!(wrapper_proof.inputs.len() == 1); + + let expected_wrapper_pi = compress_stark_pi_to_snark_pi(scheduler_pi); + assert_eq!(expected_wrapper_pi, wrapper_pi); +} + +#[ignore = "broken test"] +#[test] +fn test_wrapper_pi() { + let config = get_testing_wrapper_config(); + + let mut source = LocalFileDataSource::default(); + source.create_folders_for_storing_data(); + + test_wrapper_pi_inner(&mut source, config); +} + +#[test] +fn test_pi_aggregation_function() { + use crate::zkevm_circuits::scheduler::NUM_SCHEDULER_PUBLIC_INPUTS; + use circuit_definitions::boojum::field::goldilocks::GoldilocksField; + use circuit_definitions::boojum::field::{Field, PrimeField, U64Representable}; + use rand::Rng; + + let input_keccak_hash = rand::thread_rng().gen::<[u8; 32]>(); + + // almost code from scheduler: + let take_by = GoldilocksField::CAPACITY_BITS / 8; + + let mut pi = vec![]; + for chunk in input_keccak_hash + .chunks_exact(take_by) + .take(NUM_SCHEDULER_PUBLIC_INPUTS) + { + let mut lc = GoldilocksField::ZERO; + // treat as BE + for (idx, el) in chunk.iter().rev().enumerate() { + let mut el = GoldilocksField::from_u64(*el as u64).unwrap(); + el.mul_assign(&GoldilocksField::from_u64(1 << (idx * 8)).unwrap()); + lc.add_assign(&el); + } + pi.push(lc); + } + + let wrapper_pi = compress_stark_pi_to_snark_pi(pi.try_into().unwrap()); + + println!("{:x?}", input_keccak_hash); + println!("{:?}", wrapper_pi); +} + +#[ignore = "broken test"] +#[test] +fn test_wrapper_vk_generation() { + let config = get_testing_wrapper_config(); + + let mut source = LocalFileDataSource::default(); + source.create_folders_for_storing_data(); + + let scheduler_vk = source + .get_recursion_layer_vk(ZkSyncRecursionLayerStorageType::SchedulerCircuit as u8) + .unwrap(); + + use crate::proof_wrapper_utils::get_wrapper_setup_and_vk_from_scheduler_vk; + let (_, wrapper_vk) = get_wrapper_setup_and_vk_from_scheduler_vk(scheduler_vk, config); + + source.set_wrapper_vk(wrapper_vk).unwrap(); +} + +pub(crate) fn get_testing_wrapper_config() -> WrapperConfig { + let compression = + std::env::var("COMPRESSION_NUM").map(|s| s.parse::().expect("should be a number")); + + if let Ok(compression) = compression { + WrapperConfig::new(compression as u8) + } else { + DEFAULT_WRAPPER_CONFIG + } +} diff --git a/crates/zkevm_test_harness/src/tests/complex_tests/utils.rs b/crates/zkevm_test_harness/src/tests/complex_tests/utils.rs new file mode 100644 index 0000000..62a3a1b --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/complex_tests/utils.rs @@ -0,0 +1,24 @@ +use circuit_definitions::circuit_definitions::recursion_layer::ZkSyncRecursionLayerProof; + +use crate::{ + data_source::{local_file_data_source::LocalFileDataSource, BlockDataSource}, + helper::artifact_utils::TestArtifact, +}; +use std::fs::{self, File}; + +const BASIC_TEST_JSON_LOCATION: &str = "src/tests/complex_tests/test_artifacts/basic_test.json"; + +// Reads the example basic artifact. +// To regenerate, please follow README in https://github.com/matter-labs/test-contract/tree/v1.5.0 +#[allow(dead_code)] +pub fn read_basic_test_artifact() -> TestArtifact { + let basic_test_bytes = fs::read(BASIC_TEST_JSON_LOCATION).expect("failed reading file"); + let text = std::str::from_utf8(&basic_test_bytes) + .expect("basic test json should be utf8 encoded string"); + serde_json::from_str(text).unwrap() +} + +// Returns an 'empty' node proof, that can be used in cases where we don't have any basic (and node) circuits of a given type. +pub fn empty_node_proof() -> ZkSyncRecursionLayerProof { + bincode::deserialize_from(&include_bytes!("test_artifacts/empty_proof.bin")[..]).unwrap() +} diff --git a/crates/zkevm_test_harness/src/tests/complex_tests/wrapper_negative_tests.rs b/crates/zkevm_test_harness/src/tests/complex_tests/wrapper_negative_tests.rs new file mode 100644 index 0000000..0b2f1a5 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/complex_tests/wrapper_negative_tests.rs @@ -0,0 +1,205 @@ +use super::*; + +use crate::boojum::field::{ExtensionField, Field}; +use crate::data_source::{ + local_file_data_source::LocalFileDataSource, BlockDataSource, SetupDataSource, +}; +use crate::proof_wrapper_utils::{ + compute_compression_circuits, compute_compression_for_wrapper_circuit, + compute_compression_for_wrapper_vk_and_write, compute_compression_vks_and_write, WrapperConfig, +}; +use crate::snark_wrapper::franklin_crypto::bellman::Field as BellmanField; +use crate::tests::complex_tests::testing_wrapper::get_testing_wrapper_config; +use crate::tests::{ + Worker, ZkSyncCompressionForWrapperProof, ZkSyncCompressionForWrapperVerificationKey, +}; + +fn get_compression_for_wrapper_vk_for_testing( + config: WrapperConfig, +) -> ZkSyncCompressionForWrapperVerificationKey { + let mut source = LocalFileDataSource::default(); + + let compression_for_wrapper_type = config.get_compression_for_wrapper_type(); + if source + .get_compression_for_wrapper_vk(compression_for_wrapper_type) + .is_err() + { + // Scheduler vk should be present! + let worker = Worker::new(); + // 1. All but one layers of compression with Goldilocks Poseidon2 hash + compute_compression_vks_and_write(&mut source, config, &worker); + // 2. Final compression with Bn256 Poseidon2 hash + compute_compression_for_wrapper_vk_and_write(config, &mut source, &worker); + } + + source + .get_compression_for_wrapper_vk(compression_for_wrapper_type) + .unwrap() +} + +fn get_compression_for_wrapper_proof_for_testing( + config: WrapperConfig, +) -> ZkSyncCompressionForWrapperProof { + let mut source = LocalFileDataSource::default(); + + let compression_for_wrapper_type = config.get_compression_for_wrapper_type(); + if source + .get_compression_for_wrapper_proof(compression_for_wrapper_type) + .is_err() + { + // Scheduler vk and proof should be present! + let worker = Worker::new(); + // 1. All but one layers of compression with Goldilocks Poseidon2 hash + compute_compression_circuits(&mut source, config, &worker); + // 2. Final compression with Bn256 Poseidon2 hash + compute_compression_for_wrapper_circuit(&mut source, config, &worker); + } + + source + .get_compression_for_wrapper_proof(compression_for_wrapper_type) + .unwrap() +} + +use crate::proof_wrapper_utils::{ + TranscriptForWrapper, TreeHasherForWrapper, L1_VERIFIER_DOMAIN_SIZE_LOG, +}; + +fn try_to_synthesize_wrapper( + proof: ZkSyncCompressionForWrapperProof, + vk: ZkSyncCompressionForWrapperVerificationKey, + config: WrapperConfig, +) { + let wrapper_type = config.get_wrapper_type(); + + let compression_for_wrapper_type = config.get_compression_for_wrapper_type(); + assert_eq!(compression_for_wrapper_type, proof.numeric_circuit_type()); + assert_eq!(compression_for_wrapper_type, vk.numeric_circuit_type()); + + let proof = proof.into_inner(); + let vk = vk.into_inner(); + + let mut assembly = TrivialAssembly::< + Bn256, + PlonkCsWidth4WithNextStepAndCustomGatesParams, + SelectorOptimizedWidth4MainGateWithDNext, + >::new(); + + let fixed_parameters = vk.fixed_parameters.clone(); + + let wrapper_function = ZkSyncCompressionWrapper::from_numeric_circuit_type(wrapper_type); + let wrapper_circuit = WrapperCircuit::<_, _, TreeHasherForWrapper, TranscriptForWrapper, _> { + witness: Some(proof), + vk: vk, + fixed_parameters, + transcript_params: (), + wrapper_function, + }; + + wrapper_circuit.synthesize(&mut assembly).unwrap(); + + dbg!(assembly.n()); + + assembly.finalize_to_size_log_2(L1_VERIFIER_DOMAIN_SIZE_LOG); + assert!(assembly.is_satisfied()); +} + +#[cfg(test)] +mod wrapper_tests { + use super::*; + + #[ignore = "currently broken"] + #[test] + fn synthesize() { + let config = get_testing_wrapper_config(); + let (proof, vk) = ( + get_compression_for_wrapper_proof_for_testing(config), + get_compression_for_wrapper_vk_for_testing(config), + ); + try_to_synthesize_wrapper(proof, vk, config); + } + + #[test] + #[should_panic] + fn synthesize_with_empty_pi() { + let config = get_testing_wrapper_config(); + let (proof, vk) = ( + get_compression_for_wrapper_proof_for_testing(config), + get_compression_for_wrapper_vk_for_testing(config), + ); + + let mut proof = proof.into_inner(); + proof.public_inputs.clear(); + + let wrapper_type = config.get_wrapper_type(); + let proof = ZkSyncCompressionForWrapperProof::from_inner(wrapper_type, proof); + try_to_synthesize_wrapper(proof, vk, config); + } + + #[test] + #[should_panic] + fn synthesize_with_wrong_pi() { + let config = get_testing_wrapper_config(); + let (proof, vk) = ( + get_compression_for_wrapper_proof_for_testing(config), + get_compression_for_wrapper_vk_for_testing(config), + ); + + let mut proof = proof.into_inner(); + proof.public_inputs[0] = GoldilocksField::ZERO; + + let wrapper_type = config.get_wrapper_type(); + let proof = ZkSyncCompressionForWrapperProof::from_inner(wrapper_type, proof); + try_to_synthesize_wrapper(proof, vk, config); + } + + #[test] + #[should_panic] + fn synthesize_with_wrong_oracle_cap() { + let config = get_testing_wrapper_config(); + let (proof, vk) = ( + get_compression_for_wrapper_proof_for_testing(config), + get_compression_for_wrapper_vk_for_testing(config), + ); + + let mut proof = proof.into_inner(); + proof.stage_2_oracle_cap[0] = Fr::zero(); + + let wrapper_type = config.get_wrapper_type(); + let proof = ZkSyncCompressionForWrapperProof::from_inner(wrapper_type, proof); + try_to_synthesize_wrapper(proof, vk, config); + } + + #[test] + #[should_panic] + fn synthesize_with_wrong_values_at_z() { + let config = get_testing_wrapper_config(); + let (proof, vk) = ( + get_compression_for_wrapper_proof_for_testing(config), + get_compression_for_wrapper_vk_for_testing(config), + ); + + let mut proof = proof.into_inner(); + proof.values_at_z[0] = ExtensionField::ZERO; + + let wrapper_type = config.get_wrapper_type(); + let proof = ZkSyncCompressionForWrapperProof::from_inner(wrapper_type, proof); + try_to_synthesize_wrapper(proof, vk, config); + } + + #[test] + #[should_panic] + fn synthesize_with_wrong_fri_queries() { + let config = get_testing_wrapper_config(); + let (proof, vk) = ( + get_compression_for_wrapper_proof_for_testing(config), + get_compression_for_wrapper_vk_for_testing(config), + ); + + let mut proof = proof.into_inner(); + proof.queries_per_fri_repetition[0].quotient_query.proof[0] = Fr::zero(); + + let wrapper_type = config.get_wrapper_type(); + let proof = ZkSyncCompressionForWrapperProof::from_inner(wrapper_type, proof); + try_to_synthesize_wrapper(proof, vk, config); + } +} diff --git a/crates/zkevm_test_harness/src/tests/mod.rs b/crates/zkevm_test_harness/src/tests/mod.rs new file mode 100644 index 0000000..3c206a4 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/mod.rs @@ -0,0 +1,426 @@ +use super::*; + +pub mod complex_tests; +#[cfg(test)] +pub mod run_manually; +#[cfg(test)] +pub mod simple_tests; +#[cfg(test)] +pub(crate) mod storage; +#[cfg(test)] +pub(crate) mod utils; + +use crate::blake2::Blake2s256; +use crate::boojum::worker::Worker; +use crate::ethereum_types::Address; +use crate::ethereum_types::H160; +use crate::ethereum_types::U256; +use crate::witness::tree::BinarySparseStorageTree; +use crate::witness::tree::ZkSyncStorageLeaf; +use crate::zk_evm::aux_structures::LogQuery; +use crate::zk_evm::bytecode_to_code_hash; +use crate::zk_evm::testing::storage::InMemoryStorage; +use circuit_definitions::circuit_definitions::base_layer::ZkSyncBaseLayerCircuit; +use circuit_definitions::circuit_definitions::recursion_layer::ZkSyncRecursiveLayerCircuit; +use circuit_definitions::ZkSyncDefaultRoundFunction; +use std::alloc::Global; +use std::collections::HashMap; + +const ACCOUNT_CODE_STORAGE_ADDRESS: Address = H160([ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x02, +]); + +const KNOWN_CODE_HASHES_ADDRESS: Address = H160([ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x80, 0x04, +]); + +pub(crate) fn save_predeployed_contracts( + storage: &mut InMemoryStorage, + tree: &mut impl BinarySparseStorageTree<256, 32, 32, 8, 32, Blake2s256, ZkSyncStorageLeaf>, + contracts: &HashMap>, +) { + let mut sorted_contracts = vec![]; + let mut keys: Vec<_> = contracts.keys().cloned().collect(); + keys.sort(); + for el in keys.into_iter() { + let v = contracts[&el].clone(); + + sorted_contracts.push((el, v)); + } + + let storage_logs: Vec<(u8, Address, U256, U256)> = sorted_contracts + .clone() + .into_iter() + .map(|(address, bytecode)| { + let hash = bytecode_to_code_hash(&bytecode).unwrap(); + + println!( + "Have address {:?} with code hash {:x}", + address, + U256::from(hash) + ); + + vec![ + ( + 0, + ACCOUNT_CODE_STORAGE_ADDRESS, + U256::from_big_endian(address.as_bytes()), + U256::from(hash), + ), + ( + 0, + KNOWN_CODE_HASHES_ADDRESS, + U256::from(hash), + U256::from(1u64), + ), + ] + }) + .flatten() + .collect(); + + storage.populate(storage_logs.clone()); + + for (shard_id, address, key, value) in storage_logs.into_iter() { + assert!(shard_id == 0); + let index = LogQuery::derive_final_address_for_params(&address, &key); + + use crate::witness::tree::EnumeratedBinaryLeaf; + let mut leaf = ZkSyncStorageLeaf::empty(); + let mut buffer = [0u8; 32]; + value.to_big_endian(&mut buffer); + leaf.set_value(&buffer); + + tree.insert_leaf(&index, leaf); + } +} + +pub(crate) fn base_test_circuit(circuit: ZkSyncBaseLayerCircuit) { + use crate::boojum::config::DevCSConfig; + use crate::boojum::cs::cs_builder::new_builder; + use crate::boojum::cs::cs_builder_reference::CsReferenceImplementationBuilder; + + type P = GoldilocksField; + // type P = MixedGL; + + let worker = Worker::new(); + + let geometry = circuit.geometry(); + let (max_trace_len, num_vars) = circuit.size_hint(); + + use crate::boojum::config::CSConfig; + let builder_impl = CsReferenceImplementationBuilder::< + GoldilocksField, + P, + DevCSConfig, + crate::boojum::dag::StCircuitResolver< + GoldilocksField, + ::ResolverConfig, + >, + >::new(geometry, max_trace_len.unwrap()); + let arg = num_vars.unwrap(); + let builder = new_builder::<_, GoldilocksField>(builder_impl); + + let mut cs = match circuit { + ZkSyncBaseLayerCircuit::MainVM(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(arg); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + let _ = cs.pad_and_shrink(); + cs.into_assembly::() + } + ZkSyncBaseLayerCircuit::CodeDecommittmentsSorter(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(arg); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + let _ = cs.pad_and_shrink(); + cs.into_assembly::() + } + ZkSyncBaseLayerCircuit::CodeDecommitter(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(arg); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + let _ = cs.pad_and_shrink(); + cs.into_assembly::() + } + ZkSyncBaseLayerCircuit::LogDemuxer(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(arg); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + let _ = cs.pad_and_shrink(); + cs.into_assembly::() + } + ZkSyncBaseLayerCircuit::KeccakRoundFunction(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(arg); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + let _ = cs.pad_and_shrink(); + cs.into_assembly::() + } + ZkSyncBaseLayerCircuit::Sha256RoundFunction(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(arg); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + let _ = cs.pad_and_shrink(); + cs.into_assembly::() + } + ZkSyncBaseLayerCircuit::ECRecover(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(arg); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + let _ = cs.pad_and_shrink(); + cs.into_assembly::() + } + ZkSyncBaseLayerCircuit::RAMPermutation(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(arg); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + let _ = cs.pad_and_shrink(); + cs.into_assembly::() + } + ZkSyncBaseLayerCircuit::StorageSorter(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(arg); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + let _ = cs.pad_and_shrink(); + cs.into_assembly::() + } + ZkSyncBaseLayerCircuit::StorageApplication(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(arg); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + let _ = cs.pad_and_shrink(); + cs.into_assembly::() + } + ZkSyncBaseLayerCircuit::EventsSorter(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(arg); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + let _ = cs.pad_and_shrink(); + cs.into_assembly::() + } + ZkSyncBaseLayerCircuit::L1MessagesSorter(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(arg); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + let _ = cs.pad_and_shrink(); + cs.into_assembly::() + } + ZkSyncBaseLayerCircuit::L1MessagesHasher(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + let _ = cs.pad_and_shrink(); + cs.into_assembly::() + } + ZkSyncBaseLayerCircuit::TransientStorageSorter(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + let _ = cs.pad_and_shrink(); + cs.into_assembly::() + } + ZkSyncBaseLayerCircuit::Secp256r1Verify(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + let _ = cs.pad_and_shrink(); + cs.into_assembly::() + } + ZkSyncBaseLayerCircuit::EIP4844Repack(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables_proxy(&mut cs); + inner.synthesize_proxy(&mut cs); + let _ = cs.pad_and_shrink(); + cs.into_assembly::() + } + }; + + let is_satisfied = cs.check_if_satisfied(&worker); + assert!(is_satisfied); +} + +pub(crate) fn test_recursive_circuit(circuit: ZkSyncRecursiveLayerCircuit) { + use crate::boojum::config::DevCSConfig; + use crate::boojum::cs::cs_builder::new_builder; + use crate::boojum::cs::cs_builder_reference::CsReferenceImplementationBuilder; + + type P = GoldilocksField; + // type P = MixedGL; + + let worker = Worker::new(); + + let geometry = circuit.geometry(); + let (max_trace_len, num_vars) = circuit.size_hint(); + + use crate::boojum::config::CSConfig; + let builder_impl = CsReferenceImplementationBuilder::< + GoldilocksField, + P, + DevCSConfig, + crate::boojum::dag::StCircuitResolver< + GoldilocksField, + ::ResolverConfig, + >, + >::new(geometry, max_trace_len.unwrap()); + let builder = new_builder::<_, GoldilocksField>(builder_impl); + let round_function = ZkSyncDefaultRoundFunction::default(); + + let mut cs = match circuit { + ZkSyncRecursiveLayerCircuit::SchedulerCircuit(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables(&mut cs); + inner.synthesize_into_cs(&mut cs, &round_function); + let _ = cs.pad_and_shrink(); + cs.into_assembly::() + } + ZkSyncRecursiveLayerCircuit::NodeLayerCircuit(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables(&mut cs); + inner.synthesize_into_cs(&mut cs, &round_function); + let _ = cs.pad_and_shrink(); + cs.into_assembly::() + } + ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForMainVM(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForCodeDecommittmentsSorter(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForCodeDecommitter(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForLogDemuxer(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForKeccakRoundFunction(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForSha256RoundFunction(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForECRecover(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForRAMPermutation(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForStorageSorter(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForStorageApplication(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForEventsSorter(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForL1MessagesSorter(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForL1MessagesHasher(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForTransientStorageSorter(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForSecp256r1Verify(inner) + | ZkSyncRecursiveLayerCircuit::LeafLayerCircuitForEIP4844Repack(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables(&mut cs); + inner.synthesize_into_cs(&mut cs, &round_function); + let _ = cs.pad_and_shrink(); + cs.into_assembly::() + } + ZkSyncRecursiveLayerCircuit::RecursionTipCircuit(inner) => { + let builder = inner.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + inner.add_tables(&mut cs); + inner.synthesize_into_cs(&mut cs, &round_function); + let _ = cs.pad_and_shrink(); + cs.into_assembly::() + } + }; + + let is_satisfied = cs.check_if_satisfied(&worker); + assert!(is_satisfied); +} + +use circuit_definitions::circuit_definitions::aux_layer::*; +pub(crate) fn test_compression_circuit(circuit: ZkSyncCompressionLayerCircuit) { + use crate::boojum::config::DevCSConfig; + use crate::boojum::cs::cs_builder::new_builder; + use crate::boojum::cs::cs_builder_reference::CsReferenceImplementationBuilder; + use crate::boojum::cs::implementations::reference_cs::CSReferenceAssembly; + use circuit_definitions::circuit_definitions::aux_layer::compression::CompressionLayerCircuit; + use circuit_definitions::circuit_definitions::aux_layer::compression::ProofCompressionFunction; + + type P = GoldilocksField; + // type P = MixedGL; + + let worker = Worker::new(); + + fn test_inner( + circuit: CompressionLayerCircuit, + ) -> CSReferenceAssembly { + let geometry = circuit.geometry(); + let (max_trace_len, num_vars) = circuit.size_hint(); + let builder_impl = CsReferenceImplementationBuilder::::new( + geometry, + max_trace_len.unwrap(), + ); + let builder = new_builder::<_, GoldilocksField>(builder_impl); + let builder = circuit.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + circuit.synthesize_into_cs(&mut cs); + + cs.pad_and_shrink(); + cs.into_assembly::() + } + + let mut cs = match circuit { + ZkSyncCompressionLayerCircuit::CompressionMode1Circuit(inner) => test_inner(inner), + ZkSyncCompressionLayerCircuit::CompressionMode2Circuit(inner) => test_inner(inner), + ZkSyncCompressionLayerCircuit::CompressionMode3Circuit(inner) => test_inner(inner), + ZkSyncCompressionLayerCircuit::CompressionMode4Circuit(inner) => test_inner(inner), + ZkSyncCompressionLayerCircuit::CompressionMode5Circuit(inner) => test_inner(inner), + }; + + let is_satisfied = cs.check_if_satisfied(&worker); + assert!(is_satisfied); +} + +pub(crate) fn test_compression_for_wrapper_circuit(circuit: ZkSyncCompressionForWrapperCircuit) { + use crate::boojum::config::DevCSConfig; + use crate::boojum::cs::cs_builder::new_builder; + use crate::boojum::cs::cs_builder_reference::CsReferenceImplementationBuilder; + use crate::boojum::cs::implementations::reference_cs::CSReferenceAssembly; + use circuit_definitions::circuit_definitions::aux_layer::compression::CompressionLayerCircuit; + use circuit_definitions::circuit_definitions::aux_layer::compression::ProofCompressionFunction; + + type P = GoldilocksField; + // type P = MixedGL; + + let worker = Worker::new(); + + fn test_inner( + circuit: CompressionLayerCircuit, + ) -> CSReferenceAssembly { + let geometry = circuit.geometry(); + let (max_trace_len, num_vars) = circuit.size_hint(); + + let builder_impl = CsReferenceImplementationBuilder::::new( + geometry, + max_trace_len.unwrap(), + ); + let builder = new_builder::<_, GoldilocksField>(builder_impl); + let builder = circuit.configure_builder_proxy(builder); + let mut cs = builder.build(num_vars.unwrap()); + circuit.synthesize_into_cs(&mut cs); + + cs.pad_and_shrink(); + cs.into_assembly::() + } + + let mut cs = match circuit { + ZkSyncCompressionForWrapperCircuit::CompressionMode1Circuit(inner) => test_inner(inner), + ZkSyncCompressionForWrapperCircuit::CompressionMode2Circuit(inner) => test_inner(inner), + ZkSyncCompressionForWrapperCircuit::CompressionMode3Circuit(inner) => test_inner(inner), + ZkSyncCompressionForWrapperCircuit::CompressionMode4Circuit(inner) => test_inner(inner), + ZkSyncCompressionForWrapperCircuit::CompressionMode5Circuit(inner) => test_inner(inner), + }; + + let is_satisfied = cs.check_if_satisfied(&worker); + assert!(is_satisfied); +} diff --git a/crates/zkevm_test_harness/src/tests/run_manually.rs b/crates/zkevm_test_harness/src/tests/run_manually.rs new file mode 100644 index 0000000..2cc04a2 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/run_manually.rs @@ -0,0 +1,366 @@ +use std::collections::HashMap; + +use super::*; +use crate::entry_point::create_out_of_circuit_global_context; + +use crate::boojum::config::{ProvingCSConfig, SetupCSConfig}; +use crate::boojum::cs::implementations::prover::ProofConfig; +use crate::boojum::cs::traits::cs::ConstraintSystem; +use crate::boojum::cs::traits::gate::GatePlacementStrategy; +use crate::boojum::field::traits::field_like::TrivialContext; +use crate::ethereum_types::*; +use crate::toolset::create_tools; +use crate::witness::oracle::create_artifacts_from_tracer; +use crate::zk_evm::abstractions::*; +use crate::zk_evm::aux_structures::DecommittmentQuery; +use crate::zk_evm::aux_structures::*; +use crate::zk_evm::testing::storage::InMemoryStorage; +use crate::zk_evm::utils::{bytecode_to_code_hash, contract_bytecode_to_words}; +use crate::zk_evm::witness_trace::VmWitnessTracer; +use crate::zk_evm::GenericNoopTracer; +use crate::zkevm_circuits::base_structures::vm_state::GlobalContextWitness; +use crate::zkevm_circuits::main_vm::main_vm_entry_point; +use boojum::gadgets::queue::full_state_queue::FullStateCircuitQueueRawWitness; +use circuit_definitions::aux_definitions::witness_oracle::VmWitnessOracle; +use circuit_definitions::zk_evm::vm_state::cycle; +use storage::{InMemoryCustomRefundStorage, StorageRefund}; +use witness::oracle::WitnessGenerationArtifact; +use zkevm_assembly::Assembly; + +#[test] +fn run_and_try_create_witness() { + // let asm = r#" + // .text + // .file "Test_26" + // .rodata.cst32 + // .p2align 5 + // .text + // .globl __entry + // __entry: + // .main: + // nop stack+=[4] + // nop stack-=[1] + // add 1, r0, r1 + // add 2, r0, r2 + // sstore r1, r2 + // near_call r0, @.continue, @.to_revert + // ret.ok r0 + // .continue: + // add 5, r0, r1 + // add 6, r0, r2 + // sstore r1, r2 + // ret.ok r0 + // .to_revert: + // add 3, r0, r1 + // add 4, r0, r2 + // sstore r1, r2 + // ret.revert r0 + // "#; + + let asm = r#" + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry + __entry: + .main: + nop stack+=[4] + nop stack-=[1] + add 12345, r0, r1 + shl.s 7, r1, r1 + add 1, r0, r1 + sload r1, r0 + add 2, r0, r2 + sstore r1, r2 + sload r1, r0 + log.event.first r1, r2, r0 + log.to_l1.first r1, r2, r0 + add 5, r0, r1 + add 6, r0, r2 + sstore r1, r2 + sload r1, r0 + sstore r1, r0 + near_call r0, @.empty_no_rollback, @.nop + .continue0: + near_call r0, @.empty_with_rollback, @.continue1 + .continue1: + near_call r0, @.to_revert, @.finish + .finish: + add 3, r0, r1 + sload r1, r0 + sstore r1, r0 + ret.ok r0 + .empty_no_rollback: + ret.ok r0 + .empty_with_rollback: + ret.revert r0 + .to_revert: + add 3, r0, r1 + add 4, r0, r2 + sstore r1, r2 + sload r1, r0 + log.event.first r1, r2, r0 + log.to_l1.first r1, r2, r0 + ret.revert r0 + .nop: + ret.revert r0 + "#; + + // let asm = r#" + // .text + // .file "Test_26" + // .rodata.cst32 + // .p2align 5 + // .text + // .globl __entry + // __entry: + // .main: + // add 12345, r0, r1 + // shl.s 7, r1, r1 + // add 1, r0, r1 + // near_call r0, @.to_revert, @.finish + // .finish: + // ret.revert r0 + // .to_revert: + // add 3, r0, r1 + // add 4, r0, r2 + // sstore r1, r2 + // sload r1, r0 + // ret.revert r0 + // "#; + + // let asm = r#" + // .text + // .file "Test_26" + // .rodata.cst32 + // .p2align 5 + // .text + // .globl __entry + // __entry: + // .main: + // add! 1, r0, r1 + // ret.ok r0 + // "#; + + run_and_try_create_witness_inner(asm, 50); +} + +#[test] +fn run_pseudo_benchmark() { + let asm = r#" + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry + __entry: + .main: + add 100, r0, r1, + .loop: + sub.s! 1, r1, r1 + jump.ne @.loop + .end + ret.ok r0 + "#; + + run_and_try_create_witness_inner(asm, 30000); +} + +#[allow(dead_code)] +pub(crate) fn run_and_try_create_witness_inner(asm: &str, cycle_limit: usize) { + let mut assembly = Assembly::try_from(asm.to_owned()).unwrap(); + let bytecode = assembly.compile_to_bytecode().unwrap(); + + run_and_try_create_witness_for_extended_state(bytecode, vec![], cycle_limit) +} + +const DEFAULT_CYCLE_LIMIT: usize = 50; +const DEFAULT_CYCLES_PER_VM_SNAPSHOT: u32 = 5; +#[derive(Clone)] +pub struct Options { + // How many cycles should the main VM run for. + // If not set - default is DEFAULT_CYCLE_LIMIT (50). + pub cycle_limit: usize, + // Additional contracts that should be deployed (pairs 'address, bytecode') + pub other_contracts: Vec<(H160, Vec<[u8; 32]>)>, + // How many cycles should a single VM handle (default is DEFAULT_CYCLES_PER_VM_SNAPSHOT = 5) + pub cycles_per_vm_snapshot: u32, +} + +impl Default for Options { + fn default() -> Self { + Self { + cycle_limit: DEFAULT_CYCLE_LIMIT, + other_contracts: Default::default(), + cycles_per_vm_snapshot: DEFAULT_CYCLES_PER_VM_SNAPSHOT, + } + } +} + +pub(crate) fn run_and_try_create_witness_for_extended_state( + entry_point_bytecode: Vec<[u8; 32]>, + other_contracts: Vec<(H160, Vec<[u8; 32]>)>, + cycle_limit: usize, +) { + run_with_options( + entry_point_bytecode, + Options { + cycle_limit, + other_contracts, + ..Default::default() + }, + ) +} + +pub(crate) fn run_with_options(entry_point_bytecode: Vec<[u8; 32]>, options: Options) { + use crate::run_vms::{run_vms, RunVmError}; + use crate::tests::utils::testing_tracer::TestingTracer; + use crate::toolset::GeometryConfig; + use crate::zk_evm::zkevm_opcode_defs::system_params::BOOTLOADER_FORMAL_ADDRESS; + + let geometry = GeometryConfig { + cycles_per_vm_snapshot: options.cycles_per_vm_snapshot, + cycles_code_decommitter_sorter: 16, + cycles_per_log_demuxer: 8, + cycles_per_storage_sorter: 4, + cycles_per_events_or_l1_messages_sorter: 2, + cycles_per_ram_permutation: 4, + cycles_per_code_decommitter: 4, + cycles_per_storage_application: 2, + cycles_per_keccak256_circuit: 1, + cycles_per_sha256_circuit: 1, + cycles_per_ecrecover_circuit: 1, + cycles_per_secp256r1_verify_circuit: 1, + cycles_per_transient_storage_sorter: 4, + + limit_for_l1_messages_pudata_hasher: 8, + }; + + use crate::witness::tree::BinarySparseStorageTree; + use crate::witness::tree::ZKSyncTestingTree; + + let mut used_bytecodes_and_hashes = HashMap::new(); + used_bytecodes_and_hashes.extend(options.other_contracts.iter().cloned().map(|(_, code)| { + let code_hash = bytecode_to_code_hash(&code).unwrap(); + + (U256::from_big_endian(&code_hash), code) + })); + + // We must pass a correct empty code hash (with proper version) into the run method. + let empty_code_hash = U256::from_big_endian(&bytecode_to_code_hash(&[[0; 32]]).unwrap()); + + let mut storage_impl = InMemoryCustomRefundStorage::new(); + + let mut tree = ZKSyncTestingTree::empty(); + + let mut known_contracts = HashMap::new(); + known_contracts.extend(options.other_contracts.iter().cloned()); + + save_predeployed_contracts(&mut storage_impl.storage, &mut tree, &known_contracts); + + let mut basic_block_circuits = vec![]; + let mut unsorted_memory_queue_witnesses = vec![]; + let mut sorted_memory_queue_witnesses = vec![]; + + // we are using TestingTracer to track prints and exceptions inside out_of_circuit_vm cycles + let mut out_of_circuit_tracer = + TestingTracer::new(Some(storage_impl.create_refund_controller())); + + let artifacts_callback = |artifact: WitnessGenerationArtifact| match artifact { + WitnessGenerationArtifact::BaseLayerCircuit(circuit) => basic_block_circuits.push(circuit), + WitnessGenerationArtifact::MemoryQueueWitness((witnesses, sorted)) => { + if sorted { + sorted_memory_queue_witnesses.push(witnesses) + } else { + unsorted_memory_queue_witnesses.push(witnesses) + } + } + _ => {} + }; + + if let Err(err) = run_vms( + Address::zero(), + *BOOTLOADER_FORMAL_ADDRESS, + entry_point_bytecode, + vec![], + false, + empty_code_hash, + empty_code_hash, + used_bytecodes_and_hashes, + vec![], + options.cycle_limit, + geometry, + storage_impl, + tree, + "kzg/src/trusted_setup.json", + std::array::from_fn(|_| None), + artifacts_callback, + &mut out_of_circuit_tracer, + ) { + let error_text = match err { + RunVmError::InvalidInput(msg) => { + format!("Invalid input error: {msg}") + } + RunVmError::OutOfCircuitExecutionError(msg) => { + let msg = if let Some(exception) = out_of_circuit_tracer.exception { + format!("{msg} {exception}") + } else { + msg + }; + format!("Out-of-circuit execution error: {msg}") + } + }; + panic!("{error_text}"); + } + + println!("Simulation and witness creation are completed"); + + let mut unsorted_memory_queue_witnesses_it = unsorted_memory_queue_witnesses.into_iter(); + let mut sorted_memory_queue_witnesses = sorted_memory_queue_witnesses.into_iter(); + for el in basic_block_circuits { + println!("Doing {} circuit", el.short_description()); + match &el { + ZkSyncBaseLayerCircuit::RAMPermutation(inner) => { + let mut witness = inner.witness.take().unwrap(); + witness.sorted_queue_witness = FullStateCircuitQueueRawWitness { + elements: sorted_memory_queue_witnesses.next().unwrap().into(), + }; + witness.unsorted_queue_witness = FullStateCircuitQueueRawWitness { + elements: unsorted_memory_queue_witnesses_it.next().unwrap().into(), + }; + + inner.witness.store(Some(witness)); + } + _ => {} + } + base_test_circuit(el); + } + + // // for el in flattened.into_iter() { + // // use crate::bellman::plonk::better_better_cs::cs::PlonkCsWidth4WithNextStepAndCustomGatesParams; + // // circuit_testing::prove_and_verify_circuit::(el).unwrap(); + // // } + + // let flattened = basic_block_circuits.into_flattened_set(); + // let flattened_inputs = basic_block_circuits_inputs.into_flattened_set(); + + // for (idx, (el, input_value)) in flattened.into_iter().zip(flattened_inputs.into_iter()).enumerate() { + // let descr = el.short_description(); + // println!("Doing {}: {}", idx, descr); + // use crate::abstract_zksync_circuit::concrete_circuits::ZkSyncCircuit; + // if !matches!(&el, ZkSyncCircuit::MainVM(..)) { + // continue; + // } + // // el.debug_witness(); + // use crate::bellman::plonk::better_better_cs::cs::PlonkCsWidth4WithNextStepAndCustomGatesParams; + // let (is_satisfied, public_input) = circuit_testing::check_if_satisfied::(el).unwrap(); + // assert!(is_satisfied); + // assert_eq!(public_input, input_value, "Public input diverged for circuit {} of type {}", idx, descr); + // // if public_input != input_value { + // // println!("Public input diverged for circuit {} of type {}", idx, descr); + // // } + // } +} diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/README.md b/crates/zkevm_test_harness/src/tests/simple_tests/README.md new file mode 100644 index 0000000..9619920 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/README.md @@ -0,0 +1,35 @@ +## Preprocessing directives + +In tests in `.asm` files it is possible to use several additional directives (not stable): +- `print("")` - print text `` in console. Max length of text is 30 symbols +- `print()` - print value of `` (register/constant/etc) in console +- `print("", )` - print text `` and value of `` in console. Max length of text is 30 symbols +- `printPtr()` - print value of `` (fat pointer) in console +- `printPtr("", )` - print text `` and value of `` (fat pointer) in console. Max length of text is 30 symbols +- `revert("")` - panic with message ``. Max length of text is 30 symbols +- `` - will be replaced with the hash of `ADDRESS.asm` additional contract +- `set_storage_cold()` - sets the storage slot refund to be cold +- `set_storage_warm()` - sets the storage slot refund to be warm with a value of `` + +## Templating + +`compile_asm_template` can be used to replace entries like `${}` with values from `Dictionary` (`HashMap<&str, &str>`). For example: + +```asm + add ${src0} r0 r1 +``` + +will be replaced by `dictionary.get("src0")`. + +This can be used to simplify creation of new tests. For example, you can create a template like this: + +```asm + .text + .globl __entry +__entry: +.main: + ${opcode} ${src0}, ${src1}, ${dst0} + ret.ok r0 +``` + +and then generate and test different sets of parameters. Also can be used for "fuzzy-style" tests. \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/asm_tests.rs b/crates/zkevm_test_harness/src/tests/simple_tests/asm_tests.rs new file mode 100644 index 0000000..152442e --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/asm_tests.rs @@ -0,0 +1,86 @@ +use self::run_manually::{ + run_and_try_create_witness_for_extended_state, run_and_try_create_witness_inner, Options, +}; +use super::*; +use crate::tests::utils::preprocess_asm::preprocess_asm; +pub use crate::tests::utils::preprocess_asm::TemplateDictionary; +use std::{fs, path::Path}; +use zkevm_assembly::Assembly; + +/// Runs the tests based on the ASM files from a given directory. +/// The main assembly should be in `entry.asm` file, while additional +/// contracts should be in `ADDRESS.asm` files, where `ADDRESS` is the numerical +/// address at which they should be deployed. +pub fn run_asm_based_test( + test_dir: &str, + additional_contracts_addresses: &[i32], + options: Options, +) { + let additional_contracts = additional_contracts_addresses + .iter() + .map(|address| (address.to_string(), *address)) + .collect(); + + run_asm_based_test_template(test_dir, &additional_contracts, options, None); +} + +pub fn run_asm_based_test_template( + test_dir: &str, + additional_contracts: &Vec<(String, i32)>, + options: Options, + dictionary: Option<&TemplateDictionary>, +) { + let data_path = Path::new(test_dir); + + let contracts: Vec<(H160, Vec<[u8; 32]>)> = + compile_additional_contracts(test_dir, additional_contracts, dictionary); + + let entry_bytecode = compile_asm_template(data_path, "entry", dictionary, Some(&contracts)); + + let mut options = options.clone(); + options.other_contracts = contracts; + run_with_options(entry_bytecode, options); +} + +pub fn compile_additional_contracts( + test_dir: &str, + contracts: &Vec<(String, i32)>, + dictionary: Option<&TemplateDictionary>, +) -> Vec<(H160, Vec<[u8; 32]>)> { + let data_path = Path::new(test_dir); + contracts + .iter() + .map(|(source_file, address)| { + let bytecode = compile_asm_template(data_path, source_file, dictionary, None); + (Address::from_low_u64_be(*address as u64), bytecode) + }) + .collect() +} + +fn compile_asm_template( + data_path: &Path, + filename: &str, + dictionary: Option<&TemplateDictionary>, + additional_contracts: Option<&Vec<(H160, Vec<[u8; 32]>)>>, +) -> Vec<[u8; 32]> { + let file_path = data_path.join(format!("{filename}.asm")); + let asm = fs::read_to_string(file_path.clone()).expect(&format!( + "Should have been able to read the file {:?}", + file_path + )); + let asm_preprocessed = preprocess_asm(asm, additional_contracts, dictionary); + Assembly::try_from(asm_preprocessed.to_owned()) + .unwrap() + .compile_to_bytecode() + .expect(&format!("Failed to compile {:?}", file_path)) +} + +#[ignore = "used for manual runs"] +#[test_log::test] +fn test_manual_asm() { + run_asm_based_test( + "src/tests/simple_tests/testdata/meta_opcode", + &[], + Default::default(), + ) +} diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/context.rs b/crates/zkevm_test_harness/src/tests/simple_tests/context.rs new file mode 100644 index 0000000..9c9a1c9 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/context.rs @@ -0,0 +1,12 @@ +use super::*; +use crate::tests::simple_tests::asm_tests::run_asm_based_test; + +// TODO return value of "meta" opcode isn't checked +#[test_log::test] +fn test_meta_opcode() { + run_asm_based_test( + "src/tests/simple_tests/testdata/meta_opcode", + &[], + Default::default(), + ) +} diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/eip4844.rs b/crates/zkevm_test_harness/src/tests/simple_tests/eip4844.rs new file mode 100644 index 0000000..352829d --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/eip4844.rs @@ -0,0 +1,46 @@ +use super::*; +use crate::zkevm_circuits::eip_4844::input::*; +use circuit_definitions::circuit_definitions::base_layer::EIP4844Circuit; +use circuit_definitions::EIP4844_CYCLE_LIMIT; +use crossbeam::atomic::AtomicCell; +use rand::Rng; +use std::collections::VecDeque; +use std::sync::Arc; + +#[test] +fn test_eip4844() { + let mut blob = vec![0; 4096 * 31]; + blob.iter_mut() + .for_each(|byte| *byte = rand::thread_rng().gen()); + + let (blob_arr, linear_hash, versioned_hash, output_hash) = + generate_eip4844_witness::(&blob, "kzg/src/trusted_setup.json"); + let blob = blob_arr + .iter() + .map(|el| BlobChunkWitness { inner: *el }) + .collect::>>(); + let witness = EIP4844CircuitInstanceWitness { + closed_form_input: EIP4844InputOutputWitness { + start_flag: true, + completion_flag: true, + hidden_fsm_input: (), + hidden_fsm_output: (), + observable_input: (), + observable_output: EIP4844OutputDataWitness { + linear_hash, + output_hash, + }, + }, + data_chunks: VecDeque::from(blob), + linear_hash_output: linear_hash, + versioned_hash, + }; + let circuit = EIP4844Circuit { + witness: AtomicCell::new(Some(witness)), + config: Arc::new(EIP4844_CYCLE_LIMIT), + round_function: ZkSyncDefaultRoundFunction::default().into(), + expected_public_input: None, + }; + let circuit = ZkSyncBaseLayerCircuit::EIP4844Repack(circuit); + base_test_circuit(circuit); +} diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/far_call.rs b/crates/zkevm_test_harness/src/tests/simple_tests/far_call.rs new file mode 100644 index 0000000..ebb378a --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/far_call.rs @@ -0,0 +1,67 @@ +use asm_tests::TemplateDictionary; + +use super::*; +use crate::tests::simple_tests::asm_tests::{run_asm_based_test, run_asm_based_test_template}; + +// For far_call, the first register is holding the 'FarCallABI', which consists of: +// 64 bytes of 'extra data' - [forwarding_byte, shard_id, constructor_call, system_byte, 32 bytes ergs] +// 64 bytes empty. +// 128 bytes of 'fat pointer' - [length, start] [memory_page, offset] + +#[test_log::test] +fn test_far_call_read_fat_pointer() { + run_asm_based_test( + "src/tests/simple_tests/testdata/far_call/read_fat_pointer", + &[65535], + Default::default(), + ); +} + +#[test_log::test] +fn test_far_call_return_large_data() { + run_asm_based_test( + "src/tests/simple_tests/testdata/far_call/return_large_data", + &[65536], + Default::default(), + ); +} + +#[test_log::test] +fn test_far_call_panic_on_return_large_data() { + run_asm_based_test( + "src/tests/simple_tests/testdata/far_call/panic_on_return_large_data", + &[65536], + Default::default(), + ); +} + +#[test_log::test] +fn test_far_call_pay_for_memory_growth() { + run_asm_based_test( + "src/tests/simple_tests/testdata/far_call/pay_for_memory_growth", + &[65536, 65537], + Default::default(), + ); +} + +#[test_log::test] +fn test_far_call_with_decommit() { + // In this test, we have a very large bytecode that we try to call. + // But we don't have enough gas to actually decommit it. + + let garbage = r#" + nop + "# + .repeat(10000); + + let dummy_address = 65536; + let contracts = Vec::from([(dummy_address.to_string(), dummy_address)]); + let dictionary: TemplateDictionary = TemplateDictionary::from([("garbage", garbage)]); + + run_asm_based_test_template( + "src/tests/simple_tests/testdata/far_call/fail_on_decommit", + &contracts, + Default::default(), + Some(&dictionary), + ); +} diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/kernel_ops.rs b/crates/zkevm_test_harness/src/tests/simple_tests/kernel_ops.rs new file mode 100644 index 0000000..1416709 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/kernel_ops.rs @@ -0,0 +1,27 @@ +use super::*; + +#[test_log::test] +fn test_kernel_opcodes() { + let asm = r#" + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry + __entry: + .main: + sstore r0, r0 + event.first r0, r0 + to_l1.first r0, r0 + add 4, r0, r2 + add 8, r0, r3 + context.set_ergs_per_pubdata r2 + context.set_context_u128 r3 + context.inc_tx_num + add 16, r0, r4 + ret.ok r0 + "#; + + run_and_try_create_witness_inner(asm, 50); +} diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/log.rs b/crates/zkevm_test_harness/src/tests/simple_tests/log.rs new file mode 100644 index 0000000..e7be2ab --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/log.rs @@ -0,0 +1,93 @@ +#[cfg(test)] +mod tests { + use crate::tests::simple_tests::{asm_tests::run_asm_based_test, Options}; + + fn test_snapshot_every_cycle(dir: &str, additional_contracts: &[i32]) { + run_asm_based_test( + &format!("src/tests/simple_tests/testdata/log/{}", dir), + additional_contracts, + Options { + // Do only 1 cycle per VM snapshot to really test all the boundary conditions. + cycles_per_vm_snapshot: 1, + ..Default::default() + }, + ) + } + + #[test_log::test] + /// Tests the case where we do not have enough gas to send a message to l1 + fn test_log_l1_message_out_of_gas() { + run_asm_based_test( + "src/tests/simple_tests/testdata/log/l1_message_out_of_gas", + &[], + Default::default(), + ) + } + + #[test_log::test] + fn test_log_l1_message_has_zero_pubdata_cost() { + run_asm_based_test( + "src/tests/simple_tests/testdata/log/l1_message_has_zero_pubdata_cost", + &[], + Default::default(), + ) + } + + #[test_log::test] + /// Tests the case where we run out of gas during the precompile execution. + fn test_log_precompile_out_of_gas() { + test_snapshot_every_cycle("precompile_out_of_gas", &[]); + } + + #[test_log::test] + fn test_log_precompile_invalid_address() { + test_snapshot_every_cycle("precompile_invalid_address", &[65399]); + } + + #[test_log::test] + fn test_log_decommit_invalid() { + test_snapshot_every_cycle("decommit_invalid", &[800000]) + } + + #[test_log::test] + fn test_log_decommit_ok() { + test_snapshot_every_cycle("decommit_ok", &[800000]); + } + + #[test_log::test] + fn test_log_decommit_ok_twice() { + test_snapshot_every_cycle("decommit_ok_twice", &[800000]); + } + + #[test_log::test] + fn test_log_decommit_ok_with_panic() { + test_snapshot_every_cycle("decommit_ok_with_panic", &[800000]); + } + + #[test_log::test] + fn test_log_storage_clear_slot() { + run_asm_based_test( + "src/tests/simple_tests/testdata/log/storage/storage_clear_slot", + &[], + Default::default(), + ) + } + + #[test_log::test] + fn test_log_storage_write_rollback_no_reads() { + run_asm_based_test( + "src/tests/simple_tests/testdata/log/storage/storage_write_rollback_no_reads", + &[], + Default::default(), + ) + } + + #[test_log::test] + fn test_log_storage_write_rollback_reads() { + run_asm_based_test( + "src/tests/simple_tests/testdata/log/storage/storage_write_rollback_reads", + &[], + Default::default(), + ) + } +} diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/memory_growth.rs b/crates/zkevm_test_harness/src/tests/simple_tests/memory_growth.rs new file mode 100644 index 0000000..7fc084e --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/memory_growth.rs @@ -0,0 +1,136 @@ +use super::*; +use crate::tests::simple_tests::asm_tests::{run_asm_based_test, run_asm_based_test_template}; +use crate::tests::utils::preprocess_asm::TemplateDictionary; + +#[test_log::test] +fn test_memory_growth_heap_write_kernel() { + test_memory_growth_heap_write(65534); +} + +#[test_log::test] +fn test_memory_growth_heap_write_not_kernel() { + test_memory_growth_heap_write(800000); +} + +fn test_memory_growth_heap_write(heaps_growth_test_address: i32) { + let additional_contracts = + Vec::<(String, i32)>::from([("heaps_grows_test".to_owned(), heaps_growth_test_address)]); + + let mut dictionary = TemplateDictionary::new(); + dictionary.insert( + "heaps_grows_test_contract_address", + heaps_growth_test_address.to_string(), + ); + + run_asm_based_test_template( + "src/tests/simple_tests/testdata/memory_growth/heap_write", + &additional_contracts, + Options { + cycle_limit: 100, + ..Default::default() + }, + Some(&dictionary), + ) +} + +#[test_log::test] +fn test_memory_growth_ret_kernel() { + test_memory_growth_ret(65534, 65533); +} + +#[test_log::test] +fn test_memory_growth_ret_not_kernel() { + test_memory_growth_ret(800000, 800001); +} + +fn test_memory_growth_ret(heap_test_address: i32, aux_heap_test_address: i32) { + let additional_contracts = Vec::<(String, i32)>::from([ + ("heap_test".to_owned(), heap_test_address), + ("aux_heap_test".to_owned(), aux_heap_test_address), + ]); + + let mut dictionary = TemplateDictionary::new(); + + dictionary.insert("heap_test_contract_address", heap_test_address.to_string()); + dictionary.insert( + "aux_heap_test_contract_address", + aux_heap_test_address.to_string(), + ); + + run_asm_based_test_template( + "src/tests/simple_tests/testdata/memory_growth/ret", + &additional_contracts, + Options { + cycle_limit: 100, + ..Default::default() + }, + Some(&dictionary), + ) +} + +#[test_log::test] +fn test_memory_growth_far_call_kernel() { + test_memory_growth_far_call(65534); +} + +#[test_log::test] +fn test_memory_growth_far_call_not_kernel() { + test_memory_growth_far_call(800000); +} + +fn test_memory_growth_far_call(far_call_test_address: i32) { + let dummy_address = 900000; + let additional_contracts = Vec::<(String, i32)>::from([ + ("far_call_test".to_owned(), far_call_test_address), + ("dummy".to_owned(), dummy_address), + ]); + + let mut dictionary = TemplateDictionary::new(); + dictionary.insert("far_call_test_address", far_call_test_address.to_string()); + dictionary.insert("dummy_address", dummy_address.to_string()); + + run_asm_based_test_template( + "src/tests/simple_tests/testdata/memory_growth/far_call", + &additional_contracts, + Options { + cycle_limit: 100, + ..Default::default() + }, + Some(&dictionary), + ) +} + +#[test_log::test] +fn test_memory_growth_ret_out_of_ergs_kernel() { + test_memory_growth_ret_out_of_ergs(65534, 65533); +} + +#[test_log::test] +fn test_memory_growth_ret_out_of_ergs_not_kernel() { + test_memory_growth_ret_out_of_ergs(800000, 800001); +} + +fn test_memory_growth_ret_out_of_ergs(heap_test_address: i32, aux_heap_test_address: i32) { + let additional_contracts = Vec::<(String, i32)>::from([ + ("heap_test".to_owned(), heap_test_address), + ("aux_heap_test".to_owned(), aux_heap_test_address), + ]); + + let mut dictionary = TemplateDictionary::new(); + + dictionary.insert("heap_test_contract_address", heap_test_address.to_string()); + dictionary.insert( + "aux_heap_test_contract_address", + aux_heap_test_address.to_string(), + ); + + run_asm_based_test_template( + "src/tests/simple_tests/testdata/memory_growth/ret_out_of_ergs", + &additional_contracts, + Options { + cycle_limit: 100, + ..Default::default() + }, + Some(&dictionary), + ) +} diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/mod.rs b/crates/zkevm_test_harness/src/tests/simple_tests/mod.rs new file mode 100644 index 0000000..a06f6a5 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/mod.rs @@ -0,0 +1,17 @@ +use super::run_manually::*; +use super::*; + +use zkevm_assembly::Assembly; + +mod asm_tests; +mod context; +mod eip4844; +mod far_call; +mod kernel_ops; +mod log; +mod memory_growth; +mod near_call; +mod ptr; +mod stack; +mod storage; +mod uma; diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/near_call.rs b/crates/zkevm_test_harness/src/tests/simple_tests/near_call.rs new file mode 100644 index 0000000..1263940 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/near_call.rs @@ -0,0 +1,50 @@ +use super::*; +use crate::tests::simple_tests::asm_tests::run_asm_based_test; + +#[test_log::test] +fn test_near_call_memory_growth_ret_ok() { + run_asm_based_test( + "src/tests/simple_tests/testdata/near_call/memory_growth_ret_ok", + &[65536], + Options { + cycle_limit: 100, + ..Default::default() + }, + ) +} + +#[test_log::test] +fn test_near_call_resets_sp() { + run_asm_based_test( + "src/tests/simple_tests/testdata/near_call/resets_sp", + &[], + Default::default(), + ) +} + +#[test_log::test] +fn test_near_call_resets_flags() { + run_asm_based_test( + "src/tests/simple_tests/testdata/near_call/resets_flags", + &[], + Default::default(), + ) +} + +#[test_log::test] +fn test_near_call_not_rollback_memory() { + run_asm_based_test( + "src/tests/simple_tests/testdata/near_call/not_rollback_memory", + &[65536], + Default::default(), + ) +} + +#[test_log::test] +fn test_near_call_limited_ergs() { + run_asm_based_test( + "src/tests/simple_tests/testdata/near_call/limited_ergs", + &[65536], + Default::default(), + ) +} diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/ptr.rs b/crates/zkevm_test_harness/src/tests/simple_tests/ptr.rs new file mode 100644 index 0000000..9c64d3b --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/ptr.rs @@ -0,0 +1,251 @@ +use super::*; +use crate::tests::simple_tests::asm_tests::run_asm_based_test; +use crate::tests::utils::preprocess_asm::asm_with_default_config; + +#[test_log::test] +fn test_ptr_add_valid_input() { + run_asm_based_test( + "src/tests/simple_tests/testdata/ptr/ptr_add_valid_input", + &[], + Default::default(), + ); +} + +#[test_log::test] +fn test_ptr_add_invalid_1_pointer() { + run_asm_based_test( + "src/tests/simple_tests/testdata/ptr/ptr_add_invalid_1_pointer", + &[], + Default::default(), + ); +} + +#[test_log::test] +fn test_ptr_add_max_offset() { + let asm = asm_with_default_config( + r#" + __entry: + .main: + add 1, r0, r2 + shl.s 32, r2, r2 + near_call r0, @should_panic, @handler + ret.panic r0 + should_panic: + ; trying to use MAX_OFFSET as second input for ptr.add + ptr.add r1, r2, r3 + handler: + ret.ok r0 + "#, + ); + + run_and_try_create_witness_inner(&asm, 50); +} + +#[test_log::test] +fn test_ptr_add_max_offset_minus_one() { + let asm = asm_with_default_config( + r#" + __entry: + .main: + add 1, r0, r2 + shl.s 32, r2, r2 + sub.s 1, r2, r2 + ; trying to use MAX_OFFSET - 1 as second input for ptr.add + ptr.add r1, r2, r3 + ret.ok r0 + "#, + ); + + run_and_try_create_witness_inner(&asm, 50); +} + +#[test_log::test] +fn test_ptr_add_overflow_offset() { + let asm = asm_with_default_config( + r#" + __entry: + .main: + add 1, r0, r2 + shl.s 31, r2, r2 + ptr.add r1, r2, r1 + near_call r0, @should_panic, @handler + ret.panic r0 + should_panic: + ; trying to overflow offset in pointer + ptr.add r1, r2, r1 + handler: + ret.ok r0 + "#, + ); + + run_and_try_create_witness_inner(&asm, 50); +} + +#[test_log::test] +fn test_ptr_add_invalid_0_number() { + let asm = asm_with_default_config( + r#" + __entry: + .main: + add 4, r0, r2 + add 8, r0, r3 + shl.s 128, r3, r3 + near_call r0, @should_panic, @handler + ret.panic r0 + should_panic: + ; trying to use number as first input for ptr.add + ptr.add r3, r2, r3 + ret.ok r0 + handler: + ret.ok r0 + "#, + ); + + run_and_try_create_witness_inner(&asm, 50); +} + +#[test_log::test] +fn test_ptr_sub_valid_input() { + let asm = asm_with_default_config( + r#" + __entry: + .main: + sstore r0, r0 + event.first r0, r0 + to_l1.first r0, r0 + add 4, r0, r2 + add 8, r0, r3 + shl.s 128, r3, r3 + ptr.add r1, r2, r1 + ptr.sub r1, r2, r1 + ptr.pack r1, r3, r4 + ret.ok r0 + "#, + ); + + run_and_try_create_witness_inner(&asm, 50); +} + +#[test_log::test] +fn test_ptr_sub_invalid_1_pointer() { + let asm = asm_with_default_config( + r#" + __entry: + .main: + sstore r0, r0 + event.first r0, r0 + to_l1.first r0, r0 + add 4, r0, r2 + add 8, r0, r3 + shl.s 128, r3, r3 + near_call r0, @should_panic, @handler + ret.panic r0 + should_panic: + ; trying to sub pointer from pointer + ptr.sub r1, r1, r1 + handler: + ret.ok r0 + "#, + ); + + run_and_try_create_witness_inner(&asm, 50); +} + +#[test_log::test] +fn test_ptr_sub_invalid_0_number() { + let asm = asm_with_default_config( + r#" + __entry: + .main: + add 4, r0, r2 + add 8, r0, r3 + shl.s 128, r3, r3 + near_call r0, @should_panic, @handler + ret.panic r0 + should_panic: + ; trying to use number as first input for ptr.sub + ptr.sub r3, r2, r3 + handler: + ret.ok r0 + "#, + ); + + run_and_try_create_witness_inner(&asm, 50); +} + +#[test_log::test] +fn test_ptr_sub_overflow_offset() { + let asm = asm_with_default_config( + r#" + __entry: + .main: + add 1, r0, r2 + shl.s 31, r2, r2 + near_call r0, @should_panic, @handler + ret.panic r0 + should_panic: + ; trying to overflow offset in pointer + ptr.sub r1, r2, r1 + handler: + ret.ok r0 + "#, + ); + + run_and_try_create_witness_inner(&asm, 50); +} + +#[test_log::test] +fn test_ptr_to_global() { + let asm = asm_with_default_config( + r#" + .data + .globl val ; @val + val: + .cell 0 + .text + __entry: + .main: + sstore r0, r0 + event.first r0, r0 + to_l1.first r0, r0 + add 4, r0, r2 + add 8, r0, r3 + shl.s 128, r3, r3 + ptr.add r1, r0, stack[@val] + ptr.add r1, r0, r1 + ptr.sub r1, r0, stack[@val] + ptr.sub r1, r0, r1 + ptr.pack r1, r3, r4 + ret.ok r0 + "#, + ); + + run_and_try_create_witness_inner(&asm, 50); +} + +#[test_log::test] +fn test_ptr_erasure_not_kernel() { + run_asm_based_test( + "src/tests/simple_tests/testdata/ptr/ptr_erasure_not_kernel", + &[65536, 65534], + Default::default(), + ) +} + +#[test_log::test] +fn test_ptr_erasure_kernel() { + run_asm_based_test( + "src/tests/simple_tests/testdata/ptr/ptr_erasure_kernel", + &[65533, 65534], + Default::default(), + ) +} + +#[test_log::test] +fn test_ptr_add_src0_erasure() { + run_asm_based_test( + "src/tests/simple_tests/testdata/ptr/ptr_add_src0_erasure", + &[65537], + Default::default(), + ) +} diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/stack.rs b/crates/zkevm_test_harness/src/tests/simple_tests/stack.rs new file mode 100644 index 0000000..df85491 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/stack.rs @@ -0,0 +1,20 @@ +use super::*; +use crate::tests::simple_tests::asm_tests::run_asm_based_test; + +#[test_log::test] +fn test_stack_addressing_modes() { + run_asm_based_test( + "src/tests/simple_tests/testdata/stack/addressing", + &[], + Default::default(), + ) +} + +#[test_log::test] +fn test_stack_overflow() { + run_asm_based_test( + "src/tests/simple_tests/testdata/stack/overflow", + &[], + Default::default(), + ) +} diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/storage.rs b/crates/zkevm_test_harness/src/tests/simple_tests/storage.rs new file mode 100644 index 0000000..4cecbf8 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/storage.rs @@ -0,0 +1,55 @@ +#[cfg(test)] +mod tests { + use crate::tests::simple_tests::{asm_tests::run_asm_based_test, Options}; + + #[test_log::test] + fn test_pubdata_and_storage_writes() { + run_asm_based_test( + "src/tests/simple_tests/testdata/log/storage/storage_writes", + &[], + Options { + cycles_per_vm_snapshot: 1, + ..Default::default() + }, + ); + } + + #[test_log::test] + fn test_storage_reads() { + run_asm_based_test( + "src/tests/simple_tests/testdata/log/storage/storage_reads", + &[], + Options { + // Do only 1 cycle per VM snapshot to really test all the boundary conditions. + cycles_per_vm_snapshot: 1, + ..Default::default() + }, + ) + } + + #[test_log::test] + fn test_storage_write_after_panic() { + run_asm_based_test( + "src/tests/simple_tests/testdata/log/storage/storage_write_after_panic", + &[], + Options { + // Do only 1 cycle per VM snapshot to really test all the boundary conditions. + cycles_per_vm_snapshot: 1, + ..Default::default() + }, + ) + } + + #[test_log::test] + fn test_storage_pubdata_refunds() { + run_asm_based_test( + "src/tests/simple_tests/testdata/log/storage/storage_pubdata_refunds", + &[], + Options { + // Do only 1 cycle per VM snapshot to really test all the boundary conditions. + cycles_per_vm_snapshot: 1, + ..Default::default() + }, + ); + } +} diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/fail_on_decommit/65536.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/fail_on_decommit/65536.asm new file mode 100644 index 0000000..ea80019 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/fail_on_decommit/65536.asm @@ -0,0 +1,12 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry +__entry: +.main: + ; bytecode fill be greatly increased + sstore r1, r1 + ${garbage} + ret.ok r0 \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/fail_on_decommit/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/fail_on_decommit/entry.asm new file mode 100644 index 0000000..a78e856 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/fail_on_decommit/entry.asm @@ -0,0 +1,36 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 +CPI0_1: + .cell 65536 + .text + .globl __entry +__entry: +.main: + ; call with 2^13 gas. + add 1, r0, r1 + shl.s 13, r1, r1 + + near_call r1, @limited, @expected_panic + revert("Near call not reverted") + +limited: + ; create ABI for far_call + ; give 6k gas + add 6000, r1, r1 + shl.s 192, r1, r1 + + ; we are calling address 65536 where we deploy inflated dummy + ; but we don't have enough gas to actually decommit it + + add @CPI0_1[0], r0, r2 + far_call r1, r2, @catch_all + + ret.ok r0 + +catch_all: + ret.panic r0 + +expected_panic: + ret.ok r0 \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/panic_on_return_large_data/65536.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/panic_on_return_large_data/65536.asm new file mode 100644 index 0000000..6289d16 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/panic_on_return_large_data/65536.asm @@ -0,0 +1,24 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry +__entry: +.main: + ; tries to return 16kb of data from the heap + ; memory stipend for user space contracts is 4kb, so we need to growth memory + + ; creating fat pointer for the return + ; forwarding byte 0 (heap) + add 0, r0, r1 + shl.s 136, r1, r1 + ; length 16000 + add 16000, r1, r1 + shl.s 32, r1, r1 + ; start at 128 + add 128, r1, r1 + shl.s 64, r1, r1 + + ; should revert with "not enough ergs for memory growth" + ret.ok r1 \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/panic_on_return_large_data/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/panic_on_return_large_data/entry.asm new file mode 100644 index 0000000..6c2f5d7 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/panic_on_return_large_data/entry.asm @@ -0,0 +1,49 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 +CPI0_0: + .cell 30272441630670900764332283662402067049651745785153368133042924362431065855 + .cell 30272434434303437454318367229716471635614919446304865000139367529706422272 +CPI0_1: + .cell 65536 ; not in kernel space + .text + .globl __entry +__entry: +.main: + ; makes 36 bytes of calldata in aux heap and calls with it + add 64, r0, r2 + add @CPI0_0[0], r0, r3 + st.2.inc r2, r3, r2 + + add @CPI0_0[1], r0, r3 + st.2 r2, r3 + + ; create ABI for far_call + ; use 2 for forwarding mode (aux heap) + add 2, r0, r1 + shl.s 32, r1, r1 + ; give 2k gas + add 2000, r1, r1 + shl.s 96, r1, r1 + add 36, r1, r1 + shl.s 32, r1, r1 + add 64, r1, r1 + shl.s 64, r1, r1 + + add @CPI0_1[0], r0, r2 + + ; should panic inside with "not enough ergs for memory growth" + far_call r1, r2, @expected_out_of_gas_on_memory_growth + + revert("Far call not reverted") + +expected_out_of_gas_on_memory_growth: + ; r1 (returned pointer) should be zero + sub! r0, r1, r0 + jump.ne @invalid_pointer_returned + + ret.ok r0 + +invalid_pointer_returned: + revert("Invalid pointer returned") \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/pay_for_memory_growth/65536.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/pay_for_memory_growth/65536.asm new file mode 100644 index 0000000..8c71fa5 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/pay_for_memory_growth/65536.asm @@ -0,0 +1,59 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 +CPI0_0: + .cell 65537 + .text + .globl __entry +__entry: +.main: + ; far call using 256 bits of data and pass 100 ergs + ; should grow memory + + near_call r0, @get_heap_bound, @panic + + ; create ABI for far_call + ; use 0 for forwarding mode (heap) + ; pass 100 ergs + add 100, r0, r1 + shl.s 96, r1, r1 + ; length 256 + add 256, r1, r1 + shl.s 32, r1, r1 + ; start at heap bound + add stack[0], r1, r1 + shl.s 64, r1, r1 + + context.ergs_left r9 + add r9, r0, stack[0] + + ; we are calling 65537 + add @CPI0_0[0], r0, r2 + far_call r1, r2, @panic + + add stack[0], r0, r10 + context.ergs_left r9 + add r9, r0, stack[0] + + shl.s 96, r1, r1 + + ret.ok r1 + +get_heap_bound: + ; get metadata of callframe + context.meta r5 + + ; prepare 32-bits mask + add 1, r0, r7 + shl.s 32, r7, r7 + sub.s 1, r7, r7 + + ; unpack heap bound + shr.s 64, r5, r6 + and r6, r7, stack[0] + + ret.ok r0 + +panic: + ret.panic r0 \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/pay_for_memory_growth/65537.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/pay_for_memory_growth/65537.asm new file mode 100644 index 0000000..a5082a9 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/pay_for_memory_growth/65537.asm @@ -0,0 +1,19 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry +__entry: +.main: + ; just return + + context.ergs_left r9 + add r9, r0, stack[0] + add stack[0], r0, r10 + + ; return 64 bits from heap + add 64, r0, r1 + shl.s 96, r1, r1 + + ret.ok r1 \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/pay_for_memory_growth/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/pay_for_memory_growth/entry.asm new file mode 100644 index 0000000..b72c11f --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/pay_for_memory_growth/entry.asm @@ -0,0 +1,34 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 +CPI0_0: + .cell 65536 ; not in kernel space + .text + .globl __entry +__entry: +.main: + ; perform far call with limited ergs + + ; create ABI for far_call + ; use 0 for forwarding mode (heap) + ; pass 1k ergs + add 1000, r0, r1 + shl.s 192, r1, r1 + + ; we are calling 65536 + add @CPI0_0[0], r0, r2 + + context.ergs_left r9 + add r9, r0, stack[0] + + far_call r1, r2, @catch_all + + add stack[0], r0, r10 + context.ergs_left r9 + add r9, r0, stack[0] + + ret.ok r0 + +catch_all: + ret.panic r0 \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/read_fat_pointer/65535.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/read_fat_pointer/65535.asm new file mode 100644 index 0000000..dae76de --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/read_fat_pointer/65535.asm @@ -0,0 +1,50 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + CPI0_0: + ; just some random values + .cell 30272441630670900764332283662402067049651745785153368133042924362431065855 + .cell 30272434434303437454318367229716471635614919446304865000139367529706422272 + .text + .globl __entry +__entry: +.main: + ; this one reads some calldata, including partially beyond the bound, + ; and completely beyond the bound, and returns + + sstore r1, r1 + event.first r1, r0 + to_l1.first r0, r1 + + ; read first 32 bytes + ld.inc r1, r2, r1 + ; should be equal to CPI0_0[0] + sub! @CPI0_0[0], r2, r0 + jump.ne @invalid_first_slot + + ; read second 32 bytes + ld.inc r1, r3, r1 + ; should be equal to first 4 bytes of CPI0_0[1] + add @CPI0_0[1], r0, r4 + shr.s 224, r4, r4 + shl.s 224, r4, r4 + sub! r4, r3, r0 + jump.ne @invalid_second_slot + + ; read 32 bytes beyond the bound + ; should be zero + ld r1, r4 + sub! r4, r0, r0 + jump.ne @invalid_third_slot + + ret.ok r0 + +invalid_first_slot: + revert("Invalid first slot") + +invalid_second_slot: + revert("Invalid second slot") + +invalid_third_slot: + revert("Invalid third slot") \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/read_fat_pointer/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/read_fat_pointer/entry.asm new file mode 100644 index 0000000..5d420a6 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/read_fat_pointer/entry.asm @@ -0,0 +1,48 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + CPI0_0: + ; just some random values + .cell 30272441630670900764332283662402067049651745785153368133042924362431065855 + .cell 30272434434303437454318367229716471635614919446304865000139367529706422272 + CPI0_1: + .cell 65535 ; in kernel space + .text + .globl __entry + __entry: + .main: + ; makes 36 bytes of calldata in aux heap and calls with it, and then does far call with fat ptr forward + + ; put data from CPI0_0 into 64 bytes on AUX heap (st.2) + add 64, r0, r2 + add @CPI0_0[0], r0, r3 + st.2.inc r2, r3, r2 + + add @CPI0_0[1], r0, r3 + st.2 r2, r3 + + ; create ABI for far_call + ; system call + add 1, r0, r1 + shl.s 24, r1, r1 + ; use 2 for forwarding mode (aux heap) + add 2, r1, r1 + shl.s 32, r1, r1 + ; give 100k gas + add 100000, r1, r1 + shl.s 96, r1, r1 + ; fat ptr length + add 36, r1, r1 + ; fat ptr start + shl.s 32, r1, r1 + add 64, r1, r1 + shl.s 64, r1, r1 + + add @CPI0_1[0], r0, r2 + far_call r1, r2, @panic + + ret.ok r0 + + panic: + ret.panic r0 \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/return_large_data/65536.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/return_large_data/65536.asm new file mode 100644 index 0000000..a436fc6 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/return_large_data/65536.asm @@ -0,0 +1,25 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry +__entry: +.main: + ; tries to return 2kb of data from the heap + ; should not growth memory + + sstore r1, r1 + + ; creating fat pointer for the return + ; forwarding byte 2 (aux heap) + add 2, r0, r1 + shl.s 136, r1, r1 + ; length 2048 + add 2048, r1, r1 + shl.s 32, r1, r1 + ; start at 128 + add 128, r1, r1 + shl.s 64, r1, r1 + + ret.ok r1 \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/return_large_data/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/return_large_data/entry.asm new file mode 100644 index 0000000..c5bff86 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/far_call/return_large_data/entry.asm @@ -0,0 +1,49 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 +CPI0_0: + .cell 30272441630670900764332283662402067049651745785153368133042924362431065855 + .cell 30272434434303437454318367229716471635614919446304865000139367529706422272 +CPI0_1: + .cell 65536 ; not in kernel space + .text + .globl __entry +__entry: +.main: + ; makes 36 bytes of calldata in aux heap and calls with it + + ; put data from CPI0_0 into 64 bytes on AUX heap (st.2) + add 64, r0, r2 + add @CPI0_0[0], r0, r3 + st.2.inc r2, r3, r2 + + add @CPI0_0[1], r0, r3 + st.2 r2, r3 + + ; create ABI for far_call + ; use 2 for forwarding mode (aux heap) + add 2, r0, r1 + shl.s 32, r1, r1 + ; give 100k gas + add 100000, r1, r1 + shl.s 96, r1, r1 + add 36, r1, r1 + shl.s 32, r1, r1 + add 64, r1, r1 + shl.s 64, r1, r1 + + add @CPI0_1[0], r0, r2 + + ; call the 65536 contract + far_call r1, r2, @panic + + ; use forward pointer mode + add 1, r0, r2 + shl.s 224, r2, r2 + ptr.pack r1, r2, r1 + + ret.ok r1 + +panic: + ret.panic r0 \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/decommit_invalid/800000.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/decommit_invalid/800000.asm new file mode 100644 index 0000000..4a60056 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/decommit_invalid/800000.asm @@ -0,0 +1,10 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry + __entry: + .main: + ; empty contract. Do not change, as its hash is hardcoded in entry.asm. + ret.ok r0 \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/decommit_invalid/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/decommit_invalid/entry.asm new file mode 100644 index 0000000..3365785 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/decommit_invalid/entry.asm @@ -0,0 +1,13 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry + __entry: + .main: + add 10000, r0, r1 + ; this decommit is invalid + log.decommit r1, r2, r3 + ret.ok r0 + \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/decommit_ok/800000.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/decommit_ok/800000.asm new file mode 100644 index 0000000..4a60056 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/decommit_ok/800000.asm @@ -0,0 +1,10 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry + __entry: + .main: + ; empty contract. Do not change, as its hash is hardcoded in entry.asm. + ret.ok r0 \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/decommit_ok/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/decommit_ok/entry.asm new file mode 100644 index 0000000..55f96ca --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/decommit_ok/entry.asm @@ -0,0 +1,38 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + CPI0_0: + ; this is the hash of the contract in 800000.asm + .cell 452312938437537823148903869859771978505772238111866864847149311043017845250 + .text + .globl __entry + __entry: + .main: + add 10000, r0, r4 + near_call r4, @inner, @handler + + ret.ok r0 + + inner: + add @CPI0_0[0], r0, r1 + context.ergs_left r9 + ; extra cost + add 2000, r0, r2 + log.decommit r1, r2, r3 + context.ergs_left r10 + + ; so after the call, we should have burned at least 2k gas. + sub.s 2000, r9, r11 + ; assert(r9-2000 >= r10) - make sure that we really burned 2k gas + sub! r11, r10, r0 + jump.lt @invalid_gas_burn + + ret.ok r0 + + handler: + ret.panic r0 + + invalid_gas_burn: + revert("Invalid gas burn in decommit") + \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/decommit_ok_twice/800000.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/decommit_ok_twice/800000.asm new file mode 100644 index 0000000..24334c4 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/decommit_ok_twice/800000.asm @@ -0,0 +1,10 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry + __entry: + .main: + ; empty contract + ret.ok r0 \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/decommit_ok_twice/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/decommit_ok_twice/entry.asm new file mode 100644 index 0000000..8132c2e --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/decommit_ok_twice/entry.asm @@ -0,0 +1,59 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + HASHES: + ; this is the hash of the contract in 800000.asm + .cell <800000.asm> + ADDRESSES: + .cell 800000 + .text + .globl __entry + __entry: + .main: + ; create ABI fo far call + ; use 0 for forwarding mode + add 0, r0, r1 + shl.s 32, r1, r1 + ; give 10k gas + add 10000, r1, r1 + shl.s 96, r1, r1 + add 36, r1, r1 + shl.s 32, r1, r1 + add 64, r1, r1 + shl.s 64, r1, r1 + + add @ADDRESSES[0], r0, r2 + + ; far call should also decommit 800000 + far_call r1, r2, @panic + + ; now we are trying to decommit it again + add 15000, r0, r4 + near_call r4, @inner, @panic + + ret.ok r0 + + inner: + add @HASHES[0], r0, r1 + ; add extra cost, we expect it to be refunded + ; since we are decommiting already decomitted contract + add 2000, r0, r2 + context.ergs_left r9 + log.decommit r1, r2, r3 + context.ergs_left r10 + + ; so after the call, we should have burned some gas and received 2k refund. + sub.s 2000, r9, r11 + ; assert(r9-2000 <= r10) - make sure that we did not burn 2k gas + sub! r11, r10, r0 + jump.gt @invalid_gas_burn + + ret.ok r0 + + panic: + ret.panic r0 + + invalid_gas_burn: + revert("Invalid gas burn in decommit") + \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/decommit_ok_with_panic/800000.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/decommit_ok_with_panic/800000.asm new file mode 100644 index 0000000..4a60056 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/decommit_ok_with_panic/800000.asm @@ -0,0 +1,10 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry + __entry: + .main: + ; empty contract. Do not change, as its hash is hardcoded in entry.asm. + ret.ok r0 \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/decommit_ok_with_panic/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/decommit_ok_with_panic/entry.asm new file mode 100644 index 0000000..7833b4f --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/decommit_ok_with_panic/entry.asm @@ -0,0 +1,29 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + CPI0_0: + ; this is the hash of the contract in 800000.asm + .cell 452312938437537823148903869859771978505772238111866864847149311043017845250 + .text + .globl __entry + __entry: + .main: + add 10000, r0, r4 + near_call r4, @inner, @handler + + revert("Near call not reverted") + + inner: + add @CPI0_0[0], r0, r1 + context.ergs_left r9 + ; extra cost - too large, will panic + add 20000, r0, r2 + log.decommit r1, r2, r3 + + ret.ok r0 + + handler: + ; we expect the near_call to panic + ret.ok r0 + \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/l1_message_has_zero_pubdata_cost/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/l1_message_has_zero_pubdata_cost/entry.asm new file mode 100644 index 0000000..95511d3 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/l1_message_has_zero_pubdata_cost/entry.asm @@ -0,0 +1,45 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry +__entry: +.main: + add 1000, r0, r1 + + ; pass 1000 gas + near_call r1, @inner, @failed_to_l1 + + near_call r0, @get_pubdata_counter, @panic + + ; check that pubdata counter is 0 + sub! stack[0], r0, r0 + jump.ne @panic_pubdata_counter_changed + + ret.ok r0 + +inner: + to_l1 r0, r1 + ret.ok r0 + +failed_to_l1: + revert("Can not send a message") + +get_pubdata_counter: + ; prepare a 32-bit mask (0xffff..) + add 1, r0, r10 + shl.s 32, r10, r10 + sub.s 1, r10, r10 + + ; get the pubdata counter + context.meta r7 + and r10, r7, stack[0] + + ret.ok r0 + +panic: + ret.panic r0 + +panic_pubdata_counter_changed: + revert("Pubdata counter changed") \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/l1_message_out_of_gas/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/l1_message_out_of_gas/entry.asm new file mode 100644 index 0000000..2c02c58 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/l1_message_out_of_gas/entry.asm @@ -0,0 +1,51 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry +__entry: +.main: + add 100, r0, r1 + + ; pass 100 gas + ; should revert inside + near_call r1, @inner, @expected_panic + + revert("Near call not panicked") + +inner: + ; trying to send message to l1 + ; but do not have enough gas + ; to_l1 does not have any pubdata cost + to_l1 r0, r1 + ret.ok r0 + +expected_panic: + near_call r0, @get_pubdata_counter, @panic + + ; check that pubdata counter is 0 + sub! stack[0], r0, r0 + jump.ne @panic_pubdata_counter_changed + + context.ergs_left r15 + + ret.ok r0 + +get_pubdata_counter: + ; prepare a 32-bit mask (0xffff..) + add 1, r0, r10 + shl.s 32, r10, r10 + sub.s 1, r10, r10 + + ; get the pubdata counter + context.meta r7 + and r10, r7, stack[0] + + ret.ok r0 + +panic: + ret.panic r0 + +panic_pubdata_counter_changed: + revert("Pubdata counter changed") \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/precompile_invalid_address/65399.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/precompile_invalid_address/65399.asm new file mode 100644 index 0000000..b291792 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/precompile_invalid_address/65399.asm @@ -0,0 +1,62 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry +__entry: +.main: + ; 2 lower bytes of this contract address are used as precompile address + ; we are in 65399 that should have address ending with 0xFF77 + ; precompile call - address 0xFF77, ABI is empty, AuxData (additional costs - 0 for now) + ; we are calling invalid precompile address, nothing should happen + log.precompile r0, r3, r4 + + ; Add extra ~16k cost + ; extra pubdata cost 2^32 - 1 + add 1, r0, r3 + shl.s 32, r3, r3 + ; extra gas cost 2^14 (~16k) + add 1, r3, r3 + shl.s 14, r3, r3 + + ; precompile call - address 0xFF77 (invalid), ABI is empty, AuxData (additional costs ~16k) + ; should burn gas + context.ergs_left r9 + log.precompile r0, r3, r4 + context.ergs_left r10 + + ; so after the precompile call, we should have burned at least 16k gas. + sub.s 16000, r9, r11 + ; assert(r9-16000 >= r10) - make sure that we really burned 16k gas + sub! r11, r10, r0 + jump.lt @not_burned_gas + + add 10000, r0, r1 + ; pass 10k gas + near_call r1, @out_of_gas_inner, @expected_panic + + revert("Near call not reverted") + +out_of_gas_inner: + to_l1 r0, r1 + + ; Add extra ~16k cost (more than this near call has) + ; extra pubdata cost 2^32 - 1 + add 1, r0, r3 + shl.s 32, r3, r3 + ; extra gas cost 2^14 (~16k) + add 1, r3, r3 + shl.s 14, r3, r3 + + ; precompile call - address 0xFF77 (invalid), ABI is empty, AuxData (additional costs ~16k) + log.precompile r0, r3, r4 + ret.ok r0 + +expected_panic: + ; we expect the near_call to panic + ret.ok r0 + +not_burned_gas: + revert("Precompile call not burned gas") + \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/precompile_invalid_address/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/precompile_invalid_address/entry.asm new file mode 100644 index 0000000..53a3654 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/precompile_invalid_address/entry.asm @@ -0,0 +1,32 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 +CPI0_0: + .cell 65399 + .text + .globl __entry +__entry: +.main: + ; We will try to call invalid precompile address inside 65399 contract + + ; create ABI for far_call + ; use 0 for forwarding mode + add 0, r0, r1 + shl.s 32, r1, r1 + ; give 100k gas + add 100000, r1, r1 + shl.s 96, r1, r1 + add 36, r1, r1 + shl.s 32, r1, r1 + add 64, r1, r1 + shl.s 64, r1, r1 + + add @CPI0_0[0], r0, r2 + + far_call r1, r2, @catch_all + + ret.ok r0 + +catch_all: + ret.panic r0 \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/precompile_out_of_gas/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/precompile_out_of_gas/entry.asm new file mode 100644 index 0000000..9b00baf --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/precompile_out_of_gas/entry.asm @@ -0,0 +1,36 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry + __entry: + .main: + ; 2 lower bytes of this contract address are used as precompile address + ; we are in bootloader that should have address ending with 0x8001 + ; precompile call - address 0x1, ABI is empty, AuxData (additional costs - 0 for now) + log.precompile r0, r3, r4 + + add 10000, r0, r1 + ; pass 10k gas + near_call r1, @inner, @handler + + revert("Near call not reverted") + inner: + to_l1 r0, r1 + + ; Add extra ~16k cost (more than this near call has) + ; extra pubdata cost 2^32 - 1 + add 1, r0, r3 + shl.s 32, r3, r3 + ; extra gas cost 2^14 (~16k) + add 1, r3, r3 + shl.s 14, r3, r3 + + ; precompile call - address 0x1, ABI is empty, AuxData (additional costs ~16k) + log.precompile r0, r3, r4 + ret.ok r0 + handler: + ; we expect the near_call to panic + ret.ok r0 + \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/storage/storage_clear_slot/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/storage/storage_clear_slot/entry.asm new file mode 100644 index 0000000..474c1c9 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/storage/storage_clear_slot/entry.asm @@ -0,0 +1,25 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry +__entry: +.main: + near_call r0, @inner, @handler + context.ergs_left r15 + + ret.ok r0 + +inner: + add 10000, r0, r1 + add 1000, r0, r10 + ; write 1000 to slot 10000 + sstore r1, r10 + ; write 0 to slot 10000 + sstore r1, r0 + + ret.ok r0 + +handler: + ret.panic r0 \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/storage/storage_pubdata_refunds/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/storage/storage_pubdata_refunds/entry.asm new file mode 100644 index 0000000..06e6d44 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/storage/storage_pubdata_refunds/entry.asm @@ -0,0 +1,64 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry +__entry: +.main: + ; allocate 20k gas for 2 writes and 2 reads + ; each write takes about 5k gas + add 20000, r0, r4 + + ; perform write via near call + near_call r4, @inner_storage_handler, @.panic + + ret.ok r0 + +inner_storage_handler: + ; we'll be writing 13 at slot 25 with a warm refund of 5400 + set_storage_warm(5400) + add 25, r0, r1 + add 13, r0, r2 + context.ergs_left r7 + add r7, r0, stack[0] + log.swrite r1, r2, r0 + context.ergs_left r7 + + ; check that we spent less than 5k gas (we have refund) + sub stack[0], r7, r7 + sub!.s 5000, r7, r0 + jump.gt @not_refunded_gas + + ; we'll be writing 19 at slot 25 with a cold storage refund + set_storage_cold() + add 19, r0, r2 + context.ergs_left r7 + add r7, r0, stack[0] + log.swrite r1, r2, r0 + context.ergs_left r7 + + ; check that we spent more than 5k gas (we do not have refund) + sub stack[0], r7, r7 + sub!.s 5000, r7, r0 + jump.lt @not_enough_gas_spent_cold + + ; read slot 25 with a warm refund of 1900 + set_storage_warm(1900) + log.sread r1, r0, r5 + + ; read slot 19 with a cold storage refund + set_storage_cold() + add 19, r0, r1 + log.sread r1, r0, r6 + + ret.ok r0 + +not_refunded_gas: + revert("Gas for write not refunded") + +not_enough_gas_spent_cold: + revert("Cold write gas spent too low") + +.panic: + ret.panic r0 \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/storage/storage_reads/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/storage/storage_reads/entry.asm new file mode 100644 index 0000000..0f76a7d --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/storage/storage_reads/entry.asm @@ -0,0 +1,84 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry + __entry: + .main: + + add 10000, r0, r4 + shl.s 3, r4, r4 + + near_call r4, @inner, @.panic + + ; + ; Basic test to see that sread and treads are reading from different locations. + ; + + ; write 28 to position 15 + add 15, r0, r1 + add 28, r0, r2 + + log.swrite r1, r2, r0 + + ; swrite key, value, UNUSED + ; tread key, UNUSED, destination + ; log.event key, value, UNUSED + + log.sread r1, r0, r5 + ; assert r5 == 28 + sub! 28, r5, r0 + jump.ne @.panic + + ; tread should return 19 from this slot (written in near call) + log.tread r1, r0, r6 + sub! 19, r6, r0 + jump.ne @.panic + + near_call r4, @inner, @handler + ; We should never get here - as the near_call should panic due to out of gas. + ret.ok r0 + + inner: + add 15, r0, r1 + add 18, r0, r2 + add 19, r0, r3 + + ; + ; Write to the same slot in storage and temp storage. + ; + + log.sread r1, r0, r5 + ; assert r5 == 0 + sub! 0, r5, r0 + jump.ne @.panic + + log.tread r1, r0, r5 + ; assert r5 == 0 + sub! 0, r5, r0 + jump.ne @.panic + + ; write 18 to position 15 + log.swrite r1, r2, r0 + ; write 19 to position 15 (but in temp storage) + log.twrite r1, r3, r0 + log.sread r1, r0, r5 + ; assert r5 == 18 + sub! 18, r5, r0 + jump.ne @.panic + + log.tread r1, r0, r5 + ; assert r5 == 19 + sub! 19, r5, r0 + jump.ne @.panic + + ret.ok r0 + + handler: + ; we expect the near_call to panic + ret.ok r0 + + .panic: + ret.panic r0 + \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/storage/storage_write_after_panic/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/storage/storage_write_after_panic/entry.asm new file mode 100644 index 0000000..5584339 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/storage/storage_write_after_panic/entry.asm @@ -0,0 +1,26 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry +__entry: +.main: + add 1000, r0, r3 + near_call r3, @test_panic, @expected_panic + revert("Near call not panicked") + +test_panic: + add 1000, r0, r3 + near_call r3, @test_panic2, @expected_panic2 + +expected_panic: + ; check that we can access storage after panic + log.swrite r0, r0, r0 + ret.ok r0 + +test_panic2: + ret.ok r0 + +expected_panic2: + ret.panic r0 \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/storage/storage_write_rollback_no_reads/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/storage/storage_write_rollback_no_reads/entry.asm new file mode 100644 index 0000000..a11ab6b --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/storage/storage_write_rollback_no_reads/entry.asm @@ -0,0 +1,24 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry +__entry: +.main: + near_call r0, @inner, @expected_panic + + revert("Near call not panicked") + +inner: + add 10000, r0, r1 + add 1000, r0, r10 + + ; write 1000 to storage slot 10000 + sstore r1, r10 + + ret.panic r0 + +expected_panic: + context.ergs_left r15 + ret.ok r0 \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/storage/storage_write_rollback_reads/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/storage/storage_write_rollback_reads/entry.asm new file mode 100644 index 0000000..e5e8528 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/storage/storage_write_rollback_reads/entry.asm @@ -0,0 +1,35 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry +__entry: +.main: + near_call r1, @inner, @expected_panic + + revert("Near call not panicked") + +inner: + add 10000, r0, r1 + add 1000, r0, r10 + ; write 1000 to storage slot 10000 + sstore r1, r10 + + ret.panic r0 + +expected_panic: + context.ergs_left r15 + + ; read value from storage slot 10000 + add 10000, r0, r1 + sload r1, r2 + + ; check that value is 0 + sub! r0, r2, r0 + jump.ne @invalid_storage_value + + ret.ok r0 + +invalid_storage_value: + revert("Invalid value in storage") \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/storage/storage_writes/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/storage/storage_writes/entry.asm new file mode 100644 index 0000000..b84acea --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/log/storage/storage_writes/entry.asm @@ -0,0 +1,98 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry + __entry: + .main: + ; each write costs around 5k. + ; start the test by giving 20k to do 2 writes + add 20000, r0, r4 + + ; just do 2 writes. + near_call r4, @inner_2_writes_ok, @.panic + + ; now do the call that will run out of gas. + add 10000, r0, r4 + near_call r4, @inner_out_of_gas_during_write, @inner_out_of_gas_handler + ret.panic r0 + + inner_out_of_gas_during_write: + ; check that pubdata counter is 0 + context.meta r7 + and r10, r7, r7 + sub! 0, r7, r0 + jump.ne @.panic + + ; we'll be writing 24 in slot 25 + + add 25, r0, r1 + add 24, r0, r2 + log.swrite r1, r2, r0 + + ; check that pubdata counter is 65 (after first write) + context.meta r7 + and r10, r7, r7 + sub! 65, r7, r0 + jump.ne @.panic + + ; and then the second write should fail out of gas. + log.swrite r1, r2, r0 + + ; if we ever get here - just return ok - as the caller will panic. + ret.ok r0 + + inner_out_of_gas_handler: + ; check pubdata counter (should be equal to 130; from the first 2 writes) + context.meta r7 + and r10, r7, r7 + sub! 130, r7, r8 + jump.ne @.panic + + ; expect the value in slot 25 to be 14 (from the second successful write) + add 25, r0, r1 + log.sread r1, r0, r2 + sub! 14, r2, r0 + jump.ne @.panic + + ret.ok r0 + + inner_2_writes_ok: + ; prepare a 32-bit mask (0xffff..) + add 1, r0, r10 + shl.s 32, r10, r10 + sub.s 1, r10, r10 + + ; check pubdata counter (should be equal to 0) + context.meta r7 + and r10, r7, r7 + sub! 0, r7, r0 + jump.ne @.panic + + ; we'll be writing 13 at slot 25 + add 25, r0, r1 + add 13, r0, r2 + log.swrite r1, r2, r0 + + ; now pubdata counter should be equal to 65 + context.meta r7 + and r10, r7, r7 + sub! 65, r7, r0 + jump.ne @.panic + + ; write a value 14 again to the same slot + add 1, r2, r2 + log.swrite r1, r2, r0 + + ; now pubdata counter should be equal to 130 + context.meta r7 + and r10, r7, r7 + sub! 130, r7, r0 + jump.ne @.panic + + ret.ok r0 + + .panic: + ret.panic r0 + \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/far_call/dummy.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/far_call/dummy.asm new file mode 100644 index 0000000..7a01b1a --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/far_call/dummy.asm @@ -0,0 +1,9 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry + __entry: + .main: + ret.ok r0 \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/far_call/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/far_call/entry.asm new file mode 100644 index 0000000..892c86e --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/far_call/entry.asm @@ -0,0 +1,30 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + CPI0_0: + .cell ${far_call_test_address} + .text + .globl __entry + __entry: + .main: + ; we are checking memory growth in separate contract + ; since our "bootloader" has MAX memory allocated in heaps + + ; memory stipend differs between kernel and non-kernel contracts + + ; create ABI for far_call + add 2, r0, r1 + shl.s 32, r1, r1 + ; give 100k gas + add 100000, r1, r1 + shl.s 192, r1, r1 + + add @CPI0_0[0], r0, r2 + ; call the other_asm contract + far_call r1, r2, @handler + + ret.ok r0 + + handler: + ret.panic r0 \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/far_call/far_call_test.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/far_call/far_call_test.asm new file mode 100644 index 0000000..ae6857e --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/far_call/far_call_test.asm @@ -0,0 +1,117 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + CPI0_0: + .cell ${dummy_address} + .text + .globl __entry + __entry: + .main: + ; checking memory growth + ; 4 KB for new non-kernel frames is "free" + ; 2 MB for new kernel frames is "free" + + ; get initial bounds + near_call r0, @get_heap_bounds, @panic + ; heap initial bound + add stack[0], r0, r11 + add stack[0], r0, stack[2] + ; aux heap initial bound + add stack[1], r0, r12 + add stack[1], r0, stack[3] + + ; create ABI for far_call + ; pointer for heap memory + add 0, r0, r1 + shl.s 32, r1, r1 + ; give 10k gas + add 100000, r1, r1 + shl.s 64, r1, r1 + shl.s 32, r1, r1 + ; length is greater than heap bound + add r11, r1, r1 + add 32, r1, r1 + shl.s 96, r1, r1 + + add @CPI0_0[0], r0, r2 + ; call the dummy contract + ; should increase heap bound + far_call r1, r2, @panic + + ; check bounds + ; new expected bound for heap + add stack[2], r0, r13 + add 32, r13, r13 + + add stack[3], r0, r12 + + near_call r0, @get_heap_bounds, @panic + sub! stack[0], r13, r0 + jump.ne @invalid_memory_growth + sub! stack[1], r12, r0 + jump.ne @unexpected_memory_growth + + ; create ABI for far_call + ; pointer for aux heap memory + add 2, r0, r1 + shl.s 32, r1, r1 + ; give 10k gas + add 100000, r1, r1 + shl.s 64, r1, r1 + shl.s 32, r1, r1 + ; length is greater than heap bounds + add r12, r1, r1 + add 32, r1, r1 + shl.s 96, r1, r1 + + add @CPI0_0[0], r0, r2 + ; call the dummy contract + ; should increase aux heap bound + far_call r1, r2, @panic + + ; check bounds + ; new expected bounds for heaps + add stack[2], r0, r13 + add 32, r13, r13 + + add stack[3], r0, r14 + add 32, r14, r14 + + near_call r0, @get_heap_bounds, @panic + sub! stack[0], r13, r0 + jump.ne @invalid_memory_growth + sub! stack[1], r14, r0 + jump.ne @invalid_memory_growth + + ret.ok r0 + + get_heap_bounds: + ; get metadata of callframe + context.meta r5 + + ; prepare 32-bits mask + add 1, r0, r7 + shl.s 32, r7, r7 + sub.s 1, r7, r7 + + ; unpack heap bound + shr.s 64, r5, r6 + and r6, r7, stack[0] + + ; unpack aux heap bound + shr.s 96, r5, r6 + and r6, r7, stack[1] + + ret.ok r0 + + panic: + print("PANIC HANDLER") + ret.panic r0 + + invalid_memory_growth: + revert("Should growth memory") + + unexpected_memory_growth: + revert("Unexpected memory growth") + diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/heap_write/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/heap_write/entry.asm new file mode 100644 index 0000000..24a04da --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/heap_write/entry.asm @@ -0,0 +1,30 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + CPI0_0: + .cell ${heaps_grows_test_contract_address} + .text + .globl __entry + __entry: + .main: + ; we are checking memory growth in separate contract + ; since our "bootloader" has MAX memory allocated in heaps + + ; memory stipend differs between kernel and non-kernel contracts + + ; create ABI for far_call + add 2, r0, r1 + shl.s 32, r1, r1 + ; give 100k gas + add 100000, r1, r1 + shl.s 192, r1, r1 + + add @CPI0_0[0], r0, r2 + ; call the other_asm contract + far_call r1, r2, @handler + + ret.ok r0 + + handler: + ret.panic r0 \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/heap_write/heaps_grows_test.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/heap_write/heaps_grows_test.asm new file mode 100644 index 0000000..b1936b2 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/heap_write/heaps_grows_test.asm @@ -0,0 +1,103 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry + __entry: + .main: + ; checking memory growth + ; 4 KB for new non-kernel frames is "free" + ; 2 MB for new kernel frames is "free" + + ; get initial bounds + near_call r0, @get_heap_bounds, @panic + ; heap initial bound + add stack[0], r0, r11 + ; aux heap initial bound + add stack[1], r0, r12 + + ; write 8 to last preallocated heap slot + ; should not growth memory + add r11, r0, r2 + sub.s 32, r2, r2 + add 8, r0, r3 + st.1 r2, r3 + + ; write 8 to last preallocated aux heap slot + ; should not growth memory + add r12, r0, r2 + sub.s 32, r2, r2 + st.2 r2, r3 + + ; check bounds + ; bounds should not change + near_call r0, @get_heap_bounds, @panic + sub! stack[0], r11, r0 + jump.ne @unexpected_memory_growth + sub! stack[1], r12, r0 + jump.ne @unexpected_memory_growth + + + ; write 8 to fisrt out-of-bounds heap slot + ; should growth memory + add r11, r0, r2 + add 8, r0, r3 + st.1 r2, r3 + + ; new expected bound for heap + add 32, r11, r13 + + ; aux bound should not change + near_call r0, @get_heap_bounds, @panic + sub! stack[0], r13, r0 + jump.ne @invalid_memory_growth + sub! stack[1], r12, r0 + jump.ne @unexpected_memory_growth + + ; write 8 to fisrt out-of-bounds aux heap slot + ; should growth memory + add r12, r0, r2 + add 8, r0, r3 + st.2 r2, r3 + + ; new expected bound for aux heap + add 32, r12, r14 + + ; bounds should be changed + near_call r0, @get_heap_bounds, @panic + sub! stack[0], r13, r0 + jump.ne @invalid_memory_growth + sub! stack[1], r14, r0 + jump.ne @invalid_memory_growth + + ret.ok r0 + + get_heap_bounds: + ; get metadata of callframe + context.meta r5 + + ; prepare 32-bits mask + add 1, r0, r7 + shl.s 32, r7, r7 + sub.s 1, r7, r7 + + ; unpack heap bound + shr.s 64, r5, r6 + and r6, r7, stack[0] + + ; unpack aux heap bound + shr.s 96, r5, r6 + and r6, r7, stack[1] + + ret.ok r0 + + panic: + ret.panic r0 + + invalid_memory_growth: + revert("Should growth memory") + + unexpected_memory_growth: + revert("Unexpected memory growth") + diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/ret/aux_heap_test.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/ret/aux_heap_test.asm new file mode 100644 index 0000000..ba2df40 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/ret/aux_heap_test.asm @@ -0,0 +1,47 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry + __entry: + .main: + ; checking memory growth + ; 4 KB for new non-kernel frames is "free" + ; 2 MB for new kernel frames is "free" + + ; get initial bounds + near_call r0, @get_aux_heap_bound, @panic + + ; create fresh pointer to return from aux heap + add 2, r0, r1 + shl.s 32, r1, r1 + shl.s 64, r1, r1 + + ; length is greater than our bound + shl.s 32, r1, r1 + add stack[1], r1, r1 + add 32, r1, r1 + shl.s 96, r1, r1 + + ; should allocate memory + ret.ok r1 + + get_aux_heap_bound: + ; get metadata of callframe + context.meta r5 + + ; prepare 32-bits mask + add 1, r0, r7 + shl.s 32, r7, r7 + sub.s 1, r7, r7 + + ; unpack aux heap bound + shr.s 96, r5, r6 + and r6, r7, stack[1] + + ret.ok r0 + + panic: + ret.panic r0 + diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/ret/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/ret/entry.asm new file mode 100644 index 0000000..bb57533 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/ret/entry.asm @@ -0,0 +1,45 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + CPI0_0: + ; heap test contract + .cell ${heap_test_contract_address} + CPI0_1: + ; aux test contract + .cell ${aux_heap_test_contract_address} + .text + .globl __entry + __entry: + .main: + ; we are checking memory growth in separate contract + ; since our "bootloader" has MAX memory allocated in heaps + + ; memory stipend differs between kernel and non-kernel contracts + + ; create ABI for far_call + add 2, r0, r1 + shl.s 32, r1, r1 + ; give 100k gas + add 100000, r1, r1 + shl.s 192, r1, r1 + + ; check heap growth + add @CPI0_0[0], r0, r2 + far_call r1, r2, @handler + + ; create ABI for far_call + add 2, r0, r1 + shl.s 32, r1, r1 + ; give 100k gas + add 100000, r1, r1 + shl.s 192, r1, r1 + + ; check aux growth + add @CPI0_1[0], r0, r2 + far_call r1, r2, @handler + + ret.ok r0 + + handler: + ret.panic r0 \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/ret/heap_test.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/ret/heap_test.asm new file mode 100644 index 0000000..38667e2 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/ret/heap_test.asm @@ -0,0 +1,47 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry + __entry: + .main: + ; checking memory growth + ; 4 KB for new non-kernel frames is "free" + ; 2 MB for new kernel frames is "free" + + ; get initial bounds + near_call r0, @get_heap_bound, @panic + + ; create fresh pointer to return from heap + add 0, r0, r1 + shl.s 32, r1, r1 + shl.s 64, r1, r1 + + ; length is greater than our bound + shl.s 32, r1, r1 + add stack[0], r1, r1 + add 32, r1, r1 + shl.s 96, r1, r1 + + ; should allocate memory + ret.ok r1 + + get_heap_bound: + ; get metadata of callframe + context.meta r5 + + ; prepare 32-bits mask + add 1, r0, r7 + shl.s 32, r7, r7 + sub.s 1, r7, r7 + + ; unpack heap bound + shr.s 64, r5, r6 + and r6, r7, stack[0] + + ret.ok r0 + + panic: + ret.panic r0 + diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/ret_out_of_ergs/aux_heap_test.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/ret_out_of_ergs/aux_heap_test.asm new file mode 100644 index 0000000..bbb7408 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/ret_out_of_ergs/aux_heap_test.asm @@ -0,0 +1,49 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry + __entry: + .main: + ; checking memory growth + ; 4 KB for new non-kernel frames is "free" + ; 2 MB for new kernel frames is "free" + + ; get initial bounds + near_call r0, @get_aux_heap_bound, @panic + + ; create fresh pointer to return from aux heap + add 2, r0, r1 + shl.s 32, r1, r1 + shl.s 64, r1, r1 + + ; length in pointer is too big + add 16000, r0, r4 + add stack[1], r4, r4 + + shl.s 32, r1, r1 + add r4, r1, r1 + shl.s 96, r1, r1 + + ; should revert with out of gas + ret.ok r1 + + get_aux_heap_bound: + ; get metadata of callframe + context.meta r5 + + ; prepare 32-bits mask + add 1, r0, r7 + shl.s 32, r7, r7 + sub.s 1, r7, r7 + + ; unpack aux heap bound + shr.s 96, r5, r6 + and r6, r7, stack[1] + + ret.ok r0 + + panic: + ret.panic r0 + diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/ret_out_of_ergs/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/ret_out_of_ergs/entry.asm new file mode 100644 index 0000000..369cd15 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/ret_out_of_ergs/entry.asm @@ -0,0 +1,51 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + CPI0_0: + ; heap test contract + .cell ${heap_test_contract_address} + CPI0_1: + ; aux test contract + .cell ${aux_heap_test_contract_address} + .text + .globl __entry + __entry: + .main: + ; we are checking memory growth in separate contract + ; since our "bootloader" has MAX memory allocated in heaps + + ; memory stipend differs between kernel and non-kernel contracts + + jump @first_call + + first_call: + ; create ABI for far_call + add 2, r0, r1 + shl.s 32, r1, r1 + ; give 10k gas + add 10000, r1, r1 + shl.s 192, r1, r1 + + ; check heap growth + add @CPI0_0[0], r0, r2 + ; we expect far call to revert + far_call r1, r2, @second_call + revert("Far call not reverted") + + second_call: + ; create ABI for far_call + add 2, r0, r1 + shl.s 32, r1, r1 + ; give 10k gas + add 10000, r1, r1 + shl.s 192, r1, r1 + + ; check aux growth + add @CPI0_1[0], r0, r2 + ; we expect far call to revert + far_call r1, r2, @ok + revert("Far call not reverted") + + ok: + ret.ok r0 \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/ret_out_of_ergs/heap_test.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/ret_out_of_ergs/heap_test.asm new file mode 100644 index 0000000..16b6fe1 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/memory_growth/ret_out_of_ergs/heap_test.asm @@ -0,0 +1,49 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry + __entry: + .main: + ; checking memory growth + ; 4 KB for new non-kernel frames is "free" + ; 2 MB for new kernel frames is "free" + + ; get initial bounds + near_call r0, @get_heap_bound, @panic + + ; create fresh pointer to return from heap + add 0, r0, r1 + shl.s 32, r1, r1 + shl.s 64, r1, r1 + + ; length in pointer is too big + add 16000, r0, r4 + add stack[0], r4, r4 + + shl.s 32, r1, r1 + add r4, r1, r1 + shl.s 96, r1, r1 + + ; should revert with out of gas + ret.ok r1 + + get_heap_bound: + ; get metadata of callframe + context.meta r5 + + ; prepare 32-bits mask + add 1, r0, r7 + shl.s 32, r7, r7 + sub.s 1, r7, r7 + + ; unpack heap bound + shr.s 64, r5, r6 + and r6, r7, stack[0] + + ret.ok r0 + + panic: + ret.panic r0 + diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/meta_opcode/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/meta_opcode/entry.asm new file mode 100644 index 0000000..ee70597 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/meta_opcode/entry.asm @@ -0,0 +1,23 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry +__entry: +.main: + add 32, r0, r2 + add 64, r0, r3 + st.1.inc r2, r3, r2 + st.2.inc r2, r3, r2 + ; execute each possible context opcode + context.set_ergs_per_pubdata r2 + context.set_context_u128 r3 + context.inc_tx_num + context.meta r5 + context.sp r6 + context.ergs_left r7 + context.this r8 + context.caller r9 + context.code_source r10 + ret.ok r0 \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/near_call/limited_ergs/65536.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/near_call/limited_ergs/65536.asm new file mode 100644 index 0000000..9e45219 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/near_call/limited_ergs/65536.asm @@ -0,0 +1,32 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry + __entry: + .main: + add 32, r0, r1 + ; should revert with out of ergs inside + near_call r1, @inner, @expected_out_of_ergs + revert("Near call not reverted") + + inner: + sstore r0, r0 + add 64, r0, r3 + st.1.inc r2, r3, r2 + ret.ok r0 + + expected_out_of_ergs: + context.ergs_left r15 + jump @check_limited_ok + + check_limited_ok: + add 15000, r0, r1 + ; should not revert with out of ergs inside + near_call r1, @inner, @panic + context.ergs_left r15 + ret.ok r0 + + panic: + ret.panic r0 \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/near_call/limited_ergs/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/near_call/limited_ergs/entry.asm new file mode 100644 index 0000000..85c166e --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/near_call/limited_ergs/entry.asm @@ -0,0 +1,25 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + CPI0_0: + .cell 65536 + .text + .globl __entry + __entry: + .main: + ; far call with 50000 ergs + add 50000, r0, r1 + shl.s 192, r1, r1 + context.ergs_left r9 + add r9, r0, stack[0] + add @CPI0_0[0], r0, r2 + + far_call r1, r2, @catch_all + + add stack[0], r0, r10 + context.ergs_left r9 + add r9, r0, stack[0] + ret.ok r0 + catch_all: + ret.panic r0 \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/near_call/memory_growth_ret_ok/65536.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/near_call/memory_growth_ret_ok/65536.asm new file mode 100644 index 0000000..426a5bb --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/near_call/memory_growth_ret_ok/65536.asm @@ -0,0 +1,76 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry + __entry: + .main: + ; open a near call frame, grow heap and return + near_call r0, @inner, @panic + + ; load saved heap bound + add stack[0], r0, r3 + ; get current heap bound + near_call r0, @get_heap_bound, @panic + + ; heap bound should not revert + sub! stack[0], r3, r0 + jump.ne @heap_bound_reverted + + st.1 100, r3 + + ret.ok r0 + + inner: + sstore r1, r1 + + add 2, r0, r1 + shl.s 136, r1, r1 + add 2000, r1, r1 + shl.s 32, r1, r1 + + near_call r0, @get_heap_bound, @panic + add stack[0], r0, r8 + add 32, r8, r8 + ; r8 now is beyond the heap bound + + ; grow memory in heap + ; store r1 at r8 + st.1 r8, r1 + + ; load from heap at r8 to r3 + ld.1 r8, r3 + + ; check value in memory + sub! r3, r1, r0 + jump.ne @memory_error + + ; write new heap bound to stack[0] + near_call r0, @get_heap_bound, @panic + + ret.ok r0 + + get_heap_bound: + ; get metadata of callframe + context.meta r5 + + ; prepare 32-bits mask + add 1, r0, r7 + shl.s 32, r7, r7 + sub.s 1, r7, r7 + + ; unpack heap bound + shr.s 64, r5, r6 + and r6, r7, stack[0] + + ret.ok r0 + + memory_error: + revert("Memory error") + + heap_bound_reverted: + revert("Heap bound reverted") + + panic: + ret.panic r0 \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/near_call/memory_growth_ret_ok/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/near_call/memory_growth_ret_ok/entry.asm new file mode 100644 index 0000000..a8be922 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/near_call/memory_growth_ret_ok/entry.asm @@ -0,0 +1,25 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + CPI0_0: + .cell 65536 + .text + .globl __entry + __entry: + .main: + ; far call with 10000 ergs + add 10000, r0, r1 + shl.s 192, r1, r1 + context.ergs_left r9 + add r9, r0, stack[0] + add @CPI0_0[0], r0, r2 + + far_call r1, r2, @catch_all + + add stack[0], r0, r10 + context.ergs_left r9 + add r9, r0, stack[0] + ret.ok r0 + catch_all: + ret.panic r0 \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/near_call/not_rollback_memory/65536.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/near_call/not_rollback_memory/65536.asm new file mode 100644 index 0000000..2508b33 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/near_call/not_rollback_memory/65536.asm @@ -0,0 +1,56 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry + __entry: + .main: + near_call r0, @inner, @check_memory + revert("Near_call not panicked") + + inner: + add 5000, r0, r2 + add 1, r0, r3 + add 2, r0, r4 + + ; write 1 to heap at address 5000 + st.1 r2, r3 + ; write 2 to aux heap at address 5000 + st.2 r2, r4 + + ; write 3 to stack[0] + add 3, r0, stack[0] + + ret.panic r0 + + check_memory: + add 5000, r0, r2 + + ; read from heap at address 5000 + ld.1 r2, r3 + sub! 1, r3, r0 + jump.ne @heap_rollback + + ; read from aux heap at address 5000 + ld.2 r2, r4 + sub! 2, r4, r0 + jump.ne @aux_heap_rollback + + ; read and check from stack[0] + add stack[0], r0, r5 + sub! 3, r5, r0 + jump.ne @stack_rollback + + sstore r0, r4 + + ret.ok r0 + + heap_rollback: + revert("Unexpected memory rollback") + + aux_heap_rollback: + revert("Unexpected aux memory rollback") + + stack_rollback: + revert("Unexpected stack rollback") \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/near_call/not_rollback_memory/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/near_call/not_rollback_memory/entry.asm new file mode 100644 index 0000000..a8be922 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/near_call/not_rollback_memory/entry.asm @@ -0,0 +1,25 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + CPI0_0: + .cell 65536 + .text + .globl __entry + __entry: + .main: + ; far call with 10000 ergs + add 10000, r0, r1 + shl.s 192, r1, r1 + context.ergs_left r9 + add r9, r0, stack[0] + add @CPI0_0[0], r0, r2 + + far_call r1, r2, @catch_all + + add stack[0], r0, r10 + context.ergs_left r9 + add r9, r0, stack[0] + ret.ok r0 + catch_all: + ret.panic r0 \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/near_call/resets_flags/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/near_call/resets_flags/entry.asm new file mode 100644 index 0000000..e37806a --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/near_call/resets_flags/entry.asm @@ -0,0 +1,60 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry + __entry: + .main: + ; set LT flag + sub.s! 1, r0, r0 + jump.lt @check_lt + + revert("LT flag not set") + + check_lt: + near_call r0, @check_flags, @panic + + ; set GT flag + sub! 1, r0, r0 + jump.gt @check_gt + revert("GT flag not set") + + check_gt: + near_call r0, @check_flags, @panic + + ; set EQ flag + sub! 0, r0, r0 + jump.eq @check_eq + revert("EQ flag not set") + + check_eq: + near_call r0, @check_flags, @panic + + ret.ok r0 + + + check_flags: + ; check LT flag + jump.lt @lt_not_reset + + ; check GT flag + jump.gt @lt_not_reset + + ; check EQ flag + jump.eq @eq_not_reset + + ret.ok r0 + + + lt_not_reset: + revert("LT flag not reset") + + gt_not_reset: + revert("GT flag not reset") + + eq_not_reset: + revert("EQ flag not reset") + + panic: + ret.panic r0 diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/near_call/resets_sp/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/near_call/resets_sp/entry.asm new file mode 100644 index 0000000..f7f7a85 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/near_call/resets_sp/entry.asm @@ -0,0 +1,48 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry + __entry: + .main: + ; SP is 0 + ; change it to 1000 + + nop stack+=[1000] + context.sp r6 + add r6, r0, stack[0] + + ; SP will be changed inside of near call + ; but all changes should be discarded after return + near_call r0, @inner, @panic + + ; SP should revert to value before near_call + context.sp r6 + sub! stack[0], r6, r0 + jump.ne @stack_pointer_not_reverted + + inner: + ; change SP again + nop stack+=[1000] + context.sp r6 + add r6, r0, stack[1] + + ; check that SP changed as expected + add stack[0], r0, r2 + add 1000, r2, r2 + sub! r2, r6, r0 + jump.ne @inner_stack_pointer_invalid + + sstore r0, r6 + ret.ok r0 + + + inner_stack_pointer_invalid: + revert("Stack pointer incorrect") + + stack_pointer_not_reverted: + revert("Stack pointer changed") + + panic: + ret.panic r0 diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_add_invalid_1_pointer/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_add_invalid_1_pointer/entry.asm new file mode 100644 index 0000000..e954ee4 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_add_invalid_1_pointer/entry.asm @@ -0,0 +1,21 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry +__entry: + .main: + sstore r0, r0 + event.first r0, r0 + to_l1.first r0, r0 + add 4, r0, r2 + add 8, r0, r3 + shl.s 128, r3, r3 + near_call r0, @should_panic, @handler + revert("Not panicked but should") + should_panic: + ; trying to add pointer to pointer + ptr.add r1, r1, r1 + handler: + ret.ok r0 \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_add_src0_erasure/65537.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_add_src0_erasure/65537.asm new file mode 100644 index 0000000..584e486 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_add_src0_erasure/65537.asm @@ -0,0 +1,19 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry +__entry: +.main: + ; should not remove "pointer" tag from r1 out of kernel mode too + add r1, r0, r4 + near_call r0, @try_add, @panic_handler + ret.ok r0 + +try_add: + ptr.add r1, r0, r5 + ret.ok r0 + +panic_handler: + revert("Pointer tag cleared") \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_add_src0_erasure/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_add_src0_erasure/entry.asm new file mode 100644 index 0000000..e2068f0 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_add_src0_erasure/entry.asm @@ -0,0 +1,33 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + CPI0_0: + .cell 65537 + .text + .globl __entry +__entry: + .main: + ; add should not clear src0 pointer tag in kernel mode + add r1, r0, r3 + ; panics if r1 isn't a pointer + ptr.add r1, r4, r5 + + ; create ABI for far_call + ; use 2 for forwarding mode (Aux heap) + add 2, r0, r1 + shl.s 32, r1, r1 + ; give 10k gas + add 100000, r1, r1 + shl.s 96, r1, r1 + add 36, r1, r1 + shl.s 32, r1, r1 + add 64, r1, r1 + shl.s 64, r1, r1 + + add @CPI0_0[0], r0, r2 + + far_call r1, r2, @.panic + ret.ok r0 + .panic: + ret.panic r0 \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_add_valid_input/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_add_valid_input/entry.asm new file mode 100644 index 0000000..e4a7965 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_add_valid_input/entry.asm @@ -0,0 +1,17 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry + __entry: + .main: + sstore r0, r0 + event.first r0, r0 + to_l1.first r0, r0 + add 4, r0, r2 + add 8, r0, r3 + shl.s 128, r3, r3 + ptr.add r1, r2, r1 + ptr.pack r1, r3, r4 + ret.ok r0 \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_erasure_kernel/65533.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_erasure_kernel/65533.asm new file mode 100644 index 0000000..b7a0d51 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_erasure_kernel/65533.asm @@ -0,0 +1,57 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 +CPI0_0: + .cell 65534 + .text + .globl __entry +__entry: +.main: + ; build ABI for far_call + + ; create new pointer memory forwarding mode + add 0, r0, r1 + + ; pass 100 ergs + shl.s 32, r1, r1 + add 100, r1, r1 + + shl.s 64, r1, r1 + + ; create "pointer" + add 1024, r0, r4 + shl.s 32, r4, r4 + add 1024, r4, r4 + shl.s 32, r4, r4 + add 2050, r4, r4 + shl.s 32, r4, r4 + + ; add pointer to abi + shl.s 128, r1, r1 + add r1, r4, r1 + + ; clone "pointer" to stack + add r4, r0, stack[0] + + add @CPI0_0[0], r0, r2 + + ; we make the extra far call to create a pointer type + far_call r1, r2, @far_call_handler + + ; load cloned "pointer" + add stack[0], r0, r4 + + ; we perform the subtraction in kernel mode, r1 should not be cleaned + sub.s! r1, r4, r5 + jump.ne @cleaned_but_should_not + sub! r1, r4, r5 + jump.ne @cleaned_but_should_not + + ret.ok r0 + +far_call_handler: + ret.panic r0 + +cleaned_but_should_not: + revert("Pointer cleaned") \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_erasure_kernel/65534.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_erasure_kernel/65534.asm new file mode 100644 index 0000000..23d1718 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_erasure_kernel/65534.asm @@ -0,0 +1,18 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry +__entry: +.main: + ; just return calldata. It is allowed in kernel mode + + ; forward pointer memory mode + add 1, r0, r2 + shl.s 32, r2, r2 + shl.s 64, r2, r2 + shl.s 128, r2, r2 + ptr.pack r1, r2, r3 + + ret.ok r3 \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_erasure_kernel/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_erasure_kernel/entry.asm new file mode 100644 index 0000000..395782e --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_erasure_kernel/entry.asm @@ -0,0 +1,32 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 +CPI0_0: + .cell 65533 + .text + .globl __entry +__entry: +.main: + ; perform far call with limited ergs. create a fat pointer and clone it before VM designates + ; it as one. then perform a sub in kernel mode and if fat pointer != fat pointer clone then we panic + + ; create ABI for far_call + ; use 0 for forwarding mode + add 0, r0, r1 + shl.s 32, r1, r1 + ; give 10k gas + add 10000, r1, r1 + shl.s 96, r1, r1 + add 36, r1, r1 + shl.s 32, r1, r1 + add 64, r1, r1 + shl.s 64, r1, r1 + + add @CPI0_0[0], r0, r2 + + far_call r1, r2, @catch_all + + ret.ok r0 +catch_all: + ret.panic r0 \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_erasure_not_kernel/65534.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_erasure_not_kernel/65534.asm new file mode 100644 index 0000000..14ec132 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_erasure_not_kernel/65534.asm @@ -0,0 +1,19 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry +__entry: +.main: + ; just return calldata, it is allowed in kernel mode + + ; forward pointer memory mode + add 1, r0, r2 + shl.s 32, r2, r2 + shl.s 64, r2, r2 + shl.s 128, r2, r2 + + ptr.pack r1, r2, r3 + + ret.ok r3 \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_erasure_not_kernel/65536.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_erasure_not_kernel/65536.asm new file mode 100644 index 0000000..32d618b --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_erasure_not_kernel/65536.asm @@ -0,0 +1,69 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 +CPI0_0: + .cell 65534 + .text + .globl __entry +__entry: +.main: + ; build ABI for far_call + + ; create new pointer memory forwarding mode + add 0, r0, r1 + + ; pass 100 ergs + shl.s 32, r1, r1 + add 100, r1, r1 + + shl.s 64, r1, r1 + + ; create "pointer" + add 1024, r0, r4 + shl.s 32, r4, r4 + add 1024, r4, r4 + shl.s 32, r4, r4 + add 2050, r4, r4 + shl.s 32, r4, r4 + + ; add pointer to abi + shl.s 128, r1, r1 + add r1, r4, r1 + + ; clone "pointer" to stack + add r4, r0, stack[0] + + add @CPI0_0[0], r0, r2 + + ; we make the extra far call to create a pointer type + + far_call r1, r2, @far_call_handler + + ; load cloned "pointer" + add stack[0], r0, r4 + + ; we perform the subtraction not in kernel mode, r1 should be cleaned + sub.s! r1, r4, r5 + jump.eq @not_cleaned_but_should + sub! r1, r4, r5 + jump.eq @not_cleaned_but_should + + ; clean tag and metadata + + add r1, r0, r3 + add 1024, r0, r4 + shl.s 96, r4, r4 + sub.s! r1, r4, r5 + jump.eq @ret_ok + + revert("Pointer invalid") + +far_call_handler: + ret.panic r0 + +not_cleaned_but_should: + revert("Not cleaned pointer") + +ret_ok: + ret.ok r0 \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_erasure_not_kernel/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_erasure_not_kernel/entry.asm new file mode 100644 index 0000000..a371b93 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/ptr/ptr_erasure_not_kernel/entry.asm @@ -0,0 +1,34 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 +CPI0_0: + .cell 65536 + .text + .globl __entry +__entry: +.main: + ; perform far call with limited ergs. create a fat pointer and clone it before VM designates + ; it as one. then perform a sub and if fat pointer == fat pointer clone then we panic + + ; create ABI for far_call + ; use 0 for forwarding mode + + add 0, r0, r1 + shl.s 32, r1, r1 + ; give 10k gas + add 10000, r1, r1 + shl.s 96, r1, r1 + add 36, r1, r1 + shl.s 32, r1, r1 + add 64, r1, r1 + shl.s 64, r1, r1 + + add @CPI0_0[0], r0, r2 + + far_call r1, r2, @catch_all + + ret.ok r0 + +catch_all: + ret.panic r0 \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/stack/addressing/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/stack/addressing/entry.asm new file mode 100644 index 0000000..cbab37c --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/stack/addressing/entry.asm @@ -0,0 +1,88 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry + __entry: + .main: + ; Stack is empty, SP is 0 + + ; try absolute address on stack + add 1, r0, stack[0] + add stack[0], r0, r2 + sub.s! 1, r2, r0 + jump.ne @absolute_panic + + add 100, r0, stack[1000] + add stack[1000], r0, r2 + sub.s! 100, r2, r0 + jump.ne @absolute_panic + + ; try addressing with offset on stack + ; checking value at SP - 0 + add 2, r0, stack-[0] + add stack-[0], r0, r2 + sub.s! 2, r2, r0 + jump.ne @offset_panic + + ; checking value at SP - 100 + add 200, r0, stack-[100] + add stack-[100], r0, r2 + sub.s! 200, r2, r0 + jump.ne @offset_panic + + ; try push addressing on stack + ; Write 3 to stack at SP - 0 and increase SP + add 3, r0, stack+=[1] + add stack-[1], r0, r2 + sub.s! 3, r2, r0 + jump.ne @push_panic + + ; try pop addressing on stack + add 4, r0, stack-[0] + ; increase stack + nop stack+=[1] + ; pop should return value at SP - offset and move SP to SP - offset + ; ! "pop" addressing can be used only as src0 + add stack-=[1], r0, r5 + sub.s! 4, r5, r0 + jump.ne @pop_panic + + ; try overflowing push addressing on stack + sub.s 2, r0, r3 + context.sp r6 + ; push should change value at SP and move SP to SP + offset + ; ! "push" addressing can be used only as dst0 + add 999, r0, stack+=[r3] + add stack[r6], r0, r2 + sub.s! 999, r2, r0 + jump.ne @push_panic + + ; try do push and pop addressing on stack simultaneously + add 4, r0, stack-[0] + ; increase stack + nop stack+=[2] + ; pop should return value at SP - offset and move SP to SP - offset + ; push should change value at SP and move SP to SP + offset + add stack-=[2], r0, stack+=[2] + add stack-[2], r0, r3 + sub.s! 4, r3, r0 + jump.ne @push_pop_panic + + ret.ok r0 + + absolute_panic: + revert("Absolute addressing failed") + + offset_panic: + revert("Offset addressing failed") + + push_panic: + revert("Push addressing failed") + + pop_panic: + revert("Pop addressing failed") + + push_pop_panic: + revert("Push+pop addressing failed") \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/stack/overflow/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/stack/overflow/entry.asm new file mode 100644 index 0000000..77e3056 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/stack/overflow/entry.asm @@ -0,0 +1,46 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry + __entry: + .main: + ; Stack is empty, SP is 0 + + ; try overflowing absolute address on stack + sub.s 2, r0, r5 + add 1, r0, stack[r5] + add stack[r5], r0, r2 + sub.s! 1, r2, r0 + jump.ne @absolute_panic + + ; try overflow stack with pop + context.sp r6 + add 1, r6, r6 + ; pop stack + nop stack-=[r6] + add 1, r0, stack-[0] + add stack-[0], r0, r3 + sub.s! 1, r3, r0 + jump.ne @pop_panic + + ; try overflowing stack with push + sub.s 2, r0, r3 + ; push stack + nop stack+=[r3] + add 2, r0, stack-[0] + add stack-[0], r0, r3 + sub.s! 2, r3, r0 + jump.ne @push_panic + + ret.ok r0 + + absolute_panic: + revert("Overflowing addressing failed") + + push_panic: + revert("Push overflow failed") + + pop_panic: + revert("Pop overflow failed") \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/uma/kernel_static_reads/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/uma/kernel_static_reads/entry.asm new file mode 100644 index 0000000..5aa69c4 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/uma/kernel_static_reads/entry.asm @@ -0,0 +1,14 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry + __entry: + .main: + add 18000, r0, r2 + add 1, r0, r1 + uma.static_read r1, r2, r0, r0 + + ret.ok r0 + \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/uma/reads_and_writes/800000.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/uma/reads_and_writes/800000.asm new file mode 100644 index 0000000..bb359dc --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/uma/reads_and_writes/800000.asm @@ -0,0 +1,52 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry + __entry: + .main: + ; we got fat pointer from the caller + ; the first value should be 0 + uma.fat_ptr_read r1, r0, r3, r0 + sub.s! 0, r3, r0 + jump.ne @.panic_wrong_read + + ;; move the pointer offset to (almost) max of u32. + add 1, r0, r15 + shl.s 32, r15, r15 + sub.s 33, r15, r15 + + ptr.add r1, r15, r12 + uma.fat_ptr_read r12, r0, r13, r0 + ; check that we read 0 + sub.s! 0, r13, r0 + jump.ne @.panic_wrong_read + + + ; but in the second value, we should see 150 (writen to aux heap in entry.asm) + + add 1, r0, r2 + ptr.add r1, r2, r1 + uma.fat_ptr_read r1, r0, r3, r0 + sub.s! 150, r3, r0 + jump.ne @.panic_wrong_read + + ; expect separate heap - which should be empty + add 5, r0, r1 + ; now reading. + uma.heap_read r1, r0, r3, r0 + ; assert r3 == 0 + sub.s! 0, r3, r0 + jump.ne @.panic_wrong_read + + uma.aux_heap_read r1, r0, r3, r0 + ; assert r3 == 0 + sub.s! 0, r3, r0 + jump.ne @.panic_wrong_read + + ret.ok r0 + + .panic_wrong_read: + revert("user: wrong value read") + diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/uma/reads_and_writes/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/uma/reads_and_writes/entry.asm new file mode 100644 index 0000000..3abb147 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/uma/reads_and_writes/entry.asm @@ -0,0 +1,81 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + CPI0_0: + ; this is 'user' contract + .cell 800000 + .text + .globl __entry + __entry: + .main: + add 65, r0, r1 + add 120, r0, r2 + + ; write '120' in slot 65 + uma.heap_write r1, r2, r0, r0 + + ; write '150' in slot 65 for AUX + add 150, r0, r2 + uma.aux_heap_write r1, r2, r0, r0 + + + ; now reading. + uma.heap_read r1, r0, r3, r0 + + ; assert r3 == 120 + sub.s! 120, r3, r0 + jump.ne @.panic_wrong_read + + + uma.aux_heap_read r1, r0, r3, r0 + sub.s! 150, r3, r4 + jump.ne @.panic_wrong_read + + ; static writes & reads are not supported from kernel contracts yet. + ;add 180, r0, r2 + ;uma.static_write r1, r2, r0, r0 + + ; create ABI for far_call + ; use 2 for forwarding mode (Aux heap) + add 2, r0, r1 + shl.s 32, r1, r1 + ; give 10k gas + add 100000, r1, r1 + shl.s 96, r1, r1 + add 36, r1, r1 + shl.s 32, r1, r1 + add 64, r1, r1 + shl.s 64, r1, r1 + add @CPI0_0[0], r0, r2 + ; call the other_asm contract + far_call r1, r2, @user_call_handler + + add 10000, r0, r4 + ; set the register for near call (doing it before, as registers values should be persisted for near calls) + add 65, r0, r1 + near_call r4, @inner, @near_call_handler + ret.ok r0 + + inner: + uma.heap_read r1, r0, r3, r0 + ; assert r3 == 120 + sub.s! 120, r3, r0 + jump.ne @.panic_wrong_read + + + uma.aux_heap_read r1, r0, r3, r0 + sub.s! 150, r3, r4 + jump.ne @.panic_wrong_read + + ret.ok r0 + + user_call_handler: + ret.panic r0 + + near_call_handler: + ret.panic r0 + + .panic_wrong_read: + revert("wrong value read") + \ No newline at end of file diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/uma/static_reads/800000.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/uma/static_reads/800000.asm new file mode 100644 index 0000000..8463c76 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/uma/static_reads/800000.asm @@ -0,0 +1,16 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + .text + .globl __entry + __entry: + .main: + ; now try accessing the static memory + add 180, r0, r2 + ; currently this will fail the whole execution. + uma.static_read r1, r2, r0, r0 + + ; user contract + ret.ok r0 + diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/testdata/uma/static_reads/entry.asm b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/uma/static_reads/entry.asm new file mode 100644 index 0000000..9a186a7 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/testdata/uma/static_reads/entry.asm @@ -0,0 +1,28 @@ + .text + .file "Test_26" + .rodata.cst32 + .p2align 5 + CPI0_0: + ; this is 'user' contract + .cell 800000 + .text + .globl __entry + __entry: + .main: + ; create ABI for far_call + add 2, r0, r1 + shl.s 32, r1, r1 + ; give 10k gas + add 100000, r1, r1 + + shl.s 192, r1, r1 + + + add @CPI0_0[0], r0, r2 + ; call the other_asm contract + far_call r1, r2, @expect_panic + revert("must panic due to static read") + + expect_panic: + ret.ok r0 + diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/uma.rs b/crates/zkevm_test_harness/src/tests/simple_tests/uma.rs new file mode 100644 index 0000000..d2cde93 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/simple_tests/uma.rs @@ -0,0 +1,44 @@ +#[cfg(test)] +mod tests { + use crate::tests::simple_tests::{asm_tests::run_asm_based_test, Options}; + + #[test_log::test] + fn test_uma_reads_and_writes() { + run_asm_based_test( + "src/tests/simple_tests/testdata/uma/reads_and_writes", + &[800000], + Options { + cycle_limit: 100, + cycles_per_vm_snapshot: 1, + ..Default::default() + }, + ) + } + + #[test_log::test] + fn test_uma_static_reads() { + run_asm_based_test( + "src/tests/simple_tests/testdata/uma/static_reads", + &[800000], + Options { + cycle_limit: 100, + cycles_per_vm_snapshot: 1, + ..Default::default() + }, + ) + } + + #[ignore = "static reads not supported yet"] + #[test_log::test] + fn test_uma_kernel_static_reads() { + run_asm_based_test( + "src/tests/simple_tests/testdata/uma/kernel_static_reads", + &[], + Options { + cycle_limit: 100, + cycles_per_vm_snapshot: 1, + ..Default::default() + }, + ) + } +} diff --git a/crates/zkevm_test_harness/src/tests/storage.rs b/crates/zkevm_test_harness/src/tests/storage.rs new file mode 100644 index 0000000..c43e9cc --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/storage.rs @@ -0,0 +1,98 @@ +use std::{cell::RefCell, rc::Rc}; + +use circuit_definitions::zk_evm::{ + abstractions::{Storage, StorageAccessRefund}, + aux_structures::{LogQuery, PubdataCost, Timestamp}, + testing::storage::InMemoryStorage, +}; + +/// Enum holding the types of storage refunds +#[derive(Debug, Copy, Clone)] +pub(crate) enum StorageRefund { + Cold, + Warm, +} + +/// Used to control updates to the slot refunds within InMemoryCustomRefundStorage +#[derive(Debug, Clone)] +pub struct RefundController { + slot_refund: Rc>, +} + +impl RefundController { + pub fn new(slot_refund: Rc>) -> Self { + Self { slot_refund } + } + + pub fn set_storage_refund(&self, storage_refund_type: StorageRefund, refund_value: u32) { + let new_value = if let StorageRefund::Warm = storage_refund_type { + refund_value + } else { + 0 + }; + *self.slot_refund.borrow_mut() = (storage_refund_type, new_value); + } +} + +/// Wrapper around the base InMemoryStorage implementation that allows for the setting of custom refunds for more +/// control over storage slot refund testing. +#[derive(Debug, Clone)] +pub struct InMemoryCustomRefundStorage { + pub storage: InMemoryStorage, + pub slot_refund: Rc>, +} + +impl InMemoryCustomRefundStorage { + pub fn new() -> Self { + Self { + storage: InMemoryStorage::new(), + slot_refund: Rc::new(RefCell::new((StorageRefund::Cold, 0u32))), + } + } + + pub fn create_refund_controller(&self) -> RefundController { + RefundController::new(Rc::clone(&self.slot_refund)) + } +} + +impl Storage for InMemoryCustomRefundStorage { + #[track_caller] + fn get_access_refund( + &mut self, // to avoid any hacks inside, like prefetch + _monotonic_cycle_counter: u32, + _partial_query: &LogQuery, + ) -> StorageAccessRefund { + let storage_refund = self.slot_refund.borrow(); + match storage_refund.0 { + StorageRefund::Cold => dbg!(StorageAccessRefund::Cold), + StorageRefund::Warm => dbg!(StorageAccessRefund::Warm { + ergs: storage_refund.1 + }), + } + } + + #[track_caller] + fn execute_partial_query( + &mut self, + monotonic_cycle_counter: u32, + query: LogQuery, + ) -> (LogQuery, PubdataCost) { + self.storage + .execute_partial_query(monotonic_cycle_counter, query) + } + + #[track_caller] + fn start_frame(&mut self, timestamp: Timestamp) { + self.storage.start_frame(timestamp) + } + + #[track_caller] + fn finish_frame(&mut self, timestamp: Timestamp, panicked: bool) { + self.storage.finish_frame(timestamp, panicked) + } + + #[track_caller] + fn start_new_tx(&mut self, timestamp: Timestamp) { + self.storage.start_new_tx(timestamp) + } +} diff --git a/crates/zkevm_test_harness/src/tests/utils/mod.rs b/crates/zkevm_test_harness/src/tests/utils/mod.rs new file mode 100644 index 0000000..a34f300 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/utils/mod.rs @@ -0,0 +1,2 @@ +pub mod preprocess_asm; +pub mod testing_tracer; diff --git a/crates/zkevm_test_harness/src/tests/utils/preprocess_asm.rs b/crates/zkevm_test_harness/src/tests/utils/preprocess_asm.rs new file mode 100644 index 0000000..958ef3e --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/utils/preprocess_asm.rs @@ -0,0 +1,458 @@ +//! Contains functions to preprocess asm templates and generate valid assembly code compatible with TestingTracer +use crate::ethereum_types::Address; +use crate::ethereum_types::H160; +use crate::ethereum_types::U256; +use crate::zk_evm::bytecode_to_code_hash; +use regex::Regex; +use std::collections::HashMap; + +/// Default config template for simple tests +const DEFAULT_CONFIG: &str = r#" + .text + .file "Test_zkevm" + .rodata.cst32 + .p2align 5 + .text + .globl __entry +"#; + +pub fn asm_with_default_config(asm: &str) -> String { + DEFAULT_CONFIG.to_owned() + asm +} + +#[derive(Debug, Clone, Copy, PartialEq)] +enum Directive { + Print(PrintType), + Revert, + StorageRefundCold, + StorageRefundWarm, +} + +#[derive(Debug, Clone, Copy, PartialEq)] +enum PrintType { + Text, + Register, + Pointer, +} + +pub const EXCEPTION_PREFIX: &str = "E:"; +pub const PRINT_PREFIX: &str = "L:"; +pub const PRINT_REG_PREFIX: &str = "R:"; +pub const PRINT_PTR_PREFIX: &str = "P:"; +pub const STORAGE_REFUND_COLD_PREFIX: &str = "C:"; +pub const STORAGE_REFUND_WARM_PREFIX: &str = "W:"; + +pub type TemplateDictionary<'a> = HashMap<&'a str, String>; + +/// Replaces special directives in asm with TestingTracer compatible "commands" +pub fn preprocess_asm( + asm: String, + additional_contracts: Option<&Vec<(H160, Vec<[u8; 32]>)>>, + dictionary: Option<&TemplateDictionary>, +) -> String { + let asm = replace_tags_in_template(asm, dictionary); + + let result = [ + Directive::Print(PrintType::Text), + Directive::Print(PrintType::Register), + Directive::Print(PrintType::Pointer), + Directive::Revert, + Directive::StorageRefundCold, + Directive::StorageRefundWarm, + ] + .iter() + .fold(asm, |acc, x| preprocess_directive(acc, *x)); + + link_additional_contracts(&result, additional_contracts) +} + +/// Replaces tags like "${TAG}" with values from dictionary +fn replace_tags_in_template( + asm_template: String, + dictionary: Option<&TemplateDictionary>, +) -> String { + let mut result = asm_template.clone(); + let template_regex = Regex::new(r#"\$\{[^\}]+\}"#).expect("Invalid regex"); + + for (_, matched) in asm_template.match_indices(&template_regex) { + let prefix = "${"; + let suffix = "}"; + let key_to_replace = matched + .strip_prefix(prefix) + .expect("Invalid text in template") + .strip_suffix(suffix) + .expect("Invalid text in template"); + + if dictionary == None { + panic!("Unknown key: {key_to_replace}"); + } + + match dictionary.unwrap().get(key_to_replace) { + Some(value) => { + result = result.replace(matched, value); + } + None => panic!("Unknown key: {key_to_replace}"), + } + } + + result +} + +fn preprocess_directive(asm: String, directive: Directive) -> String { + let (asm_replaced, messages) = replace_directives(asm, directive); + add_data_section_for_directive(asm_replaced, directive, messages) +} + +fn link_additional_contracts( + asm: &str, + additional_contracts: Option<&Vec<(H160, Vec<[u8; 32]>)>>, +) -> String { + let mut result = asm.to_owned(); + // regex: + let contract_regex = Regex::new(r#"<\d+\.asm>"#).expect("Invalid regex"); + + for (_, matched) in asm.match_indices(&contract_regex) { + let prefix = "<"; + let suffix = ".asm>"; + let contract_address = Address::from_low_u64_be( + matched + .strip_prefix(&prefix) + .expect("Invalid text in directive") + .strip_suffix(&suffix) + .expect("Invalid text in directive") + .parse::() + .expect("Invalid additional contract address"), + ); + + if additional_contracts.is_none() { + panic!("Can't link additional contract: {}", matched); + } + + result = if let Some((_, bytecode)) = additional_contracts + .unwrap() + .iter() + .find(|(address, _)| *address == contract_address) + { + let hash = bytecode_to_code_hash(&bytecode).unwrap(); + result.replace(matched, &U256::from(hash).to_string()) + } else { + panic!("Can't link additional contract: {}", matched); + } + } + + result +} + +/// replace all occurrences of the directive with the corresponding assembly code +fn replace_directives(asm: String, directive: Directive) -> (String, Vec) { + let mut result = asm.clone(); + + let (command_prefix, regex, cell_name, prefix, suffix) = match directive { + Directive::Revert => { + // regex: revert("") + let revert_regex = Regex::new(r#"revert\("[^"]*"\)"#).expect("Invalid regex"); + ( + EXCEPTION_PREFIX, + revert_regex, + "REVERT", + r#"revert("#, + r#")"#, + ) + } + Directive::Print(PrintType::Text) => { + // regex: print("") + let print_regex = Regex::new(r#"print\("[^"]*"\)"#).expect("Invalid regex"); + (PRINT_PREFIX, print_regex, "PRINT", r#"print("#, r#")"#) + } + Directive::Print(PrintType::Register) => { + // regex: print() or print(") + let print_reg_regex = + Regex::new(r#"print\(("[^"\)]+"\s*\,\s*)?([^"\)]+)\)"#).expect("Invalid regex"); + ( + PRINT_REG_PREFIX, + print_reg_regex, + "PRINT_REG", + r#"print("#, + r#")"#, + ) + } + Directive::Print(PrintType::Pointer) => { + // regex: printPtr() + let print_ptr_regex = Regex::new(r#"printPtr\([^"\)]+\)"#).expect("Invalid regex"); + ( + PRINT_PTR_PREFIX, + print_ptr_regex, + "PRINT_PTR", + r#"printPtr("#, + r#")"#, + ) + } + Directive::StorageRefundCold => { + // regex: set_storage_cold() + let set_storage_cold_regex = + Regex::new(r#"set_storage_cold\(\)"#).expect("Invalid regex"); + ( + STORAGE_REFUND_COLD_PREFIX, + set_storage_cold_regex, + "STORAGE_REFUND_COLD", + r#"set_storage_cold()"#, + r#""#, + ) + } + Directive::StorageRefundWarm => { + // regex: set_storage_warm(u32) + let set_storage_warm_regex = + Regex::new(r#"set_storage_warm\((\d*)\)"#).expect("Invalid regex"); + ( + STORAGE_REFUND_WARM_PREFIX, + set_storage_warm_regex, + "STORAGE_REFUND_WARM", + r#"set_storage_warm("#, + r#")"#, + ) + } + }; + + let mut args_for_commands: Vec = Vec::new(); + for (index, matched) in asm.match_indices(®ex) { + // skip if directive commented out + if asm[..index] + .chars() + .rev() + .take_while(|&symbol| symbol != '\n') + .any(|symbol| symbol == ';') + { + continue; + } + + let matched_args = parse_args(matched, prefix, suffix); + + args_for_commands.push(match directive { + Directive::Print(PrintType::Register | PrintType::Pointer) => { + if matched_args.len() > 1 { + // additional message + check_arg_for_command(matched_args[0], command_prefix).to_owned() + } else { + "".to_owned() + } + } + Directive::StorageRefundCold => "".to_owned(), + Directive::StorageRefundWarm => matched_args[0].to_string(), + _ => check_arg_for_command(matched_args[0], command_prefix).to_owned(), + }); + + let reference_var = format!("@{}_{}_STRING", cell_name, args_for_commands.len() - 1); + let line = format!("add {reference_var}, r0, r0"); + + // additional lines + let line = match directive { + Directive::Revert => { + format!("{line}\n ret.panic r0") + } + Directive::Print(print_type) => { + if print_type == PrintType::Text { + line + } else { + let src0 = if matched_args.len() == 1 { + matched_args[0] + } else { + matched_args[1] + }; + let opcode = match print_type { + PrintType::Register => "add", + PrintType::Pointer => "ptr.add", + _ => { + panic!("Unknown print type") + } + }; + format!("{line}\n {opcode} {src0}, r0, r0") + } + } + Directive::StorageRefundCold => { + format!("{line}\n add r0, r0, r0") + } + Directive::StorageRefundWarm => { + let src0 = matched_args[0]; + format!("{line}\n add {src0}, r0, r0") + } + }; + result = result.replace(matched, &line); + } + + (result, args_for_commands) +} + +/// add .rodata section with commands from directives +fn add_data_section_for_directive(asm: String, directive: Directive, args: Vec) -> String { + let mut result = asm; + if args.is_empty() { + return result; + } + + let (command_prefix, arg_label_prefix) = match directive { + Directive::Revert => (EXCEPTION_PREFIX, "REVERT"), + Directive::Print(PrintType::Text) => (PRINT_PREFIX, "PRINT"), + Directive::Print(PrintType::Register) => (PRINT_REG_PREFIX, "PRINT_REG"), + Directive::Print(PrintType::Pointer) => (PRINT_PTR_PREFIX, "PRINT_PTR"), + Directive::StorageRefundCold => (STORAGE_REFUND_COLD_PREFIX, "STORAGE_REFUND_COLD"), + Directive::StorageRefundWarm => (STORAGE_REFUND_WARM_PREFIX, "STORAGE_REFUND_WARM"), + }; + + let data_section: String = args + .iter() + .enumerate() + .map(|(index, arg)| { + let data_line = format!( + "{arg_label_prefix}_{index}_STRING:\n .cell {}\n", + U256::from(format!("{command_prefix}{arg}").as_bytes()) + ); + data_line + }) + .chain(Some(".text\n".to_owned())) + .fold(".rodata\n".to_owned(), |mut acc, line| { + acc.push_str(&line); + acc + }); + + let position = result.find("__entry:").expect("Invalid asm"); + result.insert_str(position, &data_section); + + result +} + +fn parse_args<'a>(text: &'a str, prefix: &str, suffix: &str) -> Vec<&'a str> { + // regex to split args from string like: <"a", b, c ...> + let args_regex = Regex::new(r#"(\"[^\"]*\")|,?\s*[^\s\,]+"#).expect("Invalid regex"); + let trimmed_content = text + .strip_prefix(prefix) + .expect("Invalid text in directive") + .strip_suffix(suffix) + .expect("Invalid text in directive") + .trim(); + + trimmed_content + .matches(&args_regex) + .map(|x| x.trim_matches(',').trim().trim_matches('"')) + .collect() +} + +fn check_arg_for_command<'a>(text_arg: &'a str, command_prefix: &str) -> &'a str { + if text_arg.len() > 32 - command_prefix.len() { + panic!("Message inside directive is too long: {}", text_arg); + } + text_arg +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_preprocess_asm() { + let asm = r#" +__entry: +.main: +print("TEST") +print(r5) +revert("TEST2")"#; + + let result = preprocess_asm(asm.to_owned(), None, None); + + let print_text = U256::from(format!("{}{}", PRINT_PREFIX, "TEST").as_bytes()); + let print_reg_text = U256::from(PRINT_REG_PREFIX.as_bytes()); + let revert_text = U256::from(format!("{}{}", EXCEPTION_PREFIX, "TEST2").as_bytes()); + + let expected_result = format!( + r#" +.rodata +PRINT_0_STRING: + .cell {print_text} +.text +.rodata +PRINT_REG_0_STRING: + .cell {print_reg_text} +.text +.rodata +REVERT_0_STRING: + .cell {revert_text} +.text +__entry: +.main: +add @PRINT_0_STRING, r0, r0 +add @PRINT_REG_0_STRING, r0, r0 + add r5, r0, r0 +add @REVERT_0_STRING, r0, r0 + ret.panic r0"# + ); + + assert_eq!(result, expected_result); + } + + #[test] + #[should_panic( + expected = "Message inside directive is too long: ttttttttttttttttttttttttttttttt" + )] + fn test_panic_too_long_print() { + let long_message = "ttttttttttttttttttttttttttttttt"; + + let asm = format! {r#" + .text + .globl __entry + __entry: + .main: + print("{long_message}") + ret.ok r0 + "#, }; + + preprocess_asm(asm.to_owned(), None, None); + } + + #[test] + #[should_panic(expected = "Invalid asm")] + fn test_panic_with_unexpected_entry() { + let args = Vec::from(["Test".to_owned()]); + let asm = r#" + .text + .globl __unexpected_entry + __unexpected_entry: + .main: + ret.ok r0 + "#; + add_data_section_for_directive(asm.to_owned(), Directive::Print(PrintType::Text), args); + } + + #[test] + fn test_templates_replace_tags() { + let mut dictionary: TemplateDictionary = Default::default(); + dictionary.insert("src0", "5".to_owned()); + dictionary.insert("src1", "r0".to_owned()); + dictionary.insert("dst0", "r2".to_owned()); + + let asm = r#" + .text + .globl __unexpected_entry + __unexpected_entry: + .main: + add ${src0} ${src1} ${dst0} + ret.ok r0 + "#; + + let res = replace_tags_in_template(asm.to_owned(), Some(&dictionary)); + + let expected_res = format!( + r#" + .text + .globl __unexpected_entry + __unexpected_entry: + .main: + add {} {} {} + ret.ok r0 + "#, + dictionary.get("src0").unwrap(), + dictionary.get("src1").unwrap(), + dictionary.get("dst0").unwrap() + ); + + assert_eq!(res, expected_res); + } +} diff --git a/crates/zkevm_test_harness/src/tests/utils/testing_tracer.rs b/crates/zkevm_test_harness/src/tests/utils/testing_tracer.rs new file mode 100644 index 0000000..87a0870 --- /dev/null +++ b/crates/zkevm_test_harness/src/tests/utils/testing_tracer.rs @@ -0,0 +1,348 @@ +use circuit_definitions::boojum::utils::PipeOp; +use circuit_definitions::ethereum_types::H160; +use circuit_definitions::zk_evm::vm_state::ErrorFlags; +use circuit_definitions::zk_evm::vm_state::PrimitiveValue; +use std::fmt; +use std::str; +use std::usize; +use zkevm_assembly::zkevm_opcode_defs::decoding::{ + AllowedPcOrImm, EncodingModeProduction, VmEncodingMode, +}; +use zkevm_assembly::zkevm_opcode_defs::AddOpcode; +use zkevm_assembly::zkevm_opcode_defs::DecodedOpcode; +use zkevm_assembly::zkevm_opcode_defs::NopOpcode; +use zkevm_assembly::zkevm_opcode_defs::Opcode; +use zkevm_assembly::zkevm_opcode_defs::PtrOpcode; +use zkevm_assembly::zkevm_opcode_defs::RetOpcode; + +use crate::ethereum_types::U256; +use crate::tests::storage::RefundController; +use crate::tests::storage::StorageRefund; +use crate::zk_evm::reference_impls::memory::SimpleMemory; +use crate::zk_evm::tracing::*; + +use crate::tests::utils::preprocess_asm::EXCEPTION_PREFIX; +use crate::tests::utils::preprocess_asm::PRINT_PREFIX; +use crate::tests::utils::preprocess_asm::PRINT_PTR_PREFIX; +use crate::tests::utils::preprocess_asm::PRINT_REG_PREFIX; +use crate::tests::utils::preprocess_asm::STORAGE_REFUND_COLD_PREFIX; +use crate::tests::utils::preprocess_asm::STORAGE_REFUND_WARM_PREFIX; + +#[derive(Debug, Clone, PartialEq, Default)] +enum TracerState { + /// will try to parse next value from VM as command + #[default] + ExpectingCommand, + /// will print next value from VM + ExpectingValueToPrint(ExpectedValueType), +} + +#[derive(Debug, Clone, PartialEq)] +enum ExpectedValueType { + /// expecting raw register value + Register, + /// expecting fat pointer + Pointer, +} + +#[derive(Debug, Clone, Default)] +pub struct OutOfCircuitException> { + pub exception_message: Option, + pub opcode: Option>, + pub contract_address: Option, +} + +impl> OutOfCircuitException { + pub fn new( + exception_message: Option, + opcode: Option>, + contract_address: Option, + ) -> Self { + Self { + exception_message, + opcode, + contract_address, + } + } +} + +impl> fmt::Display for OutOfCircuitException { + fn fmt(&self, f: &mut fmt::Formatter) -> std::fmt::Result { + if let Some(message) = &self.exception_message { + write!(f, "{}", message)? + }; + + if let Some(address) = &self.contract_address { + write!(f, "\nIn contract: {:?}", address)? + }; + + if let Some(opcode) = &self.opcode { + write!(f, "\nFailed opcode:\n{}", opcode)? + }; + + Ok(()) + } +} + +/// Tracks prints and exceptions during VM execution cycles. +#[derive(Debug, Clone)] +pub struct TestingTracer = EncodingModeProduction> { + /// the last uncatched exception + pub exception: Option>, + /// the inner state, affects the interpretation of values from the VM + tracer_state: TracerState, + /// stores pending messages that should be printed + message_buffer: Option, + /// Optional controller to set the type/amount of refund for storage slot access + storage_refund_controller: Option, +} + +/// TestingTracer interprets valid x values in `add x r0 r0` and `ptr.add x r0 r0` instructions as commands to execute. +/// Commands have following structure: "PREFIX:arg" +/// Allowed commands: +/// "EXCEPTION_PREFIX:" - save in exception_message field +/// "PRINT_PREFIX:" - print in the console +/// "PRINT_REG_PREFIX:" - print raw "x" value of next command in the console +/// "PRINT_PTR_PREFIX:" - print raw "x" pointer value of next command in the console (currently same result as previous command) +/// "STORAGE_REFUND_COLD_PREFIX:" - If used in conjuction with RefundController from InMemoryCustomRefundStorage::create_refund_controller will set the next +/// storage slot access refund to Cold +/// STORAGE_REFUND_WARM_PREFIX: - If used in conjuction with RefundController from InMemoryCustomRefundStorage::create_refund_controller will set the next +/// storage slot access refund to Warm with the specified amount of ergs +impl> TestingTracer { + pub fn new(storage_refund_controller: Option) -> Self { + Self { + exception: None, + tracer_state: TracerState::default(), + message_buffer: None, + storage_refund_controller, + } + } + + fn reset_exception(&mut self) { + self.exception = None; + } + + fn set_exception( + &mut self, + message: Option, + opcode: Option>, + contract_address: Option, + ) { + self.exception = Some(OutOfCircuitException::new( + message, + opcode, + contract_address, + )); + } + + fn execute_print(&self, message: &str) { + println!("{}", message); + } + + fn execute_print_from_register(&self, val: PrimitiveValue) { + if let TracerState::ExpectingCommand = self.tracer_state { + panic!("Unexpected execute_print_from_register command"); + } + + if let Some(message) = &self.message_buffer { + println!("{message} {}", val.value); + } else { + println!("{}", val.value); + } + } + + fn set_storage_refund(&self, storage_refund_type: StorageRefund, value: &str) { + if let Some(controller) = &self.storage_refund_controller { + match storage_refund_type { + StorageRefund::Cold => controller.set_storage_refund(StorageRefund::Cold, 0u32), + StorageRefund::Warm => { + let refund_value = + u32::from_str_radix(value, 10).expect("Refund parsing error"); + + controller.set_storage_refund(StorageRefund::Warm, refund_value); + } + } + } + } + + fn handle_value_from_vm(&mut self, value: PrimitiveValue) -> TracerState { + let mut new_state = TracerState::ExpectingCommand; + let mut new_message_buffer_value = None; + + match self.tracer_state { + TracerState::ExpectingValueToPrint(..) => { + self.execute_print_from_register(value); + } + TracerState::ExpectingCommand => { + if let Some((command_prefix, arg)) = self.parse_command_from_register(value) { + match command_prefix.as_str() { + EXCEPTION_PREFIX => { + self.set_exception(Some(arg), None, None); + } + PRINT_PREFIX => { + self.execute_print(&arg); + } + PRINT_REG_PREFIX => { + if !arg.is_empty() { + new_message_buffer_value = Some(arg); + } + new_state = + TracerState::ExpectingValueToPrint(ExpectedValueType::Register); + } + PRINT_PTR_PREFIX => { + if !arg.is_empty() { + new_message_buffer_value = Some(arg); + } + new_state = + TracerState::ExpectingValueToPrint(ExpectedValueType::Pointer); + } + STORAGE_REFUND_COLD_PREFIX => { + self.set_storage_refund(StorageRefund::Cold, &arg); + } + STORAGE_REFUND_WARM_PREFIX => { + self.set_storage_refund(StorageRefund::Warm, &arg); + } + _ => { + // ignore invalid command + } + } + } + } + } + + self.message_buffer = new_message_buffer_value; + new_state + } + + /// Returns (command_prefix, arg) if parsed command successfully + /// None otherwise + fn parse_command_from_register(&self, val: PrimitiveValue) -> Option<(String, String)> { + if val.value == U256::from(0) { + return None; + } + + let mut bytes: [u8; 32] = [0; 32]; + val.value.to_big_endian(&mut bytes); + + if let Ok(message) = std::str::from_utf8(&bytes) { + let message_trimmed = message.trim_matches(char::from(0)); + + for prefix in [ + EXCEPTION_PREFIX, + PRINT_PREFIX, + PRINT_REG_PREFIX, + PRINT_PTR_PREFIX, + STORAGE_REFUND_COLD_PREFIX, + STORAGE_REFUND_WARM_PREFIX, + ] { + if message_trimmed.starts_with(prefix) { + let arg = message_trimmed.strip_prefix(prefix).unwrap(); + return Some((prefix.to_owned(), arg.to_owned())); + } + } + } + + None + } +} + +impl> Tracer for TestingTracer { + type SupportedMemory = SimpleMemory; + const CALL_BEFORE_EXECUTION: bool = true; + const CALL_AFTER_DECODING: bool = true; + + #[inline] + fn before_decoding( + &mut self, + _state: VmLocalStateData<'_, N, E>, + _memory: &Self::SupportedMemory, + ) { + } + + fn after_decoding( + &mut self, + state: VmLocalStateData<'_, N, E>, + data: AfterDecodingData, + _memory: &Self::SupportedMemory, + ) { + if let Opcode::Ret(RetOpcode::Panic | RetOpcode::Revert) = + data.opcode_masked.inner.variant.opcode + { + if let Some(exception) = &self.exception { + if exception.opcode.is_some() { + return; + } + } + + let (raw_opcode, _) = + E::parse_preliminary_variant_and_absolute_number(data.raw_opcode_unmasked); + + let message = if data.error_flags_accumulated.is_empty() { + if let Some(exception) = &self.exception { + exception.exception_message.clone() + } else { + None + } + } else { + // check for built-in panics + let (panic_name, _) = data.error_flags_accumulated.iter_names().nth(0).unwrap(); + Some(panic_name.to_owned()) + }; + + self.set_exception( + message, + Some(raw_opcode), + Some(state.vm_local_state.callstack.current.this_address), + ); + }; + } + + fn before_execution( + &mut self, + _state: VmLocalStateData<'_, N, E>, + data: BeforeExecutionData, + _memory: &Self::SupportedMemory, + ) { + let inner_opcode = data.opcode.inner.variant.opcode; + + // Propagate error message if Nop, ret.panic, ret.revert; reset otherwise + match inner_opcode { + Opcode::Nop(NopOpcode) => {} + Opcode::Ret(RetOpcode::Panic | RetOpcode::Revert) => {} + _ => { + self.reset_exception(); + } + } + + // check if we have a valid command for TestingTracer and execute the command if any. + // commands always have r0 as src1 and dst0 + let new_state = if data.opcode.src1_reg_idx == 0 && data.opcode.dst0_reg_idx == 0 { + match inner_opcode { + Opcode::Add(AddOpcode::Add) | Opcode::Ptr(PtrOpcode::Add) => { + // `add x r0 r0` is used to pass "x" to TestingTracer + // `ptr.add x r0 r0` is used to pass "x" pointer to TestingTracer + self.handle_value_from_vm(data.src0_value) + } + _ => TracerState::ExpectingCommand, + } + } else { + TracerState::ExpectingCommand + }; + + self.tracer_state = new_state; + + // pc 0 means VM finished without any panics + if data.new_pc == E::PcOrImm::from_u64_clipped(0) { + self.reset_exception(); + } + } + + #[inline] + fn after_execution( + &mut self, + _state: VmLocalStateData<'_, N, E>, + _data: AfterExecutionData, + _memory: &Self::SupportedMemory, + ) { + } +} diff --git a/crates/zkevm_test_harness/src/toolset.rs b/crates/zkevm_test_harness/src/toolset.rs new file mode 100644 index 0000000..ed88428 --- /dev/null +++ b/crates/zkevm_test_harness/src/toolset.rs @@ -0,0 +1,102 @@ +use crate::witness::tracer::tracer::WitnessTracer; +use crate::zk_evm::abstractions::Storage; +use crate::zk_evm::reference_impls::decommitter::SimpleDecommitter; +use crate::zk_evm::reference_impls::event_sink::InMemoryEventSink; +use crate::zk_evm::zk_evm_abstractions::precompiles::DefaultPrecompilesProcessor; +use crate::zk_evm::zkevm_opcode_defs::system_params::VM_INITIAL_FRAME_ERGS; + +/// Set should only differ due to another storage that would be sustituted from outside, +/// and all other tools can be as simple as possible +pub struct ProvingToolset { + pub storage: S, + pub memory: SimpleMemory, + pub event_sink: InMemoryEventSink, + pub precompiles_processor: DefaultPrecompilesProcessor, + pub decommittment_processor: SimpleDecommitter, + pub witness_tracer: WitnessTracer, + pub config: GeometryConfig, +} + +use circuit_definitions::zk_evm::aux_structures::PubdataCost; +pub use circuit_sequencer_api::toolset::GeometryConfig; + +pub fn create_tools(storage: S, config: &GeometryConfig) -> ProvingToolset { + let memory = SimpleMemory::new_without_preallocations(); + let event_sink = InMemoryEventSink::new(); + let precompiles_processor = DefaultPrecompilesProcessor::; + let decommittment_processor = SimpleDecommitter::::new(); + let witness_tracer = WitnessTracer::new(config.cycles_per_vm_snapshot); + + ProvingToolset { + storage, + memory, + event_sink, + precompiles_processor, + decommittment_processor, + witness_tracer, + config: config.clone(), + } +} + +use crate::entry_point::initial_out_of_circuit_context; +use crate::ethereum_types::Address; +use crate::zk_evm::block_properties::BlockProperties; +use crate::zk_evm::reference_impls::memory::SimpleMemory; +use crate::zk_evm::vm_state::{PrimitiveValue, VmState}; +use crate::zk_evm::zkevm_opcode_defs::*; + +/// We expect that storage/memory/decommitter were prefilled +pub fn create_out_of_circuit_vm( + tools: ProvingToolset, + block_properties: BlockProperties, + caller_address: Address, + entry_point_address: Address, +) -> VmState< + S, + SimpleMemory, + InMemoryEventSink, + DefaultPrecompilesProcessor, + SimpleDecommitter, + WitnessTracer, +> { + let mut vm = VmState::empty_state( + tools.storage, + tools.memory, + tools.event_sink, + tools.precompiles_processor, + tools.decommittment_processor, + tools.witness_tracer, + block_properties, + ); + + let initial_context = initial_out_of_circuit_context( + 0, + VM_INITIAL_FRAME_ERGS, + entry_point_address, + caller_address, + entry_point_address, + ); + + vm.push_bootloader_context(crate::INITIAL_MONOTONIC_CYCLE_COUNTER - 1, initial_context); + + vm.local_state.pubdata_revert_counter = PubdataCost(0i32); + + vm.local_state.timestamp = STARTING_TIMESTAMP; + vm.local_state.memory_page_counter = STARTING_BASE_PAGE; + vm.local_state.monotonic_cycle_counter = crate::INITIAL_MONOTONIC_CYCLE_COUNTER; + + // we also FORMALLY mark r1 as "pointer" type, even though we will NOT have any calldata + let formal_ptr = FatPointer { + offset: 0, + memory_page: crate::zk_evm::zkevm_opcode_defs::BOOTLOADER_CALLDATA_PAGE, + start: 0, + length: 0, + }; + let formal_ptr_encoding = formal_ptr.to_u256(); + vm.local_state.registers[0] = PrimitiveValue { + value: formal_ptr_encoding, + is_pointer: true, + }; + + vm +} diff --git a/crates/zkevm_test_harness/src/utils.rs b/crates/zkevm_test_harness/src/utils.rs new file mode 100644 index 0000000..ecc2903 --- /dev/null +++ b/crates/zkevm_test_harness/src/utils.rs @@ -0,0 +1,214 @@ +use crate::boojum::field::SmallField; +use crate::kzg::KzgSettings; +use crate::witness::tree::BinaryHasher; + +use circuit_definitions::encodings::BytesSerializable; + +pub fn u64_as_u32_le(value: u64) -> [u32; 2] { + [value as u32, (value >> 32) as u32] +} + +pub fn u128_as_u32_le(value: u128) -> [u32; 4] { + [ + value as u32, + (value >> 32) as u32, + (value >> 64) as u32, + (value >> 96) as u32, + ] +} + +pub fn bytes_to_u32_le(bytes: &[u8; N]) -> [u32; M] { + assert!(M > 0); + assert!(M * 4 == N); + + let mut result = [0u32; M]; + + for (idx, chunk) in bytes.chunks_exact(4).enumerate() { + let word = u32::from_le_bytes(chunk.try_into().unwrap()); + result[idx] = word; + } + + result +} + +pub fn bytes_to_u128_le(bytes: &[u8; N]) -> [u128; M] { + assert!(M > 0); + assert!(M * 16 == N); + + let mut result = [0u128; M]; + + for (idx, chunk) in bytes.chunks_exact(16).enumerate() { + let word = u128::from_le_bytes(chunk.try_into().unwrap()); + result[idx] = word; + } + + result +} + +pub fn binary_merklize_set< + 'a, + const N: usize, + T: BytesSerializable + 'a, + H: BinaryHasher<32>, + I: Iterator + ExactSizeIterator, +>( + input: I, + tree_size: usize, +) -> [u8; 32] { + let input_len = input.len(); + assert!(tree_size >= input_len); + assert!(tree_size.is_power_of_two()); + let mut leaf_hashes = Vec::with_capacity(tree_size); + + for el in input { + let encoding = el.serialize(); + let leaf_hash = H::leaf_hash(&encoding); + leaf_hashes.push(leaf_hash); + } + + let trivial_leaf_hash = H::leaf_hash(&[0u8; N]); + leaf_hashes.resize(tree_size, trivial_leaf_hash); + + let mut previous_layer_hashes = leaf_hashes; + let mut node_hashes = vec![]; + + let num_layers = tree_size.trailing_zeros(); + + for level in 0..num_layers { + for pair in previous_layer_hashes.chunks(2) { + let new_node_hash = H::node_hash(level as usize, &pair[0], &pair[1]); + node_hashes.push(new_node_hash); + } + + let p = std::mem::replace(&mut node_hashes, vec![]); + previous_layer_hashes = p; + } + + assert_eq!(previous_layer_hashes.len(), 1); + let root = previous_layer_hashes[0]; + + root +} + +use crate::boojum::pairing::bls12_381::fr::{Fr, FrRepr}; +use crate::sha2::Digest; +use crate::sha3::Keccak256; +use crate::snark_wrapper::franklin_crypto::bellman::Field; +use crate::snark_wrapper::franklin_crypto::bellman::PrimeField; +use crate::zkevm_circuits::eip_4844::input::ELEMENTS_PER_4844_BLOCK; + +/// Generates eip4844 witness for a given blob and using a trusted setup from a given json path. +/// Returns blob array, linear hash, versioned hash and output hash. +/// Blob must have exact length of 31 * 4096 +// Example trusted setup path is in "src/kzg/trusted_setup.json". +pub fn generate_eip4844_witness( + blob: &[u8], + trusted_setup_path: &str, +) -> ( + [[u8; 31]; ELEMENTS_PER_4844_BLOCK], + [u8; 32], + [u8; 32], + [u8; 32], +) { + // create blob array from vec + assert!(blob.len() == 31 * 4096); + let mut blob_arr = [[0u8; 31]; ELEMENTS_PER_4844_BLOCK]; + blob.chunks(31).enumerate().for_each(|(i, chunk)| { + if chunk.len() == 31 { + blob_arr[i].copy_from_slice(chunk); + } else { + blob_arr[i][..chunk.len()].copy_from_slice(chunk); + } + }); + + // There chunks are representation of the monomial form + let mut poly = crate::zkevm_circuits::eip_4844::zksync_pubdata_into_monomial_form_poly(&blob); + // so FFT then + crate::zkevm_circuits::eip_4844::fft(&mut poly); + // and bitreverse + crate::zkevm_circuits::eip_4844::bitreverse(&mut poly); + // now they can be an input to KZG commitment + + use crate::kzg::compute_commitment; + use circuit_definitions::boojum::pairing::CurveAffine; + + let settings = KzgSettings::new(trusted_setup_path); + + let commitment = compute_commitment(&settings, &poly); + use crate::sha2::Sha256; + let mut versioned_hash: [u8; 32] = Sha256::digest(&commitment.into_compressed()) + .try_into() + .expect("should be able to create an array from a keccak digest"); + versioned_hash[0] = 1; + + // compute linear hash + let linear_hash: [u8; 32] = + Keccak256::digest(&blob_arr.clone().into_iter().flatten().collect::>()) + .try_into() + .expect("should be able to create an array from a keccak digest"); + + // follow circuit logic to produce FS challenge to later open poly + // at this point either from KZG in L1 or compute directly from monomial form in the circuit + let evaluation_point = &Keccak256::digest( + &linear_hash + .iter() + .chain(&versioned_hash) + .map(|x| *x) + .collect::>(), + )[16..]; + let evaluation_repr = + u128::from_be_bytes(evaluation_point.try_into().expect("should have 16 bytes")); + let evaluation_point_fe = Fr::from_repr(FrRepr([ + evaluation_repr as u64, + (evaluation_repr >> 64) as u64, + 0u64, + 0u64, + ])) + .expect("should have a valid field element from 16 bytes"); + let opening_value = blob_arr + .iter() + .enumerate() + .fold(Fr::zero(), |mut acc, (i, x)| { + let repr = x + .chunks(8) + .map(|bytes| { + let mut arr = [0u8; 8]; + for (i, b) in bytes.iter().enumerate() { + arr[i] = *b; + } + u64::from_le_bytes(arr) + }) + .collect::>(); + let el = Fr::from_repr(FrRepr([repr[0], repr[1], repr[2], repr[3]])) + .expect("31 bytes should create valid field element"); + acc.add_assign(&el); + if i != ELEMENTS_PER_4844_BLOCK - 1 { + acc.mul_assign(&evaluation_point_fe); + } + acc + }); + let opening_value_bytes = opening_value + .into_repr() + .0 + .iter() + .rev() + .flat_map(|el| el.to_be_bytes()) + .collect::>(); + + let output_hash: [u8; 32] = Keccak256::digest( + versioned_hash + .iter() + .chain(evaluation_point.iter()) + .chain(opening_value_bytes.iter()) + .map(|x| *x) + .collect::>(), + ) + .try_into() + .expect("should be able to convert genericarray to array"); + + (blob_arr, linear_hash, versioned_hash, output_hash) +} + +pub use circuit_sequencer_api::utils::calldata_to_aligned_data; +pub use circuit_sequencer_api::utils::finalize_queue_state; +pub use circuit_sequencer_api::utils::finalized_queue_state_as_bytes; diff --git a/crates/zkevm_test_harness/src/witness/artifacts.rs b/crates/zkevm_test_harness/src/witness/artifacts.rs new file mode 100644 index 0000000..0b81826 --- /dev/null +++ b/crates/zkevm_test_harness/src/witness/artifacts.rs @@ -0,0 +1,178 @@ +use crate::boojum::field::SmallField; +use crate::boojum::gadgets::queue::QueueStateWitness; +use crate::zk_evm::aux_structures::{DecommittmentQuery, LogQuery, MemoryQuery}; +use crate::zkevm_circuits::base_structures::vm_state::FULL_SPONGE_QUEUE_STATE_WIDTH; +use crate::zkevm_circuits::code_unpacker_sha256::input::CodeDecommitterCircuitInstanceWitness; +use crate::zkevm_circuits::ecrecover::EcrecoverCircuitInstanceWitness; +use crate::zkevm_circuits::keccak256_round_function::input::Keccak256RoundFunctionCircuitInstanceWitness; +use crate::zkevm_circuits::linear_hasher::input::LinearHasherCircuitInstanceWitness; +use crate::zkevm_circuits::log_sorter::input::EventsDeduplicatorInstanceWitness; +use crate::zkevm_circuits::sha256_round_function::input::Sha256RoundFunctionCircuitInstanceWitness; +use crate::zkevm_circuits::sort_decommittment_requests::input::CodeDecommittmentsDeduplicatorInstanceWitness; +use crate::zkevm_circuits::storage_validity_by_grand_product::input::StorageDeduplicatorInstanceWitness; +use circuit_definitions::encodings::decommittment_request::DecommittmentQueueState; +use circuit_definitions::encodings::memory_query::MemoryQueueState; +use circuit_definitions::encodings::*; +use circuit_definitions::zkevm_circuits::secp256r1_verify::Secp256r1VerifyCircuitInstanceWitness; +use circuit_definitions::zkevm_circuits::transient_storage_validity_by_grand_product::input::TransientStorageDeduplicatorInstanceWitness; +use circuit_sequencer_api::toolset::GeometryConfig; +use derivative::Derivative; + +use crate::witness::aux_data_structs::one_per_circuit_accumulator::CircuitsEntryAccumulatorSparse; +use crate::witness::aux_data_structs::per_circuit_accumulator::PerCircuitAccumulatorSparse; + +use crate::zk_evm::zkevm_opcode_defs::system_params::{ + EVENT_AUX_BYTE, L1_MESSAGE_AUX_BYTE, PRECOMPILE_AUX_BYTE, STORAGE_AUX_BYTE, + TRANSIENT_STORAGE_AUX_BYTE, +}; + +use crate::zk_evm::zkevm_opcode_defs::system_params::{ + ECRECOVER_INNER_FUNCTION_PRECOMPILE_FORMAL_ADDRESS, + KECCAK256_ROUND_FUNCTION_PRECOMPILE_FORMAL_ADDRESS, + SECP256R1_VERIFY_INNER_FUNCTION_PRECOMPILE_FORMAL_ADDRESS, + SHA256_ROUND_FUNCTION_PRECOMPILE_FORMAL_ADDRESS, +}; + +#[derive(Derivative)] +#[derivative(Default)] +pub struct DemuxedLogQueries { + pub io: DemuxedIOLogQueries, + pub precompiles: DemuxedPrecompilesLogQueries, +} + +#[derive(Derivative)] +#[derivative(Default)] +pub struct DemuxedIOLogQueries { + pub rollup_storage: Vec, + pub porter_storage: Vec, + pub transient_storage: Vec, + pub event: Vec, + pub to_l1: Vec, +} + +#[derive(Derivative)] +#[derivative(Default)] +pub struct DemuxedPrecompilesLogQueries { + pub keccak: Vec, + pub sha256: Vec, + pub ecrecover: Vec, + pub secp256r1_verify: Vec, +} + +impl DemuxedLogQueries { + pub fn sort_and_push(&mut self, query: LogQuery) { + match query.aux_byte { + STORAGE_AUX_BYTE => { + // sort rollup and porter + match query.shard_id { + 0 => { + self.io.rollup_storage.push(query); + } + 1 => { + self.io.porter_storage.push(query); + } + _ => unreachable!(), + } + } + TRANSIENT_STORAGE_AUX_BYTE => { + self.io.transient_storage.push(query); + } + L1_MESSAGE_AUX_BYTE => { + self.io.to_l1.push(query); + } + EVENT_AUX_BYTE => { + self.io.event.push(query); + } + PRECOMPILE_AUX_BYTE => { + let precomplies = &mut self.precompiles; + assert!(!query.rollback); + match query.address { + a if a == *KECCAK256_ROUND_FUNCTION_PRECOMPILE_FORMAL_ADDRESS => { + precomplies.keccak.push(query); + } + a if a == *SHA256_ROUND_FUNCTION_PRECOMPILE_FORMAL_ADDRESS => { + precomplies.sha256.push(query); + } + a if a == *ECRECOVER_INNER_FUNCTION_PRECOMPILE_FORMAL_ADDRESS => { + precomplies.ecrecover.push(query); + } + a if a == *SECP256R1_VERIFY_INNER_FUNCTION_PRECOMPILE_FORMAL_ADDRESS => { + precomplies.secp256r1_verify.push(query); + } + _ => { + // just burn ergs + } + } + } + _ => unreachable!(), + } + } +} + +pub struct DecommitmentArtifactsForMainVM { + pub prepared_decommittment_queries: PerCircuitAccumulatorSparse<(u32, DecommittmentQuery)>, + pub decommittment_queue_entry_states: + CircuitsEntryAccumulatorSparse<(u32, QueueStateWitness)>, +} + +pub struct MemoryArtifacts { + pub memory_queries: Vec<(u32, MemoryQuery)>, + pub memory_queue_entry_states: + CircuitsEntryAccumulatorSparse<(u32, QueueStateWitness)>, +} + +#[derive(Derivative)] +#[derivative(Default)] +pub struct LogCircuitsArtifacts { + // IO related circuits + pub storage_deduplicator_circuit_data: Vec>, + pub events_deduplicator_circuit_data: Vec>, + pub l1_messages_deduplicator_circuit_data: Vec>, + pub transient_storage_sorter_circuit_data: Vec>, + pub l1_messages_linear_hash_data: Vec>, +} + +#[derive(Derivative)] +#[derivative(Default)] +pub struct MemoryCircuitsArtifacts { + // processed code decommitter circuits, as well as sorting circuit + pub code_decommitter_circuits_data: Vec>, + pub decommittments_deduplicator_circuits_data: + Vec>, + // + pub keccak256_circuits_data: Vec>, + // + pub sha256_circuits_data: Vec>, + // + pub ecrecover_circuits_data: Vec>, + // + pub secp256r1_verify_circuits_data: Vec>, +} + +use crate::witness::aux_data_structs::one_per_circuit_accumulator::LastPerCircuitAccumulator; + +#[derive(Derivative)] +#[derivative(Default)] +pub struct LogQueueStates { + pub states_accumulator: LastPerCircuitAccumulator>, + pub simulator: LogQueueSimulator, +} + +impl LogQueueStates { + pub fn new(cycles_per_circuit: usize) -> Self { + Self { + states_accumulator: LastPerCircuitAccumulator::new(cycles_per_circuit), + simulator: LogQueueSimulator::::empty(), + } + } + + pub fn with_flat_capacity(cycles_per_circuit: usize, flat_capacity: usize) -> Self { + Self { + states_accumulator: LastPerCircuitAccumulator::with_flat_capacity( + cycles_per_circuit, + flat_capacity, + ), + simulator: LogQueueSimulator::::with_capacity(flat_capacity), + } + } +} diff --git a/crates/zkevm_test_harness/src/witness/aux_data_structs/mod.rs b/crates/zkevm_test_harness/src/witness/aux_data_structs/mod.rs new file mode 100644 index 0000000..0bae934 --- /dev/null +++ b/crates/zkevm_test_harness/src/witness/aux_data_structs/mod.rs @@ -0,0 +1,30 @@ +pub trait TupleFirst { + fn first(&self) -> u32; +} + +impl TupleFirst for u32 { + fn first(&self) -> u32 { + *self + } +} + +impl TupleFirst for (u32, T) { + fn first(&self) -> u32 { + self.0 + } +} +impl TupleFirst for (u32, T, U) { + fn first(&self) -> u32 { + self.0 + } +} + +use crate::witness::aux_data_structs::per_circuit_accumulator::PerCircuitAccumulator; +use circuit_definitions::encodings::memory_query::QueueWitness; +use circuit_definitions::encodings::memory_query::{CustomMemoryQueueSimulator, MemoryQueueState}; + +pub type MemoryQueuePerCircuitSimulator = + CustomMemoryQueueSimulator>>; + +pub(crate) mod one_per_circuit_accumulator; +pub(crate) mod per_circuit_accumulator; diff --git a/crates/zkevm_test_harness/src/witness/aux_data_structs/one_per_circuit_accumulator.rs b/crates/zkevm_test_harness/src/witness/aux_data_structs/one_per_circuit_accumulator.rs new file mode 100644 index 0000000..024696d --- /dev/null +++ b/crates/zkevm_test_harness/src/witness/aux_data_structs/one_per_circuit_accumulator.rs @@ -0,0 +1,195 @@ +use crate::witness::aux_data_structs::TupleFirst; +use circuit_sequencer_api::INITIAL_MONOTONIC_CYCLE_COUNTER; + +#[derive(Default)] +struct OnePerCircuitAccumulatorContainer { + cycles_per_circuit: usize, + circuits_data: Vec, + accumulated: usize, +} + +impl OnePerCircuitAccumulatorContainer { + pub fn new(cycles_per_circuit: usize) -> Self { + Self { + cycles_per_circuit, + circuits_data: Default::default(), + accumulated: 0, + } + } + + pub fn with_flat_capacity(cycles_per_circuit: usize, flat_capacity: usize) -> Self { + assert!(cycles_per_circuit != 0); + + let num_circuits = (flat_capacity + cycles_per_circuit - 1) / cycles_per_circuit; + + let mut _self = Self::new(cycles_per_circuit); + _self.circuits_data.reserve_exact(num_circuits); + _self + } + + pub fn reserve_exact(&mut self, additional: usize) { + self.circuits_data.reserve_exact(additional); + } + + pub fn reserve_exact_flat(&mut self, additional: usize) { + let num_circuits = + (self.accumulated + additional + self.cycles_per_circuit - 1) / self.cycles_per_circuit; + + self.circuits_data + .reserve_exact(num_circuits - self.circuits_data.capacity()); + } + + pub fn len(&self) -> usize { + self.accumulated + } + + pub fn last(&self) -> Option<&T> { + self.circuits_data.last() + } + + pub fn push_for_circuit(&mut self, circuit_index: usize, val: T) { + if self.circuits_data.len() <= circuit_index { + self.circuits_data.push(val); + } else { + self.circuits_data[circuit_index] = val; + } + + self.accumulated += 1; + } + + pub fn into_circuits(self) -> Vec { + self.circuits_data + } +} + +/// Accumulates values ​​and saves only the last value for each circuit +pub struct LastPerCircuitAccumulator { + container: OnePerCircuitAccumulatorContainer, +} + +impl LastPerCircuitAccumulator { + pub fn new(cycles_per_circuit: usize) -> Self { + Self { + container: OnePerCircuitAccumulatorContainer::new(cycles_per_circuit), + } + } + + pub fn with_flat_capacity(cycles_per_circuit: usize, flat_capacity: usize) -> Self { + Self { + container: OnePerCircuitAccumulatorContainer::with_flat_capacity( + cycles_per_circuit, + flat_capacity, + ), + } + } + + pub fn reserve_exact_flat(&mut self, additional: usize) { + self.container.reserve_exact_flat(additional); + } + + pub fn into_circuits(self) -> Vec { + self.container.into_circuits() + } + + pub fn last(&self) -> Option<&T> { + self.container.last() + } + + pub fn len(&self) -> usize { + self.container.len() + } + + pub fn push(&mut self, val: T) { + assert!(self.container.cycles_per_circuit != 0); + let circuit_id = self.container.len() / self.container.cycles_per_circuit; + self.container.push_for_circuit(circuit_id, val); + } +} + +impl Default for LastPerCircuitAccumulator { + fn default() -> Self { + Self::new(0) + } +} + +#[derive(Default)] +/// Accumulates values ​​and saves only the entry value for each circuit +/// Uses sparse input - values arrives unevenly +pub struct CircuitsEntryAccumulatorSparse +where + T: Clone, +{ + container: OnePerCircuitAccumulatorContainer, + last: T, +} + +// TODO can be optimized for sparse values +impl CircuitsEntryAccumulatorSparse +where + T: Clone, +{ + pub fn new(cycles_per_circuit: usize, initial_value: T) -> Self { + Self { + container: OnePerCircuitAccumulatorContainer::new(cycles_per_circuit), + last: initial_value, + } + } + + pub fn from_iter>( + cycles_per_circuit: usize, + initial_value: T, + iterator: I, + ) -> Self { + let mut _self = Self::new(cycles_per_circuit, initial_value); + let iterator = iterator.into_iter(); + + for element in iterator { + _self.push(element); + } + + _self + } + + pub fn extend>(&mut self, iterator: I) { + let iterator = iterator.into_iter(); + for element in iterator { + self.push(element); + } + } + + pub fn last(&self) -> &T { + &self.last + } + + pub fn push(&mut self, val: T) { + let cycle = val.first() as usize; + if cycle < INITIAL_MONOTONIC_CYCLE_COUNTER as usize { + self.last = val; + return; + } + + let circuit_index = + (cycle - INITIAL_MONOTONIC_CYCLE_COUNTER as usize) / self.container.cycles_per_circuit; + + self.fill_gap(circuit_index); + self.last = val; + } + + pub fn into_circuits(mut self, amount_of_circuits: usize) -> Vec { + if self.container.len() < amount_of_circuits { + self.container + .reserve_exact(amount_of_circuits - self.container.len()); + } + + self.fill_gap(amount_of_circuits - 1); + + self.container.into_circuits() + } + + fn fill_gap(&mut self, to_index: usize) { + while self.container.len() <= to_index { + self.container + .push_for_circuit(self.container.len(), self.last.clone()); + } + } +} diff --git a/crates/zkevm_test_harness/src/witness/aux_data_structs/per_circuit_accumulator.rs b/crates/zkevm_test_harness/src/witness/aux_data_structs/per_circuit_accumulator.rs new file mode 100644 index 0000000..27ac3fd --- /dev/null +++ b/crates/zkevm_test_harness/src/witness/aux_data_structs/per_circuit_accumulator.rs @@ -0,0 +1,281 @@ +use crate::witness::aux_data_structs::TupleFirst; +use circuit_sequencer_api::INITIAL_MONOTONIC_CYCLE_COUNTER; + +#[derive(Clone, Debug)] +struct PerCircuitAccumulatorContainer { + cycles_per_circuit: usize, + circuits_data: Vec>, + accumulated: usize, +} + +impl PerCircuitAccumulatorContainer { + pub fn new(cycles_per_circuit: usize) -> Self { + Self { + cycles_per_circuit, + circuits_data: Default::default(), + accumulated: 0, + } + } + + pub fn with_flat_capacity(cycles_per_circuit: usize, flat_capacity: usize) -> Self { + assert!(cycles_per_circuit != 0); + + let num_circuits = (flat_capacity + cycles_per_circuit - 1) / cycles_per_circuit; + + // TODO reserve in sub-vectors + let mut _self = Self::new(cycles_per_circuit); + _self.circuits_data.reserve_exact(num_circuits); + _self + } + + pub fn len(&self) -> usize { + self.accumulated + } + + pub fn amount_of_circuits_accumulated(&self) -> usize { + self.circuits_data.len() + } + + pub fn last(&self) -> Option<&T> { + let last_batch = self.circuits_data.last(); + last_batch?; + + last_batch.unwrap().last() + } + + pub fn push_for_circuit(&mut self, circuit_index: usize, val: T) { + while self.circuits_data.len() <= circuit_index { + self.seal_last_batch(); + self.push_new_batch(); + } + + self.circuits_data[circuit_index].push(val); + self.accumulated += 1; + } + + pub fn into_circuits(mut self, amount_of_circuits: usize) -> Vec> { + while self.circuits_data.len() < amount_of_circuits { + self.seal_last_batch(); + self.push_new_batch(); + } + + self.seal_last_batch(); + self.circuits_data + } + + pub fn get_batch(&self, batch_index: usize) -> Option<&Vec> { + self.circuits_data.get(batch_index) + } + + pub fn get_batch_mut(&mut self, batch_index: usize) -> Option<&mut Vec> { + if batch_index >= self.circuits_data.len() { + return None; + } + + let batch = &mut self.circuits_data[batch_index]; + Some(batch) + } + + fn push_new_batch(&mut self) { + self.circuits_data + .push(Vec::with_capacity(self.cycles_per_circuit)); + } + + fn seal_last_batch(&mut self) { + let len = self.circuits_data.len(); + if len == 0 { + return; + } + + self.circuits_data[len - 1].shrink_to_fit(); + } + + pub fn iter(&self) -> PerCircuitAccumulatorIterator { + PerCircuitAccumulatorIterator { + container: self, + batch_index: 0, + inner_index: 0, + } + } + + pub fn into_iter(self) -> PerCircuitAccumulatorIntoIter { + PerCircuitAccumulatorIntoIter { + container: self, + batch_index: 0, + } + } +} + +pub struct PerCircuitAccumulatorIterator<'a, T> { + container: &'a PerCircuitAccumulatorContainer, + batch_index: usize, + inner_index: usize, +} + +impl<'a, T> Iterator for PerCircuitAccumulatorIterator<'a, T> { + type Item = &'a T; + + fn next(&mut self) -> Option { + let mut batch = self.container.get_batch(self.batch_index); + batch?; + + if self.inner_index >= batch.unwrap().len() { + self.batch_index += 1; + self.inner_index = 0; + batch = self.container.get_batch(self.batch_index); + batch?; + } + + let res = batch.unwrap().get(self.inner_index); + self.inner_index += 1; + + res + } +} + +pub struct PerCircuitAccumulatorIntoIter { + container: PerCircuitAccumulatorContainer, + batch_index: usize, +} + +impl Iterator for PerCircuitAccumulatorIntoIter { + type Item = T; + + fn next(&mut self) -> Option { + // TODO can be optimized + let batch = self.container.get_batch_mut(self.batch_index); + batch.as_ref()?; + + let mut batch = batch.unwrap(); + + if batch.is_empty() { + self.batch_index += 1; + let next_batch = self.container.get_batch_mut(self.batch_index); + next_batch.as_ref()?; + batch = next_batch.unwrap(); + } + + let batch: &mut Vec = batch; + if batch.is_empty() { + return None; + } + + let result = batch.remove(0); + Some(result) + } +} + +/// Accumulates values ​for each circuit +/// The contents of the accumulator can be easily divided into circuits +pub struct PerCircuitAccumulator { + container: PerCircuitAccumulatorContainer, +} + +impl PerCircuitAccumulator { + pub fn with_flat_capacity(cycles_per_circuit: usize, flat_capacity: usize) -> Self { + Self { + container: PerCircuitAccumulatorContainer::with_flat_capacity( + cycles_per_circuit, + flat_capacity, + ), + } + } + + pub fn len(&self) -> usize { + self.container.len() + } + + pub fn amount_of_circuits_accumulated(&self) -> usize { + self.container.amount_of_circuits_accumulated() + } + + pub fn push(&mut self, val: T) { + assert!(self.container.cycles_per_circuit != 0); + let idx = self.container.len(); + + let circuit_index = idx / self.container.cycles_per_circuit; + self.container.push_for_circuit(circuit_index, val); + } + + pub fn into_circuits(self, amount_of_circuits: usize) -> Vec> { + self.container.into_circuits(amount_of_circuits) + } + + pub fn iter(&self) -> PerCircuitAccumulatorIterator { + self.container.iter() + } +} + +use circuit_definitions::encodings::ContainerForSimulator; +impl ContainerForSimulator for PerCircuitAccumulator { + fn push(&mut self, val: T) { + self.push(val); + } +} + +/// Accumulates values ​for each circuit +/// The contents of the accumulator can be easily divided into circuits +/// Uses sparse input - values arrives unevenly +#[derive(Clone, Debug)] +pub struct PerCircuitAccumulatorSparse { + container: PerCircuitAccumulatorContainer, +} + +impl PerCircuitAccumulatorSparse { + pub fn new(cycles_per_circuit: usize) -> Self { + Self { + container: PerCircuitAccumulatorContainer::new(cycles_per_circuit), + } + } + + pub fn from_iter>(cycles_per_circuit: usize, iterator: I) -> Self { + let mut _self = Self::new(cycles_per_circuit); + + let iterator = iterator.into_iter(); + + for element in iterator { + _self.push(element); + } + + _self + } + + pub fn last(&self) -> Option<&T> { + self.container.last() + } + + pub fn into_circuits(self, amount_of_circuits: usize) -> Vec> { + self.container.into_circuits(amount_of_circuits) + } + + /// Will ignore queries before INITIAL_MONOTONIC_CYCLE_COUNTER + pub fn push(&mut self, val: T) { + let cycle = val.first() as usize; + + // we should not have any snapshots before INITIAL_MONOTONIC_CYCLE_COUNTER + if cycle < INITIAL_MONOTONIC_CYCLE_COUNTER as usize { + // TODO replace with initial snapshot cycle? + return; + } + + let circuit_index = + (cycle - INITIAL_MONOTONIC_CYCLE_COUNTER as usize) / self.container.cycles_per_circuit; + + self.container.push_for_circuit(circuit_index, val); + } + + pub fn into_iter(self) -> PerCircuitAccumulatorIntoIter { + self.container.into_iter() + } +} + +impl Extend for PerCircuitAccumulatorSparse { + #[inline] + fn extend>(&mut self, iter: I) { + let iterator = iter.into_iter(); + + for element in iterator { + self.push(element); + } + } +} diff --git a/crates/zkevm_test_harness/src/witness/individual_circuits/data_hasher_and_merklizer.rs b/crates/zkevm_test_harness/src/witness/individual_circuits/data_hasher_and_merklizer.rs new file mode 100644 index 0000000..6762bde --- /dev/null +++ b/crates/zkevm_test_harness/src/witness/individual_circuits/data_hasher_and_merklizer.rs @@ -0,0 +1,71 @@ +use super::*; +use crate::sha3::*; +use crate::zkevm_circuits::base_structures::log_query::*; +use crate::zkevm_circuits::linear_hasher::input::*; +use circuit_definitions::encodings::*; + +pub(crate) fn compute_linear_keccak256< + F: SmallField, + R: BuildableCircuitRoundFunction + AlgebraicRoundFunction, +>( + simulator: LogQueueSimulator, + capacity: usize, + _round_function: &R, +) -> Vec> { + if simulator.num_items == 0 { + // now we can skip circuits + return vec![]; + } + + // dbg!(&simulator.num_items); + assert!(capacity <= u32::MAX as usize); + let mut full_bytestring = vec![]; + + // only append meaningful items + for (_, _, el) in simulator.witness.iter() { + let serialized = el.serialize(); + assert_eq!(serialized.len(), L2_TO_L1_MESSAGE_BYTE_LENGTH); + full_bytestring.extend(serialized); + } + + let pubdata_hash: [u8; 32] = Keccak256::digest(&full_bytestring) + .as_slice() + .try_into() + .unwrap(); + + // in general we have everything ready, just form the witness + + let mut input_passthrough_data = LinearHasherInputData::placeholder_witness(); + // we only need the state of demuxed rollup storage queue + input_passthrough_data.queue_state = take_queue_state_from_simulator(&simulator); + + let mut output_passthrough_data = LinearHasherOutputData::placeholder_witness(); + output_passthrough_data.keccak256_hash = pubdata_hash; + + let input_queue_witness: VecDeque<_> = simulator + .witness + .iter() + .map(|(_encoding, old_tail, element)| { + let circuit_witness = element.reflect(); + + (circuit_witness, *old_tail) + }) + .collect(); + + let witness = LinearHasherCircuitInstanceWitness { + closed_form_input: ClosedFormInputWitness { + start_flag: true, + completion_flag: true, + observable_input: input_passthrough_data, + observable_output: output_passthrough_data, + hidden_fsm_input: (), + hidden_fsm_output: (), + }, + + queue_witness: CircuitQueueRawWitness { + elements: input_queue_witness, + }, + }; + + vec![witness] +} diff --git a/crates/zkevm_test_harness/src/witness/individual_circuits/eip4844_repack.rs b/crates/zkevm_test_harness/src/witness/individual_circuits/eip4844_repack.rs new file mode 100644 index 0000000..40b478d --- /dev/null +++ b/crates/zkevm_test_harness/src/witness/individual_circuits/eip4844_repack.rs @@ -0,0 +1,47 @@ +use super::*; +use crate::generate_eip4844_witness; +use crate::zkevm_circuits::eip_4844::input::EIP4844CircuitInstanceWitness; +use crate::zkevm_circuits::eip_4844::input::*; +use crate::zkevm_circuits::fsm_input_output::ClosedFormInputWitness; +use crate::zkevm_circuits::scheduler::block_header::MAX_4844_BLOBS_PER_BLOCK; +use circuit_definitions::{Field, RoundFunction}; +use std::sync::Arc; + +pub(crate) fn compute_eip_4844( + eip_4844_repack_inputs: [Option>; MAX_4844_BLOBS_PER_BLOCK], + trusted_setup_path: &str, +) -> Vec> { + let mut eip_4844_circuits = Vec::new(); + for el in eip_4844_repack_inputs.into_iter() { + let Some(input_witness) = el else { + continue; + }; + let (chunks, linear_hash, versioned_hash, output_hash) = + generate_eip4844_witness::(&input_witness[..], trusted_setup_path); + let data_chunks: VecDeque<_> = chunks + .iter() + .map(|el| BlobChunkWitness { inner: *el }) + .collect(); + + let output_data = EIP4844OutputDataWitness { + linear_hash, + output_hash, + }; + let eip_4844_circuit_input = EIP4844CircuitInstanceWitness:: { + closed_form_input: ClosedFormInputWitness { + start_flag: true, + completion_flag: true, + observable_input: (), + observable_output: output_data, + hidden_fsm_input: (), + hidden_fsm_output: (), + }, + versioned_hash, + linear_hash_output: linear_hash, + data_chunks, + }; + eip_4844_circuits.push(eip_4844_circuit_input); + } + + eip_4844_circuits +} diff --git a/crates/zkevm_test_harness/src/witness/individual_circuits/events_sort_dedup.rs b/crates/zkevm_test_harness/src/witness/individual_circuits/events_sort_dedup.rs new file mode 100644 index 0000000..03ab1f9 --- /dev/null +++ b/crates/zkevm_test_harness/src/witness/individual_circuits/events_sort_dedup.rs @@ -0,0 +1,578 @@ +use super::*; +use crate::ethereum_types::U256; +use crate::witness::artifacts::LogQueueStates; +use crate::zk_evm::aux_structures::*; +use crate::zkevm_circuits::base_structures::log_query::LOG_QUERY_PACKED_WIDTH; +use crate::zkevm_circuits::base_structures::vm_state::QUEUE_STATE_WIDTH; +use crate::zkevm_circuits::log_sorter::input::*; +use crate::zkevm_circuits::DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS; +use circuit_definitions::encodings::*; +use rayon::prelude::*; +use smallvec::SmallVec; +use std::cmp::Ordering; + +pub(crate) fn compute_events_dedup_and_sort< + F: SmallField, + R: BuildableCircuitRoundFunction + AlgebraicRoundFunction, +>( + unsorted_queries: Vec, + unsorted_queue: LogQueueStates, + result_queue_simulator: &mut LogQueueSimulator, + per_circuit_capacity: usize, + round_function: &R, +) -> Vec> { + // trivial case if nothing to process + + if unsorted_queries.is_empty() { + return vec![]; + } + assert!(unsorted_queue.states_accumulator.len() > 0); + + // parallelizable between events and L2 to L1 messages + + // first we sort the storage log (only storage now) by composite key + + let total_amount_of_queries = unsorted_queries.len(); + let amount_of_circuits = + (total_amount_of_queries + per_circuit_capacity - 1) / per_circuit_capacity; + + let mut sorted_queries: Vec<_> = unsorted_queries; + + sorted_queries.par_sort_by(|a, b| match a.timestamp.0.cmp(&b.timestamp.0) { + Ordering::Equal => { + if b.rollback { + Ordering::Less + } else { + Ordering::Greater + } + } + r @ _ => r, + }); + + let mut intermediate_sorted_simulator = + LogQueueSimulator::::with_capacity(total_amount_of_queries); + let mut sorted_log_simulator_states_chunk_final_states = Vec::with_capacity(amount_of_circuits); + for (i, el) in sorted_queries.iter().enumerate() { + let (_, intermediate_state) = intermediate_sorted_simulator + .push_and_output_intermediate_data(el.clone(), round_function); + + if (i % per_circuit_capacity == per_circuit_capacity - 1) + || i == total_amount_of_queries - 1 + { + sorted_log_simulator_states_chunk_final_states.push(intermediate_state); + } + } + + let unsorted_log_simulator_states_chunk_final_states: Vec<_> = + unsorted_queue.states_accumulator.into_circuits(); + + let intermediate_sorted_simulator_final_state = + take_queue_state_from_simulator(&intermediate_sorted_simulator); + let sorted_queries = sort_and_dedup_events_log(sorted_queries); + + let unsorted_simulator_final_state = take_queue_state_from_simulator(&unsorted_queue.simulator); + + let challenges = produce_fs_challenges::< + F, + R, + QUEUE_STATE_WIDTH, + { LOG_QUERY_PACKED_WIDTH + 1 }, + DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS, + >( + take_queue_state_from_simulator(&unsorted_queue.simulator).tail, + take_queue_state_from_simulator(&intermediate_sorted_simulator).tail, + round_function, + ); + + assert_eq!( + unsorted_simulator_final_state.tail.length, + intermediate_sorted_simulator_final_state.tail.length + ); + + let lhs_contributions: Vec<_> = unsorted_queue + .simulator + .witness + .iter() + .map(|el| &el.0) + .collect(); + let rhs_contributions: Vec<_> = intermediate_sorted_simulator + .witness + .iter() + .map(|el| &el.0) + .collect(); + + // -------------------- + + let mut lhs_grand_product_chains = vec![]; + let mut rhs_grand_product_chains = vec![]; + + for idx in 0..DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS { + let (lhs_grand_product_chain, rhs_grand_product_chain) = compute_grand_product_chains::< + F, + LOG_QUERY_PACKED_WIDTH, + { LOG_QUERY_PACKED_WIDTH + 1 }, + >( + &lhs_contributions, + &rhs_contributions, + &challenges[idx], + ); + + assert_eq!( + lhs_grand_product_chain.len(), + unsorted_queue.simulator.witness.len() + ); + assert_eq!( + lhs_grand_product_chain.len(), + intermediate_sorted_simulator.witness.len() + ); + + lhs_grand_product_chains.push(lhs_grand_product_chain); + rhs_grand_product_chains.push(rhs_grand_product_chain); + } + + let transposed_lhs_chains = transpose_chunks(&lhs_grand_product_chains, per_circuit_capacity); + let transposed_rhs_chains = transpose_chunks(&rhs_grand_product_chains, per_circuit_capacity); + + assert!(unsorted_log_simulator_states_chunk_final_states.len() > 0); + assert_eq!( + unsorted_log_simulator_states_chunk_final_states.len(), + sorted_log_simulator_states_chunk_final_states.len() + ); + assert_eq!( + unsorted_log_simulator_states_chunk_final_states.len(), + transposed_lhs_chains.len() + ); + assert_eq!( + unsorted_log_simulator_states_chunk_final_states.len(), + transposed_rhs_chains.len() + ); + assert_eq!( + unsorted_log_simulator_states_chunk_final_states.len(), + unsorted_queue + .simulator + .witness + .as_slices() + .0 + .chunks(per_circuit_capacity) + .len() + ); + assert_eq!( + unsorted_log_simulator_states_chunk_final_states.len(), + intermediate_sorted_simulator + .witness + .as_slices() + .0 + .chunks(per_circuit_capacity) + .len() + ); + + let it = unsorted_log_simulator_states_chunk_final_states + .into_iter() + .zip(sorted_log_simulator_states_chunk_final_states) + .zip(transposed_lhs_chains.into_iter()) + .zip(transposed_rhs_chains.into_iter()) + .zip( + unsorted_queue + .simulator + .witness + .as_slices() + .0 + .chunks(per_circuit_capacity), + ) + .zip( + intermediate_sorted_simulator + .witness + .as_slices() + .0 + .chunks(per_circuit_capacity), + ); + + let num_circuits = it.len(); + let mut results = vec![]; + + use crate::ethereum_types::Address; + + let mut previous_key = 0u32; + let empty_log_item = LogQuery { + timestamp: Timestamp(0), + tx_number_in_block: 0, + aux_byte: 0, + shard_id: 0, + address: Address::zero(), + key: U256::zero(), + read_value: U256::zero(), + written_value: U256::zero(), + rw_flag: false, + rollback: false, + is_service: false, + }; + + let mut previous_item = empty_log_item; + + let mut deduplicated_queries_it = sorted_queries.iter(); + + let mut current_final_sorted_queue_state = + take_queue_state_from_simulator(&result_queue_simulator); + + let mut current_lhs_product = [F::ONE; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS]; + let mut current_rhs_product = [F::ONE; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS]; + + for ( + idx, + ( + ( + ( + ((unsorted_sponge_states, sorted_sponge_states), lhs_grand_product), + rhs_grand_product, + ), + unsorted_states, + ), + sorted_states, + ), + ) in it.enumerate() + { + // we need witnesses to pop elements from the front of the queue + + let unsorted_queue_witness: VecDeque<_> = unsorted_states + .iter() + .map(|(_encoding, old_tail, element)| { + let as_storage_log = log_query_into_circuit_log_query_witness(element); + + (as_storage_log, *old_tail) + }) + .collect(); + + let unsorted_witness = CircuitQueueRawWitness::< + F, + zkevm_circuits::base_structures::log_query::LogQuery, + 4, + LOG_QUERY_PACKED_WIDTH, + > { + elements: unsorted_queue_witness, + }; + + let intermediate_sorted_queue_witness: VecDeque<_> = sorted_states + .iter() + .map(|(_encoding, old_tail, element)| { + let as_timestamped_storage_witness = + log_query_into_circuit_log_query_witness(element); + + (as_timestamped_storage_witness, *old_tail) + }) + .collect(); + + let intermediate_sorted_queue_witness = CircuitQueueRawWitness::< + F, + zkevm_circuits::base_structures::log_query::LogQuery, + 4, + LOG_QUERY_PACKED_WIDTH, + > { + elements: intermediate_sorted_queue_witness, + }; + + // now we need to have final grand product value that will also become an input for the next circuit + + let is_first = idx == 0; + let is_last = idx == num_circuits - 1; + + let last_unsorted_state = unsorted_sponge_states; + let last_sorted_state = sorted_sponge_states; + + let accumulated_lhs: [F; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS] = lhs_grand_product + .iter() + .map(|el| *el.last().unwrap()) + .collect::>() + .try_into() + .unwrap(); + let accumulated_rhs: [F; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS] = rhs_grand_product + .iter() + .map(|el| *el.last().unwrap()) + .collect::>() + .try_into() + .unwrap(); + + // simulate the logic + let (new_last_key, new_last_item) = { + let mut new_last_key = previous_key; + let mut new_last_item = previous_item; + let mut current_timestamp = previous_item.timestamp.0; + + let num_items_in_chunk = sorted_states.len(); + let mut exhausted = false; + + for (sub_idx, (_encoding, _previous_tail, item)) in sorted_states.iter().enumerate() { + let first_ever = sub_idx == 0 && is_first; + let last_iteration = sub_idx == num_items_in_chunk - 1; + let is_last_ever = last_iteration && is_last; + + // we know that timestamp of 0 is unreachable, so we do not need + // to have a special first cycle here + + if !first_ever { + assert!(item.rw_flag == true); + let same_cell = current_timestamp == item.timestamp.0; + + if same_cell { + assert!(item.rollback == true); + } else { + assert!(item.rollback == false); + if new_last_item.rollback == false { + // finish with previous one and start a new one + if let Some(next_query) = deduplicated_queries_it.next() { + assert_eq!(next_query.address, new_last_item.address); + assert_eq!(next_query.key, new_last_item.key); + assert_eq!(next_query.written_value, new_last_item.written_value); + let _ = result_queue_simulator + .push_and_output_intermediate_data(*next_query, round_function); + } else { + assert!(is_last); + assert!(exhausted == false); + exhausted = true; + } + } + } + } + + new_last_key = item.timestamp.0; + new_last_item = *item; + current_timestamp = item.timestamp.0; + + // last cycle is special, we do not try to pop if we processed the last item + if is_last_ever { + if !exhausted { + if new_last_item.rollback == false { + let next_query = deduplicated_queries_it.next().unwrap(); + let _ = result_queue_simulator + .push_and_output_intermediate_data(*next_query, round_function); + } + } + } + } + + (new_last_key, new_last_item) + }; + + use crate::boojum::gadgets::queue::QueueState; + let placeholder_witness = QueueState::::placeholder_witness(); + + let (current_unsorted_queue_state, current_intermediate_sorted_queue_state) = results + .last() + .map(|el: &EventsDeduplicatorInstanceWitness| { + let tmp = &el.closed_form_input.hidden_fsm_output; + + ( + tmp.initial_unsorted_queue_state.clone(), + tmp.intermediate_sorted_queue_state.clone(), + ) + }) + .unwrap_or((placeholder_witness.clone(), placeholder_witness)); + + // we use current final state as the intermediate head + let mut final_unsorted_state = transform_queue_state(last_unsorted_state); + final_unsorted_state.head = final_unsorted_state.tail.tail; + final_unsorted_state.tail.tail = unsorted_simulator_final_state.tail.tail; + final_unsorted_state.tail.length = + unsorted_simulator_final_state.tail.length - final_unsorted_state.tail.length; + + let mut final_intermediate_sorted_state = transform_queue_state(last_sorted_state); + final_intermediate_sorted_state.head = last_sorted_state.tail; + final_intermediate_sorted_state.tail.tail = + intermediate_sorted_simulator_final_state.tail.tail; + final_intermediate_sorted_state.tail.length = + intermediate_sorted_simulator_final_state.tail.length - last_sorted_state.num_items; + + assert_eq!( + final_unsorted_state.tail.length, + final_intermediate_sorted_state.tail.length + ); + + let last_final_sorted_queue_state = + take_queue_state_from_simulator(&result_queue_simulator); + + let mut instance_witness = EventsDeduplicatorInstanceWitness:: { + closed_form_input: ClosedFormInputWitness { + start_flag: is_first, + completion_flag: is_last, + observable_input: EventsDeduplicatorInputDataWitness { + initial_log_queue_state: unsorted_simulator_final_state.clone(), + intermediate_sorted_queue_state: intermediate_sorted_simulator_final_state + .clone(), + }, + observable_output: EventsDeduplicatorOutputData::placeholder_witness(), + hidden_fsm_input: EventsDeduplicatorFSMInputOutputWitness { + lhs_accumulator: current_lhs_product, + rhs_accumulator: current_rhs_product, + initial_unsorted_queue_state: current_unsorted_queue_state, + intermediate_sorted_queue_state: current_intermediate_sorted_queue_state, + final_result_queue_state: current_final_sorted_queue_state.clone(), + previous_key, + previous_item: log_query_into_circuit_log_query_witness(&previous_item), + }, + hidden_fsm_output: EventsDeduplicatorFSMInputOutputWitness { + lhs_accumulator: accumulated_lhs, + rhs_accumulator: accumulated_rhs, + initial_unsorted_queue_state: final_unsorted_state, + intermediate_sorted_queue_state: final_intermediate_sorted_state, + final_result_queue_state: last_final_sorted_queue_state.clone(), + previous_key: new_last_key, + previous_item: log_query_into_circuit_log_query_witness(&new_last_item), + }, + }, + initial_queue_witness: unsorted_witness, + intermediate_sorted_queue_witness: intermediate_sorted_queue_witness, + }; + + assert_eq!( + instance_witness.initial_queue_witness.elements.len(), + instance_witness + .intermediate_sorted_queue_witness + .elements + .len() + ); + + if sorted_states.len() % per_circuit_capacity != 0 { + // circuit does padding, so all previous values must be reset + instance_witness + .closed_form_input + .hidden_fsm_output + .previous_key = 0u32; + instance_witness + .closed_form_input + .hidden_fsm_output + .previous_item = log_query_into_circuit_log_query_witness(&empty_log_item); + } + + current_lhs_product = accumulated_lhs; + current_rhs_product = accumulated_rhs; + + previous_key = new_last_key; + previous_item = new_last_item; + + current_final_sorted_queue_state = last_final_sorted_queue_state; + + results.push(instance_witness); + } + + assert!(results.len() > 0); + + assert!(deduplicated_queries_it.next().is_none()); + + let final_sorted_queue_state = take_queue_state_from_simulator(&result_queue_simulator); + + results + .last_mut() + .unwrap() + .closed_form_input + .observable_output + .final_queue_state = final_sorted_queue_state.clone(); + + results +} + +pub(crate) fn sort_and_dedup_events_log(sorted_history: Vec) -> Vec { + let mut stack = SmallVec::<[LogQuery; 2]>::new(); + + let mut net_history = vec![]; + + for el in sorted_history.iter().copied() { + assert_eq!(el.shard_id, 0, "only rollup shard is supported"); + if stack.is_empty() { + assert!(el.rollback == false); + stack.push(el); + } else { + // we can always pop as it's either one to add to queue, or discard + let previous = stack.pop().unwrap(); + if previous.timestamp == el.timestamp { + assert!(previous.rollback == false); + assert!(el.rollback == true); + assert!(previous.rw_flag == true); + assert!(el.rw_flag == true); + assert_eq!(previous.tx_number_in_block, el.tx_number_in_block); + assert_eq!(previous.shard_id, el.shard_id); + assert_eq!(previous.address, el.address); + assert_eq!(previous.key, el.key); + assert_eq!(previous.written_value, el.written_value); + assert_eq!(previous.is_service, el.is_service); + // do nothing, it's rolled back + + continue; + } else { + assert!(el.rollback == false); + stack.push(el); + + // cleanup some fields + // flags are conventions + let sorted_log_query = LogQuery { + timestamp: Timestamp(0), + tx_number_in_block: previous.tx_number_in_block, + aux_byte: 0, + shard_id: previous.shard_id, + address: previous.address, + key: previous.key, + read_value: U256::zero(), + written_value: previous.written_value, + rw_flag: false, + rollback: false, + is_service: previous.is_service, + }; + + net_history.push(sorted_log_query); + } + } + } + + if let Some(previous) = stack.pop() { + // cleanup some fields + // flags are conventions + let sorted_log_query = LogQuery { + timestamp: Timestamp(0), + tx_number_in_block: previous.tx_number_in_block, + aux_byte: 0, + shard_id: previous.shard_id, + address: previous.address, + key: previous.key, + read_value: U256::zero(), + written_value: previous.written_value, + rw_flag: false, + rollback: false, + is_service: previous.is_service, + }; + + net_history.push(sorted_log_query); + } + + net_history +} + +// For server side use convenience +pub fn simulate_events_log_for_commitment< + F: SmallField, + R: BuildableCircuitRoundFunction + AlgebraicRoundFunction, +>( + history: Vec, + round_function: &R, +) -> (Vec, (u32, [F; QUEUE_STATE_WIDTH])) { + let mut sorted_history = history; + sorted_history.sort_by(|a, b| match a.timestamp.0.cmp(&b.timestamp.0) { + Ordering::Equal => { + if b.rollback { + Ordering::Less + } else { + Ordering::Greater + } + } + r @ _ => r, + }); + + let net_history = sort_and_dedup_events_log(sorted_history); + + let mut simulator = LogQueueSimulator::::with_capacity(net_history.len()); + for el in net_history.iter().copied() { + simulator.push(el, round_function); + } + + let queue_len = simulator.num_items; + let tail = simulator.tail; + + (net_history, (queue_len, tail)) +} diff --git a/crates/zkevm_test_harness/src/witness/individual_circuits/log_demux.rs b/crates/zkevm_test_harness/src/witness/individual_circuits/log_demux.rs new file mode 100644 index 0000000..6cc135b --- /dev/null +++ b/crates/zkevm_test_harness/src/witness/individual_circuits/log_demux.rs @@ -0,0 +1,420 @@ +use std::sync::Arc; + +use self::toolset::GeometryConfig; +use self::witness::postprocessing::FirstAndLastCircuitWitness; +use crate::witness::postprocessing::observable_witness::LogDemuxerObservableWitness; + +use super::*; +use crate::witness::artifacts::{DemuxedLogQueries, LogQueueStates}; +use crate::witness::aux_data_structs::one_per_circuit_accumulator::LastPerCircuitAccumulator; +use crate::witness::postprocessing::CircuitMaker; +use crate::zkevm_circuits::base_structures::log_query::*; +use crate::zkevm_circuits::demux_log_queue::input::*; +use crate::zkevm_circuits::demux_log_queue::ALL_DEMUX_OUTPUTS; +use crate::zkevm_circuits::demux_log_queue::NUM_DEMUX_OUTPUTS; +use circuit_definitions::circuit_definitions::base_layer::{ + LogDemuxInstanceSynthesisFunction, ZkSyncBaseLayerCircuit, +}; +use circuit_definitions::encodings::recursion_request::RecursionQueueSimulator; +use circuit_definitions::zkevm_circuits::demux_log_queue::DemuxOutput; +use circuit_definitions::zkevm_circuits::scheduler::aux::BaseLayerCircuitType; +use circuit_definitions::{encodings::*, Field, RoundFunction}; +use oracle::WitnessGenerationArtifact; +use zk_evm::zkevm_opcode_defs::SECP256R1_VERIFY_PRECOMPILE_ADDRESS; + +use crate::zk_evm::aux_structures::LogQuery as LogQuery_; +use std::collections::HashMap; + +use crate::zk_evm::zkevm_opcode_defs::system_params::{ + ECRECOVER_INNER_FUNCTION_PRECOMPILE_FORMAL_ADDRESS, + KECCAK256_ROUND_FUNCTION_PRECOMPILE_FORMAL_ADDRESS, + SECP256R1_VERIFY_INNER_FUNCTION_PRECOMPILE_FORMAL_ADDRESS, + SHA256_ROUND_FUNCTION_PRECOMPILE_FORMAL_ADDRESS, +}; + +use crate::zk_evm::zkevm_opcode_defs::system_params::{ + EVENT_AUX_BYTE, L1_MESSAGE_AUX_BYTE, PRECOMPILE_AUX_BYTE, STORAGE_AUX_BYTE, + TRANSIENT_STORAGE_AUX_BYTE, +}; + +pub(crate) struct LogDemuxCircuitArtifacts { + pub applied_log_queue_simulator: LogQueueSimulator, + pub applied_queue_states_accumulator: LastPerCircuitAccumulator<(u32, LogQueueState)>, +} + +pub(crate) struct PrecompilesQueuesStates { + pub keccak: LogQueueStates, + pub sha256: LogQueueStates, + pub ecrecover: LogQueueStates, + pub secp256r1_verify: LogQueueStates, +} + +pub(crate) struct IOLogsQueuesStates { + pub rollup_storage: LogQueueStates, + pub transient_storage: LogQueueStates, + pub events: LogQueueStates, + pub l2_to_l1: LogQueueStates, +} + +pub struct DemuxedQueuesStatesSimulator { + pub sub_queues: HashMap>, + round_function: RoundFunction, +} + +impl DemuxedQueuesStatesSimulator { + pub fn new( + geometry: GeometryConfig, + amounts_of_queries: [usize; NUM_DEMUX_OUTPUTS], + round_function: RoundFunction, + ) -> Self { + use crate::zkevm_circuits::demux_log_queue::ALL_DEMUX_OUTPUTS; + let mut sub_queues = HashMap::new(); + for output in ALL_DEMUX_OUTPUTS { + let geometry_for_output = match output { + DemuxOutput::RollupStorage => geometry.cycles_per_storage_sorter, + DemuxOutput::TransientStorage => geometry.cycles_per_transient_storage_sorter, + DemuxOutput::ECRecover => geometry.cycles_per_ecrecover_circuit, + DemuxOutput::Secp256r1Verify => geometry.cycles_per_secp256r1_verify_circuit, + DemuxOutput::Keccak => geometry.cycles_per_keccak256_circuit, + DemuxOutput::Sha256 => geometry.cycles_per_sha256_circuit, + DemuxOutput::Events => geometry.cycles_per_events_or_l1_messages_sorter, + DemuxOutput::L2ToL1Messages => geometry.cycles_per_events_or_l1_messages_sorter, + DemuxOutput::PorterStorage => 0, // NOT IMPLEMENTED + }; + + let state = if let DemuxOutput::PorterStorage = output { + LogQueueStates::::default() // NOT IMPLEMENTED + } else { + LogQueueStates::::with_flat_capacity( + geometry_for_output as usize, + amounts_of_queries[output as usize], + ) + }; + + sub_queues.insert(output, state); + } + + Self { + sub_queues, + round_function, + } + } + + pub fn build_empty( + round_function: Poseidon2Goldilocks, + ) -> (IOLogsQueuesStates, PrecompilesQueuesStates) { + let mut sub_queues = HashMap::new(); + for output in ALL_DEMUX_OUTPUTS { + sub_queues.insert(output, LogQueueStates::::default()); + } + + Self { + sub_queues, + round_function, + } + .into_results() + } + + pub fn get_sub_queue_for_query(query: &LogQuery_) -> Option { + match query.aux_byte { + STORAGE_AUX_BYTE => Some(DemuxOutput::RollupStorage), + TRANSIENT_STORAGE_AUX_BYTE => Some(DemuxOutput::TransientStorage), + L1_MESSAGE_AUX_BYTE => Some(DemuxOutput::L2ToL1Messages), + EVENT_AUX_BYTE => Some(DemuxOutput::Events), + PRECOMPILE_AUX_BYTE => { + assert!(!query.rollback); + match query.address { + a if a == *KECCAK256_ROUND_FUNCTION_PRECOMPILE_FORMAL_ADDRESS => { + Some(DemuxOutput::Keccak) + } + a if a == *SHA256_ROUND_FUNCTION_PRECOMPILE_FORMAL_ADDRESS => { + Some(DemuxOutput::Sha256) + } + a if a == *ECRECOVER_INNER_FUNCTION_PRECOMPILE_FORMAL_ADDRESS => { + Some(DemuxOutput::ECRecover) + } + a if a == *SECP256R1_VERIFY_INNER_FUNCTION_PRECOMPILE_FORMAL_ADDRESS => { + Some(DemuxOutput::Secp256r1Verify) + } + _ => None, + } + } + _ => unreachable!("Invalid query aux byte"), + } + } + + pub fn simulate_and_push(&mut self, demux_output: DemuxOutput, item: LogQuery_) { + let sub_queue = self.sub_queues.get_mut(&demux_output).unwrap(); + + let (_old_tail, intermediate_info) = sub_queue + .simulator + .push_and_output_intermediate_data(item, &self.round_function); + + sub_queue.states_accumulator.push(intermediate_info); + } + + pub fn into_results(self) -> (IOLogsQueuesStates, PrecompilesQueuesStates) { + let mut queries = self.sub_queues; + ( + IOLogsQueuesStates { + rollup_storage: queries.remove(&DemuxOutput::RollupStorage).unwrap(), + transient_storage: queries.remove(&DemuxOutput::TransientStorage).unwrap(), + events: queries.remove(&DemuxOutput::Events).unwrap(), + l2_to_l1: queries.remove(&DemuxOutput::L2ToL1Messages).unwrap(), + }, + PrecompilesQueuesStates { + keccak: queries.remove(&DemuxOutput::Keccak).unwrap(), + sha256: queries.remove(&DemuxOutput::Sha256).unwrap(), + ecrecover: queries.remove(&DemuxOutput::ECRecover).unwrap(), + secp256r1_verify: queries.remove(&DemuxOutput::Secp256r1Verify).unwrap(), + }, + ) + } +} + +/// Take a storage log, output logs separately for events, l1 messages, storage, etc +pub(crate) fn process_logs_demux_and_make_circuits( + mut log_demux_artifacts: LogDemuxCircuitArtifacts, + demuxed_queues: &DemuxedLogQueries, + per_circuit_capacity: usize, + round_function: &RoundFunction, + geometry: &GeometryConfig, + mut artifacts_callback: CB, +) -> ( + FirstAndLastCircuitWitness>, + Vec>, + IOLogsQueuesStates, + PrecompilesQueuesStates, +) { + log_demux_artifacts + .applied_log_queue_simulator + .witness + .make_contiguous(); + + let circuit_type = BaseLayerCircuitType::LogDemultiplexer; + + let mut maker = CircuitMaker::new(geometry.cycles_per_log_demuxer, round_function.clone()); + + // trivial empty case + if log_demux_artifacts + .applied_log_queue_simulator + .witness + .as_slices() + .0 + .is_empty() + { + let (log_demux_circuits, queue_simulator, log_demux_circuits_compact_forms_witnesses) = + maker.into_results(); + artifacts_callback(WitnessGenerationArtifact::RecursionQueue(( + circuit_type as u64, + queue_simulator, + log_demux_circuits_compact_forms_witnesses.clone(), + ))); + + let (io_queues_states, precompiles_queues_states) = + DemuxedQueuesStatesSimulator::build_empty(*round_function); + + return ( + log_demux_circuits, + log_demux_circuits_compact_forms_witnesses, + io_queues_states, + precompiles_queues_states, + ); + } + + // parallelizable + + assert!(log_demux_artifacts + .applied_log_queue_simulator + .witness + .as_slices() + .1 + .is_empty()); + + let input_queue_witness = &log_demux_artifacts + .applied_log_queue_simulator + .witness + .as_slices() + .0; + + assert!( + input_queue_witness.len() == log_demux_artifacts.applied_queue_states_accumulator.len() + ); + + let last_applied_log_queue_states_for_chunks = log_demux_artifacts + .applied_queue_states_accumulator + .into_circuits(); + + let num_chunks = input_queue_witness.chunks(per_circuit_capacity).len(); + + let full_log_queue_state = + take_queue_state_from_simulator(&log_demux_artifacts.applied_log_queue_simulator); + + let mut queries_iterators = HashMap::new(); + queries_iterators.insert( + DemuxOutput::RollupStorage, + demuxed_queues.io.rollup_storage.iter(), + ); + queries_iterators.insert(DemuxOutput::Events, demuxed_queues.io.event.iter()); + queries_iterators.insert(DemuxOutput::L2ToL1Messages, demuxed_queues.io.to_l1.iter()); + queries_iterators.insert( + DemuxOutput::TransientStorage, + demuxed_queues.io.transient_storage.iter(), + ); + + queries_iterators.insert( + DemuxOutput::Keccak, + demuxed_queues.precompiles.keccak.iter(), + ); + queries_iterators.insert( + DemuxOutput::Sha256, + demuxed_queues.precompiles.sha256.iter(), + ); + queries_iterators.insert( + DemuxOutput::ECRecover, + demuxed_queues.precompiles.ecrecover.iter(), + ); + queries_iterators.insert( + DemuxOutput::Secp256r1Verify, + demuxed_queues.precompiles.secp256r1_verify.iter(), + ); + + let mut input_passthrough_data = LogDemuxerInputData::placeholder_witness(); + // we only need the state of the original input + input_passthrough_data.initial_log_queue_state = + take_queue_state_from_simulator(&log_demux_artifacts.applied_log_queue_simulator); + + let output_passthrough_data = LogDemuxerOutputData::placeholder_witness(); + let mut previous_hidden_fsm_output = None; + + let mut amounts_of_queries: [usize; NUM_DEMUX_OUTPUTS] = std::array::from_fn(|_| 0); + for (_, _, query) in input_queue_witness.iter() { + let sub_queue = DemuxedQueuesStatesSimulator::get_sub_queue_for_query(query); + if let Some(sub_queue) = sub_queue { + amounts_of_queries[sub_queue as usize] += 1; + } + } + + let mut demuxed_simulator = + DemuxedQueuesStatesSimulator::new(*geometry, amounts_of_queries, *round_function); + + let simulator_witness_it = log_demux_artifacts + .applied_log_queue_simulator + .witness + .as_slices() + .0 + .chunks(per_circuit_capacity); + + for (circuit_index, (input_chunk, simulator_witness_chunk)) in input_queue_witness + .chunks(per_circuit_capacity) + .zip(simulator_witness_it) + .enumerate() + { + let is_first = circuit_index == 0; + let is_last = circuit_index == num_chunks - 1; + + // simulate the circuit + for (_, _, query) in input_chunk.iter() { + let sub_queue = DemuxedQueuesStatesSimulator::get_sub_queue_for_query(query); + if let Some(sub_queue) = sub_queue { + let log_query = queries_iterators + .get_mut(&sub_queue) + .unwrap() + .next() + .copied() + .unwrap(); + demuxed_simulator.simulate_and_push(sub_queue, log_query); + } else { + // just burn ergs + } + } + + // make the output + + let input_witness: VecDeque<_> = simulator_witness_chunk + .into_iter() + .map(|(_encoding, old_tail, element)| { + (log_query_into_circuit_log_query_witness(element), *old_tail) + }) + .collect(); + + let mut fsm_output = LogDemuxerFSMInputOutput::placeholder_witness(); + + let mut initial_log_queue_state = full_log_queue_state.clone(); + let last_applied_log_queue_state = + last_applied_log_queue_states_for_chunks[circuit_index].1; + initial_log_queue_state.head = last_applied_log_queue_state.tail; + initial_log_queue_state.tail.length -= last_applied_log_queue_state.num_items; + + fsm_output.initial_log_queue_state = initial_log_queue_state; + fsm_output.output_queue_states = std::array::from_fn(|i| { + let output = ALL_DEMUX_OUTPUTS[i]; + let sub_queue = demuxed_simulator.sub_queues.get(&output).unwrap(); + take_queue_state_from_simulator(&sub_queue.simulator) + }); + + let mut witness = LogDemuxerCircuitInstanceWitness { + closed_form_input: ClosedFormInputWitness { + start_flag: is_first, + completion_flag: is_last, + observable_input: input_passthrough_data.clone(), + observable_output: output_passthrough_data.clone(), + hidden_fsm_input: LogDemuxerFSMInputOutput::placeholder_witness(), + hidden_fsm_output: fsm_output, + }, + initial_queue_witness: CircuitQueueRawWitness::< + Field, + LogQuery, + 4, + LOG_QUERY_PACKED_WIDTH, + > { + elements: input_witness, + }, + }; + + if is_last { + witness + .closed_form_input + .observable_output + .output_queue_states = std::array::from_fn(|i| { + let output = ALL_DEMUX_OUTPUTS[i]; + let sub_queue = demuxed_simulator.sub_queues.get(&output).unwrap(); + take_queue_state_from_simulator(&sub_queue.simulator) + }); + } + + if let Some(output) = previous_hidden_fsm_output { + witness.closed_form_input.hidden_fsm_input = output; + } + previous_hidden_fsm_output = Some(witness.closed_form_input.hidden_fsm_output.clone()); + + artifacts_callback(WitnessGenerationArtifact::BaseLayerCircuit( + ZkSyncBaseLayerCircuit::LogDemuxer(maker.process(witness, circuit_type)), + )); + } + + let (log_demux_circuits, queue_simulator, log_demux_circuits_compact_forms_witnesses) = + maker.into_results(); + artifacts_callback(WitnessGenerationArtifact::RecursionQueue(( + circuit_type as u64, + queue_simulator, + log_demux_circuits_compact_forms_witnesses.clone(), + ))); + + for (sub_queue, mut iter) in queries_iterators { + assert!( + iter.next().is_none(), + "Some queries left not processed in {:?}", + sub_queue + ); + } + + let (io_queues_states, precompiles_queues_states) = demuxed_simulator.into_results(); + + ( + log_demux_circuits, + log_demux_circuits_compact_forms_witnesses, + io_queues_states, + precompiles_queues_states, + ) +} diff --git a/crates/zkevm_test_harness/src/witness/individual_circuits/main_vm.rs b/crates/zkevm_test_harness/src/witness/individual_circuits/main_vm.rs new file mode 100644 index 0000000..7cd885f --- /dev/null +++ b/crates/zkevm_test_harness/src/witness/individual_circuits/main_vm.rs @@ -0,0 +1,543 @@ +use std::sync::Arc; + +use crate::witness::artifacts::{DecommitmentArtifactsForMainVM, MemoryArtifacts}; +use crate::witness::aux_data_structs::one_per_circuit_accumulator::CircuitsEntryAccumulatorSparse; +use crate::witness::aux_data_structs::per_circuit_accumulator::PerCircuitAccumulatorSparse; +use crate::witness::individual_circuits::SmallField; +use crate::witness::oracle::FrameLogQueueDetailedState; +use crate::witness::postprocessing::{ClosedFormInputField, FirstAndLastCircuitWitness}; +use crate::witness::tracer::vm_snapshot::VmSnapshot; +use crate::witness::utils::simulate_public_input_value_from_encodable_witness; +use crate::zk_evm::aux_structures::MemoryQuery; +use crate::zk_evm::vm_state::VmLocalState; +use crate::zkevm_circuits::base_structures::vm_state::{ + GlobalContextWitness, FULL_SPONGE_QUEUE_STATE_WIDTH, QUEUE_STATE_WIDTH, +}; +use circuit_definitions::aux_definitions::witness_oracle::VmWitnessOracle; +use circuit_definitions::boojum::field::goldilocks::GoldilocksField; +use circuit_definitions::boojum::field::Field; +use circuit_definitions::boojum::field::U64Representable; +use circuit_definitions::boojum::gadgets::queue::{ + QueueState, QueueStateWitness, QueueTailStateWitness, +}; +use circuit_definitions::boojum::gadgets::traits::allocatable::CSAllocatable; +use circuit_definitions::boojum::implementations::poseidon2::Poseidon2Goldilocks; +use circuit_definitions::circuit_definitions::base_layer::{VMMainCircuit, ZkSyncBaseLayerCircuit}; +use circuit_definitions::encodings::callstack_entry::{ + CallstackSimulatorState, ExtendedCallstackEntry, +}; +use circuit_definitions::encodings::decommittment_request::DecommittmentQueueState; +use circuit_definitions::encodings::memory_query::MemoryQueueState; +use circuit_definitions::encodings::recursion_request::{ + RecursionQueueSimulator, RecursionRequest, +}; +use circuit_definitions::zk_evm::aux_structures::{DecommittmentQuery, LogQuery, PubdataCost}; +use circuit_definitions::zk_evm::vm_state::CallStackEntry; +use circuit_definitions::zkevm_circuits::fsm_input_output::ClosedFormInputCompactFormWitness; +use circuit_definitions::zkevm_circuits::main_vm::witness_oracle::WitnessOracle; +use circuit_definitions::zkevm_circuits::scheduler::aux::BaseLayerCircuitType; +use circuit_sequencer_api::toolset::GeometryConfig; +use crossbeam::atomic::AtomicCell; +use derivative::Derivative; + +type Cycle = u32; + +pub(crate) struct CallstackSimulationResult { + pub entry_callstack_states_accumulator: + CircuitsEntryAccumulatorSparse<(Cycle, [F; FULL_SPONGE_QUEUE_STATE_WIDTH])>, + pub callstack_witnesses: PerCircuitAccumulatorSparse<( + Cycle, + (ExtendedCallstackEntry, CallstackSimulatorState), + )>, + pub entry_frames_storage_log_detailed_states: + CircuitsEntryAccumulatorSparse<(Cycle, FrameLogQueueDetailedState)>, +} + +#[derive(Derivative)] +#[derivative(Clone(bound = ""), Debug)] +pub struct VmInCircuitAuxilaryParameters { + pub callstack_state: ([F; FULL_SPONGE_QUEUE_STATE_WIDTH], CallStackEntry), + pub decommittment_queue_state: QueueStateWitness, + pub memory_queue_state: QueueStateWitness, + pub storage_log_queue_state: QueueStateWitness, + pub current_frame_rollback_queue_tail: [F; QUEUE_STATE_WIDTH], + pub current_frame_rollback_queue_head: [F; QUEUE_STATE_WIDTH], + pub current_frame_rollback_queue_segment_length: u32, +} + +impl std::default::Default for VmInCircuitAuxilaryParameters { + fn default() -> Self { + Self { + callstack_state: ( + [F::ZERO; FULL_SPONGE_QUEUE_STATE_WIDTH], + CallStackEntry::empty_context(), + ), + decommittment_queue_state: QueueState::placeholder_witness(), + memory_queue_state: QueueState::placeholder_witness(), + storage_log_queue_state: QueueState::placeholder_witness(), + current_frame_rollback_queue_tail: [F::ZERO; QUEUE_STATE_WIDTH], + current_frame_rollback_queue_head: [F::ZERO; QUEUE_STATE_WIDTH], + current_frame_rollback_queue_segment_length: 0, + } + } +} + +#[derive(Derivative)] +#[derivative(Debug, Clone)] +pub struct VmInstanceWitness> { + // we need everything to start a circuit from this point of time + + // initial state - just copy the local state in full + pub initial_state: VmLocalState, + pub witness_oracle: O, + pub auxilary_initial_parameters: VmInCircuitAuxilaryParameters, + pub cycles_range: std::ops::Range, + + // final state for test purposes + pub final_state: VmLocalState, + pub auxilary_final_parameters: VmInCircuitAuxilaryParameters, +} + +struct MainVmSimulationInput { + memory_queue_states_for_entry: + QueueStateWitness, + decommittment_queue_states_for_entry: + QueueStateWitness, + callstack_state_for_entry: [GoldilocksField; FULL_SPONGE_QUEUE_STATE_WIDTH], + frame_log_queue_detailed_state_for_entry: FrameLogQueueDetailedState, + storage_queries_witnesses: Vec<(Cycle, LogQuery)>, + cold_warm_refund_logs: Vec<(Cycle, LogQuery, u32)>, + pubdata_cost_logs: Vec<(Cycle, LogQuery, PubdataCost)>, + decommittment_requests_witness: Vec<(Cycle, DecommittmentQuery)>, + rollback_queue_initial_tails_for_new_frames: Vec<(Cycle, [GoldilocksField; QUEUE_STATE_WIDTH])>, + callstack_values_witnesses: Vec<( + Cycle, + ( + ExtendedCallstackEntry, + CallstackSimulatorState, + ), + )>, + rollback_queue_head_segments: Vec<(Cycle, [GoldilocksField; QUEUE_STATE_WIDTH])>, + callstack_new_frames_witnesses: Vec<(Cycle, CallStackEntry)>, + memory_read_witnesses: Vec<(Cycle, MemoryQuery)>, + memory_write_witnesses: Vec<(Cycle, MemoryQuery)>, +} + +/// Repack the input data into one structure for each of the MainVM circuits +fn repack_input_for_main_vm( + geometry: &GeometryConfig, + vm_snapshots: &Vec, + memory_artifacts_for_main_vm: MemoryArtifacts, + decommitment_artifacts_for_main_vm: DecommitmentArtifactsForMainVM, + callstack_simulation_result: CallstackSimulationResult, + storage_queries: PerCircuitAccumulatorSparse<(Cycle, LogQuery)>, + cold_warm_refunds_logs: PerCircuitAccumulatorSparse<(Cycle, LogQuery, u32)>, + pubdata_cost_logs: PerCircuitAccumulatorSparse<(Cycle, LogQuery, PubdataCost)>, + log_rollback_tails_for_frames: Vec<(Cycle, [GoldilocksField; QUEUE_STATE_WIDTH])>, + log_rollback_queue_heads: PerCircuitAccumulatorSparse<( + Cycle, + [GoldilocksField; QUEUE_STATE_WIDTH], + )>, + flat_new_frames_history: Vec<(Cycle, CallStackEntry)>, +) -> Vec { + tracing::debug!("Repacking data for MainVM"); + + let MemoryArtifacts { + memory_queue_entry_states, + memory_queries, + } = memory_artifacts_for_main_vm; + + let DecommitmentArtifactsForMainVM { + decommittment_queue_entry_states, + prepared_decommittment_queries, + } = decommitment_artifacts_for_main_vm; + + let CallstackSimulationResult { + entry_callstack_states_accumulator, + callstack_witnesses, + entry_frames_storage_log_detailed_states, + } = callstack_simulation_result; + + let amount_of_circuits = vm_snapshots.windows(2).enumerate().len(); + let mut main_vm_inputs = Vec::with_capacity(amount_of_circuits); + + // split the oracle witness + let memory_write_witnesses = PerCircuitAccumulatorSparse::from_iter( + geometry.cycles_per_vm_snapshot as usize, + memory_queries + .iter() + .filter(|(_, query)| query.rw_flag) + .copied(), + ); + + let memory_read_witnesses = PerCircuitAccumulatorSparse::from_iter( + geometry.cycles_per_vm_snapshot as usize, + memory_queries + .iter() + .filter(|(_, query)| !query.rw_flag) + .copied(), + ); + drop(memory_queries); + + // prepare some inputs for MainVM circuits + + let last_memory_queue_state = memory_queue_entry_states.last().1.clone(); + let mut memory_queue_entry_states_it = memory_queue_entry_states + .into_circuits(amount_of_circuits) + .into_iter(); + + let last_decommittment_queue_state = decommittment_queue_entry_states.last().1.clone(); + let mut decommittment_queue_entry_states = decommittment_queue_entry_states + .into_circuits(amount_of_circuits) + .into_iter(); + + let last_storage_log_state = entry_frames_storage_log_detailed_states.last().1; + let mut storage_log_states_for_entry_it = entry_frames_storage_log_detailed_states + .into_circuits(amount_of_circuits) + .into_iter(); + + let last_callstack_state_for_entry = [GoldilocksField::ZERO; FULL_SPONGE_QUEUE_STATE_WIDTH]; // always an empty one + let mut callstack_sponge_entry_states_it = entry_callstack_states_accumulator + .into_circuits(amount_of_circuits) + .into_iter(); + + let mut memory_write_witnesses_it = memory_write_witnesses + .into_circuits(amount_of_circuits) + .into_iter(); + let mut memory_read_witnesses_it = memory_read_witnesses + .into_circuits(amount_of_circuits) + .into_iter(); + let mut storage_queries_it = storage_queries + .into_circuits(amount_of_circuits) + .into_iter(); + let mut cold_warm_refunds_logs_it = cold_warm_refunds_logs + .into_circuits(amount_of_circuits) + .into_iter(); + let mut pubdata_cost_logs_it = pubdata_cost_logs + .into_circuits(amount_of_circuits) + .into_iter(); + let mut flat_new_frames_history_it = PerCircuitAccumulatorSparse::from_iter( + geometry.cycles_per_vm_snapshot as usize, + flat_new_frames_history, + ) + .into_circuits(amount_of_circuits) + .into_iter(); + let mut rollback_queue_tails_for_frames_it = PerCircuitAccumulatorSparse::from_iter( + geometry.cycles_per_vm_snapshot as usize, + log_rollback_tails_for_frames, + ) + .into_circuits(amount_of_circuits) + .into_iter(); + let mut rollback_queue_head_segments_it = log_rollback_queue_heads + .into_circuits(amount_of_circuits) + .into_iter(); + let mut callstack_values_witnesses_it = callstack_witnesses + .into_circuits(amount_of_circuits) + .into_iter(); + let mut prepared_decommittment_queries_it = prepared_decommittment_queries + .into_circuits(amount_of_circuits) + .into_iter(); + + for (circuit_idx, _pair) in vm_snapshots.windows(2).enumerate() { + if amount_of_circuits / 100 != 0 && circuit_idx % (amount_of_circuits / 100) == 0 { + tracing::debug!("{} / {}", circuit_idx, amount_of_circuits); + } + + let memory_queue_states_for_entry = memory_queue_entry_states_it.next().unwrap().1; + let decommittment_queue_states_for_entry = + decommittment_queue_entry_states.next().unwrap().1; + let frame_log_queue_detailed_state_for_entry = + storage_log_states_for_entry_it.next().unwrap().1; + let callstack_state_for_entry = callstack_sponge_entry_states_it.next().unwrap().1; + + let memory_write_witnesses = memory_write_witnesses_it.next().unwrap(); + let memory_read_witnesses = memory_read_witnesses_it.next().unwrap(); + let storage_queries_witnesses = storage_queries_it.next().unwrap(); + let cold_warm_refund_logs = cold_warm_refunds_logs_it.next().unwrap(); + let pubdata_cost_logs = pubdata_cost_logs_it.next().unwrap(); + let decommittment_requests_witness = prepared_decommittment_queries_it.next().unwrap(); + let rollback_queue_initial_tails_for_new_frames = + rollback_queue_tails_for_frames_it.next().unwrap(); + let callstack_values_witnesses = callstack_values_witnesses_it.next().unwrap(); + let rollback_queue_head_segments = rollback_queue_head_segments_it.next().unwrap(); + let callstack_new_frames_witnesses = flat_new_frames_history_it.next().unwrap(); + + let main_vm_input = MainVmSimulationInput { + decommittment_queue_states_for_entry, + memory_queue_states_for_entry, + frame_log_queue_detailed_state_for_entry, + callstack_state_for_entry, + memory_write_witnesses, + memory_read_witnesses, + storage_queries_witnesses, + cold_warm_refund_logs, + pubdata_cost_logs, + decommittment_requests_witness, + rollback_queue_initial_tails_for_new_frames, + callstack_values_witnesses, + rollback_queue_head_segments, + callstack_new_frames_witnesses, + }; + + main_vm_inputs.push(main_vm_input); + } + + // special pass for last one + { + let decommittment_queue_states_for_entry = last_decommittment_queue_state; + let memory_queue_states_for_entry = last_memory_queue_state; + let frame_log_queue_detailed_state_for_entry = last_storage_log_state; + let callstack_state_for_entry = last_callstack_state_for_entry; + + let main_vm_input = MainVmSimulationInput { + decommittment_queue_states_for_entry, + memory_queue_states_for_entry, + frame_log_queue_detailed_state_for_entry, + callstack_state_for_entry, + memory_write_witnesses: vec![], + memory_read_witnesses: vec![], + storage_queries_witnesses: vec![], + cold_warm_refund_logs: vec![], + pubdata_cost_logs: vec![], + decommittment_requests_witness: vec![], + rollback_queue_initial_tails_for_new_frames: vec![], + callstack_values_witnesses: vec![], + rollback_queue_head_segments: vec![], + callstack_new_frames_witnesses: vec![], + }; + + main_vm_inputs.push(main_vm_input); + } + + main_vm_inputs +} + +use crate::witness::postprocessing::observable_witness::VmObservableWitness; +use crate::zkevm_circuits::fsm_input_output::circuit_inputs::main_vm::VmCircuitWitness; + +use super::oracle::WitnessGenerationArtifact; +use super::vm_instance_witness_to_circuit_formal_input; + +pub(crate) fn process_main_vm( + geometry: &GeometryConfig, + in_circuit_global_context: GlobalContextWitness, + memory_artifacts_for_main_vm: MemoryArtifacts, + decommitment_artifacts_for_main_vm: DecommitmentArtifactsForMainVM, + storage_queries: PerCircuitAccumulatorSparse<(Cycle, LogQuery)>, + cold_warm_refunds_logs: PerCircuitAccumulatorSparse<(Cycle, LogQuery, u32)>, + pubdata_cost_logs: PerCircuitAccumulatorSparse<(Cycle, LogQuery, PubdataCost)>, + log_rollback_tails_for_frames: Vec<(Cycle, [GoldilocksField; QUEUE_STATE_WIDTH])>, + log_rollback_queue_heads: PerCircuitAccumulatorSparse<( + Cycle, + [GoldilocksField; QUEUE_STATE_WIDTH], + )>, + callstack_simulation_result: CallstackSimulationResult, + flat_new_frames_history: Vec<(Cycle, CallStackEntry)>, + mut vm_snapshots: Vec, + round_function: Poseidon2Goldilocks, + artifacts_callback: &mut CB, +) -> ( + FirstAndLastCircuitWitness>, + Vec>, +) { + let mut main_vm_circuits = FirstAndLastCircuitWitness::default(); + let mut main_vm_circuits_compact_forms_witnesses = vec![]; + let mut queue_simulator = RecursionQueueSimulator::empty(); + let mut observable_input = None; + let mut process_vm_witness = |vm_instance, is_last| { + let is_first = observable_input.is_none(); + let mut circuit_input = vm_instance_witness_to_circuit_formal_input( + vm_instance, + is_first, + is_last, + in_circuit_global_context.clone(), + ); + + if observable_input.is_none() { + assert!(is_first); + observable_input = Some(circuit_input.closed_form_input.observable_input.clone()); + } else { + circuit_input.closed_form_input.observable_input = + observable_input.as_ref().unwrap().clone(); + } + + let (proof_system_input, compact_form_witness) = + simulate_public_input_value_from_encodable_witness( + circuit_input.closed_form_input.clone(), + &round_function, + ); + + let instance = VMMainCircuit { + witness: AtomicCell::new(Some(circuit_input)), + config: Arc::new(geometry.cycles_per_vm_snapshot as usize), + round_function: Arc::new(round_function), + expected_public_input: Some(proof_system_input), + }; + + if is_first { + let mut wit = instance.clone_witness().unwrap(); + let wit = wit.closed_form_input(); + main_vm_circuits.first = Some(VmObservableWitness { + observable_input: wit.observable_input.clone(), + observable_output: wit.observable_output.clone(), + }); + } + if is_last { + let mut wit = instance.clone_witness().unwrap(); + let wit = wit.closed_form_input(); + main_vm_circuits.last = Some(VmObservableWitness { + observable_input: wit.observable_input.clone(), + observable_output: wit.observable_output.clone(), + }); + } + + let instance = ZkSyncBaseLayerCircuit::MainVM(instance); + + let recursive_request = RecursionRequest { + circuit_type: GoldilocksField::from_u64_unchecked( + instance.numeric_circuit_type() as u64 + ), + public_input: proof_system_input, + }; + queue_simulator.push(recursive_request, &round_function); + + artifacts_callback(WitnessGenerationArtifact::BaseLayerCircuit(instance)); + main_vm_circuits_compact_forms_witnesses.push(compact_form_witness); + }; + + let mut previous_instance_witness: Option< + VmInstanceWitness>, + > = None; + + let main_vm_inputs = repack_input_for_main_vm( + geometry, + &vm_snapshots, + memory_artifacts_for_main_vm, + decommitment_artifacts_for_main_vm, + callstack_simulation_result, + storage_queries, + cold_warm_refunds_logs, + pubdata_cost_logs, + log_rollback_tails_for_frames, + log_rollback_queue_heads, + flat_new_frames_history, + ); + + // duplicate last snapshot to process last circuit + vm_snapshots.push(vm_snapshots.last().unwrap().clone()); + let circuits_len = vm_snapshots.windows(2).len(); + + let amount_of_circuits = vm_snapshots.windows(2).enumerate().len(); + + tracing::debug!("Processing MainVM circuits"); + + // parallelizable + for ((circuit_idx, pair), main_vm_input) in + vm_snapshots.windows(2).enumerate().zip(main_vm_inputs) + { + if amount_of_circuits / 100 != 0 && circuit_idx % (amount_of_circuits / 100) == 0 { + tracing::debug!("{} / {}", circuit_idx, amount_of_circuits); + } + + let is_last = circuit_idx == circuits_len - 1; + + let initial_state = &pair[0]; + let final_state = &pair[1]; + + let MainVmSimulationInput { + memory_queue_states_for_entry: memory_queue_state, + decommittment_queue_states_for_entry: decommittment_queue_state, + callstack_state_for_entry, + frame_log_queue_detailed_state_for_entry: frame_log_queue_detailed_state, + .. + } = main_vm_input; + + let storage_log_queue_state = QueueStateWitness { + head: [GoldilocksField::ZERO; QUEUE_STATE_WIDTH], + tail: QueueTailStateWitness { + tail: frame_log_queue_detailed_state.forward_tail, + length: frame_log_queue_detailed_state.forward_length, + }, + }; + + let auxilary_initial_parameters = VmInCircuitAuxilaryParameters { + callstack_state: ( + callstack_state_for_entry, + *initial_state.local_state.callstack.get_current_stack(), + ), + decommittment_queue_state, + memory_queue_state, + storage_log_queue_state, + current_frame_rollback_queue_tail: frame_log_queue_detailed_state.rollback_tail, + current_frame_rollback_queue_head: frame_log_queue_detailed_state.rollback_head, + current_frame_rollback_queue_segment_length: frame_log_queue_detailed_state + .rollback_length, + }; + + if let Some(mut prev) = previous_instance_witness { + prev.auxilary_final_parameters = auxilary_initial_parameters.clone(); + process_vm_witness(prev, is_last); + } + + if !is_last { + // we need to get chunks of + // - memory read witnesses + // - storage read witnesses + // - decommittment witnesses + // - callstack witnesses + // - rollback queue witnesses + + let MainVmSimulationInput { + storage_queries_witnesses, + cold_warm_refund_logs, + pubdata_cost_logs, + // here we need all answers from the oracle, not just ones that will be executed + decommittment_requests_witness, + rollback_queue_initial_tails_for_new_frames, + callstack_values_witnesses, + rollback_queue_head_segments, + callstack_new_frames_witnesses, + memory_read_witnesses, + memory_write_witnesses, + .. + } = main_vm_input; + + // construct an oracle + let witness_oracle = VmWitnessOracle { + initial_cycle: initial_state.at_cycle, + final_cycle_inclusive: final_state.at_cycle - 1, + memory_read_witness: memory_read_witnesses.into(), + memory_write_witness: Some(memory_write_witnesses.into()), + rollback_queue_head_segments: rollback_queue_head_segments.into(), + decommittment_requests_witness: decommittment_requests_witness.into(), + rollback_queue_initial_tails_for_new_frames: + rollback_queue_initial_tails_for_new_frames.into(), + storage_queries: storage_queries_witnesses.into(), + storage_access_cold_warm_refunds: cold_warm_refund_logs.into(), + storage_pubdata_queries: pubdata_cost_logs.into(), + callstack_values_witnesses: callstack_values_witnesses.into(), + callstack_new_frames_witnesses: callstack_new_frames_witnesses.into(), + }; + + let instance_witness = VmInstanceWitness { + initial_state: initial_state.local_state.clone(), + witness_oracle, + auxilary_initial_parameters, + cycles_range: initial_state.at_cycle..final_state.at_cycle, + final_state: final_state.local_state.clone(), + auxilary_final_parameters: VmInCircuitAuxilaryParameters::default(), // we will use next circuit's initial as final here! + }; + previous_instance_witness = Some(instance_witness); + } else { + previous_instance_witness = None; + } + } + + artifacts_callback(WitnessGenerationArtifact::RecursionQueue(( + BaseLayerCircuitType::VM as u64, + queue_simulator, + main_vm_circuits_compact_forms_witnesses.clone(), + ))); + + (main_vm_circuits, main_vm_circuits_compact_forms_witnesses) +} diff --git a/crates/zkevm_test_harness/src/witness/individual_circuits/memory_related/decommit_code.rs b/crates/zkevm_test_harness/src/witness/individual_circuits/memory_related/decommit_code.rs new file mode 100644 index 0000000..49a3d1a --- /dev/null +++ b/crates/zkevm_test_harness/src/witness/individual_circuits/memory_related/decommit_code.rs @@ -0,0 +1,439 @@ +use super::*; +use crate::boojum::gadgets::queue::full_state_queue::FullStateCircuitQueueRawWitness; +use crate::witness::aux_data_structs::one_per_circuit_accumulator::LastPerCircuitAccumulator; +use crate::witness::aux_data_structs::MemoryQueuePerCircuitSimulator; +use crate::zk_evm::aux_structures::MemoryIndex; +use crate::zk_evm::aux_structures::MemoryQuery; +use crate::zk_evm::ethereum_types::U256; +use crate::zkevm_circuits::base_structures::decommit_query::DecommitQueryWitness; +use crate::zkevm_circuits::base_structures::decommit_query::DECOMMIT_QUERY_PACKED_WIDTH; +use crate::zkevm_circuits::code_unpacker_sha256::input::*; +use circuit_definitions::encodings::decommittment_request::normalized_preimage_as_u256; +use circuit_definitions::encodings::decommittment_request::DecommittmentQueueSimulator; +use circuit_definitions::encodings::decommittment_request::DecommittmentQueueState; +use circuit_definitions::encodings::memory_query::MemoryQueueSimulator; +use circuit_definitions::encodings::memory_query::MemoryQueueState; +use circuit_definitions::zk_evm::aux_structures::DecommittmentQuery; +use std::collections::VecDeque; + +pub(crate) fn decommitter_memory_queries( + deduplicated_decommit_requests_with_data: &Vec<(DecommittmentQuery, Vec)>, +) -> Vec { + let mut result = vec![]; + for (query, writes) in deduplicated_decommit_requests_with_data.iter() { + assert!(query.is_fresh); + + // now feed the queries into it + let as_queries_it = writes.iter().enumerate().map(|(idx, el)| MemoryQuery { + timestamp: query.timestamp, + location: zk_evm::aux_structures::MemoryLocation { + memory_type: zk_evm::abstractions::MemoryType::Code, + page: query.memory_page, + index: MemoryIndex(idx as u32), + }, + rw_flag: true, + value: *el, + value_is_pointer: false, + }); + + // and plain test memory queues + result.extend(as_queries_it); + } + + result +} + +pub(crate) struct DecommiterCircuitProcessingInputs { + pub deduplicated_decommittment_queue_simulator: DecommittmentQueueSimulator, + pub deduplicated_decommittment_queue_states: Vec>, + pub deduplicated_decommit_requests_with_data: Vec<(DecommittmentQuery, Vec)>, +} + +pub(crate) fn compute_decommitter_circuit_snapshots< + F: SmallField, + R: BuildableCircuitRoundFunction + AlgebraicRoundFunction, +>( + amount_of_memory_queries: usize, + decommitter_memory_queries: Vec, + decommitter_simulator_snapshots: Vec>, + decommitter_memory_states: Vec>, + final_explicit_memory_queue_state: MemoryQueueState, + decommiter_circuit_inputs: DecommiterCircuitProcessingInputs, + round_function: &R, + decommiter_circuit_capacity: usize, +) -> (Vec>, usize) { + assert_eq!( + decommitter_memory_queries.len(), + decommitter_memory_states.len() + ); + + let memory_simulator_before = &decommitter_simulator_snapshots[0]; + assert_eq!( + amount_of_memory_queries, + memory_simulator_before.num_items as usize + ); + let start_idx_for_memory_accumulator = 0; + + let initial_memory_queue_state = &memory_simulator_before.take_sponge_like_queue_state(); + + let DecommiterCircuitProcessingInputs { + deduplicated_decommit_requests_with_data, + deduplicated_decommittment_queue_states, + deduplicated_decommittment_queue_simulator, + } = decommiter_circuit_inputs; + + // now we should start chunking the requests into separate decommittment circuits by running a micro-simulator + + assert!( + deduplicated_decommit_requests_with_data.len() > 0, + "we must have some decommitment requests" + ); + + // our simulator is simple: it will try to take an element from the queue, run some number of rounds, and compare the results + + let mut results: Vec> = vec![]; + + #[derive(Clone, Copy, Debug, PartialEq, Eq)] + enum DecommitterState { + BeginNew, + DecommmitMore, + Done, + } + + let final_deduplicated_queue_state = transform_sponge_like_queue_state( + deduplicated_decommittment_queue_states + .last() + .unwrap() + .clone(), + ); + assert_eq!( + deduplicated_decommit_requests_with_data.len(), + deduplicated_decommittment_queue_states.len() + ); + + let mut current_decommittment_requests_queue_simulator = + deduplicated_decommittment_queue_simulator.clone(); + + assert_eq!( + deduplicated_decommit_requests_with_data.len(), + deduplicated_decommittment_queue_states.len(), + ); + + assert_eq!( + deduplicated_decommit_requests_with_data.len(), + deduplicated_decommittment_queue_simulator.witness.len(), + ); + + drop(deduplicated_decommittment_queue_states); + + let mut it = deduplicated_decommit_requests_with_data + .into_iter() + .zip(deduplicated_decommittment_queue_simulator.witness) + .peekable(); + + let mut fsm_state = DecommitterState::BeginNew; + let mut current_memory_data_it = vec![].into_iter(); + let mut start = true; + let mut memory_queue_state_offset = 0; + + use crate::zk_evm::zk_evm_abstractions::precompiles::keccak256::Digest; + use crate::zk_evm::zk_evm_abstractions::precompiles::sha256::transmute_state; + use crate::zk_evm::zk_evm_abstractions::precompiles::sha256::Sha256; + + let mut internal_state = Sha256::default(); + let mut fsm_internals = CodeDecommittmentFSM::::placeholder_witness(); + + use crate::boojum::gadgets::queue::QueueState; + let placeholder_witness = QueueState::::placeholder_witness(); + + 'outer: loop { + let mut current_circuit_witness = CodeDecommitterCircuitInstanceWitness { + closed_form_input: ClosedFormInputWitness { + start_flag: start, + completion_flag: false, + observable_input: CodeDecommitterInputData::placeholder_witness(), + observable_output: CodeDecommitterOutputData::placeholder_witness(), + hidden_fsm_input: CodeDecommitterFSMInputOutput::placeholder_witness(), + hidden_fsm_output: CodeDecommitterFSMInputOutput::placeholder_witness(), + }, + sorted_requests_queue_witness: FullStateCircuitQueueRawWitness::< + F, + zkevm_circuits::base_structures::decommit_query::DecommitQuery, + FULL_SPONGE_QUEUE_STATE_WIDTH, + DECOMMIT_QUERY_PACKED_WIDTH, + > { + elements: VecDeque::new(), + }, + code_words: vec![], + }; + + let wintess_state = if start_idx_for_memory_accumulator + memory_queue_state_offset == 0 { + &final_explicit_memory_queue_state + } else { + decommitter_memory_states + .get(start_idx_for_memory_accumulator + memory_queue_state_offset - 1) + .unwrap() + }; + + current_circuit_witness + .closed_form_input + .hidden_fsm_input + .memory_queue_state = transform_sponge_like_queue_state(wintess_state.clone()); + + let initial_decommittment_queue_state = results + .last() + .map(|el| { + el.closed_form_input + .hidden_fsm_output + .decommittment_requests_queue_state + .clone() + }) + .unwrap_or(placeholder_witness.clone()); + + let initial_internal_fsm_state = results + .last() + .map(|el| el.closed_form_input.hidden_fsm_output.internal_fsm.clone()) + .unwrap_or(CodeDecommittmentFSM::placeholder_witness()); + + current_circuit_witness + .closed_form_input + .hidden_fsm_input + .internal_fsm = initial_internal_fsm_state; + current_circuit_witness + .closed_form_input + .hidden_fsm_input + .decommittment_requests_queue_state = initial_decommittment_queue_state; + + if start { + // set passthrough input + start = false; + current_circuit_witness + .closed_form_input + .observable_input + .memory_queue_initial_state = initial_memory_queue_state.clone(); + current_circuit_witness + .closed_form_input + .observable_input + .sorted_requests_queue_initial_state = final_deduplicated_queue_state.clone(); + } else { + if DecommitterState::BeginNew != fsm_state { + current_circuit_witness.code_words.push(vec![]); + } + } + + for _cycle_idx in 0..decommiter_circuit_capacity { + // we will kind of fall through, so "if" instead of "match" + if &DecommitterState::BeginNew == &fsm_state { + internal_state = Sha256::default(); + + let ((query, memory_data), wit) = it.next().unwrap(); + let (el, _intermediate_info) = current_decommittment_requests_queue_simulator + .pop_and_output_intermediate_data(round_function); + debug_assert_eq!(query, el); + + assert!(memory_data.len() > 0); + current_memory_data_it = memory_data.into_iter(); + + // fill the witness + let DecommittmentQuery { + header, + normalized_preimage, + timestamp, + memory_page, + decommitted_length: _, + is_fresh, + } = wit.2; + + let num_words = u16::from_be_bytes([header.0[2], header.0[3]]); + assert!(num_words & 1 == 1); // should be odd + + let hash_as_u256 = normalized_preimage_as_u256(&normalized_preimage); + + let as_circuit_data = DecommitQueryWitness { + code_hash: hash_as_u256, + page: memory_page.0, + is_first: is_fresh, + timestamp: timestamp.0, + }; + + let wit = (as_circuit_data, wit.1); + + current_circuit_witness + .sorted_requests_queue_witness + .elements + .push_back(wit); + + fsm_internals.state_get_from_queue = false; + fsm_internals.state_decommit = true; + fsm_internals.sha256_inner_state = boojum::gadgets::sha256::INITIAL_STATE; + fsm_internals.current_index = 0; + fsm_internals.current_page = memory_page.0; + fsm_internals.timestamp = timestamp.0; + fsm_internals.hash_to_compare_against = hash_as_u256; + fsm_internals.num_byte32_words_processed = 0u16; + + fsm_state = DecommitterState::DecommmitMore; + current_circuit_witness.code_words.push(vec![]); + } + + // do the actual round + match fsm_state { + DecommitterState::DecommmitMore => { + let mut block = [0u8; 64]; + let word0 = current_memory_data_it.next().unwrap(); + word0.to_big_endian(&mut block[0..32]); + + current_circuit_witness + .code_words + .last_mut() + .unwrap() + .push(word0); + memory_queue_state_offset += 1; + fsm_internals.current_index += 1; + fsm_internals.num_byte32_words_processed += 1; + + let mut finished = false; + if let Some(word1) = current_memory_data_it.next() { + current_circuit_witness + .code_words + .last_mut() + .unwrap() + .push(word1); + word1.to_big_endian(&mut block[32..64]); + + memory_queue_state_offset += 1; + fsm_internals.current_index += 1; + fsm_internals.num_byte32_words_processed += 1; + } else { + // we decommitted everythin + // pad and do not increment index + block[32] = 0x80; + let num_bits = (fsm_internals.num_byte32_words_processed as u32) * 32 * 8; + let length_in_bits_be = num_bits.to_be_bytes(); + block[60..64].copy_from_slice(&length_in_bits_be); + finished = true; + } + + // absorb + internal_state.update(&block); + + if finished { + let mut raw_state = transmute_state(internal_state.clone()); + raw_state[0] = 0; + let mut buffer = [0u8; 32]; + for (dst, src) in buffer.array_chunks_mut::<4>().zip(raw_state.iter()) { + *dst = src.to_be_bytes(); + } + + let word = U256::from_big_endian(&buffer); + + assert!( + fsm_internals.hash_to_compare_against == word, + "Hash in FSM is 0x{:064x}, while hash in simulator is 0x{:064x}", + fsm_internals.hash_to_compare_against, + word, + ); + + if it.peek().is_none() { + fsm_state = DecommitterState::Done; + fsm_internals.state_get_from_queue = false; + fsm_internals.state_decommit = false; + fsm_internals.finished = true; + } else { + fsm_state = DecommitterState::BeginNew; + fsm_internals.state_get_from_queue = true; + fsm_internals.state_decommit = false; + } + } + } + a @ _ => unreachable!("we should never hit the state {:?}", a), + } + + if fsm_state == DecommitterState::Done { + break; + } + + // if we are done than push some data into witness + } + + // copy the final state + + let raw_state = transmute_state(internal_state.clone()); + + for (dst, src) in fsm_internals + .sha256_inner_state + .iter_mut() + .zip(raw_state.into_iter()) + { + *dst = src; + } + + // proceed with final bits + current_circuit_witness + .closed_form_input + .hidden_fsm_output + .decommittment_requests_queue_state = take_sponge_like_queue_state_from_simulator( + ¤t_decommittment_requests_queue_simulator, + ); + current_circuit_witness + .closed_form_input + .hidden_fsm_output + .decommittment_requests_queue_state = take_sponge_like_queue_state_from_simulator( + ¤t_decommittment_requests_queue_simulator, + ); + + let wintess_state = if start_idx_for_memory_accumulator + memory_queue_state_offset == 0 { + &final_explicit_memory_queue_state + } else { + decommitter_memory_states + .get(start_idx_for_memory_accumulator + memory_queue_state_offset - 1) + .unwrap() + }; + + current_circuit_witness + .closed_form_input + .hidden_fsm_output + .memory_queue_state = transform_sponge_like_queue_state(wintess_state.clone()); + + current_circuit_witness + .closed_form_input + .hidden_fsm_output + .internal_fsm = fsm_internals.clone(); + + results.push(current_circuit_witness); + + if fsm_state == DecommitterState::Done { + // mark as done and set passthrough output + results + .last_mut() + .unwrap() + .closed_form_input + .completion_flag = true; + let final_memory_state = results + .last() + .unwrap() + .closed_form_input + .hidden_fsm_output + .memory_queue_state + .clone(); + results + .last_mut() + .unwrap() + .closed_form_input + .observable_output + .memory_queue_final_state = final_memory_state; + break 'outer; + } + } + + let memory_simulator_after = &decommitter_simulator_snapshots[1]; + + let amount_of_memory_queries_after = + amount_of_memory_queries + decommitter_memory_queries.len(); + assert_eq!( + amount_of_memory_queries_after, + memory_simulator_after.num_items as usize + ); + + (results, amount_of_memory_queries_after) +} diff --git a/crates/zkevm_test_harness/src/witness/individual_circuits/memory_related/ecrecover.rs b/crates/zkevm_test_harness/src/witness/individual_circuits/memory_related/ecrecover.rs new file mode 100644 index 0000000..bb31b44 --- /dev/null +++ b/crates/zkevm_test_harness/src/witness/individual_circuits/memory_related/ecrecover.rs @@ -0,0 +1,233 @@ +use super::*; +use crate::witness::artifacts::{DemuxedLogQueries, LogQueueStates}; +use crate::witness::aux_data_structs::one_per_circuit_accumulator::LastPerCircuitAccumulator; +use crate::witness::aux_data_structs::MemoryQueuePerCircuitSimulator; +use crate::zk_evm::aux_structures::LogQuery as LogQuery_; +use crate::zk_evm::aux_structures::MemoryQuery; +use crate::zk_evm::zk_evm_abstractions::precompiles::ecrecover::ECRecoverRoundWitness; +use crate::zkevm_circuits::base_structures::log_query::*; +use crate::zkevm_circuits::ecrecover::*; +use circuit_definitions::encodings::memory_query::MemoryQueueSimulator; +use circuit_definitions::encodings::memory_query::MemoryQueueState; +use circuit_definitions::encodings::*; + +pub(crate) fn ecrecover_memory_queries( + ecrecover_witnesses: &Vec<(u32, LogQuery_, ECRecoverRoundWitness)>, +) -> Vec { + let amount_of_queries = ecrecover_witnesses + .iter() + .fold(0, |inner, (_, _, witness)| { + inner + witness.reads.len() + witness.writes.len() + }); + + let mut ecrecover_memory_queries = Vec::with_capacity(amount_of_queries); + + for (_cycle, _query, witness) in ecrecover_witnesses.iter() { + let initial_memory_len = ecrecover_memory_queries.len(); + + // we read, then write + ecrecover_memory_queries.extend_from_slice(&witness.reads); + ecrecover_memory_queries.extend_from_slice(&witness.writes); + + assert_eq!(ecrecover_memory_queries.len() - initial_memory_len, 6); + } + ecrecover_memory_queries +} + +// we want to simulate splitting of data into many separate instances of the same circuit. +// So we basically need to reconstruct the FSM state on input/output, and passthrough data. +// In practice the only difficulty is buffer state, everything else is provided by out-of-circuit VM + +pub(crate) fn ecrecover_decompose_into_per_circuit_witness< + F: SmallField, + R: BuildableCircuitRoundFunction + AlgebraicRoundFunction, +>( + amount_of_memory_queries_before: usize, + ecrecover_memory_queries: Vec, + ecrecover_simulator_snapshots: Vec>, + ecrecover_memory_states: Vec>, + ecrecover_witnesses: Vec<(u32, LogQuery_, ECRecoverRoundWitness)>, + ecrecover_queries: Vec, + mut demuxed_ecrecover_queue: LogQueueStates, + num_rounds_per_circuit: usize, + round_function: &R, +) -> (Vec>, usize) { + assert_eq!( + ecrecover_memory_queries.len(), + ecrecover_memory_states.len() + ); + + let memory_simulator_before = &ecrecover_simulator_snapshots[0]; + assert_eq!( + amount_of_memory_queries_before, + memory_simulator_before.num_items as usize + ); + + let mut result = vec![]; + + let precompile_calls = ecrecover_queries; + let simulator_witness: Vec<_> = demuxed_ecrecover_queue.simulator.witness.clone().into(); + let round_function_witness = ecrecover_witnesses; + + // check basic consistency + assert!(precompile_calls.len() == demuxed_ecrecover_queue.states_accumulator.len()); + drop(demuxed_ecrecover_queue.states_accumulator); + assert!(precompile_calls.len() == round_function_witness.len()); + + if precompile_calls.len() == 0 { + return (vec![], amount_of_memory_queries_before); + } + + let mut round_counter = 0; + let num_requests = precompile_calls.len(); + + // convension + let mut log_queue_input_state = + take_queue_state_from_simulator(&demuxed_ecrecover_queue.simulator); + let amount_ecrecover_memory_queries = ecrecover_memory_queries.len(); + let mut memory_queries_it = ecrecover_memory_queries.into_iter(); + + let mut memory_read_witnesses = vec![]; + let mut starting_request_idx = 0; + + let mut memory_queue_input_state = memory_simulator_before.take_sponge_like_queue_state(); + let mut current_memory_queue_state = memory_queue_input_state.clone(); + + let mut memory_queue_states_it = ecrecover_memory_states.iter(); + + for (request_idx, (request, per_request_work)) in precompile_calls + .into_iter() + .zip(round_function_witness.into_iter()) + .enumerate() + { + let _ = demuxed_ecrecover_queue + .simulator + .pop_and_output_intermediate_data(round_function); + + let mut memory_reads_per_request = vec![]; + + let (_cycle, _req, round_witness) = per_request_work; + assert_eq!(request, _req); + + use crate::zk_evm::zk_evm_abstractions::precompiles::precompile_abi_in_log; + let mut precompile_request = precompile_abi_in_log(request); + let is_last_request = request_idx == num_requests - 1; + + let mut amount_of_queries = 0; + // we have 4 reads + for (_query_index, read) in round_witness.reads.into_iter().enumerate() { + let read_query = memory_queries_it.next().unwrap(); + assert!(read == read_query); + assert!(read_query.rw_flag == false); + memory_reads_per_request.push(read_query.value); + + current_memory_queue_state = + transform_sponge_like_queue_state(*memory_queue_states_it.next().unwrap()); + + precompile_request.input_memory_offset += 1; + amount_of_queries += 1; + } + + // and 2 writes + for (_query_index, write) in round_witness.writes.into_iter().enumerate() { + let write_query = memory_queries_it.next().unwrap(); + assert!(write == write_query); + assert!(write_query.rw_flag == true); + + current_memory_queue_state = + transform_sponge_like_queue_state(*memory_queue_states_it.next().unwrap()); + + precompile_request.output_memory_offset += 1; + amount_of_queries += 1; + } + + assert_eq!(amount_of_queries, 6); + round_counter += 1; + + if round_counter == num_rounds_per_circuit || is_last_request { + round_counter = 0; + + let finished = is_last_request; + if finished { + assert!(memory_queries_it.next().is_none()); + } + + let range = starting_request_idx..(request_idx + 1); + let wit: VecDeque<_> = (&simulator_witness[range]) + .iter() + .map(|el| (log_query_into_circuit_log_query_witness(&el.2), el.1)) + .collect(); + + let current_reads = std::mem::take(&mut memory_reads_per_request); + let mut current_witness = std::mem::take(&mut memory_read_witnesses); + current_witness.push(current_reads); + + let mut observable_input_data = PrecompileFunctionInputData::placeholder_witness(); + if result.len() == 0 { + observable_input_data.initial_memory_queue_state = memory_queue_input_state.clone(); + observable_input_data.initial_log_queue_state = log_queue_input_state.clone(); + } + + let mut observable_output_data = PrecompileFunctionOutputData::placeholder_witness(); + if finished { + observable_output_data.final_memory_state = current_memory_queue_state.clone(); + } + + let witness = EcrecoverCircuitInstanceWitness:: { + closed_form_input: EcrecoverCircuitInputOutputWitness:: { + start_flag: result.len() == 0, + completion_flag: finished, + observable_input: observable_input_data, + observable_output: observable_output_data, + hidden_fsm_input: EcrecoverCircuitFSMInputOutputWitness:: { + log_queue_state: log_queue_input_state.clone(), + memory_queue_state: memory_queue_input_state, + }, + hidden_fsm_output: EcrecoverCircuitFSMInputOutputWitness:: { + log_queue_state: take_queue_state_from_simulator( + &demuxed_ecrecover_queue.simulator, + ), + memory_queue_state: current_memory_queue_state.clone(), + }, + }, + requests_queue_witness: CircuitQueueRawWitness::< + F, + LogQuery, + 4, + LOG_QUERY_PACKED_WIDTH, + > { + elements: wit, + }, + memory_reads_witness: current_witness + .into_iter() + .map(|el| el.try_into().expect("length must match")) + .collect(), + }; + + // make non-inclusize + starting_request_idx = request_idx + 1; + + result.push(witness); + + log_queue_input_state = + take_queue_state_from_simulator(&demuxed_ecrecover_queue.simulator); + memory_queue_input_state = current_memory_queue_state.clone(); + } + + if !memory_reads_per_request.is_empty() { + // we may have drained it already if it was the end of the circuit + memory_read_witnesses.push(memory_reads_per_request); + } + } + + let memory_simulator_after = &ecrecover_simulator_snapshots[1]; + let amount_of_memory_queries_after = + amount_of_memory_queries_before + amount_ecrecover_memory_queries; + + assert_eq!( + amount_of_memory_queries_after, + memory_simulator_after.num_items as usize + ); + + (result, amount_of_memory_queries_after) +} diff --git a/crates/zkevm_test_harness/src/witness/individual_circuits/memory_related/keccak256_round_function.rs b/crates/zkevm_test_harness/src/witness/individual_circuits/memory_related/keccak256_round_function.rs new file mode 100644 index 0000000..2b83ad3 --- /dev/null +++ b/crates/zkevm_test_harness/src/witness/individual_circuits/memory_related/keccak256_round_function.rs @@ -0,0 +1,601 @@ +use super::*; +use crate::witness::artifacts::{DemuxedLogQueries, LogQueueStates}; +use crate::witness::aux_data_structs::one_per_circuit_accumulator::LastPerCircuitAccumulator; +use crate::witness::aux_data_structs::MemoryQueuePerCircuitSimulator; +use crate::zk_evm::aux_structures::LogQuery as LogQuery_; +use crate::zk_evm::aux_structures::MemoryQuery; +use crate::zk_evm::zk_evm_abstractions::precompiles::keccak256::Keccak256RoundWitness; +use crate::zkevm_circuits::base_structures::log_query::*; +use crate::zkevm_circuits::keccak256_round_function::{ + input::*, Keccak256PrecompileCallParamsWitness, +}; +use circuit_definitions::encodings::memory_query::MemoryQueueSimulator; +use circuit_definitions::encodings::memory_query::MemoryQueueState; +use circuit_definitions::encodings::*; +use derivative::*; + +pub(crate) fn keccak256_memory_queries( + keccak_round_function_witnesses: &Vec<(u32, LogQuery_, Vec)>, +) -> Vec { + let amount_of_queries = + keccak_round_function_witnesses + .iter() + .fold(0, |mut inner, (_, _, witness)| { + witness.iter().for_each(|el| { + el.reads.iter().for_each(|read| { + if read.is_some() { + inner += 1; + } + }); + + if el.writes.is_some() { + inner += 1; + } + }); + + inner + }); + + let mut keccak_256_memory_queries = Vec::with_capacity(amount_of_queries); + + for (_cycle, _query, witness) in keccak_round_function_witnesses.iter() { + for el in witness.iter() { + let Keccak256RoundWitness { + new_request: _, + reads, + writes, + } = el; + + // we read, then write + reads.iter().for_each(|read| { + if let Some(read) = read { + keccak_256_memory_queries.push(*read); + } + }); + + if let Some(writes) = writes.as_ref() { + keccak_256_memory_queries.extend_from_slice(writes); + } + } + } + + keccak_256_memory_queries.shrink_to_fit(); + + keccak_256_memory_queries +} + +#[derive(Derivative)] +#[derivative(Clone, Copy, Debug, PartialEq, Eq)] +pub enum Keccak256PrecompileState { + GetRequestFromQueue, + RunRoundFunction, + RunPaddingRound, + Finished, +} + +// we want to simulate splitting of data into many separate instances of the same circuit. +// So we basically need to reconstruct the FSM state on input/output, and passthrough data. +// In practice the only difficulty is buffer state, everything else is provided by out-of-circuit VM + +pub(crate) fn keccak256_decompose_into_per_circuit_witness< + F: SmallField, + R: BuildableCircuitRoundFunction + AlgebraicRoundFunction, +>( + amount_of_memory_queries_before: usize, + keccak256_memory_queries: Vec, + keccak256_simulator_snapshots: Vec>, + keccak256_memory_states: Vec>, + keccak_round_function_witnesses: Vec<(u32, LogQuery_, Vec)>, + keccak_precompile_queries: Vec, + mut demuxed_keccak_precompile_queue: LogQueueStates, + num_rounds_per_circuit: usize, + round_function: &R, +) -> (Vec>, usize) { + assert_eq!( + keccak256_memory_queries.len(), + keccak256_memory_states.len() + ); + + let memory_simulator_before = &keccak256_simulator_snapshots[0]; + assert_eq!( + amount_of_memory_queries_before, + memory_simulator_before.num_items as usize + ); + + let mut result = vec![]; + + let keccak_precompile_calls = keccak_precompile_queries; + let round_function_witness = keccak_round_function_witnesses; + + // check basic consistency + assert_eq!( + keccak_precompile_calls.len(), + demuxed_keccak_precompile_queue.states_accumulator.len() + ); + drop(demuxed_keccak_precompile_queue.states_accumulator); + + assert_eq!(keccak_precompile_calls.len(), round_function_witness.len()); + assert_eq!( + demuxed_keccak_precompile_queue.simulator.num_items as usize, + round_function_witness.len() + ); + + if keccak_precompile_calls.len() == 0 { + return (vec![], amount_of_memory_queries_before); + } + + let mut round_counter = 0; + let mut starting_request_idx_for_circuit = 0; + let num_requests = keccak_precompile_calls.len(); + let keccak_requests_queue_witness_copy: Vec<_> = demuxed_keccak_precompile_queue + .simulator + .witness + .iter() + .map(|el| { + let mapped = log_query_into_circuit_log_query_witness::(&el.2); + + (mapped, el.1) + }) + .collect(); + + // convension + let mut log_queue_input_state = + take_queue_state_from_simulator(&demuxed_keccak_precompile_queue.simulator); + + let mut hidden_fsm_input_state = Keccak256RoundFunctionFSM::::placeholder_witness(); + hidden_fsm_input_state.read_precompile_call = true; + + let mut memory_queries_it = keccak256_memory_queries.iter(); + let mut precompile_state = Keccak256PrecompileState::GetRequestFromQueue; + + let mut memory_queue_input_state = memory_simulator_before.take_sponge_like_queue_state(); + let mut current_memory_queue_state = memory_queue_input_state.clone(); + + let mut memory_reads_per_circuit = VecDeque::new(); + + let mut memory_queue_states_it = keccak256_memory_states.iter(); + + for (request_idx, (request, per_request_work)) in keccak_precompile_calls + .into_iter() + .zip(round_function_witness.into_iter()) + .enumerate() + { + // request level. Each request can be broken into few rounds + + let _ = demuxed_keccak_precompile_queue + .simulator + .pop_and_output_intermediate_data(round_function); + + use crate::zk_evm::zk_evm_abstractions::precompiles::keccak256::Keccak256; + let mut internal_state = Keccak256::default(); + + assert_eq!( + precompile_state, + Keccak256PrecompileState::GetRequestFromQueue + ); + + let (_cycle, _req, round_witness) = per_request_work; + assert_eq!(request, _req); + + // those are refreshed every cycle + use crate::zk_evm::zk_evm_abstractions::precompiles::keccak256::KECCAK_PRECOMPILE_BUFFER_SIZE; + use crate::zk_evm::zk_evm_abstractions::precompiles::keccak256::KECCAK_RATE_BYTES; + + let mut input_buffer = zk_evm::zk_evm_abstractions::precompiles::keccak256::ByteBuffer { + bytes: [0u8; KECCAK_PRECOMPILE_BUFFER_SIZE], + filled: 0, + }; + + use crate::zk_evm::zk_evm_abstractions::precompiles::precompile_abi_in_log; + let mut precompile_request = precompile_abi_in_log(request); + let input_byte_offset = &mut precompile_request.input_memory_offset; + let bytes_left = &mut precompile_request.input_memory_length; + + let mut num_rounds = (*bytes_left as usize + (KECCAK_RATE_BYTES - 1)) / KECCAK_RATE_BYTES; + let padding_space = *bytes_left as usize % KECCAK_RATE_BYTES; + let needs_extra_padding_round = padding_space == 0; + if needs_extra_padding_round { + num_rounds += 1; + } + + assert_eq!(num_rounds, round_witness.len()); + + let is_last_request = request_idx == num_requests - 1; + + precompile_state = Keccak256PrecompileState::RunRoundFunction; + if *bytes_left == 0 && num_rounds == 1 { + precompile_state = Keccak256PrecompileState::RunPaddingRound; + } + + for (round_idx, round) in round_witness.into_iter().enumerate() { + // we proceed the request as long as we can + if round_idx == 0 { + assert!(round.new_request.is_some()); + } + + let is_last_round = round_idx == num_rounds - 1; + let paddings_round = needs_extra_padding_round && is_last_round; + + // simulate absorb + for (_query_index, read) in round.reads.into_iter().enumerate() { + let (memory_index, unalignment) = + (*input_byte_offset / 32, *input_byte_offset % 32); + let at_most_meaningful_bytes_in_query = 32 - unalignment; + let meaningful_bytes_in_query = if *bytes_left >= at_most_meaningful_bytes_in_query + { + at_most_meaningful_bytes_in_query + } else { + *bytes_left + }; + let enough_buffer_space = + input_buffer.can_fill_bytes(meaningful_bytes_in_query as usize); + let nothing_to_read = meaningful_bytes_in_query == 0; + let should_read = nothing_to_read == false && enough_buffer_space; + if paddings_round { + assert!(should_read == false); + assert_eq!(precompile_state, Keccak256PrecompileState::RunPaddingRound,) + } + + if should_read { + assert!(read.is_some()); + *input_byte_offset += meaningful_bytes_in_query; + *bytes_left -= meaningful_bytes_in_query; + } else { + assert!(read.is_none()); + continue; + } + let bytes_to_fill = if should_read { + meaningful_bytes_in_query + } else { + 0 + }; + + let read = read.unwrap(); + assert_eq!(read.location.index.0, memory_index); + let data: ethereum_types::U256 = read.value; + let mut bytes32_buffer = [0u8; 32]; + data.to_big_endian(&mut bytes32_buffer[..]); + + let read_query = memory_queries_it.next().unwrap(); + assert_eq!(read, *read_query); + memory_reads_per_circuit.push_back(read_query.value); + + current_memory_queue_state = + transform_sponge_like_queue_state(*memory_queue_states_it.next().unwrap()); + + input_buffer.fill_with_bytes( + &bytes32_buffer, + unalignment as usize, + bytes_to_fill as usize, + ); + } + + let mut input_block = input_buffer.consume::(); + if is_last_round { + if needs_extra_padding_round { + input_block[0] = 0x01; + input_block[KECCAK_RATE_BYTES - 1] = 0x80; + } else { + if padding_space == KECCAK_RATE_BYTES - 1 { + input_block[KECCAK_RATE_BYTES - 1] = 0x81; + } else { + input_block[padding_space] = 0x01; + input_block[KECCAK_RATE_BYTES - 1] = 0x80; + } + } + } + use crate::zk_evm::zk_evm_abstractions::precompiles::keccak256::Digest; + internal_state.update(&input_block); + + // NOTE: we need to set it for NEXT round + let next_round_is_padding = if needs_extra_padding_round { + if round_idx + 2 == num_rounds { + assert_eq!(precompile_state, Keccak256PrecompileState::RunRoundFunction); + true + } else { + false + } + } else { + false + }; + + if precompile_state == Keccak256PrecompileState::RunRoundFunction + && next_round_is_padding + { + precompile_state = Keccak256PrecompileState::RunPaddingRound; + } + + if is_last_round { + assert!(round.writes.is_some()); + let [write] = round.writes.unwrap(); + let write_query = memory_queries_it.next().unwrap(); + assert_eq!(write, *write_query); + + current_memory_queue_state = + transform_sponge_like_queue_state(*memory_queue_states_it.next().unwrap()); + + if is_last_request { + precompile_state = Keccak256PrecompileState::Finished; + } else { + precompile_state = Keccak256PrecompileState::GetRequestFromQueue; + } + } + + round_counter += 1; + + if round_counter == num_rounds_per_circuit || (is_last_request && is_last_round) { + let early_termination = round_counter != num_rounds_per_circuit; + round_counter = 0; + + let finished = is_last_request && is_last_round; + if finished { + assert!(memory_queries_it.next().is_none()); + } + + let state_inner = + zk_evm::zk_evm_abstractions::precompiles::keccak256::transmute_state( + internal_state.clone(), + ); + + let mut keccak_internal_state = encode_keccak256_inner_state(state_inner); + + if early_termination { + assert_eq!(precompile_state, Keccak256PrecompileState::Finished); + // we finished all the requests, but didn't reset the state as circuit would do + + // Even though any work of the circuit after requests are done is NOT observable + // and doesn't affect the correctness, we have a strict check that simulated input + output + // matches to what output circuit produced by itself based on the common input only + for el in input_buffer.bytes.iter_mut() { + *el = 0u8; + } + // internal state is a bit more tricky, it'll be a round over empty input + let mut internal_state_over_empty_buffer = Keccak256::default(); + let empty_block = [0u8; KECCAK_RATE_BYTES]; + internal_state_over_empty_buffer.update(&empty_block); + let empty_state_inner = + zk_evm::zk_evm_abstractions::precompiles::keccak256::transmute_state( + internal_state_over_empty_buffer.clone(), + ); + + keccak_internal_state = encode_keccak256_inner_state(empty_state_inner); + } + + let input_is_empty = is_last_request; + let nothing_left = is_last_round && input_is_empty; + + assert_eq!(nothing_left, finished); + + let completed = precompile_state == Keccak256PrecompileState::Finished; + let read_unaligned_words_for_round = + precompile_state == Keccak256PrecompileState::RunRoundFunction; + let read_precompile_call = + precompile_state == Keccak256PrecompileState::GetRequestFromQueue; + let padding_round = precompile_state == Keccak256PrecompileState::RunPaddingRound; + + let hidden_fsm_output_state = Keccak256RoundFunctionFSMWitness:: { + completed, + read_unaligned_words_for_round, + padding_round, + keccak_internal_state, + read_precompile_call, + timestamp_to_use_for_read: request.timestamp.0, + timestamp_to_use_for_write: request.timestamp.0 + 1, + precompile_call_params: Keccak256PrecompileCallParamsWitness:: { + input_page: precompile_request.memory_page_to_read, + input_memory_byte_offset: *input_byte_offset, + input_memory_byte_length: *bytes_left, + output_page: precompile_request.memory_page_to_write, + output_word_offset: precompile_request.output_memory_offset, + needs_full_padding_round: needs_extra_padding_round, + }, + buffer: zkevm_circuits::keccak256_round_function::buffer::ByteBufferWitness { + bytes: input_buffer.bytes, + filled: input_buffer.filled as u8, + }, + }; + + assert!( + hidden_fsm_output_state.read_precompile_call as usize + + hidden_fsm_output_state.read_unaligned_words_for_round as usize + + hidden_fsm_output_state.padding_round as usize + + hidden_fsm_output_state.completed as usize + == 1, + "only one state must be set, but have {:?}", + hidden_fsm_output_state + ); + + let range = starting_request_idx_for_circuit..(request_idx + 1); + starting_request_idx_for_circuit = request_idx + 1; + + let wit: VecDeque<_> = keccak_requests_queue_witness_copy[range] + .iter() + .cloned() + .collect(); + + let mut observable_input_data = PrecompileFunctionInputData::placeholder_witness(); + if result.len() == 0 { + observable_input_data.initial_log_queue_state = log_queue_input_state.clone(); + observable_input_data.initial_memory_queue_state = + memory_queue_input_state.clone(); + } + + let mut observable_output_data = + PrecompileFunctionOutputData::placeholder_witness(); + if finished { + observable_output_data.final_memory_state = current_memory_queue_state.clone(); + } + + let memory_reads_witness = std::mem::take(&mut memory_reads_per_circuit); + + let witness = Keccak256RoundFunctionCircuitInstanceWitness:: { + closed_form_input: Keccak256RoundFunctionCircuitInputOutputWitness:: { + start_flag: result.len() == 0, + completion_flag: finished, + observable_input: observable_input_data, + observable_output: observable_output_data, + hidden_fsm_input: Keccak256RoundFunctionFSMInputOutputWitness:: { + internal_fsm: hidden_fsm_input_state, + log_queue_state: log_queue_input_state.clone(), + memory_queue_state: memory_queue_input_state.clone(), + }, + hidden_fsm_output: Keccak256RoundFunctionFSMInputOutputWitness:: { + internal_fsm: hidden_fsm_output_state.clone(), + log_queue_state: take_queue_state_from_simulator( + &demuxed_keccak_precompile_queue.simulator, + ), + memory_queue_state: current_memory_queue_state.clone(), + }, + }, + requests_queue_witness: CircuitQueueRawWitness::< + F, + LogQuery, + 4, + LOG_QUERY_PACKED_WIDTH, + > { + elements: wit, + }, + memory_reads_witness: memory_reads_witness, + }; + + // make non-inclusize + result.push(witness); + + log_queue_input_state = + take_queue_state_from_simulator(&demuxed_keccak_precompile_queue.simulator); + hidden_fsm_input_state = hidden_fsm_output_state; + memory_queue_input_state = current_memory_queue_state.clone(); + } + } + } + + let memory_simulator_after = &keccak256_simulator_snapshots[1]; + let amount_of_memory_queries_after = + amount_of_memory_queries_before + keccak256_memory_queries.len(); + + assert_eq!( + amount_of_memory_queries_after, + memory_simulator_after.num_items as usize + ); + + (result, amount_of_memory_queries_after) +} + +pub(crate) fn encode_keccak256_inner_state(state: [u64; 25]) -> [[[u8; 8]; 5]; 5] { + // we need to transpose + let mut result = [[[0u8; 8]; 5]; 5]; + for (idx, src) in state.iter().enumerate() { + let i = idx % 5; + let j = idx / 5; + let dst = &mut result[i][j]; + *dst = src.to_le_bytes(); + } + + result +} + +// #[cfg(test)] +// mod test { +// use super::*; + +// use sync_vm::scheduler::queues::StorageLogQueue; +// use sync_vm::{ +// franklin_crypto::{ +// bellman::{SynthesisError}, +// plonk::circuit::tables::inscribe_default_range_table_for_bit_width_over_first_three_columns, +// }, +// precompiles::keccak256::{ +// keccak256_precompile_inner, KeccakPrecompileState, +// }, +// scheduler::queues::{FixedWidthEncodingGenericQueueState, FullSpongeLikeQueueState}, +// testing::create_test_memory_artifacts_with_optimized_gate, +// traits::{CSAllocatable, CSWitnessable}, +// }; +// type E = sync_vm::testing::Bn256; + +// use sync_vm::glue::code_unpacker_sha256::memory_query_updated::MemoryQueriesQueue; + +// #[test] +// fn test_witness_coincides() -> Result<(), SynthesisError> { +// let (mut dummy_cs, committer, _) = create_test_memory_artifacts_with_optimized_gate(); +// let cs = &mut dummy_cs; +// inscribe_default_range_table_for_bit_width_over_first_three_columns(cs, 16)?; + +// let limit = 16; + +// let witness: Keccak256RoundFunctionCircuitWitness = { todo!() }; + +// let Keccak256RoundFunctionCircuitWitness { +// is_finished, +// passthrough_data, +// hidden_fsm_input, +// hidden_fsm_output, +// memory_reads_witness, +// } = witness; + +// let initial_state = KeccakPrecompileState::alloc_from_witness(cs, Some(hidden_fsm_input))?; +// let Keccak256RoundFunctionPassthroughStructureWitness { +// memory_queue_input_state, +// memory_queue_output_state, +// log_queue_input_state, +// log_queue_output_state, +// .. +// } = passthrough_data; + +// let initial_memory_state = +// FullSpongeLikeQueueState::alloc_from_witness(cs, Some(memory_queue_input_state))?; +// let mut memory_queue = MemoryQueriesQueuFom_state(cs, initial_memory_state)?; + +// let initial_requests_queue_state = FixedWidthEncodingGenericQueueState::alloc_from_witness( +// cs, +// Some(log_queue_input_state), +// )?; +// let mut requests_queue = StorageLogQueuFom_state(cs, initial_requests_queue_state)?; + +// let final_state = keccak256_precompile_inner( +// cs, +// &mut memory_queue, +// &mut requests_queue, +// Some(memory_reads_witness), +// initial_state, +// &committer, +// limit, +// )?; + +// let final_memory_queue_state = memory_queue.into_state().create_witness().unwrap(); +// assert_eq!( +// final_memory_queue_state.head, +// memory_queue_output_state.head +// ); +// assert_eq!( +// final_memory_queue_state.tail, +// memory_queue_output_state.tail +// ); +// assert_eq!( +// final_memory_queue_state.length, +// memory_queue_output_state.length +// ); + +// let final_requests_queue_state = requests_queue.into_state().create_witness().unwrap(); +// assert_eq!( +// final_requests_queue_state.head_state, +// log_queue_output_state.head_state +// ); +// assert_eq!( +// final_requests_queue_state.tail_state, +// log_queue_output_state.tail_state +// ); +// assert_eq!( +// final_requests_queue_state.num_items, +// log_queue_output_state.num_items +// ); + +// let final_state = final_state.create_witness().unwrap(); +// assert_eq!( +// final_state.keccak_internal_state, +// hidden_fsm_output.keccak_internal_state +// ); + +// Ok(()) +// } +// } diff --git a/crates/zkevm_test_harness/src/witness/individual_circuits/memory_related/mod.rs b/crates/zkevm_test_harness/src/witness/individual_circuits/memory_related/mod.rs new file mode 100644 index 0000000..bc7e435 --- /dev/null +++ b/crates/zkevm_test_harness/src/witness/individual_circuits/memory_related/mod.rs @@ -0,0 +1,229 @@ +use decommit_code::decommitter_memory_queries; +use ecrecover::ecrecover_memory_queries; +use keccak256_round_function::keccak256_memory_queries; +use secp256r1_verify::secp256r1_memory_queries; +use sha256_round_function::sha256_memory_queries; + +use super::*; +use crate::ethereum_types::U256; + +use crate::zk_evm::aux_structures::DecommittmentQuery; +use crate::zk_evm::aux_structures::LogQuery as LogQuery_; +use crate::zk_evm::aux_structures::MemoryQuery; +use crate::zk_evm::zk_evm_abstractions::precompiles::ecrecover::ECRecoverRoundWitness; +use crate::zk_evm::zk_evm_abstractions::precompiles::keccak256::Keccak256RoundWitness; +use crate::zk_evm::zk_evm_abstractions::precompiles::secp256r1_verify::Secp256r1VerifyRoundWitness; +use crate::zk_evm::zk_evm_abstractions::precompiles::sha256::Sha256RoundWitness; + +use circuit_definitions::encodings::memory_query::MemoryQueueState; + +pub(crate) mod decommit_code; +pub(crate) mod ecrecover; +pub(crate) mod keccak256_round_function; +pub(crate) mod ram_permutation; +pub(crate) mod secp256r1_verify; +pub(crate) mod sha256_round_function; +pub(crate) mod sort_decommit_requests; + +#[derive(Clone)] +pub(crate) struct ImplicitMemoryQueries { + pub decommitter_memory_queries: Vec, + pub ecrecover_memory_queries: Vec, + pub keccak256_memory_queries: Vec, + pub secp256r1_memory_queries: Vec, + pub sha256_memory_queries: Vec, +} + +impl ImplicitMemoryQueries { + pub fn amount_of_queries(&self) -> usize { + self.decommitter_memory_queries.len() + + self.ecrecover_memory_queries.len() + + self.keccak256_memory_queries.len() + + self.secp256r1_memory_queries.len() + + self.sha256_memory_queries.len() + } + + fn get_vector(&self, index: usize) -> Option<&Vec> { + match index { + 0 => Some(&self.decommitter_memory_queries), + 1 => Some(&self.keccak256_memory_queries), + 2 => Some(&self.sha256_memory_queries), + 3 => Some(&self.ecrecover_memory_queries), + 4 => Some(&self.secp256r1_memory_queries), + _ => None, + } + } + + pub fn iter(&self) -> ImplicitMemoryQueriesIter { + ImplicitMemoryQueriesIter { + inner: &self, + circuit_index: 0, + iter: self.decommitter_memory_queries.iter(), + } + } +} + +pub struct ImplicitMemoryQueriesIter<'a> { + inner: &'a ImplicitMemoryQueries, + circuit_index: usize, + iter: Iter<'a, MemoryQuery>, +} + +use core::slice::Iter; + +impl<'a> Iterator for ImplicitMemoryQueriesIter<'a> { + type Item = &'a MemoryQuery; + + fn next(&mut self) -> Option { + let mut next = self.iter.next(); + + while next.is_none() { + self.circuit_index += 1; + let inner_vec = &self.inner.get_vector(self.circuit_index); + if inner_vec.is_none() { + return None; + } + + self.iter = inner_vec.unwrap().iter(); + next = self.iter.next(); + } + + next + } +} + +use crate::witness::oracle::PrecompilesInputData; +pub fn get_implicit_memory_queries( + deduplicated_decommit_requests_with_data: &Vec<(DecommittmentQuery, Vec)>, + precompiles_inputs: &PrecompilesInputData, +) -> ImplicitMemoryQueries { + ImplicitMemoryQueries { + decommitter_memory_queries: decommitter_memory_queries( + deduplicated_decommit_requests_with_data, + ), + ecrecover_memory_queries: ecrecover_memory_queries(&precompiles_inputs.ecrecover_witnesses), + keccak256_memory_queries: keccak256_memory_queries( + &precompiles_inputs.keccak_round_function_witnesses, + ), + secp256r1_memory_queries: secp256r1_memory_queries( + &precompiles_inputs.secp256r1_verify_witnesses, + ), + sha256_memory_queries: sha256_memory_queries( + &precompiles_inputs.sha256_round_function_witnesses, + ), + } +} + +pub(crate) struct SimulatorSnapshot { + pub head: [F; SW], + pub tail: [F; SW], + pub num_items: u32, +} +use crate::boojum::gadgets::queue::QueueStateWitness; +use crate::boojum::gadgets::queue::QueueTailStateWitness; + +impl SimulatorSnapshot { + pub fn take_sponge_like_queue_state(&self) -> QueueStateWitness { + let result = QueueStateWitness { + head: self.head, + tail: QueueTailStateWitness { + tail: self.tail, + length: self.num_items, + }, + }; + + result + } +} + +#[derive(Default)] +pub(crate) struct ImplicitMemoryStates { + pub decommitter_simulator_snapshots: Vec>, + pub decommitter_memory_states: Vec>, + pub ecrecover_simulator_snapshots: Vec>, + pub ecrecover_memory_states: Vec>, + pub keccak256_simulator_snapshots: Vec>, + pub keccak256_memory_states: Vec>, + pub secp256r1_simulator_snapshots: Vec>, + pub secp256r1_memory_states: Vec>, + pub sha256_simulator_snapshots: Vec>, + pub sha256_memory_states: Vec>, +} + +impl ImplicitMemoryStates { + pub fn amount_of_states(&self) -> usize { + self.decommitter_memory_states.len() + + self.ecrecover_memory_states.len() + + self.keccak256_memory_states.len() + + self.secp256r1_memory_states.len() + + self.sha256_memory_states.len() + } +} +use crate::witness::aux_data_structs::MemoryQueuePerCircuitSimulator; + +fn get_simulator_snapshot( + memory_queue_simulator: &mut MemoryQueuePerCircuitSimulator, +) -> SimulatorSnapshot { + SimulatorSnapshot { + head: memory_queue_simulator.head, + tail: memory_queue_simulator.tail, + num_items: memory_queue_simulator.num_items, + } +} + +use crate::witness::aux_data_structs::one_per_circuit_accumulator::LastPerCircuitAccumulator; + +pub(crate) fn simulate_implicit_memory_queues< + F: SmallField, + R: BuildableCircuitRoundFunction + AlgebraicRoundFunction, +>( + memory_queue_simulator: &mut MemoryQueuePerCircuitSimulator, + memory_queue_states_accumulator: &mut LastPerCircuitAccumulator>, + implicit_memory_queries: &ImplicitMemoryQueries, + round_function: R, +) -> ImplicitMemoryStates { + let mut implicit_memory_states = ImplicitMemoryStates::default(); + + let mut simulate_subqueue = + |memory_queries: &Vec, memory_states: &mut Vec>| { + let mut snapshots = vec![]; + snapshots.push(get_simulator_snapshot(memory_queue_simulator)); // before + for query in memory_queries.iter() { + let (_old_tail, intermediate_info) = memory_queue_simulator + .push_and_output_intermediate_data(*query, &round_function); + + memory_states.push(intermediate_info); + memory_queue_states_accumulator.push(intermediate_info); + } + snapshots.push(get_simulator_snapshot(memory_queue_simulator)); // after + + snapshots + }; + + implicit_memory_states.decommitter_simulator_snapshots = simulate_subqueue( + &implicit_memory_queries.decommitter_memory_queries, + &mut implicit_memory_states.decommitter_memory_states, + ); + + implicit_memory_states.keccak256_simulator_snapshots = simulate_subqueue( + &implicit_memory_queries.keccak256_memory_queries, + &mut implicit_memory_states.keccak256_memory_states, + ); + + implicit_memory_states.sha256_simulator_snapshots = simulate_subqueue( + &implicit_memory_queries.sha256_memory_queries, + &mut implicit_memory_states.sha256_memory_states, + ); + + implicit_memory_states.ecrecover_simulator_snapshots = simulate_subqueue( + &implicit_memory_queries.ecrecover_memory_queries, + &mut implicit_memory_states.ecrecover_memory_states, + ); + + implicit_memory_states.secp256r1_simulator_snapshots = simulate_subqueue( + &implicit_memory_queries.secp256r1_memory_queries, + &mut implicit_memory_states.secp256r1_memory_states, + ); + + implicit_memory_states +} diff --git a/crates/zkevm_test_harness/src/witness/individual_circuits/memory_related/ram_permutation.rs b/crates/zkevm_test_harness/src/witness/individual_circuits/memory_related/ram_permutation.rs new file mode 100644 index 0000000..eec69c2 --- /dev/null +++ b/crates/zkevm_test_harness/src/witness/individual_circuits/memory_related/ram_permutation.rs @@ -0,0 +1,646 @@ +use self::toolset::GeometryConfig; + +use super::*; +use crate::boojum::gadgets::queue::full_state_queue::FullStateCircuitQueueRawWitness; +use crate::witness::aux_data_structs::one_per_circuit_accumulator::LastPerCircuitAccumulator; +use crate::witness::aux_data_structs::per_circuit_accumulator::PerCircuitAccumulator; +use crate::witness::aux_data_structs::MemoryQueuePerCircuitSimulator; +use crate::witness::postprocessing::observable_witness::RamPermutationObservableWitness; +use crate::witness::postprocessing::CircuitMaker; +use crate::zk_evm::aux_structures::MemoryQuery; +use crate::zk_evm::ethereum_types::U256; +use crate::zkevm_circuits::{ + base_structures::memory_query::MEMORY_QUERY_PACKED_WIDTH, ram_permutation::input::*, +}; +use artifacts::MemoryArtifacts; +use circuit_definitions::circuit_definitions::base_layer::{ + RAMPermutationInstanceSynthesisFunction, ZkSyncBaseLayerCircuit, +}; +use circuit_definitions::encodings::memory_query::MemoryQueueSimulator; +use circuit_definitions::encodings::memory_query::MemoryQueueState; +use circuit_definitions::encodings::recursion_request::RecursionQueueSimulator; +use circuit_definitions::zkevm_circuits::scheduler::aux::BaseLayerCircuitType; +use circuit_definitions::{encodings::*, Field, RoundFunction}; +use memory_query::{CustomMemoryQueueSimulator, QueueWitness}; +use oracle::WitnessGenerationArtifact; + +use postprocessing::FirstAndLastCircuitWitness; +use rayon::prelude::*; +use snark_wrapper::boojum::field::Field as _; +use std::borrow::Borrow; +use std::cmp::Ordering; +use std::sync::Arc; +use zkevm_circuits::base_structures::vm_state::QUEUE_STATE_WIDTH; + +use crate::zk_evm::zkevm_opcode_defs::BOOTLOADER_HEAP_PAGE; + +pub(crate) fn compute_ram_circuit_snapshots( + total_amount_of_queries: usize, // including additional queries from precompiles + memory_queue_states_accumulator: LastPerCircuitAccumulator>, + sorted_memory_queue_states_accumulator: LastPerCircuitAccumulator>, + memory_queue_simulator: MemoryQueuePerCircuitSimulator, + sorted_memory_queries_simulator: MemoryQueuePerCircuitSimulator, + sorted_queries_aux_data_for_chunks: Vec<(u32, MemoryQuery, usize)>, + sorted_encodings: Vec<[Field; MEMORY_QUERY_PACKED_WIDTH]>, + unsorted_encodings: Vec<[Field; MEMORY_QUERY_PACKED_WIDTH]>, + round_function: &RoundFunction, + num_non_deterministic_heap_queries: usize, + geometry: &GeometryConfig, + mut artifacts_callback: CB, +) -> ( + FirstAndLastCircuitWitness>, + Vec>, +) { + assert_eq!( + total_amount_of_queries, + memory_queue_states_accumulator.len() + ); + + assert_eq!( + total_amount_of_queries, + sorted_memory_queue_states_accumulator.len() + ); + + assert!( + total_amount_of_queries > 0, + "VM should have made some memory requests" + ); + + let per_circuit_capacity = geometry.cycles_per_ram_permutation as usize; + + let amount_of_circuits = + (total_amount_of_queries + per_circuit_capacity - 1) / per_circuit_capacity; + + let unsorted_memory_queue_chunk_final_states = memory_queue_states_accumulator.into_circuits(); + + assert_eq!( + unsorted_memory_queue_chunk_final_states.len(), + amount_of_circuits + ); + + let sorted_memory_queue_chunk_final_states = + sorted_memory_queue_states_accumulator.into_circuits(); + + assert_eq!( + unsorted_memory_queue_chunk_final_states.len(), + sorted_memory_queue_chunk_final_states.len() + ); + + assert_eq!( + sorted_memory_queries_simulator.num_items, + memory_queue_simulator.num_items + ); + + // since encodings of the elements provide all the information necessary to perform sorting argument, + // we use them naively + + assert_eq!( + memory_queue_simulator.num_items as usize, + total_amount_of_queries + ); + + assert_eq!(unsorted_encodings.len(), sorted_encodings.len()); + + let mut lhs_grand_product_chains = + Vec::with_capacity(DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS); + let mut rhs_grand_product_chains = + Vec::with_capacity(DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS); + { + let challenges = produce_fs_challenges::< + Field, + RoundFunction, + FULL_SPONGE_QUEUE_STATE_WIDTH, + { MEMORY_QUERY_PACKED_WIDTH + 1 }, + 2, + >( + memory_queue_simulator.take_sponge_like_queue_state().tail, + sorted_memory_queries_simulator + .take_sponge_like_queue_state() + .tail, + round_function, + ); + + let lhs_contributions = unsorted_encodings; + let rhs_contributions = sorted_encodings; + + for idx in 0..DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS { + let (lhs_grand_product_chain, rhs_grand_product_chain) = compute_grand_product_chains( + &lhs_contributions.iter().collect(), + &rhs_contributions.iter().collect(), + &challenges[idx], + ); + + assert_eq!(lhs_grand_product_chain.len(), total_amount_of_queries); + assert_eq!(rhs_grand_product_chain.len(), total_amount_of_queries); + assert_eq!( + lhs_grand_product_chain.len(), + memory_queue_simulator.num_items as usize + ); + assert_eq!( + rhs_grand_product_chain.len(), + sorted_memory_queries_simulator.num_items as usize + ); + + lhs_grand_product_chains.push(lhs_grand_product_chain); + rhs_grand_product_chains.push(rhs_grand_product_chain); + } + } + + let transposed_lhs_chains = transpose_chunks(&lhs_grand_product_chains, per_circuit_capacity); + let transposed_rhs_chains = transpose_chunks(&rhs_grand_product_chains, per_circuit_capacity); + + // now we need to split them into individual circuits + // splitting is not extra hard here, we walk over iterator over everything and save states on checkpoints + + assert_eq!( + unsorted_memory_queue_chunk_final_states.len(), + transposed_lhs_chains.len() + ); + assert_eq!( + unsorted_memory_queue_chunk_final_states.len(), + transposed_rhs_chains.len() + ); + + let unsorted_global_final_state = unsorted_memory_queue_chunk_final_states + .last() + .unwrap() + .clone(); + let sorted_global_final_state = sorted_memory_queue_chunk_final_states + .last() + .unwrap() + .clone(); + + assert_eq!( + unsorted_global_final_state.num_items, + sorted_global_final_state.num_items + ); + + let it = unsorted_memory_queue_chunk_final_states + .into_iter() + .zip(sorted_memory_queue_chunk_final_states.into_iter()) + .zip(transposed_lhs_chains.into_iter()) + .zip(transposed_rhs_chains.into_iter()) + .zip(sorted_queries_aux_data_for_chunks); + + // now trivial transformation into desired data structures, + // and we are all good + + let num_circuits = it.len(); + + let mut current_lhs_product = [Field::ONE; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS]; + let mut current_rhs_product = [Field::ONE; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS]; + let mut previous_sorting_key = [0u32; RAM_SORTING_KEY_LENGTH]; + let mut previous_comparison_key = [0u32; RAM_FULL_KEY_LENGTH]; + let mut previous_value = U256::zero(); + let mut previous_is_ptr = false; + + let mut current_number_of_nondet_writes = 0u32; + + use crate::boojum::gadgets::queue::QueueState; + let placeholder_witness = + QueueState::::placeholder_witness(); + let mut last_queue_state = (placeholder_witness.clone(), placeholder_witness); + + let circuit_type = BaseLayerCircuitType::RamValidation; + let mut maker = CircuitMaker::new(geometry.cycles_per_ram_permutation, round_function.clone()); + + for ( + idx, + ( + ( + ((unsorted_sponge_final_state, sorted_sponge_final_state), lhs_grand_product), + rhs_grand_product, + ), + (num_nondet_writes_in_chunk, last_sorted_query, sorted_states_len), + ), + ) in it.enumerate() + { + assert_eq!( + lhs_grand_product.len(), + DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS + ); + assert_eq!( + rhs_grand_product.len(), + DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS + ); + + // now we need to have final grand product value that will also become an input for the next circuit + + let if_first = idx == 0; + let is_last = idx == num_circuits - 1; + + let new_num_nondet_writes = + current_number_of_nondet_writes + (num_nondet_writes_in_chunk as u32); + + let last_unsorted_state = unsorted_sponge_final_state; + let last_sorted_state = sorted_sponge_final_state; + + let accumulated_lhs: [Field; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS] = + lhs_grand_product + .into_iter() + .map(|el| *el.last().unwrap()) + .collect::>() + .try_into() + .unwrap(); + let accumulated_rhs: [Field; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS] = + rhs_grand_product + .into_iter() + .map(|el| *el.last().unwrap()) + .collect::>() + .try_into() + .unwrap(); + + use circuit_definitions::encodings::memory_query::*; + let sorting_key = sorting_key(&last_sorted_query); + let comparison_key = comparison_key(&last_sorted_query); + let is_ptr = last_sorted_query.value_is_pointer; + let value = last_sorted_query.value; + + let (current_unsorted_queue_state, current_sorted_queue_state) = last_queue_state; + + assert_eq!( + current_unsorted_queue_state.tail.length, + current_sorted_queue_state.tail.length + ); + + // we use current final state as the intermediate head + let mut final_unsorted_state = transform_sponge_like_queue_state(last_unsorted_state); + final_unsorted_state.head = final_unsorted_state.tail.tail; + final_unsorted_state.tail.tail = unsorted_global_final_state.tail; + final_unsorted_state.tail.length = + unsorted_global_final_state.num_items - final_unsorted_state.tail.length; + + let mut final_sorted_state = transform_sponge_like_queue_state(last_sorted_state); + final_sorted_state.head = final_sorted_state.tail.tail; + final_sorted_state.tail.tail = sorted_global_final_state.tail; + final_sorted_state.tail.length = + sorted_global_final_state.num_items - final_sorted_state.tail.length; + + assert_eq!( + final_unsorted_state.tail.length, + final_sorted_state.tail.length + ); + + let mut instance_witness = RamPermutationCircuitInstanceWitness { + closed_form_input: ClosedFormInputWitness { + start_flag: if_first, + completion_flag: is_last, + observable_input: RamPermutationInputDataWitness { + unsorted_queue_initial_state: transform_sponge_like_queue_state( + unsorted_global_final_state, + ), + sorted_queue_initial_state: transform_sponge_like_queue_state( + sorted_global_final_state, + ), + non_deterministic_bootloader_memory_snapshot_length: + num_non_deterministic_heap_queries as u32, + }, + observable_output: (), + hidden_fsm_input: RamPermutationFSMInputOutputWitness { + lhs_accumulator: current_lhs_product, + rhs_accumulator: current_rhs_product, + current_unsorted_queue_state, + current_sorted_queue_state, + previous_sorting_key: previous_sorting_key, + previous_full_key: previous_comparison_key, + previous_value: previous_value, + previous_is_ptr: previous_is_ptr, + num_nondeterministic_writes: current_number_of_nondet_writes, + }, + hidden_fsm_output: RamPermutationFSMInputOutputWitness { + lhs_accumulator: accumulated_lhs, + rhs_accumulator: accumulated_rhs, + current_unsorted_queue_state: final_unsorted_state, + current_sorted_queue_state: final_sorted_state, + previous_sorting_key: sorting_key.0, + previous_full_key: comparison_key.0, + previous_value: value, + previous_is_ptr: is_ptr, + num_nondeterministic_writes: new_num_nondet_writes, + }, + }, + // we will need witnesses to pop elements from the front of the queue + // but this data should be saved to storage before, during queues simulation (RAM-heavy) + // so we use placeholders here + unsorted_queue_witness: Default::default(), + sorted_queue_witness: Default::default(), + }; + + if sorted_states_len % per_circuit_capacity != 0 { + // RAM circuit does padding, so all previous values must be reset + instance_witness + .closed_form_input + .hidden_fsm_output + .previous_sorting_key = [0u32; RAM_SORTING_KEY_LENGTH]; + instance_witness + .closed_form_input + .hidden_fsm_output + .previous_full_key = [0u32; RAM_FULL_KEY_LENGTH]; + instance_witness + .closed_form_input + .hidden_fsm_output + .previous_value = U256::zero(); + instance_witness + .closed_form_input + .hidden_fsm_output + .previous_is_ptr = false; + } + + current_lhs_product = accumulated_lhs; + current_rhs_product = accumulated_rhs; + + previous_sorting_key = sorting_key.0; + previous_comparison_key = comparison_key.0; + previous_value = value; + previous_is_ptr = is_ptr; + + current_number_of_nondet_writes = new_num_nondet_writes; + + let tmp = &instance_witness.closed_form_input.hidden_fsm_output; + last_queue_state = ( + tmp.current_unsorted_queue_state.clone(), + tmp.current_sorted_queue_state.clone(), + ); + + artifacts_callback(WitnessGenerationArtifact::BaseLayerCircuit( + ZkSyncBaseLayerCircuit::RAMPermutation(maker.process(instance_witness, circuit_type)), + )); + } + + drop(lhs_grand_product_chains); + drop(rhs_grand_product_chains); + + let ( + ram_permutation_circuits, + queue_simulator, + ram_permutation_circuits_compact_forms_witnesses, + ) = maker.into_results(); + artifacts_callback(WitnessGenerationArtifact::RecursionQueue(( + circuit_type as u64, + queue_simulator, + ram_permutation_circuits_compact_forms_witnesses.clone(), + ))); + + ( + ram_permutation_circuits, + ram_permutation_circuits_compact_forms_witnesses, + ) +} + +// #[test] +// fn test_parallelized_grand_product() { +// // this is only proof of permutation, without extra login on what the permutation should be + +// use crate::ethereum_types::U256; +// use crate::zk_evm::aux_structures::*; +// use sync_vm::testing::Bn256; +// use sync_vm::testing::create_test_memory_artifacts_with_optimized_gate; +// use sync_vm::franklin_crypto::bellman::pairing::ff::ScalarEngine; +// use sync_vm::traits::GenericHasher; + +// type E = Bn256; + +// let (_, round_function, _) = create_test_memory_artifacts_with_optimized_gate(); + +// // create dummy queries + +// let mut all_queries = vec![]; + +// let write = MemoryQuery { +// timestamp: Timestamp(0), +// location: MemoryLocation { +// page: MemoryPage(0), +// index: MemoryIndex(0), +// memory_type: MemoryType::Heap, +// }, +// rw_flag: true, +// value: U256::from(123u64), +// is_pended: false, +// value_is_pointer: false, +// }; + +// all_queries.push(write); + +// for i in (1u32..(1u32<<12)).rev() { +// let read = MemoryQuery { +// timestamp: Timestamp(i), +// location: MemoryLocation { +// page: MemoryPage(0), +// index: MemoryIndex(0), +// memory_type: MemoryType::Heap, +// }, +// rw_flag: false, +// value: U256::from(123u64), +// is_pended: false, +// value_is_pointer: false, +// }; + +// all_queries.push(read); +// } + +// // sort by memory location, and then by timestamp +// let mut sorted_memory_queries_accumulated = all_queries.clone(); +// sorted_memory_queries_accumulated.par_sort_by(|a, b| { +// match a.location.cmp(&b.location) { +// Ordering::Equal => a.timestamp.cmp(&b.timestamp), +// a @ _ => a, +// } +// }); + +// println!("Sorted"); + +// // those two thins are parallelizable, and can be internally parallelized too + +// // now we can finish reconstruction of each sorted and unsorted memory queries + +// let mut unsorted_memory_queue_states = vec![]; +// let mut sorted_memory_queue_states = vec![]; + +// let mut unsorted_memory_queries_simulator = MemoryQueueSimulator::::empty(); +// for query in all_queries.iter() { +// let (_old_tail, intermediate_info) = +// unsorted_memory_queries_simulator.push_and_output_intermediate_data(*query, &round_function); + +// unsorted_memory_queue_states.push(intermediate_info); +// } + +// println!("Original committed"); + +// // reconstruct sorted one in full +// let mut sorted_memory_queries_simulator = MemoryQueueSimulator::::empty(); +// for query in sorted_memory_queries_accumulated.iter() { +// let (_old_tail, intermediate_info) = +// sorted_memory_queries_simulator.push_and_output_intermediate_data(*query, &round_function); + +// sorted_memory_queue_states.push(intermediate_info); +// } + +// println!("Sorted committed"); + +// // dbg!(&sorted_memory_queries_simulator.num_items); + +// assert_eq!(sorted_memory_queries_simulator.num_items, unsorted_memory_queries_simulator.num_items); + +// // now we should chunk it by circuits but briefly simulating their logic + +// let mut challenges = vec![]; + +// let mut fs_input = vec![]; +// fs_input.extend_from_slice(&unsorted_memory_queries_simulator.tail); +// fs_input.push(u64_to_fe(unsorted_memory_queries_simulator.num_items as u64)); +// fs_input.extend_from_slice(&sorted_memory_queries_simulator.tail); +// fs_input.push(u64_to_fe(sorted_memory_queries_simulator.num_items as u64)); + +// let sequence_of_states = round_function.simulate_absorb_multiple_rounds_into_empty_with_specialization(&fs_input); +// let final_state = sequence_of_states.last().unwrap().1; +// use sync_vm::rescue_poseidon::RescueParams; +// let base_fs_challenge: ::Fr = GenericHasher::, 2, 3>::simulate_state_into_commitment(final_state); + +// let mut current = base_fs_challenge; +// challenges.push(current); +// current.mul_assign(&base_fs_challenge); +// challenges.push(current); +// current.mul_assign(&base_fs_challenge); +// challenges.push(current); + +// // since encodings of the elements provide all the information necessary to perform soring argument, +// // we use them naively + +// let lhs_contributions: Vec<_> = unsorted_memory_queries_simulator.witness.iter().map(|el| el.0).collect(); +// let rhs_contributions: Vec<_> = sorted_memory_queries_simulator.witness.iter().map(|el| el.0).collect(); + +// assert_eq!(lhs_contributions.len(), rhs_contributions.len()); + +// let mut lhs_grand_product_chain: Vec<_> = vec![::Fr::zero(); lhs_contributions.len()]; +// let mut rhs_grand_product_chain: Vec<_> = vec![::Fr::zero(); rhs_contributions.len()]; + +// let challenges: [::Fr; 3] = challenges.try_into().unwrap(); + +// lhs_grand_product_chain.par_chunks_mut(RAM_PERMUTATION_CHUNK_SIZE).zip(lhs_contributions.par_chunks(RAM_PERMUTATION_CHUNK_SIZE)).for_each( +// |(dst, src)| { +// assert_eq!(dst.len(), src.len()); +// let mut grand_product = ::Fr::one(); +// for (dst, src) in dst.iter_mut().zip(src.iter()) { +// let mut acc = challenges[2]; + +// let mut tmp = src[0]; +// tmp.mul_assign(&challenges[0]); +// acc.add_assign(&tmp); + +// let mut tmp = src[1]; +// tmp.mul_assign(&challenges[1]); +// acc.add_assign(&tmp); + +// grand_product.mul_assign(&acc); + +// *dst = grand_product; +// } +// } +// ); + +// rhs_grand_product_chain.par_chunks_mut(RAM_PERMUTATION_CHUNK_SIZE).zip(rhs_contributions.par_chunks(RAM_PERMUTATION_CHUNK_SIZE)).for_each( +// |(dst, src)| { +// assert_eq!(dst.len(), src.len()); +// let mut grand_product = ::Fr::one(); +// for (dst, src) in dst.iter_mut().zip(src.iter()) { +// let mut acc = challenges[2]; + +// let mut tmp = src[0]; +// tmp.mul_assign(&challenges[0]); +// acc.add_assign(&tmp); + +// let mut tmp = src[1]; +// tmp.mul_assign(&challenges[1]); +// acc.add_assign(&tmp); + +// grand_product.mul_assign(&acc); + +// *dst = grand_product; +// } +// } +// ); + +// let mut grand_product = ::Fr::one(); +// let mut naive_lhs = vec![]; +// for src in lhs_contributions.iter() { +// let mut acc = challenges[2]; + +// let mut tmp = src[0]; +// tmp.mul_assign(&challenges[0]); +// acc.add_assign(&tmp); + +// let mut tmp = src[1]; +// tmp.mul_assign(&challenges[1]); +// acc.add_assign(&tmp); + +// grand_product.mul_assign(&acc); + +// naive_lhs.push(grand_product); +// } + +// assert_eq!(naive_lhs.len(), lhs_grand_product_chain.len()); + +// // elementwise products are done, now must fold + +// let mut lhs_intermediates: Vec<::Fr> = lhs_grand_product_chain.par_chunks(RAM_PERMUTATION_CHUNK_SIZE).map( +// |slice: &[::Fr]| { +// *slice.last().unwrap() +// } +// ).collect(); + +// let mut rhs_intermediates: Vec<::Fr> = rhs_grand_product_chain.par_chunks(RAM_PERMUTATION_CHUNK_SIZE).map( +// |slice: &[::Fr]| { +// *slice.last().unwrap() +// } +// ).collect(); + +// assert_eq!(lhs_intermediates.len(), lhs_grand_product_chain.chunks(RAM_PERMUTATION_CHUNK_SIZE).len()); +// assert_eq!(rhs_intermediates.len(), rhs_grand_product_chain.chunks(RAM_PERMUTATION_CHUNK_SIZE).len()); + +// // accumulate intermediate products +// // we should multiply element [1] by element [0], +// // element [2] by [0] * [1], +// // etc +// let mut acc_lhs = ::Fr::one(); +// for el in lhs_intermediates.iter_mut() { +// let tmp = *el; +// el.mul_assign(&acc_lhs); +// acc_lhs.mul_assign(&tmp); +// } + +// let mut acc_rhs = ::Fr::one(); +// for el in rhs_intermediates.iter_mut() { +// let tmp = *el; +// el.mul_assign(&acc_rhs); +// acc_rhs.mul_assign(&tmp); +// } + +// assert_eq!(lhs_intermediates.last().unwrap(), rhs_intermediates.last().unwrap()); + +// // here we skip 1 because we do not have anything to pre-accumuate +// lhs_grand_product_chain.par_chunks_mut(RAM_PERMUTATION_CHUNK_SIZE).skip(1).zip(lhs_intermediates.par_chunks(1)).for_each( +// |(dst, src)| { +// assert_eq!(src.len(), 1); +// let src = src[0]; +// for dst in dst.iter_mut() { +// dst.mul_assign(&src); +// } +// } +// ); + +// for (idx, (a, b)) in naive_lhs.iter().zip(lhs_grand_product_chain.iter()).enumerate() { +// assert_eq!(a, b, "failed at index {}: a = {}, b = {}", idx, a, b); +// } + +// rhs_grand_product_chain.par_chunks_mut(RAM_PERMUTATION_CHUNK_SIZE).skip(1).zip(rhs_intermediates.par_chunks(1)).for_each( +// |(dst, src)| { +// let src = src[0]; +// for dst in dst.iter_mut() { +// dst.mul_assign(&src); +// } +// } +// ); + +// // sanity check +// assert_eq!(lhs_grand_product_chain.last().unwrap(), rhs_grand_product_chain.last().unwrap()); +// } diff --git a/crates/zkevm_test_harness/src/witness/individual_circuits/memory_related/secp256r1_verify.rs b/crates/zkevm_test_harness/src/witness/individual_circuits/memory_related/secp256r1_verify.rs new file mode 100644 index 0000000..67af787 --- /dev/null +++ b/crates/zkevm_test_harness/src/witness/individual_circuits/memory_related/secp256r1_verify.rs @@ -0,0 +1,238 @@ +use super::*; +use crate::witness::artifacts::{DemuxedLogQueries, LogQueueStates}; +use crate::witness::aux_data_structs::one_per_circuit_accumulator::LastPerCircuitAccumulator; +use crate::witness::aux_data_structs::MemoryQueuePerCircuitSimulator; +use crate::zk_evm::aux_structures::LogQuery as LogQuery_; +use crate::zk_evm::aux_structures::MemoryQuery; +use crate::zk_evm::zk_evm_abstractions::precompiles::secp256r1_verify::Secp256r1VerifyRoundWitness; +use crate::zkevm_circuits::base_structures::log_query::*; +use crate::zkevm_circuits::secp256r1_verify::*; +use circuit_definitions::encodings::memory_query::MemoryQueueSimulator; +use circuit_definitions::encodings::memory_query::MemoryQueueState; +use circuit_definitions::encodings::*; + +pub(crate) fn secp256r1_memory_queries( + secp256r1_verify_witnesses: &Vec<(u32, LogQuery_, Secp256r1VerifyRoundWitness)>, +) -> Vec { + let amount_of_queries = secp256r1_verify_witnesses + .iter() + .fold(0, |inner, (_, _, witness)| { + inner + witness.reads.len() + witness.writes.len() + }); + + let mut secp256r1_memory_queries = Vec::with_capacity(amount_of_queries); + + for (_cycle, _query, witness) in secp256r1_verify_witnesses.iter() { + let initial_memory_len = secp256r1_memory_queries.len(); + // we read, then write + secp256r1_memory_queries.extend_from_slice(&witness.reads); + secp256r1_memory_queries.extend_from_slice(&witness.writes); + + assert_eq!(secp256r1_memory_queries.len() - initial_memory_len, 7); + } + + secp256r1_memory_queries +} + +// we want to simulate splitting of data into many separate instances of the same circuit. +// So we basically need to reconstruct the FSM state on input/output, and passthrough data. +// In practice the only difficulty is buffer state, everything else is provided by out-of-circuit VM + +pub(crate) fn secp256r1_verify_decompose_into_per_circuit_witness< + F: SmallField, + R: BuildableCircuitRoundFunction + AlgebraicRoundFunction, +>( + amount_of_memory_queries_before: usize, + secp256r1_memory_queries: Vec, + secp256r1_simulator_snapshots: Vec>, + secp256r1_memory_states: Vec>, + secp256r1_verify_witnesses: Vec<(u32, LogQuery_, Secp256r1VerifyRoundWitness)>, + secp256r1_verify_queries: Vec, + mut demuxed_secp256r1_verify_queue: LogQueueStates, + num_rounds_per_circuit: usize, + round_function: &R, +) -> (Vec>, usize) { + assert_eq!( + secp256r1_memory_queries.len(), + secp256r1_memory_states.len() + ); + + let memory_simulator_before = &secp256r1_simulator_snapshots[0]; + assert_eq!( + amount_of_memory_queries_before, + memory_simulator_before.num_items as usize + ); + + let mut result = vec![]; + + let precompile_calls = secp256r1_verify_queries; + let simulator_witness: Vec<_> = demuxed_secp256r1_verify_queue + .simulator + .witness + .clone() + .into(); + let round_function_witness = secp256r1_verify_witnesses; + + // check basic consistency + assert!(precompile_calls.len() == demuxed_secp256r1_verify_queue.states_accumulator.len()); + drop(demuxed_secp256r1_verify_queue.states_accumulator); + assert!(precompile_calls.len() == round_function_witness.len()); + + if precompile_calls.len() == 0 { + return (vec![], amount_of_memory_queries_before); + } + + let mut round_counter = 0; + let num_requests = precompile_calls.len(); + + // convension + let mut log_queue_input_state = + take_queue_state_from_simulator(&demuxed_secp256r1_verify_queue.simulator); + let amount_secp256r1_memory_queries = secp256r1_memory_queries.len(); + let mut memory_queries_it = secp256r1_memory_queries.into_iter(); + + let mut memory_read_witnesses = vec![]; + let mut starting_request_idx = 0; + + let mut memory_queue_input_state = memory_simulator_before.take_sponge_like_queue_state(); + let mut current_memory_queue_state = memory_queue_input_state.clone(); + + let mut memory_queue_states_it = secp256r1_memory_states.iter(); + + for (request_idx, (request, per_request_work)) in precompile_calls + .into_iter() + .zip(round_function_witness.into_iter()) + .enumerate() + { + let _ = demuxed_secp256r1_verify_queue + .simulator + .pop_and_output_intermediate_data(round_function); + + let mut memory_reads_per_request = vec![]; + + let (_cycle, _req, round_witness) = per_request_work; + assert_eq!(request, _req); + + use crate::zk_evm::zk_evm_abstractions::precompiles::precompile_abi_in_log; + let mut precompile_request = precompile_abi_in_log(request); + let is_last_request = request_idx == num_requests - 1; + + let mut amount_of_queries = 0; + + // we have reads + for (_query_index, read) in round_witness.reads.into_iter().enumerate() { + let read_query = memory_queries_it.next().unwrap(); + assert!(read == read_query); + assert!(read_query.rw_flag == false); + memory_reads_per_request.push(read_query.value); + + current_memory_queue_state = + transform_sponge_like_queue_state(*memory_queue_states_it.next().unwrap()); + + precompile_request.input_memory_offset += 1; + amount_of_queries += 1; + } + + // and writes + for (_query_index, write) in round_witness.writes.into_iter().enumerate() { + let write_query = memory_queries_it.next().unwrap(); + assert!(write == write_query); + assert!(write_query.rw_flag == true); + + current_memory_queue_state = + transform_sponge_like_queue_state(*memory_queue_states_it.next().unwrap()); + + precompile_request.output_memory_offset += 1; + amount_of_queries += 1; + } + + assert_eq!(amount_of_queries, 7); + round_counter += 1; + + if round_counter == num_rounds_per_circuit || is_last_request { + round_counter = 0; + + let finished = is_last_request; + if finished { + assert!(memory_queries_it.next().is_none()); + } + + let range = starting_request_idx..(request_idx + 1); + let wit: VecDeque<_> = (&simulator_witness[range]) + .iter() + .map(|el| (log_query_into_circuit_log_query_witness(&el.2), el.1)) + .collect(); + + let current_reads = std::mem::take(&mut memory_reads_per_request); + let mut current_witness = std::mem::take(&mut memory_read_witnesses); + current_witness.push(current_reads); + + let mut observable_input_data = PrecompileFunctionInputData::placeholder_witness(); + if result.len() == 0 { + observable_input_data.initial_memory_queue_state = memory_queue_input_state.clone(); + observable_input_data.initial_log_queue_state = log_queue_input_state.clone(); + } + + let mut observable_output_data = PrecompileFunctionOutputData::placeholder_witness(); + if finished { + observable_output_data.final_memory_state = current_memory_queue_state.clone(); + } + + let witness = Secp256r1VerifyCircuitInstanceWitness:: { + closed_form_input: Secp256r1VerifyCircuitInputOutputWitness:: { + start_flag: result.len() == 0, + completion_flag: finished, + observable_input: observable_input_data, + observable_output: observable_output_data, + hidden_fsm_input: Secp256r1VerifyCircuitFSMInputOutputWitness:: { + log_queue_state: log_queue_input_state.clone(), + memory_queue_state: memory_queue_input_state, + }, + hidden_fsm_output: Secp256r1VerifyCircuitFSMInputOutputWitness:: { + log_queue_state: take_queue_state_from_simulator( + &demuxed_secp256r1_verify_queue.simulator, + ), + memory_queue_state: current_memory_queue_state.clone(), + }, + }, + requests_queue_witness: CircuitQueueRawWitness::< + F, + LogQuery, + 4, + LOG_QUERY_PACKED_WIDTH, + > { + elements: wit, + }, + memory_reads_witness: current_witness + .into_iter() + .map(|el| el.try_into().expect("length must match")) + .collect(), + }; + + // make non-inclusize + starting_request_idx = request_idx + 1; + + result.push(witness); + + log_queue_input_state = + take_queue_state_from_simulator(&demuxed_secp256r1_verify_queue.simulator); + memory_queue_input_state = current_memory_queue_state.clone(); + } + + if !memory_reads_per_request.is_empty() { + // we may have drained it already if it was the end of the circuit + memory_read_witnesses.push(memory_reads_per_request); + } + } + + let memory_simulator_after = &secp256r1_simulator_snapshots[1]; + let amount_of_memory_queries_after = + amount_of_memory_queries_before + amount_secp256r1_memory_queries; + + assert_eq!( + amount_of_memory_queries_after, + memory_simulator_after.num_items as usize + ); + + (result, amount_of_memory_queries_after) +} diff --git a/crates/zkevm_test_harness/src/witness/individual_circuits/memory_related/sha256_round_function.rs b/crates/zkevm_test_harness/src/witness/individual_circuits/memory_related/sha256_round_function.rs new file mode 100644 index 0000000..23d372b --- /dev/null +++ b/crates/zkevm_test_harness/src/witness/individual_circuits/memory_related/sha256_round_function.rs @@ -0,0 +1,354 @@ +use super::*; +use crate::boojum::gadgets::traits::allocatable::CSAllocatable; +use crate::witness::artifacts::{DemuxedLogQueries, LogQueueStates}; +use crate::witness::aux_data_structs::one_per_circuit_accumulator::LastPerCircuitAccumulator; +use crate::witness::aux_data_structs::MemoryQueuePerCircuitSimulator; +use crate::zk_evm::aux_structures::LogQuery as LogQuery_; +use crate::zk_evm::aux_structures::MemoryQuery; +use crate::zk_evm::zk_evm_abstractions::precompiles::sha256::Sha256RoundWitness; +use crate::zk_evm::zkevm_opcode_defs::ethereum_types::U256; +use crate::zkevm_circuits::base_structures::log_query::*; +use crate::zkevm_circuits::sha256_round_function::input::*; +use crate::zkevm_circuits::sha256_round_function::*; +use circuit_definitions::encodings::memory_query::MemoryQueueSimulator; +use circuit_definitions::encodings::memory_query::MemoryQueueState; +use circuit_definitions::encodings::*; +use derivative::*; + +pub(crate) fn sha256_memory_queries( + sha256_round_function_witnesses: &Vec<(u32, LogQuery_, Vec)>, +) -> Vec { + let amount_of_queries = + sha256_round_function_witnesses + .iter() + .fold(0, |mut inner, (_, _, witness)| { + for el in witness.iter() { + inner += el.reads.len(); + + if let Some(writes) = el.writes.as_ref() { + inner += writes.len() + } + } + inner + }); + + let mut sha256_memory_queries = Vec::with_capacity(amount_of_queries); + + for (_cycle, _query, witness) in sha256_round_function_witnesses.iter() { + for el in witness.iter() { + let Sha256RoundWitness { + new_request: _, + reads, + writes, + } = el; + + // we read, then write + sha256_memory_queries.extend_from_slice(reads); + + if let Some(writes) = writes.as_ref() { + sha256_memory_queries.extend_from_slice(writes); + } + } + } + + sha256_memory_queries +} + +#[derive(Derivative)] +#[derivative(Clone, Copy, Debug, PartialEq, Eq)] +pub enum Sha256PrecompileState { + GetRequestFromQueue, + RunRoundFunction, + Finished, +} + +// we want to simulate splitting of data into many separate instances of the same circuit. +// So we basically need to reconstruct the FSM state on input/output, and passthrough data. +// In practice the only difficulty is buffer state, everything else is provided by out-of-circuit VM + +pub(crate) fn sha256_decompose_into_per_circuit_witness< + F: SmallField, + R: BuildableCircuitRoundFunction + AlgebraicRoundFunction, +>( + amount_of_memory_queries_before: usize, + sha256_memory_queries: Vec, + sha256_simulator_snapshots: Vec>, + sha256_memory_states: Vec>, + sha256_round_function_witnesses: Vec<(u32, LogQuery_, Vec)>, + sha256_precompile_queries: Vec, + mut demuxed_sha256_precompile_queue: LogQueueStates, + num_rounds_per_circuit: usize, + round_function: &R, +) -> (Vec>, usize) { + assert_eq!(sha256_memory_queries.len(), sha256_memory_states.len()); + + let memory_simulator_before = &sha256_simulator_snapshots[0]; + assert_eq!( + amount_of_memory_queries_before, + memory_simulator_before.num_items as usize + ); + + let mut result = vec![]; + + let precompile_calls = sha256_precompile_queries; + let simulator_witness: Vec<_> = demuxed_sha256_precompile_queue + .simulator + .witness + .clone() + .into(); + let round_function_witness = sha256_round_function_witnesses; + + // check basic consistency + assert!(precompile_calls.len() == demuxed_sha256_precompile_queue.states_accumulator.len()); + drop(demuxed_sha256_precompile_queue.states_accumulator); + assert!(precompile_calls.len() == round_function_witness.len()); + + if precompile_calls.len() == 0 { + return (vec![], amount_of_memory_queries_before); + } + + let mut round_counter = 0; + let num_requests = precompile_calls.len(); + + // convension + let mut log_queue_input_state = + take_queue_state_from_simulator(&demuxed_sha256_precompile_queue.simulator); + let mut hidden_fsm_input_state = Sha256RoundFunctionFSM::::placeholder_witness(); + hidden_fsm_input_state.read_precompile_call = true; + + let amount_sha256_memory_queries = sha256_memory_queries.len(); + let mut memory_queries_it = sha256_memory_queries.into_iter(); + + let mut memory_read_witnesses = vec![]; + + let mut precompile_state = Sha256PrecompileState::GetRequestFromQueue; + + let mut request_ranges = vec![]; + let mut starting_request_idx = 0; + + let mut memory_queue_input_state = memory_simulator_before.take_sponge_like_queue_state(); + let mut current_memory_queue_state = memory_queue_input_state.clone(); + + let mut memory_queue_states_it = sha256_memory_states.iter(); + + for (request_idx, (request, per_request_work)) in precompile_calls + .into_iter() + .zip(round_function_witness.into_iter()) + .enumerate() + { + let _ = demuxed_sha256_precompile_queue + .simulator + .pop_and_output_intermediate_data(round_function); + + use crate::zk_evm::zk_evm_abstractions::precompiles::sha256::Sha256; + let mut internal_state = Sha256::default(); + + let mut memory_reads_per_request: Vec = vec![]; + + assert_eq!(precompile_state, Sha256PrecompileState::GetRequestFromQueue); + + let (_cycle, _req, round_witness) = per_request_work; + assert_eq!(request, _req); + + use crate::zk_evm::zk_evm_abstractions::precompiles::precompile_abi_in_log; + let mut precompile_request = precompile_abi_in_log(request); + let num_rounds = precompile_request.precompile_interpreted_data as usize; + assert_eq!(num_rounds, round_witness.len()); + + let mut num_rounds_left = num_rounds; + + let is_last_request = request_idx == num_requests - 1; + + precompile_state = Sha256PrecompileState::RunRoundFunction; + + for (round_idx, round) in round_witness.into_iter().enumerate() { + if round_idx == 0 { + assert!(round.new_request.is_some()); + } + + let mut block = [0u8; 64]; + + // we have two reads + for (dst, read) in block.array_chunks_mut::<32>().zip(round.reads.into_iter()) { + let data = read.value; + data.to_big_endian(dst); + let read_query = memory_queries_it.next().unwrap(); + assert_eq!(read, read_query); + memory_reads_per_request.push(read_query.value); + + current_memory_queue_state = + transform_sponge_like_queue_state(*memory_queue_states_it.next().unwrap()); + + precompile_request.input_memory_offset += 1; + } + use crate::zk_evm::zk_evm_abstractions::precompiles::sha256::Digest; + internal_state.update(&block); + + num_rounds_left -= 1; + + let is_last_round = round_idx == num_rounds - 1; + + if is_last_round { + assert_eq!(num_rounds_left, 0); + assert!(round.writes.is_some()); + let [write] = round.writes.unwrap(); + let write_query = memory_queries_it.next().unwrap(); + assert_eq!(write, write_query); + + current_memory_queue_state = + transform_sponge_like_queue_state(*memory_queue_states_it.next().unwrap()); + + if is_last_request { + precompile_state = Sha256PrecompileState::Finished; + } else { + precompile_state = Sha256PrecompileState::GetRequestFromQueue; + } + } + + round_counter += 1; + + if round_counter == num_rounds_per_circuit || (is_last_request && is_last_round) { + let early_termination = round_counter != num_rounds_per_circuit; + round_counter = 0; + + let finished = is_last_request && is_last_round; + if finished { + assert!(memory_queries_it.next().is_none()); + } + + let state_inner = zk_evm::zk_evm_abstractions::precompiles::sha256::transmute_state( + internal_state.clone(), + ); + + let mut circuit_hash_internal_state = state_inner; + + let input_is_empty = is_last_request; + let nothing_left = is_last_round && input_is_empty; + + assert_eq!(nothing_left, finished); + + if early_termination { + assert_eq!(precompile_state, Sha256PrecompileState::Finished); + // we finished all the requests, but didn't reset the state as circuit would do + + // Even though any work of the circuit after requests are done is NOT observable + // and doesn't affect the correctness, we have a strict check that simulated input + output + // matches to what output circuit produced by itself based on the common input only + + // internal state is a bit more tricky, it'll be a round over empty input + let mut internal_state_over_empty_buffer = Sha256::default(); + let empty_block = [0u8; 64]; + internal_state_over_empty_buffer.update(&empty_block); + let sha256_internal_state_over_empty_buffer = + zk_evm::zk_evm_abstractions::precompiles::sha256::transmute_state( + internal_state_over_empty_buffer.clone(), + ); + + circuit_hash_internal_state = sha256_internal_state_over_empty_buffer; + } + + let completed = precompile_state == Sha256PrecompileState::Finished; + let read_words_for_round = + precompile_state == Sha256PrecompileState::RunRoundFunction; + let read_precompile_call = + precompile_state == Sha256PrecompileState::GetRequestFromQueue; + + let hidden_fsm_output_state = Sha256RoundFunctionFSMWitness:: { + completed, + read_words_for_round, + sha256_inner_state: circuit_hash_internal_state, + read_precompile_call, + timestamp_to_use_for_read: request.timestamp.0, + timestamp_to_use_for_write: request.timestamp.0 + 1, + precompile_call_params: Sha256PrecompileCallParamsWitness:: { + input_page: precompile_request.memory_page_to_read, + input_offset: precompile_request.input_memory_offset, + output_page: precompile_request.memory_page_to_write, + output_offset: precompile_request.output_memory_offset, + num_rounds: num_rounds_left as u32, + }, + }; + + let range = starting_request_idx..(request_idx + 1); + let wit: VecDeque<_> = (&simulator_witness[range]) + .iter() + .map(|el| (log_query_into_circuit_log_query_witness(&el.2), el.1)) + .collect(); + + let current_reads = std::mem::take(&mut memory_reads_per_request); + let mut current_witness = std::mem::take(&mut memory_read_witnesses); + current_witness.push(current_reads); + + let mut observable_input_data = PrecompileFunctionInputData::placeholder_witness(); + if result.len() == 0 { + observable_input_data.initial_memory_queue_state = + memory_queue_input_state.clone(); + observable_input_data.initial_log_queue_state = log_queue_input_state.clone(); + } + + let mut observable_output_data = + PrecompileFunctionOutputData::placeholder_witness(); + if finished { + observable_output_data.final_memory_state = current_memory_queue_state.clone(); + } + + let witness = Sha256RoundFunctionCircuitInstanceWitness:: { + closed_form_input: Sha256RoundFunctionCircuitInputOutputWitness:: { + start_flag: result.len() == 0, + completion_flag: finished, + observable_input: observable_input_data, + observable_output: observable_output_data, + hidden_fsm_input: Sha256RoundFunctionFSMInputOutputWitness:: { + internal_fsm: hidden_fsm_input_state, + log_queue_state: log_queue_input_state.clone(), + memory_queue_state: memory_queue_input_state, + }, + hidden_fsm_output: Sha256RoundFunctionFSMInputOutputWitness:: { + internal_fsm: hidden_fsm_output_state.clone(), + log_queue_state: take_queue_state_from_simulator( + &demuxed_sha256_precompile_queue.simulator, + ), + memory_queue_state: current_memory_queue_state.clone(), + }, + }, + requests_queue_witness: CircuitQueueRawWitness::< + F, + LogQuery, + 4, + LOG_QUERY_PACKED_WIDTH, + > { + elements: wit, + }, + memory_reads_witness: current_witness.into_iter().flatten().collect(), + }; + + // make non-inclusize + request_ranges.push(starting_request_idx..(request_idx + 1)); + starting_request_idx = request_idx + 1; + + result.push(witness); + + log_queue_input_state = + take_queue_state_from_simulator(&demuxed_sha256_precompile_queue.simulator); + hidden_fsm_input_state = hidden_fsm_output_state; + memory_queue_input_state = current_memory_queue_state.clone(); + } + } + + if !memory_reads_per_request.is_empty() { + // we may have drained it already if it was the end of the circuit + memory_read_witnesses.push(memory_reads_per_request); + } + } + + let memory_simulator_after = &sha256_simulator_snapshots[1]; + let amount_of_memory_queries_after = + amount_of_memory_queries_before + amount_sha256_memory_queries; + + assert_eq!( + amount_of_memory_queries_after, + memory_simulator_after.num_items as usize + ); + + (result, amount_of_memory_queries_after) +} diff --git a/crates/zkevm_test_harness/src/witness/individual_circuits/memory_related/sort_decommit_requests.rs b/crates/zkevm_test_harness/src/witness/individual_circuits/memory_related/sort_decommit_requests.rs new file mode 100644 index 0000000..93b80b0 --- /dev/null +++ b/crates/zkevm_test_harness/src/witness/individual_circuits/memory_related/sort_decommit_requests.rs @@ -0,0 +1,457 @@ +use super::*; +use crate::boojum::gadgets::queue::full_state_queue::FullStateCircuitQueueRawWitness; +use crate::boojum::gadgets::u256::decompose_u256_as_u32x8; +use crate::ethereum_types::U256; +use crate::witness::aux_data_structs::one_per_circuit_accumulator::LastPerCircuitAccumulator; +use crate::witness::individual_circuits::memory_related::decommit_code::DecommiterCircuitProcessingInputs; +use crate::witness::utils::produce_fs_challenges; +use crate::zkevm_circuits::base_structures::decommit_query::DecommitQuery; +use crate::zkevm_circuits::base_structures::decommit_query::DecommitQueryWitness; +use crate::zkevm_circuits::base_structures::decommit_query::DECOMMIT_QUERY_PACKED_WIDTH; +use crate::zkevm_circuits::base_structures::vm_state::FULL_SPONGE_QUEUE_STATE_WIDTH; +use crate::zkevm_circuits::sort_decommittment_requests::input::*; +use crate::zkevm_circuits::DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS; +use artifacts::MemoryArtifacts; +use circuit_definitions::encodings::decommittment_request::*; +use circuit_definitions::encodings::memory_query::MemoryQueueSimulator; +use circuit_definitions::encodings::memory_query::MemoryQueueState; +use circuit_definitions::encodings::CircuitEquivalentReflection; +use circuit_definitions::zk_evm::aux_structures::DecommittmentQuery; +use rayon::prelude::*; +use std::cmp::Ordering; + +pub(crate) fn compute_decommitts_sorter_circuit_snapshots< + F: SmallField, + R: BuildableCircuitRoundFunction + AlgebraicRoundFunction, +>( + mut executed_decommittment_queries: Vec<(u32, DecommittmentQuery, Vec)>, + round_function: &R, + deduplicator_circuit_capacity: usize, +) -> ( + Vec<(u32, DecommittmentQueueState)>, + Vec>, + DecommiterCircuitProcessingInputs, +) { + // TODO cleanup + let mut deduplicated_decommittment_queue_simulator: DecommittmentQueueSimulator = + Default::default(); + let mut deduplicated_decommittment_queue_states: Vec> = + Default::default(); + let mut deduplicated_decommit_requests_with_data: Vec<(DecommittmentQuery, Vec)> = + Default::default(); + + let total_executed_queries = executed_decommittment_queries.len(); + + assert!( + total_executed_queries > 0, + "VM should have made some code decommits" + ); + + let mut all_decommittment_queue_states: Vec<(u32, DecommittmentQueueState)> = + Vec::with_capacity(total_executed_queries); + + // we produce witness for two circuits at once + + let mut unsorted_decommittment_queue_simulator = + DecommittmentQueueSimulator::::with_capacity(total_executed_queries); + let mut sorted_decommittment_queue_simulator = + DecommittmentQueueSimulator::::with_capacity(total_executed_queries); + + // sort decommittment requests + + let mut sorted_decommittment_queue_states = Vec::with_capacity(total_executed_queries); + let mut unsorted_decommittment_requests_with_data = Vec::with_capacity(total_executed_queries); + + for (_cycle, decommittment_request, writes) in executed_decommittment_queries.iter_mut() { + let data = std::mem::take(writes); + unsorted_decommittment_requests_with_data.push((*decommittment_request, data)); + } + + let num_circuits = (executed_decommittment_queries.len() + deduplicator_circuit_capacity - 1) + / deduplicator_circuit_capacity; + + // internally parallelizable by the factor of 3 + for (cycle, decommittment_request, _) in executed_decommittment_queries.iter() { + // sponge + let (_, intermediate_info) = unsorted_decommittment_queue_simulator + .push_and_output_intermediate_data(*decommittment_request, round_function); + + all_decommittment_queue_states.push((*cycle, intermediate_info)); + } + + // sort queries + let mut sorted_decommittment_requests_with_data = unsorted_decommittment_requests_with_data; + sorted_decommittment_requests_with_data.par_sort_by(|a, b| + // sort by hash first, and then by timestamp + match normalized_preimage_as_u256(&a.0.normalized_preimage) + .cmp( + &normalized_preimage_as_u256(&b.0.normalized_preimage) + ) { + Ordering::Equal => a.0.timestamp.cmp(&b.0.timestamp), + a @ _ => a, + }); + + // let mut deduplicated_decommit_requests_with_data = vec![]; + + let mut counter = 0; + let mut deduplicated_intermediate_states = vec![]; + let mut previous_packed_keys = vec![]; + let mut previous_records = vec![]; + let mut first_encountered_timestamps = vec![]; + let mut first_encountered_timestamp = 0; + let mut previous_deduplicated_decommittment_queue_simulator_state = + take_sponge_like_queue_state_from_simulator(&deduplicated_decommittment_queue_simulator); + + let num_items = sorted_decommittment_requests_with_data.len(); + + // self-check that we had a proper oracle + use crate::zk_evm::aux_structures::{MemoryPage, Timestamp}; + let mut tmp: Option<(U256, MemoryPage, Timestamp)> = None; + for (query, _) in sorted_decommittment_requests_with_data.iter() { + if let Some((hash, page, timestamp)) = tmp.as_mut() { + if *hash == normalized_preimage_as_u256(&query.normalized_preimage) { + assert_eq!(*page, query.memory_page); + assert!(query.timestamp.0 > (*timestamp).0); + } else { + assert!(query.is_fresh); + let new_hash = normalized_preimage_as_u256(&query.normalized_preimage); + assert!(new_hash >= *hash); + *hash = new_hash; + *page = query.memory_page; + *timestamp = query.timestamp; + } + } else { + tmp = Some(( + normalized_preimage_as_u256(&query.normalized_preimage), + query.memory_page, + query.timestamp, + )); + } + } + + for (idx, (query, writes)) in sorted_decommittment_requests_with_data + .into_iter() + .enumerate() + { + let last = idx == num_items - 1; + if query.is_fresh { + assert!(writes.len() > 0); + + first_encountered_timestamp = query.timestamp.0; + + previous_deduplicated_decommittment_queue_simulator_state = + take_sponge_like_queue_state_from_simulator( + &deduplicated_decommittment_queue_simulator, + ); + let (_old_tail, intermediate_info) = deduplicated_decommittment_queue_simulator + .push_and_output_intermediate_data(query, round_function); + + deduplicated_decommittment_queue_states.push(intermediate_info); + deduplicated_decommit_requests_with_data.push((query, writes)); + } + + let (_old_tail, intermediate_info) = sorted_decommittment_queue_simulator + .push_and_output_intermediate_data(query, round_function); + + sorted_decommittment_queue_states.push(intermediate_info); + + counter += 1; + + if counter == deduplicator_circuit_capacity { + counter = 0; + + if last { + deduplicated_intermediate_states.push(take_sponge_like_queue_state_from_simulator( + &deduplicated_decommittment_queue_simulator, + )); + } else { + deduplicated_intermediate_states + .push(previous_deduplicated_decommittment_queue_simulator_state.clone()); + } + + let record = sorted_decommittment_queue_simulator + .witness + .pop_back() + .unwrap(); + previous_packed_keys.push(concatenate_key( + normalized_preimage_as_u256(&record.2.normalized_preimage), + record.2.timestamp.0, + )); + + previous_records.push(record.2.reflect()); + first_encountered_timestamps.push(first_encountered_timestamp); + + sorted_decommittment_queue_simulator + .witness + .push_back(record); + } + } + if counter > 0 { + deduplicated_intermediate_states.push(take_sponge_like_queue_state_from_simulator( + &deduplicated_decommittment_queue_simulator, + )); + + previous_packed_keys.push([0u32; PACKED_KEY_LENGTH]); + previous_records.push(DecommitQuery::::placeholder_witness()); + first_encountered_timestamps.push(0); + } + + // create witnesses + + let mut decommittments_deduplicator_witness: Vec< + CodeDecommittmentsDeduplicatorInstanceWitness, + > = vec![]; + + let mut input_passthrough_data = + CodeDecommittmentsDeduplicatorInputData::::placeholder_witness(); + input_passthrough_data.initial_queue_state = + take_sponge_like_queue_state_from_simulator(&unsorted_decommittment_queue_simulator); + input_passthrough_data.sorted_queue_initial_state = + take_sponge_like_queue_state_from_simulator(&sorted_decommittment_queue_simulator); + + let mut output_passthrough_data = + CodeDecommittmentsDeduplicatorOutputData::::placeholder_witness(); + output_passthrough_data.final_queue_state = + take_sponge_like_queue_state_from_simulator(&deduplicated_decommittment_queue_simulator); + + // now we should chunk it by circuits but briefly simulating their logic + + let challenges = produce_fs_challenges::( + take_sponge_like_queue_state_from_simulator(&unsorted_decommittment_queue_simulator).tail, + take_sponge_like_queue_state_from_simulator(&sorted_decommittment_queue_simulator).tail, + round_function, + ); + + let lhs_contributions: Vec<_> = unsorted_decommittment_queue_simulator + .witness + .iter() + .map(|el| &el.0) + .collect(); + let rhs_contributions: Vec<_> = sorted_decommittment_queue_simulator + .witness + .iter() + .map(|el| &el.0) + .collect(); + + let mut lhs_grand_product_chains = vec![]; + let mut rhs_grand_product_chains = vec![]; + + for idx in 0..DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS { + let (lhs_grand_product_chain, rhs_grand_product_chain) = + compute_grand_product_chains::< + F, + DECOMMIT_QUERY_PACKED_WIDTH, + { DECOMMIT_QUERY_PACKED_WIDTH + 1 }, + >(&lhs_contributions, &rhs_contributions, &challenges[idx]); + assert_eq!( + lhs_grand_product_chain.len(), + unsorted_decommittment_queue_simulator.witness.len() + ); + assert_eq!( + lhs_grand_product_chain.len(), + sorted_decommittment_queue_simulator.witness.len() + ); + + lhs_grand_product_chains.push(lhs_grand_product_chain); + rhs_grand_product_chains.push(rhs_grand_product_chain); + } + + // now we need to split them into individual circuits + // splitting is not extra hard here, we walk over iterator over everything and save states on checkpoints + + let num_items = unsorted_decommittment_queue_simulator.num_items; + + let mut input_products = [F::ONE; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS]; + let mut input_products_snapshots = vec![]; + let mut input_witness = vec![]; + let mut input_witness_chunk = VecDeque::new(); + let mut unsorted_intermediate_states = vec![]; + for i in 0..num_items { + let (encoding, old_tail, element) = unsorted_decommittment_queue_simulator + .witness + .front() + .unwrap(); + + let wit = DecommitQueryWitness { + code_hash: normalized_preimage_as_u256(&element.normalized_preimage), + page: element.memory_page.0, + is_first: element.is_fresh, + timestamp: element.timestamp.0, + }; + + input_witness_chunk.push_back((*encoding, wit, *old_tail)); + + unsorted_decommittment_queue_simulator.pop_and_output_intermediate_data(round_function); + if input_witness_chunk.len() == deduplicator_circuit_capacity { + let completed_chunk = std::mem::take(&mut input_witness_chunk); + for j in 0..DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS { + input_products[j] = lhs_grand_product_chains[j][i as usize]; + } + input_witness.push(completed_chunk); + input_products_snapshots.push(input_products); + unsorted_intermediate_states.push(take_sponge_like_queue_state_from_simulator( + &unsorted_decommittment_queue_simulator, + )); + } + } + if input_witness_chunk.len() > 0 { + input_witness.push(input_witness_chunk); + for j in 0..DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS { + input_products[j] = *lhs_grand_product_chains[j].last().unwrap(); + } + input_products_snapshots.push(input_products); + unsorted_intermediate_states.push(take_sponge_like_queue_state_from_simulator( + &unsorted_decommittment_queue_simulator, + )); + } + + assert_eq!(num_items, sorted_decommittment_queue_simulator.num_items); + let mut sorted_products = [F::ONE; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS]; + let mut sorted_products_snapshots = vec![]; + let mut sorted_witness = vec![]; + let mut sorted_witness_chunk = VecDeque::new(); + let mut sorted_intermediate_states = vec![]; + for i in 0..num_items { + let (encoding, old_tail, element) = sorted_decommittment_queue_simulator + .witness + .front() + .unwrap(); + let wit = DecommitQueryWitness { + code_hash: normalized_preimage_as_u256(&element.normalized_preimage), + page: element.memory_page.0, + is_first: element.is_fresh, + timestamp: element.timestamp.0, + }; + + sorted_witness_chunk.push_back((*encoding, wit, *old_tail)); + + sorted_decommittment_queue_simulator.pop_and_output_intermediate_data(round_function); + if sorted_witness_chunk.len() == deduplicator_circuit_capacity { + let completed_chunk = std::mem::take(&mut sorted_witness_chunk); + sorted_witness.push(completed_chunk); + for j in 0..DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS { + sorted_products[j] = rhs_grand_product_chains[j][i as usize]; + } + sorted_products_snapshots.push(sorted_products); + sorted_intermediate_states.push(take_sponge_like_queue_state_from_simulator( + &sorted_decommittment_queue_simulator, + )); + } + } + if sorted_witness_chunk.len() > 0 { + sorted_witness.push(sorted_witness_chunk); + for j in 0..DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS { + sorted_products[j] = *rhs_grand_product_chains[j].last().unwrap(); + } + sorted_products_snapshots.push(sorted_products); + sorted_intermediate_states.push(take_sponge_like_queue_state_from_simulator( + &sorted_decommittment_queue_simulator, + )); + } + + for i in 0..num_circuits { + let mut current_witness = CodeDecommittmentsDeduplicatorInstanceWitness { + closed_form_input: CodeDecommittmentsDeduplicatorInputOutputWitness { + start_flag: i == 0, + completion_flag: i == num_circuits - 1, + observable_input: input_passthrough_data.clone(), + observable_output: CodeDecommittmentsDeduplicatorOutputData::placeholder_witness(), + hidden_fsm_input: CodeDecommittmentsDeduplicatorFSMInputOutput::placeholder_witness( + ), + hidden_fsm_output: + CodeDecommittmentsDeduplicatorFSMInputOutput::placeholder_witness(), + }, + initial_queue_witness: FullStateCircuitQueueRawWitness::< + F, + DecommitQuery, + FULL_SPONGE_QUEUE_STATE_WIDTH, + DECOMMIT_QUERY_PACKED_WIDTH, + > { + elements: VecDeque::new(), + }, + sorted_queue_witness: FullStateCircuitQueueRawWitness::< + F, + DecommitQuery, + FULL_SPONGE_QUEUE_STATE_WIDTH, + DECOMMIT_QUERY_PACKED_WIDTH, + > { + elements: VecDeque::new(), + }, + }; + + if i == num_circuits - 1 { + // set passthrough output + current_witness.closed_form_input.observable_output = output_passthrough_data.clone(); + } + let unsorted_circuit_witness = input_witness[i] + .iter() + .map(|el| (el.1.clone(), el.2)) + .collect(); + let sorted_circuit_witness = sorted_witness[i] + .iter() + .map(|el| (el.1.clone(), el.2)) + .collect(); + current_witness.initial_queue_witness = FullStateCircuitQueueRawWitness::< + F, + DecommitQuery, + FULL_SPONGE_QUEUE_STATE_WIDTH, + DECOMMIT_QUERY_PACKED_WIDTH, + > { + elements: unsorted_circuit_witness, + }; + current_witness.sorted_queue_witness = FullStateCircuitQueueRawWitness::< + F, + DecommitQuery, + FULL_SPONGE_QUEUE_STATE_WIDTH, + DECOMMIT_QUERY_PACKED_WIDTH, + > { + elements: sorted_circuit_witness, + }; + + if let Some(previous_witness) = decommittments_deduplicator_witness.last() { + current_witness.closed_form_input.hidden_fsm_input = + previous_witness.closed_form_input.hidden_fsm_output.clone(); + } + + current_witness.closed_form_input.hidden_fsm_output = + CodeDecommittmentsDeduplicatorFSMInputOutputWitness { + initial_queue_state: unsorted_intermediate_states[i].clone(), + sorted_queue_state: sorted_intermediate_states[i].clone(), + final_queue_state: deduplicated_intermediate_states[i].clone(), + + lhs_accumulator: input_products_snapshots[i], + rhs_accumulator: sorted_products_snapshots[i], + + previous_packed_key: previous_packed_keys[i], + previous_record: previous_records[i].clone(), + first_encountered_timestamp: first_encountered_timestamps[i], + }; + + decommittments_deduplicator_witness.push(current_witness); + } + + ( + all_decommittment_queue_states, + decommittments_deduplicator_witness, + DecommiterCircuitProcessingInputs { + deduplicated_decommit_requests_with_data, + deduplicated_decommittment_queue_simulator, + deduplicated_decommittment_queue_states, + }, + ) +} + +fn concatenate_key(hash: U256, timestamp: u32) -> [u32; PACKED_KEY_LENGTH] { + let hash_as_u32_le = decompose_u256_as_u32x8(hash); + [ + timestamp, + hash_as_u32_le[0], + hash_as_u32_le[1], + hash_as_u32_le[2], + hash_as_u32_le[3], + hash_as_u32_le[4], + hash_as_u32_le[5], + hash_as_u32_le[6], + hash_as_u32_le[7], + ] +} diff --git a/crates/zkevm_test_harness/src/witness/individual_circuits/mod.rs b/crates/zkevm_test_harness/src/witness/individual_circuits/mod.rs new file mode 100644 index 0000000..50e6ee3 --- /dev/null +++ b/crates/zkevm_test_harness/src/witness/individual_circuits/mod.rs @@ -0,0 +1,23 @@ +use super::*; +use crate::witness::utils::*; + +use crate::boojum::algebraic_props::round_function::AlgebraicRoundFunction; +use crate::boojum::field::SmallField; +use crate::boojum::gadgets::queue::CircuitQueueRawWitness; +use crate::boojum::gadgets::traits::allocatable::CSAllocatable; +use crate::boojum::gadgets::traits::round_function::*; +use crate::zkevm_circuits::base_structures::precompile_input_outputs::*; +use crate::zkevm_circuits::base_structures::vm_state::FULL_SPONGE_QUEUE_STATE_WIDTH; +use crate::zkevm_circuits::fsm_input_output::*; +use crate::zkevm_circuits::DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS; +use std::collections::VecDeque; + +pub(crate) mod data_hasher_and_merklizer; +pub(crate) mod eip4844_repack; +pub mod events_sort_dedup; +pub(crate) mod log_demux; +pub(crate) mod main_vm; +pub(crate) mod memory_related; +pub(crate) mod storage_application; +pub(crate) mod storage_sort_dedup; +pub(crate) mod transient_storage_sorter; diff --git a/crates/zkevm_test_harness/src/witness/individual_circuits/storage_application.rs b/crates/zkevm_test_harness/src/witness/individual_circuits/storage_application.rs new file mode 100644 index 0000000..a44ee93 --- /dev/null +++ b/crates/zkevm_test_harness/src/witness/individual_circuits/storage_application.rs @@ -0,0 +1,283 @@ +use std::sync::Arc; + +use self::toolset::GeometryConfig; +use self::witness::postprocessing::FirstAndLastCircuitWitness; +use crate::witness::postprocessing::observable_witness::StorageApplicationObservableWitness; + +use super::*; +use crate::boojum::gadgets::keccak256::{self}; +use crate::witness::individual_circuits::memory_related::keccak256_round_function::encode_keccak256_inner_state; +use crate::witness::postprocessing::CircuitMaker; +use crate::witness::tree::*; +use crate::zk_evm::sha3::Keccak256; +use crate::zk_evm::zk_evm_abstractions::precompiles::keccak256::transmute_state; +use crate::zkevm_circuits::base_structures::state_diff_record::NUM_KECCAK256_ROUNDS_PER_RECORD_ACCUMULATION; +use crate::zkevm_circuits::storage_application::input::*; +use blake2::Blake2s256; +use circuit_definitions::circuit_definitions::base_layer::{ + StorageApplicationInstanceSynthesisFunction, ZkSyncBaseLayerCircuit, +}; +use circuit_definitions::encodings::recursion_request::RecursionQueueSimulator; +use circuit_definitions::encodings::state_diff_record::StateDiffRecord; +use circuit_definitions::encodings::LogQueueSimulator; +use circuit_definitions::zkevm_circuits::scheduler::aux::BaseLayerCircuitType; +use oracle::WitnessGenerationArtifact; +use tracing; +use zk_evm::aux_structures::LogQuery; + +use crate::sha3::Digest; + +pub(crate) fn decompose_into_storage_application_witnesses( + deduplicated_rollup_storage_queue_simulator: LogQueueSimulator, + deduplicated_rollup_storage_queries: Vec, + mut tree: impl BinarySparseStorageTree<256, 32, 32, 8, 32, Blake2s256, ZkSyncStorageLeaf>, + round_function: &Poseidon2Goldilocks, + num_rounds_per_circuit: usize, + geometry: &GeometryConfig, + mut artifacts_callback: CB, +) -> ( + FirstAndLastCircuitWitness>, + Vec>, +) { + const SHARD_ID_TO_PROCEED: u8 = 0; // rollup shard ID + + let circuit_type = BaseLayerCircuitType::StorageApplicator; + let mut maker = CircuitMaker::new( + geometry.cycles_per_storage_application, + round_function.clone(), + ); + + if deduplicated_rollup_storage_queries.is_empty() { + let ( + storage_application_circuits, + _queue_simulator, + storage_application_circuits_compact_forms_witnesses, + ) = maker.into_results(); + + return ( + storage_application_circuits, + storage_application_circuits_compact_forms_witnesses, + ); + } + + // first split into chunks of work for every circuit + + let mut total_tree_queries = 0; + + let mut chunks = vec![]; + + let mut current_chunk = vec![]; + + for el in deduplicated_rollup_storage_queries.iter() { + if el.rw_flag { + total_tree_queries += 2; + } else { + total_tree_queries += 1; + } + + current_chunk.push(*el); + + // we leave 1 to make a final application of "write" + if total_tree_queries >= num_rounds_per_circuit - 1 { + let current = std::mem::take(&mut current_chunk); + assert!(current.len() <= num_rounds_per_circuit); + chunks.push(current); + total_tree_queries = 0; + } + } + + if total_tree_queries != 0 { + let current = std::mem::take(&mut current_chunk); + assert!(current.len() <= num_rounds_per_circuit); + chunks.push(current); + } + + // now proceed as FSM over individual circuits + + let mut initial_fsm_state = StorageApplicationFSMInputOutput::placeholder_witness(); + // queue states are trivial for a start + + let mut hasher = ::new(); + + let mut storage_queue_state_idx = 0; + + let num_chunks = chunks.len(); + + let mut storage_application_simulator = deduplicated_rollup_storage_queue_simulator.clone(); + + tracing::debug!( + "Initial enumeration index = {}", + tree.next_enumeration_index() + ); + tracing::debug!("Initial root = {}", hex::encode(&tree.root())); + + for (idx, chunk) in chunks.into_iter().enumerate() { + let is_last = idx == num_chunks - 1; + + let mut merkle_paths = VecDeque::new(); + let mut leaf_enumeration_index_for_read = VecDeque::new(); + + let mut passthrough_input = StorageApplicationInputData::placeholder_witness(); + if idx == 0 { + passthrough_input.initial_next_enumeration_counter = + u64_as_u32_le(tree.next_enumeration_index()); + passthrough_input.initial_root_hash = tree.root(); + passthrough_input.shard = SHARD_ID_TO_PROCEED; + passthrough_input.storage_application_log_state = + take_queue_state_from_simulator(&deduplicated_rollup_storage_queue_simulator); + } + + let chunk_len = chunk.len(); + + // apply one by one in chunk + for el in chunk.into_iter() { + let _ = storage_application_simulator.pop_and_output_intermediate_data(round_function); + + let key = el.derive_final_address(); + if el.rw_flag { + // by convension we have read and write both + let read_query = tree.get_leaf(&key); + // assert!(tree.verify_inclusion_proxy(&tree.root(), &read_query)); + let mut buffer = [0u8; 32]; + el.read_value.to_big_endian(&mut buffer); + assert_eq!(&buffer, read_query.leaf.value(), "While writing: divergent leaf read value for index {}: expecting to read {}, got {}", hex::encode(&key), hex::encode(&buffer), hex::encode(&read_query.leaf.value())); + + let leaf_index = read_query.leaf.current_index(); + leaf_enumeration_index_for_read.push_back(leaf_index); + + let mut leaf = ZkSyncStorageLeaf::empty(); + el.written_value.to_big_endian(leaf.value_ref_mut()); + // we expect that tree properly updates enumeration index on insert + let write_query = tree.insert_leaf(&key, leaf); + assert!(tree.verify_inclusion_proxy(&tree.root(), &write_query)); + + assert_eq!(&*read_query.merkle_path, &*write_query.merkle_path); + + let LeafQuery { + leaf: _, + first_write: _, + index: _, + merkle_path, + } = write_query; + + merkle_paths.push_back((*merkle_path).into_iter().collect()); + + // NOTE: we need enumeration index BEFORE writing + let state_diff = StateDiffRecord { + address: el.address, + key: el.key, + derived_key: key, + enumeration_index: read_query.leaf.current_index(), + initial_value: el.read_value, + final_value: el.written_value, + }; + + let mut extended_state_diff_encoding = [0u8; keccak256::KECCAK_RATE_BYTES + * NUM_KECCAK256_ROUNDS_PER_RECORD_ACCUMULATION]; + let packed_encoding = state_diff.encode(); + extended_state_diff_encoding[0..packed_encoding.len()] + .copy_from_slice(&packed_encoding); + // dbg!(hex::encode(&extended_state_diff_encoding)); + + Digest::update(&mut hasher, &extended_state_diff_encoding); + + // dbg!(transmute_state(hasher.clone())); + } else { + // read + let read_query = tree.get_leaf(&key); + assert!(tree.verify_inclusion_proxy(&tree.root(), &read_query)); + let LeafQuery { + leaf, + first_write: _, + index: _, + merkle_path, + } = read_query; + let leaf_index = leaf.current_index(); + leaf_enumeration_index_for_read.push_back(leaf_index); + + let mut buffer = [0u8; 32]; + el.read_value.to_big_endian(&mut buffer); + assert_eq!(&buffer, leaf.value(), "While reading: divergent leaf value for index {}: expecting to read {}, got {}", hex::encode(&key), hex::encode(&buffer), hex::encode(&leaf.value())); + + merkle_paths.push_back((*merkle_path).into_iter().collect()); + } + } + + assert_eq!(leaf_enumeration_index_for_read.len(), merkle_paths.len()); + + let state = transmute_state(hasher.clone()); + + let mut final_fsm_state = StorageApplicationFSMInputOutput::placeholder_witness(); + final_fsm_state.next_enumeration_counter = u64_as_u32_le(tree.next_enumeration_index()); + final_fsm_state.current_root_hash = tree.root(); + final_fsm_state.current_storage_application_log_state = + take_queue_state_from_simulator(&storage_application_simulator); + final_fsm_state.current_diffs_keccak_accumulator_state = + encode_keccak256_inner_state(state); + + let wit = transform_queue_witness( + deduplicated_rollup_storage_queue_simulator + .witness + .iter() + .skip(storage_queue_state_idx) + .take(chunk_len), + ); + + storage_queue_state_idx += chunk_len; + + let mut passthrough_output = StorageApplicationOutputData::placeholder_witness(); + if is_last { + let mut accumulator = [0u8; 32]; + accumulator.copy_from_slice(hasher.clone().finalize().as_slice()); + + passthrough_output.new_next_enumeration_counter = + u64_as_u32_le(tree.next_enumeration_index()); + passthrough_output.new_root_hash = tree.root(); + passthrough_output.state_diffs_keccak256_hash = accumulator; + } + + let input = StorageApplicationCircuitInstanceWitness { + closed_form_input: StorageApplicationInputOutputWitness { + start_flag: idx == 0, + completion_flag: is_last, + observable_input: passthrough_input, + observable_output: passthrough_output, + hidden_fsm_input: initial_fsm_state.clone(), + hidden_fsm_output: final_fsm_state.clone(), + }, + storage_queue_witness: CircuitQueueRawWitness { + elements: wit.elements.into_inner().unwrap(), + }, + merkle_paths: merkle_paths, + leaf_indexes_for_reads: leaf_enumeration_index_for_read, + }; + + initial_fsm_state = final_fsm_state.clone(); + + artifacts_callback(WitnessGenerationArtifact::BaseLayerCircuit( + ZkSyncBaseLayerCircuit::StorageApplication(maker.process(input, circuit_type)), + )); + } + + let ( + storage_application_circuits, + queue_simulator, + storage_application_circuits_compact_forms_witnesses, + ) = maker.into_results(); + artifacts_callback(WitnessGenerationArtifact::RecursionQueue(( + circuit_type as u64, + queue_simulator, + storage_application_circuits_compact_forms_witnesses.clone(), + ))); + + tracing::debug!( + "Final enumeration index = {}", + tree.next_enumeration_index() + ); + tracing::debug!("Final root = {}", hex::encode(&tree.root())); + + ( + storage_application_circuits, + storage_application_circuits_compact_forms_witnesses, + ) +} diff --git a/crates/zkevm_test_harness/src/witness/individual_circuits/storage_sort_dedup.rs b/crates/zkevm_test_harness/src/witness/individual_circuits/storage_sort_dedup.rs new file mode 100644 index 0000000..b0618d8 --- /dev/null +++ b/crates/zkevm_test_harness/src/witness/individual_circuits/storage_sort_dedup.rs @@ -0,0 +1,674 @@ +use std::default; + +use super::*; +use crate::witness::artifacts::LogQueueStates; +use crate::witness::aux_data_structs::one_per_circuit_accumulator::LastPerCircuitAccumulator; +use crate::zk_evm::aux_structures::LogQuery; +use crate::zkevm_circuits::base_structures::log_query::LOG_QUERY_PACKED_WIDTH; +use crate::zkevm_circuits::base_structures::vm_state::QUEUE_STATE_WIDTH; +use crate::zkevm_circuits::storage_validity_by_grand_product::input::*; +use crate::zkevm_circuits::DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS; +use circuit_definitions::encodings::*; + +pub(crate) fn compute_storage_dedup_and_sort< + F: SmallField, + R: BuildableCircuitRoundFunction + AlgebraicRoundFunction, +>( + rollup_storage_queries: Vec, + demuxed_rollup_storage_queue: LogQueueStates, + per_circuit_capacity: usize, + round_function: &R, +) -> ( + LogQueueSimulator, + Vec, + Vec>, +) { + // trivial case if nothing to process + + const SHARD_ID_TO_PROCEED: u8 = 0; // rollup shard ID + + if rollup_storage_queries.is_empty() { + return (LogQueueSimulator::::empty(), vec![], vec![]); + } + + // first we sort the storage log (only storage now) by composite key + + use crate::witness::sort_storage_access::sort_storage_access_queries; + + let total_amount_of_queries = rollup_storage_queries.len(); + + let (sorted_storage_queries_with_extra_timestamp, deduplicated_rollup_storage_queries) = + sort_storage_access_queries(&rollup_storage_queries); + + let mut sorted_log_simulator_states_accumulator = LastPerCircuitAccumulator::with_flat_capacity( + per_circuit_capacity, + total_amount_of_queries, + ); + let mut intermediate_sorted_log_simulator = + LogWithExtendedEnumerationQueueSimulator::::with_capacity( + sorted_storage_queries_with_extra_timestamp.len(), + ); + for el in sorted_storage_queries_with_extra_timestamp.into_iter() { + let (_, intermediate_state) = intermediate_sorted_log_simulator + .push_and_output_intermediate_data(el.clone(), round_function); + + sorted_log_simulator_states_accumulator.push(intermediate_state); + } + + let sorted_log_simulator_states_chunk_final_states = + sorted_log_simulator_states_accumulator.into_circuits(); + let unsorted_log_simulator_states_chunk_final_states = demuxed_rollup_storage_queue + .states_accumulator + .into_circuits(); + + let unsorted_simulator_final_state = + take_queue_state_from_simulator(&demuxed_rollup_storage_queue.simulator); + + let intermediate_sorted_log_simulator_final_state = + take_queue_state_from_simulator(&intermediate_sorted_log_simulator); + + // now just implement the logic to sort and deduplicate + + let mut result_queue_simulator = LogQueueSimulator::::empty(); + + // compute sequence of states for grand product accumulation + + // -------------------- + + // now we should chunk it by circuits but briefly simulating their logic + + let challenges = produce_fs_challenges::< + F, + R, + QUEUE_STATE_WIDTH, + { LOG_QUERY_PACKED_WIDTH + 1 }, + DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS, + >( + unsorted_simulator_final_state.tail.clone(), + intermediate_sorted_log_simulator_final_state.tail.clone(), + round_function, + ); + + // since encodings of the elements provide all the information necessary to perform soring argument, + // we use them naively + + assert_eq!( + unsorted_simulator_final_state.tail.length, + intermediate_sorted_log_simulator_final_state.tail.length + ); + + let lhs_contributions: Vec<_> = rollup_storage_queries + .into_iter() + .enumerate() + .map(|(idx, el)| { + let extended_query = LogQueryWithExtendedEnumeration { + raw_query: el, + extended_timestamp: idx as u32, + }; + + >::encoding_witness(&extended_query) + }) + .collect(); + let lhs_contributions_refs = lhs_contributions.iter().collect(); + + let rhs_contributions: Vec<_> = intermediate_sorted_log_simulator + .witness + .iter() + .map(|el| &el.0) + .collect(); + + // -------------------- + + // compute chains themselves + + let mut lhs_grand_product_chains = vec![]; + let mut rhs_grand_product_chains = vec![]; + + for idx in 0..DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS { + let (lhs_grand_product_chain, rhs_grand_product_chain) = compute_grand_product_chains::< + F, + LOG_QUERY_PACKED_WIDTH, + { LOG_QUERY_PACKED_WIDTH + 1 }, + >( + &lhs_contributions_refs, + &rhs_contributions, + &challenges[idx], + ); + + assert_eq!( + lhs_grand_product_chain.len(), + demuxed_rollup_storage_queue.simulator.witness.len() + ); + assert_eq!( + rhs_grand_product_chain.len(), + intermediate_sorted_log_simulator.witness.len() + ); + + lhs_grand_product_chains.push(lhs_grand_product_chain); + rhs_grand_product_chains.push(rhs_grand_product_chain); + } + + let transposed_lhs_chains = transpose_chunks(&lhs_grand_product_chains, per_circuit_capacity); + let transposed_rhs_chains = transpose_chunks(&rhs_grand_product_chains, per_circuit_capacity); + + // now we need to split them into individual circuits + // splitting is not extra hard here, we walk over iterator over everything and save states on checkpoints + + // -------------------- + + // in general we have everything ready, just form the witness + + // as usual we simulate logic of the circuit and chunk. It's a little less convenient here than in RAM since we + // have to chunk based on 2 queues, but also guess the result of the 3rd queue, but managable + + assert!(demuxed_rollup_storage_queue + .simulator + .witness + .as_slices() + .1 + .is_empty()); + assert!(intermediate_sorted_log_simulator + .witness + .as_slices() + .1 + .is_empty()); + + let it = unsorted_log_simulator_states_chunk_final_states + .into_iter() + .zip(sorted_log_simulator_states_chunk_final_states) + .zip(transposed_lhs_chains.into_iter()) + .zip(transposed_rhs_chains.into_iter()) + .zip( + demuxed_rollup_storage_queue + .simulator + .witness + .as_slices() + .0 + .chunks(per_circuit_capacity), + ) + .zip( + intermediate_sorted_log_simulator + .witness + .as_slices() + .0 + .chunks(per_circuit_capacity), + ); + + // now trivial transformation into desired data structures, + // and we are all good + + let num_circuits = it.len(); + let mut results = vec![]; + + let mut current_lhs_product = [F::ONE; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS]; + let mut current_rhs_product = [F::ONE; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS]; + let mut previous_comparison_key = [0u32; STORAGE_VALIDITY_CHECK_PACKED_KEY_LENGTH]; + let mut previous_key = U256::zero(); + let mut previous_timestamp = 0u32; + let mut cycle_idx = 0u32; + use crate::ethereum_types::Address; + let mut previous_address = Address::default(); + + use crate::ethereum_types::U256; + + let mut this_cell_has_explicit_read_and_rollback_depth_zero = false; + let mut this_cell_base_value = U256::zero(); + let mut this_cell_current_value = U256::zero(); + let mut this_cell_current_depth = 0u32; + + let mut deduplicated_queries_it = deduplicated_rollup_storage_queries.iter(); + + let mut current_final_sorted_queue_state = + take_queue_state_from_simulator(&result_queue_simulator); + + for ( + idx, + ( + ( + ( + ((unsorted_sponge_states, sorted_sponge_states), lhs_grand_product), + rhs_grand_product, + ), + unsorted_states, + ), + sorted_states, + ), + ) in it.enumerate() + { + // we need witnesses to pop elements from the front of the queue + + let unsorted_queue_witness: VecDeque<_> = unsorted_states + .iter() + .map(|(_encoding, old_tail, element)| { + let as_storage_log = element.reflect(); + + (as_storage_log, *old_tail) + }) + .collect(); + + let unsorted_witness = CircuitQueueRawWitness::< + F, + zkevm_circuits::base_structures::log_query::LogQuery, + 4, + LOG_QUERY_PACKED_WIDTH, + > { + elements: unsorted_queue_witness, + }; + + let intermediate_sorted_queue_witness: VecDeque<_> = sorted_states + .iter() + .map(|(_encoding, old_tail, element)| { + let as_timestamped_storage_witness = + log_query_into_timestamped_storage_record_witness(element); + + (as_timestamped_storage_witness, *old_tail) + }) + .collect(); + + let intermediate_sorted_queue_witness = CircuitQueueRawWitness::< + F, + zkevm_circuits::storage_validity_by_grand_product::TimestampedStorageLogRecord, + 4, + LOG_QUERY_PACKED_WIDTH, + > { + elements: intermediate_sorted_queue_witness, + }; + + // now we need to have final grand product value that will also become an input for the next circuit + + let is_first = idx == 0; + let is_last = idx == num_circuits - 1; + + let last_unsorted_state = unsorted_sponge_states; + let last_sorted_state = sorted_sponge_states; + + let accumulated_lhs: [F; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS] = lhs_grand_product + .iter() + .map(|el| *el.last().unwrap()) + .collect::>() + .try_into() + .unwrap(); + let accumulated_rhs: [F; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS] = rhs_grand_product + .iter() + .map(|el| *el.last().unwrap()) + .collect::>() + .try_into() + .unwrap(); + + let last_sorted_query = &sorted_states.last().unwrap().2; + let last_comparison_key = comparison_key(&last_sorted_query.raw_query); + let last_key = last_sorted_query.raw_query.key; + let last_address = last_sorted_query.raw_query.address; + let last_timestamp = last_sorted_query.extended_timestamp; + + // simulate the logic + let ( + new_this_cell_has_explicit_read_and_rollback_depth_zero, + new_this_cell_base_value, + new_this_cell_current_value, + new_this_cell_current_depth, + ) = { + let mut current_address = previous_address; + let mut current_key = previous_key; + let mut new_this_cell_has_explicit_read_and_rollback_depth_zero = + this_cell_has_explicit_read_and_rollback_depth_zero; + let mut new_this_cell_base_value = this_cell_base_value; + let mut new_this_cell_current_value = this_cell_current_value; + let mut new_this_cell_current_depth = this_cell_current_depth; + + let num_items_in_chunk = sorted_states.len(); + + let mut exhausted = false; + + for (sub_idx, (_encoding, _previous_tail, item)) in sorted_states.iter().enumerate() { + let first_ever = sub_idx == 0 && is_first; + let is_last_ever = (sub_idx == num_items_in_chunk - 1) && is_last; + + if first_ever { + // only set current values + if item.raw_query.rw_flag == true { + assert!(item.raw_query.rollback == false); + new_this_cell_current_depth = 1; + new_this_cell_has_explicit_read_and_rollback_depth_zero = false; + } else { + new_this_cell_current_depth = 0; + new_this_cell_has_explicit_read_and_rollback_depth_zero = true; + } + + new_this_cell_base_value = item.raw_query.read_value; + if item.raw_query.rw_flag == true { + new_this_cell_current_value = item.raw_query.written_value; + } else { + new_this_cell_current_value = item.raw_query.read_value; + } + } else { + // main cycle + + let same_cell = current_address == item.raw_query.address + && current_key == item.raw_query.key; + + if same_cell { + // proceed previous one + if item.raw_query.rw_flag == true { + // write or rollback + if item.raw_query.rollback == false { + new_this_cell_current_depth += 1; + new_this_cell_current_value = item.raw_query.written_value; + } else { + new_this_cell_current_depth -= 1; + new_this_cell_current_value = item.raw_query.read_value; + } + } else { + // read + if new_this_cell_current_depth == 0 { + new_this_cell_has_explicit_read_and_rollback_depth_zero = + true || new_this_cell_has_explicit_read_and_rollback_depth_zero; + } + new_this_cell_current_value = item.raw_query.read_value; + } + } else { + // finish with previous one and start a new one + if new_this_cell_current_depth > 0 { + // net write + if let Some(next_query) = deduplicated_queries_it.next() { + if new_this_cell_current_value == new_this_cell_base_value { + // protective read, to ensure that if we follow + // the claim of initial value and do not overwrite, + // then we are consistent + assert!(next_query.rw_flag == false); + assert!(next_query.shard_id == SHARD_ID_TO_PROCEED); + assert!(next_query.address == current_address); + assert!(next_query.key == current_key); + assert!(next_query.read_value == new_this_cell_current_value); + assert!( + next_query.written_value == new_this_cell_current_value + ); + } else { + // plain write + assert!(next_query.rw_flag == true); + assert!(next_query.shard_id == SHARD_ID_TO_PROCEED); + assert!(next_query.address == current_address); + assert!(next_query.key == current_key); + assert!(next_query.read_value == new_this_cell_base_value); + assert!( + next_query.written_value == new_this_cell_current_value + ); + } + + let _ = result_queue_simulator + .push_and_output_intermediate_data(*next_query, round_function); + } else { + // empty cycles + assert!(is_last); + assert!(exhausted == false); + exhausted = true; + } + } else { + if new_this_cell_has_explicit_read_and_rollback_depth_zero == true { + // protective read + if let Some(next_query) = deduplicated_queries_it.next() { + assert!(next_query.rw_flag == false); + assert!(next_query.shard_id == SHARD_ID_TO_PROCEED); + assert!(next_query.address == current_address); + assert!(next_query.key == current_key); + assert!(next_query.read_value == new_this_cell_base_value); + assert!(next_query.written_value == new_this_cell_base_value); + let _ = result_queue_simulator + .push_and_output_intermediate_data( + *next_query, + round_function, + ); + } else { + assert!(is_last); + assert!(exhausted == false); + exhausted = true; + } + } + } + + // start for new one + if item.raw_query.rw_flag == true { + assert!(item.raw_query.rollback == false); + new_this_cell_current_depth = 1; + new_this_cell_has_explicit_read_and_rollback_depth_zero = false; + } else { + new_this_cell_current_depth = 0; + new_this_cell_has_explicit_read_and_rollback_depth_zero = true; + } + + new_this_cell_base_value = item.raw_query.read_value; + if item.raw_query.rw_flag == true { + new_this_cell_current_value = item.raw_query.written_value; + } else { + new_this_cell_current_value = item.raw_query.read_value; + } + } + } + + // always update keys + current_address = item.raw_query.address; + current_key = item.raw_query.key; + + if is_last_ever { + if exhausted == false { + if new_this_cell_current_depth > 0 { + // net write + let next_query = deduplicated_queries_it.next().unwrap(); + if new_this_cell_current_value == new_this_cell_base_value { + // protective read + assert!(next_query.rw_flag == false); + assert!(next_query.shard_id == SHARD_ID_TO_PROCEED); + assert!(next_query.address == current_address); + assert!(next_query.key == current_key); + assert!(next_query.read_value == new_this_cell_current_value); + assert!(next_query.written_value == new_this_cell_current_value); + } else { + assert!(next_query.rw_flag == true); + assert!(next_query.shard_id == SHARD_ID_TO_PROCEED); + assert!(next_query.address == current_address); + assert!(next_query.key == current_key); + assert!(next_query.read_value == new_this_cell_base_value); + assert!(next_query.written_value == new_this_cell_current_value); + } + + let _ = result_queue_simulator + .push_and_output_intermediate_data(*next_query, round_function); + } else { + if new_this_cell_has_explicit_read_and_rollback_depth_zero == true { + // protective read + let next_query = deduplicated_queries_it.next().unwrap(); + assert!(next_query.rw_flag == false); + assert!(next_query.shard_id == SHARD_ID_TO_PROCEED); + assert!(next_query.address == current_address); + assert!(next_query.key == current_key); + assert!(next_query.read_value == new_this_cell_base_value); + assert!(next_query.written_value == new_this_cell_base_value); + let _ = result_queue_simulator + .push_and_output_intermediate_data(*next_query, round_function); + } + } + } + } + } + + ( + new_this_cell_has_explicit_read_and_rollback_depth_zero, + new_this_cell_base_value, + new_this_cell_current_value, + new_this_cell_current_depth, + ) + }; + + use crate::boojum::gadgets::queue::QueueState; + let placeholder_witness = QueueState::::placeholder_witness(); + + let (current_unsorted_queue_state, current_intermediate_sorted_queue_state) = results + .last() + .map(|el: &StorageDeduplicatorInstanceWitness| { + let tmp = &el.closed_form_input.hidden_fsm_output; + + ( + tmp.current_unsorted_queue_state.clone(), + tmp.current_intermediate_sorted_queue_state.clone(), + ) + }) + .unwrap_or((placeholder_witness.clone(), placeholder_witness)); + + // assert_eq!(current_unsorted_queue_state.length, current_sorted_queue_state.length); + + // we use current final state as the intermediate head + let mut final_unsorted_state = transform_queue_state(last_unsorted_state); + final_unsorted_state.head = final_unsorted_state.tail.tail; + final_unsorted_state.tail.tail = unsorted_simulator_final_state.tail.tail; + final_unsorted_state.tail.length = + unsorted_simulator_final_state.tail.length - final_unsorted_state.tail.length; + + let mut final_intermediate_sorted_state = transform_queue_state(last_sorted_state); + final_intermediate_sorted_state.head = last_sorted_state.tail; + final_intermediate_sorted_state.tail.tail = + intermediate_sorted_log_simulator_final_state.tail.tail; + final_intermediate_sorted_state.tail.length = + intermediate_sorted_log_simulator_final_state.tail.length - last_sorted_state.num_items; + + assert_eq!( + final_unsorted_state.tail.length, + final_intermediate_sorted_state.tail.length + ); + + let final_cycle_idx = cycle_idx + per_circuit_capacity as u32; + + let last_final_sorted_queue_state = + take_queue_state_from_simulator(&result_queue_simulator); + + let mut instance_witness = StorageDeduplicatorInstanceWitness { + closed_form_input: ClosedFormInputWitness { + start_flag: is_first, + completion_flag: is_last, + observable_input: StorageDeduplicatorInputDataWitness { + shard_id_to_process: SHARD_ID_TO_PROCEED, + unsorted_log_queue_state: unsorted_simulator_final_state.clone(), + intermediate_sorted_queue_state: intermediate_sorted_log_simulator_final_state + .clone(), + }, + observable_output: StorageDeduplicatorOutputData::placeholder_witness(), + hidden_fsm_input: StorageDeduplicatorFSMInputOutputWitness { + lhs_accumulator: current_lhs_product, + rhs_accumulator: current_rhs_product, + current_unsorted_queue_state, + current_intermediate_sorted_queue_state, + current_final_sorted_queue_state: current_final_sorted_queue_state.clone(), + cycle_idx: cycle_idx, + previous_key: previous_key, + previous_address: previous_address, + previous_timestamp, + previous_packed_key: previous_comparison_key, + this_cell_has_explicit_read_and_rollback_depth_zero, + this_cell_base_value: this_cell_base_value, + this_cell_current_value: this_cell_current_value, + this_cell_current_depth, + }, + hidden_fsm_output: StorageDeduplicatorFSMInputOutputWitness { + lhs_accumulator: accumulated_lhs, + rhs_accumulator: accumulated_rhs, + current_unsorted_queue_state: final_unsorted_state, + current_intermediate_sorted_queue_state: final_intermediate_sorted_state, + current_final_sorted_queue_state: last_final_sorted_queue_state.clone(), + cycle_idx: final_cycle_idx, + previous_packed_key: last_comparison_key.0, + previous_key: last_key, + previous_address: last_address, + previous_timestamp: last_timestamp, + this_cell_has_explicit_read_and_rollback_depth_zero: + new_this_cell_has_explicit_read_and_rollback_depth_zero, + this_cell_base_value: new_this_cell_base_value, + this_cell_current_value: new_this_cell_current_value, + this_cell_current_depth: new_this_cell_current_depth, + }, + }, + unsorted_queue_witness: unsorted_witness, + intermediate_sorted_queue_witness: intermediate_sorted_queue_witness, + }; + + assert_eq!( + instance_witness.unsorted_queue_witness.elements.len(), + instance_witness + .intermediate_sorted_queue_witness + .elements + .len() + ); + + if sorted_states.len() % per_circuit_capacity != 0 { + assert!(is_last); + // circuit does padding, so all previous values must be reset + instance_witness + .closed_form_input + .hidden_fsm_output + .previous_packed_key = [0u32; STORAGE_VALIDITY_CHECK_PACKED_KEY_LENGTH]; + instance_witness + .closed_form_input + .hidden_fsm_output + .previous_key = U256::zero(); + instance_witness + .closed_form_input + .hidden_fsm_output + .previous_address = Address::default(); + instance_witness + .closed_form_input + .hidden_fsm_output + .previous_timestamp = 0u32; + instance_witness + .closed_form_input + .hidden_fsm_output + .this_cell_has_explicit_read_and_rollback_depth_zero = false; + } else { + if is_last { + // at the very end of the work circuit resets this_cell_has_explicit_read_and_rollback_depth_zero + // in any case + instance_witness + .closed_form_input + .hidden_fsm_output + .this_cell_has_explicit_read_and_rollback_depth_zero = false; + } + } + + current_lhs_product = accumulated_lhs; + current_rhs_product = accumulated_rhs; + + previous_comparison_key = last_comparison_key.0; + previous_key = last_key; + previous_timestamp = last_timestamp; + previous_address = last_address; + + this_cell_has_explicit_read_and_rollback_depth_zero = + new_this_cell_has_explicit_read_and_rollback_depth_zero; + this_cell_base_value = new_this_cell_base_value; + this_cell_current_value = new_this_cell_current_value; + this_cell_current_depth = new_this_cell_current_depth; + + current_final_sorted_queue_state = last_final_sorted_queue_state; + + cycle_idx = final_cycle_idx; + + results.push(instance_witness); + } + + assert!(deduplicated_queries_it.next().is_none()); + + let final_sorted_queue_state = take_queue_state_from_simulator(&result_queue_simulator); + + results + .last_mut() + .unwrap() + .closed_form_input + .observable_output + .final_sorted_queue_state = final_sorted_queue_state.clone(); + + ( + result_queue_simulator, + deduplicated_rollup_storage_queries, + results, + ) +} diff --git a/crates/zkevm_test_harness/src/witness/individual_circuits/transient_storage_sorter.rs b/crates/zkevm_test_harness/src/witness/individual_circuits/transient_storage_sorter.rs new file mode 100644 index 0000000..e595943 --- /dev/null +++ b/crates/zkevm_test_harness/src/witness/individual_circuits/transient_storage_sorter.rs @@ -0,0 +1,506 @@ +use super::*; +use crate::witness::artifacts::LogQueueStates; +use crate::witness::aux_data_structs::one_per_circuit_accumulator::LastPerCircuitAccumulator; +use crate::zk_evm::aux_structures::*; +use crate::zkevm_circuits::base_structures::log_query::LOG_QUERY_PACKED_WIDTH; +use crate::zkevm_circuits::base_structures::vm_state::QUEUE_STATE_WIDTH; +use crate::zkevm_circuits::transient_storage_validity_by_grand_product::input::*; +use crate::zkevm_circuits::DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS; +use circuit_definitions::encodings::*; + +pub(crate) fn compute_transient_storage_dedup_and_sort< + F: SmallField, + R: BuildableCircuitRoundFunction + AlgebraicRoundFunction, +>( + transient_storage_queries: Vec, + mut demuxed_transient_storage_queue: LogQueueStates, + per_circuit_capacity: usize, + round_function: &R, +) -> Vec> { + // trivial case if nothing to process + + if transient_storage_queries.is_empty() { + return vec![]; + } + + // first we sort the storage log (only storage now) by composite key + + use crate::witness::sort_storage_access::sort_transient_storage_access_queries; + + let total_amount_of_queries = transient_storage_queries.len(); + + let sorted_storage_queries_with_extra_timestamp = + sort_transient_storage_access_queries(&transient_storage_queries); + + let mut sorted_log_simulator_states_accumulator = LastPerCircuitAccumulator::with_flat_capacity( + per_circuit_capacity, + total_amount_of_queries, + ); + let mut intermediate_sorted_log_simulator = + LogWithExtendedEnumerationQueueSimulator::::with_capacity( + sorted_storage_queries_with_extra_timestamp.len(), + ); + for el in sorted_storage_queries_with_extra_timestamp.into_iter() { + let (_, intermediate_state) = intermediate_sorted_log_simulator + .push_and_output_intermediate_data(el.clone(), round_function); + + sorted_log_simulator_states_accumulator.push(intermediate_state); + } + + let sorted_log_simulator_states_chunk_final_states = + sorted_log_simulator_states_accumulator.into_circuits(); + let unsorted_log_simulator_states_chunk_final_states = demuxed_transient_storage_queue + .states_accumulator + .into_circuits(); + + let unsorted_simulator_final_state = + take_queue_state_from_simulator(&demuxed_transient_storage_queue.simulator); + + let intermediate_sorted_log_simulator_final_state = + take_queue_state_from_simulator(&intermediate_sorted_log_simulator); + + // we do NOT produce any output, but just check validity + + // compute sequence of states for grand product accumulation + + // -------------------- + + // now we should chunk it by circuits but briefly simulating their logic + + let challenges = produce_fs_challenges::< + F, + R, + QUEUE_STATE_WIDTH, + { LOG_QUERY_PACKED_WIDTH + 1 }, + DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS, + >( + unsorted_simulator_final_state.tail.clone(), + intermediate_sorted_log_simulator_final_state.tail.clone(), + round_function, + ); + + // since encodings of the elements provide all the information necessary to perform soring argument, + // we use them naively + + assert_eq!( + unsorted_simulator_final_state.tail.length, + intermediate_sorted_log_simulator_final_state.tail.length + ); + + let lhs_contributions: Vec<_> = transient_storage_queries + .into_iter() + .enumerate() + .map(|(idx, el)| { + let extended_query = LogQueryWithExtendedEnumeration { + raw_query: el, + extended_timestamp: idx as u32, + }; + + >::encoding_witness(&extended_query) + }) + .collect(); + + let lhs_contributions_refs = lhs_contributions.iter().collect(); + + // let lhs_contributions: Vec<_> = demuxed_rollup_storage_queue.simulator.witness.iter().map(|el| el.0).collect(); + let rhs_contributions: Vec<_> = intermediate_sorted_log_simulator + .witness + .iter() + .map(|el| &el.0) + .collect(); + + // -------------------- + + // compute chains themselves + + let mut lhs_grand_product_chains = vec![]; + let mut rhs_grand_product_chains = vec![]; + + for idx in 0..DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS { + let (lhs_grand_product_chain, rhs_grand_product_chain) = compute_grand_product_chains::< + F, + LOG_QUERY_PACKED_WIDTH, + { LOG_QUERY_PACKED_WIDTH + 1 }, + >( + &lhs_contributions_refs, + &rhs_contributions, + &challenges[idx], + ); + + assert_eq!( + lhs_grand_product_chain.len(), + demuxed_transient_storage_queue.simulator.witness.len() + ); + assert_eq!( + rhs_grand_product_chain.len(), + intermediate_sorted_log_simulator.witness.len() + ); + + lhs_grand_product_chains.push(lhs_grand_product_chain); + rhs_grand_product_chains.push(rhs_grand_product_chain); + } + + let transposed_lhs_chains = transpose_chunks(&lhs_grand_product_chains, per_circuit_capacity); + let transposed_rhs_chains = transpose_chunks(&rhs_grand_product_chains, per_circuit_capacity); + + // now we need to split them into individual circuits + // splitting is not extra hard here, we walk over iterator over everything and save states on checkpoints + + // -------------------- + + // in general we have everything ready, just form the witness + + // as usual we simulate logic of the circuit and chunk. It's a little less convenient here than in RAM since we + // have to chunk based on 2 queues, but also guess the result of the 3rd queue, but managable + + demuxed_transient_storage_queue + .simulator + .witness + .make_contiguous(); + + intermediate_sorted_log_simulator.witness.make_contiguous(); + + assert!(demuxed_transient_storage_queue + .simulator + .witness + .as_slices() + .1 + .is_empty()); + assert!(intermediate_sorted_log_simulator + .witness + .as_slices() + .1 + .is_empty()); + + let it = unsorted_log_simulator_states_chunk_final_states + .into_iter() + .zip(sorted_log_simulator_states_chunk_final_states) + .zip(transposed_lhs_chains.into_iter()) + .zip(transposed_rhs_chains.into_iter()) + .zip( + demuxed_transient_storage_queue + .simulator + .witness + .as_slices() + .0 + .chunks(per_circuit_capacity), + ) + .zip( + intermediate_sorted_log_simulator + .witness + .as_slices() + .0 + .chunks(per_circuit_capacity), + ); + + // now trivial transformation into desired data structures, + // and we are all good + + let num_circuits = it.len(); + let mut results = vec![]; + + let mut current_lhs_product = [F::ONE; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS]; + let mut current_rhs_product = [F::ONE; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS]; + let mut previous_comparison_key = [0u32; TRANSIENT_STORAGE_VALIDITY_CHECK_PACKED_KEY_LENGTH]; + let mut previous_key = U256::zero(); + let mut previous_timestamp = 0u32; + let mut previous_tx_number = 0u32; + let mut previous_shard_id = 0u8; + let mut cycle_idx = 0u32; + use crate::ethereum_types::Address; + let mut previous_address = Address::default(); + + use crate::ethereum_types::U256; + + let mut this_cell_current_depth = 0u32; + let mut this_cell_current_value = U256::zero(); + + for ( + idx, + ( + ( + ( + ((unsorted_sponge_states, sorted_sponge_states), lhs_grand_product), + rhs_grand_product, + ), + unsorted_states, + ), + sorted_states, + ), + ) in it.enumerate() + { + // we need witnesses to pop elements from the front of the queue + + let unsorted_queue_witness: VecDeque<_> = unsorted_states + .iter() + .map(|(_encoding, old_tail, element)| { + let as_storage_log = element.reflect(); + + (as_storage_log, *old_tail) + }) + .collect(); + + let unsorted_witness = CircuitQueueRawWitness::< + F, + zkevm_circuits::base_structures::log_query::LogQuery, + 4, + LOG_QUERY_PACKED_WIDTH, + > { + elements: unsorted_queue_witness, + }; + + let intermediate_sorted_queue_witness: VecDeque<_> = sorted_states + .iter() + .map(|(_encoding, old_tail, element)| { + let as_timestamped_storage_witness = + log_query_into_timestamped_storage_record_witness(element); + + (as_timestamped_storage_witness, *old_tail) + }) + .collect(); + + let intermediate_sorted_queue_witness = CircuitQueueRawWitness::< + F, + zkevm_circuits::storage_validity_by_grand_product::TimestampedStorageLogRecord, + 4, + LOG_QUERY_PACKED_WIDTH, + > { + elements: intermediate_sorted_queue_witness, + }; + + // now we need to have final grand product value that will also become an input for the next circuit + + let is_first = idx == 0; + let is_last = idx == num_circuits - 1; + + let last_unsorted_state = unsorted_sponge_states; + let last_sorted_state = sorted_sponge_states; + + let accumulated_lhs: [F; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS] = lhs_grand_product + .iter() + .map(|el| *el.last().unwrap()) + .collect::>() + .try_into() + .unwrap(); + let accumulated_rhs: [F; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS] = rhs_grand_product + .iter() + .map(|el| *el.last().unwrap()) + .collect::>() + .try_into() + .unwrap(); + + let last_sorted_query = &sorted_states.last().unwrap().2; + let last_comparison_key = transient_storage_comparison_key(&last_sorted_query.raw_query); + let last_timestamp = last_sorted_query.extended_timestamp; + let last_key = last_sorted_query.raw_query.key; + let last_address = last_sorted_query.raw_query.address; + let last_tx_number = last_sorted_query.raw_query.tx_number_in_block; + let last_shard_id = last_sorted_query.raw_query.shard_id; + + // simulate the logic + let (new_this_cell_current_value, new_this_cell_current_depth) = { + let mut current_address = previous_address; + let mut current_key = previous_key; + let mut current_tx_number = previous_tx_number; + let mut current_shard_id = previous_shard_id; + + let mut new_this_cell_current_value = this_cell_current_value; + let mut new_this_cell_current_depth = this_cell_current_depth; + + let num_items_in_chunk = sorted_states.len(); + + for (sub_idx, (_encoding, _previous_tail, item)) in sorted_states.iter().enumerate() { + let first_ever = sub_idx == 0 && is_first; + let is_last_ever = (sub_idx == num_items_in_chunk - 1) && is_last; + + if first_ever { + // only set current values + if item.raw_query.rw_flag == true { + assert!(item.raw_query.rollback == false); + new_this_cell_current_depth = 1; + } else { + new_this_cell_current_depth = 0; + } + + if item.raw_query.rw_flag == true { + new_this_cell_current_value = item.raw_query.written_value; + } else { + new_this_cell_current_value = item.raw_query.read_value; + } + } else { + // main cycle + + let same_cell = current_tx_number == item.raw_query.tx_number_in_block as u32 + && current_shard_id == item.raw_query.shard_id + && current_address == item.raw_query.address + && current_key == item.raw_query.key; + + if same_cell { + // proceed previous one + if item.raw_query.rw_flag == true { + // write or rollback + if item.raw_query.rollback == false { + new_this_cell_current_depth += 1; + new_this_cell_current_value = item.raw_query.written_value; + } else { + new_this_cell_current_depth -= 1; + new_this_cell_current_value = item.raw_query.read_value; + } + } else { + // read + if new_this_cell_current_depth == 0 { + assert_eq!(item.raw_query.read_value, U256::zero()); + } + new_this_cell_current_value = item.raw_query.read_value; + } + } else { + // start for new one + if item.raw_query.rw_flag == true { + assert!(item.raw_query.rollback == false); + new_this_cell_current_depth = 1; + } else { + new_this_cell_current_depth = 0; + } + + if item.raw_query.rw_flag == true { + new_this_cell_current_value = item.raw_query.written_value; + } else { + assert_eq!(item.raw_query.read_value, U256::zero()); + new_this_cell_current_value = item.raw_query.read_value; + } + } + } + + // always update keys + current_shard_id = item.raw_query.shard_id; + current_tx_number = item.raw_query.tx_number_in_block as u32; + current_address = item.raw_query.address; + current_key = item.raw_query.key; + + if is_last_ever {} + } + + (new_this_cell_current_value, new_this_cell_current_depth) + }; + + use crate::boojum::gadgets::queue::QueueState; + let placeholder_witness = QueueState::::placeholder_witness(); + + let (current_unsorted_queue_state, current_intermediate_sorted_queue_state) = results + .last() + .map(|el: &TransientStorageDeduplicatorInstanceWitness| { + let tmp = &el.closed_form_input.hidden_fsm_output; + + ( + tmp.current_unsorted_queue_state.clone(), + tmp.current_intermediate_sorted_queue_state.clone(), + ) + }) + .unwrap_or((placeholder_witness.clone(), placeholder_witness)); + + // assert_eq!(current_unsorted_queue_state.length, current_sorted_queue_state.length); + + // we use current final state as the intermediate head + let mut final_unsorted_state = transform_queue_state(last_unsorted_state); + final_unsorted_state.head = final_unsorted_state.tail.tail; + final_unsorted_state.tail.tail = unsorted_simulator_final_state.tail.tail; + final_unsorted_state.tail.length = + unsorted_simulator_final_state.tail.length - final_unsorted_state.tail.length; + + let mut final_intermediate_sorted_state = transform_queue_state(last_sorted_state); + final_intermediate_sorted_state.head = last_sorted_state.tail; + final_intermediate_sorted_state.tail.tail = + intermediate_sorted_log_simulator_final_state.tail.tail; + final_intermediate_sorted_state.tail.length = + intermediate_sorted_log_simulator_final_state.tail.length - last_sorted_state.num_items; + + assert_eq!( + final_unsorted_state.tail.length, + final_intermediate_sorted_state.tail.length + ); + + let final_cycle_idx = cycle_idx + per_circuit_capacity as u32; + + let mut instance_witness = TransientStorageDeduplicatorInstanceWitness { + closed_form_input: ClosedFormInputWitness { + start_flag: is_first, + completion_flag: is_last, + observable_input: TransientStorageDeduplicatorInputDataWitness { + unsorted_log_queue_state: unsorted_simulator_final_state.clone(), + intermediate_sorted_queue_state: intermediate_sorted_log_simulator_final_state + .clone(), + }, + observable_output: (), + hidden_fsm_input: TransientStorageDeduplicatorFSMInputOutputWitness { + lhs_accumulator: current_lhs_product, + rhs_accumulator: current_rhs_product, + current_unsorted_queue_state, + current_intermediate_sorted_queue_state, + cycle_idx: cycle_idx, + previous_timestamp, + previous_packed_key: previous_comparison_key, + this_cell_current_value: this_cell_current_value, + this_cell_current_depth, + }, + hidden_fsm_output: TransientStorageDeduplicatorFSMInputOutputWitness { + lhs_accumulator: accumulated_lhs, + rhs_accumulator: accumulated_rhs, + current_unsorted_queue_state: final_unsorted_state, + current_intermediate_sorted_queue_state: final_intermediate_sorted_state, + cycle_idx: final_cycle_idx, + previous_packed_key: last_comparison_key.0, + previous_timestamp: last_timestamp, + this_cell_current_value: new_this_cell_current_value, + this_cell_current_depth: new_this_cell_current_depth, + }, + }, + unsorted_queue_witness: unsorted_witness, + intermediate_sorted_queue_witness: intermediate_sorted_queue_witness, + }; + + assert_eq!( + instance_witness.unsorted_queue_witness.elements.len(), + instance_witness + .intermediate_sorted_queue_witness + .elements + .len() + ); + + if sorted_states.len() % per_circuit_capacity != 0 { + assert!(is_last); + // circuit does padding, so all previous values must be reset + instance_witness + .closed_form_input + .hidden_fsm_output + .previous_packed_key = [0u32; TRANSIENT_STORAGE_VALIDITY_CHECK_PACKED_KEY_LENGTH]; + instance_witness + .closed_form_input + .hidden_fsm_output + .previous_timestamp = 0u32; + } else { + if is_last {} + } + + current_lhs_product = accumulated_lhs; + current_rhs_product = accumulated_rhs; + + previous_comparison_key = last_comparison_key.0; + previous_key = last_key; + previous_timestamp = last_timestamp; + previous_address = last_address; + previous_shard_id = last_shard_id; + previous_tx_number = last_tx_number as u32; + + this_cell_current_value = new_this_cell_current_value; + this_cell_current_depth = new_this_cell_current_depth; + + cycle_idx = final_cycle_idx; + + results.push(instance_witness); + } + + results +} diff --git a/crates/zkevm_test_harness/src/witness/mod.rs b/crates/zkevm_test_harness/src/witness/mod.rs new file mode 100644 index 0000000..bfb3906 --- /dev/null +++ b/crates/zkevm_test_harness/src/witness/mod.rs @@ -0,0 +1,15 @@ +use super::*; + +pub mod artifacts; +pub mod individual_circuits; +pub mod oracle; +pub mod postprocessing; +pub mod recursive_aggregation; +pub use circuit_sequencer_api::sort_storage_access; +mod aux_data_structs; +pub mod tracer; +pub mod tree; +pub mod utils; + +// pub mod vk_set_generator; +// pub mod block_header; diff --git a/crates/zkevm_test_harness/src/witness/oracle.rs b/crates/zkevm_test_harness/src/witness/oracle.rs new file mode 100644 index 0000000..5ada14e --- /dev/null +++ b/crates/zkevm_test_harness/src/witness/oracle.rs @@ -0,0 +1,1810 @@ +// implement witness oracle to actually compute +// at the intermediate things that we need during VM execution, +// and then during specialized circuits execution + +use super::artifacts::LogCircuitsArtifacts; +use super::individual_circuits::main_vm::CallstackSimulationResult; +use super::individual_circuits::memory_related::{ImplicitMemoryQueries, ImplicitMemoryStates}; +use super::postprocessing::{ + BlockFirstAndLastBasicCircuitsObservableWitnesses, FirstAndLastCircuitWitness, +}; +use super::tracer::callstack_handler::*; +use super::utils::*; +use crate::boojum::field::SmallField; +use crate::boojum::gadgets::queue::QueueState; +use crate::boojum::gadgets::traits::allocatable::CSAllocatable; +use crate::ethereum_types::U256; +use crate::toolset::GeometryConfig; +use crate::witness::artifacts::{DemuxedLogQueries, MemoryArtifacts, MemoryCircuitsArtifacts}; +use crate::witness::aux_data_structs::one_per_circuit_accumulator::{ + CircuitsEntryAccumulatorSparse, LastPerCircuitAccumulator, +}; +use crate::witness::aux_data_structs::per_circuit_accumulator::{ + PerCircuitAccumulator, PerCircuitAccumulatorSparse, +}; +use crate::witness::aux_data_structs::MemoryQueuePerCircuitSimulator; +use crate::witness::individual_circuits::log_demux::LogDemuxCircuitArtifacts; +use crate::witness::postprocessing::make_circuits; +use crate::witness::tracer::tracer::{QueryMarker, WitnessTracer}; +use crate::witness::tracer::vm_snapshot::VmSnapshot; +use crate::zk_evm::aux_structures::DecommittmentQuery; +use crate::zk_evm::aux_structures::LogQuery; +use crate::zkevm_circuits::base_structures::vm_state::{ + GlobalContextWitness, FULL_SPONGE_QUEUE_STATE_WIDTH, QUEUE_STATE_WIDTH, +}; +use crate::zkevm_circuits::scheduler::block_header::MAX_4844_BLOBS_PER_BLOCK; +use circuit_definitions::boojum::field::goldilocks::GoldilocksField; +use circuit_definitions::boojum::field::{Field, U64Representable}; +use circuit_definitions::boojum::gadgets::queue::QueueStateWitness; +use circuit_definitions::boojum::implementations::poseidon2::Poseidon2Goldilocks; +use circuit_definitions::circuit_definitions::base_layer::ZkSyncBaseLayerCircuit; +use circuit_definitions::encodings::callstack_entry::ExtendedCallstackEntry; +use circuit_definitions::encodings::recursion_request::RecursionQueueSimulator; +use circuit_definitions::encodings::{CircuitEquivalentReflection, LogQueueSimulator}; +use circuit_definitions::zkevm_circuits::base_structures::memory_query::{ + MemoryQueryWitness, MEMORY_QUERY_PACKED_WIDTH, +}; +use circuit_definitions::zkevm_circuits::eip_4844::input::EIP4844CircuitInstanceWitness; +use circuit_definitions::zkevm_circuits::fsm_input_output::ClosedFormInputCompactFormWitness; +use circuit_definitions::zkevm_circuits::scheduler::aux::BaseLayerCircuitType; +use derivative::Derivative; +use std::collections::{BTreeMap, HashMap}; +use std::sync::mpsc::{self, Receiver, Sender}; +use std::sync::{Arc, Mutex}; +use zkevm_assembly::zkevm_opcode_defs::BOOTLOADER_HEAP_PAGE; + +#[derive(Derivative)] +#[derivative(Clone(bound = ""), Copy(bound = ""), Debug, Default)] +struct CallframeLogState { + forward_queue_tail_pointer: usize, + forward_queue_length: u32, + rollback_queue_head_pointer: usize, + rollback_queue_tail_pointer: usize, + rollback_queue_length: u32, +} + +#[derive(Derivative)] +#[derivative(Clone(bound = ""), Copy(bound = ""), Debug)] +pub struct RollbackQueueStateWitness { + pub head: [F; QUEUE_STATE_WIDTH], + pub tail: [F; QUEUE_STATE_WIDTH], + pub segment_length: u32, +} + +#[derive(Derivative)] +#[derivative( + Clone(bound = ""), + Copy(bound = ""), + Debug, + PartialEq, + Eq, + Default(bound = "") +)] +pub struct FrameLogQueueDetailedState { + pub frame_idx: usize, + pub forward_tail: [F; QUEUE_STATE_WIDTH], + pub forward_length: u32, + pub rollback_head: [F; QUEUE_STATE_WIDTH], + pub rollback_tail: [F; QUEUE_STATE_WIDTH], + pub rollback_length: u32, +} + +#[derive(Derivative)] +#[derivative(Clone(bound = ""), Copy(bound = ""), Debug, Default)] +pub struct CommonLogSponges { + pub rf_0: ([F; 12], [F; 12]), + pub rf_1: ([F; 12], [F; 12]), +} + +#[derive(Derivative)] +#[derivative(Clone(bound = ""), Copy(bound = ""), Debug, Default)] +pub struct ForwardLogSponge { + pub old_tail: [F; QUEUE_STATE_WIDTH], + pub new_tail: [F; QUEUE_STATE_WIDTH], + pub exclusive_rf: ([F; 12], [F; 12]), +} + +#[derive(Derivative)] +#[derivative(Clone(bound = ""), Copy(bound = ""), Debug, Default)] +pub struct RollbackLogSponge { + pub old_head: [F; QUEUE_STATE_WIDTH], + pub new_head: [F; QUEUE_STATE_WIDTH], + pub exclusive_rf: ([F; 12], [F; 12]), +} + +type Cycle = u32; + +#[derive(Derivative)] +#[derivative(Clone(bound = ""), Copy(bound = ""), Debug, Default)] +pub struct LogAccessSpongesInfo { + pub cycle: Cycle, + pub common_sponges: CommonLogSponges, +} + +#[derive(Derivative)] +#[derivative(Clone(bound = ""), Copy(bound = ""), Debug, Default)] +struct FlattenedLogQueueIndexer { + pub current_head: [F; QUEUE_STATE_WIDTH], + pub current_tail: [F; QUEUE_STATE_WIDTH], + pub head_offset: usize, + pub tail_offset: usize, +} + +struct LogMuxedStatesData { + /// If any forward query occurs at a given cycle, this map contains indexes of entries in chain_of_states for the query and corresponding rollback. + forward_and_rollback_pointers: BTreeMap)>, + /// The chain of all multiplexed log queue simulator state changes, old_tail -> new_tail + chain_of_states: Vec<([F; QUEUE_STATE_WIDTH], [F; QUEUE_STATE_WIDTH])>, +} + +type LogRollbackTailsForFrames = Vec<(Cycle, [GoldilocksField; QUEUE_STATE_WIDTH])>; + +/// Simulates the global multiplexed log queue and produces inputs for log demux circuit processing. +/// Together with simulation, splits the multiplexed log queue into separate queues. +/// Also returns the initial tails of the multiplexed log rollback queue for each call frame +/// and rollback queue heads for cycles +fn process_multiplexed_log_queue( + geometry: GeometryConfig, + full_callstack_history: &Vec, + mut final_callstack_entry: CallstackEntryWithAuxData, + round_function: Poseidon2Goldilocks, +) -> ( + LogMuxedStatesData, + LogDemuxCircuitArtifacts, + DemuxedLogQueries, + LogRollbackTailsForFrames, + PerCircuitAccumulatorSparse<(Cycle, [GoldilocksField; QUEUE_STATE_WIDTH])>, +) { + // Every execution frame has forward and rollback log queues. Forward queue contains "executed" queries, + // rollback queue - potential (not executed yet) rollbacks. When a frame ends, its queues are merged to the parent frame queues. + // Since we finished the VM execution, final callstack entry (root, outermost frame) contains all logs. + // These queues also contain some additional markers + let applied_queries = std::mem::take(&mut final_callstack_entry.forward_queue); + let not_applied_rollbacks = std::mem::take(&mut final_callstack_entry.rollback_queue); + drop(final_callstack_entry); + + // OutOfScope(Fresh) - record about creating a new execution frame + let total_amount_of_frames = full_callstack_history + .iter() + .filter(|x| x.action == CallstackAction::OutOfScope(OutOfScopeReason::Fresh)) + .count(); + let mut frames_beginnings_and_rollback_tails = Vec::with_capacity(total_amount_of_frames); + + for el in full_callstack_history.iter() { + match el.action { + CallstackAction::PushToStack => {} + CallstackAction::PopFromStack { panic: _ } => {} + CallstackAction::OutOfScope(OutOfScopeReason::Fresh) => { + // frame created at el.beginning_cycle, we will find log queue rollback tail later + frames_beginnings_and_rollback_tails.push((el.beginning_cycle, None)); + } + CallstackAction::OutOfScope(OutOfScopeReason::Exited { panic: _ }) => { + el.end_cycle.expect("frame must end"); // sanity check + } + } + } + + // from cycle to first two sponges (common for forwards and rollbacks) + let mut sponges_data: HashMap> = HashMap::new(); + + let mut log_queue_simulator = + LogQueueSimulator::::with_capacity(applied_queries.len()); + let mut applied_log_queue_simulator = None; + + // struct contains the chain of all multiplexed log queue simulator state changes, old_tail -> new_tail + // and pointers to corresponding indexes in this chain for forward and rollback queries (if any) at cycle + let mut states_data = LogMuxedStatesData { + forward_and_rollback_pointers: BTreeMap::)>::new(), + chain_of_states: Vec::with_capacity(applied_queries.len() + not_applied_rollbacks.len()), + }; + + let mut demuxed_queries = DemuxedLogQueries::default(); + + // used to accumulate all applied muxed log queue state changes needed for log demux circuit simulation + let mut applied_queue_states_accumulator = LastPerCircuitAccumulator::with_flat_capacity( + geometry.cycles_per_log_demuxer as usize, + applied_queries.len(), + ); + + // Now we will do following: + // - simulate the states of multiplexed log queue as a sponge + // - find initial multiplexed log queue rollback tails for every frame (including not applied rollbacks) + // - demux applied part of the log queue and prepare inputs for log demux circuit processing + + // we use reversed iterator for not_applied_rollbacks here + for (extended_query, was_applied) in applied_queries + .into_iter() + .zip(std::iter::repeat(true)) + .chain( + not_applied_rollbacks + .into_iter() + .rev() + .zip(std::iter::repeat(false)), + ) + { + // Later we will mainle need only the result of "applied" part simulation. + // So we will save a copy of simulator the first time we encounter an unapplied query. + if !was_applied { + if applied_log_queue_simulator.is_none() { + // save the applied queue simulator + applied_log_queue_simulator = Some(log_queue_simulator.clone()); + } + } else { + // check for no gaps + assert!(applied_log_queue_simulator.is_none()); + } + + let (query_marker, cycle, query) = match extended_query { + ExtendedLogQuery::Query { + marker, + cycle, + query, + } => (marker, cycle, query), + ExtendedLogQuery::FrameForwardHeadMarker(..) => { + continue; // not used + } + ExtendedLogQuery::FrameForwardTailMarker(..) => { + continue; // not used + } + ExtendedLogQuery::FrameRollbackHeadMarker(..) => { + continue; // not used + } + ExtendedLogQuery::FrameRollbackTailMarker(frame_index) => { + // special marker, use the last "new" queue simulator tail value from chain_of_states + // as initial log rollback queue tail for frame + + assert!(frames_beginnings_and_rollback_tails[frame_index] + .1 + .is_none()); + + frames_beginnings_and_rollback_tails[frame_index].1 = Some( + states_data + .chain_of_states + .last() + .map(|el| el.1) + .unwrap_or([GoldilocksField::ZERO; QUEUE_STATE_WIDTH]), + ); + + continue; // we do not have any query to simulate + } + }; + + // actually simulate new queue state + let (_, simulator_state) = + log_queue_simulator.push_and_output_intermediate_data(query, &round_function); + + let pointer_to_chain_of_states = states_data.chain_of_states.len(); + states_data + .chain_of_states + .push((simulator_state.previous_tail, simulator_state.tail)); + + if was_applied { + applied_queue_states_accumulator.push((cycle, simulator_state)); + demuxed_queries.sort_and_push(query); + } + + let timestamp = query.timestamp.0; // special "timestamp-like" value + if !query.rollback { + let sponge_data = sponges_data.entry(timestamp).or_default(); + sponge_data.rf_0 = simulator_state.round_function_execution_pairs[0]; + sponge_data.rf_1 = simulator_state.round_function_execution_pairs[1]; + // forward case + states_data + .forward_and_rollback_pointers + .entry(cycle) + .or_default() + .0 = pointer_to_chain_of_states; + } else { + let sponge_data = sponges_data + .get_mut(×tamp) + .expect("rollbacks always happen after forward case"); + assert_eq!( + &sponge_data.rf_0, + &simulator_state.round_function_execution_pairs[0] + ); + assert_eq!( + &sponge_data.rf_1, + &simulator_state.round_function_execution_pairs[1] + ); + // rollback case + states_data + .forward_and_rollback_pointers + .get_mut(&cycle) + .expect("rollbacks always happen after forward case") + .1 = Some(pointer_to_chain_of_states); + } + + match query_marker { + QueryMarker::Forward { cycle: c, .. } => { + assert_eq!(cycle, c); + assert!(!query.rollback); + } + QueryMarker::ForwardNoRollback { cycle: c, .. } => { + assert_eq!(cycle, c); + assert!(!query.rollback); + } + QueryMarker::Rollback { + cycle_of_declaration: c, + .. + } => { + assert_eq!(cycle, c); + assert!(query.rollback); + } + } + } + + let mut log_rollback_tails_for_frames = + Vec::with_capacity(frames_beginnings_and_rollback_tails.len()); + log_rollback_tails_for_frames.extend( + frames_beginnings_and_rollback_tails + .into_iter() + .enumerate() + .map(|(frame_index, (beginning_cycle, tail))| { + ( + beginning_cycle, + tail.unwrap_or_else(|| panic!("No rollback tail for frame {frame_index}")), + ) + }), + ); + + // we know for every cycle a pointer to the positions of item's forward and rollback action into + // the flattened queue + // we also know when each cycle begins/end + // so we can quickly reconstruct every current state + let mut log_rollback_queue_heads: PerCircuitAccumulatorSparse<( + Cycle, + [GoldilocksField; QUEUE_STATE_WIDTH], + )> = PerCircuitAccumulatorSparse::new(geometry.cycles_per_vm_snapshot as usize); + + for (cycle, (_forward, rollback)) in states_data.forward_and_rollback_pointers.iter() { + if let Some(pointer) = rollback { + let state = &states_data.chain_of_states[*pointer]; + log_rollback_queue_heads.push((*cycle, state.0)); + } + } + + ( + states_data, + LogDemuxCircuitArtifacts { + applied_log_queue_simulator: applied_log_queue_simulator + .unwrap_or(LogQueueSimulator::::empty()), + applied_queue_states_accumulator, + }, + demuxed_queries, + log_rollback_tails_for_frames, + log_rollback_queue_heads, + ) +} + +use circuit_definitions::encodings::callstack_entry::{ + CallstackSimulator, CallstackSimulatorState, +}; + +/// Simulate callstack and prepare callstack-related inputs for MainVM circuits processing +fn callstack_simulation( + geometry: &GeometryConfig, + full_callstack_history: Vec, + log_states_data: LogMuxedStatesData, + log_rollback_tails_for_frames: &Vec<(Cycle, [GoldilocksField; QUEUE_STATE_WIDTH])>, + round_function: &Poseidon2Goldilocks, +) -> CallstackSimulationResult { + // we need to simultaneously follow the logic of pushes/joins of the log queue, + // and encoding of the current callstack state as the sponge state + + let mut callstack_argebraic_simulator = CallstackSimulator::empty(); + + // These are "frozen" states that just lie in the callstack for now and can not be modified + // so we never follow the "current", but add on push/pop + let mut callstack_witnesses_for_main_vm = + PerCircuitAccumulatorSparse::new(geometry.cycles_per_vm_snapshot as usize); + let mut entry_callstack_states_accumulator_for_main_vm = CircuitsEntryAccumulatorSparse::new( + geometry.cycles_per_vm_snapshot as usize, + (0, [GoldilocksField::ZERO; FULL_SPONGE_QUEUE_STATE_WIDTH]), + ); + + let global_end_of_storage_log = log_states_data + .chain_of_states + .last() + .map(|el| el.1) + .unwrap_or([GoldilocksField::ZERO; QUEUE_STATE_WIDTH]); + + // we need some information that spans the whole number of cycles with "what is a frame counter at this time" + // we have all the spans of when each frame is active, so we can simulate what is saved and when + let mut log_queue_detailed_states = BTreeMap::new(); + + // we start with no rollbacks, but non-trivial tail + let initial_storage_state = FrameLogQueueDetailedState { + rollback_tail: global_end_of_storage_log, + rollback_head: global_end_of_storage_log, + ..Default::default() + }; + + let mut current_storage_log_state = initial_storage_state; + + let mut storage_logs_states_stack = vec![]; + + let mut exited_state_to_merge: Option<(bool, FrameLogQueueDetailedState)> = + None; + + let apply_frame_log_changes = + |callstack_history_entry: &CallstackActionHistoryEntry, + mut storage_log_state: FrameLogQueueDetailedState, + log_queue_detailed_states: &mut BTreeMap< + u32, + FrameLogQueueDetailedState, + >| { + let begin_at_cycle = callstack_history_entry.beginning_cycle; + let end_cycle = callstack_history_entry.end_cycle.expect("frame must end"); + + let range_of_interest = (begin_at_cycle + 1)..=end_cycle; // begin_at_cycle is formally bound to the previous one + let frame_action_span = log_states_data + .forward_and_rollback_pointers + .range(range_of_interest); + for (cycle, (forward_pointer, rollback_pointer)) in frame_action_span { + // always add to the forward + let new_forward_tail = log_states_data.chain_of_states[*forward_pointer].1; + if new_forward_tail != storage_log_state.forward_tail { + // edge case of double data on frame boudary, reword later + storage_log_state.forward_tail = new_forward_tail; + storage_log_state.forward_length += 1; + } + + // if there is a rollback then let's process it too + + if let Some(rollback_pointer) = rollback_pointer { + let new_rollback_head = log_states_data.chain_of_states[*rollback_pointer].0; + storage_log_state.rollback_head = new_rollback_head; + storage_log_state.rollback_length += 1; + } + + let previous = log_queue_detailed_states.insert(*cycle, storage_log_state); + if previous.is_some() { + assert_eq!( + previous.unwrap(), + storage_log_state, + "duplicate divergence for cycle {}: previous is {:?}, new is {:?}", + cycle, + previous.unwrap(), + storage_log_state + ) + } + } + + storage_log_state + }; + + let mut save_callstack_witness_for_main_vm = + |cycle_to_use: u32, + callstack_entry: ExtendedCallstackEntry, + callstack_simulator_state: CallstackSimulatorState| { + if let Some((prev_cycle, _)) = callstack_witnesses_for_main_vm.last() { + assert!( + cycle_to_use != *prev_cycle, + "trying to add callstack witness for cycle {}, but previous one is on cycle {}", + cycle_to_use, + prev_cycle + ); + } + callstack_witnesses_for_main_vm + .push((cycle_to_use, (callstack_entry, callstack_simulator_state))); + + // when we push a new one then we need to "finish" the previous range and start a new one + entry_callstack_states_accumulator_for_main_vm + .push((cycle_to_use, callstack_simulator_state.new_state)); + }; + + // we simulate a series of actions on the stack starting from the outermost frame + // each history record contains an information on what was the stack state between points + // when it potentially came into and out of scope + for callstack_history_entry in full_callstack_history.iter() { + let frame_index = callstack_history_entry.frame_index; + + // flow for new frame (push current and create a new one): PushToStack -> OutOfScope(Fresh) + // flow for frame ending (remove current and pop from stack): OutOfScope(Exited) -> PopFromStack + + match callstack_history_entry.action { + CallstackAction::PushToStack => { + // we did push some(!) context to the stack + // it means that between beginning and end cycles + // there could have beed some interactions with log + + // `current_storage_log_state` is what we should use for the "current" one, + // and we can mutate it, bookkeep and then use in the simulator + + current_storage_log_state = apply_frame_log_changes( + callstack_history_entry, + current_storage_log_state, + &mut log_queue_detailed_states, + ); + + // push the item to the stack + storage_logs_states_stack.push(current_storage_log_state); + + let end_cycle = callstack_history_entry.end_cycle.expect("frame must end"); + + // dump it into the entry and dump entry into simulator + let entry = ExtendedCallstackEntry { + callstack_entry: callstack_history_entry.affected_entry, + rollback_queue_head: current_storage_log_state.rollback_head, + rollback_queue_tail: current_storage_log_state.rollback_tail, + rollback_queue_segment_length: current_storage_log_state.rollback_length, + }; + + let intermediate_info = callstack_argebraic_simulator + .push_and_output_intermediate_data(entry, round_function); + + // we do push the witness at the cycle numbered at when the element was pushed + assert!(intermediate_info.is_push); + save_callstack_witness_for_main_vm(end_cycle, entry, intermediate_info); + } + CallstackAction::OutOfScope(OutOfScopeReason::Fresh) => { + // new frame created + + // we already identified initial rollback tails for new frames + let rollback_tail = log_rollback_tails_for_frames[frame_index].1; + // do not reset forward length as it's easy to merge + current_storage_log_state.frame_idx = frame_index; + current_storage_log_state.rollback_length = 0; + current_storage_log_state.rollback_head = rollback_tail; + current_storage_log_state.rollback_tail = rollback_tail; + + let beginning_cycle = callstack_history_entry.beginning_cycle; + + let previous = + log_queue_detailed_states.insert(beginning_cycle, current_storage_log_state); + + if previous.is_some() { + // ensure that basic properties hold: we replace the current frame with a new one, so + // it should have larger frame_idx and the same forward tail and length + let previous = previous.unwrap(); + assert!( + previous.frame_idx < current_storage_log_state.frame_idx, + "frame divergence for cycle {}: previous is {:?}, new is {:?}", + beginning_cycle, + previous, + current_storage_log_state + ); + assert_eq!( + previous.forward_tail, current_storage_log_state.forward_tail, + "frame divergence for cycle {}: previous is {:?}, new is {:?}", + beginning_cycle, previous, current_storage_log_state + ); + assert_eq!( + previous.forward_length, current_storage_log_state.forward_length, + "frame divergence for cycle {}: previous is {:?}, new is {:?}", + beginning_cycle, previous, current_storage_log_state + ); + } + } + CallstackAction::OutOfScope(OutOfScopeReason::Exited { panic }) => { + // frame ended + // we are not too interested, frame just ends, and all the storage log logic was resolved before it + assert!(exited_state_to_merge.is_none()); + + current_storage_log_state = apply_frame_log_changes( + callstack_history_entry, + current_storage_log_state, + &mut log_queue_detailed_states, + ); + exited_state_to_merge = Some((panic, current_storage_log_state)); + } + CallstackAction::PopFromStack { panic } => { + // an item that was in the stack becomes current + assert!(exited_state_to_merge.is_some()); + + let (pending_panic, exited_state_to_merge) = exited_state_to_merge.take().unwrap(); + assert_eq!(panic, pending_panic); + + let popped_state = storage_logs_states_stack.pop().unwrap(); + + // we can get a witness for a circuit + let (entry, intermediate_info) = + callstack_argebraic_simulator.pop_and_output_intermediate_data(round_function); + + assert_eq!( + entry.rollback_queue_head, popped_state.rollback_head, + "divergence at frame {}", + frame_index + ); + assert_eq!( + entry.rollback_queue_tail, popped_state.rollback_tail, + "divergence at frame {}", + frame_index + ); + assert_eq!( + entry.rollback_queue_segment_length, popped_state.rollback_length, + "divergence at frame {}", + frame_index + ); + + // merge state from exited frame + current_storage_log_state = popped_state; + current_storage_log_state.frame_idx = frame_index; + current_storage_log_state.forward_tail = exited_state_to_merge.forward_tail; + assert!( + current_storage_log_state.forward_length + <= exited_state_to_merge.forward_length, + "divergence at frame {}", + frame_index + ); + current_storage_log_state.forward_length = exited_state_to_merge.forward_length; + + if panic { + assert_eq!( + current_storage_log_state.forward_tail, exited_state_to_merge.rollback_head, + "divergence at frame {} with panic: {:?}", + frame_index, callstack_history_entry + ); + + current_storage_log_state.forward_tail = exited_state_to_merge.rollback_tail; + current_storage_log_state.forward_length += + exited_state_to_merge.rollback_length; + } else { + assert_eq!( + current_storage_log_state.rollback_head, + exited_state_to_merge.rollback_tail, + "divergence at frame {} without panic: {:?}", + frame_index, + callstack_history_entry + ); + current_storage_log_state.rollback_head = exited_state_to_merge.rollback_head; + current_storage_log_state.rollback_length += + exited_state_to_merge.rollback_length; + } + + let beginning_cycle = callstack_history_entry.beginning_cycle; + + let previous = + log_queue_detailed_states.insert(beginning_cycle, current_storage_log_state); + if previous.is_some() { + assert_eq!( + previous.unwrap(), + current_storage_log_state, + "duplicate divergence for cycle {}: previous is {:?}, new is {:?}", + beginning_cycle, + previous.unwrap(), + current_storage_log_state + ) + } + + assert!(!intermediate_info.is_push); + + // we place it at the cycle when it was actually popped, but not one when it became "active" + save_callstack_witness_for_main_vm(beginning_cycle, entry, intermediate_info); + } + } + } + + let entry_frames_storage_log_detailed_states = CircuitsEntryAccumulatorSparse::from_iter( + geometry.cycles_per_vm_snapshot as usize, + (0, initial_storage_state), + log_queue_detailed_states, + ); + + CallstackSimulationResult { + entry_callstack_states_accumulator: entry_callstack_states_accumulator_for_main_vm, + callstack_witnesses: callstack_witnesses_for_main_vm, + entry_frames_storage_log_detailed_states, + } +} + +use crate::witness::artifacts::DemuxedIOLogQueries; +use crate::witness::individual_circuits::log_demux::IOLogsQueuesStates; +use crate::zkevm_circuits::demux_log_queue::DemuxOutput; + +/// Process log circuits that do not use memory. +/// Storage, transient storage, events, l2 to l1 queries +/// Precompiles use memory and are processed in 'process_memory_related_circuits' +fn process_io_log_circuits( + geometry: &GeometryConfig, + tree: impl BinarySparseStorageTree<256, 32, 32, 8, 32, Blake2s256, ZkSyncStorageLeaf>, + demuxed_log_queues_states: IOLogsQueuesStates, + demuxed_log_queries: DemuxedIOLogQueries, + round_function: &Poseidon2Goldilocks, + mut artifacts_callback: &mut CB, +) -> ( + LogCircuitsArtifacts, + FirstAndLastCircuitWitness>, + Vec>, +) { + let mut log_circuits_data = LogCircuitsArtifacts::default(); + + // now completely parallel process to reconstruct the states, with internally parallelism in each round function + + use crate::witness::individual_circuits::storage_sort_dedup::compute_storage_dedup_and_sort; + + tracing::debug!("Running storage deduplication simulation"); + + let ( + deduplicated_rollup_storage_queue_simulator, + deduplicated_rollup_storage_queries, + storage_deduplicator_circuit_data, + ) = compute_storage_dedup_and_sort( + demuxed_log_queries.rollup_storage, + demuxed_log_queues_states.rollup_storage, + geometry.cycles_per_storage_sorter as usize, + round_function, + ); + log_circuits_data.storage_deduplicator_circuit_data = storage_deduplicator_circuit_data; + + use crate::witness::individual_circuits::events_sort_dedup::compute_events_dedup_and_sort; + + tracing::debug!("Running events deduplication simulation"); + + let events_deduplicator_circuit_data = compute_events_dedup_and_sort( + demuxed_log_queries.event, + demuxed_log_queues_states.events, + &mut Default::default(), + geometry.cycles_per_events_or_l1_messages_sorter as usize, + round_function, + ); + + log_circuits_data.events_deduplicator_circuit_data = events_deduplicator_circuit_data; + + tracing::debug!("Running L1 messages deduplication simulation"); + + let mut deduplicated_to_l1_queue_simulator = Default::default(); + let l1_messages_deduplicator_circuit_data = compute_events_dedup_and_sort( + demuxed_log_queries.to_l1, + demuxed_log_queues_states.l2_to_l1, + &mut deduplicated_to_l1_queue_simulator, + geometry.cycles_per_events_or_l1_messages_sorter as usize, + round_function, + ); + log_circuits_data.l1_messages_deduplicator_circuit_data = l1_messages_deduplicator_circuit_data; + + use crate::witness::individual_circuits::transient_storage_sorter::compute_transient_storage_dedup_and_sort; + + tracing::debug!("Running transient storage sorting simulation"); + + let transient_storage_sorter_circuit_data = compute_transient_storage_dedup_and_sort( + demuxed_log_queries.transient_storage, + demuxed_log_queues_states.transient_storage, + geometry.cycles_per_transient_storage_sorter as usize, + round_function, + ); + log_circuits_data.transient_storage_sorter_circuit_data = transient_storage_sorter_circuit_data; + + // compute flattened hash of all messages + + tracing::debug!("Running L1 messages linear hash simulation"); + + assert!( + deduplicated_to_l1_queue_simulator.num_items + <= geometry.limit_for_l1_messages_pudata_hasher, + "too many L1 messages to linearly hash by single circuit" + ); + + use crate::witness::individual_circuits::data_hasher_and_merklizer::compute_linear_keccak256; + + let l1_messages_pubdata_hasher_data = compute_linear_keccak256( + deduplicated_to_l1_queue_simulator, + geometry.limit_for_l1_messages_pudata_hasher as usize, + round_function, + ); + log_circuits_data.l1_messages_linear_hash_data = l1_messages_pubdata_hasher_data; + + // process the storage application + + // and do the actual storage application + use crate::witness::individual_circuits::storage_application::decompose_into_storage_application_witnesses; + + let (storage_application_circuits, storage_application_compact_forms) = + decompose_into_storage_application_witnesses( + deduplicated_rollup_storage_queue_simulator, + deduplicated_rollup_storage_queries, + tree, + round_function, + geometry.cycles_per_storage_application as usize, + geometry, + &mut artifacts_callback, + ); + + ( + log_circuits_data, + storage_application_circuits, + storage_application_compact_forms, + ) +} + +use crate::zk_evm::aux_structures::MemoryQuery; +use crate::zk_evm::zk_evm_abstractions::precompiles::ecrecover::ECRecoverRoundWitness; +use crate::zk_evm::zk_evm_abstractions::precompiles::keccak256::Keccak256RoundWitness; +use crate::zk_evm::zk_evm_abstractions::precompiles::secp256r1_verify::Secp256r1VerifyRoundWitness; +use crate::zk_evm::zk_evm_abstractions::precompiles::sha256::Sha256RoundWitness; + +use crate::witness::postprocessing::observable_witness::RamPermutationObservableWitness; +use crate::witness::postprocessing::observable_witness::StorageApplicationObservableWitness; + +use crate::blake2::Blake2s256; +use crate::witness::tree::*; + +use crate::witness::artifacts::DecommitmentArtifactsForMainVM; +use crate::witness::artifacts::LogQueueStates; +use crate::zkevm_circuits::demux_log_queue::NUM_DEMUX_OUTPUTS; + +use circuit_definitions::encodings::memory_query::{MemoryQueueState, MemoryQueueStateWitnesses}; + +fn simulate_memory_queue( + geometry: GeometryConfig, + memory_queries: Arc>, + implicit_memory_queries: Arc, + round_function: Poseidon2Goldilocks, + channel_sender: Sender, +) -> ( + CircuitsEntryAccumulatorSparse<( + u32, + QueueStateWitness, + )>, + MemoryQueueState, + LastPerCircuitAccumulator>, + MemoryQueuePerCircuitSimulator, + ImplicitMemoryStates, + Vec<[GoldilocksField; MEMORY_QUERY_PACKED_WIDTH]>, +) { + // for MainVM circuits + let mut memory_queue_entry_states = CircuitsEntryAccumulatorSparse::new( + geometry.cycles_per_vm_snapshot as usize, + (0, QueueState::placeholder_witness()), + ); + + // for RAM permutation circuits, only last per circuit + let mut memory_queue_states_accumulator = + LastPerCircuitAccumulator::>::with_flat_capacity( + geometry.cycles_per_ram_permutation as usize, + memory_queries.len(), + ); + + use crate::witness::aux_data_structs::per_circuit_accumulator::PerCircuitAccumulator; + // simulator states are very RAM-heavy + let mut memory_queue_simulator = + MemoryQueuePerCircuitSimulator::using_container(PerCircuitAccumulator::with_flat_capacity( + geometry.cycles_per_ram_permutation as usize, + geometry.cycles_per_ram_permutation as usize, + )); + + // for fs challenges in RAM permutation circuits + let mut encodings_witnesses_for_fs = vec![]; + + // move accumulated full state witnesses from simulator, and process them + let mut process_simulation_result = + |mut memory_queue_simulator: MemoryQueuePerCircuitSimulator| { + let witnesses; + (memory_queue_simulator, witnesses) = memory_queue_simulator.replace_container( + PerCircuitAccumulator::with_flat_capacity( + geometry.cycles_per_ram_permutation as usize, + geometry.cycles_per_ram_permutation as usize, + ), + ); + let amount_of_circuits_accumulated = witnesses.amount_of_circuits_accumulated(); + for full_witnesses_for_circuit in + witnesses.into_circuits(amount_of_circuits_accumulated) + { + let mut unsorted_witnesses_for_circuit = + Vec::with_capacity(full_witnesses_for_circuit.len()); + + // split full witnesses + for witness in full_witnesses_for_circuit.into_iter() { + encodings_witnesses_for_fs.push(witness.0); + unsorted_witnesses_for_circuit.push((witness.2.reflect(), witness.1)); + } + + // send to storage + channel_sender + .send(WitnessGenerationArtifact::MemoryQueueWitness(( + unsorted_witnesses_for_circuit, + false, // unsorted + ))) + .unwrap(); + } + + memory_queue_simulator + }; + + // the simulation is mostly a sequential computation of hashes + // for this reason it is one of the slowest parts + // we are simulating explicit part of queue (direct memory queries) + for (cycle, query) in memory_queries.iter() { + let (_, intermediate_info) = + memory_queue_simulator.push_and_output_intermediate_data(*query, &round_function); + + memory_queue_states_accumulator.push(intermediate_info); + memory_queue_entry_states + .push((*cycle, transform_sponge_like_queue_state(intermediate_info))); + + // if we have collected witnesses for the circuit, we process and send part of them to the storage to free up RAM + if memory_queue_simulator.witness.len() == geometry.cycles_per_ram_permutation as usize { + memory_queue_simulator = process_simulation_result(memory_queue_simulator); + } + } + + assert_eq!(memory_queries.len(), memory_queue_states_accumulator.len()); + assert_eq!( + memory_queries.len(), + memory_queue_simulator.num_items as usize + ); + + let final_explicit_memory_queue_state = memory_queue_states_accumulator.last().unwrap().clone(); + + // now we need to handle implicit memory queries produced by decomitter, precompiles etc. + + use crate::witness::individual_circuits::memory_related::simulate_implicit_memory_queues; + let implicit_memory_states = simulate_implicit_memory_queues( + &mut memory_queue_simulator, + &mut memory_queue_states_accumulator, + &implicit_memory_queries, + round_function, + ); + + memory_queue_simulator = process_simulation_result(memory_queue_simulator); + + assert_eq!( + memory_queries.len() + implicit_memory_queries.amount_of_queries(), + encodings_witnesses_for_fs.len() + ); + + ( + memory_queue_entry_states, + final_explicit_memory_queue_state, + memory_queue_states_accumulator, + memory_queue_simulator, + implicit_memory_states, + encodings_witnesses_for_fs, + ) +} + +fn simulate_sorted_memory_queue( + geometry: GeometryConfig, + memory_queries: Arc>, + implicit_memory_queries: Arc, + round_function: Poseidon2Goldilocks, + channel_sender: Sender, +) -> ( + LastPerCircuitAccumulator>, + MemoryQueuePerCircuitSimulator, + Vec<[GoldilocksField; MEMORY_QUERY_PACKED_WIDTH]>, + Vec<(u32, MemoryQuery, usize)>, +) { + let mut all_memory_queries_sorted: Vec<&MemoryQuery> = memory_queries + .iter() + .map(|(_, query)| query) + .chain(implicit_memory_queries.iter()) + .collect(); + + use crate::witness::aux_data_structs::per_circuit_accumulator::PerCircuitAccumulator; + use rayon::prelude::*; + use std::cmp::Ordering; + + // sort by memory location, and then by timestamp + all_memory_queries_sorted.par_sort_by(|a, b| match a.location.cmp(&b.location) { + Ordering::Equal => a.timestamp.cmp(&b.timestamp), + a @ _ => a, + }); + + let amount_of_queries = all_memory_queries_sorted.len(); + assert_eq!( + memory_queries.len() + implicit_memory_queries.amount_of_queries(), + amount_of_queries + ); + + // simulator states are very RAM-heavy + let mut sorted_memory_queries_simulator = + MemoryQueuePerCircuitSimulator::using_container(PerCircuitAccumulator::with_flat_capacity( + geometry.cycles_per_ram_permutation as usize, + amount_of_queries, + )); + + // for RAM permutation circuits + let mut sorted_memory_queue_states_accumulator = + LastPerCircuitAccumulator::>::with_flat_capacity( + geometry.cycles_per_ram_permutation as usize, + amount_of_queries, + ); + + // for fs challenges in RAM permutation circuits + let mut encodings_witnesses_for_fs = Vec::with_capacity(amount_of_queries); + + let amount_of_ram_circuits = (amount_of_queries as u32 + geometry.cycles_per_ram_permutation + - 1) + / geometry.cycles_per_ram_permutation; + // for RAM permutation circuits + let mut sorted_queries_aux_data_for_chunks = + Vec::with_capacity(amount_of_ram_circuits as usize); + + // the simulation is mostly a sequential computation of hashes + // for this reason it is one of the slowest parts + for (idx, query) in all_memory_queries_sorted.into_iter().enumerate() { + let (_, intermediate_info) = sorted_memory_queries_simulator + .push_and_output_intermediate_data(*query, &round_function); + sorted_memory_queue_states_accumulator.push(intermediate_info); + + // if we have collected witnesses for the circuit, we process and send part of them to the storage to free up RAM + if sorted_memory_queries_simulator.witness.len() + == geometry.cycles_per_ram_permutation as usize + || idx == amount_of_queries - 1 + { + let witnesses; + (sorted_memory_queries_simulator, witnesses) = sorted_memory_queries_simulator + .replace_container(PerCircuitAccumulator::with_flat_capacity( + geometry.cycles_per_ram_permutation as usize, + geometry.cycles_per_ram_permutation as usize, + )); + + assert_eq!(witnesses.amount_of_circuits_accumulated(), 1); + + // should be only one iteration + for full_witnesses_for_circuit in witnesses.into_circuits(1) { + let sorted_states_len = full_witnesses_for_circuit.len(); + let num_nondet_writes_in_chunk = full_witnesses_for_circuit + .iter() + .filter(|el| { + let query = &el.2; + query.rw_flag == true + && query.timestamp.0 == 0 + && query.location.page.0 == BOOTLOADER_HEAP_PAGE + }) + .count(); + let last_sorted_query = full_witnesses_for_circuit.last().unwrap().2; + + sorted_queries_aux_data_for_chunks.push(( + num_nondet_writes_in_chunk as u32, + last_sorted_query, + sorted_states_len, + )); + + let mut sorted_witnesses_for_circuit = + Vec::with_capacity(full_witnesses_for_circuit.len()); + + // split full witnesses + for witness in full_witnesses_for_circuit.into_iter() { + encodings_witnesses_for_fs.push(witness.0); + sorted_witnesses_for_circuit.push((witness.2.reflect(), witness.1)); + } + + // send to storage + channel_sender + .send(WitnessGenerationArtifact::MemoryQueueWitness(( + sorted_witnesses_for_circuit, + true, // sorted + ))) + .unwrap(); + } + } + } + + ( + sorted_memory_queue_states_accumulator, + sorted_memory_queries_simulator, + encodings_witnesses_for_fs, + sorted_queries_aux_data_for_chunks, + ) +} + +use crate::witness::artifacts::DemuxedPrecompilesLogQueries; +use crate::witness::individual_circuits::log_demux::PrecompilesQueuesStates; + +pub(crate) struct PrecompilesInputData { + pub keccak_round_function_witnesses: Vec<(Cycle, LogQuery, Vec)>, + pub sha256_round_function_witnesses: Vec<(Cycle, LogQuery, Vec)>, + pub ecrecover_witnesses: Vec<(Cycle, LogQuery, ECRecoverRoundWitness)>, + pub secp256r1_verify_witnesses: Vec<(Cycle, LogQuery, Secp256r1VerifyRoundWitness)>, + pub logs_queues_states: PrecompilesQueuesStates, + pub logs_queries: DemuxedPrecompilesLogQueries, +} + +fn process_memory_related_circuits( + geometry: &GeometryConfig, + vm_snapshots: &Vec, + memory_queries: Vec<(Cycle, MemoryQuery)>, + num_non_deterministic_heap_queries: usize, + prepared_decommittment_queries: Vec<(Cycle, DecommittmentQuery)>, + executed_decommittment_queries: Vec<(Cycle, DecommittmentQuery, Vec)>, + precompiles_data: PrecompilesInputData, + round_function: &Poseidon2Goldilocks, + mut artifacts_callback: &mut CB, +) -> ( + MemoryCircuitsArtifacts, + MemoryArtifacts, + DecommitmentArtifactsForMainVM, + FirstAndLastCircuitWitness>, + Vec>, +) { + tracing::debug!("Processing memory related queues"); + + let mut circuits_data = MemoryCircuitsArtifacts::default(); + + use crate::witness::individual_circuits::memory_related::sort_decommit_requests::compute_decommitts_sorter_circuit_snapshots; + + tracing::debug!("Running code decommittments sorter simulation"); + + let ( + decommittment_queue_states, + decommittments_deduplicator_circuits_data, + decommiter_circuit_inputs, + ) = compute_decommitts_sorter_circuit_snapshots( + executed_decommittment_queries, + round_function, + geometry.cycles_code_decommitter_sorter as usize, + ); + + // first decommittment query (for bootloader) must come before the beginning of time + { + let initial_cycle = vm_snapshots[0].at_cycle; + let decommittment_queue_states_before_start_len = decommittment_queue_states + .iter() + .take_while(|el| el.0 < initial_cycle) + .count(); + + assert_eq!(decommittment_queue_states_before_start_len, 1); + } + + let decommitment_artifacts_for_main_vm = DecommitmentArtifactsForMainVM { + prepared_decommittment_queries: PerCircuitAccumulatorSparse::from_iter( + geometry.cycles_per_vm_snapshot as usize, + prepared_decommittment_queries, + ), + decommittment_queue_entry_states: CircuitsEntryAccumulatorSparse::from_iter( + geometry.cycles_per_vm_snapshot as usize, + (0, QueueState::placeholder_witness()), + decommittment_queue_states + .into_iter() + .map(|el| (el.0, transform_sponge_like_queue_state(el.1))), + ), + }; + circuits_data.decommittments_deduplicator_circuits_data = + decommittments_deduplicator_circuits_data; + + tracing::debug!("Running unsorted memory queue simulation"); + + use crate::witness::individual_circuits::memory_related::get_implicit_memory_queries; + + // precompiles and decommiter will produce additional implicit memory queries + let implicit_memory_queries = get_implicit_memory_queries( + &decommiter_circuit_inputs.deduplicated_decommit_requests_with_data, + &precompiles_data, + ); + + let amount_of_explicit_memory_queries = memory_queries.len(); + let amount_of_ram_circuits = ((amount_of_explicit_memory_queries + + implicit_memory_queries.amount_of_queries()) as u32 + + geometry.cycles_per_ram_permutation + - 1) + / geometry.cycles_per_ram_permutation; + + // Memory queues simulation is a slowest part in basic witness generation. + // Each queue simulation is sequential single-threaded computation of hashes. + // We will simulate unsorted and sorted queues in separate threads. + + let (tx, rx): ( + Sender, + Receiver, + ) = mpsc::channel(); + + let implicit_memory_queries_arc = Arc::new(implicit_memory_queries); + let memory_queries_arc = Arc::new(memory_queries); + + use std::thread; + let sorted_handle = { + let memory_queries_arc = memory_queries_arc.clone(); + let implicit_memory_queries_arc = implicit_memory_queries_arc.clone(); + let geometry = *geometry; + let round_function = *round_function; + let tx_thread = tx.clone(); + thread::spawn(move || { + simulate_sorted_memory_queue( + geometry, + memory_queries_arc, + implicit_memory_queries_arc, + round_function, + tx_thread, + ) + }) + }; + + let unsorted_handle = { + let memory_queries_arc = memory_queries_arc.clone(); + let implicit_memory_queries_arc = implicit_memory_queries_arc.clone(); + let geometry = *geometry; + let round_function = *round_function; + let tx_thread = tx.clone(); + thread::spawn(move || { + simulate_memory_queue( + geometry, + memory_queries_arc, + implicit_memory_queries_arc, + round_function, + tx_thread, + ) + }) + }; + + // send "finalized" part of RAM permutations circuits witnesses to storage (parts of simulator states, RAM-heavy) + // the rest will be processed further + for _ in 0..amount_of_ram_circuits * 2 { + let artifact = rx.recv().unwrap(); + artifacts_callback(artifact); + } + + let ( + memory_queue_entry_states_for_main_vm, + final_explicit_memory_queue_state, + memory_queue_states_accumulator, + memory_queue_simulator, + implicit_memory_states, + unsorted_encodings, + ) = unsorted_handle.join().unwrap(); + + let ( + sorted_memory_queue_states_accumulator, + sorted_memory_queue_simulator, + sorted_encodings, + sorted_queries_aux_data_for_chunks, + ) = sorted_handle.join().unwrap(); + + let memory_artifacts_for_main_vm = MemoryArtifacts { + memory_queries: Arc::into_inner(memory_queries_arc).unwrap(), + memory_queue_entry_states: memory_queue_entry_states_for_main_vm, + }; + let implicit_memory_queries = Arc::into_inner(implicit_memory_queries_arc).unwrap(); + + // direct VM related part is done, other subcircuit's functionality is moved to other functions + // that should properly do sorts and memory writes + + assert_eq!( + implicit_memory_queries.amount_of_queries(), + implicit_memory_states.amount_of_states() + ); + + use crate::witness::individual_circuits::memory_related::decommit_code::compute_decommitter_circuit_snapshots; + + tracing::debug!("Running code code decommitter simulation"); + + let (code_decommitter_circuits_data, amount_of_memory_queries) = + compute_decommitter_circuit_snapshots( + amount_of_explicit_memory_queries, + implicit_memory_queries.decommitter_memory_queries, + implicit_memory_states.decommitter_simulator_snapshots, + implicit_memory_states.decommitter_memory_states, + final_explicit_memory_queue_state, + decommiter_circuit_inputs, + round_function, + geometry.cycles_per_code_decommitter as usize, + ); + + circuits_data.code_decommitter_circuits_data = code_decommitter_circuits_data; + + use crate::zkevm_circuits::demux_log_queue::DemuxOutput; + + // keccak precompile + + use crate::witness::individual_circuits::memory_related::keccak256_round_function::keccak256_decompose_into_per_circuit_witness; + + tracing::debug!("Running keccak simulation"); + + let (keccak256_circuits_data, amount_of_memory_queries) = + keccak256_decompose_into_per_circuit_witness( + amount_of_memory_queries, + implicit_memory_queries.keccak256_memory_queries, + implicit_memory_states.keccak256_simulator_snapshots, + implicit_memory_states.keccak256_memory_states, + precompiles_data.keccak_round_function_witnesses, + precompiles_data.logs_queries.keccak, + precompiles_data.logs_queues_states.keccak, + geometry.cycles_per_keccak256_circuit as usize, + round_function, + ); + circuits_data.keccak256_circuits_data = keccak256_circuits_data; + + // sha256 precompile + + use crate::witness::individual_circuits::memory_related::sha256_round_function::sha256_decompose_into_per_circuit_witness; + + tracing::debug!("Running sha256 simulation"); + + let (sha256_circuits_data, amount_of_memory_queries) = + sha256_decompose_into_per_circuit_witness( + amount_of_memory_queries, + implicit_memory_queries.sha256_memory_queries, + implicit_memory_states.sha256_simulator_snapshots, + implicit_memory_states.sha256_memory_states, + precompiles_data.sha256_round_function_witnesses, + precompiles_data.logs_queries.sha256, + precompiles_data.logs_queues_states.sha256, + geometry.cycles_per_sha256_circuit as usize, + round_function, + ); + circuits_data.sha256_circuits_data = sha256_circuits_data; + + // ecrecover precompile + + use crate::witness::individual_circuits::memory_related::ecrecover::ecrecover_decompose_into_per_circuit_witness; + + tracing::debug!("Running ecrecover simulation"); + + let (ecrecover_circuits_data, amount_of_memory_queries) = + ecrecover_decompose_into_per_circuit_witness( + amount_of_memory_queries, + implicit_memory_queries.ecrecover_memory_queries, + implicit_memory_states.ecrecover_simulator_snapshots, + implicit_memory_states.ecrecover_memory_states, + precompiles_data.ecrecover_witnesses, + precompiles_data.logs_queries.ecrecover, + precompiles_data.logs_queues_states.ecrecover, + geometry.cycles_per_ecrecover_circuit as usize, + round_function, + ); + circuits_data.ecrecover_circuits_data = ecrecover_circuits_data; + + use crate::witness::individual_circuits::memory_related::secp256r1_verify::secp256r1_verify_decompose_into_per_circuit_witness; + + tracing::debug!("Running secp256r1_simulation simulation"); + + let (secp256r1_verify_circuits_data, amount_of_memory_queries) = + secp256r1_verify_decompose_into_per_circuit_witness( + amount_of_memory_queries, + implicit_memory_queries.secp256r1_memory_queries, + implicit_memory_states.secp256r1_simulator_snapshots, + implicit_memory_states.secp256r1_memory_states, + precompiles_data.secp256r1_verify_witnesses, + precompiles_data.logs_queries.secp256r1_verify, + precompiles_data.logs_queues_states.secp256r1_verify, + geometry.cycles_per_secp256r1_verify_circuit as usize, + round_function, + ); + circuits_data.secp256r1_verify_circuits_data = secp256r1_verify_circuits_data; + + use crate::witness::individual_circuits::memory_related::ram_permutation::compute_ram_circuit_snapshots; + + tracing::debug!("Running RAM permutation simulation"); + + let (ram_permutation_circuits, ram_permutation_circuits_compact_forms_witnesses) = + compute_ram_circuit_snapshots( + amount_of_memory_queries, + memory_queue_states_accumulator, + sorted_memory_queue_states_accumulator, + memory_queue_simulator, + sorted_memory_queue_simulator, + sorted_queries_aux_data_for_chunks, + sorted_encodings, + unsorted_encodings, + round_function, + num_non_deterministic_heap_queries, + geometry, + &mut artifacts_callback, + ); + + ( + circuits_data, + memory_artifacts_for_main_vm, + decommitment_artifacts_for_main_vm, + ram_permutation_circuits, + ram_permutation_circuits_compact_forms_witnesses, + ) +} + +pub enum WitnessGenerationArtifact { + BaseLayerCircuit(ZkSyncBaseLayerCircuit), + RecursionQueue( + ( + u64, + RecursionQueueSimulator, + Vec>, + ), + ), + MemoryQueueWitness((MemoryQueueStateWitnesses, bool)), // sorted/unsorted +} + +/// Make basic circuits instances and witnesses, +/// create artifacts for recursion layer and scheduler +pub(crate) fn create_artifacts_from_tracer( + tracer: WitnessTracer, + round_function: &Poseidon2Goldilocks, + geometry: &GeometryConfig, + entry_point_decommittment_query: (DecommittmentQuery, Vec), + tree: impl BinarySparseStorageTree<256, 32, 32, 8, 32, Blake2s256, ZkSyncStorageLeaf>, + num_non_deterministic_heap_queries: usize, + zk_porter_is_available: bool, + default_aa_code_hash: U256, + evm_simulator_code_hash: U256, + eip_4844_repack_inputs: [Option>; MAX_4844_BLOBS_PER_BLOCK], + trusted_setup_path: &str, + mut artifacts_callback: CB, +) -> ( + BlockFirstAndLastBasicCircuitsObservableWitnesses, + Vec>, + Vec>, +) { + // Our goals are: + // - make instances of basic layer circuits and pass them via circuit_callback (inputs for the base layer proving) + // - prepare inputs for recursion layer circuits and pass them via recursion_queue_callback (for the recursion layer proving) + // - prepare observable witnesses of first and last instances of each basic circuit (part of the scheduler inputs) + // - get all compact form witnesses for layer circuits (part of the scheduler inputs) + + let WitnessTracer { + memory_queries: vm_memory_queries_accumulated, + storage_queries, + cold_warm_refunds_logs, + pubdata_cost_logs, + prepared_decommittment_queries, + executed_decommittment_queries, + keccak_round_function_witnesses, + sha256_round_function_witnesses, + ecrecover_witnesses, + secp256r1_verify_witnesses, + mut callstack_with_aux_data, + vm_snapshots, + .. + } = tracer; + + // we should have an initial decommit query somewhat before the time + assert!(!prepared_decommittment_queries.is_empty()); + assert!(!executed_decommittment_queries.is_empty()); + assert!(prepared_decommittment_queries.len() >= executed_decommittment_queries.len()); + let (timestamp, query, witness) = &executed_decommittment_queries[0]; + assert!(*timestamp < crate::zk_evm::zkevm_opcode_defs::STARTING_TIMESTAMP); + assert_eq!(query, &entry_point_decommittment_query.0); + assert_eq!(witness, &entry_point_decommittment_query.1); + + assert!(vm_snapshots.len() >= 2); // we need at least entry point and the last save (after exit) + + assert!( + callstack_with_aux_data.depth == 0, + "parent frame didn't exit" + ); + + let full_callstack_history = std::mem::take(&mut callstack_with_aux_data.full_history); + // Since we finished the VM execution, current callstack entry now should be a root (outermost) frame + let final_callstack_entry = std::mem::take(&mut callstack_with_aux_data.current_entry); + let flat_new_frames_history = + std::mem::take(&mut callstack_with_aux_data.flat_new_frames_history); + drop(callstack_with_aux_data); + + tracing::debug!("Running multiplexed log queue simulation"); + + // We have all log queries in one multiplexed queue. We need to simulate this queue, + // demultiplex it and get log queue rollback tails for every call frame + let ( + log_states_data, + log_demux_circuit_inputs, + demuxed_log_queries, + log_rollback_tails_for_frames, + log_rollback_queue_heads, + ) = process_multiplexed_log_queue( + *geometry, + &full_callstack_history, + final_callstack_entry, + *round_function, + ); + + use std::thread; + let callstack_handle = { + let log_rollback_tails_for_frames = log_rollback_tails_for_frames.clone(); + let geometry = *geometry; + let round_function = *round_function; + thread::spawn(move || { + // We need to simulate all callstack states and prepare for each MainVM circuit: + // - entry value of callstack sponge + // - callstack witnesses (for every callstack state change) + // - detailed log queue state for entry call frame (frame index, log queue state) + callstack_simulation( + &geometry, + full_callstack_history, + log_states_data, + &log_rollback_tails_for_frames, + &round_function, + ) + }) + }; + + // demux log queue circuit + use crate::witness::individual_circuits::log_demux::process_logs_demux_and_make_circuits; + + tracing::debug!("Running log demux simulation"); + + // Get circuits and witnesses for logs demultiplexer. + // Also simulate all demuxed log queues states (used for corresponding circuits further) + let ( + log_demux_circuits, + log_demux_circuits_compact_forms_witnesses, + io_logs_queues_states, + precompiles_logs_queues_states, + ) = process_logs_demux_and_make_circuits( + log_demux_circuit_inputs, + &demuxed_log_queries, + geometry.cycles_per_log_demuxer as usize, + round_function, + geometry, + &mut artifacts_callback, + ); + + tracing::debug!("Processing log circuits"); + + // Process part of log circuits that do not use memory (I/O-like). + // Precompiles will be processed in process_memory_related_circuits. + // Also makes storage application circuits and compact form witnesses. + let (log_circuits_data, storage_application_circuits, storage_application_compact_forms) = + process_io_log_circuits( + geometry, + tree, + io_logs_queues_states, + demuxed_log_queries.io, + round_function, + &mut artifacts_callback, + ); + + tracing::debug!("Processing memory-related circuits"); + + let precompiles_data = PrecompilesInputData { + keccak_round_function_witnesses, + sha256_round_function_witnesses, + ecrecover_witnesses, + secp256r1_verify_witnesses, + logs_queues_states: precompiles_logs_queues_states, + logs_queries: demuxed_log_queries.precompiles, + }; + + // Prepare inputs for processing of all circuits related to memory + // (decommitts sorter, decommiter, precompiles, ram permutation). + // Prepare decommitment an memory inputs for MainVM circuits processing. + // Also makes ram permutation circuits and compact form witnesses. + // The most RAM- and CPU-demanding part of the witness generation. + let ( + memory_circuits_data, + memory_artifacts_for_main_vm, + decommitment_artifacts_for_main_vm, + ram_permutation_circuits, + ram_permutation_circuits_compact_forms_witnesses, + ) = process_memory_related_circuits( + geometry, + &vm_snapshots, + vm_memory_queries_accumulated, + num_non_deterministic_heap_queries, + prepared_decommittment_queries, + executed_decommittment_queries, + precompiles_data, + round_function, + &mut artifacts_callback, + ); + + tracing::debug!("Waiting for callstack sumulation"); + + let callstack_simulation_result = callstack_handle.join().unwrap(); + + tracing::debug!( + "Processing VM snapshots queue (total {:?})", + vm_snapshots.windows(2).len() + ); + + use crate::witness::individual_circuits::main_vm::process_main_vm; + + let in_circuit_global_context = GlobalContextWitness { + zkporter_is_available: zk_porter_is_available, + default_aa_code_hash, + evm_simulator_code_hash, + }; + + // Prepares inputs and makes circuit instances and compact forms for MainVM circuits + // Time consuming due to usually large number of circuits + let (main_vm_circuits, main_vm_circuits_compact_forms_witnesses) = process_main_vm( + geometry, + in_circuit_global_context, + memory_artifacts_for_main_vm, + decommitment_artifacts_for_main_vm, + storage_queries, + cold_warm_refunds_logs, + pubdata_cost_logs, + log_rollback_tails_for_frames, + log_rollback_queue_heads, + callstack_simulation_result, + flat_new_frames_history, + vm_snapshots, + *round_function, + &mut artifacts_callback, + ); + + tracing::debug!("Making remaining circuits"); + + // Some circuit instances and compact form witnesses have already been made in previous functions + // Now we'll make the rest + + let LogCircuitsArtifacts { + storage_deduplicator_circuit_data, + events_deduplicator_circuit_data, + l1_messages_deduplicator_circuit_data, + l1_messages_linear_hash_data, + transient_storage_sorter_circuit_data, + } = log_circuits_data; + + let MemoryCircuitsArtifacts { + code_decommitter_circuits_data, + decommittments_deduplicator_circuits_data, + keccak256_circuits_data, + sha256_circuits_data, + ecrecover_circuits_data, + secp256r1_verify_circuits_data, + } = memory_circuits_data; + + // Code decommitter sorter + let ( + code_decommittments_sorter_circuits, + code_decommittments_sorter_circuits_compact_forms_witnesses, + ) = make_circuits( + geometry.cycles_code_decommitter_sorter, + BaseLayerCircuitType::DecommitmentsFilter, + decommittments_deduplicator_circuits_data, + *round_function, + |x| ZkSyncBaseLayerCircuit::CodeDecommittmentsSorter(x), + &mut artifacts_callback, + ); + + // Actual decommitter + let (code_decommitter_circuits, code_decommitter_circuits_compact_forms_witnesses) = + make_circuits( + geometry.cycles_per_code_decommitter, + BaseLayerCircuitType::Decommiter, + code_decommitter_circuits_data, + *round_function, + |x| ZkSyncBaseLayerCircuit::CodeDecommitter(x), + &mut artifacts_callback, + ); + + // keccak precompiles + let (keccak_precompile_circuits, keccak_precompile_circuits_compact_forms_witnesses) = + make_circuits( + geometry.cycles_per_keccak256_circuit, + BaseLayerCircuitType::KeccakPrecompile, + keccak256_circuits_data, + *round_function, + |x| ZkSyncBaseLayerCircuit::KeccakRoundFunction(x), + &mut artifacts_callback, + ); + + // sha256 precompiles + let (sha256_precompile_circuits, sha256_precompile_circuits_compact_forms_witnesses) = + make_circuits( + geometry.cycles_per_sha256_circuit, + BaseLayerCircuitType::Sha256Precompile, + sha256_circuits_data, + *round_function, + |x| ZkSyncBaseLayerCircuit::Sha256RoundFunction(x), + &mut artifacts_callback, + ); + + // ecrecover precompiles + let (ecrecover_precompile_circuits, ecrecover_precompile_circuits_compact_forms_witnesses) = + make_circuits( + geometry.cycles_per_ecrecover_circuit, + BaseLayerCircuitType::EcrecoverPrecompile, + ecrecover_circuits_data, + *round_function, + |x| ZkSyncBaseLayerCircuit::ECRecover(x), + &mut artifacts_callback, + ); + + // secp256r1 verify + let (secp256r1_verify_circuits, secp256r1_verify_circuits_compact_forms_witnesses) = + make_circuits( + geometry.cycles_per_secp256r1_verify_circuit, + BaseLayerCircuitType::Secp256r1Verify, + secp256r1_verify_circuits_data, + *round_function, + |x| ZkSyncBaseLayerCircuit::Secp256r1Verify(x), + &mut artifacts_callback, + ); + + // storage sorter + let (storage_sorter_circuits, storage_sorter_circuit_compact_form_witnesses) = make_circuits( + geometry.cycles_per_storage_sorter, + BaseLayerCircuitType::StorageFilter, + storage_deduplicator_circuit_data, + *round_function, + |x| ZkSyncBaseLayerCircuit::StorageSorter(x), + &mut artifacts_callback, + ); + + // events sorter + let (events_sorter_circuits, events_sorter_circuits_compact_forms_witnesses) = make_circuits( + geometry.cycles_per_events_or_l1_messages_sorter, + BaseLayerCircuitType::EventsRevertsFilter, + events_deduplicator_circuit_data, + *round_function, + |x| ZkSyncBaseLayerCircuit::EventsSorter(x), + &mut artifacts_callback, + ); + + // l1 messages sorter + let (l1_messages_sorter_circuits, l1_messages_sorter_circuits_compact_forms_witnesses) = + make_circuits( + geometry.cycles_per_events_or_l1_messages_sorter, + BaseLayerCircuitType::L1MessagesRevertsFilter, + l1_messages_deduplicator_circuit_data, + *round_function, + |x| ZkSyncBaseLayerCircuit::L1MessagesSorter(x), + &mut artifacts_callback, + ); + + // l1 messages pubdata hasher + let (l1_messages_hasher_circuits, l1_messages_hasher_circuits_compact_forms_witnesses) = + make_circuits( + geometry.limit_for_l1_messages_pudata_hasher, + BaseLayerCircuitType::L1MessagesHasher, + l1_messages_linear_hash_data, + *round_function, + |x| ZkSyncBaseLayerCircuit::L1MessagesHasher(x), + &mut artifacts_callback, + ); + + // transient storage sorter + let ( + transient_storage_sorter_circuits, + transient_storage_sorter_circuits_compact_forms_witnesses, + ) = make_circuits( + geometry.cycles_per_transient_storage_sorter, + BaseLayerCircuitType::TransientStorageChecker, + transient_storage_sorter_circuit_data, + *round_function, + |x| ZkSyncBaseLayerCircuit::TransientStorageSorter(x), + &mut artifacts_callback, + ); + + // eip 4844 circuits are basic, but they do not need closed form input commitments + + use crate::witness::individual_circuits::eip4844_repack::compute_eip_4844; + let eip_4844_circuits = compute_eip_4844(eip_4844_repack_inputs, trusted_setup_path); + + let (_eip_4844_circuits, _eip_4844_circuits_compact_forms_witnesses) = make_circuits( + 4096, + BaseLayerCircuitType::EIP4844Repack, + eip_4844_circuits.clone(), + *round_function, + |x| ZkSyncBaseLayerCircuit::EIP4844Repack(x), + &mut artifacts_callback, + ); + + // All done! + + let basic_circuits_first_and_last_observable_witnesses = + BlockFirstAndLastBasicCircuitsObservableWitnesses { + main_vm_circuits, + code_decommittments_sorter_circuits, + code_decommitter_circuits, + log_demux_circuits, + keccak_precompile_circuits, + sha256_precompile_circuits, + ecrecover_precompile_circuits, + ram_permutation_circuits, + storage_sorter_circuits, + storage_application_circuits, + events_sorter_circuits, + l1_messages_sorter_circuits, + l1_messages_hasher_circuits, + transient_storage_sorter_circuits, + secp256r1_verify_circuits, + }; + + // NOTE: this should follow in a sequence same as scheduler's work and `SEQUENCE_OF_CIRCUIT_TYPES` + + let all_compact_forms = main_vm_circuits_compact_forms_witnesses + .into_iter() + .chain(code_decommittments_sorter_circuits_compact_forms_witnesses) + .chain(code_decommitter_circuits_compact_forms_witnesses) + .chain(log_demux_circuits_compact_forms_witnesses) + .chain(keccak_precompile_circuits_compact_forms_witnesses) + .chain(sha256_precompile_circuits_compact_forms_witnesses) + .chain(ecrecover_precompile_circuits_compact_forms_witnesses) + .chain(ram_permutation_circuits_compact_forms_witnesses) + .chain(storage_sorter_circuit_compact_form_witnesses) + .chain(storage_application_compact_forms) + .chain(events_sorter_circuits_compact_forms_witnesses) + .chain(l1_messages_sorter_circuits_compact_forms_witnesses) + .chain(l1_messages_hasher_circuits_compact_forms_witnesses) + .chain(transient_storage_sorter_circuits_compact_forms_witnesses) + .chain(secp256r1_verify_circuits_compact_forms_witnesses) + .collect(); + + ( + basic_circuits_first_and_last_observable_witnesses, + all_compact_forms, + eip_4844_circuits, + ) +} diff --git a/crates/zkevm_test_harness/src/witness/postprocessing/mod.rs b/crates/zkevm_test_harness/src/witness/postprocessing/mod.rs new file mode 100644 index 0000000..2bd764d --- /dev/null +++ b/crates/zkevm_test_harness/src/witness/postprocessing/mod.rs @@ -0,0 +1,549 @@ +use super::*; + +use crate::witness::utils::*; +use crate::zkevm_circuits::eip_4844::input::EIP4844OutputData; +use boojum::gadgets::queue::full_state_queue::FullStateCircuitQueueRawWitness; +use boojum::gadgets::traits::encodable::WitnessVarLengthEncodable; +use circuit_definitions::aux_definitions::witness_oracle::VmWitnessOracle; +use circuit_definitions::boojum::field::U64Representable; +use circuit_definitions::boojum::gadgets::traits::allocatable::CSAllocatable; +use circuit_definitions::boojum::gadgets::traits::encodable::CircuitVarLengthEncodable; +use circuit_definitions::boojum::gadgets::traits::witnessable::WitnessHookable; +use circuit_definitions::circuit_definitions::{ + base_layer::*, ZkSyncUniformCircuitInstance, ZkSyncUniformSynthesisFunction, +}; +use circuit_definitions::encodings::recursion_request::{ + RecursionQueueSimulator, RecursionRequest, +}; +use circuit_definitions::zkevm_circuits::base_structures::precompile_input_outputs::PrecompileFunctionInputData; +use circuit_definitions::zkevm_circuits::base_structures::precompile_input_outputs::PrecompileFunctionOutputData; +use circuit_definitions::zkevm_circuits::code_unpacker_sha256::input::CodeDecommitterCircuitInstanceWitness; +use circuit_definitions::zkevm_circuits::code_unpacker_sha256::input::CodeDecommitterFSMInputOutput; +use circuit_definitions::zkevm_circuits::code_unpacker_sha256::input::CodeDecommitterInputData; +use circuit_definitions::zkevm_circuits::code_unpacker_sha256::input::CodeDecommitterOutputData; +use circuit_definitions::zkevm_circuits::demux_log_queue::input::LogDemuxerCircuitInstanceWitness; +use circuit_definitions::zkevm_circuits::demux_log_queue::input::LogDemuxerFSMInputOutput; +use circuit_definitions::zkevm_circuits::demux_log_queue::input::LogDemuxerInputData; +use circuit_definitions::zkevm_circuits::demux_log_queue::input::LogDemuxerOutputData; +use circuit_definitions::zkevm_circuits::ecrecover::EcrecoverCircuitFSMInputOutput; +use circuit_definitions::zkevm_circuits::ecrecover::EcrecoverCircuitInstanceWitness; +use circuit_definitions::zkevm_circuits::eip_4844::input::EIP4844CircuitInstanceWitness; +use circuit_definitions::zkevm_circuits::fsm_input_output::{ + ClosedFormInputCompactFormWitness, ClosedFormInputWitness, +}; +use circuit_definitions::zkevm_circuits::keccak256_round_function::input::Keccak256RoundFunctionCircuitInstanceWitness; +use circuit_definitions::zkevm_circuits::keccak256_round_function::input::Keccak256RoundFunctionFSMInputOutput; +use circuit_definitions::zkevm_circuits::linear_hasher::input::{ + LinearHasherCircuitInstanceWitness, LinearHasherInputData, LinearHasherOutputData, +}; +use circuit_definitions::zkevm_circuits::log_sorter::input::EventsDeduplicatorFSMInputOutput; +use circuit_definitions::zkevm_circuits::log_sorter::input::EventsDeduplicatorInputData; +use circuit_definitions::zkevm_circuits::log_sorter::input::EventsDeduplicatorInstanceWitness; +use circuit_definitions::zkevm_circuits::log_sorter::input::EventsDeduplicatorOutputData; +use circuit_definitions::zkevm_circuits::ram_permutation::input::RamPermutationCircuitInstanceWitness; +use circuit_definitions::zkevm_circuits::ram_permutation::input::RamPermutationFSMInputOutput; +use circuit_definitions::zkevm_circuits::ram_permutation::input::RamPermutationInputData; +use circuit_definitions::zkevm_circuits::scheduler::aux::BaseLayerCircuitType; +use circuit_definitions::zkevm_circuits::secp256r1_verify::input::*; +use circuit_definitions::zkevm_circuits::secp256r1_verify::Secp256r1VerifyCircuitInstanceWitness; +use circuit_definitions::zkevm_circuits::sha256_round_function::input::Sha256RoundFunctionCircuitInstanceWitness; +use circuit_definitions::zkevm_circuits::sha256_round_function::input::Sha256RoundFunctionFSMInputOutput; +use circuit_definitions::zkevm_circuits::sort_decommittment_requests::input::CodeDecommittmentsDeduplicatorFSMInputOutput; +use circuit_definitions::zkevm_circuits::sort_decommittment_requests::input::CodeDecommittmentsDeduplicatorInputData; +use circuit_definitions::zkevm_circuits::sort_decommittment_requests::input::CodeDecommittmentsDeduplicatorInstanceWitness; +use circuit_definitions::zkevm_circuits::sort_decommittment_requests::input::CodeDecommittmentsDeduplicatorOutputData; +use circuit_definitions::zkevm_circuits::storage_application::input::StorageApplicationCircuitInstanceWitness; +use circuit_definitions::zkevm_circuits::storage_application::input::StorageApplicationFSMInputOutput; +use circuit_definitions::zkevm_circuits::storage_application::input::StorageApplicationInputData; +use circuit_definitions::zkevm_circuits::storage_application::input::StorageApplicationOutputData; +use circuit_definitions::zkevm_circuits::storage_validity_by_grand_product::input::StorageDeduplicatorFSMInputOutput; +use circuit_definitions::zkevm_circuits::storage_validity_by_grand_product::input::StorageDeduplicatorInputData; +use circuit_definitions::zkevm_circuits::storage_validity_by_grand_product::input::StorageDeduplicatorInstanceWitness; +use circuit_definitions::zkevm_circuits::storage_validity_by_grand_product::input::StorageDeduplicatorOutputData; +use circuit_definitions::zkevm_circuits::transient_storage_validity_by_grand_product::input::TransientStorageDeduplicatorInstanceWitness; +use circuit_definitions::zkevm_circuits::transient_storage_validity_by_grand_product::input::*; +use circuit_definitions::Field; +use crossbeam::atomic::AtomicCell; +use derivative::Derivative; +use observable_witness::ObservableWitness; +use oracle::WitnessGenerationArtifact; +use zkevm_circuits::base_structures::memory_query::{MemoryQuery, MEMORY_QUERY_PACKED_WIDTH}; +use zkevm_circuits::base_structures::vm_state::FULL_SPONGE_QUEUE_STATE_WIDTH; +use zkevm_circuits::ram_permutation::input::RamPermutationCycleInputOutputWitness; + +use std::sync::Arc; + +use crate::zkevm_circuits::base_structures::vm_state::VmLocalState; +use zkevm_circuits::fsm_input_output::circuit_inputs::main_vm::{ + VmCircuitWitness, VmInputData, VmOutputData, +}; + +pub const L1_MESSAGES_MERKLIZER_OUTPUT_LINEAR_HASH: bool = false; + +use crate::boojum::field::SmallField; + +pub mod observable_witness; + +use crate::witness::postprocessing::observable_witness::*; + +pub(crate) struct BlockFirstAndLastBasicCircuitsObservableWitnesses { + pub main_vm_circuits: FirstAndLastCircuitWitness>, + pub code_decommittments_sorter_circuits: + FirstAndLastCircuitWitness>, + pub code_decommitter_circuits: + FirstAndLastCircuitWitness>, + pub log_demux_circuits: FirstAndLastCircuitWitness>, + pub keccak_precompile_circuits: + FirstAndLastCircuitWitness>, + pub sha256_precompile_circuits: + FirstAndLastCircuitWitness>, + pub ecrecover_precompile_circuits: + FirstAndLastCircuitWitness>, + pub secp256r1_verify_circuits: + FirstAndLastCircuitWitness>, + pub ram_permutation_circuits: + FirstAndLastCircuitWitness>, + pub storage_sorter_circuits: + FirstAndLastCircuitWitness>, + pub storage_application_circuits: + FirstAndLastCircuitWitness>, + pub transient_storage_sorter_circuits: + FirstAndLastCircuitWitness>, + pub events_sorter_circuits: + FirstAndLastCircuitWitness>, + pub l1_messages_sorter_circuits: + FirstAndLastCircuitWitness>, + pub l1_messages_hasher_circuits: + FirstAndLastCircuitWitness>, +} + +pub struct FirstAndLastCircuitWitness { + pub first: Option, + pub last: Option, +} + +impl Default for FirstAndLastCircuitWitness { + fn default() -> Self { + Self { + first: None, + last: None, + } + } +} + +/// Implemented for structs that have a field called `closed_form_input`. +/// They are defined as if they were completely unrelated in era-zkevm_circuits. +pub(crate) trait ClosedFormInputField { + type T: Clone + + std::fmt::Debug + + CSAllocatable + + CircuitVarLengthEncodable + + WitnessVarLengthEncodable + + WitnessHookable; + + type IN: Clone + + std::fmt::Debug + + CSAllocatable + + CircuitVarLengthEncodable + + WitnessVarLengthEncodable + + WitnessHookable; + + type OUT: Clone + + std::fmt::Debug + + CSAllocatable + + CircuitVarLengthEncodable + + WitnessVarLengthEncodable + + WitnessHookable; + + fn closed_form_input(&mut self) -> &mut ClosedFormInputWitness + where + >::Witness: serde::Serialize + serde::de::DeserializeOwned + Eq, + >::Witness: + serde::Serialize + serde::de::DeserializeOwned + Eq, + >::Witness: + serde::Serialize + serde::de::DeserializeOwned + Eq; +} + +impl ClosedFormInputField for VmCircuitWitness> { + type T = VmLocalState; + type IN = VmInputData; + type OUT = VmOutputData; + + fn closed_form_input( + &mut self, + ) -> &mut ClosedFormInputWitness { + &mut self.closed_form_input + } +} + +impl ClosedFormInputField for LinearHasherCircuitInstanceWitness { + type T = (); + type IN = LinearHasherInputData; + type OUT = LinearHasherOutputData; + + fn closed_form_input( + &mut self, + ) -> &mut ClosedFormInputWitness { + &mut self.closed_form_input + } +} + +impl ClosedFormInputField for CodeDecommittmentsDeduplicatorInstanceWitness { + type T = CodeDecommittmentsDeduplicatorFSMInputOutput; + type IN = CodeDecommittmentsDeduplicatorInputData; + type OUT = CodeDecommittmentsDeduplicatorOutputData; + + fn closed_form_input( + &mut self, + ) -> &mut ClosedFormInputWitness { + &mut self.closed_form_input + } +} + +impl ClosedFormInputField for CodeDecommitterCircuitInstanceWitness { + type T = CodeDecommitterFSMInputOutput; + type IN = CodeDecommitterInputData; + type OUT = CodeDecommitterOutputData; + + fn closed_form_input( + &mut self, + ) -> &mut ClosedFormInputWitness { + &mut self.closed_form_input + } +} + +impl ClosedFormInputField for LogDemuxerCircuitInstanceWitness { + type T = LogDemuxerFSMInputOutput; + type IN = LogDemuxerInputData; + type OUT = LogDemuxerOutputData; + + fn closed_form_input( + &mut self, + ) -> &mut ClosedFormInputWitness { + &mut self.closed_form_input + } +} + +impl ClosedFormInputField for Keccak256RoundFunctionCircuitInstanceWitness { + type T = Keccak256RoundFunctionFSMInputOutput; + type IN = PrecompileFunctionInputData; + type OUT = PrecompileFunctionOutputData; + + fn closed_form_input( + &mut self, + ) -> &mut ClosedFormInputWitness { + &mut self.closed_form_input + } +} + +impl ClosedFormInputField for Sha256RoundFunctionCircuitInstanceWitness { + type T = Sha256RoundFunctionFSMInputOutput; + type IN = PrecompileFunctionInputData; + type OUT = PrecompileFunctionOutputData; + + fn closed_form_input( + &mut self, + ) -> &mut ClosedFormInputWitness { + &mut self.closed_form_input + } +} + +impl ClosedFormInputField for EcrecoverCircuitInstanceWitness { + type T = EcrecoverCircuitFSMInputOutput; + type IN = PrecompileFunctionInputData; + type OUT = PrecompileFunctionOutputData; + + fn closed_form_input( + &mut self, + ) -> &mut ClosedFormInputWitness { + &mut self.closed_form_input + } +} + +impl ClosedFormInputField for RamPermutationCircuitInstanceWitness { + type T = RamPermutationFSMInputOutput; + type IN = RamPermutationInputData; + type OUT = (); + + fn closed_form_input( + &mut self, + ) -> &mut ClosedFormInputWitness { + &mut self.closed_form_input + } +} + +impl ClosedFormInputField for StorageDeduplicatorInstanceWitness { + type T = StorageDeduplicatorFSMInputOutput; + type IN = StorageDeduplicatorInputData; + type OUT = StorageDeduplicatorOutputData; + + fn closed_form_input( + &mut self, + ) -> &mut ClosedFormInputWitness { + &mut self.closed_form_input + } +} + +impl ClosedFormInputField for StorageApplicationCircuitInstanceWitness { + type T = StorageApplicationFSMInputOutput; + type IN = StorageApplicationInputData; + type OUT = StorageApplicationOutputData; + + fn closed_form_input( + &mut self, + ) -> &mut ClosedFormInputWitness { + &mut self.closed_form_input + } +} + +impl ClosedFormInputField for EventsDeduplicatorInstanceWitness { + type T = EventsDeduplicatorFSMInputOutput; + type IN = EventsDeduplicatorInputData; + type OUT = EventsDeduplicatorOutputData; + + fn closed_form_input( + &mut self, + ) -> &mut ClosedFormInputWitness { + &mut self.closed_form_input + } +} + +impl ClosedFormInputField for TransientStorageDeduplicatorInstanceWitness { + type T = TransientStorageDeduplicatorFSMInputOutput; + type IN = TransientStorageDeduplicatorInputData; + type OUT = (); + + fn closed_form_input( + &mut self, + ) -> &mut ClosedFormInputWitness { + &mut self.closed_form_input + } +} + +impl ClosedFormInputField for Secp256r1VerifyCircuitInstanceWitness { + type T = Secp256r1VerifyCircuitFSMInputOutput; + type IN = PrecompileFunctionInputData; + type OUT = PrecompileFunctionOutputData; + + fn closed_form_input( + &mut self, + ) -> &mut ClosedFormInputWitness { + &mut self.closed_form_input + } +} + +impl ClosedFormInputField for EIP4844CircuitInstanceWitness { + type T = (); + type IN = (); + type OUT = EIP4844OutputData; + + fn closed_form_input( + &mut self, + ) -> &mut ClosedFormInputWitness { + &mut self.closed_form_input + } +} + +pub(crate) struct CircuitMaker> { + geometry: u32, + round_function: Poseidon2Goldilocks, + observable_input: Option<>::Witness>, + recurion_queue_simulator: RecursionQueueSimulator, + compact_form_witnesses: Vec>, + extremes: FirstAndLastCircuitWitness>, +} + +impl CircuitMaker +where + T: ClosedFormInputField, + >::Witness: + serde::Serialize + serde::de::DeserializeOwned + Eq, + >::Witness: + serde::Serialize + serde::de::DeserializeOwned + Eq, + >::Witness: + serde::Serialize + serde::de::DeserializeOwned + Eq, +{ + pub(crate) fn new(geometry: u32, round_function: Poseidon2Goldilocks) -> Self { + Self { + geometry, + round_function, + observable_input: None, + recurion_queue_simulator: RecursionQueueSimulator::empty(), + compact_form_witnesses: vec![], + extremes: FirstAndLastCircuitWitness::default(), + } + } + + pub(crate) fn process>( + &mut self, + mut circuit_input: T, + circuit_type: BaseLayerCircuitType, + ) -> ZkSyncUniformCircuitInstance + where + S: ZkSyncUniformSynthesisFunction< + GoldilocksField, + Config = usize, + Witness = T, + RoundFunction = Poseidon2Goldilocks, + >, + { + if self.observable_input.is_none() { + self.observable_input = + Some(circuit_input.closed_form_input().observable_input.clone()); + } else { + circuit_input.closed_form_input().observable_input = + self.observable_input.as_ref().unwrap().clone(); + } + + let (proof_system_input, compact_form_witness) = + simulate_public_input_value_from_encodable_witness( + circuit_input.closed_form_input().clone(), + &self.round_function, + ); + + self.compact_form_witnesses.push(compact_form_witness); + + let circuit = ZkSyncUniformCircuitInstance { + witness: AtomicCell::new(Some(circuit_input)), + config: Arc::new(self.geometry as usize), + round_function: Arc::new(self.round_function), + expected_public_input: Some(proof_system_input), + }; + let mut wit: T = circuit.clone_witness().unwrap(); + if self.extremes.first.is_none() { + self.extremes.first = Some(ObservableWitness { + observable_input: wit.closed_form_input().observable_input.clone(), + observable_output: wit.closed_form_input().observable_output.clone(), + }); + } + self.extremes.last = Some(ObservableWitness { + observable_input: wit.closed_form_input().observable_input.clone(), + observable_output: wit.closed_form_input().observable_output.clone(), + }); + + let recursive_request = RecursionRequest { + circuit_type: GoldilocksField::from_u64_unchecked(circuit_type as u64), + public_input: proof_system_input, + }; + self.recurion_queue_simulator + .push(recursive_request, &self.round_function); + + circuit + } + + pub(crate) fn into_results( + self, + ) -> ( + FirstAndLastCircuitWitness>, + RecursionQueueSimulator, + Vec>, + ) { + // if we have NO compact form inputs, we need to create a dummy value for scheduler + // as scheduler can only skip one type at the time, so we need some meaningless compact form witness + let compact_form_witnesses = if self.compact_form_witnesses.is_empty() { + use crate::boojum::field::Field; + use crate::zkevm_circuits::fsm_input_output::CLOSED_FORM_COMMITTMENT_LENGTH; + + vec![ClosedFormInputCompactFormWitness:: { + start_flag: true, + completion_flag: true, + observable_input_committment: [GoldilocksField::ZERO; + CLOSED_FORM_COMMITTMENT_LENGTH], + observable_output_committment: [GoldilocksField::ZERO; + CLOSED_FORM_COMMITTMENT_LENGTH], + hidden_fsm_input_committment: [GoldilocksField::ZERO; + CLOSED_FORM_COMMITTMENT_LENGTH], + hidden_fsm_output_committment: [GoldilocksField::ZERO; + CLOSED_FORM_COMMITTMENT_LENGTH], + }] + } else { + self.compact_form_witnesses + }; + + ( + self.extremes, + self.recurion_queue_simulator, + compact_form_witnesses, + ) + } +} + +pub(crate) fn make_circuits< + T: ClosedFormInputField, + S: ZkSyncUniformSynthesisFunction, + WCB: Fn(ZkSyncUniformCircuitInstance) -> ZkSyncBaseLayerCircuit, + CB: FnMut(WitnessGenerationArtifact), +>( + geometry: u32, + circuit_type: BaseLayerCircuitType, + circuits_data: Vec, + round_function: Poseidon2Goldilocks, + wrap_circuit: WCB, + artifacts_callback: &mut CB, +) -> ( + FirstAndLastCircuitWitness>, + Vec>, +) +where + >::Witness: + serde::Serialize + serde::de::DeserializeOwned + Eq, + >::Witness: + serde::Serialize + serde::de::DeserializeOwned + Eq, + >::Witness: + serde::Serialize + serde::de::DeserializeOwned + Eq, + S: ZkSyncUniformSynthesisFunction< + GoldilocksField, + Config = usize, + Witness = T, + RoundFunction = Poseidon2Goldilocks, + >, +{ + let mut maker = CircuitMaker::new(geometry, round_function.clone()); + + for circuit_input in circuits_data.into_iter() { + artifacts_callback(WitnessGenerationArtifact::BaseLayerCircuit(wrap_circuit( + maker.process(circuit_input, circuit_type), + ))); + } + + let ( + first_and_last_observable_witnesses, + recursion_queue_simulator, + circuits_compact_forms_witnesses, + ) = maker.into_results(); + artifacts_callback(WitnessGenerationArtifact::RecursionQueue(( + circuit_type as u64, + recursion_queue_simulator, + circuits_compact_forms_witnesses.clone(), + ))); + + ( + first_and_last_observable_witnesses, + circuits_compact_forms_witnesses, + ) +} + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Debug, Default)] +#[serde(bound = "")] +pub struct RamPermutationQueuesWitness { + pub unsorted_queue_witness: FullStateCircuitQueueRawWitness< + F, + MemoryQuery, + FULL_SPONGE_QUEUE_STATE_WIDTH, + MEMORY_QUERY_PACKED_WIDTH, + >, + pub sorted_queue_witness: FullStateCircuitQueueRawWitness< + F, + MemoryQuery, + FULL_SPONGE_QUEUE_STATE_WIDTH, + MEMORY_QUERY_PACKED_WIDTH, + >, +} + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Debug, Default)] +#[serde(bound = "")] +pub struct RamPermutationCircuitInstancePartialWitness { + pub closed_form_input: RamPermutationCycleInputOutputWitness, +} diff --git a/crates/zkevm_test_harness/src/witness/postprocessing/observable_witness.rs b/crates/zkevm_test_harness/src/witness/postprocessing/observable_witness.rs new file mode 100644 index 0000000..7af2aee --- /dev/null +++ b/crates/zkevm_test_harness/src/witness/postprocessing/observable_witness.rs @@ -0,0 +1,40 @@ +use crate::witness::postprocessing::CSAllocatable; +use crate::witness::postprocessing::SmallField; +use crate::witness::postprocessing::*; +use circuit_definitions::aux_definitions::witness_oracle::VmWitnessOracle; +pub(crate) struct ObservableWitness> { + pub observable_input: >::Witness, + pub observable_output: >::Witness, +} + +pub(crate) type VmObservableWitness = + ObservableWitness>>; +pub(crate) type LinearHasherObservableWitness = + ObservableWitness>; +pub(crate) type CodeDecommittmentsDeduplicatorObservableWitness = + ObservableWitness>; +pub(crate) type CodeDecommitterObservableWitness = + ObservableWitness>; +pub(crate) type LogDemuxerObservableWitness = + ObservableWitness>; +pub(crate) type Keccak256RoundFunctionObservableWitness = + ObservableWitness>; + +pub(crate) type Sha256RoundFunctionObservableWitness = + ObservableWitness>; +pub(crate) type EcrecoverObservableWitness = + ObservableWitness>; +pub(crate) type Secp256r1VerifyObservableWitness = + ObservableWitness>; +pub(crate) type RamPermutationObservableWitness = + ObservableWitness>; + +pub(crate) type StorageDeduplicatorObservableWitness = + ObservableWitness>; +pub(crate) type StorageApplicationObservableWitness = + ObservableWitness>; + +pub(crate) type TransientStorageDeduplicatorObservableWitness = + ObservableWitness>; +pub(crate) type EventsDeduplicatorObservableWitness = + ObservableWitness>; diff --git a/crates/zkevm_test_harness/src/witness/recursive_aggregation.rs b/crates/zkevm_test_harness/src/witness/recursive_aggregation.rs new file mode 100644 index 0000000..0ed36e9 --- /dev/null +++ b/crates/zkevm_test_harness/src/witness/recursive_aggregation.rs @@ -0,0 +1,412 @@ +use crate::boojum::{ + cs::traits::cs::ConstraintSystem, + field::{goldilocks::GoldilocksExt2, U64Representable}, + gadgets::{ + queue::QueueTailStateWitness, recursion::allocated_vk::AllocatedVerificationKey, + traits::allocatable::CSAllocatable, + }, +}; + +use super::*; +use crate::boojum::gadgets::num::Num; +use crate::boojum::gadgets::queue::full_state_queue::FullStateCircuitQueueRawWitness; +use crate::boojum::gadgets::recursion::recursive_tree_hasher::CircuitGoldilocksPoseidon2Sponge; +use crate::witness::utils::take_sponge_like_queue_state_from_simulator; +use crate::zkevm_circuits::recursion::{ + leaf_layer::input::*, + node_layer::{input::RecursionNodeInputWitness, NodeLayerRecursionConfig}, + VK_COMMITMENT_LENGTH, +}; +use crate::zkevm_circuits::scheduler::LEAF_LAYER_PARAMETERS_COMMITMENT_LENGTH; +use circuit_definitions::recursion_layer_proof_config; +use circuit_definitions::{ + zkevm_circuits::scheduler::aux::NUM_CIRCUIT_TYPES_TO_SCHEDULE, ZkSyncDefaultRoundFunction, +}; +use std::collections::VecDeque; + +type F = GoldilocksField; +type EXT = GoldilocksExt2; +type H = CircuitGoldilocksPoseidon2Sponge; + +use crate::boojum::algebraic_props::round_function::AlgebraicRoundFunction; +use crate::boojum::gadgets::recursion::recursive_tree_hasher::RecursiveTreeHasher; +use crate::boojum::gadgets::traits::encodable::CircuitVarLengthEncodable; +use crate::boojum::gadgets::traits::round_function::BuildableCircuitRoundFunction; +use crate::boojum::gadgets::traits::witnessable::WitnessHookable; +use crate::zkevm_circuits::fsm_input_output::commit_variable_length_encodable_item; +use crate::zkevm_circuits::recursion::leaf_layer::LeafLayerRecursionConfig; +use crate::zkevm_circuits::scheduler::aux::BaseLayerCircuitType; +use circuit_definitions::circuit_definitions::base_layer::*; +use circuit_definitions::circuit_definitions::recursion_layer::leaf_layer::*; +use circuit_definitions::circuit_definitions::recursion_layer::{ + node_layer::ZkSyncNodeLayerRecursiveCircuit, *, +}; +use circuit_definitions::encodings::recursion_request::RecursionQueueSimulator; +use circuit_definitions::encodings::CircuitEquivalentReflection; + +pub fn split_recursion_queue(queue: RecursionQueueSimulator) -> Vec> { + let round_function = ZkSyncDefaultRoundFunction::default(); + queue.split_by(RECURSION_ARITY, &round_function) +} + +/// Creates leaf witnesses: each leaf aggregates RECURSION_ARITY (32) basic circuits of a given type. +pub fn create_leaf_witnesses( + subset: ( + u64, // circuit type + RecursionQueueSimulator, + Vec>, + ), + proofs: Vec, // proofs coming from the base layer + vk: ZkSyncBaseLayerVerificationKey, + leaf_params: (u8, RecursionLeafParametersWitness), // (cirtuit_type, and ??) +) -> ( + Vec<( + u64, // type of the basic circuit + RecursionQueueSimulator, // chunk + )>, + Vec, // proofs for chunks + Vec>, +) { + let (circuit_type, queue, closed_form_inputs) = subset; + assert_eq!(queue.num_items as usize, proofs.len()); + assert_eq!(circuit_type, vk.numeric_circuit_type() as u64); + + assert_eq!(leaf_params.0, circuit_type as u8); + + let queue_splits = split_recursion_queue(queue); + let mut proofs_iter = proofs.into_iter(); + + let mut results = Vec::with_capacity(queue_splits.len()); + let mut recursive_circuits = Vec::with_capacity(queue_splits.len()); + + for el in queue_splits.into_iter() { + let mut proofs = vec![]; + for _ in 0..el.num_items { + let t = proofs_iter.next().expect("proof"); + proofs.push(t); + } + + let (circuit_type, circuit) = + create_leaf_witness(circuit_type, el.clone(), proofs, &vk, &leaf_params); + + results.push((circuit_type, el)); + recursive_circuits.push(circuit); + } + + (results, recursive_circuits, closed_form_inputs) +} + +pub fn create_leaf_witness( + circuit_type: u64, // circuit type + queue: RecursionQueueSimulator, + proofs: Vec, // proofs coming from the base layer + vk: &ZkSyncBaseLayerVerificationKey, + leaf_params: &(u8, RecursionLeafParametersWitness), // (cirtuit_type, and ??) +) -> ( + u64, // type of the basic circuit + ZkSyncRecursiveLayerCircuit, // proofs for chunks +) { + assert_eq!(queue.num_items as usize, proofs.len()); + assert_eq!(circuit_type, vk.numeric_circuit_type() as u64); + + let (t, params) = leaf_params; + assert_eq!(*t, circuit_type as u8); + + let mut proofs_iter = proofs.into_iter(); + let mut proof_witnesses = VecDeque::new(); + for _ in 0..queue.num_items { + let t = proofs_iter.next().expect("proof"); + proof_witnesses.push_back(t.into_inner()); + } + let leaf_input = RecursionLeafInputWitness:: { + params: params.clone(), + queue_state: take_sponge_like_queue_state_from_simulator(&queue), + }; + + let elements: VecDeque<_> = queue + .witness + .iter() + .map(|(_, old_tail, element)| (element.reflect(), *old_tail)) + .collect(); + + let witness = RecursionLeafInstanceWitness:: { + input: leaf_input, + vk_witness: vk.clone().into_inner(), + queue_witness: FullStateCircuitQueueRawWitness { elements }, + proof_witnesses, + }; + + let config = LeafLayerRecursionConfig::< + F, + >>::NonCircuitSimulator, + EXT, + > { + proof_config: recursion_layer_proof_config(), + vk_fixed_parameters: vk.clone().into_inner().fixed_parameters, + capacity: RECURSION_ARITY, + _marker: std::marker::PhantomData, + }; + + let base_layer_circuit_type = + BaseLayerCircuitType::from_numeric_value(vk.numeric_circuit_type()); + let circuit = ZkSyncLeafLayerRecursiveCircuit { + witness, + config, + transcript_params: (), + base_layer_circuit_type, + _marker: std::marker::PhantomData, + }; + + let circuit = ZkSyncRecursiveLayerCircuit::leaf_circuit_from_base_type( + BaseLayerCircuitType::from_numeric_value(vk.numeric_circuit_type()), + circuit, + ); + + (circuit_type, circuit) +} + +pub fn compute_leaf_params( + circuit_type: u8, + base_layer_vk: ZkSyncBaseLayerVerificationKey, + leaf_layer_vk: ZkSyncRecursionLayerVerificationKey, +) -> RecursionLeafParametersWitness { + let round_function = ZkSyncDefaultRoundFunction::default(); + + use crate::witness::utils::*; + + assert_eq!(circuit_type, base_layer_vk.numeric_circuit_type()); + assert_eq!( + base_circuit_type_into_recursive_leaf_circuit_type( + BaseLayerCircuitType::from_numeric_value(circuit_type) + ) as u8, + leaf_layer_vk.numeric_circuit_type() + ); + + let base_vk_commitment: [_; VK_COMMITMENT_LENGTH] = + compute_encodable_witness_commitment::< + AllocatedVerificationKey, + VK_COMMITMENT_LENGTH, + _, + >(base_layer_vk.into_inner(), &round_function); + + let leaf_vk_commitment: [_; VK_COMMITMENT_LENGTH] = + compute_encodable_witness_commitment::< + AllocatedVerificationKey, + VK_COMMITMENT_LENGTH, + _, + >(leaf_layer_vk.into_inner(), &round_function); + + let params = RecursionLeafParametersWitness:: { + circuit_type: F::from_u64_unchecked(circuit_type as u64), + basic_circuit_vk_commitment: base_vk_commitment, + leaf_layer_vk_commitment: leaf_vk_commitment, + }; + + params +} + +pub fn compute_leaf_vks_and_params_commitment( + leaf_params: [RecursionLeafParametersWitness; NUM_CIRCUIT_TYPES_TO_SCHEDULE], +) -> [F; LEAF_LAYER_PARAMETERS_COMMITMENT_LENGTH] { + let round_function = ZkSyncDefaultRoundFunction::default(); + use crate::witness::utils::*; + + let params_commitment: [_; LEAF_LAYER_PARAMETERS_COMMITMENT_LENGTH] = + compute_encodable_witness_commitment::< + [RecursionLeafParameters; NUM_CIRCUIT_TYPES_TO_SCHEDULE], + LEAF_LAYER_PARAMETERS_COMMITMENT_LENGTH, + _, + >(leaf_params, &round_function); + + params_commitment +} + +pub fn compute_node_vk_commitment( + node_vk: ZkSyncRecursionLayerVerificationKey, +) -> [F; VK_COMMITMENT_LENGTH] { + let round_function = ZkSyncDefaultRoundFunction::default(); + use crate::witness::utils::*; + + let vk_commitment: [_; VK_COMMITMENT_LENGTH] = compute_encodable_witness_commitment::< + AllocatedVerificationKey, + VK_COMMITMENT_LENGTH, + _, + >(node_vk.into_inner(), &round_function); + + vk_commitment +} + +/// Creates nodes witnesses, one witness is aggregating up to RECURSION_ARITY (32) leaves (or nodes) of a single circuit type. +pub fn create_node_witnesses( + chunks: Vec<( + u64, // circuit type + RecursionQueueSimulator, // chunk + )>, + proofs: Vec, + vk: ZkSyncRecursionLayerVerificationKey, + node_vk_commitment: [F; VK_COMMITMENT_LENGTH], + leaf_layer_params: &Vec<(u8, RecursionLeafParametersWitness)>, +) -> ( + Vec<( + u64, + RecursionQueueSimulator, // chunks + )>, + Vec, // proofs for chunks +) { + use crate::zkevm_circuits::recursion::NUM_BASE_LAYER_CIRCUITS; + assert_eq!(leaf_layer_params.len(), NUM_BASE_LAYER_CIRCUITS); + + assert_eq!(chunks.len(), proofs.len()); + assert!(chunks.len() > 0); + + let circuit_type = chunks[0].0 as u8; + let mut proofs_iter = proofs.into_iter(); + + let mut results = vec![]; + let mut recursive_circuits = vec![]; + + for chunk in chunks.chunks(RECURSION_ARITY) { + let proofs_for_circuit = (&mut proofs_iter).take(chunk.len()).collect(); + let (processed_circuit_type, circuit, queue) = create_node_witness( + chunk, + proofs_for_circuit, + &vk, + node_vk_commitment, + &leaf_layer_params, + ); + + assert_eq!(circuit_type as u64, processed_circuit_type); + + results.push((circuit_type as u64, queue)); + recursive_circuits.push(circuit); + } + + assert!(proofs_iter.next().is_none()); + + (results, recursive_circuits) +} + +pub fn create_node_witness( + chunks_of_queue: &[( + u64, // circuit type + RecursionQueueSimulator, // part of queue + )], + proofs: Vec, + vk: &ZkSyncRecursionLayerVerificationKey, + node_vk_commitment: [F; VK_COMMITMENT_LENGTH], + leaf_layer_params: &Vec<(u8, RecursionLeafParametersWitness)>, +) -> ( + u64, + ZkSyncRecursiveLayerCircuit, // proof for the part of queue + RecursionQueueSimulator, +) { + use crate::zkevm_circuits::recursion::NUM_BASE_LAYER_CIRCUITS; + assert_eq!(leaf_layer_params.len(), NUM_BASE_LAYER_CIRCUITS); + + assert!(chunks_of_queue.len() > 0); + // if chunk exists it's elements are non-trivial + chunks_of_queue + .iter() + .for_each(|(_, x)| assert!(x.num_items > 0)); + let num_chunks = chunks_of_queue.len(); + assert_eq!(proofs.len(), num_chunks); // so we indeed taken exactly enough + + // now even though we would have a chunk of len N, we should only create N-1 split points at the end + + let mut split_points = Vec::with_capacity(RECURSION_ARITY); + let mut it = chunks_of_queue.into_iter(); + + // Take the first chunk (guaranteed to exist) + let (circuit_type, mut subqueue) = (&mut it).next().cloned().unwrap(); + split_points.push(QueueTailStateWitness { + tail: subqueue.tail, + length: subqueue.num_items, + }); + + // merge all of them, and record split points + for (_, c) in it { + // Split point is a tail of the subqueue + split_points.push(QueueTailStateWitness { + tail: c.tail, + length: c.num_items, + }); + + subqueue = RecursionQueueSimulator::::merge(subqueue, c.clone()); + } + + // check that for every subqueue we have a proof + assert_eq!(split_points.len(), proofs.len()); + + // self-check that we have a matching length + let total_queue_len = subqueue.num_items; + let acc = split_points.iter().fold(0, |acc, el| acc + el.length); + assert_eq!(acc, total_queue_len); + + // for N chunks we need N-1 split points, so either truncate, or pad + assert!(split_points.len() <= RECURSION_ARITY); + + if split_points.len() == RECURSION_ARITY { + let _ = split_points.pop().unwrap(); + } else { + // pad it + let padding = QueueTailStateWitness { + tail: subqueue.tail, + length: 0, + }; + split_points.resize(RECURSION_ARITY - 1, padding); + } + + assert_eq!(split_points.len() + 1, RECURSION_ARITY); + + let leaf_layer_params = leaf_layer_params + .iter() + .map(|el| { + assert_eq!(el.0 as u64, el.1.circuit_type.as_u64_reduced()); + + el.1.clone() + }) + .collect::>() + .try_into() + .unwrap(); + + let partial_inputs = RecursionNodeInputWitness { + branch_circuit_type: F::from_u64_unchecked(circuit_type as u64), + leaf_layer_parameters: leaf_layer_params, + node_layer_vk_commitment: node_vk_commitment, + queue_state: take_sponge_like_queue_state_from_simulator(&subqueue), + }; + + let proofs: Vec<_> = proofs.into_iter().map(|el| el.into_inner()).collect(); + + use crate::zkevm_circuits::recursion::node_layer::input::RecursionNodeInstanceWitness; + + let witness = RecursionNodeInstanceWitness { + input: partial_inputs, + vk_witness: vk.clone().into_inner(), + split_points: split_points.into(), + proof_witnesses: proofs.into(), + }; + + let config = NodeLayerRecursionConfig::< + F, + >>::NonCircuitSimulator, + EXT, + > { + proof_config: recursion_layer_proof_config(), + vk_fixed_parameters: vk.clone().into_inner().fixed_parameters, + leaf_layer_capacity: RECURSION_ARITY, + node_layer_capacity: RECURSION_ARITY, + _marker: std::marker::PhantomData, + }; + + let circuit = ZkSyncNodeLayerRecursiveCircuit { + witness, + config, + transcript_params: (), + _marker: std::marker::PhantomData, + }; + + let circuit = ZkSyncRecursiveLayerCircuit::NodeLayerCircuit(circuit); + + (circuit_type, circuit, subqueue) +} diff --git a/crates/zkevm_test_harness/src/witness/tracer/callstack_handler.rs b/crates/zkevm_test_harness/src/witness/tracer/callstack_handler.rs new file mode 100644 index 0000000..116b114 --- /dev/null +++ b/crates/zkevm_test_harness/src/witness/tracer/callstack_handler.rs @@ -0,0 +1,462 @@ +use std::collections::HashMap; + +use crate::witness::tracer::tracer::QueryMarker; +use crate::zk_evm::{aux_structures::LogQuery, vm_state::CallStackEntry}; + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub enum RenumeratedQueryIndex { + ForwardIndexAndRollbackIndex(usize), + ForwardNoRollbackIndex(usize), +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub enum LogAction { + ForwardAndRolledBack { + forward_counter: usize, + renumerated_rollback_counter_as_forward: usize, + }, + ForwardAndNotRolledBack { + forward_coutner: usize, + rollback_counter: usize, + }, + ForwardNoRollback(usize), +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub enum ExtendedLogQuery { + Query { + marker: QueryMarker, + cycle: u32, + query: LogQuery, + }, + FrameForwardHeadMarker(usize), + FrameForwardTailMarker(usize), + FrameRollbackHeadMarker(usize), + FrameRollbackTailMarker(usize), +} + +#[derive(Clone, Debug)] +pub struct CallstackEntryWithAuxData { + pub entry: CallStackEntry, + pub current_history_record: CallstackActionHistoryEntry, + pub frame_index: usize, + pub parent_frame_index: usize, + pub forward_queue: Vec, + pub rollback_queue: Vec, +} + +impl CallstackEntryWithAuxData { + pub fn empty() -> Self { + Self { + entry: CallStackEntry::empty_context(), + current_history_record: CallstackActionHistoryEntry::uninitialized(), + frame_index: 0, + parent_frame_index: 0, + forward_queue: vec![ExtendedLogQuery::FrameForwardHeadMarker(0)], + rollback_queue: vec![ExtendedLogQuery::FrameRollbackTailMarker(0)], + } + } +} + +impl Default for CallstackEntryWithAuxData { + fn default() -> Self { + Self::empty() + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub enum OutOfScopeReason { + Fresh, + Exited { panic: bool }, +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub enum CallstackAction { + PushToStack, + OutOfScope(OutOfScopeReason), + PopFromStack { panic: bool }, +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct CallstackActionHistoryEntry { + pub action: CallstackAction, + pub affected_entry: CallStackEntry, + pub frame_index: usize, + pub beginning_cycle: u32, + pub end_cycle: Option, + pub actions: Vec<(u32, LogAction)>, +} + +impl CallstackActionHistoryEntry { + pub fn uninitialized() -> Self { + Self { + action: CallstackAction::PushToStack, + affected_entry: CallStackEntry::empty_context(), + frame_index: 0, + beginning_cycle: 0, + end_cycle: None, + // last_action_of_parent: None, + actions: vec![], + } + } +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub enum MergeIntention { + IntoForwardTail, + IntoRollbackHead, +} + +// special cases: if we merge (potentially empty) segment of the current frame +// to the empty segment of the parent frame, then we need somewhat immutable reference +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub enum QueueSegmentIndirectablePointer { + ForwardHeadAtFrameStart(usize), + RollbackTailAtFrameStart(usize), +} + +#[derive(Clone, Debug)] +pub struct CallstackWithAuxData { + pub monotonic_frame_counter: usize, + pub rollbackable_monotonic_counter: usize, + pub non_rollbackable_monotonic_counter: usize, + pub forward_flattened_counter: usize, + pub rollback_flattened_counter: usize, + pub total_rolled_back: usize, + pub unique_query_id_counter: u64, + pub current_entry: CallstackEntryWithAuxData, + pub depth: usize, + pub stack: Vec, + pub full_history: Vec, + pub log_queue_access_snapshots: Vec<(u32, RenumeratedQueryIndex)>, + pub log_access_history: Vec<(u32, QueryMarker)>, + pub child_into_parent: HashMap, + pub flat_new_frames_history: Vec<(u32, CallStackEntry)>, +} + +impl CallstackWithAuxData { + pub fn empty() -> Self { + let initial_history_record = CallstackActionHistoryEntry { + action: CallstackAction::OutOfScope(OutOfScopeReason::Fresh), + affected_entry: CallStackEntry::empty_context(), + frame_index: 0, + beginning_cycle: 0, + end_cycle: None, + actions: vec![], + }; + + let new = Self { + monotonic_frame_counter: 1, + rollbackable_monotonic_counter: 0, + non_rollbackable_monotonic_counter: 0, + forward_flattened_counter: 0, + rollback_flattened_counter: 0, + total_rolled_back: 0, + unique_query_id_counter: 0, + current_entry: CallstackEntryWithAuxData::empty(), + depth: 0, + stack: vec![], + full_history: vec![initial_history_record], + log_queue_access_snapshots: vec![], + log_access_history: vec![], + child_into_parent: HashMap::new(), + flat_new_frames_history: vec![], + }; + + new + } + + pub fn from_initial_callstack( + monotonic_cycle_counter: u32, + simple_entry: CallStackEntry, + ) -> Self { + let mut new = Self::empty(); + let current = new.current_entry.entry.clone(); + new.push_entry(monotonic_cycle_counter, current, simple_entry); + + new + } + + pub fn push_entry( + &mut self, + monotonic_cycle_counter: u32, + previous_simple_entry: CallStackEntry, + new_simple_entry: CallStackEntry, + ) { + self.flat_new_frames_history + .push((monotonic_cycle_counter, new_simple_entry)); + + let new_counter = self.monotonic_frame_counter; + self.monotonic_frame_counter += 1; + self.depth += 1; + + // when we push a new entry we put the previous "current" into the stack, + // and intoduce a new one, for which we do not add history action as it may be unnecessary + + // we only care about the history of the stack top, so we push previous entry + let current_frame_index = self.current_entry.frame_index; + + let full_entry = CallstackEntryWithAuxData { + entry: new_simple_entry, + current_history_record: CallstackActionHistoryEntry { + action: CallstackAction::OutOfScope(OutOfScopeReason::Fresh), + affected_entry: new_simple_entry, + frame_index: new_counter, + beginning_cycle: monotonic_cycle_counter, + end_cycle: None, + actions: vec![], + }, + parent_frame_index: current_frame_index, + frame_index: new_counter, + forward_queue: vec![ExtendedLogQuery::FrameForwardHeadMarker(new_counter)], + rollback_queue: vec![ExtendedLogQuery::FrameRollbackTailMarker(new_counter)], + }; + + let history_of_new = full_entry.current_history_record.clone(); + + let mut current = std::mem::replace(&mut self.current_entry, full_entry); + // update as we do not mutate between intermediate points + current.entry = previous_simple_entry; + current.current_history_record.affected_entry = previous_simple_entry; + current.current_history_record.end_cycle = Some(monotonic_cycle_counter); + + let mut history_of_current = current.current_history_record.clone(); + history_of_current.action = CallstackAction::PushToStack; + + self.stack.push(current); + self.full_history.push(history_of_current); + self.full_history.push(history_of_new); + } + + pub fn pop_entry(&mut self, monotonic_cycle_counter: u32, panicked: bool) -> CallStackEntry { + let mut previous = self.stack.pop().unwrap(); + self.depth -= 1; + + previous.current_history_record.beginning_cycle = monotonic_cycle_counter; + previous.current_history_record.actions = vec![]; // cleanup + previous.current_history_record.end_cycle = None; + + let mut previous_history_record = previous.current_history_record.clone(); + previous_history_record.action = CallstackAction::PopFromStack { panic: panicked }; + + // when we pop then current goes out of scope + let current = std::mem::replace(&mut self.current_entry, previous); + + let CallstackEntryWithAuxData { + entry: _, + current_history_record: history_of_current, + parent_frame_index: _, + frame_index, + forward_queue, + rollback_queue, + } = current; + + let mut history_of_current = history_of_current; + let mut rollback_queue = rollback_queue; + + // work with the rollback parts + if panicked { + self.current_entry.forward_queue.extend(forward_queue); + self.current_entry + .forward_queue + .push(ExtendedLogQuery::FrameForwardTailMarker(frame_index)); + + rollback_queue.push(ExtendedLogQuery::FrameRollbackHeadMarker(frame_index)); + + let adjusted_rollbacks = rollback_queue.into_iter().rev().map(|mut el| { + match &mut el { + ExtendedLogQuery::Query { mut marker, .. } => match &mut marker { + QueryMarker::Rollback { + cycle_of_applied_rollback, + .. + } => { + *cycle_of_applied_rollback = Some(monotonic_cycle_counter); + } + _ => {} + }, + _ => {} + } + + el + }); + + self.current_entry.forward_queue.extend(adjusted_rollbacks); + + // count adjustment + let mut num_rollbacks = 0; + + for (_, el) in history_of_current.actions.iter() { + match el { + LogAction::ForwardAndNotRolledBack { .. } => { + num_rollbacks += 1; + } + _ => {} + } + } + + for (_cycle, el) in history_of_current.actions.iter_mut() { + let adjusted_el = match &*el { + LogAction::ForwardAndNotRolledBack { + forward_coutner, + rollback_counter, + } => { + // we enumerate rollback counter from the very end of the flattened queue + // and instead it should become an element from the forward queue + LogAction::ForwardAndRolledBack { + forward_counter: *forward_coutner, + renumerated_rollback_counter_as_forward: self.forward_flattened_counter + + *rollback_counter, + } + } + a @ LogAction::ForwardAndRolledBack { .. } => { + // it has become the element of the forward queue already + *a + } + a @ LogAction::ForwardNoRollback(..) => { + // never affected + *a + } + }; + + *el = adjusted_el; + } + + // renumerate for future + self.forward_flattened_counter += num_rollbacks; + self.rollback_flattened_counter -= num_rollbacks; + self.total_rolled_back += num_rollbacks; + } else { + // frame did end up ok, so we merge into parent's rollback + + // just glue + self.current_entry.forward_queue.extend(forward_queue); + self.current_entry + .forward_queue + .push(ExtendedLogQuery::FrameForwardTailMarker(frame_index)); + self.current_entry.rollback_queue.extend(rollback_queue); + self.current_entry + .rollback_queue + .push(ExtendedLogQuery::FrameRollbackHeadMarker(frame_index)); + } + + // update the current history + history_of_current.action = + CallstackAction::OutOfScope(OutOfScopeReason::Exited { panic: panicked }); + history_of_current.end_cycle = Some(monotonic_cycle_counter); + + self.full_history.push(history_of_current); + self.full_history.push(previous_history_record); + + current.entry + } + + pub fn add_log_query(&mut self, monotonic_cycle_counter: u32, log_query: LogQuery) { + let current_frame_index = self.current_entry.frame_index; + let unique_query_id = self.unique_query_id_counter; + self.unique_query_id_counter += 1; + + if log_query.rw_flag { + // can be rolled back + let query_index = self.rollbackable_monotonic_counter; + self.rollbackable_monotonic_counter += 1; + + let marker = QueryMarker::Forward { + unique_query_id, + in_frame: current_frame_index, + index: query_index, + cycle: monotonic_cycle_counter, + }; + let full_query = ExtendedLogQuery::Query { + marker, + cycle: monotonic_cycle_counter, + query: log_query, + }; + + self.current_entry.forward_queue.push(full_query); + + let mut rollback_query = log_query; + rollback_query.rollback = true; + + self.log_access_history + .push((monotonic_cycle_counter, marker)); + + let unique_query_id = self.unique_query_id_counter; + self.unique_query_id_counter += 1; + + let marker = QueryMarker::Rollback { + unique_query_id, + in_frame: current_frame_index, + index: query_index, + cycle_of_declaration: monotonic_cycle_counter, + cycle_of_applied_rollback: None, + }; + let full_query = ExtendedLogQuery::Query { + marker, + cycle: monotonic_cycle_counter, + query: rollback_query, + }; + + self.current_entry.rollback_queue.push(full_query); + + self.log_access_history + .push((monotonic_cycle_counter, marker)); + + let forward_flattened_counter = self.forward_flattened_counter; + let rollback_flattened_counter = self.rollback_flattened_counter; + + self.forward_flattened_counter += 1; + self.rollback_flattened_counter += 1; + + self.current_entry.current_history_record.actions.push(( + monotonic_cycle_counter, + LogAction::ForwardAndNotRolledBack { + forward_coutner: forward_flattened_counter, + rollback_counter: rollback_flattened_counter, + }, + )); + + // snapshot it + self.log_queue_access_snapshots.push(( + monotonic_cycle_counter, + RenumeratedQueryIndex::ForwardIndexAndRollbackIndex(query_index), + )); + } else { + assert!(log_query.rollback == false); + + let query_index = self.non_rollbackable_monotonic_counter; + self.non_rollbackable_monotonic_counter += 1; + + let forward_flattened_counter = self.forward_flattened_counter; + self.forward_flattened_counter += 1; + + self.current_entry.current_history_record.actions.push(( + monotonic_cycle_counter, + LogAction::ForwardNoRollback(forward_flattened_counter), + )); + + // snapshot it + self.log_queue_access_snapshots.push(( + monotonic_cycle_counter, + RenumeratedQueryIndex::ForwardNoRollbackIndex(query_index), + )); + + // just add + let marker = QueryMarker::ForwardNoRollback { + unique_query_id, + in_frame: current_frame_index, + index: query_index, + cycle: monotonic_cycle_counter, + }; + let full_query = ExtendedLogQuery::Query { + marker, + cycle: monotonic_cycle_counter, + query: log_query, + }; + + self.current_entry.forward_queue.push(full_query); + + self.log_access_history + .push((monotonic_cycle_counter, marker)); + } + } +} diff --git a/crates/zkevm_test_harness/src/witness/tracer/mod.rs b/crates/zkevm_test_harness/src/witness/tracer/mod.rs new file mode 100644 index 0000000..b7b7a9c --- /dev/null +++ b/crates/zkevm_test_harness/src/witness/tracer/mod.rs @@ -0,0 +1,3 @@ +pub mod callstack_handler; +pub mod tracer; +pub mod vm_snapshot; diff --git a/crates/zkevm_test_harness/src/witness/tracer/tracer.rs b/crates/zkevm_test_harness/src/witness/tracer/tracer.rs new file mode 100644 index 0000000..8b05a06 --- /dev/null +++ b/crates/zkevm_test_harness/src/witness/tracer/tracer.rs @@ -0,0 +1,424 @@ +use crate::witness::tracer::callstack_handler::CallstackWithAuxData; +use crate::witness::tracer::vm_snapshot::VmSnapshot; +use crate::zk_evm::abstractions::PrecompileCyclesWitness; +use crate::zk_evm::aux_structures::LogQuery; +use crate::zk_evm::aux_structures::*; +use crate::zk_evm::ethereum_types::U256; +use crate::zk_evm::vm_state::CallStackEntry; + +use crate::zk_evm::zk_evm_abstractions::precompiles::ecrecover::ECRecoverRoundWitness; +use crate::zk_evm::zk_evm_abstractions::precompiles::keccak256::Keccak256RoundWitness; +use crate::zk_evm::zk_evm_abstractions::precompiles::secp256r1_verify::Secp256r1VerifyRoundWitness; +use crate::zk_evm::zk_evm_abstractions::precompiles::sha256::Sha256RoundWitness; + +use crate::zk_evm::abstractions::StorageAccessRefund; +use crate::zk_evm::zkevm_opcode_defs::decoding::EncodingModeProduction; +use crate::zk_evm::zkevm_opcode_defs::system_params::STORAGE_AUX_BYTE; +use crate::zk_evm::zkevm_opcode_defs::system_params::VM_INITIAL_FRAME_ERGS; +use crate::zk_evm::zkevm_opcode_defs::system_params::VM_MAX_STACK_DEPTH; +use circuit_definitions::zk_evm::zkevm_opcode_defs::system_params::TRANSIENT_STORAGE_AUX_BYTE; +use tracing; + +// cycle indicators below are not timestamps! + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub enum QueryMarker { + ForwardNoRollback { + unique_query_id: u64, + in_frame: usize, + index: usize, + cycle: u32, + }, + Forward { + unique_query_id: u64, + in_frame: usize, + index: usize, + cycle: u32, + }, + Rollback { + unique_query_id: u64, + in_frame: usize, + index: usize, + cycle_of_declaration: u32, + cycle_of_applied_rollback: Option, + }, +} + +impl QueryMarker { + pub fn frame_index(&self) -> usize { + match self { + QueryMarker::ForwardNoRollback { in_frame, .. } => *in_frame, + QueryMarker::Forward { in_frame, .. } => *in_frame, + QueryMarker::Rollback { in_frame, .. } => *in_frame, + } + } + + pub fn query_id(&self) -> u64 { + match self { + QueryMarker::ForwardNoRollback { + unique_query_id, .. + } => *unique_query_id, + QueryMarker::Forward { + unique_query_id, .. + } => *unique_query_id, + QueryMarker::Rollback { + unique_query_id, .. + } => *unique_query_id, + } + } +} + +#[derive(Clone, Debug)] +pub struct WitnessTracer { + pub cycles_to_use_per_snapshot: u32, + pub current_cycle_counter: u32, + pub cycle_counter_of_last_snapshot: u32, + pub memory_queries: Vec<(u32, MemoryQuery)>, // flattened memory queries, with cycle indicators + pub storage_queries: PerCircuitAccumulatorSparse<(u32, LogQuery)>, // storage read queries with cycle indicators + pub cold_warm_refunds_logs: PerCircuitAccumulatorSparse<(u32, LogQuery, u32)>, + pub pubdata_cost_logs: PerCircuitAccumulatorSparse<(u32, LogQuery, PubdataCost)>, + pub prepared_decommittment_queries: Vec<(u32, DecommittmentQuery)>, + pub executed_decommittment_queries: Vec<(u32, DecommittmentQuery, Vec)>, + pub keccak_round_function_witnesses: Vec<(u32, LogQuery, Vec)>, + pub sha256_round_function_witnesses: Vec<(u32, LogQuery, Vec)>, + pub ecrecover_witnesses: Vec<(u32, LogQuery, ECRecoverRoundWitness)>, + pub secp256r1_verify_witnesses: Vec<(u32, LogQuery, Secp256r1VerifyRoundWitness)>, + pub monotonic_query_counter: usize, + // pub log_frames_stack: Vec>, // keep the unique frame index + pub callstack_with_aux_data: CallstackWithAuxData, + pub vm_snapshots: Vec, + // we need to properly preserve the information about logs. Not just flattening them into something, + // but also keep the markers on when new frame has started and has finished, and the final frame execution + // result, so we can properly substitute hash chain results in there for non-determinism +} + +#[derive(Clone, Debug)] +pub struct NumberedApplicationData { + pub index: usize, + pub forward: Vec, + pub rollbacks: Vec, +} + +impl NumberedApplicationData { + pub fn new() -> Self { + Self { + index: 0, + forward: vec![], + rollbacks: vec![], + } + } +} + +use std::ops::Range; + +#[derive(Clone, Debug)] +pub struct LogQueueFramesProcessor { + pub frame_indexes: Vec, + pub frames: NumberedApplicationData<(QueryMarker, LogQuery)>, + pub ranges: NumberedApplicationData>, +} + +impl LogQueueFramesProcessor { + pub fn empty() -> Self { + Self { + frame_indexes: vec![], + frames: NumberedApplicationData::new(), + ranges: NumberedApplicationData::new(), + } + } +} + +impl WitnessTracer { + pub fn new(cycles_per_snapshot: u32) -> Self { + Self { + cycles_to_use_per_snapshot: cycles_per_snapshot, + current_cycle_counter: 0, + cycle_counter_of_last_snapshot: 0, + memory_queries: vec![], + storage_queries: PerCircuitAccumulatorSparse::new(cycles_per_snapshot as usize), + cold_warm_refunds_logs: PerCircuitAccumulatorSparse::new(cycles_per_snapshot as usize), + pubdata_cost_logs: PerCircuitAccumulatorSparse::new(cycles_per_snapshot as usize), + prepared_decommittment_queries: vec![], + executed_decommittment_queries: vec![], + keccak_round_function_witnesses: vec![], + sha256_round_function_witnesses: vec![], + ecrecover_witnesses: vec![], + secp256r1_verify_witnesses: vec![], + monotonic_query_counter: 0, + // log_frames_stack: vec![ApplicationData::empty()], + callstack_with_aux_data: CallstackWithAuxData::empty(), + vm_snapshots: vec![], + } + } +} + +#[derive(Clone, Debug)] +pub struct AuxCallstackProto { + // monotonic counter to enumerate frames + pub monotonic_frame_counter: usize, + // current frame and it's parent + pub current: ((usize, usize), CallStackEntry), // we save PARENT index and stack entry itself + // stack of frames, along with their parents + pub stack: Vec<((usize, usize), CallStackEntry)>, + // history of "actions" - VM cycle, and action direction + pub history: Vec<(u32, (bool, usize, CallStackEntry))>, +} + +impl AuxCallstackProto { + pub fn new_with_max_ergs() -> Self { + let mut initial_callstack = CallStackEntry::empty_context(); + initial_callstack.ergs_remaining = VM_INITIAL_FRAME_ERGS; + + Self { + monotonic_frame_counter: 2, + current: ((0, 1), initial_callstack), + stack: vec![], + history: vec![], + } + } + + pub fn depth(&self) -> usize { + self.stack.len() + } + + #[track_caller] + pub fn push_entry( + &mut self, + monotonic_cycle_counter: u32, + previous_entry: CallStackEntry, + new_entry: CallStackEntry, + ) { + let new_counter = self.monotonic_frame_counter; + let current_counter = self.current.0 .1; + self.monotonic_frame_counter += 1; + let mut old = std::mem::replace( + &mut self.current, + ((current_counter, new_counter), new_entry), + ); + assert_eq!(old.1.code_page, previous_entry.code_page); + old.1 = previous_entry; + self.stack.push(old); + + self.history.push(( + monotonic_cycle_counter, + (true, current_counter, previous_entry), + )); + debug_assert!(self.depth() <= VM_MAX_STACK_DEPTH as usize); + } + + #[track_caller] + pub fn pop_entry(&mut self, monotonic_cycle_counter: u32) -> ((usize, usize), CallStackEntry) { + let previous = self.stack.pop().unwrap(); + let old = std::mem::replace(&mut self.current, previous); + + self.history + .push((monotonic_cycle_counter, (false, old.0 .1, old.1))); + + old + } +} + +use crate::zk_evm::vm_state::VmLocalState; +use crate::zk_evm::witness_trace::VmWitnessTracer; + +use crate::witness::aux_data_structs::per_circuit_accumulator::PerCircuitAccumulatorSparse; + +impl VmWitnessTracer<8, EncodingModeProduction> for WitnessTracer { + fn start_new_execution_cycle(&mut self, current_state: &VmLocalState) { + // println!("Cycle starts"); + if self.current_cycle_counter == 0 { + if self.current_cycle_counter != current_state.monotonic_cycle_counter { + // adjust + self.current_cycle_counter = current_state.monotonic_cycle_counter; + } + // make the initial one + let snapshot = VmSnapshot { + local_state: current_state.clone(), + at_cycle: self.current_cycle_counter, + }; + self.vm_snapshots.push(snapshot); + tracing::debug!( + "Made INITIAL snapshot at cycle {:?}", + self.current_cycle_counter + ); + self.cycle_counter_of_last_snapshot = current_state.monotonic_cycle_counter; + } + + assert_eq!( + self.current_cycle_counter, + current_state.monotonic_cycle_counter + ); + + if self.current_cycle_counter + >= self.cycle_counter_of_last_snapshot + self.cycles_to_use_per_snapshot + { + // do it immediatelly + let snapshot = VmSnapshot { + local_state: current_state.clone(), + at_cycle: self.current_cycle_counter, + }; + self.vm_snapshots.push(snapshot); + tracing::debug!("Made snapshot at cycle {:?}", self.current_cycle_counter); + // we made a snapshot now, but the cycle itself will be the first one for the next snapshot + self.cycle_counter_of_last_snapshot = current_state.monotonic_cycle_counter; + } + + // monotonic counter always increases + self.current_cycle_counter += 1; + } + + fn end_execution_cycle(&mut self, _current_state: &VmLocalState) { + // println!("Cycle ends"); + } + + fn add_memory_query(&mut self, monotonic_cycle_counter: u32, memory_query: MemoryQuery) { + self.memory_queries + .push((monotonic_cycle_counter, memory_query)); + } + + fn record_refund_for_query( + &mut self, + monotonic_cycle_counter: u32, + log_query: LogQuery, + refund: StorageAccessRefund, + ) { + assert!(log_query.aux_byte == STORAGE_AUX_BYTE); + self.cold_warm_refunds_logs + .push((monotonic_cycle_counter, log_query, refund.refund())); + } + + fn record_pubdata_cost_for_query( + &mut self, + monotonic_cycle_counter: u32, + log_query: LogQuery, + pubdata_cost: PubdataCost, + ) { + assert!(log_query.aux_byte == STORAGE_AUX_BYTE); + self.pubdata_cost_logs + .push((monotonic_cycle_counter, log_query, pubdata_cost)); + } + + fn add_log_query(&mut self, monotonic_cycle_counter: u32, log_query: LogQuery) { + // log both reads and writes + if log_query.aux_byte == STORAGE_AUX_BYTE + || log_query.aux_byte == TRANSIENT_STORAGE_AUX_BYTE + { + self.storage_queries + .push((monotonic_cycle_counter, log_query)); + } + + self.callstack_with_aux_data + .add_log_query(monotonic_cycle_counter, log_query); + } + + fn prepare_for_decommittment( + &mut self, + monotonic_cycle_counter: u32, + decommittment_query: DecommittmentQuery, + ) { + self.prepared_decommittment_queries + .push((monotonic_cycle_counter, decommittment_query)); + } + + fn execute_decommittment( + &mut self, + monotonic_cycle_counter: u32, + decommittment_query: DecommittmentQuery, + mem_witness: Vec, + ) { + self.executed_decommittment_queries.push(( + monotonic_cycle_counter, + decommittment_query, + mem_witness, + )); + } + + fn add_precompile_call_result( + &mut self, + monotonic_cycle_counter: u32, + call_params: LogQuery, + _mem_witness_in: Vec, + _memory_witness_out: Vec, + round_witness: PrecompileCyclesWitness, + ) { + // we bootkeep it to later on use in memory argument by opening and flattening, and in precompile circuits + match round_witness { + PrecompileCyclesWitness::Keccak256(wit) => { + self.keccak_round_function_witnesses.push(( + monotonic_cycle_counter, + call_params, + wit, + )); + } + PrecompileCyclesWitness::Sha256(wit) => { + self.sha256_round_function_witnesses.push(( + monotonic_cycle_counter, + call_params, + wit, + )); + } + PrecompileCyclesWitness::ECRecover(mut wit) => { + assert_eq!(wit.len(), 1); + self.ecrecover_witnesses.push(( + monotonic_cycle_counter, + call_params, + wit.drain(..).next().unwrap(), + )); + } + PrecompileCyclesWitness::Secp256r1Verify(mut wit) => { + assert_eq!(wit.len(), 1); + self.secp256r1_verify_witnesses.push(( + monotonic_cycle_counter, + call_params, + wit.drain(..).next().unwrap(), + )); + } + } + } + + fn add_revertable_precompile_call( + &mut self, + _monotonic_cycle_counter: u32, + _call_params: LogQuery, + ) { + unreachable!() + } + + fn start_new_execution_context( + &mut self, + monotonic_cycle_counter: u32, + previous_context: &CallStackEntry, + new_context: &CallStackEntry, + ) { + self.callstack_with_aux_data.push_entry( + monotonic_cycle_counter, + *previous_context, + *new_context, + ); + } + + fn finish_execution_context(&mut self, monotonic_cycle_counter: u32, panicked: bool) { + // log part + + self.callstack_with_aux_data + .pop_entry(monotonic_cycle_counter, panicked); + + // // if we panic then we append forward and rollbacks to the forward of parent, + // // otherwise we place rollbacks of child before rollbacks of the parent + // let current_frame = self + // .log_frames_stack + // .pop() + // .expect("frame must be started before finishing"); + // let ApplicationData { forward, rollbacks } = current_frame; + // let parent_data = self.log_frames_stack.last_mut().unwrap(); + // if panicked { + // parent_data.forward.extend(forward); + // // add to forward part, but in reverse order + // parent_data.forward.extend(rollbacks.into_iter().rev()); + // } else { + // parent_data.forward.extend(forward); + // // prepend to the parent's rollback queue + // parent_data.rollbacks.extend(rollbacks); + // } + } +} diff --git a/crates/zkevm_test_harness/src/witness/tracer/vm_snapshot.rs b/crates/zkevm_test_harness/src/witness/tracer/vm_snapshot.rs new file mode 100644 index 0000000..ba23076 --- /dev/null +++ b/crates/zkevm_test_harness/src/witness/tracer/vm_snapshot.rs @@ -0,0 +1,18 @@ +use crate::zk_evm::vm_state::VmLocalState; + +use derivative::Derivative; + +#[derive(Derivative)] +#[derivative(Clone, Debug)] +pub struct VmSnapshot { + pub local_state: VmLocalState, + pub at_cycle: u32, +} + +#[derive(Derivative)] +#[derivative(Clone, Debug)] +pub struct VmTransition { + pub from_state: VmLocalState, + pub to_state: VmLocalState, + pub cycles_range_exclusive: std::ops::Range, +} diff --git a/crates/zkevm_test_harness/src/witness/tree/mod.rs b/crates/zkevm_test_harness/src/witness/tree/mod.rs new file mode 100644 index 0000000..59e2b40 --- /dev/null +++ b/crates/zkevm_test_harness/src/witness/tree/mod.rs @@ -0,0 +1,832 @@ +pub trait EnumeratedBinaryLeaf: Clone + std::hash::Hash { + fn empty() -> Self; + fn empty_index() -> u64 { + 0 + } + fn from_value(value: [u8; LEAF_DATA_WIDTH]) -> Self; + fn current_index(&self) -> u64; + fn set_index(&mut self, value: u64); + fn value(&self) -> &[u8; LEAF_DATA_WIDTH]; + fn set_value(&mut self, value: &[u8; LEAF_DATA_WIDTH]); + fn value_ref_mut(&mut self) -> &mut [u8; LEAF_DATA_WIDTH]; +} + +pub trait BinaryHasher: Clone + Send + Sync { + fn new() -> Self; + // fn update(&mut self, input: &[u8]); + // fn finalize(self) -> [u8; HASH_OUTPUT_WIDTH]; + // there function takes &mut self, but should internally cleanup if necessary (reset state) + fn node_hash( + depth: usize, + left_node: &[u8; HASH_OUTPUT_WIDTH], + right_node: &[u8; HASH_OUTPUT_WIDTH], + ) -> [u8; HASH_OUTPUT_WIDTH]; + fn leaf_hash(leaf: &[u8]) -> [u8; HASH_OUTPUT_WIDTH]; +} + +pub struct LeafQuery< + const DEPTH: usize, + const INDEX_BYTES: usize, + const LEAF_DATA_WIDTH: usize, + const HASH_OUTPUT_WIDTH: usize, + L: EnumeratedBinaryLeaf, +> { + pub leaf: L, + pub first_write: bool, + pub index: [u8; INDEX_BYTES], + pub merkle_path: Box<[[u8; HASH_OUTPUT_WIDTH]; DEPTH]>, // too large +} + +pub trait BinarySparseStorageTree< + const DEPTH: usize, + const INDEX_BYTES: usize, + const LEAF_DATA_WIDTH: usize, + const LEAF_METADATA_WIDTH: usize, + const HASH_OUTPUT_WIDTH: usize, + H: BinaryHasher, + L: EnumeratedBinaryLeaf, +> +{ + fn empty() -> Self; + fn next_enumeration_index(&self) -> u64; + fn set_next_enumeration_index(&mut self, value: u64); + fn root(&self) -> [u8; HASH_OUTPUT_WIDTH]; + fn get_leaf( + &mut self, + index: &[u8; INDEX_BYTES], + ) -> LeafQuery; + fn insert_leaf( + &mut self, + index: &[u8; INDEX_BYTES], + leaf: L, + ) -> LeafQuery; + fn insert_many_leafs( + &mut self, + indexes: &[[u8; INDEX_BYTES]], + leafs: Vec, + ) -> Vec> { + assert_eq!(indexes.len(), leafs.len()); + // let mut uniqueness_checker = std::collections::HashSet::new(); + let mut result = Vec::with_capacity(indexes.len()); + for (idx, leaf) in indexes.iter().zip(leafs.into_iter()) { + // let is_unique = uniqueness_checker.insert(*idx); + // assert!(is_unique); + let query = self.insert_leaf(idx, leaf); + result.push(query); + } + + result + } + // fn filter_renumerate(&self, indexes: &[[u8; INDEX_BYTES]], leafs: &[L]) -> (u64, Vec, Vec); + fn filter_renumerate<'a>( + &self, + indexes: impl Iterator, + leafs: impl Iterator, + ) -> (u64, Vec<([u8; INDEX_BYTES], L)>, Vec); + fn verify_inclusion( + root: &[u8; 32], + query: &LeafQuery, + ) -> bool; + fn verify_inclusion_proxy( + &self, + root: &[u8; 32], + query: &LeafQuery, + ) -> bool { + Self::verify_inclusion(root, query) + } +} + +pub type ZKSyncTestingTree = InMemoryStorageTree<256, 32, 8, Blake2s256, ZkSyncStorageLeaf>; + +use std::collections::HashMap; + +pub struct InMemoryStorageTree< + const DEPTH: usize, + const INDEX_BYTES: usize, + const LEAF_METADATA_WIDTH: usize, + H: BinaryHasher<32>, + L: EnumeratedBinaryLeaf<32>, +> { + pub hasher: H, + // pub empty_leaf_hash: [u8; 32], + pub next_enumeration_index: u64, + pub empty_hashes: Box<[[u8; 32]; DEPTH]>, + pub root: [u8; 32], + pub layers: [HashMap<[u8; INDEX_BYTES], [u8; 32]>; DEPTH], + pub leafs: HashMap<[u8; INDEX_BYTES], L>, +} + +fn create_neighbour_index(index: &[u8; N], depth: usize) -> [u8; N] { + debug_assert!(depth < N * 8); + let byte_idx = depth / 8; + let bit_idx = depth % 8; + + let mut result = *index; + result[byte_idx] = result[byte_idx] ^ (1u8 << bit_idx); + + result +} + +fn is_right_side_node(index: &[u8; N], depth: usize) -> bool { + debug_assert!(depth < N * 8); + let byte_idx = depth / 8; + let bit_idx = depth % 8; + + let is_right_side = index[byte_idx] & (1u8 << bit_idx) != 0; + + is_right_side +} + +impl< + const DEPTH: usize, + const INDEX_BYTES: usize, + const LEAF_METADATA_WIDTH: usize, + H: BinaryHasher<32>, + L: EnumeratedBinaryLeaf<32>, + > InMemoryStorageTree +{ + pub fn new() -> Self { + assert!(INDEX_BYTES * 8 == DEPTH); + assert!(DEPTH > 0); + let mut empty_leaf = vec![0u8; LEAF_METADATA_WIDTH + 32]; + empty_leaf[LEAF_METADATA_WIDTH..].copy_from_slice(L::empty().value()); + + let empty_leaf_hash = H::leaf_hash(&empty_leaf); + // now form empty hasher for every level + // we count levels from the bottom, and level 0 is empty leaf hashes + + let mut empty_hashes = Box::<[[u8; 32]; DEPTH]>::new([[0u8; 32]; DEPTH]); + empty_hashes[0] = empty_leaf_hash; + + let mut root = [0u8; 32]; + + let mut current_hash = empty_leaf_hash; + for level in 1..=DEPTH { + let empty_node_hash = H::node_hash(level, ¤t_hash, ¤t_hash); + + if level < DEPTH { + empty_hashes[level] = empty_node_hash; + current_hash = empty_node_hash; + } else { + root = empty_node_hash; + } + } + + let layers = vec![HashMap::new(); DEPTH].try_into().unwrap(); + + Self { + hasher: H::new(), + // pub empty_leaf_hash: [u8; 32], + next_enumeration_index: 1u64, + empty_hashes, + root, + layers: layers, + leafs: HashMap::new(), + } + } + + fn insert_path_element(&mut self, level: usize, index: [u8; INDEX_BYTES], value: [u8; 32]) { + // the only important thing is to cleanup the lowest bits for consistency + let mut index = index; + for bit in 0..level { + let word_idx = bit / 8; + let bit_idx = bit % 8; + index[word_idx] = index[word_idx] & (!(1 << bit_idx)); + } + + self.layers[level].insert(index, value); + } + + fn get_path_element(&self, level: usize, index: [u8; INDEX_BYTES]) -> &[u8; 32] { + // the only important thing is to cleanup the lowest bits for consistency + let mut index = index; + for bit in 0..level { + let word_idx = bit / 8; + let bit_idx = bit % 8; + index[word_idx] = index[word_idx] & (!(1 << bit_idx)); + } + + if let Some(node_hash) = self.layers[level].get(&index) { + node_hash + } else { + &self.empty_hashes[level] + } + } + + fn get_leaf(&self, index: &[u8; INDEX_BYTES]) -> LeafQuery { + let leaf = if let Some(leaf) = self.leafs.get(index) { + leaf.clone() + } else { + L::empty() + }; + + let mut path: Box<[[u8; 32]; DEPTH]> = Box::new([[0u8; 32]; DEPTH]); + for level in 0..DEPTH { + let pair_idx = create_neighbour_index(index, level); + let pair_node_hash = self.get_path_element(level, pair_idx); + path[level] = *pair_node_hash; + } + + LeafQuery { + leaf, + first_write: false, + index: *index, + merkle_path: path, + } + } + + fn verify_inclusion(root: &[u8; 32], query: &LeafQuery) -> bool { + let mut leaf_bytes = vec![0u8; LEAF_METADATA_WIDTH + 32]; // can make a scratch space somewhere later on + leaf_bytes[LEAF_METADATA_WIDTH..].copy_from_slice(query.leaf.value()); + + let leaf_index_bytes = query.leaf.current_index().to_be_bytes(); + leaf_bytes[(LEAF_METADATA_WIDTH - 8)..LEAF_METADATA_WIDTH] + .copy_from_slice(&leaf_index_bytes); + + let leaf_hash = H::leaf_hash(&leaf_bytes); + + let mut current_hash = leaf_hash; + for level in 0..DEPTH { + let (l, r) = if is_right_side_node(&query.index, level) { + (&query.merkle_path[level], ¤t_hash) + } else { + (¤t_hash, &query.merkle_path[level]) + }; + + let this_level_hash = H::node_hash(level, l, r); + + current_hash = this_level_hash; + } + + root == ¤t_hash + } + + // fn filter_renumerate(&self, indexes: &[[u8; INDEX_BYTES]], leafs: &[L]) -> (u64, Vec, Vec) { + fn filter_renumerate<'a>( + &self, + mut indexes: impl Iterator, + mut leafs: impl Iterator, + ) -> (u64, Vec<([u8; INDEX_BYTES], L)>, Vec) { + // we assume that we want to write leafs and quickly get which of those will be unique writes, and which will be updates + let mut first_writes = vec![]; + let mut updates = vec![]; + let mut next_index = self.next_enumeration_index; + for (idx, leaf) in (&mut indexes).zip(&mut leafs) { + let mut leaf = leaf; + if let Some(existing) = self.leafs.get(idx) { + leaf.set_index(existing.current_index()); + updates.push(leaf); + } else { + leaf.set_index(next_index); + next_index += 1; + first_writes.push((*idx, leaf)); + } + } + + assert!(indexes.next().is_none()); + assert!(leafs.next().is_none()); + + (next_index, first_writes, updates) + } + + fn insert_leaf( + &mut self, + index: &[u8; INDEX_BYTES], + leaf: L, + ) -> LeafQuery { + // first decide if we enumerate + + let mut first_write = false; + + if let Some(existing_leaf) = self.leafs.get_mut(index) { + existing_leaf.set_value(leaf.value()); + } else { + // enumerate + let mut leaf = leaf; + first_write = true; + leaf.set_index(self.next_enumeration_index); + self.leafs.insert(*index, leaf); + self.next_enumeration_index += 1; + } + + // now recompute the path + let leaf = self.leafs.get(index).cloned().unwrap(); + let mut leaf_bytes = vec![0u8; LEAF_METADATA_WIDTH + 32]; // can make a scratch space somewhere later on + leaf_bytes[LEAF_METADATA_WIDTH..].copy_from_slice(leaf.value()); + + let leaf_index_bytes = leaf.current_index().to_be_bytes(); + leaf_bytes[(LEAF_METADATA_WIDTH - 8)..LEAF_METADATA_WIDTH] + .copy_from_slice(&leaf_index_bytes); + + let leaf_hash = H::leaf_hash(&leaf_bytes); + + let mut current_hash = leaf_hash; + let mut path: Box<[[u8; 32]; DEPTH]> = Box::new([[0u8; 32]; DEPTH]); + for level in 0..DEPTH { + self.insert_path_element(level, *index, current_hash); + let pair_idx = create_neighbour_index(index, level); + let pair_node_hash = self.get_path_element(level, pair_idx); + + path[level] = *pair_node_hash; + + let (l, r) = if is_right_side_node(index, level) { + (pair_node_hash, ¤t_hash) + } else { + (¤t_hash, pair_node_hash) + }; + + let parent_node_hash = H::node_hash(level, l, r); + current_hash = parent_node_hash; + } + + self.root = current_hash; + + LeafQuery { + leaf: leaf, + first_write, + index: *index, + merkle_path: path, + } + } +} + +impl< + const DEPTH: usize, + const INDEX_BYTES: usize, + const LEAF_METADATA_WIDTH: usize, + H: BinaryHasher<32>, + L: EnumeratedBinaryLeaf<32>, + > BinarySparseStorageTree + for InMemoryStorageTree +{ + fn empty() -> Self { + Self::new() + } + fn next_enumeration_index(&self) -> u64 { + self.next_enumeration_index + } + fn set_next_enumeration_index(&mut self, value: u64) { + self.next_enumeration_index = value; + } + fn root(&self) -> [u8; 32] { + self.root + } + fn get_leaf(&mut self, index: &[u8; INDEX_BYTES]) -> LeafQuery { + Self::get_leaf(self, index) + } + fn insert_leaf( + &mut self, + index: &[u8; INDEX_BYTES], + leaf: L, + ) -> LeafQuery { + Self::insert_leaf(self, index, leaf) + } + // fn filter_renumerate(&self, indexes: &[[u8; INDEX_BYTES]], leafs: &[L]) -> (u64, Vec, Vec) { + fn filter_renumerate<'a>( + &self, + indexes: impl Iterator, + leafs: impl Iterator, + ) -> (u64, Vec<([u8; INDEX_BYTES], L)>, Vec) { + Self::filter_renumerate(&self, indexes, leafs) + } + fn verify_inclusion(root: &[u8; 32], query: &LeafQuery) -> bool { + Self::verify_inclusion(root, query) + } +} + +use crate::blake2::{Blake2s256, Digest}; + +impl BinaryHasher<32> for Blake2s256 { + fn new() -> Self { + Digest::new() + } + fn node_hash(_depth: usize, left_node: &[u8; 32], right_node: &[u8; 32]) -> [u8; 32] { + let mut hasher = ::new(); + hasher.update(left_node); + hasher.update(right_node); + let mut result = [0u8; 32]; + result.copy_from_slice(hasher.finalize().as_slice()); + + result + } + fn leaf_hash(leaf: &[u8]) -> [u8; 32] { + let mut hasher = ::new(); + hasher.update(leaf); + let mut result = [0u8; 32]; + result.copy_from_slice(hasher.finalize().as_slice()); + + result + } +} + +use crate::sha3::Keccak256; + +impl BinaryHasher<32> for Keccak256 { + fn new() -> Self { + Digest::new() + } + fn node_hash(_depth: usize, left_node: &[u8; 32], right_node: &[u8; 32]) -> [u8; 32] { + let mut hasher = ::new(); + hasher.update(left_node); + hasher.update(right_node); + let mut result = [0u8; 32]; + result.copy_from_slice(hasher.finalize().as_slice()); + + result + } + fn leaf_hash(leaf: &[u8]) -> [u8; 32] { + let mut hasher = ::new(); + hasher.update(leaf); + let mut result = [0u8; 32]; + result.copy_from_slice(hasher.finalize().as_slice()); + + result + } +} + +use derivative::Derivative; + +#[derive(Derivative)] +#[derivative(Clone, Copy, Hash, Debug)] +pub struct ZkSyncStorageLeaf { + pub index: u64, + pub value: [u8; 32], +} + +impl EnumeratedBinaryLeaf<32> for ZkSyncStorageLeaf { + fn empty() -> Self { + Self { + index: 0, + value: [0u8; 32], + } + } + fn from_value(value: [u8; 32]) -> Self { + Self { index: 0, value } + } + fn current_index(&self) -> u64 { + self.index + } + fn set_index(&mut self, value: u64) { + self.index = value; + } + fn value(&self) -> &[u8; 32] { + &self.value + } + fn set_value(&mut self, value: &[u8; 32]) { + self.value.copy_from_slice(value); + } + fn value_ref_mut(&mut self) -> &mut [u8; 32] { + &mut self.value + } +} + +// #[cfg(test)] +// mod test { +// use sync_vm::{glue::storage_application::input::StorageApplicationCircuitInstanceWitness, testing::create_test_artifacts_with_optimized_gate, franklin_crypto::bellman::plonk::better_better_cs::cs::Circuit}; +// use crate::zk_evm::zkevm_opcode_defs::system_params::STORAGE_AUX_BYTE; + +// use crate::witness::postprocessing::USE_BLAKE2S_EXTRA_TABLES; + +// use super::*; + +// #[test] +// fn trivial() { +// const DEPTH: usize = 256; +// const INDEX_BYTES: usize = 32; +// // const DEPTH: usize = 8; +// // const INDEX_BYTES: usize = 1; + +// let mut tree = InMemoryStorageTree::::empty(); + +// let tree2 = InMemoryStorageTree::::empty(); + +// assert_eq!(tree.root(), tree2.root()); + +// let dummy_leaf = ZkSyncStorageLeaf::from_value([1u8; 32]); +// let index = [2u8; INDEX_BYTES]; + +// let query = tree.insert_leaf(&index, dummy_leaf); +// let root = tree.root(); +// assert!(query.leaf.current_index() == 1); +// assert!(tree.next_enumeration_index() == 2); + +// let included = InMemoryStorageTree::::verify_inclusion(&root, &query); +// assert!(included); + +// let mut index = [255u8; INDEX_BYTES]; +// index[31] = 0; +// let query = tree.get_leaf(&index); +// let included = InMemoryStorageTree::::verify_inclusion(&root, &query); +// assert!(included); + +// let dummy_leaf_1 = ZkSyncStorageLeaf::from_value([3u8; 32]); +// let index_1 = [4u8; INDEX_BYTES]; + +// let query_1 = tree.insert_leaf(&index_1, dummy_leaf_1); +// let root_1 = tree.root(); +// assert!(query_1.leaf.current_index() == 2); +// assert!(tree.next_enumeration_index() == 3); + +// assert!(root != root_1); + +// let included = InMemoryStorageTree::::verify_inclusion(&root_1, &query_1); +// assert!(included); + +// let included = InMemoryStorageTree::::verify_inclusion(&root_1, &query); +// assert!(!included); +// } + +// #[test] +// fn reference_params() { +// const DEPTH: usize = 256; +// const INDEX_BYTES: usize = 32; +// // const DEPTH: usize = 8; +// // const INDEX_BYTES: usize = 1; + +// let mut tree = InMemoryStorageTree::::empty(); + +// println!("Empty root = {}", hex::encode(&tree.root())); +// println!("Next enumeration index for empty tree = {}", tree.next_enumeration_index()); + +// // let's create a leaf + +// let dummy_leaf = ZkSyncStorageLeaf::from_value([1u8; 32]); +// use crate::zk_evm::aux_structures::LogQuery; +// use crate::ethereum_types::{Address, U256}; +// let address = Address::from_low_u64_be(0x8002); +// let key = U256::zero(); +// let index = LogQuery::derive_final_address_for_params(&address, &key); + +// println!("Equivalence of query with address = {:?} and key = {}", address, key); +// println!("Will insert a leaf with value {} at index (hashed index) {}", hex::encode(&dummy_leaf.value()), hex::encode(&index)); + +// let query = tree.insert_leaf(&index, dummy_leaf); + +// println!("New root = {}", hex::encode(&tree.root())); + +// let root = tree.root(); +// assert!(query.leaf.current_index() == 1); +// assert!(tree.next_enumeration_index() == 2); + +// println!("New tree has next enumeration index = {}, and leaf got enumeration index = {}", tree.next_enumeration_index(), query.leaf.current_index()); + +// let included = InMemoryStorageTree::::verify_inclusion(&root, &query); +// assert!(included); + +// println!("Merkle proof path elements starting from the leafs:"); +// for (level, el) in query.merkle_path.iter().take(4).enumerate() { +// println!("{}", hex::encode(el)); +// if is_right_side_node(&query.index, level) { +// println!("Merkle path element is on the LEFT side"); +// } else { +// println!("Merkle path element is on the RIGHT side"); +// } +// } +// } + +// #[test] +// fn reference_params_extended() { +// const DEPTH: usize = 256; +// const INDEX_BYTES: usize = 32; +// // const DEPTH: usize = 8; +// // const INDEX_BYTES: usize = 1; +// use crate::zk_evm::aux_structures::LogQuery; +// use crate::ethereum_types::{Address, U256}; + +// let mut tree = InMemoryStorageTree::::empty(); + +// println!("Empty root = {}", hex::encode(&tree.root())); +// println!("Next enumeration index for empty tree = {}", tree.next_enumeration_index()); + +// // let's create a leaf + +// let dummy_leaf = ZkSyncStorageLeaf::from_value([1u8; 32]); +// let address = Address::from_low_u64_be(0x8002); +// let key = U256::zero(); +// let index = LogQuery::derive_final_address_for_params(&address, &key); + +// println!("Equivalence of query with address = {:?} and key = {}", address, key); +// println!("Will insert a leaf with value {} at index (hashed index) {}", hex::encode(&dummy_leaf.value()), hex::encode(&index)); + +// let query = tree.insert_leaf(&index, dummy_leaf); +// let root = tree.root(); +// let included = InMemoryStorageTree::::verify_inclusion(&root, &query); +// assert!(included); + +// // and few more + +// for i in 1..=5 { +// let mut value = U256::max_value(); +// value -= U256::from(i as u64); +// let mut buffer = [0u8; 32]; +// value.to_big_endian(&mut buffer[..]); +// let dummy_leaf = ZkSyncStorageLeaf::from_value(buffer); +// let address = Address::from_low_u64_be(u64::MAX/2 + (i as u64)); +// let key = U256::from_big_endian(&[255 - i; 32]); +// let index = LogQuery::derive_final_address_for_params(&address, &key); + +// println!("Equivalence of query with address = {:?} and key = {}", address, key); +// println!("Will insert a leaf with value {} at index (hashed index) {}", hex::encode(&dummy_leaf.value()), hex::encode(&index)); + +// let query = tree.insert_leaf(&index, dummy_leaf); +// let root = tree.root(); +// let included = InMemoryStorageTree::::verify_inclusion(&root, &query); +// assert!(included); + +// println!("New root = {}", hex::encode(&tree.root())); +// assert_eq!(query.leaf.current_index(), 1 + (i as u64)); +// } + +// assert_eq!(tree.next_enumeration_index(), 7); + +// // check 2 leafs: non-empty and empty + +// let i = 2; +// let mut value = U256::max_value(); +// value -= U256::from(i as u64); +// let mut buffer = [0u8; 32]; +// value.to_big_endian(&mut buffer[..]); +// let address = Address::from_low_u64_be(u64::MAX/2 + (i as u64)); +// let key = U256::from_big_endian(&[255 - i; 32]); +// let index = LogQuery::derive_final_address_for_params(&address, &key); + +// let query = tree.get_leaf(&index); +// let root = tree.root(); +// let included = InMemoryStorageTree::::verify_inclusion(&root, &query); +// assert!(included); +// assert_eq!(&buffer, query.leaf.value()); + +// // and empty one + +// let address = Address::from_low_u64_be(u64::MAX); +// let key = U256::from_big_endian(&[128; 32]); +// let index = LogQuery::derive_final_address_for_params(&address, &key); + +// println!("Equivalence of query with address = {:?} and key = {}", address, key); +// println!("Will get a leaf at index (hashed index) {}", hex::encode(&index)); + +// let query = tree.get_leaf(&index); +// let root = tree.root(); +// let included = InMemoryStorageTree::::verify_inclusion(&root, &query); +// assert!(included); +// assert_eq!(query.leaf.value(), &[0u8; 32]); + +// println!("Merkle proof path elements starting from the leafs:"); +// for (level, el) in query.merkle_path.iter().take(4).enumerate() { +// println!("{}", hex::encode(el)); +// if is_right_side_node(&query.index, level) { +// println!("Merkle path element is on the LEFT side"); +// } else { +// println!("Merkle path element is on the RIGHT side"); +// } +// } +// } + +// #[test] +// fn test_via_circuit() { +// use sync_vm::testing::Bn256; +// use sync_vm::traits::CSWitnessable; +// use crate::bytes_to_u128_le; +// use crate::encodings::*; +// use crate::encodings::initial_storage_write::*; +// use crate::encodings::repeated_storage_write::*; + +// const DEPTH: usize = 256; +// const INDEX_BYTES: usize = 32; +// // const DEPTH: usize = 8; +// // const INDEX_BYTES: usize = 1; + +// let mut tree = InMemoryStorageTree::::empty(); + +// let initial_root = tree.root(); +// let initial_enumeration_counter = tree.next_enumeration_index(); + +// // let's create a leaf + +// let dummy_leaf = ZkSyncStorageLeaf::from_value([1u8; 32]); +// use crate::zk_evm::aux_structures::LogQuery; +// use crate::ethereum_types::{Address, U256}; + +// let address = Address::from_low_u64_be(0xffffff); +// let key = U256::from(1234u64); +// let index = LogQuery::derive_final_address_for_params(&address, &key); +// let read_query = tree.get_leaf(&index); + +// let address = Address::from_low_u64_be(0x8002); +// let key = U256::zero(); +// let index = LogQuery::derive_final_address_for_params(&address, &key); +// let write_query = tree.insert_leaf(&index, dummy_leaf); + +// let new_root = tree.root(); +// let new_enumeration_idnex = tree.next_enumeration_index(); + +// // form a witness + +// let (mut cs, round_function, _) = create_test_artifacts_with_optimized_gate(); + +// let mut deduplicated_rollup_storage_queue_simulator = LogQueueSimulator::empty(); + +// // manually form a log + +// use crate::zk_evm::aux_structures::*; + +// let log_query = LogQuery { +// timestamp: Timestamp(0), +// tx_number_in_block: 0, +// aux_byte: STORAGE_AUX_BYTE, +// shard_id: 0, +// address, +// key, +// read_value: U256::zero(), +// written_value: U256::zero(), +// rw_flag: false, +// rollback: false, +// is_service: false, +// }; + +// deduplicated_rollup_storage_queue_simulator.push_and_output_intermediate_data(log_query, &round_function); + +// let log_query = LogQuery { +// timestamp: Timestamp(0), +// tx_number_in_block: 0, +// aux_byte: STORAGE_AUX_BYTE, +// shard_id: 0, +// address, +// key, +// read_value: U256::zero(), +// written_value: U256::from_big_endian(dummy_leaf.value()), +// rw_flag: true, +// rollback: false, +// is_service: false, +// }; + +// deduplicated_rollup_storage_queue_simulator.push_and_output_intermediate_data(log_query, &round_function); + +// use sync_vm::glue::storage_application::input::*; +// use sync_vm::scheduler::queues::FixedWidthEncodingGenericQueueWitness; + +// let initial_fsm_state = StorageApplicationFSM::::placeholder_witness(); + +// let mut passthrough_input = StorageApplicationInputData::placeholder_witness(); +// passthrough_input.initial_next_enumeration_counter = initial_enumeration_counter; +// let root_as_u128 = bytes_to_u128_le(&initial_root); +// passthrough_input.initial_root = root_as_u128; +// passthrough_input.storage_application_log_state = take_queue_state_from_simulator(&deduplicated_rollup_storage_queue_simulator); + +// let mut final_fsm_state = StorageApplicationFSM::placeholder_witness(); +// let first_writes_simulator = InitialStorageWritesSimulator::empty(); +// let repeated_writes_simulator = RepeatedStorageWritesSimulator::empty(); + +// let root_as_u128 = bytes_to_u128_le(&new_root); +// final_fsm_state.root_hash = root_as_u128; +// final_fsm_state.next_enumeration_counter = new_enumeration_idnex; +// final_fsm_state.current_storage_application_log_state = take_queue_state_from_simulator(&deduplicated_rollup_storage_queue_simulator); +// final_fsm_state.repeated_writes_pubdata_queue_state = take_queue_state_from_simulator(&repeated_writes_simulator); +// final_fsm_state.initial_writes_pubdata_queue_state = take_queue_state_from_simulator(&first_writes_simulator); + +// let mut passthrough_output = StorageApplicationOutputData::placeholder_witness(); +// passthrough_output.final_next_enumeration_counter = new_enumeration_idnex; +// let root_as_u128 = bytes_to_u128_le(&new_root); +// passthrough_output.final_root = root_as_u128; +// passthrough_output.repeated_writes_pubdata_queue_state = take_queue_state_from_simulator(&repeated_writes_simulator); +// passthrough_output.initial_writes_pubdata_queue_state = take_queue_state_from_simulator(&first_writes_simulator); + +// let wit = transform_queue_witness( +// deduplicated_rollup_storage_queue_simulator.witness.iter() +// ); + +// // transform merkle path + +// use crate::bytes_to_u32_le; +// let path_read = (*read_query.merkle_path).into_iter().map(|el| bytes_to_u32_le(&el)).collect::>(); +// let path_write = (*write_query.merkle_path).into_iter().map(|el| bytes_to_u32_le(&el)).collect::>(); + +// let wit = StorageApplicationCircuitInstanceWitness { +// closed_form_input: StorageApplicationCycleInputOutputWitness { +// start_flag: true, +// completion_flag: true, +// observable_input: passthrough_input, +// observable_output: passthrough_output, +// hidden_fsm_input: initial_fsm_state.clone(), +// hidden_fsm_output: final_fsm_state.clone(), +// _marker_e: (), +// _marker: std::marker::PhantomData +// }, +// storage_queue_witness: wit, +// leaf_indexes_for_reads: vec![0, 0], +// merkle_paths: vec![path_read, path_write] +// }; + +// use crate::abstract_zksync_circuit::concrete_circuits::StorageApplicationCircuit; + +// let circuit = StorageApplicationCircuit::new( +// Some(wit), +// (4, USE_BLAKE2S_EXTRA_TABLES), +// round_function.clone(), +// None, +// ); + +// circuit.synthesize(&mut cs).unwrap(); +// } + +// } diff --git a/crates/zkevm_test_harness/src/witness/utils.rs b/crates/zkevm_test_harness/src/witness/utils.rs new file mode 100644 index 0000000..1f7c780 --- /dev/null +++ b/crates/zkevm_test_harness/src/witness/utils.rs @@ -0,0 +1,837 @@ +use crate::boojum::algebraic_props::round_function::AbsorptionModeOverwrite; +use crate::boojum::algebraic_props::round_function::AlgebraicRoundFunction; +use crate::boojum::config::ProvingCSConfig; +use crate::boojum::cs::gates::BooleanConstraintGate; +use crate::boojum::cs::gates::ConstantsAllocatorGate; +use crate::boojum::cs::gates::FmaGateInBaseFieldWithoutConstant; +use crate::boojum::cs::gates::ReductionGate; +use crate::boojum::cs::gates::SelectionGate; +use crate::boojum::cs::implementations::reference_cs::CSReferenceImplementation; +use crate::boojum::cs::traits::cs::ConstraintSystem; +use crate::boojum::cs::traits::gate::GatePlacementStrategy; +use crate::boojum::cs::CSGeometry; +use crate::boojum::field::SmallField; +use crate::boojum::gadgets::queue::QueueStateWitness; +use crate::boojum::gadgets::queue::QueueTailStateWitness; +use crate::boojum::gadgets::traits::encodable::CircuitEncodable; +use crate::boojum::gadgets::traits::round_function::*; +use crate::zk_evm::aux_structures::LogQuery; +use crate::zkevm_circuits::base_structures::vm_state::GlobalContextWitness; +use crate::zkevm_circuits::base_structures::vm_state::VmLocalStateWitness; +use crate::zkevm_circuits::base_structures::vm_state::{ + FULL_SPONGE_QUEUE_STATE_WIDTH, QUEUE_STATE_WIDTH, +}; +use crate::zkevm_circuits::fsm_input_output::circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH; +use boojum::cs::Place; +use boojum::dag::CSWitnessValues; +use boojum::gadgets::traits::encodable::WitnessVarLengthEncodable; +use circuit_definitions::boojum::cs::gates::lookup_marker::LookupFormalGate; +use circuit_definitions::boojum::cs::gates::ConstantToVariableMappingToolMarker; +use circuit_definitions::boojum::cs::gates::FmaGateInBaseWithoutConstantParams; +use circuit_definitions::boojum::cs::gates::ReductionGateParams; +use circuit_definitions::boojum::cs::GateTypeEntry; +use circuit_definitions::boojum::cs::Tool; +use circuit_definitions::boojum::cs::Variable; +use circuit_definitions::encodings::*; +use individual_circuits::main_vm::VmInCircuitAuxilaryParameters; +use individual_circuits::main_vm::VmInstanceWitness; +use serde::Serialize; + +use super::*; + +pub fn log_queries_into_states< + F: SmallField, + R: CircuitRoundFunction + AlgebraicRoundFunction, +>( + queries: impl Iterator, + round_function: &R, +) -> Vec> { + let mut result = vec![]; + let mut simulator = LogQueueSimulator::::empty(); + for q in queries { + let (_, intermediate_info) = simulator.push_and_output_intermediate_data(q, round_function); + result.push(intermediate_info); + } + + result +} + +pub fn transform_queue_state( + witness_state: QueueIntermediateStates, +) -> QueueStateWitness { + let result = QueueStateWitness { + head: witness_state.head, + tail: QueueTailStateWitness { + tail: witness_state.tail, + length: witness_state.num_items, + }, + }; + + result +} + +pub fn transform_sponge_like_queue_state( + witness_state: FullWidthQueueIntermediateStates, +) -> QueueStateWitness { + let result = QueueStateWitness { + head: witness_state.head, + tail: QueueTailStateWitness { + tail: witness_state.tail, + length: witness_state.num_items, + }, + }; + + result +} + +pub fn take_queue_state_from_simulator< + F: SmallField, + I: OutOfCircuitFixedLengthEncodable, + const N: usize, + const ROUNDS: usize, +>( + simulator: &QueueSimulator, +) -> QueueStateWitness { + let result = QueueStateWitness { + head: simulator.head, + tail: QueueTailStateWitness { + tail: simulator.tail, + length: simulator.num_items, + }, + }; + + result +} + +pub fn take_sponge_like_queue_state_from_simulator< + F: SmallField, + I: OutOfCircuitFixedLengthEncodable, + const N: usize, + const ROUNDS: usize, +>( + simulator: &FullWidthQueueSimulator, +) -> QueueStateWitness { + let result = QueueStateWitness { + head: simulator.head, + tail: QueueTailStateWitness { + tail: simulator.tail, + length: simulator.num_items, + }, + }; + + result +} + +use crate::boojum::gadgets::queue::CircuitQueueWitness; +use circuit_definitions::encodings::CircuitEquivalentReflection; +use circuit_definitions::encodings::OutOfCircuitFixedLengthEncodable; +use std::collections::HashMap; +use std::collections::VecDeque; +use std::sync::RwLock; + +pub fn transform_queue_witness< + 'a, + F: SmallField, + I: OutOfCircuitFixedLengthEncodable + 'a + CircuitEquivalentReflection, + const N: usize, + D: CircuitEncodable, +>( + witness_iter: impl Iterator + 'a, +) -> CircuitQueueWitness { + let wit: VecDeque<_> = witness_iter + .map(|(_enc, old_tail, el)| (el.reflect(), *old_tail)) + .collect(); + + CircuitQueueWitness { + elements: RwLock::new(wit), + } +} + +use crate::boojum::gadgets::traits::allocatable::*; +use crate::boojum::gadgets::traits::encodable::CircuitVarLengthEncodable; +use crate::boojum::gadgets::traits::witnessable::WitnessHookable; +use crate::zkevm_circuits::fsm_input_output::*; + +pub type ConstraintSystemImpl = CSReferenceImplementation< + F, + F, + ProvingCSConfig, + ( + GateTypeEntry>, + ( + GateTypeEntry< + F, + ReductionGate, + (usize, HashMap, (usize, usize)>), + >, + ( + GateTypeEntry>, + ( + GateTypeEntry< + F, + FmaGateInBaseFieldWithoutConstant, + ( + usize, + HashMap, (usize, usize)>, + ), + >, + >::GateConfiguration<( + GateTypeEntry, Option<(usize, usize)>>, + ( + GateTypeEntry< + F, + LookupFormalGate, + (Vec>, usize), + >, + (), + ), + )>, + ), + ), + ), + ), + >::Toolbox<( + Tool>, + (), + )>, +>; + +pub fn simulate_public_input_value_from_encodable_witness< + F: SmallField, + const AW: usize, + const SW: usize, + const CW: usize, + R: AlgebraicRoundFunction, + T: Clone + + std::fmt::Debug + + CSAllocatable + + CircuitVarLengthEncodable + + WitnessVarLengthEncodable + + WitnessHookable, + IN: Clone + + std::fmt::Debug + + CSAllocatable + + CircuitVarLengthEncodable + + WitnessVarLengthEncodable + + WitnessHookable, + OUT: Clone + + std::fmt::Debug + + CSAllocatable + + CircuitVarLengthEncodable + + WitnessVarLengthEncodable + + WitnessHookable, +>( + input_witness: ClosedFormInputWitness, + round_function: &R, +) -> ( + [F; INPUT_OUTPUT_COMMITMENT_LENGTH], + ClosedFormInputCompactFormWitness, +) +where + >::Witness: serde::Serialize + serde::de::DeserializeOwned + Eq, + >::Witness: serde::Serialize + serde::de::DeserializeOwned + Eq, + >::Witness: serde::Serialize + serde::de::DeserializeOwned + Eq, +{ + // compute the encoding and committment of compact form + let compact_form_witness = closed_form_witness_from_full_form(&input_witness, round_function); + + let public_input = commit_variable_length_encodable_witness::< + F, + ClosedFormInputCompactForm, + AW, + SW, + CW, + INPUT_OUTPUT_COMMITMENT_LENGTH, + R, + >(&compact_form_witness, round_function); + + (public_input, compact_form_witness) +} + +pub fn closed_form_witness_from_full_form< + F: SmallField, + const AW: usize, + const SW: usize, + const CW: usize, + T: Clone + + std::fmt::Debug + + CSAllocatable + + CircuitVarLengthEncodable + + WitnessVarLengthEncodable + + WitnessHookable, + IN: Clone + + std::fmt::Debug + + CSAllocatable + + CircuitVarLengthEncodable + + WitnessVarLengthEncodable + + WitnessHookable, + OUT: Clone + + std::fmt::Debug + + CSAllocatable + + CircuitVarLengthEncodable + + WitnessVarLengthEncodable + + WitnessHookable, + R: AlgebraicRoundFunction, +>( + full_form: &ClosedFormInputWitness, + round_function: &R, +) -> ClosedFormInputCompactFormWitness +where + >::Witness: serde::Serialize + serde::de::DeserializeOwned + Eq, + >::Witness: serde::Serialize + serde::de::DeserializeOwned + Eq, + >::Witness: serde::Serialize + serde::de::DeserializeOwned + Eq, +{ + let observable_input_committment = commit_variable_length_encodable_witness::< + F, + IN, + AW, + SW, + CW, + CLOSED_FORM_COMMITTMENT_LENGTH, + R, + >(&full_form.observable_input, round_function); + let observable_output_committment = commit_variable_length_encodable_witness::< + F, + OUT, + AW, + SW, + CW, + CLOSED_FORM_COMMITTMENT_LENGTH, + R, + >(&full_form.observable_output, round_function); + + let hidden_fsm_input_committment = commit_variable_length_encodable_witness::< + F, + T, + AW, + SW, + CW, + CLOSED_FORM_COMMITTMENT_LENGTH, + R, + >(&full_form.hidden_fsm_input, round_function); + let hidden_fsm_output_committment = commit_variable_length_encodable_witness::< + F, + T, + AW, + SW, + CW, + CLOSED_FORM_COMMITTMENT_LENGTH, + R, + >(&full_form.hidden_fsm_output, round_function); + + // mask FSM part. Observable part is NEVER masked + + let empty_committment = [F::ZERO; CLOSED_FORM_COMMITTMENT_LENGTH]; + + // mask FSM part. Observable part is NEVER masked + + let hidden_fsm_input_committment = if full_form.start_flag { + empty_committment.clone() + } else { + hidden_fsm_input_committment.clone() + }; + + // mask output. Observable output is zero is not the last indeed + let observable_output_committment = if full_form.completion_flag { + observable_output_committment.clone() + } else { + empty_committment.clone() + }; + + // and vice versa for FSM + let hidden_fsm_output_committment = if full_form.completion_flag { + empty_committment.clone() + } else { + hidden_fsm_output_committment.clone() + }; + + let new = ClosedFormInputCompactFormWitness { + start_flag: full_form.start_flag, + completion_flag: full_form.completion_flag, + observable_input_committment, + observable_output_committment, + hidden_fsm_input_committment, + hidden_fsm_output_committment, + }; + + new +} + +pub fn vm_instance_witness_to_vm_formal_state( + vm_state: &zk_evm::vm_state::VmLocalState, + aux_params: &VmInCircuitAuxilaryParameters, +) -> VmLocalStateWitness { + use crate::zkevm_circuits::base_structures::vm_state::VmLocalState; + + let mut hidden_fsm = VmLocalState::placeholder_witness(); + // depth and state encoding + hidden_fsm.callstack.stack_sponge_state = aux_params.callstack_state.0; + hidden_fsm.callstack.context_stack_depth = vm_state.callstack.depth() as u32; + + // non-saved part + hidden_fsm + .callstack + .current_context + .log_queue_forward_part_length = aux_params.storage_log_queue_state.tail.length; + hidden_fsm.callstack.current_context.log_queue_forward_tail = + aux_params.storage_log_queue_state.tail.tail; + // saved part + + let ctx = &mut hidden_fsm.callstack.current_context; + let out_of_circuit_context = &vm_state.callstack.current; + + // memory pages + ctx.saved_context.base_page = out_of_circuit_context.base_memory_page.0; + ctx.saved_context.code_page = out_of_circuit_context.code_page.0; + + // memory sizes + ctx.saved_context.heap_upper_bound = out_of_circuit_context.heap_bound; + ctx.saved_context.aux_heap_upper_bound = out_of_circuit_context.aux_heap_bound; + + // context composite + ctx.saved_context.context_u128_value_composite = + u128_as_u32_le(out_of_circuit_context.context_u128_value); + + // various counters + ctx.saved_context.pc = out_of_circuit_context.pc; + ctx.saved_context.sp = out_of_circuit_context.sp; + ctx.saved_context.exception_handler_loc = out_of_circuit_context.exception_handler_location; + ctx.saved_context.ergs_remaining = out_of_circuit_context.ergs_remaining; + ctx.saved_context.stipend = out_of_circuit_context.stipend; + ctx.saved_context.total_pubdata_spent = out_of_circuit_context.total_pubdata_spent.0 as u32; // two-complement + + // addresses + ctx.saved_context.code_address = out_of_circuit_context.code_address; + ctx.saved_context.this = out_of_circuit_context.this_address; + ctx.saved_context.caller = out_of_circuit_context.msg_sender; + + // flags + ctx.saved_context.is_static_execution = out_of_circuit_context.is_static; + ctx.saved_context.is_local_call = out_of_circuit_context.is_local_frame; + ctx.saved_context.is_kernel_mode = out_of_circuit_context.is_kernel_mode(); + + drop(ctx); + + // storage log specific part + hidden_fsm + .callstack + .current_context + .saved_context + .reverted_queue_head = aux_params.current_frame_rollback_queue_head; + hidden_fsm + .callstack + .current_context + .saved_context + .reverted_queue_tail = aux_params.current_frame_rollback_queue_tail; + hidden_fsm + .callstack + .current_context + .saved_context + .reverted_queue_segment_len = aux_params.current_frame_rollback_queue_segment_length; + + use crate::zkevm_circuits::base_structures::vm_state::ArithmeticFlagsPortWitness; + + // arithmetic flags + hidden_fsm.flags = ArithmeticFlagsPortWitness { + overflow_or_less_than: vm_state.flags.overflow_or_less_than_flag, + equal: vm_state.flags.equality_flag, + greater_than: vm_state.flags.greater_than_flag, + }; + + // registers + assert_eq!(hidden_fsm.registers.len(), vm_state.registers.len()); + for (dst, src) in hidden_fsm + .registers + .iter_mut() + .zip(vm_state.registers.iter()) + { + dst.value = src.value; + dst.is_pointer = src.is_pointer; + } + + hidden_fsm.previous_code_word = vm_state.previous_code_word; + + // auxilary counters and information + + hidden_fsm.timestamp = vm_state.timestamp; + hidden_fsm.memory_page_counter = vm_state.memory_page_counter; + hidden_fsm.tx_number_in_block = vm_state.tx_number_in_block as u32; + hidden_fsm.previous_code_page = vm_state.previous_code_memory_page.0; + hidden_fsm.previous_super_pc = vm_state.previous_super_pc; + hidden_fsm.pubdata_revert_counter = vm_state.pubdata_revert_counter.0 as u32; // two-complement + hidden_fsm.pending_exception = vm_state.pending_exception; + + hidden_fsm.context_composite_u128 = u128_as_u32_le(vm_state.context_u128_register); + + hidden_fsm.memory_queue_state = aux_params.memory_queue_state.tail.tail; + hidden_fsm.memory_queue_length = aux_params.memory_queue_state.tail.length; + + hidden_fsm.code_decommittment_queue_state = aux_params.decommittment_queue_state.tail.tail; + hidden_fsm.code_decommittment_queue_length = aux_params.decommittment_queue_state.tail.length; + + hidden_fsm +} + +use crate::zkevm_circuits::fsm_input_output::circuit_inputs::main_vm::VmCircuitWitness; +use crate::zkevm_circuits::main_vm::witness_oracle::WitnessOracle; + +pub fn vm_instance_witness_to_circuit_formal_input>( + witness: VmInstanceWitness, + is_first: bool, + is_last: bool, + global_context: GlobalContextWitness, +) -> VmCircuitWitness { + let VmInstanceWitness { + initial_state, + witness_oracle, + auxilary_initial_parameters, + cycles_range: _, + + // final state for test purposes + final_state, + auxilary_final_parameters, + } = witness; + + let hidden_fsm_input = + vm_instance_witness_to_vm_formal_state(&initial_state, &auxilary_initial_parameters); + + let hidden_fsm_output = + vm_instance_witness_to_vm_formal_state(&final_state, &auxilary_final_parameters); + + use crate::zkevm_circuits::fsm_input_output::circuit_inputs::main_vm::*; + + let mut observable_input = VmInputData::placeholder_witness(); + if is_first { + let VmInCircuitAuxilaryParameters { + decommittment_queue_state, + memory_queue_state, + current_frame_rollback_queue_tail, + .. + } = auxilary_initial_parameters; + + observable_input.rollback_queue_tail_for_block = current_frame_rollback_queue_tail; + observable_input.memory_queue_initial_state = memory_queue_state.tail; + observable_input.decommitment_queue_initial_state = decommittment_queue_state.tail; + observable_input.per_block_context = global_context; + } + + let mut observable_output = VmOutputData::placeholder_witness(); + if is_last { + let VmInCircuitAuxilaryParameters { + decommittment_queue_state, + memory_queue_state, + storage_log_queue_state, + .. + } = auxilary_final_parameters; + + observable_output.memory_queue_final_state = memory_queue_state; + observable_output.decommitment_queue_final_state = decommittment_queue_state; + observable_output.log_queue_final_state = storage_log_queue_state; + } + + VmCircuitWitness { + closed_form_input: VmCircuitInputOutputWitness { + start_flag: is_first, + completion_flag: is_last, + observable_input, + observable_output, + hidden_fsm_input, + hidden_fsm_output, + }, + witness_oracle, + } +} + +pub fn produce_fs_challenges< + F: SmallField, + R: CircuitRoundFunction + AlgebraicRoundFunction, + const N: usize, + const NUM_CHALLENGES: usize, + const NUM_REPETITIONS: usize, +>( + unsorted_tail: QueueTailStateWitness, + sorted_tail: QueueTailStateWitness, + _round_function: &R, +) -> [[F; NUM_CHALLENGES]; NUM_REPETITIONS] { + let mut fs_input = vec![]; + fs_input.extend_from_slice(&unsorted_tail.tail); + fs_input.push(F::from_u64_with_reduction(unsorted_tail.length as u64)); + fs_input.extend_from_slice(&sorted_tail.tail); + fs_input.push(F::from_u64_with_reduction(sorted_tail.length as u64)); + + let mut state = R::initial_state(); + R::specialize_for_len(fs_input.len() as u32, &mut state); + let mut it = fs_input.array_chunks::<8>(); + for chunk in &mut it { + R::absorb_into_state::(&mut state, chunk); + R::round_function(&mut state); + } + + let remainder = it.remainder(); + if remainder.len() != 0 { + let mut padded_chunk = [F::ZERO; 8]; + padded_chunk[..remainder.len()].copy_from_slice(remainder); + R::absorb_into_state::(&mut state, &padded_chunk); + R::round_function(&mut state); + } + + // now get as many as necessary + let max_to_take = 8; + let mut can_take = max_to_take; + + let mut result = [[F::ONE; NUM_CHALLENGES]; NUM_REPETITIONS]; + + for dst in result.iter_mut() { + for dst in dst.iter_mut().skip(1) { + if can_take == 0 { + R::round_function(&mut state); + can_take = max_to_take; + } + let el = state[max_to_take - can_take]; + can_take -= 1; + *dst = el; + } + } + + result +} + +const PARALLELIZATION_CHUNK_SIZE: usize = 1 << 16; + +pub(crate) fn compute_grand_product_chains( + lhs_contributions: &Vec<&[F; N]>, + rhs_contributions: &Vec<&[F; N]>, + challenges: &[F; M], +) -> (Vec, Vec) { + assert_eq!(N + 1, M); + let mut lhs_grand_product_chain: Vec = vec![F::ZERO; lhs_contributions.len()]; + let mut rhs_grand_product_chain: Vec = vec![F::ZERO; rhs_contributions.len()]; + + let challenges: [F; M] = *challenges; + + use rayon::prelude::*; + + lhs_grand_product_chain + .par_chunks_mut(PARALLELIZATION_CHUNK_SIZE) + .zip(lhs_contributions.par_chunks(PARALLELIZATION_CHUNK_SIZE)) + .for_each(|(dst, src)| { + let mut grand_product = F::ONE; + for (dst, src) in dst.iter_mut().zip(src.iter()) { + let mut acc = challenges[M - 1]; + + debug_assert_eq!(challenges[..(M - 1)].len(), src.len()); + + for (a, b) in src.iter().zip(challenges[..(M - 1)].iter()) { + let mut tmp = *a; + tmp.mul_assign(b); + acc.add_assign(&tmp); + } + + grand_product.mul_assign(&acc); + + *dst = grand_product; + } + }); + + rhs_grand_product_chain + .par_chunks_mut(PARALLELIZATION_CHUNK_SIZE) + .zip(rhs_contributions.par_chunks(PARALLELIZATION_CHUNK_SIZE)) + .for_each(|(dst, src)| { + let mut grand_product = F::ONE; + for (dst, src) in dst.iter_mut().zip(src.iter()) { + let mut acc = challenges[M - 1]; + + debug_assert_eq!(challenges[..(M - 1)].len(), src.len()); + + for (a, b) in src.iter().zip(challenges[..(M - 1)].iter()) { + let mut tmp = *a; + tmp.mul_assign(b); + acc.add_assign(&tmp); + } + + grand_product.mul_assign(&acc); + + *dst = grand_product; + } + }); + + // elementwise products are done, now must fold + + let mut lhs_intermediates: Vec = lhs_grand_product_chain + .par_chunks(PARALLELIZATION_CHUNK_SIZE) + .map(|slice: &[F]| *slice.last().unwrap()) + .collect(); + + let mut rhs_intermediates: Vec = rhs_grand_product_chain + .par_chunks(PARALLELIZATION_CHUNK_SIZE) + .map(|slice: &[F]| *slice.last().unwrap()) + .collect(); + + assert_eq!( + lhs_intermediates.len(), + lhs_grand_product_chain + .chunks(PARALLELIZATION_CHUNK_SIZE) + .len() + ); + assert_eq!( + rhs_intermediates.len(), + rhs_grand_product_chain + .chunks(PARALLELIZATION_CHUNK_SIZE) + .len() + ); + + // accumulate intermediate products + // we should multiply element [1] by element [0], + // element [2] by [0] * [1], + // etc + let mut acc_lhs = F::ONE; + for el in lhs_intermediates.iter_mut() { + let tmp = *el; + el.mul_assign(&acc_lhs); + acc_lhs.mul_assign(&tmp); + } + + let mut acc_rhs = F::ONE; + for el in rhs_intermediates.iter_mut() { + let tmp = *el; + el.mul_assign(&acc_rhs); + acc_rhs.mul_assign(&tmp); + } + + match (lhs_intermediates.last(), rhs_intermediates.last()) { + (Some(lhs), Some(rhs)) => { + assert_eq!(lhs, rhs); + } + (None, None) => {} + _ => unreachable!(), + } + + lhs_grand_product_chain + .par_chunks_mut(PARALLELIZATION_CHUNK_SIZE) + .skip(1) + .zip(lhs_intermediates.par_chunks(1)) + .for_each(|(dst, src)| { + let src = src[0]; + for dst in dst.iter_mut() { + dst.mul_assign(&src); + } + }); + + rhs_grand_product_chain + .par_chunks_mut(PARALLELIZATION_CHUNK_SIZE) + .skip(1) + .zip(rhs_intermediates.par_chunks(1)) + .for_each(|(dst, src)| { + let src = src[0]; + for dst in dst.iter_mut() { + dst.mul_assign(&src); + } + }); + + // sanity check + match ( + lhs_grand_product_chain.last(), + rhs_grand_product_chain.last(), + ) { + (Some(lhs), Some(rhs)) => { + assert_eq!(lhs, rhs); + } + (None, None) => {} + _ => unreachable!(), + } + + (lhs_grand_product_chain, rhs_grand_product_chain) +} + +pub fn transpose_chunks(original: &Vec>, chunk_size: usize) -> Vec> { + let capacity = original[0].chunks(chunk_size).len(); + let mut transposed = vec![Vec::with_capacity(original.len()); capacity]; + for outer in original.iter() { + for (dst, chunk) in transposed.iter_mut().zip(outer.chunks(chunk_size)) { + dst.push(chunk); + } + } + + transposed +} + +pub fn commit_encoding_round_function< + F: SmallField, + const AW: usize, + const SW: usize, + const CW: usize, + const N: usize, + R: AlgebraicRoundFunction, +>( + input: &[F], + _round_function: &R, +) -> [F; N] { + // we use length specialization here + let expected_length = input.len(); + + let mut state = R::initial_state(); + R::specialize_for_len(expected_length as u32, &mut state); + + // pad with zeroes + + let mut buffer_length = expected_length / AW; + if expected_length % AW != 0 { + buffer_length += 1; + } + + buffer_length *= AW; + + let mut buffer = Vec::with_capacity(buffer_length); + buffer.extend_from_slice(input); + + buffer.resize(buffer_length, F::ZERO); + + for chunk in buffer.array_chunks::() { + R::absorb_into_state::(&mut state, chunk); + R::round_function(&mut state); + } + + let output = R::state_into_commitment::(&state); + output +} + +pub fn commit_variable_length_encodable_witness< + F: SmallField, + T: WitnessVarLengthEncodable, + const AW: usize, + const SW: usize, + const CW: usize, + const N: usize, + R: AlgebraicRoundFunction, +>( + item: &T::Witness, + round_function: &R, +) -> [F; N] { + let expected_length = T::witness_encoding_length(item); + + let mut buffer = Vec::with_capacity(expected_length); + T::encode_witness_to_buffer(item, &mut buffer); + + assert_eq!(buffer.len(), expected_length); + + commit_encoding_round_function::(&buffer, round_function) +} + +pub(crate) fn compute_encodable_witness_commitment< + T: CSAllocatable + + WitnessVarLengthEncodable + + CircuitVarLengthEncodable, + const N: usize, + R: BuildableCircuitRoundFunction + + AlgebraicRoundFunction + + serde::Serialize + + serde::de::DeserializeOwned, +>( + wit: T::Witness, + round_function: &R, +) -> [GoldilocksField; N] { + let commitment = + commit_variable_length_encodable_witness::<_, T, 8, 12, 4, N, R>(&wit, round_function); + + commitment +} diff --git a/crates/zkevm_test_harness/src/witness/vk_set_generator.rs b/crates/zkevm_test_harness/src/witness/vk_set_generator.rs new file mode 100644 index 0000000..cba7430 --- /dev/null +++ b/crates/zkevm_test_harness/src/witness/vk_set_generator.rs @@ -0,0 +1,310 @@ +use super::*; +use super::oracle::VmWitnessOracle; +use crate::toolset::GeometryConfig; +use super::recursive_aggregation::*; +use sync_vm::testing::Bn256; +use sync_vm::testing::Fr; +use crate::bellman::plonk::better_better_cs::setup::VerificationKey; +use crate::bellman::plonk::better_better_cs::proof::Proof; +use sync_vm::recursion::recursion_tree::NUM_LIMBS; +use crate::abstract_zksync_circuit::concrete_circuits::*; + +// create circuits WITHOUT witness, but with all the parameters +// to generate verification keys. It needs geometry and some valid proofs for padding +pub fn circuits_for_vk_generation( + geometry: GeometryConfig, + splitting_factor_for_leafs: usize, + splitting_factor_for_nodes: usize, + scheduler_upper_bound: u32, + padding_aggregations: Vec<([Fr; NUM_LIMBS], [Fr; NUM_LIMBS], [Fr; NUM_LIMBS], [Fr; NUM_LIMBS])>, +) -> Vec>> { + // scheduler + let mut result = vec![]; + + use sync_vm::recursion::get_prefered_committer; + use sync_vm::circuit_structures::utils::bn254_rescue_params; + use sync_vm::recursion::transcript::GenericTranscriptGadget; + use sync_vm::recursion::recursion_tree::AggregationParameters; + use sync_vm::recursion::get_base_placeholder_point_for_accumulators; + use sync_vm::recursion::aggregation::VkInRns; + use sync_vm::recursion::get_prefered_rns_params; + + let rns_params = get_prefered_rns_params(); + let round_function = get_prefered_committer(); + let sponge_params = bn254_rescue_params(); + + let aggregation_params = AggregationParameters::<_, GenericTranscriptGadget<_, _, 2, 3>, _, 2, 3> { + base_placeholder_point: get_base_placeholder_point_for_accumulators(), + hash_params: sponge_params.clone(), + transcript_params: sponge_params.clone(), + }; + + let (padding_vk, padding_proofs) = get_paddings(); + + let transcript_params = (&sponge_params, &rns_params); + + use sync_vm::recursion::RescueTranscriptForRecursion; + + for proof in padding_proofs.iter() { + let is_valid = crate::bellman::plonk::better_better_cs::verifier::verify::< + Bn256, + _, + RescueTranscriptForRecursion<'_> + >( + &padding_vk, + proof, + Some(transcript_params) + ).expect("must try to verify a proof"); + assert!(is_valid, "padding proof and VK must be valid"); + } + + let padding_vk_encoding: [_; sync_vm::recursion::node_aggregation::VK_ENCODING_LENGTH] = { + // add + let vk_in_rns = VkInRns { + vk: Some(padding_vk.clone()), + rns_params: &rns_params + }; + use sync_vm::traits::ArithmeticEncodable; + let encoding = vk_in_rns.encode().unwrap(); + + encoding.try_into().unwrap() + }; + + let circuit = SchedulerCircuit::new( + None, + ( + scheduler_upper_bound, + rns_params.clone(), + aggregation_params.clone(), + padding_vk_encoding.to_vec(), + padding_proofs[0].clone(), + None, + ), + round_function.clone(), + None, + ); + + let circuit = ZkSyncCircuit::>::Scheduler(circuit); + result.push(circuit); + + let (padding_proofs, padding_public_inputs) = get_filled_paddings(splitting_factor_for_nodes, &padding_proofs); + + use sync_vm::glue::optimizable_queue::simulate_variable_length_hash; + let padding_vk_committment = simulate_variable_length_hash(&padding_vk_encoding, &round_function); + + // node aggregation + let circuit = NodeAggregationCircuit::new( + None, + ( + splitting_factor_for_nodes, + splitting_factor_for_leafs, + rns_params.clone(), + aggregation_params.clone(), + padding_vk_committment, + padding_vk_encoding.to_vec(), + padding_public_inputs.clone(), + padding_proofs.clone(), + padding_aggregations.clone(), + None, + ), + round_function.clone(), + None, + ); + + let circuit = ZkSyncCircuit::>::NodeAggregation(circuit); + result.push(circuit); + + let (padding_proofs, padding_public_inputs) = get_filled_paddings(splitting_factor_for_leafs, &padding_proofs); + + // leaf aggregation + let circuit = LeafAggregationCircuit::new( + None, + ( + splitting_factor_for_leafs, + rns_params.clone(), + aggregation_params.clone(), + padding_vk_committment, + padding_vk_encoding.to_vec(), + padding_public_inputs.clone(), + padding_proofs.clone(), + None, + ), + round_function.clone(), + None, + ); + + let circuit = ZkSyncCircuit::>::LeafAggregation(circuit); + result.push(circuit); + + // VM + let circuit = VMMainCircuit::new( + None, + geometry.cycles_per_vm_snapshot as usize, + round_function.clone(), + None + ); + let circuit = ZkSyncCircuit::>::MainVM(circuit); + result.push(circuit); + + // decommits sorter + let circuit = CodeDecommittsSorterCircuit::new( + None, + geometry.limit_for_code_decommitter_sorter as usize, + round_function.clone(), + None, + ); + let circuit = ZkSyncCircuit::>::CodeDecommittmentsSorter(circuit); + result.push(circuit); + + // code decommitter + let circuit = CodeDecommitterCircuit::new( + None, + geometry.cycles_per_code_decommitter as usize, + round_function.clone(), + None, + ); + let circuit = ZkSyncCircuit::>::CodeDecommitter(circuit); + result.push(circuit); + + // log demuxer + let circuit = LogDemuxerCircuit::new( + None, + geometry.cycles_per_log_demuxer as usize, + round_function.clone(), + None, + ); + let circuit = ZkSyncCircuit::>::LogDemuxer(circuit); + result.push(circuit); + + // keccak + let circuit = Keccak256RoundFunctionCircuit::new( + None, + geometry.cycles_per_keccak256_circuit as usize, + round_function.clone(), + None, + ); + let circuit = ZkSyncCircuit::>::KeccakRoundFunction(circuit); + result.push(circuit); + + // sha256 + let circuit = Sha256RoundFunctionCircuit::new( + None, + geometry.cycles_per_sha256_circuit as usize, + round_function.clone(), + None, + ); + let circuit = ZkSyncCircuit::>::Sha256RoundFunction(circuit); + result.push(circuit); + + // ecrecover + let circuit = ECRecoverFunctionCircuit::new( + None, + geometry.cycles_per_ecrecover_circuit as usize, + round_function.clone(), + None, + ); + let circuit = ZkSyncCircuit::>::ECRecover(circuit); + result.push(circuit); + + // ram permutation + let circuit = RAMPermutationCircuit::new( + None, + geometry.cycles_per_ram_permutation as usize, + round_function.clone(), + None, + ); + let circuit = ZkSyncCircuit::>::RAMPermutation(circuit); + result.push(circuit); + + // storage sorter + let circuit = StorageSorterCircuit::new( + None, + geometry.cycles_per_storage_sorter as usize, + round_function.clone(), + None, + ); + let circuit = ZkSyncCircuit::>::StorageSorter(circuit); + result.push(circuit); + + use crate::witness::postprocessing::USE_BLAKE2S_EXTRA_TABLES; + // storage application + let circuit = StorageApplicationCircuit::new( + None, + (geometry.cycles_per_storage_application as usize, USE_BLAKE2S_EXTRA_TABLES), + round_function.clone(), + None, + ); + let circuit = ZkSyncCircuit::>::StorageApplication(circuit); + result.push(circuit); + + // initial writes rehasher + let circuit = InitialStorageWritesPubdataHasherCircuit::new( + None, + geometry.limit_for_initial_writes_pubdata_hasher as usize, + round_function.clone(), + None, + ); + let circuit = ZkSyncCircuit::>::InitialWritesPubdataHasher(circuit); + result.push(circuit); + + // repeated writes rehasher + let circuit = RepeatedStorageWritesPubdataHasherCircuit::new( + None, + geometry.limit_for_repeated_writes_pubdata_hasher as usize, + round_function.clone(), + None, + ); + let circuit = ZkSyncCircuit::>::RepeatedWritesPubdataHasher(circuit); + result.push(circuit); + + // events sorter + let circuit = EventsSorterCircuit::new( + None, + geometry.cycles_per_events_or_l1_messages_sorter as usize, + round_function.clone(), + None, + ); + let circuit = ZkSyncCircuit::>::EventsSorter(circuit); + result.push(circuit); + + // l1 messages sorter + let circuit = L1MessagesSorterCircuit::new( + None, + geometry.cycles_per_events_or_l1_messages_sorter as usize, + round_function.clone(), + None, + ); + let circuit = ZkSyncCircuit::>::L1MessagesSorter(circuit); + result.push(circuit); + + // l1 messages hasher + let circuit = L1MessagesHasherCircuit::new( + None, + geometry.limit_for_l1_messages_pudata_hasher as usize, + round_function.clone(), + None, + ); + let circuit = ZkSyncCircuit::>::L1MessagesPubdataHasher(circuit); + result.push(circuit); + + use crate::witness::postprocessing::L1_MESSAGES_MERKLIZER_OUTPUT_LINEAR_HASH; + // l1 merklizer + let circuit = L1MessagesMerklizerCircuit::new( + None, + (geometry.limit_for_l1_messages_merklizer as usize, L1_MESSAGES_MERKLIZER_OUTPUT_LINEAR_HASH), + round_function.clone(), + None, + ); + let circuit = ZkSyncCircuit::>::L1MessagesMerklier(circuit); + result.push(circuit); + + // check ordering + let mut idx = -1; + for el in result.iter() { + let i = el.numeric_circuit_type(); + assert!(i as isize > idx, "previous idx is {}, but got {}", idx, i); + idx = i as isize; + } + + result +} diff --git a/crates/zkevm_test_harness/test_proofs/aux_layer/compression_for_wrapper_proof_1.json b/crates/zkevm_test_harness/test_proofs/aux_layer/compression_for_wrapper_proof_1.json new file mode 100644 index 0000000..714605b --- /dev/null +++ b/crates/zkevm_test_harness/test_proofs/aux_layer/compression_for_wrapper_proof_1.json @@ -0,0 +1 @@ +{"CompressionMode1Circuit":{"proof_config":{"fri_lde_factor":2,"merkle_tree_cap_size":16,"fri_folding_schedule":null,"security_level":80,"pow_bits":0},"public_inputs":[21633639700550076,48045916334222865,20177189711023887,63059293225404974],"witness_oracle_cap":[[8844676175549770232,6583850075550115690,13666586248576585481,256888860907815830],[4375819041444848485,5110939999110161520,9653814148314128608,598347526826524559],[14516237582001420425,2223773337956207717,14276546257794792922,2990749519932146870],[8120973060269282422,5837906734949881879,14563946469188618159,3141835658311057347],[15224653208001037214,5022689223541410979,1430401924588209865,1535292389881425994],[8971180122372586049,18131009073572853895,15943956471673918274,3227433527133184930],[13543708924083374165,3404295461749833191,9553969478893918530,1908064317331915484],[16498919866525390693,6000479482517816000,2140635677434672813,2609906694128897318],[1448253690725566128,855690520126432918,930262454351654755,34414059668875222],[1445171867903250364,15744489819416388386,1620636623117663126,2671945630523902382],[7262053180782096644,7088703731993255856,4094447191172482170,2356761806649885512],[14288001532998371044,15778511838950403736,7922417323152852134,2745847571440899291],[11493374110359314569,10726408648342908395,17695142520930434826,296932846174426187],[16654051699644279466,4258306041887987607,11260260034454932738,1951535121846465109],[14885726996356931263,16517540517326557170,17583168079479348977,3366507404377814345],[14870288668413096391,989162357081332964,9800022565262135107,183073198325673047]],"stage_2_oracle_cap":[[2713487605793100059,10370539147956616831,7489007792217475141,2063218982658183349],[4635513417363864026,11385635584299354763,15298307110261285988,2056602455163963304],[712045126744147875,16380446708164716263,17875192904280957020,2010508572532755620],[12333904546236226712,4580099936012117153,9294850694382282237,2987027048709572722],[3264609992452891302,6300611694246975580,1222290790434670644,1349870384353995591],[16568439558819652192,3667973317056896355,16749334336332011569,2519753249624568913],[16634083645695313245,309362137278044749,14528574939099390275,217029467390801736],[1339390012443900752,14195057114753320885,9390187366328212822,2313295938412701066],[15910877499625845251,16706786280402975268,6390972707183554073,1425445562134744006],[653963390311493213,11328131637328752939,9110276026442620930,2246990863118495571],[12713808632929797026,14106338645786617313,10696666725704671943,541506229973093201],[9086218073508038786,717486575736325933,6670482054169768624,2893521414115105852],[11710585725406534462,15779509743189931479,2187942076106667976,1557644865576925009],[9181529533134482715,7513942864784447380,3387657492075900211,458629993912112484],[18416957705222629354,12815200738193154142,10737130045285297898,1612562140327060318],[3168090934639875056,14032405859739574256,3500692247033524876,3405728536222344530]],"quotient_oracle_cap":[[8126448901209707565,7493244014146128266,12245457357743627483,206974514072702631],[15118640489164036289,2856140671160789855,12619239728467203212,74116305006461213],[10204388911698599247,9640316688258082408,11119031895423536316,366610651866537268],[591330534627750718,8439706887834301945,18407698302995972588,1154428900764966588],[3619911816081101271,12719486017746310985,7845908939359285707,2424246646757900651],[7881927259972562475,3660843872952279860,6128164999047392956,1473148787201321672],[3024153860205483842,8544234613782337359,3722611294624778108,980543270552803977],[11176261781493964223,5951243792228098744,5618676724200272788,2950109542193905686],[16052445853754520845,14084232932455627210,5586521449003472080,39966762994820528],[10730585942807647181,14080138060420035657,8903827122571282543,2184844261978929373],[11621080697152428453,1149590680740107667,4438293927262461876,2685187988683282098],[3216798224442949220,12047293272855804944,17483274987401064792,146835470157837054],[10783337675776571063,1448699083631015244,1344079293231870632,2624261056589864951],[12170354737618384480,8034727935131408781,10885384496950672266,199548995196772456],[7132770741431919452,13818067776679570924,937081224195457446,2709653169869128676],[8080562823914932794,3554195904354704484,4522678156297610915,552279379797836333]],"final_fri_monomials":[[8998092654957319715,9438910629198502298,4029675763269293339,15876362578429018837,12430007116226694718,2525605450954986208,16940983418677057654,7725561645247455194],[16273648128741099452,7777384626459149391,10340158940972408004,6662710762095648887,13739327281723970467,15988668549951659071,16458980159684012602,2297017236006987250]],"values_at_z":[{"coeffs":[267005474841715432,10783565582171727454],"_marker":null},{"coeffs":[3093038880434442140,8903154273068786586],"_marker":null},{"coeffs":[13086635101388733490,6966131402497799423],"_marker":null},{"coeffs":[4333966908566272539,2459585239845862892],"_marker":null},{"coeffs":[3360586831701505145,7213396696036856576],"_marker":null},{"coeffs":[2843684015207213594,16981175305720574993],"_marker":null},{"coeffs":[9266231666252447841,15761790789816084570],"_marker":null},{"coeffs":[15645277967267755529,15729513152515317544],"_marker":null},{"coeffs":[14021501653596824640,3022101180754984813],"_marker":null},{"coeffs":[16238157264963071193,10280619387577429898],"_marker":null},{"coeffs":[9476718130555677636,17555313002441027650],"_marker":null},{"coeffs":[5969661658982027761,11617439965324736065],"_marker":null},{"coeffs":[4858714818680719137,17471874846019917948],"_marker":null},{"coeffs":[1868889981625803932,17660953221149558932],"_marker":null},{"coeffs":[7087899526445159538,14468891461193067870],"_marker":null},{"coeffs":[8785752040167398483,5528787055417606766],"_marker":null},{"coeffs":[17361889279647151610,13068757337000150320],"_marker":null},{"coeffs":[16043494220544358507,3456676505679938909],"_marker":null},{"coeffs":[5811484853056574485,12047682157043283090],"_marker":null},{"coeffs":[14412674474441107429,922371226746427004],"_marker":null},{"coeffs":[817923558904727541,2769801467253808859],"_marker":null},{"coeffs":[1233720730468865858,14144378526822883616],"_marker":null},{"coeffs":[6929173119480288358,401621627092699193],"_marker":null},{"coeffs":[16014688079063854505,11800183491275197416],"_marker":null},{"coeffs":[7740248819673761106,4848359393924222859],"_marker":null},{"coeffs":[10408521963988288602,12410560098667422296],"_marker":null},{"coeffs":[7072318769291277763,14475122918594268895],"_marker":null},{"coeffs":[5185559879002409657,13453263610026947754],"_marker":null},{"coeffs":[10363717013788576928,14512479666379041728],"_marker":null},{"coeffs":[8218614391146770954,3389442470777292957],"_marker":null},{"coeffs":[8943300036597860587,6563071417595433875],"_marker":null},{"coeffs":[7214922039928036237,10650701920549133739],"_marker":null},{"coeffs":[18190748277096020138,12221275458933543904],"_marker":null},{"coeffs":[1623431627163210840,5883315556022294052],"_marker":null},{"coeffs":[11667812856834928932,11898488327762129112],"_marker":null},{"coeffs":[7222098160473327377,14100200095889578337],"_marker":null},{"coeffs":[1349353752751025182,3201005861441763665],"_marker":null},{"coeffs":[1279375737574786147,7223098952810796306],"_marker":null},{"coeffs":[18342700687381950456,11142587430853453664],"_marker":null},{"coeffs":[16459974764962491313,14921929641958649661],"_marker":null},{"coeffs":[16274172439305024965,9808755373129213199],"_marker":null},{"coeffs":[14736878529674038338,14264812863846521167],"_marker":null},{"coeffs":[13905099416008190025,7277905738685672808],"_marker":null},{"coeffs":[5894322810732287743,1584784304026500792],"_marker":null},{"coeffs":[13997520619398151190,16593587348199194788],"_marker":null},{"coeffs":[14803605331884751490,16942379492964368341],"_marker":null},{"coeffs":[9315650048490250106,5430419293515506663],"_marker":null},{"coeffs":[3184244145076490830,15942702073066085725],"_marker":null},{"coeffs":[15920048914718685347,7374973050161944315],"_marker":null},{"coeffs":[11025846083588977617,11727535386585813341],"_marker":null},{"coeffs":[12266133799080781962,5847841166651874610],"_marker":null},{"coeffs":[14697861152667093178,14098913615914832552],"_marker":null},{"coeffs":[3657570931276001740,959745123738116402],"_marker":null},{"coeffs":[4545578655987472185,979600121833109017],"_marker":null},{"coeffs":[16312569246315977653,7180045214142181367],"_marker":null},{"coeffs":[7178866814445877750,13385898691029343707],"_marker":null},{"coeffs":[16786336450443586612,16149063033730719494],"_marker":null},{"coeffs":[15708659759225223286,9063764868846481723],"_marker":null},{"coeffs":[905585522094127847,5638688115919999478],"_marker":null},{"coeffs":[1905962139554232246,15383653007001723421],"_marker":null},{"coeffs":[10452634577067563526,1559437719766591393],"_marker":null},{"coeffs":[10141726550018671001,17500115220455602716],"_marker":null},{"coeffs":[2436009980679565300,1888364339694865518],"_marker":null},{"coeffs":[3548275981568686792,5069942760210276640],"_marker":null},{"coeffs":[7299000742671262925,16621664748536918100],"_marker":null},{"coeffs":[15637247159380279406,11306338848792869179],"_marker":null},{"coeffs":[6557235369133041113,15990243440510622369],"_marker":null},{"coeffs":[17175560011732918314,11693670006653802487],"_marker":null},{"coeffs":[1146065302638451422,6866807692480000661],"_marker":null},{"coeffs":[15625878029790598573,7791270313226904193],"_marker":null},{"coeffs":[12436750665561213994,17059972934028057876],"_marker":null},{"coeffs":[14764070786501158120,1723600629225800001],"_marker":null},{"coeffs":[16590185271660618711,4977651525429362328],"_marker":null},{"coeffs":[3313961636383014079,13902445899355660939],"_marker":null},{"coeffs":[18195062798859324926,9135922156681727195],"_marker":null},{"coeffs":[15487123708072288980,7288893274998567589],"_marker":null},{"coeffs":[12718598075717213563,13105015823286951601],"_marker":null},{"coeffs":[6721002199586214204,2410489233024748888],"_marker":null},{"coeffs":[16017547453429852809,4782107898850302897],"_marker":null},{"coeffs":[8546947306998723028,14160553475161311937],"_marker":null},{"coeffs":[15516540447943516134,11539704445892356786],"_marker":null},{"coeffs":[148673356683059127,17687860774993371573],"_marker":null},{"coeffs":[17044172595474269540,12058870697830840513],"_marker":null},{"coeffs":[3662755918677748070,797651927254836221],"_marker":null},{"coeffs":[2448895110909322525,16573109370394292947],"_marker":null},{"coeffs":[15128636402598183443,1849297697186333804],"_marker":null},{"coeffs":[14834921777317661300,5747722843704354086],"_marker":null},{"coeffs":[2858581493707321895,10834835057813849109],"_marker":null},{"coeffs":[10093807475052665339,1708509020236807064],"_marker":null},{"coeffs":[4946259544053071394,6442894097256038487],"_marker":null},{"coeffs":[14491804721538191934,12217052147676431365],"_marker":null},{"coeffs":[12050113119417095685,14564883333639256162],"_marker":null},{"coeffs":[5792470558490775638,15320849448645333463],"_marker":null},{"coeffs":[13610662030229999707,12932747081208032174],"_marker":null},{"coeffs":[4158340867173682834,14581075376493269923],"_marker":null},{"coeffs":[5945388468910052248,15964210432429991249],"_marker":null},{"coeffs":[9164051002238462397,17851479147290062063],"_marker":null},{"coeffs":[6007607321811040270,17458579592194846458],"_marker":null},{"coeffs":[9013718150254348480,3680422910511258298],"_marker":null},{"coeffs":[7350975070531329078,5638616693062735213],"_marker":null},{"coeffs":[13932192618961741552,16029693620905507864],"_marker":null},{"coeffs":[6068211895472454908,10049380715590580630],"_marker":null},{"coeffs":[1544133361397346965,10686391533278676424],"_marker":null},{"coeffs":[4927943279715574174,13933564253891637014],"_marker":null},{"coeffs":[8832993609363701792,9776081298345785867],"_marker":null},{"coeffs":[4304053683882747714,9719700126052194042],"_marker":null},{"coeffs":[8822868797087510779,15984948773146715687],"_marker":null},{"coeffs":[5784148485229746704,1866847520262118748],"_marker":null},{"coeffs":[4997842014608408148,15369328130322296586],"_marker":null},{"coeffs":[16950387962174892794,4870519297914733320],"_marker":null},{"coeffs":[14835395307128039718,11080865854427949416],"_marker":null},{"coeffs":[13042528252791534546,14335987043557160761],"_marker":null},{"coeffs":[17693097349268049338,4506399231120224983],"_marker":null},{"coeffs":[7149495116105303755,12053096577303800112],"_marker":null},{"coeffs":[16302320718160823690,10081590277729409373],"_marker":null},{"coeffs":[9533257096533001757,14962371518013798194],"_marker":null},{"coeffs":[10173381760209699394,12327298371395927651],"_marker":null},{"coeffs":[16186361911040749541,13783933194417512031],"_marker":null},{"coeffs":[6462532395458643222,5094335679560891009],"_marker":null},{"coeffs":[1878082823122950384,10008215638593648209],"_marker":null},{"coeffs":[2803877530164049306,2560521817455225238],"_marker":null},{"coeffs":[6301972040271509147,5149081453664403117],"_marker":null},{"coeffs":[1075015069347321173,5502410759177158825],"_marker":null},{"coeffs":[9051612317992053741,11597498750660250960],"_marker":null},{"coeffs":[11947046301532799727,15468845766173184373],"_marker":null},{"coeffs":[4889469347798327086,4532727097879795866],"_marker":null},{"coeffs":[2259260947500307432,9509555426411785655],"_marker":null},{"coeffs":[1989394439592872564,5618867963125266749],"_marker":null},{"coeffs":[11723124515661506420,17287870986663826312],"_marker":null},{"coeffs":[13895735980354317780,845997933281466702],"_marker":null},{"coeffs":[536573064219933953,15688414244977482062],"_marker":null},{"coeffs":[14633199883203105599,4170212663917195093],"_marker":null},{"coeffs":[16473548613948980473,6412656588656820537],"_marker":null},{"coeffs":[6977754298167753905,3989209654926542591],"_marker":null},{"coeffs":[16251240432225938758,1032147055367714933],"_marker":null},{"coeffs":[9565859573415211912,527414217741121760],"_marker":null},{"coeffs":[7479757809070700786,16573630047727428789],"_marker":null},{"coeffs":[11989721569405926876,3506768173487651237],"_marker":null},{"coeffs":[2062542872659587522,13128256795006337124],"_marker":null},{"coeffs":[990486577967698861,14455697684704851300],"_marker":null},{"coeffs":[18421472562781143472,3066141272596893401],"_marker":null},{"coeffs":[8139441640627884479,10826635369386083882],"_marker":null},{"coeffs":[4364797070272251466,8698868686212742160],"_marker":null},{"coeffs":[6790903557723882598,11250484151039131448],"_marker":null},{"coeffs":[15199452963208194412,7264504819860901406],"_marker":null},{"coeffs":[15058012224075704199,5736751054818329729],"_marker":null},{"coeffs":[18402352008428213500,9353343399783552345],"_marker":null},{"coeffs":[16832965988367910863,7861408567980957520],"_marker":null},{"coeffs":[15288698127816490682,12355365607063279726],"_marker":null},{"coeffs":[11298990093271294523,14671374599171472883],"_marker":null},{"coeffs":[592904607981106355,4569423402910544778],"_marker":null},{"coeffs":[12012500313297302438,3353005369002360349],"_marker":null},{"coeffs":[8753219580840509237,6386962189282977421],"_marker":null},{"coeffs":[636688022342503648,12626778339628942186],"_marker":null},{"coeffs":[11550245291091363203,2309658790698272812],"_marker":null},{"coeffs":[1222459430397137720,16701085048933690404],"_marker":null},{"coeffs":[308642549569025382,4064523864567684174],"_marker":null},{"coeffs":[909530133491136280,10727288407582584000],"_marker":null},{"coeffs":[2812629660679626350,16711574551267207339],"_marker":null},{"coeffs":[9467968819017565349,1954234869378449582],"_marker":null},{"coeffs":[15231990930527582554,12068869166724279489],"_marker":null},{"coeffs":[4130524025938865677,8233974306986427115],"_marker":null},{"coeffs":[11616214285957114105,424515099076510330],"_marker":null},{"coeffs":[13931869772100800396,4807793460108687723],"_marker":null},{"coeffs":[2149230651495222932,2245333219545320196],"_marker":null},{"coeffs":[8457156741466464239,11957622728458007974],"_marker":null},{"coeffs":[865115286133887839,16258749148199876761],"_marker":null},{"coeffs":[2678012116669506089,10876836209885400023],"_marker":null},{"coeffs":[14292609920986549022,12011094763805450894],"_marker":null},{"coeffs":[3752695770414896651,4279034204087346678],"_marker":null},{"coeffs":[11814343587566706794,5975773068480352585],"_marker":null},{"coeffs":[17707559701892357681,18405023842690121992],"_marker":null},{"coeffs":[17840687390927529035,11337371977934529095],"_marker":null},{"coeffs":[12921433370914919500,46014411421110266],"_marker":null},{"coeffs":[17447977044437119737,13886121527910330855],"_marker":null},{"coeffs":[3872924299911790916,9351378565705939903],"_marker":null},{"coeffs":[15396681184379455001,10300637965443425213],"_marker":null},{"coeffs":[5604909797604063691,5901408976235852873],"_marker":null},{"coeffs":[15697381310487420243,11265964218596455660],"_marker":null},{"coeffs":[1375299410321735764,14986619008107035707],"_marker":null},{"coeffs":[1526094135333338034,2406905692242541416],"_marker":null},{"coeffs":[8885519905811798806,10479425998875652271],"_marker":null},{"coeffs":[9902513968808478807,14848252592732105441],"_marker":null},{"coeffs":[14677504142707347898,3991356770019273314],"_marker":null},{"coeffs":[17989094332885089550,670688720720473480],"_marker":null},{"coeffs":[2572774919617402703,6324198450656918240],"_marker":null},{"coeffs":[13181791395770274661,5966321314675250889],"_marker":null},{"coeffs":[447037187288284527,9973448828331976836],"_marker":null},{"coeffs":[12979075961186575982,6472126309124255126],"_marker":null},{"coeffs":[9002284153877823668,9843278859927705832],"_marker":null},{"coeffs":[14284305643859951427,3170227344501498712],"_marker":null},{"coeffs":[166537182563176894,18253649920020282505],"_marker":null},{"coeffs":[16854656103847564855,9563880887627067224],"_marker":null},{"coeffs":[10578432456833490888,8171129484307362967],"_marker":null},{"coeffs":[2645773307741955438,7136250222581937522],"_marker":null},{"coeffs":[3454630653873845103,11836795388423204],"_marker":null},{"coeffs":[15125399065509655681,8317193348971560654],"_marker":null},{"coeffs":[15570289028763488551,6245373628553914846],"_marker":null},{"coeffs":[9851562477834419105,9978809603880937482],"_marker":null},{"coeffs":[15957121900606463982,14043374889757162088],"_marker":null},{"coeffs":[6311568571911739344,7750277701008835968],"_marker":null},{"coeffs":[17072162542975324259,15620093276857458792],"_marker":null},{"coeffs":[8014457041161051136,7316595011667368542],"_marker":null},{"coeffs":[14472955556182131894,480462917633704565],"_marker":null},{"coeffs":[55887292610236099,12644437854392955684],"_marker":null},{"coeffs":[581551871254784446,11200947162188368629],"_marker":null},{"coeffs":[8884488915750386536,17976076729745073710],"_marker":null}],"values_at_z_omega":[{"coeffs":[15368309226390002947,72394664188044351],"_marker":null}],"values_at_0":[],"fri_base_oracle_cap":[[16001709499448344476,14820222707564580515,12744466032576663571,2582772672102738669],[1471191026957313969,11494268543818389338,6337897290845586336,362836141095662600],[17595896964893497292,7718317780793959563,17278407533119987623,133440826138061236],[4988704233121655054,4690880819282247762,16440994748924291248,2379285965046593084],[13171943102851875360,9635198674159205317,722826615848899051,2441910869486871502],[5217081095107753906,8412634781568989617,2828675469727117663,193525279317759762],[1827386449301371853,4609524277387013160,17033903040579396717,1618788863810862829],[16389816753502846933,680685144534170783,13581945077066558397,542727901486264103],[9721043048056819219,11525152927311170170,6498699968037868098,2555817642735375241],[1689590669551233943,17060504916594917776,10101200793652958902,1476346599080895891],[10401848512486679641,16153167318505788760,6677970445335109486,2143205977157801364],[12579217816488819012,7344777556193816493,170508741748307746,2701868830189665871],[16872251136714688241,6057053198926644450,413480218643088442,2355600634751474848],[14480711131698271999,13365909058712493642,8172944763826780964,2531448083706824222],[10403632661385621752,2244910387088390780,13926613305672366189,1987635957783317499],[10721877452844549995,9298405903890904420,4522793842108837772,2977231681706785031]],"fri_intermediate_oracles_caps":[[[1404505002950196398,2235001745952913563,1500800829522498009,104505610781280212],[10915645800981728601,16834948500384859669,11635952372204259479,3248057416672697724],[10310436757066756832,8056950822938352818,3195800086449566557,279952210947974097],[8290594727941661165,16094207879260346968,6738626163511080979,3168486389928222364],[10314243206370446635,15297120590403266054,229696710830261426,2221879004967645036],[8426375317572652472,17939036196501744051,9775564105115981034,33029603388648730],[2278428261525874912,693093507369101207,9483384542430364319,1951197592179533656],[5954493967330584415,9502255648429843519,12262840168177749128,1895905265093256684],[798221005760777790,17978837610546833906,15045928667448157117,1467727850263369945],[17404102094813168376,4856612280887081248,12700206759419726250,2654489894357005586],[5323657700728458639,16983832476272710821,12085893197638357620,486921470433033096],[7672376412790064278,14886982518106507901,10613348698164361955,2086855008809110801],[4686823168860044005,10738758586098293563,9765160531022893068,447993221293923209],[9221450478852682047,11539420713196250377,16758494729385809741,70523289353490290],[13432057839541786959,6236652836416025687,4327641370509609841,3320460100025007922],[1034701139735359377,13335779135295921900,15531858439525494710,685622844900450917]],[[16153733565662406773,18029442500376682296,11924201952827151813,2535464259236797607],[13545579529578722495,13048297904218662195,5870428786118320904,1951636846427411435],[13829574309775668478,2911052087386346736,4076006150724197196,3130674756076614476],[9966241207858358845,16156401446270405406,10441413280035608030,89742416679537626],[9540430141116102526,6503978356878305789,12668084278233011475,2282254352208360129],[5402244535433566389,13229565621132408952,15578122386514346802,502536738284303254],[9371783878454028938,12040334511183129832,11708655814943295013,3417084238195803355],[900498984197764145,12888703159917352966,10072494679167758894,3199615218714736617],[2047148528222639448,16025998609565189920,11659986513314296472,1512675032784062264],[18370434926797119782,13540831430373191178,16795883245448389286,161674420029392237],[2303344071363449722,1079271809659072596,14441699092536417832,122616240837690978],[12107765411819751515,14794491901050627451,14462741471775202411,430778761757032668],[8837166267493602473,12314357594702394641,17165638181808746414,199288217688421476],[6814764789634467298,9785966451398384184,7355550725787810535,2650428000206523425],[12764663508881534316,423839959192629182,1756311577167915900,19322268209439704],[10402425722309867202,1123117784130174608,16700517182660032100,3428784544900819990]],[[13593599816551536460,13440023752776486367,2352413407814187465,1073926276782280829],[8461746451461731920,12709026628136215625,16897754208126440517,1235157879262865479],[5066920674321177296,1385368519404376050,11781078605232585235,2632392155255104733],[10640697319372605967,2928241028847951459,4474737400548759967,3384237115057493737],[9213744227119133388,17379468964780799779,9745285344551818834,1841886759512962113],[8399446245743646549,5875925432388644093,14798951865223935319,1202344975409942142],[9658870861697142213,14036816264326242688,8733953442905757451,2053985300153878284],[4140098530798622210,11075941672715723585,15155847382072025919,3175338353969275222],[14252923572377934611,1542134998831342123,8172293706587818518,2718108141652724244],[14085419155824465196,5733654814212146715,6089100983359364720,2238996235322137807],[14415774491277304349,3702752510648428115,2260121722906152697,3077860765739822310],[335889385005619775,17818226773975829488,11494786033478264184,2943968162892137191],[12449991328720620105,3977302232573175952,9989650647338699660,291590821046171818],[10179959458615737495,6379672609849548277,6210358064177895266,2467986715003379514],[12884628403515402326,15542030086064466193,3936170801358733965,680048588788701304],[1056126867640001144,9879396982351631641,12109383058719199845,96952330842461781]],[[13033061953927257849,2544894538930012782,1126751917461926644,623857957301719760],[13395753229317240441,13535219829731526714,12901909209495195448,3397431797951100229],[7761702544694531951,3644645485988410401,14612198572052219234,965030581728680470],[8213930802020101351,4675210693368916820,14368694368560867253,1773367793978141271],[15546662848335791380,15090381129934120394,14894246705030916113,546326896993645709],[1775539582559114086,652724252801028308,13581635592076283904,2945222222745149832],[13035072558608855319,7349489488762135200,15762179043512308889,2650412089550845019],[15377258622270592859,1953432050100389436,10853493777812226766,381913834747285038],[1397805383998228867,11418495141662938515,7798166835920770939,3376196890556404169],[9245942584057223942,5919576212357338035,202705800857061696,2068008624995822647],[1239928104693506840,7427403520713688712,2017740168600516561,2355766226412073142],[17637663068965340757,709172498506042650,17964217990039520982,113046166351111833],[14547866262133278227,10942266950539995419,8918640647782559871,3370268941712508508],[16765068143348057972,10741397874758638717,7390825875736700794,1884149950312575136],[16731231638567632358,17015040664036407382,5082404376991524529,905567621637398769],[6159198299998534879,5140709060617596278,13493481277443849617,2804271234322094850]]],"queries_per_fri_repetition":[{"witness_query":{"leaf_elements":[17970123841656968559,13481790510083917202,2286784466199587102,5914087126415036404,15841926592725067655,4095052456949490275,797471193130356931,18013317896807681454,11704049956295146200,3758675282387476743,16715745698756112299,3962609814687525252,16089466656220969538,8288220562203817327,17529332409740078934,11000335161450989654,14754118548055574898,18375819843412113794,80252843665381537,16158328041780187130,14616917967723080495,8474208637876086789,2811691899835475105,7660403265570579564,14430517742170641492,4081085988668725022,13378061549720205724,1351451880948139552,5645655580912224072,17698828940214560826,12725606285971338882,1062109071466974927,892703602386091914,1894837816959611332,10380308992226978279,12136925149392240448,8961636483819017287,9220428058388094986,4987544991497060484,6720485693986266055,135458220587305938,5723635509488706158,15508161549143191733,6147575560020153112,12680056789137623665,12119489425281075310,2385037051079704026,14556095891526837179,8512016946575405515,16135029292060563171,8900180206088546909,1475405593451981887,15725528460339047368,15546873454335512116,9517253975325249857,13871595491152181966,15171973748470912242,6266286105442402613,11709865530461298833,2909753041898093178,17940128008734131033,17621079339695862426,10501027805444974944,14074741116525626185,5862256377718332612,2907348050731824671,17970979375497438822,11018071759901739622,1812861084336709525,10972185648111560482,6889007823924528855,12171007918452196078,1004844764526218695,16700990955344882705,14625999933659698606,8557669488878864106,9714413970466538362,15917116343636000645,18281821696790755160,18119057401462019422,728423191691159849,1237978038368928150,5008828746227026881,17082804009709890443,4840249556446494030,7547286114358999921,10139495905007250952,13814250249951405112,3268831253043448838,2962362656090608457,14738377641267293806,5622962214532221093,17885942087038888068,16762040393532265873,11303914261984199367,1949942933475121295,6063745684106960807,360384877947504700,8022408217090973985,4005296309391275964,16109172232629035325,11083460150121610943,11779830387816197987,9260271952114769267,10849838570811377493,18261543051921575890,1169652441886396707,10169987011001869993,10557202225064403418,16008360185096407955,8362022159849664868,10810039583589108222,4838523096180744082,15346235903124340562,15718114102160477180,4351770169919538095,16041811856979180189,2913801957681237331,16120028650024673884,3339612537813660339,1440997363860900130,17720660358259971926,16458324785516164361,63704470059080870,3948023693798519007,6026051249420781562,6493659260819100854,12638723583932896313,15114090871520704549,3029970397081241338,18392690222114596770],"proof":[[17788909700568759053,3970010317834349097,14271947439185397897,2389638249271245333],[8607125908160773000,18190610247285068661,17401255933968883594,1950195010998675510],[16138109954406164865,18332106788171926062,3493872483918638848,139935410359087745],[7088171585709415622,18006562414438319339,5114932369578051593,756822065932326026],[9564136269001489876,5506717972866169866,8261276163372671532,774193398371418062],[9421331588290320813,15183285383028952063,3565519315185806842,1169499095472457270],[3346917119334569857,4958334356482420668,6964719270748597289,622300613688029331],[4554392212335034086,15359243864478662811,9239344770013234341,181056284725246820],[4405409089704802620,11150355115603585676,14565831493461213364,2028581452564901287],[12460768900444784020,5576594848232282200,17416041079741544584,1123546804466381108],[2503665153956736773,17701251493816279618,14412658640691206573,26568670245358184],[6902291296385525908,6282427285539483573,1059247308760891000,1681441560494504270],[18265673367752908138,2754640070048023901,11724482278947537297,1725637765201767315]]},"stage_2_query":{"leaf_elements":[16723521335086567558,1491889904104646169,15987942644167580409,15182539382296250561,16878510349009371046,2239642356694345893,8459630893904936264,6668888493288017281,1839322360099462105,6496635400108412299,14525782393395726520,3251331937311277103,17387371513280940731,15650613155405433425],"proof":[[10694850792172159063,8829921499612912032,2900892484398834542,2098214348907317053],[15550391350382084589,1999534447241095900,1809932163491434307,3033191425490713782],[11768087787552530132,11343428795055416661,3550507803181346768,2908488535668877786],[12530275901483714040,14404020186491693012,13891032938439676112,3294638454953365361],[953718667548600096,6572888664396587849,17534634430759432415,2307830360569004093],[198081897449153343,6369751876418558381,2926735842838550698,2732885143298494519],[12113820430435468280,4741122413162821663,17886653308441285726,2951536505979050163],[8072424421165930287,5673025404592564179,4731011812140362184,2174488583371214694],[10963883540834088187,12411368101745084128,9295316295488679821,3074278677398873598],[15926784692644144937,10105749941195956482,11575877616074059687,1674953854457558853],[17653605708761678484,11128412812524188717,12517678524821206585,1816599886693073436],[13986678099248396499,763132589384391927,9776001136007254836,1152105376275273830],[11814671747401227134,14051467977723724755,11743029036639551575,3058315192689072958]]},"quotient_query":{"leaf_elements":[7804460979701892327,7235004382762175512,14263684747841194803,424874315771564517,6495476445270679704,9699938878719390700,7019512515058257621,1372098396425044471,16342642311884627723,18446521075852248682,727135047824387045,11960216749265786728,17177201097088443542,6088191279390927592,6809863879961606325,7857307685806882002],"proof":[[3793416896371883226,1665758574721157564,13634447506540031115,1786709718012722095],[7218542084440179990,10618758439612553879,6413868119724765901,1953746355783279816],[16740738525510394076,13581821425939534705,9657614888562824432,2806728340328595496],[15710526807201014038,14329259657017344260,16013012051502448973,1917416848660435624],[15066808579741484918,5630902026566762700,7557928092596792204,2112340584135842213],[1751418533116804468,3020592160198053352,9605758756531987538,2293217949298634031],[4624552645588543523,5531164681713149139,13556554478861737478,877527827937042995],[6182760385560116440,16616035036835733345,12534555915389532995,3009848390906577117],[8297478328250069543,9379767816802151989,2108523578306382258,2205375897450882633],[11161602453677629333,14085388039784099816,9642770167858872058,2620856497416710342],[9849695436071501586,17953769056934829276,7695364021090451497,2314536690529951670],[1142141420400307793,11479452402825870557,17088604191880103896,762895272704649451],[3504417128630898722,13418354669506357867,4877712583074407316,51888638990079231]]},"setup_query":{"leaf_elements":[6720755811817453185,17585999360779004354,6752222427941204288,7478807292076854350,12542264058134707274,7784377136206997423,10938706326085598382,5895417859050197721,7472715489308910386,4376933912468215455,13710720893324711755,137485758811502483,378020907474636377,16382625220080958521,3399001746991655998,13608655624449272528,10509884968722201332,13738841830453199331,11670059684329570138,639789851457002047,282597010848449979,4226759991328595637,10367228227206060143,15570194135181567520,695848424425685213,13399262937081226351,3667395415606237208,11732579819440843361,1761996515360146549,14934156231501704667,15230129641763643199,1984106406706218081,2680837295848754491,8208245823300071540,14631269225752378836,6978054493399966368,3603320285748463460,15923444209744769457,4035431135236954801,16322746835933664918,3653245088783491316,7412103195533200760,17186493184331437660,6611138280459798968,16744173469906362171,18171033151988384660,8111275762786322556,12171689403446328590,18409019052825366042,713943373035244123,1614745952815647191,17257223756281535554,6393100970861625569,211418019201115745,11752518897699985631,4451162047691368867,273279468850496942,17884941869253467388,11590415866939932058,7127656537568287800,378852674265837656],"proof":[[4739673289149048453,17007113841673230520,14882054601324540953,2943750432373970443],[5448258013500923588,6043109153824960520,13914748038600674096,1190467489788723282],[11722304805504363295,113088946199342037,14978103150731254168,1901582918547795297],[6020565140784535972,7932267532120613659,15495193040733062442,78956356465558750],[8194739846489535946,16500427820614525020,3717372225032169664,1352870175261767255],[13368527531067536847,16231910899429054755,8299289039085841211,3112573879900396268],[15453746841949587817,4220502126743864976,8672394160941738084,2147550994365629201],[3068106646056916709,940517368925110741,6075739962254820161,1850129720912396720],[11049878656309777010,17366909210453731484,267886745070092957,2227143188393557464],[10112465615104941234,357833218820644714,17836572035352137102,2216230345053829732],[15805847851050506814,15288827656103836746,17416016858118165468,538815875146189680],[14626434129209657568,3704788492558821904,11586933725645472561,2183731847757492550],[16340894896221363037,10515488107363041749,8989735385112029763,2859595575457666712]]},"fri_queries":[{"leaf_elements":[12204701115017836618,2837161142910256647,7611823252820475374,3207113021136752367,5479990809561416862,4801172167203884469,8548767838406603537,9546830117359244893,5276004697225208073,8386184738196600071,15370825730031443098,13188962837022093869,5115983245524809407,18408272355091172053,6097037770259917359,10329166923392860946],"proof":[[10353178748739147526,11694621427347224278,779161033485543807,97574362154997061],[5520225691076290317,7983631269359399489,128394786860828936,2721663127673627027],[1889050022788293541,13966307158963209192,14552386871579801042,3343032267222838086],[10660978818113458011,13262811635551575058,9580926212230811528,979218835364717307],[16325893452995886025,14434557817085933599,9174764330687297796,1274068813280449872],[1718533704280380175,9991292007556582659,11656308961839905952,1242905159750401192],[10710849580178033547,7811719790956016417,15249177737632781030,982457388690693665],[17408497355761376276,10474050774759595207,2528860048667436583,591482956912676393],[999846444995399222,14011138294935011139,6667964318074757587,867213260052525034],[13614949841622580336,9399492980024187335,15638599896098024049,1538027079629728594]]},{"leaf_elements":[2597962717775793180,12199617284679202625,16245608688124357758,11077381298280442747,12489171978677567447,14728716649229754486,15435603906034031489,15840329329709139247,5271104364723329962,5136201507047621581,16123643037909417823,14434305004100619150,12819950850461741247,8908457177429789381,14691877945257512366,12824780940828729746],"proof":[[7677710307327133610,2095951980846340057,13089934069766903936,3432521706637103667],[13793590847401384220,1783048621959148508,13130686000618115100,1426522966284389565],[3078649895805759068,14653220129529090420,12907338701304217574,925869809782347627],[90983467725985613,335530423920363131,658403098701060560,2604987885479845842],[33017520307084737,13852741744782689541,2645621811239446512,1404818793102642158],[1389768311319449007,14236537471961652686,3349081074204103601,2876773415225488148],[16707445333894112763,15652176173117182806,12717696149262687733,373930509062837472]]},{"leaf_elements":[14759155592439557793,16488441454620221226,17330459486777465303,11190660215740917708,14880969171061995116,13152854467232359794,6907162992881615924,1358177794514135888,16175207193546819510,928780939801814147,8223525302097893000,1954632806996643147,7011139936641774759,13866142840705453579,3590971238092489322,8091181876567799848],"proof":[[7377687488464998541,1685978064064248669,8428193370216528197,763910392754585222],[10317506766812928600,17896568784559891618,7810646376359295632,549909588202549556],[2598732342918378786,5317963112505505860,8244752469313706919,950042062237983842],[1395445178162007610,11626158447455766250,18397044548169564307,2769656745606904775]]},{"leaf_elements":[9036089175381653959,2987875599192350377,7744707005118505168,5188089847094658525,13129935381927018420,3730150788540291038,8209729877721515470,17090538519922816154,9607968513778767361,15071132642506767584,7320125160743097689,4991892819851375059,10068909456476243812,14089867269071297833,15389351978943733972,3387928692605495898],"proof":[[12726638950376879646,639506612650757720,16912813671638057237,2919186756859426224]]},{"leaf_elements":[11506617648987991818,868082017674053972,6543021463611153452,11748771781491803820],"proof":[]}]},{"witness_query":{"leaf_elements":[6077485044302383899,7964072719224616630,9922162248705172320,1931406090590497801,12896369061742191471,1847631146160749343,707072038614496207,4390763197219304357,18162066874700976413,6350472225000282963,1589555907514983906,6589206686891911739,1445985203731084581,12058410403301336694,5163207068427477127,14830831682735841882,6728326709874930114,9499030613737878010,7337313722591185428,16352500586732661420,10749200586127793729,7952746201815503369,3674854646829376802,13575901745719259818,17271415396033994751,13861528294846188784,7103064727477749527,3644076612367543485,730718586590296560,10523989598912180810,2368158989025947952,6770970596921482300,2946941805570854482,6900779089942974592,17473054737246631223,6006137527096518588,16621866350297547062,7164632357252276599,1033082909372664921,7636347499782533901,11787788953872723271,16775479653532452018,17656515573515457765,15451696296780675475,14706803047251391950,1147093381824243609,6434781450101243387,15713443787829784551,7714267045370269465,9401029519432805526,6753623774850869356,4258342076780631662,18205855732947252840,1356467339592298326,7052572597438550430,6576381663461065263,14648085871206993032,11244976151985914886,6801568067044847391,17646553686835500296,2706300175400212620,10275386993120399268,11885082404553589958,11911135187349425186,13927730445962800938,8863027467884536679,10588534527866463088,10338718621230052349,5751994206567952188,945004565257630488,13583159723214233439,16509913234493994279,10573312567590481400,5162000828836506581,16886129382880740604,12215057508120501572,17262858714177689297,1488759084367440242,10301318375284518820,4507716220870834660,15008911539305873647,7406649875528608828,17183276505818160169,13075288898921713714,6548616337090513025,1537341772560597718,16513276905385474720,7645863910817213135,7775053013146571939,2640537831274526370,17826404940079524935,7822784440207365917,7576961975860912232,15804833983607513528,7996308364970179454,11251138380187752143,13924617837729429476,6692620611882298566,8505078161193421539,4763967858212133526,9183541987958694467,13540815866790094300,10369755113881880995,9543866237420304406,18164397721129767573,5356231733361656470,9122835319091628083,6294659289611306790,5002465605520820218,11724408824945175633,3435360284021993858,13137110355791528063,15247403742912454147,7247782347499583921,2005156774516978999,9340911409797447904,11813946136486315802,2457956457913057883,16001620032677556223,201724905762209748,2268252546397170748,7364122959448423193,13077249853584050028,2129023301055679427,252893988904118453,5597663301917457573,8654703537670936441,16145255071353062528,76474902132390787,10208778331136707442,9323395107768248909],"proof":[[6242907584893370965,12372932697093631793,13942129693974896687,2843861640260251454],[775370825745608490,5417459948929670981,15212388135289648490,3184268714588316221],[9662785117647837277,3294828262773047675,14476349888257152919,1053487585110099588],[10608105030095899192,2523728841582399538,17967042290235737784,1664031471518191961],[897909777632203199,2843725045798309224,12962257836922482216,755111540203570184],[12672707398741353588,17184394726480931740,3834669951909814966,1911368097503754557],[13562762066899570754,1960124377208315643,5512412607795283414,2259400753041364861],[398329861788852579,3966873509202172362,10030862157498766177,1200346347692453620],[18390017707938171627,427903847285816559,17493013179744655031,1036606955455356385],[14301892666099265322,6222884080379243048,11726420686225479822,1325016167851522533],[16779477904172509902,16091115023491135893,13499810885676622069,3351915706379330519],[8690565119153444245,17487625917161455255,14430312195268593494,1607835318724117599],[15518311637091593798,7323673137202733312,16866621021086496135,1758145248427367643]]},"stage_2_query":{"leaf_elements":[4541254106977685728,17517769114166587354,4289111707393451731,6026148638827458564,18291914964333780148,15918609231520913488,4700688698770278021,1968488412896948431,8336631812158678922,14804079565523333494,10944350265499409063,17968204159636206574,17272094864225629810,6252469196135067848],"proof":[[17234128121471026916,17084637917518322480,9505683340603821711,736720787006288271],[13969327497910579751,6839001566400357084,5384701360824342067,537975726162849527],[15758603114754989351,17747354425417544080,6554253924921780015,644956008053688143],[15742502778751428489,13217063898869027576,10272196307146284662,37389626465142830],[9996590609178129303,3135333866328386836,11660578250839778873,3042857065914935392],[12796330549843900279,3347393794666795185,17668874360754231084,1107177520030767510],[8705836699590018197,9145438969318086043,9737133065220188019,1802088922585969946],[8812734631374898826,7915542764664098724,18212532731140347670,2971098827255997748],[16912979343278893927,605202949165733603,5092876968678233945,679232933363267743],[8322927887494576300,10360388406370206323,15171337664396455752,375861917059246569],[17954686911687466832,7688559998025566373,12366083838814267918,1844063590939899452],[1963554088813768267,14266585108512621430,7348072009656446802,1841284671791958841],[4875747540304223294,38261405649231656,4774002524529870398,1268748351122893534]]},"quotient_query":{"leaf_elements":[15456587082378659688,12483631971420952895,5201319838733066202,11647596127602017769,13709172876176206041,9238257143414914078,12529555792155144120,1741922896547063400,18253467032509374434,9546166088164480552,9272540739919121582,2840128069096664055,8013428590515956312,11649634006386193587,13531594673282374833,13164232605383663788],"proof":[[451159535645421542,4222093096152894856,11744996514505056086,2367438581197699092],[13960152649481700738,11072078900591428131,14764336816448115904,2409894692791175919],[9346221634127711092,15876414998006861686,8711752397012784165,1808990231043129626],[5716206150673734241,8499802230384408817,469571199760305114,554925651617661670],[11457774157258007246,16191313643216172508,6091744003592211581,586098189690631534],[1240371307099996956,14636694805144524847,11957825203981075246,778468398096064453],[17290744713006810289,9471039268105728250,9569375122716928123,1798617212337230379],[15050764983609212371,8450263817224090240,4399229579742096541,1534905661640819719],[7229783213173582940,3186486363585468901,12404377980950915924,2072474364914000915],[7431133909155535974,5679489411381905703,11316978234367615240,3020906890530555253],[14152989069101087202,12287794951587797756,14874830422162644088,3485185547646261355],[8331562444564311697,3970723311937752549,14203178688053940978,3390018082108970303],[10374326063544463999,13619301627134064518,17537478353870779175,1830171422987131595]]},"setup_query":{"leaf_elements":[9360499397975395688,6244332634197387253,12879994438455890988,16372300018527782898,12643370960199120975,14607210344864519784,13995111841300289005,12876839777736967704,11634952140767099272,9557637456893118623,9265302008295358731,15402655456867347443,13173754669437537222,16984039160440011927,7691694888005875920,12023499204323781953,13215524310272476182,9034499529946047908,15821612559696309016,7563420094009488884,4149974278472004701,10177900624010322294,1540876364141541754,6466695656218694082,2683260756092474571,8934615591830103962,11682491390876619067,11491537336116236253,17928318785839207880,2513446580934607560,10903650245651861594,8575830706357081582,4921519236054149198,17167066534349431042,5092715686544193792,363101849148404290,10241646212605907613,5698826321289124618,14255340395344229366,9103461050332460774,1596949410358646838,12713683711727692535,16107726454165049161,8589252259714619236,1821103663212545527,17429856793644477460,8637912130119081901,18235662355488056463,15385799383602865821,6183491282489553571,10641628979462187427,18306284708289290639,8954092633308805214,6850067403443110367,15583511535112855276,15659051243273644157,17321158911583659170,11529071205727689554,3056927067454235690,10043358737258105953,7200456072909217655],"proof":[[10008778415076816186,10288033141446420377,12168257243375150778,761578559841679412],[3297241915492615872,16627812091650867339,11054020427634967046,1062354328536498930],[1835320514805861029,14911537559856088555,1674811436123637042,1962505749431872559],[9692001106393922694,8894332088368441949,4613898696134948752,1935298238793056680],[10435965811417283106,13280038319069552987,16993955980608103513,1827342540684147807],[11831861360083826967,3452809253647043756,13075821437154107362,2380021773781417413],[9042118989544852092,7240330661278273171,14058418415593833014,2106825683148396192],[16959186525209193401,18157090504513401684,12733038888237257725,201652980071266420],[10932966571352479299,10857077330302452503,10174154837488854983,2272847697068371693],[17717967387065957201,9771438139238507642,5204958392165368010,1782310907160013305],[9457482904258610208,356219511890620635,9721094982983903760,777283556149836688],[10433510450430144301,9534562356708426407,110906836851143557,1929383473384015075],[9605218321895730305,11490338743997647430,12823317278098842748,3415966057955770875]]},"fri_queries":[{"leaf_elements":[71545121051053469,9084148606133670130,2142123131211012838,7815668100970136410,16962723519144377454,6280204493921906129,597822105705960799,3720464347937293787,4860878739101249611,6103131664908406029,11172381818931119015,9529814410488290566,3221372654247042661,6078137449183030757,4310142078742296189,9814652472503552102],"proof":[[13214171859889987881,2532991619733164674,18346444139074280726,2729434253697454055],[8270652680623102496,11241421547500690274,2155436410810924999,1346637889304547196],[146138121047430027,13990442974637457594,13784826651640996980,1109565523407472365],[16014445746210356502,9935674103449513719,5273991748295714526,1934179455373099150],[13425302871807098345,5097396896871992006,4767645093766259365,2789259936861270499],[5585126531196216757,7367913896206870359,12765078615643265650,1349553709645365897],[15520354940481339724,15536848090833273015,17616074985028870870,988739974645952979],[16652759705888100798,12007260918218635059,5145171050387575006,1214498768681436683],[8899149127723309034,16680782789077368554,12647937892000963151,2225211420632883058],[3942694800911061276,17921159622511465582,580068548089853162,1541139455362402679]]},{"leaf_elements":[10920992853615939967,3790138317200372300,13897965834944638240,8938184522676862811,9410747331155185578,2119715264165892346,5070698709204617606,9124773894282731561,18368241097985726341,10660847272129032798,5594847751799574606,5272919784515605285,585925787734288721,14956845784816589667,4472103195116628598,5848176591922456373],"proof":[[4300045949806776104,15149355326513071195,2520196133605155231,2290460473887015792],[1108575420675245642,16105008916339488847,760428530275168783,2847657089086898104],[13047896361868581167,5427983860177157663,15730569894933080204,1799402408948735291],[1723790679973059262,9870966104065550192,1088650322117238242,2196423903501652866],[3264726079356005385,1202373893288580291,13448781115362700825,1714524932960122614],[2528479504981134372,17740832014304503764,1483205343360500603,2566319671131613912],[356327678543436235,7521747318871730224,5926762661201943363,2802249010558468471]]},{"leaf_elements":[3058328279178208678,7829883332802513662,7080746957677036172,6987725583282306777,8270518424068588693,8926594841260776902,13747330287808676454,2819417015372890982,7625900463727107935,3398359389654225651,9035463830236415621,15933973516213579041,815126836308044192,17955834841048212255,17123528417263070149,5007884863202497580],"proof":[[15068152793048859010,6529765166456558571,1084033553434877304,2826818383228231636],[7188995064281191891,10021546224356321721,2776099942233359833,603700890933131035],[15828706135629023300,6002192074002833233,10107508101240280910,2288890144640514452],[7237173891938663337,8631390836781068402,10195641615156176892,531832987875452158]]},{"leaf_elements":[10795004986083287740,14360811068350965792,18254495574033950592,18333342172134336119,14842711178151700778,13998845893516253700,10325734391175010216,728330817682000593,14833964987039866727,11273087605295804328,17484234131895900348,14761196949777933922,2093000788320605630,108068430464939824,5682827616043446557,13244346337575742118],"proof":[[16205375200041717684,5114539439251029462,9508763204275366509,637819813805455874]]},{"leaf_elements":[16580212810250977730,4470259858681618858,8395368088134860335,16307579962635236903],"proof":[]}]},{"witness_query":{"leaf_elements":[11833047456433674269,14482401937426660198,13808039282343822307,10241116711484463249,17529157493674641662,12379718616512154881,10235822714357418136,17775664235670342023,5356290117774565463,1848791935994855905,4037915425641453518,16524658948093575802,16839613722142051408,815625514281500316,6687627444484829085,12321896364867652572,24321753540836695,17833988655800719223,17157671923375174392,8114858111800796521,18113410579940282123,16873538876569671508,14510109170719945086,5292137751819635063,12562021329930191548,14827725439052881507,6576106999896212387,5745381158128900866,3486623565584695370,6952032029355124980,17585211892524024945,5571933943082861117,11931390645737323493,958363269839570348,8902638456312587932,14734719538739761649,8471834030577625559,4515320106304407103,17549822990589601920,16470381105202048152,14514507963814514390,11083781282431821957,6405267897079329503,1171746317103647837,1457064308229083547,247880158063553828,18331787609161716706,3077417076286739675,7636055285676621268,12096372857863004035,14369413815628967096,14472315943524459675,9244246662194720924,2783277139316038561,5581569224513540251,624555393335118894,9112379906101305749,15914563809961999821,7591448797153556590,11288040470434210238,12770711738410993144,15455278075088956695,10292330359954949260,16219514104895724896,7612235051218568319,6288807345871233394,2106023612053225983,7684831615213403357,3991733612721842351,8954180287896742894,9175459531870770532,3245044862545910038,1359631407564196459,17934500578242638526,16939568729999298624,6846160011963963540,4717089687955592061,11659445355962040411,3015471050833849524,1421175596182760742,5529687502115565393,11190199729419392449,16024149630771157098,11497305542774695787,9285283751251295125,18268951730881038103,1698808014793756674,1606171963047433935,17788867521123786947,10449268263230047970,345267253703656972,6099518052939835347,8428403497181272640,12034372078558199135,14776742650234467664,2138655314397456557,11271563159054477978,15426859209383244542,12540900016776870425,6357177451655201009,4060674516979796439,40173386944624574,14818152953755443497,3455564891360358451,16650793083905363254,14760216656822723947,10814895135854268635,14956678661842005512,4510423573071942020,11093799253437491848,8730456460408521077,4669247982942989480,11897569219215502241,15373311605514680134,8017194288231201491,14374271314555666360,8049356188023067264,4470966076145397440,4943787683086026955,3081837284673650017,9441389328151984536,9245148712711857840,1485084669516340517,6763910963015218227,12865592066250886411,9625910224886442296,1334712000817340232,6657122026211780357,15238415257642549214,7138527190236550665,9734212909305784025],"proof":[[11500599344953850129,14996627010693695798,13739098124689258379,2842545720649165018],[3177612350684192719,13009862868933549075,13424823391114059747,3082825880270218159],[16091546789415491368,9893927759034785689,524562088104137614,1332856761099438259],[12040766112034476741,6334747586978101414,7090357655363339118,2086599339873233538],[12256004766860134761,17790555952832521376,15592764197119377843,2704489170326284792],[18095214753854189613,10178650889444219881,10270661338267585352,393938702921223812],[5390875736505904509,10599638689502109949,17179200344928311578,1885434479840728648],[16187667364613575404,14086689791477929226,11628856082037012649,188844844488450029],[1462690364762861859,7391820672947610837,14017089647055374949,3250315117990727516],[3261127681312918562,16735660629599891270,18247418370684520559,3254727243975979131],[12127852322855244248,6157826411207533768,10101693361150650378,3133699608277989220],[9768525576339722811,11672889008707792701,281691863958202578,3305185732159781746],[4832379906115138372,11028588231085674769,17437286517034418486,107753723037220434]]},"stage_2_query":{"leaf_elements":[461754584522663689,14627004407578907909,9594703282144604269,18215767994013782670,15794300310137116420,12922711970469985783,9791225853669455542,16631479976307016912,12635082145663249450,470341800010950990,11007385905063801008,11279886646091167847,9701398450104326419,5141535551904279375],"proof":[[12763101526854993020,12945148297375645180,4314537772445228430,2231407196017645621],[13453460598678558910,13211751513298653678,16912169567663353856,1331248391230377101],[13712105687585622705,17277412347745914796,6779143139926425276,1566368210781566901],[2782119326634347680,13472530477812176721,16535419109556332685,2261497630100921626],[7198000577876030731,7871578364117446775,14619183354551386368,3405526422754597005],[4017293940500637833,15391472484931446528,13582342145314476500,1032192625240215576],[2955545053657815512,14637445511489077385,12272314677165517657,1020871329916445363],[15150010895697646110,4323569470961256654,11939205563757346913,2521298077012664884],[15989479931801290198,436235686554504693,17979138085528318144,1427221777270019996],[8511712907817929782,6638848729552664602,17983170981134268312,1343681715893690621],[12974903116869077940,11105747345807080849,4417353386986237787,2856931376540744458],[4957393372301713968,7478362310982435063,2213452179512466607,2841487375964966511],[253179850175611026,12208827844828377664,5809494268557619388,1729946356149640536]]},"quotient_query":{"leaf_elements":[15057456631493700840,9684084936321153725,8845861161154755566,6859252889805933853,3444182928373053030,14893530272443917780,1894701494522633497,13580849552859764339,16487497581078082464,1001232483511750142,7407596129973418523,4617064497250536895,3366767385938467766,16734581797909442538,7846504298687170873,9856118980389912432],"proof":[[5896545675432639936,13378687597204700223,2910406306605603791,950470140173498800],[16193807557150555405,3784063233729518204,16790385303636731044,2131080980965218822],[9997634150250744468,12136882567097331194,7523619629763314080,1167157715337879945],[12854752165346602430,10858481415744379253,15073621480337422328,1890285119756935683],[17969446819146535248,8472160516200388950,18083121873626625984,120084353123249574],[3492474201649029335,12403770459565969521,9879640817612166874,1854733854281037058],[8257249178121991253,8736532774386115307,5846320139457159093,1987875836158112066],[17602380155207181813,13520762261738961810,3241333237529151353,2420566231572453932],[7992583745932746449,16945837655673480616,13293355169374859202,2200522464296877991],[9023151829240929826,2843767097796602276,12272129653273650256,1800738292201196814],[15827959190560400102,6995763554361694564,2298026645345693867,3440027472899695309],[7444540842383681101,8684344437036066525,602316500209861899,1699929338902742830],[7207630139810091379,4266854911965260134,6829268419185610647,551985630482796740]]},"setup_query":{"leaf_elements":[13042249495995175336,16103508383122432473,8915174036993875649,13149163937486451203,7350824956689476918,6804039347242122797,8778356483132889832,13581441036946801852,9982641416275748392,8250672460700703699,7911766725376112903,2939680328634267657,12109563695308686642,17478235203527976073,5594258717450566813,6418125669053747887,2105426453233858909,6516114211881588330,9079917652128661712,7799500773717000921,7176825224678971657,15925031806222784340,14151801479257858431,15102352219984075103,8456227810843329145,13764465923773542145,7538518358037890954,17154569912606000870,13258145568584015810,2402450909709416220,667111241447754780,15077239206156600320,16396999279988644093,9352703392931076072,13087974359811054095,3840034204407848633,15394275148022381436,17385703165981774366,4169948588777839693,8939268030120123935,985617123823610453,12748520481268273733,1340483831711259158,12865423819838126334,734617363878436137,3293007575857968355,3653004391161348446,3961594921146467192,13114725250299737610,8365784008905518150,13132705909447179914,2683505767183544453,12285306019357367428,5808954286719783150,5849146327741251794,14991574043010815479,3002322036058907406,6481934575647670214,4522420236140013751,13163678357337515444,3708082082192927541],"proof":[[17811720558198310683,5262147448920365167,3335634757650747879,86535972346598596],[17933927890223429782,5170206723614834981,11835135240596497817,2780901698328176728],[8795088501382377260,15276919438994538058,3976367079850947172,891061307260408209],[11483100926198428365,17143943272139637949,16321934988268600653,2242841788931608094],[14819462176352372838,15801870375245752387,1412489784275039843,2047923038803163166],[12108966629081532587,1371582505964871985,6258665001860429293,2707160348083291258],[11149238168463873263,10112657865253449964,5987838626393959003,296683685866338133],[222009559579300174,1381320973883113687,12302113045700586248,2262504708071563026],[11784985895202451185,7026340737855943442,15792999299706924198,365724601521654383],[12224643381520477969,4320966871043911358,2661660907376170966,3406627939649074732],[10455757379220240357,4099455521614776757,7291983808913411660,856319434517988093],[10367993263393630331,1790023779654835370,15091667091675067662,715938203495412360],[14430152768018435667,13625155425001863663,7751044715815897218,1229189555835738878]]},"fri_queries":[{"leaf_elements":[14521154678132547068,1216301910097758919,12098152682082253502,10348696526493963942,17419603603489388421,18318557007092911507,2102351986344710330,14537933659359485134,7148971974166702127,839172759181992818,17460977557725068761,7815724421997175209,12216655222214465279,6331639566670670163,18079698971682235747,6412668096441291945],"proof":[[8980848846838438046,17282732357186729025,13452625381143162996,497287313216990745],[16785814435432483442,4861628396995894164,4837303900009320096,3171603012762128998],[4407886159433133829,2425870433386076367,12125564675692930093,31918643222342383],[1042328702501970455,14903912564877705146,7533948852149355860,1458596514703956639],[9978337302987014658,13821741904829306231,12005701582551117454,689220667548188718],[2695334098523497815,2830126907069201030,6654738399356360623,3368107933114237444],[15187654257824309828,3965194026402803670,12039262933616569015,2737919392164299638],[2212500820357495793,6937574038175577081,8523903045346950306,2258988377035230135],[14554446821762509772,6529627218503375570,9851210291104147109,1485081884717766150],[12917255288235223966,14499976622908166881,5436213550229819212,2285844493389862808]]},{"leaf_elements":[15078471929653093160,5694287333993251367,15473951839407213249,16771283248659939155,18352237711554688479,15203442854888786928,9317033891847856615,12145214891234861485,14624108780742710309,3841808653842972125,4766791464238603457,804602386879916302,15787948655486393407,15180475794255126147,263861435622880500,12489049938808685455],"proof":[[611674732975260341,5086828433451006608,5801514558274583682,368277504814554681],[16138969907320167881,11689262890922308725,9355155393910888874,283205072987237734],[13928522118324807759,8590542890714388807,4813608130085993454,2797544329993296482],[7459324858133675254,15732445378714658871,4097417468335635664,247143953533461949],[15499152899528193300,7804569373351532253,12623084440031420317,3079078199647633414],[10755999276392972795,14331754590064518988,7553222335914137559,225262180444060771],[10678740004480657638,4821612586301572701,2713702765633163690,2883361707359353505]]},{"leaf_elements":[14546847992046342763,6171083746573157952,8501911667810956490,229890116965200758,17427125879513513245,2544006941087531624,4073944733295611295,9419392444665917827,17481348429223321626,5559719738400414222,4052402710394991850,2107505096945623478,5090702494022164656,15118151712808273061,1380716098664848849,13421737928759941286],"proof":[[10033425373562980192,11915608828670999174,2295270086726453774,1947475974416664199],[1386086042998848111,3673646343202589478,2519179364964670764,3286657799576966914],[5056283299278904916,7573716861628750030,3181551069891058784,569365129076205572],[7349579519894959072,3479006254350232831,2249506297850984686,3461002273469143448]]},{"leaf_elements":[10107650300144122446,12872316686921106367,17782138609005632202,3101284115629698348,8129718703149136541,3488748637624496172,12239539572413537733,8146046347961466389,3729132655365631872,3816743499182286664,16730468474630639466,9624190507278423052,1879743752497581249,4337712219509902155,1896622693346975870,8179875534869575739],"proof":[[2554532247243837486,6767478030061646626,4199547846988518451,2086946322843166353]]},{"leaf_elements":[6865243823879750534,264255220950879342,5012916995573505337,7094628130780347210],"proof":[]}]},{"witness_query":{"leaf_elements":[7858053895759413297,17265684436882291924,16766974822909926857,3465303499664434331,9534228294516748714,4032984289758998478,10850247355377850442,1464516432493615620,15762830965533552699,2233910658079061260,1857614548504856107,4456303440732756958,8708336317970479704,9579263915693897993,791983273371703301,15540243568502350777,17230666612686095535,10231199920379298483,2862759638803678919,421559860897805074,184125036513006281,6104399363275948941,9306873543547055142,10900821078020445261,17772399241542183959,6733384382265062729,1330965322355564972,4855917699720872194,6619361385008599225,8542077727032042915,17338062377847077341,5735345979695514352,13110457637062360636,2632091890242762259,8361470928332517985,2699421136753042056,7161863262825650290,8349689769951648140,11638863221951166222,12032645185916727136,17704892704004677664,12403061775981038565,16031757075276251123,14650862064443926906,16515203703207921243,4683025987414307939,4156744778119249862,4749348360435617831,2911567142162412649,17377160576881407761,9401573777677677330,12098153387655812015,10433906010992635352,3435742657791346113,3177486288869425333,2585819565654704019,12053047065409722849,13645059162711610947,21423275847969103,5580280916530469250,11407856738461719324,11526697323179379698,13987558369413825479,13801524763113946874,16043307182847084877,16402116663240649838,4494066996460538737,12855469553982270573,287255693971885289,2969124386453744586,8928810519062985626,4840597798250930136,15744551455689408593,3611220867817425017,1977609712293020807,3808615004478684834,2699408220846917566,16853841719781401621,7361551644600217697,11156124310228528180,16265619792038567155,3133713038354607608,63663942328739220,2311757288599513861,15151038365420826315,4549184485039584274,4138065344248967612,14406254587974572092,14839289392136175898,15943121016472190465,15095086134420153271,4823106491962138555,1073561163577799193,14494222875091136711,10181243972193507318,9899398314651438774,17114937674075741864,11387105926609214343,5302362556287250911,13588067785743770619,13382498408732249877,788744990152186242,5245580176391159200,10479343130649587529,4001598332587209591,15280950841757485376,11473607763803838741,9017760690388408092,293297464169325207,4346295824884441768,17767632442665281463,11752805059841756538,13615992397799893687,13063767029408415238,6994506286640835818,8801340772296449421,8823959093724638338,6040585894516185703,8423400221527120833,17054064767632723443,8544735916589329607,11160642711824954280,843588726499909546,8322423503310985326,13196367577408854465,8964126616648915821,8070042182156173237,17290693219251194283,4084479645041763879,16403499595766456232,7903990232150384040],"proof":[[9248726266279460407,11719716886506133603,8093472286927794750,2391733117977588000],[16230487998988215371,3869962483145590432,10667047180237612249,2619133409437079344],[16954556976740418427,6829734164595376758,9241021845014407393,2218451475913744752],[12741322580356810788,12281661807408177318,12823517827580402134,2116483097858975284],[4168687656463570433,820474106275283209,8258037139023940253,806364366208097599],[3576135308070206462,14516568160007066173,3170960222747206947,640556370129947569],[5358123620625392398,15157790135277378975,3840779527114075418,1820225871009814804],[2402996940444038742,3950758832537544534,2789895269555376893,3358125770469689491],[1430925518680982691,2151482013714942124,16913097774633859520,147599131468840431],[1404641130885712316,15967287234267707029,2952076247621225131,2559154194842940212],[9317988598386287165,4171320350909863924,7024179928034417626,2008805193649462816],[1399558611002625433,11998460121550009067,8931575056411310580,3349109739263796111],[9986534556560031500,4168905852649190801,8442442153577249726,935650195886037795]]},"stage_2_query":{"leaf_elements":[18387374257738215101,15306865974655227408,10432109101363722552,13009257871372670067,858742917555819602,11700042241141631063,11727056752961160433,17985370754237911177,8455775666096501621,158902061113344801,14384105655992688800,15222561479885621213,12412054439589846987,14203610041190331849],"proof":[[10602271031945289025,7216817529303894275,13166505173976065323,1865023148603653032],[12727876965690607425,15814055029826165251,17528228455431001104,1470221872853326659],[5199250607789117154,2398544252098586575,10172274853125479466,2972191494550935916],[14980119355089363917,11405247229453698780,4507664442888275569,2089786254495543413],[9714702084723907846,13303584281621097406,3105173158769839818,1141203502774068749],[2327605455165110139,3624045509711925208,15046532513107967618,2245319503228059824],[6469489900589334832,9624325376196692418,919653450069722995,2191430265191928589],[12111837910112259009,11424757229320283309,10945953313204065874,1077437281990647488],[11070872799713662175,14564988779637572671,7887799196142692735,3485423108122722116],[3659346768136687117,12679940537757350401,716142111141260185,1964797466937428027],[4156232298670899131,8442439683233985248,2816989313736023705,2855240463960380989],[4826186519142606509,8843526122236724294,17868385580913199502,789267515232431137],[3929106972898368341,8168702184152748531,1012745953153184386,2298210201343737391]]},"quotient_query":{"leaf_elements":[4373142612563086594,7196695026444633312,17966181116357038397,5898708573535078509,12423833816735514559,13655063470739956718,15844290769031548293,16853423080966098075,2152387015161682812,13449028288951989314,5047051715890940436,14761406751848360175,17334089116370640491,6252555333045656820,15717936551239099696,7650481587598529534],"proof":[[1352331086995267566,1400396491393940878,4746674844142304711,1260851863930028212],[10973376987389536987,12509235344157913231,7580817343989232122,50074051616339959],[5591065957170055081,12359457572268264550,1247653621792067096,583091124068274465],[442083255622447127,1099014203848345482,17962366655576264314,876113858416822965],[17344815146136435406,7118885977886899211,6137080122099893370,1512764061454333479],[8776096923298001681,1081566881641096575,1702148014321071430,1774221167702867853],[11452076884801265314,10495877807535785458,17666501598933167227,2919062808302266969],[15284633191884437224,10457892530260194329,4271961759214885038,2913223074315541258],[9003297077661626938,6311432929270788833,11967395938497052248,1817206478892744180],[14677564153425006496,15254281340754733383,7013018103077528789,1057327725926051211],[11242675047627637619,6613050748050112875,6280649273940896661,1540050270900068416],[5041539606130611705,911517593073596756,17525987174527020371,1929397605581272547],[3371259541088757273,6499617785722508082,5034023945137869546,868060244866308003]]},"setup_query":{"leaf_elements":[13362346394009980175,9765922703649385518,1384761281930046456,11404161352395288519,15563242342429714869,17436970936242412322,7445629126990963142,18201359157117362866,5375807717243711679,16972686101745404894,14665102692235845864,13913777093343325759,753387041202170043,9364842740350017109,5420656653052044375,11555717786061529664,11073175588637959843,16903406687579213789,649796185090484111,13375050265331305526,15332802773902762340,10596892116937578720,15381526947848232427,180762151583746435,14481021227183252899,4912230067271022786,14951704881092724566,8979661708963750302,9787983062512793514,17745058523192355830,10092951146302104051,6688154607682493967,14302982704500659366,12216186328706044021,18125594138526335054,16998636131538828443,1959176730016793439,16895118141237237428,2615808689926342108,15790081257058710586,18123403330007849215,8237608581322813907,8463232817732737607,17065603878084602340,3793389182477548884,6875520700161889621,11327343058397840664,16282879687489952714,16240713576847423276,8073676376859996125,10558983057594326156,901143834964025251,17284885476700362693,12898510279533251575,11573053444190212279,3273402262496919319,6912394307113305939,7497824384910778844,16245505234021041454,10019203148493413520,3330346283999610326],"proof":[[11362944488623568358,14321323659164885327,14769861324720909094,2273864781956942987],[17581069557383296241,8280362139485661281,6059938970471425519,2413765672219454825],[15172850002581237075,4007480753529100509,9994970668399738787,2618731030202893620],[2221585785030398036,10550150321083185441,6313923353761212888,3089672532832792294],[17955192206663394677,13682771751918836505,13572684429041180765,1819839124201662843],[13248143349288071894,7755576199645537547,503581653442734659,2283687638135454079],[7905410854775394028,8207723926404942478,7745566171735153328,2967590520489837012],[9731162891542664710,9115882563250478252,16506836542203721019,2620679213638050860],[16531563480308278538,2415206684488273664,7726928274633968361,2198698281715427113],[6681769119871912223,10714372967131915284,17046929091243664919,3278751980981841319],[5880536380205435091,8988109943768846168,8948683943614748747,1299484672283349041],[2096633613228542274,10247230832956913698,2582647671840881489,2337349213770688628],[694282249315834913,9131759307468547458,14859054783036377680,2556896920359897004]]},"fri_queries":[{"leaf_elements":[17448179620219742233,14907894638932304349,8152075974009371608,15452207072827673406,1887552926150902086,3375591415094970245,8355179878292433165,1006328114307204446,2060910564982400985,7937343839549568257,2330528159168748630,15575854274812294663,10834728577249479030,4129664799947145872,16250410176999245056,1334271651845186226],"proof":[[16006632195170523758,6031814007106143416,12766099896018082841,2235455319245190234],[2627061876928826620,7558242815528905287,9297991829398131661,1972949762957479292],[13053444695514198192,14959969886117666823,10973356735505849639,2669093997674898142],[7291541620870009742,9564559522487162719,7988701768424333498,2438979918018608234],[16215581870493295611,6981901017495999211,2411088552228350585,2339724453841161333],[14842540601198939926,14212332327556341966,9585353171459335345,1773011748439522014],[10067159748352494012,7283354477330642939,9796887370368421855,1420206223885988622],[7882092492228847321,4471930821896526360,6992058519468021938,1060754295174178583],[8711799995105057694,9584492765011979152,1662279205180426677,2721288857003446324],[3031335695723453993,6008477298464842454,10765433495181274712,2652030715416371027]]},{"leaf_elements":[1231632771672819545,8647645225602802115,6505641389952390315,8488095878835178397,9921832458845600027,7272157254971191398,16481763774383865736,7109060732964797969,4734528070654279650,6659267645825140762,11893976202563546575,7855816809633170471,12442853536837836513,3149635338181084106,1032366523092051375,13006031382762460192],"proof":[[7066477035558114234,8572854227660481911,11806511658222596578,43265015309209851],[13719258866141691610,9069607355396838243,3523167912845036938,1447834536367790179],[18259116392005291738,17914910057871241017,17991366593584456408,903812481976297612],[1236318463882885948,17900060928840192458,14524219386813794562,3104549702091529876],[14606953949117501867,5883776295085002593,2598488513080939241,2722239111241924332],[1308791687212800679,17439520654013078978,14966667291729064458,3407308016032870470],[9205275315130554131,12859436265214383430,10221394395219555044,1559039297082053848]]},{"leaf_elements":[9723188532656971829,1249184447740496879,15125384575301215451,4487429712898823799,5594325628639921147,9183613631676207984,6346356041473041189,9674444968242150801,8288418430817188356,643801183780068993,16343011503678450921,2340528375546138310,1889246346299928775,545642352382522353,6995236687576428003,11515050580050372673],"proof":[[5500961142336487041,9751250793586311554,775226974416726337,1953332802899312953],[5161885191070886748,17345126237564432542,4997730869086077647,2355282103243432075],[9375007685637847610,6537854564438990166,4361148130625555949,109028333873562308],[14642156447412971549,8753961440126326853,11783145797800391646,3176188692125511196]]},{"leaf_elements":[13231179435282412697,11067286733036426302,16464872316746670644,2959542249127229307,3656632155594300318,11512742211126633483,3641952820020161397,16524762161915820919,2866766436991766051,6121019872482128970,16957647701455810681,4800537360445888724,5549409295141574996,15845609310883329977,10819104344405081865,7529936042980408979],"proof":[[10164477711467631138,9942945204206605270,9118718961565509107,2739518935362102048]]},{"leaf_elements":[4501127538857023790,3168202938356671861,488429852234980958,10426529919460171421],"proof":[]}]},{"witness_query":{"leaf_elements":[18323484030534432371,1443841889208360459,3761990690188111433,16136866851823916284,5100663113579968440,13251398907985144110,3798599433797908505,4229596622638534196,8634642334638918445,3063236264164655452,18037284795093982870,4157694647778657888,17049941641587986973,8725922297699413085,13973345867842386294,8238565464305292514,1777563152996195925,2100300894680758404,3617484690192659750,14236680132795981907,10366268499416258796,2121549717373976850,9286745548122535852,16335050485911570202,2864900553339052140,7992381221778835884,14558032813621973189,14538855485597501575,17707598939744215639,5456511304712640120,6160962039817569592,15458576768511817378,6498363888440263582,875431751282704880,8981127095532687017,16675271955042566704,8826027871269297499,3389697969998375795,10495905109050930616,4126110047335666488,16555799747644865677,9441857115061216768,7852669440273983861,11022159418089648092,5860247917734866488,9537743004097560865,7211556068238256190,11615497447879057725,10166421030641480717,13332326584001424229,5897817578661815490,4743456394264907612,3423449377368646334,11583823050229840128,16812427111286277841,7557226121764056461,17368706353386910718,1522287501262381726,7248709678807278521,14358814805142124577,1097687452424285656,2087267305387315065,16849845059030686215,4179624600943224030,17709273729729467741,186016821774822371,17962947105053298632,3586297092431828193,9955551849237855258,5788598589286888743,17859330808159223290,3034094375537517945,15813471056230147221,12814744146161452060,10678623920862983790,13810100018350444066,3553444672216245372,13354530062179819862,5016097369186862049,7326641062587665258,15034183636753590748,4988821899249416109,10781389598341419876,8048994690260898148,17841784048036715714,1427649667669804476,10600611129515612549,6390033644704257459,2997106279508619006,10201389615228278988,9178381530192057921,10596672067659685275,2481474978503973758,18002754534098043014,2254408076618662702,11888966279901062588,13960768149770997094,18355957516941697313,3930112026668555785,12000550798998524753,7328493329769926291,15515526570757556802,649397367459172385,613748195726812827,6788913168937317719,14888189591074724877,16209029690883241234,5260180399498964072,7079049982676147007,17829202249508183897,7699715625978687901,8807983371983548059,1804803224760528843,3635415114476382088,2015905604767805344,18209816094662659702,13943080257138770858,3407964604981514135,337933180694800786,9304163064200126561,12942843725016449546,5343790965756122064,12871944312492523789,5674618142411392274,14169015412044923620,18153568383899349789,2333177398557171380,13995624192865920880,3640338388642267922,13559622365066353082,14273506014141871860],"proof":[[2491206631430241701,6439749856888493514,9963786596965626779,509711286808762048],[11429937226311692450,8430233198233212639,13435990789377303226,1230884057008166743],[15921820087496787662,74877410569287475,6045258402006979798,2588913826528731981],[5187279910860986996,8710605417237182324,4757504026344279584,2652756844064773116],[10673220036321479097,8372244401984639846,2022528930624666659,1852634574042662829],[16423014969113456641,17552692837361076432,7469408255939748041,2583045922627897005],[12405820383342720660,7764600441988237619,609837705467329440,1136119885811355305],[6434968310739783628,9127538386908464495,10407836532217591585,2353053664225470143],[15435286830679094625,17062255668594343075,2848770370087550394,3364452796251048273],[5893547256042664722,6028761409657483759,6592888294643335657,3197275473910754447],[2503665153956736773,17701251493816279618,14412658640691206573,26568670245358184],[6902291296385525908,6282427285539483573,1059247308760891000,1681441560494504270],[18265673367752908138,2754640070048023901,11724482278947537297,1725637765201767315]]},"stage_2_query":{"leaf_elements":[15015862435177866449,7236054672186885205,13745152809484059511,2413698356890659412,8872060594077140076,9956902294417052347,15273780179381419316,16034948209001538010,17899403068179267422,8585191457629942242,18242673787743941322,17170768719186846049,9577165461959417857,2980579989803011259],"proof":[[10551528138741913653,12481872029690152966,4185230973676683849,1972198617414624195],[9081276256773836966,11572212061764611943,1050511537098845308,1317576756904722317],[6470117461393679498,7664927281651619090,7145687203407232775,2087313415322359025],[9086082794461462864,8905818055877606423,9461281986727344949,765426391250000128],[8216024643048802303,16107686919068898745,2305755602499006435,2227922574132758503],[17077701023783486474,6739813048686032174,5314704255343384670,666208624331153033],[6728409593796422226,6470908201943483542,8521554913726535763,1371583044004857362],[15624687927112818628,7154091247040104256,10725049918323849061,269301152476186617],[2160682268525499383,3446638172960757059,7195497960834700385,580618829148160370],[7408864753338625279,17707040842568564519,9365359409953604244,1352079689472789329],[17653605708761678484,11128412812524188717,12517678524821206585,1816599886693073436],[13986678099248396499,763132589384391927,9776001136007254836,1152105376275273830],[11814671747401227134,14051467977723724755,11743029036639551575,3058315192689072958]]},"quotient_query":{"leaf_elements":[6575543290223723625,9696862086812971284,911399419694237735,13626444827345238039,7658098943045317065,17050223026091194880,3393539855348668420,12789755462635190892,13274832975814267998,11113131758347686626,10737015011619420579,15973371197526327193,14700629208964932687,2976393287473599802,5196296993063802611,13978618050945259876],"proof":[[3771329950971186405,16597118881545335275,4596979469805810908,1134468474308691894],[15056842692277642080,13409269192279961548,11898876952349686366,99544487317340066],[8747372415969467846,11417842962215468929,8474861445790833163,1694169576799852931],[13992389034605626632,14714189308495327093,2698974094651041087,2782043501347740372],[4245126246453321257,16955133961168447051,2972708368509267661,956787689084603412],[10162636162176732578,14576793817096887008,16178264886251165850,1844694136435219740],[694545856579672932,17311614921305412564,971823309868213721,215305728649349295],[5356772786556980451,10641661842742253933,9941350546198658148,2367860104687160927],[8244303796292594511,12239847792278851214,5776041679727841049,2676334164018737425],[8319558033497916956,15134643480958971268,7469846060563240007,1703987748567541111],[9849695436071501586,17953769056934829276,7695364021090451497,2314536690529951670],[1142141420400307793,11479452402825870557,17088604191880103896,762895272704649451],[3504417128630898722,13418354669506357867,4877712583074407316,51888638990079231]]},"setup_query":{"leaf_elements":[11984329116727726398,3525602127061214376,8236178664741976162,14721272715586335220,10075916755283455057,1915425955338524116,12126254853410173569,17909445733969268855,947575298944216012,8245473663367314695,7122774780519536144,12575419149100919108,16680416856591333692,10361178778337018701,7334726964326206808,3608243896987857258,1896866861716427321,5640502945513954129,18263446200406262359,2535336663540224110,5827333292383782711,7863742214564615414,14439327965831955798,14733886876011064132,8048310951123176387,1988439679555075407,292759294914187452,2687078246053840291,2282571943590183201,3655470899228466934,2764851595974602328,4256879524140773916,16654914562358511238,2381037154129757805,11881805518143993748,8071444688913543775,18122452906046860759,5391930136065260220,15726983480539380534,14535608930885217563,15218888525818058302,10269652431551494271,10256688975926424936,10062471587837641038,5602895040237444457,6788193766539062546,11175457758846976610,8906101500715247890,58259436302561613,17035258759703422504,3555965524225019559,13297348578173494068,14192358722163596617,14280050595993650803,18006441416656899332,13503717210977217532,4932735740815864280,8971123871185814380,9433356706774450525,15308640885518084148,5238765149775697422],"proof":[[10760769572583803163,13463458575378778023,8876267720869057351,2245398778255162769],[9946921523777413377,9241547953977227847,366319680732122661,2759420132097575001],[1398808648065059398,2676111957714358483,7262922684807110361,3471210893224654381],[18293230863739648949,368069484596562865,7818004055007771945,512788885246326906],[11552618598899198806,8055227613443430670,4932384470272708610,2031851054244426509],[18219872166309228181,18376230749282458304,16879536978096635092,1771736526688141413],[191320734384374181,9094267964388632465,8440874200618242164,1383021352463989878],[2673548215985444740,18216823874310659128,9395638245124015383,855252025823838114],[6505504850061707083,3793558263822328480,1347591894617603532,1065907620640625949],[7146374232138031804,1306294169116112805,17135063957859823267,829792535202030754],[15805847851050506814,15288827656103836746,17416016858118165468,538815875146189680],[14626434129209657568,3704788492558821904,11586933725645472561,2183731847757492550],[16340894896221363037,10515488107363041749,8989735385112029763,2859595575457666712]]},"fri_queries":[{"leaf_elements":[11618450351758492760,16496752045670771459,12728918608815423275,18172388212375880308,845988735730318973,6906448822536113949,13650961691807928075,8224559366408933093,8427396226408721535,9561453458371230473,14608207216378103893,15661182613153381749,15438024298238251884,5998842784437835747,4711700634786937049,6440755708883458745],"proof":[[16395757111033313665,6803346735283388955,17718087851589950117,1577575023821786943],[10661655105643418015,15793953160570581664,7638334239065336350,2298241982783124501],[2588986509143320628,12799443554610750347,7410373822102487044,1920421741008239040],[4587603480772927519,7971271078155834866,2207871477006940901,295895083255763505],[10839107141560016621,5489936144208069396,15714588142482128404,895767023833854356],[715769617315017120,1183286280270257861,5733843925469109241,2906646462715692182],[7264125311482092572,1168907455513158303,804368493162301880,3043434963273919225],[17408497355761376276,10474050774759595207,2528860048667436583,591482956912676393],[999846444995399222,14011138294935011139,6667964318074757587,867213260052525034],[13614949841622580336,9399492980024187335,15638599896098024049,1538027079629728594]]},{"leaf_elements":[4393801281606969512,17093484155532743392,11358030092308156969,14267994794617720006,17836505499152327092,165112743156092222,11550672207229857734,17475186469805737288,3403067954821470182,12744953731710480831,12033188466834240911,3343624580555701888,18424116280218841717,9953458067315072718,13074154007570251,17545583948356503265],"proof":[[6869620324539212234,5027315347979142714,8157964332028707093,1946184410786943867],[6416413444816683447,12121183298074822994,16393620040971977062,228627051611572306],[13031174565226892545,7970250805056519649,9000087678588837754,3216134566750001211],[12838049774185650428,16135150589157141450,4204846216889489667,2859255024845698733],[33017520307084737,13852741744782689541,2645621811239446512,1404818793102642158],[1389768311319449007,14236537471961652686,3349081074204103601,2876773415225488148],[16707445333894112763,15652176173117182806,12717696149262687733,373930509062837472]]},{"leaf_elements":[8974011178074889589,4650776972606361847,17024251066576812555,12387841572646439407,1874620816699592347,17174940154708249065,16631004948783231785,5291902380832776705,8272007247992656473,6502390224459270021,4475912663865115955,18386557505161871810,6235476761922802324,10862196983169983029,11259619626602767703,7703052365070986811],"proof":[[7831858875596105397,4589141293039518497,1168264694941022890,1274670217625191859],[10317506766812928600,17896568784559891618,7810646376359295632,549909588202549556],[2598732342918378786,5317963112505505860,8244752469313706919,950042062237983842],[1395445178162007610,11626158447455766250,18397044548169564307,2769656745606904775]]},{"leaf_elements":[9036089175381653959,2987875599192350377,7744707005118505168,5188089847094658525,13129935381927018420,3730150788540291038,8209729877721515470,17090538519922816154,9607968513778767361,15071132642506767584,7320125160743097689,4991892819851375059,10068909456476243812,14089867269071297833,15389351978943733972,3387928692605495898],"proof":[[12726638950376879646,639506612650757720,16912813671638057237,2919186756859426224]]},{"leaf_elements":[11506617648987991818,868082017674053972,6543021463611153452,11748771781491803820],"proof":[]}]},{"witness_query":{"leaf_elements":[1673999841898055553,17638106825674341075,16741106390371123968,11773779874332468034,18402410576819931899,12743041630059880998,11335229553295744877,3585381463503261739,4039886844343899500,17600153116538233563,1660730168095387220,6614018157153611350,2703229905986768170,9830294219769759634,8539655322962221731,12024346647171880880,3827044632292003162,17027154871207726002,16236569921652764062,8223757249353874336,16768198298420322722,3474946504872339522,5421395603019408296,14498784379604296361,2564450572405835055,55985611815570397,345557436799657946,15513074431640703399,11339447817381991345,12534375383446582225,2309688078107395715,14135871456655895410,1971113664116751131,18436324050269690564,13092880688427882089,13179801074765146089,2287305746730509210,7417172877060442865,12945244478544047524,18176104068377010393,18229926179828597046,1674119855049829813,17942139074302456113,7511238699556972469,1794270428215800791,8176965894621513675,18216055243760621333,12446092446058398827,9351034438017089000,12999924610972669895,5621401751953822876,13091863948709114990,8550147972945637270,783996871114620124,5302454802222921922,14602635477416735795,11246221419530257176,10342613683853670234,8210628908580739866,16245430279123629768,8457986242166127466,2079512749378870393,13251675954076759653,1882338146643122611,2490834110419196123,17869989816990807703,15586099258914951851,10546843703626612103,13651959934383141965,11137749762350603942,753851242836787765,12189780191030157697,17212222900364311922,14281974818450538846,1340283855523085457,2865777634276054814,9057305963490233133,17719717975512533490,332214921355298674,5573855377594453759,340813733961326668,741367710753485641,6548728066967590905,10272723965872534158,3415289011879536397,10872610719430735003,9793419727135373501,4006692755073213802,16719141097077325862,7718572436164588221,18250511615911903054,17035990649878445763,10623205816977437586,32167876533606885,6518460224372607712,17930788583797185730,13037023115396001605,2657621046670052888,17518994669729473860,8768145898397573554,12674142863829678292,7465841957763255117,1969709384186798663,11644786033029682849,14465380287771358536,10774864071221866725,9062630759664613019,17433698037048997982,2764874531550309859,8854057032944162933,5222744768651268175,11728670212932830704,6152848435084194889,9375961686550427212,10442388754584880879,14595901223466285483,9271292746845334680,15512810023822323290,72580635274748558,7622249267796766513,13246697430971346632,641987292546350474,6737532098906011319,17023329935941063635,12559580708917155671,2728253767997412296,12666565387831436664,14984757498754473839,6073315963322197818,9348250704996726251,4934680312835839220],"proof":[[994642129345447537,13247074620383922047,1855144803105224228,452819979034603778],[15654945722400381370,6212618764617231595,7264467779471719793,3359272359773357844],[14597792950341705856,3396515389155878973,13966393153697955703,2298738353040668515],[2307918998546280043,8766466053593090253,12707790380111049193,1228819674449916578],[6761086465278316798,7558695438239372220,9376512696186040317,1561194940126376676],[2538137208744740430,8185915294800942415,10706219965137051129,814288651793876798],[13585129352576906710,17618479777535529403,14716401666161114565,69536763096187087],[12233491235220066498,1755889837944056411,11655208198923090359,1500711183289173905],[14221658439044112259,762448881360649832,2787010955837564744,1018869735062517571],[8367770935239491722,14934840524337995061,6049257293628823872,2686886178563229828],[8182014679444923342,16445826551207987290,17013822517979645025,2656714516067615980],[6902291296385525908,6282427285539483573,1059247308760891000,1681441560494504270],[18265673367752908138,2754640070048023901,11724482278947537297,1725637765201767315]]},"stage_2_query":{"leaf_elements":[10283023376337143683,12705533759945197997,5694977031715361292,11190821004767595535,3399344076100338204,2716148054799928658,220577336473245719,14329430197991374778,2571668281544124597,590815850715858411,15272575037610373053,5013624108547110532,10839168765896602337,10784598846010973639],"proof":[[10992339331709547083,10601358133518438297,2791698456987770234,3397916111729693653],[14658426906460897717,15778444558232974518,9951784515703813830,237386032735080769],[3669495418148164554,5688207770109907884,16423639101254575325,1969466654158793235],[17863471966246355998,3673779170304918232,10366907437651452978,938506200218962698],[14915185722177361740,7352023276568981516,13742052162251712714,1074998853023916341],[9457003122570331988,9585223806654670553,5448680548190548820,1632707320798310341],[1090567050336204825,9372272214417532983,2162326061837574125,3010016222153994353],[4715538192299805040,5095497997188624027,14565497629219154691,1264794050787370511],[5921971944030605848,3593389454435556703,13112557240469878879,648227603904898807],[11576267748288634783,13630763058169160547,13260968374448577116,1460791085025866525],[6442970993011095046,16767343503915309638,15639864749420030818,378850544348321779],[13986678099248396499,763132589384391927,9776001136007254836,1152105376275273830],[11814671747401227134,14051467977723724755,11743029036639551575,3058315192689072958]]},"quotient_query":{"leaf_elements":[10512621980104235262,8435703583502859202,10858103888846957553,6011497498658063322,4472174904245697184,5905688520078768926,17319228555039012986,6207852663619591104,4423509557721130005,17410445283747723110,4800202087340434730,1800844311541255461,12332803112535006368,13618031002662131844,9665654754790828797,8779380044801247291],"proof":[[15186330239496636460,2108900877762499779,15163637176558042660,820659051709167840],[5799396111098804306,8838067296961941224,10812868997167877539,815939015517077892],[9847902807060326168,6705256935847544348,13759231077139469331,851899544917275821],[8025746522163489685,16359457046706917910,15443006042441987662,2420474923689716586],[18301532542152869149,12508295815641263332,1781573700580887777,567942160173604181],[5520106685886033898,14673842534293221994,9538464368878440230,473216129635313991],[13351416993527604214,7482955679942643607,10695373177926367166,2946565277854393029],[12836954216008233357,9357141381859569237,16184481083015648306,502460173866315974],[3386004484297168722,8674862339098314139,121361755044784071,1353486284509059934],[350337081150661349,1804101878965605005,15708859276316451547,1233673632858823985],[11218010515171313392,101745210632366747,17231656761344841354,3308126040096115441],[1142141420400307793,11479452402825870557,17088604191880103896,762895272704649451],[3504417128630898722,13418354669506357867,4877712583074407316,51888638990079231]]},"setup_query":{"leaf_elements":[2981592272433663023,12537334829522730537,1477650697900919827,2793622487536268425,2719442546768176053,16324688099886977811,17807300137853362173,4324978132549177890,16313086807878533560,12502765477712632749,352104463808278188,17055150438942116464,18344269684113876126,17083305411822799895,13188200014246396856,15438092879760438471,10210965019102000928,698592784761375753,11887621798742015372,12099890375709003397,12734537342384422796,15263280865060140085,5163700307139316362,16959120350528557015,2752628650319328024,3853696994926555983,12563019307895920577,3008062852743130824,174996483603192676,2374941042847599898,7404181078060385531,2549199184982545685,16044616918871897474,4164341168301830415,2036381581104922690,10511302384899612069,8420655495184093342,3239066967476534184,15643138730482545988,4359460908621771982,14587397737405500529,13176469678945873160,11472490594510369457,14761261241859791796,885990365628672963,10935876113878862931,10123378815299304608,14969253649046201413,939707495856043467,11161263949339396880,3785597984303868460,4504384204345989982,4954749785789888971,5393596864045690276,15046059614845676482,12844889891961784270,789087576624265731,7609572366401447565,13126648686008712213,16562412888600066157,11755436777217062533],"proof":[[8038825072662381353,6187547635126184730,8402053370106306203,838921634809667022],[3051461207815636685,583794667968021712,13252180833238504224,1435732635812056938],[2691288436927375153,15468566996351416493,8521895857218293627,3081669783237924339],[14076513256865902224,6047958817653733482,3907371970916224520,239641683254944124],[18209014420872915847,8587891556341194125,8645071360622107346,2388824814343735839],[709544962120373074,8731802287566750371,5649625170422791952,3363738074523265405],[3080564299174261032,16514114779974028679,8751220153329065739,828484833748328554],[6415321779162534232,242527757341009026,14355444057170073034,996739174996362201],[5064425324835907456,5930033852987696853,17383720248245519481,1255769046906380947],[16582624059087115004,6533605639799687583,10611059763982337273,1103360479940055008],[12936042570630472179,1310901294642854077,1974545396587028508,9396074164269318],[14626434129209657568,3704788492558821904,11586933725645472561,2183731847757492550],[16340894896221363037,10515488107363041749,8989735385112029763,2859595575457666712]]},"fri_queries":[{"leaf_elements":[15751898482947997321,10535835384755922684,1870915255354502230,8464095644627542276,16492815536752608992,15368322031879659683,13367732309445143445,17372197282918220949,9545810278507143051,6247878856164551131,4172549407773294410,8789302252124233750,6956453440279495641,7820974212049675424,3634565757153313429,1653747191550196476],"proof":[[17588823208488248902,16179895503687996239,13267946297614299283,175124489663869439],[8149284721021092431,4224282758107966624,427232216529095102,2690832374698178764],[7305364217194775276,7115840437243030006,11687419769936775652,2735039893117164307],[10858299353676109330,17182395097602943268,10359912302455115689,684867286249957837],[17289129682871609812,15935175586895626902,6580358140364301695,1870073076974865174],[11581985293524803789,5586244327441109282,9845055446534373733,2808818952088135136],[10143406709683650846,5633102100517303154,16469905000866411973,3406208476561652837],[10992314003799372557,17322716724534720083,15751576483304408144,1646111252671489369],[999846444995399222,14011138294935011139,6667964318074757587,867213260052525034],[13614949841622580336,9399492980024187335,15638599896098024049,1538027079629728594]]},{"leaf_elements":[15211795555875824610,7686336886199877019,16188248831084614495,11577747871536205062,717461600408997871,745613224677849039,4385485571593518306,10471031499875538044,12590367497468418652,12424699711871506526,18339274072014688,3042926086385234256,1431599270132773031,8686150398931362103,15336000343573095214,9682967388243216128],"proof":[[16442133382654394375,5420960782199519234,7378196893060848286,454397241461108396],[12256897324078302930,11893788765113874436,11294726316794671593,3300190215745527981],[11714382967511432515,13111606129023719458,10146414367791426319,508754940768771771],[884891247444970202,15023348828192863351,13299490720264045378,3185511240007856787],[14619780283819901678,12281755326726147473,319442712941351599,1558941547028822906],[1389768311319449007,14236537471961652686,3349081074204103601,2876773415225488148],[16707445333894112763,15652176173117182806,12717696149262687733,373930509062837472]]},{"leaf_elements":[10405193026471630820,5886540868220838862,12086339467788396575,18248244981775048121,15406279546541688106,8999151717228010559,978855660854391250,5806990496462608292,6234062989392770953,17342543145608919633,17879795720207709209,11123144005392420035,2305376481223293599,11256653510216225542,1552102940643429061,633285129771981570],"proof":[[14074479351977345807,10299250498137380971,1764447232380109409,230880189175204442],[9638837243345328524,3548442352561019961,7552415862605738816,2591611983958661810],[2598732342918378786,5317963112505505860,8244752469313706919,950042062237983842],[1395445178162007610,11626158447455766250,18397044548169564307,2769656745606904775]]},{"leaf_elements":[9036089175381653959,2987875599192350377,7744707005118505168,5188089847094658525,13129935381927018420,3730150788540291038,8209729877721515470,17090538519922816154,9607968513778767361,15071132642506767584,7320125160743097689,4991892819851375059,10068909456476243812,14089867269071297833,15389351978943733972,3387928692605495898],"proof":[[12726638950376879646,639506612650757720,16912813671638057237,2919186756859426224]]},{"leaf_elements":[11506617648987991818,868082017674053972,6543021463611153452,11748771781491803820],"proof":[]}]},{"witness_query":{"leaf_elements":[1014236306183794531,11722232148010281751,78310693832623439,3063610861999409473,1759393649197833974,7950810367840620499,17045214784646733291,7381020266092353058,14167859113719272075,3162127260079272597,4131938786090489557,15460414378789001934,586966744398647878,3580207531265497487,16571008311201685543,2219880355313731573,12207786544964173627,16368528346982075203,16092642209798101782,9140961250431011023,3199456332941613226,12185936508773365625,13209630683631398064,2256722394839878851,4164454658048973172,5332204459535525907,16445838238177962616,11910208627280953226,8905357949291285107,5666083168955448337,17386496520700243462,15043646628138582302,908528423622671134,7132467932889236715,6369789875413778951,17124260827524153868,7775901803401327724,550165758941845395,13771954189694815804,129410219717456781,4634651760025305060,12191520746647350859,18180150957411464894,12114724217068448611,11169639892872986440,4451068564969153789,9734457678122878559,6576132782207037525,6187235114758298147,15832300504158833254,15763615783065608049,10560271139401490700,1853630276460176150,18380881285472870344,8487569643884649912,319285942870291514,8961212771267485647,1211535043777622065,13894622396613253463,17925598727950596766,2801511327091743517,7893075062958297586,12478341616778224130,14675819002932999068,6752786154241618004,17933721277235458111,11729916442318857900,11794653181256849195,11212336651549931514,720073370336699890,14360368720416818086,7781010976573037227,10799665365054708754,11133936229564609082,2652322370025061725,3217203312659237769,9497769898729788915,10221874288594661858,17494588358430730655,7365626539232399639,12542551440164452003,15018799669534747944,14171787542054486692,16918149609088451157,5446387646883333722,11561008287803818216,14069669415659700210,4125739265391274342,7356912376410472769,5234956245901609264,12877187484791815049,1397731647470960294,178167595066796918,3795761146807276884,13926470882454997067,14531625465023330614,8608400780113088530,6601121903355675873,17077755163401988379,15638204271329442290,6445417236606198236,15455185626767590638,2381624982724695984,15972175955559789423,10832352321157493160,5953819948488918880,5245353445518592056,6138506873086304234,3810644177486211023,1911399783276108033,7697019428801973013,17376208396199555953,5211770013010043296,3174460210115303793,15159583447469192760,16705167391261970666,11568565458644506869,1277251217051530474,4756465443523991808,13631743026648032058,12006142061830765716,2149526900636751147,4475419075678143461,10187001502495626909,6910392969443962950,12520361302647292181,11449616721694777736,113423476676878921,16706145363988030226,11185058556759324429,6362844083301575678],"proof":[[4105330457805877167,8661860735077442984,1694507372862418282,2068886205508378129],[1812421815956379263,14322857626568330219,15914592269403452965,3407714766553085384],[15794225478527258501,16316231456518203158,17068908377651963963,3437765531395631605],[11320063284412414793,10795950415420379651,14357531090145560726,1572643928538292027],[1724262061167981301,18395978620843081592,6926617018299024311,2025739480882432704],[11004163675013153175,2158745370118529561,4899658848177192793,398135980201627651],[1843932380707994034,14766995473930393187,4780162934772191718,938826889575900176],[8353183975324405215,8219953705248408773,2319868468802291638,1867166280804803946],[13842078074068891798,11728423679238619812,11617025057845446240,1175616638710694607],[3674941681588722122,6937921218178197784,13667803740483330581,1805841077523833169],[10234923790260917492,16134544500046937010,6192536968478693055,2212199653872390577],[13956835885681269420,13977950138640785752,4863109640880899263,1937558364909967234],[10170411153944345348,15189428256572144992,12959700760463722718,3298790997504217383]]},"stage_2_query":{"leaf_elements":[4451992554040236219,14393514623624514476,7912556870234530930,4885802445912018098,15508786137181970067,16186385778678699812,15270952766609088365,6254535672812004565,12347832889752360236,2151085012617232637,1140108815942419298,1588908604128974254,3431998572287478651,3762489600722648848],"proof":[[13713896800199055882,9199530771703662623,896256663813590245,1005163530462412878],[2581151726896374593,14243788122034385790,3481603817348868534,579063516611630230],[3983350341089584785,6387169439075513836,12709419541294674245,3222093875296723614],[6448620137011686118,7443565194325313675,12361614284260913655,149563936564275405],[6149917216630650136,13428667959869759565,12722506626749982594,2471752316404257892],[10727037973542055447,8898181904702561031,2862276124513917382,1601201210938391197],[16139661339294992654,56040760734154540,7302275204196392082,2921392281900500523],[13914576835634164252,12171001295905527340,16231413945701879497,962166326444826459],[1723380146632626202,5295772956098083202,8318949327926379548,1367575739976870325],[15912240789430353319,2019066378173379809,1544743854581528804,527392455536907916],[13661234358441554655,5867380597679935196,16965064547634284256,1150271417876686726],[1101391570155270103,18030471955809926170,586352199699272119,1793679619803222441],[5944104811179779230,4705743378997469566,17252932908060409042,1116220520959491408]]},"quotient_query":{"leaf_elements":[6628507301279270269,16925087091697199467,16810442273668655567,9231544903713117169,13475677407978800327,13359360541802868699,3650918797498454883,291236409176748151,9331847147916138631,17225611402649617074,4182512696959126486,9264107375145259075,13817734816050391760,2892580557231210283,15921984144629369353,16260540986493513025],"proof":[[12910086181234652701,7037720533626248181,2314337105921626679,2604331666693464613],[2294649119555254764,16879645760412006440,4761050945415560106,2551489961930032246],[6845512002696591397,17375811070105492789,10108663704160500602,3248751496430251269],[3579669521127707016,17699765105858047127,5007357626416593321,1995258997054685212],[10187041404372064173,6526284829672281090,17431229025654108007,2124344148508485791],[5571566021422259323,14554172359832945661,7519993789310640603,34168347929090935],[13955897752505489071,17932721863784216900,1331959669305944831,2331489466772027738],[12530942231862598849,7007791965226478467,1523914301321699298,573601272525677822],[9323175249091540706,2641812429743234302,3701799595368381763,2061157132841749138],[11075825838577538280,15269034606084684571,8177132772191193834,670588787730383802],[8496151696296612573,7688097926724613118,15913285176425636566,260204469448824341],[17805648031392826486,2073215923224479568,7861966061060194600,1640385227104014486],[101117472389605186,17621311294920231862,9537129816252271277,264251130147554038]]},"setup_query":{"leaf_elements":[13806852647938292073,3850197098712946311,12580348127355581769,3980795266230776576,8760344364810947566,8822115905069875578,7733147435833210346,13182643917518013816,418050428405817339,12109662220597600525,10215423599957339848,5867419912629566970,5080837594911436911,16857064522578338452,2950619280713894167,7039018304025308212,15630297900529601979,15081204953944271581,6904922288890043268,11735449736320949767,17004147621230035992,3454974011954530621,7752305290179428661,9941055702958834976,18405477065607670161,17016408098195049877,6120284935893203994,12424464026246546419,11944436243083176635,7542723843177680340,15692445949603125981,16181269258762412120,13320753587393602265,16327693563659857957,11531954833901240484,12009838866004208347,3897148483246125125,5025880776148627857,959058162596298162,4845649050911767411,4177640971352692030,15446505660612674120,3956248292775628978,6549838901728037390,6693014392877428126,9075441062124052764,11419417230363842545,12145994242975885146,16732804727242846582,17284313352934093544,1076732048397735319,6930596991884085285,10769947033262955677,12471537116860575696,7514707720134952221,9046820147639271346,17080946700987697661,18182935640771918036,9154251571469353246,6684615187934703356,4164934028323647792],"proof":[[5332926073350814933,15276425721794067529,4155104185386358040,2279851439836915148],[17663970448630713734,942018067762034228,3198537011923468710,2755891609481114197],[6245404510751848121,14814322286368714163,12728414592534527862,2678539642542941636],[2875325751986187395,13119502457603823136,17149364067385865505,1623069002847919173],[9946008654496129420,16851727187409380380,8341922892728165916,1084878227602381885],[11761191962947607269,6533837475819176307,4433398193493725829,853476605821766166],[1797949597565572493,2477935105895000092,1715282977639636650,3302510774716100013],[11791140918838458737,6662526188784055125,17644529841219172303,3272909068853552475],[11360441399470316396,18433116269067948365,16544416248378954687,2809765658898487327],[8942511314576486062,3366580451246874736,14019961639623483145,2762490972839929808],[11810134053350416824,10070209752185561947,8072463214693336303,2312904188598789158],[10516063788198811860,11521768273658753976,375854070151956021,797548007667768901],[14721891719636996984,2949626462121883205,514398815710631466,2655190417159851675]]},"fri_queries":[{"leaf_elements":[2581447613514187903,372991530003623485,7837295797242363662,3891139360446921492,125247045406594894,17802070102661507035,1660703770742321976,3562925954083375102,17519311659401174455,5025035819052301273,9742455978746405772,14208889919885684236,5724813833665554162,17247851783302811917,8242335593834104819,13731332059191658282],"proof":[[8431572270809329440,2787846907535991285,16066792323433691287,138392929090575933],[12464203624175145183,5453309806462812257,8866692699696854384,3276231986450739986],[3134788416315170225,2547181856703798498,5080493699790292905,2127925841483180251],[2985392267537936500,16189811418496954821,14502617257202684588,884077810491495871],[2699895821806547946,310683302551631208,16026911394802734274,156788958977309793],[16935918147383267765,5605823580976041552,2962457246333809419,94916388846337672],[10736355005622851010,3031619636902531771,1793695099067853058,981445591399336857],[10250052735318230891,6305188096615566818,586180840856926658,1526313768161694323],[4999245903498690337,7298483859315852371,4711531156947246730,2388582959435649154],[5939124624586656117,8797311108778415437,8676485774919245055,1516009211411584182]]},{"leaf_elements":[9565829223576005284,2402084630815670231,5009181202833601428,15787558062930867380,9949819279315888367,1439443803679160234,10635045483150905740,939965641122059388,7054186668436638314,587932034541328832,14179109635291100065,16295154496982538025,1905657491327759262,13832567334012086103,1119179836396341144,8753547532092083508],"proof":[[2724622308316775943,3615790792071675127,141502793557855399,1538664784546777206],[18389952253664284516,13202332873228672103,6552880628019002520,1059631278288600810],[15100678417298115657,13874457186338398366,5512221613796313649,1315939574401156902],[2961037991650073004,12666891277499382629,1975850522687116715,505872547424588588],[1734663038235488200,12685525245348471603,2277070921607347413,2188248763925447369],[2767861238377875692,15785855316693498676,3744809610891684183,1567103551091653836],[4226831722111814395,6655831638141719359,18416793863196828265,2754055803328667659]]},{"leaf_elements":[13570227015988781841,7500101531777997892,8816433464733455109,8926772539064423180,9407403089687576453,801580812786153217,8836080678669536896,8405862057419486435,12522178852416395016,677201243902160192,5727416636598576800,14937014929751650934,2044623445036613771,13293268024941559633,4755317015488554456,11015753646241206069],"proof":[[13021967017824567280,6005782593242202559,9476063942390244347,1109097222503110018],[2571638911745539105,5939010277878936557,1517675223986912336,952587486881256034],[12210735443468912945,4228653015746222779,6294461639017255781,2485205723841483832],[10512165384836540950,12576725843624026847,9749163590345599686,3286629949348704569]]},{"leaf_elements":[13790855340402993368,7414387734080379513,12975407704994933495,11495992525856327121,922490172660792407,2216591724534083829,5681419279857519838,10808937684894799099,15699585052605113537,28254719198542013,12781572970255467545,7196566718999339916,8152988491243675749,16434549783931242612,15461814104182559509,9183595432750050028],"proof":[[14777760533211147947,4160079023517810966,16181012839474086048,2965431587160692161]]},{"leaf_elements":[16775312693976535021,11906390845590027506,16723574221087713398,13884781623836882318],"proof":[]}]},{"witness_query":{"leaf_elements":[7575258112001263694,2032155964294418382,7850506679167559948,10635400839007345247,5214238519103138406,14491747753822002453,14895681397620735770,2352101675595121791,6215679948024032257,17228362892129711274,5989317771923612731,12032455597997289368,657935033133158633,4911703843121397658,12206376080052288863,8718344390980712405,13361856824842598728,16643863179036035406,11269353697073418449,13440176340714173388,18089230242493080549,6931627570965716782,11586138418233110696,11408811450357238785,14527581803568504297,4205576783326279668,15395623133187838775,6366169393591937039,5990792643120236067,1684157578784618299,4687968112350958128,77346295726324428,2284281376857213184,4551510056672594793,9098334160738084421,79475872030333429,9446989837687402956,12310028648310806539,4381125304217830211,17352759041967692587,13232988248067996157,10670386187582083462,7218138127446983686,9153135827407969169,10982709027366291901,5731848439680239267,8840001107303388007,16596936866914077120,11905916704844609762,13813964001323815483,11691227662540900179,16135915574465575252,17545368347080345598,1923858920926290369,12105461963532793206,15593061694742960224,2267834151102628612,10853008761604927616,3264699937584794481,13006249518810349992,18235484991913245162,5750514914757284259,10713073813127908788,194877683372708035,16882176354657764373,6867244255465519357,14197025722178022685,4111839130586148485,495618086642669136,17218947525565386857,12848934895627477481,4524697077186085688,4656363683892348824,6965264358750390576,9170051976403832489,8195714207284400539,2872040637002035647,10001574473639736325,8743743587064034164,8173459467311735396,14298284443169023911,10712247432990491148,15400335936931881344,8333863308082456364,8772482082018399468,10508711238654175005,6954048273171494726,11936056877710615826,7618090340580379454,4835451119781358088,2485030930605223255,14913113880611484830,5317268447209854388,8527490659513110522,8333247243975246643,11742685909206951745,12282204873528686936,12894429617232550395,5524202359465289685,17938257147390322034,8283611475946275875,16640165956963948617,4004869966905269006,16686446232041567417,15119858085408664737,8942033491777828309,9463665518487565547,13783919027707738511,1957690563012544068,2999926330270437845,8122778598272918158,12361560124950819778,11103566828284095395,10580182933236814254,11874872351791434208,13058253826993246774,1684669227978194707,14983162758027088012,18345867098564900822,1596648035125102130,3149620406008445588,850413769785097915,14762664079274984641,1404013547863693921,5032321715649963800,11428438732576397322,1119351321536250429,7152430614346557414,16666845494692284841,267911634400460887,6842319151413804475],"proof":[[1293664567417280483,7836052416048413846,10489456053175469093,512960460041201],[6601098285063281558,11299096608530431033,12048343739016169280,714274186477491664],[2850177517139861357,15513879188463970206,8005782384157981797,1461266919290931311],[10719643219788820631,8506291482423908816,10410409205440569941,3078017185771051113],[17761748236398182707,4602476119881120416,9847684687688429998,386775346968977524],[6318638196685327188,9163904569175667847,1082576196350562271,915390251441059147],[3809181280763867337,12928943518373820253,15658128791946409742,895527974608023400],[4954263810776164163,10819509517929361772,7765276679475398381,1152988136514250551],[14128131184682063564,17038647130882398183,5113370982135933145,389612843791730124],[753673864850351312,18285912084953762099,13991842817579917537,730362296255621576],[10281909401223401895,2070502197082610462,14063637489139317945,1989185112808296337],[10874733966612544815,11074322858128802893,15990487178892717943,422650260095906956],[13357217182822843111,7246194359117680782,3300747307565431259,2805875995488588298]]},"stage_2_query":{"leaf_elements":[163244224205184638,6358718821321069833,6454190079678776980,6643892050472016397,11077153157111660324,3061039715440801814,3003500196766727506,2862780956760046383,14073830466331453821,16390053590507589984,13229396279530869799,17488977524285669328,5409853139199653378,2345040911593432986],"proof":[[4663734823917175253,5740335868787896371,11608368132291189564,51768239260955988],[4945733670710034180,10184447523882445576,9089731130341480166,300629457437599072],[12190407640764072227,3485611353298104895,11868006421651061866,229217477115119305],[16821067826163596058,14703944855925758053,8027870689607433044,1057694371161887322],[9568559354103513983,5144780446958837790,10188443492283029003,2406129589048043624],[5504272619373691723,9277235066315922862,17669161899109033228,2085614405205969661],[17102872514572312788,17624270925937499173,315300282632125347,3228835692927146296],[10718338512307719716,6068167039553028696,779487085933209099,2340753407372370785],[11902699160811830426,18327681521643124145,17275103317857452080,3372329086531058894],[4465962908280699299,17471826660734265559,16574876815416595445,3392565735226076716],[5668524759224651997,13442498307830437777,221002646873657042,231224762545497637],[3303406567477199964,7479037777574876150,3019416846549640606,2942376232877342398],[11783375733003255209,4043511936331649179,4043506204996727333,2003392045411938067]]},"quotient_query":{"leaf_elements":[8684736242403444364,7264039534805582978,741866220812128578,5143921588974934732,16834206412835353510,7906596973339944052,3436072851655673669,10743452798444769256,17301319675786765309,11777406054269609944,9203270213620342951,513845577597136498,11763845570908526333,1556678626882671698,6422168641807831994,10258091458200986433],"proof":[[17548002818061699513,3399976766035118937,11247161945789931917,2558022879896302885],[13005509625250513893,17101044320513353123,8553377545185336015,2535061843576286677],[16358474599566882536,9164075091971046731,10610828692607689296,2220208223604944700],[2365982252967093894,17846221850477931132,7925959390771266602,130754719914539698],[4662236037352833384,3042031450371495663,4185340428592342296,3280442073649566578],[6875280442445593270,8214254156287221233,14187199811233962534,1787481446475924016],[1076208214074139215,751477142498047883,10975037063710256907,2590735310509032486],[7382999284533102261,7689609186077839308,15010831791221561013,288935587987872583],[3333677992277781411,9642335684641656798,8121960486661830191,684744823763407222],[7698206421856067206,2363537360847709554,14239132750771751828,3286062784046658874],[4931499726098007716,12179671426218568034,11768395262272745015,352215414081702512],[2018525985558619984,137740710537253784,5618217583512308755,336693333814475874],[10071724685433138712,9277584171601855694,12421698781990076583,3392383529760788958]]},"setup_query":{"leaf_elements":[3133876703407586261,7153131264938803077,18379758243068865265,14150179831596174955,16035748686548881771,18393431200159964464,5951452962718186659,9698120537979355996,17877564449550619965,18399527824173098279,6835094825672425347,654656559679393733,1245795752617248364,963940306407997801,10613741517548369985,1428127578410045795,1954851299627043099,45331677403117425,13121989285737190903,4768299901087598037,3207899520500969078,13053749002910634398,16397069972584914597,9462892707689156062,13543499929822187920,1510256252832980239,17803945517958250008,16401462291070603937,17508420804963641866,1241969236454662757,2680603950466884814,16440913197777284632,4080723406633718584,5324205714248909369,2589225535363343745,5681008979749402513,14593598223147323150,17960070696550546111,5117960358512707181,11759693368414991942,8555188268600421892,3780572155422393301,15409163114567930683,17576465048962713121,3912982178122800384,16391943477845232154,1212930144985168490,16893819753171137508,9472680024795996868,5299462603040681765,3573383513911228071,2736722755720792367,3750108718234292614,13828769227425638491,10003603536746893687,9659500627999075340,17212274380115649063,1732454110416931664,7276957644278201861,14833439581409449946,13851071936480064549],"proof":[[5470304567165822535,6279637092201365906,13497029437126635812,2217204523793994589],[11329695683520257713,3079531128587286421,17234036141440452618,2450056068195111776],[5374087257919079921,18201737285357224427,10627723653982002636,3022212624635407912],[4127258002360356884,14667492175961870644,15640144375485431329,1995146124681155296],[13702839469404195535,8478621022597458485,9486256025983059533,909621569271402358],[4604977738290241412,14449616149101024076,15192580987397938522,2762286569942065018],[15952891843735141036,17041607763792713974,3486182989688276784,1574441862206874961],[2911318080300122901,16379967033804939624,8412930171638566589,1752019606172858501],[1209315724274643424,7002028690802374033,786771805449542367,1012308167974602153],[7710284734390133113,401744782823616302,15517334503689051107,3467819463180258302],[12845171450782834097,16516701653703550800,17286203523315526075,1374126044974334182],[10329734661477968365,4064135762975347579,6654916537517027331,2394750824071546707],[10215260393543767826,9751391172593344006,13862000312171403022,2102188527394459267]]},"fri_queries":[{"leaf_elements":[3373129299353353613,8152651317319037605,14322419619590182739,9481924114739997054,1174546412836127914,12465186084875487569,2490476683812511423,10701161355094375752,9185734516529307535,361630560838082607,2489183397124549110,9456638722243581054,8349817582173527250,4486138743153464924,12837038475019375634,8999133513450994431],"proof":[[7311982797387123133,4384234598000063015,3358278479944228118,603096532023215460],[17673299412068330274,10061005039250323904,16684999460099295281,2643755578941603400],[15492185054258246840,1397162963124213796,2460457124552731934,2161809742120942297],[1566428728072022945,2336941224391288014,16527327263358518692,979146100197901568],[2995823495733025283,6315338391499132025,11256234897507476889,1776118734247302141],[8533722328174273629,17955996264472142890,10876076587920121813,3366326122119469163],[15565234372276045753,10465082644416569857,5637806947175181735,2440887847756508763],[6376988885146620858,3914798314551517449,388209520764766714,3188762563956201938],[18194363797141198225,13411380482853529261,2095444994617149265,546801543464856746],[2727149282747321928,10891637232743280698,12913837565521066440,2576402083512426196]]},{"leaf_elements":[18174205741534775684,2872134835879876927,7795103723620280210,11355252863274976339,5097368694115425002,14006533225631523984,18341041523216694950,13721293343256069430,17628833196806521542,17118835017436114587,3185361996874232746,9803660964557025642,13652947077344205817,5803177989110120060,14368672610073105271,16584969461693812091],"proof":[[13402685162126347460,12395901871074968060,4099508644572886221,1621995152241741278],[16216544291669668653,9384883659878197746,5569568297091209217,763613714246732786],[6366101985058378743,584957485891872052,9370861807502874524,40786101993869548],[1896282822361108808,1250518196534309078,16036811784594702557,454217061669488764],[10728114299657712453,18050441078361654031,12472202118036179265,1748993432868781092],[17041208096320356554,7281327104126928444,8044257227016946160,296150336911917259],[3303603528948845539,3326255857540982732,3658681733470339555,1510526829171137553]]},{"leaf_elements":[9353296407067736873,12339955703703802678,18308768365098910339,9592316408774967328,5279833538446919094,16975781902354066617,15508622789552576242,15486850938367880301,15451829334875969352,1109011454527717972,13248870103710506637,17878606534257307799,3879580278837850085,5686108971143545207,12152169798697937952,15704936948656035552],"proof":[[16858314298679778665,11895273310902026704,14309628391379020858,3188967685264475927],[5302789301758403260,5221822417837137701,16048182677007640033,82924544860355382],[715015993235620286,15427062556929528446,14659021595870489039,3193097602166837712],[2675790080703259223,11672018712848555413,17368983387124538362,719346710673973172]]},{"leaf_elements":[2269900810174600336,5098110879737557033,8299216941866001348,3515417207436792722,12478804426321499801,343038200534073827,15203631289634068494,12313336925559358131,6203791195205671288,13398748586504670354,8935303490405486729,2665264765541986722,17919352332936791133,2982639848891027123,11502625188948097420,16989819816840410281],"proof":[[6212898492623545222,5273054318572493999,18120166942467567840,1600672264499078704]]},{"leaf_elements":[4501127538857023790,3168202938356671861,488429852234980958,10426529919460171421],"proof":[]}]},{"witness_query":{"leaf_elements":[11967188028393365957,9494399638041091979,9988833136245584684,2417878530111103804,3700727836422065667,16094193674833035404,4351960292036422097,723351253596449840,11647510336651714390,2923027309568061483,5680900856783889711,5147374339173526795,15912102451955757873,10681301234606057652,18364387399340944674,14487630547522737353,11992904869770560742,12914598231727235704,4724589894023542308,16199945717194279112,17141966192870429924,5604305578219633273,5044517739948165807,14123288616508409730,14486164563972304314,2140091343200877434,14545019462724586528,15069366325077592110,15462790580020094078,3336021427547020035,18383616997382963120,13692132575420995626,588129640397487381,18393532085493324984,12029890587390067485,6903564232619104534,13825324371614622384,18239406628836399723,4814895965341800298,16320083190515979186,7233078866208110624,16599378586380954259,16269038554872088348,600215203402189133,7981420556870875204,984154788558268813,7410729362521342065,11550705632589357915,14471013159965735170,17555342855167229590,9807476957278590092,14348039346217996928,2313599616165075145,13267286044390588939,16477453090389613370,10789325396873307887,7613651833169332382,17336715205931138101,11942738238430295098,11476336440232262008,8237824669397012702,1167200375530694383,3016620200167318500,8108482759642493787,770829806697888177,15028589396826397168,10894408467851404136,16308163910703453886,12406679374993514857,15281920751036090006,869393460702951686,11440530801613891751,16827380049819834191,17846688918139471706,3806989661467478705,15326738704710789606,9677256294669147386,7787374839078001125,12264859082927366152,4048212225451659436,3441214201727348709,12402890568886828231,5378898918702043546,14617010975044942104,6866724532713205676,1934413238296038438,10076544654493307373,4027230456736264851,320881575613879692,6349251576806741498,6943371657250028226,12677999792288089267,2709124886379837449,7538183113084870730,8775100965500486766,15251293327420936753,1326355519482008681,6912466300791314804,16375577325964656527,14023219810818741861,4326289412186732997,4334305796173630544,7148854381986540116,16163195697332423454,3923752033372400561,12110204262190477642,4533130334054399081,14400049960386438080,13773437819958040414,2633492718930121452,931113995867384993,6032364260843108399,13651047410974277983,17471158810945735082,236801249408502418,7447046671163130630,9785331310340821332,2039801384415370347,8053742188839186855,8988753975653060619,61157963855090694,5713355397696681808,2148332723172894478,17985717959562552742,13169233434297412020,8122322381071488776,15030223944254915131,10372841363718406913,11205691539532907664,3628243300122499265,7924113586867123123],"proof":[[9419630200857818205,4965462189067290766,4096251613555998380,110823535285948645],[14029764900784458016,10531269517360045151,3252632337445829054,794247683956073214],[10483988646940901199,4742207567291565717,7063238412655891814,960906904285179375],[7645491904229142172,5343220325471933628,12494562354055790250,3249535889629670415],[11377246993993640866,7513707666171584653,9131541854539934035,2780010046423317892],[7817111085703133807,4157225026230955516,7477787541036819346,3431994925226470645],[2826856241167462680,4554351942800660423,17948598524510533237,2433631439143257143],[15469547473165150655,5454106272042960182,17630825954262347990,2638712065295360379],[15170836176315874732,5311898155992926546,859628048047746292,3163810127323039209],[15904970467177416302,7885581310042278638,14404597872433939073,1523348859754907831],[10958490988289835192,3564692893968849492,6616438513941535093,1928006272262156707],[8971550641226983301,12666341096515836810,5119772871836300530,213649690094686053],[10824937849326215501,1718197996236237807,14099917621685022323,2178034142323898131]]},"stage_2_query":{"leaf_elements":[2851748970283595656,871347139231975690,4709350464618744273,16793167855053216517,2822982841626325121,17826097180941953394,10852900115471152983,17445760856099891466,6822949616624548200,10624579968506650735,15720981294244540191,1628080007299107186,14258892470454363917,3416272195332301233],"proof":[[6171533471957150576,1475621203829242084,11743259986955607649,1585751327989932404],[77501785877454404,14623496096126089703,15915423394322186357,2026941576585746798],[8099125009708051357,17402581171730735762,12832459147004551258,602621650504687771],[2392161717910529448,6939707943030257985,10785173904383264996,2157205440324284964],[16402583707141826060,18154577628345449207,6375735388957346675,3464729118864957125],[12326876796154787072,357427559570259459,10155693008659787946,2499231732215455987],[16784528279668927724,4257089601006013173,11752285175119356864,1368515241864028855],[4192925288304306918,14038453269174424216,5321305019389570958,2622412686732092607],[17358627338548629567,5247234787060739036,2256769281256319396,3243340277336617052],[286389416854280118,5481481029904598927,11448324684498534317,860299065237886008],[14855294033082672669,16316744861209386990,12678973156966176776,1870431974446894247],[4342695474072020893,9630581221526481868,7547063756698356121,2205642622808201909],[16392396484878729955,4126789946595454481,3364068644797407771,3206984783570342454]]},"quotient_query":{"leaf_elements":[11063796066802754934,1590897274693474913,3368087240652664619,2760823787281177504,5847043595108336358,2418195773384952189,836584809340077228,4344966241414089310,14274324646070080260,6763708705095004022,4260764883176428464,7980955694951440043,17103252578935063241,2346780522683637762,6916426472796141052,315148880854226841],"proof":[[568055332214224686,1473152555554866943,13762476245984377568,3418770979152864815],[3615916957316509500,2761443762869733720,3726355528082615644,2218720336457035173],[5047427948324093976,1623972868127267838,15069344231833864712,742190630364142277],[7618287731837488155,6440145642833337176,7491540259826185508,2242159411287227652],[9641177045875986044,7512442552669228148,6742052446624327543,3220175415467138044],[7881542669596115203,14377033939489589067,12932198063570380704,916437272887529270],[8066127584259546593,16029066477518348481,10782948260718215234,1403268713494094516],[10042761680286515210,12177985121779752693,1476178519157150564,2083717817910212901],[11263685789582593212,7513060731430950589,14838037366750172226,631861153494886968],[6824748216005742567,16885673855369499342,12067505636347794480,1814588586744554018],[3116586321160444290,6958352728219004220,14623508031201260613,3415114328625469359],[2368501418284441918,612763502767847230,14553353955504878327,805606120996264345],[5140577020405584832,8343465989344296495,13002851761865653574,2455122082449337052]]},"setup_query":{"leaf_elements":[7785508105322359922,16129873643014068083,6028962637289362150,9247620266068030675,7077850768097233844,11745333592398816560,1153511494814300069,4072975133007557337,12955841417996168648,512471617782980572,5514313184883188085,12174759550080636940,11686914608332964666,17828847661925760708,17837329009407053789,6734051223812099736,223045932108630495,14343739847522475635,9692026294965504398,17325062733603644341,14624233770969895552,17382488729997241980,7570963617152300736,18238757547347866683,139724908312160614,13855759769170392534,3731922954900460778,731906065098108120,6980965502358470838,7219341763306641275,13286247285705161105,13483087571547882253,13823006360509000434,15079655562878641954,11435256103705093724,11414000400750536037,6404471689367006022,10975373030503701288,15643297768849162965,914718967976069407,14254410968938757477,16020022249066252447,7600222909730316904,14706018491992080838,11226479924792644047,9951247172649500115,6459601163651540075,1003836800870108833,2386322900425233799,14612212938279367131,10247772796583978348,15441704264378335643,13723107777146513094,4088064999568589832,18439783424503835541,17966609329990526176,6461440699934851070,3933578027656933153,1464761498394255719,15735675783150300139,1530916477023846942],"proof":[[18210826617352773202,17726868702114030961,9617268748772950047,3954816681136549],[14569052136395074836,6946303112971344440,4264754872376378218,1650476961051801476],[6938295219040300861,14525763610817937777,11390815266854315400,3363776007915986688],[16270911231370315000,3807544845960209316,598762395845036314,880245400895289883],[7237432297042544101,13852568755905376909,14407381452108426609,1439102588699090026],[15746303232176148024,7843842242871146314,9487023045188354314,2247680079726938235],[17066625710666210719,3001543339437865806,15829871137247156037,2999788650248313300],[12689209601111999944,11911063863246420280,5209417082074260492,2405866048926820579],[4811233351172182060,17299827536728186500,11559574278006773460,3326835644597889565],[16987420973136768194,3654396609914898039,2234382432724386183,3137477222006993103],[5148122196096283165,4746302271774025234,5707164331223489048,517299353379233803],[18084428029419589912,4084746638087515202,15606040896233187936,2824151631763754800],[5756101253259440037,2507236924583807190,11397614503149736527,2196094715248116226]]},"fri_queries":[{"leaf_elements":[3939556446199740954,18166684489647718585,12866514312859997970,11930250320756390293,6379006556307309508,6901675440197434293,10312802399838738765,13121394415455323211,9587653784949423708,15871257780652415020,6019320422255464923,11130221556758633935,14087627109047978663,3891133572947192097,7749854084040363115,12250868828321092595],"proof":[[17710122167038241124,4717554906580869434,1722886778933972400,2937297633286748393],[1710219397344701572,11636134176352279683,16039345426550276839,3013714652719577172],[8068692806473870827,13451661677177453891,5290211467202828997,3168699807983095240],[13736947702827798996,9204370250385996277,11733013954149221177,1001744423684636479],[4381502737600482046,15168334462334897563,15996852678592263467,865200097522546989],[6952745563530148660,13247412316943924320,11787195675466073948,3383272035613146594],[13247135995094642894,6257044126830807190,15241741372061554329,253092306167290274],[17370964886938029298,4608757828685472961,11824757276767675278,2131933875569095071],[14587623574751915128,15605440221259329305,166993031526106173,592282036052164615],[4203734648063415088,5572606400297625904,11638643099097167954,2149312300932434459]]},{"leaf_elements":[4358167714380919263,11402484391938420805,404302512314525699,6594537255134904091,15695955483157038042,8293600223252391806,10386124383464348209,11514292159615734501,193276004962512845,1197051176388990354,17913901716008161558,5362197777948147940,16312324817682644809,377286026683109981,16725241540194858198,15226090789208671974],"proof":[[11048757224742162137,14974682095517073909,8735051700766816077,1371892634509778185],[9094404802790501872,7614529379978406412,5879909672515127570,1192735902714070125],[14318022032236464359,10233017699718499493,4447613324499287905,2282480613308093644],[16592760273712355353,10854955587800595841,8809126001910611886,2517900344164782692],[857888078231555140,6854724288508753620,17600439185098916248,2793496545818798291],[6565316766626235274,15840052527892295000,5929338727958474056,1872532020323958379],[18104451860560284932,4640583475077416108,3306284090082262603,1481349666398733696]]},{"leaf_elements":[13126109202626961236,2139133232184428322,13317050585247991707,5591776342977265348,5768775694226161461,2427815573678647081,318665822442663929,9715657985539482943,1136886958641764003,2561186386641975783,12760329195757372667,2071350179464889826,17671436990541019285,16182630691795926162,16250951031092178839,8248320394002954450],"proof":[[13396037428460928060,8515100104281655977,15077775287790727878,763151058011997982],[1914676428796838557,12308854683358632913,2788725102710754037,2668057056778906971],[17478367562608498702,14680413632411889219,9997801569494526500,1062035792450322814],[3739423148044018170,9885586201994819541,5180594229908055931,2531840889243286305]]},{"leaf_elements":[15859089997781038374,1994857186171601481,16712912127603582757,13210363489554923451,4307184507230540301,12355014920308439175,2377906283639097493,9636889481462111568,15689506450144469148,15329674555091613968,10455228447275223635,16353864476348180603,2431194475576405329,2637549350951861111,17140631889297147002,11070667164652724216],"proof":[[18273848792544346292,13194308337463836707,2821939436018162595,1287166854450626649]]},{"leaf_elements":[16775312693976535021,11906390845590027506,16723574221087713398,13884781623836882318],"proof":[]}]},{"witness_query":{"leaf_elements":[13844932413350534406,2190051052743007952,3419820526421237762,5322150152025296967,5590491159656925616,9689213247659683698,17493041783721426975,4835991368005009071,6758824487777069745,3254370626616684214,478227108190641323,6086068465982253295,7081884022231882299,2170347703440400171,8070792062541633661,10827814197050619470,8965205055050323925,629257727356680758,5060034703823435589,9953757072743975646,2682500139014856971,711976571622439026,12305641034576472520,15870314859063298312,2625722638276766811,6734197397948346529,7265453800292663161,8572066215713469905,14160641892864129072,11661910452167064200,4944263601161249724,7723286421251854897,12273621374915338555,5186207618670763062,7688379603785306529,9397723231793951871,4400294901278749742,12664916102311897352,6546610399660378450,15684957436524767652,12219280548563635690,12001535915131076074,6894538183195992354,12296336315487512505,9179094585832680070,9865615169832137801,13507225516654613135,11095326562567066663,9192349255651894406,280074172085550714,9760010679743861020,16678173217940121007,6902218934155415578,5137873067989666114,6473961007324239120,4232181583985358685,2622642904378280552,14989744167273311250,15037028374485073282,5139680276114764159,8810755042471525426,6431834517249133860,8396247240028236203,12772634759580281409,5947774332482564488,17293277225612309014,7668732252435454972,17604249929772583764,5907824284519950948,9669047407707160414,13540688560896701981,9996519629593265256,4048128009378903846,5538144702413457010,15323287589040788974,2189407515256070531,6462474937834146141,16052127872501068220,15305169758884264848,11895683050740879491,5664260312084850593,6772748669634259536,16163385942418030161,7060771550043707724,11656270497681664888,387697499227568439,3072550986648481152,10517823154836586254,7648416737524679929,11696817200759510525,13527554493933380209,18171511276721115823,12621964646850339446,11266961479465065405,4270515703753707159,13780671526415736430,7309218762508725056,556300336877261513,13747021890683570812,2806970225429983793,377609566605457938,7516409848057210412,10249239448099443302,17118533359716820047,10519313885480708668,14357780401527849161,1512595736663445452,1300121259498043921,12073216686310858346,14287282228208565539,13084969933597127439,15299736877133268396,1439526266833864121,2609089907910741806,13002339826157445583,12666392791419832896,9690909335988512744,910332392404522268,8699409721693974893,5312492763758697047,2822014700611721799,4421701532096853770,15595525706847618626,12112208327085822337,12052186502498624794,10767607110414389478,9422889056300454106,14588086158335701365,10434262652900336740,5580842667557216527,8787022358729654207],"proof":[[5079672402871298034,2615028160409743595,11192893665944342552,2781453387242409332],[16590565210158686137,4524576579897788400,17123685244919373973,1670102682284478160],[11254715432088626564,5377560282729651881,12634274735423574674,71010745704020418],[12612608951354831331,623270917778838688,11816428505521857824,1226803242267335626],[13211944059007037271,6410366223005092030,8669885281028808990,1070049912380281568],[9939556645083338188,12036062960181779546,8115457997071339029,141940874580246610],[3157473888812280755,8626073039746438770,10914133102399344061,150469567420911024],[9878223950168819129,12767781775803478075,7604681317994913519,2236498405437048556],[2929862545140706497,16280656146058387853,359930923030963978,2928634457277471496],[13073253082490204641,15638624881445348194,9841470601433926238,1676427404760367694],[10268531948664231170,6525118091667883659,2967761560303839577,861811849424894341],[17853319454102426703,11458132703626502620,15417113988119134628,674570626102661541],[10228429935734291152,15070756974979336511,15218154065077763931,1832421964913171749]]},"stage_2_query":{"leaf_elements":[903837152547199886,1435970004455423208,2907293059474586714,8404547857326504137,3106500858928861937,8841935586379113013,10764641289596637448,2953057261520463582,2325519892741787614,1900013824090320908,14990348025217843913,4513411834063013830,2093955263515056995,2245926728352860693],"proof":[[12606114837683405876,892132706467090432,11185165420580133646,1262425641877388433],[2806210459062174729,16607217590635463578,13578399035948397211,1687782343694381522],[9699318264239760091,18348730050002991056,10305050333358918565,380994401024817637],[2859574225268439372,12359588473395990809,6776519318807860909,514112873203861391],[7268569072983561358,12738828309262622123,742934250119785223,3157336970216717017],[8883734020370148527,9501005113428686139,17192418644228130033,479545163181114915],[11802016702582742134,14051821982284658637,5132814748957237808,1719106522970761206],[717528247159792666,11481946363112177104,8046717555696260108,251936863064407030],[16129526222841506927,14166328227043558724,15297222935389559663,198235865634238280],[7364223497299356969,978150780938585050,7145224579722954265,1172366305682289281],[2270320900022175314,11084083730022225629,10498212610982509104,3042167221963509761],[4635452191223119194,2876417225665026593,10993606036791249716,3465884504674745958],[2751258051649958256,17916243703110554662,13375786371768332344,179905637827751778]]},"quotient_query":{"leaf_elements":[9022938007555241602,14438734451938506970,18241986774841423103,13874292385010552714,10748904141500208274,16362320382291624985,2066366356611500832,3858616041126409696,14718245094150180577,3228629664790391670,13466763211601721333,17618092905889656988,16479310939496535431,13756990317511780405,3790983227112128072,17236756736053745252],"proof":[[12435871694549394090,17336609325884364655,239821334443914046,3262270192305557063],[14129365190415794016,9129015355793492837,14740417416689166871,2026029798270545092],[7910317387041928974,14385201834461185644,2423120838468123636,122070489281038438],[6760583030780593430,18141482037161405955,15405672274598517800,1420932374622656145],[9421674518611181103,18219053984776408794,6719266696703567083,2439770167967311543],[16562734265713768213,16856448150457336044,271460192661053419,3458982252065217782],[3036771716605111164,10449023193416215968,5520523731761551497,1559921415754015248],[4322896204110843150,9414894615148623830,4224647041284965835,1460903636457306156],[4797139944812578707,11684808730689157572,5088867655615736779,2754615984463887005],[9311127495606908805,6613148429567989397,3496496693834246804,3006318540312470433],[11420173561277255454,18057715400353369436,9202491462650698454,796211399199829229],[16565671729463939150,7300669218253294122,5820718040964588145,3134965001892430495],[12356171133472036182,3715560352098057395,10451102580509047715,2369959934291544747]]},"setup_query":{"leaf_elements":[8028645876916339322,3781315263949497547,10163494139676361452,68563941784139377,10451271646122399500,3262974182875113405,4206702660159275749,729146328309712863,3064787135427101871,3419333947202969175,5623560126256102762,1033272386049871098,16326913468636051451,43918928366865676,13944922682830891935,18307982600035978346,7983076403017909595,6215179316710630652,14605067282375350285,10745089616888144464,4018227130418750268,13918206331142750854,11101075790689391906,11998871516220475905,16684465391586621262,18002613149103632762,4481956901348381635,8220661292272559911,15777425112420375613,9839703877617253806,15937932953241237815,1457521944609089034,5096520447512530339,4134226035766672552,145961508162551036,754807440225474712,16291180011128337485,2366768530220489091,10673165989692912257,8965363365076845256,16808978356500254819,14175632436596044817,11849611356485195167,719207208017125542,18052099944357835003,2440025736450105408,13375441984650758244,14224434083564059899,17226472844534647737,10787245506000177878,16667268397109853131,18303420579111624065,7286326997969138818,3830847192582796742,3099705152233608499,17240021449687209133,28319971670948020,16297630239244625184,4589597198853459132,7010597986274003264,17874274983062509588],"proof":[[803359212808934456,1724265955804892468,15555155537954247562,1913163228446494226],[7687008898328523820,15767801722412536238,15670467535837408967,1479828109543296432],[3552601127636085116,8978934532270192859,16652243442999465578,144829765211263079],[9750830053733820286,6596375184450721747,2228640681331029333,1982101242381769644],[6705240991796151431,10531862253171850213,317979736546108285,3417549434486500039],[8343591435247680247,12796699521374552485,9461521314924151011,2692968888515466234],[12088337224080714711,14969563995689321714,9435796235305515607,2446342356998628178],[11382955391620787103,9579555865764175976,4091419046248149098,97526812475719058],[852516072309592509,1832579905906929603,11537420703747165971,1988241628815370823],[10543811926056251725,8223867670121429785,17005535188590062398,2818891784132038489],[1994173619678547646,10148852412617542927,11738218631705955193,152282741587195506],[8114630110093767876,16550415767052044878,5789539078719692602,2820570820614345953],[7450018982181130668,12654494844657139995,4699273518936840679,2505102648423673327]]},"fri_queries":[{"leaf_elements":[6543759125341495010,11823953383672674756,15002673028834585226,11961709349205673020,10498325897166149894,16209933548082168861,4173537286446717446,13581149622576454571,2023151627865007903,13701507871642680056,8892640371671725094,10129839200633772428,2880193800986450587,11093962024030494761,17040396926857371334,11460257297590904933],"proof":[[15232368756962968150,1728050953874783094,17872315587767522049,1048212858817615139],[11433450082085898850,2931254633107634605,16179893903561353998,2656891257496915238],[16315198339528687112,12221703473882543901,6730212725185859738,632160041755566273],[4175822869738072747,2965318358054530116,160212218831517393,1918048866356842510],[2369607319857290868,6367389322620150974,12226760407359691758,3011134584458574449],[9192681120024221845,1203727509762573177,14733971116742967162,531044497264843995],[5935461741890322047,12035738000010902182,11611847660690112388,3320321889769512978],[1008726943264402737,6466587780006767619,11810308758125917848,1441059928321202883],[6194151911933769572,8316546869983692090,17095017662834920753,251028876106012784],[11836481767288568977,12693209842729345382,15494293070777243110,2609142590190361171]]},{"leaf_elements":[11679623677280721732,7460412689090400020,12090057111532031993,2839856146700376401,10243978923503521960,2446409972404622534,17043000430362273849,11996735784474732360,13025559612931115901,9815807446172303033,2789872556226146382,13101312621098647514,14773714744891588914,10083019193769408729,12017428999559988552,10633961004454804075],"proof":[[6241115381434099655,9717900477169595047,10469335358641825208,1467038733306856888],[17494679617275322582,186556427690488356,13953410434179909045,513258953679026340],[18271545562307155687,10069025489759489236,50146087365325093,1367280205555322547],[18254946290161321080,11872966207879383732,13343550233043413637,303013657367501148],[1101874981325959238,4560900851701830093,9769211162644476409,3117656796157897536],[5494814019481716921,18311101359736832981,13570339656516216338,1358630459201341816],[18221825548504215278,371654840480040303,14092719419885102622,220673262799455597]]},{"leaf_elements":[5565613240052445453,4881451002888724707,18068397668498883156,4494904909318130628,380743001541324904,6751015474642466122,5785190955078372648,4940431271044920136,15239491850871874316,6675661567090458705,15846559846750524065,15021324880991846961,11317824577575091355,1467799927768502586,435157695315901377,18346283709919559934],"proof":[[13308723686730970742,17945073215094909388,9262832195351726227,23014200546860332],[3850264036200791075,13251391295098424621,17340602504065761923,67443032188134799],[9253287968541001853,15965406532159194935,2926908177009333941,289682274534081662],[14060609606501320317,14199662051727725133,14045188731999541466,360178435938369202]]},{"leaf_elements":[5617743489965329866,9656866167906423923,12342513696506161207,18445839140823577509,17173266430686786372,9885785082442603736,9640565192041168087,8859499278609365175,1962944870928990236,3217289664835128148,18150089437950339150,14748222972309771547,6995749073399235010,6830073760022153520,8684292857175602258,18324510307768863292],"proof":[[10423969435245672408,18154964293000735088,16236043164000731250,396436116672654202]]},{"leaf_elements":[18196018707140134098,3942247739030689718,1556687182756891542,8508669979898744338],"proof":[]}]},{"witness_query":{"leaf_elements":[10734847265377193395,4385220339988760972,12492576620018334491,5830056082396493784,14704787947996906028,9090398572715218286,1905972821569606751,10450166251938985651,637088788088643958,12591609331382621088,1098111196901820658,4502435829793732624,11488843254890103170,16892571967715207033,1188675014377659342,6395084388754660938,2885615405399416518,16616652876461571399,5535068396215828154,14171687765685417412,3301811478004599413,18436843832723113032,5853381145900259700,1075037097039707196,6781411269572475011,2963950193232691650,1343027816001075861,14682145511193402843,15464860538322649029,1551588954277929235,9539159580425739798,1795719610415888919,14054819822987369045,13908632758692822953,10963742792165915947,12987741940559670675,16784099278131285728,7866097578199118182,102646896476430930,15832353796317635231,9778025294896102242,11012822730960497954,4199253907201526673,14809853428752550840,10315529498535006118,2224277934024309945,10211186658972606023,2452069111225383822,17199216490440925238,10720249609407621592,5781825966774647835,5602758117745123257,11270537770690469870,5864791212580495618,11766363043052587914,3381246340951362778,16986647722511100255,9664752365966913975,16197119355273485040,6079413626540214706,503434148144813904,18266771130739386569,12183080434670869911,15181774042393100887,10737344945762175088,7165003939329193890,9519220849775294494,15664243153300516159,16002098724258114649,3279954793607025560,11845078141136568248,11057950234897444619,9069658501964126639,9873625957174530561,4762802271090658243,13858314336130152336,17066110767763817296,15839520354069017870,13259919493198256292,9251445689104058316,13140411099617506333,13596037693972416005,5407184256788272390,11722011968608208126,2446774831471404986,8215836318806260107,8599441005631077371,14353534451517445209,16058541941021945594,13678055663981302091,11821050886050086267,3134114203061400692,12068602279190629904,13214042367701641550,7212349639771104373,16423728923761568831,15890640796059871356,10974304831130479784,10100836708166186687,2371332042228498211,12728269365861146713,11443257022966363338,2735288069582956261,11348381886688819405,6919451045891863509,3486534447099917035,17053721962889103898,14458074061100315014,10854611245914701113,15603597883015704496,14832754250224325762,16898364384507308089,5106263985257036035,13714945068806123794,13803721912524252826,9341015958238358700,10976947081336355072,10987740286671483791,9048252785038465904,13496678537682529620,18349890898122718106,2125309323565174329,3477291484942256412,13102001305471189229,3701245418123921685,5566703700863596154,5510672306933357751,13400996796448698765,18266467348721260058,12942743075650842179,5341140862648901967],"proof":[[5082437751085576894,13503295085486963562,6268717206688297268,713368820017792408],[2322971944715570414,513636037931489926,2469044033376730624,1982477674284103769],[8837522889748984343,8733171237799573901,1660874890323925757,394416849561238718],[10990779083168954788,142289977293416938,14896542996083301817,1124047996648662169],[14119360018961389166,17221819306896730115,6942961155625666941,2376380455764962893],[7452543210370607286,16354603483301289585,4150755323995917542,800278697540248137],[13767221755492750010,10944585128530406082,10404250570107868869,1296717062443970658],[16657363524611837246,5697628554822062454,8991903517302523539,441007925158333984],[16691434516602183540,11364517126194071692,10196061941630621382,3163312572308894314],[15724908237463159798,2476128555711337794,893182730159862167,2389511424641657152],[10481485211999893321,18148823673357813916,536405877748246507,2216037530216711075],[11585500998014024581,18165704429894542582,3036654816167034839,1880224156156966484],[8885885328764264570,15253461075593888787,8635362468763591648,1758704055483322988]]},"stage_2_query":{"leaf_elements":[18445337089150757319,1985659166037398585,8567900310983993356,1905564921760598566,12160735339392338618,15890819313477408537,67289614684475453,18377896401367034093,9602928274041710103,12300745825120241050,706245631936510460,3547608272739530572,8078842972274904748,6557363172280477463],"proof":[[12030822058926858933,5935294659573366162,6040876685305881707,237023367073069594],[6822629239144723528,18424530615073969168,5053054743289312355,534453545308351402],[9287272502755591654,1023310268706044596,10972414159087476002,2800105593447335995],[12567283656523041720,9218114699699188606,6703823685057017783,1038518632642239485],[1735421451394868405,9535044742209852290,15124758794909304667,1846537757346155135],[10976398350073187307,17408231938720933760,14412310687776779060,3173372835444870039],[11242793996499101141,11095840971193645239,7545744032889754327,1324288668829770141],[15808802039348954282,16324732807935842589,9564081787538065640,3240642348015776576],[15880835260607700373,11394544125555454396,2093575555425727964,2177227286492690624],[935747794540775843,14644649117287967465,14831309637420490762,111187876514406520],[7939125308440738984,13207211164663922585,18419014294789621558,2041622973274595106],[6290462272635327320,11906594927819517295,9928188905264585011,2965979690039728871],[14997555234890825160,12722021247079928466,14973662964715584688,1500605475328540989]]},"quotient_query":{"leaf_elements":[2354384696286506481,9885105930033713011,15582005395671568898,15815110450503060884,1640437537782186682,6091421490928362190,16240256272887612009,2842762305413896251,4731525640412020396,18242734539730098500,6897844322256985357,14454611378711786373,4634990936693034886,11241010435901991172,5125583279706534795,18079997473933244911],"proof":[[6982178786748820782,4905973267712835525,4755050604539335501,1106821097736229134],[14073126105608266613,10386915173329991024,6292624276752024146,870884400868743219],[16643125681287263824,2905728097888958733,16161067041155979394,742087989582644165],[13774382358824107488,18249290833077407884,4646502006480488285,3057038140781490556],[9200055801486804416,3377454234273424095,396914750778042122,2078013130304926283],[17037017111729095151,11017825397541905896,15948199438414881698,2580810210816867000],[15301921067775246405,7752119588241923606,63443663472300880,1940425106787842037],[9437137519793185268,7269524954200854334,11349260093983604059,368982227996488404],[10973273263342282967,5671823598913900001,7762522711250887017,1670205373124623927],[7663246993311891346,9458561204814284184,11034902978544283452,2849373500503576090],[12704286207682930883,6142561122961796416,18024652275594999563,2605114323045480106],[13662726808171755200,15442147198637866076,17579350049766953928,1376694955370959817],[12983593438245748380,3228292378616042019,8094535644869113142,977779693227197763]]},"setup_query":{"leaf_elements":[10352356677911390958,8642956460846397082,15146359436114415843,6612735320491809071,13677084414239846214,11090317749192122468,8507729193999372153,2306774601572617257,11207927928792389022,4873138277864713350,14497293161745911813,2137134380674741493,2343158059398527953,13478207944118306569,9606259383175282322,8502729084586689833,14405232675457476777,10930747417106650205,12288541102955553647,11041514095110394452,3151942387661607726,4679024256737281307,14812776710070886866,5709863458532522851,861429351933623409,661263310846988427,4218733185897909088,17520859262757572764,4370605762413492649,11797065758898814824,7547520206341556305,3975754322459373875,9388122000044751586,18046842850933142583,12843954516945999557,1948251832674986834,13625905981495919585,3412275999808600889,7544089415911430262,10743686341989586807,2272381142449826678,3430713171784656708,16637130314598699257,273711000475785667,9886686828423199102,1385888574066414698,6979958025613005337,10626632854013460196,14684512634768076104,14948860082003090800,10735296963557076320,12852921402671749458,12514415163999044315,2859236335710144023,3516037684884663921,11629560697934491562,16478746894614528597,5015237468071211124,1017770061569684125,2759632941634575656,11603780012306261780],"proof":[[7384497761536435283,16962967661920084002,3568597578274151382,51768302599028347],[11383332123395077142,7902855490899699975,434145561068914801,2810597308203016976],[4347389443737247519,7193240396411427397,12940437599573146372,92979770436300263],[12058854524309680033,16923349299499463632,15655018141976384741,2796509467588058141],[9981616223282773103,6576465140587641270,12729133575866847648,3150187431118924091],[4071756005244360228,3004669076560014603,3550756139389053965,1060889389364887973],[6519283503288125937,853162181895537914,11417815879765553881,27044177227939880],[4635753880999120158,8146917199782070109,5342782396689034391,1201202121337541229],[4503184493933112387,8859145241309020225,16951183753062085952,2924671370225118810],[3370748523999477553,7783986352378729275,9772175682288711111,1028067807038039860],[17680691921336978422,14301628520766292053,1924351853217895611,3185911673472301622],[3076407743883423930,7998951661287753548,5794264668421718855,3230768055453350371],[349109335511215027,17635955180576205439,10873157572691085590,100138798179046082]]},"fri_queries":[{"leaf_elements":[3865993013070362238,5532823801230316031,12006164888858751604,12489355482797240596,15280449161771851187,6961092826192280168,9700399231364684376,8536409094827930621,11192110166651147090,2945356549111988174,11169917380729542994,14767570604338361036,5618691148687214438,13672073847689156686,6271639702821807466,262269164788715892],"proof":[[12694447394785781013,5895504780124702572,13041000541179623480,2609322099542809529],[3490421911472590672,6944919087081258583,10739728429183623966,1978238307296549574],[7196875726972823938,15719515539810102024,1930381777655040999,2611493419714886271],[10134290067133814702,2944362829042516636,264687289387548310,2902140708878885107],[16948078795478004381,15539505073664609293,9009298737466477093,2367734070937830988],[8120499858619132566,9442908795557788471,17114375885759005374,409517308458043786],[4084110535151932009,5938789006963722190,2631162897856151111,2155222703305860110],[4410682433289130035,5212970886802626181,16376403481127471230,3041089853216483375],[4574901668681599804,18146419379319762142,15253018587145302208,1332106348631076297],[5872362109046519663,17298216179683052012,17954241167942654865,1329959830779270496]]},{"leaf_elements":[2994552647190715639,12324813496709469604,7440074066375270263,17778293216548669929,16982716498392285740,18389741725585456210,5734828535099955386,17707439227969337371,7012482909169761751,16356049143944978421,11522326827549007668,17133475455288618386,11487700740993073037,92969711180096748,30899931288351054,14839274590150130339],"proof":[[14452344353382682678,3620715750081975663,16832799929576622602,3083055362054492200],[17439316444533342193,4996892300558345327,15122819057219097296,900563009813958485],[7264105601811391823,14341086518734238944,5302966181654712864,616295168391251644],[11570822149305146215,5779563311811392699,15189686608345357736,2860090083491693844],[7927732714397296991,17233307063368432725,15604893170033517152,72877664776598643],[9812876142300382920,13673779875247428723,7249544964718288020,269382820752168909],[16261718003729431254,12624140424445433761,8264539174081367282,1767999685948706560]]},{"leaf_elements":[16321554387713941129,7562769819463798446,12702692799425629772,5008973206428613891,14369019329085333280,17867990559888516981,3416411548751171202,3808746794100003230,7323950333897198764,8737840998287224750,6548923871431524142,14804055692892647508,3599867174793672361,2653386877696463964,15905775105548625307,12997681053164523312],"proof":[[16964177825262595436,9604102104004527812,8895596106992569144,2205277455885499259],[18195926313264799527,5708793743604447653,1578117109710579006,2767569431879076183],[4173343898888985275,9065398796238881668,2307654876821585699,1145680773226216614],[5178269920370475624,12704941860743336856,14608161129520644440,1975034317178109081]]},{"leaf_elements":[17528109201327554736,17512551739109393673,16067869402036412515,4610657633269719786,1119811347496505942,1935047269409703784,5352052601147768823,1757265509591557078,9849843274380055845,563104860289626653,2454136331468955769,15986139360915283519,14488296552677031709,16258607666023994816,3068527877316626104,12344638888204519753],"proof":[[11920089887337287797,4554508008204592489,16273321998182690570,2094470738456569066]]},{"leaf_elements":[17499325981881337266,17599898521267640417,6381771601744403426,6712813034178600945],"proof":[]}]},{"witness_query":{"leaf_elements":[14312950951887036208,540649795251404424,8010312859577520684,17996548963667312103,2548437013844402231,9033026494887359074,4959378681346399659,11362809567706646507,6993489254006618764,8449576247700131320,16875332977103309865,11661500719280602154,11858924200591744113,12273010073076965096,5940586536292955195,6806935007900300215,4370949594332692565,12295644254182709721,11581936302841590372,11726601824079853897,7320484158346516032,5521187452160586560,1355459934686715774,14495080960057358656,5697570819172890690,13617642767872836569,7418570734934158164,3867033049110989903,17891383567997557854,11913849401408476769,10898085506842521321,6402885953715394047,4346784949626703596,5894430429046724599,6112571002049527497,7053034472629276377,14041150035205250100,17045325390156580804,9027411284689091445,7313456439438294010,13634954479645096040,5057780413157300599,5866354122623532581,2702800644157946961,12784368639347562228,12575938356101453757,14949676669264692344,1200069159651685525,6319811501886432491,2731202713232806328,16347734133113368591,1345901375983387166,9027222287784917882,4119456555244636018,5451395010308868277,4310705678610444954,12386925906307855470,2698478234902777889,9919173527089563771,6199583118474730930,5641308608796273168,7912465585165322133,5715675793103003203,8769958293640132929,15838381377274375874,12752056259362953475,747228772648495940,18229147533518794186,8785309810736982796,16179167494362827627,8316014410423294787,10358236421677864050,254904052831154403,3386215134125693994,15261844838491584149,10916807226300068387,4782659664231456346,5116229151427821182,655383869351981915,5627698400672019249,9111636601566804274,11224251669109972439,5256030563560593763,9628257032183402837,15646834841353829966,3124398946468601990,6377240014889727188,4721039512472446856,9920893431525011936,3336265567200712396,8130803991093298227,4582385782869960258,16152050667010331431,6774368456018849738,1892785725688948621,9599707763697691176,3749342898984692149,11743596631033503565,2228103905895131075,13077695265116569524,4058421140212228992,9645895749034125057,8142467277246776354,16108237765022903158,8935205114054612310,6058785170028390208,17959785913745953370,6497343725004836882,3484187775602205747,11089312308756198178,16839886883147802037,15087377115130615919,4940082667766359754,6848199197196748948,7753223656052693480,6521209704358531160,5436993244852639992,4472829125248460799,17304143983854140924,7443772412987124776,15843575360296527309,13995895381501748826,18256828285240659220,16747236809893131957,2394612619668025929,6642915926678388601,15288227743000026365,4013936426807643501,12067719618694095247,14208046732376496222,13687037434245320400],"proof":[[10231495560702952659,14284445232356842093,2228764266037770014,1148756899025502956],[15529947741696777780,4126275373659682264,15805985927056022208,2067631830287816031],[14340693674603948982,13058913044105552975,8404001319262021565,2631772624859378203],[3936255618468629748,9102968894653310036,6348123515873591990,1203619457138355263],[3477042385519341633,9718171947229293453,8010099688931002447,3204689537429979047],[12031285476450758919,1213759334025678953,2733722424503990791,1217721712229465080],[1454082045151307484,635909899429527306,12087828076315983122,2134023034813708956],[8353183975324405215,8219953705248408773,2319868468802291638,1867166280804803946],[13842078074068891798,11728423679238619812,11617025057845446240,1175616638710694607],[3674941681588722122,6937921218178197784,13667803740483330581,1805841077523833169],[10234923790260917492,16134544500046937010,6192536968478693055,2212199653872390577],[13956835885681269420,13977950138640785752,4863109640880899263,1937558364909967234],[10170411153944345348,15189428256572144992,12959700760463722718,3298790997504217383]]},"stage_2_query":{"leaf_elements":[10977820177642431622,12355049730854249061,989355490586763258,10081504224373268992,13244513373510164222,11532270702569153652,3853607895109615387,4307660920782751580,11770503221449353468,17899588422098079048,16133227068588733998,1881346061661684123,11581775197013251192,15797327760664802327],"proof":[[5256572784190027373,12709266029511128990,589938865180542830,1086656762329449568],[2129121865992431522,2191911848441998257,6697073597176166309,2457217598410394823],[5413294032912112549,9349825085591014881,13762551920732339854,1835100063655092144],[10752199339913237627,16299047342074834426,15632045302221369239,2081021504822569522],[11881278564779880160,242153046048600686,3033174051897498486,1208289329489159523],[12607285682433474503,16948535903982040802,14543063309346294418,1034645106232645762],[10462860247836000272,5173411797062483326,5619596694273044435,315021801342417361],[13914576835634164252,12171001295905527340,16231413945701879497,962166326444826459],[1723380146632626202,5295772956098083202,8318949327926379548,1367575739976870325],[15912240789430353319,2019066378173379809,1544743854581528804,527392455536907916],[13661234358441554655,5867380597679935196,16965064547634284256,1150271417876686726],[1101391570155270103,18030471955809926170,586352199699272119,1793679619803222441],[5944104811179779230,4705743378997469566,17252932908060409042,1116220520959491408]]},"quotient_query":{"leaf_elements":[8473416429515718485,2261532725834506004,11346292133688818898,18318007794485152352,398136717246102608,5513469787399253355,9051869627400482894,3124225831789933885,5370451358785834065,16823798925588231194,5398407229436748694,10258850440595947925,17163782869630215394,3624845785124147722,17802936143930775821,6975285207267462577],"proof":[[15794948074676457207,17075402373575823000,13093415430188613350,2605074392191220283],[17127741553938158764,9806810613848812563,1597784993042970160,539617433200944743],[5306312853283373672,1608380737963995951,14792446383152464893,882824672668795653],[2347391813094263970,415321377325173504,5079615735739123280,578730543848509630],[10110913919842996757,4996395956139764749,14983115205935031,275909113844093812],[8958416948950735220,7484035537776734580,3316280242492832067,2344268880479604797],[15474260935514366188,16748958734754071543,913529434781076833,1404568021797679211],[12530942231862598849,7007791965226478467,1523914301321699298,573601272525677822],[9323175249091540706,2641812429743234302,3701799595368381763,2061157132841749138],[11075825838577538280,15269034606084684571,8177132772191193834,670588787730383802],[8496151696296612573,7688097926724613118,15913285176425636566,260204469448824341],[17805648031392826486,2073215923224479568,7861966061060194600,1640385227104014486],[101117472389605186,17621311294920231862,9537129816252271277,264251130147554038]]},"setup_query":{"leaf_elements":[2667209490145168168,3260981944461852719,14179170541610277474,14224222329702891628,5532607547890858617,252300195634314020,8620064470931864533,12009266417758849457,4521948570602413844,510256438112467055,14858544791018790006,3928102866172290742,9162449762235279241,9003137673368798672,4932301663117658087,3187631614127601906,2022652628789892926,9455515078250803232,10323198506705531601,8577148414490781510,3770903797967314966,10410861408104899537,12375895225136730277,7380684924203174595,12660487605140122730,7223248010908861950,4994487705353298626,11141075028669888550,11462341093270704237,10585699971265225506,14769267366807047748,1450250100014090913,13128883588177787505,3929886225125994240,51978270746154214,2969183479624006020,14279886825398201289,13831526932562048673,12705179403921752803,6567602033809535681,14316237334274541534,17254568565861248052,17648513225915073174,6142923681024332864,7180257091040864463,16179238030936402946,10247491601561050521,14028896908142098879,10005026725723018136,8044399963380898176,13310044209264445810,2827756904035901176,11986427695799811351,7007940234379019494,16172094242454974301,15984165507488021793,5335257745226198250,3066211923084981806,16739841838361127187,5888071936862439792,10266475690181076695],"proof":[[1336337568950086204,17885996910722061189,4972602400910393786,2851337735091217395],[13964474122028245897,2110976399506089636,13006350744495165249,3066831448875273989],[2449523818727329391,338952590114269227,4368175279456577367,72594337481501925],[13479628487874058349,14354547720731538477,4030935797744718899,1788441240230042209],[15467689758982026470,18263071938789191840,16105813183797791209,2991528194009807116],[10497804199026007475,3236186555630028037,9363280888642861842,204174717900907244],[8745519078250035065,13611496086325837855,5823860807038846298,2202543840617899931],[11791140918838458737,6662526188784055125,17644529841219172303,3272909068853552475],[11360441399470316396,18433116269067948365,16544416248378954687,2809765658898487327],[8942511314576486062,3366580451246874736,14019961639623483145,2762490972839929808],[11810134053350416824,10070209752185561947,8072463214693336303,2312904188598789158],[10516063788198811860,11521768273658753976,375854070151956021,797548007667768901],[14721891719636996984,2949626462121883205,514398815710631466,2655190417159851675]]},"fri_queries":[{"leaf_elements":[14691378147987986695,17677313700744140046,12779997365577689774,13762783812483410216,16630183531356663038,11561446117046618588,1403333325048708547,11100324401001426104,2641913703471851555,337445421260441550,8182927382790552039,8882894309507002328,10760537129919326035,17622837310244577754,6756190528837525374,2570780862093437186],"proof":[[17730381965655341142,183618909952771112,11729543017318790982,880003895945865243],[1572424748869408372,11955071587241670963,17105084547716903016,2278697398719820131],[15360100431560165687,4196989641602651353,4634540256312340690,2937353377240457821],[978206290860527641,13803109477032506490,4014522065650637663,463520029010295947],[2699895821806547946,310683302551631208,16026911394802734274,156788958977309793],[16935918147383267765,5605823580976041552,2962457246333809419,94916388846337672],[10736355005622851010,3031619636902531771,1793695099067853058,981445591399336857],[10250052735318230891,6305188096615566818,586180840856926658,1526313768161694323],[4999245903498690337,7298483859315852371,4711531156947246730,2388582959435649154],[5939124624586656117,8797311108778415437,8676485774919245055,1516009211411584182]]},{"leaf_elements":[10693957814404890724,7829245548291734282,11189346713915824073,3922067712387417336,1684027312654243387,13304859319369327733,1011448846606340024,8179642682941020582,6692395817053102028,442985851819391236,7285162998906916003,2517220497067476516,198726016342487827,13395674154549610524,15197305694065949814,14979208736354447518],"proof":[[4265581963009130981,14634040536346792228,8433009094958895168,2187954398372395852],[18389952253664284516,13202332873228672103,6552880628019002520,1059631278288600810],[15100678417298115657,13874457186338398366,5512221613796313649,1315939574401156902],[2961037991650073004,12666891277499382629,1975850522687116715,505872547424588588],[1734663038235488200,12685525245348471603,2277070921607347413,2188248763925447369],[2767861238377875692,15785855316693498676,3744809610891684183,1567103551091653836],[4226831722111814395,6655831638141719359,18416793863196828265,2754055803328667659]]},{"leaf_elements":[13570227015988781841,7500101531777997892,8816433464733455109,8926772539064423180,9407403089687576453,801580812786153217,8836080678669536896,8405862057419486435,12522178852416395016,677201243902160192,5727416636598576800,14937014929751650934,2044623445036613771,13293268024941559633,4755317015488554456,11015753646241206069],"proof":[[13021967017824567280,6005782593242202559,9476063942390244347,1109097222503110018],[2571638911745539105,5939010277878936557,1517675223986912336,952587486881256034],[12210735443468912945,4228653015746222779,6294461639017255781,2485205723841483832],[10512165384836540950,12576725843624026847,9749163590345599686,3286629949348704569]]},{"leaf_elements":[13790855340402993368,7414387734080379513,12975407704994933495,11495992525856327121,922490172660792407,2216591724534083829,5681419279857519838,10808937684894799099,15699585052605113537,28254719198542013,12781572970255467545,7196566718999339916,8152988491243675749,16434549783931242612,15461814104182559509,9183595432750050028],"proof":[[14777760533211147947,4160079023517810966,16181012839474086048,2965431587160692161]]},{"leaf_elements":[16775312693976535021,11906390845590027506,16723574221087713398,13884781623836882318],"proof":[]}]},{"witness_query":{"leaf_elements":[13107876929215815533,3098829163022062750,6128680907270236945,18252543035405443559,18375977621467955628,1010794992945754422,1814998548333561473,15433089497477227405,12683222516768420734,972417912862383849,15692409070633776667,1223286084123178074,17737824065872899032,7923963069497049931,10147072526808801938,10631489547960852524,5453646435181750198,3030437762573377418,13245740731076621895,5755610507679172637,15276201718747134200,12800919648510525135,15696589657809103182,2628911147679917645,12135321478174479952,17887433832661475108,786465754992931470,18267580957073487605,13162959289163925188,3611798433884734064,9777135718029712323,16612433526534200865,648591417871261793,18181412015550747621,10804879516217729118,16653327024958791578,14453469317859826472,17621645853540450409,143869295265878728,15412584344703170958,11699635791107026506,14097173207864342882,49960148084677584,9813683418104601295,14447156981074697565,3078770968668125199,12737390715503315201,14962442746491005750,1773744560531205949,8292375568690747586,15852945672886666011,17726464276111728769,10500025780428330942,16106005562962815460,18403525416290056543,215636680832569480,16296520119467512789,9623144099438326301,2847114137820596079,3669162455202808780,17600824115390087533,501084079634381141,14054289448481314493,11347699790308666007,5523051425207459930,467690531335520717,3276433090794170753,12546680199609428412,15148225383437692854,11352651092110687894,10159267377012193333,13048271395338978269,9342458830613610771,8852449984030060386,16065326227722889549,10747498060805246068,8780227517457435199,7427125882806143783,16883437903800271621,15742642531082127404,8396060676573520571,13327115878387141330,17618220163961182990,4813135526292128217,13188881392643786287,12444941564646308232,12205739132636371220,17768130444956300115,6778892389933621950,1383512606135652849,16289377461841231702,4119765526491906563,3523677935124044883,11652149595367370951,6433014300267800599,17504576906993785477,14276768306206239631,7973023999057648321,5612462184990577212,6874228104377545518,15592317863725894434,17394338302388608672,16529568226363890338,3417301406366864077,16816202200073606053,10462567305106308106,10251544820539794348,13296525020438388176,14079345280466371009,5958582320385568411,10276476156846619372,12817616411790218707,2891260365843395018,5392016648285770831,10861782281252579025,16642558161033801954,2173331832143446414,12244208897314763649,1803812138598967505,4827695754415103818,354701410273397252,5743158912119209010,17479318222236238813,13831366632346585216,12104443310132298757,7356426069390488105,1962239689118033560,16973694639649195629,351255439713420859,3821290556333270107,17780714638620871047],"proof":[[479142273563024860,13853421838676425999,17829538483207101065,306277362943378127],[15772996337760168298,15702037954096316464,9238403279788719109,1954529616307148799],[11074409001528043609,12122990801023191095,1833640661327318099,1802926233450702548],[6915915986104372199,17237226253477002273,17159495010431729121,1771647507205142217],[2888744298626616031,10857349776584289571,6426109019757045665,3052239301913917141],[13129007302767303520,16407915544547293465,14839775537481465621,3202218263055723542],[11056163118595268478,3684725042508180961,2450778309280201669,2737094789696853047],[2929859332652544356,5934164507746925817,8528857859726331346,3004418361219647098],[1614643615339081958,13801396234458060869,6575795994579754613,2170018061199986248],[15270918330674064724,18424375348583209601,16403049653150833588,2224508713353166866],[13847400891124446113,2789912962675913999,2131806968534017233,3462450050851116088],[8306212057502905801,4513570971440212739,3182621761424601631,2007843718213213775],[14367620299360517077,3486062918649683097,758936314403206639,1603949708714258502]]},"stage_2_query":{"leaf_elements":[1068063249200302089,11882442026989253917,16598719481807649997,15614021460355302394,7506379076357854902,5555692924119473597,5313612885456720822,17052715152600913292,5492782900338946149,4986859106688984958,1417329100356903623,12035853515391713407,13515996828958341120,6067781815398491823],"proof":[[4239934847447591352,1523153707173960918,947121128021886619,2805187085059775608],[2065101407282619212,17765427597500697408,951370742218989431,2952291769760739288],[3077239266353620695,10460148546520307434,10928421332731705171,799362539794338281],[6641030986932040919,6321406314685918475,15870915743050962015,2231969113739073537],[11937930699161714832,15673090503857970065,17941716796520293220,2197409681411270444],[3193710552132735047,783546245270592895,6581433316857268842,1405902862958484323],[16803080932271371360,16422210624616288416,851449020260817118,1492173049868555707],[7983856738452908083,1804797692579472291,10368720521800737431,1193977989235226881],[16629417302031571627,10368903630772021783,12808385451734518892,669650273061612865],[12955806825047399476,6486150578510343128,852423938643535460,2858942042869040817],[5887659399355191086,7174368684729802907,3922383235137934379,3354869013348000751],[17946811300233807722,10697057011455301775,8841411358577018535,2882676071995806414],[9302781254238343662,6119432163943488281,15090348966859265029,530198869118147718]]},"quotient_query":{"leaf_elements":[10284988171387872733,4189004773849949480,4498873592207817758,2045268729650227673,12504260722348189332,362229667912625398,12332483128662820138,12771896850867685532,14904027498999102566,11511941252372562783,706898284636943922,3031441651787206740,18073206506006940284,1470166520887359682,12538034071621748253,6631753434826341357],"proof":[[2284280959934824423,2164326976593746608,18221426433649216308,428119367133027107],[17064158640133625317,5997348408213780612,1198852206989385614,1351483777749294067],[13090745263642853315,1920129779073197964,9069524367401931104,1919059202109128161],[8499003373089262856,927313271566013470,14259912864024431183,2553818611455888254],[776496235608471559,7165566596603545418,6641820051230464005,3342197463674944303],[3181140125806316992,15219027077300647388,6948921430202400344,1605491166387647892],[3496698701797999174,113218878308246532,17707315565548405435,2949429912203421051],[10207134430467833892,10539999020633804313,7051302017273650359,915706280226373372],[4266584729228504188,13676796620947585267,1408597794297276185,2536825408424183519],[6264086271465643011,10371501593482275224,1421036796903795317,2818717546567841802],[11321327010506253185,8618701882431728540,17606487007445284154,2454227746734772045],[13496753780212999111,5601887085332510753,5921920338607442953,2763534670305069476],[8815952717605006386,4526522413909831776,14701097622325747530,3485165681977640036]]},"setup_query":{"leaf_elements":[16084013888982606513,8004936038459084404,6830066682586637124,899645052684504545,2830267448347156075,4135000594702886215,3069620440910478590,13574940762568370244,6714205416247675220,13303208817877836368,18136345925616308951,15595485793382957150,3477639773124904572,6800841849916822382,14071129896990402958,9872506258988281160,10843330454410834932,7882432468261864286,1992559489149779837,17594584526677048587,18331203496972985318,2302811782923009242,17796902774968891137,4833928407538341129,17689852040148069012,1514593447708981724,5704428395692071383,17994487186505434935,4251773488431517758,11379916488500787476,3690358160729180972,8998556365317261167,13667660422881710374,9510444216473157759,6852095934071647790,7562094171684857818,13227169978198459702,407639279664700263,1086440788870155902,15034593807200240991,7270665309461110644,3545005353145481949,15947194410822101340,4496175018790777773,12166547999080473499,10774094167324464543,8927918422639436316,12157972509016763383,2812663864949294920,1504985128057070359,3724920325914376189,16590803162685153476,6441651453796582937,15373467165888398991,4420362878221825179,8352324561016089196,8114290691827371197,3139908643730169201,8800455700078188208,3498677582934793511,7754826867465194618],"proof":[[7962610823606155216,10587365098014831037,7243512588197132938,1272346125059474939],[12836662193847432613,16540632926588530115,1042513543457223143,655741359162956832],[677576805936606340,13346671000305034936,7641841819659427153,3176691352051760474],[10239471945175248418,7057457706631700353,6381258370212738814,89837076637274174],[18420500987205540762,12310026697447372203,1671385397805241079,183968318795011932],[3648799507634325268,2493894060573828178,16109686109176116420,2722471867420680729],[16034663858643142202,9465318648618485264,12591412249778478203,809071420537697435],[15517486621494757174,7908488685528465109,7077297450059622126,2111462333632496935],[11310416980522924841,3807836777832857816,5284541498733480889,570519396226990130],[6666251362431125665,12923444987057555807,3041116118283722521,2767188635987646333],[9892719404195873544,2546647787023808772,18037364276362727115,2571930886089900315],[18281726552398374921,10687318528114695449,13037667625031883888,3021881666691503501],[15649328145457671106,549776313160692971,9928450923310963291,2751020716435042226]]},"fri_queries":[{"leaf_elements":[17076758299368540966,966229203040290253,14423224149310893159,2258574840720366510,17525361482167722260,5729436186846096423,17962352945159496733,15930318617802465499,16046440478118343438,18311794370256260509,1128370347617199734,480841900986784381,13604515155788320230,16965490732455185976,2033606477666006213,1077167749128541255],"proof":[[14578242136451846621,10309780406014206286,7808296213519825954,3278370048524478220],[5993957492400279091,7146943511385324340,12063563544436404216,217723864053816307],[14166957037365876309,8513157137284519711,3250090809821027732,45435760870903941],[8669878570745756870,12879597580352676100,10508957823342845608,2666262731498078264],[10193348020517764652,8439463575271561858,6071046530723178462,3457050750238077647],[9713959494299763104,8209848556810028597,14242202521271656743,207387609604468579],[17847952552214599827,10632105656150254165,13951437950939180941,3403074921740609222],[13473335106084991378,8087828339387511908,8146161747446899952,2141452261045257246],[3836149467745891357,12700830065944535128,17543171510772478243,2771009779489953517],[18274227798351134084,14614972872318737132,13670777970563782359,2498334094624877115]]},{"leaf_elements":[6943981330872316929,13715218787789212004,1217606224335626574,10512546819213213457,18338631903747577963,4285681544365026335,16605770173091648822,7378090824820035800,6012608792151348177,6083903734545912972,6784731919356897245,13957856846731532930,869052712974949456,434773995353595642,2224878072592587826,7688515409374191404],"proof":[[5989131206023916838,7161820572913304083,12769200416168121780,3476101842166954643],[7865163451349759261,616409362945865507,17220761462443780463,1274941789974854258],[11578821381284200582,13509323926933035943,756722498972069517,2974031108541776149],[2353461396289754969,2160859219742795876,7317602384919543912,1359513315536123339],[5367047093430431165,17482935022978133436,212560596756536963,2579869642965964445],[17647726135037315420,16939452995086140404,9926656647162993029,1129491512409889290],[3864735070791189707,8330668194952393004,13164775125511877827,177041749183560687]]},{"leaf_elements":[16475566031165809174,15325392876571330065,5268776904905897063,2968931797061382990,7522997360824537960,2946522724450032446,7047532903998201114,13274673540688035438,1261891468646577203,7289177497747361644,14266873858293886894,6346738787113190240,1019142652903352962,10842787559930328969,15438962912716504324,4636421722503434870],"proof":[[17256920270312594807,7784466799730635799,90433486118535057,3105622285119420210],[4564980509096746145,5089962408011563613,6258795974971092925,2663951082052024580],[8146435607594056767,5057348374914061128,4043163455170630552,490242688245896419],[15036230558710107040,11921162934449550531,16484118682594038981,2366781330473308508]]},{"leaf_elements":[1161939574018876374,8351817840696965648,18372653301453144055,1094858428888221872,17891497325732335182,6378736636084565709,2312548455298580963,11108539684721161071,646629569524013389,4395291750589940087,12400931690617795476,7655909668271100330,16676308543461110775,6945943938750155993,13376778799557250354,2903074057851475984],"proof":[[5616782601955618559,11536326776059504369,7332699799654596753,2141932960124082581]]},{"leaf_elements":[11506617648987991818,868082017674053972,6543021463611153452,11748771781491803820],"proof":[]}]},{"witness_query":{"leaf_elements":[1392585439841913702,18423733222831024563,16224839804986019453,15456101583290409437,4246116753180138923,815064347839012891,13905377810189289610,10489626153712438560,2259160300486896895,14080460092142741036,17448354874341741282,17548870470689013368,12260174825146038118,6740846407013168082,8019577344042753363,17021920327464495663,11952570439497420338,11130685014126165709,11448024605016287714,9529130761340525884,13339210091075994097,9123666933054250511,15532610514264320368,15275639160393045248,15470529976247055075,17665244222676810321,961360892993029887,7873239872422267401,15084320520822627414,2801069055496238331,13438641000564194797,16890483780823701732,9935148759790716188,1376811071139792200,894998197196915769,3971723256836744507,2721407657608641225,6505263410611454820,727078036655246444,14386258407152013606,17056501658306256351,7899770330790331960,10191096183460838615,14299885399074633849,1033181726847796920,10310885305574692065,11214953055163384063,11282412389331867307,8831969180366080412,8309585579518465540,18142400979662036564,651992277922250014,13390301506543501800,3073874700155237755,7111835997218112979,5601503275289053458,7552121508536735965,748274395215341304,11216937264317912370,2230483209157589999,6928762128729625083,12918210165860741225,15622722910303795214,10154648998470714132,3162834089782596493,3388721085896292350,17620035875409627194,14801071746718462854,4253243071019372828,2714701758281662208,11800554344219554693,1652435936526697721,8377100077205092862,13488630261174615298,7256229497716564718,17661547882334722848,1916163673658085878,10058934734211511609,778111998342521959,12327078434126200913,16921477754117533239,1455063524778226016,10901783966415537294,2701568312658637600,1381489144162744599,16528632307972989934,14338038634481496587,11449439365415194123,5314458289391384895,2730787757925178978,10781642951491132766,6525808388532507957,4044900136554699773,5091486047967798295,8605297094133766624,7203908167573024329,2565832979015866681,11019725811795523830,356111299047413618,12925031461891384296,6103867530753961640,2449728789766847985,2160979228981108777,1746112946350933645,2081426487239020684,14993550070507274202,14174755856885833942,17223185495251858713,6513285235540168257,15101223092899097263,16158878869859025646,17753501625612214972,9227880661396322860,13978271442774625385,3140696020298666978,10604691635155962629,5783294069790066428,10552967469154165973,2090853000612782615,17904565962607161211,80692470719188397,10145489522465349335,17508464128949104884,5847490567742010653,1178073814994535080,8959118940792657334,10071126839721100972,16550681783506245871,16889336614667136773,13798867875119684823,16948848422532472395],"proof":[[2395019551050168080,14450503371353262833,15747151336746221567,2573984319162689788],[17632742907064303538,6200851355192448365,10611971609627888195,2932372216223448229],[1156073710132971506,4315676136030435277,14442978106519344870,2844347497951494042],[9076304820592376653,1238783427861217436,7421290059088194200,2474994818304020171],[3907063758900125686,11849458901926119364,7584206361385037602,1685636285278938517],[13858045241177765477,15405882947442047924,2340740437974076432,3286199171908002224],[11994859677022324372,14904686079632182326,2769577283778887471,130066694828546779],[14310637277937097706,10516954110442661212,8903288866692648931,460695689387652977],[13185653855260684816,13539984563226232926,1670608875989530771,1352929439979478920],[50499025161597099,2208612728521119688,12677410341029930976,2349900618766068994],[6014675289067410209,2882854166926367824,6769315820515215535,3414482884817818369],[8812799168192178943,15817148503805171590,7416738395751409999,2656716391030436415],[10824937849326215501,1718197996236237807,14099917621685022323,2178034142323898131]]},"stage_2_query":{"leaf_elements":[5522202759125302118,11603435207986436253,4135029997724626393,16502386958249817882,2221156043842166915,81118637408159089,13218703765091592048,9484473064355127958,2264668177129486150,16910823848947643191,16321649521774950100,12361896658128410966,14354330708074327690,9611747358572741079],"proof":[[4419376120735314457,6130644640593966050,10003619786655855007,381862234426202549],[1831255002395576534,718046150349078463,675977723735577281,1781356817961270941],[2324208182302272599,9293350077001159208,13646931675331500879,1424904652737905919],[6911056795592451127,8758541995049696707,2902408232745965334,2348318725374066036],[2301637309315143210,18226661660573440932,13456626316100516068,513375297909474960],[12806740084793926405,8177713957248300475,5105581015910127279,329497160626526599],[548164878401104604,5094388148857699187,11657034083313039205,408520962812376111],[13081708554729779084,9749006311440304536,13976794579317658471,499596215362247988],[6790051861295762106,664511153537227998,11558359259146203203,3249818567006998861],[1642553001932826346,1809571692793852919,11456521542980429772,306385213232138035],[12810357796317451907,18339731872390033321,1319146508501262775,1164127292591674561],[3442307337701005884,797696030091021696,15922844621379204252,1386733303659964522],[16392396484878729955,4126789946595454481,3364068644797407771,3206984783570342454]]},"quotient_query":{"leaf_elements":[7717407690954739514,6288395939567097798,12918990434391643465,318292099294275348,2145747117350935651,5313899859634211572,12881044454969602451,13226823508973059624,17313990892617586154,5332439911750289256,11928902951770497413,9242592342179258728,16315090653902657862,2794247369480027877,7246623076684616233,2090374435959668540],"proof":[[11214469727315455511,10050332995017816232,5750092743670299703,1581510785519309731],[11438581778261744685,8094051371681974445,1431743899696664813,2379225959169891003],[2063544901389398491,11858928356971707534,16672711907867910750,3215140569994485429],[10687995661901187846,1283654889305515075,16936751143400266313,1721779908804646469],[713033381888482697,14940168328798215523,5019144678938747472,3478117840083864925],[13632300967382530047,15160310671071982813,9758986702575560795,3056519182863773250],[15730237920431541776,13166686830379886145,15048914483412891368,3406557626308027886],[7937130540191623841,18013413710501066063,17276447388665463280,1321632814037896210],[12658722071993089907,17706608705213637783,15708159573467852044,215302790508192215],[9410734011778743581,15960696430613625935,13834292985582592457,2401244792750033120],[14820106978531599798,4898700026691627161,16688866859713747666,2510079936757525968],[17743936867852481363,10113744422538872953,3685837512323243447,2484984772802128319],[5140577020405584832,8343465989344296495,13002851761865653574,2455122082449337052]]},"setup_query":{"leaf_elements":[6801497435853732456,4915647951789807439,16754689809131019179,5354313379665163293,2463144075029375396,17446212997346329169,14823665213317733159,4227790995854335099,15020060112318183046,14324231286007331765,16697041735469068607,842960128641829176,13885327920403043116,9903598287688588636,4777708588521669717,10729677246056680990,10196060179371090038,8597789538738173564,12237485239298704836,17271666227654884208,16656644327833891578,8346035718125366595,7237627179242788285,9659619560958342445,6506457654201331395,17561485754520926355,2994965603651316414,812155764150248040,2345018943169849892,14435679230174281671,11277998539937421729,6387991274488891972,15116173357032098123,17625409293213941287,13368123138200184546,4954291493961513354,13753877427206027416,6109075604146927101,7898116881603221514,4451001508858822831,10611459400613391007,6289185669661472735,5991101376014825966,16370941660214316075,912415259483176255,755912231820607239,4773412346811795557,17127401967084900328,12575823388685763717,10769996746691494469,17688568560743407679,12576306102479798821,5355143758450448408,14738819107747705779,16764166855964785626,17576546423434866741,15994083881281984774,11991025722081665119,13258122692463175020,15669629654714642663,2729727849720515395],"proof":[[18398001079540070661,12761781976170842848,6653497449065701933,464247940309603626],[6032093156691494329,6480175640249573992,17651680094429612959,2307849282520396384],[9715006617914992325,308105211207701560,279069888288978169,2856662142006116353],[6298808368083233769,8174681658929762887,17483901928704488671,894680417754673272],[11371802793674486814,4496684948780552193,10141149141517025980,703259921271060629],[4992424275002791829,11665663224405912733,6028410253147771869,1164162142760367633],[7569479061444700295,13107038814490629199,16642245847442299748,1408503334226868134],[12704649590029312089,4506164920017863030,5670025467525187193,330880658708473153],[1558894594161361377,6150125471366856314,11695472125598998786,2389684867016458171],[9921671147312707239,1362208472988864843,12225205321228228488,2657070098376354044],[11956709791970767239,12433099334634085444,18029488146378683977,824137296371291595],[13600120118518769778,7523264672317453919,8452388071972994672,1739731379094919334],[5756101253259440037,2507236924583807190,11397614503149736527,2196094715248116226]]},"fri_queries":[{"leaf_elements":[8141101898241911286,7801207245275426532,5575891171937739415,8144971451902364054,14886695420517014548,7094935336708013059,5369222692224479290,10760124255744862372,12992767700118818967,7191280884834365387,15714349334758840628,5709944680238053692,6998268985097117636,6459822189978196692,16406481288950336832,684957255879748191],"proof":[[5180207520514838160,4583840745640110061,12917605300157403539,3214738882175304132],[3393305077269863521,18051034348241170359,13305279826705555804,1023922261480880354],[3314976940683217606,15270803868855551253,3141824162406734605,1261448967392187650],[13892899619396315151,1686497672948236337,3413834594285990556,287409804946716584],[5002474575235338510,5586598796575095344,15765209518390714795,3463937966830779230],[473863755291002647,13847999676199913683,16841540213579527711,2591797402766194212],[2914718810302235043,8958446851259421940,17222426953155993345,762325359965816192],[1274556783226337682,16650448429943937011,15095493939608976315,331444902791212764],[16880965244994303231,12506394165471472704,5241695247584061404,791507468751235324],[4203734648063415088,5572606400297625904,11638643099097167954,2149312300932434459]]},{"leaf_elements":[2427445390528398123,8871734692231038848,15226688026409299264,17800142054208437905,3388016240869899195,17543382544502424892,10959911715256795716,11534579342504281997,12190660475331275433,10871039929826296785,215526370005621309,14770869253718032815,17924053886666669566,4267769096787248686,15180463145139281219,16052897209013242577],"proof":[[1969197724584313505,5325631853084969054,17509301542997861880,2923600568162336710],[12051656445990407753,6544973510415146563,1383787745116656119,864332500361230969],[1043335071286060964,9756666878576891992,7881362820265304859,306651609056190329],[10905691566842477799,5587679253825418455,7539198090802394674,234878558379516751],[14938680021002349201,4371257551769188740,6461957125718625433,2407181370293581700],[11708003656034450040,3178081941574435450,16858879150168702993,1298354803572582653],[18104451860560284932,4640583475077416108,3306284090082262603,1481349666398733696]]},{"leaf_elements":[14966554342365388974,2471534931058931988,10695881441739231484,130374336737454511,7763517382609932144,11163089576962639961,5209630413412205703,7113549177449161061,6731938126539242846,13400959355663000334,4482229756934071881,13694678042432643307,7159941228401734957,9604392362138222405,1080769394928971922,8773710650923347558],"proof":[[4112222955226904266,17569729211997010843,14601371487351814196,2254641433296629028],[1518558087098168355,471325964271538436,4500657863054745167,1566236310304240123],[15281332419856728899,15120485917225134181,2098771883856822086,273885078190931260],[3739423148044018170,9885586201994819541,5180594229908055931,2531840889243286305]]},{"leaf_elements":[15859089997781038374,1994857186171601481,16712912127603582757,13210363489554923451,4307184507230540301,12355014920308439175,2377906283639097493,9636889481462111568,15689506450144469148,15329674555091613968,10455228447275223635,16353864476348180603,2431194475576405329,2637549350951861111,17140631889297147002,11070667164652724216],"proof":[[18273848792544346292,13194308337463836707,2821939436018162595,1287166854450626649]]},{"leaf_elements":[16775312693976535021,11906390845590027506,16723574221087713398,13884781623836882318],"proof":[]}]},{"witness_query":{"leaf_elements":[11596518568050856038,12755458845198254158,17914427772261172929,7675738890234343874,14970266074695326092,11143782863552961142,18010028959524783422,8187185931257257595,9054592257750750478,12892767048129890518,12312427257398342793,3754874784475797477,15525964699741961960,7671972336986424995,13714971803321909503,2019684007835885410,6807284498992175955,17882898764529041191,3328106790734478680,13701485602527027741,12156843363128127484,5355692238437124432,10470128735808779638,365712529909055957,12646178183042245345,6009476224981704920,17090078168616043553,3641536570294853517,17438433234143609228,14334853910363827705,17794565508604237211,14136415738415445209,8181842307004869152,11922584496526440055,11109173435924297171,2453445449711421001,9350477233936583384,4216828328340471823,1967676436644088183,14692079034567375620,9536268018809884581,362703251282581881,6312696805952414798,5593776405338269245,13264032916984738445,11881298794208299385,3838398417038314726,11597042914515994370,7117128002200152709,18014990144017735935,10885211317869026430,3157522008585050717,3296179300574987606,6740376279323546470,9789982108565657195,170658594562474756,11254048188690292811,11900283538637003132,4918851050684371190,11844555625627944393,16458603579580946721,12078041030031080208,3645330528705760623,7370534852404406656,1303232251586350401,16260292409830868878,12294575062817305416,8183662374097435530,8181851384689646979,54307390126966163,18433013778226424333,11784205992062254222,9789876668182579791,8582952456896919588,4284207646417984876,4509241830299689814,17819019949484307872,15168012735187592046,17964017668813023104,11780157388267567011,8184289902547225972,13753420186611081352,13337660516718241013,14754220874436803910,6126624637604442369,13557476092206217863,9168214781220226026,13138397852347780121,10157752764718553841,5970078271386047988,15575239917114477353,11554117558152146879,14871084970456705676,8530567416829124475,11179667943557114767,889846157106193800,5234874172963797326,10805839349904065108,6454321122815605746,9444808323628326901,12245431467078739220,4243597563276166296,4694495240454427757,262512993369526888,3618526963100621105,13602137908579456584,454056760102781138,12079732210066579226,11427950503723488246,15142411482944216458,10596822752548536710,12596677032275867947,14173225087146253394,6296333037673402083,15361907083514642184,7818119805285559315,5504816254122896401,14583913787129219294,7809403848149787700,2087510024328542012,14846952497102704023,16373545937289729263,8873809366868422788,5675803858763621385,13558708186104080859,16307254597591556127,6275018441425063441,5378196908136322679,8720659144411825148,13778328951657990327,12730340495489630187],"proof":[[15549657008524968520,3504042209373079066,1452544996211213377,2684831060690091472],[13742472361333542290,7093982294921360128,16753496132696691787,1960156982302731292],[11107546881685874722,12974452672603462469,7165826494267666343,1160762928694788806],[15468730129102180926,15794804664029950493,16286233507404686164,1519673496203625660],[9173915990619188269,11539472056992750791,18203498651788388706,2051095534787701297],[17252620829481876078,3203291145295325311,10526369891822711091,1774467444039803175],[15982516717162784087,770789023286021068,8007828152619140489,2086001694246262318],[8339819429636656091,16963359177016173991,723928136042326478,912919360381121684],[9762858071388125781,1465848833213318480,5205048935631690374,3396874570418348037],[11543031132391257854,3372475063408567465,11427980464171863138,2090715540199494252],[4191256144832005274,9915222063909787702,6279758859485441310,3361022386994292658],[9644445524481950472,5116419298525792857,3413875179885627002,615924523731411124],[16174210416781440038,11224782680825625613,13584339858344595283,2293598389344857220]]},"stage_2_query":{"leaf_elements":[18357624237441986422,2199638636949711653,7544023032102750180,11741177151337504476,10793557444159068766,11445268538349224965,9579202765585012520,7976649199003738326,7044964927837679299,8828611229521339368,5723614497813765161,5695174660395340807,12608295352226312465,11171225573819685834],"proof":[[3840794058827635002,1225950571688309917,16097782830225210621,1263644015218664177],[15816804746883011235,14735609667892089118,12024975470660747781,652357797523494093],[3358519527756894198,2849727471150152134,11027939398286332686,1529110596168058539],[5577580337556098565,8743845741004811353,9979409452751211266,235449736026474548],[8829030710998617355,9698140525816687392,14798196395157527917,2536860906619480171],[15440102403327527054,14366642753713749958,17006647282460610453,2930661873441771074],[15170939506153414639,13477741394147641378,8493830027558714125,66629548763119170],[5611008531704958537,17258659528405837384,2335371474098192796,2335299178510563399],[1733783129894659166,5479315776728833169,10529952119559312639,669714573586602982],[12644003850791733368,12635397391450601328,11000105485075310288,2530987008030024691],[11539425922428798229,10316360602384796063,13626081842303084972,1387159090695357195],[3985708731772658045,10754460169425816107,7293852040011809602,1548978186074940849],[7143706776069384250,15680275494194306607,14480354172152921765,2190139242083446267]]},"quotient_query":{"leaf_elements":[7326904123016153303,6124799226547027417,6672907273742188121,11455019694052031882,13167714776959209296,1723561250420222821,10580695490205723221,5045973737044395928,14379039501232526465,11074460960529696470,6216668507654961978,3023070726277923155,18046160696521222475,10335875565346633962,16571793330272082200,14455428539053938303],"proof":[[14226980908699115950,3976136894007725954,1282068543119412866,711134770822053428],[7727852593596908070,7410607732743987373,15131258305169050034,1027706594098247516],[6319877291118508919,6725238968957948618,8234927541272436047,639273933820090350],[17363699305233005217,12441243934993108137,4275670030437928957,2493920650171549825],[16649462744217130971,5865905523587259664,6976950314710087709,805804844988964679],[6481548314053611955,16194619824332195323,6631682270031474538,199296562010431472],[15215976167458387717,7602163437268211133,3509341978187683148,1249250303263610780],[7558560123952608728,13244413176990989015,4878940572116545979,2577702239945728963],[10441093713558558436,9736052404222157972,8190712311345142212,330990458449641070],[12393370337620996100,2206623927400255796,13063982841285469851,1794440939324263598],[9069371295911015324,11543257235310531452,8197221623342521355,2888971259919567731],[14096135276490114937,934952086452724518,13685357035753289720,3464441529743507205],[893769981673929871,3319556979175080647,7336913751317520875,2767808378512761087]]},"setup_query":{"leaf_elements":[9945481527758130186,16102832343563120050,13532246229506059186,5858019866543914529,5692953674286473650,15509367855802363157,3763617068065392232,11488478922364345399,4120839411511383547,16374371828771833523,7189563768965221889,5645014407437214225,11190702690144630357,2861400451028048395,5864467485718888225,760375601433638745,12736518939452187634,5114131981361573834,8541807577570287426,17824589677268265936,8476620264570294868,5996669985851983996,5300449157973902286,15674903069002992208,10818887716613583368,17354422994995484844,13294525546675840225,10499057117219699912,8078762413272855914,3492046373632554788,1896816605209695170,2946418580619096748,11540835241815025391,10381951261942270040,17610259584620876462,7252101673979836985,6273183373678807980,1802469043846153861,5175679463942557902,16210100400586501263,1207176365337688166,15573147698677414560,566800774536433761,6679834999132939881,7490642106355923087,18322683762645778788,8226455307438150198,15449528118216156485,14028483004774003385,2368430477530764201,8231187976573592766,13433633944212610889,4188710844239861448,1886012977135134641,16177784080829642759,11173071072492329931,7637447334205354084,8633333213441431163,14346198597192263312,5995044027846560685,8415174315817406624],"proof":[[6014201907395507170,3618686433353329890,9503011021000919611,2610483707642611166],[14372241249336990740,1165666016737411441,4071525561898712063,1477238144401972836],[7467228333681986036,5690760253068148739,2837471318171734336,3403584388343384291],[8364453058071372483,15620413031408070812,8689013889239449881,470833638716728761],[2566584062079198516,4193119190038786493,450264894369992753,1108561725283575391],[6741415392291048885,8209441914089437817,9426463092604359398,2716592022973796774],[1665666486676151072,8550174627705387654,5955885602722597104,1122685594515251084],[8468160262225148582,14333971683586568391,554017511113799209,2921295986738583253],[6188922933525595983,14466443312754089481,6514164977164929108,2514780699592481942],[15676321607272174715,440492761365860235,11412702081222980020,1231556104830504558],[8677846826338869903,5427765284300324242,4714913439232743932,1762887376331384779],[7862272296835307117,13758153652198257213,11066006271944237067,3110603293053479954],[12671376312025887274,17441343524713900297,10896011836861176681,2912297064607346901]]},"fri_queries":[{"leaf_elements":[4044988298516733108,17105711088715517763,8029669423334845554,2243159589292619375,1931263189025791502,466921197246197164,2699102741958398863,13260525040258539637,9886711166983944466,5430240903211064036,2476228138099411295,3673825389693468312,10711774461527842479,14725796635385345244,4875310133497256950,12597357566530825361],"proof":[[7502750866136697098,2648333110560061234,1582518249471823416,2078067953275576612],[12255067065363132439,11883561587997179942,17211720343168383349,2529124380533552581],[17779811107903674050,15209088813787226758,14875272043329136991,3217370069035778224],[13399152694978881312,9546798323104122199,13277745734665367284,3271828369300024124],[2013520185885862472,16047132708294304254,14560134033273149505,727187883136753457],[3310867745847639932,11893178006863931600,14634459014324465186,2229301520218512936],[221197179113758607,10670223116723873526,996527548120598714,511127097577215588],[16933127110299226565,11466221292367671163,9838422806828480489,3170864960091036243],[10672073706590809111,15948760533067443828,4608531742732004549,1167752916355856979],[16109863426784669012,15963846919760798386,9142194185212147107,2313643416305218987]]},{"leaf_elements":[14928057416412781656,9251451305803729490,2087616280853457403,13484438126509183484,17167146442720047798,15093036115773061114,7165487130060919622,14779028628889559046,5294164760412174307,2272801323825790989,12067319421845823677,18079829104103887370,16754003232020325912,6849072506849166135,10296934051934006520,4186244169700244140],"proof":[[16266727134439819885,16258993261191103596,18102283598536535720,2265093101642646566],[9606552967093465044,8162934239356731352,4409827717775339783,1612707312234077765],[13874483142697052307,1352026522605036386,16586681617684642085,270116520827438013],[17156852610994765851,17269668289823375658,8206103851870634527,2672246440067815470],[9681889145106072593,8780853507047804146,6894027738928297951,1164763262799763370],[6104261833129659977,4895313453845829034,12725742286012740408,2424891684706653051],[10344127557781956199,7906363140092405288,5982125655274322770,1672165157955432393]]},{"leaf_elements":[12535956480567297718,10649620520935423708,9908702005832026910,14177578903915935141,14539206836033674747,15273978808733878513,9000443213065444397,13127899233722707873,3118544485616892007,7695207388473263739,13650062305645492989,5603078777168836203,6480226413365864298,943094878451497416,47222708529300263,17780879313766684631],"proof":[[15944290577369265171,631523402255762423,18357309078319467543,2691508116619170189],[17566745660870464212,15913787990054348328,604087449651909264,2388586265810455263],[17340377091611705279,11968596905046334040,8361551254700181307,2553393763160504229],[4274407429085135596,548774181466706774,8603117836559137571,160198004595477839]]},{"leaf_elements":[14694649177522924455,8970524565615133352,6698130501351274130,5407467138564220850,6709057259898075644,15065386984471511193,8847484406550740690,3130960100291456344,3694217830831795275,7041401053929351398,879613210345154478,14654620960715256415,11095625651784495053,10579595773725487118,8663536013231766845,10383856026212629571],"proof":[[16046369096493514353,11215590715117997524,7658673164007518840,655039943382377449]]},{"leaf_elements":[6485988802393016559,12130974100501667025,3138003141619716888,4081174251100168420],"proof":[]}]},{"witness_query":{"leaf_elements":[5575038896445247562,11098325302245653685,17133683449768992930,16353259677499689037,14634946934792682327,396627564681664282,8453193727548797538,3782754567755429116,17023947006867331054,14675413505038771702,17509333279048518699,5740732564275096553,1169645642723530540,12097010756594458322,210787582442220802,8506136285889715143,15365675308480514326,3923160988150175955,15757170303791905667,12854731220563214205,925116471989179387,12793504566483768829,4923587995327094420,17797364220246298488,5333929596770529808,16700500379445292086,16126923800522079780,13447563992993652461,1056726305372942720,11514840925868825233,8725267202833974264,18074178525144398116,5709529489930433056,634413696060703743,15660816699263366512,3675574368498939662,6393722084523403204,11278904608949165658,11535634353088165068,2024256260651198545,10353487444967408242,17780936028891684780,16959271240764697964,2469610843385974832,9127691748315808160,10259509002164047727,8032176464367335265,2223989988237349605,445769831464783993,12832195549047309098,11168861987834201507,8047844883084541736,9599111363521012833,17993694605698753369,927032017825259511,14548593580364863706,16895627301794554930,13989893061150054119,15475196861404382187,8712122105649759680,7722936693401874052,16473776110274355473,12258811519590533105,10745191367683626971,13705587863301025635,17077756827969963573,7992399004783523917,14830544869520277743,11182158475613185881,10074364395801651201,4571745331496934435,1564257142207880804,5826862177965134618,9335906177446217035,10067608566771662966,15837055919479443289,362983673558148480,7804952371420998283,7713835970534062809,12665367082533629927,6732061355941693763,10525050965389108675,13343968583604420797,10668624192416046630,1745192847340191062,3951333869766098114,9042844253003725190,12841739969871386154,7910143774291907224,16493633434471573975,6590764015481599527,10987749031000477697,4369297271835579008,18190747634974297497,912126024579212447,1254311771816779257,15883780810297270019,12543896148540513639,18018108289064539076,5866424521558669609,8091230589129164889,8880549659104994355,14072087867807978635,14935303733550751539,12255637564578358068,568740994376330168,17798660374049656507,18012104933115897670,5935047078533847004,8362240684952704018,16352692211844488175,8983786063415239485,9072323555036252133,3951401024752792358,17792877251270698364,5956561118044785932,17411924989201403509,11783361694425925305,15604374301070720689,2202560268003527994,6435727120608831512,16368886839357558256,16951503155627656962,12857721965426983760,12104654317843520733,3632551214448896160,14341514376673140713,15085607958402593966,6135126189403383178,12615246399026888125,4268960589165650025],"proof":[[7720000979888172328,14123994398394299834,185635331534512083,1640874506978993719],[2295372922971128744,521893800290413473,3348531737985781307,1937472965936695483],[867042229825447762,3164468818022115920,887957378987907955,577935423788523106],[14143517879962087800,16089611203141513647,5313454929328682358,381516236706775134],[11031395110782136298,1898385487814441992,15037274747758316767,2902752272997645315],[7371578971353133427,14769846255401276371,1242125896588497574,1368527074961802011],[11496175500270809736,6531081412039885174,17100950535852100163,902811689610825165],[934287682950800653,12024200835861669296,2395714854962153311,1736327579807174811],[1281554673275393036,14145867268327546649,13119778369171145861,1825671802834354142],[11955244089072309238,16274185217521274724,6958034684425131627,2878010863148156188],[2853992209979608543,7480421103751381478,6266145427255707523,609026604044859261],[11395209662662043513,1193952028845704783,7328494175882249763,2550616215545667113],[16588491068607937261,3526966741617928076,10392695706853076554,1484301400438308297]]},"stage_2_query":{"leaf_elements":[4981183324774549839,12675567746044210211,1041782324036530442,2255611946983787739,6435248969028338375,10403994782669861345,11734369503459468070,7653017198601972866,3746112464184027164,10179612760099500623,1133696311895222602,5116908640343708175,11997938232498284077,11529166166379028082],"proof":[[8231610012930732422,5771998389541200935,2230300104294598037,1854193759979263244],[4277445103244665901,5195086077883573295,8027255724084331711,1559616921839639678],[1399887672584275131,18094912304704349853,11591508182332494027,535743276259009723],[15691455844656267386,3095768156469673826,15651602281428688898,641563871665958537],[16441341131043756683,13065423973910502044,15744451502601480547,2987234395867788242],[1728782870333927756,11667629838455582305,9762057932000216534,800412595068406580],[9113506928561459210,6015892401173274654,5839339827906556424,1440164537792826236],[10624722560341943450,10867162268496348346,14333609325572105413,1323181526741151231],[6100827353699827898,8680907872809107107,13649105908619058201,1369699320728049867],[5267911691065447342,15050866534489357971,8135597120057048811,2046478303567617368],[11783098937363174806,10444382783640076073,5990283414820188862,3446747531802190182],[13453799667936609752,9408999572463695881,1267418068921507325,2811649048378416322],[1137189341543078283,13958353513130400171,14826580562953365354,969106141811926692]]},"quotient_query":{"leaf_elements":[16469877755494216830,1966169187529430099,7081864181501130358,15490342425158927347,12605734264248174916,881025078678805640,17638860079177265581,3672825826350537712,8836571831818084948,15555189282897768719,3923555089582030347,10855861763332351533,10102118839334936982,646312211456803284,5137267413931610619,7850255259789198780],"proof":[[1515119733648374971,10316010818082800117,8391808641353445631,539331326618327221],[6109999896701541606,8541555419585955332,8141426972134104421,26511332443474835],[8154497452557088790,1585168807508217920,6453733176500495681,3388967848157289616],[14939371418033383214,2966799676819655101,18123804574773744675,3252703824988904966],[14571756881279911147,4454671129592058991,17730527630947579388,253665498381759488],[2174857673810731725,11263510854561271523,17634387444575591157,3384764181454049850],[9522935485662558395,5772307320009326810,13188388307487667785,2961281630081871137],[9308900784713345305,9800412891750074528,7512200762715748583,3277251260189019418],[1682848634186419984,6803015471738318258,605019267689011556,783698944507546709],[8658902292368764436,6873892523014575974,15496428575405464873,3455480457979335407],[16205960092201617632,1858647265064593050,9242235220739230545,1027400683482998715],[15752324323616957754,12779224907026990562,12892007258134896959,904790612977146347],[7644633979883049593,5553498988801646622,8610663271832258607,822488044543005878]]},"setup_query":{"leaf_elements":[13438659168168928039,8015286436154703063,7990372828183818141,7762798928547763732,16389571341722378128,1605755009302160726,1999929613161514550,9493030360510940434,7264384494882267363,5679985782291513324,17915630003185729613,1884083086562275080,7002690653783629773,12417451864015137755,7903875678910572962,17926324152500168986,11501137136858751048,2071857590484402048,4462192077090867602,5566160905113570300,1462979005906586731,7830188231633434825,1526350064698471471,8426198303008220390,15764124876699141745,13332443102219650530,9638356217141106070,7384849256879549045,6493140790529497845,9615555682411260887,16870967581635035448,1701667869165193663,567357005973357301,11290515043996069131,2500999379127797174,14742087343391071081,5829928881081806492,1163726733213955818,8521151192794490176,14982169329647753986,13072222418204103496,10826828130955075121,5234930108396155713,15336288286343949692,11519139417399954446,4573856990130300419,5698563147905352346,17208215367473200292,10298217655217550534,3449889356211825506,12027795387783925616,17906752209466444266,4232814893700734499,5074872131803706702,6277667397334544622,13185290432945891524,9607220303091150643,13518749179691888864,2331681119670318075,1973480820231892814,5796505715373363596],"proof":[[1331133620160458032,17704355859520208380,8425791644587104581,297076619169368497],[14890196932649466051,6587065349494056651,1740983125534396441,605961594420093622],[11435869809684739973,262104332337220617,237527701497641382,3092249627556134060],[10708529428969847400,9314761344253057106,4517285163691538978,3079400392545827554],[9244469499433050576,7317725071125242956,4354388839423859595,814821648531861455],[2459765144100115651,16664547666953908382,7841139148405846072,61288242280657680],[12364411129204075522,6991856826408851396,7018752370647892837,130857268711805084],[12435134771692829454,5975989111264023255,2526407986907465578,1875734274204884756],[18033546302340972839,14423213476732529326,16246037090897051792,1717597567226411091],[18241057233340885498,4803731038649725236,7394498317798674985,2250054278306788662],[7159520266936439876,14749332712915783770,17912632823641890013,2783056856267458238],[486818797389721267,8084439847514817549,11236188824456470837,1459116569331864959],[17233809955911081924,346565918454960805,10256110933992363603,1021423818581111110]]},"fri_queries":[{"leaf_elements":[2856835011480465781,4919461246840178835,11455889028295827781,18096085669571130929,12984666988841455065,15146034162179693863,6581794853139215045,2264956214128562931,6614780043494067974,10415186649216392644,11523907538026172704,3859032991479802453,595740823831033701,17678520066412902671,14906702389490616933,8116344719116128166],"proof":[[1893364706585211871,8851297426931198076,6101511442253287799,476474062474625575],[13559343920712512527,17870973518976595818,14187969998841491204,1644118139111915655],[3614965705996492760,2613305768431179437,17285613091327274314,1612743170234623086],[14959049072461980782,4960260986294212814,16484084870450252263,793019204785913425],[5933027166563636015,5723313901122767400,15821905126435344526,1513233618525564695],[5467472859565875702,11895483773314262609,12881362459159527124,2610817678137105324],[16561004979137886812,13872102757749160108,16697433992167262234,1773354400604808009],[14992575685687128963,12709149031323741069,13640315697743379233,1015385893621543080],[8102852523074086294,12167191959051485489,987731537766481809,807813579561528140],[17504669361731179974,2131055028050421148,1385363377788465903,1412066716416574165]]},{"leaf_elements":[15794408177375948347,11307795520311882554,13450368065233085934,16824760126351922913,408974141518472903,17840135633980907895,11207357300035922554,10191863000124261177,463432909626314584,6379435042446119330,11712048139768930518,14169464165082657368,18321887000439203754,17745595822791931340,13351266770975207506,4937317504290477811],"proof":[[11826869622680159819,4210049058943241398,3053699576099293483,1864477843134944470],[16586906374203687430,16262572107520224808,17971830916532773394,101875466986826117],[17605145175241943502,6037298622006236924,5122345727363921818,1928677489693141221],[18182715813624259210,12851953572602146940,7910441234876407214,1128572664395105857],[1034811006155829986,4254908152578855217,18187586512564442648,2387292835542340214],[2131054147592230459,15614884782830478317,10463509545389308182,200991098452333108],[12768234999023651365,10129420054475814617,9085624202641957562,2813036854653805665]]},{"leaf_elements":[5224070489114068585,11741064992239745195,17457407556228431647,9939447143783811749,514979789292475085,16503659610491085219,867782230446166473,3445183516413990655,670270436802993874,16307827597579008724,2517692840552953873,11270576333215412393,7712938143145232793,16650455890165790458,14510668937061869231,585394501900353866],"proof":[[13219592009834583278,8147549885642118323,15149349917507242183,3265829311472343720],[16532808132867334162,11894728293018834897,15700310002404958182,2634178845003622762],[12718046904109163356,2264729531904559187,8794836354474897212,1277593160709481300],[12224604233216893620,3883891059941308031,1780591444954729148,1399256507324657499]]},{"leaf_elements":[15893017159368408170,13726125840665252010,17148517059027992310,10710769517928453429,62468483247850795,1706573451560102365,6329054516726111507,16539953298218191128,7256712283437372812,11674755078445890482,2696239738289444223,7519682009745736278,14986697876302099271,12120225001183003578,2476978608143749707,14668648539203632694],"proof":[[9243350332989540492,12504692849143041848,12202608967821609829,254256006803436255]]},{"leaf_elements":[7065729504527910035,9780518320697745842,13314892057648005417,14505346905238107109],"proof":[]}]},{"witness_query":{"leaf_elements":[1215001383032048192,6103640550078932707,13025597614303739951,4868838116283390367,11762296430279128855,5684890533556733947,4982572522400289125,10642595516310076606,14673789584735160931,1482131614986893133,5596673819736708652,2474617296555563748,9145619047392853282,16982869917070076858,3892622880181221050,13297721050003226780,10707791584266659375,12717381470180363801,15359847939544782029,7005680151778864298,10831696111713193045,15399089351720202438,1507022277337711695,17068059500876562308,6537805493655989495,6826332066363460104,9582929504419754523,15859627148605743435,838169172582453618,12807013270566472086,4698888512741186654,14551560393499638890,6627200524373426094,14240085208301751668,923680440088308301,7936127178416230263,18020274294303814539,1454841923672690898,4708557169749715273,17253763094316203744,6712476547339089674,5171721095920473003,10998144205583349250,3992206868279524211,5775137878845358139,4718529134010224859,3114891654685885224,3801001085532390068,9303518463560583168,4911033835277032921,14764582868062931621,17513653370200647562,6159959734217554521,8960173697723092226,2172493150048649690,2998483259721581405,17980811274358523712,322616837360606197,5375770481788704931,9570046941078382393,11629409403081776555,6864393612889468294,10218613536218477720,3515654483241231956,10384216959756187988,17066966274527385278,10304064446155897309,10035740768278678517,16817473706543879969,14992223831500147843,15261400016171917172,11427325180605833969,17667649090054398618,14519377115872692973,4032214479175016878,5736267368648890341,5407999627920558642,6462489248709603592,10700751430964330892,15279993627878018706,12797653241277594746,17437247032546149231,9899994928161582143,14767529820607571661,13370553325682616462,10907617809091779693,7361225411391135306,12183103407542558352,12467457165758111314,10925461732546067313,1848566868813968215,7082520027536613327,4344976893544498353,15279194096299045618,12658591787544795535,2030931625637149456,18261722800633644533,355461737926575664,11234007551329453821,16788057886299593794,10287637027862279269,6238095918950126807,12689119851482146652,12467538748724610362,390140310053875341,9383212947786603578,11408219843499108590,17920422500678483871,10421251558447501019,15846983383048256280,17750863112076975030,13497650762078792262,10471426686378174031,7800994413701956010,13545629327956099629,8915213735764185710,15799636738951486187,4197302252633617867,17268581622890544272,1788979689460815377,1467514052362054757,271210876365191028,2092162789368560100,11643933083794895881,13450098881857520650,12046570276400748488,13327907258672493977,17362864467847027600,7210299068690515282,1404802756094182179,5444372967512579683],"proof":[[15721844306525670495,8986019258970263996,16447385427951718805,2371328138956241418],[9347672204253739491,420150220209609158,11936004841552137733,148260908047937397],[8768674036788792187,10608658398638827797,2036271073605310136,2103583295874392721],[12493089384447074728,4510948699141451849,6485176626250753421,710718940788970952],[4409712369220239400,13977345140381965144,8901668879966374539,2281847530147381412],[5948689413171805977,12492725328308169833,9276844952540086039,3106558124412036143],[12819794916739253882,15508517348550795793,3627489493374704445,1282269169595592489],[1450573994636917181,10624083934349612088,5962359723705977402,3066700701614321295],[9863206242119146222,13194082874406521960,1475218077905374445,1756272685745407812],[7245279328760343895,5811176660057094455,1603635321652595093,1524156924964331757],[12036199073822799947,18344382032541332774,1150380077402298600,137757782090781130],[15056798879279227557,7642122615035966749,12396778318454286618,2846877088663908415],[8899754350472755776,12278932612733122602,15570693645971944066,1640054857718498562]]},"stage_2_query":{"leaf_elements":[10465981481798473108,735207257332012324,542679668078926140,11322947299184555078,16759480756092110673,8784430972503469621,6531191738696938598,17481415654037161950,4820802744820410139,16706361297222128059,4773939856909994627,12535884840978379143,1475478577138856685,7886696844299334129],"proof":[[16073814202852222316,14778245098081070271,6651687737078997231,2213132735571181231],[14005026472547471525,3121823583135903880,2261304686018702752,3128370120349640918],[8396595188168362447,11577523570686253992,14761828824182278688,167264701407541168],[14357854145481154580,16187215450816250022,6266536376706975430,2494986337728044104],[3940529663744603579,961906719058944224,258145945574333030,1584681599627061968],[1711565965163826212,12148443634418703794,14648012268521215761,2829018131923957802],[3842326100042717011,18325390735605480848,4359630179184651986,2189315615811226146],[2415440017609913278,9475443225397536599,7554261458078025295,3122366063351512870],[11186613281271210903,10373904054617679514,8765985318898579051,3319300046170545716],[13339117596973325593,5125175564976215035,8195156164378609410,1988983859891405696],[6089297347779533698,18288578288688712260,2464975423208903473,3381181044776058761],[2202002661820034453,14408375113858267240,700400200812454902,3451107817587353209],[12572859388325897636,17011840285034537662,14979141720780255310,2732718184850494243]]},"quotient_query":{"leaf_elements":[17825296785197578064,12250128734383074973,4867485579702967439,4284281640576972275,18294989351992912673,303897133495028776,1850911559611504940,13386764926858011541,12040701991209219526,15120176496049754999,12589828780494574359,17848656615253120170,16970757292988616122,16692433657436697360,2725874787524519786,11604811981755132861],"proof":[[5804833009483343589,7257443577809140464,2325159954357278679,2560354405676676935],[14178088466402975871,5406450458448559345,4310154258101263591,856013014486558863],[6767631633864407656,11093365133541448923,3083871483755700898,2663271744244236718],[6651089740757155000,4875528830853113498,5077123875187354417,2046216335192354993],[8247285594259639087,10675599350191214014,7551880898101425378,2470076634134984745],[10559951582219277264,8709472837422501758,183276731548429261,1517134192057281796],[13022927862504347509,503571432897713891,10687344655235423177,106145763937663356],[2204327241266416142,8026548421549464797,15352385450152997664,2774070736867018436],[10502825225986662242,10424325544720827384,17116562821988333022,3412526797174201844],[3196276470646850580,4004690858886185003,5966741146768215072,2142909305153113471],[6785880900866932520,821620509556502585,8656418859660568549,1427611543780621878],[6901920785147334066,12856560133237768599,10764700425195042763,1166708839200723743],[2322302405481175655,4650094345301116407,2541181434162447780,3440250464316257291]]},"setup_query":{"leaf_elements":[4700713063647460458,4825163406637274714,18025497119368248496,14709729825927490806,12900237827493039000,12290588654861011581,12009412454345302001,598374426864793624,17012433210512560298,8562862743071266817,697671005959623751,10794953758259582951,468941820091890524,5057567429161613572,11496285597429603848,16858075465274751170,5955595134470912636,7722650457282506664,4143825304631077817,3898105361719791138,7640751618274640911,17640135446603031618,8675530093887683,9646619112334640883,12560860918746523358,8564863237752721272,13694306121818325210,3465473977927310529,12875639431661141301,16635756735252960994,13198844944769541192,3513310936153567136,745964587776035249,17018200448156306501,15380253017152936062,10138495330454709617,7523199322251016964,2865628493718131569,5709000782301282490,7517193238514272400,13507718874883642911,4888997445058934093,7141432660954653749,16163442370825930500,677918272811083138,16552074039024109194,4275103255614744978,10469828430343077645,1164836606042612867,8786419420472289709,11848020664208334871,13369426439143906541,7399782243604744344,13099660385549820487,15137956398068897614,7600960053084153405,10651936226523514510,12714907361768932366,18410522918376988202,2818445444199346290,14023444587635018175],"proof":[[2888820399888217134,9890884505984898016,12483101221848945390,2076449834293950496],[3488931677710094405,16864393773213304053,13543505798507928878,2879892181535985135],[2995119719629856287,18324648061042124335,11000218883768177791,2427491466816355951],[17124670353761547868,6895602532587470286,15061520573820950810,2847716942417014144],[7978712398182034366,11298756726216905244,10796020156527728982,2970447912205747022],[3541239357772005813,9493194925227228188,17199486133256632489,484007383985867609],[12226512109280665502,18377379454113881035,6302340690777882002,3168535848105886281],[663669195010847064,11832512777230573183,1121474876419550544,392856606458465047],[7373791671506509467,17237201314606505003,12317503870830202867,1406803425834533937],[14580317445988625856,13149130945592640029,16604304107363690250,2841140179067370039],[1944238263364572460,16944590141222724672,2731199171487136026,929417722718882978],[8184583848188389689,1691925751284768332,4808945709990961020,1954402464110990423],[7393247476269389035,4694627994465087610,8725146533108150334,2229767323800595700]]},"fri_queries":[{"leaf_elements":[7749187509767029292,13252891345254679714,9307637443607343155,5828450646800596814,916632668659395818,6458035464258391229,6125397420106890663,6809440990995835377,1536651100100820238,12195229519014119227,3466812166242867457,5905356438217971053,8563750000199967202,9274147101843088485,9005821596535752984,13196004989815497622],"proof":[[8056930210404646730,7435308696457129121,5097783615378740073,2876169443509424612],[16828557883431877469,3423575560352973137,13925568908627070106,793163425668124139],[3855097842341130231,5916063159946231560,11256412174030430663,2196884434161248191],[11233629868580638060,16001146981040295497,17338238406503101674,1694665572255561006],[10332763375431650461,11063175572016992389,7212395916553313797,1363196769224310734],[7408005092659803064,5208385871320286472,7516922882001672374,1179399835552760453],[13809049362851506025,8607923437647402370,6301151890285172059,544502475405482617],[13349775921664257113,14150048354355143187,6461649815032889461,1502093382481396807],[7605375743785670799,10185895542438624416,7815638543420388253,3054178810126252517],[13909292638786716778,8970587721766887481,4064072683418480103,2352438592939364893]]},{"leaf_elements":[7712267997879279470,9472212827475411714,6960425966514436288,8268011658515516923,3756722708976977085,17824230482320491907,3443242133638358007,311691735506755798,17252667844409808683,5171002681264399808,13718116683420749912,143408120795613970,4664540243541949932,2918415592347774443,4076331129018653977,14552283708148115366],"proof":[[16002476354896969727,1637675569869513036,18035656005892348841,825934726762370533],[4847709282463754910,4175831001744885057,15061963814206782339,2827269874398203816],[13523793075301788403,18038620006543299865,5914085807356195225,1271185905648154550],[13158986810215683201,10792003983509805572,9763759046117259440,3200939465432167230],[12813882369894236157,6484739813566793012,7796420782761195941,129094952693746200],[2137973266876116548,10812798778330061619,1702586614393510203,1435662129826923283],[8219660059199024368,16655180989667732883,12470720334809693761,3261694339373339859]]},{"leaf_elements":[7609642428281801096,17005821060119013229,11823129476702904261,957512364212992741,184476775746606850,15607448156848144321,17715979604102664711,18408588747795226494,12972032159496124287,439953035378313170,10656303046645347390,17068679234718264430,14046546218603249124,9296731761204080269,10873591382654756613,6525842527898342333],"proof":[[11606742728350261452,4189862011412764281,455539630406906637,1064856730530685172],[5460207319851950092,7473606203375009206,8720429620102853383,1374949819360850622],[15389039272882718662,1220524723794399443,3027321851306010981,761737478691848471],[14914066784182050162,13218321865492874577,736393783097052782,1014363730706131245]]},{"leaf_elements":[10843563837985374749,2934059280078601464,522664419033492028,9663970885524212153,10528477958991422926,17612037856198408780,12590216556634830341,168568544817592541,12645274891552093570,17506125824037388715,12658942764876917960,8356328858488461741,2074282120620356578,8773718658183707819,5723522309117596141,7469780649577961051],"proof":[[12374258612337946155,8133723967161758545,9858584754587618204,1967446838911406840]]},{"leaf_elements":[17499325981881337266,17599898521267640417,6381771601744403426,6712813034178600945],"proof":[]}]},{"witness_query":{"leaf_elements":[13645949009585560531,4212573226249452588,13695339007296405194,13492436178033663056,1902934968353771945,16316810139820222950,8570473260764020303,2525664828251839187,12004976576105812783,14286051497866066906,4014749625853021264,11839273468638512124,16219686369006565635,3318153799689124532,6022923360764892660,14684839952027631558,5696211416279425483,8133130098395761949,3942945466848912909,13094485037263983541,2758784488256881788,10583926506591755192,16581431445430112972,5952716315398587478,5450109982955639898,6453970120455105068,18233698192948025571,1416679179088713824,13050857743863407128,16469736078562806801,1689633714479496261,3547968651032964672,5400673656527962057,9052924063434334244,14056704069684076090,14332925206949053163,8194775092229116440,1989750280993651646,13094527908151780208,293415293573230345,11575014885998435615,3733433296851791854,7135639821824441144,18189181423949637713,2551869537641028144,17773399829569032817,11358038850307629578,15107242195895423865,1265362580956074766,459979956584425343,4873429136503308051,8554364833660713626,5945665319997224858,5648981769586470823,269349318678345212,16931642470170640445,3622659161869752731,15968870486194540312,9483233207141100182,12802367623113047405,4052030377647813112,1391827937135405446,16527189229715555184,1988118449650103275,10431259700522543761,3511897514416089676,7376101296409805434,14983725886158412490,11575781946158927175,14969887058724417814,7971863015854501524,4281054948491826619,13382353153758853226,13899758319527170471,15053425191567795986,13934996564278482055,14675035202232104491,7210385433362639988,1144420483880373738,16906070973481882775,3755664379499868916,4269592443866328500,677195409751326717,3246434040446297854,8305014371539862307,6992350501686716804,17069193720967512454,7973284514993228894,875274616649363197,5013658595613268110,15215279279074081107,15642211220538332983,13611976458432225469,7822468108597902944,329351920134405726,9194741481507537216,17876282531288193816,12467744660140676667,17901133768087755861,1188693228881443041,14435872333384867451,8810099264622379089,14423290054229933002,11557430622947971889,14988508393593846924,6774666757984512778,17774542313014401071,11478768686329836805,7169423296913591091,7908902006266152701,11766213030011474269,1710591917972129003,2479440513352799936,6064269368045258982,7202139233293615437,16069334813747347807,2520257833002354447,3622699260631258710,17247995929797753551,7039792080307357019,11570265846430440223,2257204682373582544,5032233150090724851,793576616080860574,2207957050871963798,9558752045082836317,6332797170487433361,1986764920607329602,14992535357262908935,1052723954665517791,1017700209155531108],"proof":[[4976495185770684814,530720453191961677,15984611842081526712,1028014671490075260],[13101682018933051194,3396590318102650639,1375120270400458376,2339747603551424157],[7312349094197532601,2752649312197517291,16452477214306372585,2112757786303317581],[7689353599926164762,11915775784916387712,7500743137498694597,452916923974357810],[7202265713617304654,16780036748487895422,5099442174120459477,2441441733284025514],[17622446766599564158,15010974671025626918,1005448999634780184,121337427521051116],[3826705090257337678,8859619422318654745,17625002667950823709,1969050758630534938],[16897246651552276055,14546876273132450661,15026214729759584489,3292002413220446699],[10411840758857518852,11335727682586501573,16704342851134900219,1825567629739686869],[7845104032949413984,14227682426487064844,12235787677570897478,340075377670963195],[171331851479781644,8936991567376566139,4554582658362714294,1481229455953702197],[111213802398324409,13414388693591907295,9175218896119912829,2638942766800436560],[16081857253535339839,12369760122243596919,321147843985612881,1421310820854733572]]},"stage_2_query":{"leaf_elements":[14480576460963624557,2645119950489794076,16537500014817668754,8911326615198571261,12183329561760590549,2508094175492737542,4944171053529039147,803069720209313565,16935871172348173931,15592738769972188868,14197449598626099263,8829330426063665582,9193773790737476704,17356764200784401391],"proof":[[4388575884743525985,16612438315920319351,10065991335879371824,1102323327206117620],[17631236961467484518,10974924359845240654,7693447914865160042,484923808524793947],[6027882899988326951,803138105074458796,15240257054533195707,1608037071632342365],[3515799466111234759,16818114179052339924,6958766635986805854,585474797483191260],[15187639719200648994,16845713357625800605,13261589136350228416,3292686635377373583],[13748455259533636747,13129457746063835869,12838195330533655310,1782225714917009396],[6083026836239301795,9935423074290704970,2161274595501163416,1137911542275940782],[7412100274999400457,8520191823446518527,887313834569595105,1503944885479060636],[15424357622453784010,6205143386018520965,13541236207613629982,3046636896575722535],[16392913908751044941,11940657156077815363,12512314471613862433,233229714298843809],[15152880817095458326,4475998106991160465,15008538817701683484,2211487576287516768],[17177506030369921111,12851121567553979669,14107730224997407492,1580369957140359352],[15814695789183998421,56527914284832412,8797409215270913660,2669762635623790074]]},"quotient_query":{"leaf_elements":[4947901762974373768,13839793446727070577,8245819532096818586,17962095463648744896,13815139899011102995,7479949498173818735,2779629515201830902,5977480691696368113,17855874836746603866,7644619358932566616,8902630245773795252,6736953025409862088,18053847707478970604,7303111850232886847,3761646276421239925,2250606200799590680],"proof":[[17255433553544083984,4405278786705624746,14475229123196447557,1541029311835504210],[15792814779875232760,14695552510937008071,8452152202166036235,1270507535278472540],[4869303605529158087,11783494380661420796,18044102672130184638,3091224643998353173],[5919311199431186185,12235712953392272637,13166006390541081933,1208367033109364925],[2396957357741347449,15139303519713490469,1446453482283660415,3257412113334809655],[7564540198698649070,14148184847885731698,12262839815302611957,2379543784402717348],[16746387460775651072,17312085692393867771,17953858522159752601,619059633068603554],[16204472797234167478,12907796128695407106,16420028718873613010,2054263445169775778],[1457974482241520203,16271394766746553923,10532384162566687979,2294207979343728504],[14582940653611852153,5204292480076757109,5076104760862492616,3321339133646313086],[14956780942580856435,1258560855878731901,2322737509787285841,2918643104563390249],[3483963415091158506,3894653977204847782,12406404646759003454,3094658829410325307],[18356626245744303853,6926726491857343148,2930800252704934760,1845281596278268515]]},"setup_query":{"leaf_elements":[10402222764010504223,5097467238015203256,12015668190370510120,16450672757798295214,11551846507318505573,18163603625663144585,9262011087693061101,868627299268080494,17781039728608475675,14285385143242466922,14364899665746231088,3392288487775826375,17816101123680509942,7674765982156778108,288715594107713621,1752452861704327037,14991601748543943757,3019308995202067898,10561832885475297266,3846423051349591059,10814849944637887060,15562869258489093465,11047760504723605125,9255299233816143462,15967447243000479551,4878137984099455797,11185546861152967001,16980052483815363618,12633977380294553497,17808737162407590807,1248338019494112597,17617842949550758378,4880850367537831698,14146191452229274418,9227322571303123960,5959319972800187288,15049224837860966420,13595706549172701595,10113268970109675420,5676641547020546036,5117250876307997294,7984770713901503988,15882371861214682454,15120566089697506478,11665457183390739832,5587088831674292215,3484952570676092949,14483078824950271921,3186353562676135288,12741319815406718292,3906291135617672869,9576326013138651501,11160853429142526162,9083980083306358112,1766888867502918445,2053571970378478437,15975433653983589993,5054515666302301471,17149197860516679568,1363048115150696328,3979452102523192110],"proof":[[12844541763310039992,1022797756604560461,16938439321210459951,2250539951236636157],[11674559820161982948,18299436798864699369,17098870849355988595,855810738904534765],[11306302699080307043,4019033690089948485,6434275963467147433,3463013189992818394],[400697949087128976,1171528282377754626,8613809270496612537,2959151265723320461],[2128278939821351121,13003733584236245666,5273525010297744260,1001191370815224515],[11318702301153414067,10088065118888411010,8495080716671180794,2366475822046588759],[10871468616169632158,13405599540486591991,1489244964872477975,153161620633975422],[13700173712251592178,18159619464847619048,15194648889617595881,1055447986934910185],[2103299083336083268,15678489400018486527,4794156575473669691,3283204052906469297],[9814661791264875806,9420661027775581088,13791379520687020298,2372271057587401706],[10000891259386339385,6315007953130685884,6887747776954917417,775327446143990338],[11560595489664821065,14711084012141472140,9667246125152613359,72718795004520500],[4629382627929813659,10434807975241473018,2682618813578145242,1989052126100709949]]},"fri_queries":[{"leaf_elements":[6930060961824314901,3915588876328113216,15911860434722603607,11068026279552408615,8013906579884965050,861184092739880352,424056172376360614,14936215112851788307,2769611215570359088,12587771271501697711,8337272254247511490,745081322743516947,5251301876534421997,12250673898979579109,4577071283668219089,16134335384961354975],"proof":[[6258604226296752758,18203348287521357014,13318663044618334752,2376356165335999017],[10714619272407752488,3268651506953734882,2345972500232824178,1870553270983306778],[12580885810467431846,7449468394955545545,6875446772130912192,2583468572529752602],[4677450034241278693,119634827351242415,869383687567252334,2340662625733552530],[3356964341072353142,4030443873111094048,18321435672469228585,2814614111802855864],[14265535233567567747,2169752577714320157,11738220580594527113,486648400250316560],[2598533567160923825,1492802831977426443,2426288801517425884,386780708791788308],[12869009608291108887,6090290039398388224,5738066062384596457,1725441883651360552],[12491559816505698310,7859756576441109701,14895406505862962053,2931918777804915151],[15662626367922126968,17810244674751992628,11036241030129481650,1434089276239568845]]},{"leaf_elements":[14735240928641210407,12608747499198002111,4642928312352019599,7634431856988956119,5475763819027330985,6539945136570901880,17889019497027498965,184210942443094152,17444975956180361533,13170912251882803526,11541097912525920333,16866357306155711288,3980210715202559559,3430314987286213020,13138651486625236610,2371484729874828887],"proof":[[3351874724909009035,11717868622997149411,15302198497375369830,960304240252904372],[14711721703624095014,18440824530321704391,4046017826433700842,1236032231875722471],[17800289306509054235,10682354380096152728,275562256689185548,1690433433480492134],[17751198850040091301,15883223324839576293,15144880822275581688,1004106752842303932],[16434240657069264735,11480357466363264813,14267234548891798770,1349536451464086332],[6694393482400992803,9377296027434232341,218594664158465201,2649907960693375389],[772002559898402491,17472642335343753501,5484690018317829634,627070858078387906]]},{"leaf_elements":[5830814031683715740,11058006329376318108,15601867257491024710,10353541744365965061,12885204819861551667,7041622066613008195,10442332493100454569,3383173754296491177,4715300644367887996,14000610411267695084,9416722056787379029,4566244133653094266,8750067520076775321,15371970698808037611,3576073655089744817,12540127057735692909],"proof":[[5110993140968900735,6427708914314604314,13172507593245240792,700461219376529580],[17960074102599957202,17446519498755199449,15192701518082843601,1511720647798143606],[217518400021473653,12326198898289941254,14373323732582149021,2685234189206933142],[14851984780092764014,1641047040120452539,8824922906790340682,3018535465669299193]]},{"leaf_elements":[15944738748606314490,2274005129597262509,6673033953838553594,4782849776554528839,16471427245309607619,3638544443347737602,16900485101718499277,7270002477188713541,1980029502034887834,1890826269618363501,15614164942184560760,16775737583699511213,1065694939228935166,5741681071371454950,9624583362685852590,5349665761988333245],"proof":[[10109734138832900614,1881041950409089259,801683665027458401,2204090125200326105]]},{"leaf_elements":[16580212810250977730,4470259858681618858,8395368088134860335,16307579962635236903],"proof":[]}]},{"witness_query":{"leaf_elements":[7679382762254875438,10556063610211269920,9745197772260532384,13065270675142772818,11637188754256267615,13815369026950218520,8287878257568168740,17646608945601227933,2424832416096924283,7698040494913175364,17363741791751461826,591522865762799405,4171768702256525473,1041104532032716882,9105570007129488276,9228141315923420050,5217132925796176310,9778537382928778323,13202580128633825757,7379089222520131922,6881866102741492246,6958693931260782772,3552442831883541512,2107435872094052278,15768002858555035398,13693051837073396992,16922696986335198203,14987489456686793019,865517295249610795,14268091164429244493,614921124166753369,11933169115780024753,3404006886842267631,911104394132973965,8209572757565597589,2663167562081503993,3428514673391213410,17640168095895350984,2269007567944139027,14673013975055816339,4054947464080103302,8245464020235228263,1602316792873411419,16852591432998250930,10689310191530951670,11864203849808970849,17016403551493304400,15914216683249870891,14090165315281762235,1727908870465736872,976837732068336621,13569268397504417933,7481837840701534839,3598833861422781564,5095729652318116370,3792020622764148276,17511367689865217739,12765178270828852197,14381114610245930389,15039607642106624597,5740190439042109178,13632412743524519412,1617681073679671677,4723461402004689299,5697420909102110566,15899169325982808397,15452432670829738014,4904827405798694295,13521208463253384181,15419186998793157738,14048114375043841969,3548020579507318522,15016523343703723384,7898456359351717977,3704298511760422952,16759925368932905442,12695771156649557402,10306226451339611938,1775726898685756552,13504730833870349563,15971960810658702719,11995970275448543484,14580944261614837233,14964270925855886626,10312765519927174367,18046607778174669128,14216352074851040719,9746548911477713458,18320987887526387206,9099211954122392197,15466257935840852765,11269273708945771849,4431559084208026108,2122787598827182588,15717347257861617033,8365317533818811943,8174887194131702405,18210303984954654617,17229972879185949411,9015296414364844529,3047076715937096610,140268029516337455,4590634406688775297,1772028846660394240,6443180409655641652,7558800433973012279,2898259872955739753,7325770845671122932,11867522685917094098,3364984145189556997,906969883884391135,11130265697559307403,14369159548388882988,15976866212527061137,7542078667546989301,10495199357306133474,12347915656437424146,17044944056252736969,7907144160849186874,9894556868454209907,10245269829771747204,16106057393530000643,1998093880076281349,4009099901512548908,4453918748236367424,2693632920279140587,6250592054422973778,12371860690137165967,14697237167951586183,3342468488256850268,16706586382822146903],"proof":[[14484056700308224709,15073617203510114456,3866048498544894931,580113305006336247],[6625882647483763184,15469969540990439681,13710414397625831965,1924706999434879650],[18353000261096102680,8765709790127985745,8198557736138476120,1121890182824429820],[4327628856899542080,7571140564569435633,14337118619749843233,3409338912189435308],[11015046685451813327,1498204908494884908,7769614802762632153,1325814924496161857],[310864468468289909,15126759911203224972,5038023531799168108,1222432958273449822],[1086898904501110497,8201499778274840285,5498177318828226305,1632354289093994366],[16077659794307081146,1045773331774385111,11976045034498401047,856880332834217393],[13895810054411071029,9619167071048313283,8084381841124534498,1854228066656027406],[11201847132789597723,12595636639423380475,568186034680886954,1108132146533878665],[3451811609405046308,12955494814316407201,12624377448568066404,1181723932403558794],[17671914304407481281,15250981406533444861,14565207026805768862,2760054854315918067],[4882341907511761828,17248529125536155909,3175697314877703332,2970579942529858095]]},"stage_2_query":{"leaf_elements":[3661710880168143182,12682470354428839499,9269327727792970468,9610160961269731406,9318668051377916015,12557272910184070177,4496639517828090242,12134025667036258700,14337726367676566191,9020371025028347307,11746542031377601887,770967376152457092,2150318742322034780,12058675384345583976],"proof":[[2025995077873770270,15626586187443281493,712850049462140066,1590825915950121494],[11781336785744664981,8867877184352567794,7689066595717233932,2697631627921766899],[1453217170912674708,13488441095003447024,17206069936934363552,611999175640647456],[7213726513976890115,12073064322613673090,16917433525155527820,2866413047666152368],[10413623723771805183,16406544752652322599,8920910619619230726,1783345462457552738],[8901023751250724708,1838288308180034315,6891013999815225008,806147351899072211],[765427883932958732,6543180701213451301,18344641508909714983,3181320723758887598],[7164749361749459314,1099788419117905157,11316784975959227229,997923072084790842],[6959783703316506934,10221296278393110760,17875137551298274347,1915419180696247003],[10956917595863260187,47725423125017681,7982073389958467553,1027809880682074048],[12306973922205257953,18134892844992046818,4909846925181999553,514217486188727486],[7440879363638726122,1272187568204886256,11807148749459268623,2757513016743690613],[7193705033799763541,9048181582346268552,11152058647750961664,1742650808604916784]]},"quotient_query":{"leaf_elements":[15810167485075156907,11642066885689055318,11449545903593861125,10181937474759590646,4125290258650579106,7687461562514581226,4074286712538898617,10222322690230853855,7397937741867767727,5735615160386029426,7365963302807346424,15510807284289003096,6837819388914450409,12100700967371173075,10801453376405388247,17439186070387970140],"proof":[[3217447671982885349,6744093139036872291,9370957174423994841,2598336106602772987],[14848325423596103948,8959542363741913161,16303155398417974705,357445194203787244],[14675260247305172128,18198013589963892259,4931969293978977578,3346818492009810114],[13374971737785462181,12476109077987680321,5538268301228137240,701936184378054711],[10017473370807706134,17240964029141835836,5024661006161252003,1639841049476002042],[2508594219093545616,12648231417062082218,16860902730205205963,2307675117568995342],[10005861086127355570,2945390116757194318,6923878625273992217,3352286896812143917],[10839621544304018399,12503576249850488612,597443762507101141,2601354440248605803],[10722074010411622920,1249147544441479569,17542941708666385491,3423957276555954946],[11665641228563514993,5460805232917942395,13483300284211512875,320198936673534311],[17451694591408679228,15229411708894453702,13423381248400178260,2428060335885006254],[10036339106512996484,8017919505745166723,4863977692106479589,2511454411117686761],[117417962886288672,14214076626666423966,6745455965795245453,1238354374129802593]]},"setup_query":{"leaf_elements":[1983917255209327261,5285769086758699454,12000345156465308265,17197146789487702525,6633710861219818824,11742270245220302852,16092188277665701001,8659886529530722231,18322956918335654633,8048781955268694706,12369776614113389580,13983823300582204170,1299995122469614274,754589869030660933,13790900811695970265,16702740770617496255,2984984800237482538,15286677388903129201,1540149301304041424,2963970182571788285,10590409495410595162,3935181672254393893,1157378612439604125,268640768120195690,1821588274658722572,11482101423057666540,16623190742459203403,3075860476379353617,2692714859091179805,9848778445802149141,5637200917648252209,12930197418809255483,17363965816847447869,8285044042079296912,17604209779304388536,5061004126416929056,4014773322397079728,8456266654538501525,14633118906317820545,10812235139163601544,16326676405278390812,4226779337334292837,9282497325924391362,2820535182827250028,11904348238491130786,3108900693424035177,13384626251338364325,14100631152590959705,18169133979740436928,10948480613736374435,3121186950463475170,16449893075817973454,12258288180886509132,1432312470553757738,13963288238414019765,16212017984797002709,246213728339149091,15085463506207590496,14219285219430732094,16127452459184438384,17575375929742801856],"proof":[[972216859937085698,16770303013852474375,2471231959727304669,1245403857774267425],[2454196736143991633,1675933853406693490,16123813894614311248,1789768333489362627],[10017432010452133355,5115126407331326413,4700889609533081701,1593904259993932581],[14903795181915197178,17366196990838637371,107141593326873584,54906148506648574],[6276926877548755062,14086119768194470469,16594372698710369344,640083286382645544],[18163046995104261617,15866804735419799655,15452847346300943536,2435581505199609893],[12562837774625600087,3489686271158252678,15356834592041371058,2634825446204090360],[3617427894285370745,11326662423287198148,16085558352645256845,1530192617022959185],[4350840874500492496,18011876077385780984,6609721101410320944,2015209832986677056],[15544938126635112376,2855697305052997761,11730446877167136,1755256576539074483],[822201642010616353,16601556358609654412,14983251665919113871,1064264031937084851],[14334209393799635469,1475323473228810002,18184008165679810890,1713996275066066032],[2812288052570429747,11192114483378251971,10192533965505786912,2372986316534941658]]},"fri_queries":[{"leaf_elements":[7520098835740101800,10278719598795105367,7121853382485125352,12141076701879642521,3442449278556824807,8467956205883267478,3696819264902302086,12430874432267484030,7263632585212489991,6317381469673125298,5122959038187659220,2090271353792717038,13509525896522620881,15729547366751851370,18365428345930774746,17885354310276702172],"proof":[[10429838830576987084,1055264115807876911,1581960767543255875,199256329905235685],[9978289688726959384,13975439457425714995,12601223601286740399,890024617751658113],[14608971439920111462,11544549816362215881,1170161791325137513,1184577087051390626],[6408664906738686333,4788243557769658723,6275192305030986880,606585269587367451],[11970144788057058595,5743127531678418748,2644815693602078979,742269618636261541],[1245990148489009350,1733441002689171944,2689115015017295390,925299738181023767],[3231904232961211629,9319333604652905006,10481895074231723962,1928264077353597962],[1181378642861328473,1511033868296641097,2833311835469482257,1244195921661519822],[14498309021160317876,4335336406161045620,10269803013955387956,85048028284377013],[8616858090914454618,1663075563175866095,3467139390527938134,649361097648535523]]},{"leaf_elements":[12220592997256386643,17293595954483236385,7752034809405125705,10851230125528265521,6767925300704043401,16589699241793181047,10369170495703664426,15950057455800253657,2628819144976053150,2772472438376957622,1582313327429881142,9068987441493301532,17158384714020148005,1465367927706152349,11093005867540014841,4375801975375025847],"proof":[[5171500822808642092,11858457006155243909,10506291387323157143,318213297285397447],[1087617953807929148,1749266171114328024,6452416738505165632,2820905156032769974],[11476906344696376236,3348800926949200350,7206955281995877207,1387297043404871784],[14721451286642473617,10666934883849771075,5823705559975829969,3265248871011407522],[5752376409291467957,667947035431943061,10476895350076206282,2045674658234997720],[8769980020455982479,10264300124099998582,10055189718779220036,3407096088247693131],[2715489747108002065,5305903886920463068,7746148398384784045,2253146750247811367]]},{"leaf_elements":[11531981849707966840,14695348886464175104,2460326584497313261,10913911483493926533,7861865813663489030,9035997014056657398,14700603411437578869,12231247063912033139,321556680728611998,7792073961460301945,8909637579191763389,11283675337130427775,11971037166466592334,365064750974557868,13193305012113921173,9688118754937464704],"proof":[[13450973342998908723,12780954244954086971,7658707812888809306,3037594873587654497],[2466919783244307316,6235684966589171095,16514339429706847530,538888076790160404],[14523714712956106902,7893188032393412920,6957786632367611107,2913391734713166420],[14590848441063452794,16273615971920084576,17011998151899724188,463497794276927016]]},{"leaf_elements":[6278203763991616066,8078050046665436218,10081382088507432339,2222463645849995902,2969879425453338659,7276527334025712803,5195638262421124803,1423548983605012455,399448597950965084,10609950177358245602,3937540680217941419,2177255647077924033,8319833819507901832,10608342303844245766,7261168177199598481,4461036407361939175],"proof":[[16347249376249566426,14583720912265793793,4350686724955233422,1407886625625018208]]},{"leaf_elements":[2966080012095824694,10472639831135879261,4652833482319589241,5368590808610327190],"proof":[]}]},{"witness_query":{"leaf_elements":[12333122189483789396,5542947836332340700,9812779717402857566,2730029175401212115,35527615216679670,659294584235008375,15234548800952177327,16021811812239030860,18257734821226214956,5630939042780759440,13461484502986424341,17149600549883882897,8307151090080650360,14862927168504928324,435220907617265559,7981985565634222621,1101028049873623141,11210429014804702793,5170564253182318684,17271673313506169853,15028371106868615619,280332727415858437,13399638233962275450,16843387097867394347,3597223228360098183,10934428855917905404,8150584885992719385,1689942749103916650,6585266344931729757,17063784535573142743,17780151987091102339,18246294752873921141,13910508851604209056,9407933615099393710,16359118300036940428,17962673000250395968,14352074900053818941,16844784968381532120,3672064347322358131,13792578961361325723,7674059999511269251,13932429640573559894,16471708177337816522,5391319539706879159,15707159363924242489,15679071010109254845,8484955601364917648,6191842643663811299,12691613857653823435,5476464826019355520,3807035084183592710,7143662099836449021,3914461534814102849,13538516706410987363,7301737357728756526,2580370533757882349,976152309597680875,17754018920579159903,564850115058672890,3164234868120982457,11715729522981197272,15623744734519409391,16440275004395490141,11264098167458727061,887591781494484675,8777021402183182147,4377476961940393175,17085404291993513183,1670067235522467555,5251061279525560788,6173262506814251353,4905296099408719181,12596552020564466516,3056224752615673734,1493678547409924746,4581998988979165567,2118241838393412064,9111075377201303583,13646518807365573167,3800443601805127385,11222421938944939336,3514145268806862879,7933292492482867578,5181547552964787074,10938226900633301005,14108072898165010363,423518347717590861,14676460055096944092,3913656800320589738,1206254627070240726,11888129765557301388,13753347853527357740,4630141436825375207,9352302096930833443,9131206692475366312,5670020626714642802,15471665953951321207,15444436999251080429,12954212803420548318,2569631191764464252,7017407315739400636,7590444964226337742,289670492758369745,3845674392798474267,15901896009504641145,10556675965698591649,17109571091945748224,15479004986132428740,16530153267681389549,12322129722484303789,4180617454618643996,11050894404917942867,17880710303209433676,2087322501786151015,7822265505356124915,2873094355055495901,6325717183539509071,5227890803279849910,17309791036050569516,16874023035594900486,767388623974796911,10694610250934103874,4551504826580513937,12128803134483301527,8709308070194966873,17245751578131960792,778911382651452816,8415392326518258486,5551509111840297856,3277489988391329755,1198301288989774587],"proof":[[1929410550416711066,13631899197697275918,5116405632597919057,824245842211746719],[7417502792986537884,9531798962893186007,11270054515529762514,3108762433559880184],[7929772275763940652,6504319588665951061,4315883697658669749,644313199406745340],[8010707664703315161,6663842491710188616,3208472432129093824,2169923155807071250],[9927427075639106703,6667715248426748075,12792761283349535892,2548161571839861824],[11744592523105274815,3953904780002735897,1133322867965742173,680751201765249935],[7876003688147027155,3725645985659418894,17553019631507369538,3183798890159655955],[10239639345553746666,5869487122015266002,15500562966380087143,228803054229017627],[13138550258331372992,14893528087779969999,16714836530065588061,862045042768758462],[10951653104043587848,7919903444412719083,5162695335858127617,23119395089544772],[9388057809714662536,6881594517039155908,9621280000059624914,3408116750480582021],[5337386146685324083,1759315120300051303,1014203858517702445,2373938672992607667],[10760418131477431642,14820657774701628297,11628914349052808993,2039254384422831665]]},"stage_2_query":{"leaf_elements":[8492658903664143129,12677489378047690409,6136652003076791811,5197464343502937025,4079870915553323046,12566981598569093473,8276916886971200771,18247145586176194680,4242638230793619338,2363609957433095025,13704576765786514128,7275356406934766797,17418511491501289458,6912229660744021297],"proof":[[13288822139342018962,16576777847421905907,9942521187565654975,2944089003793974001],[14957000362305406314,3874593509714952938,2498680343202017574,2582804358792513969],[13984953655549044719,2570815733869693497,16395819666028783502,2263021108696798331],[8267563474831601079,11625348151723946364,12560336202915233016,397274194538487693],[3136803354469829712,10828497187672060123,1431785523950423864,3107843881786249296],[16689772624555613551,5008041377135709283,6932781461721355699,2259664383378524608],[7640956656048553885,8403635443237624158,16383656347291441090,459662687119049360],[3526164484871033574,10222714778840049436,10191399154573189639,2177690883375574134],[5536893132027057841,6192682532865860260,7988068125621997876,1404425105648803296],[18408895195113260190,8769004206195816899,11490392707479511896,2112799591863743477],[2222405210836799482,6953798830797038681,13472779768468229362,2244017304401157106],[10946443397241484112,7632626395748461425,2953818670712640602,466835577787625070],[10265763405734876041,5280836174585384744,1332105447072495082,1288183057809366478]]},"quotient_query":{"leaf_elements":[13092893545126992691,4504695173901388205,13132055045628749629,14316248580234625359,18234928748012540007,2336005471498418652,17350673568352635267,10393119089038164355,14765466436538523355,2650826174287951425,5891197167129895703,9422740934847213180,11254701704451586899,2125952738964001863,17165000885116162044,15037196414134197517],"proof":[[7423547709768247424,15452685769646112938,14153292244776881753,1655396746217602098],[2332499997179058523,9503173752029071281,402276593990406030,1779076328322929857],[5315424011929370453,17442459874700592793,6061313504769894239,2393732401606341197],[11433423966110562869,3807388593208140910,7815924972004829165,18174239642162419],[13078895621284286079,8057230540471309200,9127899844508799454,366928118038189434],[7008476538584705520,3334262730075475472,7673358407111505403,1324118052419445078],[17883750576839358898,6934016764710525300,984291567744841020,1784925206144876485],[12004351778418388077,4697010492969595955,7881199033422781197,1334529771020467769],[3165834478501365173,13494943742204800498,9365776494686569060,1395088187315892830],[14275460733389509382,727630136473663868,3068214610850205613,3149710175450347811],[10676253219800793360,3065231490902574033,9625064857038164035,3481474067564603472],[14698990891311628009,15892561105547541385,6630210176285877232,628055738420819513],[3336220069100085124,5759271110398045898,13618835346520552360,87853750978578886]]},"setup_query":{"leaf_elements":[3679174387034188547,6635908900094953892,9913512123156671562,2003079149100595748,3220335964757720510,9944029131317034628,6810573744923592758,2474899082534218738,12951371858138838351,11244777055143168446,11260102806539785719,15131832067252054265,975440356235274634,9739080198975453374,10280672167619084987,6377011205576497212,13884188973652003534,4976302459228930430,11556129148790312635,9191383738379315940,4256245124647993462,16217601195110451927,10396929455906818010,18153898991360599924,3730605171779030670,6845729690211612998,289689330482625128,8186460130073430752,8054623388591739380,2098887216922763145,17106482474758589873,16926940956107249803,12888561035956626311,1263509229857625280,16912276555989418158,3238613583256996810,9587292157611386299,10925914497898767039,17308451357133095640,3254694076986185431,17088446834273326269,9383800327315080895,16876157114386635067,8712477916670934144,7848684314877168368,15511078994168678161,18367476313152380585,15474158507222912080,1593018634045474770,3695912738582897124,2965956271957116975,11534385191790692031,2047055982099888450,6485464891234052700,15779283594801162293,11552858805274365675,11158834777192249799,936767347402599361,879880123187616360,5093091567538974428,15320592030502719680],"proof":[[5172144164155159287,13854763409825360831,17768797543004320966,1888216630773229226],[910386891249271145,11525773274967446717,17437826241945141114,1451738648029565780],[10239954522956327149,15621254681100037747,6654103891432866211,3374312028951390060],[4789121246699762250,6844045152413891817,13237691751710319604,2339327964607906687],[1981707095850032827,9123186666586442822,3973537398364295975,1112783683764725554],[5452000838153831375,13598102878491549520,8864652452206187588,362706343713548312],[8896428629835170979,13107835961352583805,3941340621454177410,697270259158921410],[9841076032258356833,126079188255781992,4982033767937849762,176024870523422830],[11261659494708642916,4952713328269126389,8906223940340672178,1706364260053030206],[2390011459891806211,3285298630356948080,15789193015670778304,2542725731978842878],[3204993322470177833,6051698634689342142,14629886291271439938,1970813260747825769],[8634214520312302704,5788473018517600736,3895694945095744202,1852559750666780338],[17874738227292005179,6326465745494053,13494069438792348789,1192845911089305290]]},"fri_queries":[{"leaf_elements":[5192500706881009884,3666627404035167231,15123359910653536150,4209430281216538132,7852300294938681524,15034524088785802417,7592056224803382136,6366960442971791164,3724311332473646410,4223493493230209824,6867358781863913293,7390319209912327588,3827273833963975118,10221739122018316604,14824295774074792807,11695096871900771752],"proof":[[4406374216689072176,14368171393879737179,16589759916963348599,3031812959778602391],[13202722794984755506,1180118659431536044,17628950476033966286,3099217666073203921],[15452100555557024825,11984907896208008488,6102040005886110655,3442670655275111733],[877476717893669244,10315068006689379072,163085804975125583,2211265013658280649],[17867825747058058572,1083441972522374226,5538120313443016343,2076637165706049672],[15548907228064586125,13245879855202429388,16732067322266566290,2194362118786187508],[4952831040562207074,6517362100909505655,16174006814181420491,2416180852475674433],[15278104253822765377,444973421875180932,6867578795190594467,1889369406362716708],[8736545542981214870,18091865623238342905,16938045962214512397,1619771569222218445],[4755821502693131307,9632672734832196477,6831801818195575559,1211503718015705569]]},{"leaf_elements":[7474990717223488636,2910427799124280193,16388120447690138270,15579554146344380758,2986622706563226811,7223848547773670653,3518991212579842755,1669508625798474570,13985350847907789375,14270869936918007476,11113767782102441287,14948034477438591757,5118751315079765926,1880127923263043847,16910399527523898155,1631276832051036681],"proof":[[817428331259215481,12272894036330761195,15989614189392520729,3196950180017644621],[12336676220520525764,4668850784600160372,17331121141462859224,2244482748566447947],[14879713037010436626,9996640984512543226,12195441762651172930,462077149151588135],[10800162864120345556,7596200427698308094,17553146207459303591,1946335454589994254],[12631542405088319149,8508646081898105547,12611729228031276884,1437295729419850320],[17748107662216378529,3745547155845768398,10781438857281393381,2132537212408657619],[4968579060289205032,15025470103249155658,4016020820835814409,676707436625885313]]},{"leaf_elements":[13092178898224954836,13121171690169681357,4563839687463904392,2884719900177674209,2018875173937622824,9364799514609993044,2120333816287278172,5771409380339448258,3790608599368895699,5392395979202498885,2044919337182583878,14357494483865510256,14409218015068534053,1409362299784941964,7017790157041022834,3050733522543745861],"proof":[[15096638317328239054,4245079533551746238,1928602671317396739,2694019264028933600],[6330150321326104935,115391163174278785,12091614213860527036,74519276213109023],[16787357039742660708,15074718737644074307,7357274406577523229,2904651230561894869],[6775086337445118645,3836725614252760951,1244274972769235222,3458783429667173983]]},{"leaf_elements":[16760476579281369555,11684430973873978645,3628257208263626274,13264191245930967560,16805239192496903355,15197924325062831366,2446532897786143650,2265791655783868310,12694463806107320464,16750582611044430566,7379235119149631963,8016374353919518273,11399838020256932524,8401772713760710572,16660944741874745508,2593524144018731665],"proof":[[1408739999051503414,17928989256333671698,4393560887102948271,358038974748859422]]},{"leaf_elements":[15915622550061201680,4536541224237163888,16120598048347926193,2661082248244309055],"proof":[]}]},{"witness_query":{"leaf_elements":[15346053497013852738,8863269125766156094,7233514704047142613,2135001378935003795,2956410632957077808,17250678625079629514,13811466556734628000,6562600256285389326,9956372014575548309,255712732780000300,3577412116690952867,3397140641981122195,8866634428906810021,14932710348821071669,3112872219750426104,15365559452510896840,10439299531750742510,3741895324892307768,12344281749115599326,10432534153354745159,15225644214335244530,13105653130444120965,18050867590076032260,12221106254326235266,1642357391675783217,1561633659984398242,15719337777900054757,15386146998046431875,9056644824984585588,11071793166359053002,15564059639187095750,15008319014443196683,7358059364493370982,1014948407715977181,6668379924441770203,13051434017063751456,3914997161930784331,8991968807939145802,14538933216149100752,1813246697052979910,362569534382220033,5162775333590220314,15128930515633116647,8370774036655644010,8080486867583201876,15246921184018635321,5737653504783879117,14883696236909329251,7922646266147014384,13545408768052031013,9575434312861664909,5406756295627595077,14853805792300287641,14847818388870051483,9124506697627417485,9636052627020218709,9282832419613026410,5520290308040033374,17462670092370014545,15631926525115395474,11737478134658108681,2434002842130822666,4446033662891994158,2799983907227462569,1219123514957864629,9419450209141426635,7056711572785882552,8272707177695248430,17794714882470236262,767504424771415456,7769264287408724086,2801172703842776196,17655383228351535036,16604477334620125010,16727083439875493662,15290132420125826,1647424770581491323,16689976033951682822,5755047522476966152,6998341477504919913,6172033530023988198,14963206598229003546,567047557192560314,8214583105120231901,14719444813067394735,8640428630109280029,13362707503774220,17574945268130514118,599962828961376861,18143509797635182878,17121842759933915098,13545660219812057332,15793513938007952389,12572328319492446562,3263301949210631910,9718652261516467180,12894578523867903053,1784117748399869178,993293843893884971,13558751682836847140,8416729725001846620,16221068644943505941,1545159056813026112,17476621416165204619,17534900401738676094,5163496570084443992,15111840696380344213,3779338180934133494,17151840634168489409,3839625203848618335,9453529252544661109,8896426173086900669,11182001457853115620,2332281000928831327,10335492201829709593,11789951677323836994,14752626312212602434,11525789640320442845,14343968945126223347,6465117484258748227,5551514676034245813,5147106185111767873,4710767990824229747,15057847007795186184,3265188829168044864,7622413483158670348,6795154269715631373,4833901181313785999,13283514918929879923,10607165507662021312,2511509936865117439],"proof":[[11117776589964643533,17488014309923840370,13562534603415370501,2322056006549568901],[6908808046276401982,1102354384508555170,1272844089651179409,767343935933068901],[3073598239447296909,1315363985853085851,2910595638583115831,2188115021353290704],[15964688975042750503,10738735974492747850,5531500799420015027,1168529284858060148],[126783938767772017,6249766545830413038,504833088389937217,824036703492953906],[7464673196533247921,4168154864447720444,16300281385238443290,2922568809147096054],[1312036937020716380,3259939815424595917,14816254834053454988,2903718785609729440],[3311188101964372135,14126124594489948727,5262509993807641224,2629674265415474103],[2702720675570331880,7076803046559371647,9555036583998620079,1547707184950759975],[11983607628650377709,7352316250343537026,17716902015107092039,488891433819409835],[7690951596761023,11458922597451823616,8882527569510708970,1266506885877286605],[11415905996941427151,10660302710143654885,2372276255914879287,1679654779518758413],[2402167573558463631,2137105850631415449,4214898604496638014,3277064941376453795]]},"stage_2_query":{"leaf_elements":[15800085756652357811,12772958324113929316,12254790053940049595,5152372493975117194,14712049804042260229,7111529532949187132,5301295179227688009,855390002918442830,16221304110881872126,15607697299059862245,15411194998735797251,6356567717864298562,13871095200927330334,1796319856503077902],"proof":[[16467738559374651027,14989750290282745504,4302400041007136622,2096472086955901509],[12856950691055769683,11516645791782802135,18282070607124066170,1566507834027703944],[13801738799871484,6128759668709906062,15202350847032216196,3078808479370894754],[14860424437569857359,8180819248267355332,4291395336463411437,2844688356278012670],[14469590864910700892,6751225676105699463,9653098678458347813,2710949074783560962],[3659336844960739705,5878730011172754968,10001728293176158939,2454807614818583419],[1202435918512861680,14606442478731184710,15466999085227873211,3285435054481064495],[5096390280501994819,4392377070817049917,7485082897445257716,2326980141679431574],[2906368939126608792,18148812531725172461,908633712253003875,1260393989059351374],[3109333228960940251,7856026674639660990,4328136352532250260,2612544336654324059],[17761375393950071380,6795162970777673619,14375268200983230937,2335790224882885577],[10407363249130410373,16954790918514647387,10609888232113772352,3146799241964272978],[13098703293661233855,188671376608403103,4925193949924778707,496229296521733553]]},"quotient_query":{"leaf_elements":[9785254114342712054,1261084148255323529,11445625596702558364,6340096314473311273,10662759526692736029,14834496503163310566,1930180057910011900,11146232108870353024,5926441074147525525,5319593629390311596,6480171295205043400,8010132189469565928,7374397167912915924,8254414417955199112,6136406590276438063,11563212103214645828],"proof":[[15901181904268633362,4109503920099012733,18232977425538106018,1189862879031136785],[1699202713328764314,3526426339753360928,15647013269261155574,1129730761045439185],[4247446379612409533,1697010825709227503,7953951627843086473,1787794964529418260],[2241372765459465366,10426803445031671778,10944042581072599514,3223371186308408590],[843251529686695600,5548180571119093745,10191313084309474368,3017715262360607554],[5371105199402842254,3596813569539896980,18195601177301103268,2043045830663210871],[1923322011870123423,15010750175121590866,5357228579315558937,1171307190496887195],[14138566072364735327,13555488145352762145,5827494633006015860,2623540049471837534],[2453012214444812664,12559347951707140855,11535067648379349216,1920239645087247370],[7279315271696316725,1624981244850771524,2708461011295415222,2420101634609411864],[17556510744001313675,8683728022009788672,154922456991861702,2883140580046216063],[18115605467734096472,3574051143500497427,3020749458933764493,930824462930490723],[7064726902681906417,8802656868035565002,10106252046860638745,2781091557009897750]]},"setup_query":{"leaf_elements":[11285709282252360028,1347684664187797482,5761313485463330930,3322273084175809949,14447701855152395072,1639737938791023626,229544141462178042,17331887422444777913,2831981148379666051,4716216962195145873,13386601433210219052,16855306700215342852,5771061679533575349,9957763010212447326,560518671870824069,12484476862140619415,43757402974594993,14106298807781461521,11876947927343657344,17305663203735106953,15125529586613076733,14368859525727708058,17291445035780907297,9501627163010987002,18313546386663576581,5517237263356094065,8453601465590921709,342343526146852566,10053370258628895943,11508764377859341977,1005618988427836097,16208075887075363034,5468185876626344508,13642642744518948982,7976098659450532789,17767084701181216599,18345289812240116397,4827900434548490716,13599764926086146830,12325324286417328569,10386713954183850509,14640788221281509799,11177093405491532568,11904441454789271489,11485752069424631809,11344701947374579110,5771840420457426437,16349410926302086358,1785783039550084815,6622714047542552758,169581267395249488,189775858822343314,17412582438808653825,13442679205921816380,3933575187906609044,5056523104968891893,2844004312044475974,15133300037267829582,5471205779286130701,7194923794054172642,11138172605615749691],"proof":[[4272515208564973190,10346068767566030468,12524164378928707956,3203089949494629731],[8045702424698780959,505629283037062136,13920096082351565475,2812763847016190396],[13750133457910846394,13083056599222111628,603954513673882756,3230822688674255858],[11670631755052908947,17497605764571274885,9366250947382371887,3206398445763118209],[7517611235018142406,261014279805436964,1415638207132786868,295205356317329043],[15034960643608288596,2192670825378866464,5596054660932114276,174768255557675730],[9487110337023260411,8269567457389730144,13890741413799000501,3129564668957440673],[8883712635139325113,15002766575057273832,10438038433614062930,2999963452099649562],[5935028654997809328,9558514596462948436,16336026032628243512,1215572339095748740],[13946065930384763924,17122745387154957923,16507256448872316952,682960349349592049],[17793057826571537103,5871641048410822126,135290287805394137,1286187672438399899],[5445559004216073443,1198132081030565079,17435961269386252882,409115357091037829],[5510389358968454592,6342099385859423646,15847287637010183663,1721032798950188614]]},"fri_queries":[{"leaf_elements":[17890639243567903351,15811025165767575640,12689021685310922104,17431242589786500258,14183389603963819912,924632569821346164,14093627653653337924,511708293062656281,18395991050074429463,15681215497639267405,13604190183661626394,17302851116338550478,8529372914638713126,12429274697516821231,6720964780899467212,15246940870591428579],"proof":[[15711842903238028022,12538553101098430888,2051705556569729105,3147076792678186706],[2310486221022099953,17443431131767323464,11318197262500092385,842018521706242897],[9988028768757738297,10560913459270260621,17857251753415892422,1465623475106714579],[13977918002296552381,1093037803408939680,14805987556261617589,2817011570460864409],[1906432958425770986,6063164782357779028,2672343246352986783,3485585581008055404],[18151026162341971873,10594094832116410608,4117696026799955264,2032680751620118745],[2210147654815311115,9755151552001893274,14223104150702538835,2298895887271983715],[1672215460919510228,11678346249895981517,9350507107985831061,1413091040783043124],[13576090322169072468,15773115218858709815,11549256246675271586,1581530864327155504],[11512094953525416513,301201197378265374,4065232932777357782,2702801754939657824]]},{"leaf_elements":[1541723845126899916,11488206329635341170,4535156573313732690,9717887368661501817,1957492231739585017,7110857923562567474,11383809026168903631,2323277322816787947,10714319688655089440,3543044253136833013,9116096663726360243,14553256868726023977,10180152469607391484,12032064266050969370,4344719374951135953,8195274642159070296],"proof":[[8105116858244580182,1656221177914354113,11474974154165601864,1851033562072828640],[14638477491821386280,11840371443357798529,10802281831301563377,1354347873904552172],[6949905826637729590,7916709827382836607,7270114525818431555,1994485638200166893],[3801198160896282892,14987262530264821944,1190694078219642755,788771330793622633],[12057856753089965632,6675875001242647287,137210034102096310,3476837347261188754],[3513926668228552914,15119690949552432682,963605868327422277,1009404848197770467],[6905604683261516761,785630753018559997,8071271293678686283,1371257465431982896]]},{"leaf_elements":[3019165066595823160,13095273563032438663,14425153917644764187,10954552964374299023,1700374471918703143,7069332259798822919,15305914613124902316,15253193862847849416,7579313616619506374,4093472708685020156,18208281309132313573,17224706958808545811,10805387669929938784,426318675414809286,6523771378620617956,807791544580544593],"proof":[[15938629210137001193,9930336941785222766,13471288445967932147,3469837979683864674],[7356971435280096125,6919906741957109976,16542070738234385373,2981048301230491537],[17968893795748583061,18435562828519063323,4801354124354045479,165544965653125324],[1389524551255036162,7115597326301420030,4677436100140046760,2997251062732232682]]},{"leaf_elements":[8766804231547517221,4314020161339189469,526230993367059777,1371290347504725484,9718295733965069127,18006200898151862508,4150610419468893976,14342643557102012012,13624566138619880019,553955421167211366,15268536086186198656,18097336813190350750,4289863886401648441,9987687823700455758,7369310771996817417,6478430192287573656],"proof":[[13748503802770165510,6447469746112887630,5266659250392852870,2048396772139579074]]},{"leaf_elements":[6865243823879750534,264255220950879342,5012916995573505337,7094628130780347210],"proof":[]}]},{"witness_query":{"leaf_elements":[12467691435525775255,12476621318745358482,2971399757750492257,6630752727491426662,287055990639851070,9555583773694534053,4668064156641570193,3655718973834912736,10683818642542580346,11314036742255195816,2167001313424154182,8359700121804649167,2553351116087993695,10889803909185397585,4732771266447811503,13206250328051248841,16885244933966315239,10858673869511515771,10242477091154514886,2605096041861493333,5370184675276100765,1791689728815157900,8647416902942447122,17544613579471259210,1087992792999031046,6354914677482156791,3410867116580880042,6140292333407148018,15355639355576709590,13596405861127676640,4905296161952296450,5878078620793839243,17271368512816339937,7866094372808344450,8086142443020045205,1376299895383895708,8113365468963015933,8541006836081371440,14942118376217273660,4012548515652227400,14831708446168625549,14071655561517593252,13909135146216723815,368451018676648443,1341566109976784950,12978279426936553184,5381332911066766176,10667415826345222758,14526418799327461001,4809993801225006458,6089402465635182300,12604190745853304250,12452421983084895091,15742433264079001362,3222840547297163409,11144660074475991455,4610979806355958367,17015987139946804015,12061654076999445244,6082882664562852616,14509998373871549336,11780495661762853356,6683993544119085919,1490459701400034934,3682423095576632056,1959211251110174506,9248546997089986184,6408254483671905728,11294853470803400781,13353197112722064728,15452915601476512324,14802715250199780387,8778529172594253369,8028006931551589111,6324276309302635411,5978288168786319658,2990452390401618779,823978789288197315,10365690335274516182,7232748171958569951,3492928599500919841,5679365708723729114,12735939605024371880,11820498144450539601,14444436493586079146,11072255983456333517,16346109320884668838,5911396732278193542,69577570204745550,2159301184639952501,4548737565939569575,9587297356985346813,1381206855057639770,8145826360099242587,17859748015393908512,6059560733855700981,12372819174984268663,8303516226829523580,5954846183720873353,6128071111698577115,6066428953767639434,12016406619703844718,982786517685520320,475516916111192594,8131563004875973416,10191211671194451077,11268484003752099708,8391069935248586646,13249980414076077337,11640680288901865544,11904878364139800319,2010545294048225365,4180232137729248396,8308742169409653123,14925913426823328484,6907881623778611242,2059363576264359732,13302225404301177900,14645863950455551456,14335259312770576030,2191143648982482109,9988396842031754206,2335472631660959896,2641763680384852217,15989821546729195444,13539003821162203324,17980858186223902314,16504420485543355081,8760936694307205721,10727728790356910855,1481011132338681226],"proof":[[13397669238495441801,12075232799005708990,12769853196506539122,2286565282530905704],[10395840535555029548,14837692248401899219,14767348252122830549,251329015079790037],[17600505997380817969,3564765083929496019,8162806129830619903,311465486199791565],[2687060308182107019,16396171923903907601,2748351809730201474,756951856495594247],[12339069447679904615,9213896066640712124,7123065194855735729,3161724733015783686],[8517832732985836076,3640382744074351178,16796392559353857199,132962694550140381],[14092795766206161850,16495182119204665383,10852954410018918350,1487384304314697482],[16013235422082209387,466402863454231748,8850864952350938923,736725806591412590],[11522951245599020416,2312544841108416370,15825610310176324801,1210932404184133151],[4704053039071903943,820626443950605277,8962884576541836146,1827069947529563843],[3451811609405046308,12955494814316407201,12624377448568066404,1181723932403558794],[17671914304407481281,15250981406533444861,14565207026805768862,2760054854315918067],[4882341907511761828,17248529125536155909,3175697314877703332,2970579942529858095]]},"stage_2_query":{"leaf_elements":[15566470391184705459,4442226760665492570,7080052883733058549,4866572852355543407,3904484337725471826,10193219075343048845,14381500485881682339,12191973111225503820,1159627837507420289,59481343708142672,8409929198715840677,3956137778115837399,14864217973456551570,7046704725890203577],"proof":[[1938580041312859864,954485156269238026,8603789428713725165,3198006305356844062],[18145949041410291351,1125777828874896407,10719161441673783316,2551926719921477121],[9208885652783577356,6213601899332979340,4717102982777370296,3195618805592873166],[13843087384154165654,17058475780721580464,5381380831347327535,2503629586433539034],[14836833095618222894,9874945373501164516,15029419275100101099,3143142764970412702],[9885869726014368771,13686834087814933749,8942350307599308221,1665829847761102908],[14506948900700100500,4810465070811643563,15774740091360517320,905652621680589176],[14889493505692566052,8232683243145181303,12450006610778359517,674177845823091184],[9529235157376575084,12639008820360667440,6910817947456222138,1100699829410051443],[8093257173613260020,11030253819115852377,7534133989694767698,902794213547130104],[12306973922205257953,18134892844992046818,4909846925181999553,514217486188727486],[7440879363638726122,1272187568204886256,11807148749459268623,2757513016743690613],[7193705033799763541,9048181582346268552,11152058647750961664,1742650808604916784]]},"quotient_query":{"leaf_elements":[11715541082376939109,4785427947791871753,4513679819402579211,11765121197701432388,17038444287545573377,10194889225734041142,17431646703564181442,1968121109780071315,5395063322482912713,3616160632711731761,3037036876754508369,15494927300695837137,17862189988663841864,10118585799275511000,249223075669328773,8832491872232259530],"proof":[[11074024260003894156,16123282783626164925,16976138986411868847,1674334717044204127],[8986016621553259645,10426564334412338905,14100535579115529620,2981436315298318035],[7012679922382429698,5690885929871689182,9835540414068238436,1030454823046666365],[3146896976512823038,6197532582925343946,13006790593063659512,1344651477127557430],[3117270319437377815,2590224606535071273,6055845542174650940,3484397088920723337],[15151760347705401981,17486326993421710081,6601047290932906027,3289686737649391807],[13914392795481085239,2906380843974913903,5162147304138445235,586545343956791731],[12604269867243388439,2549553504672189041,6892906380449938870,322716651933799378],[1339777488830364723,17370862978160072258,13421012144552150788,1237801771660144071],[6433617677093749054,10169252695088108363,12956811980736558685,482492555498447276],[17451694591408679228,15229411708894453702,13423381248400178260,2428060335885006254],[10036339106512996484,8017919505745166723,4863977692106479589,2511454411117686761],[117417962886288672,14214076626666423966,6745455965795245453,1238354374129802593]]},"setup_query":{"leaf_elements":[344692420001368884,7492607131540632034,8257948013198757220,8047027079021827492,13803910403151700886,7632265336585485259,2536075865751646645,11648672170537281424,754548954631715590,17820180377212813545,3072944055324723716,2534473739772183710,2085622283604625824,11393381965831765251,5812873261263242579,14840973098349293788,9227112637176663220,9552258341387287763,17637923781559005337,3422417809391663660,13333139124733697639,3647468124683624190,14190979028215941305,9555677671886835966,1737765290311363783,17197419382629410548,12148203042050076264,4283722492505416307,16655184484108007684,8855627615450092131,16149288553927578280,16671606255647239744,2638107051052749717,4561208154088393085,2647432709626951113,1833688766883832321,10497156971927137771,2666754842495419182,13470901466445422151,12076120655113644811,9922177438246328384,16933231394279210559,9628722714216543255,408050752339896991,9523099887036050521,13982462149255376426,9714813395899404367,15992282904696619548,16391407959810280861,8681092985477424638,11022506430903821199,277869443551687539,15952331632792898632,6893694292430048589,11513016763926483306,17511960280747396185,14877686735513922693,2433844682136441043,15957421598894713166,8034890539952741767,11406076511589545989],"proof":[[17604334196147511468,11516951541788305836,3849966231838546114,1536252348181713641],[1133124906183321463,9603146949859819018,8313897272647245205,1137407403688009210],[6425034220152468561,17564682975554556235,11412543979545689371,2466319148659769002],[7339846053571779188,9969975343132714890,8434145332060623144,3121602265206780335],[16697857425406747065,2452814026853671055,15034079264294028941,3387618800984314068],[9530506633435845510,2894556150693524401,13945487373016336616,1533123568275235583],[8625006335721004017,17701549014294800473,4590451143010800360,1560130186163747947],[1911815669472529911,4279521638996446834,12409061294593052488,1783420249759046776],[9063121663294140035,3395379298759875067,13076121161501390867,2748703590746106811],[5186651174829940338,5450565772055814622,4518524670176053074,1083398875337883640],[822201642010616353,16601556358609654412,14983251665919113871,1064264031937084851],[14334209393799635469,1475323473228810002,18184008165679810890,1713996275066066032],[2812288052570429747,11192114483378251971,10192533965505786912,2372986316534941658]]},"fri_queries":[{"leaf_elements":[2392987528550613325,17939857701999044142,12873023048821108839,17314908330595620341,2392101300755201570,17126468521039850710,6384958440597848910,12616127704018276688,2230469494747307513,8550845359871315044,17755324032570574540,2519104522164524939,13859966881651180437,15301840736557296768,3947356189978114829,3893224956100447858],"proof":[[11280925668216355506,734308454033926547,17883380391536858183,1964163812730784871],[10883903318915224070,16996104457966559975,13525462928873805130,2362221175935581067],[5060229525501284106,10279667764116299206,4980689923664689647,1969513744021464682],[10629764709890748768,11315387245912635920,12559399055878974249,3470538790071115108],[10045837467172319538,1911875193229486276,8229491650694377363,2190295329869156647],[3645906702503721206,15735577321776558926,1613893408418734849,1193433823862580063],[15945460522938287791,14692657355686160865,2770370044066862462,3214460137461050300],[1181378642861328473,1511033868296641097,2833311835469482257,1244195921661519822],[14498309021160317876,4335336406161045620,10269803013955387956,85048028284377013],[8616858090914454618,1663075563175866095,3467139390527938134,649361097648535523]]},{"leaf_elements":[7409569235627817213,11092853596628359201,16652960727914767560,2783241007663350339,6749873186514001908,7509570859237233122,5614929564098229681,17415326913720920504,17589487971188676567,5707125141078309979,7415656458241626336,8600623064494317679,4991029240259959564,15264147968995031097,11763557949365541085,18062150852615206352],"proof":[[8213383058746667233,2096162301080105753,9621543680884845272,3252198915055697791],[10701411359061100813,12975162305953384847,437128377654732728,2658603495049860555],[2554445331030411458,7453871052700824545,16439700159787683744,273463037902786512],[9842454499822875836,142106953811037998,4110503788048730452,858470670367287372],[5752376409291467957,667947035431943061,10476895350076206282,2045674658234997720],[8769980020455982479,10264300124099998582,10055189718779220036,3407096088247693131],[2715489747108002065,5305903886920463068,7746148398384784045,2253146750247811367]]},{"leaf_elements":[12827893241671878388,8235942690334217299,14777211708281394421,13426354428492628119,14256946422823268512,1855741559743143909,477749849174681864,7645409670655463279,12680168918836608406,12703984115287695843,13665669862860572312,2792585961915718835,15814395791280513745,13730401134196543033,3321596669379423432,1527635260253571651],"proof":[[13329999757020310457,16149474285897739737,7265603506755726220,143901432017735492],[2466919783244307316,6235684966589171095,16514339429706847530,538888076790160404],[14523714712956106902,7893188032393412920,6957786632367611107,2913391734713166420],[14590848441063452794,16273615971920084576,17011998151899724188,463497794276927016]]},{"leaf_elements":[6278203763991616066,8078050046665436218,10081382088507432339,2222463645849995902,2969879425453338659,7276527334025712803,5195638262421124803,1423548983605012455,399448597950965084,10609950177358245602,3937540680217941419,2177255647077924033,8319833819507901832,10608342303844245766,7261168177199598481,4461036407361939175],"proof":[[16347249376249566426,14583720912265793793,4350686724955233422,1407886625625018208]]},{"leaf_elements":[2966080012095824694,10472639831135879261,4652833482319589241,5368590808610327190],"proof":[]}]},{"witness_query":{"leaf_elements":[13147523419460049019,23311168919126677,16463443001930233346,14050160791100877892,8835689253158280809,12596821854063663231,670815457475244356,6454619743896235902,3937151574793030420,18132223479341982291,14358694588661629403,18407616440202366185,9462265681108873230,10771748738197623087,1410509198549833333,10102584973494851580,3941462942085616073,12098600750424757986,18169308703411575807,11138342052798747587,9219753038760272855,10612694247289899792,5036408730555019000,3312397418274342561,15039196551989135431,13521095822367002977,5497217254416174071,18376580679765247683,11043213540041410674,4425655706552181179,13201333035804248216,11179039620272501174,17316866216220276022,12088110425428911203,8726898737958841656,2758273398423900256,14886679937563281782,11226141573054967470,6259557442143441907,14354275909291427694,14586470055057159108,4125635446112969557,4519397472366126798,11839937221590646185,15660240958208971959,13125309753406623392,2723032435194407967,1045823394883243665,10443783333827874999,5561741036996902148,10093465684213560180,14867892949578348562,17092157471141094863,16476819113539244603,12410997007011346752,5782819402901993517,6520653546870730889,4902482818937629130,9251520023978927608,7831742292425573471,17427242929287553876,11479683143736366527,3259888464259252796,2448770630297298295,13719371660921409787,8989110956619133951,3663023556144571464,4500708866766347447,6484214886968064445,10625851683515368063,5224615404445095862,15065921422859684742,6614640503286906884,13442659213376433752,11872457269056957570,10372259257173855106,17520065047665108331,12887696569391472238,14449267319903632871,13392926147547620250,6913803718128056390,1977169560105215105,2651122267797115844,2724333279060152487,6542831685487180579,16812185913814743096,4026723035609666436,1034573962547178558,2639707609715119361,8744651380218232375,7126575782155210051,3325392561175720774,16991540038261810538,4828855777140182831,5523204254103049237,16723004816261138442,4361816210538388982,11954483886204395620,16883026353852114398,17740090991590757352,386629200286986440,11361334690779855209,17211655524095226687,11612889883110525697,18026760225211125558,8992796687024545321,7253529581720189119,15876234017267614790,6946049875762367371,10678694659561752284,289052244427064040,5814655809011611255,2390068087071912484,13325368209314100629,5629689275843859227,14454820369790271526,13277552965756907055,14319048872266855937,6824542417328094180,16636571613788862684,14480826684100666140,14709953843076529093,5738407961973176261,10930306817687374100,16728099150045561558,2556887685890757487,7138911333154401040,9116394823983831627,14784737206271163788,15248321727633216872,15668433742133260509],"proof":[[15937773056438871764,14079583647622596515,4841444144660138888,2840322401389044838],[11425913739942348752,3974511494346500776,17708406296318220734,1323679452504114594],[343694632719600200,6392382837124089215,4029716365849008442,3257418620094546882],[310614350034367092,9475093033123149555,2186608069505486270,3239558910582048222],[9809561547955246148,9983542693331590898,9978081841276083729,1712972180275487575],[9518438687497213235,8103665350933904694,16386793265962468953,2348328082717094094],[1747270563178215328,3143319401336715722,7099481390908865166,1020395189797517274],[13298451859968953245,8758676502645176523,3915146447991670353,1596467244368166608],[4829086690355400996,5958990850533270350,3677572876392162503,2261358819639150542],[3140279070706501915,4078218573849803731,15130969812479510640,2629247039101873382],[4470573511364538295,3072401176796498953,16201908554622770280,2788031219243177258],[8425516942936181230,483034393298231671,10477473390075102732,150189516499498482],[2402167573558463631,2137105850631415449,4214898604496638014,3277064941376453795]]},"stage_2_query":{"leaf_elements":[16865367687343217423,12409083437457577224,9516224056741658917,17436161530373813156,6944786253140356017,9520016990185623310,7581944854836327434,4916829560003237374,5551826571466275767,4606284051621228082,2103257833490452531,8482806095065352661,4467846039534117673,13557732382093583597],"proof":[[8145030084669225386,16993337258496349084,7803034689424140172,1457360888268617391],[2301286803543718576,13607669363691748159,7057934103939107178,1953972944027417697],[11986836273869629152,18165565413525437421,9019073427840066341,2556575623833191698],[7174161697971445789,5527137959234949957,3232833478298655761,1901732527304254530],[11672352248515203167,7682275009124944681,10253929940230036842,1445361917637480776],[16277424713662625778,1352674905560055726,14494249286001805380,486802226530029216],[18160594305618128661,14728935349170180064,12514929318247900034,367399597394383906],[6537130901265295283,16485063720762150364,13823169674010708268,2631769435256404356],[4859248762256803829,9584343984602993891,1987540772204714605,2098963894906190508],[7031515034786319741,18275132255742271382,4323677802722786521,654301555566673801],[6799894136363316477,15151782857945782652,18411117048748230506,1898708911910688086],[745666826706744259,17567446146397159290,17029694275521485389,27260608986812560],[13098703293661233855,188671376608403103,4925193949924778707,496229296521733553]]},"quotient_query":{"leaf_elements":[8071983920800777309,758095193053083045,7169921891357992935,8917485298631239851,14785909186135483121,779469414356988677,8591052158266163139,5581974001777227986,8342592077005823372,18030250414066101294,14612125652341960163,10818255133408315749,2076210983678752822,5765653504136703141,565553373892280786,152175554687944918],"proof":[[532416335538558144,17536352945950629972,5063356639523845406,1412421209920949686],[12215826345310357836,16521906082244165712,8339466444210997644,435618054866758079],[13870717143842996689,3682533719895005951,5556913753892683921,2621993743363235267],[7298165705025405581,12723961350317363997,8974912598601097617,3203788593530189722],[9650793842393890918,6165578675097666124,7267281840800999812,2217707175666589079],[16931000801251833902,6052509604245528889,11968488165785330371,1556672677063880322],[10903435829209587983,8956446871989644359,13659308161436375625,2398062273416001619],[9346759857334410035,17357879698505902408,12716885971271276232,3235671482609092241],[7419082044657024225,4510174949114636386,9995911549610556160,740084141018955692],[4321723759391095940,5383714445900943082,12924114311805099977,1959800114989123529],[18248813950090284891,15264769847501014554,16470925086369571060,1641734585999141467],[6483723199069637619,10922280988596920056,15638188869268327681,524906435665901280],[7064726902681906417,8802656868035565002,10106252046860638745,2781091557009897750]]},"setup_query":{"leaf_elements":[13780356109675786986,12975113501305142114,913335293252397784,14011060590877426828,14194305188187631508,14958856883757562400,12897098140715176526,2354605745002321668,17702679229205975409,5002701882917450297,5241166917824147274,6409222915107830559,10310650137144470834,147552982597486470,14471993069029173748,6890583592295170478,4931822012112753395,2259234157201488888,960572411223526430,1934195294403299529,3383146101636382294,5216202842907722569,13630668338622494572,16630136475467735482,8015571075657493448,15545842428515564458,4047931579547470827,12128134130686665704,2591309062263837756,5510400568892977004,17054657345344489639,3040119846158358151,17116374513178460987,13838166515900007172,10578440031150921080,1114627350632606259,7278276491554090803,7722009309549136079,16002948821398728841,13613710533850860300,16252182699661471966,17936394355478792942,2090621449182668686,5652311521299486408,12406887644407410482,14977890123548069895,1238255244595693045,16008012979739464834,11550415728927081380,356340974188237113,174504406739336208,12327353713411380107,2724759127286113942,2793044470897842693,10480127236947896517,709124363879304789,4714022286146532432,1086475195268048792,16747358474064877282,12291282719847052234,17483186049855412340],"proof":[[8151122552891661260,17970890769692360623,16437712203829900391,2175936430666160289],[17899225497033609767,14838881026822714589,3881950077457093194,1857221262842661336],[14538476422751779859,475923934177606731,16506614498766794482,1203742249589429518],[6819455283546442508,4177579837198529193,4807436263519348507,2552694276539514297],[4695662747957922060,17097951157710595103,9034450228484610061,2865084511945626904],[18280492342235439469,5655752789397339448,17296446819445722798,1053401606864585662],[17781090622886655784,948669538971273933,11705126096938247333,3444018051906673690],[1432881727127110960,15345576146065276842,452774187341208890,2841848704248745791],[9837277652016128890,1813434351550800808,18064557743896674895,2554336843557045670],[3137825612869565015,16190956652448818454,13814802841207229689,2727700156159039890],[14211253461318336953,14698553904440713876,1215335496790964480,3214092473229563681],[2319840627421732396,11880222938202960862,6462039118647357450,396343187455400076],[5510389358968454592,6342099385859423646,15847287637010183663,1721032798950188614]]},"fri_queries":[{"leaf_elements":[11132821523775981997,10062302253586642026,15708443357647972139,7335558055685359582,11433054216432450802,3202572890056184765,623442761536022151,5057092582045921628,968286527558009969,13958634655135382776,17493585260288284625,1309807794977947513,15883412727839236354,235159256517941177,4220823523746577800,3366958132756985156],"proof":[[16432945161875066624,5011333032354116447,15276041346919428460,381829477803512954],[15073551259154354648,5702890225957295179,9883997555975941861,649480079750540682],[6537257624729719083,10082067332431634411,9984240860145404040,1197366791836183625],[2932413117697364288,2539022990246264701,4707418089172622562,2191718811874383429],[11268650306520981872,822957727287946688,11389419539557084728,1558209520736845273],[14880453339761676419,6303383025418016265,12352442150375740021,2210075666515788345],[2619500987714521286,11482010577440727850,8410370375611017021,1364049326102807099],[14810850173207459937,2116454594748557248,230163200410766595,1641052023191719386],[15449742020830670463,2504111050166408295,6502440755783385744,2746750322419423511],[11512094953525416513,301201197378265374,4065232932777357782,2702801754939657824]]},{"leaf_elements":[15153100985228493408,14905350214289553170,902689133325621331,13106770401205820010,10548203388718182739,5631226971291496536,4368583201056672465,1906223980146206391,16691927880260361520,12583145723696337313,7899590774398371467,7164465056247216164,5419260403645748392,10858167653914846352,7302614057661440653,15876271216906965425],"proof":[[1904783563588208131,1162898314847537619,13267163592595629995,1311127455408813200],[2392141390304054594,11467022385129410741,15142332774791175337,245636142514410844],[7783768723070173024,11781420793876232060,16791622723489075159,44122111287453055],[1132848919924385043,14056526644500741775,6332784331118603800,2332792059641125617],[10191315401445696412,6280994496960481888,6251536364121698284,187367878256504162],[4690438310709256034,8652297081282077156,9367045947916506578,1164431050711913661],[6905604683261516761,785630753018559997,8071271293678686283,1371257465431982896]]},{"leaf_elements":[15549396044150810935,4377449947370068005,13788924562444469111,17902790492450737797,14596478425670398602,5656777946315898163,16447723180772387181,13465267525287585420,10147321902506868296,1196706565521110128,1798941292919754308,949685843388830599,3564976715598543520,5097215988352073899,14057553010599484721,11669462938921547717],"proof":[[12941068349182194076,3594824413437589077,10459936716266878396,2338368559615314095],[2697009025509228754,11000852118224199768,15389405589811843678,1770937907911177182],[10890060001537195700,13057372539207777287,17410616761313584025,588520907784414304],[1389524551255036162,7115597326301420030,4677436100140046760,2997251062732232682]]},{"leaf_elements":[8766804231547517221,4314020161339189469,526230993367059777,1371290347504725484,9718295733965069127,18006200898151862508,4150610419468893976,14342643557102012012,13624566138619880019,553955421167211366,15268536086186198656,18097336813190350750,4289863886401648441,9987687823700455758,7369310771996817417,6478430192287573656],"proof":[[13748503802770165510,6447469746112887630,5266659250392852870,2048396772139579074]]},{"leaf_elements":[6865243823879750534,264255220950879342,5012916995573505337,7094628130780347210],"proof":[]}]},{"witness_query":{"leaf_elements":[11948795710264375955,3579972359226832183,8536711601574309381,11396829051685123078,16952896974736752037,4812067023169352570,752137558755471761,10084960256663509835,2544750230458809155,17030651141629010623,14279814900408777125,2045317724438886490,6941441122062687621,16834404791832950995,15936326321371307779,1329410647863596500,7727519106571359668,17105886540561019822,14353595911971258176,10713749166959871379,16750870551519249184,11323464595555265601,834845291311153654,17529180241175587439,37848275059131677,18105663000759888816,4393873288488342091,3947621141477337836,5799050532406529507,4401451964912879503,2393899212721697554,11969769752241608791,4433635556526512125,12474067865023777236,1796334476796406826,12427974951280116751,9184674791025121397,1939787536911140975,7776282856808946117,10953028547075317785,4624625171157010660,8680298032529616209,10283785126883384243,1280898109036960772,14147670060461597513,5297624234194698205,11321143869167180287,16696438873603057900,13749401227833466920,15835460497571671337,3565102563089184722,15574142811337068417,11477996794931765834,12083671708967381374,3252689138429560628,13540031273572513223,11217001327991968539,9037141442767471077,4167661026166268435,15283164909420815520,14531025245956542721,8776115548046335055,8859055840084181636,12381786712538831544,3434126407083357024,7193450252638156393,18395789363135852426,7999516356386080843,10275684614336317770,13806736820695529455,2302350665630335882,13103426674578149310,13195379945687255954,10887709560799869005,13407209527852098370,10352194363026426169,13038599802795065660,5180910592622355210,11772544321268490080,14730426422217250088,16763453130020049098,4036830757664011040,7353575774814667341,7369097360190511078,16727069799353205451,2861920738879633079,17252053550106222090,10715932931918828114,3219323047427609726,7823313357974793447,16796372289272392201,12423584609180124312,15379435781773213580,134486740851710209,1485507674877020542,4618599570982800077,11735816578617590836,7843387119214334584,6211977022205361547,3935757660625493349,7474648453258992144,4762578523091358717,1271477897694462433,6083698776546104610,13634780373534588991,18393193002704725586,13579048256376560477,13957606179332349716,17493094982263522769,8663141994412089904,7282306780829774321,1563180342260108747,9332793408626379650,12843891907403264952,10835097388363274399,19777796151783993,3000136436195076083,7073744392544836758,8441458936004030459,2630130599048821497,2416727113278575964,12751883671089468955,5625413016645574770,11838182331542754612,10954355068839399879,18272997824062609226,12631306951804659139,7428505078978945213,11149821451768023381,6327508690927457581,14515729450842505361],"proof":[[10554659508671778649,3569879561146348851,2623102594771511313,2199507477741425514],[13374087441215736910,17920513061902029090,2531204468149018093,216389700490800985],[6615341234702182028,9791943736305547849,13137968285055742591,2467731851776422880],[9603036439868910141,4598306675817751940,3143808107535269908,3442704851343000251],[8176179294327968920,2933940122091421385,16755453167672504240,2380887341492756658],[17140186722172320504,9317579894634382266,3096285794062678376,2110828512695423886],[14055757009204859914,4737595654705366171,17449717446217913387,2037498423728019081],[7061904308973836850,5636894431559730080,5330257904007396198,1718349596010735736],[7150863009503969572,1204505448702042210,15651957073007012091,235018674792616253],[12074134137501755981,16299228162971215472,8115585412613276480,717261193191659743],[8182014679444923342,16445826551207987290,17013822517979645025,2656714516067615980],[6902291296385525908,6282427285539483573,1059247308760891000,1681441560494504270],[18265673367752908138,2754640070048023901,11724482278947537297,1725637765201767315]]},"stage_2_query":{"leaf_elements":[18280009013508119638,16467590438846971293,8060230084683838439,12710864283649870740,16227875809967901430,13390647711142671433,2655004526135771958,16791319757306977452,11466646892680517283,9576817100127526579,739400022542534316,13559303926608930368,5882155795018058174,17574861964033823578],"proof":[[8859287737477806861,9844682376306615927,119476763743396730,1886925092232090086],[943937782278166030,4259752835772241679,5032728382915577606,3290392282727907950],[6332378566786974686,9118474372335905726,4361268773226772851,875097267182184941],[1132085936305677001,2696146792986145696,4989887274096532267,2126119154860762241],[16920399981787442539,17626586397547740771,15292983802183743424,2281973351911042208],[4266831146031759935,12542423050082426748,10945700689640780177,3083207207112374420],[14187957889119098088,7681103484547388231,15613736954228619111,733823455672501024],[15638473760976791030,6954496999646427829,11498669177228386068,984593981875874345],[10258136441597804082,13038055152395310458,10056821565562679030,2612210956946026845],[11808796866521203003,11207404278376310701,3721232178035827594,564698731802217865],[6442970993011095046,16767343503915309638,15639864749420030818,378850544348321779],[13986678099248396499,763132589384391927,9776001136007254836,1152105376275273830],[11814671747401227134,14051467977723724755,11743029036639551575,3058315192689072958]]},"quotient_query":{"leaf_elements":[8265407751709832254,12296715845791742259,13670472454793571793,7641483485934747242,8742559451732788619,17528219422631035628,7131202490045574161,17222732473806114304,8915934786128424296,17478353321914378993,5840707644096178088,10929213252143016092,16735111816798388607,18162818324827994866,6406717822799112869,15830288299443881608],"proof":[[4967577392751128547,10231120923999071985,2920288187933826456,958807157317245791],[3092394109658711809,533194440803307039,2107713047296641498,281917863637075782],[559436666174139517,17992402307799369495,14085846431638618078,1973882349774879321],[13550452749842863058,9796967015639244127,5629053876381955083,638345255365464904],[13746150254545166815,15140374587070621509,3667595646034042726,743544085393785822],[13589156500723121971,6442717902188720845,10611670445803161354,538358515115667240],[15473455648144377650,4252996537459122264,14782827260532056552,2939415269244089094],[6352249808613789468,53754944102007352,2478300398864278931,696724686821481561],[14767227779805144849,523980339935641819,4916097963648211856,1699271712100775424],[1673228963995879266,6412421679271202550,17345905633693911519,1453735194706700661],[11218010515171313392,101745210632366747,17231656761344841354,3308126040096115441],[1142141420400307793,11479452402825870557,17088604191880103896,762895272704649451],[3504417128630898722,13418354669506357867,4877712583074407316,51888638990079231]]},"setup_query":{"leaf_elements":[16747052227524051105,12870503493232299897,7387220514673987351,1339333837602199481,16747918328338546696,12987524862862206296,7458184540077493719,16561956463250066316,7681491435899188220,5236884676411369852,8143334029580469066,13058047349709851670,6210651816470022307,1259607409855661529,3571654737126349132,17815818436527183103,12599248445261486557,7682359343352202390,18176536621467437726,4791971110248363939,15868368691154763902,15423037147980089460,7642077975305740149,8293057035620600566,9949842387765063022,10921241653581493327,7557182855315120528,11744231115835753088,5984135213929303501,17202975187523845910,3285733334806358128,5316891125243765785,3245697059015649060,8083182424157831820,10445069711594022011,13572469799958737371,10491333743773195049,9079500663331008595,15585367930935648103,8073870201697034053,9267910660633483394,6375683406729213489,11176089878825257988,3813976916188635840,16597814978461411597,6299174222607142499,17869074988840795169,2460699796722598779,13071802783172978008,3935188194871212364,5279902447986189562,13660219308385664673,16032255680562315511,17226528245240393823,9026174948625806070,8868506835612959507,4834681182567607502,18162475110619560865,17383086281176264106,16481554970874116092,6921655115418354927],"proof":[[17020888769200384246,6342289120486297637,2282033168318114611,1109450360645096053],[3913569535061780345,14779248366466509392,7332546830268806066,292953922607843272],[579772160864529171,4852821184334431198,4201029223297409239,1953555181573085614],[4254964960699300228,3756083058429470723,17175277677537909926,2570973651596630618],[14824668216646963762,7820528152655483340,2819609188775595586,671404713276198141],[2609647830242647286,10649370127312789791,795721718637389357,1141836006990541302],[5574920143586176230,15516872148987706507,607523082096478731,3212669687190729760],[14717008524679147372,4650951541322338538,5773722309021551,1428899433806618441],[6434930348788884492,11398719568328309163,10493250540552169876,2699222612433752275],[9161858143714012692,14583841292042326625,7505752205083140831,3223826884155486379],[12936042570630472179,1310901294642854077,1974545396587028508,9396074164269318],[14626434129209657568,3704788492558821904,11586933725645472561,2183731847757492550],[16340894896221363037,10515488107363041749,8989735385112029763,2859595575457666712]]},"fri_queries":[{"leaf_elements":[8953210716521508742,13430643931864996402,9186008392111375344,271640789856598445,5995511245948303339,18025877909858361663,16306711897541346531,11706973127133663203,7231821491795531882,7888736550478092763,11385391423263547112,8610557821550912546,10054511550871260390,9589186668815366176,14554183551471723688,7251978104182782834],"proof":[[6545876977560049987,6324325623585059653,18421782886204428654,1336775510558370743],[1784279041911295338,6893990376610786087,14657258225746427440,2894307102108440182],[538422128960354073,5079659609558248009,1601371199634404579,1511162614920031178],[6360940289710848672,13959020359172562063,7734307203992874219,72457029483636045],[2939633391558907317,14596408551291345863,170188067083817089,1591644173987587796],[11959305332501688504,15141526033257603834,7456321919182154890,2580728452360402841],[6380864619414380636,16167847419220614059,14037915157061739524,309969490492929172],[10992314003799372557,17322716724534720083,15751576483304408144,1646111252671489369],[999846444995399222,14011138294935011139,6667964318074757587,867213260052525034],[13614949841622580336,9399492980024187335,15638599896098024049,1538027079629728594]]},{"leaf_elements":[11530333504239215645,1751366369809449551,8781810676880441574,17898744044518770217,5068123437852440080,5767189567059560148,11212307793995376907,8176805808070644216,11400983458819192016,4448425662802430695,11211522929998577173,2774223502593013931,6955805867371182938,2912552641121283820,17877098378778789567,3452134661020584941],"proof":[[16046424079505256161,16717425652690287279,4028470104283444491,3042689486287658667],[12975326195471338756,8925853549187645950,4063408808751826092,433831207167069807],[11142964206601506757,17493852466301855203,17753202963181992484,1533192299295367021],[7772034170709087401,7904938873317950700,7550180933320659345,1472476815663134744],[14619780283819901678,12281755326726147473,319442712941351599,1558941547028822906],[1389768311319449007,14236537471961652686,3349081074204103601,2876773415225488148],[16707445333894112763,15652176173117182806,12717696149262687733,373930509062837472]]},{"leaf_elements":[4522531214427608807,2708895458228607768,14378655018498255086,3701004547392321150,15598906413480729310,5769931387414445109,5837999110613815764,3203528792294961933,13933396286397715199,10145643743243072268,18342763054078240104,15109249409918197141,2868717040574798996,15005633071425220544,9769550803238356021,16923072860317850832],"proof":[[1946900366549917852,17640196811033354600,5063518774281691521,2709440878538215044],[9638837243345328524,3548442352561019961,7552415862605738816,2591611983958661810],[2598732342918378786,5317963112505505860,8244752469313706919,950042062237983842],[1395445178162007610,11626158447455766250,18397044548169564307,2769656745606904775]]},{"leaf_elements":[9036089175381653959,2987875599192350377,7744707005118505168,5188089847094658525,13129935381927018420,3730150788540291038,8209729877721515470,17090538519922816154,9607968513778767361,15071132642506767584,7320125160743097689,4991892819851375059,10068909456476243812,14089867269071297833,15389351978943733972,3387928692605495898],"proof":[[12726638950376879646,639506612650757720,16912813671638057237,2919186756859426224]]},{"leaf_elements":[11506617648987991818,868082017674053972,6543021463611153452,11748771781491803820],"proof":[]}]},{"witness_query":{"leaf_elements":[13609445363672058865,9004000194728633488,9203190777616095306,5704151393958158684,13943071071313722973,516743361292693548,3522504134721135699,4330944302187500132,13110847250708054574,7425353087918929045,12990866878127035602,2151608528275539982,8748923711574586652,10668207835487511735,1523162534263904122,1218838723199413915,10808296954813393957,5687162473186451363,15209327970045065292,3951675673976805969,4908979908125287679,10274111459522471573,11504543762447288998,12449268394547657329,6162693352507398177,14413044192394147004,11581473165461705958,3155140515343760889,6276872120420081115,14688735611343963444,16620684949622073505,5588116089686305708,15699046164467573109,1923293440709439310,12311039017435866928,5383743772589957981,13494849223355563038,7225400992675380322,3956398665452109996,10538442769746976106,17013309398513202077,9547844172949669132,17962357870602496870,4973584233154871277,16014552364114606318,18324774294366523165,14844219196149240939,6019631490886836202,9416740548632323975,11285924044795049209,2166517775118112441,1228775463662094079,5703876632194132248,11657101798873218654,8099208127820823309,13499009157560832315,17457998127427206917,4248127420777576871,5142048344565896224,11338359845416697358,18283139880576438418,1980917715988395958,7351923662374593944,11671827686272062766,6340716764714084563,8820642644959699338,11569225906387690027,75315836347278008,11734462541188999113,16687779773465276438,13300676586325204708,1163646708904801580,1681812354070235948,8052395991962424189,13574789296237346839,16912571277780360286,17926927983601401311,12274663569708932811,8939850250294622223,14550984782596874225,16315268369790642435,16824694024440912936,8915551679931455151,13256960044151068521,8351992504063123923,18409350461967529477,10457043864918643311,7211679929234810587,11646063321070674059,14232350912811472075,16686263507037135390,8056363826536589674,10110623296824470645,17868758050231466850,6979190633374858371,14222988737992856210,12136090534955419122,12753665460362974466,1261238335654171349,9385207785693882673,1946805415264958900,7151847749346379461,18386749168922381274,1763011014335081578,7755320670047220648,16615136399969194594,14650786121190967786,1704424089306468353,11504677410476435218,9243396988346474418,14773128140521429636,774572183526346242,3585531237397015297,8104441237692277113,15224131874756537337,17457865195481416231,12167355988012729570,9814302068127561377,11139928175443923754,9472134390289198151,347071090272136776,8637235336394504464,9915197968072456538,4595071055829837790,3405639937074862558,16521576917728237542,6887642607954641134,17095871925285995419,4869434994002218253,4636140026373734638,7966416483752363717],"proof":[[1225688189026503549,8596884912250507941,5552230861248882140,374533704338334324],[14181459216776320188,13311692323378015327,6319888519519164080,1060043678868322034],[17259328171483111412,12315794921078233439,9142976098950004903,155400903858192156],[14515024104360711076,15046871677288354633,7212815095997619531,2718610444514085636],[6343340543938177797,1346809772731274307,14694273686939833760,1285178120703155845],[10846291898719997885,18120623939563648130,16763356527051280811,307281961404908203],[16384246222156383579,10631303849445819822,2064151195487627239,2699416229289726027],[7987407125754238671,15551694315394481998,10021619234004249548,2813174103834777815],[10279441134453647248,3225073937357662560,3960785182366609467,1379599797725456201],[2497971760758312965,6941215204086950283,2542074989584813641,2224767224879212028],[9529653253922139009,5282909414936017816,6161231114367956174,899405009548116716],[9653994095741149648,6693767989202592068,12384719871825976520,1147806512135128414],[14367620299360517077,3486062918649683097,758936314403206639,1603949708714258502]]},"stage_2_query":{"leaf_elements":[9083429207727951986,6686421633399160323,18293844454763530889,8483912038460331146,15266331531059204992,5371280448545886469,1192853545225990342,9390291193498123406,17803131910017342709,13542450720973917935,4529691724312955013,3130199654590855049,13581443293629676985,8833226072186190360],"proof":[[6034114375601680956,9698927623196739707,8852575493445420971,784195498101162586],[1626579736915843771,7060344006413099212,15544015096109843037,3174070312188257951],[14244742990839596573,11283776100249779030,2799135921444820417,2882713677914872668],[12389888586017365025,8145497029132810469,17698895731931732117,3215804019530496451],[2172855385536301407,12045189171047024471,1506099275893602544,2712768184820846857],[671158704972388957,17292776861394781052,8644653171866220581,3000083257489024057],[6045883898447726006,11822990785674317386,7385067520396736330,2381408147705553132],[12646260384349554022,4011993110502875278,446597308965330218,1638270342800571886],[10138896492306920536,4267193470827960145,5743714634372069362,2005093267637534173],[1770352352544555214,11503347561982608092,4967334841455303620,1881066244197976384],[5830900046758375023,15604014666533198478,3708889240989816115,577453142693312212],[11586254663808444089,9649978829832228512,2456767594798906555,2922524290208600819],[9302781254238343662,6119432163943488281,15090348966859265029,530198869118147718]]},"quotient_query":{"leaf_elements":[3676198479521639100,3218396378745322504,16198051468241260058,12598701070981975157,1292139625395755264,11897496968982380134,15679579860020113661,17355603486353203769,2128441636504681836,14860215740787472593,13964186033657593217,14355701217251943746,12439387304594169630,17281505513718197170,12813781450641474637,9993499324587015109],"proof":[[5756478946986725118,1052668720155137944,15451377503015982132,2241552816998635411],[10933561021048947813,12806903953969785580,11878379809640065882,1948755542293338808],[7147743203456391344,8486308561172142238,15227844469507035973,186022230370174975],[15845301973963794348,13890796863322776221,9636054203030181071,422717864229023998],[11764461991183093693,11013239324103336137,576318096872214745,1614964345462808907],[7132744645587727370,5203774010503966966,15132833356544549044,1626627432396720774],[4358052595228720781,8624465166383960948,10305725361909701823,3349242269044271159],[14403185115857649701,7372634461268699265,244434204854312400,2604902742872593804],[4540786855679701672,5422112622451914833,5685316574463970743,1190117837935105102],[2228005610798993496,2004724919195437665,14380929959310661678,1689511098488711356],[3567423335356629639,4411325966704188513,4268360902456184506,478658816986403953],[9173486775257139146,10137054949619224047,13924502850789890943,2822498744591213857],[8815952717605006386,4526522413909831776,14701097622325747530,3485165681977640036]]},"setup_query":{"leaf_elements":[15377337040864929377,6856847601147466964,17128308400437006829,14158611396822916182,16282794400160370416,7270371054811524792,2525131608047386118,3548075438542246338,2279790174304430185,8220151542218378422,12538694279908947782,1173826758511439009,14668441215311292145,18174026878262530682,924316457313747080,4369586636286330983,13638194858655035712,655882206293094578,3976174283193334524,3663557392574043513,8596693720384034752,18356948399564277144,11299756743551110280,2833583976580694254,7211677531670892135,9962442022104397805,6840098126822209883,5295908684519848272,10337119492839838052,17771882894095402129,4862035831875903549,1392621135705096818,14463835865887966650,17505001254708488827,2608049222825119491,100486700978007380,18321611346027550013,14899524465515442027,15682614167149768187,12273491384175497063,9765510506496749663,8113429426867211647,2963672124475784526,16449687295235955288,8711258994833886181,14119455702971143010,2357076761304754389,15577144749276496409,5369703884216727837,2669984008219415268,6868993635426302844,2375438983292015016,14531630306215598125,14875658994700365441,5917030201440408747,9905939539741454678,9114109983355034853,14177450029027642450,16622800381761502637,1002794210325826495,2533291707800199686],"proof":[[10302643081314597765,9014842997188822693,12179748895698952538,80707225326598667],[712654472999723702,9320130616043818293,6790043660115723930,1622926617377518303],[10403097884755916339,15686591120435062258,6336378395282532700,1457247642936875295],[11169334405674907084,14226943977424223932,2923426254348574602,2287222921881951074],[2069411292007468391,1741782692745125535,5496652329595839227,2110350203367401289],[17440757370267286274,9542972311375798417,16006171171768105736,708345329836378570],[17272399708287917285,16722497636434276504,11702461736567250978,2145610117747562020],[5053075542815791262,544790488003267972,6829939782065395412,1461751306701986392],[3400554617365919751,16519018606249882725,11756946234401004162,2279041505962364654],[9425367909661232718,16212916946172534455,11653542791948258347,1200020914090831840],[8897054833573090181,1053001915298800933,5632870258241756242,526235879397439495],[15200607824454873355,11040607145831835802,4383506428310207721,2767645816861274925],[15649328145457671106,549776313160692971,9928450923310963291,2751020716435042226]]},"fri_queries":[{"leaf_elements":[6181750473293269095,14894875479305564372,17645677149446644138,934081697891498507,3429790227546833910,9867975405586468804,8630728581583380963,13152149945578256278,3160413206389792062,1021842979186779246,5677592337848365206,1818613269275235459,1786315513655476764,14245415459278266930,13952226087056789264,15512258641624442969],"proof":[[811137936080113958,2186355955277390988,1613550594902251600,3424771173218413999],[7125162390246100689,16520341220538785482,7195605656993273108,1348501386223720556],[5502044875509087392,5542936917094114031,9101115753879716193,562779576613339683],[2745480676937364504,14925595917447314297,13674409487407000457,1479656902561694379],[5740410112755126766,1903757309147221639,7896260668526701584,11165980192738518],[15686790371055531565,6946454947760485889,7868064144702226772,50034450653217654],[295476054630260715,2630830757687727646,13488267475738836353,1226401965370485671],[4703718381639210305,12636191310739263230,3062071949666723777,3154517507701705152],[7385017009064519880,2637096054591857111,11922713896890014705,3084456035366891821],[18274227798351134084,14614972872318737132,13670777970563782359,2498334094624877115]]},{"leaf_elements":[1247437131519566648,5577832315081708883,4784669823468438200,17570693216835477501,9177115701836767086,17355615263171291619,8710109902447031143,10339112350006010127,2130139978358051700,3306318597656897294,18211027383887527403,6895070617996846474,9618785017791604678,17932362345426124384,3744574055042659299,15367808790258796099],"proof":[[8990557699678572383,13613345054748425557,9881952303528673150,3322472895231301278],[14507020966043414452,5779893411036489515,13245415405741977606,2618049691245294351],[13591393288879762381,4493691537977151089,5960445238358474400,3401943635529491189],[4275122454678480340,1662959997101223502,14781032076294262171,2202924470800566547],[7853223832743604015,18371017161360746611,12006668819789881266,1595732005214836354],[2740910005191995843,6716625060797660464,11518524057840860956,278856238073149708],[3864735070791189707,8330668194952393004,13164775125511877827,177041749183560687]]},{"leaf_elements":[2167546782365224427,12972500962488132878,10060384729038741461,965079689529559409,17185003784188946805,4114501435647959198,7340445652922898361,5626372596246656973,7217929690013938425,1117583472920906711,3508602984700796914,912924360294464995,12217761841714912930,14528486953412149277,14359975623516507265,12595374255463602235],"proof":[[7895962028324653724,3725676821329781357,15688631988854298891,3257510923188662860],[16251869741933535828,18422115813315679345,10222120882620913618,2647976828729845650],[11832554300978104202,14261403502407546042,14520703700616912472,468790055090309713],[15036230558710107040,11921162934449550531,16484118682594038981,2366781330473308508]]},{"leaf_elements":[1161939574018876374,8351817840696965648,18372653301453144055,1094858428888221872,17891497325732335182,6378736636084565709,2312548455298580963,11108539684721161071,646629569524013389,4395291750589940087,12400931690617795476,7655909668271100330,16676308543461110775,6945943938750155993,13376778799557250354,2903074057851475984],"proof":[[5616782601955618559,11536326776059504369,7332699799654596753,2141932960124082581]]},{"leaf_elements":[11506617648987991818,868082017674053972,6543021463611153452,11748771781491803820],"proof":[]}]},{"witness_query":{"leaf_elements":[7469752215233654574,17834740599865758764,14347226749229049243,12880433748217527071,1738735970169606598,14563784745051577497,2286536152186918569,14460699020721935159,7580943384782148226,13840945333365316862,9606749402380420287,13640354217980011803,15216802349832998812,15627811622321593861,2928820583553411653,14277476300549518261,8766449320661475720,9225519960330709821,6922175953179715837,9878690395073304819,5943422640495934177,7199741031484795359,5711564914377883519,1254592124505412410,13292951200259330726,6002568952460468529,3318932850324359917,5007680049221520589,3502648265178710332,10024476664996690502,4262572008876228033,5678410033169229336,1423950701393836136,16513099284402528972,378479404086589430,6734870010597185100,2187669501726751639,4415748919683634134,10897872495943958347,15419514357464568140,272667006752038356,7315223950791607314,2226263503345542780,18387775329009178565,14619300509960752326,2185368985892156931,1358426817693427290,15830993817921172075,4233745479740976462,1093286104243634570,12542847849284845366,560896718168510821,3132359466131531551,14023088663811093640,7578064235176902675,11781255280495815845,5375595860517915991,9287013554547842391,15836146185825462537,14347858439391649786,9496076266940250726,14357514942193984549,538763610096190356,6945027195112634478,1391756693644376141,3036380042089783189,15256742394942888214,12714457391770210538,718598720494325470,17716920649783082953,17244859700701791966,13429260773619767260,14790174337497812598,18252149204813312440,1710850862679355053,2650071210350936910,15808930557231062753,11472041748978538401,11777630659500255464,2481188753854769817,3275736526586068086,7975125631965826046,8490032484910595709,4019679985622960412,16099803215583857440,14282469282656472100,6406948414684461792,4061293705144832124,6278281589629263245,7760713530936395994,1013772222407532322,14357472372360142735,5092722140221447527,12626427217527079654,6660412633265747300,8376210762644632856,7450830859861081969,1030493021412352733,2675678002596499448,4536671327598420600,6763934832343566010,1653765618623087959,997727020402837884,9078573969455809644,4495892297830812507,11347031718341893843,7905515838737354471,11416812138314142067,18366486212697928881,3464893742106647243,5041117812917251374,17840814924079187338,18369675610703237001,1679539639791934238,17817247243019691606,8633191446361046291,12673869746983615607,13299726698257336457,8804472955632465434,4369033040508413847,18364380442345744821,210150733326245682,2523475618864020300,10196218294889254970,11879598382659782062,13830036784629764894,15829083760381641815,9026003364524373060,16465683643777364207,8646243617317788247,7338962262221554238],"proof":[[5392252111131433322,8995869437923621968,7306624904915295643,2318842668576416869],[6495898403711041617,18201549853802370027,3522461428307852241,392675762324335301],[15519182354414244821,4011007131432979893,12657745410961422139,2100204668001897282],[9160906082585450193,14934771310710968294,6808736922980491113,2227243618176552977],[16293797718216876966,12122276356798073171,2384369915371659410,476219887693452598],[18354290578464389715,10831918275454095794,5961255201484691069,3357929147899233392],[407403712093217850,5406792335175341195,14239633460425858934,596163028847181035],[5494716650503425380,8767534754545342573,7992635780232882537,3152457197191263819],[364258889916979472,827696495252320629,7839194783004057550,2161346481293142557],[17677366805921569011,12046422182053282218,8537053646158915002,238479154052576922],[14821677025821634855,12678566443032613173,18428198543260742288,866632219690740546],[3373605446307076353,12141411619945472228,9451450480592638058,485523100920767396],[6248880740263255263,2723122843674386514,16580961043761809285,1164311999391324090]]},"stage_2_query":{"leaf_elements":[67800883350363546,2137328305590470037,9860686601438671193,8384435162418605039,7548011489452619825,8983480842005816775,17277308294330593076,16734829888521877690,5081120364968917499,2005927974598503467,9592394261537259628,12165921373938363637,3852863217057164038,4060640808676946620],"proof":[[7255057163402053238,15344466295277928398,8010336369658492726,3081624969406011147],[6941076079758220787,705032027879267575,15782361409967448722,2770478373654474923],[708025622074196575,12722686116482252735,2644566954012939783,3221104641603436186],[9587537370094004467,7431398717865920517,1501168698188928387,2651396503773855669],[9969918584432710508,1618219624995309009,13327199422138701548,612259581242234752],[9706268780595254805,16130498624848580509,13337125622104896233,909417844101691826],[4454612189803976650,13123890562960435110,5898997438889459718,1608339813416682925],[12594640220544053237,1156768145777532230,15013981586165387952,263214468939355570],[14018826584308327133,11116661523792770601,59879344678105149,963140684177054219],[18228027439090359205,8800860030082764691,13374118243446597220,2529658712834039816],[11436475788057167556,16390444142263400920,76822122693605925,1085789007539480658],[17332954140750592222,10294786215967534177,5921744226753787275,1049539317754457214],[8563593989446047328,8164499793278811445,14204177022024955620,1981295651367553005]]},"quotient_query":{"leaf_elements":[14456303746342687365,10648037396387769662,6978627296740213273,4554554724015782226,6297054717069140894,9521991828400381800,4174189852131697738,11178609835693513887,2878960719783256688,837267366912057135,16072952575190657015,16567326951987880386,2583964272939045688,3077913036749217617,14025020037337191272,7353856486211988894],"proof":[[2506822217718063143,9152472917571620475,8409319086226979034,2224003601505929036],[18219253466903526311,14341200332459368209,14285440521774337145,1599169663540007910],[11912163055057770642,7675433461153645229,9251444770932821040,1800553888519101225],[18164600108862242745,16861401802341795980,17952147666747028856,1840686458045241000],[3596508889608964290,595822521703316187,16979056484737632100,552542585823958327],[7691350746105015438,14338849910825181072,7306050230414781853,1464785913387152014],[6767304703807130404,1864160373733273135,9160167266966438236,2763186315623351161],[14666595403704884749,12086617277725381025,8195476187699608819,1036146677129636963],[12243323317059650509,15495327079374339557,817632647931523023,2609407296211945329],[15552257540972297703,14803442557659497036,424164484485863958,3004148151854141989],[2687059980117537085,7924346243614277178,17285817370875823544,2302383843929577187],[755844430678329277,8599556420845964652,6680122281970827173,1296966116141781999],[14309839409676856343,9713738310784912288,7331134436690285112,971820748569824165]]},"setup_query":{"leaf_elements":[14902217536131640203,788666884859728014,1215547451922050370,2051163210588336288,8763761117880341550,3940312820048385006,12640901157765103665,17558936289235187952,6911289436979064779,8115636904569662332,1891907168300685852,9501549157046754559,17004435387780015310,4983108637165111229,16917138850191204148,14072784014201455105,6895633789459489308,1814660230196368951,3507715899235269446,5652256526616915187,13039572399643053126,2059779286456966097,14051196002738182586,15444253135583316999,17193619669279692074,12830473548557934566,5801040122955490594,2892058411196773434,2559461075692207854,10581473495256190081,10245602703501410910,11971631238631207827,17550587711245320652,15950371491373026066,10566587757491071140,10663726193531697959,4404705780367307219,3810557428537921917,4205855613413273246,2117549662867207419,9831338409627275787,15195743294965878723,16128974132170860755,8761295104464668775,4105310806656869976,14674478946085102156,5659137669277464957,6586110352017698313,11245103011629548079,9306752717749760245,3440318432057495963,17471459813847025731,8174061484357354357,4500748388345790327,7095514997435892163,14323774948008342917,4390671800457705697,14418751643267841561,16889932549092120831,17559750472908013668,3503445863674719967],"proof":[[10054261480805314322,1853879456161700335,6376349503445604161,1347897175299661493],[12958831615886461904,15273733817830938419,13167710325679047325,160044020906763733],[7119562155097739279,12444336164874924008,17791694339726168077,3085199985310493155],[4968843798543503568,6447264107745985830,7606840894474517005,185908843510338850],[13029445661035717682,17662689417102108033,10522361716169539621,1381778863725460146],[2682240208423183383,17100544346162840728,1687281972403886599,2489153063976250562],[5441787669484276335,16744926366778688610,9520338148478811606,3033669494709605099],[7793714524700783307,3268302654115481764,6411291063932951108,2620164684475004112],[10854473530224478540,2756852741911553527,2194813350792443863,1395469893813960787],[5213729582619592531,10795999448260192557,11660958328734716866,1859206544292259322],[18405049454917086573,14576648186879307123,15034690018957840330,1899751093143473928],[16551305571259784718,2018895054339524142,14470706386993702810,2054295203925096555],[10395317326975225441,6407801005412337338,10434117868465609087,2082187945290833166]]},"fri_queries":[{"leaf_elements":[7852326892621591146,8409737247167635962,57319012141639428,4086258421484168111,3659307556975909507,5073697508241518848,6982593246856089561,15731301305400341966,11407152701782398089,10917378266071916481,13159806842808285536,12876087587546790909,8704128598734495691,2962415519895347747,8509360639314911641,12963178816951901343],"proof":[[16924532538595046948,1589772296039037727,12937115754933249618,1229956109533930237],[13116881499157781191,7307281988373794832,3884746151975447427,260359108996889424],[10676071769963355542,3627625207910605845,17491969217122139181,285680302011081879],[461361017658010235,9500649204222363249,12173180651709489571,1775866261024923259],[9515343970794583425,6117709230878967072,11225159618064185926,1084070859585343239],[4140772267370476715,3543327731260586269,363322136091766667,2973244704731008154],[4168670514550649876,2020314204749884476,14272199545402345482,916792397282283268],[15637098858350978993,10451866894874032897,7236855799260821183,2868931267341681703],[3927744458549941298,3496128964211743010,16192519430312263805,3274559130776179415],[18131198280540285608,12581310562695097525,9196147599945810214,462009875683355533]]},{"leaf_elements":[13383392954386856358,12355591765578142465,9496284468992008057,1577663837140726389,1057750305418881642,6837207861185861675,2050523773048504537,7792187003501348674,5246626772525888761,12217341222574406698,14125048593059685757,140729257124342487,11587391766366201045,5849559526425643,1861918178559227106,707465782520136599],"proof":[[16347168695060316901,11799221609114043731,227645574933561099,188189684487999517],[13182296572629618092,9239431762628356511,9278028794352541539,1126824930578079647],[11465891446883698778,1618105043981160347,12822795911012242413,683541259422695612],[18379869965507177349,17196574187034164860,8785864030021707335,962615482803317601],[2440134031042957037,16887529202809299088,6741216325153862881,3459135968753911545],[17942502096034518156,16859436221861128819,1952217781406608491,2242621810152801951],[17099306107583130662,12848433781283675920,10136925567309470195,522643541969499478]]},{"leaf_elements":[16690014629847877210,7287951047495699982,17665454195277337117,17666558965150158127,7875813784344663254,1994599825534812174,14246148622283798058,1731564080210221100,7642256739323182550,10682854129282991548,12432134430989777455,5887791163196053305,5429980759607000938,12093278519029258328,2160195302834755717,15788413545726116040],"proof":[[17496052659133593606,12264356912561324979,4601662404996576460,2551876205772580673],[8413961427930482341,1121254669388356250,17296780279592351278,678698294986152038],[6375818986139564146,7254514347935865059,2420570388057316336,3151813934365162123],[17998516154849033443,12765003108734775304,3277043473406281168,1097192453493713991]]},{"leaf_elements":[6669658827104917344,4074685166664785434,9790115576362344338,2899208765474075180,3813964448471056927,10280782794637071024,11313220144895867410,2004159888459006034,2740320980919109436,14466055620107982586,7683642816942705918,4974564548964633479,15543691003783197066,73854648871467976,14457452735536113234,4188696714651533998],"proof":[[9848510709615912413,8366658415164351761,14144261372479424433,3413452159001191959]]},{"leaf_elements":[7296409731632184274,426054755240503357,8507719345572846816,17585008801542160155],"proof":[]}]},{"witness_query":{"leaf_elements":[16221721178664366970,13989122789978796867,13351682947768188127,16808551445181156734,4285064866625434225,5276917630368769412,203750107199292828,6741179546108782702,13284497628833489697,14496482610893062853,14886148047239315566,17299752439612218093,2962758864011485399,886338094738487477,9906050283410674040,17637511352593194528,7236233885798181732,12773021224993665627,877386877291842816,1467421315795887831,11340421636313639921,563119764299212700,15937771700286289458,9855671063606934124,6883393991461338526,5913228377337910596,13917042036805033538,14654257292746176316,1907300045196019425,12258001025974436204,10250002180105691094,2924767350500086707,7393576953850291469,1654397600115527893,9291417031524936772,15128051346760404657,4050645556064481011,6892438293049589272,6718293296542878208,13506416380818668744,27047968166373984,10125165438557719889,10325306627496554041,11847045269682560945,12363984574356068638,8125836489661426919,8558278368239969126,353485507033369577,12283241600079080956,4835921025420966008,1282041441377082986,15436340281884202350,17878214373644333470,9696299985070575544,12804249109050604822,1585312918664487210,9782488569521514456,2252637781844010993,12245821302764625831,16695857573286478894,2984603802479824390,15325225616001113895,4473419839464563279,11490963593145778192,15958013989308975318,8366287218329093834,6231941921876662814,13122648998991203267,11674122822272347744,10131443914542818758,11167052706267038798,16834011543749311096,1751061619357549036,4881769907521943877,13614788769756851420,10168510927716011476,10730407358584343073,15161129141175992556,10946108982641316846,7726730612847596608,6037316272037155235,5205289652073958875,12075248269731656795,1554598960039418791,14933993482045123331,13836464322100512472,564123119374898691,5165805800110701415,2566758825699786810,4566532721258921116,871044404389255080,915237985139820338,249411932749805536,4716361449230637057,17103610856765585894,6170279767388749607,7503448666216181973,10471937536998715088,3623861790749304814,2821176103381538239,1075801812187219733,11790255810860248367,18296298103917088900,2560422677144509764,4434577416805712035,14108263841146250467,8935337388294917310,18234273177335219970,3118826300535852887,12124922448205817384,10147620032722740958,14120204983857981693,5441074862591426290,232390271739001643,1647426812662702041,8565339683282957687,10260531393302891626,13638051509754428249,15902463279872613310,6407627353228690456,17830939337821768447,6725901034015272516,11757617946622332076,17845081029619103426,9711811157617794141,10974496940516250700,1817634609104201536,2892884685380541314,5053407044019780100,2787495739885667702,1691191345361519975],"proof":[[362031388581292014,12233838645401472519,17635845293079517116,1815120180882007968],[10552184296933008420,4966240921573557731,16339811292872795534,79182347281545909],[10556772973209881385,11812968537529833871,1361705464538603909,2259123702106015324],[17697445639550302514,11137340001116980064,10576396031799368190,2458901369798617644],[10665326810986840536,2757094445071759156,901048881605906907,1618543926549807782],[16418408292341990858,1000227384116415897,9242640654496607781,1199762964333561945],[15323906464114246939,9619065874742677287,15242371657539967664,1188186215707578682],[11535394326501113172,17008668753096369165,10625814454121437273,912006301171033742],[388883530297836833,1166146812163848413,10938177701117269052,2801440855367457126],[2252339037165760102,5966437402453409697,8092220380170511975,1120773937089136766],[1127030895586069538,694780759772484591,3687000931591563247,2750936864721522891],[5142135479214200327,8993737624634604378,5176462942667777740,525546059952794244],[4835930027315713455,14567191116503688260,9793062311750296446,2116148360242737249]]},"stage_2_query":{"leaf_elements":[12686177918477478895,9654681491811872109,9551764201565513628,7666270721112060820,3406334241833008900,10405588202092694091,14989522152444918826,3467603600220127627,13995072244515250488,17958081758769363830,10711324271788328610,5990604342533467549,17464626206442164729,7151507976061458735],"proof":[[8803027857079078591,14842429107552651924,12511434139057620124,677340245467054751],[1176919003309481042,11093974052157511099,10377441904371824296,2092324944841200173],[17459299018120198412,15922024554910122307,7571540435316781491,398883880436586434],[10393648237166379669,16099330459075550675,4274324062162924345,3031850054925340093],[6967927862372824890,15745919164672924098,12277410046798848529,2828363679500296854],[9241773783003353957,17162286021437742471,12287658230023517112,2505968813171505268],[16192743331420801756,16853099623822253248,4500949460661869295,427523159909760180],[15585307975185240439,10645421230436165629,9542668404047539530,2410388635889841734],[14108155453108918936,17768478179091243388,17677048954565280289,2491273503427794453],[306986072590255386,736170251667370346,5833842388505069483,3175110833536678460],[5431947802106662554,5443354384023227846,13897831674897138335,1596310562825674992],[13174836754061613523,2244801622794592706,2243592228159740092,3224233877026474973],[8400976163326016007,13459382111531745039,16189427956558551098,1917620776118434428]]},"quotient_query":{"leaf_elements":[15539341829760149260,5070538483359292704,10739172477460710888,3975248068699790615,11299568778594849102,17684955844615082967,9470679597746632413,15416801158951990148,1376446039843026679,12299376012373091436,12380015726041113055,6922270663149478623,7321984613422441921,1057638767027923979,10477359871124793304,12198958967737654898],"proof":[[9456659638386461407,10459804739950027468,4118258715336110527,3135027834408520792],[7989804177315535656,14160467106884891656,8646245262129291496,2512257392046146533],[5671250522994910665,15860451557005433745,15690743948704764470,2141240063002154394],[8633722987978111441,3657267095159696937,1576872460306535016,3212573535192863545],[9647748802488501153,9141606840556642016,9800999515371633394,2342574377652335744],[4957702768070759140,14097941451773030863,3473978284971358035,172893707022022776],[15997433120551377070,10972232126841400648,5904236753397513191,2453763533391185647],[2327639692908028998,13057650817947852413,1719208798220399402,2526188301216941217],[5425951749466856899,14508624385588496846,8024834083118233060,2580061400401503299],[8356830417145955711,9534602605795708827,10204078793677780453,1188305220769711507],[2157695038304941352,11191783211948267574,16678180536735649302,2113735272830865899],[12727463944066686440,15031778029241626609,1474235568906382933,1585885662917994428],[8560803622457089329,6576268329716751604,17480918290423520249,2783826331117575223]]},"setup_query":{"leaf_elements":[2055134557313161544,965357918958940251,3735327071672470463,12644184263503038969,1221350972148134971,7765405654249943814,5472874845763232549,11984180433617229103,2618800215481601815,9403772028149348994,8848249450230491581,12365632164738717054,9672609103653700452,4218309073687432868,4390398802628145265,17319072030845930851,1989673410952332739,6306983634174509597,4935975783169606544,2835961606091606370,16663798842440931446,10342434974769565339,15383326174698104647,6422833046025420657,10106065759651384256,2632272024255513919,897965808618989837,15844552397154315837,10568088440744857079,6774164707400721906,8808645360344605874,14377772861527623658,7717325487228938498,7039778657782223924,15927192703565385139,8355379604111178344,1977507356839558509,11810268917641074359,3671733676362715058,14734988772515418102,5529845729669907197,10291416720305679659,4343909343255340406,10014085808789597339,14432843770424241323,1164567855972365211,10456101877468708880,14918148604444517033,285236530568143626,15510936059029277638,4783774060606597899,14830299851201917097,17741535243814157688,14405983026824511256,8697872666590223349,11497163867377302654,12535456775325011286,14137880779988043006,1641915275659904765,6380219381329450360,17060884823961737882],"proof":[[17208962143061205865,14348780283112921417,11844472883286089902,2997626664388225036],[16951277476228874297,9831532517795792128,15208180506366356058,3003594910105433980],[12629889643537433729,15890047805688943641,17012480289715161552,1160273029000526754],[3168595092008639006,15838658109289260137,6755863860443619165,1630406725820087492],[8448406091151735189,4880151297973279039,10706618153362883767,3475356124827148107],[12937790747914626552,11728870585990571639,9630601499355831260,1733496685472324275],[16771403596047220549,1380347137182014405,18211691055079521038,404541225141835953],[2714156101248815368,4852826042704527885,578746972754335125,242072900226017574],[17861491712169111639,14486851144629482817,70317164938166219,2478259083062352822],[9178614914299510232,703880190692736801,10715466778585138132,926299619382688535],[736051928442084714,13996136793561635304,16064150511766965841,1622030257075208925],[12569192502573143015,16626706419100452938,89526480532839450,1151220156167419616],[13233111940330375337,3721613951002169723,13215477271364309671,463369196759619265]]},"fri_queries":[{"leaf_elements":[18214502874438579876,7696302486700219291,12800354207470834506,1463799994301308999,1722257608046149030,16989312530868493558,2722248555517965251,12984819205301281374,789483289643447767,12313279881780019617,1951626583096616240,8601715069428378620,11387180138865846928,17474436810334474449,16878410227080847297,15076645321099247724],"proof":[[9527088389042543718,1170521241781254548,8835038283948576269,786255883503742252],[14574783515459114368,14651222494923844816,17238615123932287897,904362599935953004],[7037758321051720112,9999480988483978061,3212794505013441721,704821670732092456],[7154726537181071484,2866121777207443486,438771501433567663,3357731442610815605],[16606785679027778584,8608068982801941231,11604133878995604520,1953409844535838518],[9668973662797533341,17008671945333907157,13011134964728200566,339675791014902061],[2773384782288598880,18014997815818311444,6604108646907801362,2244999675674992892],[2945639535046352386,18040994403281453872,5996673420161924372,2821830344895488563],[4804235064255669216,14729952626711900118,17533787292596999691,1688029707652464723],[10293913151203782939,17276720635789980012,10145594858043310023,3455109967926550842]]},{"leaf_elements":[2228900834281716229,1299549190204654587,9006865616199779017,14228404441233766456,12929065521212336520,14299758915935582515,16168647894681347525,971012716067556375,1384234821846101455,4502067422962884971,6587604784764740208,4407234884591606677,1537070333044138384,12707478726357704962,15005362655075721356,9407124680955709137],"proof":[[4182976749845098317,1727124410915355476,9133308911947156078,2207952676689896345],[625650313468136740,546715585006836960,16609571025960701184,3322005179135568740],[11168978340572580790,11612030342488860850,16177125614093008464,2131479750789903495],[8310248125072317605,4043618984646884373,3992279181772451218,3482627284703626172],[14708966990010504020,4452105162794639184,226325883480207383,1404688822222607006],[5473885783605311085,4026771276107960446,4742656884502189251,2192188515716722929],[7407740297327449151,1602759275088930253,1080223580461385578,3082418193151690999]]},{"leaf_elements":[16830736489035123973,2100621626496328942,11449750340129115054,8433611836233024086,6388975388185370857,15576933765194661476,225656297721650540,2921233064941678249,12671330555576495253,14697492231472457732,51115461127253171,17647807930666116374,17095594050960443002,3522074783838344,7577080264799679379,14189229942982532212],"proof":[[13835981104362840035,11270682153572237710,8650110278885517205,3262536527438020932],[14690733459800600196,6625699307920514996,11949566284692742831,1050059442516129033],[4800217489573654783,3149554734942641022,18307580925378185476,95013896439469199],[12700299161953849936,17896603572231004330,16616459751671690607,786280160165782906]]},{"leaf_elements":[3303258396085125681,7334765928689504730,14735023820760202469,9619724676555854682,17674259656641861264,11577514084267056637,2440871980048415777,4361546825864617734,17764661275648454126,14367408337706981883,3009606633506689442,9303345605953149770,3068930268487580864,16855781256128155135,10975044962187852064,14887023502175238661],"proof":[[4082544563390657584,2428803467750713898,15919672509928983616,189310895045026976]]},{"leaf_elements":[6485988802393016559,12130974100501667025,3138003141619716888,4081174251100168420],"proof":[]}]},{"witness_query":{"leaf_elements":[602619258930425763,475187827036072351,1002308757448893478,3995816576697635898,1656737791006215598,1518434625547989223,3725660881662908373,4415528101188094276,8338840836612233335,1766523412917301303,8776388329586553460,4193660726630278698,14902551575174746540,16493981000182953719,7091076716465944294,14305554483986963809,12694349962879260730,18209846013372984373,10653155052039029129,14285098775633482811,11376081736435315751,1381616595853021933,13760810404040582703,17559676910850830097,14605864490466051905,17808292860672337400,2201451807948839727,6598514272914503435,2975222499762846189,4989029037530265990,5233317242656919589,15082229320767485379,7173010162560802895,12055010512006813133,2595514890436195034,12035942356211944889,17715265473470154692,8903347784235535797,2333393618456712618,14739606083147019465,5445182073357806537,18041471416981687445,2208709744816733768,894340999055570329,7150113197421946311,4463017975855434029,16420580042011537038,9617447312504598200,8273045695739270675,15882636175016080456,16508017834643396495,18411349563523428870,11281053992812124294,14063852676109365375,10304380377656677591,6159220460848169753,1269487050386745827,14046504408431338225,13196048612508832994,13766502916024544627,5432413331164548686,7247523401921485777,532985569869465746,11687148905809312747,11304474805701197804,14663713885849803615,2550193552759562079,6300459211559012495,12154205275983828572,13228891960559595228,101814363380532977,10683072411344639549,7905870814942712009,9474636771658336875,10597651230238335092,7429055640026985299,6796250401454707418,12971464294360862288,15676989233294978359,11335504333922745058,1732444785623048529,10649816746877153098,1366462626909993690,13094375270553281566,6852640111945472784,7104658054507986263,5282759981958460252,2225179208285773791,1573400422072223490,10001366943561658188,12721894017247652786,13571263545110700542,16259427326409928602,17624966522598812440,9177942293321854990,15769387180790010617,8245270162544662831,11300446713042658730,1484511857165477426,12356076662602348406,9286679272052255780,13947468710942019665,331815081677969510,18358538453103077153,15427173027594014983,1620260365163134164,13735288795717994568,17380831341821022745,11344780422360340417,7896308470112551267,5203713189957987299,11330661910275218316,7815617760739258315,2040497088171078633,16072659395278768496,16572389140726609567,513434029562773024,17694619208908110511,9472586701815520614,3866369640797441343,10549442429904288276,44626767509795467,16201372727083214730,16335399950281687009,13780764451689729262,13748661470141538572,6012471240257064125,6471483119437711918,11175704081119533296,17272722812094073301,726374270297807832],"proof":[[16615157074579999326,12319536767894088149,3716302138234602496,477128535496728952],[449524878732669829,4558945606052382296,992002041405804161,2439597343594244476],[9367013455241819113,3462215357107608304,16208841233217953881,2898684120214590371],[15116206799472171522,12554509692953006614,14513924226073890580,2385172679432417263],[16827311950551954079,16462469024948028014,12917131866394512588,1193346717573180722],[1433817311404551936,16558502213114337649,18111930669786096338,18988415095117817],[12646733209673403300,17661892587252294157,3542898754396028665,1769518045945451713],[14901970442169215768,7289383370152616229,13855122796567358609,1545625714300529941],[5912035077522829327,7527421549868620409,6478268667789886421,2738692677567587515],[384349733363842198,15047629148647972682,6644810888003117253,3272975948910484750],[3729870639045351131,14727722161884950768,13174920228765499536,1594190664104852092],[17987329640643634080,15012964337311746710,7351410855661486719,1350274959490068541],[14529369058256465838,11494318455472272794,12643466557790876047,2895029653840738288]]},"stage_2_query":{"leaf_elements":[17670922586472016092,3463397541842089983,10379080571630315408,16691029060464470639,9805372237066595319,2866299402828465841,14763794121220501217,4185854808103214311,1142019295367696289,10556753058732616117,4081021370061776282,15326571050530132157,11990355787839517246,2828202331856521447],"proof":[[13878436616694753016,10076209391865581547,2037040832557939848,1489475458488179739],[4219037070420516733,17221102678651177634,18084793474138391579,3171064583458790084],[4752656294864547486,2608001955915436303,11517836239657342174,1727806317625785253],[769040284878056142,5424073944154300611,444246569140642173,530979925309238707],[4426110140870858327,16213809655252738809,16492878191600753238,2944824385823037151],[8165996742800031134,6211888985593543356,8904180245719727143,2185702967954594467],[16160907993371023284,14133667301165015925,8951110626011061451,498887988989259837],[15448642712886781539,8123271978372870701,12440453178746958091,1531090052651675366],[11578692153572404213,10138777034309055860,14907076530611184621,1971959472873110738],[13989252825441541054,2705925807047885813,7622508092890761251,2969810306082740077],[14148865650455366705,726062445596409966,6928639599705081508,1913446844725551294],[11220017259697723622,677001679594051167,6925218384805950482,2073318416511068166],[1241545135385123701,7679004444393135724,3025994387032875785,1519048666296970932]]},"quotient_query":{"leaf_elements":[14903411439012073551,14844272460554056120,9182202812342282877,11073665880512471388,15780131837005414517,518360153991506176,4606719201519732354,17039373331883417834,16149751756345341480,12852169082270239517,5928031106607039225,16511970598841041941,4943000872461219386,11114554164617156455,11830648730480402539,3764606100965580716],"proof":[[166705477548517628,4376702884240907676,13088294677419552355,1309665378574670140],[4264542167422112897,15925978983934247381,9619956603682808757,1870256808264591493],[6061534675974042456,14207130798276018103,5703881586353722939,3340721101707409739],[14431742305370433686,8578633206598621255,3758512954152227131,1201655430016203471],[9614894617689528196,17374902680303820881,9823062992739385274,2173802458567587651],[15366045499318596029,2791263104640335375,18269130937461766167,1635171972315280635],[10195668950741515500,2973137986729783792,585982261048546768,2500417660959417267],[12201251587566845083,8680412804891861399,7908029028625616870,3274390501759745786],[9908312030584365129,13897759345277912024,15213250926373382635,2460499880434506881],[13083085271690926205,5588446440154269276,14617806450600078052,2148254481823711617],[13814780666178806219,8701498612994953716,15105392011306361365,755338624726281651],[2032376285152840491,7142132393502982569,1384580021556495755,2616812089124926360],[11151149218063228756,8120946621539383472,2153351129223377690,1948019290312331727]]},"setup_query":{"leaf_elements":[6215765775389015629,12414126241239489180,16442719940288951239,4978583418132459544,16490232676477019295,8259793220925488033,931927045600844774,17413972938321811564,6903723826920707901,8306958220787752982,11379502230025488851,4365427720624474484,12814304964904640811,15628775106472299581,5781591452331670154,9382264918004323978,12843321451247627835,5717424719946885456,124707899200754945,16428530665611715826,3349005434163394442,2876584203932179591,13317767204104216678,13772951573848811484,1531823635773915526,11469585732597452285,1472979571563349196,9649777972658775353,15011584380269763239,13286010239967991461,17311997925851203958,2174483497339657520,7903029571669089710,5989228180070808511,13727035936312707468,7355772458140003344,9487820305945990968,7325484722797443645,7998911823919204677,18019238518528357772,17226236493318085212,2013921466325250479,8991051259873511045,10593222291717142099,4518242511277518555,15060681875341704725,17290821747921223850,18174351142328174605,2037569542906356027,1915558695101782455,5674388525659207298,7050222958160032599,7182791206268221553,4470246078125301747,16588326461650784446,10302243554711531954,11094102631488375155,16667427043034316837,11458301070152154393,15081867320368361292,11707965402660451004],"proof":[[11458476708780656178,14450451608641889936,3283244344291322244,1687600173587205501],[18039794887688030196,8102866811582291105,4488569311948976899,1731639625322453766],[11003800009851070351,8673196835389424168,6622802075744623042,3198018730598480584],[6198813077377756416,9373805290620427541,4303755995514002597,1897042732238661878],[9446441584271271818,8765758760698364136,7816906983203818602,2005703898197687890],[6845371052229018091,11135256754661176045,15929447768219602746,2220866331068780919],[446327370884842097,1121100299360871689,12859824236109466287,3036125930405783426],[3339491911280052803,9277873680338617441,14657471947964967038,1111850130442406850],[9122970035134548352,16755169178682314336,10106987669529676486,2506618339775598166],[3920135293007296747,2637231464474328039,2544803906256176382,2605758384702158180],[11330851353241959642,7737266325616587668,9576171607732079077,392559943791442360],[10710052728847521794,1310188681526079020,6397101549672991908,1637501846289329853],[13149784555253046835,14758838563795191874,7433057622550658850,986325784856918114]]},"fri_queries":[{"leaf_elements":[14054520612658914736,5641971677843973658,11774032772149780661,2183275234114411606,5983169947619777992,14867556303070692762,226080911141639297,11441734261593488141,15660018716354603824,16266196300484781469,5442710157832689116,15921339435013669654,5082779198803258275,16285982495358279784,16559833420693288410,500217656198145919],"proof":[[9070213766549711029,8030551932244479479,3501705106637477564,1708573877627180989],[2599244898618133665,6836030807626761504,5975937265590074760,1927781725989948990],[1518156883681662069,1145730092701266162,17026208183990946588,300667145282105713],[17327393068427787680,14677191601985613204,15578343363568549274,1964337171181568763],[15231584523083740636,5628865189657864984,11968052282529521585,736272508254555616],[5616469359848997669,13531524087850636664,5668290592184082305,1278353567080472548],[9299570302684351962,3485506679846794281,6141125811392908314,1163825471206286843],[6679927951018212291,5258794126340581833,10460743017857341325,1693434545059098457],[4210560855886740970,6088046815714819661,13266640682913832721,1701582425475924178],[8347360573839206051,1768446814586231047,14007334252911185829,190786222251169773]]},{"leaf_elements":[8829937386662117490,13479172081793416456,12523144444099707681,8336743620505364002,3762731741350814964,11036124705220862273,9881181617042802632,6763942774079012555,57494463623814373,906449725620364454,6345068626569328137,7884330044285818615,6882088629595456170,9292934366446309979,1858653679467060430,6405556922618052946],"proof":[[7647699429832790491,13704115884980967740,4902426751053344372,1183519067924910222],[17959027877272670452,9085212545272741663,119806900961660057,1214998597093718008],[1319752157000564172,18369248854915664602,7606164338449245004,377433471940471965],[7218012616860069511,9580058550936193288,15789053834068243802,1532092022575427679],[1644085197289565618,4385777682071696421,1933089665859629666,911849557118272594],[14157526227560209653,10829391244618508863,11697006768307302778,345724691103367460],[9127794537611649855,5814250328747267805,4296556981629366486,2685070511949217859]]},{"leaf_elements":[14845767165484150506,5717386160317909315,6622494600866111357,8095927758798238430,12894197341256661524,11787364273476415755,10543445492557719550,10277672860220629634,12920680082131347493,1113838086251821948,2529597108249929512,3763963732081166289,9120171838429573513,11061424086470694570,12649880241875324489,7938384967194726564],"proof":[[1557323779758958543,5820858620902575166,7035525896288632554,3414674497403938387],[2169544865213028053,4321849700532411418,11849290130794620169,1693218383394977429],[10948678975314608133,3924083284418572810,13364196439838498155,2305767341443876489],[17194299915970532300,415382349675028268,16738602978340998696,3449836998464456936]]},{"leaf_elements":[3789702018995450110,15854387717208756361,1862553614940700864,9514253061725497845,198987545915237403,2445744595491142240,11873260469463328166,2136424363509213897,5107746734140941096,13172010550308694095,2233544282983968511,2369746150205641333,6878826575781853838,4016984314925335006,91665176381536295,15855865455423374290],"proof":[[6449941176220115590,4755010037827490481,11626402507764205885,228837083492347851]]},{"leaf_elements":[11323862628515517922,11439196860937776991,5413344540181736252,8741335607124726181],"proof":[]}]},{"witness_query":{"leaf_elements":[9576751094841568367,11549384390847967542,11337809281632217353,18112091058731165391,14455860613671625320,1947312392629992605,9247200251193367578,12958791300864936371,3767923864175237774,12807032806251115657,10679774762756573461,15593810700228760654,5048055338023923928,4060308279066758222,12145132307359132056,2483790419001220193,4760176018067231425,15435886694080499488,17367728054090569120,5491850036640957048,16714338878147882899,2130100879713947796,11856138400605268518,11322437280969197761,14970258221954108162,3552331842998265460,4366666405677113547,9740645590430256873,8771574844136276649,15562907023075459479,12007484868184567421,8657265135222668418,3969192549861350187,379022287653374874,6197034600229666552,1573918593899722765,3675176401021600127,2419318799185966909,5726699451612643337,10022803618004069432,5817677907492497026,17376357336600422764,5489647947740267393,8824682760754036813,9901419033269065500,7010441955824342296,11922355678881334224,179538720755093198,1014366709331293734,8015850533225461193,15351993804947735298,2091175742688118491,11398857711620630842,6887935519183011562,16281130652008346452,2184181598242462923,3526182414307713736,14694277811433077935,8783286772057177511,4980484969631821222,18425650677339824219,10927904624768608345,9202745665321342140,16119616462768209410,7215939384026328930,16789481758481457342,17384718281379025168,15728586872910266605,8319014114767537037,7296249132969118439,13739548559754795929,10327796492115842875,17568555404342664218,2405309112169094795,5489995657371800997,14830163920314352421,2035903964202947258,13068021440819783114,17039915115331423681,502486269743751171,4412701720498999531,2386446855859011481,8763324509783026970,5682023955212128704,3387708986081190846,2628968031547532404,2541986101309192058,14780130883090255925,12417457106244855574,6974929799589569954,2363391646486895949,9147734930159772925,4146042945391918716,589454436929240138,18334446090304463273,14300636682693223948,17576044399020706144,16126543153671086975,5538386195559521681,836124039062721326,151270991645739046,269596979687167413,13921122550699384190,13622361920288230507,12489900888828030424,15116986730072568383,12259254109127252740,14095745062758748522,9013654270731132681,1618713530092488115,3720301359754234706,9236518253267695007,16305961658758771128,14534512449925929505,15416233320139623476,663167777262760914,10885303796051694695,10988296633583225511,11576486552149957754,2175318293903558453,7265171124725753261,9590719296933162642,17435241996282989120,1904979744138598332,14442875949978323509,12274289961618189432,1790907694168827949,16854892807549409714,11748391527805778251,2818958510372129214,87502659283352793],"proof":[[18050768959973614723,10665940034543255293,4437328589492816863,1662258828278022781],[12179169659562287906,4186294003665794086,12261106871304863605,831726938613208133],[2378803977055558706,12316085572191624628,17863138285168484606,1108480401939582361],[2063744880248880235,171045395582142937,1250042646463895159,7363821099723113],[6979783548944799823,7685455089751042192,14932172928168256263,977261150708305201],[13233311155745937075,89742059567000692,9348873021654647324,1673533088234001667],[8817559294831957244,9834113172940771641,13573551126405514228,1021531137816186284],[14583714878465552577,1568061544181166036,18399746561580329368,1064210436789031213],[523043553863187054,9905984354218801977,629451019583438268,2362734975357887362],[7225578083697310481,10201876296549829672,5751971141253932118,1814600732590357845],[12036199073822799947,18344382032541332774,1150380077402298600,137757782090781130],[15056798879279227557,7642122615035966749,12396778318454286618,2846877088663908415],[8899754350472755776,12278932612733122602,15570693645971944066,1640054857718498562]]},"stage_2_query":{"leaf_elements":[17473306423073513922,5448099279822259258,4146033170122175877,8559445682920350584,14969027455870319475,18146410953525510394,9951243776121836542,1414901612658040462,13520115702882979833,9039858657566486734,94817819360248030,16003578980445985627,18097285284229736211,383489683136345738],"proof":[[1696714152612816992,4454060729678650160,5704968249799861550,3403757306719878051],[854915854617036176,10686218281671858028,1551353194611386656,1102357920586533080],[13493329155656550177,15923381264985615186,17646705725672367957,2500421169911647928],[1211466334396868376,15700921768926201734,18098710788355758597,656832115652465189],[14461750715338718759,1849244691228761102,583573069480743375,593091477170261525],[15049105798662218319,10354200684493955003,539320360345556536,3011177372492298609],[8300468029935118722,810560895770974513,2208072390056768108,2229151655525867317],[11072746705442039374,6132142741978102765,7398589329538284966,3242542622293563382],[16449971787836292349,15203164646742497874,2163961612597871719,2941633256797704800],[12650071330826553917,6486014659524005679,10284470515523067712,1764121787341350608],[6089297347779533698,18288578288688712260,2464975423208903473,3381181044776058761],[2202002661820034453,14408375113858267240,700400200812454902,3451107817587353209],[12572859388325897636,17011840285034537662,14979141720780255310,2732718184850494243]]},"quotient_query":{"leaf_elements":[11831144125070212983,760217210587245702,2317489011429296069,3962159296066368069,14893495718841633258,5802091777719873821,6422804782839040813,7394772605308958666,13091142807810990210,14693313582949528084,2886375469140978180,10335658936704273036,5193642610975775992,10931923452049655208,12461075610614315089,11059483635660172543],"proof":[[8081652125434284123,1420849017980647363,18302470234123948064,1910765841492026512],[15048848205633345378,18324120671516504313,15485803382990626448,2392259860285029957],[16762727393160196630,16789407221974553997,16112296059450527989,3419089778811657351],[11835354099622550875,12736176025246714901,17636052427149352522,220116017686194049],[12062879889240230955,12831747163248288126,4299098913263867119,1702323347174387670],[7529470018203432423,7982065078607815015,5235566433797675016,1138145125778464297],[12832782061781978455,9435310685903933877,13248762061154520827,3418820942178996271],[3953385663957747822,16699444338975036455,2401449816348246179,2472990846993747389],[10582102723147839124,4717307175100299885,13120252777695429660,2863367089614961220],[6655869341818575767,2144410408674612246,67232810001377191,1402062444968036823],[6785880900866932520,821620509556502585,8656418859660568549,1427611543780621878],[6901920785147334066,12856560133237768599,10764700425195042763,1166708839200723743],[2322302405481175655,4650094345301116407,2541181434162447780,3440250464316257291]]},"setup_query":{"leaf_elements":[17600834682267289568,6551544975655020190,9626437669811389314,9947280749986088031,10186480616765326406,12441359337627273978,16234633058009531281,11026362119868659006,7111438461932643451,10640147784118959303,17378530060811346967,17891945817577658397,5311228459370430823,3700745279075511562,7812291405338863157,7677799859770939240,4721269911599219215,14947696288264875308,2400012490908224398,16154776614611189394,2532886600140671760,6539568829674227205,18061614080341992196,11265739861178690041,9915118265237989590,1064837276855391276,15252478354541832652,1683432285185088286,537830661562462599,12290845644940797179,13645592712636870423,12832907173019627345,4387187771895121058,12397960510589977470,1367617616728227317,14135338424015924061,6302603740629685666,10696475226799523251,16040214751748033251,5559363363678395922,7160420500770327312,9700851086204980687,17795034572361905027,15691006280206879794,6668567947441410051,1672795495794877400,14923765395064526196,8589553651890069817,5336421627308582930,6816605756977674530,5969581732898368218,17407029617593745917,6483623612413279044,5772161835510691325,10174257402210106315,3232871604747794756,7254146630626486121,16144960430261819801,3082333026672953196,11730406188518929015,12670804023141699382],"proof":[[18318902287549636408,4209674582499328476,3073468292103642828,1752235913624924248],[18127527606575670011,10244426813071973754,11508775744083872116,850207874340150371],[4225975006835144329,16638962698658642950,8405374410100795483,1728096994031773435],[4286149095793488340,18161625360289004873,10220497732097993010,2904365501353212978],[17566654073066002550,9150017445697727185,18192877639169726204,2206403996128970513],[16115257381937942766,1861405569748078867,14658335958428874331,3298864403305576422],[169952488849222552,2513645967370441379,10487349425188523174,3332927936828110739],[3704462409953609912,17259095946708594850,9170638382056556778,3336304082489188453],[13223495952886414288,7017652692921093256,5448250669894159749,687407285520057113],[17416144879797363510,12596645203997159937,7077149315526450634,2749898165155967605],[1944238263364572460,16944590141222724672,2731199171487136026,929417722718882978],[8184583848188389689,1691925751284768332,4808945709990961020,1954402464110990423],[7393247476269389035,4694627994465087610,8725146533108150334,2229767323800595700]]},"fri_queries":[{"leaf_elements":[14635685575520325862,18045476494344982081,9929148329453140589,8698384249683306681,6240962250900845351,5821024060328770672,11557413112566746551,5566415759882129929,2938788185695838414,4990140546325053821,1168000096076103410,1781730882039432907,4504450143266553411,6320619646046067666,3482573509038099415,5096963667942362535],"proof":[[6489446967705239162,15032394788444070976,10245720670230121433,2301009914412377055],[2909175762783314995,18050416537130373596,4645652091869132035,1570769626016282107],[1433522967623108742,8598851194226441398,13045352975680828456,696670495119364634],[1669915048009254230,2064036013235485943,6602017226103888174,752476135185499861],[2096731900316279930,16576188446061878311,17278675504881688388,1856556255006571606],[14844055986107451936,12628170303811961746,17108795091595755128,3200268011941517180],[15193506466800529704,9556346219543735833,12549780234843632811,2810066479216778009],[13349775921664257113,14150048354355143187,6461649815032889461,1502093382481396807],[7605375743785670799,10185895542438624416,7815638543420388253,3054178810126252517],[13909292638786716778,8970587721766887481,4064072683418480103,2352438592939364893]]},{"leaf_elements":[10115193115061861984,17929396353742094272,800136647454405862,10436361124442552708,13862982416777443129,7338938286081065530,4818120893210280041,6865401796034637299,9120707744993472055,16771258696155957653,6457274363872626557,749388593317156885,4779477613951543359,4641875835916545495,7565816221518631991,4152580604307579951],"proof":[[5125957050941643913,14347124663193603090,14983185349477303308,1675556183057672437],[7005509259887422570,9550191499395162844,16896956844251160107,1536110898128131204],[8052798945598597777,2791498987137438348,1351247512677698232,898464712438743152],[7640566031128185294,1414746828959449011,8790853225863047303,3198450905194569007],[12813882369894236157,6484739813566793012,7796420782761195941,129094952693746200],[2137973266876116548,10812798778330061619,1702586614393510203,1435662129826923283],[8219660059199024368,16655180989667732883,12470720334809693761,3261694339373339859]]},{"leaf_elements":[18226344093150864797,8026434138078381899,13097736228807377611,12118308210720633808,804378179402838628,2000490197074003766,13958069589604513714,17571099298476213225,919277563278167337,5387814971588703027,15415011347255169929,9955727367083855477,5408356955634925834,5644219902597951889,13229521572547345741,9534183104462639355],"proof":[[13289256723722013129,17256501021443216386,1814765959698446293,388096428816549163],[5460207319851950092,7473606203375009206,8720429620102853383,1374949819360850622],[15389039272882718662,1220524723794399443,3027321851306010981,761737478691848471],[14914066784182050162,13218321865492874577,736393783097052782,1014363730706131245]]},{"leaf_elements":[10843563837985374749,2934059280078601464,522664419033492028,9663970885524212153,10528477958991422926,17612037856198408780,12590216556634830341,168568544817592541,12645274891552093570,17506125824037388715,12658942764876917960,8356328858488461741,2074282120620356578,8773718658183707819,5723522309117596141,7469780649577961051],"proof":[[12374258612337946155,8133723967161758545,9858584754587618204,1967446838911406840]]},{"leaf_elements":[17499325981881337266,17599898521267640417,6381771601744403426,6712813034178600945],"proof":[]}]},{"witness_query":{"leaf_elements":[17521958612050491490,9567437649636890587,4869853096088223805,2760681524654223173,16402123085305737152,7954918130386263733,2272663865093639226,5188023742499797426,3461459904428624961,2323905028618700458,10556960171656589986,660943942524163432,9714825228453579472,1160748746400868806,2253732093594133664,10105985796226206314,10123022325461125910,4195965188939203727,6750934408113657915,14661834821995209899,5910255362281297460,4624588538135572749,12098363262883541819,9289332973315358686,6303572112477311869,265910613295759077,4515066712625191057,4533890952660483231,13694986235211686082,9985487373145829170,10662794303014309787,996140586756376228,4442944873651673612,8769760537179807130,4236427659614661012,11225198157351053695,39822611797408182,11197199690200347864,9508071117061517126,7708231855480791815,15895218741741393893,272157054942830140,1635353236163786678,5070533989251147309,17755707072067000233,3102508108213533247,13433419506197682684,4323797262220367198,16591016912209640179,5749197782019235740,5317254398417741504,7129271224636459911,18291000620860229502,15924326967676575509,12805383838168352071,8827971619548850621,7645274265064185810,14962853985711159716,18147300898559045539,8225781947295477570,7000177402165192065,1083767709955407290,12999212016044979318,4628922181583563073,11742202459220652024,13427103050251164192,2169810315993550004,15135351630597870664,3629012072559102706,7836572644918936689,7061906720293349703,1187502203767408089,8582476474689023968,629672014236317372,10098802676531163295,3226641108801442697,4426606597474288252,8241410435585506717,13534867287130463071,6987434382703003357,13843092061457163376,6790165400822008566,4342382452055212525,50464588392518455,4181311752635053026,1205183973681719676,9831955119866776629,15889816856672509638,13627874825261141675,4742056798404702702,3875908163169359755,12816879309581030896,7814457346166606765,11796741780725335901,13576814723147920788,14135433436987987368,6797476648384798418,2455260048080586925,7867741735057158428,5437045296922182866,3803546751038955096,9483627168379173104,10586455794537997836,4454425279172650813,988432138249642874,5155615089470676180,13848635980401409972,5398384086180329248,7383960274291900513,15734580293348485860,8114482970479706152,15386948723405709537,4530334361477724796,13597692879100992027,12613358688580319093,15859625984584751588,12240602738308542337,1804612021562125729,7248749685108963791,13451071369738462864,9374031095820080822,11517442877673624370,5534808790330233926,9024035214257410501,13316587001689593701,13840660546872162338,8638482430779616584,15025771393942326089,1100608703010916035,17453359609796620315,7272843649133671414],"proof":[[18004345142961760092,6477253009951200187,10270185357333010801,893088093390832016],[201258162869988388,6965059447203301049,12111768518146956821,1753472291940789137],[6319909806101242639,15083720546106811624,13543613245189538857,1025345745726295073],[9456701424623178226,17915424054819802408,10738857593805445566,2337051191688250278],[10023099585691787343,18380851324506838607,14645076184608580736,1545820490931443238],[9657176846054901487,10763085996900505396,14359871000106556893,655351451758348940],[14696504169856388730,13657932833164966005,14968522178996733733,1087096375426515979],[10178692081894777623,17221812861814519354,14411962280530904005,3437555999553059568],[13744399062368078803,4790176502208849648,14898681865517676808,1714051279044447450],[16082388412919767989,2283788685008919016,12712343997890131439,2615654387031861476],[6255716597487924478,9755540032979704580,14745922823330988308,2777748977779662694],[13836668906829710369,10341401230349416198,11163754085741760243,3218002454189563944],[12489835289634896400,6436027295365327603,13835359195736637174,2107156744221810711]]},"stage_2_query":{"leaf_elements":[982185146251640546,5765488123622228758,14180462358604098776,5341734177981767593,12381108446431704911,3930608115860599980,4322889109046346215,12243262482127711799,15982430307454506360,11458501089319823554,4314324986174080999,105328906365671602,9402285637288844890,16301297391303489371],"proof":[[5383369525447222346,11100905854750921447,17642250154953759755,3000268857654254116],[5660669331810845970,8923044850633938984,970032602702374964,1471273450783484060],[548212366007315994,1894541340566799735,17509463606202254476,687804579624460098],[15105942131336316897,15474915367481508757,2770914956755456820,1814762666059376475],[6356052328375382359,8334106609696398328,11643100270029672540,2248961784688411191],[17409707628872825729,808731439565157400,7162674576136393479,940277530845433158],[13270838478579747479,10047880545690007730,15537101255917788549,3240277803484363113],[3074523075113805979,10893692220418132941,16692981170863645261,447957130653244379],[17795438772997000713,9467915644959759111,13908319311166923984,1339230708055371837],[11165928349547906039,17044617554589589783,6052362293878905060,2116224653569415255],[1183043004176350965,6936588016048698215,535622981502154285,1988473032688790364],[1588122855051381316,15986256495690246090,15845347415925917050,3002469809967888056],[5088184440726532484,10624519551630831941,4139449485439259727,3412129392071649693]]},"quotient_query":{"leaf_elements":[3920179369862740335,11735906194314469030,12840927191927459192,2772035060102757247,16000391752356976773,3702705040004118716,1131995019464821677,9618503320216386519,12029510128144225593,4856198147995230361,7136053490736944038,913384835415627696,7744251254341365110,15683983879935552637,16141025584473190630,2060903489997869691],"proof":[[10928722193248258951,10572505756171598104,11319297931236078433,1409984112780017837],[8837442828737371094,7608713293109879837,6896898481234526173,1442064064428055466],[9096161475788296127,7621897791391409851,16923572215472987587,518975881914120809],[3109646554445648970,17551604953820246591,10664236493848211951,269670428630879908],[7699927337513856161,18267103867398426425,5034625339294322584,146294428209775491],[15867848785987450928,6207903983875976827,6694639328691206271,1136661422774194072],[12986270987902077023,977651882573203420,10153987921128420108,3336809152487621316],[3048592803754345784,1600130930372018575,2394256592783272236,828402747693583194],[9685037916267707117,7760006297178937728,9511589176593753245,1229542267381280557],[2078739388611051521,4338737628411070364,9487814046498170075,2527395053468858067],[482229698886387901,11029935584867999260,7416896752534935237,1228402156128570090],[207043033235468965,17758881744043525803,2123779994158588754,2204467661134451222],[2206136225417434008,2701764854394411613,5566855779015492723,1850531030693384592]]},"setup_query":{"leaf_elements":[1355673397133206552,16624679760373400638,10576334702516042838,7360053910164516265,9818245033085381350,13761959597850868037,2118886618023348259,7913141778299451861,17437651061225385125,13314544514542540624,11592626801821627736,3371994627777415044,15842547866684423315,11490457236889902878,13605735221386517628,12142589482455713070,3021116808106667477,15713703560518862877,17173808171656557046,12400144155615711429,16654458227608513171,2688808732270893359,14145073280589860676,3973984332380713260,8098870306854216005,16731026638679582324,3997069862706402266,1463466807851480381,2274054442290324946,2937956476090401498,4888711325099276008,2113158276658231946,474528284042613063,15372180447191937529,4172250802717157143,15535807937593433032,2273457365007002487,8050149271754798302,12637263731783815820,12343718394405685662,14790386198489269644,14527525398461380182,18380333593041546537,9050985597353161519,13157521581649082359,6235322836971444065,10005960010912737416,16630365179281611346,6916695780541869495,600008399536122585,6025051717514347262,8553788315190621937,17988241434955282717,15900008749983044289,1209192457595274367,6780036347621488180,280246316290989124,17156246495239159380,5641506186782750333,5844116681872756152,14474080224388045148],"proof":[[6527901709182734312,6406139154616769636,1748090372630010312,2936456039583879501],[17691503593666566444,13257211940848573906,2923793043851064178,2037008751216728731],[5757136084937964504,2502780160425199734,10026566853520555792,2354742848796309995],[10679676018851931945,3187567936901159794,6165409962595252519,428722590507043243],[10612634109704588899,2265921774035565070,2792634214159758412,2851093078807654382],[7184871336631684152,6410013678021026402,2647785781569885488,482185626207377247],[14926883745329312007,4482061402271079367,12411186909073642798,2790289643094819246],[4124738745312985172,4207461405898522032,17287683763856391623,1144094205236546067],[7644450250128884198,18173950873808950522,5988098850251033895,3289098661696874031],[9986892814781889647,2026850949365544285,16415112472893041071,3011090863105502475],[153888852915966077,17972168662458850399,12103382874054819748,421710622830068301],[18247657968427739412,11980466839669134857,11851357272994488667,2939293211808769075],[9160595042059558321,3003654428390274044,17180942480487853646,2327618075865250316]]},"fri_queries":[{"leaf_elements":[17254025254818345174,17183186234981699123,12754145714248302613,6414685226928119024,16695105037005275396,15794636382819703189,1777831607728994455,6284950806621789652,9161151602750391422,7230717325628819140,1561801609793300813,9572902908226383327,15750389680973061629,8965515235051357888,11635561120373700257,9086256320901372304],"proof":[[8267897130838622177,6442268717150199860,13340268300986128932,2913169008289031657],[11984059354832354156,11032280312280831634,5314515681941775038,634286045445096875],[11816810852773208260,10267329123203026022,825255327531499841,2377955466691896572],[17211569953491555835,8707372427791204028,7598000726445284342,589739286809556109],[528817135806258694,12191543876458399622,16519562356854569949,3095365550468445478],[6824941936180812492,5120161419118431481,5365667171269112921,926142812200642602],[7768623096735499719,4056460535835726199,13632021689595887433,1068826273900536014],[3868701278953793503,4100608210264928165,2780486069151558900,2115596530450397031],[12403873574716195796,2349135915077416510,7468767277575460203,2092587708709019038],[17081479404112278480,617184671756641223,8216228617306694673,3379202153544912932]]},{"leaf_elements":[14797464185987080030,847629152230489649,14151066362151177179,1836677227488812947,16916463108112252182,6215264582172269151,15642500966024366820,11117122054590960794,8646877471929605689,12225507634549888373,15802807806274145072,6730918736061398350,18425986999720794,11462119334355473508,9327854643199698366,9596166148626859978],"proof":[[3130321265368027429,7007847714692765125,2423538036867493148,3265533771464890987],[15092310831581961861,6724197227287467238,10512123145823420706,2166363089408337006],[15708896409412314513,16159106395447873471,11032417151103494118,592708483199285924],[16128822770032341206,11764570339321408245,3646507939455976389,1981301148222524901],[5420257122579917456,9714500252158636923,7779912524437290766,3452963018561853654],[17169716515783796911,1500806662997531208,4252073954974278456,2343125948170061068],[5813712587629336352,1082708786045461569,1092112838582383375,3425941116159785480]]},{"leaf_elements":[7024355718601390918,5277672392892876083,827293714387430296,16369316608947007307,9833023254632075882,1871152066860603249,9029835456346178235,12443032464155200491,14903256027728109014,10147111615072011603,8757604889383504862,11025844569948001491,14601464061959365757,7254405106310336232,5967132259268658295,5344227218450665330],"proof":[[15399971345202591582,3011667195888806057,5560387751494564333,3324582730283159586],[1493042040292047390,15395071095904431479,14600032091785965594,2327623214616711775],[3654369732084213993,12432004624548316494,143217563669780288,2095965278091705794],[4216581162791829782,12611432400497020496,4291082047923264811,6403411685447305]]},{"leaf_elements":[4311699445297929499,9806112033748572177,3539043589198585194,14593654441266355321,15762928673565885253,5932108298477060518,17925124669056389626,14193547706035909747,17259293125139773774,2442827444727177921,17080903217978581511,16105909017897668138,12320793498174218612,797232347842516762,16412067898771630043,9571229727132115841],"proof":[[6720710772968328146,8869646766528407003,16450207532160375016,2278103972111261741]]},{"leaf_elements":[11323862628515517922,11439196860937776991,5413344540181736252,8741335607124726181],"proof":[]}]},{"witness_query":{"leaf_elements":[11948795710264375955,3579972359226832183,8536711601574309381,11396829051685123078,16952896974736752037,4812067023169352570,752137558755471761,10084960256663509835,2544750230458809155,17030651141629010623,14279814900408777125,2045317724438886490,6941441122062687621,16834404791832950995,15936326321371307779,1329410647863596500,7727519106571359668,17105886540561019822,14353595911971258176,10713749166959871379,16750870551519249184,11323464595555265601,834845291311153654,17529180241175587439,37848275059131677,18105663000759888816,4393873288488342091,3947621141477337836,5799050532406529507,4401451964912879503,2393899212721697554,11969769752241608791,4433635556526512125,12474067865023777236,1796334476796406826,12427974951280116751,9184674791025121397,1939787536911140975,7776282856808946117,10953028547075317785,4624625171157010660,8680298032529616209,10283785126883384243,1280898109036960772,14147670060461597513,5297624234194698205,11321143869167180287,16696438873603057900,13749401227833466920,15835460497571671337,3565102563089184722,15574142811337068417,11477996794931765834,12083671708967381374,3252689138429560628,13540031273572513223,11217001327991968539,9037141442767471077,4167661026166268435,15283164909420815520,14531025245956542721,8776115548046335055,8859055840084181636,12381786712538831544,3434126407083357024,7193450252638156393,18395789363135852426,7999516356386080843,10275684614336317770,13806736820695529455,2302350665630335882,13103426674578149310,13195379945687255954,10887709560799869005,13407209527852098370,10352194363026426169,13038599802795065660,5180910592622355210,11772544321268490080,14730426422217250088,16763453130020049098,4036830757664011040,7353575774814667341,7369097360190511078,16727069799353205451,2861920738879633079,17252053550106222090,10715932931918828114,3219323047427609726,7823313357974793447,16796372289272392201,12423584609180124312,15379435781773213580,134486740851710209,1485507674877020542,4618599570982800077,11735816578617590836,7843387119214334584,6211977022205361547,3935757660625493349,7474648453258992144,4762578523091358717,1271477897694462433,6083698776546104610,13634780373534588991,18393193002704725586,13579048256376560477,13957606179332349716,17493094982263522769,8663141994412089904,7282306780829774321,1563180342260108747,9332793408626379650,12843891907403264952,10835097388363274399,19777796151783993,3000136436195076083,7073744392544836758,8441458936004030459,2630130599048821497,2416727113278575964,12751883671089468955,5625413016645574770,11838182331542754612,10954355068839399879,18272997824062609226,12631306951804659139,7428505078978945213,11149821451768023381,6327508690927457581,14515729450842505361],"proof":[[10554659508671778649,3569879561146348851,2623102594771511313,2199507477741425514],[13374087441215736910,17920513061902029090,2531204468149018093,216389700490800985],[6615341234702182028,9791943736305547849,13137968285055742591,2467731851776422880],[9603036439868910141,4598306675817751940,3143808107535269908,3442704851343000251],[8176179294327968920,2933940122091421385,16755453167672504240,2380887341492756658],[17140186722172320504,9317579894634382266,3096285794062678376,2110828512695423886],[14055757009204859914,4737595654705366171,17449717446217913387,2037498423728019081],[7061904308973836850,5636894431559730080,5330257904007396198,1718349596010735736],[7150863009503969572,1204505448702042210,15651957073007012091,235018674792616253],[12074134137501755981,16299228162971215472,8115585412613276480,717261193191659743],[8182014679444923342,16445826551207987290,17013822517979645025,2656714516067615980],[6902291296385525908,6282427285539483573,1059247308760891000,1681441560494504270],[18265673367752908138,2754640070048023901,11724482278947537297,1725637765201767315]]},"stage_2_query":{"leaf_elements":[18280009013508119638,16467590438846971293,8060230084683838439,12710864283649870740,16227875809967901430,13390647711142671433,2655004526135771958,16791319757306977452,11466646892680517283,9576817100127526579,739400022542534316,13559303926608930368,5882155795018058174,17574861964033823578],"proof":[[8859287737477806861,9844682376306615927,119476763743396730,1886925092232090086],[943937782278166030,4259752835772241679,5032728382915577606,3290392282727907950],[6332378566786974686,9118474372335905726,4361268773226772851,875097267182184941],[1132085936305677001,2696146792986145696,4989887274096532267,2126119154860762241],[16920399981787442539,17626586397547740771,15292983802183743424,2281973351911042208],[4266831146031759935,12542423050082426748,10945700689640780177,3083207207112374420],[14187957889119098088,7681103484547388231,15613736954228619111,733823455672501024],[15638473760976791030,6954496999646427829,11498669177228386068,984593981875874345],[10258136441597804082,13038055152395310458,10056821565562679030,2612210956946026845],[11808796866521203003,11207404278376310701,3721232178035827594,564698731802217865],[6442970993011095046,16767343503915309638,15639864749420030818,378850544348321779],[13986678099248396499,763132589384391927,9776001136007254836,1152105376275273830],[11814671747401227134,14051467977723724755,11743029036639551575,3058315192689072958]]},"quotient_query":{"leaf_elements":[8265407751709832254,12296715845791742259,13670472454793571793,7641483485934747242,8742559451732788619,17528219422631035628,7131202490045574161,17222732473806114304,8915934786128424296,17478353321914378993,5840707644096178088,10929213252143016092,16735111816798388607,18162818324827994866,6406717822799112869,15830288299443881608],"proof":[[4967577392751128547,10231120923999071985,2920288187933826456,958807157317245791],[3092394109658711809,533194440803307039,2107713047296641498,281917863637075782],[559436666174139517,17992402307799369495,14085846431638618078,1973882349774879321],[13550452749842863058,9796967015639244127,5629053876381955083,638345255365464904],[13746150254545166815,15140374587070621509,3667595646034042726,743544085393785822],[13589156500723121971,6442717902188720845,10611670445803161354,538358515115667240],[15473455648144377650,4252996537459122264,14782827260532056552,2939415269244089094],[6352249808613789468,53754944102007352,2478300398864278931,696724686821481561],[14767227779805144849,523980339935641819,4916097963648211856,1699271712100775424],[1673228963995879266,6412421679271202550,17345905633693911519,1453735194706700661],[11218010515171313392,101745210632366747,17231656761344841354,3308126040096115441],[1142141420400307793,11479452402825870557,17088604191880103896,762895272704649451],[3504417128630898722,13418354669506357867,4877712583074407316,51888638990079231]]},"setup_query":{"leaf_elements":[16747052227524051105,12870503493232299897,7387220514673987351,1339333837602199481,16747918328338546696,12987524862862206296,7458184540077493719,16561956463250066316,7681491435899188220,5236884676411369852,8143334029580469066,13058047349709851670,6210651816470022307,1259607409855661529,3571654737126349132,17815818436527183103,12599248445261486557,7682359343352202390,18176536621467437726,4791971110248363939,15868368691154763902,15423037147980089460,7642077975305740149,8293057035620600566,9949842387765063022,10921241653581493327,7557182855315120528,11744231115835753088,5984135213929303501,17202975187523845910,3285733334806358128,5316891125243765785,3245697059015649060,8083182424157831820,10445069711594022011,13572469799958737371,10491333743773195049,9079500663331008595,15585367930935648103,8073870201697034053,9267910660633483394,6375683406729213489,11176089878825257988,3813976916188635840,16597814978461411597,6299174222607142499,17869074988840795169,2460699796722598779,13071802783172978008,3935188194871212364,5279902447986189562,13660219308385664673,16032255680562315511,17226528245240393823,9026174948625806070,8868506835612959507,4834681182567607502,18162475110619560865,17383086281176264106,16481554970874116092,6921655115418354927],"proof":[[17020888769200384246,6342289120486297637,2282033168318114611,1109450360645096053],[3913569535061780345,14779248366466509392,7332546830268806066,292953922607843272],[579772160864529171,4852821184334431198,4201029223297409239,1953555181573085614],[4254964960699300228,3756083058429470723,17175277677537909926,2570973651596630618],[14824668216646963762,7820528152655483340,2819609188775595586,671404713276198141],[2609647830242647286,10649370127312789791,795721718637389357,1141836006990541302],[5574920143586176230,15516872148987706507,607523082096478731,3212669687190729760],[14717008524679147372,4650951541322338538,5773722309021551,1428899433806618441],[6434930348788884492,11398719568328309163,10493250540552169876,2699222612433752275],[9161858143714012692,14583841292042326625,7505752205083140831,3223826884155486379],[12936042570630472179,1310901294642854077,1974545396587028508,9396074164269318],[14626434129209657568,3704788492558821904,11586933725645472561,2183731847757492550],[16340894896221363037,10515488107363041749,8989735385112029763,2859595575457666712]]},"fri_queries":[{"leaf_elements":[8953210716521508742,13430643931864996402,9186008392111375344,271640789856598445,5995511245948303339,18025877909858361663,16306711897541346531,11706973127133663203,7231821491795531882,7888736550478092763,11385391423263547112,8610557821550912546,10054511550871260390,9589186668815366176,14554183551471723688,7251978104182782834],"proof":[[6545876977560049987,6324325623585059653,18421782886204428654,1336775510558370743],[1784279041911295338,6893990376610786087,14657258225746427440,2894307102108440182],[538422128960354073,5079659609558248009,1601371199634404579,1511162614920031178],[6360940289710848672,13959020359172562063,7734307203992874219,72457029483636045],[2939633391558907317,14596408551291345863,170188067083817089,1591644173987587796],[11959305332501688504,15141526033257603834,7456321919182154890,2580728452360402841],[6380864619414380636,16167847419220614059,14037915157061739524,309969490492929172],[10992314003799372557,17322716724534720083,15751576483304408144,1646111252671489369],[999846444995399222,14011138294935011139,6667964318074757587,867213260052525034],[13614949841622580336,9399492980024187335,15638599896098024049,1538027079629728594]]},{"leaf_elements":[11530333504239215645,1751366369809449551,8781810676880441574,17898744044518770217,5068123437852440080,5767189567059560148,11212307793995376907,8176805808070644216,11400983458819192016,4448425662802430695,11211522929998577173,2774223502593013931,6955805867371182938,2912552641121283820,17877098378778789567,3452134661020584941],"proof":[[16046424079505256161,16717425652690287279,4028470104283444491,3042689486287658667],[12975326195471338756,8925853549187645950,4063408808751826092,433831207167069807],[11142964206601506757,17493852466301855203,17753202963181992484,1533192299295367021],[7772034170709087401,7904938873317950700,7550180933320659345,1472476815663134744],[14619780283819901678,12281755326726147473,319442712941351599,1558941547028822906],[1389768311319449007,14236537471961652686,3349081074204103601,2876773415225488148],[16707445333894112763,15652176173117182806,12717696149262687733,373930509062837472]]},{"leaf_elements":[4522531214427608807,2708895458228607768,14378655018498255086,3701004547392321150,15598906413480729310,5769931387414445109,5837999110613815764,3203528792294961933,13933396286397715199,10145643743243072268,18342763054078240104,15109249409918197141,2868717040574798996,15005633071425220544,9769550803238356021,16923072860317850832],"proof":[[1946900366549917852,17640196811033354600,5063518774281691521,2709440878538215044],[9638837243345328524,3548442352561019961,7552415862605738816,2591611983958661810],[2598732342918378786,5317963112505505860,8244752469313706919,950042062237983842],[1395445178162007610,11626158447455766250,18397044548169564307,2769656745606904775]]},{"leaf_elements":[9036089175381653959,2987875599192350377,7744707005118505168,5188089847094658525,13129935381927018420,3730150788540291038,8209729877721515470,17090538519922816154,9607968513778767361,15071132642506767584,7320125160743097689,4991892819851375059,10068909456476243812,14089867269071297833,15389351978943733972,3387928692605495898],"proof":[[12726638950376879646,639506612650757720,16912813671638057237,2919186756859426224]]},{"leaf_elements":[11506617648987991818,868082017674053972,6543021463611153452,11748771781491803820],"proof":[]}]},{"witness_query":{"leaf_elements":[11381130096720056043,4418091170695323619,10706390494723173695,9530233665068317648,14754436103353359608,1608000997116169830,7405582144252957079,14428396442665963301,5352866742700793137,15832087951235178744,3575667938383293319,17189010643600120338,16816323120627605623,8843764720297834529,15699600556583887434,10840069773055053516,18145644424040060110,16732179017104267620,8190452824737487305,8784790073303038185,16125888585446211341,8826704773435085079,18322416113412309471,3550550118346996363,16765095245179559617,12576170432832122323,14628333952875026779,16175949987915769416,10117950228986303385,971133087009432842,3923192882560719941,16157485869486452133,1538186344167153287,15126261481730218562,15310514117095245086,2333242471521984819,3703367306420312479,9025389388872128688,3428273095580407781,6394568940089753286,403028626109712363,6858655271006080739,12880233966194053229,11431182295360732918,16970199215078244003,10674434914952537700,13130293830003105985,9746706731420320357,12280400879182994221,216236575832048881,10454063189606820195,16817284752601497494,17130659169600398267,218405356205299384,5468285243885359617,15624300742476548538,7390370213812827278,16175755706178334066,16434499950499644554,12009463666880025335,6499887326805214585,7013722265206764493,11912143908962525035,15547686443017294025,17204090477886003544,16470063732135174680,1007291153992430010,16959844123066830936,4580068045200603919,69118233644283635,13505564307351565602,10384603751724244217,15182632035517272789,2426910691989238722,10638442415476019228,13452727080881450274,7279287580390764541,15080046830848820034,17257046948875660111,9284326726189456559,14251671883669082152,2564110953368817662,18040000722286480228,4063068910394035503,17857751814657815985,12672902027536733921,18099287025125935238,17695394371478530383,2338778277458974231,10946207134948506605,1461533349317985835,10239336532692073486,17459559200146095007,8172991926965051345,7706373861468414472,3868169823586813041,7250287710495002631,806269354540034254,15759264878198441357,14566228073721018229,7816112481244556470,7411463637164508502,6857215478097658390,8013302220157404393,7706140505252264423,2237704360168306470,15385788790897275087,433022581642711491,16082961872276869441,1748349967220953730,15311523343952583187,7932144367545293651,9122819106579246112,11210066333622337600,905452872226750715,5984285822040650823,18223545883506965914,10150450708601417586,11847744476277144159,17625118990124987363,3252090377339452782,15141276115708692658,18363566780768446639,8023947659434767730,16517651902112257607,6903799543055283755,13157551212526828014,9114527326271825177,1430249512280530085,17208585497003644982,4003870372420974462],"proof":[[10636765665343972556,11385574872017768382,7622071564448307217,3198132448875007877],[2846898399276917060,4923445195069410287,8683671284851593000,2892267862329504292],[13837921771211512133,4773031160065282843,9979788310038223609,3178392181569301612],[4986878358776635029,12305297340767846716,16528882733393282415,1594586598538032493],[5435979976920785298,18117504383218081518,1347180638324187068,3344016135640309431],[9518438687497213235,8103665350933904694,16386793265962468953,2348328082717094094],[1747270563178215328,3143319401336715722,7099481390908865166,1020395189797517274],[13298451859968953245,8758676502645176523,3915146447991670353,1596467244368166608],[4829086690355400996,5958990850533270350,3677572876392162503,2261358819639150542],[3140279070706501915,4078218573849803731,15130969812479510640,2629247039101873382],[4470573511364538295,3072401176796498953,16201908554622770280,2788031219243177258],[8425516942936181230,483034393298231671,10477473390075102732,150189516499498482],[2402167573558463631,2137105850631415449,4214898604496638014,3277064941376453795]]},"stage_2_query":{"leaf_elements":[10211015551424443135,11681814958973377159,12660986941030048392,7349285843489524261,1250714826165942290,2569350534266797235,17154450489683769751,1440163494084594454,4034734564367401706,2782214164815366526,18365677222573465583,18107533811872065371,16029170231250317655,13862454113610788121],"proof":[[11857430013524163585,16688558619810672627,8024025905495607429,359195990420161290],[4353978048010923061,16209336491314236407,8342059902166351086,450806722869694311],[3415150797619744641,11528018021363580187,7539801068945299842,943484162544944675],[2245777233327352047,17249213478856839978,2173782979225619823,874973605130074310],[1001424908032419296,4183492692115837517,740986526967812706,1394832398980860812],[16277424713662625778,1352674905560055726,14494249286001805380,486802226530029216],[18160594305618128661,14728935349170180064,12514929318247900034,367399597394383906],[6537130901265295283,16485063720762150364,13823169674010708268,2631769435256404356],[4859248762256803829,9584343984602993891,1987540772204714605,2098963894906190508],[7031515034786319741,18275132255742271382,4323677802722786521,654301555566673801],[6799894136363316477,15151782857945782652,18411117048748230506,1898708911910688086],[745666826706744259,17567446146397159290,17029694275521485389,27260608986812560],[13098703293661233855,188671376608403103,4925193949924778707,496229296521733553]]},"quotient_query":{"leaf_elements":[1570071531379991477,4727612152181467629,9411066513896300710,16883188662781275681,3794771022735113831,2217101069748898559,10245170221026920909,6668246869627293083,14725707072555405007,16234540307829565863,3032785862684407736,655796073388821280,2853767002522660078,1884486221989689814,3501578465614151574,13793701041790574448],"proof":[[1616200536738074416,7982774960905498205,9323937005023158446,789056318155724686],[10658028648400024165,8565695268230384489,16318953676788949619,2434973817672414107],[4600052555526866264,9450498163207192586,14241998287906358120,2194933490963325439],[12590823811343337977,2818190716116514076,2779770876043884080,2136980450959473327],[11210472237266818801,1180336622630154236,7242235072920582104,2640120135016619206],[16931000801251833902,6052509604245528889,11968488165785330371,1556672677063880322],[10903435829209587983,8956446871989644359,13659308161436375625,2398062273416001619],[9346759857334410035,17357879698505902408,12716885971271276232,3235671482609092241],[7419082044657024225,4510174949114636386,9995911549610556160,740084141018955692],[4321723759391095940,5383714445900943082,12924114311805099977,1959800114989123529],[18248813950090284891,15264769847501014554,16470925086369571060,1641734585999141467],[6483723199069637619,10922280988596920056,15638188869268327681,524906435665901280],[7064726902681906417,8802656868035565002,10106252046860638745,2781091557009897750]]},"setup_query":{"leaf_elements":[16701293988911151669,12717733492337313503,16839096745928248860,10109518012436798952,16558552883517055941,13084243925848934942,12010567130075911449,6122520269704044939,14296929821880960315,6193193857622766246,2101600245934453523,376137331269349650,4804652258900645758,3849944895726137934,10994499961413995535,7661549761143979363,12888395814079414826,11085182739655196620,8752411132261344621,11281140057101703159,6169696576839868904,5849090709582567059,12445276985995983217,4110504352419853228,6346127431931334202,3347655863819703031,16119324337639661353,14630475914942928629,13978934954514453120,4943897523694342319,12909393369878546350,3813165339282253924,2390253967772564148,6290906497802444241,8211319162799391912,12629053625079063221,4093133371413920351,18121382652396892412,7953139713020132067,3159383338655518376,8072495412762004538,14569711008381684446,15412118939796724165,637227867874346212,15836390081343111288,2379056287835034830,15201473193538093753,9530416341093783138,11816995403227608407,12452972326601649454,17656471857516396606,81707916725270703,8268131378156997925,9727357083839208600,8879393306617700116,3432801084428547291,16375748110726746217,12850511115927161029,4178597073981254831,15867114773429021290,11552040940922368065],"proof":[[12528741290643539204,10975718579568652694,13919714049957052209,1227441226390990196],[18098699206066548712,9889861307679998155,6008232950049305295,377397884530818584],[16336886661038891680,1458689920254483160,8114869964942283603,705576327951669695],[1268137326707264959,16574892741912310808,15298800573350908213,2846991819902636062],[9325248488282481651,2428106188944361134,5036648940624683358,440866465815752642],[18280492342235439469,5655752789397339448,17296446819445722798,1053401606864585662],[17781090622886655784,948669538971273933,11705126096938247333,3444018051906673690],[1432881727127110960,15345576146065276842,452774187341208890,2841848704248745791],[9837277652016128890,1813434351550800808,18064557743896674895,2554336843557045670],[3137825612869565015,16190956652448818454,13814802841207229689,2727700156159039890],[14211253461318336953,14698553904440713876,1215335496790964480,3214092473229563681],[2319840627421732396,11880222938202960862,6462039118647357450,396343187455400076],[5510389358968454592,6342099385859423646,15847287637010183663,1721032798950188614]]},"fri_queries":[{"leaf_elements":[4141015755035035824,7929819373165337158,7569361209506647995,12559300687235665155,13017939409690148424,9113359440272217096,12582573815639195887,17723893858795052404,15797639268718969884,10692265460301980762,11173142034107009058,13246226450086578976,6868860593183859079,17535786141412617323,11749733549297615571,1763624441139498475],"proof":[[13810990734615908360,3794182279188607499,1037218506428924332,2489822007875813950],[2629662196557943660,3049368552432665046,1740197224526616989,333576352196433069],[6537257624729719083,10082067332431634411,9984240860145404040,1197366791836183625],[2932413117697364288,2539022990246264701,4707418089172622562,2191718811874383429],[11268650306520981872,822957727287946688,11389419539557084728,1558209520736845273],[14880453339761676419,6303383025418016265,12352442150375740021,2210075666515788345],[2619500987714521286,11482010577440727850,8410370375611017021,1364049326102807099],[14810850173207459937,2116454594748557248,230163200410766595,1641052023191719386],[15449742020830670463,2504111050166408295,6502440755783385744,2746750322419423511],[11512094953525416513,301201197378265374,4065232932777357782,2702801754939657824]]},{"leaf_elements":[15153100985228493408,14905350214289553170,902689133325621331,13106770401205820010,10548203388718182739,5631226971291496536,4368583201056672465,1906223980146206391,16691927880260361520,12583145723696337313,7899590774398371467,7164465056247216164,5419260403645748392,10858167653914846352,7302614057661440653,15876271216906965425],"proof":[[1904783563588208131,1162898314847537619,13267163592595629995,1311127455408813200],[2392141390304054594,11467022385129410741,15142332774791175337,245636142514410844],[7783768723070173024,11781420793876232060,16791622723489075159,44122111287453055],[1132848919924385043,14056526644500741775,6332784331118603800,2332792059641125617],[10191315401445696412,6280994496960481888,6251536364121698284,187367878256504162],[4690438310709256034,8652297081282077156,9367045947916506578,1164431050711913661],[6905604683261516761,785630753018559997,8071271293678686283,1371257465431982896]]},{"leaf_elements":[15549396044150810935,4377449947370068005,13788924562444469111,17902790492450737797,14596478425670398602,5656777946315898163,16447723180772387181,13465267525287585420,10147321902506868296,1196706565521110128,1798941292919754308,949685843388830599,3564976715598543520,5097215988352073899,14057553010599484721,11669462938921547717],"proof":[[12941068349182194076,3594824413437589077,10459936716266878396,2338368559615314095],[2697009025509228754,11000852118224199768,15389405589811843678,1770937907911177182],[10890060001537195700,13057372539207777287,17410616761313584025,588520907784414304],[1389524551255036162,7115597326301420030,4677436100140046760,2997251062732232682]]},{"leaf_elements":[8766804231547517221,4314020161339189469,526230993367059777,1371290347504725484,9718295733965069127,18006200898151862508,4150610419468893976,14342643557102012012,13624566138619880019,553955421167211366,15268536086186198656,18097336813190350750,4289863886401648441,9987687823700455758,7369310771996817417,6478430192287573656],"proof":[[13748503802770165510,6447469746112887630,5266659250392852870,2048396772139579074]]},{"leaf_elements":[6865243823879750534,264255220950879342,5012916995573505337,7094628130780347210],"proof":[]}]},{"witness_query":{"leaf_elements":[5559406573881567469,749647979114047158,2189369303140002656,18419533234370347045,12843205900125088766,16227917063144147940,15138369736228338970,11914333906680707129,9830544810698495231,3196375568525766082,9584440177031075504,11132488836546239945,7331505736610393204,10343053283288707792,17148709185694831905,10799711715807347588,7325658095155188313,13581931990313539551,13582804746812382399,16151380273755450655,5647408844646383177,5171761596719248215,8470243850122480665,14626999053933445616,1253149189715026325,8171668819911812843,4975466775497452553,10184703759926615095,240166324443738208,6254014312837991613,3588730827201630690,4586137197535668566,10882138679633345342,17749601853497519963,6632990996069083368,16205960487695758355,1441588256377950497,8264818239329985827,30360001876213571,3270673483845913589,14520735899985152265,5140799350816048562,1714431545223320886,3969014037652171752,6596312442985917284,5859039480018930667,2397254695277448850,16096277647729551875,18334785683309338898,12873902075764925648,3493113422607088239,4295190643307700815,5664664686918619232,15220117454373159445,17641386057706738218,14001084236565079166,17060523132722874207,9199559715825048089,14164399333952190637,13634233793380609543,3525357540447278620,12383746230339712477,15419092694127529856,1127589617814972591,7268799227794399140,9238062988522961082,7146791427965308093,8708187059102916561,9820530083865201962,12090107891248390320,14343717786298303731,6680054456302090824,17930373393932042110,9484827933051121536,10922549487951068852,14441454805826414959,1862970552748686005,1389420524302588430,3100872726551825777,5628365559119846502,8970181292497635917,118310903514786282,1950067479083966117,16831335976812094043,9985718005673396229,16724074902954696039,16982248023075576860,10027781331860944400,2967978148749316807,3624707513729230554,12492628729537296489,8272030015363138307,6251753846873914974,6425343718863761549,3479120408346943544,4633782966799949668,9640152578118653622,1923726657454455177,114607391269680088,12487522789097903544,14855244082228148385,523420015151053527,2783664324073169975,6860931776839535667,15873658916293966157,9044360822551789132,11945186818668392460,12908638575653736278,1176567727979049797,193440929219637933,14729552564792844707,5089755433265121856,4427157617086002904,17593464416358349123,4877586882370052878,10184564266837165,9611045817873368674,8145580947220915921,10226562319523599165,5750070584262348798,5952433866650115452,8175108559204031995,1897641242588797657,4925538441982052718,12708863831866538237,11177380226243755279,11233042365674870713,493190057289516361,9319397779211589116,16833356463292458916,3409447847206581779],"proof":[[4363853985937117355,15916481427926450742,9470470877753864977,1813665637916487696],[12416665117215326637,14008334988957456262,11895736360879716522,1790966554531433242],[15136672501117152787,18243347356251856274,16914972750673629566,206598928635686239],[8230904190733590208,8284327096148074029,1179053657665073620,3434320027778163945],[10671264266441565145,3416070959714203467,1922848527670402418,1785358724849789123],[6856778121222106268,13463639852634749821,13835268522783990134,2032974853602307968],[7723956407147189999,5494535696638472598,17280116167191638843,2516034647769109338],[15042620436125792543,4328471352099434356,4133763943020039381,1116156851058173248],[17709987292381749157,13869423038606411345,13442839829634682994,428863761033056894],[17193176952710025348,860096432313589575,17963610832003238771,1391358697504112409],[4734995795921915230,4623969510906222627,9256522227688797598,3473826067968244499],[2892709706934527733,17838480464587819444,10155705260521547536,2387506384667558531],[16174210416781440038,11224782680825625613,13584339858344595283,2293598389344857220]]},"stage_2_query":{"leaf_elements":[7922118165673263888,13943700770168875814,7585982531578202413,4345173226518716156,9348903270183886902,3506027223917219936,15257744180076487828,12157132206189901618,13815663275538098602,5036834221085854614,5528245645354817375,1348821689410919546,1862185301999167920,10666301250919858300],"proof":[[2219230748177032942,9015838469285855862,11880723110009211162,149473252795911993],[17512776156294770750,12097538450121691720,14101723035349276569,2900532533267601227],[4682283947832646192,18158128108124892144,4650574442869618354,122398471702395019],[7563129450886688636,16420673605417596663,9545803899328509210,2508037994301994233],[2230283105006200349,15422815386257433266,41282829872735191,2467667680051531374],[2531697954861284395,11780985214427733371,6665197058670131547,3020494169762385051],[9516200554373079523,5126279852544074017,4816142904478841259,1712786937460548394],[2767789402370602850,9585156646402169768,10823349752862006985,112930487613252682],[4097999239774129441,7604543444120790135,1894460702108994104,1086651341842154717],[17273947804060033556,16199810104635056885,17938796905747720364,2949621109597555988],[4307292625710429256,4505716506027778825,12415975303251403643,819183608158687576],[4099148929035402499,7673469686607061609,4505982977117334820,1485991602633362902],[7143706776069384250,15680275494194306607,14480354172152921765,2190139242083446267]]},"quotient_query":{"leaf_elements":[12055016116635274628,2017212608023413473,669701679481194446,6078620325433338747,14044359331667598302,4271925409999627628,4841106241464308876,11331545253000580019,6252867386451152114,8773725447174504196,8513631029463688082,7270193012201126499,14550843587098151104,395756205016208259,13808166796125838990,6210788466344595895],"proof":[[4346719354685880244,12926618114608717451,6759506398712597439,2141150052987243928],[7254921825377114585,7805564764983337017,10403647443254409808,1011905783111333642],[9321565990817839190,851277875937222908,11583634230498623178,2508619690757980924],[6912657797326402509,12104108814810088442,9985565283190634822,1400712640507886203],[5662121090399955923,12507363218258419815,16974820778594980611,1647747266231355098],[7462212503953252053,8846676593677081050,3720150450364719691,2714541315567993822],[17492906703257543210,9092582390869709557,13212680261756691886,2842552725939525928],[11023162467131714722,924729220689830403,180931059525246611,2003107902580152060],[9405858294736761853,16425136972550717999,13240745343526695327,569825521222689064],[7393917858099576981,12169024137893925324,5233685297229839670,2366559202330909870],[13071015009834032515,5244056340103240456,17527143666732474632,64895979602718316],[9864148082391051930,18335226582304505341,8569801661974152939,2353801358142108048],[893769981673929871,3319556979175080647,7336913751317520875,2767808378512761087]]},"setup_query":{"leaf_elements":[5623220047444164818,1486849908853603724,5705736442397741773,2469910011679317322,17640060813696286619,15495674158881169861,8931076255951265612,16187174705586483261,3650742738501422880,11172692071647106145,12809293825820435275,17335005333443614508,3451824887034557100,2054849750893442507,1536282935166712331,12147062624257433947,13516082013347612536,7338529306960876893,3238079718615534381,10705669825261030787,7424743286488982394,17597156848112869177,13784320392898251833,4543144423345199211,15636915115569575981,17682136220391382169,15277855497495660268,13281631218420694846,8881066763397756869,548473653017347790,17880217867505931013,4168029305008652809,4058713587932421276,15512466725411459678,13362569127572734625,6679227358791310170,7678533582410590572,14865097562197666022,2441692260026433796,13815040870290997649,16426473554826853844,15553185011777516705,16949718373317920610,3903639960654892640,7977641527811181507,97998152330866899,16434155302739157824,11240504636819924498,10293068834494327448,10571635011052521300,7716174089411559147,13771721911565119995,14448133008317346257,8980380690060668635,1320752963354097403,8817963984210094659,11321537144550734274,17397002871792917443,4688727770451555332,14536686652138656259,3250819622523486942],"proof":[[15281292989758118413,9960368117271073591,16980086578656680750,1920865640899662226],[14991627210139542205,4713171726195138160,14288455477410944245,1218436514210389947],[14436198302906163253,15618878822752666187,6904928634242075622,215873855892869042],[9764137166038254099,2412238046389423466,4374586455249890570,1720837215586288707],[16178437806443529110,1921752997018159699,8109843633569391675,3134183326258159401],[8534094153193231492,3773965563293280533,2993870264303556007,2953755658859541212],[8728450404752383960,11943747652111801345,4193216997335896874,1136719122625350982],[6374881958160804808,7715497075395279158,10456674726393758772,2858589021929213050],[6030411142193316661,2522123567541469446,7262132202201577603,3002253707942951799],[16032122289984447523,7499403857371149926,11887253149445581209,1683321519167369353],[12124909263257621136,10818567662606497721,3959115628505008577,1119369570721152884],[2209330244228393786,9841280879286562939,270696346365318705,11851569992788159],[12671376312025887274,17441343524713900297,10896011836861176681,2912297064607346901]]},"fri_queries":[{"leaf_elements":[11499804354974479026,8425805836772282443,3932488415933841399,16535845463908216862,7397434452379954530,3114701194886986237,16136885153449591148,9131173935143069256,10963438946675574798,3478186398916802647,200533693643064945,16222220595250667200,14429437228758843083,10973187636569281618,3148370443897343333,12499269743957640584],"proof":[[11746879286560344612,6051811078629901953,10774406656080209445,411811141102335575],[12518698658752874943,9732047466625877167,18188269043810642952,1926162134663873283],[10708180660010453041,13415259397284659947,17938431485287333874,2706944738517362489],[756187216599112268,14816289663633590365,15122165558869542724,1070025489475126399],[12956151689882073341,15314030438263027396,15990740871227633115,1399256910532196145],[8475909807969763234,9152329035167862776,6912010028224455197,2202459725789123163],[15750385535818593120,11946133434391833354,15343526478737079321,727518421252664123],[11024181518270608996,14617547031936786079,16376168583193951650,3074166109090888096],[380973593249884925,8211361821003589829,847491229067143454,1569444070397871644],[16109863426784669012,15963846919760798386,9142194185212147107,2313643416305218987]]},{"leaf_elements":[6929414629491842748,1365156121809170177,11632795321578701959,16348351580815114514,4199806014632749046,13478983893000608692,2688108622146495275,9153998855440637692,15170724909505682523,5555106124920959165,16662853090672423391,12690044657453622222,14740759025546313020,8165574303529211553,10798366361045348582,14424362084978268522],"proof":[[15537292091830035639,12925026317603621156,14890973226088930507,614546964859779556],[4463916695716678161,16874370437827275905,214848589596104186,972521220694257935],[11081156110326022310,13428368980446310311,12911907201251225563,2075006630915523632],[5029247599413956245,9614974761259856412,1607895646761284198,2761613305995890094],[4575792760137230209,11633705882469235577,9841123168578556127,2039102739463027263],[17680882297911546997,1285525161416870700,9603686181424221186,2725273453195948649],[10344127557781956199,7906363140092405288,5982125655274322770,1672165157955432393]]},{"leaf_elements":[12698284169577138121,6380679397958639310,13463694638516145173,1867763465918078328,17101323362300856734,5571058722937926322,1078874112603970839,18289262124767908587,15023365805438353369,9005816757625959421,10455895038319905090,6326587037493777221,3104769015094251340,16718980437211271523,7547915859214082494,16090006472822739677],"proof":[[10072939034673203190,8264993371088481646,14552178211266357679,1070107708830041334],[1975479693281105564,15428429971138180179,4843772626935739041,3203071186112330796],[11161226704473065150,3322189911423566603,13118161592899224271,687763930591193762],[4274407429085135596,548774181466706774,8603117836559137571,160198004595477839]]},{"leaf_elements":[14694649177522924455,8970524565615133352,6698130501351274130,5407467138564220850,6709057259898075644,15065386984471511193,8847484406550740690,3130960100291456344,3694217830831795275,7041401053929351398,879613210345154478,14654620960715256415,11095625651784495053,10579595773725487118,8663536013231766845,10383856026212629571],"proof":[[16046369096493514353,11215590715117997524,7658673164007518840,655039943382377449]]},{"leaf_elements":[6485988802393016559,12130974100501667025,3138003141619716888,4081174251100168420],"proof":[]}]},{"witness_query":{"leaf_elements":[13045638056005190393,13030191807473405744,17310937158758213798,802876004308351249,16590408904121537754,3204313087078418192,6647499931969547427,2406600641034318677,14754497814501916074,8799964358203652024,8078117943781342456,10820513014824133509,17775399899322435694,9167969689473628265,9201545433445297350,11001210051316988901,15451422501135685793,1172658916690353626,12080174720561729347,17731548320806203400,167612937351920271,18125454603568637672,12584545882517845542,8988456868624285620,12815772095462106726,4121343729348634944,8133961813131046865,18161796032634800992,17238031223982757847,652750942891806739,13821159194220858566,2354715408053866045,14288210456317323145,4252765257695200203,5399759088249943704,6128258284474699391,5613383458352610857,4925850387416044132,8242597797201387137,6062847965875482143,12987799638006323818,9168383055568218515,18016323572352341928,6618590560390955824,12336709138269286372,7281168783543597702,5222363798857339957,6243840294323695306,11444671123888538188,12207613645922346065,15268023839617286334,8183592922212972217,13241563679947138939,2101171856508860239,16780868352981761961,1640666275126129822,5692998793602951277,10116632386476475703,1975216404806820585,7298507116173693005,571415976573295533,3322570632493704505,14774299226439264603,5165963963356047007,1168565912216475895,15773435144079633692,3523378655803884265,17032602610164236075,13940214908798110521,11315798592036388116,17320734295302875997,18178204524242918713,13091498304763906812,10970437170633402120,1850311158911041859,4706147219680953526,8874598240021133611,16514251618836565706,17595608150799706832,4632673587387121585,4532884191230142085,12820485894703422132,7184482191892395181,11439903065290265474,12476129150578479841,924420765192224086,167203907766865015,16944473854472164470,5559146935263821643,13242011512894284381,8374365479291569822,7335391068161946665,6643078271824181175,6267939086769510402,15465654477140987470,8781383466315201766,912198067216312198,13662057183974058480,1064410100548229287,2519529813704305423,17309722451680557099,3252961591526735729,15665480410975473742,2425123447311407758,7115333682971649605,983561668662386744,4107870770360521928,14674184698954962671,14030307047207616593,14962983570770429519,17839864796273435846,1563475775716350731,8646934951659794148,7123097632563292805,13269135715632387210,8107392759825062179,3207529222201570256,2921513304892649043,854544875333376551,8328939000093668306,17316061104171437114,26753153765059724,11280157440439506556,2147366500633857265,3713327766650976969,13179644570978892739,13937422695327607725,10593052274751176102,5778642146373754980,15005699725661797955,16134018450820667430],"proof":[[8123512620285352593,12120275135548799438,17359547416993716440,2375349224925778904],[3965348935089276409,12815588592547547981,837868902004177388,742689524218448671],[9125071773396722688,10810829406734117496,14213024766168573703,767037916271083689],[6802523782377188243,13876779709159745282,3404908396023706801,71995098575171362],[7946386313275069542,1006192980158858364,17804942231971118345,1841860580871439205],[17784593099285883239,10816798478632450887,17013917358759841856,3120664882638367337],[1650812198388228740,13113248382101112316,5517339971177569069,726834285887879586],[1079272573430420010,16380119774048879336,4723680866198798696,1660631656862667237],[8834834589058579736,9573414920538195309,9469969059822307127,2853566505153225370],[9068500865335892846,17894902570814080090,17843791793667551540,2741035318267206374],[8945142244981022397,4132694561716680804,1668048603293474420,2592677836486414188],[2344436475178933391,4062052178812451310,9943466165468859811,1840010875486786956],[4832379906115138372,11028588231085674769,17437286517034418486,107753723037220434]]},"stage_2_query":{"leaf_elements":[9964110427227420818,17948518891976042144,15040192877608502957,408255667849237302,10325063572155835497,8439934956650689287,10755483807324323203,6117716009988039968,3792562753688536017,13838207241117508287,1176277528714501882,1042688589988781960,1754916643601715775,17163827646567502554],"proof":[[16996393949617460733,3632062165731496261,13313130332924304666,1630528767298204811],[16990938332687033481,12259049190853548370,13362131874901474396,36347199092873082],[13824325016726894436,8947267500020652106,13540399413107610471,309692617945407584],[9297142853232223576,8567684425490763008,9119782130694839939,2855025655131043333],[4567979978282458564,12900497740408619646,12676812674499068105,2109112327252332536],[12588861949601185765,7263126999372261143,16640882277990366986,1547281470321861553],[8545651807061195426,9850500085869610881,3838249122541807916,1380282496679672764],[11667502565552207664,2165987279657900869,3051573764719478071,2460158704776688153],[3620529574409128049,2909611484370346720,12673113813508401893,831832201747640700],[8650771266622145962,16375676950112046283,11481643154926592963,2506719908025588311],[1440829670241841936,7882718851365202077,17428541729952155132,1230293759435640308],[11264749751591383823,767628461264999960,5345022302686527027,209784591318481977],[253179850175611026,12208827844828377664,5809494268557619388,1729946356149640536]]},"quotient_query":{"leaf_elements":[18320236754215577267,14087485729002080709,13258114896207930237,8549288608258186846,16675401220414594354,7831309406545088311,218892335845074728,3977411489939216740,12911992331804793173,10072364754810694118,16211230988194276570,5807629257565582035,3370326243305909952,13297231244805871202,1298196375491717041,8506652796902952638],"proof":[[10795066615344129868,9205095709922883418,11164538196281451538,2536294387903744435],[16555659534226758242,17442422084721411558,8072697531427969671,1898975290372523535],[12530605775431299845,6927200052942604032,14252394340690115436,1531807211526720517],[6291149450355889093,2583511597285454446,77089133396865632,3356141060095730200],[3763256062376783710,5237355023526170916,196459803660642078,2505473292559223178],[8266547866082697416,10051423282950453516,114948799430868208,2854704686060899211],[2119359842376135242,3686072364287080504,10550147581811778875,1971050412122573447],[955747276652935470,15818653483150924295,13600681352204114295,894597453891491142],[14619688393324815930,761000202659330304,9978565748744223525,2370822683263364394],[1597696285204455968,13113360678186446514,3340200003660249777,3231363616013267433],[13333611037837570757,10966559271191553465,10701953971674168956,3279215810258115057],[18315803809008667171,17325247700639040458,15219730772163426330,2799321953579950557],[7207630139810091379,4266854911965260134,6829268419185610647,551985630482796740]]},"setup_query":{"leaf_elements":[8618030009547498974,6385221707334005108,999267163261136269,2497994390343262526,3879540893645026842,17517009067123596916,15876412348961807214,11034087373355473470,8910326643677640691,8799522270427415358,2340991441367028849,12712729339264631845,11453987099961685661,17352447331033467913,960869283003909962,3758299026740878624,3688492002786059216,12916269957023495609,11204079218212716752,13038758213601104287,16933653716907565407,834919346188309385,14576836968503540651,11412146083908998792,15478924148781966959,1512678958474369764,23691550911449970,6535151887051679220,2455648915410774690,15246607930811412763,17947028838994520143,6600640148259172798,7008131429130033283,17845151254159996665,8982537722550889049,2485837081782247034,9456712775765498175,975360696283026528,9902376210496183357,5889025332348570560,6928736622450437769,260287381396841731,13935858581771422070,2748239125819458307,9491009016908417882,2916579586732753976,16005641524589569150,3276326280691782404,11855134707059787152,5863063044541300785,6951549728962109331,12762546720758668089,17448508930515584823,14081729920200838262,341827269400327496,1309443904470819778,12629702943489139091,12332774047139213327,1267983895416088178,4891976800485821634,8750312603503278043],"proof":[[8918454826267477774,10754472288106808491,15048650070452286538,1760172127843770892],[6165423382990894590,10954139324402215260,12413879530741085376,3352623047838697773],[17972078878258736360,4610371874464303928,6291698035743062732,3237809959316472850],[6797867917032523588,619166928770935473,9082101157145787557,179552252916943602],[17013178990683563157,6203741405937926720,12859899757064031639,730483185987368980],[7922420619031895425,3696540672806065085,6552623838820640206,1520809089490749668],[4372812095555420331,8127906948003991624,2424236896461775675,1770682088936431861],[2770538530157594564,5780443567346104025,18175885130050716546,596875292044124240],[4322566344332243665,10868765582588567085,75646602951629260,1456365890761453738],[11589937129659854331,2308153153867951199,7691243075838988815,2924742680175474849],[7888579360829401936,11922182204266290931,3277690841049468158,517755490177362798],[1693793544362908852,15539779474735271465,13362084606296023968,83073674722645432],[14430152768018435667,13625155425001863663,7751044715815897218,1229189555835738878]]},"fri_queries":[{"leaf_elements":[4146213136452883636,14795435396654831333,983596790011437951,14880766584525825750,7081519357444572726,2766089406376777954,221636560777844516,9719270305462953604,13899632067138295376,12464190054389256982,6809020990790600415,988231474761082054,631569550841917299,4276900228554782388,8535552846504963826,4837466174695308259],"proof":[[14087767296181995621,1812668601066023463,9090443059647198287,1318272920369882104],[7963105915812053840,11966223071664557753,2878127094994645709,2429543001899367103],[2955678969250974400,5601837148532324599,16330727811062852955,969385874281984049],[10970414655829664215,16832902275374834431,16759148418683583890,3256929161684250134],[17837400744210882972,17895829555328731091,14342413784771492518,151159139566663800],[9944937977389129559,18100563834998528949,17572705802815158021,1346615519744565283],[299452493740989679,5358198693350343479,14747194576469339651,1342882558941638346],[2334033796281155824,9182664393340093512,8909395258253325409,64655080554692372],[12297092375196949780,4063775297884581511,8331546240352635221,2811606575599316396],[12917255288235223966,14499976622908166881,5436213550229819212,2285844493389862808]]},{"leaf_elements":[6373219193121711340,4448279816432271980,17975623741262847065,9476726989032223249,7642065529123482358,689458276936663381,15422990595222320503,10654897680639445351,16828799326067910516,11852633489182808806,12551358371923848215,17065583836921768295,7271866266003847623,9463058923895044719,11660816687387533069,10251766953852857120],"proof":[[8217782303761500707,1843280836953510061,12877973437016205234,2044008533816622988],[8268872742321199501,17820894844992548146,1946700084338542352,2785826710464694828],[813294305924426138,8953971294755770341,3841935015826332875,3331395153047427033],[1244388220173410487,4777947297051763420,3128713601712470364,625341966561650541],[9086339667247899932,11767333141410358478,1364274073655938976,1497181780258460751],[6638888986919699988,12415880786878933592,15353235368647017313,2241137818206725374],[10678740004480657638,4821612586301572701,2713702765633163690,2883361707359353505]]},{"leaf_elements":[15749615179547859340,2385152170382820467,6158293238120065824,18369397314479308768,8991264182857186475,2595109540519853107,11246271456213909191,3331755789946916381,3359979770186950142,9104016935107853096,2534950715098935098,9951046361554612799,4624696666452572261,3967934743989208892,10313333747320396397,3330206376793370688],"proof":[[10793563227244478484,5495909705855147512,8319192668437680274,206746755093220507],[4178421919246597878,3661074070934431092,12704215678000201331,3171860511508114163],[12947327200571502181,14246179720668150335,7063786210406221140,2827464451635400985],[7349579519894959072,3479006254350232831,2249506297850984686,3461002273469143448]]},{"leaf_elements":[10107650300144122446,12872316686921106367,17782138609005632202,3101284115629698348,8129718703149136541,3488748637624496172,12239539572413537733,8146046347961466389,3729132655365631872,3816743499182286664,16730468474630639466,9624190507278423052,1879743752497581249,4337712219509902155,1896622693346975870,8179875534869575739],"proof":[[2554532247243837486,6767478030061646626,4199547846988518451,2086946322843166353]]},{"leaf_elements":[6865243823879750534,264255220950879342,5012916995573505337,7094628130780347210],"proof":[]}]},{"witness_query":{"leaf_elements":[17594712228481431481,16593049000657764116,3192453836698890373,2827379378138686218,11049225200589323726,4059759649040444450,13767655809015639858,2003528809541566918,6050384086936142601,11388468092781753140,5108782027354372609,5573764071596868124,7741677850997103105,15321552211090769442,11023785334913494981,8760122105723694768,2927917564348911255,14629492412423866357,9307174832375821890,9342103493508957057,1688871804464269054,6419686348295069550,1973232065755862408,4255697477556501362,13969568555507568749,18641175448808320,4775292550972812922,2145717994679041343,17032900337635926623,13319321331126789096,9577125875496422614,2749687349459057563,11252224967082642910,8001764387679242568,12602825078551091413,7667098944453763739,10424391424977562418,4771139287145787494,10764244370967796104,3075246956501869535,15694188838346060350,17391089142925758642,2684632776573306210,16267504557300418429,13882007804885461727,17908797212125396325,9877985175588582318,8236467041844073410,677078963009221309,4735138105716775788,17006710484629239050,11936641322571129866,363143428137515214,3957867286196139163,13429488082791814269,11214636643530238697,860178825719461593,12098463406091192321,2281952856940996716,4510022028682484610,9296393797760422113,18391349732301408796,6673191929670157665,2816306319957211828,3282454602064069042,3920021522995118849,1240967092715129606,13933860033514949300,17507835051632095181,16418791244019036213,1392353942644101514,7238317901295841333,13353115105537432868,1316798251837228732,1969864329880232571,9059242127906742842,8748664586686427807,5546931123066691062,15058884491269399308,4747383855309135009,16228450589734459884,17339491867442438742,12679318108653994396,1312495849169682941,10792972672186353969,4076114097138903134,4260881308412567660,4424676897388801581,7531254674584477595,7276774955470905664,15533219067084233939,2917514084470395170,602652174108739078,12885257641877364468,14823836242432932154,7056424690250958561,5265103550632152965,8968742451623791816,10400236047628891827,15781863473140056186,3173490495531648621,8865753910898506880,711464847612847453,7433423308621476867,10582953247533274182,14539854053192509407,11356047801113540565,8195581380781699452,16651410617755243624,13077903635542199692,4479353632197912574,7052573062040972352,12474147785644597020,13192439888231133969,9170294499847928510,16244361004664782794,14875806970888805735,18287125443125812141,14271316841094863567,9987895921271634643,118112512211833099,18404171946742118727,5663036846186676000,6324863840009096728,12408013088273174018,9371341240514980423,12429456116180957490,15716453089792583719,270946551750556689,8111344784333724983,9256332346064721451],"proof":[[11601569527071904626,2207160474482540779,3954386823163440535,652534907282761902],[11258545736728660753,1658880292145037096,16464234970613666038,1201198080064964612],[6461867633353918521,2169392399423026993,8771877671180459937,2532405229368302422],[11686015906193174377,11971601974109069622,12782723660110111158,1502600254570113437],[6066460396114688167,13714209511031508462,18024375940725576491,3369512143452986644],[17842934751409561389,10541735868837009435,1525583677003216795,810932642537306256],[1257366646100203096,14154226092862216010,9724992082628218745,2376724297178552284],[7813238373931033584,1387498207355888363,1701696535736584805,2326462465775729747],[9263820449688069916,16865561148606528744,5535900983606645864,3339830188277189976],[11087646283219186339,8257765940274267283,16564377859614097803,8149533126541082],[14320153604127691138,9970218165963075177,18437857222265369302,1851927438058469084],[4867128387966308819,2970634964322252313,4305468736211036881,1331764268425527793],[15518311637091593798,7323673137202733312,16866621021086496135,1758145248427367643]]},"stage_2_query":{"leaf_elements":[3844954530135193211,10712969610099561519,17303791143738496125,7805282136058320263,13105525978127959468,1413300948043266152,14242568272864760693,17142340553785413139,17507704795959384660,1130336821089878372,9841959488108002138,1033207711056503133,13206954069210103068,13338128118065387650],"proof":[[5322995688793607529,3916873424303793225,12588086130162497007,1233356601345806357],[3740930269835630911,10549426733890752736,16064592246810609838,375557000053651846],[2744421922904523467,16973071291470623421,10312658665784265455,119877330089221933],[14176084116699993954,10739853502245407293,5805680227924258646,2743892177623054238],[10113235695966270177,4985478198938061578,1576666876515523896,2834465336528148436],[15397088457642254129,11987414861007222128,11934895806089372622,3115953645234198180],[4162156703251917524,11249298832756319366,14758493569041095023,2075141445865205174],[12696428765020101388,1875424536965578136,5106856087063974875,935330085269202244],[9521099742196222,2624336201998531745,4288133587122099553,3352980340369677347],[5605843168891182952,12945943306679240071,2015401203261295875,2549317158670480905],[11522075779004427866,4861585203080278865,646242025636271542,1796407776246754468],[6405381481079513988,14689574099534140175,7330487452385558712,684694691471920619],[4875747540304223294,38261405649231656,4774002524529870398,1268748351122893534]]},"quotient_query":{"leaf_elements":[7411110861272348397,4063685188378939160,3268581252017034750,3719041965109034100,6826357158038214551,11435114854816228633,18288120956409145756,15476248144777701370,9035412303670118323,1301359289315020746,4183350190679333437,11690193991012632295,7435762539165192772,17710751050620746534,12273180035479470373,17586747526841263489],"proof":[[75883856119523484,12593082114158901444,6597561990597188058,2453214043854483606],[14987999437150016389,4447001611062561246,3198154291410587046,2259544665748590173],[5217655719788843551,17239509953346004365,13858100547361089873,1450990371256849484],[2293378189690841698,2020314472580018729,6419297441404168409,2945203370096974168],[8894190956158401475,2762659337879337981,14842644786757980130,152643153709961556],[3540015870230002091,9559721338727746175,15332301383375956051,2782309516709074203],[4743095694255168778,14324511190603200915,10886193452728348783,1538174257793110890],[3030104235242216432,10594843396077250012,15947080307019748231,2193549805921732300],[7817160382485910063,1220013751217467561,9505069066091554657,1536547220185742981],[2229396392163593947,1723875158026080710,4147448721162570704,2417008505322238152],[4642872429447775337,2417648541373296635,5310731098671176732,1335978130614858843],[519174363265327741,17603946692452939811,7817902012424311464,735211675914646550],[10374326063544463999,13619301627134064518,17537478353870779175,1830171422987131595]]},"setup_query":{"leaf_elements":[6486730117611485160,5209749231653045531,13649003542322793023,15159391114493196603,12510780927902282756,8949714754307015108,6455504364064648478,579019099428107235,7564399563333944704,17031975393926603610,6323389328264236470,10038639528385495489,11991486481071900114,7939997714612756448,9124153884266099270,8607615652024527587,2341799487567675021,9346633761540022974,7536266821385858686,10745468764652236360,17280175426640208077,18171902460968473557,15890900746564439696,7699701595963873473,15079448164177003808,6061655006352335531,6016460129462704714,10100012253941560745,7303754892901023891,525801844168714958,14286411189920018801,6067460519052488312,12622587859672381586,7961557046894701149,13285400946030221067,13173261109356223409,11812622975214150840,4331194626958113463,3722681549059764998,14076263263579838669,7682582486998979535,3520859724338333696,4765082458861092726,14562311009334600010,17679094838098581204,4507051210696351647,9985757542957822414,18221629197624595823,2764869293782902767,17234978251576464709,10763723798208699881,18147114035958766093,1540086657688446292,13276379611110088244,10430390343605099612,5889279196347270190,2641398289932313650,18235733519088780453,11316261937896129954,9734059211730719288,17942406421167398090],"proof":[[1632002439770423206,10180571036909739267,13290645909573727944,791465031887583280],[15071520480869561127,3500786488624564715,17479871707302826433,3434913783036351352],[365756654430348890,12071449698054582968,2685670206394835533,1153155530713303367],[9346000823188635334,8586447157215307259,14807539743941229017,2507235944551469425],[14785834767341564852,12525926785786561319,1736896776184992490,243032171196048572],[12826929290018025318,4395435405865211586,14742208396075391296,924852762928368161],[5110596655589697201,15475713219464016932,2066939109513558173,661072438612375507],[3642391079750522878,2705716173434455687,774694482561543120,2868684941985713081],[10438143222845874034,5921815875338294036,11963762284564070990,2845357315015131635],[980257522714833611,15924069168176486615,3841729557039544315,2324611782429118675],[11814081956833418779,7096355811716236862,5815602076527851638,631123736172657743],[16629758827854654108,17682571778901772101,17941965808918577150,915619972758397393],[9605218321895730305,11490338743997647430,12823317278098842748,3415966057955770875]]},"fri_queries":[{"leaf_elements":[2071463506386682215,17488008895798510641,5310097325601282247,7916875755324516966,14623328266330606694,17683068451690849461,8615430338792006509,9161524716144498845,17252479674671940294,5040747481217755454,4401007837345643131,2495275470265233,14225487283538426367,7164575612346793573,13223952680366834954,9084349305626596857],"proof":[[66686872131588147,9090762000550935312,16991839139457869848,2541789923048534339],[10778772761981884165,1349871034595345429,18311103318457520508,1781124120079423931],[14368694217282840063,6479971105075814225,12706747062588799480,1194988761556000097],[14733818491180510583,15066070604905937409,6188145800451927005,2565957922231864991],[8273687034267684468,2637073237306905819,7152933216542587695,1087463239176347991],[2910846906052754915,8083533480415551910,11649333494488028628,1513039064432274447],[13415692629901076492,8577616453043143949,9048336142185042189,1790918626404120807],[12822880563444392943,8928188531713254563,10808718581413111051,3400582133303270446],[9967701348593166582,495924263350042035,3462628003174902198,166316931801075501],[3942694800911061276,17921159622511465582,580068548089853162,1541139455362402679]]},{"leaf_elements":[2857272154631741886,14743123542359265782,13314017435105058321,7748754919447435346,10019201833677441310,5688176241562501435,10426770556386333441,2173479098131691367,10887845495145396258,18368394668135803843,893389983101835020,7028946764234342891,9089811016019667753,459301820246590490,2060602376968912644,7781824238065606256],"proof":[[10002428472215174151,18400017171384940756,8311803233088297717,723610117592992140],[17261124839663676252,18013028996214630730,2503600958834781202,1597395304914972278],[12899060076629031821,7811470824192415684,8860848390029301469,3368569230775498424],[1731845384760144440,7180986322972544628,15826643773445701893,2270038857329432127],[5720604610689012225,7185148655877201843,9289879939475094609,2938787019894021832],[13695243512197703922,4457698671362304058,11046797326166973550,959503591023363226],[356327678543436235,7521747318871730224,5926762661201943363,2802249010558468471]]},{"leaf_elements":[8424899667221534324,6612756415552191136,6612796931283468376,8597016386047461390,11326844825772800350,8192832428246823869,11106453837140316791,1117948685924218467,13750917578457324240,10061966538649067179,16862294871236636093,17729303802207113239,32335188817837376,5680295553451216637,3422205144263220565,3383972669635048930],"proof":[[13553095190192181027,10727398224364960259,9175819148353165043,2547522677278321611],[12951644801913901490,2959430091162009480,10551374789189466428,875497288094680238],[6039877870596496556,1355185342888665747,3773928709771887072,296080807882380385],[7237173891938663337,8631390836781068402,10195641615156176892,531832987875452158]]},{"leaf_elements":[10795004986083287740,14360811068350965792,18254495574033950592,18333342172134336119,14842711178151700778,13998845893516253700,10325734391175010216,728330817682000593,14833964987039866727,11273087605295804328,17484234131895900348,14761196949777933922,2093000788320605630,108068430464939824,5682827616043446557,13244346337575742118],"proof":[[16205375200041717684,5114539439251029462,9508763204275366509,637819813805455874]]},{"leaf_elements":[16580212810250977730,4470259858681618858,8395368088134860335,16307579962635236903],"proof":[]}]},{"witness_query":{"leaf_elements":[17605809114421731833,10658546691552597355,13656626287559466565,3953830549984924800,13953819023051867855,4387218660890128917,8358793968849769515,16975244832414710065,12840688226503727187,14436944545562459422,13799345720419591515,13858698828277876539,17992501317962785701,1768934871347875734,13859466390318440930,4586611731156393494,12110727071811113740,17635662993504269724,12861457794030191183,13468661187730810453,8492054548412630122,7011165894337281053,6596997413522146510,2227655830024039880,6839104907912599069,18262659238575738938,8623788827858857483,4575403814646411965,17780443593568669570,671198712122360227,17770663962779868844,11794779499242187519,12130961199168905414,13167979851945066539,7688849438401005330,16934184487408401972,16492835610420677235,10613206371057398164,6503625041644053834,9792713627644354124,15109410499352599782,10782958811390849208,3010822910248775373,9849725565306094062,5197640242108846060,9376582587236116682,5532314110323537359,11183094702428307470,12752080905916647999,13323106519324431655,11593516680803761379,16527495836538671416,4094304953047447763,8678099578739486207,1769427829016433002,6287577702207361271,6063281130111677734,2862509691976030561,11467058383508272071,9277413335651116536,8744855625273472608,7708050161964060967,13158094667203063094,16107484108507667107,11307327218605334793,16837042178794894587,4947884112213757431,1454889080485414701,10968347130955428548,16852799517936496946,16444494470729734504,14290692126121830136,8150582345829049890,1399158009170172550,14876221389046809016,3115643086949530991,9697657257504673156,4542861182939023438,10654113416499311085,1586132234694866193,18030788893459337030,5485161751920222560,15532487366262735021,17629642559324902816,17374371765978508817,18051518164294118004,5927677595267164047,8437042368849396154,12361117139770083606,3071403873385414984,18070214135906693603,11365727902875839776,8321299819975025716,5370443834854712786,1801396468903323074,10598500145807043639,9270407327535041902,17287030447066328234,13832702672597643585,8315074128454805349,16661324752444515836,3970969613737106622,3809792606354740267,16348755866178404174,1769757981006016182,2395372880239104198,2194984846834180368,8243081187232774152,5900191832346647115,1261521715556389929,9003331112232345235,9002598074369319771,5287707479573540879,1876973895149439960,3990474616653449981,10809534305078268555,16201214172759116472,17107296305440325802,16490180119223580809,16415580451067785906,16750404337522450513,10218114759352875418,17050859669956747467,13263071582385926370,4064196900620266798,174573754828544660,1024433843824935494,13047959056917866689,7994516926635554643,2187452627834592673,14407827147251931062],"proof":[[9078314697975022562,9098901910305926774,16275978444288032504,274989436114260701],[11249874700537221822,13801396524782738496,17352215934472603861,2821844291408356429],[13352364272011608671,11357451007260795983,8981596073504687310,1581242074620860310],[12706669123095089,13162398519732849924,5564309125572187136,1379600085958336050],[6417808938651468720,8992199984850248935,10996233347521781009,1778755417148858166],[11811139455832068351,4445894624612048537,7500077269535084365,373984355413339590],[4662133234977522962,13635902938280395200,18440562315474524247,3448430147155556352],[9967813899400508050,265217299073687819,2119760577160009618,1683396352112395726],[2097688345774291867,1551334356762660159,8676980732097792236,1380356550077930328],[12311588002355993115,14046779706496227818,2514591721280086408,1236085812407252772],[5139450616859371181,2087204078897206196,11056165366781405704,1373790495304623363],[12889308197316909207,2282266747643383222,17495160709644002465,2419368441022065796],[4882341907511761828,17248529125536155909,3175697314877703332,2970579942529858095]]},"stage_2_query":{"leaf_elements":[14430739715548342481,14295364953876423369,13383908731562167414,4021376457938763365,7280317893064294843,7108546502689551277,14415689918119496905,14592231278995471778,5907908262291426144,14731821263598026548,9404731801530369941,11941705618344968765,8656759241910643328,6966348011281311636],"proof":[[7495912549508828129,14733524180597245268,11987355383340777831,2137136614255014954],[8075028576441004046,10408164619714397457,9829122380347774983,146141908060282460],[797005123299356942,11994804597587635699,7183368781360530506,806173439918613210],[16753085696494537344,16165316543327435946,11426904865582560035,279178507487589955],[1804769633466229342,1573608888606020111,15999550575919971645,974737622330637952],[17170172592273192900,12038038528345244274,2864979488765030673,1979355731787055371],[18120938113191513356,4932364082435130015,11871460451535109700,2939088286197845315],[16744841360254723943,5769656662315364922,15636336807664407230,1839315306604795112],[5177743251823448208,4326570970243686590,2492624941525607502,2634314475382688021],[8200862497347994868,12993355160416960209,2313472834601161464,3060061178968894826],[2279343374209367606,2164333708923678881,6016385070657409954,1594124521952387634],[3091719033970318313,13966232134961963679,17352051512255518833,2117206648197379507],[7193705033799763541,9048181582346268552,11152058647750961664,1742650808604916784]]},"quotient_query":{"leaf_elements":[11717999614889612352,6710663481663955427,6369298512351318286,9005297867318841159,17217266035524043859,1555505765335400042,12727968002908424504,6343562850414666,12675638902237175630,16707000323484678044,13478281849849051943,10320982349079097680,1140064261157597301,14333187151742133609,13518715212027509563,16345118226106906575],"proof":[[1673522622269838427,12970601757224914113,15032770239839208693,1742371850895926554],[4671183340483534948,8360294171165015929,6223841836773903668,1637751916481665441],[1054983099440854833,8719559781484191404,6930357831786576521,1686460966433019299],[13535775282484036053,8696935580285833735,10526161654279865748,1797145282256047147],[18215022457257751206,842109970180421055,12777554103825585636,1477627904408447716],[6965628319637665150,2178706704319885499,4115299823955678494,1170552591919068820],[3218275109395321120,3650485915920324678,3766387438261231373,2945642052547398144],[7319682085484880540,167043397619401794,6342802902486262924,2210144679785232500],[7126967494033341404,7910734681262260802,8409603639680244065,935981132460601280],[14959185445280292951,3036589757253135287,243382025611781600,3420901177996722616],[7105253130684250977,3241432610934844898,18396333052216698749,3252856551037188689],[1339914433452434392,45162647631230588,8631130021405866980,365543632767909237],[117417962886288672,14214076626666423966,6745455965795245453,1238354374129802593]]},"setup_query":{"leaf_elements":[13806592382513433309,17014359232589288244,2294455331293768089,13641188102213920408,11459333965920234458,16492729062134138195,2892050653963654103,12826707984526020493,5771084939800199690,1453144797466857447,17667352489062905665,9622072134786395635,16272700103366747883,14505344358655507918,14555362417741230494,2499806779076703038,8790221429619365028,11145634307595658760,4738365155557420953,2603647885267411629,1419978873246018876,4782516616394177526,15038959928094472318,3657890030390435268,13002408538509415534,503103934990690271,15348407155100698101,8610741402755092322,9144867498773284438,2853586662006165991,15291342823874671583,5856815255689917386,10794477121454832477,7348696326207771148,5322339892291369835,13595645147023422412,15395755235043394421,13127461100239628252,8032183678014896713,10032075623407431751,1427021943756203049,17671261771496423997,583947600721504693,8226004828168937456,11436625142153606202,16084737868666055364,3819806147631901050,14797525099299765141,4132986053036774357,22312325106518851,7856863763216593737,6091504133169376937,4112797042296888665,2082743184016832922,6770325206482985284,6346138389363604513,15590639913008161269,18211640448948684709,2128393900035589772,6091669393898576722,15202760537485850753],"proof":[[3002907870901220,417390139536052163,14797128980443620770,770976699696311463],[5175177459462199886,6769643913429205562,3866072970190365825,831009524654759403],[8061844020870255915,7044744676204329173,2448766975466176918,2029119345697896943],[2375531020744427089,8269277120654655391,8538697253598924129,1579201626282693980],[1058947531228255021,13502104779440662920,10301078704183360270,664754837139090110],[4899603562823662909,602483818205431903,12924497671876388686,2699113340575054589],[16990312294546780178,778222941016554731,17036887996952097263,705683733119794285],[439438727141975402,15940450817259164016,5985309408465010508,1952135629598501856],[6499532775735121977,918266073547725644,17235679573324865457,1385310496445096345],[17732518911236868111,8695815302346154982,5974038600269524308,1976622497695164700],[10171103296261072729,8004780863982512820,8226463489668754977,972255685900117889],[10336914720975372098,9618323270753389619,11106414814916715037,1399209016732401409],[2812288052570429747,11192114483378251971,10192533965505786912,2372986316534941658]]},"fri_queries":[{"leaf_elements":[10906908043036631944,13832680615250526581,11559078051263532286,8898402442791631229,8958030243207267811,14798334033293894366,12784083012712752001,2790866510236717317,15912125522578983257,7115140346860084389,10087842466278683564,13374842629660240814,9448292995921673701,3172595298311373676,709638455578477234,10438156065226873333],"proof":[[514595019331859107,3805249560099683316,16673398358662117827,1771484359283435480],[13351366678594219032,1070683893081881898,11942192261313368548,2865999489120888905],[14463598526357539431,11895276980259220352,13804093046941875603,487277178471638953],[13941702955462022486,12118247817631989940,16398767733176544653,2596695144447207452],[1270090257606092025,12015768439548632671,13530901279833131329,1263395064705998924],[4171172370961205212,2745649269923538315,5507954323922123986,2546845001221494443],[2652072232526668400,4696623662717062601,13290992267644511505,165375287401223851],[8027587598170013989,11627758616813150524,11434861074461238380,3471640561763885200],[17970507027788699634,7518146182630518600,12979247614906369857,2264518446436324027],[8616858090914454618,1663075563175866095,3467139390527938134,649361097648535523]]},{"leaf_elements":[7814465261899793890,4563248719373135387,15731542184258903415,10899545513446294272,5406985610261228272,9416432294167410615,2735177041035638668,367678197572734888,4074076980221508720,79151403378584849,9012898396866868341,3209760985997627869,4478326419224090861,1897392246638634249,18415246292078184712,7071889123005461384],"proof":[[12618312159312005042,6920130729970114015,11428459262180890110,1823029059063422229],[15027148448132599366,9333717857039799999,10893643007962355944,2213603187146284068],[7306411376545519681,2771852738032742319,8616306018600029663,121022245389855274],[10842347474234112954,1487931343508683399,8658878230999581826,1101982334789710067],[17328231401873326271,9509134007184042166,12278013693113723126,2947568277108179231],[2849322931733077405,17483247710221335294,7437202443465797114,567741684499503304],[2715489747108002065,5305903886920463068,7746148398384784045,2253146750247811367]]},{"leaf_elements":[10682835866252674269,17732497210026013683,14147770432803943938,7556788595847416526,9651970381629460715,11833207707939918843,497472898628115520,3783884591111853278,2589323885119358159,2337537984966558221,3523144764515381321,2730371061800342335,13539390225062420423,2663473649224595668,1446386267321792942,14547891104639267901],"proof":[[7441646281671916802,15711098165727754760,8653371128226417599,1082296250745376691],[17606548035232485189,15805182197147240084,285703851201593202,2034015027158211150],[2879799443635186680,4974241474058338423,5656028455063025637,2671083806016974131],[14590848441063452794,16273615971920084576,17011998151899724188,463497794276927016]]},{"leaf_elements":[6278203763991616066,8078050046665436218,10081382088507432339,2222463645849995902,2969879425453338659,7276527334025712803,5195638262421124803,1423548983605012455,399448597950965084,10609950177358245602,3937540680217941419,2177255647077924033,8319833819507901832,10608342303844245766,7261168177199598481,4461036407361939175],"proof":[[16347249376249566426,14583720912265793793,4350686724955233422,1407886625625018208]]},{"leaf_elements":[2966080012095824694,10472639831135879261,4652833482319589241,5368590808610327190],"proof":[]}]},{"witness_query":{"leaf_elements":[6555385525264050021,17105615314263141733,14415937687261688095,1840212054008767744,3725981131550390353,8647373583853526418,5572748272231480247,4333632904082115750,2311917341039377075,4359894409592528402,3647681372297070251,4927529584717050321,13239674033452402060,1996569307757814591,14191427227457273502,8430037784833173819,16985179130119593400,14039747157499301093,17187434147834297014,16550511421246332554,5208647127565737186,6126035319976390388,16666394198184380329,11638285170221959830,14163119079645024051,10526922358701663323,3742391221734531198,118694279825540165,14004070697985212954,1169660748503337444,16483454298441934854,17441040611561140817,10076037589745404680,6156423878067245306,16570429288204918236,3219003802087437679,4575531060746302087,8337073957582950081,11044098391989078834,13497052807798100227,10113907331195494499,9250759276755129796,3167768801807240787,3822991823350759273,548929162126330992,4978756541944961639,14248341532490173402,9970022058733222201,7188600232696917468,14933513783284688455,12245724990742964576,1623501270111127846,14723657369052355961,4328825712651759302,11412886516578306707,7857691332949354479,10913624552622304390,1260138173508648270,11215933371224027769,12087083232443949191,3246441758057331207,14035830758432127918,16340349051633105727,14206264255847674684,1309342078303397750,13074547292545471729,13865728557669130207,6383607216808966737,15695313964230759633,1022112205250548918,8412747540780515056,5321064037517007095,7443944128754134536,1029169588819364894,8960133043307092653,18295804738439546056,8178447566776976603,14116295757404542281,2898072021212597472,18430683001267152304,18052457256128902103,7066764150801987498,317811026667298925,6175883698229047269,6365215705838314337,9838777380850020204,18441372143962815410,9831085602189913741,3222904311456251250,14009605621942739947,4517273693866094716,13965356294231854191,17414164550342105654,4482713050429006189,2067815373878353377,2856569367689550829,17879150075710148109,16973029630312662908,8021162030409390214,9080103233994472367,2522641334648988405,14723150484078397305,6662234661389298553,11358979115310554134,13302222568235577276,14379634254935778663,1483482280840022203,11632939875868447921,3014211190149764851,9973831199110467370,2827914703852806677,16407977597361907945,13880153611018810838,11149412479001901620,4328893377445434725,6167736666755464218,246481253604793615,10886506079433339912,14943487052962605779,10863864458571697996,8168429117750508994,4526553231362724284,2715130205817921288,3250750819778029553,13883159353461705621,17781189194532738693,18318142680290401766,14401441724284044609,11626826323331627903,16663746466082701623,4955195043295450901],"proof":[[16713195945249203948,161452049869389831,15617426727351154748,2550470761896213361],[14611183633320485024,2206308790883484660,6216257423573218061,3236295754405905510],[17866973595876599193,14803934900238549133,11519992440088722458,53945562147318839],[2594442761264392268,11692262698217965868,4472360486548710320,522561818281374032],[7895060073403037032,12200349921319718645,5650779956863966845,2214480733329747100],[4649404071279579339,3413930583155147340,801169206295970773,2759742033477360711],[13594188904351187642,11677311747838537623,11201247465933119650,1122523125618434152],[11073487757891686485,13992957167560109654,4455921139172168864,309760666353782605],[5917738820991141905,4101923527724065565,17354110818614526428,69318809203172942],[13245347524737417258,2318207854407445113,16986488710682533644,3309449997624821254],[11432283659985769519,14388550926813684844,1608158383785800185,284676376548000731],[7551781662711293182,14332883861788060529,5854916174821757009,1180253320097834079],[6319403942848876859,549033099055625544,9838606079043705509,1442728268342064409]]},"stage_2_query":{"leaf_elements":[13935181415141061134,15089905820873394311,12745288946047478918,9948760285935593015,16250465347811612564,3197743565757880392,7922725133532811306,17231741309087533293,11289159695723065714,12778381203559192184,17264793533403759884,14264909726152826047,5173171433202323218,5398617649261402039],"proof":[[6157518402754492075,11898664864151976482,15206951071762232442,617607900709763586],[9562360230688445719,16665737774172462324,3014007950375697324,1652100566289427261],[8309399772898675321,3625657890238689571,8476956227969149532,1680746330606491658],[11317617417271813693,12897536401849856083,13211598148859466905,3314976229900136549],[11427874528584745629,12319134658645833859,9183127730865346436,2895698003705128481],[17415084099119758080,10776246404492192439,14931104549405692357,687645410414854219],[5501483481074596235,1995097062245763517,12656780944352127993,3468957685993204136],[13569434564481437304,4516452172566442255,15951484096398772797,2537742930847411788],[7114317960137428020,12135711669607155721,15033088621356431375,1817178335111906111],[2299784782873289057,5147273652072114973,13130374836678824315,11292614119616324],[12646582496146945603,8325812408298575004,1422645035632642136,324868366660455380],[6221897171993216899,5015940854970352631,7130320216356552427,1830735253647230345],[8559229694106243581,6083801497235235894,12366925889308928834,1093878940771847338]]},"quotient_query":{"leaf_elements":[10586751013002330248,8258278786195706755,742914268516078758,2177152007814134179,4003324156238529330,17794054954558770528,9136343169528518943,5094030960216848106,14904869938790256640,12044147474754728848,1209376155130240089,9872940074745609734,5083643865992110225,15830472958467826254,89543072051410901,1498873959760456061],"proof":[[14754871579238725651,7678105021075849924,12228305424319352308,1157574431332627064],[15122264023015046343,5105836090855766954,8472554894477260050,1285770696146952772],[4699458555932705852,17786634245955846507,16127566759445348523,268726857645034965],[4619670942420368698,14012042148689896300,6415937747776058918,1570004054313955644],[3706292282404072687,4547369689045686068,17423399795100601235,880182759493704476],[16814461992123416799,3921708987782041221,12701543969434181639,3250371904234922091],[7610620978227078821,16060691497486519789,2721437135454269219,1323829048112228693],[14243394832569950708,15634336592861189500,2692730908869484780,2015496205174590828],[9128922645184568677,11793673236739347874,6805626941011504718,3059283494033265096],[11706535233069418657,4120847561811158293,16878178140899977080,3107420277854687833],[8672123240052048088,4443353146465696788,12580392470658925822,2562127010262566621],[1006482219181302306,18103354286349078680,10357206732421543392,1184898023058336042],[6742689458430904017,12365859125775949332,17589705338515253507,41352540069468767]]},"setup_query":{"leaf_elements":[13391782601835959698,3841041908621096113,9730147035364141905,15612130477572808022,6219638897882253463,12201431705139904137,6753227336323624830,3288956005840792590,17393830451089118628,123012454219363837,8511965859185730640,10602423861141308808,3791337733016659682,8072353819765084430,278874672507620626,4094291974802628747,5036758464651862605,4845003305368569172,12062678409161478987,3342209586903665231,10224798854854030769,7733896270787497889,5721891227289286390,14806840417273660432,18088666821062909288,3412942207667439170,10438993400118278991,11629954245154704498,15804139851563988776,979052281098627701,15720439501654841287,2492806402251076570,11571255029805626675,13117400569359021712,13811540149966513030,13191722616516557388,16301547596511193202,9249743830094788397,12552036661716788849,5717435868098669636,4011332008169523969,9316213101195750606,6704663223816589184,14794193390041610621,16047443945422967302,6079083435652901554,862894441610868546,3398387181559883874,11192882603271471777,14277800928170332545,9858204768276269179,16684404465269172904,1578225235898138319,14681873781330288902,5926575642938980658,6916741707319544618,8706857833497867786,10660007763627506877,676238570075588471,10253019171751514678,3468607279434927533],"proof":[[6880531858596817979,7492389112770872361,14400221147476057171,1840310101891462633],[5549511266241700224,11613189603360352693,11184806257125258928,1350609118723359496],[4285166981806392640,10831910680368470881,1308676430362091723,1747470888435560400],[11658797554457709123,1933213385069629346,2157422481021498956,2780878946918497238],[9375547580315918599,10911842806529912834,4643289489062118769,1501396088868380250],[5506798372343935718,9979759819465109355,3009082358450122651,294565345216877989],[11063713028164355304,2796029702982226097,10183625903118808289,2834047112561872942],[18140615753808099812,17833399792085969633,2502546930939366615,1455388040566018186],[13230773132133369729,9847985827817512805,17742604482211293774,2279430797160123720],[3409777220836122989,294902725272039169,11562942377235379974,2404922618615884212],[16538951258400721934,17471398493350159549,15246487556608002010,1495316794456283210],[18273441020957215580,5310347066230532130,12853466621058370464,2796547916926690774],[4116420957544392334,981127288402861837,6702203925816007197,564656793942279335]]},"fri_queries":[{"leaf_elements":[5964971434165467043,1512532040784313065,669450722511318494,1414143880021357314,3514933371019296349,14801237265674521142,5937558249492973472,4599444339817337294,2271214014494305645,12987966555001305461,13390916402414575932,717769765314170689,13479131842695584895,9601461046107971981,12616123609142052136,7566494944759860579],"proof":[[4836252303389394731,16815087716063575576,15993263602219007969,1666855025535900785],[9853286339099945784,3114123015572063684,1454902316252015691,267063744623447287],[13191432798142895618,5755778607847798161,2733885824802526823,2098116451244502315],[1868834135185913608,1557060005862332095,8242142154863189299,1901866919591488118],[3982319961987319264,18399198019027893916,5322606592679269945,2296238295865455714],[676710917331893892,14943714864529769962,15492152756466975829,610119554405717647],[8618335763915567968,8883061498915700397,18321309157393400254,3050620840169337288],[6481597279115214364,6976410916853372392,395890284198031633,3360855170595700035],[6410108083965119228,5670695521396022464,8728923467010294359,2857961213027846142],[10701620580987285083,14029228686717680906,17606917425319476032,2505274531328869815]]},{"leaf_elements":[9636941902364412305,2052098568164135615,12463954175156608392,3297688504721653187,9965127207970713545,11402562220473832211,16654584275154357554,4113220980633730836,16162263318931525725,17686130457593907538,17326551619065663785,15079111250752727034,10197046039472377485,8180048300092084506,12855937323098906553,14599804320808670855],"proof":[[16899542279610916154,17237142162347435783,6061058601066449286,321744714051502051],[16427178820978739650,9328433331301840618,13191827738655241773,3080702551604545893],[10597494874878287729,4266249230129966602,14852714910919308151,1938489325007455626],[4869633817271567256,15487475601649221020,4722537794127713310,3212467330079453764],[6994975584673612106,10742376796409482693,7332695112669689784,1816425617286594831],[9805718263872530570,14143077419582883586,14318923842988812352,2311737774111977178],[10796312805924833779,10052204889508537523,17029417120171154458,2380688193371945324]]},{"leaf_elements":[760340993264689891,3272205859085774116,3155076320157576757,14571259853522432923,6925451141450230559,5737724787514979034,1625194676628936571,15309314608608266472,17245534346898047165,14136481595159259003,2165269278861135627,3105777634748625873,13616132648794936057,2420767980182835305,8169508359545032029,9526819383763496121],"proof":[[14731202161995375258,10242494434190312567,3048756093650892786,531799399258897551],[8457388088084640313,6779591129619376807,9094494561639129642,551983836822541437],[989000846145887814,15051402191572006114,604360734627324609,2633584895164485977],[139744036230662203,17798083038650091172,6031175594198885029,2124951385919977084]]},{"leaf_elements":[10414973603641774256,403394223439685500,10536595545238386023,14417065532054984200,12384715249560097018,3156902985129211271,9484383719828687856,15924333456246663000,7155148099983750153,2808246294803892123,1669609172955553579,1751249439668137723,2177940236717868821,5260503247396225335,17657695492767045645,12121937833396643927],"proof":[[8669456116196418953,8307641683636278137,14371410889281616166,2389164284214036631]]},{"leaf_elements":[18196018707140134098,3942247739030689718,1556687182756891542,8508669979898744338],"proof":[]}]},{"witness_query":{"leaf_elements":[12585913562589998845,6463548449492641643,15668750412976206887,706543086744788954,15612106666163741159,8015657795677450559,11238207732785264324,14184844778647037452,3213487198068786222,2485592439609978331,4309390248119342482,13335050087235769839,2195289551597235406,10694643167375552535,6902734279714536232,17961623719827372992,15402309122077782943,16592056963352820082,17600186546827984151,12165768640834158051,8262738305534873172,3444890077471762020,3294350753523450016,13328679968912578392,7773346198888369441,10392624341768070325,18284510762332186459,2714931747241697787,13425855742232707981,95373734744940915,17526395794052045642,13387566234122929528,14283925201278324991,5610782914431267194,3077988572704296047,13390015552587020291,13161437885097834624,5544275732619865590,13234263048207849571,16295180216277499440,17894934323935947275,10483146987129706443,7091770722858777750,8312601546809235770,3541009028630414968,5635334391255806778,10473851774055453183,4397307112666253859,14885911125164275243,11641004950403299328,4213589365615421652,14565667664944914029,2107872288374507507,16696189368422518522,1953853513852822563,701005490529757112,12640814504533033549,12380502972442362869,4135581572023057122,7134848594823195526,6810784797939822375,13358206254330642890,13045554916405811757,10332347516894403081,12127036303673293833,3583683575675937716,14863746968915294662,14596712965510550660,15872420213814273507,7931715027466574833,716515834243505418,11269848434452565101,9468976369657223696,5359693756184148947,2364318290001405662,17812223792306479410,17832327870984060261,1173237807530582534,451886719172792316,15920065512914222548,7343111630366262702,2851350866348120,17420530798245098476,4373345082083868159,4734604137912266682,4478830701389826891,3897781226872204272,11625799070526148,9479388748150041129,17405996718750107587,1204009373506795859,10240097113414069428,18251787648198299930,9049064130381124237,9457837430328068162,10296441190043789466,12159641145614863863,17017493176842666915,14897766426115266437,14603337252446467546,8937488418247385746,7393661953520396463,2837565462710517005,11392372860919206165,17879224071602588351,2714646102202470351,17730061704595894512,12528337780625677818,17213306952016752969,10040085721733441115,5274411394985975828,16685785088369262686,15513234662851185134,10027963802058902876,13003701491183733073,18292067221560485897,18254992728092950013,11729304005892072510,16331627434329091458,5587244822372108897,3201132268778038074,1919947440648346629,14111004672116215847,13436105878445864710,9676891414532126187,2868257138340839371,6586053875903303483,3690751166962576965,8160994230280263968,17105993877003884556,11924207463196712129],"proof":[[17465077601752138868,14286543533011758723,320464303288076595,1882039229886233365],[11709705669723556630,3459738364876745441,6545784852968688673,2850346675864094390],[16544875812161331207,7825992693032691216,18298896041164710825,826853846583232023],[5488929836944392923,5061764426817006121,17473902965742347523,952986321393836128],[15107274755904564904,13644546759340343051,9854604442340302234,3038737511226366172],[1886244432250439071,4212759787054925996,12723603143722862509,2766250180251111940],[4724319524471055414,111732527197908416,5223557258240385865,3269683383579562888],[17037201524428477992,15283435638783790113,173338870629617806,2168434166746184822],[14309438021148814601,10294785265869509488,17955065952552632788,1661380805432369533],[7651445082213597533,9553470395621017260,5109111873210239511,229806987475662],[5139450616859371181,2087204078897206196,11056165366781405704,1373790495304623363],[12889308197316909207,2282266747643383222,17495160709644002465,2419368441022065796],[4882341907511761828,17248529125536155909,3175697314877703332,2970579942529858095]]},"stage_2_query":{"leaf_elements":[15529901612211816950,8422468760352809690,5654821722581450766,4501389095001113708,5585449211260445489,11700343718586595483,16652740646138165288,6328572480737922316,8465108025335246164,3854023559711472724,13454232845413040071,17911408052655256622,4521178609466985910,17773321910082281792],"proof":[[204184140232056251,4381532002240047250,3973658225226056760,45351559559055656],[9613958139849492314,9080704480333706129,13173338951726086237,2517185114955109675],[6091269415804765338,11920807528691233807,12347494068582439266,534068906358152457],[2838803697269578615,4991436402329032951,4304362065629621398,3473910309495306253],[17086981302454728273,2045345466151320710,10210303438994869759,364680428039018160],[5469283207541240805,790160724647892365,10440238314610119336,1608390452348370729],[14080214543349024092,14575372225030994404,18403136409255370814,2739770985962000255],[18066531466696207133,2874034365841222682,10627815245012754676,2607349365750516276],[5090217706551097172,12460916553090400733,2383122355387969854,1765183529782796027],[9748721604977324592,8442260739507940350,11351118531222719495,2113612794742443602],[2279343374209367606,2164333708923678881,6016385070657409954,1594124521952387634],[3091719033970318313,13966232134961963679,17352051512255518833,2117206648197379507],[7193705033799763541,9048181582346268552,11152058647750961664,1742650808604916784]]},"quotient_query":{"leaf_elements":[1387162072975807326,6193284661204222953,11083819655512441717,7037896279010849789,8733740119487947556,2363518264381976632,7923999615694034650,2065429963383420850,3889805768810782589,8900014257171421315,3663996434407567668,8049407961074094096,9271746317004285418,15310938196309241137,17951977893698784327,17052386424395770875],"proof":[[6466764692124437064,13565096390035135797,3964726643983410382,115899186299137448],[1121949069127917666,17811546803673136557,11354067603165515888,3245059450856653160],[5260388750214678909,14682309253551401548,1267732992273494794,3013451859070746331],[14665810731513156161,2246750981620606031,10452040517451279866,1028159919315992295],[2147732278326424942,13871159964419553803,12554049185165501430,2168381051046834393],[3412059098436766508,16077645914892504475,4950273403893594308,2704025167773240477],[15515614374480898309,14968992467468684747,1399600225970756602,874562925632776325],[4416114147951235702,14838423070501480100,6534491653094926138,1519308287298886417],[14760190656857276194,3627079943434700008,11656032249010445369,1312788260291467582],[5235974788609322045,14087831825139807116,15311943734535995707,2770010158949289522],[7105253130684250977,3241432610934844898,18396333052216698749,3252856551037188689],[1339914433452434392,45162647631230588,8631130021405866980,365543632767909237],[117417962886288672,14214076626666423966,6745455965795245453,1238354374129802593]]},"setup_query":{"leaf_elements":[5202536316123024030,5503432310399564889,7590186436416435742,11450621143223712313,961154517093866066,4383323461572847511,8204274486933827401,4362120388579532946,17378269256384496340,13346955754565378501,12923402955671555557,2533168259477508390,11984756907444477354,4422710390056404122,2540649247886661961,126562353997775726,3551488420909437843,14100773629519792034,10863701052424348303,11948516762448570918,13907282977724655486,15017477991128194845,7931493196600092668,15380199894455393325,6289231572508006809,15429859260881771931,5065441922141222728,17118157959901323726,12129455797250976959,12931179812561799993,7817660734684613035,11723152777683564478,16491145487461465102,9393698183742285101,13142456007579316804,11909391239670550809,1337317892418251794,3517347825746232844,4090312244367104429,4607607674514239332,14961658807628287226,1648527861107784719,1421116839558576675,15710458210883813387,13854527305205387465,10127530609667482385,848830984271557605,17617526591790060493,11553607504670496012,3787106367709069232,4009737719161733703,4419340399625984559,14996767239602803350,14047376850870519876,1052730424574215356,3496543136945228294,14622099178628130511,4533174104563414153,6833091598983383938,5126696730332244216,16048830633137025735],"proof":[[2252590839091412144,2877102577901213509,4954597166729952869,433766877099046868],[15263716302562505366,11171611938226737197,3704612576465160380,1252573596289325751],[1164193350717784682,7808479198024948942,2432611502119188469,1611777022786530009],[17768827676141552388,17585778933950352917,2277525174099050732,2350861531639383500],[7823674080626733629,8472055443911459919,14992935513303362349,1904762600496243961],[8913399478574860875,3103722984319435662,5574343274764035123,1954673402979474968],[6087932311121548838,6540788482970339963,3119628744667513568,3020124296924505452],[17871508609194082033,6185578325526168102,15274816695451833540,3202104917945432717],[17593584234042845012,16431717641559751746,3657466060442961817,541519433143038166],[6427944541346737781,11850903295560773947,15442560863828195751,2022083000528176971],[10171103296261072729,8004780863982512820,8226463489668754977,972255685900117889],[10336914720975372098,9618323270753389619,11106414814916715037,1399209016732401409],[2812288052570429747,11192114483378251971,10192533965505786912,2372986316534941658]]},"fri_queries":[{"leaf_elements":[3406550113440878865,10834199005472537364,5989460962092036814,9674079075298540685,10775973499385306123,935514533865059579,12657813914712643618,12360348352889396074,13647578928775644733,8733367513545684970,128724391207483483,4795713343825940934,7299492689154242598,13707227227764472974,11585373693869343490,13689703966065986253],"proof":[[2675199880270114143,367488880117856368,11018772333840540082,2506116559496833213],[16327401837165725927,16265450483225513130,9856598562134327574,2091437094608397467],[15147088553068650706,9364326236495047133,17504841356452701327,1526377865778883331],[2663744844896330967,18426953221920272499,13962842972677846062,3057940948955451063],[13960597087129399307,2742413874328966525,14014472433590568700,818462817269083817],[13660720150344110738,8714834213666151266,11286857090979776975,3104117373629023326],[10145140688678011266,14375729019606233344,8098873207033452686,905872187123606030],[8027587598170013989,11627758616813150524,11434861074461238380,3471640561763885200],[17970507027788699634,7518146182630518600,12979247614906369857,2264518446436324027],[8616858090914454618,1663075563175866095,3467139390527938134,649361097648535523]]},{"leaf_elements":[709176145607890217,8031302124708633042,7402839599027833606,4865055333598849005,13244233448914351247,13321607150000049065,2651378874326432743,5343302850261581923,15763139766287883540,12337589355193190594,6850827772019786073,16685577779659204188,4796116280560660865,6656910709250349725,18416416856388925981,13727748798209415402],"proof":[[16189718842580691855,15531801813570183559,289405530253266655,576180048262125803],[18047515968259002847,9281879689877095284,4969198497906788316,439502299283953467],[9220932145306610368,4333144843807241234,12399871747620814265,2062830250169549150],[4576495701420489331,10830447008132951230,11990923709411365473,2642941914940938465],[17328231401873326271,9509134007184042166,12278013693113723126,2947568277108179231],[2849322931733077405,17483247710221335294,7437202443465797114,567741684499503304],[2715489747108002065,5305903886920463068,7746148398384784045,2253146750247811367]]},{"leaf_elements":[13896883706562634719,2933726015254331259,1615974454349873272,14015534748592643515,3891849642314202825,17417471154607537630,5373530991591536441,12078404734984428056,12588877507545296955,16828013043534499340,8663788128427695119,6583321707308322330,5490174422653847173,15749761958447762373,7473499716399862295,2016287304298384211],"proof":[[17111068438287183411,8845947713968112385,5656307296986973856,1492419519043002258],[17606548035232485189,15805182197147240084,285703851201593202,2034015027158211150],[2879799443635186680,4974241474058338423,5656028455063025637,2671083806016974131],[14590848441063452794,16273615971920084576,17011998151899724188,463497794276927016]]},{"leaf_elements":[6278203763991616066,8078050046665436218,10081382088507432339,2222463645849995902,2969879425453338659,7276527334025712803,5195638262421124803,1423548983605012455,399448597950965084,10609950177358245602,3937540680217941419,2177255647077924033,8319833819507901832,10608342303844245766,7261168177199598481,4461036407361939175],"proof":[[16347249376249566426,14583720912265793793,4350686724955233422,1407886625625018208]]},{"leaf_elements":[2966080012095824694,10472639831135879261,4652833482319589241,5368590808610327190],"proof":[]}]},{"witness_query":{"leaf_elements":[13736675821992063022,2260342515735910835,14414575235193834999,8247748154296935347,4604256127025244127,6493792264048129950,14401638783429193926,3506592484988112359,11378827460327826291,42301735886460359,8797211627068024739,7800340134078963345,5631408586112953992,6940649003697515384,5862295837349346080,2855823062611613833,14432561748398949374,6982974320866637573,6714733814410499833,5278460020524473460,18023875472650573619,11094782330537130404,1576891378707033226,15289710039063923310,14111677350976276022,6472619654816964349,7845364533416281738,7645054033170878310,15903171526100983492,3762734881561501432,2866679005937051565,14567052020140895976,9798257818640625059,1521876624410176921,8763229661565108795,2474185692933802678,6169794297152389133,11511924468584235880,12807484888375680714,6716008018820218361,9691627988024417171,8612730272055893480,13815267289133025970,4095699728750200272,1759761884669083882,12954912582508615472,8976496567292113760,4550608022123649894,5594474045796442936,6505952309063222686,1937994739079019054,13936984125129075357,17541362094978392199,13541961570504899494,12748791702646107114,5132063833646406385,7240305585422819749,6533208239080422364,6476030428856508606,7333978005166362549,9540006626211736601,15460542993645676989,11776681446744106799,9075126439154909379,10827667415588075006,12485253502156704515,1271760383679876056,18005722871378881867,2383720785729316602,16978289587156950549,17501179493314847628,13359271096760401588,10637702331892128656,6207356768618444498,5979993025698718818,18094884594417475206,1662805577716312127,11330937022982851411,3965188514914083939,884530781713667626,966538249997311506,14964455368348596066,13192462374982738177,3603411410661218510,5382228523483902033,74896961067901028,14819604101873614673,3728110977052077005,4622457370615316663,10178003234153526217,17179394696643717745,8300360034338271618,4781166012589077004,14756349977951728139,13732484686768215316,16120784669481067600,15856980093662606305,6152917557306374766,704878790824542627,5678542825972642185,7493731404103377931,11644982780889827457,9887280771763092284,12862612647257174212,17957931145470401693,13510155691364058420,6672974915351892033,7975322750222154813,13931264613505647811,11073562397937929760,1197088334755015380,16750280545186403855,6406453051275419271,8726369977080445710,9905415999987481740,17938565398137085209,806268532269440087,11004369069130721047,8132256855244701538,9631916962859160846,7362466595296700123,3384674687898441672,15327077295790697884,14213668572689022157,252687155787773237,14324926693008850183,7913144518340946658,15971409658664360944,11099503283454831617,16771503132711398242,10711197060335721889],"proof":[[13898257658613556876,8908925802307885266,14575630305361055825,636227006898391555],[8586154757994496444,5843469848315182757,6050798182749593962,3205696494589547366],[4557994414685687,6836273841905850058,12828466544325592011,1457921832438741794],[4186999260020154402,5242597085223787754,12771784626307880878,2452024304879512816],[7887828407904030197,12801358566284762945,16349147078139686354,2915018889073897914],[5221387058716811335,5253987659825292317,4652741471707365043,349711635504768526],[4338828177670192616,928569022616103016,5657076138417576649,1294335304386431447],[16493216418729599108,5864116827361353951,17341164103114647916,194889109226613152],[18198084281654034951,16357779054501277840,3597970601654398001,43479350022582833],[12251520032188166640,13964881192534298828,1199448246584760847,3426472155082523586],[39698197409192067,18328421271659813501,5373892500258405414,199683966958664387],[15421655209924002952,16368321879835928311,13763176468640007060,1827063992316191969],[6319403942848876859,549033099055625544,9838606079043705509,1442728268342064409]]},"stage_2_query":{"leaf_elements":[11429272111744661642,4099857268297115441,2364686788519224277,8046845912964263187,12622436961737741650,15008594421420397184,5923583236292691086,6064552832143330220,132825422954212446,12154610392263955392,10400531997043120075,3749453581953020199,10685994343509831064,9749345222789433926],"proof":[[15757098588375779189,900131184029093080,4490563323362141496,2476517943310059097],[10029461795784899672,10289277865409231567,18148536224527228116,1444406868128159795],[2049580505060335467,10453738724581716377,16625177389492258879,1857301932568196461],[6592271388639229393,2837053430973646635,9990952533900925119,1258774471242637933],[8380130845700165829,1625512853780682873,7966433447163397304,101639192850554901],[7797625761856211650,497134083033047442,9751311937208184975,1371471043040599820],[9835280590398222008,3181740886661925382,5330659109722971181,1433835214565024092],[7952511946970483003,14692750075241710737,15079825187338614810,1021088744848002597],[1185939834737213826,13184527098206416396,11635105567210116608,3322683249873425316],[10747819576630721630,160446580737553255,13751282753543587131,2265776968462859182],[13182354767411469832,14107148174981907075,15670800624922813846,2934633881830154385],[12021982420473469380,17569332985180571919,9131874529933552696,2059893048644664856],[8559229694106243581,6083801497235235894,12366925889308928834,1093878940771847338]]},"quotient_query":{"leaf_elements":[17197852514890217692,5643033614810698308,12057354406098146978,8913632843306854334,6682232215417780363,6361648767475776471,3417609703300702842,13947348717235653632,6124235359724714125,16189580991373262613,14661267455501966553,16716419897995600385,4903362687812588319,14822827920863742131,13772166378837335126,9313585251784706742],"proof":[[9943288797154149632,13075262464714521129,16310855415398609481,1954023226390161986],[6634067872504133974,15684308087944830922,840903531167055148,937310192537738482],[15478852750797102299,17677140896380211245,14545416355998631170,2880205497821152466],[14746506145470994628,5436758852644416451,10040033202858237512,1218133602630547217],[4815697161882295771,6680374772112471982,16879493233855109504,3413603603883686127],[17339415394433695006,9866086080820458206,4852046221525163645,2270746765593008346],[1851574303962289558,11922567396656263754,282899877194935511,2602085668420308283],[10198275252247963184,8972427500699569853,5689437695253974787,3287616051033960303],[14927900645804959535,14346403443001257816,4686965869398064733,412544221072779209],[530887412218173494,4069129494104531873,10795546427799339403,1778464432087942228],[11642634586355144404,13524183933447549346,18342548649266705956,2154561244508476359],[10864231025343200565,14365906828085033749,14285158680845176124,1852444960593571030],[6742689458430904017,12365859125775949332,17589705338515253507,41352540069468767]]},"setup_query":{"leaf_elements":[13257655338405681560,9610448405229366734,7103360759592823745,17458562960821419255,4443858245740781446,1078269107289425819,10383961486501590701,1218723242091518311,12263367624667880595,15013936046156381259,549755446292046987,12029962623399976263,9781499769608182717,2596125329824381504,3106142519388260779,13372085099933125456,14346319355198698451,14242908307744781705,3224562412977325485,10051770812501467260,1009721601907483711,17070287712371188676,546276542438139771,917234080814482765,11335644338587562058,17907004592116515220,13214522585726736933,15836175597577256800,1752293277651443260,7922962960629686886,10403756875714886470,1788789209413161116,7875708210957049537,14950961327464357136,18033333054296287107,17880889800393914808,6540360299861929795,2984763239169092140,10118087812534512809,11295490055345487419,11937993142101911775,4798994288100582813,11327308424502043752,13303945874480371527,9276516735160084191,5196116130117261646,85095196847476408,11025707274959672228,6309093227032735931,6459183073182836564,5426220075792032305,16278130905580015378,6939334112845399172,3869028740231326658,13558142903045276630,1133214146096335813,10948909070126272128,383487688320399349,11523573763937023405,11219500934169374234,17900429211458076139],"proof":[[15361331214220861085,14099921018181888282,4516391099306922823,2246587103693247867],[8685966553550540435,3766495234392472794,8007602197318693521,1116574540725268206],[1825164862518874135,15085000959470014933,2509900369743639176,2841616800670210077],[9181913070983839790,446775179372746816,3343395872024652891,1957412799261736040],[9709481083920653432,13231340542933423473,17613154774180416254,2085541999486253847],[15016065949488787234,2975647535209316200,11608079043726128112,2533824620519357426],[3601511704885768731,16040323839326082696,2683526615836094726,1993568544953592826],[15860905318086663542,10939943964564605426,4962298773706868309,2624494608236343430],[17363171682766544560,3667059035089566726,13483584785676326311,1758769245393073985],[5170783612596755313,11430313289911920418,7744932436519666651,407107225754060915],[10728006944275488600,13460645259128552188,10428182427638012003,3387795798992070862],[8290037536677198273,14658697448777920115,16438037693689542587,2289856877963691407],[4116420957544392334,981127288402861837,6702203925816007197,564656793942279335]]},"fri_queries":[{"leaf_elements":[14785045601430713326,1877464608003451327,2557074260437183436,2961596703312039889,11158592166783685692,16188214036041380059,1320991156959821580,17321341392179579494,1939526969067665925,5879061158991679696,5563683882387088898,17710095831156550696,8164949769584274327,2189789446860053788,12013633108250774879,12599543566703245088],"proof":[[6963634659720400523,6923630784534231288,2472547316778995844,3078318152402664326],[10808660774339532269,10646485197231407370,4862925652637470775,797122320591628370],[2218770939446316481,11465637897146522366,3505796439131172264,3187831079302126018],[14059901160414339910,2998733380331654224,11287643128091097044,270676664715994231],[14817240820562121182,2177026288657355457,10037324053349616000,1863527803464807164],[12429684542226109881,14542102988844799829,14200830825053149126,367221143125879678],[3532330861425255193,578049178405438148,3377079969913533457,2333512747986720465],[12018457935594535653,9692341406574464875,2760565008527368626,3391117026383682925],[12459205945557951313,9658351906122242482,10911664809236274781,2168571547161351640],[10701620580987285083,14029228686717680906,17606917425319476032,2505274531328869815]]},{"leaf_elements":[380147433001108345,3484200285947555166,17607730178584100137,10832449307728568297,195341449594400063,18356632032983789917,854402965398521978,13209138066470853817,17935347689846053486,5653489462863037600,7975571685191230114,9029697817409493510,2708271035467199524,2253198017780861558,17522495218814971507,16868105904429572594],"proof":[[9925107655808591311,4125847376615398066,1512253941015695997,1461713859118981123],[14899526231936260158,8030324692362064627,8452147608248686091,1496363574328198319],[16582085233536012084,16717570006984069584,8817668382935747194,1464862905365546558],[9141439477645370553,12575387910760566411,10796871418905408552,274546708763952851],[17567586209079277908,14226009379804531805,1678790079539932792,1740044022097005265],[17784093462431197239,12814742217395568791,6508355028532470827,2412882452421209535],[10796312805924833779,10052204889508537523,17029417120171154458,2380688193371945324]]},{"leaf_elements":[7133794153491046080,12391511318157863172,13038688150704261545,10283288148787090406,4685930859416234814,9929563938463782255,4111728149948148935,209269094361233954,4766322736084527044,16960019263469617541,10757688771833804328,14896634530808258918,17754848202993077490,422518382116188131,3068197370565502540,11856846370795087145],"proof":[[10297012102806641458,12352821735213970689,2256159259023844868,3196449397001263180],[12797790670834854050,6480329263276533545,3998602564223302896,3025504060122744324],[9037746557057048456,17834278038352391830,4656790350218572942,1400337594587714743],[139744036230662203,17798083038650091172,6031175594198885029,2124951385919977084]]},{"leaf_elements":[10414973603641774256,403394223439685500,10536595545238386023,14417065532054984200,12384715249560097018,3156902985129211271,9484383719828687856,15924333456246663000,7155148099983750153,2808246294803892123,1669609172955553579,1751249439668137723,2177940236717868821,5260503247396225335,17657695492767045645,12121937833396643927],"proof":[[8669456116196418953,8307641683636278137,14371410889281616166,2389164284214036631]]},{"leaf_elements":[18196018707140134098,3942247739030689718,1556687182756891542,8508669979898744338],"proof":[]}]},{"witness_query":{"leaf_elements":[2884571791854112631,16670949619790457349,11762211361553357743,6214549310627800344,4104645279063423911,9225182486849102410,16268433028861909356,10201337362967877809,1213660394835940277,12464236487869578199,1995454736121233795,12112066367461913573,8177394500727724875,5754008813972715841,6530538946623920454,11296551753093902800,13538524560801229524,13437841283874847275,12196334722147480018,12270818067122472037,2659089979322530514,3744472692429908107,9161523835686562642,1428774475490152796,4471862207925964549,7025669470790733729,10377550614994960386,12098755665115315896,13115413065493225158,9385606364042445523,4704994192220201702,6800082079118555256,11107559177743843432,15396503504469162688,2248237612439299308,15290436852708750924,11303083533269415066,665019374178988971,11823821146509943972,7109466142947639071,8616976299024597145,9861228051031426848,8835540252382963714,2214575326013842767,13508509938516768165,17004217153767532874,15048757313082980613,8129356263683722919,7821315043671895335,12630460512241602634,11220594644083102029,8066889219393553966,2397254008652323776,15642607197017676115,12539850323978556939,12564555233216380784,5462871454889966493,14025470534521019501,18173035894507225569,12257461676553475934,343594503856635716,1372276958800890962,8613484669665292853,11652620843133900331,5531618988142588175,8223900129372551481,3065038527938451962,11103893746415852989,2453054467506314407,13188163786656822589,6397780460246622045,7240981719259387702,16154598896477224328,12530877588630865963,7010936612217840355,14630150729686544014,5842574469585938743,2147322126682676103,18203719868053474618,5674281238767897744,14353739849702908095,8370522098996136260,16096804081001324066,944663012370106870,16923527515048833771,13092018989950543757,3119697811021010428,4172991359442309490,14369253129050525421,78702567169359924,3006642118472856093,17563802651908124495,11530715232694449866,192287041237775467,17261900460985479189,15045051830912377834,3165971233544485749,1508567077119701019,17605314105717112639,17703742401896212904,1208902124105731868,9080236671756190455,5805404714364851482,9980129529258217597,15342420017127309066,15978390775013643829,6319399874950584702,12112283714953368759,12386149422479813669,1902313873799639216,7872114271819209700,15896334433316029668,832236596124987789,18212848005911748475,10936885303282550514,13862412820992460306,11725307501180701602,14470580240462298233,14139684152715406132,5225330689415276449,11469272867585263826,10137572111195079844,1886986595319651259,7987796962663594716,1712669860267065413,340017883874505912,5019976534189398820,4713907070155153827,4528130305148083258,2450380646863927717,437344313403630905],"proof":[[7104657853792831513,9790257305930515467,8878250177808252499,2183961313278980872],[9935301416429021702,13351047907782045031,5724269679645387204,1678130250712726370],[14248540919323974481,17870882345354668880,7640495850674820714,2771048608698756241],[594483262087916468,1715039146466177043,10929004669274655890,2555625183857007346],[10741967279421883992,14504014400903291568,8618469480343499126,918307522719440457],[6278258853554207652,17014594723424108780,13127463183513078796,1570945834895522387],[7092435318147693623,5302007514230966725,7968667474058316000,901305394731961472],[6637525593608244354,18008603249090400428,991188114358936560,2072953143717394966],[14615458940141479662,15009851878164050948,392450882970930403,3228459194420982393],[14062705785943038141,15536186854940875510,3729900588673455497,2728331039382905196],[8546177603714549538,9731507560978562283,10073065034012766283,2229658289611443493],[8306212057502905801,4513570971440212739,3182621761424601631,2007843718213213775],[14367620299360517077,3486062918649683097,758936314403206639,1603949708714258502]]},"stage_2_query":{"leaf_elements":[8039291446717872823,5414646211152645812,5113953320429796184,9277055059092393047,14766084064932092353,9592266763006908553,17263440314464418130,9846106434712768309,4827797489644367426,4715171058138990324,1491767850777850704,11541779604102014040,4383317761326425771,4032517177734134705],"proof":[[10646354567037917136,15015222257725780226,8834223575290668988,385748395303296821],[1699043306984196981,5358925348669920442,11821275222708764219,1194367786293028418],[16271177768292194761,10511165054750144406,2016579787889315726,2500086330011961737],[6261562100772830968,16011787583490234975,7305009113330344567,747792432142642391],[17784318339066833378,6049903928371829205,13612594981720130335,1352646572679311789],[16740746401980029838,4333266331824423570,6037937461364451756,3441338663437851270],[14677725749627604584,14428722807736990153,15557334929657165829,3045619635819170358],[4730511195800731556,377422510996105462,14668013292803916466,2558776186906061591],[9893650935917082330,8612827559018332378,349841004139413917,1316737630730888367],[15606604571595161392,16175646993947669807,8306520237934446030,2757825325461070483],[121396382258913492,13855720110696501783,11173136907780149812,2958597000520510762],[17946811300233807722,10697057011455301775,8841411358577018535,2882676071995806414],[9302781254238343662,6119432163943488281,15090348966859265029,530198869118147718]]},"quotient_query":{"leaf_elements":[18315198000940882128,6924442667083137923,7980724922076396925,7598985012731395534,14922652009787804241,14984879086380594511,6027828251034642783,6133756628856833190,8114301623942434149,10749207867472371081,12403398460459219463,14861404922811436106,2723004073426467989,6784008507538377083,16900116661981156117,13462237132515894466],"proof":[[14480011988412573677,12461166923781205215,8795123046529213189,304914208854800550],[10998362625153574157,5037834575030937023,12284261025804947829,1332677821061162074],[5189847470069192339,14749670232200980088,15640373137635253536,2171870714041166242],[4242079684072323102,11843570488683434890,9379337898962279726,1244626332806754843],[3398410572500529060,4168581239836457285,3155411317693519514,2599258233175836882],[9732196013448118001,8909096912833325551,273733996558399278,3245055954133347213],[11585736902116164822,7188843925415210432,7197708541947804762,2283123921377660899],[18441330633635537388,10342146907818413866,2936418213829459056,3213070820011357612],[826115451053515147,6399989333022243830,14029706182131625538,2666830317371216920],[4306658815669141511,1000738004669499087,14468977217461533623,123912981583775758],[690956218003368641,11271872052100171622,12010225112564945277,2652967736515055733],[13496753780212999111,5601887085332510753,5921920338607442953,2763534670305069476],[8815952717605006386,4526522413909831776,14701097622325747530,3485165681977640036]]},"setup_query":{"leaf_elements":[10568706168260680827,8811840154583669425,8637943023549974007,9690184112352498443,6551633249103169429,1148443841457918682,950932450116580189,5402499017074414833,13629962206327574409,12868510153116359500,17195711267199182388,13484799278928519773,10448454107095374689,10790915463281212437,9951401316654649543,468355182181268258,15116941636378641447,13936103148465500516,6745084806710922572,10563982241667640048,12093444607809955665,3383633884621528113,6696416586955545947,4932600129074998277,17233826016488736852,17120974784609375359,9021455056669147673,3431047727127097970,13788469137689912688,5374543246460757966,13490302967690618278,17730959864073471261,749649031834953821,12488327101348149230,2400371849528732572,3521853764136504778,9964384484992953975,4294384076227859613,15000597396843267689,9313034171428644635,14950769605219348643,17249214070881397176,1379175824678051350,6271880075623721331,5112611820183447582,11780179289517143014,1477049557150912294,7250721285139145726,4450906159608050962,18047733523718770744,16520174905021493507,11130334505554687201,485230779869912470,18414856072190122876,4156552246856876824,12956907599080629035,1874386979216293170,1542524189150760839,385912943722319649,14012091123342144625,16370471405703171086],"proof":[[14799876193076651319,17007748532108876239,8947187280744668110,2719702049277237213],[3444522201653442859,17740167106377497420,8000825869159639321,1401779446105486838],[5108116670938852424,13300616931947094197,11005263534813970630,2733747088637586114],[12573880320975241492,13216145748907286072,4064431567262589115,2668406605992732827],[293545496347127853,7196858855287418460,8296754516676796253,1966580867337417551],[4767609931666915474,843805577036692922,6667792749108039637,2356318978668253501],[17495606465163513345,6384249972588317400,15187191879833792682,2347512599990708131],[5249811127765577229,9026432277364810784,11641230875993335357,2074415694004756986],[14267602776922856037,1373023832919764068,867740952532462755,2138129001617782437],[1151310088668724095,14038744483975954861,5760080154045965857,179705461157934831],[2376731054126549134,6819668798859308066,9876880567564165409,2668289824324948766],[18281726552398374921,10687318528114695449,13037667625031883888,3021881666691503501],[15649328145457671106,549776313160692971,9928450923310963291,2751020716435042226]]},"fri_queries":[{"leaf_elements":[3098976358104012391,18145020674912786107,4279384525206215041,6642030857785370264,2117809806577622589,344347334586786675,16876794904820204493,11108474613013295594,13128087108331306159,12751351594519692225,10318193422253850071,9918582333578868170,15244123595611990864,13359913591707304823,9115970596759538555,13210011093993852858],"proof":[[10312911504731353968,14748473113234039119,12358154010580745549,1575917249066782919],[4315852634051532141,7207059402510936663,13461992698256970806,2521138001984011098],[1088095523066260018,12626143756560875161,999904755972853404,1201580123307382844],[13041964341958327828,5216940957124430645,542300721033335161,2311453028405390980],[15403421971860379921,3744860260199247722,7595415110289436817,2639046357980125118],[3874455474330518087,5003549543090011538,936581685022270211,765776682804131332],[2522509805466932273,9653898018140610320,5599479681012700789,346176432730102797],[12009773353683871091,4506558698578468983,9089979691125928464,519890529356559345],[3836149467745891357,12700830065944535128,17543171510772478243,2771009779489953517],[18274227798351134084,14614972872318737132,13670777970563782359,2498334094624877115]]},{"leaf_elements":[15576260099674000691,11404351188836850908,11466612986236880563,14173527519111862421,430634730281163308,17687079966821558542,11275643520578309016,18260366623352218178,15912484910770750199,1225304251282636653,5710766763403120278,8211105212319988346,12732774177293320642,16614142637054873808,12142339898826138359,9694151136217859179],"proof":[[16901284299309817705,2292324165952902586,16935898757823531437,3066652160677861820],[14892402829052491347,2833191510262515177,3324989729100878882,1498231023248521031],[6530641536175766489,4242703819429625175,5064176079102228434,1045780302285621885],[12454890526333753930,3201978947918422083,10678737053118785835,777345307730208342],[6870935313225897170,17077921725179214299,2715337795293003721,382690835644999429],[17647726135037315420,16939452995086140404,9926656647162993029,1129491512409889290],[3864735070791189707,8330668194952393004,13164775125511877827,177041749183560687]]},{"leaf_elements":[14491078459708759530,18266244580071910732,2375556921371899716,10456437434718672838,3364361029694307433,7848282988736829706,12040593508154765818,6729397710684024158,10750817768927452768,13284308159480678614,1538663693094846764,10448635000390890554,13090030653961928650,2306737690079481401,1056897741158094061,11345722061824866943],"proof":[[12804840986609170954,11011107415267122649,7192919539194472114,1085663711794729646],[1065871498043493475,6532469188357444428,9781246741891437037,3390787234931501497],[8146435607594056767,5057348374914061128,4043163455170630552,490242688245896419],[15036230558710107040,11921162934449550531,16484118682594038981,2366781330473308508]]},{"leaf_elements":[1161939574018876374,8351817840696965648,18372653301453144055,1094858428888221872,17891497325732335182,6378736636084565709,2312548455298580963,11108539684721161071,646629569524013389,4395291750589940087,12400931690617795476,7655909668271100330,16676308543461110775,6945943938750155993,13376778799557250354,2903074057851475984],"proof":[[5616782601955618559,11536326776059504369,7332699799654596753,2141932960124082581]]},{"leaf_elements":[11506617648987991818,868082017674053972,6543021463611153452,11748771781491803820],"proof":[]}]},{"witness_query":{"leaf_elements":[8161998666977474657,2717970127754480060,13819512354306193148,6498582912734129907,18105474951927960540,14723275596763064196,58883675728344372,5892733964961769876,12860059915147484779,162801839319959041,18042150525451196894,3605025400544785294,14709326566502632410,13589502665620144242,7328391408669237064,400470464013985063,15045129687295861351,16739484146713986706,16355359291705419894,12907259824486410582,2072024153563672271,3466469229296092377,11750000130549856768,5278328877919417479,2174132754619770748,13735133590550290523,7596108160196750290,8594472686838046019,5993037781965474725,12503671241449944715,3288708251164152860,4329936901907922792,16083210720174342098,17435137674720077221,13065205941330945305,7376965796832715547,10235882903736772640,4219684081010020448,13982446861449433011,10200036003842419845,11401830009039430835,15492699696024005884,6538160737537724152,1137272849124947999,9671475818505310529,11573881618969603015,5047890821993036435,9993673323785936903,12310775582010085570,2458631696157664403,9971147741489422880,2233459665739935387,16874890380651591805,7611857867065127375,11654208500253829203,11968660129572697239,1025477733071324349,6188580977200384584,9377127811585654022,1006545421025003865,10479129512868394025,183281320795523256,7698108870565322881,16832697249979250309,6679649565128258101,8094336601737544597,3838653991164436842,30743309829957380,8538255457651616369,5786721133259770958,15084242429884762922,11193490598157832762,14684766412871346260,8537944715664011880,5801731381341396172,3757392100632818571,3469519710722397990,5609546847414071649,12567942343401076904,14319046724222310923,8925758562917484899,17585467546922307846,4584637716345450275,3201590843976488610,1386329025311462978,10991546346910369336,16513213612591195306,6962629961513661429,16713865293270963007,11558331309303906429,13233578552746244832,324811293551199825,11512460210584401887,11327564374291152901,7341495995687063391,11594915371895987865,9172762904888177425,2472432927312994425,17665080789492084655,6473818592597113272,2042540757809847397,7637926317803134607,9244027416751900019,4297522551510613911,17108275737463294058,5164654406389105529,11046441550024277653,18178908028924177779,16301733131604409567,16460975416214011838,9804802822959284395,10768501889413071070,14635251357910886764,6969099825798364377,11344403826001499169,10662600025189704696,7338789252228772944,17771653485164961750,8189601943626896058,12296566988500543092,7295913176487130554,9481677887173760182,4242258413575640697,8779939241117777126,7536047786078367525,14643990371541862009,18350167107501914495,18346338023218208693,18132513134963306985,3873132137923295185,4320777693749251495],"proof":[[13440864253403635329,11713927889857427733,5371560423692623855,548145032570942677],[3259690234057982269,7648136840330004794,15921946277881971997,890275379043567103],[7124990826248251738,15896214275450579946,9215494927444447866,530924695791682072],[12633434121780431579,7825267582607459094,3329545484383171749,3262772088411285629],[18296590314677053744,14780179774885872209,2620344665956991705,837991232946022122],[13381578153985953102,5114921598175027067,10076223476048443510,1327948044860008156],[4918695923936066117,17166216762991356826,4327782539045356251,476094172708581317],[1840838772452910104,14988442075250406644,8619412163719324591,1780196434435177055],[12928425502066301836,13172557842224064635,16158743681695581541,2756986240894389263],[698417159435157269,5128096137083892992,11084364247697163842,3194873589066267980],[9317988598386287165,4171320350909863924,7024179928034417626,2008805193649462816],[1399558611002625433,11998460121550009067,8931575056411310580,3349109739263796111],[9986534556560031500,4168905852649190801,8442442153577249726,935650195886037795]]},"stage_2_query":{"leaf_elements":[15048265523860294475,3094574080376679624,17103551161644463791,13832982231130643408,13817817968265701699,4790373440994824189,12907150708423606021,7177775171934965181,1029411785747585797,12763231749224249238,6873663421094968961,1202475113452208926,13118487315129250905,10409643252155854802],"proof":[[9328513131171235749,3048512048810939190,2549942417902865423,1682768524836106982],[660428304658480804,8683221935002331765,15311912095474305072,2054112655079461439],[16575132476241806908,9695504126467136770,10300225373395055743,1620763434114855626],[17689557433236023737,7575562097688436016,5241597473902342660,1299268731264598604],[14828616365264033015,14759723233626304327,8221566808712422691,405729117767263849],[9103756146470744613,3362650911466473839,15750674468652450388,92821151448559515],[17997242322908501004,17100847868529690684,13448625608249935106,2968115433700344350],[15326637242572285543,6210462883422278051,18336893949764035268,3231771582283396332],[14504164800535977191,9371243476952136901,14920815103367540568,2485795751265638679],[12027407452887463094,15035687474020459977,17957820817306104523,2581336642017829076],[4156232298670899131,8442439683233985248,2816989313736023705,2855240463960380989],[4826186519142606509,8843526122236724294,17868385580913199502,789267515232431137],[3929106972898368341,8168702184152748531,1012745953153184386,2298210201343737391]]},"quotient_query":{"leaf_elements":[5787424563812054971,9941670458315682489,12929530455607161204,8771547441226911560,2853394274436439976,2557743796087305198,2287268422574339167,2209414117003112188,8325634205467170172,16644212114145812855,8696169295340576429,7380854245451573628,6692293528094064781,13998272932284504043,6416952831147813641,4444105310313910415],"proof":[[13246692993505369007,10615812824174054440,1104911924457928601,1808223794094097179],[11656465396294712948,7801187196026671228,4032414941388915185,1067410807781660147],[12760966210459163848,17892496661167274516,14726851152319476578,1804606133636888481],[12994668641686083845,2821924006794136203,14246611837494892644,1270640770685671315],[15847730032742490712,7456813409464092912,4095140080657021461,2618450048553532099],[12339945130065569983,10593598205388770927,11801062099802035583,2616696201451531520],[12798586587647292824,1743823890538334298,5389205824344600035,2843126406293274254],[10988037142099694300,3063013406065269968,3490037553155577844,1800176573237115793],[10664573641515260949,8309492481215849904,5800901499764155573,236662996988193252],[13855451812732282993,5000499419932966588,16617327504968286146,1256024334507860132],[11242675047627637619,6613050748050112875,6280649273940896661,1540050270900068416],[5041539606130611705,911517593073596756,17525987174527020371,1929397605581272547],[3371259541088757273,6499617785722508082,5034023945137869546,868060244866308003]]},"setup_query":{"leaf_elements":[14784093583331122971,3059596313222877022,1871452540383072574,17971685177031870996,1871947145693618674,11534643484794712914,4216635144700270408,10261499203381902720,18127088777962271032,16357137612126170266,1065752950769307664,1582920827249845392,14724500376450717734,3975319953530027907,8085013229035513370,2860399415372839621,4054893852148531044,505492876778001721,5553263385068860038,18244823225214561307,5119500757557626447,8595085916650318076,3315768718390620094,14498631102537160170,12525227003712939232,2799235537981715897,7155462643487395773,15778363657361199896,7003962444103597009,654796278064831287,9926509129939547891,15881751715439237472,13772437587775931812,15949292311737340590,9753689508387912984,8266944216084312601,15875180074197381584,16109493543656270261,8275647773399043782,2153349116343715153,14593306924485330,16421955153997138467,15253088737562769243,5903226375179911221,14465682411668035254,7803323244782083637,8309501212191892308,18396687205570995424,17830361279616530890,1231259590912653525,9185080177356979369,903922256468631469,14247783247346664341,12659437896030004009,17208770931848452058,18193498592913102164,13022540323423566574,15630463997563265514,716959981641940816,4272708058352190170,7330230866608351450],"proof":[[1328496121787302230,17155971701837665523,355134518016850268,3150368643914689718],[4174723291432204918,12179150018157025997,12800235277811698673,2115688338672620831],[15245013464068565101,2269910039607277210,8030582132114938068,2399531758338968991],[11747340437115169687,7278888452113603466,18009461807862749339,745224107591598655],[13895916405105470565,4908444505600150988,6034800920012099025,1487584069961334592],[15625449963191485160,8381202418143208441,9045597482061282081,3399786361066750983],[1681658419393265156,9836263994538433897,14026849812482562093,1628965145993921513],[10419396502932781312,2569387724900235676,16984142699268798953,455065763537786945],[12027932116062701359,13961936021944938221,7047951901640731935,2988468298603780341],[907006740545163468,6269262895689363562,17851887098498866368,3120033187030792211],[5880536380205435091,8988109943768846168,8948683943614748747,1299484672283349041],[2096633613228542274,10247230832956913698,2582647671840881489,2337349213770688628],[694282249315834913,9131759307468547458,14859054783036377680,2556896920359897004]]},"fri_queries":[{"leaf_elements":[8059634466938395319,1087603675273069303,13887427810301954835,14245029163612071685,17538346192875501844,15524802611947173849,14783400768858695905,3630211827902011232,9777043384041672425,11695405228073127608,8278408336014408125,3973522133024671914,10696174491489876921,12181581826176823476,25514381388910319,3514726653043463490],"proof":[[7007368958791493358,8355422154445290097,10342513220371205707,147303390348839066],[2026522767657158741,895524326187194940,15723750370526611903,3450631149279494212],[11443319771970133611,5524708156726810923,10971349184701529508,3083527610413365317],[163171466640758978,17351989194464696535,6336576454861821254,222753214723538341],[914408659289186902,3761027086289183818,16786714230629868573,585630427233371724],[17318503094204988140,18044884685216064390,6614024638630101800,2076544447321436782],[11361730203068894426,3680121946875651386,17526033062008274652,3392669872204530935],[7882092492228847321,4471930821896526360,6992058519468021938,1060754295174178583],[8711799995105057694,9584492765011979152,1662279205180426677,2721288857003446324],[3031335695723453993,6008477298464842454,10765433495181274712,2652030715416371027]]},{"leaf_elements":[138542514111468065,2859441077371707649,5408326759719516838,18204574879932934289,3202872516731105880,10835135764697582830,10256328339983915072,7934646329097440401,16693206975438763182,9427236966150282011,14577286388591456344,7445336705463883784,15424427905622527561,1934702650119023723,18399955868471688264,15866995049239277517],"proof":[[10473189255268275882,4333295987636609172,16765928973969046273,1006189058866089642],[6174050587783112948,149887720016339890,13541188707786944022,378250261021521255],[17956264954769611488,9355461975784408498,13279103555217665460,784459187721225029],[8095378267247906322,8452209587008052269,14304794645877391388,3217989672068972675],[14606953949117501867,5883776295085002593,2598488513080939241,2722239111241924332],[1308791687212800679,17439520654013078978,14966667291729064458,3407308016032870470],[9205275315130554131,12859436265214383430,10221394395219555044,1559039297082053848]]},{"leaf_elements":[7316483859597586081,16428180163814632291,7091893937774374451,6046056136958251440,17809833247029302149,1445940697811951404,6295867159341258123,15853361936726787578,9011748475182841663,1392259783797100151,2144902125626971175,12960187304435301386,15351301122828506928,5010318016691547351,17709602852160607468,18134361388934027729],"proof":[[14631725942832508968,11782009017493823066,1641238755326935,1825415171838851693],[5161885191070886748,17345126237564432542,4997730869086077647,2355282103243432075],[9375007685637847610,6537854564438990166,4361148130625555949,109028333873562308],[14642156447412971549,8753961440126326853,11783145797800391646,3176188692125511196]]},{"leaf_elements":[13231179435282412697,11067286733036426302,16464872316746670644,2959542249127229307,3656632155594300318,11512742211126633483,3641952820020161397,16524762161915820919,2866766436991766051,6121019872482128970,16957647701455810681,4800537360445888724,5549409295141574996,15845609310883329977,10819104344405081865,7529936042980408979],"proof":[[10164477711467631138,9942945204206605270,9118718961565509107,2739518935362102048]]},{"leaf_elements":[4501127538857023790,3168202938356671861,488429852234980958,10426529919460171421],"proof":[]}]},{"witness_query":{"leaf_elements":[1694971936807105814,1960581814906018030,13239671607943332368,9290547819864941328,9918737525416844221,12337378698120264826,16973210166175936923,2970386754298723383,15996125911179171270,15258967507531021636,16983877328038857541,14763819685403724392,16716109998596733203,12967482950267694578,4648202585207145898,11563056279887844620,15553320807069497279,16814904291614794826,17346108490987091125,10958518154667669916,11302549310745798519,13951688166063156204,14077866171319161770,3913700438775006218,1155947497712428425,15655011614809806533,15603568630216109752,4816923803825131741,1947676218130889025,9989291018915446399,4185712996797341424,16643810823450928606,6064226203868817463,8996720940864756752,16088064131110077338,4266545312748805550,1088667439154535380,7365621404318501931,15943473090454578277,17706993819556148527,8917329907265803438,17339590353416996237,7555574044333209336,10306358469239906202,2218900284047884527,3504810895023671556,15808864495386822894,5027088178883164466,18313800138751524779,14165736437682684239,8464800758693866513,2798265812524661019,2022019823873912622,7842341223694490507,10174463020343400297,772924712504797022,4596427123410430304,7740386246177598998,6001247318636693594,10525473769606938623,4775460833164181258,1298463091503833147,11365136884049431457,11154569526088388494,2126084383908821478,6175435873129608269,3612890836972278024,1179522712980790553,6364505633831635863,8455214126399073516,4329381138627314881,683529310263560414,15901506951867396457,17079367134331384303,11790786467585428617,11914882419729376337,6738097452816406985,13533411989447181867,16151022961595878892,5844994529550811461,15604452556176001493,9505462376605889475,4727971672943936346,1616073999597201988,2547384888700190403,3933058235255621930,17597297120210883367,1670084406516195631,6361090361239781563,1210531366023021807,390853708604145930,15367331491208098365,1080385901063637749,2449246457290717631,13824607031880483408,18247561309890126639,5140286518543763913,4078429992080300416,16464061047013350107,17451384810173472729,10274232235527460107,4268519055811773779,16684927694640142930,15124845355506514892,12949410069349171826,9686339763878843168,15671949200789887469,1764482602592474712,637384249973319038,10713133696354283429,18082403793199207275,14960097066350130395,4660364504737560625,11280093889780813182,14576792727913915545,12202482549536369482,3407098419497347663,10031999849962263902,6583421870642871564,853598349223325518,6210069796453654738,2969551885990650481,16154574430705048918,17158888979684906466,16203996856899805212,14558494383531853448,7000925815323956021,11989227724244154170,8381226843367132970,2008237307087084710,3178620920764442816],"proof":[[16160439845184544505,7450154885754916884,15696854798246779813,445743262478815507],[2245391290491280348,11800573605196430689,12251578538496609486,3182755666867725557],[17682705671239077721,14759766540334602031,10799141844781022485,637059524373471907],[6042658337484298513,11837860439011903994,8339790866668894246,273774838810043265],[17041073959356366825,3207300363557764362,16630194392286092630,999404921820761677],[11014464264141242663,7504518153903022606,807188900621388803,2876625539868764157],[18408976750362264522,358389842512090813,14887416897826145201,1137127659818260090],[8556477515042486621,17317344015486846238,7437744676791388868,3212445515799370694],[9483627992556356738,6363986109053003498,7563101653901182871,3099897461249434709],[14162926451732993154,7768258176751161170,7951774118366133080,497679327739911498],[8647911231698358056,2295807399450814483,16916144144238836378,822673099938684472],[9768525576339722811,11672889008707792701,281691863958202578,3305185732159781746],[4832379906115138372,11028588231085674769,17437286517034418486,107753723037220434]]},"stage_2_query":{"leaf_elements":[4005674302023008264,13477820862138515671,11945698458081810670,16415404573113122342,4360007797148372437,14063327275897798053,8341038744897937618,17090355453948762668,13239164060445386769,5754641803170561694,5472327153607533928,2140151716702093105,9414176012112932971,1862652560805511583],"proof":[[2153862827621064437,3992542207469148648,5402708266758301546,2031638122445034231],[18098642574604134248,4474693192960571608,7929242384224265134,2178003450827838599],[13457790023009279569,7296378257101309611,13523588425636012740,1077783524298796685],[12056688093085496509,458188737773922803,7141279122631854864,1212316058231915001],[13697155581119556001,6377324708397821270,16582712225103106550,1730728008568010559],[9820875715511281634,8392787532622553189,266587354856788279,2683151882793789988],[7182058003155885342,9447933007233457025,16000829947138235026,361775713767438628],[10885238216987635166,15546505761809999726,15405824866064282712,120348995255248935],[14611637176592823710,1970966454688702474,12054266669811092618,735547702572591015],[1656345402767237225,8750426827503633134,14094814171731903712,2972660053551373806],[5517078829986673266,4765223688197535203,17846521699919079287,1123536604806375542],[4957393372301713968,7478362310982435063,2213452179512466607,2841487375964966511],[253179850175611026,12208827844828377664,5809494268557619388,1729946356149640536]]},"quotient_query":{"leaf_elements":[4452340948054201938,11228688178157039008,12600039847356996729,7117606220283241335,10015894635236535858,4948257927416189941,13357032890415118807,9749820947381154821,16898154356184375907,8972538947273833975,3874458714344686905,13077208266134579054,10711146831456082679,10303459371122356185,1451915849690870708,11137022007377015887],"proof":[[8806682873017029963,12904186324266479663,7517174034665604107,612152108867497360],[2590016351369342264,7501442474631662030,15539344626646833288,982693114771503606],[11428755427618955316,4304556370967303180,12894811763209391510,943492361433824019],[14016799295155133240,12595939725661274553,12930439134015301395,2305102881074702491],[17210099131265159467,8275478889460024284,2446734820002199337,265994969031213868],[15804442900067323139,17562935135620788685,10067717924967859453,2950844383054000453],[6841830497636669640,17393045450002389937,8368116957802234490,3386632811946547504],[10065460027447600264,5485558964732840239,10420803692581449786,2776628542034159834],[11741125954125309622,14991619531842660664,7934377381295883611,3428674420504629535],[15749194532270838296,161955749435476138,11305876001004709713,2489567775698804091],[11913578987079266683,10555458325815583823,2443841609235451405,3108548648251898065],[7444540842383681101,8684344437036066525,602316500209861899,1699929338902742830],[7207630139810091379,4266854911965260134,6829268419185610647,551985630482796740]]},"setup_query":{"leaf_elements":[17372833694949656235,7541604427770759338,12199952899778831893,11400128908085184057,11741824661351109752,15830142632735267429,4702504578981495819,4306583233092261080,1303401394765588524,9433783948579767697,3061994187552691841,1549533168208142663,16757981433723082267,17368120375406536622,2341286738710464330,13030830618310657685,1132487953125632689,16406333967178042666,4827086323352224227,4797198114405142466,6413190161314965983,14988583089569768249,587560481184614103,10593917678050018460,9229175757536904233,15910695747065714446,7977184287618772899,3048975415920469418,30978609562686748,17362267845172169877,6239945951980188576,16318925488987341063,17888742516043812456,17103876262272674294,12104865419517576044,7567138273235834269,13161224683991966003,7392308271434138045,6586395837936519855,13651114073111306675,9230762161609469907,12009689846574584271,9522923055619595811,17129440376576069087,3370089725513703726,12947075986559081268,15162839462968142058,10523558936263353325,9918941946032879452,14272167273613004337,15834692133593531020,15843012784171699335,9174481011980855612,4050262835582095466,11994419528078671071,15864744374171462573,15529891546315838169,1237876568035726334,11881372172326670837,8838414885202036356,11731659505123409167],"proof":[[15993597836764905642,4162663448720669544,6686731878526815144,688171962670192489],[10785778573475963500,1966921880241210025,1194837046293856380,330349584837976054],[13456063286493696259,14588063584560493190,7171986579367597575,929760873472247185],[13979347510785126573,15403716385774014755,13035060062688663685,3113900374146233885],[11909105241349961441,7959410882943305645,14647972821010937685,71365978641406961],[383356763239182157,16397829236228003638,12311059863561077082,30183411410897568],[14846062609051746979,11018031883068473576,1083111044501568327,3208185548495117593],[488228859397201539,5606717493053033219,14715986832030924582,2736499925235124148],[4231097607846732209,17532298808366557412,6327219904797164767,3397830458468060651],[15602829511307296172,14306412105585350181,2850756668987090345,3008851569837670190],[3853108449884422719,9627752530165478615,17412967633302180422,3325873838249488187],[10367993263393630331,1790023779654835370,15091667091675067662,715938203495412360],[14430152768018435667,13625155425001863663,7751044715815897218,1229189555835738878]]},"fri_queries":[{"leaf_elements":[10559746908099285327,3170294892325051422,10928445042385205020,10196000174421538947,6257299532853346630,16261463817131734363,10606029465517443987,17003703235339336834,15049792398190809941,15358938677908205960,5018437717922419613,16264499429113362295,18062081320507426806,16436964981850423415,11941707594059901354,13582831039940169117],"proof":[[12596756273658222484,88663680094597283,4470553500275495542,2338872452683034820],[14687571628399605458,525721155386007995,6832488963473984539,1821386099126200663],[2674667894324307758,8113816929839616647,151296236411995306,1689177134145562026],[14275646152434054780,8565199127808165421,15035746240363778048,3122639698782328511],[642649356325641115,10369278673199420272,16026080461974240818,3441486646352538468],[9566513808413548595,560006117462744520,17239472664259494959,3228251901777315940],[16801916908899122507,5929681946005913836,1909254740585023011,733803569298113456],[3083644177803335052,17346917103600867333,5315874095699433297,3259402054651908865],[14554446821762509772,6529627218503375570,9851210291104147109,1485081884717766150],[12917255288235223966,14499976622908166881,5436213550229819212,2285844493389862808]]},{"leaf_elements":[11685982143159445943,1543719632031993549,3762195286132297503,16624347411882283774,7050121841734903175,10420683008081865929,4864327533320107671,5928987311450676162,5488170061823846202,7459459274438836875,8471918370304388193,3352333567284367809,8205128010228481451,391628998001224389,6469830760425210667,14013283545450817400],"proof":[[12096089519500117202,8489751441337974591,10571300408170368450,2022565290752058301],[13341688086568955305,11087193438846751696,5786697713725438078,3323582275933188500],[8334828225179248755,7355246841079124895,6216841711724171346,287482368557055015],[11479276781720853054,1000302628620038843,12306400217302650057,496476198514362501],[10310290768795898811,825025388262787118,369789961353825747,2182482597144832919],[10755999276392972795,14331754590064518988,7553222335914137559,225262180444060771],[10678740004480657638,4821612586301572701,2713702765633163690,2883361707359353505]]},{"leaf_elements":[170120562046535787,9653716258521158255,18026791857002157525,11429643689863377149,3950704362830130652,4804216613364764372,4627416771046313571,17149525667940950251,14730665405148459746,9951043948163542393,11041824839418896571,14467633231638790229,8045309682662099827,13630617185281088313,9378902254906922856,492374666371975446],"proof":[[14244445302169830607,8285687263097842070,14013495657030423881,1740654508434405528],[3124197734515710538,8336586721135752433,14611100852704868617,2420503830742021714],[5056283299278904916,7573716861628750030,3181551069891058784,569365129076205572],[7349579519894959072,3479006254350232831,2249506297850984686,3461002273469143448]]},{"leaf_elements":[10107650300144122446,12872316686921106367,17782138609005632202,3101284115629698348,8129718703149136541,3488748637624496172,12239539572413537733,8146046347961466389,3729132655365631872,3816743499182286664,16730468474630639466,9624190507278423052,1879743752497581249,4337712219509902155,1896622693346975870,8179875534869575739],"proof":[[2554532247243837486,6767478030061646626,4199547846988518451,2086946322843166353]]},{"leaf_elements":[6865243823879750534,264255220950879342,5012916995573505337,7094628130780347210],"proof":[]}]},{"witness_query":{"leaf_elements":[7030561965821623616,5669801917288711509,10749157166020968894,5758648292809057437,5730891787612932477,1806404442396226257,6094631432419455820,12813537317586439092,16393834577071502748,11949044704731210928,9118893527273927622,82003426099333342,6549000804760277187,11553703452909564341,1090504250503792383,10886173681091968350,6011694708438683411,3366816843957868577,8084501423892635240,16012449788411884062,6926644001239903868,12994173680724481870,9215824103489667452,3182517358549035724,13635557676640885454,6101099112565635516,14223365483955709760,9566655547096125830,4023933533609108465,18168585892089856661,4139334490761699054,5448446867778498245,1330655015322540263,11385512069197591299,6909342017883141922,5991633250036540350,2005910671340800682,381188893190823140,8394234341108009004,15295725373902856044,6512758860277370076,7543527144318409900,16205715664851288923,6130674843978029387,787591352052696471,13281213346078627037,12172303092631782652,11912256716378587200,3998352704069964218,1805724720934268993,11021971266693567824,2087789137833292365,263041563563752386,12320179584664537502,7828580580277702455,13548699683320361370,13398192524046276472,11362942023960410322,1161786308486614621,14725734840410474295,3288414859477086946,3444944741424841530,5464773957383386236,15320901085355336945,7339037385180863934,10291839184620584420,5028484361320790845,5522524815047284395,4826295798355589045,10333326460714079404,3596427203995796136,4248791658942290200,10848324681189536897,10240348112566627300,3980386065890912513,17745750292385567692,12991112453616834279,8352337133488842115,8215918672455920691,8969059461487766698,15185905692798299772,17233852163459962127,14176676715379436454,5995654070824978762,14965902366145949692,11096598087815620635,10535171544995630455,15715903174445631009,10661571368787030888,13914042038723017455,17634019394042642999,5640716938303430192,1599205282966415704,6129703697035514870,16485012792989738552,11788395782381370859,4632198567609962184,13566265231408715112,11713079621294027206,283886480294143708,11308900406165593128,1655082456042146567,8965009423938203328,13964922878156860816,8727855994140150640,6259153869491728399,17271476090925354906,12616747102983907322,9729955742828596370,3966187061170415045,6691402547786264967,4084652064959995538,12194138010786438013,15217154846834309637,8992234940039304260,9514923859899610289,15779730517074233612,5140063396922771240,2922575283182123942,9356902668072144972,7078363985533625475,8587596513398580754,7764190848863257612,16320165373754138035,15593362413605134529,2864760174968038530,16313466506532649295,9728206877628359618,12642202617751382680,11710300976236824279,6116615507560474346],"proof":[[2742603476072053656,6505974887931257587,16755661122489620144,3055496274665791989],[11274664747919730969,17645377984527061196,4841562059952111108,395096527603900431],[17366028123394249845,6789603832942281313,3857175768237276669,1556253523301702012],[4917222435290666778,9594671207649902926,13012062091886407365,3483814177887381313],[5048102548147551649,8598010266831842736,2638010396568151352,1909369943185073754],[15408067648158245482,16510061024428541649,15968092896856955837,2904608272717385604],[7881881768289431,9796475189638078792,10099321246728504580,1524576268578222483],[9748569698170133251,6069769454731927218,11224368081131203305,2495990534480443150],[15001207518908853402,15583076913897132521,7920670534411076305,2745338736049920005],[3021903561226446393,8200634701864757838,16487565651097998291,2391192077551299953],[450723000563061488,15434080896398895877,2582070088100393897,1278712261124326559],[16863036208558952238,11988215026144335206,13195299128578403050,2619397118560080661],[8899754350472755776,12278932612733122602,15570693645971944066,1640054857718498562]]},"stage_2_query":{"leaf_elements":[10119815898826497144,10009499770870240433,1569388736032498986,503931807763565493,4466231224699375197,12601739528327908802,6218826975729166312,4069605157874790974,14388138581646666351,11549910428810366726,8560412859435354027,2359998914099646044,17795589577914817694,6954258386783200039],"proof":[[4617940185583535546,4645452069283436719,16679009735874941849,727451141940876051],[7720378233512346247,989703269993690901,13199705906464135617,38684423570515876],[14420329270509424393,17444039665461280436,16749491230929431803,2917783472294217558],[11208871071245527301,6515880799705162746,6087836218090228878,1958413799352494102],[3355864036171537236,17989330360912328255,12268017701224472157,2627169935776923197],[10295283483423443924,13702600095007857122,11337855410067059674,553984760406646356],[13052677032669872754,677071089747284146,16298957268177123815,1099808678799803051],[15190431425598042160,8368050110872340526,2392789156063739351,221488413964245346],[10485461082726957800,143304353782748699,2807166156211397245,2555588546603418815],[5290751237375684086,9848152834481505111,7386069177986578966,2611320048011078071],[6855436136382435261,1870117002762231613,15567958786874543756,391235778591055565],[4239951313504535638,16901129885328875348,13702359977106038458,2044626474161266594],[12572859388325897636,17011840285034537662,14979141720780255310,2732718184850494243]]},"quotient_query":{"leaf_elements":[11670757976430964102,2281641810762829196,10629326903856477625,5917624737704939067,14586101994970347744,9856668395163165182,1075332310592044481,10696456898848884906,12083824656022650981,13804804037234152351,6364678534175501174,6143842784415926951,6401029715612290878,3118557061613123621,10325429092969857841,1571429162781193934],"proof":[[270753219307059055,6505568877625297458,1147078131281171100,3246030015850207300],[16158396375254636220,5826496246347869840,15421420345849635915,820582257458952832],[16049234802790451216,14088563823022018289,8763294824485637388,2680134758818704223],[2455516046350429201,6370863706128507298,912422149768128263,1213139199252514523],[14136388839196321513,8485005154545293432,4164237056751863492,2251592131490633344],[922701798431188547,10442189044972743219,14930908692661327933,2612099590426610162],[10556823676336330276,2961397704566771172,766841377871744115,105352045041845844],[4683609120609815779,998310261445247658,3142048447109445634,950586763616749938],[16477136330143677390,9983398293885396725,10711761933515205197,784510967613966734],[3204585686440439986,8909968791530906666,14301355533980415395,296130618275327572],[11750331563632585034,9099622008721567403,5598521584222145596,1176108471731472748],[17226619570451333012,5804126442384619246,11303236367700841610,1628133822769581242],[2322302405481175655,4650094345301116407,2541181434162447780,3440250464316257291]]},"setup_query":{"leaf_elements":[13817590380956828157,11633635205950605805,10410657720860629699,2881957871398791396,906766402334604440,14423650288509454260,448510574368762028,3483058546543161736,10723535843362260305,7581271134298775330,14533571752501578161,5972568927355291030,710822221116788898,4303783673730884097,1770284674945103576,8243490113645654081,18410978894930940781,4615054178259315316,16334088634201703832,13095085394852240530,7078364543763210044,2105078773131655790,14322380927460271470,9519710726304321419,8493822985378390521,14153785125007061046,17214059565696643714,16774637006756546939,3444715189954557011,11213941669405984662,2047089260120260907,10377980406547620236,15651195167889236205,6044974506498882440,17112525905792784342,3935361508240891846,8009574117671920072,13120723966445957615,11177261990807932317,13802624355805421573,16824247424783238499,12919711238226307444,9380871676421245834,16184357788181846752,14156706158205175262,11753092645618970661,9734922721930533749,9181204483870645563,2952383253687246430,18029637902811984481,3168754565286228312,14312739212548467283,668223690223294960,11570481842966336818,771634491009333076,2718585406377575047,5135360622298897014,8522411807837607424,5394458655005122636,2471488556387480741,4109123283815574630],"proof":[[16037198992527258521,10702696532244505605,8834236029588442493,1292549924951315543],[1388674470398847962,18057475551138316854,16869299770415216885,2531463180083681458],[7329853068445166960,8532996226317178589,5799058396028574014,685636891689550955],[15913795422250004182,8327822900854606520,17169211611729272771,1985452738937505257],[3721821625706997424,11562728406123287757,9341393317940941803,1094304974548096320],[12408390615568495849,3025209985204177671,4836293523136309015,340256519275455950],[12124665407049781986,11855714046927924782,2380903956394528147,3086065365582321500],[4761107456464617800,17630130463648913994,7553773888409628298,3359841685074631430],[13757707014504258079,1877755430963808613,1479806010960169482,2028203436165687353],[7897282245274292570,6070231691242376800,8704913588560876920,1969179554267057642],[12420226133792857547,17016255984614324924,4366758720943739434,1589337421974557736],[152324854936793720,6434733559477165843,4995158629164115062,1904827749789826932],[7393247476269389035,4694627994465087610,8725146533108150334,2229767323800595700]]},"fri_queries":[{"leaf_elements":[15898410939818360916,11178107965171185743,3637147332250836982,17098294767889429740,4296035829713539434,16171299935289205387,7128052052398622412,18184806757642145591,9831222275150102474,4146082091368690860,2368336602361969150,7653245504355392966,808843430106943837,11562232256426541996,15886579423965899484,1396532274554378639],"proof":[[16069613034884544331,17864966653427314148,17974523230741755826,1762107372857117881],[4635563394551680731,12266981952467087686,808725876958659599,2939756238608743875],[8250856484723894157,3970916504006834561,18261309158835545613,643164117884928974],[16097696491894221213,11378451600034099367,13678860618038036674,1060530829092377710],[7008651140053791165,6048493446929834838,4108788744429494188,683254568153261939],[16748766695739318524,10835018975208126073,10464913576878391787,2286929169438187991],[12578290231270095177,105268140089458175,13081506781113439738,2959540431584216992],[7793945251104959936,11294403770291624404,15149857362310540531,2975949276820438977],[3381658889260995503,3637357565425517524,83142123069217560,2656235863936968317],[13909292638786716778,8970587721766887481,4064072683418480103,2352438592939364893]]},{"leaf_elements":[12787685275170163424,18357791615583518399,9696353547962376476,3154487431639995322,8426219577154932369,16109899580609727447,18141565523142593447,4890621316638099934,16870145897707216792,3487186794537379348,100819503290026866,5782042635177496278,17110905219570550366,3463693709869813508,1556405372383323235,14774449644835403694],"proof":[[11995139595886006979,4451460654459859783,11304920951034280209,3449873801098458744],[9030755797771948692,9019394019513513633,17863586231181738948,3310253193051333663],[973890441221613216,8014180136408230809,11021340449022718759,1179974515483355249],[12396299052082700427,11636922925782633782,14018315892845892010,1100162689157957105],[16703883870810821147,11238238038101244023,14215320887317163700,2757164543050117465],[7058560104955698145,13685770340727647471,3368167327492511222,778222969493879357],[8219660059199024368,16655180989667732883,12470720334809693761,3261694339373339859]]},{"leaf_elements":[4448754499290945384,10773325992226133674,630107828946673910,16960681374269374453,2276725812501157897,7478141619493700218,11007108831826698712,2069255390048289856,16825459579871713867,5228671458166119490,9871725927541309308,6882360901603752533,14098155155851322978,17416652416927697848,13723089993215597484,13769811594136049251],"proof":[[4949277776250941569,10024655168291975251,5203995107321912169,1059694533829483381],[2031094328539001503,16627167335287863007,1344681254547685416,2030237878421916800],[4548839254371180364,7087336273699594530,18283837389736962471,551969604138509709],[14914066784182050162,13218321865492874577,736393783097052782,1014363730706131245]]},{"leaf_elements":[10843563837985374749,2934059280078601464,522664419033492028,9663970885524212153,10528477958991422926,17612037856198408780,12590216556634830341,168568544817592541,12645274891552093570,17506125824037388715,12658942764876917960,8356328858488461741,2074282120620356578,8773718658183707819,5723522309117596141,7469780649577961051],"proof":[[12374258612337946155,8133723967161758545,9858584754587618204,1967446838911406840]]},{"leaf_elements":[17499325981881337266,17599898521267640417,6381771601744403426,6712813034178600945],"proof":[]}]},{"witness_query":{"leaf_elements":[302312780753871019,4428635474147894520,17379476623044000402,17786469797418254331,2498669099489402721,3482135386364210937,9835716310924593032,13415089386993082703,16478120205730221925,10510918681635024934,13556125432596063582,17205334453997809476,1403865416110265924,17105812319706074651,5559175606437158868,2306198693352751323,6521522156076968949,9817299897763621401,13176872369459068200,233701992054351963,14507403602637681395,5958735433023841047,17820267928595255829,6060396593056827011,14532695831861650666,17665282569768660695,980941889386745241,14348697178087691529,9763294951310394076,11174169760231988223,15595845349985218132,1656211597030039150,10023670491971383538,16794677255748833089,7608526091755868380,12393662272214466167,10939843487639725038,5584180851789092934,18229532132601291954,7236233929559658012,1970103336472990314,995593195728324625,13267290176149900492,8105993284191168481,3187425343942522192,13705458328122660471,2794425573023458164,5098111759153962851,17377915163535495098,3239295734543323678,10784690587187927580,12421464265467746170,8709301290526318664,14092852437679940079,11501043952432957597,16902675663042871881,5114381614972077731,16773543969652928938,15655263672739647770,14398512844687065721,2468900069289942760,17057594486462671250,5570579373903253480,6039837679326828249,2272011441041024824,7369132166932322377,13538969973541241438,4946290148981055650,5107046607824021173,6824633623680207116,5673584511701983048,7544313311496143787,15657363436224525137,9833624614564674656,14195033289400481925,16479468160185663279,2130599453529339306,2969560187615714634,5381875803552237141,13830381240731995267,1863595259013051966,121472805804240932,18000362157799335259,5241908120366726441,18265503248718717765,7421602049872677095,10156035464066961969,5247676988247529285,16503638746029980983,2108475818948426278,14545183532980615163,901010321983932690,6441985770919633282,14462557823923503734,13235445097194380370,6743223141870921187,10116746565292652723,1486102186619966099,16829603281202228315,14655552308950670772,16691366396361340751,14612697822780416083,5158256206815259086,5249708047025986351,3096365642126644684,7211969063220658071,3615865371509883456,15802756658234757849,6208288517071948721,3045249222120473218,18318343754695825331,9684513656278601220,759874039703504996,4710991052451409349,9268688881716510660,15743046731442070048,3277699843632859348,15515720690377948650,18383785837766952062,2277103656320892120,12567653477851701684,12039307962951268562,11455524598404995145,4670281852649676976,12271171754742605005,9577540024609650455,16285139665406759649,2576761032060771348,13519263707324008848,12024766800919641248,5638348178898210561],"proof":[[8616532636437432508,16776434551703949213,4926358168821875495,1034321575444362255],[5041726161892998219,7096547947418017546,3178962439686455010,677292441560001841],[10069546393021443706,5629153897623773958,5119897729952399058,2484692588118302629],[13070145618533252506,6560274839925950781,14508601188553664406,2359794377918276711],[10771304539691871984,13556550448753469934,1603434245192459665,2692510214277890856],[4029862936506402854,9102255325495058679,9573919752517432655,1816188556652647402],[17427629221641061107,7825851411950513827,5467110382590075917,3321022886819806972],[10581733629843383067,6980168292988652173,2805589683511883557,1465558342721646649],[10999576519686340064,7162518533837430584,8893062227899382554,766919222727204131],[13473279358552520258,18351268652446147061,3330407349260370270,2723666300754352293],[7949311848825114589,6104413394651655009,7022174876635094126,616093520121474214],[11087426802181800923,15884898200158356806,1332726411791772390,2686199046994254784],[16780060758106606046,11958032741938148456,7312416229524187577,2063252650720473744]]},"stage_2_query":{"leaf_elements":[4107198672673396548,18226261925466852002,11473747257571128161,10805682269990716904,17413931534614561465,4143680844354501828,17896729508124479271,14007972608498705447,6864072745922503246,12200296648823798831,15182793940165156132,17075229608465568822,10969724051411635989,1139072818898336522],"proof":[[4586429173650219389,17924186594504999153,15910272267450408340,3271420156929619176],[14371295299287445209,13248691779247873944,13211827090586769795,475459052712524808],[14473113969454328732,13102784251834584331,16606031274509406558,2260221118022971195],[597696875092224058,6125521943048560907,12926831749514219181,1087363170067623163],[6942062374436692620,310887101679416817,16132025844789140130,37939827018736703],[3571900467458834272,4099078057915318486,4374837855009248460,263133476735155867],[13207927460725663514,5721138418357235946,13649614717449867634,2720631906384355920],[12952874071089760197,16007518959941080332,116748753290052562,3091609167135584327],[9700526005774530018,2834953884527472437,2777098686389980159,2082416001939653902],[14121773662320592298,14184631469476648732,2628700163687270773,81847610796232201],[16358064401996142927,8450936922289422782,1742310375777747660,2082364674147704057],[1600324096323697199,12298561271247772534,10262459070123938112,297497425543426121],[5354075957868852375,7926439690175627247,8585448747203103732,3454314098108174446]]},"quotient_query":{"leaf_elements":[5038034734215509259,12294974902983075044,11399520237134706507,3587834939866484551,18324147326177643485,11810307306289479835,15538828036344028821,13503454187828825226,17794026021195719137,15251140173813012205,3748970040377080650,17137744875353546188,17985359043521256917,7989080515755450817,2605747360132779000,9546093541857314827],"proof":[[17580544060871558681,9566779694139267737,18401109277990994301,397788965307520282],[11413158615547404074,5980284484699313065,6992334003021166588,1197475965309036149],[8872918522790506758,15815325460865813325,6959045090841329485,352521106360291847],[2180719570601442050,11364753815827670222,2779673138785023323,1595071780563893310],[16968678036221312335,11257297821810763132,15689829644330041324,315606370241610300],[14077892102066456925,14259375902019270143,540891968674215148,1219217027090776627],[5223392352305033848,9575001651791601048,4857130585368801473,2132105878017743571],[3471919420718230473,11904972556378275394,3860224491052458503,2649469725858542288],[11390263896006233096,18434348726442519451,8996799934272479463,2915366322178000013],[12073103251394277465,3736466511122351874,2567245270691808411,1919310147787076698],[4971545956126970030,669295233418725715,313339822746109125,3409389182178758784],[15954198373034633801,7895793786093438672,17040091218657199541,1472989558763709756],[9894783286081270076,8285846266767218443,7388875983260854164,3412182721263324036]]},"setup_query":{"leaf_elements":[12513164830809287503,5350701525421505893,15969026302034022873,10556430679780005611,10644842001937163243,6553225499557882012,5862651879683727609,4077410902380466917,12977042825962084387,695526164184749829,8839499633900195115,7140832301056927817,14825391364419786294,17838467738470743140,6598702789185591096,9278468210565902306,13486512571013269717,10592330682532347930,15809930762918281860,5644338871231494707,14169047369385597332,18041490259793337907,12031417250334222239,9097042135035942325,14476423655700822476,16669989929020317015,17786368146082361273,1895333586298391122,12665493522602891102,9740381670108609476,6829309364433919342,16094965418329986861,2195865482714384321,1476384745806245930,1963584782887175835,14249231330915151402,7491426855840727592,13780536130297678434,15844924515227798422,14258391624532003962,17978706971616637187,2572120321574511581,11608768753275526193,8978787581962834249,4288320027056256763,16254536677778343837,18445597956180309632,5301701285096283984,15791595598954037329,1451773598617127690,14071561383762616739,2190495175295508244,17196793604577647059,6146922306890973214,5624417946781750493,70895699500806602,14511346036602846284,12617068652485988088,3178153040819381861,12558594058167754703,1490649170776524017],"proof":[[11209560670326466921,8307809405432672430,6699139747444315717,47053619768469838],[7661238220402051711,10904224992531398375,11189646543968108754,450970769354003758],[9619357454163584147,17717483513415516359,10133987817279624337,870109819322632472],[15492756928702943586,5802238046547501437,17597153442322147599,38946734462180226],[5220160673506363915,8150955126741289606,12539193634981096672,31731270134942971],[5239427320966667022,3368794621053804580,16373805219825090941,976773498082026513],[1600859562152982974,8478522287421918758,2188467005231228751,1131615008247828534],[613214897496540598,16489304097948669249,15698584638199723739,3260436440838772388],[15126242016640862169,615993858332056827,16711775644206196917,3041435191844524109],[12802412493503057635,16882954521123509908,3848811869777888217,3385995935006837957],[12885553678244712111,6256143155388119886,14640565542862303022,2658837783515037107],[14772192792860455257,11118246339688119280,1965080097173840031,3349448022561578366],[8257498406240408542,15294783180318616062,15553598136149729540,2708965552677615445]]},"fri_queries":[{"leaf_elements":[1310613289475470508,5300687168582014561,10073562317281321525,14105961855457190749,12582370340073996429,3484474482440969923,5405703365886503130,4159834640456092328,5793428172611164395,2865759409046623335,12266954955972341361,15322403071633083330,8772832444645448150,3807311187443475745,16355153246579935992,3429370400245568359],"proof":[[10903304980434562129,8628876082344702684,9346944944665442503,2133834528178615958],[14072081990949351895,12547208424262208164,3767131861083007976,19113929997590074],[12834150759685049473,7728506473126655844,16582856651751333223,3236419890743569885],[14165630224579263625,12559034004046739973,15593197459980668151,3329905078068540194],[7000290812543477958,1391973129233020235,12896018790870938442,634284796233124387],[10717958542163361518,3020093942847300967,9115197239198016520,1507624623819175979],[3493214209932470310,14352148469656456284,16540959922755673833,659985928209885110],[3640705241707191752,1439364678369733228,16823017061232202299,3287558799196288399],[8513214180609609037,13297284929573666992,6797607627951630926,1890464891137065182],[11555457030939037269,9085544040749111966,6591791325541549161,3213063993889265843]]},{"leaf_elements":[3324965197275114892,12999240749060546617,84499457182986755,7613198752404784477,16622060943088592742,11092336087401665796,15311860043681419575,11124674120508689822,11032804896987646344,5433229827358732297,1572988777800865644,221213156057061735,8355375036837245023,1965285867282549499,936643466192380347,14341453661133732188],"proof":[[2871584511416077971,11186904495231330317,9927015214717876555,1203134002069740123],[8376592063612793361,16251927674585851395,6816590692993224517,1913556680516343476],[11157214202607563605,7468618570710117446,4096019470850484628,1589536712797500894],[1592043380310194631,17927605277043203374,17326718956861760042,1901063593416629454],[2549493498408255385,14855674615213855028,833536151334318953,512168683439409590],[10668781434632063102,851620707839899462,924228320636093084,3049764870018326485],[4849490650414052880,49293529635015172,7888700325494612796,960799201708683278]]},{"leaf_elements":[6324108224470803719,9963940336969474195,1850269165618670271,1022213065944088683,1977111228944209541,9477182315152071634,6313898440555609609,15076501826452454401,4001706208885847454,5178995302113597824,4094168901182232718,1743637457997577336,2879887735877208464,6075159056992708939,422939670170608203,4110482132517673521],"proof":[[10551853953976152519,10620037343427777899,14132951982043948018,1944399682372269984],[13700806054213566414,9604222832073855930,10094771509987470565,1550243616437931062],[16293225978637085163,8792781559710197860,5437602222559494734,1152586688213575212],[18214637273193897569,17083110335864207315,2458916006554433768,3322903078046680236]]},{"leaf_elements":[15049793618273264278,17443600347219547516,1587449845484096471,9268301052953521075,15310044983624285302,3137536321055870732,17729664650163897904,7295871734567114690,948242394662532442,4174441826096490128,5717830596626736236,18234818179955594845,6559695840222737178,6570323834431778590,27890742420152916,6071881210060785784],"proof":[[1207514275877165031,36803928778764813,11527218039117858712,1899368366190537423]]},{"leaf_elements":[15915622550061201680,4536541224237163888,16120598048347926193,2661082248244309055],"proof":[]}]},{"witness_query":{"leaf_elements":[11575157606359739203,10035001864335282223,4918220150166398418,4105016304825624188,3092233500480487799,16798369206064131020,9628668051573080118,866772415166068642,14589054436027424153,3413655412605752860,4559053889384142414,12469682950093013009,10209532074869281141,16699588615795462035,6234551338494294759,1649486232882265625,8627200651651204810,10500214990005935387,748246317042637000,5128285381426845955,4856624027916867221,11433728361194366940,5478861332897318047,1265229375496707789,17399513827665820488,14830585653298670733,6879374785298567348,13696356644751470152,10222491452940066338,8092167152703328290,8970879515547824867,14463222307663398004,658860873168545753,11636286483703488387,256638840353853312,14230607971080352411,8728149039845638050,16421992749994212508,11798613827830813497,7081896095390127951,14791353099210245908,15557286094791356025,582969323098461452,12618533452284925553,5810909320859220511,11818016111608214916,5394155797349509896,8030151973373835042,1625041823337009874,15633543969773615405,7707963211949650243,2001854328950764951,4131434842146559033,1271766457350500377,11747286109884077710,6575744704951111007,8842196241740639517,4116493555482504456,6638983368653435525,2014597549749797631,9927328551776109371,11046082432612538844,15280437758447960075,7950951254918403331,17852749160143227373,12726192443992767334,15707566837501175950,18317040072728984100,5623428880311390159,7492375688842468625,8318133796035527588,3214975415326508186,3448210485314416899,13489100308768882283,2374146380797446199,3376837007608321274,17943984464424847065,11789693699192990922,3348136870251041723,4062031117638911436,17574188770989418572,6489304278545403125,8526360151116447714,10837042541776511123,4101108758385869339,3837336864846036565,8113564258271501442,5011184443001923386,3789878866042383836,15454322085954217180,10066926663871905047,17269971828869023772,7839599380774657112,5779291377810106932,17875142369300382771,13540417720346123272,1274945914653223817,1698669739283850680,15566288585037512429,5019897980702579561,16763624354860421325,17617583962867976887,2501035354779154689,12485811584966749949,17428240542759460179,12345801069946656186,10195218624405596754,14351403702981141499,6004341160859912718,1364190253033893238,15796283215725356113,1123583623759149954,584189104176586238,5895111963753146628,10789040748606011544,5829158575615694714,6463094810378857429,3689620805564337955,880290389662344336,3169102536126585608,12348767807289266235,12048492300151565150,7839108284490126735,15040338472160209631,6796558104019535410,5741171491152781341,12499346748392628185,17726474622714223686,17487319158857169522,5269687550643992471,10794739121125989909],"proof":[[8065635251923292097,17514919730054872381,2841269420192760530,2095154164117032380],[3077993298256830730,12939467787428729824,3362670740931251594,3393468914856648320],[6671111377699149479,11684400717529370063,11818443265528315260,2639889477205904238],[10934649384048679702,13832409182824507831,6831291047985636721,5941170304818324],[11194907693665501387,10000755834912637479,1901715547456259972,309486125267809630],[691599533256940751,16636632049765227124,12406295229909037314,1360021983190191714],[7647991064151427669,7060604869986141222,18256373296747910675,1874219996238918223],[16811679841022741031,6051435241087029659,14482645679736285732,1606648669161332097],[6749417622445779427,15811057044516797574,11683726509721346128,3359379759309590124],[8731331459858555400,4794785011636928767,14014502162874431284,3215988054991918654],[4248797211813909895,14040089604235735473,15599987940746318338,84186887586394144],[16487596398035217804,9647644250171436371,593772509881424834,2167801526081690019],[1443710191567724466,13285942274380957982,15597202445998108376,3018040234733100453]]},"stage_2_query":{"leaf_elements":[12917740876902986489,2798493139372662956,182816508657318693,8967282123156076745,17284074846325982011,12932616076069126041,12485772463417974063,6611610923951138746,10415505115374235713,15220981455279269982,3223115582448734169,16031237121944296974,211568238902401154,404987941762188693],"proof":[[13301335903971025884,16149881946828859285,13402336888492095518,2590876910622839082],[12816671722918978445,6785256017075321217,7045820044467482433,2933331681328164041],[871600790921702997,6233134678242528500,9788829052778325642,603077726691273719],[10036708434682869569,7605003664988386693,7987686694692075998,768679579098545922],[12800748781940793137,10781163070590823371,11137162588734285950,2121620651428131502],[13113801492376713343,13369215986025321598,12147662991293151397,1149001748123946861],[14573050616820349221,12406665978477620232,5066518873176930928,301079241976902908],[16937440436493765827,3424229021270690107,2382985060855197533,3149585940041769088],[9648559609763952530,16523746994175739948,4076193922027599233,1339863291972475785],[4048860296270760677,10654584233847122785,17658554602779271948,234782811802859205],[9556326280020632014,14622049087127220127,7188791035379400675,1318738925078166584],[8763095688229377138,4203027844693350601,15839287648717765419,2464465881556052390],[13192953421021811020,12135368163999496150,16519089414246052774,1297301135049925818]]},"quotient_query":{"leaf_elements":[465616677272876844,11319752104113346131,7597582457032679083,10610538788425563739,15068217507975025388,839747963857782835,1200123563916136879,15134075312039220209,11799997433370690621,5086401052403502286,7039218810410509848,17949686630207623392,12594082339486463027,13544191265063767246,1203721928401459271,18215184218459498962],"proof":[[4252816258206111627,9292129838949165111,943872780049401181,3357377527567005167],[15356107957572576228,8209920620279685510,3540543346517100175,2258930650012963162],[12271434124335773312,9286116666932381380,5616623095625621502,2004056420777073394],[17158079170209543604,3997957830231871535,4199889834972118272,188530503049526263],[2399465445330442756,15738996769496691104,16306586802952455558,1312021304135174057],[8193627733436817687,12754032769635347396,3543092740589951216,1143759576867300170],[4556791682155364618,4469240576795646791,10759402592819350690,2148680945946376131],[6052011947747115591,11431835354516860541,12922276237700862940,3005703562704003122],[4445228737098014185,17026879312714717423,10345194716094813465,2972546250557248354],[14911493800648682030,12034837643726087066,11622076309937884365,823795144246392576],[8812185660268755303,12934107594033073921,14594710797974305940,1970618438189651963],[13741377562277466111,1944538524945591851,13834278555587898987,2841913467563537476],[11100972887232792717,16842313487508060518,6071017510380834699,2105986336062779306]]},"setup_query":{"leaf_elements":[5819662894218759526,14567403039901330184,17527637865147891974,5430244614216171339,15293336234540272089,6097365879086149292,17882966231553552390,8813789751146913636,6677293813141474096,17725225067626873188,232000831731677746,17717133711850108902,11832278543594856958,7178660088096439478,2972178005641807889,448324806590069609,4661601423033879495,6784133508293763995,13050267335873547341,14610317053801484875,3612330163733682454,13921549839710652621,18327664736228011349,3197949094300327937,16232759288273988100,1135473910127538600,4252608059713568668,8049476801513141894,7661110979832552568,7889136920095592539,10565047707182285252,14214206120114714386,15262795854062193454,2555135223034114672,923488922758269231,9479852654674285990,12512483071134710112,16456436303422412441,17764166289733667929,11179159787845392966,11657007745265136727,12904125692802433277,12740942851155276833,13279188340353458221,1809289074622520443,5792764325096415624,5258534504232031184,6242274291791061781,7046034307234469693,2510143579222121657,15297799902100339097,2264977049038135456,15680060418289537391,1285092396695679413,10141182806296893590,11341022588597715334,16614755611467798086,3473682666066342232,11453530262216729377,4841322735229027205,1446785515492040244],"proof":[[11546572517259162216,3369164934597632025,15614107082093457441,359358591873546113],[4198041198968038593,16659249563319672999,16933798821917410272,708550381536950423],[4052275201067498218,1467272396215196041,2634479397318185323,2722774346483407855],[1138754717332223724,8998192920164028934,7083841562005352205,3485042706785643991],[13072869267535295323,14673257813557351599,12023155522621164575,2133680685351324203],[14736518490650420271,14461158402246155422,9892808841771340917,3248347951629415804],[11721285952815786128,9292034692898110868,16644406612841740392,1591729956142620649],[9144764718129318448,16824722763977984603,8508521117660693196,3417303369398421873],[17613823959946941782,15422043290643843880,5308430791448064798,209089946280225789],[6655436725026151787,5261426903001576465,12735392084318986460,902252469119205088],[11428864581181648815,12611799512637801373,5370448499064147956,1416033710994386171],[1625000981274062376,14334696978480106348,6441995967927892212,3030286209213344148],[14895236666511632273,1399194341617175758,1368280455654082000,3365187953082285783]]},"fri_queries":[{"leaf_elements":[15066654569836798321,14859402520864080354,16144297989520081400,31563161096723310,18058020377217187134,6424629234604838378,4660759429505145709,8688088295163918480,14478076076718851870,4123889785949587958,6990596892515560712,12495642850501118796,11849438677702813841,13013543870281513245,4757288454547020669,8265018080988359123],"proof":[[274839693720320368,10960662663321606151,7641653276770111815,803301155953987299],[1513861963754839633,18192665720650270561,16837421300331753970,33072038135567621],[15920907959121698605,16646217317516398030,18348425236910775489,701396968748223125],[9628335659072867494,10734619594962654627,8628015487047090815,2019222997241132474],[8016818661213428114,10861830256262736801,14015371151169018705,3005216333144095793],[4926925710469094944,18374657107725105406,13296810771716392518,421627518205276267],[3355396946822226001,15837241923345079988,17188534636111513863,691850309568703126],[613459326179506739,2324040073875118185,11972155232303911763,1528656241590597161],[347176974939002625,7719741817708622723,14418590971901590662,2029569711632894471],[4902605877920861213,11701332700254187564,8706248708951556531,2700469757148440756]]},{"leaf_elements":[10633403515774017449,13637566241263245393,13372791274910967004,9041602293111951117,12929431112657551787,17281729733346203221,16322555810331997117,2873323472445684955,3845468584241883703,1828593885063641179,16049062456097558078,7438953176668991740,12068475667667748195,5024695186481295214,13643877734462364006,1991605463420089501],"proof":[[3771927826241672530,14093823981275130606,4247885213195087828,3372405195984894094],[12551298466438789212,9236347994440695514,16093271466471936,3462601373620652658],[5392917045405381209,1487675981312816052,5697406694580600752,365780816140201001],[16110639326939105299,14365603980961760813,11377919323609459290,627961758965310213],[7115416922232224744,8146080255954698009,9062846923992120040,1349124095773385961],[14981366453569600762,8751061205393511146,4656728583089136557,2901921338668318906],[18139407998752333981,17909362892501148452,7363527141544631108,2985762817603723685]]},{"leaf_elements":[5089704405242328048,4610293652415261191,6301115028294572990,10966047133026433313,18426995840494730531,9230550097232456802,14942959027480939161,12862176383297900056,15983975016420334874,6776121426712139530,5293254082614396806,9141383582709212896,2578561387502501197,4257557193930842761,7508645388646954335,9252965497429594707],"proof":[[7201592579686222510,7964557712720126612,8260767976594055454,2792518390170497744],[2363389257407655291,14771852290769972522,13544844909431106986,3165032970444982491],[2498404504816880002,16841764584222148124,8463928566302136484,826219200934473404],[12056361099189973316,11445222606787504472,16233639641333485004,1561239046487682830]]},{"leaf_elements":[17729354569920996859,16449461548712133538,15065163420655373648,9804137193794166355,12383677593442401399,10114681989149391484,4432167545295727131,3779701101209125310,15177492424625855301,14521020974475802444,13362237075230757592,13717904117314483410,3196402900380536253,17065120679399165829,10990006025068578642,17916730893864383515],"proof":[[10651158724031988562,17385018956147728316,7353147695606921272,1616320887286571537]]},{"leaf_elements":[2512589913085626850,6670100345702245078,3875769945896076457,15189048974320662278],"proof":[]}]},{"witness_query":{"leaf_elements":[2187024112951743175,389206564411409500,6644957619314319297,4719008842232419219,9923207349656499769,12587678017236437629,8294251625052904634,1197593320593654429,11314925163096051685,3386825916392678318,17154827093124990640,7514438365737866350,4077397802270271618,12117757039007425794,10369617740770423029,15740188635641264752,5264027648551945300,3747234015324819412,18302743617708656868,11457181929095703870,4793995518702485999,2991719821909562834,6764842117313876301,9635760555993426192,9890960288976730635,9417988864714122540,7390934319667907142,2155263759883337375,5539022144712569500,14971841681803130984,13257974203548537708,1627233345540433421,3185168445642718616,18209694721905127338,6972410773164384719,4151315691103509531,3768152367238350164,7508330546160761706,17236738708207562649,9208660348891056034,14256300095877094142,16818336703118284228,18352292964038706843,4673711840562364962,6079760555506522151,4885954418811334891,5726704043522958898,13867396239395583220,564348504265594306,12789380605067280767,4437508267745596964,12358385068313580646,9789262327036212461,15104549709550124474,10383844712222445343,12758322324754476183,15606336802227623843,9988194312996518832,14290625041617347929,1020680376221276070,269369194019637307,13267624637049519398,11682108871591305863,6109965585749787192,15409527904345167005,11472389373480704757,14884190096435378228,2716658108799466386,166506142067490281,8588820458705292889,1911107342921519056,14360766409074671310,6800922082814058659,18434498429756433343,3527620612853453756,12501526016114657418,2922056334237536183,978898422414996741,18411082958993446202,17273061748252946619,5407467671571037569,1863913200623306982,3151595203680308090,1745813611405779478,18428241529177876621,3420842203729187865,10314999698484981540,11881172624357614199,1971237503627022279,12498336259764126842,1503558770691810780,7674959188308277985,8338228876216979403,16574193499621571301,6349940208857659755,4912356238269133818,678928630031422497,14138465421825369871,1772727353597793206,14612639684536489743,2051039725798607992,742524306990381008,3324043218151323285,15435693086940471665,7606519171878351349,2805316018013102265,15762959376703594321,13595772159517686873,16191470728309548390,4675919408263736981,10218168140266687650,8246202764459854961,17680452518027921471,8815352274208368635,18135312566034252416,8437769872859516420,14205147346165829173,4552605937313600267,4926947537951629962,10661667634982036883,16186594537338502651,1853029770952492067,13163878830624011280,16115892460851871878,9212038113622413228,14026014396559686949,12713054030768950071,15109534630925004687,9035084928711454321,2907466030066403863,12819379178632849395],"proof":[[3586196858641413360,6122426049232947048,17589405211711937572,3309840293806481998],[6875387195558594401,10194006291500302984,3244210814208371895,1164354882021938299],[4310774034421049840,4610312669445047810,5739726215502576454,139128042245293633],[9902710023190555120,11408801913224912707,12414253137313131329,2144260551113261681],[17580747087323158802,4377178581846199831,5069170579066984624,2458609441830847436],[5909765416057713619,6852531436660942331,12279037537139325334,836598839765877653],[10742639536128603479,9317077929744470204,2949871061783882005,253458590101910777],[11118906575606791733,5703026334620313599,18283905212633103386,1152940985109211351],[883834146545005694,14502336986477664651,9054642122190665562,1622670913918553974],[2679208933754938042,2381272374693791184,17610662853409612314,1054461821651762441],[9151718361097604542,11273441527300137089,10033571517675473104,1109114853531283164],[13836668906829710369,10341401230349416198,11163754085741760243,3218002454189563944],[12489835289634896400,6436027295365327603,13835359195736637174,2107156744221810711]]},"stage_2_query":{"leaf_elements":[9418354337741400929,16999094112014325916,3867941093132122450,15947668571674423645,7709758591106157297,6114497364487128919,16401021287023939170,18280984662756008374,12994719188695796225,8697150490203470889,928210563085379036,3587346937918290293,3518301097017610610,1664235546552981291],"proof":[[9407347896749869619,16194571088392412800,5109227489765617110,31175554995320788],[3117707595913150862,534619769165606406,7535610590554456873,2703771999761141674],[3980949612726137727,15624938739210316050,13619745477231213592,2955313286049674314],[16029522244330997492,2948531921768966498,16236942298679450727,749080303735469440],[16318245525811880900,13182988182851294309,17848226528810643700,1615440479366872622],[9812933463152658913,4668148658767669234,5656942889008838592,2538393308938002793],[1637087596550566054,16302654485001832482,8304302725728973573,3309289792542561626],[16094891269859452902,4350244887446145212,7102572066219114207,1604939959568099983],[11806312781421923461,12462845796603247095,14788536926934471141,1407630956995008113],[6147335282240955949,3696040991488513544,12986049670135589846,2830299459304505435],[14490740811161996927,3628714400200805408,1453346564145070167,1269895602592864847],[1588122855051381316,15986256495690246090,15845347415925917050,3002469809967888056],[5088184440726532484,10624519551630831941,4139449485439259727,3412129392071649693]]},"quotient_query":{"leaf_elements":[5588144395338532421,11438963819293285583,16349464809069889490,15063086010160979174,9902195544469731537,14652788419310354203,4237097549296461678,1378724871506719394,6890124023000065653,15869732242756391238,12938777277863067709,9541570340167365277,14563362165345957314,10079257020039253036,12908882297161862349,11166407153558519572],"proof":[[6144386806189431930,2747401413825151334,15296601985628704268,1312624280968563107],[10641371296486343189,10143284844261972150,10782126367910852796,2712806796064130230],[17713880566312896785,13533611391476164710,17388924033066521326,2749156045443226602],[5761635845000697090,2298281648571901307,16863445115582358295,1884857424426658354],[2932821334605889118,8694766465698227945,8761676985726368451,2700824479231176176],[6450981709066857906,14604545805723316536,13696103863984530034,894936243627926476],[10207371642268558836,8518944451360068026,14460325848107454734,1237668562775882337],[12691175024444354131,17239909912624774925,3134539748875896465,30964342674361346],[12985044385316325632,12846586802475920882,4641653627022437039,1361994546599845554],[1289195982411627349,12698588624025658034,7144633838333646047,3296920615551251496],[11121985568448180963,8201231474107074724,3483138072113700302,1888167443751953967],[207043033235468965,17758881744043525803,2123779994158588754,2204467661134451222],[2206136225417434008,2701764854394411613,5566855779015492723,1850531030693384592]]},"setup_query":{"leaf_elements":[12152233131232690247,10428163972393501038,9042419624945240618,12814233191143472786,3225195509360269562,1416027207940941981,348150063254589126,12473512859421318265,13190130576125633059,14656298542098137018,16850644259226876739,11895012901085585924,4898358146930594291,10529968263984071809,15825481967350062285,10036837590280850156,14061061680001339755,18445295748894935742,4258267176344398856,14943858069088881058,1717233597773285630,8960329990746140293,414984571413689194,9764359770657698849,6614953633917325501,906860897329559596,14117723097140283032,1433272579609596200,15850027545300661530,6702025051315398599,4994834275589510204,16580903427890136206,1428069781727582978,2272632929921522535,1980643452150727152,9807445401610607881,248367753284851747,5510376832353921649,10367452617141919804,4900653246137654489,2115819614522998969,9137082764664689868,2360969300193801356,9208984212680397043,14124094701705891220,7195025778993325810,9059787544944055188,1190032361920245300,9359372800169555280,4953657408954976553,16010312587745972776,6917044386013705312,13498626995559504047,16568697957753958941,2889420701522630539,12009559992083251977,16522186956193084809,3432032562071978211,1265366894137738314,18384965130054195734,12346481790746900832],"proof":[[12696596769644715982,17333783599888862091,18091847544190898288,1230325442793998529],[4509630059266665097,12578379825360396328,16686781503312749481,2798920361226021286],[18231257513967802729,16507619633499094873,9826434896227798700,1072460919903019241],[17504338766697481834,13104087426041736717,3185255795046764589,2145381936414031104],[2024786622910875432,6433162772613446850,1252763967353578852,3090002501882924481],[5656235721764947375,1445277791411246584,10254822864687509745,3290647037702944478],[617991043807407334,2660645427023045178,8117492593619198698,1658657704006189764],[17700148396015638622,8094946999967787175,16600294387811029466,3131468935263753511],[16716536920465424113,11614267213631418966,3625117215440609164,2991057542840667552],[15103050277332389169,14735972067864571852,7256877003769283506,3383030611167601140],[6660110760056497000,8452968119520856605,10785636027562208602,1106781653452192485],[18247657968427739412,11980466839669134857,11851357272994488667,2939293211808769075],[9160595042059558321,3003654428390274044,17180942480487853646,2327618075865250316]]},"fri_queries":[{"leaf_elements":[9997298567413397417,14730416684979584855,12633510465035351702,10954959087245385696,15132143631502628139,5698623131783046664,7583720159139389300,3081221250577084554,12529282711593343279,10536808961980441777,15864920210650176072,15694432659749732316,2995416574887580449,510703140930233511,14015033031964113980,1193940479632390737],"proof":[[12666972196946568314,13522902530809207745,5236899636880422574,159351237629273404],[488953494683537852,4391632383749844366,1177613274060560012,3027848890386019940],[16158335451246236650,5894279972411999414,16291809278054474316,966408040260163570],[10803220491509031480,3138603907894112885,1915481855243042050,2862187843327347984],[7391103650746738797,14726717671530411136,4610220978370012360,71703311237530598],[12691761911330496570,9146320363761364587,16188787681721704773,18309908416201573],[7382892552706603842,8767124160418583297,12962277305867411009,1213868553077887362],[1084128502492236214,17995698642344495368,2675199903911190239,3049917355373904467],[12403873574716195796,2349135915077416510,7468767277575460203,2092587708709019038],[17081479404112278480,617184671756641223,8216228617306694673,3379202153544912932]]},{"leaf_elements":[16242347422465709442,12055638080331459267,5732493272644436189,17083199926943365333,9453265574060680330,3682078813550250119,9841043430010912324,6567152180296725097,9235069665788421972,3905034326925758638,2905375563459656237,11415269221273774233,15711655339384831074,12316266252274399462,13641737660235459884,7154622704746792312],"proof":[[9343569741156372666,16035219319246764405,10223259757549069377,1909529800133067527],[12309857784420283257,3768919279625525212,5502528179208337120,1300252213318145656],[8476559349125885919,11931432628511952664,8083649267774376009,1931541153951705534],[1511710025571455970,12937432850323306391,9797176704949665612,1729630259582461696],[13611229207882295436,16395918807524204430,15089075286731819298,2737228933675129427],[17169716515783796911,1500806662997531208,4252073954974278456,2343125948170061068],[5813712587629336352,1082708786045461569,1092112838582383375,3425941116159785480]]},{"leaf_elements":[15429175109220991098,18414013918312540351,6204084562062188491,5846276514714138351,13445828703121114356,3454597414282645785,184539581779419670,8609899297496508365,14901317364321151430,15676634699356902132,504759763014206749,1862371919961355827,15431120340888921718,1806625636610130643,16997341141391806046,8673455573797049560],"proof":[[442195020894418925,10440362023130517719,16301671275770156330,561440230066692351],[12440136255142106039,9121368262388742986,18248593802323231034,3138111430316840132],[3654369732084213993,12432004624548316494,143217563669780288,2095965278091705794],[4216581162791829782,12611432400497020496,4291082047923264811,6403411685447305]]},{"leaf_elements":[4311699445297929499,9806112033748572177,3539043589198585194,14593654441266355321,15762928673565885253,5932108298477060518,17925124669056389626,14193547706035909747,17259293125139773774,2442827444727177921,17080903217978581511,16105909017897668138,12320793498174218612,797232347842516762,16412067898771630043,9571229727132115841],"proof":[[6720710772968328146,8869646766528407003,16450207532160375016,2278103972111261741]]},{"leaf_elements":[11323862628515517922,11439196860937776991,5413344540181736252,8741335607124726181],"proof":[]}]},{"witness_query":{"leaf_elements":[4794812290847072376,3402700122811943313,17306040371694263478,2125761926033246643,15080923575778846898,9380470803381054521,18385787082253573986,17404099306032026840,3922424085624791384,9384794125534551459,4015385287252231485,7737109644169585241,460853033762178177,5376664578050423175,17360210434722280598,14985990135868777698,9507548564187404110,15181368758792457445,5103788172042098784,13616292781325460438,5569522697619612740,8769142400598739123,2705949170756326980,3500678716352618280,18029309827549193087,7900175025279239166,1573519552052719938,11464770751308821205,7173018529905308438,2851960260192948685,3893740223101953568,1474651503426312293,9622772209646787496,5978605045195862821,394727793150576061,10406750588432943170,12300310449109311087,13350413157082636204,10330350424876488785,7597607997035195948,1678374219481539238,8009444003895675709,15998909181916306694,4910683199105111082,6467333536542852385,10174995694933978923,1882559594068028294,3300483711907113441,8205795456578610941,13120534197209162154,17345421409302209612,805422239725528741,11460789126285088082,13497292966876416522,10055550879232235376,11874739519429908645,278746517605307485,14146629457214797876,6094167768327555525,7494883169156068230,10170393907722395901,16962723380960334891,3266717485149503882,9306820771823943688,14575940205065034512,14477690275119450215,9116155535664914836,16913927870599760670,11578986172558740229,8381379976581644763,6064816339368303949,3161852286875441644,3684706554794141573,16399157839950079827,7594890478606868648,17987471108873556030,17253439374866190168,10630124599499400335,7410857338707420164,4792237616453969879,7767283764815809811,10315300750758412209,14554293623971124693,15086621086583637252,16645648046429745856,16369681235218154625,9431278883517111985,18195328317553585043,6208281553517787877,17267913356527355839,5961200504201007501,15199557799419130310,14392682717921532886,11301700538454068404,2724625553238579007,12043706759284823881,17594259472649614827,9026862426252744869,16713097010491013522,2436543605298808060,18197701189429956826,8709531706017690071,18400097547414274274,3296180596695732951,7665746991799051534,9626142487232166436,6160566872604921193,9770877745813989447,1991021582113324508,1014711568084237695,9098240845529415405,7730287056137856469,17192067455522307084,5358887624143095571,12165869421908824667,18210845062559100722,603036923350228527,8944643219866375415,9199803374173070278,16130384517570444752,2026812180538255307,6936275747947002830,2382552808087302021,9089357893716387310,3025774032132911860,8994925846048111917,536305326311037363,13633848528948856860,1539746565907133269,8649196274251363094,4663166836637281340],"proof":[[3967423979110041365,10891933468977737198,17470732313359386518,2751234033749222486],[15075349785818419563,12901198879538285996,9210593194092908991,3096694171594909907],[8486230560414034546,9838028449554926487,3912909785762411836,2163145425476682801],[2373086203760223184,401420107110475203,5886464499111066554,2034534311578850638],[6403498361852889529,4589876402872000690,8137414073929488258,1917883135313882013],[9441984223027613154,8157067561483479195,18414438335074579785,2546607660425388472],[17316876995498354523,4748957689327344667,13284046720271048510,928885099994079151],[951225373107165794,768387216045759330,17383664143899005942,1881937011703967080],[2847728188917774344,18248905509197421605,9675431151234982750,768754119271252035],[1491083142310928705,4743998026436318626,8690645089708143382,3358505118077473740],[1127030895586069538,694780759772484591,3687000931591563247,2750936864721522891],[5142135479214200327,8993737624634604378,5176462942667777740,525546059952794244],[4835930027315713455,14567191116503688260,9793062311750296446,2116148360242737249]]},"stage_2_query":{"leaf_elements":[8961369842096797827,5044044462099493206,10075456083467144559,1871751159863520128,11327825544810868400,9482782547375649819,16794254293386429268,10335920364036220071,6799508312216028896,5173084863255363692,11181954314901219335,6188980073009843577,11440182903289456961,2096055433319163842],"proof":[[4873264470465648943,1336303549876842246,18352296764469565644,3138789231669096564],[15914444318296376185,9611463257490039740,3277311775800749730,1833314230224480268],[1897672009209041574,343142558455313377,8435028482485434671,806620885723056704],[6929417412780639587,17264317340775323801,5268246468882747643,2745916549060885401],[4846231526970815644,2455312704950148592,13065679153107471349,1003640906956858832],[9689572478915353525,670658642378254341,6277177613469139920,2142701962383092018],[1969815318222037942,1614428619223595039,5039473904608107043,3244305720215407960],[18319699833045368328,9058125677857677144,8910127398458562694,423785635917254777],[17799434150604765802,6197796014779576268,12802748503648213898,3448545837040956703],[1780322833747596479,1745603590673318704,14851741195976123353,2791481713598494650],[5431947802106662554,5443354384023227846,13897831674897138335,1596310562825674992],[13174836754061613523,2244801622794592706,2243592228159740092,3224233877026474973],[8400976163326016007,13459382111531745039,16189427956558551098,1917620776118434428]]},"quotient_query":{"leaf_elements":[4489691246679236361,15250674627298475439,17438921366469849567,8060785296940928684,13630794848678354232,13290279515098916648,2969891887456658713,13728260210849971811,3428917160104439190,14642547279170411473,8700246693529926567,6527617765047433032,6365418386912933303,1343959230690247533,5614606079218955408,636547293071291601],"proof":[[1010308371779747913,15856094189714979867,9449699613969956772,1897449347393342506],[11082186515617071380,14352201859621759244,12784686962070037099,2997855059672377121],[18033719746498087718,14584728510614161321,10618922676590854890,1412227053131342184],[263868730010762457,15352625681423809705,14365360907405160402,2093841101759990757],[13105286508213018328,2580633654417109550,4695996779116304730,157839303234981830],[14080699471343723241,13210173155800407855,3695403903300669426,2723007097408091596],[10778956088513994937,3447048356945368982,5090402529668880588,220920962680807665],[978284616129456794,1678856283605058346,16369396634473963555,1114324772619981540],[3727469774085492065,13345937257991395570,10774064402505471839,2780933401153353140],[15245179022544431283,15996947075174566389,15677302735640011105,836503348099231366],[2157695038304941352,11191783211948267574,16678180536735649302,2113735272830865899],[12727463944066686440,15031778029241626609,1474235568906382933,1585885662917994428],[8560803622457089329,6576268329716751604,17480918290423520249,2783826331117575223]]},"setup_query":{"leaf_elements":[654715951002420855,2756207152671953684,14992291614043552317,14604693182198674614,165340721089819543,14312685686102600271,14748242035882941644,2093577536787108424,2616151052419095972,924331704058553300,17880477983468728725,17386907166167570819,11175895719290581389,7369175114859271066,11061399480191987709,1705995205148405785,13535940411144141485,14844662175415764954,17933400887651107404,327787634054126853,8438503379235845753,13561169673601031972,16052891578982972094,17141522158340426701,2691614907843347718,3344433873252208703,3961125078251992673,11182027221551687376,12336521534747384213,15065044204923462110,17521756036629321267,15439477674579938115,5990578968551381657,14816625993122196164,10990159240857968602,15877993066037242682,743229685298852725,9358392907676897379,13935979041084937179,5018186857807639739,16073257205594792088,12375736309039991312,13998922122499340631,2410690484180393561,8111019467854521178,15609647931668320257,9648354226505630126,7034201518080776558,15337618324336564331,10153366001896398853,14298043512080013840,14436434437350695420,17727858438695536807,15013878655856068782,18133554105926877980,17026089606494272119,16517238010516451720,589035019923420874,11307549184288971225,18401105034920779807,4544123932010603949],"proof":[[14581114440079176214,5436124821964866565,11988147712443544638,24275183717989490],[15478217229768585626,17061868033674519880,1524092403622844235,1739561317347703577],[2094805968763519212,9851053379059142207,7414660424906329275,2638499906162502848],[827356899773088351,17892376740243436133,3232829597089526770,1602458267545424273],[7785261090896837038,11537872495082681507,460819556830895160,1467847588049258682],[10454110689457587477,9005264394842790885,15395464053876710466,1406677261520585427],[11329184216262142715,7138465386973014600,15950532199201476702,2382475165635371137],[8270517562570575673,12138127413586094613,4944495091895858319,1974635899011333245],[14171156779967806029,4069843521041944458,12707813693797670346,2222893365503597537],[1508272923037230783,16599100383134782183,1362879958019308681,1877044066528613290],[736051928442084714,13996136793561635304,16064150511766965841,1622030257075208925],[12569192502573143015,16626706419100452938,89526480532839450,1151220156167419616],[13233111940330375337,3721613951002169723,13215477271364309671,463369196759619265]]},"fri_queries":[{"leaf_elements":[3634382256837446327,678556078202697093,14567667105972145854,2139730323751616797,9450894091382387179,9798186180702960371,6753527883773811015,10386830703073313501,15894115683367821285,814061718109837812,3401878287030072734,18249919344317525456,3007318781763986731,13605621355500120298,14802115159937972119,388781687240983942],"proof":[[2508608202904545375,1830335936559776431,15302592796375996005,2706305195269910507],[5371270594956437813,1991187090795080300,17284536878856747035,648459286712220161],[15810993595192899600,15900581848478638272,8375146548571066433,2672511459427246016],[14797575714013877757,3439588686538012081,5598055904637726331,2106956269934668854],[11267608028869901555,6311550243311407809,16527448107197168200,175413572045004369],[16427895550330449371,11278530785499398509,6665987420855308316,1333853721747528608],[703281410541162485,81937716967863994,5758883802304623415,2377962109147460982],[2945639535046352386,18040994403281453872,5996673420161924372,2821830344895488563],[4804235064255669216,14729952626711900118,17533787292596999691,1688029707652464723],[10293913151203782939,17276720635789980012,10145594858043310023,3455109967926550842]]},{"leaf_elements":[8366701744004785783,15628611283176443478,11406719114818598673,1390367681087055963,9371849085829210196,4561045168953537788,5011898733450589523,16483680388971281211,14320049873751075641,7021195730472576769,4995405322160358723,3376187916306918454,18152608913892242647,7951777446162880121,14450155724471379811,15438334897727114120],"proof":[[7229240363655270191,13979493989196298904,15225995018693303868,2619082390587546791],[17223868907244390765,9706801894740324984,1179463483094816448,1850208354962886454],[6386801949145623058,17452238438495136999,16649417074709082193,1480898100004536857],[2577807755405497397,18141355035645237622,8820516844858516269,1868509288398581249],[14708966990010504020,4452105162794639184,226325883480207383,1404688822222607006],[5473885783605311085,4026771276107960446,4742656884502189251,2192188515716722929],[7407740297327449151,1602759275088930253,1080223580461385578,3082418193151690999]]},{"leaf_elements":[17356559651860261601,12725442532173348047,15597425032154248096,8143773272584448380,9651626334201672884,4452841545941158216,16352824483281747528,12096256978676876977,16533960919196670103,1267973754278080950,9881509445871888062,5400710465314869476,4075577429598672956,13199238483938231281,12280597211204560789,13807198767935685743],"proof":[[17906617555350196716,2697734889843229528,17760594070209285177,3176982764010391975],[14690733459800600196,6625699307920514996,11949566284692742831,1050059442516129033],[4800217489573654783,3149554734942641022,18307580925378185476,95013896439469199],[12700299161953849936,17896603572231004330,16616459751671690607,786280160165782906]]},{"leaf_elements":[3303258396085125681,7334765928689504730,14735023820760202469,9619724676555854682,17674259656641861264,11577514084267056637,2440871980048415777,4361546825864617734,17764661275648454126,14367408337706981883,3009606633506689442,9303345605953149770,3068930268487580864,16855781256128155135,10975044962187852064,14887023502175238661],"proof":[[4082544563390657584,2428803467750713898,15919672509928983616,189310895045026976]]},{"leaf_elements":[6485988802393016559,12130974100501667025,3138003141619716888,4081174251100168420],"proof":[]}]},{"witness_query":{"leaf_elements":[10441288971292295433,17915497541340984965,12183533981135018629,2876121262988853464,12941558902968296245,2017625944432514172,12583324681569624582,9475707861373091989,15781141593993067518,16989318557516906310,15727265039109015850,1614349164792710854,1425451767875154556,8855396234857348278,17318567464276033146,9509827511423477415,13962594255007721596,4855675650360295050,17075645390886301153,11843126355658419524,11204988807196534033,6634425965172464825,16158141471928045754,12429354392002865058,16833735378481475467,7089894930215414637,11424687612046741813,11778439194884382180,5323792409102953522,8107932692828511897,6520271307613914836,8099151931313242550,4664788281389718475,15772773824965237914,13138370542930369061,14134657431467700820,5481390696692761413,4027693326704136334,7239553776751714467,2915331181175981980,11451264883670035004,1348292442767293391,4914236571767510300,4368195435823931983,12376776675452089602,15396198352272162972,4051047357981936865,8675617902053325252,8671100091905527590,8571692572927633792,10657370402044274394,12678199582059124960,16044680046336426833,11670966514389923340,16512688205985569715,8751873508177120214,11474106169269019348,2989550382556153886,12671623363357099854,7444397507045461132,2695281703244226346,9245954542137452453,16034167624214458455,13574447909873742229,14302111357081026842,2329071524169455092,12099899562501749359,13295272910787303440,14797187074382298592,14410915403514360415,13085289268951429479,15185472338735522422,12878807870424040289,15275155281481104311,13098836497194546153,8801248851466114577,12053902962455243831,1684487544071972247,8658464880184248583,871752489763879712,10836347060232984257,11039644376983212113,10398025341616357070,10598663728546475830,5208343603399261356,9827548414901928313,17699323726087516536,10256183557477221521,1378181411361468407,2412359952677480850,17559806900357664665,5833182312602163999,3255288528664639301,12171702508416303748,1612680768387248739,8952259615565312135,12221210840059293026,2034159536254121677,15066103180851370266,8495464367671564740,4591501369298447212,8746775386761068240,13197043357337105008,13226369267541904033,2444402298621006340,10290249225175849489,250140927209998621,8264915684460661753,1816999592884289862,6841484832213741780,17254362835010868190,1492702088030496170,13937700219909507414,9743480992616047529,4347304833221065861,116936805331551015,4871116698002808548,6226218933215306898,12343533440183356226,7135830823403417673,95446456667799293,17504168943742660368,3178466029955973324,2173632219272771253,4903741774307344968,7421533171970598737,12679470112921799206,10092348204257306973,17440283112913824862,11103153851399171605,11055239548814985250],"proof":[[4699250703705485833,3497480500199251677,16012171368620632965,267785348597550134],[8320480837701777703,15293332390270494964,7938295797212985898,2575901236272786493],[13091293067392077644,5388665231591625675,5672880940715497689,3408023635516380006],[17670347421062818010,17984843508928894942,11117666642290460644,1104555157145930320],[17704831442433588956,13532974725315024479,10286786853934890493,155391413888431729],[1278847935949582995,9933576507748013785,14671360377446332574,715544282950533226],[6006421457438298005,3296356121490711055,374492831520524738,2864276449302254112],[6434073621019896017,2521006277298542770,11820076791659153035,2589224354219876373],[318734463099269121,16247265767652072325,5586884991409057136,1359404956349237016],[6564565267089994989,18086740306331707935,11076902215968475447,170431649390530249],[2104366147942583527,325656767526212637,15687584321686934317,49600423922309603],[7410073984382977025,4983708886626685095,5020934352287608280,2014256418271613005],[16780060758106606046,11958032741938148456,7312416229524187577,2063252650720473744]]},"stage_2_query":{"leaf_elements":[11325580892662938550,1170330941686906088,9866752706607958579,8324390300862744820,16891529423787480726,5739682475739262069,13522731862691286894,10887691608383444122,15338660239089519191,9904141407117210737,9484814920660970172,11095737198362398799,6864753783882826683,11764942849671209727],"proof":[[15510091311763773113,11553572772704855905,7119668993070085500,101296617004535422],[4702156448568351978,3013393253336605912,17683646099858168363,1949593092392247209],[14071471335144172807,540391330055438266,9302464383369094707,2525078797606887903],[3869017407857361113,4935679905685175249,8387018173316748472,1672760121028339033],[8774737899180322250,9359851744627431908,5396241290503214699,1450747879987979376],[9097354526608896890,10463359461819077939,2404732069939517385,2151855867169375371],[11261353552534486827,10872167702586549768,11395573973162317307,3046187154792718890],[3310648052425702041,16763823569463245373,17320697665205283432,1263280013613227585],[14915440263737449488,16009002592574225847,18209854225026685861,21730918635170305],[16407414201084028659,5856487983419042992,8374681929822607906,206428409330500653],[14156826419724198095,11312986700954891604,14403898608252047750,432278914041123010],[3071035745069006946,10293589212124639477,8477104568259185096,2274061596706743004],[5354075957868852375,7926439690175627247,8585448747203103732,3454314098108174446]]},"quotient_query":{"leaf_elements":[11771155907616812853,8582126111328795887,16291385587308149233,15332416570368886476,4452881118801255807,11128919426596500015,4924584696911104468,11037620198044981503,7985008780982645965,14902428472163022396,16799448693812084334,2582331974986329940,1718675343945547673,14265577963335505173,13125033177357950342,7225180167296606260],"proof":[[4105775493032051147,1581195832709753126,38394084832566144,538595753458775535],[8559527879994111571,2877135655956800483,13367025715203979315,1072732775258672625],[16024975778253175300,5755299591633974888,4015899474080229324,1720224533666568999],[2065724269674452704,14921678981710629286,573883276510891190,1197652816716705148],[4717376425986873970,13553446900256117762,16631286986484591136,1254346926537223714],[4124205189533076393,14651816032346012653,15250649836103223361,2784870895276226780],[15336237624567894421,13094003253233319803,12452538346433828714,2332559683010045590],[2357094731362372628,6670965375207782005,2561914003826591481,32694584006121130],[14301197184074571842,4586317924748782034,18004667907984388148,2360520765237822433],[8953955251260247790,5205366719339843586,8230520589137648553,1714694091713233336],[5675142551664701273,3964371915580869745,10289337494046890160,1976433570173220005],[3204262288836114067,12551118658643858392,9474083513439660449,1631741663863701661],[9894783286081270076,8285846266767218443,7388875983260854164,3412182721263324036]]},"setup_query":{"leaf_elements":[15333882114334668825,6892235706590567566,9579616598652570282,8566920716741299493,3906495914170383579,11994340857139443122,15843286052041595,13787753044181795525,12743942492400888589,3620775319131705946,16181188823871410384,14764605153270165589,10731654757478170222,12851882971536913654,2047722772662663651,17116863880664477067,15443911129427052910,9361724893919277014,9657493602277946808,14617543379891513155,15038419968790262383,14065202498536387059,11204476801239272571,12833500899601125049,3899111621821647666,308940455012126719,14036211434835356710,8222049451025438733,6581775017226411373,12525197705292787219,1770682548056689176,5719178789827550269,17264531476156913397,5797636751721007285,10730626635537712103,14787848908774520397,4391615444133745030,4592689688203767589,15577155389392291542,14401515165218984196,11657294654316231603,13191892276356344557,10563071449132848315,561706466400182065,13326055232211684493,15705524552098748959,9333309583939152586,376691619331930558,16075585827539137024,6036909378647019035,5765734343059113927,2890494326549732269,15392367153198157535,10798617854359586472,8611895732175333234,2990759152463836600,10375303375683469028,825585203773767970,17397332653582411065,7927624494265463314,8803089978358405206],"proof":[[16409547433303099175,5528029868647200977,5636847344968567382,949531835607140867],[6351665094751831752,146043347775981296,14141991455977147453,494250495692574515],[13761107815868139119,6259159767067610957,2405283246148048886,159181896537592509],[8905475695430699126,7738444618187549650,18183532290161315854,1720430696187462157],[12540149960945281179,10203693293390465084,11515759070592587683,792775490476031477],[13145549813414791952,8969701751003751665,1012857097434196818,2739411173277100531],[8945687620930028272,10479466953866220655,7685421378652900175,2722671255647625156],[4420740540785227452,2362069760213929240,16426898884742002529,1330775225976511371],[389059000842970062,3025940174604674445,142433092389584392,1412882757043183459],[13582922178650608328,1598971795142973755,3307062095683768768,1848385521591728213],[4143417163302399210,6919295008301675546,17058252070951181637,3058865981642241175],[5913934557672547683,5916126773193269092,6753410884991633143,1320656228715007534],[8257498406240408542,15294783180318616062,15553598136149729540,2708965552677615445]]},"fri_queries":[{"leaf_elements":[2557351240199774806,8194980625509229774,7750512200234238046,14268132461441790019,18368891107015329227,12502828556188454990,1000453782745310153,17329517468703486246,5124950407204803783,10175021419002124318,200079656311325759,17921739995308947060,11629509110386496456,4336760091297084555,7024148198220540352,17127976943108725481],"proof":[[8856241023133856467,269020575295000242,18420140422983354595,2246546632807880556],[339306135243600321,14516298689991975036,16097854180543309022,472586826346336441],[958252540141346841,10525897743910600674,8972348084131906857,1811921758585401819],[8978492762040574775,16517203366756177263,7324734482039233902,1297750098974006938],[14047341810604300505,9438336016473745751,15604267459633933694,915743719059199501],[7998225502433280066,892507142418782055,2222197419631345306,384919099489357817],[2427877410394269102,8800044443291938349,12042802347235648054,2405939501116732414],[7566408421467322530,2026118716803720927,8167883592719448491,89407085636062433],[16219247362141681837,16928423012354471480,15574738645971155951,1214143588786176393],[11555457030939037269,9085544040749111966,6591791325541549161,3213063993889265843]]},{"leaf_elements":[9170386245972670832,16277736717669234917,18204185494008552789,4751915025597306409,15180347981472181436,10705430352326798168,13838946948618646797,7441911169689341099,5524827523708792880,17638035284792046146,9965536517269020278,3286863267244447417,11999099006822805546,16886921091942304579,13896996658273947350,15414016079145367357],"proof":[[2404445625116817890,17846046464319150442,12534651349552467043,597884210447167576],[2870484589216668122,4107564706674750048,18347948652833913469,281192132379861017],[2528866411890316237,15688908680329704353,12799197862349595468,1326885619892445074],[11912348547794745506,3719313222777448058,1608796665149670074,1518141577974460943],[513091978522108156,13097094926631096801,15301289754046961544,2329738128187416860],[6427968877227619501,17989961370054482037,1223698676916034283,3229462048709684664],[4849490650414052880,49293529635015172,7888700325494612796,960799201708683278]]},{"leaf_elements":[4708528301331802132,2658622690857129211,744076086777609294,7505959656018913889,16891235882263027000,5709909813535875043,5646908823768456664,15960023083279152222,710662232349665012,8573778981915918902,10471616904827766015,4159095414015557847,12251070783863533290,6159867367155980988,8457318080357612482,5116303239228248863],"proof":[[4413059430088283329,15461370013868080375,7492367997108147133,1423837814725342605],[1653564847119757862,4664741028410705035,10069352778031234376,2832398770983206753],[1324489763447242483,5436060794771051078,6403362546343843938,2197070821733807419],[18214637273193897569,17083110335864207315,2458916006554433768,3322903078046680236]]},{"leaf_elements":[15049793618273264278,17443600347219547516,1587449845484096471,9268301052953521075,15310044983624285302,3137536321055870732,17729664650163897904,7295871734567114690,948242394662532442,4174441826096490128,5717830596626736236,18234818179955594845,6559695840222737178,6570323834431778590,27890742420152916,6071881210060785784],"proof":[[1207514275877165031,36803928778764813,11527218039117858712,1899368366190537423]]},{"leaf_elements":[15915622550061201680,4536541224237163888,16120598048347926193,2661082248244309055],"proof":[]}]},{"witness_query":{"leaf_elements":[10050143888401326297,3306763487459789815,10936458571400063632,3521032038542458089,5696616502223583501,8655784198293123806,17680289626249903698,14791305567519931570,13611164675862674073,12885027322289442485,4617177628375885626,16571148998482760474,13513931571802567850,6768756076536027190,12559229257296706603,3383707506382345307,80087993177217978,549831853341191400,1764875307392551039,2146338708956611450,1712729366174464337,18292026559500484169,16966144827966167731,1965599470088305867,8768048360039058894,7522516836650640007,6183656137313080575,8811984993458484394,5930406024160258800,14649481322037233760,11138553554368682725,1853480816626353770,1483337338768015338,12317675066530634489,11099160306433511356,17292845633566934437,12151142272092009409,4549094909871968643,9482708228500651544,9294652799056201504,14710861896558995180,1175524708710272783,3129794816881099561,29054440571187386,14757705699454052612,13052935267842707671,10326501584379889025,18374564000506250289,6788140747622007273,13544530147917914796,14266096379441194907,9388834687396503683,4344635551019283132,2459708388597393944,18110676177108696552,15416394198317460636,1584215499984249443,10569201434572385865,13861370903879361661,2948229869653730214,15687012016608305744,6114133477013544483,17957713826420923516,17003058962656584263,17669550019024370288,12343741930470655696,16769044136906058889,4537561509879782266,1123741145550077368,540932719016874511,12243889481680081641,1941544905755182632,16996461505744634256,578171865618210499,16330210759414203687,7737979181597966443,14599672008867294103,232442127392932544,13179623726879132802,9418907739295400465,8190283516754160186,3423345067896989103,17579838559942809064,15479245455317199372,11633370735966044303,6013114999225220304,4772054117795748519,2573247747804664553,8120967326840685856,5843592858178927329,4393304783536392901,12343699679569334467,8045952099076796100,17826879159476966749,670069218050756132,1837135507266414643,3317972400720630004,7720050949176060774,2335903991365006860,8722134500289103758,6734618741893016672,9030312774635670641,14049248207206650124,5800067133381325436,17510898104744555302,3839773718822111103,5568954009641270999,15274829545772780725,15523075705984283681,13644340527117090875,4500737044912232202,13829817274570960267,15881501770778599728,16138481260483023604,4069982913529706452,632022926881889385,14011704247514951991,5308233628532941068,9967223072310805199,17922200442213861120,3865608822153974204,5004522339301308658,16670833885540045913,1580547840774469014,10285841989030495354,2538987419435119778,1268567335881651525,16495847953275669547,18266882471791417246,9129215276177293088,6139738483908858335],"proof":[[3543162041754611431,3280051677987735852,15581605470825488307,3163702960166029549],[8630224215003440285,2180494549031187555,16337606513938395250,1706976881106499102],[16464467193880457932,9447457404836229263,4402043553850125830,1696902232861320378],[1503361979782982135,1771471301513690577,10482306952691691402,2921809543014621248],[6892954404364835822,15480725942106912308,12304672480441622215,1457210490506234202],[13063225544877050243,7433325593677074484,4723654136779631593,140385148545544817],[6503472885804734620,485299351703072395,8116392982228511831,3307269945632889492],[12580893667233074549,16679380852349264299,13911458679765274719,1159241673002549311],[3328466614558684682,13356824135130290333,7360552298769640577,1515170122362749942],[9162827774039783876,9058377120574313965,16945724347563852287,2390140136187825816],[16138292879750550217,13270977979011614910,2587367775404837619,670282248324348919],[13956835885681269420,13977950138640785752,4863109640880899263,1937558364909967234],[10170411153944345348,15189428256572144992,12959700760463722718,3298790997504217383]]},"stage_2_query":{"leaf_elements":[15475615286810638402,5941606003349468527,7149406797220853747,14408094695260466072,5935620588522615717,360696970885289270,13328552568249680202,7478780662730886663,4991710269693280760,12444528642231171416,13388733990315296340,3846862432865267487,17370449880663240332,18006078725324001687],"proof":[[2946675202410270403,16085473693448507536,9732777204450259944,100182121040436077],[2913666794105344175,12025424693416741546,18079622373045167038,772503831382555296],[7859532325162600818,616010668244157513,7968735147500383026,2292437672857683782],[6261767386718653319,5025849822528274832,13647353099448951451,2044114585393201909],[5619068552856192055,12493836239879180842,15206697587685340812,468314258965872384],[16915616490246934394,6074555269809991873,16863396930555143351,2210394180159601344],[8638178289108172843,5413452299523624945,9247016552295550779,629272378754654261],[11764615921182342623,7566316925405593535,701820600861094499,2327239355199173655],[3772482027384474858,16846664080843896703,1152892815842111257,3193064965466408758],[16758513432939013410,939059060802428491,16909055089512467783,3366403956267459255],[13284840367506353666,12609461417301466338,4830301200085682655,3180721742702944775],[1101391570155270103,18030471955809926170,586352199699272119,1793679619803222441],[5944104811179779230,4705743378997469566,17252932908060409042,1116220520959491408]]},"quotient_query":{"leaf_elements":[15247932975560730365,7320780462605076673,5251747439963441553,12655930600651631507,13606755628631117545,16688464345814120582,9806082282000785220,887867128321985928,5569486224572387302,13679021574194323906,13752848778024799559,12782271260943006035,1882458533744760803,7393733071841197733,3434530881028818425,4812153668984337121],"proof":[[12359919334582606610,12860707606052515264,11812545155604962296,3055669825840455475],[16685007834373428602,11355941128664296484,11559466188710795118,320028853097148249],[10417085956314648390,8432336321280724182,9672439236579906089,756228063497740880],[6875650536606009717,14732851765669873440,17739550322805352947,53107543878763745],[16460026629674525327,12302587232054295892,5118813596761793440,1532057924615135700],[1634961789251502130,12977187391594002674,8797307390161715014,840784968025538952],[4127056660221968673,555699239965602857,100747746820898460,272038097021372806],[1096643144277716418,9992568742433196056,13734650985406825551,1686392887015763600],[12298628987253730464,3289475118357903876,16491669816361412218,1912623569684632214],[17596666723160575362,7499527703118665552,1153860263569251762,2384044325195890946],[1269044347733385167,15197569271567601323,4526178305405777126,1235445967747812413],[17805648031392826486,2073215923224479568,7861966061060194600,1640385227104014486],[101117472389605186,17621311294920231862,9537129816252271277,264251130147554038]]},"setup_query":{"leaf_elements":[4289634576391547924,3693723425752140503,14819616981213038734,9117038717420187508,17851779861385163882,12699280140786240163,10666140605791459986,16854355747992409827,1204944751719132138,16898581546349443709,11324333113024276685,1003417374174025642,10686690219897620316,10187381110682234682,15944264775876869021,10260577949417337931,9166368778778719355,7098837082555303485,11869378250046474502,4570186902978068750,4809112169242168684,8040778407696381097,9781723465252600771,2191628233065942756,7967252951473721625,14957407508895518903,8944007015032848589,3467301165543603629,478660638347226158,10873321850386967605,4417961032546204521,11430507897109050863,14501865616986856249,9117639605647592107,6163700493811778629,4472209138724668409,16917485674122423520,3772899794619079343,12190087752702483633,13464200849021693041,6660654117884251155,17929362804263707037,11315350830989398703,2942844436267695971,16643842650310627551,17905519946296814482,12862018692785071129,2697348811353189680,15357977434039191380,16019860535209751010,10969935766494791565,9999603820139662173,17156542285038100541,12790692086671311388,3653570275449684030,13040224568415612683,4560697730785122425,7260680317967611911,228658600402122796,10906244590785175618,11704881002553057455],"proof":[[1207607795927801329,12778268502248437684,12800021159254671829,2107272906818636325],[807437414593946696,6290222401888322249,483285801115982198,544938400383624096],[2175047394634405486,1694565273942473394,16189661069723093040,604715959344499433],[11845722519418532402,16715117442871786012,14822279670385392311,3310555175334865333],[18380654114314487865,7784856180183102544,830668299818375704,466447468956148846],[12898477813783938791,15480396059701246459,10704218788376171123,1526356054155727403],[6180262220122106019,7192175789919171110,854639968979801761,1783272814987923762],[6094126077363140780,16924369610486836995,9970725823551882765,437572095695684632],[4703402166471852317,6609887194327491239,4934923835825330382,3417091003899445853],[8253151151567512963,12284442112631241033,7333548270141704476,2808473973835984311],[11511593473130073380,16758027243998119240,11238201813964671026,1610623666683215022],[10516063788198811860,11521768273658753976,375854070151956021,797548007667768901],[14721891719636996984,2949626462121883205,514398815710631466,2655190417159851675]]},"fri_queries":[{"leaf_elements":[14322363541491293487,11195206613470942700,12843643770062254803,10545562081413253023,270558009762697530,16122884785617875149,17239742841900189369,13396302659675366515,12561981404260483090,13746996311463398219,16090203757895751314,16515296065746866289,6542357525172826076,15698983318120531305,12646354149026697506,9846491622555677015],"proof":[[8685701916712499326,573517993689562805,12330152193920436601,1026805317662455233],[4196144830769589084,13825882387113895288,4980755585818294157,119149695234457821],[3200262266958231033,11311180460537395484,1658865945887369692,3130433843649251943],[5977132661908383317,15577227715565216498,6286475954524577254,1684554450636974332],[4291651322849345571,6072611352994143468,10778447206341042063,1271303396863140611],[10415493506444250443,553720053689466004,8697199181893997963,2979772793044450586],[7275931400292024573,4672127520779342328,18245903685394006764,936600854038905670],[9869303500020419675,16951623351796344107,10732088556418064923,13056656217461683],[4999245903498690337,7298483859315852371,4711531156947246730,2388582959435649154],[5939124624586656117,8797311108778415437,8676485774919245055,1516009211411584182]]},{"leaf_elements":[8853470121701151071,17012509669602342731,16342060757775542327,512318421398344760,10026666520692207551,10566001790864063879,8470143654166545262,11936473033533025420,1256416165371994531,5623989917236720116,3821113094688792686,6451534391014005301,6861457454729447743,1840515654498355961,16093866411469816926,3274116957503284312],"proof":[[5229374790364440655,12599778466265624359,937701348223663394,2443547082390869427],[9923008058519202758,2950762569981114796,8667779831531106981,2278180134621757847],[7624500039925813169,14618041072385403792,1133921326730511628,2949519529977420828],[578519023419535324,6729669966150372522,8060010581380258995,960056631465573482],[18211480017626989338,4709303199120528782,1502152619576634948,2223187906636586282],[2767861238377875692,15785855316693498676,3744809610891684183,1567103551091653836],[4226831722111814395,6655831638141719359,18416793863196828265,2754055803328667659]]},{"leaf_elements":[12098827377785122161,5467888329142950581,8296957083938342277,11858263805259697988,16289332376730377831,5454369002615115421,4673608919955217392,9733860546816059060,5212639243081590246,6456832561473241387,17307042226371683541,12792728938626906408,14262360202210178523,9832526960386771244,3836309361574291694,17320999409185470929],"proof":[[9244770867765703028,7710536580448944157,13743910745316014004,1929416992786659380],[3361149475921811048,2294286482498528797,12030246206304109516,2389100999924704930],[12210735443468912945,4228653015746222779,6294461639017255781,2485205723841483832],[10512165384836540950,12576725843624026847,9749163590345599686,3286629949348704569]]},{"leaf_elements":[13790855340402993368,7414387734080379513,12975407704994933495,11495992525856327121,922490172660792407,2216591724534083829,5681419279857519838,10808937684894799099,15699585052605113537,28254719198542013,12781572970255467545,7196566718999339916,8152988491243675749,16434549783931242612,15461814104182559509,9183595432750050028],"proof":[[14777760533211147947,4160079023517810966,16181012839474086048,2965431587160692161]]},{"leaf_elements":[16775312693976535021,11906390845590027506,16723574221087713398,13884781623836882318],"proof":[]}]},{"witness_query":{"leaf_elements":[13475383314879609949,11821758013995837718,5857647165822095247,14424827182396038966,5638026013087879784,10238744261259446164,18086586176397083399,14714974356500238282,4410486365630155904,7657215192134681306,7808034447665573746,6863557009938967646,6988759234471517222,14982244469866588010,1074916935242935350,11003860867865458094,5622425620371445036,11099047759906940323,6643201941025419677,15621498233341784556,8785479813347429617,17785653105495529279,12056265318483140528,11948721132761019712,4306167789140698555,16634819358634882575,1993453517312566353,13087340968812190947,11932661583841480693,14333726732051472493,15802831252927083576,4763556746430980968,825827199570131041,7251231456357595427,6862386878379263995,16411442584001491490,15927567053007459668,3214091219808403983,16732803617497047367,6322688220720198889,14795605101555573374,1149070314204181151,2673469186102682485,10985548320370029659,6321457636117519083,16180878879482506844,11907363926316072880,11544847066146665837,115916306157045758,16120999998517075920,8116746753483324892,10720229433621105876,7488130161779131226,1872379176808769695,12332509368209604451,15008844934695356268,8849370854070502133,10846431103454457892,9758706146334437920,4906099524461572706,12744516015852256913,10879886518140642529,4271821438333655112,543145446911783301,12669447352632231349,7220134908278463445,266511320605793054,713977555993900895,14175293008449497223,3140297428990258509,9319210528705609677,18388555482591788069,1371711921618716479,15648512786067454711,8905131723145931240,17837479178885506122,16407470895762919447,14091297173532348658,143607518696119143,17139873075299195269,15334949741662088920,5872264062531517278,1141291557509831300,13633249547448016568,17963413086864966013,2572855617188154930,10769178277440347401,10734728931728088974,14535868291721607940,2781901393002217399,3160039815666894832,1000777256643169734,17931696745186081918,7093553708091807725,13231093590887515720,13602008883351724276,508843089652838604,8585883974092185041,7843215426469968612,14983094822424381701,17267107295134035284,17929862421866815757,12130358392744969058,15281763359226741971,16528393243977637206,632956135558391532,16963401426727225495,5265338422765038935,7540272121205460845,9600764301313863159,13213351477742567415,17527780023737877931,8408393008083273920,5496570973734106673,8932248038960244576,12007623560051550084,14055467106021441301,2733576522247971221,14159164029716909420,4714002502996375353,13222552969494162020,1893476100210984136,13075728701488649586,18073285269679452621,13691716892765144887,10593547738900506958,461658967799792429,16715670372918463505,11208629111677079129,4062365439055347234,7829082729839280564],"proof":[[17527316757453519910,17560766253745398056,10356011087673106249,2759985922530675733],[16667184649362951099,11839810135011677236,260706468294150810,987567298256932488],[7271847272232961203,66305394284348837,10736685474036289631,1918135081506183224],[17049778431920160235,47753655537597224,5651005819928873301,1080371199746553631],[11573735345982338887,17227154710516213483,6072891425372633386,1521357754676191441],[6818069857301786527,5870889669375212487,15842940422177648742,785113348687631067],[12646690592602073743,17214930909451755135,16726559582056159816,1141753055871247775],[5655715792811371276,8085015137425967550,10386484444409442125,1067394247695052301],[14270547091406400679,9437298940110618555,14605893994333448220,136444117143911252],[4985954218741978868,13643457840867935634,11059738903030275037,1020921213604094700],[4938596165638790050,4789246904654602240,1405018266607845889,732885786220588782],[5142135479214200327,8993737624634604378,5176462942667777740,525546059952794244],[4835930027315713455,14567191116503688260,9793062311750296446,2116148360242737249]]},"stage_2_query":{"leaf_elements":[4703110508832914125,2415087426786991182,5426476451626836724,8787128652414183861,10573442273551183256,1466323596334615320,8890023873314299613,7948856822706791202,15007851664251507077,16460658212565365033,7329310922791436690,6146108014974314137,8141319984372818503,15348699589075382433],"proof":[[17501042883811938813,15727130465773565166,13486661414492511305,1920065995317515940],[12794132820655828998,12499738091838311884,2128529734899225810,1377834316665672185],[3813576381674140483,11175009496950864555,11489585158747286489,1072198944618435270],[12644042269517314956,4019355444707648314,16502691345201225878,3126787870251071601],[3312874155848515897,3253026127025444734,17007383617971455834,603632515753404266],[513052871496734317,14006977731588131156,1984220014546753371,1064166462296710566],[5719256514933664235,9010260409426842228,15381640690187883230,2970060948766792531],[10105550774453834270,13604818512716826817,8507970201511742111,1296307591012524904],[14659547505127571233,10331558127143919266,3382863726398058431,2829417585110967266],[5289343936016602144,6216879279634235513,12352254977133981684,1539318850215007422],[13804284724927624830,4966686022311686561,8802885186398022619,1488410060661994260],[13174836754061613523,2244801622794592706,2243592228159740092,3224233877026474973],[8400976163326016007,13459382111531745039,16189427956558551098,1917620776118434428]]},"quotient_query":{"leaf_elements":[2197965212963589918,15977787317743546807,4971570081652714460,1342417020146486049,6171249175548297103,837577006271422788,17650315911862331103,9604721276678259880,10871662250851079977,1915933906657439858,13946180601267047331,4588188414069994213,5342132582752415727,2478381236818198066,11385528636665234036,2830347694217596361],"proof":[[12313340093387542589,15062954691145308638,10141921935200309923,1901653113151145486],[10360288465275151967,2398838322599987841,13853247376608068185,2693578465233375429],[16905359147834412864,7981652461923743146,11263343408580748126,243533592158694525],[9416387346899498870,18187100729469388612,14500298986679509044,2434199633526127303],[9805787686408300827,3514714478904316811,14279538175338064584,3082745961609780233],[9195527473231804666,117920629339167051,1154441974318210017,549103704918501272],[10170516609328035056,17109060481751761191,17531164859351729131,2122087992377220609],[5597813826779104774,16328102571357901578,2623215925996742443,39444846115805278],[3166114802906148261,10720932171018221651,15136815414354806421,3178332829050768283],[9129105635949564894,11603408119518037805,6838309326651462548,1484721021996601958],[9555337039809433660,7720157082072450846,10430032887101630327,2658560773844221879],[12727463944066686440,15031778029241626609,1474235568906382933,1585885662917994428],[8560803622457089329,6576268329716751604,17480918290423520249,2783826331117575223]]},"setup_query":{"leaf_elements":[1872454777786172384,9754929679841341838,17974530608303139948,5663633796246680332,12646268198934985727,1171710964439427941,875656469538696527,14877890442060547700,8600303721752676872,11568760628785160331,4727754742038987402,818125263351335947,6469519670113984786,7734721570420366988,9050155146601902631,3511502605123390841,13286957209560107749,12016447044911295650,12805636025143094308,13506913646697372720,5808259094122262761,16557905904778015430,5141268931056075075,1999211787795057763,11178132703581009685,4491829787235686840,5086814678316520672,10223659189803464804,6129802040971257411,4701479207072566378,9002788178363866706,13981898719059646763,14142268242179268247,3122787348067085029,424852984999022367,14304825740144472473,2669876776885276269,15007384064736288458,17405144377303649961,17156715994790488601,16739025963493693059,788732335815354972,16099262561394517512,15344331991115108251,10492649745501698178,3984824547622308904,3257830540677577291,13960801733957589164,3685235796755644218,3759453128341552741,9557725168003151103,16089029907302129070,6120924795695602929,12143187205666095334,5723345358782716539,15514448994146956958,5887676123918492512,12941815731818609942,5651887770721463797,12046920931204379548,7092723811904090958],"proof":[[6976388279140031915,13829672651217852711,13488510080836228267,2972761645386199355],[7586612608992904374,10779424151026787125,8626540445374666521,3455216502817969988],[4756895150912389251,5567346220386360786,4252960593252261523,1154746415748048840],[13091301232598333829,3022901269897577544,16014136241179049777,3027603930273527225],[640297778313985380,15831636360494591187,11946706955795304324,2370188854332129548],[2156503037052229236,9314319773785162304,9950517007426675199,3454054319739249250],[16595832725300802900,14402066961441733891,15797259325490885948,2473316522363503138],[9400053830245829634,5217985353516756264,13689137022725038540,57623692977690593],[13689561830025889794,8364871906449537195,16755057433248980334,3013061714963842367],[2412802751561812889,16638336423528935300,16359893771718326723,1391259067499736447],[11844050273273531004,8496635511186105557,8074218520401262503,1925017630146181652],[12569192502573143015,16626706419100452938,89526480532839450,1151220156167419616],[13233111940330375337,3721613951002169723,13215477271364309671,463369196759619265]]},"fri_queries":[{"leaf_elements":[14053756874869152027,10646374245763957020,8555293544766120692,6837110610636107836,15578087095589470507,2893383136870943714,10920508503745731282,6916544239374002042,2938779818819895555,9419308580984196927,1588768999359814034,17753033793388676230,7112444333122520917,5397961600110460211,8618728102059830581,11301087168550347593],"proof":[[1733140995613706286,3875291778573667327,13043230170326353122,3198278411758218890],[17242104760674663959,5012508818522049122,14274609647534296203,1050189795174622111],[4691169431864396725,18078225332446283769,10726329288740653047,142702084793537776],[5164161886591231602,17857339635758359628,16786414664458470516,658587609076009115],[17616045177514077244,4478617464363946885,6181241826156339859,3021741985569284564],[365730665921913752,221961240544600485,17408878656470425165,1527044093837645313],[455120731051178242,9060924031659420268,16190535329885659635,3458294095353453389],[17467653045468885287,5939208484021172269,15846670269887154064,2442974407936301369],[4804235064255669216,14729952626711900118,17533787292596999691,1688029707652464723],[10293913151203782939,17276720635789980012,10145594858043310023,3455109967926550842]]},{"leaf_elements":[3830742733576597299,10118750357278663853,2049925293989963981,15407468090256177929,1778568001019771038,1983734682050626504,4721287791095720532,12707436384043541506,1838985162674701324,13622249463474781976,16464085096558510163,15594510660745842657,6354700687734868970,6257885790661670706,12293305480407981654,1720274938478741682],"proof":[[16462375235538968036,6267236704995803486,13711422342500124781,1586748317816370357],[13335554084872434060,15672099898324919035,7359263000257543413,2124572309168268531],[992260052434504080,5140020301160871979,8991509337628051686,850866033059338862],[17176314644515570812,2974875921159877596,14299167926041653182,2382631316493475758],[14010706419556403221,3712952949473851457,7419215692255647423,1929805000562920671],[5473885783605311085,4026771276107960446,4742656884502189251,2192188515716722929],[7407740297327449151,1602759275088930253,1080223580461385578,3082418193151690999]]},{"leaf_elements":[6129560827756072416,12674032171627184331,1564547387859849589,12075976309103694195,14779290442284723867,15013165619541635563,16373690855436461690,14668929074834513137,17873803419057464876,6524170840020064684,10883586905891084708,10800831129482397349,14605765130177436245,18389111610014130539,12910613202332334243,11080886136814803393],"proof":[[10783859301346373355,12287979526347799696,6686350621682653853,111965784954742050],[3228293528710157651,9322735451481363043,4717096984123856486,2681158853409885982],[4800217489573654783,3149554734942641022,18307580925378185476,95013896439469199],[12700299161953849936,17896603572231004330,16616459751671690607,786280160165782906]]},{"leaf_elements":[3303258396085125681,7334765928689504730,14735023820760202469,9619724676555854682,17674259656641861264,11577514084267056637,2440871980048415777,4361546825864617734,17764661275648454126,14367408337706981883,3009606633506689442,9303345605953149770,3068930268487580864,16855781256128155135,10975044962187852064,14887023502175238661],"proof":[[4082544563390657584,2428803467750713898,15919672509928983616,189310895045026976]]},{"leaf_elements":[6485988802393016559,12130974100501667025,3138003141619716888,4081174251100168420],"proof":[]}]},{"witness_query":{"leaf_elements":[10663621626943911093,9474949378881150970,10015267735398839219,17931591625876827738,10902400772457446403,7538595352398548771,10135136202988315939,11799097636433710335,17826690365781440433,10271426313847779628,9517035224240801305,2710602149014164076,3658760428203107971,1958528770746002629,17442862647952460046,5674643659920867614,11777355322587118652,17809761222121624309,660705080155572977,15308346595246548133,10756192876517522036,10216599738659548023,5750114516482752368,3545257736279912173,5368676520592344689,15536853888830202272,873893848409117711,12074467566832253279,16502584119453786506,3275990416047917098,8600031247788994543,16396270986826682204,17800792266643202472,12189720568217945928,14323356445702440412,3472882982513786475,8506978643656503286,17469132560932817827,18145482160800446363,11379446055087306977,9909685597606186611,12726672949751114208,4933146189831962139,6401100962547175134,11082894065432955352,15493003517096005805,2056725948623024729,14417844948578285442,4432499317103788285,9719827220291885957,16969555504192637305,10643124841759131130,4074453078040674151,12204453575141193815,265684832284470204,5221200915767631753,5606937907782488511,9173465361625831807,1748643107742712681,11497656251511288568,11287177770460535355,15758299091938733292,14017046450784909704,8188641975528375685,15182467794586018361,4290821640699854343,2416681706675856225,8373814341804693587,8562672184711490926,3897230431590650537,17655752973919579273,13778889057814826782,17356099254517516018,6899941446113293270,1147402468338769875,17408804183528479560,1922955146816831817,15892376680365726074,13515168252002930946,16077640145017136843,5915506608711537000,5867399954546434706,3543010723008625422,4357844892408121959,11672237038737733127,16663289811039835080,9435134209579347755,6205811254722561281,3088277133365148483,17096725913983096996,1816220432238360525,8926037049947760877,15200079636706998574,8259501558684638136,4639465610900732760,14732889840978169147,13099324709920608399,14129306684595887364,5152969087304074540,3854036579132534887,3526035214698811128,1024928748550035108,13194626915559980838,7187816500728745444,15902408673761550144,5563750950642015039,5000195010427099451,11398758222803304621,12834142411878766401,5988483823625765456,2288282647501426740,16195391225995580460,9268652033213993876,10491135394332723192,13247856757542274553,4574545664816211949,17221876630084123226,9794214532336021117,16907637407202219271,855317558682017433,17328368698762675166,16177972188805528479,17500714187122768434,10439791295140967467,12374377867342523296,664506105484999193,4465120294721407361,3632786882315706769,18361845490105515485,8456344952174763126,10313324540977362614],"proof":[[3004620482983715891,18350215515765506474,13253415130038519731,1836589921508647948],[16002372386741925307,14568454680065515365,2811525241938698584,2743716637242514375],[15190313219615976206,1966121057027535040,4025516203552786283,841450109119734834],[11604725455032383878,1318442346853290076,4836874858600919579,2147989497917115591],[6670530144733038243,13057122204288111959,7120260382559031722,207055126686203635],[2051413559321197544,11513626554459602859,8447232366093265267,2227407664609997796],[10536305569982133295,15957702207317425978,13471780184925594574,2238662493612532853],[6288407802663865425,16973497555959370500,8342243747929918452,1793444899878636542],[3993475210696380616,12445406977946300148,6170462162933994056,3081973524688627776],[13073253082490204641,15638624881445348194,9841470601433926238,1676427404760367694],[10268531948664231170,6525118091667883659,2967761560303839577,861811849424894341],[17853319454102426703,11458132703626502620,15417113988119134628,674570626102661541],[10228429935734291152,15070756974979336511,15218154065077763931,1832421964913171749]]},"stage_2_query":{"leaf_elements":[10608235195365477814,15266558935496780506,13158934831437376788,9927778118292882103,13457890496066403108,10073770081353872718,16233006916936382248,9694144161516668100,18423471329849283705,12107388489995727992,9296410897430245322,10390265735764235824,4660239149817533443,4841339684826294837],"proof":[[5590106589809502168,221039280535966009,12919439268003808469,3371344716765188214],[15022345526827267085,10964157892630024729,18217525673363222861,1003075474742630488],[16883698900681618178,14168518682476214976,10890102417081191879,1933783641047255620],[13592847849759425547,5519604058571793040,3568414847991532030,2890570149656082283],[3337995431952687334,13932187539290665542,13850694106409647199,1180058875430916532],[15185413423192658771,4384803911522482648,16374279350160093637,2461733438480822118],[12209913052999866322,16071054814560060395,12595552347268030729,3252835621663431299],[14037611434714593050,16884468818214938134,5023818103972568096,2285693731661010000],[4778431312930965369,18259889621071908341,14647603346757945642,1919663359710058021],[7364223497299356969,978150780938585050,7145224579722954265,1172366305682289281],[2270320900022175314,11084083730022225629,10498212610982509104,3042167221963509761],[4635452191223119194,2876417225665026593,10993606036791249716,3465884504674745958],[2751258051649958256,17916243703110554662,13375786371768332344,179905637827751778]]},"quotient_query":{"leaf_elements":[17724612122144260257,1744532647741897519,15422919947975631592,2694556897661227561,12522403516599006816,4347483502384890247,10736846588769574115,7915341105740583300,12171543452911275259,4062765749162057235,11438351513877360190,5764850453343721014,6404818067879385287,483948522428777626,11411347069449353255,10827091598208481962],"proof":[[5214723830227268636,3850641095350584449,2078318169712512659,1473178968724018190],[13563921466337933604,17228225068699751683,1804315506172355058,563883695296536855],[7891116015249369781,11106416124688546675,5793905804533329197,1934712875085724760],[14749589618916241338,7467079075139460791,11408026244784824048,325025373523217130],[4106523606772748485,14484490452132093205,264721713464398059,1825371815752463194],[15974640493756290131,8753556480784491866,7799959705505606689,2064948153840513186],[13292659377301623206,16830278197582159813,10900926290780768382,632724213435232358],[3420742288754466097,14183211027271406577,73464373538644040,1531407508867544924],[14423148169716443994,13194794117578154044,7078871375268863674,3381616193040014961],[9311127495606908805,6613148429567989397,3496496693834246804,3006318540312470433],[11420173561277255454,18057715400353369436,9202491462650698454,796211399199829229],[16565671729463939150,7300669218253294122,5820718040964588145,3134965001892430495],[12356171133472036182,3715560352098057395,10451102580509047715,2369959934291544747]]},"setup_query":{"leaf_elements":[14682302885826806708,11009119016146538643,13606707279991396568,8390548807452904277,16534205284377117372,8251662305134470680,12289182216945299304,6953922461619598686,16148956937640600215,10898682417175674185,15876804611352375350,12752499923470756909,14765529555676733062,3593529541327813464,1022243934254504570,2426087020713645299,9339039332660146634,8891866864897399657,6999605820064553114,13565278028074412843,6917950908139232253,14840760070498501852,11645040949107944233,14994660131321890380,10029354427745269127,9261698526107364244,9361219178685995691,6029470192277360377,2627947045672715227,18344213320164533154,53979640218753762,13068313028771282522,8847192353264118162,13865573628974581809,13951112607015101287,4981446525325639227,15124488078355007045,7987032244690497054,8402729429204280277,12920576275768921714,11666678214107282052,4569457332765642194,6102571859611890249,13949387774032358809,14622514061199151822,18050200669127222970,11749618296764517413,2816389668168070321,8479245591755901529,3459521323053605113,7963236039900563646,5103044755337320362,10221500956430890392,12642633332737502327,4055850345247968345,10353041307260114392,15978845905308143477,3295385875386891126,8731505999659388519,6557945375481758968,6807994473934843334],"proof":[[13516147247004132300,6063019707344775830,15615625511990447061,2520701075872045183],[18266311905554926442,12626624139901927120,17690370603660245643,1162682862880988645],[9812004965330997639,14092886649202800773,17606036253889634927,2973085218731279757],[13519996928781450549,2294423406721678758,11406680285317995235,2588265312277102211],[10883665225787666152,3571744532468236516,2008046024734557203,987055005004956061],[14727933029916802379,3087215885054207780,14646554392891781380,2787033390361805002],[14537777075313204565,16107827354757553015,18176301314502355150,1857676245861441870],[16376437543722462365,10617964691161671040,10509097441675764298,2365905218315810366],[232052860262153647,4046934131873646287,4375600156485893840,556539205531626894],[10543811926056251725,8223867670121429785,17005535188590062398,2818891784132038489],[1994173619678547646,10148852412617542927,11738218631705955193,152282741587195506],[8114630110093767876,16550415767052044878,5789539078719692602,2820570820614345953],[7450018982181130668,12654494844657139995,4699273518936840679,2505102648423673327]]},"fri_queries":[{"leaf_elements":[916386125298391590,11640932268527500927,17293112347391411440,15321299027266567858,12816849509903374403,7040057294463893976,13099712761852227013,4371574441282263196,8234500697914793366,288478059396072876,1534823942041525223,4142181710898254659,12754443439429908298,15273750224853480335,16087960093385038940,6980084444203662440],"proof":[[8155690223662781147,14810885629499539291,9147648907946127905,1717220050132015381],[12071945890364132765,1415232589451380571,17143269104943421729,695632802759092780],[1343373248024516447,1051312744422094427,8799955999784305779,3204648360530983533],[13048977015793828537,913386389727947922,9445824754636167371,1523805358359165729],[15302067896785976730,11704070370262522958,7450417471057838415,3264590026550646039],[18055852439277694023,8893838933201600007,4715388663342797984,3026103007829326569],[5935461741890322047,12035738000010902182,11611847660690112388,3320321889769512978],[1008726943264402737,6466587780006767619,11810308758125917848,1441059928321202883],[6194151911933769572,8316546869983692090,17095017662834920753,251028876106012784],[11836481767288568977,12693209842729345382,15494293070777243110,2609142590190361171]]},{"leaf_elements":[13411207024832526720,10656245682985122250,3013921213735297356,3130918940093519447,2036414881602279832,15869124095863556366,831558188501942345,1310521973621904005,15499034261071249550,13246431543273031969,16637600569181405250,18348729338585969255,218637339287689556,7801087139721534471,14854702602063085192,16986771473613681945],"proof":[[5310881794316556416,11773188040541161381,5321716567474968685,3366435811656490003],[17184443126246845838,5463815939448937095,1571575723766867884,211856435772389138],[10918100353537202483,15685761115532394398,1113860192001174417,2714976668479596938],[18254946290161321080,11872966207879383732,13343550233043413637,303013657367501148],[1101874981325959238,4560900851701830093,9769211162644476409,3117656796157897536],[5494814019481716921,18311101359736832981,13570339656516216338,1358630459201341816],[18221825548504215278,371654840480040303,14092719419885102622,220673262799455597]]},{"leaf_elements":[5565613240052445453,4881451002888724707,18068397668498883156,4494904909318130628,380743001541324904,6751015474642466122,5785190955078372648,4940431271044920136,15239491850871874316,6675661567090458705,15846559846750524065,15021324880991846961,11317824577575091355,1467799927768502586,435157695315901377,18346283709919559934],"proof":[[13308723686730970742,17945073215094909388,9262832195351726227,23014200546860332],[3850264036200791075,13251391295098424621,17340602504065761923,67443032188134799],[9253287968541001853,15965406532159194935,2926908177009333941,289682274534081662],[14060609606501320317,14199662051727725133,14045188731999541466,360178435938369202]]},{"leaf_elements":[5617743489965329866,9656866167906423923,12342513696506161207,18445839140823577509,17173266430686786372,9885785082442603736,9640565192041168087,8859499278609365175,1962944870928990236,3217289664835128148,18150089437950339150,14748222972309771547,6995749073399235010,6830073760022153520,8684292857175602258,18324510307768863292],"proof":[[10423969435245672408,18154964293000735088,16236043164000731250,396436116672654202]]},{"leaf_elements":[18196018707140134098,3942247739030689718,1556687182756891542,8508669979898744338],"proof":[]}]},{"witness_query":{"leaf_elements":[2544868000864912946,13053933615362622639,13703726560527632595,11083227410053786380,5830058925024221663,16325223989755757820,4958537947151803384,17046465492217365975,7715621248232383338,11130793378932140316,795152436265121764,11021727666394068070,13437951047243106736,6622330289856707435,2445308179707147602,16901594421944236097,8355186103078924073,13141022670685427440,5709248899352007159,672014725915358744,13161923975236372387,8955514002083481085,11323440607558832630,9096840124883152355,14217359417194633524,10475911360899061260,8834621196741262322,5490269474849715838,4822426482212363833,13871989827511146425,12185304444883255168,7829785644834334262,15301910832478842322,15889350156706030105,1187559454714762298,1956693998087152711,743574314709554288,17782277141230747241,13254828937593380901,14161013611515936162,16203108925263708127,3656415261540982607,9287401738778723137,6953635668348483576,17569303229473811020,7770822741414450214,8919530390126070294,15302943847618803169,2724775013114283326,4680918764374411528,9716143721904302626,2419927762524934849,9016773950884975614,15043751262065797189,17823771358382383635,14720993685538974239,14104644533297664608,7235089621397529350,8757223322197031878,5971510536448427679,13984233381085322263,14684227666585764086,3370020982218202933,2856055293656536359,8256194493513377908,3966045744793037748,5332994108758261796,3303352163998446250,6145716035507900503,7611900436562572616,9822573591774672162,2008534742308656894,14843787370033865358,2619355897642535237,5316093937920115377,393620622733936219,7870773626678877263,8839950307612718476,5063283905469993707,13512981674855639648,9650270155341875728,11123993963320316606,6191552858454205200,4102413488060290555,8764323067311907477,15956999335367495564,12023902228044461884,1421853938245464570,13558812725454262246,8692975550883644511,11070617656779627389,9146413036054487846,14895530695755418084,7457753539377105646,758778747434134363,6225915700896356807,15662937482029084279,3610502366476017720,12567473822909277650,12427597417146569280,13119185689460700419,8504493126016227718,14458475650515743362,5969511973800798638,8565929670971200722,16201430028680360386,8186403804517289144,4068757078845205888,13967960019199946740,4425917015706382258,397569473418505980,6346534027178097092,14458237774123752854,808101545414809772,4097056764342553514,1725421699620193201,10985777117535767304,11802944576144539053,2173461065450862511,3435920501399962832,3946388627493066327,9722856758531255472,17386537697102688504,7498873419608606655,6668627233749658985,15379792174949501109,15656764663809715983,561151118861640836,62831498571551614,17855479630023479857,1785023757291686980],"proof":[[10175171982248466641,9920408217456436642,3832429211352960745,2583551103807852817],[15517714556831001967,4239256362907514845,11626095781024810191,1144205378259148420],[15039649849344219379,9682197618260074407,9486350320477719923,1738462780943730131],[15637724287272531352,11842081699954211653,14082149722748551925,2022485515615515381],[542875926406288967,13220915486870351641,16279653519502343915,2374480596324795441],[11205554299263197533,15358292587386696504,3778499820946787587,3413792110327711276],[7476909440795840880,338487938619175611,13415564709397735378,551737871920376742],[13333582015113987906,1889502359314169461,8874116366730151339,1271663459765103859],[8194322445021574268,8300756559971199565,5472687007664245089,2575246362817416334],[18196582002726257548,6746744118716689611,4204561479206427702,1610429971794223463],[3052769839153502075,16076543775274830677,15530647281036234040,1890509300522111740],[12475044989031866318,7184415729384318154,6629636478275800590,2966988193844135630],[10760418131477431642,14820657774701628297,11628914349052808993,2039254384422831665]]},"stage_2_query":{"leaf_elements":[2329180552760505150,15496161640689295104,9967434668673852775,5836149420069316217,18185481543841241689,5684964043725716702,179625336226257408,15645921902462724372,16416143230174438100,16534743194594716903,9490106337990771964,5582631808744837268,12063134483382723351,16028253469042289584],"proof":[[3433477040113029201,11738808820386592108,10076053740343997581,539902237154555886],[11300350085434193140,17266159071631209858,17697622392717159391,1850486570869524201],[5232289257816284972,3900589466819789568,3504094912433038760,116031592580796508],[10112855634438715708,11440473343589305092,13631610171704920681,2791412099231330055],[3806570097770583051,15478640578289546501,10133955138220411757,1307552282992256631],[2151589531617336454,14723346505856811256,12401919204539714983,718790956622057396],[6224194816807582754,8100589747549504895,13517151641453320941,1862066872609454674],[310246947279204687,7707746397192084661,5678090732288440889,588797951551667491],[13379121645502093800,4203616361030087683,13536563738205295515,2832504135907353358],[9183042935547927003,11849443004006479552,11761322016486598635,1961693464927131177],[15270189068040843327,6540736229038739977,1884817225337202625,2193279034898817630],[8127607865834670865,14729965564009286649,5279919429282908308,3248549838502019424],[10265763405734876041,5280836174585384744,1332105447072495082,1288183057809366478]]},"quotient_query":{"leaf_elements":[505726771785485986,7094180695133651716,12385408030689523009,7149270863427039411,11165558058271870548,13766917164773829479,2530493666778150200,8465729632537349977,461211520896821538,15011338305088956891,13450072308575863710,11829814613663271296,1120186697696819539,17260959973941643376,6115605267100127187,14288914662544955152],"proof":[[4638301722231147142,13706742403596148964,5421784437923619398,454028540397184072],[12545676741452941020,14001408528415596811,16423774146403114522,1460862478423923254],[3380190876313703483,11038803298312128130,18137466668635066475,322030468920932788],[3325399662402092098,4087080358129737135,16157086991543602382,1190514002501164116],[12235220008444425396,8765878102986231506,15288506807661522706,538400245720009243],[17847649249088351754,4066552912327446795,7873444340071837471,3159325237183933564],[10623476379938219408,1389877773106794538,15518428211044770273,1215851691742045714],[16482433469325065525,6113459233741506368,4401160248927144357,431915032439191239],[13550288856641438219,16022242347928581572,2630114900257118934,592949526637222689],[15211210063092102954,13962922723598465950,18442173497799663063,239409433161593854],[18220462470061240791,9013867161474547770,17825969056815746077,2826956307497552393],[2841694422372735971,16650924386010654716,14519535071556084623,3340584605848388621],[3336220069100085124,5759271110398045898,13618835346520552360,87853750978578886]]},"setup_query":{"leaf_elements":[8766072089071634022,14674078039919398369,719447294918929734,5973081529107753722,10896948823928262757,3038309761424127921,4977980086553520263,18212660851630390678,9379780655414674554,5037408283128545746,1726158127271201734,15495951210484123956,16270814312999017162,1589540573801826337,5043718640351728245,7182729025909894612,10169107040810197930,5328590222402736955,9434533607787505535,2201009637539485362,15702074649160526266,3330093361892333055,12110955477804847837,2933886950467762909,16981564833277781179,1368612830057765518,351391272655196003,8268497846654645359,16625900369240777689,3653157862557126877,12549290087968533619,8272113774351196406,10215822961255811391,3026733581757221248,10395359965327065292,4985587637845036125,15521828439480454595,4634912732090585091,17953718720072786080,5266077118747425525,9317292364172793497,3118907057507119490,8805150834921919978,9240923321795588599,16784248793570642931,5408928496976476881,14417517188728179360,11763754045662986340,17400531475679289333,12763619393340494315,16388235289641524588,11954069463804696804,16984287895322967986,6245296443844605744,7410294483417945173,12428864942263562042,17012331589179338294,13247114175172437460,4248341547744374505,981341606279590484,1216326441217458676],"proof":[[7052287164467666116,4128820066393817083,12004228996394496865,2757002812021063148],[7883160861928577543,11804112409078432236,4971339513581272250,2763510568597165548],[3269407060880510048,14606167247258571319,10834896035259901744,668279368239144214],[1434220207888078586,12795856600647814571,642215468475933762,1514253120306612216],[14000031067807150012,2772479537063700307,8667663038049238838,221892566235466308],[7669478523704046540,16211693337851432428,17800552370226617969,1530079332015495435],[1640040644934043095,1682222048593033598,14805476323100540507,1098144197407788823],[17687397738862792181,13625493317639025433,7875622511013496571,340125465987740783],[12121574474885441157,5464481261436606018,1057339104395557274,3191424732470567129],[9073280641395803527,2933138734167402427,2460847223802091992,747079962548205393],[9504926050382533598,6708291765656053457,9050283491920720817,124790896979962174],[816603275984845589,16421293770312208627,6436518652581983748,1646585520448043581],[17874738227292005179,6326465745494053,13494069438792348789,1192845911089305290]]},"fri_queries":[{"leaf_elements":[4002172606791593569,385052692369462065,4748618225142745884,15520333457285712038,14073189563588713025,13106001035415178824,13559484074551911899,16864528340970073873,14535495508974824692,5167623710343234293,10643924545544601756,6654987689945011190,9756252669627913458,11566048574441557109,4598106979703256167,10204947164438538105],"proof":[[3681154398562533776,11912604670203357411,2855287553322344450,1055205057099949095],[9518479379144092038,3045518956667233677,18023342720221696893,137502400988953152],[13738400380747445626,15061631818437685830,9461490775087755967,1637094372721718842],[13661942167284389081,4426924546093396567,11650819786480364813,329468488714422038],[4319437207538073834,17327644643240922859,11003738130774307769,1046833703873008410],[12760212714705876237,506461891909189548,10309807375696278639,3070593829269508072],[12216925716605557058,13489244322316852777,11184709375206925621,997589363429899811],[9106624583403281969,13612281113976011432,10326203882250134028,1761694247803376456],[2474386909479108107,15743225463482922414,6717071940973494994,880285736130704643],[4755821502693131307,9632672734832196477,6831801818195575559,1211503718015705569]]},{"leaf_elements":[6547737123782109161,17477440852365599514,2566463767088096013,15562119084103251625,7789568923415672691,15186977496010838499,1961101351391796289,16880961601068699311,5637094737578327499,16262935695710770087,15999079402828443218,17948790890945503195,17309342318021874434,17660435211483562809,3716821234407064743,6078940472428666139],"proof":[[12729337907054834397,752559693293076387,4105947889529242526,942495980523641787],[952779044381642766,11468592109269816172,38619839526358385,3477466940491611601],[12683018202999391764,6514070132978388675,9507995367267889398,2613589432259200703],[14257398705117713967,10442825125406307356,7051410383319342770,1678306670978990422],[3662088690810273411,778943384847449174,3252519369946193487,2136467769116153821],[8566120840172993465,4521693103239627433,8775637222783257403,1195809697926602439],[4968579060289205032,15025470103249155658,4016020820835814409,676707436625885313]]},{"leaf_elements":[8739475814721406167,15137291696515122693,3173315989503362132,16881332129315596714,7921600635706531894,3740117113117147208,4948980211720696074,2719609042234715302,6608217055956353199,7792155436591683532,4398503882287183505,16816831435021282405,14122856681506507267,16184022487263290557,11596834943523595209,16923408694490334406],"proof":[[11011625658805751494,16198302627463457681,5986171672753553571,2808367334269758958],[1964388511587953848,17498845169523966783,16101809794355642271,949393377346781604],[18007238475553311250,355626820106702666,14439666787943405261,3242313359508596896],[6775086337445118645,3836725614252760951,1244274972769235222,3458783429667173983]]},{"leaf_elements":[16760476579281369555,11684430973873978645,3628257208263626274,13264191245930967560,16805239192496903355,15197924325062831366,2446532897786143650,2265791655783868310,12694463806107320464,16750582611044430566,7379235119149631963,8016374353919518273,11399838020256932524,8401772713760710572,16660944741874745508,2593524144018731665],"proof":[[1408739999051503414,17928989256333671698,4393560887102948271,358038974748859422]]},{"leaf_elements":[15915622550061201680,4536541224237163888,16120598048347926193,2661082248244309055],"proof":[]}]},{"witness_query":{"leaf_elements":[5779853618823983086,13307561783707906133,4339661657852116698,16298916488557847353,992149790669577992,12940368474929067004,6684720304018190769,4270053882681024991,1089552502381302863,6614344928961471177,14149473416258873991,7791773201388381366,2924932124304380540,12586424395674962911,17298400651182434403,3888415729334598006,9135551485654886841,13375577017143307593,6010766159552080794,6764924852328851617,6857080697966096949,1520481167191205505,18124727205345784664,546492643798257663,7794493746801072048,14965019368607137133,11950888617357877377,18315976271955893006,11302848954831296619,1793142946119529698,16622780090480313282,10550794868000166651,8062939244639782863,14104718310754271178,12623862102211101098,185878607892141085,9447407278994361193,15156752716806542306,3996850036433557977,6200776661428989891,12990642503981472985,7709980023709118068,13821216809434092761,7498629093237028244,12418340850564383427,4831467936000644834,8550572663631744470,6976314393910466786,11857859298217298810,8703569161995220745,12377099224844100738,11473988216472496088,11277841043860401839,9329700617904706564,4827679151331888712,3521180961118651330,467983678138610043,4186631292466421394,10000869637190731104,18322184508142258014,16905254758403406653,4360847707228520441,12548589573353841572,392688679010344289,4855661994991857038,6697694638204026503,4517809274142646452,15201110983730500222,11701047401455721271,2907861230855621292,11994228803937582592,11865741768736847468,14412026878634655210,16854499646009687724,7510695843540553592,456207466865978184,14000220969402713468,14881747856684260063,10297685939386631480,11752066596082483896,10343769675056117379,354798997460137238,8849799041105613184,2061504157740845789,3743019318123067070,16276751604491476711,16039075868229616238,2851219190730137769,1552496437664240949,5430084091127605864,18396961518681542174,5222766486099782517,933711280001452450,4523191114835624408,9908818117406409714,1629906198679366394,9301031557517470354,16208259445128282107,8206214703042845109,9966873658054029874,4317766814964981410,6475430223533324726,12388196632677487704,11068368271837462042,5573837990940924477,4946178915437225900,4078349447862776667,14837832112341604310,4569795452945956217,17967381401526907646,5962679025537792780,4329246934978898969,5590901892058676336,5808211353630237203,5395785160049242432,12189565148972880264,13608331096732665135,15044457069577271205,638060225859316978,17203131254227109471,4060285598397809778,5834231914111491137,5920048322662013323,3409616417855047485,1602239641084120526,9370069803814083425,5176299414720895180,12866703655908236027,13028644418172073457,1085089105313967428,16060225132825716364],"proof":[[6307629537453779253,3148954064343417222,12722340062237440781,65878360194972929],[5529822347752427877,3165428967827317135,1398538536196986804,1234228118958034409],[11668757954589739598,13363096618578358264,5392048180664693777,126645489767775701],[3584345396020913860,15061606215649845155,17993522797866926508,2288610150796130206],[4484990660455022741,13030670784844915466,2863050002284310444,1189818129911757123],[10507151523252646498,9387416552488852293,7827271435977044856,2150869474247263225],[9021297734123049125,2163618883688299081,15142303302577603426,1320552075630588951],[8689572004503520826,13444571354487171448,8927461290373045054,1713315447292586690],[2049108990632876936,14748050888176687880,15495073686877757907,2233075778415540095],[1491083142310928705,4743998026436318626,8690645089708143382,3358505118077473740],[1127030895586069538,694780759772484591,3687000931591563247,2750936864721522891],[5142135479214200327,8993737624634604378,5176462942667777740,525546059952794244],[4835930027315713455,14567191116503688260,9793062311750296446,2116148360242737249]]},"stage_2_query":{"leaf_elements":[17925929539648931900,4671315894678531750,4101133104920615326,12338947758548330097,2418410221535645442,10499415048481082868,12112544211197265368,5864121182423781529,5250012323213521278,574538832935884463,1595684033626918473,15898993100424487511,649366840333443549,1629041609577845164],"proof":[[6075543903511699848,6900022404494070268,5283216428782574786,264044568769407764],[1474812596888732017,5699051392702892997,4297092633741974662,3179174857291963915],[572443514298805421,13793704664197652092,8387735880435992444,607412315945465852],[16304324659956244094,15890211973711362773,11735989571158468393,1161616250117714371],[9816154370483029610,140957910014611502,1332421814758013367,678092484669934917],[11709754351085843979,6323307718244292008,1167167750963940086,1885500829008229337],[11301027201795180158,709383491387359105,5228863522139418972,2854713676688050874],[10906398566555027720,5259078251616050617,16425271002078973562,2988920152118750223],[15819135818264679188,15629233963901781561,17871185216003779136,79086769758809576],[1780322833747596479,1745603590673318704,14851741195976123353,2791481713598494650],[5431947802106662554,5443354384023227846,13897831674897138335,1596310562825674992],[13174836754061613523,2244801622794592706,2243592228159740092,3224233877026474973],[8400976163326016007,13459382111531745039,16189427956558551098,1917620776118434428]]},"quotient_query":{"leaf_elements":[11057455710392431963,11456514923545875019,9270446623778237257,13137585538800188788,13159981542994887641,1756577302839223488,9516412917419424824,5861550649535662944,2222690009052119260,15097399140322983661,16432815118499320835,8458420795505874756,8959371978790311705,8877956325959480497,14661854079382516919,15234522058738614839],"proof":[[7894476776454053779,5087391047964452416,1046321503053612891,2440610009733917843],[15966152159655053083,5824295366042332113,4109942638569860668,3043533115986375708],[10558214776286039377,11632630980837042995,15177210153243187524,3201321340771001206],[1991921563827802398,6798628658290996260,12406288546925728302,1053868500900229966],[14685842808607737256,17133374649666332113,14562848362482301081,2773756347319392316],[16334121242824880688,12480630510557474852,2338932665451037219,1138633170820780316],[12338597362919889978,7471069148445099978,16346311540942770188,2158243581117799290],[11402489857024014181,1934576251455205838,4738988182100221779,1757898871763618118],[305949684991016194,3161518649171406873,18431490989648751867,2206541298450726119],[15245179022544431283,15996947075174566389,15677302735640011105,836503348099231366],[2157695038304941352,11191783211948267574,16678180536735649302,2113735272830865899],[12727463944066686440,15031778029241626609,1474235568906382933,1585885662917994428],[8560803622457089329,6576268329716751604,17480918290423520249,2783826331117575223]]},"setup_query":{"leaf_elements":[16115822653325335756,6031986874967093955,13329930625933829271,5494854961138555488,8470603591485338115,18132850478016172989,14322113743668962269,17397730504956279939,3837176510906628854,2217917516996685500,11813651912440523014,4877257035808104988,5017718896319348215,10083344417201021137,12491209913008154510,4039919741391922557,4005243270499739691,11679026652415630063,6925770290865156553,11914171731842423040,3005938114815545735,9706851021010881208,15297490479616048089,10013837458801579300,14369960189453774629,1894002110376124889,15178237788589600623,7264949192124515256,11817652586837655480,15103258532123918069,18345991738524012423,17924290879533987929,10070966144675640769,4036268394773448277,8207627695590171228,12521789093920622904,3994523146164767277,15884441165405962710,5267566297598091465,15034750169418631094,10809414692849407896,8976569347456045984,11854562396135561715,14489373621410289225,16211443837929540324,14918661173958551665,376450455113277953,3099455575234562191,9843767859503897054,12413361011034775230,2294728692262187494,14736939895228135550,12792138071338268959,8422521270065655473,12627591890411157140,15694391973925042593,5774506616474928916,9088473189277761394,7016152431477436252,9447587742456591439,17916797488203837912],"proof":[[6120389362944172556,3825146323069482065,12383841665392586162,2689711096329993375],[13642840510810559222,12279017376277741292,14224250033836105488,966014633920856891],[3504468798017465750,2363773685553322724,17976941477095767118,1933407302299088849],[4085515140995806540,4512819440954105276,5982343878263959108,936209207587973557],[10139662776072832744,15619705721194488177,3975931956437813171,1603052970023861569],[8453849919307092691,12296269495704581326,2143721598810667385,1927906664677276470],[10188837803326282649,5991166516152777311,2189734958670651471,1452985713154195150],[9619593424935331992,4987176234611855086,11583345369381780506,3037771297276856713],[10690909958040746457,17783148936128502689,3192296259061892329,2318908079182128924],[1508272923037230783,16599100383134782183,1362879958019308681,1877044066528613290],[736051928442084714,13996136793561635304,16064150511766965841,1622030257075208925],[12569192502573143015,16626706419100452938,89526480532839450,1151220156167419616],[13233111940330375337,3721613951002169723,13215477271364309671,463369196759619265]]},"fri_queries":[{"leaf_elements":[7593466116913793084,12049250193739827221,11484304673647065289,2603047196782908067,15463217588619988919,5367680535892970547,12409291087940659530,9536087980858550485,8027473529915763152,5651982165636901491,2400968635426681042,7384319209154395184,651830685389618418,301941204416977917,4717899314830935489,8407042854200961132],"proof":[[3633009163582421413,9385965418364950576,9060062061925219816,366441586220641064],[10176352800770996322,12413706145595610568,13046118764563645394,1629780734792557536],[9119718942165750961,2983726360098634819,12926224294151582096,350277912211060169],[5601518469438532727,13295691631628044514,10696698730253389634,1363962320400451102],[6167104588419566178,3625768114232811071,8799666038245853718,2500600228360389698],[2651859190920072050,9346738892714991781,13417680713392588179,2172383307307802297],[703281410541162485,81937716967863994,5758883802304623415,2377962109147460982],[2945639535046352386,18040994403281453872,5996673420161924372,2821830344895488563],[4804235064255669216,14729952626711900118,17533787292596999691,1688029707652464723],[10293913151203782939,17276720635789980012,10145594858043310023,3455109967926550842]]},{"leaf_elements":[9824936829806712907,8409159502656099007,9349632266878839544,10022800492355573524,14321956622795827960,4867351931320697776,6004566829844290482,567841505807059937,2944156350216799334,6944598728550518762,6809798537249097948,7932211145189275706,8424188677194793794,16262578719093728857,2612261422447080774,15187912580008094003],"proof":[[17260859401690033265,10388129597387984001,7605048808194772234,977241401799019121],[7618912741438055598,7199568753683981058,4743427605046249258,1294987760390040212],[3209022440049319388,7308505490900828086,752611779337425772,3261732914184277114],[2577807755405497397,18141355035645237622,8820516844858516269,1868509288398581249],[14708966990010504020,4452105162794639184,226325883480207383,1404688822222607006],[5473885783605311085,4026771276107960446,4742656884502189251,2192188515716722929],[7407740297327449151,1602759275088930253,1080223580461385578,3082418193151690999]]},{"leaf_elements":[17356559651860261601,12725442532173348047,15597425032154248096,8143773272584448380,9651626334201672884,4452841545941158216,16352824483281747528,12096256978676876977,16533960919196670103,1267973754278080950,9881509445871888062,5400710465314869476,4075577429598672956,13199238483938231281,12280597211204560789,13807198767935685743],"proof":[[17906617555350196716,2697734889843229528,17760594070209285177,3176982764010391975],[14690733459800600196,6625699307920514996,11949566284692742831,1050059442516129033],[4800217489573654783,3149554734942641022,18307580925378185476,95013896439469199],[12700299161953849936,17896603572231004330,16616459751671690607,786280160165782906]]},{"leaf_elements":[3303258396085125681,7334765928689504730,14735023820760202469,9619724676555854682,17674259656641861264,11577514084267056637,2440871980048415777,4361546825864617734,17764661275648454126,14367408337706981883,3009606633506689442,9303345605953149770,3068930268487580864,16855781256128155135,10975044962187852064,14887023502175238661],"proof":[[4082544563390657584,2428803467750713898,15919672509928983616,189310895045026976]]},{"leaf_elements":[6485988802393016559,12130974100501667025,3138003141619716888,4081174251100168420],"proof":[]}]},{"witness_query":{"leaf_elements":[10948608990163227128,13080402112615684659,5056632117221534878,5179122557052011065,14280555615800489988,15215866869197767009,14639878439318151202,4937772994220400576,901471331186647715,9904143283048911486,11448020057007109787,18418220562050784801,1728750718733254404,10640309183980534752,15338479526583134477,7594769909809409311,3973355773734332874,6777455742268323622,14221082866613708584,17097928381183461050,10930216232016309462,6563556897920250352,3252174521035555100,13946965766362931499,127690120843206276,4484059820606001333,4680820001604924451,15141936337901292493,17875995888828697413,3077619456576804432,4420408036432383205,10132475709956562285,9024515746681149143,16471120367444585408,17661834828874072612,382656357492025440,10965657697126258415,4129005695921358931,6653269598371082444,12517376599283370826,1307055285630565048,12919723214802359500,10449464317891394987,10604047280587507623,280135072838552779,7624284112286923233,11413033528806851551,4136698047506480914,12541560567689160018,7379179272913896411,3527745697751705994,342582657268951570,13614578386025392991,4167908547523286654,16760887774909532034,13111657504024791460,15904547775802978702,5704011330552510643,14484618222117317199,68123973382439454,238345405592604145,4548982036279381415,15778560409042073335,1452890279478912614,10420097475662107184,16447882622746687787,13077921611285926216,14786587163713146039,16822373947915528536,6406299255848669945,12000143094115642065,2568420385853024272,9608186472276636286,14683121584768779342,17948940295008628489,3533861912630195278,10489087319736580189,4829662785031772434,9417024415857857166,7364641003738583143,311556058943787279,8507060643047758011,4671082095776734475,2885218942159518807,4832382225512582594,2400263671349892695,14148362719890660124,2911307775513852778,7342343643634325704,1593515845211667289,6309880504111475014,7524373643044862976,5475018077983646732,144331500193379737,11107765325741596189,3914697109355823440,11459038766642689349,8188924239060918518,10342138531156542622,5903005755866977254,1057632374801015885,8253572756457818029,16604645327151432469,2202525898705093529,10494352311191666459,12298964260206229342,2903037447903269992,11162520034331468019,5403316407460304972,15674732230463605912,1799875646358882368,6275162083218995941,10824192801552998552,6158236629019470176,14765314044947498432,3877613781207497594,6887951793194136203,3369174630930526657,5410868023143186442,13935658388347572572,2671592007964255518,3576649878696491403,7758598283222360919,14635738848655492497,17623066426748536391,6508886273228436172,6164689256437411379,6162969979372602769,10485509195960048532,826045809743113912,2305212251269891915],"proof":[[641354973965442763,11973773562846195918,15716773302775552289,2375445199868569637],[11338168376057459716,7429640503678000295,7894650388308054773,214439383964834089],[1002753620226776010,683436536266077991,15617910541560189619,516439009290669978],[13740023795518092083,17414643979500597022,3927086667114064546,257598443055661843],[17724613988974911537,7442841772796744904,5737761243319424736,1582740763899330529],[9563955369455976350,15564608757126423376,7403160778189075328,1031250088686849310],[958395804773150342,10391740962294778912,16067530702984675585,243576660007763988],[1324334757951191114,11938579736706683050,13787601639545095410,2487961541127121946],[15966010173899575476,16694295181009117673,8154649360638629849,3082835869181658210],[10991637116190393358,18019713487067295977,17446421949851256750,3050349447645948172],[17519159683931686705,12492084838942994584,4278902334263638617,299615805260675305],[15421655209924002952,16368321879835928311,13763176468640007060,1827063992316191969],[6319403942848876859,549033099055625544,9838606079043705509,1442728268342064409]]},"stage_2_query":{"leaf_elements":[18078921992501442493,16025302091653158089,6394095920321771176,1059072422699995623,18275949780319325322,15544733974203846581,8981589781587884959,12288844072069828718,9319535323858760503,523877547113472647,2773281462578011879,9470873648217905933,17216457349528257860,3743428342505149795],"proof":[[3206472958645584540,17721197265044446226,16666249761139954803,253083419056782582],[15433232623219065212,8870498299452351550,5391254146282617936,2950178265608329350],[6305026117270676758,10255907079024160789,14657204915106568642,1354715459037427669],[252591369529932403,9499557809379910715,18079416270181668859,3365259689254567922],[7076280622445693518,3202395591646788165,15537995976987120533,1432010064834273548],[7518196019677525884,14491270981674553745,1378183218543986638,759504153005822151],[112731219400492953,17483054213384243347,4480802567320003701,536051587215848890],[4197137441227371200,5106103242843746529,6392802264378368769,2256786522559778232],[17097419543501439209,3258780264697206465,9553432340640827191,2370534050041055915],[8161609323598277935,8243259110720593217,14746445362519689663,3394881238325177171],[12870233950447818119,11764028962045992496,13275299065655103485,2880257295026148580],[12021982420473469380,17569332985180571919,9131874529933552696,2059893048644664856],[8559229694106243581,6083801497235235894,12366925889308928834,1093878940771847338]]},"quotient_query":{"leaf_elements":[10376555380930332688,11924278705749461287,17428412680359229908,8035649791956596598,11404464477137628828,3782638743578298716,17585969784099042509,1017177830650272924,14939271554238998908,6495470415943637973,4849785739647042705,3977474106461833214,14641638753307586077,9100221439726997639,15749613083380279848,4457644524811573350],"proof":[[3570319209644650816,2348673796955386166,9736063582503699410,2108907108639390050],[2754379874314766022,4762157201929967027,8072852374034011343,174921306742931785],[3960505193345395022,15488424175106794168,7896383840125544789,2805913692715202217],[942095805786504661,9778789326129797807,17206978635372081924,2674182482808231126],[14156059056993202055,10150165172927490159,16886132173807662861,598958685623139776],[6316218635699173131,12250548208633333489,16455310082050558004,2555447476004937790],[4924987783868568147,2580754240534766052,15912556025000918445,2486442940293105932],[2361112932274392430,1656148842673349073,9529736211928157283,3241033187996450491],[8737733325985449066,18084582606328121642,10729507164405040832,1311419404844288159],[17100118263872496389,7903234555707314996,12864163995324146319,1878754340965457911],[15297750724711498016,1443615784227563352,9384081075577506101,2050232170265759284],[10864231025343200565,14365906828085033749,14285158680845176124,1852444960593571030],[6742689458430904017,12365859125775949332,17589705338515253507,41352540069468767]]},"setup_query":{"leaf_elements":[3764552311375765945,14374207044287426389,13608147336844623610,14629021348244652058,7764792962366766697,595306068664656740,16898134534166706572,2025628589539213445,6959489890083421772,16041624385482968174,18378709556105772363,3329646402887407892,15957654418601589796,18107706551197655004,17069740348977628198,14547725710797039049,12478380373678473287,6396957463734812102,16854992056446613133,9760888729558841383,1527435257852608354,7573148777270580439,13108542019434658468,14385074569149558112,14149530729874465249,9661926892694668801,654146180477490493,17915157032760738661,453331652685728606,7922194193627070803,14801978190970631596,1363060634635675294,7569721907480870266,7612936902229052611,15964545456132520918,18286288187734249019,4648626881252381242,17856178241069855813,14325008259565782024,10737910371631014574,12458204078528107101,14153873292687577726,272283911625793639,2262430812377976527,16994735043898637311,11799139657465883623,17220101335680877643,17852991684842920811,14283186294135672851,471016122170882621,3217781154026986677,16748344574745082028,17518660106639067784,3504765042114877445,14639805742378128888,8563510953995368,3373069420229154818,2268859717827840473,11931267797710811364,13940138388113907255,1525026278642031061],"proof":[[203380327713015389,3282475248191270501,11992249411557401169,726814000288912346],[15606555906562305323,8625059474002376502,11190465140427478741,1527129070263221971],[10633121933075100136,1743593751501599338,1046950637657995167,2378414938471157582],[16925378032266597171,15898957115748881692,10227946981672981952,1914126051450500377],[11140209243379188290,14294703103710060672,1294254410473257234,1557770099872704904],[12763040157151374736,7066532933116177298,14688160535162025175,3052467370748413180],[6181490951601706551,5406796261818947791,13054184268984362455,53918725015928641],[12142050682830054517,5671486659038295027,1637862139555233275,2116709130481718336],[13166692045942994746,4373822046750605757,16944609110448390180,3439714572390836292],[7260886529189317407,14297077880355957191,9486960744506065432,463498015442889874],[9902139823942639191,10763284980523859807,7173184343265808925,910681841653445455],[8290037536677198273,14658697448777920115,16438037693689542587,2289856877963691407],[4116420957544392334,981127288402861837,6702203925816007197,564656793942279335]]},"fri_queries":[{"leaf_elements":[10142493818528990422,10890883423104430215,4960440988358238634,15413731859793085947,10424857213265133314,515026826915083284,18316254226924383181,6667781217113645946,12461380924111507257,13483387916502446451,9625331963653127386,15606009289521509345,16437706570064222238,11395539896782897597,9210570761304356772,14814180580117774467],"proof":[[14745856882003139034,7122574777577757823,6690239491744104122,2907157762711995284],[3939419401513045091,17995703808740146088,3604549729026179524,2099417929621913556],[17604713582700663433,2519706725714901756,14967490662308732316,2753306130357077864],[9577867943747877411,2787571589775719345,2274430636526384265,941280492538410795],[3290475972502984525,13501065159653410898,16720797137104555600,2381128985642985350],[12088988617052139771,7337368987482133376,6421866122174010281,2922247744314534147],[2612677933907930127,8465688693440690668,16065874207475283502,3102971380639974586],[14078856757752134775,16217300030537981123,16993594411714563811,2845805971970989621],[12459205945557951313,9658351906122242482,10911664809236274781,2168571547161351640],[10701620580987285083,14029228686717680906,17606917425319476032,2505274531328869815]]},{"leaf_elements":[3282273792998156330,6905645732587374840,397402934540905899,10305006113288691100,3797957403648442834,17530991030714307611,8740610252405865517,10201154878403770289,17507623662960760799,7479941277305467220,4121091990169409881,13044152786341627677,9725912955932299661,2463430367201634169,17002052177331991830,16324836131565836747],"proof":[[8792653742403108800,1496303395956909139,6056395937854109279,1000643383959152979],[13087335475085284763,11456002641677980584,7751791080058485759,2258721878920337936],[4599934747781904082,11919381319780538468,3047433832933385138,1687477995371671941],[17632903661105489631,11315557563274655423,1813175877983102015,1410008926069540140],[10242510154156362293,12182112277103374202,2592047013658237490,509195850680426011],[17784093462431197239,12814742217395568791,6508355028532470827,2412882452421209535],[10796312805924833779,10052204889508537523,17029417120171154458,2380688193371945324]]},{"leaf_elements":[16887769100482488348,15266904209205454232,2363214317348031805,12815356925714764240,4087500884689587033,1645017454326299089,17233302565082907502,1019982788229449534,404981045313298672,16364394872904230554,16527521354377696463,2603359862988264562,8636601554630138622,13533729068690122063,7747417808260565134,5933815917070666780],"proof":[[15968296949295101371,2890605523696032543,16961298101573001645,3476101181597750011],[4303536558544980372,9945524152286140669,12814948613470899335,3435840979935024480],[9037746557057048456,17834278038352391830,4656790350218572942,1400337594587714743],[139744036230662203,17798083038650091172,6031175594198885029,2124951385919977084]]},{"leaf_elements":[10414973603641774256,403394223439685500,10536595545238386023,14417065532054984200,12384715249560097018,3156902985129211271,9484383719828687856,15924333456246663000,7155148099983750153,2808246294803892123,1669609172955553579,1751249439668137723,2177940236717868821,5260503247396225335,17657695492767045645,12121937833396643927],"proof":[[8669456116196418953,8307641683636278137,14371410889281616166,2389164284214036631]]},{"leaf_elements":[18196018707140134098,3942247739030689718,1556687182756891542,8508669979898744338],"proof":[]}]},{"witness_query":{"leaf_elements":[3962889815661260570,15161867550712434691,3911170358510557726,17698418901784047298,3161078688420392201,7049819072221703564,16810042304707629367,8275547485725686169,11169376056686419820,3044547994700533104,7697780703438260166,17140582457616141032,6143652166448152702,1360476923880512957,13343819078934263381,17441864749432171954,12780993909484689525,18341167840817229626,17160143544377777968,10406128324327868412,11396615332652238806,5820192977517553183,8691968096472969032,700205842388412648,11882731743295309980,13072868433718374562,3182854894564230361,10550807895145074217,2802546122368274830,18059931359829862986,4466404030126048996,12630813412671510748,15686053114970965111,13290305275209243221,16944363025684777451,1706183354751171462,7188248114283463674,5126533065965601683,2110018146308268184,15662744623084294197,9738870662530876560,9862740380172797443,11554335998925001063,7815075112665365910,13931859598318184251,17203130087082022689,2553909148939944488,15883312798482228125,3628126591023319094,17962306179015325930,3583499395313826620,5261028341890690727,4481034910882002609,17080937977243083430,13607376762356388123,15726506932837014323,9355038896992969183,16875358311348163929,4339907787735874560,14942839527583469424,17279618369426858391,16314485321857870291,12208678949379639941,17649964446643292456,12394915199110004493,17952944801067331526,4998999723301419355,9186317136631691469,7416955975663665819,5520865025291338468,2992765628849278326,13639061756412612534,9461776076929839806,8384706446948112968,856257009943128624,6668331079233920238,17113005703696762864,16532387582513963729,12859699268976954407,2384628098975301787,9219888142850457204,13953200897188046716,9514556169288911104,10878358037554160653,4430504326536355190,11551907072652651753,15561851437520232724,10642992478090755258,7730286266988300230,8041553651059352345,11314211807038799988,13703977196385175603,6756984601205624704,987659667278110377,9014177134931842005,11277918126416955202,5276300667989863615,5387585530498533386,16443562999471011597,4433366552446240175,12634221081299707666,13323289846121780793,680663491293341800,474632662696610264,2139194625041510289,6212800541330662328,1561449392608023967,11113214570721274819,5528045066189393530,8403635273411657067,16175746452494311170,8294609549409808768,7414368897841055387,13126572269564992243,9596426200669943446,13611427237894200944,18237019593037534204,729877300884240425,8953645815565633410,8957311921873906825,2590929647952486026,11026816316025260205,16456914507822800971,10473255223030528936,6900325806479352522,7409346796115163910,15127447123777112670,246836624262398941,17660437430140307190,10231549878358464404,7247023845124127713],"proof":[[11663536692407190158,15624092323535998481,15060865244719020511,374840630584780427],[2891863002770345026,16687282782677773036,6339075317830252011,1684513210813396775],[17256798040996112963,8562686220836260176,1355955658532450955,250812377225686417],[1320556973719842302,15832828594527807237,18244038913558965323,2152715016259395730],[8963600232214250494,2332826689216112029,9896713000852833649,1544550044165961308],[11682940815439595943,7876580386155799842,2391952232829747289,1178005927844422430],[8955736969124221285,1019236955411120588,1829603986881860602,1952405883413114328],[7302776577819949345,13906052307400051169,12730990668134511003,318851399144414331],[6749417622445779427,15811057044516797574,11683726509721346128,3359379759309590124],[8731331459858555400,4794785011636928767,14014502162874431284,3215988054991918654],[4248797211813909895,14040089604235735473,15599987940746318338,84186887586394144],[16487596398035217804,9647644250171436371,593772509881424834,2167801526081690019],[1443710191567724466,13285942274380957982,15597202445998108376,3018040234733100453]]},"stage_2_query":{"leaf_elements":[11421357704744088411,10207652371119536450,5633798171953778336,12004084731100464039,8884705824149997436,7036779625383514813,17331489121881184134,16565915621712924051,1412506771319253743,16404470242119086580,8255532869265007055,1611570813804528662,12569764168659331519,8472603010635873315],"proof":[[10292849649435968312,12903295425651317128,1224847995076964248,1561758712425194625],[10490025321246722194,14420882499486198784,17970182773226127618,3406982288575522460],[11981641012187775819,8027894651075132098,4743768053263310682,2165723375896218305],[11553378813931839561,3699978287936880331,10568910472878662135,2444917134818256723],[4114384377893805622,6332258439799649446,2890776995741054537,2256092399705915049],[15795949829964541498,6202442196016794759,13099354472000341750,347041800744032905],[9858512376858999906,10059199434489536759,10785031154940491554,3407124437057352486],[14649021273271446910,17205349074018550010,267951168097989028,788639867851042763],[9648559609763952530,16523746994175739948,4076193922027599233,1339863291972475785],[4048860296270760677,10654584233847122785,17658554602779271948,234782811802859205],[9556326280020632014,14622049087127220127,7188791035379400675,1318738925078166584],[8763095688229377138,4203027844693350601,15839287648717765419,2464465881556052390],[13192953421021811020,12135368163999496150,16519089414246052774,1297301135049925818]]},"quotient_query":{"leaf_elements":[17713079287154921508,6906158046729995901,6711156392131896377,12166941396758564595,17640211418010172788,9114454597692335520,16271635955789858841,12207476447326360961,9334008067251068042,353985884501362121,7504917167768745954,7530330963956234830,4802287060524569491,17042203512935709987,11932685526657453244,6003115271079304638],"proof":[[11635944224569890151,8662494161941631579,1070060936062756235,2250616879758385132],[14979452466406446124,1969305867074761639,3634986204783468211,773834326088914046],[4281290440736975167,9170557428193140340,17095349600930348359,741627369716118115],[6623167725095867911,3098890897343819202,14462329830999901030,214493571942426815],[16807559155238527922,8326399232015045894,1284422786198510834,3036892404620382725],[16196898396562660248,9654519113073378710,1712171710949493640,1183631445878773996],[4350625754085406902,11517694987252069397,3296123057432391864,514106483018183074],[3756975171051023970,12130035998519558427,4166339418103352019,1089322710949789529],[4445228737098014185,17026879312714717423,10345194716094813465,2972546250557248354],[14911493800648682030,12034837643726087066,11622076309937884365,823795144246392576],[8812185660268755303,12934107594033073921,14594710797974305940,1970618438189651963],[13741377562277466111,1944538524945591851,13834278555587898987,2841913467563537476],[11100972887232792717,16842313487508060518,6071017510380834699,2105986336062779306]]},"setup_query":{"leaf_elements":[12053714771923162858,14482988259826271115,887797364928522229,14538833392368103919,10730876747719148196,15091159698830217185,66372659017573236,6163270160279895413,7311089694961102868,14545290557877308729,11684255665255370569,13832879722335621311,13849986347257594264,9329283346277817068,10571395048314439526,6208116032049006218,14640471889748820064,14184471552555394014,12257822076397954917,4069662575504633812,9868459618746965140,6466879752685579861,9071484346947709091,6362575504298193867,398757968034923427,1494813380820702897,1415720525813672753,11370151113648537538,10181963431871693705,1546307599756108196,5369357896993119402,4326410583917356003,16441078837140117923,7409290866814046682,11559165899948395941,4716928736950526144,14330815318365269157,6329360381694689933,8279676983953697929,18139478222380840772,10864821396093098650,7097262679221435018,14618310229858991902,3849956783617050154,18288038842497968034,13764974567954832422,3112571885935850587,13699873393700343098,12935566738840790242,7256881134898714825,1760439194013269755,15547818514165636783,8106949978640969430,16158798802751611486,3075716286331580626,7922207125356220208,8603850409000042162,9263644074220863858,3343839352171994179,16795342962507284437,14661789409676238358],"proof":[[12350015094178640248,6153994040542305774,10470620031486120144,1686246240629544349],[10035475324239791509,4399385379708581808,10921776032177513515,188849344235432135],[956438246790720008,16554888100692966552,10368036923154755599,721257101979168088],[1310864221314741422,1619635611169252373,3050635390076580587,2810225093898399308],[6122091100596310528,2207057575376700151,596568274257464859,951248558108911049],[8307754370244055714,5647568164644408554,6332552744264978427,924219161900484841],[6963193043060615188,5664957855734920570,373071700585388638,1784243811275572018],[10775349345562124160,11789541010926585185,7162463088317456889,1730531058206314203],[17613823959946941782,15422043290643843880,5308430791448064798,209089946280225789],[6655436725026151787,5261426903001576465,12735392084318986460,902252469119205088],[11428864581181648815,12611799512637801373,5370448499064147956,1416033710994386171],[1625000981274062376,14334696978480106348,6441995967927892212,3030286209213344148],[14895236666511632273,1399194341617175758,1368280455654082000,3365187953082285783]]},"fri_queries":[{"leaf_elements":[11365558775523113028,7921051751083588097,15298328421529438668,8269588853724167935,7904973835856244099,7502677851497305320,11129627246104310199,7405136349899157944,17416365074362859008,13532744317121980310,14727775716960568491,6193847659699944617,1332904864107079492,4570249061519001561,1755576673692375117,10126325384021961543],"proof":[[17223307741295849326,9326426324225991587,16994853498787523531,2241867103085443093],[10671422301438032726,12852377863287727709,14022223694259486525,2913767704794616237],[10569889832671938706,8533263608566094355,5841721696852230740,3458079105581718067],[10804176444141187544,286475127624724500,15979219712928423098,1648252736600077131],[11927484988502661830,7602415419088774444,989572515767307219,111294091281084076],[4926925710469094944,18374657107725105406,13296810771716392518,421627518205276267],[3355396946822226001,15837241923345079988,17188534636111513863,691850309568703126],[613459326179506739,2324040073875118185,11972155232303911763,1528656241590597161],[347176974939002625,7719741817708622723,14418590971901590662,2029569711632894471],[4902605877920861213,11701332700254187564,8706248708951556531,2700469757148440756]]},{"leaf_elements":[6902403536511510366,4233763010879589305,10690890627600794200,2410007705279819265,3735375793450009574,6175567993029505291,10028130504313962258,187321022152669904,16360617219432859975,1626333879234870152,9460902757857504650,15708165420261010758,2423570325039866785,9244858248057662136,2744735092066823696,17732936092121075044],"proof":[[1474579119523734765,15496760468382264925,15528556530246809523,1882665644262054184],[13693394450047548842,11610728349579964332,4113885620485865575,1171450943386644307],[5392917045405381209,1487675981312816052,5697406694580600752,365780816140201001],[16110639326939105299,14365603980961760813,11377919323609459290,627961758965310213],[7115416922232224744,8146080255954698009,9062846923992120040,1349124095773385961],[14981366453569600762,8751061205393511146,4656728583089136557,2901921338668318906],[18139407998752333981,17909362892501148452,7363527141544631108,2985762817603723685]]},{"leaf_elements":[5089704405242328048,4610293652415261191,6301115028294572990,10966047133026433313,18426995840494730531,9230550097232456802,14942959027480939161,12862176383297900056,15983975016420334874,6776121426712139530,5293254082614396806,9141383582709212896,2578561387502501197,4257557193930842761,7508645388646954335,9252965497429594707],"proof":[[7201592579686222510,7964557712720126612,8260767976594055454,2792518390170497744],[2363389257407655291,14771852290769972522,13544844909431106986,3165032970444982491],[2498404504816880002,16841764584222148124,8463928566302136484,826219200934473404],[12056361099189973316,11445222606787504472,16233639641333485004,1561239046487682830]]},{"leaf_elements":[17729354569920996859,16449461548712133538,15065163420655373648,9804137193794166355,12383677593442401399,10114681989149391484,4432167545295727131,3779701101209125310,15177492424625855301,14521020974475802444,13362237075230757592,13717904117314483410,3196402900380536253,17065120679399165829,10990006025068578642,17916730893864383515],"proof":[[10651158724031988562,17385018956147728316,7353147695606921272,1616320887286571537]]},{"leaf_elements":[2512589913085626850,6670100345702245078,3875769945896076457,15189048974320662278],"proof":[]}]},{"witness_query":{"leaf_elements":[18230675930824400076,16595533684105107657,17577311365932956162,14298821334219436093,14288821262655800840,16172663875560726088,12421802956325100135,12891755406272754878,4801706781739507673,9973875544561861592,17918746412423931859,2161349845874181869,3219887910480597073,11866903925117267054,2354360384682042073,18074070505094901153,10065671238350002919,1542173248482729245,12725472968283289263,16652097410198089526,8893026035792779486,13351066331738058808,11661543644489253432,13296678574841267095,6403545716399395832,13960333263316130043,10394732883171875202,8153477692617993832,14304716627552823936,12282009767042433789,806442331091857239,16189855777882191060,12907479170582876224,7564571452353698580,7198976836751850122,5105533824272941093,922439113722769499,2678683144279544919,8475876890352655937,8780816633973272216,6964173669822385917,627000493042619616,240515544041137189,3385275986684613224,9372925206388616037,3712890000947286625,16666796115362879407,1812491080545730865,12544232380481930304,16494379636143404191,10182761555653995526,10383756204388599830,4338684877330542788,3056216511715987070,7743991589729286217,7198618674781505652,3080170832476940937,9332879371987058012,13059161316358550222,9508941988348478313,8494899151309521580,6001177421667913568,1037070178511344508,8278989252630729900,1042055951872099621,10603340447417481898,359894391471207873,1466318159522678812,17292143835125513308,10526796713491276947,868465360825570518,1191898982693169553,5477633786500068057,408746254449562224,8132210652683473142,17285697394288294671,5063299857880846584,12444555392875490571,11090916443405143234,3830973425082756380,15104701553454812676,4604673844790656681,1018430400042691398,13737726055465487924,17042779024400020000,2088468183992264517,3519619610507278107,4581539140843104341,14519095501707833751,14138620890019371098,10843515359162065785,7623849722272735588,2446700406187902755,6549833680612650180,6814195132204797745,414967919585910373,11837215421887418426,4245843359274496775,11853341504847280646,775307942935360976,15582124563958021527,13909851690099442962,5739490547679243696,13622423554920821468,7746571089467233830,13383477080729360094,1154903488358651214,3847681478867068115,1134799978786970507,5637925741144316016,3373935412716015288,8406674984603945117,17661528536382266323,5322102731710479527,12819001402546927240,16449348977660943888,3215305634688428992,9809290133991081027,9314263429546171825,14785160362600873197,6519857300122558590,12344175554016141571,8917315561197843317,13856309723927625428,8885138172529535241,3315784085833973808,13790518505640448429,9744139225799528996,2924201175781860965,16730323201760231444,9849562383789832647],"proof":[[15391967061863790644,991320133393979801,7509520936245818274,585675714634736670],[4309294429330448722,13500616020041844245,14937930865520284181,442177560597064992],[12549591832176972594,2619507930794936239,13950489922379648580,1553643134824494315],[5688159794566396635,1949053264296809375,4607587191155663063,1641604807702577937],[12024257264089141971,13715693851454031557,4711364852662560912,2796708038062309596],[14300608358813429937,7481965439752467516,7661950216083765649,265792545838411720],[11217001417946782819,3693756236845098794,8873500696175729936,3222496416717953473],[5217067104807152822,6982551089863362117,16332131488522146933,3414053151462783329],[13063433097419226695,8474230318588280077,17785129528892561327,2101846788854710613],[4893893495993030509,15823045525216911365,1873200291009843091,2705986321176687321],[8124719023073524489,2130541610055144762,7733812074658294348,1008854424278926615],[16024126794043083705,10899560432999881639,7555937540337753015,546085181159407964],[2086040302146157032,7810162543658900816,785139048180578586,2799343072935149560]]},"stage_2_query":{"leaf_elements":[15972468157405660357,1951458275114913953,5659191139327913645,15916854616872787760,8762759590737736387,17832086332668988254,10939416553559145819,6336958668623738429,5487715789907254723,12201645271037195064,18134992703650543951,18415702513309292245,14207389114978199104,377689062033844317],"proof":[[2215201620618307738,3465232985094332676,13760383512129898131,3391213938470732138],[14212085492247514962,4643565280390090862,434635496078501992,3236241720232112288],[1470663261730669538,867416126066407068,9053924566439572727,2478483812408605958],[15531452958666125569,3102328439179684856,3088672581507834147,217034202294167745],[10542719710211101981,4666625189448481675,15967748846436612354,221770601369274021],[2209389786920166772,18180359717919804411,8215353619363357683,2796540847214850099],[9418686405935729519,5564722633530568778,5792100516840448134,501598936209246747],[14854457835365205336,11115029264391512417,5647269361080042155,491557926211684106],[7371626235160580442,14067292795461173391,17742305600708223461,574009199502754794],[7418339522154074638,12256863408392615837,14200790661275491639,1086030030070335832],[3665789200818560555,14234365222274727436,1221343164647597724,1835486777221736649],[10420647029832961792,8377141977636023760,14908232275114260877,3232998643597040836],[7020421133167892612,4107716798518306815,902385229600460307,3065494559822768460]]},"quotient_query":{"leaf_elements":[16325142988481261055,18264834875536563475,621655234203065225,5080519365740676697,8582890086999777596,17903241066428200995,10417713327602565000,1095499404857323226,10273224290677922707,14906573230093901373,8567252056271553113,378712663185175478,15444390621720513039,6631122968783234083,408370889788357677,9128069108688271432],"proof":[[8224383590707373726,5836250632028205150,11522877984546703397,403666042010453364],[12749575490177252658,2218880308055969533,1345717315252077264,2217692255971457718],[8617582651872237679,12600761573231126956,14039673741618284371,3069866218102470459],[14331553530143178657,14460907615239460814,244824966561792526,1974028319327813909],[5251147302587626613,13781516117922799568,14556995222635707536,1294751553151696330],[18335766699050386141,11754685525768759670,8871140825396356564,550506917286100459],[3472530869255658858,7793324451951682859,4811769540194182299,1554373082650778545],[9093722856872479065,8706794391678775063,8249510081892657243,3088261095409334219],[16312195808758058741,9973726501193729222,16348115344508485945,1541547708588511309],[13430307604630920964,18116456937465028445,7766145159982960540,1624558029928437083],[15097912526145131356,11069542579246812320,13941441400201535295,1860726448453234564],[15324507379258823148,18076066785690353175,16637166118380240248,1916966790277779855],[11309577697716563607,17722788140558117797,9354329122003178154,3161978493615211441]]},"setup_query":{"leaf_elements":[1098808134876543856,3568111961429263974,18109759359436550675,11684153747127255481,18097129057816167470,17702677617513850234,9994370349721416978,2793445120714689562,694725871426042373,4494116369117841348,17967141338428677342,709878786070132622,7640613617933516013,11891741037903967950,16816767528053648644,102384597816513585,10986270831138488714,6246702482804857472,16966113934940644997,3712654697093879597,13499421609912695131,13171289658979247228,2850259576516528572,431299036789264381,5507302990155316739,1303224020572566904,10220150248497029157,14535027367901378356,14042470286362488143,17952146041474199324,5950587132775847548,6791406399969129753,17804319928265483108,9330653754087773600,16042981078876243764,12026307393247590737,16414156809431528770,15677845366231796403,16525090658020854522,16250383096397909562,18380014721978608794,13843677059754467806,14362672105973970492,14789385404530715078,11091514993163816232,5824567972401262215,1850097385151498586,8161958787006978736,5315311158818352493,3136882113471337240,10218961378792663383,5264395726889259048,17685187737462367208,11203459817119065661,6868185041063759273,10643460981625435716,826451388212409922,18158988945814872906,5369321391082261794,15549796955418463539,10163367537347987844],"proof":[[15190988491286039467,6048873316158171360,2589213333993697434,2964258865139051109],[13310282971281106010,9642222031945911650,2254699869888060858,479138878758594127],[8999126256510156348,10970267504260062330,3595172384024833833,7997193953101100],[8458061344885015718,4531866945385575514,4943684467382617369,2407296924570074009],[11613941584554434004,15507195588551073740,15936514648694273954,2165430402585315681],[2198733970661511042,7840786235508765287,2797918137333009985,159370631426131144],[15281392057394865904,18031834860158843165,6797016608163496361,1010557033511692801],[7853686392660679180,11133730251837138863,2509685931229959853,1669623715302307391],[7677379544709503210,9548437124723093799,4252269420038742416,3465854416824477702],[8578550300206018357,17976483431619634566,4333479813720410445,744844072473968285],[3087250122740173921,12214099895966311783,5062908482220159778,2402824971678283790],[2887290727764094442,17085224331222863276,10457582396987618584,109691295540185976],[8256807376369432741,15168980514826175640,9277870041920615508,3198794032107338459]]},"fri_queries":[{"leaf_elements":[16498957595019353038,13834289085620096957,3389511900442014760,15260942824037845581,12542062603775044150,14224565546524167716,8057160214737232033,1616823917359374245,7094330398198617318,10741617935678454274,8381578394379299393,11821722775985865422,4148971454995232547,17191509380423866744,16747022333052900886,7716407084189670991],"proof":[[14956197343033536328,7532732853148792388,15897712929354183077,1153985219507451041],[12347761953330684260,13732179141782058601,10274181888368430700,3032285607702938556],[17127228789861504680,18405248455057655340,8344323689377958361,727202307743606842],[10494872470707781598,2222059986104734239,3722515604346737520,305450980855820511],[17200006530288005938,16568542368121053277,5995413581143989620,2315010180227189934],[13062057060307421512,4637345856133055062,15638274787630697232,2241206183497156618],[3198011279018543860,6070417269250646182,17820811483147929625,3056087012536026021],[6755771788124095350,16002892849360200122,15254603325947916879,44297949988231212],[16992438034976970084,12642660533012434575,12773412679142479647,1225112692034852006],[13622876694477883628,5833345947361085782,17891337713967508499,1013791216218856434]]},{"leaf_elements":[15348926202552378971,8532585800608605627,16118646465702889073,10591711916494644357,3358720529444722823,7779983966085245760,15279312481913536138,13406181772870950304,14176626246163010131,13605077514875562695,12418976643994759090,462016917950993869,12210032553697514612,2023882080881288256,1389776722574866948,7704657252974253176],"proof":[[10247840978632702283,11677368859836294728,1724081946466110108,3227238604769735198],[6277032646386321064,9192256238980841712,2881547728001363866,1954913252778369478],[15633105990443440866,12075471385194267671,1234056365559065361,2380661606584168539],[5792121167419933376,17646023236016268436,11594108727544920645,3061043322625973802],[15952022580806899884,16723471596644711299,4178946832376223244,1819146468093577214],[3819540347607810344,17116963439094612218,16523705837782870267,2297782081394439321],[17500939717838253157,9705443385530785495,1779363690164319671,1074122371231927020]]},{"leaf_elements":[3175751985462725434,12154395394042003087,17991628131226096427,9853028857148843118,12666890603694339191,4862694850735176503,5188777711923415836,13708667820606921164,2712250010114216481,12333410176405076026,14284401144403829340,1854669034241263389,14954253303980644246,5781838775252338572,11804857103670103013,11478935400329047729],"proof":[[4433858474442377829,5003409275864703390,6604743385869300526,2935718346901914890],[6266172138153541008,16000285683563998471,4011214948806064684,3059938997994574375],[4758383864741446900,17226598889475045556,2718477887338645498,1200054338722519702],[10328160373740026240,8849183999081324149,16955602573418810021,1200653738176335537]]},{"leaf_elements":[6670996430230973635,9411346294205502373,8483550996224526525,13740447761273969068,18383799888576087863,1861103407767075109,14128577166984205448,2729368874586322948,6073654733284029417,3615814553695871612,8114762500221555235,14148764031155796224,6047697994034696922,11425529257488454808,7856428913764654696,7581181778488487106],"proof":[[7055916157395292321,2510178398061995998,1073981448647449388,2900422869111418466]]},{"leaf_elements":[8315176551938840764,11851180921358640063,6375850040316541105,3560990375012668258],"proof":[]}]},{"witness_query":{"leaf_elements":[10418571924063498743,5827947052255948608,12002567627411450969,15205711871851306935,6993813804133538393,1503100684647831297,11449840538695276977,4284092405181535886,502304691474417467,9028515416700422621,16703695854620960496,5146595208546484925,13180664434711110260,8868430263528934209,1878101435931090884,14689847600579398820,6858161373115015049,14935465661590336483,14657536167962835438,10422802110765304720,7305985315994991931,8926835759580495241,13239403470442289165,4916943326195311758,1425841714251360907,6479475630396339517,14319455199642396213,3264567438534069309,12347429669055377490,14815806272239054229,14169555028593703605,2591562763565566524,10709542151733423478,890281787063598257,7106216828686208938,14978381613115959683,18326912492275864918,532087667913910783,4930412612132461695,16725831444246798227,12694942775407670270,16656078881021378796,3672389953734696155,5096979204415389807,12877926407634739185,14636552451752141295,8307836310592372960,1175262474271937811,3305260252521397644,2111754262443970309,8962692033032510880,9366833386099261456,15099936060613449481,1266715080117141656,116052465382737327,4469452617713374114,9485120913912532057,11958607281286018815,1637154814001875641,74432642240343753,8037694145145694164,9487972022461090361,17286552816292586570,8943701021329152180,268250108420912707,16951573227950695041,14207352563881939955,8467962002083200402,16643459970737755429,11833880001805631493,16646615294616255522,16660229626435328676,15521579359227629871,14818501696295391032,18403845775197635783,15167263997279038776,4047848674156247951,16914769561877273071,5642635715521717080,3848957958569519057,15344373718540978030,4889220979302014650,11090977819364258102,17096992098010708837,8864387525706593237,12022791652082310809,13634257859379772273,15915570719581700530,15087628047700388298,1444395501610867495,3438063145134800567,5865438364073043611,17156379552041704451,12445407981474813550,13180380129477266580,11689148304563632268,4180621260868749637,1166827667616260748,11043050580865573667,7652092514391970571,11411373483021384268,6532116818510177915,8836949214450672978,18161712477675136827,10688472193315597255,8611790998518350755,13930531266394907582,5909211196781410476,938589197932060745,1130168787679659068,4027643796281542587,4861305973168008914,6895053188089916233,18239061114152376553,17713041696048944334,2889017730220674426,16017175050532137938,6299374812341024088,7412882953280975823,10095327631247441168,9678760821560052208,13951041757534400119,15276010028411484053,13181283155463578734,3660146520357940284,7613430509537802977,18014220444476319326,8338417806866939133,10265544633770846056,18263905017846190622,2003097137689761721],"proof":[[9016335199316748133,10026664092486502564,2151415145178629182,2456953845580747188],[13691784634537993418,9586521237756871647,3063699934580387937,1244799385955666073],[17436102140137547982,6513549922598649583,6403992852421014370,948153070002570135],[10815386946234000127,17849107990642741625,224331373763219855,2895056559724928777],[10222378487179948185,4063893954722429113,3083788599763357275,943524313613805588],[6356663466266342571,403143480187582522,4149436714865515534,1311822880262070691],[7497064491737214293,2757093140000435418,9275655806501576654,2405442358289301579],[16758118795925943807,12696355488554603338,7707760698909362613,1844132738016375832],[11120895255133637266,11909925831703333535,8452991905956016421,1587453129089877863],[15429822673491620630,15022889910299107987,4789377043958502327,414340285326213930],[2199844625010788932,207243730639473275,4965686603521225943,1557124794114651053],[12596324349071297506,650568380548773699,14628353966245616893,820623334795860976],[12489835289634896400,6436027295365327603,13835359195736637174,2107156744221810711]]},"stage_2_query":{"leaf_elements":[7358670257437687355,8589692308040580224,17321548507454905679,7990673097213425774,12352707133324167249,2958372689740450665,15072735274022909374,5427353883694894509,6690377759332841308,7258671140427865609,643732426641573445,8162316875907943706,11423220487493557529,10709771705351550225],"proof":[[10721342928361333897,6264642006664855427,5867797974598473506,3429536750942923098],[17518595137217459117,10482555042157179283,15752077205537293257,3064401016571169821],[17555585222021224740,14220848334285605558,3768382405130563532,3430985381759421850],[2662327171661405925,10948858772654349483,4017571120730362864,3398224511160221575],[7417432722547319081,14246528214582681783,15045282451304434237,3337436169395733762],[10038707524020855196,5999235776054187814,14432957877054687948,2544758319165466908],[17111514158293740977,2467258707398294913,11406444748699593103,1102900643336584913],[9051566786910682029,14300629396365571579,9539242100957366303,922307911295446470],[735186647080363966,10421400106880276341,765165250681223014,2552826920950953460],[5947593888500992756,7767789340230942762,18294234105657287425,2846314976263546193],[1739782288191443403,18377148546627693567,9454299425633555570,2812435486859492082],[12199509332844513209,6289704150970667889,15090849501270404306,564382372865800925],[5088184440726532484,10624519551630831941,4139449485439259727,3412129392071649693]]},"quotient_query":{"leaf_elements":[5466422390297731442,1339554422909798236,5841779924924608942,17938324827386378662,3143180599703166401,2890612577005142279,12455372560420395904,18368005369047741581,9725200389337038237,18240663336530937127,12249271845369069224,13315649560000375147,13789819171327732683,3662986661664183479,15617791934790921050,16068702380395549116],"proof":[[14832189410358351763,16253587872385023990,602281712253618018,2492109018175628380],[390054973403017605,15674215939490642089,16227417886713739413,424276408192988403],[6120820847069300500,12707880279540806925,4918684824657239501,1839294629538061480],[15601160054240758615,1351802760258016225,1227855170244920900,112834160226727537],[13362412652321771824,1761944813182015900,1986719282747370959,755856658293003904],[6145164878327140686,1627130124813261621,16453292131182888552,1797287519765528536],[11371980449858357861,5750510087683903680,13097353056655400837,2388007775803132474],[4607778129528114378,14410004081371547204,13393034102425091093,335547067435825623],[4982166714770339335,12044149082804629221,158219208686303047,2629753251703123212],[14145755589696249525,12753906094253147629,18192309177857019130,3076359479347091329],[7614431164331918393,18255184243091980842,12278229449227605332,2678284897473371078],[9597732716930859269,17638715697466088868,16042498924296234427,785371408119740079],[2206136225417434008,2701764854394411613,5566855779015492723,1850531030693384592]]},"setup_query":{"leaf_elements":[17598706275930762053,12533792888087803757,121776315503406945,12325259939982922701,14154292624165063881,6866787127147915424,7384483865482134387,2087506255527386026,3567086933302372457,16618259578789613237,5137039297928697495,6814782862616280202,9315372266377024299,13022661936482002003,1041120338076474962,11454704622024523793,12206919546967204160,12206708157916557661,9474373201330552989,12937909019706907200,8166883968258663731,15577055545913305129,9861062664545971345,2994528466163393017,13219535622623290628,1187363378920760330,6185373446014779056,4501569778046920033,5124658957857456823,16508271231888119852,2640768180490182286,13992705746692986512,4996530735411203279,4087928520594579299,17527584660663754520,8768603685475174277,9860408403423219578,11015667638196400301,8101426167017087836,5658593031416566983,136771101915812907,1509115892495394132,18346761943071054461,1034226991660332263,826632968990026268,8763654930757744516,11309084740980561504,18420712641711467973,8921284542756910137,4730754134940839132,4359629454906864312,2223782582853514550,4727855953070954132,7248149745784875504,7534525406008704883,9659011150818799275,2134571429168433180,17733577700463888684,9111802810935863979,17745904364814229984,8269989253691303144],"proof":[[12764156469715654038,1038406757654337144,13986449738312547479,806882664273521452],[9787018687440174478,3618085271181167804,10671859150693306630,2085405699590493895],[6696338987550358138,11000232818773170825,6600098380285330515,3370227442941985379],[17826259348502919075,8232092479401560490,7328846594803020962,1745358085383574447],[4019261211298829238,14913323885421989454,10940905649547171621,2732433239495431494],[988045004965188872,4921028279025238186,8149343675263704181,314702744386192273],[12385485172491752025,10259568724594757186,3267914665597268388,656401433294045486],[6629662454573320036,3395902999632926859,4790192206761161998,2231693909374154377],[5555316125345338690,6090286166298020180,15607892846937578286,2406003010748834427],[13638097457512873933,17842293204987197455,15355390714195715911,271959683589669808],[13982435368302911826,16412714100195348126,6539485576429505075,1293216423346938695],[11520027135635602178,13631428291843464574,7547062763468766959,2304945956753451373],[9160595042059558321,3003654428390274044,17180942480487853646,2327618075865250316]]},"fri_queries":[{"leaf_elements":[6872204329437499495,17550797499121858742,4256890881153269490,7608300821972545772,2174400771222821937,13280578915515828914,17564873570240204278,10528902870946049694,161322217306017144,786888199330835488,15582159151890956927,11749427541739610778,17606517250952105317,11597806962549509159,1043503123328420721,2854967855274796420],"proof":[[17979836800131887986,11813030823926300727,13345765073332899427,2973518885788961071],[17708078235063845960,125364707743544021,6076256479159270744,3062993689467048482],[13749507951369987045,7904864553035589247,15991977794507421735,2334847532976796415],[3906296482432310688,9136427131919268187,8222803257371064453,3236598797721025433],[16160889630559288063,1333989368554058214,15078903326647135021,2871511000772733210],[4526779852542491323,16000801246627067344,16238748276152257675,651179386632511385],[1947376226308492658,9808185759736178944,14707856686060259983,350465426769938422],[4684288483664843629,5187621852905601021,2527247282874054871,1233691075335551248],[10723020342470848121,17474965981455051584,15206467815456018608,2902423583858735627],[17081479404112278480,617184671756641223,8216228617306694673,3379202153544912932]]},{"leaf_elements":[8649603656205263627,3648052589332566752,11091192055181584314,10337630542032750050,820286962491245301,694868491010285518,6885038490419582774,5873479607591314227,4402834139841116787,15462954652753817214,16801814833814680664,9769992453033991901,5351112628130761810,7630405138202886147,14366574423707690198,1403475868999229808],"proof":[[13340452076796408618,1994616910849058624,1200062281970534407,2310551901848145666],[3475398768345530559,9059115066110577571,10807463165879797456,162648545215426819],[14637884088167962345,3899377273610532611,9099275725601113949,2982153427812170242],[6390374341440854950,9948514843579518528,12875970295216571370,1241636431209157568],[8077143868170118771,4725437901546329835,4293781317923256525,2862795524965076934],[16504235514074964649,15253849892541395677,12108649168859793274,744569816225014137],[5813712587629336352,1082708786045461569,1092112838582383375,3425941116159785480]]},{"leaf_elements":[9197228715853585080,11986409890448262335,8898382392253299712,9849466047123370003,13131669293082808280,13422475063452060559,7979412999215004638,17736512003827247124,11295842764203849741,5051668327662972457,9569358171555519656,7930312562028899266,4063170401366429153,8380516489491241545,7780870777369171918,7643718619254550514],"proof":[[410650020306432265,6937567492657715955,10606739278152439103,882513824846557597],[6250532142866724018,874464391132368249,12803709443487121292,2264513077249386621],[5234607112344311336,17810096218651059591,14589380212376460928,1182833263942171622],[4216581162791829782,12611432400497020496,4291082047923264811,6403411685447305]]},{"leaf_elements":[4311699445297929499,9806112033748572177,3539043589198585194,14593654441266355321,15762928673565885253,5932108298477060518,17925124669056389626,14193547706035909747,17259293125139773774,2442827444727177921,17080903217978581511,16105909017897668138,12320793498174218612,797232347842516762,16412067898771630043,9571229727132115841],"proof":[[6720710772968328146,8869646766528407003,16450207532160375016,2278103972111261741]]},{"leaf_elements":[11323862628515517922,11439196860937776991,5413344540181736252,8741335607124726181],"proof":[]}]},{"witness_query":{"leaf_elements":[8124539724539331808,16400698383424273733,15420973902985722577,5308077112053575244,13040094474734654351,7017861419864178528,2127693512059714514,14983692779880405656,2009688044885866819,2265090434975122623,17915307538234028014,11074829006894988222,1709474153271133356,3187838121191222349,4676142253158109775,4693604981541121900,3552538003498879204,3260434701293999764,13761448486898250333,8595548218671461437,3974994256881852374,5198967410509312735,8696726196590586800,13916497394762048395,14719621491539261187,3664526152868674617,15400992958613642250,5100129608911954963,9573909405877640359,4135096473295240606,6245848128000592177,10222867780871692200,5348471487802706088,5745774637930629320,13884122806594750869,10298481892425585826,4247507214670540015,11057268755459325679,1665562049469690138,17531837938489562385,5147466901687954893,5119940145006256242,2322227790715198019,14637640476395911269,3692024074599112087,6263952904005993749,17650820432470724200,10995944605762529469,16601554032418498337,2428053262916655622,1515500342037582223,7305261793863977891,6017100172833615132,10146339802892246684,14313108610966049482,11685114489635541824,10932826540701756251,13297067225834490384,5354279184010963546,1939832556105775831,13564603238454565829,13165613549067909623,15245417195937105712,351505756928354189,8944325301476710564,1807566695596188147,13409935917694961275,1932311712180182471,17949202152875850895,12748518970587071107,12072902542580003665,1509561024403255245,6508666476966639677,7437355897079294140,9338438691887853638,15642400037104248844,10132466300183447817,271668470436863346,4036141388901352524,8379948491858222496,6257705280543316193,12244414219691510600,17946809199820923258,1945719490387774536,929383296283677280,14420208481215891216,16867795310209562598,10693307550059497286,1527379049309340645,3175921453515818195,18139901056853791323,10265403733516713878,15874670506446572135,17497842110155429477,7022960058798258523,5371344687505670789,18048325487290439972,1284905971684270,13698385705261755193,13418681510091005055,11892189006024873076,13099204902763958761,9680684402489620160,17905943313449752560,10337149086376469858,9393556580668675004,9237255902604070952,2027474309073900498,8751956303004191503,10572590477579306866,13931696858850977647,8275614164140942004,10352558918668164112,4614970265008258012,16233377522678784800,15254708358238009627,9690613817216745493,10632196184587757197,16375609678680766662,7259264134808208458,16560416085787628961,10968594471038547840,1521420939866757563,17397379120822459966,11093061025225048413,2109033338429386395,1802723497626120465,9878175040492313519,5436989383573056340,7464471563038491418,12448612942856405555],"proof":[[6514447405262728920,13705263697169627362,8490619809325128194,2562279054114238230],[4378186681081469557,9692080890938867809,15126510795329694482,2155044287863269829],[11200465091969740830,12589790725420716188,12739461205716207977,2576326683069224427],[12207801576883848287,15545150489766148436,8504203120887558797,3208652682056143545],[13155942655184858451,4980835212635984884,9217162677924129111,577028131553982046],[7696537225362381967,13653471248555229708,6688298010075282459,1014271791524987367],[14804013061433557879,15934714522815907265,2280224546568952591,3105813378643706866],[29230548507110707,16724482215220627585,13944418850228575393,2583640729276832849],[8372598071462376961,2603980865134103046,5306154123838459341,1232485177254295271],[5489788198357043875,9691038253541085117,15383810944083683222,3308415829039631731],[17349955109595768544,16743960907917532183,17857521342031017248,651961673542365248],[7218174071320126908,3391602635141918653,9896595918848906488,1823235285631652039],[16513765587432722546,121544039024893773,3138743533043215794,733950146762531495]]},"stage_2_query":{"leaf_elements":[16349455811922982987,2837376443246113383,2801268024153720610,10649009486584464653,3350035330192383520,14549387877239587818,17881231212782194661,834426590218031770,8108756682670580867,3969396883485352950,1926634206740793866,104588575683808524,4895211838517584815,3101005036013568045],"proof":[[3366733150151481575,17575495355964366851,10055488504852514574,842172419803150370],[5244999257841825539,3212443790099038703,4559132396477311345,2028376632473939112],[13020210901533142891,10668970247944318014,13359112109371949773,664177489003278719],[14771966629850626498,1468368638286871507,4868905906130336258,896406002202834697],[9885960412536761865,1033460729218715653,10363456559543815834,1727241823040539080],[669087228529765370,14942817767585156807,7228487412576441153,1188473521927956228],[18436356280944220777,18065074972925822935,195398798780014446,1088880764921757952],[15250893409243389605,16630884065388943510,10258699566778762014,1019680085488934354],[18002950842404775025,3703453828817575100,3632849190160933170,62470256635048983],[15267794468213091871,1944914123468818495,17120516978601139508,3359921725191906603],[8057777655389200611,4479722035356839996,8075693173658676205,915682735566514205],[9438806516255595655,17844878632545378719,5138587953355539140,2234801027948212830],[16525377618692489719,17328983968272744590,3650596284590334988,871340746504299580]]},"quotient_query":{"leaf_elements":[1641758046788962619,13964605734396803034,12843163866514475984,7904444671889787646,8818964640805459920,13090206157770529519,5818484331091508835,1674075563558194661,15042245767591557756,5931927253884416563,11904453816563184373,17044755162434307352,13578577347014342489,2967051227606805695,5722497738403227599,14922776829829676366],"proof":[[7965589951207691169,14502858369895340055,14651969759522488806,1839443366713850644],[9525704288425430765,9448095924791650073,11334642939529986117,2383252636201228531],[3307953280324762036,12409975942296441910,13166560859081709672,1557510180380692479],[5000309781037201114,17225809101110949088,15142620539019812343,2381195671303483010],[6915277742961050350,3719084157354204797,6590699295689153786,2843180103592053485],[5175190294553811293,13577606668963315992,10137807922531082774,1409845154265485263],[12800432408057892422,11634567445636294563,12010959371825473329,1773684238195599669],[15128945954889881028,11222579476055097270,16397018459387673168,1418323402421428482],[10151085496776236399,8955522521679813898,13578445565040379278,3409093990363432994],[4890438045013635191,12650615348801566235,17768187948190258953,2879828757293696365],[9915057964071577145,1964225964417928312,13382952069357899140,2710939449546884707],[2401237826681113308,8909424395211937939,475068384883389955,822955861264257061],[4877516156134644516,8438558471521262095,11689573288271903265,1820872385465103953]]},"setup_query":{"leaf_elements":[6616139142663604570,872606683362384398,5273200686402272312,7707060101474146976,6829551632370716260,10634669392476104794,10633091731706996300,5229815004925196695,13190066791736329686,15112455672614750291,16924704016711714324,3407434841309916445,6474509485792320121,11450493081155690087,8176250712055842338,14339430301532655072,4849321308100687842,11201672860639632976,9447362369947748988,3706426913623345537,7323912536298619645,17415453698271785014,3942251482185252695,6293062695606593252,10788870659173222135,14276898181801272626,6066462192743637438,17195236302767698316,5869945045697104743,10542848583278701012,12476562167125625113,6296082999643583888,13556201344564041758,10479025131497129270,15256886135136362433,214137651001895680,5933156863294873759,17341104732077506520,4870063029664045150,2940886245105178134,14061263582970260009,9210681106575396580,11918443727262892705,6331994352492493939,13790023008890995507,11931928390616226498,5635827882558498181,2884938783038207856,18299981416840434617,6234179593106269862,16463273835943877588,15522248954738697064,3561915516946922908,11846074145729135358,3156110467891635082,16704457729808525730,14481600151474854329,1061359800375615084,17321312755673609198,13155419274374546571,11743794473308487470],"proof":[[17181646531939560487,10337502765332238192,16495272394772778691,1877959300531805439],[16654096983448191441,14221135013384599780,6075857843502035758,133304665839553348],[4873618323392254015,15989116203432502103,11320567846143930824,1678305177052670803],[12669591453194927187,13183336063574108702,3972035094471359529,3074473048426343318],[2254788474706165704,4337571748697551249,15905547527363383312,505527677278474587],[13812257627230735801,7409684626264612435,7783876082721612866,2202975432065214398],[15358296189977591764,14278535098950540236,18191443616951919806,2229226831113516714],[14439872236529863191,8596315124349269828,2104184846693974920,346932294983722528],[1947238611397738530,6325823781000102461,5524573040176309107,314685963194860356],[5222397238295803356,8920029560215082497,17279332928133846665,1857266373320731370],[11726129945642873427,10380315726163455303,2959037522864988791,1539444225808368214],[7031390392236892690,11403796420058588736,12541295250845120410,1685901086013876799],[6903761968075767775,16335138838085280161,11255601848129470680,2840544635581585015]]},"fri_queries":[{"leaf_elements":[182226401385593990,6194808387995267172,11162712674187853215,13070705813267447706,9526237110194109738,3194852153036111490,16379028781742513309,16890426726667367941,10083879557423847126,14366122155039612503,6509588353627537342,2980746645716647430,15354662511571038056,7758052665912120966,16757664068590257179,2500067383838410336],"proof":[[17602871277047605916,15484115495855567206,17614026477403024256,3483195805153401012],[13154269641200668491,15146341242051598858,18343099964049257064,1788823339342086332],[7459239696491081168,18049170621751433518,5716932578077610570,1489374745662671986],[13288021460422759329,6738500604036649807,79981156178981967,3170068375716385322],[5249051539473680788,12304331394327030246,8429505410308375703,55266664663478305],[6230353613005622127,12788889699762855430,9942656867556520868,1351408266916127164],[11817563146632654599,13854435912354217446,13829330066251063434,2026446345469155296],[6141016834281562498,13557895874158797347,14296991498835590330,5191440726921059],[3047858776583339722,18039244376599446631,4665799727996645685,2393727567721304533],[523525909914794213,4641273345161396273,456208264863516188,3185861633421690290]]},{"leaf_elements":[14488813937680286083,9266222080651859526,217595419232362347,15689919129805550040,12027521984468272253,18046314669607699532,11623732037902912927,16898411526666662802,966693760892049744,13978457831412120951,17824845043554901067,5939013498380676691,16222557948681489239,7002038002034322607,3349346509241930131,8702552963639259436],"proof":[[9908247766181805576,12931710452507482910,12581443112573447889,1825819311921612721],[17253754433942195238,16383717618622353535,10385573986801528250,3240058210182353255],[871586174077384335,5075076414369872029,14187178070867894883,3219628464598876359],[3599831821469344156,7514406533552393940,6806177809029853116,1851935279622925902],[4858258630973905047,16889928276112672878,7889444479700284658,3442222253421765459],[2244566249098437668,17243142189126086824,9062012274749468692,1112101514670813382],[12829028331720930570,7839367307024997347,1708950152111826918,99008787807097727]]},{"leaf_elements":[6031107926071223991,7592835496868492250,5995321249216199767,14967509613363868842,12634460503970910486,3525304240552032262,10916070852699932201,540290767015729928,16747706798246691909,9394404339670905165,16601971229099546157,6574772690533936083,3448852453424294482,9336189267968852063,2433849627992908690,15948852374665086435],"proof":[[222449263846210045,6490090775212345108,13308299783656239445,2154583913325595660],[1633604523041796883,3050622003535546438,11898400139231559621,318602716408661797],[11797179099208339866,3270327483478855488,15342294916443107845,1316040111633353487],[10948929393571349751,15133035458002609575,13033826236490809564,843927101519598979]]},{"leaf_elements":[8985689063820130294,14632500928563021011,8492175115891029234,17457269209371091950,1787740454944567578,10619543811862395874,1673814834726206631,15839903481460576304,17127299113268322441,5820857297293477877,6267821794017558446,1211012250684612131,2179153015643737742,14613273144592282206,6460678397327558989,727797160042742470],"proof":[[5650056522720703258,11411019331149860848,12435384058340081666,2342512692171438581]]},{"leaf_elements":[16020615081147422815,13915578652650564399,3736948130494827047,6469096372567627750],"proof":[]}]},{"witness_query":{"leaf_elements":[18297959374293951249,3931345149495073738,6962343789842172541,10521257772647221235,5100352501022725407,13654529909062413540,11735373834331358532,2020874618630582769,9888981642566141708,12421977705577158872,1698865688195003015,10026678428978193078,11965031303586011088,1059842539570441132,15709502489820272857,10145357931242630839,7041386570423101953,2814326215970872006,8041404729018643688,9382005612094936723,11865741352924394715,17557829427323373098,14377468865565334311,8389075269757778499,7193746897056439409,5891530144556777527,18076154849309198380,4247518637360840830,9248501667428206734,9959334356028512683,12495835726379506253,908298973564225879,8908073248783877726,343944033229499048,16916204341191355365,721650926226702477,17302887446328249875,2170700445896839600,7186456206766409768,6531160384679803368,13376045282236835540,12826653638020629038,18131418675709328995,6298205178321393569,10725175149378620174,32241867300994260,12297435024413580249,10491900156859751442,5662358314563904494,8689344733906836244,6622403890931362549,5326147630491441966,8173043460304819128,14990791867062784165,153435463057330328,13100989085943743696,16166303687122896658,15643488198394533950,7598250516382198838,17636549710538017470,7496170798379484921,12153098545210913981,5072960159224689311,9746182761848426720,3105873249389817962,7976420420591126785,9044781784649464616,8577667742754374952,9645810012482909472,4215137150007056571,1257157860092758728,13683706578534600132,9574123403188986379,18330680265421526226,2635323775625315202,5857649971752868717,9664684670639611008,4700318485373701017,1267694765901512127,11896594086873825638,6737360335424980011,5463334808675725316,13811795406617314860,14042342354436730973,9071697105269539360,109633071639560184,16390685597802285534,21680881367723447,16308215978083079629,465364781979960258,12734798799316327714,17978376879942532695,9431268203623654105,13614556272927766670,3942213306717989909,2490342001848523909,15272277600804921085,14293030179972756412,1643935338417263162,7076420756860095455,7158739104684944811,12880859222737643531,3721609985293747761,5382066280933914951,15695576925987773758,6521682518885126984,13050763643822445524,10228356888086372277,14743822166351646088,15899412326739067466,15005372104840614115,1087075932729875207,1987538945752713798,16574282482741586837,12070928886630975141,7782911844837055789,14538336506634997835,14172523090321644309,16585956227542694707,2085333216844164698,14096763537226268462,8510678633628895385,492863440750899638,2531444438422712062,4185755852481839531,14446620209947896220,13447801111852088448,10225040822809992513,15299769089632545362,2321316158256600887,8091780302954576193],"proof":[[77746262458805213,11534898390091624513,15895102884833420557,1614385669357019441],[2949275311960425153,14733909456657484538,10717453814127211609,2431896009211696534],[13977630251851840632,1703429950593710553,3924637848321827692,456055270553885659],[3325996339543554822,14572098554901185955,8380645715349643079,2498285719968886147],[5653886644869586464,10291020684516370413,6762386992976912835,1574106328756456109],[8283160623654105516,3351663266629687735,482214409451521269,1604517551697098152],[7540457555463354876,963397278516882875,1470089892842488962,3484011713247105895],[851834703582443763,16861305119101482408,9962136416014150189,3413146494801032953],[1298510870950052879,12777148439123562837,630992607786586967,2841265760576453252],[5700517798463361040,15872682058702155892,3651753752888608534,1683270016700603497],[18133448950438938027,3590728441915711227,5935118372286298235,2069166987537017368],[17723243069304556056,11357807378517089352,13657516448748847876,1268493559648078622],[14076076261611183675,9659655257828759082,14706052795474948929,3072947630100654201]]},"stage_2_query":{"leaf_elements":[11337418237309378774,9214142501954318776,8334300781901076364,12325252359250307836,6419076694799226352,2440378244996884586,2280368115672283284,152586936502127697,10717864479965302752,14596239211453296118,14311284909797357323,5756221085395762283,9676021403399157853,6945073334351407412],"proof":[[15662259936679340424,8088278518720874786,15456691449526728615,1092923422362319703],[16894514400582601067,6327000136628935305,11500513024930508129,2114429998937100700],[3920685882136513298,8968323401304196603,6836903913908410756,819918360939142756],[5679081292912069248,12210798872574110087,6588345729152252269,862830225674813452],[12350599251374849496,207236413794505172,14822180136491568819,2833870039510925858],[5613806965035592347,6102317152662156447,2213818724263530679,1879373779574910469],[4501735049836707368,1346448364517277462,11172172382966276858,961000133896081152],[16825613868045794558,14889333762681354529,8584060494767983463,332057062469001777],[1028994877350102045,16084120264939554078,1631836921972401608,1219878043121008788],[10527037117328713707,778037761352702330,1058560302799952893,2819245014613598696],[14630612566051183120,9751199677521176731,6133826899499776822,2095532847582998790],[15825230168161676768,10913299072888876783,8456846884114915477,789517465186489202],[8364166707332384431,11085165977414611782,7147555899875154179,2437337308019370275]]},"quotient_query":{"leaf_elements":[1869514684235334233,16186593378984145741,11188688211078174906,13147491104843955772,5640961159247343063,3449203874134404232,3979637240915832648,4122234781530012931,17280504486879470904,13491531318827423299,8509711734701858269,12950196537308695509,13241078888539605588,3596830486363561696,9213967471924103248,10130453377216899029],"proof":[[10504389119769003711,4357955845576555285,15897822897806336195,1154396071418399276],[6689455635274149774,3489518472983365015,2171458577196824180,771387779022538946],[17664540541581316410,4968089260799610392,9580897866755086542,74228308470975168],[5046840986426025307,16935130490036772279,13244317824383714822,1726113957512713779],[14996273160637075002,13676674725058034254,3128215658068023940,330385410851614749],[15626863522873956011,8743133763729224054,12513512508105707064,887154573401085237],[11837102917145703411,4090311716041598193,12562585638665298634,1489935142270772235],[15922177363212896050,12683021565521856221,17676472234282261031,1448258946771978103],[316272772089310229,6279548667130104358,16966802669001655748,1170828971822634081],[9366567857068535942,18227855068744415641,16859995543691246840,1605511042846358251],[5556893964396667697,10583310459409899369,14179098296704603923,536838040304858988],[7006659901838543096,803969477343191497,14981256681159703528,313881293679275484],[8730086932136367951,11925599204180882986,8819274418015626761,1710917549612166364]]},"setup_query":{"leaf_elements":[9953593205679201103,2804634613446688573,13603233605933321948,3097703657634239995,4845410542070360211,15771587521860199570,5604603225523343671,16581808378365338478,3787788697133213994,5348270608716931604,9166091816817743366,15784251020102434580,5690467923710196128,16434608324552412792,13599693992570207068,287355297040241374,16744171228951698651,11661698081960667960,1755590914967377240,8318758822904118644,15540560279483824658,17723178904904599548,12129037252868476987,1534549452010067990,3731869974025065564,3156674094197607462,5904685606924938360,11624786932905041204,5571897191263685189,7966597590843702193,12391370470778634186,4410335316635306926,17750946620835706765,3835463939917496906,11903271151461087211,9111013210235408392,17049321736586513303,3342305976170074518,15590996733127896365,18443099968152224648,2614871233933426561,14648967278310633066,7402992477874491682,10647492122351820196,6443495380185378105,7921003350958562226,14811545408806671734,7126446347305389666,5184187001982096968,1380726160237319020,5325030688487819948,32145996204271264,11606403572911531840,227203725162483344,3214858221619407535,12784193531833663514,14512928299716337373,17729345260658835826,9581590878799159400,15029089864611962294,961326124234096819],"proof":[[3206605393474430990,18055731107580101786,1777738429936660804,1778743523631836938],[733459770555097396,8170526983146688920,2867696359577186967,2429630201792148571],[12205368594754540423,7304268463802406882,5530220064788790695,3035160539873191637],[264159943553899837,12404435914984258223,1123818165300790590,443834798025495729],[2168065801669329996,401101041226999748,5389367088487144663,1155793103036720021],[13245449142386012932,11255736695178232013,17900422728563882794,3221339263607920416],[18315540463687217743,3728879541257748780,1076671866001390716,2966766098053864652],[18353531070583224273,11203614929540223029,3967278062310214398,2827551468023682088],[12267858927280501505,7576890090535633434,9339848421784617928,1367247514145126637],[6670588123847843161,11533653149932071337,945910733009995587,612502495769353372],[9146488317584951273,13125702516936194298,18136646936310502200,759946512215221304],[11950118845523605228,8974871691156313033,14281810236981205890,1646875305781119811],[722733291788924176,15852581872908387515,2443795526216256097,259525222240707858]]},"fri_queries":[{"leaf_elements":[9311910525268321155,11219299489587277539,3150907074874963669,16593309000364539213,9343600742699737344,6460974068651351519,12891638520758863671,9875481701437076842,15900227559779696607,4955286390585076561,4005200885344134659,15471977211591053639,8044050222585110456,2933194867454343545,9657211659455282127,8510645267554769396],"proof":[[6801499054842160525,4748139414018880015,5143760524276512528,392322304830064476],[6106403769585829777,16241279793426893129,1950907108710066774,2801721961909115253],[2743858445025144364,16185567289310388516,5075106470694881554,815509620345061010],[279441258344345487,15240478833515826938,11747958086981438831,927557371188998430],[4482946962211315926,14497676946024730774,3973826415190024306,2780718766047714676],[12811006606735385586,1148168768341225154,10739089740428865782,2344818098874943485],[7580951838199716408,6454529149564525038,10137547856367458853,2220210809015054053],[10513572516478520082,15351965221111537265,416895882993972594,892914602842381509],[17252262767457113072,3084397863169735726,15602101305331398506,1534812293163552664],[5118267202683754962,16438757699427697566,437162205562170402,866418178278798530]]},{"leaf_elements":[4965815999885458307,7725719837041061956,16798304231495400123,8955194277927374437,10471768865896999908,978282299187587628,11189040805588935236,4996769833518300613,13021968428985553513,7021759184808504868,7645754403319355918,8020492467734186210,17693683701207298159,3292971950694725905,7636428671692652367,9733257799329405147],"proof":[[2373724329894194353,15475972173879047695,4500898216920510061,2194896733804050173],[17076604182111510544,414283360495323611,15429934746102478734,1343041960795439414],[1180746509985973576,3328949480134028292,13081662208954061291,1239019151589608580],[8616268286351361433,11313678446437513323,5084108130193669352,2365140909640226088],[10543376209209672796,8936431957960339410,10826657902299599743,693082604322999562],[1187062444726445116,10624690922973651627,10396984044167040774,3206270247758655471],[1766928392174372401,9273764266976117261,5364669811481690826,1079770134041172907]]},{"leaf_elements":[14482577333078825037,10394874100114606060,5447938818270134425,5519375567335535765,14040460667441290634,13988476428861235489,11299049926905294084,5572938966349825844,15051321890572816769,1048851991398651265,15073822220803454792,11631697679571241707,2609697069536398233,14656672259394555958,12743544293051773401,12376336801623240062],"proof":[[4502684539725247213,3177103619473326476,7151289931667891851,1353048982490199016],[8863988291767182616,11473705006316782842,12663363257106293963,866893491834465233],[2034437430147221946,2102045484291976165,5468074473542929735,2904546012807388467],[12790274898788724833,11778265757858560232,615264687241093150,189207347702324596]]},{"leaf_elements":[12951502065863114524,15589898566447076325,8471850072136287179,7795508617952139287,243812168411268926,6176350138902543632,349377700592651405,16069763194368890798,2248025273204271793,10388784969645694575,5945734337008841339,7955221026141260029,11185399327475433104,2090689616069089665,11256685780909830861,7807387601872616093],"proof":[[4892189012639208965,14949783539425906421,7682998158330916053,1995989299876921147]]},{"leaf_elements":[7065729504527910035,9780518320697745842,13314892057648005417,14505346905238107109],"proof":[]}]},{"witness_query":{"leaf_elements":[18097342364246898755,4436478314385615515,11087403113501364808,1163247671819195129,16580943507331291277,15260610969202835441,17312879612631667873,961450843063003470,7564595945351568864,9064850416128343963,490413516665168816,15568694738155899963,13680397678388309211,6151484123305706665,2592855994603384396,17701006273034565838,13478335931240187107,8114306562441341020,9020718765957210447,1533779275186758307,14197610554008709966,13410024527608947229,3632893469912342913,16932153246478017414,10017064616729203699,14480631597017166938,8093980931471800170,6805996211523179939,14596504717246328449,11733286582666029078,11002477328481592398,2662508249860406497,7069749276869619725,3775554097655037585,3848415543090400596,11714626686406630887,7760092322313685766,863635579195618479,6348027422763353012,5598530999426714314,16987563950147500233,12844396205527696406,2752868031680467616,13072121318688651446,7181735174773334576,10307536851823634483,15857915285583676673,15699606139797070445,9549357281209657745,12179146489191474822,9299509459942749562,16404938023251814550,1969295242086341438,164397542868556706,13653696243450085540,3158445654624984526,15167070885714745400,12387420907457570722,14877110555039748212,14417685237444767054,13622612106894528078,2110687628700910498,2443209341647330017,6274711471266813815,9128731513430822645,4470588371951622780,9122713834739046520,8679749229314933,9877317544430065301,1727013564947866205,5204340851672304672,4414991310058646543,5765194662362893013,18050268565330808218,4917792723825292231,15821291987035901149,11253080960187669124,11151437087740313461,12053772546581749708,2341375673800911661,11921317796607048878,5587089285955516492,17969990639819788326,15856742483112318938,16252154343646373564,10565022339965675850,15789509915220194318,14360724860390363568,16524610702939298073,14311895985091608736,15565679482200525480,4254287435884773769,4211506026110778543,956971122207561623,12615870310484733524,18138157970444225439,4542382385252968051,4862293830452466754,6385034260593621343,10726216037628907914,12341039700169625730,9105708058072055928,13758861078072950954,13969086627166359470,4665157533161296335,120378557649244690,3566593645652498988,6266948846702115201,17907124155194764660,583099400854864274,5031885790537839602,4991721580797006003,17464166371908656486,18173977074897485495,11832394286185510268,5846111045826206268,14906826369963967252,16378513103018758826,18399292334589309347,9810129111011543626,15494470282475451768,16981212780989142651,13260915303699182303,2750493102643190016,6284611416998384737,9647256758949277076,14891392251290686752,15208338404833103448,3047526851583993978,6163098219279145755,7538877070584161170],"proof":[[5380299897992273918,2203092084796453020,15471668378454095279,174821997619067179],[4190583801533686874,10504703452600616353,694228448571640492,191646941634210949],[5132695020862987240,9689500102379348103,12194217539062655260,840858458970913590],[562629151641044247,17761451737688368374,18209553072624766355,2372097143403816004],[9665207378435737078,2557047899039662201,11297262181463826569,2840826374621653705],[542459459860750268,2244521629288888256,17443125477487415514,2818116448854301917],[4196693632766578413,13789811321136558142,7025355529559919421,2488642731115341952],[13686737056287502170,16749169835048611727,867740174471630,2724109351280313013],[2700484966851988557,15422179830808976592,14819707031571775852,3451143015884046777],[17648132100849151726,11510382120374436258,2213613093252627031,2762830612510110009],[16227014586563902288,11806741452106796398,7289885446626261489,1830052120445894234],[5337386146685324083,1759315120300051303,1014203858517702445,2373938672992607667],[10760418131477431642,14820657774701628297,11628914349052808993,2039254384422831665]]},"stage_2_query":{"leaf_elements":[14682601285751762667,708606448584919366,10399825452650186611,7646195089256214434,9647950337968985771,15131339101537900435,14195902769696644108,8817523696640653029,9568974099887053935,9871551760241488859,1221597964916729673,13438396611880529942,8488071416133075909,1273632299824164510],"proof":[[13443376760817153638,16235255994949684452,14009702440820361317,755508864199369848],[9353278179576422318,3512712022624863645,6045540494455051803,1963858115960487094],[84250445187174541,3926138958909901239,14404434310062476353,517709337034187662],[6690544133719462465,10245187588232241101,4026692647098760927,600439615320196019],[3992965327149094260,1534454008104018494,1691746646734764036,2671153362661237080],[18373325801012480870,16732279587972793075,1757777907376229755,2554945850596232658],[15839140641696436942,15050146657873604837,18067950697623853197,3046671712785077626],[810930994898426710,10436400719313463824,16715368890030192525,1137810707506790062],[11879285534208010791,7084843268404195974,17397654526441175935,233707915223976710],[15511469999609308644,6531681108437632486,16640524167174633943,3245338827740932804],[17961360173795477962,7720565919948432160,2062932133412226373,3419185367283942938],[10946443397241484112,7632626395748461425,2953818670712640602,466835577787625070],[10265763405734876041,5280836174585384744,1332105447072495082,1288183057809366478]]},"quotient_query":{"leaf_elements":[2275729159892706798,2728805718254034047,16235170573787972411,4245841907850299441,16781270243883912553,1403916242737207821,639945289195229421,7812071612722588676,4831034019341332314,8171144828308759846,10586331866679048145,5642254323875808696,1168549662135383745,6099798470996515425,7235944120357361919,15616239518266068445],"proof":[[16063143889309831964,16835130928714860722,3588237727071406541,583763103836058742],[9726436863088295790,7762689300951184615,2577054146432626218,1977871962889224941],[10387075193735504056,2653730505822905427,16777080898552994844,3021234778845106902],[479537849812192417,8719051759321825272,13420623974295016095,45745292980960523],[17430286673832271403,448298288118244429,17935271234053252690,2322677956499521250],[1856367608926008379,13762502649364851778,1410371516792103768,3210042448918130169],[18127185360520436542,17697936898963258228,11693804988261469418,2698326913667054360],[11003958897459901399,11136329284095879688,13613888728084128933,3368930938716578026],[17216384032372075144,14354419070564171945,13992197128708584015,1245877274575292242],[14495633381505184602,9299846403028644538,16370141644983784684,2484358238794042371],[9799625854887603623,17768803730781488837,1027653261824511039,3144774709573792281],[14698990891311628009,15892561105547541385,6630210176285877232,628055738420819513],[3336220069100085124,5759271110398045898,13618835346520552360,87853750978578886]]},"setup_query":{"leaf_elements":[13429354277612612016,11802907434842809496,7152029691928937604,15103647393984121802,2027394955168190922,7489797271802111917,8998600295406819492,14523341192636920658,8839094728931356871,14084773731084417567,9085681190649599961,11336363551655381855,13898983373536262673,11061313952232474379,15214568595395140944,11554610467224577374,15590984150053399274,7718499046077082523,7188073932820223759,15113689703439841232,1620765393214159467,10969897001173734471,9084576198922136001,12709776599841089014,9529680643118789363,14666531661709971564,18298394388835478170,17011102065926525618,7871703278938852825,2371261253629213043,16035436735456441808,14081571924577149039,14652049321934502317,3044576550089024320,12739831904793046590,11821661912070301230,17264403334993087738,2852192288210770701,15986424422093241379,10803226692151309980,14305939724667816635,8170861396095269983,16255903804844355568,11147260202793160265,2824049960938497802,15367015026942022956,2621835543722204218,10394788390863476244,2909367711880982334,5970294618086683077,6696442598905927689,9809118948828553310,11785200675550198910,12109360128638633571,4875674644432902664,14242961163852454077,9140732816568137145,5780329646761401124,12547592343491939734,7077802455708262076,18125545990784055886],"proof":[[8706173434542235570,15360088750936225071,11042825634756440675,1113681746036943128],[12293060242658919457,3976826729935827335,1071733871710086645,357424802497652178],[2020329148802575064,5078880019606015157,5748779571604658717,2664458382016385826],[12524269147740174141,56166465706017501,14950389482561453100,2599873770787836288],[17051057822334559777,7460467209705588558,2874781892016605323,616601809530589838],[3267762387884212063,4491930682368065181,12624036904229960867,89592698308695292],[14660142671561038840,1850823301553139732,1241292503952739071,884394191861676792],[2034987172948117922,6776616278869124365,4954778331689348712,2435662031603208598],[12602783149331955748,971894995829210868,9938275213585558572,603734519592384361],[139134273537688952,6992979227619680571,5219970575822457984,759903076144052075],[8561863369731937059,3748792952491648386,16955955045075445143,1430569550067109689],[8634214520312302704,5788473018517600736,3895694945095744202,1852559750666780338],[17874738227292005179,6326465745494053,13494069438792348789,1192845911089305290]]},"fri_queries":[{"leaf_elements":[5547768765864925459,942199216610521151,1898383407799251908,4967556809431687370,10865720759834808581,2327659632545740651,16762787954261228805,4600264684859739504,9666555422039137324,12266311141699764058,14987848371979191716,12422752312359460668,26281078932804180,2109635435812752163,17269525618052527832,9414934147227695922],"proof":[[5855148264063749303,6229592738546401616,15740760744035248510,434561492177833550],[3122703685960051757,15743822883730040495,1255748104648928720,2719898581894954238],[6578804701688408036,3057391026388382463,9395780675481735360,2863916961798613844],[17273116438950023526,9429589139420393051,4917601215331481111,2248184516486759721],[8156315080531904637,13948354891094559515,13391837742319367192,1769474356877236011],[6316989014176430731,3875427538594636848,14931224154743096572,2055837446936166116],[13228320050478322458,9894090960301266730,10251212409517826905,3467804671625554517],[5740760957804843562,12683386640919453121,8731505470485739013,2549651604685741430],[8736545542981214870,18091865623238342905,16938045962214512397,1619771569222218445],[4755821502693131307,9632672734832196477,6831801818195575559,1211503718015705569]]},{"leaf_elements":[7671912735415296369,2995430212049653791,5766505774617478405,12610827994094159625,8927640188092403718,5864029239265448995,11828062946497944191,102124796354343911,3665280969895374266,14000716544758116981,985210652539723230,685270681072112348,15277639891303145181,16620850239509046686,13817379085765328585,312764416827469144],"proof":[[3797566294984244386,6187180247496797783,3848012875178044282,347435259807746710],[17340938539774380726,16686449986302717915,18109988851191378041,495815362793783790],[13490293166060865529,9685553433986131926,8979399201769514384,2600775463503387902],[10827404187231120061,6533149187892014423,11944205768551897422,499515416643671203],[18285979551069281330,1965461503927681991,6858294520353012990,1817109101893344962],[17748107662216378529,3745547155845768398,10781438857281393381,2132537212408657619],[4968579060289205032,15025470103249155658,4016020820835814409,676707436625885313]]},{"leaf_elements":[10366124592146345303,9270600929113586275,5096317204823678955,18160598869472101149,14993707494245990034,17924124337918483943,12044568294919556401,3207517519456463523,11880111490836129502,13996824970745960089,10893762151078481782,8344287899502609530,16517328923003533735,6340218306875362577,14556572799635399962,8139796564487875297],"proof":[[17976125046882125244,13272246983559278520,4938159646937417051,712855948467314754],[804078176578386963,3846429302243631822,4469311658787756735,1625073331326137204],[16787357039742660708,15074718737644074307,7357274406577523229,2904651230561894869],[6775086337445118645,3836725614252760951,1244274972769235222,3458783429667173983]]},{"leaf_elements":[16760476579281369555,11684430973873978645,3628257208263626274,13264191245930967560,16805239192496903355,15197924325062831366,2446532897786143650,2265791655783868310,12694463806107320464,16750582611044430566,7379235119149631963,8016374353919518273,11399838020256932524,8401772713760710572,16660944741874745508,2593524144018731665],"proof":[[1408739999051503414,17928989256333671698,4393560887102948271,358038974748859422]]},{"leaf_elements":[15915622550061201680,4536541224237163888,16120598048347926193,2661082248244309055],"proof":[]}]},{"witness_query":{"leaf_elements":[14800063320740863528,16024341373799135039,11411556610080075286,7955713256023226889,11791467924228747297,17084808399729590510,7648704236859624772,4731070068603496307,1720176112583597727,7242248775219424766,6184473843896192315,875002966069937715,4645304709454047108,6406861179832759264,17763568418760151600,13013928251178453476,15600579058821805487,4491622997191008000,9416359330255629433,9825309721615056130,5752325526007788713,17087703252477444218,522688201326878473,1929998537497501138,4777772012369684716,6114799019793355563,10673703922317317971,7700590693189593259,10663280551587259790,16547768944027195468,9590647852134513282,12246331389855630157,8123678792933969083,18334880415301870065,6041583540729443358,13782103009191334480,10283901054492574419,3903234201426761566,9502019538335471948,11240539038777864365,2414062674736173840,10919452499606828464,1801889636534415934,10578921586311449394,8946026022292195288,8333399711112513292,12965652515956173210,8552817025601635917,17952605688120733052,4746202286109738987,23500766268782032,17490144420371292702,2134805456623764905,18077591728455947775,1485748432022409655,15554072127729118112,4330133794199151877,16969873245022881820,16936639476573124038,2283033889606177664,14287072736503237496,7864035378614123494,2070166525567042087,6642227656084531361,6249209310004967136,5579513935377495925,13325777842204769205,11484173746474699202,3210947371878282203,15199124219534187135,4353140548264560619,8937562550473162609,2763688388995682258,15038990615331341992,5725920069559992603,6488280096379698660,1965966539510417842,3687657575067763578,7439635735129625570,5786422921508622486,13227365916848866951,9719505290070218600,4999216374808831258,15956854496438611804,17474563243824974625,12350671254095866361,10836025194494887937,10418452928132321475,7074927794481815554,13575885373937062038,6055770783762451297,17037684965456335865,9870319691409102038,8290927731450578780,6864850591523114371,16082733698836985159,14281452500617922509,16079938740392159578,3154644506811273824,11382371732268655042,16377047345973768404,8687621358218405953,4837138312715062880,6941080855923464488,15321586758582882212,14114821795343862576,13345700570844829956,7405855730312112563,9786377270291156157,7668306639512055055,8567004128670780608,6212635777830160807,18229427275763105642,17888977584831083270,9916172660082111195,6382477155832587727,14819817605245736969,12873807810435377777,10625592540654776187,10035531452004507828,410786338432897580,2536400719007642496,8751646243805652482,2170637947309164419,4435829033897369960,15108250652158432119,2691476851137000978,4884741137149395399,13751245054123410131,4556958069734457520,8304344725224047743],"proof":[[7155198303450498640,8125735099619011120,9991402947516713390,1295153204474557053],[4738508981402743310,13612043205289628075,476512630331550429,1313946642273310835],[6003614369275289451,538745130996086721,5855429410865698780,1205340351997036180],[636504358878446939,18031877158730053156,8682692371607787112,1832562221923881639],[886531883187275801,2931218712657838443,4046112196316565908,145668639177585008],[8436237407941446244,15771478676751743838,221508314252473623,85352981560413697],[15863778060365827476,10723151162392701078,7616543041232008213,1305689966799233190],[10610346795798553170,19815413671372100,13144785286063802617,2623016974436204169],[11866531546164064338,10484408113690674192,1226494682963570383,1021217355056589915],[8193514674805675027,17513323135307108884,11270300645142030525,3185484705504018671],[2226723878357767203,6907060864645212035,15288564405948249585,143356550194151194],[3025696268175542504,1811029513990196629,11033833219888416310,514707846647079341],[16588491068607937261,3526966741617928076,10392695706853076554,1484301400438308297]]},"stage_2_query":{"leaf_elements":[5746577085789269418,6695680131725294305,7121312780931793127,4970117846475921015,4640658128741395388,6495409614571479237,13761296220610152736,14470637826393487775,13620335150444756580,5429786327901003815,5398149039473428016,11342470460221277046,948445334988693149,11567030837764048550],"proof":[[13666540421408341484,722451835749466080,15208628690017489633,2385210987949983564],[17599780785096558753,379347304174338487,16260243576452578279,3040840760852039123],[5418975999669495450,3282452511524239552,1211920117631663815,3070779939590656462],[10184988983354873,16980546654622488126,708945644101015178,940131180494242074],[16994449515308479527,18009500459477519545,2213967082375235611,3413079839721366105],[13488526846002641699,1636935396592370144,5405349273147722299,2948629570450180274],[7963274894950540412,670322037059630952,10256907301400793053,769178350926615323],[5227557316152368537,5838423129486715129,14886561524899633679,919052250654285789],[4822720314503969158,10142475337245406809,3347819758621450376,1489456962083136257],[10797843017958922556,7408558772690614360,16463142077196603706,1290145295860928559],[16244871788677299291,7579926744538462936,5423572791070509393,2933673083298627417],[17603814926883290029,7657532600076575694,13189183360980068776,1053195816475917650],[1137189341543078283,13958353513130400171,14826580562953365354,969106141811926692]]},"quotient_query":{"leaf_elements":[8221614098726645745,13736680717959437859,15737727753373640427,17225068389874140982,7452529514500145543,14125032637527109450,13069199669830833097,11714638012184673457,17459058442098342584,15240651346109140636,14982643933728178958,16491669215100710694,12055053401928752894,13856579098439928871,18024249480521110627,15817566829756621443],"proof":[[5636604224438352760,13869233576256546359,10208451654171211203,2271539112391162974],[1778642748486587971,15357409392231611957,17067384795364122830,1456084243776320817],[14477421785017639250,1080554040726222203,15136910228805998309,2828318073822595628],[7590510381177641776,10498331504202846099,10662965233839590507,3116757623201220511],[2287955067896343211,17963589368633505193,10658589390706637516,18894317991354948],[6470862789380652262,12202730266918248062,14849461166855546623,2242273367187300783],[1873312511048374793,15455824937368890442,11656194112034165179,1232767769267244106],[896924289798751531,6809858855495214817,12654469680378914090,734845290839232406],[17047465576130313493,12101311390046573137,15182322769847071671,1023180773269842662],[3116618570006244150,3050304403457920310,11949602981297598743,872380798148477378],[10987904740664328733,8269807527356530332,12086673306317258424,3472869179684966342],[18400129585021623352,17725819983091570639,9335365942795346746,401863454731231604],[7644633979883049593,5553498988801646622,8610663271832258607,822488044543005878]]},"setup_query":{"leaf_elements":[17782145773595303083,12105225252455229343,12731214568750359602,5209470802896557154,2638820123361398926,18311427152904825390,15279546701342218426,3513592622558291887,6221029848168907424,6293909064554701906,13388551053245119566,6818085612886677134,7401057021151835854,18215987261128411774,16092230652700025964,11628258350891326603,12356461786131233412,9275188930439160764,17659588011863271303,16974225618898564566,1562071152613840130,7353860279372263727,1531632951340567461,886672662707435834,14833573266408609372,9440127265223643297,6651634496848732276,15786522587974477623,13508855113920158580,6154561871946805645,18299310217691059530,8521327749442408758,23162531976508560,4506982283009059460,11149257707497190205,17802775679379216391,5978224699728389606,3866893270467964579,10704054898689922140,15791602269022134074,9134947256935423526,16417489763897557273,8333226201978193258,12030775729998536147,2899427935883618613,16301250994458975161,6603704599796886543,9823448101051116572,10950006897489270177,15852693353865986544,4297211783831800441,18360548907276281086,9132769068640397598,4335526537961472207,3016105638733674178,14921466435855588769,18389356189804388112,13452881638867419801,17293386431861290212,2414881981519630940,11971364704678043858],"proof":[[1480529783378959851,12333690316688723296,4309586749459707866,43018663553873837],[2244735709016631939,11548717798700318104,17996588827949293648,2736330177885753099],[12687772483104223000,18319389174578249155,4138163291146617659,475469086536609729],[17663421293409367099,10182509609294383308,8700839027894353151,1650213355775859511],[17617405386537689624,10803890213033778063,2348809168482666178,1088977861798100722],[12367617908505877092,14957019031223963226,14117964538243414884,1344040135425316913],[14687027911334798213,14614419711818712392,17879089344145295588,466194572929063132],[1065005644255531189,1284636815828318074,6106911498311468883,1219745525821636097],[15023604465527579294,9607297900213284664,14110864797455122933,2883024653802373252],[628556957677155828,7585121546351451268,17616108359763264123,2705061026983748321],[2925546025121368322,9393212929099205742,15922491707060905970,2420077998596994704],[9570117264848148802,13031384388492958840,2875517330729552202,1797201766000743835],[17233809955911081924,346565918454960805,10256110933992363603,1021423818581111110]]},"fri_queries":[{"leaf_elements":[15526693323502978609,11070899250978640929,10065079863097543074,17412262577618895674,9788588448875878861,5429250036642708947,13135458651686023290,1721837130634776045,12171518770295980861,6043889969243474216,17734423746038417874,5100518189825784239,10541394436846761596,13865018793607541240,11084876544253950707,6857351290243584634],"proof":[[13846763017979781343,2779470092049346651,4447932101426985549,2956784984924931023],[2694868091754838793,9696423449273113661,10959434442476658633,3392037012893205280],[14482077562851930809,2129954715150560452,3064182020333460159,554125088704349108],[17854694079051012084,2123844065474761981,5806775957423980939,2326010763908955917],[13864524522564200801,182678366687134381,6643793782779364032,322788871192408940],[2681675665800531770,13497876709844975924,14399128414906976217,1805142764847213427],[14992849479960007690,11215741003905785426,15588352663165793123,165681071149794813],[17623924459256954140,12305512018102128168,18115127356720493669,2145943281043213099],[566095417874937160,15038343599373286874,8740222354101684066,2931945077491031766],[17504669361731179974,2131055028050421148,1385363377788465903,1412066716416574165]]},{"leaf_elements":[17950783216801127740,12391648107447077162,3534989011321275863,16815653095177082324,17514739812002964694,4345746075605430311,9735616760636997598,1179020435364994708,10463317660534982160,16453076427050667845,12282493913867815384,15306675023117047302,6923128916615584663,13887563646484830225,9602134933345004306,9295085251521062274],"proof":[[7511042054991971030,6167183366691983386,15258347471968729224,2062661517999546495],[3407592941498116814,8021544933882080835,3623121715345915074,1827079755456033782],[6696797621464492057,10810387206839314440,17412574846726977459,2168052137990973615],[12848174996938781007,5407283164694043099,13767705568471018668,2408050946651618038],[2385816523902613387,1501348945346020961,152288624272726131,1706442185237321805],[11942813463679522047,11347630943101030614,17936129890552113812,2881836516204859492],[12768234999023651365,10129420054475814617,9085624202641957562,2813036854653805665]]},{"leaf_elements":[15997009302944698006,14270131949276140433,4400944575674046551,10974919612377289612,15359962871354373737,15409656810324791493,9987224537441179323,14224962973178977019,4933930942537917300,6901341756775153657,3035054613398178871,17563301596685452845,714530273645811056,14350375597356506508,10442915514158627045,7373153398233004572],"proof":[[11345269940212746383,4160826551232717350,14374322261503278022,1577739514790828163],[9598025570090363779,12307631117902654730,16837469065227998637,3310607545286743763],[9757453704712024366,1285281873730643983,17442336056444085252,2819784771850586037],[12224604233216893620,3883891059941308031,1780591444954729148,1399256507324657499]]},{"leaf_elements":[15893017159368408170,13726125840665252010,17148517059027992310,10710769517928453429,62468483247850795,1706573451560102365,6329054516726111507,16539953298218191128,7256712283437372812,11674755078445890482,2696239738289444223,7519682009745736278,14986697876302099271,12120225001183003578,2476978608143749707,14668648539203632694],"proof":[[9243350332989540492,12504692849143041848,12202608967821609829,254256006803436255]]},{"leaf_elements":[7065729504527910035,9780518320697745842,13314892057648005417,14505346905238107109],"proof":[]}]},{"witness_query":{"leaf_elements":[13821774841987296576,2173465140181481093,10579817599571384327,16556890296219794650,4850930259045551056,5621484121500641944,15437940127075385190,13897394466440590129,6365505266641209790,2832136603806251877,11875745355938749398,11136683041568154300,1522698232522650764,17617190607643959336,15889309489991588546,2014099767160982315,9897495705572687348,6524898500102879059,6386663336331801460,18118472454350364687,2463154574717037640,14640428582634113512,6368023638648827989,15440544973423654700,12308289396529940189,13247999556638508556,4591170506806487405,13716762582311221643,8040149118442597519,15606757444486683016,16932230188339652369,10525054994551734117,7386210915494689220,4076991905882459008,9585708012957030502,10856442983304349121,6009258117103700617,13691364753336280902,1768104409890595444,9150208944074615997,15958426363473568198,10229315296326755022,15217714958197544405,9417282919661291755,4552179949114370037,6582494377664158016,11173806008416493697,27728799129673551,4202195515649673952,15545040712768388700,5206569818333477992,16382786877998554407,10301891261355490299,11262181081473197224,15624830296689851458,18136086736033985978,7511721595278127079,2832788120613549223,4493645438359153173,16331429190506806058,10802896200306295944,6471387783896538034,14822063353669256164,10391798824377307143,6440849523889126976,2727313916146995772,8712976204293434997,13543233381764447588,18369335883275470977,18132624393008122045,2166906815891002201,15241470635469856439,9239930054055867640,7540416786567368047,18176947553420928981,10484430892525927262,6421035613018369237,13459368807567919582,7411083459541271030,13508841703175215612,1066064386547667736,2037209011284403387,11997889897057101201,6591411190693050465,16162419862830768363,16453667175878238146,10301229634523434823,3511849686033173230,6034410505344969953,3332272288836153216,13966099606600273027,15472017513710595807,11638752472868863844,10458792455850531673,14848355837193067679,3718062904611781266,1120998465218644409,29717779390382937,11451251749539216483,13478414635932985332,8305756976508718007,8190903855229085357,12902375634002739205,7046522760627542549,2418217376705469277,9908402852831555534,15601052433234263293,14361043188438433102,16256613223894900842,17246072792009313405,6047930523623201964,9431131952030909301,16600316936049112674,11692104260058310425,10987513577072100489,7257207199736467663,8211014258472351598,9857869284777490502,4442789141728944817,1313971172699203110,7944068724024180916,18127318230973266136,16135933452334421647,13961072240110729415,7483648139095563735,9036001795877313271,6147572955373179658,11022965600870500848,3557189012402075697,7653204658697180745,11838889562519417002],"proof":[[108115099596351879,14131023580717861191,9481609829964097726,2060988456909696072],[5788467183117055334,6983515015863461004,18049046794749373917,1956792857243920792],[11755765135140478516,4216113096261181659,9729931151634588433,2706867273011983273],[785208036303707227,9933936563576436249,9627944696557539577,2999706343347557596],[4635183805052082020,6851372427819031723,11937999531152392914,3128467060100464362],[9073248950657391456,3563902054723590420,9333195910855203922,845272067293658551],[8484440992079562646,4977230656189336482,4105615194137608951,954708141528376793],[8800684375111414410,12212154409294577786,2425914583897426374,1789237837149782189],[11592596589119456637,546114280844764117,10893458119382614313,767662925490972099],[12429585374484222308,15755987540261236508,13541186208445502846,88178831612874977],[14091583747401054235,8013636446082379551,16253246224390022151,483023640479400450],[9392237965359831881,3373404592516458736,15381650937528463053,2235031350419977367],[9726171590966735923,4829651508997724003,16090602382248396675,3352657705301266573]]},"stage_2_query":{"leaf_elements":[3406874535190529868,1844884583128141,1251182387352331810,11753237838083043661,1773340663489466391,5613469283166259824,6243724882313272378,17627871525249795554,222800152535371777,12132393140224712653,12745386593368930294,17070440694549038124,3783035685356916565,8226923495702751473],"proof":[[16337032383898008421,8572557260461852276,10086414792736961996,107529055323735003],[13359846068827274605,1676277634425131080,6079529741279970619,1674244286937324659],[10746431402901577562,5295321546263257798,7326335049210441490,717222595993552561],[12984820979388084274,1095237112126188354,11456506837140311175,470930463623427129],[17327148300583119286,10477153979218471344,7343473445009952505,3430174866323862229],[4091240440321875975,521666761639895530,3448871519845678695,415657341545912571],[18080429725855358626,11162300662552894940,3645331286962591600,1177565083204240698],[16116690592960418028,15536387953535871991,7660838372346983916,437482425979689812],[300907486011493359,2585194937478303801,5409274350043594288,1849385980261750514],[16175918921888327375,14327762221961708410,11863767738778267675,2706864635906876479],[13690185690323344341,3422592527962931227,12283922099035150449,2426307266977381925],[4085129217155588969,9902617974521523003,6401123027535736409,2341382674348654216],[18089861010488996852,12225825164867094808,338012099446561451,2297052575992396677]]},"quotient_query":{"leaf_elements":[17015495238034528779,15132765810048860809,15286608113542257999,12255909478863141025,15027750992693057329,4839567215074200918,4363175597241377785,8077973453042626079,17058719253703504927,18431969539316109298,2294234259419487402,13161085382119614537,8297754059776036535,3649215185305664954,6672691052918156952,12899913326432249621],"proof":[[9667377958860907945,15353210443444378962,14521525829899525420,1042067204780841247],[6744489740621661222,13904709238090046829,15633246814557390493,2605209681722670179],[15505532064479240236,5602208866861647869,17239324858490618647,1501517448978756359],[13479446003158989986,2501790227604638460,4695891858520434857,775362646142662166],[14018861360974993152,15124498808552633361,16630568875502354281,1302406569762231360],[16835733526592946071,16387867921925113084,873022805833364243,1229940763613345294],[10274698009643330627,14379238384780950445,16682365949117888785,608980674378222610],[1369885325860478735,18064069123947309324,6121489737830458181,1761805992168430058],[3018972631656144144,6143490577040477695,6050328996577952307,3290643506711379995],[12363221408990137394,14249998656864331782,17794978571348959191,383383664826939207],[12855773456359339230,1947100207869309666,15627659640544093007,2433885526130669722],[914096873976635451,13600268564108607375,10755682147995863864,2524133046339100366],[12402567447674926623,34131464737049163,10998478783239915879,1633215049887817820]]},"setup_query":{"leaf_elements":[14764019193875456829,6728811276800868777,5917000491557725828,344623647685893797,15201507472635171202,4783221196355375155,6614712367096126211,5662100303355746873,18173325832550535919,15505414269489821457,1409018220640623236,14561724413411212077,17298478038712565949,17038904575262040353,10358550766655648665,11889185023129732669,11821459017430105330,343107432945153437,7229517784689857100,2740387578888905171,8905037291249662753,9232179249189112131,12049641580961520192,849062828764396984,13484550798584000971,7554539166569403264,11509292285003992302,13641483667166997843,10910606250255955054,15987796337968714479,10019224500939943097,2600845420839859939,9580626414561358670,6084892147123139830,12630829398559523224,12839736926583642942,17173970431855477114,15591095845323400263,2717406306941688523,11608894612372167908,11857717364138548457,2884587361837518672,12155436523349253887,3251091115110721430,1184921303192147100,162580898346778319,13625241752574124286,10713586814677454618,15364601154344578634,18197920217890928077,12196488039107195419,13969881563490652736,3771944588831012454,1720699347071383137,4412474209321505288,2343555299558190193,15617966892926760210,8735286101964777978,7886389794125106190,7768273764623176927,17996989667167363717],"proof":[[12265358872639976948,172302468761399607,399003007459820103,3423921717199795012],[18101016689691109814,6608040551859128672,5152559867786535792,2681952577876950494],[16892413158105875907,8303754829908670161,4775203378571968057,2824133849511584770],[2163852749156281716,1846321641593408015,3007702819703105012,740458673049503866],[14556123488789758314,14022635997311579502,14721163150312892667,1084775977797034537],[12260145515585580049,17322661363297850752,1850941033256480460,1194284468706441627],[1273472665081956878,14870524553347491574,4239978235242695877,1364407448580402282],[16849496271327074220,11733059684343140721,11674273614320263526,1469020967236430856],[18359097096813559168,16962403842135298548,7848896523196464197,1772769873494447580],[8321112589569803522,4939077257470082413,898685243798170262,1537360392600558003],[10314200912660081869,14899293936836911685,12814003637050044911,1120863063100975849],[13691466506730382299,12582051411105350099,7515702800952027373,1032050712653070522],[12677027283722113761,5760596819309652167,9296137788221035287,7276189033338124]]},"fri_queries":[{"leaf_elements":[4425149509202910835,1821919373434212079,908826003267245820,3492684954213879586,6385692308675741134,3185293125762409681,8513128416130144205,873999808831338179,7540361414460281832,5879741413337035746,5914496074022315145,3937231545191041718,7247751475299959618,1860706911466615153,7945570914183777337,8889751692004836654],"proof":[[9032937370111342628,77728885008321332,17975500602725426028,3286702040675708720],[15734049592565547387,11880528582138456223,17278831148291056201,2904281762711519334],[17353866491256997706,7808515110557791506,8824177846914828394,1782419013340955364],[13555935847243160864,18282501518928060462,4065256561839221055,1652415855583315996],[6032139312930022077,3797938605811134740,7701749343635663971,1770821783939346541],[3035294361217179049,17807962004999393181,16022199603808414592,3443123618314210633],[5580756781335262704,5744769864188592755,576668182097871202,1693296447257780535],[15561732359266293241,12960261280737709094,12839791413423074110,3375970917139363518],[15377055784024574031,2935190248487441831,9819102633003476332,1673248324082124694],[7833494872882654736,13491280940374720712,1865292856529784931,2326123362451408995]]},{"leaf_elements":[1910661971672655671,13406224002497762458,14270168467704478487,6062203188007533155,12317396904888359209,3260627862664857303,8790486393368991446,11461945436485809096,15117945566867935153,14637252622854989072,13744368345596956626,15472073111441057758,14188830251208038493,11845954410517033550,3246513062421065946,18160852169237166937],"proof":[[5430240083685239156,13213842175797605418,14868736740121756911,68829229777439703],[7190990858177163826,10596650108521409569,16360751759347949377,1200916602833135431],[12788328036769690358,8317622452940775999,13407505508679691691,1720808961387768581],[4768484949524193003,2866945496979662378,10961791452041971594,2414364381203295700],[8768978161874043453,1097597209188189216,3600548552493907180,1214987540168240730],[10382723244974006766,11377203304278681465,8396257149204953311,1363038635008309569],[581308798135467893,16998357754940647505,14986254711669363955,457711454011638545]]},{"leaf_elements":[17077216813323378139,14709747519409098478,5623600546262830777,679118088041086904,12218624971849167725,14673612190234717892,11810900960847463012,10995659475360312652,15676906182957334114,11345992929271999063,17687225736108474558,14513635765570081926,4178753028088895499,1054961627388689589,12931494099069612078,2172019769579270871],"proof":[[10815595415076825166,7188127971147345499,7805454341537490479,526008818062141885],[829208853847060487,11573188543703142198,9783951837554879792,122082398237023668],[9382926910159745008,8401489314014756052,2781570748316150546,1912543555875382734],[6676997926391340321,15562037663091789584,7589018588370876531,3405987729888422728]]},{"leaf_elements":[11414911216863297309,9958857463806239799,11617274891234403398,5190211773535601480,8383208128232170584,11247122109368299925,8471331620151977551,10425320070161718803,12877418394616094148,7618734693058804732,4326828691187841724,915344756469604978,11516958910916813934,10740654785186859735,16851397472892690165,5451020333978628369],"proof":[[1556664724426284765,14553328811358462559,15787649915632612502,3130198072879929077]]},{"leaf_elements":[16020615081147422815,13915578652650564399,3736948130494827047,6469096372567627750],"proof":[]}]},{"witness_query":{"leaf_elements":[12378147862235105557,16380610098810392501,7061467788356169018,18045923129330328397,15412341748570981364,16390818808754798390,6721835851823755508,14836621727805328185,14684566669652835864,2239874112232813202,5841156235228957482,2086481121249840128,1705429603817365764,17358498843792232622,16768909663448758908,6386897967756613997,11457458172522311061,4205132761882894206,12270576626337982824,9302494206191454420,8544980752611825622,45269541637439514,2412900308703753983,16807064023684433184,9426379211647782849,13829196774752094665,15305021630895434883,3794446784069095536,17735516390336236161,18425433281553388016,3122173870116389457,16781572598505171738,7034191275762259669,11827177142834765673,6590980812136480268,1005877516419489689,6239905916397220540,8062275466999113620,4079901699638452936,12227582610309066981,13009213240326961934,3645871339254153170,11523832877588242291,4204226711153736405,5333522782662205374,7197368287737328644,7623673008326335944,8550024007737828950,1202412918632503611,16226201744555711524,12595504713183102815,1472432621485828773,2741017054262912012,11803941567688273628,3747539836159608191,4638747143824215370,11565820921915004993,6077863222175014388,12249971535926244348,9038769518574091593,2165675578669112008,9929716907211545779,4785116388398577472,13493517815526512069,11268587515587608461,11393329900203480084,16694341452429594264,17336242228652073482,14669730739503138553,14388885513058387515,17388606123356668780,8130115344464292207,16444175352839041971,4100580680013747422,3855738931207754866,5264609851556260534,3716489141267421215,6270507540833638186,793714912597170776,17912586992497120945,17510200990283876756,16565660389156694933,2941783796276336636,14224522939656208615,6569559549250017880,1046677066004501711,14317566658339263350,13677501944595519591,16010569498149595668,7536094658763282154,16635409857622404009,17195895159059639895,12636101628916025613,4475029267977541547,4297082841124284110,6924247876001118730,681749564972526998,4751846155072398094,8555433344099904500,12071994877760516318,14987851340028752226,9548265492882078471,11697042254670071937,5691378036626353858,6089275687009789288,2004136431867342943,6924833304124059069,5753678252484517464,2706730175823828532,5441792029240803781,3189714167635008484,2587340177268332013,15179298794307356355,9500327148699375459,8967105130741721242,6711622183135647560,12920246842474499205,8641414630572336125,5705770168316479439,719648446608630954,9931539445583558710,11134707635961986737,15304572038909211053,11068467182555048673,7045160360920534544,11962421126169346636,15312624426642434657,10626233297001374897,17361616791430363439,2609406420711234784,17835333860024055236],"proof":[[8336982192291657318,2207436826341216797,11634807592568171203,735117407228594963],[15506550586095533315,13013336075316731404,3376066109461536108,2384323486873127727],[17424475874453656939,14981236020774157965,13547751937371430877,237300608733982819],[11511168609423990056,12466102826999630694,10314447345301351976,1586781937629832752],[13797435133729434094,14886799828829352520,344902919094967250,2751919268683730818],[11290814805735393274,12725836103602435363,12584248733229749742,3179255057311409828],[5618260122140717422,11601184528156138816,5194634568906378749,2413272886008082345],[15042620436125792543,4328471352099434356,4133763943020039381,1116156851058173248],[17709987292381749157,13869423038606411345,13442839829634682994,428863761033056894],[17193176952710025348,860096432313589575,17963610832003238771,1391358697504112409],[4734995795921915230,4623969510906222627,9256522227688797598,3473826067968244499],[2892709706934527733,17838480464587819444,10155705260521547536,2387506384667558531],[16174210416781440038,11224782680825625613,13584339858344595283,2293598389344857220]]},"stage_2_query":{"leaf_elements":[14822908254260943213,706880215095074549,18391757278300367870,8338474401524445213,10035072905225337399,8382069550914363236,16873653600316525085,15512584181366268776,13528298269012787761,6405058744682191490,4018097479485315289,17534109729573794521,7290239583486174651,18294749900486314753],"proof":[[16629258704449432895,1535873428852556293,14855622486495098069,2224485992767796708],[14523583408010058070,8140971107318563655,3793650903422800325,181447634288586309],[15457596190067676529,12152438543275835579,10597585789797693794,2137902629451796142],[15518090210489280072,2803931238397097059,209621312300059785,388834816490023008],[14949031042941832862,14857668634667210342,17183981069901122218,2973435930147366837],[4133756080407713473,10279191446177836970,1030107231845462253,2538513074587951705],[9332403821431606122,7155253334881422935,9964947943857967470,1957601079178905542],[2767789402370602850,9585156646402169768,10823349752862006985,112930487613252682],[4097999239774129441,7604543444120790135,1894460702108994104,1086651341842154717],[17273947804060033556,16199810104635056885,17938796905747720364,2949621109597555988],[4307292625710429256,4505716506027778825,12415975303251403643,819183608158687576],[4099148929035402499,7673469686607061609,4505982977117334820,1485991602633362902],[7143706776069384250,15680275494194306607,14480354172152921765,2190139242083446267]]},"quotient_query":{"leaf_elements":[248812030952529412,6762856217746997696,15109044828495968502,9850317994157206478,11319765543032717386,13899634638145401820,10428596078078564524,17169335767736377216,12262603094762562806,10187033812007071243,2237659999878679963,15001904434705230201,15289820100465071514,17281305969419193064,13402537156267801325,13277859182179962592],"proof":[[806494729078078186,11314319978597602356,9303193066899418681,3208786614534289717],[14101716351477246781,10079272957908489466,12310884832314888794,3254714862979325215],[12141223880336549216,10732073104725175886,11517091148474891720,2529154504037420096],[1680572701399345807,10390428392133393578,9801632962442923629,643713052374328032],[3623463339886697158,18151260923549110390,14289357189221627635,3424471588862521501],[6828805606036321867,18120483272107007550,9219485302957988926,929733929835488359],[4457843730121296737,10198457074278281192,3003059237990427180,1244864463125751181],[11023162467131714722,924729220689830403,180931059525246611,2003107902580152060],[9405858294736761853,16425136972550717999,13240745343526695327,569825521222689064],[7393917858099576981,12169024137893925324,5233685297229839670,2366559202330909870],[13071015009834032515,5244056340103240456,17527143666732474632,64895979602718316],[9864148082391051930,18335226582304505341,8569801661974152939,2353801358142108048],[893769981673929871,3319556979175080647,7336913751317520875,2767808378512761087]]},"setup_query":{"leaf_elements":[8759760376929764020,11606729972106050689,14264780336105757805,17313099262445637994,6935948235493248975,5293707412941225122,4721404627242574842,12995622101403513111,16062260084056439480,14635153427405317668,16556437217841217435,14478135756777166634,17575192777374736242,5235825537986121082,4244680137882148079,7542422069264114486,10020567869133067006,8352134438168596127,12589222196103280922,11875338599957196267,6993389918236307308,10300707310431707907,6821576163484181670,1570784159969970220,3815770029367084748,8461942126411382526,9204422143289599645,4656141439155907283,3411264040408551486,5731769008062606701,17922107491013138484,9155543139607635831,7581548991561842886,2706223559006198642,3068270269912533,1927418978129451839,12377165017053173839,5378777809551699837,14850888348671074729,1442902898369593960,11437849527491462701,12022718603183921917,8142682023678979071,693593270374035437,16012743383488250909,11609403062570184166,9751039410085468926,5946813030686186883,9647097260752804642,13485469846680231362,10697536011472411730,17029093578779888227,18210283382339088042,11582722849931382473,6363158900546789601,3966222584484168460,7918644140772521218,17846519341848763625,5720992035250894880,11991706065436277047,8873855061294445913],"proof":[[1645960536246882689,9868822223658293058,15889516863986373840,3106532920168906607],[16296961492468133671,12475868050990842610,17631793699736904504,1036027731991346231],[12983113375495553235,4824461160114454157,9560255633713034819,1147380050966209975],[8430694397450308972,14102919200770351249,16830865143557235138,2144142871357082798],[254629673276667013,2826711594632026002,9593753420730538488,357888162574896919],[5256987839421954282,4051967046002127726,6564720132402659192,968068871948495107],[7700002472086444552,4724571277279940496,2466410653457135959,1594761329648338885],[6374881958160804808,7715497075395279158,10456674726393758772,2858589021929213050],[6030411142193316661,2522123567541469446,7262132202201577603,3002253707942951799],[16032122289984447523,7499403857371149926,11887253149445581209,1683321519167369353],[12124909263257621136,10818567662606497721,3959115628505008577,1119369570721152884],[2209330244228393786,9841280879286562939,270696346365318705,11851569992788159],[12671376312025887274,17441343524713900297,10896011836861176681,2912297064607346901]]},"fri_queries":[{"leaf_elements":[9017462378017781621,16101196482292665279,7665503339165121049,13129573912546594153,10877532224592754596,9282268430117184638,7191907196548736860,7899441121909030017,16438151939033260289,16816251933029994050,2958809156395270718,1659794431082484049,8541618478544647422,6258876874104033501,640589225736174253,16070648532684854594],"proof":[[8713942476030565346,6842803475276604594,14244245015210981815,1811712870411061747],[16806376993794293959,8759504459074233921,12940491202915355934,1272927983866496957],[11205212739510612406,7878080797064323041,3135739584528596973,1861028949440148472],[220972554002484898,1083069764975046605,1080059382524659125,1851361876503092232],[12956151689882073341,15314030438263027396,15990740871227633115,1399256910532196145],[8475909807969763234,9152329035167862776,6912010028224455197,2202459725789123163],[15750385535818593120,11946133434391833354,15343526478737079321,727518421252664123],[11024181518270608996,14617547031936786079,16376168583193951650,3074166109090888096],[380973593249884925,8211361821003589829,847491229067143454,1569444070397871644],[16109863426784669012,15963846919760798386,9142194185212147107,2313643416305218987]]},{"leaf_elements":[9746367625657692566,9893888500343730999,369930629267831070,7556812195883317562,6051126059330903182,16732879840186833195,8889501280042402153,5730461550236598909,3731976448199845378,10569900882427889299,15930566329982855661,12561000376411720083,11104261639911777790,6008518754081807499,8142286015690442851,4762867860017816745],"proof":[[5799997093501202444,12387449882852605817,5899156034917125878,94467118652781832],[4463916695716678161,16874370437827275905,214848589596104186,972521220694257935],[11081156110326022310,13428368980446310311,12911907201251225563,2075006630915523632],[5029247599413956245,9614974761259856412,1607895646761284198,2761613305995890094],[4575792760137230209,11633705882469235577,9841123168578556127,2039102739463027263],[17680882297911546997,1285525161416870700,9603686181424221186,2725273453195948649],[10344127557781956199,7906363140092405288,5982125655274322770,1672165157955432393]]},{"leaf_elements":[12698284169577138121,6380679397958639310,13463694638516145173,1867763465918078328,17101323362300856734,5571058722937926322,1078874112603970839,18289262124767908587,15023365805438353369,9005816757625959421,10455895038319905090,6326587037493777221,3104769015094251340,16718980437211271523,7547915859214082494,16090006472822739677],"proof":[[10072939034673203190,8264993371088481646,14552178211266357679,1070107708830041334],[1975479693281105564,15428429971138180179,4843772626935739041,3203071186112330796],[11161226704473065150,3322189911423566603,13118161592899224271,687763930591193762],[4274407429085135596,548774181466706774,8603117836559137571,160198004595477839]]},{"leaf_elements":[14694649177522924455,8970524565615133352,6698130501351274130,5407467138564220850,6709057259898075644,15065386984471511193,8847484406550740690,3130960100291456344,3694217830831795275,7041401053929351398,879613210345154478,14654620960715256415,11095625651784495053,10579595773725487118,8663536013231766845,10383856026212629571],"proof":[[16046369096493514353,11215590715117997524,7658673164007518840,655039943382377449]]},{"leaf_elements":[6485988802393016559,12130974100501667025,3138003141619716888,4081174251100168420],"proof":[]}]},{"witness_query":{"leaf_elements":[7120473777872087374,12364244440942261945,15039384678952789151,4879654229323112809,17333195044769746779,11459449718962398839,4932544065141934161,15798474884844611235,8891175492587581657,6921636407387941108,10707741920929081188,3765654394628313220,17728451631586331626,17414329181355196351,320987627888049539,174348052544068129,18329946054838725753,13092330971231138504,15455311592503237045,7118647647352835928,8918195365170161645,4162635233406819531,7671596790736083783,17440281271815780808,3192351820823883967,15087403254507451347,13949682830339573622,15827855855436602153,3784604947444744411,10061125418848015065,5536003328891618829,14827026064367035649,10103379747401594772,3945611187524800855,18348847578157779834,17971961536656851601,4031411849795676436,5465064502894278329,6764439274666476006,14845474936446859821,16009126127854242452,7022556563175804600,15477924042684160893,3587759579650126710,8012578150791737390,17848122369370758489,16319557089518077048,13754536326279924471,17112461143198852524,3594856812669588322,13924264584747710182,10424296845136833709,7324528967522848390,13987582772247661377,578563499969998546,9161769595875640738,15049142577452980929,15115185842819856990,6786330304023612353,5900819638401351901,4794490039185775226,12264703263263361677,17023675841819221241,11094732188244905793,17864021174449571470,11644669173265580547,6046863249966245920,9710778232943670395,8598043564518894541,1386055798358671634,1373135685304574078,10747149788153324178,1996996432508708686,8308621847777479107,16945311629101463227,12897724117270255593,3433631408115106341,1816110527151884275,11135160301677533316,10213080894333987380,3935192093019262281,8728586563381915895,9821804315992074783,16654434595099731465,13657481155210495916,9364803269705235125,4521598631534967216,7761577150443685017,14618643306510898620,16871864132132863968,1495957372204012656,12528079457476036899,17806466596383858157,13562864374200694615,4555450239293461295,18182375540521044848,8235385653096843702,1772524996879111371,7688646301382823134,2136918407137638263,13284975785888280972,16839182896866457184,4152886957727380045,3265813036335740828,839671371454287876,15108484228508095293,2393993062601582135,3930851572149311381,6942803713275455754,17310441297738813395,12058752890119530812,10072483590632385415,14405202396152589679,14032721019356263773,6344152811427092274,8156221377866880400,2425728490774068299,17536907293334781129,14212936729633143790,13513481087186303838,243548198974514730,10071954612716916345,1966001295930155173,6413915586708595156,3740709862258994446,7560286291306442172,14468919079553702852,13248784537987459770,13389633370422267787,7750290884557092216,3039780721795656296],"proof":[[17455759871944105601,4343005790519354152,11711995422385694315,3130052694863457755],[18198602174717073086,3906635547942207359,11670578441989653496,1665261716067287048],[1382973917120578396,9314075185264048273,9651390036227939900,2409375488397587865],[16013497417180368115,4072388981348196149,6347947928125127434,3244510576770775610],[11531313080261032281,5266360041806969200,5427548327555383195,1514171892125823780],[16157721861801685930,2674547821489411168,14562652467857343859,866068238829310499],[12135050891146362881,1041583430248676968,13647619609416258494,209050212382652935],[17512014452259050776,11425234069054726212,13497319685280206084,649951967609436242],[1924084151317795520,18423834077794836803,15006718471783148654,592910906432973321],[9406116281282634345,16862610032733593760,12954890539348018523,841335985339332614],[12970486835521510226,1866445652419010628,7151429743658632178,111012358390426024],[9976335644155126785,8334260381949829728,16609245529797172699,808191351321526797],[13357217182822843111,7246194359117680782,3300747307565431259,2805875995488588298]]},"stage_2_query":{"leaf_elements":[4846770382016114306,10936044111025389656,17954576566961123189,13437486306676386569,15961411769111472634,16723765871023100490,6323039674061336197,6738260018030496171,15026889363393186151,15091050694028389855,816423396674348990,16138040641270748095,6461909611632322300,1588349866507367756],"proof":[[6659808489221645647,1097784333747589419,3135821239700392779,1212295408655051323],[6261554541491857160,120470527985291940,17293524695832014589,2119658781991752165],[18321690082159701704,16194812358118348400,13612282417018019362,732026468237898369],[8283790504858406349,4537662239765808,9483376461392815472,1450983253666268515],[7228333546192696429,7321729792310877352,13323569734119467848,969171226004965893],[3888574677383436779,13348149833215227516,16817549398079993451,172957782757390425],[6098852174577148363,18341746261172205923,16970466261662386101,937443687952982475],[15426732780254717124,8919067593761422755,12530395192168376755,133728576409286225],[15381732192316943642,13397214210872857951,1572619577451894139,1862664925225461515],[2667527601254501578,15544106504185562862,4731071859952851047,3129656168854711093],[11222195966843527041,10029558956373736288,385125420014816848,788548530015826979],[5393399548198960275,4965487180566053164,9823490252370990723,2311833187933397144],[11783375733003255209,4043511936331649179,4043506204996727333,2003392045411938067]]},"quotient_query":{"leaf_elements":[2689554338211249056,13296718297864960537,16879105976621413477,13623640051645989891,13191436024216780068,10872683277834320455,8127100567718997309,2643265051204444845,4133259584340672536,6114627369728450409,10207307803835417273,16260908079140203340,8221015754432468761,9215989403016796158,6222546556757168688,7622321688340022211],"proof":[[8178042332805728894,3029120533648388513,5882347899945616861,2896324927594540532],[7404608930713029429,14202860038401622916,14610039174630890859,587444065717688475],[4185265498667638639,267690816308937484,12974621143606804526,504392343707296855],[14511345440332177348,13868452761932693716,16462848938273846078,2044047125804704473],[4283582443133775220,18421650480376007459,1150844688010196586,3469735703320631047],[3141925074358455479,12277794621690918610,1737893692367185006,3442351771334165911],[15081270199959491591,13172173128134569392,5777546939003977079,656363898187123915],[3670713498138143288,786301259288307241,17446095964794853466,1746227770584938070],[530964016904406423,16737273259892414437,9980033554528712676,1183140712997862770],[10779324384745878413,15028309566714863609,9301081500427545290,3012364719139551719],[18349452246617137205,2023220348133599653,16807574102074814906,3094054051262067783],[11344669591276189236,5448561436747376280,10794809766239163677,2752009775522827299],[10071724685433138712,9277584171601855694,12421698781990076583,3392383529760788958]]},"setup_query":{"leaf_elements":[17389256948100453491,7591223612961268224,4724295791254875224,3955626928954446331,14875007657855407803,12478676310882237285,16279366071610453212,14695470417276404669,11813766305401512186,4373048836864412130,13007662424196245259,17769829720627124438,5676536800689110843,1651981345479425468,11163482391568421743,15806874114343563629,14414961059416602983,9809390565311114602,5318290507789990274,11984953917225379091,4783657943633277580,6019666637395764353,10785296468379988227,2803711256651983578,952305968306652050,1361769468436717248,4133259922448203177,7556176334120630993,15634150363229414682,4973961454454276197,1075894918003449699,16522387765331609732,189619007506318343,11397415602895511327,14577442216824542779,14200505306670789953,2604904461594308414,15134160354341579908,5183667190669567593,4562236843873083132,5811673139210341763,17772027687702371266,13229847439682322772,15554840592941124623,7831273597132061724,12661333554003514031,1744513120393324571,1249346110440030183,16275015702989740739,145149371936757200,1734814177864987696,11445651526548063212,6092731626224834962,15763844271767157091,14487432999729091528,13258992316802191680,16265869290701317255,16903876714966650086,13251333276254265106,11844302181382603020,12938646321292722164],"proof":[[1387728125076617538,1190859897473375019,9053843648002669140,1551319970478979938],[15954570868028986892,4017157308350626878,14126612211214499751,910174763948266908],[16978798298582695850,2879619463617264000,18105543206011945147,2716741904759988170],[442682081711520156,17505614610865454191,9452502570681061452,2648412471536133924],[17164820226748440865,6515232562641208084,14460380967051750121,113204938496878569],[2066401387514853278,3628979646875212743,2172449499360072236,647868892788379991],[442915513697819076,9033876494128225944,1750960690947286142,1588247936299934824],[141469045047550353,17856493507002094674,12291298831670844649,2917433460901041480],[16922325639024922490,12572318564549052600,6906991424794365574,245912644336985432],[5002419135473748684,2543078721467763780,6432413338614147573,747198837494799480],[10199172819188065724,4805418889441920525,7361655050538375997,2555885512702447895],[5944268534244072637,17509291754432751515,4135650977453405129,2907349052238253570],[10215260393543767826,9751391172593344006,13862000312171403022,2102188527394459267]]},"fri_queries":[{"leaf_elements":[15065703246170884804,7335346868172689456,1831839049090791387,5251834376072937361,655291798376380065,5086449075977748273,4548615260576844858,7278416464311346906,13402709827925034563,13649222018488618921,10360971204569009273,17076923465640383486,2612407008247234939,9321605681614455936,9468844879036973983,4245128543494738886],"proof":[[2300680059936476942,11782490105422725544,1154351419247709741,301645231194439536],[14366124617475277537,16458251037123396545,13436863075433132196,797971006266279003],[2506331248385366848,12254708899711747696,270758481319622439,968063938183364854],[6251461406607152087,66828212868993217,17870097918490666732,2097639554382283428],[1634950866521908515,9246371555872883672,8778106318657957476,1658023683722167021],[16771384920563478120,15376903946411295889,12207601135978666570,2299077782791686336],[847109726119985235,3275712338532899995,1039028769337242789,1639376410719245706],[13852531061222225232,14461508082217658630,1147267112765808011,3261791193482669828],[12728736652339829482,3763524200232196691,5497754700624594402,1717602228308441003],[2727149282747321928,10891637232743280698,12913837565521066440,2576402083512426196]]},{"leaf_elements":[14474075653442370873,598395732841250038,4164112465214298621,1665252630203358552,11421629661933145704,3393603602471152313,7637582412252389822,6885787785673831463,14608738285160576125,7807403729377733955,14903910248307605314,15924521827940352805,1929522310048300827,7020273707587468839,13961372690713404016,13482198883358363730],"proof":[[10432564685302744909,9479623514825725608,5654767039973423037,3440466730823134932],[4214351983741363784,10754989992039745501,4550798083872960164,594129952684281074],[6384223506224882999,16409080186695740472,12910110321082576363,3018028220792696695],[5707849192065076919,6778676395563542455,18133782838356795287,1557824070995895996],[11863858781830755159,8505276823327594098,9537695097564425097,1059886170988714660],[8479843093041232804,10838606492268780139,6179794554925052650,2794245564815508948],[3303603528948845539,3326255857540982732,3658681733470339555,1510526829171137553]]},{"leaf_elements":[5333191081715097590,5862992474815932981,14306701148266211696,17965966645393158373,1093299634746349569,11756086375131609043,6842976639385660921,42031853203513331,12096597081821512935,3485800860296058590,14005810957307971550,17645684878237869730,16825334139361091846,12123996486206508675,12154673618882333493,9533986749771702421],"proof":[[2474515105168655665,16746698621835186269,6674933517135459510,2279663511592811040],[11399712119321032488,14188219063488204416,12055815732605971814,325940372394151411],[17822320780112967606,11929122230921897343,15027943035283827874,839309485425582314],[2675790080703259223,11672018712848555413,17368983387124538362,719346710673973172]]},{"leaf_elements":[2269900810174600336,5098110879737557033,8299216941866001348,3515417207436792722,12478804426321499801,343038200534073827,15203631289634068494,12313336925559358131,6203791195205671288,13398748586504670354,8935303490405486729,2665264765541986722,17919352332936791133,2982639848891027123,11502625188948097420,16989819816840410281],"proof":[[6212898492623545222,5273054318572493999,18120166942467567840,1600672264499078704]]},{"leaf_elements":[4501127538857023790,3168202938356671861,488429852234980958,10426529919460171421],"proof":[]}]},{"witness_query":{"leaf_elements":[8610285328607253574,7791379857733166058,12453104077142581735,11402713879570643943,5060237385622322103,11747820210067130336,2592825348543218575,9677876490507248497,17041592038750195122,17178022303234746962,4585518903289889819,4514082103069463382,4386963282860614329,2566897837873771540,1195935013212034678,3061623553280797800,1310981346670642134,7724486955896505363,14385485159908728541,11458656715184112525,9274209916765896639,1960815766324422261,5010847974880972261,15037130342969737767,16779546317402968238,6842108135395441163,13964651877336301025,17133854405443323755,2400083064357106830,14732319289389424594,15912427821723078639,10585688679173539595,10228044350627016786,13999968096877603015,7414821878158919,2361734809151610874,14122175136230185203,18310538850954231060,4527436213405510990,6475435421215956843,3857594478575154359,906577876155085463,7178937540471528163,11969032578984813833,1031181777459700535,3528893098842011396,7057391010168992935,6677751402269642469,10471734909965311161,5615434738475069364,1102122195849530650,13732295629855616288,8006506808787349757,10283536900787889714,14894009314715334194,10840647869920518732,4605684219318789512,13810311419570705978,6163103491533029361,15392285766472564308,5941781696290611420,11756205851660321492,1085751294743648819,5575227067895305753,7197000368648578751,4396225425044533597,6929795567626088434,17412794275466404675,12188241838209451501,5226261219458716331,18330305057379223939,13854621505555697558,2159040259620128222,7317961741860782915,4520391431423322517,7160839567711830650,11737109682585461744,721978885326059655,16339779132064876744,7921667785475359382,1775659035479689894,4364099514722845303,7376744814511429803,15291902084067305131,8592492146996719832,16831026020004168311,4607510055467338406,5438886631401509663,8755885391854543784,7967587934872343351,11794857356046251924,3494295827695701060,10764642620395042391,468267787630117925,1109350458024174988,6083912026912643799,6208515254491098342,4613154800772136750,12954555890043416272,4884442243532128014,9151029980067926319,2633194189553715310,10797344358821358416,18266103313235009937,5996817293454567617,3602062263178300257,12074185998809742762,7098838180889089558,12883614050792667263,10305606106452396040,18012334045672587806,14254175855853330130,3878090267354103885,14260269754502006400,4686926933512845391,2155581585055876209,18160209245273088175,15525398968682419340,1744996462945127197,9905028729680958647,10405449834137390920,5281393873440152981,11867541206524571059,10050230467097846443,9591048527900745469,8683996194713836095,9688678820138719434,11293073728471645361,508585560764643214,1710999461280833210,10423489967932663215],"proof":[[18401581898673895424,1226398105242013685,4689844469790284757,1114606907966473379],[109117488067291090,14021681160582443660,9412797830776936687,943419182115742032],[3050150955070201988,1239892501353772569,4560376464015080949,1597868320707738950],[470723495945712855,5563904883747325981,7186238055808465247,229668183601677857],[11477903900512529505,16993098961729885104,11660437852921084664,1650903645273964337],[13873587110734551116,7443962674512703445,17351766882808946152,2875230231238044601],[10216859080848041752,14454745942699341070,8614602800848552693,1548891266799822372],[3500849281299165418,6941691944761507452,47693698257386186,696483923054798489],[2185101081603933938,2771783713475838348,10745203506244860706,971659783441928492],[9615776086258195605,10386827319165379920,10901404599849144334,1895109056165437778],[1090252639095477414,1003051767983179297,13656174796442251829,2759704369646211388],[17853319454102426703,11458132703626502620,15417113988119134628,674570626102661541],[10228429935734291152,15070756974979336511,15218154065077763931,1832421964913171749]]},"stage_2_query":{"leaf_elements":[1867424706360717905,5682061242219600276,7673141830055733861,4511539846161651453,3881525294216216364,16420524667440769812,9402403931888824310,9594132393020690671,10994039511626395924,16911670722373710344,4129181608417914021,13278986177943473628,5343020421992006842,5478596153069421605],"proof":[[7322930213580668141,18368650568031969971,5368659939755253688,3464527922449978806],[324292203918781471,375243322000580251,18400607892257346807,3087105732662281791],[2679589523134636742,2940422501072288043,11177925057916618201,2112868479469919987],[15388608198419661565,9558127613825629680,6291981825253672036,815834431788277019],[11476272057010363626,10972492643024966456,10691460689386717998,2657494307791409416],[17421856178437171819,17898950181826328273,11897493469789889100,703476897942718252],[15457258364198194841,4704728500804905293,5214016524785381691,804831232053095923],[18044950649686873743,3321757785888183781,3483702833637295805,189464484484133524],[3001093071035062995,5663836323763648650,6274133479706714052,2118167646640707321],[4566104170909461241,12056926391003555204,17013851159357218285,1582466914088153643],[5452128596668918044,6401345446059671116,1782610501691916069,611921027967465411],[4635452191223119194,2876417225665026593,10993606036791249716,3465884504674745958],[2751258051649958256,17916243703110554662,13375786371768332344,179905637827751778]]},"quotient_query":{"leaf_elements":[15615588344083287190,16796317693449903348,6102290737929841067,6307820430784578756,450611215077128730,14826847973514704500,9751193931339087277,5753576187116551743,12676480951305201830,11201087536641486913,12671894409158237745,1465887441338105536,18214172029470683043,15286915677599157529,2750651349067456162,348457781617119042],"proof":[[7342945255021193946,1139786280811993453,14075856851976264873,3027559334696248932],[7041859463341951377,12096010614076618516,7772502755750622456,3093018092468074734],[580043164472179462,12056113500498907219,17603327786356642608,3357936921320286041],[12949720878659344257,831935645418157132,4134534394619654257,490966205182968343],[12113298566052520311,8046410200792693648,2202429080140567004,2280902032501509907],[7879512387052175752,15133860111821069956,7637270840325588289,1577124415176991832],[12203521058141372556,8131063003268509891,6876640073501825989,1493606097866469768],[9245009466764865332,5480931177983583843,12606214966871673374,1541161334124387818],[18094648605715717241,10692740936596217286,9430822955476612071,1887821403606473476],[16485740601009555303,9736363165332285607,921253607025220285,2768452811021740926],[790551840159566589,13317763970215060465,10609960422383475796,3443614640168868803],[16565671729463939150,7300669218253294122,5820718040964588145,3134965001892430495],[12356171133472036182,3715560352098057395,10451102580509047715,2369959934291544747]]},"setup_query":{"leaf_elements":[2848134189451891680,544061351400086380,13647988743949318474,53654116091165420,8706094359192357565,17332286212664259035,5178138718686486502,8396124424563716020,5510868944576061933,16218927819473249520,10222346276657499598,12595280672643324200,1352985635889308210,14629567437419043744,7648106428804425704,8222651034733473766,16487617569269602734,6451533159730923185,365613358622512233,10711234775354941910,10786483239765324030,15072114047523718712,11153871662745547796,4117041262158953925,15959198533773423145,8662729229215861897,969369936388313507,15959601128990314838,14009480834220687537,1605451217886653856,1702544154878639852,17338794660152172425,17741487843794789978,16698957249216313327,1604481535964998597,9579797374601794591,9592895140131484631,10070872876441943925,724650511766861346,4804517361134111489,13297191197863922728,16444011829198296401,7071680759622669112,5672289198106271988,16824173561869459098,10133875311891770740,15611214405094656843,7379134907831996589,14190764910575329006,3328062257825680215,17102011355139116696,2941152299716972709,15253357520212365097,7955617386694819053,11570873856565493484,4441195258748891565,17767099258020374055,4926926607922399088,7886086269757694883,12031123121234452935,10938648824849780214],"proof":[[14620714357541866680,8861706759922069346,9550674045938788815,1816076895902207720],[13959168353658879635,5797380330107744757,6697854506200887541,2672806629029479223],[15626697459810272172,7970000333166443720,15356550203317906674,30879803164078794],[14217369077936400508,5478097121011199192,15209669965024749897,414660783810020699],[9378580867441396271,3165883213271787335,7182371648480557274,87046952434953627],[16582252399215696460,18141025296594746117,13396873937471637512,3484517852267337915],[3604044547697056802,3041170857691385924,10149995936351479232,1205568546781345441],[10671865986018617827,10590153108070152379,12023835823543779758,175773807165217285],[16758538404119302567,16345913357169147203,8875869738159765651,568307702590429675],[2327900155781653234,9479620111936595977,17991344298045740334,770148065054875054],[5797706559201630105,9961922403899465126,4579229215203798650,533441581801934177],[8114630110093767876,16550415767052044878,5789539078719692602,2820570820614345953],[7450018982181130668,12654494844657139995,4699273518936840679,2505102648423673327]]},"fri_queries":[{"leaf_elements":[8742464067679632347,14771910677779787660,13776711629779140907,14019916943470806071,7353802907458225095,14287148280871057153,5078080799969238998,16037148258158667679,10037602279042072285,15972179290651476224,12504986374309057500,7961367879982300649,13136837929042442526,14792466858556408152,13450483981549815374,13506730659384405711],"proof":[[5778877994985013179,18166569078545865182,17908051065884331624,810455143717822441],[9600776804582097856,3402933279780912990,8914530534435616726,1084470842842260592],[11596456325489060740,14435203956938690713,6800551900832382792,2988970160067038379],[5241854739735688769,17319511734875303445,6708202751788213690,1772295084206962326],[4569148466661232673,11218924122431498371,5402640565911078117,15154034876321500],[3275106500851248644,13581349233920770678,14654487106743830301,3071267940617986805],[14233632040557965637,8018066555756846088,17676169116513302888,1273460375195879282],[1424928588733702440,17641328804410442492,16195880388039101808,1938524304438241557],[6194151911933769572,8316546869983692090,17095017662834920753,251028876106012784],[11836481767288568977,12693209842729345382,15494293070777243110,2609142590190361171]]},{"leaf_elements":[6882062710363346253,10574065909906642734,13913898593141861035,1935084972466366460,5237793653160926477,17597786303665312841,1856832122359542702,16758188396222453338,17485031816965052578,14089669378529872117,3911202818402368502,12607889996757476877,13130296505620721918,10254033178209694290,18285650537489226822,17077861312187033890],"proof":[[15998422006872519635,8536287589095938954,11652577501153740672,2302946207278524738],[12705212250886568389,14385136841260239320,7425371033877862375,727532234031314098],[4356984349895837669,5253285408950714538,6895324628901688843,462735129328325435],[8975909069237241959,1665984544405572272,4213896314206141202,37268232745936987],[7001584551067187303,13355190561100452279,1302288186223270773,1236566086277083121],[5494814019481716921,18311101359736832981,13570339656516216338,1358630459201341816],[18221825548504215278,371654840480040303,14092719419885102622,220673262799455597]]},{"leaf_elements":[8265461790474828573,8291768010594166938,5163248426449179188,5784572887990822866,8521941588987919204,16266490867852204450,14358675780239904371,7819649987222633316,6049656362629608354,1786060624767365251,14098607384345449992,3062422698985319165,2509588118674979811,996284956854495390,17962858890336240332,847586205464793878],"proof":[[8061702418792495453,15751574657855257614,11910520168733886864,302883432085742265],[15551612106057279797,7080125319648695578,18211325055795745361,2155849640567126663],[9253287968541001853,15965406532159194935,2926908177009333941,289682274534081662],[14060609606501320317,14199662051727725133,14045188731999541466,360178435938369202]]},{"leaf_elements":[5617743489965329866,9656866167906423923,12342513696506161207,18445839140823577509,17173266430686786372,9885785082442603736,9640565192041168087,8859499278609365175,1962944870928990236,3217289664835128148,18150089437950339150,14748222972309771547,6995749073399235010,6830073760022153520,8684292857175602258,18324510307768863292],"proof":[[10423969435245672408,18154964293000735088,16236043164000731250,396436116672654202]]},{"leaf_elements":[18196018707140134098,3942247739030689718,1556687182756891542,8508669979898744338],"proof":[]}]},{"witness_query":{"leaf_elements":[11790877970570982776,446118578940642068,7598574781699441328,16494445964991915568,6831073959280401314,15437285794828460730,4895754765647168528,16787546768143651811,13368638430531460149,10487285764685131927,495632752889250898,6143567446700142499,11870701633948494738,16845555970058859994,16505293721492803663,13769097844820560459,18335269800533688379,11843381843877727400,7285026454325549384,5895190863314509654,11123675090418426562,3717109260493649839,5251912236300798674,6568333562852270115,13941687828546019641,12202397325657549169,13963240356634157388,1193858447443436629,15240879441157716043,12941053982883677122,1559332358130851735,11280286731904190348,2435160256089295851,3112215220949038181,11691132879878438313,283336714478844656,17344227182424967809,12669242043946015650,11779558771761835726,15704871524487028528,16924167386861549585,12672309709325643177,1798277939911919314,17765111173741458605,9481580954657318344,5654619776148281765,5573110350560276020,10752694623942364918,14515840869059303915,15299591761409881003,7558957815094801415,10746820830451228772,16149487606175843364,13204906968845140347,3931929258358168531,17513883162223232553,1815318811063330037,17427427211240249652,11271686862876326243,9425947854698129642,15449823963511971236,844535885668220036,8350393830301476166,13618865274390019010,1019112540422126272,2585821683188648834,4697638502480183955,14066433315686052684,7664695672783614807,1042224611502759795,16259560442276657950,11399011085046758969,11673149861242266457,16535402558070289043,13156274900535632597,1387195624202281265,4585628245003280150,5693587042134438781,3186361777389795835,14497266505277829487,11982699835368387802,4287575877166809297,8523212358187222084,5355137747464147652,10086209726535237175,8003728341556266272,11443032556487058964,273041288885384926,14696956837012550171,13708507895558861786,9945752416157612317,16385749149867878210,7522446956350989964,6309137675108017915,9979384065145430557,11796971435574918741,5388160898365878358,4662745944550316164,414831201355798905,3650249907970287353,1310071517150423101,12699068146114809554,15351296198779164645,17181970723824824176,16771686421084859351,4232798147097204162,17752111804545215001,8782406267787260947,14046546646641913597,17546623219962751901,4131163571330541517,1154645209328833102,4546788931600607947,4897588040928993267,17178404490809993976,14555302116626665888,785932676322620453,2074453054498582016,13603953172755209734,2115317466009175698,5240656985899753191,11205998449770467287,7535969611622717930,7750419395934444189,2214986586166642115,5578748630784194567,6961630770405435351,2831455570771506524,15757877092316278101,788655629540452460,14238807253051520904],"proof":[[8711249672568846568,524314870938414975,18225953534368370873,1124264731323639706],[4834811119027002708,17147217889415795628,10080706533179720332,307177063010256292],[1375284023154397388,4438860254422441142,13530897572629080328,1843087524730348301],[12331034257898541660,17231856861615506495,17922944953074752060,424898962377309132],[958147301098219888,7947782561131806435,13176708981236436640,2507847468689871721],[7769442315375720830,9877130110921618699,12783690505081938028,3466690137585386178],[8063343791416675091,9896213748359294893,9218261254177174274,1022601071758402620],[12970183801416066267,4052866482897735098,2289489887479283659,3001166666979493206],[11927768655091281440,8249593734582766346,14736021276598368765,2078087719271732938],[14737585616223778032,13745076075830248382,5001623363337376253,2508105059721915848],[9388057809714662536,6881594517039155908,9621280000059624914,3408116750480582021],[5337386146685324083,1759315120300051303,1014203858517702445,2373938672992607667],[10760418131477431642,14820657774701628297,11628914349052808993,2039254384422831665]]},"stage_2_query":{"leaf_elements":[76479843558730908,15948665549979019436,16452339326405802824,11353762651443380032,13694401565679392216,16273478711285541202,119695287512466366,13360036174257544279,3728658069409619724,17551530901902956592,3405363152000049665,1573869791847933892,8251793928577293182,4235084477760711785],"proof":[[8537921174549306134,10536002487736146392,17594708466806428771,1347040021811013878],[3948451454681361745,10738016679780697436,11776516062543763138,1375347522360478063],[5919629436554103797,4787214287188961692,6384397247730973448,2497425831303705760],[2453041564514341697,17309961226127732194,5927898551217954623,2683529132616504219],[11409785013320691863,13762282616345878827,17621538097780206764,823901875159432678],[16886603214478800454,13133362174909382230,13050108577974831521,3052120455135280210],[4050893927706876187,7493887753736942725,9102089217946821295,216756387800806533],[14479399800111271610,3181051412852650574,11783362378526863809,62539514393001144],[8374300493535919988,6538032286451573885,13362003286555693148,528157284078584224],[17537518918145712982,702811882081457905,15662789026126831039,3481405174646986941],[2222405210836799482,6953798830797038681,13472779768468229362,2244017304401157106],[10946443397241484112,7632626395748461425,2953818670712640602,466835577787625070],[10265763405734876041,5280836174585384744,1332105447072495082,1288183057809366478]]},"quotient_query":{"leaf_elements":[15443706856647175659,17694554960446761619,5426685037518182975,9920130029549948104,13425556593253451882,3438361957633228080,14992857847761872460,5806041171686205714,2507612947707434609,8940185103830806058,18125041200169214109,11215366831481019639,8942285623023894914,6611842996574782583,4360174868174208728,1111546199392114184],"proof":[[4384047458936117077,17121644244832218484,2139382223914461182,2562009783261654066],[7061287658741143861,13457237242172175799,18066215834575696011,2737628040583729564],[15173987763831097582,11656369227486022462,219782520668409707,954486743901570983],[11459028795883422023,14502995155698471092,11489003741607576718,1393313131725139226],[14967392653992667260,1568364930200821911,13126997927558969927,188653336775264929],[11846710256606390424,2440648526483677111,14297586738865153398,2631384492257802138],[6365310133501964925,17296767537667637361,7643279075791143603,3173205814973558537],[7103900781068643148,15683428814733219694,657103452600693962,2082117679616968486],[443110545499061246,3760793136594538564,17491704924899846387,1148843959368061390],[15882972925655843831,13958086957113699452,14932522488816505482,3089030408803848823],[10676253219800793360,3065231490902574033,9625064857038164035,3481474067564603472],[14698990891311628009,15892561105547541385,6630210176285877232,628055738420819513],[3336220069100085124,5759271110398045898,13618835346520552360,87853750978578886]]},"setup_query":{"leaf_elements":[13149909727829997808,6437071800898262793,10854087953726004127,12278640222807799479,14252113537362000273,9163940860663445924,15580801852309155353,1711886502253476392,5023792508452674002,6656119840958199967,3068116231010727362,8082019069024062532,13291641011516333237,2104835814461952296,732061843083932463,12511723534388329876,1105741062856358558,9531030606009272423,12884602853675018102,1938834351547025178,7452806169206311585,5231833510902773738,9165482593445571642,17740749911815473678,6527528036622519420,718170579177504698,5157465628635407170,8617159829964415481,17129250811023799074,7674438927344478872,6844882349037890661,12100562350406515605,3644447389876950069,4395742937266939817,2468620919622018429,10638237800440336038,5199554691687979347,11100183826855229855,1326891253974406359,11916987705318674480,9233408572286650220,8085287030476045945,4565935899581742337,17838442545325331399,14211995186192251620,2134943077505289180,15205668265311525288,18393061424862034176,4259499182376672148,14056598873791839249,7492295652449009235,11310779054183705628,10534248697528753399,8274823857798004265,13680233468940803487,6020330193825310626,16557089879236549494,1245429313114556773,7689570373937120056,2095415063085648441,14004750198744597003],"proof":[[3823854021077864609,815682609763620989,12757332698964756567,673821804796226635],[17437765792581124996,14954719964817750028,16127689030167455245,2653179804235438231],[13486952798061442993,2574058697522954559,2910611195497651673,1815184124279457997],[2870496279627200445,6561962467028313660,6134338239894263395,3115234520901725338],[1552509017239695124,598535045262107569,13619471751392840145,1858852389603744799],[16400778237661179355,6372237267536979327,10645121446796989608,3389674511271744832],[17613810564960793358,18072324457812902327,1335690039952108224,2216472110888133165],[17622220639303238778,14053507404653918414,2463913609541017966,1660495836798216476],[12951278294474316175,14511617968148919288,7154033991131353853,156349520852303076],[1566260656853570532,7030921666368450963,6968672400945466641,2459137408761903881],[3204993322470177833,6051698634689342142,14629886291271439938,1970813260747825769],[8634214520312302704,5788473018517600736,3895694945095744202,1852559750666780338],[17874738227292005179,6326465745494053,13494069438792348789,1192845911089305290]]},"fri_queries":[{"leaf_elements":[9295085784596081505,10402940307688420550,15080197055319258048,8189961571947406441,4917445186588425698,14453743338772394485,1130096060430895221,16223852860480741141,10872081667610618389,7563815780136999678,11729996275012841128,10572838343824786260,14129909607324926441,2122505655340722062,5892267779558156658,16625718047678195200],"proof":[[9641800901229274191,5349610189424995214,3583328629309906692,632140557190877872],[12709445359992635099,13916319321141541086,10204102099913904398,612258835466128027],[1142738099851438651,11442849238531782283,18128806351858754173,1244496461375598046],[7988184098359258404,8271330541446765801,12003257862494911486,2584041657848116744],[17826866681432970942,5595476787484481435,6476394214190735535,2880246277819748590],[1508445003923869709,6327538259730918405,15637634641763123247,2318678906210572688],[17590235892659829324,16869889631158424031,15455570787995697822,3110593907418655773],[15278104253822765377,444973421875180932,6867578795190594467,1889369406362716708],[8736545542981214870,18091865623238342905,16938045962214512397,1619771569222218445],[4755821502693131307,9632672734832196477,6831801818195575559,1211503718015705569]]},{"leaf_elements":[14462140882930731350,5593203826115978697,3937376592042192662,5361701539086749521,9917085288490769314,4405939402406456750,4651110537271984645,13180200428696855663,4911939045641933357,7260386287627589903,12057211650853579134,5322955248296944873,9225609860474997040,3708526688374302390,4992862812601930088,1273309260761500508],"proof":[[7972059737774811793,18011826682944938851,13743495507530254170,1333046668988461661],[11656903994129005578,13129234140725558120,14160630890180598101,59844284695602384],[14458336213137122817,11945900117761878117,11682932433367515921,3168893577757610199],[17783797389034557129,11714655599879677073,2210704385848090651,2129281144959497732],[12631542405088319149,8508646081898105547,12611729228031276884,1437295729419850320],[17748107662216378529,3745547155845768398,10781438857281393381,2132537212408657619],[4968579060289205032,15025470103249155658,4016020820835814409,676707436625885313]]},{"leaf_elements":[8955683304045896015,7567813712183879959,15756119619072957773,9917402590863726063,3894130955380148080,7652631671131667035,5307299545898405431,3630850291864102827,17969901419634817722,11438035810891577182,11443097954401481629,7097692750796647972,1553797559833334845,1338605641705226768,4702874296396786784,2072948608115309792],"proof":[[11942064506510791892,3769888679790809796,1901529127762064629,445717851217948732],[6330150321326104935,115391163174278785,12091614213860527036,74519276213109023],[16787357039742660708,15074718737644074307,7357274406577523229,2904651230561894869],[6775086337445118645,3836725614252760951,1244274972769235222,3458783429667173983]]},{"leaf_elements":[16760476579281369555,11684430973873978645,3628257208263626274,13264191245930967560,16805239192496903355,15197924325062831366,2446532897786143650,2265791655783868310,12694463806107320464,16750582611044430566,7379235119149631963,8016374353919518273,11399838020256932524,8401772713760710572,16660944741874745508,2593524144018731665],"proof":[[1408739999051503414,17928989256333671698,4393560887102948271,358038974748859422]]},{"leaf_elements":[15915622550061201680,4536541224237163888,16120598048347926193,2661082248244309055],"proof":[]}]},{"witness_query":{"leaf_elements":[494586387938845049,12965187690162682467,10891979742686861210,2592909768672742937,11235383126208540807,16442023761858403272,7639586301948251783,7951927322697264753,205826553866676563,9753748732600908382,4499478016478759708,3140109597659635151,2406084849010616776,5288601726377997543,13387564577405584033,14780056563138304150,7542227678128823477,8956759934481152949,15534565320681632388,815180232741867327,5990093741516451642,10847502871609475449,11340490545237678815,3503903110886103237,18326189305519880390,2515578336719658165,14820599151837004735,9669415519210697135,17931412632322434176,5281030167664339037,9376311069065342087,15938474160902112929,9882606680929800928,18043417556831554547,15509317776498040026,4863539730680482772,1627911548931729718,5017869250298218832,16653888533979409856,10015665985761253674,4460335737870121279,5507538080749503074,6686919026997359474,17313069942298748435,13532703551230364969,14912399559888829478,15543531445891018340,6188739397872695373,12428791603691633378,2522920874805148015,7935833024753971828,5345722782224645536,16089743405079444285,18318520546727697973,12733948203413938387,3524652139878440060,6563641269243810519,7442950269621997841,8150075893631341289,5083329233787555797,3139632146901262154,16144807467294504492,12864827147710469422,2538114101788582963,17187126257100341941,5982126082546629974,3569794539435574480,14845499217056521717,17398379253751967928,9585986761983453133,10448296356210724850,5188661246447178826,12209186293197314155,15656944740038132248,2867198867899254057,7585370725293537816,14230132653560319949,183342944906280585,8543881147869504811,4357767658493083007,864954257735935765,7220207119138205821,17822532598263318858,12694663568191570868,1075164554804012425,11037466889743387938,6295205804960720964,11764652273575068642,2390107952792184595,16877285714915705249,10963270683049111143,682710945689490004,713088695459838844,16578545635967992944,1236041391026007675,3459308318216890396,13696713138403312959,6280576506594844523,1424952151217903516,14761864330299525354,6021134953129177859,3303470999462554412,18056416780914521921,3385342438578276207,9827524473016340437,13260674901580200499,13385105512985411034,747189697145506748,15950955641943466846,10820124901554567348,7020993527588889544,1141570016575131104,2404494291320857906,17213632926113864704,14401988899409207906,2940306523249168688,1312752675048034508,15719144682688386159,8487205883685225379,1411094979181220687,17989260482900525264,6958200999062228863,2422001846532202951,3611626094335406147,5653529614290834228,14452978858324074111,11529660172070479488,8089659350794919158,17741925354518236232,701488149613117571,18252811675660071450],"proof":[[10696335801996372090,3462564433749579572,1483846664780442861,2963851280313040019],[1020267969615877062,9153700049997494634,7669979424301842780,2334941140114421785],[8969206300841449811,17584493604404983555,6055154950922203150,2893158686130790318],[16898675629602792203,5070802332578261001,13583374087271224955,2348950400177534673],[14433752388927661832,9383686529967163680,6784822415174396157,151951163773132364],[18212600953966870983,7625974820594351202,7135303582853776191,1840565515337498718],[5830125177475051803,702459762299151443,9630598523704232034,2679768005929850218],[2472023930679992251,18356608143881405046,4998780905377858911,1960456933432754825],[13978070535199150038,14475794894689565606,1284025774645954753,862890407587997772],[2497971760758312965,6941215204086950283,2542074989584813641,2224767224879212028],[9529653253922139009,5282909414936017816,6161231114367956174,899405009548116716],[9653994095741149648,6693767989202592068,12384719871825976520,1147806512135128414],[14367620299360517077,3486062918649683097,758936314403206639,1603949708714258502]]},"stage_2_query":{"leaf_elements":[11878684084962578376,4494385637174449873,4500936755451861975,3771948158363767797,17514945497790797854,15864896600997915294,9909201918061353784,18339160192527316343,16788710734065305581,2929868767828431289,4615532773735224296,18440031896085555284,15238124368229485122,15929435007693678222],"proof":[[9125778794454968774,3363003551316693607,15699345391584716828,1580421066866596968],[3583943104563717273,16346314436569001618,2770676547666066146,1233891033522471399],[17224435294655100252,18105779272742696483,15357704327161689817,367602802879093960],[15708094351084264571,12581746329043324419,5642999239911811039,55875057132468824],[930416847968676604,12106277686111108202,1299476144800702933,2859743260175195279],[4932585665350856660,8697698342793775368,10733302372073032955,3111554631839267251],[2103437357965721045,13877219266047975618,7791221423714037435,3037054352082538243],[109797339539347162,16317440720675349130,10514633912347036535,2635985395893187308],[13583244774422467326,16921440355930024926,552337557336598830,2637943588966865817],[1770352352544555214,11503347561982608092,4967334841455303620,1881066244197976384],[5830900046758375023,15604014666533198478,3708889240989816115,577453142693312212],[11586254663808444089,9649978829832228512,2456767594798906555,2922524290208600819],[9302781254238343662,6119432163943488281,15090348966859265029,530198869118147718]]},"quotient_query":{"leaf_elements":[6288864474156372661,17388641728157366436,1180701560675208900,11129139339519688730,15533943338060530058,1693763613684436777,9732260581979157822,18345881987153956135,11250323803839765043,3716551407926387316,18096569489995707896,7254733425702238458,10163512820848136084,14085860656528137086,16805068835122315196,11501300114051474512],"proof":[[3129200693084316746,9622740485476669914,13901630172841147959,2159684406808843860],[11074330326690064671,138146702920897395,7600866575468348369,2867055643309065219],[4887917946238932935,14557010846191481632,11607871067200327883,601292462299709036],[7051061243110512954,10083073046749291630,5473860099177843102,2799545839609954940],[11865923552134860458,8806958037470509095,16969655588670023762,1433556817563517999],[9203603854912061591,15710110411660610090,10452606113140824443,1420419383035754273],[6613868067163403760,585638605942311699,13339273571915463931,1806584203605759936],[101049161899328591,12306387551890381693,8757678693980921435,1217393635480002732],[18121349141535740371,6004176516485425306,1045076458799444720,2500910918030619625],[2228005610798993496,2004724919195437665,14380929959310661678,1689511098488711356],[3567423335356629639,4411325966704188513,4268360902456184506,478658816986403953],[9173486775257139146,10137054949619224047,13924502850789890943,2822498744591213857],[8815952717605006386,4526522413909831776,14701097622325747530,3485165681977640036]]},"setup_query":{"leaf_elements":[8385294869215906766,17917059330473202507,8600719207564478363,10076751219483940244,7327124785209023400,6877190184759453024,12133644788045738970,3177353668896199508,3250870610147229748,8082813536684055680,15378195082822140500,5076593909565070070,1796385137559409576,3672568812930506029,7241780534820679428,14722364220538162190,15542486647199768484,6257468906808178508,1021137440091553157,8874706302715087246,5335688239288648920,13102156342757540334,3894038144518712994,12445973771220514531,4689667414611299214,140354087578985191,16560159381448102226,8996755460599764322,4879498256458930921,11328724145508712563,2549412799628819624,7225586379434251681,15395349397336551765,13120100832500161655,10996651387022898149,487919415341007986,16712238220381947688,2949887285747412001,17435865870562093626,7928654791773960523,18277271362340044610,9603972327759192469,10616277657290668472,1878538640378929897,16757741060664548422,15991920781284594650,12277868667474397116,15853114295607152652,8827310599578740315,13258017316581220167,2530625412086275398,13493092905535887095,5709926064707014927,16597252650045743644,16753262080472051114,2027296429085459214,14234358879686968828,8071595498954207742,8748505570056607032,7830449377802491240,9195671372292857753],"proof":[[3852424932878294628,12640639232106889221,18428617351790942387,3330789616520107876],[11411778296490402724,1110650519322699744,7090864081240560183,1351569726147275597],[6857595339561500017,16781797754109457370,12399435135108266678,958269211513464326],[1461983834848139841,16593646471833302916,3426608616673136236,1859345630495628815],[10082707359174233491,12632527343413300167,3698560122656640325,791860235376707166],[5884133165775465152,18446432436308025741,11956801205287910311,468347193823575352],[11302551070342626078,5001260995988035792,1147700082967868382,3334425487210123328],[7966527370708416371,4528879710987805557,10961704621745180954,2623170439317103934],[9178563773158400734,5740593142323987753,12116820982122914009,597236797772275320],[9425367909661232718,16212916946172534455,11653542791948258347,1200020914090831840],[8897054833573090181,1053001915298800933,5632870258241756242,526235879397439495],[15200607824454873355,11040607145831835802,4383506428310207721,2767645816861274925],[15649328145457671106,549776313160692971,9928450923310963291,2751020716435042226]]},"fri_queries":[{"leaf_elements":[18361425404206606645,11561688235123884249,2044416332881486430,15545593013424070119,17741080039513186161,1145071672423310794,2946412912065580208,16424883512287660982,1343260255814495436,9279357794156720724,5773106712079305751,4479018502258749210,4235804491318106169,11416225051247409118,6272612284151212737,17476158466006824539],"proof":[[12762171578574015524,15777569029816468982,4355565471799723310,767090474218800249],[2948308959475875933,12826951153526516932,18159004496052064260,2225954715612160258],[17543440257186546684,2266462965129150073,7015209755446153191,2349762977204759064],[5392851409279150833,16490295524735157133,13558873771750992404,2903724179016134776],[12416461367675387284,17913305087949531575,5883171869909753129,2394424152843621553],[7696014833100252906,13602634672587788178,17449149766279808469,3378458341309667374],[295476054630260715,2630830757687727646,13488267475738836353,1226401965370485671],[4703718381639210305,12636191310739263230,3062071949666723777,3154517507701705152],[7385017009064519880,2637096054591857111,11922713896890014705,3084456035366891821],[18274227798351134084,14614972872318737132,13670777970563782359,2498334094624877115]]},{"leaf_elements":[2016743205984233414,9236441645675996983,8383034807154644050,1834149854278443701,942124024372044826,6215031654877250687,17395775811001977578,15877458443872988025,12590604862252311989,6694665089655356379,12379012038717156954,7091586019465688057,1472792763016645604,5120886969346147181,11001269858194436445,2955211671496724666],"proof":[[14977983449122652584,4448247215422719819,14919147253431145712,1824406463368600988],[8352427788170322625,12047247660064308117,15269712096600079817,3451515266180398094],[11830410231914324119,9924355807996254172,10267226518896677821,972089213729951395],[4275122454678480340,1662959997101223502,14781032076294262171,2202924470800566547],[7853223832743604015,18371017161360746611,12006668819789881266,1595732005214836354],[2740910005191995843,6716625060797660464,11518524057840860956,278856238073149708],[3864735070791189707,8330668194952393004,13164775125511877827,177041749183560687]]},{"leaf_elements":[2167546782365224427,12972500962488132878,10060384729038741461,965079689529559409,17185003784188946805,4114501435647959198,7340445652922898361,5626372596246656973,7217929690013938425,1117583472920906711,3508602984700796914,912924360294464995,12217761841714912930,14528486953412149277,14359975623516507265,12595374255463602235],"proof":[[7895962028324653724,3725676821329781357,15688631988854298891,3257510923188662860],[16251869741933535828,18422115813315679345,10222120882620913618,2647976828729845650],[11832554300978104202,14261403502407546042,14520703700616912472,468790055090309713],[15036230558710107040,11921162934449550531,16484118682594038981,2366781330473308508]]},{"leaf_elements":[1161939574018876374,8351817840696965648,18372653301453144055,1094858428888221872,17891497325732335182,6378736636084565709,2312548455298580963,11108539684721161071,646629569524013389,4395291750589940087,12400931690617795476,7655909668271100330,16676308543461110775,6945943938750155993,13376778799557250354,2903074057851475984],"proof":[[5616782601955618559,11536326776059504369,7332699799654596753,2141932960124082581]]},{"leaf_elements":[11506617648987991818,868082017674053972,6543021463611153452,11748771781491803820],"proof":[]}]},{"witness_query":{"leaf_elements":[12596829972955302339,16671500226364659020,16109210863711924642,231685570081114009,2871973302107584737,13246413469707634762,4581991815627331838,18406101646854138216,1657387477765713578,4282312305916548055,6732145098309388887,15160988005314955979,2229119677700718667,17958395939168665899,3455410718703688814,11587137109559930066,8157533115295742223,12558054886082375064,1685453369808711401,8370208512420990018,5134231986352481479,12736932244349154536,15082319744903836377,2353015186179822764,4120199353468999255,13938529073085549549,5824567635645402091,14069814796776599021,9602989315243064193,14994288495345573385,490679101764827453,7465530474561965845,3393709577908139484,9213685118098955867,1236705411687643646,4325133727955003859,17786177132795915202,12620604186884243170,10392235248096927209,1412421768860122813,2375121008948104154,473416502949917057,3481848748417542678,5094826841828995561,14975640707326329826,7647023128964057638,13736129695276060279,4899389595428527087,13997084885877636852,15979407657153061423,18010590535140190581,9095472346297785385,637340785719919681,16630000521758602950,5187424562671335684,13417078774506577321,3732156701502745402,5782180184576343292,15848402668329924474,15677177494334798825,13220885395415517353,8849124751052699198,13060249664193396452,10221801307049227613,2348333960962596967,18196875435442273144,16055862383977366990,6495598167520955935,357216081082737330,556673102133707852,5194646098403169554,6081528051913372259,9929838348453031151,1928542866359093726,17548878934457402741,14812598348341169278,659037648361896543,3540276467413637971,3751821149500381604,3044773635901577551,499209592071357859,17396506756840908803,6160259504598013107,4911313423070035517,3683028438351736129,528270711285324855,3847603315393288317,10222128773373756732,15983487532175954683,17226806026630839368,17216543652057558830,15357553027441566627,5718075733498894191,12827464014082979165,16829063016314045048,2206837961160855245,1457802796452221667,7632418006334513513,1418310690318744071,2089285976004413327,15719601707733187589,13530046534375155027,6439282982632705471,9606830152323671448,5287898250085567512,2812197238426727358,10882705403973822747,9179781624786742556,17148095620912582485,15994757753770320277,13650189001645349404,14136392631983997706,15838040552713483084,17009577844621011582,1962159471707731335,11041620791208733630,487355619862042381,10424087789893215234,7192747982264333783,17268786569092513703,2558635854317737304,12273783239468876434,12982803124339714708,1334152146425209416,2887408928405323340,12243467055421259218,7407125889115582531,15345830647460258916,824428719647907055,1445705946519252068,12761607262110388244],"proof":[[6372634430724570471,16319167852450059803,9470582382424916707,1599004558114385481],[9750507024387649610,12377331051037859063,15183643930896287508,2026231204237839924],[3054025127220387995,12625910069853094979,585260870776819998,1872356273132260636],[8577142899957400737,15993072841522416650,5632981808650905015,1145796400914402203],[9202739205085056335,14525428722613671433,11793450779443845861,2215490814539917458],[11256097124088287670,6687584538635438139,17382998429903923551,151794070253260145],[8473097187896131124,13790239132156085461,9167062191308911948,796304586219675798],[14057841581612219460,8566665453779435424,13179851191110558979,354578967719844858],[16889524375593664544,14146093430589149351,5905710709577275152,438609472924966719],[4066920170409194031,9923489932158254356,11401870840366022708,2325876788439815032],[12970486835521510226,1866445652419010628,7151429743658632178,111012358390426024],[9976335644155126785,8334260381949829728,16609245529797172699,808191351321526797],[13357217182822843111,7246194359117680782,3300747307565431259,2805875995488588298]]},"stage_2_query":{"leaf_elements":[3452487738018296579,2754336629459296427,9906221718805467536,6050313045510064794,5914349828631395853,6701319141046571788,15698025931596297958,2946170576040347350,16540197981305990400,6165180304359094164,16339496666124051700,13145904088173352991,1833607644585077130,4205995476466322090],"proof":[[12783323199095535804,9265236897030520509,15818623387153844984,2917420193768740664],[688607711118305943,8277474696342463463,4080550159138208248,2952788392996507573],[9326102404211415077,14430438065977921521,4029328915672934680,3401261503166064495],[17316165009836534302,7646556717630973639,4638262676559281555,2155262732223005720],[3596108100782037604,7096739080268941216,12431069475984282736,2636987151034521201],[15920930992714381553,13332061597719586958,9152541868924565858,318256328833889540],[8462266424751576056,16122111068942091396,16758785559660751737,1927102532249463500],[2141305327523017951,5689047316887693063,7746004233171881556,1269160916759011581],[10457028605763800668,1438307728004663333,3810844997901114277,2555217648133006421],[903786866936549616,297175495366222272,5894494766818701029,3172797234243725788],[11222195966843527041,10029558956373736288,385125420014816848,788548530015826979],[5393399548198960275,4965487180566053164,9823490252370990723,2311833187933397144],[11783375733003255209,4043511936331649179,4043506204996727333,2003392045411938067]]},"quotient_query":{"leaf_elements":[319537684027746327,13573817497685175538,8788364899662154504,5728643399580280044,9617948200819756032,1208118526453767827,13548321968165198002,17232742717752089367,16132345178428368054,18043834147183545898,12921677798344256548,8593813463571781145,6082961586162329219,3868040929662510830,6551460643299749937,9581505846739467684],"proof":[[15947984361353613436,7799842881915562099,1314724396237670679,849570254818477879],[12681201127696304700,5219690975424286224,1980967210004172524,1354679454769858174],[4623725267910391181,11089157567384012480,1155078021248204956,45265798919680628],[17440619473127084987,11058533422895785286,4177147164095186342,2179078454162131838],[160177516244533653,17771645565889858922,10392472388564083300,2282825335347960125],[16541989224995900192,4429152026507170780,8068827076637166383,879996040632340828],[1444534680699764768,17820874898353094375,14592545686074017180,2526406675939933807],[13779551605089688075,4226703146868845464,7036199216398608268,3217954072703787264],[17704471496014940027,1663015042485371160,16862751645129844784,1297130198030950554],[4632270919408138179,18255749408979585775,6731310840825657327,141355123216832609],[18349452246617137205,2023220348133599653,16807574102074814906,3094054051262067783],[11344669591276189236,5448561436747376280,10794809766239163677,2752009775522827299],[10071724685433138712,9277584171601855694,12421698781990076583,3392383529760788958]]},"setup_query":{"leaf_elements":[4173682486678947236,5455814597193750323,4550786671771893587,4185868996074229603,7719909750068340318,2114668571223578831,14426667122249683958,15153953271905459834,5292580676861646818,2119409815341981037,8715117325026755978,12314092509315668666,12209004173550704448,5967804433474472645,10635869642444503069,8909379201345891754,2467437111809916733,7878671497066561818,651227884950261482,12898223492605076258,15016835426004167187,12410281402923105758,17442091695925745394,17320700224961708609,6523272843558419556,12133805075319193274,13039405178013272471,1835951004623906657,14521881906826040835,11743528590867894695,10599279555348921486,10444298407900631693,7820955360572466488,17488421714390281966,9495646587863634597,1288639164796917656,14439282731891058809,14939844327490140389,15298519227072592249,11833917190305803649,1415513884588912457,4156052144261901339,6268902050428624792,399671514829515423,8488233812255084375,18000537472541967138,13858918446899274353,8387914966443158890,7444602189834895019,2472518932187599436,11468281515678831856,9099608773229364551,16368974938751917453,9592364319634536679,5363860914243620747,3251808282528628184,7018675252285035620,3198287106039461785,9171974701529459186,18144150492751742517,11129822846792103371],"proof":[[2651278722177826423,3926328576639872379,15339455547481015385,499403144977396590],[14787423464862826215,9974895430912475494,13940035632467456900,3013597758362370614],[15162096807526239258,18420598055236978120,1681108345318928749,3180929697266217351],[138246202045019549,2823151519828718409,6159289071789051096,715147916976732379],[3795354284403968235,8980617318008171790,7276581579201464876,3084799504577411446],[16664864442551074372,14814781955294693887,10757080176616036812,486732020599540467],[9547387845387706860,351913669535008800,3906453187326950769,2363294166472820985],[4049835162889371559,5844855175553567561,8783767707291408354,885428943444422797],[9994954283381267496,1018031125308182641,9325810436165097422,2886280474456714793],[3030115736555727871,12131726583026586132,17991716452447782242,3063298879899065800],[10199172819188065724,4805418889441920525,7361655050538375997,2555885512702447895],[5944268534244072637,17509291754432751515,4135650977453405129,2907349052238253570],[10215260393543767826,9751391172593344006,13862000312171403022,2102188527394459267]]},"fri_queries":[{"leaf_elements":[7238794074836478352,14511311337077755320,16248492180802102469,15185419279239724407,6841837364644648656,4404946374300170007,2938790689834103860,9013737861704700448,6164836301162554929,8075272827210162020,4119929666968297541,16392640791326008406,3029878491128585259,15012036192292599324,1781985302612398614,3714555100589384543],"proof":[[2030295978488754346,10025080296149599889,1401905798440929440,1313137706506207199],[10794691858392422920,8848165862067003015,7442157161773202678,3320378878984275050],[5402342315065525140,9800971415114813905,14279533086677500569,2506138894515971418],[13928706046945488599,45714233408086782,16003940006613528167,2466359437742257313],[7825209587567679107,4007502258153065533,15276328176020566413,1159652191916493596],[11169072030695569656,15088650786560007381,12118645955042170038,3031161908643893597],[12648340621785871026,9062810613213647782,13236935801282453375,3148362021928228592],[13852531061222225232,14461508082217658630,1147267112765808011,3261791193482669828],[12728736652339829482,3763524200232196691,5497754700624594402,1717602228308441003],[2727149282747321928,10891637232743280698,12913837565521066440,2576402083512426196]]},{"leaf_elements":[1627765665828057056,5999428113434386309,15262544140837151394,13909000515773618134,16219947555815378778,16430353343803806719,1855887307779828190,4884760626107112380,12599554646314835418,5060857157444539303,17775658940482202354,16131084211744507245,12047261769741992815,1089169556488580440,2237191800223124016,12020957201369140314],"proof":[[9966522621592958463,13563022556140669588,9826740781424225306,2548443412261550274],[5725048285989163379,748275041001877339,14640103218007607297,558580091578619906],[5599960259566243556,16955429212207628013,10628523898512240479,2000659074381940465],[10605182707835532844,1637551537758974320,6812559257891564389,1759124912786740053],[11863858781830755159,8505276823327594098,9537695097564425097,1059886170988714660],[8479843093041232804,10838606492268780139,6179794554925052650,2794245564815508948],[3303603528948845539,3326255857540982732,3658681733470339555,1510526829171137553]]},{"leaf_elements":[11576082337549313590,13228082405353895515,15863798642261130949,17429558916456669891,1001171491361697837,15752875340244672943,6947300415524028090,181784997405886942,905709583827479825,11129980706691663854,6276700527186915187,10049599254717119164,3814364704646199530,11948949424984387113,14400040339729393405,5430305118454920465],"proof":[[10238745097063724778,5793831616836089814,14845514571269711795,2094375744645305228],[11399712119321032488,14188219063488204416,12055815732605971814,325940372394151411],[17822320780112967606,11929122230921897343,15027943035283827874,839309485425582314],[2675790080703259223,11672018712848555413,17368983387124538362,719346710673973172]]},{"leaf_elements":[2269900810174600336,5098110879737557033,8299216941866001348,3515417207436792722,12478804426321499801,343038200534073827,15203631289634068494,12313336925559358131,6203791195205671288,13398748586504670354,8935303490405486729,2665264765541986722,17919352332936791133,2982639848891027123,11502625188948097420,16989819816840410281],"proof":[[6212898492623545222,5273054318572493999,18120166942467567840,1600672264499078704]]},{"leaf_elements":[4501127538857023790,3168202938356671861,488429852234980958,10426529919460171421],"proof":[]}]},{"witness_query":{"leaf_elements":[14381549949188186879,10193155844951401512,9655723379203761680,16976535023242735328,13875055781499492794,12847323553585901138,16687809977539799865,3841490557278919429,3810779465796366580,10372164302737588696,5220932687517998097,13945232068933721306,11277364001787535528,2271153148542924605,18162120653047509638,14618855655381628413,10210796762848795398,4702834344521494747,16584811721671904507,707008474703283651,11807533873372775881,13573962829834070440,17554890230195840176,11911093011379253281,3151106625865967137,3326650439957826127,13514054856268565948,10129079431306944992,11159995877267325442,211735165045048551,18021871544209410890,14343485664717430338,16545001484607392762,12441208854881715014,4740329765657422809,12804509945053936846,3824525553447981563,10734072034632651931,4770125807136550176,10528792314132762061,11066053854211919193,6527496227650382288,17482445392465496784,12279899311916648976,18211939810893807919,3392863636335679204,11964072614918127020,6392403219919132012,7718332342330387038,15902304534663678849,11782238271866825384,10952237429237933884,929035843949003907,12889816579674163475,10282861609276724416,12577870252764868445,3353901785620080047,357074745869879256,4726643945591752606,1501259203147572982,9845219898967557060,12795851953952575240,16549759925364521708,5470698355509832189,8246693293380147007,17607523447632067187,1431647171148987259,13389370611618487924,544500294861633119,3304526130525672488,2803360361808038501,12504349592053916360,5844373752630290485,4566885504199861293,5829883430008887650,12664299942132557067,15772836546037133855,7934082747341169936,14626370716720517064,16803767701434399775,1421632007060101460,16480682694028272130,16792881211358891997,2838295988064776680,8940889132544596506,9071107169435627668,7451831745865017378,663755221079021055,13359611507001830087,17795662213096093120,12959311012002819045,6456274021250975002,12846934048532457029,4363723022054500935,9710425623910320819,13801601151257530958,2049923436124559257,4169952061450353345,3157592003186032320,16660019183963394246,7388635604686776777,2771273703552248276,5621064916598900032,7940348850014897008,15247482349140768661,4969830892453949418,1817287922232767004,9715533232310075582,12022788852998364363,14843006412024200699,10592604632543675229,2178227117296581133,13153828658910572420,16581582696369609712,210861994637330525,14310648678914230595,15398483565969595729,17835047448108860672,12562531084643623301,12973766079696554226,14084666770974340282,6642169939327169445,5162327554063618152,3634046647388239226,6527129348106018884,15634909965873588586,13293555746079392366,3864902716646219759,5530398034230591790,4698217507346910179,4772190234349617697],"proof":[[8191926039644333541,10856117558904811164,11764567238340000257,3059077666268440099],[5016594445644284859,14038657875341792777,1086358762803338848,507356437161849416],[7069289585161420934,10872430627220773020,5343589814421729026,3020711012857011561],[1808236142063125182,14599318874436564861,10577699981652803943,473331665937051568],[307141819142728679,17557572397482122467,12124913454663374617,3257191107478146423],[8873044659579955284,4960373046495023101,8728467078346857980,1898742122786968582],[16389540040579962674,15165056468680971570,7528986355461727221,740466474037200071],[7952045121856297291,17886340979100599116,6118863901243946594,2152714863297305989],[5436563905394629291,8798172964229505428,5671721303726380297,3211770541907063453],[4547395613433886871,17844614407603917200,7572268213754788814,2439453082104437567],[11195354486077822150,1773340076233782383,6801418499422737127,3020710183597747319],[9213800472765615388,1158316303019748845,12991514382138391125,2372426829132123741],[3099716925912581483,6678030611343483989,7025197896971857722,2531579221790547378]]},"stage_2_query":{"leaf_elements":[13220081126465883479,3111927064520300706,12771398080711360465,16641503596654852959,9599262233086286006,4726086112676600023,510495385662462640,6137075259225948726,9132262532002929261,18169830966085489292,4509948125022015066,14205228621540280520,8584569077758127605,103701005622310512],"proof":[[14902716200288392695,14914743750952965423,11809026629545925261,2062728992110882395],[14058641519577075386,9939139921330508549,13186015301189589539,67191710391667258],[4206930362691734154,600891255202641224,2290605502279841938,772177091561610536],[16399900890399928347,782650095260578380,4398402109826868252,1759455964687391576],[16322392710294577585,18191915729612727212,818547789920402267,212766563644002183],[10577191461345236031,11295130818479859892,9371342208784556671,407686097700380066],[17432042862359151161,13805395021772422567,5935398521629703754,631630813197488974],[14445198986484222733,2369109347478517334,5356420298173870014,2000717711626599103],[4536133836263873743,3475374968721784400,4665727786500703951,3358889373262285206],[4393380720750496031,9892260491425092153,11798607321218199291,2468660382843453428],[6674516047286965592,14122137952659949972,13339681292169278889,316790666314110925],[11700693259148205928,15528432552127481912,8219018759397253025,2162129865191522389],[10631333340002775728,642120458864718232,18184208447282953832,2499189033817952518]]},"quotient_query":{"leaf_elements":[14646355118241236613,5690684197488744296,2809908011529484883,15591192660718597305,9588648313948299593,9636500257679314064,2781785342717850806,17496916971985913211,12619188976950603214,10940367245406078142,14408578703813574399,3944380693841075669,16560332542822848808,9686125166090595440,6375880545993523646,11056064625134898315],"proof":[[5660707409360475121,4458280268039403711,14634854520193596071,607121459764592043],[14234929897925854785,3832782629350728558,4386575871038845162,2643645519400341741],[5813469262854079804,6761187595074167251,8025271280703837610,331023790783482620],[6025441954297451948,3705988629911024643,4738338078134439494,514790626302006564],[1041920622314614323,13376341182282719619,1429911843859499677,1174080302807327612],[16112993061913637459,992373648383782213,10998935342093082745,1955794778208319197],[6892078933053368198,7062218555586129074,3065975781126196352,1803354906383882836],[5074535434926523258,12302128800702357313,957047598972919286,3387150291288054273],[15105608576691469162,7582664782741032873,2688001121713524055,532676682708521903],[8901442788751184725,8811147888121558392,5748985623447622024,2496817928998160398],[16456053988842746347,17234441536445376580,7200629840384684799,520407338944369231],[548550013870319300,3226183101983914273,6816022094353997718,284317959116476499],[16342986491749802556,17454831203565383762,4680887698253431682,1406959034796530272]]},"setup_query":{"leaf_elements":[18339325825380288325,14649091583613888614,17945167617167105514,7767778177397984260,859610815562664039,13334490125598535502,7798944196544916702,854887337551756616,10939593015511905767,13023171812931960398,1728303730978055868,12720113056835512876,16536869494345251587,3151256020623760939,15433890525893740854,13331136953343543853,11954291683045140896,9721378276060457720,12271827822554019586,4423895106986972800,5527272888236194886,16472764174033741806,3383688827085698960,5526934678696676092,15778369479725053657,9466299689286553173,16722441193796466051,11117740347465559207,6085538624861384136,16832831889952358859,15312857211320138741,2278639640895144699,14637146278210332554,4670397761968376846,18200374242211855712,9889979497800872024,17310221330264587172,8608056197555804870,13050091281646484109,3819543435440830394,10042798615699894519,6240160713167146551,7169894245503090164,1044816726938763813,17231284754790062524,12699588813462518294,2791818177638417756,5398385629077351345,12600676229984306338,11461593727163764452,12091627935605328674,12729533298248737214,1607623611941876789,14045458348684496870,4053881032986297121,11619800431554120693,16144932819387945897,13726323875823458545,1315298686601835793,14690475007680468185,5787451735693692505],"proof":[[9649135528893044152,11467383032054450834,11454028361645706094,1137987272757672808],[7427392430817325173,6578540227692854733,12410111014010292831,1255817079076871235],[5890657849988924735,4952509083759637203,14056292718462660003,371253101970039716],[11891466107400022052,14829011324729850697,14745493326914998020,842036935010852430],[15387986721814969214,1033419912205073998,6753889305669974602,2513803176354754982],[11253105888959457300,13903937167614516483,12991438607152466219,629625716413388434],[14612870492846284677,13946203054779924161,14147893485035460722,2984200543738586952],[12343235972735821285,9600883590299955361,9625473062009585093,2379274131479416832],[10972114921256751233,8651915268712321254,14105558962188748973,551103400239830946],[14446301563054008146,4796151942379991487,8228495201009085898,3416110020178350178],[7327335420128347748,5920222809152371247,9538311201909750707,915684056766971029],[7055319602096595194,11464783531727278740,1759839108333331006,41434432410530885],[3995132822838448454,2846542933920014253,4890579769695319057,2067526069473059889]]},"fri_queries":[{"leaf_elements":[11883361048558082806,3332163272438423170,3362185351916890823,5466514409260069890,4945820118055417929,14712040017413166772,10789673852478105970,11901949970728941506,2134139375320193241,14404442597012762943,6691585485620301759,2076237292639825883,11603284699024817765,2625982428030807648,8315113217065882410,3888979000117625406],"proof":[[2436449185420253053,2249773341521269636,13516104379391526333,2158942191542989310],[11286288414377647527,15478407964746868900,12318876420190214899,523099100410578294],[10339772684303854733,4207732518564887986,16331389658113387176,2139466856375344461],[8143123101416577652,15428961402399641771,2530356544988665639,1140328231242783666],[15768755438958403337,8632874178372512591,8181681773416162473,131516628906679810],[8862253086672634552,12705906320761570539,1900788492676378731,2863398311890240995],[16728459734944576682,15077012272153695308,17483884817304233041,1857910935087836249],[17330372961762560019,7027285076794433421,9546728019518826346,2774832751867528622],[11414814374608261462,10550371136378275745,99222866707934719,222323455718166932],[5372050669665668656,2531004979834820284,237856451516060770,1063357899924609756]]},{"leaf_elements":[490720307014304589,6624206906649539280,1106388778976032958,10679199129808160632,8248870999085964119,12594823978462992083,7755516494441439274,9098237157649777055,17852689273450045870,13799677125293519289,8058976844843042961,3541363584423508658,2467850016688734765,14886402476113162485,16132112267718114242,3012246023479344235],"proof":[[15316680158038785079,4967390707112334814,1332212905164395434,1375558356372960435],[8019068807366144672,13604589403592285442,17705902162692579097,3131883917659530805],[702424870714320722,1136975791117779823,4304063123641762243,902124151813983077],[12575247757524333914,18125035250672512876,11741031209458428718,1672377156391200884],[16427131369228368286,15161192532584863074,13785951322865727728,399724323342211631],[796562504078608021,16881067040971446732,8081660845298381682,2673579681902268455],[5260383682142355478,5611438961528204855,2999527192322743314,2910090006399941672]]},{"leaf_elements":[7770776737455661647,10668582793550647000,14004817581443878450,12984300776721617079,2260577505586345492,11209552085706032812,2572989823441891178,3939458824393215599,8877734796347860149,13724658602748200726,16896726189812717161,13280444247743168162,2228010815988240014,16611530108971585893,990617995558929027,11183745440176679302],"proof":[[13919766588471148106,10929155737272259984,10826354287109213676,3101273228507674622],[4818826844076730291,17180257000244286193,11265047987947866283,1781555415302840352],[16756467014491550361,6016903521124414545,7315589155338106837,3051887955897998784],[13563414973992183299,2116411489152791601,5001532693103286599,17692006655279297]]},{"leaf_elements":[10225814171813459836,12725893102043196075,7295078541196454247,8625410329319773927,4263878865734639923,11251946793173801696,16393238736617361826,2599091078451761432,12396122362530392359,9324346104821663189,3443820156697793777,10276648187268039057,13558877638201331801,4065790490564903520,6065438844186016293,5175052910854462695],"proof":[[4996307187254343803,16943616208787107289,5663018010017451605,555345195086986338]]},{"leaf_elements":[2966080012095824694,10472639831135879261,4652833482319589241,5368590808610327190],"proof":[]}]},{"witness_query":{"leaf_elements":[373174967087648495,13659300758451653818,10284372493792908126,2200737467866879500,616410445478336250,2416101282494944569,13870948998407387167,6839463794059714889,9922012122865523407,3986586197477111381,5032811648574846659,9260426556371952414,2366688641468211243,6564885635071170733,11777717958016533183,2595795055570054295,15178535374216292008,1223890980423665333,1095529113335693913,10549139107284727254,5070258288477535030,11374029683639681021,10128255937029662389,5383886746280421576,14040720227210918597,10472939098119070298,16971080870019052355,7561834683260179469,224792879325862593,17008517832967715372,9187137546058032293,371806203327865857,16776666285480095143,11674588816206851054,1932367053405306937,5042799916641165274,13953734236802373581,2599454267262800479,11100601082152308360,2850582894853991512,10536649264272766832,4550164226990653557,12708644045672203519,14279701800824310613,10327175217393588692,14798268331654352345,8515857710106939011,5299784275998510517,3678807673178713718,10723765451691860820,1698268580654907533,18010647754625059370,13280576408363812718,10193447756461955441,976274693415505415,13285910392556378367,5850119344470503207,11295585300165281659,4085488402474955104,6407425573881207385,8456454598178178817,12574981038512490081,7330021850836187186,10745688827303236320,3296199866975640234,14218178479180240270,15560011198264727090,15740861527337221507,1410534873458533798,13886222928533143915,15971322222127492909,8289718121177491081,12547918188094265368,10579952748188910014,8491704031206269617,10197528650430207662,11190441443014432438,14453205098444789054,6779714026395822648,8691229564158326716,366951805232144798,6459995931877118304,13066628826615284264,7927364443069873471,12171999154742483659,8391065925048169440,16289674458693536317,10260730762471185777,5052541587270220572,3084905065190527365,15765620403246891695,12592828148674918075,3424343884781232397,11868799387096352659,2486757440793567685,988900161062436232,7078824617164729082,4157788783563737429,12350967334759853698,12726998177679614685,18152106435261249795,12706289688536731825,7195877938418340619,5735764589433069002,2680008422648086237,736571427837401073,15227281624371246697,5311216722691916944,2317320206889962094,899081173439286876,7517414042049849762,12311298329683415472,9367571867688373496,14623566120118749656,3801435425406645571,14299201012120319598,12462691118043726930,13372245917262650682,7011559832026614690,12089099125865423486,12265160487456996686,6403453663460513627,3432405148188228479,16574146586994846983,5099981789039713536,13281662179450142069,4950408272251148739,5574360763338351561,5290347222598056935,4999324417964302270,17774448259059188134],"proof":[[7939439793310588787,18257284623447714505,10030872514396614860,2591487327905768878],[15907950066569400388,6680089137406624208,10757193406552804133,1042654264950990249],[17855489706175010766,18306722708490237789,14660714536164201275,634377158321052844],[7378575149168193343,7979855086189560111,1414720902283455909,2906860453415636234],[3774379492819512333,603871900469395866,15933825469077306556,3384051105823408532],[16306555844819829269,12922973042086118644,10135651314181446495,3479197395205057362],[7382443130781134166,16510712477857332404,4612102993811923754,1237225390199030984],[11482577158927091249,13304631925767743061,57457853828034868,711107901257053221],[14056647054029251523,14437732090330533697,607910341046958120,891191003123063577],[10334962000005340327,7867588562198272976,4563449465900852193,2500006382134369556],[4583040498555971616,7747100777154412055,13929384765094672206,2440872387464085566],[2766366385088090494,6769208155111811097,11371689314227132362,340257912735176976],[14529369058256465838,11494318455472272794,12643466557790876047,2895029653840738288]]},"stage_2_query":{"leaf_elements":[189056265712397897,7051642697472351371,40724834087487408,10806715658936233220,2632529184797910783,6534784530409153901,14211372350791343288,594993868570320163,8908566848711448455,3906656511690037094,13990460450936996565,152861975845167685,2064113518920521336,4497532390473058688],"proof":[[3076755899049922340,12417336138333148659,9907852856432780226,1904010737261217141],[17187386867591984753,3256172484260867994,8489957949714861561,1251689945975606827],[12808197030942827501,15696346718722240389,12278300748237705575,2669003769861160015],[7252078012991693842,15401140829952786413,12717057335842397526,1224634455363648995],[14021085593416498190,1710635376079293848,16751964086571443069,823532397508805753],[9322520957689209855,350662710554688898,2023733016047364999,2310492625471190888],[6126172794226188601,9181513353011347776,9142079991131801945,3039265806878655509],[4436865866428310667,1093428978615823097,9282758937453080159,287712519428534501],[2388597560303381171,6714534955024774119,2759869955726321724,436354429904998520],[13770098120105363085,16206939090417846846,11750618175693252153,861829443217162157],[695775844056571704,11948017328804839600,7297840129450458723,1996599486233491892],[9853728952074350056,5243511523582415604,15033444444682052514,2820152547819487473],[1241545135385123701,7679004444393135724,3025994387032875785,1519048666296970932]]},"quotient_query":{"leaf_elements":[12833932361677978990,4703597801185907993,8355849042885723886,3775056041063038750,3812617135617990162,4102516758593686650,17534467837091574422,748391016804990239,606013303743251276,6658352001734381308,10054962238351413092,18169870839350822013,15833374226689271528,9544833669773292420,4492894822051590375,991059100253914133],"proof":[[3028010237697932532,17147379807280249052,711009808626490775,1188546225726134619],[17229963152699473131,9588921317570532592,7858384590644739082,1510247958805926275],[5095906107398624141,16380311407563032697,16055223754575966171,3190685985872536349],[7141317193849907300,1223723303279175666,11977370931952074868,3420266013401402061],[11389976313000851508,6515820102762403829,15605077000580172931,895736780114167387],[7631537702860562475,10059098012069053976,15444215607690564113,222885876336663216],[7608271141265919545,2008039532303045851,12494759256652346687,1253981176739599469],[15906127309870491004,5890435689668103977,9186706466856000696,1254006674690767572],[6858681732627174830,2209024622745984763,14782618090796718938,214637902438741055],[10996578022350522067,10587029183644986899,18306673069540592560,865103154747362680],[2145289966024657905,17033641827413818572,11985851744785195685,760361178709545190],[7042052438198579881,796540043896361985,17830230185162420255,2249494067159037413],[11151149218063228756,8120946621539383472,2153351129223377690,1948019290312331727]]},"setup_query":{"leaf_elements":[15917324601686183034,4526313996582888812,17676778668344307577,10957905340595917610,12446891970149522426,7255775571207605703,12810093446913856833,2786545761412613164,16651405020009654985,7403981091405506272,11683062933164582918,6159525661017931142,12445448208248722661,11831224171338138983,862532978538994885,12535693072406412651,2491924617468386536,10729983916897791589,3984281874185964488,8021077295902614556,14413503692693750727,7377182761923824997,8152162717574899938,13791825760137988259,3001707232602870306,3620201614717075825,14987439221527200739,13675426863741864822,1157079695639124040,4951957102372620716,10559600842800630196,11938957964351891955,17206532739026255950,9582277930242443743,2255288332716593318,14175698995588912101,1535613645749060638,1596770719522306288,17739099025422132535,5567452543092794725,4523256722404973064,13130330204687859869,9232584698457373320,9343612790060933678,15646436440664739256,1826896161681019574,2804805156898948089,15844656734174806356,229436178101831704,5664023466036042636,4439074009231746846,16173074041897434688,8911289168377381826,13727268419527108544,3077916982865268494,1395814920575693988,12321719443964147356,5103293464480044636,2375136451650766928,17763908060762304173,5022718257443028245],"proof":[[15320949261462498112,10216534644205454660,17476688170466737911,2398821118212538034],[14258605962796632353,12934093406999993949,12722850803721263110,676836916741311401],[146029089537668253,3506473798636075328,14900300565208497369,2191048987455027159],[18199310978048064941,15974462568107604262,4163783721475162893,1477319168455547750],[9792070353831569312,5281921138683753456,18437778016031526792,280876615154318102],[12577299466212822317,370195534204339662,8279618526871901413,342813193479863663],[3652897303573439076,715088755169868147,6424809329369259038,53944835992254664],[17105974022780092470,11800496740020589960,1591399409039612783,2001438358512834821],[16885299428557618432,2667379643540441832,6519426898364512001,1385800044510812049],[6773097280187574234,4293151313873275442,4332258679775392364,2839900687804557218],[5948325550731255160,8238701916440581702,53113983211910388,2294278694902979384],[1730616017315666014,1299200534008402240,11162104827292250293,660519070144899916],[13149784555253046835,14758838563795191874,7433057622550658850,986325784856918114]]},"fri_queries":[{"leaf_elements":[2804838000371275513,3262563804827965064,17204178760712423529,2289800165027492005,11324905237147455669,14537386306062521554,7743837251197132621,9238822461556134138,12857766102580847453,9821509229452608795,7613697893945583356,18440083008798426706,12023051621484512151,1978698479998686184,17496943056076022069,13664821744000225994],"proof":[[10159653164669715279,3179102988197026548,12019133758213023098,2874048564765837448],[4131686452138604880,18382626038177416224,6569454443377715580,2676975562744810918],[3662068134984960897,2506274876310912228,1886506458175336841,905736917879301502],[8025889030472053053,16718556166707905552,10244432901798716458,1267296843992018301],[15518651254859695220,10176301966702647032,8025963987044189709,1650691223477459814],[18046678074296270145,14335017984576697242,11260349655594939186,956550786760256481],[6397474756562677744,10408138338120512505,3934376092695086725,2607630317762696347],[845005393906438921,10272686258973704889,3551414226955745471,3452364450445772245],[3905828464536085541,12674349991270608003,7697017796816780652,2943916197389319917],[8347360573839206051,1768446814586231047,14007334252911185829,190786222251169773]]},{"leaf_elements":[14763659853566652910,13891154743546885529,10919272531520915643,372872776985274775,3841007418316894627,16721606615101373010,15043376463893004422,13624563736432542647,16296006322135531323,1805163213581504272,3304612400978373527,16120153630941584629,1476590491358916361,1254128590189787068,17195518893317377535,6817555509331619533],"proof":[[3498012759497414026,16350765172698604173,4950135859827217641,1718446492032066225],[3781610346289643733,17753629649712561665,16029812721593707521,798601228556330354],[17902490637573479561,4331097989599163042,9065308487531684289,1963435070488674037],[9518390246800381456,13430970766535505731,3669146452630375332,874331458603803420],[14956751388932837462,3783719934086287379,10236924018805898626,105995308644831632],[16155455856565919690,5061964990708523169,1902122666115875254,343869268516906328],[9127794537611649855,5814250328747267805,4296556981629366486,2685070511949217859]]},{"leaf_elements":[13359490908652558014,5997640506745633614,4959066642841481585,13275276783934490908,3504783412645379436,332948606864961780,7392812665750659091,7313916796737550898,15454949239181403626,7820093532902416732,4190631103434677293,16374686988061935065,14019460712939982669,14271131282857817901,6172990654719820747,6340860797783558575],"proof":[[12977527118766060820,10117161255319273682,13605220916015228928,3162028651511221268],[5907087738312150412,12887804975834396340,9181568002007361439,3343111879709306985],[248844622435178628,13520985268696963693,11418430057449801682,399408629245820694],[17194299915970532300,415382349675028268,16738602978340998696,3449836998464456936]]},{"leaf_elements":[3789702018995450110,15854387717208756361,1862553614940700864,9514253061725497845,198987545915237403,2445744595491142240,11873260469463328166,2136424363509213897,5107746734140941096,13172010550308694095,2233544282983968511,2369746150205641333,6878826575781853838,4016984314925335006,91665176381536295,15855865455423374290],"proof":[[6449941176220115590,4755010037827490481,11626402507764205885,228837083492347851]]},{"leaf_elements":[11323862628515517922,11439196860937776991,5413344540181736252,8741335607124726181],"proof":[]}]},{"witness_query":{"leaf_elements":[11662769621147878501,16252016139828378581,11144075744923314804,13309895449215924800,12555113327700527594,10569012505150386385,9767671664135784579,1533874144770126257,11573572669985005121,8860098129875244560,1646799104574245503,3954238267405237757,9998980247883258908,13448336628960906315,12384543436165332381,15886219592618844027,17809481141802571674,16208085726168657802,7740055678454743534,981845710994882818,7343451576811393179,10489594854331327428,8627911724200393774,15920557181078130208,12074455257569858751,1643546329328529631,17917947306083424576,13357772735635731863,10604573487495282579,2003331781683712523,11385554162658031271,2781706506245293614,2373050411141570965,9571613678114588411,2698657520370696087,7638017724681508481,11644841688855319901,2858563418279404546,4816096871440300238,9231144414762855564,13276351818044089404,17002143170614867956,2321735181398686614,4440543370953730496,294453993175989885,13454962795498386831,5646876544945022979,2981310393101423210,1874678223214297835,5989763785683046703,4935887243579672479,7634181393191597469,12494066578383135226,11649900068365191689,225056504550797880,2200608107939282962,193348560108460530,9324251976855135049,10581127578195604031,3507161163765102840,7466472453143619807,13034365300146795868,14693158151262486990,3093033252573038581,4295322125066632195,13576685486469582121,4906622711307712836,8115465271353020373,11889822778634773460,1911337429542267518,1166869015544372355,3495144951594287642,4876516306494657129,15554637186373629536,16150484187697614806,4449874824943183301,10329715540430878509,6144554073836861012,18281776219059907389,5331047745294907710,13018896740517838446,6135511304453499922,9777952647670501803,3089982091730304467,16838877069505292948,3318176893571575436,1517749982125546718,13154346821613287339,5824805036774973584,15122326109831701978,7886937160473428528,12058988467944183977,5160501018554266393,4525871905444547136,18040804609943006024,4649760679680836508,9119634413679147835,14306666870960212615,756790013430860353,8758143952192037341,15748194109294058851,2757307344251885330,4230528320407359462,16304000557634933527,15074337250403080859,15630590363569924748,14668675772503493015,11518730877913173300,8170031527958606159,4268204344066955920,8382407662656938943,15825601178289378862,18384719984421351251,8135165002316786670,13301789213353454229,7099727085326822222,11162226844037638707,15014771302271148560,6235310768223782841,3295099990456509230,15602723504292640853,12272312267424820567,6255029205960208453,8446493374815037862,11707080636573273893,1426914390335859585,14381779112644928972,12750955104327406386,6885307191711684912,7075980362226734526,7355190205705546105],"proof":[[17608809344769670958,16820972537613212625,11683744906201766309,1541634239701563144],[1964543658510436758,15176527099243073418,17220963673152078603,2000398676118854904],[9945891713406153578,1625992486037707208,17708895956013186654,532309194701505231],[162156585752633902,1566217094553920952,2566598864872606197,1712649614629444673],[17502330882714524329,1993368179755967773,17396295323898608516,1809367281669583234],[1665374662018336136,2657997185863137129,16242334063284926010,2265720444697535199],[17256958616271272257,14242172399910949318,13986399340172442712,1187508217273968717],[8053430375618995056,12578265997111964741,724999274076528506,1505897422146829145],[3911225018129733379,10813370222067360328,10922401052279397971,2598501529215982800],[17188195007368425481,13825399381117869572,810089413047375861,2841855346059209063],[8800787531756665566,1601626430640983386,18021283412139762015,707454732071377121],[17987329640643634080,15012964337311746710,7351410855661486719,1350274959490068541],[14529369058256465838,11494318455472272794,12643466557790876047,2895029653840738288]]},"stage_2_query":{"leaf_elements":[16375643745257747433,5462321985556623988,4049377798738542873,7736337852010081210,3461157615783743185,4855281819344095391,11029329904275871835,13361742251272359141,10765105029980401446,6483482848456747153,13274451964628898603,16236174797141302120,18602374416578447,6710935517113925545],"proof":[[18075516675364813846,3237227347729210374,1900046615000419404,2465737705023800930],[12541925532033646418,1116286894474099842,16444323740835060046,185639394794280482],[4073890968681936442,2458277283394838561,15794245423755050456,599333257812876392],[11265635174965683839,2628561790443748532,6285455837485553851,2576316993454282719],[17193081254900055457,5215321644978581222,6936483947771777558,2517759135249553524],[17779428161550186288,482536800686888955,8360746325458304249,178549910916250352],[15066066463868692180,11412919472356942717,3661623246848054246,1161510239860456140],[10991714530720185133,2808241878205972507,16264713818688183835,1246863430419381265],[4383982486894115383,14037447518525819866,13591187787526663541,1565950799847022583],[8783670973508486192,11767229508935448637,4340957135599703584,654785558190631285],[14987321959618278568,13284824437122618949,14861976676288104077,731845425489805733],[11220017259697723622,677001679594051167,6925218384805950482,2073318416511068166],[1241545135385123701,7679004444393135724,3025994387032875785,1519048666296970932]]},"quotient_query":{"leaf_elements":[15173479045184989960,2906374230534452561,14685685890009252652,4053353672571475936,6967828793179795768,10147216617849127276,1913270802135794573,5073998214926507344,3756521073357288204,73899414762850493,226884154150826842,6316006949293924448,5835052906707308087,9995473217220737770,4363440976335529386,6152013726251009675],"proof":[[9139556009407840967,10293470984978183430,8855977816091829223,2359480400791448094],[5667876933242299263,6225554531008531649,2414363410948643636,1300065071671314458],[9559307566746199698,18348991681784054853,11844371999384822344,1286515743340055226],[15193542495505475878,12322810787739088613,17760835731923317417,1819976987387125405],[14544918302617219016,9589412894208417700,14938121866820469882,2475064205964823444],[13985525756015267456,6782638751143608393,9886230907329245253,309580069477910465],[17067672697963827338,10847478522102780542,2660225774438924267,1771947251325639653],[14696992882748859678,15358930003109752984,2802781166654888356,2550387557993107909],[3753067391361686890,14631982585359035201,1169785579055582494,398983197141698255],[9688347552198029610,10352161459492948250,12775465388176039219,1735153194551437697],[15897127967116985070,14781255194005157150,17826243340795235202,1235289287843546645],[2032376285152840491,7142132393502982569,1384580021556495755,2616812089124926360],[11151149218063228756,8120946621539383472,2153351129223377690,1948019290312331727]]},"setup_query":{"leaf_elements":[1259548049106495775,11613992120118129648,16715704569835660092,8782374835905395400,12133522815075465907,13782021186931806148,412754275726865900,17564738902098742962,13564783779267505104,13082788598619107096,17257470469296028173,14218633579002341089,1728539229664057788,3809665413933209484,12252083614767404171,16072979851309505341,17243418083020951768,13836686166692033701,10249309366443637306,261198249562660162,5399367894026852544,3725348457324065669,16993069479048395190,15277492104732698990,14976247235606314412,1742340215802650127,9768047101890603326,12538658291947297352,8436413907457532442,3612370810992201820,247728916646816791,13044958742530769697,1160436146294097348,15329972539798624530,7460258371709949829,14334731343764576471,15439324109308147289,11799408476797471129,3211048454722944250,13986855377825126567,14548934939494570313,16203234498321256381,10961184553948774156,2948829916364751408,3016797721551206568,10154517419789812380,18359804226204383930,16824069210618836250,6720575619175006561,2295609321900629388,2963258313726239201,13772267812819156692,4693976566732817329,821605182488899359,8196487905677442293,3239385459566093679,13041987271737187389,17685423661779499056,8214431531359056949,3256194900240135618,13522409968311741693],"proof":[[7155353871719195516,4772423470401925840,10088869667291718858,3397775263414572667],[1659313473795330100,7970221753099987152,16085081569877721625,8140868079994001],[3307753674889418073,7230450982027962551,17483196857099780278,1772723333320116208],[10237961955491739377,2441644982175592028,2787107230704134971,1550556884570755461],[15616185889014951648,2384180577961354051,8771155979817580787,750525578297629815],[5948444382674743686,2122612895908454817,17876094367977363721,1191665547787391886],[10061974321800496840,757930867346344812,15927979315502770189,907645388578204059],[16604194878953957195,5436923274378554155,12678805696993210958,2959084406074951303],[1341461015524338075,10194609277213901041,1089137671253595375,983471957334616996],[1629507222814009481,11583943973113671657,17220869231860288814,1854475850229031880],[3347708738892720858,18207696225896229587,17887413276290714469,480107742079763421],[10710052728847521794,1310188681526079020,6397101549672991908,1637501846289329853],[13149784555253046835,14758838563795191874,7433057622550658850,986325784856918114]]},"fri_queries":[{"leaf_elements":[4731946889646626419,2952560631627790554,5392455857607461929,14769637275832377280,3242554279582456692,9526011524916135972,1387737384400870266,4342748191383337599,18081671550935993518,12513360223671092942,5758412313717019796,3942871686329482629,15714186316015501328,2142456587267949198,5475008966771660217,7910188426734402792],"proof":[[18369590718096506207,11471069559171686097,18148955068242805095,2085953530802179154],[5763203966517087548,3573446473870719466,1126654361351895957,1618340753257971173],[3115875098601718141,1904535008001150045,17957818286830051434,683079903810956148],[8113408311673492777,14198376341309969683,11800955284453897165,3220718322764546336],[973137261131246401,17413545498871735159,7543883047874341718,3085028986478770311],[8623812115423311247,9065756973900211895,2233310166001780215,3163373439836825837],[1522973736789924385,752025736531433356,9767535830920750062,353797685187889862],[15588498712575954061,6054896883917248686,16895245680221302553,2312317291775608406],[4210560855886740970,6088046815714819661,13266640682913832721,1701582425475924178],[8347360573839206051,1768446814586231047,14007334252911185829,190786222251169773]]},{"leaf_elements":[17819266884068099150,17192519616148472893,3418203087063443509,5406853097639833789,16203446853451978370,16886564130241072825,5867790590339057953,13422668413555816198,17456243524121513184,6749077906520459031,3771239999836180100,10243412917169986323,7839170528402192255,4762780396485880244,14650337237879251215,14574319618113460681],"proof":[[6289522833168391751,12246122298626560803,2777935740147704734,1660239169200281878],[9712760132733152752,12476983337670345675,17688424899583460696,2051716245379163832],[3323323306618830433,613905118227761903,9939620785724853320,1792071685482093233],[11620763375071177159,3041581693030435972,11618557265365566486,2760926856464395711],[10293025377758463634,4616899267784383272,11647732056482502672,2017876803202301791],[14157526227560209653,10829391244618508863,11697006768307302778,345724691103367460],[9127794537611649855,5814250328747267805,4296556981629366486,2685070511949217859]]},{"leaf_elements":[17401742431190261443,1726031007182976277,12051965728813925763,3568977673320661942,15469465436461866310,1455657128574250149,18221608088367846267,15515125293582627508,9387483391187800786,16083020204287558544,559343653973481808,1393631344510499459,18364864831375462834,8054575329332131823,9590735090831762133,2936469302252749974],"proof":[[5626797304445397684,7299538692500801600,15247931070089125002,2133379881437494271],[1707411167394437621,2326555226076525966,10404571736012530751,2356544624993836918],[10948678975314608133,3924083284418572810,13364196439838498155,2305767341443876489],[17194299915970532300,415382349675028268,16738602978340998696,3449836998464456936]]},{"leaf_elements":[3789702018995450110,15854387717208756361,1862553614940700864,9514253061725497845,198987545915237403,2445744595491142240,11873260469463328166,2136424363509213897,5107746734140941096,13172010550308694095,2233544282983968511,2369746150205641333,6878826575781853838,4016984314925335006,91665176381536295,15855865455423374290],"proof":[[6449941176220115590,4755010037827490481,11626402507764205885,228837083492347851]]},{"leaf_elements":[11323862628515517922,11439196860937776991,5413344540181736252,8741335607124726181],"proof":[]}]},{"witness_query":{"leaf_elements":[3290268266640130409,3729757689802144689,11992612971343865473,9842296963494825698,1624178844604088271,3444867212868224058,12624052502976786154,16763765957000001438,409366643721301025,3175155346097290941,2335131187350965531,16179916233704122879,14567189020227114643,9821586314841614135,13346248469884244447,14403194258473997066,2864225459328119489,8897039741209903,4263424177170478524,5392948645208762245,11868098909543218959,13632487654844317110,9401658795625634549,13603630367065419394,7449927858959808954,10333777097156296219,2351727437787411165,3040537361063704200,6870448990461826243,16749035909455172056,17994930064122354357,3361424122763803739,3755669354962903328,6840538183569234414,4299962843074181340,303358861392478650,12114063754740192078,4911762579493767623,6484388268661706353,10565828369840102784,2315220379720823256,3644011034648853856,5161682466517552874,12180651724558097683,10698802057005171417,14709828270760729934,9121405704256280756,4620404332380577789,17599077460311212223,17575828879979645490,7506774341423965908,13901115460900506056,2746120078809548586,494929678186585501,9628356014391790387,15647467092771751491,18072020267297436759,10212514840902028606,2339478698998377785,12527397428208101553,2102191937658750328,4196114000860276753,9527804903730645106,2996497458315237097,15760722218676505131,9211189616029240831,17322938432134233747,12964010906994411518,5242616120741524658,10777253367167976197,4253478637928660790,2797327905164151309,15737270150410556291,3495577583902653274,16381075744554846704,7681158565512533117,13771309630203862093,15754288780480507467,6973166385862751078,2958908070498821522,5678166795147683713,7164487758026191692,2778784331132505749,398750670051943973,13393097627713717298,1083357396752129292,14155727006292108300,12387895762799748577,2126405479116114927,12639679737987247210,6731249703315332543,16719079388349889552,14860472810954251327,8267128311038697570,3811070533021901837,14591043972911937168,1997808834024524162,17196192926401591602,833444932560598413,13125943600926613345,12216743617604299920,11580375387359346863,16322451608422539784,16093547873287074104,4230670487872505686,15153407502585483126,15816489668621883155,10464054972915226870,7067616954127974963,16309658993581808488,1378495184303015999,7694467844370233225,13868278741895887040,3011434652890867244,3510883951825271658,2329966553820576418,15292980374037741602,15151125696931236115,17181235944607976637,18320076750631809459,638058374024356056,17776888239364358257,13520807531797313445,16939831975863124350,12419010824180325836,15903567417294629320,4248016367943269297,6037610879560927952,12903404172119908295,649381813957649934,4923872305283333270],"proof":[[919951431921670391,9410704041661442329,5415145125188637502,1440678223753693053],[10028357948036967894,9456470326721546113,17819527794724382074,574734310563975345],[4107220641812862935,4856622926791399767,5641557983288144882,3270246230316372313],[12736350580747143172,1868720629971157211,18083005081053058446,90798595706142670],[2212860053570886286,264715073973267389,11410390054367720599,1983658861781646967],[2697569942006455825,6521939019617662197,3144403436511974787,418305817315552543],[17459890758880841901,16823320731570914771,7437599298876168113,2451420042766410861],[7554465648710501828,15709342963209417198,18049134872679028110,1678268730996254454],[3905562376468690690,7769493917452620007,18353086232893079568,403752567324511919],[6357035576840156483,14231255953092015768,8122839792224942389,3077089340526063617],[14733508325092594762,9571544914722195887,14137749797057421838,647294597318033703],[2766366385088090494,6769208155111811097,11371689314227132362,340257912735176976],[14529369058256465838,11494318455472272794,12643466557790876047,2895029653840738288]]},"stage_2_query":{"leaf_elements":[13112060946361048841,4384472323128365110,9257789564796247633,11957990931589909208,3178386881179661869,16881293434628800821,16592257575148310613,7121267938033456094,10996651798730840379,950713172285310713,14765660112929411107,6393615154846996412,10583802169167458660,15953710040534728018],"proof":[[8417431094029282649,13184630017125684746,9548333399507643826,2065134999996308818],[5148624316787508964,2359967788151290561,3091570007654041184,326184102977257305],[15326262186870505134,10943199394400534188,13750872610319650915,1358337018500448706],[9251833905142407717,5534388045151043058,889083846617341011,773605802576734688],[14110144669440192154,10067112332393787672,15170673641306067666,3313772012094903069],[3319380946446862812,67437023039583685,11709671074537980974,79141161809681423],[5885682120827132797,12876564194453444202,15783180036406345321,1342524390611434595],[15887933638569986816,8972340878618494307,6890020773822989911,1680731643949090259],[6429509995662183910,13792649267867381650,11419091421300276508,2026463455601927265],[15295990751828752856,9979576372885204569,15747974117870290406,2272940730991023683],[11427303536737877639,6801814388610461876,6107641741384984598,766359408787638043],[9853728952074350056,5243511523582415604,15033444444682052514,2820152547819487473],[1241545135385123701,7679004444393135724,3025994387032875785,1519048666296970932]]},"quotient_query":{"leaf_elements":[12848869043522893069,2168301263826677000,14180517967720548473,7863704497044755032,3623371783825134497,10564082835056167404,2332499614704220895,13413199749252845006,14534745408734161911,5713373006836862306,13045406888295603444,12633897021096638406,9864198464877477786,14105915034190811061,13143025597234832944,5593541747552489243],"proof":[[11123681552974312828,6489779590573176151,5398341958608047504,786178383911450171],[10936062425878965413,10021954256223932444,14810750891160541557,2747554630362180626],[9651235330421189105,14367316669981169742,11709015687527217169,1554561329855326204],[15617859851422098327,7798648904280004865,13543711326733651422,2777808938886478287],[2829593685133908652,629329324952979115,6261930970704487062,2197047057991767396],[11199517274415944984,10081505372590939582,9190575294500086012,2853622121548697382],[7221101136046114991,3985404969826191996,3376442643676424994,2593917319071177388],[12488293110982909409,9465912346307039457,4309127809902185864,2171380772595321626],[2018211969464625440,13402918227811376840,1653340640594811206,1653282847052707610],[14106799473717877940,14568989310396713991,3635279110894153538,1012406427262795905],[15969453155653885014,11946820923768701303,7992073692205041515,1642627875497258998],[7042052438198579881,796540043896361985,17830230185162420255,2249494067159037413],[11151149218063228756,8120946621539383472,2153351129223377690,1948019290312331727]]},"setup_query":{"leaf_elements":[2650091020793697547,490757235233621531,18065137848888552107,2050605760118313670,12235821708584180128,16020167902757910960,14326078800183432417,11264086951293770356,206663537644429741,8578344062496317920,17344927259780577140,13546601209204774246,11033680999926137140,4792467305838593765,14973514831122405690,3988750876388003016,3132302445089702095,12391037104011751737,3970378219449214232,112707048754685778,6154339930255857471,1378585170132881815,5746248751118817083,7611560641032391552,12224065063555449946,16875877925842059457,16666435660508838340,9543601212811335006,517374854697631207,11224836665226275708,11370494959753352416,2575471338471454148,7152548302079046402,14719784347599479313,665355455596668839,16601828513892449297,16807162482235772582,16017884168985934264,6303029596204766638,4310087570876428825,3664547949579886879,17430113866241656756,17228857078544680758,5367574580421247127,3213956273844155443,869777182920443050,12035830306514986326,1559802306673437677,7489329858176272486,17244863027541067764,7115567871538337467,372114578395890843,16347975915116648981,9908055502141108384,3527684600131709309,12614611852329252521,7754721977973590179,17746696231547446842,6399870106470545418,14617301567994114920,11587210476323232694],"proof":[[16035189005412187092,9612458373711662662,5444998093421453197,2110198480594227957],[5695115649859179844,13988356303149554077,6822115071054864886,2907741251792029441],[5645901995392171354,9809649567472432237,11552729394204578669,807469989790882148],[6322465649938146520,5009739716624341226,8067115797835509122,2188865375483289905],[9718973949497455738,1250439191390537990,2570697029851249424,1439438967733442169],[13443749801375612798,12126266058337574983,2975375231424623932,1601457124495347566],[1029138483855778756,14936395822772351354,12508623091521215677,2036561545416471243],[12131339629907373438,13969547477225418454,5842399639225755987,2283192174606826756],[17174410910746095676,18183784474275499893,12177577405978900346,470638783381377706],[16118699847006863351,11536016472670397320,18443104935653640703,2356453852553273466],[17969422608252871793,8307312270289755147,4856288380758393470,2999967421241013405],[1730616017315666014,1299200534008402240,11162104827292250293,660519070144899916],[13149784555253046835,14758838563795191874,7433057622550658850,986325784856918114]]},"fri_queries":[{"leaf_elements":[2296141891386478992,3347253110426316739,2667655480150610060,6241988773072955246,11325384592057325261,15810194139170520635,803450512358420663,2071211750740397801,9309655459334620142,7681769166376600244,13826629654162388985,352949910776289974,5162249848242955175,11737404948600473008,5379189841134580530,9965261814919667743],"proof":[[5761622228476153673,5711010778861323717,14905650691776639337,1398482238776722952],[8757640389641768160,7890556216124843820,2533240003819317078,524548785091227257],[16042724435521643541,11129307673185187119,10247572473782192306,3193888642885598373],[11860912580444139817,18358114608040689677,3712012718042041277,1397200993493340499],[14601813494716448894,348149715189166790,3403329039247344836,1354120937282154129],[13433015128533269783,1185357919725861927,11251054840690614895,2529739479307558811],[14913262432553566734,374916928751125720,12584439829311048532,115423574785754451],[13029959466966526362,1951142863526424533,2245644542581373246,1743049093977953263],[3905828464536085541,12674349991270608003,7697017796816780652,2943916197389319917],[8347360573839206051,1768446814586231047,14007334252911185829,190786222251169773]]},{"leaf_elements":[4285498125156914455,5150746476257518427,10589952604708454896,16448485834615660996,10216507169150022023,8790684447618012031,10988627615957915974,9250804704922597666,17905101658611530671,16989473035319708920,7477143298656860270,16085096727546713326,7395066367040768919,4101001145559466477,1803823210012151629,10146016420667607112],"proof":[[6801793229012510147,10560656159170410001,6890005819286424715,3127095587549718553],[879416768156747506,2399197144308850382,10046913631290164540,1692942378713050068],[9192059461583537788,13510492456264856518,17897225275391497617,1928138751739972705],[7213119094963076980,14103233928630453938,11280135587222093722,2046587233910366629],[4009896405096881107,8990172916126270895,799619736269724941,2679326100414503874],[16155455856565919690,5061964990708523169,1902122666115875254,343869268516906328],[9127794537611649855,5814250328747267805,4296556981629366486,2685070511949217859]]},{"leaf_elements":[10729759587231574855,14780151725676541755,13256208936519045571,6038876437146793469,7739035518069284494,81459772340787090,11118035873923874512,16326665708227802180,4989244718931531485,6154792730468802525,18355290569962525423,7191271717128552275,6779553173287613837,5265678406996848988,14549770372862601040,5532128926239816455],"proof":[[10755490913806206335,14702617229410248269,17447581907979504045,2640393026520544213],[458134419148441519,4506509809646281554,3766650108044620443,2953590888960172215],[248844622435178628,13520985268696963693,11418430057449801682,399408629245820694],[17194299915970532300,415382349675028268,16738602978340998696,3449836998464456936]]},{"leaf_elements":[3789702018995450110,15854387717208756361,1862553614940700864,9514253061725497845,198987545915237403,2445744595491142240,11873260469463328166,2136424363509213897,5107746734140941096,13172010550308694095,2233544282983968511,2369746150205641333,6878826575781853838,4016984314925335006,91665176381536295,15855865455423374290],"proof":[[6449941176220115590,4755010037827490481,11626402507764205885,228837083492347851]]},{"leaf_elements":[11323862628515517922,11439196860937776991,5413344540181736252,8741335607124726181],"proof":[]}]},{"witness_query":{"leaf_elements":[16727055588311647803,8885777124717581535,2255833877203884264,851998181994959364,962687561892187979,1490729377706747237,17625323919248213670,4537537267936473840,14568270133498778654,9783495966826905404,11502458377601853698,13991375305724391548,6432930387368914084,15162596646159400832,9304184765517869877,4748149369478786258,99656077840350489,6100195525578120269,15785519784998527697,17494124057745130250,12892319690696874070,692683235134271380,7222807762484991945,5805963958481143392,14675109825724918873,10842158885600269844,89639884414433205,3198441143802915163,15152589648145063399,2335772818549024006,12218495344858540225,15080770735416625653,14045571555679603531,9692861186463696436,10036266372959086386,11132479886659773807,17671454004862309043,13712530360719012404,7962629114730011510,10871477312091561419,14775215238512111014,17212525540469838870,8308749386662454070,13495468645781472693,14709969324370671312,3730483021378021616,17241587236337298309,590188127600373705,5000938772431643810,2272178230878491835,16740680178372313382,6847249934710297274,13007414889698956855,12014182468222183893,3894613936289126055,10871700317992616133,2174020995995771914,4495230304402265362,2210344952677059195,1974799283019301761,8772879743295595680,4249114132290531011,11149513188676276275,16135570632750240840,3211938458120786034,13787643681357272339,3991710975169688582,6248434201434347672,10967104655227615564,4091714937922339062,3402004934685040748,2109278041180993638,14922942811381089654,6817857881531906418,6248345908815302595,6892028202534637651,895355700834740510,13363495860371747508,11481889158753259776,11653359018219333016,10748310986488134950,1017795480450415624,16925049511907945989,18433668230077543485,1422249990499121914,8015837643582815352,6449520623991544543,10322093862927436747,3894391168290567065,13756791991206754190,16597513782211467886,11831226398984247873,5972498206673190066,16973497609192287713,2636240830918024782,18037446361446108517,16526123246784917486,14415670332102175943,5460121563524508533,2233542221222261349,14973281934741045955,5874452296045239633,8236311556636418183,15286314862676527172,16647670871703080728,16531155237194420758,7723643511896835700,11089423295362335419,16533938458376071852,6467320773945761093,16694776618578300471,10763334661655909727,372878587342472201,8222582736403174685,16952439751924560645,12509511674450447040,15422141699645517037,8163182088396305381,2063325874357958270,16372607749499697536,10246051898498548133,13141070850685727121,14794170672745645506,13637259565195035087,10184503791183746072,4956005087879564684,8349844288372481304,14438937179780637275,11427765997242910264,8670633627089359831,3061429912063648746],"proof":[[3594356867434023337,16463089456465042882,10636440843562583766,3407029473386696888],[4508428863530196431,12485183033426120239,5536460759245761099,71172717282304773],[13060973963931763908,11021545078440491434,6691213084525755717,2002242916317768805],[2072617215840183779,5918078728395667743,4975666040266429491,976483385695257770],[15374081832113194312,8622513456562096324,17624804384012159607,520720125059178695],[13995599084704078951,12313571688667141819,12191394641893821599,951339261761751106],[8932282920467107834,17924401991525761973,11230725411861407665,3219814244620665709],[5063971433149267873,345853996087683012,16021289784284998650,1633742181807046209],[1614643615339081958,13801396234458060869,6575795994579754613,2170018061199986248],[15270918330674064724,18424375348583209601,16403049653150833588,2224508713353166866],[13847400891124446113,2789912962675913999,2131806968534017233,3462450050851116088],[8306212057502905801,4513570971440212739,3182621761424601631,2007843718213213775],[14367620299360517077,3486062918649683097,758936314403206639,1603949708714258502]]},"stage_2_query":{"leaf_elements":[9545744022484601149,13435112219577569359,11754579295936931274,10574389036431765886,15927505733043323827,17818349665455463840,1038869716056785010,17719300959269227320,2926736856490736963,12628623516226157242,11877910173116007765,526792659841463135,17381977216168483469,12927537419810112806],"proof":[[615048575946349284,7626427913212106878,14292878835981161699,432003322446502628],[13617363888569188319,13076606295165014733,7234365462721323010,2421036886577204568],[10104228750598363928,6494696787061941002,3367843820976547737,1449722762037310943],[2619293771049440581,13392118472617480911,8747162557694569788,2741729531691243369],[9079131368162469276,16929461265373840334,6382960309651018361,253130714961180943],[9713930753926991774,17909855819251797539,14342845345007743789,2103406583052056875],[9455484183888340250,11898071210162451716,5420203414199277798,2527486755996631737],[17307470612202754099,5196168425885397420,16876091796142941210,2432214646468457873],[16629417302031571627,10368903630772021783,12808385451734518892,669650273061612865],[12955806825047399476,6486150578510343128,852423938643535460,2858942042869040817],[5887659399355191086,7174368684729802907,3922383235137934379,3354869013348000751],[17946811300233807722,10697057011455301775,8841411358577018535,2882676071995806414],[9302781254238343662,6119432163943488281,15090348966859265029,530198869118147718]]},"quotient_query":{"leaf_elements":[2395050991747497738,2896880741533064903,11950081882692507716,8544801290076553862,8573449185790876722,3960470959848588029,13220655747234046839,8573129239013546866,12148133107681702364,307819625906612734,2998132780343833931,1727512416885153411,2188012307714846985,2689149582412502768,2206725076301226400,7588931027844281521],"proof":[[3001113536326048949,13396817529449167758,6759668941849027274,267882443354579060],[13036957262163732909,3563786266166915565,1073131552992950289,2300858735853607012],[6616286888463820073,14653528777432653697,12416253337035629473,1735883901626989156],[5623607936316535389,29321881576417275,16365655758080801409,1573486845095321472],[13791904318007047737,2358822006913908139,6328353631338837320,1691182430573158139],[5536987045546768916,13394992654699036423,16697423416331286753,1776690605828882173],[4769528868582155304,11621424046509725183,158676710039590766,51476995157382899],[13498672912265323130,11761648744948964038,6874092319668859913,2801100184006480070],[4266584729228504188,13676796620947585267,1408597794297276185,2536825408424183519],[6264086271465643011,10371501593482275224,1421036796903795317,2818717546567841802],[11321327010506253185,8618701882431728540,17606487007445284154,2454227746734772045],[13496753780212999111,5601887085332510753,5921920338607442953,2763534670305069476],[8815952717605006386,4526522413909831776,14701097622325747530,3485165681977640036]]},"setup_query":{"leaf_elements":[6819706164058405013,1447371157040887874,970645214626133151,11678251586692280424,14470792011997542087,10823129797455624477,17316335323828824966,16153396521448381493,11915612664644723849,8461597555322235985,15479691121807667690,12484302364988649933,14988416519934105307,18327490112658278299,5273835414865517124,4377050930623496341,11405671733762596320,12397446325418335030,425872738026306764,10483810046149236808,8054263593072350208,4375422271267147824,4984012410229328615,148500384740782647,7475501928723120512,9563638901238021539,18422152589386956929,8117860077611098452,617266107981379075,9786086724664508846,11200152775129351023,2413518570434006089,7662812472787789001,15654894338396035093,15401243461797224793,5455893854972618609,3857117711432591672,15496950600984618687,10920379777963995287,5063418391300757497,2589500200622382252,9592626862442931996,4225255481484951012,9053261508975920573,7165664452170585731,13188796130946023974,976913271290158503,10533423902622631917,6980681463879039187,16671372929212232381,8532141031755405010,13556031612066445941,10441867125043342573,15442965109169513264,9526853102028041601,5297622962140572465,2452666251809793500,13374313830080258745,2716025223122338967,2157308312873616951,9909602381542847043],"proof":[[5240531699275656872,12651767059543770612,5463358957375440904,2800696920367068415],[13254845241936544204,13531013616207556890,4974576891604651932,1931315584092371828],[4660659356559910457,17513348062026793840,14847228048790297423,2920968556080343376],[15974906031089894435,12897415078580260689,5070180540845385424,821127204946248696],[7131029556765141791,15628033066817378563,2796505516794326744,1685383287155249489],[11008802951974949872,1782215689234839078,8238070276347538596,2317577844099736376],[9273570821074938730,15278248500398179155,14195491722997099844,1227496020599686853],[2416479267346555660,2891682180143862519,4883404186418943650,3244217618994557353],[11310416980522924841,3807836777832857816,5284541498733480889,570519396226990130],[6666251362431125665,12923444987057555807,3041116118283722521,2767188635987646333],[9892719404195873544,2546647787023808772,18037364276362727115,2571930886089900315],[18281726552398374921,10687318528114695449,13037667625031883888,3021881666691503501],[15649328145457671106,549776313160692971,9928450923310963291,2751020716435042226]]},"fri_queries":[{"leaf_elements":[14963318130716412617,18194157810678747813,1170754796224454141,1055559313903342270,3113513367715403245,9127440028722460400,12771480948877855458,6394464312163661120,472300103390517289,8448728365632249869,15410906781816529116,4182661422385783366,12511281957430384144,4948376044365766026,12408564701445616866,15320834725581419118],"proof":[[837115637285514563,10860309509382821300,14339541601722897077,106710026229747641],[12821234760650249060,3514150078112301410,7377287175407960520,1816027839392198096],[5514350124154977598,11481979764190736475,12088129941024873047,1585157892215485580],[5534517321540040963,9095246835818473318,7151797477141797740,1686847420796969907],[16058438183573295747,7983279015768726012,927685901913888650,3460860317281683492],[9713959494299763104,8209848556810028597,14242202521271656743,207387609604468579],[17847952552214599827,10632105656150254165,13951437950939180941,3403074921740609222],[13473335106084991378,8087828339387511908,8146161747446899952,2141452261045257246],[3836149467745891357,12700830065944535128,17543171510772478243,2771009779489953517],[18274227798351134084,14614972872318737132,13670777970563782359,2498334094624877115]]},{"leaf_elements":[8129109564979298354,13691808552572857274,3708734668028506733,7610364632242256183,8637187580461754707,936352171048322141,6028292351650983096,13068507919199303713,16897111728319023966,6700543207840724207,634313515027214575,9795992791421588577,18146492081070262302,9501277853093171147,7035145343446357356,11354223098133486699],"proof":[[7775664999379291350,3194168724791863984,9998722069597029031,2356406325681211222],[14542197104825925603,8637982619773489900,13665798981211834410,1249827789045108101],[11578821381284200582,13509323926933035943,756722498972069517,2974031108541776149],[2353461396289754969,2160859219742795876,7317602384919543912,1359513315536123339],[5367047093430431165,17482935022978133436,212560596756536963,2579869642965964445],[17647726135037315420,16939452995086140404,9926656647162993029,1129491512409889290],[3864735070791189707,8330668194952393004,13164775125511877827,177041749183560687]]},{"leaf_elements":[16475566031165809174,15325392876571330065,5268776904905897063,2968931797061382990,7522997360824537960,2946522724450032446,7047532903998201114,13274673540688035438,1261891468646577203,7289177497747361644,14266873858293886894,6346738787113190240,1019142652903352962,10842787559930328969,15438962912716504324,4636421722503434870],"proof":[[17256920270312594807,7784466799730635799,90433486118535057,3105622285119420210],[4564980509096746145,5089962408011563613,6258795974971092925,2663951082052024580],[8146435607594056767,5057348374914061128,4043163455170630552,490242688245896419],[15036230558710107040,11921162934449550531,16484118682594038981,2366781330473308508]]},{"leaf_elements":[1161939574018876374,8351817840696965648,18372653301453144055,1094858428888221872,17891497325732335182,6378736636084565709,2312548455298580963,11108539684721161071,646629569524013389,4395291750589940087,12400931690617795476,7655909668271100330,16676308543461110775,6945943938750155993,13376778799557250354,2903074057851475984],"proof":[[5616782601955618559,11536326776059504369,7332699799654596753,2141932960124082581]]},{"leaf_elements":[11506617648987991818,868082017674053972,6543021463611153452,11748771781491803820],"proof":[]}]},{"witness_query":{"leaf_elements":[2229099440558523296,5599028387192923792,12528013767867986330,9454867799515429819,14053179662292337645,8468289284247358578,14053064746459011198,13596885218054881664,4302754224618566889,16615246116134740387,11867604380987145476,6370928452743637680,17139928190019828343,6332447839131505142,17573498163158455259,5816437587192735358,15565386800524804385,15690698838747800468,8049337067462144177,2350878214339183804,10656231480650795995,12371604883343365987,7920402593150846652,195882072401861211,3078051551092397226,9715293934790306821,6988249542379381963,6393728427514013124,11068407791485386418,11179394744330795710,2592157307538992726,11827578013206731924,15290780260277651335,16913870120676712978,8447619680944881611,12603047931390891222,13612802540274041449,2833104854311663814,17565852631757434604,17567391082052361976,17857070044597984463,9562225065790693060,12274234722834993399,17406384636400746969,4895839714749827099,11391195160328922896,17514927427076910562,12065525194275806381,15257934418666110766,11151142645733104114,13687932484742746686,542294583373678913,9037369123427596877,18138865651406243237,1441708376340006348,16823643477882128986,18091863085516791999,13398191847839922422,8234672346838593335,4032269002879479470,11531819497753308105,17308291322263200074,11975381287151257081,17016126309217673040,13463462634364074959,8533706738699817754,16428563138188510002,16509730320881262903,1919333400491414929,17129252704618452465,7901411774627468464,18201160632306587151,5288251271281180840,12222384580567642720,3130230642244920549,11750664917651664560,16765366070637078708,8565484138859529625,15442646177870704914,8732938528211785974,6958822791763961042,17701006920091905474,12266003879889950578,12233712922090884457,15193124501868533422,13804196065347370845,9348782100298158890,10255533486799051609,14610813152218809264,6110188540120869827,4479683290284293636,14300317538615552123,5249596836279226723,12162819594835094073,17341571568434127585,5130821221897064249,3223811550404288455,13665818978724487526,17888979250741334440,5003883411148382938,14082981528532133116,15060642984774751795,17311068292849204477,11902023456969407113,9239213806391786591,11876507302315698528,1820069880254049948,14098209108635353695,8213595226606878039,1310885905328880843,5021965142939764954,7177918571994605959,3002724015532367739,17103811995119727566,17109309636834805066,16717921778191100510,15178943824012624706,2155039787995365938,12999100655817858,6636965915596414662,8073890514036086262,7382266179747579113,636692693856887170,122045739292013228,3880574922652045981,6846545691661661979,2430308434235888681,3635094737061354569,6587723471552881192,9414602028396473966,14327676718443661193],"proof":[[13684258850822180527,14526792255605920449,506654973189765992,2261424723294486944],[4637441574773281002,5007627163749993099,12617061995728078223,720688027679481362],[9497516528499065718,1626065047477210529,8893976405999213320,2487862883632515462],[10783977913901904777,10782155814575824977,871108419676727997,3471682156817646502],[2991271536915901131,5140424081277286946,18189102815638378909,2672247046009544002],[7532948798595184698,1056752502244893568,8579106303919297443,1418248510599393102],[15191133912178332044,5016400572701103425,9041465841760022860,753724187118719033],[11266133263594673180,9286106902223801873,11759255521839126481,2346389725699213471],[608537996223994807,5052671579903310657,16476589408828569751,687402747179203603],[15996430774802548813,2133700828433115620,2884919011913851640,1118315428087109776],[8999899993863035888,343305868797158242,12119011018425464178,2310739249807087172],[13682456364671077567,18141653164708263783,8712061362180406792,1128828888402053263],[10228429935734291152,15070756974979336511,15218154065077763931,1832421964913171749]]},"stage_2_query":{"leaf_elements":[12704150800171421724,13877790826790432261,2067092263023322304,1235334116650560124,6789911528774554208,4034157740353125377,8475773106488492280,12688367595785292525,13161310632463880519,14415940243476097083,2638880576809400011,341035541184699287,6899373962292879930,5198035963791201512],"proof":[[18192831684611729399,13867264412219210717,11390222167340895822,2449861647434756931],[11946376681202524519,7183570869481233574,17742019245181505865,225643613470579900],[17337016982375278740,10597231002281428200,4655021626255060361,1608121357592754692],[6207632663563155206,12030980170518363163,4771932449889855363,1459723152624468319],[13474974322570416209,4905948380969189472,801062023765188658,1504888603766746386],[3630344676017688819,9171804454745918669,13749916507668014466,1956559127278720833],[4395853796519785331,16661193308597591146,1029864115308283134,1744072709947231398],[6121249696837778378,14211706874408619182,15283914496140466599,230895556086656871],[14667397562891713340,5949438165242150190,571055670287669080,277025780872119269],[14310686493592408760,7877252193894340430,14662553633531673087,1227768448205866575],[17084674663193673154,7445058713372520873,11860933753098295678,2690951818121935294],[2552139015318238056,11872018541665332455,15345673388535962130,3124487018502601172],[2751258051649958256,17916243703110554662,13375786371768332344,179905637827751778]]},"quotient_query":{"leaf_elements":[5443742218778929142,11769539108216591888,16333292963974487538,5431505284954966180,8246876748854645150,12089496086992443842,16207811038799362198,15882290438899137804,15443675497132857955,12132323915894670847,2906880678281240354,13149287043613452753,613211912951791802,13296156636312053048,688520590055780296,7047009880458222836],"proof":[[3564790349841133468,15543145886235582318,651530066432323355,365815337399015543],[14022526613336320502,10911549331247418379,7154579130899125029,1769807072163825134],[6612362835272153977,15237407459162434643,11258933511665566634,213230106950061330],[10614730498970468140,13076099444384271806,9216885329882694310,260103569536987433],[334169507632601421,13583960729214377420,3302698625481617817,2385114966963966223],[5520600920680267865,4952659411451883978,2930429795038001767,3481973428135635416],[13115949991923673926,4956354891266187602,1358188147632039435,1022023654779521115],[1806646683100504388,12897257098438069896,5141439438556010974,2564671654927153936],[7530115382770162086,8451717686147303827,9542342747471222571,1603696559869007060],[13549430107270173735,14120134983373570779,7878001544555622516,2367153215970887517],[7123211934832565815,17307471784896381509,6159679868171803733,1550807928852191849],[17382057367068000542,16683567394761496054,15805197247815474754,1521801008129536395],[12356171133472036182,3715560352098057395,10451102580509047715,2369959934291544747]]},"setup_query":{"leaf_elements":[2594624533467960379,4641626357040249785,1497133257952173325,16146137806707727012,15978847470929350058,4293063154276030389,11822483089296091016,11605387189390468426,14836303839120521782,14637935013332753964,3286866342304579218,5331318952035488591,9857340229671497889,4533273802757379700,16153284483093512993,15434356000403725674,15727044414700703599,15509460513468032538,2974331621641166201,16952059597470781496,2222520211392057795,15328018900362239810,3169195552959339151,13807304766321999210,14565301187367776844,5834316771580205329,15264571079784768599,1947292001982463232,13981255560948026619,16862980427938856943,15676830047584462129,12020794021791485190,13705521956854828868,15366897272050914048,14533620404567511203,8225644400474702554,7044412043713281849,2193310413539772968,15834668342162662335,11893400147285167811,136065206551469308,1223304700655878009,16197353535845494792,5230761323454046638,5935709616553242506,12601139463939824689,12538585652933728339,7199353121286200535,13115114108788528288,15183202466877219847,9556422442286653858,16280617883368874454,8806741020881846335,11231708387544558745,2530596805864888020,4042369788334074830,10083918182560744047,17318994646102402846,16971392291303893976,14310941672203891583,17054954457604585368],"proof":[[2082335425977149106,12715880321228824478,12085272834623743231,2052210019973404383],[4848062440332994,15541983034584185317,18175508480540835636,3333505239829268052],[14214184578308237921,6054811946664339363,17729288403531627446,3395481439419917266],[10248717258504228341,14774403192169369380,17805059732291522210,629744946081303655],[3827349052744210304,8707902530883251455,12141966801112974356,2705132545628895850],[5913807891296121428,14569513303569245065,13209357688715482579,3282618791770370567],[10541178273818890676,12402278313446298620,6976371238361018148,2586514900498702221],[12179101167829783697,15984444736354789595,16808216686878048836,2542221680120283819],[1822526940964511415,191487880581839838,16884663915410887137,2146594898946790688],[2635406729944538580,7755331457626817398,7754307804266263282,1344692952980360206],[2674908234926353729,2961793619724172487,14426098509147974069,3286558288851690954],[9042756460705636839,18032916781835140443,1228589304641969201,1548027548703115227],[7450018982181130668,12654494844657139995,4699273518936840679,2505102648423673327]]},"fri_queries":[{"leaf_elements":[8358770292087276220,12072506531313786616,15690153693377462253,7129488981877264076,3083652953727026661,13120773539638325795,254740853479755942,7681348463467547065,13014802936910975180,1239468639833417220,13255199676302731970,11524605154211442496,18091955305889409788,17289002019571765994,5808451839621107069,534631005756609085],"proof":[[13460570590503112358,8815986423739037168,263100907188347738,942916707763149489],[9835803557577839402,1382864153857785011,17263175121949798317,389527884028907723],[10909796927640832545,2217517612543521129,15262607658104918113,1866558768565333452],[7376595209283214022,4391241015685839185,2259982449666213107,1254278590594456081],[13030253706353216700,6806276856508775907,3569856662363903588,1624221721209958346],[1798431961209076902,3160230471788922418,14425341589799134900,1599068684693535590],[12452104796680320642,14472831131785224453,7292853006546552533,2843420926205829168],[5314582985812671951,9766185085475412827,14076982134540043500,1436849805750538733],[6174463526753878589,3976066256589904306,6450163432787507129,1370516860777537170],[11836481767288568977,12693209842729345382,15494293070777243110,2609142590190361171]]},{"leaf_elements":[7007215700116805428,5279969368182507911,2048842774501115559,12346006495584459784,13470249292052891658,6900149795815965565,5425684501769746316,17964219351346255813,2930134145613216374,16362105551965153479,89482317627130834,17842884081350484439,972780494903355055,10098733397027410219,15692821980359951303,13935022762828644551],"proof":[[11251964397579098066,10371227138099487285,10510223621265601743,1045734344239014426],[6728376102031457562,359174844975121164,17374458229492820958,1628847933369238234],[10729928211847989397,10173948767655005615,16258172153565842451,3479762052107284334],[8740870165560560959,5593280064494976276,12265736355497372972,939376573699421034],[17892194403126607637,4763317137623934129,10795254700014707934,1271274731424425557],[831031810596103902,9375137598181528111,7637100785997718034,1558930276374030508],[18221825548504215278,371654840480040303,14092719419885102622,220673262799455597]]},{"leaf_elements":[14641763798181529091,8126076844639031333,8661734301755818997,7057729015970879362,11980016194258969856,5457715748878456129,14478219503045214238,16557846192866105436,1761210394906854956,12705417128751364805,13670718724902889635,1609189885981388479,99138466569820549,754747665188144542,13024192369134148795,14807572850025120596],"proof":[[2415492757400771339,10646301344596790660,5545060966040996856,2536919382665340165],[1561637246100476018,11391744941233112129,4119212403141337239,2485188293062123723],[10187320849882442284,686534248292088072,17531588228027383996,1542447043464305493],[14060609606501320317,14199662051727725133,14045188731999541466,360178435938369202]]},{"leaf_elements":[5617743489965329866,9656866167906423923,12342513696506161207,18445839140823577509,17173266430686786372,9885785082442603736,9640565192041168087,8859499278609365175,1962944870928990236,3217289664835128148,18150089437950339150,14748222972309771547,6995749073399235010,6830073760022153520,8684292857175602258,18324510307768863292],"proof":[[10423969435245672408,18154964293000735088,16236043164000731250,396436116672654202]]},{"leaf_elements":[18196018707140134098,3942247739030689718,1556687182756891542,8508669979898744338],"proof":[]}]},{"witness_query":{"leaf_elements":[1169026337575508630,4987507860946994006,2127723952804561796,1585199897462967086,1841126887212375171,892377182422924995,13925523524545465651,10890290721025377485,5801924802727251542,10087309554018352644,15938541894270301866,1014352313865297313,2794505435589195383,15658023999394737366,10378412876846257665,4571070847343992592,3555650458257159045,11752984017630309372,17956458180537564599,10518673676084931736,16473102872787882693,4261389477894180276,6509067857775870791,13436310080619496408,13628191688405071308,11281672159171470455,18013661082389571551,17509328606702775413,7040224409307270932,10434807102842063024,11257505639235587327,10193892765312279205,1852275099843258213,14294027861053923704,6451861650270032580,3085916514172345785,14469345815098890982,8086102155934161235,8804671571038385901,665669043975104888,626880905787483167,847140005870278357,4099902001491572091,4143915948116038552,3459298535182383299,7511817535728819390,8140008940169984106,1192442554558465553,3705303530468356893,18402765340447745716,10545488178550551696,16845561561608228373,16000460904668149822,13868548536450599798,8923872966245547246,4878937289792007681,722221452035646534,16460721147693569249,2990371678777141740,6743622358892465349,2714851106110182488,17867099391978751206,18160213373322887102,9180307457271322564,8092544611106342147,8589413621962459352,6159573342128705089,3160280494858633786,4614708472574317336,7148092167236599990,838999958458219208,1662963496186776432,17681757168926692279,5227564903230409309,13023925872766446692,16871942368672742160,17993528876652520222,16254640883690211478,14491142617319755884,10357019270594205092,15642782367715636911,13643032186790697110,6856390979077467197,1729767259339501045,18195317177249491322,1480096290555765426,9829623152180250748,1391041084130954644,8484919565651000915,4771508565717215531,10329358556273461814,11587267280927402892,15115399254796338458,11973589565488733941,6653176208553048934,12645984258715318757,1729883483085074340,17856912462112431733,9947635601314281165,4361283753568661153,8694032429673415392,15631669210227346296,2657196944870361680,10013383896216340308,1199921358468961478,9489324929418285035,13999223085753210560,4360057291421924431,8184867918061100955,10329766713403018221,15955378037993521339,1115690839257671151,8753298090402490554,12517684004593278535,15341791576320997513,17666788305286789737,9491316184383342731,7328167808774097118,11501468491811048521,9751967812658418126,7277877130309748755,5027967143597370880,12043039959982299149,6343813980579207714,7760316852789012072,13126498527392343427,10772329849355881494,2255390744176273353,17467343641506757230,5992088025458107314,8157036708992362868],"proof":[[17275013725500068045,18019570301431860511,17044579292572092128,165421455219536440],[5491755566131233285,305475355365225536,17536581006633279457,606625382194258895],[13833843975319402036,9988298149509942943,9547152424419037388,120014397990707903],[17086523859454728907,5864114823446826314,15231771625217629527,463148411116427877],[8672302756084763029,8488452155587555501,4582060049253250916,1315744841243204818],[18311329867529345859,11289448860343147120,1728928891441651093,3039869820456819022],[3648652725095728298,10255397692911065960,6019293248167040763,2509173491746812850],[15637296729279310238,14275364387277708288,13578754569454781096,830554599302006305],[908434258940919648,10452360125441393215,4422223327960584953,1296523216792680146],[12425054602644502221,888520762613982977,5414234429864770591,928688956887751505],[17326761311744562773,6549825147000992500,15953425104837634195,106363353390309433],[10015729539933530335,16677332769860113337,4544647630350854330,2289016026089552631],[10170411153944345348,15189428256572144992,12959700760463722718,3298790997504217383]]},"stage_2_query":{"leaf_elements":[18194996216189526292,918615050915193549,11065810798045663363,11195591903649934773,16191337279392914273,17443491731692372426,8522645741507280252,1991437507260220254,16241249688547472365,12948342728149401450,12726216140055009267,17841482046568751534,10432501770071474933,10530885338481682305],"proof":[[16767748069929140,14461800122001471689,17099201863411048052,1034853905971290263],[12551991901271164537,15095840834729159790,1030819330237141216,1472479661953211183],[5431727264063432574,1528202202515134635,7677095660147376224,985658783701300025],[1794556268864256573,18429209842690687499,4840010312688578368,309493642247820764],[10414350114419685592,11889998672875817997,13412385749534570958,2560101950190478918],[17616736784289168398,16913523434183242572,9680660457269731739,2585852965220954278],[776625350982990785,11668683199683723098,17907773124713677306,1038266782792444613],[13122535229168005194,6216250053879741190,12746702051245264485,1531863865424987063],[14182750031266697918,16586495595498551604,9569515752955463154,2059316516732528086],[11765963989955960199,13624085261983232663,6728595976407400440,1785257660135406246],[6211500316236092806,6560614962250817412,1897056650320282642,1808284784011234849],[11382531354751073732,12862440399096166043,6001950675235833060,2904395028810313080],[5944104811179779230,4705743378997469566,17252932908060409042,1116220520959491408]]},"quotient_query":{"leaf_elements":[12762700095600847500,12848576580326675030,135775853856974646,9983334645463621414,17132488458599854646,2876611369037183737,4650300367088715915,4862838071337509446,1381134503193073509,8757450727382103480,4293754069911777402,17595445647321586114,962917259249306991,6517129351182573400,2738624904936906656,178781955830432801],"proof":[[908839345071774285,9443650813882846331,11755713115332503531,1099993548939911128],[8230845672307963594,6452926773038304073,1436974555856988972,780887583380151484],[3657537565162425876,13339315410315911931,1064011483027762396,2423209754943560757],[623938157722393000,15986257347523210695,1861547453023935665,1045520882101736462],[1843998699214279257,8618761283590060748,11372950870709919888,2666259889780849437],[3466989944977415123,1815321168808514740,2413000802889900928,584931329987422174],[9248325282569100376,3257088015820337055,447174119495481620,2220516792815543822],[7785831380690014756,3816292646174152492,17049421997009426556,2588028002528659699],[10868704372010053365,7437906797835302058,7748282333925135651,967904334897905274],[1744944210677153606,14898998155686445638,2419429639788087454,478574440382010709],[3037606756596658597,10752406595064792868,12601430933494962451,1486419311172264272],[9907624180812629469,14446971549292473164,16881439250875001044,425190254503246614],[101117472389605186,17621311294920231862,9537129816252271277,264251130147554038]]},"setup_query":{"leaf_elements":[17369721567974553625,17267534216551987602,10040495944760196646,4935893648276814998,10673488011117212857,9365951764687392576,10497308573908575033,6055892912428714675,9995077351912811411,4004856904068035109,11846913854376522658,1861660430450723296,4737031461764680380,1198923326318839747,18374940542804678313,18120331973139722901,3786383584340300485,3665399265073286240,757834689302979046,8539228731720387510,10223661848127423730,14811842156506012646,1902132282449945100,2979300194014470392,7280781717255901111,3094294112539795085,14289267027842718177,5110264900030225434,6345986906625862685,10844815801672640173,1589372942566344261,6414363228119871532,12858535510843861624,8425904342316070840,2701061416932348578,16193337298451809620,11957090030104403793,11034171896405568983,7935866523987595756,1836210915817592011,18360936077136947906,3704644615509040210,5773997913189078379,10287229644638583302,5371731531396007764,3504766614189713980,3472662056978212710,5835690960760483042,8168303601974678981,12052510357919400318,12089562167480767102,12575335122308310793,235573932294616623,13357794991921537132,4068302609527800115,5316786204027201417,11976439892985702808,10851683718860176422,1091212185595294895,9429314775558567627,10037695766342841165],"proof":[[9603759759403760113,9105692358394178241,5591889150685296400,643091004371537422],[4151897306936418851,14167928841262648415,3907946319255112872,1713006988692741528],[15221471355479784443,15544864251399782868,14708925457346996456,3405446618698272235],[12857784121346285613,17199278401141021437,7643345472701893377,1833908035129090794],[13982242722569369253,14956688195675346289,4402535542574300994,1520871274825367651],[16407865486623853539,12430587678243142252,12713884778387550562,2764905515213270847],[17212016974638036994,11598593538226779614,3802286491860133644,2426845490746319248],[5590090052372163044,14626059057808858903,14918510073923188059,91007860874362021],[4331755112024051676,3392406095600032080,14177816833970995972,2821549826318628881],[12492951949980409652,7834856766146413272,2078098890016986603,1764728787865290829],[16173925822333376402,232727229995140793,130917651684296076,54938220172188244],[9379442358549346120,7100708449698755218,8003531104624666850,240405821702236893],[14721891719636996984,2949626462121883205,514398815710631466,2655190417159851675]]},"fri_queries":[{"leaf_elements":[728881734335668136,8509505192621530846,12514721522246943190,9113273814884650445,13752033775781498546,14130132581167113409,12548916631866699412,15817444541757738108,16394701305378940095,12693025312079250803,5773520103159013032,15313207000073303832,11354217187191066186,5953137794810908286,1867260727006224501,8561969703098343812],"proof":[[3061353450971088649,13793572821388361253,9984203067653732816,3426482227634888805],[12887946419334196726,2539101263950432195,12129078546123502761,2949320824227602452],[15342994387088663790,7447646069369132333,3127294104238451619,2713063922256133288],[1640714759562748672,16619608578055483149,12375000428237393328,1497920266607852120],[12078271442484866510,236484162839540825,7518486392288929081,1080700272281047940],[15977886946160032904,2149331720462486344,5905991066040727658,2207870891678361536],[13155543566709587944,13656246068263336094,1155103612438976713,2684446003927580449],[14753855280286232625,5820772626148958181,3100950260116691930,171478781242230670],[7152690124974453139,12833156512135954046,17166947046268682433,2896533487307130005],[5939124624586656117,8797311108778415437,8676485774919245055,1516009211411584182]]},{"leaf_elements":[11865434967500349365,17492241206590753650,1778563656028676133,3883207012714827125,15845953737339694460,15939037051748475979,3117604357070642287,14315512290629329576,6881197166396573450,9433611125279689561,10728494661002581501,17248110070526226191,1691559248627470401,3130380105818715664,9127807085938640088,16564695974562600477],"proof":[[11159373996866711422,10860411575853548297,2983196223082699229,2458340036936089689],[15598842979112164627,18038236874642748572,5400146307688444676,1871368251843164099],[3704591643668945506,13619801262334418106,6892764789645880867,2290215156800120079],[3971020886639112272,1905553982466237734,3646122373655155467,2329293601114980419],[10277448828266001914,4377717650572238827,14215543573906462839,973551455220086087],[1893623453574328340,11613728381160159469,4071645331713565730,1711775210905780789],[4226831722111814395,6655831638141719359,18416793863196828265,2754055803328667659]]},{"leaf_elements":[4214479544341161098,4451634067580902308,8692405550764081331,15306171780998136394,18141630236613899275,14827037713467860712,3948239617453515305,1798395024303827404,11903755507728468015,12888178283194997389,4018485881144587835,3844040313248467481,15070072488943903574,9206633274456304748,3227995667717832832,15806131501373374273],"proof":[[4759371278859000419,6353988611992497364,14128316604403190811,2448905572076335786],[2008656846137273274,8068752598518186562,13669722476974639275,3394977419891630510],[17425176810934334979,9223823599904378368,16399804404978959993,2362328860189916024],[10512165384836540950,12576725843624026847,9749163590345599686,3286629949348704569]]},{"leaf_elements":[13790855340402993368,7414387734080379513,12975407704994933495,11495992525856327121,922490172660792407,2216591724534083829,5681419279857519838,10808937684894799099,15699585052605113537,28254719198542013,12781572970255467545,7196566718999339916,8152988491243675749,16434549783931242612,15461814104182559509,9183595432750050028],"proof":[[14777760533211147947,4160079023517810966,16181012839474086048,2965431587160692161]]},{"leaf_elements":[16775312693976535021,11906390845590027506,16723574221087713398,13884781623836882318],"proof":[]}]},{"witness_query":{"leaf_elements":[15389693519449644376,5038179981953817371,15907097853423636164,16751324993051681396,15478271508498270332,17306584256326941463,18318277445387346010,7367932442394175793,3142928046692311477,13092978013339379175,14400212429644486795,13031356821499690318,16358198319582682608,6221245169094680673,14536061455173452524,14112196263108786836,723938066492557116,8648853517441889982,2335044746788114427,15735300956476951606,5715939653785694711,781473933018127593,13722126679187476730,2666453726375027381,10246239177231638657,11348850456152336526,6537002647474243832,5752184534121595466,7192937768878190018,10564200287720272072,11196929179577233889,16861523040466330187,4391322198474157468,9171823339875578933,276060631324239891,9559300907813668397,131394046199137861,5157372972120886782,17434241450459335548,6830235253451740900,7745287540251481974,15369345480685617681,17145140531241378193,5114620754579389620,15808089704066102341,16305360388818673202,8033095166175104167,8633020805261336509,10696358167701298444,16601816855668492906,1701096796286572955,16782271765626001587,8311210759073165510,15795904134157642778,13290475895664842346,2309043124255681209,5688853084234558588,7947491916304504712,17321400494324392972,7982566789092921177,1731076968457765509,13509524065017321239,5495892168496843502,9697174101306364223,11131341262143139271,14531992503215722177,11778989310761002904,15364079065642013733,17182773298688103310,6678505161286749382,12351634092121961819,1723048222771233145,18083665823771409452,2523527740956203818,11952965225909182774,14981879593731677452,3612185188963499605,18027419996265366607,13635994494512248461,17998119066049610652,2813515234255298223,16851738526771535378,16845358281728626057,12352758141461110186,680496461156963537,3175937746217209243,17657174996074975310,370597322351785634,13785815552668523315,13292739511651939614,7581163024768824815,17496659329751833390,3800447917022059466,7266375703508704352,9452673321578080074,6227268951871613947,15935889864130044226,7596323456547216704,15043683530039980214,4390265124273065137,10896402355758166722,6401361468966064208,10868656421554324509,2166905850225111137,11910640907338973458,13395383310183424786,5943265395257946469,7811929837676463038,7841910522850479612,9842246780986121091,1634244291068244508,14815925187163878564,18353778061760353040,13826804576803871886,13233326517368728111,5961191051580170127,3369247080225375471,7697970522406781153,16743711397995377158,346933986963478582,15996620155404513298,11783429801923311094,298152780080915467,11953269715764907414,15818156759588287714,9765222254701537369,17923096703918503536,16106602878891885861,17631971119865834500,5605688792052543291,6948775488170928834],"proof":[[16815313956508944314,12810785243537008570,14080286575052630635,430553277731294496],[4377692400944796140,15690310718193664211,12212352275288991967,874798388141921367],[4088430374807000313,2696187034616971230,3075859489991975995,3030002764719874144],[10677139061786364968,16330066261165514877,10352865108420015480,2590158989053698245],[14093438057626301882,14434446109274152315,16496309468612893102,176797065068249529],[948910130377503810,12587892698489502425,594556668353043034,179737944280304122],[4372318756114008595,16896787894194169069,4266555605043832733,160589241295209149],[7184236255704090369,2194747309331510485,1814930569548117353,1235791704569145204],[2600580733648450594,10305555176746422498,10605721023963914011,111748766955193454],[13615772645470212926,11933243305290104554,6879373570622515347,986134934225740146],[16138292879750550217,13270977979011614910,2587367775404837619,670282248324348919],[13956835885681269420,13977950138640785752,4863109640880899263,1937558364909967234],[10170411153944345348,15189428256572144992,12959700760463722718,3298790997504217383]]},"stage_2_query":{"leaf_elements":[8319342768497300013,9009569655544518313,18159246955733947425,17085106827848665690,17044863934670755367,5760791453442719485,10804984884533552208,11219209782866079076,8417186567676251454,14587336248457766560,14696195242430391266,11480669389208706277,6107621045875180844,4890701661153407339],"proof":[[9984249576194496441,12716827591095029894,10219617841679876668,2554629563184936105],[8917730207068821412,17665612816923605631,7981455134342567637,2502113744175905364],[18427569311697780574,6025448665159838837,14278162855558087959,2839505287227997282],[7033423866194113767,2765714364280171228,2708147182784367442,3332708604172678926],[12998144279761758797,4393276911749999087,7102059070177827958,2816783812405819474],[481064137907232558,9115359698871173830,10549468096445241005,1732668689371649701],[5914198853886964978,17373576964231163683,3159862900712454952,2176215155380670427],[9470641688670398532,6860966991048584631,3652726533893335419,295745076526821628],[766650290998193620,435203253753385534,8912943950692291243,745672242176573003],[11611572795116234415,14604468692075802986,14859318733760582479,106745124045139078],[13284840367506353666,12609461417301466338,4830301200085682655,3180721742702944775],[1101391570155270103,18030471955809926170,586352199699272119,1793679619803222441],[5944104811179779230,4705743378997469566,17252932908060409042,1116220520959491408]]},"quotient_query":{"leaf_elements":[7140397498690996616,8068240907940179366,2676547185565790665,8757677223673023861,15034305211661724790,3780746626234336669,13218330087600944487,3571152321949812228,16108538445725122269,3745967801525903094,3860141324814398270,1497468757224271526,3439727460577798436,6388711596087254038,6222195853877753602,15477304574525796243],"proof":[[6173874435124293765,8777543018241656185,13774734746482583390,1066371725121225345],[8237429034716952376,15867904007021330629,17031463640951045549,2590030303779929070],[11459734390571271983,9398373960982490511,12084983738823006113,1037962607901502119],[4670750095902494798,4426410686420796398,8984496597318169048,770655950034131117],[9459398821855017831,10948389232646596022,15301630804568539084,3065722554026821505],[9735326468307623475,6100674159043031455,4165108456091422801,1600987482343689547],[7663131570728132961,16957291639537350923,6008847615741221766,2849563414569619701],[970259066917599697,7663587304428967884,1100678013216627024,1595092779356254221],[16299588941941355374,18307713630928378492,5557649199316055006,2832732146580150691],[16240188461710060868,10777950902617923468,16712190997736403001,1740625406950774613],[1269044347733385167,15197569271567601323,4526178305405777126,1235445967747812413],[17805648031392826486,2073215923224479568,7861966061060194600,1640385227104014486],[101117472389605186,17621311294920231862,9537129816252271277,264251130147554038]]},"setup_query":{"leaf_elements":[1162640723363281444,4592745520662151432,2498599055040711827,415854216971341625,7048112655470646577,15107607531550243520,4224515406149178825,10739745523509147209,1512535250306950460,16780411270129909693,7235796680035158237,11755955765310508754,9935066019591909433,13239585532403783511,290452406345326690,723342063003461571,3311564820829892858,13831625587460246822,17048536729306506417,4779892350101168051,17521156717666329051,8457126669851543838,13208899784872714115,10210189112870346337,13919136133263520185,1460367637163248016,2952823270790995579,2647506846602191712,14483172624685387586,8571841207913466867,6692835811644289368,5138926495480453073,1468972428953941543,3759899131759755588,12287268611163626386,7189725174054863624,15137379807156896687,13942957464329716003,13133321160071361306,4439542824194915901,15258526373953598286,11069049539558915267,12488335708976779214,4329715422627646303,15577164528780564803,10208699697469560393,9381282301814411857,15586035546844480654,1136015603035961719,8100359110560109332,9022129957917766881,7050088376695651106,17628887574608695210,10120277210484867365,11161252585457373644,8781486878066227097,4507986019270398347,8107283387910571000,18165992548207838504,12061560110946377270,14236483840164150401],"proof":[[7565255705399558656,11577595045128327700,2194948195394286538,2252990525210986001],[3548709726315262681,7504193735564815110,14169453825974596498,3075373882057494430],[2131420660845517794,11259584243592729532,860890437612164456,1095330656610430290],[10168866921499038932,15508060906977989282,9694274284555413517,1219226193280204575],[2592198125934040696,10505699080905519863,4101482109823267798,1004366793534080279],[2223835944726716335,17530911941502055388,15532520154634970364,2612339682258117794],[13146976590170125616,4161197811289774750,17195914605652385452,3355512514969026183],[6479653370891765442,14232343854245830984,9901817476014369522,2043835118261663289],[11320626287850343435,7094535524195806287,16857801473543370086,2868067167961410584],[16083932235521214651,11052585747024478772,1050563401291637167,553968276334897528],[11511593473130073380,16758027243998119240,11238201813964671026,1610623666683215022],[10516063788198811860,11521768273658753976,375854070151956021,797548007667768901],[14721891719636996984,2949626462121883205,514398815710631466,2655190417159851675]]},"fri_queries":[{"leaf_elements":[5042709027524099547,9310481383413651208,3922421492748094138,1174749119676406014,13869876365501143249,8826826972437309764,6452158360317836023,13203373037177387539,13027968261582857526,17544998200416502926,16828700748895253698,6848045503659705634,14130022509299613572,5184671048283652137,9866009882515647879,11052132038655258721],"proof":[[2701275243639256696,1823111265060954116,6297632914157920387,1859714997478388187],[18064532508635293273,1269228953270673982,13846446419217978932,82472098365337626],[11406249037505794540,1441059730681983529,16396407950675386745,2925641340413512243],[6428124295697452860,5181476497642150635,1278978003685118902,2448924703169315608],[15149028989464701999,5901149603987608977,4772918424412192559,1625993390672497881],[17316770116590607772,1779309067084439660,12390197381842328934,1416071136454322042],[8473607060741978431,13554102641645913642,4940415124608138434,3425705294118668807],[9869303500020419675,16951623351796344107,10732088556418064923,13056656217461683],[4999245903498690337,7298483859315852371,4711531156947246730,2388582959435649154],[5939124624586656117,8797311108778415437,8676485774919245055,1516009211411584182]]},{"leaf_elements":[9263448910946892530,14844082906861295181,14082267717860469530,1696812927716026202,6099303238268940993,1946324577250961275,6277434233064449621,13923821899222712547,2643947075425169737,8338226996300674935,305066571431903970,5709716333269799997,4943591720422156233,12200337090769340468,5136749984555521854,8694804850262022010],"proof":[[8662507392640303615,14474485068128453538,4163329447678421486,749090120601933542],[10977818749876770900,7525885287852817074,9880430841466529112,146411727468888107],[3293845982724922952,4120504461709260765,9150041585877338389,1716262569160059627],[833915068240585543,8741965102193011948,3976710636698482744,2324217604739011653],[18211480017626989338,4709303199120528782,1502152619576634948,2223187906636586282],[2767861238377875692,15785855316693498676,3744809610891684183,1567103551091653836],[4226831722111814395,6655831638141719359,18416793863196828265,2754055803328667659]]},{"leaf_elements":[14958564030690573577,267318822844730965,9192418804759933572,7252966927688988731,15126130058393621059,14052418355406396666,706238706480646779,14350990268658631226,11044230523938883674,13385758136792853808,9612460927501827745,9334673857116548970,4270377957108915122,4059042500322783387,8037842328281328023,2056100270268452079],"proof":[[1736913916491834893,7821440272060090245,12207507031267195590,35802290930883218],[3361149475921811048,2294286482498528797,12030246206304109516,2389100999924704930],[12210735443468912945,4228653015746222779,6294461639017255781,2485205723841483832],[10512165384836540950,12576725843624026847,9749163590345599686,3286629949348704569]]},{"leaf_elements":[13790855340402993368,7414387734080379513,12975407704994933495,11495992525856327121,922490172660792407,2216591724534083829,5681419279857519838,10808937684894799099,15699585052605113537,28254719198542013,12781572970255467545,7196566718999339916,8152988491243675749,16434549783931242612,15461814104182559509,9183595432750050028],"proof":[[14777760533211147947,4160079023517810966,16181012839474086048,2965431587160692161]]},{"leaf_elements":[16775312693976535021,11906390845590027506,16723574221087713398,13884781623836882318],"proof":[]}]},{"witness_query":{"leaf_elements":[18285053511271959385,8899113625371227732,13472232704757115409,8786259087852226723,8529252521234379010,11521945807738869587,2832077901360097128,906773942836410192,3014699498002973399,1274632102119688682,11029301622983254309,13919566558847960089,2775285843076365110,17014056819092946351,17395952878953552956,3383479261983343138,17375845883951787768,7690758129707835769,13545974727330696013,1144924175365519849,9248684486401316158,6989829285263530905,18188276108509698536,11392833371361003504,10142486972034711110,5014301490369627477,5316167608893305,12266041342087042058,7194981849322330450,11278893079245787935,17214678267898700895,11929948704412136406,4969574640426046966,4986018054999345126,7040260231422804160,14027831284176616371,16648537587067046791,11122936552352208156,13927907505297532823,17581223583420082801,12327872525838023974,5851402372931420367,17615679862014265007,18092513238351985940,10466394329417842111,971152230312937620,1871359428107763127,5740382559649406284,120928707852164887,49872184836508642,9310909969358249036,5889288383099172077,11002161001120686855,2554192116619485063,3608023940261673281,17459497921452549056,8926195907093142443,15511313656827483200,17124556835166374976,17916169672020273460,15910746212125016192,2345554533561032490,1861015851966039291,17330932105599787305,11829232933625422177,13310283959928660431,7373220239532486838,15714122868814165556,12392944137540514956,12503204861188825023,12355570451452531897,12050884932332913138,1704583166931217215,16595666690732607909,13531290060407328271,14946758960008456762,2554107385543102261,2148605243160704892,612919517322000736,13210343535760169800,14518265097472531245,7723412107598258451,4419935464658402915,9651541253886428992,7440127151286983328,4770044457279554465,8972575937298108818,15718140915957484076,611327385089372224,4521557633633886420,1456658287694820951,437381106631462503,2440997603916140619,482080487955788230,897686664150812734,10907891405203649229,17116255001702396423,13585073693843319651,8149910953041709687,2200955549122642119,8366121861124446510,12493535009838846063,11088658051358819696,6310489338253194025,8098099547255908754,14557784827661057502,7950474352354580519,4348034686140697351,1960253474569964040,10110727924867478168,6909924217488402272,4748862316594166364,9235053598732591788,7913054401038361659,5375636275901295301,10175114751111697395,10889719452376284079,192701028851152914,18095805234596605757,12628890685896121725,6726966580267924656,17226337672088972748,7937240760642321128,17373392078362935403,9728755937487226129,14292261964050827710,10146496611085718689,12191163293932001775,5385348852328689562,4773012737078316773,15322911942638237808],"proof":[[4545194818960032484,16018144182842015731,18067576870516734760,2419419172432653559],[17673727522841070522,1198031396131145187,4415904375171390292,889273925402813004],[10861055764602997009,276602168743788250,10492615463841122110,3069096869530524174],[3590790677093904080,6209458073962409919,17826056093996804225,2514714038129767757],[15323997407979350882,12670551512264632074,4464036571546599655,3380529046725681531],[1322732891488752738,16841167125921369264,15732780943199899971,3456073242329841387],[5271444214938501175,14901842527422780606,14974657512536343982,3100787563260163241],[12017810422671066459,2173422596165313575,4218828457234441800,3360623074519427448],[3919076186141974043,9061765407691628343,11712299689573710842,2788220902831524556],[7845104032949413984,14227682426487064844,12235787677570897478,340075377670963195],[171331851479781644,8936991567376566139,4554582658362714294,1481229455953702197],[111213802398324409,13414388693591907295,9175218896119912829,2638942766800436560],[16081857253535339839,12369760122243596919,321147843985612881,1421310820854733572]]},"stage_2_query":{"leaf_elements":[12456126383752732971,14931932540637733263,13934278755007793162,11105905833463179979,6193677485870706186,16408135831540989150,7375262000137493205,10991394822219102245,3933737871843023061,13974085921739295357,1540761368483916640,6365144102870467592,9643937924950139937,4014520346124968789],"proof":[[15465998944310311403,12234905213185367249,13805137643441674662,3014227802387064395],[13380332521108137712,2830090874255615832,13996404841464836153,1139930489988401652],[5009640637135915220,6165366948899981337,1818634713443111512,1789999080156465552],[492302721022228370,6819045086253436508,11602196214661782495,2203728223441132784],[11245215951091709276,4051338299489848562,6662749941443455416,3044528590392166051],[7371147733066797928,16041021454021635008,15345221468532215805,1446022579044689707],[9391674918686134553,16603300007402801928,2639423570674964465,2750899057419640066],[17411636790108841105,7508791718293961968,8079631284622667542,2590178211272507977],[5826166708349852873,11921068518626084177,9771075151078444663,389904575025083676],[16392913908751044941,11940657156077815363,12512314471613862433,233229714298843809],[15152880817095458326,4475998106991160465,15008538817701683484,2211487576287516768],[17177506030369921111,12851121567553979669,14107730224997407492,1580369957140359352],[15814695789183998421,56527914284832412,8797409215270913660,2669762635623790074]]},"quotient_query":{"leaf_elements":[16659710327741176514,13161315297670969184,7563016604501506120,2157750161816032433,6269846329087011460,17061854788890392683,5742950381266004672,11420386247947934390,15068424444080904583,481961234042858291,15083429300171344719,3978012608306830565,11611820401516839687,5311393437099180658,7050732425284193844,8296310099707201126],"proof":[[11441277305951961880,15864268422525302161,16497273665756696957,1700916925459866404],[9704093396994246900,16452009709101134929,6844324897364443035,2291420782868355936],[6022867431322267916,3469352390779293647,10857748299217030610,486021625394616],[17086019409186610975,16792497820199162727,13977348804571754943,3295076915492296076],[9441460766693822997,8906264123734800291,10408301393765335882,1275843404009216838],[3138403374739954072,6950033652328438777,1674538102154547198,856400102791239999],[8723803772561630216,13069623965703409915,7136606662114402762,171647176346851060],[17116104540819397107,8295648146828676637,10620501277389384999,1037671099779942170],[16871737324826904096,7853893427292180107,10729084540305534280,784900133877557655],[14582940653611852153,5204292480076757109,5076104760862492616,3321339133646313086],[14956780942580856435,1258560855878731901,2322737509787285841,2918643104563390249],[3483963415091158506,3894653977204847782,12406404646759003454,3094658829410325307],[18356626245744303853,6926726491857343148,2930800252704934760,1845281596278268515]]},"setup_query":{"leaf_elements":[14769550792333716161,5574399603868657248,11076503449992510894,5175950689745668009,11092266209861279911,15325204852205281745,13566357387238080817,11734190158387935861,15283541991386046553,2623171831163979062,9465987268076892546,16437539805572577092,13851757620825366156,5895478397210635400,8207989499911128189,7712816031029260719,1733593166444192239,15361194788148042839,11047592525540996572,8414468202211681075,3668142552614510346,14852753810648054223,7780391147614866754,1572659983320197015,12507005579905743281,13218781168519837910,18062666187274590518,1845160948702411629,14462575549209402604,6933129291745090278,8289505344780094625,13759637786993247341,16540050479359134727,1934050164386170030,13782721757343343358,17331843788736014177,3858554466743041012,12668795621966070967,14129407791504140850,12759906109681788418,9741917269371017565,7592477749626581824,11660955497148632418,14247876799831162487,16573273210685514117,7200009263218199582,10327304688426669199,17020977877326503780,110865720092098537,5807087527279555782,6977972342651660785,6573480994268194800,5191487956396045074,7037679846585973926,5887902457872345706,4502711082162679384,9167243104713429423,11609228784005437548,4161777138272437935,6607575619651619678,3524355707497740864],"proof":[[6308557664116217352,17861180893341047514,11352686499124242891,1922978480911490145],[11966757126297198274,2978184146264363480,6305287016840053905,725401353470118692],[9846775339254548923,17941431912097268017,7609774203261416196,1915414369800656990],[5602786177808854999,15796376611372695084,4735199193393585482,3203576713903796288],[15233240229596077049,10415112759706881386,14296658490626720472,2884724579516275804],[6654559979331305484,11292313271308862858,11595517128811293024,3379789770102871647],[4157024615019345165,1730475715599443243,7601394378035057066,1939293231286493609],[13109370203292663665,9721893962074922039,6368398350388004718,99320754152866081],[469144306697255768,12868324204690112656,10712994981835943633,1739817538384926241],[9814661791264875806,9420661027775581088,13791379520687020298,2372271057587401706],[10000891259386339385,6315007953130685884,6887747776954917417,775327446143990338],[11560595489664821065,14711084012141472140,9667246125152613359,72718795004520500],[4629382627929813659,10434807975241473018,2682618813578145242,1989052126100709949]]},"fri_queries":[{"leaf_elements":[3256415220252545437,4945839825387458022,1955423542425192362,6202974793420086912,11369679411345601321,14074687149061282384,13319981531054582405,7290344013881849129,4799663464267643739,7403391484109178284,7785260732462119537,3681510849991888246,11160740561721017483,6247606613165360793,15529427475402798149,17566910154602952392],"proof":[[8186453186864381886,5277967090589380922,15592800657724045687,1263530238596958939],[15509415087562280047,14759042481001370711,6089564515211755593,1363698311128378544],[6011370238097314682,10129549209241008348,14093930644285260345,2460414698389522955],[4124303585425168245,10744597064301956010,2112509591100677504,2137528403038824509],[828152123813802469,6458350874142000896,10457087731622039757,2226312563487637909],[5356653560643438828,4953445040931655093,5987241981767271384,582093598792548341],[2598533567160923825,1492802831977426443,2426288801517425884,386780708791788308],[12869009608291108887,6090290039398388224,5738066062384596457,1725441883651360552],[12491559816505698310,7859756576441109701,14895406505862962053,2931918777804915151],[15662626367922126968,17810244674751992628,11036241030129481650,1434089276239568845]]},{"leaf_elements":[7170165347071463598,11255748720080484808,4417659934435779812,5342728612302938412,4709107758481528403,11316166300506137474,18369567551990336353,573034973715148845,10370506011363367167,8903396280576519996,452309889948293977,8486569851258600500,7544923888464688228,6375047594197815438,4032251777532425045,2632368442816034615],"proof":[[14466566885704289311,7695595986587992938,7066725076051479893,2170429434375369892],[9452123755641402114,18330302655730356258,8966399234399298825,3451454856793802954],[15747922773337540197,6133401866917676944,2594466990523678042,2262664933711852949],[17751198850040091301,15883223324839576293,15144880822275581688,1004106752842303932],[16434240657069264735,11480357466363264813,14267234548891798770,1349536451464086332],[6694393482400992803,9377296027434232341,218594664158465201,2649907960693375389],[772002559898402491,17472642335343753501,5484690018317829634,627070858078387906]]},{"leaf_elements":[5830814031683715740,11058006329376318108,15601867257491024710,10353541744365965061,12885204819861551667,7041622066613008195,10442332493100454569,3383173754296491177,4715300644367887996,14000610411267695084,9416722056787379029,4566244133653094266,8750067520076775321,15371970698808037611,3576073655089744817,12540127057735692909],"proof":[[5110993140968900735,6427708914314604314,13172507593245240792,700461219376529580],[17960074102599957202,17446519498755199449,15192701518082843601,1511720647798143606],[217518400021473653,12326198898289941254,14373323732582149021,2685234189206933142],[14851984780092764014,1641047040120452539,8824922906790340682,3018535465669299193]]},{"leaf_elements":[15944738748606314490,2274005129597262509,6673033953838553594,4782849776554528839,16471427245309607619,3638544443347737602,16900485101718499277,7270002477188713541,1980029502034887834,1890826269618363501,15614164942184560760,16775737583699511213,1065694939228935166,5741681071371454950,9624583362685852590,5349665761988333245],"proof":[[10109734138832900614,1881041950409089259,801683665027458401,2204090125200326105]]},{"leaf_elements":[16580212810250977730,4470259858681618858,8395368088134860335,16307579962635236903],"proof":[]}]},{"witness_query":{"leaf_elements":[754919493255086205,12234023685219458422,15716988583399700125,9006841294566379092,7914760063113307602,2710404969530438554,15948723591742023430,11659165017523734028,11609071972550513424,10631679121797715874,12752431700214084985,5380937585939915293,1274396051084903090,6887950391908866318,13141498454422602670,3964258627181511599,2013595262527320348,12296559350675263291,4884862525164364801,737160325609211220,7257491981772644159,6272339402133305749,10436705654551836118,8314686781763962484,12108406654250118287,8254092316841782838,11710730866342111794,15480150568446627177,3548127155906299902,15949861591528348825,15063357883683433013,6415538434661787088,12189745394568000463,6637354052153649213,554235778905703647,16334923898491665613,4210598310087059709,2283467678346928435,15711678134752987415,10251290042636422461,5127747951726264492,1010411601901351685,14397776918968477649,9689416365045331228,1115637301750779018,9644214310749359689,2945076539296657957,6358510985504363288,14047828287758321387,16576283616839484351,15039779134189183442,14035639468601333733,7528886817007284614,15719297793772651285,11141544336805696474,12908074477179076044,16629102456160772837,8325718467050267930,7482450122176696698,9371293365942750825,9261167856932631487,6117978138350302239,11560201825643677413,9708158507187536216,345454416207303646,1816704019551648645,11722899190542355199,4233180291329957117,11195856489838731264,17705756588893490298,4025157761792032479,15114196628301671328,742075925174222076,3088369445203080909,8057031837471257928,2294157626986129535,11337240497406894938,6625775493426246189,11935958364042299317,8889128719008984856,16714156767582609865,130999170320094348,15693424447856982158,5891894328896545809,11037091520556801321,16783907784629853692,11335235868702986318,9600590918033882035,13206184788011039127,12260388182892337194,11197528786637723675,6915870647051477320,14802471060003280105,16576339105954646005,6063547395989860171,7531244252636899009,9581431996350181961,1158844458689096364,7833936018747409415,4146532837782195402,2143714889053266594,9072461752032740738,1106186338336955193,3645841992314195373,13350150742552407857,12662899913259863772,1832434460231531388,455526029235042164,8206182343727700030,12500251501058266839,6602931977638241950,9195331787033785478,6620532194349434675,5230010598708088822,15678909394205170490,2685329671479864491,16771999563035732274,11421663017048107045,16383496463914971543,3749897823098198140,12330104352353902568,2137607211179317769,6959953843916438442,8333382709835147768,10344385821949361154,12646737224971436334,7064327894008005220,9802363089541290316,5250363268852222356,304759637390510588,3654535748769123946],"proof":[[317142348160289016,1324237038755427617,12100082125585335319,3123969935288133790],[6528450905127571931,5971753421129561976,11185407083873634271,1369606705831917744],[795149306766645642,5337737688442245405,1004896738250550014,2447869337511257834],[16227186892495953403,17831634087557202985,7629642805444967705,1427904619613164012],[1474975304120584127,3022388325012117321,16849904732804259632,2536708966002750612],[7389877177593625674,13535927894080781763,9574200566159366336,1793999437095924001],[10752675588640799157,15886291600302463343,3678353935295667852,830757622554969253],[13754561355578214136,17692355723038456360,1736012239996295585,707290612348435347],[10980722691717351269,12538310560877522297,16234345069654583782,3295665373968407846],[5837602687100984571,13429690771302381074,927020594147584474,236605526730557920],[17913038790405574005,10177357468544894484,3301713929534404571,1509235318751622695],[5701050097312196064,273438735955107815,7289492473781115995,3001665390633644975],[14775659456443440031,1334530784622447516,8943612273700071220,1338759925121470796]]},"stage_2_query":{"leaf_elements":[14722993641797590989,9109072555268198135,10670314648830363461,5126444431124156438,14739380825037381773,15603126247285393632,18410075301267829703,13572898763899169891,9808554580776955292,4250556555690445822,1272977324418318934,3719958038825111153,4021703620016909118,2306636125935999137],"proof":[[14641116498067947048,3706311975619702253,11906262376107193772,3199941626126890180],[16607607753336569723,8760425010525964679,15846048861883163776,2895858045749789731],[1323421297610886713,7922068008294919120,13829345323837847689,2612808458356977490],[11678197455193774447,16531571142551276295,15309088400379328421,1184132901830725058],[16607809763987916936,2648222886869265980,3635431408131925804,3196032703118660731],[1555468928396472356,12073836111138240666,2264964211221734370,33727667994549184],[6716365167605028138,8664012501038403379,8261305223096906903,1860746776032624807],[11861020858468119228,13710933697935398554,13644947086255980842,22377997356858442],[3667346511889476418,2227489015848729995,1330865474389686279,1706716202527532896],[2072938743275050790,3460679110004826103,13859472331060847547,8276138121591401],[10145952693747646114,6112296965654229148,13911759721086195599,1542386033742297921],[2725961486644828773,968069703755735106,7014016895630597352,683643425655615046],[722241383568005332,6601780098421013494,13826961905102470983,2693007883546258981]]},"quotient_query":{"leaf_elements":[4227307210064112882,10188799809507735517,7453537231362694982,4742658086252222055,4500283331611737913,14317685033498478182,15569994025160749226,14752724888051965415,17308945209031701948,700303118454962113,7522774543654381079,918039709903913134,15954122933701544756,4350281208541118446,183457438910852708,4384678014136229154],"proof":[[17382445911519522773,696063503233140070,14266594430021695761,1987078731674900160],[14891669783146845849,11913736840207086903,17480270058778355236,1019551860685005142],[2352309959712477492,16513685286730674637,1930603567167485945,703077707244142249],[2543449264938403856,14392439296031783754,12535242977838058487,3429980353986767781],[8945079781198349755,9593015413518134992,152920102073477748,121196797364348955],[3368878920660225487,5998832516799214567,8649096574953888779,730051772567895792],[8510768180329299664,15778084791246256455,16815800186318605440,3155141682982140000],[4244929789546412949,8569946678501330065,6861163701731918063,573382273245878173],[1592634251946293001,3128665798749974776,4225545971203131686,2491753016984952884],[10796038800260870445,5957659388134020477,1270364402490344805,933354253913656990],[7320899235031288258,11485996040079662385,17597161178753405142,1067958829391331490],[9377098579159531335,17383909838798620218,5046970499680863756,3147010032550180727],[1250231735564029257,6809488777860586483,16089573894631543223,1945123631152919569]]},"setup_query":{"leaf_elements":[17985870515262358068,13382605850812713548,17109862639714798593,11091986500882412799,11880803435877553352,3768674775575388563,5213022509877037219,14771003218804260574,482578934567097562,8045801925722063544,17808105528326629566,4651904450138035686,8574221982259184942,17663451756837257774,13235607429097105862,3358295649063505067,5107383459946104009,9275707203467156660,12019955987906117425,5272901834521781813,8825420797831902939,5612802467651211828,12040023348251467130,17913448954615566060,13417549562898967320,16636060763700192701,784309968799418585,5001817261388239592,17378002081028276652,14758882828078070198,13605185931231755795,220011295913010610,8126120021526178859,18104090113286572074,16482351588137244008,16569564865182188776,13759926479894489674,16487580291223187585,13029838669854969465,5608984357468048186,17209374823975047323,689635878042294513,8266111254969147281,13840240761984304838,6676878786300463706,11310942476836380767,4369880589358713993,678014046627069641,8689777830416178352,9766404305049056255,7437654091991038906,5000323364276125084,303689712825259410,15686865947916885890,2238930477488311929,2956862206499423120,6845067650745145537,13565161564006698569,3964275749228621241,14838264383777311064,13636442081932929169],"proof":[[10310678646593613749,11608130909215224350,1842742023438342050,237818831285243983],[8009111888362995701,9723486787583184859,10261312142465241257,377984671271581312],[11924272493004018829,10061038396567189982,7706874090382999453,1998225328256785669],[1044714443606071467,4704032695045361697,1171156724565575906,924812534814850386],[9422651131963983061,9825280909767209642,9215515424789707278,1748874508600133940],[6603473792307875470,4222292778721377923,5395313167877918866,3226090315303367313],[7745873969116529995,11075213376546954037,17232291617143745095,3162334720615815424],[2879843640904956973,17339450855360728313,11763511034126620993,556927832043025724],[13577982093975527486,7929423011323269681,5797389575294079929,277351754554159579],[12053220473658978083,5377078530977605166,15115312667311114020,1360742259381589597],[15724344926544827072,7205417153972985516,4103881744555125089,1983290272126016585],[12518122685287142733,11101254042761690968,14573798326644535090,975518879293916629],[15470229706085811907,7922041834933855234,11466811437363182481,2761232339665304973]]},"fri_queries":[{"leaf_elements":[8097701943298489777,4469728239494817459,3210187552377776093,7132204273500896824,9946314909011470146,777855117184929819,2716099566610865084,18145138356965793071,14363773599475067448,17623488877200885108,6376556932738986854,13567401422246703338,9772033385172847678,17600582748060824574,14537980390636575912,9762216152585136793],"proof":[[11195891691397337388,8912773983791095944,5418605055696798650,266959641801791381],[11876608566120390402,13051977886598697247,15512199855016567569,2065913349043408747],[13066126696968787009,8681654487111881060,15028541257634660335,2427408249195209855],[4773089585373021615,6665731031628446385,8404824690658294187,707355995931083374],[10843767298881406096,9396171846494975431,16916887690744189130,415316402552028167],[13336447377309319846,14056552267549774599,9465864758008056237,3042652013440657375],[3773242069149274183,6797230317725244676,11852124273502386866,1050270621269837990],[11273582588326222567,9643444904067045425,12026071760980995910,1408924762213611125],[9971292649392864193,4677233979982873832,598129504946710962,263866205805198541],[18408097362159705766,3674782100163908896,6095738724540536383,2657308411350263184]]},{"leaf_elements":[12620209446181293669,16684097581246255543,14649530475773442343,17706708556845156445,1631170561166017202,10084245182575171871,17130179196094253593,6422075058881021274,4634691467467259365,16799394347447928116,14186792608252669845,9526843445045693728,8480980480397007858,1657847699711417720,17247255323997814792,7873061108596258169],"proof":[[8772063207839031948,15895253541206370511,11565466240392724646,1108535223230235000],[16313643990632800598,15766609047609219978,6979572879620355963,1636242517062759881],[7638620601323045623,5472619007504419368,14373284271546265932,429900821778458637],[7186127257909200015,1855120968712657171,9840177584071132914,906692480968313932],[17334156120150723288,4872930205276815022,16488189971437182006,1774196915951916456],[2836906763646278657,7057041665296351436,181644496866568053,129880401674371852],[4124618749469596092,5995537212191202230,18146879114555701726,1988346917016170719]]},{"leaf_elements":[9821242699192908719,8739857788097027336,16369633756523386499,11723530553154735349,10822407557224043081,8631371694248781430,8108135957522995034,11584973831641421332,9590476904321155943,17854335305852254970,6872850731262886464,8620625463396573285,16420106502521753294,12980374864699010408,17001651783280476661,14989637261764431126],"proof":[[5831313298898439456,5727633718348958119,5048595085608714303,3071472458779202592],[9328106451891214100,4781040186577153649,13841419071719016551,2416374854734447447],[3733279068869424779,11973263620855343548,6909992130978527075,1157920713234646116],[16420592705030288902,16154897142436087555,515784517192506590,386633383944296666]]},{"leaf_elements":[1091038529729091373,360244423195320730,14115534382564426400,5174093879692909629,17426673258368455123,5846560390879105960,6541402252381006594,11727795843090891153,10761005366554087980,11100066226836967325,18386556587157236886,9486653089691708086,18107301933890814410,1640832420586185348,4493954068875173273,9069457263268401249],"proof":[[9753454383334036633,10719921044426572154,11066443179285133377,840081113900875566]]},{"leaf_elements":[2512589913085626850,6670100345702245078,3875769945896076457,15189048974320662278],"proof":[]}]},{"witness_query":{"leaf_elements":[15444408682172657126,5683927542119395900,5091380638379402538,16345010063129180084,30859577296278176,10520880138456430412,10809311339994261603,17067628310371565162,13596653481580028928,12325037505158562697,9454268034177218332,14835374034636862381,7058530480418290480,2755236656035847749,12981176266538168773,6955744117609926217,14442884722953344902,7216295280311770763,14262409948640840499,5014052195551313897,17984687723553347321,5162588451443308448,9366091348612712766,9768891683737839174,13755024443863379891,4190851780594180966,2242863810624155687,3194884955548512976,14241282556182681340,8518256068553135154,14359856631361259742,13131567991839459469,1104104370567451532,2600407768624055992,10620056306882111878,16282781411260918782,18093711550606879797,10436240470766844623,10953807511539337180,14525934105368449652,9684945124870702378,10446578753294214062,16211785102825446806,3273598288134905210,18441501555051775509,2514572493117372829,543651137570778993,6972247398541294869,3349426680996603945,13792166454046090642,1659222680461908998,8780270922686612266,6977152963795574060,4261504763156317195,12036331351594213655,13175501818473115098,7110766174399648566,9330325595592981798,11384964352198150886,559396721094212625,5820869745383896591,16566046377010352977,7235993572185613026,16353333329610073264,3346668391993831880,9535838197603450539,2864422836531851986,12923082347655866791,5165548276530467729,6626449983443041419,12901456621443127767,16131928312659314136,9210427268183651339,10468666315321843020,5412565342199705458,6286703223811234348,16855559156710255837,641317507723784242,2429637282623200534,832788729635088780,775956281701068955,17526090864423741216,17856282446201986743,2533433705268543298,14573972027880526552,13117271832163323658,3853841612707904056,15736919977005748504,5092053380137384781,6274877416319931049,3341481834008678040,12073193812867218616,7358381829799492419,16458330951079113249,13012386254609014542,10053084537948913470,7123985646481534597,15373561040186770867,14201448111221157480,12358085105847360467,7110221259529004171,4044758826641746171,9190123952264615651,1591729050716628939,884940670954986396,11222363035221370039,4485634370621723169,3727897326058763083,11400554960830291932,12862855018039964927,2029431748998726978,7862283054552523981,10244699852157445484,13589463304580484957,9688626557378548404,16995877680639524303,10829756178464362785,8408757789776096806,72540294375932686,11101013327758806313,9014818913390714405,8639219083427723714,15669007346275225751,8133665875422074972,469234312584433707,8918823403344798487,6903259219346261910,8967488393615769234,1174853914784641606,12118345197073392,187472377333142084],"proof":[[560728842147192375,5846619407816065412,12775132585188670671,1410286602009980276],[12011904147032912308,16726263604043289350,7790080609366335246,2981765893243885615],[9602815213130112275,13373185653839736698,15770275792663162816,2465881617080807543],[12621123239441318420,17779110098285276480,14214821443265637218,899495483381895168],[15191486042958166928,4826097750720543315,12172093601546423288,910836090916890063],[14717559776427443777,9563482331781820553,11216143943670677439,451014664693699634],[7808261178805780861,9533317070162912157,6833100909364876371,3202908631105133413],[7275758856104489056,14587545246575390727,149463074815000055,2713389791701357394],[15443905923599074434,8929221619226221064,757634271911946905,1283568413665156037],[2046832725505672161,2358684602138294949,13058707605501244175,401024975988640210],[3124939890686202473,12434127287446414414,11391448563620529306,1872047008976416915],[11087426802181800923,15884898200158356806,1332726411791772390,2686199046994254784],[16780060758106606046,11958032741938148456,7312416229524187577,2063252650720473744]]},"stage_2_query":{"leaf_elements":[10831518742304226834,13174412712563926089,9920173323829569491,2917393089683798699,12511641640460039534,5224693884568025094,4756710800523322635,8527130704123697246,9275687116671269745,4881668025255872738,17693946649138567569,2696496737215223385,14255296927930386917,12126052038546001160],"proof":[[7319918293579420821,12191387891308310304,12532884566891997269,1321975765385929692],[14075814368418102292,2147809782427954356,6297236053863291943,2415477494718771817],[14377369336142667047,1826465765241253562,16235065598022015894,418375656300551345],[15050177285591485998,5710739480190074776,10971726049503431508,64633226631785650],[1798426193381111534,2837701589107704060,9605282719789679575,1373339388407647273],[6143688732123860576,1775215968191252075,9476513882467432978,3095832039663167308],[1412273420901130913,2945803650001525197,10991269116505334068,2434256254602377620],[4185977759424396906,2947270174233376525,9013152852095916349,2728869038501183445],[5827475906301776013,13245517701039921136,18222995501430134263,1577402939232764952],[6657463957781491597,10043056613982186506,5963611177171263693,337795743954390865],[6737172209953658147,16489058110007905380,1814303185256252838,2627815580957802054],[1600324096323697199,12298561271247772534,10262459070123938112,297497425543426121],[5354075957868852375,7926439690175627247,8585448747203103732,3454314098108174446]]},"quotient_query":{"leaf_elements":[6142265257202292680,15344140290857802776,2171339316071123315,16776255270219878480,501840159762669181,11424102271396485213,10655936668471758953,1568033538743760588,5382029415488370400,589386544708047106,7876099134821497523,13359828945456282077,9311174933918288491,2463754135552589751,12190692676580044595,7555705505896772051],"proof":[[11868946669630576242,8196011561193116599,15483742981110011453,2448186691650232392],[6642220636272751936,17317209010436177868,1987436726792106941,1563147890437554561],[11985420910509254666,7018647897519571129,8136291632395577267,1617710134403568665],[9784145807668764660,5521406445616224159,3979710646193867153,972596627175227555],[8225717698944281555,12067763569359892252,16650953473361133083,1726161937957560410],[10299777249375226749,7443365998738581846,9227735166569042056,3233339471354055885],[8664735868673762034,9412071431298457768,5128229658173831498,2397798344144025692],[10664685373798623850,13934048161899331668,7122953462594316004,2941862402619926640],[11441523591043033852,15813054028029977406,1956451772581751959,3320668700430887458],[10408148633400208648,11066693619713380781,10421869165366412783,124677900597386261],[9606512609427358054,10116069330568017601,7184536970639145121,3035878958718098165],[15954198373034633801,7895793786093438672,17040091218657199541,1472989558763709756],[9894783286081270076,8285846266767218443,7388875983260854164,3412182721263324036]]},"setup_query":{"leaf_elements":[16327529021383194982,7387021667992148535,6753600835399153810,3447794729926317663,16313335348105297977,10793816816519001710,9773093457938274289,3136580958259669747,12759164205970254109,7943873605554156646,9689955440194454049,7253308997513548025,10243551351470711062,15598778919032633031,14800420496148707174,5723667365745891441,14713494663561806976,8483309483289137912,8157535170336773473,10093765180065472040,5485397628542176509,1642329032539787283,27490577293184700,10395309054047252594,5917810997400640968,12773270022550614031,4390593179053840924,3654324279710716818,9519860087433519888,10039063642659724427,14281392026313962569,11128326602615586259,10281327038687705854,6456050451016195022,2874221887496087814,5272089195460135599,9939268385454213257,16548514070891667372,14732621179182315906,16828609378199442915,15447604357650913112,1216670093956894056,7938150082473645314,1219105006006880106,486197351577963324,1873118477946938998,17854667741843004421,499368159686110613,11737015822213890515,11595834003402770513,2936262800300673690,14390754673570163445,1185368291613264460,278624320602707374,13179954561654948210,2327618912824526524,3771061775110741320,8026964112670319342,9505213234009089915,11222809446496113749,14732562525269189556],"proof":[[2909355663152452600,9264516788801231550,14925533180725514526,2540794832040745400],[10150415276273939132,17849762274667119457,6204140293692611656,952901808194715831],[8681613358560457341,8906061679646456222,15710017722917605694,113751255132455062],[1347507384320339374,4662440040825466992,65537871293319429,2661700251892074243],[2917697573141094750,2672935004568741347,612155821310451510,478675869113920759],[16443679545099366896,17825935747443282547,3018605035779927845,1864526379906400847],[9244503151688907065,17142477759611146675,15481552948703002214,3403481909426386344],[10600458727831800635,8756158293337280345,5764238403990333398,2146140760205598387],[8393336726537465239,12990876132353555902,7239584864702480113,1787525439503693593],[14633369029286090213,6328171313852274177,1087291408152086768,3039328353628171596],[18220701056869606660,15899836938551514381,7294504702082007332,955695727653342264],[14772192792860455257,11118246339688119280,1965080097173840031,3349448022561578366],[8257498406240408542,15294783180318616062,15553598136149729540,2708965552677615445]]},"fri_queries":[{"leaf_elements":[13768498799938267401,15949591329177899529,2507293313614694586,5691887163811737069,7831892065570277534,7126373400485389554,929791550465030687,15287417644048224308,13971680310485293758,5348340367963362122,14413018089242379305,1448654360060196579,2272460773915978916,7062137964884726006,11453183414716575436,2352778810360585735],"proof":[[8741146529264613905,245639521816998606,6310138659924101528,229347416608565296],[1846177746220464732,13302725520937002868,10195450418291149264,2666663153613666381],[1870021855622296337,1301109678419702935,14745413611201121644,692364317773567994],[13411381582757668686,18362991217089462665,16575853108498908842,134007692259961799],[5371777708049279965,1232212087550978369,4753762104179296644,826407760210708444],[4049016070203224085,1562000625389513022,15851804015622904588,1602055886512330384],[17508543071736168641,12997509917611112420,15543826025943926197,2982069125373312895],[14342858853982456673,2454284253859467645,1609444251919599664,2674607079117991908],[8513214180609609037,13297284929573666992,6797607627951630926,1890464891137065182],[11555457030939037269,9085544040749111966,6591791325541549161,3213063993889265843]]},{"leaf_elements":[782580950601800432,8731566722117124649,17256945082928865583,18268549951257773332,704395739154726717,16074589918754864937,13485243282222503095,6829444202563601016,7452540614746898661,6396234548649509034,18176973338587471334,18174613586207417270,9634125321186228914,10262812594433134486,12515194265299415818,17260054753459241310],"proof":[[14754263447094258357,1739296025503366472,1362946511892519503,369957764981861815],[8708326874552774323,4110909247164409381,15114095375723028534,462742196856514131],[3845462801667136012,11540547707851508867,1002295649916845110,2620581685593055541],[3640910838938706379,1726243147529827367,5314084324712296205,625325497089886439],[9233446734907637133,621373823029314559,6809106629803315095,144460338219984191],[10668781434632063102,851620707839899462,924228320636093084,3049764870018326485],[4849490650414052880,49293529635015172,7888700325494612796,960799201708683278]]},{"leaf_elements":[12600873372199617279,8018817920862935128,5989851613131404427,17829343548776004528,4361811864843572115,1532231990668811414,6775679949662442184,14123084783668195725,13306635866242099436,1529064264939582818,5181615967428092847,4053341919515954389,12976890871890558409,12674967878189764793,15849729856698120978,8998685836632860789],"proof":[[2319283885128689190,7899539408342446851,5347800424197699738,2277047217891017295],[9475135118679978168,9646238608317144652,12018813147330942716,257252859296930888],[16293225978637085163,8792781559710197860,5437602222559494734,1152586688213575212],[18214637273193897569,17083110335864207315,2458916006554433768,3322903078046680236]]},{"leaf_elements":[15049793618273264278,17443600347219547516,1587449845484096471,9268301052953521075,15310044983624285302,3137536321055870732,17729664650163897904,7295871734567114690,948242394662532442,4174441826096490128,5717830596626736236,18234818179955594845,6559695840222737178,6570323834431778590,27890742420152916,6071881210060785784],"proof":[[1207514275877165031,36803928778764813,11527218039117858712,1899368366190537423]]},{"leaf_elements":[15915622550061201680,4536541224237163888,16120598048347926193,2661082248244309055],"proof":[]}]},{"witness_query":{"leaf_elements":[13573926274329169636,16447937140389869447,16906770811814160638,7483846466093302665,1654307374628008869,3599728973408095032,1689324998707772762,18056556135149972447,3668470002758051442,18089376005334747828,13254396114510277418,1511273915989945268,12392280884634562127,13856873503261401980,16144387012123049193,11313520670670405517,6534762527932152254,13800523426642226551,11930147153524463146,6169969496991866459,15206009618644216642,11582635134066624369,983558124694926521,4834495863920021327,16586523925949933130,7568209875977706505,2603127605488242573,15924377755864889018,1971597791675651807,9358495056818349996,14444130655506547959,10423329148528986327,12253168514679696638,8546845751181534769,10739859388965985128,8767549164311617107,15267364503426211566,13554142011361912752,2323282287352621634,12797037912725740110,14647014068023016225,16984652374164637421,12659940160322554330,8598979907377911990,3033683347960672137,6983060923417948585,706428785789105102,13829640821576173828,533641521544444064,7367811022049895759,564359037790249799,4952308654721818282,12445717263565279184,15177707142880786465,5738843545015917998,9581043192435262165,8292392669120666255,9043193193449444829,13968980872683020699,10173955815796283716,8047790367400548894,130889683292660894,410795479103803026,17253858844575794012,7888601892782810365,3190920537445039092,6963320703796864370,2474499506510994645,17040705217611307531,8065968892346987420,1479393972250480373,2461371613223516264,16470579785507021127,17533095064565271146,16464544923752137397,1541192714891040045,3193046576030707366,6982869147420294692,791327452518761363,12489889227502330112,7558016944426104153,3909712333295904526,2521924170286883696,12720952058321159182,1677848525907468278,10987393806061031422,6483337861759587828,8362523594626742587,14442174812221586397,10169665997791635419,4775477377305165101,17408222631451442380,12583653279517335942,16185031920536966310,9304901384595335225,298019067005627901,9416380633781691879,10880174964467886617,6648088250822017785,4740000699232454469,5839964607762902046,2451871210363340674,15359193100020258184,5663956367476153960,3391853522181709329,6888653063973208480,17190622511483831167,15219681065484350699,1652492529210112221,3834735607893009704,7988283875992506266,293760286692761729,30991073764060676,6625572261288673784,6899097344351826396,5892492439170807292,10656128526731739161,3543842950180038674,12156080846284538508,15254277194383540590,3512478725841323181,627519550896506534,11208222878687702398,11664152843970155705,18280295085294780281,13875625186582521298,11212447134708280867,18178618695677376172,4014977246002710759,1163644197113204053,3473465057149977372],"proof":[[8195866761334405402,7728372729072821601,3203751470282494769,1713003425286928051],[1788552761458782415,16365084169267858874,8814962866010254970,1265441661366488798],[17796779423316340734,13717082509527291087,4615811500797924079,842167044763381169],[15189877766753331688,15675287669799442243,2272584295007911255,1096513526603540312],[16791991325418267575,9434432791716417891,8947423195653042193,2980623406097039556],[3698874797996352281,13361606006148530351,3029962078050856214,188885932216324222],[17542998964969773477,11974819610041153163,3580999219989853324,3397037770406900356],[15074369188124768591,16050113884122261271,17141918555408804738,1972956317314318789],[9253888556754583470,15857669941876511384,474221133400533990,1453295689275094202],[2680342756764926429,3301173422649283477,9201932570514535782,1198991468438980690],[6493858094424311351,17964455185899766013,7361557769315166314,3145896826223756895],[2892709706934527733,17838480464587819444,10155705260521547536,2387506384667558531],[16174210416781440038,11224782680825625613,13584339858344595283,2293598389344857220]]},"stage_2_query":{"leaf_elements":[3698789395107801574,18156645777068534767,3797000822437501254,10793184958739941936,5065515680938867111,14107921703245122170,11325279744384819201,5294498267615926801,3352056432256083619,4268225721643006151,4418417108678997733,1747926308950623107,852805002467900917,287599025908201184],"proof":[[3126939268237288446,18444825007849734083,14669248931160134543,2723675502794845322],[11122835716992982567,13733821968971134714,4401251739460273675,2148127659495414480],[5643066818113935815,5112484605913643120,7677013224890721622,386619249410639407],[183692118871327194,5096916689331143740,16569497041668889129,271197856665780886],[16727014193281031813,3462563350130875566,6712924829384375750,1036082845355132757],[7272945444342064992,14037532907983213274,9260461531230676645,276640785065723121],[10119300732678814557,508131832248777820,9441039898168212936,2903110521621687319],[13315027455763864561,4001877763867478743,14684363449045463757,1434174929807102384],[10908167086652021337,8521065222749899132,4649363111779218893,150452410519185938],[4083363817390795534,8255507467522616370,7452300364725971151,1138822611051974478],[77691030423604040,8072883092021044577,11555075588162523475,2536731254804190307],[4099148929035402499,7673469686607061609,4505982977117334820,1485991602633362902],[7143706776069384250,15680275494194306607,14480354172152921765,2190139242083446267]]},"quotient_query":{"leaf_elements":[17260146473267161076,594339968080220049,3362803834938595464,3008650127817020815,5940898137903317025,11423573842575118155,1828256022320166639,14884360272799065335,10048296163600901712,12714985130679712040,12232245645474582705,15343360891347520167,15559651396788929001,7328419875186485066,9440781357719491306,17065990574366717350],"proof":[[15915541095443232779,6968442395726144872,4436397688681640814,2545738607106590741],[6029762474481928853,6660862838773258110,8935626722171893316,2155799527453844049],[14038455994775546008,2169888678164796769,10691814199877438068,3176973335428827565],[1365795191568466087,5291005305041738949,17270513814900819478,1828679948938265458],[2794132281487070537,11274864811403065757,11823889288350221551,2053684673420112851],[2446717869999654635,14913830052699120798,17360932943857523709,1213904405086627965],[1733502861413377019,14682833694761597055,8120704337776217963,2756387265964889464],[14307274736762744822,40134624108231816,14896167052185422012,392119272921055413],[10992070097371331120,10130487000761737745,8285803226814060059,1785276815956649122],[1097438903780754667,10250654518577101769,17719630571456478530,3123628085225008027],[513525338842350831,18260814354677563574,7310823943426295669,1311276556965140485],[9864148082391051930,18335226582304505341,8569801661974152939,2353801358142108048],[893769981673929871,3319556979175080647,7336913751317520875,2767808378512761087]]},"setup_query":{"leaf_elements":[11955716259841807692,5458147274133332500,13391632687015978207,1459713454881241157,6653841953671106242,10654946187403945664,13712318535624304530,17596068547800635914,15652604058783451833,3052457281372262253,17548262517763852985,8925225700514477808,10212468529619613197,2222155028654491534,13419636586527692751,15115968661564018480,8888642419643725248,276038193820028751,17707108708616030010,9116628066519009508,6284990807102053694,8442984849872109405,8786908644516838374,8841010973441503873,13965661075028130963,17484693987669742395,15302743291698212478,8824811339733022850,14523253112061523097,385119465004941064,8298852564217222317,3297747938793275646,17556794901025145409,14308093962457881875,7835494096636320067,9737322297257089367,1055925251947592345,1726998778914403841,5206425122588731588,134120898524610806,17295706462657118676,11441132054344217238,10487159464543597552,17026606281508594575,3106614464098578320,2464498795746284674,2305227823328432733,8022040250319176500,7478604320017319804,12388669042404837091,17276341762394374776,2640537743695782039,10021875038456907754,11486437549121864799,812926336959583565,7769816106339226653,4311182884546487218,14768963469809994607,7185972592317175078,3510271780982459568,7933664325331000423],"proof":[[15670240029668090395,8039584857555600299,4728387626407362433,2367055995456904553],[1410747611610333184,299368952263284469,11816028735552764718,1591600849974941625],[9955706858889896995,14534653371241873399,5573442511258423263,1520351854252918434],[17816336316176233165,4067647231400392955,3441246708343252340,3343698165986905315],[8239213155008983010,10878354554557215373,13281558417253075238,2655581731852521854],[9521285215636636385,382156712047272383,4704876148128151510,1084850007823243437],[18101147605642313558,12226026572563009144,7102649771760711452,556133476996434640],[1979526677510731811,2239338364261171673,11023247746465977756,592559397604982003],[8402145307336955156,8432608770869496252,14149237832006571451,316782118593362826],[8490136823157943241,10604122552062700989,2739662839645950240,1787213058684882487],[12021066607121965183,17861714534690723597,17296885748557096089,678963565057594802],[2209330244228393786,9841280879286562939,270696346365318705,11851569992788159],[12671376312025887274,17441343524713900297,10896011836861176681,2912297064607346901]]},"fri_queries":[{"leaf_elements":[8680266430840318687,15986306992002827088,3770879806478745994,10217015498601167963,6174943947767986896,17708432880210176899,10982539545400700759,16426225062349235530,3376848141478064719,16626110048955568632,4686710402240995734,11404809761518882195,729606986302839937,2517109665314586078,14962519960698691716,4005058085626367811],"proof":[[10110209148329487850,8067366408867900929,6288925598461493187,3158965601402029667],[4117597226072012858,1953455720956516868,6880414443352081601,2344145758106164077],[8377582083033960,16623913343915098489,16715392942475687693,2849195289308966639],[11752736631829508043,3624692409698735531,5389516507817522714,1902741855422451145],[6235014279802804201,17394430777918922522,5828782138821766912,2093627814931141885],[2822223559590069457,3247796785777046875,699336004311959938,2840058512128887037],[10679243869796351109,12043877745852464489,4109226623373864475,821273371395817532],[1872015595740997226,5739662186684146487,10454611751381357817,956517089745787042],[380973593249884925,8211361821003589829,847491229067143454,1569444070397871644],[16109863426784669012,15963846919760798386,9142194185212147107,2313643416305218987]]},{"leaf_elements":[15144107183277435152,5640096783634423662,14117343765696421910,2975724546282612539,11108518461309872718,6651574134435047357,9365087020172177266,17183255145248782959,16163053465742960642,3575081739878502732,1036661985199587601,3152463415753461009,8240199620420068232,15707346772573516946,16193621971557987104,4979180132624307775],"proof":[[4199415938204970929,10795572623327694592,10162663399542825246,1194423476235972406],[1763951514572754447,4963844676355894481,9548953586253179184,2750504433176231626],[7662492606912409419,13492583264118111871,14525845040437336036,1944866242665829379],[8289084913569954648,18036125490095870208,10107981285806608967,530527060839988065],[4938699479983424968,15113520228776542053,16149793309100718980,3145315196322342997],[17680882297911546997,1285525161416870700,9603686181424221186,2725273453195948649],[10344127557781956199,7906363140092405288,5982125655274322770,1672165157955432393]]},{"leaf_elements":[16293573619085866155,377941440823283910,160252430989852924,8760662639310320557,6053951938879568984,7916346170455991806,11714838629808742125,17481164413978137439,14480253569859628575,844343935620458124,6755245284194395982,5161040012839104262,15368329810896416967,7114436241732862531,2122551020211500383,14270247501092108989],"proof":[[9991673916571847555,12151362763527062452,18425071221778742165,3148791936914914032],[16132083267436180541,12995889290913544250,13657280925826151036,936283808435384592],[11161226704473065150,3322189911423566603,13118161592899224271,687763930591193762],[4274407429085135596,548774181466706774,8603117836559137571,160198004595477839]]},{"leaf_elements":[14694649177522924455,8970524565615133352,6698130501351274130,5407467138564220850,6709057259898075644,15065386984471511193,8847484406550740690,3130960100291456344,3694217830831795275,7041401053929351398,879613210345154478,14654620960715256415,11095625651784495053,10579595773725487118,8663536013231766845,10383856026212629571],"proof":[[16046369096493514353,11215590715117997524,7658673164007518840,655039943382377449]]},{"leaf_elements":[6485988802393016559,12130974100501667025,3138003141619716888,4081174251100168420],"proof":[]}]}],"pow_challenge":0,"_marker":null}} \ No newline at end of file diff --git a/crates/zkevm_test_harness/test_proofs/aux_layer/wrapper_proof_1.proof b/crates/zkevm_test_harness/test_proofs/aux_layer/wrapper_proof_1.proof new file mode 100644 index 0000000000000000000000000000000000000000..b6092b52ed64f815e0b9826ffd0e56a64af39db4 GIT binary patch literal 1624 zcmZ{jdpHwn9LKlJ?HqTqp%LRTIz}SZImtDbhP0@$q`7vX)p6OTTyhIZEw>yy$R=at zt})e^OGZVx^ti-w+d*Tw73Sm|{yEQczJI*mKYpL*^SsaReO>_IN4B=Mw(CcL+sBv$ z_`|JEgxxbKdB-%_lFFF;J;CzGp>oT6JR3;f5s}yKF?N&@LTsAk!PJ;R0bGURGX#OIB?bAPO^7{0E ziq;8=TXANvh128%`7oEeGe)-{;5Q^<|B~KqkkNps3UJ?31PS%=^gxki%Tq-!nkej# z*Zn@3p+b^fr<36oFSYE)Hb7GsqNCtY1o^%|Yp6YLDY>rW0HZd`f;hGBtqz5GYIW{r_$T3_?qsbX$1G(t+1S+2 z?JJr+OC?R%=>wFtTJ2yQZwi_0)A=J^sRSn&Zed-thos=hAK3yeINT zA1U>jC||k*B6@C2uuvqCZ%2B1^UCL7gj5V;p7TT*PM_m&QTc$^&ZfWg_I~j1Mj~Yn zPyDs((Q#~J-~&o-Ks=p^i7z+!bOy3XhzHY+$np3dr6mMxf27nCmcql48PD18fK{5B zx!&RFZu!t$rL`AHisExS9+37VwaBpQ)1G^a9h6?G9jUEHRaJt?KEtUl z6}6MqQ}_+;P>o}fG&{0Gd#lOK*!4P#nL7;1FtkX6IvV*Ky|RYegRT&l3554V`=(o&a?hi*AA%Z)*J$0vBtf~AUre81 zrrGf_Mqi-zym)F5~B+ASds$H7^Z}+xCmKN|0J>7f*dM|DjoY%!K2u~16HbBwCb2VLAW%)R4N@8OP$v4t+4#-TS` zpfNgNHTc*36$IwI#=u$$-jyb5GO58xi37+JsNiL>*j4V&v| zY3qWk-MPs!svS;u%TJD`VtaQvZSUMPVX!N-a5y!7KSkaP}k_}RIPQhiiAE9INj@S2K!Xr!M zu%Um#GaA*Z4E7Pt5l>SEO3Nls2$}3i&~+--RT|qa1Tk34l>ytJcu#|Fi;WDMJ z2Yzp*LXP9RwYRKQF5qmE3x7@PU>NyW>#!o+uo^Km0r7qpixN)1@g*oz3mc1MLd`f! R;_jX8`C09YWf-&2zX5xN*Hi!i literal 0 HcmV?d00001 From 07c3ca2c4000485783bda3b7bb53b072f49a9a6f Mon Sep 17 00:00:00 2001 From: Igor Aleksanov Date: Thu, 15 Aug 2024 14:57:38 +0400 Subject: [PATCH 7/7] Add basic CI --- .github/workflows/ci.yaml | 58 +++++++++++++++++++ .github/workflows/deny.yaml | 8 +++ crates/zkevm_opcode_defs/src/lib.rs | 2 +- .../src/tests/complex_tests/mod.rs | 4 +- .../src/tests/run_manually.rs | 2 +- .../src/tests/simple_tests/eip4844.rs | 2 +- .../zkevm_test_harness/deny.toml => deny.toml | 0 7 files changed, 71 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/ci.yaml create mode 100644 .github/workflows/deny.yaml rename crates/zkevm_test_harness/deny.toml => deny.toml (100%) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..37671d1 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,58 @@ +name: "Rust CI" +on: + pull_request: + +jobs: + build: + name: cargo build + runs-on: [ubuntu-22.04-github-hosted-32core] + steps: + - uses: actions/checkout@v3 + - uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + rustflags: "" + - name: Setup rust + run: | + rustup set profile minimal + rustup toolchain install nightly-2023-08-23 + rustup default nightly-2023-08-23 + cargo install cargo-nextest + - name: Compile + run: cargo build + + test: + name: cargo test + runs-on: [ubuntu-22.04-github-hosted-32core] + needs: build + steps: + - uses: actions/checkout@v3 + - uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + rustflags: "" + - name: Setup rust + run: | + rustup set profile minimal + rustup toolchain install nightly-2023-08-23 + rustup default nightly-2023-08-23 + cargo install cargo-nextest + - name: zkevm_test_harness - Main test + run: cargo nextest run --release --manifest-path crates/zkevm_test_harness/Cargo.toml --test-threads 2 + - name: Encodings test + run: cargo nextest run --release --manifest-path crates/circuit_encodings/Cargo.toml + - name: Api tests + run: cargo nextest run --release --manifest-path crates/circuit_sequencer_api/Cargo.toml + - name: Definitions test + run: cargo nextest run --release --manifest-path crates/circuit_definitions/Cargo.toml + - name: Kzg tests + run: cargo nextest run --release --manifest-path crates/kzg/Cargo.toml + + formatting: + name: cargo fmt + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions-rust-lang/setup-rust-toolchain@v1 + with: + components: rustfmt + - name: Rustfmt Check + uses: actions-rust-lang/rustfmt@v1 diff --git a/.github/workflows/deny.yaml b/.github/workflows/deny.yaml new file mode 100644 index 0000000..2d93581 --- /dev/null +++ b/.github/workflows/deny.yaml @@ -0,0 +1,8 @@ +name: Cargo deny check +on: pull_request +jobs: + cargo-deny: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: EmbarkStudios/cargo-deny-action@v1 diff --git a/crates/zkevm_opcode_defs/src/lib.rs b/crates/zkevm_opcode_defs/src/lib.rs index 9b2eab3..a9bee78 100644 --- a/crates/zkevm_opcode_defs/src/lib.rs +++ b/crates/zkevm_opcode_defs/src/lib.rs @@ -27,8 +27,8 @@ pub use sha3; pub use self::definitions::*; pub use self::imm_mem_modifiers::*; pub use self::opcode::*; -pub use self::utils::*; pub use self::system_params::*; +pub use self::utils::*; use lazy_static::lazy_static; diff --git a/crates/zkevm_test_harness/src/tests/complex_tests/mod.rs b/crates/zkevm_test_harness/src/tests/complex_tests/mod.rs index 932846e..f086a98 100644 --- a/crates/zkevm_test_harness/src/tests/complex_tests/mod.rs +++ b/crates/zkevm_test_harness/src/tests/complex_tests/mod.rs @@ -292,7 +292,7 @@ pub(crate) fn generate_base_layer( geometry, storage_impl, tree, - "kzg/src/trusted_setup.json", + "../kzg/src/trusted_setup.json", blobs, artifacts_callback, ); @@ -1259,7 +1259,7 @@ fn run_and_try_create_witness_inner( let eip4844_witnesses: [_; MAX_4844_BLOBS_PER_BLOCK] = blobs.map(|blob| { blob.map(|blob| { let (_blob_arr, linear_hash, _versioned_hash, output_hash) = - generate_eip4844_witness::(&blob, "kzg/src/trusted_setup.json"); + generate_eip4844_witness::(&blob, "../kzg/src/trusted_setup.json"); use crate::zkevm_circuits::eip_4844::input::BlobChunkWitness; use crate::zkevm_circuits::eip_4844::input::EIP4844CircuitInstanceWitness; use crate::zkevm_circuits::eip_4844::input::EIP4844InputOutputWitness; diff --git a/crates/zkevm_test_harness/src/tests/run_manually.rs b/crates/zkevm_test_harness/src/tests/run_manually.rs index 2cc04a2..d07693d 100644 --- a/crates/zkevm_test_harness/src/tests/run_manually.rs +++ b/crates/zkevm_test_harness/src/tests/run_manually.rs @@ -295,7 +295,7 @@ pub(crate) fn run_with_options(entry_point_bytecode: Vec<[u8; 32]>, options: Opt geometry, storage_impl, tree, - "kzg/src/trusted_setup.json", + "../kzg/src/trusted_setup.json", std::array::from_fn(|_| None), artifacts_callback, &mut out_of_circuit_tracer, diff --git a/crates/zkevm_test_harness/src/tests/simple_tests/eip4844.rs b/crates/zkevm_test_harness/src/tests/simple_tests/eip4844.rs index 352829d..8fa1e54 100644 --- a/crates/zkevm_test_harness/src/tests/simple_tests/eip4844.rs +++ b/crates/zkevm_test_harness/src/tests/simple_tests/eip4844.rs @@ -14,7 +14,7 @@ fn test_eip4844() { .for_each(|byte| *byte = rand::thread_rng().gen()); let (blob_arr, linear_hash, versioned_hash, output_hash) = - generate_eip4844_witness::(&blob, "kzg/src/trusted_setup.json"); + generate_eip4844_witness::(&blob, "../kzg/src/trusted_setup.json"); let blob = blob_arr .iter() .map(|el| BlobChunkWitness { inner: *el }) diff --git a/crates/zkevm_test_harness/deny.toml b/deny.toml similarity index 100% rename from crates/zkevm_test_harness/deny.toml rename to deny.toml

( +// generic_params: &Punctuated, +// ) -> bool { +// for p in generic_params.iter() { +// match p { +// GenericParam::Type(ty) => { +// for bound in ty.bounds.iter() { +// match bound { +// TypeParamBound::Trait(t) => { + +// }, +// _ => {} +// } +// } +// } +// _ => {} +// } +// } +// return false; +// } \ No newline at end of file diff --git a/crates/zkevm_circuits/cs_derive/src/var_length_encodable/mod.rs b/crates/zkevm_circuits/cs_derive/src/var_length_encodable/mod.rs new file mode 100644 index 0000000..6a753ab --- /dev/null +++ b/crates/zkevm_circuits/cs_derive/src/var_length_encodable/mod.rs @@ -0,0 +1,110 @@ +use proc_macro2::{Span, TokenStream}; +use proc_macro_error::abort_call_site; +use quote::quote; +use syn::{ + Expr, + Ident, parse_macro_input, punctuated::Punctuated, token::Comma, DeriveInput, GenericParam, Generics, + Type, WhereClause, parse_quote, +}; + +use crate::utils::*; + +// const BOUND_ATTR_NAME: &'static str = "CSSelectableBound"; + +pub(crate) fn derive_var_length_encodable(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + let derived_input = parse_macro_input!(input as DeriveInput); + let DeriveInput { + ident, + generics, + data, + .. + } = derived_input.clone(); + + let mut length_impls = TokenStream::new(); + let mut field_impls = TokenStream::new(); + + // let bound = if let Some(bound) = fetch_attr_from_list(BOUND_ATTR_NAME, &attrs) { + // let bound = syn::parse_str::(&bound).expect("must parse bound as WhereClause"); + + // quote! { #bound } + // } else { + // quote! { } + // }; + + match data { + syn::Data::Struct(ref struct_data) => match struct_data.fields { + syn::Fields::Named(ref named_fields) => { + for field in named_fields.named.iter() { + let field_ident = field.ident.clone().expect("should have a field elem ident"); + match field.ty { + Type::Array(ref _array_ty) => { + let field_impl = quote! { + total_len += CircuitVarLengthEncodable::::encoding_length(&self.#field_ident); + }; + length_impls.extend(field_impl); + + let field_impl = quote! { + CircuitVarLengthEncodable::::encode_to_buffer(&self.#field_ident, cs, dst); + }; + field_impls.extend(field_impl); + } + Type::Path(_) => { + let field_impl = quote! { + total_len += CircuitVarLengthEncodable::::encoding_length(&self.#field_ident); + }; + length_impls.extend(field_impl); + let field_impl = quote! { + CircuitVarLengthEncodable::::encode_to_buffer(&self.#field_ident, cs, dst); + }; + field_impls.extend(field_impl); + } + _ => abort_call_site!("only array and path types are allowed"), + }; + } + } + _ => abort_call_site!("only named fields are allowed!"), + }, + _ => abort_call_site!("only struct types are allowed!"), + } + + let comma = Comma(Span::call_site()); + + let field_generic_param = syn::parse_str::(&"F: SmallField").unwrap(); + let has_engine_param = has_proper_small_field_parameter(&generics.params, &field_generic_param); + if has_engine_param == false { + panic!("Expected to have `F: SmallField` somewhere in bounds"); + } + + // add CS to func generic params + let mut function_generic_params = Punctuated::new(); + let cs_generic_param = syn::parse_str::(&"CS: ConstraintSystem").unwrap(); + function_generic_params.push(cs_generic_param.clone()); + function_generic_params.push_punct(comma.clone()); + + let type_params_of_allocated_struct = get_type_params_from_generics(&generics, &comma); + + let function_generics = Generics { + lt_token: Some(syn::token::Lt(Span::call_site())), + params: function_generic_params, + gt_token: Some(syn::token::Gt(Span::call_site())), + where_clause: None, + }; + + + let expanded = quote! { + impl #generics CircuitVarLengthEncodable for #ident<#type_params_of_allocated_struct> { + #[inline(always)] + fn encoding_length(&self) -> usize { + let mut total_len = 0; + #length_impls; + + total_len + } + fn encode_to_buffer>(&self, cs: &mut CS, dst: &mut Vec) { + #field_impls + } + } + }; + + proc_macro::TokenStream::from(expanded) +} diff --git a/crates/zkevm_circuits/cs_derive/src/witness_hook/mod.rs b/crates/zkevm_circuits/cs_derive/src/witness_hook/mod.rs new file mode 100644 index 0000000..e6fa1a6 --- /dev/null +++ b/crates/zkevm_circuits/cs_derive/src/witness_hook/mod.rs @@ -0,0 +1,124 @@ +use proc_macro2::{Span, TokenStream}; +use proc_macro_error::abort_call_site; +use quote::quote; +use syn::{ + Expr, + Ident, parse_macro_input, punctuated::Punctuated, token::Comma, DeriveInput, GenericParam, Generics, + Type, WhereClause, parse_quote, +}; + +use crate::utils::*; + +const BOUND_ATTR_NAME: &'static str = "WitnessHookBound"; + +pub(crate) fn derive_witness_hook(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + let derived_input = parse_macro_input!(input as DeriveInput); + let DeriveInput { + ident, + generics, + data, + attrs, + .. + } = derived_input.clone(); + + let mut struct_initializations = TokenStream::new(); + let mut field_selections = TokenStream::new(); + let mut field_callings = TokenStream::new(); + + let bound = if let Some(bound) = fetch_attr_from_list(BOUND_ATTR_NAME, &attrs) { + let bound = syn::parse_str::(&bound).expect("must parse bound as WhereClause"); + + quote! { #bound } + } else { + quote! { } + }; + + match data { + syn::Data::Struct(ref struct_data) => match struct_data.fields { + syn::Fields::Named(ref named_fields) => { + for field in named_fields.named.iter() { + let field_ident = field.ident.clone().expect("should have a field elem ident"); + match field.ty { + Type::Array(ref _array_ty) => { + let field_select = quote! { + let #field_ident = WitnessHookable::::witness_hook(&self.#field_ident, cs); + }; + field_selections.extend(field_select); + let field_calling = quote! { + let #field_ident = (#field_ident)()?; + }; + field_callings.extend(field_calling); + } + Type::Path(_) => { + let field_select = quote! { + let #field_ident = WitnessHookable::::witness_hook(&self.#field_ident, cs); + }; + field_selections.extend(field_select); + let field_calling = quote! { + let #field_ident = (#field_ident)()?; + }; + field_callings.extend(field_calling); + } + _ => abort_call_site!("only array and path types are allowed"), + }; + + let init_field = quote! { + #field_ident, + }; + + struct_initializations.extend(init_field); + } + } + _ => abort_call_site!("only named fields are allowed!"), + }, + _ => abort_call_site!("only struct types are allowed!"), + } + + let comma = Comma(Span::call_site()); + + let field_generic_param = syn::parse_str::(&"F: SmallField").unwrap(); + let has_engine_param = has_proper_small_field_parameter(&generics.params, &field_generic_param); + if has_engine_param == false { + panic!("Expected to have `F: SmallField` somewhere in bounds"); + } + + // add CS to func generic params + let mut function_generic_params = Punctuated::new(); + let cs_generic_param = syn::parse_str::(&"CS: ConstraintSystem").unwrap(); + function_generic_params.push(cs_generic_param.clone()); + function_generic_params.push_punct(comma.clone()); + + let type_params_of_allocated_struct = get_type_params_from_generics(&generics, &comma); + + let function_generics = Generics { + lt_token: Some(syn::token::Lt(Span::call_site())), + params: function_generic_params, + gt_token: Some(syn::token::Gt(Span::call_site())), + where_clause: None, + }; + + let expanded = quote! { + impl #generics WitnessHookable for #ident<#type_params_of_allocated_struct> #bound { + fn witness_hook #function_generics( + &self, + cs: &CS, + ) -> Box Option + 'static> { + #field_selections; + + Box::new( + move || { + #field_callings; + + Some( + Self::Witness { + #struct_initializations + } + ) + } + ) + } + } + }; + + proc_macro::TokenStream::from(expanded) +} diff --git a/crates/zkevm_circuits/deny.toml b/crates/zkevm_circuits/deny.toml new file mode 100644 index 0000000..6977d43 --- /dev/null +++ b/crates/zkevm_circuits/deny.toml @@ -0,0 +1,79 @@ +all-features = false +no-default-features = false + +[advisories] +vulnerability = "deny" +unmaintained = "warn" +yanked = "warn" +notice = "warn" +ignore = [ + #"RUSTSEC-0000-0000", +] + +[licenses] +unlicensed = "deny" +allow = [ + #"Apache-2.0 WITH LLVM-exception", + "MIT", + "Apache-2.0", + "ISC", + "Unlicense", + "MPL-2.0", + "Unicode-DFS-2016", + "CC0-1.0", + "BSD-2-Clause", + "BSD-3-Clause", + "Zlib", +] +deny = [ + #"Nokia", +] +copyleft = "warn" +allow-osi-fsf-free = "neither" +default = "deny" +confidence-threshold = 0.8 +exceptions = [ + # Each entry is the crate and version constraint, and its specific allow + # list + #{ allow = ["Zlib"], name = "adler32", version = "*" }, +] + +unused-allowed-license = "allow" + +[licenses.private] +ignore = false +registries = [ + #"https://sekretz.com/registry +] + +[bans] +multiple-versions = "warn" +wildcards = "allow" +highlight = "all" +workspace-default-features = "allow" +external-default-features = "allow" +allow = [ + #{ name = "ansi_term", version = "=0.11.0" }, +] +# List of crates to deny +deny = [ + # Each entry the name of a crate and a version range. If version is + # not specified, all versions will be matched. + #{ name = "ansi_term", version = "=0.11.0" }, +] + +skip = [ + #{ name = "ansi_term", version = "=0.11.0" }, +] +skip-tree = [ + #{ name = "ansi_term", version = "=0.11.0", depth = 20 }, +] + +[sources] +unknown-registry = "deny" +unknown-git = "allow" +allow-registry = ["https://github.com/rust-lang/crates.io-index"] +allow-git = [] + +[sources.allow-org] +#github = ["matter-labs"] diff --git a/crates/zkevm_circuits/eraLogo.png b/crates/zkevm_circuits/eraLogo.png new file mode 100644 index 0000000000000000000000000000000000000000..5d9480d8f05342a06cd1ee03405137552bdbebbf GIT binary patch literal 79091 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 { + pub code_hash: UInt256, + pub page: UInt32, + pub is_first: Boolean, + pub timestamp: UInt32, +} + +pub const DECOMMIT_QUERY_PACKED_WIDTH: usize = 8; + +impl CircuitEncodable for DecommitQuery { + fn encode>( + &self, + cs: &mut CS, + ) -> [Variable; DECOMMIT_QUERY_PACKED_WIDTH] { + debug_assert!(F::CAPACITY_BITS >= 56); + + // we assume that page bytes are known, so it'll be nop anyway + let page_bytes = self.page.decompose_into_bytes(cs); + + let timestamp_bytes = self.timestamp.decompose_into_bytes(cs); + + let v0 = Num::linear_combination( + cs, + &[ + (self.code_hash.inner[0].get_variable(), F::ONE), + ( + page_bytes[0].get_variable(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + page_bytes[1].get_variable(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + page_bytes[2].get_variable(), + F::from_u64_unchecked(1u64 << 48), + ), + ], + ) + .get_variable(); + + let v1 = Num::linear_combination( + cs, + &[ + (self.code_hash.inner[1].get_variable(), F::ONE), + ( + page_bytes[3].get_variable(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + timestamp_bytes[0].get_variable(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + timestamp_bytes[1].get_variable(), + F::from_u64_unchecked(1u64 << 48), + ), + ], + ) + .get_variable(); + + let v2 = Num::linear_combination( + cs, + &[ + (self.code_hash.inner[2].get_variable(), F::ONE), + ( + timestamp_bytes[2].get_variable(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + timestamp_bytes[3].get_variable(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + self.is_first.get_variable(), + F::from_u64_unchecked(1u64 << 48), + ), + ], + ) + .get_variable(); + + let v3 = self.code_hash.inner[3].get_variable(); + let v4 = self.code_hash.inner[4].get_variable(); + let v5 = self.code_hash.inner[5].get_variable(); + let v6 = self.code_hash.inner[6].get_variable(); + let v7 = self.code_hash.inner[7].get_variable(); + + [v0, v1, v2, v3, v4, v5, v6, v7] + } +} + +impl CSAllocatableExt for DecommitQuery { + const INTERNAL_STRUCT_LEN: usize = 11; + + fn witness_from_set_of_values(values: [F; Self::INTERNAL_STRUCT_LEN]) -> Self::Witness { + let code_hash: U256 = WitnessCastable::cast_from_source([ + values[0], values[1], values[2], values[3], values[4], values[5], values[6], values[7], + ]); + + let page: u32 = WitnessCastable::cast_from_source(values[8]); + let is_first: bool = WitnessCastable::cast_from_source(values[9]); + let timestamp: u32 = WitnessCastable::cast_from_source(values[10]); + + Self::Witness { + code_hash, + page, + is_first, + timestamp, + } + } + + fn flatten_as_variables(&self) -> [Variable; Self::INTERNAL_STRUCT_LEN] + where + [(); Self::INTERNAL_STRUCT_LEN]:, + { + [ + self.code_hash.inner[0].get_variable(), + self.code_hash.inner[1].get_variable(), + self.code_hash.inner[2].get_variable(), + self.code_hash.inner[3].get_variable(), + self.code_hash.inner[4].get_variable(), + self.code_hash.inner[5].get_variable(), + self.code_hash.inner[6].get_variable(), + self.code_hash.inner[7].get_variable(), + self.page.get_variable(), + self.is_first.get_variable(), + self.timestamp.get_variable(), + ] + } + fn set_internal_variables_values(witness: Self::Witness, dst: &mut DstBuffer<'_, '_, F>) { + // NOTE: must be same sequence as in `flatten_as_variables` + UInt256::set_internal_variables_values(witness.code_hash, dst); + UInt32::set_internal_variables_values(witness.page, dst); + Boolean::set_internal_variables_values(witness.is_first, dst); + UInt32::set_internal_variables_values(witness.timestamp, dst); + } +} + +impl CircuitEncodableExt for DecommitQuery {} + +impl CSPlaceholder for DecommitQuery { + fn placeholder>(cs: &mut CS) -> Self { + let zero_u32 = UInt32::zero(cs); + let boolean_false = Boolean::allocated_constant(cs, false); + Self { + code_hash: UInt256::::zero(cs), + page: zero_u32, + is_first: boolean_false, + timestamp: zero_u32, + } + } +} + +use boojum::gadgets::queue::full_state_queue::{ + FullStateCircuitQueue, FullStateCircuitQueueWitness, +}; + +pub type DecommitQueryQueue = + FullStateCircuitQueue, AW, SW, CW, DECOMMIT_QUERY_PACKED_WIDTH, R>; + +pub type DecommitQueue = DecommitQueryQueue; + +pub type DecommitQueueWitness = + FullStateCircuitQueueWitness, SW, DECOMMIT_QUERY_PACKED_WIDTH>; diff --git a/crates/zkevm_circuits/src/base_structures/log_query/mod.rs b/crates/zkevm_circuits/src/base_structures/log_query/mod.rs new file mode 100644 index 0000000..4d42995 --- /dev/null +++ b/crates/zkevm_circuits/src/base_structures/log_query/mod.rs @@ -0,0 +1,686 @@ +use super::*; +use boojum::cs::traits::cs::ConstraintSystem; +use boojum::cs::traits::cs::DstBuffer; +use boojum::cs::Variable; +use boojum::field::SmallField; +use boojum::gadgets::boolean::Boolean; +use boojum::gadgets::num::Num; +use boojum::gadgets::traits::allocatable::CSPlaceholder; +use boojum::gadgets::traits::allocatable::{CSAllocatable, CSAllocatableExt}; +use boojum::gadgets::traits::castable::WitnessCastable; +use boojum::gadgets::traits::encodable::CircuitEncodableExt; +use boojum::gadgets::traits::encodable::{CircuitEncodable, CircuitVarLengthEncodable}; +use boojum::gadgets::traits::selectable::Selectable; +use boojum::gadgets::traits::witnessable::WitnessHookable; +use boojum::gadgets::u160::{recompose_address_from_u32x5, UInt160}; +use boojum::gadgets::u256::{recompose_u256_as_u32x8, UInt256}; +use boojum::gadgets::u32::UInt32; +use boojum::gadgets::u8::UInt8; +use cs_derive::*; + +#[derive(Derivative, CSAllocatable, CSSelectable, WitnessHookable, CSVarLengthEncodable)] +#[derivative(Clone, Copy, Debug, Hash)] +pub struct LogQuery { + pub address: UInt160, + pub key: UInt256, + pub read_value: UInt256, + pub written_value: UInt256, + pub aux_byte: UInt8, + pub rw_flag: Boolean, + pub rollback: Boolean, + pub is_service: Boolean, + pub shard_id: UInt8, + pub tx_number_in_block: UInt32, + pub timestamp: UInt32, +} +impl CircuitEncodableExt for LogQuery {} + +pub const LOG_QUERY_PACKED_WIDTH: usize = 20; +pub const LOG_QUERY_ABSORBTION_ROUNDS: usize = 3; + +// NOTE: (shamatar): workaround for cost generics for now +pub(crate) const FLATTENED_VARIABLE_LENGTH: usize = 36; + +// because two logs that we add to the queue on write-like operation only differ by +// rollback flag, we want to specially define offset for rollback, so we can +// pack two cases for free. Also packing of the rollback should go into variable +// number 16 or later, so we can share sponges before it + +pub const ROLLBACK_PACKING_FLAG_VARIABLE_IDX: usize = 19; + +impl LogQuery { + pub fn update_packing_for_rollback>( + cs: &mut CS, + existing_packing: &mut [Variable; LOG_QUERY_PACKED_WIDTH], + ) { + let boolean_true = Boolean::allocated_constant(cs, true); + existing_packing[ROLLBACK_PACKING_FLAG_VARIABLE_IDX] = boolean_true.get_variable(); + } + + pub(crate) fn flatten_as_variables_impl(&self) -> [Variable; FLATTENED_VARIABLE_LENGTH] { + [ + self.address.inner[0].get_variable(), + self.address.inner[1].get_variable(), + self.address.inner[2].get_variable(), + self.address.inner[3].get_variable(), + self.address.inner[4].get_variable(), + self.key.inner[0].get_variable(), + self.key.inner[1].get_variable(), + self.key.inner[2].get_variable(), + self.key.inner[3].get_variable(), + self.key.inner[4].get_variable(), + self.key.inner[5].get_variable(), + self.key.inner[6].get_variable(), + self.key.inner[7].get_variable(), + self.read_value.inner[0].get_variable(), + self.read_value.inner[1].get_variable(), + self.read_value.inner[2].get_variable(), + self.read_value.inner[3].get_variable(), + self.read_value.inner[4].get_variable(), + self.read_value.inner[5].get_variable(), + self.read_value.inner[6].get_variable(), + self.read_value.inner[7].get_variable(), + self.written_value.inner[0].get_variable(), + self.written_value.inner[1].get_variable(), + self.written_value.inner[2].get_variable(), + self.written_value.inner[3].get_variable(), + self.written_value.inner[4].get_variable(), + self.written_value.inner[5].get_variable(), + self.written_value.inner[6].get_variable(), + self.written_value.inner[7].get_variable(), + self.aux_byte.get_variable(), + self.rw_flag.get_variable(), + self.rollback.get_variable(), + self.is_service.get_variable(), + self.shard_id.get_variable(), + self.tx_number_in_block.get_variable(), + self.timestamp.get_variable(), + ] + } +} + +impl CSPlaceholder for LogQuery { + fn placeholder>(cs: &mut CS) -> Self { + let boolean_false = Boolean::allocated_constant(cs, false); + Self { + address: UInt160::::zero(cs), + key: UInt256::zero(cs), + read_value: UInt256::zero(cs), + written_value: UInt256::zero(cs), + rw_flag: boolean_false, + aux_byte: UInt8::zero(cs), + rollback: boolean_false, + is_service: boolean_false, + shard_id: UInt8::zero(cs), + tx_number_in_block: UInt32::zero(cs), + timestamp: UInt32::zero(cs), + } + } +} + +impl CircuitEncodable for LogQuery { + fn encode>(&self, cs: &mut CS) -> [Variable; LOG_QUERY_PACKED_WIDTH] { + debug_assert!(F::CAPACITY_BITS >= 56); + // we decompose "key" and mix it into other limbs because with high probability + // in VM decomposition of "key" will always exist beforehand + let key_bytes = self.key.inner.map(|el| el.decompose_into_bytes(cs)); + let address_bytes = self.address.inner.map(|el| el.decompose_into_bytes(cs)); + + // we want to pack tightly, so we "base" our packing on read and written values + + let v0 = Num::linear_combination( + cs, + &[ + (self.read_value.inner[0].get_variable(), F::ONE), + ( + key_bytes[0][0].get_variable(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + key_bytes[0][1].get_variable(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + key_bytes[0][2].get_variable(), + F::from_u64_unchecked(1u64 << 48), + ), + ], + ) + .get_variable(); + + let v1 = Num::linear_combination( + cs, + &[ + (self.read_value.inner[1].get_variable(), F::ONE), + ( + key_bytes[0][3].get_variable(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + key_bytes[1][0].get_variable(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + key_bytes[1][1].get_variable(), + F::from_u64_unchecked(1u64 << 48), + ), + ], + ) + .get_variable(); + + let v2 = Num::linear_combination( + cs, + &[ + (self.read_value.inner[2].get_variable(), F::ONE), + ( + key_bytes[1][2].get_variable(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + key_bytes[1][3].get_variable(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + key_bytes[2][0].get_variable(), + F::from_u64_unchecked(1u64 << 48), + ), + ], + ) + .get_variable(); + + let v3 = Num::linear_combination( + cs, + &[ + (self.read_value.inner[3].get_variable(), F::ONE), + ( + key_bytes[2][1].get_variable(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + key_bytes[2][2].get_variable(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + key_bytes[2][3].get_variable(), + F::from_u64_unchecked(1u64 << 48), + ), + ], + ) + .get_variable(); + + let v4 = Num::linear_combination( + cs, + &[ + (self.read_value.inner[4].get_variable(), F::ONE), + ( + key_bytes[3][0].get_variable(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + key_bytes[3][1].get_variable(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + key_bytes[3][2].get_variable(), + F::from_u64_unchecked(1u64 << 48), + ), + ], + ) + .get_variable(); + + let v5 = Num::linear_combination( + cs, + &[ + (self.read_value.inner[5].get_variable(), F::ONE), + ( + key_bytes[3][3].get_variable(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + key_bytes[4][0].get_variable(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + key_bytes[4][1].get_variable(), + F::from_u64_unchecked(1u64 << 48), + ), + ], + ) + .get_variable(); + + let v6 = Num::linear_combination( + cs, + &[ + (self.read_value.inner[6].get_variable(), F::ONE), + ( + key_bytes[4][2].get_variable(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + key_bytes[4][3].get_variable(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + key_bytes[5][0].get_variable(), + F::from_u64_unchecked(1u64 << 48), + ), + ], + ) + .get_variable(); + + let v7 = Num::linear_combination( + cs, + &[ + (self.read_value.inner[7].get_variable(), F::ONE), + ( + key_bytes[5][1].get_variable(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + key_bytes[5][2].get_variable(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + key_bytes[5][3].get_variable(), + F::from_u64_unchecked(1u64 << 48), + ), + ], + ) + .get_variable(); + + // continue with written value + + let v8 = Num::linear_combination( + cs, + &[ + (self.written_value.inner[0].get_variable(), F::ONE), + ( + key_bytes[6][0].get_variable(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + key_bytes[6][1].get_variable(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + key_bytes[6][2].get_variable(), + F::from_u64_unchecked(1u64 << 48), + ), + ], + ) + .get_variable(); + + let v9 = Num::linear_combination( + cs, + &[ + (self.written_value.inner[1].get_variable(), F::ONE), + ( + key_bytes[6][3].get_variable(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + key_bytes[7][0].get_variable(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + key_bytes[7][1].get_variable(), + F::from_u64_unchecked(1u64 << 48), + ), + ], + ) + .get_variable(); + + // continue mixing bytes, now from "address" + + let v10 = Num::linear_combination( + cs, + &[ + (self.written_value.inner[2].get_variable(), F::ONE), + ( + key_bytes[7][2].get_variable(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + key_bytes[7][3].get_variable(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + address_bytes[0][0].get_variable(), + F::from_u64_unchecked(1u64 << 48), + ), + ], + ) + .get_variable(); + + let v11 = Num::linear_combination( + cs, + &[ + (self.written_value.inner[3].get_variable(), F::ONE), + ( + address_bytes[0][1].get_variable(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + address_bytes[0][2].get_variable(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + address_bytes[0][3].get_variable(), + F::from_u64_unchecked(1u64 << 48), + ), + ], + ) + .get_variable(); + + let v12 = Num::linear_combination( + cs, + &[ + (self.written_value.inner[4].get_variable(), F::ONE), + ( + address_bytes[1][0].get_variable(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + address_bytes[1][1].get_variable(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + address_bytes[1][2].get_variable(), + F::from_u64_unchecked(1u64 << 48), + ), + ], + ) + .get_variable(); + + let v13 = Num::linear_combination( + cs, + &[ + (self.written_value.inner[5].get_variable(), F::ONE), + ( + address_bytes[1][3].get_variable(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + address_bytes[2][0].get_variable(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + address_bytes[2][1].get_variable(), + F::from_u64_unchecked(1u64 << 48), + ), + ], + ) + .get_variable(); + + let v14 = Num::linear_combination( + cs, + &[ + (self.written_value.inner[6].get_variable(), F::ONE), + ( + address_bytes[2][2].get_variable(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + address_bytes[2][3].get_variable(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + address_bytes[3][0].get_variable(), + F::from_u64_unchecked(1u64 << 48), + ), + ], + ) + .get_variable(); + + let v15 = Num::linear_combination( + cs, + &[ + (self.written_value.inner[7].get_variable(), F::ONE), + ( + address_bytes[3][1].get_variable(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + address_bytes[3][2].get_variable(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + address_bytes[3][3].get_variable(), + F::from_u64_unchecked(1u64 << 48), + ), + ], + ) + .get_variable(); + + // now we can pack using some other "large" items as base + + let v16 = Num::linear_combination( + cs, + &[ + (self.timestamp.get_variable(), F::ONE), + ( + address_bytes[4][0].get_variable(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + address_bytes[4][1].get_variable(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + address_bytes[4][2].get_variable(), + F::from_u64_unchecked(1u64 << 48), + ), + ], + ) + .get_variable(); + + let v17 = Num::linear_combination( + cs, + &[ + (self.tx_number_in_block.get_variable(), F::ONE), + ( + address_bytes[4][3].get_variable(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + self.aux_byte.get_variable(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + self.shard_id.get_variable(), + F::from_u64_unchecked(1u64 << 48), + ), + ], + ) + .get_variable(); + + let v18 = Num::linear_combination( + cs, + &[ + (self.rw_flag.get_variable(), F::ONE), + (self.is_service.get_variable(), F::TWO), + ], + ) + .get_variable(); + + // and the final variable is just rollback flag itself + + // NOTE: if you even change this encoding please ensure that corresponding part + // is updated in TimestampedStorageLogRecord + let v19 = self.rollback.get_variable(); + + [ + v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, + v19, + ] + } +} + +pub(crate) fn log_query_witness_from_values( + values: [F; FLATTENED_VARIABLE_LENGTH], +) -> as CSAllocatable>::Witness { + let address: [u32; 5] = [ + WitnessCastable::cast_from_source(values[0]), + WitnessCastable::cast_from_source(values[1]), + WitnessCastable::cast_from_source(values[2]), + WitnessCastable::cast_from_source(values[3]), + WitnessCastable::cast_from_source(values[4]), + ]; + let address = recompose_address_from_u32x5(address); + + let key: [u32; 8] = [ + WitnessCastable::cast_from_source(values[5]), + WitnessCastable::cast_from_source(values[6]), + WitnessCastable::cast_from_source(values[7]), + WitnessCastable::cast_from_source(values[8]), + WitnessCastable::cast_from_source(values[9]), + WitnessCastable::cast_from_source(values[10]), + WitnessCastable::cast_from_source(values[11]), + WitnessCastable::cast_from_source(values[12]), + ]; + let key = recompose_u256_as_u32x8(key); + + let read_value: [u32; 8] = [ + WitnessCastable::cast_from_source(values[13]), + WitnessCastable::cast_from_source(values[14]), + WitnessCastable::cast_from_source(values[15]), + WitnessCastable::cast_from_source(values[16]), + WitnessCastable::cast_from_source(values[17]), + WitnessCastable::cast_from_source(values[18]), + WitnessCastable::cast_from_source(values[19]), + WitnessCastable::cast_from_source(values[20]), + ]; + let read_value = recompose_u256_as_u32x8(read_value); + + let written_value: [u32; 8] = [ + WitnessCastable::cast_from_source(values[21]), + WitnessCastable::cast_from_source(values[22]), + WitnessCastable::cast_from_source(values[23]), + WitnessCastable::cast_from_source(values[24]), + WitnessCastable::cast_from_source(values[25]), + WitnessCastable::cast_from_source(values[26]), + WitnessCastable::cast_from_source(values[27]), + WitnessCastable::cast_from_source(values[28]), + ]; + let written_value = recompose_u256_as_u32x8(written_value); + + let aux_byte: u8 = WitnessCastable::cast_from_source(values[29]); + let rw_flag: bool = WitnessCastable::cast_from_source(values[30]); + let rollback: bool = WitnessCastable::cast_from_source(values[31]); + let is_service: bool = WitnessCastable::cast_from_source(values[32]); + let shard_id: u8 = WitnessCastable::cast_from_source(values[33]); + let tx_number_in_block: u32 = WitnessCastable::cast_from_source(values[34]); + let timestamp: u32 = WitnessCastable::cast_from_source(values[35]); + + as CSAllocatable>::Witness { + address, + key, + read_value, + written_value, + aux_byte, + rw_flag, + rollback, + is_service, + shard_id, + tx_number_in_block, + timestamp, + } +} + +impl CSAllocatableExt for LogQuery { + const INTERNAL_STRUCT_LEN: usize = FLATTENED_VARIABLE_LENGTH; + + fn witness_from_set_of_values(values: [F; Self::INTERNAL_STRUCT_LEN]) -> Self::Witness { + log_query_witness_from_values(values) + } + + // we should be able to allocate without knowing values yet + fn create_without_value>(cs: &mut CS) -> Self { + Self { + address: UInt160::allocate_without_value(cs), + key: UInt256::allocate_without_value(cs), + read_value: UInt256::allocate_without_value(cs), + written_value: UInt256::allocate_without_value(cs), + rw_flag: Boolean::allocate_without_value(cs), + aux_byte: UInt8::allocate_without_value(cs), + rollback: Boolean::allocate_without_value(cs), + is_service: Boolean::allocate_without_value(cs), + shard_id: UInt8::allocate_without_value(cs), + tx_number_in_block: UInt32::allocate_without_value(cs), + timestamp: UInt32::allocate_without_value(cs), + } + } + + fn flatten_as_variables(&self) -> [Variable; Self::INTERNAL_STRUCT_LEN] + where + [(); Self::INTERNAL_STRUCT_LEN]:, + { + self.flatten_as_variables_impl() + } + + fn set_internal_variables_values(witness: Self::Witness, dst: &mut DstBuffer<'_, '_, F>) { + // NOTE: must be same sequence as in `flatten_as_variables` + UInt160::set_internal_variables_values(witness.address, dst); + UInt256::set_internal_variables_values(witness.key, dst); + UInt256::set_internal_variables_values(witness.read_value, dst); + UInt256::set_internal_variables_values(witness.written_value, dst); + UInt8::set_internal_variables_values(witness.aux_byte, dst); + Boolean::set_internal_variables_values(witness.rw_flag, dst); + Boolean::set_internal_variables_values(witness.rollback, dst); + Boolean::set_internal_variables_values(witness.is_service, dst); + UInt8::set_internal_variables_values(witness.shard_id, dst); + UInt32::set_internal_variables_values(witness.tx_number_in_block, dst); + UInt32::set_internal_variables_values(witness.timestamp, dst); + } +} + +use crate::base_structures::vm_state::QUEUE_STATE_WIDTH; +use boojum::gadgets::queue::CircuitQueue; + +pub type LogQueryQueue = + CircuitQueue, AW, SW, CW, QUEUE_STATE_WIDTH, LOG_QUERY_PACKED_WIDTH, R>; + +// we will output L2 to L1 messages as byte packed messages, so let's make it + +pub const L2_TO_L1_MESSAGE_BYTE_LENGTH: usize = 88; + +impl ByteSerializable for LogQuery { + fn into_bytes>( + &self, + cs: &mut CS, + ) -> [UInt8; L2_TO_L1_MESSAGE_BYTE_LENGTH] { + let zero_u8 = UInt8::zero(cs); + + let mut result = [zero_u8; L2_TO_L1_MESSAGE_BYTE_LENGTH]; + let mut offset = 0; + result[offset] = self.shard_id; + offset += 1; + result[offset] = unsafe { UInt8::from_variable_unchecked(self.is_service.get_variable()) }; + offset += 1; + + let bytes_be = self.tx_number_in_block.to_be_bytes(cs); + result[offset..(offset + (bytes_be.len() - 2))].copy_from_slice(&bytes_be[2..]); + offset += bytes_be.len() - 2; + + // we truncated, so let's enforce that those were unsused + for el in bytes_be[..2].iter() { + Num::enforce_equal(cs, &zero_u8.into_num(), &el.into_num()); + } + + let bytes_be = self.address.to_be_bytes(cs); + result[offset..(offset + bytes_be.len())].copy_from_slice(&bytes_be); + offset += bytes_be.len(); + + let bytes_be = self.key.to_be_bytes(cs); + result[offset..(offset + bytes_be.len())].copy_from_slice(&bytes_be); + offset += bytes_be.len(); + + let bytes_be = self.written_value.to_be_bytes(cs); + result[offset..(offset + bytes_be.len())].copy_from_slice(&bytes_be); + offset += bytes_be.len(); + + assert_eq!(offset, L2_TO_L1_MESSAGE_BYTE_LENGTH); + + result + } +} diff --git a/crates/zkevm_circuits/src/base_structures/memory_query/mod.rs b/crates/zkevm_circuits/src/base_structures/memory_query/mod.rs new file mode 100644 index 0000000..990e01b --- /dev/null +++ b/crates/zkevm_circuits/src/base_structures/memory_query/mod.rs @@ -0,0 +1,314 @@ +use super::*; + +use boojum::field::SmallField; + +use boojum::gadgets::queue::full_state_queue::FullStateCircuitQueue; +use boojum::gadgets::u256::UInt256; + +use boojum::gadgets::boolean::Boolean; +use boojum::gadgets::u32::UInt32; + +use crate::ethereum_types::U256; +use boojum::config::*; +use boojum::cs::traits::cs::ConstraintSystem; +use boojum::cs::traits::cs::DstBuffer; +use boojum::cs::Place; +use boojum::cs::Variable; +use boojum::gadgets::num::Num; +use boojum::gadgets::traits::allocatable::{CSAllocatable, CSAllocatableExt}; +use boojum::gadgets::traits::castable::WitnessCastable; +use boojum::gadgets::traits::encodable::{CircuitEncodable, CircuitEncodableExt}; +use boojum::gadgets::traits::selectable::Selectable; + +use boojum::gadgets::traits::witnessable::WitnessHookable; +use cs_derive::*; + +pub const MEMORY_QUERY_PACKED_WIDTH: usize = 8; + +#[derive(Derivative, CSSelectable, CSAllocatable, WitnessHookable)] +#[derivative(Clone, Copy, Debug, Hash)] +pub struct MemoryQuery { + pub timestamp: UInt32, + pub memory_page: UInt32, + pub index: UInt32, + pub rw_flag: Boolean, + pub is_ptr: Boolean, + pub value: UInt256, +} + +impl CircuitEncodableExt for MemoryQuery {} + +// in practice we use memory queue, so we need to have a nice way to pack memory query into +// 8 field elements. In addition we can exploit the fact that when we will process the elements +// we will only need to exploit timestamp, page, index, value and r/w flag in their types, but +// actual value can be packed more tightly into full field elements as it will only be compared, +// without access to it's bitwidth + +pub const MEMORY_QUERY_UNROLLED_WIDTH: usize = 13; + +impl CSAllocatableExt for MemoryQuery { + const INTERNAL_STRUCT_LEN: usize = MEMORY_QUERY_UNROLLED_WIDTH; + + fn flatten_as_variables(&self) -> [Variable; Self::INTERNAL_STRUCT_LEN] { + [ + self.timestamp.get_variable(), + self.memory_page.get_variable(), + self.index.get_variable(), + self.rw_flag.get_variable(), + self.is_ptr.get_variable(), + self.value.inner[0].get_variable(), + self.value.inner[1].get_variable(), + self.value.inner[2].get_variable(), + self.value.inner[3].get_variable(), + self.value.inner[4].get_variable(), + self.value.inner[5].get_variable(), + self.value.inner[6].get_variable(), + self.value.inner[7].get_variable(), + ] + } + + fn set_internal_variables_values(witness: Self::Witness, dst: &mut DstBuffer<'_, '_, F>) { + // NOTE: must be same sequence as in `flatten_as_variables` + UInt32::set_internal_variables_values(witness.timestamp, dst); + UInt32::set_internal_variables_values(witness.memory_page, dst); + UInt32::set_internal_variables_values(witness.index, dst); + Boolean::set_internal_variables_values(witness.rw_flag, dst); + Boolean::set_internal_variables_values(witness.is_ptr, dst); + UInt256::set_internal_variables_values(witness.value, dst); + } + + fn witness_from_set_of_values(values: [F; Self::INTERNAL_STRUCT_LEN]) -> Self::Witness { + let timestamp: u32 = WitnessCastable::cast_from_source(values[0]); + let memory_page: u32 = WitnessCastable::cast_from_source(values[1]); + let index: u32 = WitnessCastable::cast_from_source(values[2]); + let rw_flag: bool = WitnessCastable::cast_from_source(values[3]); + let is_ptr: bool = WitnessCastable::cast_from_source(values[4]); + + let value: U256 = WitnessCastable::cast_from_source([ + values[5], values[6], values[7], values[8], values[9], values[10], values[11], + values[12], + ]); + + Self::Witness { + timestamp, + memory_page, + index, + rw_flag, + is_ptr, + value, + } + } +} + +impl CircuitEncodable for MemoryQuery { + fn encode>( + &self, + cs: &mut CS, + ) -> [Variable; MEMORY_QUERY_PACKED_WIDTH] { + // we assume the fact that capacity of F is quite close to 64 bits + debug_assert!(F::CAPACITY_BITS >= 56); + + // strategy: we use 3 field elements to pack timestamp, decomposition of page, index and r/w flag, + // and 5 more elements to tightly pack 8xu32 of values + + let v0 = self.timestamp.get_variable(); + let v1 = self.memory_page.get_variable(); + let v2 = Num::linear_combination( + cs, + &[ + (self.index.get_variable(), F::ONE), + ( + self.rw_flag.get_variable(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + self.is_ptr.get_variable(), + F::from_u64_unchecked(1u64 << 33), + ), + ], + ) + .get_variable(); + + // value. Those in most of the cases will be nops + let decomposition_5 = self.value.inner[5].decompose_into_bytes(cs); + let decomposition_6 = self.value.inner[6].decompose_into_bytes(cs); + let decomposition_7 = self.value.inner[7].decompose_into_bytes(cs); + + let v3 = Num::linear_combination( + cs, + &[ + (self.value.inner[0].get_variable(), F::ONE), + ( + decomposition_5[0].get_variable(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + decomposition_5[1].get_variable(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + decomposition_5[2].get_variable(), + F::from_u64_unchecked(1u64 << 48), + ), + ], + ) + .get_variable(); + + let v4 = Num::linear_combination( + cs, + &[ + (self.value.inner[1].get_variable(), F::ONE), + ( + decomposition_5[3].get_variable(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + decomposition_6[0].get_variable(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + decomposition_6[1].get_variable(), + F::from_u64_unchecked(1u64 << 48), + ), + ], + ) + .get_variable(); + + let v5 = Num::linear_combination( + cs, + &[ + (self.value.inner[2].get_variable(), F::ONE), + ( + decomposition_6[2].get_variable(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + decomposition_6[3].get_variable(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + decomposition_7[0].get_variable(), + F::from_u64_unchecked(1u64 << 48), + ), + ], + ) + .get_variable(); + + let v6 = Num::linear_combination( + cs, + &[ + (self.value.inner[3].get_variable(), F::ONE), + ( + decomposition_7[1].get_variable(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + decomposition_7[2].get_variable(), + F::from_u64_unchecked(1u64 << 40), + ), + ( + decomposition_7[3].get_variable(), + F::from_u64_unchecked(1u64 << 48), + ), + ], + ) + .get_variable(); + + let v7 = self.value.inner[4].get_variable(); + + [v0, v1, v2, v3, v4, v5, v6, v7] + } +} + +#[derive(Derivative)] +#[derivative(Clone, Copy, Debug, Hash)] +pub struct MemoryValue { + pub is_ptr: Boolean, + pub value: UInt256, +} + +use crate::main_vm::witness_oracle::MemoryWitness; +use boojum::gadgets::u256::decompose_u256_as_u32x8; + +impl MemoryValue { + pub fn allocate_from_closure_and_dependencies< + CS: ConstraintSystem, + FN: FnOnce(&[F]) -> MemoryWitness + 'static + Send + Sync, + >( + cs: &mut CS, + witness_closure: FN, + dependencies: &[Place], + ) -> Self { + let outputs = cs.alloc_multiple_variables_without_values::<9>(); + + if ::WitnessConfig::EVALUATE_WITNESS { + let value_fn = move |inputs: &[F], output_buffer: &mut DstBuffer<'_, '_, F>| { + debug_assert!(F::CAPACITY_BITS >= 32); + let witness = (witness_closure)(inputs); + let chunks = decompose_u256_as_u32x8(witness.value); + output_buffer.extend(chunks.map(|el| F::from_u64_unchecked(el as u64))); + output_buffer.push(F::from_u64_unchecked(witness.is_ptr as u64)); + }; + + cs.set_values_with_dependencies_vararg( + &dependencies, + &Place::from_variables(outputs), + value_fn, + ); + } + + let [l0, l1, l2, l3, l4, l5, l6, l7, b] = outputs; + + let chunks = + [l0, l1, l2, l3, l4, l5, l6, l7].map(|el| UInt32::from_variable_checked(cs, el)); + let is_ptr = Boolean::from_variable_checked(cs, b); + + Self { + is_ptr, + value: UInt256 { inner: chunks }, + } + } + + pub fn allocate_from_closure_and_dependencies_non_pointer< + CS: ConstraintSystem, + FN: FnOnce(&[F]) -> MemoryWitness + 'static + Send + Sync, + >( + cs: &mut CS, + witness_closure: FN, + dependencies: &[Place], + ) -> Self { + let outputs = cs.alloc_multiple_variables_without_values::<8>(); + + if ::WitnessConfig::EVALUATE_WITNESS { + let value_fn = move |inputs: &[F], output_buffer: &mut DstBuffer<'_, '_, F>| { + debug_assert!(F::CAPACITY_BITS >= 32); + let witness = (witness_closure)(inputs); + let chunks = decompose_u256_as_u32x8(witness.value); + output_buffer.extend(chunks.map(|el| F::from_u64_unchecked(el as u64))); + }; + + cs.set_values_with_dependencies_vararg( + &dependencies, + &Place::from_variables(outputs), + value_fn, + ); + } + + let chunks = outputs.map(|el| UInt32::from_variable_checked(cs, el)); + let is_ptr = Boolean::allocated_constant(cs, false); + + Self { + is_ptr, + value: UInt256 { inner: chunks }, + } + } +} + +use boojum::gadgets::queue::full_state_queue::FullStateCircuitQueueWitness; + +pub type MemoryQueryQueue = + FullStateCircuitQueue, AW, SW, CW, MEMORY_QUERY_PACKED_WIDTH, R>; +pub type MemoryQueue = MemoryQueryQueue; + +pub type MemoryQueryQueueWitness = + FullStateCircuitQueueWitness, SW, MEMORY_QUERY_PACKED_WIDTH>; diff --git a/crates/zkevm_circuits/src/base_structures/mod.rs b/crates/zkevm_circuits/src/base_structures/mod.rs new file mode 100644 index 0000000..8374deb --- /dev/null +++ b/crates/zkevm_circuits/src/base_structures/mod.rs @@ -0,0 +1,18 @@ +use boojum::field::SmallField; +use boojum::{cs::traits::cs::ConstraintSystem, gadgets::u8::UInt8}; + +use super::*; + +pub mod decommit_query; +pub mod log_query; +pub mod memory_query; +pub mod recursion_query; +pub mod register; +pub mod vm_state; + +pub mod precompile_input_outputs; +pub mod state_diff_record; + +pub trait ByteSerializable { + fn into_bytes>(&self, cs: &mut CS) -> [UInt8; N]; +} diff --git a/crates/zkevm_circuits/src/base_structures/precompile_input_outputs/mod.rs b/crates/zkevm_circuits/src/base_structures/precompile_input_outputs/mod.rs new file mode 100644 index 0000000..cc31420 --- /dev/null +++ b/crates/zkevm_circuits/src/base_structures/precompile_input_outputs/mod.rs @@ -0,0 +1,52 @@ +use super::*; +// universal precompiles passthrough input/output +// takes requests queue + memory state +// outputs memory state + +use crate::base_structures::vm_state::*; +use boojum::cs::traits::cs::ConstraintSystem; +use boojum::cs::Variable; +use boojum::field::SmallField; +use boojum::gadgets::boolean::Boolean; +use boojum::gadgets::queue::QueueState; +use boojum::gadgets::traits::allocatable::CSAllocatable; +use boojum::gadgets::traits::allocatable::CSPlaceholder; +use boojum::gadgets::traits::auxiliary::PrettyComparison; +use boojum::gadgets::traits::encodable::CircuitVarLengthEncodable; +use boojum::gadgets::traits::selectable::Selectable; +use boojum::gadgets::traits::witnessable::WitnessHookable; +use cs_derive::*; + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +#[DerivePrettyComparison("true")] +pub struct PrecompileFunctionInputData { + pub initial_log_queue_state: QueueState, + pub initial_memory_queue_state: QueueState, +} + +impl CSPlaceholder for PrecompileFunctionInputData { + fn placeholder>(cs: &mut CS) -> Self { + Self { + initial_log_queue_state: QueueState::::placeholder(cs), + initial_memory_queue_state: QueueState::::placeholder( + cs, + ), + } + } +} + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +#[DerivePrettyComparison("true")] +pub struct PrecompileFunctionOutputData { + pub final_memory_state: QueueState, +} + +impl CSPlaceholder for PrecompileFunctionOutputData { + fn placeholder>(cs: &mut CS) -> Self { + Self { + final_memory_state: QueueState::::placeholder(cs), + } + } +} diff --git a/crates/zkevm_circuits/src/base_structures/recursion_query/mod.rs b/crates/zkevm_circuits/src/base_structures/recursion_query/mod.rs new file mode 100644 index 0000000..1d46323 --- /dev/null +++ b/crates/zkevm_circuits/src/base_structures/recursion_query/mod.rs @@ -0,0 +1,110 @@ +use boojum::cs::gates::ConstantAllocatableCS; +use cs_derive::*; + +use crate::fsm_input_output::circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH; + +use super::*; +use boojum::cs::traits::cs::ConstraintSystem; +use boojum::cs::traits::cs::DstBuffer; +use boojum::cs::Variable; +use boojum::field::SmallField; +use boojum::gadgets::boolean::Boolean; +use boojum::gadgets::num::Num; +use boojum::gadgets::traits::allocatable::CSPlaceholder; +use boojum::gadgets::traits::allocatable::{CSAllocatable, CSAllocatableExt}; +use boojum::gadgets::traits::encodable::CircuitVarLengthEncodable; +use boojum::gadgets::traits::encodable::{CircuitEncodable, CircuitEncodableExt}; +use boojum::gadgets::traits::selectable::Selectable; +use boojum::gadgets::traits::witnessable::WitnessHookable; +use boojum::serde_utils::BigArraySerde; + +#[derive(Derivative, CSAllocatable, CSSelectable, WitnessHookable, CSVarLengthEncodable)] +#[derivative(Clone, Copy, Debug)] +pub struct RecursionQuery { + pub circuit_type: Num, + pub input_commitment: [Num; INPUT_OUTPUT_COMMITMENT_LENGTH], +} + +pub const RECURSION_QUERY_PACKED_WIDTH: usize = 8; + +impl CircuitEncodable for RecursionQuery { + fn encode>( + &self, + cs: &mut CS, + ) -> [Variable; RECURSION_QUERY_PACKED_WIDTH] { + let zero = cs.allocate_constant(F::ZERO); + let [t0, t1, t2, t3] = self.input_commitment.map(|el| el.get_variable()); + [ + self.circuit_type.get_variable(), + t0, + t1, + t2, + t3, + zero, + zero, + zero, + ] + } +} + +impl CSAllocatableExt for RecursionQuery { + const INTERNAL_STRUCT_LEN: usize = 5; + + fn witness_from_set_of_values(values: [F; Self::INTERNAL_STRUCT_LEN]) -> Self::Witness { + let circuit_type = values[0]; + + let t0 = values[1]; + let t1 = values[2]; + let t2 = values[3]; + let t3 = values[4]; + + Self::Witness { + circuit_type, + input_commitment: [t0, t1, t2, t3], + } + } + + fn flatten_as_variables(&self) -> [Variable; Self::INTERNAL_STRUCT_LEN] + where + [(); Self::INTERNAL_STRUCT_LEN]:, + { + [ + self.circuit_type.get_variable(), + self.input_commitment[0].get_variable(), + self.input_commitment[1].get_variable(), + self.input_commitment[2].get_variable(), + self.input_commitment[3].get_variable(), + ] + } + fn set_internal_variables_values(witness: Self::Witness, dst: &mut DstBuffer<'_, '_, F>) { + Num::set_internal_variables_values(witness.circuit_type, dst); + for src in witness.input_commitment.into_iter() { + Num::set_internal_variables_values(src, dst); + } + } +} + +impl CircuitEncodableExt for RecursionQuery {} + +impl CSPlaceholder for RecursionQuery { + fn placeholder>(cs: &mut CS) -> Self { + let zero_num = Num::zero(cs); + + Self { + circuit_type: zero_num, + input_commitment: [zero_num; INPUT_OUTPUT_COMMITMENT_LENGTH], + } + } +} + +use boojum::gadgets::queue::full_state_queue::{ + FullStateCircuitQueue, FullStateCircuitQueueWitness, +}; + +pub type RecursionQueryQueue = + FullStateCircuitQueue, AW, SW, CW, RECURSION_QUERY_PACKED_WIDTH, R>; + +pub type RecursionQueue = RecursionQueryQueue; + +pub type RecursionQueueWitness = + FullStateCircuitQueueWitness, SW, RECURSION_QUERY_PACKED_WIDTH>; diff --git a/crates/zkevm_circuits/src/base_structures/register/mod.rs b/crates/zkevm_circuits/src/base_structures/register/mod.rs new file mode 100644 index 0000000..12a33db --- /dev/null +++ b/crates/zkevm_circuits/src/base_structures/register/mod.rs @@ -0,0 +1,86 @@ +use super::*; +use boojum::field::SmallField; +use boojum::gadgets::u256::UInt256; + +use boojum::gadgets::boolean::Boolean; +use boojum::gadgets::u16::UInt16; +use boojum::gadgets::u32::UInt32; + +use boojum::cs::traits::cs::ConstraintSystem; +use boojum::cs::traits::cs::DstBuffer; +use boojum::cs::Variable; +use boojum::gadgets::traits::allocatable::{CSAllocatable, CSAllocatableExt}; +use boojum::gadgets::traits::encodable::CircuitVarLengthEncodable; +use boojum::gadgets::traits::selectable::Selectable; +use boojum::gadgets::traits::witnessable::WitnessHookable; + +use cs_derive::*; + +#[derive(Derivative, CSSelectable, CSAllocatable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug, Hash)] +pub struct VMRegister { + pub is_pointer: Boolean, + pub value: UInt256, +} + +impl VMRegister { + pub fn zero>(cs: &mut CS) -> Self { + let boolean_false = Boolean::allocated_constant(cs, false); + let zero_u256 = UInt256::zero(cs); + + Self { + is_pointer: boolean_false, + value: zero_u256, + } + } + + pub fn from_imm>(cs: &mut CS, imm: UInt16) -> Self { + let boolean_false = Boolean::allocated_constant(cs, false); + let zero_u32 = UInt32::zero(cs); + + Self { + is_pointer: boolean_false, + value: UInt256 { + inner: [ + unsafe { UInt32::from_variable_unchecked(imm.get_variable()) }, + zero_u32, + zero_u32, + zero_u32, + zero_u32, + zero_u32, + zero_u32, + zero_u32, + ], + }, + } + } +} + +impl CSAllocatableExt for VMRegister { + const INTERNAL_STRUCT_LEN: usize = 9; + + fn flatten_as_variables(&self) -> [Variable; Self::INTERNAL_STRUCT_LEN] { + // NOTE: CSAllocatable is done by the macro, so it allocates in the order of declaration, + // and we should do the same here! + + [ + self.is_pointer.get_variable(), + self.value.inner[0].get_variable(), + self.value.inner[1].get_variable(), + self.value.inner[2].get_variable(), + self.value.inner[3].get_variable(), + self.value.inner[4].get_variable(), + self.value.inner[5].get_variable(), + self.value.inner[6].get_variable(), + self.value.inner[7].get_variable(), + ] + } + + fn set_internal_variables_values(_witness: Self::Witness, _dst: &mut DstBuffer<'_, '_, F>) { + todo!() + } + + fn witness_from_set_of_values(_values: [F; Self::INTERNAL_STRUCT_LEN]) -> Self::Witness { + todo!() + } +} diff --git a/crates/zkevm_circuits/src/base_structures/state_diff_record/mod.rs b/crates/zkevm_circuits/src/base_structures/state_diff_record/mod.rs new file mode 100644 index 0000000..b14ffef --- /dev/null +++ b/crates/zkevm_circuits/src/base_structures/state_diff_record/mod.rs @@ -0,0 +1,75 @@ +use super::*; +use boojum::field::SmallField; +use boojum::gadgets::boolean::Boolean; + +use boojum::cs::traits::cs::ConstraintSystem; +use boojum::gadgets::traits::allocatable::CSAllocatable; +use boojum::gadgets::traits::selectable::Selectable; +use boojum::gadgets::traits::witnessable::WitnessHookable; +use boojum::gadgets::u8::UInt8; +use boojum::serde_utils::BigArraySerde; +use cs_derive::*; + +use boojum::gadgets::keccak256::KECCAK_RATE_BYTES; + +pub const STATE_DIFF_RECORD_BYTE_ENCODING_LEN: usize = 20 + 32 + 32 + 8 + 32 + 32; +pub const NUM_KECCAK256_ROUNDS_PER_RECORD_ACCUMULATION: usize = 2; +const _: () = if STATE_DIFF_RECORD_BYTE_ENCODING_LEN + <= KECCAK_RATE_BYTES * NUM_KECCAK256_ROUNDS_PER_RECORD_ACCUMULATION +{ + () +} else { + panic!() +}; + +#[derive(Derivative, CSAllocatable, CSSelectable, WitnessHookable)] +#[derivative(Clone, Copy, Debug, Hash)] +pub struct StateDiffRecord { + pub address: [UInt8; 20], + pub key: [UInt8; 32], + pub derived_key: [UInt8; 32], + pub enumeration_index: [UInt8; 8], + pub initial_value: [UInt8; 32], + pub final_value: [UInt8; 32], +} + +impl StateDiffRecord { + // the only thing we need is byte encoding + pub fn encode>( + &self, + cs: &mut CS, + ) -> [UInt8; STATE_DIFF_RECORD_BYTE_ENCODING_LEN] { + let zero_u8 = UInt8::zero(cs); + let mut encoding = [zero_u8; STATE_DIFF_RECORD_BYTE_ENCODING_LEN]; + let mut offset = 0; + let mut end = 0; + + end += self.address.len(); + encoding[offset..end].copy_from_slice(&self.address); + offset = end; + + end += self.key.len(); + encoding[offset..end].copy_from_slice(&self.key); + offset = end; + + end += self.derived_key.len(); + encoding[offset..end].copy_from_slice(&self.derived_key); + offset = end; + + end += self.enumeration_index.len(); + encoding[offset..end].copy_from_slice(&self.enumeration_index); + offset = end; + + end += self.initial_value.len(); + encoding[offset..end].copy_from_slice(&self.initial_value); + offset = end; + + end += self.final_value.len(); + encoding[offset..end].copy_from_slice(&self.final_value); + offset = end; + + debug_assert_eq!(offset, encoding.len()); + + encoding + } +} diff --git a/crates/zkevm_circuits/src/base_structures/vm_state/callstack.rs b/crates/zkevm_circuits/src/base_structures/vm_state/callstack.rs new file mode 100644 index 0000000..4ab9ac9 --- /dev/null +++ b/crates/zkevm_circuits/src/base_structures/vm_state/callstack.rs @@ -0,0 +1,98 @@ +use super::*; +use boojum::serde_utils::BigArraySerde; + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +#[CSSelectableBound( + "where [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:" +)] +pub struct Callstack { + pub current_context: FullExecutionContext, + pub context_stack_depth: UInt32, + pub stack_sponge_state: [Num; FULL_SPONGE_QUEUE_STATE_WIDTH], +} + +impl Callstack { + pub fn empty>(cs: &mut CS) -> Self { + let zero_u32 = UInt32::zero(cs); + let zero_num = Num::zero(cs); + Self { + current_context: FullExecutionContext::uninitialized(cs), + context_stack_depth: zero_u32, + stack_sponge_state: [zero_num; FULL_SPONGE_QUEUE_STATE_WIDTH], + } + } + + pub fn is_empty>(&self, cs: &mut CS) -> Boolean { + self.context_stack_depth.is_zero(cs) + } + + pub fn is_full>(&self, cs: &mut CS) -> Boolean { + let max_depth = + UInt32::allocated_constant(cs, zkevm_opcode_defs::system_params::VM_MAX_STACK_DEPTH); + UInt32::equals(cs, &self.context_stack_depth, &max_depth) + } +} + +use boojum::gadgets::traits::allocatable::CSAllocatableExt; + +use crate::base_structures::vm_state::saved_context::ExecutionContextRecord; + +// execution context that keeps all explicit data about the current execution frame, +// and avoid recomputing of quantities that also do not change between calls +#[derive(Derivative, CSAllocatable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +pub struct FullExecutionContext { + pub saved_context: ExecutionContextRecord, + pub log_queue_forward_tail: [Num; 4], + pub log_queue_forward_part_length: UInt32, +} + +impl Selectable for FullExecutionContext +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + fn conditionally_select>( + cs: &mut CS, + flag: Boolean, + a: &Self, + b: &Self, + ) -> Self { + let saved_context = ExecutionContextRecord::conditionally_select( + cs, + flag, + &a.saved_context, + &b.saved_context, + ); + let log_queue_forward_tail = Num::parallel_select( + cs, + flag, + &a.log_queue_forward_tail, + &b.log_queue_forward_tail, + ); + let log_queue_forward_part_length = UInt32::conditionally_select( + cs, + flag, + &a.log_queue_forward_part_length, + &b.log_queue_forward_part_length, + ); + + Self { + saved_context, + log_queue_forward_tail, + log_queue_forward_part_length, + } + } +} + +impl FullExecutionContext { + pub fn uninitialized>(cs: &mut CS) -> Self { + let zero_u32 = UInt32::zero(cs); + let zero_num = Num::zero(cs); + Self { + saved_context: ExecutionContextRecord::uninitialized(cs), + log_queue_forward_tail: [zero_num; 4], + log_queue_forward_part_length: zero_u32, + } + } +} diff --git a/crates/zkevm_circuits/src/base_structures/vm_state/mod.rs b/crates/zkevm_circuits/src/base_structures/vm_state/mod.rs new file mode 100644 index 0000000..4147eb0 --- /dev/null +++ b/crates/zkevm_circuits/src/base_structures/vm_state/mod.rs @@ -0,0 +1,171 @@ +use super::register::VMRegister; +use super::*; +use crate::base_structures::vm_state::saved_context::ExecutionContextRecord; +use boojum::cs::traits::cs::ConstraintSystem; +use boojum::cs::Variable; +use boojum::field::SmallField; +use boojum::gadgets::boolean::Boolean; +use boojum::gadgets::num::Num; +use boojum::gadgets::traits::allocatable::*; +use boojum::gadgets::traits::auxiliary::PrettyComparison; +use boojum::gadgets::traits::encodable::CircuitVarLengthEncodable; +use boojum::gadgets::traits::selectable::*; +use boojum::gadgets::traits::witnessable::WitnessHookable; +use boojum::gadgets::u16::UInt16; +use boojum::gadgets::u160::UInt160; +use boojum::gadgets::u256::UInt256; +use boojum::gadgets::u32::UInt32; +use boojum::gadgets::u8::UInt8; +use boojum::serde_utils::BigArraySerde; +use cs_derive::*; + +pub mod callstack; +pub mod saved_context; + +use crate::base_structures::vm_state::callstack::Callstack; + +pub const FULL_SPONGE_QUEUE_STATE_WIDTH: usize = 12; +pub const QUEUE_STATE_WIDTH: usize = 4; + +pub(crate) const REGISTERS_COUNT: usize = 15; + +#[derive(Derivative, CSAllocatable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +pub struct ArithmeticFlagsPort { + pub overflow_or_less_than: Boolean, + pub equal: Boolean, + pub greater_than: Boolean, +} + +impl Selectable for ArithmeticFlagsPort { + fn conditionally_select>( + cs: &mut CS, + flag: Boolean, + a: &Self, + b: &Self, + ) -> Self { + // use parallel select + + let boolean_false = Boolean::allocated_constant(cs, false); + + let a = [ + a.overflow_or_less_than, + a.equal, + a.greater_than, + boolean_false, + ]; + let b = [ + b.overflow_or_less_than, + b.equal, + b.greater_than, + boolean_false, + ]; + + let [overflow_or_less_than, equal, greater_than, _] = + Boolean::parallel_select(cs, flag, &a, &b); + + Self { + overflow_or_less_than, + equal, + greater_than, + } + } +} + +impl ArithmeticFlagsPort { + pub fn reseted_flags>(cs: &mut CS) -> Self { + let boolean_false = Boolean::allocated_constant(cs, false); + Self { + overflow_or_less_than: boolean_false, + equal: boolean_false, + greater_than: boolean_false, + } + } +} + +#[derive(Derivative, CSSelectable, CSAllocatable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +#[CSSelectableBound( + "where [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:" +)] +#[DerivePrettyComparison("true")] +pub struct VmLocalState { + pub previous_code_word: UInt256, + pub registers: [VMRegister; REGISTERS_COUNT], + pub flags: ArithmeticFlagsPort, + pub timestamp: UInt32, + pub memory_page_counter: UInt32, + pub tx_number_in_block: UInt32, + pub previous_code_page: UInt32, + pub previous_super_pc: UInt16, + pub pending_exception: Boolean, + pub ergs_per_pubdata_byte: UInt32, + pub callstack: Callstack, + pub memory_queue_state: [Num; FULL_SPONGE_QUEUE_STATE_WIDTH], + pub memory_queue_length: UInt32, + pub code_decommittment_queue_state: [Num; FULL_SPONGE_QUEUE_STATE_WIDTH], + pub code_decommittment_queue_length: UInt32, + pub context_composite_u128: [UInt32; 4], +} + +impl VmLocalState { + pub fn uninitialized>(cs: &mut CS) -> Self { + let zero_u32 = UInt32::zero(cs); + let zero_u16 = UInt16::zero(cs); + let zero_num = Num::zero(cs); + let boolean_false = Boolean::allocated_constant(cs, false); + let zero_u256 = UInt256::zero(cs); + let callstack = Callstack::empty(cs); + let empty_reg = VMRegister { + is_pointer: boolean_false, + value: zero_u256, + }; + + Self { + previous_code_word: zero_u256, + registers: [empty_reg; REGISTERS_COUNT], + flags: ArithmeticFlagsPort { + overflow_or_less_than: boolean_false, + equal: boolean_false, + greater_than: boolean_false, + }, + timestamp: zero_u32, + memory_page_counter: zero_u32, + tx_number_in_block: zero_u32, + previous_code_page: zero_u32, + previous_super_pc: zero_u16, + pending_exception: boolean_false, + ergs_per_pubdata_byte: zero_u32, + callstack, + memory_queue_state: [zero_num; FULL_SPONGE_QUEUE_STATE_WIDTH], + memory_queue_length: zero_u32, + code_decommittment_queue_state: [zero_num; FULL_SPONGE_QUEUE_STATE_WIDTH], + code_decommittment_queue_length: zero_u32, + context_composite_u128: [zero_u32; 4], + } + } +} + +impl CSPlaceholder for VmLocalState { + fn placeholder>(cs: &mut CS) -> Self { + Self::uninitialized(cs) + } +} + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +pub struct GlobalContext { + pub zkporter_is_available: Boolean, + pub default_aa_code_hash: UInt256, +} + +impl CSPlaceholder for GlobalContext { + fn placeholder>(cs: &mut CS) -> Self { + let boolean_false = Boolean::allocated_constant(cs, false); + let zero_u256 = UInt256::zero(cs); + Self { + zkporter_is_available: boolean_false, + default_aa_code_hash: zero_u256, + } + } +} diff --git a/crates/zkevm_circuits/src/base_structures/vm_state/saved_context.rs b/crates/zkevm_circuits/src/base_structures/vm_state/saved_context.rs new file mode 100644 index 0000000..f51071a --- /dev/null +++ b/crates/zkevm_circuits/src/base_structures/vm_state/saved_context.rs @@ -0,0 +1,548 @@ +use boojum::cs::gates::assert_no_placeholder_variables; +use boojum::cs::traits::cs::DstBuffer; +use boojum::cs::Variable; +use boojum::gadgets::traits::allocatable::CSAllocatableExt; +use boojum::gadgets::traits::castable::WitnessCastable; +use boojum::gadgets::traits::encodable::CircuitEncodable; +use boojum::gadgets::traits::selectable::parallel_select_variables; +use cs_derive::*; +use ethereum_types::Address; + +use super::*; + +// here we store only part of the context that keeps the data that +// needs to be stored or restored between the calls + +// repeated note on how joining of rollback queues work +// - first we use some non-determinism to declare a rollback_tail == current_rollback_head +// - when we do write we add element into front as forward_tail = hash(forward_tail, log_element) +// and also declare some rollback_head, such that current_rollback_head = hash(rollback_head, log_element) +// - if we return "ok" then we join as +// - forward_tail = callee forward_tail +// - rollback_head = callee rollback_head +// - else +// - forward_tail = rollback_tail +// - caller's rollback_head is unchanged +// - require callee forward_tail == rollback_head +// +// so to proceed with joining we need to only maintain +// - global forward_tail and length of the forward segment +// - per-context declared rollback_tail +// - per-context computed rollback segment length +// - per-context rollback_head + +#[derive(Derivative, CSAllocatable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +pub struct ExecutionContextRecord { + pub this: UInt160, // unfortunately delegatecall mangles this field - it can not be restored from callee's caller + pub caller: UInt160, + pub code_address: UInt160, + + pub code_page: UInt32, + pub base_page: UInt32, + + pub heap_upper_bound: UInt32, + pub aux_heap_upper_bound: UInt32, + + pub reverted_queue_head: [Num; 4], + pub reverted_queue_tail: [Num; 4], + pub reverted_queue_segment_len: UInt32, + + pub pc: UInt16, + pub sp: UInt16, + pub exception_handler_loc: UInt16, + pub ergs_remaining: UInt32, + + pub is_static_execution: Boolean, + pub is_kernel_mode: Boolean, + + pub this_shard_id: UInt8, + pub caller_shard_id: UInt8, + pub code_shard_id: UInt8, + + pub context_u128_value_composite: [UInt32; 4], + + pub is_local_call: Boolean, +} + +impl ExecutionContextRecord { + pub fn uninitialized>(cs: &mut CS) -> Self { + let zero_u160 = UInt160::zero(cs); + let zero_u32 = UInt32::zero(cs); + let zero_u16 = UInt16::zero(cs); + let zero_u8 = UInt8::zero(cs); + let zero_num = Num::zero(cs); + let boolean_false = Boolean::allocated_constant(cs, false); + Self { + this: zero_u160, + caller: zero_u160, + code_address: zero_u160, + code_page: zero_u32, + base_page: zero_u32, + + heap_upper_bound: zero_u32, + aux_heap_upper_bound: zero_u32, + + reverted_queue_head: [zero_num; 4], + reverted_queue_tail: [zero_num; 4], + reverted_queue_segment_len: zero_u32, + + pc: zero_u16, + sp: zero_u16, + exception_handler_loc: zero_u16, + ergs_remaining: zero_u32, + + is_static_execution: boolean_false, + is_kernel_mode: boolean_false, + + this_shard_id: zero_u8, + caller_shard_id: zero_u8, + code_shard_id: zero_u8, + + context_u128_value_composite: [zero_u32; 4], + + is_local_call: boolean_false, + } + } +} + +pub const EXECUTION_CONTEXT_RECORD_ENCODING_WIDTH: usize = 32; + +impl CircuitEncodable + for ExecutionContextRecord +{ + fn encode>( + &self, + cs: &mut CS, + ) -> [Variable; EXECUTION_CONTEXT_RECORD_ENCODING_WIDTH] { + debug_assert!(F::CAPACITY_BITS >= 57); + // full field elements first for simplicity + let v0 = self.reverted_queue_head[0].get_variable(); + let v1 = self.reverted_queue_head[1].get_variable(); + let v2 = self.reverted_queue_head[2].get_variable(); + let v3 = self.reverted_queue_head[3].get_variable(); + + let v4 = self.reverted_queue_tail[0].get_variable(); + let v5 = self.reverted_queue_tail[1].get_variable(); + let v6 = self.reverted_queue_tail[2].get_variable(); + let v7 = self.reverted_queue_tail[3].get_variable(); + + let v8 = self.code_address.inner[0].get_variable(); + let v9 = self.code_address.inner[1].get_variable(); + let v10 = self.code_address.inner[2].get_variable(); + let v11 = self.code_address.inner[3].get_variable(); + let v12 = self.code_address.inner[4].get_variable(); + + let v13 = self.this.inner[0].get_variable(); + let v14 = self.this.inner[1].get_variable(); + let v15 = self.this.inner[2].get_variable(); + let v16 = self.this.inner[3].get_variable(); + let v17 = self.this.inner[4].get_variable(); + + let v18 = self.caller.inner[0].get_variable(); + let v19 = self.caller.inner[1].get_variable(); + let v20 = self.caller.inner[2].get_variable(); + let v21 = self.caller.inner[3].get_variable(); + let v22 = self.caller.inner[4].get_variable(); + + let v23 = self.context_u128_value_composite[0].get_variable(); + let v24 = self.context_u128_value_composite[1].get_variable(); + let v25 = self.context_u128_value_composite[2].get_variable(); + let v26 = self.context_u128_value_composite[3].get_variable(); + + // now we have left + // - code_page + // - base_page + // - heap_upper_bound + // - aux_heap_upper_bound + // - ergs_remaining + // - sp + // - pc + // - eh + // - reverted_queue_segment_len + // - shard ids + // - few boolean flags + + // as usual, take u32 and add something on top + + let v27 = Num::linear_combination( + cs, + &[ + (self.code_page.get_variable(), F::ONE), + (self.pc.get_variable(), F::from_u64_unchecked(1u64 << 32)), + ( + self.this_shard_id.get_variable(), + F::from_u64_unchecked(1u64 << 48), + ), + ( + self.is_static_execution.get_variable(), + F::from_u64_unchecked(1u64 << 56), + ), + ], + ) + .get_variable(); + + let v28 = Num::linear_combination( + cs, + &[ + (self.base_page.get_variable(), F::ONE), + (self.sp.get_variable(), F::from_u64_unchecked(1u64 << 32)), + ( + self.caller_shard_id.get_variable(), + F::from_u64_unchecked(1u64 << 48), + ), + ( + self.is_kernel_mode.get_variable(), + F::from_u64_unchecked(1u64 << 56), + ), + ], + ) + .get_variable(); + + let v29 = Num::linear_combination( + cs, + &[ + (self.ergs_remaining.get_variable(), F::ONE), + ( + self.exception_handler_loc.get_variable(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + self.code_shard_id.get_variable(), + F::from_u64_unchecked(1u64 << 48), + ), + ( + self.is_local_call.get_variable(), + F::from_u64_unchecked(1u64 << 56), + ), + ], + ) + .get_variable(); + + // now we have left + // - heap_upper_bound + // - aux_heap_upper_bound + // - reverted_queue_segment_len + + let reverted_queue_segment_len_decomposition = + self.reverted_queue_segment_len.decompose_into_bytes(cs); + let v30 = Num::linear_combination( + cs, + &[ + (self.heap_upper_bound.get_variable(), F::ONE), + ( + reverted_queue_segment_len_decomposition[0].get_variable(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + reverted_queue_segment_len_decomposition[1].get_variable(), + F::from_u64_unchecked(1u64 << 40), + ), + ], + ) + .get_variable(); + + let v31 = Num::linear_combination( + cs, + &[ + (self.aux_heap_upper_bound.get_variable(), F::ONE), + ( + reverted_queue_segment_len_decomposition[2].get_variable(), + F::from_u64_unchecked(1u64 << 32), + ), + ( + reverted_queue_segment_len_decomposition[3].get_variable(), + F::from_u64_unchecked(1u64 << 40), + ), + ], + ) + .get_variable(); + + [ + v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, + v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, + ] + } +} + +// we also need allocate extended + +impl CSAllocatableExt for ExecutionContextRecord { + const INTERNAL_STRUCT_LEN: usize = 42; + + fn create_without_value>(cs: &mut CS) -> Self { + // TODO: use more optimal allocation for bytes + CSAllocatable::allocate_without_value(cs) + } + + fn flatten_as_variables(&self) -> [Variable; Self::INTERNAL_STRUCT_LEN] { + [ + self.this.inner[0].get_variable(), + self.this.inner[1].get_variable(), + self.this.inner[2].get_variable(), + self.this.inner[3].get_variable(), + self.this.inner[4].get_variable(), + self.caller.inner[0].get_variable(), + self.caller.inner[1].get_variable(), + self.caller.inner[2].get_variable(), + self.caller.inner[3].get_variable(), + self.caller.inner[4].get_variable(), + self.code_address.inner[0].get_variable(), + self.code_address.inner[1].get_variable(), + self.code_address.inner[2].get_variable(), + self.code_address.inner[3].get_variable(), + self.code_address.inner[4].get_variable(), + self.code_page.get_variable(), + self.base_page.get_variable(), + self.heap_upper_bound.get_variable(), + self.aux_heap_upper_bound.get_variable(), + self.reverted_queue_head[0].get_variable(), + self.reverted_queue_head[1].get_variable(), + self.reverted_queue_head[2].get_variable(), + self.reverted_queue_head[3].get_variable(), + self.reverted_queue_tail[0].get_variable(), + self.reverted_queue_tail[1].get_variable(), + self.reverted_queue_tail[2].get_variable(), + self.reverted_queue_tail[3].get_variable(), + self.reverted_queue_segment_len.get_variable(), + self.pc.get_variable(), + self.sp.get_variable(), + self.exception_handler_loc.get_variable(), + self.ergs_remaining.get_variable(), + self.is_static_execution.get_variable(), + self.is_kernel_mode.get_variable(), + self.this_shard_id.get_variable(), + self.caller_shard_id.get_variable(), + self.code_shard_id.get_variable(), + self.context_u128_value_composite[0].get_variable(), + self.context_u128_value_composite[1].get_variable(), + self.context_u128_value_composite[2].get_variable(), + self.context_u128_value_composite[3].get_variable(), + self.is_local_call.get_variable(), + ] + } + + fn from_variables_set(variables: [Variable; Self::INTERNAL_STRUCT_LEN]) -> Self { + unsafe { + Self { + this: UInt160::from_variables_unchecked([ + variables[0], + variables[1], + variables[2], + variables[3], + variables[4], + ]), + caller: UInt160::from_variables_unchecked([ + variables[5], + variables[6], + variables[7], + variables[8], + variables[9], + ]), + code_address: UInt160::from_variables_unchecked([ + variables[10], + variables[11], + variables[12], + variables[13], + variables[14], + ]), + code_page: UInt32::from_variable_unchecked(variables[15]), + base_page: UInt32::from_variable_unchecked(variables[16]), + + heap_upper_bound: UInt32::from_variable_unchecked(variables[17]), + aux_heap_upper_bound: UInt32::from_variable_unchecked(variables[18]), + + reverted_queue_head: [variables[19], variables[20], variables[21], variables[22]] + .map(|el| Num::from_variable(el)), + + reverted_queue_tail: [variables[23], variables[24], variables[25], variables[26]] + .map(|el| Num::from_variable(el)), + + reverted_queue_segment_len: UInt32::from_variable_unchecked(variables[27]), + + pc: UInt16::from_variable_unchecked(variables[28]), + sp: UInt16::from_variable_unchecked(variables[29]), + exception_handler_loc: UInt16::from_variable_unchecked(variables[30]), + ergs_remaining: UInt32::from_variable_unchecked(variables[31]), + + is_static_execution: Boolean::from_variable_unchecked(variables[32]), + is_kernel_mode: Boolean::from_variable_unchecked(variables[33]), + + this_shard_id: UInt8::from_variable_unchecked(variables[34]), + caller_shard_id: UInt8::from_variable_unchecked(variables[35]), + code_shard_id: UInt8::from_variable_unchecked(variables[36]), + + context_u128_value_composite: [ + variables[37], + variables[38], + variables[39], + variables[40], + ] + .map(|el| UInt32::from_variable_unchecked(el)), + + is_local_call: Boolean::from_variable_unchecked(variables[41]), + } + } + } + + fn set_internal_variables_values(witness: Self::Witness, dst: &mut DstBuffer<'_, '_, F>) { + let src = WitnessCastable::cast_into_source(witness.this); + dst.extend(src); + + let src = WitnessCastable::cast_into_source(witness.caller); + dst.extend(src); + + let src = WitnessCastable::cast_into_source(witness.code_address); + dst.extend(src); + + dst.push(WitnessCastable::cast_into_source(witness.code_page)); + dst.push(WitnessCastable::cast_into_source(witness.base_page)); + dst.push(WitnessCastable::cast_into_source(witness.heap_upper_bound)); + dst.push(WitnessCastable::cast_into_source( + witness.aux_heap_upper_bound, + )); + + dst.extend(witness.reverted_queue_head); + dst.extend(witness.reverted_queue_tail); + dst.push(WitnessCastable::cast_into_source( + witness.reverted_queue_segment_len, + )); + + dst.push(WitnessCastable::cast_into_source(witness.pc)); + dst.push(WitnessCastable::cast_into_source(witness.sp)); + dst.push(WitnessCastable::cast_into_source( + witness.exception_handler_loc, + )); + dst.push(WitnessCastable::cast_into_source(witness.ergs_remaining)); + + dst.push(WitnessCastable::cast_into_source( + witness.is_static_execution, + )); + dst.push(WitnessCastable::cast_into_source(witness.is_kernel_mode)); + dst.push(WitnessCastable::cast_into_source(witness.this_shard_id)); + dst.push(WitnessCastable::cast_into_source(witness.caller_shard_id)); + dst.push(WitnessCastable::cast_into_source(witness.code_shard_id)); + + dst.extend(WitnessCastable::cast_into_source( + witness.context_u128_value_composite, + )); + + dst.push(WitnessCastable::cast_into_source(witness.is_local_call)); + } + + fn witness_from_set_of_values(values: [F; Self::INTERNAL_STRUCT_LEN]) -> Self::Witness { + let this: Address = WitnessCastable::cast_from_source([ + values[0], values[1], values[2], values[3], values[4], + ]); + + let caller: Address = WitnessCastable::cast_from_source([ + values[5], values[6], values[7], values[8], values[9], + ]); + + let code_address: Address = WitnessCastable::cast_from_source([ + values[10], values[11], values[12], values[13], values[14], + ]); + + let code_page: u32 = WitnessCastable::cast_from_source(values[15]); + let base_page: u32 = WitnessCastable::cast_from_source(values[16]); + + let heap_upper_bound: u32 = WitnessCastable::cast_from_source(values[17]); + let aux_heap_upper_bound: u32 = WitnessCastable::cast_from_source(values[18]); + + let reverted_queue_head = [values[19], values[20], values[21], values[22]]; + + let reverted_queue_tail = [values[23], values[24], values[25], values[26]]; + + let reverted_queue_segment_len: u32 = WitnessCastable::cast_from_source(values[27]); + + let pc: u16 = WitnessCastable::cast_from_source(values[28]); + let sp: u16 = WitnessCastable::cast_from_source(values[29]); + let exception_handler_loc: u16 = WitnessCastable::cast_from_source(values[30]); + + let ergs_remaining: u32 = WitnessCastable::cast_from_source(values[31]); + + let is_static_execution: bool = WitnessCastable::cast_from_source(values[32]); + let is_kernel_mode: bool = WitnessCastable::cast_from_source(values[33]); + + let this_shard_id: u8 = WitnessCastable::cast_from_source(values[34]); + let caller_shard_id: u8 = WitnessCastable::cast_from_source(values[35]); + let code_shard_id: u8 = WitnessCastable::cast_from_source(values[36]); + + let context_u128_value_composite: [u32; 4] = + WitnessCastable::cast_from_source([values[37], values[38], values[39], values[40]]); + + let is_local_call: bool = WitnessCastable::cast_from_source(values[41]); + + Self::Witness { + this, + caller, + code_address, + + code_page, + base_page, + + heap_upper_bound, + aux_heap_upper_bound, + + reverted_queue_head, + reverted_queue_tail, + reverted_queue_segment_len, + + pc, + sp, + exception_handler_loc, + ergs_remaining, + + is_static_execution, + is_kernel_mode, + + this_shard_id, + caller_shard_id, + code_shard_id, + + context_u128_value_composite, + + is_local_call, + } + } +} + +impl Selectable for ExecutionContextRecord +where + [(); Self::INTERNAL_STRUCT_LEN]:, +{ + fn conditionally_select>( + cs: &mut CS, + flag: Boolean, + a: &Self, + b: &Self, + ) -> Self { + let a_as_variables = a.flatten_as_variables(); + let b_as_variables = b.flatten_as_variables(); + + let mut dst = [Variable::placeholder(); ExecutionContextRecord::::INTERNAL_STRUCT_LEN]; + + let it = a_as_variables + .into_iter() + .zip(b_as_variables.into_iter()) + .zip(dst.iter_mut()) + .filter_map(|((a, b), dst)| { + if a == b { + // skip and assign any + *dst = a; + + None + } else { + Some(((a, b), dst)) + } + }); + + parallel_select_variables(cs, flag, it); + + // cast back + + assert_no_placeholder_variables(&dst); + + Self::from_variables_set(dst) + } +} diff --git a/crates/zkevm_circuits/src/code_unpacker_sha256/input.rs b/crates/zkevm_circuits/src/code_unpacker_sha256/input.rs new file mode 100644 index 0000000..51148cd --- /dev/null +++ b/crates/zkevm_circuits/src/code_unpacker_sha256/input.rs @@ -0,0 +1,140 @@ +use crate::base_structures::vm_state::*; +use crate::ethereum_types::U256; +use boojum::cs::{traits::cs::ConstraintSystem, Variable}; +use boojum::field::SmallField; +use boojum::gadgets::traits::auxiliary::PrettyComparison; +use boojum::gadgets::{ + boolean::Boolean, + queue::*, + traits::{ + allocatable::*, encodable::CircuitVarLengthEncodable, selectable::Selectable, + witnessable::WitnessHookable, + }, + u16::UInt16, + u256::UInt256, + u32::UInt32, +}; +use boojum::serde_utils::BigArraySerde; +use cs_derive::*; +use derivative::*; + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +pub struct CodeDecommittmentFSM { + pub sha256_inner_state: [UInt32; 8], // 8 uint32 words of internal sha256 state + pub hash_to_compare_against: UInt256, + pub current_index: UInt32, + pub current_page: UInt32, + pub timestamp: UInt32, + pub num_rounds_left: UInt16, + pub length_in_bits: UInt32, + pub state_get_from_queue: Boolean, + pub state_decommit: Boolean, + pub finished: Boolean, +} + +impl CSPlaceholder for CodeDecommittmentFSM { + fn placeholder>(cs: &mut CS) -> Self { + let bool_false = Boolean::allocated_constant(cs, false); + let zero_uint16 = UInt16::zero(cs); + let zero_uint32 = UInt32::zero(cs); + let zero_uint256 = UInt256::zero(cs); + + Self { + sha256_inner_state: [zero_uint32; 8], + hash_to_compare_against: zero_uint256, + current_index: zero_uint32, + current_page: zero_uint32, + timestamp: zero_uint32, + num_rounds_left: zero_uint16, + length_in_bits: zero_uint32, + state_get_from_queue: bool_false, + state_decommit: bool_false, + finished: bool_false, + } + } +} + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +#[DerivePrettyComparison("true")] +pub struct CodeDecommitterFSMInputOutput { + pub internal_fsm: CodeDecommittmentFSM, + pub decommittment_requests_queue_state: QueueState, + pub memory_queue_state: QueueState, +} + +impl CSPlaceholder for CodeDecommitterFSMInputOutput { + fn placeholder>(cs: &mut CS) -> Self { + Self { + internal_fsm: CodeDecommittmentFSM::::placeholder(cs), + decommittment_requests_queue_state: + QueueState::::placeholder(cs), + memory_queue_state: QueueState::::placeholder(cs), + } + } +} + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +pub struct CodeDecommitterInputData { + pub memory_queue_initial_state: QueueState, + pub sorted_requests_queue_initial_state: QueueState, +} + +impl CSPlaceholder for CodeDecommitterInputData { + fn placeholder>(cs: &mut CS) -> Self { + Self { + memory_queue_initial_state: QueueState::::placeholder( + cs, + ), + sorted_requests_queue_initial_state: + QueueState::::placeholder(cs), + } + } +} + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +#[DerivePrettyComparison("true")] +pub struct CodeDecommitterOutputData { + pub memory_queue_final_state: QueueState, +} + +impl CSPlaceholder for CodeDecommitterOutputData { + fn placeholder>(cs: &mut CS) -> Self { + Self { + memory_queue_final_state: QueueState::::placeholder( + cs, + ), + } + } +} + +pub type CodeDecommitterCycleInputOutput = crate::fsm_input_output::ClosedFormInput< + F, + CodeDecommitterFSMInputOutput, + CodeDecommitterInputData, + CodeDecommitterOutputData, +>; +pub type CodeDecommitterCycleInputOutputWitness = + crate::fsm_input_output::ClosedFormInputWitness< + F, + CodeDecommitterFSMInputOutput, + CodeDecommitterInputData, + CodeDecommitterOutputData, + >; + +use crate::code_unpacker_sha256::full_state_queue::FullStateCircuitQueueRawWitness; +use crate::code_unpacker_sha256::{DecommitQuery, DECOMMIT_QUERY_PACKED_WIDTH}; + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Debug, Default)] +#[serde(bound = "")] +pub struct CodeDecommitterCircuitInstanceWitness { + pub closed_form_input: CodeDecommitterCycleInputOutputWitness, + + pub sorted_requests_queue_witness: + FullStateCircuitQueueRawWitness, 12, DECOMMIT_QUERY_PACKED_WIDTH>, + pub code_words: Vec>, +} diff --git a/crates/zkevm_circuits/src/code_unpacker_sha256/mod.rs b/crates/zkevm_circuits/src/code_unpacker_sha256/mod.rs new file mode 100644 index 0000000..5c555a0 --- /dev/null +++ b/crates/zkevm_circuits/src/code_unpacker_sha256/mod.rs @@ -0,0 +1,716 @@ +pub mod input; + +use input::*; + +use crate::ethereum_types::U256; +use std::collections::VecDeque; +use std::sync::{Arc, RwLock}; + +use crate::base_structures::vm_state::FULL_SPONGE_QUEUE_STATE_WIDTH; +use crate::base_structures::{decommit_query::*, memory_query::*}; +use boojum::algebraic_props::round_function::AlgebraicRoundFunction; +use boojum::cs::{gates::*, traits::cs::ConstraintSystem}; +use boojum::field::SmallField; +use boojum::gadgets::sha256::round_function::round_function_over_uint32; +use boojum::gadgets::traits::round_function::CircuitRoundFunction; +use boojum::gadgets::{ + boolean::Boolean, + num::Num, + queue::*, + traits::{ + allocatable::{CSAllocatable, CSAllocatableExt}, + selectable::Selectable, + }, + u16::UInt16, + u256::UInt256, + u32::UInt32, +}; + +use crate::fsm_input_output::{circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH, *}; + +use crate::storage_application::ConditionalWitnessAllocator; + +pub fn unpack_code_into_memory_entry_point< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, +>( + cs: &mut CS, + witness: CodeDecommitterCircuitInstanceWitness, + round_function: &R, + limit: usize, +) -> [Num; INPUT_OUTPUT_COMMITMENT_LENGTH] +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); UInt256::::INTERNAL_STRUCT_LEN]:, + [(); UInt256::::INTERNAL_STRUCT_LEN + 1]:, +{ + let CodeDecommitterCircuitInstanceWitness { + closed_form_input, + sorted_requests_queue_witness, + code_words, + } = witness; + + let code_words: VecDeque = code_words.into_iter().flatten().collect(); + + let mut structured_input = + CodeDecommitterCycleInputOutput::alloc_ignoring_outputs(cs, closed_form_input.clone()); + + let requests_queue_state = QueueState::conditionally_select( + cs, + structured_input.start_flag, + &structured_input + .observable_input + .sorted_requests_queue_initial_state, + &structured_input + .hidden_fsm_input + .decommittment_requests_queue_state, + ); + + let mut requests_queue = DecommitQueue::::from_state(cs, requests_queue_state); + + use crate::code_unpacker_sha256::full_state_queue::FullStateCircuitQueueWitness; + requests_queue.witness = Arc::new(FullStateCircuitQueueWitness::from_inner_witness( + sorted_requests_queue_witness, + )); + + let memory_queue_state = QueueState::conditionally_select( + cs, + structured_input.start_flag, + &structured_input.observable_input.memory_queue_initial_state, + &structured_input.hidden_fsm_input.memory_queue_state, + ); + + let mut memory_queue = MemoryQueryQueue::::from_state(cs, memory_queue_state); + + use boojum::gadgets::traits::allocatable::CSPlaceholder; + let mut starting_fsm_state = CodeDecommittmentFSM::placeholder(cs); + starting_fsm_state.state_get_from_queue = Boolean::allocated_constant(cs, true); + + let initial_state = CodeDecommittmentFSM::conditionally_select( + cs, + structured_input.start_flag, + &starting_fsm_state, + &structured_input.hidden_fsm_input.internal_fsm, + ); + + let code_words_allocator = ConditionalWitnessAllocator::> { + witness_source: Arc::new(RwLock::new(code_words)), + }; + + let final_state = unpack_code_into_memory_inner( + cs, + &mut memory_queue, + &mut requests_queue, + initial_state, + code_words_allocator, + round_function, + limit, + ); + + let final_memory_state = memory_queue.into_state(); + let final_requets_state = requests_queue.into_state(); + // form the final state + let done = final_state.finished; + structured_input.completion_flag = done; + structured_input.observable_output = CodeDecommitterOutputData::placeholder(cs); + + structured_input.observable_output.memory_queue_final_state = QueueState::conditionally_select( + cs, + structured_input.completion_flag, + &final_memory_state, + &structured_input.observable_output.memory_queue_final_state, + ); + + structured_input.hidden_fsm_output.internal_fsm = final_state; + structured_input + .hidden_fsm_output + .decommittment_requests_queue_state = final_requets_state; + structured_input.hidden_fsm_output.memory_queue_state = final_memory_state; + + // self-check + structured_input.hook_compare_witness(cs, &closed_form_input); + + let compact_form = + ClosedFormInputCompactForm::from_full_form(cs, &structured_input, round_function); + + let input_commitment = commit_variable_length_encodable_item(cs, &compact_form, round_function); + for el in input_commitment.iter() { + let gate = PublicInputGate::new(el.get_variable()); + gate.add_to_cs(cs); + } + + input_commitment +} + +// we take a request to decommit hash H into memory page X. Following our internal conventions +// we decommit individual elements starting from the index 1 in the page, and later on set a full length +// into index 0. All elements are 32 bytes +pub fn unpack_code_into_memory_inner< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, +>( + cs: &mut CS, + memory_queue: &mut MemoryQueue, + unpack_requests_queue: &mut DecommitQueue, + initial_state: CodeDecommittmentFSM, + code_word_witness: ConditionalWitnessAllocator>, + _round_function: &R, + limit: usize, +) -> CodeDecommittmentFSM +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); UInt256::::INTERNAL_STRUCT_LEN]:, + [(); UInt256::::INTERNAL_STRUCT_LEN + 1]:, +{ + assert!(limit <= u32::MAX as usize); + + // const POP_QUEUE_OR_WRITE_ID: u64 = 0; + // const FINALIZE_SHA256: u64 = 1; + + let mut state = initial_state; + + let mut half = F::ONE; + half.double(); + half = half.inverse().unwrap(); + let half_num = Num::allocated_constant(cs, half); + + let words_to_bits = UInt32::allocated_constant(cs, 32 * 8); + + let initial_state_uint32 = boojum::gadgets::sha256::ivs_as_uint32(cs); + + let boolean_false = Boolean::allocated_constant(cs, false); + let boolean_true = Boolean::allocated_constant(cs, true); + + let zero_u32 = UInt32::zero(cs); + + use zkevm_opcode_defs::VersionedHashDef; + let versioned_hash_top_16_bits = + (zkevm_opcode_defs::versioned_hash::ContractCodeSha256::VERSION_BYTE as u16) << 8; + let versioned_hash_top_16_bits = UInt16::allocated_constant(cs, versioned_hash_top_16_bits); + + for _cycle in 0..limit { + // we need exactly 3 sponges per cycle: + // - two memory reads when we work on the existing decommittment + // - and may be queue pop before it + let (may_be_new_request, _) = + unpack_requests_queue.pop_front(cs, state.state_get_from_queue); + + let hash = may_be_new_request.code_hash; + + let chunks = decompose_uint32_to_uint16s(cs, &hash.inner[7]); + + let version_hash_matches = UInt16::equals(cs, &chunks[1], &versioned_hash_top_16_bits); + // if we did get a fresh request from queue we expect it with a proper version bytes + version_hash_matches.conditionally_enforce_true(cs, state.state_get_from_queue); + + let uint_16_one = UInt16::allocated_constant(cs, 1); + let length_in_words = chunks[0]; + let length_in_words = UInt16::conditionally_select( + cs, + state.state_get_from_queue, + &length_in_words, + &uint_16_one, + ); + + let length_in_rounds = unsafe { length_in_words.increment_unchecked(cs) }; + + let length_in_rounds = length_in_rounds.into_num().mul(cs, &half_num); + // length is always a multiple of 2 since we decided so + + let length_in_rounds = UInt16::from_variable_checked(cs, length_in_rounds.get_variable()); + + let length_in_bits_may_be = unsafe { + UInt32::from_variable_unchecked(length_in_words.get_variable()) + .non_widening_mul(cs, &words_to_bits) + }; + + // turn over the endianess + // we IGNORE the highest 4 bytes + let uint32_zero = UInt32::allocated_constant(cs, 0); + let mut cutted_hash = hash; + cutted_hash.inner[7] = uint32_zero; + + state.num_rounds_left = UInt16::conditionally_select( + cs, + state.state_get_from_queue, + &length_in_rounds, + &state.num_rounds_left, + ); + state.length_in_bits = UInt32::conditionally_select( + cs, + state.state_get_from_queue, + &length_in_bits_may_be, + &state.length_in_bits, + ); + state.timestamp = UInt32::conditionally_select( + cs, + state.state_get_from_queue, + &may_be_new_request.timestamp, + &state.timestamp, + ); + state.current_page = UInt32::conditionally_select( + cs, + state.state_get_from_queue, + &may_be_new_request.page, + &state.current_page, + ); + state.hash_to_compare_against = UInt256::conditionally_select( + cs, + state.state_get_from_queue, + &cutted_hash, + &state.hash_to_compare_against, + ); + state.current_index = UInt32::conditionally_select( + cs, + state.state_get_from_queue, + &uint32_zero, + &state.current_index, + ); + state.sha256_inner_state = <[UInt32; 8]>::conditionally_select( + cs, + state.state_get_from_queue, + &initial_state_uint32, + &state.sha256_inner_state, + ); + + // we decommit if we either decommit or just got a new request + state.state_decommit = state.state_decommit.or(cs, state.state_get_from_queue); + state.state_get_from_queue = boolean_false; + + // even though it's not that useful, we will do it in a checked way for ease of witness + let may_be_num_rounds_left = unsafe { state.num_rounds_left.decrement_unchecked(cs) }; + state.num_rounds_left = UInt16::conditionally_select( + cs, + state.state_decommit, + &may_be_num_rounds_left, + &state.num_rounds_left, + ); + + let last_round = state.num_rounds_left.is_zero(cs); + let finalize = last_round.and(cs, state.state_decommit); + let not_last_round = last_round.negated(cs); + let process_second_word = not_last_round.and(cs, state.state_decommit); + + // we either pop from the queue, or absorb-decommit, or finalize hash + let code_word_0 = code_word_witness.conditionally_allocate(cs, state.state_decommit); + let code_word_0_be_bytes = code_word_0.to_be_bytes(cs); + + // NOTE: we have to enforce a sequence of access to witness, so we always wait for code_word_0 to be resolved + let code_word_1 = code_word_witness.conditionally_allocate_biased( + cs, + process_second_word, + code_word_0.inner[0].get_variable(), + ); + let code_word_1_be_bytes = code_word_1.to_be_bytes(cs); + + // perform two writes. It's never a "pointer" type + let mem_query_0 = MemoryQuery { + timestamp: state.timestamp, + memory_page: state.current_page, + index: state.current_index, + rw_flag: boolean_true, + value: code_word_0, + is_ptr: boolean_false, + }; + + let state_index_incremented = unsafe { state.current_index.increment_unchecked(cs) }; + + state.current_index = UInt32::conditionally_select( + cs, + state.state_decommit, + &state_index_incremented, + &state.current_index, + ); + + let mem_query_1 = MemoryQuery { + timestamp: state.timestamp, + memory_page: state.current_page, + index: state.current_index, + rw_flag: boolean_true, + value: code_word_1, + is_ptr: boolean_false, + }; + + // even if we do not write in practice then we will never use next value too + + let state_index_incremented = unsafe { state.current_index.increment_unchecked(cs) }; + + state.current_index = UInt32::conditionally_select( + cs, + process_second_word, + &state_index_incremented, + &state.current_index, + ); + + memory_queue.push(cs, mem_query_0, state.state_decommit); + memory_queue.push(cs, mem_query_1, process_second_word); + + // mind endianess! + let mut sha256_input = [zero_u32; 16]; + for (dst, src) in sha256_input.iter_mut().zip( + code_word_0_be_bytes + .array_chunks::<4>() + .chain(code_word_1_be_bytes.array_chunks::<4>()), + ) { + *dst = UInt32::from_be_bytes(cs, *src); + } + + // then conditionally form the second half of the block + + let mut sha256_padding = [zero_u32; 8]; + + // padding of single byte of 1<<7 and some zeroes after, and interpret it as BE integer + sha256_padding[0] = UInt32::allocated_constant(cs, 1 << 31); + // last word is just number of bits + sha256_padding[7] = state.length_in_bits; + + assert_eq!(sha256_input.len(), 16); + + for (dst, src) in sha256_input[8..].iter_mut().zip(sha256_padding.iter()) { + *dst = UInt32::conditionally_select(cs, finalize, src, dst); + } + + let sha256_input: [_; 16] = sha256_input.try_into().unwrap(); + + let mut new_internal_state = state.sha256_inner_state; + round_function_over_uint32(cs, &mut new_internal_state, &sha256_input); + + state.sha256_inner_state = <[UInt32; 8]>::conditionally_select( + cs, + state.state_decommit, + &new_internal_state, + &state.sha256_inner_state, + ); + + // make it into uint256, and do not forget to ignore highest four bytes + let hash = UInt256 { + inner: [ + new_internal_state[7], + new_internal_state[6], + new_internal_state[5], + new_internal_state[4], + new_internal_state[3], + new_internal_state[2], + new_internal_state[1], + UInt32::allocated_constant(cs, 0), + ], + }; + + for (part_of_first, part_of_second) in hash + .inner + .iter() + .zip(state.hash_to_compare_against.inner.iter()) + { + Num::conditionally_enforce_equal( + cs, + finalize, + &part_of_first.into_num(), + &part_of_second.into_num(), + ); + } + + // finish + let is_empty = unpack_requests_queue.is_empty(cs); + let not_empty = is_empty.negated(cs); + let done = is_empty.and(cs, finalize); + state.finished = state.finished.or(cs, done); + let proceed_next = not_empty.and(cs, finalize); + state.state_get_from_queue = proceed_next; + let continue_decommit = process_second_word; + state.state_decommit = continue_decommit; + } + + unpack_requests_queue.enforce_consistency(cs); + + state +} + +fn decompose_uint32_to_uint16s>( + cs: &mut CS, + value: &UInt32, +) -> [UInt16; 2] { + let [byte_0, byte_1, byte_2, byte_3] = value.decompose_into_bytes(cs); + + [ + UInt16::from_le_bytes(cs, [byte_0, byte_1]), + UInt16::from_le_bytes(cs, [byte_2, byte_3]), + ] +} + +#[cfg(test)] +mod tests { + use crate::base_structures::decommit_query; + + use super::*; + use crate::base_structures::vm_state::FULL_SPONGE_QUEUE_STATE_WIDTH; + use crate::ethereum_types::{Address, U256}; + use boojum::algebraic_props::poseidon2_parameters::Poseidon2GoldilocksExternalMatrix; + use boojum::cs::implementations::reference_cs::CSDevelopmentAssembly; + use boojum::cs::traits::gate::GatePlacementStrategy; + use boojum::cs::CSGeometry; + use boojum::cs::*; + use boojum::field::goldilocks::GoldilocksField; + use boojum::gadgets::queue::full_state_queue::FullStateCircuitQueueWitness; + use boojum::gadgets::tables::*; + use boojum::gadgets::traits::allocatable::{CSAllocatable, CSPlaceholder}; + use boojum::gadgets::u160::UInt160; + use boojum::gadgets::u256::UInt256; + use boojum::gadgets::u8::UInt8; + use boojum::implementations::poseidon2::Poseidon2Goldilocks; + use boojum::worker::Worker; + + type F = GoldilocksField; + type P = GoldilocksField; + + #[test] + fn test_code_unpacker_inner() { + // Create a constraint system with proper configuration + let geometry = CSGeometry { + num_columns_under_copy_permutation: 100, + num_witness_columns: 0, + num_constant_columns: 8, + max_allowed_constraint_degree: 4, + }; + + use boojum::cs::cs_builder::*; + + fn configure< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + let builder = builder.allow_lookup( + LookupParameters::UseSpecializedColumnsWithTableIdAsConstant { + width: 4, + num_repetitions: 8, + share_table_id: true, + }, + ); + let builder = ConstantsAllocatorGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = FmaGateInBaseFieldWithoutConstant::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ReductionGate::::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = BooleanConstraintGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<32>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<16>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = SelectionGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ZeroCheckGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + false, + ); + let builder = DotProductGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = MatrixMultiplicationGate::::configure_builder(builder,GatePlacementStrategy::UseGeneralPurposeColumns); + let builder = NopGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + + builder + } + + use boojum::config::DevCSConfig; + use boojum::cs::cs_builder_reference::CsReferenceImplementationBuilder; + + let builder_impl = + CsReferenceImplementationBuilder::::new(geometry, 1 << 26, 1 << 20); + use boojum::cs::cs_builder::new_builder; + let builder = new_builder::<_, F>(builder_impl); + + let builder = configure(builder); + let mut owned_cs = builder.build(()); + + let table = create_maj4_table(); + owned_cs.add_lookup_table::(table); + + let table = create_tri_xor_table(); + owned_cs.add_lookup_table::(table); + + let table = create_ch4_table(); + owned_cs.add_lookup_table::(table); + + let table = create_4bit_chunk_split_table::(); + owned_cs.add_lookup_table::, 4>(table); + let table = create_4bit_chunk_split_table::(); + owned_cs.add_lookup_table::, 4>(table); + + let cs = &mut owned_cs; + + // Create inputs for the inner function + let execute = Boolean::allocated_constant(cs, true); + let mut memory_queue = MemoryQueryQueue::::empty(cs); + let mut decommit_queue = DecommitQueue::::empty(cs); + + let decommit_queue_witness = create_request_queue_witness(cs); + for el in decommit_queue_witness { + decommit_queue.push(cs, el, execute); + } + + let round_function = Poseidon2Goldilocks; + let limit = 40; + + let mut starting_fsm_state = CodeDecommittmentFSM::placeholder(cs); + starting_fsm_state.state_get_from_queue = Boolean::allocated_constant(cs, true); + + let word_witness = create_witness_allocator(cs); + + // Run the inner function + let _final_state = unpack_code_into_memory_inner( + cs, + &mut memory_queue, + &mut decommit_queue, + starting_fsm_state, + word_witness, + &round_function, + limit, + ); + + // Check the corectness + let boolean_true = Boolean::allocated_constant(cs, true); + let no_decommits_left = decommit_queue.is_empty(cs); + no_decommits_left.conditionally_enforce_true(cs, boolean_true); + + let final_memory_queue_state = compute_memory_queue_state(cs); + for (lhs, rhs) in final_memory_queue_state + .tail + .tail + .iter() + .zip(memory_queue.tail.iter()) + { + Num::enforce_equal(cs, lhs, rhs); + } + + cs.pad_and_shrink(); + let worker = Worker::new(); + let mut owned_cs = owned_cs.into_assembly(); + owned_cs.print_gate_stats(); + assert!(owned_cs.check_if_satisfied(&worker)); + } + + fn create_witness_allocator>( + _cs: &mut CS, + ) -> ConditionalWitnessAllocator> { + let code_words_witness = get_byte_code_witness(); + + let code_words_allocator = ConditionalWitnessAllocator::> { + witness_source: Arc::new(RwLock::new(code_words_witness.into())), + }; + + code_words_allocator + } + + fn create_request_queue_witness>(cs: &mut CS) -> Vec> { + let code_hash = get_code_hash_witness(); + + let witness = DecommitQueryWitness:: { + code_hash, + page: 2368, + is_first: true, + timestamp: 40973, + }; + + let result = DecommitQuery::allocate(cs, witness); + + vec![result] + } + + fn compute_memory_queue_state>( + cs: &mut CS, + ) -> QueueState { + let boolean_true = Boolean::allocate(cs, true); + let mut memory_queue = MemoryQueryQueue::::empty(cs); + + for (index, byte_code) in get_byte_code_witness().into_iter().enumerate() { + let code_word = byte_code; + + let witness = MemoryQueryWitness:: { + timestamp: 40973, + memory_page: 2368, + index: index as u32, + rw_flag: true, + value: code_word, + is_ptr: false, + }; + + let mem_query = MemoryQuery::allocate(cs, witness); + memory_queue.push(cs, mem_query, boolean_true); + } + + memory_queue.into_state() + } + + fn get_code_hash_witness() -> U256 { + U256::from_dec_str( + "452313746998214869734508634865817576060841700842481516984674100922521850987", + ) + .unwrap() + } + + fn get_byte_code_witness() -> [U256; 33] { + [ + "1766847064778396883786768274127037193463854637992579046408942445291110457", + "20164191265753785488708351879363656296986696452890681959140868413", + "230371115084700836133063546338735802439952161310848373590933373335", + "315943403191476362254281516594763167672429992099855389200211772263", + "2588391838226565201098400008033996167521966238460106068954150751699824", + "211454133716954493758258064291659686758464834211097193222448873537", + "755661767828730679150831008859380024863962510235974769491784599863434", + "792722291272121268575835624931127487546448993321488813145330852157", + "422901469332729376614825971396751231447294514335432723148645467189", + "1725759105948670702159993994396013188152302135650842820951922845941817", + "14404925315129564325488546414599286071787685034596420832328728893", + "105318844962770555588522034545405007512793608572268457634281029689", + "809009025005867921013546649078805150441502566947026555373812841472317", + "105319039552922728847306638821735002815060289446290876141406257209", + "211036116403988059590520874377734556453268914677076498415914844236", + "1860236630555339893722514217592548129137355495764522944782381539722297", + "7764675265080516174154537029624996607702824353047648753753695920848961", + "166085834804801355241996194532094100761080533058945135475412415734372892697", + "210624740264657758079982132082095218827023230710668103574628597825", + "6588778667853837091013175373259869215603100833946083743887393845", + "970663392666895392257512002784069674802928967218673951998329152864412", + "107163641223087021704532235449659860614865516518490400358586646684", + "212475932891644255176568460416224004946153631397142661140395918382", + "2588266777670668978723371609412889835982022923910173388865216276661294", + "2588155298151653810924065765928146445685410508309586403046357418901504", + "53919893334301279589334030174039261347274288845081144962207220498432", + "1461501637330902918203684832716283019655932542975", + "432420386565659656852420866394968145599", + "432420386565659656852420866394968145600", + "35408467139433450592217433187231851964531694900788300625387963629091585785856", + "79228162514264337610723819524", + "4294967295", + "0", + ] + .map(|el| U256::from_dec_str(el).unwrap()) + } +} diff --git a/crates/zkevm_circuits/src/config.rs b/crates/zkevm_circuits/src/config.rs new file mode 100644 index 0000000..5c11895 --- /dev/null +++ b/crates/zkevm_circuits/src/config.rs @@ -0,0 +1,5 @@ +#[cfg(feature = "verbose_circuits")] +pub const CIRCUIT_VERSOBE: bool = true; + +#[cfg(not(feature = "verbose_circuits"))] +pub const CIRCUIT_VERSOBE: bool = false; diff --git a/crates/zkevm_circuits/src/demux_log_queue/input.rs b/crates/zkevm_circuits/src/demux_log_queue/input.rs new file mode 100644 index 0000000..119a5fc --- /dev/null +++ b/crates/zkevm_circuits/src/demux_log_queue/input.rs @@ -0,0 +1,106 @@ +use crate::base_structures::{ + log_query::{LogQuery, LOG_QUERY_PACKED_WIDTH}, + vm_state::*, +}; +use boojum::cs::{traits::cs::ConstraintSystem, Variable}; +use boojum::field::SmallField; +use boojum::gadgets::traits::auxiliary::PrettyComparison; +use boojum::gadgets::{ + boolean::Boolean, + queue::*, + traits::{ + allocatable::*, encodable::CircuitVarLengthEncodable, selectable::Selectable, + witnessable::WitnessHookable, + }, +}; +use cs_derive::*; +use derivative::*; + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +#[DerivePrettyComparison("true")] +pub struct LogDemuxerFSMInputOutput { + pub initial_log_queue_state: QueueState, + pub storage_access_queue_state: QueueState, + pub events_access_queue_state: QueueState, + pub l1messages_access_queue_state: QueueState, + pub keccak256_access_queue_state: QueueState, + pub sha256_access_queue_state: QueueState, + pub ecrecover_access_queue_state: QueueState, +} + +impl CSPlaceholder for LogDemuxerFSMInputOutput { + fn placeholder>(cs: &mut CS) -> Self { + Self { + initial_log_queue_state: QueueState::::placeholder(cs), + storage_access_queue_state: QueueState::::placeholder(cs), + events_access_queue_state: QueueState::::placeholder(cs), + l1messages_access_queue_state: QueueState::::placeholder(cs), + keccak256_access_queue_state: QueueState::::placeholder(cs), + sha256_access_queue_state: QueueState::::placeholder(cs), + ecrecover_access_queue_state: QueueState::::placeholder(cs), + } + } +} + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +#[DerivePrettyComparison("true")] +pub struct LogDemuxerInputData { + pub initial_log_queue_state: QueueState, +} + +impl CSPlaceholder for LogDemuxerInputData { + fn placeholder>(cs: &mut CS) -> Self { + Self { + initial_log_queue_state: QueueState::::placeholder(cs), + } + } +} + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +#[DerivePrettyComparison("true")] +pub struct LogDemuxerOutputData { + pub storage_access_queue_state: QueueState, + pub events_access_queue_state: QueueState, + pub l1messages_access_queue_state: QueueState, + pub keccak256_access_queue_state: QueueState, + pub sha256_access_queue_state: QueueState, + pub ecrecover_access_queue_state: QueueState, +} + +impl CSPlaceholder for LogDemuxerOutputData { + fn placeholder>(cs: &mut CS) -> Self { + Self { + storage_access_queue_state: QueueState::::placeholder(cs), + events_access_queue_state: QueueState::::placeholder(cs), + l1messages_access_queue_state: QueueState::::placeholder(cs), + keccak256_access_queue_state: QueueState::::placeholder(cs), + sha256_access_queue_state: QueueState::::placeholder(cs), + ecrecover_access_queue_state: QueueState::::placeholder(cs), + } + } +} + +pub type LogDemuxerInputOutput = crate::fsm_input_output::ClosedFormInput< + F, + LogDemuxerFSMInputOutput, + LogDemuxerInputData, + LogDemuxerOutputData, +>; + +pub type LogDemuxerInputOutputWitness = crate::fsm_input_output::ClosedFormInputWitness< + F, + LogDemuxerFSMInputOutput, + LogDemuxerInputData, + LogDemuxerOutputData, +>; + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Debug, Default)] +#[serde(bound = "")] +pub struct LogDemuxerCircuitInstanceWitness { + pub closed_form_input: LogDemuxerInputOutputWitness, + pub initial_queue_witness: CircuitQueueRawWitness, 4, LOG_QUERY_PACKED_WIDTH>, +} diff --git a/crates/zkevm_circuits/src/demux_log_queue/mod.rs b/crates/zkevm_circuits/src/demux_log_queue/mod.rs new file mode 100644 index 0000000..438bf11 --- /dev/null +++ b/crates/zkevm_circuits/src/demux_log_queue/mod.rs @@ -0,0 +1,922 @@ +use super::*; + +pub mod input; + +use crate::base_structures::{ + log_query::{LogQuery, LOG_QUERY_PACKED_WIDTH}, + vm_state::*, +}; +use crate::fsm_input_output::ClosedFormInputCompactForm; +use boojum::algebraic_props::round_function::AlgebraicRoundFunction; +use boojum::cs::{gates::*, traits::cs::ConstraintSystem}; +use boojum::field::SmallField; +use boojum::gadgets::queue::queue_optimizer::SpongeOptimizer; +use boojum::gadgets::traits::round_function::CircuitRoundFunction; +use boojum::gadgets::u32::UInt32; +use boojum::gadgets::u8::UInt8; +use boojum::gadgets::{ + boolean::Boolean, + num::Num, + queue::*, + traits::{ + allocatable::CSAllocatableExt, encodable::CircuitEncodableExt, selectable::Selectable, + }, + u160::*, +}; + +use zkevm_opcode_defs::system_params::*; + +use crate::{ + demux_log_queue::input::*, + fsm_input_output::{circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH, *}, +}; + +pub type StorageLogQueue = CircuitQueue, 8, 12, 4, 4, 20, R>; +pub type StorageLogQueueWitness = + CircuitQueueWitness, QUEUE_STATE_WIDTH, LOG_QUERY_PACKED_WIDTH>; + +pub fn demultiplex_storage_logs_enty_point< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, +>( + cs: &mut CS, + witness: LogDemuxerCircuitInstanceWitness, + round_function: &R, + limit: usize, +) -> [Num; INPUT_OUTPUT_COMMITMENT_LENGTH] +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + let LogDemuxerCircuitInstanceWitness { + closed_form_input, + initial_queue_witness, + } = witness; + + let mut structured_input = + LogDemuxerInputOutput::alloc_ignoring_outputs(cs, closed_form_input.clone()); + + // passthrough must be trivial + structured_input + .observable_input + .initial_log_queue_state + .enforce_trivial_head(cs); + + let state = QueueState::conditionally_select( + cs, + structured_input.start_flag, + &structured_input.observable_input.initial_log_queue_state, + &structured_input.hidden_fsm_input.initial_log_queue_state, + ); + let mut initial_queue = StorageLogQueue::::from_state(cs, state); + use std::sync::Arc; + let initial_queue_witness = CircuitQueueWitness::from_inner_witness(initial_queue_witness); + initial_queue.witness = Arc::new(initial_queue_witness); + + // for the rest it's just select between empty or from FSM + let queue_states_from_fsm = [ + &structured_input.hidden_fsm_input.storage_access_queue_state, + &structured_input.hidden_fsm_input.events_access_queue_state, + &structured_input + .hidden_fsm_input + .l1messages_access_queue_state, + &structured_input + .hidden_fsm_input + .keccak256_access_queue_state, + &structured_input.hidden_fsm_input.sha256_access_queue_state, + &structured_input + .hidden_fsm_input + .ecrecover_access_queue_state, + ]; + + let empty_state = QueueState::empty(cs); + let [mut storage_access_queue, mut events_access_queue, mut l1messages_access_queue, mut keccak256_access_queue, mut sha256_access_queue, mut ecrecover_access_queue] = + queue_states_from_fsm.map(|el| { + let state = QueueState::conditionally_select( + cs, + structured_input.start_flag, + &empty_state, + &el, + ); + StorageLogQueue::::from_state(cs, state) + }); + + let input_queues = [ + &mut storage_access_queue, + &mut events_access_queue, + &mut l1messages_access_queue, + &mut keccak256_access_queue, + &mut sha256_access_queue, + &mut ecrecover_access_queue, + ]; + + demultiplex_storage_logs_inner(cs, &mut initial_queue, input_queues, limit); + + use boojum::gadgets::traits::allocatable::CSPlaceholder; + // form the final state + structured_input.observable_output = LogDemuxerOutputData::placeholder(cs); + + let completed = initial_queue.is_empty(cs); + structured_input.completion_flag = completed; + + structured_input.hidden_fsm_output.initial_log_queue_state = initial_queue.into_state(); + + structured_input + .hidden_fsm_output + .storage_access_queue_state = storage_access_queue.into_state(); + + structured_input.hidden_fsm_output.events_access_queue_state = events_access_queue.into_state(); + + structured_input + .hidden_fsm_output + .l1messages_access_queue_state = l1messages_access_queue.into_state(); + + structured_input + .hidden_fsm_output + .keccak256_access_queue_state = keccak256_access_queue.into_state(); + + structured_input.hidden_fsm_output.sha256_access_queue_state = sha256_access_queue.into_state(); + + structured_input + .hidden_fsm_output + .ecrecover_access_queue_state = ecrecover_access_queue.into_state(); + + // copy into observable output + structured_input + .observable_output + .storage_access_queue_state = QueueState::conditionally_select( + cs, + completed, + &structured_input + .hidden_fsm_output + .storage_access_queue_state, + &structured_input + .observable_output + .storage_access_queue_state, + ); + structured_input.observable_output.events_access_queue_state = QueueState::conditionally_select( + cs, + completed, + &structured_input.hidden_fsm_output.events_access_queue_state, + &structured_input.observable_output.events_access_queue_state, + ); + structured_input + .observable_output + .l1messages_access_queue_state = QueueState::conditionally_select( + cs, + completed, + &structured_input + .hidden_fsm_output + .l1messages_access_queue_state, + &structured_input + .observable_output + .l1messages_access_queue_state, + ); + structured_input + .observable_output + .keccak256_access_queue_state = QueueState::conditionally_select( + cs, + completed, + &structured_input + .hidden_fsm_output + .keccak256_access_queue_state, + &structured_input + .observable_output + .keccak256_access_queue_state, + ); + structured_input.observable_output.sha256_access_queue_state = QueueState::conditionally_select( + cs, + completed, + &structured_input.hidden_fsm_output.sha256_access_queue_state, + &structured_input.observable_output.sha256_access_queue_state, + ); + structured_input + .observable_output + .ecrecover_access_queue_state = QueueState::conditionally_select( + cs, + completed, + &structured_input + .hidden_fsm_output + .ecrecover_access_queue_state, + &structured_input + .observable_output + .ecrecover_access_queue_state, + ); + + // self-check + structured_input.hook_compare_witness(cs, &closed_form_input); + + let compact_form = + ClosedFormInputCompactForm::from_full_form(cs, &structured_input, round_function); + + let input_commitment = commit_variable_length_encodable_item(cs, &compact_form, round_function); + for el in input_commitment.iter() { + let gate = PublicInputGate::new(el.get_variable()); + gate.add_to_cs(cs); + } + + input_commitment +} + +pub const NUM_SEPARATE_QUEUES: usize = 6; + +#[repr(u64)] +pub enum LogType { + RollupStorage = 0, + Events = 1, + L1Messages = 2, + KeccakCalls = 3, + Sha256Calls = 4, + ECRecoverCalls = 5, + PorterStorage = 1024, // force unreachable +} + +pub fn demultiplex_storage_logs_inner< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, +>( + cs: &mut CS, + storage_log_queue: &mut StorageLogQueue, + output_queues: [&mut StorageLogQueue; NUM_SEPARATE_QUEUES], + limit: usize, +) where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + assert!(limit <= u32::MAX as usize); + + let [rollup_storage_queue, events_queue, l1_messages_queue, keccak_calls_queue, sha256_calls_queue, ecdsa_calls_queue] = + output_queues; + + let keccak_precompile_address = UInt160::allocated_constant( + cs, + *zkevm_opcode_defs::system_params::KECCAK256_ROUND_FUNCTION_PRECOMPILE_FORMAL_ADDRESS, + ); + let sha256_precompile_address = UInt160::allocated_constant( + cs, + *zkevm_opcode_defs::system_params::SHA256_ROUND_FUNCTION_PRECOMPILE_FORMAL_ADDRESS, + ); + let ecrecover_precompile_address = UInt160::allocated_constant( + cs, + *zkevm_opcode_defs::system_params::ECRECOVER_INNER_FUNCTION_PRECOMPILE_FORMAL_ADDRESS, + ); + + // we have 6 queues to demux into, and up to 3 sponges per any push + // use crate::base_structures::log_query::LOG_QUERY_ABSORBTION_ROUNDS; + // let mut optimizer = SpongeOptimizer::::new(LOG_QUERY_ABSORBTION_ROUNDS * limit); + + for _ in 0..limit { + // debug_assert!(optimizer.is_fresh()); + + let queue_is_empty = storage_log_queue.is_empty(cs); + let execute = queue_is_empty.negated(cs); + let popped = storage_log_queue.pop_front(cs, execute); + + let [aux_byte_for_storage, aux_byte_for_event, aux_byte_for_l1_message, aux_byte_for_precompile_call] = + [ + STORAGE_AUX_BYTE, + EVENT_AUX_BYTE, + L1_MESSAGE_AUX_BYTE, + PRECOMPILE_AUX_BYTE, + ] + .map(|byte| UInt8::allocated_constant(cs, byte)); + + let is_storage_aux_byte = UInt8::equals(cs, &aux_byte_for_storage, &popped.0.aux_byte); + let is_event_aux_byte = UInt8::equals(cs, &aux_byte_for_event, &popped.0.aux_byte); + let is_l1_message_aux_byte = + UInt8::equals(cs, &aux_byte_for_l1_message, &popped.0.aux_byte); + let is_precompile_aux_byte = + UInt8::equals(cs, &aux_byte_for_precompile_call, &popped.0.aux_byte); + + let is_keccak_address = UInt160::equals(cs, &keccak_precompile_address, &popped.0.address); + let is_sha256_address = UInt160::equals(cs, &sha256_precompile_address, &popped.0.address); + let is_ecrecover_address = + UInt160::equals(cs, &ecrecover_precompile_address, &popped.0.address); + + let is_rollup_shard = popped.0.shard_id.is_zero(cs); + let execute_rollup_storage = + Boolean::multi_and(cs, &[is_storage_aux_byte, is_rollup_shard, execute]); + let is_porter_shard = is_rollup_shard.negated(cs); + let execute_porter_storage = + Boolean::multi_and(cs, &[is_storage_aux_byte, is_porter_shard, execute]); + + let boolean_false = Boolean::allocated_constant(cs, false); + Boolean::enforce_equal(cs, &execute_porter_storage, &boolean_false); + + let execute_event = Boolean::multi_and(cs, &[is_event_aux_byte, execute]); + let execute_l1_message = Boolean::multi_and(cs, &[is_l1_message_aux_byte, execute]); + let execute_keccak_call = + Boolean::multi_and(cs, &[is_precompile_aux_byte, is_keccak_address, execute]); + let execute_sha256_call = + Boolean::multi_and(cs, &[is_precompile_aux_byte, is_sha256_address, execute]); + let execute_ecrecover_call = + Boolean::multi_and(cs, &[is_precompile_aux_byte, is_ecrecover_address, execute]); + + // rollup_storage_queue.push_encoding_with_optimizer_without_changing_witness( + // cs, + // popped.1, + // execute_rollup_storage, + // LogType::RollupStorage as usize, + // &mut optimizer + // ); + // events_queue.push_encoding_with_optimizer_without_changing_witness( + // cs, + // popped.1, + // execute_event, + // LogType::Events as usize, + // &mut optimizer + // ); + // l1_messages_queue.push_encoding_with_optimizer_without_changing_witness( + // cs, + // popped.1, + // execute_l1_message, + // LogType::L1Messages as usize, + // &mut optimizer + // ); + // keccak_calls_queue.push_encoding_with_optimizer_without_changing_witness( + // cs, + // popped.1, + // execute_keccak_call, + // LogType::KeccakCalls as usize, + // &mut optimizer + // ); + // sha256_calls_queue.push_encoding_with_optimizer_without_changing_witness( + // cs, + // popped.1, + // execute_sha256_call, + // LogType::Sha256Calls as usize, + // &mut optimizer + // ); + // ecdsa_calls_queue.push_encoding_with_optimizer_without_changing_witness( + // cs, + // popped.1, + // execute_ecrecover_call, + // LogType::ECRecoverCalls as usize, + // &mut optimizer + // ); + + let bitmask = [ + execute_rollup_storage, + execute_event, + execute_l1_message, + execute_keccak_call, + execute_sha256_call, + execute_ecrecover_call, + ]; + + push_with_optimize( + cs, + [ + rollup_storage_queue, + events_queue, + l1_messages_queue, + keccak_calls_queue, + sha256_calls_queue, + ecdsa_calls_queue, + ], + bitmask, + popped.0, + ); + + let expected_bitmask_bits = [ + is_storage_aux_byte, + is_event_aux_byte, + is_l1_message_aux_byte, + is_precompile_aux_byte, + ]; + + let is_bitmask = check_if_bitmask_and_if_empty(cs, expected_bitmask_bits); + is_bitmask.conditionally_enforce_true(cs, execute); + + // // we enforce optimizer in this round, and it clears it up + // optimizer.enforce(cs); + } + + storage_log_queue.enforce_consistency(cs); + + // checks in "Drop" interact badly with some tools, so we check it during testing instead + // debug_assert!(optimizer.is_fresh()); +} + +pub fn push_with_optimize< + F: SmallField, + CS: ConstraintSystem, + EL: CircuitEncodableExt, + const AW: usize, + const SW: usize, + const CW: usize, + const T: usize, + const N: usize, + R: CircuitRoundFunction, + const NUM_QUEUE: usize, +>( + cs: &mut CS, + mut queues: [&mut CircuitQueue; NUM_QUEUE], + bitmask: [Boolean; NUM_QUEUE], + value_encoding: EL, +) where + [(); >::INTERNAL_STRUCT_LEN]:, +{ + let mut states = queues.iter().map(|x| x.into_state()); + let mut state = states.next().unwrap(); + + for (bit, next_state) in bitmask.iter().skip(1).zip(states) { + state = QueueState::conditionally_select(cs, *bit, &next_state, &state); + } + + let mut exec_queue = CircuitQueue::::from_raw_parts( + cs, + state.head, + state.tail.tail, + state.tail.length, + ); + + let boolean_true = Boolean::allocated_constant(cs, true); + + exec_queue.push(cs, value_encoding, boolean_true); + + for (bit, queue) in bitmask.into_iter().zip(queues.iter_mut()) { + // We don't need to update head + // queue.head = <[Num; T]>::conditionally_select(cs, bit, &exec_queue.head, &queue.head); + queue.tail = <[Num; T]>::conditionally_select(cs, bit, &exec_queue.tail, &queue.tail); + queue.length = UInt32::conditionally_select(cs, bit, &exec_queue.length, &queue.length); + } +} + +pub fn check_if_bitmask_and_if_empty, const N: usize>( + cs: &mut CS, + mask: [Boolean; N], +) -> Boolean { + let lc: [_; N] = mask.map(|el| (el.get_variable(), F::ONE)); + + let lc = Num::linear_combination(cs, &lc); + + let one = Num::from_variable(cs.allocate_constant(F::ONE)); + let is_boolean = Num::equals(cs, &lc, &one); + + is_boolean +} + +#[cfg(test)] +mod tests { + use super::*; + use boojum::algebraic_props::poseidon2_parameters::Poseidon2GoldilocksExternalMatrix; + use boojum::cs::traits::gate::GatePlacementStrategy; + use boojum::cs::CSGeometry; + use boojum::cs::*; + use boojum::field::goldilocks::GoldilocksField; + use boojum::gadgets::tables::*; + use boojum::gadgets::u160::UInt160; + use boojum::gadgets::u256::UInt256; + use boojum::gadgets::u32::UInt32; + use boojum::gadgets::u8::UInt8; + use boojum::implementations::poseidon2::Poseidon2Goldilocks; + use boojum::worker::Worker; + use ethereum_types::{Address, U256}; + type F = GoldilocksField; + type P = GoldilocksField; + + #[test] + fn test_demultiplex_storage_logs_inner() { + let geometry = CSGeometry { + num_columns_under_copy_permutation: 100, + num_witness_columns: 0, + num_constant_columns: 8, + max_allowed_constraint_degree: 4, + }; + + use boojum::cs::cs_builder::*; + + fn configure< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + let builder = builder.allow_lookup( + LookupParameters::UseSpecializedColumnsWithTableIdAsConstant { + width: 3, + num_repetitions: 8, + share_table_id: true, + }, + ); + let builder = ConstantsAllocatorGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = FmaGateInBaseFieldWithoutConstant::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ReductionGate::::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = BooleanConstraintGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<32>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<16>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = SelectionGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ZeroCheckGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + false, + ); + let builder = DotProductGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = MatrixMultiplicationGate::::configure_builder(builder,GatePlacementStrategy::UseGeneralPurposeColumns); + let builder = NopGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + + builder + } + + use boojum::config::DevCSConfig; + use boojum::cs::cs_builder_reference::CsReferenceImplementationBuilder; + + let builder_impl = + CsReferenceImplementationBuilder::::new(geometry, 1 << 26, 1 << 20); + use boojum::cs::cs_builder::new_builder; + let builder = new_builder::<_, F>(builder_impl); + + let builder = configure(builder); + let mut owned_cs = builder.build(()); + + // add tables + let table = create_xor8_table(); + owned_cs.add_lookup_table::(table); + + let cs = &mut owned_cs; + + // start test + let execute = Boolean::allocated_constant(cs, true); + + let mut storage_log_queue = StorageLogQueue::::empty(cs); + let unsorted_input = witness_input_unsorted(cs); + for el in unsorted_input { + storage_log_queue.push(cs, el, execute); + } + let mut output_queue = StorageLogQueue::empty(cs); + let mut output_queue1 = StorageLogQueue::empty(cs); + let mut output_queue2 = StorageLogQueue::empty(cs); + let mut output_queue3 = StorageLogQueue::empty(cs); + let mut output_queue4 = StorageLogQueue::empty(cs); + let mut output_queue5 = StorageLogQueue::empty(cs); + + let output = [ + &mut output_queue, + &mut output_queue1, + &mut output_queue2, + &mut output_queue3, + &mut output_queue4, + &mut output_queue5, + ]; + let limit = 16; + demultiplex_storage_logs_inner(cs, &mut storage_log_queue, output, limit); + + cs.pad_and_shrink(); + let worker = Worker::new(); + let mut owned_cs = owned_cs.into_assembly(); + owned_cs.print_gate_stats(); + assert!(owned_cs.check_if_satisfied(&worker)); + } + + fn witness_input_unsorted>(cs: &mut CS) -> Vec> { + let mut unsorted_querie = vec![]; + let bool_false = Boolean::allocated_constant(cs, false); + let bool_true = Boolean::allocated_constant(cs, true); + let zero_8 = UInt8::allocated_constant(cs, 0); + let zero_32 = UInt32::allocated_constant(cs, 0); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32770)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("32779").unwrap()), + read_value: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452319300877325313852488925888724764263521004047156906617735320131041551860", + ) + .unwrap(), + ), + written_value: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452319300877325313852488925888724764263521004047156906617735320131041551860", + ) + .unwrap(), + ), + rw_flag: bool_false, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 1205), + }; + + unsorted_querie.push(q); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32779)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("1").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + rw_flag: bool_false, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 1425), + }; + unsorted_querie.push(q); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32770)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("32779").unwrap()), + read_value: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452319300877325313852488925888724764263521004047156906617735320131041551860", + ) + .unwrap(), + ), + written_value: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452319300877325313852488925888724764263521004047156906617735320131041551860", + ) + .unwrap(), + ), + rw_flag: bool_false, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 1609), + }; + unsorted_querie.push(q); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32779)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("7").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + rw_flag: bool_false, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 1777), + }; + unsorted_querie.push(q); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32770)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("32779").unwrap()), + read_value: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452319300877325313852488925888724764263521004047156906617735320131041551860", + ) + .unwrap(), + ), + written_value: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452319300877325313852488925888724764263521004047156906617735320131041551860", + ) + .unwrap(), + ), + rw_flag: bool_false, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 1969), + }; + unsorted_querie.push(q); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32779)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("5").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + rw_flag: bool_false, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 2253), + }; + unsorted_querie.push(q); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32769)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("10").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + rw_flag: bool_true, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 2357), + }; + unsorted_querie.push(q); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32770)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("32779").unwrap()), + read_value: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452319300877325313852488925888724764263521004047156906617735320131041551860", + ) + .unwrap(), + ), + written_value: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452319300877325313852488925888724764263521004047156906617735320131041551860", + ) + .unwrap(), + ), + rw_flag: bool_false, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 2429), + }; + unsorted_querie.push(q); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32779)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("4").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + rw_flag: bool_false, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 2681), + }; + unsorted_querie.push(q); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32769)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("9").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + rw_flag: bool_false, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 2797), + }; + unsorted_querie.push(q); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32769)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("9").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + rw_flag: bool_true, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 2829), + }; + unsorted_querie.push(q); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32770)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("32779").unwrap()), + read_value: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452319300877325313852488925888724764263521004047156906617735320131041551860", + ) + .unwrap(), + ), + written_value: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452319300877325313852488925888724764263521004047156906617735320131041551860", + ) + .unwrap(), + ), + rw_flag: bool_false, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 2901), + }; + unsorted_querie.push(q); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32779)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("3").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + rw_flag: bool_false, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 3089), + }; + unsorted_querie.push(q); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32769)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("8").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + rw_flag: bool_true, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 3193), + }; + unsorted_querie.push(q); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32770)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("32779").unwrap()), + read_value: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452319300877325313852488925888724764263521004047156906617735320131041551860", + ) + .unwrap(), + ), + written_value: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452319300877325313852488925888724764263521004047156906617735320131041551860", + ) + .unwrap(), + ), + rw_flag: bool_false, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 3265), + }; + unsorted_querie.push(q); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32779)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("2").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + rw_flag: bool_false, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 3421), + }; + unsorted_querie.push(q); + + unsorted_querie + } +} diff --git a/crates/zkevm_circuits/src/ecrecover/baseline.rs b/crates/zkevm_circuits/src/ecrecover/baseline.rs new file mode 100644 index 0000000..1e01607 --- /dev/null +++ b/crates/zkevm_circuits/src/ecrecover/baseline.rs @@ -0,0 +1,937 @@ +use super::*; +use crate::base_structures::log_query::*; +use crate::base_structures::memory_query::*; +use crate::base_structures::precompile_input_outputs::PrecompileFunctionOutputData; +use crate::demux_log_queue::StorageLogQueue; +use crate::ethereum_types::U256; +use crate::fsm_input_output::circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH; +use crate::fsm_input_output::*; +use arrayvec::ArrayVec; +use boojum::algebraic_props::round_function::AlgebraicRoundFunction; +use boojum::crypto_bigint::{Zero, U1024}; +use boojum::cs::gates::ConstantAllocatableCS; +use boojum::cs::traits::cs::ConstraintSystem; +use boojum::field::SmallField; +use boojum::gadgets::boolean::Boolean; +use boojum::gadgets::curves::sw_projective::SWProjectivePoint; +use boojum::gadgets::keccak256::keccak256; +use boojum::gadgets::non_native_field::implementations::*; +use boojum::gadgets::num::Num; +use boojum::gadgets::queue::CircuitQueueWitness; +use boojum::gadgets::queue::QueueState; +use boojum::gadgets::traits::allocatable::{CSAllocatableExt, CSPlaceholder}; +use boojum::gadgets::traits::round_function::CircuitRoundFunction; +use boojum::gadgets::traits::selectable::Selectable; +use boojum::gadgets::traits::witnessable::WitnessHookable; +use boojum::gadgets::u16::UInt16; +use boojum::gadgets::u160::UInt160; +use boojum::gadgets::u256::UInt256; +use boojum::gadgets::u32::UInt32; +use boojum::gadgets::u8::UInt8; +use cs_derive::*; +use std::collections::VecDeque; +use std::sync::{Arc, RwLock}; +use zkevm_opcode_defs::system_params::PRECOMPILE_AUX_BYTE; + +pub const MEMORY_QUERIES_PER_CALL: usize = 4; + +use super::input::*; + +#[derive(Derivative, CSSelectable)] +#[derivative(Clone, Debug)] +pub struct EcrecoverPrecompileCallParams { + pub input_page: UInt32, + pub input_offset: UInt32, + pub output_page: UInt32, + pub output_offset: UInt32, +} + +impl EcrecoverPrecompileCallParams { + // pub fn empty() -> Self { + // Self { + // input_page: UInt32::::zero(), + // input_offset: UInt32::::zero(), + // output_page: UInt32::::zero(), + // output_offset: UInt32::::zero(), + // } + // } + + pub fn from_encoding>(_cs: &mut CS, encoding: UInt256) -> Self { + let input_offset = encoding.inner[0]; + let output_offset = encoding.inner[2]; + let input_page = encoding.inner[4]; + let output_page = encoding.inner[5]; + + let new = Self { + input_page, + input_offset, + output_page, + output_offset, + }; + + new + } +} + +const NUM_WORDS: usize = 17; +const SECP_B_COEF: u64 = 7; +const EXCEPTION_FLAGS_ARR_LEN: usize = 8; +const NUM_MEMORY_READS_PER_CYCLE: usize = 4; +const X_POWERS_ARR_LEN: usize = 256; +const VALID_Y_IN_EXTERNAL_FIELD: u64 = 4; +const VALID_X_CUBED_IN_EXTERNAL_FIELD: u64 = 9; + +// assume that constructed field element is not zero +// if this is not satisfied - set the result to be F::one +fn convert_uint256_to_field_element_masked< + F: SmallField, + CS: ConstraintSystem, + P: boojum::pairing::ff::PrimeField, + const N: usize, +>( + cs: &mut CS, + elem: &UInt256, + params: &Arc>, +) -> (NonNativeFieldOverU16, Boolean) +where + [(); N + 1]:, +{ + let is_zero = elem.is_zero(cs); + let one_nn = NonNativeFieldOverU16::::allocated_constant(cs, P::one(), params); + // we still have to decompose it into u16 words + let zero_var = cs.allocate_constant(F::ZERO); + let mut limbs = [zero_var; N]; + assert!(N >= 16); + for (dst, src) in limbs.array_chunks_mut::<2>().zip(elem.inner.iter()) { + let [b0, b1, b2, b3] = src.to_le_bytes(cs); + let low = UInt16::from_le_bytes(cs, [b0, b1]); + let high = UInt16::from_le_bytes(cs, [b2, b3]); + + *dst = [low.get_variable(), high.get_variable()]; + } + + let mut max_value = U1024::from_word(1u64); + max_value = max_value.shl_vartime(256); + max_value = max_value.saturating_sub(&U1024::from_word(1u64)); + + let (overflows, rem) = max_value.div_rem(¶ms.modulus_u1024); + + let mut max_moduluses = overflows.as_words()[0] as u32; + if rem.is_zero().unwrap_u8() != 1 { + max_moduluses += 1; + } + + let element = NonNativeFieldOverU16 { + limbs: limbs, + non_zero_limbs: 16, + tracker: OverflowTracker { max_moduluses }, + form: RepresentationForm::Normalized, + params: params.clone(), + _marker: std::marker::PhantomData, + }; + + let selected = Selectable::conditionally_select(cs, is_zero, &one_nn, &element); + + (selected, is_zero) +} + +fn convert_uint256_to_field_element< + F: SmallField, + CS: ConstraintSystem, + P: boojum::pairing::ff::PrimeField, + const N: usize, +>( + cs: &mut CS, + elem: &UInt256, + params: &Arc>, +) -> NonNativeFieldOverU16 { + // we still have to decompose it into u16 words + let zero_var = cs.allocate_constant(F::ZERO); + let mut limbs = [zero_var; N]; + assert!(N >= 16); + for (dst, src) in limbs.array_chunks_mut::<2>().zip(elem.inner.iter()) { + let [b0, b1, b2, b3] = src.to_le_bytes(cs); + let low = UInt16::from_le_bytes(cs, [b0, b1]); + let high = UInt16::from_le_bytes(cs, [b2, b3]); + + *dst = [low.get_variable(), high.get_variable()]; + } + + let mut max_value = U1024::from_word(1u64); + max_value = max_value.shl_vartime(256); + max_value = max_value.saturating_sub(&U1024::from_word(1u64)); + + let (overflows, rem) = max_value.div_rem(¶ms.modulus_u1024); + let mut max_moduluses = overflows.as_words()[0] as u32; + if rem.is_zero().unwrap_u8() != 1 { + max_moduluses += 1; + } + + let element = NonNativeFieldOverU16 { + limbs: limbs, + non_zero_limbs: 16, + tracker: OverflowTracker { max_moduluses }, + form: RepresentationForm::Normalized, + params: params.clone(), + _marker: std::marker::PhantomData, + }; + + element +} + +fn ecrecover_precompile_inner_routine>( + cs: &mut CS, + recid: &UInt8, + r: &UInt256, + s: &UInt256, + message_hash: &UInt256, + valid_x_in_external_field: Secp256BaseNNField, + valid_y_in_external_field: Secp256BaseNNField, + valid_t_in_external_field: Secp256BaseNNField, + base_field_params: &Arc, + scalar_field_params: &Arc, +) -> (Boolean, UInt256) { + use boojum::pairing::ff::Field; + let curve_b = Secp256Affine::b_coeff(); + + let mut minus_one = Secp256Fq::one(); + minus_one.negate(); + + let mut curve_b_nn = + Secp256BaseNNField::::allocated_constant(cs, curve_b, &base_field_params); + let mut minus_one_nn = + Secp256BaseNNField::::allocated_constant(cs, minus_one, &base_field_params); + + let secp_n_u256 = U256([ + scalar_field_params.modulus_u1024.as_ref().as_words()[0], + scalar_field_params.modulus_u1024.as_ref().as_words()[1], + scalar_field_params.modulus_u1024.as_ref().as_words()[2], + scalar_field_params.modulus_u1024.as_ref().as_words()[3], + ]); + let secp_n_u256 = UInt256::allocated_constant(cs, secp_n_u256); + + let secp_p_u256 = U256([ + base_field_params.modulus_u1024.as_ref().as_words()[0], + base_field_params.modulus_u1024.as_ref().as_words()[1], + base_field_params.modulus_u1024.as_ref().as_words()[2], + base_field_params.modulus_u1024.as_ref().as_words()[3], + ]); + let secp_p_u256 = UInt256::allocated_constant(cs, secp_p_u256); + + let mut exception_flags = ArrayVec::<_, EXCEPTION_FLAGS_ARR_LEN>::new(); + + // recid = (x_overflow ? 2 : 0) | (secp256k1_fe_is_odd(&r.y) ? 1 : 0) + // The point X = (x, y) we are going to recover is not known at the start, but it is strongly related to r. + // This is because x = r + kn for some integer k, where x is an element of the field F_q . In other words, x < q. + // (here n is the order of group of points on elleptic curve) + // For secp256k1 curve values of q and n are relatively close, that is, + // the probability of a random element of Fq being greater than n is about 1/{2^128}. + // This in turn means that the overwhelming majority of r determine a unique x, however some of them determine + // two: x = r and x = r + n. If x_overflow flag is set than x = r + n + + let [y_is_odd, x_overflow, ..] = + Num::::from_variable(recid.get_variable()).spread_into_bits::<_, 8>(cs); + + let (r_plus_n, of) = r.overflowing_add(cs, &secp_n_u256); + let mut x_as_u256 = UInt256::conditionally_select(cs, x_overflow, &r_plus_n, &r); + let error = Boolean::multi_and(cs, &[x_overflow, of]); + exception_flags.push(error); + + // we handle x separately as it is the only element of base field of a curve (not a scalar field element!) + // check that x < q - order of base point on Secp256 curve + // if it is not actually the case - mask x to be zero + let (_res, is_in_range) = x_as_u256.overflowing_sub(cs, &secp_p_u256); + x_as_u256 = x_as_u256.mask(cs, is_in_range); + let x_is_not_in_range = is_in_range.negated(cs); + exception_flags.push(x_is_not_in_range); + + let mut x_fe = convert_uint256_to_field_element(cs, &x_as_u256, &base_field_params); + + let (mut r_fe, r_is_zero) = + convert_uint256_to_field_element_masked(cs, &r, &scalar_field_params); + exception_flags.push(r_is_zero); + let (mut s_fe, s_is_zero) = + convert_uint256_to_field_element_masked(cs, &s, &scalar_field_params); + exception_flags.push(s_is_zero); + + // NB: although it is not strictly an exception we also assume that hash is never zero as field element + let (mut message_hash_fe, message_hash_is_zero) = + convert_uint256_to_field_element_masked(cs, &message_hash, &scalar_field_params); + exception_flags.push(message_hash_is_zero); + + // curve equation is y^2 = x^3 + b + // we compute t = r^3 + b and check if t is a quadratic residue or not. + // we do this by computing Legendre symbol (t, p) = t^[(p-1)/2] (mod p) + // p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1 + // n = (p-1)/2 = 2^255 - 2^31 - 2^8 - 2^7 - 2^6 - 2^5 - 2^3 - 1 + // we have to compute t^b = t^{2^255} / ( t^{2^31} * t^{2^8} * t^{2^7} * t^{2^6} * t^{2^5} * t^{2^3} * t) + // if t is not a quadratic residue we return error and replace x by another value that will make + // t = x^3 + b a quadratic residue + + let mut t = x_fe.square(cs); + t = t.mul(cs, &mut x_fe); + t = t.add(cs, &mut curve_b_nn); + + let t_is_zero = t.is_zero(cs); + exception_flags.push(t_is_zero); + + // if t is zero then just mask + let t = Selectable::conditionally_select(cs, t_is_zero, &valid_t_in_external_field, &t); + + // array of powers of t of the form t^{2^i} starting from i = 0 to 255 + let mut t_powers = Vec::with_capacity(X_POWERS_ARR_LEN); + t_powers.push(t); + + for _ in 1..X_POWERS_ARR_LEN { + let prev = t_powers.last_mut().unwrap(); + let next = prev.square(cs); + t_powers.push(next); + } + + let mut acc = t_powers[0].clone(); + for idx in [3, 5, 6, 7, 8, 31].into_iter() { + let other = &mut t_powers[idx]; + acc = acc.mul(cs, other); + } + let mut legendre_symbol = t_powers[255].div_unchecked(cs, &mut acc); + + // we can also reuse the same values to compute square root in case of p = 3 mod 4 + // p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1 + // n = (p+1)/4 = 2^254 - 2^30 - 2^7 - 2^6 - 2^5 - 2^4 - 2^2 + + let mut acc_2 = t_powers[2].clone(); + for idx in [4, 5, 6, 7, 30].into_iter() { + let other = &mut t_powers[idx]; + acc_2 = acc_2.mul(cs, other); + } + + let mut may_be_recovered_y = t_powers[254].div_unchecked(cs, &mut acc_2); + may_be_recovered_y.normalize(cs); + let mut may_be_recovered_y_negated = may_be_recovered_y.negated(cs); + may_be_recovered_y_negated.normalize(cs); + + let [lowest_bit, ..] = + Num::::from_variable(may_be_recovered_y.limbs[0]).spread_into_bits::<_, 16>(cs); + + // if lowest bit != parity bit, then we need conditionally select + let should_swap = lowest_bit.xor(cs, y_is_odd); + let may_be_recovered_y = Selectable::conditionally_select( + cs, + should_swap, + &may_be_recovered_y_negated, + &may_be_recovered_y, + ); + + let t_is_nonresidue = + Secp256BaseNNField::::equals(cs, &mut legendre_symbol, &mut minus_one_nn); + exception_flags.push(t_is_nonresidue); + // unfortunately, if t is found to be a quadratic nonresidue, we can't simply let x to be zero, + // because then t_new = 7 is again a quadratic nonresidue. So, in this case we let x to be 9, then + // t = 16 is a quadratic residue + let x = + Selectable::conditionally_select(cs, t_is_nonresidue, &valid_x_in_external_field, &x_fe); + let y = Selectable::conditionally_select( + cs, + t_is_nonresidue, + &valid_y_in_external_field, + &may_be_recovered_y, + ); + + // we recovered (x, y) using curve equation, so it's on curve (or was masked) + let mut r_fe_inversed = r_fe.inverse_unchecked(cs); + let mut s_by_r_inv = s_fe.mul(cs, &mut r_fe_inversed); + let mut message_hash_by_r_inv = message_hash_fe.mul(cs, &mut r_fe_inversed); + + s_by_r_inv.normalize(cs); + message_hash_by_r_inv.normalize(cs); + + let mut gen_negated = Secp256Affine::one(); + gen_negated.negate(); + let (gen_negated_x, gen_negated_y) = gen_negated.into_xy_unchecked(); + let gen_negated_x = + Secp256BaseNNField::allocated_constant(cs, gen_negated_x, base_field_params); + let gen_negated_y = + Secp256BaseNNField::allocated_constant(cs, gen_negated_y, base_field_params); + + let s_by_r_inv_normalized_lsb_bits: Vec<_> = s_by_r_inv + .limbs + .iter() + .map(|el| Num::::from_variable(*el).spread_into_bits::<_, 16>(cs)) + .flatten() + .collect(); + let message_hash_by_r_inv_lsb_bits: Vec<_> = message_hash_by_r_inv + .limbs + .iter() + .map(|el| Num::::from_variable(*el).spread_into_bits::<_, 16>(cs)) + .flatten() + .collect(); + + // now we are going to compute the public key Q = (x, y) determined by the formula: + // Q = (s * X - hash * G) / r which is equivalent to r * Q = s * X - hash * G + // current implementation of point by scalar multiplications doesn't support multiplication by zero + // so we check that all s, r, hash are not zero (as FieldElements): + // if any of them is zero we reject the signature and in circuit itself replace all zero variables by ones + + let mut recovered_point = (x, y); + let mut generator_point = (gen_negated_x, gen_negated_y); + // now we do multiexponentiation + let mut q_acc = + SWProjectivePoint::>::zero(cs, base_field_params); + + // we should start from MSB, double the accumulator, then conditionally add + for (cycle, (x_bit, hash_bit)) in s_by_r_inv_normalized_lsb_bits + .into_iter() + .rev() + .zip(message_hash_by_r_inv_lsb_bits.into_iter().rev()) + .enumerate() + { + if cycle != 0 { + q_acc = q_acc.double(cs); + } + let q_plus_x = q_acc.add_mixed(cs, &mut recovered_point); + let mut q_0: SWProjectivePoint> = + Selectable::conditionally_select(cs, x_bit, &q_plus_x, &q_acc); + + let q_plux_gen = q_0.add_mixed(cs, &mut generator_point); + let q_1 = Selectable::conditionally_select(cs, hash_bit, &q_plux_gen, &q_0); + + q_acc = q_1; + } + + use boojum::pairing::GenericCurveAffine; + let ((mut q_x, mut q_y), is_infinity) = + q_acc.convert_to_affine_or_default(cs, Secp256Affine::one()); + exception_flags.push(is_infinity); + let any_exception = Boolean::multi_or(cs, &exception_flags[..]); + + q_x.normalize(cs); + q_y.normalize(cs); + + let zero_u8 = UInt8::zero(cs); + + let mut bytes_to_hash = [zero_u8; 64]; + let it = q_x.limbs[..16] + .iter() + .rev() + .chain(q_y.limbs[..16].iter().rev()); + + for (dst, src) in bytes_to_hash.array_chunks_mut::<2>().zip(it) { + let limb = unsafe { UInt16::from_variable_unchecked(*src) }; + *dst = limb.to_be_bytes(cs); + } + + let mut digest_bytes = keccak256(cs, &bytes_to_hash); + // digest is 32 bytes, but we need only 20 to recover address + digest_bytes[0..12].copy_from_slice(&[zero_u8; 12]); // empty out top bytes + digest_bytes.reverse(); + let written_value_unmasked = UInt256::from_le_bytes(cs, digest_bytes); + + let written_value = written_value_unmasked.mask_negated(cs, any_exception); + let all_ok = any_exception.negated(cs); + + (all_ok, written_value) +} + +pub fn ecrecover_function_entry_point< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, +>( + cs: &mut CS, + witness: EcrecoverCircuitInstanceWitness, + round_function: &R, + limit: usize, +) -> [Num; INPUT_OUTPUT_COMMITMENT_LENGTH] +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, +{ + assert!(limit <= u32::MAX as usize); + + let EcrecoverCircuitInstanceWitness { + closed_form_input, + requests_queue_witness, + memory_reads_witness, + } = witness; + + let memory_reads_witness: VecDeque<_> = memory_reads_witness.into_iter().flatten().collect(); + + let precompile_address = UInt160::allocated_constant( + cs, + *zkevm_opcode_defs::system_params::ECRECOVER_INNER_FUNCTION_PRECOMPILE_FORMAL_ADDRESS, + ); + let aux_byte_for_precompile = UInt8::allocated_constant(cs, PRECOMPILE_AUX_BYTE); + + let scalar_params = Arc::new(secp256k1_scalar_field_params()); + let base_params = Arc::new(secp256k1_base_field_params()); + + use boojum::pairing::ff::PrimeField; + + let valid_x_in_external_field = Secp256BaseNNField::allocated_constant( + cs, + Secp256Fq::from_str(&VALID_X_CUBED_IN_EXTERNAL_FIELD.to_string()).unwrap(), + &base_params, + ); + let valid_t_in_external_field = Secp256BaseNNField::allocated_constant( + cs, + Secp256Fq::from_str(&(VALID_X_CUBED_IN_EXTERNAL_FIELD + SECP_B_COEF).to_string()).unwrap(), + &base_params, + ); + let valid_y_in_external_field = Secp256BaseNNField::allocated_constant( + cs, + Secp256Fq::from_str(&VALID_Y_IN_EXTERNAL_FIELD.to_string()).unwrap(), + &base_params, + ); + + let mut structured_input = + EcrecoverCircuitInputOutput::alloc_ignoring_outputs(cs, closed_form_input.clone()); + let start_flag = structured_input.start_flag; + + let requests_queue_state_from_input = structured_input.observable_input.initial_log_queue_state; + + // it must be trivial + requests_queue_state_from_input.enforce_trivial_head(cs); + + let requests_queue_state_from_fsm = structured_input.hidden_fsm_input.log_queue_state; + + let requests_queue_state = QueueState::conditionally_select( + cs, + start_flag, + &requests_queue_state_from_input, + &requests_queue_state_from_fsm, + ); + + let memory_queue_state_from_input = + structured_input.observable_input.initial_memory_queue_state; + + // it must be trivial + memory_queue_state_from_input.enforce_trivial_head(cs); + + let memory_queue_state_from_fsm = structured_input.hidden_fsm_input.memory_queue_state; + + let memory_queue_state = QueueState::conditionally_select( + cs, + start_flag, + &memory_queue_state_from_input, + &memory_queue_state_from_fsm, + ); + + let mut requests_queue = StorageLogQueue::::from_state(cs, requests_queue_state); + let queue_witness = CircuitQueueWitness::from_inner_witness(requests_queue_witness); + requests_queue.witness = Arc::new(queue_witness); + + let mut memory_queue = MemoryQueue::::from_state(cs, memory_queue_state); + + let one_u32 = UInt32::allocated_constant(cs, 1u32); + let zero_u256 = UInt256::zero(cs); + let boolean_false = Boolean::allocated_constant(cs, false); + let boolean_true = Boolean::allocated_constant(cs, true); + + use crate::storage_application::ConditionalWitnessAllocator; + let read_queries_allocator = ConditionalWitnessAllocator::> { + witness_source: Arc::new(RwLock::new(memory_reads_witness)), + }; + + for _cycle in 0..limit { + let is_empty = requests_queue.is_empty(cs); + let should_process = is_empty.negated(cs); + let (request, _) = requests_queue.pop_front(cs, should_process); + + let mut precompile_call_params = + EcrecoverPrecompileCallParams::from_encoding(cs, request.key); + + let timestamp_to_use_for_read = request.timestamp; + let timestamp_to_use_for_write = timestamp_to_use_for_read.add_no_overflow(cs, one_u32); + + Num::conditionally_enforce_equal( + cs, + should_process, + &Num::from_variable(request.aux_byte.get_variable()), + &Num::from_variable(aux_byte_for_precompile.get_variable()), + ); + for (a, b) in request + .address + .inner + .iter() + .zip(precompile_address.inner.iter()) + { + Num::conditionally_enforce_equal( + cs, + should_process, + &Num::from_variable(a.get_variable()), + &Num::from_variable(b.get_variable()), + ); + } + + let mut read_values = [zero_u256; NUM_MEMORY_READS_PER_CYCLE]; + let mut bias_variable = should_process.get_variable(); + for dst in read_values.iter_mut() { + let read_query_value: UInt256 = read_queries_allocator + .conditionally_allocate_biased(cs, should_process, bias_variable); + bias_variable = read_query_value.inner[0].get_variable(); + + *dst = read_query_value; + + let read_query = MemoryQuery { + timestamp: timestamp_to_use_for_read, + memory_page: precompile_call_params.input_page, + index: precompile_call_params.input_offset, + rw_flag: boolean_false, + is_ptr: boolean_false, + value: read_query_value, + }; + + let _ = memory_queue.push(cs, read_query, should_process); + + precompile_call_params.input_offset = precompile_call_params + .input_offset + .add_no_overflow(cs, one_u32); + } + + let [message_hash_as_u256, v_as_u256, r_as_u256, s_as_u256] = read_values; + let rec_id = v_as_u256.inner[0].to_le_bytes(cs)[0]; + + let (success, written_value) = ecrecover_precompile_inner_routine( + cs, + &rec_id, + &r_as_u256, + &s_as_u256, + &message_hash_as_u256, + valid_x_in_external_field.clone(), + valid_y_in_external_field.clone(), + valid_t_in_external_field.clone(), + &base_params, + &scalar_params, + ); + + let success_as_u32 = unsafe { UInt32::from_variable_unchecked(success.get_variable()) }; + let mut success_as_u256 = zero_u256; + success_as_u256.inner[0] = success_as_u32; + + let success_query = MemoryQuery { + timestamp: timestamp_to_use_for_write, + memory_page: precompile_call_params.output_page, + index: precompile_call_params.output_offset, + rw_flag: boolean_true, + value: success_as_u256, + is_ptr: boolean_false, + }; + + precompile_call_params.output_offset = precompile_call_params + .output_offset + .add_no_overflow(cs, one_u32); + + let _ = memory_queue.push(cs, success_query, should_process); + + let value_query = MemoryQuery { + timestamp: timestamp_to_use_for_write, + memory_page: precompile_call_params.output_page, + index: precompile_call_params.output_offset, + rw_flag: boolean_true, + value: written_value, + is_ptr: boolean_false, + }; + + let _ = memory_queue.push(cs, value_query, should_process); + } + + requests_queue.enforce_consistency(cs); + + // form the final state + let done = requests_queue.is_empty(cs); + structured_input.completion_flag = done; + structured_input.observable_output = PrecompileFunctionOutputData::placeholder(cs); + + let final_memory_state = memory_queue.into_state(); + let final_requets_state = requests_queue.into_state(); + + structured_input.observable_output.final_memory_state = QueueState::conditionally_select( + cs, + structured_input.completion_flag, + &final_memory_state, + &structured_input.observable_output.final_memory_state, + ); + + structured_input.hidden_fsm_output.log_queue_state = final_requets_state; + structured_input.hidden_fsm_output.memory_queue_state = final_memory_state; + + // self-check + structured_input.hook_compare_witness(cs, &closed_form_input); + + use boojum::cs::gates::PublicInputGate; + + let compact_form = + ClosedFormInputCompactForm::from_full_form(cs, &structured_input, round_function); + let input_commitment = commit_variable_length_encodable_item(cs, &compact_form, round_function); + for el in input_commitment.iter() { + let gate = PublicInputGate::new(el.get_variable()); + gate.add_to_cs(cs); + } + + input_commitment +} + +#[cfg(test)] +mod test { + use boojum::field::goldilocks::GoldilocksField; + use boojum::gadgets::traits::allocatable::CSAllocatable; + use boojum::pairing::ff::{Field, PrimeField, SqrtField}; + use boojum::worker::Worker; + + use super::*; + + type F = GoldilocksField; + type P = GoldilocksField; + + use boojum::config::DevCSConfig; + + use boojum::pairing::ff::PrimeFieldRepr; + use boojum::pairing::{GenericCurveAffine, GenericCurveProjective}; + use rand::Rng; + use rand::SeedableRng; + use rand::XorShiftRng; + + pub fn deterministic_rng() -> XorShiftRng { + XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]) + } + + fn simulate_signature() -> (Secp256Fr, Secp256Fr, Secp256Affine, Secp256Fr) { + let mut rng = deterministic_rng(); + let sk: Secp256Fr = rng.gen(); + + simulate_signature_for_sk(sk) + } + + fn transmute_representation(repr: T) -> U { + assert_eq!(std::mem::size_of::(), std::mem::size_of::()); + + unsafe { std::mem::transmute_copy::(&repr) } + } + + fn simulate_signature_for_sk( + sk: Secp256Fr, + ) -> (Secp256Fr, Secp256Fr, Secp256Affine, Secp256Fr) { + let mut rng = deterministic_rng(); + let pk = Secp256Affine::one().mul(sk.into_repr()).into_affine(); + let digest: Secp256Fr = rng.gen(); + let k: Secp256Fr = rng.gen(); + let r_point = Secp256Affine::one().mul(k.into_repr()).into_affine(); + + let r_x = r_point.into_xy_unchecked().0; + let r = transmute_representation::<_, ::Repr>(r_x.into_repr()); + let r = Secp256Fr::from_repr(r).unwrap(); + + let k_inv = k.inverse().unwrap(); + let mut s = r; + s.mul_assign(&sk); + s.add_assign(&digest); + s.mul_assign(&k_inv); + + { + let mut mul_by_generator = digest; + mul_by_generator.mul_assign(&r.inverse().unwrap()); + mul_by_generator.negate(); + + let mut mul_by_r = s; + mul_by_r.mul_assign(&r.inverse().unwrap()); + + let res_1 = Secp256Affine::one().mul(mul_by_generator.into_repr()); + let res_2 = r_point.mul(mul_by_r.into_repr()); + + let mut tmp = res_1; + tmp.add_assign(&res_2); + + let tmp = tmp.into_affine(); + + let x = tmp.into_xy_unchecked().0; + assert_eq!(x, pk.into_xy_unchecked().0); + } + + (r, s, pk, digest) + } + + fn repr_into_u256(repr: T) -> U256 { + let mut u256 = U256::zero(); + u256.0.copy_from_slice(&repr.as_ref()[..4]); + + u256 + } + + use boojum::cs::cs_builder::*; + use boojum::cs::cs_builder_reference::CsReferenceImplementationBuilder; + use boojum::cs::gates::*; + use boojum::cs::traits::gate::GatePlacementStrategy; + use boojum::cs::CSGeometry; + use boojum::cs::*; + use boojum::gadgets::tables::byte_split::ByteSplitTable; + use boojum::gadgets::tables::*; + + #[test] + fn test_signature_for_address_verification() { + let geometry = CSGeometry { + num_columns_under_copy_permutation: 100, + num_witness_columns: 0, + num_constant_columns: 8, + max_allowed_constraint_degree: 4, + }; + let max_variables = 1 << 26; + let max_trace_len = 1 << 20; + + fn configure< + F: SmallField, + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + let builder = builder.allow_lookup( + LookupParameters::UseSpecializedColumnsWithTableIdAsConstant { + width: 3, + num_repetitions: 8, + share_table_id: true, + }, + ); + let builder = ConstantsAllocatorGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = FmaGateInBaseFieldWithoutConstant::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ReductionGate::::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + // let owned_cs = ReductionGate::::configure_for_cs(owned_cs, GatePlacementStrategy::UseSpecializedColumns { num_repetitions: 8, share_constants: true }); + let builder = BooleanConstraintGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<32>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<16>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = SelectionGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ZeroCheckGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + false, + ); + let builder = DotProductGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + // let owned_cs = DotProductGate::<4>::configure_for_cs(owned_cs, GatePlacementStrategy::UseSpecializedColumns { num_repetitions: 1, share_constants: true }); + let builder = NopGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + + builder + } + + let builder_impl = CsReferenceImplementationBuilder::::new( + geometry, + max_variables, + max_trace_len, + ); + let builder = new_builder::<_, F>(builder_impl); + + let builder = configure(builder); + let mut owned_cs = builder.build(()); + + // add tables + let table = create_xor8_table(); + owned_cs.add_lookup_table::(table); + + let table = create_and8_table(); + owned_cs.add_lookup_table::(table); + + let table = create_byte_split_table::(); + owned_cs.add_lookup_table::, 3>(table); + let table = create_byte_split_table::(); + owned_cs.add_lookup_table::, 3>(table); + let table = create_byte_split_table::(); + owned_cs.add_lookup_table::, 3>(table); + let table = create_byte_split_table::(); + owned_cs.add_lookup_table::, 3>(table); + + let cs = &mut owned_cs; + + let sk = crate::ff::from_hex::( + "b5b1870957d373ef0eeffecc6e4812c0fd08f554b37b233526acc331bf1544f7", + ) + .unwrap(); + let eth_address = hex::decode("12890d2cce102216644c59dae5baed380d84830c").unwrap(); + let (r, s, _pk, digest) = simulate_signature_for_sk(sk); + + let scalar_params = secp256k1_scalar_field_params(); + let base_params = secp256k1_base_field_params(); + + let digest_u256 = repr_into_u256(digest.into_repr()); + let r_u256 = repr_into_u256(r.into_repr()); + let s_u256 = repr_into_u256(s.into_repr()); + + let rec_id = UInt8::allocate_checked(cs, 0); + let r = UInt256::allocate(cs, r_u256); + let s = UInt256::allocate(cs, s_u256); + let digest = UInt256::allocate(cs, digest_u256); + + let scalar_params = Arc::new(scalar_params); + let base_params = Arc::new(base_params); + + let valid_x_in_external_field = Secp256BaseNNField::allocated_constant( + cs, + Secp256Fq::from_str("9").unwrap(), + &base_params, + ); + let valid_t_in_external_field = Secp256BaseNNField::allocated_constant( + cs, + Secp256Fq::from_str("16").unwrap(), + &base_params, + ); + let valid_y_in_external_field = Secp256BaseNNField::allocated_constant( + cs, + Secp256Fq::from_str("4").unwrap(), + &base_params, + ); + + let (no_error, digest) = ecrecover_precompile_inner_routine( + cs, + &rec_id, + &r, + &s, + &digest, + valid_x_in_external_field.clone(), + valid_y_in_external_field.clone(), + valid_t_in_external_field.clone(), + &base_params, + &scalar_params, + ); + + assert!(no_error.witness_hook(&*cs)().unwrap() == true); + let recovered_address = digest.to_be_bytes(cs); + let recovered_address = recovered_address.witness_hook(cs)().unwrap(); + assert_eq!(&recovered_address[12..], ð_address[..]); + + dbg!(cs.next_available_row()); + + cs.pad_and_shrink(); + + let mut cs = owned_cs.into_assembly(); + cs.print_gate_stats(); + let worker = Worker::new(); + assert!(cs.check_if_satisfied(&worker)); + } +} diff --git a/crates/zkevm_circuits/src/ecrecover/decomp_table.rs b/crates/zkevm_circuits/src/ecrecover/decomp_table.rs new file mode 100644 index 0000000..636b64e --- /dev/null +++ b/crates/zkevm_circuits/src/ecrecover/decomp_table.rs @@ -0,0 +1,76 @@ +use super::*; +use crate::ecrecover::{secp256k1::fr::Fr, Secp256Affine}; +use boojum::cs::implementations::lookup_table::LookupTable; +use boojum::field::SmallField; +use boojum::pairing::ff::PrimeField; +use derivative::*; + +const TABLE_NAME: &'static str = "WNAFDECOMP table"; + +#[derive(Derivative)] +#[derivative(Clone, Copy, Debug, PartialEq, Eq)] +pub struct WnafDecompTable; + +const GLV_WINDOW_SIZE: usize = 2; +const TABLE_SIZE: i8 = 1 << (GLV_WINDOW_SIZE + 1); +const HALF_TABLE_SIZE: i8 = 1 << GLV_WINDOW_SIZE; +const MASK_FOR_MOD_TABLE_SIZE: u8 = (TABLE_SIZE as u8) - 1; + +// Lookups for wNAF decomposition of scalars. +pub fn create_wnaf_decomp_table() -> LookupTable { + let mut all_keys = Vec::with_capacity(1 << 8); + for a in 0..=u8::MAX { + let key = smallvec::smallvec![F::from_u64_unchecked(a as u64)]; + all_keys.push(key); + } + LookupTable::new_from_keys_and_generation_function( + &all_keys, + TABLE_NAME.to_string(), + 1, + |keys| { + let mut a = keys[0].as_u64_reduced() as u8; + let mut v = Vec::with_capacity(4); + let mut carry_bit = false; + for _ in 0..2 { + if a % 2 == 1 { + let mut naf = (a & MASK_FOR_MOD_TABLE_SIZE) as i8; + if naf >= HALF_TABLE_SIZE { + naf -= TABLE_SIZE + }; + + let naf_abs = naf.abs() as u8; + if naf < 0 { + if carry_bit { + a += naf_abs; + } else { + (a, carry_bit) = a.overflowing_add(naf_abs); + } + } else { + a -= naf_abs; + } + v.push(naf); + } else { + v.push(0i8); + } + + a >>= 1; + } + + let concat = { + let mut res = 0u32; + res |= (v[0] as u8) as u32; + let shifted_v1 = ((v[1] as u8) as u32) << 8; + res |= shifted_v1; + // Add carry bit if we overflowed + if carry_bit { + res |= 1 << 16; + } + res + }; + smallvec::smallvec![ + F::from_u64_unchecked(concat as u64), + F::from_u64_unchecked(a as u64) + ] + }, + ) +} diff --git a/crates/zkevm_circuits/src/ecrecover/input.rs b/crates/zkevm_circuits/src/ecrecover/input.rs new file mode 100644 index 0000000..2581b39 --- /dev/null +++ b/crates/zkevm_circuits/src/ecrecover/input.rs @@ -0,0 +1,51 @@ +use std::collections::VecDeque; + +use super::*; +use crate::base_structures::precompile_input_outputs::*; +use crate::base_structures::vm_state::*; +use boojum::cs::Variable; +use boojum::gadgets::queue::*; +use boojum::gadgets::traits::allocatable::CSAllocatable; +use boojum::gadgets::traits::allocatable::CSPlaceholder; +use boojum::gadgets::traits::encodable::CircuitVarLengthEncodable; + +use boojum::gadgets::traits::auxiliary::PrettyComparison; + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +#[DerivePrettyComparison("true")] +pub struct EcrecoverCircuitFSMInputOutput { + pub log_queue_state: QueueState, + pub memory_queue_state: QueueState, +} + +impl CSPlaceholder for EcrecoverCircuitFSMInputOutput { + fn placeholder>(cs: &mut CS) -> Self { + Self { + log_queue_state: QueueState::::placeholder(cs), + memory_queue_state: QueueState::::placeholder(cs), + } + } +} + +pub type EcrecoverCircuitInputOutput = ClosedFormInput< + F, + EcrecoverCircuitFSMInputOutput, + PrecompileFunctionInputData, + PrecompileFunctionOutputData, +>; +pub type EcrecoverCircuitInputOutputWitness = ClosedFormInputWitness< + F, + EcrecoverCircuitFSMInputOutput, + PrecompileFunctionInputData, + PrecompileFunctionOutputData, +>; + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Debug, Default)] +#[serde(bound = "")] +pub struct EcrecoverCircuitInstanceWitness { + pub closed_form_input: EcrecoverCircuitInputOutputWitness, + pub requests_queue_witness: CircuitQueueRawWitness, 4, LOG_QUERY_PACKED_WIDTH>, + pub memory_reads_witness: VecDeque<[U256; MEMORY_QUERIES_PER_CALL]>, +} diff --git a/crates/zkevm_circuits/src/ecrecover/mod.rs b/crates/zkevm_circuits/src/ecrecover/mod.rs new file mode 100644 index 0000000..7316c0b --- /dev/null +++ b/crates/zkevm_circuits/src/ecrecover/mod.rs @@ -0,0 +1,73 @@ +use super::*; +use crate::base_structures::log_query::*; +use crate::base_structures::memory_query::*; +use crate::base_structures::precompile_input_outputs::PrecompileFunctionOutputData; +use crate::demux_log_queue::StorageLogQueue; +use crate::ethereum_types::U256; +use crate::fsm_input_output::circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH; +use crate::fsm_input_output::*; +use arrayvec::ArrayVec; +use boojum::algebraic_props::round_function::AlgebraicRoundFunction; +use boojum::crypto_bigint::{Zero, U1024}; +use boojum::cs::gates::ConstantAllocatableCS; +use boojum::cs::traits::cs::ConstraintSystem; +use boojum::field::SmallField; +use boojum::gadgets::boolean::Boolean; +use boojum::gadgets::curves::sw_projective::SWProjectivePoint; +use boojum::gadgets::keccak256::keccak256; +use boojum::gadgets::non_native_field::implementations::*; +use boojum::gadgets::num::Num; +use boojum::gadgets::queue::CircuitQueueWitness; +use boojum::gadgets::queue::QueueState; +use boojum::gadgets::traits::allocatable::{CSAllocatableExt, CSPlaceholder}; +use boojum::gadgets::traits::round_function::CircuitRoundFunction; +use boojum::gadgets::traits::selectable::Selectable; +use boojum::gadgets::traits::witnessable::WitnessHookable; +use boojum::gadgets::u16::UInt16; +use boojum::gadgets::u160::UInt160; +use boojum::gadgets::u256::UInt256; +use boojum::gadgets::u32::UInt32; +use boojum::gadgets::u8::UInt8; +use cs_derive::*; +use std::collections::VecDeque; +use std::sync::{Arc, RwLock}; +use zkevm_opcode_defs::system_params::PRECOMPILE_AUX_BYTE; + +pub mod input; +pub use self::input::*; + +pub mod secp256k1; + +pub const MEMORY_QUERIES_PER_CALL: usize = 4; + +pub mod naf_abs_div2_table; +use naf_abs_div2_table::*; +pub mod decomp_table; +use decomp_table::*; + +pub mod baseline; +pub mod new_optimized; + +// characteristics of the base field for secp curve +use self::secp256k1::fq::Fq as Secp256Fq; +// order of group of points for secp curve +use self::secp256k1::fr::Fr as Secp256Fr; +// some affine point +use self::secp256k1::PointAffine as Secp256Affine; + +type Secp256BaseNNFieldParams = NonNativeFieldOverU16Params; +type Secp256ScalarNNFieldParams = NonNativeFieldOverU16Params; + +type Secp256BaseNNField = NonNativeFieldOverU16; +type Secp256ScalarNNField = NonNativeFieldOverU16; + +fn secp256k1_base_field_params() -> Secp256BaseNNFieldParams { + NonNativeFieldOverU16Params::create() +} + +fn secp256k1_scalar_field_params() -> Secp256ScalarNNFieldParams { + NonNativeFieldOverU16Params::create() +} + +// re-exports for integration +pub use self::baseline::{ecrecover_function_entry_point, EcrecoverPrecompileCallParams}; diff --git a/crates/zkevm_circuits/src/ecrecover/naf_abs_div2_table.rs b/crates/zkevm_circuits/src/ecrecover/naf_abs_div2_table.rs new file mode 100644 index 0000000..e83dd9a --- /dev/null +++ b/crates/zkevm_circuits/src/ecrecover/naf_abs_div2_table.rs @@ -0,0 +1,33 @@ +use super::*; +use crate::ecrecover::{secp256k1::fr::Fr, Secp256Affine}; +use boojum::cs::implementations::lookup_table::LookupTable; +use boojum::field::SmallField; +use boojum::pairing::ff::PrimeField; +use derivative::*; + +const TABLE_NAME: &'static str = "NAFABSDIV2 table"; + +#[derive(Derivative)] +#[derivative(Clone, Copy, Debug, PartialEq, Eq)] +pub struct NafAbsDiv2Table; + +// Quick table lookups in wNAF circuit +pub fn create_naf_abs_div2_table() -> LookupTable { + let mut all_keys = Vec::with_capacity(1 << 8); + for a in 0..=u8::MAX { + let key = smallvec::smallvec![F::from_u64_unchecked(a as u64)]; + all_keys.push(key); + } + LookupTable::new_from_keys_and_generation_function( + &all_keys, + TABLE_NAME.to_string(), + 1, + |keys| { + let a = keys[0].as_u64_reduced() as i8; + // we need unsigned abs, to handle i8::MIN + let v = a.unsigned_abs() >> 1; + + smallvec::smallvec![F::from_u64_unchecked(v as u64), F::from_u64_unchecked(0u64)] + }, + ) +} diff --git a/crates/zkevm_circuits/src/ecrecover/new_optimized.rs b/crates/zkevm_circuits/src/ecrecover/new_optimized.rs new file mode 100644 index 0000000..6d8d548 --- /dev/null +++ b/crates/zkevm_circuits/src/ecrecover/new_optimized.rs @@ -0,0 +1,1551 @@ +use super::*; +use crate::base_structures::log_query::*; +use crate::base_structures::memory_query::*; +use crate::base_structures::precompile_input_outputs::PrecompileFunctionOutputData; +use crate::demux_log_queue::StorageLogQueue; +use crate::ecrecover::secp256k1::fixed_base_mul_table::FixedBaseMulTable; +use crate::ethereum_types::U256; +use crate::fsm_input_output::circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH; +use crate::fsm_input_output::*; +use arrayvec::ArrayVec; +use boojum::algebraic_props::round_function::AlgebraicRoundFunction; +use boojum::crypto_bigint::{Zero, U1024}; +use boojum::cs::gates::ConstantAllocatableCS; +use boojum::cs::traits::cs::ConstraintSystem; +use boojum::cs::Variable; +use boojum::field::SmallField; +use boojum::gadgets::blake2s::mixing_function::merge_byte_using_table; +use boojum::gadgets::boolean::Boolean; +use boojum::gadgets::curves::sw_projective::SWProjectivePoint; +use boojum::gadgets::curves::zeroable_affine::ZeroableAffinePoint; +use boojum::gadgets::keccak256::keccak256; +use boojum::gadgets::non_native_field::implementations::*; +use boojum::gadgets::non_native_field::traits::NonNativeField; +use boojum::gadgets::num::Num; +use boojum::gadgets::queue::CircuitQueueWitness; +use boojum::gadgets::queue::QueueState; +use boojum::gadgets::tables::And8Table; +use boojum::gadgets::tables::ByteSplitTable; +use boojum::gadgets::traits::allocatable::{CSAllocatableExt, CSPlaceholder}; +use boojum::gadgets::traits::round_function::CircuitRoundFunction; +use boojum::gadgets::traits::selectable::Selectable; +use boojum::gadgets::traits::witnessable::WitnessHookable; +use boojum::gadgets::u16::UInt16; +use boojum::gadgets::u160::UInt160; +use boojum::gadgets::u256::UInt256; +use boojum::gadgets::u32::UInt32; +use boojum::gadgets::u512::UInt512; +use boojum::gadgets::u8::UInt8; +use boojum::pairing::ff::PrimeField; +use boojum::pairing::GenericCurveAffine; +use boojum::pairing::{CurveAffine, GenericCurveProjective}; +use boojum::sha3::digest::typenum::private::IsGreaterPrivate; +use cs_derive::*; +use std::collections::VecDeque; +use std::str::FromStr; +use std::sync::{Arc, RwLock}; +use zkevm_opcode_defs::system_params::PRECOMPILE_AUX_BYTE; + +pub use self::input::*; +use super::input::*; + +pub const MEMORY_QUERIES_PER_CALL: usize = 4; +pub const ALLOW_ZERO_MESSAGE: bool = false; + +#[derive(Derivative, CSSelectable)] +#[derivative(Clone, Debug)] +pub struct EcrecoverPrecompileCallParams { + pub input_page: UInt32, + pub input_offset: UInt32, + pub output_page: UInt32, + pub output_offset: UInt32, +} + +impl EcrecoverPrecompileCallParams { + pub fn from_encoding>(_cs: &mut CS, encoding: UInt256) -> Self { + let input_offset = encoding.inner[0]; + let output_offset = encoding.inner[2]; + let input_page = encoding.inner[4]; + let output_page = encoding.inner[5]; + + let new = Self { + input_page, + input_offset, + output_page, + output_offset, + }; + + new + } +} + +const NUM_WORDS: usize = 17; +const SECP_B_COEF: u64 = 7; +const EXCEPTION_FLAGS_ARR_LEN: usize = 9; +const NUM_MEMORY_READS_PER_CYCLE: usize = 4; +const X_POWERS_ARR_LEN: usize = 256; +const VALID_Y_IN_EXTERNAL_FIELD: u64 = 4; +const VALID_X_CUBED_IN_EXTERNAL_FIELD: u64 = 9; + +// GLV consts + +// 2**128 +const TWO_POW_128: &'static str = "340282366920938463463374607431768211456"; +// BETA s.t. for any curve point Q = (x,y): +// lambda * Q = (beta*x mod p, y) +const BETA: &'static str = + "55594575648329892869085402983802832744385952214688224221778511981742606582254"; +// Secp256k1.p - 1 / 2 +// 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc2f - 0x1 / 0x2 +const MODULUS_MINUS_ONE_DIV_TWO: &'static str = + "7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0"; +// Decomposition constants +// Derived through algorithm 3.74 http://tomlr.free.fr/Math%E9matiques/Math%20Complete/Cryptography/Guide%20to%20Elliptic%20Curve%20Cryptography%20-%20D.%20Hankerson,%20A.%20Menezes,%20S.%20Vanstone.pdf +// NOTE: B2 == A1 +const A1: &'static str = "0x3086d221a7d46bcde86c90e49284eb15"; +const B1: &'static str = "0xe4437ed6010e88286f547fa90abfe4c3"; +const A2: &'static str = "0x114ca50f7a8e2f3f657c1108d9d44cfd8"; + +// assume that constructed field element is not zero +// if this is not satisfied - set the result to be F::one +fn convert_uint256_to_field_element_masked< + F: SmallField, + CS: ConstraintSystem, + P: boojum::pairing::ff::PrimeField, + const N: usize, +>( + cs: &mut CS, + elem: &UInt256, + params: &Arc>, +) -> (NonNativeFieldOverU16, Boolean) +where + [(); N + 1]:, +{ + let is_zero = elem.is_zero(cs); + let one_nn = NonNativeFieldOverU16::::allocated_constant(cs, P::one(), params); + // we still have to decompose it into u16 words + let zero_var = cs.allocate_constant(F::ZERO); + let mut limbs = [zero_var; N]; + assert!(N >= 16); + for (dst, src) in limbs.array_chunks_mut::<2>().zip(elem.inner.iter()) { + let [b0, b1, b2, b3] = src.to_le_bytes(cs); + let low = UInt16::from_le_bytes(cs, [b0, b1]); + let high = UInt16::from_le_bytes(cs, [b2, b3]); + + *dst = [low.get_variable(), high.get_variable()]; + } + + let mut max_value = U1024::from_word(1u64); + max_value = max_value.shl_vartime(256); + max_value = max_value.saturating_sub(&U1024::from_word(1u64)); + + let (overflows, rem) = max_value.div_rem(¶ms.modulus_u1024); + + let mut max_moduluses = overflows.as_words()[0] as u32; + if rem.is_zero().unwrap_u8() != 1 { + max_moduluses += 1; + } + + let element = NonNativeFieldOverU16 { + limbs: limbs, + non_zero_limbs: 16, + tracker: OverflowTracker { max_moduluses }, + form: RepresentationForm::Normalized, + params: params.clone(), + _marker: std::marker::PhantomData, + }; + + let selected = Selectable::conditionally_select(cs, is_zero, &one_nn, &element); + + (selected, is_zero) +} + +fn convert_uint256_to_field_element< + F: SmallField, + CS: ConstraintSystem, + P: boojum::pairing::ff::PrimeField, + const N: usize, +>( + cs: &mut CS, + elem: &UInt256, + params: &Arc>, +) -> NonNativeFieldOverU16 { + // we still have to decompose it into u16 words + let zero_var = cs.allocate_constant(F::ZERO); + let mut limbs = [zero_var; N]; + assert!(N >= 16); + for (dst, src) in limbs.array_chunks_mut::<2>().zip(elem.inner.iter()) { + let [b0, b1, b2, b3] = src.to_le_bytes(cs); + let low = UInt16::from_le_bytes(cs, [b0, b1]); + let high = UInt16::from_le_bytes(cs, [b2, b3]); + + *dst = [low.get_variable(), high.get_variable()]; + } + + let mut max_value = U1024::from_word(1u64); + max_value = max_value.shl_vartime(256); + max_value = max_value.saturating_sub(&U1024::from_word(1u64)); + + let (overflows, rem) = max_value.div_rem(¶ms.modulus_u1024); + let mut max_moduluses = overflows.as_words()[0] as u32; + if rem.is_zero().unwrap_u8() != 1 { + max_moduluses += 1; + } + + let element = NonNativeFieldOverU16 { + limbs: limbs, + non_zero_limbs: 16, + tracker: OverflowTracker { max_moduluses }, + form: RepresentationForm::Normalized, + params: params.clone(), + _marker: std::marker::PhantomData, + }; + + element +} + +// NOTE: caller must ensure that the field element is normalized, otherwise this will fail. +fn convert_field_element_to_uint256< + F: SmallField, + CS: ConstraintSystem, + P: boojum::pairing::ff::PrimeField, + const N: usize, +>( + cs: &mut CS, + mut elem: NonNativeFieldOverU16, +) -> UInt256 { + assert_eq!(elem.form, RepresentationForm::Normalized); + assert_eq!(elem.tracker.max_moduluses, 1); + + let mut limbs = [UInt32::::zero(cs); 8]; + let two_pow_16 = Num::allocated_constant(cs, F::from_u64_unchecked(2u32.pow(16) as u64)); + for (dst, src) in limbs.iter_mut().zip(elem.limbs.array_chunks_mut::<2>()) { + let low = Num::from_variable(src[0]); + let high = Num::from_variable(src[1]); + *dst = unsafe { + UInt32::from_variable_unchecked( + Num::fma(cs, &high, &two_pow_16, &F::ONE, &low, &F::ONE).get_variable(), + ) + }; + } + + UInt256 { inner: limbs } +} + +fn to_wnaf>( + cs: &mut CS, + e: Secp256ScalarNNField, + neg: Boolean, + decomp_id: u32, + byte_split_id: u32, +) -> Vec> { + let mut naf = vec![]; + let mut bytes = e + .limbs + .iter() + .flat_map(|el| unsafe { UInt16::from_variable_unchecked(*el).to_le_bytes(cs) }) + .collect::>>(); + + // Loop for max amount of bits in e to ensure homogenous circuit + for i in 0..33 { + // Since each lookup consumes 2 bits of information, and we need at least 3 bits for + // figuring out the NAF number, we can do two lookups before needing to propagated the + // changes up the bytestring. + let mut naf_overflow = None; + for j in 0..2 { + let res = cs.perform_lookup::<1, 2>(decomp_id, &[bytes[0].get_variable()]); + let wnaf_and_carry_bits = unsafe { UInt32::from_variable_unchecked(res[0]) }; + let wnaf_bytes = wnaf_and_carry_bits.to_le_bytes(cs); + bytes[0] = unsafe { UInt8::from_variable_unchecked(res[1]) }; + wnaf_bytes[..2].iter().for_each(|byte| { + let byte_neg = byte.negate(cs); + let byte = Selectable::conditionally_select(cs, neg, byte, &byte_neg); + naf.push(byte); + }); + // Save carry bit. + // It only ever matters to save it on the first iteration as it is not possible + // to overflow for the second. + if j == 0 { + naf_overflow = Some(wnaf_bytes[2]); + } + } + + // Break up the first byte into a lower chunk and a (potential) carry bit. + let res = cs.perform_lookup::<1, 2>(byte_split_id, &[bytes[0].get_variable()]); + let mut low = res[0]; + let carry_bit = unsafe { UInt8::from_variable_unchecked(res[1]) }; + let mut of = Boolean::allocated_constant(cs, true); + + // Shift e and propagate carry. + // Because a GLV decomposed scalar is at most 129 bits, we only care to shift + // the lower 17 bytes of the number initially, and as we progress, more zero bytes + // will appear, lowering the amount of iterations needed to shift our number. + let num_iter = 16 - (i / 2); + bytes + .iter_mut() + .skip(1) + .take(num_iter) + .enumerate() + .for_each(|(i, b)| { + // Propagate carry + let (added_b, new_of) = b.overflowing_add(cs, &carry_bit); + *b = Selectable::conditionally_select(cs, of, &added_b, b); + of = new_of; + // If this is the first byte, we also add the NAF carry bit. + if i == 0 { + let naf_of; + (*b, naf_of) = b.overflowing_add(cs, &naf_overflow.unwrap()); + // If this overflows, we should remember to add a carry bit to the next element. + of = Selectable::conditionally_select(cs, naf_of, &naf_of, &of); + } + + // Glue bytes + let res = cs.perform_lookup::<1, 2>(byte_split_id, &[b.get_variable()]); + *b = unsafe { + UInt8::from_variable_unchecked(merge_byte_using_table::<_, _, 4>( + cs, low, res[0], + )) + }; + low = res[1]; + }); + + // Shift up by one to align. + bytes = bytes[1..].to_vec(); + } + + naf +} + +fn wnaf_scalar_mul>( + cs: &mut CS, + mut point: SWProjectivePoint>, + mut scalar: Secp256ScalarNNField, + base_field_params: &Arc, + scalar_field_params: &Arc, +) -> SWProjectivePoint> { + scalar.enforce_reduced(cs); + + let pow_2_128 = U256::from_dec_str(TWO_POW_128).unwrap(); + let pow_2_128 = UInt512::allocated_constant(cs, (pow_2_128, U256::zero())); + + let beta = Secp256Fq::from_str(BETA).unwrap(); + let mut beta = Secp256BaseNNField::allocated_constant(cs, beta, &base_field_params); + + let bigint_from_hex_str = |cs: &mut CS, s: &str| -> UInt512 { + let v = U256::from_str_radix(s, 16).unwrap(); + UInt512::allocated_constant(cs, (v, U256::zero())) + }; + + let modulus_minus_one_div_two = bigint_from_hex_str(cs, MODULUS_MINUS_ONE_DIV_TWO); + + // Scalar decomposition + let (k1_neg, k1, k2_neg, k2) = { + let u256_from_hex_str = |cs: &mut CS, s: &str| -> UInt256 { + let v = U256::from_str_radix(s, 16).unwrap(); + UInt256::allocated_constant(cs, v) + }; + + let a1 = u256_from_hex_str(cs, A1); + let b1 = u256_from_hex_str(cs, B1); + let a2 = u256_from_hex_str(cs, A2); + let b2 = a1.clone(); + + let k = convert_field_element_to_uint256(cs, scalar.clone()); + + // We take 8 non-zero limbs for the scalar (since it could be of any size), and 4 for B2 + // (since it fits in 128 bits). + let b2_times_k = k.widening_mul(cs, &b2, 8, 4); + let b2_times_k = b2_times_k.overflowing_add(cs, &modulus_minus_one_div_two); + let c1 = b2_times_k.0.to_high(); + + // We take 8 non-zero limbs for the scalar (since it could be of any size), and 4 for B1 + // (since it fits in 128 bits). + let b1_times_k = k.widening_mul(cs, &b1, 8, 4); + let b1_times_k = b1_times_k.overflowing_add(cs, &modulus_minus_one_div_two); + let c2 = b1_times_k.0.to_high(); + + let mut a1 = convert_uint256_to_field_element(cs, &a1, &scalar_field_params); + let mut b1 = convert_uint256_to_field_element(cs, &b1, &scalar_field_params); + let mut a2 = convert_uint256_to_field_element(cs, &a2, &scalar_field_params); + let mut b2 = a1.clone(); + let mut c1 = convert_uint256_to_field_element(cs, &c1, &scalar_field_params); + let mut c2 = convert_uint256_to_field_element(cs, &c2, &scalar_field_params); + + let mut c1_times_a1 = c1.mul(cs, &mut a1); + let mut c2_times_a2 = c2.mul(cs, &mut a2); + let mut k1 = scalar.sub(cs, &mut c1_times_a1).sub(cs, &mut c2_times_a2); + k1.normalize(cs); + let mut c2_times_b2 = c2.mul(cs, &mut b2); + let mut k2 = c1.mul(cs, &mut b1).sub(cs, &mut c2_times_b2); + k2.normalize(cs); + + let k1_u256 = convert_field_element_to_uint256(cs, k1.clone()); + let k2_u256 = convert_field_element_to_uint256(cs, k2.clone()); + let low_pow_2_128 = pow_2_128.to_low(); + let (_res, k1_neg) = k1_u256.overflowing_sub(cs, &low_pow_2_128); + let k1_negated = k1.negated(cs); + let k1 = as NonNativeField>::conditionally_select( + cs, + k1_neg, + &k1, + &k1_negated, + ); + let (_res, k2_neg) = k2_u256.overflowing_sub(cs, &low_pow_2_128); + let k2_negated = k2.negated(cs); + let k2 = as NonNativeField>::conditionally_select( + cs, + k2_neg, + &k2, + &k2_negated, + ); + + (k1_neg, k1, k2_neg, k2) + }; + + // WNAF + // The scalar multiplication window size. + const GLV_WINDOW_SIZE: usize = 2; + + // The GLV table length. + const L: usize = 1 << (GLV_WINDOW_SIZE - 1); + + let mut t1 = Vec::with_capacity(L); + // We use `convert_to_affine_or_default`, but we don't need to worry about returning 1, since + // we know that the point is not infinity. + let (mut double, _) = point + .double(cs) + .convert_to_affine_or_default(cs, Secp256Affine::one()); + t1.push(point.clone()); + for i in 1..L { + let next = t1[i - 1].add_mixed(cs, &mut double); + t1.push(next); + } + + let t1 = t1 + .iter_mut() + .map(|el| el.convert_to_affine_or_default(cs, Secp256Affine::one()).0) + .collect::>(); + + let t2 = t1 + .clone() + .into_iter() + .map(|mut el| (el.0.mul(cs, &mut beta), el.1)) + .collect::>(); + + let overflow_checker = UInt8::allocated_constant(cs, 2u8.pow(7)); + let decomp_id = cs + .get_table_id_for_marker::() + .expect("table should exist"); + let byte_split_id = cs + .get_table_id_for_marker::>() + .expect("table should exist"); + + let naf_abs_div2_table_id = cs + .get_table_id_for_marker::() + .expect("table must exist"); + let naf_add = + |cs: &mut CS, + table: &[(Secp256BaseNNField, Secp256BaseNNField)], + naf: UInt8, + acc: &mut SWProjectivePoint>| { + let is_zero = naf.is_zero(cs); + let index = unsafe { + UInt8::from_variable_unchecked( + cs.perform_lookup::<1, 2>(naf_abs_div2_table_id, &[naf.get_variable()])[0], + ) + }; + let coords = &table[index.witness_hook(cs)().unwrap() as usize]; + let mut p_1 = + SWProjectivePoint::>::from_xy_unchecked( + cs, + coords.0.clone(), + coords.1.clone(), + ); + let (_, naf_is_positive) = naf.overflowing_sub(cs, &overflow_checker); + let p_1_neg = p_1.negated(cs); + p_1 = Selectable::conditionally_select(cs, naf_is_positive, &p_1, &p_1_neg); + let acc_added = acc.add_mixed(cs, &mut (p_1.x, p_1.y)); + *acc = Selectable::conditionally_select(cs, is_zero, &acc, &acc_added); + }; + + let naf1 = to_wnaf(cs, k1, k1_neg, decomp_id, byte_split_id); + let naf2 = to_wnaf(cs, k2, k2_neg, decomp_id, byte_split_id); + let mut acc = + SWProjectivePoint::>::zero(cs, &base_field_params); + for i in (0..129).rev() { + naf_add(cs, &t1, naf1[i], &mut acc); + naf_add(cs, &t2, naf2[i], &mut acc); + if i != 0 { + acc = acc.double(cs); + } + } + + acc +} + +fn fixed_base_mul, F: SmallField>( + cs: &mut CS, + mut message_hash_by_r_inv: Secp256ScalarNNField, + base_field_params: &Arc, +) -> SWProjectivePoint> { + message_hash_by_r_inv.enforce_reduced(cs); + let is_zero = message_hash_by_r_inv.is_zero(cs); + let bytes = message_hash_by_r_inv + .limbs + .iter() + .take(16) + .flat_map(|el| unsafe { UInt16::from_variable_unchecked(*el).to_le_bytes(cs) }) + .collect::>>(); + + let zero_point = + SWProjectivePoint::>::zero(cs, base_field_params); + let mut acc = + SWProjectivePoint::>::zero(cs, base_field_params); + let mut full_table_ids = vec![]; + seq_macro::seq!(C in 0..32 { + let ids = vec![ + cs.get_table_id_for_marker::>() + .expect("table must exist"), + cs.get_table_id_for_marker::>() + .expect("table must exist"), + cs.get_table_id_for_marker::>() + .expect("table must exist"), + cs.get_table_id_for_marker::>() + .expect("table must exist"), + cs.get_table_id_for_marker::>() + .expect("table must exist"), + cs.get_table_id_for_marker::>() + .expect("table must exist"), + cs.get_table_id_for_marker::>() + .expect("table must exist"), + cs.get_table_id_for_marker::>() + .expect("table must exist"), + ]; + full_table_ids.push(ids); + }); + + full_table_ids + .into_iter() + .zip(bytes) + .rev() + .for_each(|(ids, byte)| { + // let chunks = ids + // .iter() + // .map(|id| cs.perform_lookup::<1, 2>(*id, &[byte.get_variable()])) + // .collect::>(); + + let (x, y): (Vec, Vec) = ids + .iter() + .flat_map(|id| { + let [x_v, y_v] = cs.perform_lookup::<1, 2>(*id, &[byte.get_variable()]); + let x_v = unsafe { UInt32::from_variable_unchecked(x_v) }; + let y_v = unsafe { UInt32::from_variable_unchecked(y_v) }; + let x_v = x_v.to_le_bytes(cs); + let y_v = y_v.to_le_bytes(cs); + let x_1 = UInt16::from_le_bytes(cs, x_v[..2].try_into().unwrap()); + let x_2 = UInt16::from_le_bytes(cs, x_v[2..].try_into().unwrap()); + let y_1 = UInt16::from_le_bytes(cs, y_v[..2].try_into().unwrap()); + let y_2 = UInt16::from_le_bytes(cs, y_v[2..].try_into().unwrap()); + [ + (x_1.get_variable(), y_1.get_variable()), + (x_2.get_variable(), y_2.get_variable()), + ] + }) + .collect::>() + .into_iter() + .unzip(); + let zero_var = cs.allocate_constant(F::ZERO); + let mut x_arr = [zero_var; 17]; + x_arr[..16].copy_from_slice(&x[..16]); + let mut y_arr = [zero_var; 17]; + y_arr[..16].copy_from_slice(&y[..16]); + let x = NonNativeFieldOverU16 { + limbs: x_arr, + non_zero_limbs: 16, + tracker: OverflowTracker { max_moduluses: 1 }, + form: RepresentationForm::Normalized, + params: base_field_params.clone(), + _marker: std::marker::PhantomData, + }; + let y = NonNativeFieldOverU16 { + limbs: y_arr, + non_zero_limbs: 16, + tracker: OverflowTracker { max_moduluses: 1 }, + form: RepresentationForm::Normalized, + params: base_field_params.clone(), + _marker: std::marker::PhantomData, + }; + acc = acc.add_mixed(cs, &mut (x, y)); + }); + acc = Selectable::conditionally_select(cs, is_zero, &zero_point, &acc); + acc +} + +fn ecrecover_precompile_inner_routine< + F: SmallField, + CS: ConstraintSystem, + const MESSAGE_HASH_CAN_BE_ZERO: bool, +>( + cs: &mut CS, + recid: &UInt8, + r: &UInt256, + s: &UInt256, + message_hash: &UInt256, + valid_x_in_external_field: Secp256BaseNNField, + valid_y_in_external_field: Secp256BaseNNField, + valid_t_in_external_field: Secp256BaseNNField, + base_field_params: &Arc, + scalar_field_params: &Arc, +) -> (Boolean, UInt256) { + use boojum::pairing::ff::Field; + let curve_b = Secp256Affine::b_coeff(); + + let mut minus_one = Secp256Fq::one(); + minus_one.negate(); + + let mut curve_b_nn = + Secp256BaseNNField::::allocated_constant(cs, curve_b, &base_field_params); + let mut minus_one_nn = + Secp256BaseNNField::::allocated_constant(cs, minus_one, &base_field_params); + + let secp_n_u256 = U256([ + scalar_field_params.modulus_u1024.as_ref().as_words()[0], + scalar_field_params.modulus_u1024.as_ref().as_words()[1], + scalar_field_params.modulus_u1024.as_ref().as_words()[2], + scalar_field_params.modulus_u1024.as_ref().as_words()[3], + ]); + let secp_n_u256 = UInt256::allocated_constant(cs, secp_n_u256); + + let secp_p_u256 = U256([ + base_field_params.modulus_u1024.as_ref().as_words()[0], + base_field_params.modulus_u1024.as_ref().as_words()[1], + base_field_params.modulus_u1024.as_ref().as_words()[2], + base_field_params.modulus_u1024.as_ref().as_words()[3], + ]); + let secp_p_u256 = UInt256::allocated_constant(cs, secp_p_u256); + + let mut exception_flags = ArrayVec::<_, EXCEPTION_FLAGS_ARR_LEN>::new(); + + // recid = (x_overflow ? 2 : 0) | (secp256k1_fe_is_odd(&r.y) ? 1 : 0) + // The point X = (x, y) we are going to recover is not known at the start, but it is strongly related to r. + // This is because x = r + kn for some integer k, where x is an element of the field F_q . In other words, x < q. + // (here n is the order of group of points on elleptic curve) + // For secp256k1 curve values of q and n are relatively close, that is, + // the probability of a random element of Fq being greater than n is about 1/{2^128}. + // This in turn means that the overwhelming majority of r determine a unique x, however some of them determine + // two: x = r and x = r + n. If x_overflow flag is set than x = r + n + + let [y_is_odd, x_overflow, ..] = + Num::::from_variable(recid.get_variable()).spread_into_bits::<_, 8>(cs); + + let (r_plus_n, of) = r.overflowing_add(cs, &secp_n_u256); + let mut x_as_u256 = UInt256::conditionally_select(cs, x_overflow, &r_plus_n, &r); + let error = Boolean::multi_and(cs, &[x_overflow, of]); + exception_flags.push(error); + + // we handle x separately as it is the only element of base field of a curve (not a scalar field element!) + // check that x < q - order of base point on Secp256 curve + // if it is not actually the case - mask x to be zero + let (_res, is_in_range) = x_as_u256.overflowing_sub(cs, &secp_p_u256); + x_as_u256 = x_as_u256.mask(cs, is_in_range); + let x_is_not_in_range = is_in_range.negated(cs); + exception_flags.push(x_is_not_in_range); + + let mut x_fe = convert_uint256_to_field_element(cs, &x_as_u256, &base_field_params); + + let (mut r_fe, r_is_zero) = + convert_uint256_to_field_element_masked(cs, &r, &scalar_field_params); + exception_flags.push(r_is_zero); + let (mut s_fe, s_is_zero) = + convert_uint256_to_field_element_masked(cs, &s, &scalar_field_params); + exception_flags.push(s_is_zero); + + let (mut message_hash_fe, message_hash_is_zero) = if MESSAGE_HASH_CAN_BE_ZERO { + ( + convert_uint256_to_field_element(cs, &message_hash, scalar_field_params), + Boolean::allocated_constant(cs, false), + ) + } else { + convert_uint256_to_field_element_masked(cs, &message_hash, scalar_field_params) + }; + exception_flags.push(message_hash_is_zero); + + // curve equation is y^2 = x^3 + b + // we compute t = r^3 + b and check if t is a quadratic residue or not. + // we do this by computing Legendre symbol (t, p) = t^[(p-1)/2] (mod p) + // p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1 + // n = (p-1)/2 = 2^255 - 2^31 - 2^8 - 2^7 - 2^6 - 2^5 - 2^3 - 1 + // we have to compute t^b = t^{2^255} / ( t^{2^31} * t^{2^8} * t^{2^7} * t^{2^6} * t^{2^5} * t^{2^3} * t) + // if t is not a quadratic residue we return error and replace x by another value that will make + // t = x^3 + b a quadratic residue + + let mut t = x_fe.square(cs); + t = t.mul(cs, &mut x_fe); + t = t.add(cs, &mut curve_b_nn); + + let t_is_zero = t.is_zero(cs); + exception_flags.push(t_is_zero); + + // if t is zero then just mask + let t = Selectable::conditionally_select(cs, t_is_zero, &valid_t_in_external_field, &t); + + // array of powers of t of the form t^{2^i} starting from i = 0 to 255 + let mut t_powers = Vec::with_capacity(X_POWERS_ARR_LEN); + t_powers.push(t); + + for _ in 1..X_POWERS_ARR_LEN { + let prev = t_powers.last_mut().unwrap(); + let next = prev.square(cs); + t_powers.push(next); + } + + let mut acc = t_powers[0].clone(); + for idx in [3, 5, 6, 7, 8, 31].into_iter() { + let other = &mut t_powers[idx]; + acc = acc.mul(cs, other); + } + let mut legendre_symbol = t_powers[255].div_unchecked(cs, &mut acc); + + // we can also reuse the same values to compute square root in case of p = 3 mod 4 + // p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1 + // n = (p+1)/4 = 2^254 - 2^30 - 2^7 - 2^6 - 2^5 - 2^4 - 2^2 + + let mut acc_2 = t_powers[2].clone(); + for idx in [4, 5, 6, 7, 30].into_iter() { + let other = &mut t_powers[idx]; + acc_2 = acc_2.mul(cs, other); + } + + let mut may_be_recovered_y = t_powers[254].div_unchecked(cs, &mut acc_2); + may_be_recovered_y.normalize(cs); + let may_be_recovered_y_negated = may_be_recovered_y.negated(cs); + + let [lowest_bit, ..] = + Num::::from_variable(may_be_recovered_y.limbs[0]).spread_into_bits::<_, 16>(cs); + + // if lowest bit != parity bit, then we need conditionally select + let should_swap = lowest_bit.xor(cs, y_is_odd); + let may_be_recovered_y = Selectable::conditionally_select( + cs, + should_swap, + &may_be_recovered_y_negated, + &may_be_recovered_y, + ); + + let t_is_nonresidue = + Secp256BaseNNField::::equals(cs, &mut legendre_symbol, &mut minus_one_nn); + exception_flags.push(t_is_nonresidue); + // unfortunately, if t is found to be a quadratic nonresidue, we can't simply let x to be zero, + // because then t_new = 7 is again a quadratic nonresidue. So, in this case we let x to be 9, then + // t = 16 is a quadratic residue + let x = + Selectable::conditionally_select(cs, t_is_nonresidue, &valid_x_in_external_field, &x_fe); + let y = Selectable::conditionally_select( + cs, + t_is_nonresidue, + &valid_y_in_external_field, + &may_be_recovered_y, + ); + + // we recovered (x, y) using curve equation, so it's on curve (or was masked) + let mut r_fe_inversed = r_fe.inverse_unchecked(cs); + let mut s_by_r_inv = s_fe.mul(cs, &mut r_fe_inversed); + let mut message_hash_by_r_inv = message_hash_fe.mul(cs, &mut r_fe_inversed); + + s_by_r_inv.normalize(cs); + message_hash_by_r_inv.normalize(cs); + + // now we are going to compute the public key Q = (x, y) determined by the formula: + // Q = (s * X - hash * G) / r which is equivalent to r * Q = s * X - hash * G + + let recovered_point = + SWProjectivePoint::>::from_xy_unchecked(cs, x, y); + // now we do multiplication + let mut s_times_x = wnaf_scalar_mul( + cs, + recovered_point.clone(), + s_by_r_inv.clone(), + &base_field_params, + &scalar_field_params, + ); + + let mut hash_times_g = fixed_base_mul(cs, message_hash_by_r_inv, &base_field_params); + + let (mut q_acc, is_infinity) = + hash_times_g.convert_to_affine_or_default(cs, Secp256Affine::one()); + let q_acc_added = s_times_x.add_mixed(cs, &mut q_acc); + let mut q_acc = Selectable::conditionally_select(cs, is_infinity, &s_times_x, &q_acc_added); + + let ((q_x, q_y), is_infinity) = q_acc.convert_to_affine_or_default(cs, Secp256Affine::one()); + exception_flags.push(is_infinity); + let any_exception = Boolean::multi_or(cs, &exception_flags[..]); + + let zero_u8 = UInt8::zero(cs); + + let mut bytes_to_hash = [zero_u8; 64]; + let it = q_x.limbs[..16] + .iter() + .rev() + .chain(q_y.limbs[..16].iter().rev()); + + for (dst, src) in bytes_to_hash.array_chunks_mut::<2>().zip(it) { + let limb = unsafe { UInt16::from_variable_unchecked(*src) }; + *dst = limb.to_be_bytes(cs); + } + + let mut digest_bytes = keccak256(cs, &bytes_to_hash); + // digest is 32 bytes, but we need only 20 to recover address + digest_bytes[0..12].copy_from_slice(&[zero_u8; 12]); // empty out top bytes + digest_bytes.reverse(); + let written_value_unmasked = UInt256::from_le_bytes(cs, digest_bytes); + + let written_value = written_value_unmasked.mask_negated(cs, any_exception); + let all_ok = any_exception.negated(cs); + + (all_ok, written_value) +} + +pub fn ecrecover_function_entry_point< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, +>( + cs: &mut CS, + witness: EcrecoverCircuitInstanceWitness, + round_function: &R, + limit: usize, +) -> [Num; INPUT_OUTPUT_COMMITMENT_LENGTH] +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, +{ + assert!(limit <= u32::MAX as usize); + + let EcrecoverCircuitInstanceWitness { + closed_form_input, + requests_queue_witness, + memory_reads_witness, + } = witness; + + let memory_reads_witness: VecDeque<_> = memory_reads_witness.into_iter().flatten().collect(); + + let precompile_address = UInt160::allocated_constant( + cs, + *zkevm_opcode_defs::system_params::ECRECOVER_INNER_FUNCTION_PRECOMPILE_FORMAL_ADDRESS, + ); + let aux_byte_for_precompile = UInt8::allocated_constant(cs, PRECOMPILE_AUX_BYTE); + + let scalar_params = Arc::new(secp256k1_scalar_field_params()); + let base_params = Arc::new(secp256k1_base_field_params()); + + use boojum::pairing::ff::PrimeField; + + let valid_x_in_external_field = Secp256BaseNNField::allocated_constant( + cs, + Secp256Fq::from_str(&VALID_X_CUBED_IN_EXTERNAL_FIELD.to_string()).unwrap(), + &base_params, + ); + let valid_t_in_external_field = Secp256BaseNNField::allocated_constant( + cs, + Secp256Fq::from_str(&(VALID_X_CUBED_IN_EXTERNAL_FIELD + SECP_B_COEF).to_string()).unwrap(), + &base_params, + ); + let valid_y_in_external_field = Secp256BaseNNField::allocated_constant( + cs, + Secp256Fq::from_str(&VALID_Y_IN_EXTERNAL_FIELD.to_string()).unwrap(), + &base_params, + ); + + let mut structured_input = + EcrecoverCircuitInputOutput::alloc_ignoring_outputs(cs, closed_form_input.clone()); + let start_flag = structured_input.start_flag; + + let requests_queue_state_from_input = structured_input.observable_input.initial_log_queue_state; + + // it must be trivial + requests_queue_state_from_input.enforce_trivial_head(cs); + + let requests_queue_state_from_fsm = structured_input.hidden_fsm_input.log_queue_state; + + let requests_queue_state = QueueState::conditionally_select( + cs, + start_flag, + &requests_queue_state_from_input, + &requests_queue_state_from_fsm, + ); + + let memory_queue_state_from_input = + structured_input.observable_input.initial_memory_queue_state; + + // it must be trivial + memory_queue_state_from_input.enforce_trivial_head(cs); + + let memory_queue_state_from_fsm = structured_input.hidden_fsm_input.memory_queue_state; + + let memory_queue_state = QueueState::conditionally_select( + cs, + start_flag, + &memory_queue_state_from_input, + &memory_queue_state_from_fsm, + ); + + let mut requests_queue = StorageLogQueue::::from_state(cs, requests_queue_state); + let queue_witness = CircuitQueueWitness::from_inner_witness(requests_queue_witness); + requests_queue.witness = Arc::new(queue_witness); + + let mut memory_queue = MemoryQueue::::from_state(cs, memory_queue_state); + + let one_u32 = UInt32::allocated_constant(cs, 1u32); + let zero_u256 = UInt256::zero(cs); + let boolean_false = Boolean::allocated_constant(cs, false); + let boolean_true = Boolean::allocated_constant(cs, true); + + use crate::storage_application::ConditionalWitnessAllocator; + let read_queries_allocator = ConditionalWitnessAllocator::> { + witness_source: Arc::new(RwLock::new(memory_reads_witness)), + }; + + for _cycle in 0..limit { + let is_empty = requests_queue.is_empty(cs); + let should_process = is_empty.negated(cs); + let (request, _) = requests_queue.pop_front(cs, should_process); + + let mut precompile_call_params = + EcrecoverPrecompileCallParams::from_encoding(cs, request.key); + + let timestamp_to_use_for_read = request.timestamp; + let timestamp_to_use_for_write = timestamp_to_use_for_read.add_no_overflow(cs, one_u32); + + Num::conditionally_enforce_equal( + cs, + should_process, + &Num::from_variable(request.aux_byte.get_variable()), + &Num::from_variable(aux_byte_for_precompile.get_variable()), + ); + for (a, b) in request + .address + .inner + .iter() + .zip(precompile_address.inner.iter()) + { + Num::conditionally_enforce_equal( + cs, + should_process, + &Num::from_variable(a.get_variable()), + &Num::from_variable(b.get_variable()), + ); + } + + let mut read_values = [zero_u256; NUM_MEMORY_READS_PER_CYCLE]; + let mut bias_variable = should_process.get_variable(); + for dst in read_values.iter_mut() { + let read_query_value: UInt256 = read_queries_allocator + .conditionally_allocate_biased(cs, should_process, bias_variable); + bias_variable = read_query_value.inner[0].get_variable(); + + *dst = read_query_value; + + let read_query = MemoryQuery { + timestamp: timestamp_to_use_for_read, + memory_page: precompile_call_params.input_page, + index: precompile_call_params.input_offset, + rw_flag: boolean_false, + is_ptr: boolean_false, + value: read_query_value, + }; + + let _ = memory_queue.push(cs, read_query, should_process); + + precompile_call_params.input_offset = precompile_call_params + .input_offset + .add_no_overflow(cs, one_u32); + } + + let [message_hash_as_u256, v_as_u256, r_as_u256, s_as_u256] = read_values; + let rec_id = v_as_u256.inner[0].to_le_bytes(cs)[0]; + + let (success, written_value) = ecrecover_precompile_inner_routine::<_, _, ALLOW_ZERO_MESSAGE>( + cs, + &rec_id, + &r_as_u256, + &s_as_u256, + &message_hash_as_u256, + valid_x_in_external_field.clone(), + valid_y_in_external_field.clone(), + valid_t_in_external_field.clone(), + &base_params, + &scalar_params, + ); + + let success_as_u32 = unsafe { UInt32::from_variable_unchecked(success.get_variable()) }; + let mut success_as_u256 = zero_u256; + success_as_u256.inner[0] = success_as_u32; + + let success_query = MemoryQuery { + timestamp: timestamp_to_use_for_write, + memory_page: precompile_call_params.output_page, + index: precompile_call_params.output_offset, + rw_flag: boolean_true, + value: success_as_u256, + is_ptr: boolean_false, + }; + + precompile_call_params.output_offset = precompile_call_params + .output_offset + .add_no_overflow(cs, one_u32); + + let _ = memory_queue.push(cs, success_query, should_process); + + let value_query = MemoryQuery { + timestamp: timestamp_to_use_for_write, + memory_page: precompile_call_params.output_page, + index: precompile_call_params.output_offset, + rw_flag: boolean_true, + value: written_value, + is_ptr: boolean_false, + }; + + let _ = memory_queue.push(cs, value_query, should_process); + } + + requests_queue.enforce_consistency(cs); + + // form the final state + let done = requests_queue.is_empty(cs); + structured_input.completion_flag = done; + structured_input.observable_output = PrecompileFunctionOutputData::placeholder(cs); + + let final_memory_state = memory_queue.into_state(); + let final_requets_state = requests_queue.into_state(); + + structured_input.observable_output.final_memory_state = QueueState::conditionally_select( + cs, + structured_input.completion_flag, + &final_memory_state, + &structured_input.observable_output.final_memory_state, + ); + + structured_input.hidden_fsm_output.log_queue_state = final_requets_state; + structured_input.hidden_fsm_output.memory_queue_state = final_memory_state; + + // self-check + structured_input.hook_compare_witness(cs, &closed_form_input); + + use boojum::cs::gates::PublicInputGate; + + let compact_form = + ClosedFormInputCompactForm::from_full_form(cs, &structured_input, round_function); + let input_commitment = commit_variable_length_encodable_item(cs, &compact_form, round_function); + for el in input_commitment.iter() { + let gate = PublicInputGate::new(el.get_variable()); + gate.add_to_cs(cs); + } + + input_commitment +} + +#[cfg(test)] +mod test { + use boojum::field::goldilocks::GoldilocksField; + use boojum::gadgets::traits::allocatable::CSAllocatable; + use boojum::pairing::ff::{Field, PrimeField, SqrtField}; + use boojum::worker::Worker; + + use super::*; + + type F = GoldilocksField; + type P = GoldilocksField; + + use boojum::config::DevCSConfig; + + use boojum::pairing::ff::PrimeFieldRepr; + use boojum::pairing::{GenericCurveAffine, GenericCurveProjective}; + use rand::Rng; + use rand::SeedableRng; + use rand::XorShiftRng; + + pub fn deterministic_rng() -> XorShiftRng { + XorShiftRng::from_seed([0x5dbe6259, 0x8d313d76, 0x3237db17, 0xe5bc0654]) + } + + fn simulate_signature() -> (Secp256Fr, Secp256Fr, Secp256Affine, Secp256Fr) { + let mut rng = deterministic_rng(); + let sk: Secp256Fr = rng.gen(); + + simulate_signature_for_sk(sk) + } + + fn transmute_representation(repr: T) -> U { + assert_eq!(std::mem::size_of::(), std::mem::size_of::()); + + unsafe { std::mem::transmute_copy::(&repr) } + } + + fn simulate_signature_for_sk( + sk: Secp256Fr, + ) -> (Secp256Fr, Secp256Fr, Secp256Affine, Secp256Fr) { + let mut rng = deterministic_rng(); + let pk = Secp256Affine::one().mul(sk.into_repr()).into_affine(); + let digest: Secp256Fr = rng.gen(); + let k: Secp256Fr = rng.gen(); + let r_point = Secp256Affine::one().mul(k.into_repr()).into_affine(); + + let r_x = r_point.into_xy_unchecked().0; + let r = transmute_representation::<_, ::Repr>(r_x.into_repr()); + let r = Secp256Fr::from_repr(r).unwrap(); + + let k_inv = k.inverse().unwrap(); + let mut s = r; + s.mul_assign(&sk); + s.add_assign(&digest); + s.mul_assign(&k_inv); + + { + let mut mul_by_generator = digest; + mul_by_generator.mul_assign(&r.inverse().unwrap()); + mul_by_generator.negate(); + + let mut mul_by_r = s; + mul_by_r.mul_assign(&r.inverse().unwrap()); + + let res_1 = Secp256Affine::one().mul(mul_by_generator.into_repr()); + let res_2 = r_point.mul(mul_by_r.into_repr()); + + let mut tmp = res_1; + tmp.add_assign(&res_2); + + let tmp = tmp.into_affine(); + + let x = tmp.into_xy_unchecked().0; + assert_eq!(x, pk.into_xy_unchecked().0); + } + + (r, s, pk, digest) + } + + fn repr_into_u256(repr: T) -> U256 { + let mut u256 = U256::zero(); + u256.0.copy_from_slice(&repr.as_ref()[..4]); + + u256 + } + + use crate::ecrecover::secp256k1::fixed_base_mul_table::{ + create_fixed_base_mul_table, FixedBaseMulTable, + }; + use boojum::cs::cs_builder::*; + use boojum::cs::cs_builder_reference::CsReferenceImplementationBuilder; + use boojum::cs::gates::*; + use boojum::cs::implementations::reference_cs::CSReferenceImplementation; + use boojum::cs::traits::gate::GatePlacementStrategy; + use boojum::cs::CSGeometry; + use boojum::cs::*; + use boojum::gadgets::tables::byte_split::ByteSplitTable; + use boojum::gadgets::tables::*; + + fn create_cs( + max_trace_len: usize, + ) -> CSReferenceImplementation< + F, + P, + DevCSConfig, + impl GateConfigurationHolder, + impl StaticToolboxHolder, + > { + let geometry = CSGeometry { + num_columns_under_copy_permutation: 100, + num_witness_columns: 0, + num_constant_columns: 8, + max_allowed_constraint_degree: 4, + }; + let max_variables = 1 << 26; + + fn configure< + F: SmallField, + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + let builder = builder.allow_lookup( + LookupParameters::UseSpecializedColumnsWithTableIdAsConstant { + width: 3, + num_repetitions: 8, + share_table_id: true, + }, + ); + let builder = U8x4FMAGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ConstantsAllocatorGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = FmaGateInBaseFieldWithoutConstant::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ReductionGate::::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + // let owned_cs = ReductionGate::::configure_for_cs(owned_cs, GatePlacementStrategy::UseSpecializedColumns { num_repetitions: 8, share_constants: true }); + let builder = BooleanConstraintGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<32>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<16>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<8>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = SelectionGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ZeroCheckGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + false, + ); + let builder = DotProductGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + // let owned_cs = DotProductGate::<4>::configure_for_cs(owned_cs, GatePlacementStrategy::UseSpecializedColumns { num_repetitions: 1, share_constants: true }); + let builder = NopGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + + builder + } + + let builder_impl = CsReferenceImplementationBuilder::::new( + geometry, + max_variables, + max_trace_len, + ); + let builder = new_builder::<_, F>(builder_impl); + + let builder = configure(builder); + let mut owned_cs = builder.build(()); + + // add tables + let table = create_xor8_table(); + owned_cs.add_lookup_table::(table); + + let table = create_and8_table(); + owned_cs.add_lookup_table::(table); + + let table = create_naf_abs_div2_table(); + owned_cs.add_lookup_table::(table); + + let table = create_wnaf_decomp_table(); + owned_cs.add_lookup_table::(table); + + seq_macro::seq!(C in 0..32 { + let table = create_fixed_base_mul_table::(); + owned_cs.add_lookup_table::, 3>(table); + let table = create_fixed_base_mul_table::(); + owned_cs.add_lookup_table::, 3>(table); + let table = create_fixed_base_mul_table::(); + owned_cs.add_lookup_table::, 3>(table); + let table = create_fixed_base_mul_table::(); + owned_cs.add_lookup_table::, 3>(table); + let table = create_fixed_base_mul_table::(); + owned_cs.add_lookup_table::, 3>(table); + let table = create_fixed_base_mul_table::(); + owned_cs.add_lookup_table::, 3>(table); + let table = create_fixed_base_mul_table::(); + owned_cs.add_lookup_table::, 3>(table); + let table = create_fixed_base_mul_table::(); + owned_cs.add_lookup_table::, 3>(table); + }); + + let table = create_byte_split_table::(); + owned_cs.add_lookup_table::, 3>(table); + let table = create_byte_split_table::(); + owned_cs.add_lookup_table::, 3>(table); + let table = create_byte_split_table::(); + owned_cs.add_lookup_table::, 3>(table); + let table = create_byte_split_table::(); + owned_cs.add_lookup_table::, 3>(table); + + owned_cs + } + + #[test] + fn test_signature_for_address_verification() { + let mut owned_cs = create_cs(1 << 20); + let cs = &mut owned_cs; + + let sk = crate::ff::from_hex::( + "b5b1870957d373ef0eeffecc6e4812c0fd08f554b37b233526acc331bf1544f7", + ) + .unwrap(); + let eth_address = hex::decode("12890d2cce102216644c59dae5baed380d84830c").unwrap(); + let (r, s, _pk, digest) = simulate_signature_for_sk(sk); + + let scalar_params = secp256k1_scalar_field_params(); + let base_params = secp256k1_base_field_params(); + + let digest_u256 = repr_into_u256(digest.into_repr()); + let r_u256 = repr_into_u256(r.into_repr()); + let s_u256 = repr_into_u256(s.into_repr()); + + let rec_id = UInt8::allocate_checked(cs, 0); + let r = UInt256::allocate(cs, r_u256); + let s = UInt256::allocate(cs, s_u256); + let digest = UInt256::allocate(cs, digest_u256); + + let scalar_params = Arc::new(scalar_params); + let base_params = Arc::new(base_params); + + let valid_x_in_external_field = Secp256BaseNNField::allocated_constant( + cs, + Secp256Fq::from_str("9").unwrap(), + &base_params, + ); + let valid_t_in_external_field = Secp256BaseNNField::allocated_constant( + cs, + Secp256Fq::from_str("16").unwrap(), + &base_params, + ); + let valid_y_in_external_field = Secp256BaseNNField::allocated_constant( + cs, + Secp256Fq::from_str("4").unwrap(), + &base_params, + ); + + for _ in 0..5 { + let (no_error, digest) = ecrecover_precompile_inner_routine::<_, _, false>( + cs, + &rec_id, + &r, + &s, + &digest, + valid_x_in_external_field.clone(), + valid_y_in_external_field.clone(), + valid_t_in_external_field.clone(), + &base_params, + &scalar_params, + ); + + assert!(no_error.witness_hook(&*cs)().unwrap() == true); + let recovered_address = digest.to_be_bytes(cs); + let recovered_address = recovered_address.witness_hook(cs)().unwrap(); + assert_eq!(&recovered_address[12..], ð_address[..]); + } + + dbg!(cs.next_available_row()); + + cs.pad_and_shrink(); + + let mut cs = owned_cs.into_assembly(); + cs.print_gate_stats(); + let worker = Worker::new(); + assert!(cs.check_if_satisfied(&worker)); + } + + #[test] + fn test_ecrecover_zero_elements() { + let mut owned_cs = create_cs(1 << 21); + let cs = &mut owned_cs; + + let sk = crate::ff::from_hex::( + "b5b1870957d373ef0eeffecc6e4812c0fd08f554b37b233526acc331bf1544f7", + ) + .unwrap(); + let (r, s, _pk, digest) = simulate_signature_for_sk(sk); + + let scalar_params = secp256k1_scalar_field_params(); + let base_params = secp256k1_base_field_params(); + + let zero_digest = Secp256Fr::zero(); + let zero_r = Secp256Fr::zero(); + let zero_s = Secp256Fr::zero(); + + let digest_u256 = repr_into_u256(digest.into_repr()); + let r_u256 = repr_into_u256(r.into_repr()); + let s_u256 = repr_into_u256(s.into_repr()); + + let zero_digest_u256 = repr_into_u256(zero_digest.into_repr()); + let zero_r_u256 = repr_into_u256(zero_r.into_repr()); + let zero_s_u256 = repr_into_u256(zero_s.into_repr()); + + let rec_id = UInt8::allocate_checked(cs, 0); + let r = UInt256::allocate(cs, r_u256); + let s = UInt256::allocate(cs, s_u256); + let digest = UInt256::allocate(cs, digest_u256); + + let zero_r = UInt256::allocate(cs, zero_r_u256); + let zero_s = UInt256::allocate(cs, zero_s_u256); + let zero_digest = UInt256::allocate(cs, zero_digest_u256); + + // Create an r that is unrecoverable. + let r_unrecoverable = + UInt256::allocate(cs, U256::from(0u64).overflowing_sub(U256::from(1u64)).0); + + let scalar_params = Arc::new(scalar_params); + let base_params = Arc::new(base_params); + + let valid_x_in_external_field = Secp256BaseNNField::allocated_constant( + cs, + Secp256Fq::from_str("9").unwrap(), + &base_params, + ); + let valid_t_in_external_field = Secp256BaseNNField::allocated_constant( + cs, + Secp256Fq::from_str("16").unwrap(), + &base_params, + ); + let valid_y_in_external_field = Secp256BaseNNField::allocated_constant( + cs, + Secp256Fq::from_str("4").unwrap(), + &base_params, + ); + + // Construct a table of all combinations of correct and incorrect values + // for r, s, and digest. + let r_values = vec![r, zero_r, r_unrecoverable]; + let s_values = vec![s, zero_s]; + let digest_values = vec![digest, zero_digest]; + + // We ensure that there are no combinations where all correct items are chosen, so that we + // can consistently check for errors. + let mut first = true; + let mut all_combinations = vec![]; + for r in r_values.iter() { + for s in s_values.iter() { + for digest in digest_values.iter() { + if first { + first = false; + continue; + } + all_combinations.push((r.clone(), s.clone(), digest.clone())); + } + } + } + + for (r, s, digest) in all_combinations.into_iter() { + let (no_error, _digest) = ecrecover_precompile_inner_routine::<_, _, false>( + cs, + &rec_id, + &r, + &s, + &digest, + valid_x_in_external_field.clone(), + valid_y_in_external_field.clone(), + valid_t_in_external_field.clone(), + &base_params, + &scalar_params, + ); + + assert!(no_error.witness_hook(&*cs)().unwrap() == false); + } + } + + // As discussed on ethresearch forums, a caller may 'abuse' ecrecover in order to compute a + // secp256k1 ecmul in the EVM. This test compares the result of an ecrecover scalar mul with + // the output of a previously tested ecmul in the EVM. + // + // It works as follows: given a point x coordinate `r`, we set `s` to be `r * k` for some `k`. + // This then works out in the secp256k1 recover equation to create the equation + // `res = (r, y) * r * k * inv(r, P)` which is equal to `res = (r, y) * k`, effectively + // performing a scalar multiplication. + // + // https://ethresear.ch/t/you-can-kinda-abuse-ecrecover-to-do-ecmul-in-secp256k1-today/2384 + #[test] + fn test_ecrecover_scalar_mul_trick() { + use rand::Rand; + let mut owned_cs = create_cs(1 << 20); + let cs = &mut owned_cs; + + // NOTE: This is essentially reducing a base field to a scalar field element. Due to the + // nature of the recovery equation turning into `(r, y) * r * k * inv(r, P)`, reducing r to + // a scalar value would yield the same result regardless. + let r = crate::ff::from_hex::( + "00000000000000009b37e91445e92b1423354825aa33d841d83cacfdd895d316ae88dabc31736996", + ) + .unwrap(); + let k = crate::ff::from_hex::( + "0000000000000000005aa98b08426f9dea29001fc925f3f35a10c9927082fe4d026cc485d1ebb430", + ) + .unwrap(); + let mut s = r.clone(); + s.mul_assign(&k); + let evm_tested_digest = hex::decode("eDc01060fdD6592f54A63EAE6C89436675C4d70D").unwrap(); + + let scalar_params = secp256k1_scalar_field_params(); + let base_params = secp256k1_base_field_params(); + + let r_u256 = repr_into_u256(r.into_repr()); + let s_u256 = repr_into_u256(s.into_repr()); + + let rec_id = UInt8::allocate_checked(cs, 0); + let r = UInt256::allocate(cs, r_u256); + let s = UInt256::allocate(cs, s_u256); + let digest = UInt256::allocate(cs, U256::zero()); + + let scalar_params = Arc::new(scalar_params); + let base_params = Arc::new(base_params); + + let valid_x_in_external_field = Secp256BaseNNField::allocated_constant( + cs, + Secp256Fq::from_str("9").unwrap(), + &base_params, + ); + let valid_t_in_external_field = Secp256BaseNNField::allocated_constant( + cs, + Secp256Fq::from_str("16").unwrap(), + &base_params, + ); + let valid_y_in_external_field = Secp256BaseNNField::allocated_constant( + cs, + Secp256Fq::from_str("4").unwrap(), + &base_params, + ); + + for _ in 0..5 { + let (no_error, digest) = ecrecover_precompile_inner_routine::<_, _, true>( + cs, + &rec_id, + &r, + &s, + &digest, + valid_x_in_external_field.clone(), + valid_y_in_external_field.clone(), + valid_t_in_external_field.clone(), + &base_params, + &scalar_params, + ); + + // Zero digest shouldn't give us an error + assert!(no_error.witness_hook(&*cs)().unwrap() == true); + let recovered_address = digest.to_be_bytes(cs); + let recovered_address = recovered_address.witness_hook(cs)().unwrap(); + assert_eq!(&recovered_address[12..], &evm_tested_digest[..]); + } + + dbg!(cs.next_available_row()); + + cs.pad_and_shrink(); + + let mut cs = owned_cs.into_assembly(); + cs.print_gate_stats(); + let worker = Worker::new(); + assert!(cs.check_if_satisfied(&worker)); + } +} diff --git a/crates/zkevm_circuits/src/ecrecover/secp256k1/fixed_base_mul_table.rs b/crates/zkevm_circuits/src/ecrecover/secp256k1/fixed_base_mul_table.rs new file mode 100644 index 0000000..8aec309 --- /dev/null +++ b/crates/zkevm_circuits/src/ecrecover/secp256k1/fixed_base_mul_table.rs @@ -0,0 +1,55 @@ +use super::*; +use crate::ecrecover::{secp256k1::fr::Fr, Secp256Affine}; +use boojum::cs::implementations::lookup_table::LookupTable; +use boojum::field::SmallField; +use boojum::pairing::ff::PrimeField; +use derivative::*; + +const TABLE_NAME: &'static str = "FIXEDBASEMUL table"; + +#[derive(Derivative)] +#[derivative(Clone, Copy, Debug, PartialEq, Eq)] +pub struct FixedBaseMulTable; + +// Allows for a radix scalar mul by storing all potential exponentiations +// of the generator with 0..255 +pub fn create_fixed_base_mul_table( +) -> LookupTable { + assert!(INDEX < 8); + assert!(B < 32); + let mut all_keys = Vec::with_capacity(1 << 8); + for a in 0..=u8::MAX { + let key = smallvec::smallvec![F::from_u64_unchecked(a as u64)]; + all_keys.push(key); + } + let mut generator = Secp256Affine::one(); + generator.negate(); + let r = Fr::from_str("256").unwrap(); + LookupTable::new_from_keys_and_generation_function( + &all_keys, + TABLE_NAME.to_string(), + 1, + |keys| { + let a = keys[0].as_u64_reduced(); + let b = r.pow([B]); + let mut exp = Fr::from_str(&a.to_string()).unwrap(); + exp.mul_assign(&b); + let result = generator.mul(exp); + let result = result.into_affine(); + let is_even = INDEX % 2 == 0; + let res = [result.x, result.y] + .iter() + .map(|c| { + let index = INDEX / 2; + let segment = c.into_repr().0[index]; + if is_even { + F::from_u64_unchecked(segment & (u32::MAX as u64)) + } else { + F::from_u64_unchecked(segment >> 32) + } + }) + .collect::>(); + smallvec::smallvec![res[0], res[1]] + }, + ) +} diff --git a/crates/zkevm_circuits/src/ecrecover/secp256k1/fq.rs b/crates/zkevm_circuits/src/ecrecover/secp256k1/fq.rs new file mode 100644 index 0000000..ac08cfd --- /dev/null +++ b/crates/zkevm_circuits/src/ecrecover/secp256k1/fq.rs @@ -0,0 +1,7 @@ +use boojum::pairing::ff::*; + +// base field, Q = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F +#[derive(PrimeField)] +#[PrimeFieldModulus = "115792089237316195423570985008687907853269984665640564039457584007908834671663"] +#[PrimeFieldGenerator = "2"] +pub struct Fq(FqRepr); diff --git a/crates/zkevm_circuits/src/ecrecover/secp256k1/fr.rs b/crates/zkevm_circuits/src/ecrecover/secp256k1/fr.rs new file mode 100644 index 0000000..7240987 --- /dev/null +++ b/crates/zkevm_circuits/src/ecrecover/secp256k1/fr.rs @@ -0,0 +1,7 @@ +use boojum::pairing::ff::*; + +// scalar field, R = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 +#[derive(PrimeField)] +#[PrimeFieldModulus = "115792089237316195423570985008687907852837564279074904382605163141518161494337"] +#[PrimeFieldGenerator = "2"] +pub struct Fr(FrRepr); diff --git a/crates/zkevm_circuits/src/ecrecover/secp256k1/mod.rs b/crates/zkevm_circuits/src/ecrecover/secp256k1/mod.rs new file mode 100644 index 0000000..83e13fa --- /dev/null +++ b/crates/zkevm_circuits/src/ecrecover/secp256k1/mod.rs @@ -0,0 +1,762 @@ +use boojum::pairing::ff::BitIterator; +use boojum::pairing::ff::*; +use boojum::pairing::{ + EncodingBytes, GenericCompressedEncodable, GenericCurveAffine, GenericCurveProjective, + GenericUncompressedEncodable, GroupDecodingError, +}; + +pub mod fixed_base_mul_table; +pub mod fq; +pub mod fr; + +use fixed_base_mul_table::*; +use fq::*; +use fr::*; + +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub struct PointAffine { + pub(crate) x: Fq, + pub(crate) y: Fq, + pub(crate) infinity: bool, +} + +static NAME_STR: &'static str = "Secp256k1"; + +impl ::std::fmt::Display for PointAffine { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + if self.infinity { + write!(f, "{}(Infinity)", NAME_STR) + } else { + write!(f, "{}(x={}, y={})", NAME_STR, self.x, self.y) + } + } +} + +#[derive(Copy, Clone, Debug, Eq)] +pub struct PointProjective { + pub(crate) x: Fq, + pub(crate) y: Fq, + pub(crate) z: Fq, +} + +impl ::std::fmt::Display for PointProjective { + fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result { + write!(f, "{}", self.into_affine()) + } +} + +impl PartialEq for PointProjective { + fn eq(&self, other: &PointProjective) -> bool { + if self.is_zero() { + return other.is_zero(); + } + + if other.is_zero() { + return false; + } + + // The points (X, Y, Z) and (X', Y', Z') + // are equal when (X * Z^2) = (X' * Z'^2) + // and (Y * Z^3) = (Y' * Z'^3). + + let mut z1 = self.z; + z1.square(); + let mut z2 = other.z; + z2.square(); + + let mut tmp1 = self.x; + tmp1.mul_assign(&z2); + + let mut tmp2 = other.x; + tmp2.mul_assign(&z1); + + if tmp1 != tmp2 { + return false; + } + + z1.mul_assign(&self.z); + z2.mul_assign(&other.z); + z2.mul_assign(&self.y); + z1.mul_assign(&other.y); + + if z1 != z2 { + return false; + } + + true + } +} + +impl PointAffine { + fn mul_bits>(&self, bits: BitIterator) -> PointProjective { + let mut res = PointProjective::zero(); + for i in bits { + res.double(); + if i { + res.add_assign_mixed(self) + } + } + res + } + + /// Attempts to construct an affine point given an x-coordinate. The + /// point is not guaranteed to be in the prime order subgroup. + /// + /// If and only if `greatest` is set will the lexicographically + /// largest y-coordinate be selected. + fn get_point_from_x(x: Fq, greatest: bool) -> Option { + // Compute x^3 + b + let mut x3b = x; + x3b.square(); + x3b.mul_assign(&x); + x3b.add_assign(&PointAffine::get_coeff_b()); + + x3b.sqrt().map(|y| { + let mut negy = y; + negy.negate(); + + PointAffine { + x: x, + y: if (y < negy) ^ greatest { y } else { negy }, + infinity: false, + } + }) + } + + fn is_on_curve(&self) -> bool { + if self.is_zero() { + true + } else { + // Check that the point is on the curve + let mut y2 = self.y; + y2.square(); + + let mut x3b = self.x; + x3b.square(); + x3b.mul_assign(&self.x); + x3b.add_assign(&Self::get_coeff_b()); + + y2 == x3b + } + } +} + +impl GenericCurveAffine for PointAffine { + type Scalar = Fr; + type Base = Fq; + type Projective = PointProjective; + + fn zero() -> Self { + PointAffine { + x: Fq::zero(), + y: Fq::one(), + infinity: true, + } + } + + fn one() -> Self { + Self::get_generator() + } + + fn is_zero(&self) -> bool { + self.infinity + } + + fn mul::Repr>>(&self, by: S) -> PointProjective { + let bits = BitIterator::new(by.into()); + self.mul_bits(bits) + } + + fn negate(&mut self) { + if !self.is_zero() { + self.y.negate(); + } + } + + fn into_projective(&self) -> PointProjective { + (*self).into() + } + + #[inline(always)] + fn as_xy(&self) -> (&Self::Base, &Self::Base) { + (&self.x, &self.y) + } + + #[inline(always)] + fn into_xy_unchecked(self) -> (Self::Base, Self::Base) { + (self.x, self.y) + } + + #[inline(always)] + fn from_xy_unchecked(x: Self::Base, y: Self::Base) -> Self { + let infinity = x.is_zero() && y.is_zero(); + Self { + x: x, + y: y, + infinity, + } + } + + fn from_xy_checked(x: Self::Base, y: Self::Base) -> Result { + let infinity = x.is_zero() && y.is_zero(); + let affine = Self { + x: x, + y: y, + infinity, + }; + + if !affine.is_on_curve() { + Err(GroupDecodingError::NotOnCurve) + } else { + Ok(affine) + } + } + + fn a_coeff() -> Self::Base { + Self::Base::zero() + } + + fn b_coeff() -> Self::Base { + Self::get_coeff_b() + } +} + +impl GenericCurveProjective for PointProjective { + type Scalar = Fr; + type Base = Fq; + type Affine = PointAffine; + + // The point at infinity is always represented by + // Z = 0. + fn zero() -> Self { + PointProjective { + x: Fq::zero(), + y: Fq::one(), + z: Fq::zero(), + } + } + + fn one() -> Self { + PointAffine::one().into() + } + + // The point at infinity is always represented by + // Z = 0. + fn is_zero(&self) -> bool { + self.z.is_zero() + } + + fn is_normalized(&self) -> bool { + self.is_zero() || self.z == Fq::one() + } + + fn batch_normalization(v: &mut [Self]) { + // Montgomery’s Trick and Fast Implementation of Masked AES + // Genelle, Prouff and Quisquater + // Section 3.2 + + // First pass: compute [a, ab, abc, ...] + let mut prod = Vec::with_capacity(v.len()); + let mut tmp = Fq::one(); + for g in v + .iter_mut() + // Ignore normalized elements + .filter(|g| !g.is_normalized()) + { + tmp.mul_assign(&g.z); + prod.push(tmp); + } + + // Invert `tmp`. + tmp = tmp.inverse().unwrap(); // Guaranteed to be nonzero. + + // Second pass: iterate backwards to compute inverses + for (g, s) in v + .iter_mut() + // Backwards + .rev() + // Ignore normalized elements + .filter(|g| !g.is_normalized()) + // Backwards, skip last element, fill in one for last term. + .zip(prod.into_iter().rev().skip(1).chain(Some(Fq::one()))) + { + // tmp := tmp * g.z; g.z := tmp * s = 1/z + let mut newtmp = tmp; + newtmp.mul_assign(&g.z); + g.z = tmp; + g.z.mul_assign(&s); + tmp = newtmp; + } + + // Perform affine transformations + for g in v.iter_mut().filter(|g| !g.is_normalized()) { + let mut z = g.z; // 1/z + z.square(); // 1/z^2 + g.x.mul_assign(&z); // x/z^2 + z.mul_assign(&g.z); // 1/z^3 + g.y.mul_assign(&z); // y/z^3 + g.z = Fq::one(); // z = 1 + } + } + + fn double(&mut self) { + if self.is_zero() { + return; + } + + // Other than the point at infinity, no points on E or E' + // can double to equal the point at infinity, as y=0 is + // never true for points on the curve. + + // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l + + // A = X1^2 + let mut a = self.x; + a.square(); + + // B = Y1^2 + let mut b = self.y; + b.square(); + + // C = B^2 + let mut c = b; + c.square(); + + // D = 2*((X1+B)2-A-C) + let mut d = self.x; + d.add_assign(&b); + d.square(); + d.sub_assign(&a); + d.sub_assign(&c); + d.double(); + + // E = 3*A + let mut e = a; + e.double(); + e.add_assign(&a); + + // F = E^2 + let mut f = e; + f.square(); + + // Z3 = 2*Y1*Z1 + self.z.mul_assign(&self.y); + self.z.double(); + + // X3 = F-2*D + self.x = f; + self.x.sub_assign(&d); + self.x.sub_assign(&d); + + // Y3 = E*(D-X3)-8*C + self.y = d; + self.y.sub_assign(&self.x); + self.y.mul_assign(&e); + c.double(); + c.double(); + c.double(); + self.y.sub_assign(&c); + } + + fn add_assign(&mut self, other: &Self) { + if self.is_zero() { + *self = *other; + return; + } + + if other.is_zero() { + return; + } + + // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl + + // Z1Z1 = Z1^2 + let mut z1z1 = self.z; + z1z1.square(); + + // Z2Z2 = Z2^2 + let mut z2z2 = other.z; + z2z2.square(); + + // U1 = X1*Z2Z2 + let mut u1 = self.x; + u1.mul_assign(&z2z2); + + // U2 = X2*Z1Z1 + let mut u2 = other.x; + u2.mul_assign(&z1z1); + + // S1 = Y1*Z2*Z2Z2 + let mut s1 = self.y; + s1.mul_assign(&other.z); + s1.mul_assign(&z2z2); + + // S2 = Y2*Z1*Z1Z1 + let mut s2 = other.y; + s2.mul_assign(&self.z); + s2.mul_assign(&z1z1); + + if u1 == u2 && s1 == s2 { + // The two points are equal, so we double. + self.double(); + } else { + // If we're adding -a and a together, self.z becomes zero as H becomes zero. + + if u1 == u2 { + // The two points are equal, so we double. + (*self) = Self::zero(); + return; + } + + // H = U2-U1 + let mut h = u2; + h.sub_assign(&u1); + + // I = (2*H)^2 + let mut i = h; + i.double(); + i.square(); + + // J = H*I + let mut j = h; + j.mul_assign(&i); + + // r = 2*(S2-S1) + let mut r = s2; + r.sub_assign(&s1); + r.double(); + + // V = U1*I + let mut v = u1; + v.mul_assign(&i); + + // X3 = r^2 - J - 2*V + self.x = r; + self.x.square(); + self.x.sub_assign(&j); + self.x.sub_assign(&v); + self.x.sub_assign(&v); + + // Y3 = r*(V - X3) - 2*S1*J + self.y = v; + self.y.sub_assign(&self.x); + self.y.mul_assign(&r); + s1.mul_assign(&j); // S1 = S1 * J * 2 + s1.double(); + self.y.sub_assign(&s1); + + // Z3 = ((Z1+Z2)^2 - Z1Z1 - Z2Z2)*H + self.z.add_assign(&other.z); + self.z.square(); + self.z.sub_assign(&z1z1); + self.z.sub_assign(&z2z2); + self.z.mul_assign(&h); + } + } + + fn add_assign_mixed(&mut self, other: &Self::Affine) { + if other.is_zero() { + return; + } + + if self.is_zero() { + self.x = other.x; + self.y = other.y; + self.z = Fq::one(); + return; + } + + // http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl + + // Z1Z1 = Z1^2 + let mut z1z1 = self.z; + z1z1.square(); + + // U2 = X2*Z1Z1 + let mut u2 = other.x; + u2.mul_assign(&z1z1); + + // S2 = Y2*Z1*Z1Z1 + let mut s2 = other.y; + s2.mul_assign(&self.z); + s2.mul_assign(&z1z1); + + if self.x == u2 && self.y == s2 { + // The two points are equal, so we double. + self.double(); + } else { + // If we're adding -a and a together, self.z becomes zero as H becomes zero. + + // H = U2-X1 + let mut h = u2; + h.sub_assign(&self.x); + + // HH = H^2 + let mut hh = h; + hh.square(); + + // I = 4*HH + let mut i = hh; + i.double(); + i.double(); + + // J = H*I + let mut j = h; + j.mul_assign(&i); + + // r = 2*(S2-Y1) + let mut r = s2; + r.sub_assign(&self.y); + r.double(); + + // V = X1*I + let mut v = self.x; + v.mul_assign(&i); + + // X3 = r^2 - J - 2*V + self.x = r; + self.x.square(); + self.x.sub_assign(&j); + self.x.sub_assign(&v); + self.x.sub_assign(&v); + + // Y3 = r*(V-X3)-2*Y1*J + j.mul_assign(&self.y); // J = 2*Y1*J + j.double(); + self.y = v; + self.y.sub_assign(&self.x); + self.y.mul_assign(&r); + self.y.sub_assign(&j); + + // Z3 = (Z1+H)^2-Z1Z1-HH + self.z.add_assign(&h); + self.z.square(); + self.z.sub_assign(&z1z1); + self.z.sub_assign(&hh); + } + } + + fn negate(&mut self) { + if !self.is_zero() { + self.y.negate() + } + } + + fn mul_assign::Repr>>(&mut self, other: S) { + let mut res = Self::zero(); + + let mut found_one = false; + + for i in BitIterator::new(other.into()) { + if found_one { + res.double(); + } else { + found_one = i; + } + + if i { + res.add_assign(self); + } + } + + *self = res; + } + + fn into_affine(&self) -> PointAffine { + (*self).into() + } + + fn recommended_wnaf_for_scalar(scalar: ::Repr) -> usize { + Self::empirical_recommended_wnaf_for_scalar(scalar) + } + + fn recommended_wnaf_for_num_scalars(num_scalars: usize) -> usize { + Self::empirical_recommended_wnaf_for_num_scalars(num_scalars) + } + + fn as_xyz(&self) -> (&Self::Base, &Self::Base, &Self::Base) { + (&self.x, &self.y, &self.z) + } + + fn into_xyz_unchecked(self) -> (Self::Base, Self::Base, Self::Base) { + (self.x, self.y, self.z) + } + + fn from_xyz_unchecked(x: Self::Base, y: Self::Base, z: Self::Base) -> Self { + Self { x, y, z } + } + + fn from_xyz_checked( + _x: Self::Base, + _y: Self::Base, + _z: Self::Base, + ) -> Result { + unimplemented!() + } +} + +// The affine point X, Y is represented in the jacobian +// coordinates with Z = 1. +impl From for PointProjective { + fn from(p: PointAffine) -> PointProjective { + if p.is_zero() { + PointProjective::zero() + } else { + PointProjective { + x: p.x, + y: p.y, + z: Fq::one(), + } + } + } +} + +// The projective point X, Y, Z is represented in the affine +// coordinates as X/Z^2, Y/Z^3. +impl From for PointAffine { + fn from(p: PointProjective) -> PointAffine { + if p.is_zero() { + PointAffine::zero() + } else if p.z == Fq::one() { + // If Z is one, the point is already normalized. + PointAffine { + x: p.x, + y: p.y, + infinity: false, + } + } else { + // Z is nonzero, so it must have an inverse in a field. + let zinv = p.z.inverse().unwrap(); + let mut zinv_powered = zinv; + zinv_powered.square(); + + // X/Z^2 + let mut x = p.x; + x.mul_assign(&zinv_powered); + + // Y/Z^3 + let mut y = p.y; + zinv_powered.mul_assign(&zinv); + y.mul_assign(&zinv_powered); + + PointAffine { + x: x, + y: y, + infinity: false, + } + } + } +} + +impl rand::Rand for PointProjective { + fn rand(rng: &mut R) -> Self { + loop { + let x = rng.gen(); + let greatest = rng.gen(); + + if let Some(p) = PointAffine::get_point_from_x(x, greatest) { + if !p.is_zero() { + if p.is_on_curve() { + return p.into_projective(); + } + } + } + } + } +} + +impl rand::Rand for PointAffine { + fn rand(rng: &mut R) -> Self { + loop { + let x = rng.gen(); + let greatest = rng.gen(); + + if let Some(p) = PointAffine::get_point_from_x(x, greatest) { + if !p.is_zero() { + if p.is_on_curve() { + return p; + } + } + } + } + } +} + +impl PointAffine { + fn get_coeff_b() -> ::Base { + Fq::from_str("7").unwrap() + } + + fn get_generator() -> Self { + Self { + x: crate::ff::from_hex::( + "0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", + ) + .unwrap(), + y: crate::ff::from_hex::( + "0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", + ) + .unwrap(), + infinity: false, + } + } +} + +impl PointProjective { + fn empirical_recommended_wnaf_for_scalar(scalar: FrRepr) -> usize { + let num_bits = scalar.num_bits() as usize; + + if num_bits >= 130 { + 4 + } else if num_bits >= 34 { + 3 + } else { + 2 + } + } + + fn empirical_recommended_wnaf_for_num_scalars(num_scalars: usize) -> usize { + const RECOMMENDATIONS: [usize; 12] = + [1, 3, 7, 20, 43, 120, 273, 563, 1630, 3128, 7933, 62569]; + + let mut ret = 4; + for r in &RECOMMENDATIONS { + if num_scalars > *r { + ret += 1; + } else { + break; + } + } + + ret + } +} + +impl GenericUncompressedEncodable<64> for PointAffine { + /// Converts this element into its uncompressed encoding, so long as it's not + /// the point at infinity. + fn into_uncompressed(&self) -> EncodingBytes { + todo!() + } + + /// Converts an uncompressed encoding into the curve point + fn from_uncompressed(_encoding: EncodingBytes) -> Result { + todo!() + } +} + +impl GenericCompressedEncodable<32> for PointAffine { + /// Converts this element into its uncompressed encoding, so long as it's not + /// the point at infinity. + fn into_compressed(&self) -> (EncodingBytes, bool) { + todo!(); + } + + /// Converts an uncompressed encoding into the curve point + fn from_compressed( + _encoding: EncodingBytes, + _parity: bool, + ) -> Result { + todo!() + } +} diff --git a/crates/zkevm_circuits/src/fsm_input_output/circuit_inputs/main_vm.rs b/crates/zkevm_circuits/src/fsm_input_output/circuit_inputs/main_vm.rs new file mode 100644 index 0000000..4a2c639 --- /dev/null +++ b/crates/zkevm_circuits/src/fsm_input_output/circuit_inputs/main_vm.rs @@ -0,0 +1,71 @@ +use super::*; + +use crate::base_structures::vm_state::*; +use boojum::gadgets::queue::*; +use boojum::serde_utils::BigArraySerde; + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Debug)] +pub struct VmInputData { + pub rollback_queue_tail_for_block: [Num; QUEUE_STATE_WIDTH], + pub memory_queue_initial_state: QueueTailState, + pub decommitment_queue_initial_state: QueueTailState, + pub per_block_context: GlobalContext, +} + +impl CSPlaceholder for VmInputData { + fn placeholder>(cs: &mut CS) -> Self { + let zero_num = Num::zero(cs); + let empty_tail = QueueTailState::placeholder(cs); + let placeholder_ctx = GlobalContext::::placeholder(cs); + Self { + rollback_queue_tail_for_block: [zero_num; QUEUE_STATE_WIDTH], + memory_queue_initial_state: empty_tail, + decommitment_queue_initial_state: empty_tail, + per_block_context: placeholder_ctx, + } + } +} + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Debug)] +#[DerivePrettyComparison("true")] +pub struct VmOutputData { + pub log_queue_final_state: QueueState, + pub memory_queue_final_state: QueueState, + pub decommitment_queue_final_state: QueueState, +} + +impl CSPlaceholder for VmOutputData { + fn placeholder>(cs: &mut CS) -> Self { + let empty_small = QueueState::placeholder(cs); + let empty_large = QueueState::placeholder(cs); + Self { + log_queue_final_state: empty_small, + memory_queue_final_state: empty_large, + decommitment_queue_final_state: empty_large, + } + } +} + +use crate::base_structures::vm_state::VmLocalState; + +pub type VmCircuitInputOutput = + crate::fsm_input_output::ClosedFormInput, VmInputData, VmOutputData>; +pub type VmCircuitInputOutputWitness = crate::fsm_input_output::ClosedFormInputWitness< + F, + VmLocalState, + VmInputData, + VmOutputData, +>; + +use crate::main_vm::witness_oracle::WitnessOracle; + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Debug(bound = ""), Default)] +#[serde(bound = "")] +pub struct VmCircuitWitness> { + pub closed_form_input: VmCircuitInputOutputWitness, + #[derivative(Debug = "ignore")] + pub witness_oracle: W, +} diff --git a/crates/zkevm_circuits/src/fsm_input_output/circuit_inputs/mod.rs b/crates/zkevm_circuits/src/fsm_input_output/circuit_inputs/mod.rs new file mode 100644 index 0000000..4befa82 --- /dev/null +++ b/crates/zkevm_circuits/src/fsm_input_output/circuit_inputs/mod.rs @@ -0,0 +1,6 @@ +use super::*; +use boojum::cs::Variable; + +pub const INPUT_OUTPUT_COMMITMENT_LENGTH: usize = 4; + +pub mod main_vm; diff --git a/crates/zkevm_circuits/src/fsm_input_output/mod.rs b/crates/zkevm_circuits/src/fsm_input_output/mod.rs new file mode 100644 index 0000000..c6205f5 --- /dev/null +++ b/crates/zkevm_circuits/src/fsm_input_output/mod.rs @@ -0,0 +1,326 @@ +use super::*; +use boojum::gadgets::traits::auxiliary::PrettyComparison; +use cs_derive::*; + +use boojum::cs::gates::ConstantAllocatableCS; +use boojum::cs::traits::cs::ConstraintSystem; +use boojum::cs::Variable; +use boojum::field::SmallField; +use boojum::gadgets::boolean::Boolean; +use boojum::gadgets::num::Num; +use boojum::gadgets::traits::allocatable::CSAllocatable; +use boojum::gadgets::traits::allocatable::CSPlaceholder; +use boojum::gadgets::traits::encodable::CircuitVarLengthEncodable; +use boojum::gadgets::traits::round_function::CircuitRoundFunction; +use boojum::gadgets::traits::selectable::Selectable; +use boojum::gadgets::traits::witnessable::WitnessHookable; +use boojum::gadgets::u32::UInt32; +use boojum::serde_utils::BigArraySerde; + +pub mod circuit_inputs; + +#[derive(Derivative, CSAllocatable, WitnessHookable)] +#[WitnessHookBound( + " +where + >::Witness: serde::Serialize + serde::de::DeserializeOwned + Eq, + >::Witness: serde::Serialize + serde::de::DeserializeOwned + Eq, + >::Witness: serde::Serialize + serde::de::DeserializeOwned + Eq, +" +)] +#[derivative(Clone, Debug)] +pub struct ClosedFormInput< + F: SmallField, + T: Clone + std::fmt::Debug + CSAllocatable + CircuitVarLengthEncodable + WitnessHookable, + IN: Clone + std::fmt::Debug + CSAllocatable + CircuitVarLengthEncodable + WitnessHookable, + OUT: Clone + std::fmt::Debug + CSAllocatable + CircuitVarLengthEncodable + WitnessHookable, +> where + >::Witness: serde::Serialize + serde::de::DeserializeOwned + Eq, + >::Witness: serde::Serialize + serde::de::DeserializeOwned + Eq, + >::Witness: serde::Serialize + serde::de::DeserializeOwned + Eq, +{ + pub start_flag: Boolean, + pub completion_flag: Boolean, + pub observable_input: IN, + pub observable_output: OUT, + pub hidden_fsm_input: T, + pub hidden_fsm_output: T, +} + +impl< + F: SmallField, + T: Clone + + std::fmt::Debug + + CSAllocatable + + CircuitVarLengthEncodable + + WitnessHookable, + IN: Clone + + std::fmt::Debug + + CSAllocatable + + CircuitVarLengthEncodable + + WitnessHookable, + OUT: Clone + + std::fmt::Debug + + CSAllocatable + + CircuitVarLengthEncodable + + WitnessHookable, + > ClosedFormInput +where + >::Witness: serde::Serialize + serde::de::DeserializeOwned + Eq, + >::Witness: serde::Serialize + serde::de::DeserializeOwned + Eq, + >::Witness: serde::Serialize + serde::de::DeserializeOwned + Eq, +{ + pub fn alloc_ignoring_outputs>( + cs: &mut CS, + witness: ClosedFormInputWitness, + ) -> Self + where + T: CSPlaceholder, + OUT: CSPlaceholder, + { + let start_flag = Boolean::allocate(cs, witness.start_flag); + let observable_input = IN::allocate(cs, witness.observable_input.clone()); + let hidden_fsm_input = T::allocate(cs, witness.hidden_fsm_input.clone()); + let boolean_false = Boolean::allocated_constant(cs, false); + + let observable_output = OUT::placeholder(cs); + let hidden_fsm_output = T::placeholder(cs); + + let new = Self { + start_flag, + completion_flag: boolean_false, + observable_input, + observable_output, + hidden_fsm_input, + hidden_fsm_output, + }; + + new + } + + #[track_caller] + pub fn hook_compare_witness>( + &self, + cs: &CS, + expected: & as CSAllocatable>::Witness, + ) where + T: PrettyComparison, + OUT: PrettyComparison, + { + if let Some(circuit_result) = (self.witness_hook(&*cs))() { + let comparison_lines = >::find_diffs( + &circuit_result.hidden_fsm_output, + &expected.hidden_fsm_output, + ); + if comparison_lines.is_empty() == false { + panic!( + "Difference in FSM. Left is circuit, right is expected:\n{}", + comparison_lines.join("\n") + ); + } + let comparison_lines = >::find_diffs( + &circuit_result.observable_output, + &expected.observable_output, + ); + if comparison_lines.is_empty() == false { + panic!( + "Difference in observable output. Left is circuit, right is expected:\n{}", + comparison_lines.join("\n") + ); + } + assert_eq!(&circuit_result, expected); + } + } +} + +pub const CLOSED_FORM_COMMITTMENT_LENGTH: usize = 4; + +impl< + F: SmallField, + T: Clone + + std::fmt::Debug + + CSAllocatable + + CircuitVarLengthEncodable + + WitnessHookable, + IN: Clone + + std::fmt::Debug + + CSAllocatable + + CircuitVarLengthEncodable + + WitnessHookable, + OUT: Clone + + std::fmt::Debug + + CSAllocatable + + CircuitVarLengthEncodable + + WitnessHookable, + > std::default::Default for ClosedFormInputWitness +where + >::Witness: serde::Serialize + serde::de::DeserializeOwned + Eq, + >::Witness: serde::Serialize + serde::de::DeserializeOwned + Eq, + >::Witness: serde::Serialize + serde::de::DeserializeOwned + Eq, +{ + fn default() -> Self { + ClosedFormInput::::placeholder_witness() + } +} + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Debug)] +pub struct ClosedFormInputCompactForm { + pub start_flag: Boolean, + pub completion_flag: Boolean, + pub observable_input_committment: [Num; CLOSED_FORM_COMMITTMENT_LENGTH], + pub observable_output_committment: [Num; CLOSED_FORM_COMMITTMENT_LENGTH], + pub hidden_fsm_input_committment: [Num; CLOSED_FORM_COMMITTMENT_LENGTH], + pub hidden_fsm_output_committment: [Num; CLOSED_FORM_COMMITTMENT_LENGTH], +} + +impl ClosedFormInputCompactForm { + pub fn from_full_form< + CS: ConstraintSystem, + T: Clone + + std::fmt::Debug + + CSAllocatable + + CircuitVarLengthEncodable + + WitnessHookable, + IN: Clone + + std::fmt::Debug + + CSAllocatable + + CircuitVarLengthEncodable + + WitnessHookable, + OUT: Clone + + std::fmt::Debug + + CSAllocatable + + CircuitVarLengthEncodable + + WitnessHookable, + R: CircuitRoundFunction, + >( + cs: &mut CS, + full_form: &ClosedFormInput, + round_function: &R, + ) -> Self + where + >::Witness: serde::Serialize + serde::de::DeserializeOwned + Eq, + >::Witness: serde::Serialize + serde::de::DeserializeOwned + Eq, + >::Witness: serde::Serialize + serde::de::DeserializeOwned + Eq, + { + let observable_input_committment = + commit_variable_length_encodable_item(cs, &full_form.observable_input, round_function); + let observable_output_committment = + commit_variable_length_encodable_item(cs, &full_form.observable_output, round_function); + + let hidden_fsm_input_committment = + commit_variable_length_encodable_item(cs, &full_form.hidden_fsm_input, round_function); + let hidden_fsm_output_committment = + commit_variable_length_encodable_item(cs, &full_form.hidden_fsm_output, round_function); + + // mask FSM part. Observable part is NEVER masked + + let zero_num = Num::zero(cs); + let empty_committment = [zero_num; CLOSED_FORM_COMMITTMENT_LENGTH]; + + let hidden_fsm_input_committment = Num::parallel_select( + cs, + full_form.start_flag, + &empty_committment, + &hidden_fsm_input_committment, + ); + + // mask output. Observable output is zero is not the last indeed + let observable_output_committment = Num::parallel_select( + cs, + full_form.completion_flag, + &observable_output_committment, + &empty_committment, + ); + + // and vice versa for FSM + let hidden_fsm_output_committment = Num::parallel_select( + cs, + full_form.completion_flag, + &empty_committment, + &hidden_fsm_output_committment, + ); + + let new = Self { + start_flag: full_form.start_flag, + completion_flag: full_form.completion_flag, + observable_input_committment, + observable_output_committment, + hidden_fsm_input_committment, + hidden_fsm_output_committment, + }; + + new + } +} + +pub fn commit_variable_length_encodable_item< + F: SmallField, + CS: ConstraintSystem, + T: CircuitVarLengthEncodable, + const AW: usize, + const SW: usize, + const CW: usize, + const N: usize, + R: CircuitRoundFunction, +>( + cs: &mut CS, + item: &T, + _round_function: &R, +) -> [Num; N] { + let expected_length = item.encoding_length(); + + let mut buffer = Vec::with_capacity(expected_length); + item.encode_to_buffer(cs, &mut buffer); + + assert_eq!(buffer.len(), expected_length); + + commit_encoding::(cs, &buffer, _round_function) +} + +pub fn commit_encoding< + F: SmallField, + CS: ConstraintSystem, + const AW: usize, + const SW: usize, + const CW: usize, + const N: usize, + R: CircuitRoundFunction, +>( + cs: &mut CS, + input: &[Variable], + _round_function: &R, +) -> [Num; N] { + // we use length specialization here + let expected_length = input.len(); + + let mut state = R::create_empty_state(cs); + let length = UInt32::allocated_constant(cs, expected_length as u32); + R::apply_length_specialization(cs, &mut state, length.get_variable()); + + // pad with zeroes + + let mut buffer_length = expected_length / AW; + if expected_length % AW != 0 { + buffer_length += 1; + } + + buffer_length *= AW; + + let mut buffer = Vec::with_capacity(buffer_length); + buffer.extend_from_slice(input); + + let zero_var = cs.allocate_constant(F::ZERO); + buffer.resize(buffer_length, zero_var); + + for chunk in buffer.array_chunks::() { + let capacity_els = R::split_capacity_elements(&state); + + state = R::absorb_with_replacement(cs, *chunk, capacity_els); + state = R::compute_round_function(cs, state); + } + + let output = R::state_into_commitment::(&state); + + output.map(|el| Num::from_variable(el)) +} diff --git a/crates/zkevm_circuits/src/keccak256_round_function/input.rs b/crates/zkevm_circuits/src/keccak256_round_function/input.rs new file mode 100644 index 0000000..d521b41 --- /dev/null +++ b/crates/zkevm_circuits/src/keccak256_round_function/input.rs @@ -0,0 +1,95 @@ +use std::collections::VecDeque; + +use super::*; + +use crate::base_structures::precompile_input_outputs::*; +use crate::base_structures::vm_state::*; +use boojum::cs::Variable; +use boojum::gadgets::queue::*; +use boojum::gadgets::traits::allocatable::CSAllocatable; +use boojum::gadgets::traits::allocatable::CSPlaceholder; +use boojum::gadgets::traits::encodable::CircuitVarLengthEncodable; + +use boojum::cs::traits::cs::ConstraintSystem; +use boojum::field::SmallField; +use boojum::gadgets::boolean::Boolean; +use boojum::gadgets::keccak256::{BYTES_PER_WORD, LANE_WIDTH}; +use boojum::gadgets::traits::auxiliary::PrettyComparison; +use boojum::gadgets::traits::selectable::Selectable; +use boojum::gadgets::traits::witnessable::WitnessHookable; +use boojum::serde_utils::BigArraySerde; + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +#[DerivePrettyComparison("true")] +pub struct Keccak256RoundFunctionFSM { + pub read_precompile_call: Boolean, + pub read_unaligned_words_for_round: Boolean, + pub completed: Boolean, + pub keccak_internal_state: [[[UInt8; BYTES_PER_WORD]; LANE_WIDTH]; LANE_WIDTH], + pub timestamp_to_use_for_read: UInt32, + pub timestamp_to_use_for_write: UInt32, + pub precompile_call_params: Keccak256PrecompileCallParams, + pub u8_words_buffer: [UInt8; BYTES_BUFFER_SIZE], + pub u64_words_buffer_markers: [Boolean; BUFFER_SIZE_IN_U64_WORDS], +} + +impl CSPlaceholder for Keccak256RoundFunctionFSM { + fn placeholder>(cs: &mut CS) -> Self { + let boolean_false = Boolean::allocated_constant(cs, false); + let zero_u8 = UInt8::zero(cs); + let zero_u32 = UInt32::zero(cs); + Self { + read_precompile_call: boolean_false, + read_unaligned_words_for_round: boolean_false, + completed: boolean_false, + keccak_internal_state: [[[zero_u8; BYTES_PER_WORD]; LANE_WIDTH]; LANE_WIDTH], + timestamp_to_use_for_read: zero_u32, + timestamp_to_use_for_write: zero_u32, + precompile_call_params: Keccak256PrecompileCallParams::::placeholder(cs), + u8_words_buffer: [zero_u8; BYTES_BUFFER_SIZE], + u64_words_buffer_markers: [boolean_false; BUFFER_SIZE_IN_U64_WORDS], + } + } +} + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +#[DerivePrettyComparison("true")] +pub struct Keccak256RoundFunctionFSMInputOutput { + pub internal_fsm: Keccak256RoundFunctionFSM, + pub log_queue_state: QueueState, + pub memory_queue_state: QueueState, +} + +impl CSPlaceholder for Keccak256RoundFunctionFSMInputOutput { + fn placeholder>(cs: &mut CS) -> Self { + Self { + internal_fsm: Keccak256RoundFunctionFSM::placeholder(cs), + log_queue_state: QueueState::::placeholder(cs), + memory_queue_state: QueueState::::placeholder(cs), + } + } +} + +pub type Keccak256RoundFunctionCircuitInputOutput = ClosedFormInput< + F, + Keccak256RoundFunctionFSMInputOutput, + PrecompileFunctionInputData, + PrecompileFunctionOutputData, +>; +pub type Keccak256RoundFunctionCircuitInputOutputWitness = ClosedFormInputWitness< + F, + Keccak256RoundFunctionFSMInputOutput, + PrecompileFunctionInputData, + PrecompileFunctionOutputData, +>; + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Debug, Default)] +#[serde(bound = "")] +pub struct Keccak256RoundFunctionCircuitInstanceWitness { + pub closed_form_input: Keccak256RoundFunctionCircuitInputOutputWitness, + pub requests_queue_witness: CircuitQueueRawWitness, 4, LOG_QUERY_PACKED_WIDTH>, + pub memory_reads_witness: VecDeque, +} diff --git a/crates/zkevm_circuits/src/keccak256_round_function/mod.rs b/crates/zkevm_circuits/src/keccak256_round_function/mod.rs new file mode 100644 index 0000000..b726488 --- /dev/null +++ b/crates/zkevm_circuits/src/keccak256_round_function/mod.rs @@ -0,0 +1,573 @@ +use super::*; + +use boojum::field::SmallField; + +use boojum::cs::traits::cs::ConstraintSystem; +use boojum::gadgets::boolean::Boolean; +use boojum::gadgets::traits::selectable::Selectable; +use boojum::gadgets::traits::witnessable::WitnessHookable; +use boojum::gadgets::u16::UInt16; +use boojum::gadgets::u256::UInt256; +use boojum::gadgets::u32::UInt32; +use cs_derive::*; + +use crate::ethereum_types::U256; +use crate::fsm_input_output::circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH; +use boojum::gadgets::num::Num; +use zkevm_opcode_defs::system_params::PRECOMPILE_AUX_BYTE; + +use crate::base_structures::log_query::*; +use crate::base_structures::memory_query::*; +use crate::base_structures::precompile_input_outputs::PrecompileFunctionOutputData; +use crate::demux_log_queue::StorageLogQueue; +use crate::fsm_input_output::*; +use crate::storage_application::ConditionalWitnessAllocator; +use boojum::algebraic_props::round_function::AlgebraicRoundFunction; +use boojum::cs::Variable; +use boojum::gadgets::keccak256::{self}; +use boojum::gadgets::queue::CircuitQueueWitness; +use boojum::gadgets::queue::QueueState; +use boojum::gadgets::traits::allocatable::CSAllocatable; +use boojum::gadgets::traits::allocatable::{CSAllocatableExt, CSPlaceholder}; +use boojum::gadgets::traits::encodable::CircuitVarLengthEncodable; +use boojum::gadgets::traits::round_function::CircuitRoundFunction; +use boojum::gadgets::u160::UInt160; +use boojum::gadgets::u8::UInt8; +use std::sync::{Arc, RwLock}; + +pub mod input; +use self::input::*; + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +// #[DerivePrettyComparison("true")] +pub struct Keccak256PrecompileCallParams { + pub input_page: UInt32, + pub input_offset: UInt32, + pub output_page: UInt32, + pub output_offset: UInt32, + pub num_rounds: UInt32, +} + +impl CSPlaceholder for Keccak256PrecompileCallParams { + fn placeholder>(cs: &mut CS) -> Self { + let zero_u32 = UInt32::zero(cs); + Self { + input_page: zero_u32, + input_offset: zero_u32, + output_page: zero_u32, + output_offset: zero_u32, + num_rounds: zero_u32, + } + } +} + +impl Keccak256PrecompileCallParams { + pub fn from_encoding>(_cs: &mut CS, encoding: UInt256) -> Self { + let input_offset = encoding.inner[0]; + let output_offset = encoding.inner[2]; + let input_page = encoding.inner[4]; + let output_page = encoding.inner[5]; + + let num_rounds = encoding.inner[6]; + + let new = Self { + input_page, + input_offset, + output_page, + output_offset, + num_rounds, + }; + + new + } +} + +pub const KECCAK256_RATE_IN_U64_WORDS: usize = 17; +pub const MEMORY_EQURIES_PER_CYCLE: usize = 5; // we need to read as much as possible to use a round function every cycle +pub const NUM_U64_WORDS_PER_CYCLE: usize = 4 * MEMORY_EQURIES_PER_CYCLE; +pub const NEW_BYTES_PER_CYCLE: usize = 8 * NUM_U64_WORDS_PER_CYCLE; +// we absorb 136 elements per cycle, and add 160 elements per cycle, so we need to skip memory reads +// sometimes and do absorbs instead +pub const BUFFER_SIZE_IN_U64_WORDS: usize = + MEMORY_EQURIES_PER_CYCLE * 4 + KECCAK256_RATE_IN_U64_WORDS - 1; +pub const BYTES_BUFFER_SIZE: usize = BUFFER_SIZE_IN_U64_WORDS * 8; + +pub fn keccak256_precompile_inner< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, +>( + cs: &mut CS, + memory_queue: &mut MemoryQueue, + precompile_calls_queue: &mut StorageLogQueue, + memory_read_witness: ConditionalWitnessAllocator>, + mut state: Keccak256RoundFunctionFSM, + _round_function: &R, + limit: usize, +) -> Keccak256RoundFunctionFSM +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, +{ + assert!(limit <= u32::MAX as usize); + + let precompile_address = UInt160::allocated_constant( + cs, + *zkevm_opcode_defs::system_params::KECCAK256_ROUND_FUNCTION_PRECOMPILE_FORMAL_ADDRESS, + ); + let aux_byte_for_precompile = UInt8::allocated_constant(cs, PRECOMPILE_AUX_BYTE); + + let boolean_false = Boolean::allocated_constant(cs, false); + let boolean_true = Boolean::allocated_constant(cs, true); + let zero_u8 = UInt8::zero(cs); + let buffer_len_bound = UInt16::allocated_constant( + cs, + (BUFFER_SIZE_IN_U64_WORDS - NUM_U64_WORDS_PER_CYCLE + 1) as u16, + ); + + // we can have a degenerate case when queue is empty, but it's a first circuit in the queue, + // so we taken default FSM state that has state.read_precompile_call = true; + let input_queue_is_empty = precompile_calls_queue.is_empty(cs); + // we can only skip the full circuit if we are not in any form of progress + let can_finish_immediatelly = + Boolean::multi_and(cs, &[state.read_precompile_call, input_queue_is_empty]); + + if crate::config::CIRCUIT_VERSOBE { + dbg!(can_finish_immediatelly.witness_hook(cs)()); + dbg!(state.witness_hook(cs)()); + } + + state.read_precompile_call = state + .read_precompile_call + .mask_negated(cs, can_finish_immediatelly); + state.read_unaligned_words_for_round = state + .read_unaligned_words_for_round + .mask_negated(cs, can_finish_immediatelly); + state.completed = Boolean::multi_or(cs, &[state.completed, can_finish_immediatelly]); + + // main work cycle + for _cycle in 0..limit { + // if we are in a proper state then get the ABI from the queue + let (precompile_call, _) = precompile_calls_queue.pop_front(cs, state.read_precompile_call); + + Num::conditionally_enforce_equal( + cs, + state.read_precompile_call, + &Num::from_variable(precompile_call.aux_byte.get_variable()), + &Num::from_variable(aux_byte_for_precompile.get_variable()), + ); + for (a, b) in precompile_call + .address + .inner + .iter() + .zip(precompile_address.inner.iter()) + { + Num::conditionally_enforce_equal( + cs, + state.read_precompile_call, + &Num::from_variable(a.get_variable()), + &Num::from_variable(b.get_variable()), + ); + } + + // now compute some parameters that describe the call itself + + let params_encoding = precompile_call.key; + let call_params = Keccak256PrecompileCallParams::from_encoding(cs, params_encoding); + + state.precompile_call_params = Keccak256PrecompileCallParams::conditionally_select( + cs, + state.read_precompile_call, + &call_params, + &state.precompile_call_params, + ); + // also set timestamps + state.timestamp_to_use_for_read = UInt32::conditionally_select( + cs, + state.read_precompile_call, + &precompile_call.timestamp, + &state.timestamp_to_use_for_read, + ); + + // timestamps have large space, so this can be expected + let timestamp_to_use_for_write = + unsafe { state.timestamp_to_use_for_read.increment_unchecked(cs) }; + state.timestamp_to_use_for_write = UInt32::conditionally_select( + cs, + state.read_precompile_call, + ×tamp_to_use_for_write, + &state.timestamp_to_use_for_write, + ); + + // and do some work! keccak256 is expensive + let reset_buffer = Boolean::multi_or(cs, &[state.read_precompile_call, state.completed]); + state.read_unaligned_words_for_round = Boolean::multi_or( + cs, + &[ + state.read_precompile_call, + state.read_unaligned_words_for_round, + ], + ); + state.read_precompile_call = boolean_false; + + // --------------------------------- + // Now perform few memory queries to read content + + for el in state.u64_words_buffer_markers.iter_mut() { + *el = Boolean::conditionally_select(cs, reset_buffer, &boolean_false, el); + } + + // even though it's not important, we cleanup the buffer too + for el in state.u8_words_buffer.iter_mut() { + *el = UInt8::conditionally_select(cs, reset_buffer, &zero_u8, el); + } + + let initial_buffer_len = { + let lc: Vec<_> = state + .u64_words_buffer_markers + .iter() + .map(|el| (el.get_variable(), F::ONE)) + .collect(); + let lc = Num::linear_combination(cs, &lc); + + unsafe { UInt16::from_variable_unchecked(lc.get_variable()) } + }; + + // we can fill the buffer as soon as it's length <= MAX - NEW_WORDS_PER_CYCLE + let (_, of) = initial_buffer_len.overflowing_sub(cs, &buffer_len_bound); + let can_fill = of; + let can_not_fill = can_fill.negated(cs); + let zero_rounds_left = state.precompile_call_params.num_rounds.is_zero(cs); + // if we can not fill then we should (sanity check) be in a state of reading new words + // and have >0 rounds left + + state + .read_unaligned_words_for_round + .conditionally_enforce_true(cs, can_not_fill); + zero_rounds_left.conditionally_enforce_false(cs, can_not_fill); + let non_zero_rounds_left = zero_rounds_left.negated(cs); + + let should_read = Boolean::multi_and( + cs, + &[ + non_zero_rounds_left, + state.read_unaligned_words_for_round, + can_fill, + ], + ); + + let mut new_bytes_to_read = [zero_u8; NEW_BYTES_PER_CYCLE]; + let mut bias_variable = should_read.get_variable(); + for dst in new_bytes_to_read.array_chunks_mut::<32>() { + let read_query_value = + memory_read_witness.conditionally_allocate_biased(cs, should_read, bias_variable); + bias_variable = read_query_value.inner[0].get_variable(); + + let read_query = MemoryQuery { + timestamp: state.timestamp_to_use_for_read, + memory_page: state.precompile_call_params.input_page, + index: state.precompile_call_params.input_offset, + rw_flag: boolean_false, + is_ptr: boolean_false, + value: read_query_value, + }; + + let may_be_new_offset = unsafe { + state + .precompile_call_params + .input_offset + .increment_unchecked(cs) + }; + state.precompile_call_params.input_offset = UInt32::conditionally_select( + cs, + should_read, + &may_be_new_offset, + &state.precompile_call_params.input_offset, + ); + + // perform read + memory_queue.push(cs, read_query, should_read); + + // we need to change endianess. Memory is BE, and each of 4 byte chunks should be interpreted as BE u32 for sha256 + let be_bytes = read_query_value.to_be_bytes(cs); + *dst = be_bytes; + } + + // our buffer len fits at least to push new elements and get enough for round function + // this is quadratic complexity, but we it's easier to handle and cheap compared to round function + let should_push = should_read; + + for src in new_bytes_to_read.array_chunks::<8>() { + let mut should_push = should_push; + for (is_busy, dst) in state + .u64_words_buffer_markers + .iter_mut() + .zip(state.u8_words_buffer.array_chunks_mut::<8>()) + { + let is_free = is_busy.negated(cs); + let update = Boolean::multi_and(cs, &[is_free, should_push]); + let should_not_update = update.negated(cs); + *dst = UInt8::parallel_select(cs, update, src, dst); + *is_busy = Boolean::multi_or(cs, &[update, *is_busy]); + should_push = Boolean::multi_and(cs, &[should_push, should_not_update]); + } + + Boolean::enforce_equal(cs, &should_push, &boolean_false); + } + + let may_be_new_num_rounds = unsafe { + state + .precompile_call_params + .num_rounds + .decrement_unchecked(cs) + }; + state.precompile_call_params.num_rounds = UInt32::conditionally_select( + cs, + state.read_unaligned_words_for_round, + &may_be_new_num_rounds, + &state.precompile_call_params.num_rounds, + ); + + // absorb + + // compute shifted buffer that removes first RATE elements and padds with something + + // take some work + let mut input = [zero_u8; keccak256::KECCAK_RATE_BYTES]; + input.copy_from_slice(&state.u8_words_buffer[..keccak256::KECCAK_RATE_BYTES]); + + // keep the rest + let mut tmp_buffer = [zero_u8; BYTES_BUFFER_SIZE]; + tmp_buffer[..(BYTES_BUFFER_SIZE - keccak256::KECCAK_RATE_BYTES)] + .copy_from_slice(&state.u8_words_buffer[keccak256::KECCAK_RATE_BYTES..]); + + // also reset markers + let mut tmp_buffer_markers = [boolean_false; BUFFER_SIZE_IN_U64_WORDS]; + tmp_buffer_markers[..(BUFFER_SIZE_IN_U64_WORDS - KECCAK256_RATE_IN_U64_WORDS)] + .copy_from_slice(&state.u64_words_buffer_markers[KECCAK256_RATE_IN_U64_WORDS..]); + + // update buffers + state.u8_words_buffer = tmp_buffer; + state.u64_words_buffer_markers = tmp_buffer_markers; + + // conditionally reset state. Keccak256 empty state is just all 0s + + for dst in state.keccak_internal_state.iter_mut() { + for dst in dst.iter_mut() { + for dst in dst.iter_mut() { + *dst = dst.mask_negated(cs, reset_buffer); + } + } + } + + // manually absorb and run round function + let squeezed = + keccak256_absorb_and_run_permutation(cs, &mut state.keccak_internal_state, &input); + + let no_rounds_left = state.precompile_call_params.num_rounds.is_zero(cs); + let write_result = + Boolean::multi_and(cs, &[state.read_unaligned_words_for_round, no_rounds_left]); + + let result = UInt256::from_be_bytes(cs, squeezed); + + let write_query = MemoryQuery { + timestamp: state.timestamp_to_use_for_write, + memory_page: state.precompile_call_params.output_page, + index: state.precompile_call_params.output_offset, + rw_flag: boolean_true, + is_ptr: boolean_false, + value: result, + }; + + // perform write + memory_queue.push(cs, write_query, write_result); + + // --------------------------------- + + // update call props + let input_is_empty = precompile_calls_queue.is_empty(cs); + let input_is_not_empty = input_is_empty.negated(cs); + let nothing_left = Boolean::multi_and(cs, &[write_result, input_is_empty]); + let process_next = Boolean::multi_and(cs, &[write_result, input_is_not_empty]); + + state.read_precompile_call = process_next; + state.completed = Boolean::multi_or(cs, &[nothing_left, state.completed]); + let t = Boolean::multi_or(cs, &[state.read_precompile_call, state.completed]); + state.read_unaligned_words_for_round = t.negated(cs); + } + + precompile_calls_queue.enforce_consistency(cs); + + state +} + +#[track_caller] +pub fn keccak256_round_function_entry_point< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, +>( + cs: &mut CS, + witness: Keccak256RoundFunctionCircuitInstanceWitness, + round_function: &R, + limit: usize, +) -> [Num; INPUT_OUTPUT_COMMITMENT_LENGTH] +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, +{ + let Keccak256RoundFunctionCircuitInstanceWitness { + closed_form_input, + requests_queue_witness, + memory_reads_witness, + } = witness; + + let mut structured_input = Keccak256RoundFunctionCircuitInputOutput::alloc_ignoring_outputs( + cs, + closed_form_input.clone(), + ); + + let start_flag = structured_input.start_flag; + + let requests_queue_state_from_input = structured_input.observable_input.initial_log_queue_state; + + // it must be trivial + requests_queue_state_from_input.enforce_trivial_head(cs); + + let requests_queue_state_from_fsm = structured_input.hidden_fsm_input.log_queue_state; + + let requests_queue_state = QueueState::conditionally_select( + cs, + start_flag, + &requests_queue_state_from_input, + &requests_queue_state_from_fsm, + ); + + let memory_queue_state_from_input = + structured_input.observable_input.initial_memory_queue_state; + + // it must be trivial + memory_queue_state_from_input.enforce_trivial_head(cs); + + let memory_queue_state_from_fsm = structured_input.hidden_fsm_input.memory_queue_state; + + let memory_queue_state = QueueState::conditionally_select( + cs, + start_flag, + &memory_queue_state_from_input, + &memory_queue_state_from_fsm, + ); + + let mut requests_queue = StorageLogQueue::::from_state(cs, requests_queue_state); + let queue_witness = CircuitQueueWitness::from_inner_witness(requests_queue_witness); + requests_queue.witness = Arc::new(queue_witness); + + let mut memory_queue = MemoryQueue::::from_state(cs, memory_queue_state); + + let read_queries_allocator = ConditionalWitnessAllocator::> { + witness_source: Arc::new(RwLock::new(memory_reads_witness)), + }; + + let mut starting_fsm_state = Keccak256RoundFunctionFSM::placeholder(cs); + starting_fsm_state.read_precompile_call = Boolean::allocated_constant(cs, true); + + let initial_state = Keccak256RoundFunctionFSM::conditionally_select( + cs, + start_flag, + &starting_fsm_state, + &structured_input.hidden_fsm_input.internal_fsm, + ); + + let final_state = keccak256_precompile_inner::( + cs, + &mut memory_queue, + &mut requests_queue, + read_queries_allocator, + initial_state, + round_function, + limit, + ); + + let final_memory_state = memory_queue.into_state(); + let final_requets_state = requests_queue.into_state(); + + // form the final state + let done = final_state.completed; + structured_input.completion_flag = done; + structured_input.observable_output = PrecompileFunctionOutputData::placeholder(cs); + + structured_input.observable_output.final_memory_state = QueueState::conditionally_select( + cs, + structured_input.completion_flag, + &final_memory_state, + &structured_input.observable_output.final_memory_state, + ); + + structured_input.hidden_fsm_output.internal_fsm = final_state; + structured_input.hidden_fsm_output.log_queue_state = final_requets_state; + structured_input.hidden_fsm_output.memory_queue_state = final_memory_state; + + // self-check + structured_input.hook_compare_witness(cs, &closed_form_input); + + use boojum::cs::gates::PublicInputGate; + + let compact_form = + ClosedFormInputCompactForm::from_full_form(cs, &structured_input, round_function); + let input_commitment = commit_variable_length_encodable_item(cs, &compact_form, round_function); + for el in input_commitment.iter() { + let gate = PublicInputGate::new(el.get_variable()); + gate.add_to_cs(cs); + } + + input_commitment +} + +pub(crate) fn keccak256_absorb_and_run_permutation>( + cs: &mut CS, + state: &mut [[[UInt8; keccak256::BYTES_PER_WORD]; keccak256::LANE_WIDTH]; + keccak256::LANE_WIDTH], + block: &[UInt8; keccak256::KECCAK_RATE_BYTES], +) -> [UInt8; keccak256::KECCAK256_DIGEST_SIZE] { + let mut state_as_variables = state.map(|el| el.map(|el| el.map(|el| el.get_variable()))); + for i in 0..keccak256::LANE_WIDTH { + for j in 0..keccak256::LANE_WIDTH { + if i + keccak256::LANE_WIDTH * j + < (keccak256::KECCAK_RATE_BYTES / keccak256::BYTES_PER_WORD) + { + let tmp = block + .array_chunks::<{ keccak256::BYTES_PER_WORD }>() + .skip(i + keccak256::LANE_WIDTH * j) + .next() + .unwrap(); + use boojum::gadgets::blake2s::mixing_function::xor_many; + let tmp = tmp.map(|el| el.get_variable()); + state_as_variables[i][j] = xor_many(cs, &state_as_variables[i][j], &tmp); + } + } + } + use boojum::gadgets::keccak256::round_function::keccak_256_round_function; + keccak_256_round_function(cs, &mut state_as_variables); + + let new_state = unsafe { + state_as_variables.map(|el| el.map(|el| el.map(|el| UInt8::from_variable_unchecked(el)))) + }; + + *state = new_state; + + // copy back + let mut result = + [std::mem::MaybeUninit::>::uninit(); keccak256::KECCAK256_DIGEST_SIZE]; + for (i, dst) in result.array_chunks_mut::<8>().enumerate() { + for (dst, src) in dst.iter_mut().zip(state[i][0].iter()) { + dst.write(*src); + } + } + + unsafe { result.map(|el| el.assume_init()) } +} diff --git a/crates/zkevm_circuits/src/lib.rs b/crates/zkevm_circuits/src/lib.rs new file mode 100644 index 0000000..ddc2dcf --- /dev/null +++ b/crates/zkevm_circuits/src/lib.rs @@ -0,0 +1,41 @@ +#![allow(clippy::drop_ref)] +#![allow(dead_code)] +#![allow(dropping_references)] +#![allow(unused_imports)] +#![feature(generic_const_exprs)] +#![feature(array_chunks)] +#![feature(more_qualified_paths)] + +use derivative::*; + +pub use boojum; +pub use boojum::ethereum_types; + +pub mod config; + +pub mod base_structures; +pub mod code_unpacker_sha256; +pub mod demux_log_queue; +pub mod ecrecover; +pub mod fsm_input_output; +pub mod keccak256_round_function; +pub mod linear_hasher; +pub mod log_sorter; +pub mod main_vm; +pub mod ram_permutation; +pub mod recursion; +pub mod scheduler; +pub mod sha256_round_function; +pub mod sort_decommittment_requests; +pub mod storage_application; +pub mod storage_validity_by_grand_product; +pub mod tables; +pub mod utils; + +use boojum::pairing::ff; + +pub const DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS: usize = 2; + +pub const fn bit_width_to_bitmask(width: usize) -> u64 { + (1u64 << width) - 1 +} diff --git a/crates/zkevm_circuits/src/linear_hasher/input.rs b/crates/zkevm_circuits/src/linear_hasher/input.rs new file mode 100644 index 0000000..9ed2817 --- /dev/null +++ b/crates/zkevm_circuits/src/linear_hasher/input.rs @@ -0,0 +1,80 @@ +use crate::base_structures::{ + log_query::{LogQuery, LOG_QUERY_PACKED_WIDTH}, + vm_state::*, +}; +use boojum::cs::{traits::cs::ConstraintSystem, Variable}; +use boojum::field::SmallField; +use boojum::gadgets::keccak256; +use boojum::gadgets::traits::auxiliary::PrettyComparison; +use boojum::gadgets::u32::UInt32; +use boojum::gadgets::u8::UInt8; +use boojum::gadgets::{ + boolean::Boolean, + queue::*, + traits::{ + allocatable::*, encodable::CircuitVarLengthEncodable, selectable::Selectable, + witnessable::WitnessHookable, + }, +}; +use boojum::serde_utils::BigArraySerde; +use cs_derive::*; +use derivative::*; +use std::collections::VecDeque; + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +#[DerivePrettyComparison("true")] +pub struct LinearHasherInputData { + pub queue_state: QueueState, +} + +impl CSPlaceholder for LinearHasherInputData { + fn placeholder>(cs: &mut CS) -> Self { + Self { + queue_state: QueueState::::placeholder(cs), + } + } +} + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +#[DerivePrettyComparison("true")] +pub struct LinearHasherOutputData { + pub keccak256_hash: [UInt8; 32], +} + +impl CSPlaceholder for LinearHasherOutputData { + fn placeholder>(cs: &mut CS) -> Self { + Self { + keccak256_hash: [UInt8::::placeholder(cs); 32], + } + } +} + +pub type LinearHasherInputOutput = crate::fsm_input_output::ClosedFormInput< + F, + (), + LinearHasherInputData, + LinearHasherOutputData, +>; + +pub type LinearHasherInputOutputWitness = crate::fsm_input_output::ClosedFormInputWitness< + F, + (), + LinearHasherInputData, + LinearHasherOutputData, +>; + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Debug, Default)] +#[serde(bound = "")] +pub struct LinearHasherCircuitInstanceWitness { + pub closed_form_input: LinearHasherInputOutputWitness, + // #[serde(bound( + // serialize = "CircuitQueueRawWitness, 4, LOG_QUERY_PACKED_WIDTH>: serde::Serialize" + // ))] + // #[serde(bound( + // deserialize = "CircuitQueueRawWitness, 4, LOG_QUERY_PACKED_WIDTH>: serde::de::DeserializeOwned" + // ))] + pub queue_witness: CircuitQueueRawWitness, 4, LOG_QUERY_PACKED_WIDTH>, +} diff --git a/crates/zkevm_circuits/src/linear_hasher/mod.rs b/crates/zkevm_circuits/src/linear_hasher/mod.rs new file mode 100644 index 0000000..2409b3c --- /dev/null +++ b/crates/zkevm_circuits/src/linear_hasher/mod.rs @@ -0,0 +1,214 @@ +use std::collections::VecDeque; +use std::mem::MaybeUninit; + +use crate::base_structures::log_query::LogQuery; +use crate::base_structures::state_diff_record::StateDiffRecord; +use crate::demux_log_queue::StorageLogQueue; +use crate::ethereum_types::U256; +use crate::fsm_input_output::circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH; +use crate::keccak256_round_function::keccak256_absorb_and_run_permutation; +use boojum::algebraic_props::round_function::AlgebraicRoundFunction; +use boojum::config::*; +use boojum::cs::traits::cs::{ConstraintSystem, DstBuffer}; +use boojum::cs::{Place, Variable}; +use boojum::field::SmallField; +use boojum::gadgets::boolean::Boolean; +use boojum::gadgets::keccak256; +use boojum::gadgets::num::Num; +use boojum::gadgets::queue::CircuitQueueWitness; +use boojum::gadgets::queue::QueueState; +use boojum::gadgets::traits::allocatable::{CSAllocatable, CSAllocatableExt, CSPlaceholder}; +use boojum::gadgets::traits::castable::WitnessCastable; +use boojum::gadgets::traits::round_function::CircuitRoundFunction; +use boojum::gadgets::traits::selectable::Selectable; +use boojum::gadgets::u256::UInt256; +use boojum::gadgets::u32::UInt32; +use boojum::gadgets::u8::UInt8; +use std::sync::{Arc, RwLock}; +use zkevm_opcode_defs::system_params::STORAGE_AUX_BYTE; + +use super::*; + +pub mod input; +use self::input::*; + +pub fn linear_hasher_entry_point< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, +>( + cs: &mut CS, + witness: LinearHasherCircuitInstanceWitness, + round_function: &R, + params: usize, +) -> [Num; INPUT_OUTPUT_COMMITMENT_LENGTH] +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, +{ + let limit = params; + + assert!(limit <= u32::MAX as usize); + + let LinearHasherCircuitInstanceWitness { + closed_form_input, + queue_witness, + } = witness; + + let mut structured_input = + LinearHasherInputOutput::alloc_ignoring_outputs(cs, closed_form_input.clone()); + let start_flag = structured_input.start_flag; + + let zero_u8: UInt8 = UInt8::zero(cs); + let boolean_true = Boolean::allocated_constant(cs, true); + + // only 1 instance of the circuit here for now + Boolean::enforce_equal(cs, &start_flag, &boolean_true); + + let queue_state_from_input = structured_input.observable_input.queue_state; + + // it must be trivial + queue_state_from_input.enforce_trivial_head(cs); + + let mut queue = StorageLogQueue::::from_state(cs, queue_state_from_input); + let queue_witness = CircuitQueueWitness::from_inner_witness(queue_witness); + queue.witness = Arc::new(queue_witness); + + let keccak_accumulator_state = + [[[zero_u8; keccak256::BYTES_PER_WORD]; keccak256::LANE_WIDTH]; keccak256::LANE_WIDTH]; + + let mut keccak_accumulator_state = + keccak_accumulator_state.map(|el| el.map(|el| el.map(|el| el.get_variable()))); + + use crate::base_structures::log_query::L2_TO_L1_MESSAGE_BYTE_LENGTH; + // we do not serialize length because it's recalculatable in L1 + + let empty_hash = { + use zkevm_opcode_defs::sha3::*; + + let mut result = [0u8; 32]; + let digest = Keccak256::digest(&[]); + result.copy_from_slice(digest.as_slice()); + + result.map(|el| UInt8::allocated_constant(cs, el)) + }; + + let mut buffer = vec![]; + + let mut done = queue.is_empty(cs); + let no_work = done; + + use crate::storage_application::keccak256_conditionally_absorb_and_run_permutation; + use boojum::gadgets::keccak256::KECCAK_RATE_BYTES; + + for _cycle in 0..limit { + let queue_is_empty = queue.is_empty(cs); + let should_pop = queue_is_empty.negated(cs); + + let (storage_log, _) = queue.pop_front(cs, should_pop); + + let now_empty = queue.is_empty(cs); + let is_last_serialization = Boolean::multi_and(cs, &[should_pop, now_empty]); + use crate::base_structures::ByteSerializable; + let as_bytes = storage_log.into_bytes(cs); + + assert!(buffer.len() < 136); + + buffer.extend(as_bytes); + + let continue_to_absorb = done.negated(cs); + + if buffer.len() >= 136 { + let buffer_for_round: [UInt8; KECCAK_RATE_BYTES] = buffer[..136].try_into().unwrap(); + let buffer_for_round = buffer_for_round.map(|el| el.get_variable()); + let carry_on = buffer[136..].to_vec(); + + buffer = carry_on; + + // absorb if we are not done yet + keccak256_conditionally_absorb_and_run_permutation( + cs, + continue_to_absorb, + &mut keccak_accumulator_state, + &buffer_for_round, + ); + } + + assert!(buffer.len() < 136); + + // in case if we do last round + { + let absorb_as_last_round = + Boolean::multi_and(cs, &[continue_to_absorb, is_last_serialization]); + let mut last_round_buffer = [zero_u8; KECCAK_RATE_BYTES]; + let tail_len = buffer.len(); + last_round_buffer[..tail_len].copy_from_slice(&buffer); + + if tail_len == KECCAK_RATE_BYTES - 1 { + // unreachable, but we set it for completeness + last_round_buffer[tail_len] = UInt8::allocated_constant(cs, 0x81); + } else { + last_round_buffer[tail_len] = UInt8::allocated_constant(cs, 0x01); + last_round_buffer[KECCAK_RATE_BYTES - 1] = UInt8::allocated_constant(cs, 0x80); + } + + let last_round_buffer = last_round_buffer.map(|el| el.get_variable()); + + // absorb if it's the last round + keccak256_conditionally_absorb_and_run_permutation( + cs, + absorb_as_last_round, + &mut keccak_accumulator_state, + &last_round_buffer, + ); + } + + done = Boolean::multi_or(cs, &[done, is_last_serialization]); + } + + queue.enforce_consistency(cs); + let completed = queue.is_empty(cs); + + Boolean::enforce_equal(cs, &completed, &boolean_true); + + structured_input.completion_flag = completed.clone(); + + let fsm_output = (); + structured_input.hidden_fsm_output = fsm_output; + + // squeeze + let mut keccak256_hash = [MaybeUninit::>::uninit(); keccak256::KECCAK256_DIGEST_SIZE]; + for (i, dst) in keccak256_hash.array_chunks_mut::<8>().enumerate() { + for (dst, src) in dst.iter_mut().zip(keccak_accumulator_state[i][0].iter()) { + let tmp = unsafe { UInt8::from_variable_unchecked(*src) }; + dst.write(tmp); + } + } + + let keccak256_hash = unsafe { keccak256_hash.map(|el| el.assume_init()) }; + + let keccak256_hash = + <[UInt8; 32]>::conditionally_select(cs, no_work, &empty_hash, &keccak256_hash); + + let mut observable_output = LinearHasherOutputData::placeholder(cs); + observable_output.keccak256_hash = keccak256_hash; + structured_input.observable_output = observable_output; + + // self-check + structured_input.hook_compare_witness(cs, &closed_form_input); + + use crate::fsm_input_output::commit_variable_length_encodable_item; + use crate::fsm_input_output::ClosedFormInputCompactForm; + use boojum::cs::gates::PublicInputGate; + + let compact_form = + ClosedFormInputCompactForm::from_full_form(cs, &structured_input, round_function); + let input_commitment = commit_variable_length_encodable_item(cs, &compact_form, round_function); + for el in input_commitment.iter() { + let gate = PublicInputGate::new(el.get_variable()); + gate.add_to_cs(cs); + } + + input_commitment +} diff --git a/crates/zkevm_circuits/src/log_sorter/input.rs b/crates/zkevm_circuits/src/log_sorter/input.rs new file mode 100644 index 0000000..ee2d1de --- /dev/null +++ b/crates/zkevm_circuits/src/log_sorter/input.rs @@ -0,0 +1,106 @@ +use crate::base_structures::{ + log_query::{LogQuery, LOG_QUERY_PACKED_WIDTH}, + vm_state::*, +}; +use boojum::cs::{traits::cs::ConstraintSystem, Variable}; +use boojum::field::SmallField; +use boojum::gadgets::queue::QueueState; +use boojum::gadgets::traits::auxiliary::PrettyComparison; +use boojum::gadgets::u32::UInt32; +use boojum::gadgets::{ + boolean::Boolean, + num::Num, + queue::*, + traits::{ + allocatable::*, encodable::CircuitVarLengthEncodable, selectable::Selectable, + witnessable::WitnessHookable, + }, +}; +use boojum::serde_utils::BigArraySerde; +use cs_derive::*; +use derivative::*; + +use crate::DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS; + +#[derive(Derivative, CSAllocatable, CSVarLengthEncodable, CSSelectable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +#[DerivePrettyComparison("true")] +pub struct EventsDeduplicatorFSMInputOutput { + pub lhs_accumulator: [Num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + pub rhs_accumulator: [Num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + pub initial_unsorted_queue_state: QueueState, + pub intermediate_sorted_queue_state: QueueState, + pub final_result_queue_state: QueueState, + pub previous_key: UInt32, + pub previous_item: LogQuery, +} + +impl CSPlaceholder for EventsDeduplicatorFSMInputOutput { + fn placeholder>(cs: &mut CS) -> Self { + let zero_num = Num::zero(cs); + let zero_u32 = UInt32::zero(cs); + Self { + lhs_accumulator: [zero_num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + rhs_accumulator: [zero_num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + initial_unsorted_queue_state: QueueState::::placeholder(cs), + intermediate_sorted_queue_state: QueueState::::placeholder(cs), + final_result_queue_state: QueueState::::placeholder(cs), + previous_key: zero_u32, + previous_item: LogQuery::::placeholder(cs), + } + } +} + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +#[DerivePrettyComparison("true")] +pub struct EventsDeduplicatorInputData { + pub initial_log_queue_state: QueueState, + pub intermediate_sorted_queue_state: QueueState, +} + +impl CSPlaceholder for EventsDeduplicatorInputData { + fn placeholder>(cs: &mut CS) -> Self { + Self { + initial_log_queue_state: QueueState::::placeholder(cs), + intermediate_sorted_queue_state: QueueState::::placeholder(cs), + } + } +} + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +#[DerivePrettyComparison("true")] +pub struct EventsDeduplicatorOutputData { + pub final_queue_state: QueueState, +} + +impl CSPlaceholder for EventsDeduplicatorOutputData { + fn placeholder>(cs: &mut CS) -> Self { + Self { + final_queue_state: QueueState::::placeholder(cs), + } + } +} + +pub type EventsDeduplicatorInputOutput = crate::fsm_input_output::ClosedFormInput< + F, + EventsDeduplicatorFSMInputOutput, + EventsDeduplicatorInputData, + EventsDeduplicatorOutputData, +>; +pub type EventsDeduplicatorInputOutputWitness = crate::fsm_input_output::ClosedFormInputWitness< + F, + EventsDeduplicatorFSMInputOutput, + EventsDeduplicatorInputData, + EventsDeduplicatorOutputData, +>; +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Debug, Default)] +#[serde(bound = "")] +pub struct EventsDeduplicatorInstanceWitness { + pub closed_form_input: EventsDeduplicatorInputOutputWitness, + pub initial_queue_witness: CircuitQueueRawWitness, 4, LOG_QUERY_PACKED_WIDTH>, + pub intermediate_sorted_queue_witness: + CircuitQueueRawWitness, 4, LOG_QUERY_PACKED_WIDTH>, +} diff --git a/crates/zkevm_circuits/src/log_sorter/mod.rs b/crates/zkevm_circuits/src/log_sorter/mod.rs new file mode 100644 index 0000000..b29ccc9 --- /dev/null +++ b/crates/zkevm_circuits/src/log_sorter/mod.rs @@ -0,0 +1,814 @@ +pub mod input; + +use super::*; +use crate::base_structures::log_query::{LogQuery, LOG_QUERY_PACKED_WIDTH}; +use crate::base_structures::vm_state::*; +use crate::fsm_input_output::circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH; +use crate::fsm_input_output::{commit_variable_length_encodable_item, ClosedFormInputCompactForm}; +use crate::storage_validity_by_grand_product::unpacked_long_comparison; +use crate::utils::accumulate_grand_products; +use boojum::cs::{gates::*, traits::cs::ConstraintSystem}; +use boojum::field::SmallField; +use boojum::gadgets::traits::round_function::CircuitRoundFunction; +use boojum::gadgets::{ + boolean::Boolean, + num::Num, + queue::*, + traits::{allocatable::CSAllocatableExt, selectable::Selectable}, + u256::UInt256, + u32::UInt32, + u8::UInt8, +}; + +use crate::demux_log_queue::StorageLogQueue; +use boojum::algebraic_props::round_function::AlgebraicRoundFunction; +// This is a sorter of logs that are kind-of "pure", e.g. event emission or L2 -> L1 messages. +// Those logs do not affect a global state and may either be rolled back in full or not. +// We identify equality of logs using "timestamp" field that is a monotonic unique counter +// across the block + +pub const NUM_PERMUTATION_ARG_CHALLENGES: usize = LOG_QUERY_PACKED_WIDTH + 1; + +use crate::log_sorter::input::*; + +pub fn sort_and_deduplicate_events_entry_point< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, +>( + cs: &mut CS, + witness: EventsDeduplicatorInstanceWitness, + round_function: &R, + limit: usize, +) -> [Num; INPUT_OUTPUT_COMMITMENT_LENGTH] +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + //use table + let EventsDeduplicatorInstanceWitness { + closed_form_input, + initial_queue_witness, + intermediate_sorted_queue_witness, + } = witness; + + let mut structured_input = + EventsDeduplicatorInputOutput::alloc_ignoring_outputs(cs, closed_form_input.clone()); + + let unsorted_queue_from_passthrough_state = + structured_input.observable_input.initial_log_queue_state; + + // passthrough must be trivial + unsorted_queue_from_passthrough_state.enforce_trivial_head(cs); + + let unsorted_queue_from_fsm_input_state = structured_input + .hidden_fsm_input + .initial_unsorted_queue_state; + + let state = QueueState::conditionally_select( + cs, + structured_input.start_flag, + &unsorted_queue_from_passthrough_state, + &unsorted_queue_from_fsm_input_state, + ); + + let mut unsorted_queue = StorageLogQueue::::from_state(cs, state); + + use std::sync::Arc; + let initial_queue_witness = CircuitQueueWitness::from_inner_witness(initial_queue_witness); + unsorted_queue.witness = Arc::new(initial_queue_witness); + + let intermediate_sorted_queue_from_passthrough_state = structured_input + .observable_input + .intermediate_sorted_queue_state; + + // passthrough must be trivial + intermediate_sorted_queue_from_passthrough_state.enforce_trivial_head(cs); + + let intermediate_sorted_queue_from_fsm_state = structured_input + .hidden_fsm_input + .intermediate_sorted_queue_state; + + let state = QueueState::conditionally_select( + cs, + structured_input.start_flag, + &intermediate_sorted_queue_from_passthrough_state, + &intermediate_sorted_queue_from_fsm_state, + ); + let mut intermediate_sorted_queue = StorageLogQueue::::from_state(cs, state); + let intermediate_sorted_queue_witness = + CircuitQueueWitness::from_inner_witness(intermediate_sorted_queue_witness); + intermediate_sorted_queue.witness = Arc::new(intermediate_sorted_queue_witness); + + let final_sorted_queue_from_fsm = structured_input.hidden_fsm_input.final_result_queue_state; + let empty_state = QueueState::empty(cs); + + let final_sorted_state = QueueState::conditionally_select( + cs, + structured_input.start_flag, + &empty_state, + &final_sorted_queue_from_fsm, + ); + let mut final_sorted_queue = StorageLogQueue::::from_state(cs, final_sorted_state); + + // get challenges for permutation argument + let challenges = crate::utils::produce_fs_challenges::< + F, + CS, + R, + QUEUE_STATE_WIDTH, + { LOG_QUERY_PACKED_WIDTH + 1 }, + DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS, + >( + cs, + structured_input + .observable_input + .initial_log_queue_state + .tail, + structured_input + .observable_input + .intermediate_sorted_queue_state + .tail, + round_function, + ); + + let one = Num::allocated_constant(cs, F::ONE); + let initial_lhs = Num::parallel_select( + cs, + structured_input.start_flag, + &[one; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + &structured_input.hidden_fsm_input.lhs_accumulator, + ); + + let initial_rhs = Num::parallel_select( + cs, + structured_input.start_flag, + &[one; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + &structured_input.hidden_fsm_input.rhs_accumulator, + ); + + // there is no code at address 0 in our case, so we can formally use it for all the purposes + let zero_u32 = UInt32::zero(cs); + let previous_key = UInt32::conditionally_select( + cs, + structured_input.start_flag, + &zero_u32, + &structured_input.hidden_fsm_input.previous_key, + ); + + // there is no code at address 0 in our case, so we can formally use it for all the purposes + use boojum::gadgets::traits::allocatable::CSPlaceholder; + let empty_storage = LogQuery::placeholder(cs); + let previous_item = LogQuery::conditionally_select( + cs, + structured_input.start_flag, + &empty_storage, + &structured_input.hidden_fsm_input.previous_item, + ); + + let (new_lhs, new_rhs, previous_key, previous_item) = + repack_and_prove_events_rollbacks_inner::<_, _, R>( + cs, + initial_lhs, + initial_rhs, + &mut unsorted_queue, + &mut intermediate_sorted_queue, + &mut final_sorted_queue, + structured_input.start_flag, + challenges, + previous_key, + previous_item, + limit, + ); + + let unsorted_is_empty = unsorted_queue.is_empty(cs); + let sorted_is_empty = intermediate_sorted_queue.is_empty(cs); + + Boolean::enforce_equal(cs, &unsorted_is_empty, &sorted_is_empty); + + let completed = unsorted_queue.length.is_zero(cs); + for (lhs, rhs) in new_lhs.iter().zip(new_rhs.iter()) { + Num::conditionally_enforce_equal(cs, completed, lhs, rhs); + } + // form the final state + structured_input.hidden_fsm_output.previous_key = previous_key; + structured_input.hidden_fsm_output.previous_item = previous_item; + structured_input.hidden_fsm_output.lhs_accumulator = new_lhs; + structured_input.hidden_fsm_output.rhs_accumulator = new_rhs; + + structured_input + .hidden_fsm_output + .initial_unsorted_queue_state = unsorted_queue.into_state(); + structured_input + .hidden_fsm_output + .intermediate_sorted_queue_state = intermediate_sorted_queue.into_state(); + + structured_input.completion_flag = completed; + + let empty_state = QueueState::empty(cs); + let final_queue_for_observable_output = QueueState::conditionally_select( + cs, + completed, + &final_sorted_queue.into_state(), + &empty_state, + ); + + structured_input.observable_output.final_queue_state = final_queue_for_observable_output; + + structured_input.hidden_fsm_output.final_result_queue_state = final_sorted_queue.into_state(); + + // self-check + structured_input.hook_compare_witness(cs, &closed_form_input); + + let compact_form = + ClosedFormInputCompactForm::from_full_form(cs, &structured_input, round_function); + + let input_commitment = commit_variable_length_encodable_item(cs, &compact_form, round_function); + for el in input_commitment.iter() { + let gate = PublicInputGate::new(el.get_variable()); + gate.add_to_cs(cs); + } + + input_commitment +} + +pub fn repack_and_prove_events_rollbacks_inner< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, +>( + cs: &mut CS, + mut lhs: [Num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + mut rhs: [Num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + unsorted_queue: &mut StorageLogQueue, + intermediate_sorted_queue: &mut StorageLogQueue, + result_queue: &mut StorageLogQueue, + is_start: Boolean, + fs_challenges: [[Num; LOG_QUERY_PACKED_WIDTH + 1]; + DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + mut previous_key: UInt32, + mut previous_item: LogQuery, + limit: usize, +) -> ( + [Num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + [Num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + UInt32, + LogQuery, +) +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + assert!(limit <= u32::MAX as usize); + + // we can recreate it here, there are two cases: + // - we are 100% empty, but it's the only circuit in this case + // - otherwise we continue, and then it's not trivial + + // NOTE: scheduler guarantees that only 1 - the first - circuit will have "is_start", + // so to take a shortcut we can only need to test if there is nothing in the queue + let no_work = unsorted_queue.is_empty(cs); + let mut previous_is_trivial = Boolean::multi_or(cs, &[no_work, is_start]); + + let unsorted_queue_lenght = Num::from_variable(unsorted_queue.length.get_variable()); + let intermediate_sorted_queue_lenght = + Num::from_variable(intermediate_sorted_queue.length.get_variable()); + + Num::enforce_equal( + cs, + &unsorted_queue_lenght, + &intermediate_sorted_queue_lenght, + ); + + // reallocate and simultaneously collapse rollbacks + + for _cycle in 0..limit { + let original_is_empty = unsorted_queue.is_empty(cs); + let sorted_is_empty = intermediate_sorted_queue.is_empty(cs); + Boolean::enforce_equal(cs, &original_is_empty, &sorted_is_empty); + + let should_pop = original_is_empty.negated(cs); + let is_trivial = original_is_empty; + + let (unsorted_item, original_encoding) = unsorted_queue.pop_front(cs, should_pop); + let (sorted_item, sorted_encoding) = intermediate_sorted_queue.pop_front(cs, should_pop); + + // we also ensure that original items are "write" unless it's a padding + unsorted_item + .rw_flag + .conditionally_enforce_true(cs, should_pop); + + accumulate_grand_products::< + F, + CS, + LOG_QUERY_PACKED_WIDTH, + { LOG_QUERY_PACKED_WIDTH + 1 }, + DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS, + >( + cs, + &mut lhs, + &mut rhs, + &fs_challenges, + &original_encoding, + &sorted_encoding, + should_pop, + ); + + // now ensure sorting + { + // sanity check - all such logs are "write into the sky" + sorted_item + .rw_flag + .conditionally_enforce_true(cs, should_pop); + + // check if keys are equal and check a value + + // We compare timestamps, and then resolve logic over rollbacks, so the only way when + // keys are equal can be when we do rollback + let sorting_key = sorted_item.timestamp; + + // ensure sorting for uniqueness timestamp and rollback flag + // We know that timestamps are unique accross logs, and are also the same between write and rollback + let (keys_are_equal, new_key_is_smaller) = + unpacked_long_comparison(cs, &[previous_key], &[sorting_key]); + + // keys are always ordered as >= unless is padding + new_key_is_smaller.conditionally_enforce_false(cs, should_pop); + + let same_log = keys_are_equal; + let same_nontrivial_log = Boolean::multi_and(cs, &[should_pop, same_log]); + let may_be_different_log = same_log.negated(cs); + let different_nontrivial_log = + Boolean::multi_and(cs, &[should_pop, may_be_different_log]); + + // if we pop an item and it's not trivial with different log, then it MUST be non-rollback + let this_item_is_not_rollback = sorted_item.rollback.negated(cs); + this_item_is_not_rollback.conditionally_enforce_true(cs, different_nontrivial_log); + + // if it's same non-trivial log, then previous one is always guaranteed to be not-rollback by line above, + // and so this one should be rollback + sorted_item + .rollback + .conditionally_enforce_true(cs, same_nontrivial_log); + + // we self-check ourselves over the content of the log, even though by the construction + // of the queue it's a guaranteed permutation + let keys_are_equal = UInt256::equals(cs, &sorted_item.key, &previous_item.key); + let values_are_equal = + UInt256::equals(cs, &sorted_item.written_value, &previous_item.written_value); + let same_body = Boolean::multi_and(cs, &[keys_are_equal, values_are_equal]); + + // if previous is not trivial then we always have equal content + let previous_is_non_trivial = previous_is_trivial.negated(cs); + let should_enforce = Boolean::multi_and(cs, &[same_log, previous_is_non_trivial]); + + same_body.conditionally_enforce_true(cs, should_enforce); + + let previous_item_is_not_rollback = previous_item.rollback.negated(cs); + + // decide if we should add the PREVIOUS into the queue + // We add only if previous one is not trivial, and current one doesn't rollback it due to different timestamp, + // OR if current one is trivial + + let maybe_add_to_queue = may_be_different_log.or(cs, is_trivial); + + let add_to_the_queue = Boolean::multi_and( + cs, + &[ + previous_is_non_trivial, + maybe_add_to_queue, + previous_item_is_not_rollback, + ], + ); + let boolean_false = Boolean::allocated_constant(cs, false); + // cleanup some fields that are not useful + let query_to_add = LogQuery { + address: previous_item.address, + key: previous_item.key, + read_value: UInt256::zero(cs), + written_value: previous_item.written_value, + rw_flag: boolean_false, + aux_byte: UInt8::zero(cs), + rollback: boolean_false, + is_service: previous_item.is_service, + shard_id: previous_item.shard_id, + tx_number_in_block: previous_item.tx_number_in_block, + timestamp: UInt32::zero(cs), + }; + + result_queue.push(cs, query_to_add, add_to_the_queue); + + previous_is_trivial = is_trivial; + previous_item = sorted_item; + previous_key = sorting_key; + } + } + + // finalization step - same way, check if last item is not a rollback + { + let now_empty = unsorted_queue.is_empty(cs); + + let previous_is_non_trivial = previous_is_trivial.negated(cs); + let previous_item_is_not_rollback = previous_item.rollback.negated(cs); + let add_to_the_queue = Boolean::multi_and( + cs, + &[ + previous_is_non_trivial, + previous_item_is_not_rollback, + now_empty, + ], + ); + let boolean_false = Boolean::allocated_constant(cs, false); + let query_to_add = LogQuery { + address: previous_item.address, + key: previous_item.key, + read_value: UInt256::zero(cs), + written_value: previous_item.written_value, + rw_flag: boolean_false, + aux_byte: UInt8::zero(cs), + rollback: boolean_false, + is_service: previous_item.is_service, + shard_id: previous_item.shard_id, + tx_number_in_block: previous_item.tx_number_in_block, + timestamp: UInt32::zero(cs), + }; + + result_queue.push(cs, query_to_add, add_to_the_queue); + } + + unsorted_queue.enforce_consistency(cs); + intermediate_sorted_queue.enforce_consistency(cs); + + (lhs, rhs, previous_key, previous_item) +} + +/// Check that a == b and a > b by performing a long subtraction b - a with borrow. +/// Both a and b are considered as least significant word first +#[track_caller] +pub fn prepacked_long_comparison>( + cs: &mut CS, + a: &[Num], + b: &[Num], + width_data: &[usize], +) -> (Boolean, Boolean) { + assert_eq!(a.len(), b.len()); + assert_eq!(a.len(), width_data.len()); + + let mut previous_borrow = Boolean::allocated_constant(cs, false); + let mut limbs_are_equal = vec![]; + for (a, b) in a.iter().zip(b.iter()) { + let a_uint32 = unsafe { UInt32::from_variable_unchecked(a.get_variable()) }; + let b_uint32 = unsafe { UInt32::from_variable_unchecked(b.get_variable()) }; + let (diff, borrow) = a_uint32.overflowing_sub_with_borrow_in(cs, b_uint32, previous_borrow); + let equal = diff.is_zero(cs); + limbs_are_equal.push(equal); + previous_borrow = borrow; + } + let final_borrow = previous_borrow; + let eq = Boolean::multi_and(cs, &limbs_are_equal); + + (eq, final_borrow) +} + +#[cfg(test)] +mod tests { + use super::*; + use boojum::algebraic_props::poseidon2_parameters::Poseidon2GoldilocksExternalMatrix; + use boojum::cs::implementations::reference_cs::CSDevelopmentAssembly; + use boojum::cs::traits::gate::GatePlacementStrategy; + use boojum::cs::CSGeometry; + use boojum::cs::*; + use boojum::field::goldilocks::GoldilocksField; + use boojum::gadgets::tables::*; + use boojum::gadgets::traits::allocatable::CSPlaceholder; + use boojum::gadgets::u160::UInt160; + use boojum::gadgets::u256::UInt256; + use boojum::gadgets::u8::UInt8; + use boojum::implementations::poseidon2::Poseidon2Goldilocks; + use boojum::worker::Worker; + use ethereum_types::{Address, U256}; + type F = GoldilocksField; + type P = GoldilocksField; + + #[test] + fn test_repack_and_prove_events_rollbacks_inner() { + let geometry = CSGeometry { + num_columns_under_copy_permutation: 100, + num_witness_columns: 0, + num_constant_columns: 8, + max_allowed_constraint_degree: 4, + }; + + use boojum::cs::cs_builder::*; + + fn configure< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + let builder = builder.allow_lookup( + LookupParameters::UseSpecializedColumnsWithTableIdAsConstant { + width: 3, + num_repetitions: 8, + share_table_id: true, + }, + ); + let builder = ConstantsAllocatorGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = FmaGateInBaseFieldWithoutConstant::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ReductionGate::::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = BooleanConstraintGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<32>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<16>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = SelectionGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ZeroCheckGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + false, + ); + let builder = DotProductGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = MatrixMultiplicationGate::::configure_builder(builder,GatePlacementStrategy::UseGeneralPurposeColumns); + let builder = NopGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + + builder + } + + use boojum::config::DevCSConfig; + use boojum::cs::cs_builder_reference::CsReferenceImplementationBuilder; + + let builder_impl = + CsReferenceImplementationBuilder::::new(geometry, 1 << 26, 1 << 20); + use boojum::cs::cs_builder::new_builder; + let builder = new_builder::<_, F>(builder_impl); + + let builder = configure(builder); + let mut owned_cs = builder.build(()); + + // add tables + let table = create_xor8_table(); + owned_cs.add_lookup_table::(table); + + let cs = &mut owned_cs; + + let execute = Boolean::allocated_constant(cs, true); + let mut original_queue = StorageLogQueue::::empty(cs); + let unsorted_input = witness_input_unsorted(cs); + for el in unsorted_input { + original_queue.push(cs, el, execute); + } + let mut sorted_queue = StorageLogQueue::::empty(cs); + let sorted_input = witness_input_sorted(cs); + for el in sorted_input { + sorted_queue.push(cs, el, execute); + } + + let mut result_queue = StorageLogQueue::empty(cs); + + let lhs = [Num::allocated_constant(cs, F::from_nonreduced_u64(1)); + DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS]; + let rhs = [Num::allocated_constant(cs, F::from_nonreduced_u64(1)); + DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS]; + let is_start = Boolean::allocated_constant(cs, true); + let round_function = Poseidon2Goldilocks; + let fs_challenges = crate::utils::produce_fs_challenges::< + F, + _, + Poseidon2Goldilocks, + QUEUE_STATE_WIDTH, + { LOG_QUERY_PACKED_WIDTH + 1 }, + DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS, + >( + cs, + original_queue.into_state().tail, + sorted_queue.into_state().tail, + &round_function, + ); + let limit = 16; + let previous_key = UInt32::allocated_constant(cs, 0); + let previous_item = LogQuery::placeholder(cs); + repack_and_prove_events_rollbacks_inner( + cs, + lhs, + rhs, + &mut original_queue, + &mut sorted_queue, + &mut result_queue, + is_start, + fs_challenges, + previous_key, + previous_item, + limit, + ); + + cs.pad_and_shrink(); + let worker = Worker::new(); + let mut owned_cs = owned_cs.into_assembly(); + owned_cs.print_gate_stats(); + assert!(owned_cs.check_if_satisfied(&worker)); + } + + fn witness_input_unsorted>(cs: &mut CS) -> Vec> { + let mut unsorted_querie = vec![]; + let bool_false = Boolean::allocated_constant(cs, false); + let bool_true = Boolean::allocated_constant(cs, true); + let zero_8 = UInt8::allocated_constant(cs, 0); + let one_8 = UInt8::allocated_constant(cs, 1); + let zero_32 = UInt32::allocated_constant(cs, 0); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32781)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("962072674308").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("32776").unwrap()), + rw_flag: bool_true, + aux_byte: one_8, + rollback: bool_false, + is_service: bool_true, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 9441), + }; + + unsorted_querie.push(q); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32781)), + key: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "26331131646299181274004581916076390273434308111684230560370784413089286382145", + ) + .unwrap(), + ), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("32769").unwrap()), + rw_flag: bool_true, + aux_byte: one_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 9597), + }; + unsorted_querie.push(q); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32781)), + key: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "39698723498166066574330386068075452510013183019908537087846976369872031173837", + ) + .unwrap(), + ), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("32").unwrap()), + rw_flag: bool_true, + aux_byte: one_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 9677), + }; + unsorted_querie.push(q); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32781)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("154").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "34572686050049115524117736286529744084162467349680365734578449291092091566196", + ) + .unwrap(), + ), + rw_flag: bool_true, + aux_byte: one_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 9725), + }; + unsorted_querie.push(q); + + unsorted_querie + } + fn witness_input_sorted>(cs: &mut CS) -> Vec> { + let mut sorted_querie = vec![]; + let bool_false = Boolean::allocated_constant(cs, false); + let bool_true = Boolean::allocated_constant(cs, true); + let zero_8 = UInt8::allocated_constant(cs, 0); + let one_8 = UInt8::allocated_constant(cs, 1); + let zero_32 = UInt32::allocated_constant(cs, 0); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32781)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("962072674308").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("32776").unwrap()), + rw_flag: bool_true, + aux_byte: one_8, + rollback: bool_false, + is_service: bool_true, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 9441), + }; + + sorted_querie.push(q); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32781)), + key: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "26331131646299181274004581916076390273434308111684230560370784413089286382145", + ) + .unwrap(), + ), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("32769").unwrap()), + rw_flag: bool_true, + aux_byte: one_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 9597), + }; + sorted_querie.push(q); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32781)), + key: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "39698723498166066574330386068075452510013183019908537087846976369872031173837", + ) + .unwrap(), + ), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("32").unwrap()), + rw_flag: bool_true, + aux_byte: one_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 9677), + }; + sorted_querie.push(q); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32781)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("154").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "34572686050049115524117736286529744084162467349680365734578449291092091566196", + ) + .unwrap(), + ), + rw_flag: bool_true, + aux_byte: one_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 9725), + }; + sorted_querie.push(q); + + sorted_querie + } +} diff --git a/crates/zkevm_circuits/src/main_vm/cycle.rs b/crates/zkevm_circuits/src/main_vm/cycle.rs new file mode 100644 index 0000000..1e70c5b --- /dev/null +++ b/crates/zkevm_circuits/src/main_vm/cycle.rs @@ -0,0 +1,966 @@ +use arrayvec::ArrayVec; + +use super::opcodes::context::apply_context; +use super::pre_state::{create_prestate, PendingSponge}; +use super::state_diffs::{ + StateDiffsAccumulator, MAX_ADD_SUB_RELATIONS_PER_CYCLE, MAX_MUL_DIV_RELATIONS_PER_CYCLE, +}; +use super::*; +use boojum::algebraic_props::round_function::AlgebraicRoundFunction; +use boojum::cs::CSGeometry; +use boojum::gadgets::traits::allocatable::CSAllocatableExt; +use boojum::gadgets::traits::round_function::CircuitRoundFunction; + +use crate::base_structures::decommit_query::DecommitQuery; +use crate::base_structures::log_query::LogQuery; +use crate::base_structures::memory_query::{self, MemoryQuery}; +use crate::base_structures::register::VMRegister; +use crate::base_structures::vm_state::callstack::Callstack; +use crate::base_structures::vm_state::saved_context::ExecutionContextRecord; +use crate::base_structures::vm_state::{ArithmeticFlagsPort, GlobalContext}; +use crate::base_structures::vm_state::{VmLocalState, FULL_SPONGE_QUEUE_STATE_WIDTH}; +use crate::main_vm::opcodes::*; +use crate::main_vm::witness_oracle::SynchronizedWitnessOracle; +use crate::main_vm::witness_oracle::WitnessOracle; +use boojum::cs::traits::cs::DstBuffer; +use boojum::gadgets::u256::UInt256; + +pub(crate) fn vm_cycle< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, + W: WitnessOracle, +>( + cs: &mut CS, + current_state: VmLocalState, + witness_oracle: &SynchronizedWitnessOracle, + global_context: &GlobalContext, + round_function: &R, +) -> VmLocalState +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + // first we create a pre-state + + if crate::config::CIRCUIT_VERSOBE { + println!("------------------------------------------------------------"); + println!("Start of new cycle"); + // synchronization point + let _current_state = current_state.witness_hook(&*cs)().unwrap(); + // dbg!(_current_state); + dbg!(_current_state.pending_exception); + dbg!(_current_state.callstack.current_context.saved_context.pc); + dbg!(_current_state.flags); + } + + let (draft_next_state, common_opcode_state, opcode_carry_parts) = + create_prestate(cs, current_state, witness_oracle, round_function); + + if crate::config::CIRCUIT_VERSOBE { + // synchronization point + let _common_opcode_state = common_opcode_state.witness_hook(&*cs)().unwrap(); + dbg!(_common_opcode_state.src0); + dbg!(_common_opcode_state.src1); + } + + // then we apply each opcode and accumulate state diffs + + let mut diffs_accumulator = StateDiffsAccumulator::::default(); + + apply_nop( + cs, + &draft_next_state, + &common_opcode_state, + &opcode_carry_parts, + &mut diffs_accumulator, + ); + apply_add_sub( + cs, + &draft_next_state, + &common_opcode_state, + &opcode_carry_parts, + &mut diffs_accumulator, + ); + apply_jump( + cs, + &draft_next_state, + &common_opcode_state, + &opcode_carry_parts, + &mut diffs_accumulator, + ); + apply_binop( + cs, + &draft_next_state, + &common_opcode_state, + &opcode_carry_parts, + &mut diffs_accumulator, + ); + apply_context( + cs, + &draft_next_state, + &common_opcode_state, + &opcode_carry_parts, + &mut diffs_accumulator, + ); + apply_ptr( + cs, + &draft_next_state, + &common_opcode_state, + &opcode_carry_parts, + &mut diffs_accumulator, + ); + apply_log( + cs, + &draft_next_state, + &common_opcode_state, + &opcode_carry_parts, + &mut diffs_accumulator, + witness_oracle, + round_function, + ); + apply_calls_and_ret( + cs, + &draft_next_state, + &common_opcode_state, + &opcode_carry_parts, + &mut diffs_accumulator, + witness_oracle, + global_context, + round_function, + ); + apply_mul_div( + cs, + &draft_next_state, + &common_opcode_state, + &opcode_carry_parts, + &mut diffs_accumulator, + ); + apply_shifts( + cs, + &draft_next_state, + &common_opcode_state, + &opcode_carry_parts, + &mut diffs_accumulator, + ); + apply_uma( + cs, + &draft_next_state, + &common_opcode_state, + &opcode_carry_parts, + &mut diffs_accumulator, + witness_oracle, + round_function, + ); + + // and finally apply state diffs + + let mut new_state = draft_next_state; + + let mut write_dst0_bools = ArrayVec::, 8>::new(); + for el in diffs_accumulator.dst_0_values.iter() { + if el.0 { + write_dst0_bools.push(el.1); + } + } + // potentially we can have registers that update DST0 as memory location, + // so we choose only cases where it's indeed into memory. + // It is only a possibility for now. Later we will predicate it based on the + // decoded opcode properties + let dst0_update_potentially_to_memory = Boolean::multi_or(cs, &write_dst0_bools); + + // select dst0 and dst1 values + + let mut can_update_dst0_as_register_only = ArrayVec::, 8>::new(); + let mut should_update_dst1 = ArrayVec::, 8>::new(); + + // for DST0 it's possible to have opcode-constrainted updates only into registers + for el in diffs_accumulator.dst_0_values.iter() { + if el.0 == false { + can_update_dst0_as_register_only.push(el.1); + } + } + for el in diffs_accumulator.dst_1_values.iter() { + should_update_dst1.push(el.0); + } + + let can_update_dst0_as_register_only = Boolean::multi_or(cs, &can_update_dst0_as_register_only); + + let dst0_is_ptr_candidates_iter = + diffs_accumulator + .dst_0_values + .iter() + .map(|el: &(bool, Boolean, VMRegister)| { + (el.1.get_variable(), el.2.is_pointer.get_variable()) + }); + let num_candidates_len = dst0_is_ptr_candidates_iter.len(); + + // Safety: we know by orthogonality of opcodes that boolean selectors in our iterators form either a mask, + // or an empty mask. So we can use unchecked casts below. Even if none of the bits is set (like in NOP case), + // it's not a problem because in the same situation we will not have an update of register/memory anyway + + use boojum::gadgets::num::dot_product; + let dst0_is_ptr = dot_product(cs, dst0_is_ptr_candidates_iter, num_candidates_len); + let dst0_is_ptr = unsafe { Boolean::from_variable_unchecked(dst0_is_ptr) }; + + let mut dst0_value = UInt256::zero(cs); + for (idx, dst) in dst0_value.inner.iter_mut().enumerate() { + let src = + diffs_accumulator + .dst_0_values + .iter() + .map(|el: &(bool, Boolean, VMRegister)| { + (el.1.get_variable(), el.2.value.inner[idx].get_variable()) + }); + + let limb = dot_product(cs, src, num_candidates_len); + + let limb = unsafe { UInt32::from_variable_unchecked(limb) }; + *dst = limb; + } + + let dst1_is_ptr_candidates_iter = diffs_accumulator + .dst_1_values + .iter() + .map(|el| (el.0.get_variable(), el.1.is_pointer.get_variable())); + let num_candidates_len = dst1_is_ptr_candidates_iter.len(); + + let dst1_is_ptr = dot_product(cs, dst1_is_ptr_candidates_iter, num_candidates_len); + let dst1_is_ptr = unsafe { Boolean::from_variable_unchecked(dst1_is_ptr) }; + + let mut dst1_value = UInt256::zero(cs); + for (idx, dst) in dst1_value.inner.iter_mut().enumerate() { + let src = diffs_accumulator + .dst_1_values + .iter() + .map(|el: &(Boolean, VMRegister)| { + (el.0.get_variable(), el.1.value.inner[idx].get_variable()) + }); + + let limb = dot_product(cs, src, num_candidates_len); + + let limb = unsafe { UInt32::from_variable_unchecked(limb) }; + *dst = limb; + } + + let perform_dst0_memory_write_update = Boolean::multi_and( + cs, + &[ + opcode_carry_parts.dst0_performs_memory_access, + dst0_update_potentially_to_memory, + ], + ); + + // We know that UMA opcodes (currently by design) are not allowed to write dst argument into memory + // in any form, so if we do the write here we always base on the state of memory from prestate + + let memory_queue_tail_for_dst0_write = draft_next_state.memory_queue_state; + let memory_queue_length_for_dst0_write = draft_next_state.memory_queue_length; + + let dst0 = VMRegister { + is_pointer: dst0_is_ptr, + value: dst0_value, + }; + + let ( + (dst0_write_initial_state_to_enforce, dst0_write_final_state_to_enforce), + new_memory_queue_tail, + new_memory_queue_len, + ) = may_be_write_memory( + cs, + &perform_dst0_memory_write_update, + &dst0, + &common_opcode_state.timestamp_for_dst_write, + &opcode_carry_parts.dst0_memory_location, + &memory_queue_tail_for_dst0_write, + &memory_queue_length_for_dst0_write, + witness_oracle, + round_function, + ); + + // update tail in next state candidate + new_state.memory_queue_state = new_memory_queue_tail; + new_state.memory_queue_length = new_memory_queue_len; + + // if dst0 is not in memory then update + + let boolean_false = Boolean::allocated_constant(cs, false); + let _boolean_true = Boolean::allocated_constant(cs, true); + let zero_u256 = UInt256::zero(cs); + + // do at once for dst0 and dst1 + + // case when we want to update DST0 from potentially memory-writing opcodes, + // but we address register in fact + + let dst0_performs_reg_update = opcode_carry_parts.dst0_performs_memory_access.negated(cs); + let t = Boolean::multi_and( + cs, + &[dst0_performs_reg_update, dst0_update_potentially_to_memory], + ); + + let dst0_update_register = Boolean::multi_or(cs, &[can_update_dst0_as_register_only, t]); + + if crate::config::CIRCUIT_VERSOBE { + dbg!(dst0_value.witness_hook(&*cs)().unwrap()); + dbg!(dst1_value.witness_hook(&*cs)().unwrap()); + } + + // We should update registers, and the only "exotic" case is if someone tries to put + // dst0 and dst1 in the same location. + + // Note that "register" is a "wide" structure, so it doesn't benefit too much from + // multiselect, and we can just do a sequence, that + // we update each register as being: + // - dst0 in some operation + // - dst1 in some operation + // - special update in some operation + + // outer cycle is over ALL REGISTERS + for (idx, (flag_dst0, flag_dst1)) in common_opcode_state.decoded_opcode.dst_regs_selectors[0] + .iter() + .zip(common_opcode_state.decoded_opcode.dst_regs_selectors[1].iter()) + .enumerate() + { + // form an iterator for all possible candidates + let write_as_dst0 = Boolean::multi_and(cs, &[dst0_update_register, *flag_dst0]); + // dst1 is always register + let write_as_dst1 = *flag_dst1; + + // unfortunately we can not use iter chaining here due to syntax constraint + let mut apply_ptr_update_as_dst0 = ArrayVec::, 32>::new(); + let mut apply_ptr_update_as_dst1 = ArrayVec::, 32>::new(); + let mut it_is_ptr_as_dst0 = ArrayVec::<(Boolean, Boolean), 32>::new(); + let mut it_is_ptr_as_dst1 = ArrayVec::<(Boolean, Boolean), 32>::new(); + let mut it_value_as_dst0 = ArrayVec::<(Boolean, UInt256), 32>::new(); + let mut it_value_as_dst1 = ArrayVec::<(Boolean, UInt256), 32>::new(); + + apply_ptr_update_as_dst0.push(write_as_dst0); + apply_ptr_update_as_dst1.push(write_as_dst1); + + it_is_ptr_as_dst0.push((write_as_dst0, dst0_is_ptr)); + it_value_as_dst0.push((write_as_dst0, dst0_value)); + + it_is_ptr_as_dst1.push((write_as_dst1, dst1_is_ptr)); + it_value_as_dst1.push((write_as_dst1, dst1_value)); + + // then chain all specific register updates. Opcodes that produce specific updates do not make non-specific register updates, + // so we just place them along with dst0 + for specific_update in diffs_accumulator.specific_registers_updates[idx].drain(..) { + apply_ptr_update_as_dst0.push(specific_update.0); + it_is_ptr_as_dst0.push((specific_update.0, specific_update.1.is_pointer)); + it_value_as_dst0.push((specific_update.0, specific_update.1.value)); + } + + // chain removal of pointer markers at once. Same, can be placed into dst0 + let mut tmp = ArrayVec::, 16>::new(); + for remove_ptr_request in diffs_accumulator.remove_ptr_on_specific_registers[idx].drain(..) + { + tmp.push(remove_ptr_request); + } + + if tmp.is_empty() == false { + let remove_ptr_marker = Boolean::multi_or(cs, &tmp); + apply_ptr_update_as_dst0.push(remove_ptr_marker); + it_is_ptr_as_dst0.push((remove_ptr_marker, boolean_false)); + } + + // chain zeroing at once. Same, can be placed into dst0 + let mut tmp = ArrayVec::, 16>::new(); + for zeroing_requests in diffs_accumulator.specific_registers_zeroing[idx].drain(..) { + tmp.push(zeroing_requests); + } + + if tmp.is_empty() == false { + let zero_out_reg = Boolean::multi_or(cs, &tmp); + it_value_as_dst0.push((zero_out_reg, zero_u256)); + } + + let any_ptr_update_as_dst0 = Boolean::multi_or(cs, &apply_ptr_update_as_dst0); + let any_ptr_update_as_dst1 = Boolean::multi_or(cs, &apply_ptr_update_as_dst1); + + // Safety: our update flags are preconditioned by the applicability of the opcodes, and if opcode + // updates specific registers it does NOT write using "normal" dst0/dst1 addressing, so our mask + // is indeed a bitmask or empty + + // as dst0 + let num_candidates = it_is_ptr_as_dst0.len(); + let is_ptr_as_dst0 = dot_product( + cs, + it_is_ptr_as_dst0 + .into_iter() + .map(|el| (el.0.get_variable(), el.1.get_variable())), + num_candidates, + ); + let is_ptr_as_dst0 = unsafe { Boolean::from_variable_unchecked(is_ptr_as_dst0) }; + + new_state.registers[idx].is_pointer = Boolean::conditionally_select( + cs, + any_ptr_update_as_dst0, + &is_ptr_as_dst0, + &new_state.registers[idx].is_pointer, + ); + + // now as dst1 + let num_candidates = it_is_ptr_as_dst1.len(); + let is_ptr_as_dst1 = dot_product( + cs, + it_is_ptr_as_dst1 + .into_iter() + .map(|el| (el.0.get_variable(), el.1.get_variable())), + num_candidates, + ); + let is_ptr_as_dst1 = unsafe { Boolean::from_variable_unchecked(is_ptr_as_dst1) }; + new_state.registers[idx].is_pointer = Boolean::conditionally_select( + cs, + any_ptr_update_as_dst1, + &is_ptr_as_dst1, + &new_state.registers[idx].is_pointer, + ); + + // for registers we just use parallel select, that has the same efficiency as multiselect, + // because internally it's [UInt32; 8] + + for (flag, value) in it_value_as_dst0 + .into_iter() + .chain(it_value_as_dst1.into_iter()) + { + new_state.registers[idx].value = + UInt256::conditionally_select(cs, flag, &value, &new_state.registers[idx].value); + } + } + + // apply smaller changes to VM state, such as ergs left, etc + + // PC + for (flag, value) in diffs_accumulator.new_pc_candidates.drain(..) { + new_state.callstack.current_context.saved_context.pc = UInt16::conditionally_select( + cs, + flag, + &value, + &new_state.callstack.current_context.saved_context.pc, + ); + } + + // Ergs + for (flag, value) in diffs_accumulator.new_ergs_left_candidates.drain(..) { + new_state + .callstack + .current_context + .saved_context + .ergs_remaining = UInt32::conditionally_select( + cs, + flag, + &value, + &new_state + .callstack + .current_context + .saved_context + .ergs_remaining, + ); + } + + // Ergs per pubdata + for (flag, value) in diffs_accumulator.new_ergs_per_pubdata.into_iter() { + new_state.ergs_per_pubdata_byte = + UInt32::conditionally_select(cs, flag, &value, &new_state.ergs_per_pubdata_byte); + } + + // Tx number in block + for (flag, value) in diffs_accumulator.new_tx_number.into_iter() { + new_state.tx_number_in_block = + UInt32::conditionally_select(cs, flag, &value, &new_state.tx_number_in_block); + } + + // Page counter + new_state.memory_page_counter = diffs_accumulator.memory_page_counters.expect("is some"); + + // Context value + for (flag, value) in diffs_accumulator.context_u128_candidates.drain(..) { + new_state.context_composite_u128 = + UInt32::parallel_select(cs, flag, &value, &new_state.context_composite_u128); + } + + // Heap limit + for (flag, value) in diffs_accumulator.new_heap_bounds.drain(..) { + new_state + .callstack + .current_context + .saved_context + .heap_upper_bound = UInt32::conditionally_select( + cs, + flag, + &value, + &new_state + .callstack + .current_context + .saved_context + .heap_upper_bound, + ); + } + + // Axu heap limit + for (flag, value) in diffs_accumulator.new_aux_heap_bounds.drain(..) { + new_state + .callstack + .current_context + .saved_context + .aux_heap_upper_bound = UInt32::conditionally_select( + cs, + flag, + &value, + &new_state + .callstack + .current_context + .saved_context + .aux_heap_upper_bound, + ); + } + + // variable queue states + + // Memory due to UMA + for (flag, length, state) in diffs_accumulator.memory_queue_candidates.into_iter() { + new_state.memory_queue_length = + UInt32::conditionally_select(cs, flag, &length, &new_state.memory_queue_length); + + new_state.memory_queue_state = + Num::parallel_select(cs, flag, &state, &new_state.memory_queue_state); + } + + // decommittment due to far call + for (flag, length, state) in diffs_accumulator.decommitment_queue_candidates.into_iter() { + new_state.code_decommittment_queue_length = UInt32::conditionally_select( + cs, + flag, + &length, + &new_state.code_decommittment_queue_length, + ); + + new_state.code_decommittment_queue_state = + Num::parallel_select(cs, flag, &state, &new_state.code_decommittment_queue_state); + } + + // forward storage log + for (flag, length, state) in diffs_accumulator.log_queue_forward_candidates.into_iter() { + new_state + .callstack + .current_context + .log_queue_forward_part_length = UInt32::conditionally_select( + cs, + flag, + &length, + &new_state + .callstack + .current_context + .log_queue_forward_part_length, + ); + + new_state.callstack.current_context.log_queue_forward_tail = Num::parallel_select( + cs, + flag, + &state, + &new_state.callstack.current_context.log_queue_forward_tail, + ); + } + + // rollback log head(!) + for (flag, length, state) in diffs_accumulator.log_queue_rollback_candidates.into_iter() { + new_state + .callstack + .current_context + .saved_context + .reverted_queue_segment_len = UInt32::conditionally_select( + cs, + flag, + &length, + &new_state + .callstack + .current_context + .saved_context + .reverted_queue_segment_len, + ); + + new_state + .callstack + .current_context + .saved_context + .reverted_queue_head = Num::parallel_select( + cs, + flag, + &state, + &new_state + .callstack + .current_context + .saved_context + .reverted_queue_head, + ); + } + + // flags + for (flag, flags) in diffs_accumulator.flags.iter() { + new_state.flags = + ArithmeticFlagsPort::conditionally_select(cs, *flag, flags, &new_state.flags); + } + + // and now we either replace or not the callstack in full + for (flag, callstack) in diffs_accumulator.callstacks.into_iter() { + new_state.callstack = + Callstack::conditionally_select(cs, flag, &callstack, &new_state.callstack); + } + + // other state parts + let new_pending_exception = Boolean::multi_or(cs, &diffs_accumulator.pending_exceptions); + new_state.pending_exception = new_pending_exception; + + // conditional u32 range checks. All of those are of the fixed length per opcode, so we just select + { + let (_, mut to_enforce) = diffs_accumulator + .u32_conditional_range_checks + .pop() + .unwrap(); + for (applies, candidate) in diffs_accumulator.u32_conditional_range_checks.drain(..) { + to_enforce = UInt32::parallel_select(cs, applies, &candidate, &to_enforce); + } + + let _ = to_enforce.map(|el| UInt32::from_variable_checked(cs, el.get_variable())); + } + + // add/sub relations + let cap = diffs_accumulator.add_sub_relations.len(); + for _ in 0..MAX_ADD_SUB_RELATIONS_PER_CYCLE { + let mut relations = Vec::with_capacity(cap); + for (flag, values) in diffs_accumulator.add_sub_relations.iter_mut() { + if let Some(el) = values.pop() { + relations.push((*flag, el)); + } + } + + if let Some((_, selected)) = relations.pop() { + let mut selected = selected; + for (flag, el) in relations.into_iter() { + selected = AddSubRelation::conditionally_select(cs, flag, &el, &selected); + } + + enforce_addition_relation(cs, selected); + } + } + + let cap = diffs_accumulator.mul_div_relations.len(); + for _ in 0..MAX_MUL_DIV_RELATIONS_PER_CYCLE { + let mut relations = Vec::with_capacity(cap); + for (flag, values) in diffs_accumulator.mul_div_relations.iter_mut() { + if let Some(el) = values.pop() { + relations.push((*flag, el)); + } + } + + if let Some((_, selected)) = relations.pop() { + let mut selected = selected; + for (flag, el) in relations.into_iter() { + selected = MulDivRelation::conditionally_select(cs, flag, &el, &selected); + } + + enforce_mul_relation(cs, selected); + } + } + + // now we can enforce sponges. There are only 2 outcomes + // - we have dst0 write (and may be src0 read), that we taken care above + // - opcode itself modified memory queue, based on outcome of src0 read + // in parallel opcodes either + // - do not use sponges and only rely on src0/dst0 + // - can not have src0/dst0 in memory, but use sponges (UMA, near_call, far call, ret) + + let src0_read_state_pending_sponge = opcode_carry_parts.src0_read_sponge_data; + let dst0_write_state_pending_sponge = PendingSponge { + initial_state: dst0_write_initial_state_to_enforce, + final_state: dst0_write_final_state_to_enforce, + should_enforce: perform_dst0_memory_write_update, + }; + + let mut first_sponge_candidate = src0_read_state_pending_sponge; + for (can_use_sponge_for_src0, can_use_sponge_for_dst0, opcode_applies, sponge_data) in + diffs_accumulator.sponge_candidates_to_run.iter_mut() + { + assert!(*can_use_sponge_for_src0 == false); + assert!(*can_use_sponge_for_dst0 == false); + + if let Some((should_enforce, initial_state, final_state)) = sponge_data.pop() { + // we can conditionally select + let formal_sponge = PendingSponge { + initial_state: initial_state, + final_state: final_state, + should_enforce: should_enforce, + }; + + first_sponge_candidate = Selectable::conditionally_select( + cs, + *opcode_applies, + &formal_sponge, + &first_sponge_candidate, + ); + } + } + + let mut second_sponge_candidate = dst0_write_state_pending_sponge; + for (can_use_sponge_for_src0, can_use_sponge_for_dst0, opcode_applies, sponge_data) in + diffs_accumulator.sponge_candidates_to_run.iter_mut() + { + assert!(*can_use_sponge_for_src0 == false); + assert!(*can_use_sponge_for_dst0 == false); + + if let Some((should_enforce, initial_state, final_state)) = sponge_data.pop() { + // we can conditionally select + let formal_sponge = PendingSponge { + initial_state: initial_state, + final_state: final_state, + should_enforce: should_enforce, + }; + + second_sponge_candidate = Selectable::conditionally_select( + cs, + *opcode_applies, + &formal_sponge, + &second_sponge_candidate, + ); + } + } + + use super::state_diffs::MAX_SPONGES_PER_CYCLE; + let mut selected_sponges_to_enforce = ArrayVec::<_, MAX_SPONGES_PER_CYCLE>::new(); + selected_sponges_to_enforce.push(first_sponge_candidate); + selected_sponges_to_enforce.push(second_sponge_candidate); + + for _ in 2..MAX_SPONGES_PER_CYCLE { + let mut selected = None; + for (_, _, opcode_applies, sponge_data) in + diffs_accumulator.sponge_candidates_to_run.iter_mut() + { + if let Some((should_enforce, initial_state, final_state)) = sponge_data.pop() { + if let Some(selected) = selected.as_mut() { + // we can conditionally select + let formal_sponge = PendingSponge { + initial_state: initial_state, + final_state: final_state, + should_enforce: should_enforce, + }; + + *selected = Selectable::conditionally_select( + cs, + *opcode_applies, + &formal_sponge, + &*selected, + ); + } else { + let should_enforce = Boolean::multi_and(cs, &[should_enforce, *opcode_applies]); + let formal_sponge = PendingSponge { + initial_state: initial_state, + final_state: final_state, + should_enforce: should_enforce, + }; + selected = Some(formal_sponge); + } + } + } + + let selected = selected.expect("non-trivial sponge"); + selected_sponges_to_enforce.push(selected); + } + + // ensure that we selected everything + for (_, _, _, sponge_data) in diffs_accumulator.sponge_candidates_to_run.iter_mut() { + assert!(sponge_data.is_empty()); + } + assert_eq!(selected_sponges_to_enforce.len(), MAX_SPONGES_PER_CYCLE); + + // dbg!(new_state.memory_queue_state.witness_hook(&*cs)().unwrap()); + // dbg!(new_state.memory_queue_length.witness_hook(&*cs)().unwrap()); + + // actually enforce_sponges + + enforce_sponges(cs, &selected_sponges_to_enforce, round_function); + + if crate::config::CIRCUIT_VERSOBE { + // synchronization point + let _wit = new_state.witness_hook(&*cs)().unwrap(); + // dbg!(_wit.memory_queue_state); + // dbg!(_wit.memory_queue_length); + println!("End of cycle"); + } + + new_state +} + +use crate::main_vm::pre_state::MemoryLocation; + +fn may_be_write_memory< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, + W: WitnessOracle, +>( + cs: &mut CS, + should_write_dst0: &Boolean, + dst0_value: &VMRegister, + timestamp: &UInt32, + location: &MemoryLocation, + current_memory_sponge_tail: &[Num; FULL_SPONGE_QUEUE_STATE_WIDTH], + current_memory_sponge_length: &UInt32, + witness_oracle: &SynchronizedWitnessOracle, + _round_function: &R, +) -> ( + ( + [Num; FULL_SPONGE_QUEUE_STATE_WIDTH], + [Num; FULL_SPONGE_QUEUE_STATE_WIDTH], + ), + [Num; FULL_SPONGE_QUEUE_STATE_WIDTH], + UInt32, +) +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + if crate::config::CIRCUIT_VERSOBE { + if should_write_dst0.witness_hook(&*cs)().unwrap() { + println!("Will write DST0 to memory"); + dbg!(location.witness_hook(&*cs)().unwrap()); + dbg!(dst0_value.witness_hook(&*cs)().unwrap()); + } + } + + let MemoryLocation { page, index } = location; + let boolean_true = Boolean::allocated_constant(cs, true); + + let query = MemoryQuery { + timestamp: *timestamp, + memory_page: *page, + index: *index, + is_ptr: dst0_value.is_pointer, + value: dst0_value.value, + rw_flag: boolean_true, + }; + + use boojum::gadgets::traits::encodable::CircuitEncodable; + let packed_query = query.encode(cs); + + // absorb by replacement + + use boojum::gadgets::queue::full_state_queue::simulate_new_tail_for_full_state_queue; + + use crate::base_structures::memory_query::MEMORY_QUERY_PACKED_WIDTH; + + let simulated_values = simulate_new_tail_for_full_state_queue::< + F, + 8, + FULL_SPONGE_QUEUE_STATE_WIDTH, + 4, + MEMORY_QUERY_PACKED_WIDTH, + R, + _, + >( + cs, + packed_query, + current_memory_sponge_tail.map(|el| el.get_variable()), + *should_write_dst0, + ); + + // create absorbed initial state + + let initial_state = [ + Num::from_variable(packed_query[0]), + Num::from_variable(packed_query[1]), + Num::from_variable(packed_query[2]), + Num::from_variable(packed_query[3]), + Num::from_variable(packed_query[4]), + Num::from_variable(packed_query[5]), + Num::from_variable(packed_query[6]), + Num::from_variable(packed_query[7]), + current_memory_sponge_tail[8], + current_memory_sponge_tail[9], + current_memory_sponge_tail[10], + current_memory_sponge_tail[11], + ]; + + let simulated_final_state = simulated_values.map(|el| Num::from_variable(el)); + + // for all reasonable execution traces it's fine + let new_len_candidate = unsafe { current_memory_sponge_length.increment_unchecked(cs) }; + + let new_length = UInt32::conditionally_select( + cs, + *should_write_dst0, + &new_len_candidate, + ¤t_memory_sponge_length, + ); + + let final_state = Num::parallel_select( + cs, + *should_write_dst0, + &simulated_final_state, + current_memory_sponge_tail, + ); + + let oracle = witness_oracle.clone(); + // we should assemble all the dependencies here, and we will use AllocateExt here + let mut dependencies = + Vec::with_capacity( as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1); + dependencies.push(should_write_dst0.get_variable().into()); + dependencies.extend(Place::from_variables(query.flatten_as_variables())); + + cs.set_values_with_dependencies_vararg( + &dependencies, + &[], + move |inputs: &[F], _buffer: &mut DstBuffer<'_, '_, F>| { + let execute = >::cast_from_source(inputs[0]); + + use crate::main_vm::cycle::memory_query::MemoryQueryWitness; + + let mut query = [F::ZERO; as CSAllocatableExt>::INTERNAL_STRUCT_LEN]; + query.copy_from_slice(&inputs[1..]); + let query: MemoryQueryWitness = CSAllocatableExt::witness_from_set_of_values(query); + + let mut guard = oracle.inner.write().expect("not poisoned"); + guard.push_memory_witness(&query, execute); + drop(guard); + }, + ); + + ( + (initial_state, simulated_final_state), + final_state, + new_length, + ) +} + +fn enforce_sponges< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, +>( + cs: &mut CS, + candidates: &[PendingSponge], + _round_function: &R, +) { + for el in candidates.iter() { + let PendingSponge { + initial_state, + final_state, + should_enforce, + } = el; + let true_final = R::compute_round_function_over_nums(cs, *initial_state); + for (a, b) in true_final.iter().zip(final_state.iter()) { + Num::conditionally_enforce_equal(cs, *should_enforce, a, b); + } + } +} + +pub const fn reference_vm_geometry() -> CSGeometry { + CSGeometry { + num_columns_under_copy_permutation: 140, + num_witness_columns: 0, + num_constant_columns: 8, + max_allowed_constraint_degree: 8, + } +} diff --git a/crates/zkevm_circuits/src/main_vm/decoded_opcode.rs b/crates/zkevm_circuits/src/main_vm/decoded_opcode.rs new file mode 100644 index 0000000..13093d6 --- /dev/null +++ b/crates/zkevm_circuits/src/main_vm/decoded_opcode.rs @@ -0,0 +1,576 @@ +use super::*; +use boojum::cs::gates::{ConstantAllocatableCS, ReductionByPowersGate, ReductionGate}; +use boojum::cs::traits::cs::ConstraintSystem; +use boojum::cs::{Place, Variable}; +use boojum::gadgets::boolean::Boolean; +use boojum::gadgets::impls::limbs_decompose::reduce_terms; +use boojum::gadgets::num::Num; +use boojum::gadgets::traits::allocatable::CSAllocatable; +use boojum::gadgets::traits::castable::WitnessCastable; +use boojum::gadgets::traits::selectable::Selectable; +use boojum::gadgets::u32::UInt32; +use boojum::gadgets::u8::UInt8; +use boojum::serde_utils::BigArraySerde; +use boojum::{field::SmallField, gadgets::u16::UInt16}; +use cs_derive::*; + +use zkevm_opcode_defs::{ + OPCODE_INPUT_VARIANT_FLAGS, OPCODE_OUTPUT_VARIANT_FLAGS, OPCODE_TYPE_BITS, REGISTERS_COUNT, +}; + +pub const NUM_SRC_REGISTERS: usize = 2; +pub const NUM_DST_REGISTERS: usize = 2; +pub const REGISTER_ENCODING_BITS: usize = 4; + +use super::opcode_bitmask::OpcodeBitmask; +use super::opcode_bitmask::TOTAL_OPCODE_MEANINGFULL_DESCRIPTION_BITS; + +#[derive(Derivative, CSAllocatable, WitnessHookable)] +#[derivative(Debug)] +pub struct OpcodePropertiesDecoding { + pub properties_bits: OpcodeBitmask, + pub src_regs_selectors: [[Boolean; REGISTERS_COUNT]; NUM_SRC_REGISTERS], + pub dst_regs_selectors: [[Boolean; REGISTERS_COUNT]; NUM_DST_REGISTERS], + pub imm0: UInt16, + pub imm1: UInt16, +} + +/// we assume that +/// - we did read the opcode either from memory, or have skipped opcode, or something else +/// - if we should have skipped cycle then we did it already +/// Now we need to decide either to mask into exception or into NOP, or execute +pub fn perform_initial_decoding>( + cs: &mut CS, + raw_opcode: [UInt32; 2], + encoded_flags: Num, + is_kernel_mode: Boolean, + is_static_context: Boolean, + callstack_is_full: Boolean, + ergs_left: UInt32, + did_skip_cycle: Boolean, +) -> (OpcodePropertiesDecoding, UInt32) { + // decode and resolve condition immediatelly + // If we will later on mask into PANIC then we will just ignore resolved condition + let initial_decoding = + partially_decode_from_integer_and_resolve_condition(cs, raw_opcode, encoded_flags); + + let (opcode_boolean_spread_data, aux_bools) = + split_out_aux_bits(cs, initial_decoding.opcode_boolean_spread_data); + let condition_if_not_masked_later = initial_decoding.condition; + + // resolve fast exceptions + // - out of ergs + // - kernel mode + // - writes in static context + // - callstack is full + + // set ergs cost to 0 if we are skipping cycle + let masked_ergs_cost = initial_decoding.ergs_cost.mask_negated(cs, did_skip_cycle); + + if crate::config::CIRCUIT_VERSOBE { + println!( + "Have {} ergs left, opcode cost is {}", + ergs_left.witness_hook(&*cs)().unwrap(), + masked_ergs_cost.witness_hook(&*cs)().unwrap(), + ); + } + + let (ergs_left, out_of_ergs_exception) = ergs_left.overflowing_sub(cs, masked_ergs_cost); + let ergs_left = ergs_left.mask_negated(cs, out_of_ergs_exception); // it's 0 if we underflow + + let requires_kernel_mode = aux_bools[zkevm_opcode_defs::KERNER_MODE_FLAG_IDX]; + let can_be_used_in_static_context = + aux_bools[zkevm_opcode_defs::CAN_BE_USED_IN_STATIC_CONTEXT_FLAG_IDX]; + let explicit_panic = aux_bools[zkevm_opcode_defs::EXPLICIT_PANIC_FLAG_IDX]; + + let normal_mode = is_kernel_mode.negated(cs); + let kernel_mode_exception = Boolean::multi_and(cs, &[requires_kernel_mode, normal_mode]); + let opcode_can_not_be_used_in_static_context = can_be_used_in_static_context.negated(cs); + let write_in_static_exception = Boolean::multi_and( + cs, + &[is_static_context, opcode_can_not_be_used_in_static_context], + ); + + let any_exception = Boolean::multi_or( + cs, + &[ + explicit_panic, + out_of_ergs_exception, + kernel_mode_exception, + write_in_static_exception, + callstack_is_full, + ], + ); + + // if we do have an exception then we have mask properties into PANIC + let mask_into_panic = any_exception; + if crate::config::CIRCUIT_VERSOBE { + if mask_into_panic.witness_hook(&*cs)().unwrap() { + println!("Masking into PANIC in decoding phase"); + dbg!([ + explicit_panic, + out_of_ergs_exception, + kernel_mode_exception, + write_in_static_exception, + callstack_is_full, + ] + .witness_hook(&*cs)() + .unwrap()); + } + } + let panic_encoding = *zkevm_opcode_defs::PANIC_BITSPREAD_U64; + + // mask out aux bits (those are 0, but do it just in case) + let panic_encoding = panic_encoding & OPCODE_PROPS_BITMASK_FOR_BITSPREAD_ENCODING; + + let panic_encoding = F::from_u64(panic_encoding).expect("fits into field"); + let panic_encoding = Num::allocated_constant(cs, panic_encoding); + let opcode_boolean_spread_data = Num::conditionally_select( + cs, + mask_into_panic, + &panic_encoding, + &opcode_boolean_spread_data, + ); + + let no_panic = mask_into_panic.negated(cs); + let condition_is_not_fulfilled = condition_if_not_masked_later.negated(cs); + + // then if we didn't mask into panic and condition was false then mask into NOP + let mask_into_nop = Boolean::multi_and(cs, &[no_panic, condition_is_not_fulfilled]); + if crate::config::CIRCUIT_VERSOBE { + if mask_into_nop.witness_hook(&*cs)().unwrap() { + println!("Masking into NOP in decoding phase"); + } + } + + let nop_encoding = *zkevm_opcode_defs::NOP_BITSPREAD_U64; + // mask out aux bits (those are 0, but do it just in case) + let nop_encoding = nop_encoding & OPCODE_PROPS_BITMASK_FOR_BITSPREAD_ENCODING; + let nop_encoding = F::from_u64(nop_encoding).expect("fits into field"); + let nop_encoding = Num::allocated_constant(cs, nop_encoding); + + let opcode_boolean_spread_data = Num::conditionally_select( + cs, + mask_into_nop, + &nop_encoding, + &opcode_boolean_spread_data, + ); + + let mask_any = Boolean::multi_or(cs, &[mask_into_nop, mask_into_panic]); + + // Ok, now just decompose spreads into bitmasks, and spread and decompose register indexes + + let all_opcodes_props_bits = + opcode_boolean_spread_data + .spread_into_bits::<_, TOTAL_OPCODE_MEANINGFULL_DESCRIPTION_BITS>(cs); + + let src_regs_encoding = initial_decoding + .src_regs_encoding + .mask_negated(cs, mask_any); + let dst_regs_encoding = initial_decoding + .dst_regs_encoding + .mask_negated(cs, mask_any); + + // split encodings into 4 bit chunks unchecked + + let [src0_encoding, src1_encoding] = split_register_encoding_byte(cs, src_regs_encoding); + let [dst0_encoding, dst1_encoding] = split_register_encoding_byte(cs, dst_regs_encoding); + + if crate::config::CIRCUIT_VERSOBE { + dbg!(&src0_encoding.witness_hook(&*cs)().unwrap()); + dbg!(&src1_encoding.witness_hook(&*cs)().unwrap()); + + dbg!(&dst0_encoding.witness_hook(&*cs)().unwrap()); + dbg!(&dst1_encoding.witness_hook(&*cs)().unwrap()); + } + + // and enforce their bit length by table access, and simultaneously get + // bitmasks for selection + + // for every register we first need to spread integer index -> bitmask as integer, and then transform integer bitmask into individual bits + + let src0_mask = reg_idx_into_bitspread(cs, src0_encoding); + let src0_bitspread = src0_mask.spread_into_bits::<_, REGISTERS_COUNT>(cs); + + let src1_mask = reg_idx_into_bitspread(cs, src1_encoding); + let src1_bitspread = src1_mask.spread_into_bits::<_, REGISTERS_COUNT>(cs); + + let dst0_mask = reg_idx_into_bitspread(cs, dst0_encoding); + let dst0_bitspread = dst0_mask.spread_into_bits::<_, REGISTERS_COUNT>(cs); + + let dst1_mask = reg_idx_into_bitspread(cs, dst1_encoding); + let dst1_bitspread = dst1_mask.spread_into_bits::<_, REGISTERS_COUNT>(cs); + + let imm0 = initial_decoding.imm0; + let imm1 = initial_decoding.imm1; + + // place everything into struct + + let opcode_props = OpcodeBitmask::from_full_mask(all_opcodes_props_bits); + + let new = OpcodePropertiesDecoding { + properties_bits: opcode_props, + src_regs_selectors: [src0_bitspread, src1_bitspread], + dst_regs_selectors: [dst0_bitspread, dst1_bitspread], + imm0, + imm1, + }; + + (new, ergs_left) +} + +// for integer N returns a field element with value 0 if N is zero, and 1 << (N-1) otherwise +pub fn reg_idx_into_bitspread>( + cs: &mut CS, + integer: Num, +) -> Num { + use crate::tables::integer_to_boolean_mask::RegisterIndexToBitmaskTable; + + let table_id = cs + .get_table_id_for_marker::() + .expect("table must be added before"); + + let vals = cs.perform_lookup::<1, 2>(table_id, &[integer.get_variable()]); + let bitspread = vals[0]; + + Num::from_variable(bitspread) +} + +use zkevm_opcode_defs::{ + CONDITIONAL_BITS_SHIFT, OPCODES_TABLE_WIDTH, VARIANT_AND_CONDITION_ENCODING_BITS, +}; + +use crate::bit_width_to_bitmask; + +pub const VARIANT_AND_CONDITION_ENCODING_MASK: u64 = + bit_width_to_bitmask(VARIANT_AND_CONDITION_ENCODING_BITS); +pub const VARIANT_ENCODING_MASK: u64 = bit_width_to_bitmask(OPCODES_TABLE_WIDTH); +pub const OPCODE_PROPS_BITMASK_FOR_BITSPREAD_ENCODING: u64 = + bit_width_to_bitmask(TOTAL_OPCODE_DESCRIPTION_BITS_FLATTENED); + +use zkevm_opcode_defs::TOTAL_AUX_BITS; + +use super::opcode_bitmask::{ + OPCODE_FLAGS_BITS, OPCODE_VARIANT_BITS, TOTAL_OPCODE_DESCRIPTION_AND_AUX_BITS, + TOTAL_OPCODE_DESCRIPTION_BITS_FLATTENED, +}; + +const CONDITION_ENCODING_BITS: usize = 3; + +const UNUSED_GAP: usize = + VARIANT_AND_CONDITION_ENCODING_BITS - OPCODES_TABLE_WIDTH - CONDITION_ENCODING_BITS; + +pub const NUM_BITS_BEFORE_AUX_INFORMATION: usize = OPCODE_TYPE_BITS + + OPCODE_VARIANT_BITS + + OPCODE_FLAGS_BITS + + OPCODE_INPUT_VARIANT_FLAGS + + OPCODE_OUTPUT_VARIANT_FLAGS; + +use crate::base_structures::vm_state::ArithmeticFlagsPort; + +pub(crate) fn encode_flags>( + cs: &mut CS, + flags: &ArithmeticFlagsPort, +) -> Num { + if cs.gate_is_allowed::>() { + let zero = Num::allocated_constant(cs, F::ZERO); + let inputs = [ + flags.overflow_or_less_than.get_variable(), + flags.equal.get_variable(), + flags.greater_than.get_variable(), + zero.get_variable(), + ]; + let result = reduce_terms(cs, F::TWO, inputs); + + Num::from_variable(result) + } else if cs.gate_is_allowed::>() { + let zero = Num::allocated_constant(cs, F::ZERO); + let inputs = [ + flags.overflow_or_less_than.get_variable(), + flags.equal.get_variable(), + flags.greater_than.get_variable(), + zero.get_variable(), + ]; + let contants = [F::ONE, F::TWO, F::from_u64_unchecked(4), F::ZERO]; + let result = ReductionGate::::reduce_terms(cs, contants, inputs); + + Num::from_variable(result) + } else { + unimplemented!() + } +} + +pub struct OpcodePreliminaryDecoding { + pub condition: Boolean, + pub opcode_boolean_spread_data: Num, // this has both flags that describe the opcode itself, and aux flags for EH + pub src_regs_encoding: UInt8, + pub dst_regs_encoding: UInt8, + pub imm0: UInt16, + pub imm1: UInt16, + pub ergs_cost: UInt32, +} + +pub fn split_out_aux_bits>( + cs: &mut CS, + opcode_boolean_spread_data: Num, +) -> (Num, [Boolean; TOTAL_AUX_BITS]) { + assert!(TOTAL_OPCODE_DESCRIPTION_AND_AUX_BITS <= 64); + assert!(TOTAL_OPCODE_DESCRIPTION_AND_AUX_BITS <= F::CAPACITY_BITS); + + let main_props_var = cs.alloc_variable_without_value(); + let extra_props_vars = cs.alloc_multiple_variables_without_values::(); + + if ::WitnessConfig::EVALUATE_WITNESS { + let mut all_outputs = [Variable::placeholder(); TOTAL_AUX_BITS + 1]; + all_outputs[0] = main_props_var; + all_outputs[1..].copy_from_slice(&extra_props_vars); + + let value_fn = move |inputs: [F; 1]| { + let witness = inputs[0].as_u64_reduced(); + let mut result = [F::ZERO; TOTAL_AUX_BITS + 1]; + + let props = witness & OPCODE_PROPS_BITMASK_FOR_BITSPREAD_ENCODING; // bits without AUX flag + + result[0] = F::from_u64(props).expect("must fit into field"); + + assert!(OPCODE_PROPS_BITMASK_FOR_BITSPREAD_ENCODING < u64::MAX); + let aux_bits_as_u64 = witness >> TOTAL_OPCODE_DESCRIPTION_BITS_FLATTENED; + let mut aux_bits_as_u64 = aux_bits_as_u64 as u64; + for idx in 0..TOTAL_AUX_BITS { + let bit = (aux_bits_as_u64 & 1u64) == 1; + result[idx + 1] = if bit { F::ONE } else { F::ZERO }; + + aux_bits_as_u64 >>= 1; + } + debug_assert!(aux_bits_as_u64 == 0); + + result + }; + + let dependencies = [opcode_boolean_spread_data.get_variable().into()]; + + cs.set_values_with_dependencies( + &dependencies, + &Place::from_variables(all_outputs), + value_fn, + ); + } + + let main_props = Num::from_variable(main_props_var); + let extra_props_bits = extra_props_vars.map(|el| Boolean::from_variable_checked(cs, el)); + + // we should enforce bit length because we just did the splitting + let _ = main_props.constraint_bit_length_as_bytes(cs, TOTAL_OPCODE_DESCRIPTION_BITS_FLATTENED); + + // now just make a combination to prove equality + + let to_enforce = [ + (main_props_var, F::ONE), + ( + extra_props_vars[0], + F::from_u64_unchecked(1u64 << (TOTAL_OPCODE_DESCRIPTION_BITS_FLATTENED)), + ), + ( + extra_props_vars[1], + F::from_u64_unchecked(1u64 << (TOTAL_OPCODE_DESCRIPTION_BITS_FLATTENED + 1)), + ), + ( + extra_props_vars[2], + F::from_u64_unchecked(1u64 << (TOTAL_OPCODE_DESCRIPTION_BITS_FLATTENED + 2)), + ), + (opcode_boolean_spread_data.get_variable(), F::MINUS_ONE), + ]; + + Num::enforce_zero_for_linear_combination(cs, &to_enforce); + + (main_props, extra_props_bits) +} + +/// Decodes only necessary parts of the opcode to resolve condition +/// for masking into NOP if opcode does nothing. +/// We also output imm0/imm1 parts that will NOT be ever masked, +/// and register index encoding parts too that would be masked into 0. +/// Please remember that we mask only bitspread part after condition is resolved, and we do not need +/// to recompute the cost(!) +pub fn partially_decode_from_integer_and_resolve_condition< + F: SmallField, + CS: ConstraintSystem, +>( + cs: &mut CS, + opcode_properties_words: [UInt32; 2], + encoded_flags: Num, +) -> OpcodePreliminaryDecoding { + // we need into total 4 elements: + // - 11 bits that encode opcode + variant + addressing mode + etc + // - 2x1 unused bits + // - conditional 3bit integer (constrainted later by lookup table) + + let word_0_bytes = opcode_properties_words[0].decompose_into_bytes(cs); + + let opcode_variant_and_conditional_word = + UInt16::from_le_bytes(cs, [word_0_bytes[0], word_0_bytes[1]]); + + let variant_var = cs.alloc_variable_without_value(); + let unused_bits_vars = cs.alloc_multiple_variables_without_values::<2>(); + let conditionals_var = cs.alloc_variable_without_value(); + + // booleanity constraints + let _unused_bits = unused_bits_vars.map(|el| Boolean::from_variable_checked(cs, el)); + + if ::WitnessConfig::EVALUATE_WITNESS { + let all_outputs = [ + variant_var, + unused_bits_vars[0], + unused_bits_vars[1], + conditionals_var, + ]; + + let value_fn = move |inputs: [F; 1]| { + debug_assert_eq!(VARIANT_AND_CONDITION_ENCODING_BITS, 16); + + let variant_and_condition = >::cast_from_source(inputs[0]); + let variant_and_condition = variant_and_condition as u64; + let variant_and_condition = variant_and_condition & VARIANT_AND_CONDITION_ENCODING_MASK; + + let variant = variant_and_condition & VARIANT_ENCODING_MASK; + + let unused_bits = + (variant_and_condition >> OPCODES_TABLE_WIDTH) & bit_width_to_bitmask(UNUSED_GAP); + let unused_bit_0 = unused_bits & 1 > 0; + let unused_bit_1 = (unused_bits >> 1) & 1 > 0; + let condition = variant_and_condition >> CONDITIONAL_BITS_SHIFT; + + if crate::config::CIRCUIT_VERSOBE { + let opcode = zkevm_opcode_defs::OPCODES_TABLE[variant as usize]; + dbg!(opcode); + let condition = zkevm_opcode_defs::condition::Condition::materialize_variant( + condition as usize, + ); + dbg!(condition); + } + + [ + F::from_u64_unchecked(variant), + F::from_u64_unchecked(unused_bit_0 as u64), + F::from_u64_unchecked(unused_bit_1 as u64), + F::from_u64_unchecked(condition), + ] + }; + + let dependencies = [opcode_variant_and_conditional_word.get_variable().into()]; + + cs.set_values_with_dependencies( + &dependencies, + &Place::from_variables(all_outputs), + value_fn, + ); + } + + // enforce our claimed decomposition + Num::enforce_zero_for_linear_combination( + cs, + &[ + (variant_var, F::ONE), + (unused_bits_vars[0], F::SHIFTS[OPCODES_TABLE_WIDTH]), + (unused_bits_vars[1], F::SHIFTS[OPCODES_TABLE_WIDTH + 1]), + (conditionals_var, F::SHIFTS[OPCODES_TABLE_WIDTH + 2]), + ( + opcode_variant_and_conditional_word.get_variable(), + F::MINUS_ONE, + ), + ], + ); + + // range check parts by feeding into the tables + + use crate::tables::opcodes_decoding::VMOpcodeDecodingTable; + let table_id = cs + .get_table_id_for_marker::() + .expect("table must exist"); + + // bit check variant and spread it + let values = cs.perform_lookup::<1, 2>(table_id, &[variant_var]); + // by our definition of the table we check the prices to fit into u32 + let opcode_cost = unsafe { UInt32::from_variable_unchecked(values[0]) }; + let opcode_properties = Num::from_variable(values[1]); + + // condition is checked to be 3 bits through resolution here + use crate::tables::conditional::VMConditionalResolutionTable; + let table_id = cs + .get_table_id_for_marker::() + .expect("table must exist"); + + let values = + cs.perform_lookup::<2, 1>(table_id, &[conditionals_var, encoded_flags.get_variable()]); + let resolution = unsafe { Boolean::from_variable_unchecked(values[0]) }; + + // decode the end + let src_regs_encoding = word_0_bytes[2]; + let dst_regs_encoding = word_0_bytes[3]; + + let word_1_bytes = opcode_properties_words[1].decompose_into_bytes(cs); + + let imm0 = UInt16::from_le_bytes(cs, [word_1_bytes[0], word_1_bytes[1]]); + let imm1 = UInt16::from_le_bytes(cs, [word_1_bytes[2], word_1_bytes[3]]); + + let props = OpcodePreliminaryDecoding { + condition: resolution, + opcode_boolean_spread_data: opcode_properties, + src_regs_encoding, + dst_regs_encoding, + imm0, + imm1, + ergs_cost: opcode_cost, + }; + + props +} + +fn split_register_encoding_byte>( + cs: &mut CS, + encoding: UInt8, +) -> [Num; 2] { + // we only need one FMA gate, so we write the routine manually + + let outputs = cs.alloc_multiple_variables_without_values::<2>(); + + if ::WitnessConfig::EVALUATE_WITNESS { + const MASK: u64 = (1u64 << REGISTER_ENCODING_BITS) - 1; + let value_fn = move |inputs: [F; 1]| { + let mut as_u64 = inputs[0].as_u64(); + let src0 = as_u64 & MASK; + as_u64 >>= REGISTER_ENCODING_BITS; + debug_assert!(as_u64 <= MASK); + let src1 = as_u64; + + [F::from_u64_unchecked(src0), F::from_u64_unchecked(src1)] + }; + + let dependencies = Place::from_variables([encoding.get_variable()]); + + cs.set_values_with_dependencies(&dependencies, &Place::from_variables(outputs), value_fn); + } + + if ::SetupConfig::KEEP_SETUP { + use boojum::cs::gates::FmaGateInBaseFieldWithoutConstant; + + if cs.gate_is_allowed::>() { + let one = cs.allocate_constant(F::ONE); + let mut gate = FmaGateInBaseFieldWithoutConstant::empty(); + gate.quadratic_part = (one, outputs[0]); + gate.linear_part = outputs[1]; + use boojum::cs::gates::fma_gate_without_constant::FmaGateInBaseWithoutConstantParams; + gate.params = FmaGateInBaseWithoutConstantParams { + coeff_for_quadtaric_part: F::ONE, + linear_term_coeff: F::from_u64_unchecked(1u64 << REGISTER_ENCODING_BITS), + }; + gate.rhs_part = encoding.get_variable(); + + gate.add_to_cs(cs); + } else { + unimplemented!() + } + } + + outputs.map(|el| Num::from_variable(el)) +} diff --git a/crates/zkevm_circuits/src/main_vm/loading.rs b/crates/zkevm_circuits/src/main_vm/loading.rs new file mode 100644 index 0000000..7b4d0cb --- /dev/null +++ b/crates/zkevm_circuits/src/main_vm/loading.rs @@ -0,0 +1,226 @@ +use super::*; +use crate::base_structures::register::VMRegister; +use crate::base_structures::vm_state::callstack::Callstack; +use crate::base_structures::vm_state::callstack::FullExecutionContext; +use crate::base_structures::vm_state::{ + VmLocalState, FULL_SPONGE_QUEUE_STATE_WIDTH, QUEUE_STATE_WIDTH, +}; +use boojum::algebraic_props::round_function::AlgebraicRoundFunction; +use boojum::gadgets::traits::round_function::CircuitRoundFunction; +use boojum::gadgets::u160::UInt160; +use boojum::gadgets::u256::{decompose_u256_as_u32x8, UInt256}; + +pub fn initial_bootloader_state< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, +>( + cs: &mut CS, + memory_queue_initial_length: UInt32, + memory_queue_initial_tail: [Num; FULL_SPONGE_QUEUE_STATE_WIDTH], + decommitment_queue_initial_length: UInt32, + decommitment_queue_initial_tail: [Num; FULL_SPONGE_QUEUE_STATE_WIDTH], + initial_rollback_queue_value: [Num; QUEUE_STATE_WIDTH], + _round_function: &R, +) -> VmLocalState { + // first create the context + let mut ctx = FullExecutionContext::uninitialized(cs); + + ctx.saved_context.base_page = + UInt32::allocated_constant(cs, zkevm_opcode_defs::BOOTLOADER_BASE_PAGE); + ctx.saved_context.code_page = + UInt32::allocated_constant(cs, zkevm_opcode_defs::BOOTLOADER_CODE_PAGE); + + let zero_num = Num::zero(cs); + let zero_u32 = UInt32::zero(cs); + let zero_u16 = UInt16::zero(cs); + let _boolean_false = Boolean::allocated_constant(cs, false); + let boolean_true = Boolean::allocated_constant(cs, true); + + ctx.saved_context.pc = zero_u16; + ctx.saved_context.exception_handler_loc = UInt16::allocated_constant( + cs, + zkevm_opcode_defs::system_params::INITIAL_FRAME_FORMAL_EH_LOCATION, + ); + ctx.saved_context.ergs_remaining = + UInt32::allocated_constant(cs, zkevm_opcode_defs::system_params::VM_INITIAL_FRAME_ERGS); + + let formal_bootloader_address_low = UInt32::allocated_constant( + cs, + zkevm_opcode_defs::system_params::BOOTLOADER_FORMAL_ADDRESS_LOW as u32, + ); + + let formal_bootloader_address = UInt160 { + inner: [ + formal_bootloader_address_low, + zero_u32, + zero_u32, + zero_u32, + zero_u32, + ], + }; + + ctx.saved_context.code_address = formal_bootloader_address; + ctx.saved_context.this = formal_bootloader_address; + ctx.saved_context.caller = UInt160::zero(cs); // is called from nowhere + + // circuit specific bit + ctx.saved_context.reverted_queue_tail = initial_rollback_queue_value; + ctx.saved_context.reverted_queue_head = ctx.saved_context.reverted_queue_tail; + + // mark as kernel + ctx.saved_context.is_kernel_mode = boolean_true; + + // bootloader should not pay for resizes + ctx.saved_context.heap_upper_bound = + UInt32::allocated_constant(cs, zkevm_opcode_defs::system_params::BOOTLOADER_MAX_MEMORY); + ctx.saved_context.aux_heap_upper_bound = + UInt32::allocated_constant(cs, zkevm_opcode_defs::system_params::BOOTLOADER_MAX_MEMORY); + + // now push that to the callstack, manually + + let mut empty_entry = FullExecutionContext::uninitialized(cs); + empty_entry.saved_context.reverted_queue_tail = initial_rollback_queue_value; + empty_entry.saved_context.reverted_queue_head = ctx.saved_context.reverted_queue_tail; + empty_entry.saved_context.is_kernel_mode = boolean_true; + + use boojum::gadgets::traits::encodable::CircuitEncodable; + let empty_entry_encoding = empty_entry.saved_context.encode(cs); // only saved part + + let callstack_empty_state = [zero_num; FULL_SPONGE_QUEUE_STATE_WIDTH]; + + let mut current_state = callstack_empty_state.map(|el| el.get_variable()); + + // absorb by replacement + let round_0_initial = [ + empty_entry_encoding[0], + empty_entry_encoding[1], + empty_entry_encoding[2], + empty_entry_encoding[3], + empty_entry_encoding[4], + empty_entry_encoding[5], + empty_entry_encoding[6], + empty_entry_encoding[7], + current_state[8], + current_state[9], + current_state[10], + current_state[11], + ]; + + let round_0_final = R::compute_round_function(cs, round_0_initial); + + current_state = round_0_final; + + let round_1_initial = [ + empty_entry_encoding[8], + empty_entry_encoding[9], + empty_entry_encoding[10], + empty_entry_encoding[11], + empty_entry_encoding[12], + empty_entry_encoding[13], + empty_entry_encoding[14], + empty_entry_encoding[15], + current_state[8], + current_state[9], + current_state[10], + current_state[11], + ]; + + let round_1_final = R::compute_round_function(cs, round_1_initial); + + current_state = round_1_final; + + let round_2_initial = [ + empty_entry_encoding[16], + empty_entry_encoding[17], + empty_entry_encoding[18], + empty_entry_encoding[19], + empty_entry_encoding[20], + empty_entry_encoding[21], + empty_entry_encoding[22], + empty_entry_encoding[23], + current_state[8], + current_state[9], + current_state[10], + current_state[11], + ]; + + let round_2_final = R::compute_round_function(cs, round_2_initial); + + current_state = round_2_final; + + let round_3_initial = [ + empty_entry_encoding[24], + empty_entry_encoding[25], + empty_entry_encoding[26], + empty_entry_encoding[27], + empty_entry_encoding[28], + empty_entry_encoding[29], + empty_entry_encoding[30], + empty_entry_encoding[31], + current_state[8], + current_state[9], + current_state[10], + current_state[11], + ]; + + let round_3_final = R::compute_round_function(cs, round_3_initial); + + current_state = round_3_final; + + let callstack_initial_state = current_state.map(|el| Num::from_variable(el)); + + let callstack_depth = UInt32::allocated_constant(cs, 1u32); + + let callstack = Callstack { + current_context: ctx, + context_stack_depth: callstack_depth, + stack_sponge_state: callstack_initial_state, + }; + + let mut bootloaded_state = VmLocalState::uninitialized(cs); + // memory + bootloaded_state.memory_queue_length = memory_queue_initial_length; + bootloaded_state.memory_queue_state = memory_queue_initial_tail; + // code decommittments + bootloaded_state.code_decommittment_queue_length = decommitment_queue_initial_length; + bootloaded_state.code_decommittment_queue_state = decommitment_queue_initial_tail; + // rest + bootloaded_state.callstack = callstack; + // timestamp and global counters + bootloaded_state.timestamp = + UInt32::allocated_constant(cs, zkevm_opcode_defs::STARTING_TIMESTAMP); + bootloaded_state.memory_page_counter = + UInt32::allocated_constant(cs, zkevm_opcode_defs::STARTING_BASE_PAGE); + + // we also FORMALLY mark r1 as "pointer" type, even though we will NOT have any calldata + // Nevertheless we put it "formally" to make an empty slice to designated page + + let formal_ptr = zkevm_opcode_defs::FatPointer { + offset: 0, + memory_page: zkevm_opcode_defs::BOOTLOADER_CALLDATA_PAGE, + start: 0, + length: 0, + }; + let formal_ptr_encoding = formal_ptr.to_u256(); + + let decomposition = decompose_u256_as_u32x8(formal_ptr_encoding); + let l0 = UInt32::allocated_constant(cs, decomposition[0]); + let l1 = UInt32::allocated_constant(cs, decomposition[1]); + let l2 = UInt32::allocated_constant(cs, decomposition[2]); + let l3 = UInt32::allocated_constant(cs, decomposition[3]); + + debug_assert_eq!(decomposition[4], 0); + debug_assert_eq!(decomposition[5], 0); + debug_assert_eq!(decomposition[6], 0); + debug_assert_eq!(decomposition[7], 0); + + bootloaded_state.registers[0] = VMRegister { + is_pointer: boolean_true, + value: UInt256 { + inner: [l0, l1, l2, l3, zero_u32, zero_u32, zero_u32, zero_u32], + }, + }; + + bootloaded_state +} diff --git a/crates/zkevm_circuits/src/main_vm/mod.rs b/crates/zkevm_circuits/src/main_vm/mod.rs new file mode 100644 index 0000000..3be2bc2 --- /dev/null +++ b/crates/zkevm_circuits/src/main_vm/mod.rs @@ -0,0 +1,232 @@ +use super::*; + +use boojum::cs::gates::PublicInputGate; +use boojum::cs::traits::cs::ConstraintSystem; +use boojum::cs::{Place, Variable}; +use boojum::gadgets::boolean::Boolean; +use boojum::gadgets::num::Num; +use boojum::gadgets::queue::{QueueState, QueueTailState}; +use boojum::gadgets::traits::castable::WitnessCastable; + +use crate::base_structures::vm_state::VmLocalState; +use boojum::config::*; +use boojum::gadgets::traits::selectable::Selectable; +use boojum::gadgets::u32::UInt32; +use boojum::gadgets::u8::UInt8; +use boojum::{field::SmallField, gadgets::u16::UInt16}; + +pub mod cycle; +pub mod decoded_opcode; +pub mod loading; +pub mod opcode_bitmask; +pub mod opcodes; +pub mod pre_state; +pub mod register_input_view; +pub mod state_diffs; +pub mod utils; +pub mod witness_oracle; + +use crate::base_structures::decommit_query::DecommitQuery; +use crate::base_structures::log_query::LogQuery; +use crate::base_structures::memory_query::MemoryQuery; +use crate::base_structures::vm_state::saved_context::ExecutionContextRecord; +use crate::base_structures::vm_state::{FULL_SPONGE_QUEUE_STATE_WIDTH, QUEUE_STATE_WIDTH}; +use crate::fsm_input_output::circuit_inputs::main_vm::VmCircuitWitness; +use crate::fsm_input_output::circuit_inputs::main_vm::*; +use crate::fsm_input_output::circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH; +use crate::fsm_input_output::commit_variable_length_encodable_item; +use crate::fsm_input_output::ClosedFormInputCompactForm; +use crate::main_vm::cycle::vm_cycle; +use crate::main_vm::loading::initial_bootloader_state; +use crate::main_vm::witness_oracle::{SynchronizedWitnessOracle, WitnessOracle}; +use boojum::algebraic_props::round_function::AlgebraicRoundFunction; +use boojum::gadgets::traits::allocatable::{CSAllocatableExt, CSPlaceholder}; +use boojum::gadgets::traits::round_function::CircuitRoundFunction; +use boojum::gadgets::traits::witnessable::WitnessHookable; + +pub fn main_vm_entry_point< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, + W: WitnessOracle, +>( + cs: &mut CS, + witness: VmCircuitWitness, + round_function: &R, + limit: usize, +) -> [Num; INPUT_OUTPUT_COMMITMENT_LENGTH] +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + let VmCircuitWitness { + closed_form_input, + witness_oracle, + } = witness; + + let mut structured_input = + VmCircuitInputOutput::alloc_ignoring_outputs(cs, closed_form_input.clone()); + + let start_flag = structured_input.start_flag; + let observable_input = structured_input.observable_input.clone(); + let hidden_fsm_input = structured_input.hidden_fsm_input.clone(); + + let VmInputData { + rollback_queue_tail_for_block, + memory_queue_initial_state, + decommitment_queue_initial_state, + per_block_context, + } = observable_input; + + // we also need to create the state that reflects the "initial" state for boot process + + let bootloader_state = initial_bootloader_state( + cs, + memory_queue_initial_state.length, + memory_queue_initial_state.tail, + decommitment_queue_initial_state.length, + decommitment_queue_initial_state.tail, + rollback_queue_tail_for_block, + round_function, + ); + + // or may be it's from FSM, so select + let mut state = + VmLocalState::conditionally_select(cs, start_flag, &bootloader_state, &hidden_fsm_input); + + let synchronized_oracle = SynchronizedWitnessOracle::new(witness_oracle); + + // we run `limit` of "normal" cycles + for _cycle_idx in 0..limit { + state = vm_cycle( + cs, + state, + &synchronized_oracle, + &per_block_context, + round_function, + ); + } + + // here we have too large state to run self-tests, so we will compare it only against the full committments + + // check for "done" flag + let done = state.callstack.is_empty(cs); + + // we can not fail exiting, so check for our convention that pc == 0 on success, and != 0 in failure + let bootloader_exited_successfully = + state.callstack.current_context.saved_context.pc.is_zero(cs); + + // bootloader must exist succesfully + bootloader_exited_successfully.conditionally_enforce_true(cs, done); + + structured_input.completion_flag = done; + + let final_state = state; + + let mut observable_output = VmOutputData::placeholder(cs); + + let full_empty_state_large = QueueState::::empty(cs); + + // select tails + + // memory + + let memory_queue_current_tail = QueueTailState { + tail: final_state.memory_queue_state, + length: final_state.memory_queue_length, + }; + let memory_queue_final_tail = QueueTailState::conditionally_select( + cs, + structured_input.completion_flag, + &memory_queue_current_tail, + &full_empty_state_large.tail, + ); + + // code decommit + let decommitment_queue_current_tail = QueueTailState { + tail: final_state.code_decommittment_queue_state, + length: final_state.code_decommittment_queue_length, + }; + let decommitment_queue_final_tail = QueueTailState::conditionally_select( + cs, + structured_input.completion_flag, + &decommitment_queue_current_tail, + &full_empty_state_large.tail, + ); + + // log. We IGNORE rollbacks that never happened obviously + let final_log_state_tail = final_state.callstack.current_context.log_queue_forward_tail; + let final_log_state_length = final_state + .callstack + .current_context + .log_queue_forward_part_length; + + // but we CAN still check that it's potentially mergeable, basically to check that witness generation is good + for (a, b) in final_log_state_tail.iter().zip( + final_state + .callstack + .current_context + .saved_context + .reverted_queue_head + .iter(), + ) { + Num::conditionally_enforce_equal(cs, structured_input.completion_flag, a, b); + } + + let full_empty_state_small = QueueState::::empty(cs); + + let log_queue_current_tail = QueueTailState { + tail: final_log_state_tail, + length: final_log_state_length, + }; + let log_queue_final_tail = QueueTailState::conditionally_select( + cs, + structured_input.completion_flag, + &log_queue_current_tail, + &full_empty_state_small.tail, + ); + + // set everything + + observable_output.log_queue_final_state.tail = log_queue_final_tail; + observable_output.memory_queue_final_state.tail = memory_queue_final_tail; + observable_output.decommitment_queue_final_state.tail = decommitment_queue_final_tail; + + structured_input.observable_output = observable_output; + structured_input.hidden_fsm_output = final_state; + + // if we generate witness then we can self-check + if ::WitnessConfig::EVALUATE_WITNESS { + let value_fn = move |_ins: [F; 1]| { + let mut guard = synchronized_oracle.inner.write().expect("not poisoned"); + let consumed_witness = std::mem::replace(&mut *guard, W::default()); + drop(guard); + + consumed_witness.at_completion(); + + [] + }; + + cs.set_values_with_dependencies( + &[structured_input.completion_flag.get_variable().into()], + &[], + value_fn, + ); + } + + structured_input.hook_compare_witness(&*cs, &closed_form_input); + + let compact_form = + ClosedFormInputCompactForm::from_full_form(cs, &structured_input, round_function); + + let input_commitment: [_; INPUT_OUTPUT_COMMITMENT_LENGTH] = + commit_variable_length_encodable_item(cs, &compact_form, round_function); + for el in input_commitment.iter() { + let gate = PublicInputGate::new(el.get_variable()); + gate.add_to_cs(cs); + } + + input_commitment +} diff --git a/crates/zkevm_circuits/src/main_vm/opcode_bitmask.rs b/crates/zkevm_circuits/src/main_vm/opcode_bitmask.rs new file mode 100644 index 0000000..f0398f3 --- /dev/null +++ b/crates/zkevm_circuits/src/main_vm/opcode_bitmask.rs @@ -0,0 +1,130 @@ +use super::*; +use boojum::field::SmallField; +use boojum::gadgets::boolean::Boolean; +use boojum::gadgets::traits::allocatable::CSAllocatable; +use boojum::gadgets::u16::UInt16; +use boojum::serde_utils::BigArraySerde; +use cs_derive::*; + +use zkevm_opcode_defs::{ + ISAVersion, ImmMemHandlerFlags, OPCODE_INPUT_VARIANT_FLAGS, OPCODE_OUTPUT_VARIANT_FLAGS, + OPCODE_TYPE_BITS, TOTAL_AUX_BITS, +}; + +// opcode defs only provide runtime-computeable variable, so we have to pin ISA version and assert + +pub const SUPPORTED_ISA_VERSION: ISAVersion = ISAVersion(1); + +const _: () = if SUPPORTED_ISA_VERSION.0 != zkevm_opcode_defs::DEFAULT_ISA_VERSION.0 { + panic!() +} else { + () +}; + +pub(crate) const OPCODE_VARIANT_BITS: usize = 10; +pub(crate) const OPCODE_FLAGS_BITS: usize = 2; +pub(crate) const TOTAL_OPCODE_MEANINGFULL_DESCRIPTION_BITS: usize = 38; +pub(crate) const TOTAL_OPCODE_DESCRIPTION_BITS_FLATTENED: usize = 48; +pub(crate) const TOTAL_OPCODE_DESCRIPTION_AND_AUX_BITS: usize = + TOTAL_OPCODE_DESCRIPTION_BITS_FLATTENED + TOTAL_AUX_BITS; + +/// We hide all the source selection and updating in preprocessing, +/// so we only need imms and some variant properties +#[derive(Derivative)] +#[derivative(Debug)] +pub struct UsedOpcode { + pub properties_bitmask: OpcodeBitmask, + pub imm0: UInt16, + pub imm1: UInt16, +} + +#[derive(Derivative, CSAllocatable, WitnessHookable)] +#[derivative(Debug)] +pub struct OpcodeBitmask { + pub opcode_type_booleans: [Boolean; OPCODE_TYPE_BITS], + pub opcode_variant_booleans: [Boolean; OPCODE_VARIANT_BITS], + pub flag_booleans: [Boolean; OPCODE_FLAGS_BITS], + pub input_variant_booleans: [Boolean; OPCODE_INPUT_VARIANT_FLAGS], + pub output_variant_booleans: [Boolean; OPCODE_OUTPUT_VARIANT_FLAGS], +} + +use zkevm_opcode_defs::Opcode; + +impl OpcodeBitmask { + pub fn boolean_for_opcode(&self, opcode: Opcode) -> Boolean { + let opcode_idx = opcode.variant_idx(); + self.opcode_type_booleans[opcode_idx] + } + + pub fn boolean_for_variant(&self, opcode: Opcode) -> Boolean { + let variant_idx = opcode.materialize_subvariant_idx(); + self.opcode_variant_booleans[variant_idx] + } + + pub fn boolean_for_src_mem_access(&self, access_type: ImmMemHandlerFlags) -> Boolean { + let variant_idx = access_type.variant_index(); + self.input_variant_booleans[variant_idx] + } + + pub fn boolean_for_dst_mem_access(&self, access_type: ImmMemHandlerFlags) -> Boolean { + assert!(access_type.is_allowed_for_dst()); + let variant_idx = access_type.variant_index(); + self.output_variant_booleans[variant_idx] + } + + pub fn from_full_mask(mask: [Boolean; TOTAL_OPCODE_MEANINGFULL_DESCRIPTION_BITS]) -> Self { + // assert to not mismatch alignments + debug_assert_eq!( + OPCODE_VARIANT_BITS, + zkevm_opcode_defs::max_num_variants_for_version(SUPPORTED_ISA_VERSION) + ); + debug_assert_eq!( + OPCODE_FLAGS_BITS, + zkevm_opcode_defs::max_num_flags_for_version(SUPPORTED_ISA_VERSION) + ); + debug_assert_eq!( + TOTAL_OPCODE_DESCRIPTION_BITS_FLATTENED, + zkevm_opcode_defs::total_description_bits_rounded_for_version(SUPPORTED_ISA_VERSION) + ); + debug_assert_eq!( + TOTAL_OPCODE_MEANINGFULL_DESCRIPTION_BITS, + zkevm_opcode_defs::total_description_bits_for_version(SUPPORTED_ISA_VERSION) + ); + + let mut offset = 0; + let opcode_type_booleans: [Boolean; OPCODE_TYPE_BITS] = mask + [offset..(offset + OPCODE_TYPE_BITS)] + .try_into() + .unwrap(); + offset += OPCODE_TYPE_BITS; + let opcode_variant_booleans: [Boolean; OPCODE_VARIANT_BITS] = mask + [offset..(offset + OPCODE_VARIANT_BITS)] + .try_into() + .unwrap(); + offset += OPCODE_VARIANT_BITS; + let flag_booleans: [Boolean; OPCODE_FLAGS_BITS] = mask + [offset..(offset + OPCODE_FLAGS_BITS)] + .try_into() + .unwrap(); + offset += OPCODE_FLAGS_BITS; + let input_variant_booleans: [Boolean; OPCODE_INPUT_VARIANT_FLAGS] = mask + [offset..(offset + OPCODE_INPUT_VARIANT_FLAGS)] + .try_into() + .unwrap(); + offset += OPCODE_INPUT_VARIANT_FLAGS; + let output_variant_booleans: [Boolean; OPCODE_OUTPUT_VARIANT_FLAGS] = mask + [offset..(offset + OPCODE_OUTPUT_VARIANT_FLAGS)] + .try_into() + .unwrap(); + offset += OPCODE_OUTPUT_VARIANT_FLAGS; + debug_assert_eq!(offset, TOTAL_OPCODE_MEANINGFULL_DESCRIPTION_BITS); + + Self { + opcode_type_booleans, + opcode_variant_booleans, + flag_booleans, + input_variant_booleans, + output_variant_booleans, + } + } +} diff --git a/crates/zkevm_circuits/src/main_vm/opcodes/add_sub.rs b/crates/zkevm_circuits/src/main_vm/opcodes/add_sub.rs new file mode 100644 index 0000000..4f745f9 --- /dev/null +++ b/crates/zkevm_circuits/src/main_vm/opcodes/add_sub.rs @@ -0,0 +1,282 @@ +use arrayvec::ArrayVec; + +use crate::base_structures::{register::VMRegister, vm_state::ArithmeticFlagsPort}; +use boojum::gadgets::{traits::castable::WitnessCastable, u256::UInt256}; + +use super::*; + +pub(crate) fn apply_add_sub>( + cs: &mut CS, + _draft_vm_state: &VmLocalState, + common_opcode_state: &CommonOpcodeState, + _opcode_carry_parts: &AfterDecodingCarryParts, + diffs_accumulator: &mut StateDiffsAccumulator, +) { + // main point of merging add/sub is to enforce single add/sub relation, that doesn't leak into any + // other opcodes + + let (addition_result_unchecked, of_unchecked) = allocate_addition_result_unchecked( + cs, + &common_opcode_state.src0_view.u32x8_view, + &common_opcode_state.src1_view.u32x8_view, + ); + + let (subtraction_result_unchecked, uf_unchecked) = allocate_subtraction_result_unchecked( + cs, + &common_opcode_state.src0_view.u32x8_view, + &common_opcode_state.src1_view.u32x8_view, + ); + + const ADD_OPCODE: zkevm_opcode_defs::Opcode = Opcode::Add(AddOpcode::Add); + const SUB_OPCODE: zkevm_opcode_defs::Opcode = Opcode::Sub(SubOpcode::Sub); + + // now we need to properly select and enforce + let apply_add = common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_opcode(ADD_OPCODE); + let apply_sub = common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_opcode(SUB_OPCODE); + + if crate::config::CIRCUIT_VERSOBE { + if (apply_add.witness_hook(&*cs))().unwrap_or(false) { + println!("Applying ADD"); + } + if (apply_sub.witness_hook(&*cs))().unwrap_or(false) { + println!("Applying SUB"); + } + } + + let result = UInt32::::parallel_select( + cs, + apply_add, + &addition_result_unchecked, + &subtraction_result_unchecked, + ); + + // even though we will select for range check in final state diffs application, we already need a selection + // over result here, so we just add one conditional check + let conditional_range_checks = result; + + // now we need to enforce relation + // we enforce a + b = c + 2^N * of, + // so if we subtract, then we need to swap some staff + + // relation is a + b == c + of * 2^N, + // but we compute d - e + 2^N * borrow = f, + // so e + f = d + of * 2^N + + // Naive options + // let add_relation = AddSubRelation { + // a: common_opcode_state.src0_view.u32x8_view, + // b: common_opcode_state.src1_view.u32x8_view, + // c: addition_result_unchecked, + // of + // }; + + // let sub_relation = AddSubRelation { + // a: common_opcode_state.src1_view.u32x8_view, + // b: subtraction_result_unchecked, + // c: common_opcode_state.src0_view.u32x8_view, + // of: uf, + // }; + + // Instead we select non-common part, using the fact + // that it's summetric over a/b + + let new_a = common_opcode_state.src1_view.u32x8_view; + + let new_b = UInt32::::parallel_select( + cs, + apply_add, + &common_opcode_state.src0_view.u32x8_view, + &subtraction_result_unchecked, + ); + + let new_c = UInt32::::parallel_select( + cs, + apply_add, + &addition_result_unchecked, + &common_opcode_state.src0_view.u32x8_view, + ); + + let new_of = Boolean::conditionally_select(cs, apply_add, &of_unchecked, &uf_unchecked); + + let relation = AddSubRelation { + a: new_a, + b: new_b, + c: new_c, + of: new_of, + }; + + // now we need to check for zero and output + let limb_is_zero = result.map(|el| el.is_zero(cs)); + let result_is_zero = Boolean::multi_and(cs, &limb_is_zero); + + // gt = !of & !zero, so it's !(of || zero) + let gt = Boolean::multi_or(cs, &[new_of, result_is_zero]).negated(cs); + + let update_flags = common_opcode_state + .decoded_opcode + .properties_bits + .flag_booleans[SET_FLAGS_FLAG_IDX]; + + let candidate_flags = ArithmeticFlagsPort { + overflow_or_less_than: new_of, + equal: result_is_zero, + greater_than: gt, + }; + + // we only update flags and dst0 + + let apply_any = Boolean::multi_or(cs, &[apply_add, apply_sub]); + let boolean_false = Boolean::allocated_constant(cs, false); + let dst0 = VMRegister { + is_pointer: boolean_false, + value: UInt256 { inner: result }, + }; + + let can_write_into_memory = ADD_OPCODE.can_write_dst0_into_memory(SUPPORTED_ISA_VERSION); + debug_assert_eq!( + can_write_into_memory, + SUB_OPCODE.can_write_dst0_into_memory(SUPPORTED_ISA_VERSION) + ); + + let update_flags = Boolean::multi_and(cs, &[apply_any, update_flags]); + + diffs_accumulator + .dst_0_values + .push((can_write_into_memory, apply_any, dst0)); + diffs_accumulator + .flags + .push((update_flags, candidate_flags)); + + // add range check request + diffs_accumulator + .u32_conditional_range_checks + .push((apply_any, conditional_range_checks)); + + let mut add_sub_relations = ArrayVec::new(); + add_sub_relations.push(relation); + diffs_accumulator + .add_sub_relations + .push((apply_any, add_sub_relations)); +} + +pub fn allocate_addition_result_unchecked>( + cs: &mut CS, + a: &[UInt32; 8], + b: &[UInt32; 8], +) -> ([UInt32; 8], Boolean) { + let limbs = cs.alloc_multiple_variables_without_values::<8>(); + let of = cs.alloc_variable_without_value(); + + if ::WitnessConfig::EVALUATE_WITNESS { + let value_fn = move |inputs: [F; 16]| { + let mut of = false; + let mut result = [F::ZERO; 9]; + for (idx, (a, b)) in inputs[..8].iter().zip(inputs[8..].iter()).enumerate() { + let a = >::cast_from_source(*a); + let b = >::cast_from_source(*b); + let (c, new_of_0) = a.overflowing_add(b); + let (c, new_of_1) = c.overflowing_add(of as u32); + + of = new_of_0 || new_of_1; + + result[idx] = F::from_u64_unchecked(c as u64); + } + + result[8] = F::from_u64_unchecked(of as u64); + + result + }; + + let dependencies = Place::from_variables([ + a[0].get_variable(), + a[1].get_variable(), + a[2].get_variable(), + a[3].get_variable(), + a[4].get_variable(), + a[5].get_variable(), + a[6].get_variable(), + a[7].get_variable(), + b[0].get_variable(), + b[1].get_variable(), + b[2].get_variable(), + b[3].get_variable(), + b[4].get_variable(), + b[5].get_variable(), + b[6].get_variable(), + b[7].get_variable(), + ]); + let outputs = Place::from_variables([ + limbs[0], limbs[1], limbs[2], limbs[3], limbs[4], limbs[5], limbs[6], limbs[7], of, + ]); + cs.set_values_with_dependencies(&dependencies, &outputs, value_fn); + } + + let limbs = limbs.map(|el| unsafe { UInt32::from_variable_unchecked(el) }); + let of = unsafe { Boolean::from_variable_unchecked(of) }; + + (limbs, of) +} + +pub fn allocate_subtraction_result_unchecked>( + cs: &mut CS, + a: &[UInt32; 8], + b: &[UInt32; 8], +) -> ([UInt32; 8], Boolean) { + let limbs = cs.alloc_multiple_variables_without_values::<8>(); + let of = cs.alloc_variable_without_value(); + + if ::WitnessConfig::EVALUATE_WITNESS { + let value_fn = move |inputs: [F; 16]| { + let mut uf = false; + let mut result = [F::ZERO; 9]; + for (idx, (a, b)) in inputs[..8].iter().zip(inputs[8..].iter()).enumerate() { + let a = >::cast_from_source(*a); + let b = >::cast_from_source(*b); + let (c, new_uf_0) = (a).overflowing_sub(b); + let (c, new_uf_1) = c.overflowing_sub(uf as u32); + + uf = new_uf_0 || new_uf_1; + + result[idx] = F::from_u64_unchecked(c as u64); + } + + result[8] = F::from_u64_unchecked(uf as u64); + + result + }; + + let dependencies = Place::from_variables([ + a[0].get_variable(), + a[1].get_variable(), + a[2].get_variable(), + a[3].get_variable(), + a[4].get_variable(), + a[5].get_variable(), + a[6].get_variable(), + a[7].get_variable(), + b[0].get_variable(), + b[1].get_variable(), + b[2].get_variable(), + b[3].get_variable(), + b[4].get_variable(), + b[5].get_variable(), + b[6].get_variable(), + b[7].get_variable(), + ]); + let outputs = Place::from_variables([ + limbs[0], limbs[1], limbs[2], limbs[3], limbs[4], limbs[5], limbs[6], limbs[7], of, + ]); + cs.set_values_with_dependencies(&dependencies, &outputs, value_fn); + } + + let limbs = limbs.map(|el| unsafe { UInt32::from_variable_unchecked(el) }); + let of = unsafe { Boolean::from_variable_unchecked(of) }; + + (limbs, of) +} diff --git a/crates/zkevm_circuits/src/main_vm/opcodes/binop.rs b/crates/zkevm_circuits/src/main_vm/opcodes/binop.rs new file mode 100644 index 0000000..b6012bf --- /dev/null +++ b/crates/zkevm_circuits/src/main_vm/opcodes/binop.rs @@ -0,0 +1,244 @@ +use reduction_by_powers_gate::ReductionByPowersGate; + +use boojum::{ + cs::gates::{ + reduction_by_powers_gate, ConstantAllocatableCS, ReductionGate, ReductionGateParams, + }, + gadgets::u256::UInt256, +}; + +use crate::base_structures::{register::VMRegister, vm_state::ArithmeticFlagsPort}; + +use super::*; + +pub(crate) fn apply_binop>( + cs: &mut CS, + _draft_vm_state: &VmLocalState, + common_opcode_state: &CommonOpcodeState, + _opcode_carry_parts: &AfterDecodingCarryParts, + diffs_accumulator: &mut StateDiffsAccumulator, +) { + const AND_OPCODE: zkevm_opcode_defs::Opcode = + zkevm_opcode_defs::Opcode::Binop(zkevm_opcode_defs::definitions::binop::BinopOpcode::And); + const OR_OPCODE: zkevm_opcode_defs::Opcode = + zkevm_opcode_defs::Opcode::Binop(zkevm_opcode_defs::definitions::binop::BinopOpcode::Or); + const XOR_OPCODE: zkevm_opcode_defs::Opcode = + zkevm_opcode_defs::Opcode::Binop(zkevm_opcode_defs::definitions::binop::BinopOpcode::Xor); + + let should_apply = common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_opcode(AND_OPCODE); + + let should_set_flags = common_opcode_state + .decoded_opcode + .properties_bits + .flag_booleans[SET_FLAGS_FLAG_IDX]; + + let is_and = common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(AND_OPCODE); + let is_or = common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(OR_OPCODE); + let _is_xor = common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(XOR_OPCODE); + // main point of merging add/sub is to enforce single add/sub relation, that doesn't leak into any + // other opcodes + + if crate::config::CIRCUIT_VERSOBE { + if should_apply.witness_hook(&*cs)().unwrap_or(false) { + println!("Applying BINOP"); + if is_and.witness_hook(&*cs)().unwrap_or(false) { + println!("BINOP AND"); + } + if is_or.witness_hook(&*cs)().unwrap_or(false) { + println!("BINOP OR"); + } + if _is_xor.witness_hook(&*cs)().unwrap_or(false) { + println!("BINOP XOR"); + } + } + } + + let (and_result, or_result, xor_result) = get_binop_subresults( + cs, + &common_opcode_state.src0_view.u8x32_view, + &common_opcode_state.src1_view.u8x32_view, + ); + + // now we need to select, so we first reduce, and then select + + let mut and_chunks = common_opcode_state.src0_view.u32x8_view; + let mut or_chunks = common_opcode_state.src0_view.u32x8_view; + let mut xor_chunks = common_opcode_state.src0_view.u32x8_view; + + for (dst, src) in [&mut and_chunks, &mut or_chunks, &mut xor_chunks] + .into_iter() + .zip([and_result, or_result, xor_result].into_iter()) + { + for (dst, src) in dst.iter_mut().zip(src.array_chunks::<4>()) { + *dst = UInt32::from_le_bytes(cs, *src); + } + } + + // now select + + let mut result = UInt32::parallel_select(cs, is_and, &and_chunks, &xor_chunks); + result = UInt32::parallel_select(cs, is_or, &or_chunks, &result); + + let limb_is_zero = result.map(|el| el.is_zero(cs)); + let result_is_zero = Boolean::multi_and(cs, &limb_is_zero); + + let constant_false = Boolean::allocated_constant(cs, false); + + let candidate_flags = ArithmeticFlagsPort { + overflow_or_less_than: constant_false, + equal: result_is_zero, + greater_than: constant_false, + }; + + // we only update flags and dst0 + + let dst0 = VMRegister { + is_pointer: Boolean::allocated_constant(cs, false), + value: UInt256 { inner: result }, + }; + let can_write_into_memory = AND_OPCODE.can_write_dst0_into_memory(SUPPORTED_ISA_VERSION); + diffs_accumulator + .dst_0_values + .push((can_write_into_memory, should_apply, dst0)); + + let update_flags = Boolean::multi_and(cs, &[should_apply, should_set_flags]); + + diffs_accumulator + .flags + .push((update_flags, candidate_flags)); +} + +fn get_binop_subresults>( + cs: &mut CS, + a: &[UInt8; 32], + b: &[UInt8; 32], +) -> ([UInt8; 32], [UInt8; 32], [UInt8; 32]) { + // we apply our composite table twice - one to get compound result, and another one as range checks + // and add alreabraic relation + use boojum::gadgets::tables::binop_table::BinopTable; + + let table_id = cs + .get_table_id_for_marker::() + .expect("table must exist"); + + let mut composite_result = [Variable::placeholder(); 32]; + for ((a, b), dst) in a.iter().zip(b.iter()).zip(composite_result.iter_mut()) { + let [result] = cs.perform_lookup::<2, 1>(table_id, &[a.get_variable(), b.get_variable()]); + *dst = result; + } + + // now we need to pull out individual parts. For that we decompose a value + // let value = (xor_result as u64) << 32 | (or_result as u64) << 16 | (and_result as u64); + + let all_results = cs.alloc_multiple_variables_without_values::<96>(); + + if ::WitnessConfig::EVALUATE_WITNESS { + let value_fn = move |inputs: [F; 32]| { + let mut results = [F::ZERO; 96]; + + const MASK: u64 = (1u64 << 8) - 1; + + for (src, dst) in inputs.iter().zip(results.array_chunks_mut::<3>()) { + let mut src = src.as_u64_reduced(); + let and_result = src & MASK; + src >>= 16; + let or_result = src & MASK; + src >>= 16; + let xor_result = src & MASK; + + *dst = [ + F::from_u64_unchecked(and_result), + F::from_u64_unchecked(or_result), + F::from_u64_unchecked(xor_result), + ] + } + + results + }; + + let dependencies = Place::from_variables(composite_result); + let outputs = Place::from_variables(all_results); + cs.set_values_with_dependencies(&dependencies, &outputs, value_fn); + } + + // lookup more, but this time using a table as a range check for all the and/or/xor chunks + for source_set in all_results.array_chunks::<2>() { + // value is irrelevant, it's just a range check + let _: [Variable; 1] = cs.perform_lookup::<2, 1>(table_id, &[source_set[0], source_set[1]]); + } + + let zero_var = cs.allocate_constant(F::ZERO); + + debug_assert!(F::CAPACITY_BITS >= 56); + + if ::SetupConfig::KEEP_SETUP { + // enforce. Note that there are no new variables here + for (src, decomposition) in composite_result.iter().zip(all_results.array_chunks::<3>()) { + if cs.gate_is_allowed::>() { + let mut gate = ReductionGate::::empty(); + gate.params = ReductionGateParams { + reduction_constants: [F::SHIFTS[0], F::SHIFTS[16], F::SHIFTS[32], F::ZERO], + }; + gate.reduction_result = *src; + gate.terms = [ + decomposition[0], + decomposition[1], + decomposition[2], + zero_var, + ]; + + gate.add_to_cs(cs); + } else if cs.gate_is_allowed::>() { + let mut gate = ReductionByPowersGate::::empty(); + use crate::main_vm::opcodes::binop::reduction_by_powers_gate::ReductionByPowersGateParams; + gate.params = ReductionByPowersGateParams { + reduction_constant: F::from_u64_unchecked(1u64 << 16), + }; + gate.reduction_result = *src; + gate.terms = [ + decomposition[0], + decomposition[1], + decomposition[2], + zero_var, + ]; + + gate.add_to_cs(cs); + } else { + unimplemented!() + } + } + } + + let mut and_results = [Variable::placeholder(); 32]; + let mut or_results = [Variable::placeholder(); 32]; + let mut xor_results = [Variable::placeholder(); 32]; + + for (((and, or), xor), src) in and_results + .iter_mut() + .zip(or_results.iter_mut()) + .zip(xor_results.iter_mut()) + .zip(all_results.array_chunks::<3>()) + { + *and = src[0]; + *or = src[1]; + *xor = src[2]; + } + + let and_results = and_results.map(|el| unsafe { UInt8::from_variable_unchecked(el) }); + let or_results = or_results.map(|el| unsafe { UInt8::from_variable_unchecked(el) }); + let xor_results = xor_results.map(|el| unsafe { UInt8::from_variable_unchecked(el) }); + + (and_results, or_results, xor_results) +} diff --git a/crates/zkevm_circuits/src/main_vm/opcodes/call_ret.rs b/crates/zkevm_circuits/src/main_vm/opcodes/call_ret.rs new file mode 100644 index 0000000..3fb6e5c --- /dev/null +++ b/crates/zkevm_circuits/src/main_vm/opcodes/call_ret.rs @@ -0,0 +1,512 @@ +use boojum::cs::traits::cs::DstBuffer; +use boojum::gadgets::traits::castable::WitnessCastable; + +use crate::base_structures::{ + log_query::LogQuery, vm_state::saved_context::ExecutionContextRecord, +}; + +use super::*; +use crate::base_structures::decommit_query::DecommitQuery; +use crate::base_structures::vm_state::GlobalContext; +use crate::base_structures::vm_state::FULL_SPONGE_QUEUE_STATE_WIDTH; +use crate::main_vm::opcodes::call_ret_impl::*; +use crate::main_vm::state_diffs::MAX_SPONGES_PER_CYCLE; +use crate::main_vm::witness_oracle::SynchronizedWitnessOracle; +use crate::main_vm::witness_oracle::WitnessOracle; +use arrayvec::ArrayVec; +use boojum::algebraic_props::round_function::AlgebraicRoundFunction; +use boojum::gadgets::traits::allocatable::CSAllocatableExt; +use boojum::gadgets::traits::round_function::CircuitRoundFunction; + +// call and ret are merged because their main part is manipulation over callstack, +// and we will keep those functions here + +pub(crate) fn apply_calls_and_ret< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, + W: WitnessOracle, +>( + cs: &mut CS, + draft_vm_state: &VmLocalState, + common_opcode_state: &CommonOpcodeState, + opcode_carry_parts: &AfterDecodingCarryParts, + diffs_accumulator: &mut StateDiffsAccumulator, + witness_oracle: &SynchronizedWitnessOracle, + global_context: &GlobalContext, + round_function: &R, +) where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + let (common_part, far_call_abi, call_ret_forwarding_mode) = + compute_shared_abi_parts(cs, &common_opcode_state.src0_view); + + let near_call_data = callstack_candidate_for_near_call( + cs, + draft_vm_state, + common_opcode_state, + opcode_carry_parts, + witness_oracle, + ); + + let far_call_data = callstack_candidate_for_far_call( + cs, + draft_vm_state, + common_opcode_state, + opcode_carry_parts, + witness_oracle, + global_context, + &common_part, + &far_call_abi, + &call_ret_forwarding_mode, + round_function, + ); + + let ret_data = callstack_candidate_for_ret( + cs, + draft_vm_state, + common_opcode_state, + opcode_carry_parts, + witness_oracle, + &common_part, + &call_ret_forwarding_mode, + ); + + // select callstack that will become current + + let NearCallData { + apply_near_call, + old_context: old_context_for_near_call, + new_context: new_context_for_near_call, + } = near_call_data; + + let FarCallData { + apply_far_call, + old_context: old_context_for_far_call, + new_context: new_context_for_far_call, + new_decommittment_queue_tail, + new_decommittment_queue_len, + new_forward_queue_tail: new_forward_queue_state_for_far_call, + new_forward_queue_len: new_forward_queue_len_for_far_call, + + pending_sponges: pending_sponges_for_far_call, + + specific_registers_updates: specific_registers_updates_for_far_call, + specific_registers_zeroing: specific_registers_zeroing_for_far_call, + remove_ptr_on_specific_registers: remove_ptr_on_specific_registers_for_far_call, + + new_memory_pages_counter, + pending_exception: pending_exception_from_far_call, + } = far_call_data; + + let RetData { + apply_ret, + is_panic: is_ret_panic, + new_context: new_context_for_ret, + originally_popped_context: originally_popped_context_for_ret, + previous_callstack_state: previous_callstack_state_for_ret, + new_forward_queue_tail: new_forward_queue_state_for_ret, + new_forward_queue_len: new_forward_queue_len_for_ret, + did_return_from_far_call, + + specific_registers_updates: specific_registers_updates_for_ret, + specific_registers_zeroing: specific_registers_zeroing_for_ret, + remove_ptr_on_specific_registers: remove_ptr_on_specific_registers_for_ret, + } = ret_data; + + let is_call_like = Boolean::multi_or(cs, &[apply_near_call, apply_far_call]); + let apply_any = Boolean::multi_or(cs, &[is_call_like, apply_ret]); + let is_ret_panic_if_apply = Boolean::multi_and(cs, &[is_ret_panic, apply_ret]); + let pending_exception_if_far_call = + Boolean::multi_and(cs, &[pending_exception_from_far_call, apply_far_call]); + + let current_frame_is_local = draft_vm_state + .callstack + .current_context + .saved_context + .is_local_call; + + let _current_frame_is_global = current_frame_is_local.negated(cs); + + let is_far_return = Boolean::multi_and(cs, &[apply_ret, did_return_from_far_call]); + let reset_context_value = Boolean::multi_or(cs, &[is_far_return, apply_far_call]); + + // we only need select between candidates, and later on we will select on higher level between current and candidate from (near_call/far_call/ret) + + let mut new_callstack_entry = ExecutionContextRecord::conditionally_select( + cs, + apply_far_call, + &new_context_for_far_call, + &new_context_for_near_call, + ); + + new_callstack_entry = ExecutionContextRecord::conditionally_select( + cs, + apply_ret, + &new_context_for_ret, + &new_callstack_entry, + ); + + // this one will be largely no-op + let mut old_callstack_entry = ExecutionContextRecord::conditionally_select( + cs, + apply_far_call, + &old_context_for_far_call, + &old_context_for_near_call, + ); + + old_callstack_entry = ExecutionContextRecord::conditionally_select( + cs, + apply_ret, + &originally_popped_context_for_ret, + &old_callstack_entry, + ); + + // manual implementation of the stack: we either take a old entry and hash along with the saved context for call-like, or one popped in case of ret + + let initial_state_to_use_for_sponge = Num::parallel_select( + cs, + apply_ret, + &previous_callstack_state_for_ret, + &draft_vm_state.callstack.stack_sponge_state, + ); + + // now we simulate absorb. Note that we have already chosen an initial state, + // so we just use initial state and absorb + + let mut current_state = initial_state_to_use_for_sponge.map(|el| el.get_variable()); + use boojum::gadgets::traits::encodable::CircuitEncodable; + + let encoded_execution_record = old_callstack_entry.encode(cs); + + use boojum::gadgets::round_function::simulate_round_function; + + // absorb by replacement + let round_0_initial = [ + encoded_execution_record[0], + encoded_execution_record[1], + encoded_execution_record[2], + encoded_execution_record[3], + encoded_execution_record[4], + encoded_execution_record[5], + encoded_execution_record[6], + encoded_execution_record[7], + current_state[8], + current_state[9], + current_state[10], + current_state[11], + ]; + + let round_0_final = + simulate_round_function::<_, _, 8, 12, 4, R>(cs, round_0_initial, apply_any); + + current_state = round_0_final; + + let round_1_initial = [ + encoded_execution_record[8], + encoded_execution_record[9], + encoded_execution_record[10], + encoded_execution_record[11], + encoded_execution_record[12], + encoded_execution_record[13], + encoded_execution_record[14], + encoded_execution_record[15], + current_state[8], + current_state[9], + current_state[10], + current_state[11], + ]; + + let round_1_final = + simulate_round_function::<_, _, 8, 12, 4, R>(cs, round_1_initial, apply_any); + + current_state = round_1_final; + + let round_2_initial = [ + encoded_execution_record[16], + encoded_execution_record[17], + encoded_execution_record[18], + encoded_execution_record[19], + encoded_execution_record[20], + encoded_execution_record[21], + encoded_execution_record[22], + encoded_execution_record[23], + current_state[8], + current_state[9], + current_state[10], + current_state[11], + ]; + + let round_2_final = + simulate_round_function::<_, _, 8, 12, 4, R>(cs, round_2_initial, apply_any); + + current_state = round_2_final; + + let round_3_initial = [ + encoded_execution_record[24], + encoded_execution_record[25], + encoded_execution_record[26], + encoded_execution_record[27], + encoded_execution_record[28], + encoded_execution_record[29], + encoded_execution_record[30], + encoded_execution_record[31], + current_state[8], + current_state[9], + current_state[10], + current_state[11], + ]; + + let round_3_final = + simulate_round_function::<_, _, 8, 12, 4, R>(cs, round_3_initial, apply_any); + + current_state = round_3_final; + + let potential_final_state = current_state.map(|el| Num::from_variable(el)); + + for (a, b) in potential_final_state + .iter() + .zip(draft_vm_state.callstack.stack_sponge_state.iter()) + { + Num::conditionally_enforce_equal(cs, apply_ret, a, b); + } + + let new_callstack_state = Num::parallel_select( + cs, + apply_ret, + &previous_callstack_state_for_ret, + &potential_final_state, + ); + + let depth_increased = unsafe { + draft_vm_state + .callstack + .context_stack_depth + .increment_unchecked(cs) + }; + let one_u32 = UInt32::allocated_constant(cs, 1); + let (depth_decreased, uf) = draft_vm_state + .callstack + .context_stack_depth + .overflowing_sub(cs, one_u32); + + uf.conditionally_enforce_false(cs, apply_ret); + + let new_callstack_depth = + UInt32::conditionally_select(cs, apply_ret, &depth_decreased, &depth_increased); + + // assemble a new callstack in full + + let new_log_queue_forward_tail = Num::parallel_select( + cs, + apply_ret, + &new_forward_queue_state_for_ret, + &new_forward_queue_state_for_far_call, + ); + + let new_log_queue_forward_len = UInt32::conditionally_select( + cs, + apply_ret, + &new_forward_queue_len_for_ret, + &new_forward_queue_len_for_far_call, + ); + + use crate::base_structures::vm_state::callstack::FullExecutionContext; + + let new_context = FullExecutionContext { + saved_context: new_callstack_entry, + log_queue_forward_tail: new_log_queue_forward_tail, + log_queue_forward_part_length: new_log_queue_forward_len, + }; + + use crate::base_structures::vm_state::callstack::Callstack; + + let new_callstack = Callstack { + current_context: new_context, + context_stack_depth: new_callstack_depth, + stack_sponge_state: new_callstack_state, + }; + + let mut common_relations_buffer = ArrayVec::< + ( + Boolean, + [Num; FULL_SPONGE_QUEUE_STATE_WIDTH], + [Num; FULL_SPONGE_QUEUE_STATE_WIDTH], + ), + MAX_SPONGES_PER_CYCLE, + >::new(); + // first we push relations that are common, namely callstack sponge + + common_relations_buffer.push(( + apply_any, + round_0_initial.map(|el| Num::from_variable(el)), + round_0_final.map(|el| Num::from_variable(el)), + )); + + common_relations_buffer.push(( + apply_any, + round_1_initial.map(|el| Num::from_variable(el)), + round_1_final.map(|el| Num::from_variable(el)), + )); + + common_relations_buffer.push(( + apply_any, + round_2_initial.map(|el| Num::from_variable(el)), + round_2_final.map(|el| Num::from_variable(el)), + )); + + common_relations_buffer.push(( + apply_any, + round_3_initial.map(|el| Num::from_variable(el)), + round_3_final.map(|el| Num::from_variable(el)), + )); + + // and now we append relations for far call, that are responsible for storage read and decommittment + common_relations_buffer.extend(pending_sponges_for_far_call); + + // now just append relations to select later on + + // all the opcodes reset flags in full + let mut new_flags = common_opcode_state.reseted_flags; + new_flags.overflow_or_less_than = is_ret_panic_if_apply; + + // report to witness oracle + let oracle = witness_oracle.clone(); + // we should assemble all the dependencies here, and we will use AllocateExt here + let mut dependencies = Vec::with_capacity( + as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 3, + ); + dependencies.push(apply_any.get_variable().into()); + dependencies.push(is_call_like.get_variable().into()); + dependencies.push(new_callstack_depth.get_variable().into()); + dependencies.extend(Place::from_variables( + new_callstack_entry.flatten_as_variables(), + )); + + cs.set_values_with_dependencies_vararg( + &dependencies, + &[], + move |inputs: &[F], _buffer: &mut DstBuffer<'_, '_, F>| { + let execute = >::cast_from_source(inputs[0]); + let is_call_like = >::cast_from_source(inputs[1]); + let new_depth = >::cast_from_source(inputs[2]); + + let mut query = + [F::ZERO; as CSAllocatableExt>::INTERNAL_STRUCT_LEN]; + query.copy_from_slice(&inputs[3..]); + use crate::base_structures::vm_state::saved_context::ExecutionContextRecordWitness; + let query: ExecutionContextRecordWitness = + CSAllocatableExt::witness_from_set_of_values(query); + + let mut guard = oracle.inner.write().expect("not poisoned"); + guard.report_new_callstack_frame(&query, new_depth, is_call_like, execute); + drop(guard); + }, + ); + + // add everything to state diffs + + // we should check that opcode can not use src0/dst0 in memory + const FAR_CALL_OPCODE: zkevm_opcode_defs::Opcode = + zkevm_opcode_defs::Opcode::FarCall(zkevm_opcode_defs::FarCallOpcode::Normal); + const NEAR_CALL_OPCODE: zkevm_opcode_defs::Opcode = + zkevm_opcode_defs::Opcode::NearCall(zkevm_opcode_defs::NearCallOpcode); + const RET_OPCODE: zkevm_opcode_defs::Opcode = + zkevm_opcode_defs::Opcode::Ret(zkevm_opcode_defs::RetOpcode::Ok); + + assert!(FAR_CALL_OPCODE.can_have_src0_from_mem(SUPPORTED_ISA_VERSION) == false); + assert!(NEAR_CALL_OPCODE.can_have_src0_from_mem(SUPPORTED_ISA_VERSION) == false); + assert!(RET_OPCODE.can_have_src0_from_mem(SUPPORTED_ISA_VERSION) == false); + + assert!(FAR_CALL_OPCODE.can_write_dst0_into_memory(SUPPORTED_ISA_VERSION) == false); + assert!(NEAR_CALL_OPCODE.can_write_dst0_into_memory(SUPPORTED_ISA_VERSION) == false); + assert!(RET_OPCODE.can_write_dst0_into_memory(SUPPORTED_ISA_VERSION) == false); + + diffs_accumulator.sponge_candidates_to_run.push(( + false, + false, + apply_any, + common_relations_buffer, + )); + diffs_accumulator.flags.push((apply_any, new_flags)); + + // each opcode may have different register updates + for (idx, el) in specific_registers_updates_for_far_call + .into_iter() + .enumerate() + { + if let Some(el) = el { + diffs_accumulator.specific_registers_updates[idx].push(el); + } + } + + for (idx, el) in specific_registers_updates_for_ret.into_iter().enumerate() { + if let Some(el) = el { + diffs_accumulator.specific_registers_updates[idx].push(el); + } + } + + // same for zeroing out and removing ptr markers + for (idx, el) in specific_registers_zeroing_for_far_call + .into_iter() + .enumerate() + { + if let Some(el) = el { + diffs_accumulator.specific_registers_zeroing[idx].push(el); + } + } + + for (idx, el) in specific_registers_zeroing_for_ret.into_iter().enumerate() { + if let Some(el) = el { + diffs_accumulator.specific_registers_zeroing[idx].push(el); + } + } + + for (idx, el) in remove_ptr_on_specific_registers_for_far_call + .into_iter() + .enumerate() + { + if let Some(el) = el { + diffs_accumulator.remove_ptr_on_specific_registers[idx].push(el); + } + } + + for (idx, el) in remove_ptr_on_specific_registers_for_ret + .into_iter() + .enumerate() + { + if let Some(el) = el { + diffs_accumulator.remove_ptr_on_specific_registers[idx].push(el); + } + } + + // pending exception if any + diffs_accumulator + .pending_exceptions + .push(pending_exception_if_far_call); + + // callstacks in full + diffs_accumulator + .callstacks + .push((apply_any, new_callstack)); + + // far call already chosen it + debug_assert!(diffs_accumulator.memory_page_counters.is_none()); + diffs_accumulator.memory_page_counters = Some(new_memory_pages_counter); + + let zero_u32 = UInt32::zero(cs); + let empty_context_value = [zero_u32; 4]; + + diffs_accumulator + .context_u128_candidates + .push((reset_context_value, empty_context_value)); + + debug_assert!(diffs_accumulator.decommitment_queue_candidates.is_none()); + diffs_accumulator.decommitment_queue_candidates = Some(( + apply_far_call, + new_decommittment_queue_len, + new_decommittment_queue_tail, + )); +} diff --git a/crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/far_call.rs b/crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/far_call.rs new file mode 100644 index 0000000..125ee24 --- /dev/null +++ b/crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/far_call.rs @@ -0,0 +1,1594 @@ +use zkevm_opcode_defs::system_params::STORAGE_AUX_BYTE; + +use crate::base_structures::{ + log_query::{self, LogQuery}, + register::VMRegister, + vm_state::FULL_SPONGE_QUEUE_STATE_WIDTH, +}; +use boojum::gadgets::{u160::UInt160, u256::UInt256}; + +use super::*; +use crate::base_structures::decommit_query::DecommitQuery; +use crate::base_structures::decommit_query::DecommitQueryWitness; +use crate::base_structures::vm_state::saved_context::ExecutionContextRecord; +use crate::base_structures::vm_state::saved_context::ExecutionContextRecordWitness; +use crate::base_structures::vm_state::GlobalContext; +use crate::base_structures::vm_state::QUEUE_STATE_WIDTH; +use crate::main_vm::opcodes::call_ret_impl::far_call::log_query::LogQueryWitness; +use crate::main_vm::state_diffs::MAX_SPONGES_PER_CYCLE; +use crate::main_vm::witness_oracle::SynchronizedWitnessOracle; +use crate::main_vm::witness_oracle::WitnessOracle; +use arrayvec::ArrayVec; +use boojum::algebraic_props::round_function::AlgebraicRoundFunction; +use boojum::cs::traits::cs::DstBuffer; +use boojum::gadgets::traits::allocatable::CSAllocatable; +use boojum::gadgets::traits::allocatable::CSAllocatableExt; +use boojum::gadgets::traits::round_function::CircuitRoundFunction; + +const FORCED_ERGS_FOR_MSG_VALUE_SIMUALTOR: bool = false; + +pub(crate) struct FarCallData { + pub(crate) apply_far_call: Boolean, + pub(crate) old_context: ExecutionContextRecord, + pub(crate) new_context: ExecutionContextRecord, + pub(crate) new_decommittment_queue_tail: [Num; FULL_SPONGE_QUEUE_STATE_WIDTH], + pub(crate) new_decommittment_queue_len: UInt32, + pub(crate) new_forward_queue_tail: [Num; QUEUE_STATE_WIDTH], + pub(crate) new_forward_queue_len: UInt32, + pub(crate) pending_sponges: ArrayVec< + ( + Boolean, + [Num; FULL_SPONGE_QUEUE_STATE_WIDTH], + [Num; FULL_SPONGE_QUEUE_STATE_WIDTH], + ), + MAX_SPONGES_PER_CYCLE, + >, + pub(crate) specific_registers_updates: [Option<(Boolean, VMRegister)>; REGISTERS_COUNT], + pub(crate) specific_registers_zeroing: [Option>; REGISTERS_COUNT], + pub(crate) remove_ptr_on_specific_registers: [Option>; REGISTERS_COUNT], + pub(crate) pending_exception: Boolean, + pub(crate) new_memory_pages_counter: UInt32, +} + +#[derive(Derivative, CSAllocatable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] + +pub(crate) struct FarCallPartialABI { + pub(crate) ergs_passed: UInt32, + pub(crate) shard_id: UInt8, + pub(crate) constructor_call: Boolean, + pub(crate) system_call: Boolean, +} + +use crate::main_vm::register_input_view::RegisterInputView; + +impl FarCallPartialABI { + pub fn from_register_view>( + cs: &mut CS, + input: &RegisterInputView, + ) -> Self { + // low part of highest 64 bits + let ergs_passed = input.u32x8_view[6]; + + // higher parts of highest 64 bits + let shard_id = input.u8x32_view + [zkevm_opcode_defs::definitions::abi::far_call::FAR_CALL_SHARD_ID_BYTE_IDX]; + let constructor_call = input.u8x32_view + [zkevm_opcode_defs::definitions::abi::far_call::FAR_CALL_CONSTRUCTOR_CALL_BYTE_IDX] + .is_zero(cs) + .negated(cs); + let system_call = input.u8x32_view + [zkevm_opcode_defs::definitions::abi::far_call::FAR_CALL_SYSTEM_CALL_BYTE_IDX] + .is_zero(cs) + .negated(cs); + + let new = Self { + ergs_passed, + shard_id, + constructor_call, + system_call, + }; + + new + } +} + +#[derive(Derivative, CSAllocatable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] + +pub(crate) struct CommonCallRetABI { + pub(crate) fat_ptr: FatPtrInABI, + pub(crate) upper_bound: UInt32, + pub(crate) ptr_validation_data: PtrValidationData, +} + +#[derive(Derivative, CSAllocatable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] + +pub(crate) struct CallRetForwardingMode { + pub(crate) use_heap: Boolean, + pub(crate) use_aux_heap: Boolean, + pub(crate) forward_fat_pointer: Boolean, +} + +#[derive(Derivative, CSAllocatable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +pub(crate) struct FatPtrInABI { + pub(crate) offset: UInt32, + pub(crate) page: UInt32, + pub(crate) start: UInt32, + pub(crate) length: UInt32, +} + +impl Selectable for FatPtrInABI { + fn conditionally_select>( + cs: &mut CS, + flag: Boolean, + a: &Self, + b: &Self, + ) -> Self { + // do via multiselect + let a = [a.offset, a.page, a.start, a.length]; + let b = [b.offset, b.page, b.start, b.length]; + + let result = UInt32::parallel_select(cs, flag, &a, &b); + + Self { + offset: result[0], + page: result[1], + start: result[2], + length: result[3], + } + } +} + +#[derive(Derivative, CSAllocatable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +pub(crate) struct PtrValidationData { + pub(crate) generally_invalid: Boolean, // common invariants + pub(crate) is_non_addressable: Boolean, +} + +impl FatPtrInABI { + pub(crate) fn parse_and_validate>( + cs: &mut CS, + input: &RegisterInputView, + as_fresh: Boolean, + ) -> (Self, UInt32, PtrValidationData) { + // we can never address a range [2^32 - 32..2^32] this way, but we don't care because + // it's impossible to pay for such memory growth + let offset = input.u32x8_view[0]; + let page = input.u32x8_view[1]; + let start = input.u32x8_view[2]; + let length = input.u32x8_view[3]; + + let offset_is_zero = offset.is_zero(cs); + let offset_is_non_zero = offset_is_zero.negated(cs); + + let non_zero_offset_if_should_be_fresh = + Boolean::multi_and(cs, &[offset_is_non_zero, as_fresh]); + + let (end_non_inclusive, slice_u32_range_overflow) = start.overflowing_add(cs, length); + + // offset <= length, that captures the empty slice (0, 0) + let (_, is_invalid_as_slice) = length.overflowing_sub(cs, offset); + + let ptr_is_invalid = Boolean::multi_or( + cs, + &[ + non_zero_offset_if_should_be_fresh, + slice_u32_range_overflow, + is_invalid_as_slice, + ], + ); + + let offset = offset.mask_negated(cs, ptr_is_invalid); + let page = page.mask_negated(cs, ptr_is_invalid); + let start = start.mask_negated(cs, ptr_is_invalid); + let length = length.mask_negated(cs, ptr_is_invalid); + + let new = Self { + offset, + page, + start, + length, + }; + + let validation_data = PtrValidationData { + generally_invalid: ptr_is_invalid, + is_non_addressable: slice_u32_range_overflow, + }; + + (new, end_non_inclusive, validation_data) + } + + pub(crate) fn mask_into_empty>( + &self, + cs: &mut CS, + set_empty: Boolean, + ) -> Self { + let offset = self.offset.mask_negated(cs, set_empty); + let page = self.page.mask_negated(cs, set_empty); + let start = self.start.mask_negated(cs, set_empty); + let length = self.length.mask_negated(cs, set_empty); + + let new = Self { + offset, + page, + start, + length, + }; + + new + } + + // ONLY call after validations + pub(crate) fn readjust>(&self, cs: &mut CS) -> Self { + // if we have prevalidated everything, then we KNOW that "length + start" doesn't overflow and is within addressable bound, + // and that offset < length, so overflows here can be ignored + let new_start = self.start.add_no_overflow(cs, self.offset); + let new_length = self.length.sub_no_overflow(cs, self.offset); + + let zero_u32 = UInt32::zero(cs); + + let new = Self { + offset: zero_u32, + page: self.page, + start: new_start, + length: new_length, + }; + + new + } + + pub(crate) fn into_register>(self, cs: &mut CS) -> VMRegister { + let zero_u32 = UInt32::zero(cs); + let boolean_true = Boolean::allocated_constant(cs, true); + + let result = VMRegister { + is_pointer: boolean_true, + value: UInt256 { + inner: [ + self.offset, + self.page, + self.start, + self.length, + zero_u32, + zero_u32, + zero_u32, + zero_u32, + ], + }, + }; + + result + } +} + +pub(crate) fn callstack_candidate_for_far_call< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, + W: WitnessOracle, +>( + cs: &mut CS, + draft_vm_state: &VmLocalState, + common_opcode_state: &CommonOpcodeState, + opcode_carry_parts: &AfterDecodingCarryParts, + witness_oracle: &SynchronizedWitnessOracle, + global_context: &GlobalContext, + common_abi_parts: &CommonCallRetABI, + far_call_abi: &FarCallPartialABI, + forwarding_data: &CallRetForwardingMode, + round_function: &R, +) -> FarCallData +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + // new callstack should be just the same a the old one, but we also need to update the pricing for pubdata in the rare case + + const FAR_CALL_OPCODE: zkevm_opcode_defs::Opcode = + zkevm_opcode_defs::Opcode::FarCall(zkevm_opcode_defs::FarCallOpcode::Normal); + + let execute = common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_opcode(FAR_CALL_OPCODE); + + if crate::config::CIRCUIT_VERSOBE { + if (execute.witness_hook(&*cs))().unwrap_or(false) { + println!("Applying FAR CALL"); + } + } + + let _is_normal_call = common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(zkevm_opcode_defs::Opcode::FarCall( + zkevm_opcode_defs::FarCallOpcode::Normal, + )); + let is_delegated_call = common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(zkevm_opcode_defs::Opcode::FarCall( + zkevm_opcode_defs::FarCallOpcode::Delegate, + )); + let is_mimic_call = common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(zkevm_opcode_defs::Opcode::FarCall( + zkevm_opcode_defs::FarCallOpcode::Mimic, + )); + + let is_kernel_mode = draft_vm_state + .callstack + .current_context + .saved_context + .is_kernel_mode; + let mut current_callstack_entry = draft_vm_state.callstack.current_context.saved_context; + // perform all known modifications, like PC/SP saving + current_callstack_entry.pc = opcode_carry_parts.next_pc; + + // we need a completely fresh one + let mut new_callstack_entry = ExecutionContextRecord::uninitialized(cs); + // apply memory stipends right away + new_callstack_entry.heap_upper_bound = UInt32::allocated_constant( + cs, + zkevm_opcode_defs::system_params::NEW_FRAME_MEMORY_STIPEND, + ); + new_callstack_entry.aux_heap_upper_bound = UInt32::allocated_constant( + cs, + zkevm_opcode_defs::system_params::NEW_FRAME_MEMORY_STIPEND, + ); + + // now also create target for mimic + let implicit_mimic_call_reg = draft_vm_state.registers + [zkevm_opcode_defs::definitions::far_call::CALL_IMPLICIT_PARAMETER_REG_IDX as usize]; + + // - get code destination address + // - resolve caller/callee dependencies + // - resolve calldata page + // - resolve ergs + + let caller_address_for_mimic = UInt160 { + inner: [ + implicit_mimic_call_reg.value.inner[0], + implicit_mimic_call_reg.value.inner[1], + implicit_mimic_call_reg.value.inner[2], + implicit_mimic_call_reg.value.inner[3], + implicit_mimic_call_reg.value.inner[4], + ], + }; + + // in src0 lives the ABI + // in src1 lives the destination + + // we also reuse pre-parsed ABI + + // src1 is target address + let destination_address = UInt160 { + inner: [ + common_opcode_state.src1_view.u32x8_view[0], + common_opcode_state.src1_view.u32x8_view[1], + common_opcode_state.src1_view.u32x8_view[2], + common_opcode_state.src1_view.u32x8_view[3], + common_opcode_state.src1_view.u32x8_view[4], + ], + }; + + let is_static_call = common_opcode_state + .decoded_opcode + .properties_bits + .flag_booleans[FAR_CALL_STATIC_FLAG_IDX]; + let is_call_shard = common_opcode_state + .decoded_opcode + .properties_bits + .flag_booleans[FAR_CALL_SHARD_FLAG_IDX]; + + let destination_shard = far_call_abi.shard_id; + let caller_shard_id = current_callstack_entry.this_shard_id; + let destination_shard = + UInt8::conditionally_select(cs, is_call_shard, &destination_shard, &caller_shard_id); + let target_is_zkporter = destination_shard.is_zero(cs).negated(cs); + + let target_is_kernel = { + let destination_16_32 = UInt16::from_le_bytes( + cs, + [ + common_opcode_state.src1_view.u8x32_view[2], + common_opcode_state.src1_view.u8x32_view[3], + ], + ); + + let destination_16_32_is_zero = destination_16_32.is_zero(cs); + let destination_32_64_is_zero = common_opcode_state.src1_view.u32x8_view[1].is_zero(cs); + let destination_64_96_is_zero = common_opcode_state.src1_view.u32x8_view[2].is_zero(cs); + let destination_96_128_is_zero = common_opcode_state.src1_view.u32x8_view[3].is_zero(cs); + let destination_128_160_is_zero = common_opcode_state.src1_view.u32x8_view[4].is_zero(cs); + + let higher_bytes_are_zeroes = Boolean::multi_and( + cs, + &[ + destination_16_32_is_zero, + destination_32_64_is_zero, + destination_64_96_is_zero, + destination_96_128_is_zero, + destination_128_160_is_zero, + ], + ); + + higher_bytes_are_zeroes + }; + + let mut far_call_abi = *far_call_abi; + + // mask flags in ABI if not applicable + far_call_abi.constructor_call = + Boolean::multi_and(cs, &[far_call_abi.constructor_call, is_kernel_mode]); + far_call_abi.system_call = + Boolean::multi_and(cs, &[far_call_abi.system_call, target_is_kernel]); + + if crate::config::CIRCUIT_VERSOBE { + if execute.witness_hook(&*cs)().unwrap_or(false) { + dbg!(forwarding_data.witness_hook(&*cs)().unwrap()); + dbg!(far_call_abi.witness_hook(&*cs)().unwrap()); + } + } + + // the same as we use for LOG + let timestamp_to_use_for_decommittment_request = + common_opcode_state.timestamp_for_first_decommit_or_precompile_read; + let default_target_memory_page = draft_vm_state.memory_page_counter; + + // increment next counter + let new_base_page = draft_vm_state.memory_page_counter; + let memory_pages_per_far_call = UInt32::allocated_constant(cs, NEW_MEMORY_PAGES_PER_FAR_CALL); + let new_memory_pages_counter = draft_vm_state + .memory_page_counter + .add_no_overflow(cs, memory_pages_per_far_call); + + let new_memory_pages_counter = UInt32::conditionally_select( + cs, + execute, + &new_memory_pages_counter, + &draft_vm_state.memory_page_counter, + ); + + // now we have everything to perform code read and decommittment + + let mut all_pending_sponges = ArrayVec::new(); + + let (bytecode_hash_is_trivial, bytecode_hash, (new_forward_queue_tail, new_forward_queue_len)) = + may_be_read_code_hash( + cs, + &mut all_pending_sponges, + &destination_address, + &destination_shard, + &target_is_zkporter, + &global_context.zkporter_is_available, + &execute, + &global_context.default_aa_code_hash, + &target_is_kernel, + draft_vm_state + .callstack + .current_context + .log_queue_forward_tail, + draft_vm_state + .callstack + .current_context + .log_queue_forward_part_length, + timestamp_to_use_for_decommittment_request, + draft_vm_state.tx_number_in_block, + witness_oracle, + round_function, + ); + + // now we should do validation BEFORE decommittment + + let zero_u32 = UInt32::zero(cs); + + let target_code_memory_page = UInt32::conditionally_select( + cs, + bytecode_hash_is_trivial, + &zero_u32, + &default_target_memory_page, + ); + + // first we validate if code hash is indeed in the format that we expect + + // If we do not do "constructor call" then 2nd byte should be 0, + // otherwise it's 1 + + let bytecode_hash_upper_decomposition = bytecode_hash.inner[7].decompose_into_bytes(cs); + + let version_byte = bytecode_hash_upper_decomposition[3]; + let code_hash_version_byte = + UInt8::allocated_constant(cs, zkevm_opcode_defs::ContractCodeSha256::VERSION_BYTE); + let versioned_byte_is_valid = UInt8::equals(cs, &version_byte, &code_hash_version_byte); + let versioned_byte_is_invalid = versioned_byte_is_valid.negated(cs); + + let marker_byte = bytecode_hash_upper_decomposition[2]; + let is_normal_call_marker = marker_byte.is_zero(cs); + let now_in_construction_marker_byte = UInt8::allocated_constant( + cs, + zkevm_opcode_defs::ContractCodeSha256::YET_CONSTRUCTED_MARKER, + ); + let is_constructor_call_marker = + UInt8::equals(cs, &marker_byte, &now_in_construction_marker_byte); + let unknown_marker = + Boolean::multi_or(cs, &[is_normal_call_marker, is_constructor_call_marker]).negated(cs); + + // NOTE: if bytecode hash is trivial then it's 0, so version byte is not valid! + let code_format_exception = Boolean::multi_or(cs, &[versioned_byte_is_invalid, unknown_marker]); + + // we do not remask right away yet + + let normal_call_code = far_call_abi.constructor_call.negated(cs); + + let can_call_normally = Boolean::multi_and(cs, &[is_normal_call_marker, normal_call_code]); + let can_call_constructor = Boolean::multi_and( + cs, + &[is_constructor_call_marker, far_call_abi.constructor_call], + ); + let can_call_code = Boolean::multi_or(cs, &[can_call_normally, can_call_constructor]); + + let marker_byte_masked = UInt8::allocated_constant( + cs, + zkevm_opcode_defs::ContractCodeSha256::CODE_AT_REST_MARKER, + ); + + let bytecode_at_rest_top_word = UInt32::from_le_bytes( + cs, + [ + bytecode_hash_upper_decomposition[0], + bytecode_hash_upper_decomposition[1], + marker_byte_masked, + code_hash_version_byte, + ], + ); + + let mut bytecode_at_storage_format = bytecode_hash; + bytecode_at_storage_format.inner[7] = bytecode_at_rest_top_word; + + let zero_u256 = UInt256::zero(cs); + + let masked_value_if_mask = UInt256::conditionally_select( + cs, + target_is_kernel, + &zero_u256, + &global_context.default_aa_code_hash, + ); + + let masked_bytecode_hash = UInt256::conditionally_select( + cs, + can_call_code, + &bytecode_at_storage_format, + &masked_value_if_mask, + ); + + // at the end of the day all our exceptions will lead to memory page being 0 + + let masked_bytecode_hash_upper_decomposition = + masked_bytecode_hash.inner[7].decompose_into_bytes(cs); + + let mut code_hash_length_in_words = UInt16::from_le_bytes( + cs, + [ + masked_bytecode_hash_upper_decomposition[0], + masked_bytecode_hash_upper_decomposition[1], + ], + ); + code_hash_length_in_words = code_hash_length_in_words.mask_negated(cs, code_format_exception); + + // if we call now-in-construction system contract, then we formally mask into 0 (even though it's not needed), + // and we should put an exception here + + let can_not_call_code = can_call_code.negated(cs); + let call_now_in_construction_kernel = + Boolean::multi_and(cs, &[can_not_call_code, target_is_kernel]); + + // exceptions, along with `bytecode_hash_is_trivial` indicate whether we will or will decommit code + // into memory, or will just use UNMAPPED_PAGE + let mut exceptions = ArrayVec::, 5>::new(); + exceptions.push(code_format_exception); + exceptions.push(call_now_in_construction_kernel); + + // resolve passed ergs, passed calldata page, etc + + let forward_fat_pointer = forwarding_data.forward_fat_pointer; + let src0_is_integer = common_opcode_state.src0_view.is_ptr.negated(cs); + + let fat_ptr_expected_exception = + Boolean::multi_and(cs, &[forward_fat_pointer, src0_is_integer]); + exceptions.push(fat_ptr_expected_exception); + + // add pointer validation cases + exceptions.push(common_abi_parts.ptr_validation_data.generally_invalid); + exceptions.push(common_abi_parts.ptr_validation_data.is_non_addressable); + + let do_not_forward_ptr = forward_fat_pointer.negated(cs); + + let exceptions_collapsed = Boolean::multi_or(cs, &exceptions); + + // if crate::config::CIRCUIT_VERSOBE { + // if execute.witness_hook(&*cs)().unwrap() { + // dbg!(code_format_exception.witness_hook(&*cs)().unwrap()); + // dbg!(call_now_in_construction_kernel.witness_hook(&*cs)().unwrap()); + // dbg!(fat_ptr_expected_exception.witness_hook(&*cs)().unwrap()); + // } + // } + + let fat_ptr = common_abi_parts.fat_ptr; + // we readjust before heap resize + + let fat_ptr_adjusted_if_forward = fat_ptr.readjust(cs); + + let page = UInt32::conditionally_select( + cs, + forwarding_data.use_heap, + &opcode_carry_parts.heap_page, + &opcode_carry_parts.aux_heap_page, + ); + + let fat_ptr_for_heaps = FatPtrInABI { + offset: zero_u32, + page, + start: fat_ptr.start, + length: fat_ptr.length, + }; + + let final_fat_ptr = FatPtrInABI::conditionally_select( + cs, + forwarding_data.forward_fat_pointer, + &fat_ptr_adjusted_if_forward, + &fat_ptr_for_heaps, + ); + + // and mask in case of exceptions + + let final_fat_ptr = final_fat_ptr.mask_into_empty(cs, exceptions_collapsed); + + if crate::config::CIRCUIT_VERSOBE { + if execute.witness_hook(&*cs)().unwrap_or(false) { + dbg!(final_fat_ptr.witness_hook(&*cs)().unwrap()); + } + } + + // now we can resize memory + + let upper_bound = common_abi_parts.upper_bound; + // first mask to 0 if exceptions happened + let upper_bound = upper_bound.mask_negated(cs, exceptions_collapsed); + // then compute to penalize for out of memory access attemp + let memory_region_is_not_addressable = common_abi_parts.ptr_validation_data.is_non_addressable; + + // and penalize if pointer is fresh and not addressable + let penalize_heap_overflow = + Boolean::multi_and(cs, &[memory_region_is_not_addressable, do_not_forward_ptr]); + let u32_max = UInt32::allocated_constant(cs, u32::MAX); + + let upper_bound = + UInt32::conditionally_select(cs, penalize_heap_overflow, &u32_max, &upper_bound); + + // potentially pay for memory growth for heap and aux heap + + let heap_max_accessed = upper_bound.mask(cs, forwarding_data.use_heap); + let heap_bound = current_callstack_entry.heap_upper_bound; + let (mut heap_growth, uf) = heap_max_accessed.overflowing_sub(cs, heap_bound); + heap_growth = heap_growth.mask_negated(cs, uf); // if we access in bounds then it's 0 + let new_heap_upper_bound = + UInt32::conditionally_select(cs, uf, &heap_bound, &heap_max_accessed); + let grow_heap = Boolean::multi_and(cs, &[forwarding_data.use_heap, execute]); + + let aux_heap_max_accessed = upper_bound.mask(cs, forwarding_data.use_aux_heap); + let aux_heap_bound = current_callstack_entry.aux_heap_upper_bound; + let (mut aux_heap_growth, uf) = aux_heap_max_accessed.overflowing_sub(cs, aux_heap_bound); + aux_heap_growth = aux_heap_growth.mask_negated(cs, uf); // if we access in bounds then it's 0 + let new_aux_heap_upper_bound = + UInt32::conditionally_select(cs, uf, &aux_heap_bound, &aux_heap_max_accessed); + let grow_aux_heap = Boolean::multi_and(cs, &[forwarding_data.use_aux_heap, execute]); + + let mut growth_cost = heap_growth.mask(cs, grow_heap); + growth_cost = UInt32::conditionally_select(cs, grow_aux_heap, &aux_heap_growth, &growth_cost); + + // if crate::config::CIRCUIT_VERSOBE { + // if execute.witness_hook(&*cs)().unwrap() { + // dbg!(opcode_carry_parts.preliminary_ergs_left.witness_hook(&*cs)().unwrap()); + // dbg!(growth_cost.witness_hook(&*cs)().unwrap()); + // } + // } + + let (ergs_left_after_growth, uf) = opcode_carry_parts + .preliminary_ergs_left + .overflowing_sub(cs, growth_cost); + + let mut exceptions = ArrayVec::, 5>::new(); + exceptions.push(exceptions_collapsed); + + let ergs_left_after_growth = ergs_left_after_growth.mask_negated(cs, uf); // if not enough - set to 0 + exceptions.push(uf); + + // if crate::config::CIRCUIT_VERSOBE { + // if execute.witness_hook(&*cs)().unwrap() { + // dbg!(ergs_left_after_growth.witness_hook(&*cs)().unwrap()); + // } + // } + + current_callstack_entry.heap_upper_bound = UInt32::conditionally_select( + cs, + grow_heap, + &new_heap_upper_bound, + ¤t_callstack_entry.heap_upper_bound, + ); + + current_callstack_entry.aux_heap_upper_bound = UInt32::conditionally_select( + cs, + grow_aux_heap, + &new_aux_heap_upper_bound, + ¤t_callstack_entry.aux_heap_upper_bound, + ); + + // now any extra cost + let callee_stipend = if FORCED_ERGS_FOR_MSG_VALUE_SIMUALTOR == false { + zero_u32 + } else { + let is_msg_value_simulator_address_low = + UInt32::allocated_constant(cs, zkevm_opcode_defs::ADDRESS_MSG_VALUE as u32); + let target_low_is_msg_value_simulator = UInt32::equals( + cs, + &destination_address.inner[0], + &is_msg_value_simulator_address_low, + ); + // we know that that msg.value simulator is kernel, so we test equality of low address segment and test for kernel + let target_is_msg_value = + Boolean::multi_and(cs, &[target_is_kernel, target_low_is_msg_value_simulator]); + let is_system_abi = far_call_abi.system_call; + let require_extra = Boolean::multi_and(cs, &[target_is_msg_value, is_system_abi]); + + let additive_cost = UInt32::allocated_constant( + cs, + zkevm_opcode_defs::system_params::MSG_VALUE_SIMULATOR_ADDITIVE_COST, + ); + let max_pubdata_bytes = UInt32::allocated_constant( + cs, + zkevm_opcode_defs::system_params::MSG_VALUE_SIMULATOR_PUBDATA_BYTES_TO_PREPAY, + ); + + let pubdata_cost = + max_pubdata_bytes.non_widening_mul(cs, &draft_vm_state.ergs_per_pubdata_byte); + let cost = pubdata_cost.add_no_overflow(cs, additive_cost); + + cost.mask(cs, require_extra) + }; + + let (ergs_left_after_extra_costs, uf) = + ergs_left_after_growth.overflowing_sub(cs, callee_stipend); + let ergs_left_after_extra_costs = ergs_left_after_extra_costs.mask_negated(cs, uf); // if not enough - set to 0 + let callee_stipend = callee_stipend.mask_negated(cs, uf); // also set to 0 if we were not able to take it + exceptions.push(uf); + + // now we can indeed decommit + + let exception = Boolean::multi_or(cs, &exceptions); + let valid_execution = exception.negated(cs); + let should_decommit = Boolean::multi_and(cs, &[execute, valid_execution]); + + let target_code_memory_page = target_code_memory_page.mask(cs, should_decommit); + + // if crate::config::CIRCUIT_VERSOBE { + // if execute.witness_hook(&*cs)().unwrap() { + // dbg!(exception.witness_hook(&*cs)().unwrap()); + // dbg!(ergs_left_after_extra_costs.witness_hook(&*cs)().unwrap()); + // } + // } + + let ( + not_enough_ergs_to_decommit, + code_memory_page, + (new_decommittment_queue_tail, new_decommittment_queue_len), + ergs_remaining_after_decommit, + ) = add_to_decommittment_queue( + cs, + &mut all_pending_sponges, + &should_decommit, + &ergs_left_after_extra_costs, + &masked_bytecode_hash, + &code_hash_length_in_words, + &draft_vm_state.code_decommittment_queue_state, + &draft_vm_state.code_decommittment_queue_length, + ×tamp_to_use_for_decommittment_request, + &target_code_memory_page, + witness_oracle, + round_function, + ); + + let exception = Boolean::multi_or(cs, &[exception, not_enough_ergs_to_decommit]); + + if crate::config::CIRCUIT_VERSOBE { + if execute.witness_hook(&*cs)().unwrap_or(false) { + dbg!(exception.witness_hook(&*cs)().unwrap()); + } + } + + // on call-like path we continue the forward queue, but have to allocate the rollback queue state from witness + let call_timestamp = draft_vm_state.timestamp; + + let oracle = witness_oracle.clone(); + + let dependencies = [ + call_timestamp.get_variable().into(), + execute.get_variable().into(), + ]; + + // we always access witness, as even for writes we have to get a claimed read value! + let potential_rollback_queue_segment_tail = + Num::allocate_multiple_from_closure_and_dependencies( + cs, + move |inputs: &[F]| { + let call_timestamp = >::cast_from_source(inputs[0]); + let execute = >::cast_from_source(inputs[1]); + + let mut guard = oracle.inner.write().expect("not poisoned"); + let witness = + guard.get_rollback_queue_tail_witness_for_call(call_timestamp, execute); + drop(guard); + + witness + }, + &dependencies, + ); + + new_callstack_entry.reverted_queue_tail = potential_rollback_queue_segment_tail; + new_callstack_entry.reverted_queue_head = potential_rollback_queue_segment_tail; + new_callstack_entry.reverted_queue_segment_len = zero_u32; + + let dst_pc = UInt16::zero(cs); + let eh_pc = common_opcode_state.decoded_opcode.imm0; + + // if crate::config::CIRCUIT_VERSOBE { + // if execute.witness_hook(&*cs)().unwrap() { + // dbg!(ergs_remaining_after_decommit.witness_hook(&*cs)().unwrap()); + // } + // } + + // now we should resolve all passed ergs. That means + // that we have to read it from ABI, and then use 63/64 rule + let preliminary_ergs_left = ergs_remaining_after_decommit; + + let (ergs_div_by_64, _) = preliminary_ergs_left.div_by_constant(cs, 64); + + let constant_63 = UInt32::allocated_constant(cs, 63); + // NOTE: max passable is 63 / 64 * preliminary_ergs_left, that is itself u32, so it's safe to just + // mul as field elements + let max_passable = Num::from_variable(ergs_div_by_64.get_variable()) + .mul(cs, &Num::from_variable(constant_63.get_variable())); + let max_passable = unsafe { UInt32::from_variable_unchecked(max_passable.get_variable()) }; + + // max passable is <= preliminary_ergs_left from computations above, so it's also safe + let leftover = Num::from_variable(preliminary_ergs_left.get_variable()) + .sub(cs, &Num::from_variable(max_passable.get_variable())); + let leftover = unsafe { UInt32::from_variable_unchecked(leftover.get_variable()) }; + let ergs_to_pass = far_call_abi.ergs_passed; + + let (remaining_from_max_passable, uf) = max_passable.overflowing_sub(cs, ergs_to_pass); + // this one can overflow IF one above underflows, but we are not interested in it's overflow value + let (leftover_and_remaining_if_no_uf, _of) = + leftover.overflowing_add(cs, remaining_from_max_passable); + + let ergs_to_pass = UInt32::conditionally_select(cs, uf, &max_passable, &ergs_to_pass); + + let remaining_for_this_context = + UInt32::conditionally_select(cs, uf, &leftover, &leftover_and_remaining_if_no_uf); + + let remaining_ergs_if_pass = remaining_for_this_context; + let passed_ergs_if_pass = ergs_to_pass; + let passed_ergs_if_pass = passed_ergs_if_pass.add_no_overflow(cs, callee_stipend); + + current_callstack_entry.ergs_remaining = remaining_ergs_if_pass; + + // resolve this/callee shard + let new_this_shard_id = + UInt8::conditionally_select(cs, is_delegated_call, &caller_shard_id, &destination_shard); + + // default is normal call + let mut this_for_next = destination_address; + let mut caller_for_next = current_callstack_entry.this; + + // change if delegate or mimic + // - "this" only changed if delegate + this_for_next = UInt160::conditionally_select( + cs, + is_delegated_call, + ¤t_callstack_entry.this, + &this_for_next, + ); + // "caller" changes in both cases + + caller_for_next = UInt160::conditionally_select( + cs, + is_delegated_call, + ¤t_callstack_entry.caller, + &caller_for_next, + ); + + caller_for_next = UInt160::conditionally_select( + cs, + is_mimic_call, + &caller_address_for_mimic, + &caller_for_next, + ); + + // resolve static, etc + let next_is_static = Boolean::multi_or( + cs, + &[is_static_call, current_callstack_entry.is_static_execution], + ); + + // actually parts to the new one + new_callstack_entry.ergs_remaining = passed_ergs_if_pass; + new_callstack_entry.pc = dst_pc; + new_callstack_entry.exception_handler_loc = eh_pc; + new_callstack_entry.is_static_execution = next_is_static; + + // we need to decide whether new frame is kernel or not for degelatecall + let new_frame_is_kernel = Boolean::conditionally_select( + cs, + is_delegated_call, + ¤t_callstack_entry.is_kernel_mode, + &target_is_kernel, + ); + new_callstack_entry.is_kernel_mode = new_frame_is_kernel; + + // code part + new_callstack_entry.code_shard_id = destination_shard; + new_callstack_entry.code_address = destination_address; + // this part + new_callstack_entry.this_shard_id = new_this_shard_id; + new_callstack_entry.this = this_for_next; + // caller part + new_callstack_entry.caller = caller_for_next; + new_callstack_entry.caller_shard_id = caller_shard_id; + // code page + new_callstack_entry.code_page = code_memory_page; + // base page + new_callstack_entry.base_page = new_base_page; + // context u128 + // if we do delegatecall then we propagate current context value, otherwise + // we capture the current one + new_callstack_entry.context_u128_value_composite = UInt32::parallel_select( + cs, + is_delegated_call, + ¤t_callstack_entry.context_u128_value_composite, + &draft_vm_state.context_composite_u128, + ); + // non-local call + let boolean_false = Boolean::allocated_constant(cs, false); + new_callstack_entry.is_local_call = boolean_false; + + let oracle = witness_oracle.clone(); + // we should assemble all the dependencies here, and we will use AllocateExt here + let mut dependencies = Vec::with_capacity( + as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 2, + ); + dependencies.push(execute.get_variable().into()); + dependencies.push( + draft_vm_state + .callstack + .context_stack_depth + .get_variable() + .into(), + ); + dependencies.extend(Place::from_variables( + current_callstack_entry.flatten_as_variables(), + )); + + cs.set_values_with_dependencies_vararg( + &dependencies, + &[], + move |inputs: &[F], _buffer: &mut DstBuffer<'_, '_, F>| { + let execute = >::cast_from_source(inputs[0]); + let current_depth = >::cast_from_source(inputs[1]); + + let mut query = + [F::ZERO; as CSAllocatableExt>::INTERNAL_STRUCT_LEN]; + query.copy_from_slice(&inputs[2..]); + let query: ExecutionContextRecordWitness = + CSAllocatableExt::witness_from_set_of_values(query); + + let mut guard = oracle.inner.write().expect("not poisoned"); + guard.push_callstack_witness(&query, current_depth, execute); + drop(guard); + }, + ); + + // and update registers following our ABI rules + + let new_r1 = final_fat_ptr.into_register(cs); + + let one = Num::allocated_constant(cs, F::ONE); + + let r2_low = Num::fma( + cs, + &Num::from_variable(far_call_abi.constructor_call.get_variable()), + &one, + &F::ONE, + &Num::from_variable(far_call_abi.system_call.get_variable()), + &F::TWO, + ); + + let r2_low = unsafe { UInt32::from_variable_unchecked(r2_low.get_variable()) }; + + let new_r2 = VMRegister { + is_pointer: boolean_false, + value: UInt256 { + inner: [ + r2_low, zero_u32, zero_u32, zero_u32, zero_u32, zero_u32, zero_u32, zero_u32, + ], + }, + }; + + let mut specific_registers_updates = [None; REGISTERS_COUNT]; + specific_registers_updates[0] = Some((execute, new_r1)); + specific_registers_updates[1] = Some((execute, new_r2)); + + let non_system_call = far_call_abi.system_call.negated(cs); + let cleanup_register = Boolean::multi_and(cs, &[execute, non_system_call]); + + let mut register_zero_out = [None; REGISTERS_COUNT]; + + for reg_idx in zkevm_opcode_defs::definitions::far_call::CALL_SYSTEM_ABI_REGISTERS { + register_zero_out[reg_idx as usize] = Some(cleanup_register); + } + for reg_idx in zkevm_opcode_defs::definitions::far_call::CALL_RESERVED_RANGE { + register_zero_out[reg_idx as usize] = Some(execute); + } + register_zero_out + [zkevm_opcode_defs::definitions::far_call::CALL_IMPLICIT_PARAMETER_REG_IDX as usize] = + Some(execute); + + // erase markers everywhere anyway + let mut erase_ptr_markers = [None; REGISTERS_COUNT]; + + for reg_idx in zkevm_opcode_defs::definitions::far_call::CALL_SYSTEM_ABI_REGISTERS { + erase_ptr_markers[reg_idx as usize] = Some(execute); + } + for reg_idx in zkevm_opcode_defs::definitions::far_call::CALL_RESERVED_RANGE { + erase_ptr_markers[reg_idx as usize] = Some(execute); + } + erase_ptr_markers + [zkevm_opcode_defs::definitions::far_call::CALL_IMPLICIT_PARAMETER_REG_IDX as usize] = + Some(execute); + + // if we didn't decommit for ANY reason then we will have target memory page == UNMAPPED PAGE, that will trigger panic + let full_data = FarCallData { + apply_far_call: execute, + old_context: current_callstack_entry, + new_context: new_callstack_entry, + new_decommittment_queue_tail, + new_decommittment_queue_len, + new_forward_queue_tail, + new_forward_queue_len, + new_memory_pages_counter, + pending_sponges: all_pending_sponges, + specific_registers_updates, + specific_registers_zeroing: register_zero_out, + remove_ptr_on_specific_registers: erase_ptr_markers, + pending_exception: exception, + }; + + if crate::config::CIRCUIT_VERSOBE { + if (execute.witness_hook(&*cs))().unwrap_or(false) { + println!( + "New frame as a result of FAR CALL: {:?}", + full_data.new_context.witness_hook(cs)() + ); + } + } + + full_data +} + +// We read code hash from the storage if we have enough ergs, and mask out +// a case if code hash is 0 into either default AA or 0 if destination is kernel +pub fn may_be_read_code_hash< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, + W: WitnessOracle, +>( + cs: &mut CS, + relations_buffer: &mut ArrayVec< + ( + Boolean, + [Num; FULL_SPONGE_QUEUE_STATE_WIDTH], + [Num; FULL_SPONGE_QUEUE_STATE_WIDTH], + ), + MAX_SPONGES_PER_CYCLE, + >, + call_target: &UInt160, + shard_id: &UInt8, + target_is_zkporter: &Boolean, + zkporter_is_available: &Boolean, + should_execute: &Boolean, + default_aa_code_hash: &UInt256, + target_is_kernel: &Boolean, + forward_queue_tail: [Num; QUEUE_STATE_WIDTH], + forward_queue_length: UInt32, + timestamp_to_use_for_read_request: UInt32, + tx_number_in_block: UInt32, + witness_oracle: &SynchronizedWitnessOracle, + round_function: &R, +) -> ( + Boolean, + UInt256, + ([Num; QUEUE_STATE_WIDTH], UInt32), +) +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + let target_is_porter_and_its_available = + Boolean::multi_and(cs, &[*target_is_zkporter, *zkporter_is_available]); + let target_is_rollup = target_is_zkporter.negated(cs); + let zkporter_is_not_available = zkporter_is_available.negated(cs); + + let can_read = Boolean::multi_or(cs, &[target_is_rollup, target_is_porter_and_its_available]); + let should_read = Boolean::multi_and(cs, &[*should_execute, can_read]); + let needs_porter_mask = + Boolean::multi_and(cs, &[*target_is_zkporter, zkporter_is_not_available]); + + let zero_u32 = UInt32::zero(cs); + let target_as_u256 = UInt256 { + inner: [ + call_target.inner[0], + call_target.inner[1], + call_target.inner[2], + call_target.inner[3], + call_target.inner[4], + zero_u32, + zero_u32, + zero_u32, + ], + }; + + let deployer_contract_address_low = UInt32::allocated_constant( + cs, + zkevm_opcode_defs::system_params::DEPLOYER_SYSTEM_CONTRACT_ADDRESS_LOW as u32, + ); + let deployer_contract_address = UInt160 { + inner: [ + deployer_contract_address_low, + zero_u32, + zero_u32, + zero_u32, + zero_u32, + ], + }; + + let zero_u256 = UInt256::zero(cs); + let boolean_false = Boolean::allocated_constant(cs, false); + let aux_byte_for_storage = UInt8::allocated_constant(cs, STORAGE_AUX_BYTE); + + let mut log = LogQuery { + address: deployer_contract_address, + key: target_as_u256, + read_value: zero_u256, + written_value: zero_u256, + rw_flag: boolean_false, + aux_byte: aux_byte_for_storage, + rollback: boolean_false, + is_service: boolean_false, + shard_id: *shard_id, + tx_number_in_block, + timestamp: timestamp_to_use_for_read_request, + }; + + let oracle = witness_oracle.clone(); + // we should assemble all the dependencies here, and we will use AllocateExt here + let mut dependencies = + Vec::with_capacity( as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 2); + dependencies.push(should_read.get_variable().into()); + dependencies.push(should_execute.get_variable().into()); + dependencies.extend(Place::from_variables(log.flatten_as_variables())); + + // we always access witness, as even for writes we have to get a claimed read value! + let read_value = UInt256::allocate_from_closure_and_dependencies( + cs, + move |inputs: &[F]| { + let is_storage = >::cast_from_source(inputs[0]); + let execute = >::cast_from_source(inputs[1]); + let mut log_query = + [F::ZERO; as CSAllocatableExt>::INTERNAL_STRUCT_LEN]; + log_query.copy_from_slice(&inputs[2..]); + let log_query: LogQueryWitness = + CSAllocatableExt::witness_from_set_of_values(log_query); + + let mut guard = oracle.inner.write().expect("not poisoned"); + let witness = guard.get_storage_read_witness(&log_query, is_storage, execute); + drop(guard); + + witness + }, + &dependencies, + ); + + log.read_value = read_value; + log.written_value = read_value; // our convension as in LOG opcode + + let code_hash_from_storage = read_value; + + let mut bytecode_hash = code_hash_from_storage; + let limbs_are_zero = bytecode_hash.inner.map(|el| el.is_zero(cs)); + let bytecode_is_empty = Boolean::multi_and(cs, &limbs_are_zero); + + let target_is_userspace = target_is_kernel.negated(cs); + let mask_for_default_aa = + Boolean::multi_and(cs, &[should_read, bytecode_is_empty, target_is_userspace]); + + // mask based on some conventions + // first - mask for default AA + bytecode_hash = UInt256::conditionally_select( + cs, + mask_for_default_aa, + &default_aa_code_hash, + &bytecode_hash, + ); + + // - if we couldn't read porter + bytecode_hash = + UInt256::conditionally_select(cs, needs_porter_mask, &zero_u256, &bytecode_hash); + + let dont_mask_to_default_aa = mask_for_default_aa.negated(cs); + let t0 = Boolean::multi_and(cs, &[bytecode_is_empty, dont_mask_to_default_aa]); + let skip_read = should_read.negated(cs); + let bytecode_hash_is_trivial = Boolean::multi_or(cs, &[t0, needs_porter_mask, skip_read]); + + // now process the sponges on whether we did read + let (new_forward_queue_tail, new_forward_queue_length) = + construct_hash_relations_code_hash_read( + cs, + relations_buffer, + &log, + &forward_queue_tail, + &forward_queue_length, + &should_read, + round_function, + ); + + let new_forward_queue_tail = Num::parallel_select( + cs, + should_read, + &new_forward_queue_tail, + &forward_queue_tail, + ); + + ( + bytecode_hash_is_trivial, + bytecode_hash, + (new_forward_queue_tail, new_forward_queue_length), + ) +} + +fn construct_hash_relations_code_hash_read< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, +>( + cs: &mut CS, + relations_buffer: &mut ArrayVec< + ( + Boolean, + [Num; FULL_SPONGE_QUEUE_STATE_WIDTH], + [Num; FULL_SPONGE_QUEUE_STATE_WIDTH], + ), + MAX_SPONGES_PER_CYCLE, + >, + log: &LogQuery, + forward_queue_tail: &[Num; 4], + forward_queue_length: &UInt32, + should_read: &Boolean, + _round_function: &R, +) -> ([Num; 4], UInt32) { + // we absort with replacement + + let mut current_state = R::create_empty_state(cs); + // TODO: may be decide on length specialization + use boojum::gadgets::traits::encodable::CircuitEncodable; + + let forward_packed_log = log.encode(cs); + + // NOTE: since we do merged call/ret, we simulate proper relations here always, + // because we will do join enforcement on call/ret + + let boolean_true = Boolean::allocated_constant(cs, true); + + // absorb by replacement + let round_0_initial = [ + forward_packed_log[0], + forward_packed_log[1], + forward_packed_log[2], + forward_packed_log[3], + forward_packed_log[4], + forward_packed_log[5], + forward_packed_log[6], + forward_packed_log[7], + current_state[8], + current_state[9], + current_state[10], + current_state[11], + ]; + + use boojum::gadgets::round_function::simulate_round_function; + + let round_0_final = + simulate_round_function::<_, _, 8, 12, 4, R>(cs, round_0_initial, boolean_true); + + current_state = round_0_final; + + // absorb by replacement + let round_1_initial = [ + forward_packed_log[8], + forward_packed_log[9], + forward_packed_log[10], + forward_packed_log[11], + forward_packed_log[12], + forward_packed_log[13], + forward_packed_log[14], + forward_packed_log[15], + current_state[8], + current_state[9], + current_state[10], + current_state[11], + ]; + + let round_1_final = + simulate_round_function::<_, _, 8, 12, 4, R>(cs, round_1_initial, boolean_true); + + current_state = round_1_final; + + // absorb by replacement + let round_2_initial = [ + forward_packed_log[16], + forward_packed_log[17], + forward_packed_log[18], + forward_packed_log[19], + forward_queue_tail[0].get_variable(), + forward_queue_tail[1].get_variable(), + forward_queue_tail[2].get_variable(), + forward_queue_tail[3].get_variable(), + current_state[8], + current_state[9], + current_state[10], + current_state[11], + ]; + + let round_2_final = + simulate_round_function::<_, _, 8, 12, 4, R>(cs, round_2_initial, boolean_true); + + let new_forward_queue_tail = [ + round_2_final[0], + round_2_final[1], + round_2_final[2], + round_2_final[3], + ]; + + let new_forward_queue_length_candidate = + unsafe { forward_queue_length.increment_unchecked(cs) }; + let new_forward_queue_length = UInt32::conditionally_select( + cs, + *should_read, + &new_forward_queue_length_candidate, + &forward_queue_length, + ); + + relations_buffer.push(( + *should_read, + round_0_initial.map(|el| Num::from_variable(el)), + round_0_final.map(|el| Num::from_variable(el)), + )); + + relations_buffer.push(( + *should_read, + round_1_initial.map(|el| Num::from_variable(el)), + round_1_final.map(|el| Num::from_variable(el)), + )); + + relations_buffer.push(( + *should_read, + round_2_initial.map(|el| Num::from_variable(el)), + round_2_final.map(|el| Num::from_variable(el)), + )); + + ( + new_forward_queue_tail.map(|el| Num::from_variable(el)), + new_forward_queue_length, + ) +} + +pub fn add_to_decommittment_queue< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, + W: WitnessOracle, +>( + cs: &mut CS, + relations_buffer: &mut ArrayVec< + ( + Boolean, + [Num; FULL_SPONGE_QUEUE_STATE_WIDTH], + [Num; FULL_SPONGE_QUEUE_STATE_WIDTH], + ), + MAX_SPONGES_PER_CYCLE, + >, + should_decommit: &Boolean, + ergs_remaining: &UInt32, + bytecode_hash: &UInt256, + num_words_in_bytecode: &UInt16, + current_decommittment_queue_tail: &[Num; FULL_SPONGE_QUEUE_STATE_WIDTH], + current_decommittment_queue_len: &UInt32, + timestamp_to_use_for_decommittment_request: &UInt32, + target_memory_page: &UInt32, + witness_oracle: &SynchronizedWitnessOracle, + _round_function: &R, +) -> ( + Boolean, + UInt32, + ([Num; FULL_SPONGE_QUEUE_STATE_WIDTH], UInt32), + UInt32, +) +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + // compute any associated extra costs + + let cost_of_decommit_per_word = + UInt32::allocated_constant(cs, zkevm_opcode_defs::ERGS_PER_CODE_WORD_DECOMMITTMENT); + let num_words_in_bytecode = + unsafe { UInt32::from_variable_unchecked(num_words_in_bytecode.get_variable()) }; + + let cost_of_decommittment = + cost_of_decommit_per_word.non_widening_mul(cs, &num_words_in_bytecode); + + let (ergs_after_decommit_may_be, uf) = + ergs_remaining.overflowing_sub(cs, cost_of_decommittment); + + let not_enough_ergs_to_decommit = uf; + let have_enough_ergs_to_decommit = uf.negated(cs); + let should_decommit = Boolean::multi_and(cs, &[*should_decommit, have_enough_ergs_to_decommit]); + + // if we do not decommit then we will eventually map into 0 page for 0 extra ergs + let ergs_remaining_after_decommit = UInt32::conditionally_select( + cs, + should_decommit, + &ergs_after_decommit_may_be, + &ergs_remaining, + ); + + if crate::config::CIRCUIT_VERSOBE { + if should_decommit.witness_hook(&*cs)().unwrap() { + dbg!(num_words_in_bytecode.witness_hook(&*cs)().unwrap()); + dbg!(ergs_after_decommit_may_be.witness_hook(&*cs)().unwrap()); + dbg!(ergs_remaining_after_decommit.witness_hook(&*cs)().unwrap()); + } + } + + // decommit and return new code page and queue states + + let boolean_false = Boolean::allocated_constant(cs, false); + + let mut decommittment_request = DecommitQuery { + code_hash: *bytecode_hash, + page: *target_memory_page, + is_first: boolean_false, + timestamp: *timestamp_to_use_for_decommittment_request, + }; + + let oracle = witness_oracle.clone(); + // we should assemble all the dependencies here, and we will use AllocateExt here + let mut dependencies = + Vec::with_capacity( as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1); + dependencies.push(should_decommit.get_variable().into()); + dependencies.extend(Place::from_variables( + decommittment_request.flatten_as_variables(), + )); + + // we always access witness, as even for writes we have to get a claimed read value! + let suggested_page = UInt32::allocate_from_closure_and_dependencies( + cs, + move |inputs: &[F]| { + let should_decommit = >::cast_from_source(inputs[0]); + + let mut query = + [F::ZERO; as CSAllocatableExt>::INTERNAL_STRUCT_LEN]; + query.copy_from_slice(&inputs[1..]); + let query: DecommitQueryWitness = + CSAllocatableExt::witness_from_set_of_values(query); + + let mut guard = oracle.inner.write().expect("not poisoned"); + let witness = guard.get_decommittment_request_suggested_page(&query, should_decommit); + drop(guard); + + witness + }, + &dependencies, + ); + + let is_first = UInt32::equals(cs, &target_memory_page, &suggested_page); + + decommittment_request.is_first = is_first; + decommittment_request.page = suggested_page; + + // kind of refund if we didn't decommit + + let was_decommitted_before = is_first.negated(cs); + + let refund = Boolean::multi_and(cs, &[should_decommit, was_decommitted_before]); + + let ergs_remaining_after_decommit = + UInt32::conditionally_select(cs, refund, &ergs_remaining, &ergs_remaining_after_decommit); + + use boojum::gadgets::traits::encodable::CircuitEncodable; + + let encoded_request = decommittment_request.encode(cs); + // absorb by replacement + let initial_state = [ + encoded_request[0], + encoded_request[1], + encoded_request[2], + encoded_request[3], + encoded_request[4], + encoded_request[5], + encoded_request[6], + encoded_request[7], + current_decommittment_queue_tail[8].get_variable(), + current_decommittment_queue_tail[9].get_variable(), + current_decommittment_queue_tail[10].get_variable(), + current_decommittment_queue_tail[11].get_variable(), + ]; + + use boojum::gadgets::round_function::simulate_round_function; + + // NOTE: since we do merged call/ret, we simulate proper relations here always, + // because we will do join enforcement on call/ret + + let final_state = + simulate_round_function::<_, _, 8, 12, 4, R>(cs, initial_state, should_decommit); + + relations_buffer.push(( + should_decommit, + initial_state.map(|el| Num::from_variable(el)), + final_state.map(|el| Num::from_variable(el)), + )); + + let final_state = final_state.map(|el| Num::from_variable(el)); + + let new_decommittment_queue_tail = Num::parallel_select( + cs, + should_decommit, + &final_state, + ¤t_decommittment_queue_tail, + ); + + let new_decommittment_queue_len_candidate = + unsafe { current_decommittment_queue_len.increment_unchecked(cs) }; + let new_decommittment_queue_len = UInt32::conditionally_select( + cs, + should_decommit, + &new_decommittment_queue_len_candidate, + ¤t_decommittment_queue_len, + ); + // we use `should_decommit` as a marker that we did actually execute both read and decommittment (whether fresh or not) + + let target_memory_page = decommittment_request.page; + let unmapped_page = UInt32::allocated_constant(cs, UNMAPPED_PAGE); + let target_memory_page = + UInt32::conditionally_select(cs, should_decommit, &target_memory_page, &unmapped_page); + + ( + not_enough_ergs_to_decommit, + target_memory_page, + (new_decommittment_queue_tail, new_decommittment_queue_len), + ergs_remaining_after_decommit, + ) +} diff --git a/crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/mod.rs b/crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/mod.rs new file mode 100644 index 0000000..6f2b175 --- /dev/null +++ b/crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/mod.rs @@ -0,0 +1,86 @@ +use crate::main_vm::register_input_view::RegisterInputView; + +use super::*; +use cs_derive::*; + +pub mod far_call; +pub mod near_call; +pub mod ret; + +pub use self::far_call::*; +pub use self::near_call::*; +pub use self::ret::*; + +#[derive(Derivative)] +#[derivative(Clone, Copy, Debug)] + +pub(crate) struct ForwardingModeABI { + pub(crate) forwarding_mode_byte: UInt8, +} + +impl ForwardingModeABI { + pub fn from_register_view>( + _cs: &mut CS, + input: &RegisterInputView, + ) -> Self { + // higher parts of highest 64 bits + let forwarding_mode_byte = input.u8x32_view + [zkevm_opcode_defs::definitions::abi::far_call::FAR_CALL_FORWARDING_MODE_BYTE_IDX]; + + let new = Self { + forwarding_mode_byte, + }; + + new + } +} + +pub(crate) fn compute_shared_abi_parts>( + cs: &mut CS, + src0_view: &RegisterInputView, +) -> ( + CommonCallRetABI, + FarCallPartialABI, + CallRetForwardingMode, +) { + let far_call_abi = FarCallPartialABI::from_register_view(cs, src0_view); + let forwarding_mode_abi = ForwardingModeABI::from_register_view(cs, &src0_view); + // we can share some checks + + let use_aux_heap_marker = + UInt8::allocated_constant(cs, FarCallForwardPageType::UseAuxHeap as u8); + let forward_fat_pointer_marker = + UInt8::allocated_constant(cs, FarCallForwardPageType::ForwardFatPointer as u8); + + let call_ret_use_aux_heap = UInt8::equals( + cs, + &forwarding_mode_abi.forwarding_mode_byte, + &use_aux_heap_marker, + ); + let call_ret_forward_fat_pointer = UInt8::equals( + cs, + &forwarding_mode_abi.forwarding_mode_byte, + &forward_fat_pointer_marker, + ); + let call_ret_use_heap = + Boolean::multi_or(cs, &[call_ret_use_aux_heap, call_ret_forward_fat_pointer]).negated(cs); + + let do_not_forward_ptr = call_ret_forward_fat_pointer.negated(cs); + + let (fat_ptr, upper_bound, ptr_validation_data) = + FatPtrInABI::parse_and_validate(cs, src0_view, do_not_forward_ptr); + + let common_parts = CommonCallRetABI { + fat_ptr, + upper_bound, + ptr_validation_data, + }; + + let forwarding_mode = CallRetForwardingMode { + use_heap: call_ret_use_heap, + use_aux_heap: call_ret_use_aux_heap, + forward_fat_pointer: call_ret_forward_fat_pointer, + }; + + (common_parts, far_call_abi, forwarding_mode) +} diff --git a/crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/near_call.rs b/crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/near_call.rs new file mode 100644 index 0000000..54a57ed --- /dev/null +++ b/crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/near_call.rs @@ -0,0 +1,184 @@ +use super::*; + +use crate::base_structures::vm_state::saved_context::ExecutionContextRecord; +use crate::base_structures::vm_state::saved_context::ExecutionContextRecordWitness; +use crate::main_vm::witness_oracle::SynchronizedWitnessOracle; +use crate::main_vm::witness_oracle::WitnessOracle; +use boojum::gadgets::traits::allocatable::CSAllocatable; +use boojum::gadgets::traits::allocatable::CSAllocatableExt; +use boojum::gadgets::traits::castable::WitnessCastable; + +#[derive(Derivative, CSAllocatable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +pub(crate) struct NearCallData { + pub(crate) apply_near_call: Boolean, + pub(crate) old_context: ExecutionContextRecord, + pub(crate) new_context: ExecutionContextRecord, + // we do not need to change queues on call +} + +struct NearCallABI { + ergs_passed: UInt32, +} + +use crate::main_vm::register_input_view::RegisterInputView; + +impl NearCallABI { + fn from_register_view(input: &RegisterInputView) -> Self { + Self { + ergs_passed: input.u32x8_view[0], + } + } +} + +pub(crate) fn callstack_candidate_for_near_call< + F: SmallField, + CS: ConstraintSystem, + W: WitnessOracle, +>( + cs: &mut CS, + draft_vm_state: &VmLocalState, + common_opcode_state: &CommonOpcodeState, + opcode_carry_parts: &AfterDecodingCarryParts, + witness_oracle: &SynchronizedWitnessOracle, +) -> NearCallData +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + // new callstack should be just the same a the old one, but we also need to update the pricing for pubdata in the rare case + const NEAR_CALL_OPCODE: zkevm_opcode_defs::Opcode = + zkevm_opcode_defs::Opcode::NearCall(zkevm_opcode_defs::NearCallOpcode); + + let execute = common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_opcode(NEAR_CALL_OPCODE); + + if crate::config::CIRCUIT_VERSOBE { + if (execute.witness_hook(&*cs))().unwrap_or(false) { + println!("Applying NEAR CALL"); + } + } + + let mut current_callstack_entry = draft_vm_state.callstack.current_context.saved_context; + + // perform all known modifications, like PC/SP saving + current_callstack_entry.pc = opcode_carry_parts.next_pc; + + // for NEAR CALL the next callstack entry is largely the same + let mut new_callstack_entry = current_callstack_entry.clone(); + // on call-like path we continue the forward queue, but have to allocate the rollback queue state from witness + let call_timestamp = draft_vm_state.timestamp; + + let oracle = witness_oracle.clone(); + let dependencies = [ + execute.get_variable().into(), + call_timestamp.get_variable().into(), + ]; + let potential_rollback_queue_segment_tail = + Num::allocate_multiple_from_closure_and_dependencies( + cs, + move |inputs: &[F]| { + let execute = >::cast_from_source(inputs[0]); + let timestamp = >::cast_from_source(inputs[1]); + + let mut guard = oracle.inner.write().expect("not poisoned"); + let witness = guard.get_rollback_queue_tail_witness_for_call(timestamp, execute); + drop(guard); + + witness + }, + &dependencies, + ); + + let zero_u32 = UInt32::zero(cs); + + new_callstack_entry.reverted_queue_tail = potential_rollback_queue_segment_tail; + new_callstack_entry.reverted_queue_head = potential_rollback_queue_segment_tail; + new_callstack_entry.reverted_queue_segment_len = zero_u32; + + let dst_pc = common_opcode_state.decoded_opcode.imm0; + let eh_pc = common_opcode_state.decoded_opcode.imm1; + + let near_call_abi = NearCallABI::from_register_view(&common_opcode_state.src0_view); + let pass_all_ergs = near_call_abi.ergs_passed.is_zero(cs); + + let preliminary_ergs_left = opcode_carry_parts.preliminary_ergs_left; + + // we did spend some ergs on decoding, so we use one from prestate + let ergs_to_pass = UInt32::conditionally_select( + cs, + pass_all_ergs, + &preliminary_ergs_left, + &near_call_abi.ergs_passed, + ); + + let (remaining_for_this_context, uf) = preliminary_ergs_left.overflowing_sub(cs, ergs_to_pass); + + let remaining_ergs_if_pass = remaining_for_this_context; + let passed_ergs_if_pass = ergs_to_pass; + + // if underflow than we pass everything! + let remaining_ergs_if_pass = + UInt32::conditionally_select(cs, uf, &zero_u32, &remaining_ergs_if_pass); + + let passed_ergs_if_pass = + UInt32::conditionally_select(cs, uf, &preliminary_ergs_left, &passed_ergs_if_pass); + + current_callstack_entry.ergs_remaining = remaining_ergs_if_pass; + + let oracle = witness_oracle.clone(); + let mut dependencies = Vec::with_capacity( + as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 2, + ); + dependencies.push(execute.get_variable().into()); + dependencies.push( + draft_vm_state + .callstack + .context_stack_depth + .get_variable() + .into(), + ); + dependencies.extend(Place::from_variables( + current_callstack_entry.flatten_as_variables(), + )); + + let _: [Num; 0] = Num::allocate_multiple_from_closure_and_dependencies( + cs, + move |inputs: &[F]| { + let execute = >::cast_from_source(inputs[0]); + let current_depth = >::cast_from_source(inputs[1]); + + let mut context = + [F::ZERO; as CSAllocatableExt>::INTERNAL_STRUCT_LEN]; + context.copy_from_slice(&inputs[2..]); + let context: ExecutionContextRecordWitness = + CSAllocatableExt::witness_from_set_of_values(context); + + let mut guard = oracle.inner.write().expect("not poisoned"); + guard.push_callstack_witness(&context, current_depth, execute); + drop(guard); + + [] + }, + &dependencies, + ); + + // --------------------- + // actually "apply" far call + + let boolean_true = Boolean::allocated_constant(cs, true); + + new_callstack_entry.ergs_remaining = passed_ergs_if_pass; + new_callstack_entry.pc = dst_pc; + new_callstack_entry.exception_handler_loc = eh_pc; + new_callstack_entry.is_local_call = boolean_true; + + let full_data = NearCallData { + apply_near_call: execute, + old_context: current_callstack_entry, + new_context: new_callstack_entry, + }; + + full_data +} diff --git a/crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/ret.rs b/crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/ret.rs new file mode 100644 index 0000000..6f9773e --- /dev/null +++ b/crates/zkevm_circuits/src/main_vm/opcodes/call_ret_impl/ret.rs @@ -0,0 +1,463 @@ +use crate::base_structures::{register::VMRegister, vm_state::FULL_SPONGE_QUEUE_STATE_WIDTH}; +use boojum::config::*; +use boojum::cs::traits::cs::DstBuffer; + +use super::*; + +use crate::base_structures::vm_state::saved_context::ExecutionContextRecord; +use crate::base_structures::vm_state::QUEUE_STATE_WIDTH; +use crate::main_vm::witness_oracle::SynchronizedWitnessOracle; +use crate::main_vm::witness_oracle::WitnessOracle; +use boojum::gadgets::traits::allocatable::CSAllocatableExt; + +use arrayvec::ArrayVec; + +pub(crate) struct RetData { + pub(crate) apply_ret: Boolean, + pub(crate) is_panic: Boolean, + pub(crate) did_return_from_far_call: Boolean, + pub(crate) originally_popped_context: ExecutionContextRecord, + pub(crate) new_context: ExecutionContextRecord, + pub(crate) previous_callstack_state: [Num; FULL_SPONGE_QUEUE_STATE_WIDTH], + pub(crate) new_forward_queue_tail: [Num; QUEUE_STATE_WIDTH], // after we glue + pub(crate) new_forward_queue_len: UInt32, + pub(crate) specific_registers_updates: [Option<(Boolean, VMRegister)>; REGISTERS_COUNT], + pub(crate) specific_registers_zeroing: [Option>; REGISTERS_COUNT], + pub(crate) remove_ptr_on_specific_registers: [Option>; REGISTERS_COUNT], +} + +pub(crate) fn callstack_candidate_for_ret< + F: SmallField, + CS: ConstraintSystem, + W: WitnessOracle, +>( + cs: &mut CS, + draft_vm_state: &VmLocalState, + common_opcode_state: &CommonOpcodeState, + opcode_carry_parts: &AfterDecodingCarryParts, + witness_oracle: &SynchronizedWitnessOracle, + common_abi_parts: &CommonCallRetABI, + forwarding_data: &CallRetForwardingMode, +) -> RetData +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + // new callstack should be just the same a the old one, but we also need to update the pricing for pubdata in the rare case + const RET_OPCODE: zkevm_opcode_defs::Opcode = + zkevm_opcode_defs::Opcode::Ret(zkevm_opcode_defs::RetOpcode::Ok); + + let execute = common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_opcode(RET_OPCODE); + + let is_ret_ok = common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(zkevm_opcode_defs::Opcode::Ret( + zkevm_opcode_defs::RetOpcode::Ok, + )); + // revert and panic are different only in ABI: whether we zero-out any hints (returndata) about why we reverted or not + let is_ret_revert = common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(zkevm_opcode_defs::Opcode::Ret( + zkevm_opcode_defs::RetOpcode::Revert, + )); + let is_ret_panic = common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(zkevm_opcode_defs::Opcode::Ret( + zkevm_opcode_defs::RetOpcode::Panic, + )); + + let is_local_frame = draft_vm_state + .callstack + .current_context + .saved_context + .is_local_call; + + if crate::config::CIRCUIT_VERSOBE { + if execute.witness_hook(&*cs)().unwrap_or(false) { + println!("Applying RET"); + if is_local_frame.witness_hook(&*cs)().unwrap_or(false) { + println!("Is local RET"); + } else { + println!("Is global RET"); + } + + if is_ret_ok.witness_hook(&*cs)().unwrap_or(false) { + println!("Applying RET Ok"); + } + if is_ret_revert.witness_hook(&*cs)().unwrap_or(false) { + println!("Applying RET Revert"); + } + if is_ret_panic.witness_hook(&*cs)().unwrap_or(false) { + println!("Applying RET Panic"); + } + } + } + + let current_callstack_entry = draft_vm_state.callstack.current_context.saved_context; + + // we may want to return to label + let is_to_label = common_opcode_state + .decoded_opcode + .properties_bits + .flag_booleans[zkevm_opcode_defs::ret::RET_TO_LABEL_BIT_IDX]; + + let label_pc = common_opcode_state.decoded_opcode.imm0; + + let current_depth = draft_vm_state.callstack.context_stack_depth; + + // it's a composite allocation, so we handwrite it + + let (mut new_callstack_entry, previous_callstack_state) = { + // this applies necessary constraints + let raw_callstack_entry = ExecutionContextRecord::create_without_value(cs); + let raw_previous_callstack_state = + cs.alloc_multiple_variables_without_values::(); + + if ::WitnessConfig::EVALUATE_WITNESS { + let oracle = witness_oracle.clone(); + + let dependencies = [ + current_depth.get_variable().into(), + execute.get_variable().into(), + ]; + + let mut outputs_to_set = Vec::with_capacity( + as CSAllocatableExt>::INTERNAL_STRUCT_LEN + + FULL_SPONGE_QUEUE_STATE_WIDTH, + ); + outputs_to_set.extend(Place::from_variables( + raw_callstack_entry.flatten_as_variables(), + )); + outputs_to_set.extend(Place::from_variables(raw_previous_callstack_state)); + + cs.set_values_with_dependencies_vararg( + &dependencies, + &outputs_to_set, + move |inputs: &[F], buffer: &mut DstBuffer<'_, '_, F>| { + let callstack_depth = + >::cast_from_source(inputs[0]); + let execute = >::cast_from_source(inputs[1]); + + let mut guard = oracle.inner.write().expect("not poisoned"); + let (record_witness, previous_state) = + guard.get_callstack_witness(execute, callstack_depth); + drop(guard); + + ExecutionContextRecord::set_internal_variables_values(record_witness, buffer); + buffer.extend(previous_state); + }, + ); + } + + let previous_callstack_state = + raw_previous_callstack_state.map(|el| Num::from_variable(el)); + + (raw_callstack_entry, previous_callstack_state) + }; + + let originally_popped_context = new_callstack_entry; + + // pass back all the ergs (after we paid the cost of "ret" itself), + // with may be a small charge for memory growth + let preliminary_ergs_left = opcode_carry_parts.preliminary_ergs_left; + + // resolve some exceptions over fat pointer use and memory growth + + // exceptions that are specific only to return from non-local frame + let mut non_local_frame_exceptions = ArrayVec::, 4>::new(); + + let forward_fat_pointer = forwarding_data.forward_fat_pointer; + let src0_is_integer = common_opcode_state.src0_view.is_ptr.negated(cs); + let is_far_return = is_local_frame.negated(cs); + + // resolve returndata pointer if forwarded + let fat_ptr_expected_exception = + Boolean::multi_and(cs, &[forward_fat_pointer, src0_is_integer, is_far_return]); + non_local_frame_exceptions.push(fat_ptr_expected_exception); + + let do_not_forward_ptr = forward_fat_pointer.negated(cs); + + // we also want unidirectional movement of returndata + // check if fat_ptr.memory_page < ctx.base_page and throw if it's the case + let (_, uf) = common_abi_parts.fat_ptr.page.overflowing_sub( + cs, + draft_vm_state + .callstack + .current_context + .saved_context + .base_page, + ); + + // if we try to forward then we should be unidirectional + let non_unidirectional_forwarding = Boolean::multi_and(cs, &[forward_fat_pointer, uf]); + + non_local_frame_exceptions.push(non_unidirectional_forwarding); + + non_local_frame_exceptions.push(is_ret_panic); // just feed it here as a shorthand + + let exceptions_collapsed = Boolean::multi_or(cs, &non_local_frame_exceptions); + + let fat_ptr = common_abi_parts + .fat_ptr + .mask_into_empty(cs, exceptions_collapsed); + + // now we can modify fat ptr that is prevalidated + + let fat_ptr_adjusted_if_forward = fat_ptr.readjust(cs); + + let page = UInt32::conditionally_select( + cs, + forwarding_data.use_heap, + &opcode_carry_parts.heap_page, + &opcode_carry_parts.aux_heap_page, + ); + + let zero_u32 = UInt32::zero(cs); + + let fat_ptr_for_heaps = FatPtrInABI { + offset: zero_u32, + page, + start: fat_ptr.start, + length: fat_ptr.length, + }; + + let fat_ptr = FatPtrInABI::conditionally_select( + cs, + forwarding_data.forward_fat_pointer, + &fat_ptr_adjusted_if_forward, + &fat_ptr_for_heaps, + ); + + // potentially pay for memory growth + + let memory_region_is_not_addressable = common_abi_parts.ptr_validation_data.is_non_addressable; + let upper_bound = common_abi_parts.upper_bound; + // first mask to 0 if exceptions happened + let upper_bound = upper_bound.mask_negated(cs, exceptions_collapsed); + // then compute to penalize for out of memory access attemp + + // and penalize if pointer is fresh and not addressable + let penalize_heap_overflow = + Boolean::multi_and(cs, &[memory_region_is_not_addressable, do_not_forward_ptr]); + let u32_max = UInt32::allocated_constant(cs, u32::MAX); + + let upper_bound = + UInt32::conditionally_select(cs, penalize_heap_overflow, &u32_max, &upper_bound); + + let heap_max_accessed = upper_bound.mask(cs, forwarding_data.use_heap); + let heap_bound = current_callstack_entry.heap_upper_bound; + let (mut heap_growth, uf) = heap_max_accessed.overflowing_sub(cs, heap_bound); + heap_growth = heap_growth.mask_negated(cs, uf); // of we access in bounds then it's 0 + let grow_heap = Boolean::multi_and(cs, &[forwarding_data.use_heap, execute, is_far_return]); + + let aux_heap_max_accessed = upper_bound.mask(cs, forwarding_data.use_aux_heap); + let aux_heap_bound = current_callstack_entry.aux_heap_upper_bound; + let (mut aux_heap_growth, uf) = aux_heap_max_accessed.overflowing_sub(cs, aux_heap_bound); + aux_heap_growth = aux_heap_growth.mask_negated(cs, uf); // of we access in bounds then it's 0 + let grow_aux_heap = + Boolean::multi_and(cs, &[forwarding_data.use_aux_heap, execute, is_far_return]); + + let mut growth_cost = heap_growth.mask(cs, grow_heap); + growth_cost = UInt32::conditionally_select(cs, grow_aux_heap, &aux_heap_growth, &growth_cost); + + // subtract + + let (ergs_left_after_growth, uf) = preliminary_ergs_left.overflowing_sub(cs, growth_cost); + + let mut non_local_frame_exceptions = ArrayVec::, 4>::new(); + non_local_frame_exceptions.push(exceptions_collapsed); + + let ergs_left_after_growth = ergs_left_after_growth.mask_negated(cs, uf); // if not enough - set to 0 + non_local_frame_exceptions.push(uf); + + let ergs_left_after_growth = UInt32::conditionally_select( + cs, + is_local_frame, + &preliminary_ergs_left, + &ergs_left_after_growth, + ); + + non_local_frame_exceptions.push(is_ret_panic); + + let non_local_frame_panic = Boolean::multi_or(cs, &non_local_frame_exceptions); + let non_local_frame_panic = Boolean::multi_and(cs, &[non_local_frame_panic, is_far_return]); + let final_fat_ptr = fat_ptr.mask_into_empty(cs, non_local_frame_panic); + + // ----------------------------------------- + + let new_ergs_left = + ergs_left_after_growth.add_no_overflow(cs, new_callstack_entry.ergs_remaining); + + new_callstack_entry.ergs_remaining = new_ergs_left; + + // resolve merging of the queues + + // most likely it's the most interesting amount all the tricks that are pulled by this VM + + // During the execution we maintain the following queue segments of what is usually called a "storage log", that is basically a sequence of bookkeeped + // storage, events, precompiles, etc accesses + // - global "forward" queue - all the changes (both rollbackable and not (read-like)) go in there, and it's "global" per block + // - frame-specific "reverts" queue, where we put "canceling" state updates for all "write-like" things, like storage write, event, + // l1 message, etc. E.g. precompilecall is pure function and doesn't rollback, and we add nothing to this segment + // When frame ends we have to decide whether we discard it's changes or not. So we can do either: + // - if frame does NOT revert then we PREPEND all the changes in "rollback" segment to the rollback segment of the parent queue + // - if frame DOES revert, then we APPEND all the changes from "rollback" to the global "forward" segment + // It's easy to notice that this behavior is: + // - local O(1): only things like heads/tails of the queues are updated. Changes do accumulate along the O(N) potential changes in a frame, but + // then we can apply it O(1) + // - recursively consistent as one would expect it: if this frame does NOT revert, but parent REVERTS, then all the changes are rolled back! + + // Why one can not do simpler and just memorize the state of some "forward" queue on frame entry and return to it when revert happens? Because we can have + // a code like + // if (SLOAD(x)) { + // revert(0, 0) + // } else { + // .. something useful + // } + + // then we branch on result of SLOAD, but it is not observable (we discarded everything in "forward" queue)! So it can be maliciously manipulated! + + // if we revert then we should append rollback to forward + // if we return ok then we should prepend to the rollback of the parent + + let should_perform_revert = + Boolean::multi_or(cs, &[is_ret_revert, is_ret_panic, non_local_frame_panic]); + let perform_revert = Boolean::multi_and(cs, &[execute, should_perform_revert]); + + for (a, b) in current_callstack_entry.reverted_queue_head.iter().zip( + draft_vm_state + .callstack + .current_context + .log_queue_forward_tail + .iter(), + ) { + Num::conditionally_enforce_equal(cs, perform_revert, a, b); + } + + let new_forward_queue_len_if_revert = draft_vm_state + .callstack + .current_context + .log_queue_forward_part_length + .add_no_overflow(cs, current_callstack_entry.reverted_queue_segment_len); + + let no_exceptions = non_local_frame_panic.negated(cs); + + let should_perform_ret_ok = Boolean::multi_and(cs, &[execute, is_ret_ok, no_exceptions]); + + for (a, b) in new_callstack_entry + .reverted_queue_head + .iter() + .zip(current_callstack_entry.reverted_queue_tail.iter()) + { + Num::conditionally_enforce_equal(cs, should_perform_ret_ok, a, b); + } + + let new_rollback_queue_len_if_ok = new_callstack_entry + .reverted_queue_segment_len + .add_no_overflow(cs, current_callstack_entry.reverted_queue_segment_len); + + // update forward queue + + let new_forward_queue_tail = Num::parallel_select( + cs, + should_perform_revert, // it's only true if we DO execute and DO revert + ¤t_callstack_entry.reverted_queue_tail, + &draft_vm_state + .callstack + .current_context + .log_queue_forward_tail, + ); + + let new_forward_queue_len = UInt32::conditionally_select( + cs, + should_perform_revert, + &new_forward_queue_len_if_revert, + &draft_vm_state + .callstack + .current_context + .log_queue_forward_part_length, + ); + + // update rollback queue of the parent + let new_rollback_queue_head = Num::parallel_select( + cs, + should_perform_ret_ok, // it's only true if we DO execute and DO return ok + ¤t_callstack_entry.reverted_queue_head, + &new_callstack_entry.reverted_queue_head, + ); + + let new_rollback_queue_len = UInt32::conditionally_select( + cs, + should_perform_ret_ok, + &new_rollback_queue_len_if_ok, + &new_callstack_entry.reverted_queue_segment_len, + ); + + new_callstack_entry.reverted_queue_head = new_rollback_queue_head; + new_callstack_entry.reverted_queue_segment_len = new_rollback_queue_len; + + // we ignore label if we return from the root, of course + let should_use_label = Boolean::multi_and(cs, &[is_to_label, is_local_frame]); + + // Candidates for PC to return to + let ok_ret_pc = + UInt16::conditionally_select(cs, should_use_label, &label_pc, &new_callstack_entry.pc); + // but EH is stored in the CURRENT context + let eh_pc = UInt16::conditionally_select( + cs, + should_use_label, + &label_pc, + ¤t_callstack_entry.exception_handler_loc, + ); + + let dst_pc = UInt16::conditionally_select(cs, perform_revert, &eh_pc, &ok_ret_pc); + + new_callstack_entry.pc = dst_pc; + + // and update registers following our ABI rules + + // everything goes into r1, and the rest is cleared + let new_r1 = final_fat_ptr.into_register(cs); + let update_specific_registers_on_ret = Boolean::multi_and(cs, &[execute, is_far_return]); + + let mut specific_registers_updates = [None; REGISTERS_COUNT]; + specific_registers_updates[0] = Some((update_specific_registers_on_ret, new_r1)); + + let is_panic = Boolean::multi_or(cs, &[is_ret_panic, non_local_frame_panic]); + + // the rest is cleared on far return + + let mut register_zero_out = [None; REGISTERS_COUNT]; + + for reg_idx in 1..REGISTERS_COUNT { + register_zero_out[reg_idx as usize] = Some(update_specific_registers_on_ret); + } + + // erase markers everywhere anyway + let mut erase_ptr_markers = [None; REGISTERS_COUNT]; + + for reg_idx in 1..REGISTERS_COUNT { + erase_ptr_markers[reg_idx as usize] = Some(update_specific_registers_on_ret); + } + + let full_data = RetData { + apply_ret: execute, + is_panic: is_panic, + did_return_from_far_call: is_far_return, + new_context: new_callstack_entry, + originally_popped_context, + previous_callstack_state, + new_forward_queue_tail, + new_forward_queue_len, + specific_registers_updates, + specific_registers_zeroing: register_zero_out, + remove_ptr_on_specific_registers: erase_ptr_markers, + }; + + full_data +} diff --git a/crates/zkevm_circuits/src/main_vm/opcodes/context.rs b/crates/zkevm_circuits/src/main_vm/opcodes/context.rs new file mode 100644 index 0000000..69b3f8e --- /dev/null +++ b/crates/zkevm_circuits/src/main_vm/opcodes/context.rs @@ -0,0 +1,307 @@ +use boojum::gadgets::u256::UInt256; + +use crate::base_structures::register::VMRegister; + +use super::*; + +pub(crate) fn apply_context>( + cs: &mut CS, + draft_vm_state: &VmLocalState, + common_opcode_state: &CommonOpcodeState, + opcode_carry_parts: &AfterDecodingCarryParts, + diffs_accumulator: &mut StateDiffsAccumulator, +) { + const GET_THIS_ADDRESS_OPCODE: zkevm_opcode_defs::Opcode = zkevm_opcode_defs::Opcode::Context( + zkevm_opcode_defs::definitions::context::ContextOpcode::This, + ); + const GET_CALLER_ADDRESS_OPCODE: zkevm_opcode_defs::Opcode = zkevm_opcode_defs::Opcode::Context( + zkevm_opcode_defs::definitions::context::ContextOpcode::Caller, + ); + const GET_CODE_ADDRESS_OPCODE: zkevm_opcode_defs::Opcode = zkevm_opcode_defs::Opcode::Context( + zkevm_opcode_defs::definitions::context::ContextOpcode::CodeAddress, + ); + const GET_META_OPCODE: zkevm_opcode_defs::Opcode = zkevm_opcode_defs::Opcode::Context( + zkevm_opcode_defs::definitions::context::ContextOpcode::Meta, + ); + const GET_ERGS_LEFT_OPCODE: zkevm_opcode_defs::Opcode = zkevm_opcode_defs::Opcode::Context( + zkevm_opcode_defs::definitions::context::ContextOpcode::ErgsLeft, + ); + const GET_SP_OPCODE: zkevm_opcode_defs::Opcode = zkevm_opcode_defs::Opcode::Context( + zkevm_opcode_defs::definitions::context::ContextOpcode::Sp, + ); + const GET_CONTEXT_U128_OPCODE: zkevm_opcode_defs::Opcode = zkevm_opcode_defs::Opcode::Context( + zkevm_opcode_defs::definitions::context::ContextOpcode::GetContextU128, + ); + // attempt to execute in non-kernel mode for this opcode would be caught before + const SET_CONTEXT_U128_OPCODE: zkevm_opcode_defs::Opcode = zkevm_opcode_defs::Opcode::Context( + zkevm_opcode_defs::definitions::context::ContextOpcode::SetContextU128, + ); + const SET_PUBDATA_ERGS_OPCODE: zkevm_opcode_defs::Opcode = zkevm_opcode_defs::Opcode::Context( + zkevm_opcode_defs::definitions::context::ContextOpcode::SetErgsPerPubdataByte, + ); + const INCREMENT_TX_NUMBER_OPCODE: zkevm_opcode_defs::Opcode = + zkevm_opcode_defs::Opcode::Context( + zkevm_opcode_defs::definitions::context::ContextOpcode::IncrementTxNumber, + ); + + let should_apply = { + common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_opcode(GET_THIS_ADDRESS_OPCODE) + }; + + let is_retrieve_this = { + common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(GET_THIS_ADDRESS_OPCODE) + }; + let is_retrieve_caller = { + common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(GET_CALLER_ADDRESS_OPCODE) + }; + let is_retrieve_code_address = { + common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(GET_CODE_ADDRESS_OPCODE) + }; + let is_retrieve_meta = { + common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(GET_META_OPCODE) + }; + let is_retrieve_ergs_left = { + common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(GET_ERGS_LEFT_OPCODE) + }; + let _is_retrieve_sp = { + common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(GET_SP_OPCODE) + }; + let is_get_context_u128 = { + common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(GET_CONTEXT_U128_OPCODE) + }; + let is_set_context_u128 = { + common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(SET_CONTEXT_U128_OPCODE) + }; + let is_set_pubdata_ergs = { + common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(SET_PUBDATA_ERGS_OPCODE) + }; + let is_inc_tx_num = { + common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(INCREMENT_TX_NUMBER_OPCODE) + }; + + let write_to_context = Boolean::multi_and(cs, &[should_apply, is_set_context_u128]); + let set_pubdata_ergs = Boolean::multi_and(cs, &[should_apply, is_set_pubdata_ergs]); + let increment_tx_counter = Boolean::multi_and(cs, &[should_apply, is_inc_tx_num]); + + // write in regards of dst0 register + let read_only = Boolean::multi_or( + cs, + &[is_set_context_u128, is_set_pubdata_ergs, is_inc_tx_num], + ); + let write_like = read_only.negated(cs); + + let write_to_dst0 = Boolean::multi_and(cs, &[should_apply, write_like]); + + let potentially_new_ergs_for_pubdata = common_opcode_state.src0_view.u32x8_view[0]; + + let one_u32 = UInt32::allocated_constant(cs, 1u32); + let (incremented_tx_number, _of) = draft_vm_state + .tx_number_in_block + .overflowing_add(cs, one_u32); + + let context_composite_to_set = [ + common_opcode_state.src0_view.u32x8_view[0], + common_opcode_state.src0_view.u32x8_view[1], + common_opcode_state.src0_view.u32x8_view[2], + common_opcode_state.src0_view.u32x8_view[3], + ]; + + let zero_u32 = UInt32::zero(cs); + let zero_u8 = UInt8::zero(cs); + + let meta_highest_u32 = UInt32::from_le_bytes( + cs, + [ + draft_vm_state + .callstack + .current_context + .saved_context + .this_shard_id, + draft_vm_state + .callstack + .current_context + .saved_context + .caller_shard_id, + draft_vm_state + .callstack + .current_context + .saved_context + .code_shard_id, + zero_u8, + ], + ); + + let meta_as_register = UInt256 { + inner: [ + draft_vm_state.ergs_per_pubdata_byte, + zero_u32, // reserved + draft_vm_state + .callstack + .current_context + .saved_context + .heap_upper_bound, + draft_vm_state + .callstack + .current_context + .saved_context + .aux_heap_upper_bound, + zero_u32, // reserved + zero_u32, // reserved + zero_u32, // reserved + meta_highest_u32, + ], + }; + + // now we will select in the growding width manner + + let low_u32_to_get_sp = unsafe { + UInt32::from_variable_unchecked( + draft_vm_state + .callstack + .current_context + .saved_context + .sp + .get_variable(), + ) + }; + + let low_u32_ergs_left = opcode_carry_parts.preliminary_ergs_left; + + let low_u32 = UInt32::conditionally_select( + cs, + is_retrieve_ergs_left, + &low_u32_ergs_left, + &low_u32_to_get_sp, + ); + + // now we have context + + let mut result_128 = [low_u32, zero_u32, zero_u32, zero_u32]; + + result_128 = UInt32::parallel_select( + cs, + is_get_context_u128, + &draft_vm_state + .callstack + .current_context + .saved_context + .context_u128_value_composite, + &result_128, + ); + + // then we have address-like values + + let mut result_160 = [ + result_128[0], + result_128[1], + result_128[2], + result_128[3], + zero_u32, + ]; + + result_160 = UInt32::parallel_select( + cs, + is_retrieve_this, + &draft_vm_state + .callstack + .current_context + .saved_context + .this + .inner, + &result_160, + ); + + result_160 = UInt32::parallel_select( + cs, + is_retrieve_caller, + &draft_vm_state + .callstack + .current_context + .saved_context + .caller + .inner, + &result_160, + ); + + result_160 = UInt32::parallel_select( + cs, + is_retrieve_code_address, + &draft_vm_state + .callstack + .current_context + .saved_context + .code_address + .inner, + &result_160, + ); + + // and finally full register for meta + + let mut result_256 = [ + result_160[0], + result_160[1], + result_160[2], + result_160[3], + result_160[4], + zero_u32, + zero_u32, + zero_u32, + ]; + + result_256 = + UInt32::parallel_select(cs, is_retrieve_meta, &meta_as_register.inner, &result_256); + + let boolean_false = Boolean::allocated_constant(cs, false); + + let dst0 = VMRegister { + is_pointer: boolean_false, + value: UInt256 { inner: result_256 }, + }; + let can_write_into_memory = + GET_THIS_ADDRESS_OPCODE.can_write_dst0_into_memory(SUPPORTED_ISA_VERSION); + diffs_accumulator + .dst_0_values + .push((can_write_into_memory, write_to_dst0, dst0)); + + diffs_accumulator + .context_u128_candidates + .push((write_to_context, context_composite_to_set)); + debug_assert!(diffs_accumulator.new_tx_number.is_none()); + diffs_accumulator.new_tx_number = Some((increment_tx_counter, incremented_tx_number)); + debug_assert!(diffs_accumulator.new_ergs_per_pubdata.is_none()); + diffs_accumulator.new_ergs_per_pubdata = + Some((set_pubdata_ergs, potentially_new_ergs_for_pubdata)); +} diff --git a/crates/zkevm_circuits/src/main_vm/opcodes/jump.rs b/crates/zkevm_circuits/src/main_vm/opcodes/jump.rs new file mode 100644 index 0000000..a14751a --- /dev/null +++ b/crates/zkevm_circuits/src/main_vm/opcodes/jump.rs @@ -0,0 +1,38 @@ +use super::*; + +pub(crate) fn apply_jump>( + cs: &mut CS, + _draft_vm_state: &VmLocalState, + common_opcode_state: &CommonOpcodeState, + _opcode_carry_parts: &AfterDecodingCarryParts, + diffs_accumulator: &mut StateDiffsAccumulator, +) { + const JUMP_OPCODE: zkevm_opcode_defs::Opcode = + zkevm_opcode_defs::Opcode::Jump(zkevm_opcode_defs::definitions::jump::JumpOpcode); + + let should_apply = common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_opcode(JUMP_OPCODE); + + if crate::config::CIRCUIT_VERSOBE { + if (should_apply.witness_hook(&*cs))().unwrap_or(false) { + println!("Applying JUMP"); + } + } + + // main point of merging add/sub is to enforce single add/sub relation, that doesn't leak into any + // other opcodes + + let jump_dst = UInt16::from_le_bytes( + cs, + [ + common_opcode_state.src0_view.u8x32_view[0], + common_opcode_state.src0_view.u8x32_view[1], + ], + ); + + diffs_accumulator + .new_pc_candidates + .push((should_apply, jump_dst)); +} diff --git a/crates/zkevm_circuits/src/main_vm/opcodes/log.rs b/crates/zkevm_circuits/src/main_vm/opcodes/log.rs new file mode 100644 index 0000000..83b3338 --- /dev/null +++ b/crates/zkevm_circuits/src/main_vm/opcodes/log.rs @@ -0,0 +1,667 @@ +use boojum::gadgets::u256::UInt256; + +use crate::base_structures::{ + log_query::{self, LogQuery, LOG_QUERY_PACKED_WIDTH, ROLLBACK_PACKING_FLAG_VARIABLE_IDX}, + register::VMRegister, +}; + +use super::*; +use crate::main_vm::opcodes::log::log_query::LogQueryWitness; +use crate::main_vm::witness_oracle::SynchronizedWitnessOracle; +use crate::main_vm::witness_oracle::WitnessOracle; +use boojum::algebraic_props::round_function::AlgebraicRoundFunction; +use boojum::gadgets::traits::allocatable::CSAllocatableExt; +use boojum::gadgets::traits::round_function::CircuitRoundFunction; + +pub(crate) fn apply_log< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, + W: WitnessOracle, +>( + cs: &mut CS, + draft_vm_state: &VmLocalState, + common_opcode_state: &CommonOpcodeState, + opcode_carry_parts: &AfterDecodingCarryParts, + diffs_accumulator: &mut StateDiffsAccumulator, + witness_oracle: &SynchronizedWitnessOracle, + round_function: &R, +) where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + const STORAGE_READ_OPCODE: zkevm_opcode_defs::Opcode = + zkevm_opcode_defs::Opcode::Log(LogOpcode::StorageRead); + const STORAGE_WRITE_OPCODE: zkevm_opcode_defs::Opcode = + zkevm_opcode_defs::Opcode::Log(LogOpcode::StorageWrite); + const L1_MESSAGE_OPCODE: zkevm_opcode_defs::Opcode = + zkevm_opcode_defs::Opcode::Log(LogOpcode::ToL1Message); + const EVENT_OPCODE: zkevm_opcode_defs::Opcode = + zkevm_opcode_defs::Opcode::Log(LogOpcode::Event); + const PRECOMPILE_CALL_OPCODE: zkevm_opcode_defs::Opcode = + zkevm_opcode_defs::Opcode::Log(LogOpcode::PrecompileCall); + + let should_apply = common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_opcode(STORAGE_READ_OPCODE); + + let is_storage_read = { + common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(STORAGE_READ_OPCODE) + }; + let is_storage_write = { + common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(STORAGE_WRITE_OPCODE) + }; + let is_event = { + common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(EVENT_OPCODE) + }; + let is_l1_message = { + common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(L1_MESSAGE_OPCODE) + }; + let is_precompile = { + common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(PRECOMPILE_CALL_OPCODE) + }; + + if crate::config::CIRCUIT_VERSOBE { + if should_apply.witness_hook(&*cs)().unwrap_or(false) { + println!("Applying LOG"); + if is_storage_read.witness_hook(&*cs)().unwrap_or(false) { + println!("SLOAD"); + } + if is_storage_write.witness_hook(&*cs)().unwrap_or(false) { + println!("SSTORE"); + } + if is_event.witness_hook(&*cs)().unwrap_or(false) { + println!("EVENT"); + } + if is_l1_message.witness_hook(&*cs)().unwrap_or(false) { + println!("L2 to L1 message"); + } + if is_precompile.witness_hook(&*cs)().unwrap_or(false) { + println!("PRECOMPILECALL"); + } + } + } + + let address = draft_vm_state.callstack.current_context.saved_context.this; + + let mut key = UInt256 { + inner: common_opcode_state.src0_view.u32x8_view, + }; + let written_value = UInt256 { + inner: common_opcode_state.src1_view.u32x8_view, + }; + + // modify the key by replacing parts for precompile call + let precompile_memory_page_to_read = opcode_carry_parts.heap_page; + let precompile_memory_page_to_write = opcode_carry_parts.heap_page; + // replace bits 128..160 and 160..192 + key.inner[4] = UInt32::conditionally_select( + cs, + is_precompile, + &precompile_memory_page_to_read, + &key.inner[4], + ); + key.inner[5] = UInt32::conditionally_select( + cs, + is_precompile, + &precompile_memory_page_to_write, + &key.inner[5], + ); + + use zkevm_opcode_defs::system_params::{ + INITIAL_STORAGE_WRITE_PUBDATA_BYTES, L1_MESSAGE_PUBDATA_BYTES, + }; + + let is_rollup = draft_vm_state + .callstack + .current_context + .saved_context + .this_shard_id + .is_zero(cs); + let write_to_rollup = Boolean::multi_and(cs, &[is_rollup, is_storage_write]); + + let emit_l1_message = is_l1_message; + + let l1_message_pubdata_bytes_constnt = + UInt32::allocated_constant(cs, L1_MESSAGE_PUBDATA_BYTES as u32); + let ergs_to_burn_for_l1_message = draft_vm_state + .ergs_per_pubdata_byte + .non_widening_mul(cs, &l1_message_pubdata_bytes_constnt); + + let ergs_to_burn_for_precompile_call = common_opcode_state.src1_view.u32x8_view[0]; + + let is_storage_access = Boolean::multi_or(cs, &[is_storage_read, is_storage_write]); + let is_nonrevertable = Boolean::multi_or(cs, &[is_storage_read, is_precompile]); + let is_revertable = is_nonrevertable.negated(cs); + + let aux_byte_variable = Num::linear_combination( + cs, + &[ + ( + is_storage_access.get_variable(), + F::from_u64_unchecked(zkevm_opcode_defs::system_params::STORAGE_AUX_BYTE as u64), + ), + ( + is_event.get_variable(), + F::from_u64_unchecked(zkevm_opcode_defs::system_params::EVENT_AUX_BYTE as u64), + ), + ( + is_l1_message.get_variable(), + F::from_u64_unchecked(zkevm_opcode_defs::system_params::L1_MESSAGE_AUX_BYTE as u64), + ), + ( + is_precompile.get_variable(), + F::from_u64_unchecked(zkevm_opcode_defs::system_params::PRECOMPILE_AUX_BYTE as u64), + ), + ], + ) + .get_variable(); + + let aux_byte = unsafe { UInt8::from_variable_unchecked(aux_byte_variable) }; + let timestamp = common_opcode_state.timestamp_for_first_decommit_or_precompile_read; + + let shard_id = draft_vm_state + .callstack + .current_context + .saved_context + .this_shard_id; + + // NOTE: our opcodes encoding guarantees that there is no "storage read + is first" + // variant encodable + let is_event_init = { + common_opcode_state + .decoded_opcode + .properties_bits + .flag_booleans[FIRST_MESSAGE_FLAG_IDX] + }; + + let zero_u256 = UInt256::zero(cs); + let boolean_false = Boolean::allocated_constant(cs, false); + let tx_number = draft_vm_state.tx_number_in_block; + + let mut log = LogQuery { + address, + key, + read_value: zero_u256, + written_value, + rw_flag: is_revertable, + aux_byte, + rollback: boolean_false, + is_service: is_event_init, + shard_id, + tx_number_in_block: tx_number, + timestamp, + }; + + let oracle = witness_oracle.clone(); + // we should assemble all the dependencies here, and we will use AllocateExt here + let mut dependencies = + Vec::with_capacity( as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 2); + dependencies.push(is_storage_write.get_variable().into()); + dependencies.push(should_apply.get_variable().into()); + dependencies.extend(Place::from_variables(log.flatten_as_variables())); + + let pubdata_refund = UInt32::allocate_from_closure_and_dependencies( + cs, + move |inputs: &[F]| { + let is_write = >::cast_from_source(inputs[0]); + let execute = >::cast_from_source(inputs[1]); + let mut log_query = + [F::ZERO; as CSAllocatableExt>::INTERNAL_STRUCT_LEN]; + log_query.copy_from_slice(&inputs[2..]); + let log_query: LogQueryWitness = + CSAllocatableExt::witness_from_set_of_values(log_query); + + let mut guard = oracle.inner.write().expect("not poisoned"); + let witness = guard.get_refunds(&log_query, is_write, execute); + drop(guard); + + witness + }, + &dependencies, + ); + + let initial_storage_write_pubdata_bytes = + UInt32::allocated_constant(cs, INITIAL_STORAGE_WRITE_PUBDATA_BYTES as u32); + let net_cost = initial_storage_write_pubdata_bytes.sub_no_overflow(cs, pubdata_refund); + + let ergs_to_burn_for_rollup_storage_write = draft_vm_state + .ergs_per_pubdata_byte + .non_widening_mul(cs, &net_cost); + + let zero_u32 = UInt32::allocated_constant(cs, 0); + + // now we know net cost + let ergs_to_burn = UInt32::conditionally_select( + cs, + write_to_rollup, + &ergs_to_burn_for_rollup_storage_write, + &zero_u32, + ); + let ergs_to_burn = UInt32::conditionally_select( + cs, + is_precompile, + &ergs_to_burn_for_precompile_call, + &ergs_to_burn, + ); + let ergs_to_burn = UInt32::conditionally_select( + cs, + emit_l1_message, + &ergs_to_burn_for_l1_message, + &ergs_to_burn, + ); + + let (ergs_remaining, uf) = opcode_carry_parts + .preliminary_ergs_left + .overflowing_sub(cs, ergs_to_burn); + let not_enough_ergs_for_op = uf; + + // if not enough then leave only 0 + let ergs_remaining = ergs_remaining.mask_negated(cs, not_enough_ergs_for_op); + let have_enough_ergs = not_enough_ergs_for_op.negated(cs); + + let execute_either_in_practice = Boolean::multi_and(cs, &[should_apply, have_enough_ergs]); + + let oracle = witness_oracle.clone(); + // we should assemble all the dependencies here, and we will use AllocateExt here + let mut dependencies = + Vec::with_capacity( as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 2); + dependencies.push(is_storage_access.get_variable().into()); + dependencies.push(execute_either_in_practice.get_variable().into()); + dependencies.extend(Place::from_variables(log.flatten_as_variables())); + + // we always access witness, as even for writes we have to get a claimed read value! + let read_value = UInt256::allocate_from_closure_and_dependencies( + cs, + move |inputs: &[F]| { + let is_storage = >::cast_from_source(inputs[0]); + let execute = >::cast_from_source(inputs[1]); + let mut log_query = + [F::ZERO; as CSAllocatableExt>::INTERNAL_STRUCT_LEN]; + log_query.copy_from_slice(&inputs[2..]); + let log_query: LogQueryWitness = + CSAllocatableExt::witness_from_set_of_values(log_query); + + let mut guard = oracle.inner.write().expect("not poisoned"); + let witness = guard.get_storage_read_witness(&log_query, is_storage, execute); + drop(guard); + + witness + }, + &dependencies, + ); + + let u256_zero = UInt256::zero(cs); + + let read_value = UInt256::conditionally_select(cs, is_storage_access, &read_value, &u256_zero); + log.read_value = read_value.clone(); + // if we read then use the same value - convension! + log.written_value = + UInt256::conditionally_select(cs, log.rw_flag, &log.written_value, &log.read_value); + + use boojum::gadgets::traits::encodable::CircuitEncodable; + let packed_log_forward = log.encode(cs); + + let mut packed_log_rollback = packed_log_forward; + LogQuery::update_packing_for_rollback(cs, &mut packed_log_rollback); + + let execute_rollback = Boolean::multi_and(cs, &[execute_either_in_practice, is_revertable]); + + let current_forward_tail = draft_vm_state + .callstack + .current_context + .log_queue_forward_tail; + let current_rollback_head = draft_vm_state + .callstack + .current_context + .saved_context + .reverted_queue_head; + + let oracle = witness_oracle.clone(); + let mut dependencies = + Vec::with_capacity( as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1); + dependencies.push(execute_rollback.get_variable().into()); + dependencies.extend(Place::from_variables(log.flatten_as_variables())); + + let prev_revert_head_witness = Num::allocate_multiple_from_closure_and_dependencies( + cs, + move |inputs: &[F]| { + let execute_rollback = >::cast_from_source(inputs[0]); + let mut log_query = + [F::ZERO; as CSAllocatableExt>::INTERNAL_STRUCT_LEN]; + log_query.copy_from_slice(&inputs[1..]); + let log_query: LogQueryWitness = + CSAllocatableExt::witness_from_set_of_values(log_query); + + let mut guard = oracle.inner.write().expect("not poisoned"); + let witness = guard.get_rollback_queue_witness(&log_query, execute_rollback); + drop(guard); + + witness + }, + &dependencies, + ); + + let (new_forward_queue_tail, new_rollback_queue_head, relations) = + construct_hash_relations_for_log_and_new_queue_states( + cs, + &packed_log_forward, + &packed_log_rollback, + ¤t_forward_tail, + &prev_revert_head_witness, + ¤t_rollback_head, + &execute_either_in_practice, + &execute_rollback, + round_function, + ); + + // add actual update of register in case of write + let register_value_if_storage_read = read_value; + + let mut precompile_call_result = u256_zero; + precompile_call_result.inner[0] = + unsafe { UInt32::from_variable_unchecked(have_enough_ergs.get_variable()) }; + + let register_value = UInt256::conditionally_select( + cs, + is_storage_read, + ®ister_value_if_storage_read, + &precompile_call_result, + ); + + let dst0 = VMRegister { + value: register_value, + is_pointer: boolean_false, + }; + + let old_forward_queue_length = draft_vm_state + .callstack + .current_context + .log_queue_forward_part_length; + + let new_forward_queue_length_candidate = + unsafe { old_forward_queue_length.increment_unchecked(cs) }; + let new_forward_queue_length = UInt32::conditionally_select( + cs, + execute_either_in_practice, + &new_forward_queue_length_candidate, + &old_forward_queue_length, + ); + + let old_revert_queue_length = draft_vm_state + .callstack + .current_context + .saved_context + .reverted_queue_segment_len; + + let new_revert_queue_length_candidate = + unsafe { old_revert_queue_length.increment_unchecked(cs) }; + let new_revert_queue_length = UInt32::conditionally_select( + cs, + execute_rollback, + &new_revert_queue_length_candidate, + &old_revert_queue_length, + ); + + let can_update_dst0 = Boolean::multi_or(cs, &[is_storage_read, is_precompile]); + let should_update_dst0 = Boolean::multi_and(cs, &[can_update_dst0, should_apply]); + + if crate::config::CIRCUIT_VERSOBE { + if should_apply.witness_hook(&*cs)().unwrap() { + dbg!(should_update_dst0.witness_hook(&*cs)().unwrap()); + dbg!(dst0.witness_hook(&*cs)().unwrap()); + } + } + + let can_write_into_memory = + STORAGE_READ_OPCODE.can_write_dst0_into_memory(SUPPORTED_ISA_VERSION); + diffs_accumulator + .dst_0_values + .push((can_write_into_memory, should_update_dst0, dst0)); + + diffs_accumulator.log_queue_forward_candidates.push(( + should_apply, + new_forward_queue_length, + new_forward_queue_tail, + )); + + diffs_accumulator.log_queue_rollback_candidates.push(( + should_apply, + new_revert_queue_length, + new_rollback_queue_head, + )); + + diffs_accumulator + .new_ergs_left_candidates + .push((should_apply, ergs_remaining)); + + assert!(STORAGE_READ_OPCODE.can_have_src0_from_mem(SUPPORTED_ISA_VERSION) == false); + assert!(STORAGE_READ_OPCODE.can_write_dst0_into_memory(SUPPORTED_ISA_VERSION) == false); + + diffs_accumulator + .sponge_candidates_to_run + .push((false, false, should_apply, relations)); +} + +use crate::base_structures::vm_state::FULL_SPONGE_QUEUE_STATE_WIDTH; +use crate::main_vm::state_diffs::MAX_SPONGES_PER_CYCLE; +use arrayvec::ArrayVec; + +fn construct_hash_relations_for_log_and_new_queue_states< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, +>( + cs: &mut CS, + forward_packed_log: &[Variable; LOG_QUERY_PACKED_WIDTH], + forward_rollback_log: &[Variable; LOG_QUERY_PACKED_WIDTH], + forward_queue_tail: &[Num; 4], + claimed_rollback_head: &[Num; 4], + current_rollback_head: &[Num; 4], + should_execute_either: &Boolean, + should_execute_rollback: &Boolean, + _round_function: &R, +) -> ( + [Num; 4], + [Num; 4], + ArrayVec< + ( + Boolean, + [Num; FULL_SPONGE_QUEUE_STATE_WIDTH], + [Num; FULL_SPONGE_QUEUE_STATE_WIDTH], + ), + MAX_SPONGES_PER_CYCLE, + >, +) { + // we should be clever and simultaneously produce 2 relations: + // - 2 common sponges for forward/rollback that only touch the encodings + // - 1 unique sponge for forward + // - 1 unique sponge for rollback + + // check that we only differ at the very end + for (a, b) in forward_packed_log[..ROLLBACK_PACKING_FLAG_VARIABLE_IDX] + .iter() + .zip(forward_rollback_log[..ROLLBACK_PACKING_FLAG_VARIABLE_IDX].iter()) + { + debug_assert_eq!(a, b); + } + + // we absort with replacement + + let mut current_state = R::create_empty_state(cs); + // TODO: may be decide on length specialization + + // absorb by replacement + let round_0_initial = [ + forward_packed_log[0], + forward_packed_log[1], + forward_packed_log[2], + forward_packed_log[3], + forward_packed_log[4], + forward_packed_log[5], + forward_packed_log[6], + forward_packed_log[7], + current_state[8], + current_state[9], + current_state[10], + current_state[11], + ]; + + use boojum::gadgets::round_function::simulate_round_function; + + let round_0_final = + simulate_round_function::<_, _, 8, 12, 4, R>(cs, round_0_initial, *should_execute_either); + + current_state = round_0_final; + + // absorb by replacement + let round_1_initial = [ + forward_packed_log[8], + forward_packed_log[9], + forward_packed_log[10], + forward_packed_log[11], + forward_packed_log[12], + forward_packed_log[13], + forward_packed_log[14], + forward_packed_log[15], + current_state[8], + current_state[9], + current_state[10], + current_state[11], + ]; + + let round_1_final = + simulate_round_function::<_, _, 8, 12, 4, R>(cs, round_1_initial, *should_execute_either); + + current_state = round_1_final; + + // absorb by replacement + let round_2_initial_forward = [ + forward_packed_log[16], + forward_packed_log[17], + forward_packed_log[18], + forward_packed_log[19], + forward_queue_tail[0].get_variable(), + forward_queue_tail[1].get_variable(), + forward_queue_tail[2].get_variable(), + forward_queue_tail[3].get_variable(), + current_state[8], + current_state[9], + current_state[10], + current_state[11], + ]; + + let forward_round_2_final = simulate_round_function::<_, _, 8, 12, 4, R>( + cs, + round_2_initial_forward, + *should_execute_either, + ); + + // absorb by replacement + let round_2_initial_rollback = [ + forward_rollback_log[16], + forward_rollback_log[17], + forward_rollback_log[18], + forward_rollback_log[19], + claimed_rollback_head[0].get_variable(), + claimed_rollback_head[1].get_variable(), + claimed_rollback_head[2].get_variable(), + claimed_rollback_head[3].get_variable(), + current_state[8], + current_state[9], + current_state[10], + current_state[11], + ]; + + let rollback_round_2_final = simulate_round_function::<_, _, 8, 12, 4, R>( + cs, + round_2_initial_rollback, + *should_execute_either, + ); // at the moment we do not mark which sponges are actually used and which are not + // in the opcode, so we properly simulate all of them + + let new_forward_tail_candidate = [ + forward_round_2_final[0], + forward_round_2_final[1], + forward_round_2_final[2], + forward_round_2_final[3], + ]; + + let new_forward_tail_candidate = new_forward_tail_candidate.map(|el| Num::from_variable(el)); + + let simulated_rollback_head = [ + rollback_round_2_final[0], + rollback_round_2_final[1], + rollback_round_2_final[2], + rollback_round_2_final[3], + ]; + + let simulated_rollback_head = simulated_rollback_head.map(|el| Num::from_variable(el)); + + // select forward + + let new_forward_queue_tail = Num::parallel_select( + cs, + *should_execute_either, + &new_forward_tail_candidate, + &forward_queue_tail, + ); + + // select rollback + + let new_rollback_queue_head = Num::parallel_select( + cs, + *should_execute_rollback, + &claimed_rollback_head, + ¤t_rollback_head, + ); + + for (a, b) in simulated_rollback_head + .iter() + .zip(current_rollback_head.iter()) + { + Num::conditionally_enforce_equal(cs, *should_execute_rollback, a, b); + } + + let mut relations = ArrayVec::new(); + relations.push(( + *should_execute_either, + round_0_initial.map(|el| Num::from_variable(el)), + round_0_final.map(|el| Num::from_variable(el)), + )); + + relations.push(( + *should_execute_either, + round_1_initial.map(|el| Num::from_variable(el)), + round_1_final.map(|el| Num::from_variable(el)), + )); + + relations.push(( + *should_execute_either, + round_2_initial_forward.map(|el| Num::from_variable(el)), + forward_round_2_final.map(|el| Num::from_variable(el)), + )); + + relations.push(( + *should_execute_rollback, + round_2_initial_rollback.map(|el| Num::from_variable(el)), + rollback_round_2_final.map(|el| Num::from_variable(el)), + )); + + (new_forward_queue_tail, new_rollback_queue_head, relations) +} diff --git a/crates/zkevm_circuits/src/main_vm/opcodes/mod.rs b/crates/zkevm_circuits/src/main_vm/opcodes/mod.rs new file mode 100644 index 0000000..48055e9 --- /dev/null +++ b/crates/zkevm_circuits/src/main_vm/opcodes/mod.rs @@ -0,0 +1,180 @@ +use super::*; +use crate::base_structures::vm_state::VmLocalState; +use crate::main_vm::opcode_bitmask::SUPPORTED_ISA_VERSION; +use crate::main_vm::pre_state::AfterDecodingCarryParts; +use crate::main_vm::pre_state::CommonOpcodeState; +use crate::main_vm::state_diffs::{ + StateDiffsAccumulator, MAX_U32_CONDITIONAL_RANGE_CHECKS_PER_CYCLE, +}; +use boojum::cs::gates::U8x4FMAGate; +use zkevm_opcode_defs::*; + +pub mod add_sub; +pub mod binop; +pub mod call_ret; +pub mod context; +pub mod jump; +pub mod log; +pub mod mul_div; +pub mod nop; +pub mod ptr; +pub mod shifts; +pub mod uma; + +pub(crate) mod call_ret_impl; + +pub use self::add_sub::*; +pub use self::binop::*; +pub use self::call_ret::*; +pub use self::context::*; +pub use self::jump::*; +pub use self::log::*; +pub use self::mul_div::*; +pub use self::nop::*; +pub use self::ptr::*; +pub use self::ptr::*; +pub use self::shifts::*; +pub use self::uma::*; + +pub struct AddSubRelation { + pub a: [UInt32; 8], + pub b: [UInt32; 8], + pub c: [UInt32; 8], + pub of: Boolean, +} + +impl Selectable for AddSubRelation { + fn conditionally_select>( + cs: &mut CS, + flag: Boolean, + a: &Self, + b: &Self, + ) -> Self { + let sel_a = UInt32::parallel_select(cs, flag, &a.a, &b.a); + let sel_b = UInt32::parallel_select(cs, flag, &a.b, &b.b); + let c = UInt32::parallel_select(cs, flag, &a.c, &b.c); + let of = Boolean::conditionally_select(cs, flag, &a.of, &b.of); + + Self { + a: sel_a, + b: sel_b, + c, + of, + } + } +} + +pub struct MulDivRelation { + pub a: [UInt32; 8], + pub b: [UInt32; 8], + pub rem: [UInt32; 8], + pub mul_low: [UInt32; 8], + pub mul_high: [UInt32; 8], +} + +impl Selectable for MulDivRelation { + fn conditionally_select>( + cs: &mut CS, + flag: Boolean, + a: &Self, + b: &Self, + ) -> Self { + let sel_a = UInt32::parallel_select(cs, flag, &a.a, &b.a); + let sel_b = UInt32::parallel_select(cs, flag, &a.b, &b.b); + let rem = UInt32::parallel_select(cs, flag, &a.rem, &b.rem); + let mul_low = UInt32::parallel_select(cs, flag, &a.mul_low, &b.mul_low); + let mul_high = UInt32::parallel_select(cs, flag, &a.mul_high, &b.mul_high); + + Self { + a: sel_a, + b: sel_b, + rem, + mul_low, + mul_high, + } + } +} + +use boojum::cs::gates::ConstantAllocatableCS; +use boojum::cs::gates::UIntXAddGate; + +pub(crate) fn enforce_addition_relation>( + cs: &mut CS, + relation: AddSubRelation, +) { + let AddSubRelation { a, b, c, of } = relation; + if cs.gate_is_allowed::>() { + let mut intermediate_of = cs.allocate_constant(F::ZERO); + + for ((a, b), c) in a.iter().zip(b.iter()).zip(c.iter()) { + intermediate_of = UIntXAddGate::<32>::enforce_add_relation_compute_carry( + cs, + a.get_variable(), + b.get_variable(), + intermediate_of, + c.get_variable(), + ); + } + + let intermediate_of = unsafe { Boolean::from_variable_unchecked(intermediate_of) }; + + Boolean::enforce_equal(cs, &intermediate_of, &of); + } else { + unimplemented!() + } +} + +// NOTE: fields `a`, `b` and `rem` will be range checked, and fields `mul_low` and `mul_high` are used +// only for equality check with guaranteed 32-bit results, so they are also range checked +pub(crate) fn enforce_mul_relation>( + cs: &mut CS, + relation: MulDivRelation, +) { + let MulDivRelation { + a, + b, + rem, + mul_low, + mul_high, + } = relation; + + // a * b + rem = mul_low + 2^256 * mul_high + + // in case of multiplication rem == 0, a and b are src0 and src1 + // in case of division a = quotient, b = src1, rem is remainder, mul_low = src0 + + if cs.gate_is_allowed::() { + let mut partial_result = [UInt32::zero(cs); 16]; + partial_result[0..8].copy_from_slice(&rem[0..8]); + for a_idx in 0..8 { + let mut intermidiate_overflow = UInt32::zero(cs); + for b_idx in 0..8 { + let [low_wrapped, high_wrapped] = UInt32::fma_with_carry( + cs, + a[a_idx], + b[b_idx], + partial_result[a_idx + b_idx], + intermidiate_overflow, + ); + partial_result[a_idx + b_idx] = low_wrapped.0; + intermidiate_overflow = high_wrapped.0; + } + // place end of chain + if a_idx + 8 < 16 { + partial_result[a_idx + 8] = + partial_result[a_idx + 8].add_no_overflow(cs, intermidiate_overflow); + } else { + let zero_num = Num::zero(cs); + Num::enforce_equal(cs, &zero_num, &intermidiate_overflow.into_num()); + } + } + for (lhs, rhs) in partial_result + .iter() + .zip(mul_low.iter().chain(mul_high.iter())) + { + Num::enforce_equal(cs, &lhs.into_num(), &rhs.into_num()) + } + } else { + unimplemented!() + } +} diff --git a/crates/zkevm_circuits/src/main_vm/opcodes/mul_div.rs b/crates/zkevm_circuits/src/main_vm/opcodes/mul_div.rs new file mode 100644 index 0000000..12261ae --- /dev/null +++ b/crates/zkevm_circuits/src/main_vm/opcodes/mul_div.rs @@ -0,0 +1,417 @@ +use self::ethereum_types::U256; +use super::*; + +use crate::base_structures::register::VMRegister; +use crate::base_structures::vm_state::ArithmeticFlagsPort; +use arrayvec::ArrayVec; +use boojum::gadgets::u256::{decompose_u256_as_u32x8, UInt256}; + +fn u256_from_limbs(limbs: &[F]) -> U256 { + debug_assert_eq!(limbs.len(), 8); + + let mut byte_array = [0u8; 32]; + for (dst, limb) in byte_array.array_chunks_mut::<4>().zip(limbs.iter()) { + *dst = (limb.as_u64_reduced() as u32).to_le_bytes(); + } + + U256::from_little_endian(&byte_array) +} + +pub fn allocate_mul_result_unchecked>( + cs: &mut CS, + a: &[UInt32; 8], + b: &[UInt32; 8], +) -> ([UInt32; 8], [UInt32; 8]) { + let limbs_low = cs.alloc_multiple_variables_without_values::<8>(); + let limbs_high = cs.alloc_multiple_variables_without_values::<8>(); + + if ::WitnessConfig::EVALUATE_WITNESS { + let value_fn = move |inputs: [F; 16]| { + let a = u256_from_limbs(&inputs[0..8]); + let b = u256_from_limbs(&inputs[8..16]); + let mut c_bytes = [0u8; 64]; + a.full_mul(b).to_little_endian(&mut c_bytes[..]); + + let mut outputs = [F::ZERO; 16]; + let mut byte_array = [0u8; 4]; + for (in_chunk, out_elem) in c_bytes.chunks(4).zip(outputs.iter_mut()) { + byte_array.copy_from_slice(in_chunk); + let as_u32 = u32::from_le_bytes(byte_array); + *out_elem = F::from_u64_unchecked(as_u32 as u64); + } + + outputs + }; + + let dependencies = Place::from_variables([ + a[0].get_variable(), + a[1].get_variable(), + a[2].get_variable(), + a[3].get_variable(), + a[4].get_variable(), + a[5].get_variable(), + a[6].get_variable(), + a[7].get_variable(), + b[0].get_variable(), + b[1].get_variable(), + b[2].get_variable(), + b[3].get_variable(), + b[4].get_variable(), + b[5].get_variable(), + b[6].get_variable(), + b[7].get_variable(), + ]); + let outputs = Place::from_variables([ + limbs_low[0], + limbs_low[1], + limbs_low[2], + limbs_low[3], + limbs_low[4], + limbs_low[5], + limbs_low[6], + limbs_low[7], + limbs_high[0], + limbs_high[1], + limbs_high[2], + limbs_high[3], + limbs_high[4], + limbs_high[5], + limbs_high[6], + limbs_high[7], + ]); + cs.set_values_with_dependencies(&dependencies, &outputs, value_fn); + } + + let limbs_low = limbs_low.map(|el| unsafe { UInt32::from_variable_unchecked(el) }); + let limbs_high = limbs_high.map(|el| unsafe { UInt32::from_variable_unchecked(el) }); + + (limbs_low, limbs_high) +} + +// by convention this function set remainder to the dividend if divisor is 0 to satisfy +// mul-div relation. Later in the code we set remainder to 0 in this case for convention +pub(crate) fn allocate_div_result_unchecked>( + cs: &mut CS, + a: &[UInt32; 8], + b: &[UInt32; 8], +) -> ([UInt32; 8], [UInt32; 8]) { + let quotient = cs.alloc_multiple_variables_without_values::<8>(); + let remainder = cs.alloc_multiple_variables_without_values::<8>(); + + if ::WitnessConfig::EVALUATE_WITNESS { + let value_fn = move |inputs: [F; 16]| { + let a = u256_from_limbs(&inputs[0..8]); + let b = u256_from_limbs(&inputs[8..16]); + + let (quotient, remainder) = if b.is_zero() { + (U256::zero(), a) + } else { + a.div_mod(b) + }; + + let mut outputs = [F::ZERO; 16]; + for (dst, src) in outputs[..8] + .iter_mut() + .zip(decompose_u256_as_u32x8(quotient).into_iter()) + { + *dst = F::from_u64_unchecked(src as u64); + } + for (dst, src) in outputs[8..] + .iter_mut() + .zip(decompose_u256_as_u32x8(remainder).into_iter()) + { + *dst = F::from_u64_unchecked(src as u64); + } + + outputs + }; + + let dependencies = Place::from_variables([ + a[0].get_variable(), + a[1].get_variable(), + a[2].get_variable(), + a[3].get_variable(), + a[4].get_variable(), + a[5].get_variable(), + a[6].get_variable(), + a[7].get_variable(), + b[0].get_variable(), + b[1].get_variable(), + b[2].get_variable(), + b[3].get_variable(), + b[4].get_variable(), + b[5].get_variable(), + b[6].get_variable(), + b[7].get_variable(), + ]); + let outputs = Place::from_variables([ + quotient[0], + quotient[1], + quotient[2], + quotient[3], + quotient[4], + quotient[5], + quotient[6], + quotient[7], + remainder[0], + remainder[1], + remainder[2], + remainder[3], + remainder[4], + remainder[5], + remainder[6], + remainder[7], + ]); + cs.set_values_with_dependencies(&dependencies, &outputs, value_fn); + } + + let quotient = quotient.map(|el| unsafe { UInt32::from_variable_unchecked(el) }); + let remainder = remainder.map(|el| unsafe { UInt32::from_variable_unchecked(el) }); + + (quotient, remainder) +} + +pub fn all_limbs_are_zero>( + cs: &mut CS, + limbs: &[UInt32; 8], +) -> Boolean { + let limb_is_zero = limbs.map(|el| el.is_zero(cs)); + let result_is_zero = Boolean::multi_and(cs, &limb_is_zero); + + result_is_zero +} + +pub fn all_limbs_are_equal>( + cs: &mut CS, + lhs: &[UInt32; 8], + rhs: &[UInt32; 8], +) -> Boolean { + let boolean_false = Boolean::allocated_constant(cs, false); + let mut flags = [boolean_false; 8]; + for ((lhs_limb, rhs_limb), out) in lhs.iter().zip(rhs.iter()).zip(flags.iter_mut()) { + *out = UInt32::equals(cs, lhs_limb, rhs_limb); + } + let result = Boolean::multi_and(cs, &flags); + + result +} + +pub(crate) fn apply_mul_div>( + cs: &mut CS, + _draft_vm_state: &VmLocalState, + common_opcode_state: &CommonOpcodeState, + _opcode_carry_parts: &AfterDecodingCarryParts, + diffs_accumulator: &mut StateDiffsAccumulator, +) { + const MUL_OPCODE: zkevm_opcode_defs::Opcode = + zkevm_opcode_defs::Opcode::Mul(zkevm_opcode_defs::MulOpcode); + const DIV_OPCODE: zkevm_opcode_defs::Opcode = + zkevm_opcode_defs::Opcode::Div(zkevm_opcode_defs::DivOpcode); + + let should_apply_mul = common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_opcode(MUL_OPCODE); + let should_apply_div = common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_opcode(DIV_OPCODE); + + if crate::config::CIRCUIT_VERSOBE { + if (should_apply_mul.witness_hook(&*cs))().unwrap_or(false) { + println!("Applying MUL"); + } + if (should_apply_div.witness_hook(&*cs))().unwrap_or(false) { + println!("Applying DIV"); + } + } + + let should_set_flags = common_opcode_state + .decoded_opcode + .properties_bits + .flag_booleans[SET_FLAGS_FLAG_IDX]; + + let src0_view = &common_opcode_state.src0_view.u32x8_view; + let src1_view = &common_opcode_state.src1_view.u32x8_view; + + let (mul_low_unchecked, mul_high_unchecked) = + allocate_mul_result_unchecked(cs, src0_view, src1_view); + let (quotient_unchecked, remainder_unchecked) = + allocate_div_result_unchecked(cs, src0_view, src1_view); + + // if crate::config::CIRCUIT_VERSOBE { + // if (should_apply_mul.witness_hook(&*cs))().unwrap_or(false) || (should_apply_div.witness_hook(&*cs))().unwrap_or(false) { + // dbg!(mul_low_unchecked.witness_hook(&*cs)().unwrap()); + // dbg!(mul_high_unchecked.witness_hook(&*cs)().unwrap()); + // dbg!(quotient_unchecked.witness_hook(&*cs)().unwrap()); + // dbg!(remainder_unchecked.witness_hook(&*cs)().unwrap()); + // } + // } + + // IMPORTANT: MulDiv relation is later enforced via `enforce_mul_relation` function, that effectively range-checks all the fields, + // so we do NOT need range checkes on anything that will go into MulDiv relation + let result_0 = UInt32::parallel_select( + cs, + should_apply_mul, + &mul_low_unchecked, + "ient_unchecked, + ); + let result_1 = UInt32::parallel_select( + cs, + should_apply_mul, + &mul_high_unchecked, + &remainder_unchecked, + ); + + // see below, but in short: + // - if we apply mul then `mul_low_unchecked` is checked as `mul_low_to_enforce`, and `mul_high_unchecked` as `mul_high_to_enforce` + // - if we apply div then `remainder_unchecked` is checked as `rem_to_enforce`, and `quotient_unchecked` as `a_to_enforce` + + // if we mull: src0 * src1 = mul_low + (mul_high << 256) => rem = 0, a = src0, b = src1, mul_low = mul_low, mul_high = mul_high + // if we divide: src0 = q * src1 + rem => rem = rem, a = quotient, b = src1, mul_low = src0, mul_high = 0 + let uint256_zero = UInt256::zero(cs); + + // note that if we do division, then remainder is range-checked by "result_1" above + let rem_to_enforce = UInt32::parallel_select( + cs, + should_apply_mul, + &uint256_zero.inner, + &remainder_unchecked, + ); + let a_to_enforce = + UInt32::parallel_select(cs, should_apply_mul, src0_view, "ient_unchecked); + let b_to_enforce = src1_view.clone(); + let mul_low_to_enforce = + UInt32::parallel_select(cs, should_apply_mul, &mul_low_unchecked, &src0_view); + let mul_high_to_enforce = UInt32::parallel_select( + cs, + should_apply_mul, + &mul_high_unchecked, + &uint256_zero.inner, + ); + + let mul_relation = MulDivRelation { + a: a_to_enforce, + b: b_to_enforce, + rem: rem_to_enforce, + mul_low: mul_low_to_enforce, + mul_high: mul_high_to_enforce, + }; + + // flags which are set in case of executing mul + let high_is_zero = all_limbs_are_zero(cs, &mul_high_unchecked); + let low_is_zero = all_limbs_are_zero(cs, &mul_low_unchecked); + let of_mul = high_is_zero.negated(cs); + let eq_mul = low_is_zero; + let gt_mul = { + let x = of_mul.negated(cs); + let y = eq_mul.negated(cs); + Boolean::multi_and(cs, &[x, y]) + }; + + // flags which are set in case of executing div + let divisor_is_zero = all_limbs_are_zero(cs, src1_view); + let divisor_is_non_zero = divisor_is_zero.negated(cs); + // check if quotient and remainder are 0 + let quotient_is_zero = all_limbs_are_zero(cs, "ient_unchecked); + let remainder_is_zero = all_limbs_are_zero(cs, &remainder_unchecked); + + // check that remainder is smaller than divisor + + // do remainder - divisor + let (subtraction_result_unchecked, remainder_is_less_than_divisor) = + allocate_subtraction_result_unchecked(cs, &remainder_unchecked, src1_view); + + // if we do division then remainder will be range checked, but not the subtraction result + let conditional_range_checks = subtraction_result_unchecked; + + // relation is a + b == c + of * 2^N, + // but we compute d - e + 2^N * borrow = f + + // so we need to shuffle + let addition_relation = AddSubRelation { + a: *src1_view, + b: subtraction_result_unchecked, + c: remainder_unchecked, + of: remainder_is_less_than_divisor, + }; + + // unless divisor is 0 (that we handle separately), + // we require that remainder is < divisor + remainder_is_less_than_divisor.conditionally_enforce_true(cs, divisor_is_non_zero); + + // if divisor is 0, then we assume quotient is zero + quotient_is_zero.conditionally_enforce_true(cs, divisor_is_zero); + // and by convention we set remainder to 0 if we divide by 0 + let mask_remainder_into_zero = Boolean::multi_and(cs, &[should_apply_div, divisor_is_zero]); + let result_1 = result_1.map(|el| el.mask_negated(cs, mask_remainder_into_zero)); + + let of_div = divisor_is_zero; + let eq_div = { + let x = divisor_is_zero.negated(cs); + Boolean::multi_and(cs, &[x, quotient_is_zero]) + }; + let gt_div = { + let y = divisor_is_zero.negated(cs); + Boolean::multi_and(cs, &[y, remainder_is_zero]) + }; + + let of = Boolean::conditionally_select(cs, should_apply_mul, &of_mul, &of_div); + let eq = Boolean::conditionally_select(cs, should_apply_mul, &eq_mul, &eq_div); + let gt = Boolean::conditionally_select(cs, should_apply_mul, >_mul, >_div); + + let candidate_flags = ArithmeticFlagsPort { + overflow_or_less_than: of, + equal: eq, + greater_than: gt, + }; + + let apply_any = Boolean::multi_or(cs, &[should_apply_mul, should_apply_div]); + let dst0 = VMRegister { + is_pointer: Boolean::allocated_constant(cs, false), + value: UInt256 { inner: result_0 }, + }; + let dst1 = VMRegister { + is_pointer: Boolean::allocated_constant(cs, false), + value: UInt256 { inner: result_1 }, + }; + + // if crate::config::CIRCUIT_VERSOBE { + // if (should_apply_mul.witness_hook(&*cs))().unwrap_or(false) || (should_apply_div.witness_hook(&*cs))().unwrap_or(false) { + // dbg!(result_0.witness_hook(&*cs)().unwrap()); + // dbg!(result_1.witness_hook(&*cs)().unwrap()); + // } + // } + + let can_write_into_memory = MUL_OPCODE.can_write_dst0_into_memory(SUPPORTED_ISA_VERSION); + debug_assert_eq!( + can_write_into_memory, + DIV_OPCODE.can_write_dst0_into_memory(SUPPORTED_ISA_VERSION) + ); + + diffs_accumulator + .dst_0_values + .push((can_write_into_memory, apply_any, dst0)); + diffs_accumulator.dst_1_values.push((apply_any, dst1)); + let set_flags_and_execute = Boolean::multi_and(cs, &[apply_any, should_set_flags]); + diffs_accumulator + .flags + .push((set_flags_and_execute, candidate_flags)); + + // add range check request. Even though it's only needed for division, it's always satisfiable + diffs_accumulator + .u32_conditional_range_checks + .push((apply_any, conditional_range_checks)); + + let mut add_sub_relations = ArrayVec::new(); + add_sub_relations.push(addition_relation); + diffs_accumulator + .add_sub_relations + .push((apply_any, add_sub_relations)); + + let mut mul_div_relations = ArrayVec::new(); + mul_div_relations.push(mul_relation); + diffs_accumulator + .mul_div_relations + .push((apply_any, mul_div_relations)); +} diff --git a/crates/zkevm_circuits/src/main_vm/opcodes/nop.rs b/crates/zkevm_circuits/src/main_vm/opcodes/nop.rs new file mode 100644 index 0000000..ea0fbd2 --- /dev/null +++ b/crates/zkevm_circuits/src/main_vm/opcodes/nop.rs @@ -0,0 +1,24 @@ +use super::*; + +#[inline(always)] +pub(crate) fn apply_nop>( + cs: &mut CS, + _draft_vm_state: &VmLocalState, + common_opcode_state: &CommonOpcodeState, + _opcode_carry_parts: &AfterDecodingCarryParts, + _diffs_accumulator: &mut StateDiffsAccumulator, +) { + const NOP_OPCODE: zkevm_opcode_defs::Opcode = Opcode::Nop(NopOpcode); + + // now we need to properly select and enforce + let apply_nop = common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_opcode(NOP_OPCODE); + + if crate::config::CIRCUIT_VERSOBE { + if (apply_nop.witness_hook(&*cs))().unwrap_or(false) { + println!("Applying NOP"); + } + } +} diff --git a/crates/zkevm_circuits/src/main_vm/opcodes/ptr.rs b/crates/zkevm_circuits/src/main_vm/opcodes/ptr.rs new file mode 100644 index 0000000..0610bd8 --- /dev/null +++ b/crates/zkevm_circuits/src/main_vm/opcodes/ptr.rs @@ -0,0 +1,183 @@ +use crate::base_structures::register::VMRegister; +use boojum::gadgets::u256::UInt256; + +use super::*; + +pub(crate) fn apply_ptr>( + cs: &mut CS, + _draft_vm_state: &VmLocalState, + common_opcode_state: &CommonOpcodeState, + _opcode_carry_parts: &AfterDecodingCarryParts, + diffs_accumulator: &mut StateDiffsAccumulator, +) { + const PTR_ADD_OPCODE: zkevm_opcode_defs::Opcode = + zkevm_opcode_defs::Opcode::Ptr(zkevm_opcode_defs::PtrOpcode::Add); + const PTR_SUB_OPCODE: zkevm_opcode_defs::Opcode = + zkevm_opcode_defs::Opcode::Ptr(zkevm_opcode_defs::PtrOpcode::Sub); + const PTR_PACK_OPCODE: zkevm_opcode_defs::Opcode = + zkevm_opcode_defs::Opcode::Ptr(zkevm_opcode_defs::PtrOpcode::Pack); + const PTR_SHRINK_OPCODE: zkevm_opcode_defs::Opcode = + zkevm_opcode_defs::Opcode::Ptr(zkevm_opcode_defs::PtrOpcode::Shrink); + + let should_apply = common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_opcode(PTR_ADD_OPCODE); + + if crate::config::CIRCUIT_VERSOBE { + if (should_apply.witness_hook(&*cs))().unwrap_or(false) { + println!("Applying PTR"); + } + } + + let ptr_add_variant = common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(PTR_ADD_OPCODE); + let ptr_sub_variant = common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(PTR_SUB_OPCODE); + let ptr_pack_variant = common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(PTR_PACK_OPCODE); + let ptr_shrink_variant = common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(PTR_SHRINK_OPCODE); + + let src_0 = &common_opcode_state.src0_view; + let src_1 = &common_opcode_state.src1_view; + + let src1_is_integer = src_1.is_ptr.negated(cs); + + // pointer + non_pointer + let args_have_valid_type = Boolean::multi_and(cs, &[src_0.is_ptr, src1_is_integer]); + let args_types_are_invalid = args_have_valid_type.negated(cs); + // we also want to check that src1 is "small" in case of ptr.add + + let limb_is_zero = common_opcode_state + .src1_view + .u32x8_view + .map(|el| el.is_zero(cs)); + let src1_32_to_256_is_zero = Boolean::multi_and(cs, &limb_is_zero[1..]); + let src1_0_to_128_is_zero = Boolean::multi_and(cs, &limb_is_zero[..4]); + + let src1_32_to_256_is_nonzero = src1_32_to_256_is_zero.negated(cs); + + // if we add we want upper part of src1 to be zero + let ptr_arith_variant = Boolean::multi_or(cs, &[ptr_add_variant, ptr_sub_variant]); + let too_large_offset = Boolean::multi_and(cs, &[src1_32_to_256_is_nonzero, ptr_arith_variant]); + + // if we pack we want lower part of src1 to be zero + let src1_0_to_128_is_nonzero = src1_0_to_128_is_zero.negated(cs); + let dirty_value_for_pack = + Boolean::multi_and(cs, &[src1_0_to_128_is_nonzero, ptr_pack_variant]); + + // now check overflows/underflows + let (result_for_ptr_add, of) = src_0.u32x8_view[0].overflowing_add(cs, src_1.u32x8_view[0]); + let overflow_panic_if_add = Boolean::multi_and(cs, &[ptr_add_variant, of]); + + let (result_for_ptr_sub, uf) = src_0.u32x8_view[0].overflowing_sub(cs, src_1.u32x8_view[0]); + let underflow_panic_if_sub = Boolean::multi_and(cs, &[ptr_sub_variant, uf]); + + let (result_for_ptr_shrink, uf) = src_0.u32x8_view[3].overflowing_sub(cs, src_1.u32x8_view[0]); + let underflow_panic_if_shrink = Boolean::multi_and(cs, &[ptr_shrink_variant, uf]); + + let any_potential_panic = Boolean::multi_or( + cs, + &[ + args_types_are_invalid, + too_large_offset, + dirty_value_for_pack, + overflow_panic_if_add, + underflow_panic_if_sub, + underflow_panic_if_shrink, + ], + ); + + let should_panic = Boolean::multi_and(cs, &[should_apply, any_potential_panic]); + let ok_to_execute = any_potential_panic.negated(cs); + let should_update_register = Boolean::multi_and(cs, &[should_apply, ok_to_execute]); + + // now we just need to select the result + + // low 32 bits from addition or unchanged original values + let low_u32_if_add_or_sub = UInt32::conditionally_select( + cs, + ptr_add_variant, + &result_for_ptr_add, + &src_0.u32x8_view[0], + ); + + // low 32 bits from subtraction + let low_u32_if_add_or_sub = UInt32::conditionally_select( + cs, + ptr_sub_variant, + &result_for_ptr_sub, + &low_u32_if_add_or_sub, + ); + + // higher 32 bits if shrink + let bits_96_to_128_if_shrink = UInt32::conditionally_select( + cs, + ptr_shrink_variant, + &result_for_ptr_shrink, + &src_0.u32x8_view[3], // otherwise keep src_0 bits 96..128 + ); + + let highest_128 = UInt32::parallel_select( + cs, + ptr_pack_variant, + &[ + src_1.u32x8_view[4], + src_1.u32x8_view[5], + src_1.u32x8_view[6], + src_1.u32x8_view[7], + ], + &[ + src_0.u32x8_view[4], + src_0.u32x8_view[5], + src_0.u32x8_view[6], + src_0.u32x8_view[7], + ], + ); + + let lowest32 = UInt32::conditionally_select( + cs, + ptr_pack_variant, + &src_0.u32x8_view[0], + &low_u32_if_add_or_sub, + ); + + let bits_96_to_128 = UInt32::conditionally_select( + cs, + ptr_pack_variant, + &src_0.u32x8_view[3], + &bits_96_to_128_if_shrink, + ); + + let dst0 = VMRegister { + is_pointer: src_0.is_ptr, + value: UInt256 { + inner: [ + lowest32, + src_0.u32x8_view[1], + src_0.u32x8_view[2], + bits_96_to_128, + highest_128[0], + highest_128[1], + highest_128[2], + highest_128[3], + ], + }, + }; + + // only update dst0 and set exception if necessary + let can_write_into_memory = PTR_ADD_OPCODE.can_write_dst0_into_memory(SUPPORTED_ISA_VERSION); + diffs_accumulator + .dst_0_values + .push((can_write_into_memory, should_update_register, dst0)); + diffs_accumulator.pending_exceptions.push(should_panic); +} diff --git a/crates/zkevm_circuits/src/main_vm/opcodes/shifts.rs b/crates/zkevm_circuits/src/main_vm/opcodes/shifts.rs new file mode 100644 index 0000000..a18777b --- /dev/null +++ b/crates/zkevm_circuits/src/main_vm/opcodes/shifts.rs @@ -0,0 +1,221 @@ +use super::*; +use crate::base_structures::register::VMRegister; +use crate::base_structures::vm_state::ArithmeticFlagsPort; +use crate::tables::bitshift::*; +use arrayvec::ArrayVec; +use boojum::gadgets::u256::UInt256; + +pub(crate) fn apply_shifts>( + cs: &mut CS, + _draft_vm_state: &VmLocalState, + common_opcode_state: &CommonOpcodeState, + _opcode_carry_parts: &AfterDecodingCarryParts, + diffs_accumulator: &mut StateDiffsAccumulator, +) { + const SHL_OPCODE: zkevm_opcode_defs::Opcode = + zkevm_opcode_defs::Opcode::Shift(zkevm_opcode_defs::definitions::shift::ShiftOpcode::Shl); + const ROL_OPCODE: zkevm_opcode_defs::Opcode = + zkevm_opcode_defs::Opcode::Shift(zkevm_opcode_defs::definitions::shift::ShiftOpcode::Rol); + const SHR_OPCODE: zkevm_opcode_defs::Opcode = + zkevm_opcode_defs::Opcode::Shift(zkevm_opcode_defs::definitions::shift::ShiftOpcode::Shr); + const ROR_OPCODE: zkevm_opcode_defs::Opcode = + zkevm_opcode_defs::Opcode::Shift(zkevm_opcode_defs::definitions::shift::ShiftOpcode::Ror); + + let should_apply = common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_opcode(SHL_OPCODE); + + if crate::config::CIRCUIT_VERSOBE { + if (should_apply.witness_hook(&*cs))().unwrap_or(false) { + println!("Applying SHIFT"); + } + } + + let should_set_flags = common_opcode_state + .decoded_opcode + .properties_bits + .flag_booleans[SET_FLAGS_FLAG_IDX]; + + let is_rol = common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(ROL_OPCODE); + let is_ror = common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(ROR_OPCODE); + let is_shr = common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(SHR_OPCODE); + + let is_cyclic = is_rol.or(cs, is_ror); + let is_right = is_ror.or(cs, is_shr); + + let reg = &common_opcode_state.src0_view.u32x8_view; + let shift = common_opcode_state.src1_view.u8x32_view[0]; + let shift = shift.into_num(); + + // cyclic right rotation x is the same as left cyclic rotation 256 - x + let change_rot = is_ror; + let shift_is_zero = shift.is_zero(cs); + let cnst = Num::allocated_constant(cs, F::from_u64_unchecked(256)); + // no underflow here + let inverted_shift = cnst.sub(cs, &shift); + + let change_flag = { + let x = shift_is_zero.negated(cs); + change_rot.and(cs, x) + }; + let full_shift = Num::conditionally_select(cs, change_flag, &inverted_shift, &shift); + + // and only NOW it's indeed 8-bit, even if we had a subtraction of 256 - 0 above + let full_shift = unsafe { UInt8::from_variable_unchecked(full_shift.get_variable()) }; + + let full_shift_limbs = get_shift_constant(cs, full_shift); + + let is_right_shift = { + let x = is_cyclic.negated(cs); + is_right.and(cs, x) + }; + let (rshift_q, rshift_r) = allocate_div_result_unchecked(cs, ®, &full_shift_limbs); + + let apply_left_shift = { + let x = is_right_shift.negated(cs); + Boolean::multi_and(cs, &[should_apply, x]) + }; + let (lshift_low, lshift_high) = allocate_mul_result_unchecked(cs, ®, &full_shift_limbs); + + // see description of MulDivRelation to range checks in mul_div.rs, but in short: + // - if we shift right then `rshift_q`` is checked as `a_to_enforce`, `rshift_r` is checked as `rem_to_enforce` + // - if we shift left then `lshift_low` is checked as `mul_low_to_enforce` and `lshift_high` as `mul_high_to_enforce` + + // actual enforcement: + // for left_shift: a = reg, b = full_shuft, remainder = 0, high = lshift_high, low = lshift_low + // for right_shift : a = rshift_q, b = full_shift, remainder = rshift_r, high = 0, low = reg + let uint256_zero = UInt256::zero(cs); + + let rem_to_enforce = + UInt32::parallel_select(cs, apply_left_shift, &uint256_zero.inner, &rshift_r); + let a_to_enforce = UInt32::parallel_select(cs, apply_left_shift, reg, &rshift_q); + let b_to_enforce = full_shift_limbs; + let mul_low_to_enforce = UInt32::parallel_select(cs, apply_left_shift, &lshift_low, reg); + let mul_high_to_enforce = + UInt32::parallel_select(cs, apply_left_shift, &lshift_high, &uint256_zero.inner); + + let mul_relation = MulDivRelation { + a: a_to_enforce, + b: b_to_enforce, + rem: rem_to_enforce, + mul_low: mul_low_to_enforce, + mul_high: mul_high_to_enforce, + }; + + // but since we can do division, we need to check that remainder < divisor. We also know that divisor != 0, so no + // extra checks are necessary + let (subtraction_result_unchecked, remainder_is_less_than_divisor) = + allocate_subtraction_result_unchecked(cs, &rshift_r, &full_shift_limbs); + + remainder_is_less_than_divisor.conditionally_enforce_true(cs, is_right_shift); + + // if we do division then remainder will be range checked, but not the subtraction result + let conditional_range_checks = subtraction_result_unchecked; + + // relation is a + b == c + of * 2^N, + // but we compute d - e + 2^N * borrow = f + + // so we need to shuffle + let addition_relation = AddSubRelation { + a: full_shift_limbs, + b: subtraction_result_unchecked, + c: rshift_r, + of: remainder_is_less_than_divisor, + }; + + let temp_result = UInt32::parallel_select(cs, is_right_shift, &rshift_q, &lshift_low); + let overflow = lshift_high; + let mut final_result = UInt256::zero(cs).inner; + + let zipped_iter = (temp_result.iter(), overflow.iter(), final_result.iter_mut()); + for (limb_in, of_in, limb_out) in itertools::multizip(zipped_iter) { + // of * is_cyclic + limb_in + let res = Num::fma( + cs, + &of_in.into_num(), + &is_cyclic.into_num(), + &F::ONE, + &limb_in.into_num(), + &F::ONE, + ); + *limb_out = unsafe { UInt32::from_variable_unchecked(res.get_variable()) }; + } + + // Sets an eq flag if out1 is zero + let res_is_zero = all_limbs_are_zero(cs, &final_result); + let boolean_false = Boolean::allocated_constant(cs, false); + let new_flag_port = ArithmeticFlagsPort { + overflow_or_less_than: boolean_false, + equal: res_is_zero, + greater_than: boolean_false, + }; + + // flags for a case if we do not set flags + let set_flags_and_execute = Boolean::multi_and(cs, &[should_apply, should_set_flags]); + + let dst0 = VMRegister { + is_pointer: boolean_false, + value: UInt256 { + inner: final_result, + }, + }; + + let can_write_into_memory = SHL_OPCODE.can_write_dst0_into_memory(SUPPORTED_ISA_VERSION); + + diffs_accumulator + .dst_0_values + .push((can_write_into_memory, should_apply, dst0)); + diffs_accumulator + .flags + .push((set_flags_and_execute, new_flag_port)); + + // add range check request + diffs_accumulator + .u32_conditional_range_checks + .push((should_apply, conditional_range_checks)); + + let mut add_sub_relations = ArrayVec::new(); + add_sub_relations.push(addition_relation); + diffs_accumulator + .add_sub_relations + .push((should_apply, add_sub_relations)); + + let mut mul_div_relations = ArrayVec::new(); + mul_div_relations.push(mul_relation); + diffs_accumulator + .mul_div_relations + .push((should_apply, mul_div_relations)); +} + +pub(crate) fn get_shift_constant>( + cs: &mut CS, + shift: UInt8, +) -> [UInt32; 8] { + let shift_table_id = cs + .get_table_id_for_marker::() + .expect("table must exist"); + + let mut full_shift_limbs = [UInt32::zero(cs); 8]; + for (idx, dst) in full_shift_limbs.chunks_mut(2).enumerate() { + // shift + idx << 8 + let summand = Num::allocated_constant(cs, F::from_u64_unchecked((idx << 8) as u64)); + let key = shift.into_num().add(cs, &summand); + let [a, b] = cs.perform_lookup::<1, 2>(shift_table_id, &[key.get_variable()]); + unsafe { + dst[0] = UInt32::from_variable_unchecked(a); + dst[1] = UInt32::from_variable_unchecked(b); + } + } + + full_shift_limbs +} diff --git a/crates/zkevm_circuits/src/main_vm/opcodes/uma.rs b/crates/zkevm_circuits/src/main_vm/opcodes/uma.rs new file mode 100644 index 0000000..d3ee192 --- /dev/null +++ b/crates/zkevm_circuits/src/main_vm/opcodes/uma.rs @@ -0,0 +1,1103 @@ +use crate::base_structures::register::VMRegister; +use boojum::gadgets::{traits::castable::WitnessCastable, u256::UInt256}; +use cs_derive::CSAllocatable; + +use super::*; +use crate::base_structures::memory_query::MemoryQueryWitness; +use crate::base_structures::memory_query::MemoryValue; +use crate::main_vm::pre_state::MemoryLocation; +use crate::main_vm::register_input_view::RegisterInputView; +use crate::main_vm::witness_oracle::SynchronizedWitnessOracle; +use crate::main_vm::witness_oracle::WitnessOracle; +use arrayvec::ArrayVec; +use boojum::algebraic_props::round_function::AlgebraicRoundFunction; +use boojum::cs::traits::cs::DstBuffer; +use boojum::gadgets::traits::allocatable::CSAllocatableExt; +use boojum::gadgets::traits::round_function::CircuitRoundFunction; + +pub(crate) fn apply_uma< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, + W: WitnessOracle, +>( + cs: &mut CS, + draft_vm_state: &VmLocalState, + common_opcode_state: &CommonOpcodeState, + opcode_carry_parts: &AfterDecodingCarryParts, + diffs_accumulator: &mut StateDiffsAccumulator, + witness_oracle: &SynchronizedWitnessOracle, + _round_function: &R, +) where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + const UMA_HEAP_READ_OPCODE: zkevm_opcode_defs::Opcode = + zkevm_opcode_defs::Opcode::UMA(UMAOpcode::HeapRead); + const UMA_HEAP_WRITE_OPCODE: zkevm_opcode_defs::Opcode = + zkevm_opcode_defs::Opcode::UMA(UMAOpcode::HeapWrite); + const UMA_AUX_HEAP_READ_OPCODE: zkevm_opcode_defs::Opcode = + zkevm_opcode_defs::Opcode::UMA(UMAOpcode::AuxHeapRead); + const UMA_AUX_HEAP_WRITE_OPCODE: zkevm_opcode_defs::Opcode = + zkevm_opcode_defs::Opcode::UMA(UMAOpcode::AuxHeapWrite); + const UMA_FAT_PTR_READ_OPCODE: zkevm_opcode_defs::Opcode = + zkevm_opcode_defs::Opcode::UMA(UMAOpcode::FatPointerRead); + + let should_apply = common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_opcode(UMA_HEAP_READ_OPCODE); + + let is_uma_heap_read = common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(UMA_HEAP_READ_OPCODE); + let is_uma_heap_write = common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(UMA_HEAP_WRITE_OPCODE); + let is_uma_aux_heap_read = common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(UMA_AUX_HEAP_READ_OPCODE); + let is_uma_aux_heap_write = common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(UMA_AUX_HEAP_WRITE_OPCODE); + let is_uma_fat_ptr_read = common_opcode_state + .decoded_opcode + .properties_bits + .boolean_for_variant(UMA_FAT_PTR_READ_OPCODE); + + let increment_offset = common_opcode_state + .decoded_opcode + .properties_bits + .flag_booleans[UMA_INCREMENT_FLAG_IDX]; + + let access_heap = Boolean::multi_or(cs, &[is_uma_heap_read, is_uma_heap_write]); + let access_aux_heap = Boolean::multi_or(cs, &[is_uma_aux_heap_read, is_uma_aux_heap_write]); + + if crate::config::CIRCUIT_VERSOBE { + if should_apply.witness_hook(&*cs)().unwrap_or(false) { + println!("Applying UMA"); + if is_uma_heap_read.witness_hook(&*cs)().unwrap_or(false) { + println!("Heap read"); + } + if is_uma_heap_write.witness_hook(&*cs)().unwrap_or(false) { + println!("Heap write"); + } + if is_uma_aux_heap_read.witness_hook(&*cs)().unwrap_or(false) { + println!("Aux heap read"); + } + if is_uma_aux_heap_write.witness_hook(&*cs)().unwrap_or(false) { + println!("Aux heap write"); + } + if is_uma_fat_ptr_read.witness_hook(&*cs)().unwrap_or(false) { + println!("Fat ptr read"); + } + } + } + + let src0_is_integer = common_opcode_state.src0_view.is_ptr.negated(cs); + + // perform basic validation + let not_a_ptr_when_expected = + Boolean::multi_and(cs, &[should_apply, is_uma_fat_ptr_read, src0_is_integer]); + + let quasi_fat_ptr = QuasiFatPtrInUMA::parse_and_validate( + cs, + &common_opcode_state.src0_view, + not_a_ptr_when_expected, + is_uma_fat_ptr_read, + ); + + // this one could wrap around, so we account for it. In case if we wrapped we will skip operation anyway + let max_accessed = quasi_fat_ptr.incremented_offset; + + let heap_max_accessed = max_accessed.mask(cs, access_heap); + let heap_bound = draft_vm_state + .callstack + .current_context + .saved_context + .heap_upper_bound; + let (mut heap_growth, uf) = heap_max_accessed.overflowing_sub(cs, heap_bound); + heap_growth = heap_growth.mask_negated(cs, uf); // of we access in bounds then it's 0 + let new_heap_upper_bound = + UInt32::conditionally_select(cs, uf, &heap_bound, &heap_max_accessed); + let grow_heap = Boolean::multi_and(cs, &[access_heap, should_apply]); + + let aux_heap_max_accessed = max_accessed.mask(cs, access_aux_heap); + let aux_heap_bound = draft_vm_state + .callstack + .current_context + .saved_context + .aux_heap_upper_bound; + let (mut aux_heap_growth, uf) = aux_heap_max_accessed.overflowing_sub(cs, aux_heap_bound); + aux_heap_growth = aux_heap_growth.mask_negated(cs, uf); // of we access in bounds then it's 0 + let new_aux_heap_upper_bound = + UInt32::conditionally_select(cs, uf, &aux_heap_bound, &aux_heap_max_accessed); + let grow_aux_heap = Boolean::multi_and(cs, &[access_aux_heap, should_apply]); + + let mut growth_cost = heap_growth.mask(cs, access_heap); + growth_cost = UInt32::conditionally_select(cs, access_aux_heap, &aux_heap_growth, &growth_cost); + + let limbs_to_check = [ + common_opcode_state.src0_view.u32x8_view[1], + common_opcode_state.src0_view.u32x8_view[2], + common_opcode_state.src0_view.u32x8_view[3], + common_opcode_state.src0_view.u32x8_view[4], + common_opcode_state.src0_view.u32x8_view[5], + common_opcode_state.src0_view.u32x8_view[6], + common_opcode_state.src0_view.u32x8_view[7], + ]; + + let limbs_are_zero = limbs_to_check.map(|el| el.is_zero(cs)); + let top_bits_are_clear = Boolean::multi_and(cs, &limbs_are_zero); + let top_bits_are_non_zero = top_bits_are_clear.negated(cs); + + if crate::config::CIRCUIT_VERSOBE { + if should_apply.witness_hook(&*cs)().unwrap_or(false) { + dbg!(quasi_fat_ptr.witness_hook(&*cs)().unwrap()); + dbg!(&common_opcode_state.src0_view.u32x8_view.witness_hook(&*cs)().unwrap()[..4]); + dbg!(common_opcode_state.src1.witness_hook(&*cs)().unwrap()); + } + } + + let t: Boolean = Boolean::multi_or( + cs, + &[ + top_bits_are_non_zero, + quasi_fat_ptr.heap_deref_out_of_bounds, + ], + ); + let heap_access_like = Boolean::multi_or(cs, &[access_heap, access_aux_heap]); + let exception_heap_deref_out_of_bounds = Boolean::multi_and(cs, &[heap_access_like, t]); + + if crate::config::CIRCUIT_VERSOBE { + if should_apply.witness_hook(&*cs)().unwrap_or(false) { + dbg!(top_bits_are_non_zero.witness_hook(&*cs)().unwrap()); + dbg!(quasi_fat_ptr.heap_deref_out_of_bounds.witness_hook(&*cs)().unwrap()); + dbg!(heap_access_like.witness_hook(&*cs)().unwrap()); + dbg!(exception_heap_deref_out_of_bounds.witness_hook(&*cs)().unwrap()); + } + } + + // penalize for heap out of bounds access + let uint32_max = UInt32::allocated_constant(cs, u32::MAX); + growth_cost = UInt32::conditionally_select( + cs, + exception_heap_deref_out_of_bounds, + &uint32_max, + &growth_cost, + ); + + let (ergs_left_after_growth, uf) = opcode_carry_parts + .preliminary_ergs_left + .overflowing_sub(cs, growth_cost); + + let set_panic = Boolean::multi_or( + cs, + &[ + quasi_fat_ptr.should_set_panic, + uf, + exception_heap_deref_out_of_bounds, + ], + ); + if crate::config::CIRCUIT_VERSOBE { + if should_apply.witness_hook(&*cs)().unwrap_or(false) { + dbg!(set_panic.witness_hook(&*cs)().unwrap()); + } + } + // burn all the ergs if not enough + let ergs_left_after_growth = ergs_left_after_growth.mask_negated(cs, uf); + + let should_skip_memory_ops = + Boolean::multi_or(cs, &[quasi_fat_ptr.skip_memory_access, set_panic]); + + let is_read_access = Boolean::multi_or( + cs, + &[is_uma_heap_read, is_uma_aux_heap_read, is_uma_fat_ptr_read], + ); + let is_write_access = Boolean::multi_or(cs, &[is_uma_heap_write, is_uma_aux_heap_write]); + + // NB: Etherium virtual machine is big endian; + // we need to determine the memory cells' indexes which will be accessed + // every memory cell is 32 bytes long, the first cell to be accesed has idx = offset / 32 + // if rem = offset % 32 is zero than it is the only one cell to be accessed + // 1) cell_idx = offset / cell_length, rem = offset % cell_length => + // offset = cell_idx * cell_length + rem + // we should also enforce that cell_idx /in [0, 2^32-1] - this would require range check + // we should also enforce that 0 <= rem < cell_length = 2^5; + // rem is actually the byte offset in the first touched cell, to compute bitoffset and shifts + // we do bit_offset = rem * 8 and then apply shift computing tables + // flag does_cross_border = rem != 0 + let offset = quasi_fat_ptr.absolute_address; + + if crate::config::CIRCUIT_VERSOBE { + if should_apply.witness_hook(&*cs)().unwrap() { + dbg!(offset.witness_hook(&*cs)().unwrap()); + } + } + + let (cell_idx, unalignment) = offset.div_by_constant(cs, 32); + let unalignment_is_zero = unalignment.is_zero(cs); + let access_is_unaligned = unalignment_is_zero.negated(cs); + + // read both memory cells: in what follows we will call the first memory slot A + // and the second memory Slot B + let current_memory_queue_state = draft_vm_state.memory_queue_state; + let current_memory_queue_length = draft_vm_state.memory_queue_length; + + let mut mem_page = quasi_fat_ptr.page_candidate; + mem_page = + UInt32::conditionally_select(cs, access_heap, &opcode_carry_parts.heap_page, &mem_page); + mem_page = UInt32::conditionally_select( + cs, + access_aux_heap, + &opcode_carry_parts.aux_heap_page, + &mem_page, + ); + + let a_cell_idx = cell_idx; + let one_uint32 = UInt32::allocated_constant(cs, 1); + // wrap around + let (b_cell_idx, _of) = a_cell_idx.overflowing_add(cs, one_uint32); + + let a_memory_loc = MemoryLocation { + page: mem_page, + index: a_cell_idx, + }; + let b_memory_loc = MemoryLocation { + page: mem_page, + index: b_cell_idx, + }; + + let mem_read_timestamp = common_opcode_state.timestamp_for_code_or_src_read; + let mem_timestamp_write = common_opcode_state.timestamp_for_dst_write; + + let do_not_skip_memory_access = should_skip_memory_ops.negated(cs); + + let is_unaligned_read = Boolean::multi_and( + cs, + &[should_apply, access_is_unaligned, do_not_skip_memory_access], + ); + + // we yet access the `a` always + let should_read_a_cell = Boolean::multi_and(cs, &[should_apply, do_not_skip_memory_access]); + let should_read_b_cell = is_unaligned_read; + + // we read twice + + let oracle = witness_oracle.clone(); + let mut memory_value_a = MemoryValue::allocate_from_closure_and_dependencies_non_pointer( + cs, + move |inputs: &[F]| { + debug_assert_eq!(inputs.len(), 4); + let timestamp = >::cast_from_source(inputs[0]); + let memory_page = >::cast_from_source(inputs[1]); + let index = >::cast_from_source(inputs[2]); + let should_access = >::cast_from_source(inputs[3]); + + if crate::config::CIRCUIT_VERSOBE { + if should_access { + println!("Will read word A for UMA"); + } + } + + let mut guard = oracle.inner.write().expect("not poisoned"); + let witness = + guard.get_memory_witness_for_read(timestamp, memory_page, index, should_access); + drop(guard); + + witness + }, + &[ + mem_read_timestamp.get_variable().into(), + a_memory_loc.page.get_variable().into(), + a_memory_loc.index.get_variable().into(), + should_read_a_cell.get_variable().into(), + ], + ); + // if we would not need to read we mask it into 0. We do not care about pointer part as we set constant "false" below + memory_value_a.value = memory_value_a.value.mask(cs, should_read_a_cell); + + let oracle = witness_oracle.clone(); + let mut memory_value_b = MemoryValue::allocate_from_closure_and_dependencies_non_pointer( + cs, + move |inputs: &[F]| { + debug_assert_eq!(inputs.len(), 5); + let timestamp = >::cast_from_source(inputs[0]); + let memory_page = >::cast_from_source(inputs[1]); + let index = >::cast_from_source(inputs[2]); + let should_access = >::cast_from_source(inputs[3]); + + if crate::config::CIRCUIT_VERSOBE { + if should_access { + println!("Will read word B for UMA"); + } + } + + let mut guard = oracle.inner.write().expect("not poisoned"); + let witness = + guard.get_memory_witness_for_read(timestamp, memory_page, index, should_access); + drop(guard); + + witness + }, + &[ + mem_read_timestamp.get_variable().into(), + b_memory_loc.page.get_variable().into(), + b_memory_loc.index.get_variable().into(), + should_read_b_cell.get_variable().into(), + // NOTE: we need to evaluate this closure strictly AFTER we evaluate previous access to witness, + // so we "bias" it here + memory_value_a.value.inner[0].get_variable().into(), + ], + ); + // if we would not need to read we mask it into 0. We do not care about pointer part as we set constant "false" below + memory_value_b.value = memory_value_b.value.mask(cs, should_read_b_cell); + + // now we can update the memory queue state + + let boolean_false = Boolean::allocated_constant(cs, false); + let boolean_true = Boolean::allocated_constant(cs, true); + + let ( + new_memory_queue_tail_after_read, + new_memory_queue_length_after_read, + sponge_candidates_after_read, + ) = { + let mut relations = ArrayVec::new(); + + // if crate::config::CIRCUIT_VERSOBE { + // if should_apply.witness_hook(&*cs)().unwrap() { + // dbg!(should_read_a_cell.witness_hook(&*cs)().unwrap()); + // dbg!(should_read_b_cell.witness_hook(&*cs)().unwrap()); + // } + // } + + let query = MemoryQuery { + timestamp: mem_read_timestamp, + memory_page: a_memory_loc.page, + index: a_memory_loc.index, + is_ptr: boolean_false, + value: memory_value_a.value, + rw_flag: boolean_false, + }; + + use boojum::gadgets::traits::encodable::CircuitEncodable; + + let packed_query = query.encode(cs); + + // this is absorb with replacement + let initial_state = [ + packed_query[0], + packed_query[1], + packed_query[2], + packed_query[3], + packed_query[4], + packed_query[5], + packed_query[6], + packed_query[7], + current_memory_queue_state[8].get_variable(), + current_memory_queue_state[9].get_variable(), + current_memory_queue_state[10].get_variable(), + current_memory_queue_state[11].get_variable(), + ]; + + use boojum::gadgets::round_function::simulate_round_function; + + let final_state_candidate = + simulate_round_function::<_, _, 8, 12, 4, R>(cs, initial_state, should_read_a_cell); + let final_state_candidate = final_state_candidate.map(|el| Num::from_variable(el)); + + // if crate::config::CIRCUIT_VERSOBE { + // if should_apply.witness_hook(&*cs)().unwrap() { + // if should_read_a_cell.witness_hook(&*cs)().unwrap() { + // dbg!(initial_state.map(|el| Num::from_variable(el)).witness_hook(&*cs)().unwrap()); + // dbg!(final_state_candidate.witness_hook(&*cs)().unwrap()); + // } + // } + // } + + relations.push(( + should_read_a_cell, + initial_state.map(|el| Num::from_variable(el)), + final_state_candidate, + )); + + let mut new_memory_queue_state = Num::parallel_select( + cs, + should_read_a_cell, + &final_state_candidate, + ¤t_memory_queue_state, + ); + + // for all reasonable execution traces it's fine + let new_len_candidate = unsafe { current_memory_queue_length.increment_unchecked(cs) }; + + let new_length = UInt32::conditionally_select( + cs, + should_read_a_cell, + &new_len_candidate, + ¤t_memory_queue_length, + ); + + // now second query + + let query = MemoryQuery { + timestamp: mem_read_timestamp, + memory_page: b_memory_loc.page, + index: b_memory_loc.index, + is_ptr: boolean_false, + value: memory_value_b.value, + rw_flag: boolean_false, + }; + + let packed_query = query.encode(cs); + + // this is absorb with replacement + let initial_state = [ + packed_query[0], + packed_query[1], + packed_query[2], + packed_query[3], + packed_query[4], + packed_query[5], + packed_query[6], + packed_query[7], + new_memory_queue_state[8].get_variable(), + new_memory_queue_state[9].get_variable(), + new_memory_queue_state[10].get_variable(), + new_memory_queue_state[11].get_variable(), + ]; + + let final_state_candidate = + simulate_round_function::<_, _, 8, 12, 4, R>(cs, initial_state, should_read_b_cell); + let final_state_candidate = final_state_candidate.map(|el| Num::from_variable(el)); + + // if crate::config::CIRCUIT_VERSOBE { + // if should_apply.witness_hook(&*cs)().unwrap() { + // if should_read_b_cell.witness_hook(&*cs)().unwrap() { + // dbg!(initial_state.map(|el| Num::from_variable(el)).witness_hook(&*cs)().unwrap()); + // dbg!(final_state_candidate.witness_hook(&*cs)().unwrap()); + // } + // } + // } + + relations.push(( + should_read_b_cell, + initial_state.map(|el| Num::from_variable(el)), + final_state_candidate, + )); + + new_memory_queue_state = Num::parallel_select( + cs, + should_read_b_cell, + &final_state_candidate, + &new_memory_queue_state, + ); + + // for all reasonable execution traces it's fine + let new_len_candidate = unsafe { new_length.increment_unchecked(cs) }; + + let new_length = + UInt32::conditionally_select(cs, should_read_b_cell, &new_len_candidate, &new_length); + + (new_memory_queue_state, new_length, relations) + }; + + // if crate::config::CIRCUIT_VERSOBE { + // if should_apply.witness_hook(&*cs)().unwrap() { + // dbg!(new_memory_queue_length_after_read.witness_hook(&*cs)().unwrap()); + // } + // } + + // the issue with UMA is that if we cleanup bytes using shifts + // then it's just too heavy in our arithmetization compared to some implementation of shift + // register + + // we have a table that is: + // b1000000.. LSB first if unalignment is 0 + // b0100000.. LSB first if unalignment is 1 + // so it's 32 bits max, and we use parallel select + + let unalignment_bitspread = + uma_shift_into_bitspread(cs, Num::from_variable(unalignment.get_variable())); + let unalignment_bit_mask = unalignment_bitspread.spread_into_bits::<_, 32>(cs); + + // implement shift register + let zero_u8 = UInt8::zero(cs); + let mut bytes_array = [zero_u8; 64]; + + let memory_value_a_bytes = memory_value_a.value.to_be_bytes(cs); + bytes_array[..32].copy_from_slice(&memory_value_a_bytes); + + let memory_value_b_bytes = memory_value_b.value.to_be_bytes(cs); + bytes_array[32..].copy_from_slice(&memory_value_b_bytes); + + // now mask-shift + let mut selected_word = [zero_u8; 32]; + + // idx 0 is unalignment of 0 (aligned), idx 31 is unalignment of 31 + for (idx, mask_bit) in unalignment_bit_mask.iter().enumerate() { + let src = &bytes_array[idx..(idx + 32)]; // source + debug_assert_eq!(src.len(), selected_word.len()); + + for (dst, src) in selected_word + .array_chunks_mut::<4>() + .zip(src.array_chunks::<4>()) + { + *dst = UInt8::parallel_select(cs, *mask_bit, src, &*dst); + } + + // if crate::config::CIRCUIT_VERSOBE { + // if should_apply.witness_hook(&*cs)().unwrap() { + // if should_read_a_cell.witness_hook(&*cs)().unwrap() { + // let src: [_; 32] = src.to_vec().try_into().unwrap(); + // dbg!(mask_bit.witness_hook(&*cs)().unwrap()); + // let src_buffer = src.witness_hook(&*cs)().unwrap(); + // dbg!(hex::encode(&src_buffer)); + // let dst_buffer = selected_word.witness_hook(&*cs)().unwrap(); + // dbg!(hex::encode(&dst_buffer)); + // } + // } + // } + } + + // in case of out-of-bounds UMA we should zero-out tail of our array + // now we need to shift it once again to cleanup from out of bounds part. So we just shift right and left on BE machine + use crate::tables::uma_ptr_read_cleanup::UMAPtrReadCleanupTable; + + let table_id = cs + .get_table_id_for_marker::() + .expect("table must exist"); + let bytes_to_cleanup_out_of_bound = quasi_fat_ptr.bytes_to_cleanup_out_of_bounds; + let bytes_to_cleanup_out_of_bound_if_ptr_read = + bytes_to_cleanup_out_of_bound.mask(cs, is_uma_fat_ptr_read); + let [uma_cleanup_bitspread, _] = cs.perform_lookup::<1, 2>( + table_id, + &[bytes_to_cleanup_out_of_bound_if_ptr_read.get_variable()], + ); + let uma_ptr_read_cleanup_mask = + Num::from_variable(uma_cleanup_bitspread).spread_into_bits::<_, 32>(cs); + + for (dst, masking_bit) in selected_word + .iter_mut() + .zip(uma_ptr_read_cleanup_mask.iter().rev()) + { + *dst = dst.mask(cs, *masking_bit); + } + + if crate::config::CIRCUIT_VERSOBE { + if should_apply.witness_hook(&*cs)().unwrap() { + if should_read_a_cell.witness_hook(&*cs)().unwrap() { + dbg!(unalignment.witness_hook(&*cs)().unwrap()); + let src_buffer = bytes_array.witness_hook(&*cs)().unwrap(); + dbg!(hex::encode(&src_buffer)); + let result_buffer = selected_word.witness_hook(&*cs)().unwrap(); + dbg!(hex::encode(&result_buffer)); + } + } + } + + // for "write" we have to keep the "leftovers" + // and replace the "inner" part with decomposition of the value from src1 + + let execute_write = Boolean::multi_and( + cs, + &[should_apply, is_write_access, do_not_skip_memory_access], + ); // we do not need set panic here, as it's "inside" of `should_skip_memory_ops` + let execute_unaligned_write = Boolean::multi_and(cs, &[execute_write, access_is_unaligned]); + + // make it BE + let mut written_value_bytes = common_opcode_state.src1_view.u8x32_view; + written_value_bytes.reverse(); + + let mut written_bytes_buffer = bytes_array; + // now it's a little trickier as we have to kind-of transpose + + if crate::config::CIRCUIT_VERSOBE { + if should_apply.witness_hook(&*cs)().unwrap() { + if execute_write.witness_hook(&*cs)().unwrap() { + dbg!(unalignment.witness_hook(&*cs)().unwrap()); + let to_write = written_value_bytes.witness_hook(&*cs)().unwrap(); + dbg!(hex::encode(&to_write)); + let original_buffer = bytes_array.witness_hook(&*cs)().unwrap(); + dbg!(hex::encode(&original_buffer)); + } + } + } + + // place back + for (idx, mask_bit) in unalignment_bit_mask.iter().enumerate() { + let dst = &mut written_bytes_buffer[idx..(idx + 32)]; // destination + for (dst, src) in dst + .array_chunks_mut::<4>() + .zip(written_value_bytes.array_chunks::<4>()) + { + *dst = UInt8::parallel_select(cs, *mask_bit, src, &*dst); + } + } + + if crate::config::CIRCUIT_VERSOBE { + if should_apply.witness_hook(&*cs)().unwrap() { + if execute_write.witness_hook(&*cs)().unwrap() { + let result_buffer = written_bytes_buffer.witness_hook(&*cs)().unwrap(); + dbg!(hex::encode(&result_buffer)); + } + } + } + + // now we should write both values in corresponding cells + + // update memory queue state again + let ( + new_memory_queue_tail_after_writes, + new_memory_queue_length_after_writes, + sponge_candidates_after_writes, + ) = { + let mut relations = sponge_candidates_after_read; + + if crate::config::CIRCUIT_VERSOBE { + if should_apply.witness_hook(&*cs)().unwrap() { + dbg!(execute_write.witness_hook(&*cs)().unwrap()); + dbg!(execute_unaligned_write.witness_hook(&*cs)().unwrap()); + } + } + + let mut a_new_value = UInt256::zero(cs); + // read value is LE integer, while words are treated as BE + for (dst, src) in a_new_value + .inner + .iter_mut() + .rev() + .zip(written_bytes_buffer[..32].array_chunks::<4>()) + { + let be_bytes = *src; + let u32_word = UInt32::from_be_bytes(cs, be_bytes); + *dst = u32_word; + } + + let mut b_new_value = UInt256::zero(cs); + // read value is LE integer, while words are treated as BE + for (dst, src) in b_new_value + .inner + .iter_mut() + .rev() + .zip(written_bytes_buffer[32..].array_chunks::<4>()) + { + let be_bytes = *src; + let u32_word = UInt32::from_be_bytes(cs, be_bytes); + *dst = u32_word; + } + + let a_query = MemoryQuery { + timestamp: mem_timestamp_write, + memory_page: a_memory_loc.page, + index: a_memory_loc.index, + is_ptr: boolean_false, + value: a_new_value, + rw_flag: boolean_true, + }; + + use boojum::gadgets::traits::encodable::CircuitEncodable; + + let packed_query = a_query.encode(cs); + + // this is absorb with replacement + let initial_state = [ + packed_query[0], + packed_query[1], + packed_query[2], + packed_query[3], + packed_query[4], + packed_query[5], + packed_query[6], + packed_query[7], + new_memory_queue_tail_after_read[8].get_variable(), + new_memory_queue_tail_after_read[9].get_variable(), + new_memory_queue_tail_after_read[10].get_variable(), + new_memory_queue_tail_after_read[11].get_variable(), + ]; + + use boojum::gadgets::round_function::simulate_round_function; + + let final_state_candidate = + simulate_round_function::<_, _, 8, 12, 4, R>(cs, initial_state, execute_write); + let final_state_candidate = final_state_candidate.map(|el| Num::from_variable(el)); + + // if crate::config::CIRCUIT_VERSOBE { + // if should_apply.witness_hook(&*cs)().unwrap() { + // if execute_write.witness_hook(&*cs)().unwrap() { + // dbg!(initial_state.map(|el| Num::from_variable(el)).witness_hook(&*cs)().unwrap()); + // dbg!(final_state_candidate.witness_hook(&*cs)().unwrap()); + // } + // } + // } + + relations.push(( + execute_write, + initial_state.map(|el| Num::from_variable(el)), + final_state_candidate, + )); + + let mut new_memory_queue_state = Num::parallel_select( + cs, + execute_write, + &final_state_candidate, + &new_memory_queue_tail_after_read, + ); + + // for all reasonable execution traces it's fine + let new_len_candidate = + unsafe { new_memory_queue_length_after_read.increment_unchecked(cs) }; + + let new_length_after_aligned_write = UInt32::conditionally_select( + cs, + execute_write, + &new_len_candidate, + &new_memory_queue_length_after_read, + ); + + // now second query + + let b_query = MemoryQuery { + timestamp: mem_timestamp_write, + memory_page: b_memory_loc.page, + index: b_memory_loc.index, + is_ptr: boolean_false, + value: b_new_value, + rw_flag: boolean_true, + }; + + let packed_query = b_query.encode(cs); + + // this is absorb with replacement + let initial_state = [ + packed_query[0], + packed_query[1], + packed_query[2], + packed_query[3], + packed_query[4], + packed_query[5], + packed_query[6], + packed_query[7], + new_memory_queue_state[8].get_variable(), + new_memory_queue_state[9].get_variable(), + new_memory_queue_state[10].get_variable(), + new_memory_queue_state[11].get_variable(), + ]; + + let final_state_candidate = simulate_round_function::<_, _, 8, 12, 4, R>( + cs, + initial_state, + execute_unaligned_write, + ); + let final_state_candidate = final_state_candidate.map(|el| Num::from_variable(el)); + + // if crate::config::CIRCUIT_VERSOBE { + // if should_apply.witness_hook(&*cs)().unwrap() { + // if execute_unaligned_write.witness_hook(&*cs)().unwrap() { + // dbg!(initial_state.map(|el| Num::from_variable(el)).witness_hook(&*cs)().unwrap()); + // dbg!(final_state_candidate.witness_hook(&*cs)().unwrap()); + // } + // } + // } + + relations.push(( + execute_unaligned_write, + initial_state.map(|el| Num::from_variable(el)), + final_state_candidate, + )); + + new_memory_queue_state = Num::parallel_select( + cs, + execute_unaligned_write, + &final_state_candidate, + &new_memory_queue_state, + ); + + // for all reasonable execution traces it's fine + let new_len_candidate = unsafe { new_length_after_aligned_write.increment_unchecked(cs) }; + + let new_length_after_unaligned_write = UInt32::conditionally_select( + cs, + execute_unaligned_write, + &new_len_candidate, + &new_length_after_aligned_write, + ); + + // push witness updates + { + let oracle = witness_oracle.clone(); + // we should assemble all the dependencies here, and we will use AllocateExt here + let mut dependencies = Vec::with_capacity( + as CSAllocatableExt>::INTERNAL_STRUCT_LEN * 2 + 2, + ); + dependencies.push(execute_write.get_variable().into()); + dependencies.push(execute_unaligned_write.get_variable().into()); + dependencies.extend(Place::from_variables(a_query.flatten_as_variables())); + dependencies.extend(Place::from_variables(b_query.flatten_as_variables())); + + cs.set_values_with_dependencies_vararg( + &dependencies, + &[], + move |inputs: &[F], _buffer: &mut DstBuffer<'_, '_, F>| { + debug_assert_eq!( + inputs.len(), + 2 + 2 * as CSAllocatableExt>::INTERNAL_STRUCT_LEN + ); + + let execute_0 = >::cast_from_source(inputs[0]); + let execute_1 = >::cast_from_source(inputs[1]); + + if crate::config::CIRCUIT_VERSOBE { + if execute_0 { + println!("Will overwrite word A for UMA") + } + } + + let mut query = + [F::ZERO; as CSAllocatableExt>::INTERNAL_STRUCT_LEN]; + query.copy_from_slice( + &inputs + [2..(2 + as CSAllocatableExt>::INTERNAL_STRUCT_LEN)], + ); + let a_query: MemoryQueryWitness = + CSAllocatableExt::witness_from_set_of_values(query); + + let mut guard = oracle.inner.write().expect("not poisoned"); + guard.push_memory_witness(&a_query, execute_0); + + if crate::config::CIRCUIT_VERSOBE { + if execute_1 { + println!("Will overwrite word B for UMA") + } + } + + let mut query = + [F::ZERO; as CSAllocatableExt>::INTERNAL_STRUCT_LEN]; + query.copy_from_slice( + &inputs + [(2 + as CSAllocatableExt>::INTERNAL_STRUCT_LEN)..], + ); + let b_query: MemoryQueryWitness = + CSAllocatableExt::witness_from_set_of_values(query); + guard.push_memory_witness(&b_query, execute_1); + + drop(guard); + }, + ); + } + + ( + new_memory_queue_state, + new_length_after_unaligned_write, + relations, + ) + }; + + // if crate::config::CIRCUIT_VERSOBE { + // if should_apply.witness_hook(&*cs)().unwrap() { + // dbg!(new_memory_queue_length_after_writes.witness_hook(&*cs)().unwrap()); + // } + // } + + let mut read_value_u256 = UInt256::zero(cs); + // read value is LE integer, while words are treated as BE + for (dst, src) in read_value_u256 + .inner + .iter_mut() + .rev() + .zip(selected_word.array_chunks::<4>()) + { + let mut le_bytes = *src; + le_bytes.reverse(); + let u32_word = UInt32::from_le_bytes(cs, le_bytes); + *dst = u32_word; + } + + let read_value_as_register = VMRegister { + is_pointer: boolean_false, + value: read_value_u256, + }; + + // compute incremented dst0 if we increment + let mut incremented_src0_register = common_opcode_state.src0; + incremented_src0_register.value.inner[0] = quasi_fat_ptr.incremented_offset; + + let is_write_access_and_increment = + Boolean::multi_and(cs, &[is_write_access, increment_offset]); + let update_dst0 = Boolean::multi_or(cs, &[is_read_access, is_write_access_and_increment]); + + let no_panic = set_panic.negated(cs); + let apply_any = Boolean::multi_and(cs, &[should_apply, no_panic]); + let should_update_dst0 = Boolean::multi_and(cs, &[apply_any, update_dst0]); + + let dst0_value = VMRegister::conditionally_select( + cs, + is_write_access_and_increment, + &incremented_src0_register, + &read_value_as_register, + ); + + let should_update_dst1 = Boolean::multi_and(cs, &[apply_any, is_read_access, increment_offset]); + + let can_write_into_memory = + UMA_HEAP_READ_OPCODE.can_write_dst0_into_memory(SUPPORTED_ISA_VERSION); + + diffs_accumulator + .dst_0_values + .push((can_write_into_memory, should_update_dst0, dst0_value)); + diffs_accumulator + .dst_1_values + .push((should_update_dst1, incremented_src0_register)); + + // exceptions + let should_panic = Boolean::multi_and(cs, &[should_apply, set_panic]); + diffs_accumulator.pending_exceptions.push(should_panic); + + // and memory related staff + diffs_accumulator + .new_heap_bounds + .push((grow_heap, new_heap_upper_bound)); + diffs_accumulator + .new_aux_heap_bounds + .push((grow_aux_heap, new_aux_heap_upper_bound)); + // pay for growth + diffs_accumulator + .new_ergs_left_candidates + .push((should_apply, ergs_left_after_growth)); + // update sponges and queue states + + assert!(UMA_HEAP_READ_OPCODE.can_have_src0_from_mem(SUPPORTED_ISA_VERSION) == false); + assert!(UMA_HEAP_READ_OPCODE.can_write_dst0_into_memory(SUPPORTED_ISA_VERSION) == false); + + diffs_accumulator.sponge_candidates_to_run.push(( + false, + false, + apply_any, + sponge_candidates_after_writes, + )); + diffs_accumulator.memory_queue_candidates.push(( + should_apply, + new_memory_queue_length_after_writes, + new_memory_queue_tail_after_writes, + )); +} + +use boojum::gadgets::traits::allocatable::CSAllocatable; +use cs_derive::*; + +#[derive(CSAllocatable, WitnessHookable)] +pub struct QuasiFatPtrInUMA { + pub absolute_address: UInt32, + pub page_candidate: UInt32, + pub incremented_offset: UInt32, + pub heap_deref_out_of_bounds: Boolean, + pub skip_memory_access: Boolean, + pub should_set_panic: Boolean, + pub bytes_to_cleanup_out_of_bounds: UInt8, +} + +impl QuasiFatPtrInUMA { + pub(crate) fn parse_and_validate>( + cs: &mut CS, + input: &RegisterInputView, + already_panicked: Boolean, + is_fat_ptr: Boolean, + ) -> Self { + // we can never address a range [2^32 - 32..2^32] this way, but we don't care because + // it's impossible to pay for such memory growth + + let offset = input.u32x8_view[0]; + let page = input.u32x8_view[1]; + let start = input.u32x8_view[2]; + let length = input.u32x8_view[3]; + + // if crate::config::CIRCUIT_VERSOBE { + // dbg!(offset.witness_hook(&*cs)().unwrap()); + // dbg!(start.witness_hook(&*cs)().unwrap()); + // dbg!(length.witness_hook(&*cs)().unwrap()); + // } + + // we need to check whether we will or not deref the fat pointer. + // we only dereference if offset < length (or offset - length < 0) + let (_, offset_is_strictly_in_slice) = offset.overflowing_sub(cs, length); + let offset_is_beyond_the_slice = offset_is_strictly_in_slice.negated(cs); + let skip_if_legitimate_fat_ptr = + Boolean::multi_and(cs, &[offset_is_beyond_the_slice, is_fat_ptr]); + + // 0 of it's heap/aux heap, otherwise use what we have + let formal_start = start.mask(cs, is_fat_ptr); + // by prevalidating fat pointer we know that there is no overflow here, + // so we ignore the information + let (absolute_address, _of) = formal_start.overflowing_add(cs, offset); + + let u32_constant_32 = UInt32::allocated_constant(cs, 32); + + let (incremented_offset, is_non_addressable) = offset.overflowing_add(cs, u32_constant_32); + + // check that we agree in logic with out-of-circuit comparisons + debug_assert_eq!( + zkevm_opcode_defs::uma::MAX_OFFSET_TO_DEREF_LOW_U32 + 32u32, + u32::MAX + ); + let max_offset = UInt32::allocated_constant(cs, u32::MAX); + let is_non_addressable_extra = UInt32::equals(cs, &incremented_offset, &max_offset); + + let is_non_addressable = + Boolean::multi_or(cs, &[is_non_addressable, is_non_addressable_extra]); + + let should_set_panic = Boolean::multi_or(cs, &[already_panicked, is_non_addressable]); + + let skip_memory_access = Boolean::multi_or( + cs, + &[ + already_panicked, + skip_if_legitimate_fat_ptr, + is_non_addressable, + ], + ); + + // only necessary for fat pointer deref: now many bytes we zero-out beyond the end of fat pointer + let (mut bytes_out_of_bound, uf) = incremented_offset.overflowing_sub(cs, length); + + bytes_out_of_bound = bytes_out_of_bound.mask_negated(cs, skip_memory_access); + bytes_out_of_bound = bytes_out_of_bound.mask_negated(cs, uf); + + let (_, bytes_out_of_bound) = bytes_out_of_bound.div_by_constant(cs, 32); + // remainder fits into 8 bits too + let bytes_to_cleanup_out_of_bounds = + unsafe { UInt8::from_variable_unchecked(bytes_out_of_bound.get_variable()) }; + + let new = Self { + absolute_address, + page_candidate: page, + incremented_offset, + heap_deref_out_of_bounds: is_non_addressable, + skip_memory_access: skip_memory_access, + should_set_panic, + bytes_to_cleanup_out_of_bounds, + }; + + new + } +} + +// for integer N returns a field element with value 1 << N +pub fn uma_shift_into_bitspread>( + cs: &mut CS, + integer: Num, +) -> Num { + use crate::tables::integer_to_boolean_mask::UMAShiftToBitmaskTable; + + let table_id = cs + .get_table_id_for_marker::() + .expect("table must be added before"); + + let vals = cs.perform_lookup::<1, 2>(table_id, &[integer.get_variable()]); + let bitspread = vals[0]; + + Num::from_variable(bitspread) +} diff --git a/crates/zkevm_circuits/src/main_vm/pre_state.rs b/crates/zkevm_circuits/src/main_vm/pre_state.rs new file mode 100644 index 0000000..ff7ecc9 --- /dev/null +++ b/crates/zkevm_circuits/src/main_vm/pre_state.rs @@ -0,0 +1,489 @@ +use cs_derive::*; + +use super::witness_oracle::{SynchronizedWitnessOracle, WitnessOracle}; +use super::*; + +use crate::base_structures::register::VMRegister; +use crate::base_structures::vm_state::{ArithmeticFlagsPort, FULL_SPONGE_QUEUE_STATE_WIDTH}; +use crate::main_vm::decoded_opcode::OpcodePropertiesDecoding; +use crate::main_vm::register_input_view::RegisterInputView; +use crate::main_vm::utils::*; +use boojum::field::SmallField; +use boojum::gadgets::boolean::Boolean; +use boojum::gadgets::num::Num; +use boojum::gadgets::traits::allocatable::CSAllocatable; +use boojum::gadgets::u16::UInt16; +use boojum::gadgets::u256::UInt256; +use boojum::gadgets::u32::UInt32; +use boojum::serde_utils::BigArraySerde; + +#[derive(Derivative, CSAllocatable, WitnessHookable)] +#[derivative(Debug)] +pub struct CommonOpcodeState { + pub reseted_flags: ArithmeticFlagsPort, + pub current_flags: ArithmeticFlagsPort, + pub decoded_opcode: OpcodePropertiesDecoding, + pub src0: VMRegister, + pub src1: VMRegister, + pub src0_view: RegisterInputView, + pub src1_view: RegisterInputView, + pub timestamp_for_code_or_src_read: UInt32, + pub timestamp_for_first_decommit_or_precompile_read: UInt32, + pub timestamp_for_second_decommit_or_precompile_write: UInt32, + pub timestamp_for_dst_write: UInt32, +} + +#[derive(Derivative, CSAllocatable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +pub struct MemoryLocation { + pub page: UInt32, + pub index: UInt32, +} + +#[derive(Derivative, CSAllocatable, WitnessHookable)] +#[derivative(Debug)] +pub struct AfterDecodingCarryParts { + pub did_skip_cycle: Boolean, + pub heap_page: UInt32, + pub aux_heap_page: UInt32, + pub next_pc: UInt16, + pub preliminary_ergs_left: UInt32, + pub src0_read_sponge_data: PendingSponge, + pub dst0_memory_location: MemoryLocation, + pub dst0_performs_memory_access: Boolean, +} + +#[derive(Derivative, CSAllocatable, CSSelectable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +pub struct PendingSponge { + pub initial_state: [Num; FULL_SPONGE_QUEUE_STATE_WIDTH], + pub final_state: [Num; FULL_SPONGE_QUEUE_STATE_WIDTH], + pub should_enforce: Boolean, +} + +use crate::base_structures::vm_state::VmLocalState; +use boojum::algebraic_props::round_function::AlgebraicRoundFunction; +use boojum::cs::traits::cs::ConstraintSystem; +use boojum::gadgets::traits::round_function::CircuitRoundFunction; + +// create a draft candidate for next VM state, as well as all the data required for +// opcodes to proceed +pub fn create_prestate< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, + W: WitnessOracle, +>( + cs: &mut CS, + current_state: VmLocalState, + witness_oracle: &SynchronizedWitnessOracle, + round_function: &R, +) -> ( + VmLocalState, + CommonOpcodeState, + AfterDecodingCarryParts, +) { + let mut current_state = current_state; + + let execution_has_ended = current_state.callstack.is_empty(cs); + let should_skip_cycle = execution_has_ended; + let pending_exception = current_state.pending_exception; + let execute_cycle = should_skip_cycle.negated(cs); + + if crate::config::CIRCUIT_VERSOBE { + dbg!(execution_has_ended.witness_hook(&*cs)().unwrap()); + } + + // we should even try to perform a read only if we have something to do this cycle + let should_try_to_read_opcode = execute_cycle.mask_negated(cs, pending_exception); + + let execute_pending_exception_at_this_cycle = pending_exception; + + // take down the flag + current_state.pending_exception = current_state + .pending_exception + .mask_negated(cs, execute_pending_exception_at_this_cycle); + + let current_pc = current_state.callstack.current_context.saved_context.pc; + + let one_u16 = UInt16::allocated_constant(cs, 1); + + let (pc_plus_one, _) = current_pc.overflowing_add(cs, &one_u16); + + let (super_pc, subpc_spread) = split_pc(cs, current_pc); + let previous_super_pc = current_state.previous_super_pc; + + let should_read_for_new_pc = should_read_memory( + cs, + current_state.previous_code_page, + current_state + .callstack + .current_context + .saved_context + .code_page, + super_pc, + previous_super_pc, + ); + + let should_read_opcode = + Boolean::multi_and(cs, &[should_try_to_read_opcode, should_read_for_new_pc]); + + // and in addition if we did finish execution then we never care and cleanup + + let location = MemoryLocation { + page: current_state + .callstack + .current_context + .saved_context + .code_page, + index: unsafe { UInt32::from_variable_unchecked(super_pc.get_variable()) }, + }; + + // precompute timestamps + let timestamp_for_code_or_src_read = current_state.timestamp; + let timestamp_for_first_decommit_or_precompile_read = + unsafe { timestamp_for_code_or_src_read.increment_unchecked(cs) }; + let timestamp_for_second_decommit_or_precompile_write = + unsafe { timestamp_for_first_decommit_or_precompile_read.increment_unchecked(cs) }; + let timestamp_for_dst_write = + unsafe { timestamp_for_second_decommit_or_precompile_write.increment_unchecked(cs) }; + let next_cycle_timestamp = unsafe { timestamp_for_dst_write.increment_unchecked(cs) }; + let next_cycle_timestamp = UInt32::conditionally_select( + cs, + should_skip_cycle, + ¤t_state.timestamp, + &next_cycle_timestamp, + ); + + // we can hardly make a judgement of using or not this sponge + // for optimization purposes, so we will assume that we always run it + + let (mut code_word, (new_memory_queue_state, new_memory_queue_length)) = + may_be_read_memory_for_code( + cs, + should_read_opcode, + timestamp_for_code_or_src_read, + location, + current_state.memory_queue_state, + current_state.memory_queue_length, + round_function, + witness_oracle, + ); + + // update current state + current_state.memory_queue_length = new_memory_queue_length; + current_state.memory_queue_state = new_memory_queue_state; + + code_word = UInt256::conditionally_select( + cs, + should_read_opcode, + &code_word, + ¤t_state.previous_code_word, + ); + + // subpc is 2 bits, so it's a range from 0 to 3. 1..=3 are bitspread via the table + let subpc_bitmask = subpc_spread.spread_into_bits::<_, 3>(cs); + + // default one is one corresponding to the "highest" bytes in 32 byte word in our BE machine + let opcode = [code_word.inner[6], code_word.inner[7]]; + let opcode = <[UInt32; 2]>::conditionally_select( + cs, + subpc_bitmask[0], + &[code_word.inner[4], code_word.inner[5]], + &opcode, + ); + let opcode = <[UInt32; 2]>::conditionally_select( + cs, + subpc_bitmask[1], + &[code_word.inner[2], code_word.inner[3]], + &opcode, + ); + let opcode = <[UInt32; 2]>::conditionally_select( + cs, + subpc_bitmask[2], + &[code_word.inner[0], code_word.inner[1]], + &opcode, + ); + + if crate::config::CIRCUIT_VERSOBE { + if should_skip_cycle.witness_hook(&*cs)().unwrap() { + println!("Skipping cycle"); + } + if execute_pending_exception_at_this_cycle.witness_hook(&*cs)().unwrap() { + println!("Executing pending exception"); + } + } + + // mask if we would be ok with NOPing. This masks a full 8-byte opcode, and not properties bitspread + // We mask if this cycle is just NOPing till the end of circuit + let opcode = mask_into_nop(cs, should_skip_cycle, opcode); + // if we are not pending, and we have an exception to run - run it + let opcode = mask_into_panic(cs, execute_pending_exception_at_this_cycle, opcode); + + // update super_pc and code words if we did read + current_state.previous_code_word = code_word; + // always update code page + current_state.previous_code_page = current_state + .callstack + .current_context + .saved_context + .code_page; + current_state.callstack.current_context.saved_context.pc = UInt16::conditionally_select( + cs, + should_skip_cycle, + ¤t_state.callstack.current_context.saved_context.pc, + &pc_plus_one, + ); + + current_state.previous_super_pc = UInt16::conditionally_select( + cs, + should_skip_cycle, + ¤t_state.previous_super_pc, + &super_pc, + ); // may be it can be unconditional + + // update timestamp + current_state.timestamp = next_cycle_timestamp; + + let is_kernel_mode = current_state + .callstack + .current_context + .saved_context + .is_kernel_mode; + let is_static_context = current_state + .callstack + .current_context + .saved_context + .is_static_execution; + let callstack_is_full = current_state.callstack.is_full(cs); + let ergs_left = current_state + .callstack + .current_context + .saved_context + .ergs_remaining; + + use crate::main_vm::decoded_opcode::encode_flags; + + let encoded_flags = encode_flags(cs, ¤t_state.flags); + + use crate::main_vm::decoded_opcode::perform_initial_decoding; + + let (decoded_opcode, dirty_ergs_left) = perform_initial_decoding( + cs, + opcode, + encoded_flags, + is_kernel_mode, + is_static_context, + callstack_is_full, + ergs_left, + should_skip_cycle, + ); + + // decoded opcode and current (yet dirty) ergs left should be passed into the opcode, + // but by default we set it into context that is true for most of the opcodes + current_state + .callstack + .current_context + .saved_context + .ergs_remaining = dirty_ergs_left; + + // we did all the masking and "INVALID" opcode must never happed + let invalid_opcode_bit = + decoded_opcode + .properties_bits + .boolean_for_opcode(zkevm_opcode_defs::Opcode::Invalid( + zkevm_opcode_defs::InvalidOpcode, + )); + + let boolean_false = Boolean::allocated_constant(cs, false); + Boolean::enforce_equal(cs, &invalid_opcode_bit, &boolean_false); + + // now read source operands + // select low part of the registers + let mut draft_src0 = VMRegister::::zero(cs); + for (mask_bit, register) in decoded_opcode.src_regs_selectors[0] + .iter() + .zip(current_state.registers.iter()) + { + draft_src0 = VMRegister::conditionally_select(cs, *mask_bit, ®ister, &draft_src0); + } + let src0_reg_lowest = draft_src0.value.inner[0].low_u16(cs); + + let mut src1_register = VMRegister::::zero(cs); + for (mask_bit, register) in decoded_opcode.src_regs_selectors[1] + .iter() + .zip(current_state.registers.iter()) + { + src1_register = VMRegister::conditionally_select(cs, *mask_bit, ®ister, &src1_register); + } + + let mut current_dst0_reg_low = UInt32::::zero(cs); + for (mask_bit, register) in decoded_opcode.dst_regs_selectors[0] + .iter() + .zip(current_state.registers.iter()) + { + let reg_low = register.value.inner[0]; + current_dst0_reg_low = + UInt32::conditionally_select(cs, *mask_bit, ®_low, ¤t_dst0_reg_low); + } + let dst0_reg_lowest = current_dst0_reg_low.low_u16(cs); + + let current_sp = current_state.callstack.current_context.saved_context.sp; + let code_page = current_state + .callstack + .current_context + .saved_context + .code_page; + let base_page = current_state + .callstack + .current_context + .saved_context + .base_page; + let stack_page = unsafe { base_page.increment_unchecked(cs) }; + let heap_page = unsafe { stack_page.increment_unchecked(cs) }; + let aux_heap_page = unsafe { heap_page.increment_unchecked(cs) }; + + if crate::config::CIRCUIT_VERSOBE { + dbg!(decoded_opcode.imm0.witness_hook(&*cs)().unwrap()); + dbg!(decoded_opcode.imm1.witness_hook(&*cs)().unwrap()); + } + + let (memory_location_for_src0, new_sp_after_src0, should_read_memory_for_src0) = + resolve_memory_region_and_index_for_source( + cs, + code_page, + stack_page, + src0_reg_lowest, + &decoded_opcode, + current_sp, + ); + + let (memory_location_for_dst0, new_sp, should_write_memory_for_dst0) = + resolve_memory_region_and_index_for_dest( + cs, + stack_page, + dst0_reg_lowest, + &decoded_opcode, + new_sp_after_src0, + ); + + current_state.callstack.current_context.saved_context.sp = new_sp; + + // perform actual read + + let ( + src0_register_from_mem, + ( + initial_state_src0_read_sponge, + final_state_src0_read_sponge, + new_memory_queue_length, + should_use_src0_read_sponge, + ), + ) = may_be_read_memory_for_source_operand( + cs, + should_read_memory_for_src0, + timestamp_for_code_or_src_read, + memory_location_for_src0, + current_state.memory_queue_state, + current_state.memory_queue_length, + round_function, + witness_oracle, + ); + + // update current state + current_state.memory_queue_length = new_memory_queue_length; + current_state.memory_queue_state = final_state_src0_read_sponge; + + // select source0 and source1 + + use zkevm_opcode_defs::ImmMemHandlerFlags; + + // select if it was reg + let use_reg = decoded_opcode + .properties_bits + .boolean_for_src_mem_access(ImmMemHandlerFlags::UseRegOnly); + let src0 = VMRegister::conditionally_select(cs, use_reg, &draft_src0, &src0_register_from_mem); + + // select if it was imm + let imm_as_reg = VMRegister::from_imm(cs, decoded_opcode.imm0); + let use_imm = decoded_opcode + .properties_bits + .boolean_for_src_mem_access(ImmMemHandlerFlags::UseImm16Only); + let src0 = VMRegister::conditionally_select(cs, use_imm, &imm_as_reg, &src0); + + // form an intermediate state to process the opcodes over it + let next_pc = pc_plus_one; + + // swap operands + let swap_operands = { + use zkevm_opcode_defs::*; + + let is_sub = decoded_opcode + .properties_bits + .boolean_for_opcode(Opcode::Sub(SubOpcode::Sub)); + let is_div = decoded_opcode + .properties_bits + .boolean_for_opcode(Opcode::Div(DivOpcode)); + let is_shift = decoded_opcode + .properties_bits + .boolean_for_opcode(Opcode::Shift(ShiftOpcode::Rol)); + + let is_assymmetric = Boolean::multi_or(cs, &[is_sub, is_div, is_shift]); + let swap_flag = + decoded_opcode.properties_bits.flag_booleans[SWAP_OPERANDS_FLAG_IDX_FOR_ARITH_OPCODES]; + + let t0 = Boolean::multi_and(cs, &[is_assymmetric, swap_flag]); + + let is_ptr = decoded_opcode + .properties_bits + .boolean_for_opcode(Opcode::Ptr(PtrOpcode::Add)); + let swap_flag = + decoded_opcode.properties_bits.flag_booleans[SWAP_OPERANDS_FLAG_IDX_FOR_PTR_OPCODE]; + + let t1 = Boolean::multi_and(cs, &[is_ptr, swap_flag]); + + Boolean::multi_or(cs, &[t0, t1]) + }; + + let selected_src0 = src0; + let selected_src1 = src1_register; + + let src0 = VMRegister::conditionally_select(cs, swap_operands, &selected_src1, &selected_src0); + let src1 = VMRegister::conditionally_select(cs, swap_operands, &selected_src0, &selected_src1); + + let src0_view = RegisterInputView::from_input_value(cs, &src0); + let src1_view = RegisterInputView::from_input_value(cs, &src1); + + let empty_flags = ArithmeticFlagsPort::reseted_flags(cs); + + let common_opcode_state = CommonOpcodeState { + reseted_flags: empty_flags, + current_flags: current_state.flags, + decoded_opcode: decoded_opcode, + src0, + src1, + src0_view, + src1_view, + timestamp_for_code_or_src_read, + timestamp_for_first_decommit_or_precompile_read, + timestamp_for_second_decommit_or_precompile_write, + timestamp_for_dst_write, + }; + + let carry_parts = AfterDecodingCarryParts { + did_skip_cycle: should_skip_cycle, + next_pc, + src0_read_sponge_data: PendingSponge { + initial_state: initial_state_src0_read_sponge, + final_state: final_state_src0_read_sponge, + should_enforce: should_use_src0_read_sponge, + }, + dst0_memory_location: memory_location_for_dst0, + dst0_performs_memory_access: should_write_memory_for_dst0, + preliminary_ergs_left: dirty_ergs_left, + heap_page, + aux_heap_page, + }; + + (current_state, common_opcode_state, carry_parts) +} diff --git a/crates/zkevm_circuits/src/main_vm/register_input_view.rs b/crates/zkevm_circuits/src/main_vm/register_input_view.rs new file mode 100644 index 0000000..5db8a53 --- /dev/null +++ b/crates/zkevm_circuits/src/main_vm/register_input_view.rs @@ -0,0 +1,54 @@ +use super::*; +use crate::base_structures::register::VMRegister; +use boojum::cs::traits::cs::ConstraintSystem; +use boojum::gadgets::boolean::Boolean; +use boojum::gadgets::traits::allocatable::CSAllocatable; +use boojum::gadgets::u32::UInt32; +use boojum::serde_utils::BigArraySerde; +use boojum::{field::SmallField, gadgets::u8::UInt8}; +use cs_derive::*; +use std::mem::MaybeUninit; + +// we can decompose register into bytes before passing it into individual opcodes +// because eventually those bytes will go into XOR/AND/OR table as inputs and will be range checked +// anyway + +#[derive(Derivative, CSAllocatable, WitnessHookable)] +#[derivative(Clone, Debug)] +pub struct RegisterInputView { + // used for bitwise operations and as a shift + pub u8x32_view: [UInt8; 32], + // copied from initial decomposition + pub u32x8_view: [UInt32; 8], + pub is_ptr: Boolean, +} + +impl RegisterInputView { + pub fn from_input_value>( + cs: &mut CS, + register: &VMRegister, + ) -> Self { + let mut u8x32_view: [MaybeUninit>; 32] = [MaybeUninit::uninit(); 32]; + + for (src, dst) in register + .value + .inner + .iter() + .zip(u8x32_view.array_chunks_mut::<4>()) + { + let decomposition = unsafe { src.decompose_into_bytes_unchecked(cs) }; + dst[0].write(decomposition[0]); + dst[1].write(decomposition[1]); + dst[2].write(decomposition[2]); + dst[3].write(decomposition[3]); + } + + let u8x32_view = unsafe { u8x32_view.map(|el| el.assume_init()) }; + + Self { + u8x32_view, + u32x8_view: register.value.inner, + is_ptr: register.is_pointer, + } + } +} diff --git a/crates/zkevm_circuits/src/main_vm/state_diffs.rs b/crates/zkevm_circuits/src/main_vm/state_diffs.rs new file mode 100644 index 0000000..8e05eed --- /dev/null +++ b/crates/zkevm_circuits/src/main_vm/state_diffs.rs @@ -0,0 +1,99 @@ +use arrayvec::ArrayVec; + +use super::*; +use crate::base_structures::vm_state::*; +use crate::base_structures::{ + register::VMRegister, + vm_state::{callstack::Callstack, ArithmeticFlagsPort}, +}; +use boojum::field::SmallField; +use boojum::gadgets::num::Num; +use boojum::gadgets::{boolean::Boolean, u16::UInt16, u32::UInt32}; + +use crate::main_vm::opcodes::{AddSubRelation, MulDivRelation}; + +pub(crate) const MAX_SPONGES_PER_CYCLE: usize = 8; +pub(crate) const MAX_U32_CONDITIONAL_RANGE_CHECKS_PER_CYCLE: usize = 8; +pub(crate) const MAX_ADD_SUB_RELATIONS_PER_CYCLE: usize = 1; +pub(crate) const MAX_MUL_DIV_RELATIONS_PER_CYCLE: usize = 3; + +#[derive(Derivative)] +#[derivative(Default(bound = ""))] +pub struct StateDiffsAccumulator { + // dst0 candidates + pub dst_0_values: Vec<(bool, Boolean, VMRegister)>, + // dst1 candidates + pub dst_1_values: Vec<(Boolean, VMRegister)>, + // flags candidates + pub flags: Vec<(Boolean, ArithmeticFlagsPort)>, + // specific register updates + pub specific_registers_updates: [Vec<(Boolean, VMRegister)>; REGISTERS_COUNT], + // zero out specific registers + pub specific_registers_zeroing: [Vec>; REGISTERS_COUNT], + // remove ptr markers on specific registers + pub remove_ptr_on_specific_registers: [Vec>; REGISTERS_COUNT], + // pending exceptions, to be resolved next cycle. Should be masked by opcode applicability already + pub pending_exceptions: Vec>, + // ergs left, PC + // new ergs left if it's not one available after decoding + pub new_ergs_left_candidates: Vec<(Boolean, UInt32)>, + // new PC in case if it's not just PC+1 + pub new_pc_candidates: Vec<(Boolean, UInt16)>, + // other meta parameters of VM + pub new_tx_number: Option<(Boolean, UInt32)>, + pub new_ergs_per_pubdata: Option<(Boolean, UInt32)>, + // memory bouds + pub new_heap_bounds: Vec<(Boolean, UInt32)>, + pub new_aux_heap_bounds: Vec<(Boolean, UInt32)>, + // u128 special register, one from context, another from call/ret + pub context_u128_candidates: Vec<(Boolean, [UInt32; 4])>, + // internal machinery + pub callstacks: Vec<(Boolean, Callstack)>, + // memory page counter + pub memory_page_counters: Option>, + // decommittment queue + pub decommitment_queue_candidates: Option<( + Boolean, + UInt32, + [Num; FULL_SPONGE_QUEUE_STATE_WIDTH], + )>, + // memory queue + pub memory_queue_candidates: Vec<( + Boolean, + UInt32, + [Num; FULL_SPONGE_QUEUE_STATE_WIDTH], + )>, + // forward piece of log queue + pub log_queue_forward_candidates: Vec<(Boolean, UInt32, [Num; QUEUE_STATE_WIDTH])>, + // rollback piece of log queue + pub log_queue_rollback_candidates: Vec<(Boolean, UInt32, [Num; QUEUE_STATE_WIDTH])>, + // sponges to run. Should not include common sponges for src/dst operands + pub sponge_candidates_to_run: Vec<( + bool, + bool, + Boolean, + ArrayVec< + ( + Boolean, + [Num; FULL_SPONGE_QUEUE_STATE_WIDTH], + [Num; FULL_SPONGE_QUEUE_STATE_WIDTH], + ), + MAX_SPONGES_PER_CYCLE, + >, + )>, + // conditional range checks to enforce + pub u32_conditional_range_checks: Vec<( + Boolean, + [UInt32; MAX_U32_CONDITIONAL_RANGE_CHECKS_PER_CYCLE], // at the moment we only have one + )>, + // add/sub relations to enforce + pub add_sub_relations: Vec<( + Boolean, + ArrayVec, MAX_ADD_SUB_RELATIONS_PER_CYCLE>, + )>, + // mul/div relations to enforce + pub mul_div_relations: Vec<( + Boolean, + ArrayVec, MAX_MUL_DIV_RELATIONS_PER_CYCLE>, + )>, +} diff --git a/crates/zkevm_circuits/src/main_vm/utils.rs b/crates/zkevm_circuits/src/main_vm/utils.rs new file mode 100644 index 0000000..9463d6e --- /dev/null +++ b/crates/zkevm_circuits/src/main_vm/utils.rs @@ -0,0 +1,521 @@ +use boojum::field::SmallField; + +use super::decoded_opcode::OpcodePropertiesDecoding; +use super::witness_oracle::SynchronizedWitnessOracle; +use super::*; +use crate::base_structures::memory_query::{MemoryQuery, MemoryValue}; +use crate::base_structures::register::VMRegister; +use boojum::algebraic_props::round_function::AlgebraicRoundFunction; +use boojum::config::*; +use boojum::cs::gates::ConstantAllocatableCS; +use boojum::gadgets::traits::encodable::CircuitEncodable; +use boojum::gadgets::u256::UInt256; + +pub fn mask_into_nop>( + cs: &mut CS, + should_mask: Boolean, + opcode: [UInt32; 2], +) -> [UInt32; 2] { + use zkevm_opcode_defs::decoding::*; + let nop_encoding = EncodingModeProduction::nop_encoding(); + let low = nop_encoding as u32; + let low = UInt32::allocated_constant(cs, low); + let high = (nop_encoding >> 32) as u32; + let high = UInt32::allocated_constant(cs, high); + + <[UInt32; 2]>::conditionally_select(cs, should_mask, &[low, high], &opcode) +} + +pub fn mask_into_panic>( + cs: &mut CS, + should_mask: Boolean, + opcode: [UInt32; 2], +) -> [UInt32; 2] { + use zkevm_opcode_defs::decoding::*; + let nop_encoding = EncodingModeProduction::exception_revert_encoding(); + let low = nop_encoding as u32; + let low = UInt32::allocated_constant(cs, low); + let high = (nop_encoding >> 32) as u32; + let high = UInt32::allocated_constant(cs, high); + + <[UInt32; 2]>::conditionally_select(cs, should_mask, &[low, high], &opcode) +} + +pub(crate) const SUB_PC_BITS: usize = 2; +pub(crate) const SUB_PC_MASK: u16 = (1u16 << SUB_PC_BITS) - 1; + +pub(crate) fn split_pc>( + cs: &mut CS, + pc: UInt16, +) -> (UInt16, Num) { + let outputs = cs.alloc_multiple_variables_without_values::<2>(); + + if ::WitnessConfig::EVALUATE_WITNESS { + let value_fn = move |inputs: [F; 1]| { + let mut as_u64 = inputs[0].as_u64(); + let sub_pc = as_u64 & (SUB_PC_MASK as u64); + as_u64 >>= SUB_PC_BITS; + let super_pc = as_u64; + + [ + F::from_u64_unchecked(sub_pc), + F::from_u64_unchecked(super_pc), + ] + }; + + let dependencies = Place::from_variables([pc.get_variable()]); + + cs.set_values_with_dependencies(&dependencies, &Place::from_variables(outputs), value_fn); + } + + if ::SetupConfig::KEEP_SETUP { + use boojum::cs::gates::FmaGateInBaseFieldWithoutConstant; + + if cs.gate_is_allowed::>() { + let one = cs.allocate_constant(F::ONE); + let mut gate = FmaGateInBaseFieldWithoutConstant::empty(); + gate.quadratic_part = (one, outputs[0]); + gate.linear_part = outputs[1]; + use boojum::cs::gates::fma_gate_without_constant::FmaGateInBaseWithoutConstantParams; + gate.params = FmaGateInBaseWithoutConstantParams { + coeff_for_quadtaric_part: F::ONE, + linear_term_coeff: F::from_u64_unchecked(1u64 << SUB_PC_BITS), + }; + gate.rhs_part = pc.get_variable(); + + gate.add_to_cs(cs); + } else { + unimplemented!() + } + } + + let super_pc = UInt16::from_variable_checked(cs, outputs[1]); + + use crate::tables::integer_to_boolean_mask::VMSubPCToBitmaskTable; + let table_id = cs + .get_table_id_for_marker::() + .expect("table must be added before"); + + let vals = cs.perform_lookup::<1, 2>(table_id, &[outputs[0]]); + let bitspread = vals[0]; + let bitspread = Num::from_variable(bitspread); + + (super_pc, bitspread) +} + +#[inline] +pub(crate) fn should_read_memory>( + cs: &mut CS, + previous_code_page: UInt32, + current_code_page: UInt32, + super_pc: UInt16, + previous_super_pc: UInt16, +) -> Boolean { + let code_pages_are_equal = UInt32::equals(cs, &previous_code_page, ¤t_code_page); + let super_pc_are_equal = UInt16::equals(cs, &super_pc, &previous_super_pc); + + let can_skip = Boolean::multi_and(cs, &[code_pages_are_equal, super_pc_are_equal]); + + can_skip.negated(cs) +} + +use crate::base_structures::vm_state::FULL_SPONGE_QUEUE_STATE_WIDTH; +use crate::main_vm::pre_state::MemoryLocation; +use crate::main_vm::witness_oracle::WitnessOracle; +use boojum::gadgets::traits::round_function::CircuitRoundFunction; + +/// NOTE: final state is one if we INDEED READ, so extra care should be taken to select and preserve markers +/// if we ever need it or not +pub(crate) fn may_be_read_memory_for_code< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction, + W: WitnessOracle, +>( + cs: &mut CS, + should_access: Boolean, + timestamp: UInt32, + location: MemoryLocation, + current_memory_sponge_state: [Num; FULL_SPONGE_QUEUE_STATE_WIDTH], + current_memory_sponge_length: UInt32, + _round_function: &R, + witness_oracle: &SynchronizedWitnessOracle, +) -> ( + UInt256, + ([Num; FULL_SPONGE_QUEUE_STATE_WIDTH], UInt32), +) { + if crate::config::CIRCUIT_VERSOBE { + if should_access.witness_hook(&*cs)().unwrap() { + println!("Will read 32-byte word for opcode"); + // dbg!(timestamp.witness_hook(&*cs)().unwrap()); + // dbg!(location.witness_hook(&*cs)().unwrap()); + } + } + + let MemoryLocation { page, index } = location; + + let witness_oracle = witness_oracle.clone(); + let memory_value = MemoryValue::allocate_from_closure_and_dependencies_non_pointer( + cs, + move |inputs: &[F]| { + debug_assert_eq!(inputs.len(), 4); + let timestamp = inputs[0].as_u64() as u32; + let memory_page = inputs[1].as_u64() as u32; + let index = inputs[2].as_u64() as u32; + debug_assert!(inputs[3].as_u64() == 0 || inputs[3].as_u64() == 1); + let should_access = if inputs[3].as_u64() == 0 { false } else { true }; + + let mut guard = witness_oracle.inner.write().expect("not poisoned"); + let witness = + guard.get_memory_witness_for_read(timestamp, memory_page, index, should_access); + drop(guard); + + witness + }, + &[ + timestamp.get_variable().into(), + page.get_variable().into(), + index.get_variable().into(), + should_access.get_variable().into(), + ], + ); + + let boolean_false = Boolean::allocated_constant(cs, false); + + let query = MemoryQuery { + timestamp, + memory_page: page, + index, + is_ptr: memory_value.is_ptr, + value: memory_value.value, + rw_flag: boolean_false, + }; + + let packed_query = query.encode(cs); + + // this is absorb with replacement + let initial_state = [ + packed_query[0], + packed_query[1], + packed_query[2], + packed_query[3], + packed_query[4], + packed_query[5], + packed_query[6], + packed_query[7], + current_memory_sponge_state[8].get_variable(), + current_memory_sponge_state[9].get_variable(), + current_memory_sponge_state[10].get_variable(), + current_memory_sponge_state[11].get_variable(), + ]; + + let final_state_candidate = R::compute_round_function(cs, initial_state); + let final_state_candidate = final_state_candidate.map(|el| Num::from_variable(el)); + + // for all reasonable execution traces it's fine + let new_len_candidate = unsafe { current_memory_sponge_length.increment_unchecked(cs) }; + + let new_length = UInt32::conditionally_select( + cs, + should_access, + &new_len_candidate, + ¤t_memory_sponge_length, + ); + + let final_state = Num::parallel_select( + cs, + should_access, + &final_state_candidate, + ¤t_memory_sponge_state, + ); + + (memory_value.value, (final_state, new_length)) +} + +use zkevm_opcode_defs::ImmMemHandlerFlags; + +pub fn resolve_memory_region_and_index_for_source>( + cs: &mut CS, + code_page: UInt32, + stack_page: UInt32, + register_low_value: UInt16, + opcode_props: &OpcodePropertiesDecoding, + current_sp: UInt16, +) -> (MemoryLocation, UInt16, Boolean) { + // we assume that we did quickly select low part of the register before somehow, so we + + let use_code = opcode_props + .properties_bits + .boolean_for_src_mem_access(ImmMemHandlerFlags::UseCodePage); + let use_stack_absolute = opcode_props + .properties_bits + .boolean_for_src_mem_access(ImmMemHandlerFlags::UseAbsoluteOnStack); + let use_stack_relative = opcode_props + .properties_bits + .boolean_for_src_mem_access(ImmMemHandlerFlags::UseStackWithOffset); + let use_stack_with_push_pop = opcode_props + .properties_bits + .boolean_for_src_mem_access(ImmMemHandlerFlags::UseStackWithPushPop); + + let absolute_mode = Boolean::multi_or(cs, &[use_code, use_stack_absolute]); + let (index_for_absolute, _) = register_low_value.overflowing_add(cs, &opcode_props.imm0); + let (index_for_relative, _) = current_sp.overflowing_sub(cs, &index_for_absolute); + + // if we use absolute addressing then we just access reg + imm mod 2^16 + // if we use relative addressing then we access sp +/- (reg + imm), and if we push/pop then we update sp to such value + + // here we only read + + // manually unrolled selection. We KNOW that either we will not care about this particular value, + // or one of the bits here was set anyway + + let use_stack = Boolean::multi_or( + cs, + &[ + use_stack_absolute, + use_stack_relative, + use_stack_with_push_pop, + ], + ); + let did_read = Boolean::multi_or(cs, &[use_stack, use_code]); + // we have a special rule for NOP opcode: if we NOP then even though we CAN formally address the memory we SHOULD NOT read + let is_nop = opcode_props + .properties_bits + .boolean_for_opcode(zkevm_opcode_defs::Opcode::Nop(zkevm_opcode_defs::NopOpcode)); + + let not_nop = is_nop.negated(cs); + let did_read = Boolean::multi_and(cs, &[did_read, not_nop]); + let page = UInt32::conditionally_select(cs, use_stack, &stack_page, &code_page); + + let index = + UInt16::conditionally_select(cs, absolute_mode, &index_for_absolute, &index_for_relative); + + let new_sp = UInt16::conditionally_select( + cs, + use_stack_with_push_pop, + &index_for_relative, + ¤t_sp, + ); + let location = MemoryLocation { + page, + index: unsafe { UInt32::from_variable_unchecked(index.get_variable()) }, + }; + + (location, new_sp, did_read) +} + +pub fn resolve_memory_region_and_index_for_dest>( + cs: &mut CS, + stack_page: UInt32, + register_low_value: UInt16, + opcode_props: &OpcodePropertiesDecoding, + current_sp: UInt16, +) -> (MemoryLocation, UInt16, Boolean) { + // we assume that we did quickly select low part of the register before somehow, so we + + let use_stack_absolute = opcode_props + .properties_bits + .boolean_for_dst_mem_access(ImmMemHandlerFlags::UseAbsoluteOnStack); + let use_stack_relative = opcode_props + .properties_bits + .boolean_for_dst_mem_access(ImmMemHandlerFlags::UseStackWithOffset); + let use_stack_with_push_pop = opcode_props + .properties_bits + .boolean_for_dst_mem_access(ImmMemHandlerFlags::UseStackWithPushPop); + + let absolute_mode = use_stack_absolute; + let (index_for_absolute, _) = register_low_value.overflowing_add(cs, &opcode_props.imm1); + let (index_for_relative_with_push, _) = current_sp.overflowing_add(cs, &index_for_absolute); + let (index_for_relative, _) = current_sp.overflowing_sub(cs, &index_for_absolute); + + // if we use absolute addressing then we just access reg + imm mod 2^16 + // if we use relative addressing then we access sp +/- (reg + imm), and if we push/pop then we update sp + + // here we only write + + // manually unrolled selection. We KNOW that either we will not care about this particular value, + // or one of the bits here was set anyway + + let page = stack_page; + let did_write = Boolean::multi_or( + cs, + &[ + use_stack_absolute, + use_stack_relative, + use_stack_with_push_pop, + ], + ); + // we have a special rule for NOP opcode: if we NOP then even though we CAN formally address the memory we SHOULD NOT write + let is_nop = opcode_props + .properties_bits + .boolean_for_opcode(zkevm_opcode_defs::Opcode::Nop(zkevm_opcode_defs::NopOpcode)); + + let not_nop = is_nop.negated(cs); + let did_write = Boolean::multi_and(cs, &[did_write, not_nop]); + + let index_with_somewhat_relative_addressing = UInt16::conditionally_select( + cs, + use_stack_with_push_pop, + &index_for_relative_with_push, + &index_for_relative, + ); + + let index = UInt16::conditionally_select( + cs, + absolute_mode, + &index_for_absolute, + &index_with_somewhat_relative_addressing, + ); + + let new_sp = UInt16::conditionally_select( + cs, + use_stack_with_push_pop, + &index_for_relative_with_push, + ¤t_sp, + ); + + let location = MemoryLocation { + page, + index: unsafe { UInt32::from_variable_unchecked(index.get_variable()) }, + }; + + (location, new_sp, did_write) +} + +/// NOTE: final state is one if we INDEED READ, so extra care should be taken to select and preserve markers +/// if we ever need it or not +pub fn may_be_read_memory_for_source_operand< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, + W: WitnessOracle, +>( + cs: &mut CS, + should_access: Boolean, + timestamp: UInt32, + location: MemoryLocation, + current_memory_sponge_state: [Num; FULL_SPONGE_QUEUE_STATE_WIDTH], + current_memory_sponge_length: UInt32, + _round_function: &R, + witness_oracle: &SynchronizedWitnessOracle, +) -> ( + VMRegister, + ( + [Num; FULL_SPONGE_QUEUE_STATE_WIDTH], + [Num; FULL_SPONGE_QUEUE_STATE_WIDTH], + UInt32, + Boolean, + ), +) { + if crate::config::CIRCUIT_VERSOBE { + if should_access.witness_hook(&*cs)().unwrap() { + println!("Will read SRC0 from memory"); + dbg!(timestamp.witness_hook(&*cs)().unwrap()); + dbg!(location.witness_hook(&*cs)().unwrap()); + } + } + + let MemoryLocation { page, index } = location; + + let witness_oracle = witness_oracle.clone(); + let memory_value = MemoryValue::allocate_from_closure_and_dependencies( + cs, + move |inputs: &[F]| { + debug_assert_eq!(inputs.len(), 4); + let timestamp = inputs[0].as_u64() as u32; + let memory_page = inputs[1].as_u64() as u32; + let index = inputs[2].as_u64() as u32; + debug_assert!(inputs[3].as_u64() == 0 || inputs[3].as_u64() == 1); + let should_access = if inputs[3].as_u64() == 0 { false } else { true }; + + let mut guard = witness_oracle.inner.write().expect("not poisoned"); + let witness = + guard.get_memory_witness_for_read(timestamp, memory_page, index, should_access); + drop(guard); + + witness + }, + &[ + timestamp.get_variable().into(), + page.get_variable().into(), + index.get_variable().into(), + should_access.get_variable().into(), + ], + ); + + let boolean_false = Boolean::allocated_constant(cs, false); + + let query = MemoryQuery { + timestamp, + memory_page: page, + index, + is_ptr: memory_value.is_ptr, + value: memory_value.value, + rw_flag: boolean_false, + }; + + let packed_query = query.encode(cs); + + use boojum::gadgets::queue::full_state_queue::simulate_new_tail_for_full_state_queue; + + use crate::base_structures::memory_query::MEMORY_QUERY_PACKED_WIDTH; + + let simulated_values = simulate_new_tail_for_full_state_queue::< + F, + 8, + FULL_SPONGE_QUEUE_STATE_WIDTH, + 4, + MEMORY_QUERY_PACKED_WIDTH, + R, + _, + >( + cs, + packed_query, + current_memory_sponge_state.map(|el| el.get_variable()), + should_access, + ); + + let initial_state = [ + Num::from_variable(packed_query[0]), + Num::from_variable(packed_query[1]), + Num::from_variable(packed_query[2]), + Num::from_variable(packed_query[3]), + Num::from_variable(packed_query[4]), + Num::from_variable(packed_query[5]), + Num::from_variable(packed_query[6]), + Num::from_variable(packed_query[7]), + current_memory_sponge_state[8], + current_memory_sponge_state[9], + current_memory_sponge_state[10], + current_memory_sponge_state[11], + ]; + + let simulated_final_state = simulated_values.map(|el| Num::from_variable(el)); + + // for all reasonable execution traces it's fine + let new_len_candidate = unsafe { current_memory_sponge_length.increment_unchecked(cs) }; + + let new_length = UInt32::conditionally_select( + cs, + should_access, + &new_len_candidate, + ¤t_memory_sponge_length, + ); + + let final_state = Num::parallel_select( + cs, + should_access, + &simulated_final_state, + ¤t_memory_sponge_state, + ); + + let as_register = VMRegister { + is_pointer: memory_value.is_ptr, + value: memory_value.value, + }; + + ( + as_register, + (initial_state, final_state, new_length, should_access), + ) +} diff --git a/crates/zkevm_circuits/src/main_vm/witness_oracle.rs b/crates/zkevm_circuits/src/main_vm/witness_oracle.rs new file mode 100644 index 0000000..386e728 --- /dev/null +++ b/crates/zkevm_circuits/src/main_vm/witness_oracle.rs @@ -0,0 +1,168 @@ +use crate::ethereum_types::U256; + +use crate::base_structures::decommit_query::DecommitQueryWitness; +use crate::base_structures::vm_state::saved_context::ExecutionContextRecordWitness; +use boojum::field::SmallField; + +use super::*; + +#[derive(Derivative)] +#[derivative(Clone, Debug, Default)] +pub struct MemoryWitness { + pub value: U256, + pub is_ptr: bool, +} + +use std::sync::{Arc, RwLock}; + +pub struct SynchronizedWitnessOracle> { + pub inner: Arc>, + pub _marker: std::marker::PhantomData, +} + +impl> Clone for SynchronizedWitnessOracle { + fn clone(&self) -> Self { + Self { + inner: Arc::clone(&self.inner), + _marker: std::marker::PhantomData, + } + } +} + +impl> SynchronizedWitnessOracle { + pub fn new(raw_oracle: W) -> Self { + Self { + inner: Arc::new(RwLock::new(raw_oracle)), + _marker: std::marker::PhantomData, + } + } +} + +use crate::base_structures::log_query::LogQueryWitness; + +use crate::base_structures::memory_query::MemoryQueryWitness; + +pub trait WitnessOracle: + 'static + Send + Sync + Default + Clone + serde::Serialize + serde::de::DeserializeOwned +{ + fn get_memory_witness_for_read( + &mut self, + timestamp: u32, + memory_page: u32, + index: u32, + execute: bool, + ) -> MemoryWitness; + fn push_memory_witness(&mut self, memory_query: &MemoryQueryWitness, execute: bool); + fn get_storage_read_witness( + &mut self, + key: &LogQueryWitness, + needs_witness: bool, + execute: bool, + ) -> U256; + fn get_refunds(&mut self, query: &LogQueryWitness, is_write: bool, execute: bool) -> u32; + fn push_storage_witness(&mut self, key: &LogQueryWitness, execute: bool); + fn get_rollback_queue_witness(&mut self, key: &LogQueryWitness, execute: bool) -> [F; 4]; + fn get_rollback_queue_tail_witness_for_call(&mut self, timestamp: u32, execute: bool) + -> [F; 4]; + fn report_new_callstack_frame( + &mut self, + new_record: &ExecutionContextRecordWitness, + new_depth: u32, + is_call: bool, + execute: bool, + ); + fn push_callstack_witness( + &mut self, + current_record: &ExecutionContextRecordWitness, + current_depth: u32, + execute: bool, + ); + fn get_callstack_witness( + &mut self, + execute: bool, + depth: u32, + ) -> (ExecutionContextRecordWitness, [F; 12]); + fn get_decommittment_request_suggested_page( + &mut self, + request: &DecommitQueryWitness, + execute: bool, + ) -> u32; + fn at_completion(self) {} +} + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Copy, Debug, Default(bound = ""))] +pub struct DummyOracle { + pub _marker: std::marker::PhantomData, +} + +impl WitnessOracle for DummyOracle { + fn get_memory_witness_for_read( + &mut self, + _timestamp: u32, + _memory_page: u32, + _index: u32, + _execute: bool, + ) -> MemoryWitness { + todo!() + } + fn push_memory_witness(&mut self, _memory_query: &MemoryQueryWitness, _execute: bool) { + todo!() + } + fn get_storage_read_witness( + &mut self, + _key: &LogQueryWitness, + _needs_witness: bool, + _execute: bool, + ) -> U256 { + todo!() + } + fn get_refunds(&mut self, _query: &LogQueryWitness, _is_write: bool, _execute: bool) -> u32 { + todo!() + } + fn push_storage_witness(&mut self, _key: &LogQueryWitness, _execute: bool) { + todo!() + } + fn get_rollback_queue_witness(&mut self, _key: &LogQueryWitness, _execute: bool) -> [F; 4] { + todo!() + } + fn get_rollback_queue_tail_witness_for_call( + &mut self, + _timestamp: u32, + _execute: bool, + ) -> [F; 4] { + todo!() + } + fn report_new_callstack_frame( + &mut self, + _current_record: &ExecutionContextRecordWitness, + _new_depth: u32, + _is_call: bool, + _execute: bool, + ) { + todo!() + } + fn push_callstack_witness( + &mut self, + _current_record: &ExecutionContextRecordWitness, + _current_depth: u32, + _execute: bool, + ) { + todo!() + } + fn get_callstack_witness( + &mut self, + _execute: bool, + _depth: u32, + ) -> (ExecutionContextRecordWitness, [F; 12]) { + todo!() + } + fn get_decommittment_request_suggested_page( + &mut self, + _request: &DecommitQueryWitness, + _execute: bool, + ) -> u32 { + todo!() + } + fn at_completion(self) {} +} diff --git a/crates/zkevm_circuits/src/ram_permutation/input.rs b/crates/zkevm_circuits/src/ram_permutation/input.rs new file mode 100644 index 0000000..099c413 --- /dev/null +++ b/crates/zkevm_circuits/src/ram_permutation/input.rs @@ -0,0 +1,120 @@ +use crate::base_structures::{ + memory_query::{MemoryQuery, MEMORY_QUERY_PACKED_WIDTH}, + vm_state::*, +}; +use crate::boojum::gadgets::traits::auxiliary::PrettyComparison; +use crate::DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS; +use boojum::cs::{traits::cs::ConstraintSystem, Variable}; +use boojum::field::SmallField; +use boojum::gadgets::{ + boolean::Boolean, + num::Num, + queue::full_state_queue::*, + queue::*, + traits::{ + allocatable::*, encodable::CircuitVarLengthEncodable, selectable::Selectable, + witnessable::WitnessHookable, + }, + u256::UInt256, + u32::UInt32, +}; +use boojum::serde_utils::BigArraySerde; +use cs_derive::*; +use derivative::*; + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Debug)] +pub struct RamPermutationInputData { + pub unsorted_queue_initial_state: QueueState, + pub sorted_queue_initial_state: QueueState, + pub non_deterministic_bootloader_memory_snapshot_length: UInt32, +} + +impl CSPlaceholder for RamPermutationInputData { + fn placeholder>(cs: &mut CS) -> Self { + let zero_u32 = UInt32::zero(cs); + let empty_state = QueueState::placeholder(cs); + + Self { + unsorted_queue_initial_state: empty_state, + sorted_queue_initial_state: empty_state, + non_deterministic_bootloader_memory_snapshot_length: zero_u32, + } + } +} + +pub const RAM_SORTING_KEY_LENGTH: usize = 3; +pub const RAM_FULL_KEY_LENGTH: usize = 2; + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +#[DerivePrettyComparison("true")] +pub struct RamPermutationFSMInputOutput { + pub lhs_accumulator: [Num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + pub rhs_accumulator: [Num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + pub current_unsorted_queue_state: QueueState, + pub current_sorted_queue_state: QueueState, + pub previous_sorting_key: [UInt32; RAM_SORTING_KEY_LENGTH], + pub previous_full_key: [UInt32; RAM_FULL_KEY_LENGTH], + pub previous_value: UInt256, + pub previous_is_ptr: Boolean, + pub num_nondeterministic_writes: UInt32, +} + +impl CSPlaceholder for RamPermutationFSMInputOutput { + fn placeholder>(cs: &mut CS) -> Self { + let zero_num = Num::zero(cs); + let zero_u32 = UInt32::zero(cs); + let zero_u256 = UInt256::zero(cs); + let boolean_false = Boolean::allocated_constant(cs, false); + let empty_state = QueueState::placeholder(cs); + + Self { + lhs_accumulator: [zero_num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + rhs_accumulator: [zero_num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + current_unsorted_queue_state: empty_state, + current_sorted_queue_state: empty_state, + previous_sorting_key: [zero_u32; RAM_SORTING_KEY_LENGTH], + previous_full_key: [zero_u32; RAM_FULL_KEY_LENGTH], + previous_value: zero_u256, + previous_is_ptr: boolean_false, + num_nondeterministic_writes: zero_u32, + } + } +} + +pub type RamPermutationCycleInputOutput = crate::fsm_input_output::ClosedFormInput< + F, + RamPermutationFSMInputOutput, + RamPermutationInputData, + (), +>; +pub type RamPermutationCycleInputOutputWitness = crate::fsm_input_output::ClosedFormInputWitness< + F, + RamPermutationFSMInputOutput, + RamPermutationInputData, + (), +>; + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Debug, Default)] +#[serde(bound = "")] +pub struct RamPermutationCircuitInstanceWitness { + pub closed_form_input: RamPermutationCycleInputOutputWitness, + + pub unsorted_queue_witness: FullStateCircuitQueueRawWitness< + F, + MemoryQuery, + FULL_SPONGE_QUEUE_STATE_WIDTH, + MEMORY_QUERY_PACKED_WIDTH, + >, + pub sorted_queue_witness: FullStateCircuitQueueRawWitness< + F, + MemoryQuery, + FULL_SPONGE_QUEUE_STATE_WIDTH, + MEMORY_QUERY_PACKED_WIDTH, + >, +} + +pub type MemoryQueriesQueue = + FullStateCircuitQueue, 8, 12, 4, MEMORY_QUERY_PACKED_WIDTH, R>; diff --git a/crates/zkevm_circuits/src/ram_permutation/mod.rs b/crates/zkevm_circuits/src/ram_permutation/mod.rs new file mode 100644 index 0000000..7e3c13a --- /dev/null +++ b/crates/zkevm_circuits/src/ram_permutation/mod.rs @@ -0,0 +1,633 @@ +use super::*; + +use boojum::cs::traits::cs::ConstraintSystem; +use boojum::field::SmallField; +use boojum::gadgets::boolean::Boolean; +use boojum::gadgets::num::Num; +use boojum::gadgets::traits::selectable::Selectable; +use boojum::gadgets::u256::UInt256; +use boojum::gadgets::u32::UInt32; +use std::sync::Arc; + +use crate::base_structures::memory_query::MemoryQuery; +use crate::base_structures::memory_query::MEMORY_QUERY_PACKED_WIDTH; +use crate::fsm_input_output::circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH; +use crate::fsm_input_output::commit_variable_length_encodable_item; +use crate::fsm_input_output::ClosedFormInputCompactForm; +use crate::storage_validity_by_grand_product::unpacked_long_comparison; +use crate::utils::accumulate_grand_products; +use boojum::algebraic_props::round_function::AlgebraicRoundFunction; +use boojum::cs::gates::PublicInputGate; +use boojum::gadgets::queue::full_state_queue::FullStateCircuitQueueWitness; +use boojum::gadgets::queue::QueueState; +use boojum::gadgets::traits::allocatable::CSAllocatableExt; +use boojum::gadgets::traits::round_function::CircuitRoundFunction; + +use zkevm_opcode_defs::BOOTLOADER_HEAP_PAGE; + +pub mod input; +use input::*; + +pub fn ram_permutation_entry_point< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, +>( + cs: &mut CS, + closed_form_input_witness: RamPermutationCircuitInstanceWitness, + round_function: &R, + limit: usize, +) -> [Num; INPUT_OUTPUT_COMMITMENT_LENGTH] +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + let RamPermutationCircuitInstanceWitness { + closed_form_input, + unsorted_queue_witness, + sorted_queue_witness, + } = closed_form_input_witness; + + let mut structured_input = + RamPermutationCycleInputOutput::alloc_ignoring_outputs(cs, closed_form_input.clone()); + + let start_flag = structured_input.start_flag; + let observable_input = structured_input.observable_input.clone(); + let hidden_fsm_input = structured_input.hidden_fsm_input.clone(); + + // passthrought must be trivial + observable_input + .unsorted_queue_initial_state + .enforce_trivial_head(cs); + + let unsorted_queue_state = QueueState::conditionally_select( + cs, + start_flag, + &observable_input.unsorted_queue_initial_state, + &hidden_fsm_input.current_unsorted_queue_state, + ); + + use crate::boojum::gadgets::queue::full_state_queue::FullStateCircuitQueue; + let mut unsorted_queue: FullStateCircuitQueue< + F, + MemoryQuery, + 8, + 12, + 4, + MEMORY_QUERY_PACKED_WIDTH, + R, + > = MemoryQueriesQueue::from_state(cs, unsorted_queue_state); + + unsorted_queue.witness = Arc::new(FullStateCircuitQueueWitness::from_inner_witness( + unsorted_queue_witness, + )); + + // passthrought must be trivial + observable_input + .sorted_queue_initial_state + .enforce_trivial_head(cs); + + let sorted_queue_state = QueueState::conditionally_select( + cs, + start_flag, + &observable_input.sorted_queue_initial_state, + &hidden_fsm_input.current_sorted_queue_state, + ); + + let mut sorted_queue: FullStateCircuitQueue< + F, + MemoryQuery, + 8, + 12, + 4, + MEMORY_QUERY_PACKED_WIDTH, + R, + > = MemoryQueriesQueue::from_state(cs, sorted_queue_state); + + sorted_queue.witness = Arc::new(FullStateCircuitQueueWitness::from_inner_witness( + sorted_queue_witness, + )); + + // get challenges for permutation argument + let fs_challenges = crate::utils::produce_fs_challenges( + cs, + observable_input.unsorted_queue_initial_state.tail, + observable_input.sorted_queue_initial_state.tail, + round_function, + ); + + let num_one = Num::allocated_constant(cs, F::ONE); + let mut lhs = <[Num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS]>::conditionally_select( + cs, + start_flag, + &[num_one; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + &hidden_fsm_input.lhs_accumulator, + ); + let mut rhs = <[Num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS]>::conditionally_select( + cs, + start_flag, + &[num_one; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + &hidden_fsm_input.rhs_accumulator, + ); + + let uint32_zero = UInt32::zero(cs); + let mut num_nondeterministic_writes = UInt32::conditionally_select( + cs, + start_flag, + &uint32_zero, + &hidden_fsm_input.num_nondeterministic_writes, + ); + + let mut previous_sorting_key = hidden_fsm_input.previous_sorting_key; + let mut previous_full_key = hidden_fsm_input.previous_full_key; + let mut previous_value = hidden_fsm_input.previous_value; + let mut previous_is_ptr = hidden_fsm_input.previous_is_ptr; + + partial_accumulate_inner::( + cs, + &mut unsorted_queue, + &mut sorted_queue, + &fs_challenges, + start_flag, + &mut lhs, + &mut rhs, + &mut previous_sorting_key, + &mut previous_full_key, + &mut previous_value, + &mut previous_is_ptr, + &mut num_nondeterministic_writes, + limit, + ); + + unsorted_queue.enforce_consistency(cs); + sorted_queue.enforce_consistency(cs); + + let completed = unsorted_queue.length.is_zero(cs); + + for (lhs, rhs) in lhs.iter().zip(rhs.iter()) { + Num::conditionally_enforce_equal(cs, completed, lhs, rhs); + } + + let num_nondeterministic_writes_equal = UInt32::equals( + cs, + &num_nondeterministic_writes, + &observable_input.non_deterministic_bootloader_memory_snapshot_length, + ); + num_nondeterministic_writes_equal.conditionally_enforce_true(cs, completed); + + // form the final state + structured_input + .hidden_fsm_output + .num_nondeterministic_writes = num_nondeterministic_writes; + structured_input + .hidden_fsm_output + .current_unsorted_queue_state = unsorted_queue.into_state(); + structured_input + .hidden_fsm_output + .current_sorted_queue_state = sorted_queue.into_state(); + + structured_input.hidden_fsm_output.lhs_accumulator = lhs; + structured_input.hidden_fsm_output.rhs_accumulator = rhs; + + structured_input.hidden_fsm_output.previous_sorting_key = previous_sorting_key; + structured_input.hidden_fsm_output.previous_full_key = previous_full_key; + structured_input.hidden_fsm_output.previous_value = previous_value; + structured_input.hidden_fsm_output.previous_is_ptr = previous_is_ptr; + + structured_input.completion_flag = completed; + + structured_input.hook_compare_witness(cs, &closed_form_input); + + let compact_form = + ClosedFormInputCompactForm::from_full_form(cs, &structured_input, round_function); + + let input_commitment = commit_variable_length_encodable_item(cs, &compact_form, round_function); + for el in input_commitment.iter() { + let gate = PublicInputGate::new(el.get_variable()); + gate.add_to_cs(cs); + } + + input_commitment +} + +pub fn partial_accumulate_inner< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, +>( + cs: &mut CS, + unsorted_queue: &mut MemoryQueriesQueue, + sorted_queue: &mut MemoryQueriesQueue, + fs_challenges: &[[Num; MEMORY_QUERY_PACKED_WIDTH + 1]; + DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + is_start: Boolean, + lhs: &mut [Num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + rhs: &mut [Num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + previous_sorting_key: &mut [UInt32; RAM_SORTING_KEY_LENGTH], + previous_comparison_key: &mut [UInt32; RAM_FULL_KEY_LENGTH], + previous_element_value: &mut UInt256, + previous_is_ptr: &mut Boolean, + num_nondeterministic_writes: &mut UInt32, + limit: usize, +) where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); MEMORY_QUERY_PACKED_WIDTH]:, + [(); MEMORY_QUERY_PACKED_WIDTH + 1]:, +{ + let not_start = is_start.negated(cs); + Num::enforce_equal( + cs, + &unsorted_queue.length.into_num(), + &sorted_queue.length.into_num(), + ); + + let bootloader_heap_page = UInt32::allocated_constant(cs, BOOTLOADER_HEAP_PAGE); + let uint256_zero = UInt256::zero(cs); + + for _cycle in 0..limit { + let unsorted_is_empty = unsorted_queue.is_empty(cs); + let sorted_is_empty = sorted_queue.is_empty(cs); + + // this is an exotic way so synchronize popping from both queues + // in asynchronous resolution + Boolean::enforce_equal(cs, &unsorted_is_empty, &sorted_is_empty); + let can_pop = unsorted_is_empty.negated(cs); + + // we do not need any information about unsorted element other than it's encoding + let (_, unsorted_item_encoding) = unsorted_queue.pop_front(cs, can_pop); + let (sorted_item, sorted_item_encoding) = sorted_queue.pop_front(cs, can_pop); + + // check non-deterministic writes + { + let ts_is_zero = sorted_item.timestamp.is_zero(cs); + + let page_is_bootloader_heap = + UInt32::equals(cs, &sorted_item.memory_page, &bootloader_heap_page); + + let is_write = sorted_item.rw_flag; + let is_ptr = sorted_item.is_ptr; + let not_ptr = is_ptr.negated(cs); + + let is_nondeterministic_write = Boolean::multi_and( + cs, + &[ + can_pop, + ts_is_zero, + page_is_bootloader_heap, + is_write, + not_ptr, + ], + ); + + let num_nondeterministic_writes_incremented = + unsafe { UInt32::increment_unchecked(&num_nondeterministic_writes, cs) }; + + *num_nondeterministic_writes = UInt32::conditionally_select( + cs, + is_nondeterministic_write, + &num_nondeterministic_writes_incremented, + &num_nondeterministic_writes, + ); + } + + // check RAM ordering + { + // either continue the argument or do nothing + + let sorting_key = [ + sorted_item.timestamp, + sorted_item.index, + sorted_item.memory_page, + ]; + let comparison_key = [sorted_item.index, sorted_item.memory_page]; + + // ensure sorting + let (_keys_are_equal, previous_key_is_smaller) = + unpacked_long_comparison(cs, &sorting_key, previous_sorting_key); + + // we can not have previous sorting key even to be >= than our current key + + let keys_are_in_ascending_order = previous_key_is_smaller; + + if _cycle != 0 { + keys_are_in_ascending_order.conditionally_enforce_true(cs, can_pop); + } else { + let should_enforce = can_pop.and(cs, not_start); + keys_are_in_ascending_order.conditionally_enforce_true(cs, should_enforce); + } + + let same_memory_cell = long_equals(cs, &comparison_key, previous_comparison_key); + let value_equal = UInt256::equals(cs, &sorted_item.value, &previous_element_value); + + let not_same_cell = same_memory_cell.negated(cs); + let rw_flag = sorted_item.rw_flag; + let not_rw_flag = rw_flag.negated(cs); + + // check uninit read + let value_is_zero = UInt256::equals(cs, &sorted_item.value, &uint256_zero); + let is_ptr = sorted_item.is_ptr; + let not_ptr = is_ptr.negated(cs); + let is_zero = value_is_zero.and(cs, not_ptr); + let ptr_equality = Num::equals(cs, &previous_is_ptr.into_num(), &is_ptr.into_num()); + let value_and_ptr_equal = value_equal.and(cs, ptr_equality); + + // we only have a difference in these flags at the first step + if _cycle != 0 { + let read_uninitialized = not_same_cell.and(cs, not_rw_flag); + is_zero.conditionally_enforce_true(cs, read_uninitialized); + + // check standard RW validity + let check_equality = same_memory_cell.and(cs, not_rw_flag); + value_and_ptr_equal.conditionally_enforce_true(cs, check_equality); + } else { + // see if we continue the argument then all our checks should be valid, + // otherwise only read uninit should be enforced + + // if we start a fresh argument then our comparison + let read_uninitialized_if_continue = + Boolean::multi_and(cs, &[not_start, not_same_cell, not_rw_flag]); + let read_uninit_if_at_the_start = is_start.and(cs, not_rw_flag); + let should_enforce = + read_uninitialized_if_continue.or(cs, read_uninit_if_at_the_start); + is_zero.conditionally_enforce_true(cs, should_enforce); + + // check standard RW validity, but it can break if we are at the very start + let check_equality = + Boolean::multi_and(cs, &[same_memory_cell, not_rw_flag, not_start]); + value_and_ptr_equal.conditionally_enforce_true(cs, check_equality); + } + + *previous_sorting_key = sorting_key; + *previous_comparison_key = comparison_key; + *previous_element_value = sorted_item.value; + *previous_is_ptr = sorted_item.is_ptr; + } + + // if we did pop then accumulate to grand product + accumulate_grand_products::< + F, + CS, + MEMORY_QUERY_PACKED_WIDTH, + { MEMORY_QUERY_PACKED_WIDTH + 1 }, + DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS, + >( + cs, + lhs, + rhs, + fs_challenges, + &unsorted_item_encoding, + &sorted_item_encoding, + can_pop, + ); + } +} + +pub(crate) fn long_equals, const N: usize>( + cs: &mut CS, + a: &[UInt32; N], + b: &[UInt32; N], +) -> Boolean { + let equals: [_; N] = std::array::from_fn(|i| UInt32::equals(cs, &a[i], &b[i])); + + Boolean::multi_and(cs, &equals) +} + +#[cfg(test)] +mod tests { + use super::*; + use boojum::algebraic_props::poseidon2_parameters::Poseidon2GoldilocksExternalMatrix; + use boojum::cs::gates::*; + use boojum::cs::implementations::reference_cs::CSDevelopmentAssembly; + use boojum::cs::traits::gate::GatePlacementStrategy; + use boojum::cs::CSGeometry; + use boojum::cs::*; + use boojum::field::goldilocks::GoldilocksField; + use boojum::gadgets::tables::*; + use boojum::gadgets::traits::allocatable::CSPlaceholder; + use boojum::gadgets::u160::UInt160; + use boojum::gadgets::u256::UInt256; + use boojum::gadgets::u8::UInt8; + use boojum::implementations::poseidon2::Poseidon2Goldilocks; + use boojum::worker::Worker; + use ethereum_types::{Address, U256}; + type F = GoldilocksField; + type P = GoldilocksField; + + #[test] + fn test_ram_permutation_inner() { + let geometry = CSGeometry { + num_columns_under_copy_permutation: 100, + num_witness_columns: 0, + num_constant_columns: 8, + max_allowed_constraint_degree: 4, + }; + + use boojum::cs::cs_builder::*; + + fn configure< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + let builder = builder.allow_lookup( + LookupParameters::UseSpecializedColumnsWithTableIdAsConstant { + width: 3, + num_repetitions: 8, + share_table_id: true, + }, + ); + let builder = ConstantsAllocatorGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = FmaGateInBaseFieldWithoutConstant::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ReductionGate::::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = BooleanConstraintGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<32>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<16>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = SelectionGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ZeroCheckGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + false, + ); + let builder = DotProductGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = MatrixMultiplicationGate::::configure_builder(builder,GatePlacementStrategy::UseGeneralPurposeColumns); + let builder = NopGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + + builder + } + + use boojum::config::DevCSConfig; + use boojum::cs::cs_builder_reference::CsReferenceImplementationBuilder; + + let builder_impl = + CsReferenceImplementationBuilder::::new(geometry, 1 << 26, 1 << 20); + use boojum::cs::cs_builder::new_builder; + let builder = new_builder::<_, F>(builder_impl); + + let builder = configure(builder); + let mut owned_cs = builder.build(()); + + // add tables + let table = create_xor8_table(); + owned_cs.add_lookup_table::(table); + + let cs = &mut owned_cs; + + let execute = Boolean::allocated_constant(cs, true); + let mut original_queue = MemoryQueriesQueue::::empty(cs); + let unsorted_input = witness_input_unsorted(cs); + for el in unsorted_input { + original_queue.push(cs, el, execute); + } + let mut sorted_queue = MemoryQueriesQueue::::empty(cs); + let sorted_input = witness_input_sorted(cs); + for el in sorted_input { + sorted_queue.push(cs, el, execute); + } + + let mut lhs = [Num::allocated_constant(cs, F::from_nonreduced_u64(1)); + DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS]; + let mut rhs = [Num::allocated_constant(cs, F::from_nonreduced_u64(1)); + DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS]; + let is_start = Boolean::allocated_constant(cs, true); + let round_function = Poseidon2Goldilocks; + let fs_challenges = crate::utils::produce_fs_challenges( + cs, + original_queue.into_state().tail, + sorted_queue.into_state().tail, + &round_function, + ); + let limit = 16; + let mut previous_sorting_key = [UInt32::allocated_constant(cs, 0); RAM_SORTING_KEY_LENGTH]; + let mut previous_comparison_key = [UInt32::allocated_constant(cs, 0); RAM_FULL_KEY_LENGTH]; + let mut previous_element_value = + UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()); + let mut previous_is_ptr = Boolean::allocated_constant(cs, false); + let mut num_nondeterministic_writes = UInt32::allocated_constant(cs, 1); + partial_accumulate_inner( + cs, + &mut original_queue, + &mut sorted_queue, + &fs_challenges, + is_start, + &mut lhs, + &mut rhs, + &mut previous_sorting_key, + &mut previous_comparison_key, + &mut previous_element_value, + &mut previous_is_ptr, + &mut num_nondeterministic_writes, + limit, + ); + + cs.pad_and_shrink(); + let worker = Worker::new(); + let mut owned_cs = owned_cs.into_assembly(); + owned_cs.print_gate_stats(); + assert!(owned_cs.check_if_satisfied(&worker)); + } + + fn witness_input_unsorted>(cs: &mut CS) -> Vec> { + let mut unsorted_querie = vec![]; + let bool_false = Boolean::allocated_constant(cs, false); + let bool_true = Boolean::allocated_constant(cs, true); + + let q = MemoryQuery:: { + timestamp: UInt32::allocated_constant(cs, 1025), + memory_page: UInt32::allocated_constant(cs, 30), + index: UInt32::allocated_constant(cs, 0), + rw_flag: bool_false, + is_ptr: bool_false, + value: UInt256::allocated_constant(cs, U256::from_dec_str("1125899906842626").unwrap()), + }; + unsorted_querie.push(q); + + let q = MemoryQuery:: { + timestamp: UInt32::allocated_constant(cs, 1024), + memory_page: UInt32::allocated_constant(cs, 30), + index: UInt32::allocated_constant(cs, 0), + rw_flag: bool_true, + is_ptr: bool_false, + value: UInt256::allocated_constant(cs, U256::from_dec_str("1125899906842626").unwrap()), + }; + + unsorted_querie.push(q); + + let q = MemoryQuery:: { + timestamp: UInt32::allocated_constant(cs, 0), + memory_page: UInt32::allocated_constant(cs, BOOTLOADER_HEAP_PAGE), + index: UInt32::allocated_constant(cs, 695), + rw_flag: bool_true, + is_ptr: bool_false, + value: UInt256::allocated_constant(cs, U256::from_dec_str("12345678").unwrap()), + }; + unsorted_querie.push(q); + + unsorted_querie + } + + fn witness_input_sorted>(cs: &mut CS) -> Vec> { + let mut sorted_querie = vec![]; + let bool_false = Boolean::allocated_constant(cs, false); + let bool_true = Boolean::allocated_constant(cs, true); + + let q = MemoryQuery:: { + timestamp: UInt32::allocated_constant(cs, 0), + memory_page: UInt32::allocated_constant(cs, BOOTLOADER_HEAP_PAGE), + index: UInt32::allocated_constant(cs, 695), + rw_flag: bool_true, + is_ptr: bool_false, + value: UInt256::allocated_constant(cs, U256::from_dec_str("12345678").unwrap()), + }; + sorted_querie.push(q); + + let q = MemoryQuery:: { + timestamp: UInt32::allocated_constant(cs, 1024), + memory_page: UInt32::allocated_constant(cs, 30), + index: UInt32::allocated_constant(cs, 0), + rw_flag: bool_true, + is_ptr: bool_false, + value: UInt256::allocated_constant(cs, U256::from_dec_str("1125899906842626").unwrap()), + }; + sorted_querie.push(q); + + let q = MemoryQuery:: { + timestamp: UInt32::allocated_constant(cs, 1025), + memory_page: UInt32::allocated_constant(cs, 30), + index: UInt32::allocated_constant(cs, 0), + rw_flag: bool_false, + is_ptr: bool_false, + value: UInt256::allocated_constant(cs, U256::from_dec_str("1125899906842626").unwrap()), + }; + sorted_querie.push(q); + + sorted_querie + } +} diff --git a/crates/zkevm_circuits/src/recursion/compression/input.rs b/crates/zkevm_circuits/src/recursion/compression/input.rs new file mode 100644 index 0000000..b9cb60e --- /dev/null +++ b/crates/zkevm_circuits/src/recursion/compression/input.rs @@ -0,0 +1,23 @@ +use super::*; + +use boojum::cs::implementations::proof::Proof; +use boojum::field::FieldExtension; +use boojum::field::SmallField; +use boojum::gadgets::num::Num; +use boojum::gadgets::recursion::recursive_tree_hasher::RecursiveTreeHasher; +use boojum::gadgets::traits::allocatable::CSAllocatable; +use std::collections::VecDeque; + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Debug, Default(bound = ""))] +#[serde( + bound = ">::Witness: serde::Serialize + serde::de::DeserializeOwned" +)] +pub struct CompressionCircuitInstanceWitness< + F: SmallField, + H: RecursiveTreeHasher>, + EXT: FieldExtension<2, BaseField = F>, +> { + #[derivative(Debug = "ignore")] + pub proof_witness: Option>, +} diff --git a/crates/zkevm_circuits/src/recursion/compression/mod.rs b/crates/zkevm_circuits/src/recursion/compression/mod.rs new file mode 100644 index 0000000..0bd8c1b --- /dev/null +++ b/crates/zkevm_circuits/src/recursion/compression/mod.rs @@ -0,0 +1,121 @@ +use super::*; + +pub mod input; +pub use self::input::*; + +use crate::fsm_input_output::circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH; +use boojum::algebraic_props::round_function::AlgebraicRoundFunction; +use boojum::config::*; +use boojum::cs::implementations::proof::Proof; +use boojum::cs::implementations::prover::ProofConfig; +use boojum::cs::implementations::verifier::VerificationKey; +use boojum::cs::oracle::TreeHasher; +use boojum::cs::traits::circuit::ErasedBuilderForRecursiveVerifier; +use boojum::cs::traits::cs::ConstraintSystem; +use boojum::field::FieldExtension; +use boojum::field::SmallField; +use boojum::gadgets::boolean::Boolean; +use boojum::gadgets::num::Num; +use boojum::gadgets::recursion::allocated_proof::AllocatedProof; +use boojum::gadgets::recursion::allocated_vk::AllocatedVerificationKey; +use boojum::gadgets::recursion::circuit_pow::RecursivePoWRunner; +use boojum::gadgets::recursion::recursive_transcript::*; +use boojum::gadgets::recursion::recursive_tree_hasher::*; +use boojum::gadgets::traits::allocatable::CSAllocatable; +use boojum::gadgets::traits::round_function::CircuitRoundFunction; + +// We recursively verify SINGLE proofs over FIXED VK and output it's inputs + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Debug)] +#[serde(bound = "H::Output: serde::Serialize + serde::de::DeserializeOwned")] +pub struct CompressionRecursionConfig< + F: SmallField, + H: TreeHasher, + EXT: FieldExtension<2, BaseField = F>, +> { + pub proof_config: ProofConfig, + pub verification_key: VerificationKey, + pub _marker: std::marker::PhantomData<(F, H, EXT)>, +} + +pub fn proof_compression_function< + F: SmallField, + CS: ConstraintSystem + 'static, + H: RecursiveTreeHasher>, + EXT: FieldExtension<2, BaseField = F>, + TR: RecursiveTranscript< + F, + CompatibleCap = >::Output, + CircuitReflection = CTR, + >, + CTR: CircuitTranscript< + F, + CircuitCompatibleCap = >>::CircuitOutput, + TransciptParameters = TR::TransciptParameters, + >, + POW: RecursivePoWRunner, +>( + cs: &mut CS, + witness: CompressionCircuitInstanceWitness, + config: CompressionRecursionConfig, + verifier_builder: Box>, + transcript_params: TR::TransciptParameters, +) { + let CompressionCircuitInstanceWitness { proof_witness } = witness; + + // as usual - create verifier for FIXED VK, verify, aggregate inputs, output inputs + + let CompressionRecursionConfig { + proof_config, + verification_key, + .. + } = config; + + // use this and deal with borrow checker + + let r = cs as *mut CS; + + assert_eq!( + verification_key.fixed_parameters.parameters, + verifier_builder.geometry() + ); + + let fixed_parameters = verification_key.fixed_parameters.clone(); + + let verifier = verifier_builder.create_recursive_verifier(cs); + + let cs = unsafe { &mut *r }; + + let vk = AllocatedVerificationKey::allocate_constant(cs, verification_key); + + let proof = AllocatedProof::allocate_from_witness( + cs, + proof_witness, + &verifier, + &fixed_parameters, + &proof_config, + ); + + // verify the proof + let (is_valid, public_inputs) = verifier.verify::( + cs, + transcript_params.clone(), + &proof, + &fixed_parameters, + &proof_config, + &vk, + ); + + let boolean_true = Boolean::allocated_constant(cs, true); + Boolean::enforce_equal(cs, &is_valid, &boolean_true); + + assert_eq!(public_inputs.len(), INPUT_OUTPUT_COMMITMENT_LENGTH); + assert_eq!(public_inputs.len(), fixed_parameters.num_public_inputs()); + + for el in public_inputs.into_iter() { + use boojum::cs::gates::PublicInputGate; + let gate = PublicInputGate::new(el.get_variable()); + gate.add_to_cs(cs); + } +} diff --git a/crates/zkevm_circuits/src/recursion/interblock/input.rs b/crates/zkevm_circuits/src/recursion/interblock/input.rs new file mode 100644 index 0000000..9c24e61 --- /dev/null +++ b/crates/zkevm_circuits/src/recursion/interblock/input.rs @@ -0,0 +1,23 @@ +use super::*; + +use boojum::cs::implementations::proof::Proof; +use boojum::field::FieldExtension; +use boojum::field::SmallField; +use boojum::gadgets::num::Num; +use boojum::gadgets::recursion::recursive_tree_hasher::RecursiveTreeHasher; +use boojum::gadgets::traits::allocatable::CSAllocatable; +use std::collections::VecDeque; + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Debug, Default(bound = ""))] +#[serde( + bound = ">::Witness: serde::Serialize + serde::de::DeserializeOwned" +)] +pub struct InterblockRecursionCircuitInstanceWitness< + F: SmallField, + H: RecursiveTreeHasher>, + EXT: FieldExtension<2, BaseField = F>, +> { + #[derivative(Debug = "ignore")] + pub proof_witnesses: VecDeque>, +} diff --git a/crates/zkevm_circuits/src/recursion/interblock/keccak_aggregator.rs b/crates/zkevm_circuits/src/recursion/interblock/keccak_aggregator.rs new file mode 100644 index 0000000..9adc5cf --- /dev/null +++ b/crates/zkevm_circuits/src/recursion/interblock/keccak_aggregator.rs @@ -0,0 +1,96 @@ +use boojum::gadgets::{traits::selectable::Selectable, u8::UInt8}; + +use super::*; + +pub struct KeccakPublicInputAggregator< + F: SmallField, + const N: usize, + const IS_BE: bool, + const NUM_OUTS: usize, +> { + pub masking_value: u8, + _marker: std::marker::PhantomData, +} + +impl + InputAggregationFunction for KeccakPublicInputAggregator +{ + type Params = u8; + + fn new>(_cs: &mut CS, params: Self::Params) -> Self { + Self { + masking_value: params, + _marker: std::marker::PhantomData, + } + } + fn aggregate_inputs>( + &self, + cs: &mut CS, + inputs: &[Vec>], + validity_flags: &[Boolean], + ) -> Vec> { + assert_eq!(inputs.len(), N); + assert_eq!(validity_flags.len(), N); + + let masking_value = UInt8::allocated_constant(cs, self.masking_value); + + let mut input_flattened_bytes = Vec::with_capacity(32 * N); + let zero_u8 = UInt8::zero(cs); + let take_by = F::CAPACITY_BITS / 8; + + let mut total_byte_len = take_by; + if F::CAPACITY_BITS % 8 != 0 { + total_byte_len += 1; + } + + for (validity_flag, input) in validity_flags.iter().zip(inputs.iter()) { + assert_eq!(input.len(), INPUT_OUTPUT_COMMITMENT_LENGTH); + + // transform to bytes + for src in input.iter() { + let mut bytes: arrayvec::ArrayVec, 8> = + src.constraint_bit_length_as_bytes(cs, total_byte_len); // le + if F::CAPACITY_BITS % 8 != 0 { + for el in bytes[take_by..].iter() { + // assert byte is 0 + Num::conditionally_enforce_equal( + cs, + *validity_flag, + &el.into_num(), + &zero_u8.into_num(), + ); + } + } + // mask if necessary + for el in bytes[..take_by].iter_mut() { + *el = UInt8::conditionally_select(cs, *validity_flag, &*el, &masking_value); + } + + if IS_BE { + input_flattened_bytes.extend(bytes[..take_by].iter().copied().rev()); + } else { + input_flattened_bytes.extend_from_slice(&bytes[..take_by]); + } + } + } + + // run keccak over it + use boojum::gadgets::keccak256; + let aggregated_keccak_hash = keccak256::keccak256(cs, &input_flattened_bytes); + + let mut result = Vec::with_capacity(NUM_OUTS); + + // and make it our publid input + for chunk in aggregated_keccak_hash.chunks_exact(take_by).take(NUM_OUTS) { + let mut lc = Vec::with_capacity(chunk.len()); + // treat as BE + for (idx, el) in chunk.iter().rev().enumerate() { + lc.push((el.get_variable(), F::SHIFTS[idx * 8])); + } + let as_num = Num::linear_combination(cs, &lc); + result.push(as_num); + } + + result + } +} diff --git a/crates/zkevm_circuits/src/recursion/interblock/mod.rs b/crates/zkevm_circuits/src/recursion/interblock/mod.rs new file mode 100644 index 0000000..d0e45e2 --- /dev/null +++ b/crates/zkevm_circuits/src/recursion/interblock/mod.rs @@ -0,0 +1,154 @@ +use super::*; + +pub mod input; +pub use self::input::*; + +pub mod keccak_aggregator; + +use crate::fsm_input_output::circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH; +use boojum::algebraic_props::round_function::AlgebraicRoundFunction; +use boojum::config::*; +use boojum::cs::implementations::proof::Proof; +use boojum::cs::implementations::prover::ProofConfig; +use boojum::cs::implementations::verifier::VerificationKey; +use boojum::cs::oracle::TreeHasher; +use boojum::cs::traits::circuit::ErasedBuilderForRecursiveVerifier; +use boojum::cs::traits::cs::ConstraintSystem; +use boojum::field::FieldExtension; +use boojum::field::SmallField; +use boojum::gadgets::boolean::Boolean; +use boojum::gadgets::num::Num; +use boojum::gadgets::recursion::allocated_proof::AllocatedProof; +use boojum::gadgets::recursion::allocated_vk::AllocatedVerificationKey; +use boojum::gadgets::recursion::circuit_pow::RecursivePoWRunner; +use boojum::gadgets::recursion::recursive_transcript::*; +use boojum::gadgets::recursion::recursive_tree_hasher::*; +use boojum::gadgets::traits::allocatable::CSAllocatable; +use boojum::gadgets::traits::round_function::CircuitRoundFunction; + +// performs recursion between "independent" units for FIXED verification key + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Debug)] +#[serde(bound = "H::Output: serde::Serialize + serde::de::DeserializeOwned")] +pub struct InterblockRecursionConfig< + F: SmallField, + H: TreeHasher, + EXT: FieldExtension<2, BaseField = F>, +> { + pub proof_config: ProofConfig, + pub verification_key: VerificationKey, + pub capacity: usize, + pub _marker: std::marker::PhantomData<(F, H, EXT)>, +} + +pub trait InputAggregationFunction { + type Params; + + fn new>(cs: &mut CS, params: Self::Params) -> Self; + fn aggregate_inputs>( + &self, + cs: &mut CS, + inputs: &[Vec>], + validity_flags: &[Boolean], + ) -> Vec>; +} + +pub fn interblock_recursion_function< + F: SmallField, + CS: ConstraintSystem + 'static, + H: RecursiveTreeHasher>, + EXT: FieldExtension<2, BaseField = F>, + TR: RecursiveTranscript< + F, + CompatibleCap = >::Output, + CircuitReflection = CTR, + >, + CTR: CircuitTranscript< + F, + CircuitCompatibleCap = >>::CircuitOutput, + TransciptParameters = TR::TransciptParameters, + >, + POW: RecursivePoWRunner, + AGG: InputAggregationFunction, +>( + cs: &mut CS, + witness: InterblockRecursionCircuitInstanceWitness, + config: InterblockRecursionConfig, + verifier_builder: Box>, + transcript_params: TR::TransciptParameters, + aggregation_params: AGG::Params, +) { + let InterblockRecursionCircuitInstanceWitness { proof_witnesses } = witness; + let mut proof_witnesses = proof_witnesses; + + // as usual - create verifier for FIXED VK, verify, aggregate inputs, output inputs + + let InterblockRecursionConfig { + proof_config, + verification_key, + capacity, + .. + } = config; + + // use this and deal with borrow checker + + let r = cs as *mut CS; + + assert_eq!( + verification_key.fixed_parameters.parameters, + verifier_builder.geometry() + ); + + let fixed_parameters = verification_key.fixed_parameters.clone(); + + let verifier = verifier_builder.create_recursive_verifier(cs); + + let cs = unsafe { &mut *r }; + + let mut validity_flags = Vec::with_capacity(capacity); + let mut inputs = Vec::with_capacity(capacity); + + let vk = AllocatedVerificationKey::allocate_constant(cs, verification_key); + + for _ in 0..capacity { + let proof_witness = proof_witnesses.pop_front(); + + let proof = AllocatedProof::allocate_from_witness( + cs, + proof_witness, + &verifier, + &fixed_parameters, + &proof_config, + ); + + // verify the proof + let (is_valid, public_inputs) = verifier.verify::( + cs, + transcript_params.clone(), + &proof, + &fixed_parameters, + &proof_config, + &vk, + ); + + assert_eq!(public_inputs.len(), INPUT_OUTPUT_COMMITMENT_LENGTH); + assert_eq!(public_inputs.len(), fixed_parameters.num_public_inputs()); + + validity_flags.push(is_valid); + inputs.push(public_inputs); + } + + // now actually aggregate + + let aggregator = AGG::new(cs, aggregation_params); + let aggregated_input = aggregator.aggregate_inputs(cs, &inputs, &validity_flags); + + assert_eq!(aggregated_input.len(), INPUT_OUTPUT_COMMITMENT_LENGTH); + + for el in aggregated_input.into_iter() { + use boojum::cs::gates::PublicInputGate; + let gate = PublicInputGate::new(el.get_variable()); + gate.add_to_cs(cs); + } +} diff --git a/crates/zkevm_circuits/src/recursion/leaf_layer/input.rs b/crates/zkevm_circuits/src/recursion/leaf_layer/input.rs new file mode 100644 index 0000000..6f4153a --- /dev/null +++ b/crates/zkevm_circuits/src/recursion/leaf_layer/input.rs @@ -0,0 +1,83 @@ +use super::*; +use crate::base_structures::recursion_query::*; +use crate::base_structures::vm_state::*; +use boojum::cs::implementations::proof::Proof; +use boojum::cs::implementations::verifier::VerificationKey; +use boojum::cs::{traits::cs::ConstraintSystem, Variable}; +use boojum::field::SmallField; +use boojum::gadgets::num::Num; +use boojum::gadgets::queue::full_state_queue::FullStateCircuitQueueRawWitness; +use boojum::gadgets::traits::auxiliary::PrettyComparison; +use boojum::gadgets::{ + boolean::Boolean, + traits::{ + allocatable::*, encodable::CircuitVarLengthEncodable, selectable::Selectable, + witnessable::WitnessHookable, + }, +}; +use cs_derive::*; + +use boojum::field::FieldExtension; +use boojum::serde_utils::BigArraySerde; + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +#[DerivePrettyComparison("true")] +pub struct RecursionLeafParameters { + pub circuit_type: Num, + pub basic_circuit_vk_commitment: [Num; VK_COMMITMENT_LENGTH], + pub leaf_layer_vk_commitment: [Num; VK_COMMITMENT_LENGTH], +} + +impl CSPlaceholder for RecursionLeafParameters { + fn placeholder>(cs: &mut CS) -> Self { + let zero = Num::zero(cs); + Self { + circuit_type: zero, + basic_circuit_vk_commitment: [zero; VK_COMMITMENT_LENGTH], + leaf_layer_vk_commitment: [zero; VK_COMMITMENT_LENGTH], + } + } +} + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +#[DerivePrettyComparison("true")] +pub struct RecursionLeafInput { + pub params: RecursionLeafParameters, + pub queue_state: QueueState, +} + +impl CSPlaceholder for RecursionLeafInput { + fn placeholder>(cs: &mut CS) -> Self { + Self { + params: RecursionLeafParameters::placeholder(cs), + queue_state: QueueState::::placeholder(cs), + } + } +} + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative( + Clone, + Debug(bound = ""), + Default(bound = "RecursionLeafInputWitness: Default") +)] +#[serde( + bound = ">::Witness: serde::Serialize + serde::de::DeserializeOwned" +)] +pub struct RecursionLeafInstanceWitness< + F: SmallField, + H: RecursiveTreeHasher>, + EXT: FieldExtension<2, BaseField = F>, +> { + pub input: RecursionLeafInputWitness, + pub vk_witness: VerificationKey, + pub queue_witness: FullStateCircuitQueueRawWitness< + F, + RecursionQuery, + FULL_SPONGE_QUEUE_STATE_WIDTH, + RECURSION_QUERY_PACKED_WIDTH, + >, + pub proof_witnesses: VecDeque>, +} diff --git a/crates/zkevm_circuits/src/recursion/leaf_layer/mod.rs b/crates/zkevm_circuits/src/recursion/leaf_layer/mod.rs new file mode 100644 index 0000000..645f2d6 --- /dev/null +++ b/crates/zkevm_circuits/src/recursion/leaf_layer/mod.rs @@ -0,0 +1,214 @@ +use crate::base_structures::recursion_query::{RecursionQuery, RecursionQueue}; +use crate::fsm_input_output::commit_variable_length_encodable_item; +use boojum::cs::implementations::proof::Proof; +use boojum::cs::implementations::prover::ProofConfig; +use boojum::gadgets::recursion::allocated_proof::AllocatedProof; +use boojum::gadgets::recursion::allocated_vk::AllocatedVerificationKey; +use boojum::gadgets::recursion::recursive_transcript::RecursiveTranscript; +use boojum::gadgets::recursion::recursive_tree_hasher::RecursiveTreeHasher; + +use std::collections::VecDeque; +use std::sync::Arc; + +use crate::fsm_input_output::circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH; +use boojum::algebraic_props::round_function::AlgebraicRoundFunction; +use boojum::config::*; +use boojum::cs::traits::circuit::ErasedBuilderForRecursiveVerifier; +use boojum::cs::{gates::*, traits::cs::ConstraintSystem}; +use boojum::field::SmallField; +use boojum::gadgets::queue::full_state_queue::FullStateCircuitQueueWitness; +use boojum::gadgets::traits::round_function::CircuitRoundFunction; +use boojum::gadgets::{ + boolean::Boolean, + num::Num, + queue::*, + traits::{allocatable::CSAllocatable, allocatable::CSAllocatableExt}, +}; + +use super::*; + +pub mod input; + +use self::input::*; + +use boojum::cs::implementations::verifier::VerificationKeyCircuitGeometry; +use boojum::cs::oracle::TreeHasher; +use boojum::field::FieldExtension; +use boojum::gadgets::recursion::circuit_pow::RecursivePoWRunner; +use boojum::gadgets::recursion::recursive_transcript::CircuitTranscript; +use boojum::gadgets::recursion::recursive_tree_hasher::CircuitTreeHasher; + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Debug(bound = ""))] +#[serde(bound = "H::Output: serde::Serialize + serde::de::DeserializeOwned")] +pub struct LeafLayerRecursionConfig< + F: SmallField, + H: TreeHasher, + EXT: FieldExtension<2, BaseField = F>, +> { + pub proof_config: ProofConfig, + pub vk_fixed_parameters: VerificationKeyCircuitGeometry, + pub capacity: usize, + pub _marker: std::marker::PhantomData<(F, H, EXT)>, +} + +// NOTE: does NOT allocate public inputs! we will deal with locations of public inputs being the same at the "outer" stage +pub fn leaf_layer_recursion_entry_point< + F: SmallField, + CS: ConstraintSystem + 'static, + R: CircuitRoundFunction + AlgebraicRoundFunction, + H: RecursiveTreeHasher>, + EXT: FieldExtension<2, BaseField = F>, + TR: RecursiveTranscript< + F, + CompatibleCap = >::Output, + CircuitReflection = CTR, + >, + CTR: CircuitTranscript< + F, + CircuitCompatibleCap = >>::CircuitOutput, + TransciptParameters = TR::TransciptParameters, + >, + POW: RecursivePoWRunner, +>( + cs: &mut CS, + witness: RecursionLeafInstanceWitness, + round_function: &R, + config: LeafLayerRecursionConfig, + verifier_builder: Box>, + transcript_params: TR::TransciptParameters, +) -> [Num; INPUT_OUTPUT_COMMITMENT_LENGTH] +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + let RecursionLeafInstanceWitness { + input, + vk_witness, + queue_witness, + proof_witnesses, + } = witness; + + let input = RecursionLeafInput::allocate(cs, input); + let RecursionLeafInput { + params, + queue_state, + } = input; + let mut queue = RecursionQueue::::from_state(cs, queue_state); + + let RecursionLeafParameters { + circuit_type, + leaf_layer_vk_commitment: _, + basic_circuit_vk_commitment, + } = params; + + queue.witness = Arc::new(FullStateCircuitQueueWitness::from_inner_witness( + queue_witness, + )); + + queue.enforce_consistency(cs); + + // small trick to simplify setup. If we have nothing to verify, we do not care about VK + // being one that we want + let is_meaningful = queue.is_empty(cs).negated(cs); + + let vk = AllocatedVerificationKey::::allocate(cs, vk_witness); + assert_eq!( + vk.setup_merkle_tree_cap.len(), + config.vk_fixed_parameters.cap_size + ); + let vk_commitment_computed: [_; VK_COMMITMENT_LENGTH] = + commit_variable_length_encodable_item(cs, &vk, round_function); + + for (a, b) in basic_circuit_vk_commitment + .iter() + .zip(vk_commitment_computed.iter()) + { + Num::conditionally_enforce_equal(cs, is_meaningful, a, b); + } + + let mut proof_witnesses = proof_witnesses; + + let LeafLayerRecursionConfig { + proof_config, + vk_fixed_parameters, + capacity, + .. + } = config; + + // use this and deal with borrow checker + + let r = cs as *mut CS; + + assert_eq!(vk_fixed_parameters.parameters, verifier_builder.geometry()); + + let verifier = verifier_builder.create_recursive_verifier(cs); + + drop(cs); + + let cs = unsafe { &mut *r }; + + for _ in 0..capacity { + let proof_witness = proof_witnesses.pop_front(); + + let proof = AllocatedProof::allocate_from_witness( + cs, + proof_witness, + &verifier, + &vk_fixed_parameters, + &proof_config, + ); + + let queue_is_empty = queue.is_empty(cs); + let can_pop = queue_is_empty.negated(cs); + + let (recursive_request, _) = queue.pop_front(cs, can_pop); + + // ensure that it's an expected type + Num::conditionally_enforce_equal( + cs, + can_pop, + &recursive_request.circuit_type, + &circuit_type, + ); + + // verify the proof + let (is_valid, public_inputs) = verifier.verify::( + cs, + transcript_params.clone(), + &proof, + &vk_fixed_parameters, + &proof_config, + &vk, + ); + + assert_eq!(public_inputs.len(), INPUT_OUTPUT_COMMITMENT_LENGTH); + + // expected proof should be valid + is_valid.conditionally_enforce_true(cs, can_pop); + + // enforce publici inputs + + for (a, b) in recursive_request + .input_commitment + .iter() + .zip(public_inputs.iter()) + { + Num::conditionally_enforce_equal(cs, can_pop, a, b); + } + } + + queue.enforce_consistency(cs); + + let queue_is_empty = queue.is_empty(cs); + let boolean_true = Boolean::allocated_constant(cs, true); + Boolean::enforce_equal(cs, &queue_is_empty, &boolean_true); + + let input_commitment: [_; INPUT_OUTPUT_COMMITMENT_LENGTH] = + commit_variable_length_encodable_item(cs, &input, round_function); + // for el in input_commitment.iter() { + // let gate = PublicInputGate::new(el.get_variable()); + // gate.add_to_cs(cs); + // } + + input_commitment +} diff --git a/crates/zkevm_circuits/src/recursion/mod.rs b/crates/zkevm_circuits/src/recursion/mod.rs new file mode 100644 index 0000000..7923239 --- /dev/null +++ b/crates/zkevm_circuits/src/recursion/mod.rs @@ -0,0 +1,9 @@ +use super::*; + +pub mod compression; +pub mod interblock; +pub mod leaf_layer; +pub mod node_layer; + +pub const VK_COMMITMENT_LENGTH: usize = 4; +pub const NUM_BASE_LAYER_CIRCUITS: usize = 13; diff --git a/crates/zkevm_circuits/src/recursion/node_layer/input.rs b/crates/zkevm_circuits/src/recursion/node_layer/input.rs new file mode 100644 index 0000000..77db03b --- /dev/null +++ b/crates/zkevm_circuits/src/recursion/node_layer/input.rs @@ -0,0 +1,61 @@ +use super::*; +use boojum::cs::implementations::proof::Proof; +use boojum::cs::implementations::verifier::VerificationKey; +use boojum::cs::{traits::cs::ConstraintSystem, Variable}; +use boojum::field::SmallField; + +use boojum::gadgets::traits::auxiliary::PrettyComparison; +use boojum::gadgets::{ + boolean::Boolean, + traits::{ + allocatable::*, encodable::CircuitVarLengthEncodable, selectable::Selectable, + witnessable::WitnessHookable, + }, +}; +use cs_derive::*; + +use crate::base_structures::vm_state::*; +use boojum::gadgets::num::Num; + +use crate::recursion::leaf_layer::input::RecursionLeafParameters; +use boojum::field::FieldExtension; +use boojum::serde_utils::BigArraySerde; + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +#[DerivePrettyComparison("true")] +pub struct RecursionNodeInput { + pub branch_circuit_type: Num, + pub leaf_layer_parameters: [RecursionLeafParameters; NUM_BASE_LAYER_CIRCUITS], + pub node_layer_vk_commitment: [Num; VK_COMMITMENT_LENGTH], + pub queue_state: QueueState, +} + +impl CSPlaceholder for RecursionNodeInput { + fn placeholder>(cs: &mut CS) -> Self { + let zero = Num::zero(cs); + let leaf_layer_param = RecursionLeafParameters::placeholder(cs); + Self { + branch_circuit_type: zero, + leaf_layer_parameters: [leaf_layer_param; NUM_BASE_LAYER_CIRCUITS], + node_layer_vk_commitment: [zero; VK_COMMITMENT_LENGTH], + queue_state: QueueState::::placeholder(cs), + } + } +} + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Debug, Default(bound = "RecursionNodeInputWitness: Default"))] +#[serde( + bound = ">::Witness: serde::Serialize + serde::de::DeserializeOwned" +)] +pub struct RecursionNodeInstanceWitness< + F: SmallField, + H: RecursiveTreeHasher>, + EXT: FieldExtension<2, BaseField = F>, +> { + pub input: RecursionNodeInputWitness, + pub vk_witness: VerificationKey, + pub split_points: VecDeque>, + pub proof_witnesses: VecDeque>, +} diff --git a/crates/zkevm_circuits/src/recursion/node_layer/mod.rs b/crates/zkevm_circuits/src/recursion/node_layer/mod.rs new file mode 100644 index 0000000..35f4454 --- /dev/null +++ b/crates/zkevm_circuits/src/recursion/node_layer/mod.rs @@ -0,0 +1,316 @@ +use crate::base_structures::recursion_query::RecursionQuery; +use crate::fsm_input_output::commit_variable_length_encodable_item; +use boojum::cs::implementations::proof::Proof; +use boojum::cs::implementations::prover::ProofConfig; + +use crate::base_structures::recursion_query::RecursionQueue; +use boojum::gadgets::recursion::allocated_proof::AllocatedProof; +use boojum::gadgets::recursion::allocated_vk::AllocatedVerificationKey; +use boojum::gadgets::recursion::recursive_transcript::RecursiveTranscript; +use boojum::gadgets::recursion::recursive_tree_hasher::RecursiveTreeHasher; +use boojum::gadgets::traits::witnessable::WitnessHookable; + +use std::collections::VecDeque; + +use crate::fsm_input_output::circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH; +use boojum::algebraic_props::round_function::AlgebraicRoundFunction; +use boojum::cs::{gates::*, traits::cs::ConstraintSystem}; +use boojum::field::SmallField; +use boojum::gadgets::traits::round_function::CircuitRoundFunction; +use boojum::gadgets::{ + boolean::Boolean, + num::Num, + queue::*, + traits::{allocatable::CSAllocatable, allocatable::CSAllocatableExt, selectable::Selectable}, +}; + +use boojum::config::*; +use boojum::gadgets::u32::UInt32; + +use super::*; + +pub mod input; + +use self::input::*; + +use boojum::cs::implementations::verifier::VerificationKeyCircuitGeometry; +use boojum::cs::oracle::TreeHasher; +use boojum::field::FieldExtension; +use boojum::gadgets::recursion::circuit_pow::RecursivePoWRunner; +use boojum::gadgets::recursion::recursive_transcript::CircuitTranscript; +use boojum::gadgets::recursion::recursive_tree_hasher::CircuitTreeHasher; + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Debug(bound = ""))] +#[serde(bound = "H::Output: serde::Serialize + serde::de::DeserializeOwned")] +pub struct NodeLayerRecursionConfig< + F: SmallField, + H: TreeHasher, + EXT: FieldExtension<2, BaseField = F>, +> { + pub proof_config: ProofConfig, + pub vk_fixed_parameters: VerificationKeyCircuitGeometry, + pub leaf_layer_capacity: usize, + pub node_layer_capacity: usize, + pub _marker: std::marker::PhantomData<(F, H, EXT)>, +} + +use boojum::cs::traits::circuit::*; + +// NOTE: does NOT allocate public inputs! we will deal with locations of public inputs being the same at the "outer" stage +pub fn node_layer_recursion_entry_point< + F: SmallField, + CS: ConstraintSystem + 'static, + R: CircuitRoundFunction + AlgebraicRoundFunction, + H: RecursiveTreeHasher>, + EXT: FieldExtension<2, BaseField = F>, + TR: RecursiveTranscript< + F, + CompatibleCap = >::Output, + CircuitReflection = CTR, + >, + CTR: CircuitTranscript< + F, + CircuitCompatibleCap = >>::CircuitOutput, + TransciptParameters = TR::TransciptParameters, + >, + POW: RecursivePoWRunner, +>( + cs: &mut CS, + witness: RecursionNodeInstanceWitness, + round_function: &R, + config: NodeLayerRecursionConfig, + verifier_builder: Box>, + transcript_params: TR::TransciptParameters, +) -> [Num; INPUT_OUTPUT_COMMITMENT_LENGTH] +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + let RecursionNodeInstanceWitness { + input, + vk_witness, + split_points, + proof_witnesses, + } = witness; + + let input = RecursionNodeInput::allocate(cs, input); + let RecursionNodeInput { + branch_circuit_type, + leaf_layer_parameters, + node_layer_vk_commitment, + queue_state, + } = input; + + assert_eq!(config.vk_fixed_parameters, vk_witness.fixed_parameters,); + + let vk = AllocatedVerificationKey::::allocate(cs, vk_witness); + assert_eq!( + vk.setup_merkle_tree_cap.len(), + config.vk_fixed_parameters.cap_size + ); + let vk_commitment_computed: [_; VK_COMMITMENT_LENGTH] = + commit_variable_length_encodable_item(cs, &vk, round_function); + + // select over which branch we work + use crate::recursion::leaf_layer::input::RecursionLeafParameters; + use boojum::gadgets::traits::allocatable::CSPlaceholder; + let mut leaf_params = RecursionLeafParameters::placeholder(cs); + + for el in leaf_layer_parameters.iter() { + let this_type = Num::equals(cs, &branch_circuit_type, &el.circuit_type); + leaf_params = + RecursionLeafParameters::conditionally_select(cs, this_type, el, &leaf_params); + } + + // now we need to try to split the circuit + + let NodeLayerRecursionConfig { + proof_config, + vk_fixed_parameters, + leaf_layer_capacity, + node_layer_capacity, + .. + } = config; + + let max_length_if_leafs = leaf_layer_capacity * node_layer_capacity; + let max_length_if_leafs = UInt32::allocated_constant(cs, max_length_if_leafs as u32); + // if queue length is <= max_length_if_leafs then next layer we aggregate leafs, or aggregate nodes otherwise + let (_, uf) = max_length_if_leafs.overflowing_sub(cs, queue_state.tail.length); + let next_layer_aggregates_nodes = uf; + let next_layer_aggregates_leafs = next_layer_aggregates_nodes.negated(cs); + + let mut vk_commitment = leaf_params.leaf_layer_vk_commitment; + + vk_commitment = <[Num; VK_COMMITMENT_LENGTH]>::conditionally_select( + cs, + next_layer_aggregates_nodes, + &node_layer_vk_commitment, + &vk_commitment, + ); + + // small trick to simplify setup. If we have nothing to verify, we do not care about VK + // being one that we want + let is_meaningful = RecursionQueue::::from_state(cs, queue_state) + .is_empty(cs) + .negated(cs); + + for (a, b) in vk_commitment.iter().zip(vk_commitment_computed.iter()) { + Num::conditionally_enforce_equal(cs, is_meaningful, a, b); + } + + // split the original queue into "node_layer_capacity" elements, regardless if next layer + // down will aggregate leafs or nodes + + let mut proof_witnesses = proof_witnesses; + + // use this and deal with borrow checker + + let r = cs as *mut CS; + + assert_eq!(vk_fixed_parameters.parameters, verifier_builder.geometry()); + + let verifier = verifier_builder.create_recursive_verifier(cs); + + drop(cs); + + let cs = unsafe { &mut *r }; + + let subqueues = split_queue_state_into_n(cs, queue_state, node_layer_capacity, split_points); + + let leaf_layer_capacity = UInt32::allocated_constant(cs, leaf_layer_capacity as u32); + for el in subqueues.iter() { + // if we aggregate leafs, then we ensure length to be small enough. + // It's not mandatory, but nevertheless + + // check len <= leaf capacity + + let (_, uf) = leaf_layer_capacity.overflowing_sub(cs, el.tail.length); + uf.conditionally_enforce_false(cs, next_layer_aggregates_leafs); + } + + assert_eq!(subqueues.len(), node_layer_capacity); + + for subqueue in subqueues.into_iter() { + let proof_witness = proof_witnesses.pop_front(); + + let proof = AllocatedProof::allocate_from_witness( + cs, + proof_witness, + &verifier, + &vk_fixed_parameters, + &proof_config, + ); + + let chunk_is_empty = subqueue.tail.length.is_zero(cs); + let chunk_is_meaningful = chunk_is_empty.negated(cs); + + // verify the proof + let (is_valid, public_inputs) = verifier.verify::( + cs, + transcript_params.clone(), + &proof, + &vk_fixed_parameters, + &proof_config, + &vk, + ); + + is_valid.conditionally_enforce_true(cs, chunk_is_meaningful); + + // if it's a meaningful proof we should also check that it indeed proofs a subqueue + + let next_layer_input_if_node = RecursionNodeInput { + branch_circuit_type: branch_circuit_type, + leaf_layer_parameters: leaf_layer_parameters, + node_layer_vk_commitment: node_layer_vk_commitment, + queue_state: subqueue, + }; + let input_commitment_if_node: [_; INPUT_OUTPUT_COMMITMENT_LENGTH] = + commit_variable_length_encodable_item(cs, &next_layer_input_if_node, round_function); + + use crate::recursion::leaf_layer::input::RecursionLeafInput; + let next_layer_input_if_leaf = RecursionLeafInput { + params: leaf_params, + queue_state: subqueue, + }; + let input_commitment_if_leaf: [_; INPUT_OUTPUT_COMMITMENT_LENGTH] = + commit_variable_length_encodable_item(cs, &next_layer_input_if_leaf, round_function); + + let input_commitment = <[Num; INPUT_OUTPUT_COMMITMENT_LENGTH]>::conditionally_select( + cs, + next_layer_aggregates_nodes, + &input_commitment_if_node, + &input_commitment_if_leaf, + ); + + assert_eq!(public_inputs.len(), INPUT_OUTPUT_COMMITMENT_LENGTH); + for (a, b) in input_commitment.iter().zip(public_inputs.into_iter()) { + Num::conditionally_enforce_equal(cs, chunk_is_meaningful, a, &b); + } + } + + let input_commitment: [_; INPUT_OUTPUT_COMMITMENT_LENGTH] = + commit_variable_length_encodable_item(cs, &input, round_function); + // for el in input_commitment.iter() { + // let gate = PublicInputGate::new(el.get_variable()); + // gate.add_to_cs(cs); + // } + + input_commitment +} + +pub(crate) fn split_queue_state_into_n, const N: usize>( + cs: &mut CS, + queue_state: QueueState, + split_into: usize, + mut split_point_witnesses: VecDeque>, +) -> Vec> { + assert!(split_into <= u32::MAX as usize); + assert!(split_into >= 2); + if ::WitnessConfig::EVALUATE_WITNESS { + assert_eq!(split_point_witnesses.len() + 1, split_into); + } + + // our logic is that external caller provides splitting witness, and + // we just need to ensure that total length matches, and glue intermediate points. + + // We also ensure consistency of split points + + let mut total_len = UInt32::zero(cs); + + let mut current_head = queue_state.head; + let mut result = Vec::with_capacity(split_into); + + for _ in 0..(split_into - 1) { + let witness = split_point_witnesses + .pop_front() + .unwrap_or(QueueTailState::placeholder_witness()); + let current_tail = QueueTailState::allocate(cs, witness); + let first = QueueState { + head: current_head, + tail: current_tail, + }; + + current_head = current_tail.tail; + // add length + total_len = total_len.add_no_overflow(cs, current_tail.length); + // ensure consistency + first.enforce_consistency(cs); + + result.push(first); + } + // push the last one + let last_len = queue_state.tail.length.sub_no_overflow(cs, total_len); + let last = QueueState { + head: current_head, + tail: QueueTailState { + tail: queue_state.tail.tail, + length: last_len, + }, + }; + last.enforce_consistency(cs); + result.push(last); + + assert_eq!(result.len(), split_into); + + result +} diff --git a/crates/zkevm_circuits/src/scheduler/auxiliary.rs b/crates/zkevm_circuits/src/scheduler/auxiliary.rs new file mode 100644 index 0000000..08c66b2 --- /dev/null +++ b/crates/zkevm_circuits/src/scheduler/auxiliary.rs @@ -0,0 +1,302 @@ +use crate::fsm_input_output::circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH; + +use crate::fsm_input_output::commit_variable_length_encodable_item; + +use crate::base_structures::vm_state::*; +use crate::fsm_input_output::*; +use crate::linear_hasher::input::LinearHasherInputData; +use boojum::gadgets::u32::UInt32; + +use boojum::algebraic_props::round_function::AlgebraicRoundFunction; +use boojum::cs::traits::cs::ConstraintSystem; +use boojum::field::SmallField; +use boojum::gadgets::traits::round_function::CircuitRoundFunction; +use boojum::gadgets::{boolean::Boolean, num::Num, queue::*, traits::selectable::Selectable}; + +use crate::base_structures::precompile_input_outputs::*; +use crate::log_sorter::input::*; +use crate::storage_application::input::*; +use boojum::gadgets::u8::UInt8; + +use super::*; + +pub const NUM_CIRCUIT_TYPES_TO_SCHEDULE: usize = crate::recursion::NUM_BASE_LAYER_CIRCUITS; + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Copy, Debug, Eq, Hash, PartialEq)] +#[repr(u8)] +pub enum BaseLayerCircuitType { + None = 0, + VM = 1, + DecommitmentsFilter = 2, + Decommiter = 3, + LogDemultiplexer = 4, + KeccakPrecompile = 5, + Sha256Precompile = 6, + EcrecoverPrecompile = 7, + RamValidation = 8, + StorageFilter = 9, + StorageApplicator = 10, + EventsRevertsFilter = 11, + L1MessagesRevertsFilter = 12, + L1MessagesHasher = 13, +} + +impl BaseLayerCircuitType { + pub fn from_numeric_value(value: u8) -> Self { + match value { + a if a == Self::VM as u8 => Self::VM, + a if a == Self::DecommitmentsFilter as u8 => Self::DecommitmentsFilter, + a if a == Self::Decommiter as u8 => Self::Decommiter, + a if a == Self::LogDemultiplexer as u8 => Self::LogDemultiplexer, + a if a == Self::KeccakPrecompile as u8 => Self::KeccakPrecompile, + a if a == Self::Sha256Precompile as u8 => Self::Sha256Precompile, + a if a == Self::EcrecoverPrecompile as u8 => Self::EcrecoverPrecompile, + a if a == Self::RamValidation as u8 => Self::RamValidation, + a if a == Self::StorageFilter as u8 => Self::StorageFilter, + a if a == Self::StorageApplicator as u8 => Self::StorageApplicator, + a if a == Self::EventsRevertsFilter as u8 => Self::EventsRevertsFilter, + a if a == Self::L1MessagesRevertsFilter as u8 => Self::L1MessagesRevertsFilter, + a if a == Self::L1MessagesHasher as u8 => Self::L1MessagesHasher, + _ => { + panic!("unknown circuit type {}", value) + } + } + } +} + +#[track_caller] +pub(crate) fn compute_precompile_commitment< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, +>( + cs: &mut CS, + precompile_queue_state: &QueueState, + mem_queue_state_before: &QueueState, + mem_queue_state_after: &QueueState, + round_function: &R, +) -> ( + [Num; CLOSED_FORM_COMMITTMENT_LENGTH], + [Num; CLOSED_FORM_COMMITTMENT_LENGTH], +) { + let input_data = PrecompileFunctionInputData { + initial_log_queue_state: precompile_queue_state.clone(), + initial_memory_queue_state: mem_queue_state_before.clone(), + }; + let input_data_commitment = + commit_variable_length_encodable_item(cs, &input_data, round_function); + + let output_data = PrecompileFunctionOutputData { + final_memory_state: mem_queue_state_after.clone(), + }; + let output_data_commitment = + commit_variable_length_encodable_item(cs, &output_data, round_function); + + (input_data_commitment, output_data_commitment) +} + +#[track_caller] +pub(crate) fn compute_storage_sorter_circuit_commitment< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, +>( + cs: &mut CS, + shard_id: UInt8, + queue_state_before: &QueueState, + intermediate_queue_state: &QueueTailState, + queue_state_after: &QueueState, + round_function: &R, +) -> ( + [Num; CLOSED_FORM_COMMITTMENT_LENGTH], + [Num; CLOSED_FORM_COMMITTMENT_LENGTH], +) { + // We use here the naming events_deduplicator but the function is applicable for + // storage deduplicator is well - may be we should make this fact more observable + let mut full_state = QueueState::empty(cs); + full_state.tail = *intermediate_queue_state; + let input_data = StorageDeduplicatorInputData { + shard_id_to_process: shard_id, + unsorted_log_queue_state: queue_state_before.clone(), + intermediate_sorted_queue_state: full_state, + }; + let input_data_commitment = + commit_variable_length_encodable_item(cs, &input_data, round_function); + + let output_data = StorageDeduplicatorOutputData { + final_sorted_queue_state: queue_state_after.clone(), + }; + let output_data_commitment = + commit_variable_length_encodable_item(cs, &output_data, round_function); + + (input_data_commitment, output_data_commitment) +} + +#[track_caller] +pub(crate) fn compute_filter_circuit_commitment< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, +>( + cs: &mut CS, + queue_state_before: &QueueState, + intermediate_queue_state: &QueueTailState, + queue_state_after: &QueueState, + round_function: &R, +) -> ( + [Num; CLOSED_FORM_COMMITTMENT_LENGTH], + [Num; CLOSED_FORM_COMMITTMENT_LENGTH], +) { + // We use here the naming events_deduplicator but the function is applicable for + // storage deduplicator is well - may be we should make this fact more observable + let mut full_state = QueueState::empty(cs); + full_state.tail = *intermediate_queue_state; + let input_data = EventsDeduplicatorInputData { + initial_log_queue_state: queue_state_before.clone(), + intermediate_sorted_queue_state: full_state, + }; + let input_data_commitment = + commit_variable_length_encodable_item(cs, &input_data, round_function); + + let output_data = EventsDeduplicatorOutputData { + final_queue_state: queue_state_after.clone(), + }; + let output_data_commitment = + commit_variable_length_encodable_item(cs, &output_data, round_function); + + (input_data_commitment, output_data_commitment) +} + +#[track_caller] +pub(crate) fn compute_storage_applicator_circuit_commitment< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, +>( + cs: &mut CS, + storage_queue_state: &QueueState, + initial_root: &[UInt8; 32], + initial_enumeration_counter: &[UInt32; 2], + final_root: &[UInt8; 32], + final_enumeration_counter: &[UInt32; 2], + rollup_state_diff_for_compression: &[UInt8; 32], + shard_id: u8, + round_function: &R, +) -> ( + [Num; CLOSED_FORM_COMMITTMENT_LENGTH], + [Num; CLOSED_FORM_COMMITTMENT_LENGTH], +) { + let shard_id = UInt8::allocated_constant(cs, shard_id); + + let input_data = StorageApplicationInputData { + initial_next_enumeration_counter: *initial_enumeration_counter, + shard: shard_id, + initial_root_hash: *initial_root, + storage_application_log_state: storage_queue_state.clone(), + }; + let input_data_commitment = + commit_variable_length_encodable_item(cs, &input_data, round_function); + + let output_data = StorageApplicationOutputData { + new_root_hash: *final_root, + new_next_enumeration_counter: *final_enumeration_counter, + state_diffs_keccak256_hash: *rollup_state_diff_for_compression, + }; + let output_data_commitment = + commit_variable_length_encodable_item(cs, &output_data, round_function); + + (input_data_commitment, output_data_commitment) +} + +#[track_caller] +pub(crate) fn compute_hasher_circuit_commitment< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, +>( + cs: &mut CS, + input_queue_state: &QueueState, + pubdata_hash: &[UInt8; 32], + round_function: &R, +) -> ( + [Num; CLOSED_FORM_COMMITTMENT_LENGTH], + [Num; CLOSED_FORM_COMMITTMENT_LENGTH], +) { + let input_data = LinearHasherInputData { + queue_state: input_queue_state.clone(), + }; + let input_data_commitment = + commit_variable_length_encodable_item(cs, &input_data, round_function); + + let output_data = LinearHasherOutputData { + keccak256_hash: *pubdata_hash, + }; + let output_data_commitment = + commit_variable_length_encodable_item(cs, &output_data, round_function); + + (input_data_commitment, output_data_commitment) +} + +#[track_caller] +pub(crate) fn conditionally_enforce_circuit_commitment>( + cs: &mut CS, + should_validate: Boolean, + actual_commitment: &[Num; INPUT_OUTPUT_COMMITMENT_LENGTH], + sample_commitment: &[Num; INPUT_OUTPUT_COMMITMENT_LENGTH], +) { + for (a, b) in actual_commitment.iter().zip(sample_commitment.iter()) { + Num::conditionally_enforce_equal(cs, should_validate, a, b); + } +} + +#[track_caller] +pub(crate) fn conditionally_select_queue_tail< + F: SmallField, + CS: ConstraintSystem, + const N: usize, +>( + cs: &mut CS, + flag: Boolean, + a: &QueueTailState, + b: &QueueTailState, +) -> QueueTailState { + let tail = Num::parallel_select(cs, flag, &a.tail, &b.tail); + let length = UInt32::conditionally_select(cs, flag, &a.length, &b.length); + + QueueTailState { tail, length } +} + +pub(crate) fn finalize_queue_state< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction, + const N: usize, + const M: usize, +>( + cs: &mut CS, + state: &QueueTailState, + _round_function: &R, +) -> [Num; M] { + let mut to_absorb = vec![]; + to_absorb.extend(state.tail); + let one_num = Num::allocated_constant(cs, F::ONE); + let zero_num = Num::zero(cs); + // we do rescue prime padding and absorb + to_absorb.push(one_num); + let mut multiple = to_absorb.len() / 8; + if to_absorb.len() % 8 != 0 { + multiple += 1; + } + to_absorb.resize(multiple * 8, zero_num); + let mut state = [zero_num; 12]; + for chunk in to_absorb.array_chunks::<8>() { + let els_to_keep = R::split_capacity_elements(&state.map(|el| el.get_variable())) + .map(|el| Num::from_variable(el)); + state = R::absorb_with_replacement_over_nums(cs, *chunk, els_to_keep); + state = R::compute_round_function_over_nums(cs, state); + } + + R::state_into_commitment::(&state.map(|el| el.get_variable())) + .map(|el| Num::from_variable(el)) +} diff --git a/crates/zkevm_circuits/src/scheduler/block_header/mod.rs b/crates/zkevm_circuits/src/scheduler/block_header/mod.rs new file mode 100644 index 0000000..c54d2a6 --- /dev/null +++ b/crates/zkevm_circuits/src/scheduler/block_header/mod.rs @@ -0,0 +1,178 @@ +use super::*; + +use boojum::cs::{traits::cs::ConstraintSystem, Variable}; +use boojum::field::SmallField; + +use boojum::gadgets::u256::UInt256; +use boojum::gadgets::u32::UInt32; +use boojum::gadgets::u8::UInt8; +use boojum::gadgets::{ + boolean::Boolean, + traits::{ + allocatable::*, encodable::CircuitVarLengthEncodable, selectable::Selectable, + witnessable::WitnessHookable, + }, +}; +use cs_derive::*; + +use boojum::serde_utils::BigArraySerde; + +use boojum::gadgets::keccak256; + +pub const NUM_SHARDS: usize = 2; + +// Data that represents a pure state +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +pub struct PerShardState { + pub enumeration_counter: [UInt32; 2], + pub state_root: [UInt8; 32], +} + +// Data that is something like STF(BlockPassthroughData, BlockMetaParameters) -> (BlockPassthroughData, BlockAuxilaryOutput) +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +pub struct BlockPassthroughData { + pub per_shard_states: [PerShardState; NUM_SHARDS], +} + +// Defining some system parameters that are configurable +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +pub struct BlockMetaParameters { + pub zkporter_is_available: Boolean, + pub bootloader_code_hash: UInt256, + pub default_aa_code_hash: UInt256, +} + +// This is the information that represents artifacts only meaningful for this block, that will not be used for any +// next block +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +pub struct BlockAuxilaryOutput { + pub l1_messages_linear_hash: [UInt8; 32], + pub rollup_state_diff_for_compression: [UInt8; 32], + pub bootloader_heap_initial_content: [UInt8; 32], + pub events_queue_state: [UInt8; 32], +} + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +pub struct BlockHeader { + pub previous_block_content_hash: [UInt8; 32], + pub new_block_content_hash: [UInt8; 32], +} + +// only contains information about this block (or any one block in general), +// without anything about the previous one +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +pub struct BlockContentHeader { + pub block_data: BlockPassthroughData, + pub block_meta: BlockMetaParameters, + pub auxilary_output: BlockAuxilaryOutput, +} + +impl PerShardState { + pub fn into_flattened_bytes>(&self, cs: &mut CS) -> Vec> { + // everything is BE + let mut result = vec![]; + for el in self.enumeration_counter.iter().rev() { + let be_bytes = el.to_be_bytes(cs); + result.extend(be_bytes); + } + result.extend_from_slice(&self.state_root); + + result + } +} + +impl BlockPassthroughData { + pub fn into_flattened_bytes>(&self, cs: &mut CS) -> Vec> { + // everything is BE + let mut result = vec![]; + for el in self.per_shard_states.iter() { + let be_bytes = el.into_flattened_bytes(cs); + result.extend(be_bytes); + } + + result + } +} + +impl BlockMetaParameters { + pub fn into_flattened_bytes>(&self, cs: &mut CS) -> Vec> { + // everything is BE + let mut result = vec![]; + let zk_porter_byte = + unsafe { UInt8::from_variable_unchecked(self.zkporter_is_available.get_variable()) }; + result.push(zk_porter_byte); + + result.extend_from_slice(&self.bootloader_code_hash.to_be_bytes(cs)); + result.extend_from_slice(&self.default_aa_code_hash.to_be_bytes(cs)); + + result + } +} + +impl BlockAuxilaryOutput { + pub fn into_flattened_bytes>(&self, _cs: &mut CS) -> Vec> { + // everything is BE + let mut result = vec![]; + result.extend_from_slice(&self.l1_messages_linear_hash); + result.extend_from_slice(&self.rollup_state_diff_for_compression); + result.extend_from_slice(&self.bootloader_heap_initial_content); + result.extend_from_slice(&self.events_queue_state); + + result + } +} + +impl BlockContentHeader { + pub fn into_formal_block_hash>( + self, + cs: &mut CS, + ) -> ( + [UInt8; 32], + ([UInt8; 32], [UInt8; 32], [UInt8; 32]), + ) { + // everything is BE + let block_data = self.block_data.into_flattened_bytes(cs); + let block_meta = self.block_meta.into_flattened_bytes(cs); + let auxilary_output = self.auxilary_output.into_flattened_bytes(cs); + + let block_data_hash = keccak256::keccak256(cs, &block_data); + + let block_meta_hash = keccak256::keccak256(cs, &block_meta); + + let auxilary_output_hash = keccak256::keccak256(cs, &auxilary_output); + + let block_hash = Self::formal_block_hash_from_partial_hashes( + cs, + block_data_hash, + block_meta_hash, + auxilary_output_hash, + ); + + ( + block_hash, + (block_data_hash, block_meta_hash, auxilary_output_hash), + ) + } + + pub fn formal_block_hash_from_partial_hashes>( + cs: &mut CS, + block_data_hash: [UInt8; 32], + block_meta_hash: [UInt8; 32], + auxilary_output_hash: [UInt8; 32], + ) -> [UInt8; 32] { + let mut concatenated = vec![]; + concatenated.extend(block_data_hash); + concatenated.extend(block_meta_hash); + concatenated.extend(auxilary_output_hash); + + let block_header_hash = keccak256::keccak256(cs, &concatenated); + + block_header_hash + } +} diff --git a/crates/zkevm_circuits/src/scheduler/input.rs b/crates/zkevm_circuits/src/scheduler/input.rs new file mode 100644 index 0000000..1263b63 --- /dev/null +++ b/crates/zkevm_circuits/src/scheduler/input.rs @@ -0,0 +1,132 @@ +use super::*; +use boojum::cs::implementations::proof::Proof; +use boojum::cs::implementations::verifier::VerificationKey; + +use boojum::field::SmallField; + +use boojum::gadgets::{queue::*, traits::allocatable::*}; + +use crate::base_structures::precompile_input_outputs::PrecompileFunctionOutputDataWitness; + +use crate::base_structures::vm_state::*; +use crate::code_unpacker_sha256::input::CodeDecommitterOutputDataWitness; + +use crate::fsm_input_output::circuit_inputs::main_vm::VmOutputDataWitness; +use crate::linear_hasher::input::LinearHasherOutputDataWitness; +use crate::log_sorter::input::EventsDeduplicatorOutputDataWitness; + +use crate::fsm_input_output::ClosedFormInputCompactFormWitness; +use crate::storage_application::input::StorageApplicationOutputDataWitness; +use crate::storage_validity_by_grand_product::input::StorageDeduplicatorOutputDataWitness; +use boojum::gadgets::num::Num; +use boojum::gadgets::recursion::recursive_tree_hasher::RecursiveTreeHasher; +use std::collections::VecDeque; + +use crate::recursion::leaf_layer::input::*; +use crate::recursion::*; +use boojum::field::FieldExtension; + +// This structure only keeps witness, but there is a lot of in unfortunately +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Debug)] +#[serde( + bound = ">::Witness: serde::Serialize + serde::de::DeserializeOwned, + [RecursionLeafParametersWitness; NUM_BASE_LAYER_CIRCUITS]: serde::Serialize + serde::de::DeserializeOwned" +)] +pub struct SchedulerCircuitInstanceWitness< + F: SmallField, + H: RecursiveTreeHasher>, + EXT: FieldExtension<2, BaseField = F>, +> { + pub prev_block_data: BlockPassthroughDataWitness, + pub block_meta_parameters: BlockMetaParametersWitness, + + // passthrough outputs for all the circuits that produce such + pub vm_end_of_execution_observable_output: VmOutputDataWitness, + pub decommits_sorter_observable_output: CodeDecommittmentsDeduplicatorOutputDataWitness, + pub code_decommitter_observable_output: CodeDecommitterOutputDataWitness, + pub log_demuxer_observable_output: LogDemuxerOutputDataWitness, + pub keccak256_observable_output: PrecompileFunctionOutputDataWitness, + pub sha256_observable_output: PrecompileFunctionOutputDataWitness, + pub ecrecover_observable_output: PrecompileFunctionOutputDataWitness, + // RAM permutation doesn't produce anything + pub storage_sorter_observable_output: StorageDeduplicatorOutputDataWitness, + pub storage_application_observable_output: StorageApplicationOutputDataWitness, + pub events_sorter_observable_output: EventsDeduplicatorOutputDataWitness, + pub l1messages_sorter_observable_output: EventsDeduplicatorOutputDataWitness, + pub l1messages_linear_hasher_observable_output: LinearHasherOutputDataWitness, + + // very few things that we need to properly produce this block + pub storage_log_tail: [F; QUEUE_STATE_WIDTH], + pub per_circuit_closed_form_inputs: VecDeque>, + + pub bootloader_heap_memory_state: QueueTailStateWitness, + pub ram_sorted_queue_state: QueueTailStateWitness, + pub decommits_sorter_intermediate_queue_state: + QueueTailStateWitness, + + // all multi-circuits responsible for sorting + pub rollup_storage_sorter_intermediate_queue_state: QueueTailStateWitness, + pub events_sorter_intermediate_queue_state: QueueTailStateWitness, + pub l1messages_sorter_intermediate_queue_state: QueueTailStateWitness, + + // extra information about the previous block + pub previous_block_meta_hash: [u8; 32], + pub previous_block_aux_hash: [u8; 32], + + // proofs for every individual circuit type's aggregation subtree + #[derivative(Debug = "ignore")] + pub proof_witnesses: VecDeque>, + #[derivative(Debug = "ignore")] + pub node_layer_vk_witness: VerificationKey, + #[derivative(Debug = "ignore")] + pub leaf_layer_parameters: [RecursionLeafParametersWitness; NUM_BASE_LAYER_CIRCUITS], +} + +impl>, EXT: FieldExtension<2, BaseField = F>> + SchedulerCircuitInstanceWitness +{ + pub fn placeholder() -> Self { + Self { + prev_block_data: BlockPassthroughData::placeholder_witness(), + block_meta_parameters: BlockMetaParameters::placeholder_witness(), + + vm_end_of_execution_observable_output: VmOutputData::placeholder_witness(), + decommits_sorter_observable_output: + CodeDecommittmentsDeduplicatorOutputData::placeholder_witness(), + code_decommitter_observable_output: CodeDecommitterOutputData::placeholder_witness(), + log_demuxer_observable_output: LogDemuxerOutputData::placeholder_witness(), + keccak256_observable_output: PrecompileFunctionOutputData::placeholder_witness(), + sha256_observable_output: PrecompileFunctionOutputData::placeholder_witness(), + ecrecover_observable_output: PrecompileFunctionOutputData::placeholder_witness(), + storage_sorter_observable_output: StorageDeduplicatorOutputData::placeholder_witness(), + storage_application_observable_output: + StorageApplicationOutputData::placeholder_witness(), + events_sorter_observable_output: EventsDeduplicatorOutputData::placeholder_witness(), + l1messages_sorter_observable_output: EventsDeduplicatorOutputData::placeholder_witness( + ), + l1messages_linear_hasher_observable_output: LinearHasherOutputData::placeholder_witness( + ), + + storage_log_tail: [F::ZERO; QUEUE_STATE_WIDTH], + per_circuit_closed_form_inputs: VecDeque::new(), + + bootloader_heap_memory_state: QueueTailState::placeholder_witness(), + ram_sorted_queue_state: QueueTailState::placeholder_witness(), + decommits_sorter_intermediate_queue_state: QueueTailState::placeholder_witness(), + + rollup_storage_sorter_intermediate_queue_state: QueueTailState::placeholder_witness(), + events_sorter_intermediate_queue_state: QueueTailState::placeholder_witness(), + l1messages_sorter_intermediate_queue_state: QueueTailState::placeholder_witness(), + + previous_block_meta_hash: [0u8; 32], + previous_block_aux_hash: [0u8; 32], + + proof_witnesses: VecDeque::new(), + node_layer_vk_witness: VerificationKey::default(), + leaf_layer_parameters: std::array::from_fn(|_| { + RecursionLeafParameters::placeholder_witness() + }), + } + } +} diff --git a/crates/zkevm_circuits/src/scheduler/mod.rs b/crates/zkevm_circuits/src/scheduler/mod.rs new file mode 100644 index 0000000..817bf82 --- /dev/null +++ b/crates/zkevm_circuits/src/scheduler/mod.rs @@ -0,0 +1,1059 @@ +use super::*; + +pub mod block_header; +use self::block_header::*; + +pub mod input; +use self::input::*; + +pub mod auxiliary; +pub use auxiliary as aux; + +use boojum::cs::implementations::proof::Proof; + +use boojum::cs::traits::cs::ConstraintSystem; +use boojum::field::SmallField; + +use boojum::gadgets::recursion::allocated_proof::AllocatedProof; +use boojum::gadgets::recursion::allocated_vk::AllocatedVerificationKey; + +use boojum::gadgets::traits::witnessable::WitnessHookable; +use boojum::gadgets::u32::UInt32; +use boojum::gadgets::u8::UInt8; +use boojum::gadgets::{ + boolean::Boolean, + queue::*, + traits::{allocatable::*, selectable::Selectable}, +}; + +use crate::base_structures::decommit_query::DecommitQuery; +use crate::base_structures::decommit_query::DecommitQueue; +use crate::base_structures::memory_query::MemoryQuery; +use crate::base_structures::memory_query::MemoryQueue; + +use crate::base_structures::recursion_query::*; +use crate::fsm_input_output::circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH; +use crate::linear_hasher::input::LinearHasherOutputData; +use crate::recursion::VK_COMMITMENT_LENGTH; +use crate::scheduler::auxiliary::NUM_CIRCUIT_TYPES_TO_SCHEDULE; +use boojum::gadgets::num::Num; +use boojum::gadgets::recursion::recursive_tree_hasher::RecursiveTreeHasher; + +use crate::base_structures::precompile_input_outputs::*; +use boojum::algebraic_props::round_function::AlgebraicRoundFunction; +use boojum::cs::implementations::prover::ProofConfig; +use boojum::cs::implementations::verifier::VerificationKeyCircuitGeometry; +use boojum::cs::oracle::TreeHasher; +use boojum::cs::traits::circuit::*; +use boojum::field::FieldExtension; +use boojum::gadgets::keccak256; +use boojum::gadgets::recursion::circuit_pow::RecursivePoWRunner; +use boojum::gadgets::recursion::recursive_transcript::*; +use boojum::gadgets::recursion::recursive_tree_hasher::*; +use boojum::gadgets::traits::round_function::CircuitRoundFunction; +use std::collections::HashMap; + +use crate::base_structures::vm_state::*; +use crate::code_unpacker_sha256::input::*; +use crate::demux_log_queue::input::*; +use crate::fsm_input_output::circuit_inputs::main_vm::*; +use crate::fsm_input_output::*; +use crate::log_sorter::input::*; +use crate::ram_permutation::input::*; +use crate::recursion::leaf_layer::input::*; +use crate::recursion::node_layer::input::*; +use crate::scheduler::auxiliary::*; +use crate::sort_decommittment_requests::input::*; +use crate::storage_application::input::*; +use crate::storage_validity_by_grand_product::input::*; + +pub const SCHEDULER_TIMESTAMP: u32 = 1; +pub const NUM_SCHEDULER_PUBLIC_INPUTS: usize = 4; +pub const LEAF_LAYER_PARAMETERS_COMMITMENT_LENGTH: usize = 4; +pub const QUEUE_FINAL_STATE_COMMITMENT_LENGTH: usize = 4; + +pub const SEQUENCE_OF_CIRCUIT_TYPES: [BaseLayerCircuitType; NUM_CIRCUIT_TYPES_TO_SCHEDULE] = [ + BaseLayerCircuitType::VM, + BaseLayerCircuitType::DecommitmentsFilter, + BaseLayerCircuitType::Decommiter, + BaseLayerCircuitType::LogDemultiplexer, + BaseLayerCircuitType::KeccakPrecompile, + BaseLayerCircuitType::Sha256Precompile, + BaseLayerCircuitType::EcrecoverPrecompile, + BaseLayerCircuitType::RamValidation, + BaseLayerCircuitType::StorageFilter, + BaseLayerCircuitType::StorageApplicator, + BaseLayerCircuitType::EventsRevertsFilter, + BaseLayerCircuitType::L1MessagesRevertsFilter, + BaseLayerCircuitType::L1MessagesHasher, +]; + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Debug)] +#[serde(bound = "H::Output: serde::Serialize + serde::de::DeserializeOwned")] +pub struct SchedulerConfig, EXT: FieldExtension<2, BaseField = F>> { + pub proof_config: ProofConfig, + pub vk_fixed_parameters: VerificationKeyCircuitGeometry, + pub capacity: usize, + pub _marker: std::marker::PhantomData<(F, H, EXT)>, +} + +pub fn scheduler_function< + F: SmallField, + CS: ConstraintSystem + 'static, + R: CircuitRoundFunction + AlgebraicRoundFunction, + H: RecursiveTreeHasher>, + EXT: FieldExtension<2, BaseField = F>, + TR: RecursiveTranscript< + F, + CompatibleCap = >::Output, + CircuitReflection = CTR, + >, + CTR: CircuitTranscript< + F, + CircuitCompatibleCap = >>::CircuitOutput, + TransciptParameters = TR::TransciptParameters, + >, + POW: RecursivePoWRunner, +>( + cs: &mut CS, + mut witness: SchedulerCircuitInstanceWitness, + round_function: &R, + config: SchedulerConfig, + verifier_builder: Box>, + transcript_params: TR::TransciptParameters, +) where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + let prev_block_data = BlockPassthroughData::allocate(cs, witness.prev_block_data.clone()); + let block_meta_parameters = + BlockMetaParameters::allocate(cs, witness.block_meta_parameters.clone()); + + let boolean_false = Boolean::allocated_constant(cs, false); + let boolean_true = Boolean::allocated_constant(cs, true); + + Boolean::enforce_equal( + cs, + &block_meta_parameters.zkporter_is_available, + &boolean_false, + ); + + // create initial queues + let bootloader_heap_memory_state = + QueueTailState::allocate(cs, witness.bootloader_heap_memory_state.clone()); + + let mut initial_memory_queue_state = MemoryQueue::::empty(cs); + initial_memory_queue_state.tail = bootloader_heap_memory_state.tail; + initial_memory_queue_state.length = bootloader_heap_memory_state.length; + + let mut decommittments_queue = DecommitQueue::::empty(cs); + let bootloader_code_hash = block_meta_parameters.bootloader_code_hash; + let bootloader_code_page = + UInt32::allocated_constant(cs, zkevm_opcode_defs::BOOTLOADER_CODE_PAGE); + let scheduler_timestamp = UInt32::allocated_constant(cs, SCHEDULER_TIMESTAMP); + let bootloader_decommittment_query = crate::base_structures::decommit_query::DecommitQuery { + code_hash: bootloader_code_hash, + page: bootloader_code_page, + is_first: boolean_true, + timestamp: scheduler_timestamp, + }; + + let _ = decommittments_queue.push(cs, bootloader_decommittment_query, boolean_true); + + // create all the intermediate output data in uncommitted form to later check for equality + + let vm_end_of_execution_observable_output = + VmOutputData::allocate(cs, witness.vm_end_of_execution_observable_output.clone()); + + let decommits_sorter_observable_output = CodeDecommittmentsDeduplicatorOutputData::allocate( + cs, + witness.decommits_sorter_observable_output.clone(), + ); + + let code_decommitter_observable_output = + CodeDecommitterOutputData::allocate(cs, witness.code_decommitter_observable_output.clone()); + + let log_demuxer_observable_output = + LogDemuxerOutputData::allocate(cs, witness.log_demuxer_observable_output.clone()); + + let keccak256_observable_output = + PrecompileFunctionOutputData::allocate(cs, witness.keccak256_observable_output.clone()); + + let sha256_observable_output = + PrecompileFunctionOutputData::allocate(cs, witness.sha256_observable_output.clone()); + + let ecrecover_observable_output = + PrecompileFunctionOutputData::allocate(cs, witness.ecrecover_observable_output.clone()); + + let storage_sorter_observable_output = StorageDeduplicatorOutputData::allocate( + cs, + witness.storage_sorter_observable_output.clone(), + ); + + let storage_application_observable_output = StorageApplicationOutputData::allocate( + cs, + witness.storage_application_observable_output.clone(), + ); + + let events_sorter_observable_output = + EventsDeduplicatorOutputData::allocate(cs, witness.events_sorter_observable_output.clone()); + + let l1messages_sorter_observable_output = EventsDeduplicatorOutputData::allocate( + cs, + witness.l1messages_sorter_observable_output.clone(), + ); + + let l1messages_linear_hasher_observable_output = + LinearHasherOutputData::allocate(cs, witness.l1messages_linear_hasher_observable_output); + + // auxilary intermediate states + let rollup_storage_sorter_intermediate_queue_state = QueueTailState::allocate( + cs, + witness + .rollup_storage_sorter_intermediate_queue_state + .clone(), + ); + + let events_sorter_intermediate_queue_state = + QueueTailState::allocate(cs, witness.events_sorter_intermediate_queue_state.clone()); + + let l1messages_sorter_intermediate_queue_state = QueueTailState::allocate( + cs, + witness.l1messages_sorter_intermediate_queue_state.clone(), + ); + + // final VM storage log state for our construction + let storage_log_tail = <[Num; QUEUE_STATE_WIDTH]>::allocate(cs, witness.storage_log_tail); + + // form the VM input + let default_aa_code_hash = block_meta_parameters.default_aa_code_hash; + + let global_context = GlobalContext { + zkporter_is_available: block_meta_parameters.zkporter_is_available, + default_aa_code_hash, + }; + + // we can form all the observable inputs already as those are just functions of observable outputs + + let vm_observable_input = VmInputData { + rollback_queue_tail_for_block: storage_log_tail, + memory_queue_initial_state: initial_memory_queue_state.into_state().tail, + decommitment_queue_initial_state: decommittments_queue.into_state().tail, + per_block_context: global_context, + }; + let vm_observable_input_commitment = + commit_variable_length_encodable_item(cs, &vm_observable_input, round_function); + let vm_observable_output_commitment = commit_variable_length_encodable_item( + cs, + &vm_end_of_execution_observable_output, + round_function, + ); + + let mut decommittments_sorted_queue_state = QueueState::empty(cs); + decommittments_sorted_queue_state.tail = QueueTailState::allocate( + cs, + witness.decommits_sorter_intermediate_queue_state.clone(), + ); + + let decommittments_sorter_circuit_input = CodeDecommittmentsDeduplicatorInputData { + initial_queue_state: vm_end_of_execution_observable_output.decommitment_queue_final_state, + sorted_queue_initial_state: decommittments_sorted_queue_state, + }; + let decommittments_sorter_circuit_input_commitment = commit_variable_length_encodable_item( + cs, + &decommittments_sorter_circuit_input, + round_function, + ); + let decommittments_sorter_observable_output_commitment = commit_variable_length_encodable_item( + cs, + &decommits_sorter_observable_output, + round_function, + ); + + // code decommiments: + let code_decommitter_circuit_input = CodeDecommitterInputData { + memory_queue_initial_state: vm_end_of_execution_observable_output.memory_queue_final_state, + sorted_requests_queue_initial_state: decommits_sorter_observable_output.final_queue_state, + }; + let code_decommitter_circuit_input_commitment = + commit_variable_length_encodable_item(cs, &code_decommitter_circuit_input, round_function); + let code_decommitter_observable_output_commitment = commit_variable_length_encodable_item( + cs, + &code_decommitter_observable_output, + round_function, + ); + + // log demultiplexer + let log_demux_circuit_input = LogDemuxerInputData { + initial_log_queue_state: vm_end_of_execution_observable_output.log_queue_final_state, + }; + let log_demux_circuit_input_commitment = + commit_variable_length_encodable_item(cs, &log_demux_circuit_input, round_function); + let log_demuxer_observable_output_commitment = + commit_variable_length_encodable_item(cs, &log_demuxer_observable_output, round_function); + + // all intermediate queues for sorters + + // precompiles: keccak, sha256 and ecrecover + let (keccak_circuit_observable_input_commitment, keccak_circuit_observable_output_commitment) = + compute_precompile_commitment( + cs, + &log_demuxer_observable_output.keccak256_access_queue_state, + &code_decommitter_observable_output.memory_queue_final_state, + &keccak256_observable_output.final_memory_state, + round_function, + ); + let (sha256_circuit_observable_input_commitment, sha256_circuit_observable_output_commitment) = + compute_precompile_commitment( + cs, + &log_demuxer_observable_output.sha256_access_queue_state, + &keccak256_observable_output.final_memory_state, + &sha256_observable_output.final_memory_state, + round_function, + ); + let ( + ecrecover_circuit_observable_input_commitment, + ecrecover_circuit_observable_output_commitment, + ) = compute_precompile_commitment( + cs, + &log_demuxer_observable_output.ecrecover_access_queue_state, + &sha256_observable_output.final_memory_state, + &ecrecover_observable_output.final_memory_state, + round_function, + ); + + // ram permutation and validation + // NBL this circuit is terminal - it has no actual output + + let mut ram_sorted_queue_state = QueueState::empty(cs); + ram_sorted_queue_state.tail = + QueueTailState::allocate(cs, witness.ram_sorted_queue_state.clone()); + + let ram_validation_circuit_input = RamPermutationInputData { + unsorted_queue_initial_state: ecrecover_observable_output.final_memory_state, + sorted_queue_initial_state: ram_sorted_queue_state, + non_deterministic_bootloader_memory_snapshot_length: bootloader_heap_memory_state.length, + }; + let ram_validation_circuit_input_commitment = + commit_variable_length_encodable_item(cs, &ram_validation_circuit_input, round_function); + + // events reverts filter and merkelization + let (events_filter_input_com, events_filter_output_com) = compute_filter_circuit_commitment( + cs, + &log_demuxer_observable_output.events_access_queue_state, + &events_sorter_intermediate_queue_state, + &events_sorter_observable_output.final_queue_state, + round_function, + ); + + // let (events_merkelizer_input_com, events_merkelizer_output_com) = compute_merkelization_circuit_commitment( + // cs, + // &filtered_events_queue_state, + // &events_linear_hash_as_bytes32, + // &events_root_as_bytes32, + // round_function + // ); + + // l1 messages reverts filter and merkelization + let (l1_messages_filter_input_com, l1_messages_filter_output_com) = + compute_filter_circuit_commitment( + cs, + &log_demuxer_observable_output.l1messages_access_queue_state, + &l1messages_sorter_intermediate_queue_state, + &l1messages_sorter_observable_output.final_queue_state, + round_function, + ); + + let (l1_messages_hasher_input_com, l1_messages_hasher_output_com) = + compute_hasher_circuit_commitment( + cs, + &l1messages_sorter_observable_output.final_queue_state, + &l1messages_linear_hasher_observable_output.keccak256_hash, + round_function, + ); + + const NUM_PROCESSABLE_SHARDS: usize = 1; + + let zero_num = Num::zero(cs); + let empty_input_output_commitment = [zero_num; CLOSED_FORM_COMMITTMENT_LENGTH]; + + let mut storage_filter_input_commitments = + [empty_input_output_commitment; NUM_PROCESSABLE_SHARDS]; + let mut storage_filter_output_commitments = + [empty_input_output_commitment; NUM_PROCESSABLE_SHARDS]; + let mut storage_applicator_input_commitments = + [empty_input_output_commitment; NUM_PROCESSABLE_SHARDS]; + let mut storage_applicator_output_commitments = + [empty_input_output_commitment; NUM_PROCESSABLE_SHARDS]; + + let storage_queues_state = [log_demuxer_observable_output.storage_access_queue_state]; + + let filtered_storage_queues_state = [storage_sorter_observable_output.final_sorted_queue_state]; + + let initial_enumeration_counters = [prev_block_data.per_shard_states[0].enumeration_counter]; + + let initial_state_roots = [prev_block_data.per_shard_states[0].state_root]; + + let final_enumeration_counters = + [storage_application_observable_output.new_next_enumeration_counter]; + + let final_state_roots = [storage_application_observable_output.new_root_hash]; + + let storage_intermediate_sorted_queue_state = [rollup_storage_sorter_intermediate_queue_state]; + + let storage_diffs_for_compression = + [storage_application_observable_output.state_diffs_keccak256_hash]; + + assert_eq!(NUM_PROCESSABLE_SHARDS, 1); // no support of porter as of yet + + for shard_id in 0..NUM_PROCESSABLE_SHARDS { + assert!(shard_id <= u8::MAX as usize); + + let shard_id_uint8 = UInt8::allocated_constant(cs, shard_id as u8); + // storage acesses filter + let (storage_filter_input_com, storage_filter_output_com) = + compute_storage_sorter_circuit_commitment( + cs, + shard_id_uint8, + &storage_queues_state[shard_id], + &storage_intermediate_sorted_queue_state[shard_id], + &filtered_storage_queues_state[shard_id], + round_function, + ); + storage_filter_input_commitments[shard_id] = storage_filter_input_com; + storage_filter_output_commitments[shard_id] = storage_filter_output_com; + + // storage applicator for rollup subtree (porter subtree is shut down globally currently) + let (storage_applicator_input_com, storage_applicator_output_com) = + compute_storage_applicator_circuit_commitment( + cs, + &filtered_storage_queues_state[shard_id], + &initial_state_roots[shard_id], + &initial_enumeration_counters[shard_id], + &final_state_roots[shard_id], + &final_enumeration_counters[shard_id], + &storage_diffs_for_compression[shard_id], + shard_id as u8, + round_function, + ); + storage_applicator_input_commitments[shard_id] = storage_applicator_input_com; + storage_applicator_output_commitments[shard_id] = storage_applicator_output_com; + } + + // now we can run all the cirucits in sequence + + // now let's map it for convenience, and later on walk over it + + let input_commitments_as_map = + HashMap::; CLOSED_FORM_COMMITTMENT_LENGTH]>::from_iter( + [ + (BaseLayerCircuitType::VM, vm_observable_input_commitment), + ( + BaseLayerCircuitType::DecommitmentsFilter, + decommittments_sorter_circuit_input_commitment, + ), + ( + BaseLayerCircuitType::Decommiter, + code_decommitter_circuit_input_commitment, + ), + ( + BaseLayerCircuitType::LogDemultiplexer, + log_demux_circuit_input_commitment, + ), + ( + BaseLayerCircuitType::KeccakPrecompile, + keccak_circuit_observable_input_commitment, + ), + ( + BaseLayerCircuitType::Sha256Precompile, + sha256_circuit_observable_input_commitment, + ), + ( + BaseLayerCircuitType::EcrecoverPrecompile, + ecrecover_circuit_observable_input_commitment, + ), + ( + BaseLayerCircuitType::RamValidation, + ram_validation_circuit_input_commitment, + ), + ( + BaseLayerCircuitType::EventsRevertsFilter, + events_filter_input_com, + ), + ( + BaseLayerCircuitType::L1MessagesRevertsFilter, + l1_messages_filter_input_com, + ), + ( + BaseLayerCircuitType::StorageFilter, + storage_filter_input_commitments[0], + ), + ( + BaseLayerCircuitType::StorageApplicator, + storage_applicator_input_commitments[0], + ), + ( + BaseLayerCircuitType::L1MessagesHasher, + l1_messages_hasher_input_com, + ), + ] + .into_iter(), + ); + + let output_commitments_as_map = + HashMap::; CLOSED_FORM_COMMITTMENT_LENGTH]>::from_iter( + [ + (BaseLayerCircuitType::VM, vm_observable_output_commitment), + ( + BaseLayerCircuitType::DecommitmentsFilter, + decommittments_sorter_observable_output_commitment, + ), + ( + BaseLayerCircuitType::Decommiter, + code_decommitter_observable_output_commitment, + ), + ( + BaseLayerCircuitType::LogDemultiplexer, + log_demuxer_observable_output_commitment, + ), + ( + BaseLayerCircuitType::KeccakPrecompile, + keccak_circuit_observable_output_commitment, + ), + ( + BaseLayerCircuitType::Sha256Precompile, + sha256_circuit_observable_output_commitment, + ), + ( + BaseLayerCircuitType::EcrecoverPrecompile, + ecrecover_circuit_observable_output_commitment, + ), + ( + BaseLayerCircuitType::RamValidation, + [zero_num; CLOSED_FORM_COMMITTMENT_LENGTH], // formally set here + ), + ( + BaseLayerCircuitType::EventsRevertsFilter, + events_filter_output_com, + ), + ( + BaseLayerCircuitType::L1MessagesRevertsFilter, + l1_messages_filter_output_com, + ), + ( + BaseLayerCircuitType::StorageFilter, + storage_filter_output_commitments[0], + ), + ( + BaseLayerCircuitType::StorageApplicator, + storage_applicator_output_commitments[0], + ), + ( + BaseLayerCircuitType::L1MessagesHasher, + l1_messages_hasher_output_com, + ), + ] + .into_iter(), + ); + + // self-check + for pair in SEQUENCE_OF_CIRCUIT_TYPES.windows(2) { + assert_eq!((pair[0] as u8) + 1, pair[1] as u8); + } + + // we can potentially skip some circuits + let mut skip_flags = [None; NUM_CIRCUIT_TYPES_TO_SCHEDULE]; + // we can skip everything except VM + skip_flags[(BaseLayerCircuitType::DecommitmentsFilter as u8 as usize) - 1] = Some( + decommittments_sorter_circuit_input + .initial_queue_state + .tail + .length + .is_zero(cs), + ); + skip_flags[(BaseLayerCircuitType::Decommiter as u8 as usize) - 1] = Some( + code_decommitter_circuit_input + .sorted_requests_queue_initial_state + .tail + .length + .is_zero(cs), + ); + skip_flags[(BaseLayerCircuitType::LogDemultiplexer as u8 as usize) - 1] = Some( + log_demux_circuit_input + .initial_log_queue_state + .tail + .length + .is_zero(cs), + ); + skip_flags[(BaseLayerCircuitType::KeccakPrecompile as u8 as usize) - 1] = Some( + log_demuxer_observable_output + .keccak256_access_queue_state + .tail + .length + .is_zero(cs), + ); + skip_flags[(BaseLayerCircuitType::Sha256Precompile as u8 as usize) - 1] = Some( + log_demuxer_observable_output + .sha256_access_queue_state + .tail + .length + .is_zero(cs), + ); + skip_flags[(BaseLayerCircuitType::EcrecoverPrecompile as u8 as usize) - 1] = Some( + log_demuxer_observable_output + .ecrecover_access_queue_state + .tail + .length + .is_zero(cs), + ); + skip_flags[(BaseLayerCircuitType::RamValidation as u8 as usize) - 1] = Some( + ram_validation_circuit_input + .unsorted_queue_initial_state + .tail + .length + .is_zero(cs), + ); + skip_flags[(BaseLayerCircuitType::StorageFilter as u8 as usize) - 1] = + Some(storage_queues_state[0].tail.length.is_zero(cs)); + skip_flags[(BaseLayerCircuitType::StorageApplicator as u8 as usize) - 1] = + Some(filtered_storage_queues_state[0].tail.length.is_zero(cs)); + skip_flags[(BaseLayerCircuitType::EventsRevertsFilter as u8 as usize) - 1] = Some( + log_demuxer_observable_output + .events_access_queue_state + .tail + .length + .is_zero(cs), + ); + skip_flags[(BaseLayerCircuitType::L1MessagesRevertsFilter as u8 as usize) - 1] = Some( + log_demuxer_observable_output + .l1messages_access_queue_state + .tail + .length + .is_zero(cs), + ); + + // for (idx, el) in skip_flags.iter().enumerate() { + // if let Some(el) = el { + // let circuit_type = BaseLayerCircuitType::from_numeric_value((idx+1) as u8); + // println!("Skip for {:?} = {:?}", circuit_type, el.witness_hook(cs)()); + // } + // } + + // In practice we do NOT skip it + // skip_flags[(BaseLayerCircuitType::L1MessagesHasher as u8 as usize) - 1] = Some( + // l1messages_sorter_observable_output.final_queue_state.tail.length.is_zero(cs) + // ); + + // now we just walk one by one + + let mut execution_stage_bitmask = [boolean_false; NUM_CIRCUIT_TYPES_TO_SCHEDULE]; + execution_stage_bitmask[0] = boolean_true; // VM + + assert_eq!( + SEQUENCE_OF_CIRCUIT_TYPES.len(), + execution_stage_bitmask.len() + ); + + let mut execution_flag = boolean_true; + let mut previous_completion_flag = boolean_true; + + let empty_recursive_queue_state_tail = QueueTailState::empty(cs); + let mut recursive_queue_state_tails = + [empty_recursive_queue_state_tail; NUM_CIRCUIT_TYPES_TO_SCHEDULE]; + + let mut hidden_fsm_input_to_use = [zero_num; CLOSED_FORM_COMMITTMENT_LENGTH]; + + for _idx in 0..config.capacity { + let mut next_mask = [boolean_false; NUM_CIRCUIT_TYPES_TO_SCHEDULE]; + + let closed_form_input_witness = witness + .per_circuit_closed_form_inputs + .pop_front() + .unwrap_or(ClosedFormInputCompactForm::placeholder_witness()); + let closed_form_input = ClosedFormInputCompactForm::allocate(cs, closed_form_input_witness); + + // we believe that prover gives us valid compact forms, + // so we check equality + let start_of_next_when_previous_is_finished = + Boolean::equals(cs, &closed_form_input.start_flag, &previous_completion_flag); + start_of_next_when_previous_is_finished.conditionally_enforce_true(cs, execution_flag); + + let mut computed_applicability_flags = [boolean_false; NUM_CIRCUIT_TYPES_TO_SCHEDULE]; + let mut circuit_type_to_use = Num::zero(cs); + + for (idx, ((circuit_type, stage_flag), skip_flag)) in SEQUENCE_OF_CIRCUIT_TYPES + .iter() + .zip(execution_stage_bitmask.iter()) + .zip(skip_flags.iter()) + .enumerate() + { + let sample_circuit_commitment = input_commitments_as_map + .get(circuit_type) + .cloned() + .expect(&format!( + "circuit input commitment for type {:?}", + circuit_type + )); + // .unwrap_or([zero_num; CLOSED_FORM_COMMITTMENT_LENGTH]); + + let validate = if let Some(skip_flag) = skip_flag { + let not_skip = skip_flag.negated(cs); // this is memoized + Boolean::multi_and(cs, &[*stage_flag, execution_flag, not_skip]) + } else { + Boolean::multi_and(cs, &[*stage_flag, execution_flag]) + }; + + let validate_observable_input = validate; // input commitment is ALWAYS the same for all the circuits of some type + conditionally_enforce_circuit_commitment( + cs, + validate_observable_input, + &closed_form_input.observable_input_committment, + &sample_circuit_commitment, + ); + + let validate_observable_output = if let Some(skip_flag) = skip_flag { + let not_skip = skip_flag.negated(cs); // this is memoized + Boolean::multi_and( + cs, + &[closed_form_input.completion_flag, not_skip, *stage_flag], + ) + } else { + Boolean::multi_and(cs, &[closed_form_input.completion_flag, *stage_flag]) + }; + + let sample_circuit_commitment = output_commitments_as_map + .get(circuit_type) + .cloned() + .expect(&format!( + "circuit output commitment for type {:?}", + circuit_type + )); + // .unwrap_or([zero_num; CLOSED_FORM_COMMITTMENT_LENGTH]); + + conditionally_enforce_circuit_commitment( + cs, + validate_observable_output, + &closed_form_input.observable_output_committment, + &sample_circuit_commitment, + ); + + let should_start_next = if let Some(skip_flag) = skip_flag { + Boolean::multi_or(cs, &[closed_form_input.completion_flag, *skip_flag]) + } else { + closed_form_input.completion_flag + }; + + let stage_just_finished = + Boolean::multi_and(cs, &[should_start_next, execution_flag, *stage_flag]); + next_mask[idx] = stage_just_finished; + + let circuit_type = UInt8::allocated_constant(cs, *circuit_type as u8).into_num(); + + circuit_type_to_use = + Num::conditionally_select(cs, validate, &circuit_type, &circuit_type_to_use); + + computed_applicability_flags[idx] = validate; + } + + // now we can use a proper circuit type and manyally add it into single queue + let mut tail_to_use = QueueTailState::empty(cs); + for (_idx, (flag, state)) in computed_applicability_flags + .iter() + .zip(recursive_queue_state_tails.iter()) + .enumerate() + { + tail_to_use = conditionally_select_queue_tail(cs, *flag, &state, &tail_to_use); + } + + let push_to_any = Boolean::multi_or(cs, &computed_applicability_flags); + + // for any circuit that is NOT start, but is added to recursion queue we validate that previous hidden FSM output + // is given to this circuit as hidden FSM input + + // NOTE: we use `start_flag` from witness because we validated it's logic in the lines around + // `start_of_next_when_previous_is_finished` above, so it correctly represents continuation + + let continue_same_type = closed_form_input.start_flag.negated(cs); + let validate_hidden_input = Boolean::multi_and(cs, &[push_to_any, continue_same_type]); + conditionally_enforce_circuit_commitment( + cs, + validate_hidden_input, + &closed_form_input.hidden_fsm_input_committment, + &hidden_fsm_input_to_use, + ); + + // and here we can just update it for the next step + hidden_fsm_input_to_use = closed_form_input.hidden_fsm_output_committment; + + let closed_form_input_comm = + commit_variable_length_encodable_item(cs, &closed_form_input, round_function); + let query = RecursionQuery { + circuit_type: circuit_type_to_use, + input_commitment: closed_form_input_comm, + }; + // push + let mut tmp_queue = RecursionQueue::::empty(cs); + tmp_queue.tail = tail_to_use.tail; + tmp_queue.length = tail_to_use.length; + + let _ = tmp_queue.push(cs, query, push_to_any); + let tail_to_use_for_update = tmp_queue.into_state().tail; + + for (_idx, (flag, state)) in computed_applicability_flags + .iter() + .zip(recursive_queue_state_tails.iter_mut()) + .enumerate() + { + // if flag.witness_hook(cs)().unwrap_or(false) { + // let circuit_type = BaseLayerCircuitType::from_numeric_value((_idx+1) as u8); + // println!( + // "Pushing for circuit type {:?}, old state = {:?}, new state = {:?}", + // circuit_type, + // state.witness_hook(cs)(), + // tail_to_use_for_update.witness_hook(cs)(), + // ); + // } + *state = conditionally_select_queue_tail(cs, *flag, &tail_to_use_for_update, &*state); + } + + previous_completion_flag = Boolean::multi_or(cs, &next_mask); + // for the next stage we do shifted AND + let mut tmp = [boolean_false; NUM_CIRCUIT_TYPES_TO_SCHEDULE]; + // note skip(1) + for (idx, start_next) in next_mask.iter().enumerate() { + let finished_this_stage = *start_next; + let not_finished = finished_this_stage.negated(cs); + let proceed_current = + Boolean::multi_and(cs, &[execution_stage_bitmask[idx], not_finished]); + // update + let start_as_next = tmp[idx]; + let do_this_stage = Boolean::multi_or(cs, &[start_as_next, proceed_current]); + execution_stage_bitmask[idx] = do_this_stage; + if idx + 1 < NUM_CIRCUIT_TYPES_TO_SCHEDULE { + tmp[idx + 1] = finished_this_stage; + } + } + + // and check if we are done + let just_finished = *next_mask.last().unwrap(); + let should_continue = just_finished.negated(cs); + + execution_flag = Boolean::multi_and(cs, &[execution_flag, should_continue]); + } + + // so we are done! + Boolean::enforce_equal(cs, &execution_flag, &boolean_false); + + // actually perform verification + let leaf_layer_parameters = witness + .leaf_layer_parameters + .clone() + .map(|el| RecursionLeafParameters::allocate(cs, el)); + + let leaf_layer_parameters_commitment: [_; LEAF_LAYER_PARAMETERS_COMMITMENT_LENGTH] = + commit_variable_length_encodable_item(cs, &leaf_layer_parameters, round_function); + + let node_layer_vk = + AllocatedVerificationKey::::allocate(cs, witness.node_layer_vk_witness.clone()); + let node_layer_vk_commitment: [_; VK_COMMITMENT_LENGTH] = + commit_variable_length_encodable_item(cs, &node_layer_vk, round_function); + + if crate::config::CIRCUIT_VERSOBE { + dbg!(leaf_layer_parameters_commitment.witness_hook(cs)()); + dbg!(node_layer_vk_commitment.witness_hook(cs)()); + } + + let mut proof_witnesses = witness.proof_witnesses; + + // create verifier + let r = cs as *mut CS; + + assert_eq!( + config.vk_fixed_parameters.parameters, + verifier_builder.geometry() + ); + + let verifier = verifier_builder.create_recursive_verifier(cs); + + drop(cs); + + let cs = unsafe { &mut *r }; + + for (_idx, (circuit_type, state)) in SEQUENCE_OF_CIRCUIT_TYPES + .iter() + .zip(recursive_queue_state_tails.into_iter()) + .enumerate() + { + println!("Verifying circuit type {:?}", circuit_type); + + let should_skip = state.length.is_zero(cs); + let should_verify = should_skip.negated(cs); + + let circuit_type = UInt8::allocated_constant(cs, *circuit_type as u8).into_num(); + + let mut queue_state = QueueState::empty(cs); + queue_state.tail = state; + + let input: RecursionNodeInput = RecursionNodeInput { + branch_circuit_type: circuit_type, + leaf_layer_parameters: leaf_layer_parameters, + node_layer_vk_commitment: node_layer_vk_commitment, + queue_state: queue_state, + }; + + let expected_input_commitment: [_; INPUT_OUTPUT_COMMITMENT_LENGTH] = + commit_variable_length_encodable_item(cs, &input, round_function); + + let proof_witness = proof_witnesses.pop_front(); + + let proof = AllocatedProof::allocate_from_witness( + cs, + proof_witness, + &verifier, + &config.vk_fixed_parameters, + &config.proof_config, + ); + + let (is_valid, inputs) = verifier.verify::( + cs, + transcript_params.clone(), + &proof, + &config.vk_fixed_parameters, + &config.proof_config, + &node_layer_vk, + ); + + is_valid.conditionally_enforce_true(cs, should_verify); + assert_eq!(inputs.len(), expected_input_commitment.len()); + + for (a, b) in inputs.iter().zip(expected_input_commitment.iter()) { + Num::conditionally_enforce_equal(cs, should_verify, a, b); + } + } + + // now we can collapse queues + let bootloader_heap_snapshot: [_; QUEUE_FINAL_STATE_COMMITMENT_LENGTH] = + finalize_queue_state(cs, &bootloader_heap_memory_state, round_function); + + let events_snapshot: [_; QUEUE_FINAL_STATE_COMMITMENT_LENGTH] = finalize_queue_state( + cs, + &events_sorter_observable_output.final_queue_state.tail, + round_function, + ); + + // Form a public block header + let mut this_block_data = prev_block_data.clone(); + + for ((dst, counter), root) in this_block_data + .per_shard_states + .iter_mut() + .zip(final_enumeration_counters.iter()) + .zip(final_state_roots.iter()) + { + dst.enumeration_counter = *counter; + dst.state_root = *root; + } + + let zero_u8 = UInt8::zero(cs); + + let mut bootloader_heap_initial_content = [zero_u8; 32]; + for (dst, src) in bootloader_heap_initial_content + .array_chunks_mut::<8>() + .zip(bootloader_heap_snapshot.iter()) + { + let le_bytes = src.constraint_bit_length_as_bytes(cs, 64); + dst.copy_from_slice(&le_bytes[..]); + dst.reverse(); + } + + let mut events_queue_state = [zero_u8; 32]; + for (dst, src) in events_queue_state + .array_chunks_mut::<8>() + .zip(events_snapshot.iter()) + { + let le_bytes = src.constraint_bit_length_as_bytes(cs, 64); + dst.copy_from_slice(&le_bytes[..]); + dst.reverse(); + } + + let aux_data = BlockAuxilaryOutput { + rollup_state_diff_for_compression: storage_application_observable_output + .state_diffs_keccak256_hash, + bootloader_heap_initial_content, + events_queue_state, + l1_messages_linear_hash: l1messages_linear_hasher_observable_output.keccak256_hash, + }; + + let block_content_header = BlockContentHeader { + block_data: this_block_data, + block_meta: block_meta_parameters, + auxilary_output: aux_data, + }; + + let (this_block_content_hash, _) = block_content_header.clone().into_formal_block_hash(cs); + + // we are done with this block, process the previous one + let previous_block_passthrough_data = prev_block_data.into_flattened_bytes(cs); + let previous_block_passthrough_hash = + keccak256::keccak256(cs, &previous_block_passthrough_data); + + let previous_block_meta_hash = <[UInt8; 32]>::allocate(cs, witness.previous_block_meta_hash); + let previous_block_aux_hash = <[UInt8; 32]>::allocate(cs, witness.previous_block_aux_hash); + + let previous_block_content_hash = BlockContentHeader::formal_block_hash_from_partial_hashes( + cs, + previous_block_passthrough_hash, + previous_block_meta_hash, + previous_block_aux_hash, + ); + + // form full block hash + + let mut flattened_public_input = vec![]; + flattened_public_input.extend(previous_block_content_hash); + flattened_public_input.extend(this_block_content_hash); + // recursion parameters + + let mut recursion_node_verification_key_hash = [zero_u8; 32]; + for (dst, src) in recursion_node_verification_key_hash + .array_chunks_mut::<8>() + .zip(node_layer_vk_commitment.iter()) + { + let le_bytes = src.constraint_bit_length_as_bytes(cs, 64); + dst.copy_from_slice(&le_bytes[..]); + dst.reverse(); + } + + let mut leaf_layer_parameters_hash = [zero_u8; 32]; + for (dst, src) in leaf_layer_parameters_hash + .array_chunks_mut::<8>() + .zip(leaf_layer_parameters_commitment.iter()) + { + let le_bytes = src.constraint_bit_length_as_bytes(cs, 64); + dst.copy_from_slice(&le_bytes[..]); + dst.reverse(); + } + + flattened_public_input.extend(recursion_node_verification_key_hash); + flattened_public_input.extend(leaf_layer_parameters_hash); + + let input_keccak_hash = keccak256::keccak256(cs, &flattened_public_input); + let take_by = F::CAPACITY_BITS / 8; + + for chunk in input_keccak_hash + .chunks_exact(take_by) + .take(NUM_SCHEDULER_PUBLIC_INPUTS) + { + let mut lc = Vec::with_capacity(chunk.len()); + // treat as BE + for (idx, el) in chunk.iter().rev().enumerate() { + lc.push((el.get_variable(), F::SHIFTS[idx * 8])); + } + let as_num = Num::linear_combination(cs, &lc); + use boojum::cs::gates::PublicInputGate; + let gate = PublicInputGate::new(as_num.get_variable()); + gate.add_to_cs(cs); + } +} diff --git a/crates/zkevm_circuits/src/sha256_round_function/input.rs b/crates/zkevm_circuits/src/sha256_round_function/input.rs new file mode 100644 index 0000000..b6f81c5 --- /dev/null +++ b/crates/zkevm_circuits/src/sha256_round_function/input.rs @@ -0,0 +1,89 @@ +use std::collections::VecDeque; + +use super::*; + +use crate::base_structures::precompile_input_outputs::*; +use crate::base_structures::vm_state::*; +use boojum::cs::Variable; +use boojum::gadgets::queue::*; +use boojum::gadgets::traits::allocatable::CSAllocatable; +use boojum::gadgets::traits::allocatable::CSPlaceholder; +use boojum::gadgets::traits::encodable::CircuitVarLengthEncodable; + +use boojum::cs::traits::cs::ConstraintSystem; +use boojum::field::SmallField; +use boojum::gadgets::boolean::Boolean; +use boojum::gadgets::traits::auxiliary::PrettyComparison; +use boojum::gadgets::traits::selectable::Selectable; +use boojum::gadgets::traits::witnessable::WitnessHookable; +use boojum::serde_utils::BigArraySerde; + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +#[DerivePrettyComparison("true")] +pub struct Sha256RoundFunctionFSM { + pub read_precompile_call: Boolean, + pub read_words_for_round: Boolean, + pub completed: Boolean, + pub sha256_inner_state: [UInt32; 8], + pub timestamp_to_use_for_read: UInt32, + pub timestamp_to_use_for_write: UInt32, + pub precompile_call_params: Sha256PrecompileCallParams, +} + +impl CSPlaceholder for Sha256RoundFunctionFSM { + fn placeholder>(cs: &mut CS) -> Self { + let boolean_false = Boolean::allocated_constant(cs, false); + let zero_u32 = UInt32::zero(cs); + Self { + read_precompile_call: boolean_false, + read_words_for_round: boolean_false, + completed: boolean_false, + sha256_inner_state: boojum::gadgets::sha256::ivs_as_uint32(cs), + timestamp_to_use_for_read: zero_u32, + timestamp_to_use_for_write: zero_u32, + precompile_call_params: Sha256PrecompileCallParams::::placeholder(cs), + } + } +} + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +#[DerivePrettyComparison("true")] +pub struct Sha256RoundFunctionFSMInputOutput { + pub internal_fsm: Sha256RoundFunctionFSM, + pub log_queue_state: QueueState, + pub memory_queue_state: QueueState, +} + +impl CSPlaceholder for Sha256RoundFunctionFSMInputOutput { + fn placeholder>(cs: &mut CS) -> Self { + Self { + internal_fsm: Sha256RoundFunctionFSM::placeholder(cs), + log_queue_state: QueueState::::placeholder(cs), + memory_queue_state: QueueState::::placeholder(cs), + } + } +} + +pub type Sha256RoundFunctionCircuitInputOutput = ClosedFormInput< + F, + Sha256RoundFunctionFSMInputOutput, + PrecompileFunctionInputData, + PrecompileFunctionOutputData, +>; +pub type Sha256RoundFunctionCircuitInputOutputWitness = ClosedFormInputWitness< + F, + Sha256RoundFunctionFSMInputOutput, + PrecompileFunctionInputData, + PrecompileFunctionOutputData, +>; + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Debug, Default)] +#[serde(bound = "")] +pub struct Sha256RoundFunctionCircuitInstanceWitness { + pub closed_form_input: Sha256RoundFunctionCircuitInputOutputWitness, + pub requests_queue_witness: CircuitQueueRawWitness, 4, LOG_QUERY_PACKED_WIDTH>, + pub memory_reads_witness: VecDeque, +} diff --git a/crates/zkevm_circuits/src/sha256_round_function/mod.rs b/crates/zkevm_circuits/src/sha256_round_function/mod.rs new file mode 100644 index 0000000..400ec6d --- /dev/null +++ b/crates/zkevm_circuits/src/sha256_round_function/mod.rs @@ -0,0 +1,464 @@ +use super::*; + +use boojum::field::SmallField; + +use boojum::gadgets::traits::witnessable::WitnessHookable; + +use boojum::cs::traits::cs::ConstraintSystem; +use boojum::gadgets::boolean::Boolean; +use boojum::gadgets::traits::selectable::Selectable; +use boojum::gadgets::u256::UInt256; +use boojum::gadgets::u32::UInt32; +use cs_derive::*; + +use crate::ethereum_types::U256; +use crate::fsm_input_output::circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH; +use boojum::gadgets::num::Num; +use zkevm_opcode_defs::system_params::PRECOMPILE_AUX_BYTE; + +use crate::base_structures::log_query::*; +use crate::base_structures::memory_query::*; +use crate::base_structures::precompile_input_outputs::PrecompileFunctionOutputData; +use crate::demux_log_queue::StorageLogQueue; +use crate::fsm_input_output::*; +use crate::storage_application::ConditionalWitnessAllocator; +use boojum::algebraic_props::round_function::AlgebraicRoundFunction; +use boojum::cs::Variable; +use boojum::gadgets::queue::CircuitQueueWitness; +use boojum::gadgets::queue::QueueState; +use boojum::gadgets::sha256::{self}; +use boojum::gadgets::traits::allocatable::CSAllocatable; +use boojum::gadgets::traits::allocatable::{CSAllocatableExt, CSPlaceholder}; +use boojum::gadgets::traits::encodable::CircuitVarLengthEncodable; +use boojum::gadgets::traits::round_function::CircuitRoundFunction; +use boojum::gadgets::u160::UInt160; +use boojum::gadgets::u8::UInt8; +use std::sync::{Arc, RwLock}; + +pub mod input; +use self::input::*; + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +// #[DerivePrettyComparison("true")] +pub struct Sha256PrecompileCallParams { + pub input_page: UInt32, + pub input_offset: UInt32, + pub output_page: UInt32, + pub output_offset: UInt32, + pub num_rounds: UInt32, +} + +impl CSPlaceholder for Sha256PrecompileCallParams { + fn placeholder>(cs: &mut CS) -> Self { + let zero_u32 = UInt32::zero(cs); + Self { + input_page: zero_u32, + input_offset: zero_u32, + output_page: zero_u32, + output_offset: zero_u32, + num_rounds: zero_u32, + } + } +} + +impl Sha256PrecompileCallParams { + pub fn from_encoding>(_cs: &mut CS, encoding: UInt256) -> Self { + let input_offset = encoding.inner[0]; + let output_offset = encoding.inner[2]; + let input_page = encoding.inner[4]; + let output_page = encoding.inner[5]; + + let num_rounds = encoding.inner[6]; + + let new = Self { + input_page, + input_offset, + output_page, + output_offset, + num_rounds, + }; + + new + } +} + +pub const MEMORY_READ_QUERIES_PER_CYCLE: usize = 2; + +pub fn sha256_precompile_inner< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, +>( + cs: &mut CS, + memory_queue: &mut MemoryQueue, + precompile_calls_queue: &mut StorageLogQueue, + memory_read_witness: ConditionalWitnessAllocator>, + mut state: Sha256RoundFunctionFSM, + _round_function: &R, + limit: usize, +) -> Sha256RoundFunctionFSM +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, +{ + assert!(limit <= u32::MAX as usize); + + let precompile_address = UInt160::allocated_constant( + cs, + *zkevm_opcode_defs::system_params::SHA256_ROUND_FUNCTION_PRECOMPILE_FORMAL_ADDRESS, + ); + let aux_byte_for_precompile = UInt8::allocated_constant(cs, PRECOMPILE_AUX_BYTE); + + let boolean_false = Boolean::allocated_constant(cs, false); + let boolean_true = Boolean::allocated_constant(cs, true); + let zero_u32 = UInt32::zero(cs); + let zero_u256 = UInt256::zero(cs); + + // we can have a degenerate case when queue is empty, but it's a first circuit in the queue, + // so we taken default FSM state that has state.read_precompile_call = true; + let input_queue_is_empty = precompile_calls_queue.is_empty(cs); + // we can only skip the full circuit if we are not in any form of progress + let can_finish_immediatelly = + Boolean::multi_and(cs, &[state.read_precompile_call, input_queue_is_empty]); + + if crate::config::CIRCUIT_VERSOBE { + dbg!(can_finish_immediatelly.witness_hook(cs)()); + dbg!(state.witness_hook(cs)()); + } + + state.read_precompile_call = state + .read_precompile_call + .mask_negated(cs, can_finish_immediatelly); + state.read_words_for_round = state + .read_words_for_round + .mask_negated(cs, can_finish_immediatelly); + state.completed = Boolean::multi_or(cs, &[state.completed, can_finish_immediatelly]); + + if crate::config::CIRCUIT_VERSOBE { + dbg!(state.witness_hook(cs)()); + dbg!(precompile_calls_queue.into_state().witness_hook(cs)()); + memory_read_witness.print_debug_info(); + } + // main work cycle + for _cycle in 0..limit { + if crate::config::CIRCUIT_VERSOBE { + dbg!(_cycle); + dbg!(state.witness_hook(cs)()); + dbg!(precompile_calls_queue.into_state().witness_hook(cs)()); + } + // if we are in a proper state then get the ABI from the queue + let (precompile_call, _) = precompile_calls_queue.pop_front(cs, state.read_precompile_call); + + Num::conditionally_enforce_equal( + cs, + state.read_precompile_call, + &Num::from_variable(precompile_call.aux_byte.get_variable()), + &Num::from_variable(aux_byte_for_precompile.get_variable()), + ); + for (a, b) in precompile_call + .address + .inner + .iter() + .zip(precompile_address.inner.iter()) + { + Num::conditionally_enforce_equal( + cs, + state.read_precompile_call, + &Num::from_variable(a.get_variable()), + &Num::from_variable(b.get_variable()), + ); + } + + // now compute some parameters that describe the call itself + + let params_encoding = precompile_call.key; + let call_params = Sha256PrecompileCallParams::from_encoding(cs, params_encoding); + + state.precompile_call_params = Sha256PrecompileCallParams::conditionally_select( + cs, + state.read_precompile_call, + &call_params, + &state.precompile_call_params, + ); + // also set timestamps + state.timestamp_to_use_for_read = UInt32::conditionally_select( + cs, + state.read_precompile_call, + &precompile_call.timestamp, + &state.timestamp_to_use_for_read, + ); + + // timestamps have large space, so this can be expected + let timestamp_to_use_for_write = + unsafe { state.timestamp_to_use_for_read.increment_unchecked(cs) }; + state.timestamp_to_use_for_write = UInt32::conditionally_select( + cs, + state.read_precompile_call, + ×tamp_to_use_for_write, + &state.timestamp_to_use_for_write, + ); + + let reset_buffer = Boolean::multi_or(cs, &[state.read_precompile_call, state.completed]); + state.read_words_for_round = Boolean::multi_or( + cs, + &[state.read_precompile_call, state.read_words_for_round], + ); + state.read_precompile_call = boolean_false; + + // --------------------------------- + // Now perform few memory queries to read content + + let zero_rounds_left = state.precompile_call_params.num_rounds.is_zero(cs); + + let mut memory_queries_as_u32_words = [zero_u32; 8 * MEMORY_READ_QUERIES_PER_CYCLE]; + let should_read = zero_rounds_left.negated(cs); + let mut bias_variable = should_read.get_variable(); + for dst in memory_queries_as_u32_words.array_chunks_mut::<8>() { + let read_query_value = + memory_read_witness.conditionally_allocate_biased(cs, should_read, bias_variable); + bias_variable = read_query_value.inner[0].get_variable(); + + let read_query = MemoryQuery { + timestamp: state.timestamp_to_use_for_read, + memory_page: state.precompile_call_params.input_page, + index: state.precompile_call_params.input_offset, + rw_flag: boolean_false, + is_ptr: boolean_false, + value: read_query_value, + }; + + let may_be_new_offset = unsafe { + state + .precompile_call_params + .input_offset + .increment_unchecked(cs) + }; + state.precompile_call_params.input_offset = UInt32::conditionally_select( + cs, + state.read_words_for_round, + &may_be_new_offset, + &state.precompile_call_params.input_offset, + ); + + // perform read + memory_queue.push(cs, read_query, should_read); + + // we need to change endianess. Memory is BE, and each of 4 byte chunks should be interpreted as BE u32 for sha256 + let be_bytes = read_query_value.to_be_bytes(cs); + for (dst, src) in dst.iter_mut().zip(be_bytes.array_chunks::<4>()) { + let as_u32 = UInt32::from_be_bytes(cs, *src); + *dst = as_u32; + } + } + + let may_be_new_num_rounds = unsafe { + state + .precompile_call_params + .num_rounds + .decrement_unchecked(cs) + }; + state.precompile_call_params.num_rounds = UInt32::conditionally_select( + cs, + state.read_words_for_round, + &may_be_new_num_rounds, + &state.precompile_call_params.num_rounds, + ); + + // absorb + let sha256_empty_internal_state = sha256::ivs_as_uint32(cs); + + let mut current_sha256_state = <[UInt32; 8]>::conditionally_select( + cs, + reset_buffer, + &sha256_empty_internal_state, + &state.sha256_inner_state, + ); + + let sha256_output = sha256::round_function::round_function_over_uint32( + cs, + &mut current_sha256_state, + &memory_queries_as_u32_words, + ); + state.sha256_inner_state = current_sha256_state; + + let no_rounds_left = state.precompile_call_params.num_rounds.is_zero(cs); + let write_result = Boolean::multi_and(cs, &[state.read_words_for_round, no_rounds_left]); + + let mut write_word = zero_u256; + // some endianess magic + for (dst, src) in write_word + .inner + .iter_mut() + .rev() + .zip(sha256_output.array_chunks::<4>()) + { + *dst = UInt32::from_le_bytes(cs, *src); + } + + let write_query = MemoryQuery { + timestamp: state.timestamp_to_use_for_write, + memory_page: state.precompile_call_params.output_page, + index: state.precompile_call_params.output_offset, + rw_flag: boolean_true, + is_ptr: boolean_false, + value: write_word, + }; + + // perform write + memory_queue.push(cs, write_query, write_result); + + // --------------------------------- + + // update state + let input_is_empty = precompile_calls_queue.is_empty(cs); + let input_is_not_empty = input_is_empty.negated(cs); + let nothing_left = Boolean::multi_and(cs, &[write_result, input_is_empty]); + let process_next = Boolean::multi_and(cs, &[write_result, input_is_not_empty]); + + state.read_precompile_call = process_next; + state.completed = Boolean::multi_or(cs, &[nothing_left, state.completed]); + let t = Boolean::multi_or(cs, &[state.read_precompile_call, state.completed]); + state.read_words_for_round = t.negated(cs); + + if crate::config::CIRCUIT_VERSOBE { + dbg!(state.witness_hook(cs)()); + dbg!(precompile_calls_queue.into_state().witness_hook(cs)()); + } + } + + if crate::config::CIRCUIT_VERSOBE { + dbg!(state.witness_hook(cs)()); + dbg!(precompile_calls_queue.into_state().witness_hook(cs)()); + } + + precompile_calls_queue.enforce_consistency(cs); + + state +} + +#[track_caller] +pub fn sha256_round_function_entry_point< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, +>( + cs: &mut CS, + witness: Sha256RoundFunctionCircuitInstanceWitness, + round_function: &R, + limit: usize, +) -> [Num; INPUT_OUTPUT_COMMITMENT_LENGTH] +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, +{ + let Sha256RoundFunctionCircuitInstanceWitness { + closed_form_input, + requests_queue_witness, + memory_reads_witness, + } = witness; + + let mut structured_input = Sha256RoundFunctionCircuitInputOutput::alloc_ignoring_outputs( + cs, + closed_form_input.clone(), + ); + + let start_flag = structured_input.start_flag; + + let requests_queue_state_from_input = structured_input.observable_input.initial_log_queue_state; + + // it must be trivial + requests_queue_state_from_input.enforce_trivial_head(cs); + + let requests_queue_state_from_fsm = structured_input.hidden_fsm_input.log_queue_state; + + let requests_queue_state = QueueState::conditionally_select( + cs, + start_flag, + &requests_queue_state_from_input, + &requests_queue_state_from_fsm, + ); + + let memory_queue_state_from_input = + structured_input.observable_input.initial_memory_queue_state; + + // it must be trivial + memory_queue_state_from_input.enforce_trivial_head(cs); + + let memory_queue_state_from_fsm = structured_input.hidden_fsm_input.memory_queue_state; + + let memory_queue_state = QueueState::conditionally_select( + cs, + start_flag, + &memory_queue_state_from_input, + &memory_queue_state_from_fsm, + ); + + let mut requests_queue = StorageLogQueue::::from_state(cs, requests_queue_state); + let queue_witness = CircuitQueueWitness::from_inner_witness(requests_queue_witness); + requests_queue.witness = Arc::new(queue_witness); + + let mut memory_queue = MemoryQueue::::from_state(cs, memory_queue_state); + + let read_queries_allocator = ConditionalWitnessAllocator::> { + witness_source: Arc::new(RwLock::new(memory_reads_witness)), + }; + + let mut starting_fsm_state = Sha256RoundFunctionFSM::placeholder(cs); + starting_fsm_state.read_precompile_call = Boolean::allocated_constant(cs, true); + + let initial_state = Sha256RoundFunctionFSM::conditionally_select( + cs, + start_flag, + &starting_fsm_state, + &structured_input.hidden_fsm_input.internal_fsm, + ); + + let final_state = sha256_precompile_inner::( + cs, + &mut memory_queue, + &mut requests_queue, + read_queries_allocator, + initial_state, + round_function, + limit, + ); + + let final_memory_state = memory_queue.into_state(); + let final_requets_state = requests_queue.into_state(); + + // form the final state + let done = final_state.completed; + structured_input.completion_flag = done; + structured_input.observable_output = PrecompileFunctionOutputData::placeholder(cs); + + structured_input.observable_output.final_memory_state = QueueState::conditionally_select( + cs, + structured_input.completion_flag, + &final_memory_state, + &structured_input.observable_output.final_memory_state, + ); + + structured_input.hidden_fsm_output.internal_fsm = final_state; + structured_input.hidden_fsm_output.log_queue_state = final_requets_state; + structured_input.hidden_fsm_output.memory_queue_state = final_memory_state; + + // self-check + structured_input.hook_compare_witness(cs, &closed_form_input); + + use boojum::cs::gates::PublicInputGate; + + let compact_form = + ClosedFormInputCompactForm::from_full_form(cs, &structured_input, round_function); + let input_commitment = commit_variable_length_encodable_item(cs, &compact_form, round_function); + for el in input_commitment.iter() { + let gate = PublicInputGate::new(el.get_variable()); + gate.add_to_cs(cs); + } + + input_commitment +} diff --git a/crates/zkevm_circuits/src/sort_decommittment_requests/input.rs b/crates/zkevm_circuits/src/sort_decommittment_requests/input.rs new file mode 100644 index 0000000..de15754 --- /dev/null +++ b/crates/zkevm_circuits/src/sort_decommittment_requests/input.rs @@ -0,0 +1,124 @@ +use crate::base_structures::decommit_query::DECOMMIT_QUERY_PACKED_WIDTH; +use crate::sort_decommittment_requests::full_state_queue::FullStateCircuitQueueRawWitness; +use crate::sort_decommittment_requests::*; +use boojum::cs::{traits::cs::ConstraintSystem, Variable}; +use boojum::field::SmallField; +use boojum::gadgets::num::Num; +use boojum::gadgets::traits::auxiliary::PrettyComparison; +use boojum::gadgets::u32::UInt32; +use boojum::gadgets::{ + boolean::Boolean, + queue::*, + traits::{ + allocatable::*, encodable::CircuitVarLengthEncodable, selectable::Selectable, + witnessable::WitnessHookable, + }, +}; +use boojum::serde_utils::BigArraySerde; +use cs_derive::*; +use derivative::*; + +pub const PACKED_KEY_LENGTH: usize = 8 + 1; + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +#[DerivePrettyComparison("true")] +pub struct CodeDecommittmentsDeduplicatorFSMInputOutput { + pub initial_queue_state: QueueState, + pub sorted_queue_state: QueueState, + pub final_queue_state: QueueState, + + pub lhs_accumulator: [Num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + pub rhs_accumulator: [Num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + + pub previous_packed_key: [UInt32; PACKED_KEY_LENGTH], + pub first_encountered_timestamp: UInt32, + pub previous_record: DecommitQuery, +} + +impl CSPlaceholder for CodeDecommittmentsDeduplicatorFSMInputOutput { + fn placeholder>(cs: &mut CS) -> Self { + let zero_num = Num::zero(cs); + let zero_u32 = UInt32::zero(cs); + + Self { + initial_queue_state: QueueState::::placeholder(cs), + sorted_queue_state: QueueState::::placeholder(cs), + final_queue_state: QueueState::::placeholder(cs), + + lhs_accumulator: [zero_num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + rhs_accumulator: [zero_num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + + previous_packed_key: [zero_u32; PACKED_KEY_LENGTH], + first_encountered_timestamp: zero_u32, + previous_record: DecommitQuery::::placeholder(cs), + } + } +} + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +#[DerivePrettyComparison("true")] +pub struct CodeDecommittmentsDeduplicatorInputData { + pub initial_queue_state: QueueState, + pub sorted_queue_initial_state: QueueState, +} + +impl CSPlaceholder for CodeDecommittmentsDeduplicatorInputData { + fn placeholder>(cs: &mut CS) -> Self { + Self { + initial_queue_state: QueueState::::placeholder(cs), + sorted_queue_initial_state: QueueState::::placeholder( + cs, + ), + } + } +} + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +#[DerivePrettyComparison("true")] +pub struct CodeDecommittmentsDeduplicatorOutputData { + pub final_queue_state: QueueState, +} + +impl CSPlaceholder for CodeDecommittmentsDeduplicatorOutputData { + fn placeholder>(cs: &mut CS) -> Self { + Self { + final_queue_state: QueueState::::placeholder(cs), + } + } +} + +pub type CodeDecommittmentsDeduplicatorInputOutput = crate::fsm_input_output::ClosedFormInput< + F, + CodeDecommittmentsDeduplicatorFSMInputOutput, + CodeDecommittmentsDeduplicatorInputData, + CodeDecommittmentsDeduplicatorOutputData, +>; +pub type CodeDecommittmentsDeduplicatorInputOutputWitness = + crate::fsm_input_output::ClosedFormInputWitness< + F, + CodeDecommittmentsDeduplicatorFSMInputOutput, + CodeDecommittmentsDeduplicatorInputData, + CodeDecommittmentsDeduplicatorOutputData, + >; + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Debug, Default)] +#[serde(bound = "")] +pub struct CodeDecommittmentsDeduplicatorInstanceWitness { + pub closed_form_input: CodeDecommittmentsDeduplicatorInputOutputWitness, + pub initial_queue_witness: FullStateCircuitQueueRawWitness< + F, + DecommitQuery, + FULL_SPONGE_QUEUE_STATE_WIDTH, + DECOMMIT_QUERY_PACKED_WIDTH, + >, + pub sorted_queue_witness: FullStateCircuitQueueRawWitness< + F, + DecommitQuery, + FULL_SPONGE_QUEUE_STATE_WIDTH, + DECOMMIT_QUERY_PACKED_WIDTH, + >, +} diff --git a/crates/zkevm_circuits/src/sort_decommittment_requests/mod.rs b/crates/zkevm_circuits/src/sort_decommittment_requests/mod.rs new file mode 100644 index 0000000..9c5b51b --- /dev/null +++ b/crates/zkevm_circuits/src/sort_decommittment_requests/mod.rs @@ -0,0 +1,1389 @@ +use super::*; + +use crate::base_structures::log_query::LOG_QUERY_PACKED_WIDTH; +use crate::fsm_input_output::ClosedFormInputCompactForm; +use crate::utils::accumulate_grand_products; + +use boojum::cs::{gates::*, traits::cs::ConstraintSystem}; +use boojum::field::SmallField; +use boojum::gadgets::queue::full_state_queue::FullStateCircuitQueueWitness; +use boojum::gadgets::traits::round_function::CircuitRoundFunction; +use boojum::gadgets::traits::witnessable::WitnessHookable; +use boojum::gadgets::{ + boolean::Boolean, + num::Num, + queue::*, + traits::{allocatable::CSAllocatableExt, selectable::Selectable}, + u32::UInt32, +}; + +use crate::base_structures::decommit_query::{DecommitQueue, DECOMMIT_QUERY_PACKED_WIDTH}; +use crate::base_structures::vm_state::*; +use crate::base_structures::{ + decommit_query::DecommitQuery, memory_query::MEMORY_QUERY_PACKED_WIDTH, +}; +use crate::fsm_input_output::{circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH, *}; +use crate::sort_decommittment_requests::input::*; +use crate::storage_validity_by_grand_product::unpacked_long_comparison; +use boojum::algebraic_props::round_function::AlgebraicRoundFunction; +use boojum::gadgets::traits::allocatable::CSPlaceholder; +use boojum::gadgets::u256::UInt256; + +pub mod input; + +// This is a sorter of logs that are kind-of "pure", F.g. event emission or L2 -> L1 messages. +// Those logs do not affect a global state and may either be rolled back in full or not. +// We identify equality of logs using "timestamp" field that is a monotonic unique counter +// across the block +pub const NUM_PERMUTATION_ARG_CHALLENGES: usize = LOG_QUERY_PACKED_WIDTH + 1; + +pub fn sort_and_deduplicate_code_decommittments_entry_point< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, +>( + cs: &mut CS, + witness: CodeDecommittmentsDeduplicatorInstanceWitness, + round_function: &R, + limit: usize, +) -> [Num; INPUT_OUTPUT_COMMITMENT_LENGTH] +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + // as usual we assume that a caller of this fuunction has already split input queue, + // so it can be comsumed in full + + //use table + let CodeDecommittmentsDeduplicatorInstanceWitness { + closed_form_input, + initial_queue_witness, + sorted_queue_witness, + } = witness; + + let mut structured_input = CodeDecommittmentsDeduplicatorInputOutput::alloc_ignoring_outputs( + cs, + closed_form_input.clone(), + ); + + let initial_queue_from_passthrough_state = + structured_input.observable_input.initial_queue_state; + let initial_log_queue_state_from_fsm_state = + structured_input.hidden_fsm_input.initial_queue_state; + + let state = QueueState::conditionally_select( + cs, + structured_input.start_flag, + &initial_queue_from_passthrough_state, + &initial_log_queue_state_from_fsm_state, + ); + let mut initial_queue = DecommitQueue::::from_state(cs, state); + + // passthrough must be trivial + initial_queue_from_passthrough_state.enforce_trivial_head(cs); + + use std::sync::Arc; + let initial_queue_witness = + FullStateCircuitQueueWitness::from_inner_witness(initial_queue_witness); + initial_queue.witness = Arc::new(initial_queue_witness); + + let intermediate_sorted_queue_from_passthrough_state = + structured_input.observable_input.sorted_queue_initial_state; + let intermediate_sorted_queue_from_fsm_input_state = + structured_input.hidden_fsm_input.sorted_queue_state; + + // it must be trivial + intermediate_sorted_queue_from_passthrough_state.enforce_trivial_head(cs); + + let state = QueueState::conditionally_select( + cs, + structured_input.start_flag, + &intermediate_sorted_queue_from_passthrough_state, + &intermediate_sorted_queue_from_fsm_input_state, + ); + let mut intermediate_sorted_queue = DecommitQueue::::from_state(cs, state); + + let sorted_queue_witness = + FullStateCircuitQueueWitness::from_inner_witness(sorted_queue_witness); + intermediate_sorted_queue.witness = Arc::new(sorted_queue_witness); + + let empty_state = QueueState::empty(cs); + + let final_sorted_queue_from_fsm_state = structured_input.hidden_fsm_input.final_queue_state; + + let state = QueueState::conditionally_select( + cs, + structured_input.start_flag, + &empty_state, + &final_sorted_queue_from_fsm_state, + ); + let mut final_sorted_queue = DecommitQueue::::from_state(cs, state); + + let challenges = crate::utils::produce_fs_challenges::< + F, + CS, + R, + FULL_SPONGE_QUEUE_STATE_WIDTH, + { DECOMMIT_QUERY_PACKED_WIDTH + 1 }, + DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS, + >( + cs, + structured_input.observable_input.initial_queue_state.tail, + structured_input + .observable_input + .sorted_queue_initial_state + .tail, + round_function, + ); + + let one = Num::allocated_constant(cs, F::ONE); + let initial_lhs = Num::parallel_select( + cs, + structured_input.start_flag, + &[one; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + &structured_input.hidden_fsm_input.lhs_accumulator, + ); + + let initial_rhs = Num::parallel_select( + cs, + structured_input.start_flag, + &[one; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + &structured_input.hidden_fsm_input.rhs_accumulator, + ); + + let trivial_record = DecommitQuery::placeholder(cs); + let mut previous_record = DecommitQuery::conditionally_select( + cs, + structured_input.start_flag, + &trivial_record, + &structured_input.hidden_fsm_input.previous_record, + ); + + let zero_u32 = UInt32::zero(cs); + let mut previous_packed_key = <[UInt32; PACKED_KEY_LENGTH]>::conditionally_select( + cs, + structured_input.start_flag, + &[zero_u32; PACKED_KEY_LENGTH], + &structured_input.hidden_fsm_input.previous_packed_key, + ); + + let mut first_encountered_timestamp = UInt32::conditionally_select( + cs, + structured_input.start_flag, + &zero_u32, + &structured_input + .hidden_fsm_input + .first_encountered_timestamp, + ); + + let (completed, new_lhs, new_rhs) = sort_and_deduplicate_code_decommittments_inner( + cs, + &mut initial_queue, + &mut intermediate_sorted_queue, + &mut final_sorted_queue, + initial_lhs, + initial_rhs, + challenges, + &mut previous_packed_key, + &mut first_encountered_timestamp, + &mut previous_record, + structured_input.start_flag, + limit, + ); + + for (lhs, rhs) in new_lhs.iter().zip(new_rhs.iter()) { + Num::conditionally_enforce_equal(cs, completed, lhs, rhs); + } + // form the final state + structured_input.observable_output = CodeDecommittmentsDeduplicatorOutputData::placeholder(cs); + + structured_input.hidden_fsm_output = + CodeDecommittmentsDeduplicatorFSMInputOutput::placeholder(cs); + structured_input.hidden_fsm_output.initial_queue_state = initial_queue.into_state(); + structured_input.hidden_fsm_output.sorted_queue_state = intermediate_sorted_queue.into_state(); + structured_input.hidden_fsm_output.final_queue_state = final_sorted_queue.into_state(); + structured_input.hidden_fsm_output.lhs_accumulator = new_lhs; + structured_input.hidden_fsm_output.rhs_accumulator = new_rhs; + structured_input.hidden_fsm_output.previous_packed_key = previous_packed_key; + structured_input.hidden_fsm_output.previous_record = previous_record; + structured_input + .hidden_fsm_output + .first_encountered_timestamp = first_encountered_timestamp; + + structured_input.observable_output.final_queue_state = QueueState::conditionally_select( + cs, + completed, + &structured_input.hidden_fsm_output.final_queue_state, + &structured_input.observable_output.final_queue_state, + ); + + structured_input.completion_flag = completed; + + // self-check + structured_input.hook_compare_witness(cs, &closed_form_input); + + let compact_form = + ClosedFormInputCompactForm::from_full_form(cs, &structured_input, round_function); + let input_commitment = commit_variable_length_encodable_item(cs, &compact_form, round_function); + for el in input_commitment.iter() { + let gate = PublicInputGate::new(el.get_variable()); + gate.add_to_cs(cs); + } + + input_commitment +} + +pub fn sort_and_deduplicate_code_decommittments_inner< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, +>( + cs: &mut CS, + original_queue: &mut DecommitQueue, + sorted_queue: &mut DecommitQueue, + result_queue: &mut DecommitQueue, + mut lhs: [Num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + mut rhs: [Num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + fs_challenges: [[Num; DECOMMIT_QUERY_PACKED_WIDTH + 1]; + DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + previous_packed_key: &mut [UInt32; PACKED_KEY_LENGTH], + first_encountered_timestamp: &mut UInt32, + previous_record: &mut DecommitQuery, + start_flag: Boolean, + limit: usize, +) -> ( + Boolean, + [Num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + [Num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], +) +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); DECOMMIT_QUERY_PACKED_WIDTH + 1]:, +{ + assert!(limit <= u32::MAX as usize); + let unsorted_queue_length = Num::from_variable(original_queue.length.get_variable()); + let intermediate_sorted_queue_length = Num::from_variable(sorted_queue.length.get_variable()); + + Num::enforce_equal( + cs, + &unsorted_queue_length, + &intermediate_sorted_queue_length, + ); + + let no_work = original_queue.is_empty(cs); + + let mut previous_item_is_trivial = no_work.or(cs, start_flag); + + // Simultaneously pop, prove sorting and resolve logic + + for _cycle in 0..limit { + let original_is_empty = original_queue.is_empty(cs); + let sorted_is_empty = sorted_queue.is_empty(cs); + Boolean::enforce_equal(cs, &original_is_empty, &sorted_is_empty); + + let should_pop = original_is_empty.negated(cs); + let is_trivial = original_is_empty; + + let (_, original_encoding) = original_queue.pop_front(cs, should_pop); + let (sorted_item, sorted_encoding) = sorted_queue.pop_front(cs, should_pop); + + // we make encoding that is the same as defined for timestamped item + accumulate_grand_products::< + F, + CS, + DECOMMIT_QUERY_PACKED_WIDTH, + { DECOMMIT_QUERY_PACKED_WIDTH + 1 }, + DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS, + >( + cs, + &mut lhs, + &mut rhs, + &fs_challenges, + &original_encoding, + &sorted_encoding, + should_pop, + ); + + // check if keys are equal and check a value + let packed_key = concatenate_key(cs, (sorted_item.timestamp, sorted_item.code_hash)); + + // ensure sorting for uniqueness timestamp and rollback flag + // We know that timestamps are unique accross logs, and are also the same between write and rollback + let (_keys_are_equal, new_key_is_greater) = + unpacked_long_comparison(cs, &packed_key, &*previous_packed_key); + // always ascedning + new_key_is_greater.conditionally_enforce_true(cs, should_pop); + + let same_hash = UInt256::equals(cs, &previous_record.code_hash, &sorted_item.code_hash); + + // if we get new hash then it my have a "first" marker + let different_hash = same_hash.negated(cs); + let enforce_must_be_first = Boolean::multi_and(cs, &[different_hash, should_pop]); + sorted_item + .is_first + .conditionally_enforce_true(cs, enforce_must_be_first); + + // otherwise it should have the same memory page + let previous_is_non_trivial = previous_item_is_trivial.negated(cs); + let enforce_same_memory_page = + Boolean::multi_and(cs, &[same_hash, previous_is_non_trivial]); + + Num::conditionally_enforce_equal( + cs, + enforce_same_memory_page, + &sorted_item.page.into_num(), + &previous_record.page.into_num(), + ); + + // decide if we should add the PREVIOUS into the queue + let add_to_the_queue = Boolean::multi_and(cs, &[previous_is_non_trivial, different_hash]); + + let mut record_to_add = *previous_record; + record_to_add.is_first = Boolean::allocated_constant(cs, true); // we use convension to be easier consistent with out of circuit part + record_to_add.timestamp = *first_encountered_timestamp; + result_queue.push(cs, record_to_add, add_to_the_queue); + + previous_item_is_trivial = is_trivial; + // may be update the timestamp + *first_encountered_timestamp = UInt32::conditionally_select( + cs, + same_hash, + &first_encountered_timestamp, + &sorted_item.timestamp, + ); + *previous_record = sorted_item; + *previous_packed_key = packed_key; + } + + // if this circuit is the last one the queues must be empty and grand products must be equal + let completed = original_queue.is_empty(cs); + let sorted_queue_is_empty = sorted_queue.is_empty(cs); + Boolean::enforce_equal(cs, &completed, &sorted_queue_is_empty); + + // finalization step - push the last one if necessary + { + let previous_is_non_trivial = previous_item_is_trivial.negated(cs); + let add_to_the_queue = Boolean::multi_and(cs, &[previous_is_non_trivial, completed]); + + let mut record_to_add = *previous_record; + record_to_add.is_first = Boolean::allocated_constant(cs, true); // we use convension to be easier consistent with out of circuit part + record_to_add.timestamp = *first_encountered_timestamp; + + result_queue.push(cs, record_to_add, add_to_the_queue); + } + + original_queue.enforce_consistency(cs); + sorted_queue.enforce_consistency(cs); + + (completed, lhs, rhs) +} + +fn concatenate_key>( + _cs: &mut CS, + key_tuple: (UInt32, UInt256), +) -> [UInt32; PACKED_KEY_LENGTH] { + // LE packing so comparison is subtraction + let (timestamp, key) = key_tuple; + [ + timestamp, + key.inner[0], + key.inner[1], + key.inner[2], + key.inner[3], + key.inner[4], + key.inner[5], + key.inner[6], + key.inner[7], + ] +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::ethereum_types::U256; + use boojum::algebraic_props::poseidon2_parameters::Poseidon2GoldilocksExternalMatrix; + use boojum::cs::implementations::reference_cs::CSDevelopmentAssembly; + use boojum::cs::traits::gate::GatePlacementStrategy; + use boojum::cs::CSGeometry; + use boojum::cs::*; + use boojum::field::goldilocks::GoldilocksField; + use boojum::gadgets::tables::*; + use boojum::gadgets::traits::allocatable::CSPlaceholder; + use boojum::gadgets::u256::UInt256; + use boojum::implementations::poseidon2::Poseidon2Goldilocks; + use boojum::worker::Worker; + type F = GoldilocksField; + type P = GoldilocksField; + + #[test] + fn test_sort_and_deduplicate_code_decommittments_inner() { + let geometry = CSGeometry { + num_columns_under_copy_permutation: 100, + num_witness_columns: 0, + num_constant_columns: 8, + max_allowed_constraint_degree: 4, + }; + + use boojum::cs::cs_builder::*; + + fn configure< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + let builder = builder.allow_lookup( + LookupParameters::UseSpecializedColumnsWithTableIdAsConstant { + width: 3, + num_repetitions: 8, + share_table_id: true, + }, + ); + let builder = ConstantsAllocatorGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = FmaGateInBaseFieldWithoutConstant::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ReductionGate::::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = BooleanConstraintGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<32>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = UIntXAddGate::<16>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = SelectionGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = ZeroCheckGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + false, + ); + let builder = DotProductGate::<4>::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let builder = MatrixMultiplicationGate::::configure_builder(builder,GatePlacementStrategy::UseGeneralPurposeColumns); + let builder = NopGate::configure_builder( + builder, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + + builder + } + + use boojum::config::DevCSConfig; + use boojum::cs::cs_builder_reference::CsReferenceImplementationBuilder; + + let builder_impl = + CsReferenceImplementationBuilder::::new(geometry, 1 << 26, 1 << 20); + use boojum::cs::cs_builder::new_builder; + let builder = new_builder::<_, F>(builder_impl); + + let builder = configure(builder); + let mut owned_cs = builder.build(()); + + // add tables + let table = create_xor8_table(); + owned_cs.add_lookup_table::(table); + + let cs = &mut owned_cs; + + let execute = Boolean::allocated_constant(cs, true); + let mut original_queue = DecommitQueue::::empty(cs); + let unsorted_input = witness_input_unsorted(cs); + for el in unsorted_input { + original_queue.push(cs, el, execute); + } + let mut sorted_queue = DecommitQueue::::empty(cs); + let sorted_input = witness_input_sorted(cs); + for el in sorted_input { + sorted_queue.push(cs, el, execute); + } + + let mut result_queue = DecommitQueue::empty(cs); + + let lhs = [Num::allocated_constant(cs, F::from_nonreduced_u64(1)); + DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS]; + let rhs = [Num::allocated_constant(cs, F::from_nonreduced_u64(1)); + DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS]; + let is_start = Boolean::allocated_constant(cs, true); + let round_function = Poseidon2Goldilocks; + let fs_challenges = crate::utils::produce_fs_challenges::< + F, + _, + Poseidon2Goldilocks, + FULL_SPONGE_QUEUE_STATE_WIDTH, + { MEMORY_QUERY_PACKED_WIDTH + 1 }, + DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS, + >( + cs, + original_queue.into_state().tail, + sorted_queue.into_state().tail, + &round_function, + ); + let limit = 16; + let mut previous_packed_key = [UInt32::allocated_constant(cs, 0); PACKED_KEY_LENGTH]; + let mut first_encountered_timestamp = UInt32::allocated_constant(cs, 0); + let mut previous_record = DecommitQuery::placeholder(cs); + sort_and_deduplicate_code_decommittments_inner( + cs, + &mut original_queue, + &mut sorted_queue, + &mut result_queue, + lhs, + rhs, + fs_challenges, + &mut previous_packed_key, + &mut first_encountered_timestamp, + &mut previous_record, + is_start, + limit, + ); + + cs.pad_and_shrink(); + let worker = Worker::new(); + let mut owned_cs = owned_cs.into_assembly(); + owned_cs.print_gate_stats(); + assert!(owned_cs.check_if_satisfied(&worker)); + } + fn witness_input_unsorted>(cs: &mut CS) -> Vec> { + let mut unsorted_querie = vec![]; + let bool_false = Boolean::allocated_constant(cs, false); + let bool_true = Boolean::allocated_constant(cs, true); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452334469539131717490596781220410444809589670111004622364436613658071035425", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 8), + is_first: bool_true, + timestamp: UInt32::allocated_constant(cs, 1), + }; + unsorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452319300877325313852488925888724764263521004047156906617735320131041551860", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2048), + is_first: bool_true, + timestamp: UInt32::allocated_constant(cs, 1205), + }; + unsorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452319300877325313852488925888724764263521004047156906617735320131041551860", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2048), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 1609), + }; + unsorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452319300877325313852488925888724764263521004047156906617735320131041551860", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2048), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 1969), + }; + unsorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452319300877325313852488925888724764263521004047156906617735320131041551860", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2048), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 2429), + }; + unsorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452319300877325313852488925888724764263521004047156906617735320131041551860", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2048), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 2901), + }; + unsorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452319300877325313852488925888724764263521004047156906617735320131041551860", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2048), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 3265), + }; + unsorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452319300877325313852488925888724764263521004047156906617735320131041551860", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2048), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 3597), + }; + unsorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452319300877325313852488925888724764263521004047156906617735320131041551860", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2048), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 4001), + }; + unsorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452319300877325313852488925888724764263521004047156906617735320131041551860", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2048), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 4389), + }; + unsorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452319300877325313852488925888724764263521004047156906617735320131041551860", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2048), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 4889), + }; + unsorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314302625333346664221779405237214670769280401891479637776384083169086090", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2128), + is_first: bool_true, + timestamp: UInt32::allocated_constant(cs, 5413), + }; + unsorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314303070458905393772003110276921984481582690891142221610001680774704050", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2136), + is_first: bool_true, + timestamp: UInt32::allocated_constant(cs, 6181), + }; + unsorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452315323292561252187007358802027294616051526905825659974295089200090160077", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2144), + is_first: bool_true, + timestamp: UInt32::allocated_constant(cs, 7689), + }; + unsorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314302625333346664221779405237214670769280401891479637776384083169086090", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2128), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 8333), + }; + unsorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314563023454543640061243127807783650961769624362936951212864970460788229", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2160), + is_first: bool_true, + timestamp: UInt32::allocated_constant(cs, 9281), + }; + unsorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314302625333346664221779405237214670769280401891479637776384083169086090", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2128), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 10337), + }; + unsorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314303070458905393772003110276921984481582690891142221610001680774704050", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2136), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 11169), + }; + unsorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452315323292561252187007358802027294616051526905825659974295089200090160077", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2144), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 13521), + }; + unsorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314302625333346664221779405237214670769280401891479637776384083169086090", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2128), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 14197), + }; + unsorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314563023454543640061243127807783650961769624362936951212864970460788229", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2160), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 15209), + }; + unsorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314302625333346664221779405237214670769280401891479637776384083169086090", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2128), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 16321), + }; + unsorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314303070458905393772003110276921984481582690891142221610001680774704050", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2136), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 17217), + }; + unsorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452315323292561252187007358802027294616051526905825659974295089200090160077", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2144), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 19561), + }; + unsorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314302625333346664221779405237214670769280401891479637776384083169086090", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2128), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 20269), + }; + unsorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314563023454543640061243127807783650961769624362936951212864970460788229", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2160), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 21345), + }; + unsorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314302625333346664221779405237214670769280401891479637776384083169086090", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2128), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 22457), + }; + unsorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314303070458905393772003110276921984481582690891142221610001680774704050", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2136), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 23417), + }; + unsorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452315323292561252187007358802027294616051526905825659974295089200090160077", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2144), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 26209), + }; + unsorted_querie.push(q); + + unsorted_querie + } + fn witness_input_sorted>(cs: &mut CS) -> Vec> { + let mut sorted_querie = vec![]; + let bool_false = Boolean::allocated_constant(cs, false); + let bool_true = Boolean::allocated_constant(cs, true); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452313746998214869734508634865817576060841700842481516984674100922521850987", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2368), + is_first: bool_true, + timestamp: UInt32::allocated_constant(cs, 40973), + }; + sorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452313746998214869734508634865817576060841700842481516984674100922521850987", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2368), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 41617), + }; + sorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452313746998214869734508634865817576060841700842481516984674100922521850987", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2368), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 42369), + }; + sorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314299079945159748026115793412643474177571247148724523427478208200944620", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2680), + is_first: bool_true, + timestamp: UInt32::allocated_constant(cs, 60885), + }; + sorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314302625333346664221779405237214670769280401891479637776384083169086090", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2128), + is_first: bool_true, + timestamp: UInt32::allocated_constant(cs, 5413), + }; + sorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314302625333346664221779405237214670769280401891479637776384083169086090", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2128), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 8333), + }; + sorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314302625333346664221779405237214670769280401891479637776384083169086090", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2128), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 10337), + }; + sorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314302625333346664221779405237214670769280401891479637776384083169086090", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2128), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 14197), + }; + sorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314302625333346664221779405237214670769280401891479637776384083169086090", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2128), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 16321), + }; + sorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314302625333346664221779405237214670769280401891479637776384083169086090", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2128), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 20269), + }; + sorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314302625333346664221779405237214670769280401891479637776384083169086090", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2128), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 22457), + }; + sorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314302625333346664221779405237214670769280401891479637776384083169086090", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2128), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 26949), + }; + sorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314302625333346664221779405237214670769280401891479637776384083169086090", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2128), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 31393), + }; + sorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314302625333346664221779405237214670769280401891479637776384083169086090", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2128), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 38757), + }; + sorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314302625333346664221779405237214670769280401891479637776384083169086090", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2128), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 53341), + }; + sorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314302625333346664221779405237214670769280401891479637776384083169086090", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2128), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 53865), + }; + sorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314302625333346664221779405237214670769280401891479637776384083169086090", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2128), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 54737), + }; + sorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314302625333346664221779405237214670769280401891479637776384083169086090", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2128), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 56061), + }; + sorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314302625333346664221779405237214670769280401891479637776384083169086090", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2128), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 57493), + }; + sorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314302625333346664221779405237214670769280401891479637776384083169086090", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2128), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 59957), + }; + sorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314303070458905393772003110276921984481582690891142221610001680774704050", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2136), + is_first: bool_true, + timestamp: UInt32::allocated_constant(cs, 6181), + }; + sorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314303070458905393772003110276921984481582690891142221610001680774704050", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2136), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 11169), + }; + sorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314303070458905393772003110276921984481582690891142221610001680774704050", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2136), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 17217), + }; + sorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314303070458905393772003110276921984481582690891142221610001680774704050", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2136), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 23417), + }; + sorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314303070458905393772003110276921984481582690891142221610001680774704050", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2136), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 37357), + }; + sorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314563023454543640061243127807783650961769624362936951212864970460788229", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2160), + is_first: bool_true, + timestamp: UInt32::allocated_constant(cs, 9281), + }; + sorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314563023454543640061243127807783650961769624362936951212864970460788229", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2160), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 15209), + }; + sorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314563023454543640061243127807783650961769624362936951212864970460788229", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2160), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 21345), + }; + sorted_querie.push(q); + + let q = DecommitQuery:: { + code_hash: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452314563023454543640061243127807783650961769624362936951212864970460788229", + ) + .unwrap(), + ), + page: UInt32::allocated_constant(cs, 2160), + is_first: bool_false, + timestamp: UInt32::allocated_constant(cs, 28089), + }; + sorted_querie.push(q); + + sorted_querie + } +} diff --git a/crates/zkevm_circuits/src/storage_application/input.rs b/crates/zkevm_circuits/src/storage_application/input.rs new file mode 100644 index 0000000..5eb45bc --- /dev/null +++ b/crates/zkevm_circuits/src/storage_application/input.rs @@ -0,0 +1,121 @@ +use crate::base_structures::{ + log_query::{LogQuery, LOG_QUERY_PACKED_WIDTH}, + vm_state::*, +}; +use boojum::cs::{traits::cs::ConstraintSystem, Variable}; +use boojum::field::SmallField; +use boojum::gadgets::keccak256; +use boojum::gadgets::traits::auxiliary::PrettyComparison; +use boojum::gadgets::u32::UInt32; +use boojum::gadgets::u8::UInt8; +use boojum::gadgets::{ + boolean::Boolean, + queue::*, + traits::{ + allocatable::*, encodable::CircuitVarLengthEncodable, selectable::Selectable, + witnessable::WitnessHookable, + }, +}; +use boojum::serde_utils::BigArraySerde; +use cs_derive::*; +use derivative::*; +use std::collections::VecDeque; + +pub const STORAGE_DEPTH: usize = 256; + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +#[DerivePrettyComparison("true")] +pub struct StorageApplicationFSMInputOutput { + pub current_root_hash: [UInt8; 32], + pub next_enumeration_counter: [UInt32; 2], + pub current_storage_application_log_state: QueueState, + pub current_diffs_keccak_accumulator_state: + [[[UInt8; keccak256::BYTES_PER_WORD]; keccak256::LANE_WIDTH]; keccak256::LANE_WIDTH], +} + +impl CSPlaceholder for StorageApplicationFSMInputOutput { + fn placeholder>(cs: &mut CS) -> Self { + Self { + current_root_hash: [UInt8::::placeholder(cs); 32], + next_enumeration_counter: [UInt32::::placeholder(cs); 2], + current_storage_application_log_state: QueueState::::placeholder( + cs, + ), + current_diffs_keccak_accumulator_state: [[[UInt8::::placeholder(cs); + keccak256::BYTES_PER_WORD]; + keccak256::LANE_WIDTH]; + keccak256::LANE_WIDTH], + } + } +} + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +#[DerivePrettyComparison("true")] +pub struct StorageApplicationInputData { + pub shard: UInt8, + pub initial_root_hash: [UInt8; 32], + pub initial_next_enumeration_counter: [UInt32; 2], + pub storage_application_log_state: QueueState, +} + +impl CSPlaceholder for StorageApplicationInputData { + fn placeholder>(cs: &mut CS) -> Self { + Self { + shard: UInt8::::placeholder(cs), + initial_root_hash: [UInt8::::placeholder(cs); 32], + initial_next_enumeration_counter: [UInt32::::placeholder(cs); 2], + storage_application_log_state: QueueState::::placeholder(cs), + } + } +} + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +#[DerivePrettyComparison("true")] +pub struct StorageApplicationOutputData { + pub new_root_hash: [UInt8; 32], + pub new_next_enumeration_counter: [UInt32; 2], + pub state_diffs_keccak256_hash: [UInt8; 32], +} + +impl CSPlaceholder for StorageApplicationOutputData { + fn placeholder>(cs: &mut CS) -> Self { + Self { + new_root_hash: [UInt8::::placeholder(cs); 32], + new_next_enumeration_counter: [UInt32::::placeholder(cs); 2], + state_diffs_keccak256_hash: [UInt8::::placeholder(cs); 32], + } + } +} + +pub type StorageApplicationInputOutput = crate::fsm_input_output::ClosedFormInput< + F, + StorageApplicationFSMInputOutput, + StorageApplicationInputData, + StorageApplicationOutputData, +>; + +pub type StorageApplicationInputOutputWitness = crate::fsm_input_output::ClosedFormInputWitness< + F, + StorageApplicationFSMInputOutput, + StorageApplicationInputData, + StorageApplicationOutputData, +>; + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Debug, Default)] +#[serde(bound = "")] +pub struct StorageApplicationCircuitInstanceWitness { + pub closed_form_input: StorageApplicationInputOutputWitness, + // #[serde(bound( + // serialize = "CircuitQueueRawWitness, 4, LOG_QUERY_PACKED_WIDTH>: serde::Serialize" + // ))] + // #[serde(bound( + // deserialize = "CircuitQueueRawWitness, 4, LOG_QUERY_PACKED_WIDTH>: serde::de::DeserializeOwned" + // ))] + pub storage_queue_witness: CircuitQueueRawWitness, 4, LOG_QUERY_PACKED_WIDTH>, + pub merkle_paths: VecDeque>, + pub leaf_indexes_for_reads: VecDeque, +} diff --git a/crates/zkevm_circuits/src/storage_application/mod.rs b/crates/zkevm_circuits/src/storage_application/mod.rs new file mode 100644 index 0000000..950930f --- /dev/null +++ b/crates/zkevm_circuits/src/storage_application/mod.rs @@ -0,0 +1,720 @@ +use std::collections::VecDeque; +use std::mem::MaybeUninit; + +use crate::base_structures::log_query::LogQuery; +use crate::base_structures::state_diff_record::StateDiffRecord; +use crate::demux_log_queue::StorageLogQueue; +use crate::ethereum_types::U256; +use crate::fsm_input_output::circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH; +use boojum::algebraic_props::round_function::AlgebraicRoundFunction; +use boojum::config::*; +use boojum::cs::traits::cs::{ConstraintSystem, DstBuffer}; +use boojum::cs::{Place, Variable}; +use boojum::field::SmallField; +use boojum::gadgets::blake2s::blake2s; +use boojum::gadgets::boolean::Boolean; +use boojum::gadgets::keccak256; +use boojum::gadgets::num::Num; +use boojum::gadgets::queue::CircuitQueueWitness; +use boojum::gadgets::queue::QueueState; +use boojum::gadgets::traits::allocatable::{CSAllocatable, CSAllocatableExt, CSPlaceholder}; +use boojum::gadgets::traits::castable::WitnessCastable; +use boojum::gadgets::traits::round_function::CircuitRoundFunction; +use boojum::gadgets::traits::selectable::Selectable; +use boojum::gadgets::u256::UInt256; +use boojum::gadgets::u32::UInt32; +use boojum::gadgets::u8::UInt8; +use std::sync::{Arc, RwLock}; +use zkevm_opcode_defs::system_params::STORAGE_AUX_BYTE; + +use super::*; + +pub mod input; +use self::input::*; + +fn u64_as_u32x2_conditionally_increment>( + cs: &mut CS, + input: &[UInt32; 2], + should_increment: &Boolean, +) -> [UInt32; 2] { + let one_u32 = UInt32::allocated_constant(cs, 1u32); + let (incremented_low, carry) = input[0].overflowing_add(cs, one_u32); + let carry_as_u32 = unsafe { UInt32::from_variable_unchecked(carry.get_variable()) }; + let incremented_high = input[1].add_no_overflow(cs, carry_as_u32); + + let selected = Selectable::conditionally_select( + cs, + *should_increment, + &[incremented_low, incremented_high], + input, + ); + + selected +} + +pub(crate) fn keccak256_conditionally_absorb_and_run_permutation< + F: SmallField, + CS: ConstraintSystem, +>( + cs: &mut CS, + condition: Boolean, + state: &mut [[[Variable; keccak256::BYTES_PER_WORD]; keccak256::LANE_WIDTH]; + keccak256::LANE_WIDTH], + block: &[Variable; keccak256::KECCAK_RATE_BYTES], +) { + let mut new_state = *state; + for i in 0..keccak256::LANE_WIDTH { + for j in 0..keccak256::LANE_WIDTH { + if i + keccak256::LANE_WIDTH * j + < (keccak256::KECCAK_RATE_BYTES / keccak256::BYTES_PER_WORD) + { + let tmp = block + .array_chunks::<{ keccak256::BYTES_PER_WORD }>() + .skip(i + keccak256::LANE_WIDTH * j) + .next() + .unwrap(); + use boojum::gadgets::blake2s::mixing_function::xor_many; + new_state[i][j] = xor_many(cs, &new_state[i][j], tmp); + } + } + } + use boojum::gadgets::keccak256::round_function::keccak_256_round_function; + keccak_256_round_function(cs, &mut new_state); + + // if we do not write then discard + for (a, b) in state.iter_mut().zip(new_state.iter()) { + for (a, b) in a.iter_mut().zip(b.iter()) { + let new = b.map(|el| Num::from_variable(el)); + let old = a.map(|el| Num::from_variable(el)); + let selected = Num::parallel_select(cs, condition, &new, &old); + *a = selected.map(|el| el.get_variable()); + } + } +} + +pub struct ConditionalWitnessAllocator> { + pub witness_source: Arc>>, +} + +impl> ConditionalWitnessAllocator +where + [(); EL::INTERNAL_STRUCT_LEN]:, + [(); EL::INTERNAL_STRUCT_LEN + 1]:, +{ + pub fn print_debug_info(&self) { + if let Ok(read_lock) = self.witness_source.read() { + let inner = &*read_lock; + dbg!(inner.len()); + } + } + + pub fn conditionally_allocate_with_default< + CS: ConstraintSystem, + DEF: FnOnce() -> EL::Witness + 'static + Send + Sync, + >( + &self, + cs: &mut CS, + should_allocate: Boolean, + default_values_closure: DEF, + ) -> EL { + let el = EL::allocate_without_value(cs); + + if ::WitnessConfig::EVALUATE_WITNESS { + let dependencies = [should_allocate.get_variable().into()]; + let witness = self.witness_source.clone(); + let value_fn = move |inputs: [F; 1]| { + let should_allocate = >::cast_from_source(inputs[0]); + + let witness = if should_allocate == true { + let mut guard = witness.write().expect("not poisoned"); + let witness_element = guard.pop_front().expect("not empty witness"); + drop(guard); + + witness_element + } else { + let witness_element = (default_values_closure)(); + + witness_element + }; + + let mut result = [F::ZERO; EL::INTERNAL_STRUCT_LEN]; + let mut dst = DstBuffer::MutSlice(&mut result, 0); + EL::set_internal_variables_values(witness, &mut dst); + drop(dst); + + result + }; + + let outputs = Place::from_variables(el.flatten_as_variables()); + + cs.set_values_with_dependencies(&dependencies, &outputs, value_fn); + } + + el + } + + pub fn conditionally_allocate_with_default_biased< + CS: ConstraintSystem, + DEF: FnOnce() -> EL::Witness + 'static + Send + Sync, + >( + &self, + cs: &mut CS, + should_allocate: Boolean, + bias: Variable, // any variable that has to be resolved BEFORE executing witness query + default_values_closure: DEF, + ) -> EL { + let el = EL::allocate_without_value(cs); + + if ::WitnessConfig::EVALUATE_WITNESS { + let dependencies = [should_allocate.get_variable().into(), bias.into()]; + let witness = self.witness_source.clone(); + let value_fn = move |inputs: [F; 2]| { + let should_allocate = >::cast_from_source(inputs[0]); + + let witness = if should_allocate == true { + let mut guard = witness.write().expect("not poisoned"); + let witness_element = guard.pop_front().expect("not empty witness"); + drop(guard); + + witness_element + } else { + let witness_element = (default_values_closure)(); + + witness_element + }; + + let mut result = [F::ZERO; EL::INTERNAL_STRUCT_LEN]; + let mut dst = DstBuffer::MutSlice(&mut result, 0); + EL::set_internal_variables_values(witness, &mut dst); + drop(dst); + + result + }; + + let outputs = Place::from_variables(el.flatten_as_variables()); + + cs.set_values_with_dependencies(&dependencies, &outputs, value_fn); + } + + el + } + + pub fn conditionally_allocate>( + &self, + cs: &mut CS, + should_allocate: Boolean, + ) -> EL + where + EL::Witness: Default, + { + self.conditionally_allocate_with_default(cs, should_allocate, || { + std::default::Default::default() + }) + } + + pub fn conditionally_allocate_biased>( + &self, + cs: &mut CS, + should_allocate: Boolean, + bias: Variable, // any variable that has to be resolved BEFORE executing witness query + ) -> EL + where + EL::Witness: Default, + { + self.conditionally_allocate_with_default_biased(cs, should_allocate, bias, || { + std::default::Default::default() + }) + } +} + +fn allocate_enumeration_index_from_witness>( + cs: &mut CS, + should_allocate: Boolean, + witness_source: Arc>>, +) -> [UInt32; 2] { + let flattened: [_; 2] = std::array::from_fn(|_| UInt32::allocate_without_value(cs)); + + if ::WitnessConfig::EVALUATE_WITNESS { + let dependencies = [should_allocate.get_variable().into()]; + let witness = witness_source.clone(); + let value_fn = move |inputs: [F; 1]| { + let should_allocate = >::cast_from_source(inputs[0]); + + let (low, high) = if should_allocate == true { + let mut guard = witness.write().expect("not poisoned"); + let witness_element = guard.pop_front().expect("not empty witness"); + drop(guard); + + witness_element + } else { + (0, 0) + }; + + [ + F::from_u64_with_reduction(low as u64), + F::from_u64_with_reduction(high as u64), + ] + }; + + let outputs = Place::from_variables(flattened.map(|el| el.get_variable())); + + cs.set_values_with_dependencies(&dependencies, &outputs, value_fn); + } + + flattened +} + +pub fn storage_applicator_entry_point< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, +>( + cs: &mut CS, + witness: StorageApplicationCircuitInstanceWitness, + round_function: &R, + params: usize, +) -> [Num; INPUT_OUTPUT_COMMITMENT_LENGTH] +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN + 1]:, +{ + let limit = params; + + assert!(limit <= u32::MAX as usize); + + let StorageApplicationCircuitInstanceWitness { + closed_form_input, + storage_queue_witness, + merkle_paths, + leaf_indexes_for_reads, + } = witness; + + let leaf_indexes_for_reads: VecDeque<_> = leaf_indexes_for_reads + .into_iter() + .map(|el| (el as u32, (el >> 32) as u32)) + .collect(); + + let merkle_paths: VecDeque = merkle_paths + .into_iter() + .flatten() + .map(|el| U256::from_little_endian(&el)) + .collect(); + + let mut structured_input = + StorageApplicationInputOutput::alloc_ignoring_outputs(cs, closed_form_input.clone()); + let start_flag = structured_input.start_flag; + + let mut current_root_hash = UInt8::::parallel_select( + cs, + start_flag, + &structured_input.observable_input.initial_root_hash, + &structured_input.hidden_fsm_input.current_root_hash, + ); + let shard = structured_input.observable_input.shard; + + let mut current_next_enumeration_index = <[UInt32; 2]>::conditionally_select( + cs, + start_flag, + &structured_input + .observable_input + .initial_next_enumeration_counter, + &structured_input.hidden_fsm_input.next_enumeration_counter, + ); + + let storage_queue_state_from_input = structured_input + .observable_input + .storage_application_log_state; + + // it must be trivial + storage_queue_state_from_input.enforce_trivial_head(cs); + + let storage_queue_state_from_fsm = structured_input + .hidden_fsm_input + .current_storage_application_log_state; + + let storage_accesses_queue_state = QueueState::conditionally_select( + cs, + start_flag, + &storage_queue_state_from_input, + &storage_queue_state_from_fsm, + ); + + let mut storage_accesses_queue = + StorageLogQueue::::from_state(cs, storage_accesses_queue_state); + let storage_queue_witness = CircuitQueueWitness::from_inner_witness(storage_queue_witness); + storage_accesses_queue.witness = Arc::new(storage_queue_witness); + + let zero_u8: UInt8 = UInt8::zero(cs); + + let mut diffs_keccak_accumulator_state = + [[[zero_u8; keccak256::BYTES_PER_WORD]; keccak256::LANE_WIDTH]; keccak256::LANE_WIDTH]; + let keccak_sponge_state_from_fsm = structured_input + .hidden_fsm_input + .current_diffs_keccak_accumulator_state; + + for (a, b) in diffs_keccak_accumulator_state + .iter_mut() + .zip(keccak_sponge_state_from_fsm.iter()) + { + for (a, b) in a.iter_mut().zip(b.iter()) { + *a = UInt8::parallel_select(cs, start_flag, &*a, b); + } + } + + let mut diffs_keccak_accumulator_state = + diffs_keccak_accumulator_state.map(|el| el.map(|el| el.map(|el| el.get_variable()))); + + let boolean_false = Boolean::allocated_constant(cs, false); + let boolean_true = Boolean::allocated_constant(cs, true); + let zero_u32 = UInt32::allocated_constant(cs, 0u32); + + let storage_aux_byte = UInt8::allocated_constant(cs, STORAGE_AUX_BYTE); + let mut write_stage_in_progress = boolean_false; + let mut path_key = [zero_u8; 32]; + let mut completed = storage_accesses_queue.is_empty(cs); + let mut merkle_path_witness = Box::new([[zero_u8; 32]; STORAGE_DEPTH]); + let mut current_in_progress_enumeration_index = [zero_u32; 2]; + let mut saved_written_value = [zero_u8; 32]; + + let mut state_diff_data = StateDiffRecord { + address: [zero_u8; 20], + key: [zero_u8; 32], + derived_key: [zero_u8; 32], + enumeration_index: [zero_u8; 8], + initial_value: [zero_u8; 32], + final_value: [zero_u8; 32], + }; + + let read_index_witness_allocator = Arc::new(RwLock::new(leaf_indexes_for_reads)); + let merkle_path_witness_allocator = ConditionalWitnessAllocator::> { + witness_source: Arc::new(RwLock::new(merkle_paths)), + }; + + for cycle in 0..limit { + let is_first = cycle == 0; + let is_last = cycle == limit - 1; + + // if this is the last executing cycle - we do not start the parsing of the new element: + // instead we either complete the second iter of processing of the last element or simply do nothing + let (should_compare_roots, parse_next_queue_elem) = if is_last == false { + let should_compare_roots = completed.negated(cs); + let read_stage_in_progress = write_stage_in_progress.negated(cs); + let parse_next_queue_elem = should_compare_roots.and(cs, read_stage_in_progress); + + (should_compare_roots, parse_next_queue_elem) + } else { + // last iteration can never pop, and is never "read" + + (boolean_false, boolean_false) + }; + + let (storage_log, _) = storage_accesses_queue.pop_front(cs, parse_next_queue_elem); + + let LogQuery { + address, + key, + read_value, + written_value, + rw_flag, + shard_id, + .. + } = storage_log; + + let shard_is_valid = UInt8::equals(cs, &shard_id, &shard); + let aux_byte_is_valid = UInt8::equals(cs, &storage_log.aux_byte, &storage_aux_byte); + let is_valid = Boolean::multi_and(cs, &[shard_is_valid, aux_byte_is_valid]); + is_valid.conditionally_enforce_true(cs, parse_next_queue_elem); + + // we can decompose everythin right away + let address_bytes = address.to_be_bytes(cs); + let key_bytes = key.to_be_bytes(cs); + + let mut bytes_for_key_derivation = [zero_u8; 64]; + bytes_for_key_derivation[12..32].copy_from_slice(&address_bytes); + bytes_for_key_derivation[32..64].copy_from_slice(&key_bytes); + + let derived_key = blake2s(cs, &bytes_for_key_derivation); + + // update current key + path_key = UInt8::parallel_select(cs, parse_next_queue_elem, &derived_key, &path_key); + let mut path_selectors = [boolean_false; STORAGE_DEPTH]; + // get path bits + for (dst, src) in path_selectors.array_chunks_mut::<8>().zip(path_key.iter()) { + let bits: [_; 8] = Num::from_variable(src.get_variable()).spread_into_bits(cs); + *dst = bits; + } + + // determine whether we need to increment enumeration index + let read_index = allocate_enumeration_index_from_witness( + cs, + parse_next_queue_elem, + read_index_witness_allocator.clone(), + ); + // update index over which we work + current_in_progress_enumeration_index = <[UInt32; 2]>::conditionally_select( + cs, + parse_next_queue_elem, + &read_index, + ¤t_in_progress_enumeration_index, + ); + + let idx_parts_are_zeroes = current_in_progress_enumeration_index.map(|el| el.is_zero(cs)); + let current_idx_is_zero = Boolean::multi_and(cs, &idx_parts_are_zeroes); + let should_assign_fresh_idx = + Boolean::multi_and(cs, &[write_stage_in_progress, current_idx_is_zero]); + + // use next enumeration index + current_in_progress_enumeration_index = <[UInt32; 2]>::conditionally_select( + cs, + should_assign_fresh_idx, + ¤t_next_enumeration_index, + ¤t_in_progress_enumeration_index, + ); + current_next_enumeration_index = u64_as_u32x2_conditionally_increment( + cs, + ¤t_next_enumeration_index, + &should_assign_fresh_idx, + ); + + // index is done, now we need merkle path + let mut new_merkle_path_witness = Vec::with_capacity(STORAGE_DEPTH); + let mut bias_variable = parse_next_queue_elem.get_variable(); + for _ in 0..STORAGE_DEPTH { + let wit = merkle_path_witness_allocator.conditionally_allocate_biased( + cs, + parse_next_queue_elem, + bias_variable, + ); + bias_variable = wit.inner[0].get_variable(); + new_merkle_path_witness.push(wit); + } + + // if we read then we save and use it for write too + for (dst, src) in merkle_path_witness + .iter_mut() + .zip(new_merkle_path_witness.iter()) + { + let src_bytes = src.to_le_bytes(cs); // NOP + *dst = UInt8::parallel_select(cs, parse_next_queue_elem, &src_bytes, &*dst); + } + + let read_value_bytes = read_value.to_be_bytes(cs); + let written_value_bytes = written_value.to_be_bytes(cs); + + let mut leaf_value_for_this_stage = read_value_bytes; + // if we just processed a value from the queue then save it + saved_written_value = UInt8::parallel_select( + cs, + parse_next_queue_elem, + &written_value_bytes, + &saved_written_value, + ); + // if we have write stage in progress then use saved value as the one we will use for path + leaf_value_for_this_stage = UInt8::parallel_select( + cs, + write_stage_in_progress, + &saved_written_value, + &leaf_value_for_this_stage, + ); + + // we need to serialize leaf index as 8 bytes + + let leaf_index_low_be = current_in_progress_enumeration_index[0].to_be_bytes(cs); + let leaf_index_high_be = current_in_progress_enumeration_index[1].to_be_bytes(cs); + + let mut leaf_index_bytes = [zero_u8; 8]; + leaf_index_bytes[0..4].copy_from_slice(&leaf_index_high_be); + leaf_index_bytes[4..8].copy_from_slice(&leaf_index_low_be); + + // now we have everything to update state diff data + { + state_diff_data.address = UInt8::parallel_select( + cs, + parse_next_queue_elem, + &address_bytes, + &state_diff_data.address, + ); + state_diff_data.key = + UInt8::parallel_select(cs, parse_next_queue_elem, &key_bytes, &state_diff_data.key); + state_diff_data.derived_key = UInt8::parallel_select( + cs, + parse_next_queue_elem, + &derived_key, + &state_diff_data.derived_key, + ); + // NOTE: we need READ index, before updating + state_diff_data.enumeration_index = UInt8::parallel_select( + cs, + parse_next_queue_elem, + &leaf_index_bytes, + &state_diff_data.enumeration_index, + ); + state_diff_data.initial_value = UInt8::parallel_select( + cs, + parse_next_queue_elem, + &read_value_bytes, + &state_diff_data.initial_value, + ); + state_diff_data.final_value = UInt8::parallel_select( + cs, + parse_next_queue_elem, + &written_value_bytes, + &state_diff_data.final_value, + ); + } + + let mut leaf_bytes = [zero_u8; 32 + 8]; + leaf_bytes[0..8].copy_from_slice(&leaf_index_bytes); + leaf_bytes[8..40].copy_from_slice(&leaf_value_for_this_stage); + + let mut current_hash = blake2s(cs, &leaf_bytes); + + for (path_bit, path_witness) in path_selectors + .into_iter() + .zip(merkle_path_witness.into_iter()) + { + let left = UInt8::parallel_select(cs, path_bit, &path_witness, ¤t_hash); + let right = UInt8::parallel_select(cs, path_bit, ¤t_hash, &path_witness); + let mut input = [zero_u8; 64]; + input[0..32].copy_from_slice(&left); + input[32..64].copy_from_slice(&right); + + current_hash = blake2s(cs, &input); + } + + // in case of read: merkle_root == computed_merkle_root == new_merkle_root + // new_merkle_root = select(if is_write: then new_merkle_root else computed_merkle_root); + // so we first compute merkle_root - either the old one or the selected one and then enforce equality + + // update if we write + current_root_hash = UInt8::parallel_select( + cs, + write_stage_in_progress, + ¤t_hash, + ¤t_root_hash, + ); + // otherwise enforce equality + for (a, b) in current_root_hash.iter().zip(current_hash.iter()) { + Num::conditionally_enforce_equal( + cs, + should_compare_roots, + &Num::from_variable(a.get_variable()), + &Num::from_variable(b.get_variable()), + ); + } + + // update our accumulator + + // we use keccak256 here because it's same table structure + use crate::base_structures::state_diff_record::NUM_KECCAK256_ROUNDS_PER_RECORD_ACCUMULATION; + let mut extended_state_diff_encoding = + [zero_u8; keccak256::KECCAK_RATE_BYTES * NUM_KECCAK256_ROUNDS_PER_RECORD_ACCUMULATION]; + let packed_encoding = state_diff_data.encode(cs); + extended_state_diff_encoding[0..packed_encoding.len()].copy_from_slice(&packed_encoding); + let extended_state_diff_encoding = extended_state_diff_encoding.map(|el| el.get_variable()); + // absorb and run permutation + + // we do not write here anyway + if is_first == false { + for block in + extended_state_diff_encoding.array_chunks::<{ keccak256::KECCAK_RATE_BYTES }>() + { + keccak256_conditionally_absorb_and_run_permutation( + cs, + write_stage_in_progress, + &mut diffs_keccak_accumulator_state, + block, + ); + } + } + + // toggle control flags + let input_queue_is_empty = storage_accesses_queue.is_empty(cs); + // cur elem is processed only in the case second iter in progress or rw_flag is false; + let current_element_is_read = rw_flag.negated(cs); + let cur_elem_was_processed = + Boolean::multi_or(cs, &[write_stage_in_progress, current_element_is_read]); + let completed_now = Boolean::multi_and(cs, &[input_queue_is_empty, cur_elem_was_processed]); + completed = Boolean::multi_or(cs, &[completed, completed_now]); + + write_stage_in_progress = Boolean::multi_and(cs, &[parse_next_queue_elem, rw_flag]); + } + + storage_accesses_queue.enforce_consistency(cs); + + structured_input.completion_flag = completed.clone(); + let storage_queue_state = storage_accesses_queue.into_state(); + + let current_diffs_keccak_accumulator_state_for_fsm = unsafe { + diffs_keccak_accumulator_state + .map(|el| el.map(|el| el.map(|el| UInt8::from_variable_unchecked(el)))) + }; + + let fsm_output = StorageApplicationFSMInputOutput { + current_root_hash: current_root_hash, + next_enumeration_counter: current_next_enumeration_index, + current_storage_application_log_state: storage_queue_state.clone(), + current_diffs_keccak_accumulator_state: current_diffs_keccak_accumulator_state_for_fsm, + }; + structured_input.hidden_fsm_output = fsm_output; + + // we need to run padding and one more permutation for final output + let zero_var = zero_u8.get_variable(); + let mut padding_block = [zero_var; keccak256::KECCAK_RATE_BYTES]; + use boojum::cs::gates::ConstantAllocatableCS; + padding_block[0] = cs.allocate_constant(F::from_u64_unchecked(0x01 as u64)); + padding_block[135] = cs.allocate_constant(F::from_u64_unchecked(0x80 as u64)); + keccak256_conditionally_absorb_and_run_permutation( + cs, + boolean_true, + &mut diffs_keccak_accumulator_state, + &padding_block, + ); + + // squeeze + let mut result = [MaybeUninit::>::uninit(); keccak256::KECCAK256_DIGEST_SIZE]; + for (i, dst) in result.array_chunks_mut::<8>().enumerate() { + for (dst, src) in dst + .iter_mut() + .zip(diffs_keccak_accumulator_state[i][0].iter()) + { + let tmp = unsafe { UInt8::from_variable_unchecked(*src) }; + dst.write(tmp); + } + } + + let state_diffs_keccak256_hash = unsafe { result.map(|el| el.assume_init()) }; + + let observable_output = StorageApplicationOutputData { + new_root_hash: current_root_hash, + new_next_enumeration_counter: current_next_enumeration_index, + state_diffs_keccak256_hash: state_diffs_keccak256_hash, + }; + + let empty_observable_output = StorageApplicationOutputData::placeholder(cs); + let observable_output = StorageApplicationOutputData::conditionally_select( + cs, + structured_input.completion_flag, + &observable_output, + &empty_observable_output, + ); + structured_input.observable_output = observable_output; + + // self-check + structured_input.hook_compare_witness(cs, &closed_form_input); + + use crate::fsm_input_output::commit_variable_length_encodable_item; + use crate::fsm_input_output::ClosedFormInputCompactForm; + use boojum::cs::gates::PublicInputGate; + + let compact_form = + ClosedFormInputCompactForm::from_full_form(cs, &structured_input, round_function); + let input_commitment = commit_variable_length_encodable_item(cs, &compact_form, round_function); + for el in input_commitment.iter() { + let gate = PublicInputGate::new(el.get_variable()); + gate.add_to_cs(cs); + } + + input_commitment +} diff --git a/crates/zkevm_circuits/src/storage_validity_by_grand_product/input.rs b/crates/zkevm_circuits/src/storage_validity_by_grand_product/input.rs new file mode 100644 index 0000000..84ee713 --- /dev/null +++ b/crates/zkevm_circuits/src/storage_validity_by_grand_product/input.rs @@ -0,0 +1,136 @@ +use crate::base_structures::{ + log_query::{LogQuery, LOG_QUERY_PACKED_WIDTH}, + vm_state::*, +}; +use crate::DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS; +use boojum::cs::{traits::cs::ConstraintSystem, Variable}; +use boojum::field::SmallField; +use boojum::gadgets::traits::auxiliary::PrettyComparison; +use boojum::{ + gadgets::{ + boolean::Boolean, + num::*, + queue::*, + traits::{ + allocatable::*, encodable::CircuitVarLengthEncodable, selectable::Selectable, + witnessable::WitnessHookable, + }, + u160::*, + u256::*, + u32::*, + u8::*, + }, + serde_utils::BigArraySerde, +}; +use cs_derive::*; +use derivative::*; + +pub const PACKED_KEY_LENGTH: usize = 5 + 8; + +use super::TimestampedStorageLogRecord; + +// FSM + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +#[DerivePrettyComparison("true")] +pub struct StorageDeduplicatorFSMInputOutput { + pub lhs_accumulator: [Num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + pub rhs_accumulator: [Num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + pub current_unsorted_queue_state: QueueState, + pub current_intermediate_sorted_queue_state: QueueState, + pub current_final_sorted_queue_state: QueueState, + pub cycle_idx: UInt32, + pub previous_packed_key: [UInt32; PACKED_KEY_LENGTH], + pub previous_key: UInt256, + pub previous_address: UInt160, + pub previous_timestamp: UInt32, + pub this_cell_has_explicit_read_and_rollback_depth_zero: Boolean, + pub this_cell_base_value: UInt256, + pub this_cell_current_value: UInt256, + pub this_cell_current_depth: UInt32, +} + +impl CSPlaceholder for StorageDeduplicatorFSMInputOutput { + fn placeholder>(cs: &mut CS) -> Self { + let zero_num = Num::::zero(cs); + let zero_u32 = UInt32::zero(cs); + let zero_address = UInt160::zero(cs); + let zero_u256 = UInt256::zero(cs); + let boolean_false = Boolean::allocated_constant(cs, false); + + Self { + lhs_accumulator: [zero_num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + rhs_accumulator: [zero_num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + current_unsorted_queue_state: QueueState::::placeholder(cs), + current_intermediate_sorted_queue_state: + QueueState::::placeholder(cs), + current_final_sorted_queue_state: QueueState::::placeholder(cs), + cycle_idx: zero_u32, + previous_packed_key: [zero_u32; PACKED_KEY_LENGTH], + previous_key: zero_u256, + previous_address: zero_address, + previous_timestamp: zero_u32, + this_cell_has_explicit_read_and_rollback_depth_zero: boolean_false, + this_cell_base_value: zero_u256, + this_cell_current_value: zero_u256, + this_cell_current_depth: zero_u32, + } + } +} + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Debug)] +pub struct StorageDeduplicatorInputData { + pub shard_id_to_process: UInt8, + pub unsorted_log_queue_state: QueueState, + pub intermediate_sorted_queue_state: QueueState, +} + +impl CSPlaceholder for StorageDeduplicatorInputData { + fn placeholder>(cs: &mut CS) -> Self { + Self { + shard_id_to_process: UInt8::placeholder(cs), + unsorted_log_queue_state: QueueState::::placeholder(cs), + intermediate_sorted_queue_state: QueueState::::placeholder(cs), + } + } +} + +#[derive(Derivative, CSAllocatable, CSSelectable, CSVarLengthEncodable, WitnessHookable)] +#[derivative(Clone, Copy, Debug)] +#[DerivePrettyComparison("true")] +pub struct StorageDeduplicatorOutputData { + pub final_sorted_queue_state: QueueState, +} + +impl CSPlaceholder for StorageDeduplicatorOutputData { + fn placeholder>(cs: &mut CS) -> Self { + Self { + final_sorted_queue_state: QueueState::::placeholder(cs), + } + } +} + +pub type StorageDeduplicatorInputOutput = crate::fsm_input_output::ClosedFormInput< + F, + StorageDeduplicatorFSMInputOutput, + StorageDeduplicatorInputData, + StorageDeduplicatorOutputData, +>; +pub type StorageDeduplicatorInputOutputWitness = crate::fsm_input_output::ClosedFormInputWitness< + F, + StorageDeduplicatorFSMInputOutput, + StorageDeduplicatorInputData, + StorageDeduplicatorOutputData, +>; + +#[derive(Derivative, serde::Serialize, serde::Deserialize)] +#[derivative(Clone, Debug, Default)] +#[serde(bound = "")] +pub struct StorageDeduplicatorInstanceWitness { + pub closed_form_input: StorageDeduplicatorInputOutputWitness, + pub unsorted_queue_witness: CircuitQueueRawWitness, 4, LOG_QUERY_PACKED_WIDTH>, + pub intermediate_sorted_queue_witness: + CircuitQueueRawWitness, 4, LOG_QUERY_PACKED_WIDTH>, +} diff --git a/crates/zkevm_circuits/src/storage_validity_by_grand_product/mod.rs b/crates/zkevm_circuits/src/storage_validity_by_grand_product/mod.rs new file mode 100644 index 0000000..356c481 --- /dev/null +++ b/crates/zkevm_circuits/src/storage_validity_by_grand_product/mod.rs @@ -0,0 +1,1133 @@ +use super::*; + +pub mod input; +#[cfg(test)] +mod test_input; + +use crate::base_structures::log_query::log_query_witness_from_values; +use crate::fsm_input_output::ClosedFormInputCompactForm; + +use crate::base_structures::{ + log_query::{LogQuery, LOG_QUERY_PACKED_WIDTH}, + vm_state::*, +}; +use boojum::algebraic_props::round_function::AlgebraicRoundFunction; +use boojum::cs::traits::cs::DstBuffer; +use boojum::cs::{gates::*, traits::cs::ConstraintSystem, Variable}; +use boojum::field::SmallField; +use boojum::gadgets::traits::castable::WitnessCastable; +use boojum::gadgets::traits::round_function::CircuitRoundFunction; +use boojum::gadgets::{ + boolean::Boolean, + num::Num, + queue::*, + traits::{ + allocatable::*, + encodable::{CircuitEncodable, CircuitEncodableExt}, + selectable::Selectable, + witnessable::*, + }, + u160::*, + u256::*, + u32::UInt32, + u8::UInt8, +}; + +use crate::{ + demux_log_queue::StorageLogQueue, + fsm_input_output::{circuit_inputs::INPUT_OUTPUT_COMMITMENT_LENGTH, *}, + storage_validity_by_grand_product::input::*, +}; + +use crate::utils::accumulate_grand_products; + +// we make a generation aware memory that store all the old and new values +// for a current storage cell. There are largely 3 possible sequences that we must be aware of +// - write_0, .. .... without rollback of the current write +// - write_0, ..., rollback_0, read_0, ... - in this case we must issue and explicit read, even though it's not the first one +// - read_0, ..., - same as above + +// We use extra structure with timestamping. Even though we DO have +// timestamp field in LogQuery, such timestamp is the SAME +// for "forward" and "rollback" items, while we do need to have them +// on different timestamps + +const TIMESTAMPED_STORAGE_LOG_ENCODING_LEN: usize = 20; + +use cs_derive::*; + +use std::sync::Arc; + +#[derive(Derivative, CSAllocatable, WitnessHookable)] +#[derivative(Clone, Debug)] +pub struct TimestampedStorageLogRecord { + pub record: LogQuery, + pub timestamp: UInt32, +} + +pub const EXTENDED_TIMESTAMP_ENCODING_ELEMENT: usize = 19; +pub const EXTENDED_TIMESTAMP_ENCODING_OFFSET: usize = 8; + +impl TimestampedStorageLogRecord { + pub fn append_timestamp_to_raw_query_encoding>( + cs: &mut CS, + original_encoding: &[Variable; TIMESTAMPED_STORAGE_LOG_ENCODING_LEN], + timestamp: &UInt32, + ) -> [Variable; TIMESTAMPED_STORAGE_LOG_ENCODING_LEN] { + debug_assert!(F::CAPACITY_BITS >= 40); + // LogQuery encoding leaves last variable as < 8 bits value + let encoding = Num::linear_combination( + cs, + &[ + ( + // Original encoding at index 19 is only 8 bits + original_encoding[EXTENDED_TIMESTAMP_ENCODING_ELEMENT], + F::ONE, + ), + (timestamp.get_variable(), F::from_u64_unchecked(1u64 << 8)), + ], + ) + .get_variable(); + + let mut result = *original_encoding; + result[EXTENDED_TIMESTAMP_ENCODING_ELEMENT] = encoding; + result + } +} + +impl CircuitEncodable + for TimestampedStorageLogRecord +{ + fn encode>( + &self, + cs: &mut CS, + ) -> [Variable; TIMESTAMPED_STORAGE_LOG_ENCODING_LEN] { + let original_encoding = self.record.encode(cs); + + Self::append_timestamp_to_raw_query_encoding(cs, &original_encoding, &self.timestamp) + } +} + +impl CSAllocatableExt for TimestampedStorageLogRecord { + const INTERNAL_STRUCT_LEN: usize = 37; + + fn witness_from_set_of_values(values: [F; Self::INTERNAL_STRUCT_LEN]) -> Self::Witness { + // NOTE(shamatar) Using CSAllocatableExt causes cyclic dependency here, so we use workaround + let mut record_values = + [F::ZERO; crate::base_structures::log_query::FLATTENED_VARIABLE_LENGTH]; + record_values.copy_from_slice( + &values[..crate::base_structures::log_query::FLATTENED_VARIABLE_LENGTH], + ); + let record = log_query_witness_from_values(record_values); + let other_timestamp: u32 = WitnessCastable::cast_from_source(values[36]); + + Self::Witness { + record, + timestamp: other_timestamp, + } + } + + // we should be able to allocate without knowing values yet + fn create_without_value>(cs: &mut CS) -> Self { + Self { + record: LogQuery::::allocate_without_value(cs), + timestamp: UInt32::allocate_without_value(cs), + } + } + + fn flatten_as_variables(&self) -> [Variable; 37] + where + [(); Self::INTERNAL_STRUCT_LEN]:, + { + let mut result = [Variable::placeholder(); 37]; + let record_variables = self.record.flatten_as_variables_impl(); + result[..crate::base_structures::log_query::FLATTENED_VARIABLE_LENGTH] + .copy_from_slice(&record_variables); + result[crate::base_structures::log_query::FLATTENED_VARIABLE_LENGTH] = + self.timestamp.get_variable(); + assert_no_placeholder_variables(&result); + + result + } + + fn set_internal_variables_values(witness: Self::Witness, dst: &mut DstBuffer<'_, '_, F>) { + LogQuery::set_internal_variables_values(witness.record, dst); + UInt32::set_internal_variables_values(witness.timestamp, dst); + } +} + +impl CircuitEncodableExt + for TimestampedStorageLogRecord +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ +} + +pub fn sort_and_deduplicate_storage_access_entry_point< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, +>( + cs: &mut CS, + closed_form_input: StorageDeduplicatorInstanceWitness, + round_function: &R, + limit: usize, +) -> [Num; INPUT_OUTPUT_COMMITMENT_LENGTH] +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + let structured_input_witness = closed_form_input.closed_form_input; + let unsorted_queue_witness = closed_form_input.unsorted_queue_witness; + let intermediate_sorted_queue_witness = closed_form_input.intermediate_sorted_queue_witness; + + let mut structured_input = StorageDeduplicatorInputOutput::alloc_ignoring_outputs( + cs, + structured_input_witness.clone(), + ); + + let unsorted_queue_from_passthrough_state = QueueState { + head: structured_input + .observable_input + .unsorted_log_queue_state + .head, + tail: structured_input + .observable_input + .unsorted_log_queue_state + .tail, + }; + + let unsorted_queue_from_fsm_input_state = QueueState { + head: structured_input + .hidden_fsm_input + .current_unsorted_queue_state + .head, + tail: structured_input + .hidden_fsm_input + .current_unsorted_queue_state + .tail, + }; + + // passthrought must be trivial + unsorted_queue_from_passthrough_state.enforce_trivial_head(cs); + + let state = QueueState::conditionally_select( + cs, + structured_input.start_flag, + &unsorted_queue_from_passthrough_state, + &unsorted_queue_from_fsm_input_state, + ); + let mut unsorted_queue = StorageLogQueue::::from_state(cs, state); + + unsorted_queue.witness = Arc::new(CircuitQueueWitness::from_inner_witness( + unsorted_queue_witness, + )); + + // same logic from sorted + let intermediate_sorted_queue_from_passthrough = CircuitQueue::< + F, + TimestampedStorageLogRecord, + 8, + 12, + 4, + QUEUE_STATE_WIDTH, + TIMESTAMPED_STORAGE_LOG_ENCODING_LEN, + R, + >::from_raw_parts( + cs, + structured_input + .observable_input + .intermediate_sorted_queue_state + .head, + structured_input + .observable_input + .intermediate_sorted_queue_state + .tail + .tail, + structured_input + .observable_input + .intermediate_sorted_queue_state + .tail + .length, + ); + + let intermediate_sorted_queue_from_fsm_input = CircuitQueue::< + F, + TimestampedStorageLogRecord, + 8, + 12, + 4, + QUEUE_STATE_WIDTH, + TIMESTAMPED_STORAGE_LOG_ENCODING_LEN, + R, + >::from_raw_parts( + cs, + structured_input + .hidden_fsm_input + .current_intermediate_sorted_queue_state + .head, + structured_input + .hidden_fsm_input + .current_intermediate_sorted_queue_state + .tail + .tail, + structured_input + .hidden_fsm_input + .current_intermediate_sorted_queue_state + .tail + .length, + ); + + // passthrought must be trivial + intermediate_sorted_queue_from_passthrough.enforce_trivial_head(cs); + + let state = QueueState::conditionally_select( + cs, + structured_input.start_flag, + &intermediate_sorted_queue_from_passthrough.into_state(), + &intermediate_sorted_queue_from_fsm_input.into_state(), + ); + let mut intermediate_sorted_queue = CircuitQueue::< + F, + TimestampedStorageLogRecord, + 8, + 12, + 4, + QUEUE_STATE_WIDTH, + TIMESTAMPED_STORAGE_LOG_ENCODING_LEN, + R, + >::from_state(cs, state); + + intermediate_sorted_queue.witness = Arc::new(CircuitQueueWitness::from_inner_witness( + intermediate_sorted_queue_witness, + )); + + // for final sorted queue it's easier + + let empty_final_sorted_queue = StorageLogQueue::::empty(cs); + let final_sorted_queue_from_fsm_input = StorageLogQueue::::from_raw_parts( + cs, + structured_input + .hidden_fsm_input + .current_final_sorted_queue_state + .head, + structured_input + .hidden_fsm_input + .current_final_sorted_queue_state + .tail + .tail, + structured_input + .hidden_fsm_input + .current_final_sorted_queue_state + .tail + .length, + ); + + let state = QueueState::conditionally_select( + cs, + structured_input.start_flag, + &empty_final_sorted_queue.into_state(), + &final_sorted_queue_from_fsm_input.into_state(), + ); + let mut final_sorted_queue = StorageLogQueue::::from_state(cs, state); + + // get challenges for permutation argument + let challenges = crate::utils::produce_fs_challenges::< + F, + CS, + R, + QUEUE_STATE_WIDTH, + { TIMESTAMPED_STORAGE_LOG_ENCODING_LEN + 1 }, + DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS, + >( + cs, + structured_input + .observable_input + .unsorted_log_queue_state + .tail, + structured_input + .observable_input + .intermediate_sorted_queue_state + .tail, + round_function, + ); + + let one = Num::allocated_constant(cs, F::ONE); + let initial_lhs = + <[Num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS]>::conditionally_select( + cs, + structured_input.start_flag, + &[one; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + &structured_input.hidden_fsm_input.lhs_accumulator, + ); + + let initial_rhs = + <[Num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS]>::conditionally_select( + cs, + structured_input.start_flag, + &[one; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + &structured_input.hidden_fsm_input.rhs_accumulator, + ); + + let zero_u32: UInt32 = UInt32::zero(cs); + + // there is no code at address 0 in our case, so we can formally use it for all the purposes + let previous_packed_key = <[UInt32; PACKED_KEY_LENGTH]>::conditionally_select( + cs, + structured_input.start_flag, + &[zero_u32; PACKED_KEY_LENGTH], + &structured_input.hidden_fsm_input.previous_packed_key, + ); + + let cycle_idx = UInt32::conditionally_select( + cs, + structured_input.start_flag, + &zero_u32, + &structured_input.hidden_fsm_input.cycle_idx, + ); + + let shard_id = structured_input.observable_input.shard_id_to_process; + + let ( + new_lhs, + new_rhs, + cycle_idx, + previous_packed_key, + previous_key, + previous_address, + previous_timestamp, + this_cell_has_explicit_read_and_rollback_depth_zero, + this_cell_base_value, + this_cell_current_value, + this_cell_current_depth, + ) = sort_and_deduplicate_storage_access_inner( + cs, + initial_lhs, + initial_rhs, + &mut unsorted_queue, + &mut intermediate_sorted_queue, + &mut final_sorted_queue, + structured_input.start_flag, + cycle_idx, + challenges, + previous_packed_key, + structured_input.hidden_fsm_input.previous_key, + structured_input.hidden_fsm_input.previous_address, + structured_input.hidden_fsm_input.previous_timestamp, + structured_input + .hidden_fsm_input + .this_cell_has_explicit_read_and_rollback_depth_zero, + structured_input.hidden_fsm_input.this_cell_base_value, + structured_input.hidden_fsm_input.this_cell_current_value, + structured_input.hidden_fsm_input.this_cell_current_depth, + shard_id, + limit, + ); + + unsorted_queue.enforce_consistency(cs); + intermediate_sorted_queue.enforce_consistency(cs); + + let unsorted_is_empty = unsorted_queue.is_empty(cs); + let sorted_is_empty = intermediate_sorted_queue.is_empty(cs); + + Boolean::enforce_equal(cs, &unsorted_is_empty, &sorted_is_empty); + + let completed = unsorted_is_empty.and(cs, sorted_is_empty); + new_lhs.iter().zip(new_rhs).for_each(|(l, r)| { + Num::conditionally_enforce_equal(cs, completed, &l, &r); + }); + + // form the input/output + + structured_input.hidden_fsm_output.cycle_idx = cycle_idx; + structured_input.hidden_fsm_output.previous_packed_key = previous_packed_key; + structured_input.hidden_fsm_output.previous_key = previous_key; + structured_input.hidden_fsm_output.previous_address = previous_address; + structured_input.hidden_fsm_output.previous_timestamp = previous_timestamp; + structured_input + .hidden_fsm_output + .this_cell_has_explicit_read_and_rollback_depth_zero = + this_cell_has_explicit_read_and_rollback_depth_zero; + structured_input.hidden_fsm_output.this_cell_base_value = this_cell_base_value; + structured_input.hidden_fsm_output.this_cell_current_value = this_cell_current_value; + structured_input.hidden_fsm_output.this_cell_current_depth = this_cell_current_depth; + + structured_input.hidden_fsm_output.lhs_accumulator = new_lhs; + structured_input.hidden_fsm_output.rhs_accumulator = new_rhs; + + structured_input + .hidden_fsm_output + .current_unsorted_queue_state = unsorted_queue.into_state(); + structured_input + .hidden_fsm_output + .current_intermediate_sorted_queue_state = intermediate_sorted_queue.into_state(); + + structured_input.completion_flag = completed; + + let empty_queue_state = QueueState::empty(cs); + let state = QueueState::conditionally_select( + cs, + completed, + &final_sorted_queue.into_state(), + &empty_queue_state, + ); + let final_queue_for_observable_output = CircuitQueue::< + F, + LogQuery, + 8, + 12, + 4, + QUEUE_STATE_WIDTH, + LOG_QUERY_PACKED_WIDTH, + R, + >::from_state(cs, state); + + structured_input.observable_output.final_sorted_queue_state = + final_queue_for_observable_output.into_state(); + + structured_input + .hidden_fsm_output + .current_final_sorted_queue_state = final_sorted_queue.into_state(); + + structured_input.hook_compare_witness(cs, &structured_input_witness); + + let compact_form = + ClosedFormInputCompactForm::from_full_form(cs, &structured_input, round_function); + + // dbg!(compact_form.create_witness()); + let input_committment = + commit_variable_length_encodable_item(cs, &compact_form, round_function); + for el in input_committment.iter() { + let gate = PublicInputGate::new(el.get_variable()); + gate.add_to_cs(cs); + } + + input_committment +} + +pub const NUM_PERMUTATION_ARG_CHALLENGES: usize = TIMESTAMPED_STORAGE_LOG_ENCODING_LEN + 1; + +pub fn sort_and_deduplicate_storage_access_inner< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction, +>( + cs: &mut CS, + mut lhs: [Num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + mut rhs: [Num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + original_queue: &mut StorageLogQueue, + intermediate_sorted_queue: &mut CircuitQueue< + F, + TimestampedStorageLogRecord, + 8, + 12, + 4, + QUEUE_STATE_WIDTH, + TIMESTAMPED_STORAGE_LOG_ENCODING_LEN, + R, + >, + sorted_queue: &mut StorageLogQueue, + is_start: Boolean, + mut cycle_idx: UInt32, + fs_challenges: [[Num; TIMESTAMPED_STORAGE_LOG_ENCODING_LEN + 1]; + DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + mut previous_packed_key: [UInt32; PACKED_KEY_LENGTH], + mut previous_key: UInt256, + mut previous_address: UInt160, + mut previous_timestamp: UInt32, + mut this_cell_has_explicit_read_and_rollback_depth_zero: Boolean, + mut this_cell_base_value: UInt256, + mut this_cell_current_value: UInt256, + mut this_cell_current_depth: UInt32, + shard_id_to_process: UInt8, + limit: usize, +) -> ( + [Num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + [Num; DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS], + UInt32, + [UInt32; PACKED_KEY_LENGTH], + UInt256, + UInt160, + UInt32, + Boolean, + UInt256, + UInt256, + UInt32, +) +where + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, + [(); as CSAllocatableExt>::INTERNAL_STRUCT_LEN]:, +{ + assert!(limit <= u32::MAX as usize); + + let unsorted_queue_length = Num::from_variable(original_queue.length.get_variable()); + let intermediate_sorted_queue_length = + Num::from_variable(intermediate_sorted_queue.length.get_variable()); + + Num::enforce_equal( + cs, + &unsorted_queue_length, + &intermediate_sorted_queue_length, + ); + + // we can recreate it here, there are two cases: + // - we are 100% empty, but it's the only circuit in this case + // - otherwise we continue, and then it's not trivial + let no_work = original_queue.is_empty(cs); + let mut previous_item_is_trivial = no_work.or(cs, is_start); + + // we simultaneously pop, accumulate partial product, + // and decide whether or not we should move to the next cell + + // to ensure uniqueness we place timestamps in a addition to the original values encoding access location + + for _cycle in 0..limit { + let original_timestamp = cycle_idx; + // increment it immediatelly + unsafe { + let new_cycle_idx = cycle_idx.increment_unchecked(cs); + cycle_idx = new_cycle_idx; + } + + let original_is_empty = original_queue.is_empty(cs); + let sorted_is_empty = intermediate_sorted_queue.is_empty(cs); + Boolean::enforce_equal(cs, &original_is_empty, &sorted_is_empty); + + let original_is_not_empty = original_is_empty.negated(cs); + let sorted_is_not_empty = sorted_is_empty.negated(cs); + + let should_pop = Boolean::multi_and(cs, &[original_is_not_empty, sorted_is_not_empty]); + let item_is_trivial = original_is_empty; + + // NOTE: we do not need to check shard_id of unsorted item because we can just check it on sorted item + let (_, original_encoding) = original_queue.pop_front(cs, should_pop); + let (sorted_item, sorted_encoding) = intermediate_sorted_queue.pop_front(cs, should_pop); + let extended_original_encoding = + TimestampedStorageLogRecord::append_timestamp_to_raw_query_encoding( + cs, + &original_encoding, + &original_timestamp, + ); + + let shard_id_is_valid = + UInt8::equals(cs, &shard_id_to_process, &sorted_item.record.shard_id); + shard_id_is_valid.conditionally_enforce_true(cs, should_pop); + + accumulate_grand_products::< + F, + CS, + TIMESTAMPED_STORAGE_LOG_ENCODING_LEN, + { TIMESTAMPED_STORAGE_LOG_ENCODING_LEN + 1 }, + DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS, + >( + cs, + &mut lhs, + &mut rhs, + &fs_challenges, + &extended_original_encoding, + &sorted_encoding, + should_pop, + ); + + let TimestampedStorageLogRecord { record, timestamp } = sorted_item; + + // now resolve a logic about sorting itself + let packed_key = concatenate_key(cs, (record.address.clone(), record.key)); + + // ensure sorting. Check that previous key < this key + let (keys_are_equal, previous_key_is_greater) = + unpacked_long_comparison(cs, &previous_packed_key, &packed_key); + + let not_item_is_trivial = item_is_trivial.negated(cs); + previous_key_is_greater.conditionally_enforce_false(cs, not_item_is_trivial); + + // if keys are the same then timestamps are sorted + let (_, previous_timestamp_is_less) = previous_timestamp.overflowing_sub(cs, timestamp); + // enforce if keys are the same and not trivial + let must_enforce = keys_are_equal.and(cs, not_item_is_trivial); + previous_timestamp_is_less.conditionally_enforce_true(cs, must_enforce); + + // we follow the procedure: + // if keys are different then we finish with a previous one and update parameters + // else we just update parameters + + // if new cell + { + let not_keys_are_equal = keys_are_equal.negated(cs); + if _cycle == 0 { + // it must always be true if we start + not_keys_are_equal.conditionally_enforce_true(cs, is_start); + } + // finish with the old one + // if somewhere along the way we did encounter a read at rollback depth zero (not important if there were such), + // and if current rollback depth is 0 then we MUST issue a read + + let value_is_unchanged = + UInt256::equals(cs, &this_cell_current_value, &this_cell_base_value); + // there may be a situation when as a result of sequence of writes + // storage slot is CLAIMED to be unchanged. There are two options: + // - unchanged because we had write - ... - rollback AND we do not have read at depth 0. + // In this case we used a temporary value, and the fact that the last action is rollback + // all the way to the start (to depth 0), we are not interested in what was an initial value + // - unchanged because a -> write b -> ... -> write a AND we do or do not have read at depth 0. + // In this case we would not need to write IF prover is honest and provides a true witness to "read value" + // field at the first write. But we can not rely on this and have to check this fact! + let current_depth_is_zero = this_cell_current_depth.is_zero(cs); + let not_current_depth_is_zero = current_depth_is_zero.negated(cs); + let unchanged_but_not_by_rollback = + value_is_unchanged.and(cs, not_current_depth_is_zero); + let issue_protective_read = this_cell_has_explicit_read_and_rollback_depth_zero + .or(cs, unchanged_but_not_by_rollback); + let should_write = value_is_unchanged.negated(cs); + + let query = LogQuery { + address: previous_address, + key: previous_key, + read_value: this_cell_base_value, + written_value: this_cell_current_value, + rw_flag: should_write, + aux_byte: UInt8::zero(cs), + rollback: Boolean::allocated_constant(cs, false), + is_service: Boolean::allocated_constant(cs, false), + shard_id: shard_id_to_process, + tx_number_in_block: UInt32::zero(cs), + timestamp: UInt32::zero(cs), + }; + + // if we did only writes and rollbacks then we don't need to update + let should_update = issue_protective_read.or(cs, should_write); + let not_keys_are_equal_and_should_update = not_keys_are_equal.and(cs, should_update); + let should_push = previous_item_is_trivial + .negated(cs) + .and(cs, not_keys_are_equal_and_should_update); + + sorted_queue.push(cs, query, should_push); + + let new_non_trivial_cell = item_is_trivial.negated(cs).and(cs, not_keys_are_equal); + + // and update as we switch to the new cell with extra logic + let meaningful_value = UInt256::conditionally_select( + cs, + record.rw_flag, + &record.written_value, + &record.read_value, + ); + + // re-update + this_cell_base_value = UInt256::conditionally_select( + cs, + new_non_trivial_cell, + &record.read_value, + &this_cell_base_value, + ); + + this_cell_current_value = UInt256::conditionally_select( + cs, + new_non_trivial_cell, + &meaningful_value, + &this_cell_current_value, + ); + + let one = UInt32::allocated_constant(cs, 1); + let zero = UInt32::zero(cs); + let rollback_depth_for_new_cell = + UInt32::conditionally_select(cs, record.rw_flag, &one, &zero); + + this_cell_current_depth = UInt32::conditionally_select( + cs, + new_non_trivial_cell, + &rollback_depth_for_new_cell, + &this_cell_current_depth, + ); + + // we have new non-trivial + // and if it's read then it's definatelly at depth 0 + let not_rw_flag = record.rw_flag.negated(cs); + this_cell_has_explicit_read_and_rollback_depth_zero = Boolean::conditionally_select( + cs, + new_non_trivial_cell, + ¬_rw_flag, + &this_cell_has_explicit_read_and_rollback_depth_zero, + ); + } + + // if same cell - update + { + let not_rw_flag = record.rw_flag.negated(cs); + let non_trivial_and_same_cell = item_is_trivial.negated(cs).and(cs, keys_are_equal); + let non_trivial_read_of_same_cell = non_trivial_and_same_cell.and(cs, not_rw_flag); + let non_trivial_write_of_same_cell = non_trivial_and_same_cell.and(cs, record.rw_flag); + let not_rollback = record.rollback.negated(cs); + let write_no_rollback = non_trivial_write_of_same_cell.and(cs, not_rollback); + let write_rollback = non_trivial_write_of_same_cell.and(cs, record.rollback); + + // update rollback depth the is a result of this action + unsafe { + let incremented_depth = this_cell_current_depth.increment_unchecked(cs); + this_cell_current_depth = UInt32::conditionally_select( + cs, + write_no_rollback, + &incremented_depth, + &this_cell_current_depth, + ); + let decremented_depth = this_cell_current_depth.decrement_unchecked(cs); + this_cell_current_depth = UInt32::conditionally_select( + cs, + write_rollback, + &decremented_depth, + &this_cell_current_depth, + ); + } + + // check consistency + let read_is_equal_to_current = + UInt256::equals(cs, &this_cell_current_value, &record.read_value); + // we ALWAYS ensure read consistency on write (but not rollback) and on plain read + let check_read_consistency = + Boolean::multi_or(cs, &[non_trivial_read_of_same_cell, write_no_rollback]); + read_is_equal_to_current.conditionally_enforce_true(cs, check_read_consistency); + + // decide to update + this_cell_current_value = UInt256::conditionally_select( + cs, + write_no_rollback, + &record.written_value, + &this_cell_current_value, + ); + + this_cell_current_value = UInt256::conditionally_select( + cs, + write_rollback, + &record.read_value, + &this_cell_current_value, + ); + + let current_rollback_depth_is_zero = this_cell_current_depth.is_zero(cs); + let read_at_rollback_depth_zero_of_same_cell = + current_rollback_depth_is_zero.and(cs, non_trivial_read_of_same_cell); + + this_cell_base_value = UInt256::conditionally_select( + cs, + read_at_rollback_depth_zero_of_same_cell, + &record.read_value, + &this_cell_base_value, + ); + + // we definately read non-trivial, and that is on depth 0, so set to true + let constant_true = Boolean::allocated_constant(cs, true); + this_cell_has_explicit_read_and_rollback_depth_zero = Boolean::conditionally_select( + cs, + read_at_rollback_depth_zero_of_same_cell, + &constant_true, + &this_cell_has_explicit_read_and_rollback_depth_zero, + ); + } + + // always update counters + previous_address = record.address; + previous_key = record.key; + previous_item_is_trivial = item_is_trivial; + previous_timestamp = timestamp; + previous_packed_key = packed_key; + } + + // finalization step - out of cycle, and only if we are done just yet + { + let queues_exhausted = original_queue.is_empty(cs); + + // cell state is final + let value_is_unchanged = + UInt256::equals(cs, &this_cell_current_value, &this_cell_base_value); + let current_depth_is_zero = this_cell_current_depth.is_zero(cs); + let not_current_depth_is_zero = current_depth_is_zero.negated(cs); + let unchanged_but_not_by_rollback = value_is_unchanged.and(cs, not_current_depth_is_zero); + let issue_protective_read = this_cell_has_explicit_read_and_rollback_depth_zero + .or(cs, unchanged_but_not_by_rollback); + let should_write = value_is_unchanged.negated(cs); + + let query = LogQuery { + address: previous_address, + key: previous_key, + read_value: this_cell_base_value, + written_value: this_cell_current_value, + rw_flag: should_write, + aux_byte: UInt8::zero(cs), + rollback: Boolean::allocated_constant(cs, false), + is_service: Boolean::allocated_constant(cs, false), + shard_id: shard_id_to_process, + tx_number_in_block: UInt32::zero(cs), + timestamp: UInt32::zero(cs), + }; + + // if we did only writes and rollbacks then we don't need to update + let should_update = issue_protective_read.or(cs, should_write); + let should_update_and_queues_exhausted = should_update.and(cs, queues_exhausted); + let should_push = previous_item_is_trivial + .negated(cs) + .and(cs, should_update_and_queues_exhausted); + + sorted_queue.push(cs, query, should_push); + + // reset flag to match simple witness generation convensions + let constant_false = Boolean::allocated_constant(cs, false); + this_cell_has_explicit_read_and_rollback_depth_zero = Boolean::conditionally_select( + cs, + queues_exhausted, + &constant_false, + &this_cell_has_explicit_read_and_rollback_depth_zero, + ); + } + + // output our FSM values + + ( + lhs, + rhs, + cycle_idx, + previous_packed_key, + previous_key, + previous_address, + previous_timestamp, + this_cell_has_explicit_read_and_rollback_depth_zero, + this_cell_base_value, + this_cell_current_value, + this_cell_current_depth, + ) +} + +fn concatenate_key>( + _cs: &mut CS, + key_tuple: (UInt160, UInt256), +) -> [UInt32; PACKED_KEY_LENGTH] { + // LE packing so comparison is subtraction + let (address, key) = key_tuple; + [ + key.inner[0], + key.inner[1], + key.inner[2], + key.inner[3], + key.inner[4], + key.inner[5], + key.inner[6], + key.inner[7], + address.inner[0], + address.inner[1], + address.inner[2], + address.inner[3], + address.inner[4], + ] +} + +/// Check that a == b and a > b by performing a long subtraction b - a with borrow. +/// Both a and b are considered as least significant word first +#[track_caller] +pub fn unpacked_long_comparison, const N: usize>( + cs: &mut CS, + a: &[UInt32; N], + b: &[UInt32; N], +) -> (Boolean, Boolean) { + let boolean_false = Boolean::allocated_constant(cs, false); + let mut equals = [boolean_false; N]; + let mut borrow = boolean_false; + + for i in 0..N { + let (diff, new_borrow) = b[i].overflowing_sub_with_borrow_in(cs, a[i], borrow); + borrow = new_borrow; + equals[i] = diff.is_zero(cs); + } + + let equal = Boolean::multi_and(cs, &equals); + let a_is_greater = borrow; + + (equal, a_is_greater) +} + +#[cfg(test)] +mod tests { + use super::*; + use boojum::algebraic_props::poseidon2_parameters::Poseidon2GoldilocksExternalMatrix; + use boojum::cs::implementations::reference_cs::{ + CSDevelopmentAssembly, CSReferenceImplementation, + }; + use boojum::cs::traits::gate::GatePlacementStrategy; + use boojum::cs::CSGeometry; + // use boojum::cs::EmptyToolbox; + use boojum::cs::*; + use boojum::field::goldilocks::GoldilocksField; + use boojum::gadgets::tables::*; + use boojum::implementations::poseidon2::Poseidon2Goldilocks; + use boojum::worker::Worker; + use ethereum_types::{Address, U256}; + + type F = GoldilocksField; + type P = GoldilocksField; + + use boojum::config::*; + use boojum::cs::cs_builder::*; + + fn configure< + T: CsBuilderImpl, + GC: GateConfigurationHolder, + TB: StaticToolboxHolder, + >( + builder: CsBuilder, + ) -> CsBuilder, impl StaticToolboxHolder> { + let owned_cs = builder; + let owned_cs = owned_cs.allow_lookup( + LookupParameters::UseSpecializedColumnsWithTableIdAsConstant { + width: 3, + num_repetitions: 8, + share_table_id: true, + }, + ); + let owned_cs = ConstantsAllocatorGate::configure_builder( + owned_cs, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let owned_cs = FmaGateInBaseFieldWithoutConstant::configure_builder( + owned_cs, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let owned_cs = ReductionGate::::configure_builder( + owned_cs, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let owned_cs = BooleanConstraintGate::configure_builder( + owned_cs, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let owned_cs = UIntXAddGate::<32>::configure_builder( + owned_cs, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let owned_cs = UIntXAddGate::<16>::configure_builder( + owned_cs, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let owned_cs = SelectionGate::configure_builder( + owned_cs, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let owned_cs = ZeroCheckGate::configure_builder( + owned_cs, + GatePlacementStrategy::UseGeneralPurposeColumns, + false, + ); + let owned_cs = DotProductGate::<4>::configure_builder( + owned_cs, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let owned_cs = + MatrixMultiplicationGate::::configure_builder( + owned_cs, + GatePlacementStrategy::UseGeneralPurposeColumns, + ); + let owned_cs = + NopGate::configure_builder(owned_cs, GatePlacementStrategy::UseGeneralPurposeColumns); + + owned_cs + } + + #[test] + fn test_storage_validity_circuit() { + let geometry = CSGeometry { + num_columns_under_copy_permutation: 100, + num_witness_columns: 0, + num_constant_columns: 8, + max_allowed_constraint_degree: 4, + }; + + use boojum::config::DevCSConfig; + use boojum::cs::cs_builder_reference::*; + + let builder_impl = + CsReferenceImplementationBuilder::::new(geometry, 1 << 26, 1 << 20); + use boojum::cs::cs_builder::new_builder; + let builder = new_builder::<_, F>(builder_impl); + + let builder = configure(builder); + let mut owned_cs = builder.build(()); + + // add tables + let table = create_xor8_table(); + owned_cs.add_lookup_table::(table); + + let cs = &mut owned_cs; + + let lhs = [Num::allocated_constant(cs, F::from_nonreduced_u64(1)); + DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS]; + let rhs = [Num::allocated_constant(cs, F::from_nonreduced_u64(1)); + DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS]; + + let execute = Boolean::allocated_constant(cs, true); + let mut original_queue = StorageLogQueue::::empty(cs); + let unsorted_input = test_input::generate_test_input_unsorted(cs); + for el in unsorted_input { + original_queue.push(cs, el, execute); + } + + let mut intermediate_sorted_queue = CircuitQueue::empty(cs); + let sorted_input = test_input::generate_test_input_sorted(cs); + for el in sorted_input { + intermediate_sorted_queue.push(cs, el, execute); + } + + let mut sorted_queue = StorageLogQueue::empty(cs); + + let is_start = Boolean::allocated_constant(cs, true); + let cycle_idx = UInt32::allocated_constant(cs, 0); + let round_function = Poseidon2Goldilocks; + let fs_challenges = crate::utils::produce_fs_challenges::< + F, + _, + Poseidon2Goldilocks, + QUEUE_STATE_WIDTH, + { TIMESTAMPED_STORAGE_LOG_ENCODING_LEN + 1 }, + DEFAULT_NUM_PERMUTATION_ARGUMENT_REPETITIONS, + >( + cs, + original_queue.into_state().tail, + intermediate_sorted_queue.into_state().tail, + &round_function, + ); + let previous_packed_key = [UInt32::allocated_constant(cs, 0); PACKED_KEY_LENGTH]; + let previous_key = UInt256::allocated_constant(cs, U256::default()); + let previous_address = UInt160::allocated_constant(cs, Address::default()); + let previous_timestamp = UInt32::allocated_constant(cs, 0); + let this_cell_has_explicit_read_and_rollback_depth_zero = + Boolean::allocated_constant(cs, false); + let this_cell_base_value = UInt256::allocated_constant(cs, U256::default()); + let this_cell_current_value = UInt256::allocated_constant(cs, U256::default()); + let this_cell_current_depth = UInt32::allocated_constant(cs, 0); + let shard_id_to_process = UInt8::allocated_constant(cs, 0); + let limit = 16; + + sort_and_deduplicate_storage_access_inner( + cs, + lhs, + rhs, + &mut original_queue, + &mut intermediate_sorted_queue, + &mut sorted_queue, + is_start, + cycle_idx, + fs_challenges, + previous_packed_key, + previous_key, + previous_address, + previous_timestamp, + this_cell_has_explicit_read_and_rollback_depth_zero, + this_cell_base_value, + this_cell_current_value, + this_cell_current_depth, + shard_id_to_process, + limit, + ); + + cs.pad_and_shrink(); + let worker = Worker::new(); + let mut owned_cs = owned_cs.into_assembly(); + owned_cs.print_gate_stats(); + assert!(owned_cs.check_if_satisfied(&worker)); + } +} diff --git a/crates/zkevm_circuits/src/storage_validity_by_grand_product/test_input.rs b/crates/zkevm_circuits/src/storage_validity_by_grand_product/test_input.rs new file mode 100644 index 0000000..fba4970 --- /dev/null +++ b/crates/zkevm_circuits/src/storage_validity_by_grand_product/test_input.rs @@ -0,0 +1,632 @@ +use super::TimestampedStorageLogRecord; +use crate::base_structures::log_query::LogQuery; +use crate::ethereum_types::{Address, U256}; +use boojum::cs::gates::{assert_no_placeholder_variables, assert_no_placeholders}; +use boojum::cs::traits::cs::ConstraintSystem; +use boojum::field::goldilocks::GoldilocksField; +use boojum::gadgets::{boolean::Boolean, u160::*, u256::*, u32::*, u8::*}; + +type F = GoldilocksField; + +// This witness input is generated from the old test harness, and remodeled to work in the current type system. +pub fn generate_test_input_unsorted>(cs: &mut CS) -> Vec> { + let mut queries = vec![]; + let bool_false = Boolean::allocated_constant(cs, false); + let bool_true = Boolean::allocated_constant(cs, true); + let zero_8 = UInt8::allocated_constant(cs, 0); + let zero_32 = UInt32::allocated_constant(cs, 0); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32770)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("32779").unwrap()), + read_value: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452319300877325313852488925888724764263521004047156906617735320131041551860", + ) + .unwrap(), + ), + written_value: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452319300877325313852488925888724764263521004047156906617735320131041551860", + ) + .unwrap(), + ), + rw_flag: bool_false, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 1205), + }; + queries.push(q); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32779)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("1").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + rw_flag: bool_false, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 1425), + }; + queries.push(q); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32770)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("32779").unwrap()), + read_value: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452319300877325313852488925888724764263521004047156906617735320131041551860", + ) + .unwrap(), + ), + written_value: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452319300877325313852488925888724764263521004047156906617735320131041551860", + ) + .unwrap(), + ), + rw_flag: bool_false, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 1609), + }; + queries.push(q); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32779)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("7").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + rw_flag: bool_false, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 1777), + }; + queries.push(q); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32770)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("32779").unwrap()), + read_value: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452319300877325313852488925888724764263521004047156906617735320131041551860", + ) + .unwrap(), + ), + written_value: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452319300877325313852488925888724764263521004047156906617735320131041551860", + ) + .unwrap(), + ), + rw_flag: bool_false, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 1969), + }; + queries.push(q); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32779)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("5").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + rw_flag: bool_false, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 2253), + }; + queries.push(q); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32769)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("10").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + rw_flag: bool_true, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 2357), + }; + queries.push(q); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32770)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("32779").unwrap()), + read_value: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452319300877325313852488925888724764263521004047156906617735320131041551860", + ) + .unwrap(), + ), + written_value: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452319300877325313852488925888724764263521004047156906617735320131041551860", + ) + .unwrap(), + ), + rw_flag: bool_false, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 2429), + }; + queries.push(q); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32779)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("4").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + rw_flag: bool_false, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 2681), + }; + queries.push(q); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32769)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("9").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + rw_flag: bool_false, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 2797), + }; + queries.push(q); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32769)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("9").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + rw_flag: bool_true, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 2829), + }; + queries.push(q); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32770)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("32779").unwrap()), + read_value: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452319300877325313852488925888724764263521004047156906617735320131041551860", + ) + .unwrap(), + ), + written_value: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452319300877325313852488925888724764263521004047156906617735320131041551860", + ) + .unwrap(), + ), + rw_flag: bool_false, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 2901), + }; + queries.push(q); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32779)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("3").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + rw_flag: bool_false, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 3089), + }; + queries.push(q); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32769)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("8").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + rw_flag: bool_true, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 3193), + }; + queries.push(q); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32770)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("32779").unwrap()), + read_value: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452319300877325313852488925888724764263521004047156906617735320131041551860", + ) + .unwrap(), + ), + written_value: UInt256::allocated_constant( + cs, + U256::from_dec_str( + "452319300877325313852488925888724764263521004047156906617735320131041551860", + ) + .unwrap(), + ), + rw_flag: bool_false, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 3265), + }; + queries.push(q); + + let q = LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32779)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("2").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + rw_flag: bool_false, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 3421), + }; + queries.push(q); + + queries +} + +pub fn generate_test_input_sorted>( + cs: &mut CS, +) -> Vec> { + let mut records = vec![]; + let bool_false = Boolean::allocated_constant(cs, false); + let bool_true = Boolean::allocated_constant(cs, true); + let zero_8 = UInt8::allocated_constant(cs, 0); + let zero_32 = UInt32::allocated_constant(cs, 0); + + let r = TimestampedStorageLogRecord:: { + timestamp: UInt32::allocated_constant(cs, 27), + record: LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32769)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("2").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + rw_flag: bool_false, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 4785), + }, + }; + records.push(r); + + let r = TimestampedStorageLogRecord:: { + timestamp: UInt32::allocated_constant(cs, 28), + record: LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32769)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("2").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + rw_flag: bool_true, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 4817), + }, + }; + records.push(r); + + let r = TimestampedStorageLogRecord:: { + timestamp: UInt32::allocated_constant(cs, 22), + record: LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32769)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("3").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + rw_flag: bool_true, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 4317), + }, + }; + records.push(r); + + let r = TimestampedStorageLogRecord:: { + timestamp: UInt32::allocated_constant(cs, 25), + record: LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32769)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("4").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + rw_flag: bool_false, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 4721), + }, + }; + records.push(r); + + let r = TimestampedStorageLogRecord:: { + timestamp: UInt32::allocated_constant(cs, 26), + record: LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32769)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("4").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + rw_flag: bool_true, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 4753), + }, + }; + records.push(r); + + let r = TimestampedStorageLogRecord:: { + timestamp: UInt32::allocated_constant(cs, 31), + record: LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32769)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("5").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + rw_flag: bool_true, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 5177), + }, + }; + records.push(r); + + let r = TimestampedStorageLogRecord:: { + timestamp: UInt32::allocated_constant(cs, 19), + record: LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32769)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("6").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + rw_flag: bool_true, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 3929), + }, + }; + records.push(r); + + let r = TimestampedStorageLogRecord:: { + timestamp: UInt32::allocated_constant(cs, 16), + record: LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32769)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("7").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + rw_flag: bool_true, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 3525), + }, + }; + records.push(r); + + let r = TimestampedStorageLogRecord:: { + timestamp: UInt32::allocated_constant(cs, 13), + record: LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32769)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("8").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + rw_flag: bool_true, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 3193), + }, + }; + records.push(r); + + let r = TimestampedStorageLogRecord:: { + timestamp: UInt32::allocated_constant(cs, 9), + record: LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32769)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("9").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + rw_flag: bool_false, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 2797), + }, + }; + records.push(r); + + let r = TimestampedStorageLogRecord:: { + timestamp: UInt32::allocated_constant(cs, 10), + record: LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32769)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("9").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + rw_flag: bool_true, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 2829), + }, + }; + records.push(r); + + let r = TimestampedStorageLogRecord:: { + timestamp: UInt32::allocated_constant(cs, 6), + record: LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32769)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("10").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + rw_flag: bool_true, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 2357), + }, + }; + records.push(r); + + let r = TimestampedStorageLogRecord:: { + timestamp: UInt32::allocated_constant(cs, 32), + record: LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32769)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("11").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + rw_flag: bool_true, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 5197), + }, + }; + records.push(r); + + let r = TimestampedStorageLogRecord:: { + timestamp: UInt32::allocated_constant(cs, 35), + record: LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32769)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("12").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + rw_flag: bool_false, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 7093), + }, + }; + records.push(r); + + let r = TimestampedStorageLogRecord:: { + timestamp: UInt32::allocated_constant(cs, 36), + record: LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32769)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("12").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("0").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("1").unwrap()), + rw_flag: bool_true, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 7129), + }, + }; + records.push(r); + + let r = TimestampedStorageLogRecord:: { + timestamp: UInt32::allocated_constant(cs, 38), + record: LogQuery:: { + address: UInt160::allocated_constant(cs, Address::from_low_u64_le(32769)), + key: UInt256::allocated_constant(cs, U256::from_dec_str("13").unwrap()), + read_value: UInt256::allocated_constant(cs, U256::from_dec_str("1").unwrap()), + written_value: UInt256::allocated_constant(cs, U256::from_dec_str("1").unwrap()), + rw_flag: bool_false, + aux_byte: zero_8, + rollback: bool_false, + is_service: bool_false, + shard_id: zero_8, + tx_number_in_block: zero_32, + timestamp: UInt32::allocated_constant(cs, 7177), + }, + }; + records.push(r); + + records +} diff --git a/crates/zkevm_circuits/src/tables/bitshift.rs b/crates/zkevm_circuits/src/tables/bitshift.rs new file mode 100644 index 0000000..18f71e0 --- /dev/null +++ b/crates/zkevm_circuits/src/tables/bitshift.rs @@ -0,0 +1,40 @@ +use super::*; +use crate::ethereum_types::U256; +use boojum::cs::implementations::lookup_table::LookupTable; +use boojum::field::SmallField; + +pub const VM_SHIFT_TO_NUM_CONVERTER_TABLE_NAME: &'static str = "Shift to num converter table"; + +#[derive(Derivative)] +#[derivative(Clone, Copy, Debug, PartialEq, Eq)] +pub struct BitshiftTable; + +pub fn create_shift_to_num_converter_table() -> LookupTable { + // there are 256 possible shifts and 8 32-bit limbs in any 256-bit register + // we give the value of two limbs per row, so the total number of rows in the table is: + // 256 * 8/2 = 256 * 4 = 1024 + let num_rows = 1024; + let mut all_keys = Vec::with_capacity(num_rows); + + for shift in 0..256 { + let mut modulus = U256::from(1u64) << shift; + let mut idx = 0; + while idx < 4 { + let x = F::from_u64((shift + (idx << 8)) as u64).unwrap(); + let y = F::from_u64(modulus.low_u32() as u64).unwrap(); + modulus >>= 32; + let z = F::from_u64(modulus.low_u32() as u64).unwrap(); + modulus >>= 32; + idx += 1; + + let row = [x, y, z]; + all_keys.push(row); + } + } + + LookupTable::new_from_content( + all_keys, + VM_SHIFT_TO_NUM_CONVERTER_TABLE_NAME.to_string(), + 1, + ) +} diff --git a/crates/zkevm_circuits/src/tables/conditional.rs b/crates/zkevm_circuits/src/tables/conditional.rs new file mode 100644 index 0000000..6351100 --- /dev/null +++ b/crates/zkevm_circuits/src/tables/conditional.rs @@ -0,0 +1,58 @@ +use super::*; +use boojum::cs::implementations::lookup_table::LookupTable; +use boojum::field::SmallField; + +pub const FLAGS_PACKED_ENCODING_BIT_WIDTH: usize = 3; + +pub(crate) fn integer_into_flags(encoding: u8) -> (bool, bool, bool) { + ( + (encoding & 0x1) != 0, + ((encoding & 0x2) != 0), + ((encoding & 0x4) != 0), + ) +} + +pub const VM_CONDITIONAL_RESOLUTION_TABLE_NAME: &'static str = "Conditional resolution table"; + +#[derive(Derivative)] +#[derivative(Clone, Copy, Debug, PartialEq, Eq)] +pub struct VMConditionalResolutionTable; + +pub fn create_conditionals_resolution_table() -> LookupTable { + let num_rows = 8 * 8; + + let mut all_keys = Vec::with_capacity(num_rows); + + let all_conditions = zkevm_opcode_defs::ALL_CONDITIONS; + use zkevm_opcode_defs::Condition; + for condition in all_conditions.iter() { + let x = condition.variant_index(); // integer encoding + for i in 0..(1 << FLAGS_PACKED_ENCODING_BIT_WIDTH) { + let (of, eq, gt) = integer_into_flags(i as u8); + let resolution = match condition { + Condition::Always => true, + Condition::Lt => of, + Condition::Eq => eq, + Condition::Gt => gt, + Condition::Ge => gt || eq, + Condition::Le => of || eq, + Condition::Ne => !eq, + Condition::GtOrLt => gt || of, + }; + + let row = [ + F::from_u64(x as u64).unwrap(), + F::from_u64(i as u64).unwrap(), + F::from_u64(resolution as u64).unwrap(), + ]; + + all_keys.push(row); + } + } + + LookupTable::new_from_content( + all_keys, + VM_CONDITIONAL_RESOLUTION_TABLE_NAME.to_string(), + 2, + ) +} diff --git a/crates/zkevm_circuits/src/tables/integer_to_boolean_mask.rs b/crates/zkevm_circuits/src/tables/integer_to_boolean_mask.rs new file mode 100644 index 0000000..83caf64 --- /dev/null +++ b/crates/zkevm_circuits/src/tables/integer_to_boolean_mask.rs @@ -0,0 +1,91 @@ +use super::*; +use boojum::cs::implementations::lookup_table::LookupTable; +use boojum::field::SmallField; + +pub const REG_IDX_TO_BITMASK_TABLE_NAME: &'static str = "Register index to bitmask table"; +pub const UMA_SHIFT_TO_BITMASK_TABLE_NAME: &'static str = "UMA shift to bitmask table"; +pub const VM_SUBPC_TO_BITMASK_TABLE_NAME: &'static str = "Sub PC to bitmask table"; + +#[derive(Derivative)] +#[derivative(Clone, Copy, Debug, PartialEq, Eq)] +pub struct RegisterIndexToBitmaskTable; + +#[derive(Derivative)] +#[derivative(Clone, Copy, Debug, PartialEq, Eq)] +pub struct UMAShiftToBitmaskTable; + +#[derive(Derivative)] +#[derivative(Clone, Copy, Debug, PartialEq, Eq)] +pub struct VMSubPCToBitmaskTable; + +pub fn create_integer_to_bitmask_table( + num_bits: usize, + name: &'static str, +) -> LookupTable { + assert!(num_bits <= 16); + let mut all_keys = Vec::with_capacity(1 << num_bits); + for integer in 0..(1u64 << num_bits) { + let key = smallvec::smallvec![F::from_u64_unchecked(integer as u64)]; + all_keys.push(key); + } + + LookupTable::new_from_keys_and_generation_function(&all_keys, name.to_string(), 1, |keys| { + let a = keys[0].as_u64_reduced(); + + let result = if a == 0 { + 0u64 + } else { + 1u64 << (a - 1) // 1 in some position + }; + + smallvec::smallvec![F::from_u64_unchecked(result), F::ZERO] + }) +} + +pub fn create_integer_set_ith_bit_table( + num_bits: usize, + name: &'static str, +) -> LookupTable { + assert!(num_bits <= 16); + let mut all_keys = Vec::with_capacity(1 << num_bits); + for integer in 0..(1u64 << num_bits) { + let key = smallvec::smallvec![F::from_u64_unchecked(integer as u64)]; + all_keys.push(key); + } + + LookupTable::new_from_keys_and_generation_function(&all_keys, name.to_string(), 1, |keys| { + let a = keys[0].as_u64_reduced(); + + let result = 1u64 << a; // 1 in some position + + smallvec::smallvec![F::from_u64_unchecked(result), F::ZERO] + }) +} + +pub fn create_subpc_bitmask_table() -> LookupTable { + create_integer_to_bitmask_table(2, VM_SUBPC_TO_BITMASK_TABLE_NAME) + + // let num_bits = 2; + // let mut all_keys = Vec::with_capacity(1 << num_bits); + // for integer in 0..(1u64 << num_bits) { + // let key = smallvec::smallvec![F::from_u64_unchecked(integer as u64)]; + // all_keys.push(key); + // } + + // LookupTable::new_from_keys_and_generation_function( + // &all_keys, + // VM_SUBPC_TO_BITMASK_TABLE_NAME.to_string(), + // 1, + // |keys| { + // let a = keys[0].as_u64_reduced(); + + // let result = if a == 0 { + // 0u64 + // } else { + // 1u64 << (a - 1) // 1 in some position + // }; + + // smallvec::smallvec![F::from_u64_unchecked(result), F::ZERO] + // }, + // ) +} diff --git a/crates/zkevm_circuits/src/tables/mod.rs b/crates/zkevm_circuits/src/tables/mod.rs new file mode 100644 index 0000000..32989e7 --- /dev/null +++ b/crates/zkevm_circuits/src/tables/mod.rs @@ -0,0 +1,13 @@ +use derivative::*; + +pub mod bitshift; +pub mod conditional; +pub mod integer_to_boolean_mask; +pub mod opcodes_decoding; +pub mod uma_ptr_read_cleanup; + +pub use self::bitshift::*; +pub use self::conditional::*; +pub use self::integer_to_boolean_mask::*; +pub use self::opcodes_decoding::*; +pub use self::uma_ptr_read_cleanup::*; diff --git a/crates/zkevm_circuits/src/tables/opcodes_decoding.rs b/crates/zkevm_circuits/src/tables/opcodes_decoding.rs new file mode 100644 index 0000000..cf1ff11 --- /dev/null +++ b/crates/zkevm_circuits/src/tables/opcodes_decoding.rs @@ -0,0 +1,38 @@ +use super::*; +use boojum::cs::implementations::lookup_table::LookupTable; +use boojum::field::SmallField; + +use zkevm_opcode_defs::OPCODES_TABLE_WIDTH; + +pub const VM_OPCODE_DECODING_AND_PRICING_TABLE_NAME: &'static str = + "Opcode decoding and pricing table"; + +#[derive(Derivative)] +#[derivative(Clone, Copy, Debug, PartialEq, Eq)] +pub struct VMOpcodeDecodingTable; + +pub fn create_opcodes_decoding_and_pricing_table() -> LookupTable { + let mut all_keys = Vec::with_capacity(1 << OPCODES_TABLE_WIDTH); + let num_rows = zkevm_opcode_defs::OPCODES_TABLE.len(); + assert_eq!(num_rows, 1 << OPCODES_TABLE_WIDTH); + + for x in 0..num_rows { + let opcode_as_integer = x as u64; + let opcode_props_encoding = zkevm_opcode_defs::OPCODES_PROPS_INTEGER_BITMASKS[x]; + let price = zkevm_opcode_defs::OPCODES_PRICES[x]; + + let row = [ + F::from_u64(opcode_as_integer).unwrap(), + F::from_u64(price as u64).unwrap(), + F::from_u64(opcode_props_encoding).unwrap(), + ]; + + all_keys.push(row); + } + + LookupTable::new_from_content( + all_keys, + VM_OPCODE_DECODING_AND_PRICING_TABLE_NAME.to_string(), + 1, + ) +} diff --git a/crates/zkevm_circuits/src/tables/uma_ptr_read_cleanup.rs b/crates/zkevm_circuits/src/tables/uma_ptr_read_cleanup.rs new file mode 100644 index 0000000..ab64839 --- /dev/null +++ b/crates/zkevm_circuits/src/tables/uma_ptr_read_cleanup.rs @@ -0,0 +1,40 @@ +use super::*; +use boojum::cs::implementations::lookup_table::LookupTable; +use boojum::field::SmallField; + +pub const UMA_PTR_READ_CLEANUP_TABLE_NAME: &'static str = "UMA PTR read cleanup mask table"; + +#[derive(Derivative)] +#[derivative(Clone, Copy, Debug, PartialEq, Eq)] +pub struct UMAPtrReadCleanupTable; + +pub fn create_uma_ptr_read_bitmask_table() -> LookupTable { + let num_keys = 32; + let mut all_keys = Vec::with_capacity(num_keys); + for integer in 0..num_keys { + let key = smallvec::smallvec![F::from_u64_unchecked(integer as u64)]; + all_keys.push(key); + } + + const FULL_MASK: u64 = (1u64 << 32) - 1; + + LookupTable::new_from_keys_and_generation_function( + &all_keys, + UMA_PTR_READ_CLEANUP_TABLE_NAME.to_string(), + 1, + |keys| { + let a = keys[0].as_u64_reduced(); + + let result = if a == 0 { + FULL_MASK + } else { + let mut tmp = FULL_MASK; + tmp -= (1u64 << a) - 1; + + tmp + }; + + smallvec::smallvec![F::from_u64_unchecked(result), F::ZERO] + }, + ) +} diff --git a/crates/zkevm_circuits/src/utils.rs b/crates/zkevm_circuits/src/utils.rs new file mode 100644 index 0000000..d0356d5 --- /dev/null +++ b/crates/zkevm_circuits/src/utils.rs @@ -0,0 +1,137 @@ +use boojum::algebraic_props::round_function::AlgebraicRoundFunction; +use boojum::cs::traits::cs::ConstraintSystem; +use boojum::cs::Variable; +use boojum::field::SmallField; +use boojum::gadgets::boolean::Boolean; +use boojum::gadgets::num::Num; +use boojum::gadgets::queue::QueueTailState; +use boojum::gadgets::traits::round_function::CircuitRoundFunction; +use boojum::gadgets::traits::selectable::Selectable; +use boojum::gadgets::u32::UInt32; + +pub fn produce_fs_challenges< + F: SmallField, + CS: ConstraintSystem, + R: CircuitRoundFunction + AlgebraicRoundFunction, + const N: usize, + const NUM_CHALLENGES: usize, + const NUM_REPETITIONS: usize, +>( + cs: &mut CS, + unsorted_tail: QueueTailState, + sorted_tail: QueueTailState, + _round_function: &R, +) -> [[Num; NUM_CHALLENGES]; NUM_REPETITIONS] { + let mut fs_input = vec![]; + fs_input.extend_from_slice(&unsorted_tail.tail); + fs_input.push(unsorted_tail.length.into_num()); + fs_input.extend_from_slice(&sorted_tail.tail); + fs_input.push(sorted_tail.length.into_num()); + + let mut state = R::create_empty_state(cs); + let length = UInt32::allocated_constant(cs, fs_input.len() as u32); + R::apply_length_specialization(cs, &mut state, length.get_variable()); + + let zero_num = Num::allocated_constant(cs, F::ZERO); + + let mut state = state.map(|el| Num::from_variable(el)); + + let mut it = fs_input.array_chunks::<8>(); + for chunk in &mut it { + let mut state_to_keep = [zero_num; 4]; + state_to_keep.copy_from_slice(&state[8..]); + state = R::absorb_with_replacement_over_nums(cs, *chunk, state_to_keep); + state = R::compute_round_function_over_nums(cs, state); + } + + let remainder = it.remainder(); + if remainder.len() != 0 { + let mut state_to_keep = [zero_num; 4]; + state_to_keep.copy_from_slice(&state[8..]); + let mut padded_chunk = [zero_num; 8]; + padded_chunk[..remainder.len()].copy_from_slice(remainder); + state = R::absorb_with_replacement_over_nums(cs, padded_chunk, state_to_keep); + state = R::compute_round_function_over_nums(cs, state); + } + + // now get as many as necessary + let max_to_take = 8; + let mut can_take = max_to_take; + + let one_num = Num::allocated_constant(cs, F::ONE); + + let mut result = [[one_num; NUM_CHALLENGES]; NUM_REPETITIONS]; + + for dst in result.iter_mut() { + for dst in dst.iter_mut().skip(1) { + if can_take == 0 { + state = R::compute_round_function_over_nums(cs, state); + can_take = max_to_take; + } + let el = state[max_to_take - can_take]; + can_take -= 1; + *dst = el; + } + } + + result +} + +// Strange signature of the function is due to const generics bugs +pub fn accumulate_grand_products< + F: SmallField, + CS: ConstraintSystem, + const ENCODING_LENGTH: usize, + const NUM_CHALLENGES: usize, + const NUM_REPETITIONS: usize, +>( + cs: &mut CS, + lhs_accumulator: &mut [Num; NUM_REPETITIONS], + rhs_accumulator: &mut [Num; NUM_REPETITIONS], + fs_challenges: &[[Num; NUM_CHALLENGES]; NUM_REPETITIONS], + lhs_encoding: &[Variable; ENCODING_LENGTH], + rhs_encoding: &[Variable; ENCODING_LENGTH], + should_accumulate: Boolean, +) { + assert!(ENCODING_LENGTH > 0); + assert_eq!(ENCODING_LENGTH + 1, NUM_CHALLENGES); + for ((challenges, lhs), rhs) in fs_challenges + .iter() + .zip(lhs_accumulator.iter_mut()) + .zip(rhs_accumulator.iter_mut()) + { + // additive parts + let mut lhs_contribution = challenges[ENCODING_LENGTH]; + let mut rhs_contribution = challenges[ENCODING_LENGTH]; + + for ((lhs_el, rhs_el), challenge) in lhs_encoding + .iter() + .zip(rhs_encoding.iter()) + .zip(challenges.iter()) + { + lhs_contribution = Num::fma( + cs, + &Num::from_variable(*lhs_el), + challenge, + &F::ONE, + &lhs_contribution, + &F::ONE, + ); + + rhs_contribution = Num::fma( + cs, + &Num::from_variable(*rhs_el), + challenge, + &F::ONE, + &rhs_contribution, + &F::ONE, + ); + } + + let new_lhs = lhs.mul(cs, &lhs_contribution); + let new_rhs = rhs.mul(cs, &rhs_contribution); + + *lhs = Num::conditionally_select(cs, should_accumulate, &new_lhs, &lhs); + *rhs = Num::conditionally_select(cs, should_accumulate, &new_rhs, &rhs); + } +} From 2c212fc335b1fb47a2db7564fb883d1542f7e9be Mon Sep 17 00:00:00 2001 From: Igor Aleksanov Date: Thu, 15 Aug 2024 14:16:56 +0400 Subject: [PATCH 4/7] Historical release: v0.141.1 --- crates/circuit_encodings/Cargo.toml | 8 +- crates/circuit_sequencer_api/Cargo.toml | 10 +- .../src/geometry_config.rs | 6 +- crates/zk_evm/.github/workflows/ci.yaml | 5 +- crates/zk_evm/Cargo.toml | 6 +- crates/zk_evm/eraLogo.svg | 13 - crates/zk_evm/src/opcodes/execution/add.rs | 1 - crates/zk_evm/src/opcodes/execution/binop.rs | 1 - .../zk_evm/src/opcodes/execution/context.rs | 1 - crates/zk_evm/src/opcodes/execution/div.rs | 1 - .../zk_evm/src/opcodes/execution/far_call.rs | 3 +- crates/zk_evm/src/opcodes/execution/jump.rs | 1 - crates/zk_evm/src/opcodes/execution/log.rs | 74 +- crates/zk_evm/src/opcodes/execution/mul.rs | 1 - .../zk_evm/src/opcodes/execution/near_call.rs | 1 - crates/zk_evm/src/opcodes/execution/noop.rs | 1 - crates/zk_evm/src/opcodes/execution/ptr.rs | 1 - crates/zk_evm/src/opcodes/execution/ret.rs | 30 +- crates/zk_evm/src/opcodes/execution/shift.rs | 1 - crates/zk_evm/src/opcodes/execution/sub.rs | 1 - crates/zk_evm/src/opcodes/execution/uma.rs | 3 +- crates/zk_evm/src/opcodes/parsing.rs | 1 - crates/zk_evm/src/testing/mod.rs | 16 +- crates/zk_evm/src/testing/tests/mod.rs | 57 +- .../testing/tests/precompiles/keccak256.rs | 226 ++- .../src/testing/tests/precompiles/mod.rs | 8 +- crates/zk_evm/src/testing/tests/trivial.rs | 11 +- crates/zk_evm/src/tests/assembly.rs | 468 ----- crates/zk_evm/src/tests/mod.rs | 1750 ----------------- crates/zk_evm/src/vm_state/cycle.rs | 27 +- crates/zk_evm/src/vm_state/helpers.rs | 6 +- crates/zk_evm/src/vm_state/mem_ops.rs | 6 +- crates/zk_evm/src/vm_state/mod.rs | 2 - crates/zk_evm/src/vm_state/pending_port.rs | 26 - crates/zk_evm_abstractions/.gitignore | 6 +- crates/zk_evm_abstractions/CONTRIBUTING.md | 45 +- crates/zk_evm_abstractions/Cargo.toml | 5 +- .../src/precompiles/ecrecover.rs | 35 +- .../src/precompiles/keccak256.rs | 212 +- .../src/precompiles/mod.rs | 16 +- .../zkevm_circuits/.github/workflows/ci.yaml | 2 +- crates/zkevm_circuits/Cargo.toml | 8 +- crates/zkevm_circuits/cs_derive/.gitignore | 3 - crates/zkevm_circuits/cs_derive/Cargo.toml | 15 - crates/zkevm_circuits/cs_derive/src/.DS_Store | Bin 6148 -> 0 bytes .../cs_derive/src/allocatable/mod.rs | 283 --- crates/zkevm_circuits/cs_derive/src/lib.rs | 100 - .../cs_derive/src/selectable/mod.rs | 105 - crates/zkevm_circuits/cs_derive/src/utils.rs | 167 -- .../cs_derive/src/var_length_encodable/mod.rs | 110 -- .../cs_derive/src/witness_hook/mod.rs | 124 -- .../src/base_structures/register/mod.rs | 20 + .../src/code_unpacker_sha256/mod.rs | 8 +- .../src/demux_log_queue/input.rs | 15 + .../zkevm_circuits/src/demux_log_queue/mod.rs | 8 +- .../zkevm_circuits/src/ecrecover/baseline.rs | 14 +- .../src/ecrecover/decomp_table.rs | 10 +- crates/zkevm_circuits/src/ecrecover/mod.rs | 2 +- .../src/ecrecover/naf_abs_div2_table.rs | 2 +- .../src/ecrecover/new_optimized.rs | 668 ++++++- .../secp256k1/fixed_base_mul_table.rs | 81 +- crates/zkevm_circuits/src/eip_4844/input.rs | 66 + crates/zkevm_circuits/src/eip_4844/mod.rs | 772 ++++++++ .../keccak256_round_function/buffer/mod.rs | 164 ++ .../src/keccak256_round_function/input.rs | 12 +- .../src/keccak256_round_function/mod.rs | 852 ++++++-- crates/zkevm_circuits/src/lib.rs | 2 + crates/zkevm_circuits/src/log_sorter/mod.rs | 8 +- .../main_vm/opcodes/call_ret_impl/far_call.rs | 9 + .../src/main_vm/opcodes/call_ret_impl/ret.rs | 18 +- .../zkevm_circuits/src/main_vm/opcodes/log.rs | 8 +- .../zkevm_circuits/src/main_vm/pre_state.rs | 34 +- crates/zkevm_circuits/src/main_vm/utils.rs | 5 +- .../zkevm_circuits/src/ram_permutation/mod.rs | 8 +- .../zkevm_circuits/src/scheduler/auxiliary.rs | 1 + .../src/scheduler/block_header/mod.rs | 11 + crates/zkevm_circuits/src/scheduler/input.rs | 7 + crates/zkevm_circuits/src/scheduler/mod.rs | 295 ++- .../src/sort_decommittment_requests/mod.rs | 8 +- .../storage_validity_by_grand_product/mod.rs | 13 +- crates/zkevm_circuits/src/utils.rs | 20 +- crates/zkevm_opcode_defs/Cargo.toml | 10 +- crates/zkevm_opcode_defs/deny.toml | 4 +- .../src/definitions/abi/precompile_call.rs | 34 +- .../zkevm_opcode_defs/src/definitions/add.rs | 8 + .../zkevm_opcode_defs/src/definitions/all.rs | 42 + .../src/definitions/binop.rs | 8 + .../src/definitions/context.rs | 8 + .../zkevm_opcode_defs/src/definitions/div.rs | 8 + .../src/definitions/far_call.rs | 8 + .../src/definitions/invalid_opcode.rs | 8 + .../zkevm_opcode_defs/src/definitions/jump.rs | 8 + .../zkevm_opcode_defs/src/definitions/log.rs | 14 +- .../zkevm_opcode_defs/src/definitions/mul.rs | 8 + .../src/definitions/near_call.rs | 8 + .../zkevm_opcode_defs/src/definitions/noop.rs | 8 + .../src/definitions/opcode_trait.rs | 2 + .../zkevm_opcode_defs/src/definitions/ptr.rs | 8 + .../zkevm_opcode_defs/src/definitions/ret.rs | 8 + .../src/definitions/shift.rs | 8 + .../zkevm_opcode_defs/src/definitions/sub.rs | 8 + .../zkevm_opcode_defs/src/definitions/uma.rs | 8 + crates/zkevm_opcode_defs/src/utils.rs | 10 + 103 files changed, 3446 insertions(+), 3940 deletions(-) delete mode 100644 crates/zk_evm/eraLogo.svg delete mode 100644 crates/zk_evm/src/tests/assembly.rs delete mode 100644 crates/zk_evm/src/tests/mod.rs delete mode 100644 crates/zk_evm/src/vm_state/pending_port.rs delete mode 100644 crates/zkevm_circuits/cs_derive/.gitignore delete mode 100644 crates/zkevm_circuits/cs_derive/Cargo.toml delete mode 100644 crates/zkevm_circuits/cs_derive/src/.DS_Store delete mode 100644 crates/zkevm_circuits/cs_derive/src/allocatable/mod.rs delete mode 100644 crates/zkevm_circuits/cs_derive/src/lib.rs delete mode 100644 crates/zkevm_circuits/cs_derive/src/selectable/mod.rs delete mode 100644 crates/zkevm_circuits/cs_derive/src/utils.rs delete mode 100644 crates/zkevm_circuits/cs_derive/src/var_length_encodable/mod.rs delete mode 100644 crates/zkevm_circuits/cs_derive/src/witness_hook/mod.rs create mode 100644 crates/zkevm_circuits/src/eip_4844/input.rs create mode 100644 crates/zkevm_circuits/src/eip_4844/mod.rs create mode 100644 crates/zkevm_circuits/src/keccak256_round_function/buffer/mod.rs diff --git a/crates/circuit_encodings/Cargo.toml b/crates/circuit_encodings/Cargo.toml index 949b413..c8a0b51 100644 --- a/crates/circuit_encodings/Cargo.toml +++ b/crates/circuit_encodings/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "circuit_encodings" -version = "0.140.1" +version = "0.141.1" edition = "2021" authors = ["The Matter Labs Team "] homepage = "https://zksync.io/" @@ -13,12 +13,14 @@ description = "ZKsync Era circuits encodings" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -zkevm_circuits = { version = "0.140", path = "../zkevm_circuits" } # Not pinned, because it's an old version used only by MultiVM. -zk_evm = { version = "0.140", path = "../zk_evm" } # Not pinned, because it's an old version used only by MultiVM +zkevm_circuits = { version = "0.141", path = "../zkevm_circuits" } # Not pinned, because it's an old dependency used by MultiVM +zk_evm = { version = "0.141", path = "../zk_evm" } # Not pinned, because it's an old dependency used by MultiVM + derivative = "2.2" serde = {version = "1", features = ["derive"]} + [features] default = [] log_tracing = ["zkevm_circuits/log_tracing"] diff --git a/crates/circuit_sequencer_api/Cargo.toml b/crates/circuit_sequencer_api/Cargo.toml index 4618212..dff6e06 100644 --- a/crates/circuit_sequencer_api/Cargo.toml +++ b/crates/circuit_sequencer_api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "circuit_sequencer_api" -version = "0.140.1" +version = "0.141.1" edition = "2021" authors = ["The Matter Labs Team "] homepage = "https://zksync.io/" @@ -13,16 +13,14 @@ description = "ZKsync Era circuits API for sequencer" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -circuit_encodings = { version = "0.140", path = "../circuit_encodings" } # Not pinned, because it's an old version used only by MultiVM - -zk_evm = { version = "0.140", path = "../zk_evm" } # Not pinned, because it's an old version used only by MultiVM -bellman = { package = "bellman_ce", version = "0" } # Not pinned, because it's an old version used only by MultiVM +circuit_encodings = { version = "0.141", path = "../circuit_encodings" } # Not pinned, because it's an old dependency used by MultiVM +zk_evm = { version = "0.141", path = "../zk_evm" } # Not pinned, because it's an old dependency used by MultiVM +bellman = { package = "bellman_ce", version = "0" } # Not pinned, because it's an old dependency used by MultiVM derivative = "2.2" serde = {version = "1", features = ["derive"]} rayon = "1.10" - [features] default = [] diff --git a/crates/circuit_sequencer_api/src/geometry_config.rs b/crates/circuit_sequencer_api/src/geometry_config.rs index b1096d7..9c3ff16 100644 --- a/crates/circuit_sequencer_api/src/geometry_config.rs +++ b/crates/circuit_sequencer_api/src/geometry_config.rs @@ -4,7 +4,7 @@ use crate::toolset::GeometryConfig; pub const fn get_geometry_config() -> GeometryConfig { GeometryConfig { - cycles_per_vm_snapshot: 5692, + cycles_per_vm_snapshot: 5585, cycles_code_decommitter_sorter: 117500, cycles_per_log_demuxer: 58750, cycles_per_storage_sorter: 46921, @@ -12,9 +12,9 @@ pub const fn get_geometry_config() -> GeometryConfig { cycles_per_ram_permutation: 136714, cycles_per_code_decommitter: 2845, cycles_per_storage_application: 33, - cycles_per_keccak256_circuit: 672, + cycles_per_keccak256_circuit: 293, cycles_per_sha256_circuit: 2206, - cycles_per_ecrecover_circuit: 2, + cycles_per_ecrecover_circuit: 7, limit_for_l1_messages_pudata_hasher: 774, } } diff --git a/crates/zk_evm/.github/workflows/ci.yaml b/crates/zk_evm/.github/workflows/ci.yaml index 8b2b519..9b8e22e 100644 --- a/crates/zk_evm/.github/workflows/ci.yaml +++ b/crates/zk_evm/.github/workflows/ci.yaml @@ -10,9 +10,10 @@ jobs: - uses: actions/checkout@v3 - uses: actions-rust-lang/setup-rust-toolchain@v1 with: - toolchain: nightly-2023-04-17 + toolchain: stable - run: cargo build --verbose --all-features - - run: RUSTFLAGS="-Awarnings" cargo test --verbose --all-features +# OOMs on ubuntu-latest. +# - run: RUSTFLAGS="-Awarnings" cargo test --verbose --all-features formatting: name: cargo fmt diff --git a/crates/zk_evm/Cargo.toml b/crates/zk_evm/Cargo.toml index ee2bf35..dba036d 100644 --- a/crates/zk_evm/Cargo.toml +++ b/crates/zk_evm/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zk_evm" -version = "0.140.0" +version = "0.141.0" edition = "2021" authors = ["The Matter Labs Team "] homepage = "https://zksync.io/" @@ -18,8 +18,8 @@ serde_json = "1.0" anyhow = "1.0" num = { version = "0.4"} static_assertions = "1" -zkevm_opcode_defs = { version = "=0.132.0", path = "../zkevm_opcode_defs" } -zk_evm_abstractions = { version = "=0.140.0", path = "../zk_evm_abstractions" } +zkevm_opcode_defs = { version = "=0.141.0", path = "../zkevm_opcode_defs" } +zk_evm_abstractions = { version = "=0.141.0", path = "../zk_evm_abstractions" } lazy_static = "1.4" [dev-dependencies] diff --git a/crates/zk_evm/eraLogo.svg b/crates/zk_evm/eraLogo.svg deleted file mode 100644 index 6ec790c..0000000 --- a/crates/zk_evm/eraLogo.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/crates/zk_evm/src/opcodes/execution/add.rs b/crates/zk_evm/src/opcodes/execution/add.rs index d53ca88..5f629be 100644 --- a/crates/zk_evm/src/opcodes/execution/add.rs +++ b/crates/zk_evm/src/opcodes/execution/add.rs @@ -2,7 +2,6 @@ use super::*; impl> DecodedOpcode { pub fn add_opcode_apply< - 'a, S: zk_evm_abstractions::vm::Storage, M: zk_evm_abstractions::vm::Memory, EV: zk_evm_abstractions::vm::EventSink, diff --git a/crates/zk_evm/src/opcodes/execution/binop.rs b/crates/zk_evm/src/opcodes/execution/binop.rs index e31a421..9a64c00 100644 --- a/crates/zk_evm/src/opcodes/execution/binop.rs +++ b/crates/zk_evm/src/opcodes/execution/binop.rs @@ -3,7 +3,6 @@ use zkevm_opcode_defs::{BinopOpcode, Opcode}; impl> DecodedOpcode { pub fn binop_opcode_apply< - 'a, S: zk_evm_abstractions::vm::Storage, M: zk_evm_abstractions::vm::Memory, EV: zk_evm_abstractions::vm::EventSink, diff --git a/crates/zk_evm/src/opcodes/execution/context.rs b/crates/zk_evm/src/opcodes/execution/context.rs index a6a3f9f..8e0b3cc 100644 --- a/crates/zk_evm/src/opcodes/execution/context.rs +++ b/crates/zk_evm/src/opcodes/execution/context.rs @@ -4,7 +4,6 @@ use zkevm_opcode_defs::{ContextOpcode, Opcode}; impl> DecodedOpcode { pub fn context_opcode_apply< - 'a, S: zk_evm_abstractions::vm::Storage, M: zk_evm_abstractions::vm::Memory, EV: zk_evm_abstractions::vm::EventSink, diff --git a/crates/zk_evm/src/opcodes/execution/div.rs b/crates/zk_evm/src/opcodes/execution/div.rs index f09d9b9..b5e834f 100644 --- a/crates/zk_evm/src/opcodes/execution/div.rs +++ b/crates/zk_evm/src/opcodes/execution/div.rs @@ -2,7 +2,6 @@ use super::*; impl> DecodedOpcode { pub fn div_opcode_apply< - 'a, S: zk_evm_abstractions::vm::Storage, M: zk_evm_abstractions::vm::Memory, EV: zk_evm_abstractions::vm::EventSink, diff --git a/crates/zk_evm/src/opcodes/execution/far_call.rs b/crates/zk_evm/src/opcodes/execution/far_call.rs index 412f910..7d1e040 100644 --- a/crates/zk_evm/src/opcodes/execution/far_call.rs +++ b/crates/zk_evm/src/opcodes/execution/far_call.rs @@ -33,7 +33,6 @@ use zkevm_opcode_defs::{FarCallABI, FarCallForwardPageType, FarCallOpcode, FatPo impl> DecodedOpcode { pub fn far_call_opcode_apply< - 'a, S: zk_evm_abstractions::vm::Storage, M: zk_evm_abstractions::vm::Memory, EV: zk_evm_abstractions::vm::EventSink, @@ -96,6 +95,7 @@ impl> DecodedOpcode { let remaining_ergs = current_stack.ergs_remaining; let current_context_u128 = current_stack.context_u128_value; + #[allow(dropping_references)] drop(current_stack); let timestamp_for_storage_read = vm_state.timestamp_for_first_decommit_or_precompile_read(); @@ -368,6 +368,7 @@ impl> DecodedOpcode { FarCallForwardPageType::ForwardFatPointer => 0u32, }; + #[allow(dropping_references)] drop(current_stack_mut); // MEMORY_GROWTH_ERGS_PER_BYTE is always 1 diff --git a/crates/zk_evm/src/opcodes/execution/jump.rs b/crates/zk_evm/src/opcodes/execution/jump.rs index 85cc4dc..4c314df 100644 --- a/crates/zk_evm/src/opcodes/execution/jump.rs +++ b/crates/zk_evm/src/opcodes/execution/jump.rs @@ -2,7 +2,6 @@ use super::*; impl> DecodedOpcode { pub fn jump_opcode_apply< - 'a, S: zk_evm_abstractions::vm::Storage, M: zk_evm_abstractions::vm::Memory, EV: zk_evm_abstractions::vm::EventSink, diff --git a/crates/zk_evm/src/opcodes/execution/log.rs b/crates/zk_evm/src/opcodes/execution/log.rs index d99ca78..d2708e2 100644 --- a/crates/zk_evm/src/opcodes/execution/log.rs +++ b/crates/zk_evm/src/opcodes/execution/log.rs @@ -1,9 +1,7 @@ use super::*; use zk_evm_abstractions::queries::LogQuery; -use zkevm_opcode_defs::{ - LogOpcode, Opcode, PrecompileCallABI, PrecompileCallInnerABI, FIRST_MESSAGE_FLAG_IDX, -}; +use zkevm_opcode_defs::{LogOpcode, Opcode, PrecompileCallABI, FIRST_MESSAGE_FLAG_IDX}; use zkevm_opcode_defs::system_params::{ EVENT_AUX_BYTE, L1_MESSAGE_AUX_BYTE, PRECOMPILE_AUX_BYTE, STORAGE_AUX_BYTE, @@ -11,7 +9,6 @@ use zkevm_opcode_defs::system_params::{ impl> DecodedOpcode { pub fn log_opcode_apply< - 'a, S: zk_evm_abstractions::vm::Storage, M: zk_evm_abstractions::vm::Memory, EV: zk_evm_abstractions::vm::EventSink, @@ -78,6 +75,8 @@ impl> DecodedOpcode { let current_context = vm_state.local_state.callstack.get_current_stack(); let address = current_context.this_address; let shard_id = current_context.this_shard_id; + + #[allow(dropping_references)] drop(current_context); // we do not need all the values here, but we DO need the written value @@ -156,7 +155,10 @@ impl> DecodedOpcode { let current_context = vm_state.local_state.callstack.get_current_stack(); let address = current_context.this_address; let shard_id = current_context.this_shard_id; + + #[allow(dropping_references)] drop(current_context); + match inner_variant { LogOpcode::StorageRead => { assert!(not_enough_power == false); @@ -261,51 +263,42 @@ impl> DecodedOpcode { return; } - let precompile_abi = PrecompileCallABI::from_u256(src0); - let PrecompileCallABI { - input_memory_offset, - input_memory_length, - output_memory_offset, - output_memory_length, - per_precompile_interpreted, - } = precompile_abi; - + let mut precompile_abi = PrecompileCallABI::from_u256(src0); // normal execution vm_state .local_state .callstack .get_current_stack_mut() .ergs_remaining = ergs_remaining; - let memory_page_to_read = CallStackEntry::::heap_page_from_base( - vm_state - .local_state - .callstack - .get_current_stack() - .base_memory_page, - ); - let memory_page_to_write = CallStackEntry::::heap_page_from_base( - vm_state - .local_state - .callstack - .get_current_stack() - .base_memory_page, - ); + if precompile_abi.memory_page_to_read == 0 { + let memory_page_to_read = CallStackEntry::::heap_page_from_base( + vm_state + .local_state + .callstack + .get_current_stack() + .base_memory_page, + ); + precompile_abi.memory_page_to_read = memory_page_to_read.0; + } + + if precompile_abi.memory_page_to_write == 0 { + let memory_page_to_write = CallStackEntry::::heap_page_from_base( + vm_state + .local_state + .callstack + .get_current_stack() + .base_memory_page, + ); + precompile_abi.memory_page_to_write = memory_page_to_write.0; + } let timestamp_to_read = vm_state.timestamp_for_first_decommit_or_precompile_read(); + debug_assert!(timestamp_to_read == timestamp_for_log); let timestamp_to_write = vm_state.timestamp_for_second_decommit_or_precompile_write(); - assert!(timestamp_to_read.0 + 1 == timestamp_to_write.0); - - let precompile_inner_abi = PrecompileCallInnerABI { - input_memory_offset, - input_memory_length, - output_memory_offset, - output_memory_length, - memory_page_to_read: memory_page_to_read.0, - memory_page_to_write: memory_page_to_write.0, - precompile_interpreted_data: per_precompile_interpreted, - }; - let precompile_inner_abi = precompile_inner_abi.to_u256(); + debug_assert!(timestamp_to_read.0 + 1 == timestamp_to_write.0); + + let precompile_abi_encoded = precompile_abi.to_u256(); let query = LogQuery { timestamp: timestamp_for_log, @@ -313,13 +306,14 @@ impl> DecodedOpcode { aux_byte: PRECOMPILE_AUX_BYTE, shard_id, address, - key: precompile_inner_abi, + key: precompile_abi_encoded, read_value: U256::zero(), written_value: U256::zero(), rw_flag: false, rollback: false, is_service: is_first_message, }; + vm_state.call_precompile(vm_state.local_state.monotonic_cycle_counter, query); let result = PrimitiveValue { value: U256::from(1u64), diff --git a/crates/zk_evm/src/opcodes/execution/mul.rs b/crates/zk_evm/src/opcodes/execution/mul.rs index 21f4415..253e8bd 100644 --- a/crates/zk_evm/src/opcodes/execution/mul.rs +++ b/crates/zk_evm/src/opcodes/execution/mul.rs @@ -2,7 +2,6 @@ use super::*; impl> DecodedOpcode { pub fn mul_opcode_apply< - 'a, S: zk_evm_abstractions::vm::Storage, M: zk_evm_abstractions::vm::Memory, EV: zk_evm_abstractions::vm::EventSink, diff --git a/crates/zk_evm/src/opcodes/execution/near_call.rs b/crates/zk_evm/src/opcodes/execution/near_call.rs index fbe7eed..714eb3f 100644 --- a/crates/zk_evm/src/opcodes/execution/near_call.rs +++ b/crates/zk_evm/src/opcodes/execution/near_call.rs @@ -4,7 +4,6 @@ use super::*; impl> DecodedOpcode { pub fn near_call_opcode_apply< - 'a, S: zk_evm_abstractions::vm::Storage, M: zk_evm_abstractions::vm::Memory, EV: zk_evm_abstractions::vm::EventSink, diff --git a/crates/zk_evm/src/opcodes/execution/noop.rs b/crates/zk_evm/src/opcodes/execution/noop.rs index 1b2b8f8..f7c3e53 100644 --- a/crates/zk_evm/src/opcodes/execution/noop.rs +++ b/crates/zk_evm/src/opcodes/execution/noop.rs @@ -2,7 +2,6 @@ use super::*; impl> DecodedOpcode { pub fn noop_opcode_apply< - 'a, S: zk_evm_abstractions::vm::Storage, M: zk_evm_abstractions::vm::Memory, EV: zk_evm_abstractions::vm::EventSink, diff --git a/crates/zk_evm/src/opcodes/execution/ptr.rs b/crates/zk_evm/src/opcodes/execution/ptr.rs index 3623954..244b319 100644 --- a/crates/zk_evm/src/opcodes/execution/ptr.rs +++ b/crates/zk_evm/src/opcodes/execution/ptr.rs @@ -4,7 +4,6 @@ use zkevm_opcode_defs::{FatPointer, Opcode, PtrOpcode}; impl> DecodedOpcode { pub fn ptr_opcode_apply< - 'a, S: zk_evm_abstractions::vm::Storage, M: zk_evm_abstractions::vm::Memory, EV: zk_evm_abstractions::vm::EventSink, diff --git a/crates/zk_evm/src/opcodes/execution/ret.rs b/crates/zk_evm/src/opcodes/execution/ret.rs index 0803f21..76e71df 100644 --- a/crates/zk_evm/src/opcodes/execution/ret.rs +++ b/crates/zk_evm/src/opcodes/execution/ret.rs @@ -7,7 +7,6 @@ use zkevm_opcode_defs::{FatPointer, Opcode, RetABI, RetForwardPageType, RetOpcod impl> DecodedOpcode { pub fn ret_opcode_apply< - 'a, S: zk_evm_abstractions::vm::Storage, M: zk_evm_abstractions::vm::Memory, EV: zk_evm_abstractions::vm::EventSink, @@ -28,10 +27,19 @@ impl> DecodedOpcode { vm_state.local_state.flags.reset(); let PrimitiveValue { - value: src0, - is_pointer: src0_is_ptr, + value: mut src0, + is_pointer: mut src0_is_ptr, } = src0; + // on panic, we should never return any data. in this case, zero out src0 data + match inner_variant { + RetOpcode::Panic => { + src0 = U256::default(); + src0_is_ptr = false; + } + _ => {} + } + let ret_abi = RetABI::from_u256(src0); // we want to mark with one that was will become a new current (taken from stack) @@ -128,9 +136,9 @@ impl> DecodedOpcode { } } } - RetOpcode::Panic => { - memory_quasi_fat_pointer = FatPointer::empty(); - } + // data should be zeroed out for panic case, both for caller case and malformed + // pointer case + _ => {} } // potentially pay for memory growth @@ -180,6 +188,8 @@ impl> DecodedOpcode { // we do nothing with it later on, so just keep returndata page, and set zeroes for other Some(memory_quasi_fat_pointer) }; + + #[allow(dropping_references)] drop(current_callstack); // done with exceptions, so we can pop the callstack entry @@ -240,6 +250,14 @@ impl> DecodedOpcode { // just use a saved value } + // grow memory on near call + if finished_callstack.is_local_frame == true { + assert!(finished_callstack.heap_bound >= next_context.heap_bound); + assert!(finished_callstack.aux_heap_bound >= next_context.aux_heap_bound); + next_context.heap_bound = finished_callstack.heap_bound; + next_context.aux_heap_bound = finished_callstack.aux_heap_bound; + } + // and set flag on panic if inner_variant == RetOpcode::Panic { vm_state.local_state.flags.overflow_or_less_than_flag = true; diff --git a/crates/zk_evm/src/opcodes/execution/shift.rs b/crates/zk_evm/src/opcodes/execution/shift.rs index 010181a..b51858b 100644 --- a/crates/zk_evm/src/opcodes/execution/shift.rs +++ b/crates/zk_evm/src/opcodes/execution/shift.rs @@ -6,7 +6,6 @@ use zkevm_opcode_defs::{Opcode, ShiftOpcode}; impl> DecodedOpcode { pub fn shift_opcode_apply< - 'a, S: zk_evm_abstractions::vm::Storage, M: zk_evm_abstractions::vm::Memory, EV: zk_evm_abstractions::vm::EventSink, diff --git a/crates/zk_evm/src/opcodes/execution/sub.rs b/crates/zk_evm/src/opcodes/execution/sub.rs index 19aec14..bf18f35 100644 --- a/crates/zk_evm/src/opcodes/execution/sub.rs +++ b/crates/zk_evm/src/opcodes/execution/sub.rs @@ -2,7 +2,6 @@ use super::*; impl> DecodedOpcode { pub fn sub_opcode_apply< - 'a, S: zk_evm_abstractions::vm::Storage, M: zk_evm_abstractions::vm::Memory, EV: zk_evm_abstractions::vm::EventSink, diff --git a/crates/zk_evm/src/opcodes/execution/uma.rs b/crates/zk_evm/src/opcodes/execution/uma.rs index 72b07b7..f05c990 100644 --- a/crates/zk_evm/src/opcodes/execution/uma.rs +++ b/crates/zk_evm/src/opcodes/execution/uma.rs @@ -24,7 +24,6 @@ bitflags! { impl> DecodedOpcode { pub fn uma_opcode_apply< - 'a, S: zk_evm_abstractions::vm::Storage, M: zk_evm_abstractions::vm::Memory, EV: zk_evm_abstractions::vm::EventSink, @@ -216,6 +215,8 @@ impl> DecodedOpcode { exceptions.set(UMAExceptionFlags::NOT_ENOUGH_ERGS_TO_GROW_MEMORY, true); } current_callstack_mut.ergs_remaining = ergs_after_memory_growth; + + #[allow(dropping_references)] drop(current_callstack_mut); // we will set panic if any exception was triggered diff --git a/crates/zk_evm/src/opcodes/parsing.rs b/crates/zk_evm/src/opcodes/parsing.rs index 6db4127..da73244 100644 --- a/crates/zk_evm/src/opcodes/parsing.rs +++ b/crates/zk_evm/src/opcodes/parsing.rs @@ -45,7 +45,6 @@ impl> DecodedOpcode { } pub fn apply< - 'a, S: zk_evm_abstractions::vm::Storage, M: zk_evm_abstractions::vm::Memory, EV: zk_evm_abstractions::vm::EventSink, diff --git a/crates/zk_evm/src/testing/mod.rs b/crates/zk_evm/src/testing/mod.rs index 45f82b8..205c0a6 100644 --- a/crates/zk_evm/src/testing/mod.rs +++ b/crates/zk_evm/src/testing/mod.rs @@ -8,20 +8,10 @@ pub mod simple_tracer; pub mod storage; use self::storage::InMemoryStorage; -use crate::vm_state::VmState; use crate::witness_trace::DummyTracer; use zk_evm_abstractions::precompiles::DefaultPrecompilesProcessor; use zk_evm_abstractions::queries::LogQuery; -pub type BasicTestingVmState = VmState< - InMemoryStorage, - SimpleMemory, - InMemoryEventSink, - DefaultPrecompilesProcessor, - SimpleDecommitter, - DummyTracer, ->; - pub struct BasicTestingTools { pub storage: InMemoryStorage, pub memory: SimpleMemory, @@ -50,7 +40,7 @@ pub fn create_default_testing_tools() -> BasicTestingTools { } pub fn get_final_net_states( - vm: BasicTestingVmState, + tools: BasicTestingTools, ) -> ( Vec, [HashMap>; NUM_SHARDS], @@ -59,12 +49,12 @@ pub fn get_final_net_states( Vec, SimpleMemory, ) { - let BasicTestingVmState { + let BasicTestingTools:: { storage, event_sink, memory, .. - } = vm; + } = tools; let final_storage_state = storage.inner.clone(); let (full_storage_access_history, _per_slot_history) = storage.flatten_and_net_history(); diff --git a/crates/zk_evm/src/testing/tests/mod.rs b/crates/zk_evm/src/testing/tests/mod.rs index 16ed0bb..360dbbf 100644 --- a/crates/zk_evm/src/testing/tests/mod.rs +++ b/crates/zk_evm/src/testing/tests/mod.rs @@ -1,59 +1,6 @@ use super::*; use zk_evm_abstractions::aux::MemoryPage; -use zkevm_opcode_defs::system_params::BOOTLOADER_FORMAL_ADDRESS; -use crate::vm_state::*; -use crate::{ - block_properties::BlockProperties, - reference_impls::{event_sink::InMemoryEventSink, memory::SimpleMemory}, - testing::storage::InMemoryStorage, - vm_state::VmState, - witness_trace::DummyTracer, -}; - -pub fn create_default_block_info() -> BlockProperties { - BlockProperties { - default_aa_code_hash: U256::zero(), - zkporter_is_available: true, - } -} - -pub fn create_initial_vm_state_for_basic_testing( - tools: BasicTestingTools, - block_properties: BlockProperties, -) -> BasicTestingVmState { - let mut vm = VmState::empty_state( - tools.storage, - tools.memory, - tools.event_sink, - tools.precompiles_processor, - tools.decommittment_processor, - tools.witness_tracer, - block_properties, - ); - - let bootloader_context = CallStackEntry { - this_address: *BOOTLOADER_FORMAL_ADDRESS, - msg_sender: Address::zero(), - code_address: *BOOTLOADER_FORMAL_ADDRESS, - base_memory_page: MemoryPage(zkevm_opcode_defs::BOOTLOADER_BASE_PAGE), - code_page: MemoryPage(zkevm_opcode_defs::BOOTLOADER_CODE_PAGE), - sp: 0u16, - pc: 0u16, - exception_handler_location: 0u16, - ergs_remaining: zkevm_opcode_defs::system_params::VM_INITIAL_FRAME_ERGS, - this_shard_id: 0u8, - caller_shard_id: 0u8, - code_shard_id: 0u8, - is_static: false, - is_local_frame: false, - context_u128_value: 0, - heap_bound: 0u32, - aux_heap_bound: 0u32, - }; - - vm.push_bootloader_context(0, bootloader_context); - - vm -} +#[cfg(test)] +mod precompiles; diff --git a/crates/zk_evm/src/testing/tests/precompiles/keccak256.rs b/crates/zk_evm/src/testing/tests/precompiles/keccak256.rs index ee1e743..d4e62e2 100644 --- a/crates/zk_evm/src/testing/tests/precompiles/keccak256.rs +++ b/crates/zk_evm/src/testing/tests/precompiles/keccak256.rs @@ -1,138 +1,196 @@ use super::*; -use crate::precompiles::keccak256::*; - -fn pad_and_fill_memory(input: &[u8], page: u32, memory: &mut M) -> u16 { - let mut padded = vec![]; - padded.extend_from_slice(input); - - let block_size = KECCAK_RATE_IN_U64_WORDS * 8; - let last_block_size = padded.len() % block_size; - let padlen = block_size - last_block_size; - if padlen == 1 { - padded.push(0x81); - } else { - padded.push(0x01); - padded.extend(std::iter::repeat(0u8).take(padlen - 2)); - padded.push(0x80); - } - - assert_eq!(padded.len() % block_size, 0); - - let num_rounds = padded.len() / block_size; - - let mut num_rounds_u256 = U256::zero(); - num_rounds_u256.0[0] = num_rounds as u64; - println!("Num rounds = {}", num_rounds_u256); - let mut location = MemoryLocation {page: MemoryPage(page), index: MemoryIndex(0)}; - let num_rounds_query = MemoryQuery { - timestamp: Timestamp(0u32), - location, - value: num_rounds_u256, - rw_flag: true - }; - - let _ = memory.execute_partial_query(num_rounds_query); - - let total_len_as_u64_words = padded.len() / 8; - let mut num_words = total_len_as_u64_words / 4; - if total_len_as_u64_words % 4 != 0 { - num_words += 1; - } - - let mut chunk_iter = padded.chunks_exact(8); - - for _word in 0..num_words { - location.index.0 += 1; - let mut value = U256::zero(); - for i in (0..4).rev() { - if let Some(chunk) = chunk_iter.next() { - let as_u64 = u64::from_be_bytes(chunk.try_into().unwrap()); - value.0[i] = as_u64; +use zk_evm_abstractions::auxiliary::*; +use zk_evm_abstractions::queries::MemoryQuery; +use zk_evm_abstractions::vm::Memory; +use zk_evm_abstractions::vm::MemoryType; +use zk_evm_abstractions::vm::PrecompilesProcessor; +use zkevm_opcode_defs::PrecompileCallABI; + +fn bytes_to_u256_words(input: Vec, unalignement: usize) -> Vec { + let mut result = vec![]; + let mut it = std::iter::repeat(0xffu8) + .take(unalignement) + .chain(input.into_iter()); + 'outer: loop { + let mut done = false; + let mut buffer = [0u8; 32]; + for (idx, dst) in buffer.iter_mut().enumerate() { + if let Some(src) = it.next() { + *dst = src; + } else { + done = true; + if idx == 0 { + break 'outer; + } + break; } } + let el = U256::from_big_endian(&buffer); + result.push(el); + if done { + break 'outer; + } + } - let data_query = MemoryQuery { + result +} + +fn pad_and_fill_memory( + input: &[u8], + page: u32, + memory: &mut M, + unalignment: u32, +) -> u32 { + let input = input.to_vec(); + let words = bytes_to_u256_words(input, unalignment as usize); + let mut index = 0u32; + let num_words = words.len() as u32; + + for word in words.into_iter() { + let location = MemoryLocation { + page: MemoryPage(page), + index: MemoryIndex(index), + memory_type: MemoryType::Heap, + }; + let num_rounds_query = MemoryQuery { timestamp: Timestamp(0u32), location, - value, - rw_flag: true + value: word, + value_is_pointer: false, + rw_flag: true, }; - let _ = memory.execute_partial_query(data_query); + let _ = memory.execute_partial_query(1, num_rounds_query); + index += 1; } - assert!(chunk_iter.remainder().len() == 0); - - (1 + num_words) as u16 + num_words } use sha3::Digest; use sha3::Keccak256; -fn run_keccak256_test_inner(input: &[u8]) -> (Vec<[u8; 32]>, std::ops::Range) { +fn run_keccak256_test_inner( + input: &[u8], + unalignment: u32, +) -> (Vec<[u8; 32]>, std::ops::Range) { let mut memory = SimpleMemory::new(); + + let input_memory_page = 4u32; + let output_memory_page = 4u32; + + memory.heaps.push(( + (input_memory_page, vec![U256::zero(); 1 << 10]), + (0, vec![U256::zero(); 0]), + )); + memory.page_numbers_indirections.insert( + input_memory_page, + reference_impls::memory::Indirection::Heap(1), + ); let mut precompiles_processor = DefaultPrecompilesProcessor::; let mut hasher = Keccak256::default(); hasher.update(input); let result = hasher.finalize(); - let bytes: &[u8] = result.as_ref(); - println!("{}", hex::encode(bytes)); + let expected_output: &[u8] = result.as_ref(); // fill the memory - let num_words_used = pad_and_fill_memory(input, 0u32, &mut memory); - - let precompile_call_params = PrecompileCallParams { - input_location: MemoryLocation {page: MemoryPage(0u32), index: MemoryIndex(0u16)}, - output_location: MemoryLocation {page: MemoryPage(0u32), index: MemoryIndex(num_words_used)}, - timestamp_for_input_read: Timestamp(1u32), - timestamp_for_output_write: Timestamp(2u32), + let num_words_used = pad_and_fill_memory(input, input_memory_page, &mut memory, unalignment); + let input_byte_offset = unalignment; + let input_length = input.len(); + + let precompile_abi = PrecompileCallABI { + input_memory_offset: input_byte_offset, + input_memory_length: input_length as u32, + output_memory_offset: num_words_used as u32, + output_memory_length: 0, + memory_page_to_read: input_memory_page, + memory_page_to_write: output_memory_page, + precompile_interpreted_data: 0, }; - let address = Address::from_low_u64_be(KECCAK256_ROUND_FUNCTION_PRECOMPILE_ADDRESS as u64); + let address = + *zkevm_opcode_defs::system_params::KECCAK256_ROUND_FUNCTION_PRECOMPILE_FORMAL_ADDRESS; let precompile_query = LogQuery { - timestamp: precompile_call_params.timestamp_for_input_read, + timestamp: Timestamp(1), tx_number_in_block: 0, shard_id: 0, - aux_byte: PRECOMPILE_AUX_BYTE, + aux_byte: zkevm_opcode_defs::system_params::PRECOMPILE_AUX_BYTE, address, - key: U256::zero(), - read_value: precompile_call_params.encode_into_log_value(), + key: precompile_abi.to_u256(), + read_value: U256::zero(), written_value: U256::zero(), rw_flag: false, rollback: false, is_service: false, }; - let _ = precompiles_processor.execute_precompile(precompile_query, &mut memory); + let _ = precompiles_processor.execute_precompile(4, precompile_query, &mut memory); - let range = 0u16..(num_words_used + 1); - let content = memory.dump_page_content(0u32, range.clone()); - let expected_output = content.last().copied().unwrap(); + let range = 0u32..(num_words_used + 1); + let content = memory.dump_page_content(output_memory_page, range.clone()); + let output = content.last().copied().unwrap(); - assert_eq!(&expected_output[..], bytes); + dbg!(hex::encode(&expected_output)); + dbg!(hex::encode(&output)); + + assert_eq!(&expected_output[..], &output[..]); (content, range) } #[test] fn test_empty_keccak256() { - let (content, range) = run_keccak256_test_inner(&[]); + let (content, range) = run_keccak256_test_inner(&[], 0); pretty_print_memory_dump(&content, range); } #[test] -fn test_few_rounds_of_keccak256() { - let data = vec![255u8; 256]; - let (content, range) = run_keccak256_test_inner(&data); +fn test_empty_keccak256_unaligned() { + let (content, range) = run_keccak256_test_inner(&[], 31); pretty_print_memory_dump(&content, range); } #[test] -fn test_very_long_keccak256() { - let data = vec![255u8; 10_000]; - let (content, range) = run_keccak256_test_inner(&data); +fn test_one_round_of_keccak256() { + let data = vec![123u8; 50]; + let (content, range) = run_keccak256_test_inner(&data, 0); pretty_print_memory_dump(&content, range); -} \ No newline at end of file +} + +#[test] +fn test_one_round_of_keccak256_unaligned() { + let data = vec![123u8; 50]; + let (content, range) = run_keccak256_test_inner(&data, 31); + pretty_print_memory_dump(&content, range); +} + +#[test] +fn test_one_round_of_keccak256_with_full_paddings() { + let data = vec![123u8; 136]; + let (content, range) = run_keccak256_test_inner(&data, 0); + pretty_print_memory_dump(&content, range); +} + +#[test] +fn test_one_round_of_keccak256_with_full_paddings_unaligned() { + let data = vec![123u8; 136]; + let (content, range) = run_keccak256_test_inner(&data, 31); + pretty_print_memory_dump(&content, range); +} + +#[test] +fn test_two_rounds_of_keccak256() { + let data = vec![123u8; 200]; + let (content, range) = run_keccak256_test_inner(&data, 0); + pretty_print_memory_dump(&content, range); +} + +#[test] +fn test_two_rounds_of_keccak256_unaligned() { + let data = vec![123u8; 200]; + let (content, range) = run_keccak256_test_inner(&data, 31); + pretty_print_memory_dump(&content, range); +} diff --git a/crates/zk_evm/src/testing/tests/precompiles/mod.rs b/crates/zk_evm/src/testing/tests/precompiles/mod.rs index 21ad581..0706c4c 100644 --- a/crates/zk_evm/src/testing/tests/precompiles/mod.rs +++ b/crates/zk_evm/src/testing/tests/precompiles/mod.rs @@ -1,14 +1,14 @@ use super::*; mod keccak256; -mod sha256; -mod ecrecover; +// mod sha256; +// mod ecrecover; -fn pretty_print_memory_dump(content: &Vec<[u8; 32]>, range: std::ops::Range) { +fn pretty_print_memory_dump(content: &Vec<[u8; 32]>, range: std::ops::Range) { println!("Memory dump:"); println!("-----------------------------------------"); for (cont, index) in content.into_iter().zip(range.into_iter()) { println!("{:04x}: 0x{}", index, hex::encode(cont)); } println!("-----------------------------------------"); -} \ No newline at end of file +} diff --git a/crates/zk_evm/src/testing/tests/trivial.rs b/crates/zk_evm/src/testing/tests/trivial.rs index f8f2988..ac0f3ed 100644 --- a/crates/zk_evm/src/testing/tests/trivial.rs +++ b/crates/zk_evm/src/testing/tests/trivial.rs @@ -1,13 +1,12 @@ -use zkevm_opcode_defs::BOOTLOADER_CODE_PAGE; use super::*; use super::simple_tracer::*; #[test] fn run_dummy_log_and_unmapped_noop() { - let tools = create_default_testing_tools(); + let mut tools = create_default_testing_tools(); let block_properties = create_default_block_info(); - let mut vm = create_initial_vm_state_for_basic_testing(tools, block_properties); + let mut vm = create_initial_vm_state_for_basic_testing(&mut tools, &block_properties); let tracing_closure = |state: &VmState<_, _, _, _, _, _>, aux: AuxTracingInformation, cycle_idx: u32| { println!("------------------------------------------------------------"); @@ -42,7 +41,7 @@ fn run_dummy_log_and_unmapped_noop() { vm.cycle(&mut debug_tracer); vm.cycle(&mut debug_tracer); - let (full_storage_access_history, storage_pre_shard, events_log_history, events, l1_messages, _) = get_final_net_states(vm); + let (full_storage_access_history, storage_pre_shard, events_log_history, events, l1_messages, _) = get_final_net_states!(vm, tools); println!("------------------------------------------------------"); println!("Storage log access history:"); @@ -61,10 +60,10 @@ fn run_dummy_log_and_unmapped_noop() { fn check_nop_moves_sp() { let mut tools = create_default_testing_tools(); let block_properties = create_default_block_info(); - let mut vm = create_initial_vm_state_for_basic_testing(tools, block_properties); + let mut vm = create_initial_vm_state_for_basic_testing(&mut tools, &block_properties); let default_tracing_tool = DefaultTracingClosure::new(); - let mut debug_tracer = ClosureBasedTracer::new(|a, b, c| default_tracing_tool.trace(a, b, c)); + let mut debug_tracer = ClosureBasedTracer::new(|a, b, c| default_tracing_tool.trace(a, b, c)); // manually encode LE let opcode = "000100005000002000"; diff --git a/crates/zk_evm/src/tests/assembly.rs b/crates/zk_evm/src/tests/assembly.rs deleted file mode 100644 index e9d9907..0000000 --- a/crates/zk_evm/src/tests/assembly.rs +++ /dev/null @@ -1,468 +0,0 @@ -use crate::tests::set_account_type; -use crate::vm_runner::{run_vm, VmLaunchOption, VmSnapshot}; -use crate::VmExecutionResult; -use std::collections::HashMap; -use std::convert::TryFrom; -use std::num::ParseIntError; -use std::path::PathBuf; -use std::str::FromStr; - -#[test] -fn factorial_5() { - let assembly = - zkevm_assembly::Assembly::try_from(PathBuf::from("examples/factorial.sasm")).unwrap(); - let VmSnapshot { registers, .. } = run_vm( - assembly, - Vec::new(), - HashMap::new(), - vec![U256::from(5)], - None, - VmLaunchOption::Default, - usize::MAX, - ); - - assert_eq!(registers[0], U256::from(120)); //5! = 120 -} - -#[test] -fn errors_in_contract() { - // You can find the exact contract code in etc/contracts-test-data/error-contract/SimpleRequire.sol - let assembly = - zkevm_assembly::Assembly::try_from(PathBuf::from("examples/require.zasm")).unwrap(); - let short_calldata = decode_hex("000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e6136e38").unwrap(); - let long_calldata = decode_hex("0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b5fa981").unwrap(); - let new_error_calldata = decode_hex("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000058f822ca").unwrap(); - - let mut storage = HashMap::new(); - let storage_key = StorageKey::UserKey( - AccountTreeId::Rollup(Address::default()), - AccountTreeId::Rollup(Address::default()), - H256::from_str("0xc49821d8653c58e43c7c6b0f17e15eb7f774bf3333419e9bedb01be51ae97e7c") - .unwrap(), - ); - storage.insert(storage_key, u32_to_h256(1)); - set_account_type(&mut storage, &Address::default(), &AccountType::ZkRollup); - let VmSnapshot { - execution_result: VmExecutionResult { revert_reason, .. }, - .. - } = run_vm( - assembly.clone(), - short_calldata, - storage.clone(), - vec![], - None, - VmLaunchOption::Default, - usize::MAX, - ); - let revert_reason = revert_reason.unwrap(); - assert_eq!(revert_reason.require_msg().unwrap(), "short"); - assert_eq!(hex::encode(revert_reason.complete_byte_message()),"08c379a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000573686f7274000000000000000000000000000000000000000000000000000000"); - let VmSnapshot { - execution_result: VmExecutionResult { revert_reason, .. }, - .. - } = run_vm( - assembly.clone(), - long_calldata, - storage.clone(), - vec![], - None, - VmLaunchOption::Default, - usize::MAX, - ); - assert_eq!(revert_reason.unwrap().require_msg().unwrap(), "llonglonglongtextblonglonglongtextblonglonglongtextblonglonglongtextblonglonglongtextblonglonglongtextblonglonglongtextblonglonglongtextblonglonglongtextblonglonglongtextblonglonglongtextblonglonglongtextbonglonglongtextb"); - let VmSnapshot { - execution_result: VmExecutionResult { revert_reason, .. }, - .. - } = run_vm( - assembly.clone(), - new_error_calldata, - storage.clone(), - vec![], - None, - VmLaunchOption::Default, - usize::MAX, - ); - //Correct error encoded with abi - assert_eq!(hex::encode(revert_reason.unwrap().msg), "000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000046461746100000000000000000000000000000000000000000000000000000000"); -} - -#[test] -fn factorial_rec_5() { - let assembly = - zkevm_assembly::Assembly::try_from(PathBuf::from("examples/factorial_rec.sasm")).unwrap(); - - let VmSnapshot { registers, .. } = run_vm( - assembly, - Vec::new(), - HashMap::new(), - vec![U256::from(5)], - None, - VmLaunchOption::Default, - usize::MAX, - ); - - assert_eq!(registers[0], U256::from(120)); //5! = 120 -} - -#[test] -#[ignore] // ignore because fibonacci.sasm is generated with compiler with old sp handling -fn fibonacci_23() { - vlog::init(); - let assembly = - zkevm_assembly::Assembly::try_from(PathBuf::from("examples/fibonacci.sasm")).unwrap(); - - let VmSnapshot { registers, .. } = run_vm( - assembly, - Vec::new(), - HashMap::new(), - vec![U256::from(5)], - None, - VmLaunchOption::Label(String::from("three")), - usize::MAX, - ); - - assert_eq!(registers[0], U256::from(63245986)); //23th fibonacci number = 17711 -} - -#[test] -#[ignore] -fn test_increase_storage() { - vlog::init(); - let asm_text = r#" - .text - .file "main" - .type reverse,@function -reverse: - push #33, r0 - add r1, r0, r4 - sfll #0, r5, r5 - sflh #0, r5, r5 - sfll #320, r3, r3 - sflh #0, r3, r3 - sfll #736, r0, r1 - add r1, r3, r3 - mov r3, 22(sp) - sfll #288, r3, r3 - sflh #0, r3, r3 - add r1, r3, r3 - mov r3, 7(sp) - sfll #224, r3, r3 - sflh #0, r3, r3 - add r1, r3, r3 - mov r3, 9(sp) - sfll #192, r3, r3 - sflh #0, r3, r3 - add r1, r3, r3 - mov r3, 8(sp) - sfll #160, r3, r3 - sflh #0, r3, r3 - add r1, r3, r3 - mov r3, 6(sp) - sfll #128, r3, r3 - sflh #0, r3, r3 - add r1, r3, r3 - mov r3, 5(sp) - sfll #96, r3, r3 - sflh #0, r3, r3 - add r1, r3, r3 - mov r3, 4(sp) - sfll #64, r3, r3 - sflh #0, r3, r3 - add r1, r3, r3 - mov r3, 3(sp) - sfll #32, r6, r6 - sflh #0, r6, r6 - div r2, r6, r3, r0 - mov r6, 23(sp) - add r1, r6, r2 - mov r2, 2(sp) - sfll #256, r6, r6 - sflh #0, r6, r6 - add r1, r6, r1 - mov r1, 1(sp) - add 1088, r4, r1 - mov r1, 11(sp) - mov 35(sp-r3), r2 - mov 36(sp-r3), r1 - mov r1, 13(sp) - mov 37(sp-r3), r1 - mov r1, 20(sp) - mov 38(sp-r3), r1 - mov r1, 19(sp) - mov 39(sp-r3), r1 - mov r1, 18(sp) - mov 40(sp-r3), r1 - mov r1, 17(sp) - mov 41(sp-r3), r1 - mov r1, 16(sp) - mov 42(sp-r3), r1 - mov r1, 15(sp) - mov 43(sp-r3), r1 - mov r1, 14(sp) - mov 44(sp-r3), r1 - mov 45(sp-r3), r4 - mov r4, 34(sp) - div r4, r6, r0, r3 - mov r3, 10(sp) - mov r1, 12(sp) - mov r1, 33(sp) - mov 14(sp), r1 - mov r1, 32(sp) - mov 15(sp), r1 - mov r1, 31(sp) - mov 16(sp), r1 - mov r1, 30(sp) - mov 17(sp), r1 - mov r1, 29(sp) - mov 18(sp), r1 - mov r1, 28(sp) - mov 19(sp), r1 - mov r1, 27(sp) - mov 20(sp), r1 - mov r1, 26(sp) - mov 13(sp), r1 - mov r1, 25(sp) - mov r2, 24(sp) - sfll #2, r3, r3 - sflh #0, r3, r3 - mov r3, 21(sp) - mov 10(sp), r1 - sub r1, r3, r0 - jlt .LBB0_4, .LBB0_1 -.LBB0_1: - sub r0, r5, r3 - sfll #340282366920938463463374607431768211455, r1, r1 - sflh #340282366920938463463374607431768211455, r1, r1 - add r3, r1, r1 - add r4, r1, r3 - div r3, r6, r0, r3 - mov 24(sp-r3), r3 - div r3, r6, r0, r3 - div r5, r6, r0, r4 - mov r3, 24(sp-r4) - mov 23(sp), r3 - mov 22(sp), r4 - div r4, r3, r3, r0 - mov 1(sp-r3), r4 - add r4, r1, r1 - div r2, r6, r0, r2 - div r1, r6, r0, r1 - mov r2, 24(sp-r1) - sfll #1, r1, r1 - sflh #0, r1, r1 - add r5, r1, r5 - mov 1(sp-r3), r4 - div r4, r6, r0, r1 - mov 21(sp), r2 - div r1, r2, r1, r0 - div r5, r6, r0, r2 - sub r2, r1, r0 - jge .LBB0_3, .LBB0_2 -.LBB0_2: - mov 24(sp-r2), r1 - div r1, r6, r0, r2 - j .LBB0_1, .LBB0_1 -.LBB0_3: - mov 23(sp), r1 - mov 1(sp), r2 - div r2, r1, r2, r0 - mov r2, 19(sp) - mov 7(sp), r2 - div r2, r1, r6, r0 - mov 2(sp), r2 - div r2, r1, r2, r0 - mov r2, 22(sp) - mov 3(sp), r2 - div r2, r1, r2, r0 - mov r2, 21(sp) - mov 4(sp), r2 - div r2, r1, r2, r0 - mov r2, 20(sp) - mov 5(sp), r2 - div r2, r1, r2, r0 - mov r2, 18(sp) - mov 6(sp), r2 - div r2, r1, r5, r0 - mov 8(sp), r2 - div r2, r1, r3, r0 - mov 9(sp), r2 - div r2, r1, r1, r0 - mov 24(sp), r2 - mov 1(sp-r6), r6 - mov r6, 12(sp) - mov 19(sp), r6 - mov 1(sp-r6), r6 - mov r6, 14(sp) - mov 1(sp-r1), r1 - mov r1, 15(sp) - mov 1(sp-r3), r1 - mov r1, 16(sp) - mov 1(sp-r5), r1 - mov r1, 17(sp) - mov 18(sp), r1 - mov 1(sp-r1), r1 - mov r1, 18(sp) - mov 20(sp), r1 - mov 1(sp-r1), r1 - mov r1, 19(sp) - mov 21(sp), r1 - mov 1(sp-r1), r1 - mov r1, 20(sp) - mov 22(sp), r1 - mov 1(sp-r1), r1 - mov r1, 13(sp) -.LBB0_4: - mov 11(sp), r1 - mov 23(sp), r3 - div r1, r3, r3, r0 - mov r4, 11(sp-r3) - mov 12(sp), r4 - mov r4, 10(sp-r3) - mov 14(sp), r4 - mov r4, 9(sp-r3) - mov 15(sp), r4 - mov r4, 8(sp-r3) - mov 16(sp), r4 - mov r4, 7(sp-r3) - mov 17(sp), r4 - mov r4, 6(sp-r3) - mov 18(sp), r4 - mov r4, 5(sp-r3) - mov 19(sp), r4 - mov r4, 4(sp-r3) - mov 20(sp), r4 - mov r4, 3(sp-r3) - mov 13(sp), r4 - mov r4, 2(sp-r3) - mov r2, 1(sp-r3) - pop #33, r0 - ret -reverse_test: - push #26, r0 - sfll #9, r1, r1 - sflh #0, r1, r1 - mov r1, 25(sp) - sfll #4, r1, r1 - sflh #0, r1, r1 - mov r1, 24(sp) - sfll #5, r1, r1 - sflh #0, r1, r1 - mov r1, 23(sp) - sfll #10, r1, r1 - sflh #0, r1, r1 - mov r1, 27(sp) - mov r1, 21(sp) - sfll #8, r1, r1 - sflh #0, r1, r1 - mov r1, 20(sp) - sfll #6, r1, r1 - sflh #0, r1, r1 - mov r1, 4(sp) - mov r1, 26(sp) - sfll #3, r1, r1 - sflh #0, r1, r1 - mov r1, 2(sp) - mov r1, 22(sp) - sfll #1, r1, r1 - sflh #0, r1, r1 - mov r1, 1(sp) - mov r1, 19(sp) - sfll #2, r1, r1 - sflh #0, r1, r1 - mov r1, 5(sp) - mov r1, 18(sp) - sfll #7, r1, r1 - sflh #0, r1, r1 - mov r1, 3(sp) - mov r1, 17(sp) - sfll #160, r0, r1 - sfll #512, r0, r2 - call reverse - mov 1(sp), r5 - sfll #0, r2, r2 - sflh #0, r2, r2 - mov 10(sp), r3 - add r5, r0, r1 - mov 2(sp), r4 - sub r3, r4, r0 - je .LBB1_2, .LBB1_1 -.LBB1_1: - add r2, r0, r1 -.LBB1_2: - mov 15(sp), r4 - add r5, r0, r3 - mov 3(sp), r6 - sub r4, r6, r0 - je .LBB1_4, .LBB1_3 -.LBB1_3: - add r2, r0, r3 -.LBB1_4: - mov 6(sp), r4 - mov 4(sp), r6 - sub r4, r6, r0 - je .LBB1_6, .LBB1_5 -.LBB1_5: - add r2, r0, r5 -.LBB1_6: - mul r5, r3, r2, r0 - mul r1, r2, r1, r0 - mov 5(sp), r2 - div r1, r2, r0, r1 - pop #26, r0 - ret -.Lfunc_end1: - .size reverse_test, .Lfunc_end1-reverse_test - - .section ".note.GNU-stack","",@progbits - "#; - - let assembly = zkevm_assembly::Assembly::try_from(asm_text.to_owned()).unwrap(); - let calldata = r#" - 0100 0000 0000 0000 0000 0000 0000 0000 - 0000 0000 0000 0000 0000 0000 0000 0000 - 0100 0000 0000 0000 0000 0000 0000 0000 - 0000 0000 0000 0000 0000 0000 0000 0000 - 0000 0000 0000 0000 0000 0000 0000 0000 - 0000 0000 0000 0000 0000 0000 0000 0000 - 0000 0000 0000 0000 0000 0000 0000 0000 - 0000 0000 0000 0000 0000 0000 0000 0000 - 0000 0000 0000 0000 0000 0000 0000 0000 - 0000 0000 0000 0000 0000 0000 0000 0000 - 0000 0000 0000 0000 0000 0000 0000 0000 - 0000 0000 0000 0000 0000 0000 0000 0000 - 0000 0000 0000 0000 0000 0000 0000 0000 - 0000 0000 0000 0000 0000 0000 0000 0000 - 0000 0000 0000 0000 0000 0000 0000 0000 - 0000 0000 0000 0000 0000 0000 7bfc 6c64 - 0500 0000 0000 0000 0000 0000 0000 0000 - 0000 0000 0000 0000 0000 0000 0000 0000 - - "# - .replace(|c: char| c.is_whitespace(), ""); - - let decoded_calldata = decode_hex(&calldata).expect("Decoding failed"); - let storage_key = UserKey( - Rollup(H160::zero()), - Rollup(H160::zero()), - H256::from_low_u64_be(1), - ); - let mut initial_storage: HashMap = HashMap::new(); - initial_storage.insert(storage_key.clone(), H256::from_low_u64_be(43)); - let VmSnapshot { storage, .. } = run_vm( - assembly, - decoded_calldata, - initial_storage, - vec![], - None, - VmLaunchOption::Default, - usize::MAX, - ); - assert_eq!(storage.get(&storage_key), Some(&H256::from_low_u64_be(48))) // 43 + 5 = 48 -} - -pub fn decode_hex(s: &str) -> Result, ParseIntError> { - (0..s.len()) - .step_by(2) - .map(|i| u8::from_str_radix(&s[i..i + 2], 16)) - .collect() -} diff --git a/crates/zk_evm/src/tests/mod.rs b/crates/zk_evm/src/tests/mod.rs deleted file mode 100644 index c33b137..0000000 --- a/crates/zk_evm/src/tests/mod.rs +++ /dev/null @@ -1,1750 +0,0 @@ -#![allow(clippy::bool_assert_comparison)] // There are a lot of bool checks, direct comparison is more declarative. - -mod assembly; - -use crate::vm::VmExecutionContext; -use crate::vm_runner::{run_vm_multi_contracts, set_account_type, RawInMemoryStorage}; -use crate::{run_vm, VmExecutionResult, VmInstance, VmLaunchOption, VmSnapshot}; -use std::collections::HashMap; -use zkevm_assembly::*; -use zksync_types::AccountTreeId::Rollup; -use zksync_types::{ - utils::{address_to_h256, h256_to_u256}, - Address, BlockNumber, VmEvent, H160, H256, U256, -}; -use zksync_types::{AccountTreeId, AccountType, StorageKey}; - -const NULL: RegisterOperand = RegisterOperand::Null; -const RG0: RegisterOperand = RegisterOperand::Register(0); -const RG1: RegisterOperand = RegisterOperand::Register(1); -const RG2: RegisterOperand = RegisterOperand::Register(2); -const RG3: RegisterOperand = RegisterOperand::Register(3); -const RG4: RegisterOperand = RegisterOperand::Register(4); -const RG5: RegisterOperand = RegisterOperand::Register(5); - -const RF0: FullOperand = FullOperand::Register(RG0); -const RF1: FullOperand = FullOperand::Register(RG1); -const RF2: FullOperand = FullOperand::Register(RG2); - -const OP_RETURN: Instruction = - Instruction::FunctionJump(FunctionJumpInstruction::Return { error: false }); - -#[test] -fn test_calldata_allocation() { - let storage = &mut dummy_storage(); - let mut calldata_word_2_bytes = [0u8; 32]; - U256::from(42424242).to_little_endian(&mut calldata_word_2_bytes); - let mut calldata = vec![0x0; 32]; - calldata.extend_from_slice(&calldata_word_2_bytes); - let mut vm = VmInstance::new( - storage, - &calldata, - dummy_context(), - usize::MAX, - Default::default(), - ) - .unwrap(); - - vm.dispatch_opcode(Instruction::Memory(MemoryInstruction { - address: MemoryOperand { - r#type: MemoryType::SharedParent, - offset: 0, - register: NULL, - }, - operation: DataOperation::Read { destination: RG0 }, - })) - .unwrap(); - - vm.dispatch_opcode(Instruction::Memory(MemoryInstruction { - address: MemoryOperand { - r#type: MemoryType::SharedParent, - offset: 1, - register: NULL, - }, - operation: DataOperation::Read { destination: RG1 }, - })) - .unwrap(); - - assert_eq!(vm.read_reg(RG0), U256::zero()); - assert_eq!(vm.read_reg(RG1), U256::from(42424242)); -} - -#[test] -fn test_add_execution() { - let storage = &mut dummy_storage(); - let mut vm = VmInstance::new( - storage, - &Vec::new(), - dummy_context(), - usize::MAX, - Default::default(), - ) - .unwrap(); - vm.write_reg(RG0, U256::from(1)); - vm.write_reg(RG1, U256::from(2)); - - vm.dispatch_opcode(Instruction::Add(AddInstruction { - source_1: RF0, - source_2: RG1, - destination: RG2, - })) - .unwrap(); - - assert_eq!(vm.read_reg(RG2), U256::from(3)); - assert_eq!(vm.flags.error_overflow_or_less_than_flag, false); -} - -#[test] -fn test_bitwise_xor() { - let storage = &mut dummy_storage(); - let mut vm = VmInstance::new( - storage, - &Vec::new(), - dummy_context(), - usize::MAX, - Default::default(), - ) - .unwrap(); - vm.write_reg(RG0, U256::from(0b01011011)); - vm.write_reg(RG1, U256::from(0b10000001)); - - vm.dispatch_opcode(Instruction::Bitwise(BitwiseInstruction { - source_1: RF0, - source_2: RG1, - destination: RG2, - op_type: BitwiseOpType::Xor, - })) - .unwrap(); - - assert_eq!(vm.read_reg(RG2), U256::from(0b11011010)); - assert_eq!(vm.flags.error_overflow_or_less_than_flag, false); -} - -#[test] -fn test_bitwise_shift() { - let storage = &mut dummy_storage(); - let mut vm = VmInstance::new( - storage, - &Vec::new(), - dummy_context(), - usize::MAX, - Default::default(), - ) - .unwrap(); - vm.write_reg(RG0, U256::from(3 + (17 << 8))); // only first 8 bytes must be considered - vm.write_reg(RG1, U256::from(0b010111011011) + (U256::one() << 255)); - - vm.dispatch_opcode(Instruction::Shift(ShiftInstruction { - source_1: RF0, - source_2: RG1, - destination: RG2, - is_cyclic: false, - is_right: false, - })) - .unwrap(); - - vm.dispatch_opcode(Instruction::Shift(ShiftInstruction { - source_1: RF0, - source_2: RG1, - destination: RG3, - is_cyclic: false, - is_right: true, - })) - .unwrap(); - - vm.dispatch_opcode(Instruction::Shift(ShiftInstruction { - source_1: RF0, - source_2: RG1, - destination: RG4, - is_cyclic: true, - is_right: false, - })) - .unwrap(); - - vm.dispatch_opcode(Instruction::Shift(ShiftInstruction { - source_1: RF0, - source_2: RG1, - destination: RG5, - is_cyclic: true, - is_right: true, - })) - .unwrap(); - assert_eq!(vm.read_reg(RG2), U256::from(0b010111011011000)); - assert_eq!( - vm.read_reg(RG3), - U256::from(0b010111011) + (U256::one() << 252) - ); - assert_eq!(vm.read_reg(RG4), U256::from(0b010111011011100)); - assert_eq!( - vm.read_reg(RG5), - U256::from(0b010111011) + (U256::from(0b111) << 252) - ); -} - -#[test] -fn test_add_execution_overflow() { - let storage = &mut dummy_storage(); - let mut vm = VmInstance::new( - storage, - &Vec::new(), - dummy_context(), - usize::MAX, - Default::default(), - ) - .unwrap(); - vm.write_reg(RG0, U256::max_value()); - vm.write_reg(RG1, U256::from(44)); - - vm.dispatch_opcode(Instruction::Add(AddInstruction { - source_1: RF0, - source_2: RG1, - destination: RG2, - })) - .unwrap(); - assert_eq!(vm.read_reg(RG2), U256::from(43)); - assert_eq!(vm.flags.error_overflow_or_less_than_flag, true); -} - -#[test] -fn test_mul_execution() { - let storage = &mut dummy_storage(); - let mut vm = VmInstance::new( - storage, - &Vec::new(), - dummy_context(), - usize::MAX, - Default::default(), - ) - .unwrap(); - vm.write_reg(RG0, U256::from(1000)); - vm.write_reg(RG1, U256::from(43)); - - vm.dispatch_opcode(Instruction::Mul(MulInstruction { - source_1: RF0, - source_2: RG1, - destination_1: RG2, - destination_2: RG3, - })) - .unwrap(); - - assert_eq!(vm.read_reg(RG2), U256::from(43000)); - assert_eq!(vm.flags.error_overflow_or_less_than_flag, true); - assert_eq!(vm.flags.greater_than_flag, false); -} - -#[test] -fn test_mul_execution_overflow() { - let storage = &mut dummy_storage(); - let mut vm = VmInstance::new( - storage, - &Vec::new(), - dummy_context(), - usize::MAX, - Default::default(), - ) - .unwrap(); - vm.write_reg(RG0, (U256::max_value() - 1) / 2); - vm.write_reg(RG1, U256::from(3)); - - vm.dispatch_opcode(Instruction::Mul(MulInstruction { - source_1: RF0, - source_2: RG1, - destination_1: RG2, - destination_2: RG3, - })) - .unwrap(); - - assert_eq!(vm.read_reg(RG2), (U256::max_value() - 4) / 2); - assert_eq!(vm.read_reg(RG3), U256::one()); - assert_eq!(vm.flags.error_overflow_or_less_than_flag, false); - assert_eq!(vm.flags.greater_than_flag, true); -} - -#[test] -fn test_div_execution() { - let storage = &mut dummy_storage(); - let mut vm = VmInstance::new( - storage, - &Vec::new(), - dummy_context(), - usize::MAX, - Default::default(), - ) - .unwrap(); - vm.write_reg(RG0, U256::from(43)); - vm.write_reg(RG1, U256::from(10)); - - vm.dispatch_opcode(Instruction::Div(DivInstruction { - source_1: RF0, - source_2: RG1, - quotient_destination: RG2, - remainder_destination: RG3, - swap_operands: false, - })) - .unwrap(); - - assert_eq!(vm.read_reg(RG2), U256::from(4)); - assert_eq!(vm.read_reg(RG3), U256::from(3)); - assert_eq!(vm.flags.error_overflow_or_less_than_flag, false); - assert_eq!(vm.flags.equality_flag, false); - assert_eq!(vm.flags.greater_than_flag, true); -} - -#[test] -fn test_div_execution_zero() { - let storage = &mut dummy_storage(); - let mut vm = VmInstance::new( - storage, - &Vec::new(), - dummy_context(), - usize::MAX, - Default::default(), - ) - .unwrap(); - - vm.write_reg(RG0, U256::from(43)); - vm.write_reg(RG1, U256::from(0)); - - vm.dispatch_opcode(Instruction::Div(DivInstruction { - source_1: RF0, - source_2: RG1, - quotient_destination: RG2, - remainder_destination: RG3, - swap_operands: false, - })) - .unwrap(); - - assert_eq!(vm.read_reg(RG2), U256::from(0)); - assert_eq!(vm.read_reg(RG3), U256::from(0)); - assert_eq!(vm.flags.error_overflow_or_less_than_flag, false); - assert_eq!(vm.flags.equality_flag, true); - assert_eq!(vm.flags.greater_than_flag, true); -} - -#[test] -fn test_div_execution_both_zero() { - let storage = &mut dummy_storage(); - let mut vm = VmInstance::new( - storage, - &Vec::new(), - dummy_context(), - usize::MAX, - Default::default(), - ) - .unwrap(); - vm.write_reg(RG0, U256::from(0)); - vm.write_reg(RG1, U256::from(0)); - - vm.dispatch_opcode(Instruction::Div(DivInstruction { - source_1: RF0, - source_2: RG1, - quotient_destination: RG2, - remainder_destination: RG3, - swap_operands: false, - })) - .unwrap(); - - assert_eq!(vm.read_reg(RG2), U256::from(0)); - assert_eq!(vm.read_reg(RG3), U256::from(0)); - assert_eq!(vm.flags.error_overflow_or_less_than_flag, false); - assert_eq!(vm.flags.equality_flag, true); - assert_eq!(vm.flags.greater_than_flag, false); -} - -#[test] -fn test_shuffle_lowest() { - let storage = &mut dummy_storage(); - let mut vm = VmInstance::new( - storage, - &Vec::new(), - dummy_context(), - usize::MAX, - Default::default(), - ) - .unwrap(); - vm.dispatch_opcode(Instruction::Shuffle(ShuffleInstruction { - source_1: FullOperand::Immediate(43), - source_2: NULL, - destination: RG3, - load_in_low: true, - })) - .unwrap(); - - assert_eq!(vm.read_reg(RG3), U256::from(43)); - assert_eq!(vm.flags.error_overflow_or_less_than_flag, false); - assert_eq!(vm.flags.equality_flag, false); - assert_eq!(vm.flags.greater_than_flag, false); -} - -#[test] -fn test_immediate_highest() { - let storage = &mut dummy_storage(); - let mut vm = VmInstance::new( - storage, - &Vec::new(), - dummy_context(), - usize::MAX, - Default::default(), - ) - .unwrap(); - vm.dispatch_opcode(Instruction::Shuffle(ShuffleInstruction { - source_1: FullOperand::Immediate(43), - source_2: NULL, - destination: RG3, - load_in_low: false, - })) - .unwrap(); - - assert_eq!(vm.read_reg(RG3), (U256::from(u128::MAX) + 1) * 43); - assert_eq!(vm.flags.error_overflow_or_less_than_flag, false); - assert_eq!(vm.flags.equality_flag, false); - assert_eq!(vm.flags.greater_than_flag, false); -} - -#[test] -fn test_hash_zero() { - let storage = &mut dummy_storage(); - let mut vm = VmInstance::new( - storage, - &Vec::new(), - dummy_context(), - usize::MAX, - Default::default(), - ) - .unwrap(); - vm.write_reg(RG1, U256::from(123)); - - vm.dispatch_opcode(Instruction::HashOutput(HashOutputInstruction { - destination: RG1, - })) - .unwrap(); - - assert_eq!(vm.read_reg(RG1), U256::zero()); -} - -#[test] -fn test_hash_reset() { - let assembly = Assembly { - instructions: vec![ - Instruction::HashAbsorb(HashAbsorbInstruction { - source: RF1, - reset: false, - }), - Instruction::HashAbsorb(HashAbsorbInstruction { - source: RF2, - reset: true, - }), - Instruction::HashOutput(HashOutputInstruction { destination: RG3 }), - OP_RETURN, - ], - labels: HashMap::new(), - assembly_code: "".to_string(), - pc_line_mapping: Default::default(), - }; - - let VmSnapshot { registers, .. } = run_vm( - assembly, - Vec::new(), - HashMap::new(), - vec![U256::zero(), U256::from(123), U256::zero()], - None, - VmLaunchOption::Default, - usize::MAX, - ); - - assert_eq!( - registers[3], - U256::from_dec_str( - "5862139083026206628832301127335791535962889136620943667582563443715053309945" - ) - .unwrap() - ); -} - -#[test] -fn test_hash() { - let assembly = Assembly { - instructions: vec![ - Instruction::HashAbsorb(HashAbsorbInstruction { - source: RF1, - reset: false, - }), - Instruction::HashAbsorb(HashAbsorbInstruction { - source: RF2, - reset: false, - }), - Instruction::HashOutput(HashOutputInstruction { destination: RG3 }), - OP_RETURN, - ], - labels: HashMap::new(), - assembly_code: "".to_string(), - pc_line_mapping: Default::default(), - }; - - let VmSnapshot { registers, .. } = run_vm( - assembly, - Vec::new(), - HashMap::new(), - vec![U256::zero(), U256::from(123), U256::from(125)], - None, - VmLaunchOption::Default, - usize::MAX, - ); - - assert_eq!( - registers[3], - U256::from_dec_str( - "9683768255054160865462551840877242526106853161404912121878200381733926296023" - ) - .unwrap() - ); -} - -#[test] -fn test_jump() { - // the second instruction will be skipped - let assembly = Assembly { - instructions: vec![ - Instruction::Jump(JumpInstruction { - source: FullOperand::Register(NULL), - flags: vec![JumpFlag::Unconditional], - destination_true: 2, - destination_false: 1, - }), - Instruction::Shuffle(ShuffleInstruction { - source_1: FullOperand::Immediate(17), - source_2: NULL, - destination: RG0, - load_in_low: true, - }), - Instruction::Shuffle(ShuffleInstruction { - source_1: FullOperand::Immediate(42), - source_2: NULL, - destination: RG2, - load_in_low: true, - }), - OP_RETURN, - ], - labels: HashMap::new(), - assembly_code: "".to_string(), - pc_line_mapping: Default::default(), - }; - - let VmSnapshot { registers, .. } = run_vm( - assembly, - Vec::new(), - HashMap::new(), - vec![U256::zero(), U256::from(123), U256::from(125)], - None, - VmLaunchOption::Default, - usize::MAX, - ); - - assert_eq!(registers[2], U256::from(42)); - assert_eq!(registers[0], U256::from(0)); -} - -#[test] -fn test_jump_source_zero() { - let assembly = Assembly { - instructions: vec![ - Instruction::Jump(JumpInstruction { - source: RF0, - flags: vec![], - // should jump here - destination_true: 2, - destination_false: 1, - }), - // this instruction should be skipped - Instruction::Shuffle(ShuffleInstruction { - source_1: FullOperand::Immediate(17), - source_2: NULL, - destination: RG2, - load_in_low: true, - }), - Instruction::Shuffle(ShuffleInstruction { - source_1: FullOperand::Immediate(42), - source_2: NULL, - destination: RG3, - load_in_low: true, - }), - Instruction::Jump(JumpInstruction { - source: RF1, - flags: vec![], - destination_true: 5, - // should jump here - no skipped instructions - destination_false: 4, - }), - Instruction::Shuffle(ShuffleInstruction { - source_1: FullOperand::Immediate(17), - source_2: NULL, - destination: RG4, - load_in_low: true, - }), - Instruction::Shuffle(ShuffleInstruction { - source_1: FullOperand::Immediate(42), - source_2: NULL, - destination: RG5, - load_in_low: true, - }), - OP_RETURN, - ], - labels: HashMap::new(), - assembly_code: "".to_string(), - pc_line_mapping: Default::default(), - }; - - let VmSnapshot { registers, .. } = run_vm( - assembly, - // first register: first two bytes are not zero, flag evaluates to true - // second register: first two bytes are zero, flag evaluates to false - Vec::new(), - HashMap::new(), - vec![U256::from(1 << 15), U256::from(1 << 17)], - None, - VmLaunchOption::Default, - usize::MAX, - ); - - assert_eq!(registers[2], U256::from(0)); - assert_eq!(registers[3], U256::from(42)); - assert_eq!(registers[4], U256::from(17)); - assert_eq!(registers[5], U256::from(42)); -} - -#[test] -fn test_mul_memory_stack() { - let assembly = Assembly { - instructions: vec![ - Instruction::Memory(MemoryInstruction { - address: MemoryOperand { - r#type: MemoryType::Stack { force: true }, - offset: 0, - register: NULL, - }, - operation: DataOperation::Write { source: RG0 }, - }), - Instruction::Shuffle(ShuffleInstruction { - source_1: FullOperand::Immediate(20), - source_2: NULL, - destination: RG1, - load_in_low: true, - }), - Instruction::Mul(MulInstruction { - source_1: FullOperand::Memory(MemoryOperand { - r#type: MemoryType::Stack { force: true }, - offset: 0, // pop one element - the one added in the preceding memory op (= 7) - register: RegisterOperand::Null, - }), - source_2: RG1, // = 20 - destination_1: RG2, - destination_2: RG3, - }), - OP_RETURN, - ], - labels: HashMap::new(), - - assembly_code: "".to_string(), - pc_line_mapping: Default::default(), - }; - - let VmSnapshot { - registers, - first_contract_stack, - .. - } = run_vm( - assembly, - Vec::new(), - HashMap::new(), - vec![U256::from(7)], - None, - VmLaunchOption::Default, - usize::MAX, - ); - - assert_eq!(registers[2], U256::from(140)); - // make sure stack pop clears the poped element - assert_eq!(first_contract_stack.read(0).unwrap(), U256::zero()); -} - -#[test] -fn test_mul_memory_local() { - let assembly = Assembly { - instructions: vec![ - Instruction::Memory(MemoryInstruction { - address: MemoryOperand { - r#type: MemoryType::Local, - offset: 5, - register: RG0, // = 3 - }, - operation: DataOperation::Write { source: RG1 }, // = 5 - }), - Instruction::Shuffle(ShuffleInstruction { - source_1: FullOperand::Immediate(20), - source_2: NULL, - destination: RG1, - load_in_low: true, - }), - Instruction::Mul(MulInstruction { - source_1: FullOperand::Memory(MemoryOperand { - r#type: MemoryType::Local, - offset: 8, - register: RegisterOperand::Null, - }), // = 5 - source_2: RG1, // = 20 - destination_1: RG2, - destination_2: RG3, - }), - OP_RETURN, - ], - labels: HashMap::new(), - - assembly_code: "".to_string(), - pc_line_mapping: Default::default(), - }; - - let VmSnapshot { - registers, - first_contract_local_memory, - .. - } = run_vm( - assembly, - Vec::new(), - HashMap::new(), - vec![U256::from(3), U256::from(5)], - None, - VmLaunchOption::Default, - usize::MAX, - ); - - assert_eq!(registers[2], U256::from(100)); - assert_eq!(first_contract_local_memory.read(8).unwrap(), U256::from(5)); -} - -#[test] -fn test_jump_lesser_than() { - let assembly = Assembly { - instructions: vec![ - Instruction::Sub(SubInstruction { - source_1: RF0, - source_2: RG1, - destination: NULL, // we only need it to set flags - swap_operands: false, - }), - Instruction::Jump(JumpInstruction { - source: FullOperand::Register(NULL), - flags: vec![JumpFlag::LesserThan], - // should jump here - destination_true: 3, - destination_false: 2, - }), - // this instruction should be skipped - Instruction::Shuffle(ShuffleInstruction { - source_1: FullOperand::Immediate(17), - source_2: NULL, - destination: RG2, - load_in_low: true, - }), - Instruction::Shuffle(ShuffleInstruction { - source_1: FullOperand::Immediate(42), - source_2: NULL, - destination: RG3, - load_in_low: true, - }), - OP_RETURN, - ], - labels: HashMap::new(), - - assembly_code: "".to_string(), - pc_line_mapping: Default::default(), - }; - - let VmSnapshot { registers, .. } = run_vm( - assembly, - Vec::new(), - HashMap::new(), - vec![U256::from(5), U256::from(7)], - None, - VmLaunchOption::Default, - usize::MAX, - ); - - assert_eq!(registers[2], U256::zero()); - assert_eq!(registers[3], U256::from(42)); -} - -#[test] -fn test_memory_stack_push_pop() { - let assembly = Assembly { - instructions: vec![ - Instruction::Memory(MemoryInstruction { - address: MemoryOperand { - r#type: MemoryType::Stack { force: true }, - offset: 0, - register: NULL, - }, - operation: DataOperation::Write { source: RG0 }, - }), - Instruction::Memory(MemoryInstruction { - address: MemoryOperand { - r#type: MemoryType::Stack { force: true }, - offset: 1, // pushes two elements: zero and RG1 - register: NULL, - }, - operation: DataOperation::Write { source: RG1 }, - }), - Instruction::Memory(MemoryInstruction { - address: MemoryOperand { - r#type: MemoryType::Stack { force: true }, - offset: 0, - register: NULL, - }, - operation: DataOperation::Write { source: RG2 }, - }), - Instruction::Memory(MemoryInstruction { - address: MemoryOperand { - r#type: MemoryType::Stack { force: true }, - offset: 0, - register: RG3, // RG3 == 1: raw_mem_offset = 1. POP two elements. - }, - operation: DataOperation::Read { destination: RG3 }, - }), - Instruction::Memory(MemoryInstruction { - address: MemoryOperand { - r#type: MemoryType::Stack { force: true }, - offset: 0, - register: RG4, // RG4 == 0: raw_mem_offset = 1. - }, - operation: DataOperation::Read { destination: RG4 }, - }), - Instruction::Memory(MemoryInstruction { - address: MemoryOperand { - r#type: MemoryType::Stack { force: true }, - offset: 0, - register: RG4, // RG4 == 0: raw_mem_offset = 1. - }, - operation: DataOperation::Read { destination: RG5 }, - }), - OP_RETURN, - ], - labels: HashMap::new(), - assembly_code: "".to_string(), - pc_line_mapping: Default::default(), - }; - - let VmSnapshot { registers, .. } = run_vm( - assembly, - Vec::new(), - HashMap::new(), - vec![ - U256::from(201), - U256::from(202), - U256::from(203), - U256::from(1), - ], - None, - VmLaunchOption::Default, - usize::MAX, - ); - - assert_eq!(registers[3], U256::from(202)); - assert_eq!(registers[4], U256::from(0)); - assert_eq!(registers[5], U256::from(201)); -} - -#[test] -fn test_memory_push_pop() { - let assembly = Assembly { - instructions: vec![ - Instruction::Memory(MemoryInstruction { - // bump sp to 1 - address: MemoryOperand { - r#type: MemoryType::Stack { force: true }, - offset: 0, - register: NULL, - }, - operation: DataOperation::Write { source: RG0 }, - }), - Instruction::Memory(MemoryInstruction { - // bump sp to 3 - address: MemoryOperand { - r#type: MemoryType::Stack { force: true }, - offset: 1, - register: NULL, - }, - operation: DataOperation::Write { source: RG1 }, - }), - Instruction::Memory(MemoryInstruction { - // bump sp to 5 - address: MemoryOperand { - r#type: MemoryType::Stack { force: true }, - offset: 1, - register: NULL, - }, - operation: DataOperation::Write { source: RG2 }, - }), - Instruction::Memory(MemoryInstruction { - // sp is down to 2 - address: MemoryOperand { - r#type: MemoryType::Stack { force: true }, - offset: 2, - register: NULL, - }, - operation: DataOperation::Read { destination: RG3 }, // value of RG1 goes here - }), - Instruction::Memory(MemoryInstruction { - address: MemoryOperand { - // sp is down to 1 - r#type: MemoryType::Stack { force: true }, - offset: 0, - register: NULL, - }, - operation: DataOperation::Read { destination: RG4 }, // NULL goes here - }), - Instruction::Memory(MemoryInstruction { - address: MemoryOperand { - // sp is down to 0 - r#type: MemoryType::Stack { force: true }, - offset: 0, - register: NULL, - }, - operation: DataOperation::Read { destination: RG5 }, //value of RG0 goes here - }), - OP_RETURN, - ], - labels: HashMap::new(), - assembly_code: "".to_string(), - pc_line_mapping: Default::default(), - }; - - let VmSnapshot { - registers, - first_contract_stack, - .. - } = run_vm( - assembly, - Vec::new(), - HashMap::new(), - vec![U256::from(10), U256::from(20)], - None, - VmLaunchOption::Default, - usize::MAX, - ); - - assert_eq!(first_contract_stack.read(0).unwrap(), U256::default()); - assert_eq!(first_contract_stack.read(1).unwrap(), U256::default()); - assert_eq!(first_contract_stack.read(2).unwrap(), U256::default()); - assert_eq!(first_contract_stack.read(3).unwrap(), U256::default()); - assert_eq!(first_contract_stack.read(4).unwrap(), U256::default()); - assert_eq!(registers[3], U256::from(20)); - assert_eq!(registers[4], U256::from(0)); - assert_eq!(registers[5], U256::from(10)); -} - -#[test] -fn test_storage() { - let assembly = Assembly { - instructions: vec![ - Instruction::Storage(StorageInstruction::Storage { - storage_key: RF0, - operation: DataOperation::Write { source: RG1 }, - is_external_storage_access: false, - }), - Instruction::Storage(StorageInstruction::Storage { - storage_key: RF0, - operation: DataOperation::Read { destination: RG2 }, - is_external_storage_access: false, - }), - OP_RETURN, - ], - labels: HashMap::new(), - assembly_code: "".to_string(), - pc_line_mapping: Default::default(), - }; - - let address1 = Address::random(); - let address2 = Address::random(); - - let address_to_u256 = |addr| h256_to_u256(address_to_h256(&addr)); - - let mut storage = HashMap::new(); - set_account_type(&mut storage, &Address::zero(), &AccountType::ZkRollup); - - let VmSnapshot { - registers, storage, .. - } = run_vm( - assembly, - Vec::new(), - storage, - vec![address_to_u256(address1), address_to_u256(address2)], - None, - VmLaunchOption::Default, - usize::MAX, - ); - - assert_eq!(registers[2], address_to_u256(address2)); - assert_eq!( - storage.get(&StorageKey::UserKey( - AccountTreeId::Rollup(Address::zero()), - AccountTreeId::Rollup(Address::zero()), - address_to_h256(&address1) - )), - Some(&address_to_h256(&address2)) - ); -} - -#[test] -fn test_limit_cycles() { - let assembly = Assembly { - instructions: vec![ - Instruction::Context(ContextInstruction { - destination: RG0, - field: ContextField::RemainingCycles, - }), - Instruction::Sub(SubInstruction { - source_1: FullOperand::Immediate(100), - source_2: RG0, - destination: NULL, - swap_operands: false, - }), // use this to compare current cycles to 100. It's more than 100 *before* the jump, and it's less *after*. - Instruction::Jump(JumpInstruction { - source: FullOperand::Register(NULL), - flags: vec![JumpFlag::LesserThan], - destination_true: 3, - destination_false: 5, - }), - Instruction::SwitchContext, - Instruction::FunctionJump(FunctionJumpInstruction::Call { - location: FunctionJumpLocation::External { - operand: FullOperand::Immediate(10 << 16), // bytes 2..4 represent `num_passed_cycles` - is_delegate: false, - }, - }), - Instruction::Context(ContextInstruction { - destination: RG1, - field: ContextField::RemainingCycles, - }), - Instruction::FunctionJump(FunctionJumpInstruction::Return { error: false }), - ], - labels: Default::default(), - assembly_code: "".to_string(), - pc_line_mapping: Default::default(), - }; - - let res_reg: [U256; 6] = run_vm( - assembly, - Vec::new(), - HashMap::new(), - vec![], - None, - VmLaunchOption::Default, - usize::MAX, - ) - .registers; - - assert_eq!(res_reg[0], U256::from(9)); - assert_eq!(res_reg[1], U256::from(usize::MAX - 11)); -} - -#[test] -fn test_rollback_multiple_contracts_explicit_error() { - let callee_1_contract_address = H160::from_low_u64_le(366); - let mut contract_1_address_bytes = callee_1_contract_address.as_bytes().to_vec(); - contract_1_address_bytes.reverse(); - let callee_2_contract_address = H160::from_low_u64_le(239); - let mut contract_2_address_bytes = callee_2_contract_address.as_bytes().to_vec(); - contract_2_address_bytes.reverse(); - let mut function_jump_calldata_bytes = vec![0u8; 32]; - function_jump_calldata_bytes.splice(4..24, contract_1_address_bytes); - let callee_1_calldata = U256::from_little_endian(&function_jump_calldata_bytes); - function_jump_calldata_bytes.splice(4..24, contract_2_address_bytes); - let callee_2_calldata = U256::from_little_endian(&function_jump_calldata_bytes); - - let main_contract = Assembly { - instructions: vec![ - Instruction::Storage(StorageInstruction::Storage { - storage_key: FullOperand::Immediate(42), - operation: DataOperation::Write { source: RG0 }, - is_external_storage_access: false, - }), - Instruction::SwitchContext, - Instruction::FunctionJump(FunctionJumpInstruction::Call { - location: FunctionJumpLocation::External { - operand: FullOperand::Register(RG2), - is_delegate: false, - }, - }), - Instruction::Storage(StorageInstruction::Storage { - storage_key: FullOperand::Immediate(34), - operation: DataOperation::Write { source: RG0 }, - is_external_storage_access: false, - }), - Instruction::FunctionJump(FunctionJumpInstruction::Return { error: false }), - ], - labels: Default::default(), - assembly_code: "".to_string(), - pc_line_mapping: Default::default(), - }; - - let callee_contract_1 = Assembly { - instructions: vec![ - Instruction::Storage(StorageInstruction::Storage { - storage_key: FullOperand::Immediate(44), - operation: DataOperation::Write { source: RG0 }, - is_external_storage_access: false, - }), - Instruction::SwitchContext, - Instruction::FunctionJump(FunctionJumpInstruction::Call { - location: FunctionJumpLocation::External { - operand: FullOperand::Register(RG3), - is_delegate: false, - }, - }), - // we return with an explicit error. This contract and the callee contract will be reverted. - Instruction::FunctionJump(FunctionJumpInstruction::Return { error: true }), - ], - labels: Default::default(), - assembly_code: "".to_string(), - pc_line_mapping: Default::default(), - }; - - let callee_contract_2 = Assembly { - instructions: vec![ - Instruction::Storage(StorageInstruction::Storage { - storage_key: FullOperand::Immediate(50), - operation: DataOperation::Write { source: RG0 }, - is_external_storage_access: false, - }), - Instruction::FunctionJump(FunctionJumpInstruction::Return { error: false }), - ], - labels: Default::default(), - assembly_code: "".to_string(), - pc_line_mapping: Default::default(), - }; - - let mut loaded_contracts: HashMap = HashMap::new(); - loaded_contracts.insert(Address::default(), main_contract); - loaded_contracts.insert(callee_1_contract_address, callee_contract_1); - loaded_contracts.insert(callee_2_contract_address, callee_contract_2); - - let mut storage = HashMap::new(); - set_account_type(&mut storage, &Address::default(), &AccountType::ZkRollup); - set_account_type( - &mut storage, - &callee_1_contract_address, - &AccountType::ZkRollup, - ); - set_account_type( - &mut storage, - &callee_2_contract_address, - &AccountType::ZkRollup, - ); - - let VmSnapshot { storage, .. } = run_vm_multi_contracts( - loaded_contracts, - Vec::new(), - storage, - vec![ - U256::from(10), - U256::from(12), - callee_1_calldata, - callee_2_calldata, - ], - Address::default(), - None, - VmLaunchOption::Default, - usize::MAX, - ); - assert_eq!( - storage.get(&StorageKey::new_user( - Rollup(Address::default()), - Rollup(Address::default()), - H256::from_low_u64_be(42) - )), - Some(&H256::from_low_u64_be(10)) - ); // the storage write from the entry contract shouldn't be rollback - assert_eq!( - storage.get(&StorageKey::new_user( - Rollup(Address::default()), - Rollup(Address::default()), - H256::from_low_u64_be(34) - )), - Some(&H256::from_low_u64_be(10)) - ); // the storage write from the entry contract shouldn't be rollback - assert_eq!( - storage.get(&StorageKey::new_user( - Rollup(callee_1_contract_address), - Rollup(callee_1_contract_address), - H256::from_low_u64_be(44) - )), - Some(&H256::zero()) - ); // callee storages must be reverted - assert_eq!( - storage.get(&StorageKey::new_user( - Rollup(callee_2_contract_address), - Rollup(callee_2_contract_address), - H256::from_low_u64_be(50) - )), - Some(&H256::zero()) - ); // callee storages must be reverted -} - -#[test] -fn test_local_call_memory_sharing() { - let assembly = Assembly { - instructions: vec![ - Instruction::Memory(MemoryInstruction { - address: MemoryOperand { - r#type: MemoryType::Local, - offset: 239, - register: NULL, - }, - operation: DataOperation::Write { source: RG1 }, - }), - Instruction::FunctionJump(FunctionJumpInstruction::Call { - location: FunctionJumpLocation::Local { - address: 4, // pc - operand: FullOperand::Immediate(0), - }, - }), - // read from stack - callee contract wrote there - Instruction::Memory(MemoryInstruction { - address: MemoryOperand { - r#type: MemoryType::Stack { force: true }, - offset: 0, - register: NULL, - }, - operation: DataOperation::Read { destination: RG2 }, - }), - Instruction::FunctionJump(FunctionJumpInstruction::Return { error: false }), - // local jump goes here - // read value saved by calling contract - Instruction::Memory(MemoryInstruction { - address: MemoryOperand { - r#type: MemoryType::Local, - offset: 239, - register: NULL, - }, - operation: DataOperation::Read { destination: RG3 }, - }), - // write to stack - calling contract should be able to pop it - Instruction::Memory(MemoryInstruction { - address: MemoryOperand { - r#type: MemoryType::Stack { force: true }, - offset: 0, - register: NULL, - }, - operation: DataOperation::Write { source: RG0 }, - }), - // return back to the entry frame - Instruction::FunctionJump(FunctionJumpInstruction::Return { error: true }), - ], - labels: Default::default(), - assembly_code: "".to_string(), - pc_line_mapping: Default::default(), - }; - - let VmSnapshot { registers, .. } = run_vm( - assembly, - Vec::new(), - HashMap::new(), - vec![U256::from(366), U256::from(30)], - None, - VmLaunchOption::Default, - usize::MAX, - ); - assert_eq!(registers[2], U256::from(366)); - assert_eq!(registers[3], U256::from(30)); -} - -#[test] -fn test_delegate_call_memory_sharing() { - let callee_contract_address = H160::from_low_u64_le(366); - let mut function_jump_calldata_bytes = vec![0u8; 32]; - let mut contract_address_bytes = callee_contract_address.as_bytes().to_vec(); - contract_address_bytes.reverse(); - function_jump_calldata_bytes.splice(4..24, contract_address_bytes); - let callee_calldata = U256::from_little_endian(&function_jump_calldata_bytes); - - let assembly_main = Assembly { - instructions: vec![ - Instruction::Memory(MemoryInstruction { - address: MemoryOperand { - r#type: MemoryType::Local, - offset: 239, - register: NULL, - }, - operation: DataOperation::Write { source: RG1 }, - }), - Instruction::FunctionJump(FunctionJumpInstruction::Call { - location: FunctionJumpLocation::External { - is_delegate: true, - operand: FullOperand::Register(RG2), - }, - }), - // read from stack - callee contract wrote there - Instruction::Memory(MemoryInstruction { - address: MemoryOperand { - r#type: MemoryType::Stack { force: true }, - offset: 0, - register: NULL, - }, - operation: DataOperation::Read { destination: RG2 }, - }), - Instruction::FunctionJump(FunctionJumpInstruction::Return { error: false }), - ], - labels: Default::default(), - assembly_code: "".to_string(), - pc_line_mapping: Default::default(), - }; - - let assembly_callee = Assembly { - instructions: vec![ - // read value saved by calling contract - Instruction::Memory(MemoryInstruction { - address: MemoryOperand { - r#type: MemoryType::Local, - offset: 239, - register: NULL, - }, - operation: DataOperation::Read { destination: RG3 }, - }), - // write to stack - calling contract should be able to pop it - Instruction::Memory(MemoryInstruction { - address: MemoryOperand { - r#type: MemoryType::Stack { force: true }, - offset: 0, - register: NULL, - }, - operation: DataOperation::Write { source: RG0 }, - }), - // return back to the entry frame - Instruction::FunctionJump(FunctionJumpInstruction::Return { error: true }), - ], - labels: Default::default(), - assembly_code: "".to_string(), - pc_line_mapping: Default::default(), - }; - - let mut loaded_contracts: HashMap = HashMap::new(); - loaded_contracts.insert(Address::default(), assembly_main); - loaded_contracts.insert(callee_contract_address, assembly_callee); - - let VmSnapshot { registers, .. } = run_vm_multi_contracts( - loaded_contracts, - Vec::new(), - HashMap::new(), - vec![U256::from(366), U256::from(30), callee_calldata], - Address::default(), - None, - VmLaunchOption::Default, - usize::MAX, - ); - - assert_eq!(registers[2], U256::from(366)); - assert_eq!(registers[3], U256::from(30)); -} - -#[test] -fn test_limit_cycles_exception() { - let assembly = Assembly { - instructions: vec![ - Instruction::Context(ContextInstruction { - destination: RG0, - field: ContextField::RemainingCycles, - }), - Instruction::Context(ContextInstruction { - destination: RG1, - field: ContextField::RemainingCycles, - }), - Instruction::SwitchContext, - Instruction::FunctionJump(FunctionJumpInstruction::Call { - location: FunctionJumpLocation::External { - operand: FullOperand::Immediate(1 << 16), // bytes 2..4 represent `num_passed_cycles`. Only pass one cycle. - is_delegate: false, - }, - }), - Instruction::Jump(JumpInstruction { - source: FullOperand::Register(NULL), - //make sure the Lesser flag is set (== exception flag) - flags: vec![JumpFlag::LesserThan], - destination_true: 5, - destination_false: 6, - }), - Instruction::Shuffle(ShuffleInstruction { - source_1: FullOperand::Immediate(42), - source_2: NULL, - destination: RG2, - load_in_low: true, - }), - Instruction::FunctionJump(FunctionJumpInstruction::Return { error: false }), - ], - labels: Default::default(), - assembly_code: "".to_string(), - pc_line_mapping: Default::default(), - }; - - let VmSnapshot { - registers, - execution_result, - .. - } = run_vm( - assembly, - Vec::new(), - HashMap::new(), - vec![], - None, - VmLaunchOption::Default, - usize::MAX, - ); - - assert_eq!( - execution_result.internal_errors, - vec![(Address::default(), "Ran out of cycles.".to_owned())] - ); - assert_eq!(registers[0], U256::from(0)); - assert_eq!(registers[1], U256::from(usize::MAX - 2)); // make sure the second operation (Instruction::Cycles(CyclesInstruction { destination: RG1 })) only ran once - assert_eq!(registers[2], U256::from(42)); -} - -#[test] -fn test_events_multi_contract() { - let callee_contract_address = H160::from_low_u64_le(366); - let mut function_jump_calldata_bytes = vec![0u8; 32]; - let mut contract_address_bytes = callee_contract_address.as_bytes().to_vec(); - contract_address_bytes.reverse(); - function_jump_calldata_bytes.splice(4..24, contract_address_bytes); - let callee_calldata = U256::from_little_endian(&function_jump_calldata_bytes); - - let assembly_main = Assembly { - instructions: vec![ - Instruction::Storage(StorageInstruction::LogInit { - packed_lengths: packed_log_lengths(2, 32), - first_topic_or_chunk: RG2, // 533 - }), - Instruction::Storage(StorageInstruction::Log(FullOperand::Immediate(777), RG3)), //366366366 - Instruction::SwitchContext, - Instruction::FunctionJump(FunctionJumpInstruction::Call { - location: FunctionJumpLocation::External { - // call `assembly_callee` - operand: FullOperand::Register(RG1), - is_delegate: false, - }, - }), - Instruction::FunctionJump(FunctionJumpInstruction::Return { error: false }), - ], - labels: Default::default(), - assembly_code: "".to_string(), - pc_line_mapping: Default::default(), - }; - - let assembly_callee = Assembly { - instructions: vec![ - Instruction::Storage(StorageInstruction::LogInit { - packed_lengths: packed_log_lengths(1, 32), - first_topic_or_chunk: RG2, // 533 - }), - Instruction::Storage(StorageInstruction::Log( - FullOperand::Immediate(239239239), - NULL, - )), - Instruction::FunctionJump(FunctionJumpInstruction::Return { error: false }), - ], - labels: Default::default(), - assembly_code: "".to_string(), - pc_line_mapping: Default::default(), - }; - - let mut loaded_contracts: HashMap = HashMap::new(); - loaded_contracts.insert(Address::default(), assembly_main); - loaded_contracts.insert(callee_contract_address, assembly_callee); - - let VmSnapshot { - execution_result: VmExecutionResult { events, .. }, - .. - } = run_vm_multi_contracts( - loaded_contracts, - Vec::new(), - HashMap::new(), - vec![ - U256::from(32), - callee_calldata, - U256::from(533), - U256::from(366366366), - ], - Address::default(), - None, - VmLaunchOption::Default, - usize::MAX, - ); - - let mut value1_bytes = [0u8; 32]; - let mut value2_bytes = [0u8; 32]; - - U256::from(366366366).to_big_endian(&mut value1_bytes); - U256::from(239239239).to_big_endian(&mut value2_bytes); - - // only one event should be emitted - - // the event in the callee contract is rolled back due to exception - assert_eq!(events.len(), 2); - assert_eq!( - events[0], - VmEvent { - address: Address::default(), - location: (BlockNumber(0), 0), - indexed_topics: vec!(H256::from_low_u64_be(533), H256::from_low_u64_be(777)), - value: value1_bytes.to_vec() - } - ); - assert_eq!( - events[1], - VmEvent { - address: callee_contract_address, - location: (BlockNumber(0), 0), - indexed_topics: vec!(H256::from_low_u64_be(533)), - value: value2_bytes.to_vec() - } - ); -} - -#[test] -fn test_events_multi_contract_exception() { - let callee_contract_address = H160::from_low_u64_le(366); - let mut function_jump_calldata_bytes = vec![0u8; 32]; - let mut contract_address_bytes = callee_contract_address.as_bytes().to_vec(); - contract_address_bytes.reverse(); - function_jump_calldata_bytes.splice(4..24, contract_address_bytes); - let callee_calldata = U256::from_little_endian(&function_jump_calldata_bytes); - - let assembly_main = Assembly { - instructions: vec![ - Instruction::Storage(StorageInstruction::LogInit { - packed_lengths: packed_log_lengths(1, 59), - first_topic_or_chunk: RG2, //533 - }), - Instruction::Storage(StorageInstruction::Log( - FullOperand::Immediate(366366366), - RG3, //544544544 - )), - Instruction::SwitchContext, - Instruction::FunctionJump(FunctionJumpInstruction::Call { - location: FunctionJumpLocation::External { - // call `assembly_callee` - operand: FullOperand::Register(RG1), - is_delegate: false, - }, - }), - Instruction::FunctionJump(FunctionJumpInstruction::Return { error: false }), - ], - labels: Default::default(), - assembly_code: "".to_string(), - pc_line_mapping: Default::default(), - }; - - let assembly_callee = Assembly { - instructions: vec![ - Instruction::Storage(StorageInstruction::LogInit { - packed_lengths: packed_log_lengths(1, 59), - first_topic_or_chunk: RG2, - }), - Instruction::Storage(StorageInstruction::Log( - FullOperand::Immediate(544544544), - NULL, - )), - Instruction::FunctionJump(FunctionJumpInstruction::Return { error: true }), - ], - labels: Default::default(), - assembly_code: "".to_string(), - pc_line_mapping: Default::default(), - }; - - let mut loaded_contracts: HashMap = HashMap::new(); - loaded_contracts.insert(Address::default(), assembly_main); - loaded_contracts.insert(callee_contract_address, assembly_callee); - - let VmSnapshot { - execution_result: - VmExecutionResult { - events, - internal_errors, - .. - }, - .. - } = run_vm_multi_contracts( - loaded_contracts, - Vec::new(), - HashMap::new(), - vec![ - U256::from(59), - callee_calldata, - U256::from(533), - U256::from(544544544), - ], // 32 + 27 bytes - Address::default(), - None, - VmLaunchOption::Default, - usize::MAX, - ); - - let mut topic_bytes = [0u8; 32]; - let mut value_bytes = [0u8; 64]; - - U256::from(533).to_little_endian(&mut topic_bytes); - U256::from(366366366).to_big_endian(&mut value_bytes[0..32]); - U256::from(544544544).to_big_endian(&mut value_bytes[32..64]); - assert_eq!( - internal_errors, - vec![( - callee_contract_address, - "Contract execution resulted in a revert".to_owned() - )] - ); - // only one event should be emitted - - // the event in the callee contract is rolled back due to exception - assert_eq!(events.len(), 1); - assert_eq!( - events[0], - VmEvent { - address: Address::default(), - location: (BlockNumber(0), 0), - indexed_topics: vec!(H256::from_low_u64_be(533)), - value: value_bytes[0..59].to_vec() - } - ); -} - -#[test] -fn test_context_contract_addresses() { - let contract_address = H160::from_low_u64_le(366); - let assembly = Assembly { - instructions: vec![ - Instruction::Context(ContextInstruction { - destination: RG0, - field: ContextField::CurrentAddress, - }), - Instruction::FunctionJump(FunctionJumpInstruction::Return { error: false }), - ], - labels: Default::default(), - assembly_code: "".to_string(), - pc_line_mapping: Default::default(), - }; - - let mut loaded_contracts: HashMap = HashMap::new(); - loaded_contracts.insert(contract_address, assembly); - - let VmSnapshot { registers, .. } = run_vm_multi_contracts( - loaded_contracts, - Vec::new(), - HashMap::new(), - vec![], - contract_address, - None, - VmLaunchOption::Default, - usize::MAX, - ); - - assert_eq!( - registers[0], - h256_to_u256(address_to_h256(&contract_address)) - ); -} - -#[test] -fn test_context_msg_sender() { - let callee_contract_address = H160::from_low_u64_le(366); - let mut function_jump_calldata_bytes = vec![0u8; 32]; - let mut contract_address_bytes = callee_contract_address.as_bytes().to_vec(); - contract_address_bytes.reverse(); - function_jump_calldata_bytes.splice(4..24, contract_address_bytes); - let callee_calldata = U256::from_little_endian(&function_jump_calldata_bytes); - - let assembly_main = Assembly { - instructions: vec![ - Instruction::Context(ContextInstruction { - destination: RG1, - field: ContextField::MsgSender, - }), - Instruction::SwitchContext, - Instruction::FunctionJump(FunctionJumpInstruction::Call { - location: FunctionJumpLocation::External { - // call `assembly_callee` - operand: FullOperand::Register(RG0), - is_delegate: false, - }, - }), - Instruction::FunctionJump(FunctionJumpInstruction::Return { error: false }), - ], - labels: Default::default(), - assembly_code: "".to_string(), - pc_line_mapping: Default::default(), - }; - - let assembly_callee = Assembly { - instructions: vec![ - Instruction::Context(ContextInstruction { - destination: RG2, - field: ContextField::MsgSender, - }), - Instruction::FunctionJump(FunctionJumpInstruction::Return { error: true }), - ], - labels: Default::default(), - assembly_code: "".to_string(), - pc_line_mapping: Default::default(), - }; - - let mut loaded_contracts: HashMap = HashMap::new(); - loaded_contracts.insert(H160::from_low_u64_be(777), assembly_main); - loaded_contracts.insert(callee_contract_address, assembly_callee); - - let VmSnapshot { registers, .. } = run_vm_multi_contracts( - loaded_contracts, - Vec::new(), - HashMap::new(), - vec![callee_calldata], // 32 + 27 bytes - H160::from_low_u64_be(777), - Some(VmExecutionContext { - msg_sender: H160::from_low_u64_be(223), - block_number: BlockNumber(0), - transaction_index: 0, - block_timestamp: 0, - entry_address: H160::from_low_u64_be(777), - }), - VmLaunchOption::Default, - usize::MAX, - ); - assert_eq!(registers[1], U256::from(223)); - assert_eq!(registers[2], U256::from(777)); -} - -fn packed_log_lengths(topics: u128, data_bytes: u128) -> FullOperand { - FullOperand::Immediate(topics + (data_bytes << 32)) -} - -fn dummy_storage() -> RawInMemoryStorage { - let mut contracts = HashMap::new(); - - contracts.insert( - Address::default(), - Assembly { - instructions: vec![OP_RETURN], - labels: HashMap::new(), - - assembly_code: "".to_string(), - pc_line_mapping: Default::default(), - }, - ); - RawInMemoryStorage { - values: Default::default(), - contracts, - } -} - -fn dummy_context() -> VmExecutionContext { - VmExecutionContext { - msg_sender: Default::default(), - block_number: BlockNumber(0), - transaction_index: 0, - block_timestamp: 0, - entry_address: Address::default(), - } -} diff --git a/crates/zk_evm/src/vm_state/cycle.rs b/crates/zk_evm/src/vm_state/cycle.rs index faca3cb..f93339d 100644 --- a/crates/zk_evm/src/vm_state/cycle.rs +++ b/crates/zk_evm/src/vm_state/cycle.rs @@ -236,7 +236,6 @@ pub fn read_and_decode< } impl< - 'a, S: zk_evm_abstractions::vm::Storage, M: zk_evm_abstractions::vm::Memory, EV: zk_evm_abstractions::vm::EventSink, @@ -339,7 +338,7 @@ impl< let src1 = self.select_register_value(after_masking_decoded.src1_reg_idx); - let (src0, src1) = if after_masking_decoded.variant.swap_operands() { + let (mut src0, mut src1) = if after_masking_decoded.variant.swap_operands() { (src1, src0) } else { (src0, src1) @@ -372,6 +371,30 @@ impl< .get_current_stack() .is_kernel_mode(); + // Erase fat pointer metadata if unwanted + if !after_masking_decoded + .inner + .variant + .opcode + .src0_can_be_pointer() + && src0.is_pointer + && !is_kernel_mode + { + erase_fat_pointer_metadata(&mut src0.value); + src0.is_pointer = false; + } + if !after_masking_decoded + .inner + .variant + .opcode + .src1_can_be_pointer() + && src1.is_pointer + && !is_kernel_mode + { + erase_fat_pointer_metadata(&mut src1.value); + src1.is_pointer = false; + } + let prestate = PreState { src0, src1, diff --git a/crates/zk_evm/src/vm_state/helpers.rs b/crates/zk_evm/src/vm_state/helpers.rs index ab7129e..f9f4b6d 100644 --- a/crates/zk_evm/src/vm_state/helpers.rs +++ b/crates/zk_evm/src/vm_state/helpers.rs @@ -40,7 +40,6 @@ pub fn read_code< } impl< - 'a, S: zk_evm_abstractions::vm::Storage, M: zk_evm_abstractions::vm::Memory, EV: zk_evm_abstractions::vm::EventSink, @@ -240,7 +239,9 @@ impl< previous_context, &context_entry, ); + #[allow(dropping_references)] drop(previous_context); + self.local_state.callstack.push_entry(context_entry); } @@ -300,7 +301,10 @@ impl< "trying to create bootloader frame with more ergs than VM has available" ); empty_context.ergs_remaining = remaining_for_this_frame; + + #[allow(dropping_references)] drop(empty_context); + self.start_frame(monotonic_cycle_counter, bootloader_context); let base_page = bootloader_context.base_memory_page; self.memory.start_global_frame( diff --git a/crates/zk_evm/src/vm_state/mem_ops.rs b/crates/zk_evm/src/vm_state/mem_ops.rs index 2d5a104..fdb9fb6 100644 --- a/crates/zk_evm/src/vm_state/mem_ops.rs +++ b/crates/zk_evm/src/vm_state/mem_ops.rs @@ -12,7 +12,6 @@ use zkevm_opcode_defs::Operand; impl> MemOpsProcessor { pub fn compute_addresses_and_select_operands< - 'a, S: zk_evm_abstractions::vm::Storage, M: zk_evm_abstractions::vm::Memory, EV: zk_evm_abstractions::vm::EventSink, @@ -54,6 +53,8 @@ impl> MemOpsProcessor { let current_sp = self.sp; // now we also have to decide on case of push or pop, to have push not to overflow 2^16, and pop not to underflow if is_write { + // a generalized version of 'push' + let old_sp = current_sp; let new_sp = current_sp.wrapping_add(vaddr); self.sp = new_sp; @@ -63,11 +64,12 @@ impl> MemOpsProcessor { let location = MemoryLocation { memory_type: MemoryType::Stack, page: stack_page, - index: MemoryIndex(new_sp.as_u64() as u32), + index: MemoryIndex(old_sp.as_u64() as u32), }; Some(location) } else { + // a generalized version of 'pop' let new_sp = current_sp.wrapping_sub(vaddr); self.sp = new_sp; diff --git a/crates/zk_evm/src/vm_state/mod.rs b/crates/zk_evm/src/vm_state/mod.rs index 536b32b..e087b54 100644 --- a/crates/zk_evm/src/vm_state/mod.rs +++ b/crates/zk_evm/src/vm_state/mod.rs @@ -12,13 +12,11 @@ pub mod cycle; pub mod execution_stack; pub mod helpers; pub mod mem_ops; -pub mod pending_port; pub use self::cycle::*; pub use self::execution_stack::*; pub use self::helpers::*; pub use self::mem_ops::*; -pub use self::pending_port::*; pub const SUPPORTED_ISA_VERSION: ISAVersion = ISAVersion(1); diff --git a/crates/zk_evm/src/vm_state/pending_port.rs b/crates/zk_evm/src/vm_state/pending_port.rs deleted file mode 100644 index 05fa83f..0000000 --- a/crates/zk_evm/src/vm_state/pending_port.rs +++ /dev/null @@ -1,26 +0,0 @@ -#[derive(Debug, Clone, Copy, PartialEq)] -pub enum PendingType { - FarCall, - Ret, - WriteLog, - UMAWrite, -} - -#[derive(Debug, Clone, Copy, PartialEq)] -pub struct SpongePendingPort { - pub pending_type: Option, -} - -impl SpongePendingPort { - pub const fn empty() -> Self { - Self { pending_type: None } - } - - pub const fn is_any_pending(&self) -> bool { - self.pending_type.is_some() - } - - pub fn reset(&mut self) { - self.pending_type = None; - } -} diff --git a/crates/zk_evm_abstractions/.gitignore b/crates/zk_evm_abstractions/.gitignore index f2f9e58..ea10157 100644 --- a/crates/zk_evm_abstractions/.gitignore +++ b/crates/zk_evm_abstractions/.gitignore @@ -1,2 +1,4 @@ -target -Cargo.lock \ No newline at end of file +/target +/Cargo.lock + +/.idea/ diff --git a/crates/zk_evm_abstractions/CONTRIBUTING.md b/crates/zk_evm_abstractions/CONTRIBUTING.md index dd3d458..f129e60 100644 --- a/crates/zk_evm_abstractions/CONTRIBUTING.md +++ b/crates/zk_evm_abstractions/CONTRIBUTING.md @@ -1,44 +1,9 @@ # Contribution Guidelines -Hello! Thanks for your interest in joining the mission to accelerate the mass adoption of crypto for personal -sovereignty! We welcome contributions from anyone on the internet, and are grateful for even the smallest of fixes! +Thank you for considering helping out with the source code! We are extremely grateful for any consideration of +contributions to this repository. However, at this time, we generally do not accept external contributions. This policy +will change in the future, so please check back regularly for updates. -## Ways to contribute +For security issues, please contact us at [security@matterlabs.dev](mailto:security@matterlabs.dev). -There are many ways to contribute to the ZK Stack: - -1. Open issues: if you find a bug, have something you believe needs to be fixed, or have an idea for a feature, please - open an issue. -2. Add color to existing issues: provide screenshots, code snippets, and whatever you think would be helpful to resolve - issues. -3. Resolve issues: either by showing an issue isn't a problem and the current state is ok as is or by fixing the problem - and opening a PR. -4. Report security issues, see [our security policy](./github/SECURITY.md). -5. [Join the team!](https://matterlabs.notion.site/Shape-the-future-of-Ethereum-at-Matter-Labs-dfb3b5a037044bb3a8006af2eb0575e0) - -## Fixing issues - -To contribute code fixing issues, please fork the repo, fix an issue, commit, add documentation as per the PR template, -and the repo's maintainers will review the PR. -[here](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork) -for guidance how to work with PRs created from a fork. - -## Licenses - -If you contribute to this project, your contributions will be made to the project under both Apache 2.0 and the MIT -license. - -## Resources - -We aim to make it as easy as possible to contribute to the mission. This is still WIP, and we're happy for contributions -and suggestions here too. Some resources to help: - -1. [In-repo docs aimed at developers](docs) -2. [zkSync Era docs!](https://era.zksync.io/docs/) -3. Company links can be found in the [repo's readme](README.md) - -## Code of Conduct - -Be polite and respectful. - -### Thank you +Thank you for your support in accelerating the mass adoption of crypto for personal sovereignty! diff --git a/crates/zk_evm_abstractions/Cargo.toml b/crates/zk_evm_abstractions/Cargo.toml index faa67a0..e49b2da 100644 --- a/crates/zk_evm_abstractions/Cargo.toml +++ b/crates/zk_evm_abstractions/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zk_evm_abstractions" -version = "0.140.0" +version = "0.141.0" edition = "2021" authors = ["The Matter Labs Team "] homepage = "https://zksync.io/" @@ -18,7 +18,8 @@ serde = { version = "1", features = ["derive"] } static_assertions = "1" num_enum = "0.6" -zkevm_opcode_defs = { version = "=0.132.0", path = "../zkevm_opcode_defs" } +zkevm_opcode_defs = { version = "=0.141.0", path = "../zkevm_opcode_defs" } + [dev-dependencies] hex = "0.4" diff --git a/crates/zk_evm_abstractions/src/precompiles/ecrecover.rs b/crates/zk_evm_abstractions/src/precompiles/ecrecover.rs index e7cb779..6088397 100644 --- a/crates/zk_evm_abstractions/src/precompiles/ecrecover.rs +++ b/crates/zk_evm_abstractions/src/precompiles/ecrecover.rs @@ -147,12 +147,7 @@ impl Precompile for ECRecoverPrecompile { let v = buffer[31]; assert!(v == 0 || v == 1); - let mut serialized = Vec::with_capacity(65); - serialized.extend(r_bytes); - serialized.extend(s_bytes); - serialized.push(v); - - let pk = ecrecover_inner(hash, serialized); + let pk = ecrecover_inner(&hash, &r_bytes, &s_bytes, v); // here it may be possible to have non-recoverable k*G point, so can fail if let Ok(recovered_pubkey) = pk { @@ -251,22 +246,22 @@ impl Precompile for ECRecoverPrecompile { } pub fn ecrecover_inner( - digest: [u8; 32], - serialized_signature: Vec, + digest: &[u8; 32], + r: &[u8; 32], + s: &[u8; 32], + rec_id: u8, ) -> Result { - if digest.iter().all(|el| *el == 0) { - // zero hash is not supported by our convension at the current version, will be activated later separately - return Err(()); - } + use k256::ecdsa::{RecoveryId, Signature}; + // r, s + let mut signature = [0u8; 64]; + signature[..32].copy_from_slice(r); + signature[32..].copy_from_slice(s); // we expect pre-validation, so this check always works - let sig = - k256::ecdsa::recoverable::Signature::try_from(&serialized_signature[..]).map_err(|_| ())?; - let mut hash_array = k256::FieldBytes::default(); - let hash_array_mut_ref: &mut [u8] = hash_array.as_mut(); - hash_array_mut_ref.copy_from_slice(&digest); - - sig.recover_verifying_key_from_digest_bytes(&hash_array) - .map_err(|_| ()) + let signature = Signature::try_from(&signature[..]).map_err(|_| ())?; + + let recid = RecoveryId::try_from(rec_id).unwrap(); + + VerifyingKey::recover_from_prehash(digest, &signature, recid).map_err(|_| ()) } pub fn ecrecover_function( diff --git a/crates/zk_evm_abstractions/src/precompiles/keccak256.rs b/crates/zk_evm_abstractions/src/precompiles/keccak256.rs index aeb4b10..22471e4 100644 --- a/crates/zk_evm_abstractions/src/precompiles/keccak256.rs +++ b/crates/zk_evm_abstractions/src/precompiles/keccak256.rs @@ -8,29 +8,59 @@ use crate::vm::*; use super::precompile_abi_in_log; -pub const KECCAK_RATE_IN_U64_WORDS: usize = 17; -pub const MEMORY_READS_PER_CYCLE: usize = 5; +pub const KECCAK_RATE_BYTES: usize = 136; +pub const MEMORY_READS_PER_CYCLE: usize = 6; +pub const KECCAK_PRECOMPILE_BUFFER_SIZE: usize = MEMORY_READS_PER_CYCLE * 32; pub const MEMORY_WRITES_PER_CYCLE: usize = 1; pub const NUM_WORDS_PER_QUERY: usize = 4; -pub const NEW_WORDS_PER_CYCLE: usize = NUM_WORDS_PER_QUERY * MEMORY_READS_PER_CYCLE; - -// we need a buffer such that if we can not fill it in this block eventually it should -// also contain enough data to run another round function this time -pub const BUFFER_SIZE: usize = NEW_WORDS_PER_CYCLE + KECCAK_RATE_IN_U64_WORDS - 1; - -// since NEW_WORDS_PER_CYCLE and KECCAK_RATE_IN_U64_WORDS are co-prime we will have remainders in a buffer like -// 0 - 3 - 6 - 9 - .... - 18 (here we can actually absorb), so there is no good trick to other than check -// if we skip or not memory reads at this cycle - -// static_assertions::const_assert!(BUFFER_SIZE - NEW_WORDS_PER_CYCLE >= KECCAK_RATE_IN_U64_WORDS); +pub const KECCAK_RATE_IN_U64_WORDS: usize = KECCAK_RATE_BYTES / 8; #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct Keccak256RoundWitness { pub new_request: Option, - pub reads: Option<[MemoryQuery; MEMORY_READS_PER_CYCLE]>, + pub reads: [Option; MEMORY_READS_PER_CYCLE], pub writes: Option<[MemoryQuery; MEMORY_WRITES_PER_CYCLE]>, } +pub struct ByteBuffer { + pub bytes: [u8; BUFFER_SIZE], + pub filled: usize, +} + +impl ByteBuffer { + pub fn can_fill_bytes(&self, num_bytes: usize) -> bool { + self.filled + num_bytes <= BUFFER_SIZE + } + + pub fn fill_with_bytes( + &mut self, + input: &[u8; N], + offset: usize, + meaningful_bytes: usize, + ) { + assert!(self.filled + meaningful_bytes <= BUFFER_SIZE); + self.bytes[self.filled..(self.filled + meaningful_bytes)] + .copy_from_slice(&input[offset..(offset + meaningful_bytes)]); + self.filled += meaningful_bytes; + } + + pub fn consume(&mut self) -> [u8; N] { + assert!(N <= BUFFER_SIZE); + let mut result = [0u8; N]; + result.copy_from_slice(&self.bytes[..N]); + if self.filled < N { + self.filled = 0; + } else { + self.filled -= N; + } + let mut new_bytes = [0u8; BUFFER_SIZE]; + new_bytes[..(BUFFER_SIZE - N)].copy_from_slice(&self.bytes[N..]); + self.bytes = new_bytes; + + result + } +} + #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct Keccak256Precompile; @@ -46,16 +76,28 @@ impl Precompile for Keccak256Precompile { usize, Option<(Vec, Vec, Vec)>, ) { + let mut full_round_padding = [0u8; KECCAK_RATE_BYTES]; + full_round_padding[0] = 0x01; + full_round_padding[KECCAK_RATE_BYTES - 1] = 0x80; + let precompile_call_params = query; // read the parameters let params = precompile_abi_in_log(precompile_call_params); let timestamp_to_read = precompile_call_params.timestamp; let timestamp_to_write = Timestamp(timestamp_to_read.0 + 1); // our default timestamping agreement - let num_rounds = params.precompile_interpreted_data as usize; + let mut input_byte_offset = params.input_memory_offset as usize; + let mut bytes_left = params.input_memory_length as usize; + + let mut num_rounds = (bytes_left + (KECCAK_RATE_BYTES - 1)) / KECCAK_RATE_BYTES; + let padding_space = bytes_left % KECCAK_RATE_BYTES; + let needs_extra_padding_round = padding_space == 0; + if needs_extra_padding_round { + num_rounds += 1; + } + let source_memory_page = params.memory_page_to_read; let destination_memory_page = params.memory_page_to_write; - let mut current_read_offset = params.input_memory_offset; let write_offset = params.output_memory_offset; let mut read_queries = if B { @@ -76,15 +118,17 @@ impl Precompile for Keccak256Precompile { vec![] }; - let mut input_buffer = Buffer::new(); - let mut words_buffer = [0u64; NEW_WORDS_PER_CYCLE]; + let mut input_buffer = ByteBuffer:: { + bytes: [0u8; KECCAK_PRECOMPILE_BUFFER_SIZE], + filled: 0, + }; let mut internal_state = Keccak256::default(); for round in 0..num_rounds { let mut round_witness = Keccak256RoundWitness { new_request: None, - reads: None, + reads: [None; MEMORY_READS_PER_CYCLE], writes: None, }; @@ -92,17 +136,40 @@ impl Precompile for Keccak256Precompile { round_witness.new_request = Some(precompile_call_params); } - // fill the buffer if we can - if input_buffer.can_read_into() { - let mut reads = [MemoryQuery::empty(); MEMORY_READS_PER_CYCLE]; + let is_last = round == num_rounds - 1; + let paddings_round = needs_extra_padding_round && is_last; + + let mut bytes32_buffer = [0u8; 32]; + for idx in 0..MEMORY_READS_PER_CYCLE { + let (memory_index, unalignment) = (input_byte_offset / 32, input_byte_offset % 32); + let at_most_meaningful_bytes_in_query = 32 - unalignment; + let meaningful_bytes_in_query = if bytes_left >= at_most_meaningful_bytes_in_query { + at_most_meaningful_bytes_in_query + } else { + bytes_left + }; + + let enough_buffer_space = input_buffer.can_fill_bytes(meaningful_bytes_in_query); + let nothing_to_read = meaningful_bytes_in_query == 0; + let should_read = + nothing_to_read == false && paddings_round == false && enough_buffer_space; + + let bytes_to_fill = if should_read { + meaningful_bytes_in_query + } else { + 0 + }; + + if should_read { + input_byte_offset += meaningful_bytes_in_query; + bytes_left -= meaningful_bytes_in_query; - for query_index in 0..MEMORY_READS_PER_CYCLE { let data_query = MemoryQuery { timestamp: timestamp_to_read, location: MemoryLocation { - memory_type: MemoryType::Heap, + memory_type: MemoryType::FatPointer, page: MemoryPage(source_memory_page), - index: MemoryIndex(current_read_offset), + index: MemoryIndex(memory_index as u32), }, value: U256::zero(), value_is_pointer: false, @@ -112,38 +179,32 @@ impl Precompile for Keccak256Precompile { memory.execute_partial_query(monotonic_cycle_counter, data_query); let data = data_query.value; if B { - reads[query_index] = data_query; + round_witness.reads[idx] = Some(data_query); read_queries.push(data_query); } - let mut bytes32_buffer = [0u8; 32]; data.to_big_endian(&mut bytes32_buffer[..]); - // revert endianess and push - for (i, chunk) in bytes32_buffer.chunks(8).enumerate() { - let as_u64 = u64::from_le_bytes(chunk.try_into().unwrap()); - words_buffer[query_index * NUM_WORDS_PER_QUERY + i] = as_u64; - } - - current_read_offset += 1; - } - - if B { - round_witness.reads = Some(reads); } - input_buffer.append(&words_buffer); + input_buffer.fill_with_bytes(&bytes32_buffer, unalignment, bytes_to_fill) } - // always consume rate and run keccak round function - let words = input_buffer.consume_rate(); - let mut block = [0u8; KECCAK_RATE_IN_U64_WORDS * 8]; - - for (i, word) in words.into_iter().enumerate() { - block[(i * 8)..(i * 8 + 8)].copy_from_slice(&word.to_le_bytes()); + // buffer is always large enough for us to have data + + let mut block = input_buffer.consume::(); + // apply padding + if paddings_round { + block = full_round_padding; + } else if is_last { + if padding_space == KECCAK_RATE_BYTES - 1 { + block[KECCAK_RATE_BYTES - 1] = 0x81; + } else { + block[padding_space] = 0x01; + block[KECCAK_RATE_BYTES - 1] = 0x80; + } } + // update the keccak internal state internal_state.update(&block); - let is_last = round == num_rounds - 1; - if is_last { let state_inner = transmute_state(internal_state.clone()); @@ -192,52 +253,6 @@ impl Precompile for Keccak256Precompile { } } -pub struct Buffer { - pub words: [u64; BUFFER_SIZE], - pub filled: usize, -} - -impl Buffer { - pub fn new() -> Self { - Self { - words: [0u64; BUFFER_SIZE], - filled: 0, - } - } - - pub fn reset(&mut self) { - self.words = [0u64; BUFFER_SIZE]; - self.filled = 0; - } - - pub fn can_read_into(&self) -> bool { - self.filled <= BUFFER_SIZE - NEW_WORDS_PER_CYCLE - } - - pub fn append(&mut self, data: &[u64; NEW_WORDS_PER_CYCLE]) { - debug_assert!( - self.filled <= BUFFER_SIZE - NEW_WORDS_PER_CYCLE, - "have {} words filled, but the limit is {}", - self.filled, - BUFFER_SIZE - NEW_WORDS_PER_CYCLE - ); - self.words[self.filled..(self.filled + NEW_WORDS_PER_CYCLE)].copy_from_slice(&data[..]); - self.filled += NEW_WORDS_PER_CYCLE; - } - - pub fn consume_rate(&mut self) -> [u64; KECCAK_RATE_IN_U64_WORDS] { - debug_assert!(self.filled >= KECCAK_RATE_IN_U64_WORDS); - let taken = self.words[..KECCAK_RATE_IN_U64_WORDS].try_into().unwrap(); - self.filled -= KECCAK_RATE_IN_U64_WORDS; - let mut tmp = [0u64; BUFFER_SIZE]; - tmp[..(BUFFER_SIZE - KECCAK_RATE_IN_U64_WORDS)] - .copy_from_slice(&self.words[KECCAK_RATE_IN_U64_WORDS..]); - self.words = tmp; - - taken - } -} - pub fn keccak256_rounds_function( monotonic_cycle_counter: u32, precompile_call_params: LogQuery, @@ -256,20 +271,21 @@ pub fn keccak256_rounds_function( pub type Keccak256InnerState = [u64; 25]; +struct Sha3State { + state: [u64; 25], + _round_count: usize, +} + struct BlockBuffer { _buffer: [u8; 136], _pos: u8, } struct CoreWrapper { - core: Keccak256VarCore, + core: Sha3State, _buffer: BlockBuffer, } -struct Keccak256VarCore { - state: Keccak256InnerState, -} - static_assertions::assert_eq_size!(Keccak256, CoreWrapper); pub fn transmute_state(reference_state: Keccak256) -> Keccak256InnerState { diff --git a/crates/zk_evm_abstractions/src/precompiles/mod.rs b/crates/zk_evm_abstractions/src/precompiles/mod.rs index 7167f09..08a4754 100644 --- a/crates/zk_evm_abstractions/src/precompiles/mod.rs +++ b/crates/zk_evm_abstractions/src/precompiles/mod.rs @@ -13,6 +13,8 @@ use zkevm_opcode_defs::system_params::{ SHA256_ROUND_FUNCTION_PRECOMPILE_ADDRESS, }; +use zkevm_opcode_defs::PrecompileCallABI; + #[repr(u16)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, TryFromPrimitive)] pub enum PrecompileAddress { @@ -21,18 +23,8 @@ pub enum PrecompileAddress { Keccak256 = KECCAK256_ROUND_FUNCTION_PRECOMPILE_ADDRESS, } -#[derive(Clone, Copy, Debug)] -pub struct PrecompileCallParams { - pub input_location: MemoryLocation, - pub timestamp_for_input_read: Timestamp, - pub output_location: MemoryLocation, - pub timestamp_for_output_write: Timestamp, -} - -use zkevm_opcode_defs::PrecompileCallInnerABI; - -pub const fn precompile_abi_in_log(query: LogQuery) -> PrecompileCallInnerABI { - PrecompileCallInnerABI::from_u256(query.key) +pub const fn precompile_abi_in_log(query: LogQuery) -> PrecompileCallABI { + PrecompileCallABI::from_u256(query.key) } #[derive(Clone, Copy, Debug)] diff --git a/crates/zkevm_circuits/.github/workflows/ci.yaml b/crates/zkevm_circuits/.github/workflows/ci.yaml index 691210c..401d548 100644 --- a/crates/zkevm_circuits/.github/workflows/ci.yaml +++ b/crates/zkevm_circuits/.github/workflows/ci.yaml @@ -13,7 +13,7 @@ jobs: toolchain: nightly-2023-09-20 rustflags: "" - run: cargo build --verbose --release - - run: cargo test --verbose --release --all + - run: cargo test --verbose --release --all -- --test-threads=1 formatting: name: cargo fmt diff --git a/crates/zkevm_circuits/Cargo.toml b/crates/zkevm_circuits/Cargo.toml index faa9256..c19d0db 100644 --- a/crates/zkevm_circuits/Cargo.toml +++ b/crates/zkevm_circuits/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "zkevm_circuits" -version = "0.140.2" +version = "0.141.1" edition = "2021" authors = ["The Matter Labs Team "] homepage = "https://zksync.io/" @@ -29,9 +29,9 @@ rand_new = { package = "rand", version = "0.8" } hex = "0.4" seq-macro = "0.3" -zkevm_opcode_defs = { version = "=0.132.0", path = "../zkevm_opcode_defs" } -cs_derive = "0" # Version is not pinned, since it's an old dependency for MultiVM only. -boojum = "0" # Version is not pinned, since it's an old dependency for MultiVM only. +zkevm_opcode_defs = { version = "=0.141.0", path = "../zkevm_opcode_defs" } +boojum = "0" +cs_derive = "0" [features] default = [] diff --git a/crates/zkevm_circuits/cs_derive/.gitignore b/crates/zkevm_circuits/cs_derive/.gitignore deleted file mode 100644 index 77147e2..0000000 --- a/crates/zkevm_circuits/cs_derive/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/target -Cargo.lock -.idea/ diff --git a/crates/zkevm_circuits/cs_derive/Cargo.toml b/crates/zkevm_circuits/cs_derive/Cargo.toml deleted file mode 100644 index 4a102f4..0000000 --- a/crates/zkevm_circuits/cs_derive/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "cs_derive" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -syn = { version = "1.0.*", features = ["extra-traits", "printing"]} -quote = {version = "1.0.*"} -proc-macro2 = "1" -proc-macro-error = "1" - -[lib] -proc-macro = true \ No newline at end of file diff --git a/crates/zkevm_circuits/cs_derive/src/.DS_Store b/crates/zkevm_circuits/cs_derive/src/.DS_Store deleted file mode 100644 index 01117831263f46ee11bed5f9109806c7b9e43482..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK%}&BV5S~R21WY8xM2~whF8hflcCSzn8{RWN)h-*;QO)K%&^^R7sdHp2ZtHgg=3DAPo`hR=6SNLv_lV2_Le$^ z>zD>$JH%5&V=zys?^eng?)A5Ia{YQPj0G;ur8{?*GZKXR}pm7Nr*jL;+DCQ-Ie8jm8)_Of8zF z1D!bn0LyS2!@b%2fSMh^z+q|;9+ proc_macro::TokenStream { - let derived_input = parse_macro_input!(input as DeriveInput); - - let DeriveInput { ident, data, generics, attrs, .. } = derived_input.clone(); - - let serde_remove_bounds = if let Some(serde_remove_bounds) = fetch_attr_nopanic(SERDE_REMOVE_BOUNDS, &attrs) { - let serde_remove_bounds = syn::parse_str::(&serde_remove_bounds).expect("has attr as Expr"); - - serde_remove_bounds == syn::parse_str::("true").unwrap() - } else { - false - }; - - let mut allocations = TokenStream::new(); - let mut allocations_without_value = TokenStream::new(); - let mut initializations = TokenStream::new(); - let mut placeholder_initializations = TokenStream::new(); - - match data { - syn::Data::Struct(ref struct_data) => { - match struct_data.fields { - syn::Fields::Named(ref named_fields) => { - for field in named_fields.named.iter() { - - let field_ident = field.ident.clone().expect("a field ident"); - - let allocation_line = match field.ty { - Type::Path(ref _path_ty) => derive_allocate_by_type_path(&field_ident, _path_ty), - Type::Array(ref _arr_ty) => { - derive_allocate_by_array_type(&field_ident, _arr_ty) - }, - _ => abort_call_site!("only array and path types are allowed"), - }; - allocations.extend(allocation_line); - - let allocation_without_value_line = match field.ty { - Type::Path(ref _path_ty) => derive_allocate_without_value_by_type_path(&field_ident, _path_ty), - Type::Array(ref _arr_ty) => { - derive_allocate_without_value_by_array_type(&field_ident, _arr_ty) - }, - _ => abort_call_site!("only array and path types are allowed"), - }; - allocations_without_value.extend(allocation_without_value_line); - - let placeholder_init_line = match field.ty { - Type::Path(ref _path_ty) => derive_placeholder_witness_by_type(&field_ident, _path_ty), - Type::Array(ref _arr_ty) => { - derive_placeholder_witness_by_array_type(&field_ident, _arr_ty) - }, - _ => abort_call_site!("only array and path types are allowed"), - }; - - placeholder_initializations.extend(placeholder_init_line); - - initializations.extend(quote!{ - #field_ident, - }); - } - } - _ => abort_call_site!("only named fields are allowed"), - } - } - _ => abort_call_site!("only data structs are allowed"), - } - - let comma = Comma(Span::call_site()); - - let type_params_of_allocated_struct = get_type_params_from_generics(&generics, &comma); - - let where_clause = if let Some(clause) = generics.where_clause.as_ref() { - quote! { - #clause - } - } else { - quote! {} - }; - - let field_generic_param = syn::parse_str::(&"F: SmallField").unwrap(); - let has_engine_param = has_proper_small_field_parameter(&generics.params, &field_generic_param); - if has_engine_param == false { - panic!("Expected to have `F: SmallField` somewhere in bounds"); - } - - let witness_ident = get_witness_ident(&ident); - let witness_struct = derive_witness_struct_recursive(derived_input.clone()); - - let derive_line = if serde_remove_bounds { - quote! { - #[derive(Derivative, ::serde::Serialize, ::serde::Deserialize)] - #[derivative(Clone, Debug, Hash(bound = ""), PartialEq(bound = ""), Eq(bound = ""))] - } - } else { - quote! { - #[derive(Derivative, ::serde::Serialize, ::serde::Deserialize)] - #[serde(bound = "")] - #[derivative(Clone, Debug, Hash(bound = ""), PartialEq(bound = ""), Eq(bound = ""))] - } - }; - - let expanded = quote! { - #derive_line - #witness_struct - - impl #generics CSAllocatable for #ident<#type_params_of_allocated_struct> #where_clause { - - type Witness = #witness_ident <#type_params_of_allocated_struct>; - - fn placeholder_witness() -> Self::Witness { - #witness_ident :: <#type_params_of_allocated_struct> { - #placeholder_initializations - } - } - - fn allocate>(cs: &mut CS, witness: Self::Witness) -> Self { - #allocations - - Self { - #initializations - } - } - - fn allocate_without_value>(cs: &mut CS) -> Self { - #allocations_without_value - - Self { - #initializations - } - } - } - }; - - proc_macro::TokenStream::from(expanded) -} - -fn derive_allocate_by_type_path(ident: &Ident, ty: &TypePath) -> TokenStream{ - // create a witness element - quote! { - let wit = witness.#ident.clone(); - let #ident = <#ty as CSAllocatable>::allocate(cs, wit); - } -} - -fn derive_allocate_without_value_by_type_path(ident: &Ident, ty: &TypePath) -> TokenStream{ - // create a witness element - quote! { - let #ident = <#ty as CSAllocatable>::allocate_without_value(cs); - } -} - -fn derive_allocate_by_array_type(ident: &Ident, ty: &TypeArray) -> TokenStream{ - quote! { - let wit = witness.#ident.clone(); - let #ident = <#ty as CSAllocatable>::allocate(cs, wit); - } -} - -fn derive_allocate_without_value_by_array_type(ident: &Ident, ty: &TypeArray) -> TokenStream{ - quote! { - let #ident = <#ty as CSAllocatable>::allocate_without_value(cs); - } -} - -// fn derive_get_witness_by_type(ident: &Ident, ty: &TypePath) -> TokenStream{ -// quote! { -// #ident: <#ty as CSAllocatable>::create_witness(&self.#ident)?, -// } -// } - -// fn derive_get_witness_by_array_type(ident: &Ident, ty: &TypeArray) -> TokenStream{ -// quote! { -// #ident: <#ty as CSAllocatable>::create_witness(&self.#ident)?, -// } -// } - -fn derive_placeholder_witness_by_type(ident: &Ident, ty: &TypePath) -> TokenStream{ - quote! { - #ident: <#ty as CSAllocatable>::placeholder_witness(), - } -} - -fn derive_placeholder_witness_by_array_type(ident: &Ident, ty: &TypeArray) -> TokenStream{ - quote! { - #ident: <#ty as CSAllocatable>::placeholder_witness(), - } -} - -pub(crate) fn derive_witness_struct_recursive(derived_input: DeriveInput) -> DeriveInput{ - let DeriveInput { - attrs: _attrs, - vis, - ident, - generics, - mut data, - .. - } = derived_input; - - let comma = Comma(Span::call_site()); - - match data { - Data::Struct(ref mut struct_data) => { - match struct_data.fields { - // we only use named fields for now - Fields::Named(ref mut fields) => { - for field in fields.named.iter_mut() { - let (new_ty, derive_hint) = get_equivalent_type_recursive(&field.ty); - field.ty = new_ty; - match derive_hint { - SerdeDeriveToUse::Default => { - // let att: Attribute = syn::parse_quote! { - // #[serde(bound = "")] - // }; - // field.attrs.push(att); - }, - SerdeDeriveToUse::BigArray => { - let att: Attribute = syn::parse_quote! { - #[serde(with = "crate::serde_utils::BigArraySerde")] - }; - field.attrs.push(att); - } - } - } - }, - _ => abort_call_site!("only named fields are allowed"), - } - }, - _ => abort_call_site!("only structs are allowed"), - }; - - let punc_generic_params = get_type_params_from_generics_output_params(&generics, &comma); - - let new_generics = Generics { - lt_token: generics.lt_token, - params: punc_generic_params, - gt_token: generics.gt_token, - where_clause: generics.where_clause, - }; - - let witness_ident = get_witness_ident(&ident); - - DeriveInput { - attrs: vec![], - vis: vis, - ident: witness_ident, - generics: new_generics, - data: data, - } -} - -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub(crate) enum SerdeDeriveToUse { - Default, - BigArray -} - -// we assume that every type implements a trait -pub(crate) fn get_equivalent_type_recursive(original_ty: &Type) -> (Type, SerdeDeriveToUse) { - match original_ty { - Type::Array(ty) => { - let ts = quote! { - <#ty as CSAllocatable>::Witness - }; - let ts = proc_macro::TokenStream::from(ts); - (Type::Path(syn::parse::(ts).unwrap()), SerdeDeriveToUse::BigArray) - }, - Type::Path(ty) => { - let ts = quote! { - <#ty as CSAllocatable>::Witness - }; - let ts = proc_macro::TokenStream::from(ts); - (Type::Path(syn::parse::(ts).unwrap()), SerdeDeriveToUse::Default) - } - _ => abort_call_site!("only array and path types are allowed"), - } -} \ No newline at end of file diff --git a/crates/zkevm_circuits/cs_derive/src/lib.rs b/crates/zkevm_circuits/cs_derive/src/lib.rs deleted file mode 100644 index b136eec..0000000 --- a/crates/zkevm_circuits/cs_derive/src/lib.rs +++ /dev/null @@ -1,100 +0,0 @@ -use proc_macro::TokenStream; - -pub(crate) mod utils; -mod selectable; -mod allocatable; -mod witness_hook; -mod var_length_encodable; - -#[proc_macro_derive(CSSelectable, attributes(CSSelectableBound))] -#[proc_macro_error::proc_macro_error] -pub fn derive_selectable(input: TokenStream) -> TokenStream{ - self::selectable::derive_select(input) -} - -#[proc_macro_derive(CSAllocatable)] -#[proc_macro_error::proc_macro_error] -pub fn derive_allocatable(input: TokenStream) -> TokenStream{ - self::allocatable::derive_allocatable(input) -} - -#[proc_macro_derive(WitnessHookable, attributes(WitnessHookBound))] -#[proc_macro_error::proc_macro_error] -pub fn derive_witness_hook(input: TokenStream) -> TokenStream{ - self::witness_hook::derive_witness_hook(input) -} - -#[proc_macro_derive(CSVarLengthEncodable)] -#[proc_macro_error::proc_macro_error] -pub fn derive_var_length_encodable(input: TokenStream) -> TokenStream{ - self::var_length_encodable::derive_var_length_encodable(input) -} - -// #[proc_macro_derive(CSOrdering)] -// pub fn derive_ord(input: TokenStream) -> TokenStream{ -// self::ord::derive_ord(input) -// } - -// #[proc_macro_derive(CSOrthogonalSelectable)] -// pub fn derive_orthogonal_select(input: TokenStream) -> TokenStream{ -// self::orth_select::derive_orthogonal_select(input) -// } - -// #[proc_macro_derive(FixedLengthEncodableExt, attributes(EncodingLength, PackWithCS))] -// pub fn derive_encodable(input: TokenStream) -> TokenStream{ -// self::fixed_encodable::derive_encodable(input) -// } -// #[proc_macro_derive(FixedLengthDecodableExt, attributes(EncodingLength))] -// pub fn derive_decodable(input: TokenStream) -> TokenStream{ -// self::fixed_decodable::derive_decodable(input) -// } - -// mod witnessable; -// #[proc_macro_derive(CSWitnessable)] -// pub fn derive_witnessable(input: TokenStream) -> TokenStream{ -// self::witnessable::derive_witnessable(input) -// } - - - -// mod packable; -// #[proc_macro_derive(CSPackable)] -// pub fn derive_packable(input: TokenStream) -> TokenStream{ -// let mut _ts = proc_macro2::TokenStream::new(); -// let derived_input = self::packable::derive_packable(input, &mut _ts); - -// derived_input -// } - -// mod encodable; -// #[proc_macro_derive(CSEncodable)] -// pub fn derive_cs_encodable(input: TokenStream) -> TokenStream{ -// let mut len_expr = proc_macro2::TokenStream::new(); -// let _ = self::packable::derive_packable(input.clone(), &mut len_expr); - -// self::encodable::derive_encodable(input, len_expr).into() -// } - -// mod decodable; -// #[proc_macro_derive(CSDecodable)] -// pub fn derive_cs_decodable(input: TokenStream) -> TokenStream{ -// let mut len_expr = proc_macro2::TokenStream::new(); -// let _ = self::packable::derive_packable(input.clone(), &mut len_expr); - -// self::decodable::derive_decodable(input, len_expr).into() -// } - -// mod var_encodable; -// #[proc_macro_derive(CSVariableLengthEncodable)] -// pub fn derive_cs_var_encodable(input: TokenStream) -> TokenStream{ -// let inner_impl: proc_macro2::TokenStream = self::packable::derive_var_packable(input.clone()).into(); -// let outer_impl: proc_macro2::TokenStream = self::var_encodable::derive_var_encodable(input).into(); - -// let expanded = quote::quote!{ -// #inner_impl - -// #outer_impl -// }; - -// proc_macro::TokenStream::from(expanded).into() -// } diff --git a/crates/zkevm_circuits/cs_derive/src/selectable/mod.rs b/crates/zkevm_circuits/cs_derive/src/selectable/mod.rs deleted file mode 100644 index 1ebdf95..0000000 --- a/crates/zkevm_circuits/cs_derive/src/selectable/mod.rs +++ /dev/null @@ -1,105 +0,0 @@ -use proc_macro2::{Span, TokenStream}; -use proc_macro_error::abort_call_site; -use quote::quote; -use syn::{ - Expr, - Ident, parse_macro_input, punctuated::Punctuated, token::Comma, DeriveInput, GenericParam, Generics, - Type, WhereClause, parse_quote, -}; - -use crate::utils::*; - -const BOUND_ATTR_NAME: &'static str = "CSSelectableBound"; - -pub(crate) fn derive_select(input: proc_macro::TokenStream) -> proc_macro::TokenStream { - let derived_input = parse_macro_input!(input as DeriveInput); - let DeriveInput { - ident, - generics, - data, - attrs, - .. - } = derived_input.clone(); - - let mut struct_initializations = TokenStream::new(); - let mut field_selections = TokenStream::new(); - - let bound = if let Some(bound) = fetch_attr_from_list(BOUND_ATTR_NAME, &attrs) { - let bound = syn::parse_str::(&bound).expect("must parse bound as WhereClause"); - - quote! { #bound } - } else { - quote! { } - }; - - match data { - syn::Data::Struct(ref struct_data) => match struct_data.fields { - syn::Fields::Named(ref named_fields) => { - for field in named_fields.named.iter() { - let field_ident = field.ident.clone().expect("should have a field elem ident"); - match field.ty { - Type::Array(ref _array_ty) => { - let field_select = quote! { - let #field_ident = Selectable::::conditionally_select(cs, flag, &a.#field_ident, &b.#field_ident); - }; - field_selections.extend(field_select); - } - Type::Path(_) => { - let field_select = quote! { - let #field_ident = Selectable::::conditionally_select(cs, flag, &a.#field_ident, &b.#field_ident); - }; - field_selections.extend(field_select); - } - _ => abort_call_site!("only array and path types are allowed"), - }; - - let init_field = quote! { - #field_ident, - }; - - struct_initializations.extend(init_field); - } - } - _ => abort_call_site!("only named fields are allowed!"), - }, - _ => abort_call_site!("only struct types are allowed!"), - } - - let comma = Comma(Span::call_site()); - - let field_generic_param = syn::parse_str::(&"F: SmallField").unwrap(); - let has_engine_param = has_proper_small_field_parameter(&generics.params, &field_generic_param); - if has_engine_param == false { - panic!("Expected to have `F: SmallField` somewhere in bounds"); - } - - // add CS to func generic params - let mut function_generic_params = Punctuated::new(); - let cs_generic_param = syn::parse_str::(&"CS: ConstraintSystem").unwrap(); - function_generic_params.push(cs_generic_param.clone()); - function_generic_params.push_punct(comma.clone()); - - let type_params_of_allocated_struct = get_type_params_from_generics(&generics, &comma); - - let function_generics = Generics { - lt_token: Some(syn::token::Lt(Span::call_site())), - params: function_generic_params, - gt_token: Some(syn::token::Gt(Span::call_site())), - where_clause: None, - }; - - - let expanded = quote! { - impl #generics Selectable for #ident<#type_params_of_allocated_struct> #bound { - fn conditionally_select #function_generics(cs: &mut CS, flag: Boolean, a: &Self, b: &Self) -> Self { - #field_selections - - Self { - #struct_initializations - } - } - } - }; - - proc_macro::TokenStream::from(expanded) -} diff --git a/crates/zkevm_circuits/cs_derive/src/utils.rs b/crates/zkevm_circuits/cs_derive/src/utils.rs deleted file mode 100644 index 7c076c5..0000000 --- a/crates/zkevm_circuits/cs_derive/src/utils.rs +++ /dev/null @@ -1,167 +0,0 @@ -use quote::__private::ext::RepToTokensExt; -use syn::punctuated::Punctuated; -use syn::{GenericParam, TypeParamBound, Generics, Ident}; - -/// Fetch an attribute string from the derived struct. -pub(crate) fn fetch_attr(name: &str, attrs: &[syn::Attribute]) -> Option { - for attr in attrs { - if let Ok(meta) = attr.parse_meta() { - match meta { - syn::Meta::NameValue(nv) => { - if nv.path.is_ident(name) { - match nv.lit { - syn::Lit::Str(ref s) =>{ - return Some(s.value()) - }, - _ => panic!("attribute {} not found", name) - } - } - } - _ => panic!("attribute {} not found", name) - } - } - } - - None -} - - -pub(crate) fn fetch_attr_from_list(name: &str, attrs: &[syn::Attribute]) -> Option { - for attr in attrs { - if attr.path.is_ident(name) { - if let Ok(meta) = attr.parse_meta() { - match meta { - syn::Meta::List(ml) => { - if let Some(nv) = ml.nested.first() { - match nv { - syn::NestedMeta::Lit( - nl - ) => { - match nl { - syn::Lit::Str(ref s) =>{ - return Some(s.value()) - }, - _ => {} - } - } - _ => {} - } - } - }, - _ => {} - } - - } - } - } - - None -} - -pub(crate) fn fetch_attr_nopanic(name: &str, attrs: &[syn::Attribute]) -> Option { - for attr in attrs { - if let Ok(meta) = attr.parse_meta() { - match meta { - syn::Meta::NameValue(nv) => { - if nv.path.is_ident(name) { - match nv.lit { - syn::Lit::Str(ref s) =>{ - return Some(s.value()) - }, - _ => {} - } - } - } - _ => {} - } - } - } - - None -} - -pub(crate) fn has_proper_small_field_parameter